Skip to content

[NCL-9065] Fix missing legend label for charts and Introduce color map for element colors #647

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 56 additions & 0 deletions src/common/colorMap.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { LabelProps } from '@patternfly/react-core';

/* See PF5 color palettes: https://v5-archive.patternfly.org/design-foundations/colors#patternfly-palettes */
export interface LabelConfig {
text: string;
color: LabelProps['color']; // PatternFly label semantic color
hexColor: string; // Exact hex code for charts/UI
}

export const buildTypeColorMap: Record<string, LabelConfig> = {
MVN: { text: 'MVN', color: 'gold', hexColor: '#F9E0A2' }, // gold-100
NPM: { text: 'NPM', color: 'purple', hexColor: '#CBC1FF' }, // purple-100
GRADLE: { text: 'GRADLE', color: 'cyan', hexColor: '#A2D9D9' }, // cyan-100
SBT: { text: 'SBT', color: 'grey', hexColor: '#D2D2D2' }, // black-300
};

export const artifactQualityColorMap: Record<string, LabelConfig> = {
NEW: { text: 'NEW', color: 'grey', hexColor: '#B8BBBE' }, // black-400
VERIFIED: { text: 'VERIFIED', color: 'blue', hexColor: '#BEE1F4' }, // blue-100
TESTED: { text: 'TESTED', color: 'green', hexColor: '#BDE5B8' }, // green-100
DEPRECATED: { text: 'DEPRECATED', color: 'orange', hexColor: '#F4B678' }, // orange-100
BLACKLISTED: { text: 'BLACKLISTED', color: 'red', hexColor: '#C9190B' }, // red-100
DELETED: { text: 'DELETED', color: 'red', hexColor: '#7D1007' }, // red-300
TEMPORARY: { text: 'TEMPORARY', color: 'cyan', hexColor: '#A2D9D9' }, // cyan-100
IMPORTED: { text: 'IMPORTED', color: 'grey', hexColor: '#F0F0F0' }, // black-200
};

export const repositoryTypeColorMap: Record<string, LabelConfig> = {
MAVEN: { text: 'MAVEN', color: 'gold', hexColor: '#F9E0A2' }, // gold-100
GENERIC_PROXY: { text: 'GENERIC_PROXY', color: 'grey', hexColor: '#D2D2D2' }, // black-300
NPM: { text: 'NPM', color: 'purple', hexColor: '#CBC1FF' }, // purple-100
COCOA_POD: { text: 'COCOA_POD', color: 'cyan', hexColor: '#A2D9D9' }, // cyan-100
DISTRIBUTION_ARCHIVE: { text: 'DISTRIBUTION_ARCHIVE', color: 'red', hexColor: '#C9190B' }, // red-100
};

export const operationProgressStatusColorMap: Record<string, LabelConfig> = {
NEW: { text: 'NEW', color: 'grey', hexColor: '#F0F0F0' }, // black-200
PENDING: { text: 'PENDING', color: 'grey', hexColor: '#B8BBBE' }, // black-400
IN_PROGRESS: { text: 'IN PROGRESS', color: 'blue', hexColor: '#BEE1F4' }, // blue-100
FINISHED: { text: 'FINISHED', color: 'green', hexColor: '#BDE5B8' }, // green-100
};

export const deliverableAnalysisColorMap: Record<string, LabelConfig> = {
DELETED: { text: 'DELETED', color: 'red', hexColor: '#C9190B' }, // red-100
SCRATCH: { text: 'SCRATCH', color: 'grey', hexColor: '#D2D2D2' }, // black-300
RELEASED: { text: 'RELEASED', color: 'blue', hexColor: '#BEE1F4' }, // blue-100
};

