Skip to content

Commit

Permalink
fix(ui): better display multiple freight in one stage node (akuity#2353)
Browse files Browse the repository at this point in the history
Signed-off-by: Remington Breeze <remington@breeze.software>
  • Loading branch information
rbreeze authored Aug 5, 2024
1 parent 7d5b229 commit a01f049
Show file tree
Hide file tree
Showing 14 changed files with 287 additions and 138 deletions.
33 changes: 33 additions & 0 deletions ui/src/features/common/commit-info.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { GitCommit } from '@ui/gen/v1alpha1/generated_pb';

export const CommitInfo = ({ commit }: { commit: GitCommit }) => (
<div className='grid grid-cols-2'>
<div>Repo:</div>
<div>
<a href={commit.repoURL}>{commit.repoURL}</a>
</div>
{commit.branch ? (
<>
<div>Branch:</div>
<div>{commit.branch}</div>
</>
) : commit.tag ? (
<>
<div>Tag:</div>
<div>{commit.tag}</div>
</>
) : null}
{commit.author && (
<>
<div>Author:</div>
<div>{commit.author}</div>
</>
)}
{commit.message && (
<>
<div>Message:</div>
<div>{commit.message}</div>
</>
)}
</div>
);
35 changes: 2 additions & 33 deletions ui/src/features/freight-timeline/freight-contents.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { Tooltip } from 'antd';
import classNames from 'classnames';

import { Freight, GitCommit } from '@ui/gen/v1alpha1/generated_pb';
import { Freight } from '@ui/gen/v1alpha1/generated_pb';
import { urlForImage } from '@ui/utils/url';

import { CommitInfo } from '../common/commit-info';
import { TruncateMiddle } from '../common/truncate-middle';

export const FreightContents = (props: {
Expand Down Expand Up @@ -100,35 +101,3 @@ export const FreightContents = (props: {
</div>
);
};

const CommitInfo = ({ commit }: { commit: GitCommit }) => (
<div className='grid grid-cols-2'>
<div>Repo:</div>
<div>
<a href={commit.repoURL}>{commit.repoURL}</a>
</div>
{commit.branch ? (
<>
<div>Branch:</div>
<div>{commit.branch}</div>
</>
) : commit.tag ? (
<>
<div>Tag:</div>
<div>{commit.tag}</div>
</>
) : null}
{commit.author && (
<>
<div>Author:</div>
<div>{commit.author}</div>
</>
)}
{commit.message && (
<>
<div>Message:</div>
<div>{commit.message}</div>
</>
)}
</div>
);
Original file line number Diff line number Diff line change
@@ -1,27 +1,14 @@
import { faBoxOpen, faCheck, faClipboard } from '@fortawesome/free-solid-svg-icons';
import { faCheck, faClipboard } from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { Tooltip } from 'antd';
import classNames from 'classnames';
import { format, formatDistance } from 'date-fns';
import { useEffect, useState } from 'react';

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

import { FreightContents } from '../freight-timeline/freight-contents';
import { getAlias } from '../common/utils';

import { getAlias } from './utils';

export const FreightLabel = ({
freight,
showTimestamp,
breakOnHyphen,
showContents
}: {
freight?: Freight;
showTimestamp?: boolean;
breakOnHyphen?: boolean;
showContents?: boolean;
}) => {
export const FreightItemLabel = ({ freight }: { freight?: Freight }) => {
const [copied, setCopied] = useState<boolean>(false);

useEffect(() => {
Expand Down Expand Up @@ -52,18 +39,18 @@ export const FreightLabel = ({
);

return (
<div
className='cursor-pointer font-mono font-semibold min-w-0 w-full'
onClick={(e) => {
if (alias || id) {
e.preventDefault();
e.stopPropagation();
navigator.clipboard.writeText(alias || id || '');
setCopied(true);
}
}}
>
{alias || id ? (
(alias || id) && (
<div
className='cursor-pointer font-mono font-semibold min-w-0 w-full'
onClick={(e) => {
if (alias || id) {
e.preventDefault();
e.stopPropagation();
navigator.clipboard.writeText(alias || id || '');
setCopied(true);
}
}}
>
<Tooltip
overlayStyle={{ maxWidth: '320px' }}
placement='right'
Expand All @@ -85,36 +72,18 @@ export const FreightLabel = ({
</div>
</Info>
)}
{showContents && (
<div className='mt-2'>
<FreightContents
freight={freight}
horizontal={true}
highlighted={false}
dark={true}
/>
</div>
)}
</>
}
>
<div
className={classNames('hover:text-gray-600 w-full', {
'h-8 flex justify-center items-end': breakOnHyphen
})}
className={'hover:text-gray-600 w-full h-8 flex justify-center items-end'}
style={{ padding: '0 3px' }}
>
<div className='truncate'>{(breakOnHyphen ? aliasLabel : alias) || id}</div>
{showTimestamp && <div className='text-xs text-gray-400 mt-1'>{humanReadable}</div>}
<div className='truncate'>{aliasLabel || id}</div>
</div>
</Tooltip>
) : (
<div className='flex items-center justify-center'>
<FontAwesomeIcon icon={faBoxOpen} className='mr-2' />
EMPTY
</div>
)}
</div>
</div>
)
);
};

Expand Down
4 changes: 2 additions & 2 deletions ui/src/features/freight-timeline/freight-item.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ import classNames from 'classnames';

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

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

import { FreightItemLabel } from './freight-item-label';
import styles from './freight-timeline.module.less';

export const FreightItem = ({
Expand Down Expand Up @@ -52,7 +52,7 @@ export const FreightItem = ({
mode === FreightMode.Confirming ? 'text-black' : 'text-gray-400'
}`}
>
{!hideLabel && <FreightLabel freight={freight} breakOnHyphen={true} />}
{!hideLabel && <FreightItemLabel freight={freight} />}
</div>
</div>
</div>
Expand Down
46 changes: 46 additions & 0 deletions ui/src/features/project/pipelines/nodes/freight-indicators.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { Tooltip } from 'antd';
import classNames from 'classnames';
import { useContext } from 'react';

import { ColorContext } from '@ui/context/colors';
import { getAlias } from '@ui/features/common/utils';
import { Freight } from '@ui/gen/v1alpha1/generated_pb';

export const FreightIndicators = ({
freight,
selectedFreight,
onClick
}: {
freight?: Freight[];
selectedFreight: number;
onClick: (index: number) => void;
}) => {
const { warehouseColorMap } = useContext(ColorContext);

if (!freight || freight.length <= 1) {
return null;
}

return (
<div className='flex gap-2 justify-center items-center py-1 absolute top-1'>
{freight.map((freight, idx) => (
<Tooltip placement='right' title={getAlias(freight)} key={freight?.metadata?.name || idx}>
<div
className={classNames('rounded-full mb-2 opacity-50 hover:opacity-30', {
'!opacity-100': selectedFreight === idx
})}
style={{
width: '10px',
height: '10px',
backgroundColor: warehouseColorMap[freight?.warehouse || '']
}}
onClick={(e) => {
e.stopPropagation();
onClick(idx);
}}
/>
</Tooltip>
))}
</div>
);
};
96 changes: 96 additions & 0 deletions ui/src/features/project/pipelines/nodes/freight-label.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
import { faDocker, faGitAlt } from '@fortawesome/free-brands-svg-icons';
import { faAnchor } from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { Tooltip } from 'antd';
import { format, formatDistance } from 'date-fns';
import { useEffect, useState } from 'react';

import { CommitInfo } from '@ui/features/common/commit-info';
import { Freight } from '@ui/gen/v1alpha1/generated_pb';

import { getAlias } from '../../../common/utils';

import style from './stage-node.module.less';

export const FreightLabel = ({ freight }: { freight?: Freight }) => {
const [copied, setCopied] = useState<boolean>(false);

useEffect(() => {
if (copied) {
const timeout = setTimeout(() => setCopied(false), 1000);
return () => clearTimeout(timeout);
}
}, [copied]);

const id = freight?.metadata?.name?.substring(0, 7);
const alias = getAlias(freight);

const humanReadable = formatDistance(
freight?.metadata?.creationTimestamp?.toDate() || 0,
new Date(),
{
addSuffix: true
}
);

return (
<div
className='cursor-pointer font-semibold min-w-0 w-full'
onClick={(e) => {
if (alias || id) {
e.preventDefault();
e.stopPropagation();
navigator.clipboard.writeText(alias || id || '');
setCopied(true);
}
}}
>
{alias || id ? (
<>
<Tooltip
className='w-full font-mono'
style={{ padding: '0 3px' }}
title={`ID: ${id}`}
placement='right'
>
<div className='truncate'>{alias || id}</div>
</Tooltip>
{freight?.metadata?.creationTimestamp && (
<Tooltip
title={format(freight?.metadata?.creationTimestamp.toDate(), 'MMM do yyyy HH:mm:ss')}
className={style.smallLabel}
placement='right'
>
Created {humanReadable}
</Tooltip>
)}
<div className='flex items-center gap-1 my-1 justify-center text-gray-500'>
{(freight?.images || []).map((image) => {
const key = `${image.repoURL}:${image?.tag}`;
return (
<Tooltip key={key} title={key} placement='bottom'>
<FontAwesomeIcon icon={faDocker} />
</Tooltip>
);
})}
{(freight?.commits || []).map((commit) => (
<Tooltip key={commit.id} title={<CommitInfo commit={commit} />} placement='bottom'>
<FontAwesomeIcon icon={faGitAlt} />
</Tooltip>
))}
{(freight?.charts || []).map((chart) => {
const key = chart.repoURL;
return (
<Tooltip key={key} title={key} placement='bottom'>
<FontAwesomeIcon icon={faAnchor} />
</Tooltip>
);
})}
</div>
</>
) : (
<div className='flex items-center justify-center text-gray-400'>NO FREIGHT</div>
)}
</div>
);
};
8 changes: 7 additions & 1 deletion ui/src/features/project/pipelines/nodes/repo-node.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,16 @@ import { ColorContext } from '@ui/context/colors';
import { urlForImage } from '@ui/utils/url';

import { MessageTooltip } from '../message-tooltip';
import { NodeType, RepoNodeType } from '../types';
import { NodeDimensions, NodeType, RepoNodeType } from '../types';

import * as styles from './repo-node.module.less';

export const RepoNodeDimensions = () =>
({
width: 185,
height: 110
}) as NodeDimensions;

type Props = {
nodeData: RepoNodeType;
children?: React.ReactNode;
Expand Down
27 changes: 27 additions & 0 deletions ui/src/features/project/pipelines/nodes/stage-node-footer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import classNames from 'classnames';
import { formatDistance } from 'date-fns';

import * as styles from './stage-node.module.less';

export const StageNodeFooter = ({ lastPromotion }: { lastPromotion?: Date }) => {
if (!lastPromotion) {
return null;
}

return (
<div className='flex flex-col w-full bg-gray-100 justify-center items-center p-1'>
{lastPromotion && (
<div className='flex items-center'>
<div className={classNames(styles.smallLabel, '!mr-2')} style={{ paddingTop: '1px' }}>
Last Promo:
</div>
<div className='text-xs text-gray-600 font-mono font-semibold'>
{formatDistance(lastPromotion, new Date(), {
addSuffix: true
})}
</div>
</div>
)}
</div>
);
};
Loading

0 comments on commit a01f049

Please sign in to comment.