@open-mercato/core 0.6.8-develop.7030.1.b84302d973 → 0.6.8-develop.7032.1.70d74d4bfe

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 (239) hide show
  1. package/dist/modules/api_keys/backend/api-keys/page.js +3 -1
  2. package/dist/modules/api_keys/backend/api-keys/page.js.map +2 -2
  3. package/dist/modules/attachments/components/AttachmentLibrary.js +2 -0
  4. package/dist/modules/attachments/components/AttachmentLibrary.js.map +2 -2
  5. package/dist/modules/audit_logs/backend/audit-logs/page.js +6 -0
  6. package/dist/modules/audit_logs/backend/audit-logs/page.js.map +2 -2
  7. package/dist/modules/auth/backend/roles/page.js +3 -1
  8. package/dist/modules/auth/backend/roles/page.js.map +2 -2
  9. package/dist/modules/auth/backend/users/page.js +2 -1
  10. package/dist/modules/auth/backend/users/page.js.map +2 -2
  11. package/dist/modules/business_rules/backend/logs/page.js +3 -1
  12. package/dist/modules/business_rules/backend/logs/page.js.map +2 -2
  13. package/dist/modules/business_rules/backend/rules/page.js +3 -1
  14. package/dist/modules/business_rules/backend/rules/page.js.map +2 -2
  15. package/dist/modules/business_rules/backend/sets/page.js +3 -1
  16. package/dist/modules/business_rules/backend/sets/page.js.map +2 -2
  17. package/dist/modules/business_rules/lib/expression-evaluator.js +9 -9
  18. package/dist/modules/business_rules/lib/expression-evaluator.js.map +2 -2
  19. package/dist/modules/business_rules/lib/rule-evaluator.js +10 -9
  20. package/dist/modules/business_rules/lib/rule-evaluator.js.map +2 -2
  21. package/dist/modules/catalog/ai-agents.js +1 -1
  22. package/dist/modules/catalog/ai-agents.js.map +1 -1
  23. package/dist/modules/catalog/ai-tools/merchandising-pack.js +2 -2
  24. package/dist/modules/catalog/ai-tools/merchandising-pack.js.map +2 -2
  25. package/dist/modules/catalog/backend/catalog/products/MerchandisingAssistantSheet.js +5 -2
  26. package/dist/modules/catalog/backend/catalog/products/MerchandisingAssistantSheet.js.map +2 -2
  27. package/dist/modules/catalog/components/categories/CategoriesDataTable.js +2 -0
  28. package/dist/modules/catalog/components/categories/CategoriesDataTable.js.map +2 -2
  29. package/dist/modules/catalog/components/products/ProductsDataTable.js +7 -1
  30. package/dist/modules/catalog/components/products/ProductsDataTable.js.map +2 -2
  31. package/dist/modules/catalog/widgets/injection/merchandising-assistant-trigger/widget.client.js +2 -0
  32. package/dist/modules/catalog/widgets/injection/merchandising-assistant-trigger/widget.client.js.map +2 -2
  33. package/dist/modules/communication_channels/backend/communication_channels/channels/page.js +3 -0
  34. package/dist/modules/communication_channels/backend/communication_channels/channels/page.js.map +2 -2
  35. package/dist/modules/configs/lib/system-status.js +9 -0
  36. package/dist/modules/configs/lib/system-status.js.map +2 -2
  37. package/dist/modules/currencies/backend/currencies/page.js +3 -1
  38. package/dist/modules/currencies/backend/currencies/page.js.map +2 -2
  39. package/dist/modules/currencies/backend/exchange-rates/page.js +3 -1
  40. package/dist/modules/currencies/backend/exchange-rates/page.js.map +2 -2
  41. package/dist/modules/customer_accounts/backend/customer_accounts/roles/page.js +3 -1
  42. package/dist/modules/customer_accounts/backend/customer_accounts/roles/page.js.map +2 -2
  43. package/dist/modules/customer_accounts/backend/customer_accounts/users/page.js +3 -1
  44. package/dist/modules/customer_accounts/backend/customer_accounts/users/page.js.map +2 -2
  45. package/dist/modules/customers/ai-tools/companies-pack.js +4 -1
  46. package/dist/modules/customers/ai-tools/companies-pack.js.map +2 -2
  47. package/dist/modules/customers/ai-tools/deals-pack.js +4 -1
  48. package/dist/modules/customers/ai-tools/deals-pack.js.map +2 -2
  49. package/dist/modules/customers/ai-tools/people-pack.js +4 -1
  50. package/dist/modules/customers/ai-tools/people-pack.js.map +2 -2
  51. package/dist/modules/customers/api/deals/map/route.js +2 -1
  52. package/dist/modules/customers/api/deals/map/route.js.map +2 -2
  53. package/dist/modules/customers/backend/customers/companies/page.js +3 -1
  54. package/dist/modules/customers/backend/customers/companies/page.js.map +2 -2
  55. package/dist/modules/customers/backend/customers/deals/page.js +5 -2
  56. package/dist/modules/customers/backend/customers/deals/page.js.map +2 -2
  57. package/dist/modules/customers/backend/customers/people/page.js +3 -1
  58. package/dist/modules/customers/backend/customers/people/page.js.map +2 -2
  59. package/dist/modules/customers/components/CustomerTodosTable.js +1 -0
  60. package/dist/modules/customers/components/CustomerTodosTable.js.map +2 -2
  61. package/dist/modules/data_sync/backend/data-sync/page.js +3 -1
  62. package/dist/modules/data_sync/backend/data-sync/page.js.map +2 -2
  63. package/dist/modules/devices/backend/devices/page.js +3 -1
  64. package/dist/modules/devices/backend/devices/page.js.map +2 -2
  65. package/dist/modules/directory/backend/directory/organizations/page.js +2 -1
  66. package/dist/modules/directory/backend/directory/organizations/page.js.map +2 -2
  67. package/dist/modules/directory/backend/directory/tenants/page.js +2 -1
  68. package/dist/modules/directory/backend/directory/tenants/page.js.map +2 -2
  69. package/dist/modules/entities/api/records.js +4 -2
  70. package/dist/modules/entities/api/records.js.map +2 -2
  71. package/dist/modules/entities/backend/entities/user/[entityId]/records/page.js +3 -1
  72. package/dist/modules/entities/backend/entities/user/[entityId]/records/page.js.map +2 -2
  73. package/dist/modules/eudr/backend/eudr/evidence-submissions/page.js +3 -0
  74. package/dist/modules/eudr/backend/eudr/evidence-submissions/page.js.map +2 -2
  75. package/dist/modules/eudr/backend/eudr/plots/page.js +3 -0
  76. package/dist/modules/eudr/backend/eudr/plots/page.js.map +2 -2
  77. package/dist/modules/eudr/backend/eudr/product-mappings/page.js +3 -0
  78. package/dist/modules/eudr/backend/eudr/product-mappings/page.js.map +2 -2
  79. package/dist/modules/eudr/backend/eudr/risk-assessments/page.js +3 -0
  80. package/dist/modules/eudr/backend/eudr/risk-assessments/page.js.map +2 -2
  81. package/dist/modules/eudr/backend/eudr/statements/page.js +3 -0
  82. package/dist/modules/eudr/backend/eudr/statements/page.js.map +2 -2
  83. package/dist/modules/feature_toggles/components/FeatureTogglesTable.js +1 -0
  84. package/dist/modules/feature_toggles/components/FeatureTogglesTable.js.map +2 -2
  85. package/dist/modules/feature_toggles/components/OverridesTable.js +1 -0
  86. package/dist/modules/feature_toggles/components/OverridesTable.js.map +2 -2
  87. package/dist/modules/inbox_ops/backend/inbox-ops/log/page.js +3 -0
  88. package/dist/modules/inbox_ops/backend/inbox-ops/log/page.js.map +2 -2
  89. package/dist/modules/inbox_ops/backend/inbox-ops/page.js +3 -0
  90. package/dist/modules/inbox_ops/backend/inbox-ops/page.js.map +2 -2
  91. package/dist/modules/messages/components/MessagesInboxPageClient.js +4 -1
  92. package/dist/modules/messages/components/MessagesInboxPageClient.js.map +2 -2
  93. package/dist/modules/payment_gateways/backend/payment-gateways/page.js +3 -1
  94. package/dist/modules/payment_gateways/backend/payment-gateways/page.js.map +2 -2
  95. package/dist/modules/planner/backend/planner/availability-rulesets/page.js +3 -0
  96. package/dist/modules/planner/backend/planner/availability-rulesets/page.js.map +2 -2
  97. package/dist/modules/push_notifications/backend/push_notifications/page.js +3 -1
  98. package/dist/modules/push_notifications/backend/push_notifications/page.js.map +2 -2
  99. package/dist/modules/query_index/lib/engine.js +108 -48
  100. package/dist/modules/query_index/lib/engine.js.map +2 -2
  101. package/dist/modules/resources/backend/resources/resource-types/page.js +3 -1
  102. package/dist/modules/resources/backend/resources/resource-types/page.js.map +2 -2
  103. package/dist/modules/resources/backend/resources/resources/page.js +3 -1
  104. package/dist/modules/resources/backend/resources/resources/page.js.map +2 -2
  105. package/dist/modules/sales/backend/sales/channels/offers/page.js +3 -0
  106. package/dist/modules/sales/backend/sales/channels/offers/page.js.map +2 -2
  107. package/dist/modules/sales/backend/sales/channels/page.js +3 -0
  108. package/dist/modules/sales/backend/sales/channels/page.js.map +2 -2
  109. package/dist/modules/sales/components/channels/SalesChannelOffersPanel.js +3 -0
  110. package/dist/modules/sales/components/channels/SalesChannelOffersPanel.js.map +2 -2
  111. package/dist/modules/sales/components/documents/SalesDocumentsTable.js +4 -0
  112. package/dist/modules/sales/components/documents/SalesDocumentsTable.js.map +2 -2
  113. package/dist/modules/staff/backend/staff/leave-requests/page.js +3 -0
  114. package/dist/modules/staff/backend/staff/leave-requests/page.js.map +2 -2
  115. package/dist/modules/staff/backend/staff/my-leave-requests/page.js +3 -0
  116. package/dist/modules/staff/backend/staff/my-leave-requests/page.js.map +2 -2
  117. package/dist/modules/staff/backend/staff/team-members/page.js +3 -0
  118. package/dist/modules/staff/backend/staff/team-members/page.js.map +2 -2
  119. package/dist/modules/staff/backend/staff/team-roles/page.js +3 -0
  120. package/dist/modules/staff/backend/staff/team-roles/page.js.map +2 -2
  121. package/dist/modules/staff/backend/staff/teams/[id]/edit/page.js +3 -0
  122. package/dist/modules/staff/backend/staff/teams/[id]/edit/page.js.map +2 -2
  123. package/dist/modules/staff/backend/staff/teams/page.js +3 -0
  124. package/dist/modules/staff/backend/staff/teams/page.js.map +2 -2
  125. package/dist/modules/staff/backend/staff/timesheets/projects/page.js +3 -0
  126. package/dist/modules/staff/backend/staff/timesheets/projects/page.js.map +2 -2
  127. package/dist/modules/warranty_claims/backend/page.js +3 -0
  128. package/dist/modules/warranty_claims/backend/page.js.map +2 -2
  129. package/dist/modules/warranty_claims/backend/warranty_claims/registrations/page.js +3 -0
  130. package/dist/modules/warranty_claims/backend/warranty_claims/registrations/page.js.map +2 -2
  131. package/dist/modules/warranty_claims/backend/warranty_claims/troubleshooting-guides/page.js +3 -0
  132. package/dist/modules/warranty_claims/backend/warranty_claims/troubleshooting-guides/page.js.map +2 -2
  133. package/dist/modules/warranty_claims/backend/warranty_claims/vendor-policies/page.js +3 -0
  134. package/dist/modules/warranty_claims/backend/warranty_claims/vendor-policies/page.js.map +2 -2
  135. package/dist/modules/warranty_claims/frontend/[orgSlug]/portal/claims/page.js +3 -0
  136. package/dist/modules/warranty_claims/frontend/[orgSlug]/portal/claims/page.js.map +2 -2
  137. package/dist/modules/wms/components/backend/WmsConfigurationPage.js +4 -0
  138. package/dist/modules/wms/components/backend/WmsConfigurationPage.js.map +2 -2
  139. package/dist/modules/wms/components/backend/WmsInventoryConsolePage.js +1 -0
  140. package/dist/modules/wms/components/backend/WmsInventoryConsolePage.js.map +2 -2
  141. package/dist/modules/wms/components/backend/WmsLotsListPage.js +1 -0
  142. package/dist/modules/wms/components/backend/WmsLotsListPage.js.map +2 -2
  143. package/dist/modules/wms/components/backend/inventoryMutationLoaders.js +27 -20
  144. package/dist/modules/wms/components/backend/inventoryMutationLoaders.js.map +2 -2
  145. package/dist/modules/workflows/backend/definitions/page.js +3 -1
  146. package/dist/modules/workflows/backend/definitions/page.js.map +2 -2
  147. package/dist/modules/workflows/backend/events/page.js +3 -1
  148. package/dist/modules/workflows/backend/events/page.js.map +2 -2
  149. package/dist/modules/workflows/backend/instances/page.js +3 -1
  150. package/dist/modules/workflows/backend/instances/page.js.map +2 -2
  151. package/dist/modules/workflows/backend/tasks/page.js +3 -1
  152. package/dist/modules/workflows/backend/tasks/page.js.map +2 -2
  153. package/package.json +7 -7
  154. package/src/modules/api_keys/backend/api-keys/page.tsx +4 -1
  155. package/src/modules/attachments/components/AttachmentLibrary.tsx +3 -0
  156. package/src/modules/audit_logs/backend/audit-logs/page.tsx +8 -0
  157. package/src/modules/auth/backend/roles/page.tsx +4 -2
  158. package/src/modules/auth/backend/users/page.tsx +3 -2
  159. package/src/modules/business_rules/backend/logs/page.tsx +4 -1
  160. package/src/modules/business_rules/backend/rules/page.tsx +4 -1
  161. package/src/modules/business_rules/backend/sets/page.tsx +4 -1
  162. package/src/modules/business_rules/lib/expression-evaluator.ts +9 -9
  163. package/src/modules/business_rules/lib/rule-evaluator.ts +10 -9
  164. package/src/modules/catalog/ai-agents.ts +1 -1
  165. package/src/modules/catalog/ai-tools/merchandising-pack.ts +2 -2
  166. package/src/modules/catalog/backend/catalog/products/MerchandisingAssistantSheet.tsx +12 -5
  167. package/src/modules/catalog/components/categories/CategoriesDataTable.tsx +3 -0
  168. package/src/modules/catalog/components/products/ProductsDataTable.tsx +7 -0
  169. package/src/modules/catalog/i18n/de.json +1 -0
  170. package/src/modules/catalog/i18n/en.json +1 -0
  171. package/src/modules/catalog/i18n/es.json +1 -0
  172. package/src/modules/catalog/i18n/ko.json +1 -0
  173. package/src/modules/catalog/i18n/pl.json +1 -0
  174. package/src/modules/catalog/widgets/injection/merchandising-assistant-trigger/widget.client.tsx +4 -0
  175. package/src/modules/communication_channels/backend/communication_channels/channels/page.tsx +4 -0
  176. package/src/modules/configs/i18n/de.json +2 -0
  177. package/src/modules/configs/i18n/en.json +2 -0
  178. package/src/modules/configs/i18n/es.json +2 -0
  179. package/src/modules/configs/i18n/ko.json +2 -0
  180. package/src/modules/configs/i18n/pl.json +2 -0
  181. package/src/modules/configs/lib/system-status.ts +9 -0
  182. package/src/modules/currencies/backend/currencies/page.tsx +4 -1
  183. package/src/modules/currencies/backend/exchange-rates/page.tsx +4 -1
  184. package/src/modules/customer_accounts/backend/customer_accounts/roles/page.tsx +4 -1
  185. package/src/modules/customer_accounts/backend/customer_accounts/users/page.tsx +4 -1
  186. package/src/modules/customers/ai-tools/companies-pack.ts +4 -1
  187. package/src/modules/customers/ai-tools/deals-pack.ts +4 -1
  188. package/src/modules/customers/ai-tools/people-pack.ts +4 -1
  189. package/src/modules/customers/api/deals/map/route.ts +1 -0
  190. package/src/modules/customers/backend/customers/companies/page.tsx +4 -1
  191. package/src/modules/customers/backend/customers/deals/page.tsx +8 -2
  192. package/src/modules/customers/backend/customers/people/page.tsx +4 -1
  193. package/src/modules/customers/components/CustomerTodosTable.tsx +2 -0
  194. package/src/modules/data_sync/backend/data-sync/page.tsx +4 -1
  195. package/src/modules/devices/backend/devices/page.tsx +4 -1
  196. package/src/modules/directory/backend/directory/organizations/page.tsx +3 -1
  197. package/src/modules/directory/backend/directory/tenants/page.tsx +3 -1
  198. package/src/modules/entities/api/records.ts +2 -0
  199. package/src/modules/entities/backend/entities/user/[entityId]/records/page.tsx +4 -1
  200. package/src/modules/eudr/backend/eudr/evidence-submissions/page.tsx +4 -0
  201. package/src/modules/eudr/backend/eudr/plots/page.tsx +4 -0
  202. package/src/modules/eudr/backend/eudr/product-mappings/page.tsx +4 -0
  203. package/src/modules/eudr/backend/eudr/risk-assessments/page.tsx +4 -0
  204. package/src/modules/eudr/backend/eudr/statements/page.tsx +4 -0
  205. package/src/modules/feature_toggles/components/FeatureTogglesTable.tsx +2 -1
  206. package/src/modules/feature_toggles/components/OverridesTable.tsx +2 -1
  207. package/src/modules/inbox_ops/backend/inbox-ops/log/page.tsx +4 -0
  208. package/src/modules/inbox_ops/backend/inbox-ops/page.tsx +4 -0
  209. package/src/modules/messages/components/MessagesInboxPageClient.tsx +4 -0
  210. package/src/modules/payment_gateways/backend/payment-gateways/page.tsx +4 -1
  211. package/src/modules/planner/backend/planner/availability-rulesets/page.tsx +4 -0
  212. package/src/modules/push_notifications/backend/push_notifications/page.tsx +4 -1
  213. package/src/modules/query_index/lib/engine.ts +156 -53
  214. package/src/modules/resources/backend/resources/resource-types/page.tsx +4 -1
  215. package/src/modules/resources/backend/resources/resources/page.tsx +4 -1
  216. package/src/modules/sales/backend/sales/channels/offers/page.tsx +4 -0
  217. package/src/modules/sales/backend/sales/channels/page.tsx +4 -0
  218. package/src/modules/sales/components/channels/SalesChannelOffersPanel.tsx +4 -0
  219. package/src/modules/sales/components/documents/SalesDocumentsTable.tsx +5 -0
  220. package/src/modules/staff/backend/staff/leave-requests/page.tsx +4 -0
  221. package/src/modules/staff/backend/staff/my-leave-requests/page.tsx +4 -0
  222. package/src/modules/staff/backend/staff/team-members/page.tsx +6 -0
  223. package/src/modules/staff/backend/staff/team-roles/page.tsx +4 -0
  224. package/src/modules/staff/backend/staff/teams/[id]/edit/page.tsx +4 -0
  225. package/src/modules/staff/backend/staff/teams/page.tsx +4 -0
  226. package/src/modules/staff/backend/staff/timesheets/projects/page.tsx +4 -0
  227. package/src/modules/warranty_claims/backend/page.tsx +4 -0
  228. package/src/modules/warranty_claims/backend/warranty_claims/registrations/page.tsx +4 -0
  229. package/src/modules/warranty_claims/backend/warranty_claims/troubleshooting-guides/page.tsx +4 -0
  230. package/src/modules/warranty_claims/backend/warranty_claims/vendor-policies/page.tsx +4 -0
  231. package/src/modules/warranty_claims/frontend/[orgSlug]/portal/claims/page.tsx +4 -0
  232. package/src/modules/wms/components/backend/WmsConfigurationPage.tsx +5 -0
  233. package/src/modules/wms/components/backend/WmsInventoryConsolePage.tsx +2 -0
  234. package/src/modules/wms/components/backend/WmsLotsListPage.tsx +2 -0
  235. package/src/modules/wms/components/backend/inventoryMutationLoaders.ts +36 -20
  236. package/src/modules/workflows/backend/definitions/page.tsx +4 -1
  237. package/src/modules/workflows/backend/events/page.tsx +4 -1
  238. package/src/modules/workflows/backend/instances/page.tsx +4 -1
  239. package/src/modules/workflows/backend/tasks/page.tsx +4 -1
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../src/modules/catalog/components/products/ProductsDataTable.tsx"],
4
- "sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport { extensionPoints } from '@open-mercato/core/modules/catalog/extension-points'\nimport Link from 'next/link'\nimport type { LegacyColumnDef as ColumnDef } from '@tanstack/react-table/legacy'\nimport type { SortingState } from '@tanstack/react-table'\nimport { DataTable, type DataTableExportFormat } from '@open-mercato/ui/backend/DataTable'\nimport { ListEmptyState } from '@open-mercato/ui/backend/filters/ListEmptyState'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { RowActions } from '@open-mercato/ui/backend/RowActions'\nimport { apiCall, readApiResultOrThrow, withScopedApiRequestHeaders } from '@open-mercato/ui/backend/utils/apiCall'\nimport { flash } from '@open-mercato/ui/backend/FlashMessages'\nimport { deleteCrud, buildCrudExportUrl } from '@open-mercato/ui/backend/utils/crud'\nimport { buildOptimisticLockHeader } from '@open-mercato/ui/backend/utils/optimisticLock'\nimport { useCustomFieldDefs } from '@open-mercato/ui/backend/utils/customFieldDefs'\nimport { applyCustomFieldVisibility } from '@open-mercato/ui/backend/utils/customFieldColumns'\nimport type { FilterDef, FilterValues } from '@open-mercato/ui/backend/FilterBar'\nimport type { FilterOption } from '@open-mercato/ui/backend/FilterOverlay'\nimport { BooleanIcon } from '@open-mercato/ui/backend/ValueIcons'\nimport { markdownToPlainText } from '@open-mercato/ui/backend/markdown/markdownToPlainText'\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 { useAppEvent } from '@open-mercato/ui/backend/injection/useAppEvent'\nimport { E } from '#generated/entities.ids.generated'\nimport { ProductImageCell } from './ProductImageCell'\n\ntype PricingScope = {\n variant_id?: string | null\n offer_id?: string | null\n channel_id?: string | null\n user_id?: string | null\n user_group_id?: string | null\n customer_id?: string | null\n customer_group_id?: string | null\n}\n\ntype PricingInfo = {\n kind?: string | null\n price_kind_id?: string | null\n price_kind_code?: string | null\n currency_code?: string | null\n unit_price_net?: string | null\n unit_price_gross?: string | null\n min_quantity?: number | null\n max_quantity?: number | null\n tax_rate?: string | null\n scope?: PricingScope | null\n} | null\n\ntype OfferInfo = {\n id: string\n channelId: string\n channelName?: string | null\n channelCode?: string | null\n title: string\n description?: string | null\n isActive: boolean\n}\n\nexport type ProductRow = {\n id: string\n title: string\n subtitle?: string | null\n description?: string | null\n sku?: string | null\n handle?: string | null\n product_type?: string | null\n status_entry_id?: string | null\n primary_currency_code?: string | null\n default_unit?: string | null\n default_media_id?: string | null\n default_media_url?: string | null\n is_configurable?: boolean\n is_active?: boolean\n metadata?: Record<string, unknown> | null\n custom_fieldset_code?: string | null\n created_at?: string\n updated_at?: string\n offers?: OfferInfo[]\n pricing?: PricingInfo\n} & Record<string, unknown>\n\ntype ProductsResponse = {\n items?: ProductRow[]\n total?: number\n totalPages?: number\n}\n\nconst PAGE_SIZE = 25\nconst ENTITY_ID = E.catalog.catalog_product\n\nfunction formatDate(value?: string): string {\n if (!value) return '\u2014'\n const date = new Date(value)\n if (Number.isNaN(date.getTime())) return '\u2014'\n return date.toLocaleDateString()\n}\n\nfunction renderOffers(offers: OfferInfo[] | undefined): React.ReactNode {\n if (!offers || offers.length === 0) return <span className=\"text-xs text-muted-foreground\">\u2014</span>\n const visible = offers.slice(0, 3)\n return (\n <div className=\"flex flex-wrap gap-1\">\n {visible.map((offer) => {\n const label =\n typeof offer.channelName === 'string' && offer.channelName.trim().length\n ? offer.channelName.trim()\n : typeof offer.title === 'string' && offer.title.trim().length\n ? offer.title.trim()\n : offer.channelId\n const badgeTitle =\n typeof offer.channelCode === 'string' && offer.channelCode.trim().length ? offer.channelCode : undefined\n return (\n <span\n key={offer.id}\n className={`inline-flex items-center rounded-full border px-2 py-0.5 text-xs ${\n offer.isActive ? 'bg-secondary/80 text-secondary-foreground' : 'bg-muted text-muted-foreground'\n }`}\n title={badgeTitle}\n >\n {label}\n </span>\n )\n })}\n {offers.length > visible.length ? (\n <span className=\"text-xs text-muted-foreground\">+{offers.length - visible.length}</span>\n ) : null}\n </div>\n )\n}\n\nfunction renderPrice(pricing: PricingInfo | undefined, currency?: string | null, fallback = '\u2014'): React.ReactNode {\n if (!pricing) return <span className=\"text-xs text-muted-foreground\">{fallback}</span>\n const unit = pricing.unit_price_net ?? pricing.unit_price_gross\n if (unit == null) return <span className=\"text-xs text-muted-foreground\">{fallback}</span>\n const formatted = `${currency ?? pricing.currency_code ?? ''} ${unit}`\n const kind = pricing.kind ?? 'list'\n return (\n <div className=\"flex flex-col\">\n <span className=\"font-medium\">{formatted.trim()}</span>\n <span className=\"text-xs text-muted-foreground\">{kind}</span>\n </div>\n )\n}\n\nexport type ProductsDataTableSnapshot = {\n search: string\n filterValues: FilterValues\n total: number\n}\n\nexport type ProductsDataTableProps = {\n /**\n * Extra actions rendered alongside the built-in Create button in the\n * DataTable header. Used by the Step 4.9 AI merchandising sheet\n * trigger without coupling DataTable to the AI module.\n */\n extraActions?: React.ReactNode\n /**\n * Optional callback invoked whenever the table's search / filter /\n * total-matching snapshot changes. Used by the Step 4.9 AI merchandising\n * sheet to form a selection-aware pageContext per spec \u00A710.1.\n */\n onSnapshotChange?: (snapshot: ProductsDataTableSnapshot) => void\n}\n\nexport default function ProductsDataTable({\n extraActions,\n onSnapshotChange,\n}: ProductsDataTableProps = {}) {\n const t = useT()\n const { confirm, ConfirmDialogElement } = useConfirmDialog()\n const scopeVersion = useOrganizationScopeVersion()\n const [rows, setRows] = React.useState<ProductRow[]>([])\n const [page, setPage] = React.useState(1)\n const [total, setTotal] = React.useState(0)\n const [totalPages, setTotalPages] = React.useState(1)\n const [cacheStatus, setCacheStatus] = React.useState<'hit' | 'miss' | null>(null)\n const [sorting, setSorting] = React.useState<SortingState>([{ id: 'title', desc: false }])\n const [search, setSearch] = React.useState('')\n const [filterValues, setFilterValues] = React.useState<FilterValues>({})\n const [isLoading, setIsLoading] = React.useState(false)\n const [reloadToken, setReloadToken] = React.useState(0)\n // Step 5.18 (spec \u00A710 line 836, D18 demo): refresh the list when a\n // catalog.product.* event arrives via the DOM event bridge. Confirmed\n // AI bulk mutations (one `ai.action.confirmed` + one\n // `catalog.product.updated` per record) and direct API writes both\n // surface here so the table reflects the new state without a manual\n // reload.\n useAppEvent('catalog.product.*', () => {\n setReloadToken((token) => token + 1)\n })\n const [customFieldsetFilter, setCustomFieldsetFilter] = React.useState<string | null>(null)\n const { data: customFieldDefs = [] } = useCustomFieldDefs(ENTITY_ID, {\n keyExtras: [scopeVersion, reloadToken],\n })\n const [channelOptionsCache, setChannelOptionsCache] = React.useState<Record<string, FilterOption>>({})\n const [categoryOptionsCache, setCategoryOptionsCache] = React.useState<Record<string, FilterOption>>({})\n const [tagOptionsCache, setTagOptionsCache] = React.useState<Record<string, FilterOption>>({})\n\n const registerOptions = React.useCallback(\n (\n setter: React.Dispatch<React.SetStateAction<Record<string, FilterOption>>>,\n options: FilterOption[]\n ) => {\n setter((prev) => {\n const next = { ...prev }\n options.forEach((opt) => {\n if (opt.value) next[opt.value] = opt\n })\n return next\n })\n },\n []\n )\n\n const registerChannelOptions = React.useCallback(\n (options: FilterOption[]) => registerOptions(setChannelOptionsCache, options),\n [registerOptions]\n )\n const registerCategoryOptions = React.useCallback(\n (options: FilterOption[]) => registerOptions(setCategoryOptionsCache, options),\n [registerOptions]\n )\n const registerTagOptions = React.useCallback(\n (options: FilterOption[]) => registerOptions(setTagOptionsCache, options),\n [registerOptions]\n )\n\n const channelOptions = React.useMemo(() => Object.values(channelOptionsCache), [channelOptionsCache])\n const categoryOptions = React.useMemo(() => Object.values(categoryOptionsCache), [categoryOptionsCache])\n const tagOptions = React.useMemo(() => Object.values(tagOptionsCache), [tagOptionsCache])\n\n const loadChannelOptions = React.useCallback(\n async (term?: string): Promise<FilterOption[]> => {\n try {\n const params = new URLSearchParams({ pageSize: '100', isActive: 'true' })\n if (term && term.trim().length) params.set('search', term.trim())\n const payload = await readApiResultOrThrow<{ items?: Array<{ id?: string; name?: string; code?: string }> }>(\n `/api/sales/channels?${params.toString()}`,\n undefined,\n { errorMessage: t('catalog.products.filters.channelsLoadError', 'Failed to load channels') },\n )\n const items = Array.isArray(payload?.items) ? payload.items : []\n const options = items\n .map((entry) => {\n const value = typeof entry.id === 'string' ? entry.id : null\n if (!value) return null\n const label =\n typeof entry.name === 'string'\n ? entry.name\n : typeof entry.code === 'string'\n ? entry.code\n : value\n return { value, label, description: typeof entry.code === 'string' ? entry.code : undefined }\n })\n .filter((option) => !!option) as FilterOption[]\n registerChannelOptions(options)\n return options\n } catch {\n return []\n }\n },\n [registerChannelOptions, t],\n )\n\n const loadCategoryOptions = React.useCallback(\n async (term?: string): Promise<FilterOption[]> => {\n try {\n const params = new URLSearchParams({ pageSize: '200', view: 'manage' })\n if (term && term.trim().length) params.set('search', term.trim())\n const payload = await readApiResultOrThrow<{ items?: Array<{ id?: string; name?: string; parentName?: string | null }> }>(\n `/api/catalog/categories?${params.toString()}`,\n undefined,\n { errorMessage: t('catalog.products.filters.categoriesLoadError', 'Failed to load categories') },\n )\n const items = Array.isArray(payload?.items) ? payload.items : []\n const options = items\n .map((entry) => {\n const value = typeof entry.id === 'string' ? entry.id : null\n if (!value) return null\n const label = typeof entry.name === 'string' && entry.name.trim().length ? entry.name : value\n const description =\n typeof entry.parentName === 'string' && entry.parentName.trim().length ? entry.parentName : null\n return { value, label, description }\n })\n .filter((option) => !!option) as FilterOption[]\n registerCategoryOptions(options)\n return options\n } catch {\n return []\n }\n },\n [registerCategoryOptions, t],\n )\n\n const loadTagOptions = React.useCallback(\n async (term?: string): Promise<FilterOption[]> => {\n try {\n const params = new URLSearchParams({ pageSize: '100' })\n if (term && term.trim().length) params.set('search', term.trim())\n const payload = await readApiResultOrThrow<{ items?: Array<{ id?: string; label?: string }> }>(\n `/api/catalog/tags?${params.toString()}`,\n undefined,\n { errorMessage: t('catalog.products.filters.tagsLoadError', 'Failed to load tags') },\n )\n const items = Array.isArray(payload?.items) ? payload.items : []\n const options = items\n .map((entry) => {\n const value = typeof entry.id === 'string' ? entry.id : null\n if (!value) return null\n const label = typeof entry.label === 'string' && entry.label.trim().length ? entry.label : value\n return { value, label }\n })\n .filter((option) => !!option) as FilterOption[]\n registerTagOptions(options)\n return options\n } catch {\n return []\n }\n },\n [registerTagOptions, t],\n )\n\n const productTypeOptions = React.useMemo<FilterOption[]>(() => [\n { value: 'simple', label: t('catalog.products.types.simple', 'Simple') },\n { value: 'configurable', label: t('catalog.products.types.configurable', 'Configurable') },\n { value: 'virtual', label: t('catalog.products.types.virtual', 'Virtual') },\n { value: 'downloadable', label: t('catalog.products.types.downloadable', 'Downloadable') },\n {\n value: 'bundle',\n label: `${t('catalog.products.types.bundle', 'Bundle')} (${t('common.comingSoon', 'Coming soon')})`,\n },\n {\n value: 'grouped',\n label: `${t('catalog.products.types.grouped', 'Grouped')} (${t('common.comingSoon', 'Coming soon')})`,\n },\n ], [t])\n\n const productTypeLabelMap = React.useMemo(() => {\n const map = new Map<string, string>()\n productTypeOptions.forEach((opt) => map.set(opt.value, opt.label))\n return map\n }, [productTypeOptions])\n\n const filters = React.useMemo<FilterDef[]>(() => [\n { id: 'status', label: t('catalog.products.filters.status'), type: 'text' },\n { id: 'isActive', label: t('catalog.products.filters.active'), type: 'checkbox' },\n { id: 'configurable', label: t('catalog.products.filters.configurable'), type: 'checkbox' },\n { id: 'productType', label: t('catalog.products.filters.productType', 'Type'), type: 'select', options: productTypeOptions },\n {\n id: 'channelIds',\n label: t('catalog.products.filters.channels'),\n type: 'tags',\n loadOptions: loadChannelOptions,\n options: channelOptions,\n formatValue: (val) => channelOptionsCache[val]?.label ?? val,\n formatDescription: (val) => channelOptionsCache[val]?.description ?? null,\n },\n {\n id: 'categoryIds',\n label: t('catalog.products.filters.categories', 'Categories'),\n type: 'tags',\n loadOptions: loadCategoryOptions,\n options: categoryOptions,\n formatValue: (val) => categoryOptionsCache[val]?.label ?? val,\n formatDescription: (val) => categoryOptionsCache[val]?.description ?? null,\n },\n {\n id: 'tagIds',\n label: t('catalog.products.filters.tags', 'Tags'),\n type: 'tags',\n loadOptions: loadTagOptions,\n options: tagOptions,\n formatValue: (val) => tagOptionsCache[val]?.label ?? val,\n },\n ], [\n categoryOptions,\n categoryOptionsCache,\n channelOptions,\n channelOptionsCache,\n loadCategoryOptions,\n loadChannelOptions,\n loadTagOptions,\n productTypeOptions,\n tagOptions,\n tagOptionsCache,\n t,\n ])\n\n const columns = React.useMemo<ColumnDef<ProductRow>[]>(() => {\n const base: ColumnDef<ProductRow>[] = [\n {\n id: 'media',\n header: '',\n size: 80,\n cell: ({ row }) => (\n <ProductImageCell\n mediaId={row.original.default_media_id}\n mediaUrl={row.original.default_media_url}\n title={row.original.title}\n cropType=\"contain\"\n />\n ),\n meta: { sticky: true },\n },\n {\n accessorKey: 'title',\n header: t('catalog.products.table.title', 'Title'),\n cell: ({ row }) => (\n <div className=\"flex flex-col\">\n <span className=\"font-medium\">{row.original.title || '\u2014'}</span>\n {row.original.subtitle ? (\n <span className=\"text-xs text-muted-foreground\">{row.original.subtitle}</span>\n ) : null}\n {row.original.handle ? (\n <span className=\"text-xs text-muted-foreground\">/{row.original.handle}</span>\n ) : null}\n {row.original.description ? (\n <span className=\"text-xs text-muted-foreground\">{markdownToPlainText(row.original.description)}</span>\n ) : null}\n </div>\n ),\n meta: { sticky: true },\n },\n {\n accessorKey: 'sku',\n header: t('catalog.products.table.sku', 'SKU'),\n cell: ({ getValue }) => {\n const value = getValue()\n return value ? <span className=\"font-mono text-xs\">{String(value)}</span> : <span className=\"text-xs text-muted-foreground\">\u2014</span>\n },\n },\n {\n accessorKey: 'product_type',\n header: t('catalog.products.table.type'),\n cell: ({ row }) => {\n const type = typeof row.original.product_type === 'string' ? row.original.product_type : 'simple'\n const label = productTypeLabelMap.get(type) ?? type\n return <span className=\"text-xs text-muted-foreground\">{label}</span>\n },\n },\n {\n accessorKey: 'is_configurable',\n header: t('catalog.products.table.configurable'),\n cell: ({ row }) => <BooleanIcon value={!!row.original.is_configurable} />,\n },\n {\n accessorKey: 'is_active',\n header: t('catalog.products.table.active'),\n cell: ({ row }) => <BooleanIcon value={!!row.original.is_active} />,\n },\n {\n accessorKey: 'pricing',\n header: t('catalog.products.table.price'),\n cell: ({ row }) => renderPrice(row.original.pricing, row.original.primary_currency_code),\n },\n {\n accessorKey: 'offers',\n header: t('catalog.products.table.channels'),\n cell: ({ row }) => renderOffers(row.original.offers),\n },\n {\n accessorKey: 'updated_at',\n header: t('catalog.products.table.updatedAt'),\n cell: ({ row }) => <span className=\"text-xs text-muted-foreground\">{formatDate(row.original.updated_at)}</span>,\n },\n ]\n return applyCustomFieldVisibility(base, customFieldDefs)\n }, [customFieldDefs, productTypeLabelMap, t])\n\n const handleSearchChange = React.useCallback((value: string) => {\n setSearch(value)\n setPage(1)\n }, [])\n\n const handleFiltersApply = React.useCallback((values: FilterValues) => {\n setFilterValues(values)\n setPage(1)\n }, [])\n\n const handleFiltersClear = React.useCallback(() => {\n setFilterValues({})\n setPage(1)\n }, [])\n\n const handleCustomFieldsetFilterChange = React.useCallback(\n (value: string | null) => {\n if (value === customFieldsetFilter) return\n setCustomFieldsetFilter(value)\n setFilterValues((prev) => {\n const entries = Object.entries(prev)\n if (!entries.some(([key]) => key.startsWith('cf_'))) return prev\n const next: FilterValues = {}\n entries.forEach(([key, val]) => {\n if (!key.startsWith('cf_')) next[key] = val\n })\n return next\n })\n setPage(1)\n },\n [customFieldsetFilter],\n )\n\n const handleRefresh = React.useCallback(() => {\n setReloadToken((token) => token + 1)\n }, [])\n\n const queryParams = React.useMemo(() => {\n const params = new URLSearchParams()\n params.set('page', String(page))\n params.set('pageSize', String(PAGE_SIZE))\n if (search.trim()) params.set('search', search.trim())\n const sort = sorting[0]\n if (sort?.id) {\n params.set('sortField', sort.id)\n params.set('sortDir', sort.desc ? 'desc' : 'asc')\n }\n const status = filterValues.status\n if (typeof status === 'string' && status.trim()) {\n params.set('status', status.trim())\n }\n if (filterValues.isActive === true) params.set('isActive', 'true')\n if (filterValues.isActive === false) params.set('isActive', 'false')\n if (filterValues.configurable === true) params.set('configurable', 'true')\n if (filterValues.configurable === false) params.set('configurable', 'false')\n if (typeof filterValues.productType === 'string' && filterValues.productType.trim()) {\n params.set('productType', filterValues.productType.trim())\n }\n if (Array.isArray(filterValues.channelIds) && filterValues.channelIds.length) {\n const values = filterValues.channelIds\n .map((value) => (typeof value === 'string' ? value : null))\n .filter((value): value is string => !!value)\n if (values.length) params.set('channelIds', values.join(','))\n }\n if (Array.isArray(filterValues.categoryIds) && filterValues.categoryIds.length) {\n const values = filterValues.categoryIds\n .map((value) => (typeof value === 'string' ? value : null))\n .filter((value): value is string => !!value)\n if (values.length) params.set('categoryIds', values.join(','))\n }\n if (Array.isArray(filterValues.tagIds) && filterValues.tagIds.length) {\n const values = filterValues.tagIds\n .map((value) => (typeof value === 'string' ? value : null))\n .filter((value): value is string => !!value)\n if (values.length) params.set('tagIds', values.join(','))\n }\n Object.entries(filterValues).forEach(([key, value]) => {\n if (!key.startsWith('cf_') || value == null) return\n if (Array.isArray(value)) {\n const entries = value\n .map((entry) => (typeof entry === 'string' ? entry.trim() : String(entry || '').trim()))\n .filter((entry) => entry.length > 0)\n if (entries.length) params.set(key, entries.join(','))\n } else if (typeof value === 'object' && value !== null && ('from' in (value as Record<string, unknown>) || 'to' in (value as Record<string, unknown>))) {\n const range = value as { from?: string; to?: string }\n if (typeof range.from === 'string' && range.from.trim().length) {\n params.set(`${key}:from`, range.from.trim())\n }\n if (typeof range.to === 'string' && range.to.trim().length) {\n params.set(`${key}:to`, range.to.trim())\n }\n } else if (typeof value === 'string' && value.trim()) {\n params.set(key, value.trim())\n }\n })\n if (typeof customFieldsetFilter === 'string' && customFieldsetFilter.trim().length > 0) {\n params.set('customFieldset', customFieldsetFilter.trim())\n }\n return params.toString()\n }, [customFieldsetFilter, filterValues, page, search, sorting])\n\n React.useEffect(() => {\n let cancelled = false\n async function load() {\n setIsLoading(true)\n setCacheStatus(null)\n try {\n const fallback: ProductsResponse = { items: [], total: 0, totalPages: 1 }\n const call = await apiCall<ProductsResponse>(\n `/api/catalog/products?${queryParams}`,\n undefined,\n { fallback },\n )\n if (!call.ok) {\n const message = t('catalog.products.list.error.load', 'Failed to load products')\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 normalized = items.filter((item): item is ProductRow => typeof item?.id === 'string')\n setRows(normalized)\n setTotal(typeof payload.total === 'number' ? payload.total : normalized.length)\n setTotalPages(typeof payload.totalPages === 'number' ? payload.totalPages : 1)\n } catch (error) {\n if (!cancelled) {\n setCacheStatus(null)\n const message =\n error instanceof Error\n ? error.message\n : t('catalog.products.list.error.load', 'Failed to load products')\n flash(message, 'error')\n }\n } finally {\n if (!cancelled) setIsLoading(false)\n }\n }\n load()\n return () => {\n cancelled = true\n }\n }, [queryParams, reloadToken, scopeVersion, t])\n\n const handleDelete = React.useCallback(async (row: ProductRow) => {\n const confirmed = await confirm({\n title: t('catalog.products.list.deleteConfirm', 'Delete this product?'),\n variant: 'destructive',\n })\n if (!confirmed) return\n try {\n const headers = buildOptimisticLockHeader(typeof row.updated_at === 'string' ? row.updated_at : null)\n await withScopedApiRequestHeaders(headers, () => (\n deleteCrud('catalog/products', row.id, {\n errorMessage: t('catalog.products.list.error.delete', 'Failed to delete product'),\n })\n ))\n flash(t('catalog.products.flash.deleted', 'Product deleted'), 'success')\n setReloadToken((token) => token + 1)\n } catch (error) {\n const message =\n error instanceof Error\n ? error.message\n : t('catalog.products.list.error.delete', 'Failed to delete product')\n flash(message, 'error')\n }\n }, [confirm, t])\n\n React.useEffect(() => {\n if (!onSnapshotChange) return\n onSnapshotChange({ search, filterValues, total })\n }, [onSnapshotChange, search, filterValues, total])\n\n const currentParams = React.useMemo(() => Object.fromEntries(new URLSearchParams(queryParams)), [queryParams])\n\n const exportConfig = React.useMemo(() => ({\n view: {\n getUrl: (format: DataTableExportFormat) =>\n buildCrudExportUrl('catalog/products', { ...currentParams, exportScope: 'view' }, format),\n },\n full: {\n getUrl: (format: DataTableExportFormat) =>\n buildCrudExportUrl('catalog/products', { ...currentParams, exportScope: 'full', all: 'true' }, format),\n },\n }), [currentParams])\n\n return (\n <>\n <DataTable<ProductRow>\n title={t('catalog.products.page.title', 'Products & services')}\n entityId={ENTITY_ID}\n customFieldFilterKeyExtras={[scopeVersion, reloadToken]}\n refreshButton={{\n label: t('catalog.products.actions.refresh', 'Refresh'),\n onRefresh: handleRefresh,\n isRefreshing: isLoading,\n }}\n actions={(\n <div className=\"flex items-center gap-2\">\n {extraActions}\n <Button asChild>\n <Link href=\"/backend/catalog/products/create\">\n {t('catalog.products.actions.create', 'Create')}\n </Link>\n </Button>\n </div>\n )}\n columns={columns}\n data={rows}\n emptyState={(\n <ListEmptyState\n entityName={t('catalog.products.page.title', 'Products & services')}\n createHref=\"/backend/catalog/products/create\"\n createLabel={t('catalog.products.actions.create', 'Create')}\n />\n )}\n searchValue={search}\n onSearchChange={handleSearchChange}\n filters={filters}\n filterValues={filterValues}\n onFiltersApply={handleFiltersApply}\n onFiltersClear={handleFiltersClear}\n onCustomFieldFilterFieldsetChange={handleCustomFieldsetFilterChange}\n sorting={sorting}\n onSortingChange={setSorting}\n injectionSpotId={extensionPoints.hosts.productsTable.baseSpotId}\n injectionContext={{\n search,\n filters: filterValues,\n customFieldset: customFieldsetFilter,\n page,\n sorting,\n scopeVersion,\n // Step 5.15: surface `total` so the merchandising AI widget\n // (rendered in `data-table:catalog.products:header`) can build\n // a selection-aware pageContext per spec \u00A710.1 without taking a\n // dependency on the host page.\n total,\n totalMatching: total,\n }}\n pagination={{\n page,\n pageSize: PAGE_SIZE,\n total,\n totalPages,\n onPageChange: setPage,\n cacheStatus,\n }}\n exporter={exportConfig}\n isLoading={isLoading}\n perspective={{ tableId: extensionPoints.hosts.productsTable.tableId }}\n stickyActionsColumn\n rowActions={(row) => (\n <RowActions\n items={[\n {\n id: 'edit',\n label: t('catalog.products.table.actions.edit', 'Edit'),\n href: `/backend/catalog/products/${row.id}`,\n },\n {\n id: 'delete',\n label: t('catalog.products.table.actions.delete', 'Delete'),\n destructive: true,\n onSelect: () => {\n void handleDelete(row)\n },\n },\n ]}\n />\n )}\n />\n {ConfirmDialogElement}\n </>\n )\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport { extensionPoints } from '@open-mercato/core/modules/catalog/extension-points'\nimport Link from 'next/link'\nimport type { LegacyColumnDef as ColumnDef } from '@tanstack/react-table/legacy'\nimport type { SortingState } from '@tanstack/react-table'\nimport { DataTable, type DataTableExportFormat } from '@open-mercato/ui/backend/DataTable'\nimport { ListEmptyState } from '@open-mercato/ui/backend/filters/ListEmptyState'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { RowActions } from '@open-mercato/ui/backend/RowActions'\nimport { apiCall, readApiResultOrThrow, withScopedApiRequestHeaders } from '@open-mercato/ui/backend/utils/apiCall'\nimport { flash } from '@open-mercato/ui/backend/FlashMessages'\nimport { deleteCrud, buildCrudExportUrl } from '@open-mercato/ui/backend/utils/crud'\nimport { buildOptimisticLockHeader } from '@open-mercato/ui/backend/utils/optimisticLock'\nimport { useCustomFieldDefs } from '@open-mercato/ui/backend/utils/customFieldDefs'\nimport { applyCustomFieldVisibility } from '@open-mercato/ui/backend/utils/customFieldColumns'\nimport type { FilterDef, FilterValues } from '@open-mercato/ui/backend/FilterBar'\nimport type { FilterOption } from '@open-mercato/ui/backend/FilterOverlay'\nimport { BooleanIcon } from '@open-mercato/ui/backend/ValueIcons'\nimport { markdownToPlainText } from '@open-mercato/ui/backend/markdown/markdownToPlainText'\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 { useAppEvent } from '@open-mercato/ui/backend/injection/useAppEvent'\nimport { E } from '#generated/entities.ids.generated'\nimport { ProductImageCell } from './ProductImageCell'\n\ntype PricingScope = {\n variant_id?: string | null\n offer_id?: string | null\n channel_id?: string | null\n user_id?: string | null\n user_group_id?: string | null\n customer_id?: string | null\n customer_group_id?: string | null\n}\n\ntype PricingInfo = {\n kind?: string | null\n price_kind_id?: string | null\n price_kind_code?: string | null\n currency_code?: string | null\n unit_price_net?: string | null\n unit_price_gross?: string | null\n min_quantity?: number | null\n max_quantity?: number | null\n tax_rate?: string | null\n scope?: PricingScope | null\n} | null\n\ntype OfferInfo = {\n id: string\n channelId: string\n channelName?: string | null\n channelCode?: string | null\n title: string\n description?: string | null\n isActive: boolean\n}\n\nexport type ProductRow = {\n id: string\n title: string\n subtitle?: string | null\n description?: string | null\n sku?: string | null\n handle?: string | null\n product_type?: string | null\n status_entry_id?: string | null\n primary_currency_code?: string | null\n default_unit?: string | null\n default_media_id?: string | null\n default_media_url?: string | null\n is_configurable?: boolean\n is_active?: boolean\n metadata?: Record<string, unknown> | null\n custom_fieldset_code?: string | null\n created_at?: string\n updated_at?: string\n offers?: OfferInfo[]\n pricing?: PricingInfo\n} & Record<string, unknown>\n\ntype ProductsResponse = {\n items?: ProductRow[]\n total?: number\n totalPages?: number\n totalIsCapped?: boolean\n}\n\nconst PAGE_SIZE = 25\nconst ENTITY_ID = E.catalog.catalog_product\n\nfunction formatDate(value?: string): string {\n if (!value) return '\u2014'\n const date = new Date(value)\n if (Number.isNaN(date.getTime())) return '\u2014'\n return date.toLocaleDateString()\n}\n\nfunction renderOffers(offers: OfferInfo[] | undefined): React.ReactNode {\n if (!offers || offers.length === 0) return <span className=\"text-xs text-muted-foreground\">\u2014</span>\n const visible = offers.slice(0, 3)\n return (\n <div className=\"flex flex-wrap gap-1\">\n {visible.map((offer) => {\n const label =\n typeof offer.channelName === 'string' && offer.channelName.trim().length\n ? offer.channelName.trim()\n : typeof offer.title === 'string' && offer.title.trim().length\n ? offer.title.trim()\n : offer.channelId\n const badgeTitle =\n typeof offer.channelCode === 'string' && offer.channelCode.trim().length ? offer.channelCode : undefined\n return (\n <span\n key={offer.id}\n className={`inline-flex items-center rounded-full border px-2 py-0.5 text-xs ${\n offer.isActive ? 'bg-secondary/80 text-secondary-foreground' : 'bg-muted text-muted-foreground'\n }`}\n title={badgeTitle}\n >\n {label}\n </span>\n )\n })}\n {offers.length > visible.length ? (\n <span className=\"text-xs text-muted-foreground\">+{offers.length - visible.length}</span>\n ) : null}\n </div>\n )\n}\n\nfunction renderPrice(pricing: PricingInfo | undefined, currency?: string | null, fallback = '\u2014'): React.ReactNode {\n if (!pricing) return <span className=\"text-xs text-muted-foreground\">{fallback}</span>\n const unit = pricing.unit_price_net ?? pricing.unit_price_gross\n if (unit == null) return <span className=\"text-xs text-muted-foreground\">{fallback}</span>\n const formatted = `${currency ?? pricing.currency_code ?? ''} ${unit}`\n const kind = pricing.kind ?? 'list'\n return (\n <div className=\"flex flex-col\">\n <span className=\"font-medium\">{formatted.trim()}</span>\n <span className=\"text-xs text-muted-foreground\">{kind}</span>\n </div>\n )\n}\n\nexport type ProductsDataTableSnapshot = {\n search: string\n filterValues: FilterValues\n total: number\n}\n\nexport type ProductsDataTableProps = {\n /**\n * Extra actions rendered alongside the built-in Create button in the\n * DataTable header. Used by the Step 4.9 AI merchandising sheet\n * trigger without coupling DataTable to the AI module.\n */\n extraActions?: React.ReactNode\n /**\n * Optional callback invoked whenever the table's search / filter /\n * total-matching snapshot changes. Used by the Step 4.9 AI merchandising\n * sheet to form a selection-aware pageContext per spec \u00A710.1.\n */\n onSnapshotChange?: (snapshot: ProductsDataTableSnapshot) => void\n}\n\nexport default function ProductsDataTable({\n extraActions,\n onSnapshotChange,\n}: ProductsDataTableProps = {}) {\n const t = useT()\n const { confirm, ConfirmDialogElement } = useConfirmDialog()\n const scopeVersion = useOrganizationScopeVersion()\n const [rows, setRows] = React.useState<ProductRow[]>([])\n const [page, setPage] = React.useState(1)\n const [total, setTotal] = React.useState(0)\n const [totalPages, setTotalPages] = React.useState(1)\n const [totalIsCapped, setTotalIsCapped] = React.useState(false)\n const [cacheStatus, setCacheStatus] = React.useState<'hit' | 'miss' | null>(null)\n const [sorting, setSorting] = React.useState<SortingState>([{ id: 'title', desc: false }])\n const [search, setSearch] = React.useState('')\n const [filterValues, setFilterValues] = React.useState<FilterValues>({})\n const [isLoading, setIsLoading] = React.useState(false)\n const [reloadToken, setReloadToken] = React.useState(0)\n // Step 5.18 (spec \u00A710 line 836, D18 demo): refresh the list when a\n // catalog.product.* event arrives via the DOM event bridge. Confirmed\n // AI bulk mutations (one `ai.action.confirmed` + one\n // `catalog.product.updated` per record) and direct API writes both\n // surface here so the table reflects the new state without a manual\n // reload.\n useAppEvent('catalog.product.*', () => {\n setReloadToken((token) => token + 1)\n })\n const [customFieldsetFilter, setCustomFieldsetFilter] = React.useState<string | null>(null)\n const { data: customFieldDefs = [] } = useCustomFieldDefs(ENTITY_ID, {\n keyExtras: [scopeVersion, reloadToken],\n })\n const [channelOptionsCache, setChannelOptionsCache] = React.useState<Record<string, FilterOption>>({})\n const [categoryOptionsCache, setCategoryOptionsCache] = React.useState<Record<string, FilterOption>>({})\n const [tagOptionsCache, setTagOptionsCache] = React.useState<Record<string, FilterOption>>({})\n\n const registerOptions = React.useCallback(\n (\n setter: React.Dispatch<React.SetStateAction<Record<string, FilterOption>>>,\n options: FilterOption[]\n ) => {\n setter((prev) => {\n const next = { ...prev }\n options.forEach((opt) => {\n if (opt.value) next[opt.value] = opt\n })\n return next\n })\n },\n []\n )\n\n const registerChannelOptions = React.useCallback(\n (options: FilterOption[]) => registerOptions(setChannelOptionsCache, options),\n [registerOptions]\n )\n const registerCategoryOptions = React.useCallback(\n (options: FilterOption[]) => registerOptions(setCategoryOptionsCache, options),\n [registerOptions]\n )\n const registerTagOptions = React.useCallback(\n (options: FilterOption[]) => registerOptions(setTagOptionsCache, options),\n [registerOptions]\n )\n\n const channelOptions = React.useMemo(() => Object.values(channelOptionsCache), [channelOptionsCache])\n const categoryOptions = React.useMemo(() => Object.values(categoryOptionsCache), [categoryOptionsCache])\n const tagOptions = React.useMemo(() => Object.values(tagOptionsCache), [tagOptionsCache])\n\n const loadChannelOptions = React.useCallback(\n async (term?: string): Promise<FilterOption[]> => {\n try {\n const params = new URLSearchParams({ pageSize: '100', isActive: 'true' })\n if (term && term.trim().length) params.set('search', term.trim())\n const payload = await readApiResultOrThrow<{ items?: Array<{ id?: string; name?: string; code?: string }> }>(\n `/api/sales/channels?${params.toString()}`,\n undefined,\n { errorMessage: t('catalog.products.filters.channelsLoadError', 'Failed to load channels') },\n )\n const items = Array.isArray(payload?.items) ? payload.items : []\n const options = items\n .map((entry) => {\n const value = typeof entry.id === 'string' ? entry.id : null\n if (!value) return null\n const label =\n typeof entry.name === 'string'\n ? entry.name\n : typeof entry.code === 'string'\n ? entry.code\n : value\n return { value, label, description: typeof entry.code === 'string' ? entry.code : undefined }\n })\n .filter((option) => !!option) as FilterOption[]\n registerChannelOptions(options)\n return options\n } catch {\n return []\n }\n },\n [registerChannelOptions, t],\n )\n\n const loadCategoryOptions = React.useCallback(\n async (term?: string): Promise<FilterOption[]> => {\n try {\n const params = new URLSearchParams({ pageSize: '200', view: 'manage' })\n if (term && term.trim().length) params.set('search', term.trim())\n const payload = await readApiResultOrThrow<{ items?: Array<{ id?: string; name?: string; parentName?: string | null }> }>(\n `/api/catalog/categories?${params.toString()}`,\n undefined,\n { errorMessage: t('catalog.products.filters.categoriesLoadError', 'Failed to load categories') },\n )\n const items = Array.isArray(payload?.items) ? payload.items : []\n const options = items\n .map((entry) => {\n const value = typeof entry.id === 'string' ? entry.id : null\n if (!value) return null\n const label = typeof entry.name === 'string' && entry.name.trim().length ? entry.name : value\n const description =\n typeof entry.parentName === 'string' && entry.parentName.trim().length ? entry.parentName : null\n return { value, label, description }\n })\n .filter((option) => !!option) as FilterOption[]\n registerCategoryOptions(options)\n return options\n } catch {\n return []\n }\n },\n [registerCategoryOptions, t],\n )\n\n const loadTagOptions = React.useCallback(\n async (term?: string): Promise<FilterOption[]> => {\n try {\n const params = new URLSearchParams({ pageSize: '100' })\n if (term && term.trim().length) params.set('search', term.trim())\n const payload = await readApiResultOrThrow<{ items?: Array<{ id?: string; label?: string }> }>(\n `/api/catalog/tags?${params.toString()}`,\n undefined,\n { errorMessage: t('catalog.products.filters.tagsLoadError', 'Failed to load tags') },\n )\n const items = Array.isArray(payload?.items) ? payload.items : []\n const options = items\n .map((entry) => {\n const value = typeof entry.id === 'string' ? entry.id : null\n if (!value) return null\n const label = typeof entry.label === 'string' && entry.label.trim().length ? entry.label : value\n return { value, label }\n })\n .filter((option) => !!option) as FilterOption[]\n registerTagOptions(options)\n return options\n } catch {\n return []\n }\n },\n [registerTagOptions, t],\n )\n\n const productTypeOptions = React.useMemo<FilterOption[]>(() => [\n { value: 'simple', label: t('catalog.products.types.simple', 'Simple') },\n { value: 'configurable', label: t('catalog.products.types.configurable', 'Configurable') },\n { value: 'virtual', label: t('catalog.products.types.virtual', 'Virtual') },\n { value: 'downloadable', label: t('catalog.products.types.downloadable', 'Downloadable') },\n {\n value: 'bundle',\n label: `${t('catalog.products.types.bundle', 'Bundle')} (${t('common.comingSoon', 'Coming soon')})`,\n },\n {\n value: 'grouped',\n label: `${t('catalog.products.types.grouped', 'Grouped')} (${t('common.comingSoon', 'Coming soon')})`,\n },\n ], [t])\n\n const productTypeLabelMap = React.useMemo(() => {\n const map = new Map<string, string>()\n productTypeOptions.forEach((opt) => map.set(opt.value, opt.label))\n return map\n }, [productTypeOptions])\n\n const filters = React.useMemo<FilterDef[]>(() => [\n { id: 'status', label: t('catalog.products.filters.status'), type: 'text' },\n { id: 'isActive', label: t('catalog.products.filters.active'), type: 'checkbox' },\n { id: 'configurable', label: t('catalog.products.filters.configurable'), type: 'checkbox' },\n { id: 'productType', label: t('catalog.products.filters.productType', 'Type'), type: 'select', options: productTypeOptions },\n {\n id: 'channelIds',\n label: t('catalog.products.filters.channels'),\n type: 'tags',\n loadOptions: loadChannelOptions,\n options: channelOptions,\n formatValue: (val) => channelOptionsCache[val]?.label ?? val,\n formatDescription: (val) => channelOptionsCache[val]?.description ?? null,\n },\n {\n id: 'categoryIds',\n label: t('catalog.products.filters.categories', 'Categories'),\n type: 'tags',\n loadOptions: loadCategoryOptions,\n options: categoryOptions,\n formatValue: (val) => categoryOptionsCache[val]?.label ?? val,\n formatDescription: (val) => categoryOptionsCache[val]?.description ?? null,\n },\n {\n id: 'tagIds',\n label: t('catalog.products.filters.tags', 'Tags'),\n type: 'tags',\n loadOptions: loadTagOptions,\n options: tagOptions,\n formatValue: (val) => tagOptionsCache[val]?.label ?? val,\n },\n ], [\n categoryOptions,\n categoryOptionsCache,\n channelOptions,\n channelOptionsCache,\n loadCategoryOptions,\n loadChannelOptions,\n loadTagOptions,\n productTypeOptions,\n tagOptions,\n tagOptionsCache,\n t,\n ])\n\n const columns = React.useMemo<ColumnDef<ProductRow>[]>(() => {\n const base: ColumnDef<ProductRow>[] = [\n {\n id: 'media',\n header: '',\n size: 80,\n cell: ({ row }) => (\n <ProductImageCell\n mediaId={row.original.default_media_id}\n mediaUrl={row.original.default_media_url}\n title={row.original.title}\n cropType=\"contain\"\n />\n ),\n meta: { sticky: true },\n },\n {\n accessorKey: 'title',\n header: t('catalog.products.table.title', 'Title'),\n cell: ({ row }) => (\n <div className=\"flex flex-col\">\n <span className=\"font-medium\">{row.original.title || '\u2014'}</span>\n {row.original.subtitle ? (\n <span className=\"text-xs text-muted-foreground\">{row.original.subtitle}</span>\n ) : null}\n {row.original.handle ? (\n <span className=\"text-xs text-muted-foreground\">/{row.original.handle}</span>\n ) : null}\n {row.original.description ? (\n <span className=\"text-xs text-muted-foreground\">{markdownToPlainText(row.original.description)}</span>\n ) : null}\n </div>\n ),\n meta: { sticky: true },\n },\n {\n accessorKey: 'sku',\n header: t('catalog.products.table.sku', 'SKU'),\n cell: ({ getValue }) => {\n const value = getValue()\n return value ? <span className=\"font-mono text-xs\">{String(value)}</span> : <span className=\"text-xs text-muted-foreground\">\u2014</span>\n },\n },\n {\n accessorKey: 'product_type',\n header: t('catalog.products.table.type'),\n cell: ({ row }) => {\n const type = typeof row.original.product_type === 'string' ? row.original.product_type : 'simple'\n const label = productTypeLabelMap.get(type) ?? type\n return <span className=\"text-xs text-muted-foreground\">{label}</span>\n },\n },\n {\n accessorKey: 'is_configurable',\n header: t('catalog.products.table.configurable'),\n cell: ({ row }) => <BooleanIcon value={!!row.original.is_configurable} />,\n },\n {\n accessorKey: 'is_active',\n header: t('catalog.products.table.active'),\n cell: ({ row }) => <BooleanIcon value={!!row.original.is_active} />,\n },\n {\n accessorKey: 'pricing',\n header: t('catalog.products.table.price'),\n cell: ({ row }) => renderPrice(row.original.pricing, row.original.primary_currency_code),\n },\n {\n accessorKey: 'offers',\n header: t('catalog.products.table.channels'),\n cell: ({ row }) => renderOffers(row.original.offers),\n },\n {\n accessorKey: 'updated_at',\n header: t('catalog.products.table.updatedAt'),\n cell: ({ row }) => <span className=\"text-xs text-muted-foreground\">{formatDate(row.original.updated_at)}</span>,\n },\n ]\n return applyCustomFieldVisibility(base, customFieldDefs)\n }, [customFieldDefs, productTypeLabelMap, t])\n\n const handleSearchChange = React.useCallback((value: string) => {\n setSearch(value)\n setPage(1)\n }, [])\n\n const handleFiltersApply = React.useCallback((values: FilterValues) => {\n setFilterValues(values)\n setPage(1)\n }, [])\n\n const handleFiltersClear = React.useCallback(() => {\n setFilterValues({})\n setPage(1)\n }, [])\n\n const handleCustomFieldsetFilterChange = React.useCallback(\n (value: string | null) => {\n if (value === customFieldsetFilter) return\n setCustomFieldsetFilter(value)\n setFilterValues((prev) => {\n const entries = Object.entries(prev)\n if (!entries.some(([key]) => key.startsWith('cf_'))) return prev\n const next: FilterValues = {}\n entries.forEach(([key, val]) => {\n if (!key.startsWith('cf_')) next[key] = val\n })\n return next\n })\n setPage(1)\n },\n [customFieldsetFilter],\n )\n\n const handleRefresh = React.useCallback(() => {\n setReloadToken((token) => token + 1)\n }, [])\n\n const queryParams = React.useMemo(() => {\n const params = new URLSearchParams()\n params.set('page', String(page))\n params.set('pageSize', String(PAGE_SIZE))\n if (search.trim()) params.set('search', search.trim())\n const sort = sorting[0]\n if (sort?.id) {\n params.set('sortField', sort.id)\n params.set('sortDir', sort.desc ? 'desc' : 'asc')\n }\n const status = filterValues.status\n if (typeof status === 'string' && status.trim()) {\n params.set('status', status.trim())\n }\n if (filterValues.isActive === true) params.set('isActive', 'true')\n if (filterValues.isActive === false) params.set('isActive', 'false')\n if (filterValues.configurable === true) params.set('configurable', 'true')\n if (filterValues.configurable === false) params.set('configurable', 'false')\n if (typeof filterValues.productType === 'string' && filterValues.productType.trim()) {\n params.set('productType', filterValues.productType.trim())\n }\n if (Array.isArray(filterValues.channelIds) && filterValues.channelIds.length) {\n const values = filterValues.channelIds\n .map((value) => (typeof value === 'string' ? value : null))\n .filter((value): value is string => !!value)\n if (values.length) params.set('channelIds', values.join(','))\n }\n if (Array.isArray(filterValues.categoryIds) && filterValues.categoryIds.length) {\n const values = filterValues.categoryIds\n .map((value) => (typeof value === 'string' ? value : null))\n .filter((value): value is string => !!value)\n if (values.length) params.set('categoryIds', values.join(','))\n }\n if (Array.isArray(filterValues.tagIds) && filterValues.tagIds.length) {\n const values = filterValues.tagIds\n .map((value) => (typeof value === 'string' ? value : null))\n .filter((value): value is string => !!value)\n if (values.length) params.set('tagIds', values.join(','))\n }\n Object.entries(filterValues).forEach(([key, value]) => {\n if (!key.startsWith('cf_') || value == null) return\n if (Array.isArray(value)) {\n const entries = value\n .map((entry) => (typeof entry === 'string' ? entry.trim() : String(entry || '').trim()))\n .filter((entry) => entry.length > 0)\n if (entries.length) params.set(key, entries.join(','))\n } else if (typeof value === 'object' && value !== null && ('from' in (value as Record<string, unknown>) || 'to' in (value as Record<string, unknown>))) {\n const range = value as { from?: string; to?: string }\n if (typeof range.from === 'string' && range.from.trim().length) {\n params.set(`${key}:from`, range.from.trim())\n }\n if (typeof range.to === 'string' && range.to.trim().length) {\n params.set(`${key}:to`, range.to.trim())\n }\n } else if (typeof value === 'string' && value.trim()) {\n params.set(key, value.trim())\n }\n })\n if (typeof customFieldsetFilter === 'string' && customFieldsetFilter.trim().length > 0) {\n params.set('customFieldset', customFieldsetFilter.trim())\n }\n return params.toString()\n }, [customFieldsetFilter, filterValues, page, search, sorting])\n\n React.useEffect(() => {\n let cancelled = false\n async function load() {\n setIsLoading(true)\n setCacheStatus(null)\n try {\n const fallback: ProductsResponse = { items: [], total: 0, totalPages: 1 }\n const call = await apiCall<ProductsResponse>(\n `/api/catalog/products?${queryParams}`,\n undefined,\n { fallback },\n )\n if (!call.ok) {\n const message = t('catalog.products.list.error.load', 'Failed to load products')\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 normalized = items.filter((item): item is ProductRow => typeof item?.id === 'string')\n setRows(normalized)\n setTotal(typeof payload.total === 'number' ? payload.total : normalized.length)\n setTotalPages(typeof payload.totalPages === 'number' ? payload.totalPages : 1)\n setTotalIsCapped(payload.totalIsCapped === true)\n } catch (error) {\n if (!cancelled) {\n setCacheStatus(null)\n const message =\n error instanceof Error\n ? error.message\n : t('catalog.products.list.error.load', 'Failed to load products')\n flash(message, 'error')\n }\n } finally {\n if (!cancelled) setIsLoading(false)\n }\n }\n load()\n return () => {\n cancelled = true\n }\n }, [queryParams, reloadToken, scopeVersion, t])\n\n const handleDelete = React.useCallback(async (row: ProductRow) => {\n const confirmed = await confirm({\n title: t('catalog.products.list.deleteConfirm', 'Delete this product?'),\n variant: 'destructive',\n })\n if (!confirmed) return\n try {\n const headers = buildOptimisticLockHeader(typeof row.updated_at === 'string' ? row.updated_at : null)\n await withScopedApiRequestHeaders(headers, () => (\n deleteCrud('catalog/products', row.id, {\n errorMessage: t('catalog.products.list.error.delete', 'Failed to delete product'),\n })\n ))\n flash(t('catalog.products.flash.deleted', 'Product deleted'), 'success')\n setReloadToken((token) => token + 1)\n } catch (error) {\n const message =\n error instanceof Error\n ? error.message\n : t('catalog.products.list.error.delete', 'Failed to delete product')\n flash(message, 'error')\n }\n }, [confirm, t])\n\n React.useEffect(() => {\n if (!onSnapshotChange) return\n onSnapshotChange({ search, filterValues, total })\n }, [onSnapshotChange, search, filterValues, total])\n\n const currentParams = React.useMemo(() => Object.fromEntries(new URLSearchParams(queryParams)), [queryParams])\n\n const exportConfig = React.useMemo(() => ({\n view: {\n getUrl: (format: DataTableExportFormat) =>\n buildCrudExportUrl('catalog/products', { ...currentParams, exportScope: 'view' }, format),\n },\n full: {\n getUrl: (format: DataTableExportFormat) =>\n buildCrudExportUrl('catalog/products', { ...currentParams, exportScope: 'full', all: 'true' }, format),\n },\n }), [currentParams])\n\n return (\n <>\n <DataTable<ProductRow>\n title={t('catalog.products.page.title', 'Products & services')}\n entityId={ENTITY_ID}\n customFieldFilterKeyExtras={[scopeVersion, reloadToken]}\n refreshButton={{\n label: t('catalog.products.actions.refresh', 'Refresh'),\n onRefresh: handleRefresh,\n isRefreshing: isLoading,\n }}\n actions={(\n <div className=\"flex items-center gap-2\">\n {extraActions}\n <Button asChild>\n <Link href=\"/backend/catalog/products/create\">\n {t('catalog.products.actions.create', 'Create')}\n </Link>\n </Button>\n </div>\n )}\n columns={columns}\n data={rows}\n emptyState={(\n <ListEmptyState\n entityName={t('catalog.products.page.title', 'Products & services')}\n createHref=\"/backend/catalog/products/create\"\n createLabel={t('catalog.products.actions.create', 'Create')}\n />\n )}\n searchValue={search}\n onSearchChange={handleSearchChange}\n filters={filters}\n filterValues={filterValues}\n onFiltersApply={handleFiltersApply}\n onFiltersClear={handleFiltersClear}\n onCustomFieldFilterFieldsetChange={handleCustomFieldsetFilterChange}\n sorting={sorting}\n onSortingChange={setSorting}\n injectionSpotId={extensionPoints.hosts.productsTable.baseSpotId}\n injectionContext={{\n search,\n filters: filterValues,\n customFieldset: customFieldsetFilter,\n page,\n sorting,\n scopeVersion,\n // Step 5.15: surface `total` so the merchandising AI widget\n // (rendered in `data-table:catalog.products:header`) can build\n // a selection-aware pageContext per spec \u00A710.1 without taking a\n // dependency on the host page.\n total,\n totalMatching: total,\n // `total` is a floor when the server capped the count, so the\n // merchandising widget must not present it as an exact match count.\n totalIsCapped,\n }}\n pagination={{\n page,\n pageSize: PAGE_SIZE,\n total,\n totalPages,\n totalIsCapped,\n onPageChange: setPage,\n cacheStatus,\n }}\n exporter={exportConfig}\n isLoading={isLoading}\n perspective={{ tableId: extensionPoints.hosts.productsTable.tableId }}\n stickyActionsColumn\n rowActions={(row) => (\n <RowActions\n items={[\n {\n id: 'edit',\n label: t('catalog.products.table.actions.edit', 'Edit'),\n href: `/backend/catalog/products/${row.id}`,\n },\n {\n id: 'delete',\n label: t('catalog.products.table.actions.delete', 'Delete'),\n destructive: true,\n onSelect: () => {\n void handleDelete(row)\n },\n },\n ]}\n />\n )}\n />\n {ConfirmDialogElement}\n </>\n )\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -29,6 +29,7 @@ function normalizeFilters(context) {
29
29
  }
