diff --git a/tools/ui/src/lib/components/app/models/ModelsManager/ModelsManagerModelsTable.svelte b/tools/ui/src/lib/components/app/models/ModelsManager/ModelsManagerModelsTable.svelte index dd9463ce92..b7c018c850 100644 --- a/tools/ui/src/lib/components/app/models/ModelsManager/ModelsManagerModelsTable.svelte +++ b/tools/ui/src/lib/components/app/models/ModelsManager/ModelsManagerModelsTable.svelte @@ -19,6 +19,7 @@ Upload } from '@lucide/svelte'; import { + BackendIcon, DropdownMenuActions, Logo, ModelAvatar, @@ -65,7 +66,9 @@ /** Repos whose quants are folded away; the rest show them. */ const collapsedQuants = new SvelteSet(); const collapsedFamilies = new SvelteSet(); - let groupFamilies = $state(false); + /** Sections rendered as collapsible table rows instead of headers. */ + let collapsibleRows = $state(false); + const collapsedSections = new SvelteSet(['hidden']); /** Sections with their repos folded into families, when that view is on. */ let sections = $derived( groups.map((group) => { @@ -73,12 +76,10 @@ return { ...group, - families: groupFamilies ? families.filter((family) => family.entries.length > 1) : null, - singles: groupFamilies - ? families - .filter((family) => family.entries.length === 1) - .flatMap((family) => family.entries) - : [] + families: families.filter((family) => family.entries.length > 1), + singles: families + .filter((family) => family.entries.length === 1) + .flatMap((family) => family.entries) }; }) ); @@ -88,6 +89,14 @@ deleteOpen = true; } + function toggleSection(key: string): void { + if (collapsedSections.has(key)) { + collapsedSections.delete(key); + } else { + collapsedSections.add(key); + } + } + function toggleFamily(key: string): void { if (collapsedFamilies.has(key)) { collapsedFamilies.delete(key); @@ -352,6 +361,52 @@ {/if} {/snippet} +{#snippet sectionRow(group: ModelsTableGroup)} + {@const isExpanded = !collapsedSections.has(group.key)} + +
+
toggleSection(group.key)} + onkeydown={(event) => event.key === 'Enter' && toggleSection(group.key)} + role="button" + tabindex="0" + > + + {#if group.kind === 'provider'} + + {:else if group.kind === 'favorites'} + + {:else if group.kind === 'loaded'} + + {:else if group.kind === 'hidden'} + + {:else if group.kind === 'local'} + + {/if} + + {group.label} + + {group.items.length} + + + + + + + + + + {#if isExpanded} + + {:else} + + {/if} + +
+
+{/snippet} + {#snippet familyRow(family: ModelFamilyGroup)} {@const isExpanded = !collapsedFamilies.has(family.key)} @@ -394,10 +449,10 @@ - + - @@ -433,15 +488,35 @@ {/if} {/snippet} - - {#if group.families} + {#if collapsibleRows} + {@render sectionRow(group)} + + {#if !collapsedSections.has(group.key)} +
+ {#each group.families as family (family.key)} + {@render familyRow(family)} + + {#if !collapsedFamilies.has(family.key)} + {#each family.entries as entry (entry.key)} + {@render entryTree(entry)} + {/each} + {/if} + {/each} + + {#each group.singles as entry (entry.key)} + {@render entryTree(entry)} + {/each} +
+ {/if} + {:else} + {#each group.families as family (family.key)} {@render familyRow(family)} @@ -455,12 +530,8 @@ {#each group.singles as entry (entry.key)} {@render entryTree(entry)} {/each} - {:else} - {#each group.items as entry (entry.key)} - {@render entryTree(entry)} - {/each} - {/if} - +
+ {/if} {/if} {/each}