mirror of
https://github.com/TryGhost/Ghost.git
synced 2025-01-07 03:22:21 +03:00
a895bafb53
refs https://github.com/TryGhost/Team/issues/966 With introduction of members filtering, the current way of editing member labels needed an upgrade. This change updates the member label input component to include editing option which allows triggering label edit modal directly from the filtering menu when working with labels. The long term idea is to make this a consistent global pattern with labels dropdown, extending to member details screen as well.
96 lines
2.9 KiB
JavaScript
96 lines
2.9 KiB
JavaScript
import Component from '@glimmer/component';
|
|
import {action} from '@ember/object';
|
|
import {inject as service} from '@ember/service';
|
|
import {tracked} from '@glimmer/tracking';
|
|
|
|
export default class GhMemberLabelInputLabs extends Component {
|
|
@service store;
|
|
|
|
@tracked selectedLabels = [];
|
|
|
|
get availableLabels() {
|
|
return this._availableLabels.toArray().sort((labelA, labelB) => {
|
|
return labelA.name.localeCompare(labelB.name, undefined, {ignorePunctuation: true});
|
|
});
|
|
}
|
|
|
|
get availableLabelNames() {
|
|
return this.availableLabels.map(label => label.name.toLowerCase());
|
|
}
|
|
|
|
constructor(...args) {
|
|
super(...args);
|
|
// 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._availableLabels = this.store.peekAll('label');
|
|
this.selectedLabels = this.args.labels || [];
|
|
}
|
|
|
|
willDestroy() {
|
|
super.willDestroy?.(...arguments);
|
|
this._availableLabels.forEach((label) => {
|
|
if (label.get('isNew')) {
|
|
this.store.deleteRecord(label);
|
|
}
|
|
});
|
|
}
|
|
|
|
@action
|
|
hideCreateOptionOnMatchingLabel(term) {
|
|
return !this.availableLabelNames.includes(term.toLowerCase());
|
|
}
|
|
|
|
@action
|
|
updateLabels(newLabels) {
|
|
let currentLabels = this.selectedLabels;
|
|
|
|
// destroy new+unsaved labels that are no longer selected
|
|
currentLabels.forEach(function (label) {
|
|
if (!newLabels.includes(label) && label.get('isNew')) {
|
|
label.destroyRecord();
|
|
}
|
|
});
|
|
|
|
// update labels
|
|
this.selectedLabels = newLabels;
|
|
this.args.onChange(newLabels);
|
|
}
|
|
|
|
@action
|
|
createLabel(labelName) {
|
|
let currentLabels = this.selectedLabels;
|
|
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
|
|
currentLabels.pushObject(labelToAdd);
|
|
this.args.onChange(currentLabels);
|
|
}
|
|
|
|
_findLabelByName(name) {
|
|
let withMatchingName = function (label) {
|
|
return label.name.toLowerCase() === name.toLowerCase();
|
|
};
|
|
return this.availableLabels.find(withMatchingName);
|
|
}
|
|
}
|