@open-mercato/core 0.6.5-develop.5382.1.f542de69af → 0.6.5

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 (237) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/dist/bootstrap.js +46 -6
  3. package/dist/bootstrap.js.map +2 -2
  4. package/dist/generated/entities/organization/index.js +2 -0
  5. package/dist/generated/entities/organization/index.js.map +2 -2
  6. package/dist/generated/entity-fields-registry.js +1 -0
  7. package/dist/generated/entity-fields-registry.js.map +2 -2
  8. package/dist/helpers/integration/crmFixtures.js +4 -0
  9. package/dist/helpers/integration/crmFixtures.js.map +2 -2
  10. package/dist/modules/attachments/api/route.js +2 -0
  11. package/dist/modules/attachments/api/route.js.map +2 -2
  12. package/dist/modules/attachments/lib/access.js +18 -0
  13. package/dist/modules/attachments/lib/access.js.map +2 -2
  14. package/dist/modules/audit_logs/data/entities.js +2 -1
  15. package/dist/modules/audit_logs/data/entities.js.map +2 -2
  16. package/dist/modules/audit_logs/migrations/Migration20260611104500.js +13 -0
  17. package/dist/modules/audit_logs/migrations/Migration20260611104500.js.map +7 -0
  18. package/dist/modules/audit_logs/services/accessLogService.js +10 -0
  19. package/dist/modules/audit_logs/services/accessLogService.js.map +2 -2
  20. package/dist/modules/auth/api/admin/nav.js +9 -0
  21. package/dist/modules/auth/api/admin/nav.js.map +2 -2
  22. package/dist/modules/auth/api/login.js +4 -13
  23. package/dist/modules/auth/api/login.js.map +2 -2
  24. package/dist/modules/auth/data/entities.js +3 -1
  25. package/dist/modules/auth/data/entities.js.map +2 -2
  26. package/dist/modules/auth/lib/backendChrome.js +35 -2
  27. package/dist/modules/auth/lib/backendChrome.js.map +2 -2
  28. package/dist/modules/auth/lib/consentIntegrity.js +3 -3
  29. package/dist/modules/auth/lib/consentIntegrity.js.map +2 -2
  30. package/dist/modules/auth/migrations/Migration20260611103000.js +15 -0
  31. package/dist/modules/auth/migrations/Migration20260611103000.js.map +7 -0
  32. package/dist/modules/auth/services/authService.js +5 -3
  33. package/dist/modules/auth/services/authService.js.map +2 -2
  34. package/dist/modules/auth/services/rbacService.js +3 -2
  35. package/dist/modules/auth/services/rbacService.js.map +2 -2
  36. package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/components/Diagnostics.js +0 -3
  37. package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/components/Diagnostics.js.map +2 -2
  38. package/dist/modules/customers/api/deals/route.js +43 -2
  39. package/dist/modules/customers/api/deals/route.js.map +2 -2
  40. package/dist/modules/customers/api/deals/summary/route.js +402 -0
  41. package/dist/modules/customers/api/deals/summary/route.js.map +7 -0
  42. package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealActivities.js +16 -5
  43. package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealActivities.js.map +2 -2
  44. package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealData.js +22 -5
  45. package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealData.js.map +2 -2
  46. package/dist/modules/customers/backend/customers/deals/[id]/page.js +12 -2
  47. package/dist/modules/customers/backend/customers/deals/[id]/page.js.map +2 -2
  48. package/dist/modules/customers/backend/customers/deals/page.js +221 -56
  49. package/dist/modules/customers/backend/customers/deals/page.js.map +3 -3
  50. package/dist/modules/customers/backend/customers/deals/pipeline/page.js +1 -1
  51. package/dist/modules/customers/backend/customers/deals/pipeline/page.js.map +2 -2
  52. package/dist/modules/customers/backend/customers/people-v2/[id]/page.js +18 -0
  53. package/dist/modules/customers/backend/customers/people-v2/[id]/page.js.map +2 -2
  54. package/dist/modules/customers/cli.js +15 -9
  55. package/dist/modules/customers/cli.js.map +2 -2
  56. package/dist/modules/customers/components/DealsKpiStrip.js +282 -0
  57. package/dist/modules/customers/components/DealsKpiStrip.js.map +7 -0
  58. package/dist/modules/customers/components/detail/ConfirmDealLostDialog.js +0 -1
  59. package/dist/modules/customers/components/detail/ConfirmDealLostDialog.js.map +2 -2
  60. package/dist/modules/customers/components/detail/DealForm.js +100 -17
  61. package/dist/modules/customers/components/detail/DealForm.js.map +2 -2
  62. package/dist/modules/customers/components/detail/PersonDetailTabs.js +11 -3
  63. package/dist/modules/customers/components/detail/PersonDetailTabs.js.map +2 -2
  64. package/dist/modules/customers/components/detail/ScheduleActivityDialog.js +1 -2
  65. package/dist/modules/customers/components/detail/ScheduleActivityDialog.js.map +2 -2
  66. package/dist/modules/customers/components/kpi/PipelineStageBar.js +63 -0
  67. package/dist/modules/customers/components/kpi/PipelineStageBar.js.map +7 -0
  68. package/dist/modules/customers/lib/dealsMetrics.js +82 -0
  69. package/dist/modules/customers/lib/dealsMetrics.js.map +7 -0
  70. package/dist/modules/directory/api/organization-branding/route.js +214 -0
  71. package/dist/modules/directory/api/organization-branding/route.js.map +7 -0
  72. package/dist/modules/directory/api/organizations/route.js +7 -0
  73. package/dist/modules/directory/api/organizations/route.js.map +3 -3
  74. package/dist/modules/directory/backend/directory/branding/page.js +214 -0
  75. package/dist/modules/directory/backend/directory/branding/page.js.map +7 -0
  76. package/dist/modules/directory/backend/directory/branding/page.meta.js +26 -0
  77. package/dist/modules/directory/backend/directory/branding/page.meta.js.map +7 -0
  78. package/dist/modules/directory/commands/organizations.js +8 -1
  79. package/dist/modules/directory/commands/organizations.js.map +2 -2
  80. package/dist/modules/directory/data/entities.js +3 -0
  81. package/dist/modules/directory/data/entities.js.map +2 -2
  82. package/dist/modules/directory/data/validators.js +9 -0
  83. package/dist/modules/directory/data/validators.js.map +2 -2
  84. package/dist/modules/directory/migrations/Migration20260607222259_directory.js +13 -0
  85. package/dist/modules/directory/migrations/Migration20260607222259_directory.js.map +7 -0
  86. package/dist/modules/directory/subscribers/invalidateOrgScopeCache.js +2 -1
  87. package/dist/modules/directory/subscribers/invalidateOrgScopeCache.js.map +2 -2
  88. package/dist/modules/directory/utils/organizationScope.js +59 -27
  89. package/dist/modules/directory/utils/organizationScope.js.map +2 -2
  90. package/dist/modules/entities/api/definitions.batch.js +2 -1
  91. package/dist/modules/entities/api/definitions.batch.js.map +2 -2
  92. package/dist/modules/entities/api/entities.js +7 -0
  93. package/dist/modules/entities/api/entities.js.map +2 -2
  94. package/dist/modules/entities/api/records.js +26 -15
  95. package/dist/modules/entities/api/records.js.map +2 -2
  96. package/dist/modules/entities/backend/entities/user/[entityId]/records/[recordId]/page.js +14 -0
  97. package/dist/modules/entities/backend/entities/user/[entityId]/records/[recordId]/page.js.map +2 -2
  98. package/dist/modules/entities/backend/entities/user/[entityId]/records/create/page.js +14 -0
  99. package/dist/modules/entities/backend/entities/user/[entityId]/records/create/page.js.map +2 -2
  100. package/dist/modules/entities/backend/entities/user/[entityId]/records/page.js +12 -0
  101. package/dist/modules/entities/backend/entities/user/[entityId]/records/page.js.map +2 -2
  102. package/dist/modules/entities/components/useRecordsEntityGuard.js +30 -0
  103. package/dist/modules/entities/components/useRecordsEntityGuard.js.map +7 -0
  104. package/dist/modules/query_index/data/entities.js +2 -1
  105. package/dist/modules/query_index/data/entities.js.map +2 -2
  106. package/dist/modules/query_index/lib/engine.js +4 -2
  107. package/dist/modules/query_index/lib/engine.js.map +2 -2
  108. package/dist/modules/query_index/migrations/Migration20260611103000_query_index.js +16 -0
  109. package/dist/modules/query_index/migrations/Migration20260611103000_query_index.js.map +7 -0
  110. package/dist/modules/sales/commands/documents.js +7 -5
  111. package/dist/modules/sales/commands/documents.js.map +2 -2
  112. package/dist/modules/sales/components/documents/SalesDocumentsTable.js +2 -1
  113. package/dist/modules/sales/components/documents/SalesDocumentsTable.js.map +2 -2
  114. package/dist/modules/sales/components/documents/salesDocumentsColumns.js +10 -0
  115. package/dist/modules/sales/components/documents/salesDocumentsColumns.js.map +7 -0
  116. package/dist/modules/staff/api/team-members.js +9 -2
  117. package/dist/modules/staff/api/team-members.js.map +2 -2
  118. package/dist/modules/staff/api/timesheets/time-entries/[id]/timer-start/route.js +24 -1
  119. package/dist/modules/staff/api/timesheets/time-entries/[id]/timer-start/route.js.map +2 -2
  120. package/dist/modules/staff/backend/staff/team-members/[id]/page.js +11 -6
  121. package/dist/modules/staff/backend/staff/team-members/[id]/page.js.map +2 -2
  122. package/dist/modules/staff/commands/team-members.js +1 -1
  123. package/dist/modules/staff/commands/team-members.js.map +2 -2
  124. package/dist/modules/staff/components/TeamMemberForm.js +1 -1
  125. package/dist/modules/staff/components/TeamMemberForm.js.map +2 -2
  126. package/dist/modules/staff/lib/scheduleSwitch.js +23 -0
  127. package/dist/modules/staff/lib/scheduleSwitch.js.map +7 -0
  128. package/dist/modules/workflows/backend/definitions/create/page.js +1 -2
  129. package/dist/modules/workflows/backend/definitions/create/page.js.map +2 -2
  130. package/dist/modules/workflows/backend/definitions/visual-editor/page.js +1 -2
  131. package/dist/modules/workflows/backend/definitions/visual-editor/page.js.map +2 -2
  132. package/dist/modules/workflows/components/DefinitionTriggersEditor.js +1 -2
  133. package/dist/modules/workflows/components/DefinitionTriggersEditor.js.map +2 -2
  134. package/dist/modules/workflows/components/NodeEditDialog.js +4 -13
  135. package/dist/modules/workflows/components/NodeEditDialog.js.map +2 -2
  136. package/dist/modules/workflows/components/NodeEditDialogCrudForm.js +4 -13
  137. package/dist/modules/workflows/components/NodeEditDialogCrudForm.js.map +2 -2
  138. package/dist/modules/workflows/components/WorkflowGraphImpl.js +1 -4
  139. package/dist/modules/workflows/components/WorkflowGraphImpl.js.map +2 -2
  140. package/dist/modules/workflows/components/fields/FormFieldArrayEditor.js +2 -5
  141. package/dist/modules/workflows/components/fields/FormFieldArrayEditor.js.map +2 -2
  142. package/generated/entities/organization/index.ts +1 -0
  143. package/generated/entity-fields-registry.ts +1 -0
  144. package/package.json +11 -12
  145. package/src/bootstrap.ts +65 -7
  146. package/src/helpers/integration/crmFixtures.ts +21 -1
  147. package/src/modules/attachments/AGENTS.md +79 -0
  148. package/src/modules/attachments/api/route.ts +2 -0
  149. package/src/modules/attachments/lib/access.ts +36 -0
  150. package/src/modules/audit_logs/data/entities.ts +1 -0
  151. package/src/modules/audit_logs/migrations/.snapshot-open-mercato.json +10 -0
  152. package/src/modules/audit_logs/migrations/Migration20260611104500.ts +13 -0
  153. package/src/modules/audit_logs/services/accessLogService.ts +15 -0
  154. package/src/modules/auth/api/admin/nav.ts +9 -0
  155. package/src/modules/auth/api/login.ts +13 -13
  156. package/src/modules/auth/data/entities.ts +2 -0
  157. package/src/modules/auth/i18n/de.json +0 -1
  158. package/src/modules/auth/i18n/en.json +0 -1
  159. package/src/modules/auth/i18n/es.json +0 -1
  160. package/src/modules/auth/i18n/pl.json +0 -1
  161. package/src/modules/auth/lib/backendChrome.tsx +37 -1
  162. package/src/modules/auth/lib/consentIntegrity.ts +6 -3
  163. package/src/modules/auth/migrations/.snapshot-open-mercato.json +20 -0
  164. package/src/modules/auth/migrations/Migration20260611103000.ts +21 -0
  165. package/src/modules/auth/services/authService.ts +24 -4
  166. package/src/modules/auth/services/rbacService.ts +11 -2
  167. package/src/modules/customer_accounts/backend/customer_accounts/settings/domain/components/Diagnostics.tsx +0 -3
  168. package/src/modules/customers/api/deals/route.ts +51 -2
  169. package/src/modules/customers/api/deals/summary/route.ts +496 -0
  170. package/src/modules/customers/backend/customers/deals/[id]/hooks/useDealActivities.ts +28 -6
  171. package/src/modules/customers/backend/customers/deals/[id]/hooks/useDealData.ts +33 -6
  172. package/src/modules/customers/backend/customers/deals/[id]/page.tsx +17 -2
  173. package/src/modules/customers/backend/customers/deals/page.tsx +254 -66
  174. package/src/modules/customers/backend/customers/deals/pipeline/page.tsx +1 -2
  175. package/src/modules/customers/backend/customers/people-v2/[id]/page.tsx +18 -0
  176. package/src/modules/customers/cli.ts +15 -15
  177. package/src/modules/customers/components/DealsKpiStrip.tsx +389 -0
  178. package/src/modules/customers/components/detail/ConfirmDealLostDialog.tsx +0 -1
  179. package/src/modules/customers/components/detail/DealForm.tsx +121 -19
  180. package/src/modules/customers/components/detail/PersonDetailTabs.tsx +12 -2
  181. package/src/modules/customers/components/detail/ScheduleActivityDialog.tsx +1 -2
  182. package/src/modules/customers/components/kpi/PipelineStageBar.tsx +77 -0
  183. package/src/modules/customers/i18n/de.json +43 -0
  184. package/src/modules/customers/i18n/en.json +43 -0
  185. package/src/modules/customers/i18n/es.json +43 -0
  186. package/src/modules/customers/i18n/pl.json +43 -0
  187. package/src/modules/customers/lib/dealsMetrics.ts +159 -0
  188. package/src/modules/directory/api/organization-branding/route.ts +238 -0
  189. package/src/modules/directory/api/organizations/route.ts +7 -0
  190. package/src/modules/directory/backend/directory/branding/page.meta.ts +24 -0
  191. package/src/modules/directory/backend/directory/branding/page.tsx +248 -0
  192. package/src/modules/directory/commands/organizations.ts +9 -1
  193. package/src/modules/directory/data/entities.ts +3 -0
  194. package/src/modules/directory/data/validators.ts +12 -0
  195. package/src/modules/directory/i18n/de.json +21 -0
  196. package/src/modules/directory/i18n/en.json +21 -0
  197. package/src/modules/directory/i18n/es.json +21 -0
  198. package/src/modules/directory/i18n/pl.json +21 -0
  199. package/src/modules/directory/migrations/.snapshot-open-mercato.json +40 -0
  200. package/src/modules/directory/migrations/Migration20260607222259_directory.ts +13 -0
  201. package/src/modules/directory/subscribers/invalidateOrgScopeCache.ts +3 -1
  202. package/src/modules/directory/utils/organizationScope.ts +85 -30
  203. package/src/modules/entities/api/definitions.batch.ts +11 -7
  204. package/src/modules/entities/api/entities.ts +11 -0
  205. package/src/modules/entities/api/records.ts +46 -25
  206. package/src/modules/entities/backend/entities/user/[entityId]/records/[recordId]/page.tsx +15 -0
  207. package/src/modules/entities/backend/entities/user/[entityId]/records/create/page.tsx +15 -0
  208. package/src/modules/entities/backend/entities/user/[entityId]/records/page.tsx +23 -0
  209. package/src/modules/entities/components/useRecordsEntityGuard.ts +41 -0
  210. package/src/modules/entities/i18n/de.json +1 -0
  211. package/src/modules/entities/i18n/en.json +1 -0
  212. package/src/modules/entities/i18n/es.json +1 -0
  213. package/src/modules/entities/i18n/pl.json +1 -0
  214. package/src/modules/query_index/data/entities.ts +1 -0
  215. package/src/modules/query_index/lib/engine.ts +11 -5
  216. package/src/modules/query_index/migrations/.snapshot-open-mercato.json +11 -0
  217. package/src/modules/query_index/migrations/Migration20260611103000_query_index.ts +29 -0
  218. package/src/modules/sales/commands/documents.ts +7 -5
  219. package/src/modules/sales/components/documents/SalesDocumentsTable.tsx +2 -1
  220. package/src/modules/sales/components/documents/salesDocumentsColumns.ts +6 -0
  221. package/src/modules/staff/api/team-members.ts +9 -2
  222. package/src/modules/staff/api/timesheets/time-entries/[id]/timer-start/route.ts +31 -1
  223. package/src/modules/staff/backend/staff/team-members/[id]/page.tsx +18 -8
  224. package/src/modules/staff/commands/team-members.ts +5 -2
  225. package/src/modules/staff/components/TeamMemberForm.tsx +4 -1
  226. package/src/modules/staff/i18n/de.json +1 -0
  227. package/src/modules/staff/i18n/en.json +1 -0
  228. package/src/modules/staff/i18n/es.json +1 -0
  229. package/src/modules/staff/i18n/pl.json +1 -0
  230. package/src/modules/staff/lib/scheduleSwitch.ts +46 -0
  231. package/src/modules/workflows/backend/definitions/create/page.tsx +1 -2
  232. package/src/modules/workflows/backend/definitions/visual-editor/page.tsx +1 -2
  233. package/src/modules/workflows/components/DefinitionTriggersEditor.tsx +1 -2
  234. package/src/modules/workflows/components/NodeEditDialog.tsx +1 -4
  235. package/src/modules/workflows/components/NodeEditDialogCrudForm.tsx +4 -7
  236. package/src/modules/workflows/components/WorkflowGraphImpl.tsx +1 -2
  237. package/src/modules/workflows/components/fields/FormFieldArrayEditor.tsx +2 -3
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../../../src/modules/staff/backend/staff/team-members/%5Bid%5D/page.tsx"],
4
- "sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport Link from 'next/link'\nimport { useRouter, useSearchParams } from 'next/navigation'\nimport { Page, PageBody } from '@open-mercato/ui/backend/Page'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { readApiResultOrThrow, withScopedApiRequestHeaders } from '@open-mercato/ui/backend/utils/apiCall'\nimport { extractCustomFieldEntries } from '@open-mercato/shared/lib/crud/custom-fields-client'\nimport { updateCrud, deleteCrud } from '@open-mercato/ui/backend/utils/crud'\nimport { buildOptimisticLockHeader } from '@open-mercato/ui/backend/utils/optimisticLock'\nimport { flash } from '@open-mercato/ui/backend/FlashMessages'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { createTranslatorWithFallback } from '@open-mercato/shared/lib/i18n/translate'\nimport { AvailabilityRulesEditor } from '@open-mercato/core/modules/planner/components/AvailabilityRulesEditor'\nimport { buildMemberScheduleItems } from '@open-mercato/core/modules/staff/lib/memberSchedule'\nimport { TeamMemberForm, buildTeamMemberPayload, type TeamMemberFormValues } from '@open-mercato/core/modules/staff/components/TeamMemberForm'\nimport { NotesSection } from '@open-mercato/ui/backend/detail'\nimport { ActivitiesSection, type SectionAction } from '@open-mercato/ui/backend/detail'\nimport { AddressesSection as SharedAddressesSection } from '@open-mercato/ui/backend/detail'\nimport { ErrorMessage, RecordNotFoundState } from '@open-mercato/ui/backend/detail'\nimport { renderDictionaryColor, renderDictionaryIcon, ICON_SUGGESTIONS } from '@open-mercato/core/modules/dictionaries/components/dictionaryAppearance'\nimport { createStaffNotesAdapter } from '@open-mercato/core/modules/staff/components/detail/notesAdapter'\nimport { createStaffActivitiesAdapter } from '@open-mercato/core/modules/staff/components/detail/activitiesAdapter'\nimport { createStaffAddressAdapter, createStaffAddressTypesAdapter } from '@open-mercato/core/modules/staff/components/detail/addressesAdapter'\nimport { MarkdownContent } from '@open-mercato/ui/backend/markdown/MarkdownContent'\nimport {\n createStaffDictionaryEntry,\n loadStaffDictionary,\n type DictionaryEntryOption,\n} from '@open-mercato/core/modules/staff/components/detail/dictionaries'\nimport { JobHistorySection } from '@open-mercato/core/modules/staff/components/detail/JobHistorySection'\nimport type { DictionarySelectLabels } from '@open-mercato/core/modules/dictionaries/components/DictionaryEntrySelect'\nimport { Plus } from 'lucide-react'\nimport { TranslationDrawerAction } from '@open-mercato/core/modules/translations/components/TranslationDrawerAction'\nimport { SendObjectMessageDialog } from '@open-mercato/ui/backend/messages'\n\nconst MARKDOWN_CLASSNAME =\n 'text-sm text-muted-foreground break-words [&>*]:mb-2 [&>*:last-child]:mb-0 [&_ul]:ml-4 [&_ul]:list-disc [&_ol]:ml-4 [&_ol]:list-decimal [&_code]:rounded [&_code]:bg-muted [&_code]:px-1 [&_code]:py-0.5 [&_pre]:rounded-md [&_pre]:bg-muted [&_pre]:p-3 [&_pre]:text-xs'\n\ntype TeamMemberRecord = {\n id: string\n teamId?: string | null\n team_id?: string | null\n displayName: string\n display_name?: string\n description?: string | null\n userId?: string | null\n user_id?: string | null\n roleIds?: string[]\n role_ids?: string[]\n roleNames?: string[]\n tags?: string[]\n isActive?: boolean\n is_active?: boolean\n availabilityRuleSetId?: string | null\n availability_rule_set_id?: string | null\n updatedAt?: string | null\n updated_at?: string | null\n user?: { id?: string; email?: string | null } | null\n team?: { id?: string; name?: string | null } | null\n customFields?: Record<string, unknown> | null\n} & Record<string, unknown>\n\ntype TeamMemberResponse = {\n items?: TeamMemberRecord[]\n}\n\nexport default function StaffTeamMemberDetailPage({ params }: { params?: { id?: string } }) {\n const memberId = params?.id\n const t = useT()\n const detailTranslator = React.useMemo(() => createTranslatorWithFallback(t), [t])\n const router = useRouter()\n const searchParams = useSearchParams()\n const [initialValues, setInitialValues] = React.useState<TeamMemberFormValues | null>(null)\n const [memberRecord, setMemberRecord] = React.useState<TeamMemberRecord | null>(null)\n const [error, setError] = React.useState<string | null>(null)\n const [isNotFound, setIsNotFound] = React.useState(false)\n const [availabilityRuleSetId, setAvailabilityRuleSetId] = React.useState<string | null>(null)\n const [activePanel, setActivePanel] = React.useState<'details' | 'availability' | 'jobHistory'>('details')\n const [activeTab, setActiveTab] = React.useState<'notes' | 'activities' | 'addresses'>('notes')\n const [sectionAction, setSectionAction] = React.useState<SectionAction | null>(null)\n const [activityDictionaryId, setActivityDictionaryId] = React.useState<string | null>(null)\n const [activityTypeEntries, setActivityTypeEntries] = React.useState<DictionaryEntryOption[]>([])\n const flashShownRef = React.useRef(false)\n\n const notesAdapter = React.useMemo(() => createStaffNotesAdapter(detailTranslator), [detailTranslator])\n const activitiesAdapter = React.useMemo(() => createStaffActivitiesAdapter(detailTranslator), [detailTranslator])\n const addressesAdapter = React.useMemo(() => createStaffAddressAdapter(detailTranslator), [detailTranslator])\n const addressTypesAdapter = React.useMemo(() => createStaffAddressTypesAdapter(detailTranslator), [detailTranslator])\n\n const activityTypeLabels = React.useMemo<DictionarySelectLabels>(() => ({\n placeholder: t('staff.teamMembers.detail.activities.dictionary.placeholder', 'Select an activity type'),\n addLabel: t('staff.teamMembers.detail.activities.dictionary.add', 'Add type'),\n addPrompt: t('staff.teamMembers.detail.activities.dictionary.prompt', 'Name the type'),\n dialogTitle: t('staff.teamMembers.detail.activities.dictionary.dialogTitle', 'Add activity type'),\n valueLabel: t('staff.teamMembers.detail.activities.dictionary.valueLabel', 'Name'),\n valuePlaceholder: t('staff.teamMembers.detail.activities.dictionary.valuePlaceholder', 'Name'),\n labelLabel: t('staff.teamMembers.detail.activities.dictionary.labelLabel', 'Label'),\n labelPlaceholder: t('staff.teamMembers.detail.activities.dictionary.labelPlaceholder', 'Display name shown in UI'),\n emptyError: t('staff.teamMembers.detail.activities.dictionary.emptyError', 'Please enter a name'),\n cancelLabel: t('staff.teamMembers.detail.activities.dictionary.cancel', 'Cancel'),\n saveLabel: t('staff.teamMembers.detail.activities.dictionary.save', 'Save'),\n saveShortcutHint: t('staff.teamMembers.detail.activities.dictionary.saveShortcut', '\u2318/Ctrl + Enter'),\n errorLoad: t('staff.teamMembers.detail.activities.dictionary.errorLoad', 'Failed to load options'),\n errorSave: t('staff.teamMembers.detail.activities.dictionary.errorSave', 'Failed to save option'),\n loadingLabel: t('staff.teamMembers.detail.activities.dictionary.loading', 'Loading\u2026'),\n manageTitle: t('staff.teamMembers.detail.activities.dictionary.manage', 'Manage dictionary'),\n }), [t])\n\n const loadActivityOptions = React.useCallback(async () => {\n const { dictionary, entries } = await loadStaffDictionary('activityTypes')\n setActivityDictionaryId(dictionary?.id ?? null)\n setActivityTypeEntries(entries)\n return entries\n }, [])\n\n const createActivityOption = React.useCallback(\n async (input: { value: string; label?: string; color?: string | null; icon?: string | null }) => {\n const entry = await createStaffDictionaryEntry('activityTypes', input)\n if (!entry) {\n throw new Error(t('staff.teamMembers.detail.activities.dictionary.errorSave', 'Failed to save option'))\n }\n return entry\n },\n [t],\n )\n\n React.useEffect(() => {\n loadActivityOptions().catch(() => {})\n }, [loadActivityOptions])\n\n const activityTypeMap = React.useMemo(\n () => new Map(activityTypeEntries.map((entry) => [entry.value, entry])),\n [activityTypeEntries],\n )\n\n const resolveActivityPresentation = React.useCallback(\n (activity: { activityType: string; appearanceIcon?: string | null; appearanceColor?: string | null }) => {\n const entry = activityTypeMap.get(activity.activityType)\n return {\n label: entry?.label ?? activity.activityType,\n icon: entry?.icon ?? activity.appearanceIcon ?? null,\n color: entry?.color ?? activity.appearanceColor ?? null,\n }\n },\n [activityTypeMap],\n )\n\n const manageActivityHref = React.useMemo(() => {\n if (!activityDictionaryId) return '/backend/config/dictionaries'\n return `/backend/config/dictionaries?dictionaryId=${encodeURIComponent(activityDictionaryId)}`\n }, [activityDictionaryId])\n\n const appearanceLabels = React.useMemo(() => ({\n colorLabel: t('staff.teamMembers.detail.activities.appearance.colorLabel', 'Color'),\n colorHelp: t('staff.teamMembers.detail.activities.appearance.colorHelp', 'Pick a highlight color for this entry.'),\n colorClearLabel: t('staff.teamMembers.detail.activities.appearance.colorClear', 'Remove color'),\n iconLabel: t('staff.teamMembers.detail.activities.appearance.iconLabel', 'Icon or emoji'),\n iconPlaceholder: t('staff.teamMembers.detail.activities.appearance.iconPlaceholder', 'Type an emoji or pick one of the suggestions.'),\n iconPickerTriggerLabel: t('staff.teamMembers.detail.activities.appearance.iconBrowse', 'Browse icons and emojis'),\n iconSearchPlaceholder: t('staff.teamMembers.detail.activities.appearance.iconSearchPlaceholder', 'Search icons or emojis\u2026'),\n iconSearchEmptyLabel: t('staff.teamMembers.detail.activities.appearance.iconSearchEmpty', 'No icons match your search.'),\n iconSuggestionsLabel: t('staff.teamMembers.detail.activities.appearance.iconSuggestions', 'Suggestions'),\n iconClearLabel: t('staff.teamMembers.detail.activities.appearance.iconClear', 'Remove icon'),\n previewEmptyLabel: t('staff.teamMembers.detail.activities.appearance.previewEmpty', 'No appearance selected'),\n }), [t])\n\n const renderCustomFields = React.useCallback((activity: { id?: string; customFields?: Array<{ key: string; label?: string | null; value: unknown }> }) => {\n const entries = Array.isArray(activity.customFields) ? activity.customFields : []\n if (!entries.length) return null\n const emptyLabel = t('staff.teamMembers.detail.activities.customFields.empty', 'Not provided')\n return (\n <div className=\"grid gap-3 sm:grid-cols-2\">\n {entries.map((entry, index) => {\n const label = entry.label ?? entry.key\n const value = entry.value\n const hasValue = !(value == null || value === '' || (Array.isArray(value) && value.length === 0))\n const content = hasValue\n ? Array.isArray(value)\n ? value.map((item) => String(item)).join(', ')\n : String(value)\n : emptyLabel\n return (\n <div\n key={`activity-${activity.id ?? 'row'}-custom-${index}`}\n className=\"rounded-md border border-border/70 bg-muted/30 px-3 py-2\"\n >\n <div className=\"text-xs font-medium text-muted-foreground\">{label}</div>\n <div className=\"mt-1 text-sm text-foreground\">{content}</div>\n </div>\n )\n })}\n </div>\n )\n }, [t])\n\n React.useEffect(() => {\n if (!memberId) return\n const memberIdValue = memberId\n let cancelled = false\n async function loadMember() {\n if (!cancelled) {\n setError(null)\n setIsNotFound(false)\n }\n try {\n const params = new URLSearchParams({ page: '1', pageSize: '1', ids: memberIdValue })\n const payload = await readApiResultOrThrow<TeamMemberResponse>(\n `/api/staff/team-members?${params.toString()}`,\n undefined,\n { errorMessage: t('staff.teamMembers.form.errors.load', 'Failed to load team member.') },\n )\n const record = Array.isArray(payload.items) ? payload.items[0] : null\n if (!record) {\n if (!cancelled) setIsNotFound(true)\n return\n }\n const customFields = extractCustomFieldEntries(record)\n if (!cancelled) {\n const resolvedTeamId = record.teamId ?? record.team_id ?? null\n const normalizedRoleIds = normalizeStringList(resolvePreferredArray(record.roleIds, record.role_ids))\n setInitialValues({\n id: record.id,\n teamId: resolvedTeamId,\n userId: record.userId ?? record.user_id ?? null,\n displayName: record.displayName ?? record.display_name ?? '',\n description: record.description ?? '',\n roleIds: normalizedRoleIds,\n tags: normalizeStringList(record.tags),\n isActive: record.isActive ?? record.is_active ?? true,\n updatedAt: typeof record.updatedAt === 'string'\n ? record.updatedAt\n : typeof record.updated_at === 'string'\n ? record.updated_at\n : null,\n ...customFields,\n })\n setMemberRecord(record)\n setAvailabilityRuleSetId(\n typeof record.availabilityRuleSetId === 'string'\n ? record.availabilityRuleSetId\n : typeof record.availability_rule_set_id === 'string'\n ? record.availability_rule_set_id\n : null,\n )\n }\n } catch (err) {\n if (!cancelled) {\n if ((err as { status?: number }).status === 404) {\n setIsNotFound(true)\n } else {\n const message = err instanceof Error ? err.message : t('staff.teamMembers.form.errors.load', 'Failed to load team member.')\n setError(message)\n }\n }\n }\n }\n void loadMember()\n return () => { cancelled = true }\n }, [memberId, t])\n\n React.useEffect(() => {\n if (!searchParams) return\n const created = searchParams.get('created') === '1'\n if (created && !flashShownRef.current) {\n flashShownRef.current = true\n flash(t('staff.teamMembers.flash.createdAvailability', 'Saved. You can now set availability.'), 'success')\n const nextParams = new URLSearchParams(searchParams.toString())\n nextParams.delete('created')\n const nextQuery = nextParams.toString()\n const nextPath = memberId\n ? `/backend/staff/team-members/${encodeURIComponent(memberId)}${nextQuery ? `?${nextQuery}` : ''}`\n : `/backend/staff/team-members${nextQuery ? `?${nextQuery}` : ''}`\n router.replace(nextPath)\n }\n }, [memberId, router, searchParams, t])\n\n const handleSubmit = React.useCallback(async (values: TeamMemberFormValues) => {\n if (!memberId) return\n const payload = buildTeamMemberPayload(values, { id: memberId })\n await updateCrud('staff/team-members', payload, {\n errorMessage: t('staff.teamMembers.form.errors.update', 'Failed to update team member.'),\n })\n flash(t('staff.teamMembers.form.flash.updated', 'Team member updated.'), 'success')\n router.push('/backend/staff/team-members')\n }, [memberId, router, t])\n\n const handleDelete = React.useCallback(async () => {\n if (!memberId) return\n await deleteCrud('staff/team-members', memberId, {\n errorMessage: t('staff.teamMembers.form.errors.delete', 'Failed to delete team member.'),\n })\n flash(t('staff.teamMembers.form.flash.deleted', 'Team member deleted.'), 'success')\n router.push('/backend/staff/team-members')\n }, [memberId, router, t])\n\n const handleRulesetChange = React.useCallback(async (nextId: string | null) => {\n if (!memberId) return\n const headers = buildOptimisticLockHeader(initialValues?.updatedAt)\n await withScopedApiRequestHeaders(headers, () => (\n updateCrud('staff/team-members', { id: memberId, availabilityRuleSetId: nextId }, {\n errorMessage: t('staff.teamMembers.availability.ruleset.updateError', 'Failed to update schedule.'),\n })\n ))\n setAvailabilityRuleSetId(nextId)\n flash(t('staff.teamMembers.availability.ruleset.updateSuccess', 'Schedule updated.'), 'success')\n }, [initialValues?.updatedAt, memberId, t])\n\n const panelTabs = React.useMemo(() => ([\n { id: 'details' as const, label: t('staff.teamMembers.detail.tabs.details', 'Details') },\n { id: 'availability' as const, label: t('staff.teamMembers.detail.tabs.availability', 'Availability') },\n { id: 'jobHistory' as const, label: t('staff.teamMembers.detail.tabs.jobHistory', 'Job history') },\n ]), [t])\n\n const tabs = React.useMemo(() => ([\n { id: 'notes' as const, label: t('staff.teamMembers.detail.tabs.notes', 'Notes') },\n { id: 'activities' as const, label: t('staff.teamMembers.detail.tabs.activities', 'Activities') },\n { id: 'addresses' as const, label: t('staff.teamMembers.detail.tabs.addresses', 'Addresses') },\n ]), [t])\n\n const resolvedInitialValues = initialValues ?? {\n roleIds: [],\n isActive: true,\n }\n\n const displayName = memberRecord?.displayName ?? memberRecord?.display_name ?? resolvedInitialValues.displayName ?? ''\n const teamLabel = memberRecord?.team?.name ?? t('staff.teamMembers.detail.team.unassigned', 'Unassigned team')\n const roleLabels = Array.isArray(memberRecord?.roleNames) && memberRecord?.roleNames.length\n ? memberRecord?.roleNames\n : [t('staff.teamMembers.detail.roles.unassigned', 'No roles assigned')]\n const userEmail = memberRecord?.user?.email ?? null\n\n if (isNotFound) {\n return (\n <Page>\n <PageBody>\n <RecordNotFoundState\n label={t('staff.teamMembers.form.errors.notFound', 'Team member not found.')}\n backHref=\"/backend/staff/team-members\"\n backLabel={t('staff.teamMembers.actions.backToList', 'Back to team members')}\n />\n </PageBody>\n </Page>\n )\n }\n\n if (error && !initialValues) {\n return (\n <Page>\n <PageBody>\n <ErrorMessage label={error} />\n </PageBody>\n </Page>\n )\n }\n\n return (\n <Page>\n <PageBody>\n <div className=\"space-y-6\">\n <div className=\"flex flex-wrap items-center justify-between gap-3\">\n <div className=\"flex items-center gap-3\">\n <Link\n href=\"/backend/staff/team-members\"\n className=\"inline-flex items-center text-sm text-muted-foreground hover:text-foreground\"\n >\n <span aria-hidden className=\"mr-1 text-base\">\u2190</span>\n <span className=\"sr-only\">{t('staff.teamMembers.detail.back', 'Back to team members')}</span>\n </Link>\n <div className=\"space-y-1\">\n <h1 className=\"text-2xl font-semibold text-foreground\">\n {displayName || t('staff.teamMembers.detail.untitled', 'Unnamed team member')}\n </h1>\n <p className=\"text-sm text-muted-foreground\">\n {t('staff.teamMembers.detail.subtitle', 'Team member profile and activity')}\n </p>\n </div>\n </div>\n <div className=\"flex items-center gap-2\">\n {memberId ? (\n <SendObjectMessageDialog\n object={{\n entityModule: 'staff',\n entityType: 'team_member',\n entityId: memberId,\n previewData: {\n title: displayName,\n metadata: {\n [t('staff.teamMembers.detail.fields.team')]: teamLabel,\n [t('staff.teamMembers.detail.fields.user')]: userEmail ?? t('staff.teamMembers.detail.fields.userEmpty', 'No user linked'),\n [t('staff.teamMembers.detail.fields.roles')]: roleLabels.join(', '),\n },\n },\n }}\n viewHref={`/backend/staff/team-members/${memberId}`}\n />\n ) : null}\n <TranslationDrawerAction\n config={memberId ? {\n entityType: 'staff:staff_team_member',\n recordId: memberId,\n baseValues: memberRecord ?? undefined,\n } : null}\n />\n </div>\n </div>\n\n <div className=\"border-b\">\n <nav\n className=\"flex flex-wrap items-center gap-5 text-sm\"\n aria-label={t('staff.teamMembers.detail.tabs.label', 'Team member sections')}\n >\n {panelTabs.map((tab) => (\n <button\n key={tab.id}\n type=\"button\"\n role=\"tab\"\n aria-selected={activePanel === tab.id}\n onClick={() => setActivePanel(tab.id)}\n className={`relative -mb-px border-b-2 px-0 py-2 text-sm font-medium transition-colors ${\n activePanel === tab.id\n ? 'border-accent-indigo text-foreground'\n : 'border-transparent text-muted-foreground hover:text-foreground'\n }`}\n >\n {tab.label}\n </button>\n ))}\n </nav>\n </div>\n\n {activePanel === 'details' ? (\n <>\n <div className=\"grid gap-6 lg:grid-cols-[minmax(0,2fr),minmax(0,1.1fr)]\">\n <div className=\"space-y-6\">\n <div className=\"rounded-lg border bg-card p-4\">\n <h2 className=\"mb-4 text-sm font-semibold uppercase text-muted-foreground\">\n {t('staff.teamMembers.detail.highlights', 'Highlights')}\n </h2>\n <div className=\"grid gap-4 sm:grid-cols-2\">\n <div>\n <p className=\"text-xs font-medium uppercase text-muted-foreground\">\n {t('staff.teamMembers.detail.fields.team', 'Team')}\n </p>\n <p className=\"text-base text-foreground\">{teamLabel}</p>\n </div>\n <div>\n <p className=\"text-xs font-medium uppercase text-muted-foreground\">\n {t('staff.teamMembers.detail.fields.roles', 'Roles')}\n </p>\n <p className=\"text-base text-foreground\">{roleLabels.join(', ')}</p>\n </div>\n <div>\n <p className=\"text-xs font-medium uppercase text-muted-foreground\">\n {t('staff.teamMembers.detail.fields.user', 'User')}\n </p>\n <p className=\"text-base text-foreground\">\n {userEmail ?? t('staff.teamMembers.detail.fields.userEmpty', 'No user linked')}\n </p>\n </div>\n <div>\n <p className=\"text-xs font-medium uppercase text-muted-foreground\">\n {t('staff.teamMembers.detail.fields.status', 'Status')}\n </p>\n <p className=\"text-base text-foreground\">\n {memberRecord?.isActive ?? memberRecord?.is_active\n ? t('staff.teamMembers.detail.status.active', 'Active')\n : t('staff.teamMembers.detail.status.inactive', 'Inactive')}\n </p>\n </div>\n </div>\n </div>\n\n <div className=\"rounded-lg border bg-card p-4\">\n <div className=\"flex flex-wrap items-center justify-between gap-3\">\n <div className=\"flex gap-2\">\n {tabs.map((tab) => (\n <button\n key={tab.id}\n type=\"button\"\n onClick={() => setActiveTab(tab.id)}\n className={`relative -mb-px border-b-2 px-0 py-1 text-sm font-medium transition-colors ${\n activeTab === tab.id\n ? 'border-accent-indigo text-foreground'\n : 'border-transparent text-muted-foreground hover:text-foreground'\n }`}\n >\n {tab.label}\n </button>\n ))}\n </div>\n {sectionAction ? (\n <Button\n type=\"button\"\n size=\"sm\"\n disabled={sectionAction.disabled}\n onClick={() => sectionAction.onClick()}\n >\n {sectionAction.icon ?? (activeTab === 'addresses' ? <Plus className=\"mr-2 h-4 w-4\" /> : null)}\n {sectionAction.label}\n </Button>\n ) : null}\n </div>\n {activeTab === 'notes' ? (\n <NotesSection\n entityId={memberId ?? null}\n emptyLabel={t('staff.teamMembers.detail.notes.empty', 'No notes yet.')}\n viewerUserId={null}\n viewerName={null}\n viewerEmail={null}\n addActionLabel={t('staff.teamMembers.detail.notes.add', 'Add note')}\n emptyState={{\n title: t('staff.teamMembers.detail.notes.emptyTitle', 'Keep everyone in the loop'),\n actionLabel: t('staff.teamMembers.detail.notes.emptyAction', 'Add a note'),\n }}\n onActionChange={setSectionAction}\n translator={detailTranslator}\n labelPrefix=\"staff.teamMembers.detail.notes\"\n inlineLabelPrefix=\"staff.teamMembers.detail.inline\"\n dataAdapter={notesAdapter}\n renderIcon={renderDictionaryIcon}\n renderColor={renderDictionaryColor}\n iconSuggestions={ICON_SUGGESTIONS}\n />\n ) : null}\n {activeTab === 'activities' ? (\n <ActivitiesSection\n entityId={memberId ?? null}\n addActionLabel={t('staff.teamMembers.detail.activities.add', 'Log activity')}\n emptyState={{\n title: t('staff.teamMembers.detail.activities.emptyTitle', 'No activities yet'),\n actionLabel: t('staff.teamMembers.detail.activities.emptyAction', 'Add an activity'),\n }}\n onActionChange={setSectionAction}\n dataAdapter={activitiesAdapter}\n activityTypeLabels={activityTypeLabels}\n loadActivityOptions={loadActivityOptions}\n createActivityOption={createActivityOption}\n resolveActivityPresentation={resolveActivityPresentation}\n renderCustomFields={renderCustomFields}\n labelPrefix=\"staff.teamMembers.detail.activities\"\n renderIcon={renderDictionaryIcon}\n renderColor={renderDictionaryColor}\n appearanceLabels={appearanceLabels}\n manageHref={manageActivityHref}\n customFieldEntityIds={['staff:staff_team_member_activity']}\n />\n ) : null}\n {activeTab === 'addresses' ? (\n <SharedAddressesSection\n entityId={memberId ?? null}\n emptyLabel={t('staff.teamMembers.detail.addresses.empty', 'No addresses yet.')}\n addActionLabel={t('staff.teamMembers.detail.addresses.add', 'Add address')}\n emptyState={{\n title: t('staff.teamMembers.detail.addresses.emptyTitle', 'No addresses yet'),\n actionLabel: t('staff.teamMembers.detail.addresses.emptyAction', 'Add an address'),\n }}\n onActionChange={setSectionAction}\n dataAdapter={addressesAdapter}\n addressTypesAdapter={addressTypesAdapter}\n labelPrefix=\"staff.teamMembers.detail.addresses\"\n />\n ) : null}\n </div>\n </div>\n <div className=\"space-y-4\">\n <div className=\"rounded-lg border bg-card p-4\">\n <h2 className=\"mb-4 text-sm font-semibold uppercase text-muted-foreground\">\n {t('staff.teamMembers.detail.details', 'Member details')}\n </h2>\n <div className=\"space-y-2\">\n {memberRecord?.description ? (\n <MarkdownContent body={memberRecord.description} format=\"markdown\" className={MARKDOWN_CLASSNAME} />\n ) : (\n <p className=\"text-sm text-muted-foreground\">\n {t('staff.teamMembers.detail.descriptionEmpty', 'No description provided.')}\n </p>\n )}\n </div>\n </div>\n </div>\n </div>\n\n <div className=\"rounded-lg border bg-card p-4\">\n <h2 className=\"mb-4 text-sm font-semibold uppercase text-muted-foreground\">\n {t('staff.teamMembers.detail.formTitle', 'Member settings')}\n </h2>\n <TeamMemberForm\n embedded\n title={t('staff.teamMembers.form.editTitle', 'Edit team member')}\n backHref=\"/backend/staff/team-members\"\n cancelHref=\"/backend/staff/team-members\"\n initialValues={resolvedInitialValues}\n onSubmit={handleSubmit}\n onDelete={handleDelete}\n isLoading={!initialValues}\n loadingMessage={t('staff.teamMembers.form.loading', 'Loading team member...')}\n />\n </div>\n </>\n ) : activePanel === 'availability' ? (\n <AvailabilityRulesEditor\n subjectType=\"member\"\n subjectId={memberId ?? ''}\n labelPrefix=\"staff.teamMembers\"\n mode=\"availability\"\n rulesetId={availabilityRuleSetId}\n onRulesetChange={handleRulesetChange}\n allowRuleSetDelete\n buildScheduleItems={({ availabilityRules, translate: translateLabel }) => (\n buildMemberScheduleItems({ availabilityRules, translate: translateLabel })\n )}\n />\n ) : (\n <div className=\"rounded-lg border bg-card p-4\">\n <JobHistorySection memberId={memberId ?? null} />\n </div>\n )}\n </div>\n </PageBody>\n </Page>\n )\n}\n\nfunction normalizeStringList(value: unknown): string[] {\n if (!Array.isArray(value)) return []\n return value\n .map((entry) => (typeof entry === 'string' ? entry.trim() : ''))\n .filter((entry) => entry.length > 0)\n}\n\nfunction resolvePreferredArray<T>(primary?: T[] | null, fallback?: T[] | null): T[] | undefined {\n if (Array.isArray(primary) && primary.length) return primary\n if (Array.isArray(fallback) && fallback.length) return fallback\n return Array.isArray(primary) ? primary : Array.isArray(fallback) ? fallback : undefined\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport Link from 'next/link'\nimport { useRouter, useSearchParams } from 'next/navigation'\nimport { Page, PageBody } from '@open-mercato/ui/backend/Page'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { readApiResultOrThrow } from '@open-mercato/ui/backend/utils/apiCall'\nimport { extractCustomFieldEntries } from '@open-mercato/shared/lib/crud/custom-fields-client'\nimport { updateCrud, deleteCrud } from '@open-mercato/ui/backend/utils/crud'\nimport { switchTeamMemberSchedule } from '@open-mercato/core/modules/staff/lib/scheduleSwitch'\nimport { flash } from '@open-mercato/ui/backend/FlashMessages'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { createTranslatorWithFallback } from '@open-mercato/shared/lib/i18n/translate'\nimport { AvailabilityRulesEditor } from '@open-mercato/core/modules/planner/components/AvailabilityRulesEditor'\nimport { buildMemberScheduleItems } from '@open-mercato/core/modules/staff/lib/memberSchedule'\nimport { TeamMemberForm, buildTeamMemberPayload, type TeamMemberFormValues } from '@open-mercato/core/modules/staff/components/TeamMemberForm'\nimport { NotesSection } from '@open-mercato/ui/backend/detail'\nimport { ActivitiesSection, type SectionAction } from '@open-mercato/ui/backend/detail'\nimport { AddressesSection as SharedAddressesSection } from '@open-mercato/ui/backend/detail'\nimport { ErrorMessage, RecordNotFoundState } from '@open-mercato/ui/backend/detail'\nimport { renderDictionaryColor, renderDictionaryIcon, ICON_SUGGESTIONS } from '@open-mercato/core/modules/dictionaries/components/dictionaryAppearance'\nimport { createStaffNotesAdapter } from '@open-mercato/core/modules/staff/components/detail/notesAdapter'\nimport { createStaffActivitiesAdapter } from '@open-mercato/core/modules/staff/components/detail/activitiesAdapter'\nimport { createStaffAddressAdapter, createStaffAddressTypesAdapter } from '@open-mercato/core/modules/staff/components/detail/addressesAdapter'\nimport { MarkdownContent } from '@open-mercato/ui/backend/markdown/MarkdownContent'\nimport {\n createStaffDictionaryEntry,\n loadStaffDictionary,\n type DictionaryEntryOption,\n} from '@open-mercato/core/modules/staff/components/detail/dictionaries'\nimport { JobHistorySection } from '@open-mercato/core/modules/staff/components/detail/JobHistorySection'\nimport type { DictionarySelectLabels } from '@open-mercato/core/modules/dictionaries/components/DictionaryEntrySelect'\nimport { Plus } from 'lucide-react'\nimport { TranslationDrawerAction } from '@open-mercato/core/modules/translations/components/TranslationDrawerAction'\nimport { SendObjectMessageDialog } from '@open-mercato/ui/backend/messages'\n\nconst MARKDOWN_CLASSNAME =\n 'text-sm text-muted-foreground break-words [&>*]:mb-2 [&>*:last-child]:mb-0 [&_ul]:ml-4 [&_ul]:list-disc [&_ol]:ml-4 [&_ol]:list-decimal [&_code]:rounded [&_code]:bg-muted [&_code]:px-1 [&_code]:py-0.5 [&_pre]:rounded-md [&_pre]:bg-muted [&_pre]:p-3 [&_pre]:text-xs'\n\ntype TeamMemberRecord = {\n id: string\n teamId?: string | null\n team_id?: string | null\n displayName: string\n display_name?: string\n description?: string | null\n userId?: string | null\n user_id?: string | null\n roleIds?: string[]\n role_ids?: string[]\n roleNames?: string[]\n tags?: string[]\n isActive?: boolean\n is_active?: boolean\n availabilityRuleSetId?: string | null\n availability_rule_set_id?: string | null\n updatedAt?: string | null\n updated_at?: string | null\n user?: { id?: string; email?: string | null } | null\n team?: { id?: string; name?: string | null } | null\n customFields?: Record<string, unknown> | null\n} & Record<string, unknown>\n\ntype TeamMemberResponse = {\n items?: TeamMemberRecord[]\n}\n\nexport default function StaffTeamMemberDetailPage({ params }: { params?: { id?: string } }) {\n const memberId = params?.id\n const t = useT()\n const detailTranslator = React.useMemo(() => createTranslatorWithFallback(t), [t])\n const router = useRouter()\n const searchParams = useSearchParams()\n const [initialValues, setInitialValues] = React.useState<TeamMemberFormValues | null>(null)\n const [memberRecord, setMemberRecord] = React.useState<TeamMemberRecord | null>(null)\n const [error, setError] = React.useState<string | null>(null)\n const [isNotFound, setIsNotFound] = React.useState(false)\n const [availabilityRuleSetId, setAvailabilityRuleSetId] = React.useState<string | null>(null)\n const [activePanel, setActivePanel] = React.useState<'details' | 'availability' | 'jobHistory'>('details')\n const [activeTab, setActiveTab] = React.useState<'notes' | 'activities' | 'addresses'>('notes')\n const [sectionAction, setSectionAction] = React.useState<SectionAction | null>(null)\n const [activityDictionaryId, setActivityDictionaryId] = React.useState<string | null>(null)\n const [activityTypeEntries, setActivityTypeEntries] = React.useState<DictionaryEntryOption[]>([])\n const flashShownRef = React.useRef(false)\n\n const notesAdapter = React.useMemo(() => createStaffNotesAdapter(detailTranslator), [detailTranslator])\n const activitiesAdapter = React.useMemo(() => createStaffActivitiesAdapter(detailTranslator), [detailTranslator])\n const addressesAdapter = React.useMemo(() => createStaffAddressAdapter(detailTranslator), [detailTranslator])\n const addressTypesAdapter = React.useMemo(() => createStaffAddressTypesAdapter(detailTranslator), [detailTranslator])\n\n const activityTypeLabels = React.useMemo<DictionarySelectLabels>(() => ({\n placeholder: t('staff.teamMembers.detail.activities.dictionary.placeholder', 'Select an activity type'),\n addLabel: t('staff.teamMembers.detail.activities.dictionary.add', 'Add type'),\n addPrompt: t('staff.teamMembers.detail.activities.dictionary.prompt', 'Name the type'),\n dialogTitle: t('staff.teamMembers.detail.activities.dictionary.dialogTitle', 'Add activity type'),\n valueLabel: t('staff.teamMembers.detail.activities.dictionary.valueLabel', 'Name'),\n valuePlaceholder: t('staff.teamMembers.detail.activities.dictionary.valuePlaceholder', 'Name'),\n labelLabel: t('staff.teamMembers.detail.activities.dictionary.labelLabel', 'Label'),\n labelPlaceholder: t('staff.teamMembers.detail.activities.dictionary.labelPlaceholder', 'Display name shown in UI'),\n emptyError: t('staff.teamMembers.detail.activities.dictionary.emptyError', 'Please enter a name'),\n cancelLabel: t('staff.teamMembers.detail.activities.dictionary.cancel', 'Cancel'),\n saveLabel: t('staff.teamMembers.detail.activities.dictionary.save', 'Save'),\n saveShortcutHint: t('staff.teamMembers.detail.activities.dictionary.saveShortcut', '\u2318/Ctrl + Enter'),\n errorLoad: t('staff.teamMembers.detail.activities.dictionary.errorLoad', 'Failed to load options'),\n errorSave: t('staff.teamMembers.detail.activities.dictionary.errorSave', 'Failed to save option'),\n loadingLabel: t('staff.teamMembers.detail.activities.dictionary.loading', 'Loading\u2026'),\n manageTitle: t('staff.teamMembers.detail.activities.dictionary.manage', 'Manage dictionary'),\n }), [t])\n\n const loadActivityOptions = React.useCallback(async () => {\n const { dictionary, entries } = await loadStaffDictionary('activityTypes')\n setActivityDictionaryId(dictionary?.id ?? null)\n setActivityTypeEntries(entries)\n return entries\n }, [])\n\n const createActivityOption = React.useCallback(\n async (input: { value: string; label?: string; color?: string | null; icon?: string | null }) => {\n const entry = await createStaffDictionaryEntry('activityTypes', input)\n if (!entry) {\n throw new Error(t('staff.teamMembers.detail.activities.dictionary.errorSave', 'Failed to save option'))\n }\n return entry\n },\n [t],\n )\n\n React.useEffect(() => {\n loadActivityOptions().catch(() => {})\n }, [loadActivityOptions])\n\n const activityTypeMap = React.useMemo(\n () => new Map(activityTypeEntries.map((entry) => [entry.value, entry])),\n [activityTypeEntries],\n )\n\n const resolveActivityPresentation = React.useCallback(\n (activity: { activityType: string; appearanceIcon?: string | null; appearanceColor?: string | null }) => {\n const entry = activityTypeMap.get(activity.activityType)\n return {\n label: entry?.label ?? activity.activityType,\n icon: entry?.icon ?? activity.appearanceIcon ?? null,\n color: entry?.color ?? activity.appearanceColor ?? null,\n }\n },\n [activityTypeMap],\n )\n\n const manageActivityHref = React.useMemo(() => {\n if (!activityDictionaryId) return '/backend/config/dictionaries'\n return `/backend/config/dictionaries?dictionaryId=${encodeURIComponent(activityDictionaryId)}`\n }, [activityDictionaryId])\n\n const appearanceLabels = React.useMemo(() => ({\n colorLabel: t('staff.teamMembers.detail.activities.appearance.colorLabel', 'Color'),\n colorHelp: t('staff.teamMembers.detail.activities.appearance.colorHelp', 'Pick a highlight color for this entry.'),\n colorClearLabel: t('staff.teamMembers.detail.activities.appearance.colorClear', 'Remove color'),\n iconLabel: t('staff.teamMembers.detail.activities.appearance.iconLabel', 'Icon or emoji'),\n iconPlaceholder: t('staff.teamMembers.detail.activities.appearance.iconPlaceholder', 'Type an emoji or pick one of the suggestions.'),\n iconPickerTriggerLabel: t('staff.teamMembers.detail.activities.appearance.iconBrowse', 'Browse icons and emojis'),\n iconSearchPlaceholder: t('staff.teamMembers.detail.activities.appearance.iconSearchPlaceholder', 'Search icons or emojis\u2026'),\n iconSearchEmptyLabel: t('staff.teamMembers.detail.activities.appearance.iconSearchEmpty', 'No icons match your search.'),\n iconSuggestionsLabel: t('staff.teamMembers.detail.activities.appearance.iconSuggestions', 'Suggestions'),\n iconClearLabel: t('staff.teamMembers.detail.activities.appearance.iconClear', 'Remove icon'),\n previewEmptyLabel: t('staff.teamMembers.detail.activities.appearance.previewEmpty', 'No appearance selected'),\n }), [t])\n\n const renderCustomFields = React.useCallback((activity: { id?: string; customFields?: Array<{ key: string; label?: string | null; value: unknown }> }) => {\n const entries = Array.isArray(activity.customFields) ? activity.customFields : []\n if (!entries.length) return null\n const emptyLabel = t('staff.teamMembers.detail.activities.customFields.empty', 'Not provided')\n return (\n <div className=\"grid gap-3 sm:grid-cols-2\">\n {entries.map((entry, index) => {\n const label = entry.label ?? entry.key\n const value = entry.value\n const hasValue = !(value == null || value === '' || (Array.isArray(value) && value.length === 0))\n const content = hasValue\n ? Array.isArray(value)\n ? value.map((item) => String(item)).join(', ')\n : String(value)\n : emptyLabel\n return (\n <div\n key={`activity-${activity.id ?? 'row'}-custom-${index}`}\n className=\"rounded-md border border-border/70 bg-muted/30 px-3 py-2\"\n >\n <div className=\"text-xs font-medium text-muted-foreground\">{label}</div>\n <div className=\"mt-1 text-sm text-foreground\">{content}</div>\n </div>\n )\n })}\n </div>\n )\n }, [t])\n\n React.useEffect(() => {\n if (!memberId) return\n const memberIdValue = memberId\n let cancelled = false\n async function loadMember() {\n if (!cancelled) {\n setError(null)\n setIsNotFound(false)\n }\n try {\n const params = new URLSearchParams({ page: '1', pageSize: '1', ids: memberIdValue })\n const payload = await readApiResultOrThrow<TeamMemberResponse>(\n `/api/staff/team-members?${params.toString()}`,\n undefined,\n { errorMessage: t('staff.teamMembers.form.errors.load', 'Failed to load team member.') },\n )\n const record = Array.isArray(payload.items) ? payload.items[0] : null\n if (!record) {\n if (!cancelled) setIsNotFound(true)\n return\n }\n const customFields = extractCustomFieldEntries(record)\n if (!cancelled) {\n const resolvedTeamId = record.teamId ?? record.team_id ?? null\n const normalizedRoleIds = normalizeStringList(resolvePreferredArray(record.roleIds, record.role_ids))\n setInitialValues({\n id: record.id,\n teamId: resolvedTeamId,\n userId: record.userId ?? record.user_id ?? null,\n displayName: record.displayName ?? record.display_name ?? '',\n description: record.description ?? '',\n roleIds: normalizedRoleIds,\n tags: normalizeStringList(record.tags),\n isActive: record.isActive ?? record.is_active ?? true,\n updatedAt: typeof record.updatedAt === 'string'\n ? record.updatedAt\n : typeof record.updated_at === 'string'\n ? record.updated_at\n : null,\n ...customFields,\n })\n setMemberRecord(record)\n setAvailabilityRuleSetId(\n typeof record.availabilityRuleSetId === 'string'\n ? record.availabilityRuleSetId\n : typeof record.availability_rule_set_id === 'string'\n ? record.availability_rule_set_id\n : null,\n )\n }\n } catch (err) {\n if (!cancelled) {\n if ((err as { status?: number }).status === 404) {\n setIsNotFound(true)\n } else {\n const message = err instanceof Error ? err.message : t('staff.teamMembers.form.errors.load', 'Failed to load team member.')\n setError(message)\n }\n }\n }\n }\n void loadMember()\n return () => { cancelled = true }\n }, [memberId, t])\n\n React.useEffect(() => {\n if (!searchParams) return\n const created = searchParams.get('created') === '1'\n if (created && !flashShownRef.current) {\n flashShownRef.current = true\n flash(t('staff.teamMembers.flash.createdAvailability', 'Saved. You can now set availability.'), 'success')\n const nextParams = new URLSearchParams(searchParams.toString())\n nextParams.delete('created')\n const nextQuery = nextParams.toString()\n const nextPath = memberId\n ? `/backend/staff/team-members/${encodeURIComponent(memberId)}${nextQuery ? `?${nextQuery}` : ''}`\n : `/backend/staff/team-members${nextQuery ? `?${nextQuery}` : ''}`\n router.replace(nextPath)\n }\n }, [memberId, router, searchParams, t])\n\n // optimistic-lock-exempt: the inline updateCrud/deleteCrud below run inside the\n // TeamMemberForm <CrudForm> host, which auto-derives the version header from\n // initialValues.updatedAt and surfaces 409 conflicts for both submit and delete.\n // The availability-schedule switch is version-locked separately via\n // switchTeamMemberSchedule (see ../../../../lib/scheduleSwitch).\n const handleSubmit = React.useCallback(async (values: TeamMemberFormValues) => {\n if (!memberId) return\n const payload = buildTeamMemberPayload(values, { id: memberId })\n await updateCrud('staff/team-members', payload, {\n errorMessage: t('staff.teamMembers.form.errors.update', 'Failed to update team member.'),\n })\n flash(t('staff.teamMembers.form.flash.updated', 'Team member updated.'), 'success')\n router.push('/backend/staff/team-members')\n }, [memberId, router, t])\n\n const handleDelete = React.useCallback(async () => {\n if (!memberId) return\n await deleteCrud('staff/team-members', memberId, {\n errorMessage: t('staff.teamMembers.form.errors.delete', 'Failed to delete team member.'),\n })\n flash(t('staff.teamMembers.form.flash.deleted', 'Team member deleted.'), 'success')\n router.push('/backend/staff/team-members')\n }, [memberId, router, t])\n\n const handleRulesetChange = React.useCallback(async (nextId: string | null) => {\n if (!memberId) return\n const { updatedAt: nextUpdatedAt } = await switchTeamMemberSchedule({\n memberId,\n nextRuleSetId: nextId,\n expectedUpdatedAt: initialValues?.updatedAt,\n t,\n })\n // Advance the optimistic-lock token so the next sequential switch sends the\n // fresh updatedAt instead of the stale one and does not falsely 409 (#2848).\n if (nextUpdatedAt) {\n setInitialValues((prev) => (prev ? { ...prev, updatedAt: nextUpdatedAt } : prev))\n }\n setAvailabilityRuleSetId(nextId)\n flash(t('staff.teamMembers.availability.ruleset.updateSuccess', 'Schedule updated.'), 'success')\n }, [initialValues?.updatedAt, memberId, t])\n\n const panelTabs = React.useMemo(() => ([\n { id: 'details' as const, label: t('staff.teamMembers.detail.tabs.details', 'Details') },\n { id: 'availability' as const, label: t('staff.teamMembers.detail.tabs.availability', 'Availability') },\n { id: 'jobHistory' as const, label: t('staff.teamMembers.detail.tabs.jobHistory', 'Job history') },\n ]), [t])\n\n const tabs = React.useMemo(() => ([\n { id: 'notes' as const, label: t('staff.teamMembers.detail.tabs.notes', 'Notes') },\n { id: 'activities' as const, label: t('staff.teamMembers.detail.tabs.activities', 'Activities') },\n { id: 'addresses' as const, label: t('staff.teamMembers.detail.tabs.addresses', 'Addresses') },\n ]), [t])\n\n const resolvedInitialValues = initialValues ?? {\n roleIds: [],\n isActive: true,\n }\n\n const displayName = memberRecord?.displayName ?? memberRecord?.display_name ?? resolvedInitialValues.displayName ?? ''\n const teamLabel = memberRecord?.team?.name ?? t('staff.teamMembers.detail.team.unassigned', 'Unassigned team')\n const roleLabels = Array.isArray(memberRecord?.roleNames) && memberRecord?.roleNames.length\n ? memberRecord?.roleNames\n : [t('staff.teamMembers.detail.roles.unassigned', 'No roles assigned')]\n const userEmail = memberRecord?.user?.email ?? null\n\n if (isNotFound) {\n return (\n <Page>\n <PageBody>\n <RecordNotFoundState\n label={t('staff.teamMembers.form.errors.notFound', 'Team member not found.')}\n backHref=\"/backend/staff/team-members\"\n backLabel={t('staff.teamMembers.actions.backToList', 'Back to team members')}\n />\n </PageBody>\n </Page>\n )\n }\n\n if (error && !initialValues) {\n return (\n <Page>\n <PageBody>\n <ErrorMessage label={error} />\n </PageBody>\n </Page>\n )\n }\n\n return (\n <Page>\n <PageBody>\n <div className=\"space-y-6\">\n <div className=\"flex flex-wrap items-center justify-between gap-3\">\n <div className=\"flex items-center gap-3\">\n <Link\n href=\"/backend/staff/team-members\"\n className=\"inline-flex items-center text-sm text-muted-foreground hover:text-foreground\"\n >\n <span aria-hidden className=\"mr-1 text-base\">\u2190</span>\n <span className=\"sr-only\">{t('staff.teamMembers.detail.back', 'Back to team members')}</span>\n </Link>\n <div className=\"space-y-1\">\n <h1 className=\"text-2xl font-semibold text-foreground\">\n {displayName || t('staff.teamMembers.detail.untitled', 'Unnamed team member')}\n </h1>\n <p className=\"text-sm text-muted-foreground\">\n {t('staff.teamMembers.detail.subtitle', 'Team member profile and activity')}\n </p>\n </div>\n </div>\n <div className=\"flex items-center gap-2\">\n {memberId ? (\n <SendObjectMessageDialog\n object={{\n entityModule: 'staff',\n entityType: 'team_member',\n entityId: memberId,\n previewData: {\n title: displayName,\n metadata: {\n [t('staff.teamMembers.detail.fields.team')]: teamLabel,\n [t('staff.teamMembers.detail.fields.user')]: userEmail ?? t('staff.teamMembers.detail.fields.userEmpty', 'No user linked'),\n [t('staff.teamMembers.detail.fields.roles')]: roleLabels.join(', '),\n },\n },\n }}\n viewHref={`/backend/staff/team-members/${memberId}`}\n />\n ) : null}\n <TranslationDrawerAction\n config={memberId ? {\n entityType: 'staff:staff_team_member',\n recordId: memberId,\n baseValues: memberRecord ?? undefined,\n } : null}\n />\n </div>\n </div>\n\n <div className=\"border-b\">\n <nav\n className=\"flex flex-wrap items-center gap-5 text-sm\"\n aria-label={t('staff.teamMembers.detail.tabs.label', 'Team member sections')}\n >\n {panelTabs.map((tab) => (\n <button\n key={tab.id}\n type=\"button\"\n role=\"tab\"\n aria-selected={activePanel === tab.id}\n onClick={() => setActivePanel(tab.id)}\n className={`relative -mb-px border-b-2 px-0 py-2 text-sm font-medium transition-colors ${\n activePanel === tab.id\n ? 'border-accent-indigo text-foreground'\n : 'border-transparent text-muted-foreground hover:text-foreground'\n }`}\n >\n {tab.label}\n </button>\n ))}\n </nav>\n </div>\n\n {activePanel === 'details' ? (\n <>\n <div className=\"grid gap-6 lg:grid-cols-[minmax(0,2fr),minmax(0,1.1fr)]\">\n <div className=\"space-y-6\">\n <div className=\"rounded-lg border bg-card p-4\">\n <h2 className=\"mb-4 text-sm font-semibold uppercase text-muted-foreground\">\n {t('staff.teamMembers.detail.highlights', 'Highlights')}\n </h2>\n <div className=\"grid gap-4 sm:grid-cols-2\">\n <div>\n <p className=\"text-xs font-medium uppercase text-muted-foreground\">\n {t('staff.teamMembers.detail.fields.team', 'Team')}\n </p>\n <p className=\"text-base text-foreground\">{teamLabel}</p>\n </div>\n <div>\n <p className=\"text-xs font-medium uppercase text-muted-foreground\">\n {t('staff.teamMembers.detail.fields.roles', 'Roles')}\n </p>\n <p className=\"text-base text-foreground\">{roleLabels.join(', ')}</p>\n </div>\n <div>\n <p className=\"text-xs font-medium uppercase text-muted-foreground\">\n {t('staff.teamMembers.detail.fields.user', 'User')}\n </p>\n <p className=\"text-base text-foreground\">\n {userEmail ?? t('staff.teamMembers.detail.fields.userEmpty', 'No user linked')}\n </p>\n </div>\n <div>\n <p className=\"text-xs font-medium uppercase text-muted-foreground\">\n {t('staff.teamMembers.detail.fields.status', 'Status')}\n </p>\n <p className=\"text-base text-foreground\">\n {memberRecord?.isActive ?? memberRecord?.is_active\n ? t('staff.teamMembers.detail.status.active', 'Active')\n : t('staff.teamMembers.detail.status.inactive', 'Inactive')}\n </p>\n </div>\n </div>\n </div>\n\n <div className=\"rounded-lg border bg-card p-4\">\n <div className=\"flex flex-wrap items-center justify-between gap-3\">\n <div className=\"flex gap-2\">\n {tabs.map((tab) => (\n <button\n key={tab.id}\n type=\"button\"\n onClick={() => setActiveTab(tab.id)}\n className={`relative -mb-px border-b-2 px-0 py-1 text-sm font-medium transition-colors ${\n activeTab === tab.id\n ? 'border-accent-indigo text-foreground'\n : 'border-transparent text-muted-foreground hover:text-foreground'\n }`}\n >\n {tab.label}\n </button>\n ))}\n </div>\n {sectionAction ? (\n <Button\n type=\"button\"\n size=\"sm\"\n disabled={sectionAction.disabled}\n onClick={() => sectionAction.onClick()}\n >\n {sectionAction.icon ?? (activeTab === 'addresses' ? <Plus className=\"mr-2 h-4 w-4\" /> : null)}\n {sectionAction.label}\n </Button>\n ) : null}\n </div>\n {activeTab === 'notes' ? (\n <NotesSection\n entityId={memberId ?? null}\n emptyLabel={t('staff.teamMembers.detail.notes.empty', 'No notes yet.')}\n viewerUserId={null}\n viewerName={null}\n viewerEmail={null}\n addActionLabel={t('staff.teamMembers.detail.notes.add', 'Add note')}\n emptyState={{\n title: t('staff.teamMembers.detail.notes.emptyTitle', 'Keep everyone in the loop'),\n actionLabel: t('staff.teamMembers.detail.notes.emptyAction', 'Add a note'),\n }}\n onActionChange={setSectionAction}\n translator={detailTranslator}\n labelPrefix=\"staff.teamMembers.detail.notes\"\n inlineLabelPrefix=\"staff.teamMembers.detail.inline\"\n dataAdapter={notesAdapter}\n renderIcon={renderDictionaryIcon}\n renderColor={renderDictionaryColor}\n iconSuggestions={ICON_SUGGESTIONS}\n />\n ) : null}\n {activeTab === 'activities' ? (\n <ActivitiesSection\n entityId={memberId ?? null}\n addActionLabel={t('staff.teamMembers.detail.activities.add', 'Log activity')}\n emptyState={{\n title: t('staff.teamMembers.detail.activities.emptyTitle', 'No activities yet'),\n actionLabel: t('staff.teamMembers.detail.activities.emptyAction', 'Add an activity'),\n }}\n onActionChange={setSectionAction}\n dataAdapter={activitiesAdapter}\n activityTypeLabels={activityTypeLabels}\n loadActivityOptions={loadActivityOptions}\n createActivityOption={createActivityOption}\n resolveActivityPresentation={resolveActivityPresentation}\n renderCustomFields={renderCustomFields}\n labelPrefix=\"staff.teamMembers.detail.activities\"\n renderIcon={renderDictionaryIcon}\n renderColor={renderDictionaryColor}\n appearanceLabels={appearanceLabels}\n manageHref={manageActivityHref}\n customFieldEntityIds={['staff:staff_team_member_activity']}\n />\n ) : null}\n {activeTab === 'addresses' ? (\n <SharedAddressesSection\n entityId={memberId ?? null}\n emptyLabel={t('staff.teamMembers.detail.addresses.empty', 'No addresses yet.')}\n addActionLabel={t('staff.teamMembers.detail.addresses.add', 'Add address')}\n emptyState={{\n title: t('staff.teamMembers.detail.addresses.emptyTitle', 'No addresses yet'),\n actionLabel: t('staff.teamMembers.detail.addresses.emptyAction', 'Add an address'),\n }}\n onActionChange={setSectionAction}\n dataAdapter={addressesAdapter}\n addressTypesAdapter={addressTypesAdapter}\n labelPrefix=\"staff.teamMembers.detail.addresses\"\n />\n ) : null}\n </div>\n </div>\n <div className=\"space-y-4\">\n <div className=\"rounded-lg border bg-card p-4\">\n <h2 className=\"mb-4 text-sm font-semibold uppercase text-muted-foreground\">\n {t('staff.teamMembers.detail.details', 'Member details')}\n </h2>\n <div className=\"space-y-2\">\n {memberRecord?.description ? (\n <MarkdownContent body={memberRecord.description} format=\"markdown\" className={MARKDOWN_CLASSNAME} />\n ) : (\n <p className=\"text-sm text-muted-foreground\">\n {t('staff.teamMembers.detail.descriptionEmpty', 'No description provided.')}\n </p>\n )}\n </div>\n </div>\n </div>\n </div>\n\n <div className=\"rounded-lg border bg-card p-4\">\n <h2 className=\"mb-4 text-sm font-semibold uppercase text-muted-foreground\">\n {t('staff.teamMembers.detail.formTitle', 'Member settings')}\n </h2>\n <TeamMemberForm\n embedded\n title={t('staff.teamMembers.form.editTitle', 'Edit team member')}\n backHref=\"/backend/staff/team-members\"\n cancelHref=\"/backend/staff/team-members\"\n initialValues={resolvedInitialValues}\n onSubmit={handleSubmit}\n onDelete={handleDelete}\n isLoading={!initialValues}\n loadingMessage={t('staff.teamMembers.form.loading', 'Loading team member...')}\n />\n </div>\n </>\n ) : activePanel === 'availability' ? (\n <AvailabilityRulesEditor\n subjectType=\"member\"\n subjectId={memberId ?? ''}\n labelPrefix=\"staff.teamMembers\"\n mode=\"availability\"\n rulesetId={availabilityRuleSetId}\n onRulesetChange={handleRulesetChange}\n allowRuleSetDelete\n buildScheduleItems={({ availabilityRules, translate: translateLabel }) => (\n buildMemberScheduleItems({ availabilityRules, translate: translateLabel })\n )}\n />\n ) : (\n <div className=\"rounded-lg border bg-card p-4\">\n <JobHistorySection memberId={memberId ?? null} />\n </div>\n )}\n </div>\n </PageBody>\n </Page>\n )\n}\n\nfunction normalizeStringList(value: unknown): string[] {\n if (!Array.isArray(value)) return []\n return value\n .map((entry) => (typeof entry === 'string' ? entry.trim() : ''))\n .filter((entry) => entry.length > 0)\n}\n\nfunction resolvePreferredArray<T>(primary?: T[] | null, fallback?: T[] | null): T[] | undefined {\n if (Array.isArray(primary) && primary.length) return primary\n if (Array.isArray(fallback) && fallback.length) return fallback\n return Array.isArray(primary) ? primary : Array.isArray(fallback) ? fallback : undefined\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["params"]
7
7
  }
