Rework tag and tag edit placement, add other feedback

- admin message shown primarily if exists
- comment demo summary tab
This commit is contained in:
Christoph Kluge 2024-09-18 17:23:29 +02:00
parent 6367c1ab4d
commit d7a8bbf40b
5 changed files with 217 additions and 199 deletions

View File

@ -25,7 +25,6 @@
CardHeader,
CardTitle,
Button,
Icon,
} from "@sveltestrap/sveltestrap";
import { getContext } from "svelte";
import {
@ -35,7 +34,6 @@
transformDataForRoofline,
} from "./generic/utils.js";
import Metric from "./job/Metric.svelte";
import TagManagement from "./job/TagManagement.svelte";
import StatsTable from "./job/StatsTable.svelte";
import JobSummary from "./job/JobSummary.svelte";
import ConcurrentJobs from "./generic/helper/ConcurrentJobs.svelte";
@ -54,12 +52,10 @@
const ccconfig = getContext("cc-config")
let isMetricsSelectionOpen = false,
showFootprint = !!ccconfig[`job_view_showFootprint`],
selectedMetrics = [],
selectedScopes = [];
let plots = {},
jobTags,
roofWidth
let missingMetrics = [],
@ -240,14 +236,22 @@
{:else if $initq.data}
<Card class="overflow-auto" style="height: 400px;">
<TabContent> <!-- on:tab={(e) => (status = e.detail)} -->
<TabPane tabId="meta-info" tab="Job Info" active>
<CardBody class="pb-2">
<JobInfo job={$initq.data.job} {jobTags} />
{#if $initq.data?.job?.metaData?.message}
<TabPane tabId="admin-msg" tab="Admin Note" active>
<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>
</TabPane>
<TabPane tabId="job-tags" tab="Job Tags">
<CardBody>
<TagManagement job={$initq.data.job} {username} {authlevel} {roles} bind:jobTags renderModal={false}/>
{/if}
<TabPane tabId="meta-info" tab="Job Info" active={$initq.data?.job?.metaData?.message?false:true}>
<CardBody class="pb-2">
<JobInfo job={$initq.data.job} {username} {authlevel} {roles} showTags={false} showTagedit/>
</CardBody>
</TabPane>
{#if $initq.data.job.concurrentJobs != null && $initq.data.job.concurrentJobs.items.length != 0}
@ -260,15 +264,6 @@
</CardBody>
</TabPane>
{/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>
</Card>
{:else}
@ -276,8 +271,7 @@
{/if}
</Col>
<!-- If enabled: Column 2: Job Footprint, Polar Representation, Heuristic Summary -->
{#if showFootprint}
<!-- Column 2: Job Footprint, Polar Representation, Heuristic Summary -->
<Col xs={12} md={6} xl={4} xxl={3} class="mb-3 mb-xxl-0">
{#if $initq.error}
<Card body color="danger">{$initq.error.message}</Card>
@ -287,10 +281,9 @@
<Spinner secondary />
{/if}
</Col>
{/if}
<!-- 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}
<Card body color="danger">
<p>Initq Error: {$initq.error?.message}</p>

View File

@ -23,12 +23,22 @@
if ($initialized && tag == null)
tag = allTags.find(tag => tag.id == id)
}
function getScopeColor(scope) {
switch (scope) {
case "admin":
return "#19e5e6";
case "global":
return "#c85fc8";
default:
return "#ffc107";
}
}
</script>
<style>
a {
margin-left: 0.5rem;
line-height: 2;
margin-right: 0.5rem;
}
span {
font-size: 0.9rem;
@ -37,13 +47,7 @@
<a target={clickable ? "_blank" : null} href={clickable ? `/monitoring/jobs/?tag=${id}` : null}>
{#if tag}
{#if tag?.scope === "global"}
<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}
<span style="background-color:{getScopeColor(tag?.scope)};" class="my-1 badge text-dark">{tag.type}: {tag.name}</span>
{:else}
Loading...
{/if}

View File

@ -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:
- `job Object`: The job object
@ -30,8 +30,8 @@
Alert,
Tooltip,
} from "@sveltestrap/sveltestrap";
import { fuzzySearchTags } from "../generic/utils.js";
import Tag from "../generic/helper/Tag.svelte";
import { fuzzySearchTags } from "../utils.js";
import Tag from "./Tag.svelte";
export let job;
export let jobTags = job.tags;
@ -178,12 +178,7 @@
{#if renderModal}
<Modal {isOpen} toggle={() => (isOpen = !isOpen)}>
<ModalHeader>
Manage Tags
{#if pendingChange !== false}
<Spinner size="sm" secondary />
{:else}
<Icon name="tags" />
{/if}
Manage Tags <Icon name="tags"/>
</ModalHeader>
<ModalBody>
<InputGroup class="mb-3">
@ -317,8 +312,8 @@
</ModalFooter>
</Modal>
<Button outline on:click={() => (isOpen = true)}>
Manage Tags <Icon name="tags" />
<Button outline on:click={() => (isOpen = true)} size="sm" color="primary">
Manage {jobTags?.length ? jobTags.length : ''} Tags
</Button>
{:else}

View File

@ -10,9 +10,14 @@
import { Badge, Icon } from "@sveltestrap/sveltestrap";
import { scrambleNames, scramble } from "../utils.js";
import Tag from "../helper/Tag.svelte";
import TagManagement from "../helper/TagManagement.svelte";
export let job;
export let jobTags = job.tags;
export let showTagedit = false;
export let username = null;
export let authlevel= null;
export let roles = null;
function formatDuration(duration) {
const hours = Math.floor(duration / 3600);
@ -36,7 +41,7 @@
</script>
<div>
<p>
<p class="mb-2">
<span class="fw-bold"
><a href="/monitoring/job/{job.id}" target="_blank">{job.jobId}</a>
({job.cluster})</span
@ -63,7 +68,7 @@
{/if}
</p>
<p>
<p class="mb-2">
<Icon name="person-fill" />
<a class="fst-italic" href="/monitoring/user/{job.user}" target="_blank">
{scrambleNames ? scramble(job.user) : job.user}
@ -84,7 +89,7 @@
{/if}
</p>
<p>
<p class="mb-2">
{#if job.numNodes == 1}
{job.resources[0].hostname}
{:else}
@ -104,7 +109,7 @@
{job.subCluster}
</p>
<p>
<p class="mb-2">
Start: <span class="fw-bold"
>{new Date(job.startTime).toLocaleString()}</span
>
@ -117,11 +122,25 @@
{/if}
</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}
<Tag {tag} />
{/each}
</p>
{/if}
</div>
<style>

View File

@ -68,6 +68,7 @@
export let height = "400px";
const ccconfig = getContext("cc-config")
const showFootprint = !!ccconfig[`job_view_showFootprint`];
const footprintData = job?.footprint?.map((jf) => {
const fmc = getContext("getMetricConfig")(job.cluster, job.subCluster, jf.name);
@ -165,6 +166,7 @@
}
}
/*
function writeSummary(fpd) {
// Hardcoded! Needs to be retrieved from globalMetrics
const performanceMetrics = ['flops_any', 'mem_bw'];
@ -225,10 +227,12 @@
};
$: summaryMessages = writeSummary(footprintData)
*/
</script>
<Card class="overflow-auto" style="width: {width}; height: {height}">
<TabContent> <!-- on:tab={(e) => (status = e.detail)} -->
{#if showFootprint}
<TabPane tabId="foot" tab="Footprint" active>
<CardBody>
{#each footprintData as fpd, index}
@ -309,7 +313,8 @@
{/each}
</CardBody>
</TabPane>
<TabPane tabId="polar" tab="Polar">
{/if}
<TabPane tabId="polar" tab="Polar" active={!showFootprint}>
<CardBody>
<Polar
{footprintData}
@ -317,6 +322,7 @@
/>
</CardBody>
</TabPane>
<!--
<TabPane tabId="summary" tab="Summary">
<CardBody>
<p>Based on footprint data, this job performs as follows:</p>
@ -330,6 +336,7 @@
</ul>
</CardBody>
</TabPane>
-->
</TabContent>
</Card>