mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-08-22 00:01:34 +00:00
internal: instant npm run check
This commit is contained in:
+3
-1
@@ -25,4 +25,6 @@ src/lib/components/copilot/chat/__tests__/app/results/
|
||||
/playwright/.cache/
|
||||
/playwright/.auth/
|
||||
e2e/auth.json
|
||||
e2e/*.png
|
||||
e2e/*.png
|
||||
|
||||
.fast-check/
|
||||
@@ -97,6 +97,11 @@ The `resource()` utility:
|
||||
|
||||
After making frontend changes, you MUST run the following and fix all errors and warnings before considering the work done:
|
||||
|
||||
```bash
|
||||
npm run check:fast
|
||||
```
|
||||
|
||||
At the end of a PR to do final validation, you can do the longer one (2s for fast vs 50s for the slow one):
|
||||
```bash
|
||||
npm run check
|
||||
```
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
"build:utils": "vite build --config sharedUtils/vite.sharedUtils.config.js",
|
||||
"preview": "vite preview",
|
||||
"postinstall": "node -e \"if (require('fs').existsSync('./scripts/untar_ui_builder.js')) { require('child_process').execSync('node ./scripts/untar_ui_builder.js', {stdio: 'inherit'}) }\"",
|
||||
"check:fast": "bun --bun svelte-fast-check --no-svelte-warnings --incremental",
|
||||
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --threshold warning",
|
||||
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
|
||||
"lint": "prettier --ignore-path .gitignore --check --plugin-search-dir=. . && eslint --ignore-path .gitignore .",
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
import { workspaceStore } from '$lib/stores'
|
||||
import { emptySchema, emptyString } from '$lib/utils'
|
||||
import SchemaForm from './SchemaForm.svelte'
|
||||
import type SimpleEditor from './SimpleEditor.svelte'
|
||||
import Toggle from './Toggle.svelte'
|
||||
import TestConnection from './TestConnection.svelte'
|
||||
import SupabaseIcon from './icons/SupabaseIcon.svelte'
|
||||
@@ -115,7 +114,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
let rawCodeEditor: SimpleEditor | undefined = $state(undefined)
|
||||
let rawCodeEditor: { setCode: (code: string) => void } | undefined = $state(undefined)
|
||||
let textFileContent: string | undefined = $state(undefined)
|
||||
|
||||
function parseTextFileContent() {
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
import ObjectResourceInput from './ObjectResourceInput.svelte'
|
||||
import Range from './Range.svelte'
|
||||
import ResourcePicker from './ResourcePicker.svelte'
|
||||
import type SimpleEditor from './SimpleEditor.svelte'
|
||||
import Toggle from './Toggle.svelte'
|
||||
import type VariableEditor from './VariableEditor.svelte'
|
||||
import { twMerge } from 'tailwind-merge'
|
||||
@@ -97,7 +96,7 @@
|
||||
title?: string | undefined
|
||||
placeholder?: string | undefined
|
||||
order?: string[] | undefined
|
||||
editor?: SimpleEditor | undefined
|
||||
editor?: any | undefined
|
||||
orderEditable?: boolean
|
||||
shouldDispatchChanges?: boolean
|
||||
noDefaultOnSelectFirst?: boolean
|
||||
|
||||
@@ -11,16 +11,10 @@
|
||||
import EditorTheme from './EditorTheme.svelte'
|
||||
import Button from '$lib/components/common/button/Button.svelte'
|
||||
import { twMerge } from 'tailwind-merge'
|
||||
import type { ButtonType } from './common'
|
||||
import type { ButtonProp } from './diffEditorTypes'
|
||||
|
||||
const SIDE_BY_SIDE_MIN_WIDTH = 700
|
||||
|
||||
export interface ButtonProp {
|
||||
text: string
|
||||
color?: ButtonType.Color
|
||||
onClick: () => void
|
||||
}
|
||||
|
||||
interface Props {
|
||||
open?: boolean
|
||||
className?: string
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
<script lang="ts">
|
||||
import type { Schema } from '$lib/common'
|
||||
import type { InputCat, DynamicInput as DynamicInputTypes } from '$lib/utils'
|
||||
import { createEventDispatcher, getContext, untrack } from 'svelte'
|
||||
import { createEventDispatcher, getContext, onDestroy, untrack } from 'svelte'
|
||||
import { computeShow } from '$lib/utils'
|
||||
|
||||
import ArgInput from './ArgInput.svelte'
|
||||
@@ -98,7 +98,6 @@
|
||||
|
||||
let monaco: SimpleEditor | undefined = $state(undefined)
|
||||
let monacoTemplate: TemplateEditor | undefined = $state(undefined)
|
||||
let focusedPrev = false
|
||||
|
||||
let hidden = $state(false)
|
||||
|
||||
@@ -118,7 +117,13 @@
|
||||
|
||||
const propPickerWrapperContext: PropPickerWrapperContext | undefined =
|
||||
getContext<PropPickerWrapperContext>('PropPickerWrapper')
|
||||
const { inputMatches, focusProp, propPickerConfig, clearFocus } = propPickerWrapperContext ?? {}
|
||||
const {
|
||||
inputMatches,
|
||||
connectProp: focusProp,
|
||||
propPickerConfig,
|
||||
clearConnect: clearFocus,
|
||||
exprBeingEdited
|
||||
} = propPickerWrapperContext ?? {}
|
||||
|
||||
let inputCat = $derived(
|
||||
computeInputCat(
|
||||
@@ -301,7 +306,7 @@
|
||||
await tick()
|
||||
|
||||
// Activate connect mode
|
||||
focusProp?.(argName, 'connect', (path) => {
|
||||
focusProp?.(argName, (path) => {
|
||||
onPath(path)
|
||||
return true
|
||||
})
|
||||
@@ -394,6 +399,22 @@
|
||||
focused = true
|
||||
}
|
||||
|
||||
function updatePropsBeingEdited(focused: boolean) {
|
||||
let newPropsBeingEdited = [...$exprBeingEdited]
|
||||
if (focused) {
|
||||
newPropsBeingEdited.push(argName)
|
||||
} else {
|
||||
newPropsBeingEdited = newPropsBeingEdited.filter((p) => p !== argName)
|
||||
}
|
||||
if (!deepEqual(newPropsBeingEdited, $exprBeingEdited)) {
|
||||
exprBeingEdited.set(newPropsBeingEdited)
|
||||
}
|
||||
}
|
||||
|
||||
onDestroy(() => {
|
||||
updatePropsBeingEdited(false)
|
||||
})
|
||||
|
||||
let prevArg: any = undefined
|
||||
function onArgChange() {
|
||||
const newArg = { arg, propertyType, inputCat }
|
||||
@@ -426,13 +447,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
function updateFocused(newFocused: boolean) {
|
||||
if (focusedPrev && !newFocused && inputMatches) {
|
||||
$inputMatches = undefined
|
||||
}
|
||||
focusedPrev = focused
|
||||
}
|
||||
|
||||
let resourceTypes: string[] | undefined = $state(undefined)
|
||||
|
||||
async function loadResourceTypes() {
|
||||
@@ -457,10 +471,7 @@
|
||||
arg?.expr
|
||||
inputCat && propertyType && arg && untrack(() => onArgChange())
|
||||
})
|
||||
$effect(() => {
|
||||
;[focused]
|
||||
untrack(() => updateFocused(focused))
|
||||
})
|
||||
|
||||
$effect(() => {
|
||||
schema?.properties?.[argName]?.default && untrack(() => setDefaultCode())
|
||||
})
|
||||
@@ -472,9 +483,7 @@
|
||||
|
||||
untrack(() => handleFieldVisibility(schema, arg, otherArgs))
|
||||
})
|
||||
let connecting = $derived(
|
||||
$propPickerConfig?.propName == argName && $propPickerConfig?.insertionMode == 'connect'
|
||||
)
|
||||
let connecting = $derived($propPickerConfig?.propName == argName)
|
||||
let shouldShowS3ArrayHelper = $derived(
|
||||
inputCat === 'list' &&
|
||||
['s3object', 's3_object'].includes(schema?.properties?.[argName]?.items?.resourceType)
|
||||
@@ -557,13 +566,10 @@
|
||||
id="flow-editor-plug"
|
||||
{connecting}
|
||||
on:click={() => {
|
||||
if (
|
||||
$propPickerConfig?.propName == argName &&
|
||||
$propPickerConfig?.insertionMode == 'connect'
|
||||
) {
|
||||
if ($propPickerConfig?.propName == argName) {
|
||||
clearFocus()
|
||||
} else {
|
||||
focusProp?.(argName, 'connect', (path) => {
|
||||
focusProp?.(argName, (path) => {
|
||||
connectProperty(path)
|
||||
dispatch('change', { argName })
|
||||
return true
|
||||
@@ -700,13 +706,6 @@
|
||||
|
||||
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
||||
<div class="relative w-full" onkeyup={handleKeyUp}>
|
||||
<!-- {#if $propPickerConfig?.propName == argName && $propPickerConfig?.insertionMode == 'connect'}
|
||||
<span
|
||||
class={'text-white z-50 px-1 text-2xs py-0.5 font-bold rounded-t-sm w-fit absolute top-0 right-0 bg-blue-500'}
|
||||
>
|
||||
Connect input →
|
||||
</span>
|
||||
{/if} -->
|
||||
<!-- {inputCat}
|
||||
{propertyType} -->
|
||||
<div class="relative flex flex-row items-top gap-1 justify-between">
|
||||
@@ -851,8 +850,14 @@
|
||||
shouldBindKey={false}
|
||||
renderLineHighlight="none"
|
||||
hideLineNumbers
|
||||
on:focus={() => (focused = true)}
|
||||
on:blur={() => (focused = false)}
|
||||
on:focus={() => {
|
||||
focused = true
|
||||
updatePropsBeingEdited(true)
|
||||
}}
|
||||
on:blur={() => {
|
||||
focused = false
|
||||
updatePropsBeingEdited(false)
|
||||
}}
|
||||
on:change={() => {
|
||||
dispatch('change', { argName, arg })
|
||||
}}
|
||||
@@ -867,7 +872,7 @@
|
||||
class="mt-2"
|
||||
{connecting}
|
||||
onClick={() =>
|
||||
focusProp?.(argName, 'connect', (path) => {
|
||||
focusProp?.(argName, (path) => {
|
||||
appendPathToArrayExpr(arg.expr, path)
|
||||
return true
|
||||
})}
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
import { ExternalLink, Loader2 } from 'lucide-svelte'
|
||||
import YAML from 'yaml'
|
||||
import Toggle from './Toggle.svelte'
|
||||
import type SimpleEditor from './SimpleEditor.svelte'
|
||||
import SettingsFooter from './workspaceSettings/SettingsFooter.svelte'
|
||||
import SettingsPageHeader from './settings/SettingsPageHeader.svelte'
|
||||
|
||||
@@ -577,7 +576,7 @@
|
||||
|
||||
let yamlCode = $state('')
|
||||
let yamlCodeInitial = $state('')
|
||||
let yamlEditor: SimpleEditor | undefined = $state(undefined)
|
||||
let yamlEditor: any | undefined = $state(undefined)
|
||||
let yamlError = $state('')
|
||||
let showSensitive = $state(false)
|
||||
|
||||
@@ -1089,5 +1088,4 @@
|
||||
/>
|
||||
{/if}
|
||||
{/snippet}
|
||||
|
||||
</div>
|
||||
|
||||
@@ -7,16 +7,29 @@
|
||||
import CaptureIcon from '$lib/components/triggers/CaptureIcon.svelte'
|
||||
import CaptureButton from './triggers/CaptureButton.svelte'
|
||||
import SavedInputsPicker from './SavedInputsPicker.svelte'
|
||||
import { createEventDispatcher } from 'svelte'
|
||||
import { createEventDispatcher, untrack } from 'svelte'
|
||||
import CaptureTable from './triggers/CaptureTable.svelte'
|
||||
import RefreshButton from './common/button/RefreshButton.svelte'
|
||||
|
||||
export let runnableId: string = ''
|
||||
export let stablePathForCaptures: string = ''
|
||||
export let runnableType: any
|
||||
export let previewArgs: any
|
||||
export let isValid: boolean = true
|
||||
export let jsonView: boolean = false
|
||||
interface Props {
|
||||
runnableId?: string
|
||||
stablePathForCaptures?: string
|
||||
runnableType: any
|
||||
previewArgs: any
|
||||
isValid?: boolean
|
||||
jsonView?: boolean
|
||||
children?: import('svelte').Snippet
|
||||
}
|
||||
|
||||
let {
|
||||
runnableId = '',
|
||||
stablePathForCaptures = '',
|
||||
runnableType,
|
||||
previewArgs,
|
||||
isValid = true,
|
||||
jsonView = false,
|
||||
children
|
||||
}: Props = $props()
|
||||
|
||||
const dispatch = createEventDispatcher()
|
||||
|
||||
@@ -77,17 +90,22 @@
|
||||
]
|
||||
}
|
||||
|
||||
let rightHeight = 0
|
||||
let selectedTab: 'history' | 'saved_inputs' | 'captures' | undefined = undefined
|
||||
let dropdownItems: any
|
||||
let rightPanelOpen = false
|
||||
let rightHeight = $state(0)
|
||||
let selectedTab: 'history' | 'saved_inputs' | 'captures' | undefined = $state(undefined)
|
||||
let dropdownItems: any = $state()
|
||||
let rightPanelOpen = $state(false)
|
||||
|
||||
let savedInputsPicker: SavedInputsPicker | undefined = undefined
|
||||
let captureTable: CaptureTable | undefined = undefined
|
||||
let historicInputs: HistoricInputs | undefined = undefined
|
||||
$: (selectedTab, (dropdownItems = getDropdownItems()))
|
||||
let savedInputsPicker: SavedInputsPicker | undefined = $state(undefined)
|
||||
let captureTable: CaptureTable | undefined = $state(undefined)
|
||||
let historicInputs: HistoricInputs | undefined = $state(undefined)
|
||||
$effect(() => {
|
||||
selectedTab
|
||||
untrack(() => {
|
||||
dropdownItems = getDropdownItems()
|
||||
})
|
||||
})
|
||||
|
||||
let inputPanelSize = 70
|
||||
let inputPanelSize = $state(70)
|
||||
</script>
|
||||
|
||||
<div class="h-fit">
|
||||
@@ -99,7 +117,7 @@
|
||||
<Splitpanes class={!rightPanelOpen ? 'splitter-hidden' : ''}>
|
||||
<Pane bind:size={inputPanelSize} class="!overflow-visible" minSize={30}>
|
||||
<div class="relative w-full h-fit pr-12 pb-4" bind:clientHeight={rightHeight}>
|
||||
<slot />
|
||||
{@render children?.()}
|
||||
</div>
|
||||
</Pane>
|
||||
|
||||
@@ -108,14 +126,16 @@
|
||||
<div style="height: {rightHeight}px" class="border-t border-r pb-2">
|
||||
{#if selectedTab === 'history'}
|
||||
<FlowInputEditor title="History">
|
||||
<svelete:fragment slot="action">
|
||||
<div class="center-center">
|
||||
<RefreshButton
|
||||
loading={historicInputs?.loading() ?? false}
|
||||
onClick={() => historicInputs?.refresh()}
|
||||
/>
|
||||
</div>
|
||||
</svelete:fragment>
|
||||
{#snippet action()}
|
||||
<svelete:fragment>
|
||||
<div class="center-center">
|
||||
<RefreshButton
|
||||
loading={historicInputs?.loading() ?? false}
|
||||
onClick={() => historicInputs?.refresh()}
|
||||
/>
|
||||
</div>
|
||||
</svelete:fragment>
|
||||
{/snippet}
|
||||
<HistoricInputs
|
||||
bind:this={historicInputs}
|
||||
{runnableId}
|
||||
@@ -141,11 +161,13 @@
|
||||
</FlowInputEditor>
|
||||
{:else if selectedTab === 'captures'}
|
||||
<FlowInputEditor title="Trigger captures">
|
||||
<svelete:fragment slot="action">
|
||||
<div class="center-center">
|
||||
<CaptureButton on:openTriggers small={true} />
|
||||
</div>
|
||||
</svelete:fragment>
|
||||
{#snippet action()}
|
||||
<svelete:fragment>
|
||||
<div class="center-center">
|
||||
<CaptureButton on:openTriggers small={true} />
|
||||
</div>
|
||||
</svelete:fragment>
|
||||
{/snippet}
|
||||
<div class="h-full">
|
||||
<CaptureTable
|
||||
path={stablePathForCaptures}
|
||||
|
||||
@@ -47,7 +47,6 @@
|
||||
<script lang="ts">
|
||||
import { CornerDownLeft, Loader2 } from 'lucide-svelte'
|
||||
import Button from './common/button/Button.svelte'
|
||||
import type Editor from './Editor.svelte'
|
||||
import { runScriptAndPollResult } from './jobs/utils'
|
||||
import { workspaceStore } from '$lib/stores'
|
||||
import { sendUserToast } from '$lib/toast'
|
||||
@@ -161,7 +160,7 @@
|
||||
isRunning = false
|
||||
}
|
||||
}
|
||||
let editor = $state<Editor | null>(null)
|
||||
let editor = $state<any | null>(null)
|
||||
</script>
|
||||
|
||||
<Splitpanes>
|
||||
|
||||
@@ -10,13 +10,13 @@
|
||||
|
||||
let hover = Object.values(toastStates).some((state) => state.hover)
|
||||
for (const toastId in toastStates) {
|
||||
const state = toastStates[toastId]
|
||||
const st = toastStates[toastId]
|
||||
if (hover) continue
|
||||
if (state.elapsed >= state.duration) {
|
||||
if (st.elapsed >= st.duration) {
|
||||
delete toastStates[toastId]
|
||||
continue
|
||||
}
|
||||
state.elapsed += delta
|
||||
st.elapsed += delta
|
||||
}
|
||||
lastTime = time
|
||||
|
||||
@@ -36,18 +36,16 @@
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export type ToastType = AlertType
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
import { toast } from '@zerodevx/svelte-toast'
|
||||
import Button from './common/button/Button.svelte'
|
||||
import { type ToastAction } from '$lib/toast'
|
||||
import { type ToastAction, type ToastType } from '$lib/toast'
|
||||
import { processMessage } from './toast'
|
||||
import { onDestroy, untrack } from 'svelte'
|
||||
import { twMerge } from 'tailwind-merge'
|
||||
import { classes, icons, type AlertType } from '$lib/components/common/alert/model'
|
||||
import { classes, icons } from '$lib/components/common/alert/model'
|
||||
|
||||
interface Props {
|
||||
message: string
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
import DrawerContent from './common/drawer/DrawerContent.svelte'
|
||||
import Alert from './common/alert/Alert.svelte'
|
||||
import Toggle from './Toggle.svelte'
|
||||
import type SimpleEditor from './SimpleEditor.svelte'
|
||||
import { sendUserToast } from '$lib/toast'
|
||||
import { canWrite, isOwner } from '$lib/utils'
|
||||
import ToggleButtonGroup from './common/toggleButton-v2/ToggleButtonGroup.svelte'
|
||||
@@ -129,7 +128,7 @@
|
||||
}
|
||||
}
|
||||
let editorKind: 'plain' | 'json' | 'yaml' = $state('plain')
|
||||
let editor: SimpleEditor | undefined = $state(undefined)
|
||||
let editor: any | undefined = $state(undefined)
|
||||
</script>
|
||||
|
||||
<Drawer bind:this={drawer} size="900px">
|
||||
|
||||
@@ -1,13 +1,16 @@
|
||||
<script lang="ts">
|
||||
import { createEventDispatcher } from 'svelte'
|
||||
import { WorkspaceDependenciesService, type ScriptLang, type WorkspaceDependencies } from '$lib/gen'
|
||||
import {
|
||||
WorkspaceDependenciesService,
|
||||
type ScriptLang,
|
||||
type WorkspaceDependencies
|
||||
} from '$lib/gen'
|
||||
import { workspaceStore } from '$lib/stores'
|
||||
import { Button } from './common'
|
||||
import Drawer from './common/drawer/Drawer.svelte'
|
||||
import DrawerContent from './common/drawer/DrawerContent.svelte'
|
||||
import Alert from './common/alert/Alert.svelte'
|
||||
import DependenciesDeploymentWarning from './DependenciesDeploymentWarning.svelte'
|
||||
import type SimpleEditor from './SimpleEditor.svelte'
|
||||
import { sendUserToast } from '$lib/toast'
|
||||
import Section from './Section.svelte'
|
||||
import { Loader2, Rocket, Code2, FolderOpen } from 'lucide-svelte'
|
||||
@@ -20,13 +23,16 @@
|
||||
// Helper function to get full filename
|
||||
export function getFullFilename(language: ScriptLang, name: string | null): string | null {
|
||||
const extension = getFileExtension(language)
|
||||
if (extension == null) return null;
|
||||
if (extension == null) return null
|
||||
return name ? `${name}.${extension}` : extension
|
||||
}
|
||||
|
||||
export function getWorkspaceDependenciesPath(name: string | null, language: ScriptLang): string | null {
|
||||
export function getWorkspaceDependenciesPath(
|
||||
name: string | null,
|
||||
language: ScriptLang
|
||||
): string | null {
|
||||
const extension = getFileExtension(language)
|
||||
if (extension == null) return null;
|
||||
if (extension == null) return null
|
||||
return name ? `dependencies/${name}.${extension}` : `dependencies/${extension}`
|
||||
}
|
||||
|
||||
@@ -52,16 +58,16 @@
|
||||
// Load existing workspace defaults from API
|
||||
async function loadExistingWorkspaceDefaults(): Promise<void> {
|
||||
if (!$workspaceStore) return
|
||||
|
||||
|
||||
try {
|
||||
const workspaceDeps = await WorkspaceDependenciesService.listWorkspaceDependencies({
|
||||
workspace: $workspaceStore
|
||||
const workspaceDeps = await WorkspaceDependenciesService.listWorkspaceDependencies({
|
||||
workspace: $workspaceStore
|
||||
})
|
||||
|
||||
|
||||
// Reset defaults
|
||||
existingWorkspaceDefaults = {}
|
||||
workspaceDefaultIds = {}
|
||||
|
||||
|
||||
// Check for workspace defaults (where name is null) for each language
|
||||
workspaceDeps.forEach((dep) => {
|
||||
if (dep.name === null) {
|
||||
@@ -83,9 +89,9 @@
|
||||
}
|
||||
|
||||
function goToWorkspaceDefault(): void {
|
||||
const language = workspaceDependencies.language;
|
||||
const defaultId = workspaceDefaultIds[language];
|
||||
|
||||
const language = workspaceDependencies.language
|
||||
const defaultId = workspaceDefaultIds[language]
|
||||
|
||||
if (defaultId) {
|
||||
// Close current drawer and edit the workspace default
|
||||
drawer?.closeDrawer()
|
||||
@@ -101,7 +107,7 @@
|
||||
|
||||
let workspaceDependenciesName: string = $state('')
|
||||
let workspaceDependenciesType = $state<'workspace' | 'named'>('workspace')
|
||||
|
||||
|
||||
// Language options for workspace dependencies - only supported languages
|
||||
const LANGUAGE_OPTIONS = [
|
||||
{ value: 'python3', label: 'Python' },
|
||||
@@ -130,19 +136,19 @@ numpy>=1.24.0
|
||||
}
|
||||
}`,
|
||||
|
||||
// go: `module mymod
|
||||
// go: `module mymod
|
||||
|
||||
// go 1.25
|
||||
// go 1.25
|
||||
|
||||
// require (
|
||||
// rsc.io/quote v1.5.2
|
||||
// github.com/gorilla/mux v1.8.1
|
||||
// github.com/lib/pq v1.10.9
|
||||
// github.com/joho/godotenv v1.5.1
|
||||
// github.com/sirupsen/logrus v1.9.3
|
||||
// github.com/stretchr/testify v1.8.4
|
||||
// )
|
||||
// `,
|
||||
// require (
|
||||
// rsc.io/quote v1.5.2
|
||||
// github.com/gorilla/mux v1.8.1
|
||||
// github.com/lib/pq v1.10.9
|
||||
// github.com/joho/godotenv v1.5.1
|
||||
// github.com/sirupsen/logrus v1.9.3
|
||||
// github.com/stretchr/testify v1.8.4
|
||||
// )
|
||||
// `,
|
||||
|
||||
php: `{
|
||||
"require": {
|
||||
@@ -172,7 +178,7 @@ numpy>=1.24.0
|
||||
let existingWorkspaceDefaults: Record<string, boolean> = $state({})
|
||||
let workspaceDefaultIds: Record<string, number> = $state({})
|
||||
let can_write = $state(true)
|
||||
let editor: SimpleEditor | undefined = $state(undefined)
|
||||
let editor: any | undefined = $state(undefined)
|
||||
let showWarning = $state(false)
|
||||
let currentImportedPath: string | null = $state(null)
|
||||
|
||||
@@ -184,10 +190,14 @@ numpy>=1.24.0
|
||||
|
||||
// Track when editor is ready
|
||||
let editorReady = $state(false)
|
||||
|
||||
|
||||
// Calculate when deploy button should be disabled
|
||||
let isDisabled = $derived(!can_write || !valid || (workspaceDependenciesType === 'named' && workspaceDependenciesName.trim() === ''))
|
||||
|
||||
let isDisabled = $derived(
|
||||
!can_write ||
|
||||
!valid ||
|
||||
(workspaceDependenciesType === 'named' && workspaceDependenciesName.trim() === '')
|
||||
)
|
||||
|
||||
$effect(() => {
|
||||
if (editor && !editorReady) {
|
||||
editor.setCode(workspaceDependencies.content)
|
||||
@@ -227,7 +237,7 @@ numpy>=1.24.0
|
||||
workspaceDependencies = {
|
||||
content: LANGUAGE_TEMPLATES.python3,
|
||||
language: 'python3',
|
||||
description: "",
|
||||
description: ''
|
||||
}
|
||||
edit = false
|
||||
initialName = undefined
|
||||
@@ -245,24 +255,29 @@ numpy>=1.24.0
|
||||
drawer?.openDrawer()
|
||||
}
|
||||
|
||||
export async function editWorkspaceDependencies(id: number, name: string | undefined, language: ScriptLang): Promise<void> {
|
||||
export async function editWorkspaceDependencies(
|
||||
id: number,
|
||||
name: string | undefined,
|
||||
language: ScriptLang
|
||||
): Promise<void> {
|
||||
edit = true
|
||||
|
||||
|
||||
try {
|
||||
// Call the get-latest endpoint to get actual content
|
||||
const workspaceDeps = await WorkspaceDependenciesService.getLatestWorkspaceDependencies({
|
||||
const workspaceDeps = await WorkspaceDependenciesService.getLatestWorkspaceDependencies({
|
||||
workspace: $workspaceStore!,
|
||||
language,
|
||||
name: name || undefined
|
||||
})
|
||||
|
||||
|
||||
can_write = true // TODO: Implement proper permissions
|
||||
|
||||
if (workspaceDeps) {
|
||||
workspaceDependencies = {
|
||||
content: workspaceDeps.content,
|
||||
language: workspaceDeps.language,
|
||||
description: workspaceDeps.description || `${name || 'Default'} requirements for ${language}`
|
||||
description:
|
||||
workspaceDeps.description || `${name || 'Default'} requirements for ${language}`
|
||||
}
|
||||
} else {
|
||||
sendUserToast('Enforced dependencies not found', true)
|
||||
@@ -273,7 +288,7 @@ numpy>=1.24.0
|
||||
sendUserToast(`Failed to load enforced dependencies: ${error.message}`, true)
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
initialName = name
|
||||
initialLanguage = language
|
||||
workspaceDependenciesName = name || ''
|
||||
@@ -294,11 +309,14 @@ numpy>=1.24.0
|
||||
content: workspaceDependencies.content,
|
||||
language: workspaceDependencies.language as any,
|
||||
workspace_id: $workspaceStore!,
|
||||
description: workspaceDependencies.description,
|
||||
description: workspaceDependencies.description
|
||||
}
|
||||
})
|
||||
|
||||
const displayName = workspaceDependenciesType === 'workspace' ? `workspace default for ${workspaceDependencies.language}` : workspaceDependenciesName
|
||||
const displayName =
|
||||
workspaceDependenciesType === 'workspace'
|
||||
? `workspace default for ${workspaceDependencies.language}`
|
||||
: workspaceDependenciesName
|
||||
sendUserToast(`Deployed enforced dependencies: ${displayName}`)
|
||||
dispatch('create')
|
||||
drawer?.closeDrawer()
|
||||
@@ -335,12 +353,13 @@ numpy>=1.24.0
|
||||
function cancelDeploy(): void {
|
||||
showWarning = false
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<Drawer bind:this={drawer} size="1200px">
|
||||
<DrawerContent
|
||||
title={edit ? `Deploy ${getFullFilename(workspaceDependencies.language, workspaceDependenciesType === 'workspace' ? null : workspaceDependenciesName)}` : 'Add enforced dependencies'}
|
||||
title={edit
|
||||
? `Deploy ${getFullFilename(workspaceDependencies.language, workspaceDependenciesType === 'workspace' ? null : workspaceDependenciesName)}`
|
||||
: 'Add enforced dependencies'}
|
||||
on:close={drawer?.closeDrawer}
|
||||
>
|
||||
<div class="flex flex-col gap-8">
|
||||
@@ -353,15 +372,20 @@ numpy>=1.24.0
|
||||
{#if showWarning && currentImportedPath}
|
||||
<DependenciesDeploymentWarning
|
||||
importedPath={currentImportedPath}
|
||||
title={workspaceDependenciesType === 'workspace' ? "Redeploy impacted runnables?" : "Deployment Warning"}
|
||||
confirmText={workspaceDependenciesType === 'workspace' ? "I'm Sure - Deploy Default" : "Deploy Anyway"}
|
||||
title={workspaceDependenciesType === 'workspace'
|
||||
? 'Redeploy impacted runnables?'
|
||||
: 'Deployment Warning'}
|
||||
confirmText={workspaceDependenciesType === 'workspace'
|
||||
? "I'm Sure - Deploy Default"
|
||||
: 'Deploy Anyway'}
|
||||
onConfirm={confirmDeploy}
|
||||
onCancel={cancelDeploy}
|
||||
isUnnamedDefault={workspaceDependenciesType === 'workspace'}
|
||||
language={LANGUAGE_OPTIONS.find(opt => opt.value === workspaceDependencies.language)?.label || workspaceDependencies.language}
|
||||
language={LANGUAGE_OPTIONS.find((opt) => opt.value === workspaceDependencies.language)
|
||||
?.label || workspaceDependencies.language}
|
||||
/>
|
||||
{/if}
|
||||
|
||||
|
||||
<Section label="Enforced Dependencies Type">
|
||||
<div class="flex flex-col gap-4">
|
||||
{#if hasWorkspaceDefault(workspaceDependencies.language) && !edit}
|
||||
@@ -385,7 +409,10 @@ numpy>=1.24.0
|
||||
</Button>
|
||||
</div>
|
||||
{:else}
|
||||
<ToggleButtonGroup bind:selected={workspaceDependenciesType} disabled={!can_write || edit}>
|
||||
<ToggleButtonGroup
|
||||
bind:selected={workspaceDependenciesType}
|
||||
disabled={!can_write || edit}
|
||||
>
|
||||
{#snippet children({ item })}
|
||||
<ToggleButton
|
||||
disabled={!can_write || edit}
|
||||
@@ -413,8 +440,8 @@ numpy>=1.24.0
|
||||
{/if}
|
||||
<div class="text-sm text-tertiary">
|
||||
<FolderOpen size={16} class="inline mr-2" />
|
||||
Default Enforced Dependencies are used when no specific Dependencies are referenced from runnables.
|
||||
Named dependencies can be referenced by scripts using
|
||||
Default Enforced Dependencies are used when no specific Dependencies are referenced from
|
||||
runnables. Named dependencies can be referenced by scripts using
|
||||
<a
|
||||
href="https://www.windmill.dev/docs/core_concepts/workspace_dependencies"
|
||||
target="_blank"
|
||||
@@ -436,7 +463,9 @@ numpy>=1.24.0
|
||||
/>
|
||||
<div class="text-sm text-tertiary">
|
||||
<Code2 size={16} class="inline mr-2" />
|
||||
{edit ? 'Language cannot be changed after creation.' : 'Select the programming language these dependencies are for. This will load a default template.'}
|
||||
{edit
|
||||
? 'Language cannot be changed after creation.'
|
||||
: 'Select the programming language these dependencies are for. This will load a default template.'}
|
||||
</div>
|
||||
</div>
|
||||
</Section>
|
||||
@@ -450,7 +479,8 @@ numpy>=1.24.0
|
||||
class="input"
|
||||
/>
|
||||
<div class="text-sm text-tertiary mt-2">
|
||||
Provide a brief description to help others understand the purpose of these enforced dependencies.
|
||||
Provide a brief description to help others understand the purpose of these enforced
|
||||
dependencies.
|
||||
</div>
|
||||
</Section>
|
||||
|
||||
@@ -476,9 +506,8 @@ numpy>=1.24.0
|
||||
{/await}
|
||||
</div>
|
||||
</Section>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
{#snippet actions()}
|
||||
<Button
|
||||
on:click={handleDeployClick}
|
||||
|
||||
@@ -2,15 +2,13 @@
|
||||
import { AlertTriangle, Edit2 } from 'lucide-svelte'
|
||||
import { Button } from '../common'
|
||||
import ExploreAssetButton, { assetCanBeExplored } from '../ExploreAssetButton.svelte'
|
||||
import S3FilePicker from '../S3FilePicker.svelte'
|
||||
import DbManagerDrawer from '../DBManagerDrawer.svelte'
|
||||
import ResourceEditorDrawer from '../ResourceEditorDrawer.svelte'
|
||||
import type { Asset } from '$lib/gen'
|
||||
import Popover from '../meltComponents/Popover.svelte'
|
||||
|
||||
type Props = {
|
||||
s3FilePicker?: S3FilePicker | undefined
|
||||
dbManagerDrawer?: DbManagerDrawer | undefined
|
||||
s3FilePicker?: any | undefined
|
||||
dbManagerDrawer?: any | undefined
|
||||
resourceEditorDrawer?: ResourceEditorDrawer | undefined
|
||||
resourceDataCache: Record<string, string | undefined>
|
||||
asset: Asset
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
import type { ButtonType } from './common'
|
||||
|
||||
export interface ButtonProp {
|
||||
text: string
|
||||
color?: ButtonType.Color
|
||||
onClick: () => void
|
||||
}
|
||||
@@ -178,9 +178,10 @@
|
||||
|
||||
setContext<PropPickerWrapperContext>('PropPickerWrapper', {
|
||||
inputMatches: writable(undefined),
|
||||
focusProp: () => {},
|
||||
connectProp: () => {},
|
||||
propPickerConfig: writable(undefined),
|
||||
clearFocus: () => {}
|
||||
clearConnect: () => {},
|
||||
exprBeingEdited: writable([])
|
||||
})
|
||||
</script>
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
import FlowModuleSkip from './FlowModuleSkip.svelte'
|
||||
import FlowPlugConnect from '$lib/components/FlowPlugConnect.svelte'
|
||||
|
||||
import PropPickerWrapper, { CONNECT } from '../propPicker/PropPickerWrapper.svelte'
|
||||
import PropPickerWrapper from '../propPicker/PropPickerWrapper.svelte'
|
||||
import type { PropPickerContext } from '$lib/components/prop_picker'
|
||||
import TabsV2 from '$lib/components/common/tabs/TabsV2.svelte'
|
||||
import { useUiIntent } from '$lib/components/copilot/chat/flow/useUiIntent'
|
||||
@@ -122,7 +122,7 @@
|
||||
}
|
||||
|
||||
$effect(() => {
|
||||
editor && currentEditor.set({ type: 'iterator', editor, stepId: mod.id })
|
||||
editor && (currentEditor as any).set({ type: 'iterator', editor, stepId: mod.id })
|
||||
})
|
||||
|
||||
let suggestion: string | undefined = $state(undefined)
|
||||
@@ -360,10 +360,9 @@
|
||||
</Tooltip>
|
||||
</div>
|
||||
<FlowPlugConnect
|
||||
connecting={$flowPropPickerConfig?.insertionMode == CONNECT}
|
||||
connecting={$flowPropPickerConfig != undefined}
|
||||
on:click={() => {
|
||||
const config = {
|
||||
insertionMode: CONNECT,
|
||||
onSelect: (code) => {
|
||||
setExpr(code)
|
||||
return true
|
||||
@@ -405,7 +404,7 @@
|
||||
notSelectable
|
||||
pickableProperties={stepPropPicker.pickableProperties}
|
||||
on:select={({ detail }) => {
|
||||
if ($flowPropPickerConfig?.insertionMode == CONNECT) {
|
||||
if ($flowPropPickerConfig) {
|
||||
setExpr(detail)
|
||||
flowPropPickerConfig.set(undefined)
|
||||
return
|
||||
|
||||
@@ -36,7 +36,8 @@
|
||||
import FlowModuleMockTransitionMessage from './FlowModuleMockTransitionMessage.svelte'
|
||||
import Tooltip from '$lib/components/Tooltip.svelte'
|
||||
import { SecondsInput } from '$lib/components/common'
|
||||
import DiffEditor, { type ButtonProp } from '$lib/components/DiffEditor.svelte'
|
||||
import DiffEditor from '$lib/components/DiffEditor.svelte'
|
||||
import type { ButtonProp } from '$lib/components/diffEditorTypes'
|
||||
import FlowModuleTimeout from './FlowModuleTimeout.svelte'
|
||||
import HighlightCode from '$lib/components/HighlightCode.svelte'
|
||||
import ToggleButtonGroup from '$lib/components/common/toggleButton-v2/ToggleButtonGroup.svelte'
|
||||
@@ -140,7 +141,7 @@
|
||||
}
|
||||
])
|
||||
|
||||
let editor: Editor | undefined = $state()
|
||||
let editor: any | undefined = $state()
|
||||
let diffEditor: DiffEditor | undefined = $state()
|
||||
let modulePreview: ModulePreview | undefined = $state()
|
||||
let websocketAlive = $state({
|
||||
|
||||
@@ -1,80 +0,0 @@
|
||||
<script lang="ts">
|
||||
import ObjectViewer from '$lib/components/propertyPicker/ObjectViewer.svelte'
|
||||
import AnimatedButton from '$lib/components/common/button/AnimatedButton.svelte'
|
||||
import Popover from '$lib/components/meltComponents/Popover.svelte'
|
||||
import Tooltip from '$lib/components/meltComponents/Tooltip.svelte'
|
||||
import { Plug } from 'lucide-svelte'
|
||||
import { twMerge } from 'tailwind-merge'
|
||||
import type { PropPickerContext } from '$lib/components/prop_picker'
|
||||
import { getContext } from 'svelte'
|
||||
|
||||
import { tick } from 'svelte'
|
||||
|
||||
export let json = {}
|
||||
export let prefix = ''
|
||||
|
||||
let isConnecting = false
|
||||
|
||||
const { flowPropPickerConfig } = getContext<PropPickerContext>('PropPickerContext')
|
||||
|
||||
async function updateConnecting() {
|
||||
await tick()
|
||||
isConnecting = $flowPropPickerConfig?.insertionMode === 'connect'
|
||||
}
|
||||
|
||||
$: $flowPropPickerConfig, updateConnecting()
|
||||
</script>
|
||||
|
||||
<button
|
||||
on:click|preventDefault|stopPropagation={(e) => {
|
||||
e.preventDefault()
|
||||
e.stopPropagation()
|
||||
}}
|
||||
on:keydown|preventDefault|stopPropagation
|
||||
data-prop-picker
|
||||
title=""
|
||||
>
|
||||
<AnimatedButton
|
||||
animate={isConnecting}
|
||||
wrapperClasses="h-[20px] w-[20px] center-center"
|
||||
baseRadius="9999px"
|
||||
marginWidth="1px"
|
||||
>
|
||||
<Popover
|
||||
floatingConfig={{ strategy: 'fixed', placement: 'bottom-start' }}
|
||||
closeOnOtherPopoverOpen={true}
|
||||
>
|
||||
<svelte:fragment slot="trigger" let:isOpen>
|
||||
<Tooltip disablePopup={isOpen}>
|
||||
<svelte:fragment slot="text">node outputs</svelte:fragment>
|
||||
<button
|
||||
class={twMerge(
|
||||
'rounded-full center-center h-[18px] w-[18px]',
|
||||
isConnecting
|
||||
? 'bg-surface text-blue-500'
|
||||
: 'outline-[1px] outline dark:outline-gray-500 outline-gray-300 duration-0 bg-blue-500 hover:bg-blue-700 text-white'
|
||||
)}
|
||||
>
|
||||
<Plug size={12} strokeWidth={2} />
|
||||
</button>
|
||||
</Tooltip>
|
||||
</svelte:fragment>
|
||||
<svelte:fragment slot="content">
|
||||
<div class="p-4 max-h-[50vh] overflow-y-auto" data-prop-picker>
|
||||
<ObjectViewer
|
||||
{json}
|
||||
topBrackets={false}
|
||||
pureViewer={false}
|
||||
{prefix}
|
||||
on:select={({ detail }) => {
|
||||
if ($flowPropPickerConfig?.onSelect(detail)) {
|
||||
$flowPropPickerConfig?.clearFocus()
|
||||
}
|
||||
}}
|
||||
allowCopy={!$flowPropPickerConfig}
|
||||
/>
|
||||
</div>
|
||||
</svelte:fragment>
|
||||
</Popover>
|
||||
</AnimatedButton>
|
||||
</button>
|
||||
@@ -50,9 +50,7 @@
|
||||
|
||||
const zoom = $derived.by(useSvelteFlow().getZoom)
|
||||
|
||||
let showConnecting = $derived(
|
||||
isConnectingCandidate && $flowPropPickerConfig?.insertionMode === 'connect'
|
||||
)
|
||||
let showConnecting = $derived(isConnectingCandidate && $flowPropPickerConfig != undefined)
|
||||
|
||||
function selectConnection(value: string) {
|
||||
if ($flowPropPickerConfig?.onSelect(value)) {
|
||||
|
||||
@@ -6,18 +6,14 @@
|
||||
propName?: string
|
||||
onSelect: SelectCallback
|
||||
clearFocus: () => void
|
||||
insertionMode: 'append' | 'connect' | 'insert'
|
||||
}
|
||||
|
||||
export type PropPickerWrapperContext = {
|
||||
propPickerConfig: Writable<PropPickerConfig | undefined>
|
||||
inputMatches: Writable<{ word: string; value: string }[] | undefined>
|
||||
focusProp: (
|
||||
propName: string,
|
||||
insertionMode: 'append' | 'connect' | 'insert',
|
||||
onSelect: SelectCallback
|
||||
) => void
|
||||
clearFocus: () => void
|
||||
connectProp: (propName: string, onSelect: SelectCallback) => void
|
||||
clearConnect: () => void
|
||||
exprBeingEdited: Writable<string[]>
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -77,10 +73,9 @@
|
||||
setContext<PropPickerWrapperContext>('PropPickerWrapper', {
|
||||
propPickerConfig,
|
||||
inputMatches,
|
||||
focusProp: (propName, insertionMode, onSelect) => {
|
||||
connectProp: (propName, onSelect) => {
|
||||
const config = {
|
||||
propName,
|
||||
insertionMode,
|
||||
onSelect,
|
||||
clearFocus: () => {
|
||||
propPickerConfig.set(undefined)
|
||||
@@ -98,10 +93,11 @@
|
||||
})
|
||||
}
|
||||
},
|
||||
clearFocus: () => {
|
||||
clearConnect: () => {
|
||||
flowPropPickerConfig.set(undefined)
|
||||
propPickerConfig.set(undefined)
|
||||
}
|
||||
},
|
||||
exprBeingEdited: writable<string[]>([])
|
||||
})
|
||||
|
||||
async function getPropPickerElements(): Promise<HTMLElement[]> {
|
||||
@@ -134,14 +130,11 @@
|
||||
<Pane minSize={20} size={40} class="!transition-none z-1000 relative {paneClass}">
|
||||
<div bind:clientHeight={rightPaneHeight} class="min-h-40 h-full !bg-surface-secondary">
|
||||
<AnimatedButton
|
||||
animate={$propPickerConfig?.insertionMode == 'connect'}
|
||||
animate={$propPickerConfig != undefined}
|
||||
baseRadius="4px"
|
||||
wrapperClasses="prop-picker-inputs h-full w-full pt-1"
|
||||
marginWidth="3px"
|
||||
ringColor={$propPickerConfig?.insertionMode == 'insert' ||
|
||||
$propPickerConfig?.insertionMode == 'append'
|
||||
? '#3b82f6'
|
||||
: 'transparent'}
|
||||
ringColor="transparent"
|
||||
animationDuration="4s"
|
||||
>
|
||||
{#if result != undefined && !pickableProperties}
|
||||
|
||||
@@ -13,7 +13,7 @@ import type { Asset, AssetWithAccessType } from '../assets/lib'
|
||||
import type S3FilePicker from '../S3FilePicker.svelte'
|
||||
import type ResourceEditorDrawer from '../ResourceEditorDrawer.svelte'
|
||||
import type { ModulesTestStates } from '../modulesTest.svelte'
|
||||
import type { ButtonProp } from '$lib/components/DiffEditor.svelte'
|
||||
import type { ButtonProp } from '$lib/components/diffEditorTypes'
|
||||
|
||||
import type { SelectionManager } from '../graph/selectionUtils.svelte'
|
||||
import type { InferAssetsSqlQueryDetails } from '$lib/infer'
|
||||
|
||||
@@ -225,7 +225,6 @@
|
||||
type AssetWithAltAccessType
|
||||
} from '$lib/components/assets/lib'
|
||||
import { twMerge } from 'tailwind-merge'
|
||||
import type { FlowGraphAssetContext } from '$lib/components/flows/types'
|
||||
import { getContext } from 'svelte'
|
||||
import ExploreAssetButton, { assetCanBeExplored } from '../../../ExploreAssetButton.svelte'
|
||||
import { Tooltip } from '$lib/components/meltComponents'
|
||||
@@ -243,7 +242,7 @@
|
||||
data: AssetN['data']
|
||||
}
|
||||
|
||||
const flowGraphAssetsCtx = getContext<FlowGraphAssetContext | undefined>('FlowGraphAssetContext')
|
||||
const flowGraphAssetsCtx = getContext<any | undefined>('FlowGraphAssetContext')
|
||||
|
||||
let { data }: Props = $props()
|
||||
|
||||
|
||||
@@ -11,19 +11,22 @@
|
||||
import { createEventDispatcher } from 'svelte'
|
||||
import { ArrowBigUp } from 'lucide-svelte'
|
||||
|
||||
export let item
|
||||
export let depth: number = 0
|
||||
|
||||
const dispatch = createEventDispatcher()
|
||||
|
||||
let deleteConfirmedCallback: (() => void) | undefined = undefined
|
||||
let shareModal: ShareModal
|
||||
let moveDrawer: MoveDrawer
|
||||
let deploymentDrawer: DeployWorkspaceDrawer
|
||||
let deleteConfirmedCallback: (() => void) | undefined = $state(undefined)
|
||||
let shareModal: any | undefined = $state()
|
||||
let moveDrawer: any | undefined = $state()
|
||||
let deploymentDrawer: any | undefined = $state()
|
||||
|
||||
let menuOpen: boolean = false
|
||||
export let showCode: (path: string, summary: string) => void
|
||||
export let showEditButton: boolean = true
|
||||
let menuOpen: boolean = $state(false)
|
||||
interface Props {
|
||||
item: any
|
||||
depth?: number
|
||||
showCode: (path: string, summary: string) => void
|
||||
showEditButton?: boolean
|
||||
}
|
||||
|
||||
let { item, depth = 0, showCode, showEditButton = true }: Props = $props()
|
||||
</script>
|
||||
|
||||
{#if item.type == 'script'}
|
||||
|
||||
@@ -1,10 +1,7 @@
|
||||
import type { Writable } from 'svelte/store'
|
||||
import type { PickableProperties } from '$lib/components/flows/previousResults'
|
||||
|
||||
type InsertionMode = 'append' | 'connect' | 'insert'
|
||||
|
||||
export type FlowPropPickerConfig = {
|
||||
insertionMode: InsertionMode
|
||||
clearFocus: () => void
|
||||
onSelect: (path: string) => boolean
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<script lang="ts">
|
||||
import { ResourceService, VariableService } from '$lib/gen'
|
||||
import { workspaceStore } from '$lib/stores'
|
||||
import { getContext, onDestroy } from 'svelte'
|
||||
import { getContext, onDestroy, untrack } from 'svelte'
|
||||
import { Badge, Button } from '../common'
|
||||
import type { PropPickerWrapperContext } from '../flows/propPicker/PropPickerWrapper.svelte'
|
||||
|
||||
@@ -13,22 +13,35 @@
|
||||
import type { PropPickerContext } from '../prop_picker'
|
||||
import Scrollable from '../Scrollable.svelte'
|
||||
|
||||
export let pickableProperties: PickableProperties
|
||||
export let displayContext = true
|
||||
export let error: boolean = false
|
||||
export let allowCopy = false
|
||||
export let previousId: string | undefined = undefined
|
||||
export let flow_env: Record<string, any> | undefined = undefined
|
||||
export let result: any | undefined = undefined
|
||||
export let extraResults: any = undefined
|
||||
interface Props {
|
||||
pickableProperties: PickableProperties
|
||||
displayContext?: boolean
|
||||
error?: boolean
|
||||
allowCopy?: boolean
|
||||
previousId?: string | undefined
|
||||
flow_env?: Record<string, any> | undefined
|
||||
result?: any | undefined
|
||||
extraResults?: any
|
||||
}
|
||||
|
||||
let variables: Record<string, string> = {}
|
||||
let resources: Record<string, any> = {}
|
||||
let displayVariable = false
|
||||
let displayResources = false
|
||||
let displayFlowEnv = false
|
||||
let {
|
||||
pickableProperties,
|
||||
displayContext = true,
|
||||
error = false,
|
||||
allowCopy = false,
|
||||
previousId = undefined,
|
||||
flow_env = undefined,
|
||||
result = undefined,
|
||||
extraResults = undefined
|
||||
}: Props = $props()
|
||||
|
||||
let allResultsCollapsed = true
|
||||
let variables: Record<string, string> = $state({})
|
||||
let resources: Record<string, any> = $state({})
|
||||
let displayVariable = $state(false)
|
||||
let displayResources = $state(false)
|
||||
let displayFlowEnv = $state(false)
|
||||
|
||||
let allResultsCollapsed = $state(true)
|
||||
let collapsableInitialState:
|
||||
| {
|
||||
allResultsCollapsed: boolean
|
||||
@@ -38,24 +51,26 @@
|
||||
}
|
||||
| undefined
|
||||
|
||||
let filterActive = false
|
||||
|
||||
const EMPTY_STRING = ''
|
||||
let search = ''
|
||||
let search = $state('')
|
||||
|
||||
const { propPickerConfig, inputMatches } =
|
||||
getContext<PropPickerWrapperContext>('PropPickerWrapper')
|
||||
const {
|
||||
propPickerConfig,
|
||||
inputMatches,
|
||||
exprBeingEdited: propsBeingEdited
|
||||
} = getContext<PropPickerWrapperContext>('PropPickerWrapper')
|
||||
|
||||
const { pickablePropertiesFiltered } = getContext<PropPickerContext>('PropPickerContext')
|
||||
$: $pickablePropertiesFiltered = pickableProperties
|
||||
$effect(() => {
|
||||
$pickablePropertiesFiltered = pickableProperties
|
||||
})
|
||||
|
||||
let flowInputsFiltered: any = pickableProperties.flow_input
|
||||
let resultByIdFiltered: any = pickableProperties.priorIds
|
||||
let flowEnvFiltered: any = pickableProperties.flow_env
|
||||
let flowInputsFiltered: any = $state(pickableProperties.flow_input)
|
||||
let resultByIdFiltered: any = $state(pickableProperties.priorIds)
|
||||
let flowEnvFiltered: any = $state(pickableProperties.flow_env)
|
||||
|
||||
let timeout: number | undefined
|
||||
function onSearch(search: string) {
|
||||
filterActive = false
|
||||
if (timeout) {
|
||||
clearTimeout(timeout)
|
||||
}
|
||||
@@ -77,11 +92,14 @@
|
||||
}, 50)
|
||||
}
|
||||
|
||||
$: suggestedPropsFiltered =
|
||||
let suggestedPropsFiltered = $derived(
|
||||
$propPickerConfig && $propPickerConfig.propName
|
||||
? keepByKey(pickableProperties.priorIds, $propPickerConfig.propName ?? '')
|
||||
: undefined
|
||||
$: search != undefined && onSearch(search)
|
||||
)
|
||||
$effect(() => {
|
||||
search != undefined && untrack(() => onSearch(search))
|
||||
})
|
||||
|
||||
async function loadVariables() {
|
||||
variables = Object.fromEntries(
|
||||
@@ -103,9 +121,9 @@
|
||||
)
|
||||
}
|
||||
|
||||
let filteringFlowInputsOrResult = ''
|
||||
let filteringFlowInputsOrResult = $state('')
|
||||
async function filterPickableProperties() {
|
||||
if (!$propPickerConfig || !filterActive) {
|
||||
if ($propsBeingEdited?.length == 0 || $propPickerConfig || !$inputMatches?.length) {
|
||||
if (search === EMPTY_STRING) {
|
||||
flowInputsFiltered = pickableProperties.flow_input
|
||||
resultByIdFiltered = pickableProperties.priorIds
|
||||
@@ -114,7 +132,6 @@
|
||||
filteringFlowInputsOrResult = ''
|
||||
return
|
||||
}
|
||||
|
||||
if (!$inputMatches?.some((match) => match.word === 'flow_input')) {
|
||||
flowInputsFiltered = {}
|
||||
}
|
||||
@@ -202,30 +219,15 @@
|
||||
collapsableInitialState = undefined
|
||||
}
|
||||
|
||||
async function updateFilterActive() {
|
||||
const prev = filterActive
|
||||
|
||||
filterActive = Boolean(
|
||||
$inputMatches &&
|
||||
$inputMatches?.length > 0 &&
|
||||
$propPickerConfig?.insertionMode === 'insert' &&
|
||||
search === EMPTY_STRING
|
||||
)
|
||||
|
||||
if (prev && !filterActive) {
|
||||
flowInputsFiltered = pickableProperties.flow_input
|
||||
resultByIdFiltered = pickableProperties.priorIds
|
||||
flowEnvFiltered = pickableProperties.flow_env
|
||||
}
|
||||
}
|
||||
|
||||
async function updateState() {
|
||||
await updateFilterActive()
|
||||
await filterPickableProperties()
|
||||
await updateCollapsable()
|
||||
}
|
||||
|
||||
$: (search, $inputMatches, $propPickerConfig, pickableProperties, updateState())
|
||||
$effect(() => {
|
||||
;[search, $inputMatches, $propPickerConfig, pickableProperties, $propsBeingEdited]
|
||||
untrack(() => updateState())
|
||||
})
|
||||
|
||||
onDestroy(() => {
|
||||
clearTimeout(timeout)
|
||||
@@ -265,7 +267,7 @@
|
||||
/>
|
||||
</div>
|
||||
{/if}
|
||||
{#if flowInputsFiltered && (Object.keys(flowInputsFiltered ?? {}).length > 0 || !filterActive)}
|
||||
{#if flowInputsFiltered && Object.keys(flowInputsFiltered ?? {}).length > 0}
|
||||
<span class={categoryTitleClasses}>Flow Input</span>
|
||||
<div class={categoryContentClasses}>
|
||||
<ObjectViewer
|
||||
@@ -338,7 +340,7 @@
|
||||
</div>
|
||||
{/if}
|
||||
{#if Object.keys(pickableProperties.priorIds).length > 0}
|
||||
{#if !filterActive && suggestedPropsFiltered && Object.keys(suggestedPropsFiltered).length > 0}
|
||||
{#if suggestedPropsFiltered && Object.keys(suggestedPropsFiltered).length > 0}
|
||||
<span class={categoryTitleClasses}>Suggested Results</span>
|
||||
<div class={categoryContentClasses}>
|
||||
<ObjectViewer
|
||||
@@ -369,7 +371,7 @@
|
||||
{/if}
|
||||
|
||||
{#if displayContext}
|
||||
{#if !filterActive || $inputMatches?.some((match) => match.word === 'variable')}
|
||||
{#if $inputMatches?.some((match) => match.word === 'variable')}
|
||||
<span class={categoryTitleClasses}>Variables</span>
|
||||
<div class={categoryContentClasses}>
|
||||
{#if displayVariable}
|
||||
@@ -406,7 +408,7 @@
|
||||
{/if}
|
||||
</div>
|
||||
{/if}
|
||||
{#if !filterActive || $inputMatches?.some((match) => match.word === 'resource')}
|
||||
{#if $inputMatches?.some((match) => match.word === 'resource')}
|
||||
<span class={categoryTitleClasses}>Resources</span>
|
||||
<div class={categoryContentClasses}>
|
||||
{#if displayResources}
|
||||
@@ -443,7 +445,7 @@
|
||||
{/if}
|
||||
</div>
|
||||
{/if}
|
||||
{#if flow_env && Object.keys(flow_env).length > 0 && (!filterActive || $inputMatches?.some((match) => match.word === 'flow_env'))}
|
||||
{#if flow_env && Object.keys(flow_env).length > 0 && $inputMatches?.some((match) => match.word === 'flow_env')}
|
||||
<div class="overflow-y-auto pb-2">
|
||||
<span class="font-normal text-xs text-secondary">Flow Env Variables:</span>
|
||||
|
||||
|
||||
@@ -48,7 +48,7 @@
|
||||
fields?: Record<string, StaticAppInput | UserAppInput | CtxAppInput>
|
||||
path: string
|
||||
onRun: () => Promise<void>
|
||||
editor?: Editor | undefined
|
||||
editor?: any | undefined
|
||||
lastDeployedCode?: string | undefined
|
||||
/** Called when code is selected in the editor */
|
||||
onSelectionChange?: (
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
<script lang="ts">
|
||||
import { preventDefault } from 'svelte/legacy'
|
||||
|
||||
import Toggle from '$lib/components/Toggle.svelte'
|
||||
import { SettingService } from '$lib/gen'
|
||||
import type { CriticalAlert } from '$lib/gen'
|
||||
@@ -9,31 +11,36 @@
|
||||
import CriticalAlertTable from './CriticalAlertTable.svelte'
|
||||
import Alert from '$lib/components/common/alert/Alert.svelte'
|
||||
import { sendUserToast } from '$lib/toast'
|
||||
import { untrack } from 'svelte'
|
||||
|
||||
export let updateHasUnacknowledgedCriticalAlerts
|
||||
export let getCriticalAlerts
|
||||
export let acknowledgeCriticalAlert
|
||||
export let acknowledgeAllCriticalAlerts
|
||||
export let numUnacknowledgedCriticalAlerts
|
||||
let filteredAlerts: CriticalAlert[] = $state([])
|
||||
|
||||
let filteredAlerts: CriticalAlert[] = []
|
||||
|
||||
let isRefreshing = false
|
||||
let hasCriticalAlertChannels = true
|
||||
|
||||
$: loading = isRefreshing
|
||||
|
||||
$: if (numUnacknowledgedCriticalAlerts) {
|
||||
refreshAlerts()
|
||||
}
|
||||
let isRefreshing = $state(false)
|
||||
let hasCriticalAlertChannels = $state(true)
|
||||
|
||||
// Pagination
|
||||
let page = 1
|
||||
let page = $state(1)
|
||||
let pageSize = 10
|
||||
let hasMore = true
|
||||
let hasMore = $state(true)
|
||||
|
||||
let hideAcknowledged = false
|
||||
export let workspaceContext = false
|
||||
let hideAcknowledged = $state(false)
|
||||
interface Props {
|
||||
updateHasUnacknowledgedCriticalAlerts: any
|
||||
getCriticalAlerts: any
|
||||
acknowledgeCriticalAlert: any
|
||||
acknowledgeAllCriticalAlerts: any
|
||||
numUnacknowledgedCriticalAlerts: any
|
||||
workspaceContext?: boolean
|
||||
}
|
||||
|
||||
let {
|
||||
updateHasUnacknowledgedCriticalAlerts,
|
||||
getCriticalAlerts,
|
||||
acknowledgeCriticalAlert,
|
||||
acknowledgeAllCriticalAlerts,
|
||||
numUnacknowledgedCriticalAlerts,
|
||||
workspaceContext = $bindable(false)
|
||||
}: Props = $props()
|
||||
|
||||
async function acknowledgeAll() {
|
||||
await acknowledgeAllCriticalAlerts()
|
||||
@@ -108,10 +115,21 @@
|
||||
getAlerts(true)
|
||||
}
|
||||
|
||||
let totalNumberOfAlerts = $state(0)
|
||||
$effect(() => {
|
||||
if (numUnacknowledgedCriticalAlerts) {
|
||||
untrack(() => {
|
||||
refreshAlerts()
|
||||
})
|
||||
}
|
||||
})
|
||||
// Update filter change handlers
|
||||
$: (hideAcknowledged, workspaceContext, onFiltersChange())
|
||||
|
||||
let totalNumberOfAlerts = 0
|
||||
$effect(() => {
|
||||
;[hideAcknowledged, workspaceContext, onFiltersChange]
|
||||
untrack(() => {
|
||||
onFiltersChange()
|
||||
})
|
||||
})
|
||||
</script>
|
||||
|
||||
<List gap="sm">
|
||||
@@ -119,7 +137,7 @@
|
||||
<div class="w-full">
|
||||
<Alert title="No critical alert channels are set up" type="warning" size="xs">
|
||||
Go to the
|
||||
<a href="/#superadmin-settings" on:click|preventDefault={goToCoreTab}>Instance settings</a>
|
||||
<a href="/#superadmin-settings" onclick={preventDefault(goToCoreTab)}>Instance settings</a>
|
||||
page to configure critical alert channels.
|
||||
</Alert>
|
||||
</div>
|
||||
@@ -145,7 +163,7 @@
|
||||
<div class="text-xs text-primary whitespace-nowrap"
|
||||
>{`${totalNumberOfAlerts === 1000 ? '1000+' : (totalNumberOfAlerts ?? '?')} items`}
|
||||
</div>
|
||||
<RefreshButton {loading} onClick={refreshAlerts} />
|
||||
<RefreshButton loading={isRefreshing} onClick={refreshAlerts} />
|
||||
</List>
|
||||
</List>
|
||||
</div>
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
import type { ResourceReturn } from 'runed'
|
||||
import type { ConfirmationModalHandle } from '../common/confirmationModal/asyncConfirmationModal.svelte'
|
||||
import ExploreAssetButton from '../ExploreAssetButton.svelte'
|
||||
import type DBManagerDrawer from '../DBManagerDrawer.svelte'
|
||||
import { ArrowRight, InfoIcon } from 'lucide-svelte'
|
||||
import type { Snippet } from 'svelte'
|
||||
import { truncate } from '$lib/utils'
|
||||
@@ -25,7 +24,7 @@
|
||||
type Props = {
|
||||
customInstanceDbs: ResourceReturn<ListCustomInstanceDbsResponse>
|
||||
confirmationModal: ConfirmationModalHandle
|
||||
dbManagerDrawer: DBManagerDrawer | undefined
|
||||
dbManagerDrawer: any | undefined
|
||||
bottomHint?: Snippet | undefined
|
||||
opened: { status: CustomInstanceDb | undefined; dbname: string } | undefined
|
||||
tag?: CustomInstanceDbTag
|
||||
|
||||
@@ -48,7 +48,7 @@
|
||||
| { open: false }
|
||||
| { open: true; storage: S3ResourceSettingsItem } = $state({ open: false })
|
||||
|
||||
let s3FileViewer: S3FilePicker | undefined = $state()
|
||||
let s3FileViewer: any | undefined = $state()
|
||||
|
||||
async function editWindmillLFSSettings(): Promise<void> {
|
||||
const large_file_storage = convertFrontendToBackendSetting(s3ResourceSettings)
|
||||
|
||||
@@ -14,7 +14,6 @@ import {
|
||||
import { getLocalSetting, type StateStore } from './utils'
|
||||
import { createState } from './svelte5Utils.svelte'
|
||||
import { DEFAULT_HUB_BASE_URL } from './hub'
|
||||
import type DBManagerDrawer from './components/DBManagerDrawer.svelte'
|
||||
|
||||
export interface UserExt {
|
||||
email: string
|
||||
@@ -127,7 +126,7 @@ export const codeCompletionSessionEnabled = writable<boolean>(
|
||||
|
||||
export const usedTriggerKinds = writable<string[]>([])
|
||||
|
||||
export let globalDbManagerDrawer: StateStore<DBManagerDrawer | undefined> = createState({
|
||||
export let globalDbManagerDrawer: StateStore<any | undefined> = createState({
|
||||
val: undefined
|
||||
})
|
||||
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
import Toast, { type ToastType } from '$lib/components/Toast.svelte'
|
||||
import Toast from '$lib/components/Toast.svelte'
|
||||
import { toast } from '@zerodevx/svelte-toast'
|
||||
import type { ComponentProps } from 'svelte'
|
||||
import type { Button } from './components/common'
|
||||
import type { AlertType } from '$lib/components/common/alert/model'
|
||||
|
||||
export type ToastType = AlertType
|
||||
|
||||
export type ToastAction = {
|
||||
label: string
|
||||
|
||||
@@ -82,7 +82,7 @@
|
||||
let assets = $derived(_assets.current?.flatMap((page) => page.assets))
|
||||
|
||||
let s3FilePicker: S3FilePicker | undefined = $state()
|
||||
let dbManagerDrawer = $derived(globalDbManagerDrawer.val)
|
||||
let dbManagerDrawer = $derived(globalDbManagerDrawer.val) as any
|
||||
let assetsUsageDropdown: AssetsUsageDrawer | undefined = $state()
|
||||
|
||||
let allS3Storages = resource(
|
||||
|
||||
@@ -481,7 +481,7 @@
|
||||
}
|
||||
})
|
||||
|
||||
let dbManagerDrawer = $derived(globalDbManagerDrawer.val)
|
||||
let dbManagerDrawer = $derived(globalDbManagerDrawer.val) as any
|
||||
|
||||
let filterUserFolders = $state(false)
|
||||
let filterUserFoldersType: 'only f/*' | 'u/username and f/*' | undefined = $derived(
|
||||
@@ -755,7 +755,7 @@
|
||||
</div>
|
||||
{/if}
|
||||
</PageHeader>
|
||||
<NoDirectDeployAlert onUpdateCanEditStatus={(v) => showCreateButtons = v} />
|
||||
<NoDirectDeployAlert onUpdateCanEditStatus={(v) => (showCreateButtons = v)} />
|
||||
<div class="flex justify-between">
|
||||
<Tabs
|
||||
class="w-full"
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
import type { FastCheckConfig } from 'svelte-fast-check';
|
||||
|
||||
export default {
|
||||
exclude: ['../src/lib/monaco_workers/**']
|
||||
} satisfies FastCheckConfig;
|
||||
@@ -6,19 +6,9 @@
|
||||
"target": "esnext",
|
||||
"outDir": "build",
|
||||
"noUnusedLocals": true,
|
||||
// "noUnusedParameters": true,
|
||||
|
||||
/**
|
||||
svelte-preprocess cannot figure out whether you have a value or a type, so tell TypeScript
|
||||
to enforce using \`import type\` instead of \`import\` for Types.
|
||||
*/
|
||||
"isolatedModules": true,
|
||||
"resolveJsonModule": true,
|
||||
"noImplicitAny": false,
|
||||
/**
|
||||
To have warnings/errors of the Svelte compiler at the correct position,
|
||||
enable source maps by default.
|
||||
*/
|
||||
"sourceMap": true,
|
||||
"esModuleInterop": true,
|
||||
"skipLibCheck": true,
|
||||
|
||||
Reference in New Issue
Block a user