Skip to content

Commit

Permalink
feat(ui): show output in promotion steps
Browse files Browse the repository at this point in the history
Signed-off-by: Mayursinh Sarvaiya <[email protected]>
  • Loading branch information
Marvin9 committed Oct 4, 2024
1 parent e6b2329 commit 3287d04
Showing 1 changed file with 96 additions and 30 deletions.
126 changes: 96 additions & 30 deletions ui/src/features/stage/promotion-details-modal.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
import {
faCaretDown,
faCaretUp,
faCheck,
faCircleNotch,
faCog,
faFileLines,
faLinesLeaning,
faShoePrints,
faTimes
} from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { Flex, Modal, Tabs } from 'antd';
import { Collapse, Flex, Modal, Segmented, Tabs } from 'antd';
import Alert from 'antd/es/alert/Alert';
import { SegmentedOptions } from 'antd/es/segmented';
import classNames from 'classnames';
import { useMemo, useState } from 'react';

Expand All @@ -25,7 +26,15 @@ import { Runner } from '@ui/features/promotion-directives/registry/types';
import { Promotion, PromotionStep } from '@ui/gen/v1alpha1/generated_pb';
import { decodeRawData } from '@ui/utils/decode-raw-data';

const Step = ({ step, result }: { step: PromotionStep; result: PromotionDirectiveStepStatus }) => {
const Step = ({
step,
result,
logs
}: {
step: PromotionStep;
result: PromotionDirectiveStepStatus;
logs?: object;
}) => {
const [showDetails, setShowDetails] = useState(false);

const { registry } = usePromotionDirectivesRegistryContext();
Expand Down Expand Up @@ -59,15 +68,43 @@ const Step = ({ step, result }: { step: PromotionStep; result: PromotionDirectiv
const success = result === PromotionDirectiveStepStatus.SUCCESS;
const failed = result === PromotionDirectiveStepStatus.FAILED;

return (
<Flex
className={classNames('rounded-md border-2 border-solid p-2 mb-3', {
'border-green-500': progressing,
'border-gray-200': !progressing
})}
vertical
>
<Flex align='center'>
const opts: SegmentedOptions<string> = [];

if (logs) {
opts.push({
label: 'Output',
value: 'output',
icon: <FontAwesomeIcon icon={faLinesLeaning} className='text-xs' />,
className: 'p-2'
});
}

if (meta?.config) {
opts.push({
label: 'Config',
value: 'config',
icon: <FontAwesomeIcon icon={faCog} className='text-xs' />,
className: 'p-2'
});
}

const [selectedOpts, setSelectedOpts] = useState(
// @ts-expect-error value is there
opts?.[0]?.value
);

const yamlView = {
config: meta?.config,
output: logs ? JSON.stringify(logs || {}, null, ' ') : ''
};

return {
className: classNames('', {
'border-green-500': progressing,
'border-gray-200': !progressing
}),
label: (
<Flex align='center' onClick={() => setShowDetails(!showDetails)}>
<Flex
align='center'
justify='center'
Expand All @@ -89,19 +126,29 @@ const Step = ({ step, result }: { step: PromotionStep; result: PromotionDirectiv
<FontAwesomeIcon key={i} icon={icon} />
))}
</Flex>
{step.config && (
<FontAwesomeIcon
icon={showDetails ? faCaretUp : faCaretDown}
onClick={() => setShowDetails(!showDetails)}
className='mr-2 text-blue-500 cursor-pointer'
/>
)}
</Flex>
</Flex>
</Flex>
{showDetails && <YamlEditor value={meta.config} height='200px' className='mt-2' disabled />}
</Flex>
);
),
children: (
<>
{opts.length > 1 && (
<Segmented
value={selectedOpts}
size='small'
options={opts}
onChange={setSelectedOpts}
className='mb-2'
/>
)}
<YamlEditor
value={yamlView[selectedOpts as keyof typeof yamlView]}
height='200px'
disabled
/>
</>
)
};
};

export const PromotionDetailsModal = ({
Expand All @@ -111,6 +158,21 @@ export const PromotionDetailsModal = ({
}: {
promotion: Promotion;
} & ModalProps) => {
const logsByStepAlias: Record<string, object> = useMemo(() => {
if (promotion?.status?.state?.raw) {
try {
const raw = decodeRawData({ result: { case: 'raw', value: promotion.status.state.raw } });

return JSON.parse(raw);
} catch (e) {
// eslint-disable-next-line no-console
console.error(e);
}
}

return {};
}, [promotion]);

return (
<Modal
title='Promotion Details'
Expand All @@ -124,13 +186,17 @@ export const PromotionDetailsModal = ({
<Tabs defaultActiveKey='1'>
{promotion.spec?.steps && (
<Tabs.TabPane tab='Steps' key='1' icon={<FontAwesomeIcon icon={faShoePrints} />}>
{promotion.spec.steps.map((step, i) => (
<Step
key={i}
step={step}
result={getPromotionDirectiveStepStatus(i, promotion.status)}
/>
))}
<Collapse
expandIconPosition='end'
bordered={false}
items={promotion.spec.steps.map((step, i) => {
return Step({
step,
result: getPromotionDirectiveStepStatus(i, promotion.status),
logs: logsByStepAlias?.[step?.as || '']
});
})}
/>
{!!promotion?.status?.message && (
<Alert message={promotion.status.message} type='error' className='mt4' />
)}
Expand Down

0 comments on commit 3287d04

Please sign in to comment.