mirror of
https://github.com/ClusterCockpit/cc-backend
synced 2025-07-26 06:06:15 +02:00
migrate system view, node list and node overview
This commit is contained in:
@@ -28,72 +28,74 @@
|
||||
import TimeSelection from "./generic/select/TimeSelection.svelte";
|
||||
import Refresher from "./generic/helper/Refresher.svelte";
|
||||
|
||||
export let displayType;
|
||||
export let cluster = null;
|
||||
export let subCluster = null;
|
||||
export let from = null;
|
||||
export let to = null;
|
||||
|
||||
const { query: initq } = init();
|
||||
|
||||
console.assert(
|
||||
displayType == "OVERVIEW" || displayType == "LIST",
|
||||
"Invalid nodes displayType provided!",
|
||||
);
|
||||
|
||||
if (from == null || to == null) {
|
||||
to = new Date(Date.now());
|
||||
from = new Date(to.getTime());
|
||||
from.setHours(from.getHours() - 12);
|
||||
}
|
||||
|
||||
const initialized = getContext("initialized");
|
||||
const ccconfig = getContext("cc-config");
|
||||
const globalMetrics = getContext("globalMetrics");
|
||||
const displayNodeOverview = (displayType === 'OVERVIEW')
|
||||
|
||||
const resampleConfig = getContext("resampling") || null;
|
||||
const resampleResolutions = resampleConfig ? [...resampleConfig.resolutions] : [];
|
||||
const resampleDefault = resampleConfig ? Math.max(...resampleConfig.resolutions) : 0;
|
||||
let selectedResolution = resampleConfig ? resampleDefault : 0;
|
||||
|
||||
let hostnameFilter = "";
|
||||
let pendingHostnameFilter = "";
|
||||
let selectedMetric = ccconfig.system_view_selectedMetric || "";
|
||||
let selectedMetrics = (
|
||||
ccconfig[`node_list_selectedMetrics:${cluster}:${subCluster}`] ||
|
||||
ccconfig[`node_list_selectedMetrics:${cluster}`]
|
||||
) || [ccconfig.system_view_selectedMetric];
|
||||
let isMetricsSelectionOpen = false;
|
||||
|
||||
/*
|
||||
Note 1: "Sorting" as use-case ignored for now, probably default to alphanumerical on hostnames of cluster (handled in frontend at the moment)
|
||||
Note 2: Add Idle State Filter (== No allocated Jobs) [Frontend?] : Cannot be handled by CCMS, requires secondary job query and refiltering of visible nodes
|
||||
*/
|
||||
|
||||
let systemMetrics = [];
|
||||
let systemUnits = {};
|
||||
/* Scelte 5 Props */
|
||||
let {
|
||||
displayType,
|
||||
cluster = null,
|
||||
subCluster = null,
|
||||
fromPreset = null,
|
||||
toPreset = null,
|
||||
} = $props();
|
||||
|
||||
function loadMetrics(isInitialized) {
|
||||
if (!isInitialized) return
|
||||
systemMetrics = [...globalMetrics.filter((gm) => gm?.availability.find((av) => av.cluster == cluster))]
|
||||
for (let sm of systemMetrics) {
|
||||
systemUnits[sm.name] = (sm?.unit?.prefix ? sm.unit.prefix : "") + (sm?.unit?.base ? sm.unit.base : "")
|
||||
}
|
||||
if (!selectedMetric) selectedMetric = systemMetrics[0].name
|
||||
}
|
||||
/* Const Init */
|
||||
const { query: initq } = init();
|
||||
const displayNodeOverview = (displayType === 'OVERVIEW');
|
||||
const ccconfig = getContext("cc-config");
|
||||
const initialized = getContext("initialized");
|
||||
const globalMetrics = getContext("globalMetrics");
|
||||
const resampleConfig = getContext("resampling") || null;
|
||||
|
||||
$: loadMetrics($initialized)
|
||||
const resampleResolutions = resampleConfig ? [...resampleConfig.resolutions] : [];
|
||||
const resampleDefault = resampleConfig ? Math.max(...resampleConfig.resolutions) : 0;
|
||||
const nowDate = new Date(Date.now());
|
||||
|
||||
$: if (displayNodeOverview) {
|
||||
selectedMetrics = [selectedMetric]
|
||||
}
|
||||
/* State Init */
|
||||
let to = $state(toPreset || new Date(Date.now()));
|
||||
let from = $state(fromPreset || new Date(nowDate.setHours(nowDate.getHours() - 12)));
|
||||
let selectedResolution = $state(resampleConfig ? resampleDefault : 0);
|
||||
let hostnameFilter = $state("");
|
||||
let pendingHostnameFilter = $state("");
|
||||
let isMetricsSelectionOpen = $state(false);
|
||||
let selectedMetric = $state(ccconfig.system_view_selectedMetric || "");
|
||||
let selectedMetrics = $state((
|
||||
ccconfig[`node_list_selectedMetrics:${cluster}:${subCluster}`] ||
|
||||
ccconfig[`node_list_selectedMetrics:${cluster}`]
|
||||
) || [ccconfig.system_view_selectedMetric]);
|
||||
|
||||
$: { // Wait after input for some time to prevent too many requests
|
||||
setTimeout(function () {
|
||||
/* Derived States */
|
||||
const systemMetrics = $derived($initialized ? [...globalMetrics.filter((gm) => gm?.availability.find((av) => av.cluster == cluster))] : []);
|
||||
const presetSystemUnits = $derived(loadUnits(systemMetrics));
|
||||
|
||||
/* Effects */
|
||||
$effect(() => {
|
||||
// OnMount: Ping Var, without this, OVERVIEW metric select is empty (reason tbd)
|
||||
systemMetrics
|
||||
});
|
||||
|
||||
/* Functions */
|
||||
function loadUnits(systemMetrics) {
|
||||
let pendingUnits = {};
|
||||
if (systemMetrics.length > 0) {
|
||||
for (let sm of systemMetrics) {
|
||||
pendingUnits[sm.name] = (sm?.unit?.prefix ? sm.unit.prefix : "") + (sm?.unit?.base ? sm.unit.base : "")
|
||||
};
|
||||
};
|
||||
return {...pendingUnits};
|
||||
};
|
||||
|
||||
// Wait after input for some time to prevent too many requests
|
||||
let timeoutId = null;
|
||||
function updateHostnameFilter() {
|
||||
if (timeoutId != null) clearTimeout(timeoutId);
|
||||
timeoutId = setTimeout(function () {
|
||||
hostnameFilter = pendingHostnameFilter;
|
||||
}, 500);
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<!-- ROW1: Tools-->
|
||||
@@ -108,7 +110,7 @@
|
||||
<Button
|
||||
outline
|
||||
color="primary"
|
||||
on:click={() => (isMetricsSelectionOpen = true)}
|
||||
onclick={() => (isMetricsSelectionOpen = true)}
|
||||
>
|
||||
{selectedMetrics.length} selected
|
||||
</Button>
|
||||
@@ -139,6 +141,7 @@
|
||||
placeholder="Filter hostname ..."
|
||||
type="text"
|
||||
bind:value={pendingHostnameFilter}
|
||||
oninput={updateHostnameFilter}
|
||||
/>
|
||||
</InputGroup>
|
||||
</Col>
|
||||
@@ -153,26 +156,28 @@
|
||||
<InputGroupText><Icon name="graph-up" /></InputGroupText>
|
||||
<InputGroupText>Metric</InputGroupText>
|
||||
<Input type="select" bind:value={selectedMetric}>
|
||||
{#each systemMetrics as metric}
|
||||
{#each systemMetrics as metric (metric.name)}
|
||||
<option value={metric.name}
|
||||
>{metric.name} {systemUnits[metric.name] ? "("+systemUnits[metric.name]+")" : ""}</option
|
||||
>{metric.name} {presetSystemUnits[metric.name] ? "("+presetSystemUnits[metric.name]+")" : ""}</option
|
||||
>
|
||||
{:else}
|
||||
<option disabled>No available options</option>
|
||||
{/each}
|
||||
</Input>
|
||||
</InputGroup>
|
||||
</Col>
|
||||
{/if}
|
||||
<!-- Refresh Col-->
|
||||
<Col class="mt-2 mt-lg-0">
|
||||
<Refresher
|
||||
onRefresh={() => {
|
||||
const diff = Date.now() - to;
|
||||
from = new Date(from.getTime() + diff);
|
||||
to = new Date(to.getTime() + diff);
|
||||
}}
|
||||
/>
|
||||
</Col>
|
||||
{/if}
|
||||
<!-- Refresh Col-->
|
||||
<Col class="mt-2 mt-lg-0">
|
||||
<Refresher
|
||||
onRefresh={() => {
|
||||
const diff = Date.now() - to;
|
||||
from = new Date(from.getTime() + diff);
|
||||
to = new Date(to.getTime() + diff);
|
||||
}}
|
||||
/>
|
||||
</Col>
|
||||
</Row>
|
||||
|
||||
<!-- ROW2: Content-->
|
||||
@@ -185,20 +190,22 @@
|
||||
{:else}
|
||||
{#if displayNodeOverview}
|
||||
<!-- ROW2-1: Node Overview (Grid Included)-->
|
||||
<NodeOverview {cluster} {subCluster} {ccconfig} {selectedMetrics} {from} {to} {hostnameFilter}/>
|
||||
<NodeOverview {cluster} {ccconfig} {selectedMetric} {from} {to} {hostnameFilter}/>
|
||||
{:else}
|
||||
<!-- ROW2-2: Node List (Grid Included)-->
|
||||
<NodeList {cluster} {subCluster} {ccconfig} {selectedMetrics} {selectedResolution} {hostnameFilter} {from} {to} {systemUnits}/>
|
||||
<NodeList {cluster} {subCluster} {ccconfig} {selectedMetrics} {selectedResolution} {hostnameFilter} {from} {to} {presetSystemUnits}/>
|
||||
{/if}
|
||||
{/if}
|
||||
|
||||
<MetricSelection
|
||||
bind:isOpen={isMetricsSelectionOpen}
|
||||
presetMetrics={selectedMetrics}
|
||||
{cluster}
|
||||
{subCluster}
|
||||
configName="node_list_selectedMetrics"
|
||||
applyMetrics={(newMetrics) =>
|
||||
selectedMetrics = [...newMetrics]
|
||||
}
|
||||
/>
|
||||
{#if !displayNodeOverview}
|
||||
<MetricSelection
|
||||
bind:isOpen={isMetricsSelectionOpen}
|
||||
presetMetrics={selectedMetrics}
|
||||
{cluster}
|
||||
{subCluster}
|
||||
configName="node_list_selectedMetrics"
|
||||
applyMetrics={(newMetrics) =>
|
||||
selectedMetrics = [...newMetrics]
|
||||
}
|
||||
/>
|
||||
{/if}
|
||||
|
Reference in New Issue
Block a user