@fieldia/widgets 0.11.0 → 0.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (243) hide show
  1. package/package.json +2 -2
  2. package/src/index.d.mts +2 -0
  3. package/src/index.d.ts +2 -0
  4. package/src/index.js +6 -1
  5. package/src/index.js.map +1 -1
  6. package/src/index.mjs +2 -0
  7. package/src/index.mjs.map +1 -1
  8. package/src/lib/badge.d.mts +8 -0
  9. package/src/lib/badge.d.ts +8 -0
  10. package/src/lib/badge.js +37 -0
  11. package/src/lib/badge.js.map +1 -0
  12. package/src/lib/badge.mjs +33 -0
  13. package/src/lib/badge.mjs.map +1 -0
  14. package/src/lib/calendar.d.mts +3 -1
  15. package/src/lib/calendar.d.ts +3 -1
  16. package/src/lib/calendar.js +17 -1
  17. package/src/lib/calendar.js.map +1 -1
  18. package/src/lib/calendar.mjs +17 -1
  19. package/src/lib/calendar.mjs.map +1 -1
  20. package/src/lib/cards.js +12 -4
  21. package/src/lib/cards.js.map +1 -1
  22. package/src/lib/cards.mjs +13 -5
  23. package/src/lib/cards.mjs.map +1 -1
  24. package/src/lib/choice-images.js +1 -1
  25. package/src/lib/choice-images.js.map +1 -1
  26. package/src/lib/choice-images.mjs +1 -1
  27. package/src/lib/choice-images.mjs.map +1 -1
  28. package/src/lib/choice-tags.js +6 -4
  29. package/src/lib/choice-tags.js.map +1 -1
  30. package/src/lib/choice-tags.mjs +6 -4
  31. package/src/lib/choice-tags.mjs.map +1 -1
  32. package/src/lib/colour.d.mts +11 -0
  33. package/src/lib/colour.d.ts +11 -0
  34. package/src/lib/colour.js +114 -0
  35. package/src/lib/colour.js.map +1 -0
  36. package/src/lib/colour.mjs +110 -0
  37. package/src/lib/colour.mjs.map +1 -0
  38. package/src/lib/copy.d.mts +8 -0
  39. package/src/lib/copy.d.ts +8 -0
  40. package/src/lib/copy.js +58 -0
  41. package/src/lib/copy.js.map +1 -0
  42. package/src/lib/copy.mjs +54 -0
  43. package/src/lib/copy.mjs.map +1 -0
  44. package/src/lib/date-range.d.mts +2 -0
  45. package/src/lib/date-range.d.ts +2 -0
  46. package/src/lib/date-range.js +220 -0
  47. package/src/lib/date-range.js.map +1 -0
  48. package/src/lib/date-range.mjs +216 -0
  49. package/src/lib/date-range.mjs.map +1 -0
  50. package/src/lib/display.d.mts +25 -1
  51. package/src/lib/display.d.ts +25 -1
  52. package/src/lib/display.js +42 -2
  53. package/src/lib/display.js.map +1 -1
  54. package/src/lib/display.mjs +39 -2
  55. package/src/lib/display.mjs.map +1 -1
  56. package/src/lib/distribution.d.mts +13 -0
  57. package/src/lib/distribution.d.ts +13 -0
  58. package/src/lib/distribution.js +159 -0
  59. package/src/lib/distribution.js.map +1 -0
  60. package/src/lib/distribution.mjs +152 -0
  61. package/src/lib/distribution.mjs.map +1 -0
  62. package/src/lib/duration.d.mts +18 -0
  63. package/src/lib/duration.d.ts +18 -0
  64. package/src/lib/duration.js +137 -0
  65. package/src/lib/duration.js.map +1 -0
  66. package/src/lib/duration.mjs +128 -0
  67. package/src/lib/duration.mjs.map +1 -0
  68. package/src/lib/embed.d.mts +3 -0
  69. package/src/lib/embed.d.ts +3 -0
  70. package/src/lib/embed.js +97 -0
  71. package/src/lib/embed.js.map +1 -0
  72. package/src/lib/embed.mjs +92 -0
  73. package/src/lib/embed.mjs.map +1 -0
  74. package/src/lib/extras.js +6 -0
  75. package/src/lib/extras.js.map +1 -1
  76. package/src/lib/extras.mjs +6 -0
  77. package/src/lib/extras.mjs.map +1 -1
  78. package/src/lib/files.d.mts +11 -0
  79. package/src/lib/files.d.ts +11 -0
  80. package/src/lib/files.js +19 -0
  81. package/src/lib/files.js.map +1 -1
  82. package/src/lib/files.mjs +18 -0
  83. package/src/lib/files.mjs.map +1 -1
  84. package/src/lib/float.d.mts +14 -0
  85. package/src/lib/float.d.ts +14 -0
  86. package/src/lib/float.js +91 -0
  87. package/src/lib/float.js.map +1 -0
  88. package/src/lib/float.mjs +88 -0
  89. package/src/lib/float.mjs.map +1 -0
  90. package/src/lib/kind-parts.d.mts +4 -3
  91. package/src/lib/kind-parts.d.ts +4 -3
  92. package/src/lib/kind-parts.js +5 -3
  93. package/src/lib/kind-parts.js.map +1 -1
  94. package/src/lib/kind-parts.mjs +5 -3
  95. package/src/lib/kind-parts.mjs.map +1 -1
  96. package/src/lib/labels.d.mts +39 -0
  97. package/src/lib/labels.d.ts +39 -0
  98. package/src/lib/labels.js +29 -0
  99. package/src/lib/labels.js.map +1 -1
  100. package/src/lib/labels.mjs +29 -0
  101. package/src/lib/labels.mjs.map +1 -1
  102. package/src/lib/layout-styles.d.mts +1 -1
  103. package/src/lib/layout-styles.d.ts +1 -1
  104. package/src/lib/layout-styles.js +12 -5
  105. package/src/lib/layout-styles.js.map +1 -1
  106. package/src/lib/layout-styles.mjs +12 -5
  107. package/src/lib/layout-styles.mjs.map +1 -1
  108. package/src/lib/lines.d.mts +12 -2
  109. package/src/lib/lines.d.ts +12 -2
  110. package/src/lib/lines.js +372 -25
  111. package/src/lib/lines.js.map +1 -1
  112. package/src/lib/lines.mjs +371 -26
  113. package/src/lib/lines.mjs.map +1 -1
  114. package/src/lib/links-table.d.mts +11 -0
  115. package/src/lib/links-table.d.ts +11 -0
  116. package/src/lib/links-table.js +116 -0
  117. package/src/lib/links-table.js.map +1 -0
  118. package/src/lib/links-table.mjs +112 -0
  119. package/src/lib/links-table.mjs.map +1 -0
  120. package/src/lib/locales/ar.js +29 -0
  121. package/src/lib/locales/ar.js.map +1 -1
  122. package/src/lib/locales/ar.mjs +29 -0
  123. package/src/lib/locales/ar.mjs.map +1 -1
  124. package/src/lib/locales/de.js +29 -0
  125. package/src/lib/locales/de.js.map +1 -1
  126. package/src/lib/locales/de.mjs +29 -0
  127. package/src/lib/locales/de.mjs.map +1 -1
  128. package/src/lib/locales/fr.js +29 -0
  129. package/src/lib/locales/fr.js.map +1 -1
  130. package/src/lib/locales/fr.mjs +29 -0
  131. package/src/lib/locales/fr.mjs.map +1 -1
  132. package/src/lib/numbers.d.mts +5 -1
  133. package/src/lib/numbers.d.ts +5 -1
  134. package/src/lib/numbers.js +15 -2
  135. package/src/lib/numbers.js.map +1 -1
  136. package/src/lib/numbers.mjs +13 -2
  137. package/src/lib/numbers.mjs.map +1 -1
  138. package/src/lib/payments.d.mts +2 -0
  139. package/src/lib/payments.d.ts +2 -0
  140. package/src/lib/payments.js +94 -0
  141. package/src/lib/payments.js.map +1 -0
  142. package/src/lib/payments.mjs +90 -0
  143. package/src/lib/payments.mjs.map +1 -0
  144. package/src/lib/popup.d.mts +11 -0
  145. package/src/lib/popup.d.ts +11 -0
  146. package/src/lib/popup.js +48 -0
  147. package/src/lib/popup.js.map +1 -0
  148. package/src/lib/popup.mjs +45 -0
  149. package/src/lib/popup.mjs.map +1 -0
  150. package/src/lib/priority.d.mts +10 -0
  151. package/src/lib/priority.d.ts +10 -0
  152. package/src/lib/priority.js +59 -0
  153. package/src/lib/priority.js.map +1 -0
  154. package/src/lib/priority.mjs +55 -0
  155. package/src/lib/priority.mjs.map +1 -0
  156. package/src/lib/progress.js +3 -0
  157. package/src/lib/progress.js.map +1 -1
  158. package/src/lib/progress.mjs +3 -0
  159. package/src/lib/progress.mjs.map +1 -1
  160. package/src/lib/properties.js +100 -9
  161. package/src/lib/properties.js.map +1 -1
  162. package/src/lib/properties.mjs +100 -9
  163. package/src/lib/properties.mjs.map +1 -1
  164. package/src/lib/read-text.d.mts +25 -0
  165. package/src/lib/read-text.d.ts +25 -0
  166. package/src/lib/read-text.js +102 -0
  167. package/src/lib/read-text.js.map +1 -0
  168. package/src/lib/read-text.mjs +98 -0
  169. package/src/lib/read-text.mjs.map +1 -0
  170. package/src/lib/relations.d.mts +12 -0
  171. package/src/lib/relations.d.ts +12 -0
  172. package/src/lib/relations.js +110 -10
  173. package/src/lib/relations.js.map +1 -1
  174. package/src/lib/relations.mjs +108 -10
  175. package/src/lib/relations.mjs.map +1 -1
  176. package/src/lib/slider.js +1 -1
  177. package/src/lib/slider.js.map +1 -1
  178. package/src/lib/slider.mjs +1 -1
  179. package/src/lib/slider.mjs.map +1 -1
  180. package/src/lib/state-dot.d.mts +2 -0
  181. package/src/lib/state-dot.d.ts +2 -0
  182. package/src/lib/state-dot.js +107 -0
  183. package/src/lib/state-dot.js.map +1 -0
  184. package/src/lib/state-dot.mjs +103 -0
  185. package/src/lib/state-dot.mjs.map +1 -0
  186. package/src/lib/statusbar.js +151 -14
  187. package/src/lib/statusbar.js.map +1 -1
  188. package/src/lib/statusbar.mjs +151 -14
  189. package/src/lib/statusbar.mjs.map +1 -1
  190. package/src/lib/styles-business.d.mts +8 -0
  191. package/src/lib/styles-business.d.ts +8 -0
  192. package/src/lib/styles-business.js +120 -0
  193. package/src/lib/styles-business.js.map +1 -0
  194. package/src/lib/styles-business.mjs +117 -0
  195. package/src/lib/styles-business.mjs.map +1 -0
  196. package/src/lib/styles-inputs.d.mts +1 -1
  197. package/src/lib/styles-inputs.d.ts +1 -1
  198. package/src/lib/styles-inputs.js +2 -0
  199. package/src/lib/styles-inputs.js.map +1 -1
  200. package/src/lib/styles-inputs.mjs +2 -0
  201. package/src/lib/styles-inputs.mjs.map +1 -1
  202. package/src/lib/styles-kinds.d.mts +1 -1
  203. package/src/lib/styles-kinds.d.ts +1 -1
  204. package/src/lib/styles-kinds.js +2 -2
  205. package/src/lib/styles-kinds.mjs +2 -2
  206. package/src/lib/styles-sheet.d.mts +6 -0
  207. package/src/lib/styles-sheet.d.ts +6 -0
  208. package/src/lib/styles-sheet.js +139 -0
  209. package/src/lib/styles-sheet.js.map +1 -0
  210. package/src/lib/styles-sheet.mjs +136 -0
  211. package/src/lib/styles-sheet.mjs.map +1 -0
  212. package/src/lib/styles.js +223 -27
  213. package/src/lib/styles.js.map +1 -1
  214. package/src/lib/styles.mjs +223 -27
  215. package/src/lib/styles.mjs.map +1 -1
  216. package/src/lib/tax-totals.d.mts +2 -0
  217. package/src/lib/tax-totals.d.ts +2 -0
  218. package/src/lib/tax-totals.js +92 -0
  219. package/src/lib/tax-totals.js.map +1 -0
  220. package/src/lib/tax-totals.mjs +88 -0
  221. package/src/lib/tax-totals.mjs.map +1 -0
  222. package/src/lib/themes.d.mts +29 -0
  223. package/src/lib/themes.d.ts +29 -0
  224. package/src/lib/themes.js +180 -0
  225. package/src/lib/themes.js.map +1 -0
  226. package/src/lib/themes.mjs +177 -0
  227. package/src/lib/themes.mjs.map +1 -0
  228. package/src/lib/timer.d.mts +4 -0
  229. package/src/lib/timer.d.ts +4 -0
  230. package/src/lib/timer.js +62 -0
  231. package/src/lib/timer.js.map +1 -0
  232. package/src/lib/timer.mjs +57 -0
  233. package/src/lib/timer.mjs.map +1 -0
  234. package/src/lib/widgets.d.mts +18 -3
  235. package/src/lib/widgets.d.ts +18 -3
  236. package/src/lib/widgets.js +89 -10
  237. package/src/lib/widgets.js.map +1 -1
  238. package/src/lib/widgets.mjs +90 -11
  239. package/src/lib/widgets.mjs.map +1 -1
  240. package/src/lib/yes-no.js +1 -1
  241. package/src/lib/yes-no.js.map +1 -1
  242. package/src/lib/yes-no.mjs +1 -1
  243. package/src/lib/yes-no.mjs.map +1 -1
