@open-mercato/core 0.6.1-develop.3260.1.dc719cac84 → 0.6.1-develop.3278.1.a4d26475e4

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 (212) hide show
  1. package/.turbo/turbo-build.log +2 -2
  2. package/dist/generated/entities/domain_mapping/index.js +31 -0
  3. package/dist/generated/entities/domain_mapping/index.js.map +7 -0
  4. package/dist/generated/entities.ids.generated.js +2 -1
  5. package/dist/generated/entities.ids.generated.js.map +2 -2
  6. package/dist/generated/entity-fields-registry.js +16 -0
  7. package/dist/generated/entity-fields-registry.js.map +2 -2
  8. package/dist/helpers/integration/salesUi.js +18 -17
  9. package/dist/helpers/integration/salesUi.js.map +2 -2
  10. package/dist/modules/customer_accounts/acl.js +2 -1
  11. package/dist/modules/customer_accounts/acl.js.map +2 -2
  12. package/dist/modules/customer_accounts/api/admin/domain-mappings/[id]/health-check.js +110 -0
  13. package/dist/modules/customer_accounts/api/admin/domain-mappings/[id]/health-check.js.map +7 -0
  14. package/dist/modules/customer_accounts/api/admin/domain-mappings/[id]/verify.js +114 -0
  15. package/dist/modules/customer_accounts/api/admin/domain-mappings/[id]/verify.js.map +7 -0
  16. package/dist/modules/customer_accounts/api/admin/domain-mappings.js +271 -0
  17. package/dist/modules/customer_accounts/api/admin/domain-mappings.js.map +7 -0
  18. package/dist/modules/customer_accounts/api/domain-check.js +70 -0
  19. package/dist/modules/customer_accounts/api/domain-check.js.map +7 -0
  20. package/dist/modules/customer_accounts/api/domain-resolve/all.js +128 -0
  21. package/dist/modules/customer_accounts/api/domain-resolve/all.js.map +7 -0
  22. package/dist/modules/customer_accounts/api/domain-resolve.js +84 -0
  23. package/dist/modules/customer_accounts/api/domain-resolve.js.map +7 -0
  24. package/dist/modules/customer_accounts/api/login.js +14 -3
  25. package/dist/modules/customer_accounts/api/login.js.map +2 -2
  26. package/dist/modules/customer_accounts/api/magic-link/request.js +14 -3
  27. package/dist/modules/customer_accounts/api/magic-link/request.js.map +2 -2
  28. package/dist/modules/customer_accounts/api/password/reset-request.js +14 -3
  29. package/dist/modules/customer_accounts/api/password/reset-request.js.map +2 -2
  30. package/dist/modules/customer_accounts/api/signup.js +32 -5
  31. package/dist/modules/customer_accounts/api/signup.js.map +2 -2
  32. package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/components/Actions.js +48 -0
  33. package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/components/Actions.js.map +7 -0
  34. package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/components/Diagnostics.js +43 -0
  35. package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/components/Diagnostics.js.map +7 -0
  36. package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/components/DnsConfig.js +53 -0
  37. package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/components/DnsConfig.js.map +7 -0
  38. package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/components/DomainPanel.js +69 -0
  39. package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/components/DomainPanel.js.map +7 -0
  40. package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/components/OrgSwitcher.js +31 -0
  41. package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/components/OrgSwitcher.js.map +7 -0
  42. package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/components/RegisterDialog.js +147 -0
  43. package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/components/RegisterDialog.js.map +7 -0
  44. package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/components/StatusBadgeSection.js +39 -0
  45. package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/components/StatusBadgeSection.js.map +7 -0
  46. package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/components/Stepper.js +60 -0
  47. package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/components/Stepper.js.map +7 -0
  48. package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/components/domainStatusMap.js +11 -0
  49. package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/components/domainStatusMap.js.map +7 -0
  50. package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/components/types.js +1 -0
  51. package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/components/types.js.map +7 -0
  52. package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/page.js +361 -0
  53. package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/page.js.map +7 -0
  54. package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/page.meta.js +28 -0
  55. package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/page.meta.js.map +7 -0
  56. package/dist/modules/customer_accounts/data/enrichers.js +78 -12
  57. package/dist/modules/customer_accounts/data/enrichers.js.map +2 -2
  58. package/dist/modules/customer_accounts/data/entities.js +85 -2
  59. package/dist/modules/customer_accounts/data/entities.js.map +2 -2
  60. package/dist/modules/customer_accounts/data/guards.js +130 -0
  61. package/dist/modules/customer_accounts/data/guards.js.map +7 -0
  62. package/dist/modules/customer_accounts/data/validators.js +19 -0
  63. package/dist/modules/customer_accounts/data/validators.js.map +2 -2
  64. package/dist/modules/customer_accounts/di.js +23 -1
  65. package/dist/modules/customer_accounts/di.js.map +2 -2
  66. package/dist/modules/customer_accounts/events.js +9 -2
  67. package/dist/modules/customer_accounts/events.js.map +2 -2
  68. package/dist/modules/customer_accounts/lib/customerAuthServer.js +27 -7
  69. package/dist/modules/customer_accounts/lib/customerAuthServer.js.map +2 -2
  70. package/dist/modules/customer_accounts/lib/customerUrl.js +48 -0
  71. package/dist/modules/customer_accounts/lib/customerUrl.js.map +7 -0
  72. package/dist/modules/customer_accounts/lib/hostname.js +55 -0
  73. package/dist/modules/customer_accounts/lib/hostname.js.map +7 -0
  74. package/dist/modules/customer_accounts/lib/platformDomains.js +7 -0
  75. package/dist/modules/customer_accounts/lib/platformDomains.js.map +7 -0
  76. package/dist/modules/customer_accounts/lib/proxyRanges.js +71 -0
  77. package/dist/modules/customer_accounts/lib/proxyRanges.js.map +7 -0
  78. package/dist/modules/customer_accounts/lib/rateLimiter.js +7 -0
  79. package/dist/modules/customer_accounts/lib/rateLimiter.js.map +2 -2
  80. package/dist/modules/customer_accounts/lib/resolveTenantContext.js +63 -0
  81. package/dist/modules/customer_accounts/lib/resolveTenantContext.js.map +7 -0
  82. package/dist/modules/customer_accounts/lib/secretCompare.js +13 -0
  83. package/dist/modules/customer_accounts/lib/secretCompare.js.map +7 -0
  84. package/dist/modules/customer_accounts/migrations/Migration20260430120000_customer_accounts.js +37 -0
  85. package/dist/modules/customer_accounts/migrations/Migration20260430120000_customer_accounts.js.map +7 -0
  86. package/dist/modules/customer_accounts/notifications.client.js +76 -0
  87. package/dist/modules/customer_accounts/notifications.client.js.map +2 -2
  88. package/dist/modules/customer_accounts/notifications.js +76 -0
  89. package/dist/modules/customer_accounts/notifications.js.map +2 -2
  90. package/dist/modules/customer_accounts/services/domainMappingService.js +497 -0
  91. package/dist/modules/customer_accounts/services/domainMappingService.js.map +7 -0
  92. package/dist/modules/customer_accounts/setup.js +48 -1
  93. package/dist/modules/customer_accounts/setup.js.map +2 -2
  94. package/dist/modules/customer_accounts/subscribers/invalidateDomainCache.js +29 -0
  95. package/dist/modules/customer_accounts/subscribers/invalidateDomainCache.js.map +7 -0
  96. package/dist/modules/customer_accounts/subscribers/notifyDomainActivated.js +29 -0
  97. package/dist/modules/customer_accounts/subscribers/notifyDomainActivated.js.map +7 -0
  98. package/dist/modules/customer_accounts/subscribers/notifyDomainDnsFailed.js +30 -0
  99. package/dist/modules/customer_accounts/subscribers/notifyDomainDnsFailed.js.map +7 -0
  100. package/dist/modules/customer_accounts/subscribers/notifyDomainTlsFailed.js +31 -0
  101. package/dist/modules/customer_accounts/subscribers/notifyDomainTlsFailed.js.map +7 -0
  102. package/dist/modules/customer_accounts/subscribers/notifyDomainVerified.js +29 -0
  103. package/dist/modules/customer_accounts/subscribers/notifyDomainVerified.js.map +7 -0
  104. package/dist/modules/customer_accounts/workers/domainTlsRetryWorker.js +67 -0
  105. package/dist/modules/customer_accounts/workers/domainTlsRetryWorker.js.map +7 -0
  106. package/dist/modules/customer_accounts/workers/domainVerificationWorker.js +34 -0
  107. package/dist/modules/customer_accounts/workers/domainVerificationWorker.js.map +7 -0
  108. package/dist/modules/customers/api/companies/route.js +4 -9
  109. package/dist/modules/customers/api/companies/route.js.map +2 -2
  110. package/dist/modules/customers/api/deals/route.js +4 -9
  111. package/dist/modules/customers/api/deals/route.js.map +2 -2
  112. package/dist/modules/customers/api/people/route.js +4 -9
  113. package/dist/modules/customers/api/people/route.js.map +2 -2
  114. package/dist/modules/customers/api/utils.js +0 -12
  115. package/dist/modules/customers/api/utils.js.map +2 -2
  116. package/dist/modules/customers/backend/customers/companies/page.js +361 -284
  117. package/dist/modules/customers/backend/customers/companies/page.js.map +2 -2
  118. package/dist/modules/customers/backend/customers/deals/page.js +378 -473
  119. package/dist/modules/customers/backend/customers/deals/page.js.map +2 -2
  120. package/dist/modules/customers/backend/customers/people/page.js +368 -286
  121. package/dist/modules/customers/backend/customers/people/page.js.map +2 -2
  122. package/dist/modules/customers/components/detail/assignableStaff.js +15 -1
  123. package/dist/modules/customers/components/detail/assignableStaff.js.map +2 -2
  124. package/dist/modules/customers/widgets/injection/ai-assistant-trigger/widget.client.js +188 -36
  125. package/dist/modules/customers/widgets/injection/ai-assistant-trigger/widget.client.js.map +2 -2
  126. package/dist/modules/customers/widgets/injection/ai-assistant-trigger/widget.js +2 -2
  127. package/dist/modules/customers/widgets/injection/ai-assistant-trigger/widget.js.map +2 -2
  128. package/dist/modules/customers/widgets/injection-table.js +6 -0
  129. package/dist/modules/customers/widgets/injection-table.js.map +2 -2
  130. package/dist/modules/perspectives/services/perspectiveService.js +16 -2
  131. package/dist/modules/perspectives/services/perspectiveService.js.map +2 -2
  132. package/dist/modules/portal/frontend/[orgSlug]/portal/login/page.js +1 -0
  133. package/dist/modules/portal/frontend/[orgSlug]/portal/login/page.js.map +2 -2
  134. package/dist/modules/query_index/lib/engine.js +31 -8
  135. package/dist/modules/query_index/lib/engine.js.map +2 -2
  136. package/generated/entities/domain_mapping/index.ts +14 -0
  137. package/generated/entities.ids.generated.ts +2 -1
  138. package/generated/entity-fields-registry.ts +16 -0
  139. package/package.json +5 -5
  140. package/src/helpers/integration/salesUi.ts +27 -23
  141. package/src/modules/customer_accounts/acl.ts +1 -0
  142. package/src/modules/customer_accounts/api/admin/domain-mappings/[id]/health-check.ts +119 -0
  143. package/src/modules/customer_accounts/api/admin/domain-mappings/[id]/verify.ts +123 -0
  144. package/src/modules/customer_accounts/api/admin/domain-mappings.ts +303 -0
  145. package/src/modules/customer_accounts/api/domain-check.ts +83 -0
  146. package/src/modules/customer_accounts/api/domain-resolve/all.ts +139 -0
  147. package/src/modules/customer_accounts/api/domain-resolve.ts +91 -0
  148. package/src/modules/customer_accounts/api/login.ts +14 -3
  149. package/src/modules/customer_accounts/api/magic-link/request.ts +14 -3
  150. package/src/modules/customer_accounts/api/password/reset-request.ts +15 -3
  151. package/src/modules/customer_accounts/api/signup.ts +36 -5
  152. package/src/modules/customer_accounts/backend/customer_accounts/settings/domain/components/Actions.tsx +70 -0
  153. package/src/modules/customer_accounts/backend/customer_accounts/settings/domain/components/Diagnostics.tsx +66 -0
  154. package/src/modules/customer_accounts/backend/customer_accounts/settings/domain/components/DnsConfig.tsx +78 -0
  155. package/src/modules/customer_accounts/backend/customer_accounts/settings/domain/components/DomainPanel.tsx +90 -0
  156. package/src/modules/customer_accounts/backend/customer_accounts/settings/domain/components/OrgSwitcher.tsx +43 -0
  157. package/src/modules/customer_accounts/backend/customer_accounts/settings/domain/components/RegisterDialog.tsx +178 -0
  158. package/src/modules/customer_accounts/backend/customer_accounts/settings/domain/components/StatusBadgeSection.tsx +56 -0
  159. package/src/modules/customer_accounts/backend/customer_accounts/settings/domain/components/Stepper.tsx +69 -0
  160. package/src/modules/customer_accounts/backend/customer_accounts/settings/domain/components/domainStatusMap.ts +10 -0
  161. package/src/modules/customer_accounts/backend/customer_accounts/settings/domain/components/types.ts +31 -0
  162. package/src/modules/customer_accounts/backend/customer_accounts/settings/domain/page.meta.ts +26 -0
  163. package/src/modules/customer_accounts/backend/customer_accounts/settings/domain/page.tsx +411 -0
  164. package/src/modules/customer_accounts/data/enrichers.ts +95 -12
  165. package/src/modules/customer_accounts/data/entities.ts +80 -1
  166. package/src/modules/customer_accounts/data/guards.ts +155 -0
  167. package/src/modules/customer_accounts/data/validators.ts +26 -0
  168. package/src/modules/customer_accounts/di.ts +35 -1
  169. package/src/modules/customer_accounts/events.ts +8 -1
  170. package/src/modules/customer_accounts/i18n/de.json +78 -0
  171. package/src/modules/customer_accounts/i18n/en.json +78 -0
  172. package/src/modules/customer_accounts/i18n/es.json +78 -0
  173. package/src/modules/customer_accounts/i18n/pl.json +78 -0
  174. package/src/modules/customer_accounts/lib/customerAuthServer.ts +44 -8
  175. package/src/modules/customer_accounts/lib/customerUrl.ts +72 -0
  176. package/src/modules/customer_accounts/lib/hostname.ts +76 -0
  177. package/src/modules/customer_accounts/lib/platformDomains.ts +14 -0
  178. package/src/modules/customer_accounts/lib/proxyRanges.ts +85 -0
  179. package/src/modules/customer_accounts/lib/rateLimiter.ts +10 -0
  180. package/src/modules/customer_accounts/lib/resolveTenantContext.ts +96 -0
  181. package/src/modules/customer_accounts/lib/secretCompare.ts +20 -0
  182. package/src/modules/customer_accounts/migrations/.snapshot-open-mercato.json +341 -0
  183. package/src/modules/customer_accounts/migrations/Migration20260430120000_customer_accounts.ts +38 -0
  184. package/src/modules/customer_accounts/notifications.client.ts +76 -0
  185. package/src/modules/customer_accounts/notifications.ts +76 -0
  186. package/src/modules/customer_accounts/services/domainMappingService.ts +632 -0
  187. package/src/modules/customer_accounts/setup.ts +81 -1
  188. package/src/modules/customer_accounts/subscribers/invalidateDomainCache.ts +35 -0
  189. package/src/modules/customer_accounts/subscribers/notifyDomainActivated.ts +32 -0
  190. package/src/modules/customer_accounts/subscribers/notifyDomainDnsFailed.ts +33 -0
  191. package/src/modules/customer_accounts/subscribers/notifyDomainTlsFailed.ts +34 -0
  192. package/src/modules/customer_accounts/subscribers/notifyDomainVerified.ts +32 -0
  193. package/src/modules/customer_accounts/workers/domainTlsRetryWorker.ts +84 -0
  194. package/src/modules/customer_accounts/workers/domainVerificationWorker.ts +45 -0
  195. package/src/modules/customers/api/companies/route.ts +4 -9
  196. package/src/modules/customers/api/deals/route.ts +4 -9
  197. package/src/modules/customers/api/people/route.ts +4 -9
  198. package/src/modules/customers/api/utils.ts +0 -14
  199. package/src/modules/customers/backend/customers/companies/page.tsx +321 -237
  200. package/src/modules/customers/backend/customers/deals/page.tsx +321 -455
  201. package/src/modules/customers/backend/customers/people/page.tsx +331 -240
  202. package/src/modules/customers/components/detail/assignableStaff.ts +21 -0
  203. package/src/modules/customers/i18n/de.json +31 -0
  204. package/src/modules/customers/i18n/en.json +31 -0
  205. package/src/modules/customers/i18n/es.json +31 -0
  206. package/src/modules/customers/i18n/pl.json +31 -0
  207. package/src/modules/customers/widgets/injection/ai-assistant-trigger/widget.client.tsx +197 -40
  208. package/src/modules/customers/widgets/injection/ai-assistant-trigger/widget.ts +13 -7
  209. package/src/modules/customers/widgets/injection-table.ts +6 -0
  210. package/src/modules/perspectives/services/perspectiveService.ts +30 -2
  211. package/src/modules/portal/frontend/[orgSlug]/portal/login/page.tsx +1 -0
  212. package/src/modules/query_index/lib/engine.ts +46 -8
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../../src/modules/customers/backend/customers/deals/page.tsx"],
4
- "sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport Link from 'next/link'\nimport { usePathname, useRouter, useSearchParams } from 'next/navigation'\nimport { useQueryClient } from '@tanstack/react-query'\nimport type { ColumnDef } from '@tanstack/react-table'\nimport { Page, PageBody } from '@open-mercato/ui/backend/Page'\nimport { DataTable, type DataTableExportFormat, withDataTableNamespaces } from '@open-mercato/ui/backend/DataTable'\nimport type { FilterDef, FilterValues } from '@open-mercato/ui/backend/FilterBar'\nimport type { AdvancedFilterState } from '@open-mercato/shared/lib/query/advanced-filter'\nimport { deserializeAdvancedFilter, serializeAdvancedFilter } from '@open-mercato/shared/lib/query/advanced-filter'\nimport { apiCall } from '@open-mercato/ui/backend/utils/apiCall'\nimport { buildCrudExportUrl, deleteCrud } from '@open-mercato/ui/backend/utils/crud'\nimport { groupBulkDeleteFailures, runBulkDelete } from '@open-mercato/ui/backend/utils/bulkDelete'\nimport { useGuardedMutation } from '@open-mercato/ui/backend/injection/useGuardedMutation'\nimport { coalesceLastOperations } from '@open-mercato/ui/backend/operations/store'\nimport { flash } from '@open-mercato/ui/backend/FlashMessages'\nimport { RowActions } from '@open-mercato/ui/backend/RowActions'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { E } from '#generated/entities.ids.generated'\nimport { useOrganizationScopeVersion } from '@open-mercato/shared/lib/frontend/useOrganizationScope'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { useConfirmDialog } from '@open-mercato/ui/backend/confirm-dialog'\nimport {\n DictionaryValue,\n type CustomerDictionaryKind,\n type CustomerDictionaryMap,\n} from '../../../lib/dictionaries'\nimport {\n ensureCustomerDictionary,\n invalidateCustomerDictionary,\n} from '../../../components/detail/hooks/useCustomerDictionary'\nimport {\n useCustomFieldDefs,\n} from '@open-mercato/ui/backend/utils/customFieldDefs'\nimport {\n mapCustomFieldKindToFilterType,\n normalizeCustomFieldFilterOptions,\n supportsCustomFieldColumn,\n} from '@open-mercato/ui/backend/utils/customFieldColumns'\nimport { CollectionPreviewCell, normalizeCollectionLabels } from '../../../components/list/CollectionPreviewCell'\n\ntype DealRow = {\n id: string\n title: string\n status?: string | null\n pipelineStage?: string | null\n pipelineStageId?: string | null\n pipelineId?: string | null\n valueAmount?: number | null\n valueCurrency?: string | null\n probability?: number | null\n expectedCloseAt?: string | null\n updatedAt?: string | null\n companies: { id: string; label: string }[]\n people: { id: string; label: string }[]\n} & Record<string, unknown>\n\ntype DealsResponse = {\n items?: Array<Record<string, unknown>>\n total?: number\n totalPages?: number\n}\n\ntype FilterOption = { value: string; label: string }\n\ntype DictionaryKey = Extract<CustomerDictionaryKind, 'deal-statuses' | 'pipeline-stages'>\n\ntype PersonLookupRecord = {\n id: string\n name: string | null\n email: string | null\n phone: string | null\n}\n\ntype CompanyLookupRecord = {\n id: string\n name: string | null\n domain: string | null\n email: string | null\n}\n\nfunction parsePersonLookupRecord(item: unknown): PersonLookupRecord | null {\n if (typeof item !== 'object' || item === null) return null\n const record = item as Record<string, unknown>\n const id = typeof record.id === 'string' ? record.id : null\n if (!id || !isUuid(id)) return null\n const name = typeof record.display_name === 'string' ? record.display_name : null\n const email = typeof record.primary_email === 'string' ? record.primary_email : null\n const phone = typeof record.primary_phone === 'string' ? record.primary_phone : null\n return { id, name, email, phone }\n}\n\nfunction parseCompanyLookupRecord(item: unknown): CompanyLookupRecord | null {\n if (typeof item !== 'object' || item === null) return null\n const record = item as Record<string, unknown>\n const id = typeof record.id === 'string' ? record.id : null\n if (!id || !isUuid(id)) return null\n const name = typeof record.display_name === 'string' ? record.display_name : null\n const domain = typeof record.primary_domain === 'string' ? record.primary_domain : null\n const email = typeof record.primary_email === 'string' ? record.primary_email : null\n return { id, name, domain, email }\n}\n\ntype OptionsState = {\n options: FilterOption[]\n idToLabel: Record<string, string>\n labelToId: Record<string, string>\n}\n\nconst EMPTY_OPTIONS_STATE: OptionsState = {\n options: [],\n idToLabel: {},\n labelToId: {},\n}\n\nconst PAGE_SIZE = 20\nconst UUID_REGEX = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i\n\nfunction isUuid(value: string | null | undefined): value is string {\n if (!value) return false\n return UUID_REGEX.test(value.trim())\n}\n\nfunction normalizeIdCandidates(raw: Array<string>): string[] {\n const set = new Set<string>()\n raw.forEach((candidate) => {\n candidate\n .split(',')\n .map((part) => part.trim())\n .filter((part) => part.length > 0)\n .forEach((part) => {\n if (isUuid(part)) set.add(part)\n })\n })\n return Array.from(set)\n}\n\nfunction extractIdsFromParams(params: URLSearchParams | null | undefined, key: string): string[] {\n if (!params) return []\n const values = params.getAll(key)\n return normalizeIdCandidates(values)\n}\n\nfunction ensureUniqueLabel(base: string, occupied: Set<string>): string {\n const trimmed = base.trim() || 'Unnamed'\n if (!occupied.has(trimmed)) {\n occupied.add(trimmed)\n return trimmed\n }\n let counter = 2\n let candidate = `${trimmed} \u2022 ${counter}`\n while (occupied.has(candidate)) {\n counter += 1\n candidate = `${trimmed} \u2022 ${counter}`\n }\n occupied.add(candidate)\n return candidate\n}\n\nasync function fetchPeopleLookup(query?: string): Promise<PersonLookupRecord[]> {\n const search = new URLSearchParams()\n search.set('page', '1')\n search.set('pageSize', '20')\n if (query && query.trim().length) search.set('search', query.trim())\n try {\n const call = await apiCall<{ items?: unknown[] }>(`/api/customers/people?${search.toString()}`)\n if (!call.ok) return []\n const items = Array.isArray(call.result?.items) ? call.result.items : []\n return items\n .map((item) => parsePersonLookupRecord(item))\n .filter((record): record is PersonLookupRecord => record !== null)\n } catch {\n return []\n }\n}\n\nasync function fetchPeopleLookupByIds(ids: string[]): Promise<PersonLookupRecord[]> {\n const unique = Array.from(new Set(ids.filter((id) => isUuid(id))))\n if (!unique.length) return []\n const results = await Promise.all(\n unique.map(async (id) => {\n const search = new URLSearchParams()\n search.set('id', id)\n search.set('page', '1')\n search.set('pageSize', '1')\n try {\n const call = await apiCall<{ items?: unknown[] }>(`/api/customers/people?${search.toString()}`)\n if (!call.ok) return null\n const items = Array.isArray(call.result?.items) ? call.result.items : []\n const match = items\n .map((item) => parsePersonLookupRecord(item))\n .find((record) => record?.id === id)\n return match ?? null\n } catch {\n return null\n }\n }),\n )\n return results.filter((record): record is PersonLookupRecord => !!record)\n}\n\nasync function fetchCompaniesLookup(query?: string): Promise<CompanyLookupRecord[]> {\n const search = new URLSearchParams()\n search.set('page', '1')\n search.set('pageSize', '20')\n if (query && query.trim().length) search.set('search', query.trim())\n try {\n const call = await apiCall<{ items?: unknown[] }>(`/api/customers/companies?${search.toString()}`)\n if (!call.ok) return []\n const items = Array.isArray(call.result?.items) ? call.result.items : []\n return items\n .map((item) => parseCompanyLookupRecord(item))\n .filter((record): record is CompanyLookupRecord => record !== null)\n } catch {\n return []\n }\n}\n\nasync function fetchCompaniesLookupByIds(ids: string[]): Promise<CompanyLookupRecord[]> {\n const unique = Array.from(new Set(ids.filter((id) => isUuid(id))))\n if (!unique.length) return []\n const results = await Promise.all(\n unique.map(async (id) => {\n const search = new URLSearchParams()\n search.set('id', id)\n search.set('page', '1')\n search.set('pageSize', '1')\n try {\n const call = await apiCall<{ items?: unknown[] }>(`/api/customers/companies?${search.toString()}`)\n if (!call.ok) return null\n const items = Array.isArray(call.result?.items) ? call.result.items : []\n const match = items\n .map((item) => parseCompanyLookupRecord(item))\n .find((record) => record?.id === id)\n return match ?? null\n } catch {\n return null\n }\n }),\n )\n return results.filter((record): record is CompanyLookupRecord => !!record)\n}\n\nfunction formatCurrency(amount: number | null | undefined, currency: string | null | undefined, fallback: string): string {\n if (typeof amount !== 'number' || Number.isNaN(amount)) return fallback\n try {\n if (currency && currency.trim().length) {\n const formatter = new Intl.NumberFormat(undefined, { style: 'currency', currency })\n return formatter.format(amount)\n }\n const formatter = new Intl.NumberFormat(undefined, { style: 'decimal', maximumFractionDigits: 2 })\n return formatter.format(amount)\n } catch {\n return currency ? `${amount} ${currency}` : String(amount)\n }\n}\n\nfunction formatDateValue(value: string | null | undefined, fallback: string): string {\n if (!value) return fallback\n const date = new Date(value)\n if (Number.isNaN(date.getTime())) return fallback\n return date.toLocaleDateString()\n}\n\nfunction arraysEqual(a: string[], b: string[]): boolean {\n if (a.length !== b.length) return false\n for (let i = 0; i < a.length; i += 1) {\n if (a[i] !== b[i]) return false\n }\n return true\n}\n\nexport default function CustomersDealsPage() {\n const t = useT()\n const { confirm, ConfirmDialogElement } = useConfirmDialog()\n const router = useRouter()\n const pathname = usePathname()\n const searchParams = useSearchParams()\n const scopeVersion = useOrganizationScopeVersion()\n const queryClient = useQueryClient()\n\n const [rows, setRows] = React.useState<DealRow[]>([])\n const [page, setPage] = React.useState(() => {\n const raw = Number(searchParams?.get('page') ?? '1')\n return Number.isFinite(raw) && raw > 0 ? raw : 1\n })\n const [pageSize, setPageSize] = React.useState(PAGE_SIZE)\n const [sorting, setSorting] = React.useState<import('@tanstack/react-table').SortingState>([])\n const [total, setTotal] = React.useState(0)\n const [totalPages, setTotalPages] = React.useState(1)\n const [search, setSearch] = React.useState(() => searchParams?.get('search')?.trim() ?? '')\n const [isLoading, setIsLoading] = React.useState(false)\n const [reloadToken, setReloadToken] = React.useState(0)\n const [pendingDeleteId, setPendingDeleteId] = React.useState<string | null>(null)\n const [filterValues, setFilterValues] = React.useState<FilterValues>({})\n const [advancedFilterState, setAdvancedFilterState] = React.useState<AdvancedFilterState>(() => {\n const params = searchParams\n if (!params) return { logic: 'and', conditions: [] }\n const record: Record<string, string> = {}\n params.forEach((value, key) => {\n if (key.startsWith('filter[')) record[key] = value\n })\n const hydrated = deserializeAdvancedFilter(record)\n return hydrated ?? { logic: 'and', conditions: [] }\n })\n const [cacheStatus, setCacheStatus] = React.useState<'hit' | 'miss' | null>(null)\n\n const initialPersonIds = React.useMemo(\n () => extractIdsFromParams(searchParams, 'personId'),\n [searchParams],\n )\n const initialCompanyIds = React.useMemo(\n () => extractIdsFromParams(searchParams, 'companyId'),\n [searchParams],\n )\n\n const [selectedPersonIds, setSelectedPersonIds] = React.useState<string[]>(initialPersonIds)\n const [selectedCompanyIds, setSelectedCompanyIds] = React.useState<string[]>(initialCompanyIds)\n\n const [peopleState, setPeopleState] = React.useState<OptionsState>(EMPTY_OPTIONS_STATE)\n const [companiesState, setCompaniesState] = React.useState<OptionsState>(EMPTY_OPTIONS_STATE)\n const peopleCacheRef = React.useRef<Map<string, FilterOption[]>>(new Map())\n const companiesCacheRef = React.useRef<Map<string, FilterOption[]>>(new Map())\n\n const buildPersonLabel = React.useCallback((record: PersonLookupRecord): string => {\n const parts: string[] = []\n const name = record.name?.trim()\n if (name) parts.push(name)\n const email = record.email?.trim()\n if (email && !parts.includes(email)) parts.push(email)\n const phone = record.phone?.trim()\n if (!parts.length && phone) parts.push(phone)\n if (!parts.length) parts.push(t('customers.deals.list.unnamedPerson', 'Unnamed person'))\n return parts.join(' \u2022 ')\n }, [t])\n\n const buildCompanyLabel = React.useCallback((record: CompanyLookupRecord): string => {\n const parts: string[] = []\n const name = record.name?.trim()\n if (name) parts.push(name)\n const domain = record.domain?.trim()\n if (domain && !parts.includes(domain)) parts.push(domain)\n const email = record.email?.trim()\n if (!parts.length && email) parts.push(email)\n if (!parts.length) parts.push(t('customers.deals.list.unnamedCompany', 'Unnamed company'))\n return parts.join(' \u2022 ')\n }, [t])\n\n const ingestPeopleRecords = React.useCallback((records: PersonLookupRecord[]) => {\n if (!records.length) return [] as FilterOption[]\n const queryMap = new Map<string, FilterOption>()\n setPeopleState((prev) => {\n const idToLabel = { ...prev.idToLabel }\n const labelToId: Record<string, string> = {}\n const merged = new Map(prev.options.map((opt) => [opt.value, opt]))\n const occupied = new Set<string>()\n Object.entries(prev.labelToId).forEach(([label, id]) => {\n occupied.add(label)\n labelToId[label] = id\n })\n records.forEach((record) => {\n if (!isUuid(record.id)) return\n const base = buildPersonLabel(record)\n let previousLabel = idToLabel[record.id]\n if (previousLabel) {\n delete labelToId[previousLabel]\n occupied.delete(previousLabel)\n }\n const label = ensureUniqueLabel(base, occupied)\n idToLabel[record.id] = label\n labelToId[label] = record.id\n const option = { value: record.id, label }\n merged.set(record.id, option)\n queryMap.set(record.id, option)\n })\n const nextOptions = Array.from(merged.values()).sort((a, b) => a.label.localeCompare(b.label))\n return { options: nextOptions, idToLabel, labelToId }\n })\n return Array.from(queryMap.values()).sort((a, b) => a.label.localeCompare(b.label))\n }, [buildPersonLabel])\n\n const ingestCompanyRecords = React.useCallback((records: CompanyLookupRecord[]) => {\n if (!records.length) return [] as FilterOption[]\n const queryMap = new Map<string, FilterOption>()\n setCompaniesState((prev) => {\n const idToLabel = { ...prev.idToLabel }\n const labelToId: Record<string, string> = {}\n const merged = new Map(prev.options.map((opt) => [opt.value, opt]))\n const occupied = new Set<string>()\n Object.entries(prev.labelToId).forEach(([label, id]) => {\n occupied.add(label)\n labelToId[label] = id\n })\n records.forEach((record) => {\n if (!isUuid(record.id)) return\n const base = buildCompanyLabel(record)\n let previousLabel = idToLabel[record.id]\n if (previousLabel) {\n delete labelToId[previousLabel]\n occupied.delete(previousLabel)\n }\n const label = ensureUniqueLabel(base, occupied)\n idToLabel[record.id] = label\n labelToId[label] = record.id\n const option = { value: record.id, label }\n merged.set(record.id, option)\n queryMap.set(record.id, option)\n })\n const nextOptions = Array.from(merged.values()).sort((a, b) => a.label.localeCompare(b.label))\n return { options: nextOptions, idToLabel, labelToId }\n })\n return Array.from(queryMap.values()).sort((a, b) => a.label.localeCompare(b.label))\n }, [buildCompanyLabel])\n\n const loadPeopleOptions = React.useCallback(async (query?: string) => {\n const normalizedQuery = (query || '').trim().toLowerCase()\n const cacheKey = `${scopeVersion}|${normalizedQuery}`\n const cached = peopleCacheRef.current.get(cacheKey)\n if (cached) return cached\n const records = await fetchPeopleLookup(query)\n const options = ingestPeopleRecords(records)\n peopleCacheRef.current.set(cacheKey, options)\n return options\n }, [scopeVersion, ingestPeopleRecords])\n\n const loadCompanyOptions = React.useCallback(async (query?: string) => {\n const normalizedQuery = (query || '').trim().toLowerCase()\n const cacheKey = `${scopeVersion}|${normalizedQuery}`\n const cached = companiesCacheRef.current.get(cacheKey)\n if (cached) return cached\n const records = await fetchCompaniesLookup(query)\n const options = ingestCompanyRecords(records)\n companiesCacheRef.current.set(cacheKey, options)\n return options\n }, [scopeVersion, ingestCompanyRecords])\n\n React.useEffect(() => {\n let cancelled = false\n if (!selectedPersonIds.length) return\n const missing = selectedPersonIds.filter((id) => !peopleState.idToLabel[id])\n if (!missing.length) return\n fetchPeopleLookupByIds(missing).then((records) => {\n if (cancelled) return\n ingestPeopleRecords(records)\n })\n return () => { cancelled = true }\n }, [selectedPersonIds, peopleState.idToLabel, ingestPeopleRecords])\n\n React.useEffect(() => {\n let cancelled = false\n if (!selectedCompanyIds.length) return\n const missing = selectedCompanyIds.filter((id) => !companiesState.idToLabel[id])\n if (!missing.length) return\n fetchCompaniesLookupByIds(missing).then((records) => {\n if (cancelled) return\n ingestCompanyRecords(records)\n })\n return () => { cancelled = true }\n }, [selectedCompanyIds, companiesState.idToLabel, ingestCompanyRecords])\n\n const [dictionaryMaps, setDictionaryMaps] = React.useState<Record<DictionaryKey, CustomerDictionaryMap>>({\n 'deal-statuses': {},\n 'pipeline-stages': {},\n })\n\n const [pipelineNames, setPipelineNames] = React.useState<Record<string, string>>({})\n\n const fetchDictionaryEntries = React.useCallback(\n async (kind: DictionaryKey) => {\n try {\n const data = await ensureCustomerDictionary(queryClient, kind, scopeVersion)\n setDictionaryMaps((prev) => ({ ...prev, [kind]: data.map }))\n } catch {\n setDictionaryMaps((prev) => ({ ...prev, [kind]: {} }))\n }\n },\n [queryClient, scopeVersion],\n )\n\n React.useEffect(() => {\n let cancelled = false\n async function loadDictionaries() {\n if (cancelled) return\n await Promise.all([fetchDictionaryEntries('deal-statuses'), fetchDictionaryEntries('pipeline-stages')])\n }\n loadDictionaries().catch(() => {})\n return () => { cancelled = true }\n }, [fetchDictionaryEntries, reloadToken])\n\n React.useEffect(() => {\n let cancelled = false\n async function loadPipelines() {\n try {\n const call = await apiCall<{ items?: Array<{ id: string; name: string }> }>('/api/customers/pipelines')\n if (cancelled || !call.ok) return\n const items = Array.isArray(call.result?.items) ? call.result.items : []\n const map: Record<string, string> = {}\n items.forEach((p) => { if (p.id && p.name) map[p.id] = p.name })\n setPipelineNames(map)\n } catch (err) {\n console.warn('[customers.deals.list] failed to load pipelines', err)\n }\n }\n loadPipelines().catch((err) => {\n console.warn('[customers.deals.list] loadPipelines threw', err)\n })\n return () => { cancelled = true }\n }, [reloadToken, scopeVersion])\n\n React.useEffect(() => {\n peopleCacheRef.current.clear()\n companiesCacheRef.current.clear()\n setPeopleState((prev) => {\n if (!prev.options.length && !Object.keys(prev.idToLabel).length) return prev\n return { ...EMPTY_OPTIONS_STATE }\n })\n setCompaniesState((prev) => {\n if (!prev.options.length && !Object.keys(prev.idToLabel).length) return prev\n return { ...EMPTY_OPTIONS_STATE }\n })\n }, [scopeVersion, reloadToken])\n\n const syncFilterIds = React.useCallback((\n key: 'people' | 'companies',\n ids: string[],\n ) => {\n setFilterValues((prev) => {\n const current = Array.isArray(prev[key]) ? (prev[key] as string[]) : []\n if (!ids.length) {\n if (!current.length) return prev\n const next = { ...prev }\n delete next[key]\n return next\n }\n if (arraysEqual(current, ids)) return prev\n return { ...prev, [key]: [...ids] }\n })\n }, [])\n\n React.useEffect(() => {\n syncFilterIds('people', selectedPersonIds)\n }, [selectedPersonIds, syncFilterIds])\n\n React.useEffect(() => {\n syncFilterIds('companies', selectedCompanyIds)\n }, [selectedCompanyIds, syncFilterIds])\n\n const handleSearchChange = React.useCallback((value: string) => {\n setSearch(value.trim())\n setPage(1)\n }, [])\n\n const handleFiltersApply = React.useCallback((values: FilterValues) => {\n const next: FilterValues = { ...values }\n\n const rawPeople = Array.isArray(values.people) ? (values.people as string[]) : []\n const nextPersonIds = Array.from(\n new Set(\n rawPeople\n .map((value) => (typeof value === 'string' ? value.trim() : ''))\n .filter((value) => value.length > 0 && isUuid(value)),\n ),\n )\n setSelectedPersonIds(nextPersonIds)\n if (nextPersonIds.length) next.people = nextPersonIds\n else delete next.people\n\n const rawCompanies = Array.isArray(values.companies) ? (values.companies as string[]) : []\n const nextCompanyIds = Array.from(\n new Set(\n rawCompanies\n .map((value) => (typeof value === 'string' ? value.trim() : ''))\n .filter((value) => value.length > 0 && isUuid(value)),\n ),\n )\n setSelectedCompanyIds(nextCompanyIds)\n if (nextCompanyIds.length) next.companies = nextCompanyIds\n else delete next.companies\n\n setFilterValues(next)\n setPage(1)\n }, [])\n\n const handleFiltersClear = React.useCallback(() => {\n setFilterValues({})\n setSelectedPersonIds([])\n setSelectedCompanyIds([])\n setPage(1)\n }, [])\n\n const queryParams = React.useMemo(() => {\n const params = new URLSearchParams()\n params.set('page', String(page))\n params.set('pageSize', String(pageSize))\n if (sorting.length > 0) {\n params.set('sort', sorting[0].id)\n params.set('order', sorting[0].desc ? 'desc' : 'asc')\n }\n if (search.trim().length) params.set('search', search.trim())\n if (selectedPersonIds.length) params.set('personId', selectedPersonIds.join(','))\n if (selectedCompanyIds.length) params.set('companyId', selectedCompanyIds.join(','))\n Object.entries(filterValues).forEach(([key, value]) => {\n if (key === 'people' || key === 'companies') return\n if (value == null) return\n if (Array.isArray(value)) {\n const normalized = value\n .map((item) => {\n if (item == null) return ''\n if (typeof item === 'string') return item.trim()\n return String(item).trim()\n })\n .filter((item) => item.length > 0)\n if (normalized.length) params.set(key, normalized.join(','))\n } else if (typeof value === 'object') {\n const obj = value as Record<string, unknown>\n const from = typeof obj.from === 'string' ? obj.from.trim() : ''\n const to = typeof obj.to === 'string' ? obj.to.trim() : ''\n if (from) params.set(`${key}[from]`, from)\n if (to) params.set(`${key}[to]`, to)\n } else {\n const stringValue = typeof value === 'string' ? value.trim() : String(value)\n if (stringValue) params.set(key, stringValue)\n }\n })\n const advancedParams = serializeAdvancedFilter(advancedFilterState)\n for (const [key, val] of Object.entries(advancedParams)) {\n params.set(key, val)\n }\n return params.toString()\n }, [advancedFilterState, filterValues, page, pageSize, search, selectedCompanyIds, selectedPersonIds, sorting])\n\n const currentParams = React.useMemo(\n () => Object.fromEntries(new URLSearchParams(queryParams)),\n [queryParams],\n )\n\n const exportConfig = React.useMemo(() => ({\n view: {\n getUrl: (format: DataTableExportFormat) =>\n buildCrudExportUrl('customers/deals', { ...currentParams, exportScope: 'view' }, format),\n },\n full: {\n getUrl: (format: DataTableExportFormat) =>\n buildCrudExportUrl('customers/deals', { ...currentParams, exportScope: 'full', all: 'true' }, format),\n },\n }), [currentParams])\n\n React.useEffect(() => {\n let cancelled = false\n async function load() {\n setIsLoading(true)\n setCacheStatus(null)\n try {\n const fallback: DealsResponse = { items: [], total: 0, totalPages: 1 }\n const call = await apiCall<DealsResponse>(`/api/customers/deals?${queryParams}`, undefined, { fallback })\n if (!call.ok) {\n const message =\n typeof (call.result as { error?: string } | undefined)?.error === 'string'\n ? (call.result as { error?: string }).error!\n : t('customers.deals.list.error.load')\n flash(message, 'error')\n if (!cancelled) setCacheStatus(null)\n return\n }\n const payload = call.result ?? fallback\n if (cancelled) return\n setCacheStatus(call.cacheStatus ?? null)\n const items = Array.isArray(payload.items) ? payload.items : []\n const mapped = items\n .map((item) => mapDeal(item as Record<string, unknown>))\n .filter((row): row is DealRow => !!row)\n setRows(mapped)\n setTotal(typeof payload.total === 'number' ? payload.total : mapped.length)\n setTotalPages(typeof payload.totalPages === 'number' ? payload.totalPages : 1)\n } catch (err) {\n if (!cancelled) {\n setCacheStatus(null)\n const message = err instanceof Error ? err.message : t('customers.deals.list.error.load')\n flash(message, 'error')\n }\n } finally {\n if (!cancelled) setIsLoading(false)\n }\n }\n load()\n return () => { cancelled = true }\n }, [queryParams, reloadToken, scopeVersion, t])\n\n React.useEffect(() => {\n if (totalPages > 0 && page > totalPages) {\n setPage(totalPages)\n }\n }, [page, totalPages])\n\n const queryRef = React.useRef(searchParams?.toString() ?? '')\n React.useEffect(() => {\n if (!pathname) return\n const params = new URLSearchParams()\n if (search.trim().length) params.set('search', search.trim())\n if (selectedPersonIds.length) selectedPersonIds.forEach((id) => params.append('personId', id))\n if (selectedCompanyIds.length) selectedCompanyIds.forEach((id) => params.append('companyId', id))\n if (page > 1) params.set('page', String(page))\n const advancedParams = serializeAdvancedFilter(advancedFilterState)\n for (const [key, val] of Object.entries(advancedParams)) {\n params.set(key, val)\n }\n const next = params.toString()\n if (queryRef.current === next) return\n queryRef.current = next\n router.replace(next ? `${pathname}?${next}` : pathname, { scroll: false })\n }, [pathname, router, page, search, selectedPersonIds, selectedCompanyIds, advancedFilterState])\n\n const handleRefresh = React.useCallback(() => {\n peopleCacheRef.current.clear()\n companiesCacheRef.current.clear()\n void Promise.all([\n invalidateCustomerDictionary(queryClient, 'deal-statuses'),\n invalidateCustomerDictionary(queryClient, 'pipeline-stages'),\n ])\n setReloadToken((token) => token + 1)\n }, [queryClient])\n\n const bulkMutationContextId = 'customers-deals-list:bulk-delete'\n const { runMutation: runBulkMutation, retryLastMutation: retryBulkMutation } = useGuardedMutation<{\n formId: string\n resourceKind: string\n retryLastMutation: () => Promise<boolean>\n }>({\n contextId: bulkMutationContextId,\n blockedMessage: t('ui.forms.flash.saveBlocked', 'Save blocked by validation'),\n })\n const singleMutationContextId = 'customers-deals-list:single-delete'\n const { runMutation: runSingleMutation, retryLastMutation: retrySingleMutation } = useGuardedMutation<{\n formId: string\n resourceKind: string\n resourceId: string\n retryLastMutation: () => Promise<boolean>\n }>({\n contextId: singleMutationContextId,\n blockedMessage: t('ui.forms.flash.saveBlocked', 'Save blocked by validation'),\n })\n\n const handleDeleteDeal = React.useCallback(\n async (dealId: string) => {\n if (pendingDeleteId) return\n const confirmed = await confirm({\n title: t(\n 'customers.deals.list.deleteConfirm',\n 'Delete this deal? This action cannot be undone.',\n ),\n variant: 'destructive',\n })\n if (!confirmed) return\n setPendingDeleteId(dealId)\n try {\n await runSingleMutation({\n operation: async () => {\n await deleteCrud('customers/deals', {\n body: { id: dealId },\n errorMessage: t('customers.deals.list.deleteError', 'Failed to delete deal.'),\n })\n },\n context: {\n formId: singleMutationContextId,\n resourceKind: 'customers.deal',\n resourceId: dealId,\n retryLastMutation: retrySingleMutation,\n },\n })\n flash(t('customers.deals.list.deleteSuccess', 'Deal deleted.'), 'success')\n setRows((prev) => prev.filter((row) => row.id !== dealId))\n setTotal((prev) => Math.max(0, prev - 1))\n handleRefresh()\n } catch (err) {\n const message =\n err instanceof Error && err.message\n ? err.message\n : t('customers.deals.list.deleteError', 'Failed to delete deal.')\n flash(message, 'error')\n } finally {\n setPendingDeleteId(null)\n }\n },\n [confirm, handleRefresh, pendingDeleteId, retrySingleMutation, runSingleMutation, singleMutationContextId, t],\n )\n\n const handlePageSizeChange = React.useCallback((newSize: number) => {\n setPageSize(newSize)\n setPage(1)\n }, [])\n\n const handleBulkDelete = React.useCallback(async (selectedRows: DealRow[]) => {\n const confirmed = await confirm({\n title: t('customers.deals.list.bulkDelete.title', 'Delete {count} deals?', { count: selectedRows.length }),\n description: t('customers.deals.list.bulkDelete.description', 'This action cannot be undone.'),\n variant: 'destructive',\n })\n if (!confirmed) return false\n\n const { succeeded, failures } = await runBulkMutation({\n operation: async () =>\n runBulkDelete(\n selectedRows,\n async (row) => {\n await deleteCrud('customers/deals', {\n body: { id: row.id },\n errorMessage: t('customers.deals.list.deleteError', 'Failed to delete deal.'),\n })\n },\n {\n fallbackErrorMessage: t('customers.deals.list.deleteError', 'Failed to delete deal.'),\n logTag: 'customers.deals.list',\n },\n ),\n context: {\n formId: bulkMutationContextId,\n resourceKind: 'customers.deal',\n retryLastMutation: retryBulkMutation,\n },\n })\n\n if (succeeded.length > 0) {\n const succeededIds = new Set(succeeded.map((r) => r.id))\n setRows((prev) => prev.filter((r) => !succeededIds.has(r.id)))\n setTotal((prev) => Math.max(0, prev - succeeded.length))\n setReloadToken((prev) => prev + 1)\n if (succeeded.length > 1) {\n coalesceLastOperations(succeeded.length, {\n commandId: 'customers.deals.delete',\n actionLabel: t('customers.deals.list.bulkDelete.operationLabel', 'Delete {count} deals', { count: succeeded.length }),\n resourceKind: 'customers.deal',\n })\n }\n if (failures.length === 0) {\n flash(\n t('customers.deals.list.bulkDelete.success', '{count} deals deleted', { count: succeeded.length }),\n 'success',\n )\n } else {\n flash(\n t('customers.deals.list.bulkDelete.partial', '{deleted} of {total} deals deleted; {failed} failed', {\n deleted: succeeded.length,\n total: selectedRows.length,\n failed: failures.length,\n }),\n 'warning',\n )\n }\n }\n\n for (const group of groupBulkDeleteFailures(failures)) {\n const message = group.count === 1\n ? group.sampleMessage\n : t(\n 'customers.deals.list.bulkDelete.failedGroup',\n '{count} deals could not be deleted: {message}',\n { count: group.count, message: group.sampleMessage },\n )\n flash(message, 'error')\n }\n\n return succeeded.length > 0\n }, [bulkMutationContextId, confirm, retryBulkMutation, runBulkMutation, t])\n\n const personOptions = peopleState.options\n const companyOptions = companiesState.options\n\n const peopleIdToLabel = peopleState.idToLabel\n const companyIdToLabel = companiesState.idToLabel\n const filters = React.useMemo<FilterDef[]>(() => [\n {\n id: 'people',\n label: t('customers.deals.list.filters.people'),\n type: 'tags',\n options: personOptions,\n loadOptions: loadPeopleOptions,\n placeholder: t('customers.deals.list.filters.peoplePlaceholder'),\n formatValue: (value: string) => peopleIdToLabel[value] ?? value,\n },\n {\n id: 'companies',\n label: t('customers.deals.list.filters.companies'),\n type: 'tags',\n options: companyOptions,\n loadOptions: loadCompanyOptions,\n placeholder: t('customers.deals.list.filters.companiesPlaceholder'),\n formatValue: (value: string) => companyIdToLabel[value] ?? value,\n },\n ], [companyIdToLabel, companyOptions, loadCompanyOptions, loadPeopleOptions, peopleIdToLabel, personOptions, t])\n\n const { data: customFieldDefs = [] } = useCustomFieldDefs([E.customers.customer_deal], {\n keyExtras: [scopeVersion, reloadToken],\n })\n\n const columns = React.useMemo<ColumnDef<DealRow>[]>(() => {\n const noValue = <span className=\"text-muted-foreground text-sm\">{t('customers.deals.list.noValue')}</span>\n const renderDictionaryCell = (kind: DictionaryKey, value: string | null | undefined) => (\n <DictionaryValue\n value={value}\n map={dictionaryMaps[kind]}\n fallback={value ? <span className=\"text-sm\">{value}</span> : noValue}\n className=\"text-sm\"\n iconWrapperClassName=\"inline-flex h-6 w-6 items-center justify-center rounded border border-border bg-card\"\n iconClassName=\"h-4 w-4\"\n colorClassName=\"h-3 w-3 rounded-full\"\n />\n )\n const renderAssociationSummary = (\n items: { id: string; label: string }[],\n fallbackLabel: string,\n ) => {\n if (!items.length) return noValue\n const labels = normalizeCollectionLabels(\n items.map((entry) => (entry.label && entry.label.trim().length ? entry.label : fallbackLabel)),\n )\n if (!labels.length) return noValue\n return (\n <CollectionPreviewCell labels={labels} maxVisible={1} />\n )\n }\n\n const customColumns = customFieldDefs\n .filter((def) => supportsCustomFieldColumn(def))\n .map<ColumnDef<DealRow>>((def) => ({\n accessorKey: `cf_${def.key}`,\n header: def.label || def.key,\n meta: {\n columnChooserGroup: def.group?.title ?? 'Custom Fields',\n filterGroup: def.group?.title ?? 'Custom Fields',\n filterType: mapCustomFieldKindToFilterType(def.kind),\n filterOptions: normalizeCustomFieldFilterOptions(def.options),\n hidden: def.listVisible === false,\n maxWidth: '220px',\n },\n cell: ({ getValue }) => {\n const value = getValue()\n if (value == null) return noValue\n if (Array.isArray(value)) {\n const normalized = normalizeCollectionLabels(\n value\n .map((item) => {\n if (item == null) return ''\n if (typeof item === 'string') return item\n return String(item)\n }),\n )\n if (!normalized.length) return noValue\n return <CollectionPreviewCell labels={normalized} maxVisible={2} />\n }\n if (typeof value === 'boolean') {\n return (\n <span className=\"text-sm\">\n {value\n ? t('customers.deals.list.booleanYes', 'Yes')\n : t('customers.deals.list.booleanNo', 'No')}\n </span>\n )\n }\n const stringValue = typeof value === 'string' ? value.trim() : String(value)\n if (!stringValue) return noValue\n return <span className=\"text-sm\">{stringValue}</span>\n },\n }))\n\n return [\n {\n accessorKey: 'title',\n header: t('customers.deals.list.columns.title'),\n meta: {\n alwaysVisible: true,\n columnChooserGroup: 'Basic Info',\n filterKey: 'title',\n maxWidth: '280px',\n },\n cell: ({ row }) => <span className=\"font-medium text-sm\">{row.original.title}</span>,\n },\n {\n accessorKey: 'status',\n header: t('customers.deals.list.columns.status'),\n meta: { filterType: 'select' as const, columnChooserGroup: 'Basic Info', filterKey: 'status' },\n cell: ({ row }) => renderDictionaryCell('deal-statuses', row.original.status),\n },\n {\n accessorKey: 'pipelineStage',\n header: t('customers.deals.list.columns.pipelineStage'),\n meta: { columnChooserGroup: 'Pipeline', filterKey: 'pipeline_stage' },\n cell: ({ row }) => renderDictionaryCell('pipeline-stages', row.original.pipelineStage),\n },\n {\n accessorKey: 'pipelineId',\n header: t('customers.deals.list.columns.pipeline', 'Pipeline'),\n meta: { columnChooserGroup: 'Pipeline', filterKey: 'pipeline_id', maxWidth: '220px' },\n cell: ({ row }) => {\n const name = row.original.pipelineId ? pipelineNames[row.original.pipelineId] : null\n return name ? <span className=\"text-sm\">{name}</span> : noValue\n },\n },\n {\n accessorKey: 'valueAmount',\n header: t('customers.deals.list.columns.value'),\n meta: { filterType: 'number' as const, columnChooserGroup: 'Financial', filterKey: 'value_amount' },\n cell: ({ row }) => (\n <span className=\"text-sm font-medium\">\n {formatCurrency(row.original.valueAmount ?? null, row.original.valueCurrency ?? null, t('customers.deals.list.noValue'))}\n </span>\n ),\n },\n {\n accessorKey: 'probability',\n header: t('customers.deals.list.columns.probability'),\n meta: { filterType: 'number' as const, columnChooserGroup: 'Financial', filterKey: 'probability' },\n cell: ({ row }) => {\n const value = row.original.probability\n if (typeof value === 'number' && Number.isFinite(value)) {\n return <span className=\"text-sm\">{`${Math.min(Math.max(value, 0), 100)}%`}</span>\n }\n return noValue\n },\n },\n {\n accessorKey: 'expectedCloseAt',\n header: t('customers.deals.list.columns.expectedClose'),\n meta: { columnChooserGroup: 'Dates', filterKey: 'expected_close_at' },\n cell: ({ row }) => (\n <span className=\"text-sm\">\n {formatDateValue(row.original.expectedCloseAt ?? null, t('customers.deals.list.noValue'))}\n </span>\n ),\n },\n {\n accessorKey: 'companies',\n header: t('customers.deals.list.columns.companies'),\n meta: {\n columnChooserGroup: 'Associations',\n filterable: false,\n maxWidth: '220px',\n tooltipContent: (row: DealRow) =>\n normalizeCollectionLabels(\n row.companies.map((entry) => (entry.label && entry.label.trim().length ? entry.label : t('customers.deals.list.unnamedCompany'))),\n ).join(', '),\n },\n cell: ({ row }) => renderAssociationSummary(row.original.companies, t('customers.deals.list.unnamedCompany')),\n },\n {\n accessorKey: 'people',\n header: t('customers.deals.list.columns.people'),\n meta: {\n columnChooserGroup: 'Associations',\n filterable: false,\n maxWidth: '220px',\n tooltipContent: (row: DealRow) =>\n normalizeCollectionLabels(\n row.people.map((entry) => (entry.label && entry.label.trim().length ? entry.label : t('customers.deals.list.unnamedPerson'))),\n ).join(', '),\n },\n cell: ({ row }) => renderAssociationSummary(row.original.people, t('customers.deals.list.unnamedPerson')),\n },\n {\n accessorKey: 'updatedAt',\n header: t('customers.deals.list.columns.updatedAt'),\n meta: { columnChooserGroup: 'Dates', filterKey: 'updated_at' },\n cell: ({ row }) => (\n <span className=\"text-sm\">\n {formatDateValue(row.original.updatedAt ?? null, t('customers.deals.list.noValue'))}\n </span>\n ),\n },\n ...customColumns,\n ]\n }, [customFieldDefs, dictionaryMaps, pipelineNames, t])\n\n return (\n <Page>\n <PageBody>\n <DataTable<DealRow>\n stickyFirstColumn\n stickyActionsColumn\n title={t('customers.deals.list.title')}\n actions={(\n <Button asChild>\n <Link href=\"/backend/customers/deals/create\">\n {t('customers.deals.list.actions.new', 'New deal')}\n </Link>\n </Button>\n )}\n columns={columns}\n columnChooser={{ auto: true }}\n data={rows}\n onRowClick={(row) => {\n router.push(`/backend/customers/deals/${row.id}`)\n }}\n rowActions={(row) => {\n const isDeleting = pendingDeleteId === row.id\n return (\n <RowActions\n items={[\n {\n id: 'edit',\n label: t('customers.deals.list.actions.edit', 'Edit'),\n onSelect: () => { router.push(`/backend/customers/deals/${row.id}`) },\n },\n {\n id: 'open-new-tab',\n label: t('customers.deals.list.actions.openInNewTab', 'Open in new tab'),\n onSelect: () => {\n if (typeof window !== 'undefined') {\n window.open(`/backend/customers/deals/${row.id}`, '_blank', 'noopener')\n }\n },\n },\n {\n id: 'delete',\n label: isDeleting\n ? t('customers.deals.list.actions.deleting', 'Deleting\u2026')\n : t('customers.deals.list.actions.delete', 'Delete'),\n destructive: true,\n onSelect: () => handleDeleteDeal(row.id),\n },\n ]}\n />\n )\n }}\n sortable\n sorting={sorting}\n onSortingChange={setSorting}\n bulkActions={[\n {\n id: 'delete',\n label: t('customers.deals.list.actions.delete', 'Delete'),\n destructive: true,\n onExecute: handleBulkDelete,\n },\n ]}\n searchValue={search}\n onSearchChange={handleSearchChange}\n searchPlaceholder={t('customers.deals.list.searchPlaceholder')}\n filters={filters}\n filterValues={filterValues}\n onFiltersApply={handleFiltersApply}\n onFiltersClear={handleFiltersClear}\n pagination={{\n page,\n pageSize,\n total,\n totalPages,\n onPageChange: (nextPage) => setPage(nextPage),\n pageSizeOptions: [10, 25, 50, 100],\n onPageSizeChange: handlePageSizeChange,\n cacheStatus,\n }}\n isLoading={isLoading}\n refreshButton={{\n label: t('customers.deals.list.refresh'),\n onRefresh: handleRefresh,\n }}\n exporter={exportConfig}\n entityId={E.customers.customer_deal}\n perspective={{ tableId: 'customers.deals.list' }}\n advancedFilter={{\n auto: true,\n value: advancedFilterState,\n onChange: setAdvancedFilterState,\n onApply: () => { setPage(1) },\n onClear: () => { setAdvancedFilterState({ logic: 'and', conditions: [] }); setPage(1) },\n }}\n virtualized\n />\n </PageBody>\n {ConfirmDialogElement}\n </Page>\n )\n}\n\nfunction mapDeal(item: Record<string, unknown>): DealRow | null {\n const id = typeof item.id === 'string' ? item.id : null\n if (!id) return null\n const title = typeof item.title === 'string' ? item.title : ''\n const status = typeof item.status === 'string' ? item.status : null\n const pipelineStage = typeof item.pipeline_stage === 'string' ? item.pipeline_stage : null\n const pipelineStageId = typeof item.pipeline_stage_id === 'string' ? item.pipeline_stage_id : null\n const pipelineId = typeof item.pipeline_id === 'string' ? item.pipeline_id : null\n const valueAmountRaw = item.value_amount\n const valueAmount =\n typeof valueAmountRaw === 'number'\n ? valueAmountRaw\n : typeof valueAmountRaw === 'string' && valueAmountRaw.trim()\n ? Number(valueAmountRaw)\n : null\n const valueCurrency =\n typeof item.value_currency === 'string' && item.value_currency.trim().length\n ? item.value_currency.trim().toUpperCase()\n : null\n const probabilityRaw = item.probability\n const probability =\n typeof probabilityRaw === 'number'\n ? probabilityRaw\n : typeof probabilityRaw === 'string' && probabilityRaw.trim().length\n ? Number(probabilityRaw)\n : null\n const expectedCloseAt = typeof item.expected_close_at === 'string' ? item.expected_close_at : null\n const updatedAt = typeof item.updated_at === 'string' ? item.updated_at : null\n const peopleRaw = Array.isArray(item.people) ? item.people : []\n const companiesRaw = Array.isArray(item.companies) ? item.companies : []\n const people = peopleRaw\n .map((entry) => {\n if (!entry || typeof entry !== 'object') return null\n const data = entry as Record<string, unknown>\n const pid = typeof data.id === 'string' ? data.id : null\n if (!pid) return null\n const label = typeof data.label === 'string' ? data.label : ''\n return { id: pid, label }\n })\n .filter((entry): entry is { id: string; label: string } => !!entry)\n const companies = companiesRaw\n .map((entry) => {\n if (!entry || typeof entry !== 'object') return null\n const data = entry as Record<string, unknown>\n const cid = typeof data.id === 'string' ? data.id : null\n if (!cid) return null\n const label = typeof data.label === 'string' ? data.label : ''\n return { id: cid, label }\n })\n .filter((entry): entry is { id: string; label: string } => !!entry)\n const customFields: Record<string, unknown> = {}\n for (const [key, value] of Object.entries(item)) {\n if (key.startsWith('cf_')) customFields[key] = value\n }\n return withDataTableNamespaces({\n id,\n title,\n status,\n pipelineStage,\n pipelineStageId,\n pipelineId,\n valueAmount,\n valueCurrency,\n probability,\n expectedCloseAt,\n updatedAt,\n people,\n companies,\n ...customFields,\n }, item)\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport Link from 'next/link'\nimport { usePathname, useRouter, useSearchParams } from 'next/navigation'\nimport { useQueryClient } from '@tanstack/react-query'\nimport type { ColumnDef } from '@tanstack/react-table'\nimport { Page, PageBody } from '@open-mercato/ui/backend/Page'\nimport { DataTable, type DataTableExportFormat, withDataTableNamespaces } from '@open-mercato/ui/backend/DataTable'\nimport type { AdvancedFilterTree } from '@open-mercato/shared/lib/query/advanced-filter-tree'\nimport { createEmptyTree, makeRuleTree, makeMultiRuleTree } from '@open-mercato/shared/lib/query/advanced-filter-tree'\nimport { deserializeTree, deserializeAdvancedFilter, flatToTree, mapDictionaryColorToTone, serializeTree, type FilterFieldDef, type FilterOption as AdvancedFilterOption } from '@open-mercato/shared/lib/query/advanced-filter'\nimport { useCurrentUserId } from '@open-mercato/ui/backend/utils/useCurrentUserId'\nimport { apiCall } from '@open-mercato/ui/backend/utils/apiCall'\nimport { buildCrudExportUrl, deleteCrud } from '@open-mercato/ui/backend/utils/crud'\nimport { groupBulkDeleteFailures, runBulkDelete } from '@open-mercato/ui/backend/utils/bulkDelete'\nimport { useGuardedMutation } from '@open-mercato/ui/backend/injection/useGuardedMutation'\nimport { coalesceLastOperations } from '@open-mercato/ui/backend/operations/store'\nimport { flash } from '@open-mercato/ui/backend/FlashMessages'\nimport { RowActions } from '@open-mercato/ui/backend/RowActions'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { E } from '#generated/entities.ids.generated'\nimport { useOrganizationScopeVersion } from '@open-mercato/shared/lib/frontend/useOrganizationScope'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { useConfirmDialog } from '@open-mercato/ui/backend/confirm-dialog'\nimport {\n DictionaryValue,\n type CustomerDictionaryKind,\n type CustomerDictionaryMap,\n} from '../../../lib/dictionaries'\nimport {\n ensureCustomerDictionary,\n invalidateCustomerDictionary,\n} from '../../../components/detail/hooks/useCustomerDictionary'\nimport {\n useCustomFieldDefs,\n} from '@open-mercato/ui/backend/utils/customFieldDefs'\nimport {\n mapCustomFieldKindToFilterType,\n normalizeCustomFieldFilterOptions,\n supportsCustomFieldColumn,\n} from '@open-mercato/ui/backend/utils/customFieldColumns'\nimport { CollectionPreviewCell, normalizeCollectionLabels } from '../../../components/list/CollectionPreviewCell'\nimport { useAutoDiscoveredFields } from '@open-mercato/ui/backend/utils/useAutoDiscoveredFields'\nimport { useAdvancedFilterTree } from '@open-mercato/ui/backend/hooks/useAdvancedFilter'\nimport { AdvancedFilterPanel } from '@open-mercato/ui/backend/filters/AdvancedFilterPanel'\nimport { ActiveFilterChips } from '@open-mercato/ui/backend/filters/ActiveFilterChips'\nimport type { FilterPreset } from '@open-mercato/ui/backend/filters/QuickFilters'\nimport {\n ensureCurrentUserFilterOption,\n fetchAssignableStaffMembers,\n mapAssignableStaffToFilterOptions,\n} from '../../../components/detail/assignableStaff'\n\nfunction makeDealsPresets(): FilterPreset[] {\n return [\n {\n id: 'my-deals',\n labelKey: 'customers.deals.presets.myDeals',\n requiresUser: true,\n build: ({ userId }) => makeRuleTree({ field: 'owner_user_id', operator: 'is', value: userId }),\n },\n {\n id: 'closing-month',\n labelKey: 'customers.deals.presets.closingMonth',\n iconName: 'clock',\n build: ({ now }) => {\n const start = new Date(now.getFullYear(), now.getMonth(), 1).toISOString().slice(0, 10)\n const end = new Date(now.getFullYear(), now.getMonth() + 1, 0).toISOString().slice(0, 10)\n return makeRuleTree({ field: 'expected_close_at', operator: 'between', value: [start, end] })\n },\n },\n // The Deal entity has no dedicated \"at risk\" or health-score field \u2014 `customer_deals`\n // exposes only `status` (open/win/loose/closed/in_progress, dictionary-driven) and\n // `closure_outcome`. Rather than fabricate a mapping, the \"At risk\" preset is omitted\n // until the data model exposes a first-class signal.\n {\n id: 'won-quarter',\n labelKey: 'customers.deals.presets.wonQuarter',\n build: ({ now }) => {\n const quarter = Math.floor(now.getMonth() / 3)\n const start = new Date(now.getFullYear(), quarter * 3, 1).toISOString().slice(0, 10)\n return makeMultiRuleTree([\n { field: 'status', operator: 'is', value: 'win' },\n { field: 'expected_close_at', operator: 'is_after', value: start },\n ], 'and')\n },\n },\n ]\n}\n\ntype DealRow = {\n id: string\n title: string\n status?: string | null\n pipelineStage?: string | null\n pipelineStageId?: string | null\n pipelineId?: string | null\n valueAmount?: number | null\n valueCurrency?: string | null\n probability?: number | null\n expectedCloseAt?: string | null\n updatedAt?: string | null\n ownerUserId?: string | null\n companies: { id: string; label: string }[]\n people: { id: string; label: string }[]\n} & Record<string, unknown>\n\ntype DealsResponse = {\n items?: Array<Record<string, unknown>>\n total?: number\n totalPages?: number\n}\n\ntype FilterOption = { value: string; label: string }\ntype DictionaryOptionWithTone = AdvancedFilterOption & FilterOption\n\ntype DictionaryKey = Extract<CustomerDictionaryKind, 'deal-statuses' | 'pipeline-stages'>\n\nconst PAGE_SIZE = 20\nconst UUID_REGEX = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i\n\nfunction isUuid(value: string | null | undefined): value is string {\n if (!value) return false\n return UUID_REGEX.test(value.trim())\n}\n\nfunction normalizeIdCandidates(raw: Array<string>): string[] {\n const set = new Set<string>()\n raw.forEach((candidate) => {\n candidate\n .split(',')\n .map((part) => part.trim())\n .filter((part) => part.length > 0)\n .forEach((part) => {\n if (isUuid(part)) set.add(part)\n })\n })\n return Array.from(set)\n}\n\nfunction extractIdsFromParams(params: URLSearchParams | null | undefined, key: string): string[] {\n if (!params) return []\n const values = params.getAll(key)\n return normalizeIdCandidates(values)\n}\n\nfunction formatCurrency(amount: number | null | undefined, currency: string | null | undefined, fallback: string): string {\n if (typeof amount !== 'number' || Number.isNaN(amount)) return fallback\n try {\n if (currency && currency.trim().length) {\n const formatter = new Intl.NumberFormat(undefined, { style: 'currency', currency })\n return formatter.format(amount)\n }\n const formatter = new Intl.NumberFormat(undefined, { style: 'decimal', maximumFractionDigits: 2 })\n return formatter.format(amount)\n } catch {\n return currency ? `${amount} ${currency}` : String(amount)\n }\n}\n\nfunction formatDateValue(value: string | null | undefined, fallback: string): string {\n if (!value) return fallback\n const date = new Date(value)\n if (Number.isNaN(date.getTime())) return fallback\n return date.toLocaleDateString()\n}\n\nexport default function CustomersDealsPage() {\n const t = useT()\n const { confirm, ConfirmDialogElement } = useConfirmDialog()\n const router = useRouter()\n const pathname = usePathname()\n const searchParams = useSearchParams()\n const scopeVersion = useOrganizationScopeVersion()\n const queryClient = useQueryClient()\n\n const [rows, setRows] = React.useState<DealRow[]>([])\n const [page, setPage] = React.useState(() => {\n const raw = Number(searchParams?.get('page') ?? '1')\n return Number.isFinite(raw) && raw > 0 ? raw : 1\n })\n const [pageSize, setPageSize] = React.useState(PAGE_SIZE)\n const [sorting, setSorting] = React.useState<import('@tanstack/react-table').SortingState>([])\n const [total, setTotal] = React.useState(0)\n const [totalPages, setTotalPages] = React.useState(1)\n const [search, setSearch] = React.useState(() => searchParams?.get('search')?.trim() ?? '')\n const [isLoading, setIsLoading] = React.useState(false)\n const [reloadToken, setReloadToken] = React.useState(0)\n const [pendingDeleteId, setPendingDeleteId] = React.useState<string | null>(null)\n // One-shot URL hydration used as the hook's initial value. The hook is the\n // single source of truth from this point on \u2014 the page MUST NOT keep a\n // parallel `useState<AdvancedFilterTree>` (see spec \"Migration & Backward\n // Compatibility\" \u2192 state ownership).\n const initialFilterTree = React.useMemo<AdvancedFilterTree>(() => {\n if (!searchParams) return createEmptyTree()\n const record: Record<string, string> = {}\n searchParams.forEach((value, key) => {\n if (key.startsWith('filter[')) record[key] = value\n })\n const v2 = deserializeTree(record)\n if (v2) return v2\n const flat = deserializeAdvancedFilter(record)\n if (flat) return flatToTree(flat)\n return createEmptyTree()\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [])\n // `filterPanel` lives at the top of the component so derived state below\n // (URL params, data fetch, export config) can read `filterPanel.appliedTree`\n // directly. Real `FilterFieldDef[]` arrives later from `useAutoDiscoveredFields`\n // (it depends on columns) and is synced into the hook via a small effect at\n // the bottom of the component. The hook reads fields through a ref at\n // validation time only \u2014 first validation cannot fire before user input, by\n // which point fields have settled, so the empty initial value is safe.\n const [panelFields, setPanelFields] = React.useState<FilterFieldDef[]>([])\n const [filtersOpen, setFiltersOpen] = React.useState(false)\n const filtersTriggerRef = React.useRef<HTMLButtonElement | null>(null)\n const filterPanel = useAdvancedFilterTree({\n initial: initialFilterTree,\n fields: panelFields,\n onApply: () => setPage(1),\n })\n const advancedFilterState = filterPanel.appliedTree\n const handleAdvancedFilterClear = React.useCallback(() => {\n filterPanel.clear()\n setPage(1)\n }, [filterPanel])\n const [cacheStatus, setCacheStatus] = React.useState<'hit' | 'miss' | null>(null)\n\n const initialPersonIds = React.useMemo(\n () => extractIdsFromParams(searchParams, 'personId'),\n [searchParams],\n )\n const initialCompanyIds = React.useMemo(\n () => extractIdsFromParams(searchParams, 'companyId'),\n [searchParams],\n )\n\n const [selectedPersonIds, setSelectedPersonIds] = React.useState<string[]>(initialPersonIds)\n const [selectedCompanyIds, setSelectedCompanyIds] = React.useState<string[]>(initialCompanyIds)\n\n const [dictionaryMaps, setDictionaryMaps] = React.useState<Record<DictionaryKey, CustomerDictionaryMap>>({\n 'deal-statuses': {},\n 'pipeline-stages': {},\n })\n\n const [pipelineNames, setPipelineNames] = React.useState<Record<string, string>>({})\n\n const fetchDictionaryEntries = React.useCallback(\n async (kind: DictionaryKey) => {\n try {\n const data = await ensureCustomerDictionary(queryClient, kind, scopeVersion)\n setDictionaryMaps((prev) => ({ ...prev, [kind]: data.map }))\n } catch {\n setDictionaryMaps((prev) => ({ ...prev, [kind]: {} }))\n }\n },\n [queryClient, scopeVersion],\n )\n\n React.useEffect(() => {\n let cancelled = false\n async function loadDictionaries() {\n if (cancelled) return\n await Promise.all([fetchDictionaryEntries('deal-statuses'), fetchDictionaryEntries('pipeline-stages')])\n }\n loadDictionaries().catch(() => {})\n return () => { cancelled = true }\n }, [fetchDictionaryEntries, reloadToken])\n const dictionaryOptions = React.useMemo(() => {\n const toOptions = (map?: CustomerDictionaryMap | null): DictionaryOptionWithTone[] =>\n Object.values(map ?? {})\n .map((entry) => {\n const tone = mapDictionaryColorToTone(entry.color)\n const option: DictionaryOptionWithTone = { value: entry.value, label: entry.label }\n if (tone) option.tone = tone\n return option\n })\n .sort((a, b) => a.label.localeCompare(b.label, undefined, { sensitivity: 'base' }))\n return {\n dealStatuses: toOptions(dictionaryMaps['deal-statuses']),\n pipelineStages: toOptions(dictionaryMaps['pipeline-stages']),\n }\n }, [dictionaryMaps])\n\n React.useEffect(() => {\n let cancelled = false\n async function loadPipelines() {\n try {\n const call = await apiCall<{ items?: Array<{ id: string; name: string }> }>('/api/customers/pipelines')\n if (cancelled || !call.ok) return\n const items = Array.isArray(call.result?.items) ? call.result.items : []\n const map: Record<string, string> = {}\n items.forEach((p) => { if (p.id && p.name) map[p.id] = p.name })\n setPipelineNames(map)\n } catch (err) {\n console.warn('[customers.deals.list] failed to load pipelines', err)\n }\n }\n loadPipelines().catch((err) => {\n console.warn('[customers.deals.list] loadPipelines threw', err)\n })\n return () => { cancelled = true }\n }, [reloadToken, scopeVersion])\n\n const handleSearchChange = React.useCallback((value: string) => {\n setSearch(value.trim())\n setPage(1)\n }, [])\n\n const queryParams = React.useMemo(() => {\n const params = new URLSearchParams()\n params.set('page', String(page))\n params.set('pageSize', String(pageSize))\n if (sorting.length > 0) {\n params.set('sort', sorting[0].id)\n params.set('order', sorting[0].desc ? 'desc' : 'asc')\n }\n if (search.trim().length) params.set('search', search.trim())\n if (selectedPersonIds.length) params.set('personId', selectedPersonIds.join(','))\n if (selectedCompanyIds.length) params.set('companyId', selectedCompanyIds.join(','))\n const advancedParams = serializeTree(advancedFilterState)\n for (const [key, val] of Object.entries(advancedParams)) {\n params.set(key, val)\n }\n return params.toString()\n }, [advancedFilterState, page, pageSize, search, selectedCompanyIds, selectedPersonIds, sorting])\n\n const currentParams = React.useMemo(\n () => Object.fromEntries(new URLSearchParams(queryParams)),\n [queryParams],\n )\n\n const exportConfig = React.useMemo(() => ({\n view: {\n getUrl: (format: DataTableExportFormat) =>\n buildCrudExportUrl('customers/deals', { ...currentParams, exportScope: 'view' }, format),\n },\n full: {\n getUrl: (format: DataTableExportFormat) =>\n buildCrudExportUrl('customers/deals', { ...currentParams, exportScope: 'full', all: 'true' }, format),\n },\n }), [currentParams])\n\n React.useEffect(() => {\n let cancelled = false\n async function load() {\n setIsLoading(true)\n setCacheStatus(null)\n try {\n const fallback: DealsResponse = { items: [], total: 0, totalPages: 1 }\n const call = await apiCall<DealsResponse>(`/api/customers/deals?${queryParams}`, undefined, { fallback })\n if (!call.ok) {\n const message =\n typeof (call.result as { error?: string } | undefined)?.error === 'string'\n ? (call.result as { error?: string }).error!\n : t('customers.deals.list.error.load')\n flash(message, 'error')\n if (!cancelled) setCacheStatus(null)\n return\n }\n const payload = call.result ?? fallback\n if (cancelled) return\n setCacheStatus(call.cacheStatus ?? null)\n const items = Array.isArray(payload.items) ? payload.items : []\n const mapped = items\n .map((item) => mapDeal(item as Record<string, unknown>))\n .filter((row): row is DealRow => !!row)\n setRows(mapped)\n setTotal(typeof payload.total === 'number' ? payload.total : mapped.length)\n setTotalPages(typeof payload.totalPages === 'number' ? payload.totalPages : 1)\n } catch (err) {\n if (!cancelled) {\n setCacheStatus(null)\n const message = err instanceof Error ? err.message : t('customers.deals.list.error.load')\n flash(message, 'error')\n }\n } finally {\n if (!cancelled) setIsLoading(false)\n }\n }\n load()\n return () => { cancelled = true }\n }, [queryParams, reloadToken, scopeVersion, t])\n\n React.useEffect(() => {\n if (totalPages > 0 && page > totalPages) {\n setPage(totalPages)\n }\n }, [page, totalPages])\n\n const queryRef = React.useRef(searchParams?.toString() ?? '')\n React.useEffect(() => {\n if (!pathname) return\n const params = new URLSearchParams()\n if (search.trim().length) params.set('search', search.trim())\n if (selectedPersonIds.length) selectedPersonIds.forEach((id) => params.append('personId', id))\n if (selectedCompanyIds.length) selectedCompanyIds.forEach((id) => params.append('companyId', id))\n if (page > 1) params.set('page', String(page))\n const advancedParams = serializeTree(advancedFilterState)\n for (const [key, val] of Object.entries(advancedParams)) {\n params.set(key, val)\n }\n const next = params.toString()\n if (queryRef.current === next) return\n queryRef.current = next\n router.replace(next ? `${pathname}?${next}` : pathname, { scroll: false })\n }, [pathname, router, page, search, selectedPersonIds, selectedCompanyIds, advancedFilterState])\n\n const handleRefresh = React.useCallback(() => {\n void Promise.all([\n invalidateCustomerDictionary(queryClient, 'deal-statuses'),\n invalidateCustomerDictionary(queryClient, 'pipeline-stages'),\n ])\n setReloadToken((token) => token + 1)\n }, [queryClient])\n\n const bulkMutationContextId = 'customers-deals-list:bulk-delete'\n const { runMutation: runBulkMutation, retryLastMutation: retryBulkMutation } = useGuardedMutation<{\n formId: string\n resourceKind: string\n retryLastMutation: () => Promise<boolean>\n }>({\n contextId: bulkMutationContextId,\n blockedMessage: t('ui.forms.flash.saveBlocked', 'Save blocked by validation'),\n })\n const singleMutationContextId = 'customers-deals-list:single-delete'\n const { runMutation: runSingleMutation, retryLastMutation: retrySingleMutation } = useGuardedMutation<{\n formId: string\n resourceKind: string\n resourceId: string\n retryLastMutation: () => Promise<boolean>\n }>({\n contextId: singleMutationContextId,\n blockedMessage: t('ui.forms.flash.saveBlocked', 'Save blocked by validation'),\n })\n\n const handleDeleteDeal = React.useCallback(\n async (dealId: string) => {\n if (pendingDeleteId) return\n const confirmed = await confirm({\n title: t(\n 'customers.deals.list.deleteConfirm',\n 'Delete this deal? This action cannot be undone.',\n ),\n variant: 'destructive',\n })\n if (!confirmed) return\n setPendingDeleteId(dealId)\n try {\n await runSingleMutation({\n operation: async () => {\n await deleteCrud('customers/deals', {\n body: { id: dealId },\n errorMessage: t('customers.deals.list.deleteError', 'Failed to delete deal.'),\n })\n },\n context: {\n formId: singleMutationContextId,\n resourceKind: 'customers.deal',\n resourceId: dealId,\n retryLastMutation: retrySingleMutation,\n },\n })\n flash(t('customers.deals.list.deleteSuccess', 'Deal deleted.'), 'success')\n setRows((prev) => prev.filter((row) => row.id !== dealId))\n setTotal((prev) => Math.max(0, prev - 1))\n handleRefresh()\n } catch (err) {\n const message =\n err instanceof Error && err.message\n ? err.message\n : t('customers.deals.list.deleteError', 'Failed to delete deal.')\n flash(message, 'error')\n } finally {\n setPendingDeleteId(null)\n }\n },\n [confirm, handleRefresh, pendingDeleteId, retrySingleMutation, runSingleMutation, singleMutationContextId, t],\n )\n\n const handlePageSizeChange = React.useCallback((newSize: number) => {\n setPageSize(newSize)\n setPage(1)\n }, [])\n\n const handleBulkDelete = React.useCallback(async (selectedRows: DealRow[]) => {\n const confirmed = await confirm({\n title: t('customers.deals.list.bulkDelete.title', 'Delete {count} deals?', { count: selectedRows.length }),\n description: t('customers.deals.list.bulkDelete.description', 'This action cannot be undone.'),\n variant: 'destructive',\n })\n if (!confirmed) return false\n\n const { succeeded, failures } = await runBulkMutation({\n operation: async () =>\n runBulkDelete(\n selectedRows,\n async (row) => {\n await deleteCrud('customers/deals', {\n body: { id: row.id },\n errorMessage: t('customers.deals.list.deleteError', 'Failed to delete deal.'),\n })\n },\n {\n fallbackErrorMessage: t('customers.deals.list.deleteError', 'Failed to delete deal.'),\n logTag: 'customers.deals.list',\n },\n ),\n context: {\n formId: bulkMutationContextId,\n resourceKind: 'customers.deal',\n retryLastMutation: retryBulkMutation,\n },\n })\n\n if (succeeded.length > 0) {\n const succeededIds = new Set(succeeded.map((r) => r.id))\n setRows((prev) => prev.filter((r) => !succeededIds.has(r.id)))\n setTotal((prev) => Math.max(0, prev - succeeded.length))\n setReloadToken((prev) => prev + 1)\n if (succeeded.length > 1) {\n coalesceLastOperations(succeeded.length, {\n commandId: 'customers.deals.delete',\n actionLabel: t('customers.deals.list.bulkDelete.operationLabel', 'Delete {count} deals', { count: succeeded.length }),\n resourceKind: 'customers.deal',\n })\n }\n if (failures.length === 0) {\n flash(\n t('customers.deals.list.bulkDelete.success', '{count} deals deleted', { count: succeeded.length }),\n 'success',\n )\n } else {\n flash(\n t('customers.deals.list.bulkDelete.partial', '{deleted} of {total} deals deleted; {failed} failed', {\n deleted: succeeded.length,\n total: selectedRows.length,\n failed: failures.length,\n }),\n 'warning',\n )\n }\n }\n\n for (const group of groupBulkDeleteFailures(failures)) {\n const message = group.count === 1\n ? group.sampleMessage\n : t(\n 'customers.deals.list.bulkDelete.failedGroup',\n '{count} deals could not be deleted: {message}',\n { count: group.count, message: group.sampleMessage },\n )\n flash(message, 'error')\n }\n\n return succeeded.length > 0\n }, [bulkMutationContextId, confirm, retryBulkMutation, runBulkMutation, t])\n\n const { data: customFieldDefs = [] } = useCustomFieldDefs([E.customers.customer_deal], {\n keyExtras: [scopeVersion, reloadToken],\n })\n const currentUserId = useCurrentUserId()\n const [ownerFilterOptions, setOwnerFilterOptions] = React.useState<AdvancedFilterOption[]>([])\n React.useEffect(() => {\n const controller = new AbortController()\n let cancelled = false\n void fetchAssignableStaffMembers('', { pageSize: 100, signal: controller.signal })\n .then((items) => {\n if (!cancelled) setOwnerFilterOptions(mapAssignableStaffToFilterOptions(items))\n })\n .catch(() => {\n if (!cancelled) setOwnerFilterOptions([])\n })\n return () => {\n cancelled = true\n controller.abort()\n }\n }, [scopeVersion])\n const resolvedOwnerFilterOptions = React.useMemo(\n () => ensureCurrentUserFilterOption(\n ownerFilterOptions,\n currentUserId,\n t('customers.filters.currentUser', 'Current user'),\n ),\n [currentUserId, ownerFilterOptions, t],\n )\n const loadOwnerFilterOptions = React.useCallback(async (query?: string): Promise<AdvancedFilterOption[]> => {\n const items = await fetchAssignableStaffMembers(query ?? '', { pageSize: 100 })\n return mapAssignableStaffToFilterOptions(items)\n }, [])\n\n const columns = React.useMemo<ColumnDef<DealRow>[]>(() => {\n const noValue = <span className=\"text-muted-foreground text-sm\">{t('customers.deals.list.noValue')}</span>\n const renderDictionaryCell = (kind: DictionaryKey, value: string | null | undefined) => (\n <DictionaryValue\n value={value}\n map={dictionaryMaps[kind]}\n fallback={value ? <span className=\"text-sm\">{value}</span> : noValue}\n className=\"text-sm\"\n iconWrapperClassName=\"inline-flex h-6 w-6 items-center justify-center rounded border border-border bg-card\"\n iconClassName=\"h-4 w-4\"\n colorClassName=\"h-3 w-3 rounded-full\"\n />\n )\n const renderAssociationSummary = (\n items: { id: string; label: string }[],\n fallbackLabel: string,\n ) => {\n if (!items.length) return noValue\n const labels = normalizeCollectionLabels(\n items.map((entry) => (entry.label && entry.label.trim().length ? entry.label : fallbackLabel)),\n )\n if (!labels.length) return noValue\n return (\n <CollectionPreviewCell labels={labels} maxVisible={1} />\n )\n }\n\n const customColumns = customFieldDefs\n .filter((def) => supportsCustomFieldColumn(def))\n .map<ColumnDef<DealRow>>((def) => ({\n accessorKey: `cf_${def.key}`,\n header: def.label || def.key,\n meta: {\n columnChooserGroup: def.group?.title ?? 'Custom Fields',\n filterGroup: def.group?.title ?? 'Custom Fields',\n filterType: mapCustomFieldKindToFilterType(def.kind),\n filterOptions: normalizeCustomFieldFilterOptions(def.options),\n hidden: def.listVisible === false,\n maxWidth: '220px',\n },\n cell: ({ getValue }) => {\n const value = getValue()\n if (value == null) return noValue\n if (Array.isArray(value)) {\n const normalized = normalizeCollectionLabels(\n value\n .map((item) => {\n if (item == null) return ''\n if (typeof item === 'string') return item\n return String(item)\n }),\n )\n if (!normalized.length) return noValue\n return <CollectionPreviewCell labels={normalized} maxVisible={2} />\n }\n if (typeof value === 'boolean') {\n return (\n <span className=\"text-sm\">\n {value\n ? t('customers.deals.list.booleanYes', 'Yes')\n : t('customers.deals.list.booleanNo', 'No')}\n </span>\n )\n }\n const stringValue = typeof value === 'string' ? value.trim() : String(value)\n if (!stringValue) return noValue\n return <span className=\"text-sm\">{stringValue}</span>\n },\n }))\n\n return [\n {\n accessorKey: 'title',\n header: t('customers.deals.list.columns.title'),\n meta: {\n alwaysVisible: true,\n columnChooserGroup: 'Basic Info',\n filterKey: 'title',\n filterGroup: 'Deal',\n maxWidth: '280px',\n },\n cell: ({ row }) => <span className=\"font-medium text-sm\">{row.original.title}</span>,\n },\n {\n accessorKey: 'status',\n header: t('customers.deals.list.columns.status'),\n meta: {\n filterType: 'select' as const,\n filterOptions: dictionaryOptions.dealStatuses,\n columnChooserGroup: 'Basic Info',\n filterKey: 'status',\n filterGroup: 'Deal',\n },\n cell: ({ row }) => renderDictionaryCell('deal-statuses', row.original.status),\n },\n {\n accessorKey: 'pipelineStage',\n header: t('customers.deals.list.columns.pipelineStage'),\n meta: {\n filterType: 'select' as const,\n filterOptions: dictionaryOptions.pipelineStages,\n columnChooserGroup: 'Pipeline',\n filterKey: 'pipeline_stage',\n filterGroup: 'Deal',\n },\n cell: ({ row }) => renderDictionaryCell('pipeline-stages', row.original.pipelineStage),\n },\n {\n accessorKey: 'pipelineId',\n header: t('customers.deals.list.columns.pipeline', 'Pipeline'),\n meta: {\n columnChooserGroup: 'Pipeline',\n filterKey: 'pipeline_id',\n filterGroup: 'Deal',\n maxWidth: '220px',\n },\n cell: ({ row }) => {\n const name = row.original.pipelineId ? pipelineNames[row.original.pipelineId] : null\n return name ? <span className=\"text-sm\">{name}</span> : noValue\n },\n },\n {\n accessorKey: 'valueAmount',\n header: t('customers.deals.list.columns.value'),\n meta: {\n filterType: 'number' as const,\n columnChooserGroup: 'Financial',\n filterKey: 'value_amount',\n filterGroup: 'Deal',\n },\n cell: ({ row }) => (\n <span className=\"text-sm font-medium\">\n {formatCurrency(row.original.valueAmount ?? null, row.original.valueCurrency ?? null, t('customers.deals.list.noValue'))}\n </span>\n ),\n },\n {\n accessorKey: 'probability',\n header: t('customers.deals.list.columns.probability'),\n meta: {\n filterType: 'number' as const,\n columnChooserGroup: 'Financial',\n filterKey: 'probability',\n filterGroup: 'Deal',\n },\n cell: ({ row }) => {\n const value = row.original.probability\n if (typeof value === 'number' && Number.isFinite(value)) {\n return <span className=\"text-sm\">{`${Math.min(Math.max(value, 0), 100)}%`}</span>\n }\n return noValue\n },\n },\n {\n accessorKey: 'expectedCloseAt',\n header: t('customers.deals.list.columns.expectedClose'),\n meta: {\n columnChooserGroup: 'Dates',\n filterKey: 'expected_close_at',\n filterGroup: 'Activity',\n filterIconName: 'calendar',\n },\n cell: ({ row }) => (\n <span className=\"text-sm\">\n {formatDateValue(row.original.expectedCloseAt ?? null, t('customers.deals.list.noValue'))}\n </span>\n ),\n },\n {\n accessorKey: 'ownerUserId',\n header: t('customers.deals.list.columns.owner', 'Owner'),\n meta: {\n columnChooserGroup: 'CRM',\n filterType: 'select',\n filterOptions: resolvedOwnerFilterOptions,\n filterLoadOptions: loadOwnerFilterOptions,\n filterGroup: 'CRM',\n filterIconName: 'user-round',\n filterKey: 'owner_user_id',\n hidden: true,\n },\n cell: ({ row }) => row.original.ownerUserId ?? null,\n },\n {\n accessorKey: 'companies',\n header: t('customers.deals.list.columns.companies'),\n meta: {\n columnChooserGroup: 'Associations',\n filterable: false,\n filterGroup: 'CRM',\n filterIconName: 'building-2',\n maxWidth: '220px',\n tooltipContent: (row: DealRow) =>\n normalizeCollectionLabels(\n row.companies.map((entry) => (entry.label && entry.label.trim().length ? entry.label : t('customers.deals.list.unnamedCompany'))),\n ).join(', '),\n },\n cell: ({ row }) => renderAssociationSummary(row.original.companies, t('customers.deals.list.unnamedCompany')),\n },\n {\n accessorKey: 'people',\n header: t('customers.deals.list.columns.people'),\n meta: {\n columnChooserGroup: 'Associations',\n filterable: false,\n filterGroup: 'CRM',\n filterIconName: 'user-round',\n maxWidth: '220px',\n tooltipContent: (row: DealRow) =>\n normalizeCollectionLabels(\n row.people.map((entry) => (entry.label && entry.label.trim().length ? entry.label : t('customers.deals.list.unnamedPerson'))),\n ).join(', '),\n },\n cell: ({ row }) => renderAssociationSummary(row.original.people, t('customers.deals.list.unnamedPerson')),\n },\n {\n accessorKey: 'updatedAt',\n header: t('customers.deals.list.columns.updatedAt'),\n meta: {\n columnChooserGroup: 'Dates',\n filterKey: 'updated_at',\n filterGroup: 'Activity',\n filterIconName: 'calendar',\n },\n cell: ({ row }) => (\n <span className=\"text-sm\">\n {formatDateValue(row.original.updatedAt ?? null, t('customers.deals.list.noValue'))}\n </span>\n ),\n },\n ...customColumns,\n ]\n }, [customFieldDefs, dictionaryMaps, dictionaryOptions, loadOwnerFilterOptions, pipelineNames, resolvedOwnerFilterOptions, t])\n\n const { advancedFilterFields } = useAutoDiscoveredFields({ columns, customFieldDefs })\n\n // Sync auto-discovered fields into the `filterPanel` declared at the top of\n // the component. See the comment on the `panelFields` state for why this\n // late-binding is safe. Bail out by content (field-key list) \u2014 every render\n // of `useAutoDiscoveredFields` produces fresh `FilterFieldDef` object refs\n // even when the set of fields hasn't actually changed, so a naive reference\n // setState would loop (\"Maximum update depth exceeded\").\n React.useEffect(() => {\n setPanelFields((prev) => {\n if (prev === advancedFilterFields) return prev\n if (prev.length === advancedFilterFields.length) {\n let same = true\n for (let i = 0; i < prev.length; i++) {\n if (prev[i].key !== advancedFilterFields[i].key) { same = false; break }\n }\n if (same) return prev\n }\n return advancedFilterFields\n })\n }, [advancedFilterFields])\n\n const associationFilterFields = React.useMemo<FilterFieldDef[]>(() => {\n const personLabels = new Map<string, string>()\n const companyLabels = new Map<string, string>()\n for (const row of rows) {\n for (const person of row.people) {\n if (selectedPersonIds.includes(person.id) && person.label.trim().length > 0) {\n personLabels.set(person.id, person.label)\n }\n }\n for (const company of row.companies) {\n if (selectedCompanyIds.includes(company.id) && company.label.trim().length > 0) {\n companyLabels.set(company.id, company.label)\n }\n }\n }\n return [\n {\n key: 'people',\n label: t('customers.deals.list.columns.people', 'People'),\n type: 'select',\n options: selectedPersonIds.map((id) => ({ value: id, label: personLabels.get(id) ?? id })),\n },\n {\n key: 'companies',\n label: t('customers.deals.list.columns.companies', 'Companies'),\n type: 'select',\n options: selectedCompanyIds.map((id) => ({ value: id, label: companyLabels.get(id) ?? id })),\n },\n ]\n }, [rows, selectedCompanyIds, selectedPersonIds, t])\n const associationFilterTree = React.useMemo<AdvancedFilterTree>(() => {\n const rules: Array<{ field: string; operator: 'is_any_of'; value: string[] }> = []\n if (selectedPersonIds.length) rules.push({ field: 'people', operator: 'is_any_of', value: selectedPersonIds })\n if (selectedCompanyIds.length) rules.push({ field: 'companies', operator: 'is_any_of', value: selectedCompanyIds })\n return rules.length ? makeMultiRuleTree(rules) : createEmptyTree()\n }, [selectedCompanyIds, selectedPersonIds])\n const handleAssociationFilterRemove = React.useCallback((nodeId: string) => {\n const node = associationFilterTree.root.children.find((child) => child.id === nodeId)\n if (!node || node.type !== 'rule') return\n if (node.field === 'people') setSelectedPersonIds([])\n if (node.field === 'companies') setSelectedCompanyIds([])\n setPage(1)\n }, [associationFilterTree.root.children])\n\n const dealsPresets = React.useMemo<FilterPreset[]>(() => makeDealsPresets(), [])\n\n return (\n <Page>\n <PageBody>\n <DataTable<DealRow>\n stickyFirstColumn\n stickyActionsColumn\n title={t('customers.deals.list.title')}\n actions={(\n <Button asChild>\n <Link href=\"/backend/customers/deals/create\">\n {t('customers.deals.list.actions.new', 'New deal')}\n </Link>\n </Button>\n )}\n columns={columns}\n columnChooser={{ auto: true }}\n data={rows}\n onRowClick={(row) => {\n router.push(`/backend/customers/deals/${row.id}`)\n }}\n rowActions={(row) => {\n const isDeleting = pendingDeleteId === row.id\n return (\n <RowActions\n items={[\n {\n id: 'edit',\n label: t('customers.deals.list.actions.edit', 'Edit'),\n onSelect: () => { router.push(`/backend/customers/deals/${row.id}`) },\n },\n {\n id: 'open-new-tab',\n label: t('customers.deals.list.actions.openInNewTab', 'Open in new tab'),\n onSelect: () => {\n if (typeof window !== 'undefined') {\n window.open(`/backend/customers/deals/${row.id}`, '_blank', 'noopener')\n }\n },\n },\n {\n id: 'delete',\n label: isDeleting\n ? t('customers.deals.list.actions.deleting', 'Deleting\u2026')\n : t('customers.deals.list.actions.delete', 'Delete'),\n destructive: true,\n onSelect: () => handleDeleteDeal(row.id),\n },\n ]}\n />\n )\n }}\n sortable\n sorting={sorting}\n onSortingChange={setSorting}\n bulkActions={[\n {\n id: 'delete',\n label: t('customers.deals.list.actions.delete', 'Delete'),\n destructive: true,\n onExecute: handleBulkDelete,\n },\n ]}\n searchValue={search}\n onSearchChange={handleSearchChange}\n searchPlaceholder={t('customers.deals.list.searchPlaceholder')}\n pagination={{\n page,\n pageSize,\n total,\n totalPages,\n onPageChange: (nextPage) => setPage(nextPage),\n pageSizeOptions: [10, 25, 50, 100],\n onPageSizeChange: handlePageSizeChange,\n cacheStatus,\n }}\n isLoading={isLoading}\n refreshButton={{\n label: t('customers.deals.list.refresh'),\n onRefresh: handleRefresh,\n }}\n exporter={exportConfig}\n entityId={E.customers.customer_deal}\n perspective={{ tableId: 'customers.deals.list' }}\n advancedFilter={{\n auto: true,\n value: filterPanel.tree,\n onChange: filterPanel.setTree,\n onApply: () => filterPanel.flush(),\n onClear: handleAdvancedFilterClear,\n triggerRef: filtersTriggerRef,\n externalPopover: true,\n onTriggerClick: () => setFiltersOpen((prev) => !prev),\n onApplyTree: (tree) => {\n filterPanel.replaceTree(tree)\n setPage(1)\n },\n }}\n activeFilterChips={(\n <>\n <ActiveFilterChips\n tree={associationFilterTree}\n fields={associationFilterFields}\n popoverOpen={filtersOpen}\n onRemoveNode={handleAssociationFilterRemove}\n onOpen={() => setFiltersOpen(true)}\n />\n <ActiveFilterChips\n tree={filterPanel.tree}\n fields={advancedFilterFields}\n popoverOpen={filtersOpen}\n onRemoveNode={(id) => filterPanel.dispatch({ type: 'removeNode', nodeId: id })}\n onOpen={() => setFiltersOpen(true)}\n />\n </>\n )}\n filterAwareEmptyState={{\n active: advancedFilterState.root.children.length > 0,\n entityNamePlural: t('customers.deals.entityPlural', 'deals'),\n canRemoveLast: filterPanel.tree.root.children.length > 0,\n onClearAll: handleAdvancedFilterClear,\n onRemoveLast: () => filterPanel.dispatch({ type: 'removeLast' }),\n }}\n virtualized\n />\n <AdvancedFilterPanel\n fields={advancedFilterFields}\n value={filterPanel.tree}\n onChange={filterPanel.setTree}\n onApply={filterPanel.flush}\n onClear={handleAdvancedFilterClear}\n onFlush={filterPanel.flush}\n pendingErrors={filterPanel.pendingErrors}\n userId={currentUserId}\n presets={dealsPresets}\n open={filtersOpen}\n onOpenChange={setFiltersOpen}\n triggerRef={filtersTriggerRef}\n savedFilterStorageKey=\"customers.deals.list\"\n />\n </PageBody>\n {ConfirmDialogElement}\n </Page>\n )\n}\n\nfunction mapDeal(item: Record<string, unknown>): DealRow | null {\n const id = typeof item.id === 'string' ? item.id : null\n if (!id) return null\n const title = typeof item.title === 'string' ? item.title : ''\n const status = typeof item.status === 'string' ? item.status : null\n const pipelineStage = typeof item.pipeline_stage === 'string' ? item.pipeline_stage : null\n const pipelineStageId = typeof item.pipeline_stage_id === 'string' ? item.pipeline_stage_id : null\n const pipelineId = typeof item.pipeline_id === 'string' ? item.pipeline_id : null\n const valueAmountRaw = item.value_amount\n const valueAmount =\n typeof valueAmountRaw === 'number'\n ? valueAmountRaw\n : typeof valueAmountRaw === 'string' && valueAmountRaw.trim()\n ? Number(valueAmountRaw)\n : null\n const valueCurrency =\n typeof item.value_currency === 'string' && item.value_currency.trim().length\n ? item.value_currency.trim().toUpperCase()\n : null\n const probabilityRaw = item.probability\n const probability =\n typeof probabilityRaw === 'number'\n ? probabilityRaw\n : typeof probabilityRaw === 'string' && probabilityRaw.trim().length\n ? Number(probabilityRaw)\n : null\n const expectedCloseAt = typeof item.expected_close_at === 'string' ? item.expected_close_at : null\n const updatedAt = typeof item.updated_at === 'string' ? item.updated_at : null\n const ownerUserId = typeof item.owner_user_id === 'string' ? item.owner_user_id : null\n const peopleRaw = Array.isArray(item.people) ? item.people : []\n const companiesRaw = Array.isArray(item.companies) ? item.companies : []\n const people = peopleRaw\n .map((entry) => {\n if (!entry || typeof entry !== 'object') return null\n const data = entry as Record<string, unknown>\n const pid = typeof data.id === 'string' ? data.id : null\n if (!pid) return null\n const label = typeof data.label === 'string' ? data.label : ''\n return { id: pid, label }\n })\n .filter((entry): entry is { id: string; label: string } => !!entry)\n const companies = companiesRaw\n .map((entry) => {\n if (!entry || typeof entry !== 'object') return null\n const data = entry as Record<string, unknown>\n const cid = typeof data.id === 'string' ? data.id : null\n if (!cid) return null\n const label = typeof data.label === 'string' ? data.label : ''\n return { id: cid, label }\n })\n .filter((entry): entry is { id: string; label: string } => !!entry)\n const customFields: Record<string, unknown> = {}\n for (const [key, value] of Object.entries(item)) {\n if (key.startsWith('cf_')) customFields[key] = value\n }\n return withDataTableNamespaces({\n id,\n title,\n status,\n pipelineStage,\n pipelineStageId,\n pipelineId,\n valueAmount,\n valueCurrency,\n probability,\n expectedCloseAt,\n updatedAt,\n ownerUserId,\n people,\n companies,\n ...customFields,\n }, item)\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["formatter"]
7
7
  }