Files
windmill/frontend/src/lib/components/select/utils.svelte.ts
T
Diego Imbert 6fac896390 fix: send alternatives on timeout toast (#6920)
* Fix broken batch reruns InputTransformForm

* send alternatives on timeout toast

* Toast when runs page query is slow + throttle toasts spamming

* configurable perPage in runs page

* store perPage in query params

* subtle border

* nit fix

* reduce to 25 actions on runs page

* Fix annoying scrollbar due to AIChatLayout

* nit animated pane

* don't kill AI Chat Manager on pane close

* button shrink 0

* nist

* Cancelable Promise Utils

* migrate to CancelablePromiseUtils

* CancelablePromise onTimeout + update usage

* CancelablePromise onTimeout + update usage

* Loading spinner + fix per page bug in audit logs

* Fix .cancel() not behaving as expected

* fix nits

* audit logs nits

* auditlog filter fix selects

* fix wrong number of jobs when switching perPage

* default 1000

* Fix breaking merge conflict

* Fix missing computeCompletedJobs

* change audit logs default perPage to 100
2025-11-13 09:51:15 +00:00

76 lines
1.9 KiB
TypeScript

export function processItems<Item extends { label?: string; value: any }>({
items,
filterText,
groupBy,
sortBy,
onCreateItem,
createText
}: {
items?: Item[]
filterText?: string
groupBy?: (item: Item) => string
sortBy?: (a: Item, b: Item) => number
onCreateItem?: (value: string) => void
createText?: string
}): ProcessedItem<Item['value']>[] {
let items2 =
items?.map((item) => ({
...item,
label: getLabel(item) ?? ''
})) ?? []
if (groupBy) {
items2 =
items2?.map((item) => ({
...item,
__select_group: groupBy(item)
})) ?? []
}
if (sortBy) {
items2 = items2?.sort(sortBy)
}
if (onCreateItem && filterText && !items2.some((item) => item.label === filterText)) {
items2.push({
label: createText ?? `Add new: "${filterText}"`,
value: filterText,
__is_create: true
} as any)
}
return items2
}
export type ProcessedItem<T> = {
__select_group?: string
__is_create?: true
label: string
value: T
subtitle?: string
disabled?: boolean
}
export function getLabel<T>(item: { label?: string; value: T } | undefined): string | undefined {
if (!item) return ''
if (item.label) return item.label
if (typeof item.value === 'string') return item.value
if (typeof item.value == 'number' || typeof item.value == 'boolean') return item.value.toString()
if (item.value == null) return undefined
return JSON.stringify(item.value)
}
export function safeSelectItems<T>(
list: (T | { value: T; label?: string } | undefined | null)[] | undefined | null
): { value: T; label?: string }[] {
if (!list) return []
if (!Array.isArray(list)) return []
return list
.filter((item) => item !== undefined && item !== null)
.map((item) => {
if (typeof item === 'string' || typeof item === 'number' || typeof item === 'boolean') {
return { value: item }
}
if (typeof item === 'object' && 'value' in item) {
return item
}
return { value: null as any, label: 'UNKNOWN_ITEM' }
})
}