Skip to content

Commit

Permalink
feat: Add resources graph into overview page (#63)
Browse files Browse the repository at this point in the history
Jira: EPMDEDP-12704
Related: #63
Change-Id: I8a9f2db0aea41dca35751ebba759b7b5de7ea857
  • Loading branch information
callmevladik committed Oct 3, 2023
1 parent f735b0b commit 4d0f0c9
Show file tree
Hide file tree
Showing 17 changed files with 535 additions and 33 deletions.
34 changes: 34 additions & 0 deletions src/components/NewStatusIcon/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { Icon } from '@iconify/react';
import { Tooltip } from '@material-ui/core';
import clsx from 'clsx';
import React from 'react';
import { useStyles } from './styles';
import { StatusIconProps } from './types';

const stopPropagation = (e: React.SyntheticEvent) => e.stopPropagation();

export const NewStatusIcon = ({
Title,
icon,
color,
isRotating = false,
width = 25,
}: StatusIconProps) => {
const classes = useStyles();

return (
// eslint-disable-next-line jsx-a11y/click-events-have-key-events,jsx-a11y/no-static-element-interactions
<div onClick={stopPropagation}>
<Tooltip title={Title} interactive>
<Icon
icon={icon}
color={color}
width={width}
className={clsx(classes.icon, {
[classes.rotateIcon]: isRotating,
})}
/>
</Tooltip>
</div>
);
};
20 changes: 20 additions & 0 deletions src/components/NewStatusIcon/styles.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { makeStyles } from '@material-ui/core';

export const useStyles = makeStyles(() => ({
icon: {
willChange: 'transform',
display: 'block',
lineHeight: 0,
},
rotateIcon: {
animation: '$spin 2s linear infinite',
},
'@keyframes spin': {
'0%': {
transform: 'rotate(360deg)',
},
'100%': {
transform: 'rotate(0deg)',
},
},
}));
9 changes: 9 additions & 0 deletions src/components/NewStatusIcon/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import React from 'react';

export interface StatusIconProps {
Title: string | React.ReactElement;
icon: string;
color: string;
isRotating?: boolean;
width?: number;
}
33 changes: 33 additions & 0 deletions src/k8s/PipelineRun/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { SelectOption } from '../../types/forms';

export const PIPELINE_RUN_REASON = {
STARTED: 'Started',
RUNNING: 'Running',
CANCELLED: 'Cancelled',
SUCCEEDED: 'Succeeded',
COMPLETED: 'Completed',
FAILED: 'Failed',
PIPELINE_RUN_TIMEOUT: 'PipelineRunTimeout',
CREATE_RUN_FAILED: 'CreateRunFailed',
} as const;

export const PIPELINE_RUN_STATUS = {
TRUE: 'True',
FALSE: 'False',
UNKNOWN: 'Unknown',
} as const;

export const PIPELINE_RUN_STATUS_SELECT_OPTIONS: SelectOption[] = [
{
label: 'Success',
value: PIPELINE_RUN_STATUS.TRUE,
},
{
label: 'Failure',
value: PIPELINE_RUN_STATUS.FALSE,
},
{
label: PIPELINE_RUN_STATUS.UNKNOWN,
value: PIPELINE_RUN_STATUS.UNKNOWN,
},
];
18 changes: 18 additions & 0 deletions src/k8s/PipelineRun/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
StreamAutotestsPipelineRunListProps,
StreamPipelineRunListByCodebaseBranchLabelProps,
StreamPipelineRunListByTypeAndPipelineNameLabelsProps,
StreamPipelineRunListByTypeLabelProps,
} from './types';

const {
Expand Down Expand Up @@ -92,4 +93,21 @@ export class PipelineRunKubeObject extends K8s.cluster.makeKubeObject<PipelineRu
labelSelector: `${PIPELINE_RUN_LABEL_SELECTOR_PARENT_PIPELINE_RUN}=${parentPipelineRunName},${PIPELINE_RUN_LABEL_SELECTOR_STAGE}=${stageSpecName},${PIPELINE_RUN_LABEL_SELECTOR_PIPELINE}=${CDPipelineMetadataName}`,
});
}

