Component cleanup
This commit is contained in:
@@ -25,6 +25,15 @@ export function getAssetPath(assetPath: string): string {
|
||||
return assetPath.startsWith("/") ? assetPath : `/${assetPath}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decorative vector marks in `public/assets/vector/<kebab-case>.svg`
|
||||
* (Figma Asset / Vector). Same folder pattern as governance template marks
|
||||
* under `assets/template-mark/`.
|
||||
*/
|
||||
export function vectorMarkPath(slug: string): string {
|
||||
return `assets/vector/${slug}.svg`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Asset paths for common components
|
||||
*/
|
||||
|
||||
@@ -231,7 +231,7 @@ export function buildFinalReviewCategoryRowsDetailed(
|
||||
}
|
||||
|
||||
/**
|
||||
* Derive the final-review RuleCard category rows from the current
|
||||
* Derive the final-review Rule category rows from the current
|
||||
* {@link CreateFlowState}.
|
||||
*
|
||||
* Two-mode contract, mirroring the two template entry points:
|
||||
|
||||
@@ -6,7 +6,7 @@ import type {
|
||||
DecisionApproachDetailEntry,
|
||||
MembershipMethodDetailEntry,
|
||||
} from "../../app/(app)/create/types";
|
||||
import type { CommunityRuleDocumentSection } from "../../app/components/sections/CommunityRuleDocument/CommunityRuleDocument.types";
|
||||
import type { CommunityRuleSection } from "../../app/components/type/CommunityRule/CommunityRule.types";
|
||||
import {
|
||||
communicationPresetFor,
|
||||
conflictManagementPresetFor,
|
||||
@@ -14,14 +14,11 @@ import {
|
||||
membershipPresetFor,
|
||||
methodLabelFor,
|
||||
} from "./finalReviewChipPresets";
|
||||
import { isDocumentEntry } from "./documentEntryGuards";
|
||||
|
||||
function isDocumentEntry(x: unknown): x is { title: string; body: string } {
|
||||
if (!x || typeof x !== "object") return false;
|
||||
const o = x as Record<string, unknown>;
|
||||
return typeof o.title === "string" && typeof o.body === "string";
|
||||
}
|
||||
export { isDocumentEntry } from "./documentEntryGuards";
|
||||
|
||||
function isDocumentSection(x: unknown): x is CommunityRuleDocumentSection {
|
||||
function isDocumentSection(x: unknown): x is CommunityRuleSection {
|
||||
if (!x || typeof x !== "object") return false;
|
||||
const o = x as Record<string, unknown>;
|
||||
if (typeof o.categoryName !== "string") return false;
|
||||
@@ -32,10 +29,10 @@ function isDocumentSection(x: unknown): x is CommunityRuleDocumentSection {
|
||||
/** Narrow `CreateFlowState.sections` into Community Rule document sections. */
|
||||
export function parseSectionsFromCreateFlowState(
|
||||
state: CreateFlowState,
|
||||
): CommunityRuleDocumentSection[] {
|
||||
): CommunityRuleSection[] {
|
||||
const raw = state.sections;
|
||||
if (!Array.isArray(raw)) return [];
|
||||
const out: CommunityRuleDocumentSection[] = [];
|
||||
const out: CommunityRuleSection[] = [];
|
||||
for (const x of raw) {
|
||||
if (isDocumentSection(x)) out.push(x);
|
||||
}
|
||||
@@ -233,7 +230,7 @@ export function buildMethodSelectionsForDocument(
|
||||
/** Read `document.sections` from a stored published payload for display. */
|
||||
export function parseDocumentSectionsForDisplay(
|
||||
document: unknown,
|
||||
): CommunityRuleDocumentSection[] {
|
||||
): CommunityRuleSection[] {
|
||||
if (!document || typeof document !== "object") return [];
|
||||
const sections = (document as Record<string, unknown>).sections;
|
||||
if (!Array.isArray(sections)) return [];
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
import type {
|
||||
CommunityRuleEntry,
|
||||
CommunityRuleLabeledBlock,
|
||||
} from "../../app/components/type/CommunityRule/CommunityRule.types";
|
||||
|
||||
function isLabeledBlock(x: unknown): x is CommunityRuleLabeledBlock {
|
||||
if (!x || typeof x !== "object") return false;
|
||||
const o = x as Record<string, unknown>;
|
||||
return typeof o.label === "string" && typeof o.body === "string";
|
||||
}
|
||||
|
||||
/** Shared by publish payload parsing and template body parsing — keep in sync. */
|
||||
export function isDocumentEntry(x: unknown): x is CommunityRuleEntry {
|
||||
if (!x || typeof x !== "object") return false;
|
||||
const o = x as Record<string, unknown>;
|
||||
if (typeof o.title !== "string" || o.title.trim().length === 0) {
|
||||
return false;
|
||||
}
|
||||
if (typeof o.body !== "string") return false;
|
||||
if (o.blocks !== undefined) {
|
||||
if (!Array.isArray(o.blocks) || !o.blocks.every(isLabeledBlock)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -1,18 +1,9 @@
|
||||
import type { Category } from "../../app/components/cards/RuleCard/RuleCard.types";
|
||||
import type { Category } from "../../app/components/cards/Rule";
|
||||
import type { ChipOption } from "../../app/components/controls/MultiSelect/MultiSelect.types";
|
||||
import type { CommunityRuleSection } from "../../app/components/type/CommunityRule/CommunityRule.types";
|
||||
import { isDocumentEntry } from "./documentEntryGuards";
|
||||
|
||||
function isDocumentEntry(x: unknown): x is { title: string; body: string } {
|
||||
if (!x || typeof x !== "object") return false;
|
||||
const o = x as Record<string, unknown>;
|
||||
return typeof o.title === "string" && typeof o.body === "string";
|
||||
}
|
||||
|
||||
function isDocumentSection(
|
||||
x: unknown,
|
||||
): x is {
|
||||
categoryName: string;
|
||||
entries: { title: string; body: string }[];
|
||||
} {
|
||||
function isDocumentSection(x: unknown): x is CommunityRuleSection {
|
||||
if (!x || typeof x !== "object") return false;
|
||||
const o = x as Record<string, unknown>;
|
||||
if (typeof o.categoryName !== "string") return false;
|
||||
@@ -79,7 +70,7 @@ export interface TemplateChipDetail {
|
||||
}
|
||||
|
||||
/**
|
||||
* Maps API template `body` (published-rule document shape) to RuleCard category
|
||||
* Maps API template `body` (published-rule document shape) to Rule category
|
||||
* rows **plus** a chipId → detail lookup for wiring chip clicks to the
|
||||
* read-only detail modal.
|
||||
*/
|
||||
@@ -144,8 +135,11 @@ export function templateSummaryFromBody(
|
||||
for (const s of sections) {
|
||||
if (!isDocumentSection(s)) continue;
|
||||
const first = s.entries[0];
|
||||
if (isDocumentEntry(first) && first.body.trim()) {
|
||||
return first.body.trim();
|
||||
if (isDocumentEntry(first)) {
|
||||
const main = first.body.trim();
|
||||
if (main.length > 0) return main;
|
||||
const fromBlock = first.blocks?.[0]?.body?.trim();
|
||||
if (fromBlock && fromBlock.length > 0) return fromBlock;
|
||||
}
|
||||
}
|
||||
return "";
|
||||
|
||||
+13
-21
@@ -72,14 +72,14 @@ export type AlertSizeValue = (typeof ALERT_SIZE_OPTIONS)[number];
|
||||
export const TOOLTIP_POSITION_OPTIONS = ["top", "bottom"] as const;
|
||||
export type TooltipPositionValue = (typeof TOOLTIP_POSITION_OPTIONS)[number];
|
||||
|
||||
export const MENU_BAR_SIZE_OPTIONS = [
|
||||
export const MENU_SIZE_OPTIONS = [
|
||||
"X Small",
|
||||
"Small",
|
||||
"Medium",
|
||||
"Large",
|
||||
"X Large",
|
||||
] as const;
|
||||
export type MenuBarSizeValue = (typeof MENU_BAR_SIZE_OPTIONS)[number];
|
||||
export type MenuSizeValue = (typeof MENU_SIZE_OPTIONS)[number];
|
||||
|
||||
export const NAVIGATION_ITEM_VARIANT_OPTIONS = ["default"] as const;
|
||||
export type NavigationItemVariantValue =
|
||||
@@ -145,13 +145,13 @@ export const QUOTE_BLOCK_VARIANT_OPTIONS = [
|
||||
export type QuoteBlockVariantValue =
|
||||
(typeof QUOTE_BLOCK_VARIANT_OPTIONS)[number];
|
||||
|
||||
export const NUMBER_CARD_SIZE_OPTIONS = [
|
||||
export const STEP_SIZE_OPTIONS = [
|
||||
"small",
|
||||
"medium",
|
||||
"large",
|
||||
"xlarge",
|
||||
] as const;
|
||||
export type NumberCardSizeValue = (typeof NUMBER_CARD_SIZE_OPTIONS)[number];
|
||||
export type StepSizeValue = (typeof STEP_SIZE_OPTIONS)[number];
|
||||
|
||||
export const ASK_ORGANIZER_VARIANT_OPTIONS = [
|
||||
"centered",
|
||||
@@ -162,14 +162,6 @@ export const ASK_ORGANIZER_VARIANT_OPTIONS = [
|
||||
export type AskOrganizerVariantValue =
|
||||
(typeof ASK_ORGANIZER_VARIANT_OPTIONS)[number];
|
||||
|
||||
export const CONTEXT_MENU_ITEM_SIZE_OPTIONS = [
|
||||
"small",
|
||||
"medium",
|
||||
"large",
|
||||
] as const;
|
||||
export type ContextMenuItemSizeValue =
|
||||
(typeof CONTEXT_MENU_ITEM_SIZE_OPTIONS)[number];
|
||||
|
||||
export const TOGGLE_GROUP_POSITION_OPTIONS = [
|
||||
"left",
|
||||
"middle",
|
||||
@@ -185,8 +177,8 @@ export const TEXT_AREA_APPEARANCE_OPTIONS = ["default", "embedded"] as const;
|
||||
export type TextAreaAppearanceValue =
|
||||
(typeof TEXT_AREA_APPEARANCE_OPTIONS)[number];
|
||||
|
||||
export const RULE_CARD_SIZE_OPTIONS = ["XS", "S", "M", "L"] as const;
|
||||
export type RuleCardSizeValue = (typeof RULE_CARD_SIZE_OPTIONS)[number];
|
||||
export const RULE_SIZE_OPTIONS = ["XS", "S", "M", "L"] as const;
|
||||
export type RuleSizeValue = (typeof RULE_SIZE_OPTIONS)[number];
|
||||
|
||||
export const CHIP_STATE_OPTIONS = [
|
||||
"unselected",
|
||||
@@ -212,19 +204,19 @@ export const INPUT_LABEL_PALETTE_OPTIONS = ["default", "inverse"] as const;
|
||||
export type InputLabelPaletteValue =
|
||||
(typeof INPUT_LABEL_PALETTE_OPTIONS)[number];
|
||||
|
||||
export const MENU_BAR_ITEM_STATE_OPTIONS = [
|
||||
export const MENU_ITEM_STATE_OPTIONS = [
|
||||
"default",
|
||||
"hover",
|
||||
"selected",
|
||||
] as const;
|
||||
export type MenuBarItemStateValue =
|
||||
(typeof MENU_BAR_ITEM_STATE_OPTIONS)[number];
|
||||
export type MenuItemStateValue =
|
||||
(typeof MENU_ITEM_STATE_OPTIONS)[number];
|
||||
|
||||
export const MENU_BAR_ITEM_MODE_OPTIONS = ["default", "inverse"] as const;
|
||||
export type MenuBarItemModeValue = (typeof MENU_BAR_ITEM_MODE_OPTIONS)[number];
|
||||
export const MENU_ITEM_MODE_OPTIONS = ["default", "inverse"] as const;
|
||||
export type MenuItemModeValue = (typeof MENU_ITEM_MODE_OPTIONS)[number];
|
||||
|
||||
export const MENU_BAR_ITEM_SIZE_OPTIONS = MENU_BAR_SIZE_OPTIONS;
|
||||
export type MenuBarItemSizeValue = MenuBarSizeValue;
|
||||
export const MENU_ITEM_SIZE_OPTIONS = MENU_SIZE_OPTIONS;
|
||||
export type MenuItemSizeValue = MenuSizeValue;
|
||||
|
||||
export const BUTTON_TYPE_OPTIONS = [
|
||||
"filled",
|
||||
|
||||
Reference in New Issue
Block a user