From 53f9a0883ed8af45bd4f873cf9e4a5c6d31cd291 Mon Sep 17 00:00:00 2001 From: Joffrey JAFFEUX Date: Wed, 6 Jan 2021 12:57:13 +0100 Subject: [PATCH] UX: allows to copy/paste a list of | separated values in sk (#11642) * UX: allows to copy/paste a list of | separated values in sk * fixes tests --- .../addon/components/multi-select.js | 25 +++++++++++++++++++ .../multi-select/multi-select-filter.js | 21 ++++++++++++++++ .../select-kit/addon/components/select-kit.js | 5 ++++ .../select-kit/select-kit-filter.js | 2 ++ .../select-kit/addon/mixins/utils.js | 16 +++++++++--- .../select-kit/select-kit-filter.hbs | 1 + 6 files changed, 66 insertions(+), 4 deletions(-) diff --git a/app/assets/javascripts/select-kit/addon/components/multi-select.js b/app/assets/javascripts/select-kit/addon/components/multi-select.js index d4b8e09a145..6f6a32eb15d 100644 --- a/app/assets/javascripts/select-kit/addon/components/multi-select.js +++ b/app/assets/javascripts/select-kit/addon/components/multi-select.js @@ -29,6 +29,31 @@ export default SelectKitComponent.extend({ ); }, + append(values) { + const existingItems = values + .map((value) => { + const defaultItem = this.defaultItem(value, value); + const existingItem = + this.findValue(this.mainCollection, defaultItem) || + this.findName(this.mainCollection, defaultItem); + if (!existingItem) { + if (this.validateCreate(value, this.content)) { + return value; + } + } else if (this.validateSelect(existingItem)) { + return this.getValue(existingItem); + } + }) + .filter(Boolean); + + const newValues = makeArray(this.value).concat(existingItems); + const newContent = makeArray(this.selectedContent).concat( + makeArray(existingItems) + ); + + this.selectKit.change(newValues, newContent); + }, + deselect(item) { this.clearErrors(); diff --git a/app/assets/javascripts/select-kit/addon/components/multi-select/multi-select-filter.js b/app/assets/javascripts/select-kit/addon/components/multi-select/multi-select-filter.js index 3e49691a4f9..c7dbe545fd2 100644 --- a/app/assets/javascripts/select-kit/addon/components/multi-select/multi-select-filter.js +++ b/app/assets/javascripts/select-kit/addon/components/multi-select/multi-select-filter.js @@ -15,4 +15,25 @@ export default SelectKitFilterComponent.extend({ } return isEmpty(placeholder) ? "" : I18n.t(placeholder); }, + + actions: { + onPaste(event) { + const data = event.originalEvent.clipboardData; + + if (!data) { + return; + } + + const parts = data.getData("text").split("|").filter(Boolean); + + if (parts.length > 1) { + event.stopPropagation(); + event.preventDefault(); + + this.selectKit.append(parts); + + return false; + } + }, + }, }); diff --git a/app/assets/javascripts/select-kit/addon/components/select-kit.js b/app/assets/javascripts/select-kit/addon/components/select-kit.js index 54fbe4100b8..1ad7f666316 100644 --- a/app/assets/javascripts/select-kit/addon/components/select-kit.js +++ b/app/assets/javascripts/select-kit/addon/components/select-kit.js @@ -112,6 +112,7 @@ export default Component.extend( change: bind(this, this._onChangeWrapper), select: bind(this, this.select), deselect: bind(this, this.deselect), + append: bind(this, this.append), onOpen: bind(this, this._onOpenWrapper), onClose: bind(this, this._onCloseWrapper), @@ -540,6 +541,10 @@ export default Component.extend( this.selectKit.change(null, null); }, + append() { + // do nothing on general case + }, + search(filter) { let content = this.content || []; if (filter) { diff --git a/app/assets/javascripts/select-kit/addon/components/select-kit/select-kit-filter.js b/app/assets/javascripts/select-kit/addon/components/select-kit/select-kit-filter.js index f9f6bbe2b38..555930325e6 100644 --- a/app/assets/javascripts/select-kit/addon/components/select-kit/select-kit-filter.js +++ b/app/assets/javascripts/select-kit/addon/components/select-kit/select-kit-filter.js @@ -47,6 +47,8 @@ export default Component.extend(UtilsMixin, { }, actions: { + onPaste() {}, + onInput(event) { this.selectKit.onInput(event); return true; diff --git a/app/assets/javascripts/select-kit/addon/mixins/utils.js b/app/assets/javascripts/select-kit/addon/mixins/utils.js index bd0e4080bf4..cb1c4244bc3 100644 --- a/app/assets/javascripts/select-kit/addon/mixins/utils.js +++ b/app/assets/javascripts/select-kit/addon/mixins/utils.js @@ -57,18 +57,26 @@ export default Mixin.create({ }, findValue(content, item) { - const property = get(this.selectKit, "valueProperty"); + return this._findInContent(content, item, "valueProperty", "getValue"); + }, + + findName(content, item) { + return this._findInContent(content, item, "nameProperty", "getName"); + }, + + _findInContent(content, item, type, getter) { + const property = get(this.selectKit, type); if (!property) { if (content.indexOf(item) > -1) { return item; } } else if (typeof property === "string") { - return content.findBy(property, this.getValue(item)); + return content.findBy(property, this[getter](item)); } else { - const value = this.getValue(item); + const name = this[getter](item); return content.find((contentItem) => { - return this.getValue(contentItem) === value; + return this[getter](contentItem) === name; }); } }, diff --git a/app/assets/javascripts/select-kit/addon/templates/components/select-kit/select-kit-filter.hbs b/app/assets/javascripts/select-kit/addon/templates/components/select-kit/select-kit-filter.hbs index 30965ec78eb..d50302e7b29 100644 --- a/app/assets/javascripts/select-kit/addon/templates/components/select-kit/select-kit-filter.hbs +++ b/app/assets/javascripts/select-kit/addon/templates/components/select-kit/select-kit-filter.hbs @@ -9,6 +9,7 @@ spellcheck=false value=(readonly selectKit.filter) input=(action "onInput") + paste=(action "onPaste") keyDown=(action "onKeydown") }}