Files
windmill/frontend/src/lib/components/workspaceSettings/CustomInstanceDbSelect.svelte
T
GuilhemandClaude Opus 4.6 4aa1f01210 refactor: replace Select placeholder hack with autocomplete model
Replace the bind:value getter/setter and placeholder-as-display hack with
a standard controlled input pattern (value={inputValue} + oninput handler).

- Remove showPlaceholderOnOpen prop (replaced by default behavior)
- Add allowUserInput prop: typed text syncs to value in real-time
- Separate rawLabel (for filtering) from displayText (for transformed display)
- Hide dropdown when no items match in allowUserInput mode
- Simplify AddUser to use allowUserInput instead of createText/onCreateItem

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 14:51:06 +00:00

100 lines
3.0 KiB
Svelte

<script lang="ts">
import type { CustomInstanceDbTag, ListCustomInstanceDbsResponse } from '$lib/gen'
import type { ResourceReturn } from 'runed'
import Select from '../select/Select.svelte'
import { safeSelectItems } from '../select/utils.svelte'
import { isCustomInstanceDbEnabled } from './utils.svelte'
import Button from '../common/button/Button.svelte'
import CustomInstanceDbWizardModal from './CustomInstanceDbWizardModal.svelte'
import { ArrowRight, TriangleAlert } from 'lucide-svelte'
import type { ConfirmationModalHandle } from '../common/confirmationModal/asyncConfirmationModal.svelte'
import DBManagerDrawer from '../DBManagerDrawer.svelte'
import type { Snippet } from 'svelte'
type Props = {
value: string | undefined
customInstanceDbs: ResourceReturn<ListCustomInstanceDbsResponse>
confirmationModal: ConfirmationModalHandle
dbManagerDrawer: DBManagerDrawer | undefined
wizardBottomHint?: Snippet | undefined
class?: string
tag?: CustomInstanceDbTag
}
let {
value = $bindable(),
customInstanceDbs,
confirmationModal,
dbManagerDrawer,
wizardBottomHint,
class: className,
tag
}: Props = $props()
let openedDbNameWizard = $state(false)
let status = $derived(customInstanceDbs.current?.[value ?? ''])
let onlySelectedTags = $derived(
safeSelectItems(
Object.entries(customInstanceDbs.current ?? {})
.filter(([_, db]) => !tag || db.tag === tag)
.map(([name, _]) => name)
)
)
let currentIsAlreadyUsedElsewhere = $derived(tag && status && status.tag !== tag)
</script>
<div class="flex relative items-center {className}">
<Select
class="flex-1"
bind:value
onCreateItem={(i) => (value = i)}
placeholder="Search or create..."
items={onlySelectedTags}
id="custom-instance-db-select"
disabled={!$isCustomInstanceDbEnabled}
>
{#snippet endSnippet({ item })}
{#if !customInstanceDbs.current?.[item.value]?.success}
<div class="w-1.5 h-1.5 rounded-full bg-red-400"></div>
{:else}
<div class="w-1.5 h-1.5 rounded-full bg-green-400"></div>
{/if}
{/snippet}
</Select>
<Button
spacingSize="xs2"
variant="default"
wrapperClasses={'absolute right-1.5 h-6 bg-surface-input'}
onClick={() => (openedDbNameWizard = true)}
disabled={currentIsAlreadyUsedElsewhere}
>
{#if !status}
<span class="text-yellow-600 dark:text-yellow-400">
Setup <ArrowRight class="inline" size={14} />
</span>
{:else if currentIsAlreadyUsedElsewhere}
<span class="text-red-400 flex gap-1">Already used as {status.tag}</span>
{:else if !status.success}
<span class="text-red-400 flex gap-1">
Error <TriangleAlert class="inline" size={16} />
</span>
{:else}
<div class="w-1.5 h-1.5 rounded-full bg-green-400"></div>
{/if}
</Button>
</div>
<CustomInstanceDbWizardModal
{customInstanceDbs}
{confirmationModal}
{dbManagerDrawer}
{tag}
bottomHint={wizardBottomHint}
bind:opened={
() => (openedDbNameWizard ? { dbname: value ?? '', status: status! } : undefined),
(v) => !v && (openedDbNameWizard = false)
}
/>