@wildo-ai/saas-frontend-lib 1.1.3 → 1.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/esm/companion-exports.d.ts +1 -1
- package/dist/esm/companion-exports.d.ts.map +1 -1
- package/dist/esm/companion-exports.js +1 -1
- package/dist/esm/companion-exports.js.map +1 -1
- package/dist/esm/components/ai-elements/decision/approval.d.ts +13 -1
- package/dist/esm/components/ai-elements/decision/approval.d.ts.map +1 -1
- package/dist/esm/components/ai-elements/decision/approval.js.map +1 -1
- package/dist/esm/components/flows-actors/approval.d.ts.map +1 -1
- package/dist/esm/components/flows-actors/approval.js +12 -7
- package/dist/esm/components/flows-actors/approval.js.map +1 -1
- package/dist/esm/components/flows-actors/approval.labels.d.ts.map +1 -1
- package/dist/esm/components/flows-actors/approval.labels.js +3 -0
- package/dist/esm/components/flows-actors/approval.labels.js.map +1 -1
- package/dist/esm/components/flows-actors/execution-plan.js +1 -1
- package/dist/esm/components/flows-actors/execution-plan.js.map +1 -1
- package/dist/esm/components/flows-actors/task-memory.js +1 -1
- package/dist/esm/components/flows-actors/task-memory.js.map +1 -1
- package/dist/esm/components/form/automated/generated-relationship-field.hooks.d.ts +1 -1
- package/dist/esm/components/form/controls/number/slider.d.ts +1 -1
- package/dist/esm/components/form/fields/form-field-file-provider-constraints.frontend.utils.d.ts +1 -1
- package/dist/esm/components/form/fields/form-field-file-provider-constraints.frontend.utils.d.ts.map +1 -1
- package/dist/esm/components/form/fields/form-field-file-provider-constraints.frontend.utils.js.map +1 -1
- package/dist/esm/components/form/fields/form-field-file.d.ts.map +1 -1
- package/dist/esm/components/form/fields/form-field-file.js +66 -17
- package/dist/esm/components/form/fields/form-field-file.js.map +1 -1
- package/dist/esm/components/form/fields/form-field-file.labels.js +2 -2
- package/dist/esm/components/form/fields/form-field-file.labels.js.map +1 -1
- package/dist/esm/components/form/form-field-types.d.ts +20 -0
- package/dist/esm/components/form/form-field-types.d.ts.map +1 -1
- package/dist/esm/components/form/form-field-types.js.map +1 -1
- package/dist/esm/components/navigation/NavigationItemBadge.d.ts +7 -1
- package/dist/esm/components/navigation/NavigationItemBadge.d.ts.map +1 -1
- package/dist/esm/components/navigation/NavigationItemBadge.js +29 -1
- package/dist/esm/components/navigation/NavigationItemBadge.js.map +1 -1
- package/dist/esm/components/navigation/menu-bar.d.ts +1 -1
- package/dist/esm/components/overlays/containers/OverlayContainer.d.ts.map +1 -1
- package/dist/esm/components/overlays/containers/OverlayContainer.js +36 -9
- package/dist/esm/components/overlays/containers/OverlayContainer.js.map +1 -1
- package/dist/esm/components/overlays/floating/context-menu.d.ts +1 -1
- package/dist/esm/components/overlays/floating/dropdown-menu.d.ts +1 -1
- package/dist/esm/components/resources/ResourceLayout_FilterChips.js +1 -1
- package/dist/esm/components/resources/ResourceLayout_FilterChips.js.map +1 -1
- package/dist/esm/components/resources/ResourceListItemRenderer.js +1 -1
- package/dist/esm/components/resources/ResourceListItemRenderer.js.map +1 -1
- package/dist/esm/components/resources/skeleton/ResourceHeaderTitle.d.ts +12 -0
- package/dist/esm/components/resources/skeleton/ResourceHeaderTitle.d.ts.map +1 -1
- package/dist/esm/components/resources/skeleton/ResourceHeaderTitle.js +13 -1
- package/dist/esm/components/resources/skeleton/ResourceHeaderTitle.js.map +1 -1
- package/dist/esm/components/settings/AppPage_ConnectedAccountsSettings.d.ts +106 -49
- package/dist/esm/components/settings/AppPage_ConnectedAccountsSettings.d.ts.map +1 -1
- package/dist/esm/components/settings/AppPage_ConnectedAccountsSettings.js +311 -109
- package/dist/esm/components/settings/AppPage_ConnectedAccountsSettings.js.map +1 -1
- package/dist/esm/components/settings/AppPage_ConnectedAccountsSettings.labels.d.ts.map +1 -1
- package/dist/esm/components/settings/AppPage_ConnectedAccountsSettings.labels.js +32 -2
- package/dist/esm/components/settings/AppPage_ConnectedAccountsSettings.labels.js.map +1 -1
- package/dist/esm/components/settings/SettingsHub.d.ts.map +1 -1
- package/dist/esm/components/settings/SettingsHub.js +30 -6
- package/dist/esm/components/settings/SettingsHub.js.map +1 -1
- package/dist/esm/components/views/onboarding-view/OnboardingView.d.ts.map +1 -1
- package/dist/esm/components/views/onboarding-view/OnboardingView.js +9 -2
- package/dist/esm/components/views/onboarding-view/OnboardingView.js.map +1 -1
- package/dist/esm/core/automated-layout/automated-layout.frontend.schemas.d.ts +16 -0
- package/dist/esm/core/automated-layout/automated-layout.frontend.schemas.d.ts.map +1 -1
- package/dist/esm/core/automated-layout/automated-layout.frontend.schemas.js +17 -0
- package/dist/esm/core/automated-layout/automated-layout.frontend.schemas.js.map +1 -1
- package/dist/esm/core/automated-layout/default-layout-generator.frontend.utils.d.ts.map +1 -1
- package/dist/esm/core/automated-layout/default-layout-generator.frontend.utils.js +3 -2
- package/dist/esm/core/automated-layout/default-layout-generator.frontend.utils.js.map +1 -1
- package/dist/esm/core/billing/billing-launcher.js +1 -1
- package/dist/esm/core/billing/billing-launcher.js.map +1 -1
- package/dist/esm/core/components-registry/provider-component-registry.frontend.service.d.ts +64 -4
- package/dist/esm/core/components-registry/provider-component-registry.frontend.service.d.ts.map +1 -1
- package/dist/esm/core/components-registry/provider-component-registry.frontend.service.js +76 -4
- package/dist/esm/core/components-registry/provider-component-registry.frontend.service.js.map +1 -1
- package/dist/esm/core/components-registry/useProviderComponent.frontend.hooks.d.ts +8 -0
- package/dist/esm/core/components-registry/useProviderComponent.frontend.hooks.d.ts.map +1 -1
- package/dist/esm/core/components-registry/useProviderComponent.frontend.hooks.js +1 -0
- package/dist/esm/core/components-registry/useProviderComponent.frontend.hooks.js.map +1 -1
- package/dist/esm/core/config/chart-view.frontend.schemas.d.ts +8 -8
- package/dist/esm/core/config/composite-view.schemas.d.ts +4 -4
- package/dist/esm/core/config/engine-settings-destinations.d.ts +0 -69
- package/dist/esm/core/config/engine-settings-destinations.d.ts.map +1 -1
- package/dist/esm/core/config/engine-settings-destinations.js +35 -74
- package/dist/esm/core/config/engine-settings-destinations.js.map +1 -1
- package/dist/esm/core/config/settings-hub.frontend.schemas.d.ts +10 -1
- package/dist/esm/core/config/settings-hub.frontend.schemas.d.ts.map +1 -1
- package/dist/esm/core/config/settings-hub.frontend.schemas.js +9 -0
- package/dist/esm/core/config/settings-hub.frontend.schemas.js.map +1 -1
- package/dist/esm/core/config/useSettingsHubConfig.d.ts.map +1 -1
- package/dist/esm/core/config/useSettingsHubConfig.js +8 -1
- package/dist/esm/core/config/useSettingsHubConfig.js.map +1 -1
- package/dist/esm/core/events/events.frontend.schemas.d.ts +4 -4
- package/dist/esm/core/external-providers/ProviderFilePickerHost.d.ts +12 -1
- package/dist/esm/core/external-providers/ProviderFilePickerHost.d.ts.map +1 -1
- package/dist/esm/core/external-providers/ProviderFilePickerHost.js +15 -2
- package/dist/esm/core/external-providers/ProviderFilePickerHost.js.map +1 -1
- package/dist/esm/core/external-providers/provider-file-selection.frontend.utils.d.ts +1 -2
- package/dist/esm/core/external-providers/provider-file-selection.frontend.utils.d.ts.map +1 -1
- package/dist/esm/core/external-providers/provider-file-selection.frontend.utils.js.map +1 -1
- package/dist/esm/core/flows-actors/FlowsActorsContext.d.ts +6 -1
- package/dist/esm/core/flows-actors/FlowsActorsContext.d.ts.map +1 -1
- package/dist/esm/core/flows-actors/FlowsActorsContext.js +10 -2
- package/dist/esm/core/flows-actors/FlowsActorsContext.js.map +1 -1
- package/dist/esm/core/i18n/I18nContext.d.ts +23 -0
- package/dist/esm/core/i18n/I18nContext.d.ts.map +1 -1
- package/dist/esm/core/i18n/I18nContext.js +6 -1
- package/dist/esm/core/i18n/I18nContext.js.map +1 -1
- package/dist/esm/core/requests/wildo-http-client-manual-calls.frontend.service.d.ts +75 -2
- package/dist/esm/core/requests/wildo-http-client-manual-calls.frontend.service.d.ts.map +1 -1
- package/dist/esm/core/requests/wildo-http-client-manual-calls.frontend.service.js +52 -0
- package/dist/esm/core/requests/wildo-http-client-manual-calls.frontend.service.js.map +1 -1
- package/dist/esm/core/requests/wildo-http-client-resources.frontend.service.d.ts +3 -2
- package/dist/esm/core/requests/wildo-http-client-resources.frontend.service.d.ts.map +1 -1
- package/dist/esm/core/requests/wildo-http-client-resources.frontend.service.js +57 -4
- package/dist/esm/core/requests/wildo-http-client-resources.frontend.service.js.map +1 -1
- package/dist/esm/core/resources/ResourceReadCacheBridge.d.ts.map +1 -1
- package/dist/esm/core/resources/ResourceReadCacheBridge.js +130 -37
- package/dist/esm/core/resources/ResourceReadCacheBridge.js.map +1 -1
- package/dist/esm/core/resources/resources.frontend.schemas.d.ts +2 -2
- package/dist/esm/core/runtime/start-application.frontend.service.d.ts.map +1 -1
- package/dist/esm/core/runtime/start-application.frontend.service.js +17 -9
- package/dist/esm/core/runtime/start-application.frontend.service.js.map +1 -1
- package/dist/esm/core/security/UserOrgsContext.d.ts.map +1 -1
- package/dist/esm/core/security/UserOrgsContext.js +61 -5
- package/dist/esm/core/security/UserOrgsContext.js.map +1 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +6 -6
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"OnboardingView.js","sourceRoot":"","sources":["../../../../../src/components/views/onboarding-view/OnboardingView.tsx"],"names":[],"mappings":"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","sourcesContent":["/**\n * OnboardingView — Wizard-style onboarding view.\n *\n * Renders a sequence of guidance elements (checklist, tour, survey, etc.)\n * with step progression, progress bar, and navigation controls.\n * Integrates with GuidanceContext only when a matching `guidanceFlowRef` is\n * provided and falls back to local transient state when the view is rendered\n * directly from a static onboarding document.\n */\n\nimport React, { useState, useMemo, useCallback, useEffect, useId } from 'react';\nimport {\n OnboardingElementType,\n OnboardingStatus,\n isTerminalOnboardingStatus,\n type OnboardingElement,\n type OnboardingViewOptions,\n type GuidanceFlowState,\n} from '@wildo-ai/saas-models';\nimport type { OnboardingViewDefinition } from '~wildo-frontend-lib/core/config/onboarding-view.frontend.schemas';\nimport type { GuidanceElementState } from '@wildo-ai/saas-models';\nimport { FrontendComponentType } from '@wildo-ai/presets-components-models';\nimport { useGuidance } from '~wildo-frontend-lib/core/guidance/useGuidance';\nimport { useI18n } from '~wildo-frontend-lib/core/i18n/useI18n';\nimport { cn } from '~wildo-frontend-lib/core/ui/cn';\nimport type { GuidanceElementRendererProps } from '~wildo-frontend-lib/core/guidance/GuidanceRenderer';\n\n// Element renderers\nimport { GuidanceChecklist } from '~wildo-frontend-lib/core/guidance/renderers/GuidanceChecklist';\nimport { GuidanceChecklistItem } from '~wildo-frontend-lib/core/guidance/renderers/GuidanceChecklistItem';\nimport { GuidanceTour } from '~wildo-frontend-lib/core/guidance/renderers/GuidanceTour';\nimport { GuidanceTooltip } from '~wildo-frontend-lib/core/guidance/renderers/GuidanceTooltip';\nimport { GuidanceModal } from '~wildo-frontend-lib/core/guidance/renderers/GuidanceModal';\nimport { GuidanceBanner } from '~wildo-frontend-lib/core/guidance/renderers/GuidanceBanner';\nimport { GuidanceAnnouncement } from '~wildo-frontend-lib/core/guidance/renderers/GuidanceAnnouncement';\nimport { GuidanceBadge } from '~wildo-frontend-lib/core/guidance/renderers/GuidanceBadge';\nimport { GuidanceCard } from '~wildo-frontend-lib/core/guidance/renderers/GuidanceCard';\nimport { GuidanceSurvey } from '~wildo-frontend-lib/core/guidance/renderers/GuidanceSurvey';\n\n// ─── Element Type → Component Map ────────────────────────────\n\nconst ELEMENT_RENDERER_MAP: Record<OnboardingElementType, React.FC<GuidanceElementRendererProps>> = {\n [OnboardingElementType.CHECKLIST]: GuidanceChecklist,\n [OnboardingElementType.CHECKLIST_ITEM]: GuidanceChecklistItem,\n [OnboardingElementType.TOUR]: GuidanceTour,\n [OnboardingElementType.TOOLTIP]: GuidanceTooltip,\n [OnboardingElementType.MODAL]: GuidanceModal,\n [OnboardingElementType.BANNER]: GuidanceBanner,\n [OnboardingElementType.ANNOUNCEMENT]: GuidanceAnnouncement,\n [OnboardingElementType.BADGE]: GuidanceBadge,\n [OnboardingElementType.CARD]: GuidanceCard,\n [OnboardingElementType.SURVEY]: GuidanceSurvey,\n};\n\n// ─── Props ───────────────────────────────────────────────────\n\nexport interface OnboardingViewProps {\n /** Onboarding document with elements */\n document: OnboardingViewDefinition;\n /** Additional options to override document options */\n options?: Partial<OnboardingViewOptions>;\n /** Custom class name */\n className?: string;\n /** Callback when element status changes */\n onStatusChange?: (elementRef: string, status: OnboardingStatus) => void;\n /** Callback when action is triggered */\n onAction?: (elementRef: string, actionRef?: string) => void;\n /** View reference for i18n/view identity when rendered from a larger document */\n viewRef?: string;\n /**\n * Connects this view to a persisted guidance flow.\n *\n * When provided, dismiss / complete / skip actions are forwarded to\n * `GuidanceContext` and persisted to the backend. Must match a\n * `GuidanceFlowDefinition.ref` registered in the app's guidance config.\n *\n * When omitted, the view operates in local-only mode — all state is\n * transient and resets on unmount. A console warning is emitted to\n * flag the non-persisted mode.\n */\n guidanceFlowRef?: string;\n}\n\n// ─── Component ───────────────────────────────────────────────\n\nexport const OnboardingView: React.FC<OnboardingViewProps> = ({\n document: doc,\n options: optionsOverride = {},\n className = '',\n onStatusChange,\n onAction,\n viewRef: viewRefProp,\n guidanceFlowRef: guidanceFlowRefProp,\n}) => {\n const { flowStates, completeElement, completeFlow, dismissFlow, skipFlow, isFlowPersistable, isLoading: guidanceIsLoading } = useGuidance();\n const localFlowId = useId();\n const guidanceFlowRef = guidanceFlowRefProp;\n /**\n * Persistence identity follows CONTENT: default to the document's own ref when\n * no explicit `guidanceFlowRef` override is given (mirrors `translationRef`).\n * Dismiss / complete / skip then persist under `doc.ref` for a first-class\n * onboarding view registered in app config — no parallel guidance flow needed.\n */\n const persistenceFlowRef = guidanceFlowRef ?? doc.ref;\n /**\n * Whether persistence will actually happen — `persistenceFlowRef` resolves to a\n * registered guidance flow OR an app-config onboarding view. When false the view\n * is a transient local-only embed (ad-hoc inline document not in config).\n */\n const isPersisted = isFlowPersistable(persistenceFlowRef);\n const flowRef = persistenceFlowRef ?? `onboarding-local-${localFlowId}`;\n /**\n * i18n namespace for this view's element labels. Element labels are read as\n * `guidance.{translationRef}.elements.{el}.{key}` (see `makeTrGuidanceElement`\n * below and `tGuidanceElement` in `core/i18n/I18nContext`).\n *\n * Translation identity follows CONTENT, not persistence. The elements this\n * view renders are `doc.elements`, so their labels belong under the document's\n * OWN ref — symmetric with `GuidanceRenderer`, which scopes a flow's elements\n * under `flow.ref`. `guidanceFlowRef` is a SEPARATE, persistence-only identity\n * (it drives complete/dismiss/skip + the `flowStates` lookup) and may name a\n * flow whose element set differs entirely from `doc.elements` — e.g. a 3-step\n * wizard document (`focus-hub-step-*`) persisted through a single-card flow\n * (`focus-hub-guide-card`). Namespacing the document's element refs under that\n * foreign flow ref resolves keys that were never generated for them: the\n * footgun this precedence closes.\n *\n * Precedence:\n * 1. `viewRefProp` — explicit override; caller knows the canonical ref\n * (e.g. this view is one surface of a larger document).\n * 2. `doc.ref` — the document's own content identity (the normal\n * case; `OnboardingViewDefinition.ref` is\n * `z.string().min(1)`, so it is present and non-empty\n * for every well-formed document).\n * 3. `guidanceFlowRef` — last-resort identity ONLY when `doc.ref` is absent\n * (untyped/malformed callers); preserves the prior\n * persisted-flow lookup instead of collapsing to (4).\n * 4. `'onboarding'` — generic terminal fallback.\n *\n * Rejected `viewRefProp || guidanceFlowRef || doc.ref || 'onboarding'`: that\n * keeps PERSISTENCE ahead of CONTENT, so any caller passing a divergent\n * `guidanceFlowRef` without a `viewRef` would re-open the exact footgun above.\n * It is also behaviorally identical to this ordering for every current\n * consumer (the only `guidanceFlowRef` caller also passes `viewRef`), so the\n * \"smaller diff\" argument buys no safety — only the wrong default semantics.\n */\n const translationRef = viewRefProp || doc.ref || guidanceFlowRef || 'onboarding';\n const guidanceKeys = useMemo(() => [`guidance.${translationRef}`], [translationRef]);\n const { makeTrGuidanceElement, tComponent, isReady } = useI18n({\n component: FrontendComponentType.GUIDANCE_ONBOARDING_VIEW,\n keys: guidanceKeys,\n });\n\n useEffect(() => {\n if (!isPersisted) {\n const elementRefs = doc.elements.map(el => el.ref).join(', ');\n console.warn(\n `[OnboardingView] Mounted with no persistable identity (ref=\"${persistenceFlowRef ?? '(none)'}\", ` +\n `viewRef=\"${viewRefProp ?? '(none)'}\", elements=[${elementRefs}]). Dismiss, complete, and skip ` +\n 'actions will only affect local component state and will NOT be persisted to the backend. To ' +\n 'persist, either declare this onboarding view (by ref) in the app frontend config so it is ' +\n 'registered, or pass the guidanceFlowRef prop matching a registered GuidanceFlowDefinition.',\n );\n }\n }, []); // eslint-disable-line react-hooks/exhaustive-deps -- intentional mount-only check\n\n const mergedOptions = useMemo<OnboardingViewOptions>(\n () => ({ ...doc.options, ...optionsOverride }),\n [doc.options, optionsOverride],\n );\n\n // Sort elements by order\n const sortedElements = useMemo<OnboardingElement[]>(\n () => [...doc.elements].sort((a, b) => a.order - b.order),\n [doc.elements],\n );\n\n // Step tracking for wizard mode\n const [currentStepIndex, setCurrentStepIndex] = useState(0);\n const [localFlowState, setLocalFlowState] = useState<GuidanceFlowState>({\n status: OnboardingStatus.IN_PROGRESS,\n elements: {},\n triggerCount: 1,\n });\n const totalSteps = sortedElements.length;\n\n useEffect(() => {\n setCurrentStepIndex(0);\n setLocalFlowState({\n status: OnboardingStatus.IN_PROGRESS,\n elements: {},\n triggerCount: 1,\n });\n }, [flowRef]);\n\n // Derive flow state from GuidanceContext when persistable; else local transient.\n const flowState = isPersisted ? (flowStates[persistenceFlowRef] ?? localFlowState) : localFlowState;\n\n const getElementState = useCallback(\n (elementRef: string): GuidanceElementState | undefined =>\n flowState?.elements?.[elementRef],\n [flowState],\n );\n\n // Count completed elements\n const completedCount = useMemo(() => {\n if (!flowState?.elements) return 0;\n return Object.values(flowState.elements).filter(\n s => s.status === OnboardingStatus.COMPLETED,\n ).length;\n }, [flowState]);\n\n // ─── Handlers ────────────────────────────────────────────\n\n const setLocalElementStatus = useCallback((\n elementRef: string,\n status: OnboardingStatus,\n data?: { surveyAnswers?: GuidanceElementState['surveyAnswers']; lastStepIndex?: number },\n ) => {\n const completedAt = status === OnboardingStatus.COMPLETED ? new Date() : undefined;\n setLocalFlowState(prev => ({\n ...prev,\n elements: {\n ...prev.elements,\n [elementRef]: {\n ...prev.elements[elementRef],\n status,\n completedAt,\n surveyAnswers: data?.surveyAnswers ?? prev.elements[elementRef]?.surveyAnswers,\n lastStepIndex: data?.lastStepIndex ?? prev.elements[elementRef]?.lastStepIndex,\n },\n },\n }));\n }, []);\n\n const setLocalFlowStatus = useCallback((status: OnboardingStatus) => {\n const now = new Date();\n setLocalFlowState(prev => ({\n ...prev,\n status,\n completedAt: status === OnboardingStatus.COMPLETED ? now : prev.completedAt,\n dismissedAt: status === OnboardingStatus.DISMISSED ? now : prev.dismissedAt,\n }));\n }, []);\n\n const handleComplete = useCallback(\n (elementRef: string, data?: { surveyAnswers?: GuidanceElementState['surveyAnswers']; lastStepIndex?: number }) => {\n setLocalElementStatus(elementRef, OnboardingStatus.COMPLETED, data);\n if (isPersisted) {\n completeElement(persistenceFlowRef, elementRef, data);\n }\n onStatusChange?.(elementRef, OnboardingStatus.COMPLETED);\n\n // Auto-advance to next step if not on last\n if (currentStepIndex < totalSteps - 1) {\n setCurrentStepIndex(prev => prev + 1);\n } else {\n setLocalFlowStatus(OnboardingStatus.COMPLETED);\n if (isPersisted) {\n completeFlow(persistenceFlowRef);\n }\n }\n },\n [completeElement, completeFlow, currentStepIndex, isPersisted, persistenceFlowRef, onStatusChange, setLocalElementStatus, setLocalFlowStatus, totalSteps],\n );\n\n const handleDismiss = useCallback(\n (elementRef: string) => {\n setLocalElementStatus(elementRef, OnboardingStatus.DISMISSED);\n onStatusChange?.(elementRef, OnboardingStatus.DISMISSED);\n if (mergedOptions.allowDismiss) {\n setLocalFlowStatus(OnboardingStatus.DISMISSED);\n if (isPersisted) {\n dismissFlow(persistenceFlowRef);\n }\n }\n },\n [dismissFlow, isPersisted, persistenceFlowRef, mergedOptions.allowDismiss, onStatusChange, setLocalElementStatus, setLocalFlowStatus],\n );\n\n const handleAction = useCallback(\n (actionRef: string) => {\n const currentElement = sortedElements[currentStepIndex];\n onAction?.(currentElement?.ref ?? '', actionRef);\n },\n [onAction, sortedElements, currentStepIndex],\n );\n\n const handleNext = useCallback(() => {\n if (currentStepIndex < totalSteps - 1) {\n setCurrentStepIndex(prev => prev + 1);\n return;\n }\n\n const currentElement = sortedElements[currentStepIndex];\n if (!currentElement) {\n setLocalFlowStatus(OnboardingStatus.COMPLETED);\n if (isPersisted) {\n completeFlow(persistenceFlowRef);\n }\n return;\n }\n\n handleComplete(currentElement.ref);\n }, [currentStepIndex, totalSteps, sortedElements, handleComplete, completeFlow, isPersisted, persistenceFlowRef, setLocalFlowStatus]);\n\n const handleBack = useCallback(() => {\n if (currentStepIndex > 0) {\n setCurrentStepIndex(prev => prev - 1);\n }\n }, [currentStepIndex]);\n\n const handleSkip = useCallback(() => {\n setLocalFlowStatus(OnboardingStatus.SKIPPED);\n if (isPersisted) {\n skipFlow(persistenceFlowRef);\n }\n }, [isPersisted, persistenceFlowRef, setLocalFlowStatus, skipFlow]);\n\n // ─── Render ──────────────────────────────────────────────\n\n if (!isReady) return null;\n\n // Hydration-flash guard: a PERSISTED onboarding view must not paint its\n // default (IN_PROGRESS) content before the backend-persisted flow state has\n // loaded — otherwise a view the user already dismissed / completed / skipped\n // flashes in and then vanishes once `flowStates` hydrates. Local-only\n // (non-persisted) views have no backend state to wait for, so they render\n // immediately. Once loading settles, `flowState` reflects the true status\n // (terminal → stays hidden; otherwise renders).\n if (isPersisted && guidanceIsLoading) return null;\n\n if (sortedElements.length === 0) {\n return (\n <div className={cn('p-container-xl text-center text-muted-foreground', className)}>\n {tComponent(FrontendComponentType.GUIDANCE_ONBOARDING_VIEW, 'empty')}\n </div>\n );\n }\n\n // A terminal flow status closes the view: the onboarding sequence is over.\n // COMPLETED (last step finished), DISMISSED (user closed), and SKIPPED (user\n // skipped) all mean \"stop rendering\". COMPLETED was previously missing from\n // this gate, so finishing the last step persisted the completion + called\n // `completeFlow(...)` but left the final modal on screen (\"not dismissed at\n // the end\"): the view kept rendering `currentElement` (still the last step).\n // Use the canonical `isTerminalOnboardingStatus` helper so this gate can never\n // drift from the lifecycle status set again (mirrors the GuidanceContext\n // complete/dismiss/skip guards).\n if (isTerminalOnboardingStatus(flowState?.status)) {\n return null;\n }\n\n const currentElement = sortedElements[currentStepIndex];\n if (!currentElement) return null;\n\n const Renderer = ELEMENT_RENDERER_MAP[currentElement.type];\n const elementState = getElementState(currentElement.ref);\n const scopedT = makeTrGuidanceElement(translationRef, currentElement.ref);\n\n return (\n <div className={cn('flex flex-col gap-element', className)}>\n {/* Progress bar */}\n {mergedOptions.showProgress && totalSteps > 1 && (\n <div className=\"flex flex-col gap-item-xs\">\n <div className=\"flex justify-between items-center text-[0.8125rem] text-muted-foreground font-medium\">\n <span>\n {tComponent(FrontendComponentType.GUIDANCE_ONBOARDING_VIEW, 'stepOf', {\n current: currentStepIndex + 1,\n total: totalSteps,\n })}\n </span>\n <span className=\"text-xs\">\n {completedCount}/{totalSteps}\n </span>\n </div>\n\n {/* Progress bar track */}\n <div\n className=\"w-full h-1 bg-muted rounded-sm overflow-hidden\"\n role=\"progressbar\"\n aria-valuenow={currentStepIndex + 1}\n aria-valuemin={1}\n aria-valuemax={totalSteps}\n >\n <div\n className=\"h-full bg-primary rounded-sm motion-safe:transition-[width] motion-safe:duration-[var(--motion-duration-normal)] motion-safe:ease-out\"\n style={{ width: `${totalSteps > 0 ? ((currentStepIndex + 1) / totalSteps) * 100 : 0}%` }}\n />\n </div>\n </div>\n )}\n\n {/* Current element renderer */}\n {Renderer && (\n <Renderer\n element={currentElement}\n flowRef={flowRef}\n state={elementState}\n onComplete={handleComplete}\n onDismiss={handleDismiss}\n onAction={handleAction}\n t={scopedT}\n />\n )}\n\n {/* Navigation controls */}\n {totalSteps > 1 && (\n <div className=\"flex justify-between items-center pt-item\">\n {/* Left: Back */}\n <div>\n {currentStepIndex > 0 && (\n // V-5: candidate for Button/IconButton migration — see audit doc\n // (raw <button> reimplements OUTLINE/GHOST recipe with non-ladder text-[0.8125rem])\n <button\n type=\"button\"\n onClick={handleBack}\n className=\"px-card py-item text-[0.8125rem] font-medium text-muted-foreground bg-transparent border border-border rounded-md cursor-pointer motion-safe:transition-colors hover:bg-muted focus-ring-offset pointer-coarse:min-h-11\"\n >\n {tComponent(FrontendComponentType.GUIDANCE_ONBOARDING_VIEW, 'back')}\n </button>\n )}\n </div>\n\n {/* Right: Skip / Next / Complete */}\n <div className=\"flex gap-item items-center\">\n {mergedOptions.allowSkip && (\n // V-5: candidate for Button/IconButton migration — see audit doc\n // (raw <button> reimplements GHOST recipe with non-ladder text-[0.8125rem])\n <button\n type=\"button\"\n onClick={handleSkip}\n className=\"px-card-sm py-item text-[0.8125rem] font-medium text-muted-foreground/70 bg-transparent border-none cursor-pointer motion-safe:transition-colors hover:text-muted-foreground focus-ring-offset pointer-coarse:min-h-11\"\n >\n {tComponent(FrontendComponentType.GUIDANCE_ONBOARDING_VIEW, 'skip')}\n </button>\n )}\n\n {/* V-5: candidate for Button/IconButton migration — see audit doc */}\n {/* (raw <button> reimplements PRIMARY recipe with non-ladder text-[0.8125rem]) */}\n <button\n type=\"button\"\n onClick={handleNext}\n className=\"px-card py-item text-[0.8125rem] font-medium text-primary-foreground bg-primary border-none rounded-md cursor-pointer motion-safe:transition-colors hover:bg-primary/90 focus-ring-offset pointer-coarse:min-h-11\"\n >\n {currentStepIndex === totalSteps - 1\n ? tComponent(FrontendComponentType.GUIDANCE_ONBOARDING_VIEW, 'complete')\n : tComponent(FrontendComponentType.GUIDANCE_ONBOARDING_VIEW, 'next')}\n </button>\n </div>\n </div>\n )}\n\n {/* Single-step footer fallback: some renderers do not expose their own completion action. */}\n {totalSteps === 1 && (\n <div className=\"flex justify-end gap-item items-center\">\n {mergedOptions.allowDismiss && (\n // V-5: candidate for Button/IconButton migration — see audit doc\n // (raw <button> reimplements GHOST recipe with non-ladder text-[0.8125rem])\n <button\n type=\"button\"\n onClick={() => handleDismiss(currentElement.ref)}\n className=\"px-card-sm py-item text-[0.8125rem] font-medium text-muted-foreground/70 bg-transparent border-none cursor-pointer motion-safe:transition-colors hover:text-muted-foreground focus-ring-offset pointer-coarse:min-h-11\"\n >\n {tComponent(FrontendComponentType.GUIDANCE_ONBOARDING_VIEW, 'dismiss')}\n </button>\n )}\n\n {/* V-5: candidate for Button/IconButton migration — see audit doc */}\n {/* (raw <button> reimplements PRIMARY recipe with non-ladder text-[0.8125rem]) */}\n <button\n type=\"button\"\n onClick={handleNext}\n className=\"px-card py-item text-[0.8125rem] font-medium text-primary-foreground bg-primary border-none rounded-md cursor-pointer motion-safe:transition-colors hover:bg-primary/90 focus-ring-offset pointer-coarse:min-h-11\"\n >\n {tComponent(FrontendComponentType.GUIDANCE_ONBOARDING_VIEW, 'complete')}\n </button>\n </div>\n )}\n </div>\n );\n};\n"]}
|
|
1
|
+
{"version":3,"file":"OnboardingView.js","sourceRoot":"","sources":["../../../../../src/components/views/onboarding-view/OnboardingView.tsx"],"names":[],"mappings":"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","sourcesContent":["/**\n * OnboardingView — Wizard-style onboarding view.\n *\n * Renders a sequence of guidance elements (checklist, tour, survey, etc.)\n * with step progression, progress bar, and navigation controls.\n * Integrates with GuidanceContext only when a matching `guidanceFlowRef` is\n * provided and falls back to local transient state when the view is rendered\n * directly from a static onboarding document.\n */\n\nimport React, { useState, useMemo, useCallback, useEffect, useId } from 'react';\nimport {\n OnboardingElementType,\n OnboardingStatus,\n isTerminalOnboardingStatus,\n type OnboardingElement,\n type OnboardingViewOptions,\n type GuidanceFlowState,\n} from '@wildo-ai/saas-models';\nimport type { OnboardingViewDefinition } from '~wildo-frontend-lib/core/config/onboarding-view.frontend.schemas';\nimport type { GuidanceElementState } from '@wildo-ai/saas-models';\nimport { FrontendComponentType } from '@wildo-ai/presets-components-models';\nimport { useGuidance } from '~wildo-frontend-lib/core/guidance/useGuidance';\nimport { useI18n } from '~wildo-frontend-lib/core/i18n/useI18n';\nimport { cn } from '~wildo-frontend-lib/core/ui/cn';\nimport type { GuidanceElementRendererProps } from '~wildo-frontend-lib/core/guidance/GuidanceRenderer';\n\n// Element renderers\nimport { GuidanceChecklist } from '~wildo-frontend-lib/core/guidance/renderers/GuidanceChecklist';\nimport { GuidanceChecklistItem } from '~wildo-frontend-lib/core/guidance/renderers/GuidanceChecklistItem';\nimport { GuidanceTour } from '~wildo-frontend-lib/core/guidance/renderers/GuidanceTour';\nimport { GuidanceTooltip } from '~wildo-frontend-lib/core/guidance/renderers/GuidanceTooltip';\nimport { GuidanceModal } from '~wildo-frontend-lib/core/guidance/renderers/GuidanceModal';\nimport { GuidanceBanner } from '~wildo-frontend-lib/core/guidance/renderers/GuidanceBanner';\nimport { GuidanceAnnouncement } from '~wildo-frontend-lib/core/guidance/renderers/GuidanceAnnouncement';\nimport { GuidanceBadge } from '~wildo-frontend-lib/core/guidance/renderers/GuidanceBadge';\nimport { GuidanceCard } from '~wildo-frontend-lib/core/guidance/renderers/GuidanceCard';\nimport { GuidanceSurvey } from '~wildo-frontend-lib/core/guidance/renderers/GuidanceSurvey';\n\n// ─── Element Type → Component Map ────────────────────────────\n\nconst ELEMENT_RENDERER_MAP: Record<OnboardingElementType, React.FC<GuidanceElementRendererProps>> = {\n [OnboardingElementType.CHECKLIST]: GuidanceChecklist,\n [OnboardingElementType.CHECKLIST_ITEM]: GuidanceChecklistItem,\n [OnboardingElementType.TOUR]: GuidanceTour,\n [OnboardingElementType.TOOLTIP]: GuidanceTooltip,\n [OnboardingElementType.MODAL]: GuidanceModal,\n [OnboardingElementType.BANNER]: GuidanceBanner,\n [OnboardingElementType.ANNOUNCEMENT]: GuidanceAnnouncement,\n [OnboardingElementType.BADGE]: GuidanceBadge,\n [OnboardingElementType.CARD]: GuidanceCard,\n [OnboardingElementType.SURVEY]: GuidanceSurvey,\n};\n\n// ─── Props ───────────────────────────────────────────────────\n\nexport interface OnboardingViewProps {\n /** Onboarding document with elements */\n document: OnboardingViewDefinition;\n /** Additional options to override document options */\n options?: Partial<OnboardingViewOptions>;\n /** Custom class name */\n className?: string;\n /** Callback when element status changes */\n onStatusChange?: (elementRef: string, status: OnboardingStatus) => void;\n /** Callback when action is triggered */\n onAction?: (elementRef: string, actionRef?: string) => void;\n /** View reference for i18n/view identity when rendered from a larger document */\n viewRef?: string;\n /**\n * Connects this view to a persisted guidance flow.\n *\n * When provided, dismiss / complete / skip actions are forwarded to\n * `GuidanceContext` and persisted to the backend. Must match a\n * `GuidanceFlowDefinition.ref` registered in the app's guidance config.\n *\n * When omitted, the view operates in local-only mode — all state is\n * transient and resets on unmount. A console warning is emitted to\n * flag the non-persisted mode.\n */\n guidanceFlowRef?: string;\n}\n\n// ─── Component ───────────────────────────────────────────────\n\nexport const OnboardingView: React.FC<OnboardingViewProps> = ({\n document: doc,\n options: optionsOverride = {},\n className = '',\n onStatusChange,\n onAction,\n viewRef: viewRefProp,\n guidanceFlowRef: guidanceFlowRefProp,\n}) => {\n const { flowStates, completeElement, completeFlow, dismissFlow, skipFlow, isFlowPersistable, isLoading: guidanceIsLoading } = useGuidance();\n const localFlowId = useId();\n const guidanceFlowRef = guidanceFlowRefProp;\n /**\n * Persistence identity follows CONTENT: default to the document's own ref when\n * no explicit `guidanceFlowRef` override is given (mirrors `translationRef`).\n * Dismiss / complete / skip then persist under `doc.ref` for a first-class\n * onboarding view registered in app config — no parallel guidance flow needed.\n */\n const persistenceFlowRef = guidanceFlowRef ?? doc.ref;\n /**\n * Whether persistence will actually happen — `persistenceFlowRef` resolves to a\n * registered guidance flow OR an app-config onboarding view. When false the view\n * is a transient local-only embed (ad-hoc inline document not in config).\n */\n const isPersisted = isFlowPersistable(persistenceFlowRef);\n const flowRef = persistenceFlowRef ?? `onboarding-local-${localFlowId}`;\n /**\n * i18n namespace for this view's element labels. Element labels are read as\n * `guidance.{translationRef}.elements.{el}.{key}` (see `makeTrGuidanceElement`\n * below and `tGuidanceElement` in `core/i18n/I18nContext`).\n *\n * Translation identity follows CONTENT, not persistence. The elements this\n * view renders are `doc.elements`, so their labels belong under the document's\n * OWN ref — symmetric with `GuidanceRenderer`, which scopes a flow's elements\n * under `flow.ref`. `guidanceFlowRef` is a SEPARATE, persistence-only identity\n * (it drives complete/dismiss/skip + the `flowStates` lookup) and may name a\n * flow whose element set differs entirely from `doc.elements` — e.g. a 3-step\n * wizard document (`focus-hub-step-*`) persisted through a single-card flow\n * (`focus-hub-guide-card`). Namespacing the document's element refs under that\n * foreign flow ref resolves keys that were never generated for them: the\n * footgun this precedence closes.\n *\n * Precedence:\n * 1. `viewRefProp` — explicit override; caller knows the canonical ref\n * (e.g. this view is one surface of a larger document).\n * 2. `doc.ref` — the document's own content identity (the normal\n * case; `OnboardingViewDefinition.ref` is\n * `z.string().min(1)`, so it is present and non-empty\n * for every well-formed document).\n * 3. `guidanceFlowRef` — last-resort identity ONLY when `doc.ref` is absent\n * (untyped/malformed callers); preserves the prior\n * persisted-flow lookup instead of collapsing to (4).\n * 4. `'onboarding'` — generic terminal fallback.\n *\n * Rejected `viewRefProp || guidanceFlowRef || doc.ref || 'onboarding'`: that\n * keeps PERSISTENCE ahead of CONTENT, so any caller passing a divergent\n * `guidanceFlowRef` without a `viewRef` would re-open the exact footgun above.\n * It is also behaviorally identical to this ordering for every current\n * consumer (the only `guidanceFlowRef` caller also passes `viewRef`), so the\n * \"smaller diff\" argument buys no safety — only the wrong default semantics.\n */\n const translationRef = viewRefProp || doc.ref || guidanceFlowRef || 'onboarding';\n const guidanceKeys = useMemo(() => [`guidance.${translationRef}`], [translationRef]);\n const { makeTrGuidanceElement, tComponent, isReady } = useI18n({\n component: FrontendComponentType.GUIDANCE_ONBOARDING_VIEW,\n keys: guidanceKeys,\n });\n\n useEffect(() => {\n if (!isPersisted) {\n const elementRefs = doc.elements.map(el => el.ref).join(', ');\n console.warn(\n `[OnboardingView] Mounted with no persistable identity (ref=\"${persistenceFlowRef ?? '(none)'}\", ` +\n `viewRef=\"${viewRefProp ?? '(none)'}\", elements=[${elementRefs}]). Dismiss, complete, and skip ` +\n 'actions will only affect local component state and will NOT be persisted to the backend. To ' +\n 'persist, either declare this onboarding view (by ref) in the app frontend config so it is ' +\n 'registered, or pass the guidanceFlowRef prop matching a registered GuidanceFlowDefinition.',\n );\n }\n }, []); // eslint-disable-line react-hooks/exhaustive-deps -- intentional mount-only check\n\n const mergedOptions = useMemo<OnboardingViewOptions>(\n () => ({ ...doc.options, ...optionsOverride }),\n [doc.options, optionsOverride],\n );\n\n // Sort elements by order\n const sortedElements = useMemo<OnboardingElement[]>(\n () => [...doc.elements].sort((a, b) => a.order - b.order),\n [doc.elements],\n );\n\n // Step tracking for wizard mode\n const [currentStepIndex, setCurrentStepIndex] = useState(0);\n const [localFlowState, setLocalFlowState] = useState<GuidanceFlowState>({\n status: OnboardingStatus.IN_PROGRESS,\n elements: {},\n triggerCount: 1,\n });\n const totalSteps = sortedElements.length;\n\n useEffect(() => {\n setCurrentStepIndex(0);\n setLocalFlowState({\n status: OnboardingStatus.IN_PROGRESS,\n elements: {},\n triggerCount: 1,\n });\n }, [flowRef]);\n\n // Derive flow state from GuidanceContext when persistable; else local transient.\n const flowState = isPersisted ? (flowStates[persistenceFlowRef] ?? localFlowState) : localFlowState;\n\n const getElementState = useCallback(\n (elementRef: string): GuidanceElementState | undefined =>\n flowState?.elements?.[elementRef],\n [flowState],\n );\n\n // Count completed elements\n const completedCount = useMemo(() => {\n if (!flowState?.elements) return 0;\n return Object.values(flowState.elements).filter(\n s => s.status === OnboardingStatus.COMPLETED,\n ).length;\n }, [flowState]);\n\n // ─── Handlers ────────────────────────────────────────────\n\n const setLocalElementStatus = useCallback((\n elementRef: string,\n status: OnboardingStatus,\n data?: { surveyAnswers?: GuidanceElementState['surveyAnswers']; lastStepIndex?: number },\n ) => {\n const completedAt = status === OnboardingStatus.COMPLETED ? new Date() : undefined;\n setLocalFlowState(prev => ({\n ...prev,\n elements: {\n ...prev.elements,\n [elementRef]: {\n ...prev.elements[elementRef],\n status,\n completedAt,\n surveyAnswers: data?.surveyAnswers ?? prev.elements[elementRef]?.surveyAnswers,\n lastStepIndex: data?.lastStepIndex ?? prev.elements[elementRef]?.lastStepIndex,\n },\n },\n }));\n }, []);\n\n const setLocalFlowStatus = useCallback((status: OnboardingStatus) => {\n const now = new Date();\n setLocalFlowState(prev => ({\n ...prev,\n status,\n completedAt: status === OnboardingStatus.COMPLETED ? now : prev.completedAt,\n dismissedAt: status === OnboardingStatus.DISMISSED ? now : prev.dismissedAt,\n }));\n }, []);\n\n const handleComplete = useCallback(\n (elementRef: string, data?: { surveyAnswers?: GuidanceElementState['surveyAnswers']; lastStepIndex?: number }) => {\n setLocalElementStatus(elementRef, OnboardingStatus.COMPLETED, data);\n if (isPersisted) {\n completeElement(persistenceFlowRef, elementRef, data);\n }\n onStatusChange?.(elementRef, OnboardingStatus.COMPLETED);\n\n // Auto-advance to next step if not on last\n if (currentStepIndex < totalSteps - 1) {\n setCurrentStepIndex(prev => prev + 1);\n } else {\n setLocalFlowStatus(OnboardingStatus.COMPLETED);\n if (isPersisted) {\n completeFlow(persistenceFlowRef);\n }\n }\n },\n [completeElement, completeFlow, currentStepIndex, isPersisted, persistenceFlowRef, onStatusChange, setLocalElementStatus, setLocalFlowStatus, totalSteps],\n );\n\n const handleDismiss = useCallback(\n (elementRef: string) => {\n setLocalElementStatus(elementRef, OnboardingStatus.DISMISSED);\n onStatusChange?.(elementRef, OnboardingStatus.DISMISSED);\n if (mergedOptions.allowDismiss) {\n setLocalFlowStatus(OnboardingStatus.DISMISSED);\n if (isPersisted) {\n dismissFlow(persistenceFlowRef);\n }\n }\n },\n [dismissFlow, isPersisted, persistenceFlowRef, mergedOptions.allowDismiss, onStatusChange, setLocalElementStatus, setLocalFlowStatus],\n );\n\n const handleAction = useCallback(\n (actionRef: string) => {\n const currentElement = sortedElements[currentStepIndex];\n onAction?.(currentElement?.ref ?? '', actionRef);\n },\n [onAction, sortedElements, currentStepIndex],\n );\n\n const handleNext = useCallback(() => {\n if (currentStepIndex < totalSteps - 1) {\n setCurrentStepIndex(prev => prev + 1);\n return;\n }\n\n const currentElement = sortedElements[currentStepIndex];\n if (!currentElement) {\n setLocalFlowStatus(OnboardingStatus.COMPLETED);\n if (isPersisted) {\n completeFlow(persistenceFlowRef);\n }\n return;\n }\n\n handleComplete(currentElement.ref);\n }, [currentStepIndex, totalSteps, sortedElements, handleComplete, completeFlow, isPersisted, persistenceFlowRef, setLocalFlowStatus]);\n\n const handleBack = useCallback(() => {\n if (currentStepIndex > 0) {\n setCurrentStepIndex(prev => prev - 1);\n }\n }, [currentStepIndex]);\n\n const handleSkip = useCallback(() => {\n setLocalFlowStatus(OnboardingStatus.SKIPPED);\n if (isPersisted) {\n skipFlow(persistenceFlowRef);\n }\n }, [isPersisted, persistenceFlowRef, setLocalFlowStatus, skipFlow]);\n\n // ─── Render ──────────────────────────────────────────────\n\n if (!isReady) return null;\n\n // Hydration-flash guard: a PERSISTED onboarding view must not paint its\n // default (IN_PROGRESS) content before the backend-persisted flow state has\n // loaded — otherwise a view the user already dismissed / completed / skipped\n // flashes in and then vanishes once `flowStates` hydrates. Local-only\n // (non-persisted) views have no backend state to wait for, so they render\n // immediately. Once loading settles, `flowState` reflects the true status\n // (terminal → stays hidden; otherwise renders).\n if (isPersisted && guidanceIsLoading) return null;\n\n if (sortedElements.length === 0) {\n return (\n <div className={cn('p-container-xl text-center text-muted-foreground', className)}>\n {tComponent(FrontendComponentType.GUIDANCE_ONBOARDING_VIEW, 'empty')}\n </div>\n );\n }\n\n // A terminal flow status closes the view: the onboarding sequence is over.\n // COMPLETED (last step finished), DISMISSED (user closed), and SKIPPED (user\n // skipped) all mean \"stop rendering\". COMPLETED was previously missing from\n // this gate, so finishing the last step persisted the completion + called\n // `completeFlow(...)` but left the final modal on screen (\"not dismissed at\n // the end\"): the view kept rendering `currentElement` (still the last step).\n // Use the canonical `isTerminalOnboardingStatus` helper so this gate can never\n // drift from the lifecycle status set again (mirrors the GuidanceContext\n // complete/dismiss/skip guards).\n if (isTerminalOnboardingStatus(flowState?.status)) {\n return null;\n }\n\n const currentElement = sortedElements[currentStepIndex];\n if (!currentElement) return null;\n\n const Renderer = ELEMENT_RENDERER_MAP[currentElement.type];\n const elementState = getElementState(currentElement.ref);\n const scopedT = makeTrGuidanceElement(translationRef, currentElement.ref);\n\n return (\n <div className={cn('flex flex-col gap-element', className)}>\n {/* Progress bar */}\n {mergedOptions.showProgress && totalSteps > 1 && (\n <div className=\"flex flex-col gap-item-xs\">\n <div className=\"flex justify-between items-center text-[0.8125rem] text-muted-foreground font-medium\">\n <span>\n {tComponent(FrontendComponentType.GUIDANCE_ONBOARDING_VIEW, 'stepOf', {\n current: currentStepIndex + 1,\n total: totalSteps,\n })}\n </span>\n <span className=\"text-xs\">\n {completedCount}/{totalSteps}\n </span>\n </div>\n\n {/* Progress bar track */}\n <div\n className=\"w-full h-1 bg-muted rounded-sm overflow-hidden\"\n role=\"progressbar\"\n aria-valuenow={currentStepIndex + 1}\n aria-valuemin={1}\n aria-valuemax={totalSteps}\n >\n <div\n className=\"h-full bg-primary rounded-sm motion-safe:transition-[width] motion-safe:duration-[var(--motion-duration-normal)] motion-safe:ease-out\"\n style={{ width: `${totalSteps > 0 ? ((currentStepIndex + 1) / totalSteps) * 100 : 0}%` }}\n />\n </div>\n </div>\n )}\n\n {/* Current element renderer */}\n {Renderer && (\n <Renderer\n element={currentElement}\n flowRef={flowRef}\n state={elementState}\n onComplete={handleComplete}\n onDismiss={handleDismiss}\n onAction={handleAction}\n t={scopedT}\n />\n )}\n\n {/* Navigation controls */}\n {totalSteps > 1 && (\n <div className=\"flex justify-between items-center pt-item\">\n {/* Left: Back */}\n <div>\n {currentStepIndex > 0 && (\n // V-5: candidate for Button/IconButton migration — see audit doc\n // (raw <button> reimplements OUTLINE/GHOST recipe with non-ladder text-[0.8125rem])\n <button\n type=\"button\"\n onClick={handleBack}\n className=\"px-card py-item text-[0.8125rem] font-medium text-muted-foreground bg-transparent border border-border rounded-md cursor-pointer motion-safe:transition-colors hover:bg-muted focus-ring-offset pointer-coarse:min-h-11\"\n >\n {tComponent(FrontendComponentType.GUIDANCE_ONBOARDING_VIEW, 'back')}\n </button>\n )}\n </div>\n\n {/* Right: Skip / Next / Complete */}\n <div className=\"flex gap-item items-center\">\n {mergedOptions.allowSkip && (\n // V-5: candidate for Button/IconButton migration — see audit doc\n // (raw <button> reimplements GHOST recipe with non-ladder text-[0.8125rem])\n <button\n type=\"button\"\n onClick={handleSkip}\n /*\n * Quiet, but not below the contrast floor: at `text-muted-foreground/70` this\n * composited to #7d899b on the light theme's #f8fafc — 3.38:1 where 4.5:1 is\n * required (axe, live stack, 2026-09-09, #533). The full token is still visibly\n * secondary to the primary action beside it.\n */\n className=\"px-card-sm py-item text-[0.8125rem] font-medium text-muted-foreground bg-transparent border-none cursor-pointer motion-safe:transition-colors hover:text-muted-foreground focus-ring-offset pointer-coarse:min-h-11\"\n >\n {tComponent(FrontendComponentType.GUIDANCE_ONBOARDING_VIEW, 'skip')}\n </button>\n )}\n\n {/* V-5: candidate for Button/IconButton migration — see audit doc */}\n {/* (raw <button> reimplements PRIMARY recipe with non-ladder text-[0.8125rem]) */}\n <button\n type=\"button\"\n onClick={handleNext}\n className=\"px-card py-item text-[0.8125rem] font-medium text-primary-foreground bg-primary border-none rounded-md cursor-pointer motion-safe:transition-colors hover:bg-primary/90 focus-ring-offset pointer-coarse:min-h-11\"\n >\n {currentStepIndex === totalSteps - 1\n ? tComponent(FrontendComponentType.GUIDANCE_ONBOARDING_VIEW, 'complete')\n : tComponent(FrontendComponentType.GUIDANCE_ONBOARDING_VIEW, 'next')}\n </button>\n </div>\n </div>\n )}\n\n {/* Single-step footer fallback: some renderers do not expose their own completion action. */}\n {totalSteps === 1 && (\n <div className=\"flex justify-end gap-item items-center\">\n {mergedOptions.allowDismiss && (\n // V-5: candidate for Button/IconButton migration — see audit doc\n // (raw <button> reimplements GHOST recipe with non-ladder text-[0.8125rem])\n <button\n type=\"button\"\n onClick={() => handleDismiss(currentElement.ref)}\n className=\"px-card-sm py-item text-[0.8125rem] font-medium text-muted-foreground bg-transparent border-none cursor-pointer motion-safe:transition-colors hover:text-muted-foreground focus-ring-offset pointer-coarse:min-h-11\"\n >\n {tComponent(FrontendComponentType.GUIDANCE_ONBOARDING_VIEW, 'dismiss')}\n </button>\n )}\n\n {/* V-5: candidate for Button/IconButton migration — see audit doc */}\n {/* (raw <button> reimplements PRIMARY recipe with non-ladder text-[0.8125rem]) */}\n <button\n type=\"button\"\n onClick={handleNext}\n className=\"px-card py-item text-[0.8125rem] font-medium text-primary-foreground bg-primary border-none rounded-md cursor-pointer motion-safe:transition-colors hover:bg-primary/90 focus-ring-offset pointer-coarse:min-h-11\"\n >\n {tComponent(FrontendComponentType.GUIDANCE_ONBOARDING_VIEW, 'complete')}\n </button>\n </div>\n )}\n </div>\n );\n};\n"]}
|
|
@@ -10,6 +10,22 @@ export declare const DEFAULT_VALIDATION_MODE = ValidationMode.ON_BLUR;
|
|
|
10
10
|
* State enum for inline field editing.
|
|
11
11
|
* Represents the different states a field can be in during inline editing.
|
|
12
12
|
*/
|
|
13
|
+
/**
|
|
14
|
+
* Which of the two automated-layout generators a diagnostic is reporting for.
|
|
15
|
+
*
|
|
16
|
+
* A named source rather than a `'form' | 'display'` literal union, so the distinction has one
|
|
17
|
+
* runtime home and each member can say what it means. Deliberately NOT reusing
|
|
18
|
+
* `GroupedSectionHostKind` (which adds `COMPOSITE` and answers "what hosts this section") or
|
|
19
|
+
* `MutationSourceType` (which answers "what initiated this mutation"): all three happen to spell
|
|
20
|
+
* two members the same way, and merging vocabularies because their wire values overlap is what the
|
|
21
|
+
* framework's own semantic rule forbids.
|
|
22
|
+
*/
|
|
23
|
+
export declare enum AutomatedLayoutTemplateKind {
|
|
24
|
+
/** The editable template — fields become form controls. */
|
|
25
|
+
FORM = "form",
|
|
26
|
+
/** The read template — fields become display chrome. */
|
|
27
|
+
DISPLAY = "display"
|
|
28
|
+
}
|
|
13
29
|
export declare enum InlineEditState {
|
|
14
30
|
/** Displaying value, not in edit mode */
|
|
15
31
|
DISPLAY = "display",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"automated-layout.frontend.schemas.d.ts","sourceRoot":"","sources":["../../../../src/core/automated-layout/automated-layout.frontend.schemas.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,EACf,MAAM,0BAA0B,CAAC;AAElC,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAE9D,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAO7B;;;GAGG;AACH,eAAO,MAAM,uBAAuB,yBAAyB,CAAC;AAM9D;;;GAGG;AACH,oBAAY,eAAe;IACzB,yCAAyC;IACzC,OAAO,YAAY;IACnB,gDAAgD;IAChD,OAAO,YAAY;IACnB,mCAAmC;IACnC,MAAM,WAAW;IACjB,+EAA+E;IAC/E,KAAK,UAAU;IACf,iCAAiC;IACjC,KAAK,UAAU;CAChB;AAMD;;;;;;;GAOG;AACH,MAAM,MAAM,iBAAiB,GACzB,qBAAqB,CAAC,MAAM,GAC5B,qBAAqB,CAAC,MAAM,GAC5B,qBAAqB,CAAC,IAAI,GAC1B,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC;AAMlB;;;;;;;GAOG;AACH,MAAM,WAAW,2BAA2B;IAC1C,yEAAyE;IACzE,kBAAkB,EAAE,MAAM,CAAC;IAC3B,4EAA4E;IAC5E,0CAA0C,CAAC,EAAE,MAAM,EAAE,CAAC;IACtD,mDAAmD;IACnD,gBAAgB,CAAC,EAAE,KAAK,CAAC;QACvB,+CAA+C;QAC/C,uBAAuB,EAAE,MAAM,CAAC;QAChC,2CAA2C;QAC3C,MAAM,EAAE,CAAC,CAAC,UAAU,CAAC;QACrB,8DAA8D;QAC9D,2BAA2B,CAAC,EAAE,2BAA2B,CAAC;KAC3D,CAAC,CAAC;CACJ"}
|
|
1
|
+
{"version":3,"file":"automated-layout.frontend.schemas.d.ts","sourceRoot":"","sources":["../../../../src/core/automated-layout/automated-layout.frontend.schemas.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,EACf,MAAM,0BAA0B,CAAC;AAElC,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAE9D,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAO7B;;;GAGG;AACH,eAAO,MAAM,uBAAuB,yBAAyB,CAAC;AAM9D;;;GAGG;AACH;;;;;;;;;GASG;AACH,oBAAY,2BAA2B;IACrC,2DAA2D;IAC3D,IAAI,SAAS;IACb,wDAAwD;IACxD,OAAO,YAAY;CACpB;AAED,oBAAY,eAAe;IACzB,yCAAyC;IACzC,OAAO,YAAY;IACnB,gDAAgD;IAChD,OAAO,YAAY;IACnB,mCAAmC;IACnC,MAAM,WAAW;IACjB,+EAA+E;IAC/E,KAAK,UAAU;IACf,iCAAiC;IACjC,KAAK,UAAU;CAChB;AAMD;;;;;;;GAOG;AACH,MAAM,MAAM,iBAAiB,GACzB,qBAAqB,CAAC,MAAM,GAC5B,qBAAqB,CAAC,MAAM,GAC5B,qBAAqB,CAAC,IAAI,GAC1B,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC;AAMlB;;;;;;;GAOG;AACH,MAAM,WAAW,2BAA2B;IAC1C,yEAAyE;IACzE,kBAAkB,EAAE,MAAM,CAAC;IAC3B,4EAA4E;IAC5E,0CAA0C,CAAC,EAAE,MAAM,EAAE,CAAC;IACtD,mDAAmD;IACnD,gBAAgB,CAAC,EAAE,KAAK,CAAC;QACvB,+CAA+C;QAC/C,uBAAuB,EAAE,MAAM,CAAC;QAChC,2CAA2C;QAC3C,MAAM,EAAE,CAAC,CAAC,UAAU,CAAC;QACrB,8DAA8D;QAC9D,2BAA2B,CAAC,EAAE,2BAA2B,CAAC;KAC3D,CAAC,CAAC;CACJ"}
|
|
@@ -14,6 +14,23 @@ export const DEFAULT_VALIDATION_MODE = ValidationMode.ON_BLUR;
|
|
|
14
14
|
* State enum for inline field editing.
|
|
15
15
|
* Represents the different states a field can be in during inline editing.
|
|
16
16
|
*/
|
|
17
|
+
/**
|
|
18
|
+
* Which of the two automated-layout generators a diagnostic is reporting for.
|
|
19
|
+
*
|
|
20
|
+
* A named source rather than a `'form' | 'display'` literal union, so the distinction has one
|
|
21
|
+
* runtime home and each member can say what it means. Deliberately NOT reusing
|
|
22
|
+
* `GroupedSectionHostKind` (which adds `COMPOSITE` and answers "what hosts this section") or
|
|
23
|
+
* `MutationSourceType` (which answers "what initiated this mutation"): all three happen to spell
|
|
24
|
+
* two members the same way, and merging vocabularies because their wire values overlap is what the
|
|
25
|
+
* framework's own semantic rule forbids.
|
|
26
|
+
*/
|
|
27
|
+
export var AutomatedLayoutTemplateKind;
|
|
28
|
+
(function (AutomatedLayoutTemplateKind) {
|
|
29
|
+
/** The editable template — fields become form controls. */
|
|
30
|
+
AutomatedLayoutTemplateKind["FORM"] = "form";
|
|
31
|
+
/** The read template — fields become display chrome. */
|
|
32
|
+
AutomatedLayoutTemplateKind["DISPLAY"] = "display";
|
|
33
|
+
})(AutomatedLayoutTemplateKind || (AutomatedLayoutTemplateKind = {}));
|
|
17
34
|
export var InlineEditState;
|
|
18
35
|
(function (InlineEditState) {
|
|
19
36
|
/** Displaying value, not in edit mode */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"automated-layout.frontend.schemas.js","sourceRoot":"","sources":["../../../../src/core/automated-layout/automated-layout.frontend.schemas.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,GACf,MAAM,0BAA0B,CAAC;AAOlC,gFAAgF;AAChF,uBAAuB;AACvB,gFAAgF;AAEhF;;;GAGG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG,cAAc,CAAC,OAAO,CAAC;AAE9D,gFAAgF;AAChF,oBAAoB;AACpB,gFAAgF;AAEhF;;;GAGG;AACH,MAAM,CAAN,IAAY,eAWX;AAXD,WAAY,eAAe;IACzB,yCAAyC;IACzC,sCAAmB,CAAA;IACnB,gDAAgD;IAChD,sCAAmB,CAAA;IACnB,mCAAmC;IACnC,oCAAiB,CAAA;IACjB,+EAA+E;IAC/E,kCAAe,CAAA;IACf,iCAAiC;IACjC,kCAAe,CAAA;AACjB,CAAC,EAXW,eAAe,KAAf,eAAe,QAW1B","sourcesContent":["import {\n ValidationMode,\n} from '@wildo-ai/zod-decorators';\n\nimport { CoreResourceOperation } from '@wildo-ai/saas-models';\n\nimport type { z } from 'zod';\n\n\n// =============================================================================\n// VALIDATION CONSTANTS\n// =============================================================================\n\n/**\n * Default validation mode for all forms.\n * Centralized constant for consistent default behavior.\n */\nexport const DEFAULT_VALIDATION_MODE = ValidationMode.ON_BLUR;\n\n// =============================================================================\n// INLINE EDIT STATE\n// =============================================================================\n\n/**\n * State enum for inline field editing.\n * Represents the different states a field can be in during inline editing.\n */\nexport enum InlineEditState {\n /** Displaying value, not in edit mode */\n DISPLAY = 'display',\n /** In edit mode, user is modifying the value */\n EDITING = 'editing',\n /** Saving changes to the server */\n SAVING = 'saving',\n /** Save completed successfully (brief feedback before returning to DISPLAY) */\n SAVED = 'saved',\n /** Save failed, showing error */\n ERROR = 'error',\n}\n\n// =============================================================================\n// FORM OPERATION TYPE\n// =============================================================================\n\n/**\n * Operation type for controlling field visibility based on operation context.\n * Uses CoreResourceOperation enum values for type safety.\n * Used with excludeFromCreate, excludeFromUpdate, and isHidden(operations) decorators.\n * \n * Branded with `& {}` to allow custom string values through type assertion\n * without collapsing the entire union to `string` (which kills autocomplete).\n */\nexport type FormOperationType = \n | CoreResourceOperation.CREATE \n | CoreResourceOperation.UPDATE \n | CoreResourceOperation.READ\n | (string & {});\n\n// =============================================================================\n// INHERITANCE SCHEMA DEFINITION\n// =============================================================================\n\n/**\n * Inheritance schema definition for discriminated unions.\n * Used to track which fields belong to which variants for conditional visibility.\n * \n * This is a simplified, non-generic version of ResourceConfiguration_InheritanceSchemaDefinition\n * from @wildo-ai/saas-models, optimized for frontend use. It is structurally compatible\n * with the backend type but avoids complex generics that aren't needed for UI rendering.\n */\nexport interface InheritanceSchemaDefinition {\n /** Field name used for discrimination (e.g., 'type', 'recurringType') */\n discriminatorField: string;\n /** Discriminator values that use base schema only (no variant extension) */\n withoutInheritanceDiscriminatorFieldValues?: string[];\n /** Variant schemas for each discriminator value */\n inheritedSchemas?: Array<{\n /** The discriminator value for this variant */\n discriminatorFieldValue: string;\n /** The extended schema for this variant */\n schema: z.ZodTypeAny;\n /** Nested inheritance for multi-level discriminated unions */\n inheritenceSchemaDefinition?: InheritanceSchemaDefinition;\n }>;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"automated-layout.frontend.schemas.js","sourceRoot":"","sources":["../../../../src/core/automated-layout/automated-layout.frontend.schemas.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,GACf,MAAM,0BAA0B,CAAC;AAOlC,gFAAgF;AAChF,uBAAuB;AACvB,gFAAgF;AAEhF;;;GAGG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG,cAAc,CAAC,OAAO,CAAC;AAE9D,gFAAgF;AAChF,oBAAoB;AACpB,gFAAgF;AAEhF;;;GAGG;AACH;;;;;;;;;GASG;AACH,MAAM,CAAN,IAAY,2BAKX;AALD,WAAY,2BAA2B;IACrC,2DAA2D;IAC3D,4CAAa,CAAA;IACb,wDAAwD;IACxD,kDAAmB,CAAA;AACrB,CAAC,EALW,2BAA2B,KAA3B,2BAA2B,QAKtC;AAED,MAAM,CAAN,IAAY,eAWX;AAXD,WAAY,eAAe;IACzB,yCAAyC;IACzC,sCAAmB,CAAA;IACnB,gDAAgD;IAChD,sCAAmB,CAAA;IACnB,mCAAmC;IACnC,oCAAiB,CAAA;IACjB,+EAA+E;IAC/E,kCAAe,CAAA;IACf,iCAAiC;IACjC,kCAAe,CAAA;AACjB,CAAC,EAXW,eAAe,KAAf,eAAe,QAW1B","sourcesContent":["import {\n ValidationMode,\n} from '@wildo-ai/zod-decorators';\n\nimport { CoreResourceOperation } from '@wildo-ai/saas-models';\n\nimport type { z } from 'zod';\n\n\n// =============================================================================\n// VALIDATION CONSTANTS\n// =============================================================================\n\n/**\n * Default validation mode for all forms.\n * Centralized constant for consistent default behavior.\n */\nexport const DEFAULT_VALIDATION_MODE = ValidationMode.ON_BLUR;\n\n// =============================================================================\n// INLINE EDIT STATE\n// =============================================================================\n\n/**\n * State enum for inline field editing.\n * Represents the different states a field can be in during inline editing.\n */\n/**\n * Which of the two automated-layout generators a diagnostic is reporting for.\n *\n * A named source rather than a `'form' | 'display'` literal union, so the distinction has one\n * runtime home and each member can say what it means. Deliberately NOT reusing\n * `GroupedSectionHostKind` (which adds `COMPOSITE` and answers \"what hosts this section\") or\n * `MutationSourceType` (which answers \"what initiated this mutation\"): all three happen to spell\n * two members the same way, and merging vocabularies because their wire values overlap is what the\n * framework's own semantic rule forbids.\n */\nexport enum AutomatedLayoutTemplateKind {\n /** The editable template — fields become form controls. */\n FORM = 'form',\n /** The read template — fields become display chrome. */\n DISPLAY = 'display',\n}\n\nexport enum InlineEditState {\n /** Displaying value, not in edit mode */\n DISPLAY = 'display',\n /** In edit mode, user is modifying the value */\n EDITING = 'editing',\n /** Saving changes to the server */\n SAVING = 'saving',\n /** Save completed successfully (brief feedback before returning to DISPLAY) */\n SAVED = 'saved',\n /** Save failed, showing error */\n ERROR = 'error',\n}\n\n// =============================================================================\n// FORM OPERATION TYPE\n// =============================================================================\n\n/**\n * Operation type for controlling field visibility based on operation context.\n * Uses CoreResourceOperation enum values for type safety.\n * Used with excludeFromCreate, excludeFromUpdate, and isHidden(operations) decorators.\n * \n * Branded with `& {}` to allow custom string values through type assertion\n * without collapsing the entire union to `string` (which kills autocomplete).\n */\nexport type FormOperationType = \n | CoreResourceOperation.CREATE \n | CoreResourceOperation.UPDATE \n | CoreResourceOperation.READ\n | (string & {});\n\n// =============================================================================\n// INHERITANCE SCHEMA DEFINITION\n// =============================================================================\n\n/**\n * Inheritance schema definition for discriminated unions.\n * Used to track which fields belong to which variants for conditional visibility.\n * \n * This is a simplified, non-generic version of ResourceConfiguration_InheritanceSchemaDefinition\n * from @wildo-ai/saas-models, optimized for frontend use. It is structurally compatible\n * with the backend type but avoids complex generics that aren't needed for UI rendering.\n */\nexport interface InheritanceSchemaDefinition {\n /** Field name used for discrimination (e.g., 'type', 'recurringType') */\n discriminatorField: string;\n /** Discriminator values that use base schema only (no variant extension) */\n withoutInheritanceDiscriminatorFieldValues?: string[];\n /** Variant schemas for each discriminator value */\n inheritedSchemas?: Array<{\n /** The discriminator value for this variant */\n discriminatorFieldValue: string;\n /** The extended schema for this variant */\n schema: z.ZodTypeAny;\n /** Nested inheritance for multi-level discriminated unions */\n inheritenceSchemaDefinition?: InheritanceSchemaDefinition;\n }>;\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"default-layout-generator.frontend.utils.d.ts","sourceRoot":"","sources":["../../../../src/core/automated-layout/default-layout-generator.frontend.utils.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,cAAc,EAAqB,MAAM,0BAA0B,CAAC;AAClF,OAAO,EACL,eAAe,EAahB,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"default-layout-generator.frontend.utils.d.ts","sourceRoot":"","sources":["../../../../src/core/automated-layout/default-layout-generator.frontend.utils.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,cAAc,EAAqB,MAAM,0BAA0B,CAAC;AAClF,OAAO,EACL,eAAe,EAahB,MAAM,0BAA0B,CAAC;AAGlC,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,qCAAqC,CAAC;AAavF;;;;GAIG;AACH,MAAM,MAAM,mBAAmB,GAAG,CAAC,SAAS,EAAE,MAAM,KAAK,MAAM,CAAC;AAMhE;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC9B,kDAAkD;IAClD,IAAI,EAAE,MAAM,CAAC;IACb,oCAAoC;IACpC,MAAM,EAAE,CAAC,CAAC,UAAU,CAAC;IACrB,iEAAiE;IACjE,UAAU,EAAE,eAAe,CAAC;IAC5B,4EAA4E;IAC5E,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,gDAAgD;IAChD,mBAAmB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC/B,sEAAsE;IACtE,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;AAsBD;;;;;;;;GAQG;AACH,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,CAAC,CAAC,UAAU,EACpB,kBAAkB,CAAC,EAAE,MAAM,GAC1B,eAAe,EAAE,CAgBnB;AAoOD;;;;;;;GAOG;AACH,MAAM,WAAW,4BAA4B;IAC3C,qFAAqF;IACrF,iBAAiB,CAAC,EAAE,2BAA2B,CAAC;IAChD,8EAA8E;IAC9E,YAAY,CAAC,EAAE,mBAAmB,CAAC;IACnC;;;;;OAKG;IACH,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B;;;;OAIG;IACH,mBAAmB,CAAC,EAAE,OAAO,CAAC;CAC/B;AAOD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoDG;AACH,wBAAgB,2BAA2B,CACzC,MAAM,EAAE,CAAC,CAAC,UAAU,EACpB,OAAO,CAAC,EAAE,4BAA4B,GACrC,KAAK,CAAC,EAAE,CA4DV;AAyQD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,8BAA8B,CAC5C,MAAM,EAAE,CAAC,CAAC,UAAU,GACnB,KAAK,CAAC,EAAE,CAyBV;AA2CD;;;;;;;;;;;;GAYG;AACH,wBAAgB,8BAA8B,CAC5C,MAAM,EAAE,CAAC,CAAC,UAAU,GACnB,KAAK,CAAC,EAAE,CA6CV"}
|
|
@@ -3,6 +3,7 @@ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-run
|
|
|
3
3
|
import React from 'react';
|
|
4
4
|
import { FieldSchemaType, getSchemaType, getObjectShape, getObjectKeys, getZodObjectShape, getZodDefArrayProperty, getZodDefStringProperty, isDiscriminatedUnion, unwrapSchema, isVirtualField, isBackendOnlyField, isSummaryField, getShowWhenParams, } from '@wildo-ai/zod-decorators';
|
|
5
5
|
import { AutomatedLayoutFrontendUtils } from './automated-layout.frontend.utils.js';
|
|
6
|
+
import { AutomatedLayoutTemplateKind } from './automated-layout.frontend.schemas.js';
|
|
6
7
|
import { FormLayout } from '../../components/resources/skeleton/FormLayout.js';
|
|
7
8
|
import { DisplayLayout } from '../../components/resources/skeleton/DisplayLayout.js';
|
|
8
9
|
import { SummaryLayout, SummaryTitlePlacement } from '../../components/resources/skeleton/SummaryLayout.js';
|
|
@@ -297,7 +298,7 @@ function reportUnrenderableNestedObjectFields(fields, templateKind, parentPathPr
|
|
|
297
298
|
export function generateDefaultFormTemplate(schema, options) {
|
|
298
299
|
const inheritanceConfig = options?.inheritanceConfig;
|
|
299
300
|
const fields = extractSchemaFieldList(schema, inheritanceConfig?.discriminatorField);
|
|
300
|
-
reportUnrenderableNestedObjectFields(fields,
|
|
301
|
+
reportUnrenderableNestedObjectFields(fields, AutomatedLayoutTemplateKind.FORM);
|
|
301
302
|
const showSubmit = options?.includeSubmitButton !== false;
|
|
302
303
|
const showErrorSummary = options?.includeErrorSummary !== false;
|
|
303
304
|
if (fields.length === 0) {
|
|
@@ -506,7 +507,7 @@ export function generateDefaultDisplayTemplate(schema) {
|
|
|
506
507
|
// Same nested-union limitation as the form generator, reported at the same
|
|
507
508
|
// moment — the display side falls back to a `<DisplayField>` that resolves no
|
|
508
509
|
// child shape and renders nothing, so the silence is identical.
|
|
509
|
-
reportUnrenderableNestedObjectFields(fields,
|
|
510
|
+
reportUnrenderableNestedObjectFields(fields, AutomatedLayoutTemplateKind.DISPLAY);
|
|
510
511
|
if (fields.length === 0) {
|
|
511
512
|
const EmptyDisplayTemplate = () => _jsx(DisplayLayout, {});
|
|
512
513
|
return EmptyDisplayTemplate;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"default-layout-generator.frontend.utils.js","sourceRoot":"","sources":["../../../../src/core/automated-layout/default-layout-generator.frontend.utils.tsx"],"names":[],"mappings":"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","sourcesContent":["'use client';\n\nimport React from 'react';\nimport type { ReactNode } from 'react';\nimport { z } from 'zod';\nimport type { ShowWhenParams, ShowWhenCondition } from '@wildo-ai/zod-decorators';\nimport {\n FieldSchemaType,\n getSchemaType,\n getObjectShape,\n getObjectKeys,\n getZodObjectShape,\n getZodDefArrayProperty,\n getZodDefStringProperty,\n isDiscriminatedUnion,\n unwrapSchema,\n isVirtualField,\n isBackendOnlyField,\n isSummaryField,\n getShowWhenParams,\n} from '@wildo-ai/zod-decorators';\nimport { AutomatedLayoutFrontendUtils } from './automated-layout.frontend.utils';\nimport type { InheritanceSchemaDefinition } from './automated-layout.frontend.schemas';\nimport { FormLayout } from '~wildo-frontend-lib/components/resources/skeleton/FormLayout';\nimport { DisplayLayout } from '~wildo-frontend-lib/components/resources/skeleton/DisplayLayout';\nimport { SummaryLayout, SummaryTitlePlacement } from '~wildo-frontend-lib/components/resources/skeleton/SummaryLayout';\nimport { FormErrorSummarySlot } from '~wildo-frontend-lib/components/resources/skeleton/FormErrorSummarySlot';\nimport { SubmitButton } from '~wildo-frontend-lib/components/resources/skeleton/SubmitButton';\nimport { ObjectScope } from '~wildo-frontend-lib/components/resources/skeleton/ObjectScope';\nimport { DiscriminatorSwitch } from '~wildo-frontend-lib/components/resources/skeleton/DiscriminatorSwitch';\nimport { FormField } from '~wildo-frontend-lib/components/form/automated/FormField';\nimport { useOptionalFormTemplateContext } from '~wildo-frontend-lib/components/form/automated/FormTemplateContext';\nimport { DisplayField } from '~wildo-frontend-lib/components/data-display/DisplayField';\nimport { useWatch } from 'react-hook-form';\n\n/**\n * Label resolver function signature for layout template generators.\n * Receives a field name (potentially dotted path) and returns a human-readable label.\n * Consumers (AutomatedForm, AutomaticDisplayer) pass their i18n-aware resolver here.\n */\nexport type LayoutLabelResolver = (fieldName: string) => string;\n\n// =============================================================================\n// SCHEMA FIELD LIST — THIN EXTRACTION UTILITY\n// =============================================================================\n\n/**\n * Lightweight field descriptor produced by `extractSchemaFieldList()`.\n * Contains only what the template generator needs — no grid/row/layout calculations.\n */\nexport interface SchemaFieldInfo {\n /** Field key (top-level name, not dotted path) */\n name: string;\n /** The Zod schema for this field */\n schema: z.ZodTypeAny;\n /** Resolved schema type (STRING, NUMBER, OBJECT, ARRAY, etc.) */\n schemaType: FieldSchemaType;\n /** showWhen conditional visibility params (from `.showWhen()` decorator) */\n showWhenParams?: ShowWhenParams;\n /** Fields that showWhen depends on (deduped) */\n showWhenWatchFields?: string[];\n /** Whether this field is a discriminator for a discriminated union */\n isDiscriminator?: boolean;\n}\n\nfunction createSchemaFieldInfo(\n name: string,\n schema: z.ZodTypeAny,\n discriminatorField?: string,\n): SchemaFieldInfo {\n const schemaType = getSchemaType(schema);\n const showWhenParams = getShowWhenParams(schema);\n\n return {\n name,\n schema,\n schemaType,\n showWhenParams,\n showWhenWatchFields: showWhenParams\n ? dedupeShowWhenWatchFields(showWhenParams)\n : undefined,\n isDiscriminator: discriminatorField === name,\n };\n}\n\n/**\n * Extracts a flat list of renderable root fields from an object-like schema.\n *\n * Produces the field metadata the template generator needs.\n * No grid math, no row calculations, no section/wizard grouping.\n *\n * Excludes: virtual fields, backend-only fields.\n * Does NOT exclude operation-specific fields — those are handled at render time.\n */\nexport function extractSchemaFieldList(\n schema: z.ZodTypeAny,\n discriminatorField?: string,\n): SchemaFieldInfo[] {\n const shape = AutomatedLayoutFrontendUtils.getObjectLikeFieldShape(schema, { commonOnly: true });\n const keys = shape ? Object.keys(shape) : [];\n\n if (!shape || keys.length === 0) return [];\n\n const fields: SchemaFieldInfo[] = [];\n\n for (const key of keys) {\n const fieldSchema = shape[key];\n if (isVirtualField(fieldSchema) || isBackendOnlyField(fieldSchema)) continue;\n\n fields.push(createSchemaFieldInfo(key, fieldSchema, discriminatorField));\n }\n\n return fields;\n}\n\n/**\n * The ONE reader every nested traversal in this file goes through, and the place\n * the surprising part of `getZodObjectShape` is written down once instead of\n * being rediscovered at three call sites.\n *\n * `getZodObjectShape()` returns `{}` — an EMPTY OBJECT, not `null` — for anything\n * that is not a BARE `ZodObject`, and that includes every ordinary authoring\n * wrapper. Measured 2026-09-08 against zod 4.3.6:\n *\n * | authored field | `getZodObjectShape` | `getObjectShape` |\n * |-------------------------------------|---------------------|------------------|\n * | `z.object({ a, b })` | `['a','b']` | `['a','b']` |\n * | `z.object({ a, b }).optional()` | **`[]`** | `['a','b']` |\n * | `z.object({ a, b }).nullable()` | **`[]`** | `['a','b']` |\n * | `z.object({ a, b }).default({...})` | **`[]`** | `['a','b']` |\n * | `z.discriminatedUnion('t', [...])` | **`[]`** | `null` |\n *\n * Because `{}` is TRUTHY, an `if (!shape)` guard never fires; the traversal falls\n * out through its \"no renderable keys\" branch instead and emits ONE\n * `<FormField name={objectField} />` for the whole subtree.\n *\n * **That fallthrough is deliberate for the wrapper rows, and this comment exists\n * so it is not \"fixed\" a second time.** Swapping in `getObjectShape` here makes\n * the generator descend into a `.optional()` nested object and emit its declared\n * `<ObjectScope>` + per-child `<FormField>` structure — which was tried, measured,\n * and reverted, because it is a CHANGE with no defect behind it:\n *\n * - the single `<FormField>` is not a dead end. Its OBJECT branch mounts\n * `FormFieldComposite`, which reads the shape with `getObjectShape` (it\n * unwraps), renders every child as a real `FormField` under an absolute\n * dotted name, and gives the object a titled `ContentSection`. Measured with\n * that section available: an `.optional()` nested object rendered BOTH\n * children, and a `showWhen` on a child hid initially and appeared live on\n * the sibling toggle — i.e. nothing is dropped;\n * - descending would therefore only trade a titled section for a flat scope, on\n * every generated screen of every application whose schema has a wrapped\n * nested object. Wonder Todos' `todos.reminder` (`z.object({...}).optional()`)\n * deliberately renders through the composite in its authored layout, which is\n * what that trade would silently undo elsewhere.\n *\n * The union row is a different story and is NOT compensated — `getObjectShape`\n * returns `null` there too, so the composite renders nothing at all. That case is\n * handled before this reader is ever reached (see `renderObjectScope`).\n */\nfunction readNestedObjectShape(schema: z.ZodTypeAny): Record<string, z.ZodTypeAny> {\n return getZodObjectShape(schema);\n}\n\n/**\n * Builds the nested equivalent of the ROOT discriminated-union layout: a scope for\n * the union field, its discriminator, and a `<DiscriminatorSwitch>` carrying each\n * variant's own fields.\n *\n * This is the case the generator used to drop in silence. A field declared\n * `payload: z.discriminatedUnion('t', [...])` is `FieldSchemaType.OBJECT`, so it\n * took the object path, produced no readable shape, fell back to a single\n * `<FormField>` — and `FormFieldComposite` gets `null` from `getObjectShape` for a\n * union, so the authored field rendered NOTHING. Measured 2026-09-08: a two-variant\n * nested union contributed not one element to the generated form.\n *\n * Nothing new is invented here. `<DiscriminatorSwitch>` already resolves its\n * `field` through `useResolvedFieldName`, so placed inside `<ObjectScope name=\"payload\">`\n * it watches `payload.t` and its children resolve to `payload.xv` / `payload.yv`.\n * The root union path (`renderDiscriminatorAndVariants`) composes the same two\n * primitives; the only reason it could not serve here is that it is driven by the\n * caller-supplied `inheritanceConfig`, which describes the ROOT resource schema and\n * says nothing about an arbitrary nested field. The discriminator and the variant\n * literals are read from the schema instead, which is where they already are.\n *\n * Variant fields are filtered to those a variant OWNS: the fields shared by every\n * variant are rendered once, outside the switch, so switching the discriminator\n * does not remount them (and does not, via `shouldUnregister`, drop their values).\n *\n * Returns `null` when the schema is not a usable discriminated union, so callers\n * fall through to their existing behaviour rather than rendering half a union.\n */\nfunction renderNestedDiscriminatedUnion(field: SchemaFieldInfo): ReactNode | null {\n const unwrapped = unwrapSchema(field.schema);\n if (!isDiscriminatedUnion(unwrapped)) return null;\n\n const discriminator = getZodDefStringProperty(unwrapped, 'discriminator');\n const options = (getZodDefArrayProperty(unwrapped, 'options') ?? []) as z.ZodTypeAny[];\n if (!discriminator || options.length === 0) return null;\n\n // Fields every variant declares (the union's common base). Rendered once,\n // outside the switch — see the JSDoc above for why that matters beyond tidiness.\n const perVariantKeys = options.map(option => new Set(getObjectKeys(option)));\n const commonKeys = [...(perVariantKeys[0] ?? new Set<string>())]\n .filter(key => key !== discriminator && perVariantKeys.every(keys => keys.has(key)));\n\n const variants: Record<string, ReactNode> = {};\n\n for (const option of options) {\n const optionShape = getObjectShape(option);\n if (!optionShape) continue;\n\n /*\n * A variant's discriminator is a LITERAL (`z.literal('x')`), and Zod 4 stores a\n * literal's value in an ARRAY under `values` — the same shape\n * `resolveDiscriminatedUnionVariant` reads to match a variant to a value. Reading\n * it here is what keys the switch on the exact authored value rather than on the\n * variant's position in the options array.\n */\n const literalValues = getZodDefArrayProperty(optionShape[discriminator], 'values') ?? [];\n const variantValue = literalValues[0];\n if (variantValue === undefined || variantValue === null) continue;\n\n const variantOnlyKeys = Object.keys(optionShape).filter(key =>\n key !== discriminator\n && !commonKeys.includes(key)\n && !isVirtualField(optionShape[key])\n && !isBackendOnlyField(optionShape[key]),\n );\n if (variantOnlyKeys.length === 0) continue;\n\n variants[String(variantValue)] = (\n <>\n {variantOnlyKeys.map(key => <FormField key={key} name={key} />)}\n </>\n );\n }\n\n const commonShape = getObjectShape(options[0]);\n const renderableCommonKeys = commonShape\n ? commonKeys.filter(key => !isVirtualField(commonShape[key]) && !isBackendOnlyField(commonShape[key]))\n : [];\n\n return (\n <ObjectScope key={field.name} name={field.name}>\n <FormField name={discriminator} />\n {renderableCommonKeys.map(key => <FormField key={key} name={key} />)}\n {Object.keys(variants).length > 0 && (\n <DiscriminatorSwitch field={discriminator} variants={variants} />\n )}\n </ObjectScope>\n );\n}\n\nfunction dedupeShowWhenWatchFields(params: ShowWhenParams): string[] {\n const conditions: ShowWhenCondition[] = Array.isArray(params.conditions)\n ? params.conditions\n : [params.conditions];\n return [...new Set(conditions.map(c => c.field))];\n}\n\n/**\n * Reports a nested discriminated-union field that will render NOTHING, walking the\n * whole nested tree rather than only its top level.\n *\n * This is the residue of the drop `renderNestedDiscriminatedUnion` fixes. The FORM\n * generator now lays a nested union out, so it reports only a union it could not\n * build (no discriminator, or no options). The DISPLAY generator has no equivalent\n * branch, and the reason is structural rather than unfinished work:\n * `<DiscriminatorSwitch>` picks the live variant with `useWatch`, and a display\n * surface has no form to watch. Picking one there means reading the VALUE — which\n * `resolveDiscriminatedUnionVariant` will do, but the display generator is\n * schema-only at generation time and holds no value. Until that path exists the\n * field renders nothing, and an authored field that renders nothing must say so.\n *\n * Deliberately a development-only `console.warn` rather than a throw:\n *\n * - Throwing would turn a layout limitation into a broken screen, on the render\n * path of every resource that has no authored template.\n * - It fires at GENERATION time (once per `generateDefault*Template()` call, which\n * callers memoize per schema), not per render, so it cannot repeat on keystrokes.\n * - Measured 2026-09-08: neither dogfood application authors a nested\n * discriminated-union field anywhere, so this is silent on the installed base. It\n * reaches only the author who would otherwise be looking at a blank space\n * wondering which layer ate their field, and it names the remedy that works.\n */\nfunction reportUnrenderableNestedObjectFields(\n fields: SchemaFieldInfo[],\n templateKind: 'form' | 'display',\n parentPathPrefix: string = '',\n): void {\n if (process.env.NODE_ENV === 'production') return;\n\n for (const field of fields) {\n if (field.schemaType !== FieldSchemaType.OBJECT) continue;\n\n const fieldPath = parentPathPrefix ? `${parentPathPrefix}.${field.name}` : field.name;\n\n if (isDiscriminatedUnion(unwrapSchema(field.schema))) {\n // The FORM generator now lays a nested union out (`renderNestedDiscriminatedUnion`),\n // so it only reports one it could not build — a union with no discriminator or\n // no options. The DISPLAY generator has no equivalent, and the reason is not\n // laziness: `<DiscriminatorSwitch>` decides the live variant with `useWatch`,\n // and a display surface has no form to watch. Choosing the variant there means\n // reading the VALUE (`resolveDiscriminatedUnionVariant` takes one), which the\n // schema-only display generator does not have at generation time. Until that\n // path exists, the field renders nothing and must at least say so.\n if (templateKind === 'form' && renderNestedDiscriminatedUnion(field) !== null) continue;\n\n // eslint-disable-next-line no-console -- authoring-time diagnostic; see the JSDoc above for why this is a warn and not a throw\n console.warn(\n `[DefaultLayoutGenerator] Field \"${fieldPath}\" is a nested discriminated union, and the generated `\n + `default ${templateKind} template cannot lay it out, so \"${fieldPath}\" will render nothing. `\n + `Provide an explicit layout.${templateKind === 'form' ? 'edit' : 'display'} template for this resource.`,\n );\n continue;\n }\n\n // Descend, because the render walk descends: an unrenderable union sitting\n // three objects down is exactly as invisible as one at the root, and a reporter\n // that only looked at the top level would be the \"invariant applied at one of\n // its N sites\" defect this repository keeps paying for. `getObjectShape` is the\n // right reader HERE (unlike in the render path) precisely because this walk\n // renders nothing — it only needs to see every authored child.\n const innerShape = getObjectShape(field.schema);\n if (!innerShape) continue;\n\n reportUnrenderableNestedObjectFields(\n Object.entries(innerShape)\n .filter(([, childSchema]) => !isVirtualField(childSchema) && !isBackendOnlyField(childSchema))\n .map(([childName, childSchema]) => createSchemaFieldInfo(childName, childSchema)),\n templateKind,\n fieldPath,\n );\n }\n}\n\n\n// =============================================================================\n// FORM TEMPLATE GENERATION — OPTIONS\n// =============================================================================\n\n/**\n * Options for `generateDefaultFormTemplate()`.\n * All options are optional — omitting everything produces a flat field list.\n *\n * For resources that need sections, wizard steps, or custom layout,\n * provide an explicit `layout.edit` template in the resource config\n * instead of using the auto-generator.\n */\nexport interface FormTemplateGeneratorOptions {\n /** Inheritance config for discriminated unions. Produces `<DiscriminatorSwitch>`. */\n inheritanceConfig?: InheritanceSchemaDefinition;\n /** Label resolver (i18n-aware). Defaults to camelCase fallback formatting. */\n resolveLabel?: LayoutLabelResolver;\n /**\n * Whether to include `<SubmitButton />` in the generated template.\n * Set to `false` when the caller provides its own submit button externally\n * (e.g., ResourceAutomatedForm for operation-specific labels, draft mode).\n * @default true\n */\n includeSubmitButton?: boolean;\n /**\n * Whether to include `<FormErrorSummarySlot />` in the generated template.\n * Set to `false` when the caller handles error summary externally.\n * @default true\n */\n includeErrorSummary?: boolean;\n}\n\n\n// =============================================================================\n// FORM TEMPLATE GENERATION — MAIN\n// =============================================================================\n\n/**\n * Generates a flat default form layout template component from a Zod object schema.\n *\n * Returns a `React.FC` (not ReactNode) so that forms with `.showWhen()` decorators\n * can use `useWatch()` hooks for conditional rendering. The returned component is\n * stable across renders when memoized by the caller.\n *\n * Capabilities:\n * - **Flat list**: one `<FormField>` per key, wrapped in `<FormLayout>`\n * - **showWhen**: produces `useWatch()` + conditional rendering for fields with `.showWhen()` decorators,\n * including nested OBJECT scopes.\n * - **Discriminated unions**: produces `<DiscriminatorSwitch>` with variant field grouping\n * - **Nested objects**: produces `<ObjectScope>` + recursive `<FormField>` for OBJECT fields\n *\n * For resources that need sections, wizard steps, or custom layouts, provide an\n * explicit `layout.edit` template in the resource config.\n *\n * Limitation — ONE, and it is the only authored shape that renders nothing:\n * - **A nested field whose schema is a discriminated union** cannot be laid out.\n * The generator has no discriminator to switch on below the root, so the field\n * falls back to a single `<FormField>` and renders nothing. It is reported at\n * generation time in development (see {@link reportUnrenderableNestedObjectFields});\n * the remedy is an explicit `layout.edit` template.\n *\n * TWO LIMITATIONS PREVIOUSLY DOCUMENTED HERE WERE FALSE, and the correction is kept\n * because the stale text did measurable damage — it was read as a specification and\n * became a filed defect against behaviour that works (`generated-screens#8`).\n * Measured 2026-09-08 by rendering the generated template against the REAL\n * `FormField` (the pre-existing generator test mocks `FormField`, which is exactly\n * why neither claim was falsifiable there — see the pins in\n * `__tests__/default-layout-generator.frontend.utils.test.tsx`):\n *\n * - *\"Array-of-objects fields fall through to `<FormField>` (no `<ArrayField>`\n * generation)\"* — literally true and materially misleading. `<FormField>` is not\n * a fallback here, it is the DISPATCHER: its ARRAY branch mounts\n * `AutomatedArrayField`, a full array editor (add / remove / drag-reorder, CARD\n * or ROW per-item layouts, per-item sub-fields). The skeleton `<ArrayField>` +\n * `<ArrayItemTemplate>` pair is the HAND-AUTHORING shape for an explicit\n * template; not emitting it costs an authored field nothing.\n * - *\"showWhen on nested fields (inside OBJECT schemas) is not captured\"* — false.\n * `FormField` evaluates `showWhen` itself, deriving the sibling scope from its\n * RESOLVED name, so a condition on a field nested in an object resolves against\n * that object and reacts live. The generator's own watch collector descends too.\n * The two evaluations agree because both scope conditions to the parent path.\n *\n * The lesson, since prose in this file ships as the authoring contract: a claim\n * about behaviour that no test can falsify will be believed. Both of these were.\n *\n * @param schema - Root object-like schema for the resource. Plain object roots and\n * discriminated-union roots are both supported.\n * @param options - Generator options (inheritance, labels, submit/error controls)\n * @returns React.FC — a component function (memoize with useMemo/useRef for stable identity)\n */\nexport function generateDefaultFormTemplate(\n schema: z.ZodTypeAny,\n options?: FormTemplateGeneratorOptions,\n): React.FC {\n const inheritanceConfig = options?.inheritanceConfig;\n\n const fields = extractSchemaFieldList(schema, inheritanceConfig?.discriminatorField);\n reportUnrenderableNestedObjectFields(fields, 'form');\n const showSubmit = options?.includeSubmitButton !== false;\n const showErrorSummary = options?.includeErrorSummary !== false;\n\n if (fields.length === 0) {\n const EmptyTemplate: React.FC = () => <FormLayout autoInjectSubmitButton={showSubmit} />;\n EmptyTemplate.displayName = 'GeneratedFormTemplate(empty)';\n return EmptyTemplate;\n }\n\n const allShowWhenWatchFields = collectAllShowWhenWatchFields(fields);\n const hasShowWhen = allShowWhenWatchFields.length > 0;\n\n const baseFieldNames = new Set(fields.map(f => f.name));\n\n const GeneratedTemplate: React.FC = () => {\n const watchValues = useConditionalWatch(hasShowWhen, allShowWhenWatchFields);\n const formTemplateContext = useOptionalFormTemplateContext();\n const hiddenGeneratedFields = new Set(\n Object.keys(formTemplateContext?.contextFieldValues ?? {})\n );\n for (const hiddenFieldName of formTemplateContext?.hiddenFieldNames ?? []) {\n hiddenGeneratedFields.add(hiddenFieldName);\n }\n\n const renderField = (field: SchemaFieldInfo): ReactNode => {\n const hasGeneratedOverride = Boolean(formTemplateContext?.generatedFieldOverrides?.[field.name]);\n const element = hiddenGeneratedFields.has(field.name) && !hasGeneratedOverride\n ? null\n : renderFieldElement(\n field,\n inheritanceConfig,\n baseFieldNames,\n hiddenGeneratedFields,\n formTemplateContext?.generatedFieldOverrides,\n watchValues,\n allShowWhenWatchFields,\n );\n\n if (!field.showWhenParams || !watchValues) return element;\n\n const isVisible = evaluateShowWhenFromWatch(field.showWhenParams, watchValues, allShowWhenWatchFields);\n return isVisible ? element : null;\n };\n\n return (\n <FormLayout autoInjectSubmitButton={showSubmit}>\n {showErrorSummary && <FormErrorSummarySlot />}\n {fields.map(renderField)}\n {showSubmit && <SubmitButton />}\n </FormLayout>\n );\n };\n\n GeneratedTemplate.displayName = 'GeneratedFormTemplate';\n return GeneratedTemplate;\n}\n\n\n// =============================================================================\n// INTERNAL — CONDITIONAL WATCH HOOK\n// =============================================================================\n\n/**\n * Conditionally calls `useWatch` — only when there are showWhen fields to track.\n * React hooks must be called unconditionally, so we always call useWatch but with\n * an empty array when not needed (no-op).\n */\nfunction useConditionalWatch(hasShowWhen: boolean, watchFields: string[]): unknown[] | undefined {\n const values = useWatch({ name: hasShowWhen ? watchFields : [] });\n return hasShowWhen ? (Array.isArray(values) ? values : [values]) : undefined;\n}\n\n\n// =============================================================================\n// INTERNAL — FIELD RENDERING\n// =============================================================================\n\n/**\n * Renders a single field element, handling OBJECT nesting and discriminated unions.\n */\nfunction renderFieldElement(\n field: SchemaFieldInfo,\n inheritanceConfig: InheritanceSchemaDefinition | undefined,\n baseFieldNames?: Set<string>,\n hiddenContextFields?: Set<string>,\n generatedFieldOverrides?: Record<string, ReactNode>,\n watchValues?: unknown[],\n allShowWhenWatchFields?: string[],\n): ReactNode {\n if (generatedFieldOverrides?.[field.name]) {\n return <FormField key={field.name} name={field.name} />;\n }\n\n if (field.isDiscriminator && inheritanceConfig && baseFieldNames && hiddenContextFields) {\n return renderDiscriminatorAndVariants(\n field,\n inheritanceConfig,\n baseFieldNames,\n hiddenContextFields,\n generatedFieldOverrides,\n );\n }\n\n if (field.schemaType === FieldSchemaType.OBJECT) {\n return renderObjectScope(field, watchValues, allShowWhenWatchFields);\n }\n\n return (\n <FormField key={field.name} name={field.name} />\n );\n}\n\n/**\n * Renders a discriminator field + DiscriminatorSwitch for variant-specific fields.\n */\nfunction renderDiscriminatorAndVariants(\n discriminatorField: SchemaFieldInfo,\n config: InheritanceSchemaDefinition,\n baseFieldNames: Set<string>,\n hiddenContextFields: Set<string>,\n generatedFieldOverrides?: Record<string, ReactNode>,\n): ReactNode {\n const variants: Record<string, ReactNode> = {};\n\n if (config.inheritedSchemas) {\n for (const variant of config.inheritedSchemas) {\n const variantShape = getObjectShape(variant.schema);\n const variantKeys = getObjectKeys(variant.schema);\n\n if (variantShape && variantKeys.length > 0) {\n const variantOnlyKeys = variantKeys.filter(k =>\n !isVirtualField(variantShape[k]) &&\n !isBackendOnlyField(variantShape[k]) &&\n !baseFieldNames.has(k) &&\n (!hiddenContextFields.has(k) || Boolean(generatedFieldOverrides?.[k])),\n );\n\n if (variantOnlyKeys.length > 0) {\n variants[variant.discriminatorFieldValue] = (\n <>\n {variantOnlyKeys.map((key) => (\n <FormField key={key} name={key} />\n ))}\n </>\n );\n }\n }\n }\n }\n\n const hasVariants = Object.keys(variants).length > 0;\n\n return (\n <React.Fragment key={discriminatorField.name}>\n <FormField name={discriminatorField.name} />\n {hasVariants && (\n <DiscriminatorSwitch\n field={config.discriminatorField}\n variants={variants}\n />\n )}\n </React.Fragment>\n );\n}\n\n/**\n * Renders a nested OBJECT field using ObjectScope + recursive FormField elements.\n */\nfunction renderObjectScope(\n field: SchemaFieldInfo,\n watchValues?: unknown[],\n allShowWhenWatchFields?: string[],\n parentPathPrefix: string = '',\n): ReactNode {\n if (field.showWhenParams && watchValues && allShowWhenWatchFields) {\n const scopedShowWhenParams = scopeShowWhenParams(field.showWhenParams, parentPathPrefix);\n const isVisible = evaluateShowWhenFromWatch(scopedShowWhenParams, watchValues, allShowWhenWatchFields);\n if (!isVisible) {\n return null;\n }\n }\n\n // BEFORE the shape read, because a discriminated union answers that read with an\n // empty shape and would otherwise fall through to a `<FormField>` that renders\n // nothing at all. This is the generator's one genuine silent drop; see\n // `renderNestedDiscriminatedUnion`.\n const unionScope = renderNestedDiscriminatedUnion(field);\n if (unionScope) {\n return unionScope;\n }\n\n const innerShape = readNestedObjectShape(field.schema);\n\n const innerKeys = Object.keys(innerShape);\n const renderableKeys = innerKeys.filter(k => {\n const s = innerShape[k];\n return !isVirtualField(s) && !isBackendOnlyField(s);\n });\n\n // Empty for a WRAPPED object (`.optional()` / `.nullable()` / `.default()`) as\n // well as for a genuinely field-less one — `readNestedObjectShape` documents why\n // that conflation is left in place, and why the single `<FormField>` below is a\n // working renderer for it rather than a dead end.\n if (renderableKeys.length === 0) {\n return <FormField key={field.name} name={field.name} />;\n }\n\n const currentFieldPath = parentPathPrefix ? `${parentPathPrefix}.${field.name}` : field.name;\n\n return (\n <ObjectScope key={field.name} name={field.name}>\n {renderableKeys.map(key => {\n const childSchema = innerShape[key];\n const childType = getSchemaType(childSchema);\n\n if (childType === FieldSchemaType.OBJECT) {\n const nestedField = createSchemaFieldInfo(key, childSchema);\n return renderObjectScope(\n nestedField,\n watchValues,\n allShowWhenWatchFields,\n currentFieldPath,\n );\n }\n\n return <FormField key={key} name={key} />;\n })}\n </ObjectScope>\n );\n}\n\n\n// =============================================================================\n// INTERNAL — SHOW WHEN EVALUATION\n// =============================================================================\n\nfunction collectAllShowWhenWatchFields(fields: SchemaFieldInfo[]): string[] {\n const allFields = new Set<string>();\n for (const field of fields) {\n collectShowWhenWatchFieldsForField(field, allFields);\n }\n return [...allFields];\n}\n\nfunction collectShowWhenWatchFieldsForField(\n field: SchemaFieldInfo,\n collector: Set<string>,\n parentPathPrefix: string = '',\n): void {\n if (field.showWhenParams) {\n const scopedShowWhenParams = scopeShowWhenParams(field.showWhenParams, parentPathPrefix);\n for (const fieldName of dedupeShowWhenWatchFields(scopedShowWhenParams)) {\n collector.add(fieldName);\n }\n }\n\n if (field.schemaType !== FieldSchemaType.OBJECT) {\n return;\n }\n\n const innerShape = readNestedObjectShape(field.schema);\n\n const currentFieldPath = parentPathPrefix ? `${parentPathPrefix}.${field.name}` : field.name;\n for (const [childName, childSchema] of Object.entries(innerShape)) {\n if (isVirtualField(childSchema) || isBackendOnlyField(childSchema)) {\n continue;\n }\n\n collectShowWhenWatchFieldsForField(\n createSchemaFieldInfo(childName, childSchema as z.ZodTypeAny),\n collector,\n currentFieldPath,\n );\n }\n}\n\nfunction scopeShowWhenParams(\n params: ShowWhenParams,\n parentPathPrefix: string,\n): ShowWhenParams {\n if (!parentPathPrefix) {\n return params;\n }\n\n const conditions = Array.isArray(params.conditions)\n ? params.conditions\n : [params.conditions];\n\n return {\n ...params,\n conditions: conditions.map((condition) => ({\n ...condition,\n field: condition.field.includes('.') || condition.field.includes('[')\n ? condition.field\n : `${parentPathPrefix}.${condition.field}`,\n })),\n };\n}\n\n/**\n * Evaluates showWhen conditions using values from the useWatch array.\n * Maps field names to their positions in the watched fields array.\n */\nfunction evaluateShowWhenFromWatch(\n params: ShowWhenParams,\n watchValues: unknown[],\n allWatchFields: string[],\n): boolean {\n const formValues: Record<string, unknown> = {};\n for (let i = 0; i < allWatchFields.length; i++) {\n formValues[allWatchFields[i]] = watchValues[i];\n }\n return AutomatedLayoutFrontendUtils.evaluateShowWhen(params, formValues);\n}\n\n\n// =============================================================================\n// DISPLAY TEMPLATE GENERATION\n// =============================================================================\n\n/**\n * Generates a flat default display layout template (React.FC) from a Zod object schema.\n *\n * Schema-only: field values, labels, and descriptions are resolved from\n * DisplayTemplateContext at render time via name-only `<DisplayField name=\"x\" />`.\n *\n * Supports nested objects (`<ObjectScope>`) and per-field showWhen\n * (DD-10 — not evaluated at generator time).\n *\n * For resources that need sections or custom display layouts, provide an\n * explicit `layout.display` template in the resource config.\n *\n * @param schema - The root Zod object schema for the resource\n * @returns React.FC component using DisplayLayout + name-only DisplayField components\n */\nexport function generateDefaultDisplayTemplate(\n schema: z.ZodTypeAny,\n): React.FC {\n const fields = extractSchemaFieldList(schema);\n // Same nested-union limitation as the form generator, reported at the same\n // moment — the display side falls back to a `<DisplayField>` that resolves no\n // child shape and renders nothing, so the silence is identical.\n reportUnrenderableNestedObjectFields(fields, 'display');\n\n if (fields.length === 0) {\n const EmptyDisplayTemplate: React.FC = () => <DisplayLayout />;\n return EmptyDisplayTemplate;\n }\n\n const renderDisplayField = (field: SchemaFieldInfo): ReactNode => {\n if (field.schemaType === FieldSchemaType.OBJECT) {\n return renderDisplayObjectScope(field);\n }\n return <DisplayField key={field.name} name={field.name} />;\n };\n\n const DefaultDisplayTemplate: React.FC = () => (\n <DisplayLayout>\n {fields.map(renderDisplayField)}\n </DisplayLayout>\n );\n return DefaultDisplayTemplate;\n}\n\n/**\n * Renders a nested OBJECT field for display using ObjectScope + recursive DisplayField.\n */\nfunction renderDisplayObjectScope(field: SchemaFieldInfo): ReactNode {\n const innerShape = readNestedObjectShape(field.schema);\n\n const innerKeys = Object.keys(innerShape);\n const renderableKeys = innerKeys.filter(k => {\n const s = innerShape[k];\n return !isVirtualField(s) && !isBackendOnlyField(s);\n });\n\n if (renderableKeys.length === 0) {\n return <DisplayField key={field.name} name={field.name} />;\n }\n\n return (\n <ObjectScope key={field.name} name={field.name}>\n {renderableKeys.map(key => {\n const childSchema = innerShape[key];\n const childType = getSchemaType(childSchema);\n\n if (childType === FieldSchemaType.OBJECT) {\n const nestedField: SchemaFieldInfo = {\n name: key,\n schema: childSchema,\n schemaType: childType,\n };\n return renderDisplayObjectScope(nestedField);\n }\n\n return <DisplayField key={key} name={key} />;\n })}\n </ObjectScope>\n );\n}\n\n// =============================================================================\n// SUMMARY TEMPLATE GENERATION\n// =============================================================================\n\n/**\n * Generates a default summary layout template (React.FC) from a Zod object schema.\n *\n * Schema-only: values are resolved from DisplayTemplateContext at render time.\n * Each field uses `<DisplayField name=\"x\" />` — rendered with compact chrome\n * from the `defaultChromeMode.summary` set on the enclosing `ResourceSummaryDisplayer`.\n *\n * Includes only fields decorated with `isSummaryField()`. If no summary fields\n * are defined, renders all non-backend-only fields with summary variant.\n *\n * @param schema - The root Zod object schema for the resource\n * @returns React.FC component using SummaryLayout + name-only DisplayField components\n */\nexport function generateDefaultSummaryTemplate(\n schema: z.ZodTypeAny,\n): React.FC {\n // Union-aware shape (matches the display/form generators): `getObjectShape`\n // returns null for a discriminated union, so a polymorphic resource with no\n // authored `layout.summary` would otherwise fall into the empty branch and\n // render a blank FK preview / ReadSummary body. `commonOnly: true` yields the\n // fields shared across variants.\n const shape = AutomatedLayoutFrontendUtils.getObjectLikeFieldShape(schema, { commonOnly: true });\n const keys = shape ? Object.keys(shape) : [];\n\n // The generated default is BODY-ONLY: `titlePlacement={TEMPLATE_OWNED}` so\n // `SummaryLayout` renders no auto title. Resources WITHOUT an authored\n // `layout.summary` keep their title host-owned (list card / FK popover render\n // the primary label themselves) — routing the default through an AUTO title\n // would restyle every no-template list in every app. Only AUTHORED templates\n // opt the title into the flow.\n if (!shape || keys.length === 0) {\n const EmptySummaryTemplate: React.FC = () => (\n <SummaryLayout titlePlacement={SummaryTitlePlacement.TEMPLATE_OWNED} />\n );\n return EmptySummaryTemplate;\n }\n\n // Summaries are `isSummaryField`-scoped (a DIFFERENT axis from the display\n // view's all-non-hidden selection), so — unlike the display generator — we do\n // NOT exclude virtual fields: a virtual field can legitimately be an authored\n // summary field, and `ResourceLayoutUtils.detectSummaryFields` (the sibling\n // path feeding table columns + card bodies) includes them too. We keep them in\n // sync; only backend-only fields (no client value) are dropped.\n const summaryKeys = keys.filter(key => {\n const fieldSchema = shape[key];\n return !isBackendOnlyField(fieldSchema) && isSummaryField(fieldSchema);\n });\n\n const targetKeys = summaryKeys.length > 0\n ? summaryKeys\n : keys.filter(key => !isBackendOnlyField(shape[key]));\n\n const DefaultSummaryTemplate: React.FC = () => (\n <SummaryLayout titlePlacement={SummaryTitlePlacement.TEMPLATE_OWNED}>\n {targetKeys.map(key => (\n <DisplayField key={key} name={key} />\n ))}\n </SummaryLayout>\n );\n return DefaultSummaryTemplate;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"default-layout-generator.frontend.utils.js","sourceRoot":"","sources":["../../../../src/core/automated-layout/default-layout-generator.frontend.utils.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAEb,OAAO,KAAK,MAAM,OAAO,CAAC;AAI1B,OAAO,EACL,eAAe,EACf,aAAa,EACb,cAAc,EACd,aAAa,EACb,iBAAiB,EACjB,sBAAsB,EACtB,uBAAuB,EACvB,oBAAoB,EACpB,YAAY,EACZ,cAAc,EACd,kBAAkB,EAClB,cAAc,EACd,iBAAiB,GAClB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,4BAA4B,EAAE,MAAM,mCAAmC,CAAC;AACjF,OAAO,EAAE,2BAA2B,EAAE,MAAM,qCAAqC,CAAC;AAElF,OAAO,EAAE,UAAU,EAAE,MAAM,8DAA8D,CAAC;AAC1F,OAAO,EAAE,aAAa,EAAE,MAAM,iEAAiE,CAAC;AAChG,OAAO,EAAE,aAAa,EAAE,qBAAqB,EAAE,MAAM,iEAAiE,CAAC;AACvH,OAAO,EAAE,oBAAoB,EAAE,MAAM,wEAAwE,CAAC;AAC9G,OAAO,EAAE,YAAY,EAAE,MAAM,gEAAgE,CAAC;AAC9F,OAAO,EAAE,WAAW,EAAE,MAAM,+DAA+D,CAAC;AAC5F,OAAO,EAAE,mBAAmB,EAAE,MAAM,uEAAuE,CAAC;AAC5G,OAAO,EAAE,SAAS,EAAE,MAAM,yDAAyD,CAAC;AACpF,OAAO,EAAE,8BAA8B,EAAE,MAAM,mEAAmE,CAAC;AACnH,OAAO,EAAE,YAAY,EAAE,MAAM,0DAA0D,CAAC;AACxF,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAgC3C,SAAS,qBAAqB,CAC5B,IAAY,EACZ,MAAoB,EACpB,kBAA2B;IAE3B,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC;IACzC,MAAM,cAAc,GAAG,iBAAiB,CAAC,MAAM,CAAC,CAAC;IAEjD,OAAO;QACL,IAAI;QACJ,MAAM;QACN,UAAU;QACV,cAAc;QACd,mBAAmB,EAAE,cAAc;YACjC,CAAC,CAAC,yBAAyB,CAAC,cAAc,CAAC;YAC3C,CAAC,CAAC,SAAS;QACb,eAAe,EAAE,kBAAkB,KAAK,IAAI;KAC7C,CAAC;AACJ,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,sBAAsB,CACpC,MAAoB,EACpB,kBAA2B;IAE3B,MAAM,KAAK,GAAG,4BAA4B,CAAC,uBAAuB,CAAC,MAAM,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC;IACjG,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAE7C,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IAE3C,MAAM,MAAM,GAAsB,EAAE,CAAC;IAErC,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,MAAM,WAAW,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC;QAC/B,IAAI,cAAc,CAAC,WAAW,CAAC,IAAI,kBAAkB,CAAC,WAAW,CAAC;YAAE,SAAS;QAE7E,MAAM,CAAC,IAAI,CAAC,qBAAqB,CAAC,GAAG,EAAE,WAAW,EAAE,kBAAkB,CAAC,CAAC,CAAC;IAC3E,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AACH,SAAS,qBAAqB,CAAC,MAAoB;IACjD,OAAO,iBAAiB,CAAC,MAAM,CAAC,CAAC;AACnC,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,SAAS,8BAA8B,CAAC,KAAsB;IAC5D,MAAM,SAAS,GAAG,YAAY,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IAC7C,IAAI,CAAC,oBAAoB,CAAC,SAAS,CAAC;QAAE,OAAO,IAAI,CAAC;IAElD,MAAM,aAAa,GAAG,uBAAuB,CAAC,SAAS,EAAE,eAAe,CAAC,CAAC;IAC1E,MAAM,OAAO,GAAG,CAAC,sBAAsB,CAAC,SAAS,EAAE,SAAS,CAAC,IAAI,EAAE,CAAmB,CAAC;IACvF,IAAI,CAAC,aAAa,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAExD,0EAA0E;IAC1E,iFAAiF;IACjF,MAAM,cAAc,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,GAAG,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;IAC7E,MAAM,UAAU,GAAG,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI,IAAI,GAAG,EAAU,CAAC,CAAC;SAC7D,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,aAAa,IAAI,cAAc,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IAEvF,MAAM,QAAQ,GAA8B,EAAE,CAAC;IAE/C,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC7B,MAAM,WAAW,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC;QAC3C,IAAI,CAAC,WAAW;YAAE,SAAS;QAE3B;;;;;;WAMG;QACH,MAAM,aAAa,GAAG,sBAAsB,CAAC,WAAW,CAAC,aAAa,CAAC,EAAE,QAAQ,CAAC,IAAI,EAAE,CAAC;QACzF,MAAM,YAAY,GAAG,aAAa,CAAC,CAAC,CAAC,CAAC;QACtC,IAAI,YAAY,KAAK,SAAS,IAAI,YAAY,KAAK,IAAI;YAAE,SAAS;QAElE,MAAM,eAAe,GAAG,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAC5D,GAAG,KAAK,aAAa;eAClB,CAAC,UAAU,CAAC,QAAQ,CAAC,GAAG,CAAC;eACzB,CAAC,cAAc,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;eACjC,CAAC,kBAAkB,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CACzC,CAAC;QACF,IAAI,eAAe,CAAC,MAAM,KAAK,CAAC;YAAE,SAAS;QAE3C,QAAQ,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,GAAG,CAC/B,4BACG,eAAe,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,KAAC,SAAS,IAAW,IAAI,EAAE,GAAG,IAAd,GAAG,CAAe,CAAC,GAC9D,CACJ,CAAC;IACJ,CAAC;IAED,MAAM,WAAW,GAAG,cAAc,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;IAC/C,MAAM,oBAAoB,GAAG,WAAW;QACtC,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,cAAc,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,kBAAkB,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC;QACtG,CAAC,CAAC,EAAE,CAAC;IAEP,OAAO,CACL,MAAC,WAAW,IAAkB,IAAI,EAAE,KAAK,CAAC,IAAI,aAC5C,KAAC,SAAS,IAAC,IAAI,EAAE,aAAa,GAAI,EACjC,oBAAoB,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,KAAC,SAAS,IAAW,IAAI,EAAE,GAAG,IAAd,GAAG,CAAe,CAAC,EACnE,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,MAAM,GAAG,CAAC,IAAI,CACnC,KAAC,mBAAmB,IAAC,KAAK,EAAE,aAAa,EAAE,QAAQ,EAAE,QAAQ,GAAI,CAClE,KALe,KAAK,CAAC,IAAI,CAMd,CACf,CAAC;AACJ,CAAC;AAED,SAAS,yBAAyB,CAAC,MAAsB;IACvD,MAAM,UAAU,GAAwB,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC;QACtE,CAAC,CAAC,MAAM,CAAC,UAAU;QACnB,CAAC,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;IACxB,OAAO,CAAC,GAAG,IAAI,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACpD,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,SAAS,oCAAoC,CAC3C,MAAyB,EACzB,YAAyC,EACzC,mBAA2B,EAAE;IAE7B,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,YAAY;QAAE,OAAO;IAElD,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,IAAI,KAAK,CAAC,UAAU,KAAK,eAAe,CAAC,MAAM;YAAE,SAAS;QAE1D,MAAM,SAAS,GAAG,gBAAgB,CAAC,CAAC,CAAC,GAAG,gBAAgB,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC;QAEtF,IAAI,oBAAoB,CAAC,YAAY,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC;YACrD,qFAAqF;YACrF,+EAA+E;YAC/E,6EAA6E;YAC7E,8EAA8E;YAC9E,+EAA+E;YAC/E,8EAA8E;YAC9E,6EAA6E;YAC7E,mEAAmE;YACnE,IAAI,YAAY,KAAK,MAAM,IAAI,8BAA8B,CAAC,KAAK,CAAC,KAAK,IAAI;gBAAE,SAAS;YAExF,+HAA+H;YAC/H,OAAO,CAAC,IAAI,CACV,mCAAmC,SAAS,uDAAuD;kBACjG,WAAW,YAAY,oCAAoC,SAAS,yBAAyB;kBAC7F,8BAA8B,YAAY,KAAK,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,8BAA8B,CAC3G,CAAC;YACF,SAAS;QACX,CAAC;QAED,2EAA2E;QAC3E,gFAAgF;QAChF,8EAA8E;QAC9E,gFAAgF;QAChF,4EAA4E;QAC5E,+DAA+D;QAC/D,MAAM,UAAU,GAAG,cAAc,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QAChD,IAAI,CAAC,UAAU;YAAE,SAAS;QAE1B,oCAAoC,CAClC,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC;aACvB,MAAM,CAAC,CAAC,CAAC,EAAE,WAAW,CAAC,EAAE,EAAE,CAAC,CAAC,cAAc,CAAC,WAAW,CAAC,IAAI,CAAC,kBAAkB,CAAC,WAAW,CAAC,CAAC;aAC7F,GAAG,CAAC,CAAC,CAAC,SAAS,EAAE,WAAW,CAAC,EAAE,EAAE,CAAC,qBAAqB,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC,EACnF,YAAY,EACZ,SAAS,CACV,CAAC;IACJ,CAAC;AACH,CAAC;AAoCD,gFAAgF;AAChF,kCAAkC;AAClC,gFAAgF;AAEhF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoDG;AACH,MAAM,UAAU,2BAA2B,CACzC,MAAoB,EACpB,OAAsC;IAEtC,MAAM,iBAAiB,GAAG,OAAO,EAAE,iBAAiB,CAAC;IAErD,MAAM,MAAM,GAAG,sBAAsB,CAAC,MAAM,EAAE,iBAAiB,EAAE,kBAAkB,CAAC,CAAC;IACrF,oCAAoC,CAAC,MAAM,EAAE,2BAA2B,CAAC,IAAI,CAAC,CAAC;IAC/E,MAAM,UAAU,GAAG,OAAO,EAAE,mBAAmB,KAAK,KAAK,CAAC;IAC1D,MAAM,gBAAgB,GAAG,OAAO,EAAE,mBAAmB,KAAK,KAAK,CAAC;IAEhE,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxB,MAAM,aAAa,GAAa,GAAG,EAAE,CAAC,KAAC,UAAU,IAAC,sBAAsB,EAAE,UAAU,GAAI,CAAC;QACzF,aAAa,CAAC,WAAW,GAAG,8BAA8B,CAAC;QAC3D,OAAO,aAAa,CAAC;IACvB,CAAC;IAED,MAAM,sBAAsB,GAAG,6BAA6B,CAAC,MAAM,CAAC,CAAC;IACrE,MAAM,WAAW,GAAG,sBAAsB,CAAC,MAAM,GAAG,CAAC,CAAC;IAEtD,MAAM,cAAc,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IAExD,MAAM,iBAAiB,GAAa,GAAG,EAAE;QACvC,MAAM,WAAW,GAAG,mBAAmB,CAAC,WAAW,EAAE,sBAAsB,CAAC,CAAC;QAC7E,MAAM,mBAAmB,GAAG,8BAA8B,EAAE,CAAC;QAC7D,MAAM,qBAAqB,GAAG,IAAI,GAAG,CACnC,MAAM,CAAC,IAAI,CAAC,mBAAmB,EAAE,kBAAkB,IAAI,EAAE,CAAC,CAC3D,CAAC;QACF,KAAK,MAAM,eAAe,IAAI,mBAAmB,EAAE,gBAAgB,IAAI,EAAE,EAAE,CAAC;YAC1E,qBAAqB,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;QAC7C,CAAC;QAED,MAAM,WAAW,GAAG,CAAC,KAAsB,EAAa,EAAE;YACxD,MAAM,oBAAoB,GAAG,OAAO,CAAC,mBAAmB,EAAE,uBAAuB,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;YACjG,MAAM,OAAO,GAAG,qBAAqB,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,oBAAoB;gBAC5E,CAAC,CAAC,IAAI;gBACN,CAAC,CAAC,kBAAkB,CAChB,KAAK,EACL,iBAAiB,EACjB,cAAc,EACd,qBAAqB,EACrB,mBAAmB,EAAE,uBAAuB,EAC5C,WAAW,EACX,sBAAsB,CACvB,CAAC;YAEN,IAAI,CAAC,KAAK,CAAC,cAAc,IAAI,CAAC,WAAW;gBAAE,OAAO,OAAO,CAAC;YAE1D,MAAM,SAAS,GAAG,yBAAyB,CAAC,KAAK,CAAC,cAAc,EAAE,WAAW,EAAE,sBAAsB,CAAC,CAAC;YACvG,OAAO,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC;QACpC,CAAC,CAAC;QAEF,OAAO,CACL,MAAC,UAAU,IAAC,sBAAsB,EAAE,UAAU,aAC3C,gBAAgB,IAAI,KAAC,oBAAoB,KAAG,EAC5C,MAAM,CAAC,GAAG,CAAC,WAAW,CAAC,EACvB,UAAU,IAAI,KAAC,YAAY,KAAG,IACpB,CACd,CAAC;IACJ,CAAC,CAAC;IAEF,iBAAiB,CAAC,WAAW,GAAG,uBAAuB,CAAC;IACxD,OAAO,iBAAiB,CAAC;AAC3B,CAAC;AAGD,gFAAgF;AAChF,oCAAoC;AACpC,gFAAgF;AAEhF;;;;GAIG;AACH,SAAS,mBAAmB,CAAC,WAAoB,EAAE,WAAqB;IACtE,MAAM,MAAM,GAAG,QAAQ,CAAC,EAAE,IAAI,EAAE,WAAW,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IAClE,OAAO,WAAW,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;AAC/E,CAAC;AAGD,gFAAgF;AAChF,6BAA6B;AAC7B,gFAAgF;AAEhF;;GAEG;AACH,SAAS,kBAAkB,CACzB,KAAsB,EACtB,iBAA0D,EAC1D,cAA4B,EAC5B,mBAAiC,EACjC,uBAAmD,EACnD,WAAuB,EACvB,sBAAiC;IAEjC,IAAI,uBAAuB,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QAC1C,OAAO,KAAC,SAAS,IAAkB,IAAI,EAAE,KAAK,CAAC,IAAI,IAA5B,KAAK,CAAC,IAAI,CAAsB,CAAC;IAC1D,CAAC;IAED,IAAI,KAAK,CAAC,eAAe,IAAI,iBAAiB,IAAI,cAAc,IAAI,mBAAmB,EAAE,CAAC;QACxF,OAAO,8BAA8B,CACnC,KAAK,EACL,iBAAiB,EACjB,cAAc,EACd,mBAAmB,EACnB,uBAAuB,CACxB,CAAC;IACJ,CAAC;IAED,IAAI,KAAK,CAAC,UAAU,KAAK,eAAe,CAAC,MAAM,EAAE,CAAC;QAChD,OAAO,iBAAiB,CAAC,KAAK,EAAE,WAAW,EAAE,sBAAsB,CAAC,CAAC;IACvE,CAAC;IAED,OAAO,CACL,KAAC,SAAS,IAAkB,IAAI,EAAE,KAAK,CAAC,IAAI,IAA5B,KAAK,CAAC,IAAI,CAAsB,CACjD,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,SAAS,8BAA8B,CACrC,kBAAmC,EACnC,MAAmC,EACnC,cAA2B,EAC3B,mBAAgC,EAChC,uBAAmD;IAEnD,MAAM,QAAQ,GAA8B,EAAE,CAAC;IAE/C,IAAI,MAAM,CAAC,gBAAgB,EAAE,CAAC;QAC5B,KAAK,MAAM,OAAO,IAAI,MAAM,CAAC,gBAAgB,EAAE,CAAC;YAC9C,MAAM,YAAY,GAAG,cAAc,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;YACpD,MAAM,WAAW,GAAG,aAAa,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;YAElD,IAAI,YAAY,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC3C,MAAM,eAAe,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAC7C,CAAC,cAAc,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;oBAChC,CAAC,kBAAkB,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;oBACpC,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC;oBACtB,CAAC,CAAC,mBAAmB,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,OAAO,CAAC,uBAAuB,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CACvE,CAAC;gBAEF,IAAI,eAAe,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBAC/B,QAAQ,CAAC,OAAO,CAAC,uBAAuB,CAAC,GAAG,CAC1C,4BACG,eAAe,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAC5B,KAAC,SAAS,IAAW,IAAI,EAAE,GAAG,IAAd,GAAG,CAAe,CACnC,CAAC,GACD,CACJ,CAAC;gBACJ,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAED,MAAM,WAAW,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;IAErD,OAAO,CACL,MAAC,KAAK,CAAC,QAAQ,eACb,KAAC,SAAS,IAAC,IAAI,EAAE,kBAAkB,CAAC,IAAI,GAAI,EAC3C,WAAW,IAAI,CACd,KAAC,mBAAmB,IAClB,KAAK,EAAE,MAAM,CAAC,kBAAkB,EAChC,QAAQ,EAAE,QAAQ,GAClB,CACH,KAPkB,kBAAkB,CAAC,IAAI,CAQ3B,CAClB,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,SAAS,iBAAiB,CACxB,KAAsB,EACtB,WAAuB,EACvB,sBAAiC,EACjC,mBAA2B,EAAE;IAE7B,IAAI,KAAK,CAAC,cAAc,IAAI,WAAW,IAAI,sBAAsB,EAAE,CAAC;QAClE,MAAM,oBAAoB,GAAG,mBAAmB,CAAC,KAAK,CAAC,cAAc,EAAE,gBAAgB,CAAC,CAAC;QACzF,MAAM,SAAS,GAAG,yBAAyB,CAAC,oBAAoB,EAAE,WAAW,EAAE,sBAAsB,CAAC,CAAC;QACvG,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IAED,iFAAiF;IACjF,+EAA+E;IAC/E,uEAAuE;IACvE,oCAAoC;IACpC,MAAM,UAAU,GAAG,8BAA8B,CAAC,KAAK,CAAC,CAAC;IACzD,IAAI,UAAU,EAAE,CAAC;QACf,OAAO,UAAU,CAAC;IACpB,CAAC;IAED,MAAM,UAAU,GAAG,qBAAqB,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IAEvD,MAAM,SAAS,GAAG,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IAC1C,MAAM,cAAc,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE;QAC1C,MAAM,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC;QACxB,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC;IACtD,CAAC,CAAC,CAAC;IAEH,+EAA+E;IAC/E,iFAAiF;IACjF,gFAAgF;IAChF,kDAAkD;IAClD,IAAI,cAAc,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAChC,OAAO,KAAC,SAAS,IAAkB,IAAI,EAAE,KAAK,CAAC,IAAI,IAA5B,KAAK,CAAC,IAAI,CAAsB,CAAC;IAC1D,CAAC;IAED,MAAM,gBAAgB,GAAG,gBAAgB,CAAC,CAAC,CAAC,GAAG,gBAAgB,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC;IAE7F,OAAO,CACL,KAAC,WAAW,IAAkB,IAAI,EAAE,KAAK,CAAC,IAAI,YAC3C,cAAc,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE;YACxB,MAAM,WAAW,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC;YACpC,MAAM,SAAS,GAAG,aAAa,CAAC,WAAW,CAAC,CAAC;YAE7C,IAAI,SAAS,KAAK,eAAe,CAAC,MAAM,EAAE,CAAC;gBACzC,MAAM,WAAW,GAAG,qBAAqB,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC;gBAC5D,OAAO,iBAAiB,CACtB,WAAW,EACX,WAAW,EACX,sBAAsB,EACtB,gBAAgB,CACjB,CAAC;YACJ,CAAC;YAED,OAAO,KAAC,SAAS,IAAW,IAAI,EAAE,GAAG,IAAd,GAAG,CAAe,CAAC;QAC5C,CAAC,CAAC,IAhBc,KAAK,CAAC,IAAI,CAiBd,CACf,CAAC;AACJ,CAAC;AAGD,gFAAgF;AAChF,kCAAkC;AAClC,gFAAgF;AAEhF,SAAS,6BAA6B,CAAC,MAAyB;IAC9D,MAAM,SAAS,GAAG,IAAI,GAAG,EAAU,CAAC;IACpC,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,kCAAkC,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;IACvD,CAAC;IACD,OAAO,CAAC,GAAG,SAAS,CAAC,CAAC;AACxB,CAAC;AAED,SAAS,kCAAkC,CACzC,KAAsB,EACtB,SAAsB,EACtB,mBAA2B,EAAE;IAE7B,IAAI,KAAK,CAAC,cAAc,EAAE,CAAC;QACzB,MAAM,oBAAoB,GAAG,mBAAmB,CAAC,KAAK,CAAC,cAAc,EAAE,gBAAgB,CAAC,CAAC;QACzF,KAAK,MAAM,SAAS,IAAI,yBAAyB,CAAC,oBAAoB,CAAC,EAAE,CAAC;YACxE,SAAS,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QAC3B,CAAC;IACH,CAAC;IAED,IAAI,KAAK,CAAC,UAAU,KAAK,eAAe,CAAC,MAAM,EAAE,CAAC;QAChD,OAAO;IACT,CAAC;IAED,MAAM,UAAU,GAAG,qBAAqB,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IAEvD,MAAM,gBAAgB,GAAG,gBAAgB,CAAC,CAAC,CAAC,GAAG,gBAAgB,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC;IAC7F,KAAK,MAAM,CAAC,SAAS,EAAE,WAAW,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC;QAClE,IAAI,cAAc,CAAC,WAAW,CAAC,IAAI,kBAAkB,CAAC,WAAW,CAAC,EAAE,CAAC;YACnE,SAAS;QACX,CAAC;QAED,kCAAkC,CAChC,qBAAqB,CAAC,SAAS,EAAE,WAA2B,CAAC,EAC7D,SAAS,EACT,gBAAgB,CACjB,CAAC;IACJ,CAAC;AACH,CAAC;AAED,SAAS,mBAAmB,CAC1B,MAAsB,EACtB,gBAAwB;IAExB,IAAI,CAAC,gBAAgB,EAAE,CAAC;QACtB,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,MAAM,UAAU,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC;QACjD,CAAC,CAAC,MAAM,CAAC,UAAU;QACnB,CAAC,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;IAExB,OAAO;QACL,GAAG,MAAM;QACT,UAAU,EAAE,UAAU,CAAC,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;YACzC,GAAG,SAAS;YACZ,KAAK,EAAE,SAAS,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,SAAS,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC;gBACnE,CAAC,CAAC,SAAS,CAAC,KAAK;gBACjB,CAAC,CAAC,GAAG,gBAAgB,IAAI,SAAS,CAAC,KAAK,EAAE;SAC7C,CAAC,CAAC;KACJ,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,SAAS,yBAAyB,CAChC,MAAsB,EACtB,WAAsB,EACtB,cAAwB;IAExB,MAAM,UAAU,GAA4B,EAAE,CAAC;IAC/C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,cAAc,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAC/C,UAAU,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC;IACjD,CAAC;IACD,OAAO,4BAA4B,CAAC,gBAAgB,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;AAC3E,CAAC;AAGD,gFAAgF;AAChF,8BAA8B;AAC9B,gFAAgF;AAEhF;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,8BAA8B,CAC5C,MAAoB;IAEpB,MAAM,MAAM,GAAG,sBAAsB,CAAC,MAAM,CAAC,CAAC;IAC9C,2EAA2E;IAC3E,8EAA8E;IAC9E,gEAAgE;IAChE,oCAAoC,CAAC,MAAM,EAAE,2BAA2B,CAAC,OAAO,CAAC,CAAC;IAElF,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxB,MAAM,oBAAoB,GAAa,GAAG,EAAE,CAAC,KAAC,aAAa,KAAG,CAAC;QAC/D,OAAO,oBAAoB,CAAC;IAC9B,CAAC;IAED,MAAM,kBAAkB,GAAG,CAAC,KAAsB,EAAa,EAAE;QAC/D,IAAI,KAAK,CAAC,UAAU,KAAK,eAAe,CAAC,MAAM,EAAE,CAAC;YAChD,OAAO,wBAAwB,CAAC,KAAK,CAAC,CAAC;QACzC,CAAC;QACD,OAAO,KAAC,YAAY,IAAkB,IAAI,EAAE,KAAK,CAAC,IAAI,IAA5B,KAAK,CAAC,IAAI,CAAsB,CAAC;IAC7D,CAAC,CAAC;IAEF,MAAM,sBAAsB,GAAa,GAAG,EAAE,CAAC,CAC7C,KAAC,aAAa,cACX,MAAM,CAAC,GAAG,CAAC,kBAAkB,CAAC,GACjB,CACjB,CAAC;IACF,OAAO,sBAAsB,CAAC;AAChC,CAAC;AAED;;GAEG;AACH,SAAS,wBAAwB,CAAC,KAAsB;IACtD,MAAM,UAAU,GAAG,qBAAqB,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IAEvD,MAAM,SAAS,GAAG,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IAC1C,MAAM,cAAc,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE;QAC1C,MAAM,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC;QACxB,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC;IACtD,CAAC,CAAC,CAAC;IAEH,IAAI,cAAc,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAChC,OAAO,KAAC,YAAY,IAAkB,IAAI,EAAE,KAAK,CAAC,IAAI,IAA5B,KAAK,CAAC,IAAI,CAAsB,CAAC;IAC7D,CAAC;IAED,OAAO,CACL,KAAC,WAAW,IAAkB,IAAI,EAAE,KAAK,CAAC,IAAI,YAC3C,cAAc,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE;YACxB,MAAM,WAAW,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC;YACpC,MAAM,SAAS,GAAG,aAAa,CAAC,WAAW,CAAC,CAAC;YAE7C,IAAI,SAAS,KAAK,eAAe,CAAC,MAAM,EAAE,CAAC;gBACzC,MAAM,WAAW,GAAoB;oBACnC,IAAI,EAAE,GAAG;oBACT,MAAM,EAAE,WAAW;oBACnB,UAAU,EAAE,SAAS;iBACtB,CAAC;gBACF,OAAO,wBAAwB,CAAC,WAAW,CAAC,CAAC;YAC/C,CAAC;YAED,OAAO,KAAC,YAAY,IAAW,IAAI,EAAE,GAAG,IAAd,GAAG,CAAe,CAAC;QAC/C,CAAC,CAAC,IAfc,KAAK,CAAC,IAAI,CAgBd,CACf,CAAC;AACJ,CAAC;AAED,gFAAgF;AAChF,8BAA8B;AAC9B,gFAAgF;AAEhF;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,8BAA8B,CAC5C,MAAoB;IAEpB,4EAA4E;IAC5E,4EAA4E;IAC5E,2EAA2E;IAC3E,8EAA8E;IAC9E,iCAAiC;IACjC,MAAM,KAAK,GAAG,4BAA4B,CAAC,uBAAuB,CAAC,MAAM,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC;IACjG,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAE7C,2EAA2E;IAC3E,uEAAuE;IACvE,8EAA8E;IAC9E,4EAA4E;IAC5E,6EAA6E;IAC7E,+BAA+B;IAC/B,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAChC,MAAM,oBAAoB,GAAa,GAAG,EAAE,CAAC,CAC3C,KAAC,aAAa,IAAC,cAAc,EAAE,qBAAqB,CAAC,cAAc,GAAI,CACxE,CAAC;QACF,OAAO,oBAAoB,CAAC;IAC9B,CAAC;IAED,2EAA2E;IAC3E,8EAA8E;IAC9E,8EAA8E;IAC9E,4EAA4E;IAC5E,+EAA+E;IAC/E,gEAAgE;IAChE,MAAM,WAAW,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE;QACpC,MAAM,WAAW,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC;QAC/B,OAAO,CAAC,kBAAkB,CAAC,WAAW,CAAC,IAAI,cAAc,CAAC,WAAW,CAAC,CAAC;IACzE,CAAC,CAAC,CAAC;IAEH,MAAM,UAAU,GAAG,WAAW,CAAC,MAAM,GAAG,CAAC;QACvC,CAAC,CAAC,WAAW;QACb,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,kBAAkB,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IAExD,MAAM,sBAAsB,GAAa,GAAG,EAAE,CAAC,CAC7C,KAAC,aAAa,IAAC,cAAc,EAAE,qBAAqB,CAAC,cAAc,YAChE,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CACrB,KAAC,YAAY,IAAW,IAAI,EAAE,GAAG,IAAd,GAAG,CAAe,CACtC,CAAC,GACY,CACjB,CAAC;IACF,OAAO,sBAAsB,CAAC;AAChC,CAAC","sourcesContent":["'use client';\n\nimport React from 'react';\nimport type { ReactNode } from 'react';\nimport { z } from 'zod';\nimport type { ShowWhenParams, ShowWhenCondition } from '@wildo-ai/zod-decorators';\nimport {\n FieldSchemaType,\n getSchemaType,\n getObjectShape,\n getObjectKeys,\n getZodObjectShape,\n getZodDefArrayProperty,\n getZodDefStringProperty,\n isDiscriminatedUnion,\n unwrapSchema,\n isVirtualField,\n isBackendOnlyField,\n isSummaryField,\n getShowWhenParams,\n} from '@wildo-ai/zod-decorators';\nimport { AutomatedLayoutFrontendUtils } from './automated-layout.frontend.utils';\nimport { AutomatedLayoutTemplateKind } from './automated-layout.frontend.schemas';\nimport type { InheritanceSchemaDefinition } from './automated-layout.frontend.schemas';\nimport { FormLayout } from '~wildo-frontend-lib/components/resources/skeleton/FormLayout';\nimport { DisplayLayout } from '~wildo-frontend-lib/components/resources/skeleton/DisplayLayout';\nimport { SummaryLayout, SummaryTitlePlacement } from '~wildo-frontend-lib/components/resources/skeleton/SummaryLayout';\nimport { FormErrorSummarySlot } from '~wildo-frontend-lib/components/resources/skeleton/FormErrorSummarySlot';\nimport { SubmitButton } from '~wildo-frontend-lib/components/resources/skeleton/SubmitButton';\nimport { ObjectScope } from '~wildo-frontend-lib/components/resources/skeleton/ObjectScope';\nimport { DiscriminatorSwitch } from '~wildo-frontend-lib/components/resources/skeleton/DiscriminatorSwitch';\nimport { FormField } from '~wildo-frontend-lib/components/form/automated/FormField';\nimport { useOptionalFormTemplateContext } from '~wildo-frontend-lib/components/form/automated/FormTemplateContext';\nimport { DisplayField } from '~wildo-frontend-lib/components/data-display/DisplayField';\nimport { useWatch } from 'react-hook-form';\n\n/**\n * Label resolver function signature for layout template generators.\n * Receives a field name (potentially dotted path) and returns a human-readable label.\n * Consumers (AutomatedForm, AutomaticDisplayer) pass their i18n-aware resolver here.\n */\nexport type LayoutLabelResolver = (fieldName: string) => string;\n\n// =============================================================================\n// SCHEMA FIELD LIST — THIN EXTRACTION UTILITY\n// =============================================================================\n\n/**\n * Lightweight field descriptor produced by `extractSchemaFieldList()`.\n * Contains only what the template generator needs — no grid/row/layout calculations.\n */\nexport interface SchemaFieldInfo {\n /** Field key (top-level name, not dotted path) */\n name: string;\n /** The Zod schema for this field */\n schema: z.ZodTypeAny;\n /** Resolved schema type (STRING, NUMBER, OBJECT, ARRAY, etc.) */\n schemaType: FieldSchemaType;\n /** showWhen conditional visibility params (from `.showWhen()` decorator) */\n showWhenParams?: ShowWhenParams;\n /** Fields that showWhen depends on (deduped) */\n showWhenWatchFields?: string[];\n /** Whether this field is a discriminator for a discriminated union */\n isDiscriminator?: boolean;\n}\n\nfunction createSchemaFieldInfo(\n name: string,\n schema: z.ZodTypeAny,\n discriminatorField?: string,\n): SchemaFieldInfo {\n const schemaType = getSchemaType(schema);\n const showWhenParams = getShowWhenParams(schema);\n\n return {\n name,\n schema,\n schemaType,\n showWhenParams,\n showWhenWatchFields: showWhenParams\n ? dedupeShowWhenWatchFields(showWhenParams)\n : undefined,\n isDiscriminator: discriminatorField === name,\n };\n}\n\n/**\n * Extracts a flat list of renderable root fields from an object-like schema.\n *\n * Produces the field metadata the template generator needs.\n * No grid math, no row calculations, no section/wizard grouping.\n *\n * Excludes: virtual fields, backend-only fields.\n * Does NOT exclude operation-specific fields — those are handled at render time.\n */\nexport function extractSchemaFieldList(\n schema: z.ZodTypeAny,\n discriminatorField?: string,\n): SchemaFieldInfo[] {\n const shape = AutomatedLayoutFrontendUtils.getObjectLikeFieldShape(schema, { commonOnly: true });\n const keys = shape ? Object.keys(shape) : [];\n\n if (!shape || keys.length === 0) return [];\n\n const fields: SchemaFieldInfo[] = [];\n\n for (const key of keys) {\n const fieldSchema = shape[key];\n if (isVirtualField(fieldSchema) || isBackendOnlyField(fieldSchema)) continue;\n\n fields.push(createSchemaFieldInfo(key, fieldSchema, discriminatorField));\n }\n\n return fields;\n}\n\n/**\n * The ONE reader every nested traversal in this file goes through, and the place\n * the surprising part of `getZodObjectShape` is written down once instead of\n * being rediscovered at three call sites.\n *\n * `getZodObjectShape()` returns `{}` — an EMPTY OBJECT, not `null` — for anything\n * that is not a BARE `ZodObject`, and that includes every ordinary authoring\n * wrapper. Measured 2026-09-08 against zod 4.3.6:\n *\n * | authored field | `getZodObjectShape` | `getObjectShape` |\n * |-------------------------------------|---------------------|------------------|\n * | `z.object({ a, b })` | `['a','b']` | `['a','b']` |\n * | `z.object({ a, b }).optional()` | **`[]`** | `['a','b']` |\n * | `z.object({ a, b }).nullable()` | **`[]`** | `['a','b']` |\n * | `z.object({ a, b }).default({...})` | **`[]`** | `['a','b']` |\n * | `z.discriminatedUnion('t', [...])` | **`[]`** | `null` |\n *\n * Because `{}` is TRUTHY, an `if (!shape)` guard never fires; the traversal falls\n * out through its \"no renderable keys\" branch instead and emits ONE\n * `<FormField name={objectField} />` for the whole subtree.\n *\n * **That fallthrough is deliberate for the wrapper rows, and this comment exists\n * so it is not \"fixed\" a second time.** Swapping in `getObjectShape` here makes\n * the generator descend into a `.optional()` nested object and emit its declared\n * `<ObjectScope>` + per-child `<FormField>` structure — which was tried, measured,\n * and reverted, because it is a CHANGE with no defect behind it:\n *\n * - the single `<FormField>` is not a dead end. Its OBJECT branch mounts\n * `FormFieldComposite`, which reads the shape with `getObjectShape` (it\n * unwraps), renders every child as a real `FormField` under an absolute\n * dotted name, and gives the object a titled `ContentSection`. Measured with\n * that section available: an `.optional()` nested object rendered BOTH\n * children, and a `showWhen` on a child hid initially and appeared live on\n * the sibling toggle — i.e. nothing is dropped;\n * - descending would therefore only trade a titled section for a flat scope, on\n * every generated screen of every application whose schema has a wrapped\n * nested object. Wonder Todos' `todos.reminder` (`z.object({...}).optional()`)\n * deliberately renders through the composite in its authored layout, which is\n * what that trade would silently undo elsewhere.\n *\n * The union row is a different story and is NOT compensated — `getObjectShape`\n * returns `null` there too, so the composite renders nothing at all. That case is\n * handled before this reader is ever reached (see `renderObjectScope`).\n */\nfunction readNestedObjectShape(schema: z.ZodTypeAny): Record<string, z.ZodTypeAny> {\n return getZodObjectShape(schema);\n}\n\n/**\n * Builds the nested equivalent of the ROOT discriminated-union layout: a scope for\n * the union field, its discriminator, and a `<DiscriminatorSwitch>` carrying each\n * variant's own fields.\n *\n * This is the case the generator used to drop in silence. A field declared\n * `payload: z.discriminatedUnion('t', [...])` is `FieldSchemaType.OBJECT`, so it\n * took the object path, produced no readable shape, fell back to a single\n * `<FormField>` — and `FormFieldComposite` gets `null` from `getObjectShape` for a\n * union, so the authored field rendered NOTHING. Measured 2026-09-08: a two-variant\n * nested union contributed not one element to the generated form.\n *\n * Nothing new is invented here. `<DiscriminatorSwitch>` already resolves its\n * `field` through `useResolvedFieldName`, so placed inside `<ObjectScope name=\"payload\">`\n * it watches `payload.t` and its children resolve to `payload.xv` / `payload.yv`.\n * The root union path (`renderDiscriminatorAndVariants`) composes the same two\n * primitives; the only reason it could not serve here is that it is driven by the\n * caller-supplied `inheritanceConfig`, which describes the ROOT resource schema and\n * says nothing about an arbitrary nested field. The discriminator and the variant\n * literals are read from the schema instead, which is where they already are.\n *\n * Variant fields are filtered to those a variant OWNS: the fields shared by every\n * variant are rendered once, outside the switch, so switching the discriminator\n * does not remount them (and does not, via `shouldUnregister`, drop their values).\n *\n * Returns `null` when the schema is not a usable discriminated union, so callers\n * fall through to their existing behaviour rather than rendering half a union.\n */\nfunction renderNestedDiscriminatedUnion(field: SchemaFieldInfo): ReactNode | null {\n const unwrapped = unwrapSchema(field.schema);\n if (!isDiscriminatedUnion(unwrapped)) return null;\n\n const discriminator = getZodDefStringProperty(unwrapped, 'discriminator');\n const options = (getZodDefArrayProperty(unwrapped, 'options') ?? []) as z.ZodTypeAny[];\n if (!discriminator || options.length === 0) return null;\n\n // Fields every variant declares (the union's common base). Rendered once,\n // outside the switch — see the JSDoc above for why that matters beyond tidiness.\n const perVariantKeys = options.map(option => new Set(getObjectKeys(option)));\n const commonKeys = [...(perVariantKeys[0] ?? new Set<string>())]\n .filter(key => key !== discriminator && perVariantKeys.every(keys => keys.has(key)));\n\n const variants: Record<string, ReactNode> = {};\n\n for (const option of options) {\n const optionShape = getObjectShape(option);\n if (!optionShape) continue;\n\n /*\n * A variant's discriminator is a LITERAL (`z.literal('x')`), and Zod 4 stores a\n * literal's value in an ARRAY under `values` — the same shape\n * `resolveDiscriminatedUnionVariant` reads to match a variant to a value. Reading\n * it here is what keys the switch on the exact authored value rather than on the\n * variant's position in the options array.\n */\n const literalValues = getZodDefArrayProperty(optionShape[discriminator], 'values') ?? [];\n const variantValue = literalValues[0];\n if (variantValue === undefined || variantValue === null) continue;\n\n const variantOnlyKeys = Object.keys(optionShape).filter(key =>\n key !== discriminator\n && !commonKeys.includes(key)\n && !isVirtualField(optionShape[key])\n && !isBackendOnlyField(optionShape[key]),\n );\n if (variantOnlyKeys.length === 0) continue;\n\n variants[String(variantValue)] = (\n <>\n {variantOnlyKeys.map(key => <FormField key={key} name={key} />)}\n </>\n );\n }\n\n const commonShape = getObjectShape(options[0]);\n const renderableCommonKeys = commonShape\n ? commonKeys.filter(key => !isVirtualField(commonShape[key]) && !isBackendOnlyField(commonShape[key]))\n : [];\n\n return (\n <ObjectScope key={field.name} name={field.name}>\n <FormField name={discriminator} />\n {renderableCommonKeys.map(key => <FormField key={key} name={key} />)}\n {Object.keys(variants).length > 0 && (\n <DiscriminatorSwitch field={discriminator} variants={variants} />\n )}\n </ObjectScope>\n );\n}\n\nfunction dedupeShowWhenWatchFields(params: ShowWhenParams): string[] {\n const conditions: ShowWhenCondition[] = Array.isArray(params.conditions)\n ? params.conditions\n : [params.conditions];\n return [...new Set(conditions.map(c => c.field))];\n}\n\n/**\n * Reports a nested discriminated-union field that will render NOTHING, walking the\n * whole nested tree rather than only its top level.\n *\n * This is the residue of the drop `renderNestedDiscriminatedUnion` fixes. The FORM\n * generator now lays a nested union out, so it reports only a union it could not\n * build (no discriminator, or no options). The DISPLAY generator has no equivalent\n * branch, and the reason is structural rather than unfinished work:\n * `<DiscriminatorSwitch>` picks the live variant with `useWatch`, and a display\n * surface has no form to watch. Picking one there means reading the VALUE — which\n * `resolveDiscriminatedUnionVariant` will do, but the display generator is\n * schema-only at generation time and holds no value. Until that path exists the\n * field renders nothing, and an authored field that renders nothing must say so.\n *\n * Deliberately a development-only `console.warn` rather than a throw:\n *\n * - Throwing would turn a layout limitation into a broken screen, on the render\n * path of every resource that has no authored template.\n * - It fires at GENERATION time (once per `generateDefault*Template()` call, which\n * callers memoize per schema), not per render, so it cannot repeat on keystrokes.\n * - Measured 2026-09-08: neither dogfood application authors a nested\n * discriminated-union field anywhere, so this is silent on the installed base. It\n * reaches only the author who would otherwise be looking at a blank space\n * wondering which layer ate their field, and it names the remedy that works.\n */\nfunction reportUnrenderableNestedObjectFields(\n fields: SchemaFieldInfo[],\n templateKind: AutomatedLayoutTemplateKind,\n parentPathPrefix: string = '',\n): void {\n if (process.env.NODE_ENV === 'production') return;\n\n for (const field of fields) {\n if (field.schemaType !== FieldSchemaType.OBJECT) continue;\n\n const fieldPath = parentPathPrefix ? `${parentPathPrefix}.${field.name}` : field.name;\n\n if (isDiscriminatedUnion(unwrapSchema(field.schema))) {\n // The FORM generator now lays a nested union out (`renderNestedDiscriminatedUnion`),\n // so it only reports one it could not build — a union with no discriminator or\n // no options. The DISPLAY generator has no equivalent, and the reason is not\n // laziness: `<DiscriminatorSwitch>` decides the live variant with `useWatch`,\n // and a display surface has no form to watch. Choosing the variant there means\n // reading the VALUE (`resolveDiscriminatedUnionVariant` takes one), which the\n // schema-only display generator does not have at generation time. Until that\n // path exists, the field renders nothing and must at least say so.\n if (templateKind === 'form' && renderNestedDiscriminatedUnion(field) !== null) continue;\n\n // eslint-disable-next-line no-console -- authoring-time diagnostic; see the JSDoc above for why this is a warn and not a throw\n console.warn(\n `[DefaultLayoutGenerator] Field \"${fieldPath}\" is a nested discriminated union, and the generated `\n + `default ${templateKind} template cannot lay it out, so \"${fieldPath}\" will render nothing. `\n + `Provide an explicit layout.${templateKind === 'form' ? 'edit' : 'display'} template for this resource.`,\n );\n continue;\n }\n\n // Descend, because the render walk descends: an unrenderable union sitting\n // three objects down is exactly as invisible as one at the root, and a reporter\n // that only looked at the top level would be the \"invariant applied at one of\n // its N sites\" defect this repository keeps paying for. `getObjectShape` is the\n // right reader HERE (unlike in the render path) precisely because this walk\n // renders nothing — it only needs to see every authored child.\n const innerShape = getObjectShape(field.schema);\n if (!innerShape) continue;\n\n reportUnrenderableNestedObjectFields(\n Object.entries(innerShape)\n .filter(([, childSchema]) => !isVirtualField(childSchema) && !isBackendOnlyField(childSchema))\n .map(([childName, childSchema]) => createSchemaFieldInfo(childName, childSchema)),\n templateKind,\n fieldPath,\n );\n }\n}\n\n\n// =============================================================================\n// FORM TEMPLATE GENERATION — OPTIONS\n// =============================================================================\n\n/**\n * Options for `generateDefaultFormTemplate()`.\n * All options are optional — omitting everything produces a flat field list.\n *\n * For resources that need sections, wizard steps, or custom layout,\n * provide an explicit `layout.edit` template in the resource config\n * instead of using the auto-generator.\n */\nexport interface FormTemplateGeneratorOptions {\n /** Inheritance config for discriminated unions. Produces `<DiscriminatorSwitch>`. */\n inheritanceConfig?: InheritanceSchemaDefinition;\n /** Label resolver (i18n-aware). Defaults to camelCase fallback formatting. */\n resolveLabel?: LayoutLabelResolver;\n /**\n * Whether to include `<SubmitButton />` in the generated template.\n * Set to `false` when the caller provides its own submit button externally\n * (e.g., ResourceAutomatedForm for operation-specific labels, draft mode).\n * @default true\n */\n includeSubmitButton?: boolean;\n /**\n * Whether to include `<FormErrorSummarySlot />` in the generated template.\n * Set to `false` when the caller handles error summary externally.\n * @default true\n */\n includeErrorSummary?: boolean;\n}\n\n\n// =============================================================================\n// FORM TEMPLATE GENERATION — MAIN\n// =============================================================================\n\n/**\n * Generates a flat default form layout template component from a Zod object schema.\n *\n * Returns a `React.FC` (not ReactNode) so that forms with `.showWhen()` decorators\n * can use `useWatch()` hooks for conditional rendering. The returned component is\n * stable across renders when memoized by the caller.\n *\n * Capabilities:\n * - **Flat list**: one `<FormField>` per key, wrapped in `<FormLayout>`\n * - **showWhen**: produces `useWatch()` + conditional rendering for fields with `.showWhen()` decorators,\n * including nested OBJECT scopes.\n * - **Discriminated unions**: produces `<DiscriminatorSwitch>` with variant field grouping\n * - **Nested objects**: produces `<ObjectScope>` + recursive `<FormField>` for OBJECT fields\n *\n * For resources that need sections, wizard steps, or custom layouts, provide an\n * explicit `layout.edit` template in the resource config.\n *\n * Limitation — ONE, and it is the only authored shape that renders nothing:\n * - **A nested field whose schema is a discriminated union** cannot be laid out.\n * The generator has no discriminator to switch on below the root, so the field\n * falls back to a single `<FormField>` and renders nothing. It is reported at\n * generation time in development (see {@link reportUnrenderableNestedObjectFields});\n * the remedy is an explicit `layout.edit` template.\n *\n * TWO LIMITATIONS PREVIOUSLY DOCUMENTED HERE WERE FALSE, and the correction is kept\n * because the stale text did measurable damage — it was read as a specification and\n * became a filed defect against behaviour that works (`generated-screens#8`).\n * Measured 2026-09-08 by rendering the generated template against the REAL\n * `FormField` (the pre-existing generator test mocks `FormField`, which is exactly\n * why neither claim was falsifiable there — see the pins in\n * `__tests__/default-layout-generator.frontend.utils.test.tsx`):\n *\n * - *\"Array-of-objects fields fall through to `<FormField>` (no `<ArrayField>`\n * generation)\"* — literally true and materially misleading. `<FormField>` is not\n * a fallback here, it is the DISPATCHER: its ARRAY branch mounts\n * `AutomatedArrayField`, a full array editor (add / remove / drag-reorder, CARD\n * or ROW per-item layouts, per-item sub-fields). The skeleton `<ArrayField>` +\n * `<ArrayItemTemplate>` pair is the HAND-AUTHORING shape for an explicit\n * template; not emitting it costs an authored field nothing.\n * - *\"showWhen on nested fields (inside OBJECT schemas) is not captured\"* — false.\n * `FormField` evaluates `showWhen` itself, deriving the sibling scope from its\n * RESOLVED name, so a condition on a field nested in an object resolves against\n * that object and reacts live. The generator's own watch collector descends too.\n * The two evaluations agree because both scope conditions to the parent path.\n *\n * The lesson, since prose in this file ships as the authoring contract: a claim\n * about behaviour that no test can falsify will be believed. Both of these were.\n *\n * @param schema - Root object-like schema for the resource. Plain object roots and\n * discriminated-union roots are both supported.\n * @param options - Generator options (inheritance, labels, submit/error controls)\n * @returns React.FC — a component function (memoize with useMemo/useRef for stable identity)\n */\nexport function generateDefaultFormTemplate(\n schema: z.ZodTypeAny,\n options?: FormTemplateGeneratorOptions,\n): React.FC {\n const inheritanceConfig = options?.inheritanceConfig;\n\n const fields = extractSchemaFieldList(schema, inheritanceConfig?.discriminatorField);\n reportUnrenderableNestedObjectFields(fields, AutomatedLayoutTemplateKind.FORM);\n const showSubmit = options?.includeSubmitButton !== false;\n const showErrorSummary = options?.includeErrorSummary !== false;\n\n if (fields.length === 0) {\n const EmptyTemplate: React.FC = () => <FormLayout autoInjectSubmitButton={showSubmit} />;\n EmptyTemplate.displayName = 'GeneratedFormTemplate(empty)';\n return EmptyTemplate;\n }\n\n const allShowWhenWatchFields = collectAllShowWhenWatchFields(fields);\n const hasShowWhen = allShowWhenWatchFields.length > 0;\n\n const baseFieldNames = new Set(fields.map(f => f.name));\n\n const GeneratedTemplate: React.FC = () => {\n const watchValues = useConditionalWatch(hasShowWhen, allShowWhenWatchFields);\n const formTemplateContext = useOptionalFormTemplateContext();\n const hiddenGeneratedFields = new Set(\n Object.keys(formTemplateContext?.contextFieldValues ?? {})\n );\n for (const hiddenFieldName of formTemplateContext?.hiddenFieldNames ?? []) {\n hiddenGeneratedFields.add(hiddenFieldName);\n }\n\n const renderField = (field: SchemaFieldInfo): ReactNode => {\n const hasGeneratedOverride = Boolean(formTemplateContext?.generatedFieldOverrides?.[field.name]);\n const element = hiddenGeneratedFields.has(field.name) && !hasGeneratedOverride\n ? null\n : renderFieldElement(\n field,\n inheritanceConfig,\n baseFieldNames,\n hiddenGeneratedFields,\n formTemplateContext?.generatedFieldOverrides,\n watchValues,\n allShowWhenWatchFields,\n );\n\n if (!field.showWhenParams || !watchValues) return element;\n\n const isVisible = evaluateShowWhenFromWatch(field.showWhenParams, watchValues, allShowWhenWatchFields);\n return isVisible ? element : null;\n };\n\n return (\n <FormLayout autoInjectSubmitButton={showSubmit}>\n {showErrorSummary && <FormErrorSummarySlot />}\n {fields.map(renderField)}\n {showSubmit && <SubmitButton />}\n </FormLayout>\n );\n };\n\n GeneratedTemplate.displayName = 'GeneratedFormTemplate';\n return GeneratedTemplate;\n}\n\n\n// =============================================================================\n// INTERNAL — CONDITIONAL WATCH HOOK\n// =============================================================================\n\n/**\n * Conditionally calls `useWatch` — only when there are showWhen fields to track.\n * React hooks must be called unconditionally, so we always call useWatch but with\n * an empty array when not needed (no-op).\n */\nfunction useConditionalWatch(hasShowWhen: boolean, watchFields: string[]): unknown[] | undefined {\n const values = useWatch({ name: hasShowWhen ? watchFields : [] });\n return hasShowWhen ? (Array.isArray(values) ? values : [values]) : undefined;\n}\n\n\n// =============================================================================\n// INTERNAL — FIELD RENDERING\n// =============================================================================\n\n/**\n * Renders a single field element, handling OBJECT nesting and discriminated unions.\n */\nfunction renderFieldElement(\n field: SchemaFieldInfo,\n inheritanceConfig: InheritanceSchemaDefinition | undefined,\n baseFieldNames?: Set<string>,\n hiddenContextFields?: Set<string>,\n generatedFieldOverrides?: Record<string, ReactNode>,\n watchValues?: unknown[],\n allShowWhenWatchFields?: string[],\n): ReactNode {\n if (generatedFieldOverrides?.[field.name]) {\n return <FormField key={field.name} name={field.name} />;\n }\n\n if (field.isDiscriminator && inheritanceConfig && baseFieldNames && hiddenContextFields) {\n return renderDiscriminatorAndVariants(\n field,\n inheritanceConfig,\n baseFieldNames,\n hiddenContextFields,\n generatedFieldOverrides,\n );\n }\n\n if (field.schemaType === FieldSchemaType.OBJECT) {\n return renderObjectScope(field, watchValues, allShowWhenWatchFields);\n }\n\n return (\n <FormField key={field.name} name={field.name} />\n );\n}\n\n/**\n * Renders a discriminator field + DiscriminatorSwitch for variant-specific fields.\n */\nfunction renderDiscriminatorAndVariants(\n discriminatorField: SchemaFieldInfo,\n config: InheritanceSchemaDefinition,\n baseFieldNames: Set<string>,\n hiddenContextFields: Set<string>,\n generatedFieldOverrides?: Record<string, ReactNode>,\n): ReactNode {\n const variants: Record<string, ReactNode> = {};\n\n if (config.inheritedSchemas) {\n for (const variant of config.inheritedSchemas) {\n const variantShape = getObjectShape(variant.schema);\n const variantKeys = getObjectKeys(variant.schema);\n\n if (variantShape && variantKeys.length > 0) {\n const variantOnlyKeys = variantKeys.filter(k =>\n !isVirtualField(variantShape[k]) &&\n !isBackendOnlyField(variantShape[k]) &&\n !baseFieldNames.has(k) &&\n (!hiddenContextFields.has(k) || Boolean(generatedFieldOverrides?.[k])),\n );\n\n if (variantOnlyKeys.length > 0) {\n variants[variant.discriminatorFieldValue] = (\n <>\n {variantOnlyKeys.map((key) => (\n <FormField key={key} name={key} />\n ))}\n </>\n );\n }\n }\n }\n }\n\n const hasVariants = Object.keys(variants).length > 0;\n\n return (\n <React.Fragment key={discriminatorField.name}>\n <FormField name={discriminatorField.name} />\n {hasVariants && (\n <DiscriminatorSwitch\n field={config.discriminatorField}\n variants={variants}\n />\n )}\n </React.Fragment>\n );\n}\n\n/**\n * Renders a nested OBJECT field using ObjectScope + recursive FormField elements.\n */\nfunction renderObjectScope(\n field: SchemaFieldInfo,\n watchValues?: unknown[],\n allShowWhenWatchFields?: string[],\n parentPathPrefix: string = '',\n): ReactNode {\n if (field.showWhenParams && watchValues && allShowWhenWatchFields) {\n const scopedShowWhenParams = scopeShowWhenParams(field.showWhenParams, parentPathPrefix);\n const isVisible = evaluateShowWhenFromWatch(scopedShowWhenParams, watchValues, allShowWhenWatchFields);\n if (!isVisible) {\n return null;\n }\n }\n\n // BEFORE the shape read, because a discriminated union answers that read with an\n // empty shape and would otherwise fall through to a `<FormField>` that renders\n // nothing at all. This is the generator's one genuine silent drop; see\n // `renderNestedDiscriminatedUnion`.\n const unionScope = renderNestedDiscriminatedUnion(field);\n if (unionScope) {\n return unionScope;\n }\n\n const innerShape = readNestedObjectShape(field.schema);\n\n const innerKeys = Object.keys(innerShape);\n const renderableKeys = innerKeys.filter(k => {\n const s = innerShape[k];\n return !isVirtualField(s) && !isBackendOnlyField(s);\n });\n\n // Empty for a WRAPPED object (`.optional()` / `.nullable()` / `.default()`) as\n // well as for a genuinely field-less one — `readNestedObjectShape` documents why\n // that conflation is left in place, and why the single `<FormField>` below is a\n // working renderer for it rather than a dead end.\n if (renderableKeys.length === 0) {\n return <FormField key={field.name} name={field.name} />;\n }\n\n const currentFieldPath = parentPathPrefix ? `${parentPathPrefix}.${field.name}` : field.name;\n\n return (\n <ObjectScope key={field.name} name={field.name}>\n {renderableKeys.map(key => {\n const childSchema = innerShape[key];\n const childType = getSchemaType(childSchema);\n\n if (childType === FieldSchemaType.OBJECT) {\n const nestedField = createSchemaFieldInfo(key, childSchema);\n return renderObjectScope(\n nestedField,\n watchValues,\n allShowWhenWatchFields,\n currentFieldPath,\n );\n }\n\n return <FormField key={key} name={key} />;\n })}\n </ObjectScope>\n );\n}\n\n\n// =============================================================================\n// INTERNAL — SHOW WHEN EVALUATION\n// =============================================================================\n\nfunction collectAllShowWhenWatchFields(fields: SchemaFieldInfo[]): string[] {\n const allFields = new Set<string>();\n for (const field of fields) {\n collectShowWhenWatchFieldsForField(field, allFields);\n }\n return [...allFields];\n}\n\nfunction collectShowWhenWatchFieldsForField(\n field: SchemaFieldInfo,\n collector: Set<string>,\n parentPathPrefix: string = '',\n): void {\n if (field.showWhenParams) {\n const scopedShowWhenParams = scopeShowWhenParams(field.showWhenParams, parentPathPrefix);\n for (const fieldName of dedupeShowWhenWatchFields(scopedShowWhenParams)) {\n collector.add(fieldName);\n }\n }\n\n if (field.schemaType !== FieldSchemaType.OBJECT) {\n return;\n }\n\n const innerShape = readNestedObjectShape(field.schema);\n\n const currentFieldPath = parentPathPrefix ? `${parentPathPrefix}.${field.name}` : field.name;\n for (const [childName, childSchema] of Object.entries(innerShape)) {\n if (isVirtualField(childSchema) || isBackendOnlyField(childSchema)) {\n continue;\n }\n\n collectShowWhenWatchFieldsForField(\n createSchemaFieldInfo(childName, childSchema as z.ZodTypeAny),\n collector,\n currentFieldPath,\n );\n }\n}\n\nfunction scopeShowWhenParams(\n params: ShowWhenParams,\n parentPathPrefix: string,\n): ShowWhenParams {\n if (!parentPathPrefix) {\n return params;\n }\n\n const conditions = Array.isArray(params.conditions)\n ? params.conditions\n : [params.conditions];\n\n return {\n ...params,\n conditions: conditions.map((condition) => ({\n ...condition,\n field: condition.field.includes('.') || condition.field.includes('[')\n ? condition.field\n : `${parentPathPrefix}.${condition.field}`,\n })),\n };\n}\n\n/**\n * Evaluates showWhen conditions using values from the useWatch array.\n * Maps field names to their positions in the watched fields array.\n */\nfunction evaluateShowWhenFromWatch(\n params: ShowWhenParams,\n watchValues: unknown[],\n allWatchFields: string[],\n): boolean {\n const formValues: Record<string, unknown> = {};\n for (let i = 0; i < allWatchFields.length; i++) {\n formValues[allWatchFields[i]] = watchValues[i];\n }\n return AutomatedLayoutFrontendUtils.evaluateShowWhen(params, formValues);\n}\n\n\n// =============================================================================\n// DISPLAY TEMPLATE GENERATION\n// =============================================================================\n\n/**\n * Generates a flat default display layout template (React.FC) from a Zod object schema.\n *\n * Schema-only: field values, labels, and descriptions are resolved from\n * DisplayTemplateContext at render time via name-only `<DisplayField name=\"x\" />`.\n *\n * Supports nested objects (`<ObjectScope>`) and per-field showWhen\n * (DD-10 — not evaluated at generator time).\n *\n * For resources that need sections or custom display layouts, provide an\n * explicit `layout.display` template in the resource config.\n *\n * @param schema - The root Zod object schema for the resource\n * @returns React.FC component using DisplayLayout + name-only DisplayField components\n */\nexport function generateDefaultDisplayTemplate(\n schema: z.ZodTypeAny,\n): React.FC {\n const fields = extractSchemaFieldList(schema);\n // Same nested-union limitation as the form generator, reported at the same\n // moment — the display side falls back to a `<DisplayField>` that resolves no\n // child shape and renders nothing, so the silence is identical.\n reportUnrenderableNestedObjectFields(fields, AutomatedLayoutTemplateKind.DISPLAY);\n\n if (fields.length === 0) {\n const EmptyDisplayTemplate: React.FC = () => <DisplayLayout />;\n return EmptyDisplayTemplate;\n }\n\n const renderDisplayField = (field: SchemaFieldInfo): ReactNode => {\n if (field.schemaType === FieldSchemaType.OBJECT) {\n return renderDisplayObjectScope(field);\n }\n return <DisplayField key={field.name} name={field.name} />;\n };\n\n const DefaultDisplayTemplate: React.FC = () => (\n <DisplayLayout>\n {fields.map(renderDisplayField)}\n </DisplayLayout>\n );\n return DefaultDisplayTemplate;\n}\n\n/**\n * Renders a nested OBJECT field for display using ObjectScope + recursive DisplayField.\n */\nfunction renderDisplayObjectScope(field: SchemaFieldInfo): ReactNode {\n const innerShape = readNestedObjectShape(field.schema);\n\n const innerKeys = Object.keys(innerShape);\n const renderableKeys = innerKeys.filter(k => {\n const s = innerShape[k];\n return !isVirtualField(s) && !isBackendOnlyField(s);\n });\n\n if (renderableKeys.length === 0) {\n return <DisplayField key={field.name} name={field.name} />;\n }\n\n return (\n <ObjectScope key={field.name} name={field.name}>\n {renderableKeys.map(key => {\n const childSchema = innerShape[key];\n const childType = getSchemaType(childSchema);\n\n if (childType === FieldSchemaType.OBJECT) {\n const nestedField: SchemaFieldInfo = {\n name: key,\n schema: childSchema,\n schemaType: childType,\n };\n return renderDisplayObjectScope(nestedField);\n }\n\n return <DisplayField key={key} name={key} />;\n })}\n </ObjectScope>\n );\n}\n\n// =============================================================================\n// SUMMARY TEMPLATE GENERATION\n// =============================================================================\n\n/**\n * Generates a default summary layout template (React.FC) from a Zod object schema.\n *\n * Schema-only: values are resolved from DisplayTemplateContext at render time.\n * Each field uses `<DisplayField name=\"x\" />` — rendered with compact chrome\n * from the `defaultChromeMode.summary` set on the enclosing `ResourceSummaryDisplayer`.\n *\n * Includes only fields decorated with `isSummaryField()`. If no summary fields\n * are defined, renders all non-backend-only fields with summary variant.\n *\n * @param schema - The root Zod object schema for the resource\n * @returns React.FC component using SummaryLayout + name-only DisplayField components\n */\nexport function generateDefaultSummaryTemplate(\n schema: z.ZodTypeAny,\n): React.FC {\n // Union-aware shape (matches the display/form generators): `getObjectShape`\n // returns null for a discriminated union, so a polymorphic resource with no\n // authored `layout.summary` would otherwise fall into the empty branch and\n // render a blank FK preview / ReadSummary body. `commonOnly: true` yields the\n // fields shared across variants.\n const shape = AutomatedLayoutFrontendUtils.getObjectLikeFieldShape(schema, { commonOnly: true });\n const keys = shape ? Object.keys(shape) : [];\n\n // The generated default is BODY-ONLY: `titlePlacement={TEMPLATE_OWNED}` so\n // `SummaryLayout` renders no auto title. Resources WITHOUT an authored\n // `layout.summary` keep their title host-owned (list card / FK popover render\n // the primary label themselves) — routing the default through an AUTO title\n // would restyle every no-template list in every app. Only AUTHORED templates\n // opt the title into the flow.\n if (!shape || keys.length === 0) {\n const EmptySummaryTemplate: React.FC = () => (\n <SummaryLayout titlePlacement={SummaryTitlePlacement.TEMPLATE_OWNED} />\n );\n return EmptySummaryTemplate;\n }\n\n // Summaries are `isSummaryField`-scoped (a DIFFERENT axis from the display\n // view's all-non-hidden selection), so — unlike the display generator — we do\n // NOT exclude virtual fields: a virtual field can legitimately be an authored\n // summary field, and `ResourceLayoutUtils.detectSummaryFields` (the sibling\n // path feeding table columns + card bodies) includes them too. We keep them in\n // sync; only backend-only fields (no client value) are dropped.\n const summaryKeys = keys.filter(key => {\n const fieldSchema = shape[key];\n return !isBackendOnlyField(fieldSchema) && isSummaryField(fieldSchema);\n });\n\n const targetKeys = summaryKeys.length > 0\n ? summaryKeys\n : keys.filter(key => !isBackendOnlyField(shape[key]));\n\n const DefaultSummaryTemplate: React.FC = () => (\n <SummaryLayout titlePlacement={SummaryTitlePlacement.TEMPLATE_OWNED}>\n {targetKeys.map(key => (\n <DisplayField key={key} name={key} />\n ))}\n </SummaryLayout>\n );\n return DefaultSummaryTemplate;\n}\n"]}
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
* widgets (`SubscriptionStatus`, `PricingTable`, …) in their own views.
|
|
21
21
|
*/
|
|
22
22
|
import { LauncherItemTargetKind, } from '../../core/config/launcher-items.frontend.schemas.js';
|
|
23
|
-
import { EngineSettingsDestinationRef } from '
|
|
23
|
+
import { EngineSettingsDestinationRef } from '@wildo-ai/saas-models';
|
|
24
24
|
/**
|
|
25
25
|
* Settings Hub section ref for the billing home (`/settings/billing`).
|
|
26
26
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"billing-launcher.js","sourceRoot":"","sources":["../../../../src/core/billing/billing-launcher.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,EACL,sBAAsB,GAGvB,MAAM,iEAAiE,CAAC;AACzE,OAAO,EAAE,4BAA4B,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"billing-launcher.js","sourceRoot":"","sources":["../../../../src/core/billing/billing-launcher.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,EACL,sBAAsB,GAGvB,MAAM,iEAAiE,CAAC;AACzE,OAAO,EAAE,4BAA4B,EAAE,MAAM,uBAAuB,CAAC;AAErE;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,MAAM,4BAA4B,GAAW,4BAA4B,CAAC,OAAO,CAAC;AAEzF,MAAM,4BAA4B,GAAsC;IACtE,oBAAoB,EAAE,CAAC,gBAAgB,CAAC;CACzC,CAAC;AAEF,0EAA0E;AAC1E,MAAM,CAAC,MAAM,yBAAyB,GAAuB;IAC3D,IAAI,EAAE,sBAAsB,CAAC,gBAAgB;IAC7C,UAAU,EAAE,4BAA4B;IACxC,QAAQ,EAAE,SAAS;IACnB,cAAc,EAAE,CAAC,SAAS,EAAE,cAAc,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,CAAC;IACpF,mBAAmB,EAAE,4BAA4B;CAClD,CAAC","sourcesContent":["/**\n * Declarative billing launcher entry.\n *\n * THE billing home is the Settings Hub \"billing\" destination (a bespoke\n * `ENGINE_PANEL` — see `engine-settings-destinations.ts` /\n * `AppPage_BillingSettings`). The only launcher the framework ships for billing\n * is a command-menu entry that opens the hub at that section.\n *\n * Note the engine ships the DESTINATION, never its placement: whether billing\n * appears in the rail at all, and where, is the application's\n * `settingsHub.placements`. That is why the command entry below is verified\n * against what the application placed rather than assumed reachable.\n *\n * HISTORY: billing used to ALSO ship an app-level full-custom view\n * (`/custom/billing`, componentRef `billing-overview`) plus a sidebar row\n * pointing at it — a second, app-registered billing home beside the settings\n * one. That placement was retired (2026-08-18): one billing surface, inside\n * settings, engine-owned. Do not reintroduce a `FullCustomViewDefinition` here;\n * apps that want extra billing surfaces compose the self-hydrating billing\n * widgets (`SubscriptionStatus`, `PricingTable`, …) in their own views.\n */\n\nimport {\n LauncherItemTargetKind,\n type LauncherRuntimeAvailabilityConfig,\n type CommandMenuCommand,\n} from '~wildo-frontend-lib/core/config/launcher-items.frontend.schemas';\nimport { EngineSettingsDestinationRef } from '@wildo-ai/saas-models';\n\n/**\n * Settings Hub section ref for the billing home (`/settings/billing`).\n *\n * Derived from the destination catalog rather than written as a literal. It used\n * to be `= 'billing'`, an engine surface asserting a ref with nothing tying it to\n * the catalog entry it names — and the failure is silent in both directions:\n * `resolveItemRef` falls back to the hub's DEFAULT section for an unknown\n * `sectionRef`, so a command labelled \"Billing\" would open Profile rather than\n * error.\n *\n * The other half of that hole is that an application may simply not PLACE the\n * billing destination, which no static reference can know. That is checked at\n * DEV startup — see `SETTINGS_SECTION_NOT_PLACED` in `verify-launcher-content.ts`.\n */\nexport const BILLING_SETTINGS_SECTION_REF: string = EngineSettingsDestinationRef.BILLING;\n\nconst BILLING_RUNTIME_AVAILABILITY: LauncherRuntimeAvailabilityConfig = {\n requiredCapabilities: ['billingEnabled'],\n};\n\n/** Command menu entry — opens the Settings Hub at the billing section. */\nexport const BILLING_COMMAND_MENU_ITEM: CommandMenuCommand = {\n kind: LauncherItemTargetKind.SETTINGS_SECTION,\n sectionRef: BILLING_SETTINGS_SECTION_REF,\n category: 'billing',\n searchKeywords: ['billing', 'subscription', 'plan', 'payment', 'invoice', 'upgrade'],\n runtimeAvailability: BILLING_RUNTIME_AVAILABILITY,\n};\n"]}
|