mirror of
https://github.com/ClusterCockpit/cc-backend
synced 2025-11-26 03:23:07 +01:00
migrate system view, node list and node overview
This commit is contained in:
@@ -10,101 +10,99 @@
|
||||
<script>
|
||||
import { queryStore, gql, getContextClient } from "@urql/svelte";
|
||||
import { Row, Col, Card, Spinner } from "@sveltestrap/sveltestrap";
|
||||
import { init, checkMetricsDisabled } from "../generic/utils.js";
|
||||
import { checkMetricDisabled } from "../generic/utils.js";
|
||||
import MetricPlot from "../generic/plots/MetricPlot.svelte";
|
||||
|
||||
export let ccconfig = null;
|
||||
export let cluster = "";
|
||||
export const subCluster = "";
|
||||
export let selectedMetrics = null;
|
||||
export let hostnameFilter = "";
|
||||
export let from = null;
|
||||
export let to = null;
|
||||
/* Svelte 5 Props */
|
||||
let {
|
||||
ccconfig = null,
|
||||
cluster = "",
|
||||
selectedMetric = "",
|
||||
hostnameFilter = "",
|
||||
from = null,
|
||||
to = null
|
||||
} = $props();
|
||||
|
||||
const { query: initq } = init();
|
||||
/* Const Init */
|
||||
const client = getContextClient();
|
||||
const nodeQuery = gql`
|
||||
query ($cluster: String!, $metrics: [String!], $from: Time!, $to: Time!) {
|
||||
nodeMetrics(
|
||||
cluster: $cluster
|
||||
metrics: $metrics
|
||||
from: $from
|
||||
to: $to
|
||||
) {
|
||||
host
|
||||
subCluster
|
||||
metrics {
|
||||
name
|
||||
scope
|
||||
metric {
|
||||
timestep
|
||||
unit {
|
||||
base
|
||||
prefix
|
||||
}
|
||||
series {
|
||||
statistics {
|
||||
min
|
||||
avg
|
||||
max
|
||||
|
||||
/* Derived */
|
||||
const nodesQuery = $derived(queryStore({
|
||||
client: client,
|
||||
query: gql`
|
||||
query ($cluster: String!, $metrics: [String!], $from: Time!, $to: Time!) {
|
||||
nodeMetrics(
|
||||
cluster: $cluster
|
||||
metrics: $metrics
|
||||
from: $from
|
||||
to: $to
|
||||
) {
|
||||
host
|
||||
subCluster
|
||||
metrics {
|
||||
name
|
||||
scope
|
||||
metric {
|
||||
timestep
|
||||
unit {
|
||||
base
|
||||
prefix
|
||||
}
|
||||
series {
|
||||
statistics {
|
||||
min
|
||||
avg
|
||||
max
|
||||
}
|
||||
data
|
||||
}
|
||||
data
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
$: selectedMetric = selectedMetrics[0] ? selectedMetrics[0] : "";
|
||||
|
||||
$: nodesQuery = queryStore({
|
||||
client: client,
|
||||
query: nodeQuery,
|
||||
`,
|
||||
variables: {
|
||||
cluster: cluster,
|
||||
metrics: selectedMetrics,
|
||||
from: from.toISOString(),
|
||||
to: to.toISOString(),
|
||||
metrics: [selectedMetric],
|
||||
from: from,
|
||||
to: to,
|
||||
},
|
||||
});
|
||||
}));
|
||||
|
||||
let rawData = []
|
||||
$: if ($initq.data && $nodesQuery?.data) {
|
||||
rawData = $nodesQuery?.data?.nodeMetrics.filter((h) => {
|
||||
if (h.subCluster === '') { // Exclude nodes with empty subCluster field
|
||||
console.warn('subCluster not configured for node', h.host)
|
||||
return false
|
||||
} else {
|
||||
return h.metrics.some(
|
||||
(m) => selectedMetrics.includes(m.name) && m.scope == "node",
|
||||
)
|
||||
}
|
||||
})
|
||||
}
|
||||
const mappedData = $derived(handleQueryData($nodesQuery?.data));
|
||||
const filteredData = $derived(mappedData.filter((h) => h.host.includes(hostnameFilter)));
|
||||
|
||||
let mappedData = []
|
||||
$: if (rawData?.length > 0) {
|
||||
mappedData = rawData.map((h) => ({
|
||||
host: h.host,
|
||||
subCluster: h.subCluster,
|
||||
data: h.metrics.filter(
|
||||
(m) => selectedMetrics.includes(m.name) && m.scope == "node",
|
||||
),
|
||||
disabled: checkMetricsDisabled(
|
||||
selectedMetrics,
|
||||
cluster,
|
||||
h.subCluster,
|
||||
),
|
||||
}))
|
||||
.sort((a, b) => a.host.localeCompare(b.host))
|
||||
}
|
||||
|
||||
let filteredData = []
|
||||
$: if (mappedData?.length > 0) {
|
||||
filteredData = mappedData.filter((h) =>
|
||||
h.host.includes(hostnameFilter)
|
||||
)
|
||||
/* Functions */
|
||||
function handleQueryData(queryData) {
|
||||
let rawData = []
|
||||
if (queryData) {
|
||||
rawData = queryData.nodeMetrics.filter((h) => {
|
||||
if (h.subCluster !== '') { // Exclude nodes with empty subCluster field
|
||||
return h.metrics.some(
|
||||
(m) => m?.name == selectedMetric && m.scope == "node",
|
||||
)
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
let pendingMapped = [];
|
||||
if (rawData.length > 0) {
|
||||
pendingMapped = rawData.map((h) => ({
|
||||
host: h.host,
|
||||
subCluster: h.subCluster,
|
||||
data: h.metrics.filter(
|
||||
(m) => m?.name == selectedMetric && m.scope == "node",
|
||||
),
|
||||
disabled: checkMetricDisabled(
|
||||
selectedMetric,
|
||||
cluster,
|
||||
h.subCluster,
|
||||
),
|
||||
}))
|
||||
.sort((a, b) => a.host.localeCompare(b.host))
|
||||
}
|
||||
|
||||
return pendingMapped;
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -132,22 +130,25 @@
|
||||
>{item.host} ({item.subCluster})</a
|
||||
>
|
||||
</h4>
|
||||
{#if item?.disabled[selectedMetric]}
|
||||
{#if item?.disabled}
|
||||
<Card body class="mx-3" color="info"
|
||||
>Metric disabled for subcluster <code
|
||||
>{selectedMetric}:{item.subCluster}</code
|
||||
></Card
|
||||
>
|
||||
{:else}
|
||||
<!-- "No Data"-Warning included in MetricPlot-Component -->
|
||||
<MetricPlot
|
||||
timestep={item.data[0].metric.timestep}
|
||||
series={item.data[0].metric.series}
|
||||
metric={item.data[0].name}
|
||||
{cluster}
|
||||
subCluster={item.subCluster}
|
||||
forNode
|
||||
/>
|
||||
<!-- "No Data"-Warning included in MetricPlot-Component -->
|
||||
<!-- #key: X-axis keeps last selected timerange otherwise -->
|
||||
{#key item.data[0].metric.series[0].data.length}
|
||||
<MetricPlot
|
||||
timestep={item.data[0].metric.timestep}
|
||||
series={item.data[0].metric.series}
|
||||
metric={item.data[0].name}
|
||||
{cluster}
|
||||
subCluster={item.subCluster}
|
||||
forNode
|
||||
/>
|
||||
{/key}
|
||||
{/if}
|
||||
</Col>
|
||||
{/each}
|
||||
|
||||
Reference in New Issue
Block a user