Files
windmill/frontend/src/lib/components/ResourcePicker.svelte
T
Faton RamadaniandRuben Fiszel 402e7eaa9c feat(frontend): Generated UI editor + Schema Form complete refactor (#3835)
* feat(frontend): wip

* feat(frontend): wip

* feat(frontend): wip

* feat(frontend): wip

* feat(frontend): wip

* feat(frontend): add type editor

* feat(frontend): wip

* feat(frontend): wip

* feat(frontend): wip

* feat(frontend): wip

* feat(frontend): dnd

* feat(frontend): add missing error

* feat(frontend): fix build

* feat(frontend): fix build

* feat(frontend): clean up

* feat(frontend): fix layout

* feat(frontend): fix dark mode

* feat(frontend): Fix Dnd + resource s3 and objects

* feat(frontend): handle inner objets

* feat(frontend): wip

* feat(frontend): wip

* feat(frontend): wip

* fix(frontend): UI nits

* fix(frontend): fix type selection

* fix(frontend): Correctly handle subproperties

* fix(frontend): fix autosize + height

* fix(frontend): replace everywhere

* fix(frontend): fix dnd

* fix(frontend): fix list refresh + height issues

* fix(frontend): fix order

* fix(frontend): restore default behavior

* fix(frontend): Move the rename input

* fix(frontend): Fix rename wrt order array

* fix(frontend): Fix hub

* fix(frontend): Fix renam

* fix(frontend): Fix UI Nits + fix SchemaForm order

* fix(frontend): Handle nested order

* fix(frontend): Fix saving properties

* fix(frontend): Improve approval form

* feat(frontend): done

* feat(frontend): merge main

* feat(frontend): done

* feat(frontend): wip

* feat(frontend): SchemaFormDND

* feat(frontend): SchemaFormDND wip

* feat(frontend): improve displayWebhookWarning

* feat(frontend): DND done

* feat(frontend): DND done

* feat(frontend): improve name

* feat(frontend): improve dnd

* feat(frontend): done

* first batch

* new try

* nits

* all

* drag handle in more places

* push everything

* migrate all

* all

* fix

* fix

* fix henri bug

---------

Co-authored-by: Ruben Fiszel <ruben@rubenfiszel.com>
2024-06-12 18:37:18 +02:00

173 lines
4.3 KiB
Svelte

<script lang="ts">
import { ResourceService } from '$lib/gen'
import { workspaceStore } from '$lib/stores'
import { createEventDispatcher } from 'svelte'
import Select from './apps/svelte-select/lib/index'
import { SELECT_INPUT_DEFAULT_STYLE } from '../defaults'
import AppConnect from './AppConnectDrawer.svelte'
import { Button } from './common'
import ResourceEditor from './ResourceEditor.svelte'
import DBSchemaExplorer from './DBSchemaExplorer.svelte'
import DarkModeObserver from './DarkModeObserver.svelte'
import { Pen, Plus, RotateCw } from 'lucide-svelte'
const dispatch = createEventDispatcher()
export let initialValue: string | undefined = undefined
export let value: string | undefined = initialValue
export let valueType: string | undefined = undefined
export let resourceType: string | undefined = undefined
export let disablePortal = false
export let showSchemaExplorer = false
export let selectFirst = false
let valueSelect =
initialValue || value
? {
value: value ?? initialValue,
label: value ?? initialValue,
type: valueType
}
: undefined
$: if (value === undefined && initialValue) {
value = initialValue
}
let collection = valueSelect ? [valueSelect] : []
async function loadResources(resourceType: string | undefined) {
const nc = (
await ResourceService.listResource({
workspace: $workspaceStore!,
resourceType
})
)
.filter((x) => x.resource_type != 'state' && x.resource_type != 'cache')
.map((x) => ({
value: x.path,
label: x.path,
type: x.resource_type
}))
// TODO check if this is needed
if (!nc.find((x) => x.value == value) && (initialValue || value)) {
nc.push({ value: value ?? initialValue!, label: value ?? initialValue!, type: '' })
}
collection = nc
if (collection.length == 1 && selectFirst && valueSelect == undefined) {
value = collection[0].value
valueType = collection[0].type
valueSelect = collection[0]
}
}
$: $workspaceStore && loadResources(resourceType)
$: dispatch('change', value)
let appConnect: AppConnect
let resourceEditor: ResourceEditor
let darkMode: boolean = false
</script>
<DarkModeObserver bind:darkMode />
<AppConnect
on:refresh={async (e) => {
await loadResources(resourceType)
value = e.detail
valueType = collection.find((x) => x?.value == value)?.type
valueSelect = {
value: e.detail,
label: e.detail,
type: valueType ?? ''
}
}}
bind:this={appConnect}
/>
<ResourceEditor
bind:this={resourceEditor}
on:refresh={async (e) => {
await loadResources(resourceType)
if (e.detail) {
value = e.detail
valueType = collection.find((x) => x?.value == value)?.type
valueSelect = { value: e.detail, label: e.detail, type: valueType ?? '' }
}
}}
/>
<div class="flex flex-col w-full items-start">
<div class="flex flex-row gap-x-1 w-full">
<Select
portal={!disablePortal}
value={valueSelect}
on:change={(e) => {
value = e.detail.value
valueType = e.detail.type
valueSelect = e.detail
}}
on:clear={() => {
value = undefined
valueType = undefined
valueSelect = undefined
}}
items={collection}
class="text-clip grow min-w-0"
placeholder="{resourceType ?? 'any'} resource"
inputStyles={SELECT_INPUT_DEFAULT_STYLE.inputStyles}
containerStyles={darkMode
? SELECT_INPUT_DEFAULT_STYLE.containerStylesDark
: SELECT_INPUT_DEFAULT_STYLE.containerStyles}
/>
{#if value && value != ''}
<Button
variant="border"
size="xs"
on:click={() => resourceEditor?.initEdit?.(value ?? '')}
startIcon={{ icon: Pen }}
iconOnly
/>
{/if}
{#if resourceType?.includes(',')}
{#each resourceType.split(',') as rt}
<Button
color="light"
variant="border"
size="xs"
on:click={() => appConnect?.open?.(rt)}
startIcon={{ icon: Plus }}>{rt}</Button
>
{/each}
{:else}
<Button
color="light"
variant="border"
size="xs"
on:click={() => appConnect?.open?.(resourceType)}
startIcon={{ icon: Plus }}
iconOnly
/>
{/if}
<Button
variant="border"
color="light"
size="xs"
on:click={() => {
loadResources(resourceType)
}}
startIcon={{ icon: RotateCw }}
iconOnly
/>
</div>
{#if showSchemaExplorer}
<DBSchemaExplorer {resourceType} resourcePath={value} />
{/if}
</div>