mirror of
https://github.com/TryGhost/Ghost.git
synced 2024-11-29 15:12:58 +03:00
0395b63d63
no issue - Unsaved labels were still persisted in the store. This was causing unsaved labels reappearing on different instances and caused broken states
106 lines
3.4 KiB
JavaScript
106 lines
3.4 KiB
JavaScript
import Component from '@ember/component';
|
|
import {computed} from '@ember/object';
|
|
import {inject as service} from '@ember/service';
|
|
import {sort} from '@ember/object/computed';
|
|
|
|
export default Component.extend({
|
|
|
|
store: service(),
|
|
|
|
// public attrs
|
|
member: null,
|
|
labelName: '',
|
|
|
|
// internal attrs
|
|
_availableLabels: null,
|
|
|
|
selectedLabels: computed.reads('member.labels'),
|
|
|
|
availableLabels: sort('_availableLabels.[]', function (labelA, labelB) {
|
|
// ignorePunctuation means the # in label names is ignored
|
|
return labelA.name.localeCompare(labelB.name, undefined, {ignorePunctuation: true});
|
|
}),
|
|
|
|
availableLabelNames: computed('availableLabels.@each.name', function () {
|
|
return this.availableLabels.map(label => label.name.toLowerCase());
|
|
}),
|
|
|
|
init() {
|
|
this._super(...arguments);
|
|
// perform a background query to fetch all users and set `availableLabels`
|
|
// to a live-query that will be immediately populated with what's in the
|
|
// store and be updated when the above query returns
|
|
this.store.query('label', {limit: 'all'});
|
|
this.set('_availableLabels', this.store.peekAll('label'));
|
|
},
|
|
|
|
willDestroyElement() {
|
|
// NOTE: cleans up labels store in case they were not persisted, this avoids unsaved labels
|
|
// from appearing on different input instances when unsaved
|
|
this.get('_availableLabels').forEach((label) => {
|
|
if (label.get('isNew')) {
|
|
this.store.deleteRecord(label);
|
|
}
|
|
});
|
|
},
|
|
|
|
actions: {
|
|
matchLabels(labelName, term) {
|
|
return labelName.toLowerCase() === term.trim().toLowerCase();
|
|
},
|
|
|
|
hideCreateOptionOnMatchingLabel(term) {
|
|
return !this.availableLabelNames.includes(term.toLowerCase());
|
|
},
|
|
|
|
updateLabels(newLabels) {
|
|
let currentLabels = this.get('member.labels');
|
|
|
|
// destroy new+unsaved labels that are no longer selected
|
|
currentLabels.forEach(function (label) {
|
|
if (!newLabels.includes(label) && label.get('isNew')) {
|
|
label.destroyRecord();
|
|
}
|
|
});
|
|
|
|
// update labels
|
|
return this.set('member.labels', newLabels);
|
|
},
|
|
|
|
createLabel(labelName) {
|
|
let currentLabels = this.get('member.labels');
|
|
let currentLabelNames = currentLabels.map(label => label.get('name').toLowerCase());
|
|
let labelToAdd;
|
|
|
|
labelName = labelName.trim();
|
|
|
|
// abort if label is already selected
|
|
if (currentLabelNames.includes(labelName.toLowerCase())) {
|
|
return;
|
|
}
|
|
|
|
// find existing label if there is one
|
|
labelToAdd = this._findLabelByName(labelName);
|
|
|
|
// create new label if no match
|
|
if (!labelToAdd) {
|
|
labelToAdd = this.store.createRecord('label', {
|
|
name: labelName
|
|
});
|
|
}
|
|
|
|
// push label onto member relationship
|
|
return currentLabels.pushObject(labelToAdd);
|
|
}
|
|
},
|
|
|
|
// methods
|
|
|
|
_findLabelByName(name) {
|
|
let withMatchingName = function (label) {
|
|
return label.name.toLowerCase() === name.toLowerCase();
|
|
};
|
|
return this.availableLabels.find(withMatchingName);
|
|
}
|
|
});
|