Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion src/stores/categories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -263,10 +263,16 @@ export const useCategoryStore = defineStore('categories', {
console.warn('Category set not found:', id);
return;
}
// Track whether the active set actually changed so we can mark dirty only
// when there is something to save (avoids spurious unsaved-changes prompts
// when initialising or re-selecting the already-active set).
const changed = this.active_set_ids.length !== 1 || this.active_set_ids[0] !== id;
syncToPrimarySet(this);
this.active_set_ids = [id];
this.classes = computeEffectiveClasses(this.category_sets, this.active_set_ids);
this.classes_unsaved_changes = false;
// When the active set changed, mark unsaved so the Save button activates
// and the user can persist the new active_set_ids to storage.
this.classes_unsaved_changes = changed;
},

/**
Expand Down
33 changes: 33 additions & 0 deletions test/unit/store/categories.test.node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -196,4 +196,37 @@ describe('categories store', () => {
categoryStore.save();
expect(categoryStore.classes_unsaved_changes).toBeFalsy();
});

test('switchToSet marks dirty when switching to a different set', () => {
// Regression test for #955: switching category sets did not enable the Save
// button because switchToSet reset classes_unsaved_changes to false even
// though the new active_set_ids hadn't been persisted yet.
categoryStore.$patch({
category_sets: [
{ id: 'setA', categories: [] },
{ id: 'setB', categories: [{ name: ['Work'], rule: { type: 'none' } }] },
],
active_set_ids: ['setA'],
classes: [],
classes_unsaved_changes: false,
});

categoryStore.switchToSet('setB');

expect(categoryStore.active_set_ids).toEqual(['setB']);
expect(categoryStore.classes_unsaved_changes).toBe(true);
});

test('switchToSet does not mark dirty when re-selecting the already-active set', () => {
categoryStore.$patch({
category_sets: [{ id: 'setA', categories: [] }],
active_set_ids: ['setA'],
classes: [],
classes_unsaved_changes: false,
});

categoryStore.switchToSet('setA');

expect(categoryStore.classes_unsaved_changes).toBe(false);
});
});
Loading