static streamPipelineRunListByTypeLabel({
namespace,
type,
dataHandler,
errorHandler,
}: StreamPipelineRunListByTypeLabelProps): () => void {
const url = `/apis/${group}/${version}/namespaces/${namespace}/${pluralForm}`;

if (type) {
return streamResults(url, dataHandler, errorHandler, {
labelSelector: `${PIPELINE_RUN_LABEL_SELECTOR_PIPELINE_TYPE}=${type}`,
});
}

return streamResults(url, dataHandler, errorHandler);
}
}
8 changes: 8 additions & 0 deletions src/k8s/PipelineRun/types.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { KubeObjectInterface } from '@kinvolk/headlamp-plugin/lib/lib/k8s/cluster';
import { PIPELINE_TYPES } from '../../constants/pipelineTypes';

export interface PipelineRunKubeObjectInterface extends KubeObjectInterface {}

Expand Down Expand Up @@ -33,3 +34,10 @@ export interface StreamAutotestsPipelineRunListProps {
dataHandler: (data: PipelineRunKubeObjectInterface[]) => void;
errorHandler: (err: Error) => void;
}

export interface StreamPipelineRunListByTypeLabelProps {
namespace: string;
type: PIPELINE_TYPES;
dataHandler: (data: PipelineRunKubeObjectInterface[]) => void;
errorHandler: (err: Error) => void;
}
27 changes: 27 additions & 0 deletions src/k8s/PipelineRun/utils/getStatusInfo/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { ICONS } from '../../../../icons/iconify-icons-mapping';
import { STATUSES_COLORS } from '../../../../utils/styling/getCustomResourceStatusIconByStatusName';
import { PIPELINE_RUN_REASON, PIPELINE_RUN_STATUS } from '../../constants';

export const getStatusIcon = (status: string, reason: string): [string, string, boolean?] => {
switch (status) {
case PIPELINE_RUN_STATUS.UNKNOWN:
if (reason === PIPELINE_RUN_REASON.STARTED) {
return [ICONS.LOADER_CIRCLE, STATUSES_COLORS.IN_PROGRESS, true];
}

if (reason === PIPELINE_RUN_REASON.RUNNING) {
return [ICONS.LOADER_CIRCLE, STATUSES_COLORS.IN_PROGRESS, true];
}

if (reason === PIPELINE_RUN_REASON.CANCELLED) {
return [ICONS.CROSS_CIRCLE, STATUSES_COLORS.ERROR];
}
break;
case PIPELINE_RUN_STATUS.TRUE:
return [ICONS.CHECK_CIRCLE, STATUSES_COLORS.SUCCESS];
case PIPELINE_RUN_STATUS.FALSE:
return [ICONS.CROSS_CIRCLE, STATUSES_COLORS.ERROR];
default:
return [ICONS.UNKNOWN, STATUSES_COLORS.UNKNOWN];
}
};
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@ import { HoverInfoLabel } from '@kinvolk/headlamp-plugin/lib/components/common';
import { Link } from '@material-ui/core';
import React from 'react';
import { useParams } from 'react-router-dom';
import { StatusIcon } from '../../../../../../../components/StatusIcon';
import { NewStatusIcon } from '../../../../../../../components/NewStatusIcon';
import { TableColumn } from '../../../../../../../components/Table/types';
import { useEDPComponentsURLsQuery } from '../../../../../../../k8s/EDPComponent/hooks/useEDPComponentsURLsQuery';
import { PipelineRunKubeObjectInterface } from '../../../../../../../k8s/PipelineRun/types';
import { getStatusIcon } from '../../../../../../../k8s/PipelineRun/utils/getStatusInfo';
import { GENERATE_URL_SERVICE } from '../../../../../../../services/url';
import { formatFullYear, humanizeDefault } from '../../../../../../../utils/date/humanize';
import { parseTektonResourceStatus } from '../../../../../../../utils/parseTektonResourceStatus';
import { EDPComponentDetailsRouteParams } from '../../../../../types';

