Persist choices through to completed page
This commit is contained in:
@@ -1,20 +1,23 @@
|
||||
import type {
|
||||
CommunicationMethodDetailEntry,
|
||||
ConflictManagementDetailEntry,
|
||||
CoreValueDetailEntry,
|
||||
CreateFlowState,
|
||||
DecisionApproachDetailEntry,
|
||||
MembershipMethodDetailEntry,
|
||||
} from "../../app/(app)/create/types";
|
||||
import type { CommunityRuleSection } from "../../app/components/type/CommunityRule/CommunityRule.types";
|
||||
import { resolveMethodPresetIdFromLabel } from "./buildFinalReviewCategories";
|
||||
import {
|
||||
communicationPresetFor,
|
||||
conflictManagementPresetFor,
|
||||
decisionApproachPresetFor,
|
||||
membershipPresetFor,
|
||||
mergeCoreValueDetailWithPresets,
|
||||
methodLabelFor,
|
||||
} from "./finalReviewChipPresets";
|
||||
import { isDocumentEntry } from "./documentEntryGuards";
|
||||
import { replaceMethodSectionsWithMethodSelections } from "./ruleSectionsFromMethodSelections";
|
||||
import { templateCategoryToGroupKey } from "./templateReviewMapping";
|
||||
|
||||
export { isDocumentEntry } from "./documentEntryGuards";
|
||||
|
||||
@@ -53,12 +56,12 @@ export function buildCoreValuesForDocument(state: CreateFlowState): Array<{
|
||||
return snap
|
||||
.filter((r) => selected.has(r.id))
|
||||
.map((r) => {
|
||||
const d: CoreValueDetailEntry | undefined = details[r.id];
|
||||
const merged = mergeCoreValueDetailWithPresets(r.id, r.label, details[r.id]);
|
||||
return {
|
||||
chipId: r.id,
|
||||
label: r.label,
|
||||
meaning: d?.meaning ?? "",
|
||||
signals: d?.signals ?? "",
|
||||
meaning: merged.meaning,
|
||||
signals: merged.signals,
|
||||
};
|
||||
});
|
||||
}
|
||||
@@ -102,7 +105,9 @@ export type BuildPublishPayloadResult =
|
||||
}
|
||||
| { ok: false; error: string };
|
||||
|
||||
const FALLBACK_CATEGORY = "Overview";
|
||||
export const PUBLISH_FALLBACK_OVERVIEW_CATEGORY = "Overview";
|
||||
|
||||
const FALLBACK_CATEGORY = PUBLISH_FALLBACK_OVERVIEW_CATEGORY;
|
||||
|
||||
const DEFAULT_FALLBACK_BODY =
|
||||
"This CommunityRule was created in the create flow. Add more detail in a future edit.";
|
||||
@@ -124,7 +129,8 @@ export function buildPublishPayload(
|
||||
return undefined;
|
||||
};
|
||||
|
||||
let summary = firstNonEmpty(state.summary, state.communityContext);
|
||||
/** Community context wins over `summary` (template review no longer copies template description into `summary`). */
|
||||
let summary = firstNonEmpty(state.communityContext, state.summary);
|
||||
|
||||
let sections = parseSectionsFromCreateFlowState(state);
|
||||
if (sections.length === 0) {
|
||||
@@ -138,8 +144,18 @@ export function buildPublishPayload(
|
||||
}
|
||||
|
||||
const coreValues = buildCoreValuesForDocument(state);
|
||||
if (coreValues.length > 0) {
|
||||
sections = sections.filter(
|
||||
(s) => templateCategoryToGroupKey(s.categoryName) !== "coreValues",
|
||||
);
|
||||
}
|
||||
|
||||
const methodSelections = buildMethodSelectionsForDocument(state);
|
||||
|
||||
if (hasAnyMethodSelection(methodSelections)) {
|
||||
sections = replaceMethodSectionsWithMethodSelections(sections, methodSelections);
|
||||
}
|
||||
|
||||
const document: Record<string, unknown> = { sections, coreValues };
|
||||
if (hasAnyMethodSelection(methodSelections)) {
|
||||
document.methodSelections = methodSelections;
|
||||
@@ -160,6 +176,59 @@ function hasAnyMethodSelection(m: PublishedMethodSelections): boolean {
|
||||
);
|
||||
}
|
||||
|
||||
function deriveMethodPresetIdsFromSections(
|
||||
sections: CommunityRuleSection[],
|
||||
): {
|
||||
communication: string[];
|
||||
membership: string[];
|
||||
decisionApproaches: string[];
|
||||
conflictManagement: string[];
|
||||
} {
|
||||
const out = {
|
||||
communication: [] as string[],
|
||||
membership: [] as string[],
|
||||
decisionApproaches: [] as string[],
|
||||
conflictManagement: [] as string[],
|
||||
};
|
||||
for (const s of sections) {
|
||||
const gk = templateCategoryToGroupKey(s.categoryName);
|
||||
if (!gk || gk === "coreValues") continue;
|
||||
const ids: string[] = [];
|
||||
for (const e of s.entries) {
|
||||
const title = typeof e.title === "string" ? e.title.trim() : "";
|
||||
if (title.length === 0) continue;
|
||||
const id = resolveMethodPresetIdFromLabel(title, gk);
|
||||
if (id) ids.push(id);
|
||||
}
|
||||
if (ids.length === 0) continue;
|
||||
switch (gk) {
|
||||
case "communication":
|
||||
out.communication = ids;
|
||||
break;
|
||||
case "membership":
|
||||
out.membership = ids;
|
||||
break;
|
||||
case "decisionApproaches":
|
||||
out.decisionApproaches = ids;
|
||||
break;
|
||||
case "conflictManagement":
|
||||
out.conflictManagement = ids;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
function pickMethodIds(
|
||||
fromState: string[] | undefined,
|
||||
derived: string[],
|
||||
): string[] {
|
||||
if (fromState && fromState.length > 0) return fromState;
|
||||
return derived;
|
||||
}
|
||||
|
||||
/**
|
||||
* Merge `selected*MethodIds` with any saved `{group}MethodDetailsById`
|
||||
* overrides authored on the final-review screen. Preset defaults from the
|
||||
@@ -170,9 +239,15 @@ function hasAnyMethodSelection(m: PublishedMethodSelections): boolean {
|
||||
export function buildMethodSelectionsForDocument(
|
||||
state: CreateFlowState,
|
||||
): PublishedMethodSelections {
|
||||
const derived = deriveMethodPresetIdsFromSections(
|
||||
parseSectionsFromCreateFlowState(state),
|
||||
);
|
||||
const out: PublishedMethodSelections = {};
|
||||
|
||||
const commIds = state.selectedCommunicationMethodIds ?? [];
|
||||
const commIds = pickMethodIds(
|
||||
state.selectedCommunicationMethodIds,
|
||||
derived.communication,
|
||||
);
|
||||
if (commIds.length > 0) {
|
||||
out.communication = commIds.map((id) => {
|
||||
const preset = communicationPresetFor(id);
|
||||
@@ -185,7 +260,10 @@ export function buildMethodSelectionsForDocument(
|
||||
});
|
||||
}
|
||||
|
||||
const memIds = state.selectedMembershipMethodIds ?? [];
|
||||
const memIds = pickMethodIds(
|
||||
state.selectedMembershipMethodIds,
|
||||
derived.membership,
|
||||
);
|
||||
if (memIds.length > 0) {
|
||||
out.membership = memIds.map((id) => {
|
||||
const preset = membershipPresetFor(id);
|
||||
@@ -198,7 +276,10 @@ export function buildMethodSelectionsForDocument(
|
||||
});
|
||||
}
|
||||
|
||||
const daIds = state.selectedDecisionApproachIds ?? [];
|
||||
const daIds = pickMethodIds(
|
||||
state.selectedDecisionApproachIds,
|
||||
derived.decisionApproaches,
|
||||
);
|
||||
if (daIds.length > 0) {
|
||||
out.decisionApproaches = daIds.map((id) => {
|
||||
const preset = decisionApproachPresetFor(id);
|
||||
@@ -211,7 +292,10 @@ export function buildMethodSelectionsForDocument(
|
||||
});
|
||||
}
|
||||
|
||||
const cmIds = state.selectedConflictManagementIds ?? [];
|
||||
const cmIds = pickMethodIds(
|
||||
state.selectedConflictManagementIds,
|
||||
derived.conflictManagement,
|
||||
);
|
||||
if (cmIds.length > 0) {
|
||||
out.conflictManagement = cmIds.map((id) => {
|
||||
const preset = conflictManagementPresetFor(id);
|
||||
|
||||
Reference in New Issue
Block a user