Skip to content

Commit

Permalink
feat: surface warehouse reconciliation errors in DAG
Browse files Browse the repository at this point in the history
Signed-off-by: Remington Breeze <remington@breeze.software>
  • Loading branch information
rbreeze committed Apr 2, 2024
1 parent 0e8f38e commit e0adb98
Show file tree
Hide file tree
Showing 10 changed files with 124 additions and 83 deletions.
77 changes: 41 additions & 36 deletions ui/src/features/common/freight-label.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,15 @@
import { faCheck, faClipboard } from '@fortawesome/free-solid-svg-icons';
import { faBoxOpen, faCheck, faClipboard } from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { Tooltip } from 'antd';
import { formatDistance } from 'date-fns';
import { useEffect, useState } from 'react';

import { Freight } from '@ui/gen/v1alpha1/generated_pb';

const ALIAS_LABEL_KEY = 'kargo.akuity.io/alias';

export const getAlias = (freight?: Freight): string | undefined => {
return freight?.metadata?.labels[ALIAS_LABEL_KEY] || undefined;
};
import { getAlias } from './utils';

export const FreightLabel = ({ freight }: { freight?: Freight }) => {
const [id, setId] = useState<string>('');
const [id, setId] = useState<string | undefined>();
const [alias, setAlias] = useState<string | undefined>();
const [copied, setCopied] = useState<boolean>(false);

Expand All @@ -25,43 +21,52 @@ export const FreightLabel = ({ freight }: { freight?: Freight }) => {
}, [copied]);

useEffect(() => {
setAlias(freight?.metadata?.labels[ALIAS_LABEL_KEY]);
setId(freight?.metadata?.name?.substring(0, 7) || 'N/A');
setAlias(getAlias(freight));
setId(freight?.metadata?.name?.substring(0, 7));
}, [freight]);

return (
<div
className='truncate cursor-pointer'
className='truncate cursor-pointer font-mono font-semibold'
onClick={() => {
navigator.clipboard.writeText(alias || id);
setCopied(true);
if (alias || id) {
navigator.clipboard.writeText(alias || id || '');
setCopied(true);
}
}}
>
<Tooltip
title={
<>
<div className='uppercase text-xs w-full text-center font-semibold text-gray-400'>
<FontAwesomeIcon icon={copied ? faCheck : faClipboard} className='mr-2' />
{copied ? 'Copied' : `Click to copy ${alias ? 'alias' : 'id'}`}
</div>
{alias && <Info title='Alias'>{alias}</Info>}
<Info title='ID'>
<div className='font-mono'>{id}</div>
</Info>
{freight?.metadata?.creationTimestamp && (
<Info title='Created'>
<div className='text-right'>
{formatDistance(freight?.metadata?.creationTimestamp?.toDate(), new Date(), {
addSuffix: true
})}
</div>
{alias || id ? (
<Tooltip
title={
<>
<div className='uppercase text-xs w-full text-center font-semibold text-gray-400'>
<FontAwesomeIcon icon={copied ? faCheck : faClipboard} className='mr-2' />
{copied ? 'Copied' : `Click to copy ${alias ? 'alias' : 'id'}`}
</div>
{alias && <Info title='Alias'>{alias}</Info>}
<Info title='ID'>
<div className='font-mono'>{id}</div>
</Info>
)}
</>
}
>
<div className='hover:text-gray-100'>{alias || id}</div>
</Tooltip>
{freight?.metadata?.creationTimestamp && (
<Info title='Created'>
<div className='text-right'>
{formatDistance(freight?.metadata?.creationTimestamp?.toDate(), new Date(), {
addSuffix: true
})}
</div>
</Info>
)}
</>
}
>
<div className='hover:text-gray-600'>{alias || id}</div>
</Tooltip>
) : (
<div className='flex items-center'>
<FontAwesomeIcon icon={faBoxOpen} className='mr-2' />
EMPTY
</div>
)}
</div>
);
};
Expand Down
7 changes: 7 additions & 0 deletions ui/src/features/common/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { Freight } from '@ui/gen/v1alpha1/generated_pb';

export const ALIAS_LABEL_KEY = 'kargo.akuity.io/alias';

export const getAlias = (freight?: Freight): string | undefined => {
return freight?.metadata?.labels[ALIAS_LABEL_KEY] || undefined;
};
9 changes: 1 addition & 8 deletions ui/src/features/freightline/freight-item.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,10 @@ import classNames from 'classnames';
import { Freight } from '@ui/gen/v1alpha1/generated_pb';

