@ketvietlab/ketsuite 0.1.25 → 0.1.29

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 (1073) hide show
  1. package/dist/cache.d.ts +23 -0
  2. package/dist/cache.d.ts.map +1 -0
  3. package/dist/cache.js +71 -0
  4. package/dist/cache.js.map +1 -0
  5. package/dist/cli-watch.d.ts +4 -0
  6. package/dist/cli-watch.d.ts.map +1 -0
  7. package/dist/cli-watch.js +52 -0
  8. package/dist/cli-watch.js.map +1 -0
  9. package/dist/cli.js +45 -17
  10. package/dist/cli.js.map +1 -1
  11. package/dist/deployment.d.ts +11 -0
  12. package/dist/deployment.d.ts.map +1 -1
  13. package/dist/deployment.js +49 -39
  14. package/dist/deployment.js.map +1 -1
  15. package/dist/deployments/commerce.d.ts +4 -0
  16. package/dist/deployments/commerce.d.ts.map +1 -0
  17. package/dist/deployments/commerce.js +34 -0
  18. package/dist/deployments/commerce.js.map +1 -0
  19. package/dist/deployments/common.d.ts +54 -0
  20. package/dist/deployments/common.d.ts.map +1 -0
  21. package/dist/deployments/common.js +112 -0
  22. package/dist/deployments/common.js.map +1 -0
  23. package/dist/deployments/hospitality.d.ts +4 -0
  24. package/dist/deployments/hospitality.d.ts.map +1 -0
  25. package/dist/deployments/hospitality.js +103 -0
  26. package/dist/deployments/hospitality.js.map +1 -0
  27. package/dist/deployments/office.d.ts +4 -0
  28. package/dist/deployments/office.d.ts.map +1 -0
  29. package/dist/deployments/office.js +31 -0
  30. package/dist/deployments/office.js.map +1 -0
  31. package/dist/development.d.ts +16 -0
  32. package/dist/development.d.ts.map +1 -1
  33. package/dist/development.js +31 -0
  34. package/dist/development.js.map +1 -1
  35. package/dist/index.d.ts +3 -0
  36. package/dist/index.d.ts.map +1 -1
  37. package/dist/index.js +3 -0
  38. package/dist/index.js.map +1 -1
  39. package/dist/modules/account_backend/index.js +364 -871
  40. package/dist/modules/account_backend/index.js.map +1 -1
  41. package/dist/modules/account_backend/screens/accounts-list.d.ts.map +1 -1
  42. package/dist/modules/account_backend/screens/accounts-list.js +5 -15
  43. package/dist/modules/account_backend/screens/accounts-list.js.map +1 -1
  44. package/dist/modules/account_backend/screens/customer-invoices-list.d.ts.map +1 -1
  45. package/dist/modules/account_backend/screens/customer-invoices-list.js +5 -15
  46. package/dist/modules/account_backend/screens/customer-invoices-list.js.map +1 -1
  47. package/dist/modules/account_backend/screens/journal-entries-list.d.ts.map +1 -1
  48. package/dist/modules/account_backend/screens/journal-entries-list.js +5 -15
  49. package/dist/modules/account_backend/screens/journal-entries-list.js.map +1 -1
  50. package/dist/modules/account_backend/screens/journals-list.d.ts.map +1 -1
  51. package/dist/modules/account_backend/screens/journals-list.js +5 -15
  52. package/dist/modules/account_backend/screens/journals-list.js.map +1 -1
  53. package/dist/modules/account_backend/screens/opening-balances.d.ts +3 -1
  54. package/dist/modules/account_backend/screens/opening-balances.d.ts.map +1 -1
  55. package/dist/modules/account_backend/screens/opening-balances.js +11 -5
  56. package/dist/modules/account_backend/screens/opening-balances.js.map +1 -1
  57. package/dist/modules/account_backend/screens/payment-terms-list.d.ts.map +1 -1
  58. package/dist/modules/account_backend/screens/payment-terms-list.js +6 -17
  59. package/dist/modules/account_backend/screens/payment-terms-list.js.map +1 -1
  60. package/dist/modules/account_backend/screens/payments-list.d.ts.map +1 -1
  61. package/dist/modules/account_backend/screens/payments-list.js +5 -15
  62. package/dist/modules/account_backend/screens/payments-list.js.map +1 -1
  63. package/dist/modules/account_backend/screens/period-closes.d.ts +3 -1
  64. package/dist/modules/account_backend/screens/period-closes.d.ts.map +1 -1
  65. package/dist/modules/account_backend/screens/period-closes.js +40 -36
  66. package/dist/modules/account_backend/screens/period-closes.js.map +1 -1
  67. package/dist/modules/account_backend/screens/taxes-list.d.ts.map +1 -1
  68. package/dist/modules/account_backend/screens/taxes-list.js +5 -15
  69. package/dist/modules/account_backend/screens/taxes-list.js.map +1 -1
  70. package/dist/modules/account_backend/screens/vendor-bills-list.d.ts.map +1 -1
  71. package/dist/modules/account_backend/screens/vendor-bills-list.js +5 -15
  72. package/dist/modules/account_backend/screens/vendor-bills-list.js.map +1 -1
  73. package/dist/modules/account_backend/search-functions.d.ts +4 -0
  74. package/dist/modules/account_backend/search-functions.d.ts.map +1 -0
  75. package/dist/modules/account_backend/search-functions.js +5 -0
  76. package/dist/modules/account_backend/search-functions.js.map +1 -0
  77. package/dist/modules/account_backend/search.d.ts +774 -0
  78. package/dist/modules/account_backend/search.d.ts.map +1 -0
  79. package/dist/modules/account_backend/search.js +312 -0
  80. package/dist/modules/account_backend/search.js.map +1 -0
  81. package/dist/modules/address_backend/index.d.ts.map +1 -1
  82. package/dist/modules/address_backend/index.js +2 -0
  83. package/dist/modules/address_backend/index.js.map +1 -1
  84. package/dist/modules/address_backend/routes.d.ts.map +1 -1
  85. package/dist/modules/address_backend/routes.js +32 -7
  86. package/dist/modules/address_backend/routes.js.map +1 -1
  87. package/dist/modules/address_backend/screens/catalogs-list.d.ts +3 -1
  88. package/dist/modules/address_backend/screens/catalogs-list.d.ts.map +1 -1
  89. package/dist/modules/address_backend/screens/catalogs-list.js +15 -9
  90. package/dist/modules/address_backend/screens/catalogs-list.js.map +1 -1
  91. package/dist/modules/address_backend/screens/country-browser.d.ts.map +1 -1
  92. package/dist/modules/address_backend/screens/country-browser.js +7 -15
  93. package/dist/modules/address_backend/screens/country-browser.js.map +1 -1
  94. package/dist/modules/address_backend/search-functions.d.ts +4 -0
  95. package/dist/modules/address_backend/search-functions.d.ts.map +1 -0
  96. package/dist/modules/address_backend/search-functions.js +7 -0
  97. package/dist/modules/address_backend/search-functions.js.map +1 -0
  98. package/dist/modules/address_backend/search.d.ts +38 -0
  99. package/dist/modules/address_backend/search.d.ts.map +1 -0
  100. package/dist/modules/address_backend/search.js +40 -0
  101. package/dist/modules/address_backend/search.js.map +1 -0
  102. package/dist/modules/backend/catalogue.d.ts.map +1 -1
  103. package/dist/modules/backend/catalogue.js +16 -13
  104. package/dist/modules/backend/catalogue.js.map +1 -1
  105. package/dist/modules/backend/collection-search.d.ts +16 -0
  106. package/dist/modules/backend/collection-search.d.ts.map +1 -0
  107. package/dist/modules/backend/collection-search.js +43 -0
  108. package/dist/modules/backend/collection-search.js.map +1 -0
  109. package/dist/modules/backend/design/HANDOFF.md +1 -1
  110. package/dist/modules/backend/design/auth.css +61 -0
  111. package/dist/modules/backend/design/brand/logo-dark.png +0 -0
  112. package/dist/modules/backend/design/brand/logo-light.png +0 -0
  113. package/dist/modules/backend/design/client/backend-shell.d.mts +2 -2
  114. package/dist/modules/backend/design/client/backend-shell.d.mts.map +1 -1
  115. package/dist/modules/backend/design/client/backend-shell.mjs +1 -1
  116. package/dist/modules/backend/design/client/backend-shell.mjs.map +4 -4
  117. package/dist/modules/backend/design/client/ket-table.d.mts +10 -0
  118. package/dist/modules/backend/design/client/ket-table.d.mts.map +1 -0
  119. package/dist/modules/backend/design/client/ket-table.mjs +2 -0
  120. package/dist/modules/backend/design/client/ket-table.mjs.map +7 -0
  121. package/dist/modules/backend/design/client/lightbox.d.mts +22 -0
  122. package/dist/modules/backend/design/client/lightbox.d.mts.map +1 -0
  123. package/dist/modules/backend/design/client/lightbox.mjs +2 -0
  124. package/dist/modules/backend/design/client/lightbox.mjs.map +7 -0
  125. package/dist/modules/backend/design/client/relation-select.d.mts +12 -3
  126. package/dist/modules/backend/design/client/relation-select.d.mts.map +1 -1
  127. package/dist/modules/backend/design/client/relation-select.mjs +1 -1
  128. package/dist/modules/backend/design/client/relation-select.mjs.map +4 -4
  129. package/dist/modules/backend/design/client/search-filter.d.mts +10 -0
  130. package/dist/modules/backend/design/client/search-filter.d.mts.map +1 -0
  131. package/dist/modules/backend/design/client/search-filter.mjs +2 -0
  132. package/dist/modules/backend/design/client/search-filter.mjs.map +7 -0
  133. package/dist/modules/backend/design/content.css +43 -5
  134. package/dist/modules/backend/design/forms.css +99 -229
  135. package/dist/modules/backend/design/foundation.css +0 -51
  136. package/dist/modules/backend/design/lists.css +79 -7
  137. package/dist/modules/backend/design/user-workflow.css +0 -20
  138. package/dist/modules/backend/global-search.d.ts +3 -0
  139. package/dist/modules/backend/global-search.d.ts.map +1 -0
  140. package/dist/modules/backend/global-search.js +82 -0
  141. package/dist/modules/backend/global-search.js.map +1 -0
  142. package/dist/modules/backend/index.d.ts +26 -0
  143. package/dist/modules/backend/index.d.ts.map +1 -1
  144. package/dist/modules/backend/index.js +23 -0
  145. package/dist/modules/backend/index.js.map +1 -1
  146. package/dist/modules/backend/islands.d.ts +44 -1
  147. package/dist/modules/backend/islands.d.ts.map +1 -1
  148. package/dist/modules/backend/islands.js +25 -1
  149. package/dist/modules/backend/islands.js.map +1 -1
  150. package/dist/modules/backend/joints.d.ts.map +1 -1
  151. package/dist/modules/backend/joints.js +12 -0
  152. package/dist/modules/backend/joints.js.map +1 -1
  153. package/dist/modules/backend/ket-table.d.ts +7 -0
  154. package/dist/modules/backend/ket-table.d.ts.map +1 -0
  155. package/dist/modules/backend/ket-table.js +2 -0
  156. package/dist/modules/backend/ket-table.js.map +1 -0
  157. package/dist/modules/backend/messages.d.ts.map +1 -1
  158. package/dist/modules/backend/messages.js +144 -0
  159. package/dist/modules/backend/messages.js.map +1 -1
  160. package/dist/modules/backend/paging.d.ts.map +1 -1
  161. package/dist/modules/backend/paging.js +2 -1
  162. package/dist/modules/backend/paging.js.map +1 -1
  163. package/dist/modules/backend/relation-select.d.ts +2 -2
  164. package/dist/modules/backend/relation-select.d.ts.map +1 -1
  165. package/dist/modules/backend/routes.d.ts.map +1 -1
  166. package/dist/modules/backend/routes.js +2 -0
  167. package/dist/modules/backend/routes.js.map +1 -1
  168. package/dist/modules/backend/row-list.d.ts +63 -0
  169. package/dist/modules/backend/row-list.d.ts.map +1 -0
  170. package/dist/modules/backend/row-list.js +252 -0
  171. package/dist/modules/backend/row-list.js.map +1 -0
  172. package/dist/modules/backend/screen.d.ts +3 -3
  173. package/dist/modules/backend/screen.d.ts.map +1 -1
  174. package/dist/modules/backend/screen.js +6 -7
  175. package/dist/modules/backend/screen.js.map +1 -1
  176. package/dist/modules/backend/search-filter-state.d.ts +42 -0
  177. package/dist/modules/backend/search-filter-state.d.ts.map +1 -0
  178. package/dist/modules/backend/search-filter-state.js +277 -0
  179. package/dist/modules/backend/search-filter-state.js.map +1 -0
  180. package/dist/modules/backend/search-filter.d.ts +77 -0
  181. package/dist/modules/backend/search-filter.d.ts.map +1 -0
  182. package/dist/modules/backend/search-filter.js +259 -0
  183. package/dist/modules/backend/search-filter.js.map +1 -0
  184. package/dist/modules/channel_api/core.d.ts +1 -0
  185. package/dist/modules/channel_api/core.d.ts.map +1 -1
  186. package/dist/modules/channel_api/core.js.map +1 -1
  187. package/dist/modules/channel_api/customer.d.ts.map +1 -1
  188. package/dist/modules/channel_api/customer.js +4 -5
  189. package/dist/modules/channel_api/customer.js.map +1 -1
  190. package/dist/modules/company_backend/index.d.ts.map +1 -1
  191. package/dist/modules/company_backend/index.js +2 -0
  192. package/dist/modules/company_backend/index.js.map +1 -1
  193. package/dist/modules/company_backend/routes.d.ts.map +1 -1
  194. package/dist/modules/company_backend/routes.js +33 -27
  195. package/dist/modules/company_backend/routes.js.map +1 -1
  196. package/dist/modules/company_backend/screens/companies-list.d.ts +3 -3
  197. package/dist/modules/company_backend/screens/companies-list.d.ts.map +1 -1
  198. package/dist/modules/company_backend/screens/companies-list.js +18 -18
  199. package/dist/modules/company_backend/screens/companies-list.js.map +1 -1
  200. package/dist/modules/company_backend/screens/hierarchy.d.ts.map +1 -1
  201. package/dist/modules/company_backend/screens/hierarchy.js +1 -2
  202. package/dist/modules/company_backend/screens/hierarchy.js.map +1 -1
  203. package/dist/modules/company_backend/search-functions.d.ts +4 -0
  204. package/dist/modules/company_backend/search-functions.d.ts.map +1 -0
  205. package/dist/modules/company_backend/search-functions.js +7 -0
  206. package/dist/modules/company_backend/search-functions.js.map +1 -0
  207. package/dist/modules/company_backend/search.d.ts +24 -0
  208. package/dist/modules/company_backend/search.d.ts.map +1 -0
  209. package/dist/modules/company_backend/search.js +24 -0
  210. package/dist/modules/company_backend/search.js.map +1 -0
  211. package/dist/modules/crm/functions/activities.js +7 -10
  212. package/dist/modules/crm/functions/activities.js.map +1 -1
  213. package/dist/modules/crm/functions/case-modal-context.d.ts +3 -0
  214. package/dist/modules/crm/functions/case-modal-context.d.ts.map +1 -0
  215. package/dist/modules/crm/functions/case-modal-context.js +156 -0
  216. package/dist/modules/crm/functions/case-modal-context.js.map +1 -0
  217. package/dist/modules/crm/functions/cases.d.ts.map +1 -1
  218. package/dist/modules/crm/functions/cases.js +35 -2
  219. package/dist/modules/crm/functions/cases.js.map +1 -1
  220. package/dist/modules/crm/functions/configuration.js +1 -1
  221. package/dist/modules/crm/functions/configuration.js.map +1 -1
  222. package/dist/modules/crm/functions/gamification.d.ts.map +1 -1
  223. package/dist/modules/crm/functions/gamification.js +11 -7
  224. package/dist/modules/crm/functions/gamification.js.map +1 -1
  225. package/dist/modules/crm/functions/index.d.ts.map +1 -1
  226. package/dist/modules/crm/functions/index.js +4 -0
  227. package/dist/modules/crm/functions/index.js.map +1 -1
  228. package/dist/modules/crm/functions/reporting.d.ts +3 -0
  229. package/dist/modules/crm/functions/reporting.d.ts.map +1 -0
  230. package/dist/modules/crm/functions/reporting.js +140 -0
  231. package/dist/modules/crm/functions/reporting.js.map +1 -0
  232. package/dist/modules/crm/functions/shared.d.ts +1 -0
  233. package/dist/modules/crm/functions/shared.d.ts.map +1 -1
  234. package/dist/modules/crm/functions/shared.js +17 -9
  235. package/dist/modules/crm/functions/shared.js.map +1 -1
  236. package/dist/modules/crm/messages.d.ts +8 -1
  237. package/dist/modules/crm/messages.d.ts.map +1 -1
  238. package/dist/modules/crm/messages.js +14 -0
  239. package/dist/modules/crm/messages.js.map +1 -1
  240. package/dist/modules/crm/models.d.ts.map +1 -1
  241. package/dist/modules/crm/models.js +7 -0
  242. package/dist/modules/crm/models.js.map +1 -1
  243. package/dist/modules/crm/operations.d.ts +4 -1
  244. package/dist/modules/crm/operations.d.ts.map +1 -1
  245. package/dist/modules/crm/operations.js +39 -7
  246. package/dist/modules/crm/operations.js.map +1 -1
  247. package/dist/modules/crm/reporting.d.ts +115 -0
  248. package/dist/modules/crm/reporting.d.ts.map +1 -0
  249. package/dist/modules/crm/reporting.js +241 -0
  250. package/dist/modules/crm/reporting.js.map +1 -0
  251. package/dist/modules/crm_backend/client/crm-case-modal.d.mts +302 -0
  252. package/dist/modules/crm_backend/client/crm-case-modal.d.mts.map +1 -0
  253. package/dist/modules/crm_backend/client/crm-case-modal.mjs +2 -0
  254. package/dist/modules/crm_backend/client/crm-case-modal.mjs.map +7 -0
  255. package/dist/modules/crm_backend/client/crm-configuration-modal.d.mts +51 -51
  256. package/dist/modules/crm_backend/client/crm-configuration-modal.d.mts.map +1 -1
  257. package/dist/modules/crm_backend/client/crm-configuration-modal.mjs +1 -1
  258. package/dist/modules/crm_backend/client/crm-configuration-modal.mjs.map +4 -4
  259. package/dist/modules/crm_backend/client/crm-kanban-view.mjs +1 -1
  260. package/dist/modules/crm_backend/client/crm-kanban-view.mjs.map +1 -1
  261. package/dist/modules/crm_backend/collection-rows.d.ts +6 -0
  262. package/dist/modules/crm_backend/collection-rows.d.ts.map +1 -0
  263. package/dist/modules/crm_backend/collection-rows.js +15 -0
  264. package/dist/modules/crm_backend/collection-rows.js.map +1 -0
  265. package/dist/modules/crm_backend/index.d.ts.map +1 -1
  266. package/dist/modules/crm_backend/index.js +2 -15
  267. package/dist/modules/crm_backend/index.js.map +1 -1
  268. package/dist/modules/crm_backend/islands.d.ts +1 -0
  269. package/dist/modules/crm_backend/islands.d.ts.map +1 -1
  270. package/dist/modules/crm_backend/islands.js +5 -0
  271. package/dist/modules/crm_backend/islands.js.map +1 -1
  272. package/dist/modules/crm_backend/messages.d.ts +34 -0
  273. package/dist/modules/crm_backend/messages.d.ts.map +1 -1
  274. package/dist/modules/crm_backend/messages.js +34 -0
  275. package/dist/modules/crm_backend/messages.js.map +1 -1
  276. package/dist/modules/crm_backend/modal/case-modal-view.d.ts +23 -0
  277. package/dist/modules/crm_backend/modal/case-modal-view.d.ts.map +1 -0
  278. package/dist/modules/crm_backend/modal/case-modal-view.js +640 -0
  279. package/dist/modules/crm_backend/modal/case-modal-view.js.map +1 -0
  280. package/dist/modules/crm_backend/routes.d.ts.map +1 -1
  281. package/dist/modules/crm_backend/routes.js +71 -15
  282. package/dist/modules/crm_backend/routes.js.map +1 -1
  283. package/dist/modules/crm_backend/screens/activity-planner.d.ts +1 -0
  284. package/dist/modules/crm_backend/screens/activity-planner.d.ts.map +1 -1
  285. package/dist/modules/crm_backend/screens/activity-planner.js +15 -11
  286. package/dist/modules/crm_backend/screens/activity-planner.js.map +1 -1
  287. package/dist/modules/crm_backend/screens/cases-list.d.ts +1 -0
  288. package/dist/modules/crm_backend/screens/cases-list.d.ts.map +1 -1
  289. package/dist/modules/crm_backend/screens/cases-list.js +17 -26
  290. package/dist/modules/crm_backend/screens/cases-list.js.map +1 -1
  291. package/dist/modules/crm_backend/screens/configuration.d.ts.map +1 -1
  292. package/dist/modules/crm_backend/screens/configuration.js +18 -16
  293. package/dist/modules/crm_backend/screens/configuration.js.map +1 -1
  294. package/dist/modules/crm_backend/screens/leaderboard.d.ts +2 -0
  295. package/dist/modules/crm_backend/screens/leaderboard.d.ts.map +1 -1
  296. package/dist/modules/crm_backend/screens/leaderboard.js +12 -18
  297. package/dist/modules/crm_backend/screens/leaderboard.js.map +1 -1
  298. package/dist/modules/flow/functions.d.ts.map +1 -1
  299. package/dist/modules/flow/functions.js +20 -39
  300. package/dist/modules/flow/functions.js.map +1 -1
  301. package/dist/modules/flow_backend/index.js +2 -1
  302. package/dist/modules/flow_backend/index.js.map +1 -1
  303. package/dist/modules/flow_backend/routes.d.ts.map +1 -1
  304. package/dist/modules/flow_backend/routes.js +181 -126
  305. package/dist/modules/flow_backend/routes.js.map +1 -1
  306. package/dist/modules/flow_backend/screens/all-epics.d.ts.map +1 -1
  307. package/dist/modules/flow_backend/screens/all-epics.js +37 -45
  308. package/dist/modules/flow_backend/screens/all-epics.js.map +1 -1
  309. package/dist/modules/flow_backend/screens/all-pages.d.ts.map +1 -1
  310. package/dist/modules/flow_backend/screens/all-pages.js +43 -51
  311. package/dist/modules/flow_backend/screens/all-pages.js.map +1 -1
  312. package/dist/modules/flow_backend/screens/issues.d.ts.map +1 -1
  313. package/dist/modules/flow_backend/screens/issues.js +68 -82
  314. package/dist/modules/flow_backend/screens/issues.js.map +1 -1
  315. package/dist/modules/flow_backend/screens/my-work.d.ts.map +1 -1
  316. package/dist/modules/flow_backend/screens/my-work.js +63 -69
  317. package/dist/modules/flow_backend/screens/my-work.js.map +1 -1
  318. package/dist/modules/flow_backend/screens/project-pages.d.ts.map +1 -1
  319. package/dist/modules/flow_backend/screens/project-pages.js +1 -2
  320. package/dist/modules/flow_backend/screens/project-pages.js.map +1 -1
  321. package/dist/modules/flow_backend/screens/projects-list.d.ts.map +1 -1
  322. package/dist/modules/flow_backend/screens/projects-list.js +41 -64
  323. package/dist/modules/flow_backend/screens/projects-list.js.map +1 -1
  324. package/dist/modules/flow_backend/screens/sprints.d.ts +3 -1
  325. package/dist/modules/flow_backend/screens/sprints.d.ts.map +1 -1
  326. package/dist/modules/flow_backend/screens/sprints.js +77 -73
  327. package/dist/modules/flow_backend/screens/sprints.js.map +1 -1
  328. package/dist/modules/flow_backend/search-functions.d.ts +13 -0
  329. package/dist/modules/flow_backend/search-functions.d.ts.map +1 -0
  330. package/dist/modules/flow_backend/search-functions.js +40 -0
  331. package/dist/modules/flow_backend/search-functions.js.map +1 -0
  332. package/dist/modules/flow_backend/search.d.ts +48 -0
  333. package/dist/modules/flow_backend/search.d.ts.map +1 -0
  334. package/dist/modules/flow_backend/search.js +57 -0
  335. package/dist/modules/flow_backend/search.js.map +1 -0
  336. package/dist/modules/hospitality_billing/index.js +2 -1
  337. package/dist/modules/hospitality_billing/index.js.map +1 -1
  338. package/dist/modules/hospitality_billing/menus.js +2 -2
  339. package/dist/modules/hospitality_billing/menus.js.map +1 -1
  340. package/dist/modules/hospitality_billing/messages.d.ts.map +1 -1
  341. package/dist/modules/hospitality_billing/messages.js +2 -0
  342. package/dist/modules/hospitality_billing/messages.js.map +1 -1
  343. package/dist/modules/hospitality_billing/routes.d.ts.map +1 -1
  344. package/dist/modules/hospitality_billing/routes.js +39 -5
  345. package/dist/modules/hospitality_billing/routes.js.map +1 -1
  346. package/dist/modules/hospitality_billing/screens/billing.d.ts.map +1 -1
  347. package/dist/modules/hospitality_billing/screens/billing.js +21 -17
  348. package/dist/modules/hospitality_billing/screens/billing.js.map +1 -1
  349. package/dist/modules/hospitality_billing/screens/charge-rules.d.ts +4 -2
  350. package/dist/modules/hospitality_billing/screens/charge-rules.d.ts.map +1 -1
  351. package/dist/modules/hospitality_billing/screens/charge-rules.js +14 -9
  352. package/dist/modules/hospitality_billing/screens/charge-rules.js.map +1 -1
  353. package/dist/modules/hospitality_billing/screens/page-frame.d.ts +3 -1
  354. package/dist/modules/hospitality_billing/screens/page-frame.d.ts.map +1 -1
  355. package/dist/modules/hospitality_billing/screens/page-frame.js +2 -4
  356. package/dist/modules/hospitality_billing/screens/page-frame.js.map +1 -1
  357. package/dist/modules/hospitality_billing/screens/shared.d.ts +4 -4
  358. package/dist/modules/hospitality_billing/screens/shared.d.ts.map +1 -1
  359. package/dist/modules/hospitality_billing/screens/shared.js +2 -2
  360. package/dist/modules/hospitality_billing/screens/shared.js.map +1 -1
  361. package/dist/modules/hospitality_billing/search-functions.d.ts +4 -0
  362. package/dist/modules/hospitality_billing/search-functions.d.ts.map +1 -0
  363. package/dist/modules/hospitality_billing/search-functions.js +16 -0
  364. package/dist/modules/hospitality_billing/search-functions.js.map +1 -0
  365. package/dist/modules/hospitality_billing/search.d.ts +66 -0
  366. package/dist/modules/hospitality_billing/search.d.ts.map +1 -0
  367. package/dist/modules/hospitality_billing/search.js +92 -0
  368. package/dist/modules/hospitality_billing/search.js.map +1 -0
  369. package/dist/modules/hospitality_core/content.d.ts.map +1 -1
  370. package/dist/modules/hospitality_core/content.js +3 -0
  371. package/dist/modules/hospitality_core/content.js.map +1 -1
  372. package/dist/modules/hospitality_core/housekeeping.d.ts.map +1 -1
  373. package/dist/modules/hospitality_core/housekeeping.js +13 -4
  374. package/dist/modules/hospitality_core/housekeeping.js.map +1 -1
  375. package/dist/modules/hospitality_core/index.d.ts.map +1 -1
  376. package/dist/modules/hospitality_core/index.js +2 -0
  377. package/dist/modules/hospitality_core/index.js.map +1 -1
  378. package/dist/modules/hospitality_core/menus.d.ts.map +1 -1
  379. package/dist/modules/hospitality_core/menus.js +27 -30
  380. package/dist/modules/hospitality_core/menus.js.map +1 -1
  381. package/dist/modules/hospitality_core/messages.d.ts.map +1 -1
  382. package/dist/modules/hospitality_core/messages.js +4 -0
  383. package/dist/modules/hospitality_core/messages.js.map +1 -1
  384. package/dist/modules/hospitality_core/routes.d.ts.map +1 -1
  385. package/dist/modules/hospitality_core/routes.js +135 -47
  386. package/dist/modules/hospitality_core/routes.js.map +1 -1
  387. package/dist/modules/hospitality_core/screens/amenities.d.ts +4 -2
  388. package/dist/modules/hospitality_core/screens/amenities.d.ts.map +1 -1
  389. package/dist/modules/hospitality_core/screens/amenities.js +9 -5
  390. package/dist/modules/hospitality_core/screens/amenities.js.map +1 -1
  391. package/dist/modules/hospitality_core/screens/cleaning-tasks.d.ts.map +1 -1
  392. package/dist/modules/hospitality_core/screens/cleaning-tasks.js +45 -30
  393. package/dist/modules/hospitality_core/screens/cleaning-tasks.js.map +1 -1
  394. package/dist/modules/hospitality_core/screens/folios.d.ts +4 -2
  395. package/dist/modules/hospitality_core/screens/folios.d.ts.map +1 -1
  396. package/dist/modules/hospitality_core/screens/folios.js +10 -4
  397. package/dist/modules/hospitality_core/screens/folios.js.map +1 -1
  398. package/dist/modules/hospitality_core/screens/page-frame.d.ts +3 -1
  399. package/dist/modules/hospitality_core/screens/page-frame.d.ts.map +1 -1
  400. package/dist/modules/hospitality_core/screens/page-frame.js +4 -7
  401. package/dist/modules/hospitality_core/screens/page-frame.js.map +1 -1
  402. package/dist/modules/hospitality_core/screens/policies.d.ts +4 -2
  403. package/dist/modules/hospitality_core/screens/policies.d.ts.map +1 -1
  404. package/dist/modules/hospitality_core/screens/policies.js +9 -5
  405. package/dist/modules/hospitality_core/screens/policies.js.map +1 -1
  406. package/dist/modules/hospitality_core/screens/properties.d.ts +4 -2
  407. package/dist/modules/hospitality_core/screens/properties.d.ts.map +1 -1
  408. package/dist/modules/hospitality_core/screens/properties.js +49 -42
  409. package/dist/modules/hospitality_core/screens/properties.js.map +1 -1
  410. package/dist/modules/hospitality_core/screens/rate-plans.d.ts.map +1 -1
  411. package/dist/modules/hospitality_core/screens/rate-plans.js +19 -15
  412. package/dist/modules/hospitality_core/screens/rate-plans.js.map +1 -1
  413. package/dist/modules/hospitality_core/screens/reservations.d.ts.map +1 -1
  414. package/dist/modules/hospitality_core/screens/reservations.js +26 -19
  415. package/dist/modules/hospitality_core/screens/reservations.js.map +1 -1
  416. package/dist/modules/hospitality_core/screens/room-types.d.ts.map +1 -1
  417. package/dist/modules/hospitality_core/screens/room-types.js +23 -19
  418. package/dist/modules/hospitality_core/screens/room-types.js.map +1 -1
  419. package/dist/modules/hospitality_core/screens/rooms.d.ts.map +1 -1
  420. package/dist/modules/hospitality_core/screens/rooms.js +26 -19
  421. package/dist/modules/hospitality_core/screens/rooms.js.map +1 -1
  422. package/dist/modules/hospitality_core/screens/shared.d.ts +4 -4
  423. package/dist/modules/hospitality_core/screens/shared.d.ts.map +1 -1
  424. package/dist/modules/hospitality_core/screens/shared.js +2 -2
  425. package/dist/modules/hospitality_core/screens/shared.js.map +1 -1
  426. package/dist/modules/hospitality_core/screens/stays.d.ts +4 -2
  427. package/dist/modules/hospitality_core/screens/stays.d.ts.map +1 -1
  428. package/dist/modules/hospitality_core/screens/stays.js +10 -4
  429. package/dist/modules/hospitality_core/screens/stays.js.map +1 -1
  430. package/dist/modules/hospitality_core/search-functions.d.ts +10 -0
  431. package/dist/modules/hospitality_core/search-functions.d.ts.map +1 -0
  432. package/dist/modules/hospitality_core/search-functions.js +17 -0
  433. package/dist/modules/hospitality_core/search-functions.js.map +1 -0
  434. package/dist/modules/hospitality_core/search.d.ts +218 -0
  435. package/dist/modules/hospitality_core/search.d.ts.map +1 -0
  436. package/dist/modules/hospitality_core/search.js +201 -0
  437. package/dist/modules/hospitality_core/search.js.map +1 -0
  438. package/dist/modules/hr_backend/index.d.ts.map +1 -1
  439. package/dist/modules/hr_backend/index.js +2 -0
  440. package/dist/modules/hr_backend/index.js.map +1 -1
  441. package/dist/modules/hr_backend/routes.d.ts.map +1 -1
  442. package/dist/modules/hr_backend/routes.js +55 -71
  443. package/dist/modules/hr_backend/routes.js.map +1 -1
  444. package/dist/modules/hr_backend/screens/employees-list.d.ts +3 -1
  445. package/dist/modules/hr_backend/screens/employees-list.d.ts.map +1 -1
  446. package/dist/modules/hr_backend/screens/employees-list.js +14 -12
  447. package/dist/modules/hr_backend/screens/employees-list.js.map +1 -1
  448. package/dist/modules/hr_backend/screens/leaves-list.d.ts +3 -1
  449. package/dist/modules/hr_backend/screens/leaves-list.d.ts.map +1 -1
  450. package/dist/modules/hr_backend/screens/leaves-list.js +11 -10
  451. package/dist/modules/hr_backend/screens/leaves-list.js.map +1 -1
  452. package/dist/modules/hr_backend/search-functions.d.ts +4 -0
  453. package/dist/modules/hr_backend/search-functions.d.ts.map +1 -0
  454. package/dist/modules/hr_backend/search-functions.js +8 -0
  455. package/dist/modules/hr_backend/search-functions.js.map +1 -0
  456. package/dist/modules/hr_backend/search.d.ts +73 -0
  457. package/dist/modules/hr_backend/search.d.ts.map +1 -0
  458. package/dist/modules/hr_backend/search.js +67 -0
  459. package/dist/modules/hr_backend/search.js.map +1 -0
  460. package/dist/modules/livedoc/islands.d.ts +1 -0
  461. package/dist/modules/livedoc/islands.d.ts.map +1 -1
  462. package/dist/modules/loyalty_backend/index.js +176 -215
  463. package/dist/modules/loyalty_backend/index.js.map +1 -1
  464. package/dist/modules/loyalty_backend/screens/index.d.ts.map +1 -1
  465. package/dist/modules/loyalty_backend/screens/index.js +321 -326
  466. package/dist/modules/loyalty_backend/screens/index.js.map +1 -1
  467. package/dist/modules/loyalty_backend/screens/page-frame.d.ts +6 -3
  468. package/dist/modules/loyalty_backend/screens/page-frame.d.ts.map +1 -1
  469. package/dist/modules/loyalty_backend/screens/page-frame.js +3 -3
  470. package/dist/modules/loyalty_backend/screens/page-frame.js.map +1 -1
  471. package/dist/modules/loyalty_backend/search-functions.d.ts +4 -0
  472. package/dist/modules/loyalty_backend/search-functions.d.ts.map +1 -0
  473. package/dist/modules/loyalty_backend/search-functions.js +11 -0
  474. package/dist/modules/loyalty_backend/search-functions.js.map +1 -0
  475. package/dist/modules/loyalty_backend/search.d.ts +33 -0
  476. package/dist/modules/loyalty_backend/search.d.ts.map +1 -0
  477. package/dist/modules/loyalty_backend/search.js +85 -0
  478. package/dist/modules/loyalty_backend/search.js.map +1 -0
  479. package/dist/modules/manufacturing_backend/index.d.ts.map +1 -1
  480. package/dist/modules/manufacturing_backend/index.js +14 -0
  481. package/dist/modules/manufacturing_backend/index.js.map +1 -1
  482. package/dist/modules/manufacturing_backend/routes.d.ts.map +1 -1
  483. package/dist/modules/manufacturing_backend/routes.js +74 -20
  484. package/dist/modules/manufacturing_backend/routes.js.map +1 -1
  485. package/dist/modules/manufacturing_backend/screens/boms-list.d.ts +3 -1
  486. package/dist/modules/manufacturing_backend/screens/boms-list.d.ts.map +1 -1
  487. package/dist/modules/manufacturing_backend/screens/boms-list.js +12 -11
  488. package/dist/modules/manufacturing_backend/screens/boms-list.js.map +1 -1
  489. package/dist/modules/manufacturing_backend/screens/orders-list.d.ts +3 -1
  490. package/dist/modules/manufacturing_backend/screens/orders-list.d.ts.map +1 -1
  491. package/dist/modules/manufacturing_backend/screens/orders-list.js +13 -12
  492. package/dist/modules/manufacturing_backend/screens/orders-list.js.map +1 -1
  493. package/dist/modules/manufacturing_backend/screens/work-centers-list.d.ts +3 -1
  494. package/dist/modules/manufacturing_backend/screens/work-centers-list.d.ts.map +1 -1
  495. package/dist/modules/manufacturing_backend/screens/work-centers-list.js +13 -12
  496. package/dist/modules/manufacturing_backend/screens/work-centers-list.js.map +1 -1
  497. package/dist/modules/manufacturing_backend/search-functions.d.ts +4 -0
  498. package/dist/modules/manufacturing_backend/search-functions.d.ts.map +1 -0
  499. package/dist/modules/manufacturing_backend/search-functions.js +9 -0
  500. package/dist/modules/manufacturing_backend/search-functions.js.map +1 -0
  501. package/dist/modules/manufacturing_backend/search.d.ts +99 -0
  502. package/dist/modules/manufacturing_backend/search.d.ts.map +1 -0
  503. package/dist/modules/manufacturing_backend/search.js +75 -0
  504. package/dist/modules/manufacturing_backend/search.js.map +1 -0
  505. package/dist/modules/oauth_backend/index.d.ts.map +1 -1
  506. package/dist/modules/oauth_backend/index.js +2 -0
  507. package/dist/modules/oauth_backend/index.js.map +1 -1
  508. package/dist/modules/oauth_backend/routes.d.ts.map +1 -1
  509. package/dist/modules/oauth_backend/routes.js +33 -2
  510. package/dist/modules/oauth_backend/routes.js.map +1 -1
  511. package/dist/modules/oauth_backend/screens/index.d.ts +7 -3
  512. package/dist/modules/oauth_backend/screens/index.d.ts.map +1 -1
  513. package/dist/modules/oauth_backend/screens/index.js +113 -103
  514. package/dist/modules/oauth_backend/screens/index.js.map +1 -1
  515. package/dist/modules/oauth_backend/search-functions.d.ts +4 -0
  516. package/dist/modules/oauth_backend/search-functions.d.ts.map +1 -0
  517. package/dist/modules/oauth_backend/search-functions.js +8 -0
  518. package/dist/modules/oauth_backend/search-functions.js.map +1 -0
  519. package/dist/modules/oauth_backend/search.d.ts +68 -0
  520. package/dist/modules/oauth_backend/search.d.ts.map +1 -0
  521. package/dist/modules/oauth_backend/search.js +69 -0
  522. package/dist/modules/oauth_backend/search.js.map +1 -0
  523. package/dist/modules/partner/functions.d.ts.map +1 -1
  524. package/dist/modules/partner/functions.js +121 -23
  525. package/dist/modules/partner/functions.js.map +1 -1
  526. package/dist/modules/partner_backend/functions.d.ts +13 -0
  527. package/dist/modules/partner_backend/functions.d.ts.map +1 -0
  528. package/dist/modules/partner_backend/functions.js +56 -0
  529. package/dist/modules/partner_backend/functions.js.map +1 -0
  530. package/dist/modules/partner_backend/index.d.ts.map +1 -1
  531. package/dist/modules/partner_backend/index.js +28 -6
  532. package/dist/modules/partner_backend/index.js.map +1 -1
  533. package/dist/modules/partner_backend/routes.d.ts.map +1 -1
  534. package/dist/modules/partner_backend/routes.js +269 -86
  535. package/dist/modules/partner_backend/routes.js.map +1 -1
  536. package/dist/modules/partner_backend/screens/index.d.ts +1 -1
  537. package/dist/modules/partner_backend/screens/index.d.ts.map +1 -1
  538. package/dist/modules/partner_backend/screens/list.d.ts +3 -4
  539. package/dist/modules/partner_backend/screens/list.d.ts.map +1 -1
  540. package/dist/modules/partner_backend/screens/list.js +13 -92
  541. package/dist/modules/partner_backend/screens/list.js.map +1 -1
  542. package/dist/modules/partner_backend/screens/types.d.ts +0 -11
  543. package/dist/modules/partner_backend/screens/types.d.ts.map +1 -1
  544. package/dist/modules/pos_backend/index.js +34 -9
  545. package/dist/modules/pos_backend/index.js.map +1 -1
  546. package/dist/modules/pos_backend/screens.d.ts +4 -2
  547. package/dist/modules/pos_backend/screens.d.ts.map +1 -1
  548. package/dist/modules/pos_backend/screens.js +105 -96
  549. package/dist/modules/pos_backend/screens.js.map +1 -1
  550. package/dist/modules/pos_backend/search-functions.d.ts +4 -0
  551. package/dist/modules/pos_backend/search-functions.d.ts.map +1 -0
  552. package/dist/modules/pos_backend/search-functions.js +7 -0
  553. package/dist/modules/pos_backend/search-functions.js.map +1 -0
  554. package/dist/modules/pos_backend/search.d.ts +41 -0
  555. package/dist/modules/pos_backend/search.d.ts.map +1 -0
  556. package/dist/modules/pos_backend/search.js +33 -0
  557. package/dist/modules/pos_backend/search.js.map +1 -0
  558. package/dist/modules/pricing_backend/index.js +31 -2
  559. package/dist/modules/pricing_backend/index.js.map +1 -1
  560. package/dist/modules/pricing_backend/screens/pricelists-list.d.ts +3 -1
  561. package/dist/modules/pricing_backend/screens/pricelists-list.d.ts.map +1 -1
  562. package/dist/modules/pricing_backend/screens/pricelists-list.js +14 -12
  563. package/dist/modules/pricing_backend/screens/pricelists-list.js.map +1 -1
  564. package/dist/modules/pricing_backend/search-functions.d.ts +4 -0
  565. package/dist/modules/pricing_backend/search-functions.d.ts.map +1 -0
  566. package/dist/modules/pricing_backend/search-functions.js +11 -0
  567. package/dist/modules/pricing_backend/search-functions.js.map +1 -0
  568. package/dist/modules/pricing_backend/search.d.ts +41 -0
  569. package/dist/modules/pricing_backend/search.d.ts.map +1 -0
  570. package/dist/modules/pricing_backend/search.js +34 -0
  571. package/dist/modules/pricing_backend/search.js.map +1 -0
  572. package/dist/modules/product/attribute-draft.d.ts +3 -0
  573. package/dist/modules/product/attribute-draft.d.ts.map +1 -0
  574. package/dist/modules/product/attribute-draft.js +126 -0
  575. package/dist/modules/product/attribute-draft.js.map +1 -0
  576. package/dist/modules/product/attribute-modal-context.d.ts +4 -0
  577. package/dist/modules/product/attribute-modal-context.d.ts.map +1 -0
  578. package/dist/modules/product/attribute-modal-context.js +57 -0
  579. package/dist/modules/product/attribute-modal-context.js.map +1 -0
  580. package/dist/modules/product/attribute-modal-labels.d.ts +3 -0
  581. package/dist/modules/product/attribute-modal-labels.d.ts.map +1 -0
  582. package/dist/modules/product/attribute-modal-labels.js +30 -0
  583. package/dist/modules/product/attribute-modal-labels.js.map +1 -0
  584. package/dist/modules/product/functions.d.ts.map +1 -1
  585. package/dist/modules/product/functions.js +7 -1
  586. package/dist/modules/product/functions.js.map +1 -1
  587. package/dist/modules/product/messages.d.ts.map +1 -1
  588. package/dist/modules/product/messages.js +24 -0
  589. package/dist/modules/product/messages.js.map +1 -1
  590. package/dist/modules/product/models.d.ts.map +1 -1
  591. package/dist/modules/product/models.js +14 -2
  592. package/dist/modules/product/models.js.map +1 -1
  593. package/dist/modules/product/product-modal-context.d.ts.map +1 -1
  594. package/dist/modules/product/product-modal-context.js +20 -30
  595. package/dist/modules/product/product-modal-context.js.map +1 -1
  596. package/dist/modules/product/record-images.d.ts +12 -0
  597. package/dist/modules/product/record-images.d.ts.map +1 -0
  598. package/dist/modules/product/record-images.js +37 -0
  599. package/dist/modules/product/record-images.js.map +1 -0
  600. package/dist/modules/product/search.d.ts +3 -0
  601. package/dist/modules/product/search.d.ts.map +1 -1
  602. package/dist/modules/product/search.js +4 -0
  603. package/dist/modules/product/search.js.map +1 -1
  604. package/dist/modules/product/variant-setup.d.ts +46 -0
  605. package/dist/modules/product/variant-setup.d.ts.map +1 -0
  606. package/dist/modules/product/variant-setup.js +444 -0
  607. package/dist/modules/product/variant-setup.js.map +1 -0
  608. package/dist/modules/product_backend/attribute-search-state.d.ts +22 -0
  609. package/dist/modules/product_backend/attribute-search-state.d.ts.map +1 -0
  610. package/dist/modules/product_backend/attribute-search-state.js +62 -0
  611. package/dist/modules/product_backend/attribute-search-state.js.map +1 -0
  612. package/dist/modules/product_backend/attributes-search.d.ts +10 -0
  613. package/dist/modules/product_backend/attributes-search.d.ts.map +1 -0
  614. package/dist/modules/product_backend/attributes-search.js +67 -0
  615. package/dist/modules/product_backend/attributes-search.js.map +1 -0
  616. package/dist/modules/product_backend/client/attribute-modal.d.mts +62 -0
  617. package/dist/modules/product_backend/client/attribute-modal.d.mts.map +1 -0
  618. package/dist/modules/product_backend/client/attribute-modal.mjs +2 -0
  619. package/dist/modules/product_backend/client/attribute-modal.mjs.map +7 -0
  620. package/dist/modules/product_backend/client/product-modal.d.mts +45 -44
  621. package/dist/modules/product_backend/client/product-modal.d.mts.map +1 -1
  622. package/dist/modules/product_backend/client/product-modal.mjs +1 -1
  623. package/dist/modules/product_backend/client/product-modal.mjs.map +4 -4
  624. package/dist/modules/product_backend/client/product.css +262 -0
  625. package/dist/modules/product_backend/client/variant-editor.d.mts +16 -0
  626. package/dist/modules/product_backend/client/variant-editor.d.mts.map +1 -0
  627. package/dist/modules/product_backend/client/variant-editor.mjs +2 -0
  628. package/dist/modules/product_backend/client/variant-editor.mjs.map +7 -0
  629. package/dist/modules/product_backend/functions.d.ts +3 -0
  630. package/dist/modules/product_backend/functions.d.ts.map +1 -0
  631. package/dist/modules/product_backend/functions.js +29 -0
  632. package/dist/modules/product_backend/functions.js.map +1 -0
  633. package/dist/modules/product_backend/index.d.ts.map +1 -1
  634. package/dist/modules/product_backend/index.js +227 -5
  635. package/dist/modules/product_backend/index.js.map +1 -1
  636. package/dist/modules/product_backend/islands.d.ts +20 -0
  637. package/dist/modules/product_backend/islands.d.ts.map +1 -1
  638. package/dist/modules/product_backend/islands.js +25 -0
  639. package/dist/modules/product_backend/islands.js.map +1 -1
  640. package/dist/modules/product_backend/menus.d.ts.map +1 -1
  641. package/dist/modules/product_backend/menus.js +4 -5
  642. package/dist/modules/product_backend/menus.js.map +1 -1
  643. package/dist/modules/product_backend/modal/attribute-modal-view.d.ts +25 -0
  644. package/dist/modules/product_backend/modal/attribute-modal-view.d.ts.map +1 -0
  645. package/dist/modules/product_backend/modal/attribute-modal-view.js +180 -0
  646. package/dist/modules/product_backend/modal/attribute-modal-view.js.map +1 -0
  647. package/dist/modules/product_backend/modal/product-modal-view.d.ts +25 -6
  648. package/dist/modules/product_backend/modal/product-modal-view.d.ts.map +1 -1
  649. package/dist/modules/product_backend/modal/product-modal-view.js +334 -251
  650. package/dist/modules/product_backend/modal/product-modal-view.js.map +1 -1
  651. package/dist/modules/product_backend/routes.d.ts.map +1 -1
  652. package/dist/modules/product_backend/routes.js +159 -200
  653. package/dist/modules/product_backend/routes.js.map +1 -1
  654. package/dist/modules/product_backend/screens/attributes.d.ts +18 -4
  655. package/dist/modules/product_backend/screens/attributes.d.ts.map +1 -1
  656. package/dist/modules/product_backend/screens/attributes.js +71 -63
  657. package/dist/modules/product_backend/screens/attributes.js.map +1 -1
  658. package/dist/modules/product_backend/screens/list.d.ts +13 -7
  659. package/dist/modules/product_backend/screens/list.d.ts.map +1 -1
  660. package/dist/modules/product_backend/screens/list.js +38 -57
  661. package/dist/modules/product_backend/screens/list.js.map +1 -1
  662. package/dist/modules/product_media/functions.d.ts.map +1 -1
  663. package/dist/modules/product_media/functions.js +2 -0
  664. package/dist/modules/product_media/functions.js.map +1 -1
  665. package/dist/modules/purchase_backend/index.js +116 -208
  666. package/dist/modules/purchase_backend/index.js.map +1 -1
  667. package/dist/modules/purchase_backend/screens/order-list-shared.js +2 -2
  668. package/dist/modules/purchase_backend/screens/order-list-shared.js.map +1 -1
  669. package/dist/modules/purchase_backend/screens/purchase-orders-list.d.ts.map +1 -1
  670. package/dist/modules/purchase_backend/screens/purchase-orders-list.js +11 -13
  671. package/dist/modules/purchase_backend/screens/purchase-orders-list.js.map +1 -1
  672. package/dist/modules/purchase_backend/screens/rfqs-list.d.ts.map +1 -1
  673. package/dist/modules/purchase_backend/screens/rfqs-list.js +10 -15
  674. package/dist/modules/purchase_backend/screens/rfqs-list.js.map +1 -1
  675. package/dist/modules/purchase_backend/screens/vendor-pricelists-list.d.ts.map +1 -1
  676. package/dist/modules/purchase_backend/screens/vendor-pricelists-list.js +11 -21
  677. package/dist/modules/purchase_backend/screens/vendor-pricelists-list.js.map +1 -1
  678. package/dist/modules/purchase_backend/search-functions.d.ts +4 -0
  679. package/dist/modules/purchase_backend/search-functions.d.ts.map +1 -0
  680. package/dist/modules/purchase_backend/search-functions.js +9 -0
  681. package/dist/modules/purchase_backend/search-functions.js.map +1 -0
  682. package/dist/modules/purchase_backend/search.d.ts +128 -0
  683. package/dist/modules/purchase_backend/search.d.ts.map +1 -0
  684. package/dist/modules/purchase_backend/search.js +106 -0
  685. package/dist/modules/purchase_backend/search.js.map +1 -0
  686. package/dist/modules/sale_backend/index.js +83 -32
  687. package/dist/modules/sale_backend/index.js.map +1 -1
  688. package/dist/modules/sale_backend/order-collection.d.ts +7 -0
  689. package/dist/modules/sale_backend/order-collection.d.ts.map +1 -0
  690. package/dist/modules/sale_backend/order-collection.js +27 -0
  691. package/dist/modules/sale_backend/order-collection.js.map +1 -0
  692. package/dist/modules/sale_backend/screens/invoicing-policies-list.d.ts.map +1 -1
  693. package/dist/modules/sale_backend/screens/invoicing-policies-list.js +10 -14
  694. package/dist/modules/sale_backend/screens/invoicing-policies-list.js.map +1 -1
  695. package/dist/modules/sale_backend/screens/overview.js +2 -2
  696. package/dist/modules/sale_backend/screens/overview.js.map +1 -1
  697. package/dist/modules/sale_backend/screens/quotations-list.d.ts.map +1 -1
  698. package/dist/modules/sale_backend/screens/quotations-list.js +12 -23
  699. package/dist/modules/sale_backend/screens/quotations-list.js.map +1 -1
  700. package/dist/modules/sale_backend/screens/sales-orders-list.d.ts.map +1 -1
  701. package/dist/modules/sale_backend/screens/sales-orders-list.js +11 -20
  702. package/dist/modules/sale_backend/screens/sales-orders-list.js.map +1 -1
  703. package/dist/modules/sale_backend/search-functions.d.ts +4 -0
  704. package/dist/modules/sale_backend/search-functions.d.ts.map +1 -0
  705. package/dist/modules/sale_backend/search-functions.js +9 -0
  706. package/dist/modules/sale_backend/search-functions.js.map +1 -0
  707. package/dist/modules/sale_backend/search.d.ts +146 -0
  708. package/dist/modules/sale_backend/search.d.ts.map +1 -0
  709. package/dist/modules/sale_backend/search.js +112 -0
  710. package/dist/modules/sale_backend/search.js.map +1 -0
  711. package/dist/modules/stock_backend/functions.d.ts +10 -0
  712. package/dist/modules/stock_backend/functions.d.ts.map +1 -0
  713. package/dist/modules/stock_backend/functions.js +19 -0
  714. package/dist/modules/stock_backend/functions.js.map +1 -0
  715. package/dist/modules/stock_backend/index.js +33 -10
  716. package/dist/modules/stock_backend/index.js.map +1 -1
  717. package/dist/modules/stock_backend/routes.d.ts.map +1 -1
  718. package/dist/modules/stock_backend/routes.js +168 -59
  719. package/dist/modules/stock_backend/routes.js.map +1 -1
  720. package/dist/modules/stock_backend/screens/locations-list.d.ts.map +1 -1
  721. package/dist/modules/stock_backend/screens/locations-list.js +11 -22
  722. package/dist/modules/stock_backend/screens/locations-list.js.map +1 -1
  723. package/dist/modules/stock_backend/screens/lots-list.d.ts.map +1 -1
  724. package/dist/modules/stock_backend/screens/lots-list.js +11 -13
  725. package/dist/modules/stock_backend/screens/lots-list.js.map +1 -1
  726. package/dist/modules/stock_backend/screens/picking-types-list.d.ts.map +1 -1
  727. package/dist/modules/stock_backend/screens/picking-types-list.js +11 -22
  728. package/dist/modules/stock_backend/screens/picking-types-list.js.map +1 -1
  729. package/dist/modules/stock_backend/screens/replenishment-list.d.ts.map +1 -1
  730. package/dist/modules/stock_backend/screens/replenishment-list.js +11 -22
  731. package/dist/modules/stock_backend/screens/replenishment-list.js.map +1 -1
  732. package/dist/modules/stock_backend/screens/stock-routes-list.d.ts.map +1 -1
  733. package/dist/modules/stock_backend/screens/stock-routes-list.js +12 -23
  734. package/dist/modules/stock_backend/screens/stock-routes-list.js.map +1 -1
  735. package/dist/modules/stock_backend/screens/transfers-list.d.ts.map +1 -1
  736. package/dist/modules/stock_backend/screens/transfers-list.js +12 -23
  737. package/dist/modules/stock_backend/screens/transfers-list.js.map +1 -1
  738. package/dist/modules/stock_backend/screens/warehouses-list.d.ts.map +1 -1
  739. package/dist/modules/stock_backend/screens/warehouses-list.js +11 -22
  740. package/dist/modules/stock_backend/screens/warehouses-list.js.map +1 -1
  741. package/dist/modules/stock_backend/search.d.ts +257 -0
  742. package/dist/modules/stock_backend/search.d.ts.map +1 -0
  743. package/dist/modules/stock_backend/search.js +349 -0
  744. package/dist/modules/stock_backend/search.js.map +1 -0
  745. package/dist/modules/storage/functions.d.ts.map +1 -1
  746. package/dist/modules/storage/functions.js +28 -5
  747. package/dist/modules/storage/functions.js.map +1 -1
  748. package/dist/modules/storage/jobs.d.ts.map +1 -1
  749. package/dist/modules/storage/jobs.js +120 -2
  750. package/dist/modules/storage/jobs.js.map +1 -1
  751. package/dist/modules/storage/models.d.ts.map +1 -1
  752. package/dist/modules/storage/models.js +21 -0
  753. package/dist/modules/storage/models.js.map +1 -1
  754. package/dist/modules/storage/policy.d.ts +27 -0
  755. package/dist/modules/storage/policy.d.ts.map +1 -1
  756. package/dist/modules/storage/policy.js +14 -0
  757. package/dist/modules/storage/policy.js.map +1 -1
  758. package/dist/modules/storage/routes.d.ts +1 -0
  759. package/dist/modules/storage/routes.d.ts.map +1 -1
  760. package/dist/modules/storage/routes.js +36 -10
  761. package/dist/modules/storage/routes.js.map +1 -1
  762. package/dist/modules/user/access-denial.d.ts +3 -0
  763. package/dist/modules/user/access-denial.d.ts.map +1 -0
  764. package/dist/modules/user/access-denial.js +34 -0
  765. package/dist/modules/user/access-denial.js.map +1 -0
  766. package/dist/modules/user/access-policy.d.ts +16 -0
  767. package/dist/modules/user/access-policy.d.ts.map +1 -0
  768. package/dist/modules/user/access-policy.js +455 -0
  769. package/dist/modules/user/access-policy.js.map +1 -0
  770. package/dist/modules/user/access-surfaces.d.ts +26 -0
  771. package/dist/modules/user/access-surfaces.d.ts.map +1 -0
  772. package/dist/modules/user/access-surfaces.js +76 -0
  773. package/dist/modules/user/access-surfaces.js.map +1 -0
  774. package/dist/modules/user/authorization.d.ts +12 -1
  775. package/dist/modules/user/authorization.d.ts.map +1 -1
  776. package/dist/modules/user/authorization.js +342 -36
  777. package/dist/modules/user/authorization.js.map +1 -1
  778. package/dist/modules/user/functions.d.ts.map +1 -1
  779. package/dist/modules/user/functions.js +26 -3
  780. package/dist/modules/user/functions.js.map +1 -1
  781. package/dist/modules/user/index.d.ts.map +1 -1
  782. package/dist/modules/user/index.js +13 -1
  783. package/dist/modules/user/index.js.map +1 -1
  784. package/dist/modules/user/modal-labels.d.ts +3 -0
  785. package/dist/modules/user/modal-labels.d.ts.map +1 -0
  786. package/dist/modules/user/modal-labels.js +30 -0
  787. package/dist/modules/user/modal-labels.js.map +1 -0
  788. package/dist/modules/user/modal-messages.d.ts +4 -0
  789. package/dist/modules/user/modal-messages.d.ts.map +1 -0
  790. package/dist/modules/user/modal-messages.js +15 -0
  791. package/dist/modules/user/modal-messages.js.map +1 -0
  792. package/dist/modules/user/models.d.ts.map +1 -1
  793. package/dist/modules/user/models.js +48 -0
  794. package/dist/modules/user/models.js.map +1 -1
  795. package/dist/modules/user/permission-areas.d.ts +20 -0
  796. package/dist/modules/user/permission-areas.d.ts.map +1 -0
  797. package/dist/modules/user/permission-areas.js +89 -0
  798. package/dist/modules/user/permission-areas.js.map +1 -0
  799. package/dist/modules/user/policy-jobs.d.ts +4 -0
  800. package/dist/modules/user/policy-jobs.d.ts.map +1 -0
  801. package/dist/modules/user/policy-jobs.js +15 -0
  802. package/dist/modules/user/policy-jobs.js.map +1 -0
  803. package/dist/modules/user/role-modal-context.d.ts +3 -0
  804. package/dist/modules/user/role-modal-context.d.ts.map +1 -0
  805. package/dist/modules/user/role-modal-context.js +264 -0
  806. package/dist/modules/user/role-modal-context.js.map +1 -0
  807. package/dist/modules/user/roles.d.ts.map +1 -1
  808. package/dist/modules/user/roles.js +2 -0
  809. package/dist/modules/user/roles.js.map +1 -1
  810. package/dist/modules/user/user-modal-context.d.ts +5 -1
  811. package/dist/modules/user/user-modal-context.d.ts.map +1 -1
  812. package/dist/modules/user/user-modal-context.js +227 -31
  813. package/dist/modules/user/user-modal-context.js.map +1 -1
  814. package/dist/modules/user_backend/access-options.d.ts +25 -0
  815. package/dist/modules/user_backend/access-options.d.ts.map +1 -0
  816. package/dist/modules/user_backend/access-options.js +38 -0
  817. package/dist/modules/user_backend/access-options.js.map +1 -0
  818. package/dist/modules/user_backend/access-policy-routes.d.ts +3 -0
  819. package/dist/modules/user_backend/access-policy-routes.d.ts.map +1 -0
  820. package/dist/modules/user_backend/access-policy-routes.js +76 -0
  821. package/dist/modules/user_backend/access-policy-routes.js.map +1 -0
  822. package/dist/modules/user_backend/client/access-policy-modal.d.mts +123 -0
  823. package/dist/modules/user_backend/client/access-policy-modal.d.mts.map +1 -0
  824. package/dist/modules/user_backend/client/access-policy-modal.mjs +2 -0
  825. package/dist/modules/user_backend/client/access-policy-modal.mjs.map +7 -0
  826. package/dist/modules/user_backend/client/role-modal.d.mts +103 -0
  827. package/dist/modules/user_backend/client/role-modal.d.mts.map +1 -0
  828. package/dist/modules/user_backend/client/role-modal.mjs +2 -0
  829. package/dist/modules/user_backend/client/role-modal.mjs.map +7 -0
  830. package/dist/modules/user_backend/client/user-modal.d.mts +160 -7
  831. package/dist/modules/user_backend/client/user-modal.d.mts.map +1 -1
  832. package/dist/modules/user_backend/client/user-modal.mjs +1 -1
  833. package/dist/modules/user_backend/client/user-modal.mjs.map +4 -4
  834. package/dist/modules/user_backend/index.d.ts +2 -2
  835. package/dist/modules/user_backend/index.d.ts.map +1 -1
  836. package/dist/modules/user_backend/index.js +4 -2
  837. package/dist/modules/user_backend/index.js.map +1 -1
  838. package/dist/modules/user_backend/islands.d.ts +14 -1
  839. package/dist/modules/user_backend/islands.d.ts.map +1 -1
  840. package/dist/modules/user_backend/islands.js +11 -3
  841. package/dist/modules/user_backend/islands.js.map +1 -1
  842. package/dist/modules/user_backend/managed-role-routes.d.ts +3 -0
  843. package/dist/modules/user_backend/managed-role-routes.d.ts.map +1 -0
  844. package/dist/modules/user_backend/managed-role-routes.js +44 -0
  845. package/dist/modules/user_backend/managed-role-routes.js.map +1 -0
  846. package/dist/modules/user_backend/menus.d.ts.map +1 -1
  847. package/dist/modules/user_backend/menus.js +9 -7
  848. package/dist/modules/user_backend/menus.js.map +1 -1
  849. package/dist/modules/user_backend/messages.d.ts +510 -2
  850. package/dist/modules/user_backend/messages.d.ts.map +1 -1
  851. package/dist/modules/user_backend/messages.js +552 -44
  852. package/dist/modules/user_backend/messages.js.map +1 -1
  853. package/dist/modules/user_backend/modal/access-policy-modal-view.d.ts +43 -0
  854. package/dist/modules/user_backend/modal/access-policy-modal-view.d.ts.map +1 -0
  855. package/dist/modules/user_backend/modal/access-policy-modal-view.js +384 -0
  856. package/dist/modules/user_backend/modal/access-policy-modal-view.js.map +1 -0
  857. package/dist/modules/user_backend/modal/access-surfaces.d.ts +51 -0
  858. package/dist/modules/user_backend/modal/access-surfaces.d.ts.map +1 -0
  859. package/dist/modules/user_backend/modal/access-surfaces.js +138 -0
  860. package/dist/modules/user_backend/modal/access-surfaces.js.map +1 -0
  861. package/dist/modules/user_backend/modal/role-modal-view.d.ts +48 -0
  862. package/dist/modules/user_backend/modal/role-modal-view.d.ts.map +1 -0
  863. package/dist/modules/user_backend/modal/role-modal-view.js +488 -0
  864. package/dist/modules/user_backend/modal/role-modal-view.js.map +1 -0
  865. package/dist/modules/user_backend/modal/user-modal-view.d.ts +45 -0
  866. package/dist/modules/user_backend/modal/user-modal-view.d.ts.map +1 -1
  867. package/dist/modules/user_backend/modal/user-modal-view.js +1317 -71
  868. package/dist/modules/user_backend/modal/user-modal-view.js.map +1 -1
  869. package/dist/modules/user_backend/routes.d.ts.map +1 -1
  870. package/dist/modules/user_backend/routes.js +109 -571
  871. package/dist/modules/user_backend/routes.js.map +1 -1
  872. package/dist/modules/user_backend/screens/access-policies-list.d.ts +31 -0
  873. package/dist/modules/user_backend/screens/access-policies-list.d.ts.map +1 -0
  874. package/dist/modules/user_backend/screens/access-policies-list.js +54 -0
  875. package/dist/modules/user_backend/screens/access-policies-list.js.map +1 -0
  876. package/dist/modules/user_backend/screens/index.d.ts +1 -3
  877. package/dist/modules/user_backend/screens/index.d.ts.map +1 -1
  878. package/dist/modules/user_backend/screens/index.js +2 -3
  879. package/dist/modules/user_backend/screens/index.js.map +1 -1
  880. package/dist/modules/user_backend/screens/roles-list.d.ts +9 -3
  881. package/dist/modules/user_backend/screens/roles-list.d.ts.map +1 -1
  882. package/dist/modules/user_backend/screens/roles-list.js +15 -23
  883. package/dist/modules/user_backend/screens/roles-list.js.map +1 -1
  884. package/dist/modules/user_backend/screens/users-list.d.ts +7 -5
  885. package/dist/modules/user_backend/screens/users-list.d.ts.map +1 -1
  886. package/dist/modules/user_backend/screens/users-list.js +29 -21
  887. package/dist/modules/user_backend/screens/users-list.js.map +1 -1
  888. package/dist/modules/user_backend/search-functions.d.ts +4 -0
  889. package/dist/modules/user_backend/search-functions.d.ts.map +1 -0
  890. package/dist/modules/user_backend/search-functions.js +13 -0
  891. package/dist/modules/user_backend/search-functions.js.map +1 -0
  892. package/dist/modules/user_backend/search.d.ts +128 -0
  893. package/dist/modules/user_backend/search.d.ts.map +1 -0
  894. package/dist/modules/user_backend/search.js +131 -0
  895. package/dist/modules/user_backend/search.js.map +1 -0
  896. package/dist/modules/website/cms.d.ts.map +1 -1
  897. package/dist/modules/website/cms.js +17 -7
  898. package/dist/modules/website/cms.js.map +1 -1
  899. package/dist/modules/website/customer.d.ts +61 -1
  900. package/dist/modules/website/customer.d.ts.map +1 -1
  901. package/dist/modules/website/customer.js +197 -15
  902. package/dist/modules/website/customer.js.map +1 -1
  903. package/dist/modules/website/index.d.ts.map +1 -1
  904. package/dist/modules/website/index.js +16 -2
  905. package/dist/modules/website/index.js.map +1 -1
  906. package/dist/modules/website/models.d.ts.map +1 -1
  907. package/dist/modules/website/models.js +15 -0
  908. package/dist/modules/website/models.js.map +1 -1
  909. package/dist/modules/website/publication.d.ts.map +1 -1
  910. package/dist/modules/website/publication.js +11 -5
  911. package/dist/modules/website/publication.js.map +1 -1
  912. package/dist/modules/website_backend/collection.d.ts +12 -0
  913. package/dist/modules/website_backend/collection.d.ts.map +1 -0
  914. package/dist/modules/website_backend/collection.js +17 -0
  915. package/dist/modules/website_backend/collection.js.map +1 -0
  916. package/dist/modules/website_backend/functions.d.ts +10 -0
  917. package/dist/modules/website_backend/functions.d.ts.map +1 -0
  918. package/dist/modules/website_backend/functions.js +37 -0
  919. package/dist/modules/website_backend/functions.js.map +1 -0
  920. package/dist/modules/website_backend/index.js +2 -0
  921. package/dist/modules/website_backend/index.js.map +1 -1
  922. package/dist/modules/website_backend/routes.d.ts.map +1 -1
  923. package/dist/modules/website_backend/routes.js +124 -29
  924. package/dist/modules/website_backend/routes.js.map +1 -1
  925. package/dist/modules/website_backend/screens/index.d.ts +4 -8
  926. package/dist/modules/website_backend/screens/index.d.ts.map +1 -1
  927. package/dist/modules/website_backend/screens/index.js +685 -666
  928. package/dist/modules/website_backend/screens/index.js.map +1 -1
  929. package/dist/modules/website_backend/screens/page-frame.d.ts +6 -3
  930. package/dist/modules/website_backend/screens/page-frame.d.ts.map +1 -1
  931. package/dist/modules/website_backend/screens/page-frame.js +3 -3
  932. package/dist/modules/website_backend/screens/page-frame.js.map +1 -1
  933. package/dist/modules/website_backend/search.d.ts +125 -0
  934. package/dist/modules/website_backend/search.d.ts.map +1 -0
  935. package/dist/modules/website_backend/search.js +135 -0
  936. package/dist/modules/website_backend/search.js.map +1 -0
  937. package/dist/permission-catalogue.d.ts.map +1 -1
  938. package/dist/permission-catalogue.js +178 -24
  939. package/dist/permission-catalogue.js.map +1 -1
  940. package/dist/phone.d.ts +32 -0
  941. package/dist/phone.d.ts.map +1 -0
  942. package/dist/phone.js +101 -0
  943. package/dist/phone.js.map +1 -0
  944. package/dist/role-templates.d.ts +79 -0
  945. package/dist/role-templates.d.ts.map +1 -0
  946. package/dist/role-templates.js +192 -0
  947. package/dist/role-templates.js.map +1 -0
  948. package/dist/scaffold/index.d.ts +1 -1
  949. package/dist/scaffold/index.d.ts.map +1 -1
  950. package/dist/scaffold/index.js +10 -5
  951. package/dist/scaffold/index.js.map +1 -1
  952. package/dist/scaffold/templates/README.md.tmpl +2 -1
  953. package/dist/scaffold/templates/ket.workspace.mjs.tmpl +4 -1
  954. package/dist/scaffold/templates/package.json.tmpl +2 -2
  955. package/dist/ui/actions.d.ts +2 -0
  956. package/dist/ui/actions.d.ts.map +1 -1
  957. package/dist/ui/actions.js +1 -1
  958. package/dist/ui/actions.js.map +1 -1
  959. package/dist/ui/chrome.d.ts +19 -6
  960. package/dist/ui/chrome.d.ts.map +1 -1
  961. package/dist/ui/chrome.js +12 -7
  962. package/dist/ui/chrome.js.map +1 -1
  963. package/dist/ui/client/bulk-selection.d.ts +7 -0
  964. package/dist/ui/client/bulk-selection.d.ts.map +1 -0
  965. package/dist/ui/client/bulk-selection.js +67 -0
  966. package/dist/ui/client/bulk-selection.js.map +1 -0
  967. package/dist/ui/client/ket-table-view.d.ts +3 -0
  968. package/dist/ui/client/ket-table-view.d.ts.map +1 -0
  969. package/dist/ui/client/ket-table-view.js +27 -0
  970. package/dist/ui/client/ket-table-view.js.map +1 -0
  971. package/dist/ui/client/live-doc-shell.d.ts +39 -1
  972. package/dist/ui/client/live-doc-shell.d.ts.map +1 -1
  973. package/dist/ui/client/live-doc-shell.js +41 -2
  974. package/dist/ui/client/live-doc-shell.js.map +1 -1
  975. package/dist/ui/client/live-doc-view.d.ts +29 -1
  976. package/dist/ui/client/live-doc-view.d.ts.map +1 -1
  977. package/dist/ui/client/live-doc-view.js +138 -4
  978. package/dist/ui/client/live-doc-view.js.map +1 -1
  979. package/dist/ui/client/live-doc.d.mts +8 -4
  980. package/dist/ui/client/live-doc.d.mts.map +1 -1
  981. package/dist/ui/client/live-doc.mjs +10 -10
  982. package/dist/ui/client/live-doc.mjs.map +3 -3
  983. package/dist/ui/client/record-modal-form.d.ts +34 -0
  984. package/dist/ui/client/record-modal-form.d.ts.map +1 -1
  985. package/dist/ui/client/record-modal-form.js +17 -1
  986. package/dist/ui/client/record-modal-form.js.map +1 -1
  987. package/dist/ui/client/record-modal.d.ts +56 -6
  988. package/dist/ui/client/record-modal.d.ts.map +1 -1
  989. package/dist/ui/client/record-modal.js +235 -39
  990. package/dist/ui/client/record-modal.js.map +1 -1
  991. package/dist/ui/client/search-filter-view.d.ts +2 -0
  992. package/dist/ui/client/search-filter-view.d.ts.map +1 -0
  993. package/dist/ui/client/search-filter-view.js +6 -0
  994. package/dist/ui/client/search-filter-view.js.map +1 -0
  995. package/dist/ui/client/table-selection-view.d.ts.map +1 -1
  996. package/dist/ui/client/table-selection-view.js +33 -16
  997. package/dist/ui/client/table-selection-view.js.map +1 -1
  998. package/dist/ui/client/user-modal-client.d.ts +6 -0
  999. package/dist/ui/client/user-modal-client.d.ts.map +1 -0
  1000. package/dist/ui/client/user-modal-client.js +4 -0
  1001. package/dist/ui/client/user-modal-client.js.map +1 -0
  1002. package/dist/ui/client/user-workflow.d.ts.map +1 -1
  1003. package/dist/ui/client/user-workflow.js +4 -3
  1004. package/dist/ui/client/user-workflow.js.map +1 -1
  1005. package/dist/ui/client/variant-attribute-create.d.ts +19 -0
  1006. package/dist/ui/client/variant-attribute-create.d.ts.map +1 -0
  1007. package/dist/ui/client/variant-attribute-create.js +177 -0
  1008. package/dist/ui/client/variant-attribute-create.js.map +1 -0
  1009. package/dist/ui/client/variant-editor-view.d.ts +72 -0
  1010. package/dist/ui/client/variant-editor-view.d.ts.map +1 -0
  1011. package/dist/ui/client/variant-editor-view.js +943 -0
  1012. package/dist/ui/client/variant-editor-view.js.map +1 -0
  1013. package/dist/ui/collection-state.d.ts +11 -0
  1014. package/dist/ui/collection-state.d.ts.map +1 -0
  1015. package/dist/ui/collection-state.js +45 -0
  1016. package/dist/ui/collection-state.js.map +1 -0
  1017. package/dist/ui/collection.d.ts +23 -0
  1018. package/dist/ui/collection.d.ts.map +1 -0
  1019. package/dist/ui/collection.js +118 -0
  1020. package/dist/ui/collection.js.map +1 -0
  1021. package/dist/ui/form.d.ts +1 -1
  1022. package/dist/ui/form.d.ts.map +1 -1
  1023. package/dist/ui/form.js +1 -1
  1024. package/dist/ui/form.js.map +1 -1
  1025. package/dist/ui/index.d.ts +3 -1
  1026. package/dist/ui/index.d.ts.map +1 -1
  1027. package/dist/ui/index.js +3 -1
  1028. package/dist/ui/index.js.map +1 -1
  1029. package/dist/ui/layout.d.ts +6 -7
  1030. package/dist/ui/layout.d.ts.map +1 -1
  1031. package/dist/ui/layout.js +25 -10
  1032. package/dist/ui/layout.js.map +1 -1
  1033. package/dist/ui/list-page.d.ts +4 -2
  1034. package/dist/ui/list-page.d.ts.map +1 -1
  1035. package/dist/ui/list-page.js +29 -4
  1036. package/dist/ui/list-page.js.map +1 -1
  1037. package/dist/ui/nav.d.ts +2 -3
  1038. package/dist/ui/nav.d.ts.map +1 -1
  1039. package/dist/ui/nav.js +4 -8
  1040. package/dist/ui/nav.js.map +1 -1
  1041. package/dist/ui/navigation.d.ts +1 -0
  1042. package/dist/ui/navigation.d.ts.map +1 -1
  1043. package/dist/ui/navigation.js +3 -3
  1044. package/dist/ui/navigation.js.map +1 -1
  1045. package/dist/ui/table.d.ts +2 -0
  1046. package/dist/ui/table.d.ts.map +1 -1
  1047. package/dist/ui/table.js +24 -0
  1048. package/dist/ui/table.js.map +1 -1
  1049. package/dist/ui/user-workflow.d.ts +2 -1
  1050. package/dist/ui/user-workflow.d.ts.map +1 -1
  1051. package/dist/ui/user-workflow.js +44 -29
  1052. package/dist/ui/user-workflow.js.map +1 -1
  1053. package/package.json +14 -4
  1054. package/dist/modules/user_backend/access-routes.d.ts +0 -31
  1055. package/dist/modules/user_backend/access-routes.d.ts.map +0 -1
  1056. package/dist/modules/user_backend/access-routes.js +0 -447
  1057. package/dist/modules/user_backend/access-routes.js.map +0 -1
  1058. package/dist/modules/user_backend/screens/presets-form.d.ts +0 -16
  1059. package/dist/modules/user_backend/screens/presets-form.d.ts.map +0 -1
  1060. package/dist/modules/user_backend/screens/presets-form.js +0 -37
  1061. package/dist/modules/user_backend/screens/presets-form.js.map +0 -1
  1062. package/dist/modules/user_backend/screens/role-form.d.ts +0 -21
  1063. package/dist/modules/user_backend/screens/role-form.d.ts.map +0 -1
  1064. package/dist/modules/user_backend/screens/role-form.js +0 -93
  1065. package/dist/modules/user_backend/screens/role-form.js.map +0 -1
  1066. package/dist/modules/user_backend/screens/user-form.d.ts +0 -56
  1067. package/dist/modules/user_backend/screens/user-form.d.ts.map +0 -1
  1068. package/dist/modules/user_backend/screens/user-form.js +0 -202
  1069. package/dist/modules/user_backend/screens/user-form.js.map +0 -1
  1070. package/dist/ui/client/relation-select-view.d.ts +0 -77
  1071. package/dist/ui/client/relation-select-view.d.ts.map +0 -1
  1072. package/dist/ui/client/relation-select-view.js +0 -216
  1073. package/dist/ui/client/relation-select-view.js.map +0 -1
