mirror of
https://github.com/TryGhost/Ghost.git
synced 2024-11-29 15:12:58 +03:00
d115204d9f
no issue refs TryGhost/Ghost#11538 * Added members label handling v1 * Added members label dropdown in list screen * Updated selected labels and member list UI refactor * Added v1 label add/delete modal * Added add label modal v1 * Fixed disabled check for new label save * First stab at member filters layout * Updated member detail screen design * Member detail refinements * Added basic editing for member labels * Fixed label deletion from members list * Updated filtered list header * Refinements for dropdown and empty filter state * Refined label modal * Updated member labels fetch logic * Added custom dropdown component for labels * Refined style for dropdown * Refined dropdown button * Restructure and refine members dropdown styles * Added selected indication to dropdown * Fixed dropdown footer style * Removed member label placeholder * Removed add label from member list actions * New label refinements * Added confirmation modal for label delete * Added duplicate validation check for labels * Updated validation check with slug * Updated copy * Updated actions dropdown copy * Fixed visual glitch of dropdown on FF * Hide scrollbar for labels dropdown Co-authored-by: Peter Zimon <peter.zimon@gmail.com>
96 lines
3.0 KiB
JavaScript
96 lines
3.0 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'));
|
|
},
|
|
|
|
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);
|
|
}
|
|
});
|