@open-mercato/ui 0.4.2-canary-c02407ff85
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/build.mjs +62 -0
- package/dist/backend/AppShell.js +902 -0
- package/dist/backend/AppShell.js.map +7 -0
- package/dist/backend/ConfirmDialog.js +17 -0
- package/dist/backend/ConfirmDialog.js.map +7 -0
- package/dist/backend/ContextHelp.js +31 -0
- package/dist/backend/ContextHelp.js.map +7 -0
- package/dist/backend/CrudForm.js +2028 -0
- package/dist/backend/CrudForm.js.map +7 -0
- package/dist/backend/DataTable.js +1363 -0
- package/dist/backend/DataTable.js.map +7 -0
- package/dist/backend/EmptyState.js +52 -0
- package/dist/backend/EmptyState.js.map +7 -0
- package/dist/backend/FilterBar.js +140 -0
- package/dist/backend/FilterBar.js.map +7 -0
- package/dist/backend/FilterOverlay.js +279 -0
- package/dist/backend/FilterOverlay.js.map +7 -0
- package/dist/backend/FlashMessages.js +66 -0
- package/dist/backend/FlashMessages.js.map +7 -0
- package/dist/backend/JsonBuilder.js +322 -0
- package/dist/backend/JsonBuilder.js.map +7 -0
- package/dist/backend/JsonDisplay.js +203 -0
- package/dist/backend/JsonDisplay.js.map +7 -0
- package/dist/backend/Page.js +27 -0
- package/dist/backend/Page.js.map +7 -0
- package/dist/backend/PerspectiveSidebar.js +282 -0
- package/dist/backend/PerspectiveSidebar.js.map +7 -0
- package/dist/backend/RowActions.js +148 -0
- package/dist/backend/RowActions.js.map +7 -0
- package/dist/backend/TruncatedCell.js +92 -0
- package/dist/backend/TruncatedCell.js.map +7 -0
- package/dist/backend/UserMenu.js +107 -0
- package/dist/backend/UserMenu.js.map +7 -0
- package/dist/backend/ValueIcons.js +34 -0
- package/dist/backend/ValueIcons.js.map +7 -0
- package/dist/backend/custom-fields/FieldDefinitionsEditor.js +1264 -0
- package/dist/backend/custom-fields/FieldDefinitionsEditor.js.map +7 -0
- package/dist/backend/custom-fields/FieldDefinitionsManager.js +332 -0
- package/dist/backend/custom-fields/FieldDefinitionsManager.js.map +7 -0
- package/dist/backend/dashboard/DashboardScreen.js +578 -0
- package/dist/backend/dashboard/DashboardScreen.js.map +7 -0
- package/dist/backend/dashboard/index.js +5 -0
- package/dist/backend/dashboard/index.js.map +7 -0
- package/dist/backend/dashboard/widgetRegistry.js +55 -0
- package/dist/backend/dashboard/widgetRegistry.js.map +7 -0
- package/dist/backend/detail/ActivitiesSection.js +962 -0
- package/dist/backend/detail/ActivitiesSection.js.map +7 -0
- package/dist/backend/detail/AddressEditor.js +413 -0
- package/dist/backend/detail/AddressEditor.js.map +7 -0
- package/dist/backend/detail/AddressTiles.js +437 -0
- package/dist/backend/detail/AddressTiles.js.map +7 -0
- package/dist/backend/detail/AddressesSection.js +264 -0
- package/dist/backend/detail/AddressesSection.js.map +7 -0
- package/dist/backend/detail/AttachmentDeleteDialog.js +41 -0
- package/dist/backend/detail/AttachmentDeleteDialog.js.map +7 -0
- package/dist/backend/detail/AttachmentMetadataDialog.js +517 -0
- package/dist/backend/detail/AttachmentMetadataDialog.js.map +7 -0
- package/dist/backend/detail/AttachmentsSection.js +367 -0
- package/dist/backend/detail/AttachmentsSection.js.map +7 -0
- package/dist/backend/detail/CustomDataSection.js +433 -0
- package/dist/backend/detail/CustomDataSection.js.map +7 -0
- package/dist/backend/detail/DetailFieldsSection.js +75 -0
- package/dist/backend/detail/DetailFieldsSection.js.map +7 -0
- package/dist/backend/detail/ErrorMessage.js +28 -0
- package/dist/backend/detail/ErrorMessage.js.map +7 -0
- package/dist/backend/detail/InlineEditors.js +681 -0
- package/dist/backend/detail/InlineEditors.js.map +7 -0
- package/dist/backend/detail/LoadingMessage.js +14 -0
- package/dist/backend/detail/LoadingMessage.js.map +7 -0
- package/dist/backend/detail/NotesSection.js +1032 -0
- package/dist/backend/detail/NotesSection.js.map +7 -0
- package/dist/backend/detail/TabEmptyState.js +25 -0
- package/dist/backend/detail/TabEmptyState.js.map +7 -0
- package/dist/backend/detail/TagsSection.js +254 -0
- package/dist/backend/detail/TagsSection.js.map +7 -0
- package/dist/backend/detail/addressFormat.js +77 -0
- package/dist/backend/detail/addressFormat.js.map +7 -0
- package/dist/backend/detail/index.js +34 -0
- package/dist/backend/detail/index.js.map +7 -0
- package/dist/backend/fields/registry.generated.js +8 -0
- package/dist/backend/fields/registry.generated.js.map +7 -0
- package/dist/backend/fields/registry.js +29 -0
- package/dist/backend/fields/registry.js.map +7 -0
- package/dist/backend/indexes/PartialIndexBanner.js +58 -0
- package/dist/backend/indexes/PartialIndexBanner.js.map +7 -0
- package/dist/backend/indexes/store.js +62 -0
- package/dist/backend/indexes/store.js.map +7 -0
- package/dist/backend/injection/InjectionSpot.js +179 -0
- package/dist/backend/injection/InjectionSpot.js.map +7 -0
- package/dist/backend/injection/PageInjectionBoundary.js +26 -0
- package/dist/backend/injection/PageInjectionBoundary.js.map +7 -0
- package/dist/backend/injection/helpers.js +26 -0
- package/dist/backend/injection/helpers.js.map +7 -0
- package/dist/backend/injection/widgetRegistry.js +55 -0
- package/dist/backend/injection/widgetRegistry.js.map +7 -0
- package/dist/backend/inputs/ComboboxInput.js +225 -0
- package/dist/backend/inputs/ComboboxInput.js.map +7 -0
- package/dist/backend/inputs/LookupSelect.js +191 -0
- package/dist/backend/inputs/LookupSelect.js.map +7 -0
- package/dist/backend/inputs/PhoneNumberField.js +100 -0
- package/dist/backend/inputs/PhoneNumberField.js.map +7 -0
- package/dist/backend/inputs/SwitchableMarkdownInput.js +92 -0
- package/dist/backend/inputs/SwitchableMarkdownInput.js.map +7 -0
- package/dist/backend/inputs/TagsInput.js +222 -0
- package/dist/backend/inputs/TagsInput.js.map +7 -0
- package/dist/backend/inputs/index.js +6 -0
- package/dist/backend/inputs/index.js.map +7 -0
- package/dist/backend/operations/LastOperationBanner.js +80 -0
- package/dist/backend/operations/LastOperationBanner.js.map +7 -0
- package/dist/backend/operations/store.js +183 -0
- package/dist/backend/operations/store.js.map +7 -0
- package/dist/backend/schedule/ScheduleAgenda.js +107 -0
- package/dist/backend/schedule/ScheduleAgenda.js.map +7 -0
- package/dist/backend/schedule/ScheduleGrid.js +107 -0
- package/dist/backend/schedule/ScheduleGrid.js.map +7 -0
- package/dist/backend/schedule/ScheduleToolbar.js +166 -0
- package/dist/backend/schedule/ScheduleToolbar.js.map +7 -0
- package/dist/backend/schedule/ScheduleView.js +165 -0
- package/dist/backend/schedule/ScheduleView.js.map +7 -0
- package/dist/backend/schedule/index.js +6 -0
- package/dist/backend/schedule/index.js.map +7 -0
- package/dist/backend/schedule/recurrence.js +83 -0
- package/dist/backend/schedule/recurrence.js.map +7 -0
- package/dist/backend/schedule/types.js +1 -0
- package/dist/backend/schedule/types.js.map +7 -0
- package/dist/backend/upgrades/UpgradeActionBanner.js +91 -0
- package/dist/backend/upgrades/UpgradeActionBanner.js.map +7 -0
- package/dist/backend/utils/api.js +127 -0
- package/dist/backend/utils/api.js.map +7 -0
- package/dist/backend/utils/apiCall.js +48 -0
- package/dist/backend/utils/apiCall.js.map +7 -0
- package/dist/backend/utils/crud.js +126 -0
- package/dist/backend/utils/crud.js.map +7 -0
- package/dist/backend/utils/customFieldColumns.js +56 -0
- package/dist/backend/utils/customFieldColumns.js.map +7 -0
- package/dist/backend/utils/customFieldDefs.js +143 -0
- package/dist/backend/utils/customFieldDefs.js.map +7 -0
- package/dist/backend/utils/customFieldFilters.js +126 -0
- package/dist/backend/utils/customFieldFilters.js.map +7 -0
- package/dist/backend/utils/customFieldForms.js +162 -0
- package/dist/backend/utils/customFieldForms.js.map +7 -0
- package/dist/backend/utils/customFieldValues.js +26 -0
- package/dist/backend/utils/customFieldValues.js.map +7 -0
- package/dist/backend/utils/flash.js +16 -0
- package/dist/backend/utils/flash.js.map +7 -0
- package/dist/backend/utils/nav.js +185 -0
- package/dist/backend/utils/nav.js.map +7 -0
- package/dist/backend/utils/serverErrors.js +230 -0
- package/dist/backend/utils/serverErrors.js.map +7 -0
- package/dist/frontend/AuthFooter.js +23 -0
- package/dist/frontend/AuthFooter.js.map +7 -0
- package/dist/frontend/LanguageSwitcher.js +57 -0
- package/dist/frontend/LanguageSwitcher.js.map +7 -0
- package/dist/frontend/Layout.js +14 -0
- package/dist/frontend/Layout.js.map +7 -0
- package/dist/index.js +32 -0
- package/dist/index.js.map +7 -0
- package/dist/primitives/DataLoader.js +67 -0
- package/dist/primitives/DataLoader.js.map +7 -0
- package/dist/primitives/ErrorNotice.js +20 -0
- package/dist/primitives/ErrorNotice.js.map +7 -0
- package/dist/primitives/alert.js +38 -0
- package/dist/primitives/alert.js.map +7 -0
- package/dist/primitives/badge.js +28 -0
- package/dist/primitives/badge.js.map +7 -0
- package/dist/primitives/button.js +44 -0
- package/dist/primitives/button.js.map +7 -0
- package/dist/primitives/card.js +91 -0
- package/dist/primitives/card.js.map +7 -0
- package/dist/primitives/checkbox.js +28 -0
- package/dist/primitives/checkbox.js.map +7 -0
- package/dist/primitives/dialog.js +90 -0
- package/dist/primitives/dialog.js.map +7 -0
- package/dist/primitives/input.js +22 -0
- package/dist/primitives/input.js.map +7 -0
- package/dist/primitives/label.js +21 -0
- package/dist/primitives/label.js.map +7 -0
- package/dist/primitives/separator.js +9 -0
- package/dist/primitives/separator.js.map +7 -0
- package/dist/primitives/spinner.js +24 -0
- package/dist/primitives/spinner.js.map +7 -0
- package/dist/primitives/switch.js +80 -0
- package/dist/primitives/switch.js.map +7 -0
- package/dist/primitives/table.js +29 -0
- package/dist/primitives/table.js.map +7 -0
- package/dist/primitives/tabs.js +87 -0
- package/dist/primitives/tabs.js.map +7 -0
- package/dist/primitives/textarea.js +21 -0
- package/dist/primitives/textarea.js.map +7 -0
- package/dist/primitives/tooltip.js +60 -0
- package/dist/primitives/tooltip.js.map +7 -0
- package/dist/theme/QueryProvider.js +44 -0
- package/dist/theme/QueryProvider.js.map +7 -0
- package/dist/theme/ThemeProvider.js +95 -0
- package/dist/theme/ThemeProvider.js.map +7 -0
- package/dist/theme/ThemeToggle.js +88 -0
- package/dist/theme/ThemeToggle.js.map +7 -0
- package/dist/theme/index.js +10 -0
- package/dist/theme/index.js.map +7 -0
- package/dist/types/react-big-calendar.d.js +1 -0
- package/dist/types/react-big-calendar.d.js.map +7 -0
- package/jest.config.cjs +23 -0
- package/jest.setup.ts +55 -0
- package/package.json +105 -0
- package/src/backend/AppShell.tsx +1096 -0
- package/src/backend/ConfirmDialog.tsx +19 -0
- package/src/backend/ContextHelp.tsx +38 -0
- package/src/backend/CrudForm.tsx +2503 -0
- package/src/backend/DataTable.tsx +1730 -0
- package/src/backend/EmptyState.tsx +65 -0
- package/src/backend/FilterBar.tsx +161 -0
- package/src/backend/FilterOverlay.tsx +328 -0
- package/src/backend/FlashMessages.tsx +82 -0
- package/src/backend/JsonBuilder.tsx +362 -0
- package/src/backend/JsonDisplay.tsx +254 -0
- package/src/backend/Page.tsx +30 -0
- package/src/backend/PerspectiveSidebar.tsx +337 -0
- package/src/backend/RowActions.tsx +151 -0
- package/src/backend/TruncatedCell.tsx +133 -0
- package/src/backend/UserMenu.tsx +118 -0
- package/src/backend/ValueIcons.tsx +48 -0
- package/src/backend/__tests__/AppShell.test.tsx +115 -0
- package/src/backend/__tests__/CrudForm.render.test.tsx +30 -0
- package/src/backend/__tests__/DataTable.render.test.tsx +48 -0
- package/src/backend/__tests__/custom-field-filters.test.ts +72 -0
- package/src/backend/__tests__/custom-field-forms.test.ts +54 -0
- package/src/backend/__tests__/serverErrors.test.ts +83 -0
- package/src/backend/custom-fields/FieldDefinitionsEditor.tsx +1292 -0
- package/src/backend/custom-fields/FieldDefinitionsManager.tsx +381 -0
- package/src/backend/dashboard/DashboardScreen.tsx +684 -0
- package/src/backend/dashboard/__tests__/DashboardScreen.test.tsx +112 -0
- package/src/backend/dashboard/index.ts +1 -0
- package/src/backend/dashboard/widgetRegistry.ts +68 -0
- package/src/backend/detail/ActivitiesSection.tsx +1284 -0
- package/src/backend/detail/AddressEditor.tsx +472 -0
- package/src/backend/detail/AddressTiles.tsx +587 -0
- package/src/backend/detail/AddressesSection.tsx +346 -0
- package/src/backend/detail/AttachmentDeleteDialog.tsx +56 -0
- package/src/backend/detail/AttachmentMetadataDialog.tsx +672 -0
- package/src/backend/detail/AttachmentsSection.tsx +414 -0
- package/src/backend/detail/CustomDataSection.tsx +530 -0
- package/src/backend/detail/DetailFieldsSection.tsx +147 -0
- package/src/backend/detail/ErrorMessage.tsx +32 -0
- package/src/backend/detail/InlineEditors.tsx +877 -0
- package/src/backend/detail/LoadingMessage.tsx +14 -0
- package/src/backend/detail/NotesSection.tsx +1275 -0
- package/src/backend/detail/TabEmptyState.tsx +48 -0
- package/src/backend/detail/TagsSection.tsx +314 -0
- package/src/backend/detail/addressFormat.tsx +121 -0
- package/src/backend/detail/index.ts +44 -0
- package/src/backend/fields/registry.generated.ts +8 -0
- package/src/backend/fields/registry.ts +38 -0
- package/src/backend/indexes/PartialIndexBanner.tsx +68 -0
- package/src/backend/indexes/store.ts +88 -0
- package/src/backend/injection/InjectionSpot.tsx +236 -0
- package/src/backend/injection/PageInjectionBoundary.tsx +31 -0
- package/src/backend/injection/helpers.ts +35 -0
- package/src/backend/injection/widgetRegistry.ts +68 -0
- package/src/backend/inputs/ComboboxInput.tsx +269 -0
- package/src/backend/inputs/LookupSelect.tsx +247 -0
- package/src/backend/inputs/PhoneNumberField.tsx +129 -0
- package/src/backend/inputs/SwitchableMarkdownInput.tsx +128 -0
- package/src/backend/inputs/TagsInput.tsx +259 -0
- package/src/backend/inputs/index.ts +5 -0
- package/src/backend/operations/LastOperationBanner.tsx +85 -0
- package/src/backend/operations/__tests__/LastOperationBanner.test.tsx +99 -0
- package/src/backend/operations/store.ts +230 -0
- package/src/backend/schedule/ScheduleAgenda.tsx +136 -0
- package/src/backend/schedule/ScheduleGrid.tsx +136 -0
- package/src/backend/schedule/ScheduleToolbar.tsx +178 -0
- package/src/backend/schedule/ScheduleView.tsx +198 -0
- package/src/backend/schedule/index.ts +5 -0
- package/src/backend/schedule/recurrence.ts +99 -0
- package/src/backend/schedule/types.ts +26 -0
- package/src/backend/upgrades/UpgradeActionBanner.tsx +128 -0
- package/src/backend/utils/__tests__/apiCall.test.ts +109 -0
- package/src/backend/utils/__tests__/crud.test.ts +87 -0
- package/src/backend/utils/__tests__/customFieldDefs.test.ts +25 -0
- package/src/backend/utils/__tests__/customFieldValues.test.ts +35 -0
- package/src/backend/utils/api.ts +149 -0
- package/src/backend/utils/apiCall.ts +96 -0
- package/src/backend/utils/crud.ts +174 -0
- package/src/backend/utils/customFieldColumns.ts +71 -0
- package/src/backend/utils/customFieldDefs.ts +245 -0
- package/src/backend/utils/customFieldFilters.ts +145 -0
- package/src/backend/utils/customFieldForms.ts +196 -0
- package/src/backend/utils/customFieldValues.ts +41 -0
- package/src/backend/utils/flash.ts +17 -0
- package/src/backend/utils/nav.ts +238 -0
- package/src/backend/utils/serverErrors.ts +302 -0
- package/src/frontend/AuthFooter.tsx +29 -0
- package/src/frontend/LanguageSwitcher.tsx +66 -0
- package/src/frontend/Layout.tsx +13 -0
- package/src/index.ts +32 -0
- package/src/primitives/DataLoader.tsx +92 -0
- package/src/primitives/ErrorNotice.tsx +26 -0
- package/src/primitives/alert.tsx +52 -0
- package/src/primitives/badge.tsx +31 -0
- package/src/primitives/button.tsx +47 -0
- package/src/primitives/card.tsx +92 -0
- package/src/primitives/checkbox.tsx +28 -0
- package/src/primitives/dialog.tsx +110 -0
- package/src/primitives/input.tsx +20 -0
- package/src/primitives/label.tsx +18 -0
- package/src/primitives/separator.tsx +7 -0
- package/src/primitives/spinner.tsx +27 -0
- package/src/primitives/switch.tsx +86 -0
- package/src/primitives/table.tsx +27 -0
- package/src/primitives/tabs.tsx +128 -0
- package/src/primitives/textarea.tsx +20 -0
- package/src/primitives/tooltip.tsx +85 -0
- package/src/theme/QueryProvider.tsx +46 -0
- package/src/theme/ThemeProvider.tsx +120 -0
- package/src/theme/ThemeToggle.tsx +88 -0
- package/src/theme/index.ts +3 -0
- package/src/types/react-big-calendar.d.ts +16 -0
- package/tsconfig.build.json +11 -0
- package/tsconfig.json +9 -0
- package/watch.mjs +6 -0
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
export * from "./InlineEditors.js";
|
|
2
|
+
export * from "./DetailFieldsSection.js";
|
|
3
|
+
export * from "./LoadingMessage.js";
|
|
4
|
+
export * from "./ErrorMessage.js";
|
|
5
|
+
export * from "./TabEmptyState.js";
|
|
6
|
+
export * from "./CustomDataSection.js";
|
|
7
|
+
export * from "./TagsSection.js";
|
|
8
|
+
import { NotesSection, mapCommentSummary } from "./NotesSection.js";
|
|
9
|
+
import { ActivitiesSection } from "./ActivitiesSection.js";
|
|
10
|
+
import { AddressesSection } from "./AddressesSection.js";
|
|
11
|
+
import { default as default2 } from "./AddressTiles.js";
|
|
12
|
+
import { default as default3 } from "./AddressEditor.js";
|
|
13
|
+
import {
|
|
14
|
+
AddressView,
|
|
15
|
+
formatAddressJson,
|
|
16
|
+
formatAddressLines,
|
|
17
|
+
formatAddressString
|
|
18
|
+
} from "./addressFormat.js";
|
|
19
|
+
export * from "./AttachmentMetadataDialog.js";
|
|
20
|
+
export * from "./AttachmentDeleteDialog.js";
|
|
21
|
+
export * from "./AttachmentsSection.js";
|
|
22
|
+
export {
|
|
23
|
+
ActivitiesSection,
|
|
24
|
+
default3 as AddressEditor,
|
|
25
|
+
default2 as AddressTiles,
|
|
26
|
+
AddressView,
|
|
27
|
+
AddressesSection,
|
|
28
|
+
NotesSection,
|
|
29
|
+
formatAddressJson,
|
|
30
|
+
formatAddressLines,
|
|
31
|
+
formatAddressString,
|
|
32
|
+
mapCommentSummary
|
|
33
|
+
};
|
|
34
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/backend/detail/index.ts"],
|
|
4
|
+
"sourcesContent": ["export * from './InlineEditors'\nexport * from './DetailFieldsSection'\nexport * from './LoadingMessage'\nexport * from './ErrorMessage'\nexport * from './TabEmptyState'\nexport * from './CustomDataSection'\nexport * from './TagsSection'\nexport { NotesSection, mapCommentSummary } from './NotesSection'\nexport type { NotesSectionProps, CommentSummary, SectionAction, TabEmptyStateConfig } from './NotesSection'\nexport { ActivitiesSection } from './ActivitiesSection'\nexport type {\n ActivitiesSectionProps,\n ActivitiesDataAdapter,\n ActivitySummary,\n ActivityCreatePayload,\n ActivityUpdatePayload,\n ActivityFormBaseValues,\n ActivityFormSubmitPayload,\n} from './ActivitiesSection'\nexport { AddressesSection } from './AddressesSection'\nexport type { AddressesSectionProps, AddressDataAdapter, AddressSummary } from './AddressesSection'\nexport { default as AddressTiles } from './AddressTiles'\nexport type { AddressInput, AddressValue as AddressTileValue, Translator as AddressTilesTranslator } from './AddressTiles'\nexport { default as AddressEditor } from './AddressEditor'\nexport type {\n AddressTypeOption,\n AddressTypesAdapter,\n AddressEditorDraft,\n AddressEditorField,\n} from './AddressEditor'\nexport {\n AddressView,\n formatAddressJson,\n formatAddressLines,\n formatAddressString,\n} from './addressFormat'\nexport type {\n AddressFormatStrategy,\n AddressJsonShape,\n AddressValue as AddressFormatValue,\n} from './addressFormat'\nexport * from './AttachmentMetadataDialog'\nexport * from './AttachmentDeleteDialog'\nexport * from './AttachmentsSection'\n"],
|
|
5
|
+
"mappings": "AAAA,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,SAAS,cAAc,yBAAyB;AAEhD,SAAS,yBAAyB;AAUlC,SAAS,wBAAwB;AAEjC,SAAoB,WAAXA,gBAA+B;AAExC,SAAoB,WAAXA,gBAAgC;AAOzC;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAMP,cAAc;AACd,cAAc;AACd,cAAc;",
|
|
6
|
+
"names": ["default"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/backend/fields/registry.generated.ts"],
|
|
4
|
+
"sourcesContent": ["// Auto-registered field components loaded at runtime.\n// This file can be regenerated by module generators. Keep imports side-effectful.\nimport '@open-mercato/core/modules/attachments/fields/attachment'\nimport '@open-mercato/core/modules/dictionaries/fields/dictionary'\n\nexport function loadAll() {\n // No-op: imports above perform registration via side effects\n}\n"],
|
|
5
|
+
"mappings": "AAEA,OAAO;AACP,OAAO;AAEA,SAAS,UAAU;AAE1B;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
class FieldRegistryImpl {
|
|
2
|
+
constructor() {
|
|
3
|
+
this.map = /* @__PURE__ */ new Map();
|
|
4
|
+
}
|
|
5
|
+
register(kind, entry) {
|
|
6
|
+
const k = kind.toLowerCase();
|
|
7
|
+
const prev = this.map.get(k) || {};
|
|
8
|
+
this.map.set(k, { ...prev, ...entry });
|
|
9
|
+
}
|
|
10
|
+
getInput(kind) {
|
|
11
|
+
return this.map.get(kind.toLowerCase())?.input;
|
|
12
|
+
}
|
|
13
|
+
getDefEditor(kind) {
|
|
14
|
+
return this.map.get(kind.toLowerCase())?.defEditor;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
const FieldRegistry = new FieldRegistryImpl();
|
|
18
|
+
async function loadGeneratedFieldRegistrations() {
|
|
19
|
+
try {
|
|
20
|
+
const gen = await import("./registry.generated.js");
|
|
21
|
+
if (typeof gen.loadAll === "function") gen.loadAll();
|
|
22
|
+
} catch {
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
export {
|
|
26
|
+
FieldRegistry,
|
|
27
|
+
loadGeneratedFieldRegistrations
|
|
28
|
+
};
|
|
29
|
+
//# sourceMappingURL=registry.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/backend/fields/registry.ts"],
|
|
4
|
+
"sourcesContent": ["import * as React from 'react'\nimport type { CrudCustomFieldRenderProps } from '../CrudForm'\n\nexport type FieldInputComponent = (props: CrudCustomFieldRenderProps & { def?: any }) => React.ReactNode\nexport type FieldDefEditorComponent = (props: { def: any; onChange: (patch: any) => void }) => React.ReactNode\n\ntype Entry = { input?: FieldInputComponent; defEditor?: FieldDefEditorComponent }\n\nclass FieldRegistryImpl {\n private map = new Map<string, Entry>()\n\n register(kind: string, entry: Entry) {\n const k = kind.toLowerCase()\n const prev = this.map.get(k) || {}\n this.map.set(k, { ...prev, ...entry })\n }\n\n getInput(kind: string): FieldInputComponent | undefined {\n return this.map.get(kind.toLowerCase())?.input\n }\n\n getDefEditor(kind: string): FieldDefEditorComponent | undefined {\n return this.map.get(kind.toLowerCase())?.defEditor\n }\n}\n\nexport const FieldRegistry = new FieldRegistryImpl()\n\n// Placeholder for generator to auto-register fields from modules\n// eslint-disable-next-line @typescript-eslint/no-empty-function\nexport async function loadGeneratedFieldRegistrations(): Promise<void> {\n try {\n const gen = await import('./registry.generated')\n if (typeof gen.loadAll === 'function') gen.loadAll()\n } catch {\n // ignore when not present\n }\n}\n"],
|
|
5
|
+
"mappings": "AAQA,MAAM,kBAAkB;AAAA,EAAxB;AACE,SAAQ,MAAM,oBAAI,IAAmB;AAAA;AAAA,EAErC,SAAS,MAAc,OAAc;AACnC,UAAM,IAAI,KAAK,YAAY;AAC3B,UAAM,OAAO,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC;AACjC,SAAK,IAAI,IAAI,GAAG,EAAE,GAAG,MAAM,GAAG,MAAM,CAAC;AAAA,EACvC;AAAA,EAEA,SAAS,MAA+C;AACtD,WAAO,KAAK,IAAI,IAAI,KAAK,YAAY,CAAC,GAAG;AAAA,EAC3C;AAAA,EAEA,aAAa,MAAmD;AAC9D,WAAO,KAAK,IAAI,IAAI,KAAK,YAAY,CAAC,GAAG;AAAA,EAC3C;AACF;AAEO,MAAM,gBAAgB,IAAI,kBAAkB;AAInD,eAAsB,kCAAiD;AACrE,MAAI;AACF,UAAM,MAAM,MAAM,OAAO,sBAAsB;AAC/C,QAAI,OAAO,IAAI,YAAY,WAAY,KAAI,QAAQ;AAAA,EACrD,QAAQ;AAAA,EAER;AACF;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
import Link from "next/link";
|
|
4
|
+
import { AlertTriangle, X } from "lucide-react";
|
|
5
|
+
import { Button } from "../../primitives/button.js";
|
|
6
|
+
import { useT } from "@open-mercato/shared/lib/i18n/context";
|
|
7
|
+
import { dismissPartialIndexWarning, usePartialIndexWarning } from "./store.js";
|
|
8
|
+
function PartialIndexBanner() {
|
|
9
|
+
const t = useT();
|
|
10
|
+
const warning = usePartialIndexWarning();
|
|
11
|
+
if (!warning) return null;
|
|
12
|
+
const entityLabel = warning.entityLabel || warning.entity;
|
|
13
|
+
const base = warning.baseCount;
|
|
14
|
+
const indexed = warning.indexedCount;
|
|
15
|
+
const hasCounts = typeof base === "number" && typeof indexed === "number";
|
|
16
|
+
return /* @__PURE__ */ jsxs("div", { className: "mb-4 flex flex-col gap-3 rounded-md border border-amber-300 bg-amber-50 px-3 py-3 text-sm text-amber-900 md:flex-row md:items-center md:justify-between", children: [
|
|
17
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2 text-sm", children: [
|
|
18
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 font-medium text-amber-950", children: [
|
|
19
|
+
/* @__PURE__ */ jsx(AlertTriangle, { className: "size-4", "aria-hidden": "true" }),
|
|
20
|
+
/* @__PURE__ */ jsx("span", { children: t("query_index.banner.partial_title") })
|
|
21
|
+
] }),
|
|
22
|
+
/* @__PURE__ */ jsx("p", { className: "text-amber-900", children: t("query_index.banner.partial_description") }),
|
|
23
|
+
/* @__PURE__ */ jsx("p", { className: "text-xs text-amber-900/90", children: t("query_index.banner.partial_entity", { entity: entityLabel }) }),
|
|
24
|
+
hasCounts && /* @__PURE__ */ jsx("p", { className: "text-xs text-amber-900/90", children: t("query_index.banner.partial_counts", { indexed, total: base }) }),
|
|
25
|
+
warning.scope === "global" && /* @__PURE__ */ jsx("p", { className: "text-xs text-amber-900/80", children: t("query_index.banner.partial_global_note") })
|
|
26
|
+
] }),
|
|
27
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [
|
|
28
|
+
/* @__PURE__ */ jsx(
|
|
29
|
+
Button,
|
|
30
|
+
{
|
|
31
|
+
asChild: true,
|
|
32
|
+
variant: "outline",
|
|
33
|
+
size: "sm",
|
|
34
|
+
className: "border-amber-300 text-amber-900 hover:bg-amber-100",
|
|
35
|
+
children: /* @__PURE__ */ jsx(Link, { href: "/backend/query-indexes", children: t("query_index.banner.manage_indexes") })
|
|
36
|
+
}
|
|
37
|
+
),
|
|
38
|
+
/* @__PURE__ */ jsxs(
|
|
39
|
+
Button,
|
|
40
|
+
{
|
|
41
|
+
variant: "ghost",
|
|
42
|
+
size: "sm",
|
|
43
|
+
onClick: () => dismissPartialIndexWarning(),
|
|
44
|
+
className: "text-amber-900 hover:bg-amber-100",
|
|
45
|
+
"aria-label": t("query_index.banner.dismiss"),
|
|
46
|
+
children: [
|
|
47
|
+
/* @__PURE__ */ jsx(X, { className: "mr-1 size-4", "aria-hidden": "true" }),
|
|
48
|
+
t("query_index.banner.dismiss")
|
|
49
|
+
]
|
|
50
|
+
}
|
|
51
|
+
)
|
|
52
|
+
] })
|
|
53
|
+
] });
|
|
54
|
+
}
|
|
55
|
+
export {
|
|
56
|
+
PartialIndexBanner
|
|
57
|
+
};
|
|
58
|
+
//# sourceMappingURL=PartialIndexBanner.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/backend/indexes/PartialIndexBanner.tsx"],
|
|
4
|
+
"sourcesContent": ["\"use client\"\nimport * as React from 'react'\nimport Link from 'next/link'\nimport { AlertTriangle, X } from 'lucide-react'\nimport { Button } from '../../primitives/button'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { dismissPartialIndexWarning, usePartialIndexWarning } from './store'\n\nexport function PartialIndexBanner() {\n const t = useT()\n const warning = usePartialIndexWarning()\n\n if (!warning) return null\n\n const entityLabel = warning.entityLabel || warning.entity\n const base = warning.baseCount\n const indexed = warning.indexedCount\n const hasCounts = typeof base === 'number' && typeof indexed === 'number'\n\n return (\n <div className=\"mb-4 flex flex-col gap-3 rounded-md border border-amber-300 bg-amber-50 px-3 py-3 text-sm text-amber-900 md:flex-row md:items-center md:justify-between\">\n <div className=\"flex flex-col gap-2 text-sm\">\n <div className=\"flex items-center gap-2 font-medium text-amber-950\">\n <AlertTriangle className=\"size-4\" aria-hidden=\"true\" />\n <span>{t('query_index.banner.partial_title')}</span>\n </div>\n <p className=\"text-amber-900\">\n {t('query_index.banner.partial_description')}\n </p>\n <p className=\"text-xs text-amber-900/90\">\n {t('query_index.banner.partial_entity', { entity: entityLabel })}\n </p>\n {hasCounts && (\n <p className=\"text-xs text-amber-900/90\">\n {t('query_index.banner.partial_counts', { indexed, total: base })}\n </p>\n )}\n {warning.scope === 'global' && (\n <p className=\"text-xs text-amber-900/80\">\n {t('query_index.banner.partial_global_note')}\n </p>\n )}\n </div>\n <div className=\"flex flex-wrap items-center gap-2\">\n <Button\n asChild\n variant=\"outline\"\n size=\"sm\"\n className=\"border-amber-300 text-amber-900 hover:bg-amber-100\"\n >\n <Link href=\"/backend/query-indexes\">\n {t('query_index.banner.manage_indexes')}\n </Link>\n </Button>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={() => dismissPartialIndexWarning()}\n className=\"text-amber-900 hover:bg-amber-100\"\n aria-label={t('query_index.banner.dismiss')}\n >\n <X className=\"mr-1 size-4\" aria-hidden=\"true\" />\n {t('query_index.banner.dismiss')}\n </Button>\n </div>\n </div>\n )\n}\n"],
|
|
5
|
+
"mappings": ";AAsBQ,SACE,KADF;AApBR,OAAO,UAAU;AACjB,SAAS,eAAe,SAAS;AACjC,SAAS,cAAc;AACvB,SAAS,YAAY;AACrB,SAAS,4BAA4B,8BAA8B;AAE5D,SAAS,qBAAqB;AACnC,QAAM,IAAI,KAAK;AACf,QAAM,UAAU,uBAAuB;AAEvC,MAAI,CAAC,QAAS,QAAO;AAErB,QAAM,cAAc,QAAQ,eAAe,QAAQ;AACnD,QAAM,OAAO,QAAQ;AACrB,QAAM,UAAU,QAAQ;AACxB,QAAM,YAAY,OAAO,SAAS,YAAY,OAAO,YAAY;AAEjE,SACE,qBAAC,SAAI,WAAU,2JACb;AAAA,yBAAC,SAAI,WAAU,+BACb;AAAA,2BAAC,SAAI,WAAU,sDACb;AAAA,4BAAC,iBAAc,WAAU,UAAS,eAAY,QAAO;AAAA,QACrD,oBAAC,UAAM,YAAE,kCAAkC,GAAE;AAAA,SAC/C;AAAA,MACA,oBAAC,OAAE,WAAU,kBACV,YAAE,wCAAwC,GAC7C;AAAA,MACA,oBAAC,OAAE,WAAU,6BACV,YAAE,qCAAqC,EAAE,QAAQ,YAAY,CAAC,GACjE;AAAA,MACC,aACC,oBAAC,OAAE,WAAU,6BACV,YAAE,qCAAqC,EAAE,SAAS,OAAO,KAAK,CAAC,GAClE;AAAA,MAED,QAAQ,UAAU,YACjB,oBAAC,OAAE,WAAU,6BACV,YAAE,wCAAwC,GAC7C;AAAA,OAEJ;AAAA,IACA,qBAAC,SAAI,WAAU,qCACb;AAAA;AAAA,QAAC;AAAA;AAAA,UACC,SAAO;AAAA,UACP,SAAQ;AAAA,UACR,MAAK;AAAA,UACL,WAAU;AAAA,UAEV,8BAAC,QAAK,MAAK,0BACR,YAAE,mCAAmC,GACxC;AAAA;AAAA,MACF;AAAA,MACA;AAAA,QAAC;AAAA;AAAA,UACC,SAAQ;AAAA,UACR,MAAK;AAAA,UACL,SAAS,MAAM,2BAA2B;AAAA,UAC1C,WAAU;AAAA,UACV,cAAY,EAAE,4BAA4B;AAAA,UAE1C;AAAA,gCAAC,KAAE,WAAU,eAAc,eAAY,QAAO;AAAA,YAC7C,EAAE,4BAA4B;AAAA;AAAA;AAAA,MACjC;AAAA,OACF;AAAA,KACF;AAEJ;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
const TTL_MS = 12e4;
|
|
4
|
+
let current = null;
|
|
5
|
+
const emitter = new EventTarget();
|
|
6
|
+
function now() {
|
|
7
|
+
return typeof performance !== "undefined" && performance.now ? Math.round(performance.timeOrigin + performance.now()) : Date.now();
|
|
8
|
+
}
|
|
9
|
+
function subscribe(listener) {
|
|
10
|
+
const wrapped = () => listener();
|
|
11
|
+
emitter.addEventListener("change", wrapped);
|
|
12
|
+
return () => emitter.removeEventListener("change", wrapped);
|
|
13
|
+
}
|
|
14
|
+
function emit() {
|
|
15
|
+
emitter.dispatchEvent(new Event("change"));
|
|
16
|
+
}
|
|
17
|
+
function normalizeInput(input) {
|
|
18
|
+
const label = typeof input.entityLabel === "string" && input.entityLabel.trim() ? input.entityLabel.trim() : input.entity;
|
|
19
|
+
return {
|
|
20
|
+
entity: input.entity,
|
|
21
|
+
entityLabel: label,
|
|
22
|
+
baseCount: typeof input.baseCount === "number" ? input.baseCount : null,
|
|
23
|
+
indexedCount: typeof input.indexedCount === "number" ? input.indexedCount : null,
|
|
24
|
+
scope: input.scope === "global" ? "global" : "scoped",
|
|
25
|
+
receivedAt: now()
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
function prune(stale) {
|
|
29
|
+
if (!stale) return null;
|
|
30
|
+
const age = now() - stale.receivedAt;
|
|
31
|
+
if (!Number.isFinite(age) || age > TTL_MS) return null;
|
|
32
|
+
return stale;
|
|
33
|
+
}
|
|
34
|
+
function getSnapshot() {
|
|
35
|
+
current = prune(current);
|
|
36
|
+
return current;
|
|
37
|
+
}
|
|
38
|
+
function usePartialIndexWarning() {
|
|
39
|
+
return React.useSyncExternalStore(
|
|
40
|
+
subscribe,
|
|
41
|
+
() => getSnapshot(),
|
|
42
|
+
() => null
|
|
43
|
+
);
|
|
44
|
+
}
|
|
45
|
+
function pushPartialIndexWarning(input) {
|
|
46
|
+
if (typeof window === "undefined") return;
|
|
47
|
+
if (!input.entity) return;
|
|
48
|
+
const next = normalizeInput(input);
|
|
49
|
+
current = next;
|
|
50
|
+
emit();
|
|
51
|
+
}
|
|
52
|
+
function dismissPartialIndexWarning() {
|
|
53
|
+
if (typeof window === "undefined") return;
|
|
54
|
+
current = null;
|
|
55
|
+
emit();
|
|
56
|
+
}
|
|
57
|
+
export {
|
|
58
|
+
dismissPartialIndexWarning,
|
|
59
|
+
pushPartialIndexWarning,
|
|
60
|
+
usePartialIndexWarning
|
|
61
|
+
};
|
|
62
|
+
//# sourceMappingURL=store.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/backend/indexes/store.ts"],
|
|
4
|
+
"sourcesContent": ["\"use client\"\nimport * as React from 'react'\n\nexport type PartialIndexNotice = {\n entity: string\n entityLabel: string\n baseCount: number | null\n indexedCount: number | null\n scope: 'scoped' | 'global'\n receivedAt: number\n}\n\ntype PartialIndexInput = {\n entity: string\n entityLabel?: string\n baseCount?: number | null\n indexedCount?: number | null\n scope?: 'scoped' | 'global'\n}\n\nconst TTL_MS = 120_000\n\nlet current: PartialIndexNotice | null = null\nconst emitter = new EventTarget()\n\nfunction now(): number {\n return typeof performance !== 'undefined' && performance.now\n ? Math.round(performance.timeOrigin + performance.now())\n : Date.now()\n}\n\nfunction subscribe(listener: () => void) {\n const wrapped = () => listener()\n emitter.addEventListener('change', wrapped)\n return () => emitter.removeEventListener('change', wrapped)\n}\n\nfunction emit() {\n emitter.dispatchEvent(new Event('change'))\n}\n\nfunction normalizeInput(input: PartialIndexInput): PartialIndexNotice {\n const label = typeof input.entityLabel === 'string' && input.entityLabel.trim()\n ? input.entityLabel.trim()\n : input.entity\n return {\n entity: input.entity,\n entityLabel: label,\n baseCount: typeof input.baseCount === 'number' ? input.baseCount : null,\n indexedCount: typeof input.indexedCount === 'number' ? input.indexedCount : null,\n scope: input.scope === 'global' ? 'global' : 'scoped',\n receivedAt: now(),\n }\n}\n\nfunction prune(stale: PartialIndexNotice | null): PartialIndexNotice | null {\n if (!stale) return null\n const age = now() - stale.receivedAt\n if (!Number.isFinite(age) || age > TTL_MS) return null\n return stale\n}\n\nfunction getSnapshot(): PartialIndexNotice | null {\n current = prune(current)\n return current\n}\n\nexport function usePartialIndexWarning(): PartialIndexNotice | null {\n return React.useSyncExternalStore(\n subscribe,\n () => getSnapshot(),\n () => null,\n )\n}\n\nexport function pushPartialIndexWarning(input: PartialIndexInput) {\n if (typeof window === 'undefined') return\n if (!input.entity) return\n const next = normalizeInput(input)\n current = next\n emit()\n}\n\nexport function dismissPartialIndexWarning() {\n if (typeof window === 'undefined') return\n current = null\n emit()\n}\n"],
|
|
5
|
+
"mappings": ";AACA,YAAY,WAAW;AAmBvB,MAAM,SAAS;AAEf,IAAI,UAAqC;AACzC,MAAM,UAAU,IAAI,YAAY;AAEhC,SAAS,MAAc;AACrB,SAAO,OAAO,gBAAgB,eAAe,YAAY,MACrD,KAAK,MAAM,YAAY,aAAa,YAAY,IAAI,CAAC,IACrD,KAAK,IAAI;AACf;AAEA,SAAS,UAAU,UAAsB;AACvC,QAAM,UAAU,MAAM,SAAS;AAC/B,UAAQ,iBAAiB,UAAU,OAAO;AAC1C,SAAO,MAAM,QAAQ,oBAAoB,UAAU,OAAO;AAC5D;AAEA,SAAS,OAAO;AACd,UAAQ,cAAc,IAAI,MAAM,QAAQ,CAAC;AAC3C;AAEA,SAAS,eAAe,OAA8C;AACpE,QAAM,QAAQ,OAAO,MAAM,gBAAgB,YAAY,MAAM,YAAY,KAAK,IAC1E,MAAM,YAAY,KAAK,IACvB,MAAM;AACV,SAAO;AAAA,IACL,QAAQ,MAAM;AAAA,IACd,aAAa;AAAA,IACb,WAAW,OAAO,MAAM,cAAc,WAAW,MAAM,YAAY;AAAA,IACnE,cAAc,OAAO,MAAM,iBAAiB,WAAW,MAAM,eAAe;AAAA,IAC5E,OAAO,MAAM,UAAU,WAAW,WAAW;AAAA,IAC7C,YAAY,IAAI;AAAA,EAClB;AACF;AAEA,SAAS,MAAM,OAA6D;AAC1E,MAAI,CAAC,MAAO,QAAO;AACnB,QAAM,MAAM,IAAI,IAAI,MAAM;AAC1B,MAAI,CAAC,OAAO,SAAS,GAAG,KAAK,MAAM,OAAQ,QAAO;AAClD,SAAO;AACT;AAEA,SAAS,cAAyC;AAChD,YAAU,MAAM,OAAO;AACvB,SAAO;AACT;AAEO,SAAS,yBAAoD;AAClE,SAAO,MAAM;AAAA,IACX;AAAA,IACA,MAAM,YAAY;AAAA,IAClB,MAAM;AAAA,EACR;AACF;AAEO,SAAS,wBAAwB,OAA0B;AAChE,MAAI,OAAO,WAAW,YAAa;AACnC,MAAI,CAAC,MAAM,OAAQ;AACnB,QAAM,OAAO,eAAe,KAAK;AACjC,YAAU;AACV,OAAK;AACP;AAEO,SAAS,6BAA6B;AAC3C,MAAI,OAAO,WAAW,YAAa;AACnC,YAAU;AACV,OAAK;AACP;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { Fragment, jsx } from "react/jsx-runtime";
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
import { loadInjectionWidgetsForSpot } from "@open-mercato/shared/modules/widgets/injection-loader";
|
|
5
|
+
function useInjectionWidgets(spotId, options) {
|
|
6
|
+
const [widgets, setWidgets] = React.useState([]);
|
|
7
|
+
const [loading, setLoading] = React.useState(true);
|
|
8
|
+
const [error, setError] = React.useState(null);
|
|
9
|
+
const loadedRef = React.useRef(false);
|
|
10
|
+
React.useEffect(() => {
|
|
11
|
+
if (!spotId) {
|
|
12
|
+
setWidgets([]);
|
|
13
|
+
setLoading(false);
|
|
14
|
+
setError(null);
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
let mounted = true;
|
|
18
|
+
const load = async () => {
|
|
19
|
+
try {
|
|
20
|
+
setLoading(true);
|
|
21
|
+
setError(null);
|
|
22
|
+
const loaded = await loadInjectionWidgetsForSpot(spotId);
|
|
23
|
+
if (!mounted) return;
|
|
24
|
+
const widgetList = loaded.map((w) => ({
|
|
25
|
+
widgetId: w.metadata.id,
|
|
26
|
+
module: w,
|
|
27
|
+
moduleId: w.moduleId,
|
|
28
|
+
key: w.key,
|
|
29
|
+
placement: w.placement
|
|
30
|
+
}));
|
|
31
|
+
setWidgets(widgetList);
|
|
32
|
+
if (!loadedRef.current && options?.triggerOnLoad) {
|
|
33
|
+
loadedRef.current = true;
|
|
34
|
+
for (const widget of widgetList) {
|
|
35
|
+
if (widget.module.eventHandlers?.onLoad) {
|
|
36
|
+
try {
|
|
37
|
+
await widget.module.eventHandlers.onLoad(options.context);
|
|
38
|
+
options.onEvent?.("onLoad", widget.widgetId);
|
|
39
|
+
} catch (err) {
|
|
40
|
+
console.error(`[InjectionSpot] Error in onLoad for widget ${widget.widgetId}:`, err);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
} catch (err) {
|
|
46
|
+
if (!mounted) return;
|
|
47
|
+
console.error(`[InjectionSpot] Failed to load widgets for spot ${spotId}:`, err);
|
|
48
|
+
setError(err instanceof Error ? err.message : String(err));
|
|
49
|
+
} finally {
|
|
50
|
+
if (mounted) setLoading(false);
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
load();
|
|
54
|
+
return () => {
|
|
55
|
+
mounted = false;
|
|
56
|
+
};
|
|
57
|
+
}, [spotId, options?.context, options?.triggerOnLoad, options?.onEvent]);
|
|
58
|
+
return { widgets, loading, error };
|
|
59
|
+
}
|
|
60
|
+
function InjectionSpot({
|
|
61
|
+
spotId,
|
|
62
|
+
context,
|
|
63
|
+
data,
|
|
64
|
+
onDataChange,
|
|
65
|
+
disabled,
|
|
66
|
+
onEvent,
|
|
67
|
+
widgetsOverride
|
|
68
|
+
}) {
|
|
69
|
+
const useSpotId = widgetsOverride ? null : spotId;
|
|
70
|
+
const { widgets, loading, error } = useInjectionWidgets(useSpotId, {
|
|
71
|
+
context,
|
|
72
|
+
triggerOnLoad: !widgetsOverride,
|
|
73
|
+
onEvent: onEvent ? (event, id) => onEvent(event, id) : void 0
|
|
74
|
+
});
|
|
75
|
+
const effectiveWidgets = widgetsOverride ?? widgets;
|
|
76
|
+
const effectiveLoading = widgetsOverride ? false : loading;
|
|
77
|
+
const effectiveError = widgetsOverride ? null : error;
|
|
78
|
+
if (effectiveLoading) {
|
|
79
|
+
return null;
|
|
80
|
+
}
|
|
81
|
+
if (effectiveError) {
|
|
82
|
+
console.error(`[InjectionSpot] Error loading widgets for spot ${spotId}:`, effectiveError);
|
|
83
|
+
return null;
|
|
84
|
+
}
|
|
85
|
+
if (effectiveWidgets.length === 0) {
|
|
86
|
+
return null;
|
|
87
|
+
}
|
|
88
|
+
return /* @__PURE__ */ jsx(Fragment, { children: effectiveWidgets.map((widget) => {
|
|
89
|
+
const { Widget } = widget.module;
|
|
90
|
+
return /* @__PURE__ */ jsx(
|
|
91
|
+
Widget,
|
|
92
|
+
{
|
|
93
|
+
context,
|
|
94
|
+
data,
|
|
95
|
+
onDataChange,
|
|
96
|
+
disabled
|
|
97
|
+
},
|
|
98
|
+
widget.widgetId
|
|
99
|
+
);
|
|
100
|
+
}) });
|
|
101
|
+
}
|
|
102
|
+
function useInjectionSpotEvents(spotId, prefetchedWidgets) {
|
|
103
|
+
const [widgets, setWidgets] = React.useState([]);
|
|
104
|
+
React.useEffect(() => {
|
|
105
|
+
if (prefetchedWidgets && prefetchedWidgets.length) {
|
|
106
|
+
setWidgets(prefetchedWidgets);
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
let mounted = true;
|
|
110
|
+
const load = async () => {
|
|
111
|
+
try {
|
|
112
|
+
const loaded = await loadInjectionWidgetsForSpot(spotId);
|
|
113
|
+
if (!mounted) return;
|
|
114
|
+
setWidgets(
|
|
115
|
+
loaded.map((w) => ({
|
|
116
|
+
widgetId: w.metadata.id,
|
|
117
|
+
module: w,
|
|
118
|
+
moduleId: w.moduleId,
|
|
119
|
+
key: w.key,
|
|
120
|
+
placement: w.placement
|
|
121
|
+
}))
|
|
122
|
+
);
|
|
123
|
+
} catch (err) {
|
|
124
|
+
console.error(`[useInjectionSpotEvents] Failed to load widgets for spot ${spotId}:`, err);
|
|
125
|
+
}
|
|
126
|
+
};
|
|
127
|
+
load();
|
|
128
|
+
return () => {
|
|
129
|
+
mounted = false;
|
|
130
|
+
};
|
|
131
|
+
}, [spotId, prefetchedWidgets]);
|
|
132
|
+
const triggerEvent = React.useCallback(
|
|
133
|
+
async (event, data, context) => {
|
|
134
|
+
const normalizeBeforeSave = (result) => {
|
|
135
|
+
if (result === false) return { ok: false };
|
|
136
|
+
if (result === true || typeof result === "undefined") return { ok: true };
|
|
137
|
+
if (result && typeof result === "object") {
|
|
138
|
+
const ok = typeof result.ok === "boolean" ? result.ok : true;
|
|
139
|
+
const message = typeof result.message === "string" ? result.message : void 0;
|
|
140
|
+
const fieldErrors = result.fieldErrors && typeof result.fieldErrors === "object" ? Object.fromEntries(
|
|
141
|
+
Object.entries(result.fieldErrors).map(([key, value]) => [key, String(value)])
|
|
142
|
+
) : void 0;
|
|
143
|
+
return { ok, message, fieldErrors };
|
|
144
|
+
}
|
|
145
|
+
return { ok: true };
|
|
146
|
+
};
|
|
147
|
+
for (const widget of widgets) {
|
|
148
|
+
const handler = widget.module.eventHandlers?.[event];
|
|
149
|
+
if (handler) {
|
|
150
|
+
try {
|
|
151
|
+
const result = await handler(data, context);
|
|
152
|
+
if (event === "onBeforeSave") {
|
|
153
|
+
const normalized = normalizeBeforeSave(result);
|
|
154
|
+
if (!normalized.ok) {
|
|
155
|
+
console.log(`[useInjectionSpotEvents] Widget ${widget.widgetId} prevented ${event}`);
|
|
156
|
+
return normalized;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
} catch (err) {
|
|
160
|
+
console.error(`[useInjectionSpotEvents] Error in ${event} for widget ${widget.widgetId}:`, err);
|
|
161
|
+
if (event === "onBeforeSave") {
|
|
162
|
+
const message = err instanceof Error ? err.message || "Validation blocked" : typeof err === "string" ? err : void 0;
|
|
163
|
+
return { ok: false, message };
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
return { ok: true };
|
|
169
|
+
},
|
|
170
|
+
[widgets]
|
|
171
|
+
);
|
|
172
|
+
return { triggerEvent, widgets };
|
|
173
|
+
}
|
|
174
|
+
export {
|
|
175
|
+
InjectionSpot,
|
|
176
|
+
useInjectionSpotEvents,
|
|
177
|
+
useInjectionWidgets
|
|
178
|
+
};
|
|
179
|
+
//# sourceMappingURL=InjectionSpot.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/backend/injection/InjectionSpot.tsx"],
|
|
4
|
+
"sourcesContent": ["\"use client\"\nimport * as React from 'react'\nimport type {\n InjectionSpotId,\n InjectionWidgetModule,\n WidgetInjectionEventHandlers,\n WidgetBeforeSaveResult,\n} from '@open-mercato/shared/modules/widgets/injection'\nimport { loadInjectionWidgetsForSpot, type LoadedInjectionWidget } from '@open-mercato/shared/modules/widgets/injection-loader'\n\nexport type InjectionSpotProps<TContext = unknown, TData = unknown> = {\n spotId: InjectionSpotId\n context: TContext\n data?: TData\n onDataChange?: (data: TData) => void\n disabled?: boolean\n onEvent?: (event: 'onLoad' | 'onBeforeSave' | 'onSave' | 'onAfterSave', widgetId: string) => void\n widgetsOverride?: LoadedWidget[]\n}\n\ntype LoadedWidget = {\n widgetId: string\n module: InjectionWidgetModule<any, any>\n moduleId: string\n key: string\n placement?: LoadedInjectionWidget['placement']\n}\n\nexport function useInjectionWidgets<TContext = unknown>(\n spotId: InjectionSpotId | null | undefined,\n options?: {\n context?: TContext\n triggerOnLoad?: boolean\n onEvent?: (event: 'onLoad', widgetId: string) => void\n }\n) {\n const [widgets, setWidgets] = React.useState<LoadedWidget[]>([])\n const [loading, setLoading] = React.useState(true)\n const [error, setError] = React.useState<string | null>(null)\n const loadedRef = React.useRef(false)\n\n React.useEffect(() => {\n if (!spotId) {\n setWidgets([])\n setLoading(false)\n setError(null)\n return\n }\n let mounted = true\n const load = async () => {\n try {\n setLoading(true)\n setError(null)\n const loaded = await loadInjectionWidgetsForSpot(spotId)\n if (!mounted) return\n const widgetList: LoadedWidget[] = loaded.map((w) => ({\n widgetId: w.metadata.id,\n module: w,\n moduleId: w.moduleId,\n key: w.key,\n placement: w.placement,\n }))\n setWidgets(widgetList)\n \n // Trigger onLoad for all widgets\n if (!loadedRef.current && options?.triggerOnLoad) {\n loadedRef.current = true\n for (const widget of widgetList) {\n if (widget.module.eventHandlers?.onLoad) {\n try {\n await widget.module.eventHandlers.onLoad(options.context as TContext)\n options.onEvent?.('onLoad', widget.widgetId)\n } catch (err) {\n console.error(`[InjectionSpot] Error in onLoad for widget ${widget.widgetId}:`, err)\n }\n }\n }\n }\n } catch (err) {\n if (!mounted) return\n console.error(`[InjectionSpot] Failed to load widgets for spot ${spotId}:`, err)\n setError(err instanceof Error ? err.message : String(err))\n } finally {\n if (mounted) setLoading(false)\n }\n }\n load()\n return () => {\n mounted = false\n }\n }, [spotId, options?.context, options?.triggerOnLoad, options?.onEvent])\n\n return { widgets, loading, error }\n}\n\nexport function InjectionSpot<TContext = unknown, TData = unknown>({\n spotId,\n context,\n data,\n onDataChange,\n disabled,\n onEvent,\n widgetsOverride,\n}: InjectionSpotProps<TContext, TData>) {\n const useSpotId = widgetsOverride ? null : spotId\n const { widgets, loading, error } = useInjectionWidgets<TContext>(useSpotId, {\n context,\n triggerOnLoad: !widgetsOverride,\n onEvent: onEvent ? (event, id) => onEvent(event, id) : undefined,\n })\n const effectiveWidgets = widgetsOverride ?? widgets\n const effectiveLoading = widgetsOverride ? false : loading\n const effectiveError = widgetsOverride ? null : error\n\n if (effectiveLoading) {\n return null\n }\n\n if (effectiveError) {\n console.error(`[InjectionSpot] Error loading widgets for spot ${spotId}:`, effectiveError)\n return null\n }\n\n if (effectiveWidgets.length === 0) {\n return null\n }\n\n return (\n <>\n {effectiveWidgets.map((widget) => {\n const { Widget } = widget.module\n return (\n <Widget\n key={widget.widgetId}\n context={context}\n data={data}\n onDataChange={onDataChange}\n disabled={disabled}\n />\n )\n })}\n </>\n )\n}\n\n/**\n * Hook to trigger injection widget events imperatively\n */\nexport function useInjectionSpotEvents<TContext = unknown, TData = unknown>(spotId: InjectionSpotId, prefetchedWidgets?: LoadedWidget[]) {\n const [widgets, setWidgets] = React.useState<LoadedWidget[]>([])\n\n React.useEffect(() => {\n if (prefetchedWidgets && prefetchedWidgets.length) {\n setWidgets(prefetchedWidgets)\n return\n }\n let mounted = true\n const load = async () => {\n try {\n const loaded = await loadInjectionWidgetsForSpot(spotId)\n if (!mounted) return\n setWidgets(\n loaded.map((w) => ({\n widgetId: w.metadata.id,\n module: w,\n moduleId: w.moduleId,\n key: w.key,\n placement: w.placement,\n }))\n )\n } catch (err) {\n console.error(`[useInjectionSpotEvents] Failed to load widgets for spot ${spotId}:`, err)\n }\n }\n load()\n return () => {\n mounted = false\n }\n }, [spotId, prefetchedWidgets])\n\n const triggerEvent = React.useCallback(\n async (\n event: keyof WidgetInjectionEventHandlers<TContext, TData>,\n data: TData,\n context: TContext\n ): Promise<{ ok: boolean; message?: string; fieldErrors?: Record<string, string> }> => {\n const normalizeBeforeSave = (result: WidgetBeforeSaveResult): { ok: boolean; message?: string; fieldErrors?: Record<string, string> } => {\n if (result === false) return { ok: false }\n if (result === true || typeof result === 'undefined') return { ok: true }\n if (result && typeof result === 'object') {\n const ok = typeof result.ok === 'boolean' ? result.ok : true\n const message = typeof result.message === 'string' ? result.message : undefined\n const fieldErrors =\n result.fieldErrors && typeof result.fieldErrors === 'object'\n ? Object.fromEntries(\n Object.entries(result.fieldErrors).map(([key, value]) => [key, String(value)]),\n )\n : undefined\n return { ok, message, fieldErrors }\n }\n return { ok: true }\n }\n\n for (const widget of widgets) {\n const handler = widget.module.eventHandlers?.[event]\n if (handler) {\n try {\n const result = await (handler as any)(data, context)\n if (event === 'onBeforeSave') {\n const normalized = normalizeBeforeSave(result as WidgetBeforeSaveResult)\n if (!normalized.ok) {\n console.log(`[useInjectionSpotEvents] Widget ${widget.widgetId} prevented ${event}`)\n return normalized\n }\n }\n } catch (err) {\n console.error(`[useInjectionSpotEvents] Error in ${event} for widget ${widget.widgetId}:`, err)\n if (event === 'onBeforeSave') {\n const message =\n err instanceof Error\n ? err.message || 'Validation blocked'\n : typeof err === 'string'\n ? err\n : undefined\n return { ok: false, message }\n }\n }\n }\n }\n return { ok: true }\n },\n [widgets]\n )\n\n return { triggerEvent, widgets }\n}\n"],
|
|
5
|
+
"mappings": ";AAgII,mBAIM,WAJN;AA/HJ,YAAY,WAAW;AAOvB,SAAS,mCAA+D;AAoBjE,SAAS,oBACd,QACA,SAKA;AACA,QAAM,CAAC,SAAS,UAAU,IAAI,MAAM,SAAyB,CAAC,CAAC;AAC/D,QAAM,CAAC,SAAS,UAAU,IAAI,MAAM,SAAS,IAAI;AACjD,QAAM,CAAC,OAAO,QAAQ,IAAI,MAAM,SAAwB,IAAI;AAC5D,QAAM,YAAY,MAAM,OAAO,KAAK;AAEpC,QAAM,UAAU,MAAM;AACpB,QAAI,CAAC,QAAQ;AACX,iBAAW,CAAC,CAAC;AACb,iBAAW,KAAK;AAChB,eAAS,IAAI;AACb;AAAA,IACF;AACA,QAAI,UAAU;AACd,UAAM,OAAO,YAAY;AACvB,UAAI;AACF,mBAAW,IAAI;AACf,iBAAS,IAAI;AACb,cAAM,SAAS,MAAM,4BAA4B,MAAM;AACvD,YAAI,CAAC,QAAS;AACd,cAAM,aAA6B,OAAO,IAAI,CAAC,OAAO;AAAA,UACpD,UAAU,EAAE,SAAS;AAAA,UACrB,QAAQ;AAAA,UACR,UAAU,EAAE;AAAA,UACZ,KAAK,EAAE;AAAA,UACP,WAAW,EAAE;AAAA,QACf,EAAE;AACF,mBAAW,UAAU;AAGrB,YAAI,CAAC,UAAU,WAAW,SAAS,eAAe;AAChD,oBAAU,UAAU;AACpB,qBAAW,UAAU,YAAY;AAC/B,gBAAI,OAAO,OAAO,eAAe,QAAQ;AACvC,kBAAI;AACF,sBAAM,OAAO,OAAO,cAAc,OAAO,QAAQ,OAAmB;AACpE,wBAAQ,UAAU,UAAU,OAAO,QAAQ;AAAA,cAC7C,SAAS,KAAK;AACZ,wBAAQ,MAAM,8CAA8C,OAAO,QAAQ,KAAK,GAAG;AAAA,cACrF;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,MACF,SAAS,KAAK;AACZ,YAAI,CAAC,QAAS;AACd,gBAAQ,MAAM,mDAAmD,MAAM,KAAK,GAAG;AAC/E,iBAAS,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC;AAAA,MAC3D,UAAE;AACA,YAAI,QAAS,YAAW,KAAK;AAAA,MAC/B;AAAA,IACF;AACA,SAAK;AACL,WAAO,MAAM;AACX,gBAAU;AAAA,IACZ;AAAA,EACF,GAAG,CAAC,QAAQ,SAAS,SAAS,SAAS,eAAe,SAAS,OAAO,CAAC;AAEvE,SAAO,EAAE,SAAS,SAAS,MAAM;AACnC;AAEO,SAAS,cAAmD;AAAA,EACjE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAwC;AACtC,QAAM,YAAY,kBAAkB,OAAO;AAC3C,QAAM,EAAE,SAAS,SAAS,MAAM,IAAI,oBAA8B,WAAW;AAAA,IAC3E;AAAA,IACA,eAAe,CAAC;AAAA,IAChB,SAAS,UAAU,CAAC,OAAO,OAAO,QAAQ,OAAO,EAAE,IAAI;AAAA,EACzD,CAAC;AACD,QAAM,mBAAmB,mBAAmB;AAC5C,QAAM,mBAAmB,kBAAkB,QAAQ;AACnD,QAAM,iBAAiB,kBAAkB,OAAO;AAEhD,MAAI,kBAAkB;AACpB,WAAO;AAAA,EACT;AAEA,MAAI,gBAAgB;AAClB,YAAQ,MAAM,kDAAkD,MAAM,KAAK,cAAc;AACzF,WAAO;AAAA,EACT;AAEA,MAAI,iBAAiB,WAAW,GAAG;AACjC,WAAO;AAAA,EACT;AAEA,SACE,gCACG,2BAAiB,IAAI,CAAC,WAAW;AAChC,UAAM,EAAE,OAAO,IAAI,OAAO;AAC1B,WACE;AAAA,MAAC;AAAA;AAAA,QAEC;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA;AAAA,MAJK,OAAO;AAAA,IAKd;AAAA,EAEJ,CAAC,GACH;AAEJ;AAKO,SAAS,uBAA4D,QAAyB,mBAAoC;AACvI,QAAM,CAAC,SAAS,UAAU,IAAI,MAAM,SAAyB,CAAC,CAAC;AAE/D,QAAM,UAAU,MAAM;AACpB,QAAI,qBAAqB,kBAAkB,QAAQ;AACjD,iBAAW,iBAAiB;AAC5B;AAAA,IACF;AACA,QAAI,UAAU;AACd,UAAM,OAAO,YAAY;AACvB,UAAI;AACF,cAAM,SAAS,MAAM,4BAA4B,MAAM;AACvD,YAAI,CAAC,QAAS;AACd;AAAA,UACE,OAAO,IAAI,CAAC,OAAO;AAAA,YACjB,UAAU,EAAE,SAAS;AAAA,YACrB,QAAQ;AAAA,YACR,UAAU,EAAE;AAAA,YACZ,KAAK,EAAE;AAAA,YACP,WAAW,EAAE;AAAA,UACf,EAAE;AAAA,QACJ;AAAA,MACF,SAAS,KAAK;AACZ,gBAAQ,MAAM,4DAA4D,MAAM,KAAK,GAAG;AAAA,MAC1F;AAAA,IACF;AACA,SAAK;AACL,WAAO,MAAM;AACX,gBAAU;AAAA,IACZ;AAAA,EACF,GAAG,CAAC,QAAQ,iBAAiB,CAAC;AAE9B,QAAM,eAAe,MAAM;AAAA,IACzB,OACE,OACA,MACA,YACqF;AACrF,YAAM,sBAAsB,CAAC,WAA4G;AACvI,YAAI,WAAW,MAAO,QAAO,EAAE,IAAI,MAAM;AACzC,YAAI,WAAW,QAAQ,OAAO,WAAW,YAAa,QAAO,EAAE,IAAI,KAAK;AACxE,YAAI,UAAU,OAAO,WAAW,UAAU;AACxC,gBAAM,KAAK,OAAO,OAAO,OAAO,YAAY,OAAO,KAAK;AACxD,gBAAM,UAAU,OAAO,OAAO,YAAY,WAAW,OAAO,UAAU;AACtE,gBAAM,cACJ,OAAO,eAAe,OAAO,OAAO,gBAAgB,WAChD,OAAO;AAAA,YACL,OAAO,QAAQ,OAAO,WAAW,EAAE,IAAI,CAAC,CAAC,KAAK,KAAK,MAAM,CAAC,KAAK,OAAO,KAAK,CAAC,CAAC;AAAA,UAC/E,IACA;AACN,iBAAO,EAAE,IAAI,SAAS,YAAY;AAAA,QACpC;AACA,eAAO,EAAE,IAAI,KAAK;AAAA,MACpB;AAEA,iBAAW,UAAU,SAAS;AAC5B,cAAM,UAAU,OAAO,OAAO,gBAAgB,KAAK;AACnD,YAAI,SAAS;AACX,cAAI;AACF,kBAAM,SAAS,MAAO,QAAgB,MAAM,OAAO;AACnD,gBAAI,UAAU,gBAAgB;AAC5B,oBAAM,aAAa,oBAAoB,MAAgC;AACvE,kBAAI,CAAC,WAAW,IAAI;AAClB,wBAAQ,IAAI,mCAAmC,OAAO,QAAQ,cAAc,KAAK,EAAE;AACnF,uBAAO;AAAA,cACT;AAAA,YACF;AAAA,UACF,SAAS,KAAK;AACZ,oBAAQ,MAAM,qCAAqC,KAAK,eAAe,OAAO,QAAQ,KAAK,GAAG;AAC9F,gBAAI,UAAU,gBAAgB;AAC5B,oBAAM,UACJ,eAAe,QACX,IAAI,WAAW,uBACf,OAAO,QAAQ,WACb,MACA;AACR,qBAAO,EAAE,IAAI,OAAO,QAAQ;AAAA,YAC9B;AAAA,UACF;AAAA,QACF;AAAA,MACF;AACA,aAAO,EAAE,IAAI,KAAK;AAAA,IACpB;AAAA,IACA,CAAC,OAAO;AAAA,EACV;AAEA,SAAO,EAAE,cAAc,QAAQ;AACjC;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { InjectionSpot } from "./InjectionSpot.js";
|
|
3
|
+
function normalizePath(path) {
|
|
4
|
+
const trimmed = path.replace(/\?.*$/, "").replace(/\/+$/, "");
|
|
5
|
+
const withoutLeading = trimmed.startsWith("/") ? trimmed.slice(1) : trimmed;
|
|
6
|
+
const safe = withoutLeading.length ? withoutLeading : "root";
|
|
7
|
+
return safe.replace(/[^a-zA-Z0-9]+/g, ":");
|
|
8
|
+
}
|
|
9
|
+
function PageInjectionBoundary({
|
|
10
|
+
path,
|
|
11
|
+
context,
|
|
12
|
+
children
|
|
13
|
+
}) {
|
|
14
|
+
const handle = normalizePath(path || "/");
|
|
15
|
+
const beforeSpotId = `admin.page:${handle}:before`;
|
|
16
|
+
const afterSpotId = `admin.page:${handle}:after`;
|
|
17
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
18
|
+
/* @__PURE__ */ jsx(InjectionSpot, { spotId: beforeSpotId, context: context ?? { path } }),
|
|
19
|
+
children,
|
|
20
|
+
/* @__PURE__ */ jsx(InjectionSpot, { spotId: afterSpotId, context: context ?? { path } })
|
|
21
|
+
] });
|
|
22
|
+
}
|
|
23
|
+
export {
|
|
24
|
+
PageInjectionBoundary
|
|
25
|
+
};
|
|
26
|
+
//# sourceMappingURL=PageInjectionBoundary.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/backend/injection/PageInjectionBoundary.tsx"],
|
|
4
|
+
"sourcesContent": ["import type { ReactNode } from 'react'\nimport { InjectionSpot } from './InjectionSpot'\n\nfunction normalizePath(path: string): string {\n const trimmed = path.replace(/\\?.*$/, '').replace(/\\/+$/, '')\n const withoutLeading = trimmed.startsWith('/') ? trimmed.slice(1) : trimmed\n const safe = withoutLeading.length ? withoutLeading : 'root'\n return safe.replace(/[^a-zA-Z0-9]+/g, ':')\n}\n\nexport function PageInjectionBoundary({\n path,\n context,\n children,\n}: {\n path: string\n context?: Record<string, unknown>\n children: ReactNode\n}) {\n const handle = normalizePath(path || '/')\n const beforeSpotId = `admin.page:${handle}:before`\n const afterSpotId = `admin.page:${handle}:after`\n\n return (\n <>\n <InjectionSpot spotId={beforeSpotId} context={context ?? { path }} />\n {children}\n <InjectionSpot spotId={afterSpotId} context={context ?? { path }} />\n </>\n )\n}\n"],
|
|
5
|
+
"mappings": "AAwBI,mBACE,KADF;AAvBJ,SAAS,qBAAqB;AAE9B,SAAS,cAAc,MAAsB;AAC3C,QAAM,UAAU,KAAK,QAAQ,SAAS,EAAE,EAAE,QAAQ,QAAQ,EAAE;AAC5D,QAAM,iBAAiB,QAAQ,WAAW,GAAG,IAAI,QAAQ,MAAM,CAAC,IAAI;AACpE,QAAM,OAAO,eAAe,SAAS,iBAAiB;AACtD,SAAO,KAAK,QAAQ,kBAAkB,GAAG;AAC3C;AAEO,SAAS,sBAAsB;AAAA,EACpC;AAAA,EACA;AAAA,EACA;AACF,GAIG;AACD,QAAM,SAAS,cAAc,QAAQ,GAAG;AACxC,QAAM,eAAe,cAAc,MAAM;AACzC,QAAM,cAAc,cAAc,MAAM;AAExC,SACE,iCACE;AAAA,wBAAC,iBAAc,QAAQ,cAAc,SAAS,WAAW,EAAE,KAAK,GAAG;AAAA,IAClE;AAAA,IACD,oBAAC,iBAAc,QAAQ,aAAa,SAAS,WAAW,EAAE,KAAK,GAAG;AAAA,KACpE;AAEJ;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
function generateCrudFormInjectionSpotId(formName) {
|
|
2
|
+
return `crud-form:${formName}`;
|
|
3
|
+
}
|
|
4
|
+
const CrudFormInjectionSpots = {
|
|
5
|
+
/**
|
|
6
|
+
* Generate injection spot ID for before the form fields
|
|
7
|
+
*/
|
|
8
|
+
beforeFields: (formName) => `${generateCrudFormInjectionSpotId(formName)}:before-fields`,
|
|
9
|
+
/**
|
|
10
|
+
* Generate injection spot ID for after the form fields
|
|
11
|
+
*/
|
|
12
|
+
afterFields: (formName) => `${generateCrudFormInjectionSpotId(formName)}:after-fields`,
|
|
13
|
+
/**
|
|
14
|
+
* Generate injection spot ID for the header area
|
|
15
|
+
*/
|
|
16
|
+
header: (formName) => `${generateCrudFormInjectionSpotId(formName)}:header`,
|
|
17
|
+
/**
|
|
18
|
+
* Generate injection spot ID for the footer/actions area
|
|
19
|
+
*/
|
|
20
|
+
footer: (formName) => `${generateCrudFormInjectionSpotId(formName)}:footer`
|
|
21
|
+
};
|
|
22
|
+
export {
|
|
23
|
+
CrudFormInjectionSpots,
|
|
24
|
+
generateCrudFormInjectionSpotId
|
|
25
|
+
};
|
|
26
|
+
//# sourceMappingURL=helpers.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/backend/injection/helpers.ts"],
|
|
4
|
+
"sourcesContent": ["import type { InjectionSpotId } from '@open-mercato/shared/modules/widgets/injection'\n\n/**\n * Generate a standard injection spot ID for CRUD forms\n * @param formName The name/identifier of the form (e.g., 'catalog.product', 'catalog.variant')\n * @returns A standardized injection spot ID\n */\nexport function generateCrudFormInjectionSpotId(formName: string): InjectionSpotId {\n return `crud-form:${formName}`\n}\n\n/**\n * Generate injection spot IDs for common CRUD form locations\n */\nexport const CrudFormInjectionSpots = {\n /**\n * Generate injection spot ID for before the form fields\n */\n beforeFields: (formName: string): InjectionSpotId => `${generateCrudFormInjectionSpotId(formName)}:before-fields`,\n \n /**\n * Generate injection spot ID for after the form fields\n */\n afterFields: (formName: string): InjectionSpotId => `${generateCrudFormInjectionSpotId(formName)}:after-fields`,\n \n /**\n * Generate injection spot ID for the header area\n */\n header: (formName: string): InjectionSpotId => `${generateCrudFormInjectionSpotId(formName)}:header`,\n \n /**\n * Generate injection spot ID for the footer/actions area\n */\n footer: (formName: string): InjectionSpotId => `${generateCrudFormInjectionSpotId(formName)}:footer`,\n}\n"],
|
|
5
|
+
"mappings": "AAOO,SAAS,gCAAgC,UAAmC;AACjF,SAAO,aAAa,QAAQ;AAC9B;AAKO,MAAM,yBAAyB;AAAA;AAAA;AAAA;AAAA,EAIpC,cAAc,CAAC,aAAsC,GAAG,gCAAgC,QAAQ,CAAC;AAAA;AAAA;AAAA;AAAA,EAKjG,aAAa,CAAC,aAAsC,GAAG,gCAAgC,QAAQ,CAAC;AAAA;AAAA;AAAA;AAAA,EAKhG,QAAQ,CAAC,aAAsC,GAAG,gCAAgC,QAAQ,CAAC;AAAA;AAAA;AAAA;AAAA,EAK3F,QAAQ,CAAC,aAAsC,GAAG,gCAAgC,QAAQ,CAAC;AAC7F;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
let _injectionWidgetEntries = null;
|
|
2
|
+
function registerInjectionWidgets(entries) {
|
|
3
|
+
if (_injectionWidgetEntries !== null && process.env.NODE_ENV === "development") {
|
|
4
|
+
console.debug("[Bootstrap] Injection widgets re-registered (this may occur during HMR)");
|
|
5
|
+
}
|
|
6
|
+
_injectionWidgetEntries = entries;
|
|
7
|
+
}
|
|
8
|
+
function getInjectionWidgets() {
|
|
9
|
+
if (!_injectionWidgetEntries) {
|
|
10
|
+
if (typeof window !== "undefined") {
|
|
11
|
+
return [];
|
|
12
|
+
}
|
|
13
|
+
throw new Error("[Bootstrap] Injection widgets not registered. Call registerInjectionWidgets() at bootstrap.");
|
|
14
|
+
}
|
|
15
|
+
return _injectionWidgetEntries;
|
|
16
|
+
}
|
|
17
|
+
let entriesPromise = null;
|
|
18
|
+
async function getEntries() {
|
|
19
|
+
if (!entriesPromise) {
|
|
20
|
+
const promise = Promise.resolve().then(() => getInjectionWidgets());
|
|
21
|
+
entriesPromise = promise.catch((err) => {
|
|
22
|
+
if (entriesPromise === promise) {
|
|
23
|
+
entriesPromise = null;
|
|
24
|
+
}
|
|
25
|
+
throw err;
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
return entriesPromise;
|
|
29
|
+
}
|
|
30
|
+
const cache = /* @__PURE__ */ new Map();
|
|
31
|
+
async function findEntry(loaderKey) {
|
|
32
|
+
const entries = await getEntries();
|
|
33
|
+
return entries.find((entry) => entry.key === loaderKey);
|
|
34
|
+
}
|
|
35
|
+
async function loadInjectionWidgetModule(loaderKey) {
|
|
36
|
+
const entry = await findEntry(loaderKey);
|
|
37
|
+
if (!entry) return null;
|
|
38
|
+
if (!cache.has(loaderKey)) {
|
|
39
|
+
cache.set(
|
|
40
|
+
loaderKey,
|
|
41
|
+
entry.loader().then((mod) => {
|
|
42
|
+
const candidate = mod;
|
|
43
|
+
const maybeDefault = mod.default;
|
|
44
|
+
return maybeDefault ?? candidate;
|
|
45
|
+
})
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
return cache.get(loaderKey) ?? null;
|
|
49
|
+
}
|
|
50
|
+
export {
|
|
51
|
+
getInjectionWidgets,
|
|
52
|
+
loadInjectionWidgetModule,
|
|
53
|
+
registerInjectionWidgets
|
|
54
|
+
};
|
|
55
|
+
//# sourceMappingURL=widgetRegistry.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/backend/injection/widgetRegistry.ts"],
|
|
4
|
+
"sourcesContent": ["import type { ModuleInjectionWidgetEntry } from '@open-mercato/shared/modules/registry'\nimport type { InjectionWidgetModule } from '@open-mercato/shared/modules/widgets/injection'\n\ntype Entry = ModuleInjectionWidgetEntry\n\n// Registration pattern for publishable packages\nlet _injectionWidgetEntries: Entry[] | null = null\n\nexport function registerInjectionWidgets(entries: Entry[]) {\n if (_injectionWidgetEntries !== null && process.env.NODE_ENV === 'development') {\n console.debug('[Bootstrap] Injection widgets re-registered (this may occur during HMR)')\n }\n _injectionWidgetEntries = entries\n}\n\nexport function getInjectionWidgets(): Entry[] {\n if (!_injectionWidgetEntries) {\n // On client-side, bootstrap doesn't run - return empty array gracefully\n if (typeof window !== 'undefined') {\n return []\n }\n throw new Error('[Bootstrap] Injection widgets not registered. Call registerInjectionWidgets() at bootstrap.')\n }\n return _injectionWidgetEntries\n}\n\nlet entriesPromise: Promise<Entry[]> | null = null\n\nasync function getEntries(): Promise<Entry[]> {\n if (!entriesPromise) {\n const promise = Promise.resolve().then(() => getInjectionWidgets())\n entriesPromise = promise.catch((err) => {\n // Clear cache on error so next call can retry after registration\n if (entriesPromise === promise) {\n entriesPromise = null\n }\n throw err\n })\n }\n return entriesPromise\n}\n\ntype LoadedWidgetModule = InjectionWidgetModule<any, any>\n\nconst cache = new Map<string, Promise<LoadedWidgetModule>>()\n\nasync function findEntry(loaderKey: string): Promise<Entry | undefined> {\n const entries = await getEntries()\n return entries.find((entry) => entry.key === loaderKey)\n}\n\nexport async function loadInjectionWidgetModule(loaderKey: string): Promise<LoadedWidgetModule | null> {\n const entry = await findEntry(loaderKey)\n if (!entry) return null\n if (!cache.has(loaderKey)) {\n cache.set(\n loaderKey,\n entry\n .loader()\n .then((mod) => {\n const candidate = mod as LoadedWidgetModule\n const maybeDefault = (mod as { default?: LoadedWidgetModule }).default\n return maybeDefault ?? candidate\n })\n )\n }\n return cache.get(loaderKey) ?? null\n}\n"],
|
|
5
|
+
"mappings": "AAMA,IAAI,0BAA0C;AAEvC,SAAS,yBAAyB,SAAkB;AACzD,MAAI,4BAA4B,QAAQ,QAAQ,IAAI,aAAa,eAAe;AAC9E,YAAQ,MAAM,yEAAyE;AAAA,EACzF;AACA,4BAA0B;AAC5B;AAEO,SAAS,sBAA+B;AAC7C,MAAI,CAAC,yBAAyB;AAE5B,QAAI,OAAO,WAAW,aAAa;AACjC,aAAO,CAAC;AAAA,IACV;AACA,UAAM,IAAI,MAAM,6FAA6F;AAAA,EAC/G;AACA,SAAO;AACT;AAEA,IAAI,iBAA0C;AAE9C,eAAe,aAA+B;AAC5C,MAAI,CAAC,gBAAgB;AACnB,UAAM,UAAU,QAAQ,QAAQ,EAAE,KAAK,MAAM,oBAAoB,CAAC;AAClE,qBAAiB,QAAQ,MAAM,CAAC,QAAQ;AAEtC,UAAI,mBAAmB,SAAS;AAC9B,yBAAiB;AAAA,MACnB;AACA,YAAM;AAAA,IACR,CAAC;AAAA,EACH;AACA,SAAO;AACT;AAIA,MAAM,QAAQ,oBAAI,IAAyC;AAE3D,eAAe,UAAU,WAA+C;AACtE,QAAM,UAAU,MAAM,WAAW;AACjC,SAAO,QAAQ,KAAK,CAAC,UAAU,MAAM,QAAQ,SAAS;AACxD;AAEA,eAAsB,0BAA0B,WAAuD;AACrG,QAAM,QAAQ,MAAM,UAAU,SAAS;AACvC,MAAI,CAAC,MAAO,QAAO;AACnB,MAAI,CAAC,MAAM,IAAI,SAAS,GAAG;AACzB,UAAM;AAAA,MACJ;AAAA,MACA,MACG,OAAO,EACP,KAAK,CAAC,QAAQ;AACb,cAAM,YAAY;AAClB,cAAM,eAAgB,IAAyC;AAC/D,eAAO,gBAAgB;AAAA,MACzB,CAAC;AAAA,IACL;AAAA,EACF;AACA,SAAO,MAAM,IAAI,SAAS,KAAK;AACjC;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|