export const operationResultColorMap: Record<string, LabelConfig> = {
SUCCESSFUL: { text: 'SUCCESSFUL', color: 'green', hexColor: '#BDE5B8' }, // green-100
FAILED: { text: 'FAILED', color: 'orange', hexColor: '#F4B678' }, // orange-100
REJECTED: { text: 'REJECTED', color: 'orange', hexColor: '#EF9234' }, // orange-300
CANCELLED: { text: 'CANCELLED', color: 'grey', hexColor: '#B8BBBE' }, // black-400
TIMEOUT: { text: 'TIMEOUT', color: 'grey', hexColor: '#D2D2D2' }, // black-300
SYSTEM_ERROR: { text: 'SYSTEM_ERROR', color: 'red', hexColor: '#C9190B' }, // red-100
};
16 changes: 12 additions & 4 deletions src/components/Charts/DoughnutChart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { dougnutCenterPlugin, legendHeightPlugin } from 'libs/chartJsPlugins';
export interface IDoughnutChartProps {
data: number[];
labels: string[];
colors?: string[];
id?: string;
description?: IDescription;
legendHeight?: number;
Expand All @@ -19,19 +20,25 @@ export interface IDoughnutChartProps {
*
* @param data - Chart data
* @param labels - Chart data labels
* @param colors - Background colors for the chart data
* @param id - ID of canvas
* @param description - Description to be displayed in help icon
* @param legendHeight - Legend height
*/
export const DoughnutChart = ({ data, labels, id, description, legendHeight = 100 }: IDoughnutChartProps) => {
export const DoughnutChart = ({ data, labels, colors, id, description, legendHeight = 100 }: IDoughnutChartProps) => {
const chart = useRef<Chart>();
const chartRef = useRef<HTMLCanvasElement>(null);

useEffect(() => {
const chartConfig: ChartConfiguration = {
type: 'doughnut',
data: {
datasets: [{ data }],
datasets: [
{
data,
backgroundColor: colors?.map((color) => color ?? '#CCCCCC'),
},
],
labels,
},
options: {
Expand All @@ -48,8 +55,9 @@ export const DoughnutChart = ({ data, labels, id, description, legendHeight = 10
plugins: {
legend: {
position: 'bottom',
maxHeight: legendHeight * 4,
labels: {
padding: 25,
padding: 15,
color: 'black',
font: {
size: 15,
Expand All @@ -74,7 +82,7 @@ export const DoughnutChart = ({ data, labels, id, description, legendHeight = 10
chart.current.config.options = chartConfig.options;
chart.current.update();
}
}, [data, labels, legendHeight]);
}, [data, labels, colors, legendHeight]);

return (
<ChartBox description={description}>
Expand Down
11 changes: 7 additions & 4 deletions src/components/Charts/StackedBarChart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ interface IStackedBarChartDataset {
export interface IStackedBarChartProps {
data: IStackedBarChartDataset[];
labels: string[];
colors?: string[];
id?: string;
description?: IDescription;
legendHeight?: number;
Expand All @@ -32,11 +33,12 @@ export interface IStackedBarChartProps {
*
* @param data - Chart data
* @param labels - Labels of stacked rows
* @param colors - Background colors for the chart data
* @param id - ID of canvas
* @param description - Description to be displayed in help icon
* @param legendHeight - Legend height
*/
export const StackedBarChart = ({ data, labels, id, description, legendHeight = 100 }: IStackedBarChartProps) => {
export const StackedBarChart = ({ data, labels, colors, id, description, legendHeight = 100 }: IStackedBarChartProps) => {
const chart = useRef<Chart>();
const chartRef = useRef<HTMLCanvasElement>(null);

Expand All @@ -45,7 +47,7 @@ export const StackedBarChart = ({ data, labels, id, description, legendHeight =
type: 'bar',
data: {
datasets: data.map((dataset: IStackedBarChartDataset, index: number) => {
return { ...dataset, backgroundColor: COLORS[index % COLORS.length] };
return { ...dataset, backgroundColor: colors ? colors[index] : COLORS[index % COLORS.length] };
}),
labels: labels,
},
Expand All @@ -70,8 +72,9 @@ export const StackedBarChart = ({ data, labels, id, description, legendHeight =
plugins: {
legend: {
position: 'bottom',
maxHeight: legendHeight * 4,
labels: {
padding: 25,
padding: 15,
color: 'black',
font: {
size: 15,
Expand All @@ -96,7 +99,7 @@ export const StackedBarChart = ({ data, labels, id, description, legendHeight =
chart.current.config.options = chartConfig.options;
chart.current.update();
}
}, [data, labels, legendHeight]);
}, [data, labels, colors, legendHeight]);

return (
<ChartBox description={description}>
Expand Down
44 changes: 6 additions & 38 deletions src/components/LabelMapper/ArtifactQualityLabelMapper.tsx
Original file line number Diff line number Diff line change
@@ -1,46 +1,14 @@
import { Artifact } from 'pnc-api-types-ts';

import { ILabelMapper, LabelMapper } from 'components/LabelMapper/LabelMapper';
import { artifactQualityColorMap } from 'common/colorMap';

const ARTIFACT_QUALITIES: ILabelMapper<Artifact['artifactQuality']> = {
NEW: {
text: 'NEW',
color: 'grey',
},
VERIFIED: {
text: 'VERIFIED',
color: 'blue',
},
TESTED: {
text: 'TESTED',
color: 'green',
},
DEPRECATED: {
text: 'DEPRECATED',
color: 'orange',
},
BLACKLISTED: {
text: 'BLACKLISTED',
color: 'red',
},
DELETED: {
text: 'DELETED',
color: 'red',
},
TEMPORARY: {
text: 'TEMPORARY',
color: 'cyan',
},
IMPORTED: {
text: 'IMPORTED',
color: 'grey',
},
};
import { LabelMapper } from 'components/LabelMapper/LabelMapper';

interface IArtifactQualityLabelMapperProps {
quality: Artifact['artifactQuality'];
}

export const ArtifactQualityLabelMapper = ({ quality }: IArtifactQualityLabelMapperProps) => (
<LabelMapper mapperItem={ARTIFACT_QUALITIES[quality]} />
);
export const ArtifactQualityLabelMapper = ({ quality }: IArtifactQualityLabelMapperProps) => {
const config = artifactQualityColorMap[quality] ?? { text: quality };
return <LabelMapper mapperItem={config} />;
};
34 changes: 8 additions & 26 deletions src/components/LabelMapper/ArtifactRepositoryTypeLabelMapper.tsx
Original file line number Diff line number Diff line change
@@ -1,34 +1,16 @@
import { TargetRepository } from 'pnc-api-types-ts';

import { ILabelMapper, LabelMapper } from 'components/LabelMapper/LabelMapper';
import { repositoryTypeColorMap } from 'common/colorMap';

const ARTIFACT_REPOSITORY_TYPES: ILabelMapper<TargetRepository['repositoryType']> = {
MAVEN: {
text: 'MAVEN',
color: 'gold',
},
GENERIC_PROXY: {
text: 'GENERIC_PROXY',
color: 'grey',
},
NPM: {
text: 'NPM',
color: 'purple',
},
COCOA_POD: {
text: 'COCOA_POD',
color: 'cyan',
},
DISTRIBUTION_ARCHIVE: {
text: 'DISTRIBUTION_ARCHIVE',
color: 'red',
},
};
import { LabelMapper } from 'components/LabelMapper/LabelMapper';

interface IArtifactRepositoryTypeLabelMapperProps {
repositoryType: TargetRepository['repositoryType'];
}

export const ArtifactRepositoryTypeLabelMapper = ({ repositoryType }: IArtifactRepositoryTypeLabelMapperProps) => (
<LabelMapper mapperItem={ARTIFACT_REPOSITORY_TYPES[repositoryType]} />
);
export const ArtifactRepositoryTypeLabelMapper = ({ repositoryType }: IArtifactRepositoryTypeLabelMapperProps) => {
const config = repositoryTypeColorMap[repositoryType] ?? {
text: repositoryType,
};
return <LabelMapper mapperItem={config} />;
};
28 changes: 6 additions & 22 deletions src/components/LabelMapper/BuildConfigBuildTypeLabelMapper.tsx
Original file line number Diff line number Diff line change
@@ -1,30 +1,14 @@
import { BuildConfiguration } from 'pnc-api-types-ts';

import { ILabelMapper, LabelMapper } from 'components/LabelMapper/LabelMapper';
import { buildTypeColorMap } from 'common/colorMap';

const BUILD_CONFIG_BUILD_TYPES: ILabelMapper<BuildConfiguration['buildType']> = {
MVN: {
text: 'MVN',
color: 'gold',
},
NPM: {
text: 'NPM',
color: 'purple',
},
GRADLE: {
text: 'GRADLE',
color: 'cyan',
},
SBT: {
text: 'SBT',
color: 'grey',
},
};
import { LabelMapper } from 'components/LabelMapper/LabelMapper';

interface IBuildConfigBuildTypeLabelMapperProps {
buildType: BuildConfiguration['buildType'];
}

export const BuildConfigBuildTypeLabelMapper = ({ buildType }: IBuildConfigBuildTypeLabelMapperProps) => (
<LabelMapper mapperItem={BUILD_CONFIG_BUILD_TYPES[buildType]} />
);
export const BuildConfigBuildTypeLabelMapper = ({ buildType }: IBuildConfigBuildTypeLabelMapperProps) => {
const config = buildTypeColorMap[buildType] ?? { text: buildType };
return <LabelMapper mapperItem={config} />;
};
26 changes: 7 additions & 19 deletions src/components/LabelMapper/DeliverableAnalysisLabelLabelMapper.tsx
Original file line number Diff line number Diff line change
@@ -1,29 +1,17 @@
import { DeliverableAnalyzerReport } from 'pnc-api-types-ts';

import { ILabelMapper, LabelMapper } from 'components/LabelMapper/LabelMapper';
import { deliverableAnalysisColorMap } from 'common/colorMap';

type deliverableAnalysisLabel = Exclude<DeliverableAnalyzerReport['labels'], undefined>[number];
import { LabelMapper } from 'components/LabelMapper/LabelMapper';

const DELIVERABLE_ANALYSIS_LABELS: ILabelMapper<deliverableAnalysisLabel> = {
DELETED: {
text: 'DELETED',
color: 'red',
},
SCRATCH: {
text: 'SCRATCH',
color: 'grey',
},
RELEASED: {
text: 'RELEASED',
color: 'blue',
},
};
type deliverableAnalysisLabel = Exclude<DeliverableAnalyzerReport['labels'], undefined>[number];

interface IDeliverableAnalysisLabelLabelMapperProps {
label: deliverableAnalysisLabel;
onRemove?: () => void;
}

export const DeliverableAnalysisLabelLabelMapper = ({ label, onRemove }: IDeliverableAnalysisLabelLabelMapperProps) => (
<LabelMapper mapperItem={DELIVERABLE_ANALYSIS_LABELS[label]} onRemove={onRemove} />
);
export const DeliverableAnalysisLabelLabelMapper = ({ label, onRemove }: IDeliverableAnalysisLabelLabelMapperProps) => {
const config = deliverableAnalysisColorMap[label] ?? { text: label };
return <LabelMapper mapperItem={config} onRemove={onRemove} />;
};
15 changes: 9 additions & 6 deletions src/components/LabelMapper/LabelMapper.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { uiLogger } from 'services/uiLogger';

interface ILabelMapperItem {
text: string;
color: LabelPropsPF['color'];
color?: LabelPropsPF['color'];
}

export type ILabelMapper<Types> = {
Expand All @@ -27,12 +27,15 @@ interface ILabelMapperProps {
export const LabelMapper = ({ mapperItem, onRemove }: ILabelMapperProps) => {
if (!mapperItem) {
uiLogger.error(`Error attempting to get mapper item: mapper item undefined`);
return <EmptyStateSymbol text={false} />;
}
return mapperItem ? (
<LabelPF color={mapperItem.color} onClose={onRemove}>
{mapperItem.text}

const { text, color } = mapperItem;
const safeColor = color ?? 'grey';

return (
<LabelPF color={safeColor} onClose={onRemove}>
{text}
</LabelPF>
) : (
<EmptyStateSymbol text={false} />
);
};
Loading