@@ -1,6 +1,30 @@
1
1
  import type { LineField, Locale, Value } from '@fieldia/core';
2
+ /**
3
+ * The currency a money field is in: its own, or the field holding it — on a
4
+ * line, `parent.` and a field of the record it is on (`parent`). A link by its
5
+ * name ("EGP"), a choice or text as it is; null when none is known.
6
+ */
7
+ export declare function currencyOf(def: LineField, values: Readonly<Record<string, Value>>, parent?: Readonly<Record<string, Value>>): string | null;
2
8
  /**
3
9
  * A value as a person reads it where it is not being edited: a cell of the
4
10
  * lines grid, a totals row. Shared by the plain lines table and @fieldia/grid.
11
+ * `parent` is the record a line is on, for money in its currency.
12
+ */
13
+ export declare function displayValue(def: LineField, value: Value | undefined, values?: Record<string, Value>, locale?: Locale, parent?: Readonly<Record<string, Value>>): string;
14
+ /** How a value is shown where it is not edited: by the widget it is drawn with (a cell's, a field's), and its options. */
15
+ export interface ShownWith {
16
+ widget?: string;
17
+ options?: Readonly<Record<string, unknown>>;
18
+ }
19
+ /**
20
+ * A value as words in the widget it is shown with — hours as HH:MM
21
+ * (`duration`), a fraction as a per cent (`percentage`) — else as its type
22
+ * says it (`displayValue`). For a table's cells and totals, plain and grid.
23
+ */
24
+ export declare function cellText(def: LineField, value: Value | undefined, values?: Record<string, Value>, locale?: Locale, parent?: Readonly<Record<string, Value>>, shown?: ShownWith): string;
25
+ /**
26
+ * The widgets a cell is drawn with rather than typed into: a bar, stars, a
27
+ * state's dot, a colour, a pill. A grid shows them in the cell itself, used
28
+ * there with a click; the rest are typed into as the field's own box.
5
29
  */
