@dainamite/cpq 0.6.0 → 0.7.0

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 (164) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/dist/modules/cpq/backend/cpq/inventory/AssetsTable.js +3 -9
  3. package/dist/modules/cpq/backend/cpq/inventory/AssetsTable.js.map +2 -2
  4. package/dist/modules/cpq/backend/cpq/inventory/SubscriptionsTable.js +21 -25
  5. package/dist/modules/cpq/backend/cpq/inventory/SubscriptionsTable.js.map +2 -2
  6. package/dist/modules/cpq/backend/cpq/inventory/assets/[id]/page.js +48 -47
  7. package/dist/modules/cpq/backend/cpq/inventory/assets/[id]/page.js.map +2 -2
  8. package/dist/modules/cpq/backend/cpq/inventory/assets/[id]/page.meta.js +1 -1
  9. package/dist/modules/cpq/backend/cpq/inventory/assets/[id]/page.meta.js.map +2 -2
  10. package/dist/modules/cpq/backend/cpq/inventory/page.meta.js +2 -2
  11. package/dist/modules/cpq/backend/cpq/inventory/page.meta.js.map +2 -2
  12. package/dist/modules/cpq/backend/cpq/inventory/shared.js +37 -2
  13. package/dist/modules/cpq/backend/cpq/inventory/shared.js.map +2 -2
  14. package/dist/modules/cpq/backend/cpq/inventory/subscriptions/[id]/page.js +154 -178
  15. package/dist/modules/cpq/backend/cpq/inventory/subscriptions/[id]/page.js.map +2 -2
  16. package/dist/modules/cpq/backend/cpq/inventory/subscriptions/[id]/page.meta.js +1 -1
  17. package/dist/modules/cpq/backend/cpq/inventory/subscriptions/[id]/page.meta.js.map +2 -2
  18. package/dist/modules/cpq/backend/cpq/offerings/[id]/page.js +168 -143
  19. package/dist/modules/cpq/backend/cpq/offerings/[id]/page.js.map +2 -2
  20. package/dist/modules/cpq/backend/cpq/offerings/page.js +36 -34
  21. package/dist/modules/cpq/backend/cpq/offerings/page.js.map +2 -2
  22. package/dist/modules/cpq/backend/cpq/orders/[id]/page.js +69 -66
  23. package/dist/modules/cpq/backend/cpq/orders/[id]/page.js.map +2 -2
  24. package/dist/modules/cpq/backend/cpq/orders/page.js +6 -6
  25. package/dist/modules/cpq/backend/cpq/orders/page.js.map +2 -2
  26. package/dist/modules/cpq/backend/cpq/price-rules/PriceRuleForm.js +41 -36
  27. package/dist/modules/cpq/backend/cpq/price-rules/PriceRuleForm.js.map +2 -2
  28. package/dist/modules/cpq/backend/cpq/price-rules/[id]/page.js +76 -72
  29. package/dist/modules/cpq/backend/cpq/price-rules/[id]/page.js.map +2 -2
  30. package/dist/modules/cpq/backend/cpq/price-rules/[id]/page.meta.js +1 -1
  31. package/dist/modules/cpq/backend/cpq/price-rules/[id]/page.meta.js.map +2 -2
  32. package/dist/modules/cpq/backend/cpq/price-rules/page.js +18 -15
  33. package/dist/modules/cpq/backend/cpq/price-rules/page.js.map +2 -2
  34. package/dist/modules/cpq/backend/cpq/pricing/[id]/EntriesEditor.js +23 -21
  35. package/dist/modules/cpq/backend/cpq/pricing/[id]/EntriesEditor.js.map +2 -2
  36. package/dist/modules/cpq/backend/cpq/pricing/[id]/ImportPreview.js +22 -50
  37. package/dist/modules/cpq/backend/cpq/pricing/[id]/ImportPreview.js.map +2 -2
  38. package/dist/modules/cpq/backend/cpq/pricing/[id]/page.js +74 -52
  39. package/dist/modules/cpq/backend/cpq/pricing/[id]/page.js.map +2 -2
  40. package/dist/modules/cpq/backend/cpq/pricing/[id]/xlsxImport.js +20 -17
  41. package/dist/modules/cpq/backend/cpq/pricing/[id]/xlsxImport.js.map +2 -2
  42. package/dist/modules/cpq/backend/cpq/pricing/page.js +1 -1
  43. package/dist/modules/cpq/backend/cpq/pricing/page.js.map +2 -2
  44. package/dist/modules/cpq/backend/cpq/quotes/[id]/_components/ArcQuoteConfigurator.js +115 -123
  45. package/dist/modules/cpq/backend/cpq/quotes/[id]/_components/ArcQuoteConfigurator.js.map +2 -2
  46. package/dist/modules/cpq/backend/cpq/quotes/[id]/_components/PriceAdjustmentDialog.js +6 -3
  47. package/dist/modules/cpq/backend/cpq/quotes/[id]/_components/PriceAdjustmentDialog.js.map +2 -2
  48. package/dist/modules/cpq/backend/cpq/quotes/[id]/page.js +129 -94
  49. package/dist/modules/cpq/backend/cpq/quotes/[id]/page.js.map +2 -2
  50. package/dist/modules/cpq/backend/cpq/quotes/page.js +23 -19
  51. package/dist/modules/cpq/backend/cpq/quotes/page.js.map +2 -2
  52. package/dist/modules/cpq/backend/cpq/specifications/[id]/DependsOnRulesEditor.js +19 -15
  53. package/dist/modules/cpq/backend/cpq/specifications/[id]/DependsOnRulesEditor.js.map +2 -2
  54. package/dist/modules/cpq/backend/cpq/specifications/[id]/page.js +171 -178
  55. package/dist/modules/cpq/backend/cpq/specifications/[id]/page.js.map +2 -2
  56. package/dist/modules/cpq/backend/cpq/specifications/page.js +2 -2
  57. package/dist/modules/cpq/backend/cpq/specifications/page.js.map +2 -2
  58. package/dist/modules/cpq/backend/cpq/wizards/[definitionCode]/detail/page.js +60 -50
  59. package/dist/modules/cpq/backend/cpq/wizards/[definitionCode]/detail/page.js.map +2 -2
  60. package/dist/modules/cpq/backend/cpq/wizards/[definitionCode]/page.js +22 -18
  61. package/dist/modules/cpq/backend/cpq/wizards/[definitionCode]/page.js.map +2 -2
  62. package/dist/modules/cpq/backend/cpq/wizards/page.js +1 -1
  63. package/dist/modules/cpq/backend/cpq/wizards/page.js.map +2 -2
  64. package/dist/modules/cpq/components/ArcLineDiff.js +2 -2
  65. package/dist/modules/cpq/components/ArcLineDiff.js.map +2 -2
  66. package/dist/modules/cpq/components/ChargeBreakdownTable.js +4 -10
  67. package/dist/modules/cpq/components/ChargeBreakdownTable.js.map +2 -2
  68. package/dist/modules/cpq/components/PriceWaterfall.js +3 -1
  69. package/dist/modules/cpq/components/PriceWaterfall.js.map +2 -2
  70. package/dist/modules/cpq/components/PricingSummaryCard.js +1 -6
  71. package/dist/modules/cpq/components/PricingSummaryCard.js.map +2 -2
  72. package/dist/modules/cpq/components/StatusPath.js +5 -3
  73. package/dist/modules/cpq/components/StatusPath.js.map +2 -2
  74. package/dist/modules/cpq/components/useCpqRowActions.js +10 -22
  75. package/dist/modules/cpq/components/useCpqRowActions.js.map +2 -2
  76. package/dist/modules/cpq/i18n/de.json +1220 -0
  77. package/dist/modules/cpq/i18n/en.json +1220 -0
  78. package/dist/modules/cpq/i18n/es.json +1220 -0
  79. package/dist/modules/cpq/i18n/pl.json +1220 -0
  80. package/dist/modules/cpq/widgets/injection/customer-inventory/widget.client.js +39 -31
  81. package/dist/modules/cpq/widgets/injection/customer-inventory/widget.client.js.map +2 -2
  82. package/dist/modules/cpq/widgets/injection/order-cpq-tab/widget.client.js +13 -5
  83. package/dist/modules/cpq/widgets/injection/order-cpq-tab/widget.client.js.map +2 -2
  84. package/dist/modules/cpq/widgets/injection/quote-configurator/widget.client.js +41 -21
  85. package/dist/modules/cpq/widgets/injection/quote-configurator/widget.client.js.map +2 -2
  86. package/dist/modules/cpq/widgets/injection-table.js +2 -2
  87. package/dist/modules/cpq/widgets/injection-table.js.map +2 -2
  88. package/dist/modules/cpq/workflows/WizardRunner.js +10 -8
  89. package/dist/modules/cpq/workflows/WizardRunner.js.map +2 -2
  90. package/dist/modules/cpq/workflows/WizardTrigger.js +15 -9
  91. package/dist/modules/cpq/workflows/WizardTrigger.js.map +2 -2
  92. package/dist/modules/cpq/workflows/steps/CustomerSelectStep.js +9 -7
  93. package/dist/modules/cpq/workflows/steps/CustomerSelectStep.js.map +2 -2
  94. package/dist/modules/cpq/workflows/steps/InventorySelectStep.js +9 -4
  95. package/dist/modules/cpq/workflows/steps/InventorySelectStep.js.map +2 -2
  96. package/dist/modules/cpq/workflows/steps/ItemListStep.js +16 -19
  97. package/dist/modules/cpq/workflows/steps/ItemListStep.js.map +2 -2
  98. package/dist/modules/cpq/workflows/steps/OfferingSelectStep.js +19 -32
  99. package/dist/modules/cpq/workflows/steps/OfferingSelectStep.js.map +2 -2
  100. package/dist/modules/cpq/workflows/steps/ProductConfigureStep.js +8 -6
  101. package/dist/modules/cpq/workflows/steps/ProductConfigureStep.js.map +2 -2
  102. package/dist/modules/cpq/workflows/steps/ReviewStep.js +32 -30
  103. package/dist/modules/cpq/workflows/steps/ReviewStep.js.map +2 -2
  104. package/dist/modules/cpq/workflows/steps/index.js +12 -0
  105. package/dist/modules/cpq/workflows/steps/index.js.map +2 -2
  106. package/package.json +1 -1
  107. package/src/modules/cpq/__tests__/i18n/dictionaries.test.ts +62 -0
  108. package/src/modules/cpq/__tests__/i18n/hardcodedStrings.test.ts +35 -0
  109. package/src/modules/cpq/__tests__/i18n/sourceScan.ts +109 -0
  110. package/src/modules/cpq/backend/cpq/inventory/AssetsTable.tsx +3 -9
  111. package/src/modules/cpq/backend/cpq/inventory/SubscriptionsTable.tsx +22 -26
  112. package/src/modules/cpq/backend/cpq/inventory/assets/[id]/page.meta.ts +1 -1
  113. package/src/modules/cpq/backend/cpq/inventory/assets/[id]/page.tsx +43 -46
  114. package/src/modules/cpq/backend/cpq/inventory/page.meta.ts +2 -2
  115. package/src/modules/cpq/backend/cpq/inventory/shared.tsx +37 -1
  116. package/src/modules/cpq/backend/cpq/inventory/subscriptions/[id]/page.meta.ts +1 -1
  117. package/src/modules/cpq/backend/cpq/inventory/subscriptions/[id]/page.tsx +134 -112
  118. package/src/modules/cpq/backend/cpq/offerings/[id]/page.tsx +169 -130
  119. package/src/modules/cpq/backend/cpq/offerings/page.tsx +34 -24
  120. package/src/modules/cpq/backend/cpq/orders/[id]/page.tsx +66 -43
  121. package/src/modules/cpq/backend/cpq/orders/page.tsx +6 -6
  122. package/src/modules/cpq/backend/cpq/price-rules/PriceRuleForm.tsx +48 -34
  123. package/src/modules/cpq/backend/cpq/price-rules/[id]/page.meta.ts +1 -1
  124. package/src/modules/cpq/backend/cpq/price-rules/[id]/page.tsx +76 -70
  125. package/src/modules/cpq/backend/cpq/price-rules/page.tsx +25 -16
  126. package/src/modules/cpq/backend/cpq/pricing/[id]/EntriesEditor.tsx +24 -18
  127. package/src/modules/cpq/backend/cpq/pricing/[id]/ImportPreview.tsx +29 -19
  128. package/src/modules/cpq/backend/cpq/pricing/[id]/page.tsx +95 -47
  129. package/src/modules/cpq/backend/cpq/pricing/[id]/xlsxImport.ts +23 -15
  130. package/src/modules/cpq/backend/cpq/pricing/page.tsx +1 -1
  131. package/src/modules/cpq/backend/cpq/quotes/[id]/_components/ArcQuoteConfigurator.tsx +111 -88
  132. package/src/modules/cpq/backend/cpq/quotes/[id]/_components/PriceAdjustmentDialog.tsx +3 -3
  133. package/src/modules/cpq/backend/cpq/quotes/[id]/page.tsx +134 -89
  134. package/src/modules/cpq/backend/cpq/quotes/page.tsx +29 -21
  135. package/src/modules/cpq/backend/cpq/specifications/[id]/DependsOnRulesEditor.tsx +19 -15
  136. package/src/modules/cpq/backend/cpq/specifications/[id]/page.tsx +171 -171
  137. package/src/modules/cpq/backend/cpq/specifications/page.tsx +2 -2
  138. package/src/modules/cpq/backend/cpq/wizards/[definitionCode]/detail/page.tsx +51 -41
  139. package/src/modules/cpq/backend/cpq/wizards/[definitionCode]/page.tsx +17 -13
  140. package/src/modules/cpq/backend/cpq/wizards/page.tsx +1 -1
  141. package/src/modules/cpq/components/ArcLineDiff.tsx +2 -2
  142. package/src/modules/cpq/components/ChargeBreakdownTable.tsx +4 -2
  143. package/src/modules/cpq/components/PriceWaterfall.tsx +4 -2
  144. package/src/modules/cpq/components/PricingSummaryCard.tsx +1 -1
  145. package/src/modules/cpq/components/StatusPath.tsx +7 -4
  146. package/src/modules/cpq/components/useCpqRowActions.tsx +17 -25
  147. package/src/modules/cpq/i18n/de.json +1220 -0
  148. package/src/modules/cpq/i18n/en.json +1220 -0
  149. package/src/modules/cpq/i18n/es.json +1220 -0
  150. package/src/modules/cpq/i18n/pl.json +1220 -0
  151. package/src/modules/cpq/widgets/injection/customer-inventory/widget.client.tsx +38 -31
  152. package/src/modules/cpq/widgets/injection/order-cpq-tab/widget.client.tsx +7 -5
  153. package/src/modules/cpq/widgets/injection/quote-configurator/widget.client.tsx +36 -21
  154. package/src/modules/cpq/widgets/injection-table.ts +8 -2
  155. package/src/modules/cpq/workflows/WizardRunner.tsx +8 -5
  156. package/src/modules/cpq/workflows/WizardTrigger.tsx +15 -9
  157. package/src/modules/cpq/workflows/steps/CustomerSelectStep.tsx +11 -7
  158. package/src/modules/cpq/workflows/steps/InventorySelectStep.tsx +9 -5
  159. package/src/modules/cpq/workflows/steps/ItemListStep.tsx +18 -12
  160. package/src/modules/cpq/workflows/steps/OfferingSelectStep.tsx +20 -16
  161. package/src/modules/cpq/workflows/steps/ProductConfigureStep.tsx +8 -6
  162. package/src/modules/cpq/workflows/steps/ReviewStep.tsx +33 -18
  163. package/src/modules/cpq/workflows/steps/index.ts +12 -0
  164. package/src/modules/cpq/workflows/types.ts +4 -0
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/modules/cpq/components/useCpqRowActions.tsx"],
4
- "sourcesContent": ["\"use client\"\nimport * as React from 'react'\nimport { flash } from '@open-mercato/ui/backend/FlashMessages'\nimport { type RowActionItem } from '@open-mercato/ui/backend/RowActions'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { useConfirmDialog } from '@open-mercato/ui/backend/confirm-dialog'\n\n// \u2500\u2500\u2500 Types \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport type UseCpqRowActionsOptions<T extends { id: string }> = {\n /** DELETE endpoint that accepts `{ id }` body (e.g. `/api/cpq/product-offerings`). */\n endpoint: string\n /**\n * Singular noun for the entity, used in confirm + flash messages.\n * E.g. `'offering'`, `'pricing table'`, `'price rule'`.\n */\n entityName: string\n /**\n * Build the href for the row's edit/detail page (e.g. `(row) =>\n * `/backend/cpq/offerings/${row.id}`).\n */\n editHref: (row: T) => string\n /** Reload the table after a successful delete. */\n onReload: () => void\n /**\n * Override the row-deletion guard. Returning `false` skips the\n * delete request without flashing an error (e.g. when the row is in a\n * lifecycle state that disallows deletion).\n */\n canDelete?: (row: T) => boolean\n}\n\nexport type CpqRowActionsApi<T extends { id: string }> = {\n /**\n * Items for `<RowActions>` for a single row. Always returns\n * `Edit` + `Delete` \u2014 extras can be prepended / appended.\n */\n buildItems: (row: T, extras?: { prepend?: RowActionItem[]; append?: RowActionItem[] }) => RowActionItem[]\n /**\n * Bulk-delete handler suitable for `<DataTable bulkActions>`. Confirms once\n * for the whole selection, then issues `DELETE` requests sequentially so\n * a partial failure stops cleanly. Reports per-row failures via `flash`.\n *\n * Note: sequential by design \u2014 DELETE on the same table from N parallel\n * requests can deadlock at the row-lock level under load. Chunked\n * parallelism would be the next step if selection counts grow > ~200.\n */\n bulkDelete: (rows: T[]) => Promise<{ ok: boolean; affectedCount?: number }>\n /**\n * Render this element somewhere in the page (typically as the\n * `footerContent` slot of `<CpqListView>`) so the confirm dialog\n * portal mounts.\n */\n ConfirmDialogElement: React.ReactNode\n}\n\n// \u2500\u2500\u2500 Implementation \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport function useCpqRowActions<T extends { id: string }>(\n options: UseCpqRowActionsOptions<T>,\n): CpqRowActionsApi<T> {\n const { endpoint, entityName, editHref, onReload, canDelete } = options\n const t = useT()\n const { confirm, ConfirmDialogElement } = useConfirmDialog()\n\n const deleteOne = React.useCallback(\n async (id: string) => {\n const res = await fetch(endpoint, {\n method: 'DELETE',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ id }),\n })\n return res.ok\n },\n [endpoint],\n )\n\n const singleDelete = React.useCallback(\n async (row: T) => {\n if (canDelete && !canDelete(row)) return\n const confirmed = await confirm({\n title: t(\n 'cpq.rowActions.deleteOne.confirm',\n `Delete this ${entityName}?`,\n ),\n variant: 'destructive',\n })\n if (!confirmed) return\n const ok = await deleteOne(row.id)\n if (!ok) {\n flash(\n t('cpq.rowActions.deleteOne.error', `Failed to delete ${entityName}`),\n 'error',\n )\n return\n }\n flash(t('cpq.rowActions.deleteOne.success', `${entityName} deleted`), 'success')\n onReload()\n },\n [canDelete, confirm, deleteOne, entityName, onReload, t],\n )\n\n const bulkDelete = React.useCallback(\n async (rows: T[]) => {\n if (!rows.length) return { ok: false }\n const eligible = canDelete ? rows.filter(canDelete) : rows\n if (!eligible.length) {\n flash(\n t(\n 'cpq.rowActions.deleteBulk.noEligible',\n `None of the selected ${entityName}s can be deleted in their current state.`,\n ),\n 'error',\n )\n return { ok: false }\n }\n const confirmed = await confirm({\n title: t(\n 'cpq.rowActions.deleteBulk.confirm',\n `Delete ${eligible.length} ${entityName}${eligible.length > 1 ? 's' : ''}?`,\n ),\n variant: 'destructive',\n })\n if (!confirmed) return { ok: false }\n\n let failed = 0\n for (const row of eligible) {\n const ok = await deleteOne(row.id)\n if (!ok) failed += 1\n }\n\n if (failed > 0) {\n flash(\n t(\n 'cpq.rowActions.deleteBulk.partialError',\n `Failed to delete ${failed} ${entityName}${failed > 1 ? 's' : ''}`,\n ),\n 'error',\n )\n } else {\n flash(\n t('cpq.rowActions.deleteBulk.success', `${entityName}s deleted`),\n 'success',\n )\n }\n onReload()\n return { ok: failed === 0, affectedCount: eligible.length - failed }\n },\n [canDelete, confirm, deleteOne, entityName, onReload, t],\n )\n\n const buildItems = React.useCallback(\n (row: T, extras?: { prepend?: RowActionItem[]; append?: RowActionItem[] }): RowActionItem[] => {\n const items: RowActionItem[] = []\n if (extras?.prepend) items.push(...extras.prepend)\n items.push({\n id: 'edit',\n label: t('cpq.rowActions.edit', 'Edit'),\n href: editHref(row),\n })\n if (extras?.append) items.push(...extras.append)\n const deletable = !canDelete || canDelete(row)\n if (deletable) {\n items.push({\n id: 'delete',\n label: t('cpq.rowActions.delete', 'Delete'),\n destructive: true,\n onSelect: () => {\n void singleDelete(row)\n },\n })\n }\n return items\n },\n [canDelete, editHref, singleDelete, t],\n )\n\n return {\n buildItems,\n bulkDelete,\n ConfirmDialogElement,\n }\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["\"use client\"\nimport * as React from 'react'\nimport { flash } from '@open-mercato/ui/backend/FlashMessages'\nimport { type RowActionItem } from '@open-mercato/ui/backend/RowActions'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { useConfirmDialog } from '@open-mercato/ui/backend/confirm-dialog'\n\n// \u2500\u2500\u2500 Types \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport type UseCpqRowActionsOptions<T extends { id: string }> = {\n /** DELETE endpoint that accepts `{ id }` body (e.g. `/api/cpq/product-offerings`). */\n endpoint: string\n /**\n * Singular noun for the entity (e.g. `'offering'`).\n *\n * @deprecated Not used in messages any more: splicing a noun into a\n * sentence cannot produce correct grammar in ES / DE / PL (gender, case).\n * Confirm and flash messages are noun-free and count-based\n * (spec 2026-11-15-cpq-multi-language). Kept for API compatibility.\n */\n entityName?: string\n /**\n * Build the href for the row's edit/detail page (e.g. `(row) =>\n * `/backend/cpq/offerings/${row.id}`).\n */\n editHref: (row: T) => string\n /** Reload the table after a successful delete. */\n onReload: () => void\n /**\n * Override the row-deletion guard. Returning `false` skips the\n * delete request without flashing an error (e.g. when the row is in a\n * lifecycle state that disallows deletion).\n */\n canDelete?: (row: T) => boolean\n}\n\nexport type CpqRowActionsApi<T extends { id: string }> = {\n /**\n * Items for `<RowActions>` for a single row. Always returns\n * `Edit` + `Delete` \u2014 extras can be prepended / appended.\n */\n buildItems: (row: T, extras?: { prepend?: RowActionItem[]; append?: RowActionItem[] }) => RowActionItem[]\n /**\n * Bulk-delete handler suitable for `<DataTable bulkActions>`. Confirms once\n * for the whole selection, then issues `DELETE` requests sequentially so\n * a partial failure stops cleanly. Reports per-row failures via `flash`.\n *\n * Note: sequential by design \u2014 DELETE on the same table from N parallel\n * requests can deadlock at the row-lock level under load. Chunked\n * parallelism would be the next step if selection counts grow > ~200.\n */\n bulkDelete: (rows: T[]) => Promise<{ ok: boolean; affectedCount?: number }>\n /**\n * Render this element somewhere in the page (typically as the\n * `footerContent` slot of `<CpqListView>`) so the confirm dialog\n * portal mounts.\n */\n ConfirmDialogElement: React.ReactNode\n}\n\n// \u2500\u2500\u2500 Implementation \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport function useCpqRowActions<T extends { id: string }>(\n options: UseCpqRowActionsOptions<T>,\n): CpqRowActionsApi<T> {\n const { endpoint, editHref, onReload, canDelete } = options\n const t = useT()\n const { confirm, ConfirmDialogElement } = useConfirmDialog()\n\n const deleteOne = React.useCallback(\n async (id: string) => {\n const res = await fetch(endpoint, {\n method: 'DELETE',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ id }),\n })\n return res.ok\n },\n [endpoint],\n )\n\n const singleDelete = React.useCallback(\n async (row: T) => {\n if (canDelete && !canDelete(row)) return\n const confirmed = await confirm({\n title: t('cpq.rowActions.deleteOne.confirm', 'Delete this item?'),\n variant: 'destructive',\n })\n if (!confirmed) return\n const ok = await deleteOne(row.id)\n if (!ok) {\n flash(\n t('cpq.rowActions.deleteOne.error', 'Failed to delete the item'),\n 'error',\n )\n return\n }\n flash(t('cpq.rowActions.deleteOne.success', 'Item deleted'), 'success')\n onReload()\n },\n [canDelete, confirm, deleteOne, onReload, t],\n )\n\n const bulkDelete = React.useCallback(\n async (rows: T[]) => {\n if (!rows.length) return { ok: false }\n const eligible = canDelete ? rows.filter(canDelete) : rows\n if (!eligible.length) {\n flash(\n t('cpq.rowActions.deleteBulk.noEligible', 'None of the selected items can be deleted in their current state.'),\n 'error',\n )\n return { ok: false }\n }\n const confirmed = await confirm({\n title: t('cpq.rowActions.deleteBulk.confirm', 'Delete selected items ({count})?', { count: eligible.length }),\n variant: 'destructive',\n })\n if (!confirmed) return { ok: false }\n\n let failed = 0\n for (const row of eligible) {\n const ok = await deleteOne(row.id)\n if (!ok) failed += 1\n }\n\n if (failed > 0) {\n flash(\n t('cpq.rowActions.deleteBulk.partialError', 'Failed to delete {count} of the selected items', { count: failed }),\n 'error',\n )\n } else {\n flash(\n t('cpq.rowActions.deleteBulk.success', 'Selected items deleted ({count})', { count: eligible.length }),\n 'success',\n )\n }\n onReload()\n return { ok: failed === 0, affectedCount: eligible.length - failed }\n },\n [canDelete, confirm, deleteOne, onReload, t],\n )\n\n const buildItems = React.useCallback(\n (row: T, extras?: { prepend?: RowActionItem[]; append?: RowActionItem[] }): RowActionItem[] => {\n const items: RowActionItem[] = []\n if (extras?.prepend) items.push(...extras.prepend)\n items.push({\n id: 'edit',\n label: t('cpq.rowActions.edit', 'Edit'),\n href: editHref(row),\n })\n if (extras?.append) items.push(...extras.append)\n const deletable = !canDelete || canDelete(row)\n if (deletable) {\n items.push({\n id: 'delete',\n label: t('cpq.rowActions.delete', 'Delete'),\n destructive: true,\n onSelect: () => {\n void singleDelete(row)\n },\n })\n }\n return items\n },\n [canDelete, editHref, singleDelete, t],\n )\n\n return {\n buildItems,\n bulkDelete,\n ConfirmDialogElement,\n }\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }