mirror of
https://github.com/ClusterCockpit/cc-backend
synced 2025-10-23 05:45:06 +02:00
Migrate user list and analysis view
This commit is contained in:
@@ -42,71 +42,90 @@
|
||||
import TextFilter from "./generic/helper/TextFilter.svelte"
|
||||
import Refresher from "./generic/helper/Refresher.svelte";
|
||||
|
||||
/* Svelte 5 Props */
|
||||
let { user, filterPresets } = $props();
|
||||
|
||||
/* Const Init */
|
||||
const { query: initq } = init();
|
||||
|
||||
const ccconfig = getContext("cc-config");
|
||||
|
||||
export let user;
|
||||
export let filterPresets;
|
||||
|
||||
let filterComponent; // see why here: https://stackoverflow.com/questions/58287729/how-can-i-export-a-function-from-a-svelte-component-that-changes-a-value-in-the
|
||||
let jobList;
|
||||
let jobFilters = [];
|
||||
let matchedListJobs = 0;
|
||||
let sorting = { field: "startTime", type: "col", order: "DESC" },
|
||||
isSortingOpen = false;
|
||||
let metrics = ccconfig.plot_list_selectedMetrics,
|
||||
isMetricsSelectionOpen = false;
|
||||
let isHistogramSelectionOpen = false;
|
||||
let selectedCluster = filterPresets?.cluster ? filterPresets.cluster : null;
|
||||
let showFootprint = filterPresets.cluster
|
||||
? !!ccconfig[`plot_list_showFootprint:${filterPresets.cluster}`]
|
||||
: !!ccconfig.plot_list_showFootprint;
|
||||
|
||||
let numDurationBins = "1h";
|
||||
let numMetricBins = 10;
|
||||
let durationBinOptions = ["1m","10m","1h","6h","12h"];
|
||||
let metricBinOptions = [10, 20, 50, 100];
|
||||
|
||||
$: selectedHistograms = selectedCluster
|
||||
? ccconfig[`user_view_histogramMetrics:${selectedCluster}`] || ( ccconfig['user_view_histogramMetrics'] || [] )
|
||||
: ccconfig['user_view_histogramMetrics'] || [];
|
||||
|
||||
const client = getContextClient();
|
||||
$: stats = queryStore({
|
||||
client: client,
|
||||
query: gql`
|
||||
query ($jobFilters: [JobFilter!]!, $selectedHistograms: [String!], $numDurationBins: String, $numMetricBins: Int) {
|
||||
jobsStatistics(filter: $jobFilters, metrics: $selectedHistograms, numDurationBins: $numDurationBins , numMetricBins: $numMetricBins ) {
|
||||
totalJobs
|
||||
shortJobs
|
||||
totalWalltime
|
||||
totalCoreHours
|
||||
histDuration {
|
||||
count
|
||||
value
|
||||
}
|
||||
histNumNodes {
|
||||
count
|
||||
value
|
||||
}
|
||||
histMetrics {
|
||||
metric
|
||||
unit
|
||||
stat
|
||||
data {
|
||||
min
|
||||
max
|
||||
const durationBinOptions = ["1m","10m","1h","6h","12h"];
|
||||
const metricBinOptions = [10, 20, 50, 100];
|
||||
|
||||
/* State Init */
|
||||
// List & Control Vars
|
||||
let filterComponent = $state(); // see why here: https://stackoverflow.com/questions/58287729/how-can-i-export-a-function-from-a-svelte-component-that-changes-a-value-in-the
|
||||
let jobFilters = $state([]);
|
||||
let jobList = $state(null);
|
||||
let matchedListJobs = $state(0);
|
||||
let isSortingOpen = $state(false);
|
||||
let isMetricsSelectionOpen = $state(false);
|
||||
let sorting = $state({ field: "startTime", type: "col", order: "DESC" });
|
||||
let selectedCluster = $state(filterPresets?.cluster ? filterPresets.cluster : null);
|
||||
let metrics = $state(filterPresets.cluster
|
||||
? ccconfig[`plot_list_selectedMetrics:${filterPresets.cluster}`] ||
|
||||
ccconfig.plot_list_selectedMetrics
|
||||
: ccconfig.plot_list_selectedMetrics
|
||||
);
|
||||
let showFootprint = $state(filterPresets.cluster
|
||||
? !!ccconfig[`plot_list_showFootprint:${filterPresets.cluster}`]
|
||||
: !!ccconfig.plot_list_showFootprint
|
||||
);
|
||||
|
||||
// Histogram Vars
|
||||
let isHistogramSelectionOpen = $state(false);
|
||||
let numDurationBins = $state("1h");
|
||||
let numMetricBins = $state(10);
|
||||
|
||||
// Compare Vars (TODO)
|
||||
// let jobCompare = $state(null);
|
||||
// let showCompare = $state(false);
|
||||
// let selectedJobs = $state([]);
|
||||
// let filterBuffer = $state([]);
|
||||
// let matchedCompareJobs = $state(0);
|
||||
|
||||
/* Derived Vars */
|
||||
let selectedHistograms = $derived(selectedCluster
|
||||
? ccconfig[`user_view_histogramMetrics:${selectedCluster}`] || ( ccconfig['user_view_histogramMetrics'] || [] )
|
||||
: ccconfig['user_view_histogramMetrics'] || []);
|
||||
|
||||
let stats = $derived(
|
||||
queryStore({
|
||||
client: client,
|
||||
query: gql`
|
||||
query ($jobFilters: [JobFilter!]!, $selectedHistograms: [String!], $numDurationBins: String, $numMetricBins: Int) {
|
||||
jobsStatistics(filter: $jobFilters, metrics: $selectedHistograms, numDurationBins: $numDurationBins , numMetricBins: $numMetricBins ) {
|
||||
totalJobs
|
||||
shortJobs
|
||||
totalWalltime
|
||||
totalCoreHours
|
||||
histDuration {
|
||||
count
|
||||
bin
|
||||
value
|
||||
}
|
||||
histNumNodes {
|
||||
count
|
||||
value
|
||||
}
|
||||
histMetrics {
|
||||
metric
|
||||
unit
|
||||
stat
|
||||
data {
|
||||
min
|
||||
max
|
||||
count
|
||||
bin
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`,
|
||||
variables: { jobFilters, selectedHistograms, numDurationBins, numMetricBins },
|
||||
});
|
||||
`,
|
||||
variables: { jobFilters, selectedHistograms, numDurationBins, numMetricBins },
|
||||
})
|
||||
);
|
||||
|
||||
/* On Mount */
|
||||
onMount(() => filterComponent.updateFilters());
|
||||
</script>
|
||||
|
||||
@@ -129,13 +148,13 @@
|
||||
<Row cols={{ xs: 1, md: 2, lg: 6}} class="mb-3">
|
||||
<Col class="mb-2 mb-lg-0">
|
||||
<ButtonGroup class="w-100">
|
||||
<Button outline color="primary" on:click={() => (isSortingOpen = true)}>
|
||||
<Button outline color="primary" onclick={() => (isSortingOpen = true)}>
|
||||
<Icon name="sort-up" /> Sorting
|
||||
</Button>
|
||||
<Button
|
||||
outline
|
||||
color="primary"
|
||||
on:click={() => (isMetricsSelectionOpen = true)}
|
||||
onclick={() => (isMetricsSelectionOpen = true)}
|
||||
>
|
||||
<Icon name="graph-up" /> Metrics
|
||||
</Button>
|
||||
@@ -143,11 +162,11 @@
|
||||
</Col>
|
||||
<Col lg="4" class="mb-1 mb-lg-0">
|
||||
<Filters
|
||||
bind:this={filterComponent}
|
||||
{filterPresets}
|
||||
matchedJobs={matchedListJobs}
|
||||
startTimeQuickSelect={true}
|
||||
bind:this={filterComponent}
|
||||
on:update-filters={({ detail }) => {
|
||||
applyFilters={(detail) => {
|
||||
jobFilters = [...detail.filters, { user: { eq: user.username } }];
|
||||
selectedCluster = jobFilters[0]?.cluster
|
||||
? jobFilters[0].cluster.eq
|
||||
@@ -173,11 +192,11 @@
|
||||
</Col>
|
||||
<Col class="mb-2 mb-lg-0">
|
||||
<TextFilter
|
||||
on:set-filter={({ detail }) => filterComponent.updateFilters(detail)}
|
||||
setFilter={(filter) => filterComponent.updateFilters(filter)}
|
||||
/>
|
||||
</Col>
|
||||
<Col class="mb-1 mb-lg-0">
|
||||
<Refresher on:refresh={() => {
|
||||
<Refresher onRefresh={() => {
|
||||
jobList.refreshJobs()
|
||||
jobList.refreshAllMetrics()
|
||||
}} />
|
||||
@@ -269,7 +288,7 @@
|
||||
outline
|
||||
color="secondary"
|
||||
class="w-100"
|
||||
on:click={() => (isHistogramSelectionOpen = true)}
|
||||
onclick={() => (isHistogramSelectionOpen = true)}
|
||||
>
|
||||
<Icon name="bar-chart-line" /> Select Histograms
|
||||
</Button>
|
||||
|
Reference in New Issue
Block a user