mirror of
https://github.com/ClusterCockpit/cc-backend
synced 2024-12-27 05:49:04 +01:00
Merge branch 'hotfix' of github.com:ClusterCockpit/cc-backend into hotfix
This commit is contained in:
commit
25acb2eaa5
@ -227,12 +227,13 @@
|
|||||||
<PlotTable
|
<PlotTable
|
||||||
let:item
|
let:item
|
||||||
let:width
|
let:width
|
||||||
|
renderFor="analysis"
|
||||||
items={metricsInHistograms.map(metric => ({ metric, ...binsFromFootprint(
|
items={metricsInHistograms.map(metric => ({ metric, ...binsFromFootprint(
|
||||||
$footprintsQuery.data.footprints.nodehours,
|
$footprintsQuery.data.footprints.nodehours,
|
||||||
$footprintsQuery.data.footprints.metrics.find(f => f.metric == metric).data, numBins) }))}
|
$footprintsQuery.data.footprints.metrics.find(f => f.metric == metric).data, numBins) }))}
|
||||||
itemsPerRow={ccconfig.plot_view_plotsPerRow}>
|
itemsPerRow={ccconfig.plot_view_plotsPerRow}>
|
||||||
<h4>Average Distribution of '{item.metric}'</h4>
|
|
||||||
|
|
||||||
|
<h4>Average Distribution of '{item.metric}'</h4>
|
||||||
<Histogram
|
<Histogram
|
||||||
width={width} height={250}
|
width={width} height={250}
|
||||||
min={item.min} max={item.max}
|
min={item.min} max={item.max}
|
||||||
|
@ -140,7 +140,7 @@
|
|||||||
width={polarPlotSize} height={polarPlotSize}
|
width={polarPlotSize} height={polarPlotSize}
|
||||||
metrics={ccconfig[`job_view_polarPlotMetrics:${$initq.data.job.cluster}`] || ccconfig[`job_view_polarPlotMetrics`]}
|
metrics={ccconfig[`job_view_polarPlotMetrics:${$initq.data.job.cluster}`] || ccconfig[`job_view_polarPlotMetrics`]}
|
||||||
cluster={$initq.data.job.cluster}
|
cluster={$initq.data.job.cluster}
|
||||||
jobMetrics={$jobMetrics.data.jobMetrics} />
|
jobMetrics={$jobMetrics.data.jobMetrics}/>
|
||||||
</Col>
|
</Col>
|
||||||
<Col>
|
<Col>
|
||||||
<Roofline
|
<Roofline
|
||||||
@ -190,6 +190,7 @@
|
|||||||
<PlotTable
|
<PlotTable
|
||||||
let:item
|
let:item
|
||||||
let:width
|
let:width
|
||||||
|
renderFor="job"
|
||||||
items={orderAndMap(groupByScope($jobMetrics.data.jobMetrics), selectedMetrics)}
|
items={orderAndMap(groupByScope($jobMetrics.data.jobMetrics), selectedMetrics)}
|
||||||
itemsPerRow={ccconfig.plot_view_plotsPerRow}>
|
itemsPerRow={ccconfig.plot_view_plotsPerRow}>
|
||||||
{#if item.data}
|
{#if item.data}
|
||||||
@ -203,7 +204,7 @@
|
|||||||
width={width}
|
width={width}
|
||||||
isShared={($initq.data.job.exclusive != 1)}/>
|
isShared={($initq.data.job.exclusive != 1)}/>
|
||||||
{:else}
|
{:else}
|
||||||
<Card body color="warning">No data for <code>{item.metric}</code></Card>
|
<Card body color="warning">No dataset returned for <code>{item.metric}</code></Card>
|
||||||
{/if}
|
{/if}
|
||||||
</PlotTable>
|
</PlotTable>
|
||||||
{/if}
|
{/if}
|
||||||
|
@ -24,6 +24,16 @@
|
|||||||
export let type;
|
export let type;
|
||||||
export let filterPresets;
|
export let filterPresets;
|
||||||
|
|
||||||
|
// By default, look at the jobs of the last 30 days:
|
||||||
|
if (filterPresets?.startTime == null) {
|
||||||
|
if (filterPresets == null)
|
||||||
|
filterPresets = {}
|
||||||
|
|
||||||
|
const lastMonth = (new Date(Date.now() - (30*24*60*60*1000))).toISOString()
|
||||||
|
const now = (new Date(Date.now())).toISOString()
|
||||||
|
filterPresets.startTime = { from: lastMonth, to: now, text: 'Last 30 Days', url: 'last30d' }
|
||||||
|
}
|
||||||
|
|
||||||
console.assert(
|
console.assert(
|
||||||
type == "USER" || type == "PROJECT",
|
type == "USER" || type == "PROJECT",
|
||||||
"Invalid list type provided!"
|
"Invalid list type provided!"
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<script>
|
<script>
|
||||||
import { init } from './utils.js'
|
import { init, checkMetricDisabled } from './utils.js'
|
||||||
import { Row, Col, InputGroup, InputGroupText, Icon, Spinner, Card } from 'sveltestrap'
|
import { Row, Col, InputGroup, InputGroupText, Icon, Spinner, Card } from 'sveltestrap'
|
||||||
import { queryStore, gql, getContextClient } from '@urql/svelte'
|
import { queryStore, gql, getContextClient } from '@urql/svelte'
|
||||||
import TimeSelection from './filters/TimeSelection.svelte'
|
import TimeSelection from './filters/TimeSelection.svelte'
|
||||||
@ -100,13 +100,23 @@
|
|||||||
<PlotTable
|
<PlotTable
|
||||||
let:item
|
let:item
|
||||||
let:width
|
let:width
|
||||||
|
renderFor="node"
|
||||||
itemsPerRow={ccconfig.plot_view_plotsPerRow}
|
itemsPerRow={ccconfig.plot_view_plotsPerRow}
|
||||||
items={$nodesQuery.data.nodeMetrics[0].metrics.sort((a, b) => a.name.localeCompare(b.name))}>
|
items={$nodesQuery.data.nodeMetrics[0].metrics
|
||||||
|
.map(m => ({ ...m, disabled: checkMetricDisabled(m.name, cluster, $nodesQuery.data.nodeMetrics[0].subCluster)}))
|
||||||
|
.sort((a, b) => a.name.localeCompare(b.name))}>
|
||||||
|
|
||||||
<h4 style="text-align: center; padding-top:15px;">{item.name} {metricUnits[item.name]}</h4>
|
<h4 style="text-align: center; padding-top:15px;">{item.name} {metricUnits[item.name]}</h4>
|
||||||
|
{#if item.disabled === false && item.metric}
|
||||||
<MetricPlot
|
<MetricPlot
|
||||||
width={width} height={300} metric={item.name} timestep={item.metric.timestep}
|
width={width} height={300} metric={item.name} timestep={item.metric.timestep}
|
||||||
cluster={clusters.find(c => c.name == cluster)} subCluster={$nodesQuery.data.nodeMetrics[0].subCluster}
|
cluster={clusters.find(c => c.name == cluster)} subCluster={$nodesQuery.data.nodeMetrics[0].subCluster}
|
||||||
series={item.metric.series} />
|
series={item.metric.series} />
|
||||||
|
{:else if item.disabled === true && item.metric}
|
||||||
|
<Card style="margin-left: 2rem;margin-right: 2rem;" body color="info">Metric disabled for subcluster <code>{item.name}:{$nodesQuery.data.nodeMetrics[0].subCluster}</code></Card>
|
||||||
|
{:else}
|
||||||
|
<Card style="margin-left: 2rem;margin-right: 2rem;" body color="warning">No dataset returned for <code>{item.name}</code></Card>
|
||||||
|
{/if}
|
||||||
</PlotTable>
|
</PlotTable>
|
||||||
{/if}
|
{/if}
|
||||||
</Col>
|
</Col>
|
||||||
|
@ -10,7 +10,9 @@
|
|||||||
export let itemsPerRow
|
export let itemsPerRow
|
||||||
export let items
|
export let items
|
||||||
export let padding = 10
|
export let padding = 10
|
||||||
|
export let renderFor
|
||||||
|
|
||||||
|
let rows = []
|
||||||
let tableWidth = 0
|
let tableWidth = 0
|
||||||
const isPlaceholder = x => x._is_placeholder === true
|
const isPlaceholder = x => x._is_placeholder === true
|
||||||
|
|
||||||
@ -30,8 +32,13 @@
|
|||||||
return rows
|
return rows
|
||||||
}
|
}
|
||||||
|
|
||||||
// Analysis Implements PlotTable: Disable flag can not be present, add to row if not defined explicitly (Helps with systems view also)
|
|
||||||
$: rows = tile(items.filter(item => (item.disabled !== null && item.disabled === false)), itemsPerRow)
|
$: if (renderFor === 'job') {
|
||||||
|
rows = tile(items.filter(item => item.disabled === false), itemsPerRow)
|
||||||
|
} else {
|
||||||
|
rows = tile(items, itemsPerRow)
|
||||||
|
}
|
||||||
|
|
||||||
$: plotWidth = (tableWidth / itemsPerRow) - (padding * itemsPerRow)
|
$: plotWidth = (tableWidth / itemsPerRow) - (padding * itemsPerRow)
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<script>
|
<script>
|
||||||
import { init } from './utils.js'
|
import { init, checkMetricDisabled } from './utils.js'
|
||||||
import { Row, Col, Input, InputGroup, InputGroupText, Icon, Spinner, Card } from 'sveltestrap'
|
import { Row, Col, Input, InputGroup, InputGroupText, Icon, Spinner, Card } from 'sveltestrap'
|
||||||
import { queryStore, gql, getContextClient } from '@urql/svelte'
|
import { queryStore, gql, getContextClient } from '@urql/svelte'
|
||||||
import TimeSelection from './filters/TimeSelection.svelte'
|
import TimeSelection from './filters/TimeSelection.svelte'
|
||||||
@ -114,25 +114,21 @@
|
|||||||
<PlotTable
|
<PlotTable
|
||||||
let:item
|
let:item
|
||||||
let:width
|
let:width
|
||||||
|
renderFor="systems"
|
||||||
itemsPerRow={ccconfig.plot_view_plotsPerRow}
|
itemsPerRow={ccconfig.plot_view_plotsPerRow}
|
||||||
items={$nodesQuery.data.nodeMetrics
|
items={$nodesQuery.data.nodeMetrics
|
||||||
.filter(h => h.host.includes(hostnameFilter) && h.metrics.some(m => m.name == selectedMetric && m.scope == 'node'))
|
.filter(h => h.host.includes(hostnameFilter) && h.metrics.some(m => m.name == selectedMetric && m.scope == 'node'))
|
||||||
.map(function (h) {
|
.map(h => ({
|
||||||
let thisConfig = metricConfig(cluster, selectedMetric)
|
host: h.host,
|
||||||
let thisSCIndex = thisConfig.subClusters.findIndex(sc => sc.name == h.subCluster)
|
subCluster: h.subCluster,
|
||||||
// Metric remove == true
|
data: h.metrics.find(m => m.name == selectedMetric && m.scope == 'node'),
|
||||||
if (thisSCIndex >= 0) {
|
disabled: checkMetricDisabled(selectedMetric, cluster, h.subCluster)
|
||||||
if (thisConfig.subClusters[thisSCIndex].remove == true) {
|
}))
|
||||||
return { host: h.host, subCluster: h.subCluster, data: null, removed: true }
|
.sort((a, b) => a.host.localeCompare(b.host))
|
||||||
}
|
}>
|
||||||
}
|
|
||||||
// Else
|
|
||||||
return { host: h.host, subCluster: h.subCluster, data: h.metrics.find(m => m.name == selectedMetric && m.scope == 'node'), removed: false }
|
|
||||||
})
|
|
||||||
.sort((a, b) => a.host.localeCompare(b.host))}>
|
|
||||||
|
|
||||||
<h4 style="width: 100%; text-align: center;"><a style="display: block;padding-top: 15px;" href="/monitoring/node/{cluster}/{item.host}">{item.host} ({item.subCluster})</a></h4>
|
<h4 style="width: 100%; text-align: center;"><a style="display: block;padding-top: 15px;" href="/monitoring/node/{cluster}/{item.host}">{item.host} ({item.subCluster})</a></h4>
|
||||||
{#if item.removed == false && item.data != null}
|
{#if item.disabled === false && item.data}
|
||||||
<MetricPlot
|
<MetricPlot
|
||||||
width={width}
|
width={width}
|
||||||
height={plotHeight}
|
height={plotHeight}
|
||||||
@ -141,10 +137,10 @@
|
|||||||
metric={item.data.name}
|
metric={item.data.name}
|
||||||
cluster={clusters.find(c => c.name == cluster)}
|
cluster={clusters.find(c => c.name == cluster)}
|
||||||
subCluster={item.subCluster} />
|
subCluster={item.subCluster} />
|
||||||
{:else if item.removed == true && item.data == null}
|
{:else if item.disabled === true && item.data}
|
||||||
<Card body color="info">Metric '{ selectedMetric }' disabled for subcluster '{ item.subCluster }'</Card>
|
<Card style="margin-left: 2rem;margin-right: 2rem;" body color="info">Metric disabled for subcluster <code>{selectedMetric}:{item.subCluster}</code></Card>
|
||||||
{:else}
|
{:else}
|
||||||
<Card body color="warning">Missing Full Dataset</Card>
|
<Card style="margin-left: 2rem;margin-right: 2rem;" body color="warning">No dataset returned for <code>{selectedMetric}</code></Card>
|
||||||
{/if}
|
{/if}
|
||||||
</PlotTable>
|
</PlotTable>
|
||||||
{/if}
|
{/if}
|
||||||
|
@ -120,7 +120,11 @@
|
|||||||
for (let state of filters.states)
|
for (let state of filters.states)
|
||||||
opts.push(`state=${state}`)
|
opts.push(`state=${state}`)
|
||||||
if (filters.startTime.from && filters.startTime.to)
|
if (filters.startTime.from && filters.startTime.to)
|
||||||
|
// if (filters.startTime.url) {
|
||||||
|
// opts.push(`startTime=${filters.startTime.url}`)
|
||||||
|
// } else {
|
||||||
opts.push(`startTime=${dateToUnixEpoch(filters.startTime.from)}-${dateToUnixEpoch(filters.startTime.to)}`)
|
opts.push(`startTime=${dateToUnixEpoch(filters.startTime.from)}-${dateToUnixEpoch(filters.startTime.to)}`)
|
||||||
|
// }
|
||||||
for (let tag of filters.tags)
|
for (let tag of filters.tags)
|
||||||
opts.push(`tag=${tag}`)
|
opts.push(`tag=${tag}`)
|
||||||
if (filters.duration.from && filters.duration.to)
|
if (filters.duration.from && filters.duration.to)
|
||||||
@ -193,16 +197,18 @@
|
|||||||
<DropdownItem divider/>
|
<DropdownItem divider/>
|
||||||
<DropdownItem disabled>Start Time Qick Selection</DropdownItem>
|
<DropdownItem disabled>Start Time Qick Selection</DropdownItem>
|
||||||
{#each [
|
{#each [
|
||||||
{ text: 'Last 6hrs', seconds: 6*60*60 },
|
{ text: 'Last 6hrs', url: 'last6h', seconds: 6*60*60 },
|
||||||
{ text: 'Last 12hrs', seconds: 12*60*60 },
|
// { text: 'Last 12hrs', seconds: 12*60*60 },
|
||||||
{ text: 'Last 24hrs', seconds: 24*60*60 },
|
{ text: 'Last 24hrs', url: 'last24h', seconds: 24*60*60 },
|
||||||
{ text: 'Last 48hrs', seconds: 48*60*60 },
|
// { text: 'Last 48hrs', seconds: 48*60*60 },
|
||||||
{ text: 'Last 7 days', seconds: 7*24*60*60 },
|
{ text: 'Last 7 days', url: 'last7d', seconds: 7*24*60*60 },
|
||||||
{ text: 'Last 30 days', seconds: 30*24*60*60 }
|
{ text: 'Last 30 days', url: 'last30d', seconds: 30*24*60*60 }
|
||||||
] as {text, seconds}}
|
] as {text, url, seconds}}
|
||||||
<DropdownItem on:click={() => {
|
<DropdownItem on:click={() => {
|
||||||
filters.startTime.from = (new Date(Date.now() - seconds * 1000)).toISOString()
|
filters.startTime.from = (new Date(Date.now() - seconds * 1000)).toISOString()
|
||||||
filters.startTime.to = (new Date(Date.now())).toISOString()
|
filters.startTime.to = (new Date(Date.now())).toISOString()
|
||||||
|
filters.startTime.text = text,
|
||||||
|
filters.startTime.url = url
|
||||||
update()
|
update()
|
||||||
}}>
|
}}>
|
||||||
<Icon name="calendar-range"/> {text}
|
<Icon name="calendar-range"/> {text}
|
||||||
@ -212,27 +218,6 @@
|
|||||||
</DropdownMenu>
|
</DropdownMenu>
|
||||||
</ButtonDropdown>
|
</ButtonDropdown>
|
||||||
</Col>
|
</Col>
|
||||||
<!-- {#if startTimeQuickSelect}
|
|
||||||
<Col xs="auto">
|
|
||||||
<TimeSelection customEnabled={false} anyEnabled={true}
|
|
||||||
from={filters.startTime.from ? new Date(filters.startTime.from) : null}
|
|
||||||
to={filters.startTime.to ? new Date(filters.startTime.to) : null}
|
|
||||||
options={{
|
|
||||||
'Last 6hrs': 6*60*60,
|
|
||||||
'Last 12hrs': 12*60*60,
|
|
||||||
'Last 24hrs': 24*60*60,
|
|
||||||
'Last 48hrs': 48*60*60,
|
|
||||||
'Last 7 days': 7*24*60*60,
|
|
||||||
'Last 30 days': 30*24*60*60}}
|
|
||||||
on:change={({ detail: { from, to } }) => {
|
|
||||||
filters.startTime.from = from?.toISOString()
|
|
||||||
filters.startTime.to = to?.toISOString()
|
|
||||||
// console.log(filters.startTime)
|
|
||||||
update()
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</Col>
|
|
||||||
{/if} -->
|
|
||||||
<Col xs="auto">
|
<Col xs="auto">
|
||||||
{#if filters.cluster}
|
{#if filters.cluster}
|
||||||
<Info icon="cpu" on:click={() => (isClusterOpen = true)}>
|
<Info icon="cpu" on:click={() => (isClusterOpen = true)}>
|
||||||
@ -251,7 +236,11 @@
|
|||||||
|
|
||||||
{#if filters.startTime.from || filters.startTime.to}
|
{#if filters.startTime.from || filters.startTime.to}
|
||||||
<Info icon="calendar-range" on:click={() => (isStartTimeOpen = true)}>
|
<Info icon="calendar-range" on:click={() => (isStartTimeOpen = true)}>
|
||||||
|
{#if filters.startTime.text}
|
||||||
|
{filters.startTime.text}
|
||||||
|
{:else}
|
||||||
{new Date(filters.startTime.from).toLocaleString()} - {new Date(filters.startTime.to).toLocaleString()}
|
{new Date(filters.startTime.from).toLocaleString()} - {new Date(filters.startTime.to).toLocaleString()}
|
||||||
|
{/if}
|
||||||
</Info>
|
</Info>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
@ -307,7 +296,11 @@
|
|||||||
bind:isOpen={isStartTimeOpen}
|
bind:isOpen={isStartTimeOpen}
|
||||||
bind:from={filters.startTime.from}
|
bind:from={filters.startTime.from}
|
||||||
bind:to={filters.startTime.to}
|
bind:to={filters.startTime.to}
|
||||||
on:update={() => update()} />
|
on:update={() => {
|
||||||
|
delete filters.startTime['text']
|
||||||
|
delete filters.startTime['url']
|
||||||
|
update()
|
||||||
|
}} />
|
||||||
|
|
||||||
<Duration
|
<Duration
|
||||||
bind:isOpen={isDurationOpen}
|
bind:isOpen={isDurationOpen}
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
import { Card, Spinner } from "sveltestrap";
|
import { Card, Spinner } from "sveltestrap";
|
||||||
import MetricPlot from "../plots/MetricPlot.svelte";
|
import MetricPlot from "../plots/MetricPlot.svelte";
|
||||||
import JobInfo from "./JobInfo.svelte";
|
import JobInfo from "./JobInfo.svelte";
|
||||||
import { maxScope } from "../utils.js";
|
import { maxScope, checkMetricDisabled } from "../utils.js";
|
||||||
|
|
||||||
export let job;
|
export let job;
|
||||||
export let metrics;
|
export let metrics;
|
||||||
@ -85,56 +85,17 @@
|
|||||||
jobMetrics[0]
|
jobMetrics[0]
|
||||||
);
|
);
|
||||||
|
|
||||||
const sortAndSelectScope = (jobMetrics) =>
|
|
||||||
metrics
|
const sortAndSelectScope = (jobMetrics) => metrics
|
||||||
.map(function (name) {
|
.map(name => jobMetrics.filter(jobMetric => jobMetric.name == name))
|
||||||
// Get MetricConf for this selected/requested metric
|
.map(jobMetrics => ({ disabled: false, data: jobMetrics.length > 0 ? selectScope(jobMetrics) : null }))
|
||||||
let thisConfig = metricConfig(cluster, name);
|
.map(jobMetric => {
|
||||||
let thisSCIndex = -1
|
if (jobMetric.data) {
|
||||||
if (thisConfig) {
|
return { disabled: checkMetricDisabled(jobMetric.data.name, job.cluster, job.subCluster), data: jobMetric.data }
|
||||||
thisSCIndex = thisConfig.subClusters.findIndex(
|
|
||||||
(sc) => sc.name == job.subCluster
|
|
||||||
);
|
|
||||||
};
|
|
||||||
// Check if Subcluster has MetricConf: If not found (index == -1), no further remove flag check required
|
|
||||||
if (thisSCIndex >= 0) {
|
|
||||||
// SubCluster Config present: Check if remove flag is set
|
|
||||||
if (thisConfig.subClusters[thisSCIndex].remove == true) {
|
|
||||||
// Return null data and informational flag
|
|
||||||
return { removed: true, data: null };
|
|
||||||
} else {
|
} else {
|
||||||
// load and return metric, if data available
|
return jobMetric
|
||||||
let thisMetric = jobMetrics.filter(
|
|
||||||
(jobMetric) => jobMetric.name == name
|
|
||||||
); // Returns Array
|
|
||||||
if (thisMetric.length > 0) {
|
|
||||||
return { removed: false, data: thisMetric };
|
|
||||||
} else {
|
|
||||||
return { removed: false, data: null };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// No specific subCluster config: 'remove' flag not set, deemed false -> load and return metric, if data available
|
|
||||||
let thisMetric = jobMetrics.filter(
|
|
||||||
(jobMetric) => jobMetric.name == name
|
|
||||||
); // Returns Array
|
|
||||||
if (thisMetric.length > 0) {
|
|
||||||
return { removed: false, data: thisMetric };
|
|
||||||
} else {
|
|
||||||
return { removed: false, data: null };
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.map(function (jobMetrics) {
|
|
||||||
if (jobMetrics.data != null && jobMetrics.data.length > 0) {
|
|
||||||
return {
|
|
||||||
removed: jobMetrics.removed,
|
|
||||||
data: selectScope(jobMetrics.data),
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
return jobMetrics;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if (job.monitoringStatus) refresh();
|
if (job.monitoringStatus) refresh();
|
||||||
</script>
|
</script>
|
||||||
@ -163,7 +124,7 @@
|
|||||||
{#each sortAndSelectScope($metricsQuery.data.jobMetrics) as metric, i (metric || i)}
|
{#each sortAndSelectScope($metricsQuery.data.jobMetrics) as metric, i (metric || i)}
|
||||||
<td>
|
<td>
|
||||||
<!-- Subluster Metricconfig remove keyword for jobtables (joblist main, user joblist, project joblist) to be used here as toplevel case-->
|
<!-- Subluster Metricconfig remove keyword for jobtables (joblist main, user joblist, project joblist) to be used here as toplevel case-->
|
||||||
{#if metric.removed == false && metric.data != null}
|
{#if metric.disabled == false && metric.data}
|
||||||
<MetricPlot
|
<MetricPlot
|
||||||
width={plotWidth}
|
width={plotWidth}
|
||||||
height={plotHeight}
|
height={plotHeight}
|
||||||
@ -176,12 +137,10 @@
|
|||||||
subCluster={job.subCluster}
|
subCluster={job.subCluster}
|
||||||
isShared={(job.exclusive != 1)}
|
isShared={(job.exclusive != 1)}
|
||||||
/>
|
/>
|
||||||
{:else if metric.removed == true && metric.data == null}
|
{:else if metric.disabled == true && metric.data}
|
||||||
<Card body color="info"
|
<Card body color="info">Metric disabled for subcluster <code>{metric.data.name}:{job.subCluster}</code></Card>
|
||||||
>Metric disabled for subcluster '{job.subCluster}'</Card
|
|
||||||
>
|
|
||||||
{:else}
|
{:else}
|
||||||
<Card body color="warning">Missing Full Dataset</Card>
|
<Card body color="warning">No dataset returned</Card>
|
||||||
{/if}
|
{/if}
|
||||||
</td>
|
</td>
|
||||||
{/each}
|
{/each}
|
||||||
|
@ -320,7 +320,7 @@
|
|||||||
{#if series[0].data.length > 0}
|
{#if series[0].data.length > 0}
|
||||||
<div bind:this={plotWrapper} class="cc-plot"></div>
|
<div bind:this={plotWrapper} class="cc-plot"></div>
|
||||||
{:else}
|
{:else}
|
||||||
<Card style="margin-left: 2rem;margin-right: 2rem;" body color="warning">Cannot render plot: No series data found for <code>{metric}</code></Card>
|
<Card style="margin-left: 2rem;margin-right: 2rem;" body color="warning">Cannot render plot: No series data returned for <code>{metric}</code></Card>
|
||||||
{/if}
|
{/if}
|
||||||
<style>
|
<style>
|
||||||
.cc-plot {
|
.cc-plot {
|
||||||
|
Loading…
Reference in New Issue
Block a user