Refactor campaign recipient and review presentation
This commit is contained in:
@@ -1,6 +1,11 @@
|
||||
import { useState, type CSSProperties, type ReactNode } from "react";
|
||||
import { ChevronDown, LockKeyhole, type LucideIcon } from "lucide-react";
|
||||
import { InlineHelp, i18nMessage } from "@govoplan/core-webui";
|
||||
import {
|
||||
InlineHelp,
|
||||
StageRail,
|
||||
i18nMessage,
|
||||
type StageRailTone
|
||||
} from "@govoplan/core-webui";
|
||||
|
||||
import { humanize } from "../utils/campaignView";
|
||||
|
||||
@@ -39,6 +44,18 @@ const stateColors: Record<FlowState, string> = {
|
||||
pending: "var(--muted)"
|
||||
};
|
||||
|
||||
const stageRailTones: Record<FlowState, StageRailTone> = {
|
||||
complete: "success",
|
||||
warning: "warning",
|
||||
danger: "danger",
|
||||
active: "active",
|
||||
locked: "neutral",
|
||||
running: "active",
|
||||
partial: "partial",
|
||||
stale: "partial",
|
||||
pending: "neutral"
|
||||
};
|
||||
|
||||
export function WorkflowNavigation({
|
||||
stages,
|
||||
onSelect
|
||||
@@ -47,50 +64,29 @@ export function WorkflowNavigation({
|
||||
onSelect: (id: string) => void;
|
||||
}) {
|
||||
return (
|
||||
<nav className="review-flow-navigation" aria-label="i18n:govoplan-campaign.review_and_send_workflow_steps.77fc8af2">
|
||||
<div className="review-flow-navigation-track">
|
||||
{stages.map((stage, index) => {
|
||||
const Icon = stage.icon;
|
||||
const nextStage = stages[index + 1];
|
||||
const connectorState = stageConnectorState(stage);
|
||||
const nextConnectorState = nextStage ? stageConnectorState(nextStage) : connectorState;
|
||||
const title = i18nMessage(stage.title);
|
||||
const shortTitle = i18nMessage(stage.shortTitle);
|
||||
const stateText = i18nMessage(stage.stateLabel);
|
||||
const style = {
|
||||
"--review-nav-color": stateColors[stage.state],
|
||||
"--review-nav-line-color": stateColors[connectorState],
|
||||
"--review-nav-line-next-color": stateColors[nextConnectorState]
|
||||
} as CSSProperties;
|
||||
const showSecondaryState = !["active", "locked"].includes(stage.state);
|
||||
return (
|
||||
<div className="review-flow-navigation-group" key={stage.id} style={style}>
|
||||
<button
|
||||
type="button"
|
||||
className="review-flow-navigation-item"
|
||||
data-state={stage.state}
|
||||
onClick={() => onSelect(stage.id)}
|
||||
title={`${title}: ${stateText}`}
|
||||
>
|
||||
<span className="review-flow-navigation-icon">
|
||||
<Icon size={17} strokeWidth={1.8} aria-hidden="true" />
|
||||
</span>
|
||||
<span className="review-flow-navigation-copy">
|
||||
<strong>
|
||||
<span>{shortTitle}</span>
|
||||
{stage.state === "locked" && (
|
||||
<LockKeyhole size={12} aria-label="i18n:govoplan-campaign.locked.a798882f" />
|
||||
)}
|
||||
</strong>
|
||||
{showSecondaryState && <small>{stateText}</small>}
|
||||
</span>
|
||||
</button>
|
||||
{nextStage && <span className="review-flow-navigation-line" aria-hidden="true" />}
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</nav>
|
||||
<StageRail
|
||||
className="review-flow-navigation"
|
||||
ariaLabel="i18n:govoplan-campaign.review_and_send_workflow_steps.77fc8af2"
|
||||
onSelect={onSelect}
|
||||
items={stages.map((stage) => {
|
||||
const Icon = stage.icon;
|
||||
const title = i18nMessage(stage.title);
|
||||
const stateText = i18nMessage(stage.stateLabel);
|
||||
return {
|
||||
id: stage.id,
|
||||
label: i18nMessage(stage.shortTitle),
|
||||
statusLabel: ["active", "locked"].includes(stage.state)
|
||||
? undefined
|
||||
: stateText,
|
||||
title: `${title}: ${stateText}`,
|
||||
icon: <Icon size={17} strokeWidth={1.8} aria-hidden="true" />,
|
||||
tone: stageRailTones[stage.state],
|
||||
connectorTone: stageRailTones[stageConnectorState(stage)],
|
||||
locked: stage.state === "locked",
|
||||
lockedLabel: "i18n:govoplan-campaign.locked.a798882f"
|
||||
};
|
||||
})}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user