mirror of
https://github.com/ClusterCockpit/cc-backend
synced 2026-02-17 16:31:45 +01:00
Merge branch 'dev' of github.com:ClusterCockpit/cc-backend into dev
This commit is contained in:
@@ -305,7 +305,7 @@
|
|||||||
{#if $jobsStore.fetching || !$jobsStore.data}
|
{#if $jobsStore.fetching || !$jobsStore.data}
|
||||||
<tr>
|
<tr>
|
||||||
<td colspan={metrics.length + 1}>
|
<td colspan={metrics.length + 1}>
|
||||||
<div style="text-align:center;">
|
<div style="text-align:center; margin-top: 1rem;">
|
||||||
<Spinner secondary />
|
<Spinner secondary />
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
|
|||||||
@@ -104,7 +104,7 @@
|
|||||||
let itemsPerPage = $derived(usePaging ? (ccconfig?.nodeList_nodesPerPage || 10) : 10);
|
let itemsPerPage = $derived(usePaging ? (ccconfig?.nodeList_nodesPerPage || 10) : 10);
|
||||||
let paging = $derived({ itemsPerPage, page });
|
let paging = $derived({ itemsPerPage, page });
|
||||||
|
|
||||||
const nodesQuery = $derived(queryStore({
|
const nodesStore = $derived(queryStore({
|
||||||
client: client,
|
client: client,
|
||||||
query: nodeListQuery,
|
query: nodeListQuery,
|
||||||
variables: {
|
variables: {
|
||||||
@@ -122,7 +122,7 @@
|
|||||||
requestPolicy: "network-only", // Resolution queries are cached, but how to access them? For now: reload on every change
|
requestPolicy: "network-only", // Resolution queries are cached, but how to access them? For now: reload on every change
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const matchedNodes = $derived($nodesQuery?.data?.nodeMetricsList?.totalNodes || 0);
|
const matchedNodes = $derived($nodesStore?.data?.nodeMetricsList?.totalNodes || 0);
|
||||||
|
|
||||||
/* Effects */
|
/* Effects */
|
||||||
$effect(() => {
|
$effect(() => {
|
||||||
@@ -135,7 +135,7 @@
|
|||||||
} = document.documentElement;
|
} = document.documentElement;
|
||||||
|
|
||||||
// Add 100 px offset to trigger load earlier
|
// Add 100 px offset to trigger load earlier
|
||||||
if (scrollTop + clientHeight >= scrollHeight - 100 && $nodesQuery?.data?.nodeMetricsList?.hasNextPage) {
|
if (scrollTop + clientHeight >= scrollHeight - 100 && $nodesStore?.data?.nodeMetricsList?.hasNextPage) {
|
||||||
page += 1
|
page += 1
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
@@ -143,9 +143,9 @@
|
|||||||
});
|
});
|
||||||
|
|
||||||
$effect(() => {
|
$effect(() => {
|
||||||
if ($nodesQuery?.data) {
|
if ($nodesStore?.data) {
|
||||||
untrack(() => {
|
untrack(() => {
|
||||||
handleNodes($nodesQuery?.data?.nodeMetricsList?.items);
|
handleNodes($nodesStore?.data?.nodeMetricsList?.items);
|
||||||
});
|
});
|
||||||
selectedMetrics = [...pendingSelectedMetrics]; // Trigger Rerender in NodeListRow Only After Data is Fetched
|
selectedMetrics = [...pendingSelectedMetrics]; // Trigger Rerender in NodeListRow Only After Data is Fetched
|
||||||
};
|
};
|
||||||
@@ -228,7 +228,7 @@
|
|||||||
style="padding-top: {headerPaddingTop}px;"
|
style="padding-top: {headerPaddingTop}px;"
|
||||||
>
|
>
|
||||||
{cluster} Node Info
|
{cluster} Node Info
|
||||||
{#if $nodesQuery.fetching}
|
{#if $nodesStore.fetching}
|
||||||
<Spinner size="sm" style="margin-left:10px;" secondary />
|
<Spinner size="sm" style="margin-left:10px;" secondary />
|
||||||
{/if}
|
{/if}
|
||||||
</th>
|
</th>
|
||||||
@@ -245,22 +245,22 @@
|
|||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{#if $nodesQuery.error}
|
{#if $nodesStore.error}
|
||||||
<Row>
|
<Row>
|
||||||
<Col>
|
<Col>
|
||||||
<Card body color="danger">{$nodesQuery.error.message}</Card>
|
<Card body color="danger">{$nodesStore.error.message}</Card>
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
{:else}
|
{:else}
|
||||||
{#each nodes as nodeData (nodeData.host)}
|
{#each nodes as nodeData (nodeData.host)}
|
||||||
<NodeListRow {nodeData} {cluster} {selectedMetrics} {globalMetrics}/>
|
<NodeListRow {nodeData} {cluster} {selectedMetrics} {globalMetrics} nodeDataFetching={$nodesStore.fetching}/>
|
||||||
{:else}
|
{:else}
|
||||||
<tr>
|
<tr>
|
||||||
<td colspan={selectedMetrics.length + 1}> No nodes found </td>
|
<td colspan={selectedMetrics.length + 1}> No nodes found </td>
|
||||||
</tr>
|
</tr>
|
||||||
{/each}
|
{/each}
|
||||||
{/if}
|
{/if}
|
||||||
{#if $nodesQuery.fetching || !$nodesQuery.data}
|
{#if $nodesStore.fetching || !$nodesStore.data}
|
||||||
<tr>
|
<tr>
|
||||||
<td colspan={pendingSelectedMetrics.length + 1}>
|
<td colspan={pendingSelectedMetrics.length + 1}>
|
||||||
<div style="text-align:center;">
|
<div style="text-align:center;">
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
Properties:
|
Properties:
|
||||||
- `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
|
||||||
|
- `nodeDataFetching Bool`: Whether the metric query still runs
|
||||||
- `selectedMetrics [String]`: The array of selected metrics
|
- `selectedMetrics [String]`: The array of selected metrics
|
||||||
- `globalMetrics [Obj]`: Includes the backend supplied availabilities for cluster and subCluster
|
- `globalMetrics [Obj]`: Includes the backend supplied availabilities for cluster and subCluster
|
||||||
-->
|
-->
|
||||||
@@ -24,6 +25,7 @@
|
|||||||
let {
|
let {
|
||||||
cluster,
|
cluster,
|
||||||
nodeData,
|
nodeData,
|
||||||
|
nodeDataFetching,
|
||||||
selectedMetrics,
|
selectedMetrics,
|
||||||
globalMetrics
|
globalMetrics
|
||||||
} = $props();
|
} = $props();
|
||||||
@@ -72,7 +74,7 @@
|
|||||||
);
|
);
|
||||||
|
|
||||||
const extendedLegendData = $derived($nodeJobsData?.data ? buildExtendedLegend() : null);
|
const extendedLegendData = $derived($nodeJobsData?.data ? buildExtendedLegend() : null);
|
||||||
const refinedData = $derived(nodeData?.metrics ? sortAndSelectScope(selectedMetrics, nodeData.metrics) : []);
|
const refinedData = $derived(!nodeDataFetching ? sortAndSelectScope(selectedMetrics, nodeData.metrics) : []);
|
||||||
const dataHealth = $derived(refinedData.filter((rd) => rd.availability == "configured").map((enabled) => (enabled?.data?.metric?.series?.length > 0)));
|
const dataHealth = $derived(refinedData.filter((rd) => rd.availability == "configured").map((enabled) => (enabled?.data?.metric?.series?.length > 0)));
|
||||||
|
|
||||||
/* Functions */
|
/* Functions */
|
||||||
@@ -150,65 +152,73 @@
|
|||||||
hoststate={nodeData?.state? nodeData.state: 'notindb'}/>
|
hoststate={nodeData?.state? nodeData.state: 'notindb'}/>
|
||||||
{/if}
|
{/if}
|
||||||
</td>
|
</td>
|
||||||
{#each refinedData as metricData, i (metricData?.data?.name || i)}
|
{#if nodeDataFetching}
|
||||||
{#key metricData}
|
<td colspan={selectedMetrics.length}>
|
||||||
<td>
|
<div style="text-align:center; margin-top: 1rem;">
|
||||||
{#if metricData?.availability == "none"}
|
<Spinner secondary />
|
||||||
<Card body class="mx-2" color="light">
|
</div>
|
||||||
<p>No dataset(s) returned for <b>{selectedMetrics[i]}</b></p>
|
</td>
|
||||||
<p class="mb-1">Metric is not configured for cluster <b>{cluster}</b>.</p>
|
{:else}
|
||||||
</Card>
|
{#each refinedData as metricData, i (metricData?.data?.name || i)}
|
||||||
{:else if metricData?.availability == "disabled"}
|
{#key metricData}
|
||||||
<Card body class="mx-2" color="info">
|
<td>
|
||||||
<p>No dataset(s) returned for <b>{selectedMetrics[i]}</b></p>
|
{#if metricData?.availability == "none"}
|
||||||
<p class="mb-1">Metric has been disabled for subcluster <b>{nodeData.subCluster}</b>.</p>
|
<Card body class="mx-2" color="light">
|
||||||
</Card>
|
<p>No dataset(s) returned for <b>{selectedMetrics[i]}</b></p>
|
||||||
{:else if !metricData?.data}
|
<p class="mb-1">Metric is not configured for cluster <b>{cluster}</b>.</p>
|
||||||
<Card body class="mx-2" color="warning">
|
</Card>
|
||||||
<p>No dataset(s) returned for <b>{selectedMetrics[i]}</b></p>
|
{:else if metricData?.availability == "disabled"}
|
||||||
<p class="mb-1">Metric or host was not found in metric store for cluster <b>{cluster}</b>.</p>
|
<Card body class="mx-2" color="info">
|
||||||
</Card>
|
<p>No dataset(s) returned for <b>{selectedMetrics[i]}</b></p>
|
||||||
{:else if !!metricData.data?.metric.statisticsSeries}
|
<p class="mb-1">Metric has been disabled for subcluster <b>{nodeData.subCluster}</b>.</p>
|
||||||
<!-- "No Data"-Warning included in MetricPlot-Component -->
|
</Card>
|
||||||
<MetricPlot
|
{:else if !metricData?.data}
|
||||||
{cluster}
|
<Card body class="mx-2" color="warning">
|
||||||
subCluster={nodeData.subCluster}
|
<p>No dataset(s) returned for <b>{selectedMetrics[i]}</b></p>
|
||||||
metric={metricData.data.name}
|
<p class="mb-1">Metric or host was not found in metric store for cluster <b>{cluster}</b>.</p>
|
||||||
scope={metricData.data.scope}
|
</Card>
|
||||||
timestep={metricData.data.metric.timestep}
|
{:else if !!metricData.data?.metric.statisticsSeries}
|
||||||
series={metricData.data.metric.series}
|
<!-- "No Data"-Warning included in MetricPlot-Component -->
|
||||||
statisticsSeries={metricData.data?.metric.statisticsSeries}
|
<MetricPlot
|
||||||
useStatsSeries={!!metricData.data?.metric.statisticsSeries}
|
{cluster}
|
||||||
height={175}
|
subCluster={nodeData.subCluster}
|
||||||
{plotSync}
|
metric={metricData.data.name}
|
||||||
forNode
|
scope={metricData.data.scope}
|
||||||
/>
|
timestep={metricData.data.metric.timestep}
|
||||||
<div class="my-2"></div>
|
series={metricData.data.metric.series}
|
||||||
<MetricPlot
|
statisticsSeries={metricData.data?.metric.statisticsSeries}
|
||||||
{cluster}
|
useStatsSeries={!!metricData.data?.metric.statisticsSeries}
|
||||||
subCluster={nodeData.subCluster}
|
height={175}
|
||||||
metric={metricData.data.name}
|
{plotSync}
|
||||||
scope={metricData.data.scope}
|
forNode
|
||||||
timestep={metricData.data.metric.timestep}
|
/>
|
||||||
series={metricData.data.metric.series}
|
<div class="my-2"></div>
|
||||||
height={175}
|
<MetricPlot
|
||||||
{extendedLegendData}
|
{cluster}
|
||||||
{plotSync}
|
subCluster={nodeData.subCluster}
|
||||||
forNode
|
metric={metricData.data.name}
|
||||||
/>
|
scope={metricData.data.scope}
|
||||||
{:else}
|
timestep={metricData.data.metric.timestep}
|
||||||
<MetricPlot
|
series={metricData.data.metric.series}
|
||||||
{cluster}
|
height={175}
|
||||||
subCluster={nodeData.subCluster}
|
{extendedLegendData}
|
||||||
metric={metricData.data.name}
|
{plotSync}
|
||||||
scope={metricData.data.scope}
|
forNode
|
||||||
timestep={metricData.data.metric.timestep}
|
/>
|
||||||
series={metricData.data.metric.series}
|
{:else}
|
||||||
height={375}
|
<MetricPlot
|
||||||
forNode
|
{cluster}
|
||||||
/>
|
subCluster={nodeData.subCluster}
|
||||||
{/if}
|
metric={metricData.data.name}
|
||||||
</td>
|
scope={metricData.data.scope}
|
||||||
{/key}
|
timestep={metricData.data.metric.timestep}
|
||||||
{/each}
|
series={metricData.data.metric.series}
|
||||||
|
height={375}
|
||||||
|
forNode
|
||||||
|
/>
|
||||||
|
{/if}
|
||||||
|
</td>
|
||||||
|
{/key}
|
||||||
|
{/each}
|
||||||
|
{/if}
|
||||||
</tr>
|
</tr>
|
||||||
|
|||||||
Reference in New Issue
Block a user