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

This commit is contained in:
2025-07-07 13:09:16 +02:00
77 changed files with 2082 additions and 1988 deletions
@@ -21,3 +21,15 @@ CREATE TABLE "node" (
meta_data TEXT, -- JSON meta_data TEXT, -- JSON
UNIQUE (hostname, cluster) UNIQUE (hostname, cluster)
); );
-- Add Indices For New Node Table VARCHAR Fields
CREATE INDEX IF NOT EXISTS nodes_cluster ON node (cluster);
CREATE INDEX IF NOT EXISTS nodes_cluster_subcluster ON node (cluster, subcluster);
CREATE INDEX IF NOT EXISTS nodes_state ON node (node_state);
CREATE INDEX IF NOT EXISTS nodes_cluster_state ON node (cluster, node_state);
CREATE INDEX IF NOT EXISTS nodes_health ON node (health_state);
CREATE INDEX IF NOT EXISTS nodes_cluster_health ON node (cluster, health_state);
-- Add Indices For Increased Amounts of Tags
CREATE INDEX IF NOT EXISTS tags_jobid ON jobtag (job_id);
CREATE INDEX IF NOT EXISTS tags_tagid ON jobtag (tag_id);
+8 -4
View File
@@ -3,7 +3,7 @@
Properties: Properties:
- `filterPresets Object`: Optional predefined filter values - `filterPresets Object`: Optional predefined filter values
--> -->
<script> <script>
import { getContext, onMount } from "svelte"; import { getContext, onMount } from "svelte";
@@ -38,7 +38,9 @@
import RooflineHeatmap from "./generic/plots/RooflineHeatmap.svelte"; import RooflineHeatmap from "./generic/plots/RooflineHeatmap.svelte";
/* Svelte 5 Props */ /* Svelte 5 Props */
let { filterPresets } = $props(); let {
filterPresets
} = $props();
// By default, look at the jobs of the last 6 hours: // By default, look at the jobs of the last 6 hours:
if (filterPresets?.startTime == null) { if (filterPresets?.startTime == null) {
@@ -346,8 +348,10 @@
{:else if cluster} {:else if cluster}
<PlotSelection <PlotSelection
availableMetrics={availableMetrics.map((av) => av.name)} availableMetrics={availableMetrics.map((av) => av.name)}
bind:metricsInHistograms presetMetricsInHistograms={metricsInHistograms}
bind:metricsInScatterplots presetMetricsInScatterplots={metricsInScatterplots}
applyHistograms={(metrics) => metricsInHistograms = [...metrics]}
applyScatter={(metrics) => metricsInScatterplots = [...metrics]}
/> />
{/if} {/if}
</Col> </Col>
+2 -1
View File
@@ -6,7 +6,8 @@
- `isSupport Bool!`: Is currently logged in user support authority - `isSupport Bool!`: Is currently logged in user support authority
- `isApi Bool!`: Is currently logged in user api authority - `isApi Bool!`: Is currently logged in user api authority
- `username String!`: Empty string if auth. is disabled, otherwise the username as string - `username String!`: Empty string if auth. is disabled, otherwise the username as string
--> - `ncontent String!`: The currently displayed message on the homescreen
-->
<script> <script>
import { Card, CardHeader, CardTitle } from "@sveltestrap/sveltestrap"; import { Card, CardHeader, CardTitle } from "@sveltestrap/sveltestrap";
+13 -7
View File
@@ -7,7 +7,7 @@
- `clusters [String]`: List of cluster names - `clusters [String]`: List of cluster names
- `subClusters [String]`: List of subCluster names - `subClusters [String]`: List of subCluster names
- `roles [Number]`: Enum containing available roles - `roles [Number]`: Enum containing available roles
--> -->
<script> <script>
import { import {
@@ -25,7 +25,13 @@
import NavbarTools from "./header/NavbarTools.svelte"; import NavbarTools from "./header/NavbarTools.svelte";
/* Svelte 5 Props */ /* Svelte 5 Props */
let { username, authlevel, clusters, subClusters, roles } = $props(); let {
username,
authlevel,
clusters,
subClusters,
roles
} = $props();
/* Const Init */ /* Const Init */
const jobsTitle = new Map(); const jobsTitle = new Map();
@@ -123,11 +129,11 @@
let isOpen = $state(false); let isOpen = $state(false);
let screenSize = $state(0); let screenSize = $state(0);
/* Derived Vars */ /* Derived */
let showMax = $derived(screenSize >= 1500); const showMax = $derived(screenSize >= 1500);
let showMid = $derived(screenSize < 1500 && screenSize >= 1300); const showMid = $derived(screenSize < 1500 && screenSize >= 1300);
let showSml = $derived(screenSize < 1300 && screenSize >= 768); const showSml = $derived(screenSize < 1300 && screenSize >= 768);
let showBrg = $derived(screenSize < 768); const showBrg = $derived(screenSize < 768);
</script> </script>
<svelte:window bind:innerWidth={screenSize} /> <svelte:window bind:innerWidth={screenSize} />
+3 -3
View File
@@ -6,7 +6,7 @@
- `username String`: Empty string if auth. is disabled, otherwise the username as string - `username String`: Empty string if auth. is disabled, otherwise the username as string
- `authlevel Number`: The current users authentication level - `authlevel Number`: The current users authentication level
- `roles [Number]`: Enum containing available roles - `roles [Number]`: Enum containing available roles
--> -->
<script> <script>
import { getContext } from "svelte"; import { getContext } from "svelte";
@@ -156,9 +156,9 @@
/* Effects */ /* Effects */
$effect(() => { $effect(() => {
document.title = $initq.fetching document.title = $initq?.fetching
? "Loading..." ? "Loading..."
: $initq.error : $initq?.error
? "Error" ? "Error"
: `Job ${$initq.data.job.jobId} - ClusterCockpit`; : `Job ${$initq.data.job.jobId} - ClusterCockpit`;
}); });
+7 -3
View File
@@ -2,10 +2,10 @@
@component Main job list component @component Main job list component
Properties: Properties:
- `filterPresets Object?`: Optional predefined filter values [Default: {}] - `filterPresets Object`: Optional predefined filter values
- `authlevel Number`: The current users authentication level - `authlevel Number`: The current users authentication level
- `roles [Number]`: Enum containing available roles - `roles [Number]`: Enum containing available roles
--> -->
<script> <script>
import { untrack, onMount, getContext } from "svelte"; import { untrack, onMount, getContext } from "svelte";
@@ -28,7 +28,11 @@
import MetricSelection from "./generic/select/MetricSelection.svelte"; import MetricSelection from "./generic/select/MetricSelection.svelte";
/* Svelte 5 Props */ /* Svelte 5 Props */
let { filterPresets, authlevel, roles } = $props(); let {
filterPresets,
authlevel,
roles
} = $props();
/* Const Init */ /* Const Init */
const { query: initq } = init(); const { query: initq } = init();
+19 -13
View File
@@ -4,7 +4,7 @@
Properties: Properties:
- `type String?`: The type of list ['USER' || 'PROJECT'] - `type String?`: The type of list ['USER' || 'PROJECT']
- `filterPresets Object?`: Optional predefined filter values [Default: {}] - `filterPresets Object?`: Optional predefined filter values [Default: {}]
--> -->
<script> <script>
import { onMount } from "svelte"; import { onMount } from "svelte";
@@ -32,18 +32,12 @@
import Filters from "./generic/Filters.svelte"; import Filters from "./generic/Filters.svelte";
/* Svelte 5 Props */ /* Svelte 5 Props */
let { type, filterPresets } = $props(); let {
type,
// By default, look at the jobs of the last 30 days: filterPresets
if (filterPresets?.startTime == null) { } = $props();
if (filterPresets == null) filterPresets = {};
filterPresets.startTime = {
range: "last30d",
text: "Last 30 Days",
};
}
/* Validate Type */
console.assert( console.assert(
type == "USER" || type == "PROJECT", type == "USER" || type == "PROJECT",
"Invalid list type provided!", "Invalid list type provided!",
@@ -107,7 +101,19 @@
} }
/* On Mount */ /* On Mount */
onMount(() => filterComponent.updateFilters()); onMount(() => {
// By default, look at the jobs of the last 30 days:
if (filterPresets?.startTime == null) {
if (filterPresets == null) filterPresets = {};
filterPresets.startTime = {
range: "last30d",
text: "Last 30 Days",
};
};
// Init Filter
filterComponent.updateFilters();
});
</script> </script>
<Row cols={{ xs: 1, md: 2}}> <Row cols={{ xs: 1, md: 2}}>
+3 -3
View File
@@ -4,9 +4,9 @@
Properties: Properties:
- `cluster String`: Currently selected cluster - `cluster String`: Currently selected cluster
- `hostname String`: Currently selected host (== node) - `hostname String`: Currently selected host (== node)
- `from Date?`: Custom Time Range selection 'from' [Default: null] - `presetFrom Date?`: Custom Time Range selection 'from' [Default: null]
- `to Date?`: Custom Time Range selection 'to' [Default: null] - `presetTo Date?`: Custom Time Range selection 'to' [Default: null]
--> -->
<script> <script>
import { import {
+10 -9
View File
@@ -3,7 +3,7 @@
Properties: Properties:
- `cluster String`: The cluster to show status information for - `cluster String`: The cluster to show status information for
--> -->
<script> <script>
import { getContext } from "svelte"; import { getContext } from "svelte";
@@ -43,7 +43,9 @@
import HistogramSelection from "./generic/select/HistogramSelection.svelte"; import HistogramSelection from "./generic/select/HistogramSelection.svelte";
/* Svelte 5 Props */ /* Svelte 5 Props */
let { cluster } = $props(); let {
cluster
} = $props();
/* Const Init */ /* Const Init */
const { query: initq } = init(); const { query: initq } = init();
@@ -60,9 +62,13 @@
/* State Init */ /* State Init */
let from = $state(new Date(Date.now() - 5 * 60 * 1000)); let from = $state(new Date(Date.now() - 5 * 60 * 1000));
let to = $state(new Date(Date.now())); let to = $state(new Date(Date.now()));
let isHistogramSelectionOpen = $state(false);
let colWidth = $state(0); let colWidth = $state(0);
let plotWidths = $state([]); let plotWidths = $state([]);
// Histrogram
let isHistogramSelectionOpen = $state(false);
let selectedHistograms = $state(cluster
? ccconfig[`user_view_histogramMetrics:${cluster}`] || ( ccconfig['user_view_histogramMetrics'] || [] )
: ccconfig['user_view_histogramMetrics'] || []);
// Bar Gauges // Bar Gauges
let allocatedNodes = $state({}); let allocatedNodes = $state({});
let flopRate = $state({}); let flopRate = $state({});
@@ -71,11 +77,7 @@
let memBwRate = $state({}); let memBwRate = $state({});
let memBwRateUnitPrefix = $state({}); let memBwRateUnitPrefix = $state({});
let memBwRateUnitBase = $state({}); let memBwRateUnitBase = $state({});
// Pie Charts
let selectedHistograms = $state(cluster
? ccconfig[`user_view_histogramMetrics:${cluster}`] || ( ccconfig['user_view_histogramMetrics'] || [] )
: ccconfig['user_view_histogramMetrics'] || []);
let topProjectSelection = $state( let topProjectSelection = $state(
topOptions.find( topOptions.find(
(option) => (option) =>
@@ -86,7 +88,6 @@
(option) => option.key == ccconfig.status_view_selectedTopProjectCategory, (option) => option.key == ccconfig.status_view_selectedTopProjectCategory,
) )
); );
let topUserSelection = $state( let topUserSelection = $state(
topOptions.find( topOptions.find(
(option) => (option) =>
+12 -9
View File
@@ -3,10 +3,11 @@
Properties: Properties:
- `displayType String?`: The type of node display ['OVERVIEW' || 'LIST'] - `displayType String?`: The type of node display ['OVERVIEW' || 'LIST']
- `cluster String`: The cluster to show status information for - `cluster String`: The cluster to show status information for [Default: null]
- `from Date?`: Custom Time Range selection 'from' [Default: null] - `subCluster String`: The subCluster to show status information for [Default: null]
- `to Date?`: Custom Time Range selection 'to' [Default: null] - `presetFrom Date?`: Custom Time Range selection 'from' [Default: null]
--> - `presetTo Date?`: Custom Time Range selection 'to' [Default: null]
-->
<script> <script>
import { getContext } from "svelte"; import { getContext } from "svelte";
@@ -38,8 +39,8 @@
displayType, displayType,
cluster = null, cluster = null,
subCluster = null, subCluster = null,
fromPreset = null, presetFrom = null,
toPreset = null, presetTo = null,
} = $props(); } = $props();
/* Const Init */ /* Const Init */
@@ -54,9 +55,12 @@
const resampleDefault = resampleConfig ? Math.max(...resampleConfig.resolutions) : 0; const resampleDefault = resampleConfig ? Math.max(...resampleConfig.resolutions) : 0;
const nowDate = new Date(Date.now()); const nowDate = new Date(Date.now());
/* Var Init */
let timeoutId = null;
/* State Init */ /* State Init */
let to = $state(toPreset || new Date(Date.now())); let to = $state(presetTo || new Date(Date.now()));
let from = $state(fromPreset || new Date(nowDate.setHours(nowDate.getHours() - 4))); let from = $state(presetFrom || new Date(nowDate.setHours(nowDate.getHours() - 4)));
let selectedResolution = $state(resampleConfig ? resampleDefault : 0); let selectedResolution = $state(resampleConfig ? resampleDefault : 0);
let hostnameFilter = $state(""); let hostnameFilter = $state("");
let pendingHostnameFilter = $state(""); let pendingHostnameFilter = $state("");
@@ -89,7 +93,6 @@
}; };
// Wait after input for some time to prevent too many requests // Wait after input for some time to prevent too many requests
let timeoutId = null;
function updateHostnameFilter() { function updateHostnameFilter() {
if (timeoutId != null) clearTimeout(timeoutId); if (timeoutId != null) clearTimeout(timeoutId);
timeoutId = setTimeout(function () { timeoutId = setTimeout(function () {
+5 -5
View File
@@ -4,8 +4,8 @@
Properties: Properties:
- `username String!`: Users username. - `username String!`: Users username.
- `isAdmin Bool!`: User has Admin Auth. - `isAdmin Bool!`: User has Admin Auth.
- `tagmap Object!`: Map of accessible, appwide tags. Prefiltered in backend. - `presetTagmap Object!`: Map of accessible, appwide tags. Prefiltered in backend.
--> -->
<script> <script>
import { import {
@@ -37,7 +37,7 @@
/* State Init */ /* State Init */
let pendingChange = $state("none"); let pendingChange = $state("none");
let tagmap = $state(presetTagmap) let tagmap = $state(presetTagmap);
/* Functions */ /* Functions */
const removeTagMutation = ({ tagIds }) => { const removeTagMutation = ({ tagIds }) => {
@@ -68,8 +68,8 @@
} }
}, },
); );
} };
} };
</script> </script>
<div class="container"> <div class="container">
+5 -2
View File
@@ -4,7 +4,7 @@
Properties: Properties:
- `user Object`: The GraphQL user object - `user Object`: The GraphQL user object
- `filterPresets Object`: Optional predefined filter values - `filterPresets Object`: Optional predefined filter values
--> -->
<script> <script>
import { onMount, getContext } from "svelte"; import { onMount, getContext } from "svelte";
@@ -43,7 +43,10 @@
import Refresher from "./generic/helper/Refresher.svelte"; import Refresher from "./generic/helper/Refresher.svelte";
/* Svelte 5 Props */ /* Svelte 5 Props */
let { user, filterPresets } = $props(); let {
user,
filterPresets
} = $props();
/* Const Init */ /* Const Init */
const { query: initq } = init(); const { query: initq } = init();
+17 -7
View File
@@ -3,9 +3,11 @@
Properties: Properties:
- `availableMetrics [String]`: Available metrics in selected cluster - `availableMetrics [String]`: Available metrics in selected cluster
- `metricsInHistograms [String]`: The currently selected metrics to display as histogram - `presetMetricsInHistograms [String]`: The latest selected metrics to display as histogram
- `metricsInScatterplots [[String, String]]`: The currently selected metrics to display as scatterplot - `presetMetricsInScatterplots [[String, String]]`: The latest selected metrics to display as scatterplot
--> - `applyHistograms Func`: The callback function to apply current histogramMetrics selection
- `applyScatter Func`: The callback function to apply current scatterMetrics selection
-->
<script> <script>
import { import {
@@ -24,8 +26,10 @@
/* Svelte 5 Props */ /* Svelte 5 Props */
let { let {
availableMetrics, availableMetrics,
metricsInHistograms = $bindable(), presetMetricsInHistograms,
metricsInScatterplots = $bindable(), presetMetricsInScatterplots,
applyHistograms,
applyScatter
} = $props(); } = $props();
/* Const Init */ /* Const Init */
@@ -45,6 +49,8 @@
/* State Init */ /* State Init */
let isHistogramConfigOpen = $state(false); let isHistogramConfigOpen = $state(false);
let isScatterPlotConfigOpen = $state(false); let isScatterPlotConfigOpen = $state(false);
let metricsInHistograms = $state(presetMetricsInHistograms);
let metricsInScatterplots = $state(presetMetricsInScatterplots);
let selectedMetric1 = $state(null); let selectedMetric1 = $state(null);
let selectedMetric2 = $state(null); let selectedMetric2 = $state(null);
@@ -84,11 +90,13 @@
type="checkbox" type="checkbox"
bind:group={metricsInHistograms} bind:group={metricsInHistograms}
value={metric} value={metric}
onchange={() => onchange={() => {
updateConfiguration({ updateConfiguration({
name: "analysis_view_histogramMetrics", name: "analysis_view_histogramMetrics",
value: metricsInHistograms, value: metricsInHistograms,
})} });
applyHistograms(metricsInHistograms);
}}
/> />
{metric} {metric}
@@ -126,6 +134,7 @@
name: "analysis_view_scatterPlotMetrics", name: "analysis_view_scatterPlotMetrics",
value: metricsInScatterplots, value: metricsInScatterplots,
}); });
applyScatter(metricsInScatterplots);
}} }}
> >
<Icon name="x" /> <Icon name="x" />
@@ -163,6 +172,7 @@
name: "analysis_view_scatterPlotMetrics", name: "analysis_view_scatterPlotMetrics",
value: metricsInScatterplots, value: metricsInScatterplots,
}); });
applyScatter(metricsInScatterplots);
}} }}
> >
Add Plot Add Plot
+7 -2
View File
@@ -1,6 +1,9 @@
<!-- <!--
@component Admin settings wrapper @component Admin settings wrapper
-->
Properties:
- `ncontent String`: The homepage notice content
-->
<script> <script>
import { Row, Col } from "@sveltestrap/sveltestrap"; import { Row, Col } from "@sveltestrap/sveltestrap";
@@ -13,7 +16,9 @@
import NoticeEdit from "./admin/NoticeEdit.svelte"; import NoticeEdit from "./admin/NoticeEdit.svelte";
/* Svelte 5 Props */ /* Svelte 5 Props */
let { ncontent } = $props(); let {
ncontent
} = $props();
/* Const Init*/ /* Const Init*/
const ccconfig = getContext("cc-config"); const ccconfig = getContext("cc-config");
@@ -1,12 +1,12 @@
<!-- <!--
@component Support settings wrapper @component Support settings wrapper
Properties: None -->
-->
<script> <script>
import { getContext } from "svelte"; import { getContext } from "svelte";
import SupportOptions from "./support/SupportOptions.svelte"; import SupportOptions from "./support/SupportOptions.svelte";
/* Const Init */
const ccconfig = getContext("cc-config"); const ccconfig = getContext("cc-config");
</script> </script>
+1 -1
View File
@@ -4,7 +4,7 @@
Properties: Properties:
- `username String!`: Empty string if auth. is disabled, otherwise the username as string - `username String!`: Empty string if auth. is disabled, otherwise the username as string
- `isApi Bool!`: Is currently logged in user api authority - `isApi Bool!`: Is currently logged in user api authority
--> -->
<script> <script>
import { getContext } from "svelte"; import { getContext } from "svelte";
+6 -5
View File
@@ -3,17 +3,18 @@
Properties: Properties:
- `roles [String]!`: List of roles used in app as strings - `roles [String]!`: List of roles used in app as strings
- `reloadUser Func`: The callback function to reload the user list
Events: -->
- `reload`: Trigger upstream reload of user list after user creation
-->
<script> <script>
import { Button, Card, CardTitle } from "@sveltestrap/sveltestrap"; import { Button, Card, CardTitle } from "@sveltestrap/sveltestrap";
import { fade } from "svelte/transition"; import { fade } from "svelte/transition";
/* Svelte 5 Props */ /* Svelte 5 Props */
let { roles, reloadUser } = $props(); let {
roles,
reloadUser
} = $props();
/* State Init */ /* State Init */
let message = $state({ msg: "", color: "#d63384" }); let message = $state({ msg: "", color: "#d63384" });
@@ -1,16 +1,18 @@
<!-- <!--
@component User managed project edit form card @component User managed project edit form card
Events: Properties:
- `reload`: Trigger upstream reload of user list after project update - `reloadUser Func`: The callback function to reload the user list
--> -->
<script> <script>
import { Card, CardTitle, CardBody } from "@sveltestrap/sveltestrap"; import { Card, CardTitle, CardBody } from "@sveltestrap/sveltestrap";
import { fade } from "svelte/transition"; import { fade } from "svelte/transition";
/* Svelte 5 Props */ /* Svelte 5 Props */
let { reloadUser } = $props(); let {
reloadUser
} = $props();
/* State Init */ /* State Init */
let message = $state({ msg: "", color: "#d63384" }); let message = $state({ msg: "", color: "#d63384" });
@@ -3,17 +3,18 @@
Properties: Properties:
- `roles [String]!`: List of roles used in app as strings - `roles [String]!`: List of roles used in app as strings
- `reloadUser Func`: The callback function to reload the user list
Events: -->
- `reload`: Trigger upstream reload of user list after role edit
-->
<script> <script>
import { Card, CardTitle, CardBody } from "@sveltestrap/sveltestrap"; import { Card, CardTitle, CardBody } from "@sveltestrap/sveltestrap";
import { fade } from "svelte/transition"; import { fade } from "svelte/transition";
/* SVelte 5 Props */ /* SVelte 5 Props */
let {roles, reloadUser } = $props(); let {
roles,
reloadUser
} = $props();
/* State Init */ /* State Init */
let message = $state({ msg: "", color: "#d63384" }); let message = $state({ msg: "", color: "#d63384" });
@@ -1,13 +1,18 @@
<!-- <!--
@component Admin edit notice.txt content card @component Admin edit notice content card
-->
Properties:
- `ncontent String`: The homepage notice content
-->
<script> <script>
import { Col, Card, CardTitle, CardBody } from "@sveltestrap/sveltestrap"; import { Col, Card, CardTitle, CardBody } from "@sveltestrap/sveltestrap";
import { fade } from "svelte/transition"; import { fade } from "svelte/transition";
/* Svelte 5 Props */ /* Svelte 5 Props */
let { ncontent } = $props(); let {
ncontent
} = $props();
/* State Init */ /* State Init */
let message = $state({ msg: "", color: "#d63384" }); let message = $state({ msg: "", color: "#d63384" });
+1 -1
View File
@@ -1,6 +1,6 @@
<!-- <!--
@component Admin option select card @component Admin option select card
--> -->
<script> <script>
import { getContext, onMount } from "svelte"; import { getContext, onMount } from "svelte";
@@ -2,11 +2,9 @@
@component User management table @component User management table
Properties: Properties:
- `users [Object]?`: List of users - `users [Object]?`: List of users [Bindable, Default: []]
- `reloadUser Func`: The callback function to reload the user list
Events: -->
- `reload`: Trigger upstream reload of user list
-->
<script> <script>
import { import {
@@ -19,7 +17,10 @@
import ShowUsersRow from "./ShowUsersRow.svelte"; import ShowUsersRow from "./ShowUsersRow.svelte";
/*Svelte 5 Props */ /*Svelte 5 Props */
let { users = $bindable([]), reloadUser } = $props(); let {
users = $bindable([]),
reloadUser
} = $props();
/* Functions */ /* Functions */
function deleteUser(username) { function deleteUser(username) {
@@ -4,14 +4,16 @@
Properties: Properties:
- `user Object!`: User Object - `user Object!`: User Object
- {username: String, name: String, roles: [String], projects: String, email: String} - {username: String, name: String, roles: [String], projects: String, email: String}
--> -->
<script> <script>
import { Button } from "@sveltestrap/sveltestrap"; import { Button } from "@sveltestrap/sveltestrap";
import { fetchJwt } from "../../generic/utils.js" import { fetchJwt } from "../../generic/utils.js"
/* Svelte 5 Props */ /* Svelte 5 Props */
let { user } = $props(); let {
user
} = $props();
/* State Init */ /* State Init */
let jwt = $state(""); let jwt = $state("");
@@ -1,13 +1,18 @@
<!-- <!--
@component Support option select card @component Support option select card
-->
Properties:
- `config Object`: Config includes latest option states
-->
<script> <script>
import { Row, Col, Card, CardTitle, CardBody, Button} from "@sveltestrap/sveltestrap"; import { Row, Col, Card, CardTitle, CardBody, Button} from "@sveltestrap/sveltestrap";
import { fade } from "svelte/transition"; import { fade } from "svelte/transition";
/* Svelte 5 Props */ /* Svelte 5 Props */
let { config } = $props(); let {
config
} = $props();
/* State Init */ /* State Init */
let message = $state(""); let message = $state("");
@@ -3,12 +3,11 @@
Properties: Properties:
- `config Object`: Current cc-config - `config Object`: Current cc-config
- `message Object`: Message to display on success or error - `message Object`: Message to display on success or error [Bindable]
- `displayMessage Bool`: If to display message content - `displayMessage Bool`: If to display message content [Bindable]
- `cbmode Bool?`: Current colorblindness mode state [Bindable, Default: false]
Events: - `updateSetting Func`: The callback function to apply current option selection
- `update-config, {selector: String, target: String}`: Trigger upstream update of the config option -->
-->
<script> <script>
import { import {
@@ -324,8 +323,8 @@
<Row cols={1} class="p-2 g-2"> <Row cols={1} class="p-2 g-2">
<!-- COLORSCHEME --> <!-- COLORSCHEME -->
<Col <Col>
><Card> <Card>
<form <form
id="colorscheme-form" id="colorscheme-form"
method="post" method="post"
@@ -337,13 +336,13 @@
style="margin-bottom: 1em; display: flex; align-items: center;" style="margin-bottom: 1em; display: flex; align-items: center;"
> >
<div>Color Scheme for Timeseries Plots {cbmode ? `(Color Blind Friendly Palettes)` : ``}</div> <div>Color Scheme for Timeseries Plots {cbmode ? `(Color Blind Friendly Palettes)` : ``}</div>
{#if displayMessage && message.target == "cs"}<div {#if displayMessage && message.target == "cs"}
style="margin-left: auto; font-size: 0.9em;" <div style="margin-left: auto; font-size: 0.9em;">
> <code style="color: {message.color};" out:fade>
<code style="color: {message.color};" out:fade Update: {message.msg}
>Update: {message.msg}</code </code>
> </div>
</div>{/if} {/if}
</CardTitle> </CardTitle>
<input type="hidden" name="key" value="plot_general_colorscheme" /> <input type="hidden" name="key" value="plot_general_colorscheme" />
<Table hover> <Table hover>
@@ -369,8 +368,7 @@
</td> </td>
<td> <td>
{#each rgbrow as rgb} {#each rgbrow as rgb}
<span class="color-dot" style="background-color: {rgb};" <span class="color-dot" style="background-color: {rgb};"></span>
></span>
{/each} {/each}
</td> </td>
</tr> </tr>
@@ -379,16 +377,16 @@
</tbody> </tbody>
</Table> </Table>
</form> </form>
</Card></Col </Card>
> </Col>
</Row> </Row>
<style> <style>
.color-dot { .color-dot {
margin-left: 1px; margin-left: 1px;
height: 12px; height: 12px;
width: 12px; width: 12px;
border-radius: 50%; border-radius: 50%;
display: inline-block; display: inline-block;
} }
</style> </style>
@@ -3,14 +3,12 @@
Properties: Properties:
- `config Object`: Current cc-config - `config Object`: Current cc-config
- `message Object`: Message to display on success or error - `message Object`: Message to display on success or error [Bindable]
- `displayMessage Bool`: If to display message content - `displayMessage Bool`: If to display message content [Bindable]
- `updateSetting Func`: The callback function to apply current option selection
-->
Events: <script>
- `update-config, {selector: String, target: String}`: Trigger upstream update of the config option
-->
<script>
import { import {
Button, Button,
Row, Row,
@@ -31,8 +29,8 @@
<Row cols={3} class="p-2 g-2"> <Row cols={3} class="p-2 g-2">
<!-- LINE WIDTH --> <!-- LINE WIDTH -->
<Col <Col>
><Card class="h-100"> <Card class="h-100">
<form <form
id="line-width-form" id="line-width-form"
method="post" method="post"
@@ -75,12 +73,12 @@
</div> </div>
<Button color="primary" type="submit">Submit</Button> <Button color="primary" type="submit">Submit</Button>
</form> </form>
</Card></Col </Card>
> </Col>
<!-- PLOTS PER ROW --> <!-- PLOTS PER ROW -->
<Col <Col>
><Card class="h-100"> <Card class="h-100">
<form <form
id="plots-per-row-form" id="plots-per-row-form"
method="post" method="post"
@@ -96,13 +94,13 @@
style="margin-bottom: 1em; display: flex; align-items: center;" style="margin-bottom: 1em; display: flex; align-items: center;"
> >
<div>Plots per Row</div> <div>Plots per Row</div>
{#if displayMessage && message.target == "ppr"}<div {#if displayMessage && message.target == "ppr"}
style="margin-left: auto; font-size: 0.9em;" <div style="margin-left: auto; font-size: 0.9em;">
> <code style="color: {message.color};" out:fade>
<code style="color: {message.color};" out:fade Update: {message.msg}
>Update: {message.msg}</code </code>
> </div>
</div>{/if} {/if}
</CardTitle> </CardTitle>
<input type="hidden" name="key" value="plot_view_plotsPerRow" /> <input type="hidden" name="key" value="plot_view_plotsPerRow" />
<div class="mb-3"> <div class="mb-3">
@@ -123,12 +121,12 @@
</div> </div>
<Button color="primary" type="submit">Submit</Button> <Button color="primary" type="submit">Submit</Button>
</form> </form>
</Card></Col </Card>
> </Col>
<!-- BACKGROUND --> <!-- BACKGROUND -->
<Col class="d-flex justify-content-between" <Col class="d-flex justify-content-between">
><Card class="h-100" style="width: 49%;"> <Card class="h-100" style="width: 49%;">
<form <form
id="backgrounds-form" id="backgrounds-form"
method="post" method="post"
@@ -144,13 +142,13 @@
style="margin-bottom: 1em; display: flex; align-items: center;" style="margin-bottom: 1em; display: flex; align-items: center;"
> >
<div>Colored Backgrounds</div> <div>Colored Backgrounds</div>
{#if displayMessage && message.target == "bg"}<div {#if displayMessage && message.target == "bg"}
style="margin-left: auto; font-size: 0.9em;" <div style="margin-left: auto; font-size: 0.9em;">
> <code style="color: {message.color};" out:fade>
<code style="color: {message.color};" out:fade Update: {message.msg}
>Update: {message.msg}</code </code>
> </div>
</div>{/if} {/if}
</CardTitle> </CardTitle>
<input type="hidden" name="key" value="plot_general_colorBackground" /> <input type="hidden" name="key" value="plot_general_colorBackground" />
<div class="mb-3"> <div class="mb-3">
@@ -190,13 +188,13 @@
style="margin-bottom: 1em; display: flex; align-items: center;" style="margin-bottom: 1em; display: flex; align-items: center;"
> >
<div>Color Blind Mode</div> <div>Color Blind Mode</div>
{#if displayMessage && message.target == "cbm"}<div {#if displayMessage && message.target == "cbm"}
style="margin-left: auto; font-size: 0.9em;" <div style="margin-left: auto; font-size: 0.9em;">
> <code style="color: {message.color};" out:fade>
<code style="color: {message.color};" out:fade Update: {message.msg}
>Update: {message.msg}</code </code>
> </div>
</div>{/if} {/if}
</CardTitle> </CardTitle>
<input type="hidden" name="key" value="plot_general_colorblindMode" /> <input type="hidden" name="key" value="plot_general_colorblindMode" />
<div class="mb-3"> <div class="mb-3">
@@ -3,14 +3,12 @@
Properties: Properties:
- `config Object`: Current cc-config - `config Object`: Current cc-config
- `message Object`: Message to display on success or error - `message Object`: Message to display on success or error [Bindable]
- `displayMessage Bool`: If to display message content - `displayMessage Bool`: If to display message content [Bindable]
- `username String!`: Empty string if auth. is disabled, otherwise the username as string - `username String!`: Empty string if auth. is disabled, otherwise the username as string
- `isApi Bool!`: Is currently logged in user api authority - `isApi Bool!`: Is currently logged in user api authority
- `updateSetting Func`: The callback function to apply current option selection
Events: -->
- `update-config, {selector: String, target: String}`: Trigger upstream update of the config option
-->
<script> <script>
import { import {
+6 -7
View File
@@ -7,13 +7,14 @@
- `disableClusterSelection Bool?`: Is the selection disabled [Default: false] - `disableClusterSelection Bool?`: Is the selection disabled [Default: false]
- `startTimeQuickSelect Bool?`: Render startTime quick selections [Default: false] - `startTimeQuickSelect Bool?`: Render startTime quick selections [Default: false]
- `matchedJobs Number?`: Number of jobs matching the filter [Default: -2] - `matchedJobs Number?`: Number of jobs matching the filter [Default: -2]
- `showFilter Func`: If the filter component should be rendered in addition to total count info [Default: true]
Events: - `applyFilters Func`: The callback function to apply current filter selection
- `update-filters, {filters: [Object]?}`: The detail's 'filters' prop are new filter items to be applied
Functions: Functions:
- `void updateFilters (additionalFilters: Object?)`: Handles new filters from nested components, triggers upstream update event - `void updateFilters (additionalFilters: Object, force: Bool)`:
--> Handles new filters from nested components, triggers upstream update event.
'additionalFilters' usually added to existing selection, but can be forced to overwrite instead.
-->
<script> <script>
import { import {
@@ -510,8 +511,6 @@
setFilter={(filter) => updateFilters(filter)} setFilter={(filter) => updateFilters(filter)}
/> />
<style> <style>
:global(.cc-dropdown-on-hover:hover .dropdown-menu) { :global(.cc-dropdown-on-hover:hover .dropdown-menu) {
display: block; display: block;
+3 -2
View File
@@ -2,9 +2,9 @@
@component jobCompare component; compares jobs according to set filters or job selection @component jobCompare component; compares jobs according to set filters or job selection
Properties: Properties:
- `matchedCompareJobs Number?`: Number of matched jobs for selected filters [Default: 0] - `matchedCompareJobs Number?`: Number of matched jobs for selected filters [Bindable, Default: 0]
- `metrics [String]?`: The currently selected metrics [Default: User-Configured Selection] - `metrics [String]?`: The currently selected metrics [Default: User-Configured Selection]
- `showFootprint Bool`: If to display the jobFootprint component - `filterBuffer [Object]?`: Latest selected filters to keep for view switch to job list [Default: []]
Functions: Functions:
- `queryJobs(filters?: [JobFilter])`: Load jobs data with new filters, starts from page 1 - `queryJobs(filters?: [JobFilter])`: Load jobs data with new filters, starts from page 1
@@ -104,6 +104,7 @@
/* Effect */ /* Effect */
$effect(() => { $effect(() => {
// Update bound property
matchedCompareJobs = $compareData?.data != null ? $compareData.data.jobsMetricStats.length : -1; matchedCompareJobs = $compareData?.data != null ? $compareData.data.jobsMetricStats.length : -1;
}); });
+5 -3
View File
@@ -3,15 +3,17 @@
Properties: Properties:
- `sorting Object?`: Currently active sorting [Default: {field: "startTime", type: "col", order: "DESC"}] - `sorting Object?`: Currently active sorting [Default: {field: "startTime", type: "col", order: "DESC"}]
- `matchedListJobs Number?`: Number of matched jobs for selected filters [Default: 0] - `matchedListJobs Number?`: Number of matched jobs for selected filters [Bindable, Default: 0]
- `metrics [String]?`: The currently selected metrics [Default: User-Configured Selection] - `metrics [String]?`: The currently selected metrics [Default: User-Configured Selection]
- `showFootprint Bool`: If to display the jobFootprint component - `showFootprint Bool?`: If to display the jobFootprint component [Default: false]
- `selectedJobs [Number]?`: IDs of jobs selected for job comparison [Bindable, Default: []]
- `filterBuffer [Object]?`: Latest selected filters to keep for view switch to job compare [Default: []]
Functions: Functions:
- `refreshJobs()`: Load jobs data with unchanged parameters and 'network-only' keyword - `refreshJobs()`: Load jobs data with unchanged parameters and 'network-only' keyword
- `refreshAllMetrics()`: Trigger downstream refresh of all running jobs' metric data - `refreshAllMetrics()`: Trigger downstream refresh of all running jobs' metric data
- `queryJobs(filters?: [JobFilter])`: Load jobs data with new filters, starts from page 1 - `queryJobs(filters?: [JobFilter])`: Load jobs data with new filters, starts from page 1
--> -->
<script> <script>
import { getContext, untrack } from "svelte"; import { getContext, untrack } from "svelte";
+3 -2
View File
@@ -1,9 +1,10 @@
<!-- <!--
@component Organized display of plots as bootstrap (sveltestrap) grid @component Organized display of svelte 5 snippets as bootstrap (sveltestrap) grid
Properties: Properties:
- `items [Any]`: Array of information required for gridContent SV5 snippet
- `itemsPerRow Number`: Elements to render per row - `itemsPerRow Number`: Elements to render per row
- `items [Any]`: List of plot components to render - `gridContent Func`: Svelte 5 Snippet from Upstream; Defines what and how to render $item data
--> -->
<script> <script>
@@ -2,15 +2,12 @@
@component Filter sub-component for selecting cluster and subCluster @component Filter sub-component for selecting cluster and subCluster
Properties: Properties:
- `isOpen Bool?`: Is this filter component opened [Bindable, Default: false]
- `presetCluster String?`: The latest selected cluster [Default: ""]
- `presetPartition String?`: The latest selected partition [Default: ""]
- `disableClusterSelection Bool?`: Is the selection disabled [Default: false] - `disableClusterSelection Bool?`: Is the selection disabled [Default: false]
- `isModified Bool?`: Is this filter component modified [Default: false] - `setFilter Func`: The callback function to apply current filter selection
- `isOpen Bool?`: Is this filter component opened [Default: false] -->
- `cluster String?`: The currently selected cluster [Default: null]
- `partition String?`: The currently selected partition (i.e. subCluster) [Default: null]
Events:
- `set-filter, {String?, String?}`: Set 'cluster, subCluster' filter in upstream component
-->
<script> <script>
import { getContext } from "svelte"; import { getContext } from "svelte";
@@ -33,14 +30,13 @@
setFilter setFilter
} = $props(); } = $props();
/* Const Init */
const clusters = getContext("clusters");
const initialized = getContext("initialized");
/* State Init */ /* State Init */
let pendingCluster = $state(presetCluster); let pendingCluster = $state(presetCluster);
let pendingPartition = $state(presetPartition); let pendingPartition = $state(presetPartition);
/* Derived Vars */
const clusters = $derived(getContext("clusters"));
const initialized = $derived(getContext("initialized"));
</script> </script>
<Modal {isOpen} toggle={() => (isOpen = !isOpen)}> <Modal {isOpen} toggle={() => (isOpen = !isOpen)}>
@@ -2,15 +2,11 @@
@component Filter sub-component for selecting job duration @component Filter sub-component for selecting job duration
Properties: Properties:
- `isOpen Bool?`: Is this filter component opened [Default: false] - `isOpen Bool?`: Is this filter component opened [Bindable, Default: false]
- `lessThan Number?`: Amount of seconds [Default: null] - `presetDuration Object?`: Object containing the latest duration filter parameters
- `moreThan Number?`: Amount of seconds [Default: null] - Default: { lessThan: null, moreThan: null, from: null, to: null }
- `from Number?`: Epoch time in seconds [Default: null] - `setFilter Func`: The callback function to apply current filter selection
- `to Number?`: Epoch time in seconds [Default: null] -->
Events:
- `set-filter, {Number, Number, Number, Number}`: Set 'lessThan, moreThan, from, to' filter in upstream component
-->
<script> <script>
import { import {
@@ -26,7 +22,12 @@
/* Svelte 5 Props */ /* Svelte 5 Props */
let { let {
isOpen = $bindable(false), isOpen = $bindable(false),
presetDuration ={lessThan: null, moreThan: null, from: null, to: null}, presetDuration = {
lessThan: null,
moreThan: null,
from: null,
to: null
},
setFilter setFilter
} = $props(); } = $props();
@@ -2,12 +2,11 @@
@component Filter sub-component for selecting job energies @component Filter sub-component for selecting job energies
Properties: Properties:
- `isOpen Bool?`: Is this filter component opened [Default: false] - `isOpen Bool?`: Is this filter component opened [Bindable, efault: false]
- `energy Object?`: The currently selected total energy filter [Default: {from:null, to:null}] - `presetEnergy Object?`: Object containing the latest energy filter parameters
- Default: { from: null, to: null }
Events: - `setFilter Func`: The callback function to apply current filter selection
- `set-filter, {Object}`: Set 'energy' filter in upstream component -->
-->
<script> <script>
import { import {
@@ -22,13 +21,15 @@
/* Svelte 5 Props */ /* Svelte 5 Props */
let { let {
isOpen = $bindable(false), isOpen = $bindable(false),
presetEnergy= {from: null, to: null}, presetEnergy = {
from: null,
to: null
},
setFilter, setFilter,
} = $props(); } = $props();
/* State Init */ /* State Init */
let energyState = $state(presetEnergy); let energyState = $state(presetEnergy);
</script> </script>
<Modal {isOpen} toggle={() => (isOpen = !isOpen)}> <Modal {isOpen} toggle={() => (isOpen = !isOpen)}>
@@ -3,15 +3,21 @@
Properties: Properties:
- `icon String`: Sveltestrap icon name - `icon String`: Sveltestrap icon name
- `modified Bool?`: Optional if filter is modified [Default: false] - `modified Bool?`: Optional if filter is modified
- `onclick Fn()`: Opens Modal on click - `onclick Func`: Opens Modal on click
- `children Fn()?`: Internal prop, Svelte 5 version of <slot/> - `children Func`: Internal prop, Svelte 5 version of <slot/>
--> -->
<script> <script>
import { Button, Icon } from "@sveltestrap/sveltestrap"; import { Button, Icon } from "@sveltestrap/sveltestrap";
/* Svelte 5 Props */ /* Svelte 5 Props */
let { icon, modified, onclick, children } = $props(); let {
icon,
modified,
onclick,
children
} = $props();
</script> </script>
<Button class="mr-2 mb-1" outline color={modified ? "warning" : "primary"} {onclick}> <Button class="mr-2 mb-1" outline color={modified ? "warning" : "primary"} {onclick}>
@@ -2,16 +2,13 @@
@component Filter sub-component for selecting job states @component Filter sub-component for selecting job states
Properties: Properties:
- `isModified Bool?`: Is this filter component modified [Default: false] - `isOpen Bool?`: Is this filter component opened [Bindable, Default: false]
- `isOpen Bool?`: Is this filter component opened [Default: false] - `presetStates [String]?`: The latest selected filter state [Default: [...allJobStates]]
- `states [String]?`: The currently selected states [Default: [...allJobStates]] - `setFilter Func`: The callback function to apply current filter selection
Events:
- `set-filter, {[String]}`: Set 'states' filter in upstream component
Exported: Exported:
- `const allJobStates [String]`: List of all available job states used in cc-backend - `const allJobStates [String]`: List of all available job states used in cc-backend
--> -->
<script module> <script module>
export const allJobStates = [ export const allJobStates = [
@@ -2,16 +2,15 @@
@component Filter sub-component for selecting job resources @component Filter sub-component for selecting job resources
Properties: Properties:
- `isOpen Bool?`: Is this filter component opened [Default: false] - `isOpen Bool?`: Is this filter component opened [Bindable, Default: false]
- `activeCluster String?`: The currently selected cluster name [Default: null] - `activeCluster String?`: The currently selected cluster name [Default: null]
- `numNodes Object?`: The currently selected numNodes filter [Default: {from:null, to:null}] - `presetNumNodes Object?`: The currently selected numNodes filter [Default: {from:null, to:null}]
- `numHWThreads Object?`: The currently selected numHWThreads filter [Default: {from:null, to:null}] - `presetNumHWThreads Object?`: The currently selected numHWThreads filter [Default: {from:null, to:null}]
- `numAccelerators Object?`: The currently selected numAccelerators filter [Default: {from:null, to:null}] - `presetNumAccelerators Object?`: The currently selected numAccelerators filter [Default: {from:null, to:null}]
- `namedNode String?`: The currently selected single named node (= hostname) [Default: null] - `presetNamedNode String?`: The currently selected single named node (= hostname) [Default: null]
- `presetNodeMatch String?`: The currently selected single named node (= hostname) [Default: "eq"]
Events: - `setFilter Func`: The callback function to apply current filter selection
- `set-filter, {Object, Object, Object, String}`: Set 'numNodes, numHWThreads, numAccelerators, namedNode' filter in upstream component -->
-->
<script> <script>
import { getContext } from "svelte"; import { getContext } from "svelte";
@@ -2,15 +2,14 @@
@component Filter sub-component for selecting job starttime @component Filter sub-component for selecting job starttime
Properties: Properties:
- `isModified Bool?`: Is this filter component modified [Default: false] - `isOpen Bool?`: Is this filter component opened [Bindable, Default: false]
- `isOpen Bool?`: Is this filter component opened [Default: false] - `presetStartTime Object?`: Object containing the latest duration filter parameters
- `from Object?`: The currently selected from startime [Default: null] - Default: { from: null, to: null, range: "" }
- `to Object?`: The currently selected to starttime (i.e. subCluster) [Default: null] - `setFilter Func`: The callback function to apply current filter selection
- `range String?`: The currently selected starttime range as string [Default: ""]
Events: Exported:
- `set-filter, {String?, String?}`: Set 'from, to' filter in upstream component - `const startTimeSelectOptions [Object]`: List of available fixed startTimes used in cc-backend
--> -->
<script module> <script module>
export const startTimeSelectOptions = [ export const startTimeSelectOptions = [
@@ -24,7 +23,6 @@
<script> <script>
/* Note: Ignore VSCode reported 'A component can only have one instance-level <script> element' error */ /* Note: Ignore VSCode reported 'A component can only have one instance-level <script> element' error */
import { parse, format, sub } from "date-fns"; import { parse, format, sub } from "date-fns";
import { import {
Row, Row,
@@ -2,12 +2,10 @@
@component Filter sub-component for selecting job statistics @component Filter sub-component for selecting job statistics
Properties: Properties:
- `isOpen Bool?`: Is this filter component opened [Default: false] - `isOpen Bool?`: Is this filter component opened [Bindable, Default: false]
- `stats [Object]?`: The currently selected statistics filter [Default: []] - `presetStats [Object]?`: The latest selected statistics filter
- `setFilter Func`: The callback function to apply current filter selection
Events: -->
- `set-filter, {[Object]}`: Set 'stats' filter in upstream component
-->
<script> <script>
import { getStatsItems } from "../utils.js"; import { getStatsItems } from "../utils.js";
+4 -7
View File
@@ -2,13 +2,10 @@
@component Filter sub-component for selecting tags @component Filter sub-component for selecting tags
Properties: Properties:
- `isModified Bool?`: Is this filter component modified [Default: false] - `isOpen Bool?`: Is this filter component opened [Bindable, Default: false]
- `isOpen Bool?`: Is this filter component opened [Default: false] - `presetTags [Number]?`: The currently selected tags (as IDs) [Default: []]
- `tags [Number]?`: The currently selected tags (as IDs) [Default: []] - `setFilter Func`: The callback function to apply current filter selection
-->
Events:
- `set-filter, {[Number]}`: Set 'tag' filter in upstream component
-->
<script> <script>
import { getContext } from "svelte"; import { getContext } from "svelte";
@@ -4,10 +4,10 @@
Properties: Properties:
- `cJobs JobLinkResultList`: List of concurrent Jobs - `cJobs JobLinkResultList`: List of concurrent Jobs
- `showLinks Bool?`: Show list as clickable links [Default: false] - `showLinks Bool?`: Show list as clickable links [Default: false]
- `renderCard Bool?`: If to render component as content only or with card wrapping [Default: true] - `renderCard Bool?`: If to render component as content only or with card wrapping [Default: false]
- `width String?`: Width of the card [Default: 'auto'] - `width String?`: Width of the card [Default: 'auto']
- `height String?`: Height of the card [Default: '310px'] - `height String?`: Height of the card [Default: '400px']
--> -->
<script> <script>
import { import {
@@ -6,7 +6,7 @@
- `displayTitle Bool?`: If to display cardHeader with title [Default: true] - `displayTitle Bool?`: If to display cardHeader with title [Default: true]
- `width String?`: Width of the card [Default: 'auto'] - `width String?`: Width of the card [Default: 'auto']
- `height String?`: Height of the card [Default: '310px'] - `height String?`: Height of the card [Default: '310px']
--> -->
<script> <script>
import { getContext } from "svelte"; import { getContext } from "svelte";
@@ -3,10 +3,10 @@
Properties: Properties:
- `initially Number?`: Initial refresh interval on component mount, in seconds [Default: null] - `initially Number?`: Initial refresh interval on component mount, in seconds [Default: null]
- `presetClass String?`: Custom class to apply to main <InputGroup>
- `onRefresh Func`: The callback function to perform at refresh times
-->
Events:
- `refresh`: When fired, the upstream component refreshes its contents
-->
<script> <script>
import { Button, Icon, Input, InputGroup } from "@sveltestrap/sveltestrap"; import { Button, Icon, Input, InputGroup } from "@sveltestrap/sveltestrap";
+12 -12
View File
@@ -2,10 +2,10 @@
@component Single tag pill component @component Single tag pill component
Properties: Properties:
- id: ID! (if the tag-id is known but not the tag type/name, this can be used) - `id ID!`: (if the tag-id is known but not the tag type/name, this can be used)
- tag: { id: ID!, type: String, name: String } - `tag Object`: The tag Object
- clickable: Boolean (default is true) - `clickable Bool`: If tag should be click reactive [Default: true]
--> -->
<script> <script>
import { getContext } from 'svelte' import { getContext } from 'svelte'
@@ -45,6 +45,14 @@
} }
</script> </script>
<a target={clickable ? "_blank" : null} href={clickable ? `/monitoring/jobs/?tag=${id}` : null}>
{#if tag}
<span style="background-color:{getScopeColor(tag?.scope)};" class="my-1 badge text-dark">{tag.type}: {tag.name}</span>
{:else}
Loading...
{/if}
</a>
<style> <style>
a { a {
margin-right: 0.5rem; margin-right: 0.5rem;
@@ -53,11 +61,3 @@
font-size: 0.9rem; font-size: 0.9rem;
} }
</style> </style>
<a target={clickable ? "_blank" : null} href={clickable ? `/monitoring/jobs/?tag=${id}` : null}>
{#if tag}
<span style="background-color:{getScopeColor(tag?.scope)};" class="my-1 badge text-dark">{tag.type}: {tag.name}</span>
{:else}
Loading...
{/if}
</a>
@@ -2,13 +2,14 @@
@component Job Info Subcomponent; allows management of job tags by deletion or new entries @component Job Info Subcomponent; allows management of job tags by deletion or new entries
Properties: Properties:
- `jobTags [Number]`: The array of currently designated tags [Bindable]
- `job Object`: The job object - `job Object`: The job object
- `jobTags [Number]`: The array of currently designated tags
- `username String`: Empty string if auth. is disabled, otherwise the username as string - `username String`: Empty string if auth. is disabled, otherwise the username as string
- `authlevel Number`: The current users authentication level - `authlevel Number`: The current users authentication level
- `roles [Number]`: Enum containing available roles - `roles [Number]`: Enum containing available roles
- `renderModal Bool?`: If component is rendered as bootstrap modal button [Default: true] - `renderModal Bool?`: If component is rendered as bootstrap modal button [Default: true]
--> -->
<script> <script>
import { getContext } from "svelte"; import { getContext } from "svelte";
import { gql, getContextClient, mutationStore } from "@urql/svelte"; import { gql, getContextClient, mutationStore } from "@urql/svelte";
@@ -5,10 +5,8 @@
- `presetProject String?`: Currently active project filter [Default: ''] - `presetProject String?`: Currently active project filter [Default: '']
- `authlevel Number?`: The current users authentication level [Default: null] - `authlevel Number?`: The current users authentication level [Default: null]
- `roles [Number]?`: Enum containing available roles [Default: null] - `roles [Number]?`: Enum containing available roles [Default: null]
- `setFilter Func`: The callback function to apply current filter selection
Events: -->
- `set-filter, {String?, String?, String?}`: Set 'user, project, jobName' filter in upstream component
-->
<script> <script>
import { InputGroup, Input, Button, Icon } from "@sveltestrap/sveltestrap"; import { InputGroup, Input, Button, Icon } from "@sveltestrap/sveltestrap";
@@ -4,7 +4,13 @@
Properties: Properties:
- `job Object`: The Job Object (GraphQL.Job) - `job Object`: The Job Object (GraphQL.Job)
- `jobTags [Number]?`: The jobs tags as IDs, default useful for dynamically updating the tags [Default: job.tags] - `jobTags [Number]?`: The jobs tags as IDs, default useful for dynamically updating the tags [Default: job.tags]
--> - `showJobSelect Bool?`: Show job selection interface for job comparison [Default: false]
- `showTagEdit Bool?`: Show tag editing interface [Default: false]
- `username String?`: The current username
- `authlevel Number`: The current user authentication level
- `roles [String]`: Available roles
- `isSelected Bool`: Whether job is selected for comparison [Bindable, Default: false]
-->
<script> <script>
import { Badge, Button, Icon, Tooltip } from "@sveltestrap/sveltestrap"; import { Badge, Button, Icon, Tooltip } from "@sveltestrap/sveltestrap";
@@ -16,12 +22,12 @@
let { let {
job, job,
jobTags = job.tags, jobTags = job.tags,
showTagedit = false, showJobSelect = false,
showTagEdit = false,
username = null, username = null,
authlevel= null, authlevel = null,
roles = null, roles = null,
isSelected = $bindable(), isSelected = $bindable(false),
showSelect = false,
} = $props(); } = $props();
/* State Init */ /* State Init */
@@ -49,7 +55,6 @@
} }
function clipJobId(jid) { function clipJobId(jid) {
// Navigator clipboard api needs a secure context (https) // Navigator clipboard api needs a secure context (https)
if (navigator.clipboard && window.isSecureContext) { if (navigator.clipboard && window.isSecureContext) {
navigator.clipboard navigator.clipboard
@@ -82,7 +87,7 @@
({job.cluster}) ({job.cluster})
</span> </span>
<span> <span>
{#if showSelect} {#if showJobSelect}
<Button id={`${job.cluster}-${job.jobId}-select`} outline={!isSelected} color={isSelected? `success`: `secondary`} size="sm" class="mr-2" <Button id={`${job.cluster}-${job.jobId}-select`} outline={!isSelected} color={isSelected? `success`: `secondary`} size="sm" class="mr-2"
onclick={() => { onclick={() => {
isSelected = !isSelected isSelected = !isSelected
@@ -193,7 +198,7 @@
{/if} {/if}
</p> </p>
{#if showTagedit} {#if showTagEdit}
<hr class="mt-0 mb-2"/> <hr class="mt-0 mb-2"/>
<p class="mb-1"> <p class="mb-1">
<TagManagement bind:jobTags {job} {username} {authlevel} {roles} renderModal/> : <TagManagement bind:jobTags {job} {username} {authlevel} {roles} renderModal/> :
@@ -6,9 +6,12 @@
- `metrics [String]`: Currently selected metrics - `metrics [String]`: Currently selected metrics
- `plotWidth Number`: Width of the sub-components - `plotWidth Number`: Width of the sub-components
- `plotHeight Number?`: Height of the sub-components [Default: 275] - `plotHeight Number?`: Height of the sub-components [Default: 275]
- `showFootprint Bool`: Display of footprint component for job - `showFootprint Bool`: Display of footprint component for job [Default: false]
- `triggerMetricRefresh Bool?`: If changed to true from upstream, will trigger metric query - `previousSelect Bool`: The latest job select state for job comparison [Default: false]
--> - `triggerMetricRefresh Bool?`: If changed to true from upstream, will trigger metric query [Default: false]
- `selectJob Func`: The callback function to select a job for comparison
- `unselectJob Func`: The callback function to unselect a job from comparison
-->
<script> <script>
import { queryStore, gql, getContextClient } from "@urql/svelte"; import { queryStore, gql, getContextClient } from "@urql/svelte";
@@ -21,15 +24,15 @@
/* Svelte 5 Props */ /* Svelte 5 Props */
let { let {
triggerMetricRefresh = false,
job, job,
metrics, metrics,
plotWidth, plotWidth,
plotHeight = 275, plotHeight = 275,
showFootprint, showFootprint = false,
previousSelect = false, previousSelect = false,
triggerMetricRefresh = false,
selectJob, selectJob,
unselectJob unselectJob,
} = $props(); } = $props();
/* Const Init */ /* Const Init */
@@ -2,14 +2,13 @@
@component Pagination selection component @component Pagination selection component
Properties: Properties:
- page: Number (changes from inside) - `page Number?`: Current page [Default: 1]
- itemsPerPage: Number (changes from inside) - `itemsPerPage Number?`: Current items displayed per page [Default: 10]
- totalItems: Number (only displayed) - `totalItems Number?`: Total count of items [Default: 0]
- `itemText String?`: Name of paged items, e.g. "Jobs" [Default: "items"]
Events: - `pageSizes [Number!]?`: Options available for page sizes [Default: [10, 25, 50]]
- "update-paging": { page: Number, itemsPerPage: Number } - `updatePaging Func`: The callback function to apply current paging selection
- Dispatched once immediately and then each time page or itemsPerPage changes -->
-->
<script> <script>
/* Svelte 5 Props */ /* Svelte 5 Props */
@@ -18,7 +17,7 @@
itemsPerPage = 10, itemsPerPage = 10,
totalItems = 0, totalItems = 0,
itemText = "items", itemText = "items",
pageSizes = [10,25,50], pageSizes = [10, 25, 50],
updatePaging updatePaging
} = $props(); } = $props();
@@ -1,16 +1,22 @@
<!-- <!--
@component Main plot component, based on uPlot; metricdata values by time @component Job Data Compare Plot Component, based on uPlot; metricData values by jobId/startTime
Only width/height should change reactively. Only width/height should change reactively.
Properties: Properties:
- `metric String`: The metric name - `metric String?`: The metric name [Default: ""]
- `width Number?`: The plot width [Default: 0] - `width Number?`: The plot width [Default: 0]
- `height Number?`: The plot height [Default: 300] - `height Number?`: The plot height [Default: 300]
- `data [Array]`: The metric data object - `data [Array]`: The data object [Default: null]
- `cluster String`: Cluster name of the parent job / data - `title String?`: Plot title [Default: ""]
- `subCluster String`: Name of the subCluster of the parent job - `xlabel String?`: Plot X axis label [Default: ""]
--> - `ylabel String?`: Plot Y axis label [Default: ""]
- `yunit String?`: Plot Y axis unit [Default: ""]
- `xticks Array`: Array containing jobIDs [Default: []]
- `xinfo Array`: Array containing job information [Default: []]
- `forResources Bool?`: Render this plot for allocated jobResources [Default: false]
- `plot Sync Object!`: uPlot cursor synchronization key
-->
<script> <script>
import uPlot from "uplot"; import uPlot from "uplot";
@@ -1,17 +1,20 @@
<!-- <!--
@component Histogram Plot based on uPlot Bars @component Histogram Plot based on uPlot Bars
Only width/height should change reactively.
Properties: Properties:
- `data [[],[]]`: uPlot data structure array ( [[],[]] == [X, Y] ) - `data [[],[]]`: uPlot data structure array ( [[],[]] == [X, Y] )
- `usesBins Bool?`: If X-Axis labels are bins ("XX-YY") [Default: false] - `usesBins Bool?`: If X-Axis labels are bins ("XX-YY") [Default: false]
- `width Number?`: Plot width (reactively adaptive) [Default: 500] - `width Number?`: Plot width (reactively adaptive) [Default: null]
- `height Number?`: Plot height (reactively adaptive) [Default: 300] - `height Number?`: Plot height (reactively adaptive) [Default: 250]
- `title String?`: Plot title [Default: ""] - `title String?`: Plot title [Default: ""]
- `xlabel String?`: Plot X axis label [Default: ""] - `xlabel String?`: Plot X axis label [Default: ""]
- `xunit String?`: Plot X axis unit [Default: ""] - `xunit String?`: Plot X axis unit [Default: ""]
- `xtime Bool?`: If X-Axis is based on time information [Default: false]
- `ylabel String?`: Plot Y axis label [Default: ""] - `ylabel String?`: Plot Y axis label [Default: ""]
- `yunit String?`: Plot Y axis unit [Default: ""] - `yunit String?`: Plot Y axis unit [Default: ""]
--> -->
<script> <script>
import uPlot from "uplot"; import uPlot from "uplot";
@@ -11,14 +11,17 @@
- `series [GraphQL.Series]`: The metric data object - `series [GraphQL.Series]`: The metric data object
- `useStatsSeries Bool?`: If this plot uses the statistics Min/Max/Median representation; automatically set to according bool [Default: false] - `useStatsSeries Bool?`: If this plot uses the statistics Min/Max/Median representation; automatically set to according bool [Default: false]
- `statisticsSeries [GraphQL.StatisticsSeries]?`: Min/Max/Median representation of metric data [Default: null] - `statisticsSeries [GraphQL.StatisticsSeries]?`: Min/Max/Median representation of metric data [Default: null]
- `cluster String`: Cluster name of the parent job / data - `cluster String?`: Cluster name of the parent job / data [Default: ""]
- `subCluster String`: Name of the subCluster of the parent job - `subCluster String`: Name of the subCluster of the parent job
- `isShared Bool?`: If this job used shared resources; will adapt threshold indicators accordingly [Default: false] - `isShared Bool?`: If this job used shared resources; will adapt threshold indicators accordingly [Default: false]
- `forNode Bool?`: If this plot is used for node data display; will render x-axis as negative time with $now as maximum [Default: false] - `forNode Bool?`: If this plot is used for node data display; will render x-axis as negative time with $now as maximum [Default: false]
- `numhwthreads Number?`: Number of job HWThreads [Default: 0] - `numhwthreads Number?`: Number of job HWThreads [Default: 0]
- `numaccs Number?`: Number of job Accelerators [Default: 0] - `numaccs Number?`: Number of job Accelerators [Default: 0]
- `zoomState Object?`: The last zoom state to preserve on user zoom [Default: null] - `zoomState Object?`: The last zoom state to preserve on user zoom [Default: null]
--> - `thersholdState Object?`: The last threshold state to preserve on user zoom [Default: null]
- `extendedLegendData Object?`: Additional information to be rendered in an extended legend [Default: null]
- `onZoom Func`: Callback function to handle zoom-in event
-->
<script> <script>
import uPlot from "uplot"; import uPlot from "uplot";
+2 -1
View File
@@ -2,6 +2,7 @@
@component Pie Plot based on chart.js Pie @component Pie Plot based on chart.js Pie
Properties: Properties:
- `canvasId String?`: Unique ID for correct parallel chart.js rendering [Default: "pie-default"]
- `size Number`: X and Y size of the plot, for square shape - `size Number`: X and Y size of the plot, for square shape
- `sliceLabel String`: Label used in segment legends - `sliceLabel String`: Label used in segment legends
- `quantities [Number]`: Data values - `quantities [Number]`: Data values
@@ -10,7 +11,7 @@
Exported: Exported:
- `colors ['rgb(x,y,z)', ...]`: Color range used for segments; upstream used for legend - `colors ['rgb(x,y,z)', ...]`: Color range used for segments; upstream used for legend
--> -->
<script module> <script module>
// http://tsitsul.in/blog/coloropt/ : 12 colors normal // http://tsitsul.in/blog/coloropt/ : 12 colors normal
+2 -1
View File
@@ -4,8 +4,9 @@
Properties: Properties:
- `polarMetrics [Object]?`: Metric names and scaled peak values for rendering polar plot [Default: [] ] - `polarMetrics [Object]?`: Metric names and scaled peak values for rendering polar plot [Default: [] ]
- `polarData [GraphQL.JobMetricStatWithName]?`: Metric data [Default: null] - `polarData [GraphQL.JobMetricStatWithName]?`: Metric data [Default: null]
- `canvasId String?`: Unique ID for correct parallel chart.js rendering [Default: "polar-default"]
- `height Number?`: Plot height [Default: 365] - `height Number?`: Plot height [Default: 365]
--> -->
<script> <script>
import { onMount } from 'svelte' import { onMount } from 'svelte'
@@ -5,12 +5,13 @@
- `X [Number]`: Data from first selected metric as X-values - `X [Number]`: Data from first selected metric as X-values
- `Y [Number]`: Data from second selected metric as Y-values - `Y [Number]`: Data from second selected metric as Y-values
- `S GraphQl.TimeWeights.X?`: Float to scale the data with [Default: null] - `S GraphQl.TimeWeights.X?`: Float to scale the data with [Default: null]
- `color String`: Color of the drawn scatter circles - `color String?`: Color of the drawn scatter circles [Default: '#0066cc']
- `width Number`: - `width Number?`: Width of the plot [Default: 250]
- `height Number`: - `height Number?`: Height of the plot [Default: 300]
- `xLabel String`: - `xLabel String?`: X-Axis Label [Ðefault: ""]
- `yLabel String`: - `yLabel String?`: Y-Axis Label [Default: ""]
--> -->
<script> <script>
import { onMount } from 'svelte'; import { onMount } from 'svelte';
import { formatNumber } from '../units.js' import { formatNumber } from '../units.js'
@@ -23,8 +24,8 @@
color = '#0066cc', color = '#0066cc',
width = 250, width = 250,
height = 300, height = 300,
xLabel, xLabel = "",
yLabel, yLabel = "",
} = $props(); } = $props();
/* Const Init */ /* Const Init */
@@ -1,20 +1,19 @@
<!-- <!--
Copyright (c) 2021 Michael Keller Copyright (c) 2021 Michael Keller
Originally created by Michael Keller (https://github.com/mhkeller/svelte-double-range-slider) Originally created by Michael Keller (https://github.com/mhkeller/svelte-double-range-slider)
Changes: remove dependency, text inputs, configurable value ranges, on:change event Changes: remove dependency, text inputs, configurable value ranges, on:change event
Changes #2: Rewritten for Svelte 5, removed bodyHandler Changes #2: Rewritten for Svelte 5, removed bodyHandler
--> -->
<!-- <!--
@component Selector component to display range selections via min and max double-sliders @component Selector component to display range selections via min and max double-sliders
Properties: Properties:
- min: Number - `sliderMin Number!`: Minimum possible value for slider
- max: Number - `sliderMax Number!`: Maximum possible value for slider
- sliderHandleFrom: Number (Starting position of slider #1) - `fromPreset Number?`: Latest "from" value selection [Default: 1]
- sliderHandleTo: Number (Starting position of slider #2) - `toPreset Number?`: Latest "to" value selection [Default: 100]
- `changeRange Func`: The callback function to apply current range selections
Events:
- `change`: [Number, Number] (Positions of the two sliders)
--> -->
<script> <script>
@@ -154,7 +153,6 @@ Changes #2: Rewritten for Svelte 5, removed bodyHandler
} }
}; };
} }
</script> </script>
<div class="double-range-container"> <div class="double-range-container">
@@ -4,8 +4,9 @@
Properties: Properties:
- `cluster String`: Currently selected cluster - `cluster String`: Currently selected cluster
- `selectedHistograms [String]`: The currently selected metrics to display as histogram - `selectedHistograms [String]`: The currently selected metrics to display as histogram
- ìsOpen Bool`: Is selection opened - `ìsOpen Bool`: Is selection opened [Bindable]
--> - `applyChange Func`: The callback function to apply current selection
-->
<script> <script>
import { getContext } from "svelte"; import { getContext } from "svelte";
@@ -2,14 +2,17 @@
@component Metric selector component; allows reorder via drag and drop @component Metric selector component; allows reorder via drag and drop
Properties: Properties:
- `metrics [String]`: (changes from inside, needs to be initialised, list of selected metrics) - `isOpen Bool`: Is selection modal opened [Bindable, Default: false]
- `isOpen Bool`: (can change from inside and outside) - `showFootprint Bool?`: Upstream state of whether to render footprint card [Bindable, Default: false]
- `configName String`: The config key for the last saved selection (constant) - `totalMetrics Number?`: Total available metrics [Bindable, Default: 0]
- `allMetrics [String]?`: List of all available metrics [Default: null] - `presetMetrics [String]`: Latest selection of metrics [Default: []]
- `cluster String?`: The currently selected cluster [Default: null] - `cluster String?`: The currently selected cluster [Default: null]
- `showFootprint Bool?`: Upstream state of wether to render footpritn card [Default: false] - `subCluster String?`: The currently selected subCluster [Default: null]
- `footprintSelect Bool?`: Render checkbox for footprint display in upstream component [Default: false] - `footprintSelect Bool?`: Render checkbox for footprint display in upstream component [Default: false]
--> - `preInitialized Bool?`: If the parent component has a dedicated call to init() [Default: false]
- `configName String`: The config key for the last saved selection (constant)
- `applyMetrics Func`: The callback function to apply current selection
-->
<script> <script>
import { getContext } from "svelte"; import { getContext } from "svelte";
@@ -64,7 +67,7 @@
/* Reactive Effects */ /* Reactive Effects */
$effect(() => { $effect(() => {
totalMetrics = allMetrics.size; totalMetrics = allMetrics?.size || 0;
}); });
$effect(() => { $effect(() => {
@@ -2,9 +2,11 @@
@component Selector for sorting field and direction @component Selector for sorting field and direction
Properties: Properties:
- sorting: { field: String, order: "DESC" | "ASC" } (changes from inside) - `presetSorting Object?`: The latest sort selection state
- isOpen: Boolean (can change from inside and outside) - Default { field: "startTime", type: "col", order: "DESC" }
--> - `isOpen Bool?`: Is modal opened [Bindable, Default: false]
- `applySorting Func`: The callback function to apply current selection
-->
<script> <script>
import { getContext, onMount } from "svelte"; import { getContext, onMount } from "svelte";
@@ -2,14 +2,12 @@
@component Selector for specified real time ranges for data cutoff; used in systems and nodes view @component Selector for specified real time ranges for data cutoff; used in systems and nodes view
Properties: Properties:
- `from Date`: The datetime to start data display from - `presetFrom Date`: The latest "from" JS Date Object
- `to Date`: The datetime to end data display at - `presetTo Date`: The latest Date "to" JS Date Object
- `customEnabled Bool?`: Allow custom time window selection [Default: true] - `customEnabled Bool?`: Allow custom time window selection [Default: true]
- `options Object? {String:Number}`: The quick time selection options [Default: {..., "Last 24hrs": 24*60*60}] - `options Object? {String:Number}`: The quick time selection options [Default: {..., "Last 24hrs": 24*60*60}]
- `applyTime Func`: The callback function to apply current selection
Events: -->
- `change, {Date, Date}`: Set 'from, to' values in upstream component
-->
<script> <script>
import { import {
+1 -1
View File
@@ -6,7 +6,7 @@ const headerDomTarget = document.getElementById('svelte-header');
if (headerDomTarget != null) { if (headerDomTarget != null) {
mount(Header, { mount(Header, {
target: headerDomTarget, target: headerDomTarget,
props: { // { ...header }, props: {
username: hUsername, username: hUsername,
authlevel: hAuthlevel, authlevel: hAuthlevel,
clusters: hClusters, clusters: hClusters,
+1 -1
View File
@@ -6,7 +6,7 @@
- `subClusters map[String][]string`: Map of subclusters by cluster names - `subClusters map[String][]string`: Map of subclusters by cluster names
- `links [Object]`: Pre-filtered link objects based on user auth - `links [Object]`: Pre-filtered link objects based on user auth
- `direction String?`: The direcion of the drop-down menue [default: down] - `direction String?`: The direcion of the drop-down menue [default: down]
--> -->
<script> <script>
import { import {
+1 -1
View File
@@ -6,7 +6,7 @@
- `authlevel Number`: The current users authentication level - `authlevel Number`: The current users authentication level
- `roles [Number]`: Enum containing available roles - `roles [Number]`: Enum containing available roles
- `screenSize Number`: The current window size, will trigger different render variants - `screenSize Number`: The current window size, will trigger different render variants
--> -->
<script> <script>
import { import {
+1 -1
View File
@@ -5,7 +5,7 @@
- `jobId Number`: The job id - `jobId Number`: The job id
- `jobEnergy Number?`: The total job energy [Default: null] - `jobEnergy Number?`: The total job energy [Default: null]
- `jobEnergyFootprint [Object]?`: The partial job energy contributions [Default: null] - `jobEnergyFootprint [Object]?`: The partial job energy contributions [Default: null]
--> -->
<script> <script>
import { import {
+1 -1
View File
@@ -4,7 +4,7 @@
Properties: Properties:
- `job Object`: The GQL job object - `job Object`: The GQL job object
- `clusters Array`: The GQL clusters array - `clusters Array`: The GQL clusters array
--> -->
<script> <script>
import { import {
+3 -3
View File
@@ -4,8 +4,8 @@
Properties: Properties:
- `job Object`: The GQL job object - `job Object`: The GQL job object
- `width String?`: Width of the card [Default: 'auto'] - `width String?`: Width of the card [Default: 'auto']
- `height String?`: Height of the card [Default: '310px'] - `height String?`: Height of the card [Default: '400px']
--> -->
<script> <script>
import { getContext } from "svelte"; import { getContext } from "svelte";
@@ -17,7 +17,6 @@
import JobFootprintBars from "./jobsummary/JobFootprintBars.svelte"; import JobFootprintBars from "./jobsummary/JobFootprintBars.svelte";
import JobFootprintPolar from "./jobsummary/JobFootprintPolar.svelte"; import JobFootprintPolar from "./jobsummary/JobFootprintPolar.svelte";
/* Svelte 5 Props */ /* Svelte 5 Props */
let { let {
job, job,
@@ -25,6 +24,7 @@
height = "400px", height = "400px",
} = $props(); } = $props();
/* Const Init */
const showFootprintTab = !!getContext("cc-config")[`job_view_showFootprint`]; const showFootprintTab = !!getContext("cc-config")[`job_view_showFootprint`];
</script> </script>
+2 -3
View File
@@ -6,10 +6,9 @@
- `metricName String`: The metrics name - `metricName String`: The metrics name
- `metricUnit Object`: The metrics GQL unit object - `metricUnit Object`: The metrics GQL unit object
- `nativeScope String`: The metrics native scope - `nativeScope String`: The metrics native scope
- `scopes [String]`: The scopes returned for this metric - `presetScopes [String]`: The preset scopes returned for this metric
- `rawData [Object]`: Metric data for all scopes returned for this metric
- `isShared Bool?`: If this job used shared resources; will adapt threshold indicators accordingly in downstream plots [Default: false] - `isShared Bool?`: If this job used shared resources; will adapt threshold indicators accordingly in downstream plots [Default: false]
--> -->
<script> <script>
import { import {
+1 -1
View File
@@ -5,7 +5,7 @@
- `job Object`: The job object - `job Object`: The job object
- `clusters Object`: The clusters object - `clusters Object`: The clusters object
- `tabActive bool`: Boolean if StatsTabe Tab is Active on Creation - `tabActive bool`: Boolean if StatsTabe Tab is Active on Creation
--> -->
<script> <script>
import { import {
@@ -3,9 +3,9 @@
Properties: Properties:
- `job Object`: The GQL job object - `job Object`: The GQL job object
--> -->
<script> <script>
import { getContext } from "svelte"; import { getContext } from "svelte";
import { import {
CardBody, CardBody,
@@ -18,7 +18,9 @@
import { findJobFootprintThresholds } from "../../generic/utils.js"; import { findJobFootprintThresholds } from "../../generic/utils.js";
/* Svelte 5 Props */ /* Svelte 5 Props */
let {job} = $props(); let {
job
} = $props();
/* Derived */ /* Derived */
// Prepare Job Footprint Data Based On Values Saved In Database // Prepare Job Footprint Data Based On Values Saved In Database
@@ -167,8 +169,7 @@
<Tooltip <Tooltip
target={`footprint-${job.jobId}-${index}`} target={`footprint-${job.jobId}-${index}`}
placement="right" placement="right"
>{fpd.message}</Tooltip >{fpd.message}</Tooltip>
>
</div> </div>
<Row cols={12} class={(jobFootprintData.length == (index + 1)) ? 'mb-0' : 'mb-2'}> <Row cols={12} class={(jobFootprintData.length == (index + 1)) ? 'mb-0' : 'mb-2'}>
{#if fpd.dir} {#if fpd.dir}
@@ -205,8 +206,7 @@
<Tooltip <Tooltip
target={`footprint-${job.jobId}-${index}`} target={`footprint-${job.jobId}-${index}`}
placement="right" placement="right"
>{fpd.message}</Tooltip >{fpd.message}</Tooltip>
>
{/if} {/if}
{/each} {/each}
{/if} {/if}
@@ -3,9 +3,9 @@
Properties: Properties:
- `job Object`: The GQL job object - `job Object`: The GQL job object
--> -->
<script> <script>
import { getContext } from "svelte"; import { getContext } from "svelte";
import { import {
queryStore, queryStore,
@@ -21,7 +21,9 @@
import Polar from "../../generic/plots/Polar.svelte"; import Polar from "../../generic/plots/Polar.svelte";
/* Svelte 5 Props */ /* Svelte 5 Props */
let { job } = $props(); let {
job
} = $props();
/* Const Init */ /* Const Init */
// Metric Names Configured To Be Footprints For (sub)Cluster // Metric Names Configured To Be Footprints For (sub)Cluster
@@ -5,7 +5,7 @@
- `hosts [String]`: The list of hostnames of this job - `hosts [String]`: The list of hostnames of this job
- `jobStats Object`: The data object - `jobStats Object`: The data object
- `selectedMetrics [String]`: The selected metrics - `selectedMetrics [String]`: The selected metrics
--> -->
<script> <script>
import { import {
@@ -123,7 +123,6 @@
return s.dir != "up" ? s1[stat] - s2[stat] : s2[stat] - s1[stat]; return s.dir != "up" ? s1[stat] - s2[stat] : s2[stat] - s1[stat];
}); });
} }
</script> </script>
<Table class="mb-0"> <Table class="mb-0">
@@ -4,7 +4,7 @@
Properties: Properties:
- `data [Object]`: The jobs statsdata for host-metric-scope - `data [Object]`: The jobs statsdata for host-metric-scope
- `scope String`: The selected scope - `scope String`: The selected scope
--> -->
<script> <script>
import { Icon } from "@sveltestrap/sveltestrap"; import { Icon } from "@sveltestrap/sveltestrap";
+8 -4
View File
@@ -3,11 +3,15 @@
Properties: Properties:
- `cluster String`: The nodes' cluster - `cluster String`: The nodes' cluster
- `subCluster String`: The nodes' subCluster - `subCluster String`: The nodes' subCluster [Default: ""]
- `ccconfig Object?`: The ClusterCockpit Config Context [Default: null] - `ccconfig Object?`: The ClusterCockpit Config Context [Default: null]
- `selectedMetrics [String]`: The array of selected metrics - `selectedMetrics [String]`: The array of selected metrics [Default []]
- `systemUnits Object`: The object of metric units - `selectedResolution Number?`: The selected data resolution [Default: 0]
--> - `hostnameFilter String?`: The active hostnamefilter [Default: ""]
- `presetSystemUnits Object`: The object of metric units [Default: null]
- `from Date?`: The selected "from" date [Default: null]
- `to Date?`: The selected "to" date [Default: null]
-->
<script> <script>
import { queryStore, gql, getContextClient, mutationStore } from "@urql/svelte"; import { queryStore, gql, getContextClient, mutationStore } from "@urql/svelte";
+4 -1
View File
@@ -5,7 +5,10 @@
- `ccconfig Object?`: The ClusterCockpit Config Context [Default: null] - `ccconfig Object?`: The ClusterCockpit Config Context [Default: null]
- `cluster String`: The cluster to show status information for - `cluster String`: The cluster to show status information for
- `selectedMetric String?`: The selectedMetric input [Default: ""] - `selectedMetric String?`: The selectedMetric input [Default: ""]
--> - `hostnameFilter String?`: The active hostnamefilter [Default: ""]
- `from Date?`: The selected "from" date [Default: null]
- `to Date?`: The selected "to" date [Default: null]
-->
<script> <script>
import { queryStore, gql, getContextClient } from "@urql/svelte"; import { queryStore, gql, getContextClient } from "@urql/svelte";
@@ -4,8 +4,10 @@
Properties: Properties:
- `cluster String`: The nodes' cluster - `cluster String`: The nodes' cluster
- `subCluster String`: The nodes' subCluster - `subCluster String`: The nodes' subCluster
- `cluster String`: The nodes' hostname - `hostname String`: The nodes' hostname
--> - `dataHealth [Bool]`: Array of Booleans depicting state of returned data per metric
- `nodeJobsData [Object]`: Data returned by GQL for jobs runninig on this node [Default: null]
-->
<script> <script>
import { import {
@@ -5,7 +5,7 @@
- `cluster String`: The nodes' cluster - `cluster String`: The nodes' cluster
- `nodeData Object`: The node data object including metric data - `nodeData Object`: The node data object including metric data
- `selectedMetrics [String]`: The array of selected metrics - `selectedMetrics [String]`: The array of selected metrics
--> -->
<script> <script>
import { import {