export const usePipelineRunsColumns = (): TableColumn<PipelineRunKubeObjectInterface>[] => {
Expand All @@ -21,13 +21,18 @@ export const usePipelineRunsColumns = (): TableColumn<PipelineRunKubeObjectInter
id: 'status',
label: 'Status',
render: resource => {
const status = parseTektonResourceStatus(resource);
const status = resource?.status?.conditions?.[0]?.status;
const reason = resource?.status?.conditions?.[0]?.reason;

const [icon, color, isRotating] = getStatusIcon(status, reason);

return (
<StatusIcon
status={status}
<NewStatusIcon
icon={icon}
color={color}
isRotating={isRotating}
width={25}
customTitle={`Pipeline run status: ${status}`}
Title={`Status: ${status}. Reason: ${reason}`}
/>
);
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,17 @@ import React from 'react';
import { CUSTOM_RESOURCE_STATUSES } from '../../../../constants/statuses';
import { EDPCDPipelineKubeObject } from '../../../../k8s/EDPCDPipeline';
import { PipelineRunKubeObjectInterface } from '../../../../k8s/PipelineRun/types';
import { getDefaultNamespace } from '../../../../utils/getDefaultNamespace';

export const CDPipelinesGraph = () => {
const [CDPipelinesInfo, setCDPipelinesInfo] = React.useState<{
total: number;
green: number;
red: number;
}>({
total: 0,
green: 0,
red: 0,
total: null,
green: null,
red: null,
});
const [, setError] = React.useState<unknown>(null);
EDPCDPipelineKubeObject.useApiList(
Expand All @@ -35,12 +36,15 @@ export const CDPipelinesGraph = () => {

setCDPipelinesInfo(newCDPipelinesInfo);
},
error => setError(error)
error => setError(error),
{
namespace: getDefaultNamespace(),
}
);

return (
<TileChart
total={CDPipelinesInfo.total === 0 ? -1 : CDPipelinesInfo.total}
total={CDPipelinesInfo.total === null ? -1 : CDPipelinesInfo.total}
data={[
{
name: 'OK',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,17 @@ import React from 'react';
import { CUSTOM_RESOURCE_STATUSES } from '../../../../constants/statuses';
import { EDPCodebaseBranchKubeObject } from '../../../../k8s/EDPCodebaseBranch';
import { EDPCodebaseBranchKubeObjectInterface } from '../../../../k8s/EDPCodebaseBranch/types';
import { getDefaultNamespace } from '../../../../utils/getDefaultNamespace';

export const CodebaseBranchesGraph = () => {
const [codebaseBranchesInfo, setCodebaseBranchesInfo] = React.useState<{
total: number;
green: number;
red: number;
}>({
total: 0,
green: 0,
red: 0,
total: null,
green: null,
red: null,
});
const [, setError] = React.useState<unknown>(null);
EDPCodebaseBranchKubeObject.useApiList(
Expand All @@ -35,12 +36,15 @@ export const CodebaseBranchesGraph = () => {

setCodebaseBranchesInfo(newCodebaseBranchesInfo);
},
error => setError(error)
error => setError(error),
{
namespace: getDefaultNamespace(),
}
);

return (
<TileChart
total={codebaseBranchesInfo.total}
total={codebaseBranchesInfo.total === null ? -1 : codebaseBranchesInfo.total}
data={[
{
name: 'OK',
Expand Down
14 changes: 9 additions & 5 deletions src/pages/edp-overview-list/components/CodebasesGraph/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,17 @@ import React from 'react';
import { CUSTOM_RESOURCE_STATUSES } from '../../../../constants/statuses';
import { EDPCodebaseKubeObject } from '../../../../k8s/EDPCodebase';
import { EDPCodebaseKubeObjectInterface } from '../../../../k8s/EDPCodebase/types';
import { getDefaultNamespace } from '../../../../utils/getDefaultNamespace';

export const CodebasesGraph = () => {
const [codebasesInfo, setCodebasesInfo] = React.useState<{
total: number;
green: number;
red: number;
}>({
total: 0,
green: 0,
red: 0,
total: null,
green: null,
red: null,
});
const [, setError] = React.useState<unknown>(null);
EDPCodebaseKubeObject.useApiList(
Expand All @@ -35,12 +36,15 @@ export const CodebasesGraph = () => {

setCodebasesInfo(newCodebasesInfo);
},
error => setError(error)
error => setError(error),
{
namespace: getDefaultNamespace(),
}
);

return (
<TileChart
total={codebasesInfo.total}
total={codebasesInfo.total === null ? -1 : codebasesInfo.total}
data={[
{
name: 'OK',
Expand Down
Loading

0 comments on commit 4d0f0c9

Please sign in to comment.