Skip to content

Commit 727e6f4

Browse files
🐛 Fixed removed tags not showing in dropdown in editor sidebar (#25262)
fixes #25020 Fixed tag disappearing from the dropdown after removal in the post editor. When a tag was removed while the tags dropdown was open, it would disappear from the available options until the editor was closed and reopened. This is now fixed by comparing tag IDs instead of object references. --------- Co-authored-by: Steve Larson <9larsons@gmail.com>
1 parent d97d93a commit 727e6f4

2 files changed

Lines changed: 43 additions & 6 deletions

File tree

ghost/admin/app/components/gh-tags-token-input.js

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,14 @@ export default class GhTagsTokenInput extends Component {
2424

2525
constructor() {
2626
super(...arguments);
27-
this.addInitialTags(this.args.selected?.toArray ? this.args.selected.toArray() : (this.args.selected || []));
27+
const selectedTags = this.args.selected?.toArray ? this.args.selected.toArray() : (this.args.selected || []);
28+
this._initialTags = new TrackedArray(selectedTags);
2829
}
2930

3031
get availableTags() {
3132
const selectedTags = this.args.selected || [];
32-
return this.tagsManager.sortTags(this._initialTags.filter(tag => !selectedTags.includes(tag)));
33+
const selectedTagIds = new Set(selectedTags.map(tag => tag.id));
34+
return this.tagsManager.sortTags(this._initialTags.filter(tag => !selectedTagIds.has(tag.id)));
3335
}
3436

3537
// if we only have one page of tags available or we've already loaded all tags
@@ -43,15 +45,15 @@ export default class GhTagsTokenInput extends Component {
4345

4446
@action
4547
addInitialTags(tags) {
46-
const selectedTags = this.args.selected || [];
47-
const deduplicatedTags = tags.filter(tag => !selectedTags.includes(tag));
48+
const existingTagIds = new Set(this._initialTags.map(tag => tag.id));
49+
const deduplicatedTags = tags.filter(tag => !existingTagIds.has(tag.id));
4850
this._initialTags.push(...deduplicatedTags);
4951
}
5052

5153
@action
5254
addSearchedTags(tags) {
53-
const selectedTags = this.args.selected || [];
54-
const deduplicatedTags = tags.filter(tag => !selectedTags.includes(tag));
55+
const selectedTagIds = new Set((this.args.selected || []).map(tag => tag.id));
56+
const deduplicatedTags = tags.filter(tag => !selectedTagIds.has(tag.id));
5557
this._searchedTags.push(...deduplicatedTags);
5658
}
5759

ghost/admin/tests/integration/components/gh-psm-tags-input-test.js

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,28 @@ describe('Integration: Component: gh-psm-tags-input', function () {
7979
expect(options[3]).to.contain.text('Tag 4');
8080
});
8181

82+
it('shows a removed tag in the options list again', async function () {
83+
await assignPostWithTags(this, 'one', 'three');
84+
await render(hbs`<GhPsmTagsInput @post={{post}} />`);
85+
await clickTrigger();
86+
await settled();
87+
await waitUntil(() => findAll('.ember-power-select-option').length >= 2);
88+
89+
let options = findAll('.ember-power-select-option');
90+
expect(options.length).to.equal(2);
91+
expect(options[0]).to.contain.text('#Tag 2');
92+
expect(options[1]).to.contain.text('Tag 4');
93+
94+
// remove the "Tag 1" token then re-open the dropdown
95+
await click('.ember-power-select-multiple-remove-btn');
96+
await clickTrigger();
97+
await settled();
98+
99+
options = findAll('.ember-power-select-option');
100+
expect(options.length).to.equal(3);
101+
expect(options[0]).to.contain.text('Tag 1');
102+
});
103+
82104
it('uses local search if all tags have been loaded in first page', async function () {
83105
this.set('post', this.store.findRecord('post', 1));
84106
await settled();
@@ -185,7 +207,20 @@ describe('Integration: Component: gh-psm-tags-input', function () {
185207
});
186208

187209
describe('server-side search', function () {
210+
it('excludes selected tags from search results', async function () {
211+
server.create('tag', {name: 'Alpha', slug: 'alpha'});
212+
server.createList('tag', 150, {name: i => `Search ${i.toString().padStart(3, '0')}`});
213+
214+
await assignPostWithTags(this, 'alpha');
215+
await render(hbs`<GhPsmTagsInput @post={{post}} />`);
216+
await clickTrigger();
217+
await typeInSearch('Alph');
218+
await settled();
188219

220+
let options = findAll('.ember-power-select-option');
221+
expect(options.length).to.equal(1);
222+
expect(options[0]).to.contain.text('Add "Alph"...');
223+
});
189224
});
190225

191226
it('highlights internal tags', async function () {

0 commit comments

Comments
 (0)