@limetech/lime-crm-building-blocks 2.3.0 → 2.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (293) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/dist/cjs/{condition-tree-translate-B_qIQz9s.js → condition-tree-translate-BQwKtiNZ.js} +1 -1
  3. package/dist/cjs/{filter-group-logic-Bt5tIbfP.js → filter-group-logic-CeGmYgsu.js} +1 -1
  4. package/dist/cjs/{filter-operators-CzIq9qKC.js → filter-operators-C3T2czC_.js} +1 -1
  5. package/dist/cjs/{index-mDIvByXc.js → index-Du4GyM0Y.js} +13 -8
  6. package/dist/cjs/index.cjs.js +3 -3
  7. package/dist/cjs/{index.esm-D1EzGa8X.js → index.esm-C2zw0QJK.js} +2 -2
  8. package/dist/cjs/lime-crm-building-blocks.cjs.js +3 -3
  9. package/dist/cjs/{lime-query-validation-Df4GZRGm.js → lime-query-validation-CzYkphmi.js} +1 -1
  10. package/dist/cjs/limebb-alert-dialog.cjs.entry.js +1 -1
  11. package/dist/cjs/limebb-browser.cjs.entry.js +2 -2
  12. package/dist/cjs/limebb-chat-icon-list_3.cjs.entry.js +2 -2
  13. package/dist/cjs/limebb-chat-list.cjs.entry.js +9 -4
  14. package/dist/cjs/limebb-color-palette-picker.cjs.entry.js +1 -1
  15. package/dist/cjs/limebb-color-palette-swatches.cjs.entry.js +1 -1
  16. package/dist/cjs/limebb-component-config.cjs.entry.js +3 -3
  17. package/dist/cjs/limebb-component-picker.cjs.entry.js +2 -2
  18. package/dist/cjs/limebb-composer-toolbar.cjs.entry.js +2 -2
  19. package/dist/cjs/limebb-condition-tree-editor.cjs.entry.js +24 -9
  20. package/dist/cjs/limebb-condition-tree.cjs.entry.js +121 -34
  21. package/dist/cjs/limebb-currency-picker.cjs.entry.js +2 -2
  22. package/dist/cjs/limebb-dashboard-widget.cjs.entry.js +1 -1
  23. package/dist/cjs/limebb-data-cells.cjs.entry.js +2 -2
  24. package/dist/cjs/limebb-date-picker.cjs.entry.js +2 -2
  25. package/dist/cjs/limebb-date-range.cjs.entry.js +1 -1
  26. package/dist/cjs/limebb-document-chips.cjs.entry.js +1 -1
  27. package/dist/cjs/limebb-document-item.cjs.entry.js +1 -1
  28. package/dist/cjs/limebb-document-picker.cjs.entry.js +1 -1
  29. package/dist/cjs/limebb-empty-state.cjs.entry.js +1 -1
  30. package/dist/cjs/limebb-feed-item-thumbnail-file-info.cjs.entry.js +1 -1
  31. package/dist/cjs/limebb-feed-timeline-item.cjs.entry.js +2 -2
  32. package/dist/cjs/limebb-feed.cjs.entry.js +2 -2
  33. package/dist/cjs/limebb-filter-chip_6.cjs.entry.js +4 -4
  34. package/dist/cjs/limebb-icon-picker.cjs.entry.js +1 -1
  35. package/dist/cjs/limebb-info-tile-currency-format.cjs.entry.js +1 -1
  36. package/dist/cjs/limebb-info-tile-date-format.cjs.entry.js +1 -1
  37. package/dist/cjs/limebb-info-tile-decimal-format.cjs.entry.js +1 -1
  38. package/dist/cjs/limebb-info-tile-format.cjs.entry.js +1 -1
  39. package/dist/cjs/limebb-info-tile-relative-date-format.cjs.entry.js +1 -1
  40. package/dist/cjs/limebb-info-tile-unit-format.cjs.entry.js +1 -1
  41. package/dist/cjs/limebb-info-tile.cjs.entry.js +3 -3
  42. package/dist/cjs/limebb-inline-image.cjs.entry.js +2 -2
  43. package/dist/cjs/limebb-kanban-group.cjs.entry.js +2 -2
  44. package/dist/cjs/limebb-kanban-item.cjs.entry.js +2 -2
  45. package/dist/cjs/limebb-kanban.cjs.entry.js +1 -1
  46. package/dist/cjs/limebb-lime-query-builder.cjs.entry.js +3 -3
  47. package/dist/cjs/limebb-lime-query-filter-builder.cjs.entry.js +3 -3
  48. package/dist/cjs/limebb-lime-query-filter-comparison_2.cjs.entry.js +4 -4
  49. package/dist/cjs/limebb-lime-query-order-by-editor_2.cjs.entry.js +3 -3
  50. package/dist/cjs/limebb-lime-query-order-by-item.cjs.entry.js +1 -1
  51. package/dist/cjs/limebb-lime-query-response-format-builder.cjs.entry.js +3 -3
  52. package/dist/cjs/limebb-lime-query-response-format-editor_2.cjs.entry.js +1 -1
  53. package/dist/cjs/limebb-limeobject-file-viewer.cjs.entry.js +2 -2
  54. package/dist/cjs/limebb-live-docs-info.cjs.entry.js +1 -1
  55. package/dist/cjs/limebb-loader.cjs.entry.js +2 -2
  56. package/dist/cjs/limebb-locale-picker.cjs.entry.js +2 -2
  57. package/dist/cjs/limebb-mention-group-counter.cjs.entry.js +1 -1
  58. package/dist/cjs/limebb-mention.cjs.entry.js +2 -2
  59. package/dist/cjs/limebb-navigation-button_2.cjs.entry.js +1 -1
  60. package/dist/cjs/limebb-notification-item.cjs.entry.js +2 -2
  61. package/dist/cjs/limebb-notification-list.cjs.entry.js +2 -2
  62. package/dist/cjs/limebb-object-chip.cjs.entry.js +3 -3
  63. package/dist/cjs/limebb-percentage-visualizer.cjs.entry.js +2 -2
  64. package/dist/cjs/limebb-property-selector.cjs.entry.js +3 -3
  65. package/dist/cjs/limebb-rule-arg-filter-editor.cjs.entry.js +2 -2
  66. package/dist/cjs/limebb-rule-condition-chip.cjs.entry.js +71 -0
  67. package/dist/cjs/limebb-rule-condition-editor-CHWTMOmi.js +285 -0
  68. package/dist/cjs/limebb-rule-condition-editor.cjs.entry.js +9 -0
  69. package/dist/cjs/limebb-rule-editor.cjs.entry.js +217 -573
  70. package/dist/cjs/limebb-rule-gate.cjs.entry.js +2 -2
  71. package/dist/cjs/limebb-text-editor-picker.cjs.entry.js +1 -1
  72. package/dist/cjs/limebb-text-editor.cjs.entry.js +3 -3
  73. package/dist/cjs/limebb-trend-indicator.cjs.entry.js +2 -2
  74. package/dist/cjs/limebb-value-comparison-editor.cjs.entry.js +3 -3
  75. package/dist/cjs/{limetype-BPuuRLtH.js → limetype-BzVDjAKS.js} +1 -1
  76. package/dist/cjs/loader.cjs.js +2 -2
  77. package/dist/cjs/{web-component-template-DRMW9wHN.js → web-component-template-C-AkY5as.js} +1 -1
  78. package/dist/collection/collection-manifest.json +3 -2
  79. package/dist/collection/components/chat-list/chat-list.js +7 -2
  80. package/dist/collection/components/condition-tree/condition-tree-editor/condition-tree-editor.js +46 -5
  81. package/dist/collection/components/condition-tree/condition-tree-nodes.js +13 -6
  82. package/dist/collection/components/condition-tree/condition-tree.js +69 -18
  83. package/dist/collection/components/condition-tree/group-node-view.js +41 -5
  84. package/dist/collection/components/condition-tree/leaf-node-view.js +19 -2
  85. package/dist/collection/components/rule-editor/condition-tree-adapter.js +229 -0
  86. package/dist/collection/components/rule-editor/rule-condition-chip/rule-condition-chip.css +4 -0
  87. package/dist/collection/components/rule-editor/rule-condition-chip/rule-condition-chip.js +322 -0
  88. package/dist/collection/components/rule-editor/rule-condition-editor/rule-condition-editor.css +5 -0
  89. package/dist/collection/components/rule-editor/rule-condition-editor/rule-condition-editor.js +259 -0
  90. package/dist/collection/components/rule-editor/rule-editor.css +1 -73
  91. package/dist/collection/components/rule-editor/rule-editor.js +143 -153
  92. package/dist/collection/components/rule-editor/rule-issues.js +89 -0
  93. package/dist/collection/components/rule-editor/view-helpers.js +19 -41
  94. package/dist/components/condition-tree-adapter.js +1 -0
  95. package/dist/components/condition-tree-editor.js +1 -1
  96. package/dist/components/condition-tree.js +1 -0
  97. package/dist/components/limebb-chat-list.js +1 -1
  98. package/dist/components/limebb-condition-tree.js +1 -1
  99. package/dist/components/limebb-rule-condition-chip.d.ts +11 -0
  100. package/dist/components/limebb-rule-condition-chip.js +1 -0
  101. package/dist/components/limebb-rule-condition-editor.d.ts +11 -0
  102. package/dist/components/limebb-rule-condition-editor.js +1 -0
  103. package/dist/components/limebb-rule-editor.js +1 -1
  104. package/dist/esm/{condition-tree-translate-CBeXbZ_z.js → condition-tree-translate-ZQptbaXF.js} +1 -1
  105. package/dist/esm/{filter-group-logic-CzThKf85.js → filter-group-logic-nqCMmV0e.js} +1 -1
  106. package/dist/esm/{filter-operators-u3T1PKhm.js → filter-operators-QbKK26m2.js} +1 -1
  107. package/dist/esm/{index-COtSgrC5.js → index-BK566_jX.js} +13 -8
  108. package/dist/esm/{index.esm-B9D_MXA6.js → index.esm-C__n3hug.js} +1 -1
  109. package/dist/esm/index.js +3 -3
  110. package/dist/esm/lime-crm-building-blocks.js +4 -4
  111. package/dist/esm/{lime-query-validation-dGoN_93p.js → lime-query-validation-BvB2v-yP.js} +1 -1
  112. package/dist/esm/limebb-alert-dialog.entry.js +1 -1
  113. package/dist/esm/limebb-browser.entry.js +2 -2
  114. package/dist/esm/limebb-chat-icon-list_3.entry.js +2 -2
  115. package/dist/esm/limebb-chat-list.entry.js +9 -4
  116. package/dist/esm/limebb-color-palette-picker.entry.js +1 -1
  117. package/dist/esm/limebb-color-palette-swatches.entry.js +1 -1
  118. package/dist/esm/limebb-component-config.entry.js +3 -3
  119. package/dist/esm/limebb-component-picker.entry.js +2 -2
  120. package/dist/esm/limebb-composer-toolbar.entry.js +2 -2
  121. package/dist/esm/limebb-condition-tree-editor.entry.js +24 -9
  122. package/dist/esm/limebb-condition-tree.entry.js +121 -34
  123. package/dist/esm/limebb-currency-picker.entry.js +2 -2
  124. package/dist/esm/limebb-dashboard-widget.entry.js +1 -1
  125. package/dist/esm/limebb-data-cells.entry.js +2 -2
  126. package/dist/esm/limebb-date-picker.entry.js +2 -2
  127. package/dist/esm/limebb-date-range.entry.js +1 -1
  128. package/dist/esm/limebb-document-chips.entry.js +1 -1
  129. package/dist/esm/limebb-document-item.entry.js +1 -1
  130. package/dist/esm/limebb-document-picker.entry.js +1 -1
  131. package/dist/esm/limebb-empty-state.entry.js +1 -1
  132. package/dist/esm/limebb-feed-item-thumbnail-file-info.entry.js +1 -1
  133. package/dist/esm/limebb-feed-timeline-item.entry.js +2 -2
  134. package/dist/esm/limebb-feed.entry.js +2 -2
  135. package/dist/esm/limebb-filter-chip_6.entry.js +4 -4
  136. package/dist/esm/limebb-icon-picker.entry.js +1 -1
  137. package/dist/esm/limebb-info-tile-currency-format.entry.js +1 -1
  138. package/dist/esm/limebb-info-tile-date-format.entry.js +1 -1
  139. package/dist/esm/limebb-info-tile-decimal-format.entry.js +1 -1
  140. package/dist/esm/limebb-info-tile-format.entry.js +1 -1
  141. package/dist/esm/limebb-info-tile-relative-date-format.entry.js +1 -1
  142. package/dist/esm/limebb-info-tile-unit-format.entry.js +1 -1
  143. package/dist/esm/limebb-info-tile.entry.js +3 -3
  144. package/dist/esm/limebb-inline-image.entry.js +2 -2
  145. package/dist/esm/limebb-kanban-group.entry.js +2 -2
  146. package/dist/esm/limebb-kanban-item.entry.js +2 -2
  147. package/dist/esm/limebb-kanban.entry.js +1 -1
  148. package/dist/esm/limebb-lime-query-builder.entry.js +3 -3
  149. package/dist/esm/limebb-lime-query-filter-builder.entry.js +3 -3
  150. package/dist/esm/limebb-lime-query-filter-comparison_2.entry.js +4 -4
  151. package/dist/esm/limebb-lime-query-order-by-editor_2.entry.js +3 -3
  152. package/dist/esm/limebb-lime-query-order-by-item.entry.js +1 -1
  153. package/dist/esm/limebb-lime-query-response-format-builder.entry.js +3 -3
  154. package/dist/esm/limebb-lime-query-response-format-editor_2.entry.js +1 -1
  155. package/dist/esm/limebb-limeobject-file-viewer.entry.js +2 -2
  156. package/dist/esm/limebb-live-docs-info.entry.js +1 -1
  157. package/dist/esm/limebb-loader.entry.js +2 -2
  158. package/dist/esm/limebb-locale-picker.entry.js +2 -2
  159. package/dist/esm/limebb-mention-group-counter.entry.js +1 -1
  160. package/dist/esm/limebb-mention.entry.js +2 -2
  161. package/dist/esm/limebb-navigation-button_2.entry.js +1 -1
  162. package/dist/esm/limebb-notification-item.entry.js +2 -2
  163. package/dist/esm/limebb-notification-list.entry.js +2 -2
  164. package/dist/esm/limebb-object-chip.entry.js +3 -3
  165. package/dist/esm/limebb-percentage-visualizer.entry.js +2 -2
  166. package/dist/esm/limebb-property-selector.entry.js +3 -3
  167. package/dist/esm/limebb-rule-arg-filter-editor.entry.js +2 -2
  168. package/dist/esm/limebb-rule-condition-chip.entry.js +69 -0
  169. package/dist/esm/limebb-rule-condition-editor-DeY758N-.js +281 -0
  170. package/dist/esm/limebb-rule-condition-editor.entry.js +3 -0
  171. package/dist/esm/limebb-rule-editor.entry.js +217 -573
  172. package/dist/esm/limebb-rule-gate.entry.js +2 -2
  173. package/dist/esm/limebb-text-editor-picker.entry.js +1 -1
  174. package/dist/esm/limebb-text-editor.entry.js +3 -3
  175. package/dist/esm/limebb-trend-indicator.entry.js +2 -2
  176. package/dist/esm/limebb-value-comparison-editor.entry.js +3 -3
  177. package/dist/esm/{limetype-BcELY1NF.js → limetype-Muf9VutX.js} +1 -1
  178. package/dist/esm/loader.js +3 -3
  179. package/dist/esm/{web-component-template-DxbwHsvw.js → web-component-template-D1JpeNy_.js} +1 -1
  180. package/dist/lime-crm-building-blocks/index.esm.js +1 -1
  181. package/dist/lime-crm-building-blocks/lime-crm-building-blocks.esm.js +1 -1
  182. package/dist/lime-crm-building-blocks/p-0621e884.entry.js +1 -0
  183. package/dist/lime-crm-building-blocks/{p-ab0f8170.entry.js → p-087d5651.entry.js} +1 -1
  184. package/dist/lime-crm-building-blocks/{p-ce2755a0.entry.js → p-1917956c.entry.js} +1 -1
  185. package/dist/lime-crm-building-blocks/{p-07a9c8f2.entry.js → p-1ae4962d.entry.js} +1 -1
  186. package/dist/lime-crm-building-blocks/{p-021e452a.entry.js → p-23d2632b.entry.js} +1 -1
  187. package/dist/lime-crm-building-blocks/{p-ffca266e.entry.js → p-251784bf.entry.js} +1 -1
  188. package/dist/lime-crm-building-blocks/{p-635a45ad.entry.js → p-27240bb0.entry.js} +1 -1
  189. package/dist/lime-crm-building-blocks/p-2adeac66.entry.js +1 -0
  190. package/dist/lime-crm-building-blocks/{p-6a8422d2.entry.js → p-32339f09.entry.js} +1 -1
  191. package/dist/lime-crm-building-blocks/{p-1990e369.entry.js → p-3446290c.entry.js} +1 -1
  192. package/dist/lime-crm-building-blocks/{p-d495cc19.entry.js → p-35d9b3ad.entry.js} +1 -1
  193. package/dist/lime-crm-building-blocks/{p-eed0b2c2.entry.js → p-3865eec4.entry.js} +1 -1
  194. package/dist/lime-crm-building-blocks/{p-dacf9e77.entry.js → p-394b521a.entry.js} +1 -1
  195. package/dist/lime-crm-building-blocks/{p-8c36b847.entry.js → p-39a36450.entry.js} +1 -1
  196. package/dist/lime-crm-building-blocks/{p-97e75dee.entry.js → p-3b672249.entry.js} +1 -1
  197. package/dist/lime-crm-building-blocks/{p-ad5dcefd.entry.js → p-47b56a75.entry.js} +1 -1
  198. package/dist/lime-crm-building-blocks/{p-402a9c97.entry.js → p-4af3ea2c.entry.js} +1 -1
  199. package/dist/lime-crm-building-blocks/{p-e7dee7ac.entry.js → p-4bdaf436.entry.js} +1 -1
  200. package/dist/lime-crm-building-blocks/{p-cf66256a.entry.js → p-4f60b7bc.entry.js} +1 -1
  201. package/dist/lime-crm-building-blocks/{p-90f0c96b.entry.js → p-4fd9d615.entry.js} +1 -1
  202. package/dist/lime-crm-building-blocks/{p-28550961.entry.js → p-53b44865.entry.js} +1 -1
  203. package/dist/lime-crm-building-blocks/{p-7ae27308.entry.js → p-550606f6.entry.js} +1 -1
  204. package/dist/lime-crm-building-blocks/p-573f9e95.entry.js +1 -0
  205. package/dist/lime-crm-building-blocks/{p-a5f3913d.entry.js → p-5c541d0c.entry.js} +1 -1
  206. package/dist/lime-crm-building-blocks/{p-ce723c21.entry.js → p-612c6b28.entry.js} +1 -1
  207. package/dist/lime-crm-building-blocks/{p-5f682c06.entry.js → p-627b0c79.entry.js} +1 -1
  208. package/dist/lime-crm-building-blocks/{p-49d042aa.entry.js → p-6303201b.entry.js} +1 -1
  209. package/dist/lime-crm-building-blocks/{p-6f923112.entry.js → p-687640ed.entry.js} +1 -1
  210. package/dist/lime-crm-building-blocks/{p-8e9fcf3c.entry.js → p-6bd61290.entry.js} +1 -1
  211. package/dist/lime-crm-building-blocks/{p-dcb49a62.entry.js → p-6d2dba20.entry.js} +1 -1
  212. package/dist/lime-crm-building-blocks/{p-0193ed83.entry.js → p-6e2553b4.entry.js} +1 -1
  213. package/dist/lime-crm-building-blocks/{p-Cz5s8qGk.js → p-7DQ7qvMa.js} +1 -1
  214. package/dist/lime-crm-building-blocks/p-7c3d3e06.entry.js +1 -0
  215. package/dist/lime-crm-building-blocks/{p-dd02821e.entry.js → p-7d53756b.entry.js} +1 -1
  216. package/dist/lime-crm-building-blocks/{p-79d743bb.entry.js → p-895c8966.entry.js} +1 -1
  217. package/dist/lime-crm-building-blocks/{p-da35bcc7.entry.js → p-8c0455e4.entry.js} +1 -1
  218. package/dist/lime-crm-building-blocks/{p-a201df35.entry.js → p-8f80d024.entry.js} +1 -1
  219. package/dist/lime-crm-building-blocks/{p-32a81271.entry.js → p-949ed056.entry.js} +1 -1
  220. package/dist/lime-crm-building-blocks/{p-cf03a756.entry.js → p-985ae787.entry.js} +1 -1
  221. package/dist/lime-crm-building-blocks/p-9959019d.entry.js +1 -0
  222. package/dist/lime-crm-building-blocks/{p-DLec4QaM.js → p-B7whyaAL.js} +1 -1
  223. package/dist/lime-crm-building-blocks/{p-COtSgrC5.js → p-BK566_jX.js} +1 -1
  224. package/dist/lime-crm-building-blocks/p-ClYOFrOo.js +1 -0
  225. package/dist/lime-crm-building-blocks/{p-DVypQWZ4.js → p-Cve-3L4y.js} +1 -1
  226. package/dist/lime-crm-building-blocks/p-DOULPRTn.js +1 -0
  227. package/dist/lime-crm-building-blocks/{p-Cj_3f9vm.js → p-DhGRAeCH.js} +1 -1
  228. package/dist/lime-crm-building-blocks/p-DjoMDjMo.js +1 -0
  229. package/dist/lime-crm-building-blocks/p-DuWEcQ7n.js +1 -0
  230. package/dist/lime-crm-building-blocks/{p-dfaef740.entry.js → p-a1052482.entry.js} +1 -1
  231. package/dist/lime-crm-building-blocks/{p-3babfbe0.entry.js → p-a14bed52.entry.js} +1 -1
  232. package/dist/lime-crm-building-blocks/{p-cc53a8ca.entry.js → p-a2e291b4.entry.js} +1 -1
  233. package/dist/lime-crm-building-blocks/{p-8a17a7ea.entry.js → p-a2ebd5a4.entry.js} +1 -1
  234. package/dist/lime-crm-building-blocks/{p-0cbe2180.entry.js → p-a4556649.entry.js} +1 -1
  235. package/dist/lime-crm-building-blocks/{p-f5c1ed0c.entry.js → p-a598f92f.entry.js} +1 -1
  236. package/dist/lime-crm-building-blocks/{p-b44b9dbc.entry.js → p-a938384f.entry.js} +1 -1
  237. package/dist/lime-crm-building-blocks/{p-f3539042.entry.js → p-ab0210b2.entry.js} +1 -1
  238. package/dist/lime-crm-building-blocks/{p-c0d49532.entry.js → p-b272730c.entry.js} +1 -1
  239. package/dist/lime-crm-building-blocks/{p-0370200d.entry.js → p-b4571d32.entry.js} +1 -1
  240. package/dist/lime-crm-building-blocks/{p-551a36f6.entry.js → p-b72c748b.entry.js} +1 -1
  241. package/dist/lime-crm-building-blocks/{p-0ed9a7cc.entry.js → p-bac9d3a9.entry.js} +1 -1
  242. package/dist/lime-crm-building-blocks/p-bd6c12bc.entry.js +1 -0
  243. package/dist/lime-crm-building-blocks/{p-81783bd4.entry.js → p-bf693702.entry.js} +1 -1
  244. package/dist/lime-crm-building-blocks/{p-e6cc320a.entry.js → p-c58067ec.entry.js} +1 -1
  245. package/dist/lime-crm-building-blocks/{p-08797129.entry.js → p-c7bfa2e4.entry.js} +1 -1
  246. package/dist/lime-crm-building-blocks/{p-a953d48e.entry.js → p-d4635a39.entry.js} +1 -1
  247. package/dist/lime-crm-building-blocks/{p-d3c58bc1.entry.js → p-d6099dc7.entry.js} +1 -1
  248. package/dist/lime-crm-building-blocks/{p-bf05d9de.entry.js → p-d6c7cf0f.entry.js} +1 -1
  249. package/dist/lime-crm-building-blocks/{p-1ebe45b8.entry.js → p-da79c5fc.entry.js} +1 -1
  250. package/dist/lime-crm-building-blocks/p-e18a2cef.entry.js +1 -0
  251. package/dist/lime-crm-building-blocks/{p-f9991c35.entry.js → p-e19f4b3b.entry.js} +1 -1
  252. package/dist/lime-crm-building-blocks/{p-46aec244.entry.js → p-eb95767a.entry.js} +1 -1
  253. package/dist/lime-crm-building-blocks/{p-ddc4ede8.entry.js → p-ec9b5e30.entry.js} +1 -1
  254. package/dist/lime-crm-building-blocks/{p-95ba7a84.entry.js → p-f49250f3.entry.js} +1 -1
  255. package/dist/types/components/condition-tree/condition-tree-editor/condition-tree-editor.d.ts +20 -3
  256. package/dist/types/components/condition-tree/condition-tree-nodes.d.ts +11 -4
  257. package/dist/types/components/condition-tree/condition-tree-view-context.d.ts +3 -2
  258. package/dist/types/components/condition-tree/condition-tree.d.ts +41 -8
  259. package/dist/types/components/condition-tree/condition-tree.types.d.ts +21 -2
  260. package/dist/types/components/rule-editor/condition-tree-adapter.d.ts +67 -0
  261. package/dist/types/components/rule-editor/rule-condition-chip/rule-condition-chip.d.ts +82 -0
  262. package/dist/types/components/rule-editor/rule-condition-editor/rule-condition-editor.d.ts +61 -0
  263. package/dist/types/components/rule-editor/rule-editor.d.ts +105 -47
  264. package/dist/types/components/rule-editor/rule-issues.d.ts +12 -0
  265. package/dist/types/components/rule-editor/view-helpers.d.ts +16 -35
  266. package/dist/types/components.d.ts +304 -79
  267. package/dist/types/stencil-public-runtime.d.ts +61 -55
  268. package/package.json +4 -4
  269. package/dist/cjs/limebb-rule-chip-popover.cjs.entry.js +0 -82
  270. package/dist/collection/components/rule-editor/chip-picker-view.js +0 -148
  271. package/dist/collection/components/rule-editor/group-node-view.js +0 -79
  272. package/dist/collection/components/rule-editor/rule-chip-popover/rule-chip-popover.css +0 -36
  273. package/dist/collection/components/rule-editor/rule-chip-popover/rule-chip-popover.js +0 -344
  274. package/dist/collection/components/rule-editor/rule-editor-views.js +0 -43
  275. package/dist/collection/components/rule-editor/rule-operations.js +0 -145
  276. package/dist/components/limebb-rule-chip-popover.d.ts +0 -11
  277. package/dist/components/limebb-rule-chip-popover.js +0 -1
  278. package/dist/components/rule-chip-popover.js +0 -1
  279. package/dist/esm/limebb-rule-chip-popover.entry.js +0 -80
  280. package/dist/lime-crm-building-blocks/p-1578c8f0.entry.js +0 -1
  281. package/dist/lime-crm-building-blocks/p-229d018c.entry.js +0 -1
  282. package/dist/lime-crm-building-blocks/p-6331f9c5.entry.js +0 -1
  283. package/dist/lime-crm-building-blocks/p-705c53c0.entry.js +0 -1
  284. package/dist/lime-crm-building-blocks/p-84ad9159.entry.js +0 -1
  285. package/dist/lime-crm-building-blocks/p-BxCq236x.js +0 -1
  286. package/dist/lime-crm-building-blocks/p-Css8537O.js +0 -1
  287. package/dist/lime-crm-building-blocks/p-a58c9e1e.entry.js +0 -1
  288. package/dist/lime-crm-building-blocks/p-hsyotUav.js +0 -1
  289. package/dist/types/components/rule-editor/chip-picker-view.d.ts +0 -35
  290. package/dist/types/components/rule-editor/group-node-view.d.ts +0 -11
  291. package/dist/types/components/rule-editor/rule-chip-popover/rule-chip-popover.d.ts +0 -43
  292. package/dist/types/components/rule-editor/rule-editor-views.d.ts +0 -58
  293. package/dist/types/components/rule-editor/rule-operations.d.ts +0 -70
