From f58de16d1c7abc710290d182649ae84d817ec0dd Mon Sep 17 00:00:00 2001 From: Steve Taylor Date: Mon, 5 Aug 2024 17:25:00 -0700 Subject: [PATCH] Add a view component for tagging --- .../javascripts/spotlight/spotlight.esm.js | 764 +++++------------ .../spotlight/spotlight.esm.js.map | 2 +- app/assets/javascripts/spotlight/spotlight.js | 770 +++++------------- .../javascripts/spotlight/spotlight.js.map | 2 +- .../stylesheets/spotlight/_catalog.scss | 15 - .../stylesheets/spotlight/_spotlight.scss | 1 + .../stylesheets/spotlight/_tag_selector.scss | 34 + .../spotlight/tag_selector_component.html.erb | 39 + .../spotlight/tag_selector_component.rb | 61 ++ .../spotlight/tag_selector_component.yml | 6 + .../controllers/tag_selector_controller.js | 190 +++++ .../admin/exhibit_tag_autocomplete.js | 39 - app/javascript/spotlight/admin/index.js | 3 - app/javascript/spotlight/index.js | 5 + app/views/catalog/_add_tags.html.erb | 2 +- app/views/catalog/_remove_tags.html.erb | 2 +- app/views/layouts/spotlight/base.html.erb | 1 + .../spotlight/catalog/_edit_default.html.erb | 3 +- .../spotlight/templates/spotlight.scss | 1 - rollup.config.js | 8 +- spec/features/bulk_actions_spec.rb | 6 +- .../catalog/_edit_default.html.erb_spec.rb | 2 - .../assets/javascripts/bootstrap-tagsinput.js | 530 ------------ .../stylesheets/bootstrap-tagsinput.css | 46 -- 24 files changed, 740 insertions(+), 1792 deletions(-) create mode 100644 app/assets/stylesheets/spotlight/_tag_selector.scss create mode 100644 app/components/spotlight/tag_selector_component.html.erb create mode 100644 app/components/spotlight/tag_selector_component.rb create mode 100644 app/components/spotlight/tag_selector_component.yml create mode 100644 app/javascript/controllers/tag_selector_controller.js delete mode 100644 app/javascript/spotlight/admin/exhibit_tag_autocomplete.js delete mode 100644 vendor/assets/javascripts/bootstrap-tagsinput.js delete mode 100644 vendor/assets/stylesheets/bootstrap-tagsinput.css diff --git a/app/assets/javascripts/spotlight/spotlight.esm.js b/app/assets/javascripts/spotlight/spotlight.esm.js index f314a2c97a..4c711fa02e 100644 --- a/app/assets/javascripts/spotlight/spotlight.esm.js +++ b/app/assets/javascripts/spotlight/spotlight.esm.js @@ -1,3 +1,5 @@ +import { Controller, Application } from '@hotwired/stimulus'; + class BrowseGroupCateogries { connect() { var $container, slider; @@ -905,535 +907,6 @@ Downcoder.Initialize = function() Downcoder.regex = new RegExp('[' + Downcoder.chars + ']|[^' + Downcoder.chars + ']+','g') ; }; -/* From https://github.com/TimSchlechter/bootstrap-tagsinput/blob/2661784c2c281d3a69b93897ff3f39e4ffa5cbd1/dist/bootstrap-tagsinput.js */ - -/* The MIT License (MIT) - -Copyright (c) 2013 Tim Schlechter - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ - -/* Retrieved 12 February 2014 */ - -(function ($) { - - var defaultOptions = { - tagClass: function(item) { - return 'badge badge-info bg-info'; - }, - itemValue: function(item) { - return item ? item.toString() : item; - }, - itemText: function(item) { - return this.itemValue(item); - }, - freeInput: true, - maxTags: undefined, - confirmKeys: [13], - onTagExists: function(item, $tag) { - $tag.hide().fadeIn(); - } - }; - - /** - * Constructor function - */ - function TagsInput(element, options) { - this.itemsArray = []; - - this.$element = $(element); - this.$element.hide(); - - this.isSelect = (element.tagName === 'SELECT'); - this.multiple = (this.isSelect && element.hasAttribute('multiple')); - this.objectItems = options && options.itemValue; - this.placeholderText = element.hasAttribute('placeholder') ? this.$element.attr('placeholder') : ''; - this.inputSize = Math.max(1, this.placeholderText.length); - - this.$container = $('
'); - this.$input = $('').appendTo(this.$container); - - this.$element.after(this.$container); - - this.build(options); - } - - TagsInput.prototype = { - constructor: TagsInput, - - /** - * Adds the given item as a new tag. Pass true to dontPushVal to prevent - * updating the elements val() - */ - add: function(item, dontPushVal) { - var self = this; - - if (self.options.maxTags && self.itemsArray.length >= self.options.maxTags) - return; - - // Ignore falsey values, except false - if (item !== false && !item) - return; - - // Throw an error when trying to add an object while the itemValue option was not set - if (typeof item === "object" && !self.objectItems) - throw("Can't add objects when itemValue option is not set"); - - // Ignore strings only containg whitespace - if (item.toString().match(/^\s*$/)) - return; - - // If SELECT but not multiple, remove current tag - if (self.isSelect && !self.multiple && self.itemsArray.length > 0) - self.remove(self.itemsArray[0]); - - if (typeof item === "string" && this.$element[0].tagName === 'INPUT') { - var items = item.split(','); - if (items.length > 1) { - for (var i = 0; i < items.length; i++) { - this.add(items[i], true); - } - - if (!dontPushVal) - self.pushVal(); - return; - } - } - - var itemValue = self.options.itemValue(item), - itemText = self.options.itemText(item), - tagClass = self.options.tagClass(item); - - // Ignore items allready added - var existing = $.grep(self.itemsArray, function(item) { return self.options.itemValue(item) === itemValue; } )[0]; - if (existing) { - // Invoke onTagExists - if (self.options.onTagExists) { - var $existingTag = $(".tag", self.$container).filter(function() { return $(this).data("item") === existing; }); - self.options.onTagExists(item, $existingTag); - } - return; - } - - // register item in internal array and map - self.itemsArray.push(item); - - // add a tag element - var $tag = $('' + htmlEncode(itemText) + ''); - $tag.data('item', item); - self.findInputWrapper().before($tag); - $tag.after(' '); - - // add