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}
|
||||||
|
<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>
|
||||||
|
{/if}
|
||||||
|
<TabPane tabId="meta-info" tab="Job Info" active={$initq.data?.job?.metaData?.message?false:true}>
|
||||||
<CardBody class="pb-2">
|
<CardBody class="pb-2">
|
||||||
<JobInfo job={$initq.data.job} {jobTags} />
|
<JobInfo job={$initq.data.job} {username} {authlevel} {roles} showTags={false} showTagedit/>
|
||||||
</CardBody>
|
|
||||||
</TabPane>
|
|
||||||
<TabPane tabId="job-tags" tab="Job Tags">
|
|
||||||
<CardBody>
|
|
||||||
<TagManagement job={$initq.data.job} {username} {authlevel} {roles} bind:jobTags renderModal={false}/>
|
|
||||||
</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,21 +271,19 @@
|
|||||||
{/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>
|
{:else if $initq?.data && $jobMetrics?.data}
|
||||||
{:else if $initq?.data && $jobMetrics?.data}
|
<JobSummary job={$initq.data.job} jobMetrics={$jobMetrics.data.jobMetrics}/>
|
||||||
<JobSummary job={$initq.data.job} jobMetrics={$jobMetrics.data.jobMetrics}/>
|
{:else}
|
||||||
{:else}
|
<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}
|
||||||
{#each jobTags as tag}
|
<hr class="mt-0 mb-2"/>
|
||||||
<Tag {tag} />
|
<p class="mb-1">
|
||||||
{/each}
|
<TagManagement bind:jobTags {job} {username} {authlevel} {roles} renderModal/> :
|
||||||
</p>
|
{#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>
|
</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,101 +166,142 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function writeSummary(fpd) {
|
/*
|
||||||
// Hardcoded! Needs to be retrieved from globalMetrics
|
function writeSummary(fpd) {
|
||||||
const performanceMetrics = ['flops_any', 'mem_bw'];
|
// Hardcoded! Needs to be retrieved from globalMetrics
|
||||||
const utilizationMetrics = ['cpu_load', 'acc_utilization'];
|
const performanceMetrics = ['flops_any', 'mem_bw'];
|
||||||
const energyMetrics = ['cpu_power'];
|
const utilizationMetrics = ['cpu_load', 'acc_utilization'];
|
||||||
|
const energyMetrics = ['cpu_power'];
|
||||||
|
|
||||||
let performanceScore = 0;
|
let performanceScore = 0;
|
||||||
let utilizationScore = 0;
|
let utilizationScore = 0;
|
||||||
let energyScore = 0;
|
let energyScore = 0;
|
||||||
|
|
||||||
let performanceMetricsCounted = 0;
|
let performanceMetricsCounted = 0;
|
||||||
let utilizationMetricsCounted = 0;
|
let utilizationMetricsCounted = 0;
|
||||||
let energyMetricsCounted = 0;
|
let energyMetricsCounted = 0;
|
||||||
|
|
||||||
fpd.forEach(metric => {
|
fpd.forEach(metric => {
|
||||||
console.log('Metric, Impact', metric.name, metric.impact)
|
console.log('Metric, Impact', metric.name, metric.impact)
|
||||||
if (performanceMetrics.includes(metric.name)) {
|
if (performanceMetrics.includes(metric.name)) {
|
||||||
performanceScore += metric.impact
|
performanceScore += metric.impact
|
||||||
performanceMetricsCounted += 1
|
performanceMetricsCounted += 1
|
||||||
} else if (utilizationMetrics.includes(metric.name)) {
|
} else if (utilizationMetrics.includes(metric.name)) {
|
||||||
utilizationScore += metric.impact
|
utilizationScore += metric.impact
|
||||||
utilizationMetricsCounted += 1
|
utilizationMetricsCounted += 1
|
||||||
} else if (energyMetrics.includes(metric.name)) {
|
} else if (energyMetrics.includes(metric.name)) {
|
||||||
energyScore += metric.impact
|
energyScore += metric.impact
|
||||||
energyMetricsCounted += 1
|
energyMetricsCounted += 1
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
performanceScore = (performanceMetricsCounted == 0) ? performanceScore : (performanceScore / performanceMetricsCounted);
|
||||||
|
utilizationScore = (utilizationMetricsCounted == 0) ? utilizationScore : (utilizationScore / utilizationMetricsCounted);
|
||||||
|
energyScore = (energyMetricsCounted == 0) ? energyScore : (energyScore / energyMetricsCounted);
|
||||||
|
|
||||||
|
let res = [];
|
||||||
|
|
||||||
|
console.log('Perf', performanceScore, performanceMetricsCounted)
|
||||||
|
console.log('Util', utilizationScore, utilizationMetricsCounted)
|
||||||
|
console.log('Energy', energyScore, energyMetricsCounted)
|
||||||
|
|
||||||
|
if (performanceScore == 1) {
|
||||||
|
res.push('<b>Performance:</b> Your job performs well.')
|
||||||
|
} else if (performanceScore != 0) {
|
||||||
|
res.push('<b>Performance:</b> Your job performs suboptimal.')
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
|
||||||
performanceScore = (performanceMetricsCounted == 0) ? performanceScore : (performanceScore / performanceMetricsCounted);
|
if (utilizationScore == 1) {
|
||||||
utilizationScore = (utilizationMetricsCounted == 0) ? utilizationScore : (utilizationScore / utilizationMetricsCounted);
|
res.push('<b>Utilization:</b> Your job utilizes resources well.')
|
||||||
energyScore = (energyMetricsCounted == 0) ? energyScore : (energyScore / energyMetricsCounted);
|
} else if (utilizationScore != 0) {
|
||||||
|
res.push('<b>Utilization:</b> Your job utilizes resources suboptimal.')
|
||||||
|
}
|
||||||
|
|
||||||
let res = [];
|
if (energyScore == 1) {
|
||||||
|
res.push('<b>Energy:</b> Your job has good energy values.')
|
||||||
|
} else if (energyScore != 0) {
|
||||||
|
res.push('<b>Energy:</b> Your job consumes more energy than necessary.')
|
||||||
|
}
|
||||||
|
|
||||||
console.log('Perf', performanceScore, performanceMetricsCounted)
|
return res;
|
||||||
console.log('Util', utilizationScore, utilizationMetricsCounted)
|
};
|
||||||
console.log('Energy', energyScore, energyMetricsCounted)
|
|
||||||
|
|
||||||
if (performanceScore == 1) {
|
$: summaryMessages = writeSummary(footprintData)
|
||||||
res.push('<b>Performance:</b> Your job performs well.')
|
*/
|
||||||
} else if (performanceScore != 0) {
|
|
||||||
res.push('<b>Performance:</b> Your job performs suboptimal.')
|
|
||||||
}
|
|
||||||
|
|
||||||
if (utilizationScore == 1) {
|
|
||||||
res.push('<b>Utilization:</b> Your job utilizes resources well.')
|
|
||||||
} else if (utilizationScore != 0) {
|
|
||||||
res.push('<b>Utilization:</b> Your job utilizes resources suboptimal.')
|
|
||||||
}
|
|
||||||
|
|
||||||
if (energyScore == 1) {
|
|
||||||
res.push('<b>Energy:</b> Your job has good energy values.')
|
|
||||||
} else if (energyScore != 0) {
|
|
||||||
res.push('<b>Energy:</b> Your job consumes more energy than necessary.')
|
|
||||||
}
|
|
||||||
|
|
||||||
return res;
|
|
||||||
};
|
|
||||||
|
|
||||||
$: 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)} -->
|
||||||
<TabPane tabId="foot" tab="Footprint" active>
|
{#if showFootprint}
|
||||||
<CardBody>
|
<TabPane tabId="foot" tab="Footprint" active>
|
||||||
{#each footprintData as fpd, index}
|
<CardBody>
|
||||||
{#if fpd.impact !== 4}
|
{#each footprintData as fpd, index}
|
||||||
<div class="mb-1 d-flex justify-content-between">
|
{#if fpd.impact !== 4}
|
||||||
<div> <b>{fpd.name} ({fpd.stat})</b></div>
|
<div class="mb-1 d-flex justify-content-between">
|
||||||
<div
|
<div> <b>{fpd.name} ({fpd.stat})</b></div>
|
||||||
class="cursor-help d-inline-flex"
|
<div
|
||||||
id={`footprint-${job.jobId}-${index}`}
|
class="cursor-help d-inline-flex"
|
||||||
>
|
id={`footprint-${job.jobId}-${index}`}
|
||||||
<div class="mx-1">
|
>
|
||||||
{#if fpd.impact === 3 || fpd.impact === -1}
|
<div class="mx-1">
|
||||||
<Icon name="exclamation-triangle-fill" class="text-danger" />
|
{#if fpd.impact === 3 || fpd.impact === -1}
|
||||||
{:else if fpd.impact === 2}
|
<Icon name="exclamation-triangle-fill" class="text-danger" />
|
||||||
<Icon name="exclamation-triangle" class="text-warning" />
|
{:else if fpd.impact === 2}
|
||||||
{/if}
|
<Icon name="exclamation-triangle" class="text-warning" />
|
||||||
{#if fpd.impact === 3}
|
{/if}
|
||||||
<Icon name="emoji-frown" class="text-danger" />
|
{#if fpd.impact === 3}
|
||||||
{:else if fpd.impact === 2}
|
<Icon name="emoji-frown" class="text-danger" />
|
||||||
<Icon name="emoji-neutral" class="text-warning" />
|
{:else if fpd.impact === 2}
|
||||||
{:else if fpd.impact === 1}
|
<Icon name="emoji-neutral" class="text-warning" />
|
||||||
<Icon name="emoji-smile" class="text-success" />
|
{:else if fpd.impact === 1}
|
||||||
{:else if fpd.impact === 0}
|
<Icon name="emoji-smile" class="text-success" />
|
||||||
<Icon name="emoji-laughing" class="text-info" />
|
{:else if fpd.impact === 0}
|
||||||
{:else if fpd.impact === -1}
|
<Icon name="emoji-laughing" class="text-info" />
|
||||||
<Icon name="emoji-dizzy" class="text-danger" />
|
{:else if fpd.impact === -1}
|
||||||
{/if}
|
<Icon name="emoji-dizzy" class="text-danger" />
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
{fpd.value} / {fpd.peak}
|
||||||
|
{fpd.unit}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<Tooltip
|
||||||
|
target={`footprint-${job.jobId}-${index}`}
|
||||||
|
placement="right"
|
||||||
|
>{fpd.message}</Tooltip
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
<Row cols={12} class="{(footprintData.length == (index + 1)) ? 'mb-0' : 'mb-2'}">
|
||||||
|
{#if fpd.dir}
|
||||||
|
<Col xs="1">
|
||||||
|
<Icon name="caret-left-fill" />
|
||||||
|
</Col>
|
||||||
|
{/if}
|
||||||
|
<Col xs="11" class="align-content-center">
|
||||||
|
<Progress value={fpd.value} max={fpd.peak} color={fpd.color} />
|
||||||
|
</Col>
|
||||||
|
{#if !fpd.dir}
|
||||||
|
<Col xs="1">
|
||||||
|
<Icon name="caret-right-fill" />
|
||||||
|
</Col>
|
||||||
|
{/if}
|
||||||
|
</Row>
|
||||||
|
{:else}
|
||||||
|
<div class="mb-1 d-flex justify-content-between">
|
||||||
<div>
|
<div>
|
||||||
{fpd.value} / {fpd.peak}
|
<b>{fpd.name} ({fpd.stat})</b>
|
||||||
{fpd.unit}
|
</div>
|
||||||
|
<div
|
||||||
|
class="cursor-help d-inline-flex"
|
||||||
|
id={`footprint-${job.jobId}-${index}`}
|
||||||
|
>
|
||||||
|
<div class="mx-1">
|
||||||
|
<Icon name="info-circle"/>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
{fpd.value}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<Tooltip
|
<Tooltip
|
||||||
@ -267,49 +309,12 @@
|
|||||||
placement="right"
|
placement="right"
|
||||||
>{fpd.message}</Tooltip
|
>{fpd.message}</Tooltip
|
||||||
>
|
>
|
||||||
</div>
|
{/if}
|
||||||
<Row cols={12} class="{(footprintData.length == (index + 1)) ? 'mb-0' : 'mb-2'}">
|
{/each}
|
||||||
{#if fpd.dir}
|
</CardBody>
|
||||||
<Col xs="1">
|
</TabPane>
|
||||||
<Icon name="caret-left-fill" />
|
{/if}
|
||||||
</Col>
|
<TabPane tabId="polar" tab="Polar" active={!showFootprint}>
|
||||||
{/if}
|
|
||||||
<Col xs="11" class="align-content-center">
|
|
||||||
<Progress value={fpd.value} max={fpd.peak} color={fpd.color} />
|
|
||||||
</Col>
|
|
||||||
{#if !fpd.dir}
|
|
||||||
<Col xs="1">
|
|
||||||
<Icon name="caret-right-fill" />
|
|
||||||
</Col>
|
|
||||||
{/if}
|
|
||||||
</Row>
|
|
||||||
{:else}
|
|
||||||
<div class="mb-1 d-flex justify-content-between">
|
|
||||||
<div>
|
|
||||||
<b>{fpd.name} ({fpd.stat})</b>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
class="cursor-help d-inline-flex"
|
|
||||||
id={`footprint-${job.jobId}-${index}`}
|
|
||||||
>
|
|
||||||
<div class="mx-1">
|
|
||||||
<Icon name="info-circle"/>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
{fpd.value}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<Tooltip
|
|
||||||
target={`footprint-${job.jobId}-${index}`}
|
|
||||||
placement="right"
|
|
||||||
>{fpd.message}</Tooltip
|
|
||||||
>
|
|
||||||
{/if}
|
|
||||||
{/each}
|
|
||||||
</CardBody>
|
|
||||||
</TabPane>
|
|
||||||
<TabPane tabId="polar" tab="Polar">
|
|
||||||
<CardBody>
|
<CardBody>
|
||||||
<Polar
|
<Polar
|
||||||
{footprintData}
|
{footprintData}
|
||||||
@ -317,19 +322,21 @@
|
|||||||
/>
|
/>
|
||||||
</CardBody>
|
</CardBody>
|
||||||
</TabPane>
|
</TabPane>
|
||||||
<TabPane tabId="summary" tab="Summary">
|
<!--
|
||||||
<CardBody>
|
<TabPane tabId="summary" tab="Summary">
|
||||||
<p>Based on footprint data, this job performs as follows:</p>
|
<CardBody>
|
||||||
<hr/>
|
<p>Based on footprint data, this job performs as follows:</p>
|
||||||
<ul>
|
<hr/>
|
||||||
{#each summaryMessages as sm}
|
<ul>
|
||||||
<li>
|
{#each summaryMessages as sm}
|
||||||
{@html sm}
|
<li>
|
||||||
</li>
|
{@html sm}
|
||||||
{/each}
|
</li>
|
||||||
</ul>
|
{/each}
|
||||||
</CardBody>
|
</ul>
|
||||||
</TabPane>
|
</CardBody>
|
||||||
|
</TabPane>
|
||||||
|
-->
|
||||||
</TabContent>
|
</TabContent>
|
||||||
</Card>
|
</Card>
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user