Initial migration to Svelte5 via full syntax compatability

- updated all dependencies
- removed svelte-chartjs wrapper from dependencies
- sveltestrap causes compilation warnings (once)
- Header.svelte uses new Svelte5 syntax as example
- fixed most initial compilation warnings except circular dependencies with TBD cause
This commit is contained in:
Christoph Kluge 2025-02-03 17:31:01 +01:00
parent 1e63cdbcda
commit 5681062f01
27 changed files with 561 additions and 471 deletions

File diff suppressed because it is too large Load Diff

View File

@ -7,24 +7,23 @@
"dev": "rollup -c -w"
},
"devDependencies": {
"@rollup/plugin-commonjs": "^25.0.8",
"@rollup/plugin-node-resolve": "^15.3.0",
"@rollup/plugin-commonjs": "^28.0.2",
"@rollup/plugin-node-resolve": "^16.0.0",
"@rollup/plugin-terser": "^0.4.4",
"@timohausmann/quadtree-js": "^1.2.6",
"rollup": "^4.27.4",
"rollup": "^4.34.1",
"rollup-plugin-css-only": "^4.5.2",
"rollup-plugin-svelte": "^7.2.2",
"svelte": "^4.2.19"
"svelte": "^5.19.6"
},
"dependencies": {
"@rollup/plugin-replace": "^5.0.7",
"@sveltestrap/sveltestrap": "^6.2.7",
"@rollup/plugin-replace": "^6.0.2",
"@sveltestrap/sveltestrap": "^7.0.3",
"@urql/svelte": "^4.2.2",
"chart.js": "^4.4.6",
"date-fns": "^2.30.0",
"graphql": "^16.9.0",
"mathjs": "^12.4.3",
"svelte-chartjs": "^3.1.5",
"chart.js": "^4.4.7",
"date-fns": "^4.1.0",
"graphql": "^16.10.0",
"mathjs": "^14.2.0",
"uplot": "^1.6.31",
"wonka": "^6.3.4"
}

View File