@@ -8,9 +8,11 @@
8
8
  // that decides whether a login may exist, where it works and what it may do.
9
9
  //
10
10
  // Bundled by tools/build-backend-client.mjs into user_backend/client/.
11
- import { Badge, Button, DataTable, DescriptionList, Notice, RecordSummary, Section, Stack, } from '@ketvietlab/design-system';
12
- import { createRecordModal } from '../../../ui/client/record-modal.js';
11
+ import { Badge, Button, DataTable, Disclosure, DescriptionList, Notice, LinkButton, Section, Stack, } from '@ketvietlab/design-system';
12
+ import { createRecordModal, RECORD_COMMAND_FIELD } from '../../../ui/client/record-modal.js';
13
+ import { USER_RECORD_MODAL_LABELS } from '../../user/modal-labels.js';
13
14
  import { RecordDialogTrigger, RecordModalForm, recordStateSelectControl, } from '../../../ui/client/record-modal-form.js';
15
+ import { SurfaceAccessView, SurfaceChangeTable } from './access-surfaces.js';
14
16
  const ACCESS_KINDS = ['internal', 'portal', 'public'];
15
17
  const uuid = () => typeof crypto !== 'undefined' && 'randomUUID' in crypto
16
18
  ? crypto.randomUUID()
@@ -65,12 +67,32 @@ const stateSelect = (c, props) => {
65
67
  };