6
- export declare function displayValue(def: LineField, value: Value | undefined, values?: Record<string, Value>, locale?: Locale): string;
30
+ export declare const DRAWN_IN_CELLS: ReadonlySet<string>;
@@ -1,6 +1,30 @@
1
1
  import type { LineField, Locale, Value } from '@fieldia/core';
2
+ /**
3
+ * The currency a money field is in: its own, or the field holding it — on a
4
+ * line, `parent.` and a field of the record it is on (`parent`). A link by its
5
+ * name ("EGP"), a choice or text as it is; null when none is known.
6
+ */
7
+ export declare function currencyOf(def: LineField, values: Readonly<Record<string, Value>>, parent?: Readonly<Record<string, Value>>): string | null;
2
8
  /**
3
9
  * A value as a person reads it where it is not being edited: a cell of the
4
10
  * lines grid, a totals row. Shared by the plain lines table and @fieldia/grid.
11
+ * `parent` is the record a line is on, for money in its currency.
12
+ */
13
+ export declare function displayValue(def: LineField, value: Value | undefined, values?: Record<string, Value>, locale?: Locale, parent?: Readonly<Record<string, Value>>): string;
14
+ /** How a value is shown where it is not edited: by the widget it is drawn with (a cell's, a field's), and its options. */
15
+ export interface ShownWith {
16
+ widget?: string;
17
+ options?: Readonly<Record<string, unknown>>;
18
+ }
19
+ /**
20
+ * A value as words in the widget it is shown with — hours as HH:MM
21
+ * (`duration`), a fraction as a per cent (`percentage`) — else as its type
22
+ * says it (`displayValue`). For a table's cells and totals, plain and grid.
23
+ */
24
+ export declare function cellText(def: LineField, value: Value | undefined, values?: Record<string, Value>, locale?: Locale, parent?: Readonly<Record<string, Value>>, shown?: ShownWith): string;
25
+ /**
26
+ * The widgets a cell is drawn with rather than typed into: a bar, stars, a
27
+ * state's dot, a colour, a pill. A grid shows them in the cell itself, used
28
+ * there with a click; the rest are typed into as the field's own box.
5
29
  */
6
- export declare function displayValue(def: LineField, value: Value | undefined, values?: Record<string, Value>, locale?: Locale): string;
30
+ export declare const DRAWN_IN_CELLS: ReadonlySet<string>;
@@ -1,7 +1,12 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DRAWN_IN_CELLS = void 0;
4
+ exports.currencyOf = currencyOf;
3
5
  exports.displayValue = displayValue;
6
+ exports.cellText = cellText;
4
7
  const numbers_1 = require("./numbers");
