@limetech/lime-crm-building-blocks 2.0.4 → 2.2.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 (288) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/dist/cjs/condition-tree-translate-B_qIQz9s.js +27 -0
  3. package/dist/cjs/index.cjs.js +6 -0
  4. package/dist/cjs/lime-crm-building-blocks.cjs.js +1 -1
  5. package/dist/cjs/limebb-alert-dialog.cjs.entry.js +1 -1
  6. package/dist/cjs/limebb-browser.cjs.entry.js +2 -2
  7. package/dist/cjs/limebb-chat-icon-list_3.cjs.entry.js +4 -4
  8. package/dist/cjs/limebb-chat-list.cjs.entry.js +1 -1
  9. package/dist/cjs/limebb-color-palette-picker.cjs.entry.js +1 -1
  10. package/dist/cjs/limebb-color-palette-swatches.cjs.entry.js +1 -1
  11. package/dist/cjs/limebb-composer-toolbar.cjs.entry.js +2 -2
  12. package/dist/cjs/limebb-condition-tree-editor.cjs.entry.js +90 -0
  13. package/dist/cjs/limebb-condition-tree.cjs.entry.js +882 -0
  14. package/dist/cjs/limebb-currency-picker.cjs.entry.js +1 -1
  15. package/dist/cjs/limebb-dashboard-widget.cjs.entry.js +1 -1
  16. package/dist/cjs/limebb-date-picker.cjs.entry.js +1 -1
  17. package/dist/cjs/limebb-date-range.cjs.entry.js +1 -1
  18. package/dist/cjs/limebb-document-chips.cjs.entry.js +1 -1
  19. package/dist/cjs/limebb-document-item.cjs.entry.js +2 -2
  20. package/dist/cjs/limebb-document-picker.cjs.entry.js +1 -1
  21. package/dist/cjs/limebb-feed-item-thumbnail-file-info.cjs.entry.js +1 -1
  22. package/dist/cjs/limebb-feed-timeline-item.cjs.entry.js +1 -1
  23. package/dist/cjs/limebb-feed.cjs.entry.js +1 -1
  24. package/dist/cjs/limebb-filter-chip_6.cjs.entry.js +7 -7
  25. package/dist/cjs/limebb-icon-picker.cjs.entry.js +1 -1
  26. package/dist/cjs/limebb-info-tile-format.cjs.entry.js +1 -1
  27. package/dist/cjs/limebb-info-tile.cjs.entry.js +1 -1
  28. package/dist/cjs/limebb-kanban-group.cjs.entry.js +1 -1
  29. package/dist/cjs/limebb-kanban-item.cjs.entry.js +1 -1
  30. package/dist/cjs/limebb-lime-query-builder.cjs.entry.js +1 -1
  31. package/dist/cjs/limebb-lime-query-filter-comparison_2.cjs.entry.js +2 -2
  32. package/dist/cjs/limebb-lime-query-order-by-editor_2.cjs.entry.js +2 -2
  33. package/dist/cjs/limebb-lime-query-order-by-item.cjs.entry.js +2 -2
  34. package/dist/cjs/limebb-lime-query-response-format-builder.cjs.entry.js +1 -1
  35. package/dist/cjs/limebb-lime-query-response-format-editor_2.cjs.entry.js +1 -1
  36. package/dist/cjs/limebb-live-docs-info.cjs.entry.js +2 -2
  37. package/dist/cjs/limebb-locale-picker.cjs.entry.js +1 -1
  38. package/dist/cjs/limebb-mention-group-counter.cjs.entry.js +2 -2
  39. package/dist/cjs/limebb-navigation-button_2.cjs.entry.js +2 -2
  40. package/dist/cjs/limebb-notification-item.cjs.entry.js +1 -1
  41. package/dist/cjs/limebb-percentage-visualizer.cjs.entry.js +2 -2
  42. package/dist/cjs/limebb-rule-chip-popover.cjs.entry.js +2 -2
  43. package/dist/cjs/limebb-rule-editor.cjs.entry.js +162 -22
  44. package/dist/cjs/limebb-rule-gate.cjs.entry.js +1 -1
  45. package/dist/cjs/limebb-text-editor.cjs.entry.js +1 -1
  46. package/dist/cjs/limebb-trend-indicator.cjs.entry.js +1 -1
  47. package/dist/cjs/limebb-value-comparison-editor.cjs.entry.js +1 -1
  48. package/dist/cjs/loader.cjs.js +1 -1
  49. package/dist/cjs/rule-editor-modes-Dc6rnwD2.js +76 -0
  50. package/dist/collection/collection-manifest.json +3 -1
  51. package/dist/collection/components/alert-dialog/alert-dialog.js +1 -1
  52. package/dist/collection/components/browser/browser.js +2 -2
  53. package/dist/collection/components/chat-list/chat-icon-list/chat-icon-list.js +1 -1
  54. package/dist/collection/components/chat-list/chat-item/chat-item.js +2 -2
  55. package/dist/collection/components/chat-list/chat-list.js +1 -1
  56. package/dist/collection/components/chat-list/typing-indicator/typing-indicator.js +1 -1
  57. package/dist/collection/components/color-palette-picker/color-palette-picker.js +1 -1
  58. package/dist/collection/components/color-palette-picker/color-palette-swatches/color-palette-swatches.js +1 -1
  59. package/dist/collection/components/composer-toolbar/composer-toolbar.js +2 -2
  60. package/dist/collection/components/condition-tree/condition-tree-combinators.js +78 -0
  61. package/dist/collection/components/condition-tree/condition-tree-editor/condition-tree-editor.css +17 -0
  62. package/dist/collection/components/condition-tree/condition-tree-editor/condition-tree-editor.js +333 -0
  63. package/dist/collection/components/condition-tree/condition-tree-nodes.js +218 -0
  64. package/dist/collection/components/condition-tree/condition-tree-open-state.js +127 -0
  65. package/dist/collection/components/condition-tree/condition-tree-translate.js +22 -0
  66. package/dist/collection/components/condition-tree/condition-tree-view-context.js +22 -0
  67. package/dist/collection/components/condition-tree/condition-tree.css +132 -0
  68. package/dist/collection/components/condition-tree/condition-tree.js +461 -0
  69. package/dist/collection/components/condition-tree/condition-tree.types.js +1 -0
  70. package/dist/collection/components/condition-tree/group-node-view.js +153 -0
  71. package/dist/collection/components/condition-tree/leaf-node-view.js +74 -0
  72. package/dist/collection/components/currency-picker/currency-picker.js +1 -1
  73. package/dist/collection/components/dashboard-widget/dashboard-widget.js +1 -1
  74. package/dist/collection/components/date-picker/date-picker.js +1 -1
  75. package/dist/collection/components/date-range/date-range.js +1 -1
  76. package/dist/collection/components/document-chips/document-chips.js +1 -1
  77. package/dist/collection/components/document-picker/document-item/document-item.js +2 -2
  78. package/dist/collection/components/document-picker/document-picker.js +1 -1
  79. package/dist/collection/components/feed/feed-item/feed-timeline-item.js +1 -1
  80. package/dist/collection/components/feed/feed-item-thumbnail-file-info/feed-item-thumbnail-file-info.js +1 -1
  81. package/dist/collection/components/feed/feed.js +1 -1
  82. package/dist/collection/components/filter-chip/filter-chip.js +2 -2
  83. package/dist/collection/components/filter-condition-picker/filter-condition-picker.js +1 -1
  84. package/dist/collection/components/icon-picker/icon-picker.js +1 -1
  85. package/dist/collection/components/info-tile/format/config/info-tile-format.js +1 -1
  86. package/dist/collection/components/info-tile/info-tile.js +1 -1
  87. package/dist/collection/components/kanban/kanban-group/kanban-group.js +1 -1
  88. package/dist/collection/components/kanban/kanban-item/kanban-item.js +1 -1
  89. package/dist/collection/components/lime-query-builder/expressions/lime-query-filter-comparison-editor.js +1 -1
  90. package/dist/collection/components/lime-query-builder/expressions/lime-query-filter-comparison.js +2 -2
  91. package/dist/collection/components/lime-query-builder/expressions/lime-query-filter-group.js +2 -2
  92. package/dist/collection/components/lime-query-builder/expressions/lime-query-filter-not.js +1 -1
  93. package/dist/collection/components/lime-query-builder/lime-query-builder.js +1 -1
  94. package/dist/collection/components/lime-query-builder/lime-query-response-format-builder.js +1 -1
  95. package/dist/collection/components/lime-query-builder/limetype-field/limetype-field.js +1 -1
  96. package/dist/collection/components/lime-query-builder/order-by/order-by-editor.js +1 -1
  97. package/dist/collection/components/lime-query-builder/order-by/order-by-item.js +2 -2
  98. package/dist/collection/components/lime-query-builder/response-format/response-format-item.js +1 -1
  99. package/dist/collection/components/limeobject/file-viewer/live-docs-info.js +2 -2
  100. package/dist/collection/components/locale-picker/locale-picker.js +1 -1
  101. package/dist/collection/components/notification-list/notification-item/notification-item.js +1 -1
  102. package/dist/collection/components/percentage-visualizer/percentage-visualizer.js +2 -2
  103. package/dist/collection/components/rule-editor/group-node-view.js +3 -3
  104. package/dist/collection/components/rule-editor/rule-chip-popover/rule-chip-popover.js +2 -2
  105. package/dist/collection/components/rule-editor/rule-editor-mode-view.js +32 -0
  106. package/dist/collection/components/rule-editor/rule-editor-modes.js +68 -0
  107. package/dist/collection/components/rule-editor/rule-editor.css +153 -12
  108. package/dist/collection/components/rule-editor/rule-editor.js +201 -19
  109. package/dist/collection/components/rule-editor/rule-editor.types.js +1 -0
  110. package/dist/collection/components/rule-editor/value-comparison-editor/value-comparison-editor.js +1 -1
  111. package/dist/collection/components/rule-gate/rule-gate.js +1 -1
  112. package/dist/collection/components/summary-popover/summary-popover.js +2 -2
  113. package/dist/collection/components/text-editor/mention-group-counter.js +2 -2
  114. package/dist/collection/components/text-editor/text-editor.js +1 -1
  115. package/dist/collection/components/trend-indicator/trend-indicator.js +1 -1
  116. package/dist/collection/index.js +2 -0
  117. package/dist/components/chat-icon-list.js +1 -1
  118. package/dist/components/chat-item.js +1 -1
  119. package/dist/components/condition-tree-editor.js +1 -0
  120. package/dist/components/currency-picker.js +1 -1
  121. package/dist/components/date-picker.js +1 -1
  122. package/dist/components/document-item.js +1 -1
  123. package/dist/components/feed-item-thumbnail-file-info.js +1 -1
  124. package/dist/components/feed-timeline-item.js +1 -1
  125. package/dist/components/filter-chip.js +1 -1
  126. package/dist/components/filter-condition-picker.js +1 -1
  127. package/dist/components/index.js +1 -1
  128. package/dist/components/kanban-group.js +1 -1
  129. package/dist/components/kanban-item.js +1 -1
  130. package/dist/components/lime-query-filter-comparison-editor.js +1 -1
  131. package/dist/components/lime-query-filter-comparison.js +1 -1
  132. package/dist/components/lime-query-filter-expression.js +1 -1
  133. package/dist/components/limebb-alert-dialog.js +1 -1
  134. package/dist/components/limebb-browser.js +1 -1
  135. package/dist/components/limebb-chat-list.js +1 -1
  136. package/dist/components/limebb-color-palette-picker.js +1 -1
  137. package/dist/components/limebb-color-palette-swatches.js +1 -1
  138. package/dist/components/limebb-composer-toolbar.js +1 -1
  139. package/dist/components/limebb-condition-tree-editor.d.ts +11 -0
  140. package/dist/components/limebb-condition-tree-editor.js +1 -0
  141. package/dist/components/limebb-condition-tree.d.ts +11 -0
  142. package/dist/components/limebb-condition-tree.js +1 -0
  143. package/dist/components/limebb-dashboard-widget.js +1 -1
  144. package/dist/components/limebb-date-range.js +1 -1
  145. package/dist/components/limebb-document-chips.js +1 -1
  146. package/dist/components/limebb-document-picker.js +1 -1
  147. package/dist/components/limebb-feed.js +1 -1
  148. package/dist/components/limebb-icon-picker.js +1 -1
  149. package/dist/components/limebb-info-tile-format.js +1 -1
  150. package/dist/components/limebb-info-tile.js +1 -1
  151. package/dist/components/limebb-lime-query-builder.js +1 -1
  152. package/dist/components/limebb-lime-query-response-format-builder.js +1 -1
  153. package/dist/components/limebb-locale-picker.js +1 -1
  154. package/dist/components/limebb-mention-group-counter.js +1 -1
  155. package/dist/components/limebb-rule-editor.js +1 -1
  156. package/dist/components/limebb-rule-gate.js +1 -1
  157. package/dist/components/limebb-text-editor.js +1 -1
  158. package/dist/components/limebb-trend-indicator.js +1 -1
  159. package/dist/components/limebb-value-comparison-editor.js +1 -1
  160. package/dist/components/limetype-field.js +1 -1
  161. package/dist/components/live-docs-info.js +1 -1
  162. package/dist/components/notification-item.js +1 -1
  163. package/dist/components/order-by-editor.js +1 -1
  164. package/dist/components/order-by-item.js +1 -1
  165. package/dist/components/percentage-visualizer.js +1 -1
  166. package/dist/components/response-format-item.js +1 -1
  167. package/dist/components/rule-chip-popover.js +1 -1
  168. package/dist/components/rule-editor-modes.js +1 -0
  169. package/dist/components/summary-popover.js +1 -1
  170. package/dist/components/typing-indicator.js +1 -1
  171. package/dist/esm/condition-tree-translate-CBeXbZ_z.js +25 -0
  172. package/dist/esm/index.js +1 -0
  173. package/dist/esm/lime-crm-building-blocks.js +1 -1
  174. package/dist/esm/limebb-alert-dialog.entry.js +1 -1
  175. package/dist/esm/limebb-browser.entry.js +2 -2
  176. package/dist/esm/limebb-chat-icon-list_3.entry.js +4 -4
  177. package/dist/esm/limebb-chat-list.entry.js +1 -1
  178. package/dist/esm/limebb-color-palette-picker.entry.js +1 -1
  179. package/dist/esm/limebb-color-palette-swatches.entry.js +1 -1
  180. package/dist/esm/limebb-composer-toolbar.entry.js +2 -2
  181. package/dist/esm/limebb-condition-tree-editor.entry.js +88 -0
  182. package/dist/esm/limebb-condition-tree.entry.js +880 -0
  183. package/dist/esm/limebb-currency-picker.entry.js +1 -1
  184. package/dist/esm/limebb-dashboard-widget.entry.js +1 -1
  185. package/dist/esm/limebb-date-picker.entry.js +1 -1
  186. package/dist/esm/limebb-date-range.entry.js +1 -1
  187. package/dist/esm/limebb-document-chips.entry.js +1 -1
  188. package/dist/esm/limebb-document-item.entry.js +2 -2
  189. package/dist/esm/limebb-document-picker.entry.js +1 -1
  190. package/dist/esm/limebb-feed-item-thumbnail-file-info.entry.js +1 -1
  191. package/dist/esm/limebb-feed-timeline-item.entry.js +1 -1
  192. package/dist/esm/limebb-feed.entry.js +1 -1
  193. package/dist/esm/limebb-filter-chip_6.entry.js +7 -7
  194. package/dist/esm/limebb-icon-picker.entry.js +1 -1
  195. package/dist/esm/limebb-info-tile-format.entry.js +1 -1
  196. package/dist/esm/limebb-info-tile.entry.js +1 -1
  197. package/dist/esm/limebb-kanban-group.entry.js +1 -1
  198. package/dist/esm/limebb-kanban-item.entry.js +1 -1
  199. package/dist/esm/limebb-lime-query-builder.entry.js +1 -1
  200. package/dist/esm/limebb-lime-query-filter-comparison_2.entry.js +2 -2
  201. package/dist/esm/limebb-lime-query-order-by-editor_2.entry.js +2 -2
  202. package/dist/esm/limebb-lime-query-order-by-item.entry.js +2 -2
  203. package/dist/esm/limebb-lime-query-response-format-builder.entry.js +1 -1
  204. package/dist/esm/limebb-lime-query-response-format-editor_2.entry.js +1 -1
  205. package/dist/esm/limebb-live-docs-info.entry.js +2 -2
  206. package/dist/esm/limebb-locale-picker.entry.js +1 -1
  207. package/dist/esm/limebb-mention-group-counter.entry.js +2 -2
  208. package/dist/esm/limebb-navigation-button_2.entry.js +2 -2
  209. package/dist/esm/limebb-notification-item.entry.js +1 -1
  210. package/dist/esm/limebb-percentage-visualizer.entry.js +2 -2
  211. package/dist/esm/limebb-rule-chip-popover.entry.js +2 -2
  212. package/dist/esm/limebb-rule-editor.entry.js +163 -23
  213. package/dist/esm/limebb-rule-gate.entry.js +1 -1
  214. package/dist/esm/limebb-text-editor.entry.js +1 -1
  215. package/dist/esm/limebb-trend-indicator.entry.js +1 -1
  216. package/dist/esm/limebb-value-comparison-editor.entry.js +1 -1
  217. package/dist/esm/loader.js +1 -1
  218. package/dist/esm/rule-editor-modes-BCglve2Z.js +70 -0
  219. package/dist/lime-crm-building-blocks/index.esm.js +1 -1
  220. package/dist/lime-crm-building-blocks/lime-crm-building-blocks.esm.js +1 -1
  221. package/dist/lime-crm-building-blocks/{p-2f8540ab.entry.js → p-02fba38e.entry.js} +1 -1
  222. package/dist/lime-crm-building-blocks/{p-76151fce.entry.js → p-0445035f.entry.js} +1 -1
  223. package/dist/lime-crm-building-blocks/{p-4f0a4893.entry.js → p-0a05b3e9.entry.js} +1 -1
  224. package/dist/lime-crm-building-blocks/p-0dd64440.entry.js +1 -0
  225. package/dist/lime-crm-building-blocks/p-1578c8f0.entry.js +1 -0
  226. package/dist/lime-crm-building-blocks/{p-76064593.entry.js → p-170ab4be.entry.js} +1 -1
  227. package/dist/lime-crm-building-blocks/{p-542047c4.entry.js → p-27b9c824.entry.js} +1 -1
  228. package/dist/lime-crm-building-blocks/{p-2628fe8e.entry.js → p-2d1c7b6f.entry.js} +1 -1
  229. package/dist/lime-crm-building-blocks/{p-c2c181f1.entry.js → p-3fd84800.entry.js} +1 -1
  230. package/dist/lime-crm-building-blocks/{p-c7daffb6.entry.js → p-45dd8663.entry.js} +1 -1
  231. package/dist/lime-crm-building-blocks/{p-cede8095.entry.js → p-4e4d096c.entry.js} +1 -1
  232. package/dist/lime-crm-building-blocks/{p-51eb53ee.entry.js → p-54735042.entry.js} +1 -1
  233. package/dist/lime-crm-building-blocks/{p-c2899d68.entry.js → p-568c4e76.entry.js} +1 -1
  234. package/dist/lime-crm-building-blocks/{p-9907deb1.entry.js → p-584a48e4.entry.js} +1 -1
  235. package/dist/lime-crm-building-blocks/{p-ac4bddfc.entry.js → p-5b97d4f4.entry.js} +1 -1
  236. package/dist/lime-crm-building-blocks/p-615770be.entry.js +1 -0
  237. package/dist/lime-crm-building-blocks/{p-edfaf566.entry.js → p-6d8efe87.entry.js} +1 -1
  238. package/dist/lime-crm-building-blocks/p-705c53c0.entry.js +1 -0
  239. package/dist/lime-crm-building-blocks/{p-031b1648.entry.js → p-73f23d08.entry.js} +1 -1
  240. package/dist/lime-crm-building-blocks/{p-2baab674.entry.js → p-7c5ecffe.entry.js} +1 -1
  241. package/dist/lime-crm-building-blocks/{p-1fac8130.entry.js → p-7cd8dffd.entry.js} +1 -1
  242. package/dist/lime-crm-building-blocks/p-93af3e81.entry.js +1 -0
  243. package/dist/lime-crm-building-blocks/{p-247fcace.entry.js → p-97e2e5c9.entry.js} +1 -1
  244. package/dist/lime-crm-building-blocks/p-BCglve2Z.js +1 -0
  245. package/dist/lime-crm-building-blocks/p-BxCq236x.js +1 -0
  246. package/dist/lime-crm-building-blocks/p-a2b9c410.entry.js +1 -0
  247. package/dist/lime-crm-building-blocks/{p-f9f7020f.entry.js → p-a716b3a8.entry.js} +1 -1
  248. package/dist/lime-crm-building-blocks/p-b3529254.entry.js +1 -0
  249. package/dist/lime-crm-building-blocks/{p-2bfd351d.entry.js → p-b48d7d23.entry.js} +1 -1
  250. package/dist/lime-crm-building-blocks/{p-b373c60f.entry.js → p-b6807166.entry.js} +1 -1
  251. package/dist/lime-crm-building-blocks/{p-318369ae.entry.js → p-b6c2d93b.entry.js} +1 -1
  252. package/dist/lime-crm-building-blocks/{p-d82a2424.entry.js → p-c46802cd.entry.js} +1 -1
  253. package/dist/lime-crm-building-blocks/{p-9099b440.entry.js → p-c635f826.entry.js} +1 -1
  254. package/dist/lime-crm-building-blocks/{p-fec173db.entry.js → p-d816fcc8.entry.js} +1 -1
  255. package/dist/lime-crm-building-blocks/{p-4594c2b1.entry.js → p-d8ce3497.entry.js} +1 -1
  256. package/dist/lime-crm-building-blocks/{p-0f74d662.entry.js → p-d8d32cb1.entry.js} +1 -1
  257. package/dist/lime-crm-building-blocks/{p-99556fc0.entry.js → p-de7724f0.entry.js} +1 -1
  258. package/dist/lime-crm-building-blocks/{p-92403251.entry.js → p-e910963c.entry.js} +1 -1
  259. package/dist/lime-crm-building-blocks/{p-4274cbe3.entry.js → p-ea6ab8b0.entry.js} +1 -1
  260. package/dist/lime-crm-building-blocks/{p-eedbf69a.entry.js → p-ee7bd504.entry.js} +1 -1
  261. package/dist/lime-crm-building-blocks/{p-e1f35866.entry.js → p-f024c185.entry.js} +1 -1
  262. package/dist/lime-crm-building-blocks/{p-7bb2788b.entry.js → p-f102f169.entry.js} +1 -1
  263. package/dist/lime-crm-building-blocks/{p-2984005d.entry.js → p-f1060c88.entry.js} +1 -1
  264. package/dist/lime-crm-building-blocks/{p-17588c29.entry.js → p-f3905fa2.entry.js} +1 -1
  265. package/dist/lime-crm-building-blocks/{p-ac97c7cc.entry.js → p-fc372344.entry.js} +1 -1
  266. package/dist/types/components/condition-tree/condition-tree-combinators.d.ts +47 -0
  267. package/dist/types/components/condition-tree/condition-tree-editor/condition-tree-editor.d.ts +84 -0
  268. package/dist/types/components/condition-tree/condition-tree-nodes.d.ts +130 -0
  269. package/dist/types/components/condition-tree/condition-tree-open-state.d.ts +76 -0
  270. package/dist/types/components/condition-tree/condition-tree-translate.d.ts +11 -0
  271. package/dist/types/components/condition-tree/condition-tree-view-context.d.ts +48 -0
  272. package/dist/types/components/condition-tree/condition-tree.d.ts +177 -0
  273. package/dist/types/components/condition-tree/condition-tree.types.d.ts +323 -0
  274. package/dist/types/components/condition-tree/group-node-view.d.ts +30 -0
  275. package/dist/types/components/condition-tree/leaf-node-view.d.ts +21 -0
  276. package/dist/types/components/rule-editor/rule-editor-mode-view.d.ts +22 -0
  277. package/dist/types/components/rule-editor/rule-editor-modes.d.ts +43 -0
  278. package/dist/types/components/rule-editor/rule-editor.d.ts +129 -5
  279. package/dist/types/components/rule-editor/rule-editor.types.d.ts +16 -0
  280. package/dist/types/components.d.ts +412 -4
  281. package/dist/types/index.d.ts +2 -0
  282. package/dist/types/interface.d.ts +2 -0
  283. package/package.json +3 -3
  284. package/dist/lime-crm-building-blocks/p-1e83a491.entry.js +0 -1
  285. package/dist/lime-crm-building-blocks/p-73f79d42.entry.js +0 -1
  286. package/dist/lime-crm-building-blocks/p-761deada.entry.js +0 -1
  287. package/dist/lime-crm-building-blocks/p-b8d74591.entry.js +0 -1
  288. package/dist/lime-crm-building-blocks/p-e8a7a94c.entry.js +0 -1
