mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-10-27 16:02:43 +00:00
improve modularity for whitelabelling
This commit is contained in:
@@ -1 +1 @@
|
||||
export const base: string = import.meta.env.VITE_BASE_URL ?? ''
|
||||
export let base: string = import.meta.env.VITE_BASE_URL ?? ''
|
||||
|
||||
@@ -45,6 +45,7 @@
|
||||
import CodeCompletionStatus from './copilot/CodeCompletionStatus.svelte'
|
||||
import Popover from './Popover.svelte'
|
||||
import ResourceEditorDrawer from './ResourceEditorDrawer.svelte'
|
||||
import type { EditorBarUi } from './custom_ui'
|
||||
|
||||
export let lang: SupportedLanguage | 'bunnative' | undefined
|
||||
export let editor: Editor | undefined
|
||||
@@ -68,6 +69,7 @@
|
||||
export let args: Record<string, any>
|
||||
export let noHistory = false
|
||||
export let saveToWorkspace = false
|
||||
export let customUi: EditorBarUi = {}
|
||||
|
||||
let contextualVariablePicker: ItemPicker
|
||||
let variablePicker: ItemPicker
|
||||
@@ -313,6 +315,7 @@
|
||||
{/if}
|
||||
</DrawerContent>
|
||||
</Drawer>
|
||||
|
||||
<ItemPicker
|
||||
bind:this={contextualVariablePicker}
|
||||
pickCallback={(path, name) => {
|
||||
@@ -513,7 +516,7 @@ $res = json_decode(curl_exec($ch));`)
|
||||
class="rounded-full w-2 h-2 mx-2 {validCode ? 'bg-green-300' : 'bg-red-300'}"
|
||||
/>
|
||||
<div class="flex items-center gap-0.5">
|
||||
{#if showContextVarPicker}
|
||||
{#if showContextVarPicker && customUi?.contextVar != false}
|
||||
<Button
|
||||
title="Add context variable"
|
||||
color="light"
|
||||
@@ -526,7 +529,7 @@ $res = json_decode(curl_exec($ch));`)
|
||||
>+Context Var
|
||||
</Button>
|
||||
{/if}
|
||||
{#if showVarPicker}
|
||||
{#if showVarPicker && customUi?.variable != false}
|
||||
<Button
|
||||
title="Add variable"
|
||||
color="light"
|
||||
@@ -556,7 +559,7 @@ $res = json_decode(curl_exec($ch));`)
|
||||
</Button>
|
||||
{/if}
|
||||
|
||||
{#if showResourceTypePicker}
|
||||
{#if showResourceTypePicker && customUi?.type != false}
|
||||
<Button
|
||||
title="Add resource type"
|
||||
btnClasses="!font-medium text-tertiary"
|
||||
@@ -584,37 +587,41 @@ $res = json_decode(curl_exec($ch));`)
|
||||
Reset
|
||||
</Button>
|
||||
|
||||
{#if lang == 'deno' || lang == 'python3' || lang == 'go' || lang == 'bash'}
|
||||
<Button
|
||||
btnClasses="!font-medium text-tertiary"
|
||||
size="xs"
|
||||
spacingSize="md"
|
||||
color="light"
|
||||
on:click={() => editor?.reloadWebsocket()}
|
||||
startIcon={{
|
||||
icon: RotateCw,
|
||||
classes: websocketAlive[lang] == false ? 'animate-spin' : ''
|
||||
}}
|
||||
title="Reload assistants"
|
||||
>
|
||||
{#if !iconOnly}
|
||||
Assistants
|
||||
{/if}
|
||||
<span class="-my-1">
|
||||
{#if lang == 'deno'}
|
||||
(<span class={websocketAlive.deno ? 'green' : 'text-red-700'}>Deno</span>)
|
||||
{:else if lang == 'go'}
|
||||
(<span class={websocketAlive.go ? 'green' : 'text-red-700'}>Go</span>)
|
||||
{:else if lang == 'python3'}
|
||||
(<span class={websocketAlive.pyright ? 'green' : 'text-red-700'}>Pyright</span>
|
||||
<span class={websocketAlive.ruff ? 'green' : 'text-red-700'}>Ruff</span>)
|
||||
{:else if lang == 'bash'}
|
||||
(<span class={websocketAlive.shellcheck ? 'green' : 'text-red-700'}>Shellcheck</span>)
|
||||
{#if customUi?.assistants != false}
|
||||
{#if lang == 'deno' || lang == 'python3' || lang == 'go' || lang == 'bash'}
|
||||
<Button
|
||||
btnClasses="!font-medium text-tertiary"
|
||||
size="xs"
|
||||
spacingSize="md"
|
||||
color="light"
|
||||
on:click={() => editor?.reloadWebsocket()}
|
||||
startIcon={{
|
||||
icon: RotateCw,
|
||||
classes: websocketAlive[lang] == false ? 'animate-spin' : ''
|
||||
}}
|
||||
title="Reload assistants"
|
||||
>
|
||||
{#if !iconOnly}
|
||||
Assistants
|
||||
{/if}
|
||||
</span>
|
||||
</Button>
|
||||
<span class="-my-1">
|
||||
{#if lang == 'deno'}
|
||||
(<span class={websocketAlive.deno ? 'green' : 'text-red-700'}>Deno</span>)
|
||||
{:else if lang == 'go'}
|
||||
(<span class={websocketAlive.go ? 'green' : 'text-red-700'}>Go</span>)
|
||||
{:else if lang == 'python3'}
|
||||
(<span class={websocketAlive.pyright ? 'green' : 'text-red-700'}>Pyright</span>
|
||||
<span class={websocketAlive.ruff ? 'green' : 'text-red-700'}>Ruff</span>)
|
||||
{:else if lang == 'bash'}
|
||||
(<span class={websocketAlive.shellcheck ? 'green' : 'text-red-700'}>Shellcheck</span
|
||||
>)
|
||||
{/if}
|
||||
</span>
|
||||
</Button>
|
||||
{/if}
|
||||
{/if}
|
||||
{#if collabMode}
|
||||
|
||||
{#if collabMode && customUi?.multiplayer != false}
|
||||
<div class="flex items-center px-3">
|
||||
<Toggle
|
||||
options={{ right: '' }}
|
||||
@@ -648,11 +655,15 @@ $res = json_decode(curl_exec($ch));`)
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<FormatOnSave />
|
||||
|
||||
<ScriptGen {editor} {diffEditor} {lang} {iconOnly} {args} />
|
||||
|
||||
<CodeCompletionStatus />
|
||||
{#if customUi?.autoformatting != false}
|
||||
<FormatOnSave />
|
||||
{/if}
|
||||
{#if customUi?.aiGen != false}
|
||||
<ScriptGen {editor} {diffEditor} {lang} {iconOnly} {args} />
|
||||
{/if}
|
||||
{#if customUi?.aiFix != false}
|
||||
<CodeCompletionStatus />
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -671,7 +682,7 @@ $res = json_decode(curl_exec($ch));`)
|
||||
History
|
||||
</Button>
|
||||
{/if}
|
||||
{#if SCRIPT_EDITOR_SHOW_EXPLORE_OTHER_SCRIPTS}
|
||||
{#if SCRIPT_EDITOR_SHOW_EXPLORE_OTHER_SCRIPTS && customUi?.library != false}
|
||||
<Button
|
||||
btnClasses="!font-medium text-tertiary"
|
||||
size="xs"
|
||||
|
||||
@@ -80,7 +80,7 @@
|
||||
import { twMerge } from 'tailwind-merge'
|
||||
import CustomPopover from './CustomPopover.svelte'
|
||||
import Summary from './Summary.svelte'
|
||||
import type { WhitelabelCustomUi } from './custom_ui'
|
||||
import type { FlowBuilderWhitelabelCustomUi } from './custom_ui'
|
||||
|
||||
export let initialPath: string = ''
|
||||
export let pathStoreInit: string | undefined = undefined
|
||||
@@ -96,7 +96,7 @@
|
||||
})
|
||||
| undefined = undefined
|
||||
export let diffDrawer: DiffDrawer | undefined = undefined
|
||||
export let customUi: WhitelabelCustomUi = {}
|
||||
export let customUi: FlowBuilderWhitelabelCustomUi = {}
|
||||
|
||||
$: setContext('customUi', customUi)
|
||||
|
||||
@@ -403,7 +403,8 @@
|
||||
testStepStore,
|
||||
saveDraft,
|
||||
initialPath,
|
||||
flowInputsStore: writable<FlowInput>({})
|
||||
flowInputsStore: writable<FlowInput>({}),
|
||||
customUi
|
||||
})
|
||||
|
||||
async function loadSchedule() {
|
||||
@@ -489,18 +490,20 @@
|
||||
onClick: () => void
|
||||
}> = []
|
||||
|
||||
if (savedFlow?.draft_only === false || savedFlow?.draft_only === undefined) {
|
||||
dropdownItems.push({
|
||||
label: 'Exit & see details',
|
||||
onClick: () => dispatch('details', $pathStore)
|
||||
})
|
||||
}
|
||||
if (customUi.topBar?.extraDeployOptions != false) {
|
||||
if (savedFlow?.draft_only === false || savedFlow?.draft_only === undefined) {
|
||||
dropdownItems.push({
|
||||
label: 'Exit & see details',
|
||||
onClick: () => dispatch('details', $pathStore)
|
||||
})
|
||||
}
|
||||
|
||||
if (!newFlow) {
|
||||
dropdownItems.push({
|
||||
label: 'Fork',
|
||||
onClick: () => window.open(`/flows/add?template=${initialPath}`)
|
||||
})
|
||||
if (!newFlow) {
|
||||
dropdownItems.push({
|
||||
label: 'Fork',
|
||||
onClick: () => window.open(`/flows/add?template=${initialPath}`)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
let flowCopilotContext: FlowCopilotContext = {
|
||||
@@ -1026,7 +1029,7 @@
|
||||
|
||||
$: onCustomUiChange(customUi)
|
||||
|
||||
function onCustomUiChange(customUi: WhitelabelCustomUi | undefined) {
|
||||
function onCustomUiChange(customUi: FlowBuilderWhitelabelCustomUi | undefined) {
|
||||
moreItems = [
|
||||
...(customUi?.topBar?.history != false
|
||||
? [
|
||||
|
||||
@@ -12,6 +12,9 @@
|
||||
export let flowStateStore: Writable<FlowState> = writable({})
|
||||
export let selectedJobStep: string | undefined = undefined
|
||||
export let hideFlowResult = false
|
||||
export let hideTimeline = false
|
||||
export let hideDownloadInGraph = false
|
||||
export let hideNodeDefinition = false
|
||||
|
||||
export let isOwner = false
|
||||
export let wideResults = false
|
||||
@@ -23,7 +26,10 @@
|
||||
setContext<FlowStatusViewerContext>('FlowStatusViewer', {
|
||||
flowStateStore,
|
||||
suspendStatus,
|
||||
retryStatus
|
||||
retryStatus,
|
||||
hideDownloadInGraph,
|
||||
hideNodeDefinition,
|
||||
hideTimeline
|
||||
})
|
||||
|
||||
function loadOwner(path: string) {
|
||||
|
||||
@@ -32,8 +32,14 @@
|
||||
|
||||
const dispatch = createEventDispatcher()
|
||||
|
||||
let { flowStateStore, retryStatus, suspendStatus } =
|
||||
getContext<FlowStatusViewerContext>('FlowStatusViewer')
|
||||
let {
|
||||
flowStateStore,
|
||||
retryStatus,
|
||||
suspendStatus,
|
||||
hideDownloadInGraph,
|
||||
hideTimeline,
|
||||
hideNodeDefinition
|
||||
} = getContext<FlowStatusViewerContext>('FlowStatusViewer')
|
||||
|
||||
export let jobId: string
|
||||
export let workspaceId: string | undefined = undefined
|
||||
@@ -924,7 +930,7 @@
|
||||
</div>
|
||||
|
||||
<FlowGraphV2
|
||||
download
|
||||
download={!hideDownloadInGraph}
|
||||
minHeight={wrapperHeight}
|
||||
success={jobId != undefined && isSuccess(job?.['success'])}
|
||||
flowModuleStates={$localModuleStates}
|
||||
@@ -964,9 +970,14 @@
|
||||
class="border-l border-tertiary-inverse pt-1 overflow-auto min-h-[700px] flex flex-col z-0 h-full"
|
||||
>
|
||||
<Tabs bind:selected={rightColumnSelect}>
|
||||
<Tab value="timeline"><span class="font-semibold text-md">Timeline</span></Tab>
|
||||
{#if !hideTimeline}
|
||||
<Tab value="timeline"><span class="font-semibold text-md">Timeline</span></Tab>
|
||||
{/if}
|
||||
<Tab value="node_status"><span class="font-semibold">Node status</span></Tab>
|
||||
<Tab value="node_definition"><span class="font-semibold">Node definition</span></Tab>
|
||||
{#if !hideNodeDefinition}
|
||||
<Tab value="node_definition"><span class="font-semibold">Node definition</span></Tab
|
||||
>
|
||||
{/if}
|
||||
{#if Object.keys(job?.flow_status?.user_states ?? {}).length > 0}
|
||||
<Tab value="user_states"><span class="font-semibold">User States</span></Tab>
|
||||
{/if}
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
|
||||
export let tab: 'ui' | 'raw' | 'schema' = noGraph ? 'schema' : 'ui'
|
||||
export let noSummary = false
|
||||
export let noGraphDownload = false
|
||||
|
||||
let rawType: 'json' | 'yaml' = 'yaml'
|
||||
|
||||
@@ -88,7 +89,7 @@
|
||||
<div class="text-secondary text-xs italic mb-4">No inputs</div>
|
||||
{/if}
|
||||
|
||||
<FlowGraphViewer download {noSide} {flow} overflowAuto />
|
||||
<FlowGraphViewer download={!noGraphDownload} {noSide} {flow} overflowAuto />
|
||||
</div>
|
||||
</TabContent>
|
||||
<TabContent value="raw"
|
||||
|
||||
@@ -67,6 +67,7 @@
|
||||
import { createEventDispatcher } from 'svelte'
|
||||
import CustomPopover from './CustomPopover.svelte'
|
||||
import Summary from './Summary.svelte'
|
||||
import type { ScriptBuilderWhitelabelCustomUi } from './custom_ui'
|
||||
|
||||
export let script: NewScript
|
||||
export let fullyLoaded: boolean = true
|
||||
@@ -81,6 +82,7 @@
|
||||
export let disableHistoryChange = false
|
||||
export let replaceStateFn: (url: string) => void = (url) =>
|
||||
window.history.replaceState(null, '', url)
|
||||
export let customUi: ScriptBuilderWhitelabelCustomUi = {}
|
||||
|
||||
let metadataOpen =
|
||||
showMeta ||
|
||||
@@ -423,7 +425,7 @@
|
||||
|
||||
function computeDropdownItems(initialPath: string) {
|
||||
let dropdownItems: { label: string; onClick: () => void }[] =
|
||||
initialPath != ''
|
||||
initialPath != '' && customUi?.topBar?.extraDeployOptions != false
|
||||
? [
|
||||
{
|
||||
label: 'Deploy & Stay here',
|
||||
@@ -1050,32 +1052,34 @@
|
||||
{$scheduleStore.cron ?? ''}
|
||||
</Button>
|
||||
{/if}
|
||||
<div class="flex justify-start w-full border rounded-md overflow-hidden">
|
||||
<div>
|
||||
<button
|
||||
on:click={async () => {
|
||||
metadataOpen = true
|
||||
}}
|
||||
>
|
||||
<Badge
|
||||
color="gray"
|
||||
class="center-center !bg-surface-secondary !text-tertiary !h-[28px] !w-[70px] rounded-none hover:!bg-surface-hover transition-all"
|
||||
{#if customUi?.topBar?.path != false}
|
||||
<div class="flex justify-start w-full border rounded-md overflow-hidden">
|
||||
<div>
|
||||
<button
|
||||
on:click={async () => {
|
||||
metadataOpen = true
|
||||
}}
|
||||
>
|
||||
<Pen size={12} class="mr-2" /> Path
|
||||
</Badge>
|
||||
</button>
|
||||
<Badge
|
||||
color="gray"
|
||||
class="center-center !bg-surface-secondary !text-tertiary !h-[28px] !w-[70px] rounded-none hover:!bg-surface-hover transition-all"
|
||||
>
|
||||
<Pen size={12} class="mr-2" /> Path
|
||||
</Badge>
|
||||
</button>
|
||||
</div>
|
||||
<input
|
||||
type="text"
|
||||
readonly
|
||||
value={script.path}
|
||||
size={script.path?.length || 50}
|
||||
class="font-mono !text-xs !min-w-[96px] !max-w-[300px] !w-full !h-[28px] !my-0 !py-0 !border-l-0 !rounded-l-none !border-0 !shadow-none"
|
||||
on:focus={({ currentTarget }) => {
|
||||
currentTarget.select()
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<input
|
||||
type="text"
|
||||
readonly
|
||||
value={script.path}
|
||||
size={script.path?.length || 50}
|
||||
class="font-mono !text-xs !min-w-[96px] !max-w-[300px] !w-full !h-[28px] !my-0 !py-0 !border-l-0 !rounded-l-none !border-0 !shadow-none"
|
||||
on:focus={({ currentTarget }) => {
|
||||
currentTarget.select()
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
{#if $enterpriseLicense && initialPath != ''}
|
||||
@@ -1106,17 +1110,19 @@
|
||||
<span class="hidden lg:flex"> Diff </span>
|
||||
</div>
|
||||
</Button>
|
||||
<Button
|
||||
color="light"
|
||||
variant="border"
|
||||
size="xs"
|
||||
on:click={() => {
|
||||
metadataOpen = true
|
||||
}}
|
||||
startIcon={{ icon: Settings }}
|
||||
>
|
||||
<span class="hidden lg:flex"> Settings </span>
|
||||
</Button>
|
||||
{#if customUi?.topBar?.settings != false}
|
||||
<Button
|
||||
color="light"
|
||||
variant="border"
|
||||
size="xs"
|
||||
on:click={() => {
|
||||
metadataOpen = true
|
||||
}}
|
||||
startIcon={{ icon: Settings }}
|
||||
>
|
||||
<span class="hidden lg:flex"> Settings </span>
|
||||
</Button>
|
||||
{/if}
|
||||
<Button
|
||||
loading={loadingDraft}
|
||||
size="xs"
|
||||
@@ -1170,6 +1176,7 @@
|
||||
</div>
|
||||
|
||||
<ScriptEditor
|
||||
{customUi}
|
||||
collabMode
|
||||
edit={initialPath != ''}
|
||||
on:format={() => {
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
import DiffEditor from './DiffEditor.svelte'
|
||||
import { Clipboard, CornerDownLeft, Github, Play } from 'lucide-svelte'
|
||||
import { setLicense } from '$lib/enterpriseUtils'
|
||||
import type { ScriptEditorWhitelabelCustomUi } from './custom_ui'
|
||||
|
||||
// Exported
|
||||
export let schema: Schema | any = emptySchema()
|
||||
@@ -43,6 +44,7 @@
|
||||
export let noHistory = false
|
||||
export let saveToWorkspace = false
|
||||
export let watchChanges = false
|
||||
export let customUi: ScriptEditorWhitelabelCustomUi = {}
|
||||
|
||||
let websocketAlive = {
|
||||
pyright: false,
|
||||
@@ -243,6 +245,7 @@
|
||||
setCollaborationMode()
|
||||
}
|
||||
}}
|
||||
customUi={customUi?.editorBar}
|
||||
collabLive={wsProvider?.shouldConnect}
|
||||
{collabMode}
|
||||
{validCode}
|
||||
@@ -260,7 +263,7 @@
|
||||
{noHistory}
|
||||
{saveToWorkspace}
|
||||
/>
|
||||
{#if !noSyncFromGithub}
|
||||
{#if !noSyncFromGithub && customUi?.editorBar?.useVsCode != false}
|
||||
<div class="py-1">
|
||||
<Button
|
||||
target="_blank"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import type { SupportedLanguage } from '$lib/common'
|
||||
|
||||
export type WhitelabelCustomUi = {
|
||||
export type FlowBuilderWhitelabelCustomUi = {
|
||||
topBar?: {
|
||||
path?: boolean
|
||||
export?: boolean
|
||||
@@ -8,8 +8,18 @@ export type WhitelabelCustomUi = {
|
||||
aiBuilder?: boolean
|
||||
tutorials?: boolean
|
||||
diff?: boolean
|
||||
extraDeployOptions?: boolean
|
||||
}
|
||||
settingsPanel?: boolean
|
||||
settingsTabs?: {
|
||||
schedule?: boolean
|
||||
sharedDiretory?: boolean
|
||||
earlyStop?: boolean
|
||||
earlyReturn?: boolean
|
||||
workerGroup?: boolean
|
||||
concurrency?: boolean
|
||||
cache?: boolean
|
||||
}
|
||||
triggers?: boolean
|
||||
flowNode?: boolean
|
||||
hub?: boolean
|
||||
@@ -18,4 +28,31 @@ export type WhitelabelCustomUi = {
|
||||
stepAdvancedSettings?: boolean
|
||||
languages?: (SupportedLanguage | 'docker' | 'bunnative')[]
|
||||
scriptFork?: boolean
|
||||
editorBar?: EditorBarUi
|
||||
}
|
||||
|
||||
export type EditorBarUi = {
|
||||
contextVar?: boolean
|
||||
variable?: boolean
|
||||
type?: boolean
|
||||
assistants?: boolean
|
||||
multiplayer?: boolean
|
||||
autoformatting?: boolean
|
||||
aiGen?: boolean
|
||||
aiFix?: boolean
|
||||
library?: boolean
|
||||
useVsCode?: boolean
|
||||
}
|
||||
|
||||
export type ScriptEditorWhitelabelCustomUi = {
|
||||
editorBar?: EditorBarUi
|
||||
}
|
||||
|
||||
export type ScriptBuilderWhitelabelCustomUi = {
|
||||
topBar?: {
|
||||
path?: boolean
|
||||
settings?: boolean
|
||||
extraDeployOptions?: boolean
|
||||
}
|
||||
editorBar?: EditorBarUi
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
import { defaultScriptLanguages, processLangs } from '$lib/scripts'
|
||||
import type { SupportedLanguage } from '$lib/common'
|
||||
import DefaultScripts from '$lib/components/DefaultScripts.svelte'
|
||||
import type { WhitelabelCustomUi } from '$lib/components/custom_ui'
|
||||
import type { FlowBuilderWhitelabelCustomUi } from '$lib/components/custom_ui'
|
||||
|
||||
export let failureModule: boolean
|
||||
export let shouldDisableTriggerScripts: boolean = false
|
||||
@@ -55,7 +55,7 @@
|
||||
return kind == 'script' && !failureModule
|
||||
}
|
||||
|
||||
let customUi: undefined | WhitelabelCustomUi = getContext('customUi')
|
||||
let customUi: undefined | FlowBuilderWhitelabelCustomUi = getContext('customUi')
|
||||
</script>
|
||||
|
||||
<div class="p-4 h-full flex flex-col" id="flow-editor-flow-inputs">
|
||||
|
||||
@@ -55,7 +55,8 @@
|
||||
flowStore,
|
||||
pathStore,
|
||||
saveDraft,
|
||||
flowInputsStore
|
||||
flowInputsStore,
|
||||
customUi
|
||||
} = getContext<FlowEditorContext>('FlowEditorContext')
|
||||
|
||||
export let flowModule: FlowModule
|
||||
@@ -265,6 +266,7 @@
|
||||
{#if flowModule.value.type === 'rawscript' && !noEditor}
|
||||
<div class="border-b-2 shadow-sm px-1">
|
||||
<EditorBar
|
||||
customUi={customUi?.editorBar}
|
||||
{validCode}
|
||||
{editor}
|
||||
{diffEditor}
|
||||
|
||||
@@ -19,14 +19,14 @@
|
||||
import { sendUserToast } from '$lib/utils'
|
||||
import { workerTags } from '$lib/stores'
|
||||
import { getLatestHashForScript } from '$lib/scripts'
|
||||
import type { WhitelabelCustomUi } from '$lib/components/custom_ui'
|
||||
import type { FlowBuilderWhitelabelCustomUi } from '$lib/components/custom_ui'
|
||||
|
||||
export let module: FlowModule
|
||||
const { scriptEditorDrawer, flowStore, selectedId } =
|
||||
getContext<FlowEditorContext>('FlowEditorContext')
|
||||
|
||||
const dispatch = createEventDispatcher()
|
||||
let customUi: undefined | WhitelabelCustomUi = getContext('customUi')
|
||||
let customUi: undefined | FlowBuilderWhitelabelCustomUi = getContext('customUi')
|
||||
|
||||
loadWorkerGroups()
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
|
||||
export let noEditor: boolean
|
||||
|
||||
const { selectedId, flowStore, initialPath, previewArgs, pathStore, schedule } =
|
||||
const { selectedId, flowStore, initialPath, previewArgs, pathStore, schedule, customUi } =
|
||||
getContext<FlowEditorContext>('FlowEditorContext')
|
||||
|
||||
let hostname = BROWSER ? window.location.protocol + '//' + window.location.host : 'SSR'
|
||||
@@ -52,22 +52,33 @@
|
||||
<div class="h-full flex-1">
|
||||
<Tabs bind:selected={$selectedId}>
|
||||
<Tab value="settings-metadata">Metadata</Tab>
|
||||
{#if !noEditor}
|
||||
{#if !noEditor && customUi?.settingsTabs?.schedule != false}
|
||||
<Tab value="settings-schedule" active={$schedule.enabled}>Schedule</Tab>
|
||||
{/if}
|
||||
<Tab value="settings-same-worker" active={$flowStore.value.same_worker}>
|
||||
Shared Directory
|
||||
</Tab>
|
||||
<Tab value="settings-early-stop" active={Boolean($flowStore.value.skip_expr)}>
|
||||
Early Stop
|
||||
</Tab>
|
||||
<Tab value="settings-early-return" active={Boolean($flowStore.value.early_return)}>
|
||||
Early Return
|
||||
</Tab>
|
||||
<Tab value="settings-worker-group">Worker Group</Tab>
|
||||
<Tab value="settings-concurrency">Concurrency</Tab>
|
||||
<Tab value="settings-cache" active={Boolean($flowStore.value.cache_ttl)}>Cache</Tab>
|
||||
|
||||
{#if customUi?.settingsTabs?.sharedDiretory != false}
|
||||
<Tab value="settings-same-worker" active={$flowStore.value.same_worker}>
|
||||
Shared Directory
|
||||
</Tab>
|
||||
{/if}
|
||||
{#if customUi?.settingsTabs?.earlyStop != false}
|
||||
<Tab value="settings-early-stop" active={Boolean($flowStore.value.skip_expr)}>
|
||||
Early Stop
|
||||
</Tab>
|
||||
{/if}
|
||||
{#if customUi?.settingsTabs?.earlyReturn != false}
|
||||
<Tab value="settings-early-return" active={Boolean($flowStore.value.early_return)}>
|
||||
Early Return
|
||||
</Tab>
|
||||
{/if}
|
||||
{#if customUi?.settingsTabs?.workerGroup != false}
|
||||
<Tab value="settings-worker-group">Worker Group</Tab>
|
||||
{/if}
|
||||
{#if customUi?.settingsTabs?.concurrency != false}
|
||||
<Tab value="settings-concurrency">Concurrency</Tab>
|
||||
{/if}
|
||||
{#if customUi?.settingsTabs?.cache != false}
|
||||
<Tab value="settings-cache" active={Boolean($flowStore.value.cache_ttl)}>Cache</Tab>
|
||||
{/if}
|
||||
<svelte:fragment slot="content">
|
||||
<TabContent value="settings-metadata" class="p-4 h-full overflow-auto">
|
||||
<Section label="Metadata">
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
import StepGen from '$lib/components/copilot/StepGen.svelte'
|
||||
import type { FlowModule } from '$lib/gen'
|
||||
import BarsStaggered from '$lib/components/icons/BarsStaggered.svelte'
|
||||
import type { WhitelabelCustomUi } from '$lib/components/custom_ui'
|
||||
import type { FlowBuilderWhitelabelCustomUi } from '$lib/components/custom_ui'
|
||||
import { twMerge } from 'tailwind-merge'
|
||||
|
||||
const dispatch = createEventDispatcher()
|
||||
@@ -18,7 +18,7 @@
|
||||
export let disableAi = false
|
||||
|
||||
$: !open && (funcDesc = '')
|
||||
let customUi: undefined | WhitelabelCustomUi = getContext('customUi')
|
||||
let customUi: undefined | FlowBuilderWhitelabelCustomUi = getContext('customUi')
|
||||
</script>
|
||||
|
||||
<Menu
|
||||
|
||||
@@ -4,6 +4,7 @@ import type { Writable } from 'svelte/store'
|
||||
import type ScriptEditorDrawer from './content/ScriptEditorDrawer.svelte'
|
||||
import type { FlowState } from './flowState'
|
||||
import type { Schedule } from './scheduleUtils'
|
||||
import type { FlowBuilderWhitelabelCustomUi } from '../custom_ui'
|
||||
|
||||
export type FlowInput = Record<
|
||||
string,
|
||||
@@ -39,4 +40,5 @@ export type FlowEditorContext = {
|
||||
saveDraft: () => void
|
||||
initialPath: string
|
||||
flowInputsStore: Writable<FlowInput>
|
||||
customUi: FlowBuilderWhitelabelCustomUi
|
||||
}
|
||||
|
||||
@@ -33,6 +33,9 @@ export type FlowStatusViewerContext = {
|
||||
flowStateStore?: Writable<FlowState>
|
||||
retryStatus: Writable<Record<string, number | undefined>>
|
||||
suspendStatus: Writable<Record<string, { nb: number; job: Job }>>
|
||||
hideDownloadInGraph?: boolean
|
||||
hideTimeline?: boolean
|
||||
hideNodeDefinition?: boolean
|
||||
}
|
||||
export type GraphModuleState = {
|
||||
type: FlowStatusModule['type']
|
||||
|
||||
@@ -1,22 +1,61 @@
|
||||
<script lang="ts">
|
||||
import EditableSchemaWrapper from '$lib/components/schema/EditableSchemaWrapper.svelte'
|
||||
// import EditableSchemaWrapper from '$lib/components/schema/EditableSchemaWrapper.svelte'
|
||||
|
||||
let schema = {
|
||||
type: 'object',
|
||||
properties: {
|
||||
foo: {
|
||||
type: 'string',
|
||||
description: '',
|
||||
required: [],
|
||||
nullable: false,
|
||||
default: '',
|
||||
disableVariablePicker: false,
|
||||
disableCreate: false,
|
||||
password: false
|
||||
}
|
||||
},
|
||||
order: ['foo']
|
||||
}
|
||||
import FlowBuilder from '$lib/components/FlowBuilder.svelte'
|
||||
import ScriptBuilder from '$lib/components/ScriptBuilder.svelte'
|
||||
import type { OpenFlow } from '$lib/gen'
|
||||
import { writable, type Writable } from 'svelte/store'
|
||||
|
||||
// let schema = {
|
||||
// type: 'object',
|
||||
// properties: {
|
||||
// foo: {
|
||||
// type: 'string',
|
||||
// description: '',
|
||||
// required: [],
|
||||
// nullable: false,
|
||||
// default: '',
|
||||
// disableVariablePicker: false,
|
||||
// disableCreate: false,
|
||||
// password: false
|
||||
// }
|
||||
// },
|
||||
// order: ['foo']
|
||||
// }
|
||||
|
||||
// let flowStore: Writable<OpenFlow> = writable({
|
||||
// summary: 'foo',
|
||||
// value: {
|
||||
// modules: []
|
||||
// }
|
||||
// })
|
||||
// let flowStateStore: Writable<Record<string, any>> = writable({})
|
||||
</script>
|
||||
|
||||
<EditableSchemaWrapper on:change={() => console.log('FOO')} {schema} />
|
||||
<!-- <EditableSchemaWrapper on:change={() => console.log('FOO')} {schema} /> -->
|
||||
<!-- <FlowBuilder
|
||||
newFlow={false}
|
||||
initialPath="u/admin/foo"
|
||||
selectedId={undefined}
|
||||
{flowStore}
|
||||
{flowStateStore}
|
||||
customUi={{
|
||||
topBar: {
|
||||
extraDeployOptions: false
|
||||
},
|
||||
settingsTabs: {
|
||||
workerGroup: false
|
||||
},
|
||||
settingsPanel: false
|
||||
}}
|
||||
/> -->
|
||||
|
||||
<ScriptBuilder
|
||||
script={{
|
||||
summary: 'foo',
|
||||
path: 'u/admin/foo',
|
||||
description: 'foo',
|
||||
language: 'python3',
|
||||
content: 'print("foo")'
|
||||
}}
|
||||
/>
|
||||
|
||||
Reference in New Issue
Block a user