mirror of
https://github.com/ClusterCockpit/cc-backend
synced 2025-06-08 00:23:48 +02:00
Migrate metricSelection
This commit is contained in:
parent
42c4926c47
commit
927e25c72c
@ -56,8 +56,8 @@
|
||||
selectedScopes = [],
|
||||
plots = {};
|
||||
|
||||
let availableMetrics = new Set(),
|
||||
missingMetrics = [],
|
||||
let totalMetrics = 0;
|
||||
let missingMetrics = [],
|
||||
missingHosts = [],
|
||||
somethingMissing = false;
|
||||
|
||||
@ -294,7 +294,7 @@
|
||||
{#if $initq?.data}
|
||||
<Col xs="auto">
|
||||
<Button outline on:click={() => (isMetricsSelectionOpen = true)} color="primary">
|
||||
Select Metrics (Selected {selectedMetrics.length} of {availableMetrics.size} available)
|
||||
Select Metrics (Selected {selectedMetrics.length} of {totalMetrics} available)
|
||||
</Button>
|
||||
</Col>
|
||||
{/if}
|
||||
@ -428,12 +428,16 @@
|
||||
|
||||
{#if $initq?.data}
|
||||
<MetricSelection
|
||||
bind:isOpen={isMetricsSelectionOpen}
|
||||
bind:totalMetrics
|
||||
presetMetrics={selectedMetrics}
|
||||
cluster={$initq.data.job.cluster}
|
||||
subCluster={$initq.data.job.subCluster}
|
||||
configName="job_view_selectedMetrics"
|
||||
bind:metrics={selectedMetrics}
|
||||
bind:isOpen={isMetricsSelectionOpen}
|
||||
bind:allMetrics={availableMetrics}
|
||||
preInitialized
|
||||
applyMetrics={(newMetrics) =>
|
||||
selectedMetrics = [...newMetrics]
|
||||
}
|
||||
/>
|
||||
{/if}
|
||||
|
||||
|
@ -197,10 +197,13 @@
|
||||
<Sorting bind:sorting bind:isOpen={isSortingOpen}/>
|
||||
|
||||
<MetricSelection
|
||||
bind:cluster={selectedCluster}
|
||||
configName="plot_list_selectedMetrics"
|
||||
bind:metrics
|
||||
bind:isOpen={isMetricsSelectionOpen}
|
||||
bind:showFootprint
|
||||
footprintSelect
|
||||
bind:isOpen={isMetricsSelectionOpen}
|
||||
bind:showFootprint
|
||||
presetMetrics={metrics}
|
||||
cluster={selectedCluster}
|
||||
configName="plot_list_selectedMetrics"
|
||||
footprintSelect
|
||||
applyMetrics={(newMetrics) =>
|
||||
metrics = [...newMetrics]
|
||||
}
|
||||
/>
|
||||
|
@ -193,12 +193,12 @@
|
||||
{/if}
|
||||
|
||||
<MetricSelection
|
||||
bind:isOpen={isMetricsSelectionOpen}
|
||||
presetMetrics={selectedMetrics}
|
||||
{cluster}
|
||||
{subCluster}
|
||||
configName="node_list_selectedMetrics"
|
||||
metrics={selectedMetrics}
|
||||
bind:isOpen={isMetricsSelectionOpen}
|
||||
on:update-metrics={({ detail }) => {
|
||||
selectedMetrics = [...detail]
|
||||
}}
|
||||
applyMetrics={(newMetrics) =>
|
||||
selectedMetrics = [...newMetrics]
|
||||
}
|
||||
/>
|
||||
|
@ -366,12 +366,15 @@
|
||||
<Sorting bind:sorting bind:isOpen={isSortingOpen} />
|
||||
|
||||
<MetricSelection
|
||||
bind:cluster={selectedCluster}
|
||||
configName="plot_list_selectedMetrics"
|
||||
bind:metrics
|
||||
bind:isOpen={isMetricsSelectionOpen}
|
||||
bind:showFootprint
|
||||
footprintSelect
|
||||
bind:isOpen={isMetricsSelectionOpen}
|
||||
bind:showFootprint
|
||||
presetMetrics={metrics}
|
||||
cluster={selectedCluster}
|
||||
configName="plot_list_selectedMetrics"
|
||||
applyMetrics={(newMetrics) =>
|
||||
metrics = [...newMetrics]
|
||||
}
|
||||
footprintSelect
|
||||
/>
|
||||
|
||||
<HistogramSelection
|
||||
|
@ -12,7 +12,7 @@
|
||||
-->
|
||||
|
||||
<script>
|
||||
import { getContext, createEventDispatcher } from "svelte";
|
||||
import { getContext } from "svelte";
|
||||
import {
|
||||
Modal,
|
||||
ModalBody,
|
||||
@ -23,57 +23,23 @@
|
||||
} from "@sveltestrap/sveltestrap";
|
||||
import { gql, getContextClient, mutationStore } from "@urql/svelte";
|
||||
|
||||
export let metrics;
|
||||
export let isOpen;
|
||||
export let configName;
|
||||
export let allMetrics = null;
|
||||
export let cluster = null;
|
||||
export let subCluster = null;
|
||||
export let showFootprint = false;
|
||||
export let footprintSelect = false;
|
||||
|
||||
const onInit = getContext("on-init")
|
||||
const globalMetrics = getContext("globalMetrics")
|
||||
const dispatch = createEventDispatcher();
|
||||
|
||||
let newMetricsOrder = [];
|
||||
let unorderedMetrics = [...metrics];
|
||||
let pendingShowFootprint = !!showFootprint;
|
||||
|
||||
onInit(() => {
|
||||
if (allMetrics == null) allMetrics = new Set();
|
||||
for (let metric of globalMetrics) allMetrics.add(metric.name);
|
||||
});
|
||||
|
||||
$: {
|
||||
if (allMetrics != null) {
|
||||
if (!cluster) {
|
||||
for (let metric of globalMetrics) allMetrics.add(metric.name);
|
||||
} else {
|
||||
allMetrics.clear();
|
||||
for (let gm of globalMetrics) {
|
||||
if (!subCluster) {
|
||||
if (gm.availability.find((av) => av.cluster === cluster)) allMetrics.add(gm.name);
|
||||
} else {
|
||||
if (gm.availability.find((av) => av.cluster === cluster && av.subClusters.includes(subCluster))) allMetrics.add(gm.name);
|
||||
}
|
||||
}
|
||||
}
|
||||
newMetricsOrder = [...allMetrics].filter((m) => !metrics.includes(m));
|
||||
newMetricsOrder.unshift(...metrics.filter((m) => allMetrics.has(m)));
|
||||
unorderedMetrics = unorderedMetrics.filter((m) => allMetrics.has(m));
|
||||
}
|
||||
}
|
||||
|
||||
function printAvailability(metric, cluster) {
|
||||
const avail = globalMetrics.find((gm) => gm.name === metric)?.availability
|
||||
if (!cluster) {
|
||||
return avail.map((av) => av.cluster).join(',')
|
||||
} else {
|
||||
return avail.find((av) => av.cluster === cluster).subClusters.join(',')
|
||||
}
|
||||
}
|
||||
/* Svelte 5 Props */
|
||||
let {
|
||||
isOpen = $bindable(false),
|
||||
showFootprint = $bindable(false),
|
||||
totalMetrics = $bindable(0),
|
||||
presetMetrics = [],
|
||||
cluster = null,
|
||||
subCluster = null,
|
||||
footprintSelect = false,
|
||||
preInitialized = false, // Job View is Pre-Init'd: $initialized "alone" store returns false
|
||||
configName,
|
||||
applyMetrics
|
||||
} = $props();
|
||||
|
||||
/* Const Init */
|
||||
const globalMetrics = getContext("globalMetrics");
|
||||
const initialized = getContext("initialized");
|
||||
const client = getContextClient();
|
||||
const updateConfigurationMutation = ({ name, value }) => {
|
||||
return mutationStore({
|
||||
@ -87,7 +53,51 @@
|
||||
});
|
||||
};
|
||||
|
||||
let columnHovering = null;
|
||||
/* State Init */
|
||||
let pendingMetrics = $state(presetMetrics);
|
||||
let pendingShowFootprint = $state(!!showFootprint);
|
||||
let listedMetrics = $state([]);
|
||||
let columnHovering = $state(null);
|
||||
|
||||
/* Derives States */
|
||||
const allMetrics = $derived(loadAvailable(preInitialized || $initialized));
|
||||
|
||||
/* Reactive Effects */
|
||||
$effect(() => {
|
||||
totalMetrics = allMetrics.size;
|
||||
});
|
||||
|
||||
$effect(() => {
|
||||
listedMetrics = [...presetMetrics, ...allMetrics.difference(new Set(presetMetrics))]; // List (preset) active metrics first, then list inactives
|
||||
});
|
||||
|
||||
/* Functions */
|
||||
function loadAvailable(init) {
|
||||
const availableMetrics = new Set();
|
||||
if (init) {
|
||||
for (let gm of globalMetrics) {
|
||||
if (!cluster) {
|
||||
availableMetrics.add(gm.name)
|
||||
} else {
|
||||
if (!subCluster) {
|
||||
if (gm.availability.find((av) => av.cluster === cluster)) availableMetrics.add(gm.name);
|
||||
} else {
|
||||
if (gm.availability.find((av) => av.cluster === cluster && av.subClusters.includes(subCluster))) availableMetrics.add(gm.name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return availableMetrics
|
||||
}
|
||||
|
||||
function printAvailability(metric, cluster) {
|
||||
const avail = globalMetrics.find((gm) => gm.name === metric)?.availability
|
||||
if (!cluster) {
|
||||
return avail.map((av) => av.cluster).join(',')
|
||||
} else {
|
||||
return avail.find((av) => av.cluster === cluster).subClusters.join(',')
|
||||
}
|
||||
}
|
||||
|
||||
function columnsDragStart(event, i) {
|
||||
event.dataTransfer.effectAllowed = "move";
|
||||
@ -99,20 +109,20 @@
|
||||
event.dataTransfer.dropEffect = "move";
|
||||
const start = Number.parseInt(event.dataTransfer.getData("text/plain"));
|
||||
|
||||
let pendingMetricsOrder = [...newMetricsOrder];
|
||||
let pendingMetricsOrder = [...listedMetrics];
|
||||
if (start < target) {
|
||||
pendingMetricsOrder.splice(target + 1, 0, newMetricsOrder[start]);
|
||||
pendingMetricsOrder.splice(target + 1, 0, listedMetrics[start]);
|
||||
pendingMetricsOrder.splice(start, 1);
|
||||
} else {
|
||||
pendingMetricsOrder.splice(target, 0, newMetricsOrder[start]);
|
||||
pendingMetricsOrder.splice(target, 0, listedMetrics[start]);
|
||||
pendingMetricsOrder.splice(start + 1, 1);
|
||||
}
|
||||
newMetricsOrder = [...pendingMetricsOrder];
|
||||
listedMetrics = [...pendingMetricsOrder];
|
||||
columnHovering = null;
|
||||
}
|
||||
|
||||
function closeAndApply() {
|
||||
metrics = newMetricsOrder.filter((m) => unorderedMetrics.includes(m));
|
||||
pendingMetrics = listedMetrics.filter((m) => pendingMetrics.includes(m));
|
||||
isOpen = false;
|
||||
|
||||
let configKey;
|
||||
@ -126,7 +136,7 @@
|
||||
|
||||
updateConfigurationMutation({
|
||||
name: configKey,
|
||||
value: JSON.stringify(metrics),
|
||||
value: JSON.stringify(pendingMetrics),
|
||||
}).subscribe((res) => {
|
||||
if (res.fetching === false && res.error) {
|
||||
throw res.error;
|
||||
@ -148,7 +158,7 @@
|
||||
});
|
||||
};
|
||||
|
||||
dispatch('update-metrics', metrics);
|
||||
applyMetrics(pendingMetrics);
|
||||
}
|
||||
</script>
|
||||
|
||||
@ -162,7 +172,7 @@
|
||||
</li>
|
||||
<hr />
|
||||
{/if}
|
||||
{#each newMetricsOrder as metric, index (metric)}
|
||||
{#each listedMetrics as metric, index (metric)}
|
||||
<li
|
||||
class="cc-config-column list-group-item"
|
||||
draggable={true}
|
||||
@ -180,17 +190,17 @@
|
||||
ondragenter={() => (columnHovering = index)}
|
||||
class:is-active={columnHovering === index}
|
||||
>
|
||||
{#if unorderedMetrics.includes(metric)}
|
||||
{#if pendingMetrics.includes(metric)}
|
||||
<input
|
||||
type="checkbox"
|
||||
bind:group={unorderedMetrics}
|
||||
bind:group={pendingMetrics}
|
||||
value={metric}
|
||||
checked
|
||||
/>
|
||||
{:else}
|
||||
<input
|
||||
type="checkbox"
|
||||
bind:group={unorderedMetrics}
|
||||
bind:group={pendingMetrics}
|
||||
value={metric}
|
||||
/>
|
||||
{/if}
|
||||
@ -203,8 +213,8 @@
|
||||
</ListGroup>
|
||||
</ModalBody>
|
||||
<ModalFooter>
|
||||
<Button color="primary" on:click={() => closeAndApply()}>Close & Apply</Button>
|
||||
<Button color="secondary" on:click={() => (isOpen = !isOpen)}>Cancel</Button>
|
||||
<Button color="primary" onclick={() => closeAndApply()}>Close & Apply</Button>
|
||||
<Button color="secondary" onclick={() => (isOpen = !isOpen)}>Cancel</Button>
|
||||
</ModalFooter>
|
||||
</Modal>
|
||||
|
||||
|
@ -33,7 +33,7 @@
|
||||
let loadScopes = false;
|
||||
let selectedScopes = [];
|
||||
let selectedMetrics = [];
|
||||
let availableMetrics = new Set(); // For Info Only, filled by MetricSelection Component
|
||||
let totalMetrics = 0; // For Info Only, filled by MetricSelection Component
|
||||
let isMetricSelectionOpen = false;
|
||||
|
||||
const client = getContextClient();
|
||||
@ -99,7 +99,7 @@
|
||||
<Row>
|
||||
<Col class="m-2">
|
||||
<Button outline on:click={() => (isMetricSelectionOpen = true)} class="px-2" color="primary" style="margin-right:0.5rem">
|
||||
Select Metrics (Selected {selectedMetrics.length} of {availableMetrics.size} available)
|
||||
Select Metrics (Selected {selectedMetrics.length} of {totalMetrics} available)
|
||||
</Button>
|
||||
{#if job.numNodes > 1}
|
||||
<Button class="px-2 ml-auto" color="success" outline on:click={() => (loadScopes = !loadScopes)} disabled={loadScopes}>
|
||||
@ -136,10 +136,13 @@
|
||||
</TabPane>
|
||||
|
||||
<MetricSelection
|
||||
bind:isOpen={isMetricSelectionOpen}
|
||||
bind:totalMetrics
|
||||
presetMetrics={selectedMetrics}
|
||||
cluster={job.cluster}
|
||||
subCluster={job.subCluster}
|
||||
configName="job_view_nodestats_selectedMetrics"
|
||||
bind:allMetrics={availableMetrics}
|
||||
bind:metrics={selectedMetrics}
|
||||
bind:isOpen={isMetricSelectionOpen}
|
||||
applyMetrics={(newMetrics) =>
|
||||
selectedMetrics = [...newMetrics]
|
||||
}
|
||||
/>
|
||||
|
@ -81,7 +81,7 @@
|
||||
<thead>
|
||||
<!-- Header Row 1: Selectors -->
|
||||
<tr>
|
||||
<th/>
|
||||
<th></th>
|
||||
{#each selectedMetrics as metric}
|
||||
<!-- To Match Row-2 Header Field Count-->
|
||||
<th colspan={selectedScopes[metric] == "node" ? 3 : 4}>
|
||||
|
Loading…
x
Reference in New Issue
Block a user