@open-mercato/core 0.9.0 → 0.9.1-develop.7459.1.99e3accd30

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.
Files changed (243) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/dist/generated/entities/customer_dictionary_entry/index.js +2 -0
  3. package/dist/generated/entities/customer_dictionary_entry/index.js.map +2 -2
  4. package/dist/generated/entities/customer_interaction/index.js +2 -0
  5. package/dist/generated/entities/customer_interaction/index.js.map +2 -2
  6. package/dist/generated/entity-fields-registry.js +2 -0
  7. package/dist/generated/entity-fields-registry.js.map +2 -2
  8. package/dist/modules/catalog/commands/categories.js +1 -1
  9. package/dist/modules/catalog/commands/categories.js.map +2 -2
  10. package/dist/modules/catalog/commands/productDeleteChildren.js +389 -0
  11. package/dist/modules/catalog/commands/productDeleteChildren.js.map +7 -0
  12. package/dist/modules/catalog/commands/products.js +52 -17
  13. package/dist/modules/catalog/commands/products.js.map +2 -2
  14. package/dist/modules/communication_channels/api/post/channels/connect/credentials/route.js +4 -6
  15. package/dist/modules/communication_channels/api/post/channels/connect/credentials/route.js.map +2 -2
  16. package/dist/modules/communication_channels/api/post/channels/connect/tenant-credentials/route.js +4 -6
  17. package/dist/modules/communication_channels/api/post/channels/connect/tenant-credentials/route.js.map +2 -2
  18. package/dist/modules/communication_channels/api/post/oauth/[provider]/initiate/route.js +47 -11
  19. package/dist/modules/communication_channels/api/post/oauth/[provider]/initiate/route.js.map +3 -3
  20. package/dist/modules/communication_channels/commands/deliver-outbound-message.js +5 -1
  21. package/dist/modules/communication_channels/commands/deliver-outbound-message.js.map +2 -2
  22. package/dist/modules/communication_channels/lib/inbound-message-origin.js +1 -1
  23. package/dist/modules/communication_channels/lib/inbound-message-origin.js.map +2 -2
  24. package/dist/modules/communication_channels/lib/oauth-state.js +4 -1
  25. package/dist/modules/communication_channels/lib/oauth-state.js.map +2 -2
  26. package/dist/modules/communication_channels/lib/use-connect-channel.js +10 -0
  27. package/dist/modules/communication_channels/lib/use-connect-channel.js.map +2 -2
  28. package/dist/modules/customers/api/activity-types/route.js +151 -0
  29. package/dist/modules/customers/api/activity-types/route.js.map +7 -0
  30. package/dist/modules/customers/api/deals/[id]/people/route.js +58 -5
  31. package/dist/modules/customers/api/deals/[id]/people/route.js.map +2 -2
  32. package/dist/modules/customers/api/dictionaries/[kind]/[id]/route.js +13 -5
  33. package/dist/modules/customers/api/dictionaries/[kind]/[id]/route.js.map +2 -2
  34. package/dist/modules/customers/api/dictionaries/[kind]/route.js +20 -5
  35. package/dist/modules/customers/api/dictionaries/[kind]/route.js.map +2 -2
  36. package/dist/modules/customers/api/interactions/route.js +3 -0
  37. package/dist/modules/customers/api/interactions/route.js.map +2 -2
  38. package/dist/modules/customers/api/interactions/tasks/route.js +1 -0
  39. package/dist/modules/customers/api/interactions/tasks/route.js.map +2 -2
  40. package/dist/modules/customers/backend/config/customers/pipeline-stages/page.meta.js +18 -0
  41. package/dist/modules/customers/backend/config/customers/pipeline-stages/page.meta.js.map +2 -2
  42. package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealAssociations.js +0 -23
  43. package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealAssociations.js.map +2 -2
  44. package/dist/modules/customers/backend/customers/deals/[id]/page.js +15 -17
  45. package/dist/modules/customers/backend/customers/deals/[id]/page.js.map +2 -2
  46. package/dist/modules/customers/calendar-event-types.js +548 -0
  47. package/dist/modules/customers/calendar-event-types.js.map +7 -0
  48. package/dist/modules/customers/commands/dictionaries.js +70 -10
  49. package/dist/modules/customers/commands/dictionaries.js.map +2 -2
  50. package/dist/modules/customers/commands/interactions.js +187 -22
  51. package/dist/modules/customers/commands/interactions.js.map +3 -3
  52. package/dist/modules/customers/components/ActivityTypeEditor.js +288 -0
  53. package/dist/modules/customers/components/ActivityTypeEditor.js.map +7 -0
  54. package/dist/modules/customers/components/DictionarySettings.js +3 -1
  55. package/dist/modules/customers/components/DictionarySettings.js.map +2 -2
  56. package/dist/modules/customers/components/calendar/CalendarEventEditor.js +391 -297
  57. package/dist/modules/customers/components/calendar/CalendarEventEditor.js.map +3 -3
  58. package/dist/modules/customers/components/calendar/CalendarSettingsModal.js +9 -74
  59. package/dist/modules/customers/components/calendar/CalendarSettingsModal.js.map +2 -2
  60. package/dist/modules/customers/components/calendar/TimeGrid.js +20 -16
  61. package/dist/modules/customers/components/calendar/TimeGrid.js.map +2 -2
  62. package/dist/modules/customers/components/calendar/editor/EventTypePanel.js +218 -0
  63. package/dist/modules/customers/components/calendar/editor/EventTypePanel.js.map +7 -0
  64. package/dist/modules/customers/components/calendar/editor/LocationField.js +7 -3
  65. package/dist/modules/customers/components/calendar/editor/LocationField.js.map +2 -2
  66. package/dist/modules/customers/components/calendar/editor/PeopleField.js +5 -2
  67. package/dist/modules/customers/components/calendar/editor/PeopleField.js.map +2 -2
  68. package/dist/modules/customers/components/calendar/editor/PriorityField.js +3 -1
  69. package/dist/modules/customers/components/calendar/editor/PriorityField.js.map +2 -2
  70. package/dist/modules/customers/components/calendar/editor/RepeatField.js +9 -1
  71. package/dist/modules/customers/components/calendar/editor/RepeatField.js.map +2 -2
  72. package/dist/modules/customers/components/calendar/editor/ResourcesField.js +4 -1
  73. package/dist/modules/customers/components/calendar/editor/ResourcesField.js.map +2 -2
  74. package/dist/modules/customers/components/calendar/editor/ScheduleSection.js +15 -7
  75. package/dist/modules/customers/components/calendar/editor/ScheduleSection.js.map +2 -2
  76. package/dist/modules/customers/components/calendar/editor/SegmentGroup.js +3 -1
  77. package/dist/modules/customers/components/calendar/editor/SegmentGroup.js.map +2 -2
  78. package/dist/modules/customers/components/calendar/editor/hooks.js +28 -13
  79. package/dist/modules/customers/components/calendar/editor/hooks.js.map +3 -3
  80. package/dist/modules/customers/components/calendar/editor/inputs.js +14 -6
  81. package/dist/modules/customers/components/calendar/editor/inputs.js.map +2 -2
  82. package/dist/modules/customers/components/calendar/editor/useCalendarCustomFields.js +54 -0
  83. package/dist/modules/customers/components/calendar/editor/useCalendarCustomFields.js.map +7 -0
  84. package/dist/modules/customers/components/calendar/editor/useEventTypeCatalog.js +82 -0
  85. package/dist/modules/customers/components/calendar/editor/useEventTypeCatalog.js.map +7 -0
  86. package/dist/modules/customers/components/calendar/types.js +1 -0
  87. package/dist/modules/customers/components/calendar/types.js.map +2 -2
  88. package/dist/modules/customers/components/detail/CompanyPeopleSection.js +78 -343
  89. package/dist/modules/customers/components/detail/CompanyPeopleSection.js.map +2 -2
  90. package/dist/modules/customers/components/detail/CreatePersonDialog.js +12 -11
  91. package/dist/modules/customers/components/detail/CreatePersonDialog.js.map +2 -2
  92. package/dist/modules/customers/components/detail/DealForm.js +7 -3
  93. package/dist/modules/customers/components/detail/DealForm.js.map +2 -2
  94. package/dist/modules/customers/components/detail/DealPeopleSection.js +206 -0
  95. package/dist/modules/customers/components/detail/DealPeopleSection.js.map +7 -0
  96. package/dist/modules/customers/components/detail/LinkedPeopleSection.js +342 -0
  97. package/dist/modules/customers/components/detail/LinkedPeopleSection.js.map +7 -0
  98. package/dist/modules/customers/components/detail/PersonCard.js +5 -2
  99. package/dist/modules/customers/components/detail/PersonCard.js.map +2 -2
  100. package/dist/modules/customers/components/linking/adapters/personAdapter.js +3 -0
  101. package/dist/modules/customers/components/linking/adapters/personAdapter.js.map +2 -2
  102. package/dist/modules/customers/data/entities.js +6 -0
  103. package/dist/modules/customers/data/entities.js.map +2 -2
  104. package/dist/modules/customers/data/validators.js +39 -10
  105. package/dist/modules/customers/data/validators.js.map +2 -2
  106. package/dist/modules/customers/di.js +20 -1
  107. package/dist/modules/customers/di.js.map +2 -2
  108. package/dist/modules/customers/extension-points.js +13 -0
  109. package/dist/modules/customers/extension-points.js.map +2 -2
  110. package/dist/modules/customers/lib/calendar/conflicts.js +59 -16
  111. package/dist/modules/customers/lib/calendar/conflicts.js.map +2 -2
  112. package/dist/modules/customers/lib/calendar/editorPayload.js +34 -16
  113. package/dist/modules/customers/lib/calendar/editorPayload.js.map +2 -2
  114. package/dist/modules/customers/lib/calendar/eventTypeResolver.js +197 -0
  115. package/dist/modules/customers/lib/calendar/eventTypeResolver.js.map +7 -0
  116. package/dist/modules/customers/lib/calendar/interactionApplicability.js +67 -0
  117. package/dist/modules/customers/lib/calendar/interactionApplicability.js.map +7 -0
  118. package/dist/modules/customers/lib/calendar/mapItem.js +5 -2
  119. package/dist/modules/customers/lib/calendar/mapItem.js.map +2 -2
  120. package/dist/modules/customers/lib/calendar/recurrence.js +62 -1
  121. package/dist/modules/customers/lib/calendar/recurrence.js.map +2 -2
  122. package/dist/modules/customers/lib/calendar/timezone.js +111 -0
  123. package/dist/modules/customers/lib/calendar/timezone.js.map +7 -0
  124. package/dist/modules/customers/lib/interactionReadModel.js +1 -0
  125. package/dist/modules/customers/lib/interactionReadModel.js.map +2 -2
  126. package/dist/modules/customers/lib/todoCompatibility.js +1 -0
  127. package/dist/modules/customers/lib/todoCompatibility.js.map +2 -2
  128. package/dist/modules/customers/migrations/Migration20260928175058_customers.js +17 -0
  129. package/dist/modules/customers/migrations/Migration20260928175058_customers.js.map +7 -0
  130. package/dist/modules/customers/migrations/Migration20260930110235_customers.js +17 -0
  131. package/dist/modules/customers/migrations/Migration20260930110235_customers.js.map +7 -0
  132. package/dist/modules/dictionaries/components/DictionaryTable.js +60 -51
  133. package/dist/modules/dictionaries/components/DictionaryTable.js.map +2 -2
  134. package/dist/modules/messages/subscribers/message-notification.js +13 -1
  135. package/dist/modules/messages/subscribers/message-notification.js.map +2 -2
  136. package/dist/modules/payment_gateways/api/webhook/[provider]/route.js +201 -53
  137. package/dist/modules/payment_gateways/api/webhook/[provider]/route.js.map +2 -2
  138. package/dist/modules/payment_gateways/lib/gateway-service.js +37 -11
  139. package/dist/modules/payment_gateways/lib/gateway-service.js.map +2 -2
  140. package/dist/modules/planner/lib/availabilityMerge.js +101 -38
  141. package/dist/modules/planner/lib/availabilityMerge.js.map +3 -3
  142. package/dist/modules/planner/services/plannerAvailabilityService.js.map +2 -2
  143. package/dist/modules/sales/components/documents/LineItemDialog.js +159 -81
  144. package/dist/modules/sales/components/documents/LineItemDialog.js.map +2 -2
  145. package/dist/modules/sales/components/documents/lineItemUtils.js +7 -0
  146. package/dist/modules/sales/components/documents/lineItemUtils.js.map +2 -2
  147. package/dist/modules/staff/backend/staff/time-tracking/projects/[id]/page.js +12 -7
  148. package/dist/modules/staff/backend/staff/time-tracking/projects/[id]/page.js.map +2 -2
  149. package/dist/modules/sync_excel/lib/adapters/customers.js +28 -25
  150. package/dist/modules/sync_excel/lib/adapters/customers.js.map +2 -2
  151. package/generated/entities/customer_dictionary_entry/index.ts +1 -0
  152. package/generated/entities/customer_interaction/index.ts +1 -0
  153. package/generated/entity-fields-registry.ts +2 -0
  154. package/package.json +9 -8
  155. package/src/modules/auth/i18n/de.json +3 -0
  156. package/src/modules/auth/i18n/en.json +3 -0
  157. package/src/modules/auth/i18n/es.json +3 -0
  158. package/src/modules/auth/i18n/ko.json +3 -0
  159. package/src/modules/auth/i18n/pl.json +3 -0
  160. package/src/modules/catalog/commands/categories.ts +1 -1
  161. package/src/modules/catalog/commands/productDeleteChildren.ts +557 -0
  162. package/src/modules/catalog/commands/products.ts +58 -17
  163. package/src/modules/communication_channels/api/post/channels/connect/credentials/route.ts +4 -6
  164. package/src/modules/communication_channels/api/post/channels/connect/tenant-credentials/route.ts +4 -6
  165. package/src/modules/communication_channels/api/post/oauth/[provider]/initiate/route.ts +46 -10
  166. package/src/modules/communication_channels/commands/deliver-outbound-message.ts +6 -1
  167. package/src/modules/communication_channels/i18n/de.json +4 -0
  168. package/src/modules/communication_channels/i18n/en.json +4 -0
  169. package/src/modules/communication_channels/i18n/es.json +4 -0
  170. package/src/modules/communication_channels/i18n/ko.json +4 -0
  171. package/src/modules/communication_channels/i18n/pl.json +4 -0
  172. package/src/modules/communication_channels/lib/inbound-message-origin.ts +2 -6
  173. package/src/modules/communication_channels/lib/oauth-state.ts +4 -1
  174. package/src/modules/communication_channels/lib/use-connect-channel.ts +10 -0
  175. package/src/modules/customers/api/activity-types/route.ts +154 -0
  176. package/src/modules/customers/api/deals/[id]/people/route.ts +82 -3
  177. package/src/modules/customers/api/dictionaries/[kind]/[id]/route.ts +9 -1
  178. package/src/modules/customers/api/dictionaries/[kind]/route.ts +18 -2
  179. package/src/modules/customers/api/interactions/route.ts +4 -0
  180. package/src/modules/customers/api/interactions/tasks/route.ts +1 -0
  181. package/src/modules/customers/backend/config/customers/pipeline-stages/page.meta.ts +20 -0
  182. package/src/modules/customers/backend/customers/deals/[id]/hooks/useDealAssociations.ts +0 -29
  183. package/src/modules/customers/backend/customers/deals/[id]/page.tsx +15 -17
  184. package/src/modules/customers/calendar-event-types.ts +674 -0
  185. package/src/modules/customers/commands/dictionaries.ts +84 -8
  186. package/src/modules/customers/commands/interactions.ts +244 -21
  187. package/src/modules/customers/components/ActivityTypeEditor.tsx +239 -0
  188. package/src/modules/customers/components/DictionarySettings.tsx +5 -3
  189. package/src/modules/customers/components/calendar/CalendarEventEditor.tsx +347 -218
  190. package/src/modules/customers/components/calendar/CalendarSettingsModal.tsx +18 -96
  191. package/src/modules/customers/components/calendar/TimeGrid.tsx +20 -18
  192. package/src/modules/customers/components/calendar/editor/EventTypePanel.tsx +230 -0
  193. package/src/modules/customers/components/calendar/editor/LocationField.tsx +7 -1
  194. package/src/modules/customers/components/calendar/editor/PeopleField.tsx +4 -0
  195. package/src/modules/customers/components/calendar/editor/PriorityField.tsx +3 -0
  196. package/src/modules/customers/components/calendar/editor/RepeatField.tsx +10 -0
  197. package/src/modules/customers/components/calendar/editor/ResourcesField.tsx +4 -0
  198. package/src/modules/customers/components/calendar/editor/ScheduleSection.tsx +16 -4
  199. package/src/modules/customers/components/calendar/editor/SegmentGroup.tsx +3 -0
  200. package/src/modules/customers/components/calendar/editor/hooks.ts +29 -13
  201. package/src/modules/customers/components/calendar/editor/inputs.tsx +17 -5
  202. package/src/modules/customers/components/calendar/editor/useCalendarCustomFields.ts +49 -0
  203. package/src/modules/customers/components/calendar/editor/useEventTypeCatalog.ts +100 -0
  204. package/src/modules/customers/components/calendar/types.ts +1 -0
  205. package/src/modules/customers/components/detail/CompanyPeopleSection.tsx +94 -388
  206. package/src/modules/customers/components/detail/CreatePersonDialog.tsx +39 -19
  207. package/src/modules/customers/components/detail/DealForm.tsx +7 -3
  208. package/src/modules/customers/components/detail/DealPeopleSection.tsx +256 -0
  209. package/src/modules/customers/components/detail/LinkedPeopleSection.tsx +474 -0
  210. package/src/modules/customers/components/detail/PersonCard.tsx +12 -4
  211. package/src/modules/customers/components/detail/types.ts +1 -0
  212. package/src/modules/customers/components/linking/adapters/personAdapter.tsx +4 -0
  213. package/src/modules/customers/data/entities.ts +8 -1
  214. package/src/modules/customers/data/validators.ts +42 -7
  215. package/src/modules/customers/di.ts +21 -0
  216. package/src/modules/customers/extension-points.ts +13 -0
  217. package/src/modules/customers/i18n/de.json +104 -8
  218. package/src/modules/customers/i18n/en.json +104 -8
  219. package/src/modules/customers/i18n/es.json +104 -8
  220. package/src/modules/customers/i18n/ko.json +104 -8
  221. package/src/modules/customers/i18n/pl.json +104 -8
  222. package/src/modules/customers/lib/calendar/conflicts.ts +106 -27
  223. package/src/modules/customers/lib/calendar/editorPayload.ts +39 -19
  224. package/src/modules/customers/lib/calendar/eventTypeResolver.ts +258 -0
  225. package/src/modules/customers/lib/calendar/interactionApplicability.ts +99 -0
  226. package/src/modules/customers/lib/calendar/mapItem.ts +6 -2
  227. package/src/modules/customers/lib/calendar/recurrence.ts +65 -1
  228. package/src/modules/customers/lib/calendar/timezone.ts +117 -0
  229. package/src/modules/customers/lib/interactionReadModel.ts +1 -0
  230. package/src/modules/customers/lib/todoCompatibility.ts +2 -0
  231. package/src/modules/customers/migrations/.snapshot-open-mercato.json +34 -0
  232. package/src/modules/customers/migrations/Migration20260928175058_customers.ts +15 -0
  233. package/src/modules/customers/migrations/Migration20260930110235_customers.ts +15 -0
  234. package/src/modules/dictionaries/components/DictionaryTable.tsx +63 -56
  235. package/src/modules/messages/subscribers/message-notification.ts +13 -3
  236. package/src/modules/payment_gateways/api/webhook/[provider]/route.ts +243 -62
  237. package/src/modules/payment_gateways/lib/gateway-service.ts +39 -12
  238. package/src/modules/planner/lib/availabilityMerge.ts +106 -41
  239. package/src/modules/planner/services/plannerAvailabilityService.ts +4 -0
  240. package/src/modules/sales/components/documents/LineItemDialog.tsx +194 -111
  241. package/src/modules/sales/components/documents/lineItemUtils.ts +18 -0
  242. package/src/modules/staff/backend/staff/time-tracking/projects/[id]/page.tsx +25 -13
  243. package/src/modules/sync_excel/lib/adapters/customers.ts +33 -27