66
68
  const roleFieldName = (roleId) => `role_${roleId}`;
67
69
  const selectedRoles = (form, roles) => roles.map((role) => String(role.id)).filter((id) => checked(form, roleFieldName(id)));
70
+ /** Who is reading this record is the person in it. Nobody changes their own authority. */
71
+ const readingSelf = (c) => c.data.actor?.self === true;
72
+ const actorSuperuser = (c) => c.data.actor?.superuser === true;
73
+ /** A role that hands out authority over authority. Only a superuser may give it. */
74
+ const securityTier = (role) => String(role.tier ?? '') === 'security';
75
+ /**
76
+ * The roles a form offers, each on its own line.
77
+ *
78
+ * A security-tier role is named as one and, for anyone but a superuser, offered
79
+ * disabled rather than hidden: the reader sees it exists and why it is not theirs
80
+ * to give, instead of wondering where it went.
81
+ */
82
+ const roleOptions = (c, isChecked) => c.data.roles.map((role) => ({
83
+ name: roleFieldName(String(role.id)),
84
+ value: '1',
85
+ label: securityTier(role) ? `${String(role.name)} · ${t(c, 'role.tier.security')}` : String(role.name),
86
+ checked: isChecked(String(role.id)),
87
+ disabled: securityTier(role) && !actorSuperuser(c),
88
+ }));
89
+ /** Why some offered roles cannot be ticked, when that is the case. */
90
+ const roleHelp = (c, fallback) => c.data.roles.some(securityTier) && !actorSuperuser(c) ? t(c, 'access.securityTierHint') : fallback;
68
91
  /**
69
92
  * The form that hires someone.
70
93
  *
71
94
  * It asks for the whole decision at once — who they are, where they work, what
72
- * they do and why — because that is the request being made, and because the
73
- * reason is what the audit of their new authority will carry.
95
+ * they do. The server records the resulting authority change in its audit.
74
96
  */
