Migrate all to Svelte 5 and fix npm check type stuff

This commit is contained in:
Diego Imbert
2025-10-30 16:39:33 +01:00
parent f51991c25c
commit c724efd3d0
279 changed files with 3653 additions and 2254 deletions
@@ -1,4 +1,6 @@
<script lang="ts">
import { run } from 'svelte/legacy'
import { createEventDispatcher } from 'svelte'
import { Button, Drawer } from './common'
import DrawerContent from './common/drawer/DrawerContent.svelte'
@@ -6,24 +8,26 @@
import AppConnectInner from './AppConnectInner.svelte'
import DarkModeObserver from './DarkModeObserver.svelte'
export let expressOAuthSetup = false
let drawer: Drawer
let resourceType = ''
let step = 1
let disabled = false
let isGoogleSignin = false
let manual = true
let appConnectInner: AppConnectInner | undefined = undefined
let rtToLoad: string | undefined = ''
export async function open(rt?: string) {
rtToLoad = rt
drawer.openDrawer?.()
interface Props {
expressOAuthSetup?: boolean
}
$: appConnectInner && onRtToLoadChange(rtToLoad)
let { expressOAuthSetup = false }: Props = $props()
let drawer: Drawer | undefined = $state()
let resourceType = $state('')
let step = $state(1)
let disabled = $state(false)
let isGoogleSignin = $state(false)
let manual = $state(true)
let appConnectInner: AppConnectInner | undefined = $state(undefined)
let rtToLoad: string | undefined = $state('')
export async function open(rt?: string) {
rtToLoad = rt
drawer?.openDrawer?.()
}
function onRtToLoadChange(rtToLoad: string | undefined) {
appConnectInner?.open(rtToLoad)
@@ -31,7 +35,10 @@
const dispatch = createEventDispatcher()
let darkMode: boolean = false
let darkMode: boolean = $state(false)
run(() => {
appConnectInner && onRtToLoadChange(rtToLoad)
})
</script>
<DarkModeObserver bind:darkMode />
@@ -46,7 +53,7 @@
>
<DrawerContent
title="Add a resource"
on:close={drawer.closeDrawer}
on:close={() => drawer?.closeDrawer()}
tooltip="Resources represent connections to third party systems. Learn more on how to integrate external APIs."
documentationLink="https://www.windmill.dev/docs/integrations/integrations_on_windmill"
>
@@ -57,7 +64,7 @@
bind:isGoogleSignin
bind:disabled
bind:manual
on:close={drawer?.closeDrawer}
on:close={() => drawer?.closeDrawer()}
on:refresh
express={expressOAuthSetup}
/>
@@ -67,7 +74,7 @@
<Button variant="default" on:click={appConnectInner?.back ?? (() => {})}>Back</Button>
{/if}
{#if isGoogleSignin}
<button {disabled} on:click={appConnectInner?.next}>
<button {disabled} onclick={appConnectInner?.next}>
<img
class="h-10 w-auto object-contain"
src={darkMode ? '/google_signin_dark.png' : '/google_signin_light.png'}
@@ -4,9 +4,9 @@
import BackgroundRunnablesTutorial from './tutorials/app/BackgroundRunnablesTutorial.svelte'
import ConnectionTutorial from './tutorials/app/ConnectionTutorial.svelte'
let backgroundRunnablesTutorial: BackgroundRunnablesTutorial | undefined = undefined
let connectionTutorial: ConnectionTutorial | undefined = undefined
let appTutorial: AppTutorial | undefined = undefined
let backgroundRunnablesTutorial: BackgroundRunnablesTutorial | undefined = $state(undefined)
let connectionTutorial: ConnectionTutorial | undefined = $state(undefined)
let appTutorial: AppTutorial | undefined = $state(undefined)
export function runTutorialById(id: string, options?: { skipStepsCount?: number }) {
if (id === 'backgroundrunnables') {
@@ -1,14 +1,18 @@
<script lang="ts">
import { run } from 'svelte/legacy';
import IconedResourceType from './IconedResourceType.svelte'
import Toggle from './Toggle.svelte'
export let value: any
interface Props {
value: any;
}
$: enabled = value != undefined
let { value = $bindable() }: Props = $props();
let org = ''
$: changeOrg(org)
let org = $state('')
function changeOrg(org) {
if (value) {
@@ -28,10 +32,14 @@
}
}
}
let enabled = $derived(value != undefined)
run(() => {
changeOrg(org)
});
</script>
<div class="flex flex-col gap-1">
<!-- svelte-ignore a11y-label-has-associated-control -->
<!-- svelte-ignore a11y_label_has_associated_control -->
<label class="text-sm font-medium text-primary flex gap-4 items-center"
><div class="w-[120px]"><IconedResourceType name={'authelia'} after={true} /></div><Toggle
checked={enabled}
@@ -1,14 +1,18 @@
<script lang="ts">
import { run } from 'svelte/legacy';
import IconedResourceType from './IconedResourceType.svelte'
import Toggle from './Toggle.svelte'
export let value: any
interface Props {
value: any;
}
$: enabled = value != undefined
let { value = $bindable() }: Props = $props();
let org = ''
$: changeOrg(org)
let org = $state('')
function changeOrg(org) {
if (value) {
@@ -28,10 +32,14 @@
}
}
}
let enabled = $derived(value != undefined)
run(() => {
changeOrg(org)
});
</script>
<div class="flex flex-col gap-1">
<!-- svelte-ignore a11y-label-has-associated-control -->
<!-- svelte-ignore a11y_label_has_associated_control -->
<label class="text-sm font-medium text-primary flex gap-4 items-center"
><div class="w-[120px]"><IconedResourceType name={'authentik'} after={true} /></div><Toggle
checked={enabled}
@@ -1,38 +1,48 @@
<script lang="ts">
import { run } from 'svelte/legacy';
import { ExternalLink } from 'lucide-svelte'
import OauthScopes from './OauthScopes.svelte'
export let connect_config: {
interface Props {
connect_config?: {
scopes: string[]
auth_url: string
token_url: string
req_body_auth: boolean
extra_params: { tenant_id: string }
extra_params_callback: Record<string, any>
} = {
};
}
let { connect_config = $bindable({
scopes: ['offline_access'],
auth_url: '',
token_url: '',
req_body_auth: true,
extra_params: { tenant_id: '' },
extra_params_callback: {}
}
}) }: Props = $props();
$: if (!connect_config) {
connect_config = {
scopes: ['offline_access'],
auth_url: '',
token_url: '',
req_body_auth: true,
extra_params: { tenant_id: '' },
extra_params_callback: {}
run(() => {
if (!connect_config) {
connect_config = {
scopes: ['offline_access'],
auth_url: '',
token_url: '',
req_body_auth: true,
extra_params: { tenant_id: '' },
extra_params_callback: {}
}
}
}
});
$: if (connect_config.extra_params.tenant_id) {
connect_config.auth_url = `https://login.microsoftonline.com/${connect_config.extra_params.tenant_id}/oauth2/v2.0/authorize`
connect_config.token_url = `https://login.microsoftonline.com/${connect_config.extra_params.tenant_id}/oauth2/v2.0/token`
}
run(() => {
if (connect_config.extra_params.tenant_id) {
connect_config.auth_url = `https://login.microsoftonline.com/${connect_config.extra_params.tenant_id}/oauth2/v2.0/authorize`
connect_config.token_url = `https://login.microsoftonline.com/${connect_config.extra_params.tenant_id}/oauth2/v2.0/token`
}
});
</script>
<label class="block pb-2" for="tenant-id">
+14 -4
View File
@@ -1,12 +1,22 @@
<script lang="ts">
import Tooltip from './Tooltip.svelte'
export let twBgColor = 'bg-blue-200'
export let twTextColor = 'text-secondary'
export let tooltip: string | undefined = undefined
interface Props {
twBgColor?: string;
twTextColor?: string;
tooltip?: string | undefined;
children?: import('svelte').Snippet;
}
let {
twBgColor = 'bg-blue-200',
twTextColor = 'text-secondary',
tooltip = undefined,
children
}: Props = $props();
</script>
<span class="{twBgColor} {twTextColor} text-2xs rounded px-1 whitespace-nowrap">
<slot />
{@render children?.()}
{#if tooltip && tooltip != ''}
<Tooltip>{tooltip}</Tooltip>
{/if}
@@ -4,10 +4,21 @@
import WindmillIcon from './icons/WindmillIcon.svelte'
import LoginPageHeader from './LoginPageHeader.svelte'
export let subtitle: string | undefined = undefined
export let title = 'Windmill'
export let disableLogo = false
export let large = false
interface Props {
subtitle?: string | undefined;
title?: string;
disableLogo?: boolean;
large?: boolean;
children?: import('svelte').Snippet;
}
let {
subtitle = undefined,
title = 'Windmill',
disableLogo = false,
large = false,
children
}: Props = $props();
setLicense()
</script>
@@ -38,7 +49,7 @@
</p>
{/if}
</div>
<slot />
{@render children?.()}
</div>
</div>
@@ -1,9 +1,15 @@
<script>
<script lang="ts">
import { twMerge } from 'tailwind-merge'
interface Props {
children?: import('svelte').Snippet;
[key: string]: any
}
let { children, ...rest }: Props = $props();
</script>
<div class="pb-8">
<div class={twMerge('max-w-7xl mx-auto px-4 sm:px-6 md:px-8', $$restProps.class)}>
<slot />
<div class={twMerge('max-w-7xl mx-auto px-4 sm:px-6 md:px-8', rest.class)}>
{@render children?.()}
</div>
</div>
@@ -5,12 +5,21 @@
import Alert from './common/alert/Alert.svelte'
import { createEventDispatcher } from 'svelte'
export let email: string
export let username: string
export let isConflict = false
export let noPadding = false
interface Props {
email: string;
username: string;
isConflict?: boolean;
noPadding?: boolean;
}
let loading = false
let {
email,
username = $bindable(),
isConflict = false,
noPadding = false
}: Props = $props();
let loading = $state(false)
let usernameInfo:
| {
@@ -20,7 +29,7 @@
username: string
}[]
}
| undefined = undefined
| undefined = $state(undefined)
function handleKeyUp(event: KeyboardEvent) {
const key = event.key
@@ -83,7 +92,7 @@
<input
type="text"
class="mb-4"
on:keyup={handleKeyUp}
onkeyup={handleKeyUp}
bind:value={username}
disabled={isConflict}
/>
@@ -4,12 +4,24 @@
import { twMerge } from 'tailwind-merge'
import { ChevronDown } from 'lucide-svelte'
export let open = false
export let text: string
export let small = false
interface Props {
open?: boolean
text: string
small?: boolean
children?: import('svelte').Snippet
class?: string
}
let {
open = $bindable(false),
text,
small = false,
children,
class: className = ''
}: Props = $props()
</script>
<div class={twMerge('flex', $$props.class)}>
<div class={twMerge('flex', className)}>
<Button
variant="default"
btnClasses="text-primary {small ? 'text-xs' : ''} "
@@ -20,5 +32,5 @@
</Button>
</div>
{#if open}
<div transition:slide|local={{ duration: 100 }}><slot /></div>
<div transition:slide|local={{ duration: 100 }}>{@render children?.()}</div>
{/if}
@@ -3,8 +3,13 @@
import { Check, X } from 'lucide-svelte'
import { createEventDispatcher } from 'svelte'
export let confirmation: string = 'Are you sure?'
let firstClick = false
interface Props {
confirmation?: string;
children?: import('svelte').Snippet;
}
let { confirmation = 'Are you sure?', children }: Props = $props();
let firstClick = $state(false)
const dispatch = createEventDispatcher()
</script>
@@ -13,7 +18,7 @@
<Button
on:click={() => {
firstClick = true
}}><slot /></Button
}}>{@render children?.()}</Button
>
{:else}
{confirmation}
@@ -15,21 +15,39 @@
team_name: string
}
export let platform: 'slack' | 'teams'
export let teamName: string | undefined
export let display_name: string | undefined
export let scriptPath: string
export let initialPath: string
export let onDisconnect: () => Promise<void>
export let onSelect: () => Promise<void>
export let connectHref: string | undefined
export let createScriptHref: string
export let createFlowHref: string
export let documentationLink: string
export let onLoadSettings: () => void
export let itemKind: 'flow' | 'script' = 'script'
interface Props {
platform: 'slack' | 'teams';
teamName: string | undefined;
display_name: string | undefined;
scriptPath: string;
initialPath: string;
onDisconnect: () => Promise<void>;
onSelect: () => Promise<void>;
connectHref: string | undefined;
createScriptHref: string;
createFlowHref: string;
documentationLink: string;
onLoadSettings: () => void;
itemKind?: 'flow' | 'script';
}
let selectedTeam: TeamItem | undefined = undefined
let {
platform,
teamName,
display_name,
scriptPath = $bindable(),
initialPath,
onDisconnect,
onSelect,
connectHref,
createScriptHref,
createFlowHref,
documentationLink,
onLoadSettings,
itemKind = $bindable('script')
}: Props = $props();
let selectedTeam: TeamItem | undefined = $state(undefined)
async function connectTeams() {
if (!selectedTeam) return
@@ -13,25 +13,25 @@
const dispatch = createEventDispatcher()
let edit: boolean = false
let name: string = ''
let value: string = ''
let edit: boolean = $state(false)
let name: string = $state('')
let value: string = $state('')
export function initNew(): void {
edit = false
name = ''
value = ''
drawer.openDrawer()
drawer?.openDrawer()
}
export function editVariable(editName: string, editValue: string): void {
edit = true
name = editName
value = editValue
drawer.openDrawer()
drawer?.openDrawer()
}
let drawer: Drawer
let drawer: Drawer | undefined = $state()
async function updateVariable(): Promise<void> {
await WorkspaceService.setEnvironmentVariable({
@@ -48,7 +48,7 @@
)
dispatch('update')
drawer.closeDrawer()
drawer?.closeDrawer()
setTimeout(() => {
dispatch('update')
}, 5000)
@@ -58,7 +58,7 @@
<Drawer bind:this={drawer} size="900px">
<DrawerContent
title={edit ? `Update contextual variable ${name}` : 'Create a contextual variable'}
on:close={drawer.closeDrawer}
on:close={drawer?.closeDrawer}
>
<div class="flex flex-col gap-8">
{#if !edit}
+1 -1
View File
@@ -219,7 +219,7 @@
{#if !disabled}
<div class="flex flex-row gap-2 shrink-0">
{@render cronBuilder()}
<CronGen bind:schedule bind:cronVersion />
<CronGen bind:schedule {cronVersion} />
</div>
{/if}
</div>
+19 -15
View File
@@ -1,28 +1,32 @@
<script lang="ts">
import { run } from 'svelte/legacy';
import OauthExtraParams from './OauthExtraParams.svelte'
import OauthScopes from './OauthScopes.svelte'
import Toggle from './Toggle.svelte'
import Tooltip from './Tooltip.svelte'
export let connect_config = {
let { connect_config = $bindable({
scopes: [],
auth_url: '',
token_url: '',
req_body_auth: false,
extra_params: {},
extra_params_callback: {}
}
}) } = $props();
$: if (!connect_config) {
connect_config = {
scopes: [],
auth_url: '',
token_url: '',
req_body_auth: false,
extra_params: {},
extra_params_callback: {}
run(() => {
if (!connect_config) {
connect_config = {
scopes: [],
auth_url: '',
token_url: '',
req_body_auth: false,
extra_params: {},
extra_params_callback: {}
}
}
}
});
</script>
<label class="block pb-2">
@@ -41,12 +45,12 @@
bind:value={connect_config.token_url}
/>
</label>
<!-- svelte-ignore a11y-label-has-associated-control -->
<!-- svelte-ignore a11y_label_has_associated_control -->
<label class="block pb-2">
<span class="text-primary font-semibold text-sm">Scopes</span>
<OauthScopes bind:scopes={connect_config.scopes} />
</label>
<!-- svelte-ignore a11y-label-has-associated-control -->
<!-- svelte-ignore a11y_label_has_associated_control -->
<label class="block pb-2">
<span class="text-primary font-semibold text-sm"
>Extra Query Args for Authorize Request&nbsp;<Tooltip
@@ -56,14 +60,14 @@
>
<OauthExtraParams bind:extra_params={connect_config.extra_params} />
</label>
<!-- svelte-ignore a11y-label-has-associated-control -->
<!-- svelte-ignore a11y_label_has_associated_control -->
<label class="block pb-2">
<span class="text-primary font-semibold text-sm"
>Extra Query Args for Token request <Tooltip>Not needed in most cases</Tooltip></span
>
<OauthExtraParams bind:extra_params={connect_config.extra_params_callback} />
</label>
<!-- svelte-ignore a11y-label-has-associated-control -->
<!-- svelte-ignore a11y_label_has_associated_control -->
<label class="block pb-2">
<span class="text-primary font-semibold text-sm"
>Payload <Tooltip
@@ -1,3 +1,4 @@
<!-- @migration-task Error while migrating Svelte code: $$props is used together with named props in a way that cannot be automatically migrated. -->
<script lang="ts">
import { createPopperActions, type PopperOptions } from 'svelte-popperjs'
import type { PopoverPlacement } from './Popover.model'
+20 -16
View File
@@ -1,10 +1,12 @@
<script lang="ts">
import { run } from 'svelte/legacy';
import OauthExtraParams from './OauthExtraParams.svelte'
import OauthScopes from './OauthScopes.svelte'
import Toggle from './Toggle.svelte'
import Tooltip from './Tooltip.svelte'
export let login_config = {
let { login_config = $bindable({
scopes: [],
auth_url: '',
token_url: '',
@@ -12,19 +14,21 @@
req_body_auth: false,
extra_params: {},
extra_params_callback: {}
}
}) } = $props();
$: if (!login_config) {
login_config = {
scopes: [],
auth_url: '',
token_url: '',
userinfo_url: '',
req_body_auth: false,
extra_params: {},
extra_params_callback: {}
run(() => {
if (!login_config) {
login_config = {
scopes: [],
auth_url: '',
token_url: '',
userinfo_url: '',
req_body_auth: false,
extra_params: {},
extra_params_callback: {}
}
}
}
});
</script>
<label class="block pb-2">
@@ -51,12 +55,12 @@
bind:value={login_config.userinfo_url}
/>
</label>
<!-- svelte-ignore a11y-label-has-associated-control -->
<!-- svelte-ignore a11y_label_has_associated_control -->
<label class="block pb-2">
<span class="text-primary font-semibold text-xs">Scopes</span>
<OauthScopes bind:scopes={login_config.scopes} />
</label>
<!-- svelte-ignore a11y-label-has-associated-control -->
<!-- svelte-ignore a11y_label_has_associated_control -->
<label class="block pb-2">
<span class="text-primary font-semibold text-xs"
>Extra Query Args for Authorize Request&nbsp;<Tooltip
@@ -66,14 +70,14 @@
>
<OauthExtraParams bind:extra_params={login_config.extra_params} />
</label>
<!-- svelte-ignore a11y-label-has-associated-control -->
<!-- svelte-ignore a11y_label_has_associated_control -->
<label class="block pb-2">
<span class="text-primary font-semibold text-xs"
>Extra Query Args for Token request <Tooltip>Not needed in most cases</Tooltip></span
>
<OauthExtraParams bind:extra_params={login_config.extra_params_callback} />
</label>
<!-- svelte-ignore a11y-label-has-associated-control -->
<!-- svelte-ignore a11y_label_has_associated_control -->
<label class="block pb-2">
<span class="text-primary font-semibold text-xs"
>Payload <Tooltip
+8 -6
View File
@@ -144,12 +144,14 @@
}))}
class="w-fit"
>
<svelte:fragment slot="buttonReplacement">
<MoreVertical
size={8}
class="w-8 h-8 p-2 hover:bg-surface-hover cursor-pointer rounded-md"
/>
</svelte:fragment>
{#snippet buttonReplacement()}
<MoreVertical
size={8}
class="w-8 h-8 p-2 hover:bg-surface-hover cursor-pointer rounded-md"
/>
{/snippet}
</DropdownV2>
{/if}
</button>
+24 -10
View File
@@ -1,19 +1,33 @@
<script lang="ts">
import { createBubbler } from 'svelte/legacy';
const bubble = createBubbler();
import { createEventDispatcher } from 'svelte'
import { format, isValid, parse } from 'date-fns'
import { sendUserToast } from '$lib/toast'
export let value: string | undefined = undefined
export let autofocus: boolean | null = false
export let minDate: string | undefined = undefined
export let maxDate: string | undefined = undefined
export let dateFormat: string | undefined = 'dd-MM-yyyy'
export let disabled: boolean = false
interface Props {
value?: string | undefined;
autofocus?: boolean | null;
minDate?: string | undefined;
maxDate?: string | undefined;
dateFormat?: string | undefined;
disabled?: boolean;
}
let {
value = $bindable(undefined),
autofocus = false,
minDate = undefined,
maxDate = undefined,
dateFormat = $bindable('dd-MM-yyyy'),
disabled = false
}: Props = $props();
const defaultDateFormat = 'dd-MM-yyyy'
const defaultHtmlDateFormat = 'yyyy-MM-dd'
let date: string | undefined = computeDate(value)
let date: string | undefined = $state(computeDate(value))
const dispatch = createEventDispatcher()
@@ -70,8 +84,8 @@
let randomId = 'datetarget-' + Math.random().toString(36).substring(7)
</script>
<div class="flex flex-row gap-1 items-center w-full" id={randomId} on:pointerdown on:focus>
<!-- svelte-ignore a11y-autofocus -->
<div class="flex flex-row gap-1 items-center w-full" id={randomId} onpointerdown={bubble('pointerdown')} onfocus={bubble('focus')}>
<!-- svelte-ignore a11y_autofocus -->
<input
{disabled}
type="date"
@@ -80,7 +94,7 @@
class="!w-full app-editor-input"
min={minDate}
max={maxDate}
on:change={() => {
onchange={() => {
if (date) {
updateValue(date)
}
@@ -6,11 +6,15 @@
import DrawerContent from './common/drawer/DrawerContent.svelte'
import DefaultScriptsInner from './DefaultScriptsInner.svelte'
let drawer: Drawer
export let placement: 'left' | 'right' = 'left'
let drawer: Drawer | undefined = $state()
export let size: 'xs3' | 'xs2' = 'xs2'
export let noText = false
interface Props {
placement?: 'left' | 'right'
size?: 'xs3' | 'xs2'
noText?: boolean
}
let { placement = 'left', size = 'xs2', noText = false }: Props = $props()
</script>
{#if $userStore?.is_admin || $userStore?.is_super_admin}
@@ -6,8 +6,11 @@
import { defaultScriptLanguages } from '$lib/scripts'
import Alert from './common/alert/Alert.svelte'
export let small = false
$: langs = computeLangs($defaultScripts)
interface Props {
small?: boolean;
}
let { small = false }: Props = $props();
function computeLangs(defaultScripts: WorkspaceDefaultScripts | undefined): Script['language'][] {
const allLangs = Object.keys(defaultScriptLanguages) as Script['language'][]
@@ -30,6 +33,7 @@
requestBody: $defaultScripts
})
}
let langs = $derived(computeLangs($defaultScripts))
</script>
<Alert title="Global to workspace" type="info" class="mb-4" size={small ? 'xs' : 'sm'}>
@@ -47,7 +51,7 @@
<div>
{#if i > 0}
<button
on:click={() => changePosition(i ?? 0, true)}
onclick={() => changePosition(i ?? 0, true)}
class={small ? 'mr-2 text-secondary text-sm' : 'text-lg mr-2'}
title="Move up"
>
@@ -56,7 +60,7 @@
{/if}
{#if i < langs.length - 1}
<button
on:click={() => changePosition(i ?? 0, false)}
onclick={() => changePosition(i ?? 0, false)}
class={small ? 'mr-2 text-secondary text-sm' : 'text-lg mr-2'}
title="Move down">&downarrow;</button
>
@@ -10,12 +10,16 @@
import MultiSelect from './select/MultiSelect.svelte'
import { safeSelectItems } from './select/utils.svelte'
let defaultTags: string[] | undefined = undefined
export let defaultTagPerWorkspace: boolean | undefined = undefined
export let defaultTagWorkspaces: string[] = []
let limitToWorkspaces = false
let defaultTags: string[] | undefined = $state(undefined)
interface Props {
defaultTagPerWorkspace?: boolean | undefined;
defaultTagWorkspaces?: string[];
}
let workspaces: string[] = []
let { defaultTagPerWorkspace = $bindable(undefined), defaultTagWorkspaces = $bindable([]) }: Props = $props();
let limitToWorkspaces = $state(false)
let workspaces: string[] = $state([])
async function loadWorkspaces() {
workspaces = (await WorkspaceService.listWorkspacesAsSuperAdmin()).map((m) => m.id)
}
@@ -9,9 +9,9 @@
import Toggle from './Toggle.svelte'
import { emptyString } from '$lib/utils'
$: deployableWorkspaces = $usersWorkspaceStore?.workspaces
.map((w) => w.id)
.filter((w) => w != $workspaceStore)
let deployableWorkspaces = $derived(
$usersWorkspaceStore?.workspaces.map((w) => w.id).filter((w) => w != $workspaceStore)
)
type DeployUITypeMap = {
scripts: boolean
@@ -34,14 +34,21 @@
triggers: true
}
export let workspaceToDeployTo: string | undefined
export let deployUiSettings: {
include_path: string[]
include_type: DeployUITypeMap
} = {
include_path: [],
include_type: all_ok
interface Props {
workspaceToDeployTo: string | undefined
deployUiSettings?: {
include_path: string[]
include_type: DeployUITypeMap
}
}
let {
workspaceToDeployTo = $bindable(),
deployUiSettings = $bindable({
include_path: [],
include_type: all_ok
})
}: Props = $props()
function deployUITypeMapToArray(
typesMap: DeployUITypeMap,
expectedValue: boolean
@@ -91,7 +98,7 @@
<div class="flex min-w-0 mt-1">
<select
bind:value={workspaceToDeployTo}
on:change={async (e) => {
onchange={async (e) => {
await WorkspaceService.editDeployTo({
workspace: $workspaceStore ?? '',
requestBody: { deploy_to: workspaceToDeployTo == '' ? undefined : workspaceToDeployTo }
@@ -125,14 +132,14 @@
anything including slashes.
</Tooltip></h4
>
{#each deployUiSettings.include_path ?? [] as regexpPath, idx}
{#each deployUiSettings.include_path ?? [] as _, idx}
<div class="flex mt-1 items-center">
<input type="text" bind:value={regexpPath} id="arg-input-array" />
<input type="text" bind:value={deployUiSettings.include_path[idx]} id="arg-input-array" />
<button
transition:fade|local={{ duration: 100 }}
class="rounded-full p-1 bg-surface-secondary duration-200 hover:bg-surface-hover ml-2"
aria-label="Clear"
on:click={() => {
onclick={() => {
deployUiSettings.include_path.splice(idx, 1)
deployUiSettings.include_path = [...deployUiSettings.include_path]
}}
@@ -4,12 +4,12 @@
import DeployWorkspace from './DeployWorkspace.svelte'
import { type AdditionalInformation, type Kind } from '$lib/utils_deployable'
let initialPath: string | undefined = undefined
let kind: Kind | undefined = undefined
let drawer: Drawer | undefined = undefined
let workspaceToDeployTo: string | undefined = undefined
let deployWorkspace: DeployWorkspace | undefined = undefined
let additionalInformation: AdditionalInformation | undefined = undefined
let initialPath: string | undefined = $state(undefined)
let kind: Kind | undefined = $state(undefined)
let drawer: Drawer | undefined = $state(undefined)
let workspaceToDeployTo: string | undefined = $state(undefined)
let deployWorkspace: DeployWorkspace | undefined = $state(undefined)
let additionalInformation: AdditionalInformation | undefined = $state(undefined)
export async function openDrawer(
initialPath_l: string,
@@ -1,3 +1,4 @@
<!-- @migration-task Error while migrating Svelte code: $$props is used together with named props in a way that cannot be automatically migrated. -->
<script lang="ts">
import { twMerge } from 'tailwind-merge'
+4 -4
View File
@@ -21,7 +21,7 @@
import { Pane, Splitpanes } from 'svelte-splitpanes'
import { onDestroy, onMount, setContext, untrack } from 'svelte'
import DarkModeToggle from '$lib/components/sidebar/DarkModeToggle.svelte'
import { page } from '$app/stores'
import { page } from '$app/state'
import { getUserExt } from '$lib/user'
import FlowPreviewButtons from './flows/header/FlowPreviewButtons.svelte'
import FlowModuleSchemaMap from './flows/map/FlowModuleSchemaMap.svelte'
@@ -581,9 +581,9 @@
}
})
}
let token = $derived($page.url.searchParams.get('wm_token') ?? undefined)
let workspace = $derived($page.url.searchParams.get('workspace') ?? undefined)
let themeDarkRaw = $derived($page.url.searchParams.get('activeColorTheme'))
let token = $derived(page.url.searchParams.get('wm_token') ?? undefined)
let workspace = $derived(page.url.searchParams.get('workspace') ?? undefined)
let themeDarkRaw = $derived(page.url.searchParams.get('activeColorTheme'))
let themeDark = $derived(themeDarkRaw == '2' || themeDarkRaw == '4')
$effect.pre(() => {
@@ -27,7 +27,7 @@
import Toggle from './Toggle.svelte'
import FileDownload from './common/fileDownload/FileDownload.svelte'
import ParqetTableRenderer from './ParqetCsvTableRenderer.svelte'
import ParqetTableRenderer from './ParquetCsvTableRenderer.svelte'
import ToggleButtonGroup from './common/toggleButton-v2/ToggleButtonGroup.svelte'
import ToggleButton from './common/toggleButton-v2/ToggleButton.svelte'
import MapResult from './MapResult.svelte'
@@ -4,9 +4,13 @@
import { Hourglass } from 'lucide-svelte'
import WaitTimeWarning from './common/waitTimeWarning/WaitTimeWarning.svelte'
export let duration_ms: number
export let self_wait_time_ms: number | undefined = undefined
export let aggregate_wait_time_ms: number | undefined = undefined
interface Props {
duration_ms: number;
self_wait_time_ms?: number | undefined;
aggregate_wait_time_ms?: number | undefined;
}
let { duration_ms, self_wait_time_ms = undefined, aggregate_wait_time_ms = undefined }: Props = $props();
</script>
<div>
@@ -1,32 +1,40 @@
<script lang="ts">
import { run } from 'svelte/legacy';
import { type Job } from '$lib/gen'
import { isScriptPreview } from '$lib/utils'
import { onDestroy } from 'svelte'
export let job: Job | undefined = undefined
/** Execution duration of current active job (in ms) */
export let executionDuration: number = 0
/** Is current job running more than specified value in `longDefinition` seconds */
export let longRunning: boolean = false
/** What do we count as "long" (in ms)*/
export let longDefinition: number = 30_000
/** How often component updates execution duration (in ms)
interface Props {
job?: Job | undefined;
/** Execution duration of current active job (in ms) */
executionDuration?: number;
/** Is current job running more than specified value in `longDefinition` seconds */
longRunning?: boolean;
/** What do we count as "long" (in ms)*/
longDefinition?: number;
/** How often component updates execution duration (in ms)
* Higher value -> more efficient component is, less accuracy it has
* Lower value -> less efficient component is, more accuracy it has
*/
export let updateResolution: number = 5_000
updateResolution?: number;
}
let {
job = undefined,
executionDuration = $bindable(0),
longRunning = $bindable(false),
longDefinition = 30_000,
updateResolution = 5_000
}: Props = $props();
let startedAt: number | undefined = undefined
let busy: boolean = false
let busy: boolean = $state(false)
let interval: number | undefined
// Detect when execution of job started
$: if (
!busy &&
job &&
'running' in job &&
(job.job_kind == 'script' || isScriptPreview(job?.job_kind))
)
start(job)
function start(job: Job) {
busy = true
@@ -50,4 +58,14 @@
// Clear the interval when the component is destroyed
clearInterval(interval)
})
// Detect when execution of job started
run(() => {
if (
!busy &&
job &&
'running' in job &&
(job.job_kind == 'script' || isScriptPreview(job?.job_kind))
)
start(job)
});
</script>
+36 -16
View File
@@ -5,19 +5,37 @@
import Tooltip from './meltComponents/Tooltip.svelte'
import { InfoIcon } from 'lucide-svelte'
export let label: string
export let format: string = ''
export let contentEncoding = ''
export let type: string | undefined = undefined
export let disabled: boolean = false
export let required = false
export let displayType: boolean = true
export let labelClass: string = ''
export let prettify = false
export let simpleTooltip: string | undefined = undefined
export let lightHeader = false
export let SimpleTooltipIcon = InfoIcon
export let simpleTooltipIconClass = ''
interface Props {
label: string;
format?: string;
contentEncoding?: string;
type?: string | undefined;
disabled?: boolean;
required?: boolean;
displayType?: boolean;
labelClass?: string;
prettify?: boolean;
simpleTooltip?: string | undefined;
lightHeader?: boolean;
SimpleTooltipIcon?: any;
simpleTooltipIconClass?: string;
}
let {
label,
format = '',
contentEncoding = '',
type = undefined,
disabled = false,
required = false,
displayType = true,
labelClass = '',
prettify = false,
simpleTooltip = undefined,
lightHeader = false,
SimpleTooltipIcon = InfoIcon,
simpleTooltipIconClass = ''
}: Props = $props();
</script>
<div class="inline-flex flex-row items-baseline truncated">
@@ -54,9 +72,11 @@
{#if !emptyString(simpleTooltip)}
<Tooltip class="ml-2" placement="bottom">
<SimpleTooltipIcon size="14" class={'-mb-0.5 ' + simpleTooltipIconClass} />
<span class="text-xs" slot="text">
{simpleTooltip}
</span>
{#snippet text()}
<span class="text-xs" >
{simpleTooltip}
</span>
{/snippet}
</Tooltip>
{/if}
</div>
@@ -9,21 +9,34 @@
import { dfs } from './flows/dfs'
import { workspaceStore } from '$lib/stores'
export let flow: {
interface Props {
flow: {
summary: string
description?: string
value: FlowValue
schema?: any
path?: string
};
overflowAuto?: boolean;
noSide?: boolean;
download?: boolean;
noGraph?: boolean;
triggerNode?: boolean;
stepDetail?: FlowModule | string | undefined;
workspace?: string | undefined;
}
export let overflowAuto = false
export let noSide = false
export let download = false
export let noGraph = false
export let triggerNode = false
export let stepDetail: FlowModule | string | undefined = undefined
export let workspace: string | undefined = $workspaceStore
let {
flow,
overflowAuto = false,
noSide = false,
download = false,
noGraph = false,
triggerNode = false,
stepDetail = $bindable(undefined),
workspace = $workspaceStore
}: Props = $props();
const dispatch = createEventDispatcher()
</script>
@@ -18,16 +18,19 @@
import { Copy } from 'lucide-svelte'
import HighlightTheme from './HighlightTheme.svelte'
export let schema: any | undefined = undefined
interface Props {
schema?: any | undefined
stepDetail?: FlowModule | string | undefined
}
export let stepDetail: FlowModule | string | undefined = undefined
let codeViewer: Drawer
let { schema = undefined, stepDetail = undefined }: Props = $props()
let codeViewer: Drawer | undefined = $state()
</script>
<HighlightTheme />
<Drawer bind:this={codeViewer} size="900px">
<DrawerContent title={'Expanded Code'} on:close={codeViewer.closeDrawer}>
<DrawerContent title={'Expanded Code'} on:close={() => codeViewer?.closeDrawer()}>
{#if stepDetail && typeof stepDetail != 'string'}
{#if stepDetail.value.type == 'script'}
<div class="mb-4">
@@ -170,7 +173,12 @@
<div>
<div class="mb-2 mt-4 flex justify-between items-center">
<h3 class="font-semibold">Code</h3>
<Button size="xs2" color="light" variant="contained" on:click={codeViewer.openDrawer}>
<Button
size="xs2"
color="light"
variant="contained"
on:click={() => codeViewer?.openDrawer()}
>
Expand
</Button>
</div>
@@ -205,7 +213,12 @@
<div class="flex flex-col grow">
<div class="mb-2 flex justify-between items-center">
<h3 class="font-semibold">Code</h3>
<Button size="xs2" color="light" variant="contained" on:click={codeViewer.openDrawer}>
<Button
size="xs2"
color="light"
variant="contained"
on:click={() => codeViewer?.openDrawer()}
>
Expand
</Button>
</div>
@@ -3,7 +3,11 @@
import FieldHeader from './FieldHeader.svelte'
export let schema: Schema | { [key: string]: unknown } | undefined
interface Props {
schema: Schema | { [key: string]: unknown } | undefined;
}
let { schema }: Props = $props();
</script>
<ul class="my-2">
@@ -4,9 +4,13 @@
import AnimatedButton from './common/button/AnimatedButton.svelte'
import { twMerge } from 'tailwind-merge'
export let connecting: boolean
export let id: undefined | string = undefined
export let wrapperClasses = ''
interface Props {
connecting: boolean;
id?: undefined | string;
wrapperClasses?: string;
}
let { connecting, id = undefined, wrapperClasses = '' }: Props = $props();
</script>
<AnimatedButton animate={connecting} baseRadius="6px" animationDuration="2s" marginWidth="2px">
@@ -1,4 +1,6 @@
<script lang="ts">
import { run } from 'svelte/legacy';
import { mergeSchema } from '$lib/common'
import { type Job, JobService } from '$lib/gen'
import { workspaceStore } from '$lib/stores'
@@ -9,23 +11,30 @@
import { Button } from './common'
import SchemaForm from './SchemaForm.svelte'
export let isOwner: boolean
export let workspaceId: string | undefined
export let job: Job
export let light: boolean = false
interface Props {
isOwner: boolean;
workspaceId: string | undefined;
job: Job;
light?: boolean;
}
let default_payload: object = {}
let resumeUrl: string | undefined = undefined
let cancelUrl: string | undefined = undefined
let description: any = undefined
let hide_cancel = false
let {
isOwner,
workspaceId,
job,
light = false
}: Props = $props();
$: approvalStep = (job?.flow_status?.step ?? 1) - 1
let default_payload: object = $state({})
let resumeUrl: string | undefined = $state(undefined)
let cancelUrl: string | undefined = $state(undefined)
let description: any = $state(undefined)
let hide_cancel = $state(false)
let defaultValues = {}
$: job && getDefaultArgs()
let schema = {}
let defaultValues = $state({})
let schema = $state({})
let lastJobId: string | undefined = undefined
async function getDefaultArgs() {
let jobId = job?.flow_status?.modules?.[approvalStep]?.job
@@ -113,6 +122,10 @@
}
}
}
let approvalStep = $derived((job?.flow_status?.step ?? 1) - 1)
run(() => {
job && getDefaultArgs()
});
</script>
<div class="w-full h-full mt-2 text-xs text-primary">
@@ -267,7 +267,8 @@
{#if perms}
<TableCustom>
<!-- @migration-task: migrate this slot by hand, `header-row` is an invalid identifier -->
<tr slot="header-row">
<!-- @migration-task: migrate this slot by hand, `header-row` is an invalid identifier -->
<tr slot="header-row">
<th>user/group</th>
<th></th>
<th></th>
@@ -1,19 +1,27 @@
<script lang="ts">
import { run } from 'svelte/legacy';
import { FolderService } from '$lib/gen'
import { workspaceStore } from '$lib/stores'
import Cell from './table/Cell.svelte'
export let name: string
export let tabular = false
export let order = ['scripts', 'flows', 'apps', 'schedules', 'variables', 'resources']
interface Props {
name: string;
tabular?: boolean;
order?: any;
}
$: $workspaceStore && loadUsage()
let { name, tabular = false, order = ['scripts', 'flows', 'apps', 'schedules', 'variables', 'resources'] }: Props = $props();
let usage: Record<string, number> = {}
let usage: Record<string, number> = $state({})
async function loadUsage() {
usage = await FolderService.getFolderUsage({ workspace: $workspaceStore!, name })
}
run(() => {
$workspaceStore && loadUsage()
});
</script>
{#if tabular}
@@ -3,7 +3,11 @@
import { gfmPlugin } from 'svelte-exmarkdown/gfm'
import rehypeRaw from 'rehype-raw'
import { rehypeGithubAlerts } from 'rehype-github-alerts'
export let md: string
interface Props {
md: string;
}
let { md }: Props = $props();
const plugins: Plugin[] = [
gfmPlugin(),
{ rehypePlugin: [rehypeRaw] },
@@ -1,3 +1,4 @@
<!-- @migration-task Error while migrating Svelte code: $$props is used together with named props in a way that cannot be automatically migrated. -->
<script lang="ts">
import { BROWSER } from 'esm-env'
@@ -149,7 +149,8 @@
{#if members}
<TableCustom>
<!-- @migration-task: migrate this slot by hand, `header-row` is an invalid identifier -->
<tr slot="header-row">
<!-- @migration-task: migrate this slot by hand, `header-row` is an invalid identifier -->
<tr slot="header-row">
<th>user</th>
<th></th>
<th></th>
@@ -291,7 +292,8 @@
<h2 class="mt-6 text-emphasis text-xs font-semibold">Members from the instance group</h2>
<TableCustom>
<!-- @migration-task: migrate this slot by hand, `header-row` is an invalid identifier -->
<tr slot="header-row">
<!-- @migration-task: migrate this slot by hand, `header-row` is an invalid identifier -->
<tr slot="header-row">
<th>user</th>
</tr>
{#snippet body()}
@@ -132,8 +132,10 @@
{#if !lines}
<Highlight class="nowrap {className}" language={lang} {code} />
{:else}
<Highlight class="nowrap {className}" language={lang} {code} let:highlighted>
<LineNumbers {highlighted} />
<Highlight class="nowrap {className}" language={lang} {code}>
{#snippet children({ highlighted })}
<LineNumbers {highlighted} />
{/snippet}
</Highlight>
{/if}
{:else}
@@ -1,3 +1,4 @@
<!-- @migration-task Error while migrating Svelte code: $$props is used together with named props in a way that cannot be automatically migrated. -->
<script lang="ts">
import { truncateHash } from '$lib/utils'
import { Building } from 'lucide-svelte'
@@ -3,8 +3,12 @@
import { cleanExpr } from '$lib/utils'
import ObjectViewer from './propertyPicker/ObjectViewer.svelte'
export let inputTransforms: Record<string, InputTransform>
$: entries = Object.entries(inputTransforms)
interface Props {
inputTransforms: Record<string, InputTransform>;
}
let { inputTransforms }: Props = $props();
let entries = $derived(Object.entries(inputTransforms))
</script>
{#if entries.length}
@@ -1,4 +1,6 @@
<script lang="ts">
import { run } from 'svelte/legacy';
import { GroupService, type InstanceGroup } from '$lib/gen'
import { createEventDispatcher } from 'svelte'
import autosize from '$lib/autosize'
@@ -8,17 +10,18 @@
import { sendUserToast } from '$lib/toast'
import { Loader2 } from 'lucide-svelte'
export let name: string
interface Props {
name: string;
}
let email = ''
let instance_group: InstanceGroup | undefined
let members: { member_email: string }[] | undefined = undefined
let { name }: Props = $props();
let email = $state('')
let instance_group: InstanceGroup | undefined = $state()
let members: { member_email: string }[] | undefined = $state(undefined)
const dispatch = createEventDispatcher()
$: {
load()
}
async function load() {
return Promise.all([loadInstanceGroup()])
@@ -32,6 +35,9 @@
})
: []
}
run(() => {
load()
});
</script>
<div class="flex flex-col gap-6">
@@ -85,17 +91,19 @@
</div>
{#if members}
<TableCustom>
<tr slot="header-row">
<!-- @migration-task: migrate this slot by hand, `header-row` is an invalid identifier -->
<tr slot="header-row">
<th>user</th>
<th></th>
</tr>
<tbody slot="body">
{#each members as { member_email }}<tr>
<td>{member_email}</td>
<td>
<button
class="ml-2 text-red-500"
on:click={async () => {
{#snippet body()}
<tbody >
{#each members as { member_email }}<tr>
<td>{member_email}</td>
<td>
<button
class="ml-2 text-red-500"
onclick={async () => {
await GroupService.removeUserFromInstanceGroup({
name,
requestBody: { email: member_email }
@@ -104,10 +112,11 @@
sendUserToast('User removed')
loadInstanceGroup()
}}>remove</button
>
</td>
</tr>{/each}
</tbody>
>
</td>
</tr>{/each}
</tbody>
{/snippet}
</TableCustom>
{:else}
<div class="flex flex-col">
@@ -1,4 +1,7 @@
<script lang="ts">
import { stopPropagation, createBubbler } from 'svelte/legacy'
const bubble = createBubbler()
import { Pencil } from 'lucide-svelte'
import { createEventDispatcher } from 'svelte'
import Button from './common/button/Button.svelte'
@@ -9,13 +12,23 @@
import { sendUserToast } from '$lib/toast'
import TextInput from './text_input/TextInput.svelte'
export let value: string | undefined
export let email: string
export let username: string | undefined = undefined
export let automateUsernameCreation: boolean = false
export let login_type: string
interface Props {
value: string | undefined
email: string
username?: string | undefined
automateUsernameCreation?: boolean
login_type: string
}
let password: string = ''
let {
value = $bindable(),
email,
username = undefined,
automateUsernameCreation = false,
login_type = $bindable()
}: Props = $props()
let password: string = $state('')
const dispatch = createEventDispatcher()
@@ -46,10 +59,10 @@
}}
closeButton
>
<svelte:fragment slot="trigger">
{#snippet trigger()}
<Button nonCaptureEvent={true} size="xs" color="light" endIcon={{ icon: Pencil }}>Edit</Button>
</svelte:fragment>
<svelte:fragment slot="content">
{/snippet}
{#snippet content()}
<div class="flex flex-col gap-8 max-w-sm p-4">
{#if automateUsernameCreation && username}
<ChangeInstanceUsernameInner {email} {username} on:renamed noPadding />
@@ -94,13 +107,13 @@
type="password"
bind:value={password}
class="!w-auto grow"
on:click|stopPropagation={() => {}}
on:keydown|stopPropagation
on:keypress|stopPropagation={({ key }) => {
onclick={stopPropagation(() => {})}
onkeydown={stopPropagation(bubble('keydown'))}
onkeypress={stopPropagation(({ key }) => {
if (key === 'Enter') {
savePassword()
}
}}
})}
/>
</div>
<Button
@@ -124,13 +137,13 @@
type="text"
bind:value={login_type}
class="!w-auto grow"
on:click|stopPropagation={() => {}}
on:keydown|stopPropagation
on:keypress|stopPropagation={({ key }) => {
onclick={stopPropagation(() => {})}
onkeydown={stopPropagation(bubble('keydown'))}
onkeypress={stopPropagation(({ key }) => {
if (key === 'Enter') {
saveLoginType()
}
}}
})}
/>
</div>
<div class="text-2xs text-secondary mb-1">
@@ -151,5 +164,5 @@
</Button>
</label>
</div>
</svelte:fragment>
{/snippet}
</Popover>
@@ -9,9 +9,9 @@
const dispatch = createEventDispatcher()
let is_super_admin = false
let password: string = generateRandomString(10)
let name: string | undefined
let is_super_admin = $state(false)
let password: string = $state(generateRandomString(10))
let name: string | undefined = $state()
let company: string | undefined
async function addUser() {
+11 -8
View File
@@ -4,14 +4,17 @@
const dispatch = createEventDispatcher()
export let updateOnBlur = true
export let placeholder =
'Write a JSON payload. The input schema will be inferred.<br/><br/>Example:<br/><br/>{<br/>&nbsp;&nbsp;"foo": "12"<br/>}'
export let selected: boolean = false
interface Props {
updateOnBlur?: boolean;
placeholder?: string;
selected?: boolean;
}
let pendingJson = ''
let simpleEditor: SimpleEditor | undefined = undefined
let focusTrap: HTMLElement | undefined
let { updateOnBlur = true, placeholder = 'Write a JSON payload. The input schema will be inferred.<br/><br/>Example:<br/><br/>{<br/>&nbsp;&nbsp;"foo": "12"<br/>}', selected = false }: Props = $props();
let pendingJson = $state('')
let simpleEditor: SimpleEditor | undefined = $state(undefined)
let focusTrap: HTMLElement | undefined = $state()
function updatePayloadFromJson(jsonInput: string) {
if (jsonInput === undefined || jsonInput === null || jsonInput.trim() === '') {
@@ -44,7 +47,7 @@
}
</script>
<svelte:window on:keydown={handleKeydown} />
<svelte:window onkeydown={handleKeydown} />
<!-- Add a hidden button that can receive focus -->
<button bind:this={focusTrap} class="sr-only" tabindex="-1" aria-hidden="true">Focus trap</button>
@@ -1,22 +1,20 @@
<script lang="ts">
import { run } from 'svelte/legacy';
import IconedResourceType from './IconedResourceType.svelte'
import Toggle from './Toggle.svelte'
export let value: any
interface Props {
value: any;
}
let { value = $bindable() }: Props = $props();
const AUTH_URL_SUFFIX = '/ui/oauth2'
$: enabled = value != undefined
// If `baseUrl` is not already set in the form, try to parse it from the `auth_url` value
//
// The binding dance here allows us to avoid rendering the string 'undefined' in the input, and
// also allow lazy/async binding of the `value` prop.
$: derivedBaseUrl = value?.connect_config?.auth_url?.replace(AUTH_URL_SUFFIX, '')
let proxyUrlValue = undefined
$: baseUrl = proxyUrlValue ?? derivedBaseUrl ?? ''
let proxyUrlValue = $state(undefined)
$: changeValues({ baseUrl, id: value?.id ?? '' })
function changeValues({ baseUrl, id }) {
if (value) {
@@ -38,10 +36,20 @@
proxyUrlValue = baseUrl
}
}
let enabled = $derived(value != undefined)
// If `baseUrl` is not already set in the form, try to parse it from the `auth_url` value
//
// The binding dance here allows us to avoid rendering the string 'undefined' in the input, and
// also allow lazy/async binding of the `value` prop.
let derivedBaseUrl = $derived(value?.connect_config?.auth_url?.replace(AUTH_URL_SUFFIX, ''))
let baseUrl = $derived(proxyUrlValue ?? derivedBaseUrl ?? '')
run(() => {
changeValues({ baseUrl, id: value?.id ?? '' })
});
</script>
<div class="flex flex-col gap-1">
<!-- svelte-ignore a11y-label-has-associated-control -->
<!-- svelte-ignore a11y_label_has_associated_control -->
<label class="text-sm font-medium text-primary flex gap-4 items-center"
><div class="w-[120px]"><IconedResourceType name={'kanidm'} after={true} /></div><Toggle
checked={enabled}
@@ -1,14 +1,18 @@
<script lang="ts">
import { run } from 'svelte/legacy';
import IconedResourceType from './IconedResourceType.svelte'
import Toggle from './Toggle.svelte'
export let value: any
interface Props {
value: any;
}
$: enabled = value != undefined
let { value = $bindable() }: Props = $props();
let org = ''
$: changeOrg(org)
let org = $state('')
function changeOrg(org) {
if (value) {
@@ -28,10 +32,14 @@
}
}
}
let enabled = $derived(value != undefined)
run(() => {
changeOrg(org)
});
</script>
<div class="flex flex-col gap-1">
<!-- svelte-ignore a11y-label-has-associated-control -->
<!-- svelte-ignore a11y_label_has_associated_control -->
<label class="text-sm font-medium text-primary flex gap-4 items-center"
><div class="w-[120px]"><IconedResourceType name={'keycloak'} after={true} /></div><Toggle
checked={enabled}
+10 -2
View File
@@ -1,5 +1,13 @@
<script lang="ts">
export let id: string
import { run } from 'svelte/legacy';
$: id && console.log('updateJobId')
interface Props {
id: string;
}
let { id }: Props = $props();
run(() => {
id && console.log('updateJobId')
});
</script>
@@ -1,8 +1,15 @@
<script lang="ts">
import { AnsiUp } from 'ansi_up'
import { createBubbler } from 'svelte/legacy'
export let content: string
export let highlighted: any[]
const bubble = createBubbler()
import { AnsiUp } from 'ansi_up'
interface Props {
content: string
highlighted: any[]
onClick?: () => void
}
let { content, highlighted, onClick }: Props = $props()
const ansi_up = new AnsiUp()
ansi_up.use_classes = true
@@ -30,7 +37,13 @@
let html = highlightSnippet(content)
</script>
<button on:click class="font-light !m-0 !p-0">
<button
onclick={() => {
onClick?.()
bubble('click')
}}
class="font-light !m-0 !p-0"
>
<pre
class="bg-surface-secondary hover:bg-surface px-2 py-1 text-secondary text-xs w-[100%] whitespace-pre border min-w-full text-start">
{@html html}
@@ -1,3 +1,4 @@
<!-- @migration-task Error while migrating Svelte code: $$props is used together with named props in a way that cannot be automatically migrated. -->
<script lang="ts">
import { createPopperActions } from 'svelte-popperjs'
import type { PopoverPlacement } from './Popover.model'
+44 -31
View File
@@ -1,4 +1,6 @@
<script lang="ts">
import { run } from 'svelte/legacy';
import { Map, View, Feature } from 'ol'
import { Fill, Stroke, Style, Text } from 'ol/style.js'
import { useGeographic } from 'ol/proj'
@@ -18,17 +20,26 @@
strokeColor?: string
}
export let lon: number | undefined = undefined
export let lat: number | undefined = undefined
export let zoom: number | undefined = undefined
export let markers: Marker[] | string | undefined = undefined
interface Props {
lon?: number | undefined;
lat?: number | undefined;
zoom?: number | undefined;
markers?: Marker[] | string | undefined;
}
let {
lon = undefined,
lat = undefined,
zoom = undefined,
markers = undefined
}: Props = $props();
const LAYER_NAME = {
MARKER: 'Marker'
} as const
let map: Map | undefined = undefined
let mapElement: HTMLDivElement | undefined = undefined
let map: Map | undefined = $state(undefined)
let mapElement: HTMLDivElement | undefined = $state(undefined)
function getLayersByName(name: keyof typeof LAYER_NAME) {
return map
@@ -100,36 +111,38 @@
createMarkerLayers()?.forEach((l) => map?.addLayer(l))
}
$: if (!map && mapElement) {
useGeographic()
map = new Map({
target: mapElement,
layers: [
new TileLayer({
source: new OSM()
run(() => {
if (!map && mapElement) {
useGeographic()
map = new Map({
target: mapElement,
layers: [
new TileLayer({
source: new OSM()
}),
...(createMarkerLayers() || [])
],
view: new View({
center: [lon ?? 0, lat ?? 0],
zoom: zoom ?? 2
}),
...(createMarkerLayers() || [])
],
view: new View({
center: [lon ?? 0, lat ?? 0],
zoom: zoom ?? 2
}),
controls: defaultControls({
attribution: false
controls: defaultControls({
attribution: false
})
})
})
if (lat && lon) {
map.getView().setCenter([lon, lat])
}
if (lat && lon) {
map.getView().setCenter([lon, lat])
}
if (map && zoom) {
map.getView().setZoom(zoom)
}
if (map && zoom) {
map.getView().setZoom(zoom)
}
if (map && markers) {
updateMarkers()
if (map && markers) {
updateMarkers()
}
}
}
});
</script>
<div bind:this={mapElement} class="w-full h-[300px]"></div>
@@ -1,4 +1,6 @@
<script lang="ts">
import { run } from 'svelte/legacy';
import { type MetricDataPoint, MetricsService } from '$lib/gen'
import { displayTime } from '$lib/utils'
import { enterpriseLicense, workspaceStore } from '$lib/stores'
@@ -17,16 +19,20 @@
ChartJS.register(Title, Tooltip, Legend, LineElement, LinearScale, PointElement, CategoryScale)
export let jobId: string
export let jobUpdateLastFetch: Date | undefined
interface Props {
jobId: string;
jobUpdateLastFetch: Date | undefined;
}
let { jobId, jobUpdateLastFetch }: Props = $props();
let jobMetricsLastFetch: Date | undefined = undefined
let jobMemoryStats: MetricDataPoint[] | undefined = undefined
let jobMemoryStats: MetricDataPoint[] | undefined = $state(undefined)
let data: {
x: number
y: number
}[] = []
}[] = $state([])
let labels: string[] = []
async function loadMetricsData() {
@@ -66,7 +72,9 @@
data = [...data]
}
$: jobUpdateLastFetch && loadMetricsData()
run(() => {
jobUpdateLastFetch && loadMetricsData()
});
</script>
<div class="relative max-h-100">
@@ -5,9 +5,13 @@
import { displayDate } from '$lib/utils'
import { Hourglass } from 'lucide-svelte'
export let type: FlowStatusModule['type']
export let scheduled_for: Date | undefined
export let skipped: boolean = false
interface Props {
type: FlowStatusModule['type'];
scheduled_for: Date | undefined;
skipped?: boolean;
}
let { type, scheduled_for, skipped = false }: Props = $props();
</script>
{#if type == 'WaitingForEvents'}
@@ -11,14 +11,14 @@
type Kind = 'script' | 'resource' | 'schedule' | 'variable' | 'flow' | 'app' | 'raw_app'
let kind: Kind
let initialPath: string = ''
let path: string | undefined = undefined
let summary: undefined | string = undefined
let kind: Kind = $state('script')
let initialPath: string = $state('')
let path: string | undefined = $state(undefined)
let summary: undefined | string = $state(undefined)
let drawer: Drawer
let drawer: Drawer | undefined = $state()
let own = false
let own = $state(false)
export async function openDrawer(
initialPath_l: string,
summary_l: string | undefined,
@@ -29,7 +29,7 @@
initialPath = initialPath_l
summary = summary_l
loadOwner()
drawer.openDrawer()
drawer?.openDrawer()
}
function loadOwner() {
@@ -94,7 +94,7 @@
})
}
dispatch('update', path)
drawer.closeDrawer()
drawer?.closeDrawer()
}
</script>
+24 -11
View File
@@ -1,4 +1,6 @@
<script lang="ts">
import { run } from 'svelte/legacy';
import { X } from 'lucide-svelte'
import CollapseLink from './CollapseLink.svelte'
import IconedResourceType from './IconedResourceType.svelte'
@@ -6,15 +8,22 @@
import { onMount } from 'svelte'
import { enterpriseLicense } from '$lib/stores'
export let name: string
export let value: any
export let login = true
export let eeOnly = false
interface Props {
name: string;
value: any;
login?: boolean;
eeOnly?: boolean;
}
$: enabled = value != undefined && !(eeOnly && !$enterpriseLicense)
let {
name,
value = $bindable(),
login = true,
eeOnly = false
}: Props = $props();
let tenant: string = ''
$: (name == 'microsoft' || name == 'teams') && changeTenantId(tenant)
let tenant: string = $state('')
onMount(() => {
try {
@@ -60,10 +69,14 @@
}
}
}
let enabled = $derived(value != undefined && !(eeOnly && !$enterpriseLicense))
run(() => {
(name == 'microsoft' || name == 'teams') && changeTenantId(tenant)
});
</script>
<div class="flex flex-col">
<!-- svelte-ignore a11y-label-has-associated-control -->
<!-- svelte-ignore a11y_label_has_associated_control -->
<label
class="text-sm flex gap-4 items-center font-medium text-primary {enabled ? 'rounded py-2' : ''}"
><div class="w-[120px]"><IconedResourceType {name} after={true} /></div><Toggle
@@ -116,7 +129,7 @@
class="max-w-96 w-full"
type="text"
bind:value={value['allowed_domains'][idx]}
on:keyup={(e) => {
onkeyup={(e) => {
if (domain == '') {
value['allowed_domains'] = value['allowed_domains']?.filter(
(d) => d != domain
@@ -126,7 +139,7 @@
/>
<button
class="text-primary text-xs rounded hover:bg-surface-hover"
on:click={() => {
onclick={() => {
value['allowed_domains'] = value['allowed_domains']?.filter((d) => d != domain)
if (value['allowed_domains'].length == 0) {
value['allowed_domains'] = undefined
@@ -140,7 +153,7 @@
<div class="flex gap-2">
<button
class="text-primary text-sm border rounded p-1"
on:click={() => {
onclick={() => {
value['allowed_domains'] = [...(value['allowed_domains'] ?? []), 'mydomain.com']
}}>+ Add domain</button
>
@@ -2,9 +2,13 @@
import { Button } from './common'
import { Minus, Plus } from 'lucide-svelte'
export let extra_params: Record<string, string> = {}
interface Props {
extra_params?: Record<string, string>;
}
let extra_params_vec: [string, string][] = Object.entries(extra_params)
let { extra_params = $bindable({}) }: Props = $props();
let extra_params_vec: [string, string][] = $state(Object.entries(extra_params))
function sync() {
extra_params = Object.fromEntries(extra_params_vec)
@@ -13,8 +17,8 @@
{#each extra_params_vec as o}
<div class="flex flex-row max-w-md mb-2">
<input type="text" on:keyup={sync} bind:value={o[0]} />
<input type="text" on:keyup={sync} bind:value={o[1]} />
<input type="text" onkeyup={sync} bind:value={o[0]} />
<input type="text" onkeyup={sync} bind:value={o[1]} />
<Button
variant="default"
destructive
@@ -2,13 +2,17 @@
import { Button } from './common'
import { Minus, Plus } from 'lucide-svelte'
export let scopes: string[] = []
interface Props {
scopes?: string[]
}
let { scopes = $bindable([]) }: Props = $props()
</script>
{#if scopes && Array.isArray(scopes)}
{#each scopes as v}
{#each scopes as v, i}
<div class="flex flex-row max-w-md mb-2">
<input type="text" bind:value={v} />
<input type="text" bind:value={scopes[i]} />
<Button
variant="default"
size="xs"
@@ -1,4 +1,6 @@
<script lang="ts">
import { run } from 'svelte/legacy';
import { Database, Loader2 } from 'lucide-svelte'
import Toggle from './Toggle.svelte'
import { Button, Tab, Tabs } from './common'
@@ -42,13 +44,18 @@
serviceAccountKey: Record<string, string>
}
export let bucket_config: S3Config | AzureConfig | AwsOidcConfig | GcsConfig | undefined =
undefined
interface Props {
bucket_config?: S3Config | AzureConfig | AwsOidcConfig | GcsConfig | undefined;
}
$: bucket_config?.type == 'S3' &&
bucket_config.allow_http == undefined &&
(bucket_config.allow_http = true)
let loading = false
let { bucket_config = $bindable(undefined) }: Props = $props();
run(() => {
bucket_config?.type == 'S3' &&
bucket_config.allow_http == undefined &&
(bucket_config.allow_http = true)
});
let loading = $state(false)
async function testConnection() {
loading = true
+17 -6
View File
@@ -1,10 +1,21 @@
<script lang="ts">
import Tooltip from './Tooltip.svelte'
export let title: string
export let tooltip: string = ''
export let documentationLink: string | undefined = undefined
export let primary: boolean = true
interface Props {
title: string;
tooltip?: string;
documentationLink?: string | undefined;
primary?: boolean;
children?: import('svelte').Snippet;
}
let {
title,
tooltip = '',
documentationLink = undefined,
primary = true,
children
}: Props = $props();
</script>
<div class="flex flex-row flex-wrap justify-between pb-2 my-4 mr-2">
@@ -30,9 +41,9 @@
</span>
{/if}
{#if $$slots.default}
{#if children}
<div class="my-2">
<slot />
{@render children?.()}
</div>
{/if}
</div>
@@ -1,4 +1,6 @@
<script lang="ts">
import { run } from 'svelte/legacy'
import { type GridApi, createGrid, type IDatasource } from 'ag-grid-community'
import 'ag-grid-community/styles/ag-grid.css'
@@ -14,15 +16,19 @@
// import 'ag-grid-community/dist/styles/ag-theme-alpine-dark.css'
let selectedRowIndex = -1
export let s3resource: string
export let storage: string | undefined
export let workspaceId: string | undefined
export let disable_download: boolean = false
interface Props {
s3resource: string
storage: string | undefined
workspaceId: string | undefined
disable_download?: boolean
}
let { s3resource, storage, workspaceId, disable_download = false }: Props = $props()
let lastSearch: string | undefined = undefined
let nbRows: number | undefined = undefined
let csvSeparatorChar: string = ','
let nbRows: number | undefined = $state(undefined)
let csvSeparatorChar: string = $state(',')
let datasource: IDatasource = {
rowCount: 0,
getRows: async function (params) {
@@ -95,11 +101,9 @@
toggleRow(rows[0])
}
let eGui: HTMLDivElement
let eGui: HTMLDivElement | undefined = $state()
$: eGui && mountGrid()
let error: string | undefined = undefined
let error: string | undefined = $state(undefined)
async function mountGrid() {
if (eGui) {
try {
@@ -170,7 +174,10 @@
}
}
let darkMode: boolean = false
let darkMode: boolean = $state(false)
run(() => {
eGui && mountGrid()
})
</script>
<DarkModeObserver bind:darkMode />
@@ -182,7 +189,7 @@
<label for="csvSeparatorChar" class="text-2xs text-secondary">Separator</label>
<div class="w-12 ml-2 mr-2">
<select class="h-8" bind:value={csvSeparatorChar} on:change={(e) => mountGrid()}>
<select class="h-8" bind:value={csvSeparatorChar} onchange={(e) => mountGrid()}>
<option value=",">,</option>
<option value=";">;</option>
<option value="\t">\t</option>
@@ -10,19 +10,19 @@
import { Hourglass, Loader2, Play, RefreshCw } from 'lucide-svelte'
let dispatch = createEventDispatcher()
let drawer: Drawer
let drawer: Drawer | undefined = $state()
let script: Script
let loadQueuedJobs = true
let queuedJobsLoading = false
let script: Script | undefined = $state()
let loadQueuedJobs = $state(true)
let queuedJobsLoading = $state(false)
let queuedJobs: {
status: 'running' | 'queued'
jobId: string
scheduledFor: string
scriptHash: string
}[] = []
}[] = $state([])
let cancellingInProgress = false
let cancellingInProgress = $state(false)
async function continuouslyLoadQueuedJobs() {
while (loadQueuedJobs) {
@@ -40,7 +40,7 @@
let qjs = await JobService.listQueue({
workspace: $workspaceStore ?? '',
orderDesc: false,
scriptPathExact: script.path
scriptPathExact: script?.path
})
let loadingQueuedJobs: {
status: 'running' | 'queued'
@@ -71,12 +71,12 @@
cancellingInProgress = true
await JobService.cancelPersistentQueuedJobs({
workspace: $workspaceStore ?? '',
path: script.path,
path: script?.path ?? '',
requestBody: {
reason: undefined
}
})
sendUserToast(`All jobs cancelled for ${script.path}`)
sendUserToast(`All jobs cancelled for ${script?.path}`)
cancellingInProgress = false
}
@@ -88,12 +88,12 @@
script = persistentScript!
loadQueuedJobs = true
continuouslyLoadQueuedJobs()
drawer.openDrawer?.()
drawer?.openDrawer?.()
}
async function exit() {
loadQueuedJobs = false
drawer.closeDrawer?.()
drawer?.closeDrawer?.()
}
onDestroy(() => {
@@ -117,51 +117,56 @@
>
<div class="flex gap-2 items-center justify-between">
<h2>
Queued jobs for {script.path}
Queued jobs for {script?.path}
</h2>
<Button size="md" btnClasses="w-full h-8" variant="default" on:click={loadQueuedJobsOnce}>
<RefreshCw class={queuedJobsLoading ? 'animate-spin' : ''} size={14} />
</Button>
</div>
<TableCustom>
<!-- @migration-task: migrate this slot by hand, `header-row` is an invalid identifier -->
<tr slot="header-row">
<th class="text-xs">Script Hash</th>
<th class="text-xs">Job ID</th>
<th class="text-xs">Status</th>
<th class="text-xs">Scheduled For</th>
</tr>
<tbody slot="body">
{#each queuedJobs as { jobId, status, scriptHash, scheduledFor }}
<tr class="">
<td class="text-xs">
<a
class="pr-3"
href="{base}/scripts/get/{scriptHash}?workspace={$workspaceStore}"
target="_blank"
>
{scriptHash}
</a>
</td>
<td class="text-xs">
<a class="pr-3" href="{base}/run/{jobId}?workspace={$workspaceStore}" target="_blank"
>{jobId.substring(24)}</a
>
</td>
<td class="text-xs">
{#if status === 'running'}
<Badge color="yellow" baseClass="!px-1.5">
<Play size={14} />
</Badge>
{:else}
<Badge baseClass="!px-1.5">
<Hourglass size={14} />
</Badge>
{/if}
</td>
<td class="text-xs">{scheduledFor}</td>
</tr>
{/each}
</tbody>
{#snippet body()}
<tbody>
{#each queuedJobs as { jobId, status, scriptHash, scheduledFor }}
<tr class="">
<td class="text-xs">
<a
class="pr-3"
href="{base}/scripts/get/{scriptHash}?workspace={$workspaceStore}"
target="_blank"
>
{scriptHash}
</a>
</td>
<td class="text-xs">
<a
class="pr-3"
href="{base}/run/{jobId}?workspace={$workspaceStore}"
target="_blank">{jobId.substring(24)}</a
>
</td>
<td class="text-xs">
{#if status === 'running'}
<Badge color="yellow" baseClass="!px-1.5">
<Play size={14} />
</Badge>
{:else}
<Badge baseClass="!px-1.5">
<Hourglass size={14} />
</Badge>
{/if}
</td>
<td class="text-xs">{scheduledFor}</td>
</tr>
{/each}
</tbody>
{/snippet}
</TableCustom>
{#snippet actions()}
@@ -1,4 +1,7 @@
<script lang="ts">
import { run, createBubbler, preventDefault } from 'svelte/legacy'
const bubble = createBubbler()
import { onMount } from 'svelte'
import { Drawer, DrawerContent, Button } from './common'
import QueueMetricsDrawerInner from './QueueMetricsDrawerInner.svelte'
@@ -21,24 +24,26 @@
}
}
let drawer: Drawer
let drawer: Drawer | undefined = $state()
export function openDrawer() {
drawer?.openDrawer()
}
let alerts: Alert[] = []
let alerts: Alert[] = $state([])
let configName = 'alert__job_queue_waiting'
let originalAlerts: Alert[] = []
let newTag = ''
let editingIndex = -1
let changesMade = false
let removedAlerts: Alert[] = []
let newTag = $state('')
let editingIndex = $state(-1)
let changesMade = $state(false)
let removedAlerts: Alert[] = $state([])
let stagedNewAlert = false
let workerTags: string[] = []
let filteredTags: string[] = []
let workerTags: string[] = $state([])
let filteredTags: string[] = $state([])
$: removedAlerts
run(() => {
removedAlerts
})
onMount(async () => {
await fetchConfig()
@@ -234,7 +239,7 @@
{#if alerts.length > 0}
<div>
<form on:submit|preventDefault>
<form onsubmit={preventDefault(bubble('submit'))}>
<table class="w-full border-collapse mb-2 text-xs table-auto">
<thead class="bg-gray-200 dark:bg-slate-600 text-left text-xs">
<tr>
@@ -263,7 +268,7 @@
<th class="p-2 min-w-[100px]"> Actions </th>
</tr>
</thead>
<tbody on:input={handleInput}>
<tbody oninput={handleInput}>
{#each alerts as alert, index}
<tr
class={removedAlerts.includes(alert)
@@ -279,7 +284,7 @@
>
{tag}
<button
on:click={() => removeTag(index, tag)}
onclick={() => removeTag(index, tag)}
aria-label="Remove tag"
class="ml-1 text-xs">x</button
>
@@ -293,17 +298,17 @@
placeholder={workerTags.length === alert.tags_to_monitor.length
? 'All tags already added'
: 'Add tag from dropdown'}
on:input={(e) => filterTags(e)}
oninput={(e) => filterTags(e)}
disabled={workerTags.length === alert.tags_to_monitor.length}
class="p-1 flex-grow mr-1"
/>
<button on:click={() => addTag(index, newTag)} aria-label="Add tag">
<button onclick={() => addTag(index, newTag)} aria-label="Add tag">
<PlusCircle size={16} />
</button>
</div>
<!-- Add the new "Add All Tags" button here -->
<button
on:click={() => addAllTags(index)}
onclick={() => addAllTags(index)}
class="text-xs hover:bg-gray-200 dark:hover:bg-gray-700 rounded px-2 py-1 mt-1"
disabled={workerTags.length === alert.tags_to_monitor.length}
>
@@ -319,7 +324,7 @@
<button
type="button"
class="w-full text-left p-2 cursor-pointer hover:bg-slate-200 dark:hover:bg-slate-700"
on:click={() => addTag(index, tag)}
onclick={() => addTag(index, tag)}
>
{tag}
</button>
@@ -375,14 +380,14 @@
<td class="border p-2">
<div class="flex gap-3 justify-center items-center">
{#if editingIndex === index}
<button on:click={() => saveAlert(index)} aria-label="Save">
<button onclick={() => saveAlert(index)} aria-label="Save">
<Check size={16} />
</button>
{:else}
<button on:click={() => startEditing(index)} aria-label="Edit">
<button onclick={() => startEditing(index)} aria-label="Edit">
<Pencil size={16} />
</button>
<button on:click={() => stageDeleteAlert(index)} aria-label="Delete">
<button onclick={() => stageDeleteAlert(index)} aria-label="Delete">
<Trash size={16} />
</button>
{/if}
@@ -1,4 +1,6 @@
<script lang="ts">
import { run } from 'svelte/legacy';
import 'chartjs-adapter-date-fns'
import { Line } from '$lib/components/chartjs-wrappers/chartJs'
@@ -21,7 +23,7 @@
import DarkModeObserver from './DarkModeObserver.svelte'
import Alert from './common/alert/Alert.svelte'
let loading: boolean = true
let loading: boolean = $state(true)
const colorTuples = [
['#7EB26D', 'rgba(126, 178, 109, 0.2)'],
@@ -63,12 +65,12 @@
LogarithmicScale
)
let countData: ChartData<'line', Point[], undefined> | undefined = undefined
let delayData: ChartData<'line', Point[], undefined> | undefined = undefined
let countData: ChartData<'line', Point[], undefined> | undefined = $state(undefined)
let delayData: ChartData<'line', Point[], undefined> | undefined = $state(undefined)
let minDate = new Date()
let minDate = $state(new Date())
let noMetrics = false
let noMetrics = $state(false)
function fillData(
data: {
@@ -178,10 +180,14 @@
loadMetrics()
let darkMode = false
let darkMode = $state(false)
$: ChartJS.defaults.color = darkMode ? '#ccc' : '#666'
$: ChartJS.defaults.borderColor = darkMode ? 'rgba(255, 255, 255, 0.1)' : 'rgba(0, 0, 0, 0.1)'
run(() => {
ChartJS.defaults.color = darkMode ? '#ccc' : '#666'
});
run(() => {
ChartJS.defaults.borderColor = darkMode ? 'rgba(255, 255, 255, 0.1)' : 'rgba(0, 0, 0, 0.1)'
});
</script>
<DarkModeObserver bind:darkMode />
+18 -7
View File
@@ -1,13 +1,24 @@
<script lang="ts">
export let label = ''
export let options: [string | { title: string; desc: string }, any][]
export let value: any
export let disabled = false
export let labelClass = ''
export let inputClass = ''
import { createEventDispatcher } from 'svelte'
import Tooltip from './Tooltip.svelte'
interface Props {
label?: string;
options: [string | { title: string; desc: string }, any][];
value: any;
disabled?: boolean;
labelClass?: string;
inputClass?: string;
}
let {
label = '',
options,
value = $bindable(),
disabled = false,
labelClass = '',
inputClass = ''
}: Props = $props();
const dispatch = createEventDispatcher()
</script>
@@ -28,7 +39,7 @@
class="sr-only"
bind:group={value}
aria-labelledby="memory-option-0-label"
on:click={() => dispatch('change', val)}
onclick={() => dispatch('change', val)}
/>
<p>
{#if typeof label !== 'string'}
+35 -17
View File
@@ -1,29 +1,47 @@
<script lang="ts">
import { run, createBubbler, stopPropagation } from 'svelte/legacy'
const bubble = createBubbler()
import RangeSlider from 'svelte-range-slider-pips'
export let min = 0
export let max = 100
export let initialValue = 0
export let value = typeof initialValue === 'string' ? parseInt(initialValue) : initialValue
export let disabled: boolean = false
export let defaultValue: number | undefined = undefined
export let format: (value: number) => string = (v) => `${v}`
export let hideInput: boolean = false
interface Props {
min?: number
max?: number
initialValue?: number
value?: any
disabled?: boolean
defaultValue?: number | undefined
format?: (value: number) => string
hideInput?: boolean
}
let {
min = 0,
max = 100,
initialValue = 0,
value = $bindable(typeof initialValue === 'string' ? parseInt(initialValue) : initialValue),
disabled = false,
defaultValue = undefined,
format = (v) => `${v}`,
hideInput = false
}: Props = $props()
let step: number = 1
let slider: HTMLElement
let slider: HTMLElement | undefined = $state()
function calculateAxisStep(min: number, max: number): number {
const range = max - min
return range < 100 ? 1 : range / 20
}
$: if (value === null) {
value = 0
}
run(() => {
if (value === null) {
value = 0
}
})
$: axisStep = calculateAxisStep(min, max)
let axisStep = $derived(calculateAxisStep(min, max))
function handleKeyDown(event: KeyboardEvent) {
if (disabled) return
@@ -44,17 +62,17 @@
}
// Calculate the handle width based on the length of the max value
$: handleWidth = `${Math.max(max.toString().length ?? 2, 2)}em`
let handleWidth = $derived(`${Math.max(max.toString().length ?? 2, 2)}em`)
</script>
<div class="flex flex-row w-full mx-2 items-center gap-8">
<!-- svelte-ignore a11y-no-static-element-interactions -->
<!-- svelte-ignore a11y_no_static_element_interactions -->
<div
class={'grow'}
style="--range-handle-focus: {'#7e9abd'}; --range-handle: {'#7e9abd'}; --handle-width: {handleWidth}; --handle-border: 4px;"
on:pointerdown|stopPropagation
on:keydown={handleKeyDown}
onpointerdown={stopPropagation(bubble('pointerdown'))}
onkeydown={handleKeyDown}
>{#if max <= min}
<div class="text-secondary text-sm"
>Impossible to display range: {`max (${max}) <= min (${min})`}</div
@@ -1,3 +1,4 @@
<!-- @migration-task Error while migrating Svelte code: $$props is used together with named props in a way that cannot be automatically migrated. -->
<script lang="ts">
export let required: boolean
export let detail = ''
@@ -1,26 +1,29 @@
<script lang="ts">
import { run } from 'svelte/legacy'
import { Button, Drawer } from './common'
import DrawerContent from './common/drawer/DrawerContent.svelte'
import { Loader2, Save } from 'lucide-svelte'
import { untrack } from 'svelte'
let drawer: Drawer
let canSave = true
let resource_type: string | undefined = undefined
let defaultValues: Record<string, any> | undefined = undefined
let drawer: Drawer | undefined = $state()
let canSave = $state(true)
let resource_type: string | undefined = $state(undefined)
let defaultValues: Record<string, any> | undefined = $state(undefined)
let resourceEditor: { editResource: () => void; createResource: () => void } | undefined =
undefined
$state(undefined)
let path: string | undefined = undefined
let path: string | undefined = $state(undefined)
let newResource = false
let newResource = $state(false)
export async function initEdit(p: string): Promise<void> {
resource_type = undefined
newResource = false
path = p
drawer.openDrawer?.()
drawer?.openDrawer?.()
}
export async function initNew(
@@ -31,12 +34,14 @@
path = undefined
resource_type = resourceType
defaultValues = nDefaultValues
drawer.openDrawer?.()
drawer?.openDrawer?.()
}
let mode: 'edit' | 'new' = newResource ? 'new' : 'edit'
let mode: 'edit' | 'new' = $state(untrack(() => newResource) ? 'new' : 'edit')
$: path ? (mode = 'edit') : (mode = 'new')
run(() => {
path ? (mode = 'edit') : (mode = 'new')
})
</script>
<Drawer bind:this={drawer} size="800px">
@@ -68,7 +73,7 @@
} else {
resourceEditor?.createResource()
}
drawer.closeDrawer()
drawer?.closeDrawer()
}}
disabled={!canSave}
>
+13 -4
View File
@@ -2,10 +2,19 @@
import { Button } from '$lib/components/common'
import { CornerDownLeft, Loader2 } from 'lucide-svelte'
export let isLoading
export let hideShortcut = false
export let onRun: () => Promise<void>
export let onCancel: () => Promise<void>
interface Props {
isLoading: any;
hideShortcut?: boolean;
onRun: () => Promise<void>;
onCancel: () => Promise<void>;
}
let {
isLoading,
hideShortcut = false,
onRun,
onCancel
}: Props = $props();
</script>
{#if !isLoading}
@@ -8,7 +8,9 @@
import { WorkerService } from '$lib/gen'
import DateTimeInput from './DateTimeInput.svelte'
export let runnable:
interface Props {
runnable:
| {
summary?: string
description?: string
@@ -21,11 +23,18 @@
created_by?: string
extra_perms?: Record<string, boolean>
}
| undefined
| undefined;
scheduledForStr: string | undefined;
invisible_to_owner: boolean | undefined;
overrideTag: string | undefined;
}
export let scheduledForStr: string | undefined
export let invisible_to_owner: boolean | undefined
export let overrideTag: string | undefined
let {
runnable,
scheduledForStr = $bindable(),
invisible_to_owner = $bindable(),
overrideTag = $bindable()
}: Props = $props();
loadWorkerGroups()
async function loadWorkerGroups() {
@@ -11,15 +11,19 @@
import S3FilePicker from './S3FilePicker.svelte'
import FileUpload from './common/fileUpload/FileUpload.svelte'
export let value: any
export let editor: SimpleEditor | undefined = undefined
interface Props {
value: any
editor?: SimpleEditor | undefined
}
let { value = $bindable(), editor = $bindable(undefined) }: Props = $props()
const dispatch = createEventDispatcher()
let s3FilePicker: S3FilePicker
let s3FileUploadRawMode: false
let s3FilePicker: S3FilePicker | undefined = $state()
let s3FileUploadRawMode: false | undefined = $state()
let el: HTMLTextAreaElement | undefined = undefined
let rawValue: string | undefined = undefined
let rawValue: string | undefined = $state(undefined)
function evalValueToRaw() {
rawValue = JSON.stringify(value, null, 2)
@@ -10,14 +10,25 @@
const dispatch = createEventDispatcher()
export let runnableId: string | undefined
export let runnableType: RunnableType | undefined
export let args: object
export let disabled: boolean = false
export let small: boolean | undefined = undefined
export let showTooltip: boolean | undefined = undefined
interface Props {
runnableId: string | undefined;
runnableType: RunnableType | undefined;
args: object;
disabled?: boolean;
small?: boolean | undefined;
showTooltip?: boolean | undefined;
}
let savingInputs = false
let {
runnableId,
runnableType,
args,
disabled = false,
small = undefined,
showTooltip = undefined
}: Props = $props();
let savingInputs = $state(false)
async function saveInput(args: object) {
savingInputs = true
@@ -1,4 +1,7 @@
<script lang="ts">
import { run, createBubbler } from 'svelte/legacy';
const bubble = createBubbler();
import { Button } from '$lib/components/common'
import Popover from '$lib/components/meltComponents/Popover.svelte'
import ObjectViewerWrapper from '$lib/components/propertyPicker/ObjectViewerWrapper.svelte'
@@ -6,12 +9,23 @@
import { Eye, CopyIcon, Loader2 } from 'lucide-svelte'
import { createEventDispatcher } from 'svelte'
export let payloadData: any
export let limitPayloadSize: boolean = false
export let hover: boolean = false
export let viewerOpen: boolean = false
export let maxWidth: number | undefined = undefined
export let editOptions: boolean = true
interface Props {
payloadData: any;
limitPayloadSize?: boolean;
hover?: boolean;
viewerOpen?: boolean;
maxWidth?: number | undefined;
editOptions?: boolean;
}
let {
payloadData,
limitPayloadSize = false,
hover = false,
viewerOpen = false,
maxWidth = undefined,
editOptions = true
}: Props = $props();
const dispatch = createEventDispatcher()
const payloadTooBigForPreview = payloadData != 'WINDMILL_TOO_BIG' && isObjectTooBig(payloadData)
@@ -32,11 +46,11 @@
}
const xOffset = editOptions ? 218 : 168 // width of the optional buttons on the right
let popover: Popover | undefined
let popover: Popover | undefined = $state()
let popoverOpen = false
let hoverTimeout: ReturnType<typeof setTimeout> | undefined
let objectViewerLoaded = false
let popoverFullyOpened = false
let objectViewerLoaded = $state(false)
let popoverFullyOpened = $state(false)
function handlePopoverChange(event: CustomEvent<boolean>) {
const isOpen = event.detail
@@ -73,8 +87,10 @@
}
}
$: handleHoverChange(hover)
$: ajustedWidth = maxWidth ? Math.abs(maxWidth - xOffset) : undefined
run(() => {
handleHoverChange(hover)
});
let ajustedWidth = $derived(maxWidth ? Math.abs(maxWidth - xOffset) : undefined)
</script>
<Popover
@@ -88,75 +104,79 @@
closeOnClickOutside={false}
usePointerDownOutside
>
<svelte:fragment slot="trigger" let:isOpen>
<Button
variant="subtle"
unifiedSize="sm"
btnClasses={hover || isOpen ? 'block -my-2 bg-transparent' : 'hidden'}
wrapperClasses="p-0"
iconOnly
nonCaptureEvent
startIcon={{ icon: Eye }}
/>
</svelte:fragment>
<svelte:fragment slot="content">
<div
class="p-2 overflow-auto"
style="width: {ajustedWidth ? ajustedWidth + 'px' : '50vh'}; max-height: 50vh"
>
{#if payloadData === 'WINDMILL_TOO_BIG'}
<div class="text-center text-primary text-xs">
{#if limitPayloadSize}
Payload too big to be used
{:else}
Payload too big to preview but can still be loaded
{/if}
</div>
{:else}
<div
class="relative p-2"
role="button"
tabindex="0"
aria-label="Copy JSON payload to clipboard"
on:click={() => {
{#snippet trigger({ isOpen })}
<Button
variant="subtle"
unifiedSize="sm"
btnClasses={hover || isOpen ? 'block -my-2 bg-transparent' : 'hidden'}
wrapperClasses="p-0"
iconOnly
nonCaptureEvent
startIcon={{ icon: Eye }}
/>
{/snippet}
{#snippet content()}
<div
class="p-2 overflow-auto"
style="width: {ajustedWidth ? ajustedWidth + 'px' : '50vh'}; max-height: 50vh"
>
{#if payloadData === 'WINDMILL_TOO_BIG'}
<div class="text-center text-primary text-xs">
{#if limitPayloadSize}
Payload too big to be used
{:else}
Payload too big to preview but can still be loaded
{/if}
</div>
{:else}
<div
class="relative p-2"
role="button"
tabindex="0"
aria-label="Copy JSON payload to clipboard"
onclick={() => {
copyToClipboard(JSON.stringify(payloadData))
}}
on:keydown
>
{#if !objectViewerLoaded && payloadTooBigForPreview}
<div class="flex justify-center items-center py-4">
<Loader2 size={20} class="animate-spin text-primary" />
<span class="ml-2 text-xs text-primary">Loading data...</span>
</div>
{/if}
onkeydown={bubble('keydown')}
>
{#if !objectViewerLoaded && payloadTooBigForPreview}
<div class="flex justify-center items-center py-4">
<Loader2 size={20} class="animate-spin text-primary" />
<span class="ml-2 text-xs text-primary">Loading data...</span>
</div>
{/if}
{#if popoverFullyOpened || !payloadTooBigForPreview}
<div
class={!objectViewerLoaded && payloadTooBigForPreview
? 'invisible h-0 overflow-hidden'
: ''}
>
<ObjectViewerWrapper
json={payloadData}
allowCopy
pureViewer
on:mounted={() => (objectViewerLoaded = true)}
{#if popoverFullyOpened || !payloadTooBigForPreview}
<div
class={!objectViewerLoaded && payloadTooBigForPreview
? 'invisible h-0 overflow-hidden'
: ''}
>
<ObjectViewerWrapper
json={payloadData}
allowCopy
pureViewer
on:mounted={() => (objectViewerLoaded = true)}
/>
</div>
{/if}
<div class="absolute top-2 right-2 w-full h-full">
<Button
variant="subtle"
unifiedSize="sm"
class="absolute top-0 right-0"
iconOnly
startIcon={{ icon: CopyIcon }}
nonCaptureEvent
/>
</div>
{/if}
<div class="absolute top-2 right-2 w-full h-full">
<Button
variant="subtle"
unifiedSize="sm"
class="absolute top-0 right-0"
iconOnly
startIcon={{ icon: CopyIcon }}
nonCaptureEvent
/>
</div>
</div>
{/if}
</div>
</svelte:fragment>
{/if}
</div>
{/snippet}
</Popover>
@@ -2,7 +2,11 @@
import type { SchemaProperty } from '$lib/common'
import Badge from './common/badge/Badge.svelte'
export let property: SchemaProperty
interface Props {
property: SchemaProperty;
}
let { property }: Props = $props();
</script>
<div class="flex flex-row flex-wrap gap-1">
@@ -1,4 +1,6 @@
<script lang="ts">
import { run } from 'svelte/legacy'
import { Pane, Splitpanes } from 'svelte-splitpanes'
import FlowInputEditor from '$lib/components/flows/content/FlowInputEditor.svelte'
import HistoricInputs from '$lib/components/HistoricInputs.svelte'
@@ -7,16 +9,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,18 +92,23 @@
]
}
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 loading = false
let captureTable: CaptureTable | undefined = undefined
let historicInputs: HistoricInputs | undefined = undefined
$: (selectedTab, (dropdownItems = getDropdownItems()))
let savedInputsPicker: SavedInputsPicker | undefined = $state(undefined)
let loading = $state(false)
let captureTable: CaptureTable | undefined = $state(undefined)
let historicInputs: HistoricInputs | undefined = $state(undefined)
run(() => {
;[selectedTab]
untrack(() => {
dropdownItems = getDropdownItems()
})
})
let inputPanelSize = 70
let inputPanelSize = $state(70)
</script>
<div class="h-fit">
@@ -100,7 +120,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>
@@ -109,11 +129,13 @@
<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} onClick={() => historicInputs?.refresh()} />
</div>
</svelete:fragment>
{#snippet action()}
<svelete:fragment>
<div class="center-center">
<RefreshButton {loading} onClick={() => historicInputs?.refresh()} />
</div>
</svelete:fragment>
{/snippet}
<HistoricInputs
bind:loading
bind:this={historicInputs}
@@ -140,11 +162,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}
@@ -40,7 +40,8 @@
<div class="flex flex-row">
<TableCustom>
<!-- @migration-task: migrate this slot by hand, `header-row` is an invalid identifier -->
<tr slot="header-row" class="underline">
<!-- @migration-task: migrate this slot by hand, `header-row` is an invalid identifier -->
<tr slot="header-row" class="underline">
<th>name</th>
<th>type</th>
<th>description</th>
@@ -1,3 +1,5 @@
<!-- @migration-task Error while migrating Svelte code: Can only bind to an Identifier or MemberExpression or a `{get, set}` pair
https://svelte.dev/e/bind_invalid_expression -->
<script lang="ts">
import { createBubbler } from 'svelte/legacy'
+14 -9
View File
@@ -2,14 +2,19 @@
import { onMount, onDestroy } from 'svelte'
import { twMerge } from 'tailwind-merge'
let isAtBottom: boolean = false
let isScrollable = false
let isAtBottom: boolean = $state(false)
let isScrollable = $state(false)
export let id: string | null | undefined = undefined
export let scrollableClass: string = ''
export let shiftedShadow: boolean = false
interface Props {
id?: string | null | undefined
scrollableClass?: string
shiftedShadow?: boolean
children?: import('svelte').Snippet
}
let { id = undefined, scrollableClass = '', shiftedShadow = false, children }: Props = $props()
let mutationObserver: MutationObserver
let el: HTMLDivElement
let el: HTMLDivElement | undefined = $state()
function handleScroll(event) {
const scrollableElement = event.target
@@ -33,7 +38,7 @@
}
export function scrollIntoView(top: number) {
el.scrollTo({ top, behavior: 'smooth' })
el?.scrollTo({ top, behavior: 'smooth' })
}
onMount(() => {
observeScrollability(el)
@@ -45,8 +50,8 @@
</script>
<div {id} class={twMerge('relative pb-1', scrollableClass)}>
<div bind:this={el} on:scroll={handleScroll} class="w-full h-full overflow-y-auto">
<slot />
<div bind:this={el} onscroll={handleScroll} class="w-full h-full overflow-y-auto">
{@render children?.()}
</div>
{#if !isAtBottom && isScrollable}
<div
@@ -19,7 +19,7 @@
import SplitPanesOrColumnOnMobile from './splitPanes/SplitPanesOrColumnOnMobile.svelte'
import Select from './select/Select.svelte'
import { goto } from '$lib/navigation'
import { page } from '$app/stores'
import { page } from '$app/state'
interface Props {
searchTerm: string
@@ -32,8 +32,8 @@
let minTs: undefined | string = $state(undefined)
let maxTs: undefined | string = $state(undefined)
let minTsManual: undefined | string = $state($page.url.searchParams.get('minTs') ?? undefined)
let maxTsManual: undefined | string = $state($page.url.searchParams.get('maxTs') ?? undefined)
let minTsManual: undefined | string = $state(page.url.searchParams.get('minTs') ?? undefined)
let maxTsManual: undefined | string = $state(page.url.searchParams.get('maxTs') ?? undefined)
let max_lines: undefined | number = $state(undefined)
@@ -171,13 +171,13 @@
type Selected = { mode: string; workerGroup: string; hostname: string }
let initialSelected =
$page.url.searchParams.get('mode') &&
$page.url.searchParams.get('workerGroup') &&
$page.url.searchParams.get('hostname')
page.url.searchParams.get('mode') &&
page.url.searchParams.get('workerGroup') &&
page.url.searchParams.get('hostname')
? {
mode: $page.url.searchParams.get('mode')!,
workerGroup: $page.url.searchParams.get('workerGroup')!,
hostname: $page.url.searchParams.get('hostname')!
mode: page.url.searchParams.get('mode')!,
workerGroup: page.url.searchParams.get('workerGroup')!,
hostname: page.url.searchParams.get('hostname')!
}
: undefined
let selected: Selected | undefined = $state(initialSelected)
@@ -710,7 +710,7 @@
<LogSnippetViewer
content={snippet_fragment || document.logs[0]}
highlighted={snippet_highlighted}
on:click={() => {
onClick={() => {
let logLineNumber = document.line_number[0]
let logFile = document.file_name[0]
let host = document.host[0]
@@ -155,7 +155,8 @@
{#if acls?.length > 0}
<TableCustom>
<!-- @migration-task: migrate this slot by hand, `header-row` is an invalid identifier -->
<tr slot="header-row">
<!-- @migration-task: migrate this slot by hand, `header-row` is an invalid identifier -->
<tr slot="header-row">
<th>owner</th>
<th></th>
<th></th>
+16 -5
View File
@@ -5,10 +5,21 @@
import Tooltip from './Tooltip.svelte'
import { twMerge } from 'tailwind-merge'
export let text: string
export let tooltip: string | undefined = undefined
export let view = false
export let size: 'xs' | 'sm' | 'md' | 'lg' = 'md'
interface Props {
text: string;
tooltip?: string | undefined;
view?: boolean;
size?: 'xs' | 'sm' | 'md' | 'lg';
children?: import('svelte').Snippet;
}
let {
text,
tooltip = undefined,
view = $bindable(false),
size = 'md',
children
}: Props = $props();
</script>
<Button
@@ -26,5 +37,5 @@
{/if}
</Button>
{#if view}
<div class="my-4 px-2" transition:slide|local><slot /></div>
<div class="my-4 px-2" transition:slide|local>{@render children?.()}</div>
{/if}
+17 -9
View File
@@ -1,16 +1,22 @@
<script lang="ts">
import { preventDefault } from 'svelte/legacy'
import { FavoriteService } from '$lib/gen'
import { starStore } from '$lib/stores'
import { sendUserToast } from '$lib/toast'
import { createEventDispatcher } from 'svelte'
import { Star, StarOff } from 'lucide-svelte'
export let path: string
export let kind: 'flow' | 'app' | 'script' | 'raw_app'
export let starred = false
export let workspace_id: string
interface Props {
path: string
kind: 'flow' | 'app' | 'script' | 'raw_app'
starred?: boolean
workspace_id: string
}
let buttonHover = false
let { path, kind, starred = false, workspace_id }: Props = $props()
let buttonHover = $state(false)
async function onClick() {
buttonHover = false
@@ -31,13 +37,15 @@
}
dispatch('starred', !starred)
}
const dispatch = createEventDispatcher()
const dispatch = createEventDispatcher<{
starred: boolean
}>()
</script>
<button
on:click|preventDefault={onClick}
on:mouseenter={() => (buttonHover = true)}
on:mouseleave={() => (buttonHover = false)}
onclick={preventDefault(onClick)}
onmouseenter={() => (buttonHover = true)}
onmouseleave={() => (buttonHover = false)}
class="p-2"
>
{#if starred}
+6 -2
View File
@@ -2,8 +2,12 @@
import { Pen } from 'lucide-svelte'
import TextInput from './text_input/TextInput.svelte'
export let value: string
export let disabled = false
interface Props {
value: string;
disabled?: boolean;
}
let { value = $bindable(), disabled = false }: Props = $props();
function blur(e: KeyboardEvent) {
e.key === 'Enter' && (e?.target as any)?.blur()
@@ -1,4 +1,6 @@
<script lang="ts">
import { run } from 'svelte/legacy'
import { Loader2, RotateCwIcon } from 'lucide-svelte'
import { Button, DrawerContent } from './common'
@@ -15,16 +17,16 @@
import { createEventDispatcher } from 'svelte'
import HighlightTheme from './HighlightTheme.svelte'
let drawer: Drawer
let token: undefined | string = undefined
let drawer: Drawer | undefined = $state()
let token: undefined | string = $state(undefined)
export async function open() {
token = $oauthStore?.access_token ?? ''
drawer.openDrawer?.()
drawer?.openDrawer?.()
step = 'init'
description = ''
}
let step: 'init' | 'resource' = 'init'
let step: 'init' | 'resource' = $state('init')
async function listDatabases() {
if (!token) return
@@ -44,31 +46,33 @@
region: string
id: string
}
let databases: undefined | Database[] = undefined
let databases: undefined | Database[] = $state(undefined)
$: token != undefined && listDatabases()
run(() => {
token != undefined && listDatabases()
})
let selectedDatabase: undefined | Database = undefined
let selectedDatabase: undefined | Database = $state(undefined)
let description = ''
let pathError = ''
let password = ''
let path: string | undefined = undefined
let description = $state('')
let pathError = $state('')
let password = $state('')
let path: string | undefined = $state(undefined)
/**
* https://github.com/orgs/supabase/discussions/17817
* host is in the format of `aws-0-${region}.pooler.supabase.com`
* user is in the format of `postgres.${id}`
*/
$: resourceValue = {
let resourceValue = $derived.by(() => ({
host: `aws-0-${selectedDatabase?.region}.pooler.supabase.com`,
user: `postgres.${selectedDatabase?.id}`,
port: 5432,
dbname: 'postgres',
sslmode: 'prefer',
password: `$var:${path}`
}
$: disabled = path == undefined || pathError != '' || path == ''
}))
let disabled = $derived(path == undefined || pathError != '' || path == '')
const dispatch = createEventDispatcher()
async function save() {
@@ -95,7 +99,7 @@
})
sendUserToast('Saved postgres resource')
dispatch('refresh')
drawer.closeDrawer?.()
drawer?.closeDrawer?.()
}
</script>
@@ -120,7 +124,7 @@
{#each databases as database}
<button
class="btn btn-outline-primary mt-2 border p-2 w-full border-secondary-inverse hover:border-secondary rounded"
on:click={() => {
onclick={() => {
selectedDatabase = database
step = 'resource'
@@ -6,7 +6,7 @@
import { sendUserToast } from '$lib/toast'
import { base } from '$lib/base'
import SearchItems from './SearchItems.svelte'
import { page } from '$app/stores'
import { page } from '$app/state'
import { goto as gotoUrl } from '$app/navigation'
import Version from './Version.svelte'
import Uptodate from './Uptodate.svelte'
@@ -31,9 +31,9 @@
let { closeDrawer } = $props()
function removeHash() {
const index = $page.url.href.lastIndexOf('#')
const index = page.url.href.lastIndexOf('#')
if (index === -1) return
const hashRemoved = $page.url.href.slice(0, index)
const hashRemoved = page.url.href.slice(0, index)
gotoUrl(hashRemoved)
}
@@ -209,7 +209,8 @@
<div class="mt-2 overflow-auto">
<TableCustom>
<!-- @migration-task: migrate this slot by hand, `header-row` is an invalid identifier -->
<tr slot="header-row" class="sticky top-0 bg-surface border-b">
<!-- @migration-task: migrate this slot by hand, `header-row` is an invalid identifier -->
<tr slot="header-row" class="sticky top-0 bg-surface border-b">
<th>email</th>
<th>auth</th>
<th>name</th>
@@ -1,3 +1,4 @@
<!-- @migration-task Error while migrating Svelte code: $$props is used together with named props in a way that cannot be automatically migrated. -->
<script lang="ts">
import { createEventDispatcher } from 'svelte'
@@ -1,3 +1,4 @@
<!-- @migration-task Error while migrating Svelte code: $$props is used together with named props in a way that cannot be automatically migrated. -->
<script module>
import '@codingame/monaco-vscode-standalone-typescript-language-features'
</script>
@@ -7,10 +7,19 @@
import { workspaceStore } from '$lib/stores'
import { tryEvery } from '$lib/utils'
export let workspaceOverride: string | undefined = undefined
export let resourceType: string | undefined
export let args: Record<string, any> | any = {}
export let buttonTextOverride: string | undefined = undefined
interface Props {
workspaceOverride?: string | undefined;
resourceType: string | undefined;
args?: Record<string, any> | any;
buttonTextOverride?: string | undefined;
}
let {
workspaceOverride = undefined,
resourceType,
args = {},
buttonTextOverride = undefined
}: Props = $props();
const scripts: {
[key: string]: {
@@ -166,7 +175,7 @@ export async function main(bucket: any) {
}
}
let loading = false
let loading = $state(false)
async function testConnection() {
if (!resourceType) return
loading = true
+19 -6
View File
@@ -1,18 +1,28 @@
<script lang="ts">
import { run } from 'svelte/legacy';
import { getDbClockNow } from '$lib/forLater'
import { displayDate } from '$lib/utils'
import { onDestroy, onMount } from 'svelte'
export let date: string
export let agoOnlyIfRecent: boolean = false
export let noDate = false
export let isRecent: boolean = true
interface Props {
date: string;
agoOnlyIfRecent?: boolean;
noDate?: boolean;
isRecent?: boolean;
}
let computedTimeAgo: string | undefined = undefined
let {
date,
agoOnlyIfRecent = false,
noDate = false,
isRecent = $bindable(true)
}: Props = $props();
let computedTimeAgo: string | undefined = $state(undefined)
let interval
$: date && computeDate()
onMount(() => {
interval = setInterval(() => {
@@ -73,6 +83,9 @@
}
}
}
run(() => {
date && computeDate()
});
</script>
{#if computedTimeAgo && (!agoOnlyIfRecent || isRecent)}
@@ -2,8 +2,13 @@
import Markdown from 'svelte-exmarkdown'
import { ExternalLink } from 'lucide-svelte'
import { gfmPlugin } from 'svelte-exmarkdown/gfm'
export let documentationLink: string | undefined = undefined
export let markdownTooltip: string | undefined = undefined
interface Props {
documentationLink?: string | undefined;
markdownTooltip?: string | undefined;
children?: import('svelte').Snippet;
}
let { documentationLink = undefined, markdownTooltip = undefined, children }: Props = $props();
const plugins = [gfmPlugin()]
</script>
@@ -15,7 +20,7 @@
<Markdown md={markdownTooltip} {plugins} />
</div>
{:else}
<slot />
{@render children?.()}
{/if}
{#if documentationLink}
+1 -1
View File
@@ -3,7 +3,7 @@
import { isCloudHosted } from '$lib/cloud'
import Tooltip from './Tooltip.svelte'
let uptodate: string | undefined = undefined
let uptodate: string | undefined = $state(undefined)
async function loadVersion() {
try {
+6 -2
View File
@@ -1,8 +1,12 @@
<script lang="ts">
import { urlize } from '$lib/utils'
export let text: string
$: parsed = text ? urlize(text, 'html') : ''
interface Props {
text: string;
}
let { text }: Props = $props();
let parsed = $derived(text ? urlize(text, 'html') : '')
</script>
{@html parsed}
+1 -1
View File
@@ -1,7 +1,7 @@
<script lang="ts">
import { SettingsService } from '$lib/gen'
let version = ''
let version = $state('')
loadVersion()
@@ -2,7 +2,7 @@
import { WorkerService } from '$lib/gen'
import { Alert } from './common'
let ips: string[] | undefined = undefined
let ips: string[] | undefined = $state(undefined)
WorkerService.listWorkers({ pingSince: 300 }).then((workers) => {
ips = [
@@ -1,3 +1,5 @@
<!-- @migration-task Error while migrating Svelte code: Can only bind to an Identifier or MemberExpression or a `{get, set}` pair
https://svelte.dev/e/bind_invalid_expression -->
<script lang="ts">
import { Copy, Plus, RefreshCcwIcon, Settings, Trash, X } from 'lucide-svelte'
import { Alert, Badge, Button, Drawer } from './common'
@@ -7,23 +7,15 @@
import TimelineBar from './TimelineBar.svelte'
import type { WorkflowStatus } from '$lib/gen'
export let flow_status: Record<string, WorkflowStatus>
export let flowDone = false
interface Props {
flow_status: Record<string, WorkflowStatus>;
flowDone?: boolean;
}
$: min = Object.values(flow_status).reduce(
(a, b) => Math.min(a, b.scheduled_for ? new Date(b.scheduled_for).getTime() : Infinity),
Infinity
)
$: max = flowDone
? Object.values(flow_status).reduce(
(a, b) =>
Math.max(a, b.started_at ? new Date(b.started_at).getTime() + (b.duration_ms ?? 0) : 0),
0
)
: undefined
$: total = flowDone && max ? max - min : now - min
let { flow_status, flowDone = false }: Props = $props();
let now = getDbClockNow().getTime()
let now = $state(getDbClockNow().getTime())
let interval = setInterval((x) => {
if (!max) {
@@ -37,6 +29,18 @@
onDestroy(() => {
interval && clearInterval(interval)
})
let min = $derived(Object.values(flow_status).reduce(
(a, b) => Math.min(a, b.scheduled_for ? new Date(b.scheduled_for).getTime() : Infinity),
Infinity
))
let max = $derived(flowDone
? Object.values(flow_status).reduce(
(a, b) =>
Math.max(a, b.started_at ? new Date(b.started_at).getTime() + (b.duration_ms ?? 0) : 0),
0
)
: undefined)
let total = $derived(flowDone && max ? max - min : now - min)
</script>
{#if flow_status}
@@ -1,14 +1,18 @@
<script lang="ts">
import { run } from 'svelte/legacy';
import IconedResourceType from './IconedResourceType.svelte'
import Toggle from './Toggle.svelte'
export let value: any
interface Props {
value: any;
}
$: enabled = value != undefined
let { value = $bindable() }: Props = $props();
let org = ''
$: changeOrg(org)
let org = $state('')
function changeOrg(org) {
if (value) {
@@ -28,10 +32,14 @@
}
}
}
let enabled = $derived(value != undefined)
run(() => {
changeOrg(org)
});
</script>
<div class="flex flex-col gap-1">
<!-- svelte-ignore a11y-label-has-associated-control -->
<!-- svelte-ignore a11y_label_has_associated_control -->
<label class="text-sm font-medium text-primary flex gap-4 items-center"
><div class="w-[120px]"><IconedResourceType name={'zitadel'} after={true} /></div><Toggle
checked={enabled}
@@ -24,7 +24,7 @@
</script>
<svelte:window
on:keydown={(e) => {
onkeydown={(e) => {
if ((e.ctrlKey || e.metaKey) && e.key === 'Enter') {
onConfirm()
}
@@ -14,11 +14,11 @@
import Tab from '$lib/components/common/tabs/Tab.svelte'
import HighlightTheme from '$lib/components/HighlightTheme.svelte'
let jsonViewerDrawer: Drawer
let jsonViewerDrawer: Drawer | undefined = $state()
let app: any | undefined = undefined
let app: any | undefined = $state(undefined)
let rawType: 'json' | 'yaml' = 'yaml'
let rawType: 'json' | 'yaml' = $state('yaml')
export function open(app_l: any) {
app = app_l
@@ -29,7 +29,7 @@
<HighlightTheme />
<Drawer bind:this={jsonViewerDrawer} size="800px">
<DrawerContent title="App Export" on:close={() => jsonViewerDrawer.toggleDrawer()}>
<DrawerContent title="App Export" on:close={() => jsonViewerDrawer?.toggleDrawer()}>
<div>
<Tabs bind:selected={rawType}>
<Tab value="yaml" label="YAML" />

Some files were not shown because too many files have changed in this diff Show More