@@ -54,13 +54,14 @@ function UppercaseBadge({ style, className, children }) {
54
54
  }
55
55
  );
56
56
  }
57
- function AllDayToggle({ checked, onCheckedChange, label }) {
57
+ function AllDayToggle({ checked, onCheckedChange, label, disabled }) {
58
58
  return /* @__PURE__ */ jsx(
59
59
  Switch,
60
60
  {
61
61
  checked,
62
62
  "aria-label": label,
63
63
  onCheckedChange,
64
+ disabled,
64
65
  className: "h-6 w-10"
65
66
  }
66
67
  );
@@ -85,7 +86,8 @@ function DateControl({
85
86
  value,
86
87
  onChange,
87
88
  ariaLabel,
88
- className
89
+ className,
90
+ disabled
89
91
  }) {
90
92
  const [open, setOpen] = React.useState(false);
91
93
  useCloseOnEditorScroll(setOpen);
@@ -100,6 +102,7 @@ function DateControl({
100
102
  open,
101
103
  onOpenChange: setOpen,
102
104
  "aria-label": ariaLabel,
105
+ disabled,
103
106
  className: cn("w-full", className)
104
107
  }
105
108
  );
@@ -109,11 +112,14 @@ const TIME_OPTIONS = Array.from({ length: 48 }, (_, index) => {
109
112
  const minute = index % 2 === 0 ? "00" : "30";
110
113
  return `${String(hour).padStart(2, "0")}:${minute}`;
111
114
  });
112
- function TimeControl({ value, onChange, ariaLabel }) {
115
+ function TimeControl({ value, onChange, ariaLabel, disabled }) {
113
116
  const [open, setOpen] = React.useState(false);
114
117
  useCloseOnEditorScroll(setOpen);
115
- const options = value && !TIME_OPTIONS.includes(value) ? [value, ...TIME_OPTIONS] : TIME_OPTIONS;
116
- return /* @__PURE__ */ jsxs(Select, { value, onValueChange: onChange, open, onOpenChange: setOpen, children: [
118
+ const options = React.useMemo(() => {
119
+ if (!open) return value ? [value] : [];
120
+ return value && !TIME_OPTIONS.includes(value) ? [value, ...TIME_OPTIONS] : TIME_OPTIONS;
121
+ }, [open, value]);
122
+ return /* @__PURE__ */ jsxs(Select, { value, onValueChange: onChange, open, onOpenChange: setOpen, disabled, children: [
117
123
  /* @__PURE__ */ jsx(SelectTrigger, { "aria-label": ariaLabel, className: "h-9 w-32 shrink-0", children: /* @__PURE__ */ jsx(SelectValue, {}) }),
118
124
  /* @__PURE__ */ jsx(SelectContent, { className: "max-h-64", children: options.map((time) => /* @__PURE__ */ jsx(SelectItem, { value: time, children: time }, time)) })
119
125
  ] });
@@ -123,7 +129,8 @@ function PersonChip({
123
129
  badge,
124
130
  compact,
125
131
  onRemove,
126
- removeLabel
132
+ removeLabel,
133
+ disabled
127
134
  }) {
128
135
  return /* @__PURE__ */ jsxs(
129
136
  "span",
@@ -146,6 +153,7 @@ function PersonChip({
146
153
  onRemove();
147
154
  },
148
155
  "aria-label": removeLabel,
156
+ disabled,
149
157
  className: "size-5 shrink-0",
150
158
  children: /* @__PURE__ */ jsx(Plus, { "aria-hidden": true, className: "size-3.5 rotate-45 opacity-50" })
151
159
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../../src/modules/customers/components/calendar/editor/inputs.tsx"],
4
- "sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport { Plus } from 'lucide-react'\nimport { cn } from '@open-mercato/shared/lib/utils'\nimport { Avatar } from '@open-mercato/ui/primitives/avatar'\nimport { DatePicker } from '@open-mercato/ui/primitives/date-picker'\nimport { IconButton } from '@open-mercato/ui/primitives/icon-button'\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@open-mercato/ui/primitives/select'\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\n/**\n * Closes an editor dropdown on pointer-down outside the component or Escape.\n * Blur alone is unreliable inside the Radix dialog focus trap (#3552 feedback:\n * the Resources list stayed open), so dismissal listens on the document while\n * the dropdown is open. Returns the ref to attach to the component root.\n */\nexport function useDropdownDismiss(open: boolean, onClose: () => void): React.RefObject<HTMLDivElement | null> {\n const rootRef = React.useRef<HTMLDivElement | null>(null)\n React.useEffect(() => {\n if (!open) return\n const handlePointerDown = (event: PointerEvent) => {\n if (rootRef.current && event.target instanceof Node && !rootRef.current.contains(event.target)) onClose()\n }\n const handleKeyDown = (event: KeyboardEvent) => {\n if (event.key === 'Escape') {\n // Swallow Escape so the dialog itself stays open.\n event.stopPropagation()\n onClose()\n }\n }\n document.addEventListener('pointerdown', handlePointerDown, true)\n document.addEventListener('keydown', handleKeyDown, true)\n return () => {\n document.removeEventListener('pointerdown', handlePointerDown, true)\n document.removeEventListener('keydown', handleKeyDown, true)\n }\n }, [open, onClose])\n return rootRef\n}\n\nexport function Field({ label, children, error, className }: { label: string; children: React.ReactNode; error?: string | null; className?: string }) {\n return (\n <div className={cn('flex w-full flex-col gap-1.5', className)}>\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\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 parseDateValue(value: string): Date | null {\n if (!value) return null\n const parsed = new Date(`${value}T00:00:00`)\n return Number.isNaN(parsed.getTime()) ? null : parsed\n}\n\nfunction formatDateValue(date: Date): string {\n return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}-${String(date.getDate()).padStart(2, '0')}`\n}\n\n// Close the field's popover when the surrounding editor dialog scrolls, so a\n// portalled DS popover (DatePicker/Select) doesn't float over the form or drift\n// from its field (#3747 feedback). Radix ignores synthetic dismiss events, so\n// this drives the popover's controlled `open` state instead. The editor\n// dispatches `EDITOR_SCROLL_EVENT` on scroll.\nexport const EDITOR_SCROLL_EVENT = 'om-calendar-editor-scroll'\nfunction useCloseOnEditorScroll(setOpen: (open: boolean) => void) {\n React.useEffect(() => {\n const handler = () => setOpen(false)\n document.addEventListener(EDITOR_SCROLL_EVENT, handler)\n return () => document.removeEventListener(EDITOR_SCROLL_EVENT, handler)\n }, [setOpen])\n}\n\n// DS DatePicker (calendar popover) + DS Select (scrolling 30-min list) replace\n// the native `<input type=date|time>` overlays, which only opened via the\n// browser chevron and did not match the design system (#3747 feedback).\nexport function DateControl({\n value,\n onChange,\n ariaLabel,\n className,\n}: {\n value: string\n onChange(next: string): void\n ariaLabel: string\n className?: string\n}) {\n const [open, setOpen] = React.useState(false)\n useCloseOnEditorScroll(setOpen)\n return (\n <DatePicker\n value={parseDateValue(value)}\n onChange={(date) => { if (date) onChange(formatDateValue(date)) }}\n footer=\"none\"\n open={open}\n onOpenChange={setOpen}\n aria-label={ariaLabel}\n className={cn('w-full', className)}\n />\n )\n}\n\n// 24h times at 30-minute steps.\nconst TIME_OPTIONS: string[] = Array.from({ length: 48 }, (_, index) => {\n const hour = Math.floor(index / 2)\n const minute = index % 2 === 0 ? '00' : '30'\n return `${String(hour).padStart(2, '0')}:${minute}`\n})\n\nexport function TimeControl({ value, onChange, ariaLabel }: { value: string; onChange(next: string): void; ariaLabel: string }) {\n const [open, setOpen] = React.useState(false)\n useCloseOnEditorScroll(setOpen)\n // Keep an off-grid value (e.g. an imported 22:15) selectable.\n const options = value && !TIME_OPTIONS.includes(value) ? [value, ...TIME_OPTIONS] : TIME_OPTIONS\n return (\n <Select value={value} onValueChange={onChange} open={open} onOpenChange={setOpen}>\n <SelectTrigger aria-label={ariaLabel} className=\"h-9 w-32 shrink-0\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent className=\"max-h-64\">\n {options.map((time) => (\n <SelectItem key={time} value={time}>{time}</SelectItem>\n ))}\n </SelectContent>\n </Select>\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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",
4
+ "sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport { Plus } from 'lucide-react'\nimport { cn } from '@open-mercato/shared/lib/utils'\nimport { Avatar } from '@open-mercato/ui/primitives/avatar'\nimport { DatePicker } from '@open-mercato/ui/primitives/date-picker'\nimport { IconButton } from '@open-mercato/ui/primitives/icon-button'\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@open-mercato/ui/primitives/select'\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\n/**\n * Closes an editor dropdown on pointer-down outside the component or Escape.\n * Blur alone is unreliable inside the Radix dialog focus trap (#3552 feedback:\n * the Resources list stayed open), so dismissal listens on the document while\n * the dropdown is open. Returns the ref to attach to the component root.\n */\nexport function useDropdownDismiss(open: boolean, onClose: () => void): React.RefObject<HTMLDivElement | null> {\n const rootRef = React.useRef<HTMLDivElement | null>(null)\n React.useEffect(() => {\n if (!open) return\n const handlePointerDown = (event: PointerEvent) => {\n if (rootRef.current && event.target instanceof Node && !rootRef.current.contains(event.target)) onClose()\n }\n const handleKeyDown = (event: KeyboardEvent) => {\n if (event.key === 'Escape') {\n // Swallow Escape so the dialog itself stays open.\n event.stopPropagation()\n onClose()\n }\n }\n document.addEventListener('pointerdown', handlePointerDown, true)\n document.addEventListener('keydown', handleKeyDown, true)\n return () => {\n document.removeEventListener('pointerdown', handlePointerDown, true)\n document.removeEventListener('keydown', handleKeyDown, true)\n }\n }, [open, onClose])\n return rootRef\n}\n\nexport function Field({ label, children, error, className }: { label: string; children: React.ReactNode; error?: string | null; className?: string }) {\n return (\n <div className={cn('flex w-full flex-col gap-1.5', className)}>\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\nexport function AllDayToggle({ checked, onCheckedChange, label, disabled }: { checked: boolean; onCheckedChange(next: boolean): void; label: string; disabled?: boolean }) {\n return (\n <Switch\n checked={checked}\n aria-label={label}\n onCheckedChange={onCheckedChange}\n disabled={disabled}\n className=\"h-6 w-10\"\n />\n )\n}\n\nfunction parseDateValue(value: string): Date | null {\n if (!value) return null\n const parsed = new Date(`${value}T00:00:00`)\n return Number.isNaN(parsed.getTime()) ? null : parsed\n}\n\nfunction formatDateValue(date: Date): string {\n return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}-${String(date.getDate()).padStart(2, '0')}`\n}\n\n// Close the field's popover when the surrounding editor dialog scrolls, so a\n// portalled DS popover (DatePicker/Select) doesn't float over the form or drift\n// from its field (#3747 feedback). Radix ignores synthetic dismiss events, so\n// this drives the popover's controlled `open` state instead. The editor\n// dispatches `EDITOR_SCROLL_EVENT` on scroll.\nexport const EDITOR_SCROLL_EVENT = 'om-calendar-editor-scroll'\nfunction useCloseOnEditorScroll(setOpen: (open: boolean) => void) {\n React.useEffect(() => {\n const handler = () => setOpen(false)\n document.addEventListener(EDITOR_SCROLL_EVENT, handler)\n return () => document.removeEventListener(EDITOR_SCROLL_EVENT, handler)\n }, [setOpen])\n}\n\n// DS DatePicker (calendar popover) + DS Select (scrolling 30-min list) replace\n// the native `<input type=date|time>` overlays, which only opened via the\n// browser chevron and did not match the design system (#3747 feedback).\nexport function DateControl({\n value,\n onChange,\n ariaLabel,\n className,\n disabled,\n}: {\n value: string\n onChange(next: string): void\n ariaLabel: string\n className?: string\n disabled?: boolean\n}) {\n const [open, setOpen] = React.useState(false)\n useCloseOnEditorScroll(setOpen)\n return (\n <DatePicker\n value={parseDateValue(value)}\n onChange={(date) => { if (date) onChange(formatDateValue(date)) }}\n footer=\"none\"\n open={open}\n onOpenChange={setOpen}\n aria-label={ariaLabel}\n disabled={disabled}\n className={cn('w-full', className)}\n />\n )\n}\n\n// 24h times at 30-minute steps.\nconst TIME_OPTIONS: string[] = Array.from({ length: 48 }, (_, index) => {\n const hour = Math.floor(index / 2)\n const minute = index % 2 === 0 ? '00' : '30'\n return `${String(hour).padStart(2, '0')}:${minute}`\n})\n\nexport function TimeControl({ value, onChange, ariaLabel, disabled }: { value: string; onChange(next: string): void; ariaLabel: string; disabled?: boolean }) {\n const [open, setOpen] = React.useState(false)\n useCloseOnEditorScroll(setOpen)\n // Radix renders every item even while the list is closed, so a closed picker\n // mounts only the selected time and the full grid is built on open. An\n // off-grid value (e.g. an imported 22:15) stays selectable.\n const options = React.useMemo(() => {\n if (!open) return value ? [value] : []\n return value && !TIME_OPTIONS.includes(value) ? [value, ...TIME_OPTIONS] : TIME_OPTIONS\n }, [open, value])\n return (\n <Select value={value} onValueChange={onChange} open={open} onOpenChange={setOpen} disabled={disabled}>\n <SelectTrigger aria-label={ariaLabel} className=\"h-9 w-32 shrink-0\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent className=\"max-h-64\">\n {options.map((time) => (\n <SelectItem key={time} value={time}>{time}</SelectItem>\n ))}\n </SelectContent>\n </Select>\n )\n}\n\nexport function PersonChip({\n name,\n badge,\n compact,\n onRemove,\n removeLabel,\n disabled,\n}: {\n name: string\n badge?: React.ReactNode\n compact?: boolean\n onRemove?: () => void\n removeLabel?: string\n disabled?: boolean\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 disabled={disabled}\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
6
  "names": []
7
7
  }
@@ -0,0 +1,54 @@
1
+ "use client";
2
+ import * as React from "react";
3
+ import { buildFormFieldsFromCustomFields, fetchCustomFieldFormStructure } from "@open-mercato/ui/backend/utils/customFieldForms";
4
+ import { filterCustomFieldDefs } from "@open-mercato/ui/backend/utils/customFieldDefs";
5
+ import { validateValuesAgainstDefs } from "@open-mercato/shared/modules/entities/validation";
6
+ function selectCalendarCustomFields(definitions, fieldsetIds) {
7
+ if (!fieldsetIds.length) return filterCustomFieldDefs(definitions, "form");
8
+ const allowed = new Set(fieldsetIds);
9
+ return filterCustomFieldDefs(definitions, "form").filter((definition) => {
10
+ const fieldsets = definition.fieldsets?.length ? definition.fieldsets : definition.fieldset ? [definition.fieldset] : [];
11
+ return fieldsets.length ? fieldsets.some((fieldset) => allowed.has(fieldset)) : allowed.has("__general__");
12
+ });
13
+ }
14
+ function projectCalendarCustomValues(values, definitions) {
15
+ const activeIds = new Set(definitions.map((definition) => `cf_${definition.key}`));
16
+ return Object.fromEntries(Object.entries(values).filter(([key]) => !key.startsWith("cf_") || activeIds.has(key)));
17
+ }
18
+ function validateCalendarCustomValues(values, definitions) {
19
+ const customValues = Object.fromEntries(definitions.map((definition) => [definition.key, values[`cf_${definition.key}`]]));
20
+ return validateValuesAgainstDefs(customValues, definitions.map((definition) => ({
21
+ key: definition.key,
22
+ kind: definition.kind,
23
+ configJson: { validation: definition.validation ?? [] }
24
+ })));
25
+ }
26
+ function useCalendarCustomFields(open, entityId, fieldsetIds) {
27
+ const [state, setState] = React.useState({
28
+ definitions: [],
29
+ status: "loading"
30
+ });
31
+ React.useEffect(() => {
32
+ if (!open) return;
33
+ let active = true;
34
+ setState({ definitions: [], status: "loading" });
35
+ void fetchCustomFieldFormStructure([entityId]).then(({ definitions: definitions2 }) => {
36
+ if (active) setState({ definitions: definitions2, status: "ready" });
37
+ }).catch(() => {
38
+ if (active) setState({ definitions: [], status: "error" });
39
+ });
40
+ return () => {
41
+ active = false;
42
+ };
43
+ }, [open, entityId]);
44
+ const definitions = React.useMemo(() => selectCalendarCustomFields(state.definitions, fieldsetIds), [state.definitions, fieldsetIds]);
45
+ const fields = React.useMemo(() => buildFormFieldsFromCustomFields(definitions), [definitions]);
46
+ return { definitions, allDefinitions: state.definitions, fields, status: state.status };
47
+ }
48
+ export {
49
+ projectCalendarCustomValues,
50
+ selectCalendarCustomFields,
51
+ useCalendarCustomFields,
52
+ validateCalendarCustomValues
53
+ };
54
+ //# sourceMappingURL=useCalendarCustomFields.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../../src/modules/customers/components/calendar/editor/useCalendarCustomFields.ts"],
4
+ "sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport { buildFormFieldsFromCustomFields, fetchCustomFieldFormStructure } from '@open-mercato/ui/backend/utils/customFieldForms'\nimport { filterCustomFieldDefs, type CustomFieldDefDto } from '@open-mercato/ui/backend/utils/customFieldDefs'\nimport { validateValuesAgainstDefs } from '@open-mercato/shared/modules/entities/validation'\n\nexport function selectCalendarCustomFields(definitions: CustomFieldDefDto[], fieldsetIds: readonly string[]) {\n if (!fieldsetIds.length) return filterCustomFieldDefs(definitions, 'form')\n const allowed = new Set(fieldsetIds)\n return filterCustomFieldDefs(definitions, 'form').filter((definition) => {\n const fieldsets = definition.fieldsets?.length ? definition.fieldsets : definition.fieldset ? [definition.fieldset] : []\n return fieldsets.length ? fieldsets.some((fieldset) => allowed.has(fieldset)) : allowed.has('__general__')\n })\n}\n\nexport function projectCalendarCustomValues(values: Record<string, unknown>, definitions: CustomFieldDefDto[]) {\n const activeIds = new Set(definitions.map((definition) => `cf_${definition.key}`))\n return Object.fromEntries(Object.entries(values).filter(([key]) => !key.startsWith('cf_') || activeIds.has(key)))\n}\n\nexport function validateCalendarCustomValues(values: Record<string, unknown>, definitions: CustomFieldDefDto[]) {\n const customValues = Object.fromEntries(definitions.map((definition) => [definition.key, values[`cf_${definition.key}`]]))\n return validateValuesAgainstDefs(customValues, definitions.map((definition) => ({\n key: definition.key,\n kind: definition.kind,\n configJson: { validation: definition.validation ?? [] },\n })))\n}\n\nexport function useCalendarCustomFields(open: boolean, entityId: string, fieldsetIds: readonly string[]) {\n const [state, setState] = React.useState<{ definitions: CustomFieldDefDto[]; status: 'loading' | 'ready' | 'error' }>({\n definitions: [], status: 'loading',\n })\n React.useEffect(() => {\n if (!open) return\n let active = true\n setState({ definitions: [], status: 'loading' })\n void fetchCustomFieldFormStructure([entityId]).then(({ definitions }) => {\n if (active) setState({ definitions, status: 'ready' })\n }).catch(() => {\n if (active) setState({ definitions: [], status: 'error' })\n })\n return () => { active = false }\n }, [open, entityId])\n const definitions = React.useMemo(() => selectCalendarCustomFields(state.definitions, fieldsetIds), [state.definitions, fieldsetIds])\n const fields = React.useMemo(() => buildFormFieldsFromCustomFields(definitions), [definitions])\n return { definitions, allDefinitions: state.definitions, fields, status: state.status }\n}\n"],
5
+ "mappings": ";AAEA,YAAY,WAAW;AACvB,SAAS,iCAAiC,qCAAqC;AAC/E,SAAS,6BAAqD;AAC9D,SAAS,iCAAiC;AAEnC,SAAS,2BAA2B,aAAkC,aAAgC;AAC3G,MAAI,CAAC,YAAY,OAAQ,QAAO,sBAAsB,aAAa,MAAM;AACzE,QAAM,UAAU,IAAI,IAAI,WAAW;AACnC,SAAO,sBAAsB,aAAa,MAAM,EAAE,OAAO,CAAC,eAAe;AACvE,UAAM,YAAY,WAAW,WAAW,SAAS,WAAW,YAAY,WAAW,WAAW,CAAC,WAAW,QAAQ,IAAI,CAAC;AACvH,WAAO,UAAU,SAAS,UAAU,KAAK,CAAC,aAAa,QAAQ,IAAI,QAAQ,CAAC,IAAI,QAAQ,IAAI,aAAa;AAAA,EAC3G,CAAC;AACH;AAEO,SAAS,4BAA4B,QAAiC,aAAkC;AAC7G,QAAM,YAAY,IAAI,IAAI,YAAY,IAAI,CAAC,eAAe,MAAM,WAAW,GAAG,EAAE,CAAC;AACjF,SAAO,OAAO,YAAY,OAAO,QAAQ,MAAM,EAAE,OAAO,CAAC,CAAC,GAAG,MAAM,CAAC,IAAI,WAAW,KAAK,KAAK,UAAU,IAAI,GAAG,CAAC,CAAC;AAClH;AAEO,SAAS,6BAA6B,QAAiC,aAAkC;AAC9G,QAAM,eAAe,OAAO,YAAY,YAAY,IAAI,CAAC,eAAe,CAAC,WAAW,KAAK,OAAO,MAAM,WAAW,GAAG,EAAE,CAAC,CAAC,CAAC;AACzH,SAAO,0BAA0B,cAAc,YAAY,IAAI,CAAC,gBAAgB;AAAA,IAC9E,KAAK,WAAW;AAAA,IAChB,MAAM,WAAW;AAAA,IACjB,YAAY,EAAE,YAAY,WAAW,cAAc,CAAC,EAAE;AAAA,EACxD,EAAE,CAAC;AACL;AAEO,SAAS,wBAAwB,MAAe,UAAkB,aAAgC;AACvG,QAAM,CAAC,OAAO,QAAQ,IAAI,MAAM,SAAsF;AAAA,IACpH,aAAa,CAAC;AAAA,IAAG,QAAQ;AAAA,EAC3B,CAAC;AACD,QAAM,UAAU,MAAM;AACpB,QAAI,CAAC,KAAM;AACX,QAAI,SAAS;AACb,aAAS,EAAE,aAAa,CAAC,GAAG,QAAQ,UAAU,CAAC;AAC/C,SAAK,8BAA8B,CAAC,QAAQ,CAAC,EAAE,KAAK,CAAC,EAAE,aAAAA,aAAY,MAAM;AACvE,UAAI,OAAQ,UAAS,EAAE,aAAAA,cAAa,QAAQ,QAAQ,CAAC;AAAA,IACvD,CAAC,EAAE,MAAM,MAAM;AACb,UAAI,OAAQ,UAAS,EAAE,aAAa,CAAC,GAAG,QAAQ,QAAQ,CAAC;AAAA,IAC3D,CAAC;AACD,WAAO,MAAM;AAAE,eAAS;AAAA,IAAM;AAAA,EAChC,GAAG,CAAC,MAAM,QAAQ,CAAC;AACnB,QAAM,cAAc,MAAM,QAAQ,MAAM,2BAA2B,MAAM,aAAa,WAAW,GAAG,CAAC,MAAM,aAAa,WAAW,CAAC;AACpI,QAAM,SAAS,MAAM,QAAQ,MAAM,gCAAgC,WAAW,GAAG,CAAC,WAAW,CAAC;AAC9F,SAAO,EAAE,aAAa,gBAAgB,MAAM,aAAa,QAAQ,QAAQ,MAAM,OAAO;AACxF;",
6
+ "names": ["definitions"]
7
+ }
@@ -0,0 +1,82 @@
1
+ "use client";
2
+ import * as React from "react";
3
+ import { getTelemetryRuntime } from "@open-mercato/shared/lib/telemetry/runtime";
4
+ import { readApiResultOrThrow } from "@open-mercato/ui/backend/utils/apiCall";
5
+ import { calendarEventTypes } from "../../../calendar-event-types.js";
6
+ import { KIND_CONFIG } from "../../../lib/calendar/editorPayload.js";
7
+ function useEventTypeCatalog(open) {
8
+ const [state, setState] = React.useState({ status: "loading", items: [] });
9
+ const [attempt, setAttempt] = React.useState(0);
10
+ React.useEffect(() => {
11
+ if (!open) {
12
+ setState({ status: "loading", items: [] });
13
+ return;
14
+ }
15
+ let active = true;
16
+ setState({ status: "loading", items: [] });
17
+ void readApiResultOrThrow("/api/customers/activity-types").then((catalog) => {
18
+ if (!Array.isArray(catalog.items)) throw new Error("[internal] Invalid activity type catalog");
19
+ if (active) setState({ status: "ready", items: catalog.items });
20
+ }).catch((error) => {
21
+ if (!active) return;
22
+ getTelemetryRuntime()?.reportError(error, {
23
+ module: "customers",
24
+ code: "customers.activity_type_catalog_load_failed"
25
+ });
26
+ setState({ status: "error", items: [] });
27
+ });
28
+ return () => {
29
+ active = false;
30
+ };
31
+ }, [open, attempt]);
32
+ const retry = React.useCallback(() => setAttempt((value) => value + 1), []);
33
+ return { ...state, retry };
34
+ }
35
+ function selectedEventType(items, key) {
36
+ const normalizedKey = key.trim().toLowerCase();
37
+ const selected = items.find((item) => item.key === normalizedKey);
38
+ if (selected) return selected;
39
+ const baseline = calendarEventTypes.find((item) => item.key === normalizedKey) ?? calendarEventTypes[0];
40
+ return {
41
+ ...baseline,
42
+ key,
43
+ label: key,
44
+ provenance: {},
45
+ historical: true,
46
+ fallbackReason: "unknown"
47
+ };
48
+ }
49
+ function isSelectableEventType(items, key) {
50
+ const normalizedKey = key.trim().toLowerCase();
51
+ return items.some((item) => item.key === normalizedKey && item.selectable && !item.historical);
52
+ }
53
+ function eventTypeOptions(items, selectedKey, translate) {
54
+ const displayLabel = (item) => item.labelKey ? translate(item.labelKey, item.label) : item.label;
55
+ const normalizedSelectedKey = selectedKey.trim().toLowerCase();
56
+ const options = items.filter((item) => item.selectable && !item.historical).sort((left, right) => left.behavior.order - right.behavior.order).map((item) => ({ value: item.key === normalizedSelectedKey ? selectedKey : item.key, label: displayLabel(item), icon: item.icon ?? null }));
57
+ if (!options.some((option) => option.value === selectedKey)) {
58
+ const current = items.find((item) => item.key === normalizedSelectedKey);
59
+ options.unshift({ value: selectedKey, label: current ? displayLabel(current) : selectedKey, icon: current?.icon ?? null });
60
+ }
61
+ return options;
62
+ }
63
+ function eventTypeConfig(definition) {
64
+ const { baseKind, fields } = definition.behavior;
65
+ return {
66
+ dateLabel: KIND_CONFIG[baseKind].dateLabel,
67
+ hasEnd: fields.endTime,
68
+ hasAllDay: fields.allDay,
69
+ hasRepeat: fields.recurrence,
70
+ location: fields.location === "none" ? null : fields.location,
71
+ people: fields.people === "none" ? null : fields.people === "recipients" ? "to" : fields.people,
72
+ hasPriority: fields.priority
73
+ };
74
+ }
75
+ export {
76
+ eventTypeConfig,
77
+ eventTypeOptions,
78
+ isSelectableEventType,
79
+ selectedEventType,
80
+ useEventTypeCatalog
81
+ };
82
+ //# sourceMappingURL=useEventTypeCatalog.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../../src/modules/customers/components/calendar/editor/useEventTypeCatalog.ts"],
4
+ "sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport { getTelemetryRuntime } from '@open-mercato/shared/lib/telemetry/runtime'\nimport { readApiResultOrThrow } from '@open-mercato/ui/backend/utils/apiCall'\nimport { calendarEventTypes, type EffectiveCalendarEventType } from '../../../calendar-event-types'\nimport type { CalendarEventTypeCatalog, ScopedCalendarEventType } from '../../../lib/calendar/eventTypeResolver'\nimport { KIND_CONFIG, type EditorKindConfig, type EditorTypeOption } from '../../../lib/calendar/editorPayload'\n\ntype CatalogState =\n | { status: 'loading' | 'error'; items: readonly ScopedCalendarEventType[] }\n | { status: 'ready'; items: readonly ScopedCalendarEventType[] }\n\nexport function useEventTypeCatalog(open: boolean) {\n const [state, setState] = React.useState<CatalogState>({ status: 'loading', items: [] })\n const [attempt, setAttempt] = React.useState(0)\n\n React.useEffect(() => {\n if (!open) {\n setState({ status: 'loading', items: [] })\n return\n }\n let active = true\n setState({ status: 'loading', items: [] })\n void readApiResultOrThrow<CalendarEventTypeCatalog>('/api/customers/activity-types')\n .then((catalog) => {\n if (!Array.isArray(catalog.items)) throw new Error('[internal] Invalid activity type catalog')\n if (active) setState({ status: 'ready', items: catalog.items })\n })\n .catch((error) => {\n if (!active) return\n getTelemetryRuntime()?.reportError(error, {\n module: 'customers',\n code: 'customers.activity_type_catalog_load_failed',\n })\n setState({ status: 'error', items: [] })\n })\n return () => { active = false }\n }, [open, attempt])\n\n const retry = React.useCallback(() => setAttempt((value) => value + 1), [])\n\n return { ...state, retry }\n}\n\nexport function selectedEventType(\n items: readonly ScopedCalendarEventType[],\n key: string,\n): EffectiveCalendarEventType {\n const normalizedKey = key.trim().toLowerCase()\n const selected = items.find((item) => item.key === normalizedKey)\n if (selected) return selected\n const baseline = calendarEventTypes.find((item) => item.key === normalizedKey) ?? calendarEventTypes[0]!\n return {\n ...baseline,\n key,\n label: key,\n provenance: {},\n historical: true,\n fallbackReason: 'unknown',\n }\n}\n\nexport function isSelectableEventType(items: readonly ScopedCalendarEventType[], key: string): boolean {\n const normalizedKey = key.trim().toLowerCase()\n return items.some((item) => item.key === normalizedKey && item.selectable && !item.historical)\n}\n\nexport function eventTypeOptions(\n items: readonly ScopedCalendarEventType[],\n selectedKey: string,\n translate: (key: string, fallback: string) => string,\n): EditorTypeOption[] {\n const displayLabel = (item: ScopedCalendarEventType) => item.labelKey\n ? translate(item.labelKey, item.label)\n : item.label\n const normalizedSelectedKey = selectedKey.trim().toLowerCase()\n const options = items\n .filter((item) => item.selectable && !item.historical)\n .sort((left, right) => left.behavior.order - right.behavior.order)\n .map((item) => ({ value: item.key === normalizedSelectedKey ? selectedKey : item.key, label: displayLabel(item), icon: item.icon ?? null }))\n if (!options.some((option) => option.value === selectedKey)) {\n const current = items.find((item) => item.key === normalizedSelectedKey)\n options.unshift({ value: selectedKey, label: current ? displayLabel(current) : selectedKey, icon: current?.icon ?? null })\n }\n return options\n}\n\nexport function eventTypeConfig(definition: EffectiveCalendarEventType): EditorKindConfig {\n const { baseKind, fields } = definition.behavior\n return {\n dateLabel: KIND_CONFIG[baseKind].dateLabel,\n hasEnd: fields.endTime,\n hasAllDay: fields.allDay,\n hasRepeat: fields.recurrence,\n location: fields.location === 'none' ? null : fields.location,\n people: fields.people === 'none' ? null : fields.people === 'recipients' ? 'to' : fields.people,\n hasPriority: fields.priority,\n }\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -12,6 +12,7 @@ const calendarInteractionPayloadSchema = z.object({
12
12
  scheduledAt: z.string().nullable().optional(),
13
13
  occurredAt: z.string().nullable().optional(),
14
14
  durationMinutes: z.number().nullable().optional(),
15
+ timezone: z.string().nullable().optional(),
15
16
  allDay: z.boolean().nullable().optional(),
16
17
  location: z.string().nullable().optional(),
17
18
  participants: z.array(calendarParticipantSchema).nullable().optional(),
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
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().optional(),\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; status?: 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 canManage?: 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,EAAE,SAAS;AAAA,EAC5B,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;",
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().optional(),\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 timezone: z.string().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; status?: 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 canManage?: 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,EAAE,SAAS;AAAA,EAC5B,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,UAAU,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS;AAAA,EACzC,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
6
  "names": []
7
7
  }