From 2cf046b6ff024ab1596d01c6201245d19c2122fb Mon Sep 17 00:00:00 2001 From: ricoberger Date: Mon, 26 Jul 2021 21:38:08 +0200 Subject: [PATCH] Fix variable handling for dashboards This commit adds the following fixes: - Fix variable handling for dashboards, so that a dashboard can also be used when no values are found for a variable. - Fix label for Prometheu sparkline charts, so that it doesn't show an error, when no data for a metric is received. - Fix container status in the Pod overview. --- CHANGELOG.md | 2 ++ .../src/components/dashboards/Dashboard.tsx | 3 ++- .../src/components/panel/Sparkline.tsx | 21 +++++++++++++------ .../src/components/preview/Sparkline.tsx | 21 +++++++++++++------ .../panel/details/overview/Container.tsx | 2 +- 5 files changed, 35 insertions(+), 14 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ca8ad30f3..a0437d084 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,8 @@ NOTE: As semantic versioning states all 0.y.z releases can contain breaking chan ### Fixed +- [#94](https://github.com/kobsio/kobs/pull/94): Fix variable handling for dashboards. + ### Changed - [#82](https://github.com/kobsio/kobs/pull/82): Improve error handling for our API. diff --git a/plugins/dashboards/src/components/dashboards/Dashboard.tsx b/plugins/dashboards/src/components/dashboards/Dashboard.tsx index 5c3a7e263..ad1656953 100644 --- a/plugins/dashboards/src/components/dashboards/Dashboard.tsx +++ b/plugins/dashboards/src/components/dashboards/Dashboard.tsx @@ -116,7 +116,8 @@ const Dashboard: React.FunctionComponent = ({ tmpVariables[i].value = json && json.includes(tmpVariables[i].value) ? tmpVariables[i].value : json ? json[0] : ''; } else { - throw new Error(`No values for variable ${tmpVariables[i].label || tmpVariables[i].name}`); + tmpVariables[i].values = ['']; + tmpVariables[i].value = ''; } } else { if (json.error) { diff --git a/plugins/prometheus/src/components/panel/Sparkline.tsx b/plugins/prometheus/src/components/panel/Sparkline.tsx index 5353b0e42..c8924816c 100644 --- a/plugins/prometheus/src/components/panel/Sparkline.tsx +++ b/plugins/prometheus/src/components/panel/Sparkline.tsx @@ -48,7 +48,11 @@ export const Spakrline: React.FunctionComponent = ({ const json = await response.json(); if (response.status >= 200 && response.status < 300) { - return convertMetrics(json).series; + if (json) { + return convertMetrics(json).series; + } else { + return []; + } } else { if (json.error) { throw new Error(json.error); @@ -65,11 +69,16 @@ export const Spakrline: React.FunctionComponent = ({ // Determine the label which should be shown above the chart. This is the last value in first metric of the returned // data or a value from the user specified mappings. - let label = ''; - if (data && options.mappings && Object.keys(options.mappings).length > 0) { - label = getMappingValue(data[0].data[data[0].data.length - 1].y, options.mappings); - } else if (data) { - label = `${data[0].data[data[0].data.length - 1].y} ${options.unit ? options.unit : ''}`; + let label = 'N/A'; + if (data && data.length > 0) { + if (options.mappings && Object.keys(options.mappings).length > 0) { + label = getMappingValue(data[0].data[data[0].data.length - 1].y, options.mappings); + } else { + label = + data[0].data[data[0].data.length - 1].y === null + ? 'N/A' + : `${data[0].data[data[0].data.length - 1].y} ${options.unit ? options.unit : ''}`; + } } return ( diff --git a/plugins/prometheus/src/components/preview/Sparkline.tsx b/plugins/prometheus/src/components/preview/Sparkline.tsx index e032dc93c..585595c9f 100644 --- a/plugins/prometheus/src/components/preview/Sparkline.tsx +++ b/plugins/prometheus/src/components/preview/Sparkline.tsx @@ -41,7 +41,11 @@ export const Spakrline: React.FunctionComponent = ({ const json = await response.json(); if (response.status >= 200 && response.status < 300) { - return convertMetrics(json).series; + if (json) { + return convertMetrics(json).series; + } else { + return []; + } } else { if (json.error) { throw new Error(json.error); @@ -58,11 +62,16 @@ export const Spakrline: React.FunctionComponent = ({ // Determine the label which should be shown above the chart. This is the last value in first metric of the returned // data or a value from the user specified mappings. - let label = ''; - if (data && options.mappings && Object.keys(options.mappings).length > 0) { - label = getMappingValue(data[0].data[data[0].data.length - 1].y, options.mappings); - } else if (data) { - label = `${data[0].data[data[0].data.length - 1].y} ${options.unit ? options.unit : ''}`; + let label = 'N/A'; + if (data && data.length > 0) { + if (options.mappings && Object.keys(options.mappings).length > 0) { + label = getMappingValue(data[0].data[data[0].data.length - 1].y, options.mappings); + } else { + label = + data[0].data[data[0].data.length - 1].y === null + ? 'N/A' + : `${data[0].data[data[0].data.length - 1].y} ${options.unit ? options.unit : ''}`; + } } return ( diff --git a/plugins/resources/src/components/panel/details/overview/Container.tsx b/plugins/resources/src/components/panel/details/overview/Container.tsx index b25e5605b..896165ad3 100644 --- a/plugins/resources/src/components/panel/details/overview/Container.tsx +++ b/plugins/resources/src/components/panel/details/overview/Container.tsx @@ -15,7 +15,7 @@ const getContainerStatus = (state: V1ContainerState): string => { if (state.running) { return `Started at ${state.running.startedAt}`; } else if (state.waiting) { - return `Waiting: ${state.waiting.message}`; + return state.waiting.message ? `Waiting: ${state.waiting.message}` : 'Waiting'; } else if (state.terminated) { return `Terminated with ${state.terminated.exitCode} at ${state.terminated.finishedAt}: ${state.terminated.reason}`; }