UX improvements

This commit is contained in:
Ruben Fiszel
2022-12-13 21:04:53 +01:00
parent a85705e8c9
commit fac5b19d41
10 changed files with 111 additions and 83 deletions
@@ -6,7 +6,6 @@
import { Tab, Tabs, TabContent, Button } from './common'
import SchemaViewer from './SchemaViewer.svelte'
import FieldHeader from './FieldHeader.svelte'
import SvelteMarkdown from 'svelte-markdown'
import { copyToClipboard } from '../utils'
import FlowGraphViewer from './FlowGraphViewer.svelte'
@@ -49,7 +48,7 @@
<div class="flow-root w-full pb-4">
{#if !noSummary}
<h2 class="my-4">{flow.summary}</h2>
<SvelteMarkdown source={flow.description ?? ''} />
<div>{flow.description ?? ''}</div>
{/if}
<p class="font-black text-lg w-full my-4">
@@ -309,11 +309,7 @@
/>
{:else if step === 3}
<CenteredPage>
<ScriptSchema
bind:summary={script.summary}
bind:description={script.description}
bind:schema={script.schema}
/>
<ScriptSchema bind:description={script.description} bind:schema={script.schema} />
</CenteredPage>
{/if}
</div>
+11 -30
View File
@@ -8,11 +8,10 @@
import Highlight from 'svelte-highlight'
import json from 'svelte-highlight/languages/json'
import SvelteMarkdown from 'svelte-markdown'
import { Alert } from './common'
import autosize from 'svelte-autosize'
export let schema: Schema
export let summary: string
export let description: string | undefined
export function setSchema(newSchema: Schema) {
@@ -24,37 +23,19 @@
<h1 class="my-4">Advanced</h1>
<Tabs selected="ui">
<Tab value="ui">UI</Tab>
<Tab value="ui">Description & Arguments refinement</Tab>
<Tab value="jsonschema">JSON Schema</Tab>
<svelte:fragment slot="content">
<TabContent value="ui">
<h2 class="border-b pb-1 mt-6">Display</h2>
<div class="grid grid-cols-3 gap-2 mt-4">
<label>
<div class="text-gray-700 text-sm">Summary</div>
<textarea bind:value={summary} placeholder="Edit summary" class="text-sm" />
</label>
<label class="col-span-2">
<div class="text-gray-700 text-sm">Description</div>
<textarea
bind:value={description}
placeholder="Edit description. Markdown accepted."
class="text-sm"
/>
<div class="mt-1 px-2">
{#if description}
<div
class="prose !max-w-full !max-h-48 text-xs shadow-inner shadow-blue overflow-auto mt-1"
>
<SvelteMarkdown source={description} />
</div>
{:else}
<div class="text-xs text-gray-500"> Enter a description to see the preview </div>
{/if}
</div>
</label>
</div>
<h2 class="border-b pb-1 my-4">Arguments</h2>
<h2 class="border-b pb-1 mt-6 mb-4">Description</h2>
<textarea
use:autosize
bind:value={description}
placeholder="Edit description"
class="text-sm"
/>
<h2 class="border-b pb-1 mb-4 mt-8">Arguments</h2>
<Alert type="info" title="Synchronized with main signature">
Argument names, being required or not, and default values are derived from the main
signature of step 2 and cannot be edited directly. Change the main signature to edit them.
@@ -8,7 +8,6 @@
import Required from '$lib/components/Required.svelte'
import FlowCard from '../common/FlowCard.svelte'
import FlowSchedules from './FlowSchedules.svelte'
import SvelteMarkdown from 'svelte-markdown'
import Toggle from '$lib/components/Toggle.svelte'
import { Alert } from '$lib/components/common'
import { FlowGraph } from '$lib/components/graph'
@@ -66,7 +65,7 @@
<div class="font-bold pb-1 mt-4">Description preview</div>
{#if $flowStore.description}
<div class="prose max-h-48 mt-5 text-xs shadow-inner shadow-blue p-4 overflow-auto">
<SvelteMarkdown source={$flowStore.description} />
{$flowStore.description}
</div>
{:else}
<div class="text-sm text-gray-500"> Enter a description to see the preview </div>
+1 -3
View File
@@ -42,10 +42,8 @@ def main(no_default: str,
# the return value is then parsed and can be retrieved by other scripts conveniently
return {"splitted": name.split(), "user": user, "state": new_state}
`
export const DENO_INIT_CODE = `// reload the smart assistant on the top right if it dies to get autocompletion and syntax highlighting
// (Ctrl+space to cache dependencies on imports hover, Ctrl+S to autoformat and parse parameters).
export const DENO_INIT_CODE = `// Ctrl+space to cache dependencies on imports hover, Ctrl+S to format.
// you can use npm imports directly
// import { toWords } from "npm:number-to-words@1"
// import * as wmill from "https://deno.land/x/windmill@v${__pkg__.version}/mod.ts"
+33 -4
View File
@@ -8,7 +8,7 @@
<script lang="ts">
import { page } from '$app/stores'
import { FlowService, ScheduleService, type Flow, type Schedule } from '$lib/gen'
import { FlowService, JobService, ScheduleService, type Flow, type Schedule } from '$lib/gen'
import {
displayDaysAgo,
canWrite,
@@ -42,6 +42,8 @@
import JobArgs from '$lib/components/JobArgs.svelte'
import CronInput from '$lib/components/CronInput.svelte'
import Icon from 'svelte-awesome'
import RunForm from '$lib/components/RunForm.svelte'
import { goto } from '$app/navigation'
let userSettings: UserSettings
@@ -95,6 +97,20 @@
}
$: url = `${$page.url.hostname}/api/w/${$workspaceStore}/jobs/run/f/${flow?.path}`
let runForm: RunForm | undefined
let isValid = true
async function runFlow(scheduledForStr: string | undefined, args: Record<string, any>) {
const scheduledFor = scheduledForStr ? new Date(scheduledForStr).toISOString() : undefined
let run = await JobService.runFlowByPath({
workspace: $workspaceStore!,
path,
requestBody: args,
scheduledFor
})
await goto('/run/' + run + '?workspace=' + $workspaceStore)
}
</script>
<UserSettings bind:this={userSettings} />
@@ -212,11 +228,24 @@
{#if flow.archived}
<div class="bg-red-100 border-l-4 border-red-500 text-orange-700 p-4" role="alert">
<p class="font-bold">Archived</p>
<p>This version was archived</p>
<p>This flow was archived</p>
</div>
{/if}
<div class="prose text-sm box max-w-6xl w-full mt-4">
<SvelteMarkdown source={defaultIfEmptyString(flow?.description, 'No description')} />
<div class="mt-6 grid grid-cols-1 sm:grid-cols-3 gap-6">
<div class="col-span-2">
<RunForm
autofocus
detailed={false}
bind:isValid
bind:this={runForm}
runnable={flow}
runAction={runFlow}
/>
</div>
<div class="mt-6">
{defaultIfEmptyString(flow.description, 'No description')}
</div>
</div>
<div class="mt-4">
<FlowViewer {flow} noSummary={true} />
@@ -23,7 +23,6 @@
import { Button, Kbd, Skeleton } from '$lib/components/common'
import { faPlay, faScroll } from '@fortawesome/free-solid-svg-icons'
import SharedBadge from '$lib/components/SharedBadge.svelte'
import SvelteMarkdown from 'svelte-markdown'
const path = $page.params.path
let flow: Flow | undefined
@@ -54,7 +53,6 @@
requestBody: args,
scheduledFor
})
sendUserToast(`Job <a href='/run/${run}?workspace=${$workspaceStore}'>${run}</a> started`)
goto('/run/' + run + '?workspace=' + $workspaceStore)
}
@@ -128,7 +126,7 @@
</div>
</div>
<div class="prose text-sm box max-w-6xl w-full mt-8">
<SvelteMarkdown source={defaultIfEmptyString(flow.description, 'No description')} />
{defaultIfEmptyString(flow.description, 'No description')}
</div>
</div>
<RunForm
+1 -2
View File
@@ -16,7 +16,6 @@
import IconedResourceType from '$lib/components/IconedResourceType.svelte'
import ShareModal from '$lib/components/ShareModal.svelte'
import SharedBadge from '$lib/components/SharedBadge.svelte'
import SvelteMarkdown from 'svelte-markdown'
import { userStore, workspaceStore, oauthStore, superadmin } from '$lib/stores'
import SchemaEditor from '$lib/components/SchemaEditor.svelte'
import SchemaViewer from '$lib/components/SchemaViewer.svelte'
@@ -213,7 +212,7 @@
<div>
<h1 class="mb-8 mt-4"><IconedResourceType name={resourceTypeViewerObj.rt} /></h1>
<div class="py-2 box prose mb-8">
<SvelteMarkdown source={resourceTypeViewerObj.description} />
{resourceTypeViewerObj.description ?? ''}
</div>
<SchemaViewer schema={resourceTypeViewerObj.schema} />
</div>
@@ -8,7 +8,7 @@
<script lang="ts">
import { page } from '$app/stores'
import { ScriptService, type Script } from '$lib/gen'
import { JobService, ScriptService, type Script } from '$lib/gen'
import {
truncateHash,
sendUserToast,
@@ -54,6 +54,8 @@
import Skeleton from '../../../lib/components/common/skeleton/Skeleton.svelte'
import UserSettings from '$lib/components/UserSettings.svelte'
import Icon from 'svelte-awesome'
import RunForm from '$lib/components/RunForm.svelte'
import { goto } from '$app/navigation'
let userSettings: UserSettings
let script: Script | undefined
@@ -138,6 +140,23 @@
onDestroy(() => {
intervalId && clearInterval(intervalId)
})
let isValid = true
let runForm: RunForm | undefined
async function runScript(scheduledForStr: string | undefined, args: Record<string, any>) {
try {
const scheduledFor = scheduledForStr ? new Date(scheduledForStr).toISOString() : undefined
let run = await JobService.runScriptByHash({
workspace: $workspaceStore!,
hash: script?.hash ?? '',
requestBody: args,
scheduledFor
})
await goto('/run/' + run + '?workspace=' + $workspaceStore)
} catch (err) {
sendUserToast(`Could not create job: ${err.body}`, true)
}
}
</script>
{#if script}
@@ -178,6 +197,15 @@
</Button>
{/if}
{/if}
<Button
href={`/runs/${script.path}`}
size="md"
startIcon={{ icon: faList }}
color="light"
variant="border"
>
View Runs
</Button>
</div>
</div>
@@ -253,15 +281,6 @@
>
Schedule
</Button>
<Button
href={`/runs/${script.path}`}
size="xs"
startIcon={{ icon: faList }}
color="light"
variant="border"
>
View runs
</Button>
{#if Array.isArray(script.parent_hashes) && script.parent_hashes.length > 0}
<ButtonPopup
color="dark"
@@ -310,33 +329,39 @@
</div>
{/if}
<div class="max-w-2xl box mt-6">
<SvelteMarkdown source={defaultIfEmptyString(script.description, 'No description')} />
<div class="mt-6 grid grid-cols-1 sm:grid-cols-3 gap-6">
<div class="col-span-2">
<RunForm
autofocus
detailed={false}
bind:isValid
bind:this={runForm}
runnable={script}
runAction={runScript}
/>
</div>
<div class="mt-6">
{defaultIfEmptyString(script.description, 'No description')}
</div>
</div>
<div class="max-w-2xl">
<h3>
Arguments JSON schema
<Tooltip>
The jsonschema defines the constraints that the payload must respect to be compatible
with the input parameters of this script. The UI form is generated automatically from
the script jsonschema. See
<a href="https://json-schema.org/" class="text-blue-500"> jsonschema documentation </a>
</Tooltip>
</h3>
<Skeleton {loading} layout={[[15]]} />
<SchemaViewer schema={script.schema} />
</div>
<div>
<h3>Code</h3>
<div class="mt-8">
<Skeleton {loading} layout={[[20]]} />
<Tabs selected="code">
<Tab value="code">Code</Tab>
<Tab value="dependencies">Dependencies lock file</Tab>
<Tab value="arguments"
>Arguments JSON Schema
<Tooltip>
The jsonschema defines the constraints that the payload must respect to be compatible
with the input parameters of this script. The UI form is generated automatically from
the script jsonschema. See
<a href="https://json-schema.org/" class="text-blue-500">
jsonschema documentation
</a>
</Tooltip></Tab
>
<svelte:fragment slot="content">
<TabContent value="code">
<div class="border rounded-sm mt-2">
@@ -352,6 +377,11 @@
{/if}
</div>
</TabContent>
<TabContent value="arguments">
<div class="max-w-2xl">
<SchemaViewer schema={script.schema} />
</div>
</TabContent>
</svelte:fragment>
</Tabs>
</div>
@@ -25,7 +25,6 @@
import RunForm from '$lib/components/RunForm.svelte'
import { Alert, Badge, Button, Kbd, Skeleton } from '$lib/components/common'
import SharedBadge from '$lib/components/SharedBadge.svelte'
import SvelteMarkdown from 'svelte-markdown'
import { faPlay, faScroll } from '@fortawesome/free-solid-svg-icons'
$: hash = $page.params.hash
@@ -163,7 +162,7 @@
</div>
</div>
<div class="prose text-sm box max-w-6xl w-full mb-4 mt-8">
<SvelteMarkdown source={defaultIfEmptyString(script.description, 'No description')} />
{defaultIfEmptyString(script.description, 'No description')}
</div>
</div>