@@ -10,20 +10,30 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
10
10
  };
11
11
  import { Host, h, } from "@stencil/core";
12
12
  import { PlatformServiceName, SelectContext, } from "@limetech/lime-web-components";
13
- import { deleteNode, getNode, replaceNode, updateArgs, } from "./rule-operations";
14
- import { extractGroup, RuleNodeView, } from "./rule-editor-views";
15
- import { buildChipPath, extractRef } from "./chip-picker-view";
16
- import { createPrimitiveOptions, primitiveReadsCovered } from "./view-helpers";
13
+ import { createTranslator } from "../condition-tree/condition-tree-translate";
14
+ import { createRuleConditionTreeAdapter, groupOf, } from "./condition-tree-adapter";
15
+ import { collectRuleIssues } from "./rule-issues";
16
+ import { createPrimitiveOptions, createSearcher, primitiveReadsCovered, primitiveTitle, } from "./view-helpers";
17
+ // The adapter names the chip and the args editor by tag only, and a tag that
18
+ // appears solely as a string is not a dependency the compiler can see.
19
+ import "./rule-condition-chip/rule-condition-chip";
20
+ import "./rule-condition-editor/rule-condition-editor";
17
21
  import { RuleModeView } from "./rule-editor-mode-view";
18
22
  import { ALWAYS_PRIMITIVE_ID, ruleForMode, ruleMode, } from "./rule-editor-modes";
