Skip to content
Open
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
62 changes: 43 additions & 19 deletions ui/src/features/stage/promotion-steps.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,22 +34,31 @@ export const PromotionSteps = (props: PromotionStepsProps) => {

const phase = getPromotionStatusPhase(props.promotion);

const shouldShowMessage =
isPromotionPhaseTerminal(phase) &&
phase !== PromotionStatusPhase.SUCCEEDED &&
phase !== PromotionStatusPhase.ERRORED && // because its already handled at individual step level
!!props.promotion?.status?.message;
const message = props.promotion?.status?.message;

// A failed step's message becomes the Promotion's, so it is already on screen.
const hasIndividualPromotionStepTerminalMessage = (
props.promotion.status?.stepExecutionMetadata ?? []
).some((meta, i) => isFailedStep(i, props.promotion.status) && !!meta.message);

let shouldShowMessage = false;

if (isPromotionPhaseTerminal(phase)) {
switch (phase) {
case PromotionStatusPhase.FAILED:
case PromotionStatusPhase.ERRORED:
// The failing step already shows this message, so don't repeat it.
shouldShowMessage = !hasIndividualPromotionStepTerminalMessage;
break;
case PromotionStatusPhase.ABORTED:
// An abort is not attributable to any one step.
shouldShowMessage = true;
break;
}
}

const steps = props.promotion?.spec?.steps ?? [];

const errorItem = {
key: 'error',
label: <Alert message={props.promotion.status?.message} type='error' />,
showArrow: false,
collapsible: 'disabled' as const,
styles: { header: { paddingTop: 0 } }
};

// Steps with a registered extension are interactive
const hasExtension = (step: (typeof steps)[number]) =>
promotionStepExtensions.some((ext) => ext.identifier === step.uses);
Expand All @@ -76,9 +85,26 @@ export const PromotionSteps = (props: PromotionStepsProps) => {
key
};

return isFailedStep(i, props.promotion.status)
? [{ ...item, className: `${item.className || ''} !border-none` }, errorItem]
: [item];
if (!isFailedStep(i, props.promotion.status)) {
return [item];
}

const stepMessage = props.promotion.status?.stepExecutionMetadata?.[i]?.message;

if (!stepMessage) {
return [item];
}

return [
{ ...item, className: `${item.className || ''} !border-none` },
{
key: `${key}-error`,
label: <Alert message={stepMessage} type='error' />,
showArrow: false,
collapsible: 'disabled' as const,
styles: { header: { paddingTop: 0 } }
}
];
});

useEffect(() => {
Expand All @@ -97,9 +123,7 @@ export const PromotionSteps = (props: PromotionStepsProps) => {
activeKey={activeKeys}
onChange={(keys) => setActiveKeys(typeof keys === 'string' ? [keys] : keys)}
/>
{shouldShowMessage && (
<Alert message={props.promotion.status?.message} type='error' className='mt-4' />
)}
{shouldShowMessage && !!message && <Alert message={message} type='error' className='mt-4' />}
</>
);
};
Loading