Merge branch 'dev' of github.com:ClusterCockpit/cc-backend into dev

This commit is contained in:
2025-12-17 05:46:10 +01:00
8 changed files with 137 additions and 84 deletions

View File

@@ -7,6 +7,7 @@
- `isApi Bool!`: Is currently logged in user api authority
- `username String!`: Empty string if auth. is disabled, otherwise the username as string
- `ncontent String!`: The currently displayed message on the homescreen
- `clusters [String]`: The available clusternames
-->
<script>
@@ -22,6 +23,7 @@
isApi,
username,
ncontent,
clusters
} = $props();
</script>
@@ -30,7 +32,7 @@
<CardHeader>
<CardTitle class="mb-1">Admin Options</CardTitle>
</CardHeader>
<AdminSettings {ncontent}/>
<AdminSettings {ncontent} {clusters}/>
</Card>
{/if}

View File

@@ -30,6 +30,7 @@
Table,
Progress,
Icon,
Button
} from "@sveltestrap/sveltestrap";
import Roofline from "./generic/plots/Roofline.svelte";
import Pie, { colors } from "./generic/plots/Pie.svelte";
@@ -353,6 +354,11 @@
}}
/>
</Col>
<Col class="d-flex justify-content-end">
<Button outline class="mb-1" size="sm" color="light" href="/">
<Icon name="x"/>
</Button>
</Col>
</Row>
{#if $statusQuery.fetching || $statesTimed.fetching}
<Row class="justify-content-center">
@@ -503,6 +509,7 @@
</Col>
<Col> <!-- Pie Last States -->
<Row>
{#if refinedStateData.length > 0}
<Col class="px-3 mt-2 mt-lg-0">
<div bind:clientWidth={colWidthStates}>
{#key refinedStateData}
@@ -541,6 +548,13 @@
</Table>
{/key}
</Col>
{:else}
<Col>
<Card body color="warning" class="mx-4 my-2"
>Cannot render state status: No state data returned for <code>Pie Chart</code></Card
>
</Col>
{/if}
</Row>
</Col>

View File

@@ -10,6 +10,7 @@ mount(Config, {
isApi: isApi,
username: username,
ncontent: ncontent,
clusters: hClusters.map((c) => c.name) // Defined in Header Template
},
context: new Map([
['cc-config', clusterCockpitConfig],

View File

@@ -3,6 +3,7 @@
Properties:
- `ncontent String`: The homepage notice content
- `clusters [String]`: The available clusternames
-->
<script>
@@ -17,7 +18,8 @@
/* Svelte 5 Props */
let {
ncontent
ncontent,
clusters
} = $props();
/* Const Init*/
@@ -66,6 +68,6 @@
<Col>
<EditProject reloadUser={() => getUserList()} />
</Col>
<Options config={ccconfig}/>
<Options config={ccconfig} {clusters}/>
<NoticeEdit {ncontent}/>
</Row>

View File

@@ -1,10 +1,18 @@
<!--
@component Admin option select card
Properties:
- `clusters [String]`: The available clusternames
-->
<script>
import { getContext, onMount } from "svelte";
import { Col, Card, CardBody, CardTitle } from "@sveltestrap/sveltestrap";
import { Row, Col, Card, CardBody, CardTitle, Button, Icon } from "@sveltestrap/sveltestrap";
/* Svelte 5 Props */
let {
clusters,
} = $props();
/*Const Init */
const resampleConfig = getContext("resampling");
@@ -44,6 +52,26 @@
</Card>
</Col>
{#if clusters?.length > 0}
<Col>
<Card class="h-100">
<CardBody>
<CardTitle class="mb-3">Public Dashboard Links</CardTitle>
<Row>
{#each clusters as cluster}
<Col>
<Button color="info" class="mb-2 mb-xl-0" href={`/monitoring/dashboard/${cluster}`} target="_blank">
<Icon name="clipboard-pulse" class="mr-2"/>
{cluster.charAt(0).toUpperCase() + cluster.slice(1)} Public Dashboard
</Button>
</Col>
{/each}
</Row>
</CardBody>
</Card>
</Col>
{/if}
{#if resampleConfig}
<Col>
<Card class="h-100">

View File

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

View File

@@ -101,10 +101,10 @@
};
// Data Prep For uPlot
const sortedData = data.sort((a, b) => a.state.localeCompare(b.state));
const sortedData = data?.sort((a, b) => a.state.localeCompare(b.state)) || [];
const collectLabel = sortedData.map(d => d.state);
// Align Data to Timesteps, Introduces 'undefied' as placeholder, reiterate and set those to 0
const collectData = uPlot.join(sortedData.map(d => [d.times, d.counts])).map(d => d.map(i => i ? i : 0));
const collectData = (sortedData.length > 0) ? uPlot.join(sortedData.map(d => [d.times, d.counts])).map(d => d.map(i => i ? i : 0)) : [];
// STACKED CHART FUNCTIONS //
function stack(data, omit) {
@@ -344,7 +344,7 @@
</script>
<!-- Define $width Wrapper and NoData Card -->
{#if data && collectData[0].length > 0}
{#if data && collectData.length > 0}
<div bind:this={plotWrapper} bind:clientWidth={width}
style="background-color: rgba(255, 255, 255, 1.0);" class="rounded"
></div>

View File

@@ -487,6 +487,7 @@
</Col>
<Col> <!-- Pie Jobs -->
{#if topJobsQuery?.data?.jobsStatistics?.length > 0}
<Row cols={{xs:1, md:2}}>
<Col class="p-2">
<div bind:clientWidth={colWidthJobs}>
@@ -526,6 +527,11 @@
</Table>
</Col>
</Row>
{:else}
<Card body color="warning" class="mx-4 my-2"
>Cannot render job status: No state data returned for <code>Pie Chart</code></Card
>
{/if}
</Col>
<Col> <!-- Job Roofline -->