@@ -0,0 +1,880 @@
1
+ import { h, r as registerInstance, c as createEvent, H as Host } from './index-COtSgrC5.js';
2
+ import { c as createTranslator } from './condition-tree-translate-CBeXbZ_z.js';
3
+ import './index.esm-B9D_MXA6.js';
4
+
5
+ /**
6
+ * Every combinator a group can use, in the order they are offered.
7
+ *
8
+ * @public
9
+ */
10
+ const CONDITION_TREE_COMBINATORS = [
11
+ 'all',
12
+ 'any',
13
+ 'not-all',
14
+ 'none',
15
+ ];
16
+ /**
17
+ * The combinator to give a group nested inside one joined by `combinator`.
18
+ *
19
+ * The opposite join is the useful default: a group joined the same way as the
20
+ * one holding it says nothing the outer group does not already say. The
21
+ * negation is dropped with it, since a nested group has nothing to negate yet.
22
+ * @param combinator
23
+ */
24
+ function oppositeCombinator(combinator) {
25
+ return OPPOSITE[combinator];
26
+ }
27
+ const OPPOSITE = {
28
+ all: 'any',
29
+ any: 'all',
30
+ 'not-all': 'any',
31
+ none: 'all',
32
+ };
33
+ /**
34
+ * How each combinator looks and reads. The labels are fallbacks used when the
35
+ * platform has no translation for the key next to them.
36
+ */
37
+ const COMBINATOR_PRESENTATION = {
38
+ all: {
39
+ color: 'rgb(var(--contrast-900))',
40
+ iconName: 'dot_circle',
41
+ labelKey: 'webclient.combinator.all',
42
+ label: 'All of the following',
43
+ descriptionKey: 'webclient.combinator.all.description',
44
+ description: 'Every condition must be met.',
45
+ negated: false,
46
+ delimiterKey: 'webclient.delimiter.and',
47
+ delimiter: '&',
48
+ },
49
+ any: {
50
+ color: 'rgb(var(--color-sky-default))',
51
+ iconName: 'centre_point',
52
+ labelKey: 'webclient.combinator.any',
53
+ label: 'Any of the following',
54
+ descriptionKey: 'webclient.combinator.any.description',
55
+ description: 'At least one condition must be met.',
56
+ negated: false,
57
+ delimiterKey: 'webclient.delimiter.or',
58
+ delimiter: 'or',
59
+ },
60
+ 'not-all': {
61
+ color: 'rgb(var(--color-orange-default))',
62
+ iconName: 'dot_circle',
63
+ labelKey: 'webclient.combinator.not-all',
64
+ label: 'Not all of the following',
65
+ descriptionKey: 'webclient.combinator.not-all.description',
66
+ description: 'At least one condition must not be met.',
67
+ negated: true,
68
+ delimiterKey: 'webclient.delimiter.and',
69
+ delimiter: '&',
70
+ },
71
+ none: {
72
+ color: 'rgb(var(--color-red-default))',
73
+ iconName: 'centre_point',
74
+ labelKey: 'webclient.combinator.none',
75
+ label: 'None of the following',
76
+ descriptionKey: 'webclient.combinator.none.description',
77
+ description: 'No conditions may be met.',
78
+ negated: true,
79
+ delimiterKey: 'webclient.delimiter.or',
80
+ delimiter: 'or',
81
+ },
82
+ };
83
+
84
+ /**
85
+ * A stable string form of a path, for `key` attributes and for comparing two
86
+ * paths without an element-by-element loop at every call site.
87
+ * @param path
88
+ */
89
+ function pathKey(path) {
90
+ return path.length === 0 ? 'root' : path.join('.');
91
+ }
92
+ /**
93
+ * Reads and rebuilds a consumer's tree through its adapter.
94
+ *
95
+ * Walking down goes through `describe`, so the tree never has to know how a
96
+ * consumer nests its nodes. Rebuilding goes up through `group`, and only groups
97
+ * are rebuilt: a condition is moved as the object it already is.
98
+ */
99
+ class ConditionTreeWalker {
100
+ /**
101
+ * @param adapter
102
+ * @param isVisited - Whether the user has opened and closed a node's
103
+ * editor. Read through a function rather than taken as a set, so that the
104
+ * walker outlives the tree's tally growing.
105
+ */
106
+ constructor(adapter, isVisited = () => false) {
107
+ this.adapter = adapter;
108
+ this.isVisited = isVisited;
109
+ }
110
+ /**
111
+ * What the tree should draw for `node`.
112
+ * @param node
113
+ */
114
+ describe(node) {
115
+ return this.adapter.describe(node, {
116
+ visited: this.isVisited(node),
117
+ });
118
+ }
119
+ /**
120
+ * How `node` reads as a group, or `undefined` when it is a single
121
+ * condition rather than a group of them.
122
+ * @param node
123
+ */
124
+ groupOf(node) {
125
+ const description = this.describe(node);
126
+ return description.kind === 'group' ? description : undefined;
127
+ }
128
+ /**
129
+ * The children of a group, or `undefined` for a single condition.
130
+ * @param node
131
+ */
132
+ childrenOf(node) {
133
+ var _a;
134
+ return (_a = this.groupOf(node)) === null || _a === void 0 ? void 0 : _a.children;
135
+ }
136
+ /**
137
+ * The node at `path`, or `undefined` when the path leads nowhere — which
138
+ * happens routinely when the consumer replaces the tree while an editor is
139
+ * open.
140
+ * @param root
141
+ * @param path
142
+ */
143
+ nodeAt(root, path) {
144
+ let node = root;
145
+ for (const index of path) {
146
+ if (node === undefined) {
147
+ return undefined;
148
+ }
149
+ const children = this.childrenOf(node);
150
+ if (!children) {
151
+ return undefined;
152
+ }
153
+ node = children[index];
154
+ }
155
+ return node;
156
+ }
157
+ /**
158
+ * The group at `path`, or `undefined` when the path leads nowhere or to a
159
+ * condition. Every caller that wants to look inside a group first has to
160
+ * find it and then find out whether it is one, so both steps live here.
161
+ * @param root
162
+ * @param path
163
+ */
164
+ groupAt(root, path) {
165
+ const node = this.nodeAt(root, path);
166
+ return node === undefined ? undefined : this.groupOf(node);
167
+ }
168
+ /**
169
+ * Whether `node` is still somewhere in the tree, by identity.
170
+ *
171
+ * Identity rather than equality: a condition the tree did not touch is the
172
+ * very object the consumer handed over, so one that merely looks the same
173
+ * is a different condition.
174
+ * @param root
175
+ * @param node
176
+ */
177
+ contains(root, node) {
178
+ if (root === undefined) {
179
+ return false;
180
+ }
181
+ if (root === node) {
182
+ return true;
183
+ }
184
+ const children = this.childrenOf(root);
185
+ return !!(children === null || children === void 0 ? void 0 : children.some((child) => this.contains(child, node)));
186
+ }
187
+ /**
188
+ * Every condition asking to be opened, in display order.
189
+ *
190
+ * All of them rather than the first, because a consumer that leaves the
191
+ * flag on a condition it has already added would otherwise keep pointing at
192
+ * that one, and the next condition added would never get its turn.
193
+ * @param root
194
+ */
195
+ autoOpenNodes(root) {
196
+ if (root === undefined) {
197
+ return [];
198
+ }
199
+ const description = this.describe(root);
200
+ if (description.kind === 'leaf') {
201
+ return description.autoOpen ? [root] : [];
202
+ }
203
+ return description.children.flatMap((child) => this.autoOpenNodes(child));
204
+ }
205
+ /**
206
+ * The tree with the node at `path` replaced by `next`, or removed when
207
+ * `next` is `undefined`.
208
+ * @param root
209
+ * @param path
210
+ * @param next
211
+ */
212
+ replaceAt(root, path, next) {
213
+ if (path.length === 0) {
214
+ return next;
215
+ }
216
+ const group = this.groupOf(root);
217
+ if (!group) {
218
+ return root;
219
+ }
220
+ const [index, ...rest] = path;
221
+ const children = group.children;
222
+ if (!(index in children)) {
223
+ return root;
224
+ }
225
+ const child = this.replaceAt(children[index], rest, next);
226
+ return this.rebuild(group.combinator, spliced(children, index, child));
227
+ }
228
+ /**
229
+ * The tree with `child` added to the end of the group at `path`. A path
230
+ * leading to a condition rather than a group leaves the tree alone: there
231
+ * is nothing there to add to.
232
+ * @param root
233
+ * @param path
234
+ * @param child
235
+ */
236
+ appendAt(root, path, child) {
237
+ const group = this.groupAt(root, path);
238
+ if (!group) {
239
+ return root;
240
+ }
241
+ return this.replaceAt(root, path, this.adapter.group(group.combinator, [...group.children, child]));
242
+ }
243
+ /**
244
+ * The tree with the group at `path` joined by `combinator` instead, and
245
+ * what is inside it left alone. A path leading anywhere but a group leaves
246
+ * the tree as it was.
247
+ * @param root
248
+ * @param path
249
+ * @param combinator
250
+ */
251
+ rejoinAt(root, path, combinator) {
252
+ const group = this.groupAt(root, path);
253
+ if (!group) {
254
+ return root;
255
+ }
256
+ return this.replaceAt(root, path, this.adapter.group(combinator, group.children));
257
+ }
258
+ /**
259
+ * The tree with the condition at `path` negated, or not.
260
+ *
261
+ * An adapter with no way to rebuild a negated condition leaves the tree
262
+ * alone: it has already told the tree not to offer the control.
263
+ * @param root
264
+ * @param path
265
+ * @param negated
266
+ */
267
+ negateAt(root, path, negated) {
268
+ const target = this.nodeAt(root, path);
269
+ if (target === undefined || !this.adapter.negate) {
270
+ return root;
271
+ }
272
+ return this.replaceAt(root, path, this.adapter.negate(target, negated));
273
+ }
274
+ /**
275
+ * A group holding `children`, or nothing at all when there are none left: a
276
+ * group with nothing in it says nothing, so it goes the way of its last
277
+ * condition — and so, in turn, does the group that held it.
278
+ * @param combinator
279
+ * @param children
280
+ */
281
+ rebuild(combinator, children) {
282
+ if (children.length === 0) {
283
+ return undefined;
284
+ }
285
+ return this.adapter.group(combinator, children);
286
+ }
287
+ }
288
+ /**
289
+ * The same list with the entry at `index` swapped for `replacement`, or dropped
290
+ * when there is no replacement.
291
+ * @param children
292
+ * @param index
293
+ * @param replacement
294
+ */
295
+ function spliced(children, index, replacement) {
296
+ return [
297
+ ...children.slice(0, index),
298
+ ...(replacement === undefined ? [] : [replacement]),
299
+ ...children.slice(index + 1),
300
+ ];
301
+ }
302
+
303
+ /**
304
+ * Which condition's editor is open, and what the tree remembers about the user
305
+ * having been there.
306
+ *
307
+ * All of it is held by condition rather than by place in the tree, so that it
308
+ * survives the tree being rearranged around it.
309
+ *
310
+ * Every method returns a new state rather than changing this one, because
311
+ * `limebb-condition-tree` keeps it in `@State` and Stencil redraws on a new
312
+ * reference, not on a changed field.
313
+ */
314
+ class ConditionTreeOpenState {
315
+ constructor(fields) {
316
+ this.fields = fields;
317
+ }
318
+ static empty() {
319
+ return new ConditionTreeOpenState({
320
+ open: null,
321
+ pending: null,
322
+ seen: new Set(),
323
+ autoOpened: new Set(),
324
+ });
325
+ }
326
+ get openNode() {
327
+ return this.fields.open;
328
+ }
329
+ /**
330
+ * Whether the user has opened this condition's editor and closed it again.
331
+ * @param node
332
+ */
333
+ hasSeen(node) {
334
+ return this.fields.seen.has(node);
335
+ }
336
+ /**
337
+ * The open editor moved onto `next`, or onto nothing at all, remembering
338
+ * the condition left behind — the moment the user is done with it for now,
339
+ * and the earliest anything can fairly judge it. Losing a condition because
340
+ * it went away is not the user leaving it: see `dropIfGone`.
341
+ * @param next
342
+ */
343
+ moveTo(next) {
344
+ const previous = this.fields.open;
345
+ const moved = this.with({
346
+ open: next,
347
+ // Whatever the consumer was about to send back is no longer the
348
+ // condition being edited, so it must not be chased later.
349
+ pending: null,
350
+ });
351
+ if (previous === null || previous === next) {
352
+ return moved;
353
+ }
354
+ return moved.with({ seen: new Set(this.fields.seen).add(previous) });
355
+ }
356
+ /**
357
+ * The same state, now waiting for `next` — the condition an editor just
358
+ * reported — to turn up in a tree from the consumer.
359
+ * @param next
360
+ */
361
+ expect(next) {
362
+ return this.with({ pending: next });
363
+ }
364
+ /**
365
+ * The state brought up to date with a tree the consumer has just handed
366
+ * over: follow the condition that replaced the one being edited, open
367
+ * whatever is asking to be opened, and let go of a condition that is no
368
+ * longer there.
369
+ * @param root
370
+ * @param walker
371
+ */
372
+ sync(root, walker) {
373
+ return this.followPending(root, walker)
374
+ .openWhatAsks(root, walker)
375
+ .dropIfGone(root, walker);
376
+ }
377
+ with(changes) {
378
+ return new ConditionTreeOpenState(Object.assign(Object.assign({}, this.fields), changes));
379
+ }
380
+ /**
381
+ * Move the editor onto the replacement, once the consumer has sent a tree
382
+ * holding it. One that reports the edit elsewhere, or normalizes the
383
+ * condition on the way through, never sends it back at all — the editor
384
+ * then stays where it is, and `dropIfGone` settles it if that has gone too.
385
+ * @param root
386
+ * @param walker
387
+ */
388
+ followPending(root, walker) {
389
+ if (this.fields.pending === null) {
390
+ return this;
391
+ }
392
+ if (!walker.contains(root, this.fields.pending)) {
393
+ return this;
394
+ }
395
+ return this.with({ open: this.fields.pending, pending: null });
396
+ }
397
+ /**
398
+ * Open the condition that is asking for it and has not had its turn yet.
399
+ *
400
+ * A consumer is free to leave the flag on conditions it added earlier, so
401
+ * what settles this is not the flag alone but whether that condition has
402
+ * already been opened once. Conditions that stop asking are forgotten
403
+ * again, so one that is removed and put back opens anew.
404
+ * @param root
405
+ * @param walker
406
+ */
407
+ openWhatAsks(root, walker) {
408
+ const nodes = walker.autoOpenNodes(root);
409
+ const fresh = nodes.find((node) => !this.fields.autoOpened.has(node));
410
+ const remembered = this.with({ autoOpened: new Set(nodes) });
411
+ return fresh === undefined ? remembered : remembered.moveTo(fresh);
412
+ }
413
+ /**
414
+ * Let go of the open condition when it is no longer there — the user
415
+ * removed it, or the consumer replaced the tree under it. That is not the
416
+ * user finishing with it, so it does not count as having been seen.
417
+ * @param root
418
+ * @param walker
419
+ */
420
+ dropIfGone(root, walker) {
421
+ if (this.fields.open === null) {
422
+ return this;
423
+ }
424
+ if (walker.contains(root, this.fields.open)) {
425
+ return this;
426
+ }
427
+ return this.with({ open: null });
428
+ }
429
+ }
430
+
431
+ /**
432
+ * Problems reported on a node, listed beneath it.
433
+ * @param props
434
+ */
435
+ const IssuesView = (props) => {
436
+ var _a;
437
+ if (!((_a = props.issues) === null || _a === void 0 ? void 0 : _a.length)) {
438
+ return null;
439
+ }
440
+ return props.issues.map((issue) => h("div", { class: "issue" }, issue));
441
+ };
442
+ /**
443
+ * Throwing a node away. Shared because both kinds offer it: a group through
444
+ * the button in its header, a condition through the cross on its chip.
445
+ * @param path
446
+ * @param ctx
447
+ */
448
+ const handleDelete = (path, ctx) => (event) => {
449
+ event.stopPropagation();
450
+ ctx.onDelete(path);
451
+ };
452
+
453
+ /**
454
+ * One condition: a chip that summarizes it, and the editor it opens.
455
+ * @param props
456
+ */
457
+ const LeafView = (props) => {
458
+ const { node, description, path, ctx } = props;
459
+ const isOpen = ctx.openNode === node;
460
+ return [
461
+ h("limel-popover", { class: "leaf", key: pathKey(path), open: isOpen, openDirection: "bottom-start", onClose: handleClose(ctx) }, h(ChipView, { node: node, description: description, path: path, ctx: ctx }), h("limebb-condition-tree-editor", { platform: ctx.platform, context: ctx.context, open: isOpen, editor: description.editor, value: node, heading: description.chip.label, negated: ctx.negatable ? description.negated : undefined, readonly: ctx.readonly, disabled: ctx.disabled, onNegateChange: handleNegate(path, ctx), onConditionChange: handleConditionChange(path, ctx) })),
462
+ h(IssuesView, { issues: description.issues }),
463
+ ];
464
+ };
465
+ /**
466
+ * The chip that summarizes a condition: `limebb-filter-chip` unless the
467
+ * condition named another component, and either way the control the tree
468
+ * drives — it selects, locks and removes it the same way.
469
+ *
470
+ * The built-in chip is written out as itself rather than reached through the
471
+ * same tag name as the rest, so that the build sees it: a tag that only ever
472
+ * appears as a string is not counted as a dependency, and the chip would then
473
+ * never be defined for a consumer importing one component at a time.
474
+ * @param props
475
+ */
476
+ const ChipView = (props) => {
477
+ const { component } = props.description.chip;
478
+ if (!component) {
479
+ return h("limebb-filter-chip", Object.assign({}, drivenProps(props)));
480
+ }
481
+ const Chip = component.name;
482
+ return h(Chip, Object.assign({}, component.props, drivenProps(props)));
483
+ };
484
+ /**
485
+ * What the tree tells a chip, whichever chip it is. Spread after the
486
+ * descriptor's own props, so that a chip cannot opt out of the tree's state.
487
+ * @param props
488
+ */
489
+ function drivenProps(props) {
490
+ const { node, description, path, ctx } = props;
491
+ const { chip } = description;
492
+ return {
493
+ slot: 'trigger',
494
+ platform: ctx.platform,
495
+ label: chip.label,
496
+ value: chip.value,
497
+ icon: chip.icon,
498
+ invalid: chip.invalid,
499
+ selected: ctx.openNode === node,
500
+ readonly: ctx.readonly,
501
+ disabled: ctx.disabled,
502
+ removable: !ctx.readonly,
503
+ onClick: handleOpen(node, description, ctx),
504
+ onRemove: handleDelete(path, ctx),
505
+ };
506
+ }
507
+ const handleOpen = (node, description, ctx) => () => {
508
+ if (description.editor && !ctx.disabled) {
509
+ ctx.onOpen(node);
510
+ }
511
+ };
512
+ const handleClose = (ctx) => (event) => {
513
+ event.stopPropagation();
514
+ ctx.onOpen(null);
515
+ };
516
+ const handleNegate = (path, ctx) => (event) => {
517
+ event.stopPropagation();
518
+ ctx.onNegate(path, event.detail);
519
+ };
520
+ const handleConditionChange = (path, ctx) => (event) => {
521
+ event.stopPropagation();
522
+ ctx.onConditionChange(path, event.detail);
523
+ };
524
+
525
+ /**
526
+ * Render one of the consumer's nodes, whichever kind the adapter says it is.
527
+ *
528
+ * It lives beside `GroupView` because a group is what holds nodes of either
529
+ * kind: the recursion is the group's, and keeping the choice here is what lets
530
+ * a group draw a group without two modules importing each other.
531
+ * @param props
532
+ */
533
+ const NodeView = (props) => {
534
+ const { description } = props;
535
+ if (description.kind === 'group') {
536
+ return (h(GroupView, { description: description, path: props.path, ctx: props.ctx }));
537
+ }
538
+ return (h(LeafView, { node: props.node, description: description, path: props.path, ctx: props.ctx }));
539
+ };
540
+ /**
541
+ * A box holding a combinator, the conditions joined by it, and the two buttons
542
+ * that grow it.
543
+ * @param props
544
+ */
545
+ const GroupView = (props) => {
546
+ const { description, path, ctx, placeholder } = props;
547
+ const presentation = COMBINATOR_PRESENTATION[description.combinator];
548
+ const delimiter = ctx.translate(presentation.delimiterKey, presentation.delimiter);
549
+ // The marker between two rows reads as the join itself: "&", "or", and
550
+ // for the negated combinators the same joins prefixed with "not".
551
+ const marker = presentation.negated
552
+ ? `${ctx.translate('webclient.delimiter.not', 'not')} ${delimiter}`
553
+ : delimiter;
554
+ return (h("div", { class: "group", key: pathKey(path), "data-combinator": description.combinator, style: { '--group-rail-color': presentation.color } }, h("div", { class: "group-header" }, renderCombinator(description, path, ctx), renderDeleteGroup(path, ctx, placeholder)), h(IssuesView, { issues: description.issues }), h("ul", { class: "rows" }, description.children.map((child, index) => {
555
+ const childDescription = ctx.walker.describe(child);
556
+ return (h("li", { class: {
557
+ row: true,
558
+ 'row--group': childDescription.kind === 'group',
559
+ }, "data-marker": marker, key: pathKey([...path, index]) }, h(NodeView, { node: child, description: childDescription, path: [...path, index], ctx: ctx })));
560
+ }), renderAddCondition(path, marker, ctx)), renderAddGroup(path, ctx)));
561
+ };
562
+ /**
563
+ * The "+" that turns a noun into an action.
564
+ *
565
+ * The chips and buttons that grow the tree read as "+ Condition" and
566
+ * "+ Group": a sighted reader takes the glyph as the verb, so the label only
567
+ * has to carry the noun. A screen reader cannot — an icon without a `title`
568
+ * is hidden from it entirely, leaving nothing but a bare "Condition". The
569
+ * title supplies the missing verb, and lime-elements composes the two into
570
+ * "Add Condition" for assistive technology and for the tooltip alike.
571
+ *
572
+ * This is why the translated strings behind these are nouns, and must stay
573
+ * nouns: the verb lives here.
574
+ * @param ctx
575
+ * @param color
576
+ */
577
+ function addIcon(ctx, color) {
578
+ return {
579
+ name: 'plus_math',
580
+ title: ctx.translate('webclient.add', 'Add'),
581
+ color: color,
582
+ };
583
+ }
584
+ /**
585
+ * The combinators to list, which is what the consumer offers — plus the one the
586
+ * group already uses, when that is not among them. A group saved before the
587
+ * consumer narrowed the list has to keep saying what it does, rather than
588
+ * misrepresenting itself as using one of the offered ones.
589
+ * @param ctx
590
+ * @param current
591
+ */
592
+ function combinatorOptions(ctx, current) {
593
+ const combinators = [...ctx.combinators];
594
+ if (current && !combinators.includes(current)) {
595
+ combinators.push(current);
596
+ }
597
+ return combinators.map((combinator) => {
598
+ const presentation = COMBINATOR_PRESENTATION[combinator];
599
+ return {
600
+ value: combinator,
601
+ text: ctx.translate(presentation.labelKey, presentation.label),
602
+ secondaryText: ctx.translate(presentation.descriptionKey, presentation.description),
603
+ icon: {
604
+ name: presentation.iconName,
605
+ color: presentation.color,
606
+ },
607
+ };
608
+ });
609
+ }
610
+ /**
611
+ * The dropdown that says how a group joins what is inside it.
612
+ *
613
+ * A group holding fewer than two things has nothing to join yet, so choosing
614
+ * between "All of the following" and "Any of the following" would change
615
+ * nothing, and the dropdown is left out until there is a second thing for it to
616
+ * act on. A negating combinator is the exception: "None of the following" says
617
+ * something about a lone condition that "All of the following" does not, so
618
+ * leaving it out would leave out the negation with it.
619
+ * @param description
620
+ * @param path
621
+ * @param ctx
622
+ */
623
+ function renderCombinator(description, path, ctx) {
624
+ const joins = description.children.length > 1;
625
+ if (!joins && !COMBINATOR_PRESENTATION[description.combinator].negated) {
626
+ return null;
627
+ }
628
+ const options = combinatorOptions(ctx, description.combinator);
629
+ // No label: every option is a full sentence about the group ("All of the
630
+ // following"), so a label above it could only name the same thing twice.
631
+ // The accessible name comes from the selected option for the same reason.
632
+ return (h("limel-select", { class: "combinator", value: options.find((option) => option.value === description.combinator), options: options, disabled: ctx.disabled, readonly: ctx.readonly, onChange: handleCombinator(path, ctx) }));
633
+ }
634
+ function renderDeleteGroup(path, ctx, placeholder) {
635
+ if (ctx.readonly) {
636
+ return null;
637
+ }
638
+ return (h("limel-icon-button", { class: "delete-group", icon: "trash", label: ctx.translate('webclient.delete-group', 'Delete this group'), disabled: ctx.disabled || !!placeholder, onClick: handleDelete(path, ctx) }));
639
+ }
640
+ function renderAddCondition(path, marker, ctx) {
641
+ var _a;
642
+ if (ctx.readonly) {
643
+ return null;
644
+ }
645
+ const offersChoice = !!((_a = ctx.addOptions) === null || _a === void 0 ? void 0 : _a.length);
646
+ const chip = (h("limel-chip", { slot: offersChoice ? 'trigger' : undefined, class: "add-condition", text: ctx.translate('webclient.condition', 'Condition'), disabled: ctx.disabled, icon: addIcon(ctx), onClick: offersChoice ? undefined : handleAddLeaf(path, ctx) }));
647
+ // A row of its own rather than a bare chip, so that the join between it
648
+ // and the condition before it is drawn by the same rule that joins any two
649
+ // rows: the button is where the next condition goes, and it reads as part
650
+ // of the sequence — "Won or 100000 or + Condition".
651
+ return (h("li", { class: "row", "data-marker": marker, key: `${pathKey(path)}.add` }, offersChoice ? (h("limel-menu", { class: "add-condition-menu", items: ctx.addOptions, openDirection: "bottom-start", onSelect: handleAddLeafPick(path, ctx) }, chip)) : (chip)));
652
+ }
653
+ function renderAddGroup(path, ctx) {
654
+ if (ctx.readonly) {
655
+ return null;
656
+ }
657
+ return (h("limel-chip", { class: "add-group", size: "small", text: ctx.translate('webclient.group', 'Group'), disabled: ctx.disabled, icon: addIcon(ctx, 'var(--group-rail-color)'), onClick: handleAddGroup(path, ctx) }));
658
+ }
659
+ const handleCombinator = (path, ctx) => (event) => {
660
+ var _a;
661
+ event.stopPropagation();
662
+ const combinator = (_a = event.detail) === null || _a === void 0 ? void 0 : _a.value;
663
+ if (combinator) {
664
+ ctx.onCombinator(path, combinator);
665
+ }
666
+ };
667
+ const handleAddLeaf = (path, ctx) => () => ctx.onAddLeaf(path);
668
+ const handleAddLeafPick = (path, ctx) => (event) => {
669
+ event.stopPropagation();
670
+ ctx.onAddLeaf(path, event.detail);
671
+ };
672
+ const handleAddGroup = (path, ctx) => () => ctx.onAddGroup(path);
673
+
674
+ const conditionTreeCss = () => `*,*:before,*::after{box-sizing:border-box}:host{display:flex;flex-direction:column;gap:1.5rem}.group{position:relative;display:flex;flex-direction:column;gap:1rem;padding:0.5rem;border-radius:0.75rem;background-color:rgb(var(--contrast-800), 0.15);transition:box-shadow 120ms ease}.group:before{content:"";position:absolute;top:1rem;bottom:calc(1rem + 1.75rem);left:0;width:0.125rem;transform:translateX(-50%);border-radius:1rem;background-color:var(--group-rail-color)}.group:has(>.group-header>limel-icon-button.delete-group:not([disabled]):hover),.group:has(>.group-header>limel-icon-button.delete-group:not([disabled]):focus-within){box-shadow:var(--shadow-error-state)}.group-header{display:flex;align-items:center;gap:0.5rem;min-height:2.5rem}limel-select.combinator{min-width:12rem}limel-icon-button.delete-group{margin-left:auto;opacity:0;transition:opacity 120ms ease}.group:hover>.group-header>limel-icon-button.delete-group,.group:focus-within>.group-header>limel-icon-button.delete-group{opacity:1}limel-chip.add-group{--lime-elevated-surface-background-color:transparent;--button-shadow-normal:none;isolation:isolate;position:relative;margin-right:auto}limel-chip.add-group:after{content:"";position:absolute;width:0.5rem;height:1.75rem;top:0;left:calc(0.5rem * -1 - 0.125rem / 2);border-width:0 0 0.125rem 0.125rem;border-color:var(--group-rail-color);border-style:solid;border-radius:0 0 0 0.5rem;transform:translateY(calc(-50% - 0.125rem / 2))}ul.rows{list-style:none;margin:0;display:flex;flex-direction:row;flex-wrap:wrap;align-items:center;column-gap:0.5rem;row-gap:0.5rem;padding:0 0.5rem 0.5rem 0.5rem}li.row{list-style:none;position:relative}li.row.row--group{flex-basis:100%;align-self:stretch}li.row+li.row:before{content:attr(data-marker);color:var(--group-rail-color);font-size:0.75rem;font-weight:600;line-height:normal}li.row+li.row.row--group:before{position:absolute;left:0;top:0;transform:translate(-50%, -50%)}li.row+li.row:not(.row--group){display:inline-flex;align-items:center;flex-wrap:wrap}li.row+li.row:not(.row--group):before{margin-right:0.5rem}limel-popover.leaf{display:inline-block;max-width:25rem}.issue{color:rgb(var(--color-red-default));font-size:0.875rem;flex-basis:100%}`;
675
+
676
+ /**
677
+ * The group drawn when there is no tree yet. Nothing is inside it, so no
678
+ * combinator is offered and there is nothing to delete or to group.
679
+ */
680
+ const EMPTY_GROUP = {
681
+ kind: 'group',
682
+ combinator: 'all',
683
+ children: [],
684
+ };
685
+ const ConditionTree = class {
686
+ constructor(hostRef) {
687
+ registerInstance(this, hostRef);
688
+ this.change = createEvent(this, "change");
689
+ /**
690
+ * Which combinators to offer in the group dropdowns, in the order given.
691
+ *
692
+ * All four are offered by default. "Not all of the following" and "None of
693
+ * the following" are harder to reason about than the two they negate, so a
694
+ * consumer whose users would be better served without them passes
695
+ * `['all', 'any']`. A group that already uses a combinator left off this
696
+ * list still shows it, rather than misrepresenting itself as using one of
697
+ * the offered ones.
698
+ */
699
+ this.combinators = [
700
+ ...CONDITION_TREE_COMBINATORS,
701
+ ];
702
+ /**
703
+ * Set to `true` when the tree is not the viewer's to change: the add,
704
+ * delete and negate controls are not rendered at all, leaving the
705
+ * conditions to be read. Use it where the tree is being shown rather than
706
+ * edited — a saved filter summarized on a card, or a rule the viewer has
707
+ * no rights over.
708
+ */
709
+ this.readonly = false;
710
+ /**
711
+ * Set to `true` when the tree *is* the viewer's to change, but not at this
712
+ * moment: every control stays where it is, dimmed and inert. Use it for a
713
+ * state that will pass — a form mid-save, or a tree behind an "Apply a
714
+ * filter" switch that is currently off.
715
+ */
716
+ this.disabled = false;
717
+ /**
718
+ * Which editor is open, and what the user has already been through — see
719
+ * `condition-tree-open-state.ts`.
720
+ */
721
+ this.openState = ConditionTreeOpenState.empty();
722
+ }
723
+ componentWillLoad() {
724
+ this.buildWalker();
725
+ }
726
+ buildWalker() {
727
+ this.walker = new ConditionTreeWalker(this.adapter, (node) => this.openState.hasSeen(node));
728
+ this.syncOpenState();
729
+ }
730
+ /**
731
+ * Nothing can be read out of a tree until there is an adapter to read it
732
+ * with, so a tree that arrives first waits here. `buildWalker` catches it
733
+ * up when the adapter turns up.
734
+ */
735
+ syncOpenState() {
736
+ if (!this.adapter) {
737
+ return;
738
+ }
739
+ this.openState = this.openState.sync(this.value, this.walker);
740
+ }
741
+ render() {
742
+ if (!this.adapter) {
743
+ return h(Host, null);
744
+ }
745
+ return (h(Host, null, this.isEmpty ? (this.renderEmptyState()) : (h(NodeView, { node: this.value, description: this.walker.describe(this.value), path: [], ctx: this.renderContext() }))));
746
+ }
747
+ /**
748
+ * The empty tree is drawn as the group it is about to become, rather than
749
+ * as a lone button: every condition here ends up inside a group, so the
750
+ * first one lands in a frame that was already on screen instead of
751
+ * conjuring one around itself. It can be filled either way round, with a
752
+ * condition or with a nested group.
753
+ */
754
+ renderEmptyState() {
755
+ if (this.readonly) {
756
+ return null;
757
+ }
758
+ return (h(GroupView, { description: EMPTY_GROUP, path: [], ctx: this.renderContext(), placeholder: true }));
759
+ }
760
+ renderContext() {
761
+ return {
762
+ platform: this.platform,
763
+ context: this.context,
764
+ walker: this.walker,
765
+ translate: createTranslator(this.platform),
766
+ combinators: this.combinators,
767
+ readonly: this.readonly,
768
+ disabled: this.disabled,
769
+ negatable: !!this.adapter.negate,
770
+ openNode: this.openState.openNode,
771
+ addOptions: this.addOptions,
772
+ onAddLeaf: (path, item) => this.addLeaf(path, item),
773
+ onAddGroup: (path) => this.addGroup(path),
774
+ onDelete: (path) => this.applyEdit((root) => this.walker.replaceAt(root, path, undefined)),
775
+ onCombinator: (path, combinator) => this.applyEdit((root) => this.walker.rejoinAt(root, path, combinator)),
776
+ onNegate: (path, negated) => this.applyEdit((root) => this.walker.negateAt(root, path, negated)),
777
+ onConditionChange: (path, next) => {
778
+ this.openState = this.openState.expect(next);
779
+ this.applyEdit((root) => this.walker.replaceAt(root, path, next));
780
+ },
781
+ onOpen: (node) => {
782
+ this.openState = this.openState.moveTo(node);
783
+ },
784
+ };
785
+ }
786
+ addLeaf(path, item) {
787
+ this.grow(path, this.adapter.createLeaf(item));
788
+ }
789
+ /**
790
+ * A nested group is joined the other way round from the one holding it: a
791
+ * group joined the same way as its parent would say nothing the parent does
792
+ * not already say.
793
+ * @param path
794
+ */
795
+ addGroup(path) {
796
+ var _a, _b;
797
+ const combinator = (_b = (_a = this.walker.groupAt(this.value, path)) === null || _a === void 0 ? void 0 : _a.combinator) !== null && _b !== void 0 ? _b : this.rootCombinator();
798
+ this.grow(path, this.adapter.group(oppositeCombinator(combinator), this.newGroupChildren()));
799
+ }
800
+ /**
801
+ * What a new group starts with: one blank condition, so that a group is
802
+ * never handed over saying nothing — the same rule by which a group emptied
803
+ * of its last condition is dropped rather than kept. A consumer offering a
804
+ * menu of kinds is the exception, since the tree cannot know which kind to
805
+ * make.
806
+ */
807
+ newGroupChildren() {
808
+ var _a;
809
+ if ((_a = this.addOptions) === null || _a === void 0 ? void 0 : _a.length) {
810
+ return [];
811
+ }
812
+ return [this.adapter.createLeaf()];
813
+ }
814
+ /**
815
+ * Add a condition, or a group to put conditions in.
816
+ *
817
+ * Everything in this tree lives inside a group, so the first thing added
818
+ * to an empty one gets a root group to live in. After that the walker
819
+ * places it.
820
+ * @param path
821
+ * @param child
822
+ */
823
+ grow(path, child) {
824
+ if (this.isEmpty) {
825
+ this.emitChange(this.adapter.group(this.rootCombinator(), [child]));
826
+ return;
827
+ }
828
+ this.emitChange(this.walker.appendAt(this.value, path, child));
829
+ }
830
+ /**
831
+ * An empty tree has nothing to edit.
832
+ * @param edit
833
+ */
834
+ applyEdit(edit) {
835
+ if (this.isEmpty) {
836
+ return;
837
+ }
838
+ this.emitChange(edit(this.value));
839
+ }
840
+ /**
841
+ * Announce a tree the user has changed — unless it was not theirs to
842
+ * change. Every control is hidden or dimmed by then, so what this catches
843
+ * is an editor: the tree mounts whatever component a condition names, and
844
+ * has no way to make it honour the `readonly` it was handed.
845
+ * @param next
846
+ */
847
+ emitChange(next) {
848
+ if (this.readonly || this.disabled) {
849
+ return;
850
+ }
851
+ this.change.emit(next);
852
+ }
853
+ /**
854
+ * Whether there is no tree yet — which is not the same as a tree that
855
+ * happens to be an empty group.
856
+ */
857
+ get isEmpty() {
858
+ return this.value === undefined || this.value === null;
859
+ }
860
+ /**
861
+ * The combinator a group made here is joined by: the first one the consumer
862
+ * offers, so a tree that never offers "All of the following" never invents
863
+ * one.
864
+ */
865
+ rootCombinator() {
866
+ var _a;
867
+ return (_a = this.combinators[0]) !== null && _a !== void 0 ? _a : 'all';
868
+ }
869
+ static get watchers() { return {
870
+ "adapter": [{
871
+ "buildWalker": 0
872
+ }],
873
+ "value": [{
874
+ "syncOpenState": 0
875
+ }]
876
+ }; }
877
+ };
878
+ ConditionTree.style = conditionTreeCss();
879
+
880
+ export { ConditionTree as limebb_condition_tree };