Show seven cards on the four method decks and open each as a routing overlay of its parts, so groups write from empty fields with Generate draft, search the full deck, and see unselected scope chips with enough contrast.

This commit is contained in:
adilallo committed 2026-11-05 22:43:30 -07:00
1 parent dea7dd7fbd
commit 46656f52d3
28 files changed
+1349 -318

No files matched your search

@@ -7,12 +7,9 @@
* Page chrome is the shared question-and-options shell
* (`CreateFlowTwoColumnSelectShell`); options are CardStack `singleStack`.
*
* Card click opens the Figma "Add Approach" create modal (node `20874-172292`)
* with four controls rendered by {@link ConflictManagementEditFields}: Core
* Principle, Applicable Scope (text area), Process Protocol, and Restoration
* & Fallbacks. The same field set is reused on `/create/final-review` — see
* `FinalReviewChipEditModal`. Confirm persists both the chip selection and
* any user edits as a `conflictManagementDetailsById[id]` override.
* Card click opens Overlay / Modal / Card as a routing view of its parts
* ({@link MethodCardPolicyDialog}). Confirm persists the chip selection and
* any edits as a `conflictManagementDetailsById[id]` override.
*/
import { useState, useCallback, useMemo, useRef } from "react";
@@ -24,9 +21,9 @@ import { useMethodCardDeckOrdering } from "../../hooks/useMethodCardDeckOrdering
import { CreateFlowHeaderLockup } from "../../components/CreateFlowHeaderLockup";
import { CreateFlowTwoColumnSelectShell } from "../../components/CreateFlowTwoColumnSelectShell";
import CardStack from "../../../../components/cards/CardStack";
import Create from "../../../../components/modals/Create";
import InlineTextButton from "../../../../components/buttons/InlineTextButton";
import { ConflictManagementEditFields } from "../../components/methodEditFields";
import { MethodCardPolicyDialog } from "../../components/MethodCardPolicyDialog";
import { useConflictPolicySteps } from "../../components/methodCardPolicySteps";
import CustomMethodCardWizard from "../../components/CustomMethodCardWizard";
import { uploadCreateFlowFile } from "../../../../../lib/create/uploadToServer";
import { conflictManagementPresetFor, emptyConflictManagementDetails } from "../../../../../lib/create/finalReviewChipPresets";
@@ -105,7 +102,8 @@ export function ConflictManagementScreen() {
[cm.methods, selectedIds, state.customMethodCardMetaById],
);
const { sampleCards, compactCardIds, methodById, recommendationsReady } =
const rec = m.create.customRule.recommendations;
const { sampleCards, compactCardIds, methodById, recommendationsReady, showDeckLine, compactLimit } =
useMethodCardDeckOrdering(
"conflictManagement",
mergedMethods,
@@ -192,10 +190,14 @@ export function ConflictManagementScreen() {
},
[markCreateFlowInteraction],
);
const conflictSteps = useConflictPolicySteps(
pendingDraft ?? emptyConflictManagementDetails(),
handleDraftChange,
pendingCardId ? conflictManagementPresetFor(pendingCardId) : undefined,
);
const isSelectedCardModal =
pendingCardId !== null && selectedIds.includes(pendingCardId);
const showMethodModalPrimary = true;
const customFacetDetailsMatchPreset = useMemo(() => {
if (!pendingCardId || !pendingDraft) return false;
@@ -716,57 +718,52 @@ export function ConflictManagementScreen() {
}}
hasMore={true}
toggleLabel={cm.page.seeAllLink}
compactRecommendedLimit={5}
compactRecommendedLimit={compactLimit}
compactCardIds={compactCardIds}
layout="singleStack"
deckLine={showDeckLine ? rec.deckLine : undefined}
searchPlaceholder={rec.searchPlaceholder}
alternativePrefix={rec.alternative}
onAlternativeSelect={handleCardClick}
className="w-full lg:h-full lg:min-h-0 lg:flex-1"
/>
)}
</div>
</CreateFlowTwoColumnSelectShell>
<Create
<MethodCardPolicyDialog
isOpen={createModalOpen}
onClose={handleCreateModalClose}
onNext={handleCreateModalPrimary}
title={modalConfig.title}
cardLabel={modalConfig.title}
description={modalConfig.description}
nextButtonText={modalConfig.nextButtonText}
showBackButton={false}
showNextButton={showMethodModalPrimary}
showRemoveButton={isSelectedCardModal}
onRemove={handleRemoveSelectedFromModal}
backdropVariant="blurredYellow"
editing={isSelectedCardModal}
steps={conflictSteps}
onClose={handleCreateModalClose}
onConfirm={handleCreateModalPrimary}
onDeselect={
isSelectedCardModal ? handleRemoveSelectedFromModal : undefined
}
kebabTriggerAriaLabel={modalKebabMenu.triggerAriaLabel}
kebabMenuAriaLabel={modalKebabMenu.menuAriaLabel}
kebabMenuItems={kebabMenuItems}
>
{pendingCardId && pendingDraft ? (
modalUsesWizardFieldBlocksBody ? (
<CustomMethodCardModalBody
cardId={pendingCardId}
blocksById={state.customMethodCardFieldBlocksById}
blocksOverride={
draftFieldBlocks !== null ? draftFieldBlocks : undefined
}
policyMeta={state.customMethodCardMetaById?.[pendingCardId]}
showPolicyContentLockupWhenNoBlocks={
draftFieldBlocks === null || draftFieldBlocks.length === 0
}
onFieldBlocksChange={
draftFieldBlocks === null
? undefined
: (next) => setDraftFieldBlocks(next)
}
/>
) : (
<ConflictManagementEditFields
value={pendingDraft}
onChange={handleDraftChange}
generateDraft={conflictManagementPresetFor(pendingCardId)}
/>
)
{pendingCardId && modalUsesWizardFieldBlocksBody ? (
<CustomMethodCardModalBody
cardId={pendingCardId}
blocksById={state.customMethodCardFieldBlocksById}
blocksOverride={
draftFieldBlocks !== null ? draftFieldBlocks : undefined
}
policyMeta={state.customMethodCardMetaById?.[pendingCardId]}
showPolicyContentLockupWhenNoBlocks={
draftFieldBlocks === null || draftFieldBlocks.length === 0
}
onFieldBlocksChange={
draftFieldBlocks === null
? undefined
: (next) => setDraftFieldBlocks(next)
}
/>
) : null}
</Create>
</MethodCardPolicyDialog>
<CustomMethodCardWizard
isOpen={addCustomWizardOpen}
onClose={handleCloseAddWizard}