mirror of
https://github.com/ClusterCockpit/cc-backend
synced 2025-10-02 20:54:32 +02:00
add manual job selection for comparison in jobs view
This commit is contained in:
@@ -78,6 +78,7 @@
|
||||
from: null,
|
||||
to: null,
|
||||
},
|
||||
dbId: filterPresets.dbId || [],
|
||||
jobId: filterPresets.jobId || "",
|
||||
arrayJobId: filterPresets.arrayJobId || null,
|
||||
user: filterPresets.user || "",
|
||||
@@ -137,6 +138,8 @@
|
||||
items.push({
|
||||
energy: { from: filters.energy.from, to: filters.energy.to },
|
||||
});
|
||||
if (filters.dbId.length != 0)
|
||||
items.push({ dbId: filters.dbId });
|
||||
if (filters.jobId)
|
||||
items.push({ jobId: { [filters.jobIdMatch]: filters.jobId } });
|
||||
if (filters.arrayJobId != null)
|
||||
@@ -180,7 +183,6 @@
|
||||
|
||||
function changeURL() {
|
||||
const dateToUnixEpoch = (rfc3339) => Math.floor(Date.parse(rfc3339) / 1000);
|
||||
|
||||
let opts = [];
|
||||
if (filters.cluster) opts.push(`cluster=${filters.cluster}`);
|
||||
if (filters.node) opts.push(`node=${filters.node}`);
|
||||
@@ -196,6 +198,11 @@
|
||||
if (filters.startTime.range) {
|
||||
opts.push(`startTime=${filters.startTime.range}`)
|
||||
}
|
||||
if (filters.dbId.length != 0) {
|
||||
for (let dbi of filters.dbId) {
|
||||
opts.push(`dbId=${dbi}`);
|
||||
}
|
||||
}
|
||||
if (filters.jobId.length != 0)
|
||||
if (filters.jobIdMatch != "in") {
|
||||
opts.push(`jobId=${filters.jobId}`);
|
||||
|
@@ -39,6 +39,7 @@
|
||||
export let metrics = ccconfig.plot_list_selectedMetrics;
|
||||
export let showFootprint;
|
||||
export let filterBuffer = [];
|
||||
export let selectedJobs = [];
|
||||
|
||||
let usePaging = ccconfig.job_list_usePaging
|
||||
let itemsPerPage = usePaging ? ccconfig.plot_list_jobsPerPage : 10;
|
||||
@@ -285,7 +286,10 @@
|
||||
</tr>
|
||||
{:else}
|
||||
{#each jobs as job (job)}
|
||||
<JobListRow bind:triggerMetricRefresh {job} {metrics} {plotWidth} {showFootprint} />
|
||||
<JobListRow bind:triggerMetricRefresh {job} {metrics} {plotWidth} {showFootprint} previousSelect={selectedJobs.includes(job.id)}
|
||||
on:select-job={({detail}) => selectedJobs = [...selectedJobs, detail]}
|
||||
on:unselect-job={({detail}) => selectedJobs = selectedJobs.filter(item => item !== detail)}
|
||||
/>
|
||||
{:else}
|
||||
<tr>
|
||||
<td colspan={metrics.length + 1}> No jobs found </td>
|
||||
|
@@ -18,6 +18,8 @@
|
||||
export let username = null;
|
||||
export let authlevel= null;
|
||||
export let roles = null;
|
||||
export let isSelected = null;
|
||||
export let showSelect = false;
|
||||
|
||||
function formatDuration(duration) {
|
||||
const hours = Math.floor(duration / 3600);
|
||||
@@ -76,18 +78,39 @@
|
||||
<a href="/monitoring/job/{job.id}" target="_blank">{job.jobId}</a>
|
||||
({job.cluster})
|
||||
</span>
|
||||
<Button id={`${job.cluster}-${job.jobId}-clipboard`} outline color="secondary" size="sm" on:click={clipJobId(job.jobId)} >
|
||||
{#if displayCheck}
|
||||
<Icon name="clipboard2-check-fill"/>
|
||||
{:else}
|
||||
<Icon name="clipboard2"/>
|
||||
<span>
|
||||
{#if showSelect}
|
||||
<Button id={`${job.cluster}-${job.jobId}-select`} outline={!isSelected} color={isSelected? `success`: `secondary`} size="sm" class="mr-2"
|
||||
on:click={() => {
|
||||
isSelected = !isSelected
|
||||
}}>
|
||||
{#if isSelected}
|
||||
<Icon name="check-square"/>
|
||||
{:else if isSelected == false}
|
||||
<Icon name="square"/>
|
||||
{:else}
|
||||
<Icon name="plus-square-dotted" />
|
||||
{/if}
|
||||
</Button>
|
||||
<Tooltip
|
||||
target={`${job.cluster}-${job.jobId}-select`}
|
||||
placement="left">
|
||||
{ 'Add or Remove Job to/from Comparison Selection' }
|
||||
</Tooltip>
|
||||
{/if}
|
||||
</Button>
|
||||
<Tooltip
|
||||
target={`${job.cluster}-${job.jobId}-clipboard`}
|
||||
placement="right">
|
||||
{ displayCheck ? 'Copied!' : 'Copy Job ID to Clipboard' }
|
||||
</Tooltip>
|
||||
<Button id={`${job.cluster}-${job.jobId}-clipboard`} outline color="secondary" size="sm" on:click={clipJobId(job.jobId)} >
|
||||
{#if displayCheck}
|
||||
<Icon name="clipboard2-check-fill"/>
|
||||
{:else}
|
||||
<Icon name="clipboard2"/>
|
||||
{/if}
|
||||
</Button>
|
||||
<Tooltip
|
||||
target={`${job.cluster}-${job.jobId}-clipboard`}
|
||||
placement="right">
|
||||
{ displayCheck ? 'Copied!' : 'Copy Job ID to Clipboard' }
|
||||
</Tooltip>
|
||||
</span>
|
||||
</span>
|
||||
{#if job.metaData?.jobName}
|
||||
{#if job.metaData?.jobName.length <= 25}
|
||||
|
@@ -12,7 +12,7 @@
|
||||
|
||||
<script>
|
||||
import { queryStore, gql, getContextClient } from "@urql/svelte";
|
||||
import { getContext } from "svelte";
|
||||
import { getContext, createEventDispatcher } from "svelte";
|
||||
import { Card, Spinner } from "@sveltestrap/sveltestrap";
|
||||
import { maxScope, checkMetricDisabled } from "../utils.js";
|
||||
import JobInfo from "./JobInfo.svelte";
|
||||
@@ -25,7 +25,9 @@
|
||||
export let plotHeight = 275;
|
||||
export let showFootprint;
|
||||
export let triggerMetricRefresh = false;
|
||||
export let previousSelect = false;
|
||||
|
||||
const dispatch = createEventDispatcher();
|
||||
const resampleConfig = getContext("resampling") || null;
|
||||
const resampleDefault = resampleConfig ? Math.max(...resampleConfig.resolutions) : 0;
|
||||
|
||||
@@ -38,6 +40,8 @@
|
||||
let selectedResolution = resampleDefault;
|
||||
let zoomStates = {};
|
||||
let thresholdStates = {};
|
||||
|
||||
$: isSelected = previousSelect || null;
|
||||
|
||||
const cluster = getContext("clusters").find((c) => c.name == job.cluster);
|
||||
const client = getContextClient();
|
||||
@@ -112,6 +116,12 @@
|
||||
refreshMetrics();
|
||||
}
|
||||
|
||||
$: if (isSelected == true && previousSelect == false) {
|
||||
dispatch("select-job", job.id)
|
||||
} else if (isSelected == false && previousSelect == true) {
|
||||
dispatch("unselect-job", job.id)
|
||||
}
|
||||
|
||||
// Helper
|
||||
const selectScope = (jobMetrics) =>
|
||||
jobMetrics.reduce(
|
||||
@@ -152,7 +162,7 @@
|
||||
|
||||
<tr>
|
||||
<td>
|
||||
<JobInfo {job} />
|
||||
<JobInfo {job} bind:isSelected showSelect/>
|
||||
</td>
|
||||
{#if job.monitoringStatus == 0 || job.monitoringStatus == 2}
|
||||
<td colspan={metrics.length}>
|
||||
|
@@ -308,7 +308,7 @@
|
||||
style="background-color: rgba(255, 255, 255, 1.0);" class="rounded"
|
||||
/>
|
||||
{:else}
|
||||
<Card body color="warning" class="mx-4"
|
||||
>Cannot render plot: No series data returned for <code>{metric}</code></Card
|
||||
<Card body color="warning" class="mx-4 my-2"
|
||||
>Cannot render plot: No series data returned for <code>{metric?metric:'job resources'}</code></Card
|
||||
>
|
||||
{/if}
|
||||
|
@@ -461,11 +461,11 @@ export function convert2uplot(canvasData, secondsToMinutes = false, secondsToHou
|
||||
} else { // Default -> Fill Histodata with zero values on unused value placing -> maybe allows zoom trigger as known
|
||||
if (secondsToHours) {
|
||||
let hours = cd.value / 3600
|
||||
console.log("x seconds to y hours", cd.value, hours)
|
||||
// console.log("x seconds to y hours", cd.value, hours)
|
||||
uplotData[0].push(hours)
|
||||
} else if (secondsToMinutes) {
|
||||
let minutes = cd.value / 60
|
||||
console.log("x seconds to y minutes", cd.value, minutes)
|
||||
// console.log("x seconds to y minutes", cd.value, minutes)
|
||||
uplotData[0].push(minutes)
|
||||
} else {
|
||||
uplotData[0].push(cd.value)
|
||||
|
Reference in New Issue
Block a user