Skip to content

Commit

Permalink
feat: add data quality to kpi and status
Browse files Browse the repository at this point in the history
  • Loading branch information
jmbuss authored and ssjagad committed Mar 29, 2024
1 parent f57f091 commit 7248004
Show file tree
Hide file tree
Showing 15 changed files with 187 additions and 79 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -62,13 +62,22 @@ const RenderDisplaySettingsSection = ({
})
);

const [maybeShowDataQuality, updateShowDataQuality] = useProperty(
(properties) => properties.showDataQuality,
(properties, updatedShowDataQuality) => ({
...properties,
showDataQuality: updatedShowDataQuality,
})
);

const showName = maybeWithDefault(undefined, maybeShowName);
const showTimestamp = maybeWithDefault(undefined, maybeShowTimestamp);
const showUnit = maybeWithDefault(undefined, maybeShowUnit);
const showAggregationAndResolution = maybeWithDefault(
undefined,
maybeShowAggregationAndResolution
);
const showDataQuality = maybeWithDefault(undefined, maybeShowDataQuality);

return (
<ExpandableSection
Expand Down Expand Up @@ -109,6 +118,13 @@ const RenderDisplaySettingsSection = ({
>
Show aggregation & resolution
</Checkbox>
<Checkbox
onChange={(event) => updateShowDataQuality(event.detail.checked)}
checked={!!showDataQuality}
data-testid='show-hide-data-quality'
>
Show data quality
</Checkbox>
</FormField>
</Box>
</ExpandableSection>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ const KPIWidgetComponent: React.FC<KPIWidget> = (widget) => {
showAggregationAndResolution,
showName,
showTimestamp,
showDataQuality,
backgroundColor,
thresholds,
significantDigits: widgetSignificantDigits,
Expand Down Expand Up @@ -58,6 +59,7 @@ const KPIWidgetComponent: React.FC<KPIWidget> = (widget) => {
showValue,
showUnit,
showTimestamp,
showDataQuality,
backgroundColor,
fontSize: primaryFont.fontSize,
color: primaryFont.fontColor,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ export const kpiPlugin: DashboardPlugin = {
showTimestamp: true,
showUnit: true,
showAggregationAndResolution: true,
showDataQuality: true,
}),
initialSize: {
height: KPI_WIDGET_INITIAL_HEIGHT,
Expand Down
2 changes: 2 additions & 0 deletions packages/dashboard/src/customization/widgets/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ export type KPIProperties = QueryProperties & {
showIcon?: boolean;
showName?: boolean;
showTimestamp?: boolean;
showDataQuality?: boolean;
thresholds?: StyledThreshold[];
backgroundColor?: string;
significantDigits?: number;
Expand All @@ -66,6 +67,7 @@ export type StatusProperties = QueryProperties & {
showUnit?: boolean;
showIcon?: boolean;
showName?: boolean;
showDataQuality?: boolean;
thresholds?: StyledThreshold[];
showTimestamp?: boolean;
backgroundColor?: string;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.data-quality-text {
display: flex;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import React from 'react';
import { Quality } from '@aws-sdk/client-iotsitewise';
import Box from '@cloudscape-design/components/box';
import Icon from '@cloudscape-design/components/icon';
import {
spaceScaledXxs,
colorBackgroundStatusError,
colorBackgroundStatusWarning,
borderRadiusBadge,
colorBorderStatusError,
colorBorderStatusWarning,
spaceScaledXs,
} from '@cloudscape-design/design-tokens';

import './data-quality-text.css';

type DataQualityTextOptions = {
quality?: Quality;
};

export const DataQualityText = ({ quality }: DataQualityTextOptions) => {
// Don't show any special UX for good quality points
if (!quality || quality === 'GOOD') return null;

let icon = null;
let text = null;
let styles: React.CSSProperties = {
padding: `${spaceScaledXxs} ${spaceScaledXs}`,
border: '1px solid',
borderRadius: borderRadiusBadge,
gap: spaceScaledXxs,
};

switch (quality) {
case 'BAD':
icon = <Icon name='status-negative' variant='error' />;
text = <Box color='text-status-error'>Bad Quality</Box>;
styles = {
...styles,
borderColor: colorBorderStatusError,
backgroundColor: colorBackgroundStatusError,
};
break;
case 'UNCERTAIN':
icon = <Icon name='status-warning' variant='warning' />;
text = <Box color='text-status-warning'>Uncertain Quality</Box>;
styles = {
...styles,
borderColor: colorBorderStatusWarning,
backgroundColor: colorBackgroundStatusWarning,
};
break;
}

return (
<div
data-testid='data-quality-text'
className='data-quality data-quality-text'
>
<div className='data-quality-text' style={styles}>
{icon}
{text}
</div>
</div>
);
};
1 change: 1 addition & 0 deletions packages/react-components/src/components/kpi/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export const KPI_ICON_SHRINK_FACTOR = 0.7;
export const DEFAULT_KPI_SETTINGS: Required<KPISettings> = {
showTimestamp: true,
showUnit: true,
showDataQuality: true,
color: '#000000',
showIcon: true,
showAggregationAndResolution: true,
Expand Down
4 changes: 4 additions & 0 deletions packages/react-components/src/components/kpi/kpi.css
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,10 @@
height: 18px;
}

.kpi .data-quality {
padding: 4px 8px 2px;
}

.kpi-line-threshold {
height: 100%;
width: 16px;
Expand Down
66 changes: 66 additions & 0 deletions packages/react-components/src/components/kpi/kpiBase.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,72 @@ describe('unit', () => {
});
});

describe('data quality', () => {
const goodQualityPoint: DataPoint = { x: 1213, y: 123, quality: 'GOOD' };
const badQualityPoint: DataPoint = { x: 1213, y: 123, quality: 'BAD' };
const uncertainQualityPoint: DataPoint = {
x: 1213,
y: 123,
quality: 'UNCERTAIN',
};
const undefinedQualityPoint: DataPoint = { x: 1213, y: 123 };

it('renders quality when showDataQuality is true and provided a property point with bad quality', () => {
render(
<KpiBase
propertyPoint={badQualityPoint}
settings={{ showDataQuality: true }}
/>
);

expect(screen.queryByText('Bad quality')).toBeDefined();
});

it('renders quality when showDataQuality is true and provided a property point with uncertain quality', () => {
render(
<KpiBase
propertyPoint={uncertainQualityPoint}
settings={{ showDataQuality: true }}
/>
);

expect(screen.queryByText('Uncertain quality')).toBeDefined();
});

it('does not render quality when showDataQuality is true and it is a good quality point', () => {
render(
<KpiBase
propertyPoint={goodQualityPoint}
settings={{ showDataQuality: true }}
/>
);

expect(screen.queryByTestId('data-quality-text')).toBeNull();
});

it('does not render quality if the point quality is not defined', () => {
render(
<KpiBase
propertyPoint={undefinedQualityPoint}
settings={{ showDataQuality: true }}
/>
);

expect(screen.queryByTestId('data-quality-text')).toBeNull();
});

it('does not render quality when showDataQuality is false', () => {
render(
<KpiBase
propertyPoint={badQualityPoint}
settings={{ showDataQuality: false }}
/>
);

expect(screen.queryByText('Bad quality')).toBeNull();
});
});

describe('property value', () => {
it('renders property points y value', () => {
const Y_VALUE = 123445;
Expand Down
5 changes: 5 additions & 0 deletions packages/react-components/src/components/kpi/kpiBase.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import './kpi.css';
import { highContrastColor } from './highContrastColor';
import { getAggregationFrequency } from '../../utils/aggregationFrequency';
import { fontSizeBodyS } from '@cloudscape-design/design-tokens';
import { DataQualityText } from '../data-quality/data-quality-text';

export const KpiBase: React.FC<KPIBaseProperties> = ({
propertyPoint,
Expand All @@ -29,6 +30,7 @@ export const KpiBase: React.FC<KPIBaseProperties> = ({
showUnit,
showName,
showTimestamp,
showDataQuality,
showAggregationAndResolution,
backgroundColor,
fontSize,
Expand Down Expand Up @@ -95,6 +97,9 @@ export const KpiBase: React.FC<KPIBaseProperties> = ({
<Value value={point?.y} precision={significantDigits} />
)}
</div>
{!isLoading && showDataQuality && (
<DataQualityText quality={point?.quality} />
)}
</div>
{point && (
<div
Expand Down
1 change: 1 addition & 0 deletions packages/react-components/src/components/kpi/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export type KPISettings = {
showAggregationAndResolution: boolean;
showName: boolean;
showUnit: boolean;
showDataQuality: boolean;
fontSize: number; // pixels
secondaryFontSize: number; // pixels
backgroundColor: string; // hex string
Expand Down
1 change: 1 addition & 0 deletions packages/react-components/src/components/status/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ export type StatusSettings = {
showAggregationAndResolution: boolean;
showName: boolean;
showUnit: boolean;
showDataQuality: boolean;
fontSize: number; // pixels
secondaryFontSize: number; // pixels
backgroundColor: string; // hex string
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,20 @@ import { LoadingSpinner } from './spinner';
import { getIcons } from '../../common/iconUtils';
import type { TableColumnDefinition, TableItemHydrated } from './types';
import {
colorTextStatusError,
colorTextStatusWarning,
spaceStaticS,
spaceStaticXxs,
} from '@cloudscape-design/design-tokens';

const dataQuality = ({ quality }: { quality: DataPoint['quality'] }) => {
const color =
quality === 'BAD' ? colorTextStatusError : colorTextStatusWarning;
return (
<span
style={{
color: `${colorTextStatusWarning}`,
borderBottom: `1px dotted ${colorTextStatusWarning}`,
color,
borderBottom: `1px dotted ${color}`,
marginLeft: `${spaceStaticS}`,
}}
>
Expand Down
75 changes: 0 additions & 75 deletions packages/react-components/stories/kpi/kpiBaseUpdated.tsx

This file was deleted.

0 comments on commit 7248004

Please sign in to comment.