diff --git a/interface/package-lock.json b/interface/package-lock.json index 863fcf5f5..0dcacdd78 100644 --- a/interface/package-lock.json +++ b/interface/package-lock.json @@ -14,7 +14,7 @@ "jwt-decode": "^4.0.0", "luxon": "^3.7.1", "msgpack-lite": "^0.1.26", - "svelte-dnd-list": "^0.1.8", + "svelte-dnd-action": "^0.9.65", "svelte-modals": "^2.0.1" }, "devDependencies": { @@ -4132,11 +4132,14 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/svelte-dnd-list": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/svelte-dnd-list/-/svelte-dnd-list-0.1.8.tgz", - "integrity": "sha512-81Nt/niux7kf59lql0lxTAH0z8xwAxHdHC9dZT7MbfE32T6hgeLsLZ7RIBNAihQ040Io1KghqqPXD+k2viiKeA==", - "license": "MIT" + "node_modules/svelte-dnd-action": { + "version": "0.9.65", + "resolved": "https://registry.npmjs.org/svelte-dnd-action/-/svelte-dnd-action-0.9.65.tgz", + "integrity": "sha512-GKFtrAtYAjcm27aMELoXOhkLtKA1AEoj2njjCReCer6jh1hnRtTHdEO4Kjfpayz+ZAvE0MMwIvLISW3tsiO9Qg==", + "license": "MIT", + "peerDependencies": { + "svelte": ">=3.23.0 || ^5.0.0-next.0" + } }, "node_modules/svelte-eslint-parser": { "version": "1.2.0", diff --git a/interface/package.json b/interface/package.json index badff56de..b83bd8a9b 100644 --- a/interface/package.json +++ b/interface/package.json @@ -3,7 +3,7 @@ "version": "0.2.0", "private": true, "scripts": { - "dev": "vite dev", + "dev": "vite dev --host", "build": "vite build", "preview": "vite preview", "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json", @@ -44,7 +44,7 @@ "jwt-decode": "^4.0.0", "luxon": "^3.7.1", "msgpack-lite": "^0.1.26", - "svelte-dnd-list": "^0.1.8", + "svelte-dnd-action": "^0.9.65", "svelte-modals": "^2.0.1" } } \ No newline at end of file diff --git a/interface/src/lib/components/Collapsible.svelte b/interface/src/lib/components/Collapsible.svelte index 419083cba..af93c0a60 100644 --- a/interface/src/lib/components/Collapsible.svelte +++ b/interface/src/lib/components/Collapsible.svelte @@ -2,24 +2,54 @@ import { slide } from 'svelte/transition'; import { cubicOut } from 'svelte/easing'; import Down from '~icons/tabler/chevron-down'; + import Alert from '~icons/tabler/alert-hexagon'; - let { icon, title, children, opened, closed, open = false, class: className = '' } = $props(); + interface Props { + open?: boolean; + opened?: any; + closed?: any; + collapsible?: boolean; + icon?: import('svelte').Snippet; + title?: import('svelte').Snippet; + children?: import('svelte').Snippet; + class?: string; + isDirty?: boolean; + } + + let { + open = $bindable(false), + opened, + closed, + icon, + title, + children, + class: className = '', + isDirty = false + }: Props = $props(); function openCollapsible() { open = !open; if (open) { - opened(); + if (opened) opened(); } else { - closed(); + if (closed) closed(); } }
+ {#if isDirty} +
+ {/if}
- + {@render icon?.()} {@render title?.()} + {#if isDirty} +
+ +
+ {/if}
{labels?.cancel.label} {labels?.confirm.label}
diff --git a/interface/src/lib/components/DraggableList.svelte b/interface/src/lib/components/DraggableList.svelte new file mode 100644 index 000000000..7b14e0cab --- /dev/null +++ b/interface/src/lib/components/DraggableList.svelte @@ -0,0 +1,83 @@ + + +
+ {#each itemsWithIds as item, index (item.id)} + {@render children({ item, index, originalItem: items[index] })} + {/each} +
+ + diff --git a/interface/src/lib/components/InfoDialog.svelte b/interface/src/lib/components/InfoDialog.svelte index d2dbf4181..d78eaa34b 100644 --- a/interface/src/lib/components/InfoDialog.svelte +++ b/interface/src/lib/components/InfoDialog.svelte @@ -35,7 +35,7 @@ >

{title}

-

{message}

+

{@html message}

{/if} diff --git a/interface/src/lib/components/toasts/Toast.svelte b/interface/src/lib/components/toasts/Toast.svelte index 162e97215..f3f470f14 100644 --- a/interface/src/lib/components/toasts/Toast.svelte +++ b/interface/src/lib/components/toasts/Toast.svelte @@ -32,7 +32,7 @@ out:fly={{ x: 100, duration: 400 }} > - {notification.message} + {@html notification.message}
{/each} diff --git a/interface/src/lib/stores/socket.ts b/interface/src/lib/stores/socket.ts index 4c21368f2..e47e1c7e4 100644 --- a/interface/src/lib/stores/socket.ts +++ b/interface/src/lib/stores/socket.ts @@ -19,7 +19,7 @@ function createWebSocket() { } function disconnect(reason: SocketEvent, event?: Event) { - console.log('disconnect', reason, event); + //console.log('disconnect', reason, event); ws.close(); set(false); clearTimeout(unresponsiveTimeoutId); @@ -29,7 +29,7 @@ function createWebSocket() { } function connect() { - console.log('connect'); + //console.log('connect'); ws = new WebSocket(socketUrl); ws.binaryType = 'arraybuffer'; ws.onopen = (ev) => { @@ -101,11 +101,14 @@ function createWebSocket() { on: (event: string, listener: (data: T) => void): (() => void) => { let eventListeners = listeners.get(event); if (!eventListeners) { - if (!socketEvents.includes(event as SocketEvent)) { - sendEvent('subscribe', event); - } eventListeners = new Set(); listeners.set(event, eventListeners); + + // Only send subscription if WebSocket is open and it's not a socket event + if (!socketEvents.includes(event as SocketEvent) && + ws && ws.readyState === WebSocket.OPEN) { + sendEvent('subscribe', event); + } } eventListeners.add(listener as (data: any) => void); diff --git a/interface/src/routes/+layout.svelte b/interface/src/routes/+layout.svelte index 7200910c2..2c321448b 100644 --- a/interface/src/routes/+layout.svelte +++ b/interface/src/routes/+layout.svelte @@ -39,8 +39,9 @@ const initSocket = () => { const ws_token = page.data.features.security ? '?access_token=' + $user.bearer_token : ''; + const ws_protocol = window.location.protocol === 'https:' ? 'wss' : 'ws'; socket.init( - `ws://${window.location.host}/ws/events${ws_token}`, + `${ws_protocol}://${window.location.host}/ws/events${ws_token}`, page.data.features.event_use_json ); addEventListeners(); @@ -167,6 +168,9 @@ class="fixed inset-0 z-40 max-h-full max-w-full bg-black/20 backdrop-blur-sm" transition:fade|global onclick={() => close()} + role="button" + tabindex="0" + aria-label="Close modal" > {/snippet} diff --git a/interface/src/routes/login.svelte b/interface/src/routes/login.svelte index 0ec0d300a..4a68615ee 100644 --- a/interface/src/routes/login.svelte +++ b/interface/src/routes/login.svelte @@ -58,7 +58,11 @@ in:fly={{ delay: 200, y: 100, duration: 500 }} out:fade={{ duration: 200 }} > -
Logo
+
+
+ Logo +
+

Login

@@ -82,6 +86,22 @@