fix: flow editor design improvements

This commit is contained in:
Ruben Fiszel
2023-06-13 11:41:00 +02:00
parent 2678e9a203
commit eafb6edb45
9 changed files with 90 additions and 65 deletions

View File

@@ -319,7 +319,7 @@
<div class="flex mt-2">
<Button
variant="border"
color="dark"
color="light"
size="xs"
btnClasses="mt-1"
on:click={() => {

View File

@@ -6,9 +6,9 @@
import { ResourceService, VariableService } from '$lib/gen'
import {
faBook,
faCube,
faDollarSign,
faEye,
faPlus,
faRotate,
faRotateLeft
@@ -22,7 +22,7 @@
import Button from './common/button/Button.svelte'
import HighlightCode from './HighlightCode.svelte'
import DrawerContent from './common/drawer/DrawerContent.svelte'
import { Badge, Drawer } from './common'
import { Drawer } from './common'
import WorkspaceScriptPicker from './flows/pickers/WorkspaceScriptPicker.svelte'
import PickHubScript from './flows/pickers/PickHubScript.svelte'
import ToggleHubWorkspace from './ToggleHubWorkspace.svelte'
@@ -253,16 +253,17 @@
<ResourceEditor bind:this={resourceEditor} on:refresh={resourcePicker.openDrawer} />
<VariableEditor bind:this={variableEditor} on:create={variablePicker.openDrawer} />
<div class="flex justify-between items-center overflow-y-auto w-full p-1">
<div class="flex justify-between items-center overflow-y-auto w-full p-0.5">
<div class="flex items-center">
<Badge color={validCode ? 'green' : 'red'} class="min-w-[60px] mr-3">
{validCode ? 'Valid' : 'Invalid'}
</Badge>
<div class="flex items-center divide-x">
<div
title={validCode ? 'Main function parsable' : 'Main function not parsable'}
class="rounded-full w-2 h-2 mx-2 {validCode ? 'bg-green-300' : 'bg-red-300'}"
/>
<div class="flex items-center">
<Button
title="Add context variable"
color="light"
btnClasses="!font-medium !h-full"
btnClasses="!font-medium text-gray-600"
on:click={contextualVariablePicker.openDrawer}
size="xs"
spacingSize="md"
@@ -275,7 +276,7 @@
<Button
title="Add variable"
color="light"
btnClasses="!font-medium !h-full"
btnClasses="!font-medium text-gray-600"
on:click={variablePicker.openDrawer}
size="xs"
spacingSize="md"
@@ -287,7 +288,7 @@
<Button
title="Add resource"
btnClasses="!font-medium !h-full"
btnClasses="!font-medium text-gray-600"
size="xs"
spacingSize="md"
color="light"
@@ -300,7 +301,7 @@
<Button
title="Reset Content"
btnClasses="!font-medium !h-full"
btnClasses="!font-medium text-gray-600"
size="xs"
spacingSize="md"
color="light"
@@ -312,7 +313,7 @@
</Button>
<Button
btnClasses="!font-medium !h-full"
btnClasses="!font-medium text-gray-600"
size="xs"
spacingSize="md"
color="light"
@@ -399,16 +400,16 @@
{#if SCRIPT_EDITOR_SHOW_EXPLORE_OTHER_SCRIPTS}
<Button
btnClasses="!font-medium"
btnClasses="!font-medium text-gray-600"
size="xs"
spacingSize="md"
color="light"
on:click={scriptPicker.openDrawer}
{iconOnly}
startIcon={{ icon: faEye }}
startIcon={{ icon: faBook }}
title="Explore other scripts"
>
Explore other scripts
Library
</Button>
{/if}
</div>

View File

@@ -1,5 +1,12 @@
<script lang="ts">
import { FlowService, ScheduleService, type Flow, type FlowModule, DraftService } from '$lib/gen'
import {
FlowService,
ScheduleService,
type Flow,
type FlowModule,
DraftService,
type PathScript
} from '$lib/gen'
import { initHistory, redo, undo } from '$lib/history'
import { enterpriseLicense, userStore, workspaceStore } from '$lib/stores'
import { encodeState, formatCron } from '$lib/utils'
@@ -24,6 +31,7 @@
import { loadHubScripts } from '$lib/scripts'
import { createEventDispatcher } from 'svelte'
import Awareness from './Awareness.svelte'
import { getAllModules } from './flows/previousResults'
export let initialPath: string = ''
export let selectedId: string | undefined
@@ -93,10 +101,21 @@
loadingDraft = false
}
export function computeUnlockedSteps(flow: Flow) {
return Object.fromEntries(
getAllModules(flow)
.filter((m) => m.value.type == 'script' && m.value.hash == null)
.map((m) => [m.id, (m.value as PathScript).path])
)
}
async function saveFlow(): Promise<void> {
loadingSave = true
try {
const flow = cleanInputs($flowStore)
// console.log('flow', computeUnlockedSteps(flow)) // del
// loadingSave = false // del
// return
const { cron, timezone, args, enabled } = $scheduleStore
$dirtyStore = false
if (initialPath === '') {

View File

@@ -9,14 +9,16 @@
import type { PropPickerWrapperContext } from './flows/propPicker/PropPickerWrapper.svelte'
import { codeToStaticTemplate, getDefaultExpr, isCodeInjection } from './flows/utils'
import SimpleEditor from './SimpleEditor.svelte'
import { Button, ToggleButton, ToggleButtonGroup } from './common'
import { faCode } from '@fortawesome/free-solid-svg-icons'
import { Button } from './common'
import ToggleButtonGroup from '$lib/components/common/toggleButton-v2/ToggleButtonGroup.svelte'
import ToggleButton from '$lib/components/common/toggleButton-v2/ToggleButton.svelte'
import type VariableEditor from './VariableEditor.svelte'
import type ItemPicker from './ItemPicker.svelte'
import type { InputTransform } from '$lib/gen'
import TemplateEditor from './TemplateEditor.svelte'
import { setInputCat as computeInputCat } from '$lib/utils'
import { Plug } from 'lucide-svelte'
import { Code, Plug } from 'lucide-svelte'
export let schema: Schema
export let arg: InputTransform | any
@@ -153,7 +155,7 @@
{/if}
</div>
{#if !noDynamicToggle}
<div class="flex flex-row gap-x-4 gap-y-1 flex-wrap z-10">
<div class="flex flex-row gap-x-6 gap-y-1 flex-wrap z-10 items-center">
<div>
<ToggleButtonGroup
bind:selected={propertyType}
@@ -196,24 +198,25 @@
>
{#if isStaticTemplate(inputCat)}
<ToggleButton
title={`Write text or surround javascript with \`\$\{\` and \`\}\`. Use \`results\` to connect to another node\'s output.`}
tooltip={`Write text or surround javascript with \`\$\{\` and \`\}\`. Use \`results\` to connect to another node\'s output.`}
light
position="left"
value="static"
size="xs2"
>
{'${} '}&nbsp;
</ToggleButton>
small
label={'${}'}
/>
{:else}
<ToggleButton light position="left" value="static" size="xs2">Static</ToggleButton>
<ToggleButton small label="Static" position="left" value="static" size="xs2" />
{/if}
<ToggleButton
small
light
title="Javascript expression ('flow_input' or 'results')."
tooltip="Javascript expression ('flow_input' or 'results')."
position="right"
value="javascript"
startIcon={{ icon: faCode }}
icon={Code}
size="xs2"
/>
</ToggleButtonGroup>

View File

@@ -61,7 +61,7 @@
{#if keys.length > 0}
{#each keys as argName (argName)}
{#if (!filter || filter.includes(argName)) && Object.keys(schema.properties ?? {}).includes(argName)}
<div class="z-10 pt-1.5">
<div class="z-10 pt-4">
<InputTransformForm
{previousModuleId}
bind:arg={args[argName]}

View File

@@ -98,11 +98,17 @@
>
{/if}
<Button variant="border" size="xs" on:click={() => appConnect?.open?.(resourceType)}>
<Button
color="light"
variant="border"
size="xs"
on:click={() => appConnect?.open?.(resourceType)}
>
<Icon scale={0.8} data={faPlus} /></Button
>
<Button
variant="border"
color="light"
size="xs"
on:click={() => {
loadResources(resourceType)

View File

@@ -12,6 +12,7 @@
export let icon: any | undefined = undefined
export let disabled: boolean = false
export let selectedColor: string = '#3b82f6'
export let small: boolean = false
const { select, selected } = getContext<ToggleButtonContext>('ToggleButtonGroup')
</script>
@@ -20,7 +21,8 @@
<Tab
{disabled}
class={twMerge(
'px-2 py-1 rounded-md transition-all text-xs flex gap-1 flex-row items-center',
' rounded-md transition-all text-xs flex gap-1 flex-row items-center',
small ? 'px-1 py-0.5' : 'px-2 py-1',
$selected === value ? 'bg-white shadow-md text-gray-800' : 'text-gray-600 hover:bg-gray-200',
$$props.class
)}

View File

@@ -1,21 +1,15 @@
<script lang="ts">
import type { BadgeColor } from '$lib/components/common'
import Badge from '$lib/components/common/badge/Badge.svelte'
import Button from '$lib/components/common/button/Button.svelte'
import LanguageIcon from '$lib/components/common/languageIcons/LanguageIcon.svelte'
import IconedPath from '$lib/components/IconedPath.svelte'
import { RawScript, ScriptService, type FlowModule, type PathScript } from '$lib/gen'
import { ScriptService, type FlowModule, type PathScript } from '$lib/gen'
import { workspaceStore } from '$lib/stores'
import { Lock, Unlock } from 'lucide-svelte'
export let flowModule: FlowModule | undefined = undefined
export let title: string | undefined = undefined
const languageColors: Record<RawScript.language, BadgeColor> = {
[RawScript.language.GO]: 'dark-indigo',
[RawScript.language.DENO]: 'dark-blue',
[RawScript.language.PYTHON3]: 'dark-green',
[RawScript.language.BASH]: 'dark-yellow'
}
let latestHash: string | undefined = undefined
async function loadLatestHash(value: PathScript) {
let script = await ScriptService.getScriptByPath({
@@ -33,7 +27,7 @@
</script>
<div
class="overflow-x-auto scrollbar-hidden flex items-center justify-between py-2 px-4 border-b border-gray-300 space-x-2 h-full max-h-12 flex-nowrap"
class="overflow-x-auto scrollbar-hidden flex items-center justify-between px-4 py-1 border-b border-gray-100 space-x-2 flex-nowrap"
>
{#if flowModule}
<span class="text-sm w-full mr-4">
@@ -41,9 +35,9 @@
{#if flowModule.value.type === 'identity'}
<span class="font-bold text-xs">Identity (input copied to output)</span>
{:else if flowModule?.value.type === 'rawscript'}
<Badge color={languageColors[flowModule?.value.language] ?? 'gray'} capitalize>
{flowModule?.value.language}
</Badge>
<div class="w-4 mx-0.5">
<LanguageIcon lang={flowModule.value.language} class="w-4 h-4" />
</div>
<input bind:value={flowModule.summary} placeholder={'Summary'} class="w-full grow" />
{:else if flowModule?.value.type === 'script' && 'path' in flowModule.value && flowModule.value.path}
<IconedPath path={flowModule.value.path} hash={flowModule.value.hash} class="grow" />
@@ -62,25 +56,27 @@
>
{/if}
<Button
title="Unlock hash to always use latest deployed version at that path"
size="xs"
btnClasses="text-gray-600 inline-flex gap-1 items-center"
color="light"
variant="border"
on:click={() => {
if (flowModule?.value.type == 'script') {
flowModule.value.hash = undefined
}
}}>Unlock hash</Button
}}><Unlock size={12} />hash</Button
>
{:else if latestHash}
<Button
title="Lock hash to always use this specific version"
color="light"
size="xs"
variant="border"
btnClasses="text-gray-600 inline-flex gap-1 items-center"
on:click={() => {
if (flowModule?.value.type == 'script') {
flowModule.value.hash = latestHash
}
}}>Lock hash</Button
}}><Lock size={12} />hash</Button
>
{/if}
<input bind:value={flowModule.summary} placeholder="Summary" class="w-full grow" />

View File

@@ -30,9 +30,9 @@
{#if module.value.type === 'script' || module.value.type === 'rawscript' || module.value.type == 'flow'}
<Popover
placement="bottom"
class="center-center rounded border p-2
class="center-center rounded p-2
{moduleRetry
? 'bg-blue-100 text-blue-800 border-blue-300 hover:bg-blue-200'
? 'bg-blue-100 text-blue-800 border border-blue-300 hover:bg-blue-200'
: 'bg-white text-gray-800 border-gray-300 hover:bg-gray-100'}"
on:click={() => dispatch('toggleRetry')}
>
@@ -41,10 +41,10 @@
</Popover>
<Popover
placement="bottom"
class="center-center rounded border p-2
class="center-center rounded p-2
{module.cache_ttl != undefined
? 'bg-blue-100 text-blue-800 border-blue-300 hover:bg-blue-200'
: 'bg-white text-gray-800 border-gray-300 hover:bg-gray-100'}"
? 'bg-blue-100 text-blue-800 border border-blue-300 hover:bg-blue-200'
: 'bg-white text-gray-800 hover:bg-gray-100'}"
on:click={() => dispatch('toggleCache')}
>
<Database size={14} />
@@ -52,10 +52,10 @@
</Popover>
<Popover
placement="bottom"
class="center-center rounded border p-2
class="center-center rounded p-2
{module.stop_after_if
? 'bg-blue-100 text-blue-800 border-blue-300 hover:bg-blue-200'
: 'bg-white text-gray-800 border-gray-300 hover:bg-gray-100'}"
? 'bg-blue-100 text-blue-800 border border-blue-300 hover:bg-blue-200'
: 'bg-white text-gray-800 hover:bg-gray-100'}"
on:click={() => dispatch('toggleStopAfterIf')}
>
<Square size={14} />
@@ -63,10 +63,10 @@
</Popover>
<Popover
placement="bottom"
class="center-center rounded border p-2
class="center-center rounded p-2
{module.suspend
? 'bg-blue-100 text-blue-800 border-blue-300 hover:bg-blue-200'
: 'bg-white text-gray-800 border-gray-300 hover:bg-gray-100'}"
? 'bg-blue-100 text-blue-800 border border-blue-300 hover:bg-blue-200'
: 'bg-white text-gray-800 hover:bg-gray-100'}"
on:click={() => dispatch('toggleSuspend')}
>
<PhoneIncoming size={14} />
@@ -74,10 +74,10 @@
</Popover>
<Popover
placement="bottom"
class="center-center rounded border p-2
class="center-center rounded p-2
{module.sleep
? 'bg-blue-100 text-blue-800 border-blue-300 hover:bg-blue-200'
: 'bg-white text-gray-800 border-gray-300 hover:bg-gray-100'}"
? 'bg-blue-100 text-blue-800 border border-blue-300 hover:bg-blue-200'
: 'bg-white text-gray-800 hover:bg-gray-100'}"
on:click={() => dispatch('toggleSleep')}
>
<Bed size={14} />
@@ -90,7 +90,6 @@
<Button
size="xs"
color="light"
variant="border"
on:click={async () => {
if (module.value.type == 'script') {
const hash = module.value.hash ?? (await getLatestHashForScript(module.value.path))
@@ -110,7 +109,6 @@
<Button
size="xs"
color="light"
variant="border"
on:click={() => dispatch('fork')}
startIcon={{ icon: faCodeBranch }}
iconOnly={false}
@@ -149,7 +147,7 @@
<Button
size="xs"
color="light"
variant="border"
btnClasses="text-gray-600"
startIcon={{ icon: faSave }}
on:click={() => dispatch('createScriptFromInlineScript')}
iconOnly={false}