mirror of
https://github.com/ClusterCockpit/cc-backend
synced 2024-12-26 13:29:05 +01:00
Rework tag and tag edit placement, add other feedback
- admin message shown primarily if exists - comment demo summary tab
This commit is contained in:
parent
6367c1ab4d
commit
d7a8bbf40b
@ -25,7 +25,6 @@
|
|||||||
CardHeader,
|
CardHeader,
|
||||||
CardTitle,
|
CardTitle,
|
||||||
Button,
|
Button,
|
||||||
Icon,
|
|
||||||
} from "@sveltestrap/sveltestrap";
|
} from "@sveltestrap/sveltestrap";
|
||||||
import { getContext } from "svelte";
|
import { getContext } from "svelte";
|
||||||
import {
|
import {
|
||||||
@ -35,7 +34,6 @@
|
|||||||
transformDataForRoofline,
|
transformDataForRoofline,
|
||||||
} from "./generic/utils.js";
|
} from "./generic/utils.js";
|
||||||
import Metric from "./job/Metric.svelte";
|
import Metric from "./job/Metric.svelte";
|
||||||
import TagManagement from "./job/TagManagement.svelte";
|
|
||||||
import StatsTable from "./job/StatsTable.svelte";
|
import StatsTable from "./job/StatsTable.svelte";
|
||||||
import JobSummary from "./job/JobSummary.svelte";
|
import JobSummary from "./job/JobSummary.svelte";
|
||||||
import ConcurrentJobs from "./generic/helper/ConcurrentJobs.svelte";
|
import ConcurrentJobs from "./generic/helper/ConcurrentJobs.svelte";
|
||||||
@ -54,12 +52,10 @@
|
|||||||
const ccconfig = getContext("cc-config")
|
const ccconfig = getContext("cc-config")
|
||||||
|
|
||||||
let isMetricsSelectionOpen = false,
|
let isMetricsSelectionOpen = false,
|
||||||
showFootprint = !!ccconfig[`job_view_showFootprint`],
|
|
||||||
selectedMetrics = [],
|
selectedMetrics = [],
|
||||||
selectedScopes = [];
|
selectedScopes = [];
|
||||||
|
|
||||||
let plots = {},
|
let plots = {},
|
||||||
jobTags,
|
|
||||||
roofWidth
|
roofWidth
|
||||||
|
|
||||||
let missingMetrics = [],
|
let missingMetrics = [],
|
||||||
@ -240,14 +236,22 @@
|
|||||||
{:else if $initq.data}
|
{:else if $initq.data}
|
||||||
<Card class="overflow-auto" style="height: 400px;">
|
<Card class="overflow-auto" style="height: 400px;">
|
||||||
<TabContent> <!-- on:tab={(e) => (status = e.detail)} -->
|
<TabContent> <!-- on:tab={(e) => (status = e.detail)} -->
|
||||||
<TabPane tabId="meta-info" tab="Job Info" active>
|
{#if $initq.data?.job?.metaData?.message}
|
||||||
<CardBody class="pb-2">
|
<TabPane tabId="admin-msg" tab="Admin Note" active>
|
||||||
<JobInfo job={$initq.data.job} {jobTags} />
|
<CardBody>
|
||||||
|
<Card body class="mb-2" color="warning">
|
||||||
|
<h5>Job {$initq.data?.job?.jobId} ({$initq.data?.job?.cluster})</h5>
|
||||||
|
The following note was added by administrators:
|
||||||
|
</Card>
|
||||||
|
<Card body>
|
||||||
|
{@html $initq.data.job.metaData.message}
|
||||||
|
</Card>
|
||||||
</CardBody>
|
</CardBody>
|
||||||
</TabPane>
|
</TabPane>
|
||||||
<TabPane tabId="job-tags" tab="Job Tags">
|
{/if}
|
||||||
<CardBody>
|
<TabPane tabId="meta-info" tab="Job Info" active={$initq.data?.job?.metaData?.message?false:true}>
|
||||||
<TagManagement job={$initq.data.job} {username} {authlevel} {roles} bind:jobTags renderModal={false}/>
|
<CardBody class="pb-2">
|
||||||
|
<JobInfo job={$initq.data.job} {username} {authlevel} {roles} showTags={false} showTagedit/>
|
||||||
</CardBody>
|
</CardBody>
|
||||||
</TabPane>
|
</TabPane>
|
||||||
{#if $initq.data.job.concurrentJobs != null && $initq.data.job.concurrentJobs.items.length != 0}
|
{#if $initq.data.job.concurrentJobs != null && $initq.data.job.concurrentJobs.items.length != 0}
|
||||||
@ -260,15 +264,6 @@
|
|||||||
</CardBody>
|
</CardBody>
|
||||||
</TabPane>
|
</TabPane>
|
||||||
{/if}
|
{/if}
|
||||||
{#if $initq.data?.job?.metaData?.message}
|
|
||||||
<TabPane tabId="admin-msg" tab="Admin Note">
|
|
||||||
<CardBody>
|
|
||||||
<p>This note was added by administrators:</p>
|
|
||||||
<hr/>
|
|
||||||
<p>{@html $initq.data.job.metaData.message}</p>
|
|
||||||
</CardBody>
|
|
||||||
</TabPane>
|
|
||||||
{/if}
|
|
||||||
</TabContent>
|
</TabContent>
|
||||||
</Card>
|
</Card>
|
||||||
{:else}
|
{:else}
|
||||||
@ -276,8 +271,7 @@
|
|||||||
{/if}
|
{/if}
|
||||||
</Col>
|
</Col>
|
||||||
|
|
||||||
<!-- If enabled: Column 2: Job Footprint, Polar Representation, Heuristic Summary -->
|
<!-- Column 2: Job Footprint, Polar Representation, Heuristic Summary -->
|
||||||
{#if showFootprint}
|
|
||||||
<Col xs={12} md={6} xl={4} xxl={3} class="mb-3 mb-xxl-0">
|
<Col xs={12} md={6} xl={4} xxl={3} class="mb-3 mb-xxl-0">
|
||||||
{#if $initq.error}
|
{#if $initq.error}
|
||||||
<Card body color="danger">{$initq.error.message}</Card>
|
<Card body color="danger">{$initq.error.message}</Card>
|
||||||
@ -287,10 +281,9 @@
|
|||||||
<Spinner secondary />
|
<Spinner secondary />
|
||||||
{/if}
|
{/if}
|
||||||
</Col>
|
</Col>
|
||||||
{/if}
|
|
||||||
|
|
||||||
<!-- Column 3: Job Roofline; If footprint Enabled: full width, else half width -->
|
<!-- Column 3: Job Roofline; If footprint Enabled: full width, else half width -->
|
||||||
<Col xs={12} md={showFootprint ? 12 : 6} xl={showFootprint ? 5 : 6} xxl={6}>
|
<Col xs={12} md={12} xl={5} xxl={6}>
|
||||||
{#if $initq.error || $jobMetrics.error}
|
{#if $initq.error || $jobMetrics.error}
|
||||||
<Card body color="danger">
|
<Card body color="danger">
|
||||||
<p>Initq Error: {$initq.error?.message}</p>
|
<p>Initq Error: {$initq.error?.message}</p>
|
||||||
|
@ -23,12 +23,22 @@
|
|||||||
if ($initialized && tag == null)
|
if ($initialized && tag == null)
|
||||||
tag = allTags.find(tag => tag.id == id)
|
tag = allTags.find(tag => tag.id == id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getScopeColor(scope) {
|
||||||
|
switch (scope) {
|
||||||
|
case "admin":
|
||||||
|
return "#19e5e6";
|
||||||
|
case "global":
|
||||||
|
return "#c85fc8";
|
||||||
|
default:
|
||||||
|
return "#ffc107";
|
||||||
|
}
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
a {
|
a {
|
||||||
margin-left: 0.5rem;
|
margin-right: 0.5rem;
|
||||||
line-height: 2;
|
|
||||||
}
|
}
|
||||||
span {
|
span {
|
||||||
font-size: 0.9rem;
|
font-size: 0.9rem;
|
||||||
@ -37,13 +47,7 @@
|
|||||||
|
|
||||||
<a target={clickable ? "_blank" : null} href={clickable ? `/monitoring/jobs/?tag=${id}` : null}>
|
<a target={clickable ? "_blank" : null} href={clickable ? `/monitoring/jobs/?tag=${id}` : null}>
|
||||||
{#if tag}
|
{#if tag}
|
||||||
{#if tag?.scope === "global"}
|
<span style="background-color:{getScopeColor(tag?.scope)};" class="my-1 badge text-dark">{tag.type}: {tag.name}</span>
|
||||||
<span style="background-color:#c85fc8;" class="badge text-dark">{tag.type}: {tag.name}</span>
|
|
||||||
{:else if tag?.scope === "admin"}
|
|
||||||
<span style="background-color:#19e5e6;" class="badge text-dark">{tag.type}: {tag.name}</span>
|
|
||||||
{:else}
|
|
||||||
<span class="badge bg-warning text-dark">{tag.type}: {tag.name}</span>
|
|
||||||
{/if}
|
|
||||||
{:else}
|
{:else}
|
||||||
Loading...
|
Loading...
|
||||||
{/if}
|
{/if}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<!--
|
<!--
|
||||||
@component Job View Subcomponent; allows management of job tags by deletion or new entries
|
@component Job Info Subcomponent; allows management of job tags by deletion or new entries
|
||||||
|
|
||||||
Properties:
|
Properties:
|
||||||
- `job Object`: The job object
|
- `job Object`: The job object
|
||||||
@ -30,8 +30,8 @@
|
|||||||
Alert,
|
Alert,
|
||||||
Tooltip,
|
Tooltip,
|
||||||
} from "@sveltestrap/sveltestrap";
|
} from "@sveltestrap/sveltestrap";
|
||||||
import { fuzzySearchTags } from "../generic/utils.js";
|
import { fuzzySearchTags } from "../utils.js";
|
||||||
import Tag from "../generic/helper/Tag.svelte";
|
import Tag from "./Tag.svelte";
|
||||||
|
|
||||||
export let job;
|
export let job;
|
||||||
export let jobTags = job.tags;
|
export let jobTags = job.tags;
|
||||||
@ -178,12 +178,7 @@
|
|||||||
{#if renderModal}
|
{#if renderModal}
|
||||||
<Modal {isOpen} toggle={() => (isOpen = !isOpen)}>
|
<Modal {isOpen} toggle={() => (isOpen = !isOpen)}>
|
||||||
<ModalHeader>
|
<ModalHeader>
|
||||||
Manage Tags
|
Manage Tags <Icon name="tags"/>
|
||||||
{#if pendingChange !== false}
|
|
||||||
<Spinner size="sm" secondary />
|
|
||||||
{:else}
|
|
||||||
<Icon name="tags" />
|
|
||||||
{/if}
|
|
||||||
</ModalHeader>
|
</ModalHeader>
|
||||||
<ModalBody>
|
<ModalBody>
|
||||||
<InputGroup class="mb-3">
|
<InputGroup class="mb-3">
|
||||||
@ -317,8 +312,8 @@
|
|||||||
</ModalFooter>
|
</ModalFooter>
|
||||||
</Modal>
|
</Modal>
|
||||||
|
|
||||||
<Button outline on:click={() => (isOpen = true)}>
|
<Button outline on:click={() => (isOpen = true)} size="sm" color="primary">
|
||||||
Manage Tags <Icon name="tags" />
|
Manage {jobTags?.length ? jobTags.length : ''} Tags
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
{:else}
|
{:else}
|
@ -10,9 +10,14 @@
|
|||||||
import { Badge, Icon } from "@sveltestrap/sveltestrap";
|
import { Badge, Icon } from "@sveltestrap/sveltestrap";
|
||||||
import { scrambleNames, scramble } from "../utils.js";
|
import { scrambleNames, scramble } from "../utils.js";
|
||||||
import Tag from "../helper/Tag.svelte";
|
import Tag from "../helper/Tag.svelte";
|
||||||
|
import TagManagement from "../helper/TagManagement.svelte";
|
||||||
|
|
||||||
export let job;
|
export let job;
|
||||||
export let jobTags = job.tags;
|
export let jobTags = job.tags;
|
||||||
|
export let showTagedit = false;
|
||||||
|
export let username = null;
|
||||||
|
export let authlevel= null;
|
||||||
|
export let roles = null;
|
||||||
|
|
||||||
function formatDuration(duration) {
|
function formatDuration(duration) {
|
||||||
const hours = Math.floor(duration / 3600);
|
const hours = Math.floor(duration / 3600);
|
||||||
@ -36,7 +41,7 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<p>
|
<p class="mb-2">
|
||||||
<span class="fw-bold"
|
<span class="fw-bold"
|
||||||
><a href="/monitoring/job/{job.id}" target="_blank">{job.jobId}</a>
|
><a href="/monitoring/job/{job.id}" target="_blank">{job.jobId}</a>
|
||||||
({job.cluster})</span
|
({job.cluster})</span
|
||||||
@ -63,7 +68,7 @@
|
|||||||
{/if}
|
{/if}
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p class="mb-2">
|
||||||
<Icon name="person-fill" />
|
<Icon name="person-fill" />
|
||||||
<a class="fst-italic" href="/monitoring/user/{job.user}" target="_blank">
|
<a class="fst-italic" href="/monitoring/user/{job.user}" target="_blank">
|
||||||
{scrambleNames ? scramble(job.user) : job.user}
|
{scrambleNames ? scramble(job.user) : job.user}
|
||||||
@ -84,7 +89,7 @@
|
|||||||
{/if}
|
{/if}
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p class="mb-2">
|
||||||
{#if job.numNodes == 1}
|
{#if job.numNodes == 1}
|
||||||
{job.resources[0].hostname}
|
{job.resources[0].hostname}
|
||||||
{:else}
|
{:else}
|
||||||
@ -104,7 +109,7 @@
|
|||||||
{job.subCluster}
|
{job.subCluster}
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p class="mb-2">
|
||||||
Start: <span class="fw-bold"
|
Start: <span class="fw-bold"
|
||||||
>{new Date(job.startTime).toLocaleString()}</span
|
>{new Date(job.startTime).toLocaleString()}</span
|
||||||
>
|
>
|
||||||
@ -117,11 +122,25 @@
|
|||||||
{/if}
|
{/if}
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p class="mb-2">
|
{#if showTagedit}
|
||||||
|
<hr class="mt-0 mb-2"/>
|
||||||
|
<p class="mb-1">
|
||||||
|
<TagManagement bind:jobTags {job} {username} {authlevel} {roles} renderModal/> :
|
||||||
|
{#if jobTags?.length > 0}
|
||||||
|
{#each jobTags as tag}
|
||||||
|
<Tag {tag}/>
|
||||||
|
{/each}
|
||||||
|
{:else}
|
||||||
|
<span style="font-size: 0.9rem; background-color: lightgray;" class="my-1 badge text-dark">No Tags</span>
|
||||||
|
{/if}
|
||||||
|
</p>
|
||||||
|
{:else}
|
||||||
|
<p class="mb-1">
|
||||||
{#each jobTags as tag}
|
{#each jobTags as tag}
|
||||||
<Tag {tag} />
|
<Tag {tag} />
|
||||||
{/each}
|
{/each}
|
||||||
</p>
|
</p>
|
||||||
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
@ -68,6 +68,7 @@
|
|||||||
export let height = "400px";
|
export let height = "400px";
|
||||||
|
|
||||||
const ccconfig = getContext("cc-config")
|
const ccconfig = getContext("cc-config")
|
||||||
|
const showFootprint = !!ccconfig[`job_view_showFootprint`];
|
||||||
|
|
||||||
const footprintData = job?.footprint?.map((jf) => {
|
const footprintData = job?.footprint?.map((jf) => {
|
||||||
const fmc = getContext("getMetricConfig")(job.cluster, job.subCluster, jf.name);
|
const fmc = getContext("getMetricConfig")(job.cluster, job.subCluster, jf.name);
|
||||||
@ -165,6 +166,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
function writeSummary(fpd) {
|
function writeSummary(fpd) {
|
||||||
// Hardcoded! Needs to be retrieved from globalMetrics
|
// Hardcoded! Needs to be retrieved from globalMetrics
|
||||||
const performanceMetrics = ['flops_any', 'mem_bw'];
|
const performanceMetrics = ['flops_any', 'mem_bw'];
|
||||||
@ -225,10 +227,12 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
$: summaryMessages = writeSummary(footprintData)
|
$: summaryMessages = writeSummary(footprintData)
|
||||||
|
*/
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<Card class="overflow-auto" style="width: {width}; height: {height}">
|
<Card class="overflow-auto" style="width: {width}; height: {height}">
|
||||||
<TabContent> <!-- on:tab={(e) => (status = e.detail)} -->
|
<TabContent> <!-- on:tab={(e) => (status = e.detail)} -->
|
||||||
|
{#if showFootprint}
|
||||||
<TabPane tabId="foot" tab="Footprint" active>
|
<TabPane tabId="foot" tab="Footprint" active>
|
||||||
<CardBody>
|
<CardBody>
|
||||||
{#each footprintData as fpd, index}
|
{#each footprintData as fpd, index}
|
||||||
@ -309,7 +313,8 @@
|
|||||||
{/each}
|
{/each}
|
||||||
</CardBody>
|
</CardBody>
|
||||||
</TabPane>
|
</TabPane>
|
||||||
<TabPane tabId="polar" tab="Polar">
|
{/if}
|
||||||
|
<TabPane tabId="polar" tab="Polar" active={!showFootprint}>
|
||||||
<CardBody>
|
<CardBody>
|
||||||
<Polar
|
<Polar
|
||||||
{footprintData}
|
{footprintData}
|
||||||
@ -317,6 +322,7 @@
|
|||||||
/>
|
/>
|
||||||
</CardBody>
|
</CardBody>
|
||||||
</TabPane>
|
</TabPane>
|
||||||
|
<!--
|
||||||
<TabPane tabId="summary" tab="Summary">
|
<TabPane tabId="summary" tab="Summary">
|
||||||
<CardBody>
|
<CardBody>
|
||||||
<p>Based on footprint data, this job performs as follows:</p>
|
<p>Based on footprint data, this job performs as follows:</p>
|
||||||
@ -330,6 +336,7 @@
|
|||||||
</ul>
|
</ul>
|
||||||
</CardBody>
|
</CardBody>
|
||||||
</TabPane>
|
</TabPane>
|
||||||
|
-->
|
||||||
</TabContent>
|
</TabContent>
|
||||||
</Card>
|
</Card>
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user