Skip to content

Commit 2feeb55

Browse files
committed
fix: refine extension preference sorting
1 parent 66195be commit 2feeb55

3 files changed

Lines changed: 37 additions & 12 deletions

File tree

dashboard/src/views/extension/extensionPreferenceStorage.mjs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,14 @@ export const SHOW_RESERVED_PLUGINS_STORAGE_KEY = "showReservedPlugins";
22
export const PLUGIN_LIST_VIEW_MODE_STORAGE_KEY = "pluginListViewMode";
33
export const PIN_UPDATES_ON_TOP_STORAGE_KEY = "pinUpdatesOnTop";
44

5+
/**
6+
* Resolve the storage backend for preference helpers.
7+
* Pass `null` to explicitly disable storage access in callers/tests.
8+
*/
59
const resolveStorage = (storage) => {
10+
if (storage === null) {
11+
return null;
12+
}
613
if (storage !== undefined) {
714
return storage;
815
}

dashboard/src/views/extension/useExtensionPage.js

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -441,30 +441,35 @@ export const useExtensionPage = () => {
441441
installedAtTimestamp: getInstalledAtTimestamp(plugin),
442442
}))
443443
.sort((left, right) => {
444-
const fallbackNameCompare = compareInstalledPluginNames(
445-
left.plugin,
446-
right.plugin,
447-
);
448-
const fallbackResult =
449-
fallbackNameCompare !== 0 ? fallbackNameCompare : left.index - right.index;
450-
451444
if (
452445
pinUpdatesOnTop.value &&
453446
installedSortBy.value !== "update_status"
454447
) {
448+
// Pinning updates is a primary grouping; the selected sort order still
449+
// applies within the "has update" and "no update" groups below.
455450
const leftHasUpdate = left.plugin?.has_update ? 1 : 0;
456451
const rightHasUpdate = right.plugin?.has_update ? 1 : 0;
457452
if (leftHasUpdate !== rightHasUpdate) {
458453
return rightHasUpdate - leftHasUpdate;
459454
}
460455
}
461456

457+
const getFallbackResult = () => {
458+
const fallbackNameCompare = compareInstalledPluginNames(
459+
left.plugin,
460+
right.plugin,
461+
);
462+
return fallbackNameCompare !== 0
463+
? fallbackNameCompare
464+
: left.index - right.index;
465+
};
466+
462467
if (installedSortBy.value === "install_time") {
463468
const leftTimestamp = left.installedAtTimestamp;
464469
const rightTimestamp = right.installedAtTimestamp;
465470

466471
if (leftTimestamp == null && rightTimestamp == null) {
467-
return fallbackResult;
472+
return getFallbackResult();
468473
}
469474
if (leftTimestamp == null) {
470475
return 1;
@@ -477,7 +482,7 @@ export const useExtensionPage = () => {
477482
installedSortOrder.value === "desc"
478483
? rightTimestamp - leftTimestamp
479484
: leftTimestamp - rightTimestamp;
480-
return timeDiff !== 0 ? timeDiff : fallbackResult;
485+
return timeDiff !== 0 ? timeDiff : getFallbackResult();
481486
}
482487

483488
if (installedSortBy.value === "name") {
@@ -500,7 +505,7 @@ export const useExtensionPage = () => {
500505
? -authorCompare
501506
: authorCompare;
502507
}
503-
return fallbackResult;
508+
return getFallbackResult();
504509
}
505510

506511
if (installedSortBy.value === "update_status") {
@@ -510,10 +515,10 @@ export const useExtensionPage = () => {
510515
installedSortOrder.value === "desc"
511516
? rightHasUpdate - leftHasUpdate
512517
: leftHasUpdate - rightHasUpdate;
513-
return updateDiff !== 0 ? updateDiff : fallbackResult;
518+
return updateDiff !== 0 ? updateDiff : getFallbackResult();
514519
}
515520

516-
return fallbackResult;
521+
return getFallbackResult();
517522
})
518523
.map((item) => item.plugin);
519524
};

dashboard/tests/extensionPreferenceStorage.test.mjs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,13 @@ test("readBooleanPreference parses stored boolean strings", () => {
3333
);
3434
});
3535

36+
test("readBooleanPreference treats explicit null storage as unavailable", () => {
37+
assert.equal(
38+
readBooleanPreference(PIN_UPDATES_ON_TOP_STORAGE_KEY, true, null),
39+
true,
40+
);
41+
});
42+
3643
test("writeBooleanPreference stores boolean strings and swallows storage errors", () => {
3744
const writes = [];
3845
const storage = {
@@ -47,3 +54,9 @@ test("writeBooleanPreference stores boolean strings and swallows storage errors"
4754
);
4855
assert.deepEqual(writes, [[PIN_UPDATES_ON_TOP_STORAGE_KEY, "true"]]);
4956
});
57+
58+
test("writeBooleanPreference ignores explicit null storage", () => {
59+
assert.doesNotThrow(() =>
60+
writeBooleanPreference(PIN_UPDATES_ON_TOP_STORAGE_KEY, true, null),
61+
);
62+
});

0 commit comments

Comments
 (0)