improve input picker

This commit is contained in:
Guilhem
2024-10-23 19:08:51 +02:00
parent 908f8d05d4
commit 63abd70f2e
2 changed files with 103 additions and 81 deletions

View File

@@ -1,12 +1,11 @@
<script lang="ts">
import { copyToClipboard, pluralize, truncate } from '$lib/utils'
import { copyToClipboard, truncate } from '$lib/utils'
import { createEventDispatcher } from 'svelte'
import { Badge } from '../common'
import { computeKey } from './utils'
import WarningMessage from './WarningMessage.svelte'
import { NEVER_TESTED_THIS_FAR } from '../flows/models'
import Portal from '$lib/components/Portal.svelte'
import { Button } from '$lib/components/common'
import { Download, PanelRightOpen } from 'lucide-svelte'
import S3FilePicker from '../S3FilePicker.svelte'
@@ -19,7 +18,6 @@
export let collapsed = (level != 0 && level % 3 == 0) || Array.isArray(json)
export let rawKey = false
export let topBrackets = false
export let topLevelNode = false
export let allowCopy = true
export let collapseLevel: number | undefined = undefined
@@ -73,28 +71,32 @@
{#if level != 0 && keys.length > 1}
<!-- svelte-ignore a11y-click-events-have-key-events -->
<!-- svelte-ignore a11y-no-static-element-interactions -->
<span class="cursor-pointer border hover:bg-surface-hover px-1 rounded" on:click={collapse}>
-
</span>
<Button
color="light"
size="xs2"
variant="border"
on:click={collapse}
wrapperClasses="inline-flex w-fit h-5"
btnClasses="font-semibold text-primary border-nord-300 rounded-[0.275rem]">-</Button
>
{/if}
{#if level == 0 && topBrackets}<span class="h-0">{openBracket}</span>{/if}
<ul class={`w-full pl-2 ${level === 0 ? 'border-none' : 'border-l border-dotted'}`}>
{#each keys.length > keyLimit ? keys.slice(0, keyLimit) : keys as key, index (key)}
<li>
<button on:click={() => selectProp(key)} class="whitespace-nowrap">
{#if topLevelNode}
<Badge baseClass="border border-blue-600" color="indigo">{key}</Badge>
{:else}
<span
class="key {pureViewer
? 'cursor-auto'
: 'border '} font-semibold rounded px-1 hover:bg-surface-hover text-2xs text-secondary"
>
{!isArray ? key : index}</span
>
{/if}:
</button>
<Button
on:click={() => selectProp(key)}
size="xs2"
color="dark"
variant="contained"
wrapperClasses="inline-flex p-0 whitespace-nowrap w-fit h-4"
btnClasses="font-normal rounded-[0.275rem]"
>
<span class={pureViewer ? 'cursor-auto' : ''}>
{!isArray ? key : index}
</span>
</Button>
:
{#if getTypeAsString(json[key]) === 'object'}
<svelte:self
json={json[key]}
@@ -114,9 +116,12 @@
json[key]
)}"
on:click={() => selectProp(key, json[key])}
disabled={true}
>
{#if json[key] === NEVER_TESTED_THIS_FAR}
<WarningMessage />
<span class="text-2xs text-tertiary font-normal">
Test the flow to see a value
</span>
{:else if json[key] == undefined}
<span class="text-2xs">undefined</span>
{:else if json[key] == null}
@@ -167,17 +172,18 @@
<!-- svelte-ignore a11y-click-events-have-key-events -->
<!-- svelte-ignore a11y-no-static-element-interactions -->
<span
class="border border-blue-600 rounded px-1 cursor-pointer hover:bg-gray-200"
class:hidden={!fullyCollapsed}
on:click={collapse}
>
{openBracket}{collapsedSymbol}{closeBracket}
</span>
{#if fullyCollapsed}
<span class="text-tertiary text-xs">
{pluralize(Object.keys(json).length, Array.isArray(json) ? 'item' : 'key')}
</span>
<Button
color="light"
size="xs2"
variant="border"
on:click={collapse}
wrapperClasses="inline-flex w-fit h-5"
btnClasses="font-semibold border-nord-300 rounded-[0.275rem] p-1"
>
{openBracket}{collapsedSymbol}{closeBracket}
</Button>
{/if}
{:else if topBrackets}
<span class="text-primary">{openBracket}{closeBracket}</span>
@@ -200,14 +206,14 @@
@apply text-tertiary;
}
.val.string {
@apply text-green-600 dark:text-green-400/80;
@apply text-primary;
}
.val.number {
@apply text-orange-600 dark:text-orange-400/90;
@apply text-primary;
@apply font-mono;
}
.val.boolean {
@apply text-blue-600 dark:text-blue-400/90;
@apply text-primary;
}
</style>

View File

@@ -21,7 +21,7 @@
let resources: Record<string, any> = {}
let displayVariable = false
let displayResources = false
let allResultsCollapsed = true
const dispatch = createEventDispatcher()
const EMPTY_STRING = ''
@@ -68,16 +68,7 @@
<div class="px-2">
{#if !notSelectable}
<div class="flex flex-row space-x-1">
{#if $propPickerConfig}
<Badge large color="blue">
{`Selected: ${$propPickerConfig?.propName}`}
</Badge>
<Badge large color="blue">
{`Mode: ${$propPickerConfig?.insertionMode}`}
</Badge>
{:else}
<Badge large color="blue">&leftarrow; Edit or connect an input</Badge>
{/if}
<Badge large color="blue">&leftarrow; Edit or connect an input</Badge>
</div>
{/if}
<ClearableInput bind:value={search} placeholder="Search prop..." wrapperClass="py-2" />
@@ -87,7 +78,7 @@
class:bg-surface-secondary={!$propPickerConfig && !notSelectable}
>
<div class="flex justify-between items-center space-x-1">
<span class="font-bold text-sm">Flow Input</span>
<span class="font-normal text-sm text-secondary">Flow Input</span>
<div class="flex space-x-2 items-center" />
</div>
<div class="overflow-y-auto mb-2">
@@ -104,7 +95,7 @@
/>
</div>
{#if error}
<span class="font-bold text-sm">Error</span>
<span class="font-normal text-sm text-secondary">Error</span>
<div class="overflow-y-auto mb-2">
<ObjectViewer
allowCopy={false}
@@ -122,11 +113,10 @@
</div>
{#if Object.keys(pickableProperties.priorIds).length > 0}
{#if suggestedPropsFiltered && Object.keys(suggestedPropsFiltered).length > 0}
<span class="font-bold text-sm">Suggested Results</span>
<span class="font-normal text-sm text-secondary">Suggested Results</span>
<div class="overflow-y-auto mb-2">
<ObjectViewer
allowCopy={false}
topLevelNode
pureViewer={!$propPickerConfig}
collapsed={false}
json={suggestedPropsFiltered}
@@ -136,11 +126,10 @@
/>
</div>
{/if}
<span class="font-bold text-sm">All Results</span>
<span class="font-normal text-sm text-secondary">All Results</span>
<div class="overflow-y-auto mb-2">
<ObjectViewer
allowCopy={false}
topLevelNode
pureViewer={!$propPickerConfig}
collapsed={true}
json={resultByIdFiltered}
@@ -152,11 +141,10 @@
{/if}
{:else}
{#if previousId}
<span class="font-bold text-sm">Previous Result</span>
<span class="font-normal text-sm text-secondary">Previous Result</span>
<div class="overflow-y-auto mb-2">
<ObjectViewer
allowCopy={false}
topLevelNode
pureViewer={!$propPickerConfig}
json={Object.fromEntries(
Object.entries(resultByIdFiltered).filter(([k, v]) => k == previousId)
@@ -168,11 +156,10 @@
</div>
{/if}
{#if pickableProperties.hasResume}
<span class="font-bold text-sm">Resume payloads</span>
<span class="font-normal text-sm text-secondary">Resume payloads</span>
<div class="overflow-y-auto mb-2">
<ObjectViewer
allowCopy={false}
topLevelNode
pureViewer={!$propPickerConfig}
json={{
resume: 'The resume payload',
@@ -187,11 +174,10 @@
{/if}
{#if Object.keys(pickableProperties.priorIds).length > 0}
{#if suggestedPropsFiltered && Object.keys(suggestedPropsFiltered).length > 0}
<span class="font-bold text-sm">Suggested Results</span>
<span class="font-normal text-sm text-secondary">Suggested Results</span>
<div class="overflow-y-auto mb-2">
<ObjectViewer
allowCopy={false}
topLevelNode
pureViewer={!$propPickerConfig}
collapsed={false}
json={suggestedPropsFiltered}
@@ -201,13 +187,25 @@
/>
</div>
{/if}
<span class="font-bold text-sm">All Results</span>
<div class="overflow-y-auto mb-2">
<span class="font-normal text-sm text-tertiary">All Results :</span>
{#if !allResultsCollapsed}
<Button
color="light"
size="xs2"
variant="border"
on:click={() => {
allResultsCollapsed = true
}}
wrapperClasses="inline-flex w-fit h-4"
btnClasses="font-normal text-primary border-nord-300 rounded-[0.275rem]">-</Button
>
{/if}
<ObjectViewer
allowCopy={false}
topLevelNode
pureViewer={!$propPickerConfig}
collapsed={true}
bind:collapsed={allResultsCollapsed}
json={resultByIdFiltered}
on:select={(e) => {
dispatch('select', `results.${e.detail}`)
@@ -218,19 +216,21 @@
{/if}
{#if displayContext}
<span class="font-bold text-sm">Variables </span>
<div class="overflow-y-auto mb-2">
<span class="font-normal text-sm text-secondary">Variables :</span>
{#if displayVariable}
<div class="flex">
<Button
color="light"
size="xs"
variant="border"
on:click={() => {
displayVariable = false
}}>-</Button
>
</div>
<Button
color="light"
size="xs2"
variant="border"
on:click={() => {
displayVariable = false
}}
wrapperClasses="inline-flex w-fit h-4"
btnClasses="font-normal text-primary border-nord-300 rounded-[0.275rem]">-</Button
>
<ObjectViewer
allowCopy={false}
pureViewer={!$propPickerConfig}
@@ -239,25 +239,35 @@
on:select={(e) => dispatch('select', `variable('${e.detail}')`)}
/>
{:else}
<button
class="border border-blue-600 key font-normal rounded hover:bg-blue-100 px-1"
<Button
color="light"
size="xs2"
variant="border"
on:click={async () => {
await loadVariables()
displayVariable = true
}}>{'{...}'}</button
}}
wrapperClasses="inline-flex w-fit h-5"
btnClasses="font-semibold border-nord-300 rounded-[0.275rem] p-1"
>
{'{...}'}
</Button>
{/if}
</div>
<span class="font-bold text-sm">Resources</span>
<div class="overflow-y-auto mb-2">
<span class="font-normal text-sm text-secondary">Resources :</span>
{#if displayResources}
<Button
color="light"
size="xs2"
variant="border"
size="xs"
on:click={() => {
displayResources = false
}}>-</Button
}}
wrapperClasses="inline-flex w-fit h-5"
btnClasses="font-semibold text-primary border-nord-300 rounded-[0.275rem]">-</Button
>
<ObjectViewer
allowCopy={false}
@@ -267,13 +277,19 @@
on:select={(e) => dispatch('select', `resource('${e.detail}')`)}
/>
{:else}
<button
class="border border-blue-600 px-1 key font-normal rounded hover:bg-blue-100"
<Button
color="light"
size="xs2"
variant="border"
on:click={async () => {
await loadResources()
displayResources = true
}}>{'{...}'}</button
}}
wrapperClasses="inline-flex w-fit h-5"
btnClasses="font-semibold border-nord-300 rounded-[0.275rem] p-1"
>
{'{...}'}
</Button>
{/if}
</div>
{/if}