Skip to content

Commit 1ae9099

Browse files
committed
fix(workspaces): show FeatureSets in stable alpha order
Same binding listed different sequences per machine because display used insertion order. Signed-off-by: crimsonsunset <jsangio1@gmail.com>
1 parent ef03e78 commit 1ae9099

3 files changed

Lines changed: 14 additions & 19 deletions

File tree

apps/desktop/src/features/workspaces/WorkspacesPage.tsx

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ import {
8484
} from '@/stores';
8585
import type { Space } from '@/lib/api/spaces';
8686
import { FormField } from './workspace-binding-form.component';
87+
import { formatFsList } from './workspace-binding-form.helpers';
8788
import { EmojiPickerButton } from '@/components/emoji-picker-button.component';
8889
import { useViewerIdentity } from '@/hooks/use-viewer-identity.hook';
8990

@@ -699,18 +700,6 @@ export function WorkspacesPage() {
699700
// Filter segmented control
700701
// ---------------------------------------------------------------------------
701702

702-
/**
703-
* Render a list of FeatureSet names as a single string for display
704-
* surfaces (cards, badges, panel headers) where a multi-FS binding has
705-
* to fit on one line. Returns '' for empty input so callers can fall
706-
* back to a placeholder. Drops empty/missing entries silently — they're
707-
* already known to the caller as "fs not found", and there's nothing
708-
* useful to show.
709-
*/
710-
function formatFsList(names: string[]): string {
711-
return names.filter((n) => n && n.length > 0).join(' + ');
712-
}
713-
714703
/**
715704
* Primary title for a workspace entry — label when set, otherwise the path.
716705
*/

apps/desktop/src/features/workspaces/workspace-binding-form.helpers.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,18 @@ export function normalizeIcon(icon: string | null | undefined): string | null {
2121
return trimmed.length > 0 ? trimmed : null;
2222
}
2323

24+
/**
25+
* Render FeatureSet names as one display line (`a + b + c`).
26+
* Sorted A–Z so the same set always reads the same across machines.
27+
* Drops empty/missing names; returns '' so callers can fall back to a placeholder.
28+
*/
29+
export function formatFsList(names: string[]): string {
30+
return names
31+
.filter((n) => n.length > 0)
32+
.sort((a, b) => a.localeCompare(b, undefined, { sensitivity: 'base' }))
33+
.join(' + ');
34+
}
35+
2436
/**
2537
* Last path segment of a workspace root, normalized for cross-platform matching.
2638
*/

apps/desktop/src/features/workspaces/workspace-binding-panel.component.tsx

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ import {
5353
adoptBindingSeed,
5454
findAdoptableSiblingBindings,
5555
folderName,
56+
formatFsList,
5657
normalizeIcon,
5758
sameBindingInput,
5859
type RootValidationState,
@@ -64,13 +65,6 @@ import {
6465
type CollapsibleSectionRef,
6566
} from './WorkspacesPage';
6667

67-
/**
68-
* Render a list of FeatureSet names as a single string for panel subtitles.
69-
*/
70-
function formatFsList(names: string[]): string {
71-
return names.filter((n) => n && n.length > 0).join(' + ');
72-
}
73-
7468
/**
7569
* Resolve machine badge label for header and Scope subtitle.
7670
*/

0 commit comments

Comments
 (0)