import { FreightLabel } from '../common/freight-label';
import { FreightMode } from '../project/project-details/types';

import styles from './freightline.module.less';

export enum FreightMode {
Default = 'default', // not promoting, has stages
Promotable = 'promotable', // promoting, promotable
Disabled = 'disabled',
Selected = 'selected',
Confirming = 'confirming' // promoting, confirming
}

export const FreightItem = ({
freight,
children,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,34 +7,44 @@
height: 100%;

h3 {
padding: 0.4em 0.5em;
padding: 0.5em;
color: #333;
font-size: 15px;
font-weight: 600;
margin-left: 0.25em;
margin-left: 0.1em;
margin-bottom: 0;
}

.repoLabel {
color: gray;
font-size: 10px;
margin-bottom: 0.75em;
font-weight: 600;
}
}

.body {
background-color: white;
border-bottom-left-radius: 10px;
border-bottom-right-radius: 10px;
padding: 8px;
font-size: 12px;
flex: 1;
display: flex;
@apply items-center justify-center;
}

.value {
display: block;
display: flex;
margin-top: 3px;
color: #777;
font-size: 11px;
text-decoration: none;
white-space: nowrap;
overflow-x: hidden;
padding-bottom: 0.25em;
text-overflow: ellipsis;
color: black;
font-weight: 600;
font-size: 14px;
@apply font-mono items-center justify-center;

&:hover {
text-decoration: underline;
Expand Down
32 changes: 25 additions & 7 deletions ui/src/features/project/project-details/nodes/repo-node.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
import { faDocker, faGit } from '@fortawesome/free-brands-svg-icons';
import { faAnchor, faBuilding, faCircleNotch } from '@fortawesome/free-solid-svg-icons';
import {
faAnchor,
faBuilding,
faCircleNotch,
faExclamationCircle,
faExternalLinkAlt
} from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { Tooltip } from 'antd';

Expand Down Expand Up @@ -27,23 +33,35 @@ export const RepoNode = ({ nodeData, children }: Props) => {
type === NodeType.REPO_CHART
? nodeData?.data?.repoURL || ''
: type === NodeType.WAREHOUSE
? nodeData?.data
? nodeData?.data?.metadata?.name || ''
: nodeData?.data?.repoURL || '';
return (
<div className={styles.node}>
<h3 className='flex justify-between gap-2'>
<div className='text-ellipsis whitespace-nowrap overflow-x-hidden pb-1'>
{nodeData.type === NodeType.WAREHOUSE ? nodeData.data : 'Subscription'}
<div className='text-ellipsis whitespace-nowrap overflow-x-hidden py-1'>
{nodeData.type === NodeType.WAREHOUSE ? nodeData.data?.metadata?.name : 'Subscription'}
</div>
<div className='flex items-center'>
{nodeData.refreshing && <FontAwesomeIcon icon={faCircleNotch} spin className='mr-2' />}
{nodeData.type === NodeType.WAREHOUSE && nodeData?.data?.status?.message && (
<Tooltip
title={
<div className='flex items-center'>
<FontAwesomeIcon icon={faExclamationCircle} className='mr-2' />
{nodeData?.data?.status?.message}
</div>
}
>
<FontAwesomeIcon icon={faExclamationCircle} className='mr-1 text-red-600' />
</Tooltip>
)}
{type && <FontAwesomeIcon icon={ico[type]} />}
</div>
</h3>
<div className={styles.body}>
{nodeData.type !== NodeType.WAREHOUSE && (
<div className='mb-2'>
Repo URL
<div className='text-center'>
<div className={styles.repoLabel}>REPO URL</div>
<Tooltip title={value}>
<a
href={
Expand All @@ -55,12 +73,12 @@ export const RepoNode = ({ nodeData, children }: Props) => {
target='_blank'
rel='noreferrer'
>
<FontAwesomeIcon icon={faExternalLinkAlt} size='sm' className='mr-2' />
{value}
</a>
</Tooltip>
</div>
)}

{children}
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
transition: all 0.2s ease-in-out;

h3 {
padding: 0.7em 0.75em;
padding: 0.75em;
color: white;
font-weight: 600;
font-size: 15px;
Expand All @@ -22,14 +22,15 @@
text-align: center;
display: flex;
flex-direction: column;
}

h3 {
margin-top: 0.5em;
margin-bottom: 0.25em;
color: gray;
text-transform: uppercase;
font-size: 0.5em;
}
.freightLabel {
margin: 0;
margin-bottom: 0.5em;
color: gray;
text-transform: uppercase;
font-size: 10px;
font-weight: 600;
}
}

Expand Down
10 changes: 4 additions & 6 deletions ui/src/features/project/project-details/nodes/stage-node.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -105,12 +105,10 @@ export const StageNode = ({
APPROVE
</div>
) : (
<>
<h3>Current Freight</h3>
<div className='font-mono text-sm font-semibold h-full flex items-center justify-center'>
<FreightLabel freight={currentFreight} />
</div>
</>
<div className='text-sm h-full flex flex-col items-center justify-center -mt-1'>
<div className={styles.freightLabel}>CURRENT FREIGHT</div>
<FreightLabel freight={currentFreight} />
</div>
)}
</div>
{!approving && (
Expand Down
19 changes: 10 additions & 9 deletions ui/src/features/project/project-details/project-details.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,11 @@ import { useParams } from 'react-router-dom';
import { transportWithAuth } from '@ui/config/transport';
import { ColorContext } from '@ui/context/colors';
import { LoadingState } from '@ui/features/common';
import { getAlias } from '@ui/features/common/freight-label';
import { useModal } from '@ui/features/common/modal/use-modal';
import { getAlias } from '@ui/features/common/utils';
import { ConfirmPromotionDialogue } from '@ui/features/freightline/confirm-promotion-dialogue';
import { FreightContents } from '@ui/features/freightline/freight-contents';
import { FreightItem, FreightMode } from '@ui/features/freightline/freight-item';
import { FreightItem } from '@ui/features/freightline/freight-item';
import { Freightline } from '@ui/features/freightline/freightline';
import { FreightlineHeader } from '@ui/features/freightline/freightline-header';
import { StageIndicators } from '@ui/features/freightline/stage-indicators';
Expand All @@ -53,6 +53,7 @@ import { RepoNode } from './nodes/repo-node';
import { Nodule, StageNode } from './nodes/stage-node';
import styles from './project-details.module.less';
import {
FreightMode,
FreightlineAction,
NewWarehouseNode,
NodeType,
Expand All @@ -65,8 +66,8 @@ const lineThickness = 2;
const nodeWidth = 150;
const nodeHeight = 118;

const warehouseNodeWidth = 150;
const warehouseNodeHeight = 100;
const warehouseNodeWidth = 165;
const warehouseNodeHeight = 110;

const getSeconds = (ts?: Time): number => Number(ts?.seconds) || 0;

Expand Down Expand Up @@ -326,7 +327,7 @@ export const ProjectDetails = () => {
}
});

layout(g, { lablepos: 'c' });
layout(g, { labelpos: 'c' });

const nodes = myNodes.map((node, index) => {
const gNode = g.node(String(index));
Expand Down Expand Up @@ -795,8 +796,8 @@ export const ProjectDetails = () => {
</>
) : (
<RepoNode nodeData={node}>
<div className='flex w-full h-full'>
{node.type === NodeType.WAREHOUSE && (
{node.type === NodeType.WAREHOUSE && (
<div className='flex w-full h-full'>
<Button
onClick={() =>
refreshWarehouseAction({
Expand All @@ -810,8 +811,8 @@ export const ProjectDetails = () => {
>
Refresh
</Button>
)}
</div>
</div>
)}
{node.type === NodeType.WAREHOUSE && (
<Nodule
nodeHeight={warehouseNodeHeight}
Expand Down
12 changes: 10 additions & 2 deletions ui/src/features/project/project-details/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ export type NodesRepoType = (
}
| {
type: NodeType.WAREHOUSE;
data: string;
data: Warehouse;
}
) &
NodeBase;
Expand All @@ -51,7 +51,7 @@ export type NodesItemType =
export const NewWarehouseNode = (warehouse: Warehouse, stageNames?: string[]): NodesRepoType => {
const name = warehouse?.metadata?.name || '';
return {
data: name,
data: warehouse,
stageNames: stageNames || [],
warehouseName: name,
refreshing: !!warehouse?.metadata?.annotations['kargo.akuity.io/refresh'],
Expand All @@ -60,3 +60,11 @@ export const NewWarehouseNode = (warehouse: Warehouse, stageNames?: string[]): N
};

export type FreightlineAction = 'promote' | 'promoteSubscribers' | 'manualApproval';

export enum FreightMode {
Default = 'default', // not promoting, has stages
Promotable = 'promotable', // promoting, promotable
Disabled = 'disabled',
Selected = 'selected',
Confirming = 'confirming' // promoting, confirming
}
Loading

0 comments on commit e0adb98

Please sign in to comment.