From 4c387c7295d8ea78647a07c21a7d0b43d988d5d5 Mon Sep 17 00:00:00 2001 From: Thanatat Tamtan Date: Wed, 12 Feb 2025 20:35:45 +0700 Subject: [PATCH 1/4] update dep --- .tool-versions | 4 ++-- bun.lockb | Bin 197929 -> 204295 bytes package.json | 26 +++++++++++++------------- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/.tool-versions b/.tool-versions index 8505c76..f4132be 100644 --- a/.tool-versions +++ b/.tool-versions @@ -1,2 +1,2 @@ -bun 1.1.42 -nodejs 22.12.0 +bun 1.2.2 +nodejs 22.14.0 diff --git a/bun.lockb b/bun.lockb index e3297d312c2e06332bf303d21f1421549b63fdda..2484976848e083a6af3994674c6f867a81803a8b 100755 GIT binary patch delta 37654 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 A(*OVf delta 35087 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 diff --git a/package.json b/package.json index 01b944a..c02b0a8 100644 --- a/package.json +++ b/package.json @@ -12,27 +12,27 @@ "lint": "eslint ." }, "devDependencies": { - "@nomimono/nomimono-css": "^0.4.25", - "@sveltejs/adapter-cloudflare": "^4.9.0", - "@sveltejs/adapter-node": "^5.2.11", - "@sveltejs/kit": "=2.11.1", - "@typescript-eslint/eslint-plugin": "^8.18.0", - "@typescript-eslint/parser": "^8.18.0", + "@nomimono/nomimono-css": "^0.6.0", + "@sveltejs/adapter-cloudflare": "^5.0.2", + "@sveltejs/adapter-node": "^5.2.12", + "@sveltejs/kit": "=2.17.1", + "@typescript-eslint/eslint-plugin": "^8.24.0", + "@typescript-eslint/parser": "^8.24.0", "clipboard": "^2.0.11", "dayjs": "^1.11.13", - "eslint": "^9.17.0", + "eslint": "^9.20.1", "eslint-plugin-svelte": "^2.46.1", "global": "^4.4.0", "gravatar-url": "^4.0.1", - "highcharts": "^11.4.8", + "highcharts": "^12.1.2", "js-cookie": "^3.0.5", - "sass": "^1.83.0", - "svelte": "^4.2.19", - "svelte-check": "^4.1.1", + "sass": "^1.84.0", + "svelte": "^5.19.10", + "svelte-check": "^4.1.4", "svelte-eslint-parser": "^0.43.0", "svelte-preprocess": "^6.0.3", - "sweetalert2": "^11.14.5", - "typescript": "~5.7.2", + "sweetalert2": "^11.16.0", + "typescript": "~5.7.3", "valid-url": "^1.0.9" }, "type": "module" From 93721aeda9df4f8664d4a500ede47d075ccf0242 Mon Sep 17 00:00:00 2001 From: Thanatat Tamtan Date: Wed, 12 Feb 2025 21:29:12 +0700 Subject: [PATCH 2/4] migrate to svelte 5 --- src/lib/components/Chart.svelte | 41 +-- .../components/DeploymentStatusIcon.svelte | 49 ++-- src/lib/components/ErrorRow.svelte | 30 +- src/lib/components/LoadingRow.svelte | 8 +- src/lib/components/NoDataRow.svelte | 18 +- src/lib/components/Secret.svelte | 14 +- src/lib/components/StatusIcon.svelte | 12 +- src/routes/(auth)/(project)/+layout.svelte | 4 +- src/routes/(auth)/(project)/+page.svelte | 24 +- .../deployment/(detail)/+layout.svelte | 10 +- .../deployment/(detail)/detail/+page.svelte | 272 +++++++++--------- .../deployment/(detail)/events/+page.svelte | 6 +- .../deployment/(detail)/logs/+page.svelte | 6 +- .../deployment/(detail)/metrics/+page.svelte | 18 +- .../deployment/(detail)/revision/+page.svelte | 4 +- .../(auth)/(project)/deployment/+page.svelte | 8 +- .../deployment/_components/Header.svelte | 24 +- .../(project)/deployment/deploy/+page.svelte | 76 ++--- .../(project)/disk/(detail)/+layout.svelte | 8 +- .../disk/(detail)/detail/+page.svelte | 12 +- .../disk/(detail)/metrics/+page.svelte | 12 +- src/routes/(auth)/(project)/disk/+page.svelte | 8 +- .../(auth)/(project)/disk/create/+page.svelte | 20 +- .../(auth)/(project)/domain/+page.svelte | 10 +- .../(project)/domain/create/+page.svelte | 18 +- .../(project)/domain/detail/+page.svelte | 18 +- .../(auth)/(project)/dropbox/+page.svelte | 17 +- .../(auth)/(project)/email/+page.svelte | 6 +- .../(auth)/(project)/pull-secret/+page.svelte | 8 +- .../(project)/pull-secret/create/+page.svelte | 20 +- .../(project)/pull-secret/detail/+page.svelte | 12 +- .../(auth)/(project)/registry/+page.svelte | 8 +- .../(project)/registry/detail/+page.svelte | 10 +- src/routes/(auth)/(project)/role/+page.svelte | 8 +- .../(auth)/(project)/role/bind/+page.svelte | 23 +- .../(auth)/(project)/role/create/+page.svelte | 26 +- .../(auth)/(project)/role/users/+page.svelte | 10 +- .../(auth)/(project)/route/+page.svelte | 10 +- .../(project)/route/create/+page.svelte | 36 ++- .../(project)/service-account/+page.svelte | 8 +- .../service-account/create/+page.svelte | 21 +- .../service-account/detail/+page.svelte | 16 +- .../(project)/workload-identity/+page.svelte | 8 +- .../workload-identity/create/+page.svelte | 20 +- .../workload-identity/detail/+page.svelte | 10 +- src/routes/(auth)/+layout.svelte | 24 +- src/routes/(auth)/ModalSelectProject.svelte | 19 +- src/routes/(auth)/Navbar.svelte | 35 ++- src/routes/(auth)/Sidebar.svelte | 23 +- src/routes/(auth)/billing/+page.svelte | 6 +- src/routes/(auth)/billing/create/+page.svelte | 18 +- src/routes/(auth)/billing/detail/+page.svelte | 6 +- src/routes/(auth)/billing/report/+page.svelte | 15 +- src/routes/(auth)/project/+page.svelte | 6 +- src/routes/(auth)/project/create/+page.svelte | 18 +- src/routes/+layout.svelte | 9 +- 56 files changed, 664 insertions(+), 522 deletions(-) diff --git a/src/lib/components/Chart.svelte b/src/lib/components/Chart.svelte index dfe82ca..b741c44 100644 --- a/src/lib/components/Chart.svelte +++ b/src/lib/components/Chart.svelte @@ -4,23 +4,27 @@ import * as hc from '$lib/hc' import { browser } from '$app/environment' - /** @type {string} */ - export let title - - /** @type {string} */ - export let unit - /** @typedef {Object} Series */ /** @property {string} prefix */ /** @property {Array} lines */ /** @property {string?} dashStyle */ /** @property {string?} color */ - /** @type {Series[]} */ - export let series - - /** @type {'line' | 'spline'} */ - export let type = 'line' + /** + * @typedef {Object} Props + * @property {string} title + * @property {string} unit + * @property {Series[]} series + * @property {'line' | 'spline'} [type] + */ + + /** @type {Props} */ + let { + title, + unit, + series, + type = 'line' + } = $props() /** @type {HTMLDivElement} */ let el @@ -53,13 +57,6 @@ } }) - $: { - if (series?.length === 0) clear() - series?.forEach((s) => { - update(s.prefix, s.lines, s.dashStyle, s.color) - }) - chart?.redraw() - } function update (name, lines, dashStyle, color) { if (!browser || !chart) return @@ -108,6 +105,14 @@ } return v } + + $effect(() => { + if (series?.length === 0) clear() + series?.forEach((s) => { + update(s.prefix, s.lines, s.dashStyle, s.color) + }) + chart?.redraw() + })
diff --git a/src/lib/components/DeploymentStatusIcon.svelte b/src/lib/components/DeploymentStatusIcon.svelte index feed8b6..311b79a 100644 --- a/src/lib/components/DeploymentStatusIcon.svelte +++ b/src/lib/components/DeploymentStatusIcon.svelte @@ -2,17 +2,21 @@ import { browser } from '$app/environment' import { onDestroy } from 'svelte' - /** @type {Api.DeploymentAction} */ - export let action - - /** @type {Api.DeploymentStatus} */ - export let status - - /** @type {string} */ - export let url + /** + * @typedef {Object} Props + * @property {Api.DeploymentAction} action + * @property {Api.DeploymentStatus} status + * @property {string} url + * @property {Api.DeploymentType} type + */ - /** @type {Api.DeploymentType} */ - export let type + /** @type {Props} */ + let { + action, + status, + url, + type + } = $props() const statusIconClass = { pending: 'fa-solid fa-spinner-third fa-spin', @@ -22,21 +26,10 @@ } /** @type {Api.PodStatus | null} */ - let podStatus + let podStatus = $state(null) /** @type {string} */ - let iconClass - - $: { - status - url - action - browser && fetchPodStatus() - } - $: { - podStatus - iconClass = getIconClass() - } + let iconClass = $state('') /** * @returns {string} @@ -93,6 +86,16 @@ destroyed = true fetchPodStatusTimeout && clearTimeout(fetchPodStatusTimeout) }) + $effect(() => { + status + url + action + browser && fetchPodStatus() + }) + $effect(() => { + podStatus + iconClass = getIconClass() + }) diff --git a/src/lib/components/ErrorRow.svelte b/src/lib/components/ErrorRow.svelte index 321292d..0954263 100644 --- a/src/lib/components/ErrorRow.svelte +++ b/src/lib/components/ErrorRow.svelte @@ -1,16 +1,24 @@ {#if error} - - {#if error.forbidden} - You don't have permission to view data - {:else if error.message} - {error.message} - {:else} - {error} - {/if} - + + + {#if error.forbidden} + You don't have permission to view data + {:else if error.message} + {error.message} + {:else} + {error} + {/if} + + {/if} diff --git a/src/lib/components/LoadingRow.svelte b/src/lib/components/LoadingRow.svelte index c1d9e5a..abf8eb7 100644 --- a/src/lib/components/LoadingRow.svelte +++ b/src/lib/components/LoadingRow.svelte @@ -1,5 +1,11 @@ diff --git a/src/lib/components/NoDataRow.svelte b/src/lib/components/NoDataRow.svelte index c6b15d5..29d0d76 100644 --- a/src/lib/components/NoDataRow.svelte +++ b/src/lib/components/NoDataRow.svelte @@ -1,10 +1,18 @@ {#if !list?.length} - - No data - + + + No data + + {/if} diff --git a/src/lib/components/Secret.svelte b/src/lib/components/Secret.svelte index 2d1c188..edbbcf5 100644 --- a/src/lib/components/Secret.svelte +++ b/src/lib/components/Secret.svelte @@ -1,8 +1,14 @@ -
+
{#if isHidden} {:else} diff --git a/src/lib/components/StatusIcon.svelte b/src/lib/components/StatusIcon.svelte index d5b1c1f..a8804c9 100644 --- a/src/lib/components/StatusIcon.svelte +++ b/src/lib/components/StatusIcon.svelte @@ -1,6 +1,12 @@ diff --git a/src/routes/(auth)/(project)/+layout.svelte b/src/routes/(auth)/(project)/+layout.svelte index be519e8..925525b 100644 --- a/src/routes/(auth)/(project)/+layout.svelte +++ b/src/routes/(auth)/(project)/+layout.svelte @@ -2,7 +2,7 @@ import Cookie from 'js-cookie' import { onMount } from 'svelte' - export let data + let { data, children } = $props() const project = data.project @@ -11,4 +11,4 @@ }) - +{@render children?.()} diff --git a/src/routes/(auth)/(project)/+page.svelte b/src/routes/(auth)/(project)/+page.svelte index 3b37f81..d748d94 100644 --- a/src/routes/(auth)/(project)/+page.svelte +++ b/src/routes/(auth)/(project)/+page.svelte @@ -2,22 +2,11 @@ import { onMount } from 'svelte' import api from '$lib/api' - export let data + let { data } = $props() - $: projectInfo = data.projectInfo - $: usage = data.usage - $: price = data.price const unitGiB = 1024 * 1024 * 1024 - $: billing = { - price: formatNumber(price.price), - cpu: formatNumber(usage.cpuUsage), - memory: formatNumber(usage.memory / unitGiB), - egress: formatNumber(usage.egress / unitGiB), - disk: formatNumber(usage.disk / unitGiB), - replica: formatNumber(usage.replica) - } onMount(() => { const interval = setInterval(() => { @@ -32,6 +21,17 @@ if (Number.isNaN(v)) return '?' return v?.toLocaleString(undefined, { maximumFractionDigits: 2 }) ?? '?' } + let projectInfo = $derived(data.projectInfo) + let usage = $derived(data.usage) + let price = $derived(data.price) + let billing = $derived({ + price: formatNumber(price.price), + cpu: formatNumber(usage.cpuUsage), + memory: formatNumber(usage.memory / unitGiB), + egress: formatNumber(usage.egress / unitGiB), + disk: formatNumber(usage.disk / unitGiB), + replica: formatNumber(usage.replica) + })
Dashboard
diff --git a/src/routes/(auth)/(project)/deployment/(detail)/+layout.svelte b/src/routes/(auth)/(project)/deployment/(detail)/+layout.svelte index c3643b9..3ca2f87 100644 --- a/src/routes/(auth)/(project)/deployment/(detail)/+layout.svelte +++ b/src/routes/(auth)/(project)/deployment/(detail)/+layout.svelte @@ -3,10 +3,10 @@ import { onMount } from 'svelte' import api from '$lib/api' - export let data + let { data, children } = $props() - $: project = data.project - $: deployment = data.deployment + let project = $derived(data.project) + let deployment = $derived(data.deployment) let lastReload = Date.now() @@ -31,7 +31,7 @@
-
api.invalidate('deployment.get')} /> +
api.invalidate('deployment.get')} /> - + {@render children?.()}
diff --git a/src/routes/(auth)/(project)/deployment/(detail)/detail/+page.svelte b/src/routes/(auth)/(project)/deployment/(detail)/detail/+page.svelte index 09d5ea5..a958759 100644 --- a/src/routes/(auth)/(project)/deployment/(detail)/detail/+page.svelte +++ b/src/routes/(auth)/(project)/deployment/(detail)/detail/+page.svelte @@ -8,13 +8,13 @@ import Secret from '$lib/components/Secret.svelte' import NoDataRow from '$lib/components/NoDataRow.svelte' - export let data + let { data } = $props() - $: deployment = data.deployment - $: location = data.location + let deployment = $derived(data.deployment) + let location = $derived(data.location) - $: hasExternalTCPAddress = ['TCPService'].includes(deployment.type) - $: hasInternalTCPAddress = ['WebService', 'TCPService', 'InternalTCPService'].includes(deployment.type) + let hasExternalTCPAddress = $derived(['TCPService'].includes(deployment.type)) + let hasInternalTCPAddress = $derived(['WebService', 'TCPService', 'InternalTCPService'].includes(deployment.type)) onMount(() => { const copyList = new ClipboardJS('.copy') @@ -46,166 +46,168 @@
Deployment details
- {#if deployment.type === 'WebService'} - {#if !deployment.internal} + + {#if deployment.type === 'WebService'} + {#if !deployment.internal} + + + + + {/if} + + + + + {/if} + {#if hasExternalTCPAddress} + + + + + {/if} + {#if hasInternalTCPAddress} - + {/if} - + - {/if} - {#if hasExternalTCPAddress} - - - - - {/if} - {#if hasInternalTCPAddress} - + - {/if} - - - - - - - - - - - - - {#if deployment.type === 'WebService'} - - - - - {:else if deployment.type === 'TCPService'} - - + + - {/if} - {#if location.features.disk} + {#if deployment.type === 'WebService'} + + + + + {:else if deployment.type === 'TCPService'} + + + + + {/if} + {#if location.features.disk} + + + + + {/if} + {#if deployment.minReplicas > 0} - + - {/if} - {#if deployment.minReplicas > 0} - - - - - {/if} - {#if deployment.type === 'CronJob'} + {/if} + {#if deployment.type === 'CronJob'} + + + + + {/if} - - + + - {/if} - - - - - - - - - - - - - {#if location.features.workloadIdentity} - - + + - {/if} - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + {#if location.features.workloadIdentity} + + + + + {/if} + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
URL + + {`https://${deployment.url}`} + + + + +
Internal URL + http://{deployment.internalUrl} + + + +
Address{deployment.address}:{deployment.nodePort}
URLInternal Address - - {`https://${deployment.url}`} - - + {deployment.internalAddress}:{deployment.port} +
Internal URLType - http://{deployment.internalUrl} - - - + {format.deploymentType(deployment.type)} + {#if deployment.internal} + (Internal) + {/if}
Address{deployment.address}:{deployment.nodePort}
Internal AddressLocation - {deployment.internalAddress}:{deployment.port} - + {deployment.location} +
Type - {format.deploymentType(deployment.type)} - {#if deployment.internal} - (Internal) - {/if} -
Location - {deployment.location} - - - -
Image - {deployment.image} - - - -
Port{deployment.port}{deployment.protocol ? `:${deployment.protocol}` : ''}
Port{deployment.port}:{deployment.nodePort}Image + {deployment.image} + + + +
Port{deployment.port}{deployment.protocol ? `:${deployment.protocol}` : ''}
Port{deployment.port}:{deployment.nodePort}
Disk + {#if deployment.disk} + {deployment.disk.name} + (mount: {deployment.disk.mountPath || '-'}, sub: {deployment.disk.subPath || '-'}) + {:else} + - + {/if} +
DiskReplicas - {#if deployment.disk} - {deployment.disk.name} - (mount: {deployment.disk.mountPath || '-'}, sub: {deployment.disk.subPath || '-'}) + {#if deployment.minReplicas > 0} + {#if deployment.minReplicas === deployment.maxReplicas} + {deployment.minReplicas} + {:else} + {deployment.minReplicas} - {deployment.maxReplicas} + {/if} {:else} - {/if}
Replicas - {#if deployment.minReplicas > 0} - {#if deployment.minReplicas === deployment.maxReplicas} - {deployment.minReplicas} - {:else} - {deployment.minReplicas} - {deployment.maxReplicas} - {/if} - {:else} - - - {/if} -
Schedule{deployment.schedule}
Schedule{deployment.schedule}Command{deployment.command.join(' ') || '-'}
Command{deployment.command.join(' ') || '-'}
Args{deployment.args.join(' ') || '-'}
Pull Secret{deployment.pullSecret || '-'}
Workload Identity{deployment.workloadIdentity || '-'}Args{deployment.args.join(' ') || '-'}
CPU limited{format.cpuLimited(deployment.resources.limits.cpu)}
Memory allocated{format.memory(deployment.resources.requests.memory)}
Sidecars{deployment.sidecars?.length || 0}
Deployed At{format.datetime(deployment.createdAt)}
Deployed By{deployment.createdBy}
Allocated Price{deployment.allocatedPrice.toLocaleString(undefined, { maximumFractionDigits: 2 })} THB/month/replica
Pull Secret{deployment.pullSecret || '-'}
Workload Identity{deployment.workloadIdentity || '-'}
CPU limited{format.cpuLimited(deployment.resources.limits.cpu)}
Memory allocated{format.memory(deployment.resources.requests.memory)}
Sidecars{deployment.sidecars?.length || 0}
Deployed At{format.datetime(deployment.createdAt)}
Deployed By{deployment.createdBy}
Allocated Price{deployment.allocatedPrice.toLocaleString(undefined, { maximumFractionDigits: 2 })} THB/month/replica
diff --git a/src/routes/(auth)/(project)/deployment/(detail)/events/+page.svelte b/src/routes/(auth)/(project)/deployment/(detail)/events/+page.svelte index e326908..c8dd8bf 100644 --- a/src/routes/(auth)/(project)/deployment/(detail)/events/+page.svelte +++ b/src/routes/(auth)/(project)/deployment/(detail)/events/+page.svelte @@ -3,11 +3,11 @@ import * as format from '$lib/format' import NoDataRow from '$lib/components/NoDataRow.svelte' - export let data + let { data } = $props() - $: deployment = data.deployment + let deployment = $derived(data.deployment) - let events = [] + let events = $state([]) onMount(() => { reloadEvents() diff --git a/src/routes/(auth)/(project)/deployment/(detail)/logs/+page.svelte b/src/routes/(auth)/(project)/deployment/(detail)/logs/+page.svelte index f5065fe..f6e6f26 100644 --- a/src/routes/(auth)/(project)/deployment/(detail)/logs/+page.svelte +++ b/src/routes/(auth)/(project)/deployment/(detail)/logs/+page.svelte @@ -1,12 +1,12 @@
Deployments
diff --git a/src/routes/(auth)/(project)/deployment/_components/Header.svelte b/src/routes/(auth)/(project)/deployment/_components/Header.svelte index 38f9fae..0595ef8 100644 --- a/src/routes/(auth)/(project)/deployment/_components/Header.svelte +++ b/src/routes/(auth)/(project)/deployment/_components/Header.svelte @@ -1,18 +1,22 @@
Disks
diff --git a/src/routes/(auth)/(project)/disk/create/+page.svelte b/src/routes/(auth)/(project)/disk/create/+page.svelte index 6dede68..5352a2d 100644 --- a/src/routes/(auth)/(project)/disk/create/+page.svelte +++ b/src/routes/(auth)/(project)/disk/create/+page.svelte @@ -3,7 +3,7 @@ import * as modal from '$lib/modal' import api from '$lib/api' - export let data + let { data } = $props() const { locations, location, @@ -11,16 +11,22 @@ disk } = data - $: project = data.project + let project = $derived(data.project) - const form = { + const form = $state({ location: location || '', name: name || '', size: disk?.size || 1 - } + }) + + let saving = $state(false) + + /** + * @param {Event} e + */ + async function save (e) { + e.preventDefault() - let saving = false - async function save () { if (saving) { return } @@ -78,7 +84,7 @@
-
+
diff --git a/src/routes/(auth)/(project)/domain/+page.svelte b/src/routes/(auth)/(project)/domain/+page.svelte index 5a05070..efe3787 100644 --- a/src/routes/(auth)/(project)/domain/+page.svelte +++ b/src/routes/(auth)/(project)/domain/+page.svelte @@ -5,11 +5,11 @@ import api from '$lib/api' import ErrorRow from '$lib/components/ErrorRow.svelte' - export let data + let { data } = $props() - $: project = data.project - $: domains = data.domains - $: error = data.error + let project = $derived(data.project) + let domains = $derived(data.domains) + let error = $derived(data.error) function deleteDomain (domain) { modal.confirm({ @@ -79,7 +79,7 @@ - diff --git a/src/routes/(auth)/(project)/domain/create/+page.svelte b/src/routes/(auth)/(project)/domain/create/+page.svelte index a2f1125..d38757f 100644 --- a/src/routes/(auth)/(project)/domain/create/+page.svelte +++ b/src/routes/(auth)/(project)/domain/create/+page.svelte @@ -3,22 +3,28 @@ import * as modal from '$lib/modal' import api from '$lib/api' - export let data + let { data } = $props() const { project, locations, projectInfo } = data - const form = { + const form = $state({ domain: '', location: '', cdn: false, wildcard: false - } + }) + + let saving = $state(false) + + /** + * @param {Event} e + */ + async function save (e) { + e.preventDefault() - let saving = false - async function save () { if (saving) { return } @@ -61,7 +67,7 @@

- +
diff --git a/src/routes/(auth)/(project)/domain/detail/+page.svelte b/src/routes/(auth)/(project)/domain/detail/+page.svelte index ac9c9eb..f989eca 100644 --- a/src/routes/(auth)/(project)/domain/detail/+page.svelte +++ b/src/routes/(auth)/(project)/domain/detail/+page.svelte @@ -7,10 +7,10 @@ import api from '$lib/api' import Swal from 'sweetalert2' - export let data + let { data } = $props() - $: project = data.project - $: domain = data.domain + let project = $derived(data.project) + let domain = $derived(data.domain) onMount(() => { const copyList = new ClipboardJS('.copy') @@ -42,7 +42,7 @@ setTimeout(f, 3000) } - let purging = false + let purging = $state(false) async function purgeCache () { if (domain.wildcard) { return // not supported @@ -403,7 +403,7 @@
Purge everything

Remove all cached resources

-
@@ -413,7 +413,7 @@
Purge prefix

Remove cached resources at prefix path

-
@@ -423,7 +423,7 @@
Purge file

Remove cached resources at exact path

- @@ -435,13 +435,13 @@ {#if !domain.cdn}
- +
{/if}
-
diff --git a/src/routes/(auth)/(project)/dropbox/+page.svelte b/src/routes/(auth)/(project)/dropbox/+page.svelte index e51b8ba..f7bfa35 100644 --- a/src/routes/(auth)/(project)/dropbox/+page.svelte +++ b/src/routes/(auth)/(project)/dropbox/+page.svelte @@ -1,15 +1,20 @@
Emails
diff --git a/src/routes/(auth)/(project)/pull-secret/+page.svelte b/src/routes/(auth)/(project)/pull-secret/+page.svelte index b6a58dc..27ded6c 100644 --- a/src/routes/(auth)/(project)/pull-secret/+page.svelte +++ b/src/routes/(auth)/(project)/pull-secret/+page.svelte @@ -4,11 +4,11 @@ import * as format from '$lib/format' import ErrorRow from '$lib/components/ErrorRow.svelte' - export let data + let { data } = $props() - $: project = data.project - $: pullSecrets = data.pullSecrets - $: error = data.error + let project = $derived(data.project) + let pullSecrets = $derived(data.pullSecrets) + let error = $derived(data.error)
Pull Secrets
diff --git a/src/routes/(auth)/(project)/pull-secret/create/+page.svelte b/src/routes/(auth)/(project)/pull-secret/create/+page.svelte index 8326805..edb03ed 100644 --- a/src/routes/(auth)/(project)/pull-secret/create/+page.svelte +++ b/src/routes/(auth)/(project)/pull-secret/create/+page.svelte @@ -4,21 +4,27 @@ import * as modal from '$lib/modal' import api from '$lib/api' - export let data + let { data } = $props() - $: project = data.project + let project = $derived(data.project) const locations = data.locations - const form = { + const form = $state({ name: '', location: '', server: 'https://index.docker.io/v2/', username: '', password: '' - } + }) + + let saving = $state(false) + + /** + * @param {Event} e + */ + async function save (e) { + e.preventDefault() - let saving = false - async function save () { if (saving) { return } @@ -71,7 +77,7 @@
- +
diff --git a/src/routes/(auth)/(project)/pull-secret/detail/+page.svelte b/src/routes/(auth)/(project)/pull-secret/detail/+page.svelte index 60a6497..dba2c4b 100644 --- a/src/routes/(auth)/(project)/pull-secret/detail/+page.svelte +++ b/src/routes/(auth)/(project)/pull-secret/detail/+page.svelte @@ -5,12 +5,12 @@ import * as modal from '$lib/modal' import api from '$lib/api' - export let data + let { data } = $props() - $: project = data.project - $: location = data.location - $: name = data.name - $: pullSecret = data.pullSecret + let project = $derived(data.project) + let location = $derived(data.location) + let name = $derived(data.name) + let pullSecret = $derived(data.pullSecret) onMount(() => { const copyList = new ClipboardJS('.copy') @@ -99,7 +99,7 @@
- +
diff --git a/src/routes/(auth)/(project)/registry/+page.svelte b/src/routes/(auth)/(project)/registry/+page.svelte index 4f7e6fe..dd5b50b 100644 --- a/src/routes/(auth)/(project)/registry/+page.svelte +++ b/src/routes/(auth)/(project)/registry/+page.svelte @@ -2,11 +2,11 @@ import ErrorRow from '$lib/components/ErrorRow.svelte' import NoDataRow from '$lib/components/NoDataRow.svelte' - export let data + let { data } = $props() - $: project = data.project - $: repositories = data.repositories - $: error = data.error + let project = $derived(data.project) + let repositories = $derived(data.repositories) + let error = $derived(data.error)
Registry (Alpha)
diff --git a/src/routes/(auth)/(project)/registry/detail/+page.svelte b/src/routes/(auth)/(project)/registry/detail/+page.svelte index 33d53a6..55e59f3 100644 --- a/src/routes/(auth)/(project)/registry/detail/+page.svelte +++ b/src/routes/(auth)/(project)/registry/detail/+page.svelte @@ -5,12 +5,12 @@ import ErrorRow from '$lib/components/ErrorRow.svelte' import NoDataRow from '$lib/components/NoDataRow.svelte' - export let data + let { data } = $props() - $: project = data.project - $: repository = data.repository - $: tags = data.tags - $: error = data.error + let project = $derived(data.project) + let repository = $derived(data.repository) + let tags = $derived(data.tags) + let error = $derived(data.error) onMount(() => { const copyList = new ClipboardJS('.copy') diff --git a/src/routes/(auth)/(project)/role/+page.svelte b/src/routes/(auth)/(project)/role/+page.svelte index 838568a..525b58c 100644 --- a/src/routes/(auth)/(project)/role/+page.svelte +++ b/src/routes/(auth)/(project)/role/+page.svelte @@ -3,11 +3,11 @@ import * as format from '$lib/format' import ErrorRow from '$lib/components/ErrorRow.svelte' - export let data + let { data } = $props() - $: project = data.project - $: roles = data.roles - $: error = data.error + let project = $derived(data.project) + let roles = $derived(data.roles) + let error = $derived(data.error) /** * @param {string} sid diff --git a/src/routes/(auth)/(project)/role/bind/+page.svelte b/src/routes/(auth)/(project)/role/bind/+page.svelte index 7a1a943..d73e1db 100644 --- a/src/routes/(auth)/(project)/role/bind/+page.svelte +++ b/src/routes/(auth)/(project)/role/bind/+page.svelte @@ -4,19 +4,19 @@ import api from '$lib/api' import NoDataRow from '$lib/components/NoDataRow.svelte' - export let data + let { data } = $props() const { roles, email, selected } = data - $: project = data.project + let project = $derived(data.project) - const form = { + const form = $state({ email, roles: selected - } + }) function addRole (role) { if (!role || form.roles.includes(role)) { @@ -35,9 +35,14 @@ e.target.value = '' } - let saving = false + let saving = $state(false) + + /** + * @param {Event} e + */ + async function save (e) { + e.preventDefault() - async function save () { if (saving) { return } @@ -79,7 +84,7 @@
- +
@@ -87,7 +92,7 @@
- {#each roles as it} {#if !form.roles.includes(it.role)} @@ -112,7 +117,7 @@ {it}
removeRole(it)} on:keypress={() => removeRole(it)}> + onclick={() => removeRole(it)} onkeypress={() => removeRole(it)}>
diff --git a/src/routes/(auth)/(project)/role/create/+page.svelte b/src/routes/(auth)/(project)/role/create/+page.svelte index 43b4abe..c1e9e4b 100644 --- a/src/routes/(auth)/(project)/role/create/+page.svelte +++ b/src/routes/(auth)/(project)/role/create/+page.svelte @@ -4,19 +4,19 @@ import * as modal from '$lib/modal' import api from '$lib/api' - export let data + let { data } = $props() const { role, permissions } = data - $: project = data.project + let project = $derived(data.project) - const form = { + const form = $state({ role: role?.role ?? '', name: role?.name ?? '', permissions: role?.permissions ?? [] - } + }) function deleteItem () { if (!role) return @@ -57,8 +57,14 @@ form.permissions = form.permissions.filter((x) => x !== permission) } - let saving = false - async function save () { + let saving = $state(false) + + /** + * @param {Event} e + */ + async function save (e) { + e.preventDefault() + if (saving) { return } @@ -113,7 +119,7 @@
- +
@@ -137,7 +143,7 @@
- {#each permissions.filter((x) => !form.permissions.includes(x)) as it} @@ -160,7 +166,7 @@ {it}
removePermission(it)} on:keypress={() => removePermission(it)}> + onclick={() => removePermission(it)} onkeypress={() => removePermission(it)}>
@@ -180,7 +186,7 @@ {#if role}Update{:else}Create{/if} {#if role} - + {/if}
diff --git a/src/routes/(auth)/(project)/role/users/+page.svelte b/src/routes/(auth)/(project)/role/users/+page.svelte index 56c897f..6d1d2a1 100644 --- a/src/routes/(auth)/(project)/role/users/+page.svelte +++ b/src/routes/(auth)/(project)/role/users/+page.svelte @@ -4,11 +4,11 @@ import api from '$lib/api' import ErrorRow from '$lib/components/ErrorRow.svelte' - export let data + let { data } = $props() - $: project = data.project - $: users = data.users - $: error = data.error + let project = $derived(data.project) + let users = $derived(data.users) + let error = $derived(data.error) /** * @param {string} email @@ -68,7 +68,7 @@
- diff --git a/src/routes/(auth)/(project)/route/+page.svelte b/src/routes/(auth)/(project)/route/+page.svelte index f082005..4569b22 100644 --- a/src/routes/(auth)/(project)/route/+page.svelte +++ b/src/routes/(auth)/(project)/route/+page.svelte @@ -4,11 +4,11 @@ import api from '$lib/api' import ErrorRow from '$lib/components/ErrorRow.svelte' - export let data + let { data } = $props() - $: project = data.project - $: routes = data.routes - $: error = data.error + let project = $derived(data.project) + let routes = $derived(data.routes) + let error = $derived(data.error) /** * @param {Api.Route} route @@ -76,7 +76,7 @@ - diff --git a/src/routes/(auth)/(project)/route/create/+page.svelte b/src/routes/(auth)/(project)/route/create/+page.svelte index 4d5cd7c..82035ad 100644 --- a/src/routes/(auth)/(project)/route/create/+page.svelte +++ b/src/routes/(auth)/(project)/route/create/+page.svelte @@ -3,12 +3,12 @@ import * as modal from '$lib/modal' import api from '$lib/api' - export let data + let { data } = $props() - $: project = data.project - $: locations = data.locations + let project = $derived(data.project) + let locations = $derived(data.locations) - const form = { + const form = $state({ domain: '', subdomain: '', path: '', @@ -23,19 +23,19 @@ } // TODO: add forwardAuth } - } + }) - $: targetPlaceholder = { + let targetPlaceholder = $derived({ 'redirect://': 'https://example.com', 'ipfs://': 'QmUVTKsrYJpaxUT7dr9FpKq6AoKHhEM7eG1ZHGL56haKLG', 'ipns://': 'k51qzi5uqu5dkkciu33khkzbcmxtyhn376i1e83tya8kuy7z9euedzyr5nhoew' - }[form.targetPrefix] || '' + }[form.targetPrefix] || '') /** @type {Api.Domain[]} */ - let domains = [] - let deployments = [] + let domains = $state([]) + let deployments = $state([]) - $: selectedDomain = domains.find((x) => x.domain === form.domain) + let selectedDomain = $derived(domains.find((x) => x.domain === form.domain)) async function fetchDomains () { domains = [] @@ -73,8 +73,14 @@ fetchDeployments() } - let saving = false - async function save () { + let saving = $state(false) + + /** + * @param {Event} e + */ + async function save (e) { + e.preventDefault() + if (saving) { return } @@ -132,11 +138,11 @@

-
+
- {#each locations as it} @@ -178,7 +184,7 @@
- form.targetValue = ''} required> diff --git a/src/routes/(auth)/(project)/service-account/+page.svelte b/src/routes/(auth)/(project)/service-account/+page.svelte index 575f2ce..22728cc 100644 --- a/src/routes/(auth)/(project)/service-account/+page.svelte +++ b/src/routes/(auth)/(project)/service-account/+page.svelte @@ -3,11 +3,11 @@ import * as format from '$lib/format' import ErrorRow from '$lib/components/ErrorRow.svelte' - export let data + let { data } = $props() - $: project = data.project - $: serviceAccounts = data.serviceAccounts - $: error = data.error + let project = $derived(data.project) + let serviceAccounts = $derived(data.serviceAccounts) + let error = $derived(data.error)
Service Accounts
diff --git a/src/routes/(auth)/(project)/service-account/create/+page.svelte b/src/routes/(auth)/(project)/service-account/create/+page.svelte index a037292..6c010d7 100644 --- a/src/routes/(auth)/(project)/service-account/create/+page.svelte +++ b/src/routes/(auth)/(project)/service-account/create/+page.svelte @@ -3,20 +3,25 @@ import * as modal from '$lib/modal' import api from '$lib/api' - export let data + let { data } = $props() const { id, serviceAccount } = data - $: project = data.project + let project = $derived(data.project) - let sid = serviceAccount?.sid - let name = serviceAccount?.name - let desc = serviceAccount?.description - let saving = false + let sid = $state(serviceAccount?.sid) + let name = $state(serviceAccount?.name) + let desc = $state(serviceAccount?.description) + let saving = $state(false) + + /** + * @param {Event} e + */ + async function save (e) { + e.preventDefault() - async function save () { if (saving) { return } @@ -77,7 +82,7 @@
- + {#if id}
diff --git a/src/routes/(auth)/(project)/service-account/detail/+page.svelte b/src/routes/(auth)/(project)/service-account/detail/+page.svelte index abb05f1..991bc0f 100644 --- a/src/routes/(auth)/(project)/service-account/detail/+page.svelte +++ b/src/routes/(auth)/(project)/service-account/detail/+page.svelte @@ -4,11 +4,11 @@ import * as modal from '$lib/modal' import api from '$lib/api' - export let data + let { data } = $props() - $: project = data.project - $: id = data.id - $: serviceAccount = data.serviceAccount + let project = $derived(data.project) + let id = $derived(data.id) + let serviceAccount = $derived(data.serviceAccount) function deleteItem () { modal.confirm({ @@ -25,7 +25,7 @@ }) } - let loadingCreateKey = false + let loadingCreateKey = $state(false) async function createKey () { if (loadingCreateKey) { @@ -122,14 +122,14 @@ {#each (serviceAccount.keys ?? []) as key}
-
{/each}
- @@ -139,7 +139,7 @@
-
diff --git a/src/routes/(auth)/(project)/workload-identity/+page.svelte b/src/routes/(auth)/(project)/workload-identity/+page.svelte index a74dd6e..fb828ae 100644 --- a/src/routes/(auth)/(project)/workload-identity/+page.svelte +++ b/src/routes/(auth)/(project)/workload-identity/+page.svelte @@ -4,11 +4,11 @@ import * as format from '$lib/format' import ErrorRow from '$lib/components/ErrorRow.svelte' - export let data + let { data } = $props() - $: project = data.project - $: workloadIdentities = data.workloadIdentities - $: error = data.error + let project = $derived(data.project) + let workloadIdentities = $derived(data.workloadIdentities) + let error = $derived(data.error)
Workload Identities
diff --git a/src/routes/(auth)/(project)/workload-identity/create/+page.svelte b/src/routes/(auth)/(project)/workload-identity/create/+page.svelte index a518109..6e12f3c 100644 --- a/src/routes/(auth)/(project)/workload-identity/create/+page.svelte +++ b/src/routes/(auth)/(project)/workload-identity/create/+page.svelte @@ -3,20 +3,26 @@ import * as modal from '$lib/modal' import api from '$lib/api' - export let data + let { data } = $props() const locations = data.locations - $: project = data.project + let project = $derived(data.project) - const form = { + const form = $state({ name: '', location: '', gsa: '' - } + }) + + let saving = $state(false) + + /** + * @param {Event} e + */ + async function save (e) { + e.preventDefault() - let saving = false - async function save () { if (saving) { return } @@ -57,7 +63,7 @@

- +
diff --git a/src/routes/(auth)/(project)/workload-identity/detail/+page.svelte b/src/routes/(auth)/(project)/workload-identity/detail/+page.svelte index 48c5d0a..9e37b94 100644 --- a/src/routes/(auth)/(project)/workload-identity/detail/+page.svelte +++ b/src/routes/(auth)/(project)/workload-identity/detail/+page.svelte @@ -6,11 +6,11 @@ import * as modal from '$lib/modal' import api from '$lib/api' - export let data + let { data } = $props() - $: workloadIdentity = data.workloadIdentity - $: project = data.project - $: projectInfo = data.projectInfo + let workloadIdentity = $derived(data.workloadIdentity) + let project = $derived(data.project) + let projectInfo = $derived(data.projectInfo) onMount(() => { const copyList = new ClipboardJS('.copy') @@ -95,7 +95,7 @@
- +
diff --git a/src/routes/(auth)/+layout.svelte b/src/routes/(auth)/+layout.svelte index 7ea2d93..bf212ab 100644 --- a/src/routes/(auth)/+layout.svelte +++ b/src/routes/(auth)/+layout.svelte @@ -7,13 +7,16 @@ import Sidebar from './Sidebar.svelte' import ModalSelectProject from './ModalSelectProject.svelte' - export let data + let { data, children } = $props() - $: profile = data.profile - $: projects = data.projects ?? [] + let profile = $derived(data.profile) + let projects = $derived(data.projects ?? []) - let showSidebar = false - $: $page, showSidebar = false + let showSidebar = $state(false) + $effect(() => { + $page + showSidebar = false + }) /** @type {ModalSelectProject} */ let projectModal @@ -29,23 +32,20 @@ } - showSidebar = !showSidebar} /> -
+ projectModal.open()} />
- + {@render children?.()}
diff --git a/src/routes/(auth)/ModalSelectProject.svelte b/src/routes/(auth)/ModalSelectProject.svelte index 2179f1a..e7741ee 100644 --- a/src/routes/(auth)/ModalSelectProject.svelte +++ b/src/routes/(auth)/ModalSelectProject.svelte @@ -2,11 +2,16 @@ import { page } from '$app/stores' import { goto } from '$app/navigation' - /** @type {Api.Project[]} */ - export let projects + /** + * @typedef {Object} Props + * @property {Api.Project[]} projects + */ + + /** @type {Props} */ + let { projects } = $props() - $: project = $page.url.searchParams.get('project') - let isActive = false + let project = $derived($page.url.searchParams.get('project')) + let isActive = $state(false) /** * @param {string} sid @@ -34,9 +39,9 @@ } -