19
23
  import { createRandomString } from "../../util/random-string";
20
24
  /**
21
25
  * Tree editor for {@link Rule}.
22
26
  *
23
- * Renders a `Rule` value as a tree of nodes. Lets an author pick
24
- * primitive refs in `all` / `any` groups, toggle negation, delete
25
- * nodes, and edit per-primitive args via the editor declared on each
26
- * primitive's metadata.
27
+ * Renders a `Rule` value as a `limebb-condition-tree`. Lets an author
28
+ * add primitive refs to `all` / `any` groups and to the negations of
29
+ * those two, nest groups, negate a single ref, delete nodes, and edit
30
+ * per-primitive args via the editor declared on each primitive's
31
+ * metadata.
32
+ *
33
+ * The tree owns every structural edit, and knows nothing about rules. A
34
+ * `Rule` reaches it through an adapter — see `condition-tree-adapter.ts`
35
+ * — which is also where the group negation the rule model writes as a
36
+ * `not` wrapper is folded into the combinator the tree shows.
27
37
  *
28
38
  * The component is value-in / value-out. Pass `value` and listen for
29
39
  * `change`; persistence is the caller's concern.
@@ -64,8 +74,6 @@ import { createRandomString } from "../../util/random-string";
64
74
  */
65
75
  export class RuleEditor {
66
76
  constructor() {
67
- this.issues = [];
68
- this.openChipPath = null;
69
77
  /**
70
78
  * The mode the author last clicked, held until `value` reads back
71
79
  * as it.
@@ -76,10 +84,27 @@ export class RuleEditor {
76
84
  * what the author just clicked.
77
85
  */
78
86
  this.modeOverride = null;
79
- this.focusOnOpen = false;
80
87
  this.metadataById = new Map();
81
- this.allPrimitiveOptions = [];
88
+ /**
89
+ * How each registered primitive reads, by id. Translated once here
90
+ * because the platform's translator parses the message afresh on
91
+ * every call, and the adapter would otherwise do that per condition,
92
+ * several times over, on every edit.
93
+ */
94
+ this.primitiveTitles = new Map();
82
95
  this.availablePrimitiveOptions = [];
96
+ this.searcher = createSearcher([]);
97
+ /**
98
+ * What validation found, by the node it belongs to.
99
+ */
100
+ this.issuesByNode = new Map();
101
+ /**
102
+ * The conditions added here rather than loaded, which a `RuleRef`
103
+ * does not record. The adapter reads it to decide which condition
104
+ * opens itself. Replaced when the tree goes, since a condition still
105
+ * listed when the author comes back would open itself again.
106
+ */
107
+ this.created = new WeakSet();
83
108
  this.reachableSlots = new Set();
84
109
  this.normalizedCache = null;
85
110
  this.hasLoaded = false;
@@ -93,6 +118,9 @@ export class RuleEditor {
93
118
  * conditions are gone, rather than handing back the ones they
94
119
  * removed. With nothing stashed, `conditional` emits no rule, which
95
120
  * is how the editor already says "the author cleared this".
121
+ *
122
+ * What is not stashed is which conditions had just been added, so
123
+ * that none of them opens itself again on the way back.
96
124
  * @param mode
97
125
  */
98
126
  this.handleModeChange = (mode) => {
@@ -100,32 +128,28 @@ export class RuleEditor {
100
128
  if (this.currentMode === 'conditional') {
101
129
  this.stashedTree = this.value;
102
130
  }
131
+ if (mode !== 'conditional') {
132
+ this.created = new WeakSet();
133
+ }
103
134
  this.modeOverride = mode;
104
135
  this.change.emit((_a = ruleForMode(mode)) !== null && _a !== void 0 ? _a : this.stashedTree);
105
136
  };
106
- this.handleDelete = (path) => {
107
- this.openChipPath = null;
108
- this.focusOnOpen = false;
109
- this.emitIfChanged(deleteNode(this.normalizedValue, path));
110
- };
111
- this.handleUpdateArgs = (path, args) => {
112
- this.emitIfChanged(updateArgs(this.normalizedValue, path, args));
113
- };
114
- this.handleReplaceNode = (path, replacement) => {
115
- const autoOpenPath = this.autoOpenPathFor(path, replacement);
116
- this.focusOnOpen = autoOpenPath !== null;
117
- if (autoOpenPath !== null) {
118
- this.openChipPath = autoOpenPath;
119
- }
120
- this.emitIfChanged(replaceNode(this.normalizedValue, path, replacement));
121
- };
122
- this.handleChipInteract = (path) => {
123
- this.openChipPath = path;
124
- this.focusOnOpen = false;
125
- };
126
- this.handlePopoverClose = () => {
127
- this.openChipPath = null;
128
- this.focusOnOpen = false;
137
+ /**
138
+ * Take in a tree the author changed. The tree reports `null` when
139
+ * the last condition goes, which for a rule means there is none —
140
+ * the same thing an emptied editor has always emitted.
141
+ *
142
+ * Editing the tree is only possible in `conditional`, so the edit
143
+ * itself records the mode: without this, a tree emptied to nothing
144
+ * would read back as the first offered mode and rewrite the setting
145
+ * under the author.
146
+ * @param event
147
+ */
148
+ this.handleTreeChange = (event) => {
149
+ var _a;
150
+ event.stopPropagation();
151
+ this.modeOverride = 'conditional';
152
+ this.change.emit((_a = event.detail) !== null && _a !== void 0 ? _a : undefined);
129
153
  };
130
154
  }
131
155
  componentWillLoad() {
@@ -136,6 +160,7 @@ export class RuleEditor {
136
160
  this.indexMetadata();
137
161
  this.rebuildAvailableOptions();
138
162
  this.runValidation();
163
+ this.rebuildAdapter();
139
164
  }
140
165
  /**
141
166
  * Re-walk reachable slots when the editor is re-attached to the DOM,
@@ -150,6 +175,7 @@ export class RuleEditor {
150
175
  this.computeReachableSlots();
151
176
  this.rebuildAvailableOptions();
152
177
  this.runValidation();
178
+ this.rebuildAdapter();
153
179
  }
154
180
  componentDidLoad() {
155
181
  this.hasLoaded = true;
@@ -166,7 +192,7 @@ export class RuleEditor {
166
192
  this.rebuildFromRegistries();
167
193
  }
168
194
  render() {
169
- return (h(Host, { key: '98380987c6687ce58cca822ea2fd2f106787897b' }, this.renderHelp(), h("limel-notched-outline", { key: 'bbf2d6da192524c4cf8e2e616ca2dab6206a43a6', label: this.label, labelId: this.labelId, required: this.required, readonly: this.readonly, disabled: this.disabled, invalid: this.invalid, hasValue: true, hasFloatingLabel: true }, h("div", { key: '9e7043bae1b8f60f9ead7b0ed1874dae32944e9e', slot: "content", class: {
195
+ return (h(Host, { key: 'eb89af0c748f82d8e60b1209c4fcce3475ac2934' }, this.renderHelp(), h("limel-notched-outline", { key: '9d454ec87268aa9ff07776d38882365a544a64e7', label: this.label, labelId: this.labelId, required: this.required, readonly: this.readonly, disabled: this.disabled, invalid: this.invalid, hasValue: true, hasFloatingLabel: true }, h("div", { key: '57293e75c641d4909a4d2e1d3a3d2c20a60a4512', slot: "content", class: {
170
196
  'rule-editor': true,
171
197
  'rule-editor--disabled': this.disabled,
172
198
  }, role: "group", "aria-labelledby": this.label ? this.labelId : undefined, "aria-describedby": this.helperText ? this.helperTextId : undefined }, this.renderModes(), this.renderTree())), this.renderHelperLine()));
@@ -183,13 +209,18 @@ export class RuleEditor {
183
209
  * The condition tree, shown unless a mode other than `conditional`
184
210
  * is selected — an unconditional rule has no conditions to show.
185
211
  * A caller offering no modes at all gets the tree, as before.
212
+ *
213
+ * An unset rule is handed over as unset, rather than as an empty
214
+ * group: the tree draws the group an author's first condition will
215
+ * land in, and drawing one here would only be a second opinion on
216
+ * what that looks like.
186
217
  */
187
218
  renderTree() {
188
219
  const mode = this.currentMode;
189
220
  if (mode && mode !== 'conditional') {
190
221
  return null;
191
222
  }
192
- return (h(RuleNodeView, { node: this.normalizedValue, path: [], ctx: this.createRenderContext() }));
223
+ return (h("limebb-condition-tree", { platform: this.platform, context: this.effectiveContext, value: this.normalizedValue, adapter: this.adapter, addOptions: this.availablePrimitiveOptions, addSearcher: this.searcher, readonly: this.readonly, disabled: this.disabled, onChange: this.handleTreeChange }));
193
224
  }
194
225
  renderHelperLine() {
195
226
  if (!this.helperText) {
@@ -203,27 +234,6 @@ export class RuleEditor {
203
234
  }
204
235
  return h("limel-help", { value: this.help });
205
236
  }
206
- createRenderContext() {
207
- return {
208
- issues: this.issues,
209
- metadataById: this.metadataById,
210
- allPrimitiveOptions: this.allPrimitiveOptions,
211
- availablePrimitiveOptions: this.availablePrimitiveOptions,
212
- isMutable: !this.readonly && !this.disabled,
213
- readonly: this.readonly,
214
- disabled: this.disabled,
215
- platform: this.platform,
216
- context: this.effectiveContext,
217
- translator: this.translator,
218
- openChipPath: this.openChipPath,
219
- focusOnOpen: this.focusOnOpen,
220
- onDelete: this.handleDelete,
221
- onUpdateArgs: this.handleUpdateArgs,
222
- onReplaceNode: this.handleReplaceNode,
223
- onChipInteract: this.handleChipInteract,
224
- onPopoverClose: this.handlePopoverClose,
225
- };
226
- }
227
237
  /**
228
238
  * The mode the editor is in, or `undefined` when it offers none —
229
239
  * then it is the plain tree editor it was before modes existed.
@@ -257,51 +267,14 @@ export class RuleEditor {
257
267
  this.modeOverride = null;
258
268
  }
259
269
  }
260
- /**
261
- * Path of a newly added chip whose primitive declares a config
262
- * component, so its args editor opens immediately on add. The new
263
- * ref is found by object identity — the picker reuses existing ref
264
- * objects and only the added chip is a fresh node — so adding a
265
- * second instance of a primitive already in the group is still
266
- * detected. Returns `null` unless exactly one ref was added and it
267
- * has an editor, leaving the open chip untouched for removals,
268
- * multi-adds, and negation.
269
- * @param path
270
- * @param replacement
271
- */
272
- autoOpenPathFor(path, replacement) {
273
- var _a;
274
- if (replacement.type !== 'all' && replacement.type !== 'any') {
275
- return null;
276
- }
277
- const previous = getNode(this.normalizedValue, path);
278
- if (previous === undefined ||
279
- (previous.type !== 'all' && previous.type !== 'any')) {
280
- return null;
281
- }
282
- const previousRefs = new Set(previous.rules
283
- .map((rule) => { var _a; return (_a = extractRef(rule)) === null || _a === void 0 ? void 0 : _a.ref; })
284
- .filter((ref) => ref !== undefined));
285
- const added = replacement.rules
286
- .map((rule, index) => {
287
- var _a;
288
- const ref = (_a = extractRef(rule)) === null || _a === void 0 ? void 0 : _a.ref;
289
- return ref && !previousRefs.has(ref) ? { ref, index } : null;
290
- })
291
- .filter((entry) => entry !== null);
292
- if (added.length !== 1) {
293
- return null;
294
- }
295
- const [{ ref, index }] = added;
296
- return ((_a = this.metadataById.get(ref.id)) === null || _a === void 0 ? void 0 : _a.configComponent)
297
- ? buildChipPath(path, index)
298
- : null;
299
- }
300
270
  indexMetadata() {
301
271
  var _a, _b, _c;
302
272
  const metadata = (_c = (_b = (_a = this.ruleRegistry).listMetadata) === null || _b === void 0 ? void 0 : _b.call(_a)) !== null && _c !== void 0 ? _c : [];
303
273
  this.metadataById = new Map(metadata.map((item) => [item.id, item]));
304
- this.allPrimitiveOptions = createPrimitiveOptions(this.metadataById, this.translator);
274
+ this.primitiveTitles = new Map(metadata.map((item) => [
275
+ item.id,
276
+ primitiveTitle(item, this.translator),
277
+ ]));
305
278
  }
306
279
  /**
307
280
  * Recompute the cached add-palette options. The inputs — indexed
@@ -311,6 +284,7 @@ export class RuleEditor {
311
284
  */
312
285
  rebuildAvailableOptions() {
313
286
  this.availablePrimitiveOptions = createPrimitiveOptions(this.availablePrimitiveMetadata(), this.translator);
287
+ this.searcher = createSearcher(this.availablePrimitiveOptions);
314
288
  }
315
289
  /**
316
290
  * The subset of registered metadata offered for adding in the
@@ -318,7 +292,7 @@ export class RuleEditor {
318
292
  * reachable slots are dropped, and so is the always primitive —
319
293
  * it reads nothing, so it is always covered, but an "Always" chip
320
294
  * among a group's conditions says nothing. Filtering only the
321
- * palette — not the full `allPrimitiveOptions` — keeps
295
+ * palette — the adapter still reads the whole index — keeps
322
296
  * already-placed chips resolving to their proper title even when
323
297
  * their read slot isn't reachable.
324
298
  */
@@ -358,45 +332,81 @@ export class RuleEditor {
358
332
  ]);
359
333
  }
360
334
  runValidation() {
361
- if (!this.value) {
362
- this.issues = [];
363
- return;
364
- }
365
- const result = this.ruleRegistry.validate(this.normalizedValue, [
366
- ...this.reachableSlots,
367
- ]);
368
- this.issues = result.ok ? [] : result.issues;
335
+ this.issuesByNode = this.findIssues();
369
336
  }
370
337
  /**
371
- * Emit an edited tree. Editing the tree is only possible in
372
- * `conditional`, so the edit itself records the mode: an edit that
373
- * empties the tree emits no rule, and without this the empty value
374
- * would read back as the first offered mode.
375
- * @param next
338
+ * What the registry finds wrong with the rule, gathered by the node
339
+ * each problem belongs to. Validation runs against the normalized
340
+ * rule, which is also what the tree is handed, so the paths the
341
+ * registry reports address the very nodes the tree draws.
342
+ *
343
+ * A rule the registry cannot even walk — one hand-edited into a shape
344
+ * that is not a rule — makes it throw rather than report. That is the
345
+ * rule an author most needs the editor for, so the throw is caught
346
+ * and the editor drawn anyway: the tree marks the offending condition
347
+ * unreadable itself, which is the same thing validation would have
348
+ * said and in the place it belongs.
376
349
  */
377
- emitIfChanged(next) {
378
- if (next === this.normalizedValue) {
379
- return;
350
+ findIssues() {
351
+ const root = this.normalizedValue;
352
+ if (!root) {
353
+ return new Map();
354
+ }
355
+ try {
356
+ const result = this.ruleRegistry.validate(root, [
357
+ ...this.reachableSlots,
358
+ ]);
359
+ return result.ok
360
+ ? new Map()
361
+ : collectRuleIssues(root, result.issues);
362
+ }
363
+ catch (error) {
364
+ // The throw names the node it choked on. What the author needs is
365
+ // already in the tree; this is what tells a developer an unreadable
366
+ // rule from a registry that could not answer for a readable one.
367
+ console.warn('rule-editor could not validate the rule', {
368
+ rule: root,
369
+ error,
370
+ });
371
+ return new Map();
380
372
  }
381
- this.modeOverride = 'conditional';
382
- this.change.emit(collapseEmptyRoot(next));
383
373
  }
384
374
  /**
385
- * Wrap any non-group `value` in a top-level `all` so the editor
386
- * always has a group to render against. When `value` is unset,
387
- * returns a fresh empty `all`-group as a render-only placeholder —
388
- * `emitNormalization` will *not* push that placeholder back to the
389
- * caller, so an unset value stays unset until the user edits.
375
+ * Gather what the tree draws from into a new adapter, which is how a
376
+ * change the rule does not carry reaches the screen at all.
377
+ *
378
+ * Not rebuilt for a validation pass: that runs because the rule
379
+ * changed, and the tree is already redrawing for the same reason.
380
+ * Rebuilding there would sync its open state twice for one edit.
381
+ */
382
+ rebuildAdapter() {
383
+ this.adapter = createRuleConditionTreeAdapter({
384
+ metadata: this.metadataById,
385
+ titles: this.primitiveTitles,
386
+ translate: createTranslator(this.platform),
387
+ issues: () => this.issuesByNode,
388
+ created: () => this.created,
389
+ });
390
+ }
391
+ /**
392
+ * Wrap any non-group `value` in a top-level `all`, so that a lone
393
+ * condition has a group to grow in. An unset value stays unset: the
394
+ * tree draws the group a first condition will land in, and
395
+ * `emitNormalization` never pushes that placeholder back to the
396
+ * caller, so "no rule yet" stays distinguishable from "the author
397
+ * cleared this".
390
398
  *
391
399
  * An unconditional mode is the exception: its sentinel is left
392
400
  * exactly as it came in, because wrapping it would rewrite the
393
401
  * shape the mode is read back from.
394
402
  *
395
- * Memoized so callers that read this several times in one handler
396
- * see the same reference — the identity check in `emitIfChanged`
397
- * depends on it.
403
+ * Memoized, so that the tree is handed the same rule on every
404
+ * render and redraws only when the rule itself changes.
398
405
  */
399
406
  get normalizedValue() {
407
+ if (!this.value) {
408
+ return undefined;
409
+ }
400
410
  const mode = this.currentMode;
401
411
  if (this.normalizedCache !== null &&
402
412
  this.normalizedCache.source === this.value &&
@@ -529,7 +539,7 @@ export class RuleEditor {
529
539
  "name": "inheritdoc",
530
540
  "text": undefined
531
541
  }],
532
- "text": "The value of the current property"
542
+ "text": "The value of the current property\nThe rule under edit. Hand back what `change` emitted, not a copy:\nwhich condition is open, which have been visited and what\nvalidation said about each are all tracked by object identity, so\na deep-cloned rule reads as a different one that happens to look\nthe same."
533
543
  },
534
544
  "getter": false,
535
545
  "setter": false
@@ -619,7 +629,7 @@ export class RuleEditor {
619
629
  "name": "inheritdoc",
620
630
  "text": undefined
621
631
  }],
622
- "text": "Whether or not the current property is readonly\nThe mutation UI (delete and negate toggles, add-group button) is\nhidden when set. The args editor for each ref is still rendered,\nwith `readonly` forwarded to it."
632
+ "text": "Whether or not the current property is readonly\nThe controls that add, delete and negate are not rendered when set,\nleaving the rule to be read. The args editor for each ref is still\nrendered, with `readonly` forwarded to it."
623
633
  },
624
634
  "getter": false,
625
635
  "setter": false,
@@ -641,7 +651,7 @@ export class RuleEditor {
641
651
  "name": "inheritdoc",
642
652
  "text": undefined
643
653
  }],
644
- "text": "Whether or not the current property is disabled\nThe mutation UI is hidden when set. The args editor is rendered\nwith `disabled` forwarded to it."
654
+ "text": "Whether or not the current property is disabled\nEvery control stays where it is, dimmed and inert, when set. The\nargs editor is rendered with `disabled` forwarded to it."
645
655
  },
646
656
  "getter": false,
647
657
  "setter": false,
@@ -735,10 +745,9 @@ export class RuleEditor {
735
745
  static get states() {
736
746
  return {
737
747
  "resolvedContext": {},
738
- "issues": {},
739
- "openChipPath": {},
740
748
  "modeOverride": {},
741
- "availablePrimitiveOptions": {}
749
+ "availablePrimitiveOptions": {},
750
+ "adapter": {}
742
751
  };
743
752
  }
744
753
  static get events() {
@@ -750,7 +759,7 @@ export class RuleEditor {
750
759
  "composed": true,
751
760
  "docs": {
752
761
  "tags": [],
753
- "text": "Emitted when the rule tree is mutated. Detail is the new rule, or\n`undefined` when the user has cleared the editor to an empty root\ngroup \u2014 callers can persist `undefined` as \"no rule\" without\nhaving to inspect the rule shape themselves."
762
+ "text": "The edited rule, or nothing when the author has cleared it.\n\nWhat comes out is what should go back in as `value` \u2014 see the note\nthere on why the objects themselves matter."
754
763
  },
755
764
  "complexType": {
756
765
  "original": "Rule | undefined",
@@ -785,32 +794,13 @@ const EMPTY_CONTEXT = Object.freeze({
785
794
  id: null,
786
795
  });
787
796
  function normalize(value, mode) {
788
- if (!value) {
789
- return { type: 'all', rules: [] };
790
- }
791
797
  // Neither sentinel is a group, and wrapping one would rewrite the
792
798
  // very shape the mode is read back from.
793
799
  if (mode === 'always' || mode === 'never') {
794
800
  return value;
795
801
  }
796
- if (extractGroup(value)) {
802
+ if (groupOf(value)) {
797
803
  return value;
798
804
  }
799
805
  return { type: 'all', rules: [value] };
800
806
  }
801
- /**
802
- * Treat an empty root `all`/`any` as "no rule". Mapping that back to
803
- * `undefined` on emit keeps the form contract a clean
804
- * `Rule | undefined` — callers don't have to inspect rule shape to
805
- * tell "user cleared this" from "user has a real rule". A negated
806
- * empty group (`not(all())` etc.) is left intact — vacuous either
807
- * direction, but the user explicitly opted into the wrapper, so we
808
- * don't second-guess.
809
- * @param rule
810
- */
811
- function collapseEmptyRoot(rule) {
812
- if (rule.type !== 'all' && rule.type !== 'any') {
813
- return rule;
814
- }
815
- return rule.rules.length === 0 ? undefined : rule;
816
- }
@@ -0,0 +1,89 @@
1
+ /**
2
+ * The problems the registry found, gathered by the node each belongs to.
3
+ *
4
+ * The registry addresses an issue by path — `['rules', 0, 'rule']` for
5
+ * `root.rules[0].rule` — while the tree asks about one node at a time and never
6
+ * says where it is. Resolving the paths once, here, bridges the two.
7
+ * @param root
8
+ * @param issues
9
+ */
10
+ export function collectRuleIssues(root, issues) {
11
+ var _a, _b;
12
+ const owners = displayOwners(root);
13
+ const byNode = new Map();
14
+ for (const issue of issues) {
15
+ const node = nodeAt(root, issue.path);
16
+ // An empty path means the rule as a whole, and one the path cannot
17
+ // reach has nowhere better to go than the root either.
18
+ const owner = (_a = (node && owners.get(node))) !== null && _a !== void 0 ? _a : root;
19
+ byNode.set(owner, [...((_b = byNode.get(owner)) !== null && _b !== void 0 ? _b : []), issue.message]);
20
+ }
21
+ return byNode;
22
+ }
23
+ /**
24
+ * Which node each node is drawn as part of. Most stand for themselves; the
25
+ * exception is everything under a `not`, which is drawn as that `not` — the
26
+ * two are one thing on screen, and only the wrapper has somewhere to show it.
27
+ * @param root
28
+ */
29
+ function displayOwners(root) {
30
+ const owners = new Map();
31
+ const visit = (node, owner) => {
32
+ // A hand-edited rule can hold a `null` where a node should be. It is
33
+ // drawn, as something that cannot be read, so it is walked past here.
34
+ if (typeof node !== 'object' || node === null) {
35
+ return;
36
+ }
37
+ owners.set(node, owner);
38
+ if (node.type === 'not') {
39
+ visit(node.rule, owner);
40
+ return;
41
+ }
42
+ if ((node.type === 'all' || node.type === 'any') &&
43
+ Array.isArray(node.rules)) {
44
+ for (const child of node.rules) {
45
+ visit(child, child);
46
+ }
47
+ }
48
+ };
49
+ visit(root, root);
50
+ return owners;
51
+ }
52
+ /**
53
+ * The node a validation path addresses, or nothing when it addresses none.
54
+ *
55
+ * Walked one hop at a time because the two the registry emits have different
56
+ * shapes: into a negation is the single segment `rule`, into the *n*-th child
57
+ * of a group is the pair `rules`, *n*. Anything else is not a path this rule
58
+ * can be walked by.
59
+ * @param root
60
+ * @param path
61
+ */
62
+ function nodeAt(root, path) {
63
+ let node = root;
64
+ let index = 0;
65
+ while (index < path.length) {
66
+ // The same `null` can be standing one hop short of the path's end,
67
+ // with no hop to take from it. Asked for `type`, it would throw.
68
+ if (node === null || typeof node !== 'object') {
69
+ return undefined;
70
+ }
71
+ const key = path[index];
72
+ if (key === 'rule' && node.type === 'not') {
73
+ node = node.rule;
74
+ index += 1;
75
+ continue;
76
+ }
77
+ const child = path[index + 1];
78
+ if (key === 'rules' &&
79
+ (node.type === 'all' || node.type === 'any') &&
80
+ Array.isArray(node.rules) &&
81
+ typeof child === 'number') {
82
+ node = node.rules[child];
83
+ index += 2;
84
+ continue;
85
+ }
86
+ return undefined;
87
+ }
88
+ return node;
89
+ }
@@ -1,26 +1,7 @@
1
- const UNKNOWN_ICON = {
2
- name: 'question',
3
- color: 'rgb(var(--color-glaucous-light))',
4
- };
5
1
  /**
6
- * Class map for a rule-node container. Adds the type modifier and an
7
- * `invalid` flag when validation issues attach to this node.
8
- * @param type
9
- * @param issues
10
- */
11
- export function nodeClasses(type, issues) {
12
- return {
13
- 'rule-node': true,
14
- [`rule-node--${type}`]: true,
15
- 'rule-node--invalid': issues.length > 0,
16
- };
17
- }
18
- /**
19
- * Build the searchable list shown by the primitive pickers. Cached on
20
- * the render context so it isn't recomputed per node. `meta.title` and
21
- * `meta.description` are passed through the translator so callers can
22
- * register translation keys as metadata — plain strings travel through
23
- * unchanged.
2
+ * The primitives the add button offers. Titles and descriptions go through the
3
+ * translator, so a caller can register translation keys as metadata — plain
4
+ * strings travel through unchanged.
24
5
  * @param metadataById
25
6
  * @param translator
26
7
  */
@@ -28,7 +9,7 @@ export function createPrimitiveOptions(metadataById, translator) {
28
9
  return [...metadataById.values()]
29
10
  .map((meta) => ({
30
11
  value: meta.id,
31
- text: meta.title ? translator.get(meta.title) : meta.id,
12
+ text: primitiveTitle(meta, translator),
32
13
  secondaryText: meta.description
33
14
  ? translator.get(meta.description)
34
15
  : '',
@@ -36,6 +17,15 @@ export function createPrimitiveOptions(metadataById, translator) {
36
17
  }))
37
18
  .sort((a, b) => a.text.localeCompare(b.text));
38
19
  }
20
+ /**
21
+ * How a primitive reads: its translated title, or its bare id when it has none
22
+ * to give. The add menu and the chip both read it from here, so they agree.
23
+ * @param meta
24
+ * @param translator
25
+ */
26
+ export function primitiveTitle(meta, translator) {
27
+ return meta.title ? translator.get(meta.title) : meta.id;
28
+ }
39
29
  /**
40
30
  * Whether every context key a primitive reads is in the reachable set.
41
31
  * A primitive that reads nothing is always covered.
@@ -46,23 +36,9 @@ export function primitiveReadsCovered(meta, reachable) {
46
36
  return meta.reads.every((key) => reachable.has(key));
47
37
  }
48
38
  /**
49
- * Find the picker item for `id`, falling back to a placeholder marked
50
- * with the unknown-primitive icon when the id isn't in the registry.
51
- * @param allItems
52
- * @param id
53
- */
54
- export function resolveItem(allItems, id) {
55
- var _a;
56
- return ((_a = allItems.find((item) => item.value === id)) !== null && _a !== void 0 ? _a : {
57
- value: id,
58
- text: id,
59
- icon: UNKNOWN_ICON,
60
- });
61
- }
62
- /**
63
- * Build a picker `searcher` bound to a fixed item list. Both the ref
64
- * picker and the chip picker want exactly this — wrapping
65
- * {@link searchItems} in a promise — and deserve to share it.
39
+ * Narrow the primitives as the user types, for the search field at the top of
40
+ * the add menu. Every word has to match somewhere — title, description or id —
41
+ * so that "deal won" finds "Won deals".
66
42
  * @param items
67
43
  */
68
44
  export function createSearcher(items) {
@@ -77,6 +53,8 @@ function searchItems(allItems, query) {
77
53
  var _a, _b;
78
54
  return item.text.toLocaleLowerCase().includes(part) ||
79
55
  ((_a = item.secondaryText) === null || _a === void 0 ? void 0 : _a.toLocaleLowerCase().includes(part)) ||
80
- ((_b = item.value) === null || _b === void 0 ? void 0 : _b.toLocaleLowerCase().includes(part));
56
+ String((_b = item.value) !== null && _b !== void 0 ? _b : '')
57
+ .toLocaleLowerCase()
58
+ .includes(part);
81
59
  }));
82
60
  }
@@ -0,0 +1 @@
1
+ const n={all:{type:"all",negated:!1},any:{type:"any",negated:!1},"not-all":{type:"all",negated:!0},none:{type:"any",negated:!0}},e={all:"not-all",any:"none","not-all":"all",none:"any"};function t(n){return{describe:(e,t)=>function(n,e,t){const r=t.issues().get(n),d=o(n);if(d)return{kind:"group",combinator:d.combinator,children:d.rules,issues:r};const f=i(n);return f?function(n,e,t,o){const{ref:i,negated:r}=n,l=t.metadata.get(i.id),d=t.created().has(i),f=null==l?void 0:l.configComponent;return{kind:"leaf",chip:{label:u(i,t),icon:a(l),invalid:!l||!!(null==o?void 0:o.length),component:{name:"limebb-rule-condition-chip",props:{negated:r,iconColor:c(l)}}},negated:r,issues:o,autoOpen:d&&!!f,editor:f&&{name:"limebb-rule-condition-editor",props:{configComponent:f,focusOnOpen:d&&!e.visited}}}}(f,e,t,r):function(n,e,t){var o;return{kind:"leaf",chip:{label:null!==(o=l(n))&&void 0!==o?o:"…",icon:"question",invalid:!0,component:{name:"limebb-rule-condition-chip"}},issues:(null==t?void 0:t.length)?t:[e.translate("webclient.rule-editor.unreadable-condition","This condition cannot be read, and so cannot be edited here.")]}}(n,t,r)}(e,t,n),group:d,negate:f,createLeaf:e=>{var t;const o={type:"ref",id:String(null!==(t=null==e?void 0:e.value)&&void 0!==t?t:"")};return n.created().add(o),o}}}function o(n){if(!r(n))return;if("all"===n.type||"any"===n.type)return Array.isArray(n.rules)?{combinator:n.type,rules:n.rules}:void 0;if("not"!==n.type)return;const t=o(n.rule);return t?{combinator:e[t.combinator],rules:t.rules}:void 0}function i(n){if(r(n))return"ref"===n.type?{ref:n,negated:!1}:"not"===n.type&&r(n.rule)&&"ref"===n.rule.type?{ref:n.rule,negated:!0}:void 0}function r(n){return"object"==typeof n&&null!==n}function u(n,e){return e.titles.get(n.id)||n.id||"…"}function l(n){if(!r(n))return;const e=n.type;return"string"==typeof e&&e?e:void 0}function a(n){return n?n.icon?"string"==typeof n.icon?n.icon:n.icon.name:void 0:"question"}function c(n){return"object"==typeof(null==n?void 0:n.icon)?n.icon.color:void 0}function d(e,t){const o={type:n[e].type,rules:[...t]};return n[e].negated?{type:"not",rule:o}:o}function f(n,e){return e?"not"===n.type?n:{type:"not",rule:n}:"not"===n.type?n.rule:n}export{t as c,o as g,i as r}