@@ -313,7 +313,7 @@ const updateTeamMemberCommand = {
313
313
  events: staffTeamMemberCrudEvents,
314
314
  indexer: teamMemberCrudIndexer
315
315
  });
316
- return { memberId: member.id };
316
+ return { memberId: member.id, updatedAt: member.updatedAt ? member.updatedAt.toISOString() : null };
317
317
  },
318
318
  buildLog: async ({ snapshots, ctx }) => {
319
319
  const before = snapshots.before;
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/modules/staff/commands/team-members.ts"],
4
- "sourcesContent": ["import type { CommandHandler } from '@open-mercato/shared/lib/commands'\nimport { registerCommand } from '@open-mercato/shared/lib/commands'\nimport type { EntityManager } from '@mikro-orm/postgresql'\nimport { CrudHttpError } from '@open-mercato/shared/lib/crud/errors'\nimport { resolveTranslations } from '@open-mercato/shared/lib/i18n/server'\nimport { findOneWithDecryption, findWithDecryption } from '@open-mercato/shared/lib/encryption/find'\nimport { buildChanges, emitCrudSideEffects, emitCrudUndoSideEffects, parseWithCustomFields, setCustomFieldsIfAny } from '@open-mercato/shared/lib/commands/helpers'\nimport { buildCustomFieldResetMap, diffCustomFieldChanges, loadCustomFieldSnapshot, type CustomFieldSnapshot } from '@open-mercato/shared/lib/commands/customFieldSnapshots'\nimport { makeCreateRedo } from '@open-mercato/shared/lib/commands/redo'\nimport { withAtomicFlush } from '@open-mercato/shared/lib/commands/flush'\nimport type { DataEngine } from '@open-mercato/shared/lib/data/engine'\nimport type { CrudIndexerConfig } from '@open-mercato/shared/lib/crud/types'\nimport { User } from '@open-mercato/core/modules/auth/data/entities'\nimport { StaffTeam, StaffTeamMember, StaffTeamRole } from '../data/entities'\nimport {\n staffTeamMemberCreateSchema,\n staffTeamMemberUpdateSchema,\n type StaffTeamMemberCreateInput,\n type StaffTeamMemberUpdateInput,\n} from '../data/validators'\nimport { staffTeamMemberCrudEvents } from '../lib/crud'\nimport { ensureOrganizationScope, ensureTenantScope, extractUndoPayload } from './shared'\nimport { E } from '#generated/entities.ids.generated'\n\nconst teamMemberCrudIndexer: CrudIndexerConfig<StaffTeamMember> = {\n entityType: E.staff.staff_team_member,\n}\n\ntype TeamMemberSnapshot = {\n id: string\n tenantId: string\n organizationId: string\n teamId: string | null\n displayName: string\n description: string | null\n userId: string | null\n roleIds: string[]\n tags: string[]\n isActive: boolean\n deletedAt: string | null\n}\n\ntype TeamMemberUndoPayload = {\n before?: TeamMemberSnapshot | null\n after?: TeamMemberSnapshot | null\n customBefore?: CustomFieldSnapshot | null\n customAfter?: CustomFieldSnapshot | null\n}\n\nfunction normalizeStringList(value: unknown): string[] {\n if (!Array.isArray(value)) return []\n const set = new Set<string>()\n value.forEach((entry) => {\n if (typeof entry === 'string') {\n const trimmed = entry.trim()\n if (trimmed.length) set.add(trimmed)\n }\n })\n return Array.from(set)\n}\n\nasync function loadTeamMemberSnapshot(em: EntityManager, id: string): Promise<TeamMemberSnapshot | null> {\n const member = await findOneWithDecryption(em, StaffTeamMember, { id }, undefined, { tenantId: null, organizationId: null })\n if (!member) return null\n return {\n id: member.id,\n tenantId: member.tenantId,\n organizationId: member.organizationId,\n teamId: member.teamId ?? null,\n displayName: member.displayName,\n description: member.description ?? null,\n userId: member.userId ?? null,\n roleIds: Array.isArray(member.roleIds) ? member.roleIds : [],\n tags: Array.isArray(member.tags) ? member.tags : [],\n isActive: member.isActive ?? true,\n deletedAt: member.deletedAt ? member.deletedAt.toISOString() : null,\n }\n}\n\nasync function loadTeamMemberCustomSnapshot(\n em: EntityManager,\n snapshot: TeamMemberSnapshot,\n): Promise<CustomFieldSnapshot> {\n return loadCustomFieldSnapshot(em, {\n entityId: E.staff.staff_team_member,\n recordId: snapshot.id,\n tenantId: snapshot.tenantId,\n organizationId: snapshot.organizationId,\n })\n}\n\nfunction teamMemberSeedFromSnapshot(snapshot: TeamMemberSnapshot): Record<string, unknown> {\n return {\n id: snapshot.id,\n tenantId: snapshot.tenantId,\n organizationId: snapshot.organizationId,\n teamId: snapshot.teamId ?? null,\n displayName: snapshot.displayName,\n description: snapshot.description ?? null,\n userId: snapshot.userId ?? null,\n roleIds: Array.isArray(snapshot.roleIds) ? snapshot.roleIds : [],\n tags: Array.isArray(snapshot.tags) ? snapshot.tags : [],\n availabilityRuleSetId: null,\n isActive: snapshot.isActive,\n createdAt: new Date(),\n updatedAt: new Date(),\n deletedAt: null,\n }\n}\n\nconst redoTeamMemberCreate = makeCreateRedo<StaffTeamMember, TeamMemberSnapshot, StaffTeamMemberCreateInput, { memberId: string }>({\n entityClass: StaffTeamMember,\n getSnapshotId: (snapshot) => snapshot.id,\n seedFromSnapshot: teamMemberSeedFromSnapshot,\n buildResult: (entity) => ({ memberId: entity.id }),\n events: staffTeamMemberCrudEvents,\n indexer: teamMemberCrudIndexer,\n})\n\nasync function ensureRolesExist(em: EntityManager, roleIds: string[], tenantId: string, organizationId: string): Promise<void> {\n if (!roleIds.length) return\n const roles = await findWithDecryption(\n em,\n StaffTeamRole,\n { id: { $in: roleIds }, tenantId, organizationId, deletedAt: null },\n undefined,\n { tenantId, organizationId },\n )\n if (roles.length !== roleIds.length) {\n throw new CrudHttpError(400, { error: 'One or more team roles were not found.' })\n }\n}\n\nasync function ensureUserExists(em: EntityManager, userId: string, tenantId: string, organizationId: string): Promise<void> {\n const user = await findOneWithDecryption(\n em,\n User,\n { id: userId, deletedAt: null },\n undefined,\n { tenantId, organizationId },\n )\n if (!user) throw new CrudHttpError(400, { error: 'User not found.' })\n if (user.tenantId && user.tenantId !== tenantId) {\n throw new CrudHttpError(400, { error: 'User does not belong to this tenant.' })\n }\n if (user.organizationId && user.organizationId !== organizationId) {\n throw new CrudHttpError(400, { error: 'User does not belong to this organization.' })\n }\n}\n\nasync function ensureTeamExists(em: EntityManager, teamId: string, tenantId: string, organizationId: string): Promise<void> {\n const team = await findOneWithDecryption(\n em,\n StaffTeam,\n { id: teamId, tenantId, organizationId, deletedAt: null },\n undefined,\n { tenantId, organizationId },\n )\n if (!team) throw new CrudHttpError(400, { error: 'Team not found.' })\n}\n\nconst createTeamMemberCommand: CommandHandler<StaffTeamMemberCreateInput, { memberId: string }> = {\n id: 'staff.team-members.create',\n async execute(rawInput, ctx) {\n const { parsed, custom } = parseWithCustomFields(staffTeamMemberCreateSchema, rawInput)\n ensureTenantScope(ctx, parsed.tenantId)\n ensureOrganizationScope(ctx, parsed.organizationId)\n\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const roleIds = normalizeStringList(parsed.roleIds)\n const tags = normalizeStringList(parsed.tags)\n if (parsed.userId) {\n await ensureUserExists(em, parsed.userId, parsed.tenantId, parsed.organizationId)\n }\n if (parsed.teamId) {\n await ensureTeamExists(em, parsed.teamId, parsed.tenantId, parsed.organizationId)\n }\n await ensureRolesExist(em, roleIds, parsed.tenantId, parsed.organizationId)\n\n const now = new Date()\n const member = em.create(StaffTeamMember, {\n tenantId: parsed.tenantId,\n organizationId: parsed.organizationId,\n teamId: parsed.teamId ?? null,\n displayName: parsed.displayName,\n description: parsed.description ?? null,\n userId: parsed.userId ?? null,\n roleIds,\n tags,\n availabilityRuleSetId: parsed.availabilityRuleSetId ?? null,\n isActive: parsed.isActive ?? true,\n createdAt: now,\n updatedAt: now,\n deletedAt: null,\n })\n em.persist(member)\n await em.flush()\n\n const de = (ctx.container.resolve('dataEngine') as DataEngine)\n await setCustomFieldsIfAny({\n dataEngine: de,\n entityId: E.staff.staff_team_member,\n recordId: member.id,\n tenantId: member.tenantId,\n organizationId: member.organizationId,\n values: custom,\n })\n\n await emitCrudSideEffects({\n dataEngine: de,\n action: 'created',\n entity: member,\n identifiers: {\n id: member.id,\n organizationId: member.organizationId,\n tenantId: member.tenantId,\n },\n events: staffTeamMemberCrudEvents,\n indexer: teamMemberCrudIndexer,\n })\n\n return { memberId: member.id }\n },\n captureAfter: async (_input, result, ctx) => {\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const snapshot = await loadTeamMemberSnapshot(em, result.memberId)\n if (!snapshot) return null\n const custom = await loadTeamMemberCustomSnapshot(em, snapshot)\n return { snapshot, custom }\n },\n buildLog: async ({ result, ctx }) => {\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const snapshot = await loadTeamMemberSnapshot(em, result.memberId)\n if (!snapshot) return null\n const custom = await loadTeamMemberCustomSnapshot(em, snapshot)\n const { translate } = await resolveTranslations()\n return {\n actionLabel: translate('staff.audit.teamMembers.create', 'Create team member'),\n resourceKind: 'staff.teamMember',\n resourceId: snapshot.id,\n tenantId: snapshot.tenantId,\n organizationId: snapshot.organizationId,\n snapshotAfter: snapshot,\n payload: {\n undo: {\n after: snapshot,\n customAfter: custom,\n } satisfies TeamMemberUndoPayload,\n },\n }\n },\n undo: async ({ logEntry, ctx }) => {\n const payload = extractUndoPayload<TeamMemberUndoPayload>(logEntry)\n const after = payload?.after\n if (!after) return\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const member = await em.findOne(StaffTeamMember, { id: after.id })\n if (member) {\n member.deletedAt = new Date()\n await em.flush()\n\n const de = (ctx.container.resolve('dataEngine') as DataEngine)\n await emitCrudUndoSideEffects({\n dataEngine: de,\n action: 'deleted',\n entity: member,\n identifiers: {\n id: member.id,\n organizationId: member.organizationId,\n tenantId: member.tenantId,\n },\n events: staffTeamMemberCrudEvents,\n indexer: teamMemberCrudIndexer,\n })\n }\n },\n redo: async ({ logEntry, ctx }) => {\n const result = await redoTeamMemberCreate({ input: undefined as unknown as StaffTeamMemberCreateInput, ctx, logEntry })\n const payload = extractUndoPayload<TeamMemberUndoPayload>(logEntry)\n const customAfter = payload?.customAfter\n if (customAfter && Object.keys(customAfter).length) {\n await setCustomFieldsIfAny({\n dataEngine: ctx.container.resolve('dataEngine') as DataEngine,\n entityId: E.staff.staff_team_member,\n recordId: result.memberId,\n tenantId: payload?.after?.tenantId ?? '',\n organizationId: payload?.after?.organizationId ?? '',\n values: customAfter,\n })\n }\n return result\n },\n}\n\nconst updateTeamMemberCommand: CommandHandler<StaffTeamMemberUpdateInput, { memberId: string }> = {\n id: 'staff.team-members.update',\n async prepare(rawInput, ctx) {\n const { parsed } = parseWithCustomFields(staffTeamMemberUpdateSchema, rawInput)\n const em = (ctx.container.resolve('em') as EntityManager)\n const snapshot = await loadTeamMemberSnapshot(em, parsed.id)\n if (!snapshot) return {}\n const custom = await loadTeamMemberCustomSnapshot(em, snapshot)\n return { before: snapshot, customBefore: custom }\n },\n async execute(rawInput, ctx) {\n const { parsed, custom } = parseWithCustomFields(staffTeamMemberUpdateSchema, rawInput)\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const member = await findOneWithDecryption(\n em,\n StaffTeamMember,\n { id: parsed.id, deletedAt: null },\n undefined,\n { tenantId: ctx.auth?.tenantId ?? null, organizationId: ctx.auth?.orgId ?? null },\n )\n if (!member) throw new CrudHttpError(404, { error: 'Team member not found.' })\n ensureTenantScope(ctx, member.tenantId)\n ensureOrganizationScope(ctx, member.organizationId)\n\n // Resolve validation queries BEFORE mutating scalars: `ensure*` runs `em.find`,\n // which would otherwise reset unit-of-work tracking between mutations and the\n // flush and silently drop earlier scalar changes (SPEC-018 Problem 1).\n if (parsed.userId !== undefined && parsed.userId) {\n await ensureUserExists(em, parsed.userId, member.tenantId, member.organizationId)\n }\n if (parsed.teamId !== undefined && parsed.teamId) {\n await ensureTeamExists(em, parsed.teamId, member.tenantId, member.organizationId)\n }\n let nextRoleIds: string[] | undefined\n if (parsed.roleIds !== undefined) {\n nextRoleIds = normalizeStringList(parsed.roleIds)\n await ensureRolesExist(em, nextRoleIds, member.tenantId, member.organizationId)\n }\n\n await withAtomicFlush(em, [\n () => {\n if (parsed.userId !== undefined) member.userId = parsed.userId ?? null\n if (parsed.teamId !== undefined) member.teamId = parsed.teamId ?? null\n if (parsed.roleIds !== undefined) member.roleIds = nextRoleIds ?? []\n if (parsed.tags !== undefined) member.tags = normalizeStringList(parsed.tags)\n if (parsed.availabilityRuleSetId !== undefined) member.availabilityRuleSetId = parsed.availabilityRuleSetId ?? null\n if (parsed.displayName !== undefined) member.displayName = parsed.displayName\n if (parsed.description !== undefined) member.description = parsed.description ?? null\n if (parsed.isActive !== undefined) member.isActive = parsed.isActive\n member.updatedAt = new Date()\n },\n ], { transaction: true })\n\n const de = (ctx.container.resolve('dataEngine') as DataEngine)\n await setCustomFieldsIfAny({\n dataEngine: de,\n entityId: E.staff.staff_team_member,\n recordId: member.id,\n tenantId: member.tenantId,\n organizationId: member.organizationId,\n values: custom,\n })\n\n await emitCrudSideEffects({\n dataEngine: de,\n action: 'updated',\n entity: member,\n identifiers: {\n id: member.id,\n organizationId: member.organizationId,\n tenantId: member.tenantId,\n },\n events: staffTeamMemberCrudEvents,\n indexer: teamMemberCrudIndexer,\n })\n\n return { memberId: member.id }\n },\n buildLog: async ({ snapshots, ctx }) => {\n const before = snapshots.before as TeamMemberSnapshot | undefined\n if (!before) return null\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const after = await loadTeamMemberSnapshot(em, before.id)\n if (!after) return null\n const customBefore = (snapshots as { customBefore?: CustomFieldSnapshot | null }).customBefore ?? undefined\n const customAfter = await loadTeamMemberCustomSnapshot(em, after)\n const changes = buildChanges(before as unknown as Record<string, unknown>, after as unknown as Record<string, unknown>, [\n 'teamId',\n 'displayName',\n 'description',\n 'userId',\n 'roleIds',\n 'tags',\n 'isActive',\n 'deletedAt',\n ])\n const customChanges = diffCustomFieldChanges(customBefore, customAfter)\n if (Object.keys(customChanges).length) {\n changes.customFields = { from: customBefore ?? null, to: customAfter ?? null }\n }\n const { translate } = await resolveTranslations()\n return {\n actionLabel: translate('staff.audit.teamMembers.update', 'Update team member'),\n resourceKind: 'staff.teamMember',\n resourceId: before.id,\n tenantId: before.tenantId,\n organizationId: before.organizationId,\n snapshotBefore: before,\n snapshotAfter: after,\n changes,\n payload: {\n undo: {\n before,\n after,\n customBefore: customBefore ?? null,\n customAfter,\n } satisfies TeamMemberUndoPayload,\n },\n }\n },\n undo: async ({ logEntry, ctx }) => {\n const payload = extractUndoPayload<TeamMemberUndoPayload>(logEntry)\n const before = payload?.before\n if (!before) return\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const member = await em.findOne(StaffTeamMember, { id: before.id })\n if (!member) return\n member.teamId = before.teamId ?? null\n member.displayName = before.displayName\n member.description = before.description ?? null\n member.userId = before.userId ?? null\n member.roleIds = Array.isArray(before.roleIds) ? before.roleIds : []\n member.tags = Array.isArray(before.tags) ? before.tags : []\n member.isActive = before.isActive\n member.deletedAt = before.deletedAt ? new Date(before.deletedAt) : null\n member.updatedAt = new Date()\n await em.flush()\n\n const de = (ctx.container.resolve('dataEngine') as DataEngine)\n if (payload.customBefore || payload.customAfter) {\n const reset = buildCustomFieldResetMap(payload.customBefore ?? undefined, payload.customAfter ?? undefined)\n await setCustomFieldsIfAny({\n dataEngine: de,\n entityId: E.staff.staff_team_member,\n recordId: member.id,\n tenantId: member.tenantId,\n organizationId: member.organizationId,\n values: reset,\n })\n }\n\n await emitCrudUndoSideEffects({\n dataEngine: de,\n action: 'updated',\n entity: member,\n identifiers: {\n id: member.id,\n organizationId: member.organizationId,\n tenantId: member.tenantId,\n },\n events: staffTeamMemberCrudEvents,\n indexer: teamMemberCrudIndexer,\n })\n },\n}\n\nconst deleteTeamMemberCommand: CommandHandler<{ id?: string }, { memberId: string }> = {\n id: 'staff.team-members.delete',\n async prepare(input, ctx) {\n const id = input?.id\n if (!id) throw new CrudHttpError(400, { error: 'Member id is required.' })\n const em = (ctx.container.resolve('em') as EntityManager)\n const snapshot = await loadTeamMemberSnapshot(em, id)\n if (!snapshot) return {}\n const custom = await loadTeamMemberCustomSnapshot(em, snapshot)\n return { before: snapshot, customBefore: custom }\n },\n async execute(input, ctx) {\n const id = input?.id\n if (!id) throw new CrudHttpError(400, { error: 'Member id is required.' })\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const member = await findOneWithDecryption(\n em,\n StaffTeamMember,\n { id, deletedAt: null },\n undefined,\n { tenantId: ctx.auth?.tenantId ?? null, organizationId: ctx.auth?.orgId ?? null },\n )\n if (!member) throw new CrudHttpError(404, { error: 'Team member not found.' })\n ensureTenantScope(ctx, member.tenantId)\n ensureOrganizationScope(ctx, member.organizationId)\n member.deletedAt = new Date()\n member.updatedAt = new Date()\n await em.flush()\n\n const de = (ctx.container.resolve('dataEngine') as DataEngine)\n await emitCrudSideEffects({\n dataEngine: de,\n action: 'deleted',\n entity: member,\n identifiers: {\n id: member.id,\n organizationId: member.organizationId,\n tenantId: member.tenantId,\n },\n events: staffTeamMemberCrudEvents,\n indexer: teamMemberCrudIndexer,\n })\n\n return { memberId: member.id }\n },\n buildLog: async ({ snapshots }) => {\n const before = snapshots.before as TeamMemberSnapshot | undefined\n if (!before) return null\n const customBefore = (snapshots as { customBefore?: CustomFieldSnapshot | null }).customBefore ?? undefined\n const { translate } = await resolveTranslations()\n return {\n actionLabel: translate('staff.audit.teamMembers.delete', 'Delete team member'),\n resourceKind: 'staff.teamMember',\n resourceId: before.id,\n tenantId: before.tenantId,\n organizationId: before.organizationId,\n snapshotBefore: before,\n payload: {\n undo: {\n before,\n customBefore: customBefore ?? null,\n } satisfies TeamMemberUndoPayload,\n },\n }\n },\n undo: async ({ logEntry, ctx }) => {\n const payload = extractUndoPayload<TeamMemberUndoPayload>(logEntry)\n const before = payload?.before\n if (!before) return\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n let member = await em.findOne(StaffTeamMember, { id: before.id })\n if (!member) {\n member = em.create(StaffTeamMember, {\n id: before.id,\n tenantId: before.tenantId,\n organizationId: before.organizationId,\n teamId: before.teamId ?? null,\n displayName: before.displayName,\n description: before.description ?? null,\n userId: before.userId ?? null,\n roleIds: before.roleIds ?? [],\n tags: before.tags ?? [],\n isActive: before.isActive,\n deletedAt: null,\n createdAt: new Date(),\n updatedAt: new Date(),\n })\n em.persist(member)\n } else {\n member.teamId = before.teamId ?? null\n member.displayName = before.displayName\n member.description = before.description ?? null\n member.userId = before.userId ?? null\n member.roleIds = before.roleIds ?? []\n member.tags = before.tags ?? []\n member.isActive = before.isActive\n member.deletedAt = null\n member.updatedAt = new Date()\n }\n await em.flush()\n\n const de = (ctx.container.resolve('dataEngine') as DataEngine)\n if (payload.customBefore) {\n const reset = buildCustomFieldResetMap(payload.customBefore, undefined)\n await setCustomFieldsIfAny({\n dataEngine: de,\n entityId: E.staff.staff_team_member,\n recordId: member.id,\n tenantId: member.tenantId,\n organizationId: member.organizationId,\n values: reset,\n })\n }\n\n await emitCrudUndoSideEffects({\n dataEngine: de,\n action: 'created',\n entity: member,\n identifiers: {\n id: member.id,\n organizationId: member.organizationId,\n tenantId: member.tenantId,\n },\n events: staffTeamMemberCrudEvents,\n indexer: teamMemberCrudIndexer,\n })\n },\n}\n\nregisterCommand(createTeamMemberCommand)\nregisterCommand(updateTeamMemberCommand)\nregisterCommand(deleteTeamMemberCommand)\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import type { CommandHandler } from '@open-mercato/shared/lib/commands'\nimport { registerCommand } from '@open-mercato/shared/lib/commands'\nimport type { EntityManager } from '@mikro-orm/postgresql'\nimport { CrudHttpError } from '@open-mercato/shared/lib/crud/errors'\nimport { resolveTranslations } from '@open-mercato/shared/lib/i18n/server'\nimport { findOneWithDecryption, findWithDecryption } from '@open-mercato/shared/lib/encryption/find'\nimport { buildChanges, emitCrudSideEffects, emitCrudUndoSideEffects, parseWithCustomFields, setCustomFieldsIfAny } from '@open-mercato/shared/lib/commands/helpers'\nimport { buildCustomFieldResetMap, diffCustomFieldChanges, loadCustomFieldSnapshot, type CustomFieldSnapshot } from '@open-mercato/shared/lib/commands/customFieldSnapshots'\nimport { makeCreateRedo } from '@open-mercato/shared/lib/commands/redo'\nimport { withAtomicFlush } from '@open-mercato/shared/lib/commands/flush'\nimport type { DataEngine } from '@open-mercato/shared/lib/data/engine'\nimport type { CrudIndexerConfig } from '@open-mercato/shared/lib/crud/types'\nimport { User } from '@open-mercato/core/modules/auth/data/entities'\nimport { StaffTeam, StaffTeamMember, StaffTeamRole } from '../data/entities'\nimport {\n staffTeamMemberCreateSchema,\n staffTeamMemberUpdateSchema,\n type StaffTeamMemberCreateInput,\n type StaffTeamMemberUpdateInput,\n} from '../data/validators'\nimport { staffTeamMemberCrudEvents } from '../lib/crud'\nimport { ensureOrganizationScope, ensureTenantScope, extractUndoPayload } from './shared'\nimport { E } from '#generated/entities.ids.generated'\n\nconst teamMemberCrudIndexer: CrudIndexerConfig<StaffTeamMember> = {\n entityType: E.staff.staff_team_member,\n}\n\ntype TeamMemberSnapshot = {\n id: string\n tenantId: string\n organizationId: string\n teamId: string | null\n displayName: string\n description: string | null\n userId: string | null\n roleIds: string[]\n tags: string[]\n isActive: boolean\n deletedAt: string | null\n}\n\ntype TeamMemberUndoPayload = {\n before?: TeamMemberSnapshot | null\n after?: TeamMemberSnapshot | null\n customBefore?: CustomFieldSnapshot | null\n customAfter?: CustomFieldSnapshot | null\n}\n\nfunction normalizeStringList(value: unknown): string[] {\n if (!Array.isArray(value)) return []\n const set = new Set<string>()\n value.forEach((entry) => {\n if (typeof entry === 'string') {\n const trimmed = entry.trim()\n if (trimmed.length) set.add(trimmed)\n }\n })\n return Array.from(set)\n}\n\nasync function loadTeamMemberSnapshot(em: EntityManager, id: string): Promise<TeamMemberSnapshot | null> {\n const member = await findOneWithDecryption(em, StaffTeamMember, { id }, undefined, { tenantId: null, organizationId: null })\n if (!member) return null\n return {\n id: member.id,\n tenantId: member.tenantId,\n organizationId: member.organizationId,\n teamId: member.teamId ?? null,\n displayName: member.displayName,\n description: member.description ?? null,\n userId: member.userId ?? null,\n roleIds: Array.isArray(member.roleIds) ? member.roleIds : [],\n tags: Array.isArray(member.tags) ? member.tags : [],\n isActive: member.isActive ?? true,\n deletedAt: member.deletedAt ? member.deletedAt.toISOString() : null,\n }\n}\n\nasync function loadTeamMemberCustomSnapshot(\n em: EntityManager,\n snapshot: TeamMemberSnapshot,\n): Promise<CustomFieldSnapshot> {\n return loadCustomFieldSnapshot(em, {\n entityId: E.staff.staff_team_member,\n recordId: snapshot.id,\n tenantId: snapshot.tenantId,\n organizationId: snapshot.organizationId,\n })\n}\n\nfunction teamMemberSeedFromSnapshot(snapshot: TeamMemberSnapshot): Record<string, unknown> {\n return {\n id: snapshot.id,\n tenantId: snapshot.tenantId,\n organizationId: snapshot.organizationId,\n teamId: snapshot.teamId ?? null,\n displayName: snapshot.displayName,\n description: snapshot.description ?? null,\n userId: snapshot.userId ?? null,\n roleIds: Array.isArray(snapshot.roleIds) ? snapshot.roleIds : [],\n tags: Array.isArray(snapshot.tags) ? snapshot.tags : [],\n availabilityRuleSetId: null,\n isActive: snapshot.isActive,\n createdAt: new Date(),\n updatedAt: new Date(),\n deletedAt: null,\n }\n}\n\nconst redoTeamMemberCreate = makeCreateRedo<StaffTeamMember, TeamMemberSnapshot, StaffTeamMemberCreateInput, { memberId: string }>({\n entityClass: StaffTeamMember,\n getSnapshotId: (snapshot) => snapshot.id,\n seedFromSnapshot: teamMemberSeedFromSnapshot,\n buildResult: (entity) => ({ memberId: entity.id }),\n events: staffTeamMemberCrudEvents,\n indexer: teamMemberCrudIndexer,\n})\n\nasync function ensureRolesExist(em: EntityManager, roleIds: string[], tenantId: string, organizationId: string): Promise<void> {\n if (!roleIds.length) return\n const roles = await findWithDecryption(\n em,\n StaffTeamRole,\n { id: { $in: roleIds }, tenantId, organizationId, deletedAt: null },\n undefined,\n { tenantId, organizationId },\n )\n if (roles.length !== roleIds.length) {\n throw new CrudHttpError(400, { error: 'One or more team roles were not found.' })\n }\n}\n\nasync function ensureUserExists(em: EntityManager, userId: string, tenantId: string, organizationId: string): Promise<void> {\n const user = await findOneWithDecryption(\n em,\n User,\n { id: userId, deletedAt: null },\n undefined,\n { tenantId, organizationId },\n )\n if (!user) throw new CrudHttpError(400, { error: 'User not found.' })\n if (user.tenantId && user.tenantId !== tenantId) {\n throw new CrudHttpError(400, { error: 'User does not belong to this tenant.' })\n }\n if (user.organizationId && user.organizationId !== organizationId) {\n throw new CrudHttpError(400, { error: 'User does not belong to this organization.' })\n }\n}\n\nasync function ensureTeamExists(em: EntityManager, teamId: string, tenantId: string, organizationId: string): Promise<void> {\n const team = await findOneWithDecryption(\n em,\n StaffTeam,\n { id: teamId, tenantId, organizationId, deletedAt: null },\n undefined,\n { tenantId, organizationId },\n )\n if (!team) throw new CrudHttpError(400, { error: 'Team not found.' })\n}\n\nconst createTeamMemberCommand: CommandHandler<StaffTeamMemberCreateInput, { memberId: string }> = {\n id: 'staff.team-members.create',\n async execute(rawInput, ctx) {\n const { parsed, custom } = parseWithCustomFields(staffTeamMemberCreateSchema, rawInput)\n ensureTenantScope(ctx, parsed.tenantId)\n ensureOrganizationScope(ctx, parsed.organizationId)\n\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const roleIds = normalizeStringList(parsed.roleIds)\n const tags = normalizeStringList(parsed.tags)\n if (parsed.userId) {\n await ensureUserExists(em, parsed.userId, parsed.tenantId, parsed.organizationId)\n }\n if (parsed.teamId) {\n await ensureTeamExists(em, parsed.teamId, parsed.tenantId, parsed.organizationId)\n }\n await ensureRolesExist(em, roleIds, parsed.tenantId, parsed.organizationId)\n\n const now = new Date()\n const member = em.create(StaffTeamMember, {\n tenantId: parsed.tenantId,\n organizationId: parsed.organizationId,\n teamId: parsed.teamId ?? null,\n displayName: parsed.displayName,\n description: parsed.description ?? null,\n userId: parsed.userId ?? null,\n roleIds,\n tags,\n availabilityRuleSetId: parsed.availabilityRuleSetId ?? null,\n isActive: parsed.isActive ?? true,\n createdAt: now,\n updatedAt: now,\n deletedAt: null,\n })\n em.persist(member)\n await em.flush()\n\n const de = (ctx.container.resolve('dataEngine') as DataEngine)\n await setCustomFieldsIfAny({\n dataEngine: de,\n entityId: E.staff.staff_team_member,\n recordId: member.id,\n tenantId: member.tenantId,\n organizationId: member.organizationId,\n values: custom,\n })\n\n await emitCrudSideEffects({\n dataEngine: de,\n action: 'created',\n entity: member,\n identifiers: {\n id: member.id,\n organizationId: member.organizationId,\n tenantId: member.tenantId,\n },\n events: staffTeamMemberCrudEvents,\n indexer: teamMemberCrudIndexer,\n })\n\n return { memberId: member.id }\n },\n captureAfter: async (_input, result, ctx) => {\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const snapshot = await loadTeamMemberSnapshot(em, result.memberId)\n if (!snapshot) return null\n const custom = await loadTeamMemberCustomSnapshot(em, snapshot)\n return { snapshot, custom }\n },\n buildLog: async ({ result, ctx }) => {\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const snapshot = await loadTeamMemberSnapshot(em, result.memberId)\n if (!snapshot) return null\n const custom = await loadTeamMemberCustomSnapshot(em, snapshot)\n const { translate } = await resolveTranslations()\n return {\n actionLabel: translate('staff.audit.teamMembers.create', 'Create team member'),\n resourceKind: 'staff.teamMember',\n resourceId: snapshot.id,\n tenantId: snapshot.tenantId,\n organizationId: snapshot.organizationId,\n snapshotAfter: snapshot,\n payload: {\n undo: {\n after: snapshot,\n customAfter: custom,\n } satisfies TeamMemberUndoPayload,\n },\n }\n },\n undo: async ({ logEntry, ctx }) => {\n const payload = extractUndoPayload<TeamMemberUndoPayload>(logEntry)\n const after = payload?.after\n if (!after) return\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const member = await em.findOne(StaffTeamMember, { id: after.id })\n if (member) {\n member.deletedAt = new Date()\n await em.flush()\n\n const de = (ctx.container.resolve('dataEngine') as DataEngine)\n await emitCrudUndoSideEffects({\n dataEngine: de,\n action: 'deleted',\n entity: member,\n identifiers: {\n id: member.id,\n organizationId: member.organizationId,\n tenantId: member.tenantId,\n },\n events: staffTeamMemberCrudEvents,\n indexer: teamMemberCrudIndexer,\n })\n }\n },\n redo: async ({ logEntry, ctx }) => {\n const result = await redoTeamMemberCreate({ input: undefined as unknown as StaffTeamMemberCreateInput, ctx, logEntry })\n const payload = extractUndoPayload<TeamMemberUndoPayload>(logEntry)\n const customAfter = payload?.customAfter\n if (customAfter && Object.keys(customAfter).length) {\n await setCustomFieldsIfAny({\n dataEngine: ctx.container.resolve('dataEngine') as DataEngine,\n entityId: E.staff.staff_team_member,\n recordId: result.memberId,\n tenantId: payload?.after?.tenantId ?? '',\n organizationId: payload?.after?.organizationId ?? '',\n values: customAfter,\n })\n }\n return result\n },\n}\n\nconst updateTeamMemberCommand: CommandHandler<StaffTeamMemberUpdateInput, { memberId: string; updatedAt: string | null }> = {\n id: 'staff.team-members.update',\n async prepare(rawInput, ctx) {\n const { parsed } = parseWithCustomFields(staffTeamMemberUpdateSchema, rawInput)\n const em = (ctx.container.resolve('em') as EntityManager)\n const snapshot = await loadTeamMemberSnapshot(em, parsed.id)\n if (!snapshot) return {}\n const custom = await loadTeamMemberCustomSnapshot(em, snapshot)\n return { before: snapshot, customBefore: custom }\n },\n async execute(rawInput, ctx) {\n const { parsed, custom } = parseWithCustomFields(staffTeamMemberUpdateSchema, rawInput)\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const member = await findOneWithDecryption(\n em,\n StaffTeamMember,\n { id: parsed.id, deletedAt: null },\n undefined,\n { tenantId: ctx.auth?.tenantId ?? null, organizationId: ctx.auth?.orgId ?? null },\n )\n if (!member) throw new CrudHttpError(404, { error: 'Team member not found.' })\n ensureTenantScope(ctx, member.tenantId)\n ensureOrganizationScope(ctx, member.organizationId)\n\n // Resolve validation queries BEFORE mutating scalars: `ensure*` runs `em.find`,\n // which would otherwise reset unit-of-work tracking between mutations and the\n // flush and silently drop earlier scalar changes (SPEC-018 Problem 1).\n if (parsed.userId !== undefined && parsed.userId) {\n await ensureUserExists(em, parsed.userId, member.tenantId, member.organizationId)\n }\n if (parsed.teamId !== undefined && parsed.teamId) {\n await ensureTeamExists(em, parsed.teamId, member.tenantId, member.organizationId)\n }\n let nextRoleIds: string[] | undefined\n if (parsed.roleIds !== undefined) {\n nextRoleIds = normalizeStringList(parsed.roleIds)\n await ensureRolesExist(em, nextRoleIds, member.tenantId, member.organizationId)\n }\n\n await withAtomicFlush(em, [\n () => {\n if (parsed.userId !== undefined) member.userId = parsed.userId ?? null\n if (parsed.teamId !== undefined) member.teamId = parsed.teamId ?? null\n if (parsed.roleIds !== undefined) member.roleIds = nextRoleIds ?? []\n if (parsed.tags !== undefined) member.tags = normalizeStringList(parsed.tags)\n if (parsed.availabilityRuleSetId !== undefined) member.availabilityRuleSetId = parsed.availabilityRuleSetId ?? null\n if (parsed.displayName !== undefined) member.displayName = parsed.displayName\n if (parsed.description !== undefined) member.description = parsed.description ?? null\n if (parsed.isActive !== undefined) member.isActive = parsed.isActive\n member.updatedAt = new Date()\n },\n ], { transaction: true })\n\n const de = (ctx.container.resolve('dataEngine') as DataEngine)\n await setCustomFieldsIfAny({\n dataEngine: de,\n entityId: E.staff.staff_team_member,\n recordId: member.id,\n tenantId: member.tenantId,\n organizationId: member.organizationId,\n values: custom,\n })\n\n await emitCrudSideEffects({\n dataEngine: de,\n action: 'updated',\n entity: member,\n identifiers: {\n id: member.id,\n organizationId: member.organizationId,\n tenantId: member.tenantId,\n },\n events: staffTeamMemberCrudEvents,\n indexer: teamMemberCrudIndexer,\n })\n\n // Return the freshly-bumped updatedAt so non-CrudForm callers (e.g. the\n // availability schedule switcher) can refresh their optimistic-lock token\n // and not falsely 409 on the next sequential edit (#2848).\n return { memberId: member.id, updatedAt: member.updatedAt ? member.updatedAt.toISOString() : null }\n },\n buildLog: async ({ snapshots, ctx }) => {\n const before = snapshots.before as TeamMemberSnapshot | undefined\n if (!before) return null\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const after = await loadTeamMemberSnapshot(em, before.id)\n if (!after) return null\n const customBefore = (snapshots as { customBefore?: CustomFieldSnapshot | null }).customBefore ?? undefined\n const customAfter = await loadTeamMemberCustomSnapshot(em, after)\n const changes = buildChanges(before as unknown as Record<string, unknown>, after as unknown as Record<string, unknown>, [\n 'teamId',\n 'displayName',\n 'description',\n 'userId',\n 'roleIds',\n 'tags',\n 'isActive',\n 'deletedAt',\n ])\n const customChanges = diffCustomFieldChanges(customBefore, customAfter)\n if (Object.keys(customChanges).length) {\n changes.customFields = { from: customBefore ?? null, to: customAfter ?? null }\n }\n const { translate } = await resolveTranslations()\n return {\n actionLabel: translate('staff.audit.teamMembers.update', 'Update team member'),\n resourceKind: 'staff.teamMember',\n resourceId: before.id,\n tenantId: before.tenantId,\n organizationId: before.organizationId,\n snapshotBefore: before,\n snapshotAfter: after,\n changes,\n payload: {\n undo: {\n before,\n after,\n customBefore: customBefore ?? null,\n customAfter,\n } satisfies TeamMemberUndoPayload,\n },\n }\n },\n undo: async ({ logEntry, ctx }) => {\n const payload = extractUndoPayload<TeamMemberUndoPayload>(logEntry)\n const before = payload?.before\n if (!before) return\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const member = await em.findOne(StaffTeamMember, { id: before.id })\n if (!member) return\n member.teamId = before.teamId ?? null\n member.displayName = before.displayName\n member.description = before.description ?? null\n member.userId = before.userId ?? null\n member.roleIds = Array.isArray(before.roleIds) ? before.roleIds : []\n member.tags = Array.isArray(before.tags) ? before.tags : []\n member.isActive = before.isActive\n member.deletedAt = before.deletedAt ? new Date(before.deletedAt) : null\n member.updatedAt = new Date()\n await em.flush()\n\n const de = (ctx.container.resolve('dataEngine') as DataEngine)\n if (payload.customBefore || payload.customAfter) {\n const reset = buildCustomFieldResetMap(payload.customBefore ?? undefined, payload.customAfter ?? undefined)\n await setCustomFieldsIfAny({\n dataEngine: de,\n entityId: E.staff.staff_team_member,\n recordId: member.id,\n tenantId: member.tenantId,\n organizationId: member.organizationId,\n values: reset,\n })\n }\n\n await emitCrudUndoSideEffects({\n dataEngine: de,\n action: 'updated',\n entity: member,\n identifiers: {\n id: member.id,\n organizationId: member.organizationId,\n tenantId: member.tenantId,\n },\n events: staffTeamMemberCrudEvents,\n indexer: teamMemberCrudIndexer,\n })\n },\n}\n\nconst deleteTeamMemberCommand: CommandHandler<{ id?: string }, { memberId: string }> = {\n id: 'staff.team-members.delete',\n async prepare(input, ctx) {\n const id = input?.id\n if (!id) throw new CrudHttpError(400, { error: 'Member id is required.' })\n const em = (ctx.container.resolve('em') as EntityManager)\n const snapshot = await loadTeamMemberSnapshot(em, id)\n if (!snapshot) return {}\n const custom = await loadTeamMemberCustomSnapshot(em, snapshot)\n return { before: snapshot, customBefore: custom }\n },\n async execute(input, ctx) {\n const id = input?.id\n if (!id) throw new CrudHttpError(400, { error: 'Member id is required.' })\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const member = await findOneWithDecryption(\n em,\n StaffTeamMember,\n { id, deletedAt: null },\n undefined,\n { tenantId: ctx.auth?.tenantId ?? null, organizationId: ctx.auth?.orgId ?? null },\n )\n if (!member) throw new CrudHttpError(404, { error: 'Team member not found.' })\n ensureTenantScope(ctx, member.tenantId)\n ensureOrganizationScope(ctx, member.organizationId)\n member.deletedAt = new Date()\n member.updatedAt = new Date()\n await em.flush()\n\n const de = (ctx.container.resolve('dataEngine') as DataEngine)\n await emitCrudSideEffects({\n dataEngine: de,\n action: 'deleted',\n entity: member,\n identifiers: {\n id: member.id,\n organizationId: member.organizationId,\n tenantId: member.tenantId,\n },\n events: staffTeamMemberCrudEvents,\n indexer: teamMemberCrudIndexer,\n })\n\n return { memberId: member.id }\n },\n buildLog: async ({ snapshots }) => {\n const before = snapshots.before as TeamMemberSnapshot | undefined\n if (!before) return null\n const customBefore = (snapshots as { customBefore?: CustomFieldSnapshot | null }).customBefore ?? undefined\n const { translate } = await resolveTranslations()\n return {\n actionLabel: translate('staff.audit.teamMembers.delete', 'Delete team member'),\n resourceKind: 'staff.teamMember',\n resourceId: before.id,\n tenantId: before.tenantId,\n organizationId: before.organizationId,\n snapshotBefore: before,\n payload: {\n undo: {\n before,\n customBefore: customBefore ?? null,\n } satisfies TeamMemberUndoPayload,\n },\n }\n },\n undo: async ({ logEntry, ctx }) => {\n const payload = extractUndoPayload<TeamMemberUndoPayload>(logEntry)\n const before = payload?.before\n if (!before) return\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n let member = await em.findOne(StaffTeamMember, { id: before.id })\n if (!member) {\n member = em.create(StaffTeamMember, {\n id: before.id,\n tenantId: before.tenantId,\n organizationId: before.organizationId,\n teamId: before.teamId ?? null,\n displayName: before.displayName,\n description: before.description ?? null,\n userId: before.userId ?? null,\n roleIds: before.roleIds ?? [],\n tags: before.tags ?? [],\n isActive: before.isActive,\n deletedAt: null,\n createdAt: new Date(),\n updatedAt: new Date(),\n })\n em.persist(member)\n } else {\n member.teamId = before.teamId ?? null\n member.displayName = before.displayName\n member.description = before.description ?? null\n member.userId = before.userId ?? null\n member.roleIds = before.roleIds ?? []\n member.tags = before.tags ?? []\n member.isActive = before.isActive\n member.deletedAt = null\n member.updatedAt = new Date()\n }\n await em.flush()\n\n const de = (ctx.container.resolve('dataEngine') as DataEngine)\n if (payload.customBefore) {\n const reset = buildCustomFieldResetMap(payload.customBefore, undefined)\n await setCustomFieldsIfAny({\n dataEngine: de,\n entityId: E.staff.staff_team_member,\n recordId: member.id,\n tenantId: member.tenantId,\n organizationId: member.organizationId,\n values: reset,\n })\n }\n\n await emitCrudUndoSideEffects({\n dataEngine: de,\n action: 'created',\n entity: member,\n identifiers: {\n id: member.id,\n organizationId: member.organizationId,\n tenantId: member.tenantId,\n },\n events: staffTeamMemberCrudEvents,\n indexer: teamMemberCrudIndexer,\n })\n },\n}\n\nregisterCommand(createTeamMemberCommand)\nregisterCommand(updateTeamMemberCommand)\nregisterCommand(deleteTeamMemberCommand)\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -366,7 +366,7 @@ function TeamMemberForm(props) {
366
366
  if (!tagsSection) {
367
367
  baseFields.splice(5, 0, {
368
368
  id: "tags",
369
- label: translate("staff.teamMembers.form.fields.tags", "Tags"),
369
+ label: "",
370
370
  type: "tags",
371
371
  placeholder: translate("staff.teamMembers.form.fields.tags.placeholder", "Add tags")
372
372
  });