@alfadocs/ui-kit-debug 1.127.0 → 1.127.2

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 (121) hide show
  1. package/dist/_chunks/{bill-line-table-BRxX0Awq.js → bill-line-table-CzYzg-Qh.js} +8 -5
  2. package/dist/_chunks/bill-line-table-CzYzg-Qh.js.map +1 -0
  3. package/dist/_chunks/{data-grid-bzvkQ3kc.js → data-grid-C9xlUMLt.js} +9 -5
  4. package/dist/_chunks/data-grid-C9xlUMLt.js.map +1 -0
  5. package/dist/_chunks/{default-tabs-yEfqAPuT.js → default-tabs-DOuHEKI5.js} +3 -3
  6. package/dist/_chunks/{default-tabs-yEfqAPuT.js.map → default-tabs-DOuHEKI5.js.map} +1 -1
  7. package/dist/_chunks/{invoice-upload-list-CgS_TBuX.js → invoice-upload-list-tJY7W1g_.js} +6 -4
  8. package/dist/_chunks/invoice-upload-list-tJY7W1g_.js.map +1 -0
  9. package/dist/_chunks/{muscle-scheme-TgnoZGDA.js → muscle-scheme-CHrjv7p2.js} +237 -235
  10. package/dist/_chunks/{muscle-scheme-TgnoZGDA.js.map → muscle-scheme-CHrjv7p2.js.map} +1 -1
  11. package/dist/_chunks/{toolbar-Co46MEn9.js → toolbar-CC-Ls_eC.js} +2 -2
  12. package/dist/_chunks/{toolbar-Co46MEn9.js.map → toolbar-CC-Ls_eC.js.map} +1 -1
  13. package/dist/agent-catalog.json +1 -1
  14. package/dist/browser-support.js +1 -1
  15. package/dist/components/bill-line-table/bill-line-table.columns.d.ts +7 -3
  16. package/dist/components/bill-line-table/bill-line-table.columns.d.ts.map +1 -1
  17. package/dist/components/bill-line-table/index.js +1 -1
  18. package/dist/components/bill-table/index.js +1 -1
  19. package/dist/components/data-grid/data-grid.variants.d.ts.map +1 -1
  20. package/dist/components/data-grid/index.js +2 -2
  21. package/dist/components/invoice-upload-list/columns.d.ts.map +1 -1
  22. package/dist/components/invoice-upload-list/index.js +1 -1
  23. package/dist/components/muscle-scheme/index.js +1 -1
  24. package/dist/components/muscle-scheme/muscle-scheme.d.ts.map +1 -1
  25. package/dist/core.css +1 -1
  26. package/dist/i18n/locales/ar.d.ts +5 -0
  27. package/dist/i18n/locales/ar.d.ts.map +1 -1
  28. package/dist/i18n/locales/ar.js +5 -0
  29. package/dist/i18n/locales/ar.js.map +1 -1
  30. package/dist/i18n/locales/de.d.ts +5 -0
  31. package/dist/i18n/locales/de.d.ts.map +1 -1
  32. package/dist/i18n/locales/de.js +5 -0
  33. package/dist/i18n/locales/de.js.map +1 -1
  34. package/dist/i18n/locales/el.d.ts +5 -0
  35. package/dist/i18n/locales/el.d.ts.map +1 -1
  36. package/dist/i18n/locales/el.js +5 -0
  37. package/dist/i18n/locales/el.js.map +1 -1
  38. package/dist/i18n/locales/en.d.ts +5 -0
  39. package/dist/i18n/locales/en.d.ts.map +1 -1
  40. package/dist/i18n/locales/en.js +5 -0
  41. package/dist/i18n/locales/en.js.map +1 -1
  42. package/dist/i18n/locales/es.d.ts +5 -0
  43. package/dist/i18n/locales/es.d.ts.map +1 -1
  44. package/dist/i18n/locales/es.js +5 -0
  45. package/dist/i18n/locales/es.js.map +1 -1
  46. package/dist/i18n/locales/fr.d.ts +5 -0
  47. package/dist/i18n/locales/fr.d.ts.map +1 -1
  48. package/dist/i18n/locales/fr.js +5 -0
  49. package/dist/i18n/locales/fr.js.map +1 -1
  50. package/dist/i18n/locales/hi.d.ts +5 -0
  51. package/dist/i18n/locales/hi.d.ts.map +1 -1
  52. package/dist/i18n/locales/hi.js +5 -0
  53. package/dist/i18n/locales/hi.js.map +1 -1
  54. package/dist/i18n/locales/it.d.ts +5 -0
  55. package/dist/i18n/locales/it.d.ts.map +1 -1
  56. package/dist/i18n/locales/it.js +5 -0
  57. package/dist/i18n/locales/it.js.map +1 -1
  58. package/dist/i18n/locales/ja.d.ts +5 -0
  59. package/dist/i18n/locales/ja.d.ts.map +1 -1
  60. package/dist/i18n/locales/ja.js +5 -0
  61. package/dist/i18n/locales/ja.js.map +1 -1
  62. package/dist/i18n/locales/nl.d.ts +5 -0
  63. package/dist/i18n/locales/nl.d.ts.map +1 -1
  64. package/dist/i18n/locales/nl.js +5 -0
  65. package/dist/i18n/locales/nl.js.map +1 -1
  66. package/dist/i18n/locales/pl.d.ts +5 -0
  67. package/dist/i18n/locales/pl.d.ts.map +1 -1
  68. package/dist/i18n/locales/pl.js +5 -0
  69. package/dist/i18n/locales/pl.js.map +1 -1
  70. package/dist/i18n/locales/pt.d.ts +5 -0
  71. package/dist/i18n/locales/pt.d.ts.map +1 -1
  72. package/dist/i18n/locales/pt.js +5 -0
  73. package/dist/i18n/locales/pt.js.map +1 -1
  74. package/dist/i18n/locales/ro.d.ts +5 -0
  75. package/dist/i18n/locales/ro.d.ts.map +1 -1
  76. package/dist/i18n/locales/ro.js +5 -0
  77. package/dist/i18n/locales/ro.js.map +1 -1
  78. package/dist/i18n/locales/ru.d.ts +5 -0
  79. package/dist/i18n/locales/ru.d.ts.map +1 -1
  80. package/dist/i18n/locales/ru.js +5 -0
  81. package/dist/i18n/locales/ru.js.map +1 -1
  82. package/dist/i18n/locales/sq.d.ts +5 -0
  83. package/dist/i18n/locales/sq.d.ts.map +1 -1
  84. package/dist/i18n/locales/sq.js +5 -0
  85. package/dist/i18n/locales/sq.js.map +1 -1
  86. package/dist/i18n/locales/sv.d.ts +5 -0
  87. package/dist/i18n/locales/sv.d.ts.map +1 -1
  88. package/dist/i18n/locales/sv.js +5 -0
  89. package/dist/i18n/locales/sv.js.map +1 -1
  90. package/dist/i18n/locales/tr.d.ts +5 -0
  91. package/dist/i18n/locales/tr.d.ts.map +1 -1
  92. package/dist/i18n/locales/tr.js +5 -0
  93. package/dist/i18n/locales/tr.js.map +1 -1
  94. package/dist/i18n/locales/zh.d.ts +5 -0
  95. package/dist/i18n/locales/zh.d.ts.map +1 -1
  96. package/dist/i18n/locales/zh.js +5 -0
  97. package/dist/i18n/locales/zh.js.map +1 -1
  98. package/dist/index.js +6 -6
  99. package/dist/locales/ar.json +5 -0
  100. package/dist/locales/de.json +5 -0
  101. package/dist/locales/el.json +5 -0
  102. package/dist/locales/en.json +5 -0
  103. package/dist/locales/es.json +5 -0
  104. package/dist/locales/fr.json +5 -0
  105. package/dist/locales/hi.json +5 -0
  106. package/dist/locales/it.json +5 -0
  107. package/dist/locales/ja.json +5 -0
  108. package/dist/locales/nl.json +5 -0
  109. package/dist/locales/pl.json +5 -0
  110. package/dist/locales/pt.json +5 -0
  111. package/dist/locales/ro.json +5 -0
  112. package/dist/locales/ru.json +5 -0
  113. package/dist/locales/sq.json +5 -0
  114. package/dist/locales/sv.json +5 -0
  115. package/dist/locales/tr.json +5 -0
  116. package/dist/locales/zh.json +5 -0
  117. package/dist/tokens.css +1 -1
  118. package/package.json +1 -1
  119. package/dist/_chunks/bill-line-table-BRxX0Awq.js.map +0 -1
  120. package/dist/_chunks/data-grid-bzvkQ3kc.js.map +0 -1
  121. package/dist/_chunks/invoice-upload-list-CgS_TBuX.js.map +0 -1
@@ -2,7 +2,7 @@ import { jsxs as p, jsx as r, Fragment as Je } from "react/jsx-runtime";
2
2
  import { createContext as Mt, useContext as ge, useRef as k, useLayoutEffect as Tn, useMemo as w, forwardRef as In, useEffect as je, useState as _e, useCallback as C, useImperativeHandle as Nn, useId as wn } from "react";
3
3
  import { useTranslation as Pt } from "react-i18next";
4
4
  import { u as kn } from "./registry-DvAUVLHh.js";
5
- import { e as xn } from "./data-grid-bzvkQ3kc.js";
5
+ import { e as xn } from "./data-grid-C9xlUMLt.js";
6
6
  import { a as q } from "./format-number-DdzqwMs1.js";
7
7
  import { i as _n } from "./is-development-CLUAnsU7.js";
8
8
  import { B as Ft } from "./badge-BUk4RjTS.js";
@@ -1215,7 +1215,8 @@ function Bi(e) {
1215
1215
  align: "end",
1216
1216
  cell: (i) => ki(i, e),
1217
1217
  exportValue: (i) => i.line.unitPrice,
1218
- size: 128,
1218
+ // 112 px of text: "EENHEIDSPRIJS" (nl) is the longest word.
1219
+ size: 144,
1219
1220
  hideable: !1,
1220
1221
  reorderable: !1
1221
1222
  },
@@ -1239,7 +1240,8 @@ function Bi(e) {
1239
1240
  exportValue: (i) => i.line.adjustments.map(
1240
1241
  (a) => `${a.type === "discount" ? "-" : "+"}${a.percent !== null ? `${a.percent}%` : a.amount ?? ""}`
1241
1242
  ).join(", ") || null,
1242
- size: 128,
1243
+ // 112 px of text: "MAGGIORAZIONE" (it) is the longest word.
1244
+ size: 144,
1243
1245
  hideable: !1,
1244
1246
  reorderable: !1
1245
1247
  },
@@ -1248,7 +1250,8 @@ function Bi(e) {
1248
1250
  header: t("billLineTable.column.supplierCode", "Supplier code"),
1249
1251
  cell: (i) => i.line.supplierCode === null ? null : /* @__PURE__ */ r("span", { dir: "ltr", className: Ue(), children: i.line.supplierCode }),
1250
1252
  exportValue: (i) => i.line.supplierCode,
1251
- size: 112,
1253
+ // 136 px of text: "LEVERANCIERSCODE" (nl) is the longest word.
1254
+ size: 168,
1252
1255
  hideable: !1,
1253
1256
  reorderable: !1
1254
1257
  }
@@ -1751,4 +1754,4 @@ export {
1751
1754
  oi as s,
1752
1755
  Ot as t
1753
1756
  };
