@open-mercato/core 0.6.6-develop.6089.1.a7ed560528 → 0.6.6-develop.6121.1.5797a901b3
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/dist/generated/entities/catalog_product/index.js +52 -0
- package/dist/generated/entities/catalog_product/index.js.map +2 -2
- package/dist/generated/entities/catalog_product_variant/index.js +4 -0
- package/dist/generated/entities/catalog_product_variant/index.js.map +2 -2
- package/dist/generated/entity-fields-registry.js +28 -0
- package/dist/generated/entity-fields-registry.js.map +2 -2
- package/dist/modules/catalog/api/products/route.js +103 -33
- package/dist/modules/catalog/api/products/route.js.map +2 -2
- package/dist/modules/catalog/api/variants/route.js +4 -0
- package/dist/modules/catalog/api/variants/route.js.map +2 -2
- package/dist/modules/catalog/backend/catalog/products/[id]/page.js +46 -2
- package/dist/modules/catalog/backend/catalog/products/[id]/page.js.map +2 -2
- package/dist/modules/catalog/backend/catalog/products/[productId]/variants/[variantId]/page.js +4 -0
- package/dist/modules/catalog/backend/catalog/products/[productId]/variants/[variantId]/page.js.map +2 -2
- package/dist/modules/catalog/backend/catalog/products/[productId]/variants/create/page.js +2 -0
- package/dist/modules/catalog/backend/catalog/products/[productId]/variants/create/page.js.map +2 -2
- package/dist/modules/catalog/backend/catalog/products/create/page.js +42 -2
- package/dist/modules/catalog/backend/catalog/products/create/page.js.map +2 -2
- package/dist/modules/catalog/commands/products.js +251 -14
- package/dist/modules/catalog/commands/products.js.map +2 -2
- package/dist/modules/catalog/commands/variants.js +72 -1
- package/dist/modules/catalog/commands/variants.js.map +2 -2
- package/dist/modules/catalog/components/products/ProductComplianceSection.js +500 -0
- package/dist/modules/catalog/components/products/ProductComplianceSection.js.map +7 -0
- package/dist/modules/catalog/components/products/VariantBuilder.js +39 -1
- package/dist/modules/catalog/components/products/VariantBuilder.js.map +2 -2
- package/dist/modules/catalog/components/products/productForm.js +164 -2
- package/dist/modules/catalog/components/products/productForm.js.map +2 -2
- package/dist/modules/catalog/components/products/variantForm.js +2 -0
- package/dist/modules/catalog/components/products/variantForm.js.map +2 -2
- package/dist/modules/catalog/data/entities.js +93 -0
- package/dist/modules/catalog/data/entities.js.map +2 -2
- package/dist/modules/catalog/data/types.js +28 -0
- package/dist/modules/catalog/data/types.js.map +2 -2
- package/dist/modules/catalog/data/validators.js +100 -5
- package/dist/modules/catalog/data/validators.js.map +2 -2
- package/dist/modules/catalog/lib/gtin.js +61 -0
- package/dist/modules/catalog/lib/gtin.js.map +7 -0
- package/dist/modules/catalog/migrations/Migration20260611090000.js +17 -0
- package/dist/modules/catalog/migrations/Migration20260611090000.js.map +7 -0
- package/dist/modules/catalog/translations.js +1 -1
- package/dist/modules/catalog/translations.js.map +2 -2
- package/dist/modules/configs/api/cache/route.js +60 -10
- package/dist/modules/configs/api/cache/route.js.map +3 -3
- package/dist/modules/configs/components/CachePanel.js +52 -29
- package/dist/modules/configs/components/CachePanel.js.map +2 -2
- package/dist/modules/currencies/api/currencies/options/route.js +18 -4
- package/dist/modules/currencies/api/currencies/options/route.js.map +2 -2
- package/dist/modules/currencies/services/rateFetchingService.js +35 -18
- package/dist/modules/currencies/services/rateFetchingService.js.map +2 -2
- package/dist/modules/customer_accounts/backend/customer_accounts/users/[id]/page.js +16 -16
- package/dist/modules/customer_accounts/backend/customer_accounts/users/[id]/page.js.map +2 -2
- package/dist/modules/customer_accounts/backend/customer_accounts/users/page.js +1 -1
- package/dist/modules/customer_accounts/backend/customer_accounts/users/page.js.map +2 -2
- package/dist/modules/customers/backend/calendar/page.js +10 -0
- package/dist/modules/customers/backend/calendar/page.js.map +7 -0
- package/dist/modules/customers/backend/calendar/page.meta.js +25 -0
- package/dist/modules/customers/backend/calendar/page.meta.js.map +7 -0
- package/dist/modules/customers/cli.js +1 -0
- package/dist/modules/customers/cli.js.map +2 -2
- package/dist/modules/customers/components/calendar/AgendaList.js +182 -0
- package/dist/modules/customers/components/calendar/AgendaList.js.map +7 -0
- package/dist/modules/customers/components/calendar/CalendarEventEditor.js +331 -0
- package/dist/modules/customers/components/calendar/CalendarEventEditor.js.map +7 -0
- package/dist/modules/customers/components/calendar/CalendarFooter.js +48 -0
- package/dist/modules/customers/components/calendar/CalendarFooter.js.map +7 -0
- package/dist/modules/customers/components/calendar/CalendarHeader.js +36 -0
- package/dist/modules/customers/components/calendar/CalendarHeader.js.map +7 -0
- package/dist/modules/customers/components/calendar/CalendarScreen.js +516 -0
- package/dist/modules/customers/components/calendar/CalendarScreen.js.map +7 -0
- package/dist/modules/customers/components/calendar/CalendarSettingsModal.js +163 -0
- package/dist/modules/customers/components/calendar/CalendarSettingsModal.js.map +7 -0
- package/dist/modules/customers/components/calendar/CalendarTabs.js +60 -0
- package/dist/modules/customers/components/calendar/CalendarTabs.js.map +7 -0
- package/dist/modules/customers/components/calendar/CalendarToolbar.js +262 -0
- package/dist/modules/customers/components/calendar/CalendarToolbar.js.map +7 -0
- package/dist/modules/customers/components/calendar/EventBlock.js +149 -0
- package/dist/modules/customers/components/calendar/EventBlock.js.map +7 -0
- package/dist/modules/customers/components/calendar/EventPeekPopover.js +72 -0
- package/dist/modules/customers/components/calendar/EventPeekPopover.js.map +7 -0
- package/dist/modules/customers/components/calendar/MonthGrid.js +214 -0
- package/dist/modules/customers/components/calendar/MonthGrid.js.map +7 -0
- package/dist/modules/customers/components/calendar/ShortcutsDialog.js +44 -0
- package/dist/modules/customers/components/calendar/ShortcutsDialog.js.map +7 -0
- package/dist/modules/customers/components/calendar/TimeGrid.js +410 -0
- package/dist/modules/customers/components/calendar/TimeGrid.js.map +7 -0
- package/dist/modules/customers/components/calendar/UpcomingCards.js +175 -0
- package/dist/modules/customers/components/calendar/UpcomingCards.js.map +7 -0
- package/dist/modules/customers/components/calendar/editor/CategoryField.js +75 -0
- package/dist/modules/customers/components/calendar/editor/CategoryField.js.map +7 -0
- package/dist/modules/customers/components/calendar/editor/LocationField.js +30 -0
- package/dist/modules/customers/components/calendar/editor/LocationField.js.map +7 -0
- package/dist/modules/customers/components/calendar/editor/PeopleField.js +135 -0
- package/dist/modules/customers/components/calendar/editor/PeopleField.js.map +7 -0
- package/dist/modules/customers/components/calendar/editor/RelatedToField.js +218 -0
- package/dist/modules/customers/components/calendar/editor/RelatedToField.js.map +7 -0
- package/dist/modules/customers/components/calendar/editor/RepeatField.js +119 -0
- package/dist/modules/customers/components/calendar/editor/RepeatField.js.map +7 -0
- package/dist/modules/customers/components/calendar/editor/ScheduleSection.js +83 -0
- package/dist/modules/customers/components/calendar/editor/ScheduleSection.js.map +7 -0
- package/dist/modules/customers/components/calendar/editor/SegmentGroup.js +44 -0
- package/dist/modules/customers/components/calendar/editor/SegmentGroup.js.map +7 -0
- package/dist/modules/customers/components/calendar/editor/hooks.js +132 -0
- package/dist/modules/customers/components/calendar/editor/hooks.js.map +7 -0
- package/dist/modules/customers/components/calendar/editor/inputs.js +160 -0
- package/dist/modules/customers/components/calendar/editor/inputs.js.map +7 -0
- package/dist/modules/customers/components/calendar/editor/lookups.js +107 -0
- package/dist/modules/customers/components/calendar/editor/lookups.js.map +7 -0
- package/dist/modules/customers/components/calendar/types.js +30 -0
- package/dist/modules/customers/components/calendar/types.js.map +7 -0
- package/dist/modules/customers/components/calendar/useCalendarItems.js +131 -0
- package/dist/modules/customers/components/calendar/useCalendarItems.js.map +7 -0
- package/dist/modules/customers/components/calendar/useCalendarPreferences.js +41 -0
- package/dist/modules/customers/components/calendar/useCalendarPreferences.js.map +7 -0
- package/dist/modules/customers/lib/calendar/categories.js +28 -0
- package/dist/modules/customers/lib/calendar/categories.js.map +7 -0
- package/dist/modules/customers/lib/calendar/conflicts.js +72 -0
- package/dist/modules/customers/lib/calendar/conflicts.js.map +7 -0
- package/dist/modules/customers/lib/calendar/editorPayload.js +271 -0
- package/dist/modules/customers/lib/calendar/editorPayload.js.map +7 -0
- package/dist/modules/customers/lib/calendar/grid.js +48 -0
- package/dist/modules/customers/lib/calendar/grid.js.map +7 -0
- package/dist/modules/customers/lib/calendar/layout.js +39 -0
- package/dist/modules/customers/lib/calendar/layout.js.map +7 -0
- package/dist/modules/customers/lib/calendar/mapItem.js +79 -0
- package/dist/modules/customers/lib/calendar/mapItem.js.map +7 -0
- package/dist/modules/customers/lib/calendar/preferences.js +71 -0
- package/dist/modules/customers/lib/calendar/preferences.js.map +7 -0
- package/dist/modules/customers/lib/calendar/range.js +46 -0
- package/dist/modules/customers/lib/calendar/range.js.map +7 -0
- package/dist/modules/customers/lib/calendar/recurrence.js +113 -0
- package/dist/modules/customers/lib/calendar/recurrence.js.map +7 -0
- package/dist/modules/dashboards/services/widgetDataService.js +5 -5
- package/dist/modules/dashboards/services/widgetDataService.js.map +2 -2
- package/dist/modules/dictionaries/api/[dictionaryId]/entries/[entryId]/route.js +61 -1
- package/dist/modules/dictionaries/api/[dictionaryId]/entries/[entryId]/route.js.map +2 -2
- package/dist/modules/dictionaries/api/[dictionaryId]/entries/route.js +33 -1
- package/dist/modules/dictionaries/api/[dictionaryId]/entries/route.js.map +2 -2
- package/dist/modules/dictionaries/api/[dictionaryId]/route.js +61 -1
- package/dist/modules/dictionaries/api/[dictionaryId]/route.js.map +2 -2
- package/dist/modules/dictionaries/api/route.js +33 -1
- package/dist/modules/dictionaries/api/route.js.map +2 -2
- package/dist/modules/feature_toggles/lib/queries.js +36 -52
- package/dist/modules/feature_toggles/lib/queries.js.map +2 -2
- package/dist/modules/messages/commands/actions.js +81 -9
- package/dist/modules/messages/commands/actions.js.map +2 -2
- package/dist/modules/perspectives/api/[tableId]/[perspectiveId]/route.js +32 -1
- package/dist/modules/perspectives/api/[tableId]/[perspectiveId]/route.js.map +2 -2
- package/dist/modules/perspectives/api/[tableId]/roles/[roleId]/route.js +32 -1
- package/dist/modules/perspectives/api/[tableId]/roles/[roleId]/route.js.map +2 -2
- package/dist/modules/perspectives/api/[tableId]/route.js +73 -2
- package/dist/modules/perspectives/api/[tableId]/route.js.map +2 -2
- package/dist/modules/perspectives/services/perspectiveService.js +5 -3
- package/dist/modules/perspectives/services/perspectiveService.js.map +2 -2
- package/dist/modules/planner/api/access.js +9 -0
- package/dist/modules/planner/api/access.js.map +2 -2
- package/dist/modules/planner/api/availability-date-specific.js +22 -1
- package/dist/modules/planner/api/availability-date-specific.js.map +2 -2
- package/dist/modules/planner/api/availability-weekly.js +22 -1
- package/dist/modules/planner/api/availability-weekly.js.map +2 -2
- package/dist/modules/resources/api/resources/tags/assign/route.js +39 -0
- package/dist/modules/resources/api/resources/tags/assign/route.js.map +2 -2
- package/dist/modules/resources/api/resources/tags/unassign/route.js +39 -0
- package/dist/modules/resources/api/resources/tags/unassign/route.js.map +2 -2
- package/dist/modules/sales/api/settings/document-numbers/route.js +33 -1
- package/dist/modules/sales/api/settings/document-numbers/route.js.map +2 -2
- package/dist/modules/sales/api/settings/order-editing/route.js +35 -3
- package/dist/modules/sales/api/settings/order-editing/route.js.map +2 -2
- package/dist/modules/staff/api/leave-requests/accept/route.js +41 -0
- package/dist/modules/staff/api/leave-requests/accept/route.js.map +2 -2
- package/dist/modules/staff/api/leave-requests/reject/route.js +41 -0
- package/dist/modules/staff/api/leave-requests/reject/route.js.map +2 -2
- package/dist/modules/staff/api/team-members/self/route.js +40 -0
- package/dist/modules/staff/api/team-members/self/route.js.map +2 -2
- package/dist/modules/staff/api/team-members/tags/assign/route.js +41 -0
- package/dist/modules/staff/api/team-members/tags/assign/route.js.map +2 -2
- package/dist/modules/staff/api/team-members/tags/unassign/route.js +41 -0
- package/dist/modules/staff/api/team-members/tags/unassign/route.js.map +2 -2
- package/dist/modules/translations/api/[entityType]/[entityId]/route.js +61 -1
- package/dist/modules/translations/api/[entityType]/[entityId]/route.js.map +2 -2
- package/dist/modules/translations/api/context.js +7 -0
- package/dist/modules/translations/api/context.js.map +2 -2
- package/dist/modules/translations/api/put/locales.js +33 -1
- package/dist/modules/translations/api/put/locales.js.map +2 -2
- package/dist/modules/workflows/backend/definitions/visual-editor/page.js +6 -7
- package/dist/modules/workflows/backend/definitions/visual-editor/page.js.map +2 -2
- package/dist/modules/workflows/backend/instances/[id]/page.js.map +1 -1
- package/dist/modules/workflows/components/EdgeEditDialog.js.map +1 -1
- package/dist/modules/workflows/components/EdgeEditDialogCrudForm.js.map +1 -1
- package/dist/modules/workflows/components/NodeEditDialog.js.map +1 -1
- package/dist/modules/workflows/components/NodeEditDialogCrudForm.js.map +1 -1
- package/dist/modules/workflows/components/WorkflowGraph.js.map +1 -1
- package/dist/modules/workflows/components/WorkflowGraphImpl.js +17 -9
- package/dist/modules/workflows/components/WorkflowGraphImpl.js.map +2 -2
- package/dist/modules/workflows/components/mobile/MobileVisualEditor.js.map +1 -1
- package/dist/modules/workflows/frontend/checkout-demo/deriveCurrentStep.js +8 -0
- package/dist/modules/workflows/frontend/checkout-demo/deriveCurrentStep.js.map +7 -0
- package/dist/modules/workflows/frontend/checkout-demo/page.js +2 -20
- package/dist/modules/workflows/frontend/checkout-demo/page.js.map +2 -2
- package/dist/modules/workflows/lib/graph-utils.js +8 -0
- package/dist/modules/workflows/lib/graph-utils.js.map +2 -2
- package/generated/entities/catalog_product/index.ts +26 -0
- package/generated/entities/catalog_product_variant/index.ts +2 -0
- package/generated/entity-fields-registry.ts +28 -0
- package/package.json +7 -7
- package/src/modules/catalog/api/products/route.ts +123 -39
- package/src/modules/catalog/api/variants/route.ts +4 -0
- package/src/modules/catalog/backend/catalog/products/[id]/page.tsx +43 -0
- package/src/modules/catalog/backend/catalog/products/[productId]/variants/[variantId]/page.tsx +14 -0
- package/src/modules/catalog/backend/catalog/products/[productId]/variants/create/page.tsx +2 -0
- package/src/modules/catalog/backend/catalog/products/create/page.tsx +41 -0
- package/src/modules/catalog/commands/products.ts +307 -2
- package/src/modules/catalog/commands/variants.ts +90 -1
- package/src/modules/catalog/components/products/ProductComplianceSection.tsx +497 -0
- package/src/modules/catalog/components/products/VariantBuilder.tsx +43 -0
- package/src/modules/catalog/components/products/productForm.ts +262 -0
- package/src/modules/catalog/components/products/variantForm.ts +4 -0
- package/src/modules/catalog/data/entities.ts +97 -0
- package/src/modules/catalog/data/types.ts +36 -0
- package/src/modules/catalog/data/validators.ts +159 -3
- package/src/modules/catalog/i18n/de.json +64 -0
- package/src/modules/catalog/i18n/en.json +64 -0
- package/src/modules/catalog/i18n/es.json +64 -0
- package/src/modules/catalog/i18n/pl.json +64 -0
- package/src/modules/catalog/lib/gtin.ts +66 -0
- package/src/modules/catalog/migrations/.snapshot-open-mercato.json +457 -0
- package/src/modules/catalog/migrations/Migration20260611090000.ts +17 -0
- package/src/modules/catalog/translations.ts +1 -1
- package/src/modules/configs/api/cache/route.ts +72 -10
- package/src/modules/configs/components/CachePanel.tsx +59 -29
- package/src/modules/currencies/api/currencies/options/route.ts +22 -4
- package/src/modules/currencies/services/rateFetchingService.ts +63 -26
- package/src/modules/customer_accounts/backend/customer_accounts/users/[id]/page.tsx +18 -18
- package/src/modules/customer_accounts/backend/customer_accounts/users/page.tsx +1 -1
- package/src/modules/customer_accounts/i18n/de.json +1 -1
- package/src/modules/customer_accounts/i18n/en.json +1 -1
- package/src/modules/customer_accounts/i18n/es.json +1 -1
- package/src/modules/customer_accounts/i18n/pl.json +1 -1
- package/src/modules/customers/backend/calendar/page.meta.ts +23 -0
- package/src/modules/customers/backend/calendar/page.tsx +12 -0
- package/src/modules/customers/cli.ts +1 -0
- package/src/modules/customers/components/calendar/AgendaList.tsx +219 -0
- package/src/modules/customers/components/calendar/CalendarEventEditor.tsx +386 -0
- package/src/modules/customers/components/calendar/CalendarFooter.tsx +61 -0
- package/src/modules/customers/components/calendar/CalendarHeader.tsx +40 -0
- package/src/modules/customers/components/calendar/CalendarScreen.tsx +590 -0
- package/src/modules/customers/components/calendar/CalendarSettingsModal.tsx +207 -0
- package/src/modules/customers/components/calendar/CalendarTabs.tsx +63 -0
- package/src/modules/customers/components/calendar/CalendarToolbar.tsx +295 -0
- package/src/modules/customers/components/calendar/EventBlock.tsx +205 -0
- package/src/modules/customers/components/calendar/EventPeekPopover.tsx +100 -0
- package/src/modules/customers/components/calendar/MonthGrid.tsx +236 -0
- package/src/modules/customers/components/calendar/ShortcutsDialog.tsx +57 -0
- package/src/modules/customers/components/calendar/TimeGrid.tsx +510 -0
- package/src/modules/customers/components/calendar/UpcomingCards.tsx +220 -0
- package/src/modules/customers/components/calendar/editor/CategoryField.tsx +79 -0
- package/src/modules/customers/components/calendar/editor/LocationField.tsx +37 -0
- package/src/modules/customers/components/calendar/editor/PeopleField.tsx +148 -0
- package/src/modules/customers/components/calendar/editor/RelatedToField.tsx +242 -0
- package/src/modules/customers/components/calendar/editor/RepeatField.tsx +132 -0
- package/src/modules/customers/components/calendar/editor/ScheduleSection.tsx +110 -0
- package/src/modules/customers/components/calendar/editor/SegmentGroup.tsx +50 -0
- package/src/modules/customers/components/calendar/editor/hooks.ts +162 -0
- package/src/modules/customers/components/calendar/editor/inputs.tsx +158 -0
- package/src/modules/customers/components/calendar/editor/lookups.ts +160 -0
- package/src/modules/customers/components/calendar/types.ts +163 -0
- package/src/modules/customers/components/calendar/useCalendarItems.ts +162 -0
- package/src/modules/customers/components/calendar/useCalendarPreferences.ts +52 -0
- package/src/modules/customers/i18n/de.json +195 -0
- package/src/modules/customers/i18n/en.json +195 -0
- package/src/modules/customers/i18n/es.json +195 -0
- package/src/modules/customers/i18n/pl.json +195 -0
- package/src/modules/customers/lib/calendar/categories.ts +26 -0
- package/src/modules/customers/lib/calendar/conflicts.ts +117 -0
- package/src/modules/customers/lib/calendar/editorPayload.ts +388 -0
- package/src/modules/customers/lib/calendar/grid.ts +50 -0
- package/src/modules/customers/lib/calendar/layout.ts +47 -0
- package/src/modules/customers/lib/calendar/mapItem.ts +94 -0
- package/src/modules/customers/lib/calendar/preferences.ts +95 -0
- package/src/modules/customers/lib/calendar/range.ts +45 -0
- package/src/modules/customers/lib/calendar/recurrence.ts +137 -0
- package/src/modules/dashboards/services/widgetDataService.ts +8 -6
- package/src/modules/dictionaries/api/[dictionaryId]/entries/[entryId]/route.ts +61 -1
- package/src/modules/dictionaries/api/[dictionaryId]/entries/route.ts +33 -1
- package/src/modules/dictionaries/api/[dictionaryId]/route.ts +65 -1
- package/src/modules/dictionaries/api/route.ts +36 -1
- package/src/modules/feature_toggles/lib/queries.ts +41 -60
- package/src/modules/messages/commands/actions.ts +100 -7
- package/src/modules/perspectives/api/[tableId]/[perspectiveId]/route.ts +34 -1
- package/src/modules/perspectives/api/[tableId]/roles/[roleId]/route.ts +34 -1
- package/src/modules/perspectives/api/[tableId]/route.ts +107 -32
- package/src/modules/perspectives/services/perspectiveService.ts +9 -5
- package/src/modules/planner/api/access.ts +9 -0
- package/src/modules/planner/api/availability-date-specific.ts +22 -1
- package/src/modules/planner/api/availability-weekly.ts +22 -1
- package/src/modules/resources/api/resources/tags/assign/route.ts +42 -0
- package/src/modules/resources/api/resources/tags/unassign/route.ts +42 -0
- package/src/modules/sales/api/settings/document-numbers/route.ts +35 -1
- package/src/modules/sales/api/settings/order-editing/route.ts +37 -3
- package/src/modules/staff/api/leave-requests/accept/route.ts +45 -0
- package/src/modules/staff/api/leave-requests/reject/route.ts +45 -0
- package/src/modules/staff/api/team-members/self/route.ts +43 -0
- package/src/modules/staff/api/team-members/tags/assign/route.ts +45 -0
- package/src/modules/staff/api/team-members/tags/unassign/route.ts +45 -0
- package/src/modules/translations/api/[entityType]/[entityId]/route.ts +65 -1
- package/src/modules/translations/api/context.ts +7 -0
- package/src/modules/translations/api/put/locales.ts +35 -1
- package/src/modules/workflows/backend/definitions/visual-editor/page.tsx +11 -9
- package/src/modules/workflows/backend/instances/[id]/page.tsx +1 -1
- package/src/modules/workflows/components/EdgeEditDialog.tsx +1 -1
- package/src/modules/workflows/components/EdgeEditDialogCrudForm.tsx +1 -1
- package/src/modules/workflows/components/NodeEditDialog.tsx +1 -1
- package/src/modules/workflows/components/NodeEditDialogCrudForm.tsx +1 -1
- package/src/modules/workflows/components/WorkflowGraph.tsx +2 -2
- package/src/modules/workflows/components/WorkflowGraphImpl.tsx +27 -13
- package/src/modules/workflows/components/mobile/MobileVisualEditor.tsx +3 -3
- package/src/modules/workflows/frontend/checkout-demo/deriveCurrentStep.ts +12 -0
- package/src/modules/workflows/frontend/checkout-demo/page.tsx +3 -23
- package/src/modules/workflows/lib/graph-utils.ts +21 -1
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
import { endOfDay } from "date-fns/endOfDay";
|
|
4
|
+
import { startOfDay } from "date-fns/startOfDay";
|
|
5
|
+
import { useT } from "@open-mercato/shared/lib/i18n/context";
|
|
6
|
+
import { computeDurationMinutes } from "../../../lib/calendar/editorPayload.js";
|
|
7
|
+
import { findEditorConflictItems } from "../../../lib/calendar/conflicts.js";
|
|
8
|
+
import { mapInteractionToCalendarItem } from "../../../lib/calendar/mapItem.js";
|
|
9
|
+
import { expandOccurrences } from "../../../lib/calendar/recurrence.js";
|
|
10
|
+
import { getFetchWindow } from "../../../lib/calendar/range.js";
|
|
11
|
+
import { fetchInteractionWindow } from "../useCalendarItems.js";
|
|
12
|
+
import { fetchDealById, fetchRelatedEntityById, findStaffMemberName } from "./lookups.js";
|
|
13
|
+
function useEditorLabelResolution(open, form, update) {
|
|
14
|
+
React.useEffect(() => {
|
|
15
|
+
if (!open) return;
|
|
16
|
+
const controller = new AbortController();
|
|
17
|
+
let cancelled = false;
|
|
18
|
+
async function resolveLabels() {
|
|
19
|
+
if (form.relatedTo && form.relatedTo.kind === "unknown") {
|
|
20
|
+
const resolved = await fetchRelatedEntityById(form.relatedTo.id, controller.signal);
|
|
21
|
+
if (!cancelled && resolved) update({ relatedTo: { id: resolved.id, kind: resolved.kind, label: resolved.label } });
|
|
22
|
+
}
|
|
23
|
+
if (form.dealId && !form.dealLabel) {
|
|
24
|
+
const deal = await fetchDealById(form.dealId, controller.signal);
|
|
25
|
+
if (!cancelled && deal) update({ dealLabel: deal.label });
|
|
26
|
+
}
|
|
27
|
+
if (form.assigneeUserId && !form.assigneeName) {
|
|
28
|
+
const name = await findStaffMemberName(form.assigneeUserId, controller.signal);
|
|
29
|
+
if (!cancelled && name) update({ assigneeName: name });
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
resolveLabels().catch(() => {
|
|
33
|
+
if (cancelled || controller.signal.aborted || !form.relatedTo || form.relatedTo.kind !== "unknown" || form.relatedTo.label) {
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
update({ relatedTo: { ...form.relatedTo, label: form.relatedTo.id } });
|
|
37
|
+
});
|
|
38
|
+
return () => {
|
|
39
|
+
cancelled = true;
|
|
40
|
+
controller.abort();
|
|
41
|
+
};
|
|
42
|
+
}, [open, form.relatedTo, form.dealId, form.dealLabel, form.assigneeUserId, form.assigneeName, update]);
|
|
43
|
+
}
|
|
44
|
+
function formatClock(date) {
|
|
45
|
+
return date.toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" });
|
|
46
|
+
}
|
|
47
|
+
function useConflictProbe(open, form, config, excludeId, draftOwnerUserId, scope, currentUserId) {
|
|
48
|
+
const t = useT();
|
|
49
|
+
const [conflict, setConflict] = React.useState(null);
|
|
50
|
+
const participantsKey = form.participants.map((participant) => participant.userId).join(",");
|
|
51
|
+
React.useEffect(() => {
|
|
52
|
+
if (!open || !form.date) {
|
|
53
|
+
setConflict(null);
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
const isAllDay = config.hasAllDay && form.allDay;
|
|
57
|
+
let start;
|
|
58
|
+
let end;
|
|
59
|
+
if (isAllDay) {
|
|
60
|
+
const dayDate = /* @__PURE__ */ new Date(`${form.date}T00:00:00`);
|
|
61
|
+
if (Number.isNaN(dayDate.getTime())) {
|
|
62
|
+
setConflict(null);
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
start = startOfDay(dayDate);
|
|
66
|
+
end = endOfDay(dayDate);
|
|
67
|
+
} else {
|
|
68
|
+
if (!form.startTime) {
|
|
69
|
+
setConflict(null);
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
start = /* @__PURE__ */ new Date(`${form.date}T${form.startTime}:00`);
|
|
73
|
+
if (Number.isNaN(start.getTime())) {
|
|
74
|
+
setConflict(null);
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
const durationMinutes = config.hasEnd ? computeDurationMinutes(form) ?? 30 : 30;
|
|
78
|
+
end = new Date(start.getTime() + durationMinutes * 6e4);
|
|
79
|
+
}
|
|
80
|
+
const dayStart = startOfDay(start);
|
|
81
|
+
dayStart.setDate(dayStart.getDate() - 1);
|
|
82
|
+
const dayEnd = endOfDay(end);
|
|
83
|
+
dayEnd.setDate(dayEnd.getDate() + 1);
|
|
84
|
+
const fetchWindow = getFetchWindow({ from: dayStart, to: dayEnd });
|
|
85
|
+
const controller = new AbortController();
|
|
86
|
+
let active = true;
|
|
87
|
+
const timer = setTimeout(async () => {
|
|
88
|
+
try {
|
|
89
|
+
const { payloads } = await fetchInteractionWindow(fetchWindow, controller.signal);
|
|
90
|
+
if (!active) return;
|
|
91
|
+
const others = [];
|
|
92
|
+
for (const payload of payloads) {
|
|
93
|
+
const item = mapInteractionToCalendarItem(payload, {});
|
|
94
|
+
if (!item) continue;
|
|
95
|
+
others.push(...expandOccurrences(item, fetchWindow));
|
|
96
|
+
}
|
|
97
|
+
const conflictItems = findEditorConflictItems(
|
|
98
|
+
{
|
|
99
|
+
start,
|
|
100
|
+
end,
|
|
101
|
+
ownerUserId: draftOwnerUserId,
|
|
102
|
+
participants: form.participants.map((participant) => ({ userId: participant.userId, name: participant.name })),
|
|
103
|
+
status: form.status
|
|
104
|
+
},
|
|
105
|
+
others,
|
|
106
|
+
excludeId,
|
|
107
|
+
{ scope, currentUserId }
|
|
108
|
+
);
|
|
109
|
+
if (!active) return;
|
|
110
|
+
if (conflictItems.length === 0) {
|
|
111
|
+
setConflict(null);
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
const summary = conflictItems.map((item) => `${formatClock(item.start)}\u2013${formatClock(item.end)}: ${item.title || t("customers.calendar.grid.untitled", "Untitled")}`).join(", ");
|
|
115
|
+
setConflict(summary ? t("customers.calendar.editor.conflictWarning", "Overlaps with: {items}", { items: summary }) : null);
|
|
116
|
+
} catch {
|
|
117
|
+
if (active) setConflict(null);
|
|
118
|
+
}
|
|
119
|
+
}, 500);
|
|
120
|
+
return () => {
|
|
121
|
+
active = false;
|
|
122
|
+
clearTimeout(timer);
|
|
123
|
+
controller.abort();
|
|
124
|
+
};
|
|
125
|
+
}, [open, form.date, form.startTime, form.endDate, form.endTime, form.allDay, form.status, participantsKey, config.hasAllDay, config.hasEnd, excludeId, draftOwnerUserId, scope, currentUserId, t]);
|
|
126
|
+
return conflict;
|
|
127
|
+
}
|
|
128
|
+
export {
|
|
129
|
+
useConflictProbe,
|
|
130
|
+
useEditorLabelResolution
|
|
131
|
+
};
|
|
132
|
+
//# sourceMappingURL=hooks.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../../../src/modules/customers/components/calendar/editor/hooks.ts"],
|
|
4
|
+
"sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport { endOfDay } from 'date-fns/endOfDay'\nimport { startOfDay } from 'date-fns/startOfDay'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { computeDurationMinutes, type EditorFormState, type EditorKindConfig } from '../../../lib/calendar/editorPayload'\nimport { findEditorConflictItems } from '../../../lib/calendar/conflicts'\nimport type { ConflictScope } from '../../../lib/calendar/preferences'\nimport { mapInteractionToCalendarItem } from '../../../lib/calendar/mapItem'\nimport { expandOccurrences } from '../../../lib/calendar/recurrence'\nimport { getFetchWindow } from '../../../lib/calendar/range'\nimport type { CalendarItem } from '../types'\nimport { fetchInteractionWindow } from '../useCalendarItems'\nimport { fetchDealById, fetchRelatedEntityById, findStaffMemberName } from './lookups'\n\n// Edit-mode prefill stores ids only (parseItemToFormState is pure); resolve the\n// human labels for the related entity, the deal chip and the task assignee.\nexport function useEditorLabelResolution(\n open: boolean,\n form: EditorFormState,\n update: (patch: Partial<EditorFormState>) => void,\n): void {\n React.useEffect(() => {\n if (!open) return\n const controller = new AbortController()\n let cancelled = false\n async function resolveLabels() {\n if (form.relatedTo && form.relatedTo.kind === 'unknown') {\n const resolved = await fetchRelatedEntityById(form.relatedTo.id, controller.signal)\n if (!cancelled && resolved) update({ relatedTo: { id: resolved.id, kind: resolved.kind, label: resolved.label } })\n }\n if (form.dealId && !form.dealLabel) {\n const deal = await fetchDealById(form.dealId, controller.signal)\n if (!cancelled && deal) update({ dealLabel: deal.label })\n }\n if (form.assigneeUserId && !form.assigneeName) {\n const name = await findStaffMemberName(form.assigneeUserId, controller.signal)\n if (!cancelled && name) update({ assigneeName: name })\n }\n }\n resolveLabels().catch(() => {\n if (cancelled || controller.signal.aborted || !form.relatedTo || form.relatedTo.kind !== 'unknown' || form.relatedTo.label) {\n return\n }\n update({ relatedTo: { ...form.relatedTo, label: form.relatedTo.id } })\n })\n return () => {\n cancelled = true\n controller.abort()\n }\n }, [open, form.relatedTo, form.dealId, form.dealLabel, form.assigneeUserId, form.assigneeName, update])\n}\n\nfunction formatClock(date: Date): string {\n return date.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })\n}\n\n// Debounced save-time conflict probe. Detection uses the SAME `findConflicts`\n// logic the grid uses (overlap + shared owner/participant) against a freshly\n// fetched \u00B11-day window, so the editor warning is always consistent with the\n// conflict badges/rings the user sees on the calendar. The warning is\n// informational and never blocks saving.\nexport function useConflictProbe(\n open: boolean,\n form: EditorFormState,\n config: EditorKindConfig,\n excludeId: string | null,\n draftOwnerUserId: string | null,\n scope: ConflictScope,\n currentUserId: string | null,\n): string | null {\n const t = useT()\n const [conflict, setConflict] = React.useState<string | null>(null)\n const participantsKey = form.participants.map((participant) => participant.userId).join(',')\n React.useEffect(() => {\n if (!open || !form.date) {\n setConflict(null)\n return\n }\n // Resolve the draft's [start, end] span exactly as the grid will after save:\n // all-day spans startOfDay..endOfDay (matching mapInteractionToCalendarItem),\n // timed events use the start + computed duration (multi-day endDate included).\n const isAllDay = config.hasAllDay && form.allDay\n let start: Date\n let end: Date\n if (isAllDay) {\n const dayDate = new Date(`${form.date}T00:00:00`)\n if (Number.isNaN(dayDate.getTime())) {\n setConflict(null)\n return\n }\n start = startOfDay(dayDate)\n end = endOfDay(dayDate)\n } else {\n if (!form.startTime) {\n setConflict(null)\n return\n }\n start = new Date(`${form.date}T${form.startTime}:00`)\n if (Number.isNaN(start.getTime())) {\n setConflict(null)\n return\n }\n const durationMinutes = config.hasEnd ? computeDurationMinutes(form) ?? 30 : 30\n end = new Date(start.getTime() + durationMinutes * 60_000)\n }\n // The same padded window + recurrence expansion the grid uses, so the probe\n // sees the exact candidate set behind the grid's conflict badges/rings. The\n // window pads \u00B11 day around the FULL draft span so multi-day drafts still\n // catch neighbours near their end, not just their start day.\n const dayStart = startOfDay(start)\n dayStart.setDate(dayStart.getDate() - 1)\n const dayEnd = endOfDay(end)\n dayEnd.setDate(dayEnd.getDate() + 1)\n const fetchWindow = getFetchWindow({ from: dayStart, to: dayEnd })\n const controller = new AbortController()\n let active = true\n const timer = setTimeout(async () => {\n try {\n const { payloads } = await fetchInteractionWindow(fetchWindow, controller.signal)\n if (!active) return\n const others: CalendarItem[] = []\n for (const payload of payloads) {\n const item = mapInteractionToCalendarItem(payload, {})\n if (!item) continue\n others.push(...expandOccurrences(item, fetchWindow))\n }\n const conflictItems = findEditorConflictItems(\n {\n start,\n end,\n ownerUserId: draftOwnerUserId,\n participants: form.participants.map((participant) => ({ userId: participant.userId, name: participant.name })),\n status: form.status,\n },\n others,\n excludeId,\n { scope, currentUserId },\n )\n if (!active) return\n if (conflictItems.length === 0) {\n setConflict(null)\n return\n }\n const summary = conflictItems\n .map((item) => `${formatClock(item.start)}\u2013${formatClock(item.end)}: ${item.title || t('customers.calendar.grid.untitled', 'Untitled')}`)\n .join(', ')\n setConflict(summary ? t('customers.calendar.editor.conflictWarning', 'Overlaps with: {items}', { items: summary }) : null)\n } catch {\n if (active) setConflict(null)\n }\n }, 500)\n return () => {\n active = false\n clearTimeout(timer)\n controller.abort()\n }\n // Re-probe when schedule-relevant inputs change (time window, all-day, attendees, owner, status, scope).\n }, [open, form.date, form.startTime, form.endDate, form.endTime, form.allDay, form.status, participantsKey, config.hasAllDay, config.hasEnd, excludeId, draftOwnerUserId, scope, currentUserId, t]) // eslint-disable-line react-hooks/exhaustive-deps\n return conflict\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { ChevronDown, Plus } from "lucide-react";
|
|
4
|
+
import { cn } from "@open-mercato/shared/lib/utils";
|
|
5
|
+
import { Avatar } from "@open-mercato/ui/primitives/avatar";
|
|
6
|
+
import { IconButton } from "@open-mercato/ui/primitives/icon-button";
|
|
7
|
+
import { Input } from "@open-mercato/ui/primitives/input";
|
|
8
|
+
import { Switch } from "@open-mercato/ui/primitives/switch";
|
|
9
|
+
const CONTROL_BORDER = "border border-input";
|
|
10
|
+
const CONTROL_TEXT = "text-sm text-foreground placeholder:text-muted-foreground";
|
|
11
|
+
const LABEL_CLASS = "text-xs font-medium text-muted-foreground";
|
|
12
|
+
const DROPDOWN_PANEL_CLASS = "absolute z-50 mt-1 max-h-56 w-full overflow-y-auto rounded-md border border-border bg-popover p-1 text-popover-foreground shadow-md";
|
|
13
|
+
function Field({ label, children, error }) {
|
|
14
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex w-full flex-col gap-1.5", children: [
|
|
15
|
+
/* @__PURE__ */ jsx("span", { className: LABEL_CLASS, children: label }),
|
|
16
|
+
children,
|
|
17
|
+
error ? /* @__PURE__ */ jsx("p", { className: "text-xs text-status-error-text", children: error }) : null
|
|
18
|
+
] });
|
|
19
|
+
}
|
|
20
|
+
function UppercaseBadge({ style, className, children }) {
|
|
21
|
+
return /* @__PURE__ */ jsx(
|
|
22
|
+
"span",
|
|
23
|
+
{
|
|
24
|
+
className: cn(
|
|
25
|
+
"inline-flex shrink-0 items-center justify-center rounded-full bg-muted px-2 py-0.5 text-overline font-medium uppercase text-muted-foreground",
|
|
26
|
+
className
|
|
27
|
+
),
|
|
28
|
+
style,
|
|
29
|
+
children
|
|
30
|
+
}
|
|
31
|
+
);
|
|
32
|
+
}
|
|
33
|
+
function categoryPillStyle(color) {
|
|
34
|
+
if (typeof color === "string" && /^#[0-9a-fA-F]{6}$/.test(color)) {
|
|
35
|
+
return { backgroundColor: `${color}59`, color: `color-mix(in srgb, ${color} 55%, black)` };
|
|
36
|
+
}
|
|
37
|
+
if (typeof color === "string" && color.length > 0) {
|
|
38
|
+
return {
|
|
39
|
+
backgroundColor: `color-mix(in srgb, ${color} 35%, white)`,
|
|
40
|
+
color: `color-mix(in srgb, ${color} 55%, black)`
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
return {};
|
|
44
|
+
}
|
|
45
|
+
function AllDayToggle({ checked, onCheckedChange, label }) {
|
|
46
|
+
return /* @__PURE__ */ jsx(
|
|
47
|
+
Switch,
|
|
48
|
+
{
|
|
49
|
+
checked,
|
|
50
|
+
"aria-label": label,
|
|
51
|
+
onCheckedChange,
|
|
52
|
+
className: "h-6 w-10"
|
|
53
|
+
}
|
|
54
|
+
);
|
|
55
|
+
}
|
|
56
|
+
function formatDisplayDate(value, locale) {
|
|
57
|
+
const parsed = /* @__PURE__ */ new Date(`${value}T00:00:00`);
|
|
58
|
+
if (Number.isNaN(parsed.getTime())) return value;
|
|
59
|
+
return new Intl.DateTimeFormat(locale, { weekday: "short", month: "short", day: "numeric", year: "numeric" }).format(parsed);
|
|
60
|
+
}
|
|
61
|
+
function DateControl({
|
|
62
|
+
value,
|
|
63
|
+
onChange,
|
|
64
|
+
ariaLabel,
|
|
65
|
+
locale,
|
|
66
|
+
className
|
|
67
|
+
}) {
|
|
68
|
+
return /* @__PURE__ */ jsxs(
|
|
69
|
+
"div",
|
|
70
|
+
{
|
|
71
|
+
className: cn(
|
|
72
|
+
"relative flex h-9 w-full items-center justify-between rounded-md bg-background px-3",
|
|
73
|
+
CONTROL_BORDER,
|
|
74
|
+
className
|
|
75
|
+
),
|
|
76
|
+
children: [
|
|
77
|
+
/* @__PURE__ */ jsx("span", { className: "truncate text-sm text-foreground", children: formatDisplayDate(value, locale) }),
|
|
78
|
+
/* @__PURE__ */ jsx("span", { "aria-hidden": true, className: "h-px w-2 shrink-0" }),
|
|
79
|
+
/* @__PURE__ */ jsx(ChevronDown, { "aria-hidden": true, className: "size-4 shrink-0 opacity-60" }),
|
|
80
|
+
/* @__PURE__ */ jsx(
|
|
81
|
+
Input,
|
|
82
|
+
{
|
|
83
|
+
type: "date",
|
|
84
|
+
value,
|
|
85
|
+
onChange: (event) => {
|
|
86
|
+
if (event.target.value) onChange(event.target.value);
|
|
87
|
+
},
|
|
88
|
+
"aria-label": ariaLabel,
|
|
89
|
+
className: "absolute inset-0 h-full w-full cursor-pointer border-0 bg-transparent p-0 opacity-0 shadow-none hover:bg-transparent",
|
|
90
|
+
inputClassName: "h-full cursor-pointer"
|
|
91
|
+
}
|
|
92
|
+
)
|
|
93
|
+
]
|
|
94
|
+
}
|
|
95
|
+
);
|
|
96
|
+
}
|
|
97
|
+
function TimeControl({ value, onChange, ariaLabel }) {
|
|
98
|
+
return /* @__PURE__ */ jsx(
|
|
99
|
+
Input,
|
|
100
|
+
{
|
|
101
|
+
type: "time",
|
|
102
|
+
value,
|
|
103
|
+
onChange: (event) => {
|
|
104
|
+
if (event.target.value) onChange(event.target.value);
|
|
105
|
+
},
|
|
106
|
+
"aria-label": ariaLabel,
|
|
107
|
+
className: "h-9 w-32 shrink-0"
|
|
108
|
+
}
|
|
109
|
+
);
|
|
110
|
+
}
|
|
111
|
+
function PersonChip({
|
|
112
|
+
name,
|
|
113
|
+
badge,
|
|
114
|
+
compact,
|
|
115
|
+
onRemove,
|
|
116
|
+
removeLabel
|
|
117
|
+
}) {
|
|
118
|
+
return /* @__PURE__ */ jsxs(
|
|
119
|
+
"span",
|
|
120
|
+
{
|
|
121
|
+
className: cn(
|
|
122
|
+
"inline-flex shrink-0 items-center gap-1.5 rounded-full bg-muted pl-1 pr-2",
|
|
123
|
+
compact ? "py-0.5" : "py-1"
|
|
124
|
+
),
|
|
125
|
+
children: [
|
|
126
|
+
/* @__PURE__ */ jsx(Avatar, { size: "xs", label: name }),
|
|
127
|
+
/* @__PURE__ */ jsx("span", { className: "max-w-40 truncate text-xs font-medium text-foreground", children: name }),
|
|
128
|
+
badge,
|
|
129
|
+
onRemove ? /* @__PURE__ */ jsx(
|
|
130
|
+
IconButton,
|
|
131
|
+
{
|
|
132
|
+
variant: "ghost",
|
|
133
|
+
size: "xs",
|
|
134
|
+
onClick: (event) => {
|
|
135
|
+
event.stopPropagation();
|
|
136
|
+
onRemove();
|
|
137
|
+
},
|
|
138
|
+
"aria-label": removeLabel,
|
|
139
|
+
className: "size-5 shrink-0",
|
|
140
|
+
children: /* @__PURE__ */ jsx(Plus, { "aria-hidden": true, className: "size-3.5 rotate-45 opacity-50" })
|
|
141
|
+
}
|
|
142
|
+
) : null
|
|
143
|
+
]
|
|
144
|
+
}
|
|
145
|
+
);
|
|
146
|
+
}
|
|
147
|
+
export {
|
|
148
|
+
AllDayToggle,
|
|
149
|
+
CONTROL_BORDER,
|
|
150
|
+
CONTROL_TEXT,
|
|
151
|
+
DROPDOWN_PANEL_CLASS,
|
|
152
|
+
DateControl,
|
|
153
|
+
Field,
|
|
154
|
+
LABEL_CLASS,
|
|
155
|
+
PersonChip,
|
|
156
|
+
TimeControl,
|
|
157
|
+
UppercaseBadge,
|
|
158
|
+
categoryPillStyle
|
|
159
|
+
};
|
|
160
|
+
//# sourceMappingURL=inputs.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../../../src/modules/customers/components/calendar/editor/inputs.tsx"],
|
|
4
|
+
"sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport { ChevronDown, Plus } from 'lucide-react'\nimport { cn } from '@open-mercato/shared/lib/utils'\nimport { Avatar } from '@open-mercato/ui/primitives/avatar'\nimport { IconButton } from '@open-mercato/ui/primitives/icon-button'\nimport { Input } from '@open-mercato/ui/primitives/input'\nimport { Switch } from '@open-mercato/ui/primitives/switch'\n\nexport const CONTROL_BORDER = 'border border-input'\nexport const CONTROL_TEXT = 'text-sm text-foreground placeholder:text-muted-foreground'\nexport const LABEL_CLASS = 'text-xs font-medium text-muted-foreground'\nexport const DROPDOWN_PANEL_CLASS =\n 'absolute z-50 mt-1 max-h-56 w-full overflow-y-auto rounded-md border border-border bg-popover p-1 text-popover-foreground shadow-md'\n\nexport function Field({ label, children, error }: { label: string; children: React.ReactNode; error?: string | null }) {\n return (\n <div className=\"flex w-full flex-col gap-1.5\">\n <span className={LABEL_CLASS}>{label}</span>\n {children}\n {error ? <p className=\"text-xs text-status-error-text\">{error}</p> : null}\n </div>\n )\n}\n\nexport function UppercaseBadge({ style, className, children }: { style?: React.CSSProperties; className?: string; children: React.ReactNode }) {\n return (\n <span\n className={cn(\n 'inline-flex shrink-0 items-center justify-center rounded-full bg-muted px-2 py-0.5 text-overline font-medium uppercase text-muted-foreground',\n className,\n )}\n style={style}\n >\n {children}\n </span>\n )\n}\n\n// Mockup tint colors are illustrative; runtime pills derive from the\n// dictionary entry color using the appearanceColor hex-alpha tint technique\n// (see EventBlock.softTintStyle) with a darkened text shade of the same hue.\nexport function categoryPillStyle(color: string | null | undefined): React.CSSProperties {\n if (typeof color === 'string' && /^#[0-9a-fA-F]{6}$/.test(color)) {\n return { backgroundColor: `${color}59`, color: `color-mix(in srgb, ${color} 55%, black)` }\n }\n if (typeof color === 'string' && color.length > 0) {\n return {\n backgroundColor: `color-mix(in srgb, ${color} 35%, white)`,\n color: `color-mix(in srgb, ${color} 55%, black)`,\n }\n }\n return {}\n}\n\nexport function AllDayToggle({ checked, onCheckedChange, label }: { checked: boolean; onCheckedChange(next: boolean): void; label: string }) {\n return (\n <Switch\n checked={checked}\n aria-label={label}\n onCheckedChange={onCheckedChange}\n className=\"h-6 w-10\"\n />\n )\n}\n\nfunction formatDisplayDate(value: string, locale: string): string {\n const parsed = new Date(`${value}T00:00:00`)\n if (Number.isNaN(parsed.getTime())) return value\n return new Intl.DateTimeFormat(locale, { weekday: 'short', month: 'short', day: 'numeric', year: 'numeric' }).format(parsed)\n}\n\nexport function DateControl({\n value,\n onChange,\n ariaLabel,\n locale,\n className,\n}: {\n value: string\n onChange(next: string): void\n ariaLabel: string\n locale: string\n className?: string\n}) {\n return (\n <div\n className={cn(\n 'relative flex h-9 w-full items-center justify-between rounded-md bg-background px-3',\n CONTROL_BORDER,\n className,\n )}\n >\n <span className=\"truncate text-sm text-foreground\">{formatDisplayDate(value, locale)}</span>\n <span aria-hidden className=\"h-px w-2 shrink-0\" />\n <ChevronDown aria-hidden className=\"size-4 shrink-0 opacity-60\" />\n <Input\n type=\"date\"\n value={value}\n onChange={(event) => { if (event.target.value) onChange(event.target.value) }}\n aria-label={ariaLabel}\n className=\"absolute inset-0 h-full w-full cursor-pointer border-0 bg-transparent p-0 opacity-0 shadow-none hover:bg-transparent\"\n inputClassName=\"h-full cursor-pointer\"\n />\n </div>\n )\n}\n\nexport function TimeControl({ value, onChange, ariaLabel }: { value: string; onChange(next: string): void; ariaLabel: string }) {\n return (\n <Input\n type=\"time\"\n value={value}\n onChange={(event) => { if (event.target.value) onChange(event.target.value) }}\n aria-label={ariaLabel}\n className=\"h-9 w-32 shrink-0\"\n />\n )\n}\n\nexport function PersonChip({\n name,\n badge,\n compact,\n onRemove,\n removeLabel,\n}: {\n name: string\n badge?: React.ReactNode\n compact?: boolean\n onRemove?: () => void\n removeLabel?: string\n}) {\n return (\n <span\n className={cn(\n 'inline-flex shrink-0 items-center gap-1.5 rounded-full bg-muted pl-1 pr-2',\n compact ? 'py-0.5' : 'py-1',\n )}\n >\n <Avatar size=\"xs\" label={name} />\n <span className=\"max-w-40 truncate text-xs font-medium text-foreground\">{name}</span>\n {badge}\n {onRemove ? (\n <IconButton\n variant=\"ghost\"\n size=\"xs\"\n onClick={(event) => { event.stopPropagation(); onRemove() }}\n aria-label={removeLabel}\n className=\"size-5 shrink-0\"\n >\n <Plus aria-hidden className=\"size-3.5 rotate-45 opacity-50\" />\n </IconButton>\n ) : null}\n </span>\n )\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { readApiResultOrThrow } from "@open-mercato/ui/backend/utils/apiCall";
|
|
2
|
+
import { fetchAssignableStaffMembers } from "../../detail/assignableStaff.js";
|
|
3
|
+
function readNonEmptyString(value) {
|
|
4
|
+
if (typeof value !== "string") return null;
|
|
5
|
+
const trimmed = value.trim();
|
|
6
|
+
return trimmed.length > 0 ? trimmed : null;
|
|
7
|
+
}
|
|
8
|
+
function extractRelatedEntityOption(item, kind) {
|
|
9
|
+
const id = typeof item.id === "string" ? item.id : null;
|
|
10
|
+
if (!id) return null;
|
|
11
|
+
const displayName = readNonEmptyString(item.displayName) ?? readNonEmptyString(item.display_name);
|
|
12
|
+
const detail = kind === "person" ? readNonEmptyString(item.primaryEmail) ?? readNonEmptyString(item.primary_email) : readNonEmptyString(item.domain) ?? readNonEmptyString(item.websiteUrl) ?? readNonEmptyString(item.website_url);
|
|
13
|
+
const label = displayName ?? detail ?? id;
|
|
14
|
+
return { id, kind, label, subtitle: detail && detail !== label ? detail : null };
|
|
15
|
+
}
|
|
16
|
+
async function searchRelatedEntities(kind, query, signal) {
|
|
17
|
+
const params = new URLSearchParams({ page: "1", pageSize: "20", sortField: "name", sortDir: "asc" });
|
|
18
|
+
if (query.length) params.set("search", query);
|
|
19
|
+
const endpoint = kind === "person" ? `/api/customers/people?${params.toString()}` : `/api/customers/companies?${params.toString()}`;
|
|
20
|
+
const data = await readApiResultOrThrow(endpoint, { signal });
|
|
21
|
+
const items = Array.isArray(data?.items) ? data.items : [];
|
|
22
|
+
return items.map((item) => item && typeof item === "object" ? extractRelatedEntityOption(item, kind) : null).filter((option) => option !== null);
|
|
23
|
+
}
|
|
24
|
+
async function fetchRelatedEntityOfKind(kind, entityId, signal) {
|
|
25
|
+
const params = new URLSearchParams({ page: "1", pageSize: "1", ids: entityId });
|
|
26
|
+
const endpoint = kind === "person" ? `/api/customers/people?${params.toString()}` : `/api/customers/companies?${params.toString()}`;
|
|
27
|
+
try {
|
|
28
|
+
const data = await readApiResultOrThrow(endpoint, { signal });
|
|
29
|
+
const item = Array.isArray(data?.items) ? data.items[0] : null;
|
|
30
|
+
return item && typeof item === "object" ? extractRelatedEntityOption(item, kind) : null;
|
|
31
|
+
} catch {
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
async function fetchRelatedEntityById(entityId, signal) {
|
|
36
|
+
const [person, company] = await Promise.all([
|
|
37
|
+
fetchRelatedEntityOfKind("person", entityId, signal),
|
|
38
|
+
fetchRelatedEntityOfKind("company", entityId, signal)
|
|
39
|
+
]);
|
|
40
|
+
return person ?? company;
|
|
41
|
+
}
|
|
42
|
+
function extractDealOption(item) {
|
|
43
|
+
const id = typeof item.id === "string" ? item.id : null;
|
|
44
|
+
if (!id) return null;
|
|
45
|
+
const label = readNonEmptyString(item.title) ?? id;
|
|
46
|
+
return { id, label };
|
|
47
|
+
}
|
|
48
|
+
async function fetchDealsForEntity(entity, signal) {
|
|
49
|
+
const params = new URLSearchParams({ page: "1", pageSize: "20" });
|
|
50
|
+
params.set(entity.kind === "person" ? "personId" : "companyId", entity.id);
|
|
51
|
+
const data = await readApiResultOrThrow(
|
|
52
|
+
`/api/customers/deals?${params.toString()}`,
|
|
53
|
+
{ signal }
|
|
54
|
+
);
|
|
55
|
+
const items = Array.isArray(data?.items) ? data.items : [];
|
|
56
|
+
return items.map((item) => item && typeof item === "object" ? extractDealOption(item) : null).filter((option) => option !== null);
|
|
57
|
+
}
|
|
58
|
+
async function fetchDealById(dealId, signal) {
|
|
59
|
+
try {
|
|
60
|
+
const params = new URLSearchParams({ page: "1", pageSize: "1", ids: dealId });
|
|
61
|
+
const data = await readApiResultOrThrow(
|
|
62
|
+
`/api/customers/deals?${params.toString()}`,
|
|
63
|
+
{ signal }
|
|
64
|
+
);
|
|
65
|
+
const item = Array.isArray(data?.items) ? data.items[0] : null;
|
|
66
|
+
return item && typeof item === "object" ? extractDealOption(item) : null;
|
|
67
|
+
} catch {
|
|
68
|
+
return null;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
async function searchPeopleOptions(query, options) {
|
|
72
|
+
const [staff, customers] = await Promise.all([
|
|
73
|
+
fetchAssignableStaffMembers(query, { pageSize: 10, signal: options.signal }),
|
|
74
|
+
options.includeCustomers ? searchRelatedEntities("person", query, options.signal) : Promise.resolve([])
|
|
75
|
+
]);
|
|
76
|
+
const staffOptions = staff.map((member) => ({
|
|
77
|
+
userId: member.userId,
|
|
78
|
+
name: member.displayName,
|
|
79
|
+
email: member.email,
|
|
80
|
+
isCustomer: false
|
|
81
|
+
}));
|
|
82
|
+
const customerOptions = customers.map((person) => ({
|
|
83
|
+
userId: person.id,
|
|
84
|
+
name: person.label,
|
|
85
|
+
email: person.subtitle,
|
|
86
|
+
isCustomer: true
|
|
87
|
+
}));
|
|
88
|
+
return [...staffOptions, ...customerOptions];
|
|
89
|
+
}
|
|
90
|
+
async function findStaffMemberName(userId, signal) {
|
|
91
|
+
try {
|
|
92
|
+
const members = await fetchAssignableStaffMembers("", { pageSize: 100, signal });
|
|
93
|
+
const match = members.find((member) => member.userId === userId);
|
|
94
|
+
return match ? match.displayName : null;
|
|
95
|
+
} catch {
|
|
96
|
+
return null;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
export {
|
|
100
|
+
fetchDealById,
|
|
101
|
+
fetchDealsForEntity,
|
|
102
|
+
fetchRelatedEntityById,
|
|
103
|
+
findStaffMemberName,
|
|
104
|
+
searchPeopleOptions,
|
|
105
|
+
searchRelatedEntities
|
|
106
|
+
};
|
|
107
|
+
//# sourceMappingURL=lookups.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../../../src/modules/customers/components/calendar/editor/lookups.ts"],
|
|
4
|
+
"sourcesContent": ["import { readApiResultOrThrow } from '@open-mercato/ui/backend/utils/apiCall'\nimport { fetchAssignableStaffMembers } from '../../detail/assignableStaff'\n\nexport type RelatedEntityKind = 'person' | 'company'\n\nexport type RelatedEntityOption = {\n id: string\n kind: RelatedEntityKind\n label: string\n subtitle: string | null\n}\n\nexport type DealOption = {\n id: string\n label: string\n}\n\nexport type PersonOption = {\n userId: string\n name: string\n email: string | null\n isCustomer: boolean\n}\n\nfunction readNonEmptyString(value: unknown): string | null {\n if (typeof value !== 'string') return null\n const trimmed = value.trim()\n return trimmed.length > 0 ? trimmed : null\n}\n\nfunction extractRelatedEntityOption(item: Record<string, unknown>, kind: RelatedEntityKind): RelatedEntityOption | null {\n const id = typeof item.id === 'string' ? item.id : null\n if (!id) return null\n const displayName = readNonEmptyString(item.displayName) ?? readNonEmptyString(item.display_name)\n const detail = kind === 'person'\n ? readNonEmptyString(item.primaryEmail) ?? readNonEmptyString(item.primary_email)\n : readNonEmptyString(item.domain)\n ?? readNonEmptyString(item.websiteUrl)\n ?? readNonEmptyString(item.website_url)\n const label = displayName ?? detail ?? id\n return { id, kind, label, subtitle: detail && detail !== label ? detail : null }\n}\n\n// Same lookup source as the deal-association pattern in DealForm\n// (useDealAssociationLookups): the people/companies CRUD list APIs with\n// `search` + name sorting, merged into a single related-to picker.\nexport async function searchRelatedEntities(\n kind: RelatedEntityKind,\n query: string,\n signal: AbortSignal,\n): Promise<RelatedEntityOption[]> {\n const params = new URLSearchParams({ page: '1', pageSize: '20', sortField: 'name', sortDir: 'asc' })\n if (query.length) params.set('search', query)\n const endpoint = kind === 'person'\n ? `/api/customers/people?${params.toString()}`\n : `/api/customers/companies?${params.toString()}`\n const data = await readApiResultOrThrow<{ items?: Array<Record<string, unknown>> }>(endpoint, { signal })\n const items = Array.isArray(data?.items) ? data.items : []\n return items\n .map((item) => (item && typeof item === 'object' ? extractRelatedEntityOption(item, kind) : null))\n .filter((option): option is RelatedEntityOption => option !== null)\n}\n\nasync function fetchRelatedEntityOfKind(\n kind: RelatedEntityKind,\n entityId: string,\n signal: AbortSignal,\n): Promise<RelatedEntityOption | null> {\n const params = new URLSearchParams({ page: '1', pageSize: '1', ids: entityId })\n const endpoint = kind === 'person'\n ? `/api/customers/people?${params.toString()}`\n : `/api/customers/companies?${params.toString()}`\n try {\n const data = await readApiResultOrThrow<{ items?: Array<Record<string, unknown>> }>(endpoint, { signal })\n const item = Array.isArray(data?.items) ? data.items[0] : null\n return item && typeof item === 'object' ? extractRelatedEntityOption(item, kind) : null\n } catch {\n return null\n }\n}\n\nexport async function fetchRelatedEntityById(entityId: string, signal: AbortSignal): Promise<RelatedEntityOption | null> {\n const [person, company] = await Promise.all([\n fetchRelatedEntityOfKind('person', entityId, signal),\n fetchRelatedEntityOfKind('company', entityId, signal),\n ])\n return person ?? company\n}\n\nfunction extractDealOption(item: Record<string, unknown>): DealOption | null {\n const id = typeof item.id === 'string' ? item.id : null\n if (!id) return null\n const label = readNonEmptyString(item.title) ?? id\n return { id, label }\n}\n\nexport async function fetchDealsForEntity(\n entity: { id: string; kind: RelatedEntityKind },\n signal: AbortSignal,\n): Promise<DealOption[]> {\n const params = new URLSearchParams({ page: '1', pageSize: '20' })\n params.set(entity.kind === 'person' ? 'personId' : 'companyId', entity.id)\n const data = await readApiResultOrThrow<{ items?: Array<Record<string, unknown>> }>(\n `/api/customers/deals?${params.toString()}`,\n { signal },\n )\n const items = Array.isArray(data?.items) ? data.items : []\n return items\n .map((item) => (item && typeof item === 'object' ? extractDealOption(item) : null))\n .filter((option): option is DealOption => option !== null)\n}\n\nexport async function fetchDealById(dealId: string, signal: AbortSignal): Promise<DealOption | null> {\n try {\n const params = new URLSearchParams({ page: '1', pageSize: '1', ids: dealId })\n const data = await readApiResultOrThrow<{ items?: Array<Record<string, unknown>> }>(\n `/api/customers/deals?${params.toString()}`,\n { signal },\n )\n const item = Array.isArray(data?.items) ? data.items[0] : null\n return item && typeof item === 'object' ? extractDealOption(item) : null\n } catch {\n return null\n }\n}\n\nexport async function searchPeopleOptions(\n query: string,\n options: { includeCustomers: boolean; signal: AbortSignal },\n): Promise<PersonOption[]> {\n const [staff, customers] = await Promise.all([\n fetchAssignableStaffMembers(query, { pageSize: 10, signal: options.signal }),\n options.includeCustomers\n ? searchRelatedEntities('person', query, options.signal)\n : Promise.resolve<RelatedEntityOption[]>([]),\n ])\n const staffOptions: PersonOption[] = staff.map((member) => ({\n userId: member.userId,\n name: member.displayName,\n email: member.email,\n isCustomer: false,\n }))\n const customerOptions: PersonOption[] = customers.map((person) => ({\n userId: person.id,\n name: person.label,\n email: person.subtitle,\n isCustomer: true,\n }))\n return [...staffOptions, ...customerOptions]\n}\n\nexport async function findStaffMemberName(userId: string, signal: AbortSignal): Promise<string | null> {\n try {\n const members = await fetchAssignableStaffMembers('', { pageSize: 100, signal })\n const match = members.find((member) => member.userId === userId)\n return match ? match.displayName : null\n } catch {\n return null\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
const calendarParticipantSchema = z.object({
|
|
3
|
+
userId: z.string(),
|
|
4
|
+
name: z.string().optional(),
|
|
5
|
+
email: z.string().optional()
|
|
6
|
+
}).passthrough();
|
|
7
|
+
const calendarInteractionPayloadSchema = z.object({
|
|
8
|
+
id: z.string(),
|
|
9
|
+
interactionType: z.string(),
|
|
10
|
+
title: z.string().nullable().optional(),
|
|
11
|
+
status: z.string(),
|
|
12
|
+
scheduledAt: z.string().nullable().optional(),
|
|
13
|
+
occurredAt: z.string().nullable().optional(),
|
|
14
|
+
durationMinutes: z.number().nullable().optional(),
|
|
15
|
+
allDay: z.boolean().nullable().optional(),
|
|
16
|
+
location: z.string().nullable().optional(),
|
|
17
|
+
participants: z.array(calendarParticipantSchema).nullable().optional(),
|
|
18
|
+
recurrenceRule: z.string().nullable().optional(),
|
|
19
|
+
recurrenceEnd: z.string().nullable().optional(),
|
|
20
|
+
appearanceIcon: z.string().nullable().optional(),
|
|
21
|
+
appearanceColor: z.string().nullable().optional(),
|
|
22
|
+
ownerUserId: z.string().nullable().optional(),
|
|
23
|
+
entityId: z.string().nullable().optional(),
|
|
24
|
+
dealId: z.string().nullable().optional(),
|
|
25
|
+
updatedAt: z.string().nullable().optional()
|
|
26
|
+
}).passthrough();
|
|
27
|
+
export {
|
|
28
|
+
calendarInteractionPayloadSchema
|
|
29
|
+
};
|
|
30
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../../src/modules/customers/components/calendar/types.ts"],
|
|
4
|
+
"sourcesContent": ["import { z } from 'zod'\n\nexport type CalendarView = 'day' | 'week' | 'month' | 'agenda'\n\nexport type CalendarCategory = 'meeting' | 'event' | 'task' | 'other'\n\nexport type CalendarItemStatus = 'planned' | 'done' | 'canceled'\n\nexport type CalendarPlatform = 'zoom' | 'meet' | 'slack' | 'teams'\n\nexport type CalendarLocationKind = 'url' | 'venue' | 'platform'\n\nexport type CalendarTab = 'all' | 'meetings' | 'events'\n\nexport type CalendarRangePreset = 'thisWeek' | 'next7' | 'thisMonth' | 'next30'\n\nexport type CalendarRange = { from: Date; to: Date }\n\nconst calendarParticipantSchema = z\n .object({\n userId: z.string(),\n name: z.string().optional(),\n email: z.string().optional(),\n })\n .passthrough()\n\nexport const calendarInteractionPayloadSchema = z\n .object({\n id: z.string(),\n interactionType: z.string(),\n title: z.string().nullable().optional(),\n status: z.string(),\n scheduledAt: z.string().nullable().optional(),\n occurredAt: z.string().nullable().optional(),\n durationMinutes: z.number().nullable().optional(),\n allDay: z.boolean().nullable().optional(),\n location: z.string().nullable().optional(),\n participants: z.array(calendarParticipantSchema).nullable().optional(),\n recurrenceRule: z.string().nullable().optional(),\n recurrenceEnd: z.string().nullable().optional(),\n appearanceIcon: z.string().nullable().optional(),\n appearanceColor: z.string().nullable().optional(),\n ownerUserId: z.string().nullable().optional(),\n entityId: z.string().nullable().optional(),\n dealId: z.string().nullable().optional(),\n updatedAt: z.string().nullable().optional(),\n })\n .passthrough()\n\nexport type CalendarInteractionPayload = z.infer<typeof calendarInteractionPayloadSchema>\n\nexport type CalendarParticipant = { userId: string; name?: string; email?: string }\n\nexport interface CalendarItem {\n id: string\n title: string\n interactionType: string\n category: CalendarCategory\n status: CalendarItemStatus\n start: Date\n end: Date\n allDay: boolean\n location: string | null\n platform: CalendarPlatform | null\n locationKind: CalendarLocationKind | null\n participants: CalendarParticipant[]\n ownerUserId: string | null\n entityId: string | null\n dealId: string | null\n color: string | null\n isRecurringOccurrence: boolean\n updatedAt: string | null\n raw: CalendarInteractionPayload\n}\n\nexport interface CalendarFiltersValue {\n types: string[]\n status: string | null\n ownerUserId: string | null\n}\n\nexport interface TimeGridProps {\n days: 1 | 7\n anchor: Date\n items: CalendarItem[]\n conflictIds: Set<string>\n showWeekends: boolean\n showConflicts: boolean\n aiSummaries: boolean\n highlightItemId?: string | null\n onItemClick(item: CalendarItem): void\n onJoin(item: CalendarItem): void\n onNavigate(deltaDays: number): void\n onCreate?: () => void\n onCreateRange?(start: Date, end: Date): void\n}\n\nexport interface MonthGridProps {\n anchor: Date\n items: CalendarItem[]\n onItemClick(item: CalendarItem): void\n onDayOpen(date: Date): void\n}\n\nexport interface AgendaListProps {\n anchor: Date\n horizonDays: number\n items: CalendarItem[]\n typeLabels?: Record<string, string>\n onItemClick(item: CalendarItem): void\n}\n\nexport interface UpcomingCard {\n item: CalendarItem\n kind: 'today' | 'conflicted' | 'cancelled' | 'future'\n conflictCount: number\n}\n\nexport interface UpcomingCardsProps {\n cards: UpcomingCard[]\n canManage?: boolean\n onJoin(item: CalendarItem): void\n onSeeConflict(item: CalendarItem): void\n onOpen(item: CalendarItem): void\n onEdit(item: CalendarItem): void\n onCancel(item: CalendarItem): void\n}\n\nexport interface CalendarHeaderProps {\n view: CalendarView\n anchor: Date\n onNewEvent?: () => void\n}\n\nexport interface CalendarToolbarProps {\n view: CalendarView\n anchor: Date\n range: CalendarRange\n preset: CalendarRangePreset | null\n search: string\n filters: CalendarFiltersValue\n typeOptions: Array<{ value: string; label: string }>\n ownerOptions: Array<{ value: string; label: string }>\n onToday(): void\n onPresetChange(preset: CalendarRangePreset): void\n onAnchorChange(date: Date): void\n onSearchChange(value: string): void\n onFiltersChange(value: CalendarFiltersValue): void\n onOpenSettings(): void\n}\n\nexport interface CalendarTabsProps {\n tab: CalendarTab\n counts: { all: number; meetings: number; events: number }\n view: CalendarView\n onTabChange(tab: CalendarTab): void\n onViewChange(view: CalendarView): void\n}\n\nexport interface CalendarFooterProps {\n timezoneLabel: string\n onOpenShortcuts?: () => void\n}\n"],
|
|
5
|
+
"mappings": "AAAA,SAAS,SAAS;AAkBlB,MAAM,4BAA4B,EAC/B,OAAO;AAAA,EACN,QAAQ,EAAE,OAAO;AAAA,EACjB,MAAM,EAAE,OAAO,EAAE,SAAS;AAAA,EAC1B,OAAO,EAAE,OAAO,EAAE,SAAS;AAC7B,CAAC,EACA,YAAY;AAER,MAAM,mCAAmC,EAC7C,OAAO;AAAA,EACN,IAAI,EAAE,OAAO;AAAA,EACb,iBAAiB,EAAE,OAAO;AAAA,EAC1B,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS;AAAA,EACtC,QAAQ,EAAE,OAAO;AAAA,EACjB,aAAa,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS;AAAA,EAC5C,YAAY,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS;AAAA,EAC3C,iBAAiB,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS;AAAA,EAChD,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS;AAAA,EACxC,UAAU,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS;AAAA,EACzC,cAAc,EAAE,MAAM,yBAAyB,EAAE,SAAS,EAAE,SAAS;AAAA,EACrE,gBAAgB,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS;AAAA,EAC/C,eAAe,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS;AAAA,EAC9C,gBAAgB,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS;AAAA,EAC/C,iBAAiB,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS;AAAA,EAChD,aAAa,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS;AAAA,EAC5C,UAAU,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS;AAAA,EACzC,QAAQ,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS;AAAA,EACvC,WAAW,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS;AAC5C,CAAC,EACA,YAAY;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|