@open-mercato/ui 0.6.7 → 0.6.8-develop.6874.1.982d6097d8
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/.turbo/turbo-build.log +1 -1
- package/AGENTS.md +4 -2
- package/agentic/standalone-guide.md +1 -1
- package/build.mjs +2 -54
- package/dist/ai/AiChat.js +26 -7
- package/dist/ai/AiChat.js.map +2 -2
- package/dist/ai/LoopDisabledBanner.js +1 -1
- package/dist/ai/LoopDisabledBanner.js.map +2 -2
- package/dist/ai/parts/ConfirmationCard.js +4 -4
- package/dist/ai/parts/ConfirmationCard.js.map +2 -2
- package/dist/ai/parts/FieldDiffCard.js +2 -2
- package/dist/ai/parts/FieldDiffCard.js.map +2 -2
- package/dist/ai/parts/MutationResultCard.js +3 -3
- package/dist/ai/parts/MutationResultCard.js.map +2 -2
- package/dist/ai/ui-parts/pending-phase3-placeholder.js +1 -1
- package/dist/ai/ui-parts/pending-phase3-placeholder.js.map +2 -2
- package/dist/backend/AppShell.js +43 -4
- package/dist/backend/AppShell.js.map +2 -2
- package/dist/backend/AuthSessionGuard.js +14 -0
- package/dist/backend/AuthSessionGuard.js.map +2 -2
- package/dist/backend/BackendChromeProvider.js +6 -1
- package/dist/backend/BackendChromeProvider.js.map +2 -2
- package/dist/backend/CrudForm.js +6 -4
- package/dist/backend/CrudForm.js.map +2 -2
- package/dist/backend/DataTable.js +20 -18
- package/dist/backend/DataTable.js.map +2 -2
- package/dist/backend/JsonBuilder.js +3 -3
- package/dist/backend/JsonBuilder.js.map +2 -2
- package/dist/backend/NextStepCallout.js +4 -4
- package/dist/backend/NextStepCallout.js.map +1 -1
- package/dist/backend/PerspectiveSidebar.js +1 -1
- package/dist/backend/PerspectiveSidebar.js.map +2 -2
- package/dist/backend/ProfileDropdown.js +2 -1
- package/dist/backend/ProfileDropdown.js.map +2 -2
- package/dist/backend/RowActions.js +2 -2
- package/dist/backend/RowActions.js.map +2 -2
- package/dist/backend/confirm-dialog/ConfirmDialog.js +13 -1
- package/dist/backend/confirm-dialog/ConfirmDialog.js.map +2 -2
- package/dist/backend/crud/useGroupOrder.js +14 -21
- package/dist/backend/crud/useGroupOrder.js.map +2 -2
- package/dist/backend/custom-fields/FieldDefinitionsManager.js +1 -1
- package/dist/backend/custom-fields/FieldDefinitionsManager.js.map +2 -2
- package/dist/backend/dashboard/DashboardScreen.js +3 -3
- package/dist/backend/dashboard/DashboardScreen.js.map +2 -2
- package/dist/backend/detail/AddressTiles.js +4 -5
- package/dist/backend/detail/AddressTiles.js.map +2 -2
- package/dist/backend/detail/AttachmentDeleteDialog.js +1 -1
- package/dist/backend/detail/AttachmentDeleteDialog.js.map +2 -2
- package/dist/backend/detail/AttachmentMetadataDialog.js.map +1 -1
- package/dist/backend/detail/AttachmentsSection.js +1 -1
- package/dist/backend/detail/AttachmentsSection.js.map +2 -2
- package/dist/backend/detail/NotesSection.js +1 -1
- package/dist/backend/detail/NotesSection.js.map +2 -2
- package/dist/backend/detail/TagsSection.js +1 -1
- package/dist/backend/detail/TagsSection.js.map +2 -2
- package/dist/backend/filters/AdvancedFilterPanel.js +1 -1
- package/dist/backend/filters/AdvancedFilterPanel.js.map +2 -2
- package/dist/backend/forms/FormHeader.js +1 -2
- package/dist/backend/forms/FormHeader.js.map +2 -2
- package/dist/backend/icons/lucideRegistry.generated.js +1 -25
- package/dist/backend/icons/lucideRegistry.generated.js.map +2 -2
- package/dist/backend/icons/lucideRegistry.js +3 -3
- package/dist/backend/icons/lucideRegistry.js.map +2 -2
- package/dist/backend/icons/lucideRegistryRuntime.js +28 -0
- package/dist/backend/icons/lucideRegistryRuntime.js.map +7 -0
- package/dist/backend/injection/spotIds.js +23 -18
- package/dist/backend/injection/spotIds.js.map +2 -2
- package/dist/backend/inputs/ComboboxInput.js.map +1 -1
- package/dist/backend/messages/EmailThreadsPanel.js +1 -1
- package/dist/backend/messages/EmailThreadsPanel.js.map +2 -2
- package/dist/backend/perspectiveState.js +34 -0
- package/dist/backend/perspectiveState.js.map +7 -0
- package/dist/backend/schedule/ScheduleAgenda.js +3 -3
- package/dist/backend/schedule/ScheduleAgenda.js.map +1 -1
- package/dist/backend/schedule/ScheduleGrid.js +3 -3
- package/dist/backend/schedule/ScheduleGrid.js.map +1 -1
- package/dist/backend/schedule/ScheduleToolbar.js +87 -70
- package/dist/backend/schedule/ScheduleToolbar.js.map +2 -2
- package/dist/backend/sidebar/SidebarCustomizationEditor.js +30 -2
- package/dist/backend/sidebar/SidebarCustomizationEditor.js.map +2 -2
- package/dist/backend/sidebar/customization-helpers.js +30 -0
- package/dist/backend/sidebar/customization-helpers.js.map +2 -2
- package/dist/backend/utils/apiCall.js +21 -1
- package/dist/backend/utils/apiCall.js.map +2 -2
- package/dist/backend/utils/customFieldDefs.js.map +2 -2
- package/dist/backend/utils/customFieldForms.js +10 -9
- package/dist/backend/utils/customFieldForms.js.map +2 -2
- package/dist/backend/utils/fetchAllPages.js +57 -0
- package/dist/backend/utils/fetchAllPages.js.map +7 -0
- package/dist/backend/utils/nav.js +5 -2
- package/dist/backend/utils/nav.js.map +2 -2
- package/dist/backend/version-history/VersionHistoryPanel.js +1 -1
- package/dist/backend/version-history/VersionHistoryPanel.js.map +2 -2
- package/dist/frontend/LanguageSwitcher.js +2 -1
- package/dist/frontend/LanguageSwitcher.js.map +2 -2
- package/dist/portal/PortalContext.js +1 -1
- package/dist/portal/PortalContext.js.map +2 -2
- package/dist/portal/hooks/portalBridgeStatus.js +25 -0
- package/dist/portal/hooks/portalBridgeStatus.js.map +7 -0
- package/dist/portal/hooks/usePortalEventBridge.js +6 -0
- package/dist/portal/hooks/usePortalEventBridge.js.map +2 -2
- package/dist/portal/hooks/usePortalNotifications.js +42 -4
- package/dist/portal/hooks/usePortalNotifications.js.map +2 -2
- package/dist/portal/utils/nav.js +2 -3
- package/dist/portal/utils/nav.js.map +2 -2
- package/dist/primitives/ErrorNotice.js +1 -1
- package/dist/primitives/ErrorNotice.js.map +2 -2
- package/dist/primitives/Notice.js +1 -1
- package/dist/primitives/Notice.js.map +1 -1
- package/dist/primitives/button.js +9 -4
- package/dist/primitives/button.js.map +2 -2
- package/dist/theme/ThemeProvider.js +1 -1
- package/dist/theme/ThemeProvider.js.map +2 -2
- package/dist/theme/index.js +3 -0
- package/dist/theme/index.js.map +2 -2
- package/dist/theme/theme-init-script.js +17 -0
- package/dist/theme/theme-init-script.js.map +7 -0
- package/figma/alert.figma.tsx +35 -0
- package/figma/badge.figma.tsx +33 -0
- package/figma/button.figma.tsx +33 -0
- package/figma/checkbox.figma.tsx +28 -0
- package/figma/drawer.figma.tsx +40 -0
- package/figma/input-variants.figma.tsx +58 -0
- package/figma/radio.figma.tsx +16 -0
- package/figma/select.figma.tsx +24 -0
- package/figma/status-badge.figma.tsx +24 -0
- package/figma/switch.figma.tsx +28 -0
- package/figma/tabs.figma.tsx +22 -0
- package/figma/tag.figma.tsx +27 -0
- package/figma.config.json +6 -0
- package/jest.config.cjs +2 -1
- package/package.json +21 -18
- package/scripts/lucideRegistrySource.cjs +133 -0
- package/src/ai/AiChat.tsx +36 -7
- package/src/ai/LoopDisabledBanner.tsx +1 -1
- package/src/ai/__tests__/AiChat.test.tsx +31 -0
- package/src/ai/parts/ConfirmationCard.tsx +4 -4
- package/src/ai/parts/FieldDiffCard.tsx +2 -2
- package/src/ai/parts/MutationResultCard.tsx +3 -3
- package/src/ai/ui-parts/pending-phase3-placeholder.tsx +2 -2
- package/src/backend/AppShell.tsx +55 -4
- package/src/backend/AuthSessionGuard.tsx +29 -0
- package/src/backend/BackendChromeProvider.tsx +19 -1
- package/src/backend/CrudForm.tsx +18 -4
- package/src/backend/DataTable.tsx +36 -19
- package/src/backend/JsonBuilder.tsx +3 -3
- package/src/backend/NextStepCallout.tsx +4 -4
- package/src/backend/PerspectiveSidebar.tsx +1 -1
- package/src/backend/ProfileDropdown.tsx +1 -0
- package/src/backend/RowActions.tsx +2 -2
- package/src/backend/__tests__/AppShell.test.tsx +65 -7
- package/src/backend/__tests__/AuthSessionGuard.test.tsx +52 -0
- package/src/backend/__tests__/BackendChromeProvider.test.tsx +98 -2
- package/src/backend/__tests__/CrudForm.fieldsetBinding.test.tsx +158 -0
- package/src/backend/__tests__/CrudForm.groupInjectionColumn.test.tsx +98 -0
- package/src/backend/__tests__/DataTable.metaHiddenLateColumns.test.tsx +105 -0
- package/src/backend/__tests__/DataTable.perspectiveStorage.test.ts +62 -1
- package/src/backend/__tests__/nav-utils.test.ts +139 -0
- package/src/backend/confirm-dialog/ConfirmDialog.tsx +16 -1
- package/src/backend/confirm-dialog/__tests__/ConfirmDialog.test.tsx +68 -1
- package/src/backend/crud/__tests__/useGroupOrder.test.ts +39 -1
- package/src/backend/crud/useGroupOrder.ts +30 -25
- package/src/backend/custom-fields/FieldDefinitionsManager.tsx +1 -1
- package/src/backend/dashboard/DashboardScreen.tsx +3 -3
- package/src/backend/detail/AddressTiles.tsx +3 -6
- package/src/backend/detail/AttachmentDeleteDialog.tsx +1 -1
- package/src/backend/detail/AttachmentMetadataDialog.tsx +1 -1
- package/src/backend/detail/AttachmentsSection.tsx +1 -1
- package/src/backend/detail/NotesSection.tsx +1 -1
- package/src/backend/detail/TagsSection.tsx +1 -1
- package/src/backend/detail/__tests__/AttachmentAssignmentsEditor.test.tsx +21 -0
- package/src/backend/filters/AdvancedFilterPanel.tsx +1 -1
- package/src/backend/forms/FormHeader.tsx +1 -2
- package/src/backend/icons/__tests__/lucideRegistryGenerator.test.ts +177 -0
- package/src/backend/icons/lucideRegistry.generated.tsx +3 -37
- package/src/backend/icons/lucideRegistry.ts +2 -2
- package/src/backend/icons/lucideRegistryRuntime.tsx +36 -0
- package/src/backend/injection/__tests__/spotIds.extension-points.test.ts +38 -0
- package/src/backend/injection/spotIds.ts +23 -18
- package/src/backend/inputs/ComboboxInput.tsx +1 -1
- package/src/backend/messages/EmailThreadsPanel.tsx +1 -1
- package/src/backend/perspectiveState.ts +44 -0
- package/src/backend/schedule/ScheduleAgenda.tsx +3 -3
- package/src/backend/schedule/ScheduleGrid.tsx +3 -3
- package/src/backend/schedule/ScheduleToolbar.tsx +89 -68
- package/src/backend/sidebar/SidebarCustomizationEditor.tsx +42 -3
- package/src/backend/sidebar/__tests__/group-visibility.test.ts +131 -0
- package/src/backend/sidebar/customization-helpers.ts +47 -0
- package/src/backend/utils/__tests__/apiCall.test.ts +61 -0
- package/src/backend/utils/__tests__/customFieldForms.optionsPaging.test.ts +95 -0
- package/src/backend/utils/__tests__/fetchAllPages.test.ts +103 -0
- package/src/backend/utils/apiCall.ts +29 -1
- package/src/backend/utils/customFieldDefs.ts +1 -0
- package/src/backend/utils/customFieldForms.ts +15 -11
- package/src/backend/utils/fetchAllPages.ts +93 -0
- package/src/backend/utils/nav.ts +22 -2
- package/src/backend/version-history/VersionHistoryPanel.tsx +1 -1
- package/src/frontend/LanguageSwitcher.tsx +1 -0
- package/src/portal/PortalContext.tsx +1 -1
- package/src/portal/hooks/__tests__/usePortalEventBridge.test.tsx +66 -0
- package/src/portal/hooks/__tests__/usePortalNotifications.test.tsx +155 -0
- package/src/portal/hooks/portalBridgeStatus.ts +29 -0
- package/src/portal/hooks/usePortalEventBridge.ts +6 -0
- package/src/portal/hooks/usePortalNotifications.ts +55 -12
- package/src/portal/utils/__tests__/nav.test.ts +2 -2
- package/src/portal/utils/nav.ts +3 -4
- package/src/primitives/ErrorNotice.tsx +1 -1
- package/src/primitives/Notice.tsx +5 -5
- package/src/primitives/__tests__/button.test.tsx +70 -0
- package/src/primitives/button.tsx +10 -4
- package/src/theme/ThemeProvider.tsx +1 -2
- package/src/theme/__tests__/theme-init-script.test.ts +70 -0
- package/src/theme/index.ts +1 -0
- package/src/theme/theme-init-script.ts +23 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/backend/AuthSessionGuard.tsx"],
|
|
4
|
-
"sourcesContent": ["'use client'\nimport * as React from 'react'\nimport { apiCall } from './utils/apiCall'\n\nexport const AUTH_IDENTITY_STORAGE_KEY = 'om:auth:identity'\nexport const AUTH_IDENTITY_BROADCAST_CHANNEL = 'om-auth-identity'\n\ntype FeatureCheckResponse = {\n ok: boolean\n granted?: string[]\n userId?: string\n}\n\nexport type AuthSessionGuardProps = {\n serverUserId: string | null\n}\n\nexport const __reload = {\n fn: (): void => {\n if (typeof window !== 'undefined') window.location.reload()\n },\n}\n\nexport function AuthSessionGuard({ serverUserId }: AuthSessionGuardProps) {\n React.useEffect(() => {\n if (typeof window === 'undefined') return\n let cancelled = false\n let reloadScheduled = false\n\n const triggerReload = () => {\n if (reloadScheduled) return\n reloadScheduled = true\n __reload.fn()\n }\n\n const checkIdentity = async () => {\n if (cancelled || reloadScheduled) return\n try {\n const res = await apiCall<FeatureCheckResponse>('/api/auth/feature-check', {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ features: [] }),\n cache: 'no-store',\n })\n if (cancelled || reloadScheduled) return\n if (res.status === 401) {\n if (serverUserId) triggerReload()\n return\n }\n if (!res.ok) return\n const currentUserId = typeof res.result?.userId === 'string' ? res.result.userId : null\n if (!currentUserId) return\n if (currentUserId !== serverUserId) triggerReload()\n } catch {\n // network errors are ignored \u2014 next focus/storage event retries\n }\n }\n\n const onVisibilityOrFocus = () => {\n if (typeof document !== 'undefined' && document.visibilityState === 'hidden') return\n void checkIdentity()\n }\n\n const onStorage = (event: StorageEvent) => {\n if (event.key !== AUTH_IDENTITY_STORAGE_KEY) return\n void checkIdentity()\n }\n\n let broadcastChannel: BroadcastChannel | null = null\n if (typeof BroadcastChannel !== 'undefined') {\n try {\n broadcastChannel = new BroadcastChannel(AUTH_IDENTITY_BROADCAST_CHANNEL)\n broadcastChannel.onmessage = () => { void checkIdentity() }\n } catch {\n broadcastChannel = null\n }\n }\n\n window.addEventListener('focus', onVisibilityOrFocus)\n document.addEventListener('visibilitychange', onVisibilityOrFocus)\n window.addEventListener('storage', onStorage)\n\n return () => {\n cancelled = true\n window.removeEventListener('focus', onVisibilityOrFocus)\n document.removeEventListener('visibilitychange', onVisibilityOrFocus)\n window.removeEventListener('storage', onStorage)\n if (broadcastChannel) {\n broadcastChannel.onmessage = null\n broadcastChannel.close()\n }\n }\n }, [serverUserId])\n\n return null\n}\n\nexport function notifyAuthIdentityChange(): void {\n if (typeof window === 'undefined') return\n try {\n if (typeof BroadcastChannel !== 'undefined') {\n const channel = new BroadcastChannel(AUTH_IDENTITY_BROADCAST_CHANNEL)\n channel.postMessage('changed')\n channel.close()\n }\n } catch {\n // ignore \u2014 fall back to storage event below\n }\n try {\n window.localStorage.setItem(AUTH_IDENTITY_STORAGE_KEY, String(Date.now()))\n } catch {\n // private mode / quota errors are non-fatal\n }\n}\n"],
|
|
5
|
-
"mappings": ";AACA,YAAY,WAAW;AACvB,SAAS,eAAe;
|
|
4
|
+
"sourcesContent": ["'use client'\nimport * as React from 'react'\nimport { apiCall } from './utils/apiCall'\nimport { clearAllPerspectiveState } from './perspectiveState'\n\nexport const AUTH_IDENTITY_STORAGE_KEY = 'om:auth:identity'\nexport const AUTH_IDENTITY_BROADCAST_CHANNEL = 'om-auth-identity'\nexport const AUTH_IDENTITY_USER_STORAGE_KEY = 'om:auth:identity:user'\n\n/**\n * Purge browser-local DataTable perspective state whenever the backend renders for a\n * different user than the one it last rendered for (#4185).\n *\n * The login form also purges on submit, but that only fires when its client handler\n * runs: a form submitted before hydration, an SSO/magic-link return, or any other\n * entry point into the backend bypasses it entirely and the previous account's unsaved\n * column widths carry over. Anchoring the purge to the observed server identity covers\n * every route into the backend instead of one form.\n *\n * Missing identity metadata is treated as a legacy browser state and purged once:\n * snapshots may predate this marker and belong to a different account. After the\n * marker is recorded, an account's own unsaved widths survive a plain reload.\n */\nfunction purgePerspectiveStateOnIdentityChange(serverUserId: string | null): void {\n if (typeof window === 'undefined' || !serverUserId) return\n try {\n const lastSeenUserId = window.localStorage.getItem(AUTH_IDENTITY_USER_STORAGE_KEY)\n if (lastSeenUserId === serverUserId) return\n clearAllPerspectiveState()\n window.localStorage.setItem(AUTH_IDENTITY_USER_STORAGE_KEY, serverUserId)\n } catch {\n // private mode / quota errors are non-fatal\n }\n}\n\ntype FeatureCheckResponse = {\n ok: boolean\n granted?: string[]\n userId?: string\n}\n\nexport type AuthSessionGuardProps = {\n serverUserId: string | null\n}\n\nexport const __reload = {\n fn: (): void => {\n if (typeof window !== 'undefined') window.location.reload()\n },\n}\n\nexport function AuthSessionGuard({ serverUserId }: AuthSessionGuardProps) {\n React.useEffect(() => {\n if (typeof window === 'undefined') return\n purgePerspectiveStateOnIdentityChange(serverUserId)\n let cancelled = false\n let reloadScheduled = false\n\n const triggerReload = () => {\n if (reloadScheduled) return\n reloadScheduled = true\n __reload.fn()\n }\n\n const checkIdentity = async () => {\n if (cancelled || reloadScheduled) return\n try {\n const res = await apiCall<FeatureCheckResponse>('/api/auth/feature-check', {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ features: [] }),\n cache: 'no-store',\n })\n if (cancelled || reloadScheduled) return\n if (res.status === 401) {\n if (serverUserId) triggerReload()\n return\n }\n if (!res.ok) return\n const currentUserId = typeof res.result?.userId === 'string' ? res.result.userId : null\n if (!currentUserId) return\n if (currentUserId !== serverUserId) triggerReload()\n } catch {\n // network errors are ignored \u2014 next focus/storage event retries\n }\n }\n\n const onVisibilityOrFocus = () => {\n if (typeof document !== 'undefined' && document.visibilityState === 'hidden') return\n void checkIdentity()\n }\n\n const onStorage = (event: StorageEvent) => {\n if (event.key !== AUTH_IDENTITY_STORAGE_KEY) return\n void checkIdentity()\n }\n\n let broadcastChannel: BroadcastChannel | null = null\n if (typeof BroadcastChannel !== 'undefined') {\n try {\n broadcastChannel = new BroadcastChannel(AUTH_IDENTITY_BROADCAST_CHANNEL)\n broadcastChannel.onmessage = () => { void checkIdentity() }\n } catch {\n broadcastChannel = null\n }\n }\n\n window.addEventListener('focus', onVisibilityOrFocus)\n document.addEventListener('visibilitychange', onVisibilityOrFocus)\n window.addEventListener('storage', onStorage)\n\n return () => {\n cancelled = true\n window.removeEventListener('focus', onVisibilityOrFocus)\n document.removeEventListener('visibilitychange', onVisibilityOrFocus)\n window.removeEventListener('storage', onStorage)\n if (broadcastChannel) {\n broadcastChannel.onmessage = null\n broadcastChannel.close()\n }\n }\n }, [serverUserId])\n\n return null\n}\n\nexport function notifyAuthIdentityChange(): void {\n if (typeof window === 'undefined') return\n try {\n if (typeof BroadcastChannel !== 'undefined') {\n const channel = new BroadcastChannel(AUTH_IDENTITY_BROADCAST_CHANNEL)\n channel.postMessage('changed')\n channel.close()\n }\n } catch {\n // ignore \u2014 fall back to storage event below\n }\n try {\n window.localStorage.setItem(AUTH_IDENTITY_STORAGE_KEY, String(Date.now()))\n } catch {\n // private mode / quota errors are non-fatal\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -78,8 +78,13 @@ function useBackendChrome() {
|
|
|
78
78
|
}
|
|
79
79
|
};
|
|
80
80
|
}
|
|
81
|
+
function useCurrentOrganization() {
|
|
82
|
+
const { payload } = useBackendChrome();
|
|
83
|
+
return payload?.currentOrganization ?? null;
|
|
84
|
+
}
|
|
81
85
|
export {
|
|
82
86
|
BackendChromeProvider,
|
|
83
|
-
useBackendChrome
|
|
87
|
+
useBackendChrome,
|
|
88
|
+
useCurrentOrganization
|
|
84
89
|
};
|
|
85
90
|
//# sourceMappingURL=BackendChromeProvider.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/backend/BackendChromeProvider.tsx"],
|
|
4
|
-
"sourcesContent": ["'use client'\n\nimport * as React from 'react'\nimport { apiCall } from './utils/apiCall'\nimport { subscribeOrganizationScopeChanged, getCurrentOrganizationScopeVersion } from '@open-mercato/shared/lib/frontend/organizationEvents'\nimport type {
|
|
5
|
-
"mappings": ";
|
|
4
|
+
"sourcesContent": ["'use client'\n\nimport * as React from 'react'\nimport { apiCall } from './utils/apiCall'\nimport { subscribeOrganizationScopeChanged, getCurrentOrganizationScopeVersion } from '@open-mercato/shared/lib/frontend/organizationEvents'\nimport type {\n BackendChromeCurrentOrganization,\n BackendChromePayload,\n} from '@open-mercato/shared/modules/navigation/backendChrome'\n\ntype BackendChromeContextValue = {\n payload: BackendChromePayload | null\n isLoading: boolean\n isReady: boolean\n refresh: () => Promise<void>\n}\n\ntype BackendChromeProviderProps = {\n adminNavApi?: string\n children: React.ReactNode\n}\n\nconst chromeCache = new Map<string, BackendChromePayload>()\nconst BackendChromeContext = React.createContext<BackendChromeContextValue | null>(null)\n\nfunction buildCacheKey(api: string): string {\n return `${api}::scope:${getCurrentOrganizationScopeVersion()}`\n}\n\nexport function BackendChromeProvider({ adminNavApi, children }: BackendChromeProviderProps) {\n const cachedPayload = React.useMemo(() => {\n if (!adminNavApi) return null\n return chromeCache.get(buildCacheKey(adminNavApi)) ?? null\n }, [adminNavApi])\n const [payload, setPayload] = React.useState<BackendChromePayload | null>(cachedPayload)\n const [isLoading, setIsLoading] = React.useState(Boolean(adminNavApi && !cachedPayload))\n\n const refresh = React.useCallback(async () => {\n if (!adminNavApi) return\n setIsLoading(true)\n try {\n const call = await apiCall<BackendChromePayload>(adminNavApi, { credentials: 'include' as never })\n if (!call.ok || !call.result) return\n const nextPayload = call.result\n chromeCache.set(buildCacheKey(adminNavApi), nextPayload)\n setPayload(nextPayload)\n } catch {\n return\n } finally {\n setIsLoading(false)\n }\n }, [adminNavApi])\n\n React.useEffect(() => {\n if (!adminNavApi) {\n setPayload(null)\n setIsLoading(false)\n return\n }\n const cached = chromeCache.get(buildCacheKey(adminNavApi)) ?? null\n setPayload(cached)\n if (!cached) {\n void refresh()\n }\n }, [adminNavApi, refresh])\n\n React.useEffect(() => {\n if (!adminNavApi) return\n const onFocus = () => { void refresh() }\n const onManualRefresh = () => { void refresh() }\n const unsubscribeScope = subscribeOrganizationScopeChanged(() => {\n void refresh()\n })\n window.addEventListener('focus', onFocus)\n window.addEventListener('om:refresh-sidebar', onManualRefresh as EventListener)\n return () => {\n unsubscribeScope()\n window.removeEventListener('focus', onFocus)\n window.removeEventListener('om:refresh-sidebar', onManualRefresh as EventListener)\n }\n }, [adminNavApi, refresh])\n\n const value = React.useMemo<BackendChromeContextValue>(() => ({\n payload,\n isLoading,\n isReady: !adminNavApi || payload !== null,\n refresh,\n }), [adminNavApi, isLoading, payload, refresh])\n\n return (\n <BackendChromeContext.Provider value={value}>\n {children}\n </BackendChromeContext.Provider>\n )\n}\n\nexport function useBackendChrome(): BackendChromeContextValue {\n return React.useContext(BackendChromeContext) ?? {\n payload: null,\n isLoading: false,\n isReady: true,\n refresh: async () => {},\n }\n}\n\n/**\n * The organization the backend chrome is currently scoped to, for UI that needs to label\n * \"you are viewing: <name>\".\n *\n * Reads the payload this provider already holds, so it costs no additional request. Returns `null`\n * under an all-organizations selection, outside a provider, or before the payload has arrived \u2014 treat\n * it as \"unknown\", not as \"no organization\".\n *\n * Prefer this over `payload.brand`, which only populates when the organization has a logo configured.\n */\nexport function useCurrentOrganization(): BackendChromeCurrentOrganization | null {\n const { payload } = useBackendChrome()\n return payload?.currentOrganization ?? null\n}\n"],
|
|
5
|
+
"mappings": ";AA0FI;AAxFJ,YAAY,WAAW;AACvB,SAAS,eAAe;AACxB,SAAS,mCAAmC,0CAA0C;AAkBtF,MAAM,cAAc,oBAAI,IAAkC;AAC1D,MAAM,uBAAuB,MAAM,cAAgD,IAAI;AAEvF,SAAS,cAAc,KAAqB;AAC1C,SAAO,GAAG,GAAG,WAAW,mCAAmC,CAAC;AAC9D;AAEO,SAAS,sBAAsB,EAAE,aAAa,SAAS,GAA+B;AAC3F,QAAM,gBAAgB,MAAM,QAAQ,MAAM;AACxC,QAAI,CAAC,YAAa,QAAO;AACzB,WAAO,YAAY,IAAI,cAAc,WAAW,CAAC,KAAK;AAAA,EACxD,GAAG,CAAC,WAAW,CAAC;AAChB,QAAM,CAAC,SAAS,UAAU,IAAI,MAAM,SAAsC,aAAa;AACvF,QAAM,CAAC,WAAW,YAAY,IAAI,MAAM,SAAS,QAAQ,eAAe,CAAC,aAAa,CAAC;AAEvF,QAAM,UAAU,MAAM,YAAY,YAAY;AAC5C,QAAI,CAAC,YAAa;AAClB,iBAAa,IAAI;AACjB,QAAI;AACF,YAAM,OAAO,MAAM,QAA8B,aAAa,EAAE,aAAa,UAAmB,CAAC;AACjG,UAAI,CAAC,KAAK,MAAM,CAAC,KAAK,OAAQ;AAC9B,YAAM,cAAc,KAAK;AACzB,kBAAY,IAAI,cAAc,WAAW,GAAG,WAAW;AACvD,iBAAW,WAAW;AAAA,IACxB,QAAQ;AACN;AAAA,IACF,UAAE;AACA,mBAAa,KAAK;AAAA,IACpB;AAAA,EACF,GAAG,CAAC,WAAW,CAAC;AAEhB,QAAM,UAAU,MAAM;AACpB,QAAI,CAAC,aAAa;AAChB,iBAAW,IAAI;AACf,mBAAa,KAAK;AAClB;AAAA,IACF;AACA,UAAM,SAAS,YAAY,IAAI,cAAc,WAAW,CAAC,KAAK;AAC9D,eAAW,MAAM;AACjB,QAAI,CAAC,QAAQ;AACX,WAAK,QAAQ;AAAA,IACf;AAAA,EACF,GAAG,CAAC,aAAa,OAAO,CAAC;AAEzB,QAAM,UAAU,MAAM;AACpB,QAAI,CAAC,YAAa;AAClB,UAAM,UAAU,MAAM;AAAE,WAAK,QAAQ;AAAA,IAAE;AACvC,UAAM,kBAAkB,MAAM;AAAE,WAAK,QAAQ;AAAA,IAAE;AAC/C,UAAM,mBAAmB,kCAAkC,MAAM;AAC/D,WAAK,QAAQ;AAAA,IACf,CAAC;AACD,WAAO,iBAAiB,SAAS,OAAO;AACxC,WAAO,iBAAiB,sBAAsB,eAAgC;AAC9E,WAAO,MAAM;AACX,uBAAiB;AACjB,aAAO,oBAAoB,SAAS,OAAO;AAC3C,aAAO,oBAAoB,sBAAsB,eAAgC;AAAA,IACnF;AAAA,EACF,GAAG,CAAC,aAAa,OAAO,CAAC;AAEzB,QAAM,QAAQ,MAAM,QAAmC,OAAO;AAAA,IAC5D;AAAA,IACA;AAAA,IACA,SAAS,CAAC,eAAe,YAAY;AAAA,IACrC;AAAA,EACF,IAAI,CAAC,aAAa,WAAW,SAAS,OAAO,CAAC;AAE9C,SACE,oBAAC,qBAAqB,UAArB,EAA8B,OAC5B,UACH;AAEJ;AAEO,SAAS,mBAA8C;AAC5D,SAAO,MAAM,WAAW,oBAAoB,KAAK;AAAA,IAC/C,SAAS;AAAA,IACT,WAAW;AAAA,IACX,SAAS;AAAA,IACT,SAAS,YAAY;AAAA,IAAC;AAAA,EACxB;AACF;AAYO,SAAS,yBAAkE;AAChF,QAAM,EAAE,QAAQ,IAAI,iBAAiB;AACrC,SAAO,SAAS,uBAAuB;AACzC;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist/backend/CrudForm.js
CHANGED
|
@@ -100,6 +100,7 @@ import { InjectedField } from "./injection/InjectedField.js";
|
|
|
100
100
|
import { insertByInjectionPlacement } from "@open-mercato/shared/modules/widgets/injection-position";
|
|
101
101
|
import { evaluateInjectedVisibility } from "./injection/visibility-utils.js";
|
|
102
102
|
import { ComponentReplacementHandles } from "@open-mercato/shared/modules/widgets/component-registry";
|
|
103
|
+
import { crudFormExtensionSpotId, extensionSpotChildId } from "@open-mercato/shared/modules/widgets/extension-points";
|
|
103
104
|
import { RichEditor } from "../primitives/rich-editor.js";
|
|
104
105
|
import MarkdownField from "./inputs/MarkdownField.js";
|
|
105
106
|
const logger = createLogger("ui").child({ component: "CrudForm" });
|
|
@@ -453,7 +454,7 @@ function CrudForm({
|
|
|
453
454
|
if (injectionSpotId) return injectionSpotId;
|
|
454
455
|
if (resolvedEntityIds.length) {
|
|
455
456
|
const normalized = resolvedEntityIds[0].replace(/[:]+/g, ".");
|
|
456
|
-
return
|
|
457
|
+
return crudFormExtensionSpotId(normalized);
|
|
457
458
|
}
|
|
458
459
|
return void 0;
|
|
459
460
|
}, [injectionSpotId, resolvedEntityIds]);
|
|
@@ -462,7 +463,7 @@ function CrudForm({
|
|
|
462
463
|
if (resolvedEntityIds.length) return ComponentReplacementHandles.crudForm(resolvedEntityIds[0].replace(/[:]+/g, "."));
|
|
463
464
|
return ComponentReplacementHandles.crudForm("unknown");
|
|
464
465
|
}, [replacementHandle, resolvedEntityIds]);
|
|
465
|
-
const headerInjectionSpotId = resolvedInjectionSpotId ?
|
|
466
|
+
const headerInjectionSpotId = resolvedInjectionSpotId ? extensionSpotChildId(resolvedInjectionSpotId, "header") : void 0;
|
|
466
467
|
const recordId = React.useMemo(() => {
|
|
467
468
|
const raw = values.id;
|
|
468
469
|
if (typeof raw === "string") return raw;
|
|
@@ -679,7 +680,7 @@ function CrudForm({
|
|
|
679
680
|
triggerOnLoad: true
|
|
680
681
|
});
|
|
681
682
|
const { widgets: injectedFieldWidgets } = useInjectionDataWidgets(
|
|
682
|
-
resolvedInjectionSpotId ?
|
|
683
|
+
resolvedInjectionSpotId ? extensionSpotChildId(resolvedInjectionSpotId, "fields") : "__disabled__:fields"
|
|
683
684
|
);
|
|
684
685
|
const { triggerEvent: triggerInjectionEvent } = useInjectionSpotEvents(resolvedInjectionSpotId ?? "", injectionWidgets);
|
|
685
686
|
const extendedInjectionEventsEnabled = CRUDFORM_EXTENDED_EVENTS_ENABLED && Boolean(resolvedInjectionSpotId);
|
|
@@ -1798,10 +1799,11 @@ function CrudForm({
|
|
|
1798
1799
|
}, [validateFieldOnBlur]);
|
|
1799
1800
|
const handleFieldsetSelectionChange = React.useCallback(
|
|
1800
1801
|
(entityId2, nextCode) => {
|
|
1802
|
+
if (!nextCode) return;
|
|
1801
1803
|
setCfFieldsetSelections((prev) => ({ ...prev, [entityId2]: nextCode }));
|
|
1802
1804
|
const bindingKey = customFieldsetBindings?.[entityId2]?.valueKey;
|
|
1803
1805
|
if (bindingKey) {
|
|
1804
|
-
setValue(bindingKey, nextCode
|
|
1806
|
+
setValue(bindingKey, nextCode);
|
|
1805
1807
|
}
|
|
1806
1808
|
},
|
|
1807
1809
|
[customFieldsetBindings, setValue]
|