1754
- //# sourceMappingURL=bill-line-table-BRxX0Awq.js.map
1757
+ //# sourceMappingURL=bill-line-table-CzYzg-Qh.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bill-line-table-CzYzg-Qh.js","sources":["../../src/components/bill-line-table/bill-line-table.agent.ts","../../src/components/bill-line-table/bill-line-table.variants.ts","../../src/components/bill-line-table/bill-line-table.header.tsx","../../src/components/bill-line-table/bill-line-table.model.ts","../../src/components/bill-line-table/bill-line-table.columns.tsx","../../src/components/bill-line-table/bill-line-table.tsx"],"sourcesContent":["/* -------------------------------------------------------------------- */\n/* Agent adapter: BillLineTable. */\n/* */\n/* Works against the curated BillLineTableHandle: ids, codes and exact */\n/* decimal text only. Never a description, supplier code, item name or */\n/* warning text: the state slots are PHI-free by construction. Ticks and */\n/* edits are `write`: they change what the host's Confirm loads into the */\n/* warehouse. Confirm itself is the host's button, not an action here. */\n/* A refused call throws an Error whose message starts with its code: the */\n/* handle validates and throws (BillLineErrorCode), the adapter lets it */\n/* pass. Type-only imports: the catalog build loads this file in plain */\n/* Node. */\n/* -------------------------------------------------------------------- */\n\nimport type { AgentAdapter } from '../../agent/types';\nimport type {\n BillLineFocusField,\n BillLineTableHandle,\n} from './bill-line-table.types';\n\nfunction refuse(code: 'UNKNOWN_LINE' | 'INVALID_ARGS', detail: string): never {\n throw new Error(`${code}: ${detail}`);\n}\n\n/** Unsigned decimal, dot separator, up to 8 places\n * (`BILL_LINE_QUANTITY_FRACTION_DIGITS`) and 8 integer digits. Values above\n * `BILL_LINE_MAX_QUANTITY` (10,000,000) or equal to 0 pass the pattern and\n * are refused by the handle with `INVALID_QUANTITY`. A literal, because\n * this file imports types only. */\nconst QUANTITY_PATTERN = '^[0-9]{1,8}([.][0-9]{1,8})?$';\n\nconst LINE_ID = { type: 'string', minLength: 1 } as const;\n\nconst LINE_INFO_TYPE =\n '{ id, lineNumber, matchState, selected, selectable, readOnly, quantityLocked, itemKind, itemId, quantity, removesStock, warningCodes, invalid }';\n\nexport const billLineTableAgent: AgentAdapter<BillLineTableHandle> = {\n id: 'bill-line-table',\n // select_multiple: ticks. set_value: a line's quantity and its item\n // (whole-value assignment to a NumberInput and a Combobox, 26 section 4).\n // scroll: focus_line. No `confirm`: loading is the host's.\n capabilities: ['select_multiple', 'set_value', 'scroll'],\n state: {\n lines: {\n type: `Array<${LINE_INFO_TYPE}>`,\n descriptionKey: 'ui.agent.billLineTable.state.lines',\n description:\n 'Every invoice line in invoice order, with what Confirm will do with it. matchState is one of matched, newItem, itemToUpdate (a matched line whose price, VAT or discount will change; counted inside matchedCount), skip or alreadyLoaded. Quantities are exact decimal text as shown, unsigned; there are no descriptions or names.',\n read: (handle) => handle.getLines(),\n },\n selection: {\n type: 'string[]',\n descriptionKey: 'ui.agent.billLineTable.state.selection',\n description: 'Ids of the ticked lines: the lines Confirm will load.',\n read: (handle) => handle.getSelection(),\n },\n summary: {\n type: '{ lineCount, selectedCount, matchedCount, newItemCount, itemUpdateCount, skippedCount, alreadyLoadedCount, warningLineCount, invoiceLoaded, invalidCount, net, vat, gross, canConfirm, dirty }',\n descriptionKey: 'ui.agent.billLineTable.state.summary',\n description:\n 'Counts and totals of the ticked lines. net, vat and gross are exact decimal text with 2 places (\"14.58\"). canConfirm is false while no line is ticked, a ticked line cannot load, or the invoice is already loaded (invoiceLoaded).',\n read: (handle) => handle.getSummary(),\n },\n invalidLineIds: {\n type: 'string[]',\n descriptionKey: 'ui.agent.billLineTable.state.invalidLineIds',\n description:\n 'Ticked lines that cannot load as they are: an empty or zero quantity, an item no longer in the warehouse, or an error from the server.',\n read: (handle) => handle.getInvalidLineIds(),\n },\n },\n actions: {\n select_lines: {\n safety: 'write',\n idempotent: true,\n argsType: \"{ ids: string[]; mode?: 'replace' | 'add' | 'remove' }\",\n argsSchema: {\n type: 'object',\n properties: {\n ids: { type: 'array', items: LINE_ID, uniqueItems: true },\n mode: { type: 'string', enum: ['replace', 'add', 'remove'] },\n },\n required: ['ids'],\n additionalProperties: false,\n },\n returns: 'string[]',\n errors: ['UNKNOWN_LINE', 'LINE_READ_ONLY', 'TABLE_READ_ONLY'],\n examples: [{ args: { ids: ['ln-3', 'ln-4'], mode: 'add' } }],\n descriptionKey: 'ui.agent.billLineTable.actions.selectLines',\n description:\n 'Tick or untick lines. Lines of an invoice that is already loaded cannot be ticked. Returns the ticked ids.',\n invoke: (\n handle,\n args: { ids: string[]; mode?: 'replace' | 'add' | 'remove' },\n ) => {\n // Unknown ids are refused in every mode, removal included.\n for (const id of args.ids) {\n if (!handle.getLine(id)) refuse('UNKNOWN_LINE', `no line \"${id}\".`);\n }\n const current = handle.getSelection();\n const mode = args.mode ?? 'replace';\n const next =\n mode === 'replace'\n ? args.ids\n : mode === 'add'\n ? [...current, ...args.ids]\n : current.filter((id) => !args.ids.includes(id));\n handle.setSelection(next);\n return handle.getSelection();\n },\n },\n select_all_lines: {\n safety: 'write',\n idempotent: true,\n returns: 'string[]',\n errors: ['TABLE_READ_ONLY'],\n descriptionKey: 'ui.agent.billLineTable.actions.selectAllLines',\n description: 'Tick every line that can load. Returns the ticked ids.',\n invoke: (handle) => {\n handle.selectAll();\n return handle.getSelection();\n },\n },\n clear_selection: {\n safety: 'write',\n idempotent: true,\n returns: 'string[]',\n errors: ['TABLE_READ_ONLY'],\n descriptionKey: 'ui.agent.billLineTable.actions.clearSelection',\n description: 'Untick every line.',\n invoke: (handle) => {\n handle.clearSelection();\n return handle.getSelection();\n },\n },\n set_quantity: {\n safety: 'write',\n idempotent: true,\n argsType: '{ lineId: string; quantity: string }',\n argsSchema: {\n type: 'object',\n properties: {\n lineId: LINE_ID,\n quantity: { type: 'string', pattern: QUANTITY_PATTERN },\n },\n required: ['lineId', 'quantity'],\n additionalProperties: false,\n },\n returns: LINE_INFO_TYPE,\n errors: [\n 'UNKNOWN_LINE',\n 'INVALID_QUANTITY',\n 'TABLE_READ_ONLY',\n 'LINE_READ_ONLY',\n ],\n examples: [\n { args: { lineId: 'ln-2', quantity: '2.5' } },\n {\n args: { lineId: 'ln-7', quantity: '3' },\n note: 'On a credit note this removes 3 from stock.',\n },\n ],\n descriptionKey: 'ui.agent.billLineTable.actions.setQuantity',\n description:\n 'Set the quantity of a line as shown in the table: a decimal above 0 and at most 10000000, with a dot and up to 8 places, never signed. On a credit note it is the quantity to remove. The line amount stays as invoiced. Does not tick the line.',\n invoke: (handle, args: { lineId: string; quantity: string }) => {\n // The handle validates and normalises (\"02.50\" is stored as \"2.5\").\n handle.setQuantity(args.lineId, args.quantity);\n return handle.getLine(args.lineId);\n },\n },\n set_item: {\n safety: 'write',\n idempotent: true,\n argsType: '{ lineId: string; itemId: string }',\n argsSchema: {\n type: 'object',\n properties: {\n lineId: LINE_ID,\n itemId: { type: 'string', minLength: 1 },\n },\n required: ['lineId', 'itemId'],\n additionalProperties: false,\n },\n returns: LINE_INFO_TYPE,\n errors: [\n 'UNKNOWN_LINE',\n 'UNKNOWN_ITEM',\n 'TABLE_READ_ONLY',\n 'LINE_READ_ONLY',\n ],\n descriptionKey: 'ui.agent.billLineTable.actions.setItem',\n description:\n 'Load a line into an existing warehouse item, by item id. Does not tick the line.',\n invoke: (handle, args: { lineId: string; itemId: string }) => {\n handle.setItem(args.lineId, { kind: 'existing', itemId: args.itemId });\n return handle.getLine(args.lineId);\n },\n },\n create_new_item: {\n safety: 'write',\n idempotent: true,\n argsType: '{ lineId: string; name?: string }',\n argsSchema: {\n type: 'object',\n properties: {\n lineId: LINE_ID,\n // DoctorInventoryItem.name is a string of 255.\n name: { type: 'string', minLength: 1, maxLength: 255 },\n },\n required: ['lineId'],\n additionalProperties: false,\n },\n returns: LINE_INFO_TYPE,\n errors: [\n 'UNKNOWN_LINE',\n 'INVALID_ARGS',\n 'TABLE_READ_ONLY',\n 'LINE_READ_ONLY',\n ],\n descriptionKey: 'ui.agent.billLineTable.actions.createNewItem',\n description:\n 'Mark a line to create a new warehouse item when the invoice is loaded. Without a name, the item takes the line description. Nothing is created until Confirm. Does not tick the line.',\n invoke: (handle, args: { lineId: string; name?: string }) => {\n const name = args.name?.trim();\n if (args.name !== undefined && !name) {\n refuse('INVALID_ARGS', 'name is empty.');\n }\n // The handle fills in the description when the name is empty, so the\n // description never passes through the agent.\n handle.setItem(args.lineId, { kind: 'new', name: name ?? '' });\n return handle.getLine(args.lineId);\n },\n },\n focus_line: {\n safety: 'read',\n idempotent: true,\n argsType: \"{ lineId: string; field?: 'select' | 'quantity' | 'item' }\",\n argsSchema: {\n type: 'object',\n properties: {\n lineId: LINE_ID,\n field: { type: 'string', enum: ['select', 'quantity', 'item'] },\n },\n required: ['lineId'],\n additionalProperties: false,\n },\n errors: ['UNKNOWN_LINE'],\n descriptionKey: 'ui.agent.billLineTable.actions.focusLine',\n description:\n 'Scroll a line into view and move focus to its checkbox, quantity or item field.',\n invoke: (\n handle,\n args: { lineId: string; field?: BillLineFocusField },\n ) => {\n handle.focusLine(args.lineId, args.field);\n },\n },\n },\n domHooks: {\n root: {\n attr: 'data-component',\n value: 'bill-line-table',\n description: 'Marks the element as a kit BillLineTable.',\n },\n instanceId: {\n attr: 'data-component-id',\n sourceProp: 'gridId',\n description: 'The agent instance id.',\n },\n item: {\n attr: 'data-row-id',\n sourceProp: 'lines[].id',\n description:\n 'BillLine.id on each body row (written by DataGrid). The only line datum in the DOM.',\n },\n },\n};\n","/* -------------------------------------------------------------------- */\n/* BillLineTable: CVA (tokens only, logical properties). */\n/* -------------------------------------------------------------------- */\n\nimport { cva } from 'class-variance-authority';\nimport { EDITOR_COMPACT_FIELDS_CLASS } from '../_shared/compact-editor-fields';\n\n/** The bounding element: a flex column around the DataGrid, so `fill`\n * reaches the grid inside `Dialog.Body` (the Dialog recipe). */\nexport const billLineTableVariants = cva('ds:flex ds:min-w-0 ds:flex-col', {\n variants: {\n height: {\n auto: '',\n fill: 'ds:min-h-0 ds:flex-1',\n },\n },\n defaultVariants: { height: 'fill' },\n});\n\n/** The item Combobox in its cell: the kit's compact field exception, as\n * DataGrid's built-in editors use it (32 px, raised to `--min-target-size`\n * under the accessible themes and on touch widths), instead of\n * `size=\"sm\"`, so the list rows keep the kit's target. */\nexport const itemEditorVariants = cva([\n 'ds:w-full ds:min-w-0',\n EDITOR_COMPACT_FIELDS_CLASS,\n]);\n\n/** A value with a second line under it (unit price and \"Net per unit\"). */\nexport const stackVariants = cva('ds:flex ds:flex-col', {\n variants: {\n align: {\n start: 'ds:items-start',\n end: 'ds:items-end',\n },\n },\n defaultVariants: { align: 'start' },\n});\n\n/** Muted second-line text. */\nexport const secondaryTextVariants = cva(\n 'type-body-sm ds:text-[color:var(--muted-foreground)]',\n);\n\n/** Adjustment and warning lists inside a cell. */\nexport const cellListVariants = cva(\n 'ds:m-0 ds:flex ds:list-none ds:flex-col ds:gap-[var(--spacing-2xs)] ds:p-0',\n {\n variants: {\n align: {\n start: 'ds:items-start',\n end: 'ds:items-end',\n },\n },\n defaultVariants: { align: 'start' },\n },\n);\n\n/** Figures that line up in a column. */\nexport const figureVariants = cva('ds:tabular-nums');\n\n/** One warning: icon, then the text. */\nexport const warningItemVariants = cva(\n 'ds:flex ds:items-start ds:gap-[var(--spacing-xs)]',\n);\n\n/** The warning icon carries the tone; the message stays in the body ink. */\nexport const warningIconVariants = cva(\n 'ds:mt-[var(--spacing-2xs)] ds:size-4 ds:shrink-0',\n {\n variants: {\n severity: {\n warning: 'ds:text-[color:var(--warning-foreground)]',\n error: 'ds:text-[color:var(--error-foreground)]',\n },\n },\n defaultVariants: { severity: 'warning' },\n },\n);\n\nexport const warningTextVariants = cva('ds:text-[color:var(--foreground)]');\n\n/** Net and Total with VAT under the Amount column. Each label sits above its\n * figure: side by side, \"Total with VAT\" broke over three lines in the\n * 128 px column. */\nexport const totalsListVariants = cva(\n 'ds:m-0 ds:grid ds:grid-cols-1 ds:justify-items-end ds:text-end',\n);\n\nexport const totalsTermVariants = cva(\n 'type-meta ds:text-[color:var(--muted-foreground)]',\n);\n\nexport const totalsValueVariants = cva(\n 'ds:m-0 ds:[&:not(:last-child)]:mb-[var(--spacing-2xs)]',\n);\n\n/** One adjustment block: its label, then the signed figure. */\nexport const adjustmentItemVariants = cva(\n 'ds:flex ds:flex-wrap ds:items-baseline ds:justify-end ds:gap-x-[var(--spacing-xs)]',\n);\n\n/** The arrow between the old and the new value: inline with the text, and\n * mirrored in right-to-left so it points the way the sentence reads. */\nexport const updateArrowVariants = cva(\n 'ds:inline ds:size-3 ds:align-middle ds:rtl:-scale-x-100',\n);\n\n/** One change under the Status badge: figures in tabular numerals. */\nexport const updateItemVariants = cva('ds:tabular-nums type-body-sm');\n\n/** The invoice header block above the table: facts side by side, wrapping\n * on a narrow Dialog. */\nexport const headerVariants = cva(\n 'ds:m-0 ds:flex ds:shrink-0 ds:flex-wrap ds:gap-x-[var(--spacing-lg)] ds:gap-y-[var(--spacing-sm)] ds:pb-[var(--spacing-md)]',\n);\n\nexport const headerTermVariants = cva(\n 'type-meta ds:text-[color:var(--muted-foreground)]',\n);\n\nexport const headerValueVariants = cva(\n 'ds:m-0 ds:flex ds:items-center ds:gap-[var(--spacing-xs)] ds:text-[color:var(--foreground)]',\n);\n","/* -------------------------------------------------------------------- */\n/* BillLineTable: the optional invoice header block (supplier, number, */\n/* date, SDI or Upload tag). Display only; the host passes the facts. */\n/* A person supplier (a sole trader or private individual) is masked */\n/* under privacy mode; a company stays visible. Only ids reach the DOM: */\n/* nothing here writes the supplier name to an attribute. */\n/* -------------------------------------------------------------------- */\n\nimport { EyeOff } from 'lucide-react';\nimport { useTranslation } from 'react-i18next';\nimport { Badge } from '../badge';\nimport { formatLocale } from '../_shared/intl-locale';\nimport { privacyMask } from '../_shared/privacy-mask-text';\nimport { VisuallyHidden } from '../visually-hidden';\nimport {\n headerTermVariants,\n headerValueVariants,\n headerVariants,\n} from './bill-line-table.variants';\nimport type { BillLineInvoiceHeader } from './bill-line-table.types';\n\nconst dayFormatters = new Map<string, Intl.DateTimeFormat>();\nconst CALENDAR_DAY = /^(\\d{4})-(\\d{2})-(\\d{2})$/;\n\n/** `YYYY-MM-DD` in the UI language, medium style, read in UTC so the day\n * never moves with the time zone. Other text is returned as given. */\nfunction formatDay(day: string, language: string): string {\n const match = CALENDAR_DAY.exec(day);\n if (!match) return day;\n const instant = new Date(\n Date.UTC(Number(match[1]), Number(match[2]) - 1, Number(match[3])),\n );\n if (Number.isNaN(instant.getTime())) return day;\n const locale = formatLocale(language);\n let formatter = dayFormatters.get(locale);\n if (!formatter) {\n formatter = new Intl.DateTimeFormat(locale, {\n dateStyle: 'medium',\n timeZone: 'UTC',\n });\n dayFormatters.set(locale, formatter);\n }\n return formatter.format(instant);\n}\n\nexport interface BillLineInvoiceHeaderBlockProps {\n invoice: BillLineInvoiceHeader;\n privacyMode: boolean;\n}\n\nexport function BillLineInvoiceHeaderBlock({\n invoice,\n privacyMode,\n}: BillLineInvoiceHeaderBlockProps) {\n const { t, i18n } = useTranslation('ui');\n const masked = privacyMode && invoice.supplier.kind === 'person';\n return (\n <dl\n className={headerVariants()}\n data-component=\"bill-line-invoice-header\"\n data-part=\"invoice-header\"\n >\n <div>\n <dt className={headerTermVariants()}>\n {t('billLineTable.header.supplier', 'Supplier')}\n </dt>\n <dd className={headerValueVariants()}>\n {masked ? (\n <>\n <EyeOff aria-hidden=\"true\" className=\"ds:size-4 ds:shrink-0\" />\n <VisuallyHidden>\n {t('billLineTable.header.supplierHidden', 'Name hidden')}\n </VisuallyHidden>\n <span aria-hidden=\"true\">{privacyMask()}</span>\n </>\n ) : (\n <span dir=\"auto\">{invoice.supplier.name}</span>\n )}\n </dd>\n </div>\n <div>\n <dt className={headerTermVariants()}>\n {t('billLineTable.header.number', 'Invoice number')}\n </dt>\n <dd className={headerValueVariants()}>\n <span dir=\"auto\">{invoice.number}</span>\n </dd>\n </div>\n <div>\n <dt className={headerTermVariants()}>\n {t('billLineTable.header.date', 'Date')}\n </dt>\n <dd className={headerValueVariants()}>\n {formatDay(invoice.date, i18n.language)}\n </dd>\n </div>\n <div>\n <dt className={headerTermVariants()}>\n {t('billLineTable.header.source', 'Source')}\n </dt>\n <dd className={headerValueVariants()}>\n <Badge size=\"sm\" variant=\"neutral\">\n {invoice.source === 'sdi'\n ? t('billLineTable.header.sourceSdi', 'SDI')\n : t('billLineTable.header.sourceUpload', 'Upload')}\n </Badge>\n </dd>\n </div>\n </dl>\n );\n}\n","/* -------------------------------------------------------------------- */\n/* BillLineTable: the pure model (design-bill-line-table.md sections 1, */\n/* 2.2, 4.1). */\n/* */\n/* Defaults, match state, validity, the totals, the load payload and the */\n/* DataGrid row view model. React-free. Every decimal goes through the */\n/* kit's `../_shared/decimal` (`@alfadocs/ui-kit/decimal`): integer units */\n/* plus a scale, BigInt inside every sum, one rounding per figure, half */\n/* away from zero. A float exists only inside NumberInput while a person */\n/* types; `numberToDecimal` turns it back into exact text at once. */\n/* -------------------------------------------------------------------- */\n\nimport {\n FATTURAPA_VALUE,\n compareDecimal,\n decimalToNumber,\n divideDecimal,\n formatDecimal,\n multiplyDecimal,\n numberToDecimal,\n parseDecimal,\n rescaleDecimal,\n sumDecimals,\n type DecimalRules,\n type DecimalString,\n type ScaledDecimal,\n} from '../_shared/decimal';\nimport type {\n BillDocumentKind,\n BillLine,\n BillLineInfo,\n BillLineItemChoice,\n BillLineItemOption,\n BillLineItemUpdateChange,\n BillLineLoadEntry,\n BillLineLoadResult,\n BillLineMatchState,\n BillLineRow,\n BillLineSummary,\n BillLineValue,\n BillLineValues,\n} from './bill-line-table.types';\n\n/* ================================================================== */\n/* Constants */\n/* ================================================================== */\n\n/** Most fraction digits of a quantity: FatturaPA 2.2.1.5 `Quantita`\n * (`[0-9]{1,12}\\.[0-9]{2,8}`, quoted in `Version20260608180319.php:38`). */\nexport const BILL_LINE_QUANTITY_FRACTION_DIGITS = 8;\n\n/** Most fraction digits of a price or amount: FatturaPA 2.2.1.9\n * `PrezzoUnitario`, 2.2.1.11 `PrezzoTotale`, 2.2.1.10.3 `Importo`. */\nexport const BILL_LINE_PRICE_FRACTION_DIGITS = 8;\n\n/** Fraction digits of a rate: 2.2.1.12 `AliquotaIVA`, 2.2.1.10.2\n * `Percentuale`. */\nexport const BILL_LINE_PERCENT_FRACTION_DIGITS = 2;\n\n/** Largest quantity the editor accepts (D15). It keeps every typed value\n * where a double and its decimal text agree exactly. An invoiced quantity\n * above it, or with more than 15 significant digits, is shown read-only\n * with the kit's \"too large to edit here\" note and loads unchanged: it is\n * never clamped. The handle and the agent refuse a larger value with\n * `INVALID_QUANTITY`. */\nexport const BILL_LINE_MAX_QUANTITY = 10_000_000;\n\n/** Longest new-item name: `DoctorInventoryItem.name` is a string of 255\n * (`DoctorInventoryItem.orm.xml`). */\nexport const BILL_LINE_ITEM_NAME_MAX_LENGTH = 255;\n\n/** Combobox value of the per-line \"New item: …\" option. Never a platform\n * article id: `DoctorInventoryItem.id` is an integer\n * (`DoctorInventoryItem.orm.xml`, `<id name=\"id\" type=\"integer\">`). */\nexport const BILL_LINE_NEW_ITEM_VALUE = 'bill-line-table:new-item';\n\n/** The kit's own warning code for a locked quantity (D15). */\nexport const BILL_LINE_QUANTITY_TOO_LARGE = 'quantityTooLarge';\n\n/* ================================================================== */\n/* Reading decimals */\n/* ================================================================== */\n\nconst ZERO: ScaledDecimal = { units: 0, scale: 0 };\n\nconst MAX_QUANTITY: ScaledDecimal = { units: BILL_LINE_MAX_QUANTITY, scale: 0 };\n\n/** Quantities are read with the sign allowed and judged afterwards: a\n * negative quantity is a contract error the line must show, not hide. */\nconst QUANTITY_READ: DecimalRules = {\n ...FATTURAPA_VALUE.quantity,\n allowNegative: true,\n};\n\n/** Trailing zeros dropped: the same value at its smallest scale. Exact:\n * only whole multiples of ten are divided. */\nfunction trimDecimal(value: ScaledDecimal): ScaledDecimal {\n let { units, scale } = value;\n while (scale > 0 && units % 10 === 0) {\n units /= 10;\n scale -= 1;\n }\n return { units: units || 0, scale };\n}\n\nfunction absDecimal(value: ScaledDecimal): ScaledDecimal {\n return { units: Math.abs(value.units), scale: value.scale };\n}\n\n/** What a quantity text means to the table. */\nexport interface BillLineQuantityReading {\n /** No text: the field is empty. */\n empty: boolean;\n /** Syntax and digits pass `FATTURAPA_VALUE.quantity`, the sign aside. */\n wellFormed: boolean;\n /** Above zero. */\n positive: boolean;\n /** The exact value when a safe integer holds its units, else `null`. */\n value: ScaledDecimal | null;\n /** The number NumberInput shows: exact both ways (at most 15 significant\n * digits) and at most `BILL_LINE_MAX_QUANTITY` in size. `null` for an\n * empty, malformed or out-of-range quantity. */\n editorNumber: number | null;\n}\n\nexport function readBillLineQuantity(\n text: DecimalString | null,\n): BillLineQuantityReading {\n const blank: BillLineQuantityReading = {\n empty: true,\n wellFormed: false,\n positive: false,\n value: null,\n editorNumber: null,\n };\n if (text === null || text.trim() === '') return blank;\n const parsed = parseDecimal(text, QUANTITY_READ);\n if (parsed.ok) {\n const number = decimalToNumber(parsed.value);\n return {\n empty: false,\n wellFormed: true,\n positive: parsed.value.units > 0,\n value: parsed.value,\n editorNumber:\n number !== null && Math.abs(number) <= BILL_LINE_MAX_QUANTITY\n ? number\n : null,\n };\n }\n if (parsed.error === 'unsafe') {\n // Well formed, but more digits than a safe integer holds: always far\n // above BILL_LINE_MAX_QUANTITY, so it loads as invoiced, read-only.\n return {\n empty: false,\n wellFormed: true,\n positive: !text.trim().startsWith('-'),\n value: null,\n editorNumber: null,\n };\n }\n return { ...blank, empty: false };\n}\n\n/** Can the editor hold this quantity exactly (D15)? False above\n * `BILL_LINE_MAX_QUANTITY` or beyond 15 significant digits: the line then\n * shows its quantity read-only with the kit's `quantityTooLarge` note and\n * loads it as invoiced. A malformed quantity stays editable, so the\n * reviewer can type a correct one. */\nexport function isBillLineQuantityEditable(quantity: DecimalString): boolean {\n const reading = readBillLineQuantity(quantity);\n return !reading.wellFormed || reading.editorNumber !== null;\n}\n\n/** A NumberInput value back to exact decimal text, at most 8 fraction\n * digits, never padded and with no trailing zeros (`2.5` is `\"2.5\"`,\n * `0.1 + 0.2` is `\"0.3\"`). `null` for NaN or Infinity. */\nexport function billLineQuantityFromNumber(\n value: number,\n): DecimalString | null {\n const scaled = numberToDecimal(value, BILL_LINE_QUANTITY_FRACTION_DIGITS);\n return scaled ? formatDecimal(trimDecimal(scaled)) : null;\n}\n\n/** A signed amount (line total, unit price, adjustment, summary figure),\n * up to 8 places. `null` when the text is malformed or its units pass a\n * safe integer (about 90 million at 8 places): the platform flags such a\n * line `valueOutOfRange`, and the kit counts it as invalid. */\nexport function readBillLineAmount(text: DecimalString): ScaledDecimal | null {\n const parsed = parseDecimal(text, FATTURAPA_VALUE.lineTotal);\n return parsed.ok ? parsed.value : null;\n}\n\n/** A rate (VAT or a discount percentage), unsigned, 2 places. */\nexport function readBillLineRate(\n text: DecimalString | null,\n): ScaledDecimal | null {\n if (text === null) return null;\n const parsed = parseDecimal(text, FATTURAPA_VALUE.rate);\n return parsed.ok ? parsed.value : null;\n}\n\n/** Net unit cost (D14): `lineTotal` / quantity at 8 places, one rounding\n * half away from zero, trailing zeros dropped (30.86 / 2.5 is\n * `\"12.344\"`). `null` for an empty, zero or unreadable quantity. */\nexport function netUnitCost(\n lineTotal: DecimalString,\n quantity: DecimalString | null,\n): DecimalString | null {\n const total = readBillLineAmount(lineTotal);\n const count = readBillLineQuantity(quantity).value;\n if (!total || !count || count.units === 0) return null;\n const cost = divideDecimal(total, count, BILL_LINE_PRICE_FRACTION_DIGITS);\n return cost ? formatDecimal(trimDecimal(cost)) : null;\n}\n\n/** Do two signed amounts have the same size? A credit note may carry an\n * unsigned `PrezzoUnitario` beside an inverted `PrezzoTotale`, so the\n * \"Net per unit\" line compares sizes, not signs. */\nexport function sameBillLineMagnitude(\n a: DecimalString,\n b: DecimalString,\n): boolean {\n const x = readBillLineAmount(a);\n const y = readBillLineAmount(b);\n if (!x || !y) return a.trim() === b.trim();\n return compareDecimal(absDecimal(x), absDecimal(y)) === 0;\n}\n\n/* ================================================================== */\n/* Values and defaults */\n/* ================================================================== */\n\n/** A new-item name as the platform stores it: trimmed, at most 255\n * characters (code points, as MySQL counts them). */\nexport function normaliseBillLineItemName(name: string): string {\n const trimmed = name.trim();\n const characters = Array.from(trimmed);\n return characters.length > BILL_LINE_ITEM_NAME_MAX_LENGTH\n ? characters.slice(0, BILL_LINE_ITEM_NAME_MAX_LENGTH).join('').trim()\n : trimmed;\n}\n\n/** A choice as the table stores it: a new item with no name takes the line\n * description (D5). */\nexport function normaliseBillLineItemChoice(\n choice: BillLineItemChoice,\n line: BillLine,\n): BillLineItemChoice {\n if (choice.kind === 'existing') {\n return { kind: 'existing', itemId: choice.itemId };\n }\n const name = normaliseBillLineItemName(choice.name);\n return {\n kind: 'new',\n name: name === '' ? normaliseBillLineItemName(line.description) : name,\n };\n}\n\n/** Is a quantity text above `BILL_LINE_MAX_QUANTITY` (or too long for a\n * safe integer)? Only a well-formed quantity can be. */\nfunction exceedsBillLineMaxQuantity(text: DecimalString | null): boolean {\n const reading = readBillLineQuantity(text);\n if (!reading.wellFormed) return false;\n if (reading.value === null) return true;\n return compareDecimal(absDecimal(reading.value), MAX_QUANTITY) > 0;\n}\n\n/** D15: a quantity a person set above `BILL_LINE_MAX_QUANTITY`. The\n * invoiced quantity itself never counts: a locked line loads as invoiced. */\nexport function isBillLineQuantityTooLarge(\n line: BillLine,\n value: BillLineValue,\n): boolean {\n return (\n exceedsBillLineMaxQuantity(value.quantity) &&\n !sameQuantity(value.quantity, line.quantity)\n );\n}\n\n/** A new item with no name: the description was blank and nothing was\n * typed. The platform cannot create an item without a name. */\nexport function isBillLineNewItemNameMissing(value: BillLineValue): boolean {\n return (\n value.item.kind === 'new' &&\n normaliseBillLineItemName(value.item.name) === ''\n );\n}\n\n/** A new item that still carries the line description as its name (the\n * prefill, D5). On a lab invoice that name can be a patient's (Q3), so\n * privacy mode asks the reviewer to check it with privacy mode off. */\nexport function isBillLineNewItemNamedFromDescription(\n line: BillLine,\n value: BillLineValue,\n): boolean {\n if (value.item.kind !== 'new') return false;\n const name = normaliseBillLineItemName(value.item.name);\n return name !== '' && name === normaliseBillLineItemName(line.description);\n}\n\n/** True when any line is already loaded: the HTP-7311 one-load rule then\n * locks the whole invoice (D8). */\nexport function isBillInvoiceLoaded(lines: readonly BillLine[]): boolean {\n return lines.some((line) => line.alreadyLoaded);\n}\n\n/** The value every line starts with: its invoiced quantity and the\n * proposal's item, or a new item named after the description (see product\n * question Q3 on lab lines that name a patient). */\nexport function getDefaultBillLineValue(line: BillLine): BillLineValue {\n // Warehouse item names are never masked once created: see\n // `isBillLineNewItemNamedFromDescription` for the privacy-mode check.\n return {\n quantity: line.quantity,\n item:\n line.proposal === 'existing' && line.proposedItemId !== null\n ? { kind: 'existing', itemId: line.proposedItemId }\n : { kind: 'new', name: normaliseBillLineItemName(line.description) },\n };\n}\n\nexport function getDefaultBillLineValues(\n lines: readonly BillLine[],\n): Record<string, BillLineValue> {\n const values: Record<string, BillLineValue> = {};\n for (const line of lines) values[line.id] = getDefaultBillLineValue(line);\n return values;\n}\n\n/** Every line that can load and was not proposed as skip. None once the\n * invoice is loaded. */\nexport function getDefaultBillLineSelection(\n lines: readonly BillLine[],\n): string[] {\n if (isBillInvoiceLoaded(lines)) return [];\n return lines\n .filter((line) => line.proposal !== 'skip')\n .map((line) => line.id);\n}\n\n/** Every current line's value, missing entries as their default; entries\n * for lines no longer in `lines` are dropped. */\nexport function resolveBillLineValues(\n lines: readonly BillLine[],\n values: BillLineValues,\n): Record<string, BillLineValue> {\n const resolved: Record<string, BillLineValue> = {};\n for (const line of lines) {\n resolved[line.id] = values[line.id] ?? getDefaultBillLineValue(line);\n }\n return resolved;\n}\n\n/** Can this line be ticked? Not when it, or any line of its invoice, is\n * already loaded (D8). */\nfunction isSelectableLine(line: BillLine, invoiceLoaded: boolean): boolean {\n return !invoiceLoaded && !line.alreadyLoaded;\n}\n\n/** The ids that are ticked in effect: known, tickable lines only, unique,\n * in invoice order. */\nexport function resolveBillLineSelection(\n lines: readonly BillLine[],\n selection: readonly string[],\n): string[] {\n const invoiceLoaded = isBillInvoiceLoaded(lines);\n if (invoiceLoaded || selection.length === 0) return [];\n const ticked = new Set(selection);\n return lines\n .filter((line) => ticked.has(line.id) && isSelectableLine(line, false))\n .map((line) => line.id);\n}\n\nfunction sameItemChoice(a: BillLineItemChoice, b: BillLineItemChoice): boolean {\n if (a.kind === 'existing') {\n return b.kind === 'existing' && a.itemId === b.itemId;\n }\n return (\n b.kind === 'new' &&\n normaliseBillLineItemName(a.name) === normaliseBillLineItemName(b.name)\n );\n}\n\nfunction sameQuantity(a: DecimalString | null, b: DecimalString | null) {\n if (a === b) return true;\n if (a === null || b === null) return false;\n const x = readBillLineQuantity(a).value;\n const y = readBillLineQuantity(b).value;\n return x && y ? compareDecimal(x, y) === 0 : a.trim() === b.trim();\n}\n\n/** Same value whatever the scale (\"2.50\" equals \"2.5\"). */\nexport function sameBillLineValue(a: BillLineValue, b: BillLineValue): boolean {\n return sameQuantity(a.quantity, b.quantity) && sameItemChoice(a.item, b.item);\n}\n\n/* ================================================================== */\n/* Match state and validity */\n/* ================================================================== */\n\n/** What Confirm will do with the line (D3): the badge cannot disagree with\n * the checkbox. */\nexport function getBillLineMatchState(\n line: BillLine,\n value: BillLineValue,\n selected: boolean,\n): BillLineMatchState {\n if (line.alreadyLoaded) return 'alreadyLoaded';\n if (!selected) return 'skip';\n if (value.item.kind !== 'existing') return 'newItem';\n return isBillLineItemToUpdate(line, value) ? 'itemToUpdate' : 'matched';\n}\n\n/** One change counts when it has a side and the sides differ. Decimal\n * values compare by value, so \"10\" to \"10.00\" is no change. The state and\n * the cell share this rule. */\nexport function isBillLineItemUpdateChange(\n change: BillLineItemUpdateChange | undefined,\n): boolean {\n if (!change) return false;\n if (change.from === change.to) return false;\n if (change.from === null || change.to === null) return true;\n const a = parseDecimal(change.from, FATTURAPA_VALUE.lineTotal);\n const b = parseDecimal(change.to, FATTURAPA_VALUE.lineTotal);\n return a.ok && b.ok ? compareDecimal(a.value, b.value) !== 0 : true;\n}\n\n/** True when the line carries at least one item change. */\nexport function hasBillLineItemUpdate(line: BillLine): boolean {\n const update = line.itemUpdate;\n if (!update) return false;\n return (\n isBillLineItemUpdateChange(update.unitPrice) ||\n isBillLineItemUpdateChange(update.vatRate) ||\n isBillLineItemUpdateChange(update.discountPercent)\n );\n}\n\n/** The changes were computed against the proposed item, so they apply only\n * while that item is the chosen one. */\nexport function isBillLineItemToUpdate(\n line: BillLine,\n value: BillLineValue,\n): boolean {\n return (\n value.item.kind === 'existing' &&\n line.proposal === 'existing' &&\n value.item.itemId === line.proposedItemId &&\n hasBillLineItemUpdate(line)\n );\n}\n\n/**\n * Can this line load as it stands? Judged for ticked lines. Invalid when:\n * - the quantity is empty, malformed, zero or negative (quantities are\n * unsigned, so a negative one is a contract error);\n * - a person set the quantity above `BILL_LINE_MAX_QUANTITY` (D15);\n * - a new item has no name;\n * - an `'error'` warning is on the line;\n * - the line amount cannot be read exactly (`valueOutOfRange`);\n * - `itemKnown` is false: the chosen existing item is no longer known\n * (the table passes this; a host calling the helper may leave it out).\n */\nexport function isBillLineInvalid(\n line: BillLine,\n value: BillLineValue,\n itemKnown = true,\n): boolean {\n const quantity = readBillLineQuantity(value.quantity);\n if (!quantity.wellFormed || !quantity.positive) return true;\n if (isBillLineQuantityTooLarge(line, value)) return true;\n if (!readBillLineAmount(line.lineTotal)) return true;\n if (value.item.kind === 'existing' && !itemKnown) return true;\n if (isBillLineNewItemNameMissing(value)) return true;\n return line.warnings.some((warning) => warning.severity === 'error');\n}\n\n/** Item lookup the table passes to the helpers; the default knows every\n * item. */\nexport type BillLineItemLookup = (itemId: string) => boolean;\n\nconst KNOWS_EVERY_ITEM: BillLineItemLookup = () => true;\n\nfunction itemKnownFor(value: BillLineValue, isItemKnown: BillLineItemLookup) {\n return value.item.kind !== 'existing' || isItemKnown(value.item.itemId);\n}\n\n/* ================================================================== */\n/* Totals */\n/* ================================================================== */\n\n/** The exact sum at the widest scale. A sum whose units pass a safe\n * integer (above about 90 million at 8 places, beyond any valid FatturaPA\n * document total) rounds each amount to cents first. */\nfunction sumExact(values: readonly ScaledDecimal[]): ScaledDecimal {\n const exact = sumDecimals(values);\n if (exact) return exact;\n const cents: ScaledDecimal[] = [];\n for (const value of values) {\n const rounded = rescaleDecimal(value, 2);\n if (rounded) cents.push(rounded);\n }\n return sumDecimals(cents) ?? ZERO;\n}\n\n/** Rounded once to cents, half away from zero. */\nfunction toCents(value: ScaledDecimal): ScaledDecimal {\n return rescaleDecimal(value, 2) ?? ZERO;\n}\n\nconst centsText = (value: ScaledDecimal): DecimalString =>\n formatDecimal(value, 2);\n\n/** The ticks and values the table starts from, for `dirty`. */\nexport interface BillLineDefaults {\n values: BillLineValues;\n selection: readonly string[];\n}\n\n/**\n * Totals and counts (see `BillLineSummary`). Net is the ticked lines'\n * `PrezzoTotale` summed exactly and rounded once to cents; VAT is, per rate,\n * the rate's net rounded to cents first (FatturaPA 2.2.2.5\n * `ImponibileImporto` has two places), times the rate, rounded to cents,\n * then added, the `DatiRiepilogo` shape; gross\n * is net plus VAT (D7, design section 4.1). A quantity edit changes none of\n * them.\n */\nexport function summariseBillLines(\n lines: readonly BillLine[],\n values: BillLineValues,\n selection: readonly string[],\n defaults: BillLineDefaults,\n isItemKnown: BillLineItemLookup = KNOWS_EVERY_ITEM,\n): BillLineSummary {\n const invoiceLoaded = isBillInvoiceLoaded(lines);\n const ticked = new Set(resolveBillLineSelection(lines, selection));\n let selectedCount = 0;\n let matchedCount = 0;\n let newItemCount = 0;\n let itemUpdateCount = 0;\n let skippedCount = 0;\n let alreadyLoadedCount = 0;\n let warningLineCount = 0;\n let invalidCount = 0;\n const amounts: ScaledDecimal[] = [];\n const byRate = new Map<\n string,\n { rate: ScaledDecimal; amounts: ScaledDecimal[] }\n >();\n\n for (const line of lines) {\n const value = values[line.id] ?? getDefaultBillLineValue(line);\n if (\n line.warnings.length > 0 ||\n !isBillLineQuantityEditable(line.quantity)\n ) {\n warningLineCount += 1;\n }\n if (line.alreadyLoaded) {\n alreadyLoadedCount += 1;\n continue;\n }\n if (!ticked.has(line.id)) {\n skippedCount += 1;\n continue;\n }\n selectedCount += 1;\n if (value.item.kind === 'existing') {\n matchedCount += 1;\n if (isBillLineItemToUpdate(line, value)) itemUpdateCount += 1;\n } else newItemCount += 1;\n if (isBillLineInvalid(line, value, itemKnownFor(value, isItemKnown))) {\n invalidCount += 1;\n }\n const amount = readBillLineAmount(line.lineTotal);\n if (!amount) continue;\n amounts.push(amount);\n const rate = readBillLineRate(line.vatPercent);\n if (rate) {\n const key = formatDecimal(trimDecimal(rate));\n const group = byRate.get(key);\n if (group) group.amounts.push(amount);\n else byRate.set(key, { rate, amounts: [amount] });\n }\n }\n\n const net = toCents(sumExact(amounts));\n const vatByRate: ScaledDecimal[] = [];\n for (const group of byRate.values()) {\n // rate / 100: the same digits, two places further right.\n const ratio: ScaledDecimal = {\n units: group.rate.units,\n scale: group.rate.scale + 2,\n };\n // The taxable amount in cents first, as `ImponibileImporto` carries\n // it, then the tax on that figure (2.2.2.6 `Imposta`).\n const taxable = toCents(sumExact(group.amounts));\n vatByRate.push(multiplyDecimal(taxable, ratio, 2) ?? ZERO);\n }\n const vat = sumDecimals(vatByRate) ?? ZERO;\n const gross = sumDecimals([net, vat]) ?? ZERO;\n\n const defaultTicks = resolveBillLineSelection(lines, defaults.selection);\n const dirty =\n defaultTicks.length !== ticked.size ||\n defaultTicks.some((id) => !ticked.has(id)) ||\n lines.some(\n (line) =>\n !sameBillLineValue(\n values[line.id] ?? getDefaultBillLineValue(line),\n defaults.values[line.id] ?? getDefaultBillLineValue(line),\n ),\n );\n\n return {\n lineCount: lines.length,\n selectedCount,\n matchedCount,\n newItemCount,\n itemUpdateCount,\n skippedCount,\n alreadyLoadedCount,\n warningLineCount,\n invoiceLoaded,\n invalidCount,\n net: centsText(net),\n vat: centsText(toCents(vat)),\n gross: centsText(toCents(gross)),\n canConfirm: selectedCount > 0 && invalidCount === 0,\n dirty,\n };\n}\n\n/* ================================================================== */\n/* Load payload */\n/* ================================================================== */\n\n/** The quantity as the request sends it: the value's own digits, unsigned. */\nfunction loadQuantityText(text: DecimalString): DecimalString {\n const value = readBillLineQuantity(text).value;\n return value ? formatDecimal(value) : text.trim();\n}\n\n/**\n * The HTP-7311 request body, or the ticked lines that block it. The only\n * place the credit-note sign is applied (D6): a credit note's quantities go\n * out negative. A loaded invoice gives no payload (D8).\n */\nexport function getBillLineLoadPayload(\n lines: readonly BillLine[],\n values: BillLineValues,\n selection: readonly string[],\n documentKind: BillDocumentKind,\n isItemKnown: BillLineItemLookup = KNOWS_EVERY_ITEM,\n): BillLineLoadResult {\n if (isBillInvoiceLoaded(lines)) return { ok: false, invalidLineIds: [] };\n const ticked = new Set(resolveBillLineSelection(lines, selection));\n const entries: BillLineLoadEntry[] = [];\n const invalidLineIds: string[] = [];\n for (const line of lines) {\n if (!ticked.has(line.id)) continue;\n const value = values[line.id] ?? getDefaultBillLineValue(line);\n if (\n value.quantity === null ||\n isBillLineInvalid(line, value, itemKnownFor(value, isItemKnown))\n ) {\n invalidLineIds.push(line.id);\n continue;\n }\n const magnitude = loadQuantityText(value.quantity);\n const entry: BillLineLoadEntry = {\n lineId: line.id,\n quantity: documentKind === 'creditNote' ? `-${magnitude}` : magnitude,\n item: normaliseBillLineItemChoice(value.item, line),\n };\n if (isBillLineItemToUpdate(line, value)) entry.updateItem = true;\n entries.push(entry);\n }\n if (invalidLineIds.length > 0) return { ok: false, invalidLineIds };\n return { ok: true, lines: entries };\n}\n\n/* ================================================================== */\n/* Row view model (D13) */\n/* ================================================================== */\n\nexport interface BillLineRowContext {\n /** `isBillInvoiceLoaded(lines)`. */\n invoiceLoaded: boolean;\n /** Ticked ids in effect (`resolveBillLineSelection`). */\n ticked: ReadonlySet<string>;\n /** The item behind an id, when the table knows it. */\n findItem: (itemId: string) => BillLineItemOption | undefined;\n}\n\n/** One line's view model. */\nexport function buildBillLineRow(\n line: BillLine,\n value: BillLineValue,\n context: BillLineRowContext,\n): BillLineRow {\n const selected = context.ticked.has(line.id);\n const item =\n value.item.kind === 'existing'\n ? (context.findItem(value.item.itemId) ?? null)\n : null;\n const itemKnown = value.item.kind !== 'existing' || item !== null;\n return {\n line,\n value,\n selected,\n matchState: getBillLineMatchState(line, value, selected),\n invalid: selected && isBillLineInvalid(line, value, itemKnown),\n readOnly: context.invoiceLoaded,\n quantityLocked: !isBillLineQuantityEditable(line.quantity),\n item,\n itemKnown,\n };\n}\n\nfunction sameOption(\n a: BillLineItemOption | null,\n b: BillLineItemOption | null,\n): boolean {\n if (a === b) return true;\n if (a === null || b === null) return false;\n return a.id === b.id && a.name === b.name && a.code === b.code;\n}\n\nfunction sameRow(a: BillLineRow, b: BillLineRow): boolean {\n return (\n a.line === b.line &&\n a.value.quantity === b.value.quantity &&\n sameItemChoice(a.value.item, b.value.item) &&\n a.selected === b.selected &&\n a.matchState === b.matchState &&\n a.invalid === b.invalid &&\n a.readOnly === b.readOnly &&\n a.quantityLocked === b.quantityLocked &&\n a.itemKnown === b.itemKnown &&\n sameOption(a.item, b.item)\n );\n}\n\nexport interface BillLineRowsInput {\n lines: readonly BillLine[];\n values: BillLineValues;\n selection: readonly string[];\n findItem: (itemId: string) => BillLineItemOption | undefined;\n /** The rows of the last build, by line id: an unchanged line keeps its\n * object, so DataGrid re-renders only the lines that changed. */\n previous?: ReadonlyMap<string, BillLineRow>;\n}\n\n/** Every line's view model, in invoice order, with structural sharing. */\nexport function buildBillLineRows(input: BillLineRowsInput): BillLineRow[] {\n const context: BillLineRowContext = {\n invoiceLoaded: isBillInvoiceLoaded(input.lines),\n ticked: new Set(resolveBillLineSelection(input.lines, input.selection)),\n findItem: input.findItem,\n };\n return input.lines.map((line) => {\n const next = buildBillLineRow(\n line,\n input.values[line.id] ?? getDefaultBillLineValue(line),\n context,\n );\n const before = input.previous?.get(line.id);\n return before && sameRow(before, next) ? before : next;\n });\n}\n\n/** The privacy-safe facts the handle and the agent read. */\nexport function toBillLineInfo(\n row: BillLineRow,\n options: { tableReadOnly: boolean; documentKind: BillDocumentKind },\n): BillLineInfo {\n const codes = row.line.warnings.map((warning) => warning.code);\n if (row.quantityLocked) codes.push(BILL_LINE_QUANTITY_TOO_LARGE);\n const blocked = row.readOnly || row.line.alreadyLoaded;\n return {\n id: row.line.id,\n lineNumber: row.line.lineNumber,\n matchState: row.matchState,\n selected: row.selected,\n selectable: !blocked && !options.tableReadOnly,\n readOnly: blocked || options.tableReadOnly,\n quantityLocked: row.quantityLocked,\n itemKind: row.value.item.kind,\n itemId: row.value.item.kind === 'existing' ? row.value.item.itemId : null,\n quantity: row.value.quantity,\n removesStock: options.documentKind === 'creditNote',\n warningCodes: codes,\n invalid: row.invalid,\n };\n}\n\n/* ================================================================== */\n/* Handle input checks */\n/* ================================================================== */\n\n/** A quantity a handle or agent write may set: unsigned, above 0, at most 8\n * fraction digits and at most `BILL_LINE_MAX_QUANTITY`. Returns the\n * normalised text (`\"02.50\"` is `\"2.5\"`), or `null` to refuse it. */\nexport function normaliseBillLineQuantityInput(\n text: string,\n): DecimalString | null {\n const parsed = parseDecimal(text, FATTURAPA_VALUE.quantity);\n if (!parsed.ok || parsed.value.units <= 0) return null;\n if (compareDecimal(parsed.value, MAX_QUANTITY) > 0) return null;\n return formatDecimal(trimDecimal(parsed.value));\n}\n","/* -------------------------------------------------------------------- */\n/* BillLineTable: the DataGrid columns (design-bill-line-table.md */\n/* section 3) and the cells, editors and footers they render. */\n/* */\n/* The columns depend only on what rarely changes (language, document */\n/* kind, currency, privacy mode, stable setters), so DataGrid keeps them */\n/* and re-renders only the line that changed (D13). What changes while a */\n/* person works (the totals, the offered items, the search state) reaches */\n/* the cells through two contexts. */\n/* */\n/* Only `line.id` reaches the DOM as data: descriptions, item names and */\n/* warning messages are text, never attributes. Editors are named by */\n/* reference to DataGrid's column header and hidden row-name span. */\n/* -------------------------------------------------------------------- */\n\nimport {\n createContext,\n useContext,\n useLayoutEffect,\n useMemo,\n useRef,\n type ReactNode,\n} from 'react';\nimport type { TFunction } from 'i18next';\nimport {\n ArrowRight,\n Check,\n CircleAlert,\n Plus,\n TriangleAlert,\n} from 'lucide-react';\n\nimport { Badge } from '../badge';\nimport {\n Combobox,\n type ComboboxAction,\n type ComboboxOption,\n} from '../combobox';\nimport type {\n DataGridColumn,\n DataGridEditContext,\n DataGridNumberEdit,\n} from '../data-grid';\nimport { Money } from '../money';\nimport { VisuallyHidden } from '../visually-hidden';\nimport {\n decimalToNumber,\n shiftDecimal,\n type DecimalString,\n} from '../_shared/decimal';\nimport { formatNumber } from '../_shared/format-number';\nimport {\n WAREHOUSE_LINE_STATE_COPY,\n WAREHOUSE_LINE_STATE_VARIANT,\n} from '../_shared/warehouse-load';\nimport {\n BILL_LINE_MAX_QUANTITY,\n BILL_LINE_NEW_ITEM_VALUE,\n BILL_LINE_PERCENT_FRACTION_DIGITS,\n BILL_LINE_PRICE_FRACTION_DIGITS,\n BILL_LINE_QUANTITY_FRACTION_DIGITS,\n BILL_LINE_QUANTITY_TOO_LARGE,\n billLineQuantityFromNumber,\n isBillLineNewItemNameMissing,\n isBillLineNewItemNamedFromDescription,\n isBillLineItemUpdateChange,\n isBillLineQuantityTooLarge,\n netUnitCost,\n readBillLineAmount,\n readBillLineQuantity,\n readBillLineRate,\n sameBillLineMagnitude,\n} from './bill-line-table.model';\nimport type {\n BillDocumentKind,\n BillLineItemChoice,\n BillLineItemOption,\n BillLineMatchState,\n BillLineRow,\n BillLineSummary,\n BillLineWarning,\n} from './bill-line-table.types';\nimport {\n adjustmentItemVariants,\n cellListVariants,\n figureVariants,\n itemEditorVariants,\n secondaryTextVariants,\n stackVariants,\n totalsListVariants,\n totalsTermVariants,\n totalsValueVariants,\n updateArrowVariants,\n updateItemVariants,\n warningIconVariants,\n warningItemVariants,\n warningTextVariants,\n} from './bill-line-table.variants';\n\n/* ================================================================== */\n/* Contexts */\n/* ================================================================== */\n\n/** What the item editors read that changes while a person works. */\nexport interface BillLineItemSearch {\n /** `items` as Combobox options, mapped once per change of `items`. */\n itemOptions: ComboboxOption[];\n /** Ids in `itemOptions`. */\n itemOptionIds: ReadonlySet<string>;\n /** `onItemQueryChange` is set: the host filters, the Combobox does not. */\n serverSearch: boolean;\n itemsLoading: boolean;\n /** The line whose item field typed last: only its list shows loading. */\n searchingLineId: string | null;\n}\n\nconst NO_ITEM_SEARCH: BillLineItemSearch = {\n itemOptions: [],\n itemOptionIds: new Set<string>(),\n serverSearch: false,\n itemsLoading: false,\n searchingLineId: null,\n};\n\nexport const BillLineItemSearchContext =\n createContext<BillLineItemSearch>(NO_ITEM_SEARCH);\n\n/** The rendered summary, for the totals row. */\nexport const BillLineSummaryContext = createContext<BillLineSummary | null>(\n null,\n);\n\n/* ================================================================== */\n/* Inputs of the builder */\n/* ================================================================== */\n\nexport interface BillLineColumnDeps {\n t: TFunction<'ui'>;\n /** The UI language (`i18n.language`), for `formatNumber`. */\n language: string;\n documentKind: BillDocumentKind;\n currency: string;\n privacyMode: boolean;\n /** A person edited a quantity; `null` while the field is empty. */\n setQuantity: (lineId: string, quantity: DecimalString | null) => void;\n /** A person chose an item, or \"Create new item\". */\n setItem: (lineId: string, choice: BillLineItemChoice) => void;\n /** A person typed in a line's item field (server search only). */\n queryItems: (lineId: string, query: string) => void;\n /** Id prefix of the Status cell: `{prefix}-{lineId}`. */\n statusIdPrefix: string;\n}\n\n/* ================================================================== */\n/* Cell helpers */\n/* ================================================================== */\n\n/** D12: matched success, new item info, item to update warning, skip\n * neutral, already loaded neutral with a check. Tones come from the shared\n * warehouse-load vocabulary. */\nconst MATCH_BADGE: Record<\n BillLineMatchState,\n { variant: 'success' | 'info' | 'warning' | 'neutral'; check: boolean }\n> = {\n matched: { variant: WAREHOUSE_LINE_STATE_VARIANT.matched, check: false },\n newItem: { variant: WAREHOUSE_LINE_STATE_VARIANT.newItem, check: false },\n itemToUpdate: {\n variant: WAREHOUSE_LINE_STATE_VARIANT.itemToUpdate,\n check: false,\n },\n skip: { variant: WAREHOUSE_LINE_STATE_VARIANT.skip, check: false },\n alreadyLoaded: {\n variant: WAREHOUSE_LINE_STATE_VARIANT.alreadyLoaded,\n check: true,\n },\n};\n\nfunction matchLabel(state: BillLineMatchState, t: TFunction<'ui'>): string {\n const copy = WAREHOUSE_LINE_STATE_COPY[state];\n return t(copy.key, copy.en);\n}\n\n/** A rate as a percentage in the UI language, through the kit's\n * `formatNumber` (06-i18n), so Albanian and Arabic digits match Money.\n * Display only: a 2-place rate survives the float step exactly. */\nfunction percentText(text: DecimalString, language: string): string {\n const rate = readBillLineRate(text);\n const number = rate ? decimalToNumber(rate) : null;\n if (number === null) return text.trim();\n return formatNumber(shiftDecimal(number, -2), language, {\n style: 'percent',\n minimumFractionDigits: 0,\n maximumFractionDigits: BILL_LINE_PERCENT_FRACTION_DIGITS,\n });\n}\n\n/** Money for a decimal string: integer units at the string's own scale, so\n * no digit is lost. Beyond a safe integer (the platform also flags the line\n * `valueOutOfRange`) the exact text shows instead of a rounded amount. */\nfunction DecimalMoney({\n value,\n currency,\n fractionDigits = BILL_LINE_PRICE_FRACTION_DIGITS,\n tone = 'default',\n}: {\n value: DecimalString;\n currency: string;\n /** Most fraction digits shown; 2 for the totals. */\n fractionDigits?: number;\n tone?: 'default' | 'muted';\n}) {\n const amount = readBillLineAmount(value);\n if (!amount) {\n return (\n <span dir=\"ltr\" className={figureVariants()}>\n {value.trim()}\n </span>\n );\n }\n return (\n <Money\n size=\"sm\"\n tone={tone}\n value={amount.units}\n scale={amount.scale}\n currency={currency}\n minimumFractionDigits={Math.min(2, fractionDigits)}\n maximumFractionDigits={fractionDigits}\n />\n );\n}\n\nfunction quantityCell(row: BillLineRow, language: string): ReactNode {\n const text = row.value.quantity;\n if (text === null) return null;\n const reading = readBillLineQuantity(text);\n const number = reading.value ? decimalToNumber(reading.value) : null;\n return (\n <span className={figureVariants()}>\n {number === null ? (\n // More digits than a double holds: every digit, as sent.\n <span dir=\"ltr\">{text.trim()}</span>\n ) : (\n formatNumber(number, language, {\n maximumFractionDigits: BILL_LINE_QUANTITY_FRACTION_DIGITS,\n })\n )}\n {row.line.unitOfMeasure ? (\n <>\n {' '}\n <span dir=\"auto\">{row.line.unitOfMeasure}</span>\n </>\n ) : null}\n </span>\n );\n}\n\nfunction quantityError(\n row: BillLineRow,\n deps: BillLineColumnDeps,\n): string | undefined {\n const { t } = deps;\n // Only ticked lines are judged: an unticked line loads nothing.\n if (!row.selected) return undefined;\n const reading = readBillLineQuantity(row.value.quantity);\n if (reading.empty) {\n return t('billLineTable.quantity.errorRequired', 'Enter a quantity');\n }\n // Zero, malformed, or negative from the platform (quantities are\n // unsigned): a visible error, never a silent block.\n if (!reading.wellFormed || !reading.positive) {\n return t(\n 'billLineTable.quantity.errorNotPositive',\n 'Enter a quantity above 0',\n );\n }\n // D15: the field takes any number while a person types; above the limit\n // the line is invalid and says so here, never silently clamped.\n if (isBillLineQuantityTooLarge(row.line, row.value)) {\n return t('billLineTable.quantity.errorTooLarge', {\n max: formatNumber(BILL_LINE_MAX_QUANTITY, deps.language),\n defaultValue: 'Enter a quantity of {{max}} or less',\n });\n }\n // A host 'error' warning (a refused load) is linked to the field that\n // `focusLine(id, 'quantity')` moves to, so the error is heard there too.\n // BillLineWarning.message never quotes the description.\n const failure = row.line.warnings.find(\n (warning) => warning.severity === 'error',\n );\n return failure?.message;\n}\n\nfunction itemError(row: BillLineRow, t: TFunction<'ui'>): string | undefined {\n // Unknown in both modes: not in `items`, `selectedItems`, nor any item\n // given before (with server search the host keeps `selectedItems`\n // current, so this still means \"deleted\").\n if (!row.itemKnown) {\n return t(\n 'billLineTable.item.errorUnknown',\n 'This item is no longer in the warehouse. Choose another.',\n );\n }\n if (row.selected && isBillLineNewItemNameMissing(row.value)) {\n return t(\n 'billLineTable.item.errorNameRequired',\n 'Enter a name for the new item',\n );\n }\n return undefined;\n}\n\nfunction unitPriceCell(row: BillLineRow, deps: BillLineColumnDeps): ReactNode {\n // D14: the net unit cost the stock movement receives (PrezzoTotale /\n // quantity), shown only when its size differs from PrezzoUnitario (line\n // adjustments, or an edited quantity under D7).\n const net = netUnitCost(row.line.lineTotal, row.value.quantity);\n const shownNet =\n net !== null && !sameBillLineMagnitude(net, row.line.unitPrice)\n ? net\n : null;\n return (\n <span className={stackVariants({ align: 'end' })}>\n <DecimalMoney value={row.line.unitPrice} currency={deps.currency} />\n {shownNet !== null ? (\n <span className={secondaryTextVariants()}>\n {deps.t('billLineTable.unitPrice.netLabel', 'Net per unit')}{' '}\n <DecimalMoney\n value={shownNet}\n currency={deps.currency}\n tone=\"muted\"\n />\n </span>\n ) : null}\n </span>\n );\n}\n\nfunction adjustmentCell(row: BillLineRow, deps: BillLineColumnDeps): ReactNode {\n if (row.line.adjustments.length === 0) return null;\n return (\n <ul className={cellListVariants({ align: 'end' })}>\n {row.line.adjustments.map((adjustment, index) => (\n // Index key: the blocks have no identity and never reorder.\n <li key={index} className={adjustmentItemVariants()}>\n {/* Labelled on screen too: a discount is negative, a surcharge\n positive, and the word says which. */}\n <span className={secondaryTextVariants()}>\n {adjustment.type === 'discount'\n ? deps.t('billLineTable.adjustment.discount', 'Discount')\n : deps.t('billLineTable.adjustment.surcharge', 'Surcharge')}\n </span>\n <span className={figureVariants()}>\n <span aria-hidden=\"true\">\n {adjustment.type === 'discount' ? '−' : '+'}\n </span>\n {adjustment.percent !== null ? (\n percentText(adjustment.percent, deps.language)\n ) : adjustment.amount !== null ? (\n <DecimalMoney\n value={adjustment.amount}\n currency={deps.currency}\n />\n ) : null}\n </span>\n </li>\n ))}\n </ul>\n );\n}\n\n/** A change side as plain text: an amount, a percentage, or \"none\" for\n * `null`. Used for the spoken sentence, where one template orders the\n * words per language. */\nfunction updateValueText(\n kind: 'price' | 'vat' | 'discount',\n value: DecimalString | null,\n deps: BillLineColumnDeps,\n): string {\n if (value === null) {\n return deps.t('billLineTable.update.none', 'none');\n }\n if (kind !== 'price') return percentText(value, deps.language);\n const amount = readBillLineAmount(value);\n if (!amount) return value.trim();\n return formatNumber(amount.units / 10 ** amount.scale, deps.language, {\n style: 'currency',\n currency: deps.currency,\n minimumFractionDigits: Math.min(2, BILL_LINE_PRICE_FRACTION_DIGITS),\n maximumFractionDigits: BILL_LINE_PRICE_FRACTION_DIGITS,\n });\n}\n\n/** A decimal as a euro amount, a percentage, or \"none\" for `null`. */\nfunction updateValue(\n kind: 'price' | 'vat' | 'discount',\n value: DecimalString | null,\n deps: BillLineColumnDeps,\n): ReactNode {\n if (value === null) {\n return deps.t('billLineTable.update.none', 'none');\n }\n return kind === 'price' ? (\n <DecimalMoney value={value} currency={deps.currency} />\n ) : (\n percentText(value, deps.language)\n );\n}\n\n/** The item changes under the Status badge: \"Price €8.50 → €9.00\". The\n * visible line is hidden from assistive technology; a reader hears one\n * translated sentence, \"Price: from €8.50 to €9.00\". */\nfunction itemUpdateCell(row: BillLineRow, deps: BillLineColumnDeps): ReactNode {\n if (row.matchState !== 'itemToUpdate' || !row.line.itemUpdate) return null;\n const update = row.line.itemUpdate;\n const entries = [\n {\n key: 'price' as const,\n label: deps.t('billLineTable.update.price', 'Price'),\n change: update.unitPrice,\n },\n {\n key: 'vat' as const,\n label: deps.t('billLineTable.update.vat', 'VAT'),\n change: update.vatRate,\n },\n {\n key: 'discount' as const,\n label: deps.t('billLineTable.update.discount', 'Discount'),\n change: update.discountPercent,\n },\n ].filter((entry) => isBillLineItemUpdateChange(entry.change));\n if (entries.length === 0) return null;\n return (\n <ul\n className={cellListVariants({ align: 'start' })}\n aria-label={deps.t('billLineTable.update.label', 'Changes to the item')}\n >\n {entries.map(({ key, label, change }) =>\n change ? (\n <li key={key} className={updateItemVariants()}>\n <span aria-hidden=\"true\">\n {label} {updateValue(key, change.from, deps)}{' '}\n <ArrowRight className={updateArrowVariants()} />{' '}\n {updateValue(key, change.to, deps)}\n </span>\n <VisuallyHidden>\n {deps.t('billLineTable.update.change', {\n label,\n from: updateValueText(key, change.from, deps),\n to: updateValueText(key, change.to, deps),\n defaultValue: '{{label}}: from {{from}} to {{to}}',\n })}\n </VisuallyHidden>\n </li>\n ) : null,\n )}\n </ul>\n );\n}\n\nfunction vatCell(row: BillLineRow, deps: BillLineColumnDeps): ReactNode {\n if (row.line.vatPercent === null) {\n return (\n <>\n <span aria-hidden=\"true\">{'–'}</span>\n <VisuallyHidden>\n {deps.t('billLineTable.vat.none', 'No VAT rate')}\n </VisuallyHidden>\n </>\n );\n }\n // 0 is a real rate (HTP-6221): \"0%\", and \"0% (N4)\" with its Natura.\n const rate = percentText(row.line.vatPercent, deps.language);\n if (!row.line.vatNature) return rate;\n return deps.t('billLineTable.vat.withNature', {\n rate,\n nature: row.line.vatNature,\n defaultValue: '{{rate}} ({{nature}})',\n });\n}\n\n/** \"New item: {{name}}\"; \"New item\" under privacy mode, where the name\n * (by default the description) may name a patient. */\nfunction newItemLabel(name: string, deps: BillLineColumnDeps): string {\n return deps.privacyMode\n ? deps.t('billLineTable.item.newOptionMasked', 'New item')\n : deps.t('billLineTable.item.newOption', {\n name,\n defaultValue: 'New item: {{name}}',\n });\n}\n\n/** The Combobox keeps the shown label in the field, so a person who edits\n * a \"New item: Bibs\" line's text types after that label. The label's own\n * words are not part of the name: drop them, then trim. */\nfunction stripNewItemPrefix(query: string, deps: BillLineColumnDeps): string {\n // \"New item:\" ends in punctuation, so a real name rarely starts with it;\n // the masked \"New item\" is only shown, so only stripped, in privacy mode.\n const prefixes = [newItemLabel('', { ...deps, privacyMode: false }).trim()];\n if (deps.privacyMode) {\n prefixes.push(deps.t('billLineTable.item.newOptionMasked', 'New item'));\n }\n for (const prefix of prefixes) {\n if (prefix !== '' && query.startsWith(prefix)) {\n return query.slice(prefix.length).trim();\n }\n }\n return query.trim();\n}\n\nfunction itemText(row: BillLineRow, deps: BillLineColumnDeps): string {\n const choice = row.value.item;\n if (choice.kind === 'new') return newItemLabel(choice.name, deps);\n return row.item?.name ?? '';\n}\n\nfunction toItemOption(item: BillLineItemOption): ComboboxOption {\n return {\n value: item.id,\n label: item.name,\n description: item.code ?? undefined,\n // Item names are text a practice wrote.\n dir: 'auto',\n };\n}\n\n/** Server search: the host's results are already filtered. */\nconst acceptEveryOption = (): number => 1;\n\nfunction warningsCell(row: BillLineRow, deps: BillLineColumnDeps): ReactNode {\n // The kit's own notes after the host's warnings. Warnings, not errors.\n const warnings: BillLineWarning[] = [...row.line.warnings];\n // A quantity the editor cannot hold exactly: the line still loads as\n // invoiced (D15).\n if (row.quantityLocked) {\n warnings.push({\n code: BILL_LINE_QUANTITY_TOO_LARGE,\n message: deps.t(\n 'billLineTable.quantity.tooLarge',\n 'This quantity is too large to edit here. It loads as on the invoice.',\n ),\n severity: 'warning',\n });\n }\n // Q3 / R13: privacy mode hides a new item's name, and by default that\n // name is the description, which can name a patient. A created item is\n // masked nowhere, so the reviewer checks it with privacy mode off.\n if (\n deps.privacyMode &&\n row.selected &&\n isBillLineNewItemNamedFromDescription(row.line, row.value)\n ) {\n warnings.push({\n code: 'newItemNameHidden',\n message: deps.t(\n 'billLineTable.item.checkNameHidden',\n 'The new item takes the line description as its name. Turn off privacy mode to check it before you load.',\n ),\n severity: 'warning',\n });\n }\n if (warnings.length === 0) return null;\n return (\n <ul className={cellListVariants()}>\n {warnings.map((warning, index) => (\n // Index key: warnings have no identity of their own.\n <li key={index} className={warningItemVariants()}>\n {warning.severity === 'error' ? (\n <CircleAlert\n aria-hidden=\"true\"\n className={warningIconVariants({ severity: 'error' })}\n />\n ) : (\n <TriangleAlert\n aria-hidden=\"true\"\n className={warningIconVariants({ severity: 'warning' })}\n />\n )}\n <span className={warningTextVariants()}>\n <VisuallyHidden>\n {warning.severity === 'error'\n ? deps.t('billLineTable.warnings.error', 'Error:')\n : deps.t('billLineTable.warnings.warning', 'Warning:')}\n </VisuallyHidden>\n <span dir=\"auto\">{warning.message}</span>\n </span>\n </li>\n ))}\n </ul>\n );\n}\n\n/* ================================================================== */\n/* The item editor */\n/* ================================================================== */\n\nfunction ItemEditor({\n row,\n context,\n deps,\n}: {\n row: BillLineRow;\n context: DataGridEditContext;\n deps: BillLineColumnDeps;\n}) {\n const search = useContext(BillLineItemSearchContext);\n const { t, setItem, queryItems } = deps;\n const { line, value, item } = row;\n const newName = value.item.kind === 'new' ? value.item.name : null;\n\n // The Combobox moves its text to a new label only while its list is\n // closed. A privacy change while this field has focus (its list may be\n // open) therefore remounts the Combobox, so the field shows the masked\n // label at once and no unmasked name reaches `onItemQueryChange` on the\n // next keystroke. Focus comes back to the new field, after cmdk's own\n // mount work (cmdk moves focus to any input it mounts while another cmdk\n // input has focus). Fields without focus keep their Combobox: it takes\n // the new label as soon as the change commits.\n const wrapperRef = useRef<HTMLDivElement>(null);\n const shownPrivacy = useRef(deps.privacyMode);\n const remountKey = useRef(0);\n const refocus = useRef(false);\n if (shownPrivacy.current !== deps.privacyMode) {\n shownPrivacy.current = deps.privacyMode;\n const wrapper = wrapperRef.current;\n if (\n wrapper !== null &&\n wrapper.contains(wrapper.ownerDocument.activeElement)\n ) {\n remountKey.current += 1;\n refocus.current = true;\n }\n }\n useLayoutEffect(() => {\n if (!refocus.current) return;\n refocus.current = false;\n const focusField = () =>\n wrapperRef.current\n ?.querySelector<HTMLInputElement>('input[role=\"combobox\"]')\n ?.focus();\n focusField();\n queueMicrotask(focusField);\n }, [deps.privacyMode]);\n\n const options = useMemo<ComboboxOption[]>(() => {\n if (newName !== null) {\n // The per-line \"New item: …\" option, so the field shows the choice.\n return [\n {\n value: BILL_LINE_NEW_ITEM_VALUE,\n label: newItemLabel(newName, deps),\n description: t(\n 'billLineTable.item.newOptionDescription',\n 'Created when you load the invoice',\n ),\n },\n ...search.itemOptions,\n ];\n }\n // With server search `items` holds another query's results: the chosen\n // item stays listed, so the field keeps its name (D18).\n if (item && !search.itemOptionIds.has(item.id)) {\n return [toItemOption(item), ...search.itemOptions];\n }\n return search.itemOptions;\n }, [newName, item, search.itemOptions, search.itemOptionIds, deps, t]);\n\n const action = useMemo<ComboboxAction>(\n () => ({\n label: t('billLineTable.item.createNew', 'Create new item'),\n icon: <Plus />,\n // Marks the line only; nothing is created before Confirm (D5). The\n // typed text names the item; with none, the description does.\n onSelect: (query) =>\n setItem(line.id, {\n kind: 'new',\n name: stripNewItemPrefix(query, deps),\n }),\n }),\n [t, setItem, line.id, deps],\n );\n\n return (\n <div ref={wrapperRef} className={itemEditorVariants()}>\n <Combobox\n key={remountKey.current}\n // Kit fix (c): named by reference, so the row name stays text.\n aria-labelledby={context.labelledBy}\n aria-invalid={context.invalid || undefined}\n aria-describedby={\n [context.errorId, `${deps.statusIdPrefix}-${line.id}`]\n .filter(Boolean)\n .join(' ') || undefined\n }\n options={options}\n value={\n value.item.kind === 'existing'\n ? value.item.itemId\n : BILL_LINE_NEW_ITEM_VALUE\n }\n onValueChange={(next) => {\n // Choosing an item never ticks the line (D4).\n if (next === '' || next === BILL_LINE_NEW_ITEM_VALUE) return;\n setItem(line.id, { kind: 'existing', itemId: next });\n }}\n placeholder={t('billLineTable.item.placeholder', 'Choose an item')}\n // Tabbing down forty lines opens no list.\n openOnFocus={false}\n popoverSize=\"md\"\n wrapOptionLabels\n action={action}\n onQueryChange={\n search.serverSearch\n ? (query) => queryItems(line.id, query)\n : undefined\n }\n filter={search.serverSearch ? acceptEveryOption : undefined}\n // A boolean from the start with server search, so the list's\n // status is in place before it changes (kit fix b).\n loading={\n search.serverSearch\n ? search.searchingLineId === line.id && search.itemsLoading\n : undefined\n }\n />\n </div>\n );\n}\n\n/* ================================================================== */\n/* Footers (the sticky totals row) */\n/* ================================================================== */\n\nfunction TickedFooter({ deps }: { deps: BillLineColumnDeps }) {\n const summary = useContext(BillLineSummaryContext);\n if (!summary) return null;\n // \"line\" agrees with the loadable total, so `count` is the total; the\n // figures shown go through formatNumber (06-i18n).\n const total = summary.lineCount - summary.alreadyLoadedCount;\n return (\n <span className={stackVariants()}>\n <span>\n {deps.t('billLineTable.footer.ticked', {\n count: total,\n selected: formatNumber(summary.selectedCount, deps.language),\n total: formatNumber(total, deps.language),\n defaultValue: '{{selected}} of {{total}} lines ticked',\n defaultValue_one: '{{selected}} of {{total}} line ticked',\n defaultValue_other: '{{selected}} of {{total}} lines ticked',\n })}\n </span>\n {summary.itemUpdateCount > 0 ? (\n <span className={secondaryTextVariants()}>\n {deps.t('billLineTable.footer.itemsToUpdate', {\n count: summary.itemUpdateCount,\n countText: formatNumber(summary.itemUpdateCount, deps.language),\n defaultValue: '{{countText}} items to update',\n defaultValue_one: '{{countText}} item to update',\n defaultValue_other: '{{countText}} items to update',\n })}\n </span>\n ) : null}\n {summary.newItemCount > 0 ? (\n <span className={secondaryTextVariants()}>\n {deps.t('billLineTable.footer.newItems', {\n count: summary.newItemCount,\n countText: formatNumber(summary.newItemCount, deps.language),\n defaultValue: '{{countText}} new items',\n defaultValue_one: '{{countText}} new item',\n defaultValue_other: '{{countText}} new items',\n })}\n </span>\n ) : null}\n </span>\n );\n}\n\nfunction VatFooter({ currency }: { currency: string }) {\n const summary = useContext(BillLineSummaryContext);\n if (!summary) return null;\n return (\n <DecimalMoney value={summary.vat} currency={currency} fractionDigits={2} />\n );\n}\n\nfunction AmountFooter({ deps }: { deps: BillLineColumnDeps }) {\n const summary = useContext(BillLineSummaryContext);\n if (!summary) return null;\n return (\n <dl className={totalsListVariants()}>\n <dt className={totalsTermVariants()}>\n {deps.t('billLineTable.footer.net', 'Net')}\n </dt>\n <dd className={totalsValueVariants()}>\n <DecimalMoney\n value={summary.net}\n currency={deps.currency}\n fractionDigits={2}\n />\n </dd>\n <dt className={totalsTermVariants()}>\n {deps.t('billLineTable.footer.gross', 'Total with VAT')}\n </dt>\n <dd className={totalsValueVariants()}>\n <DecimalMoney\n value={summary.gross}\n currency={deps.currency}\n fractionDigits={2}\n />\n </dd>\n </dl>\n );\n}\n\nfunction WarningsFooter({ deps }: { deps: BillLineColumnDeps }) {\n const summary = useContext(BillLineSummaryContext);\n if (!summary || summary.warningLineCount === 0) return null;\n return (\n <span>\n {deps.t('billLineTable.footer.warningLines', {\n count: summary.warningLineCount,\n countText: formatNumber(summary.warningLineCount, deps.language),\n defaultValue: '{{countText}} lines with warnings',\n defaultValue_one: '{{countText}} line with warnings',\n defaultValue_other: '{{countText}} lines with warnings',\n })}\n </span>\n );\n}\n\n/* ================================================================== */\n/* Columns */\n/* ================================================================== */\n\n/**\n * The columns. The working columns come first after the pinned description\n * (quantity, item, status, warnings), then Amount, whose footer holds the\n * totals: 1,092 px with the 52 px checkbox, inside the 1,152 px an `xl`\n * Dialog gives its body. The figures to check against the paper invoice\n * follow; all of it is 1,636 px, and a narrower box scrolls them sideways\n * while the description stays pinned. Every column is wide enough for the\n * longest word of its header in each of the 18 languages, with a margin\n * for the few pixels by which text is wider on other systems, since\n * headers wrap between words and are not hyphenated (story \"Header words\n * stay whole\"). Widths are DataGrid `size` numbers (the column API, not CSS);\n * the table is in fixed layout. No sorting, filtering, hiding or moving\n * (D10), and no responsive tiers: a column hidden at 200% zoom would have\n * no way back, so the table scrolls sideways instead (WCAG 1.4.10).\n */\nexport function buildBillLineColumns(\n deps: BillLineColumnDeps,\n): DataGridColumn<BillLineRow>[] {\n const { t } = deps;\n\n const quantityEdit: DataGridNumberEdit<BillLineRow> = {\n kind: 'number',\n mode: 'decimal',\n // The float lives only inside NumberInput: every change goes back to\n // exact text at once, within BILL_LINE_MAX_QUANTITY. Unsigned in the\n // field and in the value: the document carries the sign (D6).\n // A typed value above the limit stays in the field with its error\n // (`quantityError`); an invoiced one is locked by `isEditable`.\n getValue: (row) => {\n const exact = readBillLineQuantity(row.value.quantity).value;\n return exact ? decimalToNumber(exact) : null;\n },\n onChange: (row, next) =>\n deps.setQuantity(\n row.line.id,\n next === null ? null : billLineQuantityFromNumber(next),\n ),\n // A quantity the editor cannot hold exactly stays text, never clamped.\n isEditable: (row) => !row.readOnly && !row.quantityLocked,\n min: 0,\n max: BILL_LINE_MAX_QUANTITY,\n step: 1,\n maximumFractionDigits: BILL_LINE_QUANTITY_FRACTION_DIGITS,\n // DG-1: FatturaPA UnitaMisura per line, as the supplier wrote it.\n unit: (row) => row.line.unitOfMeasure ?? undefined,\n error: (row) => quantityError(row, deps),\n // WCAG 3.3.2: the field says how many decimals it takes, since a digit\n // past the limit is refused as it is typed. Kit copy and a constant\n // only, so it shows in privacy mode too (`hostTextPrivacySafe`).\n description: () =>\n t(\n 'billLineTable.quantity.precision',\n 'Up to {{formatted}} decimal places',\n {\n count: BILL_LINE_QUANTITY_FRACTION_DIGITS,\n formatted: formatNumber(\n BILL_LINE_QUANTITY_FRACTION_DIGITS,\n deps.language,\n ),\n },\n ),\n };\n\n return [\n {\n id: 'description',\n header: t('billLineTable.column.description', 'Description'),\n rowHeader: true,\n pin: 'start',\n wrap: true,\n // Lab invoices can name a patient here (D9).\n privacy: 'mask',\n cell: (row) => <span dir=\"auto\">{row.line.description}</span>,\n value: (row) => row.line.description,\n // No sorting in any mode (D10); privacy mode would turn it off anyway.\n sort: false,\n size: 200,\n minSize: 192,\n hideable: false,\n reorderable: false,\n // The totals row's header cell.\n footer: () => <TickedFooter deps={deps} />,\n },\n {\n id: 'quantity',\n header:\n deps.documentKind === 'creditNote'\n ? t('billLineTable.column.quantityCreditNote', 'Quantity to remove')\n : t('billLineTable.column.quantity', 'Quantity'),\n align: 'end',\n // Read-only lines (a loaded invoice, the table while loading, or a\n // locked quantity): the unsigned value as text, plus the unit.\n cell: (row) => quantityCell(row, deps.language),\n exportValue: (row) => row.value.quantity,\n edit: quantityEdit,\n size: 128,\n hideable: false,\n reorderable: false,\n },\n {\n id: 'item',\n header: t('billLineTable.column.item', 'Warehouse item'),\n cell: (row) => <span dir=\"auto\">{itemText(row, deps)}</span>,\n exportValue: (row) => itemText(row, deps) || null,\n edit: {\n kind: 'custom',\n render: (row, context) => (\n <ItemEditor row={row} context={context} deps={deps} />\n ),\n error: (row) => itemError(row, t),\n },\n size: 240,\n minSize: 192,\n hideable: false,\n reorderable: false,\n },\n {\n id: 'match',\n header: t('billLineTable.column.match', 'Status'),\n cell: (row) => {\n const badge = MATCH_BADGE[row.matchState];\n return (\n <span\n id={`${deps.statusIdPrefix}-${row.line.id}`}\n className={stackVariants()}\n >\n <Badge\n size=\"sm\"\n variant={badge.variant}\n leading={badge.check ? <Check /> : undefined}\n >\n {matchLabel(row.matchState, t)}\n </Badge>\n {itemUpdateCell(row, deps)}\n </span>\n );\n },\n exportValue: (row) => matchLabel(row.matchState, t),\n wrap: true,\n size: 176,\n hideable: false,\n reorderable: false,\n },\n {\n id: 'warnings',\n header: t('billLineTable.column.warnings', 'Warnings'),\n wrap: true,\n // Not masked: a warning must not quote the description\n // (BillLineWarning.message), so errors stay readable (D9).\n cell: (row) => warningsCell(row, deps),\n exportValue: (row) =>\n row.line.warnings.map((warning) => warning.message).join('; ') || null,\n size: 168,\n hideable: false,\n reorderable: false,\n footer: () => <WarningsFooter deps={deps} />,\n },\n {\n id: 'lineTotal',\n header: t('billLineTable.column.lineTotal', 'Amount'),\n align: 'end',\n cell: (row) => (\n <DecimalMoney value={row.line.lineTotal} currency={deps.currency} />\n ),\n exportValue: (row) => row.line.lineTotal,\n size: 128,\n hideable: false,\n reorderable: false,\n // From the summary (exact decimals, ticked lines), not from the\n // footer context's rows.\n footer: () => <AmountFooter deps={deps} />,\n },\n {\n id: 'unitPrice',\n header: t('billLineTable.column.unitPrice', 'Unit price'),\n align: 'end',\n cell: (row) => unitPriceCell(row, deps),\n exportValue: (row) => row.line.unitPrice,\n // 112 px of text: \"EENHEIDSPRIJS\" (nl) is the longest word.\n size: 144,\n hideable: false,\n reorderable: false,\n },\n {\n id: 'vat',\n header: t('billLineTable.column.vat', 'VAT'),\n align: 'end',\n cell: (row) => vatCell(row, deps),\n exportValue: (row) => row.line.vatPercent,\n size: 88,\n hideable: false,\n reorderable: false,\n // VAT of the ticked lines, under the VAT header.\n footer: () => <VatFooter currency={deps.currency} />,\n },\n {\n id: 'adjustment',\n header: t('billLineTable.column.adjustment', 'Discount or surcharge'),\n align: 'end',\n cell: (row) => adjustmentCell(row, deps),\n exportValue: (row) =>\n row.line.adjustments\n .map(\n (adjustment) =>\n `${adjustment.type === 'discount' ? '-' : '+'}${\n adjustment.percent !== null\n ? `${adjustment.percent}%`\n : (adjustment.amount ?? '')\n }`,\n )\n .join(', ') || null,\n // 112 px of text: \"MAGGIORAZIONE\" (it) is the longest word.\n size: 144,\n hideable: false,\n reorderable: false,\n },\n {\n id: 'supplierCode',\n header: t('billLineTable.column.supplierCode', 'Supplier code'),\n cell: (row) =>\n row.line.supplierCode === null ? null : (\n <span dir=\"ltr\" className={figureVariants()}>\n {row.line.supplierCode}\n </span>\n ),\n exportValue: (row) => row.line.supplierCode,\n // 136 px of text: \"LEVERANCIERSCODE\" (nl) is the longest word.\n size: 168,\n hideable: false,\n reorderable: false,\n },\n ];\n}\n\n/** `items` as Combobox options (mapped once per change of `items`). */\nexport function toItemOptions(\n items: readonly BillLineItemOption[],\n): ComboboxOption[] {\n return items.map(toItemOption);\n}\n","/* -------------------------------------------------------------------- */\n/* BillLineTable: invoice lines mapped to warehouse items, reviewed in */\n/* the HTP-7311 \"Load into warehouse\" Dialog before the host's Confirm. */\n/* */\n/* Built on the kit DataGrid (no second table implementation): a native */\n/* table with a tri-state row checkbox, an always-on quantity NumberInput */\n/* (decimals, per-line unit) and an item Combobox with \"Create new item\", */\n/* read-only rows once the invoice is loaded, a sticky header and a */\n/* sticky totals row. Values and selection are controlled or */\n/* uncontrolled; the curated handle and `billLineTableAgent` expose ids, */\n/* codes and exact decimal text only: no DataGrid handle, no TanStack */\n/* object, no row object, no DOM node. */\n/* */\n/* Dialog recipe: `<Dialog.Content size=\"xl\" scroll=\"body\">`, */\n/* `<Dialog.Body className=\"ds:flex ds:flex-col\">`, `<BillLineTable */\n/* height=\"fill\" />`, Confirm and Cancel in `<Dialog.Footer>`. The root */\n/* is a flex column so the fill reaches the grid; the header and totals */\n/* then stay in view inside the Dialog's height cap. */\n/* -------------------------------------------------------------------- */\n\nimport {\n forwardRef,\n useCallback,\n useEffect,\n useImperativeHandle,\n useId,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport { useTranslation } from 'react-i18next';\n\nimport { useAgentRegistration } from '../../agent';\nimport {\n DataGrid,\n type DataGridHandle,\n type DataGridRowSelectability,\n} from '../data-grid';\nimport type { DecimalString } from '../_shared/decimal';\nimport { formatNumber } from '../_shared/format-number';\nimport { isDevelopment } from '../_shared/is-development';\nimport { billLineTableAgent } from './bill-line-table.agent';\nimport { BillLineInvoiceHeaderBlock } from './bill-line-table.header';\nimport {\n BillLineItemSearchContext,\n BillLineSummaryContext,\n buildBillLineColumns,\n toItemOptions,\n type BillLineItemSearch,\n} from './bill-line-table.columns';\nimport {\n BILL_LINE_MAX_QUANTITY,\n BILL_LINE_NEW_ITEM_VALUE,\n BILL_LINE_QUANTITY_FRACTION_DIGITS,\n buildBillLineRow,\n buildBillLineRows,\n getBillLineLoadPayload,\n getDefaultBillLineSelection,\n getDefaultBillLineValue,\n isBillInvoiceLoaded,\n isBillLineQuantityEditable,\n normaliseBillLineItemChoice,\n normaliseBillLineQuantityInput,\n resolveBillLineSelection,\n resolveBillLineValues,\n sameBillLineValue,\n summariseBillLines,\n toBillLineInfo,\n type BillLineDefaults,\n} from './bill-line-table.model';\nimport type {\n BillLine,\n BillLineChangeSource,\n BillLineErrorCode,\n BillLineInfo,\n BillLineItemChoice,\n BillLineItemOption,\n BillLineRow,\n BillLineSummary,\n BillLineTableChange,\n BillLineTableHandle,\n BillLineTableProps,\n BillLineValue,\n BillLineValueChange,\n BillLineValues,\n} from './bill-line-table.types';\nimport { billLineTableVariants } from './bill-line-table.variants';\n\nexport type {\n BillLineTableHandle,\n BillLineTableProps,\n} from './bill-line-table.types';\n\n/* ------------------------------------------------------------------ */\n/* Helpers */\n/* ------------------------------------------------------------------ */\n\nconst EMPTY_VALUES: BillLineValues = {};\n\n/** A refused handle write: the message starts with the code (D17). Ids\n * only, never line text. */\nfunction billLineError(code: BillLineErrorCode, detail: string): Error {\n return new Error(`${code}: ${detail}`);\n}\n\nfunction sameIds(a: readonly string[], b: readonly string[]): boolean {\n return a.length === b.length && a.every((id, index) => id === b[index]);\n}\n\n/** Stable text of a summary: its fields are numbers, booleans and decimal\n * text, so the host hears only a real change. */\nfunction summaryKey(summary: BillLineSummary): string {\n return JSON.stringify(summary);\n}\n\n/* ------------------------------------------------------------------ */\n/* Component */\n/* ------------------------------------------------------------------ */\n\nexport const BillLineTable = forwardRef<\n BillLineTableHandle,\n BillLineTableProps\n>(function BillLineTable(\n {\n lines,\n items,\n selectedItems,\n documentKind = 'invoice',\n currency = 'EUR',\n gridId,\n caption,\n invoice,\n values: valuesProp,\n defaultValues,\n onValuesChange,\n selection: selectionProp,\n defaultSelection,\n onSelectionChange,\n onSummaryChange,\n onItemQueryChange,\n itemsLoading = false,\n status = 'ready',\n error,\n readOnly = false,\n privacyMode = false,\n height = 'fill',\n className,\n ...rest\n },\n ref,\n) {\n const { t, i18n } = useTranslation('ui');\n const language = i18n.language;\n const gridRef = useRef<DataGridHandle>(null);\n const tableReadOnly = readOnly !== false;\n\n /* ---------------- items (D18) ---------------- */\n\n // Every item the table has been given, so a line keeps its item's name\n // while `items` holds another line's search results.\n const rememberedItems = useRef(new Map<string, BillLineItemOption>());\n const itemIndex = useMemo<ReadonlyMap<string, BillLineItemOption>>(() => {\n const known = rememberedItems.current;\n for (const item of selectedItems ?? []) known.set(item.id, item);\n for (const item of items) known.set(item.id, item);\n return new Map(known);\n }, [items, selectedItems]);\n\n useEffect(() => {\n if (\n isDevelopment() &&\n items.some((item) => item.id === BILL_LINE_NEW_ITEM_VALUE)\n ) {\n console.warn(\n `[BillLineTable] an item id equals \"${BILL_LINE_NEW_ITEM_VALUE}\", the value of the new-item option, so that item cannot be chosen.`,\n );\n }\n }, [items]);\n\n const itemOptions = useMemo(() => toItemOptions(items), [items]);\n const itemOptionIds = useMemo(\n () => new Set(items.map((item) => item.id)),\n [items],\n );\n const [searchingLineId, setSearchingLineId] = useState<string | null>(null);\n const serverSearch = onItemQueryChange !== undefined;\n const itemSearch = useMemo<BillLineItemSearch>(\n () => ({\n itemOptions,\n itemOptionIds,\n serverSearch,\n itemsLoading,\n searchingLineId,\n }),\n [itemOptions, itemOptionIds, serverSearch, itemsLoading, searchingLineId],\n );\n\n /* ---------------- values and selection ---------------- */\n\n // A slice is the component's own only while its prop is undefined;\n // otherwise every write goes to `on…Change` and the prop wins.\n const valuesControlled = valuesProp !== undefined;\n const [ownValues, setOwnValues] = useState<BillLineValues>(\n () => defaultValues ?? EMPTY_VALUES,\n );\n const shownValues = valuesProp ?? ownValues;\n\n const selectionControlled = selectionProp !== undefined;\n const [ownSelection, setOwnSelection] = useState<readonly string[]>(\n () => defaultSelection ?? getDefaultBillLineSelection(lines),\n );\n // Uncontrolled with no `defaultSelection`: a line that arrives after\n // mount (the host loaded the lines while the skeleton showed) takes its\n // own default tick. Lines already shown keep the person's choice.\n const [seenLines, setSeenLines] = useState(lines);\n if (seenLines !== lines) {\n setSeenLines(lines);\n if (!selectionControlled && defaultSelection === undefined) {\n const before = new Set(seenLines.map((line) => line.id));\n const added = getDefaultBillLineSelection(lines).filter(\n (id) => !before.has(id) && !ownSelection.includes(id),\n );\n // A value, not an updater: idempotent if React renders twice.\n if (added.length > 0) setOwnSelection([...ownSelection, ...added]);\n }\n }\n const shownSelection = selectionProp ?? ownSelection;\n\n // Reads after a write are fresh, controlled slices included, and two\n // writes in one tick compose. Every render then puts back what is shown,\n // so a write the host refused (it ignored `on…Change`) is gone at the\n // next render and the handle reads what the person sees (as DataGrid's\n // `syncFromProps` does).\n const liveValues = useRef(shownValues);\n liveValues.current = shownValues;\n const liveSelection = useRef(shownSelection);\n liveSelection.current = shownSelection;\n const writtenValues = useRef<BillLineValues | null>(null);\n const writtenSelection = useRef<readonly string[] | null>(null);\n\n const defaults = useMemo<BillLineDefaults>(\n () => ({\n values: defaultValues ?? EMPTY_VALUES,\n selection: defaultSelection ?? getDefaultBillLineSelection(lines),\n }),\n [defaultValues, defaultSelection, lines],\n );\n\n /* ---------------- rows (D13) and summary ---------------- */\n\n const previousRows = useRef<ReadonlyMap<string, BillLineRow>>(new Map());\n const rows = useMemo(() => {\n const next = buildBillLineRows({\n lines,\n values: shownValues,\n selection: shownSelection,\n findItem: (itemId) => itemIndex.get(itemId),\n previous: previousRows.current,\n });\n previousRows.current = new Map(next.map((row) => [row.line.id, row]));\n return next;\n }, [lines, shownValues, shownSelection, itemIndex]);\n\n const gridSelection = useMemo(\n () => rows.filter((row) => row.selected).map((row) => row.line.id),\n [rows],\n );\n\n const isItemKnown = useCallback(\n (itemId: string) => itemIndex.has(itemId),\n [itemIndex],\n );\n const summary = useMemo(\n () =>\n summariseBillLines(\n lines,\n shownValues,\n shownSelection,\n defaults,\n isItemKnown,\n ),\n [lines, shownValues, shownSelection, defaults, isItemKnown],\n );\n\n /* ---------------- latest state for the handle ---------------- */\n\n const lineById = useMemo(\n () => new Map(lines.map((line) => [line.id, line])),\n [lines],\n );\n const latest = useRef({\n lines,\n lineById,\n itemIndex,\n defaults,\n documentKind,\n tableReadOnly,\n valuesControlled,\n selectionControlled,\n });\n latest.current = {\n lines,\n lineById,\n itemIndex,\n defaults,\n documentKind,\n tableReadOnly,\n valuesControlled,\n selectionControlled,\n };\n const callbacks = useRef({\n onValuesChange,\n onSelectionChange,\n onSummaryChange,\n onItemQueryChange,\n });\n callbacks.current = {\n onValuesChange,\n onSelectionChange,\n onSummaryChange,\n onItemQueryChange,\n };\n\n const listeners = useRef(new Set<(change: BillLineTableChange) => void>());\n const emit = useCallback((change: BillLineTableChange) => {\n for (const listener of [...listeners.current]) listener(change);\n }, []);\n\n /* ---------------- writes ---------------- */\n\n const writeValue = useCallback(\n (\n lineId: string,\n field: BillLineValueChange['field'],\n patch: Partial<BillLineValue>,\n source: BillLineChangeSource,\n ) => {\n const state = latest.current;\n if (!state.lineById.has(lineId)) return;\n const current = resolveBillLineValues(state.lines, liveValues.current);\n const before = current[lineId];\n const after: BillLineValue = { ...before, ...patch };\n if (sameBillLineValue(before, after)) return;\n const next: Record<string, BillLineValue> = {\n ...current,\n [lineId]: after,\n };\n liveValues.current = next;\n writtenValues.current = next;\n if (!state.valuesControlled) setOwnValues(next);\n callbacks.current.onValuesChange?.(next, { lineId, field, source });\n emit({ event: 'values', source });\n },\n [emit],\n );\n\n const writeSelection = useCallback(\n (ids: readonly string[], source: BillLineChangeSource) => {\n const state = latest.current;\n const next = resolveBillLineSelection(state.lines, ids);\n const current = resolveBillLineSelection(\n state.lines,\n liveSelection.current,\n );\n if (sameIds(next, current)) return;\n liveSelection.current = next;\n writtenSelection.current = next;\n if (!state.selectionControlled) setOwnSelection(next);\n callbacks.current.onSelectionChange?.(next);\n emit({ event: 'selection', source });\n },\n [emit],\n );\n\n const setQuantityFromUser = useCallback(\n (lineId: string, quantity: DecimalString | null) =>\n writeValue(lineId, 'quantity', { quantity }, 'user'),\n [writeValue],\n );\n const setItemFromUser = useCallback(\n (lineId: string, choice: BillLineItemChoice) => {\n const line = latest.current.lineById.get(lineId);\n if (!line) return;\n writeValue(\n lineId,\n 'item',\n { item: normaliseBillLineItemChoice(choice, line) },\n 'user',\n );\n },\n [writeValue],\n );\n const queryItems = useCallback((lineId: string, query: string) => {\n setSearchingLineId(lineId);\n callbacks.current.onItemQueryChange?.(lineId, query);\n }, []);\n const onGridSelectionChange = useCallback(\n (ids: string[]) => writeSelection(ids, 'user'),\n [writeSelection],\n );\n\n /* ---------------- events for the host ---------------- */\n\n const lastSummary = useRef<string | null>(null);\n useEffect(() => {\n // Once on mount, then after each change that changes the summary.\n const key = summaryKey(summary);\n if (key === lastSummary.current) return;\n lastSummary.current = key;\n callbacks.current.onSummaryChange?.(summary);\n }, [summary]);\n\n const statusKey = `${status}:${tableReadOnly ? 'readOnly' : 'editable'}`;\n const seenByFeed = useRef({\n lines,\n values: shownValues,\n selection: shownSelection,\n status: statusKey,\n });\n useEffect(() => {\n // Prop changes the table did not write itself reach subscribers with\n // source 'host'.\n const seen = seenByFeed.current;\n if (\n seen.lines !== lines ||\n (seen.values !== shownValues && shownValues !== writtenValues.current)\n ) {\n emit({ event: 'values', source: 'host' });\n }\n if (\n seen.selection !== shownSelection &&\n shownSelection !== writtenSelection.current\n ) {\n emit({ event: 'selection', source: 'host' });\n }\n if (seen.status !== statusKey) emit({ event: 'status', source: 'host' });\n seenByFeed.current = {\n lines,\n values: shownValues,\n selection: shownSelection,\n status: statusKey,\n };\n }, [lines, shownValues, shownSelection, statusKey, emit]);\n\n /* ---------------- curated handle ---------------- */\n\n const handle = useMemo<BillLineTableHandle>(() => {\n const rowsNow = (): BillLineRow[] => {\n const state = latest.current;\n return buildBillLineRows({\n lines: state.lines,\n values: liveValues.current,\n selection: liveSelection.current,\n findItem: (itemId) => state.itemIndex.get(itemId),\n });\n };\n const infoOf = (row: BillLineRow): BillLineInfo =>\n toBillLineInfo(row, {\n tableReadOnly: latest.current.tableReadOnly,\n documentKind: latest.current.documentKind,\n });\n const knows = (itemId: string) => latest.current.itemIndex.has(itemId);\n const requireLine = (lineId: string): BillLine => {\n const line = latest.current.lineById.get(lineId);\n if (!line) throw billLineError('UNKNOWN_LINE', `no line \"${lineId}\".`);\n return line;\n };\n const refuseWhileReadOnly = () => {\n if (latest.current.tableReadOnly) {\n throw billLineError(\n 'TABLE_READ_ONLY',\n 'the table is read-only while the load request runs.',\n );\n }\n };\n const refuseLoadedInvoice = (lineId: string) => {\n if (isBillInvoiceLoaded(latest.current.lines)) {\n throw billLineError(\n 'LINE_READ_ONLY',\n `line \"${lineId}\" belongs to an invoice that is already loaded.`,\n );\n }\n };\n\n return {\n getLineIds: () => latest.current.lines.map((line) => line.id),\n getLine: (id) => {\n const state = latest.current;\n const line = state.lineById.get(id);\n if (!line) return null;\n const row = buildBillLineRow(\n line,\n liveValues.current[id] ?? getDefaultBillLineValue(line),\n {\n invoiceLoaded: isBillInvoiceLoaded(state.lines),\n ticked: new Set(\n resolveBillLineSelection(state.lines, liveSelection.current),\n ),\n findItem: (itemId) => state.itemIndex.get(itemId),\n },\n );\n return infoOf(row);\n },\n getLines: () => rowsNow().map(infoOf),\n getSelection: () =>\n resolveBillLineSelection(latest.current.lines, liveSelection.current),\n getValues: () =>\n resolveBillLineValues(latest.current.lines, liveValues.current),\n getSummary: () => {\n const state = latest.current;\n return summariseBillLines(\n state.lines,\n liveValues.current,\n liveSelection.current,\n state.defaults,\n knows,\n );\n },\n getInvalidLineIds: () =>\n rowsNow()\n .filter((row) => row.invalid)\n .map((row) => row.line.id),\n getLoadPayload: () => {\n const state = latest.current;\n return getBillLineLoadPayload(\n state.lines,\n liveValues.current,\n liveSelection.current,\n state.documentKind,\n knows,\n );\n },\n\n setSelection: (ids) => {\n for (const id of ids) requireLine(id);\n refuseWhileReadOnly();\n for (const id of ids) {\n if (requireLine(id).alreadyLoaded) {\n throw billLineError(\n 'LINE_READ_ONLY',\n `line \"${id}\" is already loaded.`,\n );\n }\n refuseLoadedInvoice(id);\n }\n writeSelection(ids, 'api');\n },\n selectAll: () => {\n refuseWhileReadOnly();\n // Lines that cannot load drop out (a loaded invoice ticks none).\n writeSelection(\n latest.current.lines.map((line) => line.id),\n 'api',\n );\n },\n clearSelection: () => {\n refuseWhileReadOnly();\n writeSelection([], 'api');\n },\n setQuantity: (lineId, quantity) => {\n const line = requireLine(lineId);\n const normalised = normaliseBillLineQuantityInput(quantity);\n if (normalised === null) {\n throw billLineError(\n 'INVALID_QUANTITY',\n `\"${quantity}\" is not a quantity above 0 and at most ${BILL_LINE_MAX_QUANTITY}, with at most ${BILL_LINE_QUANTITY_FRACTION_DIGITS} decimal places.`,\n );\n }\n refuseWhileReadOnly();\n refuseLoadedInvoice(lineId);\n if (!isBillLineQuantityEditable(line.quantity)) {\n throw billLineError(\n 'LINE_READ_ONLY',\n `line \"${lineId}\" has a quantity too large to edit; it loads as invoiced.`,\n );\n }\n writeValue(lineId, 'quantity', { quantity: normalised }, 'api');\n },\n setItem: (lineId, choice) => {\n const line = requireLine(lineId);\n if (\n choice.kind === 'existing' &&\n (choice.itemId === BILL_LINE_NEW_ITEM_VALUE || !knows(choice.itemId))\n ) {\n throw billLineError('UNKNOWN_ITEM', `no item \"${choice.itemId}\".`);\n }\n refuseWhileReadOnly();\n refuseLoadedInvoice(lineId);\n writeValue(\n lineId,\n 'item',\n { item: normaliseBillLineItemChoice(choice, line) },\n 'api',\n );\n },\n\n focusLine: (lineId, field = 'select') => {\n requireLine(lineId);\n gridRef.current?.focusRow(\n lineId,\n field === 'select' ? undefined : field,\n );\n },\n scrollToLine: (lineId) => {\n requireLine(lineId);\n gridRef.current?.scrollToRow(lineId);\n },\n\n subscribe: (listener) => {\n listeners.current.add(listener);\n return () => {\n listeners.current.delete(listener);\n };\n },\n };\n }, [writeSelection, writeValue]);\n\n useImperativeHandle(ref, () => handle, [handle]);\n // One table, one agent surface: the inner DataGrid registers nothing\n // (`registerAgent={false}`, no `gridId`) and saves no column state.\n useAgentRegistration(billLineTableAgent, handle, gridId);\n\n /* ---------------- DataGrid wiring ---------------- */\n\n // The Status cell's id, built from ids only, so the item field can be\n // described by it.\n const statusIdPrefix = `${useId()}-status`;\n const columns = useMemo(\n () =>\n buildBillLineColumns({\n t,\n language,\n documentKind,\n currency,\n privacyMode,\n setQuantity: setQuantityFromUser,\n setItem: setItemFromUser,\n queryItems,\n statusIdPrefix,\n }),\n [\n t,\n language,\n documentKind,\n currency,\n privacyMode,\n setQuantityFromUser,\n setItemFromUser,\n queryItems,\n statusIdPrefix,\n ],\n );\n\n const getRowId = useCallback((row: BillLineRow) => row.line.id, []);\n const isRowReadOnly = useCallback((row: BillLineRow) => row.readOnly, []);\n // \"Line 4\" from NumeroLinea names the row (\"Select Line 4\"), in every\n // mode: a description can name a patient and must never be an attribute.\n const getRowLabel = useCallback(\n (row: BillLineRow) =>\n t('billLineTable.rowLabel', {\n number: formatNumber(row.line.lineNumber, language),\n defaultValue: 'Line {{number}}',\n }),\n [t, language],\n );\n const getRowSelectability = useCallback(\n (row: BillLineRow): DataGridRowSelectability => {\n if (row.line.alreadyLoaded) {\n return {\n state: 'none',\n reason: t(\n 'billLineTable.selection.alreadyLoadedReason',\n 'Already loaded into the warehouse',\n ),\n };\n }\n // D8: one loaded line locks the whole invoice.\n if (row.readOnly) {\n return {\n state: 'none',\n reason: t(\n 'billLineTable.selection.invoiceLoadedReason',\n 'This invoice was already loaded. Lines left out then cannot be loaded later.',\n ),\n };\n }\n return 'selectable';\n },\n [t],\n );\n\n // DG-2. While the host's request runs: editors as text, every box\n // disabled with the reason, ticks kept. A loaded invoice (D8) is frozen\n // the same way, so its select-all box is disabled with the reason too\n // (its rows have no box, and their editors are already text). The grid\n // shows this reason as written (`hostTextPrivacySafe`), so under privacy\n // mode the host's own reason, free text that could name a person, gives\n // way to the kit's.\n const invoiceLoaded = summary.invoiceLoaded;\n const frozenReason = tableReadOnly\n ? typeof readOnly === 'object' && readOnly.reason !== '' && !privacyMode\n ? readOnly.reason\n : t(\n 'billLineTable.selection.readOnlyReason',\n 'Loading into the warehouse',\n )\n : invoiceLoaded\n ? t(\n 'billLineTable.selection.invoiceLoadedReason',\n 'This invoice was already loaded. Lines left out then cannot be loaded later.',\n )\n : null;\n const gridReadOnly = useMemo<boolean | { reason: string }>(\n () => (frozenReason === null ? false : { reason: frozenReason }),\n [frozenReason],\n );\n\n const gridError = useMemo(\n () => ({\n title:\n error?.title ??\n t('billLineTable.error.title', 'The invoice lines could not be read'),\n description:\n error?.description ??\n t(\n 'billLineTable.error.description',\n 'Try again. If it keeps failing, open the invoice to check it.',\n ),\n onRetry: error?.onRetry,\n }),\n [error, t],\n );\n const gridEmpty = useMemo(\n () => ({\n title: t(\n 'billLineTable.empty.title',\n 'This invoice has no lines to load',\n ),\n description: t(\n 'billLineTable.empty.description',\n 'Open the invoice to check what the supplier sent.',\n ),\n }),\n [t],\n );\n\n const gridCaption =\n caption ??\n (documentKind === 'creditNote'\n ? t('billLineTable.captionCreditNote', 'Credit note lines')\n : t('billLineTable.caption', 'Invoice lines'));\n\n return (\n <div\n {...rest}\n data-component=\"bill-line-table\"\n data-component-id={gridId}\n className={billLineTableVariants({ height, className })}\n >\n {invoice ? (\n <BillLineInvoiceHeaderBlock\n invoice={invoice}\n privacyMode={privacyMode}\n />\n ) : null}\n <BillLineItemSearchContext.Provider value={itemSearch}>\n <BillLineSummaryContext.Provider value={summary}>\n <DataGrid<BillLineRow>\n ref={gridRef}\n caption={gridCaption}\n columns={columns}\n rows={rows}\n getRowId={getRowId}\n registerAgent={false}\n persistColumnState={false}\n dataMode=\"client\"\n selectionMode=\"multiple\"\n rowSelection={gridSelection}\n onRowSelectionChange={onGridSelectionChange}\n getRowSelectability={getRowSelectability}\n selectAllScope=\"all\"\n rangeSelection\n isRowReadOnly={isRowReadOnly}\n readOnly={gridReadOnly}\n getRowLabel={getRowLabel}\n rowLabelPrivacySafe\n // Errors, the quantity hint and selection reasons are kit copy\n // with line numbers, or `BillLineWarning.message`, which must\n // never quote the description: they stay readable in privacy\n // mode, so a refused load is heard as written.\n hostTextPrivacySafe\n multiSort={false}\n columnResizing={false}\n // Every column stays: a hidden fiscal figure would have no way\n // back at 200% zoom. The table scrolls sideways instead.\n responsiveColumns={false}\n status={status}\n error={gridError}\n empty={gridEmpty}\n density=\"default\"\n height={height}\n virtualization=\"auto\"\n privacyMode={privacyMode}\n />\n </BillLineSummaryContext.Provider>\n </BillLineItemSearchContext.Provider>\n </div>\n );\n});\n\nBillLineTable.displayName = 'BillLineTable';\n"],"names":["refuse","code","detail","QUANTITY_PATTERN","LINE_ID","LINE_INFO_TYPE","billLineTableAgent","handle","args","id","current","mode","next","name","_a","billLineTableVariants","cva","itemEditorVariants","EDITOR_COMPACT_FIELDS_CLASS","stackVariants","secondaryTextVariants","cellListVariants","figureVariants","warningItemVariants","warningIconVariants","warningTextVariants","totalsListVariants","totalsTermVariants","totalsValueVariants","adjustmentItemVariants","updateArrowVariants","updateItemVariants","headerVariants","headerTermVariants","headerValueVariants","dayFormatters","CALENDAR_DAY","formatDay","day","language","match","instant","locale","formatLocale","formatter","BillLineInvoiceHeaderBlock","invoice","privacyMode","t","i18n","useTranslation","masked","jsxs","jsx","Fragment","EyeOff","VisuallyHidden","Badge","BILL_LINE_QUANTITY_FRACTION_DIGITS","BILL_LINE_PRICE_FRACTION_DIGITS","BILL_LINE_PERCENT_FRACTION_DIGITS","BILL_LINE_MAX_QUANTITY","BILL_LINE_ITEM_NAME_MAX_LENGTH","BILL_LINE_NEW_ITEM_VALUE","BILL_LINE_QUANTITY_TOO_LARGE","ZERO","MAX_QUANTITY","QUANTITY_READ","FATTURAPA_VALUE","trimDecimal","value","units","scale","absDecimal","readBillLineQuantity","text","blank","parsed","parseDecimal","number","decimalToNumber","isBillLineQuantityEditable","quantity","reading","billLineQuantityFromNumber","scaled","numberToDecimal","formatDecimal","readBillLineAmount","readBillLineRate","netUnitCost","lineTotal","total","count","cost","divideDecimal","sameBillLineMagnitude","a","b","x","y","compareDecimal","normaliseBillLineItemName","trimmed","characters","normaliseBillLineItemChoice","choice","line","exceedsBillLineMaxQuantity","isBillLineQuantityTooLarge","sameQuantity","isBillLineNewItemNameMissing","isBillLineNewItemNamedFromDescription","isBillInvoiceLoaded","lines","getDefaultBillLineValue","getDefaultBillLineValues","values","getDefaultBillLineSelection","resolveBillLineValues","resolved","isSelectableLine","invoiceLoaded","resolveBillLineSelection","selection","ticked","sameItemChoice","sameBillLineValue","getBillLineMatchState","selected","isBillLineItemToUpdate","isBillLineItemUpdateChange","change","hasBillLineItemUpdate","update","isBillLineInvalid","itemKnown","warning","KNOWS_EVERY_ITEM","itemKnownFor","isItemKnown","sumExact","exact","sumDecimals","cents","rounded","rescaleDecimal","toCents","centsText","summariseBillLines","defaults","selectedCount","matchedCount","newItemCount","itemUpdateCount","skippedCount","alreadyLoadedCount","warningLineCount","invalidCount","amounts","byRate","amount","rate","key","group","net","vatByRate","ratio","taxable","multiplyDecimal","vat","gross","defaultTicks","dirty","loadQuantityText","getBillLineLoadPayload","documentKind","entries","invalidLineIds","magnitude","entry","buildBillLineRow","context","item","sameOption","sameRow","buildBillLineRows","input","before","toBillLineInfo","row","options","codes","blocked","normaliseBillLineQuantityInput","NO_ITEM_SEARCH","BillLineItemSearchContext","createContext","BillLineSummaryContext","MATCH_BADGE","WAREHOUSE_LINE_STATE_VARIANT","matchLabel","state","copy","WAREHOUSE_LINE_STATE_COPY","percentText","formatNumber","shiftDecimal","DecimalMoney","currency","fractionDigits","tone","Money","quantityCell","quantityError","deps","failure","itemError","unitPriceCell","shownNet","adjustmentCell","adjustment","index","updateValueText","kind","updateValue","itemUpdateCell","label","ArrowRight","vatCell","newItemLabel","stripNewItemPrefix","query","prefixes","prefix","itemText","toItemOption","acceptEveryOption","warningsCell","warnings","CircleAlert","TriangleAlert","ItemEditor","search","useContext","setItem","queryItems","newName","wrapperRef","useRef","shownPrivacy","remountKey","refocus","wrapper","useLayoutEffect","focusField","_b","useMemo","action","Plus","Combobox","TickedFooter","summary","VatFooter","AmountFooter","WarningsFooter","buildBillLineColumns","quantityEdit","badge","Check","toItemOptions","items","EMPTY_VALUES","billLineError","sameIds","summaryKey","BillLineTable","forwardRef","selectedItems","gridId","caption","valuesProp","defaultValues","onValuesChange","selectionProp","defaultSelection","onSelectionChange","onSummaryChange","onItemQueryChange","itemsLoading","status","error","readOnly","height","className","rest","ref","gridRef","tableReadOnly","rememberedItems","itemIndex","known","useEffect","isDevelopment","itemOptions","itemOptionIds","searchingLineId","setSearchingLineId","useState","serverSearch","itemSearch","valuesControlled","ownValues","setOwnValues","shownValues","selectionControlled","ownSelection","setOwnSelection","seenLines","setSeenLines","added","shownSelection","liveValues","liveSelection","writtenValues","writtenSelection","previousRows","rows","itemId","gridSelection","useCallback","lineById","latest","callbacks","listeners","emit","listener","writeValue","lineId","field","patch","source","after","writeSelection","ids","setQuantityFromUser","setItemFromUser","onGridSelectionChange","lastSummary","statusKey","seenByFeed","seen","rowsNow","infoOf","knows","requireLine","refuseWhileReadOnly","refuseLoadedInvoice","normalised","useImperativeHandle","useAgentRegistration","statusIdPrefix","useId","columns","getRowId","isRowReadOnly","getRowLabel","getRowSelectability","frozenReason","gridReadOnly","gridError","gridEmpty","gridCaption","DataGrid"],"mappings":"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"}
@@ -5160,10 +5160,14 @@ const Tl = [
5160
5160
  // The eyebrow, as DataTable's header. CJK has no capitals to track.
5161
5161
  "ds:[font-size:var(--data-grid-eyebrow-size,var(--font-size-xs))] ds:[font-weight:var(--font-weight-bold)] ds:uppercase ds:tracking-[0.04em] ds:text-[color:var(--data-grid-eyebrow-ink,var(--muted-foreground))]",
5162
5162
  "ds:[&:lang(ja)]:tracking-normal ds:[&:lang(ko)]:tracking-normal ds:[&:lang(zh)]:tracking-normal",
5163
- // A word longer than a fixed column ("LIEFERANTENCODE") breaks
5164
- // inside its own cell, hyphenated where the language allows,
5165
- // instead of running under the next header.
5166
- "ds:hyphens-auto ds:wrap-break-word",
5163
+ // Header text wraps between words and is not hyphenated by the
5164
+ // browser: a column must be wide enough for the longest word of
5165
+ // its header in every language. A word that still does not fit
5166
+ // breaks inside its own cell, as a last resort, instead of
5167
+ // running under the next header. The accessible themes, whose
5168
+ // eyebrow is larger, set `--data-grid-header-hyphens: auto` so
5169
+ // that such a break is at least hyphenated.
5170
+ "ds:[hyphens:var(--data-grid-header-hyphens,manual)] ds:wrap-break-word",
5167
5171
  // Printed headers repeat on every page; sticky would pin them once.
5168
5172
  "ds:print:static"
5169
5173
  ],
@@ -9838,4 +9842,4 @@ export {
9838
9842
  Cm as f,
9839
9843
  _h as g
9840
9844
  };
9841
- //# sourceMappingURL=data-grid-bzvkQ3kc.js.map
9845
+ //# sourceMappingURL=data-grid-C9xlUMLt.js.map