30
30
  function computeCatalogMerchandisingPageContext(context) {
31
31
  const totalMatching = readNumber(context?.totalMatching ?? context?.total);
32
+ const totalMatchingIsCapped = context?.totalIsCapped === true;
32
33
  const selectedRowIds = Array.isArray(context?.selectedRowIds) ? context.selectedRowIds : [];
33
34
  const selectedCount = selectedRowIds.length > 0 ? selectedRowIds.length : readNumber(context?.selectedCount);
34
35
  return {
@@ -39,6 +40,7 @@ function computeCatalogMerchandisingPageContext(context) {
39
40
  extra: {
40
41
  filter: normalizeFilters(context),
41
42
  totalMatching,
43
+ totalMatchingIsCapped,
42
44
  selectedCount
43
45
  }
44
46
  };
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../../src/modules/catalog/widgets/injection/merchandising-assistant-trigger/widget.client.tsx"],
4
- "sourcesContent": ["\"use client\"\n\n/**\n * Step 5.15 \u2014 Catalog merchandising AiChat injection widget.\n *\n * Reuses the Step 4.9 `MerchandisingAssistantSheet` component but loads\n * it through the widget-injection system instead of being imported\n * directly from the products list page. `pageContext` follows spec \u00A710.1\n * exactly and is derived from the DataTable's injection context (filter\n * snapshot + total-matching count). Selection data is not exposed by the\n * shared DataTable today (Phase 2 contract); `selectedCount` ships as 0\n * until the host lifts selection into injection context.\n */\n\nimport * as React from 'react'\nimport MerchandisingAssistantSheet, {\n type MerchandisingPageContext,\n type MerchandisingPageContextFilter,\n} from '../../../backend/catalog/products/MerchandisingAssistantSheet'\n\ninterface HostInjectionContext {\n search?: string\n filters?: {\n categoryIds?: unknown\n tagIds?: unknown\n status?: unknown\n }\n customFieldset?: string | null\n page?: number\n sorting?: unknown\n scopeVersion?: unknown\n total?: number | string\n totalMatching?: number | string\n /** Selected row IDs from DataTable (auto-enriched when bulk actions are present). */\n selectedRowIds?: string[]\n selectedCount?: number\n}\n\ninterface MerchandisingAssistantTriggerProps {\n context?: HostInjectionContext\n}\n\nfunction readString(value: unknown): string | null {\n return typeof value === 'string' && value.length > 0 ? value : null\n}\n\nfunction readNumber(value: unknown): number {\n if (typeof value === 'number' && Number.isFinite(value)) return value\n if (typeof value === 'string') {\n const parsed = Number.parseInt(value, 10)\n if (Number.isFinite(parsed)) return parsed\n }\n return 0\n}\n\nfunction normalizeFilters(context: HostInjectionContext | undefined): MerchandisingPageContextFilter {\n const rawCategories = context?.filters?.categoryIds\n const categoryIds = Array.isArray(rawCategories) ? rawCategories : []\n const firstCategoryId = categoryIds\n .map(readString)\n .find((value): value is string => value !== null && value.length > 0) ?? null\n\n const rawTags = context?.filters?.tagIds\n const tags = Array.isArray(rawTags)\n ? rawTags.map(readString).filter((value): value is string => value !== null)\n : []\n\n const status = readString(context?.filters?.status)\n\n return {\n categoryId: firstCategoryId,\n priceRange: null,\n tags,\n status,\n }\n}\n\n/**\n * Exposed for unit tests so the page-context derivation is exercisable\n * without mounting the widget.\n */\nexport function computeCatalogMerchandisingPageContext(\n context: HostInjectionContext | undefined,\n): MerchandisingPageContext {\n const totalMatching = readNumber(context?.totalMatching ?? context?.total)\n const selectedRowIds = Array.isArray(context?.selectedRowIds) ? context.selectedRowIds : []\n const selectedCount = selectedRowIds.length > 0 ? selectedRowIds.length : readNumber(context?.selectedCount)\n return {\n view: 'catalog.products.list',\n entityType: 'catalog.products.list',\n recordType: null,\n recordId: selectedRowIds.join(','),\n extra: {\n filter: normalizeFilters(context),\n totalMatching,\n selectedCount,\n },\n }\n}\n\nexport default function MerchandisingAssistantTriggerWidget({\n context,\n}: MerchandisingAssistantTriggerProps) {\n const pageContext = React.useMemo(\n () => computeCatalogMerchandisingPageContext(context),\n [context],\n )\n return <MerchandisingAssistantSheet pageContext={pageContext} />\n}\n"],
5
- "mappings": ";AA2GS;AA7FT,YAAY,WAAW;AACvB,OAAO,iCAGA;AAwBP,SAAS,WAAW,OAA+B;AACjD,SAAO,OAAO,UAAU,YAAY,MAAM,SAAS,IAAI,QAAQ;AACjE;AAEA,SAAS,WAAW,OAAwB;AAC1C,MAAI,OAAO,UAAU,YAAY,OAAO,SAAS,KAAK,EAAG,QAAO;AAChE,MAAI,OAAO,UAAU,UAAU;AAC7B,UAAM,SAAS,OAAO,SAAS,OAAO,EAAE;AACxC,QAAI,OAAO,SAAS,MAAM,EAAG,QAAO;AAAA,EACtC;AACA,SAAO;AACT;AAEA,SAAS,iBAAiB,SAA2E;AACnG,QAAM,gBAAgB,SAAS,SAAS;AACxC,QAAM,cAAc,MAAM,QAAQ,aAAa,IAAI,gBAAgB,CAAC;AACpE,QAAM,kBAAkB,YACrB,IAAI,UAAU,EACd,KAAK,CAAC,UAA2B,UAAU,QAAQ,MAAM,SAAS,CAAC,KAAK;AAE3E,QAAM,UAAU,SAAS,SAAS;AAClC,QAAM,OAAO,MAAM,QAAQ,OAAO,IAC9B,QAAQ,IAAI,UAAU,EAAE,OAAO,CAAC,UAA2B,UAAU,IAAI,IACzE,CAAC;AAEL,QAAM,SAAS,WAAW,SAAS,SAAS,MAAM;AAElD,SAAO;AAAA,IACL,YAAY;AAAA,IACZ,YAAY;AAAA,IACZ;AAAA,IACA;AAAA,EACF;AACF;AAMO,SAAS,uCACd,SAC0B;AAC1B,QAAM,gBAAgB,WAAW,SAAS,iBAAiB,SAAS,KAAK;AACzE,QAAM,iBAAiB,MAAM,QAAQ,SAAS,cAAc,IAAI,QAAQ,iBAAiB,CAAC;AAC1F,QAAM,gBAAgB,eAAe,SAAS,IAAI,eAAe,SAAS,WAAW,SAAS,aAAa;AAC3G,SAAO;AAAA,IACL,MAAM;AAAA,IACN,YAAY;AAAA,IACZ,YAAY;AAAA,IACZ,UAAU,eAAe,KAAK,GAAG;AAAA,IACjC,OAAO;AAAA,MACL,QAAQ,iBAAiB,OAAO;AAAA,MAChC;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACF;AAEe,SAAR,oCAAqD;AAAA,EAC1D;AACF,GAAuC;AACrC,QAAM,cAAc,MAAM;AAAA,IACxB,MAAM,uCAAuC,OAAO;AAAA,IACpD,CAAC,OAAO;AAAA,EACV;AACA,SAAO,oBAAC,+BAA4B,aAA0B;AAChE;",
4
+ "sourcesContent": ["\"use client\"\n\n/**\n * Step 5.15 \u2014 Catalog merchandising AiChat injection widget.\n *\n * Reuses the Step 4.9 `MerchandisingAssistantSheet` component but loads\n * it through the widget-injection system instead of being imported\n * directly from the products list page. `pageContext` follows spec \u00A710.1\n * exactly and is derived from the DataTable's injection context (filter\n * snapshot + total-matching count). Selection data is not exposed by the\n * shared DataTable today (Phase 2 contract); `selectedCount` ships as 0\n * until the host lifts selection into injection context.\n */\n\nimport * as React from 'react'\nimport MerchandisingAssistantSheet, {\n type MerchandisingPageContext,\n type MerchandisingPageContextFilter,\n} from '../../../backend/catalog/products/MerchandisingAssistantSheet'\n\ninterface HostInjectionContext {\n search?: string\n filters?: {\n categoryIds?: unknown\n tagIds?: unknown\n status?: unknown\n }\n customFieldset?: string | null\n page?: number\n sorting?: unknown\n scopeVersion?: unknown\n total?: number | string\n totalMatching?: number | string\n /** `totalMatching` is a floor, not an exact count (server-capped list count). */\n totalIsCapped?: boolean\n /** Selected row IDs from DataTable (auto-enriched when bulk actions are present). */\n selectedRowIds?: string[]\n selectedCount?: number\n}\n\ninterface MerchandisingAssistantTriggerProps {\n context?: HostInjectionContext\n}\n\nfunction readString(value: unknown): string | null {\n return typeof value === 'string' && value.length > 0 ? value : null\n}\n\nfunction readNumber(value: unknown): number {\n if (typeof value === 'number' && Number.isFinite(value)) return value\n if (typeof value === 'string') {\n const parsed = Number.parseInt(value, 10)\n if (Number.isFinite(parsed)) return parsed\n }\n return 0\n}\n\nfunction normalizeFilters(context: HostInjectionContext | undefined): MerchandisingPageContextFilter {\n const rawCategories = context?.filters?.categoryIds\n const categoryIds = Array.isArray(rawCategories) ? rawCategories : []\n const firstCategoryId = categoryIds\n .map(readString)\n .find((value): value is string => value !== null && value.length > 0) ?? null\n\n const rawTags = context?.filters?.tagIds\n const tags = Array.isArray(rawTags)\n ? rawTags.map(readString).filter((value): value is string => value !== null)\n : []\n\n const status = readString(context?.filters?.status)\n\n return {\n categoryId: firstCategoryId,\n priceRange: null,\n tags,\n status,\n }\n}\n\n/**\n * Exposed for unit tests so the page-context derivation is exercisable\n * without mounting the widget.\n */\nexport function computeCatalogMerchandisingPageContext(\n context: HostInjectionContext | undefined,\n): MerchandisingPageContext {\n const totalMatching = readNumber(context?.totalMatching ?? context?.total)\n const totalMatchingIsCapped = context?.totalIsCapped === true\n const selectedRowIds = Array.isArray(context?.selectedRowIds) ? context.selectedRowIds : []\n const selectedCount = selectedRowIds.length > 0 ? selectedRowIds.length : readNumber(context?.selectedCount)\n return {\n view: 'catalog.products.list',\n entityType: 'catalog.products.list',\n recordType: null,\n recordId: selectedRowIds.join(','),\n extra: {\n filter: normalizeFilters(context),\n totalMatching,\n totalMatchingIsCapped,\n selectedCount,\n },\n }\n}\n\nexport default function MerchandisingAssistantTriggerWidget({\n context,\n}: MerchandisingAssistantTriggerProps) {\n const pageContext = React.useMemo(\n () => computeCatalogMerchandisingPageContext(context),\n [context],\n )\n return <MerchandisingAssistantSheet pageContext={pageContext} />\n}\n"],
5
+ "mappings": ";AA+GS;AAjGT,YAAY,WAAW;AACvB,OAAO,iCAGA;AA0BP,SAAS,WAAW,OAA+B;AACjD,SAAO,OAAO,UAAU,YAAY,MAAM,SAAS,IAAI,QAAQ;AACjE;AAEA,SAAS,WAAW,OAAwB;AAC1C,MAAI,OAAO,UAAU,YAAY,OAAO,SAAS,KAAK,EAAG,QAAO;AAChE,MAAI,OAAO,UAAU,UAAU;AAC7B,UAAM,SAAS,OAAO,SAAS,OAAO,EAAE;AACxC,QAAI,OAAO,SAAS,MAAM,EAAG,QAAO;AAAA,EACtC;AACA,SAAO;AACT;AAEA,SAAS,iBAAiB,SAA2E;AACnG,QAAM,gBAAgB,SAAS,SAAS;AACxC,QAAM,cAAc,MAAM,QAAQ,aAAa,IAAI,gBAAgB,CAAC;AACpE,QAAM,kBAAkB,YACrB,IAAI,UAAU,EACd,KAAK,CAAC,UAA2B,UAAU,QAAQ,MAAM,SAAS,CAAC,KAAK;AAE3E,QAAM,UAAU,SAAS,SAAS;AAClC,QAAM,OAAO,MAAM,QAAQ,OAAO,IAC9B,QAAQ,IAAI,UAAU,EAAE,OAAO,CAAC,UAA2B,UAAU,IAAI,IACzE,CAAC;AAEL,QAAM,SAAS,WAAW,SAAS,SAAS,MAAM;AAElD,SAAO;AAAA,IACL,YAAY;AAAA,IACZ,YAAY;AAAA,IACZ;AAAA,IACA;AAAA,EACF;AACF;AAMO,SAAS,uCACd,SAC0B;AAC1B,QAAM,gBAAgB,WAAW,SAAS,iBAAiB,SAAS,KAAK;AACzE,QAAM,wBAAwB,SAAS,kBAAkB;AACzD,QAAM,iBAAiB,MAAM,QAAQ,SAAS,cAAc,IAAI,QAAQ,iBAAiB,CAAC;AAC1F,QAAM,gBAAgB,eAAe,SAAS,IAAI,eAAe,SAAS,WAAW,SAAS,aAAa;AAC3G,SAAO;AAAA,IACL,MAAM;AAAA,IACN,YAAY;AAAA,IACZ,YAAY;AAAA,IACZ,UAAU,eAAe,KAAK,GAAG;AAAA,IACjC,OAAO;AAAA,MACL,QAAQ,iBAAiB,OAAO;AAAA,MAChC;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACF;AAEe,SAAR,oCAAqD;AAAA,EAC1D;AACF,GAAuC;AACrC,QAAM,cAAc,MAAM;AAAA,IACxB,MAAM,uCAAuC,OAAO;AAAA,IACpD,CAAC,OAAO;AAAA,EACV;AACA,SAAO,oBAAC,+BAA4B,aAA0B;AAChE;",
6
6
  "names": []
7
7
  }
@@ -12,6 +12,7 @@ function ChannelsListPage() {
12
12
  const [rows, setRows] = React.useState([]);
13
13
  const [total, setTotal] = React.useState(0);
14
14
  const [totalPages, setTotalPages] = React.useState(1);
15
+ const [totalIsCapped, setTotalIsCapped] = React.useState(false);
15
16
  const [page, setPage] = React.useState(1);
16
17
  const [isLoading, setIsLoading] = React.useState(true);
17
18
  const [errorMessage, setErrorMessage] = React.useState(null);
@@ -49,6 +50,7 @@ function ChannelsListPage() {
49
50
  setRows(Array.isArray(data.items) ? data.items : []);
50
51
  setTotal(typeof data.total === "number" ? data.total : 0);
51
52
  setTotalPages(typeof data.totalPages === "number" ? data.totalPages : 1);
53
+ setTotalIsCapped(data.totalIsCapped === true);
52
54
  }
53
55
  setIsLoading(false);
54
56
  }
@@ -104,6 +106,7 @@ function ChannelsListPage() {
104
106
  pageSize,
105
107
  total,
106
108
  totalPages,
109
+ totalIsCapped,
107
110
  onPageChange: setPage
108
111
  }
109
112
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../../src/modules/communication_channels/backend/communication_channels/channels/page.tsx"],
4
- "sourcesContent": ["'use client'\n\nimport * as React from 'react'\nimport { extensionPoints } from '@open-mercato/core/modules/communication_channels/extension-points'\nimport type { LegacyColumnDef as ColumnDef } from '@tanstack/react-table/legacy'\nimport { Page, PageBody } from '@open-mercato/ui/backend/Page'\nimport { DataTable } from '@open-mercato/ui/backend/DataTable'\nimport { Tag } from '@open-mercato/ui/primitives/tag'\nimport { apiCall } from '@open-mercato/ui/backend/utils/apiCall'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\n\ntype ChannelRow = {\n id: string\n providerKey: string\n channelType: string\n displayName: string\n externalIdentifier: string | null\n isActive: boolean\n capabilities: Record<string, unknown> | null\n createdAt: string | null\n}\n\ntype ChannelListResponse = {\n items?: ChannelRow[]\n total?: number\n totalPages?: number\n}\n\nexport default function ChannelsListPage() {\n const t = useT()\n const [rows, setRows] = React.useState<ChannelRow[]>([])\n const [total, setTotal] = React.useState(0)\n const [totalPages, setTotalPages] = React.useState(1)\n const [page, setPage] = React.useState(1)\n const [isLoading, setIsLoading] = React.useState(true)\n const [errorMessage, setErrorMessage] = React.useState<string | null>(null)\n // Bumped by injected connect widgets (FCM/APNs/Expo) so a freshly connected\n // tenant-wide channel appears without a manual page reload.\n const [reloadToken, setReloadToken] = React.useState(0)\n const pageSize = 50\n\n const reload = React.useCallback(() => setReloadToken((token) => token + 1), [])\n const injectionContext = React.useMemo(\n () => ({ tableId: extensionPoints.hosts.channelsTable.tableId, reload }),\n [reload],\n )\n\n React.useEffect(() => {\n let cancelled = false\n async function load() {\n setIsLoading(true)\n setErrorMessage(null)\n const response = await apiCall<ChannelListResponse>(\n `/api/communication_channels/channels?page=${page}&pageSize=${pageSize}`,\n ).catch((err: unknown) => {\n return {\n ok: false,\n result: { error: err instanceof Error ? err.message : 'Failed to load channels' },\n }\n })\n if (cancelled) return\n if (!response.ok) {\n const errBody = response.result as { error?: string } | undefined\n setErrorMessage(\n errBody?.error ?? t('communication_channels.errors.loadList', 'Failed to load channels'),\n )\n setRows([])\n setTotal(0)\n setTotalPages(1)\n } else {\n const data = (response.result ?? {}) as ChannelListResponse\n setRows(Array.isArray(data.items) ? data.items : [])\n setTotal(typeof data.total === 'number' ? data.total : 0)\n setTotalPages(typeof data.totalPages === 'number' ? data.totalPages : 1)\n }\n setIsLoading(false)\n }\n void load()\n return () => {\n cancelled = true\n }\n }, [page, reloadToken, t])\n\n const columns = React.useMemo<ColumnDef<ChannelRow>[]>(\n () => [\n {\n header: t('communication_channels.columns.displayName', 'Channel'),\n accessorKey: 'displayName',\n },\n {\n header: t('communication_channels.columns.provider', 'Provider'),\n accessorKey: 'providerKey',\n },\n {\n header: t('communication_channels.columns.type', 'Type'),\n accessorKey: 'channelType',\n },\n {\n header: t('communication_channels.columns.identifier', 'External ID'),\n accessorKey: 'externalIdentifier',\n cell: ({ row }) => row.original.externalIdentifier ?? '\u2014',\n meta: { truncate: true, maxWidth: 240 },\n },\n {\n header: t('communication_channels.columns.status', 'Status'),\n accessorKey: 'isActive',\n cell: ({ row }) =>\n row.original.isActive ? (\n <Tag variant=\"success\" dot>\n {t('communication_channels.status.active', 'Active')}\n </Tag>\n ) : (\n <Tag variant=\"neutral\">\n {t('communication_channels.status.inactive', 'Inactive')}\n </Tag>\n ),\n },\n ],\n [t],\n )\n\n return (\n <Page>\n <PageBody>\n <DataTable<ChannelRow>\n title={t('communication_channels.nav.title', 'Communication Channels')}\n extensionTableId={extensionPoints.hosts.channelsTable.tableId}\n injectionContext={injectionContext}\n columns={columns}\n data={rows}\n isLoading={isLoading}\n error={errorMessage}\n emptyState={t(\n 'communication_channels.emptyState',\n 'No shared channels yet. This page lists shared, tenant-wide channels. Your personal email mailbox is private \u2014 connect and manage it under Profile \u2192 Communication Channels.',\n )}\n pagination={{\n page,\n pageSize,\n total,\n totalPages,\n onPageChange: setPage,\n }}\n />\n </PageBody>\n </Page>\n )\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["'use client'\n\nimport * as React from 'react'\nimport { extensionPoints } from '@open-mercato/core/modules/communication_channels/extension-points'\nimport type { LegacyColumnDef as ColumnDef } from '@tanstack/react-table/legacy'\nimport { Page, PageBody } from '@open-mercato/ui/backend/Page'\nimport { DataTable } from '@open-mercato/ui/backend/DataTable'\nimport { Tag } from '@open-mercato/ui/primitives/tag'\nimport { apiCall } from '@open-mercato/ui/backend/utils/apiCall'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\n\ntype ChannelRow = {\n id: string\n providerKey: string\n channelType: string\n displayName: string\n externalIdentifier: string | null\n isActive: boolean\n capabilities: Record<string, unknown> | null\n createdAt: string | null\n}\n\ntype ChannelListResponse = {\n items?: ChannelRow[]\n total?: number\n totalPages?: number\n totalIsCapped?: boolean\n}\n\nexport default function ChannelsListPage() {\n const t = useT()\n const [rows, setRows] = React.useState<ChannelRow[]>([])\n const [total, setTotal] = React.useState(0)\n const [totalPages, setTotalPages] = React.useState(1)\n const [totalIsCapped, setTotalIsCapped] = React.useState(false)\n const [page, setPage] = React.useState(1)\n const [isLoading, setIsLoading] = React.useState(true)\n const [errorMessage, setErrorMessage] = React.useState<string | null>(null)\n // Bumped by injected connect widgets (FCM/APNs/Expo) so a freshly connected\n // tenant-wide channel appears without a manual page reload.\n const [reloadToken, setReloadToken] = React.useState(0)\n const pageSize = 50\n\n const reload = React.useCallback(() => setReloadToken((token) => token + 1), [])\n const injectionContext = React.useMemo(\n () => ({ tableId: extensionPoints.hosts.channelsTable.tableId, reload }),\n [reload],\n )\n\n React.useEffect(() => {\n let cancelled = false\n async function load() {\n setIsLoading(true)\n setErrorMessage(null)\n const response = await apiCall<ChannelListResponse>(\n `/api/communication_channels/channels?page=${page}&pageSize=${pageSize}`,\n ).catch((err: unknown) => {\n return {\n ok: false,\n result: { error: err instanceof Error ? err.message : 'Failed to load channels' },\n }\n })\n if (cancelled) return\n if (!response.ok) {\n const errBody = response.result as { error?: string } | undefined\n setErrorMessage(\n errBody?.error ?? t('communication_channels.errors.loadList', 'Failed to load channels'),\n )\n setRows([])\n setTotal(0)\n setTotalPages(1)\n } else {\n const data = (response.result ?? {}) as ChannelListResponse\n setRows(Array.isArray(data.items) ? data.items : [])\n setTotal(typeof data.total === 'number' ? data.total : 0)\n setTotalPages(typeof data.totalPages === 'number' ? data.totalPages : 1)\n setTotalIsCapped(data.totalIsCapped === true)\n }\n setIsLoading(false)\n }\n void load()\n return () => {\n cancelled = true\n }\n }, [page, reloadToken, t])\n\n const columns = React.useMemo<ColumnDef<ChannelRow>[]>(\n () => [\n {\n header: t('communication_channels.columns.displayName', 'Channel'),\n accessorKey: 'displayName',\n },\n {\n header: t('communication_channels.columns.provider', 'Provider'),\n accessorKey: 'providerKey',\n },\n {\n header: t('communication_channels.columns.type', 'Type'),\n accessorKey: 'channelType',\n },\n {\n header: t('communication_channels.columns.identifier', 'External ID'),\n accessorKey: 'externalIdentifier',\n cell: ({ row }) => row.original.externalIdentifier ?? '\u2014',\n meta: { truncate: true, maxWidth: 240 },\n },\n {\n header: t('communication_channels.columns.status', 'Status'),\n accessorKey: 'isActive',\n cell: ({ row }) =>\n row.original.isActive ? (\n <Tag variant=\"success\" dot>\n {t('communication_channels.status.active', 'Active')}\n </Tag>\n ) : (\n <Tag variant=\"neutral\">\n {t('communication_channels.status.inactive', 'Inactive')}\n </Tag>\n ),\n },\n ],\n [t],\n )\n\n return (\n <Page>\n <PageBody>\n <DataTable<ChannelRow>\n title={t('communication_channels.nav.title', 'Communication Channels')}\n extensionTableId={extensionPoints.hosts.channelsTable.tableId}\n injectionContext={injectionContext}\n columns={columns}\n data={rows}\n isLoading={isLoading}\n error={errorMessage}\n emptyState={t(\n 'communication_channels.emptyState',\n 'No shared channels yet. This page lists shared, tenant-wide channels. Your personal email mailbox is private \u2014 connect and manage it under Profile \u2192 Communication Channels.',\n )}\n pagination={{\n page,\n pageSize,\n total,\n totalPages,\n totalIsCapped,\n onPageChange: setPage,\n }}\n />\n </PageBody>\n </Page>\n )\n}\n"],
5
+ "mappings": ";AA+GY;AA7GZ,YAAY,WAAW;AACvB,SAAS,uBAAuB;AAEhC,SAAS,MAAM,gBAAgB;AAC/B,SAAS,iBAAiB;AAC1B,SAAS,WAAW;AACpB,SAAS,eAAe;AACxB,SAAS,YAAY;AAoBN,SAAR,mBAAoC;AACzC,QAAM,IAAI,KAAK;AACf,QAAM,CAAC,MAAM,OAAO,IAAI,MAAM,SAAuB,CAAC,CAAC;AACvD,QAAM,CAAC,OAAO,QAAQ,IAAI,MAAM,SAAS,CAAC;AAC1C,QAAM,CAAC,YAAY,aAAa,IAAI,MAAM,SAAS,CAAC;AACpD,QAAM,CAAC,eAAe,gBAAgB,IAAI,MAAM,SAAS,KAAK;AAC9D,QAAM,CAAC,MAAM,OAAO,IAAI,MAAM,SAAS,CAAC;AACxC,QAAM,CAAC,WAAW,YAAY,IAAI,MAAM,SAAS,IAAI;AACrD,QAAM,CAAC,cAAc,eAAe,IAAI,MAAM,SAAwB,IAAI;AAG1E,QAAM,CAAC,aAAa,cAAc,IAAI,MAAM,SAAS,CAAC;AACtD,QAAM,WAAW;AAEjB,QAAM,SAAS,MAAM,YAAY,MAAM,eAAe,CAAC,UAAU,QAAQ,CAAC,GAAG,CAAC,CAAC;AAC/E,QAAM,mBAAmB,MAAM;AAAA,IAC7B,OAAO,EAAE,SAAS,gBAAgB,MAAM,cAAc,SAAS,OAAO;AAAA,IACtE,CAAC,MAAM;AAAA,EACT;AAEA,QAAM,UAAU,MAAM;AACpB,QAAI,YAAY;AAChB,mBAAe,OAAO;AACpB,mBAAa,IAAI;AACjB,sBAAgB,IAAI;AACpB,YAAM,WAAW,MAAM;AAAA,QACrB,6CAA6C,IAAI,aAAa,QAAQ;AAAA,MACxE,EAAE,MAAM,CAAC,QAAiB;AACxB,eAAO;AAAA,UACL,IAAI;AAAA,UACJ,QAAQ,EAAE,OAAO,eAAe,QAAQ,IAAI,UAAU,0BAA0B;AAAA,QAClF;AAAA,MACF,CAAC;AACD,UAAI,UAAW;AACf,UAAI,CAAC,SAAS,IAAI;AAChB,cAAM,UAAU,SAAS;AACzB;AAAA,UACE,SAAS,SAAS,EAAE,0CAA0C,yBAAyB;AAAA,QACzF;AACA,gBAAQ,CAAC,CAAC;AACV,iBAAS,CAAC;AACV,sBAAc,CAAC;AAAA,MACjB,OAAO;AACL,cAAM,OAAQ,SAAS,UAAU,CAAC;AAClC,gBAAQ,MAAM,QAAQ,KAAK,KAAK,IAAI,KAAK,QAAQ,CAAC,CAAC;AACnD,iBAAS,OAAO,KAAK,UAAU,WAAW,KAAK,QAAQ,CAAC;AACxD,sBAAc,OAAO,KAAK,eAAe,WAAW,KAAK,aAAa,CAAC;AACvE,yBAAiB,KAAK,kBAAkB,IAAI;AAAA,MAC9C;AACA,mBAAa,KAAK;AAAA,IACpB;AACA,SAAK,KAAK;AACV,WAAO,MAAM;AACX,kBAAY;AAAA,IACd;AAAA,EACF,GAAG,CAAC,MAAM,aAAa,CAAC,CAAC;AAEzB,QAAM,UAAU,MAAM;AAAA,IACpB,MAAM;AAAA,MACJ;AAAA,QACE,QAAQ,EAAE,8CAA8C,SAAS;AAAA,QACjE,aAAa;AAAA,MACf;AAAA,MACA;AAAA,QACE,QAAQ,EAAE,2CAA2C,UAAU;AAAA,QAC/D,aAAa;AAAA,MACf;AAAA,MACA;AAAA,QACE,QAAQ,EAAE,uCAAuC,MAAM;AAAA,QACvD,aAAa;AAAA,MACf;AAAA,MACA;AAAA,QACE,QAAQ,EAAE,6CAA6C,aAAa;AAAA,QACpE,aAAa;AAAA,QACb,MAAM,CAAC,EAAE,IAAI,MAAM,IAAI,SAAS,sBAAsB;AAAA,QACtD,MAAM,EAAE,UAAU,MAAM,UAAU,IAAI;AAAA,MACxC;AAAA,MACA;AAAA,QACE,QAAQ,EAAE,yCAAyC,QAAQ;AAAA,QAC3D,aAAa;AAAA,QACb,MAAM,CAAC,EAAE,IAAI,MACX,IAAI,SAAS,WACX,oBAAC,OAAI,SAAQ,WAAU,KAAG,MACvB,YAAE,wCAAwC,QAAQ,GACrD,IAEA,oBAAC,OAAI,SAAQ,WACV,YAAE,0CAA0C,UAAU,GACzD;AAAA,MAEN;AAAA,IACF;AAAA,IACA,CAAC,CAAC;AAAA,EACJ;AAEA,SACE,oBAAC,QACC,8BAAC,YACC;AAAA,IAAC;AAAA;AAAA,MACC,OAAO,EAAE,oCAAoC,wBAAwB;AAAA,MACrE,kBAAkB,gBAAgB,MAAM,cAAc;AAAA,MACtD;AAAA,MACA;AAAA,MACA,MAAM;AAAA,MACN;AAAA,MACA,OAAO;AAAA,MACP,YAAY;AAAA,QACV;AAAA,QACA;AAAA,MACF;AAAA,MACA,YAAY;AAAA,QACV;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA,cAAc;AAAA,MAChB;AAAA;AAAA,EACF,GACF,GACF;AAEJ;",
6
6
  "names": []
7
7
  }
@@ -227,6 +227,15 @@ const SYSTEM_STATUS_VARIABLES = [
227
227
  docUrl: `${SYSTEM_STATUS_DOC_BASE}#optimize_index_coverage_stats`,
228
228
  defaultValue: "false"
229
229
  },
230
+ {
231
+ key: "OM_LIST_COUNT_CAP",
232
+ category: "query_index",
233
+ kind: "string",
234
+ labelKey: "configs.systemStatus.variables.listCountCap.label",
235
+ descriptionKey: "configs.systemStatus.variables.listCountCap.description",
236
+ docUrl: `${SYSTEM_STATUS_DOC_BASE}#om_list_count_cap`,
237
+ defaultValue: "10000"
238
+ },
230
239
  {
231
240
  key: "FORCE_QUERY_INDEX_ON_PARTIAL_INDEXES",
232
241
  category: "query_index",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/modules/configs/lib/system-status.ts"],
4
- "sourcesContent": ["import type {\n SystemStatusCategory,\n SystemStatusCategoryKey,\n SystemStatusItem,\n SystemStatusSnapshot,\n SystemStatusVariableKind,\n SystemStatusState,\n SystemStatusRuntimeMode,\n} from './system-status.types'\nimport { parseBooleanToken } from '@open-mercato/shared/lib/boolean'\n\ntype SystemStatusVariableDefinition = {\n key: string\n category: SystemStatusCategoryKey\n kind: SystemStatusVariableKind\n labelKey: string\n descriptionKey: string\n docUrl: string | null\n defaultValue: string | null\n valueTransform?: (raw: string | undefined) => string | undefined\n}\n\nconst CATEGORY_ORDER: SystemStatusCategoryKey[] = [\n 'profiling',\n 'logging',\n 'security',\n 'caching',\n 'query_index',\n 'entities',\n]\n\nconst CATEGORY_METADATA: Record<\n SystemStatusCategoryKey,\n { labelKey: string; descriptionKey: string | null }\n> = {\n profiling: {\n labelKey: 'configs.systemStatus.categories.profiling',\n descriptionKey: 'configs.systemStatus.categories.profilingDescription',\n },\n logging: {\n labelKey: 'configs.systemStatus.categories.logging',\n descriptionKey: 'configs.systemStatus.categories.loggingDescription',\n },\n security: {\n labelKey: 'configs.systemStatus.categories.security',\n descriptionKey: 'configs.systemStatus.categories.securityDescription',\n },\n caching: {\n labelKey: 'configs.systemStatus.categories.caching',\n descriptionKey: 'configs.systemStatus.categories.cachingDescription',\n },\n query_index: {\n labelKey: 'configs.systemStatus.categories.queryIndex',\n descriptionKey: 'configs.systemStatus.categories.queryIndexDescription',\n },\n entities: {\n labelKey: 'configs.systemStatus.categories.entities',\n descriptionKey: 'configs.systemStatus.categories.entitiesDescription',\n },\n}\n\nconst SYSTEM_STATUS_DOC_BASE = 'https://docs.openmercato.com/docs/framework/operations/system-status'\nconst DEFAULT_SQLITE_CACHE_PATH = './.mercato/cache/cache.db'\n\nfunction maskConnectionCredentials(raw: string | undefined): string | undefined {\n if (typeof raw !== 'string') return raw\n const trimmed = raw.trim()\n if (!trimmed) return trimmed\n\n const maskAuthorityLikeCredentials = (value: string): string => {\n const schemeIndex = value.indexOf('://')\n if (schemeIndex < 0) return value\n\n const userInfoStart = schemeIndex + 3\n const queryIndex = value.indexOf('?', userInfoStart)\n const fragmentIndex = value.indexOf('#', userInfoStart)\n const searchEnd =\n queryIndex >= 0 && fragmentIndex >= 0\n ? Math.min(queryIndex, fragmentIndex)\n : queryIndex >= 0\n ? queryIndex\n : fragmentIndex >= 0\n ? fragmentIndex\n : value.length\n\n const authorityLikeSegment = value.slice(userInfoStart, searchEnd)\n const lastAtIndex = authorityLikeSegment.lastIndexOf('@')\n if (lastAtIndex < 0) return value\n\n return `${value.slice(0, userInfoStart)}${authorityLikeSegment.slice(lastAtIndex + 1)}${value.slice(searchEnd)}`\n }\n\n try {\n const parsed = new URL(trimmed)\n if (!parsed.username && !parsed.password) {\n return trimmed\n }\n parsed.username = ''\n parsed.password = ''\n return parsed.toString()\n } catch {\n return maskAuthorityLikeCredentials(trimmed)\n }\n}\n\nexport const SYSTEM_STATUS_VARIABLES: SystemStatusVariableDefinition[] = [\n {\n key: 'OM_PROFILE',\n category: 'profiling',\n kind: 'string',\n labelKey: 'configs.systemStatus.variables.omProfile.label',\n descriptionKey: 'configs.systemStatus.variables.omProfile.description',\n docUrl: `${SYSTEM_STATUS_DOC_BASE}#om_profile`,\n defaultValue: '',\n },\n {\n key: 'NEXT_PUBLIC_OM_PROFILE',\n category: 'profiling',\n kind: 'string',\n labelKey: 'configs.systemStatus.variables.nextPublicOmProfile.label',\n descriptionKey: 'configs.systemStatus.variables.nextPublicOmProfile.description',\n docUrl: `${SYSTEM_STATUS_DOC_BASE}#next_public_om_profile`,\n defaultValue: '',\n },\n {\n key: 'OM_CRUD_PROFILE',\n category: 'profiling',\n kind: 'string',\n labelKey: 'configs.systemStatus.variables.omCrudProfile.label',\n descriptionKey: 'configs.systemStatus.variables.omCrudProfile.description',\n docUrl: `${SYSTEM_STATUS_DOC_BASE}#om_crud_profile`,\n defaultValue: '',\n },\n {\n key: 'OM_QE_PROFILE',\n category: 'profiling',\n kind: 'string',\n labelKey: 'configs.systemStatus.variables.omQeProfile.label',\n descriptionKey: 'configs.systemStatus.variables.omQeProfile.description',\n docUrl: `${SYSTEM_STATUS_DOC_BASE}#om_qe_profile`,\n defaultValue: '',\n },\n {\n key: 'QUERY_ENGINE_DEBUG_SQL',\n category: 'logging',\n kind: 'boolean',\n labelKey: 'configs.systemStatus.variables.queryEngineDebugSql.label',\n descriptionKey: 'configs.systemStatus.variables.queryEngineDebugSql.description',\n docUrl: `${SYSTEM_STATUS_DOC_BASE}#query_engine_debug_sql`,\n defaultValue: 'false',\n },\n {\n key: 'LOG_VERBOSITY',\n category: 'logging',\n kind: 'string',\n labelKey: 'configs.systemStatus.variables.logVerbosity.label',\n descriptionKey: 'configs.systemStatus.variables.logVerbosity.description',\n docUrl: `${SYSTEM_STATUS_DOC_BASE}#log_verbosity`,\n defaultValue: '',\n },\n {\n key: 'LOG_LEVEL',\n category: 'logging',\n kind: 'string',\n labelKey: 'configs.systemStatus.variables.logLevel.label',\n descriptionKey: 'configs.systemStatus.variables.logLevel.description',\n docUrl: `${SYSTEM_STATUS_DOC_BASE}#log_level`,\n defaultValue: '',\n },\n {\n key: 'OM_PASSWORD_MIN_LENGTH',\n category: 'security',\n kind: 'string',\n labelKey: 'configs.systemStatus.variables.passwordMinLength.label',\n descriptionKey: 'configs.systemStatus.variables.passwordMinLength.description',\n docUrl: `${SYSTEM_STATUS_DOC_BASE}#om_password_min_length`,\n defaultValue: '6',\n },\n {\n key: 'DATABASE_URL',\n category: 'security',\n kind: 'string',\n labelKey: 'configs.systemStatus.variables.databaseUrl.label',\n descriptionKey: 'configs.systemStatus.variables.databaseUrl.description',\n docUrl: null,\n defaultValue: null,\n valueTransform: maskConnectionCredentials,\n },\n {\n key: 'OM_PASSWORD_REQUIRE_DIGIT',\n category: 'security',\n kind: 'boolean',\n labelKey: 'configs.systemStatus.variables.passwordRequireDigit.label',\n descriptionKey: 'configs.systemStatus.variables.passwordRequireDigit.description',\n docUrl: `${SYSTEM_STATUS_DOC_BASE}#om_password_require_digit`,\n defaultValue: 'true',\n },\n {\n key: 'OM_PASSWORD_REQUIRE_UPPERCASE',\n category: 'security',\n kind: 'boolean',\n labelKey: 'configs.systemStatus.variables.passwordRequireUppercase.label',\n descriptionKey: 'configs.systemStatus.variables.passwordRequireUppercase.description',\n docUrl: `${SYSTEM_STATUS_DOC_BASE}#om_password_require_uppercase`,\n defaultValue: 'true',\n },\n {\n key: 'OM_PASSWORD_REQUIRE_SPECIAL',\n category: 'security',\n kind: 'boolean',\n labelKey: 'configs.systemStatus.variables.passwordRequireSpecial.label',\n descriptionKey: 'configs.systemStatus.variables.passwordRequireSpecial.description',\n docUrl: `${SYSTEM_STATUS_DOC_BASE}#om_password_require_special`,\n defaultValue: 'true',\n },\n {\n key: 'ENABLE_CRUD_API_CACHE',\n category: 'caching',\n kind: 'boolean',\n labelKey: 'configs.systemStatus.variables.enableCrudApiCache.label',\n descriptionKey: 'configs.systemStatus.variables.enableCrudApiCache.description',\n docUrl: `${SYSTEM_STATUS_DOC_BASE}#enable_crud_api_cache`,\n defaultValue: 'false',\n },\n {\n key: 'CACHE_STRATEGY',\n category: 'caching',\n kind: 'string',\n labelKey: 'configs.systemStatus.variables.cacheStrategy.label',\n descriptionKey: 'configs.systemStatus.variables.cacheStrategy.description',\n docUrl: `${SYSTEM_STATUS_DOC_BASE}#cache_strategy`,\n defaultValue: 'memory',\n },\n {\n key: 'CACHE_TTL',\n category: 'caching',\n kind: 'string',\n labelKey: 'configs.systemStatus.variables.cacheTtl.label',\n descriptionKey: 'configs.systemStatus.variables.cacheTtl.description',\n docUrl: `${SYSTEM_STATUS_DOC_BASE}#cache_ttl`,\n defaultValue: '',\n },\n {\n key: 'CACHE_SQLITE_PATH',\n category: 'caching',\n kind: 'string',\n labelKey: 'configs.systemStatus.variables.cacheSqlitePath.label',\n descriptionKey: 'configs.systemStatus.variables.cacheSqlitePath.description',\n docUrl: `${SYSTEM_STATUS_DOC_BASE}#cache_sqlite_path`,\n defaultValue: DEFAULT_SQLITE_CACHE_PATH,\n },\n {\n key: 'SCHEDULE_AUTO_REINDEX',\n category: 'query_index',\n kind: 'boolean',\n labelKey: 'configs.systemStatus.variables.scheduleAutoReindex.label',\n descriptionKey: 'configs.systemStatus.variables.scheduleAutoReindex.description',\n docUrl: `${SYSTEM_STATUS_DOC_BASE}#schedule_auto_reindex`,\n defaultValue: 'true',\n },\n {\n key: 'OPTIMIZE_INDEX_COVERAGE_STATS',\n category: 'query_index',\n kind: 'boolean',\n labelKey: 'configs.systemStatus.variables.optimizeIndexCoverageStats.label',\n descriptionKey: 'configs.systemStatus.variables.optimizeIndexCoverageStats.description',\n docUrl: `${SYSTEM_STATUS_DOC_BASE}#optimize_index_coverage_stats`,\n defaultValue: 'false',\n },\n {\n key: 'FORCE_QUERY_INDEX_ON_PARTIAL_INDEXES',\n category: 'query_index',\n kind: 'boolean',\n labelKey: 'configs.systemStatus.variables.forceQueryIndexOnPartialIndexes.label',\n descriptionKey: 'configs.systemStatus.variables.forceQueryIndexOnPartialIndexes.description',\n docUrl: `${SYSTEM_STATUS_DOC_BASE}#force_query_index_on_partial_indexes`,\n defaultValue: 'false',\n },\n {\n key: 'QUERY_INDEX_WARMUP_ENABLED',\n category: 'query_index',\n kind: 'boolean',\n labelKey: 'configs.systemStatus.variables.queryIndexWarmupEnabled.label',\n descriptionKey: 'configs.systemStatus.variables.queryIndexWarmupEnabled.description',\n docUrl: `${SYSTEM_STATUS_DOC_BASE}#query_index_warmup_enabled`,\n defaultValue: 'true',\n },\n {\n key: 'QUERY_INDEX_WARMUP_THROTTLE_MS',\n category: 'query_index',\n kind: 'string',\n labelKey: 'configs.systemStatus.variables.queryIndexWarmupThrottleMs.label',\n descriptionKey: 'configs.systemStatus.variables.queryIndexWarmupThrottleMs.description',\n docUrl: `${SYSTEM_STATUS_DOC_BASE}#query_index_warmup_throttle_ms`,\n defaultValue: String(5 * 60 * 1000),\n },\n {\n key: 'QUERY_INDEX_WARMUP_CONCURRENCY',\n category: 'query_index',\n kind: 'string',\n labelKey: 'configs.systemStatus.variables.queryIndexWarmupConcurrency.label',\n descriptionKey: 'configs.systemStatus.variables.queryIndexWarmupConcurrency.description',\n docUrl: `${SYSTEM_STATUS_DOC_BASE}#query_index_warmup_concurrency`,\n defaultValue: '10',\n },\n {\n key: 'QUERY_INDEX_WARMUP_STAGGER_MS',\n category: 'query_index',\n kind: 'string',\n labelKey: 'configs.systemStatus.variables.queryIndexWarmupStaggerMs.label',\n descriptionKey: 'configs.systemStatus.variables.queryIndexWarmupStaggerMs.description',\n docUrl: `${SYSTEM_STATUS_DOC_BASE}#query_index_warmup_stagger_ms`,\n defaultValue: '0',\n },\n {\n key: 'ENTITIES_BACKCOMPAT_EAV_FOR_CUSTOM',\n category: 'entities',\n kind: 'boolean',\n labelKey: 'configs.systemStatus.variables.entitiesBackcompatEav.label',\n descriptionKey: 'configs.systemStatus.variables.entitiesBackcompatEav.description',\n docUrl: `${SYSTEM_STATUS_DOC_BASE}#entities_backcompat_eav_for_custom`,\n defaultValue: 'false',\n },\n]\n\ntype AnalyzedValue = { state: SystemStatusState; value: string | null; normalizedValue: string | null }\n\nfunction analyzeBooleanValue(raw: string | undefined): AnalyzedValue {\n if (typeof raw !== 'string') {\n return { state: 'unset', value: null, normalizedValue: null }\n }\n const trimmed = raw.trim()\n if (!trimmed) return { state: 'unset', value: null, normalizedValue: null }\n const parsed = parseBooleanToken(trimmed)\n if (parsed === true) {\n return { state: 'enabled', value: trimmed, normalizedValue: 'true' }\n }\n if (parsed === false) {\n return { state: 'disabled', value: trimmed, normalizedValue: 'false' }\n }\n return { state: 'unknown', value: trimmed, normalizedValue: trimmed }\n}\n\nfunction analyzeStringValue(raw: string | undefined): AnalyzedValue {\n if (typeof raw !== 'string') {\n return { state: 'unset', value: null, normalizedValue: null }\n }\n const trimmed = raw.trim()\n if (!trimmed) return { state: 'unset', value: null, normalizedValue: null }\n return { state: 'set', value: trimmed, normalizedValue: trimmed }\n}\n\nfunction toItem(definition: SystemStatusVariableDefinition, env: Record<string, string | undefined>): SystemStatusItem {\n const raw = definition.valueTransform ? definition.valueTransform(env[definition.key]) : env[definition.key]\n const analyzed = definition.kind === 'boolean' ? analyzeBooleanValue(raw) : analyzeStringValue(raw)\n return {\n key: definition.key,\n category: definition.category,\n kind: definition.kind,\n labelKey: definition.labelKey,\n descriptionKey: definition.descriptionKey,\n docUrl: definition.docUrl,\n defaultValue: definition.defaultValue,\n state: analyzed.state,\n value: analyzed.value,\n normalizedValue: analyzed.normalizedValue,\n }\n}\n\nfunction buildCategorySnapshot(\n key: SystemStatusCategoryKey,\n items: SystemStatusItem[],\n): SystemStatusCategory {\n const metadata = CATEGORY_METADATA[key]\n return {\n key,\n labelKey: metadata.labelKey,\n descriptionKey: metadata.descriptionKey,\n items,\n }\n}\n\nfunction resolveRuntimeMode(env: Record<string, string | undefined>): SystemStatusRuntimeMode {\n const raw = env.NODE_ENV\n if (typeof raw !== 'string') return 'unknown'\n const value = raw.trim().toLowerCase()\n if (value === 'development') return 'development'\n if (value === 'production') return 'production'\n if (value === 'test') return 'test'\n return 'unknown'\n}\n\nexport function buildSystemStatusSnapshot(\n env: Record<string, string | undefined> = process.env as Record<string, string | undefined>,\n): SystemStatusSnapshot {\n const byCategory = new Map<SystemStatusCategoryKey, SystemStatusItem[]>()\n for (const definition of SYSTEM_STATUS_VARIABLES) {\n const bucket = byCategory.get(definition.category)\n const item = toItem(definition, env)\n if (bucket) {\n bucket.push(item)\n } else {\n byCategory.set(definition.category, [item])\n }\n }\n\n const categories: SystemStatusCategory[] = []\n for (const categoryKey of CATEGORY_ORDER) {\n const items = byCategory.get(categoryKey) ?? []\n categories.push(buildCategorySnapshot(categoryKey, items))\n }\n\n return {\n generatedAt: new Date().toISOString(),\n runtimeMode: resolveRuntimeMode(env),\n categories,\n }\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import type {\n SystemStatusCategory,\n SystemStatusCategoryKey,\n SystemStatusItem,\n SystemStatusSnapshot,\n SystemStatusVariableKind,\n SystemStatusState,\n SystemStatusRuntimeMode,\n} from './system-status.types'\nimport { parseBooleanToken } from '@open-mercato/shared/lib/boolean'\n\ntype SystemStatusVariableDefinition = {\n key: string\n category: SystemStatusCategoryKey\n kind: SystemStatusVariableKind\n labelKey: string\n descriptionKey: string\n docUrl: string | null\n defaultValue: string | null\n valueTransform?: (raw: string | undefined) => string | undefined\n}\n\nconst CATEGORY_ORDER: SystemStatusCategoryKey[] = [\n 'profiling',\n 'logging',\n 'security',\n 'caching',\n 'query_index',\n 'entities',\n]\n\nconst CATEGORY_METADATA: Record<\n SystemStatusCategoryKey,\n { labelKey: string; descriptionKey: string | null }\n> = {\n profiling: {\n labelKey: 'configs.systemStatus.categories.profiling',\n descriptionKey: 'configs.systemStatus.categories.profilingDescription',\n },\n logging: {\n labelKey: 'configs.systemStatus.categories.logging',\n descriptionKey: 'configs.systemStatus.categories.loggingDescription',\n },\n security: {\n labelKey: 'configs.systemStatus.categories.security',\n descriptionKey: 'configs.systemStatus.categories.securityDescription',\n },\n caching: {\n labelKey: 'configs.systemStatus.categories.caching',\n descriptionKey: 'configs.systemStatus.categories.cachingDescription',\n },\n query_index: {\n labelKey: 'configs.systemStatus.categories.queryIndex',\n descriptionKey: 'configs.systemStatus.categories.queryIndexDescription',\n },\n entities: {\n labelKey: 'configs.systemStatus.categories.entities',\n descriptionKey: 'configs.systemStatus.categories.entitiesDescription',\n },\n}\n\nconst SYSTEM_STATUS_DOC_BASE = 'https://docs.openmercato.com/docs/framework/operations/system-status'\nconst DEFAULT_SQLITE_CACHE_PATH = './.mercato/cache/cache.db'\n\nfunction maskConnectionCredentials(raw: string | undefined): string | undefined {\n if (typeof raw !== 'string') return raw\n const trimmed = raw.trim()\n if (!trimmed) return trimmed\n\n const maskAuthorityLikeCredentials = (value: string): string => {\n const schemeIndex = value.indexOf('://')\n if (schemeIndex < 0) return value\n\n const userInfoStart = schemeIndex + 3\n const queryIndex = value.indexOf('?', userInfoStart)\n const fragmentIndex = value.indexOf('#', userInfoStart)\n const searchEnd =\n queryIndex >= 0 && fragmentIndex >= 0\n ? Math.min(queryIndex, fragmentIndex)\n : queryIndex >= 0\n ? queryIndex\n : fragmentIndex >= 0\n ? fragmentIndex\n : value.length\n\n const authorityLikeSegment = value.slice(userInfoStart, searchEnd)\n const lastAtIndex = authorityLikeSegment.lastIndexOf('@')\n if (lastAtIndex < 0) return value\n\n return `${value.slice(0, userInfoStart)}${authorityLikeSegment.slice(lastAtIndex + 1)}${value.slice(searchEnd)}`\n }\n\n try {\n const parsed = new URL(trimmed)\n if (!parsed.username && !parsed.password) {\n return trimmed\n }\n parsed.username = ''\n parsed.password = ''\n return parsed.toString()\n } catch {\n return maskAuthorityLikeCredentials(trimmed)\n }\n}\n\nexport const SYSTEM_STATUS_VARIABLES: SystemStatusVariableDefinition[] = [\n {\n key: 'OM_PROFILE',\n category: 'profiling',\n kind: 'string',\n labelKey: 'configs.systemStatus.variables.omProfile.label',\n descriptionKey: 'configs.systemStatus.variables.omProfile.description',\n docUrl: `${SYSTEM_STATUS_DOC_BASE}#om_profile`,\n defaultValue: '',\n },\n {\n key: 'NEXT_PUBLIC_OM_PROFILE',\n category: 'profiling',\n kind: 'string',\n labelKey: 'configs.systemStatus.variables.nextPublicOmProfile.label',\n descriptionKey: 'configs.systemStatus.variables.nextPublicOmProfile.description',\n docUrl: `${SYSTEM_STATUS_DOC_BASE}#next_public_om_profile`,\n defaultValue: '',\n },\n {\n key: 'OM_CRUD_PROFILE',\n category: 'profiling',\n kind: 'string',\n labelKey: 'configs.systemStatus.variables.omCrudProfile.label',\n descriptionKey: 'configs.systemStatus.variables.omCrudProfile.description',\n docUrl: `${SYSTEM_STATUS_DOC_BASE}#om_crud_profile`,\n defaultValue: '',\n },\n {\n key: 'OM_QE_PROFILE',\n category: 'profiling',\n kind: 'string',\n labelKey: 'configs.systemStatus.variables.omQeProfile.label',\n descriptionKey: 'configs.systemStatus.variables.omQeProfile.description',\n docUrl: `${SYSTEM_STATUS_DOC_BASE}#om_qe_profile`,\n defaultValue: '',\n },\n {\n key: 'QUERY_ENGINE_DEBUG_SQL',\n category: 'logging',\n kind: 'boolean',\n labelKey: 'configs.systemStatus.variables.queryEngineDebugSql.label',\n descriptionKey: 'configs.systemStatus.variables.queryEngineDebugSql.description',\n docUrl: `${SYSTEM_STATUS_DOC_BASE}#query_engine_debug_sql`,\n defaultValue: 'false',\n },\n {\n key: 'LOG_VERBOSITY',\n category: 'logging',\n kind: 'string',\n labelKey: 'configs.systemStatus.variables.logVerbosity.label',\n descriptionKey: 'configs.systemStatus.variables.logVerbosity.description',\n docUrl: `${SYSTEM_STATUS_DOC_BASE}#log_verbosity`,\n defaultValue: '',\n },\n {\n key: 'LOG_LEVEL',\n category: 'logging',\n kind: 'string',\n labelKey: 'configs.systemStatus.variables.logLevel.label',\n descriptionKey: 'configs.systemStatus.variables.logLevel.description',\n docUrl: `${SYSTEM_STATUS_DOC_BASE}#log_level`,\n defaultValue: '',\n },\n {\n key: 'OM_PASSWORD_MIN_LENGTH',\n category: 'security',\n kind: 'string',\n labelKey: 'configs.systemStatus.variables.passwordMinLength.label',\n descriptionKey: 'configs.systemStatus.variables.passwordMinLength.description',\n docUrl: `${SYSTEM_STATUS_DOC_BASE}#om_password_min_length`,\n defaultValue: '6',\n },\n {\n key: 'DATABASE_URL',\n category: 'security',\n kind: 'string',\n labelKey: 'configs.systemStatus.variables.databaseUrl.label',\n descriptionKey: 'configs.systemStatus.variables.databaseUrl.description',\n docUrl: null,\n defaultValue: null,\n valueTransform: maskConnectionCredentials,\n },\n {\n key: 'OM_PASSWORD_REQUIRE_DIGIT',\n category: 'security',\n kind: 'boolean',\n labelKey: 'configs.systemStatus.variables.passwordRequireDigit.label',\n descriptionKey: 'configs.systemStatus.variables.passwordRequireDigit.description',\n docUrl: `${SYSTEM_STATUS_DOC_BASE}#om_password_require_digit`,\n defaultValue: 'true',\n },\n {\n key: 'OM_PASSWORD_REQUIRE_UPPERCASE',\n category: 'security',\n kind: 'boolean',\n labelKey: 'configs.systemStatus.variables.passwordRequireUppercase.label',\n descriptionKey: 'configs.systemStatus.variables.passwordRequireUppercase.description',\n docUrl: `${SYSTEM_STATUS_DOC_BASE}#om_password_require_uppercase`,\n defaultValue: 'true',\n },\n {\n key: 'OM_PASSWORD_REQUIRE_SPECIAL',\n category: 'security',\n kind: 'boolean',\n labelKey: 'configs.systemStatus.variables.passwordRequireSpecial.label',\n descriptionKey: 'configs.systemStatus.variables.passwordRequireSpecial.description',\n docUrl: `${SYSTEM_STATUS_DOC_BASE}#om_password_require_special`,\n defaultValue: 'true',\n },\n {\n key: 'ENABLE_CRUD_API_CACHE',\n category: 'caching',\n kind: 'boolean',\n labelKey: 'configs.systemStatus.variables.enableCrudApiCache.label',\n descriptionKey: 'configs.systemStatus.variables.enableCrudApiCache.description',\n docUrl: `${SYSTEM_STATUS_DOC_BASE}#enable_crud_api_cache`,\n defaultValue: 'false',\n },\n {\n key: 'CACHE_STRATEGY',\n category: 'caching',\n kind: 'string',\n labelKey: 'configs.systemStatus.variables.cacheStrategy.label',\n descriptionKey: 'configs.systemStatus.variables.cacheStrategy.description',\n docUrl: `${SYSTEM_STATUS_DOC_BASE}#cache_strategy`,\n defaultValue: 'memory',\n },\n {\n key: 'CACHE_TTL',\n category: 'caching',\n kind: 'string',\n labelKey: 'configs.systemStatus.variables.cacheTtl.label',\n descriptionKey: 'configs.systemStatus.variables.cacheTtl.description',\n docUrl: `${SYSTEM_STATUS_DOC_BASE}#cache_ttl`,\n defaultValue: '',\n },\n {\n key: 'CACHE_SQLITE_PATH',\n category: 'caching',\n kind: 'string',\n labelKey: 'configs.systemStatus.variables.cacheSqlitePath.label',\n descriptionKey: 'configs.systemStatus.variables.cacheSqlitePath.description',\n docUrl: `${SYSTEM_STATUS_DOC_BASE}#cache_sqlite_path`,\n defaultValue: DEFAULT_SQLITE_CACHE_PATH,\n },\n {\n key: 'SCHEDULE_AUTO_REINDEX',\n category: 'query_index',\n kind: 'boolean',\n labelKey: 'configs.systemStatus.variables.scheduleAutoReindex.label',\n descriptionKey: 'configs.systemStatus.variables.scheduleAutoReindex.description',\n docUrl: `${SYSTEM_STATUS_DOC_BASE}#schedule_auto_reindex`,\n defaultValue: 'true',\n },\n {\n key: 'OPTIMIZE_INDEX_COVERAGE_STATS',\n category: 'query_index',\n kind: 'boolean',\n labelKey: 'configs.systemStatus.variables.optimizeIndexCoverageStats.label',\n descriptionKey: 'configs.systemStatus.variables.optimizeIndexCoverageStats.description',\n docUrl: `${SYSTEM_STATUS_DOC_BASE}#optimize_index_coverage_stats`,\n defaultValue: 'false',\n },\n {\n key: 'OM_LIST_COUNT_CAP',\n category: 'query_index',\n kind: 'string',\n labelKey: 'configs.systemStatus.variables.listCountCap.label',\n descriptionKey: 'configs.systemStatus.variables.listCountCap.description',\n docUrl: `${SYSTEM_STATUS_DOC_BASE}#om_list_count_cap`,\n defaultValue: '10000',\n },\n {\n key: 'FORCE_QUERY_INDEX_ON_PARTIAL_INDEXES',\n category: 'query_index',\n kind: 'boolean',\n labelKey: 'configs.systemStatus.variables.forceQueryIndexOnPartialIndexes.label',\n descriptionKey: 'configs.systemStatus.variables.forceQueryIndexOnPartialIndexes.description',\n docUrl: `${SYSTEM_STATUS_DOC_BASE}#force_query_index_on_partial_indexes`,\n defaultValue: 'false',\n },\n {\n key: 'QUERY_INDEX_WARMUP_ENABLED',\n category: 'query_index',\n kind: 'boolean',\n labelKey: 'configs.systemStatus.variables.queryIndexWarmupEnabled.label',\n descriptionKey: 'configs.systemStatus.variables.queryIndexWarmupEnabled.description',\n docUrl: `${SYSTEM_STATUS_DOC_BASE}#query_index_warmup_enabled`,\n defaultValue: 'true',\n },\n {\n key: 'QUERY_INDEX_WARMUP_THROTTLE_MS',\n category: 'query_index',\n kind: 'string',\n labelKey: 'configs.systemStatus.variables.queryIndexWarmupThrottleMs.label',\n descriptionKey: 'configs.systemStatus.variables.queryIndexWarmupThrottleMs.description',\n docUrl: `${SYSTEM_STATUS_DOC_BASE}#query_index_warmup_throttle_ms`,\n defaultValue: String(5 * 60 * 1000),\n },\n {\n key: 'QUERY_INDEX_WARMUP_CONCURRENCY',\n category: 'query_index',\n kind: 'string',\n labelKey: 'configs.systemStatus.variables.queryIndexWarmupConcurrency.label',\n descriptionKey: 'configs.systemStatus.variables.queryIndexWarmupConcurrency.description',\n docUrl: `${SYSTEM_STATUS_DOC_BASE}#query_index_warmup_concurrency`,\n defaultValue: '10',\n },\n {\n key: 'QUERY_INDEX_WARMUP_STAGGER_MS',\n category: 'query_index',\n kind: 'string',\n labelKey: 'configs.systemStatus.variables.queryIndexWarmupStaggerMs.label',\n descriptionKey: 'configs.systemStatus.variables.queryIndexWarmupStaggerMs.description',\n docUrl: `${SYSTEM_STATUS_DOC_BASE}#query_index_warmup_stagger_ms`,\n defaultValue: '0',\n },\n {\n key: 'ENTITIES_BACKCOMPAT_EAV_FOR_CUSTOM',\n category: 'entities',\n kind: 'boolean',\n labelKey: 'configs.systemStatus.variables.entitiesBackcompatEav.label',\n descriptionKey: 'configs.systemStatus.variables.entitiesBackcompatEav.description',\n docUrl: `${SYSTEM_STATUS_DOC_BASE}#entities_backcompat_eav_for_custom`,\n defaultValue: 'false',\n },\n]\n\ntype AnalyzedValue = { state: SystemStatusState; value: string | null; normalizedValue: string | null }\n\nfunction analyzeBooleanValue(raw: string | undefined): AnalyzedValue {\n if (typeof raw !== 'string') {\n return { state: 'unset', value: null, normalizedValue: null }\n }\n const trimmed = raw.trim()\n if (!trimmed) return { state: 'unset', value: null, normalizedValue: null }\n const parsed = parseBooleanToken(trimmed)\n if (parsed === true) {\n return { state: 'enabled', value: trimmed, normalizedValue: 'true' }\n }\n if (parsed === false) {\n return { state: 'disabled', value: trimmed, normalizedValue: 'false' }\n }\n return { state: 'unknown', value: trimmed, normalizedValue: trimmed }\n}\n\nfunction analyzeStringValue(raw: string | undefined): AnalyzedValue {\n if (typeof raw !== 'string') {\n return { state: 'unset', value: null, normalizedValue: null }\n }\n const trimmed = raw.trim()\n if (!trimmed) return { state: 'unset', value: null, normalizedValue: null }\n return { state: 'set', value: trimmed, normalizedValue: trimmed }\n}\n\nfunction toItem(definition: SystemStatusVariableDefinition, env: Record<string, string | undefined>): SystemStatusItem {\n const raw = definition.valueTransform ? definition.valueTransform(env[definition.key]) : env[definition.key]\n const analyzed = definition.kind === 'boolean' ? analyzeBooleanValue(raw) : analyzeStringValue(raw)\n return {\n key: definition.key,\n category: definition.category,\n kind: definition.kind,\n labelKey: definition.labelKey,\n descriptionKey: definition.descriptionKey,\n docUrl: definition.docUrl,\n defaultValue: definition.defaultValue,\n state: analyzed.state,\n value: analyzed.value,\n normalizedValue: analyzed.normalizedValue,\n }\n}\n\nfunction buildCategorySnapshot(\n key: SystemStatusCategoryKey,\n items: SystemStatusItem[],\n): SystemStatusCategory {\n const metadata = CATEGORY_METADATA[key]\n return {\n key,\n labelKey: metadata.labelKey,\n descriptionKey: metadata.descriptionKey,\n items,\n }\n}\n\nfunction resolveRuntimeMode(env: Record<string, string | undefined>): SystemStatusRuntimeMode {\n const raw = env.NODE_ENV\n if (typeof raw !== 'string') return 'unknown'\n const value = raw.trim().toLowerCase()\n if (value === 'development') return 'development'\n if (value === 'production') return 'production'\n if (value === 'test') return 'test'\n return 'unknown'\n}\n\nexport function buildSystemStatusSnapshot(\n env: Record<string, string | undefined> = process.env as Record<string, string | undefined>,\n): SystemStatusSnapshot {\n const byCategory = new Map<SystemStatusCategoryKey, SystemStatusItem[]>()\n for (const definition of SYSTEM_STATUS_VARIABLES) {\n const bucket = byCategory.get(definition.category)\n const item = toItem(definition, env)\n if (bucket) {\n bucket.push(item)\n } else {\n byCategory.set(definition.category, [item])\n }\n }\n\n const categories: SystemStatusCategory[] = []\n for (const categoryKey of CATEGORY_ORDER) {\n const items = byCategory.get(categoryKey) ?? []\n categories.push(buildCategorySnapshot(categoryKey, items))\n }\n\n return {\n generatedAt: new Date().toISOString(),\n runtimeMode: resolveRuntimeMode(env),\n categories,\n }\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -26,6 +26,7 @@ function CurrenciesPage() {
26
26
  const [page, setPage] = React.useState(1);
27
27
  const [total, setTotal] = React.useState(0);
28
28
  const [totalPages, setTotalPages] = React.useState(1);
29
+ const [totalIsCapped, setTotalIsCapped] = React.useState(false);
29
30
  const [search, setSearch] = React.useState("");
30
31
  const [filters, setFilters] = React.useState({});
31
32
  const [isLoading, setIsLoading] = React.useState(true);
@@ -63,6 +64,7 @@ function CurrenciesPage() {
63
64
  setRows(Array.isArray(payload.items) ? payload.items : []);
64
65
  setTotal(payload.total || 0);
65
66
  setTotalPages(payload.totalPages || 1);
67
+ setTotalIsCapped(payload?.totalIsCapped === true);
66
68
  }
67
69
  } catch (error) {
68
70
  if (!cancelled) {
@@ -291,7 +293,7 @@ function CurrenciesPage() {
291
293
  createLabel: t("currencies.list.actions.create")
292
294
  }
293
295
  ),
294
- pagination: { page, pageSize: 50, total, totalPages, onPageChange: setPage },
296
+ pagination: { page, pageSize: 50, total, totalPages, totalIsCapped, onPageChange: setPage },
295
297
  isLoading,
296
298
  perspective: { tableId: extensionPoints.hosts.currenciesTable.tableId }
297
299
  }