@nuxeo/nuxeo-ui-elements
Version:
Nuxeo UI Web Components.
292 lines (256 loc) • 7.71 kB
JavaScript
/**
@license
(C) Copyright Nuxeo Corp. (http://nuxeo.com/)
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
import { mixinBehaviors } from '@polymer/polymer/lib/legacy/class.js';
import { IronFormElementBehavior } from '@polymer/iron-form-element-behavior/iron-form-element-behavior.js';
import { IronValidatableBehavior } from '@polymer/iron-validatable-behavior/iron-validatable-behavior.js';
import '@nuxeo/nuxeo-elements/nuxeo-element.js';
import '@nuxeo/nuxeo-elements/nuxeo-operation.js';
import '@polymer/paper-toast/paper-toast.js';
import { I18nBehavior } from '../nuxeo-i18n-behavior.js';
import { escapeHTML } from './nuxeo-selectivity.js';
{
/**
* `nuxeo-tag-suggestion` allows selecting one or more tags.
*
* <nuxeo-tag-suggestion document="[[document]]"
* placeholder="Search for Tags"
* value="{{tags}}" allow-new-tags>
* </nuxeo-tag-suggestion>
*
* @memberof Nuxeo
* @demo demo/nuxeo-tag-suggestion/index.html
*/
class TagSuggestion extends mixinBehaviors(
[I18nBehavior, IronFormElementBehavior, IronValidatableBehavior],
Nuxeo.Element,
) {
static get template() {
return html`
<style>
:host {
display: block;
}
:host([hidden]) {
display: none;
}
</style>
<nuxeo-selectivity
id="s2"
operation="[[operation]]"
label="[[label]]"
min-chars="[[minChars]]"
tagging$="[[allowNewTags]]"
multiple
params="[[params]]"
placeholder="[[placeholder]]"
error-message="[[errorMessage]]"
readonly="[[readonly]]"
value="{{value}}"
selected-items="{{selectedItems}}"
required="[[required]]"
invalid="[[invalid]]"
new-entry-formatter="[[newEntryFormatter]]"
result-formatter="[[resultFormatter]]"
added-entry-handler="[[addedTagHandler]]"
removed-entry-handler="[[removedTagHandler]]"
init-selection="[[initSelection]]"
stay-open-on-select="[[stayOpenOnSelect]]"
>
</nuxeo-selectivity>
<nuxeo-operation id="addTagOp" op="Services.TagDocument" input="[[document.uid]]"></nuxeo-operation>
<nuxeo-operation id="removeTagOp" op="Services.UntagDocument" input="[[document.uid]]"></nuxeo-operation>
<paper-toast id="toast"></paper-toast>
`;
}
static get is() {
return 'nuxeo-tag-suggestion';
}
static get properties() {
return {
/**
* Label.
*/
label: String,
/**
* Operation to call for suggestions.
*/
operation: {
type: String,
value: 'Tag.Suggestion',
},
/**
* Parameters for the operation.
*/
params: Object,
/**
* The document to add / remove tags from.
*/
document: {
type: Object,
observer: '_observeDocument',
},
/*
* Set to true for allowing to add new tags.
*/
allowNewTags: Boolean,
/**
* Selected value(s).
*/
value: {
type: String,
notify: true,
},
/**
* Set to `true` for read only mode.
*/
readonly: {
type: Boolean,
value: false,
},
/**
* Minimum number of chars to trigger the suggestions.
*/
minChars: {
type: Number,
value: 1,
},
/**
* Placeholder.
*/
placeholder: String,
/**
* If true, the dropdown stays open after a selection is made.
*/
stayOpenOnSelect: {
type: Boolean,
value: false,
},
/**
* Error message to show when `invalid` is true.
*/
errorMessage: String,
/**
* Selected items.
*/
selectedItems: {
type: Object,
notify: true,
},
/**
* Formatter for suggested entries.
*/
resultFormatter: {
type: Function,
value() {
return this._resultFormatter.bind(this);
},
},
/**
* Formatter for initial selection.
*/
initSelection: {
type: Function,
value() {
return this._initSelection.bind(this);
},
},
/**
* Formatter for new suggested entries.
*/
newEntryFormatter: {
type: Function,
value() {
return this._newEntryFormatter.bind(this);
},
},
/**
* Handler called when a tag is added.
*/
addedTagHandler: {
type: Function,
value() {
return this._addedTagHandler.bind(this);
},
},
/**
* Handler called when a tag is removed.
*/
removedTagHandler: {
type: Function,
value() {
return this._removedTagHandler.bind(this);
},
},
};
}
/* Override method from Polymer.IronValidatableBehavior. */
_getValidity() {
return this.$.s2._getValidity();
}
_resultFormatter(tag) {
if (tag.newTag) {
return `<span class='s2newTag'>+ ${escapeHTML(tag.displayLabel)}</span>`;
}
return `<span class='s2existingTag'>${escapeHTML(tag.displayLabel)}</span>`;
}
_newEntryFormatter(term) {
return { id: term, displayLabel: term, newTag: true };
}
_addedTagHandler(entry) {
if (this.document) {
this.$.addTagOp.params = { tags: entry.id };
this.$.addTagOp.execute().then(() => {
this.$.toast.hide();
this.$.toast.text = this.i18n('tags.addedToDocument', entry.id);
this.$.toast.open();
});
}
}
_removedTagHandler(entry) {
if (this.document) {
this.$.removeTagOp.params = { tags: entry.id };
this.$.removeTagOp.execute().then(() => {
this.$.toast.hide();
this.$.toast.text = this.i18n('tags.removedFromDocument', entry.id);
this.$.toast.open();
});
}
}
_initSelection(element, callback) {
return callback(
this.value.map((entry) => {
return { id: entry, displayLabel: entry };
}),
);
}
_observeDocument() {
if (this.document) {
if (this.document.contextParameters && this.document.contextParameters.tags) {
this.value = this.document.contextParameters.tags;
} else {
this.value = [];
console.warn(
'Cannot use nuxeo-tag-element on a document that has no tag in its contextParameters. ' +
"Make sure you use the 'tags' enricher to fetch the document",
);
}
} else {
this.value = [];
}
}
}
customElements.define(TagSuggestion.is, TagSuggestion);
Nuxeo.TagSuggestion = TagSuggestion;
}