Skip to content

Commit 1e71eae

Browse files
authored
Persist template filters (#6657)
This pull request adds persistent filter and sort settings to the template library, allowing users' filter choices and sort preferences to be saved and restored across sessions. The main changes include integrating the settings store with the template filtering composable, updating the schema and core settings, and ensuring filter changes are saved efficiently. **Template Library Filter Persistence:** * [`src/composables/useTemplateFiltering.ts`](diffhunk://#diff-a1ec9d65962033526942cbcabeac8538ef3cd723e2e9e889cf668ccf6270d167L1-R32): The filter state (`selectedModels`, `selectedUseCases`, `selectedRunsOn`, and `sortBy`) is now initialized from the settings store and changes are persisted back using debounced watchers. This ensures user preferences are saved and restored. [[1]](diffhunk://#diff-a1ec9d65962033526942cbcabeac8538ef3cd723e2e9e889cf668ccf6270d167L1-R32) [[2]](diffhunk://#diff-a1ec9d65962033526942cbcabeac8538ef3cd723e2e9e889cf668ccf6270d167R259-R291) * [`src/platform/settings/constants/coreSettings.ts`](diffhunk://#diff-9fb7e2cdcdc60a92bdb54698fb49909bd2a84a50ffb69e2b60529a948eeb9756R1056-R1083): Added new hidden settings for template filter selections and sort preference, with sensible defaults. * [`src/schemas/apiSchema.ts`](diffhunk://#diff-b769532e74f826ca909951c0c34331b9246efb3f6901ff95a856ecf01ad826beR504-R514): Updated the settings schema to include the new template filter and sort settings, ensuring type safety and validation. **Default Behavior Adjustment:** * [`src/composables/useTemplateFiltering.ts`](diffhunk://#diff-a1ec9d65962033526942cbcabeac8538ef3cd723e2e9e889cf668ccf6270d167L200-R209): Changed the default sort order when clearing filters to `'newest'` to match the new default in settings. https://github.com/user-attachments/assets/259e87e6-20b3-4c91-b1bf-4b7d70649878 ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-6657-Persist-template-filters-2a86d73d3650818ca46fda23a6528391) by [Unito](https://www.unito.io)
1 parent 2c3c97d commit 1e71eae

File tree

4 files changed

+122
-8
lines changed

4 files changed

+122
-8
lines changed

src/composables/useTemplateFiltering.ts

Lines changed: 48 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,35 @@
1-
import { refDebounced } from '@vueuse/core'
1+
import { refDebounced, watchDebounced } from '@vueuse/core'
22
import Fuse from 'fuse.js'
33
import { computed, ref, watch } from 'vue'
44
import type { Ref } from 'vue'
55

6+
import { useSettingStore } from '@/platform/settings/settingStore'
67
import { useTelemetry } from '@/platform/telemetry'
78
import type { TemplateInfo } from '@/platform/workflow/templates/types/template'
89
import { debounce } from 'es-toolkit/compat'
910

1011
export function useTemplateFiltering(
1112
templates: Ref<TemplateInfo[]> | TemplateInfo[]
1213
) {
14+
const settingStore = useSettingStore()
15+
1316
const searchQuery = ref('')
14-
const selectedModels = ref<string[]>([])
15-
const selectedUseCases = ref<string[]>([])
16-
const selectedRunsOn = ref<string[]>([])
17+
const selectedModels = ref<string[]>(
18+
settingStore.get('Comfy.Templates.SelectedModels')
19+
)
20+
const selectedUseCases = ref<string[]>(
21+
settingStore.get('Comfy.Templates.SelectedUseCases')
22+
)
23+
const selectedRunsOn = ref<string[]>(
24+
settingStore.get('Comfy.Templates.SelectedRunsOn')
25+
)
1726
const sortBy = ref<
1827
| 'default'
1928
| 'alphabetical'
2029
| 'newest'
2130
| 'vram-low-to-high'
2231
| 'model-size-low-to-high'
23-
>('newest')
32+
>(settingStore.get('Comfy.Templates.SortBy'))
2433

2534
const templatesArray = computed(() => {
2635
const templateData = 'value' in templates ? templates.value : templates
@@ -197,7 +206,7 @@ export function useTemplateFiltering(
197206
selectedModels.value = []
198207
selectedUseCases.value = []
199208
selectedRunsOn.value = []
200-
sortBy.value = 'default'
209+
sortBy.value = 'newest'
201210
}
202211

203212
const removeModelFilter = (model: string) => {
@@ -247,6 +256,39 @@ export function useTemplateFiltering(
247256
{ deep: true }
248257
)
249258

259+
// Persist filter changes to settings (debounced to avoid excessive saves)
260+
watchDebounced(
261+
selectedModels,
262+
(newValue) => {
263+
void settingStore.set('Comfy.Templates.SelectedModels', newValue)
264+
},
265+
{ debounce: 500, deep: true }
266+
)
267+
268+
watchDebounced(
269+
selectedUseCases,
270+
(newValue) => {
271+
void settingStore.set('Comfy.Templates.SelectedUseCases', newValue)
272+
},
273+
{ debounce: 500, deep: true }
274+
)
275+
276+
watchDebounced(
277+
selectedRunsOn,
278+
(newValue) => {
279+
void settingStore.set('Comfy.Templates.SelectedRunsOn', newValue)
280+
},
281+
{ debounce: 500, deep: true }
282+
)
283+
284+
watchDebounced(
285+
sortBy,
286+
(newValue) => {
287+
void settingStore.set('Comfy.Templates.SortBy', newValue)
288+
},
289+
{ debounce: 500 }
290+
)
291+
250292
return {
251293
// State
252294
searchQuery,

src/platform/settings/constants/coreSettings.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1053,6 +1053,34 @@ export const CORE_SETTINGS: SettingParams[] = [
10531053
defaultValue: 0
10541054
},
10551055

1056+
/**
1057+
* Template Library Filter Settings
1058+
*/
1059+
{
1060+
id: 'Comfy.Templates.SelectedModels',
1061+
name: 'Template library - Selected model filters',
1062+
type: 'hidden',
1063+
defaultValue: []
1064+
},
1065+
{
1066+
id: 'Comfy.Templates.SelectedUseCases',
1067+
name: 'Template library - Selected use case filters',
1068+
type: 'hidden',
1069+
defaultValue: []
1070+
},
1071+
{
1072+
id: 'Comfy.Templates.SelectedRunsOn',
1073+
name: 'Template library - Selected runs on filters',
1074+
type: 'hidden',
1075+
defaultValue: []
1076+
},
1077+
{
1078+
id: 'Comfy.Templates.SortBy',
1079+
name: 'Template library - Sort preference',
1080+
type: 'hidden',
1081+
defaultValue: 'newest'
1082+
},
1083+
10561084
/**
10571085
* Vue Node System Settings
10581086
*/

src/schemas/apiSchema.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -501,6 +501,17 @@ const zSettings = z.object({
501501
"what's new seen"
502502
]),
503503
'Comfy.Release.Timestamp': z.number(),
504+
/** Template library filter settings */
505+
'Comfy.Templates.SelectedModels': z.array(z.string()),
506+
'Comfy.Templates.SelectedUseCases': z.array(z.string()),
507+
'Comfy.Templates.SelectedRunsOn': z.array(z.string()),
508+
'Comfy.Templates.SortBy': z.enum([
509+
'default',
510+
'alphabetical',
511+
'newest',
512+
'vram-low-to-high',
513+
'model-size-low-to-high'
514+
]),
504515
/** Settings used for testing */
505516
'test.setting': z.any(),
506517
'main.sub.setting.name': z.any(),

tests-ui/tests/composables/useTemplateFiltering.test.ts

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,43 @@
1-
import { afterEach, describe, expect, it, vi } from 'vitest'
1+
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
22
import { nextTick, ref } from 'vue'
33

4-
import { useTemplateFiltering } from '@/composables/useTemplateFiltering'
54
import type { TemplateInfo } from '@/platform/workflow/templates/types/template'
65

6+
const defaultSettingStore = {
7+
get: vi.fn((key: string) => {
8+
switch (key) {
9+
case 'Comfy.Templates.SelectedModels':
10+
case 'Comfy.Templates.SelectedUseCases':
11+
case 'Comfy.Templates.SelectedRunsOn':
12+
return []
13+
case 'Comfy.Templates.SortBy':
14+
return 'newest'
15+
default:
16+
return undefined
17+
}
18+
}),
19+
set: vi.fn().mockResolvedValue(undefined)
20+
}
21+
22+
vi.mock('@/platform/settings/settingStore', () => ({
23+
useSettingStore: vi.fn(() => defaultSettingStore)
24+
}))
25+
26+
vi.mock('@/platform/telemetry', () => ({
27+
useTelemetry: vi.fn(() => ({
28+
trackTemplateFilterChanged: vi.fn()
29+
}))
30+
}))
31+
32+
const { useTemplateFiltering } = await import(
33+
'@/composables/useTemplateFiltering'
34+
)
35+
736
describe('useTemplateFiltering', () => {
37+
beforeEach(() => {
38+
vi.clearAllMocks()
39+
})
40+
841
afterEach(() => {
942
vi.useRealTimers()
1043
})

0 commit comments

Comments
 (0)