8
+ const duration_1 = require("./duration");
9
+ const distribution_1 = require("./distribution");
5
10
  function localDate(text) {
6
11
  const match = /^(\d{4})-(\d{2})-(\d{2})(?:[T ](\d{2}):(\d{2}))?/.exec(text);
7
12
  if (!match)
@@ -9,11 +14,29 @@ function localDate(text) {
9
14
  const [, y, m, d, hh, mm] = match;
10
15
  return new Date(Number(y), Number(m) - 1, Number(d), Number(hh ?? 0), Number(mm ?? 0));
11
16
  }
17
+ /**
18
+ * The currency a money field is in: its own, or the field holding it — on a
19
+ * line, `parent.` and a field of the record it is on (`parent`). A link by its
20
+ * name ("EGP"), a choice or text as it is; null when none is known.
21
+ */
22
+ function currencyOf(def, values, parent) {
23
+ if (def.type !== 'monetary')
24
+ return null;
25
+ if (def.currency)
26
+ return def.currency;
27
+ if (!def.currencyField)
28
+ return null;
29
+ const holder = def.currencyField.startsWith('parent.') ? parent?.[def.currencyField.slice('parent.'.length)] : values[def.currencyField];
30
+ if (holder && typeof holder === 'object' && 'label' in holder)
31
+ return holder.label || null;
32
+ return typeof holder === 'string' && holder ? holder : null;
33
+ }
12
34
  /**
13
35
  * A value as a person reads it where it is not being edited: a cell of the
14
36
  * lines grid, a totals row. Shared by the plain lines table and @fieldia/grid.
37
+ * `parent` is the record a line is on, for money in its currency.
15
38
  */
16
- function displayValue(def, value, values = {}, locale = 'en') {
39
+ function displayValue(def, value, values = {}, locale = 'en', parent) {
17
40
  const number = (n, digits) => (0, numbers_1.formatNumber)(n, digits, locale);
18
41
  if (value === null || value === undefined || value === '')
19
42
  return '';
@@ -32,7 +55,7 @@ function displayValue(def, value, values = {}, locale = 'en') {
32
55
  case 'float':
33
56
  return number(Number(value), def.digits?.[1] ?? 2);
34
57
  case 'monetary': {
35
- const currency = def.currency ?? (def.currencyField ? values[def.currencyField]?.label : undefined);
58
+ const currency = currencyOf(def, values, parent);
36
59
  // Its currency's symbol, as the amount's own box shows it.
37
60
  return currency ? (0, numbers_1.formatMoney)(Number(value), currency, def.digits?.[1] ?? 2, locale) : number(Number(value), def.digits?.[1] ?? 2);
38
61
  }
@@ -58,4 +81,21 @@ function displayValue(def, value, values = {}, locale = 'en') {
58
81
  return String(value);
59
82
  }
60
83
  }
84
+ /**
85
+ * A value as words in the widget it is shown with — hours as HH:MM
86
+ * (`duration`), a fraction as a per cent (`percentage`) — else as its type
87
+ * says it (`displayValue`). For a table's cells and totals, plain and grid.
88
+ */
89
+ function cellText(def, value, values = {}, locale = 'en', parent, shown = {}) {
90
+ // An analytic distribution in a cell: its shares, "60% · 40%".
91
+ if (shown.widget === 'distribution' && def.type === 'json')
92
+ return (0, distribution_1.distributionWords)(value, locale);
93
+ return (0, duration_1.shownNumber)(shown.widget, def, value, locale, shown.options) ?? displayValue(def, value, values, locale, parent);
94
+ }
95
+ /**
96
+ * The widgets a cell is drawn with rather than typed into: a bar, stars, a
97
+ * state's dot, a colour, a pill. A grid shows them in the cell itself, used
98
+ * there with a click; the rest are typed into as the field's own box.
99
+ */
100
+ exports.DRAWN_IN_CELLS = new Set(['progressbar', 'priority', 'dot', 'color', 'timer', 'badge']);
61
101
  //# sourceMappingURL=display.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"display.js","sourceRoot":"","sources":["../../../../../libs/widgets/src/lib/display.ts"],"names":[],"mappings":";;AAeA,oCA2CC;AAzDD,uCAAsD;AAGtD,SAAS,SAAS,CAAC,IAAY;IAC7B,MAAM,KAAK,GAAG,kDAAkD,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC5E,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAC;IACxB,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,GAAG,KAAK,CAAC;IAClC,OAAO,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,EAAE,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC;AACzF,CAAC;AAED;;;GAGG;AACH,SAAgB,YAAY,CAAC,GAAc,EAAE,KAAwB,EAAE,SAAgC,EAAE,EAAE,SAAiB,IAAI;IAC9H,MAAM,MAAM,GAAG,CAAC,CAAS,EAAE,MAAc,EAAE,EAAE,CAAC,IAAA,sBAAY,EAAC,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9E,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,EAAE;QAAE,OAAO,EAAE,CAAC;IACrE,QAAQ,GAAG,CAAC,IAAI,EAAE,CAAC;QACjB,KAAK,UAAU,CAAC;QAChB,KAAK,WAAW;YACd,OAAQ,KAA4B,CAAC,KAAK,IAAI,EAAE,CAAC;QACnD,KAAK,WAAW;YACd,OAAO,CAAE,KAA6B,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC/E,KAAK,WAAW,CAAC,CAAC,CAAC;YACjB,MAAM,KAAK,GAAG,CAAC,CAAU,EAAE,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,EAAE,KAAK,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC;YACzF,OAAO,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QAC3E,CAAC;QACD,KAAK,SAAS;YACZ,OAAO,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC;QAClC,KAAK,OAAO;YACV,OAAO,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;QACrD,KAAK,UAAU,CAAC,CAAC,CAAC;YAChB,MAAM,QAAQ,GAAG,GAAG,CAAC,QAAQ,IAAI,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC,CAAE,MAAM,CAAC,GAAG,CAAC,aAAa,CAA+B,EAAE,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;YACnI,2DAA2D;YAC3D,OAAO,QAAQ,CAAC,CAAC,CAAC,IAAA,qBAAW,EAAC,MAAM,CAAC,KAAK,CAAC,EAAE,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;QACrI,CAAC;QACD,KAAK,MAAM,CAAC,CAAC,CAAC;YACZ,MAAM,IAAI,GAAG,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;YACtC,OAAO,IAAI,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,cAAc,CAAC,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,GAAG,EAAE,SAAS,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACvL,CAAC;QACD,KAAK,UAAU,CAAC,CAAC,CAAC;YAChB,MAAM,IAAI,GAAG,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;YACtC,OAAO,IAAI;gBACT,CAAC,CAAC,IAAI,IAAI,CAAC,cAAc,CAAC,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,GAAG,EAAE,SAAS,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC;gBAC5L,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACpB,CAAC;QACD,KAAK,MAAM;YACT,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;QAC5E,KAAK,QAAQ,CAAC;QACd,KAAK,OAAO;YACV,qCAAqC;YACrC,OAAO,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAE,IAA0B,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACzF,KAAK,SAAS;YACZ,OAAO,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;QAC1B;YACE,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;IACzB,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"display.js","sourceRoot":"","sources":["../../../../../libs/widgets/src/lib/display.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,6 @@
1
1
  import { formatMoney, formatNumber } from './numbers.mjs';
2
+ import { shownNumber } from './duration.mjs';
3
+ import { distributionWords } from './distribution.mjs';
2
4
  function localDate(text) {
3
5
  const match = /^(\d{4})-(\d{2})-(\d{2})(?:[T ](\d{2}):(\d{2}))?/.exec(text);
4
6
  if (!match)
@@ -6,11 +8,29 @@ function localDate(text) {
6
8
  const [, y, m, d, hh, mm] = match;
7
9
  return new Date(Number(y), Number(m) - 1, Number(d), Number(hh ?? 0), Number(mm ?? 0));
8
10
  }
11
+ /**
12
+ * The currency a money field is in: its own, or the field holding it — on a
13
+ * line, `parent.` and a field of the record it is on (`parent`). A link by its
14
+ * name ("EGP"), a choice or text as it is; null when none is known.
15
+ */
16
+ export function currencyOf(def, values, parent) {
17
+ if (def.type !== 'monetary')
18
+ return null;
19
+ if (def.currency)
20
+ return def.currency;
21
+ if (!def.currencyField)
22
+ return null;
23
+ const holder = def.currencyField.startsWith('parent.') ? parent?.[def.currencyField.slice('parent.'.length)] : values[def.currencyField];
24
+ if (holder && typeof holder === 'object' && 'label' in holder)
25
+ return holder.label || null;
26
+ return typeof holder === 'string' && holder ? holder : null;
27
+ }
9
28
  /**
10
29
  * A value as a person reads it where it is not being edited: a cell of the
11
30
  * lines grid, a totals row. Shared by the plain lines table and @fieldia/grid.
31
+ * `parent` is the record a line is on, for money in its currency.
12
32
  */
13
- export function displayValue(def, value, values = {}, locale = 'en') {
33
+ export function displayValue(def, value, values = {}, locale = 'en', parent) {
14
34
  const number = (n, digits) => formatNumber(n, digits, locale);
15
35
  if (value === null || value === undefined || value === '')
16
36
  return '';
@@ -29,7 +49,7 @@ export function displayValue(def, value, values = {}, locale = 'en') {
29
49
  case 'float':
30
50
  return number(Number(value), def.digits?.[1] ?? 2);
31
51
  case 'monetary': {
32
- const currency = def.currency ?? (def.currencyField ? values[def.currencyField]?.label : undefined);
52
+ const currency = currencyOf(def, values, parent);
33
53
  // Its currency's symbol, as the amount's own box shows it.
34
54
  return currency ? formatMoney(Number(value), currency, def.digits?.[1] ?? 2, locale) : number(Number(value), def.digits?.[1] ?? 2);
35
55
  }
@@ -55,4 +75,21 @@ export function displayValue(def, value, values = {}, locale = 'en') {
55
75
  return String(value);
56
76
  }
57
77
  }
78
+ /**
79
+ * A value as words in the widget it is shown with — hours as HH:MM
80
+ * (`duration`), a fraction as a per cent (`percentage`) — else as its type
81
+ * says it (`displayValue`). For a table's cells and totals, plain and grid.
82
+ */
83
+ export function cellText(def, value, values = {}, locale = 'en', parent, shown = {}) {
84
+ // An analytic distribution in a cell: its shares, "60% · 40%".
85
+ if (shown.widget === 'distribution' && def.type === 'json')
86
+ return distributionWords(value, locale);
87
+ return shownNumber(shown.widget, def, value, locale, shown.options) ?? displayValue(def, value, values, locale, parent);
88
+ }
89
+ /**
90
+ * The widgets a cell is drawn with rather than typed into: a bar, stars, a
91
+ * state's dot, a colour, a pill. A grid shows them in the cell itself, used
92
+ * there with a click; the rest are typed into as the field's own box.
93
+ */
94
+ export const DRAWN_IN_CELLS = new Set(['progressbar', 'priority', 'dot', 'color', 'timer', 'badge']);
58
95
  //# sourceMappingURL=display.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"display.mjs","sourceRoot":"","sources":["../../../../../libs/widgets/src/lib/display.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"display.mjs","sourceRoot":"","sources":["../../../../../libs/widgets/src/lib/display.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ import type { Locale, RecordId, Value } from '@fieldia/core';
2
+ import type { WidgetFactory } from './widgets.mjs';
3
+ /** The model a distribution's accounts are records of: its `options.model`, else Flectra's analytic accounts. */
4
+ export declare const distributionModel: (options: Readonly<Record<string, unknown>> | undefined) => string;
5
+ /** The accounts' ids a distribution names, each once, as a data source finds them. */
6
+ export declare function distributionIds(value: Value | undefined): RecordId[];
7
+ /**
8
+ * A distribution in a few words, for a table's cell: each account by its
9
+ * name — `nameOf`, when it knows it — and its share, "Sales 60% · Marketing
10
+ * 40%"; the shares alone without names. Empty for none.
11
+ */
12
+ export declare function distributionWords(value: Value | undefined, locale?: Locale, nameOf?: (id: string) => string | undefined): string;
13
+ export declare const distributionWidget: WidgetFactory;
@@ -0,0 +1,13 @@
1
+ import type { Locale, RecordId, Value } from '@fieldia/core';
2
+ import type { WidgetFactory } from './widgets';
3
+ /** The model a distribution's accounts are records of: its `options.model`, else Flectra's analytic accounts. */
4
+ export declare const distributionModel: (options: Readonly<Record<string, unknown>> | undefined) => string;
5
+ /** The accounts' ids a distribution names, each once, as a data source finds them. */
6
+ export declare function distributionIds(value: Value | undefined): RecordId[];
7
+ /**
8
+ * A distribution in a few words, for a table's cell: each account by its
9
+ * name — `nameOf`, when it knows it — and its share, "Sales 60% · Marketing
10
+ * 40%"; the shares alone without names. Empty for none.
11
+ */
12
+ export declare function distributionWords(value: Value | undefined, locale?: Locale, nameOf?: (id: string) => string | undefined): string;
13
+ export declare const distributionWidget: WidgetFactory;
@@ -0,0 +1,159 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.distributionWidget = exports.distributionModel = void 0;
4
+ exports.distributionIds = distributionIds;
5
+ exports.distributionWords = distributionWords;
6
+ const kind_parts_1 = require("./kind-parts");
7
+ const numbers_1 = require("./numbers");
8
+ const relations_1 = require("./relations");
9
+ /** The model a distribution's accounts are records of: its `options.model`, else Flectra's analytic accounts. */
10
+ const distributionModel = (options) => (typeof options?.['model'] === 'string' ? options['model'] : 'account.analytic.account');
11
+ exports.distributionModel = distributionModel;
12
+ /** The accounts' ids a distribution names, each once, as a data source finds them. */
13
+ function distributionIds(value) {
14
+ return [...new Set(sharesOf(value).flatMap(([key]) => key.split(',')))].map((one) => (/^\d+$/.test(one) ? Number(one) : one));
15
+ }
16
+ /**
17
+ * A distribution in a few words, for a table's cell: each account by its
18
+ * name — `nameOf`, when it knows it — and its share, "Sales 60% · Marketing
19
+ * 40%"; the shares alone without names. Empty for none.
20
+ */
21
+ function distributionWords(value, locale = 'en', nameOf) {
22
+ const percent = (n) => `${(0, numbers_1.formatNumber)(n, Number.isInteger(n) ? 0 : 2, locale)}%`;
23
+ return sharesOf(value)
24
+ .map(([key, share]) => {
25
+ const name = nameOf ? key.split(',').map((one) => nameOf(one) ?? `#${one}`).join(' · ') : '';
26
+ return name ? `${name} ${percent(share)}` : percent(share);
27
+ })
28
+ .join(nameOf ? ', ' : ' · ');
29
+ }
30
+ const sharesOf = (value) => value && typeof value === 'object' && !Array.isArray(value) ? Object.entries(value).map(([key, share]) => [key, typeof share === 'number' ? share : Number(share) || 0]) : [];
31
+ const distributionWidget = (context) => {
32
+ const { form, name, node, id, document, labels, locale = 'en' } = context;
33
+ const make = (0, kind_parts_1.maker)(document);
34
+ const words = (0, kind_parts_1.wordsFor)(labels, locale);
35
+ const model = (0, exports.distributionModel)(node.options);
36
+ /** The accounts' names, by their key, as they are found. */
37
+ const names = new Map();
38
+ const nameOf = (key) => key.split(',').map((one) => names.get(one) ?? `#${one}`).join(' · ');
39
+ const percent = (n) => `${(0, numbers_1.formatNumber)(n, Number.isInteger(n) ? 0 : 2, locale)}%`;
40
+ const body = make('tbody');
41
+ const total = make('td', { class: 'fd-distribution-total' });
42
+ const table = make('table', { class: 'fd-lines-table fd-distribution-table' }, make('thead', {}, make('tr', {}, make('th', { scope: 'col' }, words.account), make('th', { scope: 'col', class: 'fd-distribution-share' }, words.share), make('th', { class: 'fd-lines-tools' }))), body, make('tfoot', {}, make('tr', { class: 'fd-lines-totals' }, make('td', {}, words.total), total, make('td'))));
43
+ const add = make('button', { type: 'button', class: 'fd-button fd-button-link fd-lines-add fd-distribution-add' }, `+ ${words.addAccount}`);
44
+ const off = make('div', { class: 'fd-warning fd-distribution-off', role: 'status', hidden: '' });
45
+ const element = make('div', { id, class: 'fd-distribution', role: 'group' }, make('div', { class: 'fd-lines-scroll' }, table), add, off);
46
+ let rows = [];
47
+ let readonly = false;
48
+ /** The value the lines say: those with an account, in their order. */
49
+ function save() {
50
+ const value = {};
51
+ for (const row of rows)
52
+ if (row.key)
53
+ value[row.key] = row.share;
54
+ form.setValue(name, (rows.some((row) => row.key) ? value : null));
55
+ }
56
+ function makeRow(key, share) {
57
+ const n = rows.length;
58
+ const cellId = `${id}-${n}-${Math.random().toString(36).slice(2, 7)}`;
59
+ // The account's own link box: it searches the model's records, and its pick becomes the line's key.
60
+ const row = { key, share };
61
+ const own = {
62
+ ...form,
63
+ getState: () => ({ ...form.getState(), values: { account: row.key ? { id: row.key, label: nameOf(row.key) } : null } }),
64
+ setValue: (_name, picked) => {
65
+ const record = picked;
66
+ row.key = record ? String(record.id) : '';
67
+ if (record)
68
+ names.set(String(record.id), record.label);
69
+ save();
70
+ },
71
+ search: (_name, query, limit) => form.search(name, query, limit, { model }),
72
+ canCreate: () => false,
73
+ };
74
+ const accountField = { type: 'many2one', label: words.account, relation: model };
75
+ row.account = (0, relations_1.many2oneWidget)({ ...context, form: own, name: 'account', field: accountField, node: { type: 'field', id: `${node.id}.account`, field: 'account', options: { create: false } }, id: cellId });
76
+ row.input = make('input', { type: 'text', class: 'fd-input fd-number-input fd-share', inputmode: 'decimal', autocomplete: 'off', 'aria-label': words.share });
77
+ row.input.addEventListener('input', () => {
78
+ const text = (0, numbers_1.normalizeNumber)(row.input.value.trim(), locale);
79
+ if (!/^\d+\.?\d*$|^\.\d+$/.test(text))
80
+ return;
81
+ row.share = Number(text);
82
+ save();
83
+ });
84
+ row.remove = make('button', { type: 'button', class: 'fd-line-delete', 'aria-label': words.deleteLine }, '×');
85
+ row.remove.addEventListener('click', () => {
86
+ rows = rows.filter((other) => other !== row);
87
+ row.account.destroy?.();
88
+ row.element.remove();
89
+ save();
90
+ draw();
91
+ });
92
+ row.element = make('tr', {}, make('td', {}, make('label', { class: 'fd-sr-only', for: cellId }, words.account), row.account.element), make('td', { class: 'fd-distribution-share' }, make('span', { class: 'fd-number' }, row.input, make('span', { class: 'fd-unit' }, '%'))), make('td', { class: 'fd-lines-tools' }, row.remove));
93
+ return row;
94
+ }
95
+ add.addEventListener('click', () => {
96
+ const left = Math.max(0, 100 - rows.reduce((sum, row) => sum + row.share, 0));
97
+ const row = makeRow('', Math.round(left * 100) / 100);
98
+ rows.push(row);
99
+ body.append(row.element);
100
+ draw();
101
+ row.account.focus();
102
+ });
103
+ /** Names for the accounts the value holds that are not known yet. */
104
+ let asked = '';
105
+ function findNames(keys) {
106
+ const unknown = [...new Set(keys.flatMap((key) => key.split(',')))].filter((one) => !names.has(one));
107
+ if (!unknown.length || unknown.join() === asked)
108
+ return;
109
+ asked = unknown.join();
110
+ const ids = unknown.map((one) => (/^\d+$/.test(one) ? Number(one) : one));
111
+ form.search(name, '', unknown.length, { model, ids }).then((found) => {
112
+ for (const record of found)
113
+ names.set(String(record.id), record.label);
114
+ draw();
115
+ }, () => undefined);
116
+ }
117
+ function draw() {
118
+ const sum = rows.reduce((total, row) => total + row.share, 0);
119
+ (0, kind_parts_1.setText)(total, percent(Math.round(sum * 100) / 100));
120
+ const wrong = rows.some((row) => row.key) && Math.abs(sum - 100) > 0.001;
121
+ (0, kind_parts_1.setText)(off, wrong ? (0, kind_parts_1.fillIn)(words.sharesOff, { n: percent(Math.round(sum * 100) / 100) }) : '');
122
+ (0, kind_parts_1.setHidden)(off, !wrong);
123
+ (0, kind_parts_1.setHidden)(add, readonly);
124
+ for (const row of rows) {
125
+ row.account.update({ value: row.key ? { id: row.key, label: nameOf(row.key) } : null, values: {}, readonly, required: false, invalid: false });
126
+ const text = (0, numbers_1.formatNumber)(row.share, Number.isInteger(row.share) ? 0 : 2, locale);
127
+ if (document.activeElement !== row.input && row.input.value !== text)
128
+ row.input.value = text;
129
+ row.input.readOnly = readonly;
130
+ if (readonly)
131
+ row.remove.remove();
132
+ else if (!row.remove.isConnected)
133
+ row.element.lastElementChild?.append(row.remove);
134
+ }
135
+ }
136
+ return {
137
+ element,
138
+ focus: () => (rows[0]?.input ?? add).focus(),
139
+ destroy: () => rows.forEach((row) => row.account.destroy?.()),
140
+ update(state) {
141
+ readonly = state.readonly;
142
+ const shares = sharesOf(state.value);
143
+ // Lines follow the value: those it holds, in its order, and a new one still without its account.
144
+ const same = shares.length === rows.filter((row) => row.key).length && shares.every(([key, share], i) => rows.filter((row) => row.key)[i]?.key === key && rows.filter((row) => row.key)[i]?.share === share);
145
+ if (!same) {
146
+ for (const row of rows)
147
+ row.account.destroy?.();
148
+ const waiting = rows.filter((row) => !row.key);
149
+ rows = shares.map(([key, share]) => makeRow(key, share));
150
+ rows.push(...waiting.map((row) => makeRow('', row.share)));
151
+ body.replaceChildren(...rows.map((row) => row.element));
152
+ }
153
+ findNames(shares.map(([key]) => key));
154
+ draw();
155
+ },
156
+ };
157
+ };
158
+ exports.distributionWidget = distributionWidget;
159
+ //# sourceMappingURL=distribution.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"distribution.js","sourceRoot":"","sources":["../../../../../libs/widgets/src/lib/distribution.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,152 @@
1
+ import { fillIn, maker, setHidden, setText, wordsFor } from './kind-parts.mjs';
2
+ import { formatNumber, normalizeNumber } from './numbers.mjs';
3
+ import { many2oneWidget } from './relations.mjs';
4
+ /** The model a distribution's accounts are records of: its `options.model`, else Flectra's analytic accounts. */
5
+ export const distributionModel = (options) => (typeof options?.['model'] === 'string' ? options['model'] : 'account.analytic.account');
6
+ /** The accounts' ids a distribution names, each once, as a data source finds them. */
7
+ export function distributionIds(value) {
8
+ return [...new Set(sharesOf(value).flatMap(([key]) => key.split(',')))].map((one) => (/^\d+$/.test(one) ? Number(one) : one));
9
+ }
10
+ /**
11
+ * A distribution in a few words, for a table's cell: each account by its
12
+ * name — `nameOf`, when it knows it — and its share, "Sales 60% · Marketing
13
+ * 40%"; the shares alone without names. Empty for none.
14
+ */
15
+ export function distributionWords(value, locale = 'en', nameOf) {
16
+ const percent = (n) => `${formatNumber(n, Number.isInteger(n) ? 0 : 2, locale)}%`;
17
+ return sharesOf(value)
18
+ .map(([key, share]) => {
19
+ const name = nameOf ? key.split(',').map((one) => nameOf(one) ?? `#${one}`).join(' · ') : '';
20
+ return name ? `${name} ${percent(share)}` : percent(share);
21
+ })
22
+ .join(nameOf ? ', ' : ' · ');
23
+ }
24
+ const sharesOf = (value) => value && typeof value === 'object' && !Array.isArray(value) ? Object.entries(value).map(([key, share]) => [key, typeof share === 'number' ? share : Number(share) || 0]) : [];
25
+ export const distributionWidget = (context) => {
26
+ const { form, name, node, id, document, labels, locale = 'en' } = context;
27
+ const make = maker(document);
28
+ const words = wordsFor(labels, locale);
29
+ const model = distributionModel(node.options);
30
+ /** The accounts' names, by their key, as they are found. */
31
+ const names = new Map();
32
+ const nameOf = (key) => key.split(',').map((one) => names.get(one) ?? `#${one}`).join(' · ');
33
+ const percent = (n) => `${formatNumber(n, Number.isInteger(n) ? 0 : 2, locale)}%`;
34
+ const body = make('tbody');
35
+ const total = make('td', { class: 'fd-distribution-total' });
36
+ const table = make('table', { class: 'fd-lines-table fd-distribution-table' }, make('thead', {}, make('tr', {}, make('th', { scope: 'col' }, words.account), make('th', { scope: 'col', class: 'fd-distribution-share' }, words.share), make('th', { class: 'fd-lines-tools' }))), body, make('tfoot', {}, make('tr', { class: 'fd-lines-totals' }, make('td', {}, words.total), total, make('td'))));
37
+ const add = make('button', { type: 'button', class: 'fd-button fd-button-link fd-lines-add fd-distribution-add' }, `+ ${words.addAccount}`);
38
+ const off = make('div', { class: 'fd-warning fd-distribution-off', role: 'status', hidden: '' });
39
+ const element = make('div', { id, class: 'fd-distribution', role: 'group' }, make('div', { class: 'fd-lines-scroll' }, table), add, off);
40
+ let rows = [];
41
+ let readonly = false;
42
+ /** The value the lines say: those with an account, in their order. */
43
+ function save() {
44
+ const value = {};
45
+ for (const row of rows)
46
+ if (row.key)
47
+ value[row.key] = row.share;
48
+ form.setValue(name, (rows.some((row) => row.key) ? value : null));
49
+ }
50
+ function makeRow(key, share) {
51
+ const n = rows.length;
52
+ const cellId = `${id}-${n}-${Math.random().toString(36).slice(2, 7)}`;
53
+ // The account's own link box: it searches the model's records, and its pick becomes the line's key.
54
+ const row = { key, share };
55
+ const own = {
56
+ ...form,
57
+ getState: () => ({ ...form.getState(), values: { account: row.key ? { id: row.key, label: nameOf(row.key) } : null } }),
58
+ setValue: (_name, picked) => {
59
+ const record = picked;
60
+ row.key = record ? String(record.id) : '';
61
+ if (record)
62
+ names.set(String(record.id), record.label);
63
+ save();
64
+ },
65
+ search: (_name, query, limit) => form.search(name, query, limit, { model }),
66
+ canCreate: () => false,
67
+ };
68
+ const accountField = { type: 'many2one', label: words.account, relation: model };
69
+ row.account = many2oneWidget({ ...context, form: own, name: 'account', field: accountField, node: { type: 'field', id: `${node.id}.account`, field: 'account', options: { create: false } }, id: cellId });
70
+ row.input = make('input', { type: 'text', class: 'fd-input fd-number-input fd-share', inputmode: 'decimal', autocomplete: 'off', 'aria-label': words.share });
71
+ row.input.addEventListener('input', () => {
72
+ const text = normalizeNumber(row.input.value.trim(), locale);
73
+ if (!/^\d+\.?\d*$|^\.\d+$/.test(text))
74
+ return;
75
+ row.share = Number(text);
76
+ save();
77
+ });
78
+ row.remove = make('button', { type: 'button', class: 'fd-line-delete', 'aria-label': words.deleteLine }, '×');
79
+ row.remove.addEventListener('click', () => {
80
+ rows = rows.filter((other) => other !== row);
81
+ row.account.destroy?.();
82
+ row.element.remove();
83
+ save();
84
+ draw();
85
+ });
86
+ row.element = make('tr', {}, make('td', {}, make('label', { class: 'fd-sr-only', for: cellId }, words.account), row.account.element), make('td', { class: 'fd-distribution-share' }, make('span', { class: 'fd-number' }, row.input, make('span', { class: 'fd-unit' }, '%'))), make('td', { class: 'fd-lines-tools' }, row.remove));
87
+ return row;
88
+ }
89
+ add.addEventListener('click', () => {
90
+ const left = Math.max(0, 100 - rows.reduce((sum, row) => sum + row.share, 0));
91
+ const row = makeRow('', Math.round(left * 100) / 100);
92
+ rows.push(row);
93
+ body.append(row.element);
94
+ draw();
95
+ row.account.focus();
96
+ });
97
+ /** Names for the accounts the value holds that are not known yet. */
98
+ let asked = '';
99
+ function findNames(keys) {
100
+ const unknown = [...new Set(keys.flatMap((key) => key.split(',')))].filter((one) => !names.has(one));
101
+ if (!unknown.length || unknown.join() === asked)
102
+ return;
103
+ asked = unknown.join();
104
+ const ids = unknown.map((one) => (/^\d+$/.test(one) ? Number(one) : one));
105
+ form.search(name, '', unknown.length, { model, ids }).then((found) => {
106
+ for (const record of found)
107
+ names.set(String(record.id), record.label);
108
+ draw();
109
+ }, () => undefined);
110
+ }
111
+ function draw() {
112
+ const sum = rows.reduce((total, row) => total + row.share, 0);
113
+ setText(total, percent(Math.round(sum * 100) / 100));
114
+ const wrong = rows.some((row) => row.key) && Math.abs(sum - 100) > 0.001;
115
+ setText(off, wrong ? fillIn(words.sharesOff, { n: percent(Math.round(sum * 100) / 100) }) : '');
116
+ setHidden(off, !wrong);
117
+ setHidden(add, readonly);
118
+ for (const row of rows) {
119
+ row.account.update({ value: row.key ? { id: row.key, label: nameOf(row.key) } : null, values: {}, readonly, required: false, invalid: false });
120
+ const text = formatNumber(row.share, Number.isInteger(row.share) ? 0 : 2, locale);
121
+ if (document.activeElement !== row.input && row.input.value !== text)
122
+ row.input.value = text;
123
+ row.input.readOnly = readonly;
124
+ if (readonly)
125
+ row.remove.remove();
126
+ else if (!row.remove.isConnected)
127
+ row.element.lastElementChild?.append(row.remove);
128
+ }
129
+ }
130
+ return {
131
+ element,
132
+ focus: () => (rows[0]?.input ?? add).focus(),
133
+ destroy: () => rows.forEach((row) => row.account.destroy?.()),
134
+ update(state) {
135
+ readonly = state.readonly;
136
+ const shares = sharesOf(state.value);
137
+ // Lines follow the value: those it holds, in its order, and a new one still without its account.
138
+ const same = shares.length === rows.filter((row) => row.key).length && shares.every(([key, share], i) => rows.filter((row) => row.key)[i]?.key === key && rows.filter((row) => row.key)[i]?.share === share);
139
+ if (!same) {
140
+ for (const row of rows)
141
+ row.account.destroy?.();
142
+ const waiting = rows.filter((row) => !row.key);
143
+ rows = shares.map(([key, share]) => makeRow(key, share));
144
+ rows.push(...waiting.map((row) => makeRow('', row.share)));
145
+ body.replaceChildren(...rows.map((row) => row.element));
146
+ }
147
+ findNames(shares.map(([key]) => key));
148
+ draw();
149
+ },
150
+ };
151
+ };
152
+ //# sourceMappingURL=distribution.mjs.map