feat: add ownership and base model filtering, unify asset/dropdown types (#8497)

Add ownership and base model filtering to AssetBrowserModal and
FormDropdown widgets.

## Changes

- **Ownership filter**: Filter by All/My Models/Public Models (uses
`is_immutable` field)
- **Base model filter**: Multi-select filter with Clear Filters button
- **Type unification**: Replace `AssetDropdownItem` with
`FormDropdownItem`
- **Sorting unification**: Extract shared utilities to
`assetSortUtils.ts`
- **UI refactor**: Use `Button` component, Vue 3.5 prop shorthand, i18n
improvements

---------

Co-authored-by: Amp <amp@ampcode.com>
This commit is contained in:
Alexander Brown
2026-02-01 20:01:18 -08:00
committed by GitHub
parent 4e20b7522b
commit eaa3ff1579
30 changed files with 1200 additions and 368 deletions

View File

@@ -4,16 +4,25 @@ import type { VueWrapper } from '@vue/test-utils'
import PrimeVue from 'primevue/config'
import type { ComponentPublicInstance } from 'vue'
import { describe, expect, it, vi } from 'vitest'
import { createI18n } from 'vue-i18n'
import type { FormDropdownItem } from '@/renderer/extensions/vueNodes/widgets/components/form/dropdown/types'
import type { ComboInputSpec } from '@/schemas/nodeDef/nodeDefSchemaV2'
import type { DropdownItem } from '@/renderer/extensions/vueNodes/widgets/components/form/dropdown/types'
import type { SimplifiedWidget } from '@/types/simplifiedWidget'
import WidgetSelectDropdown from '@/renderer/extensions/vueNodes/widgets/components/WidgetSelectDropdown.vue'
const i18n = createI18n({
legacy: false,
locale: 'en',
messages: { en: {} }
})
interface WidgetSelectDropdownInstance extends ComponentPublicInstance {
inputItems: DropdownItem[]
outputItems: DropdownItem[]
inputItems: FormDropdownItem[]
outputItems: FormDropdownItem[]
dropdownItems: FormDropdownItem[]
filterSelected: string
updateSelectedItems: (selectedSet: Set<string>) => void
}
@@ -50,7 +59,7 @@ describe('WidgetSelectDropdown custom label mapping', () => {
uploadFolder: 'input'
},
global: {
plugins: [PrimeVue, createTestingPinia()]
plugins: [PrimeVue, createTestingPinia(), i18n]
}
}) as unknown as VueWrapper<WidgetSelectDropdownInstance>
}
@@ -230,9 +239,7 @@ describe('WidgetSelectDropdown custom label mapping', () => {
).toBe(false)
// The missing value should be accessible via dropdownItems when filter is 'all' (default)
const dropdownItems = (
wrapper.vm as unknown as { dropdownItems: DropdownItem[] }
).dropdownItems
const dropdownItems = wrapper.vm.dropdownItems
expect(
dropdownItems.some((item) => item.name === 'template_image.png')
).toBe(true)
@@ -246,15 +253,10 @@ describe('WidgetSelectDropdown custom label mapping', () => {
})
const wrapper = mountComponent(widget, 'template_image.png')
const vmWithFilter = wrapper.vm as unknown as {
filterSelected: string
dropdownItems: DropdownItem[]
}
vmWithFilter.filterSelected = 'inputs'
wrapper.vm.filterSelected = 'inputs'
await wrapper.vm.$nextTick()
const dropdownItems = vmWithFilter.dropdownItems
const dropdownItems = wrapper.vm.dropdownItems
expect(dropdownItems).toHaveLength(2)
expect(
dropdownItems.every((item) => !String(item.id).startsWith('missing-'))
@@ -267,16 +269,10 @@ describe('WidgetSelectDropdown custom label mapping', () => {
})
const wrapper = mountComponent(widget, 'template_image.png')
const vmWithFilter = wrapper.vm as unknown as {
filterSelected: string
dropdownItems: DropdownItem[]
outputItems: DropdownItem[]
}
vmWithFilter.filterSelected = 'outputs'
wrapper.vm.filterSelected = 'outputs'
await wrapper.vm.$nextTick()
const dropdownItems = vmWithFilter.dropdownItems
const dropdownItems = wrapper.vm.dropdownItems
expect(dropdownItems).toHaveLength(wrapper.vm.outputItems.length)
expect(
dropdownItems.every((item) => !String(item.id).startsWith('missing-'))
@@ -289,9 +285,7 @@ describe('WidgetSelectDropdown custom label mapping', () => {
})
const wrapper = mountComponent(widget, 'img_001.png')
const dropdownItems = (
wrapper.vm as unknown as { dropdownItems: DropdownItem[] }
).dropdownItems
const dropdownItems = wrapper.vm.dropdownItems
expect(dropdownItems).toHaveLength(2)
expect(
dropdownItems.every((item) => !String(item.id).startsWith('missing-'))
@@ -304,9 +298,7 @@ describe('WidgetSelectDropdown custom label mapping', () => {
})
const wrapper = mountComponent(widget, undefined)
const dropdownItems = (
wrapper.vm as unknown as { dropdownItems: DropdownItem[] }
).dropdownItems
const dropdownItems = wrapper.vm.dropdownItems
expect(dropdownItems).toHaveLength(2)
expect(
dropdownItems.every((item) => !String(item.id).startsWith('missing-'))