75
97
  const createFields = (c) => {
76
98
  const scopeKind = c.state('scopeKind', 'branch');
@@ -78,7 +100,13 @@ const createFields = (c) => {
78
100
  return [
79
101
  field(c, { name: 'name', label: t(c, 'field.name'), required: true }),
80
102
  field(c, { name: 'login', label: t(c, 'field.login'), required: true }),
81
- field(c, { name: 'email', label: t(c, 'field.email'), type: 'email', required: true, span: 'full' }),
103
+ field(c, {
104
+ name: 'email',
105
+ label: t(c, 'field.email'),
106
+ type: 'email',
107
+ required: true,
108
+ span: 'full',
109
+ }),
82
110
  stateSelect(c, {
83
111
  name: 'scopeKind',
84
112
  label: t(c, 'field.scope'),
@@ -112,76 +140,264 @@ const createFields = (c) => {
112
140
  required: true,
113
141
  options: c.data.branches
114
142
  .filter((branch) => String(branch.companyId) === companyId)
115
- .map((branch) => ({ value: String(branch.id), label: String(branch.name) })),
143
+ .map((branch) => ({
144
+ value: String(branch.id),
145
+ label: String(branch.name),
146
+ })),
116
147
  }),
117
148
  ]
118
149
  : []),
150
+ // Roles are optional: someone created without one holds no function until a
151
+ // role is assigned, and there may be none to offer yet.
152
+ ...(c.data.roles.length
153
+ ? [
154
+ field(c, {
155
+ name: 'roleIds',
156
+ label: t(c, 'field.jobRoles'),
157
+ type: 'checkbox-group',
158
+ span: 'full',
159
+ help: roleHelp(c, t(c, 'users.rolesOptionalHint')),
160
+ // One role per line: a person can hold several, and a row of boxes hides that.
161
+ optionsOrientation: 'vertical',
162
+ // What was ticked before a refusal comes back ticked.
163
+ options: roleOptions(c, (roleId) => c.draftChecked(roleFieldName(roleId))),
164
+ }),
165
+ ]
166
+ : []),
167
+ ];
168
+ };
169
+ const createView = (c) => Stack({
170
+ gap: 'default',
171
+ items: [
172
+ // No role to offer does not stop the hire; it says why the person will start
173
+ // with no access.
174
+ ...(c.data.roles.length
175
+ ? []
176
+ : [
177
+ Notice({
178
+ tone: 'info',
179
+ title: t(c, 'access.noAssignableRoles'),
180
+ message: t(c, 'users.createWithoutRolesHint'),
181
+ }),
182
+ ]),
183
+ Section({
184
+ title: t(c, 'users.newTitle'),
185
+ body: RecordModalForm({
186
+ kind: c.kind,
187
+ fields: createFields(c),
188
+ command: 'create',
189
+ actions: [
190
+ Button({
191
+ label: t(c, 'action.createUser'),
192
+ variant: 'primary',
193
+ type: 'submit',
194
+ }),
195
+ ],
196
+ }),
197
+ }),
198
+ ],
199
+ });
200
+ const profileFields = (c) => [
201
+ field(c, {
202
+ name: 'name',
203
+ label: t(c, 'field.name'),
204
+ value: c.data.record.name,
205
+ required: true,
206
+ }),
207
+ field(c, {
208
+ name: 'login',
209
+ label: t(c, 'field.login'),
210
+ value: c.data.record.login,
211
+ required: true,
212
+ }),
213
+ field(c, {
214
+ name: 'email',
215
+ label: t(c, 'field.email'),
216
+ type: 'email',
217
+ value: c.data.record.email,
218
+ }),
219
+ field(c, {
220
+ name: 'accessKind',
221
+ label: t(c, 'field.accessKind'),
222
+ type: 'select',
223
+ value: c.data.record.accessKind,
224
+ options: ACCESS_KINDS.map((kind) => ({
225
+ value: kind,
226
+ label: t(c, `access.${kind}`),
227
+ })),
228
+ }),
229
+ field(c, {
230
+ name: 'active',
231
+ label: t(c, 'state.active'),
232
+ type: 'checkbox',
233
+ value: c.data.record.active,
234
+ }),
235
+ ];
236
+ const companyFieldName = (companyId) => `company_${companyId}`;
237
+ const branchFieldName = (branchId) => `branch_${branchId}`;
238
+ const selectedIds = (form, rows, name) => rows.map((row) => String(row.id)).filter((id) => checked(form, name(id)));
239
+ /**
240
+ * Where this person works, edited as one decision.
241
+ *
242
+ * Companies, branches and the workplace they land in are one answer, not five, so
243
+ * they are one form and one command. Holding a company always carries its root
244
+ * branch, which is why a company can be ticked without naming any branch.
245
+ */
246
+ const workplaceFields = (c) => {
247
+ const companies = c.data.memberships.companies;
248
+ const branches = c.data.memberships.branches;
249
+ const chosenCompanies = c.data.companies.filter((company) => c.draftChecked(companyFieldName(String(company.id)), '1', companies.includes(String(company.id))));
250
+ const chosen = new Set(chosenCompanies.map((company) => String(company.id)));
251
+ const offeredBranches = c.data.branches.filter((branch) => chosen.has(String(branch.companyId)));
252
+ return [
119
253
  field(c, {
120
- name: 'roleIds',
121
- label: t(c, 'field.jobRoles'),
254
+ name: 'companies',
255
+ label: t(c, 'field.companies'),
122
256
  type: 'checkbox-group',
123
257
  required: true,
124
258
  span: 'full',
125
- // One role per line: a person can hold several, and a row of boxes hides that.
126
259
  optionsOrientation: 'vertical',
127
- options: c.data.roles.map((role) => ({
128
- name: roleFieldName(String(role.id)),
260
+ options: c.data.companies.map((company) => ({
261
+ name: companyFieldName(String(company.id)),
129
262
  value: '1',
130
- label: String(role.name),
131
- // What was ticked before a refusal comes back ticked.
132
- checked: c.draftChecked(roleFieldName(String(role.id))),
263
+ label: String(company.name),
264
+ checked: companies.includes(String(company.id)),
133
265
  })),
134
266
  }),
135
267
  field(c, {
136
- name: 'reason',
137
- label: t(c, 'field.reason'),
138
- type: 'textarea',
139
- required: true,
268
+ name: 'branches',
269
+ label: t(c, 'field.branches'),
270
+ type: 'checkbox-group',
140
271
  span: 'full',
272
+ optionsOrientation: 'vertical',
273
+ options: offeredBranches.map((branch) => ({
274
+ name: branchFieldName(String(branch.id)),
275
+ value: '1',
276
+ label: `${String(branch.name)} · ${String(c.data.companies.find((company) => String(company.id) === String(branch.companyId))?.name ?? '')}`,
277
+ checked: branches.includes(String(branch.id)),
278
+ })),
279
+ }),
280
+ field(c, {
281
+ name: 'defaultCompanyId',
282
+ label: t(c, 'field.defaultCompany'),
283
+ type: 'select',
284
+ required: true,
285
+ value: c.data.record.defaultCompanyId ?? String(chosenCompanies[0]?.id ?? ''),
286
+ options: chosenCompanies.map((company) => ({
287
+ value: String(company.id),
288
+ label: String(company.name),
289
+ })),
290
+ }),
291
+ field(c, {
292
+ name: 'defaultBranchId',
293
+ label: t(c, 'field.defaultBranch'),
294
+ type: 'select',
295
+ required: true,
296
+ value: c.data.record.defaultBranchId ?? '',
297
+ options: offeredBranches.map((branch) => ({
298
+ value: String(branch.id),
299
+ label: String(branch.name),
300
+ })),
141
301
  }),
142
302
  ];
143
303
  };
144
- const createView = (c) => Section({
145
- title: t(c, 'users.newTitle'),
146
- body: RecordModalForm({
147
- kind: c.kind,
148
- fields: createFields(c),
149
- command: 'create',
150
- actions: [Button({ label: t(c, 'action.createUser'), variant: 'primary', type: 'submit' })],
151
- }),
152
- });
153
- const profileFields = (c) => [
154
- field(c, { name: 'name', label: t(c, 'field.name'), value: c.data.record.name, required: true }),
155
- field(c, { name: 'login', label: t(c, 'field.login'), value: c.data.record.login, required: true }),
156
- field(c, { name: 'email', label: t(c, 'field.email'), type: 'email', value: c.data.record.email }),
157
- field(c, {
158
- name: 'accessKind',
159
- label: t(c, 'field.accessKind'),
160
- type: 'select',
161
- value: c.data.record.accessKind,
162
- options: ACCESS_KINDS.map((kind) => ({ value: kind, label: t(c, `access.${kind}`) })),
163
- }),
164
- field(c, { name: 'active', label: t(c, 'state.active'), type: 'checkbox', value: c.data.record.active }),
165
- ];
304
+ /**
305
+ * What leaving a workplace takes with it.
306
+ *
307
+ * A role held at a company or branch the person no longer works at is authority
308
+ * nobody can see a use for; saving the new workplaces removes it too. The preview
309
+ * names those roles first, so the removal is read before it is made.
310
+ */
311
+ const workplacePreview = (c) => {
312
+ const preview = c.outcome('previewWorkplaces');
313
+ if (!preview)
314
+ return '';
315
+ if (!preview.ok)
316
+ return Notice({ tone: 'warning', title: t(c, 'preview.unavailable'), message: '' });
317
+ const removed = preview.removed ?? [];
318
+ return removed.length
319
+ ? Stack({
320
+ gap: 'compact',
321
+ items: [
322
+ Notice({
323
+ tone: 'warning',
324
+ title: t(c, 'workplace.removesTitle').replace('{count}', String(removed.length)),
325
+ message: t(c, 'workplace.removesHint'),
326
+ }),
327
+ DataTable({
328
+ rows: removed,
329
+ id: (row) => String(row.id),
330
+ columns: [
331
+ {
332
+ key: 'role',
333
+ label: t(c, 'field.assignment'),
334
+ priority: 'primary',
335
+ cell: (row) => String(row.roleName),
336
+ },
337
+ { key: 'scope', label: t(c, 'field.scope'), cell: (row) => scopeName(c, row) },
338
+ ],
339
+ }),
340
+ ],
341
+ })
342
+ : Notice({ tone: 'info', title: t(c, 'workplace.keepsAll'), message: '' });
343
+ };
344
+ /** Where this person works. Where removals can be previewed, they are read before saving. */
345
+ const workplaceForm = (c) => {
346
+ const previewing = c.data.permissions.previewWorkplaces === true;
347
+ return Stack({
348
+ gap: 'default',
349
+ items: [
350
+ RecordModalForm({
351
+ kind: c.kind,
352
+ fields: workplaceFields(c),
353
+ command: previewing ? null : 'setWorkplaces',
354
+ actions: previewing
355
+ ? [
356
+ Button({
357
+ label: t(c, 'action.previewWorkplaces'),
358
+ variant: 'secondary',
359
+ type: 'submit',
360
+ name: RECORD_COMMAND_FIELD,
361
+ value: 'previewWorkplaces',
362
+ }),
363
+ ...(c.outcome('previewWorkplaces')
364
+ ? [
365
+ Button({
366
+ label: t(c, 'action.saveWorkplaces'),
367
+ variant: 'primary',
368
+ type: 'submit',
369
+ name: RECORD_COMMAND_FIELD,
370
+ value: 'setWorkplaces',
371
+ }),
372
+ ]
373
+ : []),
374
+ ]
375
+ : [
376
+ Button({
377
+ label: t(c, 'action.saveWorkplaces'),
378
+ variant: 'primary',
379
+ type: 'submit',
380
+ }),
381
+ ],
382
+ }),
383
+ workplacePreview(c),
384
+ ],
385
+ });
386
+ };
166
387
  /** The person, named once at the top of every tab, with the state that decides access. */
167
388
  const header = (c) => c.creating
168
389
  ? ''
169
390
  : Stack({
170
391
  gap: 'compact',
171
392
  items: [
172
- RecordSummary({
173
- title: c.data.record.name || c.data.record.login,
174
- subtitle: c.data.record.login,
175
- status: {
176
- label: c.data.record.active ? t(c, 'state.active') : t(c, 'state.archived'),
177
- tone: c.data.record.active ? 'positive' : 'neutral',
178
- },
179
- }),
180
393
  ...(c.data.permissions.save
181
394
  ? [
182
395
  RecordDialogTrigger({
183
396
  dialog: 'edit',
184
- children: Button({ label: t(c, 'action.editProfile'), variant: 'secondary' }),
397
+ children: Button({
398
+ label: t(c, 'action.editProfile'),
399
+ variant: 'secondary',
400
+ }),
185
401
  }),
186
402
  ]
187
403
  : [
@@ -200,7 +416,11 @@ const overviewTab = (c) => {
200
416
  body: DescriptionList({
201
417
  columns: 2,
202
418
  items: [
203
- { id: 'email', label: t(c, 'field.email'), value: c.data.record.email || '—' },
419
+ {
420
+ id: 'email',
421
+ label: t(c, 'field.email'),
422
+ value: c.data.record.email || '—',
423
+ },
204
424
  {
205
425
  id: 'state',
206
426
  label: t(c, 'field.state'),
@@ -209,44 +429,900 @@ const overviewTab = (c) => {
209
429
  tone: c.data.record.active ? 'positive' : 'neutral',
210
430
  }),
211
431
  },
212
- { id: 'roles', label: t(c, 'field.rolesHeld'), value: String(c.data.assignments.length) },
213
- { id: 'company', label: t(c, 'field.company'), value: company ? String(company) : '—' },
432
+ {
433
+ id: 'roles',
434
+ label: t(c, 'field.rolesHeld'),
435
+ value: String(c.data.assignments.length),
436
+ },
437
+ {
438
+ id: 'company',
439
+ label: t(c, 'field.company'),
440
+ value: company ? String(company) : '—',
441
+ },
442
+ ...(c.data.record.superuser
443
+ ? [
444
+ {
445
+ id: 'superuser',
446
+ label: t(c, 'field.superuser'),
447
+ value: Badge({
448
+ label: c.data.record.superuserExpiresAt
449
+ ? t(c, 'breakGlass.activeUntil').replace('{until}', c.data.record.superuserExpiresAt)
450
+ : t(c, 'breakGlass.standing'),
451
+ tone: 'danger',
452
+ }),
453
+ },
454
+ ]
455
+ : []),
214
456
  ],
215
457
  }),
216
458
  });
217
459
  };
460
+ /** The call this person was last refused, said the way they would have met it. */
461
+ const denialNotice = (c) => {
462
+ const denial = c.data.lastDenial;
463
+ if (!denial)
464
+ return [];
465
+ const where = denial.surface
466
+ ? t(c, 'denial.onSurface').replace('{surface}', denial.surface).replace('{at}', denial.at)
467
+ : t(c, 'denial.at').replace('{at}', denial.at);
468
+ const times = denial.count > 1 ? ` ${t(c, 'denial.count').replace('{count}', String(denial.count))}` : '';
469
+ const fix = denial.templates.length
470
+ ? t(c, 'denial.fix').replace('{roles}', denial.templates.join(', '))
471
+ : t(c, 'denial.noFix');
472
+ return [
473
+ Notice({
474
+ tone: 'warning',
475
+ title: t(c, 'denial.title').replace('{area}', denial.label),
476
+ message: `${where}${times} ${fix}`,
477
+ }),
478
+ ];
479
+ };
480
+ /**
481
+ * What this person can open and actually work on.
482
+ *
483
+ * The question a support call asks is never "which bundles": it is "why can't
484
+ * they pick a tax on the quotation". The last refusal, when there is one, leads,
485
+ * because it is usually the reason the record was opened.
486
+ */
487
+ const screensTab = (c) => Stack({
488
+ gap: 'default',
489
+ items: [
490
+ DescriptionList({
491
+ columns: 1,
492
+ items: [
493
+ {
494
+ id: 'diagnostic-scope',
495
+ label: t(c, 'surface.scopeLabel'),
496
+ value: [
497
+ c.data.companies.find((row) => row.id === c.data.record.defaultCompanyId)?.name,
498
+ c.data.branches.find((row) => row.id === c.data.record.defaultBranchId)?.name,
499
+ ]
500
+ .filter(Boolean)
501
+ .join(' · ') || t(c, 'surface.noWorkplace'),
502
+ },
503
+ ],
504
+ }),
505
+ ...denialNotice(c),
506
+ SurfaceAccessView({
507
+ t: (key, params) => c.t(key, params),
508
+ surfaces: c.data.surfaces ?? [],
509
+ showVia: true,
510
+ empty: { title: t(c, 'surface.emptyTitle'), message: t(c, 'surface.emptyHint') },
511
+ }),
512
+ ],
513
+ });
514
+ /** Where an assignment applies, written the way the person reads it. */
515
+ const scopeName = (c, row) => row.branch
516
+ ? `${String(row.company)} · ${String(row.branch)}`
517
+ : row.company
518
+ ? String(row.company)
519
+ : t(c, 'scope.choice.tenant');
520
+ /** One group per place: authority is held somewhere, and the place is what differs. */
521
+ const assignmentGroups = (c) => {
522
+ const groups = new Map();
523
+ for (const row of c.data.assignments) {
524
+ const key = String(row.scopeKey ?? 'tenant');
525
+ const group = groups.get(key) ?? {
526
+ key,
527
+ title: scopeName(c, row),
528
+ rows: [],
529
+ };
530
+ group.rows.push(row);
531
+ groups.set(key, group);
532
+ }
533
+ return [...groups.values()];
534
+ };
535
+ /** Where an assignment came from: someone's decision, or a rule that matched this person. */
536
+ const sourceOf = (row) => row.source?.kind === 'policy'
537
+ ? { kind: 'policy', policyName: String(row.source.policyName ?? row.source.policyId ?? '') }
538
+ : { kind: 'manual' };
539
+ const sourceBadge = (c, row) => {
540
+ const source = sourceOf(row);
541
+ return source.kind === 'policy'
542
+ ? Badge({ label: t(c, 'access.source.policy').replace('{policy}', source.policyName), tone: 'info' })
543
+ : Badge({ label: t(c, 'access.source.manual'), tone: 'neutral' });
544
+ };
545
+ /** Why the reader is not offered the assign action, or the action itself. */
546
+ const accessControls = (c) => readingSelf(c)
547
+ ? // Nobody widens or narrows their own authority, superuser or not: the change
548
+ // would be approved by the person it benefits.
549
+ [
550
+ Notice({
551
+ tone: 'info',
552
+ title: t(c, 'access.selfTitle'),
553
+ message: t(c, 'access.selfHint'),
554
+ }),
555
+ ]
556
+ : c.data.permissions.assign
557
+ ? [
558
+ RecordDialogTrigger({
559
+ dialog: 'assign',
560
+ children: Button({
561
+ label: t(c, 'action.assignRole'),
562
+ variant: 'primary',
563
+ }),
564
+ }),
565
+ ]
566
+ : [
567
+ Notice({
568
+ tone: 'info',
569
+ title: t(c, 'users.readOnlyTitle'),
570
+ message: t(c, 'access.readOnlyHint'),
571
+ }),
572
+ ];
573
+ /**
574
+ * Standing in for a superuser for a while, and taking it back.
575
+ *
576
+ * Nobody is made a superuser by editing their profile: it is a grant with an end,
577
+ * an owner, given only by a superuser, and it shows here for as long
578
+ * as it lasts.
579
+ */
580
+ const breakGlassSection = (c) => {
581
+ const record = c.data.record;
582
+ const active = record.superuser === true;
583
+ if (!c.data.permissions.breakGlass || readingSelf(c))
584
+ return active
585
+ ? [
586
+ Notice({
587
+ tone: 'warning',
588
+ title: t(c, 'breakGlass.activeTitle'),
589
+ message: record.superuserExpiresAt
590
+ ? t(c, 'breakGlass.activeUntil').replace('{until}', record.superuserExpiresAt)
591
+ : t(c, 'breakGlass.standing'),
592
+ }),
593
+ ]
594
+ : [];
595
+ return [
596
+ Section({
597
+ title: t(c, 'breakGlass.title'),
598
+ description: t(c, 'breakGlass.hint'),
599
+ body: active
600
+ ? Stack({
601
+ gap: 'default',
602
+ items: [
603
+ Notice({
604
+ tone: 'warning',
605
+ title: t(c, 'breakGlass.activeTitle'),
606
+ message: record.superuserExpiresAt
607
+ ? t(c, 'breakGlass.activeUntil').replace('{until}', record.superuserExpiresAt)
608
+ : t(c, 'breakGlass.standing'),
609
+ }),
610
+ RecordModalForm({
611
+ kind: c.kind,
612
+ fields: [],
613
+ command: 'revokeBreakGlass',
614
+ actions: [
615
+ Button({ label: t(c, 'action.revokeBreakGlass'), variant: 'destructive', type: 'submit' }),
616
+ ],
617
+ }),
618
+ ],
619
+ })
620
+ : RecordModalForm({
621
+ kind: c.kind,
622
+ fields: [
623
+ field(c, {
624
+ name: 'breakGlassUntil',
625
+ label: t(c, 'field.breakGlassUntil'),
626
+ type: 'datetime-local',
627
+ required: true,
628
+ disabled: false,
629
+ }),
630
+ ],
631
+ command: 'grantBreakGlass',
632
+ actions: [
633
+ Button({ label: t(c, 'action.grantBreakGlass'), variant: 'destructive', type: 'submit' }),
634
+ ],
635
+ }),
636
+ }),
637
+ ];
638
+ };
218
639
  /** What this person may do, as rows of role and place — the authority they actually hold. */
219
- const accessTab = (c) => c.data.assignments.length
640
+ const accessTab = (c) => {
641
+ const groups = assignmentGroups(c);
642
+ return Stack({
643
+ gap: 'default',
644
+ items: [
645
+ ...accessControls(c),
646
+ ...(groups.length
647
+ ? groups.map((group) => Section({
648
+ title: group.title,
649
+ body: DataTable({
650
+ rows: group.rows,
651
+ id: (row) => String(row.id),
652
+ columns: [
653
+ {
654
+ key: 'role',
655
+ label: t(c, 'field.assignment'),
656
+ priority: 'primary',
657
+ // The row opens the role: what it covers, and the way to take it back.
658
+ cell: (row) => RecordDialogTrigger({
659
+ dialog: 'role',
660
+ id: String(row.id),
661
+ children: String(row.roleName),
662
+ }),
663
+ },
664
+ {
665
+ key: 'source',
666
+ label: t(c, 'access.sourceColumn'),
667
+ cell: (row) => sourceBadge(c, row),
668
+ },
669
+ ],
670
+ }),
671
+ }))
672
+ : [
673
+ Notice({
674
+ tone: 'info',
675
+ title: t(c, 'users.noAssignments'),
676
+ message: t(c, 'access.emptyHint'),
677
+ }),
678
+ ]),
679
+ ...(Array.isArray(c.data.surfaces)
680
+ ? [
681
+ RecordDialogTrigger({
682
+ dialog: 'diagnostics',
683
+ children: Button({ label: t(c, 'action.checkAccess'), variant: 'secondary' }),
684
+ }),
685
+ ]
686
+ : []),
687
+ ...(breakGlassSection(c).length
688
+ ? [Disclosure({ summary: t(c, 'access.advanced'), body: Stack({ items: breakGlassSection(c) }) })]
689
+ : []),
690
+ ],
691
+ });
692
+ };
693
+ /** The fields that say where a role would apply and which roles are being given. */
694
+ const assignFields = (c) => {
695
+ const scopeKind = c.state('scopeKind', 'branch');
696
+ const companyId = c.state('companyId', String(c.data.companies[0]?.id ?? ''));
697
+ return [
698
+ stateSelect(c, {
699
+ name: 'scopeKind',
700
+ label: t(c, 'field.scope'),
701
+ value: scopeKind,
702
+ required: true,
703
+ options: c.data.scopeKinds.map((kind) => ({
704
+ value: kind,
705
+ label: t(c, `scope.choice.${kind}`),
706
+ })),
707
+ }),
708
+ ...(scopeKind === 'tenant'
709
+ ? []
710
+ : [
711
+ stateSelect(c, {
712
+ name: 'companyId',
713
+ label: t(c, 'field.company'),
714
+ value: companyId,
715
+ required: true,
716
+ options: c.data.companies.map((company) => ({
717
+ value: String(company.id),
718
+ label: String(company.name),
719
+ })),
720
+ }),
721
+ ]),
722
+ ...(scopeKind === 'branch'
723
+ ? [
724
+ field(c, {
725
+ name: 'branchId',
726
+ label: t(c, 'field.branch'),
727
+ type: 'select',
728
+ required: true,
729
+ options: c.data.branches
730
+ .filter((branch) => String(branch.companyId) === companyId)
731
+ .map((branch) => ({
732
+ value: String(branch.id),
733
+ label: String(branch.name),
734
+ })),
735
+ }),
736
+ ]
737
+ : []),
738
+ field(c, {
739
+ name: 'roleIds',
740
+ label: t(c, 'field.jobRoles'),
741
+ type: 'checkbox-group',
742
+ required: true,
743
+ span: 'full',
744
+ optionsOrientation: 'vertical',
745
+ help: roleHelp(c),
746
+ options: roleOptions(c, (roleId) => c.draft(roleFieldName(roleId), '') === '1'),
747
+ }),
748
+ ];
749
+ };
750
+ /** How much of a bundle a person covers, said in words rather than a fraction. */
751
+ const coverage = (c, covered, total) => covered === 0 ? t(c, 'coverage.none') : covered >= total ? t(c, 'coverage.full') : t(c, 'coverage.partial');
752
+ /**
753
+ * What the selection would change, before it changes anything.
754
+ *
755
+ * The answer is the server's, computed from the same selection that is still on
756
+ * screen: every bundle the added or removed roles touch, with the reach the
757
+ * person has now beside the reach they would have.
758
+ */
759
+ const previewPanel = (c, command) => {
760
+ const preview = c.outcome(command);
761
+ if (!preview)
762
+ return '';
763
+ if (!preview.ok)
764
+ return Notice({
765
+ tone: 'warning',
766
+ title: t(c, 'preview.unavailable'),
767
+ message: '',
768
+ });
769
+ const contexts = preview.contexts ?? [];
770
+ if (!contexts.length)
771
+ return Notice({
772
+ tone: 'info',
773
+ title: t(c, 'preview.noChange'),
774
+ message: t(c, 'preview.noChangeHint'),
775
+ });
776
+ return Stack({
777
+ gap: 'compact',
778
+ items: contexts.flatMap((entry) => [
779
+ ...(entry.sensitiveChange
780
+ ? [
781
+ Notice({
782
+ tone: 'warning',
783
+ title: t(c, 'preview.sensitiveTitle'),
784
+ message: t(c, 'preview.sensitiveHint'),
785
+ }),
786
+ ]
787
+ : []),
788
+ ...(entry.superuser
789
+ ? [
790
+ Notice({
791
+ tone: 'info',
792
+ title: t(c, 'preview.superuser'),
793
+ message: '',
794
+ }),
795
+ ]
796
+ : entry.bundles.length || entry.surfaces?.length
797
+ ? [
798
+ Section({
799
+ title: t(c, 'preview.gains'),
800
+ body: Stack({
801
+ items: entry.bundles
802
+ .filter((row) => row.after > row.before)
803
+ .map((row) => row.labels[c.data.lang] ?? row.key)
804
+ .concat(entry.bundles.some((row) => row.after > row.before) ? [] : [t(c, 'value.unchanged')]),
805
+ }),
806
+ }),
807
+ Section({
808
+ title: t(c, 'preview.loses'),
809
+ body: Stack({
810
+ items: entry.bundles
811
+ .filter((row) => row.after < row.before)
812
+ .map((row) => row.labels[c.data.lang] ?? row.key)
813
+ .concat(entry.bundles.some((row) => row.after < row.before) ? [] : [t(c, 'value.unchanged')]),
814
+ }),
815
+ }),
816
+ Disclosure({
817
+ summary: t(c, 'preview.details'),
818
+ body: Stack({
819
+ items: [
820
+ // Screens first: "can open the quotation form but not pick a tax" is
821
+ // the consequence a reader acts on; the bundles below say why.
822
+ ...(entry.surfaces?.length
823
+ ? [
824
+ Section({
825
+ title: t(c, 'surface.previewTitle'),
826
+ body: SurfaceChangeTable((key, params) => c.t(key, params), entry.surfaces, `${entry.companyId}:${entry.branchId ?? ''}`),
827
+ }),
828
+ ]
829
+ : []),
830
+ DataTable({
831
+ rows: entry.bundles,
832
+ id: (row) => `${entry.companyId}:${entry.branchId ?? ''}:${row.key}`,
833
+ columns: [
834
+ {
835
+ key: 'bundle',
836
+ label: t(c, 'preview.bundle'),
837
+ priority: 'primary',
838
+ cell: (row) => row.labels[c.data.lang] ?? row.key,
839
+ },
840
+ {
841
+ key: 'before',
842
+ label: t(c, 'preview.before'),
843
+ cell: (row) => coverage(c, row.before, row.total),
844
+ },
845
+ {
846
+ key: 'after',
847
+ label: t(c, 'preview.after'),
848
+ cell: (row) => coverage(c, row.after, row.total),
849
+ },
850
+ ],
851
+ }),
852
+ ],
853
+ }),
854
+ }),
855
+ ]
856
+ : [
857
+ Notice({
858
+ tone: 'info',
859
+ title: t(c, 'preview.noChange'),
860
+ message: '',
861
+ }),
862
+ ]),
863
+ ]),
864
+ });
865
+ };
866
+ /** Ask what a role would do here, then give it. Both steps are one form and one selection. */
867
+ const assignDialog = (c) => !c.data.roles.length
868
+ ? // Nothing to choose from is a state of the deployment, not an empty field: a
869
+ // role can only be given here once it has been built from a role template.
870
+ Notice({
871
+ tone: 'warning',
872
+ title: t(c, 'access.noAssignableRoles'),
873
+ message: t(c, 'access.noAssignableRolesHint'),
874
+ })
875
+ : Stack({
876
+ gap: 'default',
877
+ items: [
878
+ RecordModalForm({
879
+ kind: c.kind,
880
+ fields: assignFields(c),
881
+ actions: [
882
+ Button({
883
+ label: t(c, 'action.previewAssignment'),
884
+ variant: 'secondary',
885
+ type: 'submit',
886
+ name: RECORD_COMMAND_FIELD,
887
+ value: 'previewAssign',
888
+ }),
889
+ // Only offered once the consequence has been read: the confirm button
890
+ // appears beside the answer, not before it.
891
+ ...(c.outcome('previewAssign')
892
+ ? [
893
+ Button({
894
+ label: t(c, 'action.confirmAssign'),
895
+ variant: 'primary',
896
+ type: 'submit',
897
+ name: RECORD_COMMAND_FIELD,
898
+ value: 'assign',
899
+ }),
900
+ ]
901
+ : []),
902
+ ],
903
+ }),
904
+ previewPanel(c, 'previewAssign'),
905
+ ],
906
+ });
907
+ /** The areas one role covers, as the context measured them. */
908
+ const coverageOf = (c, roleId) => c.data.roleCoverage[roleId] ?? [];
909
+ /** The role as held: what it covers, where it applies, and the form that takes it back. */
910
+ const roleDialog = (c) => {
911
+ const assignment = c.data.assignments.find((row) => String(row.id) === String(c.dialog?.params.id ?? ''));
912
+ if (!assignment)
913
+ return Notice({
914
+ tone: 'info',
915
+ title: t(c, 'users.noAssignments'),
916
+ message: '',
917
+ });
918
+ return Stack({
919
+ gap: 'default',
920
+ items: [
921
+ DescriptionList({
922
+ columns: 2,
923
+ items: [
924
+ {
925
+ id: 'role',
926
+ label: t(c, 'field.assignment'),
927
+ value: String(assignment.roleName),
928
+ },
929
+ {
930
+ id: 'scope',
931
+ label: t(c, 'field.scope'),
932
+ value: scopeName(c, assignment),
933
+ },
934
+ {
935
+ id: 'source',
936
+ label: t(c, 'access.sourceColumn'),
937
+ value: sourceBadge(c, assignment),
938
+ },
939
+ ],
940
+ }),
941
+ // What the role is for, not only where it applies.
942
+ ...(coverageOf(c, String(assignment.roleId)).length
943
+ ? [
944
+ Section({
945
+ title: t(c, 'preview.bundle'),
946
+ body: DataTable({
947
+ rows: coverageOf(c, String(assignment.roleId)),
948
+ id: (row) => String(row.key),
949
+ columns: [
950
+ {
951
+ key: 'bundle',
952
+ label: t(c, 'preview.bundle'),
953
+ priority: 'primary',
954
+ cell: (row) => String(row.labels?.[c.data.lang] ?? row.key),
955
+ },
956
+ {
957
+ key: 'level',
958
+ label: t(c, 'coverage.level'),
959
+ cell: (row) => coverage(c, Number(row.covered), Number(row.total)),
960
+ },
961
+ ],
962
+ }),
963
+ }),
964
+ ]
965
+ : []),
966
+ // A rule gave it, so a rule takes it back: removing it here would last until
967
+ // the next sign-in re-applied the policy.
968
+ ...(sourceOf(assignment).kind === 'policy'
969
+ ? [
970
+ Notice({
971
+ tone: 'info',
972
+ title: t(c, 'access.policyOwnedTitle'),
973
+ message: t(c, 'access.policyOwnedHint'),
974
+ }),
975
+ ]
976
+ : []),
977
+ ...(c.data.permissions.remove && !readingSelf(c) && sourceOf(assignment).kind !== 'policy'
978
+ ? [
979
+ Stack({
980
+ gap: 'default',
981
+ items: [
982
+ RecordModalForm({
983
+ kind: c.kind,
984
+ fields: [],
985
+ actions: [
986
+ Button({
987
+ label: t(c, 'action.previewRemoval'),
988
+ variant: 'secondary',
989
+ type: 'submit',
990
+ name: RECORD_COMMAND_FIELD,
991
+ value: 'previewUnassign',
992
+ }),
993
+ ...(c.outcome('previewUnassign')
994
+ ? [
995
+ Button({
996
+ label: t(c, 'action.unassignScopedRole'),
997
+ variant: 'destructive',
998
+ type: 'submit',
999
+ name: RECORD_COMMAND_FIELD,
1000
+ value: 'unassign',
1001
+ }),
1002
+ ]
1003
+ : []),
1004
+ ],
1005
+ }),
1006
+ previewPanel(c, 'previewUnassign'),
1007
+ ],
1008
+ }),
1009
+ ]
1010
+ : []),
1011
+ ],
1012
+ });
1013
+ };
1014
+ /**
1015
+ * How a new credential reaches this person here.
1016
+ *
1017
+ * The tenant chooses: a link sent to the person's own inbox, so nobody else ever
1018
+ * holds it, or — where staff share devices or have no mailbox — a code shown once
1019
+ * to the administrator. A deployment that cannot send the link yet falls back to
1020
+ * the code rather than offering a button that fails.
1021
+ */
1022
+ const deliveryOf = (c) => c.data.credentialDelivery === 'email' && !c.data.externalCredential && !c.data.permissions.sendLink
1023
+ ? 'oneTime'
1024
+ : (c.data.credentialDelivery ?? 'oneTime');
1025
+ const activated = (c) => c.data.externalCredential?.activated ?? c.data.record.passwordReady;
1026
+ /** Send the person a link to set their own password. The administrator never sees it. */
1027
+ const emailReset = (c) => {
1028
+ const sent = c.outcome('sendResetLink');
1029
+ return [
1030
+ ...(sent?.ok
1031
+ ? [
1032
+ Notice({
1033
+ tone: 'positive',
1034
+ title: t(c, 'login.linkSentTitle'),
1035
+ message: t(c, 'login.linkSentHint')
1036
+ .replace('{email}', String(sent.sentTo ?? c.data.record.email))
1037
+ .replace('{until}', String(sent.expiresAt ?? '')),
1038
+ }),
1039
+ ]
1040
+ : []),
1041
+ Section({
1042
+ title: t(c, activated(c) ? 'login.linkTitle' : 'login.inviteTitle'),
1043
+ description: c.data.record.email
1044
+ ? t(c, activated(c) ? 'login.linkHint' : 'login.inviteHint').replace('{email}', c.data.record.email)
1045
+ : null,
1046
+ // No address, no link: say what is missing instead of offering a send that
1047
+ // has nowhere to go.
1048
+ body: c.data.record.email
1049
+ ? RecordModalForm({
1050
+ kind: c.kind,
1051
+ fields: [],
1052
+ command: 'sendResetLink',
1053
+ actions: [
1054
+ Button({
1055
+ label: t(c, activated(c)
1056
+ ? 'action.sendResetLink'
1057
+ : sent?.ok || c.data.record.invitationSentAt
1058
+ ? 'action.resendInvite'
1059
+ : 'action.sendInvite'),
1060
+ variant: 'primary',
1061
+ type: 'submit',
1062
+ }),
1063
+ ],
1064
+ })
1065
+ : Notice({
1066
+ tone: 'warning',
1067
+ title: t(c, 'login.linkNoEmail'),
1068
+ message: t(c, 'login.linkNoEmailHint'),
1069
+ }),
1070
+ }),
1071
+ ];
1072
+ };
1073
+ /** Issue a one-time code and show it, once, to the administrator who asked. */
1074
+ const oneTimeReset = (c) => {
1075
+ const issued = c.outcome('resetPassword') ??
1076
+ c.outcome('claimCredential');
1077
+ return [
1078
+ // Shown once, by the only party that ever holds it in the clear.
1079
+ ...(issued?.token || issued?.temporaryPassword
1080
+ ? [
1081
+ Section({
1082
+ title: t(c, issued?.temporaryPassword ? 'login.temporaryShownOnce' : 'login.oneTimeTitle'),
1083
+ body: Stack({
1084
+ gap: 'compact',
1085
+ items: [
1086
+ Notice({
1087
+ tone: 'warning',
1088
+ title: t(c, issued?.temporaryPassword ? 'login.temporaryShownOnce' : 'login.oneTimeTitle'),
1089
+ message: t(c, 'login.oneTimeHint'),
1090
+ }),
1091
+ DescriptionList({
1092
+ columns: 1,
1093
+ items: [
1094
+ {
1095
+ id: 'token',
1096
+ label: t(c, c.data.externalCredential ? 'login.temporaryLabel' : 'login.oneTimeLabel'),
1097
+ value: issued.token ?? issued.temporaryPassword,
1098
+ },
1099
+ ],
1100
+ }),
1101
+ ],
1102
+ }),
1103
+ }),
1104
+ ]
1105
+ : []),
1106
+ issued?.temporaryPassword
1107
+ ? null
1108
+ : Section({
1109
+ title: t(c, c.data.externalCredential
1110
+ ? 'login.temporaryTitle'
1111
+ : activated(c)
1112
+ ? 'login.resetTitle'
1113
+ : 'login.activateTitle'),
1114
+ description: t(c, c.data.externalCredential
1115
+ ? 'login.temporaryHint'
1116
+ : activated(c)
1117
+ ? 'login.resetHint'
1118
+ : 'login.activateHint'),
1119
+ body: issued?.temporaryPassword
1120
+ ? null
1121
+ : RecordModalForm({
1122
+ kind: c.kind,
1123
+ fields: [],
1124
+ command: c.data.externalCredential?.claimable ? 'claimCredential' : 'resetPassword',
1125
+ actions: [
1126
+ Button({
1127
+ label: t(c, c.data.externalCredential
1128
+ ? c.data.externalCredential.claimable
1129
+ ? 'action.claimPassword'
1130
+ : 'action.temporaryPassword'
1131
+ : activated(c)
1132
+ ? 'action.resetPassword'
1133
+ : 'action.activationCode'),
1134
+ variant: 'primary',
1135
+ type: 'submit',
1136
+ }),
1137
+ ],
1138
+ }),
1139
+ }),
1140
+ ];
1141
+ };
1142
+ /**
1143
+ * What it takes to sign in as this person, and the one thing an administrator may
1144
+ * do about it.
1145
+ *
1146
+ * There is no session list and no way to set somebody else's password. A session
1147
+ * belongs to the serve layer rather than to this module, so there is nothing here
1148
+ * to read or revoke; and a reset does the administrator's work — a new credential,
1149
+ * every session ended — while leaving the password itself with its owner.
1150
+ */
1151
+ const loginTab = (c) => {
1152
+ const delivery = deliveryOf(c);
1153
+ const mayReset = c.data.permissions.sendLink || c.data.permissions.resetPassword;
1154
+ return Stack({
1155
+ gap: 'default',
1156
+ items: [
1157
+ ...(c.data.permissions.identities
1158
+ ? [
1159
+ LinkButton({
1160
+ label: t(c, 'login.identities'),
1161
+ href: `/admin/oauth/identities?${new URLSearchParams({ user: c.id, lang: c.data.lang })}`,
1162
+ }),
1163
+ ]
1164
+ : []),
1165
+ Section({
1166
+ title: t(c, 'login.accountTitle'),
1167
+ body: DescriptionList({
1168
+ columns: 2,
1169
+ items: [
1170
+ {
1171
+ id: 'credential',
1172
+ label: t(c, 'field.credential'),
1173
+ value: Badge({
1174
+ label: t(c, activated(c)
1175
+ ? 'login.ready'
1176
+ : c.data.record.invitationSentAt || c.outcome('sendResetLink')?.ok
1177
+ ? 'login.invited'
1178
+ : 'login.preparing'),
1179
+ tone: activated(c) ? 'positive' : 'warning',
1180
+ }),
1181
+ },
1182
+ {
1183
+ id: 'login',
1184
+ label: t(c, 'field.login'),
1185
+ value: c.data.record.login,
1186
+ },
1187
+ {
1188
+ id: 'lastLogin',
1189
+ label: t(c, 'login.lastSignIn'),
1190
+ value: c.data.record.lastLoginAt || t(c, 'login.never'),
1191
+ },
1192
+ {
1193
+ id: 'delivery',
1194
+ label: t(c, 'login.delivery'),
1195
+ value: t(c, `login.delivery.${delivery}`),
1196
+ },
1197
+ ],
1198
+ }),
1199
+ }),
1200
+ ...(c.data.externalCredential
1201
+ ? [
1202
+ Section({
1203
+ title: t(c, `login.externalState.${c.data.externalCredential.state}`),
1204
+ body: RecordModalForm({
1205
+ kind: c.kind,
1206
+ fields: [],
1207
+ command: c.data.permissions.retryCredential ? 'retryCredential' : 'refreshAccount',
1208
+ actions: [
1209
+ Button({
1210
+ type: 'submit',
1211
+ label: t(c, c.data.permissions.retryCredential ? 'action.retryAccount' : 'action.refreshAccount'),
1212
+ }),
1213
+ ],
1214
+ }),
1215
+ }),
1216
+ ]
1217
+ : []),
1218
+ ...(c.data.externalCredential?.emailState
1219
+ ? [
1220
+ Notice({
1221
+ tone: ['failed', 'uncertain'].includes(c.data.externalCredential.emailState)
1222
+ ? 'warning'
1223
+ : 'info',
1224
+ title: t(c, `login.emailState.${c.data.externalCredential.emailState}`),
1225
+ message: t(c, 'login.emailStateHint'),
1226
+ }),
1227
+ ]
1228
+ : []),
1229
+ // Resetting your own password is the profile's job, with the current one.
1230
+ ...(readingSelf(c)
1231
+ ? [
1232
+ Notice({
1233
+ tone: 'info',
1234
+ title: t(c, 'login.selfTitle'),
1235
+ message: t(c, 'login.selfHint'),
1236
+ }),
1237
+ ]
1238
+ : mayReset
1239
+ ? [
1240
+ ...(delivery !== 'oneTime' && c.data.permissions.sendLink ? emailReset(c) : []),
1241
+ ...(delivery !== 'email' && c.data.permissions.resetPassword ? oneTimeReset(c) : []),
1242
+ ]
1243
+ : // An account still being prepared waits on its state, which the section above
1244
+ // already names; calling that "read only" blames a permission the reader has.
1245
+ c.data.externalCredential && c.data.externalCredential.state !== 'ready'
1246
+ ? []
1247
+ : [
1248
+ Notice({
1249
+ tone: 'info',
1250
+ title: t(c, 'users.readOnlyTitle'),
1251
+ message: t(c, 'login.readOnlyHint'),
1252
+ }),
1253
+ ]),
1254
+ ],
1255
+ });
1256
+ };
1257
+ /** What was done to this person's authority, and who did it. */
1258
+ const auditTab = (c) => c.data.audit.length
220
1259
  ? DataTable({
221
- rows: c.data.assignments,
1260
+ rows: c.data.audit,
222
1261
  id: (row) => String(row.id),
223
1262
  columns: [
224
1263
  {
225
- key: 'role',
226
- label: t(c, 'field.assignment'),
1264
+ key: 'when',
1265
+ label: t(c, 'audit.when'),
1266
+ cell: (row) => String(row.occurredAt ?? '—'),
1267
+ },
1268
+ {
1269
+ key: 'event',
1270
+ label: t(c, 'audit.action'),
227
1271
  priority: 'primary',
228
- cell: (row) => String(row.roleName),
1272
+ cell: (row) => `${t(c, `audit.event.${String(row.event)}`)} · ${String(row.actor ?? '—')}`,
1273
+ },
1274
+ {
1275
+ key: 'roles',
1276
+ label: t(c, 'field.assignment'),
1277
+ cell: (row) => row.roleIds.map((id) => roleNameOf(c, id)).join(' · ') || '—',
229
1278
  },
230
1279
  {
231
- key: 'scope',
232
- label: t(c, 'field.scope'),
233
- cell: (row) => row.branch
234
- ? `${String(row.company)} · ${String(row.branch)}`
235
- : row.company
236
- ? String(row.company)
237
- : t(c, 'scope.choice.tenant'),
1280
+ key: 'outcome',
1281
+ label: t(c, 'audit.outcome'),
1282
+ cell: (row) => Badge({
1283
+ label: t(c, `audit.outcome.${String(row.outcome)}`),
1284
+ tone: String(row.outcome) === 'success' ? 'positive' : 'danger',
1285
+ }),
238
1286
  },
239
1287
  ],
240
1288
  })
241
- : Notice({ tone: 'info', title: t(c, 'users.noAssignments'), message: t(c, 'users.readOnlyHint') });
1289
+ : Notice({
1290
+ tone: 'info',
1291
+ title: t(c, 'audit.empty'),
1292
+ message: t(c, 'audit.emptyHint'),
1293
+ });
1294
+ /** A role named by what it is called, falling back to the id it was recorded under. */
1295
+ const roleNameOf = (c, roleId) => String(c.data.assignments.find((row) => String(row.roleId) === roleId)?.roleName ??
1296
+ c.data.roles.find((row) => String(row.id) === roleId)?.name ??
1297
+ roleId);
1298
+ /** The assignment a role dialog is open on, for the commands it submits. */
1299
+ const openAssignment = (c) => c.data.assignments.find((row) => String(row.id) === String(c.dialog?.params.id ?? '')) ?? {};
1300
+ /** The workplace and roles a submitted assign form is asking for. */
1301
+ const assignSelection = (form, c) => ({
1302
+ userId: c.id,
1303
+ roleIds: selectedRoles(form, c.data.roles),
1304
+ scopeKind: text(form, 'scopeKind') || 'branch',
1305
+ companyId: text(form, 'companyId') || null,
1306
+ branchId: text(form, 'branchId') || null,
1307
+ // A role given somewhere the person does not yet work brings the workplace with
1308
+ // it; the server refuses that unless the actor may also grant the membership.
1309
+ addMembership: true,
1310
+ });
242
1311
  export const userModalDefinition = {
243
1312
  kind: 'user.user',
1313
+ labels: () => USER_RECORD_MODAL_LABELS[pageLang()],
244
1314
  context: {
245
1315
  fn: 'user.userModalContext',
246
1316
  input: (id, creating) => (creating ? { locale: pageLang() } : { id, locale: pageLang() }),
247
1317
  },
248
1318
  title: (c) => (c.creating ? t(c, 'users.create') : c.data.record.name || c.data.record.login),
249
1319
  description: (c) => (c.creating ? t(c, 'users.createSubtitle') : c.data.record.login),
1320
+ status: (c) => c.creating
1321
+ ? undefined
1322
+ : Badge({
1323
+ label: c.data.record.active ? t(c, 'state.active') : t(c, 'state.archived'),
1324
+ tone: c.data.record.active ? 'positive' : 'neutral',
1325
+ }),
250
1326
  header,
251
1327
  body: (c) => (c.creating ? createView(c) : ''),
252
1328
  tabs: [
@@ -262,15 +1338,67 @@ export const userModalDefinition = {
262
1338
  visible: (c) => !c.creating,
263
1339
  view: accessTab,
264
1340
  },
1341
+ {
1342
+ id: 'screens',
1343
+ label: (c) => t(c, 'tab.screens'),
1344
+ // Only where the context measured it: a deployment that does not report
1345
+ // screens has nothing true to put in the tab.
1346
+ visible: () => false,
1347
+ view: screensTab,
1348
+ },
1349
+ {
1350
+ id: 'login',
1351
+ label: (c) => t(c, 'tab.login'),
1352
+ visible: (c) => !c.creating,
1353
+ view: loginTab,
1354
+ },
1355
+ {
1356
+ id: 'audit',
1357
+ label: (c) => t(c, 'tab.audit'),
1358
+ // The log is its own permission: a viewer may open a person without being
1359
+ // allowed to read the history of who gave them what.
1360
+ visible: (c) => !c.creating && c.data.permissions.audit === true,
1361
+ view: auditTab,
1362
+ },
265
1363
  ],
266
1364
  dialogs: {
1365
+ diagnostics: { title: (c) => t(c, 'action.checkAccess'), view: screensTab, size: 'large' },
1366
+ assign: { title: (c) => t(c, 'action.assignRole'), view: assignDialog },
1367
+ role: {
1368
+ title: (c) => String(openAssignment(c).roleName ?? ''),
1369
+ view: roleDialog,
1370
+ },
267
1371
  edit: {
268
1372
  title: (c) => t(c, 'action.editProfile'),
269
- view: (c) => RecordModalForm({
270
- kind: c.kind,
271
- fields: profileFields(c),
272
- command: 'save',
273
- actions: [Button({ label: t(c, 'action.save'), variant: 'primary', type: 'submit' })],
1373
+ view: (c) => Stack({
1374
+ gap: 'default',
1375
+ items: [
1376
+ Section({
1377
+ title: t(c, 'users.profileTitle'),
1378
+ body: RecordModalForm({
1379
+ kind: c.kind,
1380
+ fields: profileFields(c),
1381
+ command: 'save',
1382
+ actions: [
1383
+ Button({
1384
+ label: t(c, 'action.save'),
1385
+ variant: 'primary',
1386
+ type: 'submit',
1387
+ }),
1388
+ ],
1389
+ }),
1390
+ }),
1391
+ // Its own form and its own command: who a person is and where they work
1392
+ // are separate decisions, and only the second one is audited authority.
1393
+ ...(c.data.permissions.workplaces
1394
+ ? [
1395
+ Section({
1396
+ title: t(c, 'users.workplaceTitle'),
1397
+ body: workplaceForm(c),
1398
+ }),
1399
+ ]
1400
+ : []),
1401
+ ],
274
1402
  }),
275
1403
  },
276
1404
  },
@@ -287,7 +1415,6 @@ export const userModalDefinition = {
287
1415
  scopeKind: text(form, 'scopeKind') || 'branch',
288
1416
  companyId: text(form, 'companyId') || null,
289
1417
  branchId: text(form, 'branchId') || null,
290
- reason: text(form, 'reason'),
291
1418
  expectedAuthorizationRevision: c.data.revision,
292
1419
  idempotencyKey: uuid(),
293
1420
  }),
@@ -299,6 +1426,125 @@ export const userModalDefinition = {
299
1426
  return typeof row.id === 'string' ? row.id : null;
300
1427
  },
301
1428
  },
1429
+ previewWorkplaces: {
1430
+ fn: 'user.previewWorkplaces',
1431
+ input: (form, c) => ({
1432
+ userId: c.id,
1433
+ companyIds: selectedIds(form, c.data.companies, companyFieldName),
1434
+ branchIds: selectedIds(form, c.data.branches, branchFieldName),
1435
+ }),
1436
+ preview: true,
1437
+ },
1438
+ setWorkplaces: {
1439
+ fn: 'user.setWorkplaces',
1440
+ input: (form, c) => ({
1441
+ userId: c.id,
1442
+ companyIds: selectedIds(form, c.data.companies, companyFieldName),
1443
+ branchIds: selectedIds(form, c.data.branches, branchFieldName),
1444
+ defaultCompanyId: text(form, 'defaultCompanyId'),
1445
+ defaultBranchId: text(form, 'defaultBranchId'),
1446
+ expectedAuthorizationRevision: c.data.revision,
1447
+ idempotencyKey: uuid(),
1448
+ }),
1449
+ // The server names its inputs; the form names its fields.
1450
+ issueField: (field) => ({ companyIds: 'companies', branchIds: 'branches' })[field] ?? field,
1451
+ // Read the person again: every tab shows where they now work.
1452
+ after: 'reload',
1453
+ },
1454
+ sendResetLink: {
1455
+ fn: 'user.sendCredentialLink',
1456
+ input: (form, c) => ({
1457
+ userId: c.id,
1458
+ kind: c.data.record.passwordReady ? 'reset' : 'invitation',
1459
+ idempotencyKey: uuid(),
1460
+ }),
1461
+ // Reload invitation status while keeping the delivery outcome visible.
1462
+ after: 'reload',
1463
+ },
1464
+ grantBreakGlass: {
1465
+ fn: 'user.setBreakGlass',
1466
+ input: (form, c) => {
1467
+ const until = text(form, 'breakGlassUntil');
1468
+ const at = until ? new Date(until) : null;
1469
+ return {
1470
+ userId: c.id,
1471
+ enabled: true,
1472
+ expiresAt: at && Number.isFinite(at.getTime()) ? at.toISOString() : null,
1473
+ expectedAuthorizationRevision: c.data.revision,
1474
+ idempotencyKey: uuid(),
1475
+ };
1476
+ },
1477
+ issueField: (field) => (field === 'expiresAt' ? 'breakGlassUntil' : field),
1478
+ confirm: (c) => t(c, 'breakGlass.confirm'),
1479
+ after: 'reload',
1480
+ },
1481
+ revokeBreakGlass: {
1482
+ fn: 'user.setBreakGlass',
1483
+ input: (form, c) => ({
1484
+ userId: c.id,
1485
+ enabled: false,
1486
+ expiresAt: null,
1487
+ expectedAuthorizationRevision: c.data.revision,
1488
+ idempotencyKey: uuid(),
1489
+ }),
1490
+ after: 'reload',
1491
+ },
1492
+ resetPassword: {
1493
+ fn: 'user.issueAuthToken',
1494
+ input: (_form, c) => ({
1495
+ userId: c.id,
1496
+ kind: c.data.record.passwordReady ? 'reset' : 'invitation',
1497
+ realm: 'backend',
1498
+ }),
1499
+ // Stay: the server hands back a credential it will never say again, and the
1500
+ // tab is where the person reading it is.
1501
+ after: 'stay',
1502
+ },
1503
+ previewAssign: {
1504
+ fn: 'user.previewRoleAssignment',
1505
+ input: (form, c) => assignSelection(form, c),
1506
+ preview: true,
1507
+ },
1508
+ assign: {
1509
+ fn: 'user.assignRoles',
1510
+ input: (form, c) => ({
1511
+ ...assignSelection(form, c),
1512
+ expectedAuthorizationRevision: c.data.revision,
1513
+ idempotencyKey: uuid(),
1514
+ }),
1515
+ // Read the person again: the access tab is a list of what they now hold.
1516
+ after: 'reload',
1517
+ },
1518
+ previewUnassign: {
1519
+ fn: 'user.previewRoleAssignment',
1520
+ input: (_form, c) => {
1521
+ const assignment = openAssignment(c);
1522
+ return {
1523
+ userId: c.id,
1524
+ assignmentId: String(assignment.id ?? ''),
1525
+ roleIds: [String(assignment.roleId ?? '')],
1526
+ scopeKind: String(assignment.scopeKind ?? 'tenant'),
1527
+ companyId: assignment.companyId ?? null,
1528
+ branchId: assignment.branchId ?? null,
1529
+ };
1530
+ },
1531
+ preview: true,
1532
+ },
1533
+ unassign: {
1534
+ fn: 'user.unassignScopedRole',
1535
+ input: (form, c) => {
1536
+ const assignment = openAssignment(c);
1537
+ return {
1538
+ userId: c.id,
1539
+ assignmentId: String(assignment.id ?? ''),
1540
+ roleId: String(assignment.roleId ?? ''),
1541
+ scopeKey: String(assignment.scopeKey ?? 'tenant'),
1542
+ expectedAuthorizationRevision: c.data.revision,
1543
+ idempotencyKey: uuid(),
1544
+ };
1545
+ },
1546
+ after: 'reload',
1547
+ },
302
1548
  save: {
303
1549
  fn: 'user.saveUser',
304
1550
  input: (form, c) => ({