From 1b2cf1d3bab4640b5f342d78f9ecda69d4d51dac Mon Sep 17 00:00:00 2001 From: Vito Sansevero Date: Tue, 20 Oct 2026 09:51:44 -0700 Subject: [PATCH] fix(images): sort toolbar categories alphabetically on the client D36 promises alphabetical real categories, which held only while the server sorted them and a restored category was among its list. The page now sorts them case-insensitively itself, a restored category included. Failing before: the toolbar listed a server's [zeta, Alpha, beta] in that order. --- tests/browser/workspace-images.spec.mjs | 10 ++++++++++ web/js/workspace/images.mjs | 5 ++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/tests/browser/workspace-images.spec.mjs b/tests/browser/workspace-images.spec.mjs index 517dea0..a451508 100644 --- a/tests/browser/workspace-images.spec.mjs +++ b/tests/browser/workspace-images.spec.mjs @@ -1544,3 +1544,13 @@ test('unreachable sources and categories announce one error', async ({ page }) = await rescan(page); await expect(page.getByRole('alert')).toHaveCount(0); }); + +// #249 final review m8: D36's alphabetical categories hold whatever order the server sends. +test('toolbar categories are alphabetical regardless of server order', async ({ page }) => { + await page.route('**/prompt_manager/library/options*', route => route.fulfill({ + json: { success: true, categories: ['zeta', 'Alpha', 'beta'] }, + })); + await page.goto(workspace); + const category = page.getByRole('combobox', { name: 'Filter by category', exact: true }); + await expect(category.locator('option')).toHaveText(['All categories', 'Alpha', 'beta', 'zeta']); +}); diff --git a/web/js/workspace/images.mjs b/web/js/workspace/images.mjs index 4d5203b..ba9af95 100644 --- a/web/js/workspace/images.mjs +++ b/web/js/workspace/images.mjs @@ -672,7 +672,10 @@ export function mountImages(main, api, parentScope, {embedded = false, fetchPage const data = await api.get('/prompt_manager/library/options', {signal:request.signal}); if (scope.signal.aborted || request !== categoryRequest) return; if (!Array.isArray(data?.categories)) throw new TypeError('Invalid categories'); - toolbar.setCategories([...data.categories.filter(value => typeof value === 'string'), filters.category]); + // D36: alphabetical (case-insensitive) whatever order the server sends, a restored category among them. + const names = new Set([...data.categories.filter(value => typeof value === 'string' && value), filters.category]); + names.delete(''); + toolbar.setCategories([...names].sort((a, b) => a.localeCompare(b, 'en-US', {sensitivity:'base'}) || (a < b ? -1 : a > b ? 1 : 0))); categoriesFailed = false; } catch { if (scope.signal.aborted || request !== categoryRequest) return;