@ -386,6 +386,7 @@
<Card body color="danger">{$topQuery.error.message}</Card>
{:else}
<Pie
type={groupSelection.key}
size={colWidth1}
sliceLabel={sortSelection.label}
quantities={$topQuery.data.topList.map(

View File

@ -5,6 +5,7 @@
- `username String`: Empty string if auth. is disabled, otherwise the username as string
- `authlevel Number`: The current users authentication level
- `clusters [String]`: List of cluster names
- `subClusters [String]`: List of subCluster names
- `roles [Number]`: Enum containing available roles
-->
@ -23,14 +24,15 @@
import NavbarLinks from "./header/NavbarLinks.svelte";
import NavbarTools from "./header/NavbarTools.svelte";
export let username;
export let authlevel;
export let clusters;
export let subClusters;
export let roles;
let { username, authlevel, clusters, subClusters, roles } = $props();
let isOpen = false;
let screenSize;
let isOpen = $state(false);
let screenSize = $state(0);
let showMax = $derived(screenSize >= 1500);
let showMid = $derived(screenSize < 1500 && screenSize >= 1300);
let showSml = $derived(screenSize < 1300 && screenSize >= 768);
let showBrg = $derived(screenSize < 768);
const jobsTitle = new Map();
jobsTitle.set(2, "Job Search");
@ -123,26 +125,28 @@
</script>
<svelte:window bind:innerWidth={screenSize} />
<Navbar color="light" light expand="md" fixed="top">
<NavbarBrand href="/">
<img alt="ClusterCockpit Logo" src="/img/logo.png" height="25rem" />
</NavbarBrand>
<NavbarToggler on:click={() => (isOpen = !isOpen)} />
<NavbarToggler onclick={() => (isOpen = !isOpen)} />
<Collapse
style="justify-content: space-between"
{isOpen}
navbar
expand="md"
on:update={({ detail }) => (isOpen = detail.isOpen)}
onupdate={({ detail }) => (isOpen = detail.isOpen)}
>
<Nav navbar>
{#if screenSize > 1500 || screenSize < 768}
{#if showMax || showBrg}
<NavbarLinks
{clusters}
{subClusters}
links={views.filter((item) => item.requiredRole <= authlevel)}
/>
{:else if screenSize > 1300}
{:else if showMid}
<NavbarLinks
{clusters}
{subClusters}
@ -169,7 +173,8 @@
</DropdownMenu>
</Dropdown>
{/if}
{:else}
{:else if showSml}
<NavbarLinks
{clusters}
{subClusters}
@ -228,8 +233,11 @@
</DropdownMenu>
</Dropdown>
{/if}
{:else}
<span>Error: Unknown Window Size!</span>
{/if}
</Nav>
<NavbarTools {username} {authlevel} {roles} {screenSize} />
</Collapse>
</Navbar>
</Navbar>

View File

@ -478,6 +478,7 @@
<Card body color="danger">{$topUserQuery.error.message}</Card>
{:else}
<Pie
canvasId="hpcpie-users"
size={colWidth}
sliceLabel={topUserSelection.label}
quantities={$topUserQuery.data.topUser.map(
@ -538,6 +539,7 @@
<Card body color="danger">{$topProjectQuery.error.message}</Card>
{:else}
<Pie
canvasId="hpcpie-projects"
size={colWidth}
sliceLabel={topProjectSelection.label}
quantities={$topProjectQuery.data.topProjects.map(

View File

@ -1,9 +1,10 @@
import { mount } from 'svelte';
import {} from './header.entrypoint.js'
import Analysis from './Analysis.root.svelte'
filterPresets.cluster = cluster
new Analysis({
mount(Analysis, {
target: document.getElementById('svelte-app'),
props: {
filterPresets: filterPresets,

View File

@ -1,7 +1,8 @@
import { mount } from 'svelte';
import {} from './header.entrypoint.js'
import Config from './Config.root.svelte'
new Config({
mount(Config, {
target: document.getElementById('svelte-app'),
props: {
isAdmin: isAdmin,

View File

@ -153,13 +153,13 @@
{/each}
</div>
<p style="display: flex; align-items: center;">
<Button type="submit" color="primary">Submit</Button>
{#if displayMessage}<div style="margin-left: 1.5em;">
<b
><code style="color: {message.color};" out:fade>{message.msg}</code
></b
>
</div>{/if}
<Button type="submit" color="primary" style="margin-right: 1.5em;">Submit</Button>
{#if displayMessage}
<b
><code style="color: {message.color};" out:fade>{message.msg}</code
></b
>
{/if}
</p>
</form>
</Card>

View File

@ -91,15 +91,15 @@
</span>
{#if job.metaData?.jobName}
{#if job.metaData?.jobName.length <= 25}
<div>{job.metaData.jobName}</div>
<span>{job.metaData.jobName}</span>
{:else}
<div
<span
class="truncate"
style="cursor:help;"
title={job.metaData.jobName}
>
{job.metaData.jobName}
</div>
</span>
{/if}
{/if}
{#if job.arrayJobId}

View File

@ -28,13 +28,13 @@
</div>
<div class="cc-pagination-right">
{#if !backButtonDisabled}
<button class="reset nav" type="button"
<button aria-label="page-reset" class="reset nav" type="button"
on:click|preventDefault="{reset}"></button>
<button class="left nav" type="button"
<button aria-label="page-back" class="left nav" type="button"
on:click|preventDefault="{() => { page -= 1; }}"></button>
{/if}
{#if !nextButtonDisabled}
<button class="right nav" type="button"
<button aria-label="page-up" class="right nav" type="button"
on:click|preventDefault="{() => { page += 1; }}"></button>
{/if}
</div>

View File

@ -259,7 +259,7 @@
<!-- Define Wrapper and NoData Card within $width -->
<div bind:clientWidth={width}>
{#if data.length > 0}
<div bind:this={plotWrapper} />
<div bind:this={plotWrapper}></div>
{:else}
<Card class="mx-4" body color="warning"
>Cannot render histogram: No data!</Card

View File

@ -607,7 +607,7 @@
{#if series[0]?.data && series[0].data.length > 0}
<div bind:this={plotWrapper} bind:clientWidth={width}
style="background-color: {backgroundColor()};" class={forNode ? 'py-2 rounded' : 'rounded'}
/>
></div>
{:else}
<Card body color="warning" class="mx-4"
>Cannot render plot: No series data returned for <code>{metric}</code></Card

View File

@ -1,5 +1,5 @@
<!--
@component Pie Plot based on uPlot Pie
@component Pie Plot based on chart.js Pie
Properties:
- `size Number`: X and Y size of the plot, for square shape
@ -31,33 +31,17 @@
]
</script>
<script>
import { Pie } from 'svelte-chartjs';
import {
Chart as ChartJS,
Title,
Tooltip,
Legend,
Filler,
ArcElement,
CategoryScale
} from 'chart.js';
ChartJS.register(
Title,
Tooltip,
Legend,
Filler,
ArcElement,
CategoryScale
);
import Chart from 'chart.js/auto'
import { onMount } from 'svelte';
export let canvasId
export let size
export let sliceLabel
export let quantities
export let entities
export let displayLegend = false
$: data = {
const data = {
labels: entities,
datasets: [
{
@ -79,10 +63,22 @@
}
}
onMount(() => {
new Chart(
document.getElementById(canvasId),
{
type: 'pie',
data: data,
options: options
}
);
});
</script>
<!-- <div style="width: 500px;"><canvas id="dimensions"></canvas></div><br/> -->
<div class="chart-container" style="--container-width: {size}; --container-height: {size}">
<Pie {data} {options}/>
<canvas id={canvasId}></canvas>
</div>
<style>

View File

@ -1,5 +1,5 @@
<!--
@component Polar Plot based on chartJS Radar
@component Polar Plot based on chart.js Radar
Properties:
- `footprintData [Object]?`: job.footprint content, evaluated in regards to peak config in jobSummary.svelte [Default: null]
@ -11,29 +11,10 @@
-->
<script>
import { getContext } from 'svelte'
import { Radar } from 'svelte-chartjs';
import {
Chart as ChartJS,
Title,
Tooltip,
Legend,
Filler,
PointElement,
RadialLinearScale,
LineElement
} from 'chart.js';
ChartJS.register(
Title,
Tooltip,
Legend,
Filler,
PointElement,
RadialLinearScale,
LineElement
);
import { getContext, onMount } from 'svelte'
import Chart from 'chart.js/auto'
export let canvasId;
export let footprintData = null;
export let metrics = null;
export let cluster = null;
@ -183,10 +164,23 @@
}
}
onMount(() => {
new Chart(
document.getElementById(canvasId),
{
type: 'radar',
data: data,
options: options,
height: height
}
);
});
</script>
<!-- <div style="width: 500px;"><canvas id="dimensions"></canvas></div><br/> -->
<div class="chart-container">
<Radar {data} {options} {height}/>
<canvas id={canvasId}></canvas>
</div>
<style>

View File

@ -363,7 +363,7 @@
</script>
{#if data != null}
<div bind:this={plotWrapper} class="p-2"/>
<div bind:this={plotWrapper} class="p-2"></div>
{:else}
<Card class="mx-4" body color="warning">Cannot render roofline: No data!</Card
>

View File

@ -148,10 +148,13 @@
<li
class="cc-config-column list-group-item"
draggable={true}
ondragover="return false"
on:dragstart={(event) => columnsDragStart(event, index)}
on:drop|preventDefault={(event) => columnsDrag(event, index)}
on:dragenter={() => (columnHovering = index)}
ondragover={() => false}
ondragstart={(event) => columnsDragStart(event, index)}
ondrop={(event) => {
event.preventDefault()
columnsDrag(event, index)
}}
ondragenter={() => (columnHovering = index)}
class:is-active={columnHovering === index}
>
{#if unorderedMetrics.includes(metric)}

View File

@ -1,10 +1,11 @@
import Header from './Header.svelte'
import { mount } from 'svelte';
import Header from './Header.svelte';
const headerDomTarget = document.getElementById('svelte-header')
const headerDomTarget = document.getElementById('svelte-header');
if (headerDomTarget != null) {
new Header({
mount(Header, {
target: headerDomTarget,
props: { ...header },
})
});
}

View File

@ -1,7 +1,8 @@
import { mount } from 'svelte';
import {} from './header.entrypoint.js'
import Job from './Job.root.svelte'
new Job({
mount(Job, {
target: document.getElementById('svelte-app'),
props: {
dbid: jobInfos.id,

View File

@ -282,6 +282,7 @@
<TabPane tabId="polar" tab="Polar" active={!showFootprint}>
<CardBody>
<Polar
canvasId={job.jobId}
{footprintData}
{jobMetrics}
/>

View File

@ -71,26 +71,28 @@
{:else}
<td colspan="4">
<table style="width: 100%;">
<tr>
{#each ["id", "min", "avg", "max"] as field}
<th on:click={() => sortByField(field)}>
Sort
<Icon
name="caret-{sorting[field].dir}{sorting[field].active
? '-fill'
: ''}"
/>
</th>
{/each}
</tr>
{#each series as s, i}
<tbody>
<tr>
<th>{s.id ?? i}</th>
<td>{s.statistics.min}</td>
<td>{s.statistics.avg}</td>
<td>{s.statistics.max}</td>
{#each ["id", "min", "avg", "max"] as field}
<th on:click={() => sortByField(field)}>
Sort
<Icon
name="caret-{sorting[field].dir}{sorting[field].active
? '-fill'
: ''}"
/>
</th>
{/each}
</tr>
{/each}
{#each series as s, i}
<tr>
<th>{s.id ?? i}</th>
<td>{s.statistics.min}</td>
<td>{s.statistics.avg}</td>
<td>{s.statistics.max}</td>
</tr>
{/each}
</tbody>
</table>
</td>
{/if}

View File

@ -1,7 +1,8 @@
import { mount } from 'svelte';
import {} from './header.entrypoint.js'
import Jobs from './Jobs.root.svelte'
new Jobs({
mount(Jobs, {
target: document.getElementById('svelte-app'),
props: {
filterPresets: filterPresets,

View File

@ -1,7 +1,8 @@
import { mount } from 'svelte';
import {} from './header.entrypoint.js'
import List from './List.root.svelte'
new List({
mount(List, {
target: document.getElementById('svelte-app'),
props: {
filterPresets: filterPresets,

View File

@ -1,7 +1,8 @@
import { mount } from 'svelte';
import {} from './header.entrypoint.js'
import Node from './Node.root.svelte'
new Node({
mount(Node, {
target: document.getElementById('svelte-app'),
props: {
cluster: infos.cluster,

View File

@ -1,7 +1,8 @@
import { mount } from 'svelte';
import {} from './header.entrypoint.js'
import Status from './Status.root.svelte'
new Status({
mount(Status, {
target: document.getElementById('svelte-app'),
props: {
cluster: infos.cluster,

View File

@ -1,7 +1,8 @@
import { mount } from 'svelte';
import {} from './header.entrypoint.js'
import Systems from './Systems.root.svelte'
new Systems({
mount(Systems, {
target: document.getElementById('svelte-app'),
props: {
displayType: displayType,

View File

@ -155,7 +155,7 @@
height={175}
forNode
/>
<div class="my-2"/>
<div class="my-2"></div>
{#key extendedLegendData}
<MetricPlot
{cluster}

View File

@ -1,7 +1,8 @@
import { mount } from 'svelte';
import {} from './header.entrypoint.js'
import User from './User.root.svelte'
new User({
mount(User, {
target: document.getElementById('svelte-app'),
props: {
filterPresets: filterPresets,