145 lines
4.0 KiB
TypeScript
145 lines
4.0 KiB
TypeScript
"use client";
|
|
|
|
/**
|
|
* Figma: Overlay / Modal / Card (24973:1852) with Has Steps on. A deck card
|
|
* opens as a routing view of its parts; each row opens that field's Step
|
|
* Modal with Generate draft on an empty field.
|
|
*/
|
|
|
|
import { memo, useCallback, useEffect, useState, type ReactNode } from "react";
|
|
import Create from "../../../components/modals/Create";
|
|
import { useMessages } from "../../../contexts/MessagesContext";
|
|
import type { ModalHeaderMenuItem } from "../../../components/modals/ModalHeader/ModalHeader.types";
|
|
import { ValueDialogStepCard } from "./ValueDialogStepCard";
|
|
|
|
export type MethodCardPolicyStep = {
|
|
id: string;
|
|
title: string;
|
|
emptyDescription: string;
|
|
done: boolean;
|
|
summary: string;
|
|
renderEditor: () => ReactNode;
|
|
};
|
|
|
|
export type MethodCardPolicyDialogProps = {
|
|
isOpen: boolean;
|
|
cardLabel: string;
|
|
description?: string;
|
|
editing: boolean;
|
|
steps: MethodCardPolicyStep[];
|
|
onClose: () => void;
|
|
onConfirm: () => void;
|
|
onDeselect?: () => void;
|
|
kebabTriggerAriaLabel?: string;
|
|
kebabMenuAriaLabel?: string;
|
|
kebabMenuItems?: ModalHeaderMenuItem[];
|
|
ariaLabel?: string;
|
|
/** Customized field-blocks body. Replaces the routing steps. */
|
|
children?: ReactNode;
|
|
};
|
|
|
|
function MethodCardPolicyDialogComponent({
|
|
isOpen,
|
|
cardLabel,
|
|
description = "",
|
|
editing,
|
|
steps,
|
|
onClose,
|
|
onConfirm,
|
|
onDeselect,
|
|
kebabTriggerAriaLabel,
|
|
kebabMenuAriaLabel,
|
|
kebabMenuItems,
|
|
ariaLabel,
|
|
children,
|
|
}: MethodCardPolicyDialogProps) {
|
|
const m = useMessages();
|
|
const t = m.create.customRule.cardDialog;
|
|
const [activeStepId, setActiveStepId] = useState<string | null>(null);
|
|
|
|
useEffect(() => {
|
|
if (!isOpen) {
|
|
setActiveStepId(null);
|
|
}
|
|
}, [isOpen]);
|
|
|
|
const activeStep =
|
|
activeStepId == null
|
|
? null
|
|
: (steps.find((step) => step.id === activeStepId) ?? null);
|
|
const useCustomBody = Boolean(children);
|
|
const showSteps = !useCustomBody && activeStep == null;
|
|
|
|
const handleRequestClose = useCallback(() => {
|
|
if (activeStepId != null) {
|
|
setActiveStepId(null);
|
|
return;
|
|
}
|
|
onClose();
|
|
}, [activeStepId, onClose]);
|
|
|
|
const handleNext = useCallback(() => {
|
|
if (activeStepId != null) {
|
|
setActiveStepId(null);
|
|
return;
|
|
}
|
|
onConfirm();
|
|
}, [activeStepId, onConfirm]);
|
|
|
|
const title = activeStep ? activeStep.title : cardLabel;
|
|
const primaryLabel = activeStepId != null || editing ? t.save : t.addToRule;
|
|
|
|
return (
|
|
<Create
|
|
isOpen={isOpen}
|
|
onClose={handleRequestClose}
|
|
title={title}
|
|
description={activeStep ? undefined : description || undefined}
|
|
showBackButton={false}
|
|
showCancelButton
|
|
showNextButton
|
|
showRemoveButton={editing && activeStepId == null}
|
|
onCancel={handleRequestClose}
|
|
onNext={handleNext}
|
|
onRemove={onDeselect}
|
|
cancelButtonText={t.cancel}
|
|
nextButtonText={primaryLabel}
|
|
removeButtonText={t.deselect}
|
|
stepper={false}
|
|
backdropVariant="blurredYellow"
|
|
kebabTriggerAriaLabel={kebabTriggerAriaLabel}
|
|
kebabMenuAriaLabel={kebabMenuAriaLabel}
|
|
kebabMenuItems={
|
|
activeStepId == null && kebabMenuItems && kebabMenuItems.length > 0
|
|
? kebabMenuItems
|
|
: undefined
|
|
}
|
|
ariaLabel={ariaLabel || cardLabel}
|
|
>
|
|
{useCustomBody ? (
|
|
children
|
|
) : showSteps ? (
|
|
<div className="flex w-full flex-col gap-[8px]">
|
|
{steps.map((step, index) => (
|
|
<ValueDialogStepCard
|
|
key={step.id}
|
|
stepNumber={index + 1}
|
|
stepBadgeLabel={t.stepBadge}
|
|
title={step.title}
|
|
description={step.done ? step.summary : step.emptyDescription}
|
|
done={step.done}
|
|
onClick={() => setActiveStepId(step.id)}
|
|
/>
|
|
))}
|
|
</div>
|
|
) : (
|
|
activeStep?.renderEditor()
|
|
)}
|
|
</Create>
|
|
);
|
|
}
|
|
|
|
MethodCardPolicyDialogComponent.displayName = "MethodCardPolicyDialog";
|
|
|
|
export const MethodCardPolicyDialog = memo(MethodCardPolicyDialogComponent);
|