@limetech/lime-crm-building-blocks 2.3.1 → 2.4.1
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.
- package/CHANGELOG.md +20 -0
- package/dist/cjs/{condition-tree-translate-B_qIQz9s.js → condition-tree-translate-BQwKtiNZ.js} +1 -1
- package/dist/cjs/{filter-group-logic-Bt5tIbfP.js → filter-group-logic-CeGmYgsu.js} +1 -1
- package/dist/cjs/{filter-operators-CzIq9qKC.js → filter-operators-C3T2czC_.js} +1 -1
- package/dist/cjs/{index-mDIvByXc.js → index-Du4GyM0Y.js} +13 -8
- package/dist/cjs/index.cjs.js +3 -3
- package/dist/cjs/{index.esm-D1EzGa8X.js → index.esm-C2zw0QJK.js} +2 -2
- package/dist/cjs/lime-crm-building-blocks.cjs.js +3 -3
- package/dist/cjs/{lime-query-validation-Df4GZRGm.js → lime-query-validation-CzYkphmi.js} +1 -1
- package/dist/cjs/limebb-alert-dialog.cjs.entry.js +1 -1
- package/dist/cjs/limebb-browser.cjs.entry.js +2 -2
- package/dist/cjs/limebb-chat-icon-list_3.cjs.entry.js +2 -2
- package/dist/cjs/limebb-chat-list.cjs.entry.js +2 -2
- package/dist/cjs/limebb-color-palette-picker.cjs.entry.js +1 -1
- package/dist/cjs/limebb-color-palette-swatches.cjs.entry.js +1 -1
- package/dist/cjs/limebb-component-config.cjs.entry.js +3 -3
- package/dist/cjs/limebb-component-picker.cjs.entry.js +2 -2
- package/dist/cjs/limebb-composer-toolbar.cjs.entry.js +2 -2
- package/dist/cjs/limebb-condition-tree-editor.cjs.entry.js +24 -9
- package/dist/cjs/limebb-condition-tree.cjs.entry.js +121 -34
- package/dist/cjs/limebb-currency-picker.cjs.entry.js +2 -2
- package/dist/cjs/limebb-dashboard-widget.cjs.entry.js +1 -1
- package/dist/cjs/limebb-data-cells.cjs.entry.js +2 -2
- package/dist/cjs/limebb-date-picker.cjs.entry.js +2 -2
- package/dist/cjs/limebb-date-range.cjs.entry.js +1 -1
- package/dist/cjs/limebb-document-chips.cjs.entry.js +1 -1
- package/dist/cjs/limebb-document-item.cjs.entry.js +1 -1
- package/dist/cjs/limebb-document-picker.cjs.entry.js +1 -1
- package/dist/cjs/limebb-empty-state.cjs.entry.js +1 -1
- package/dist/cjs/limebb-feed-item-thumbnail-file-info.cjs.entry.js +1 -1
- package/dist/cjs/limebb-feed-timeline-item.cjs.entry.js +2 -2
- package/dist/cjs/limebb-feed.cjs.entry.js +2 -2
- package/dist/cjs/limebb-filter-chip_6.cjs.entry.js +4 -4
- package/dist/cjs/limebb-icon-picker.cjs.entry.js +1 -1
- package/dist/cjs/limebb-info-tile-currency-format.cjs.entry.js +1 -1
- package/dist/cjs/limebb-info-tile-date-format.cjs.entry.js +1 -1
- package/dist/cjs/limebb-info-tile-decimal-format.cjs.entry.js +1 -1
- package/dist/cjs/limebb-info-tile-format.cjs.entry.js +1 -1
- package/dist/cjs/limebb-info-tile-relative-date-format.cjs.entry.js +1 -1
- package/dist/cjs/limebb-info-tile-unit-format.cjs.entry.js +1 -1
- package/dist/cjs/limebb-info-tile.cjs.entry.js +3 -3
- package/dist/cjs/limebb-inline-image.cjs.entry.js +2 -2
- package/dist/cjs/limebb-kanban-group.cjs.entry.js +2 -2
- package/dist/cjs/limebb-kanban-item.cjs.entry.js +2 -2
- package/dist/cjs/limebb-kanban.cjs.entry.js +1 -1
- package/dist/cjs/limebb-lime-query-builder.cjs.entry.js +3 -3
- package/dist/cjs/limebb-lime-query-filter-builder.cjs.entry.js +3 -3
- package/dist/cjs/limebb-lime-query-filter-comparison_2.cjs.entry.js +4 -4
- package/dist/cjs/limebb-lime-query-order-by-editor_2.cjs.entry.js +3 -3
- package/dist/cjs/limebb-lime-query-order-by-item.cjs.entry.js +1 -1
- package/dist/cjs/limebb-lime-query-response-format-builder.cjs.entry.js +3 -3
- package/dist/cjs/limebb-lime-query-response-format-editor_2.cjs.entry.js +1 -1
- package/dist/cjs/limebb-limeobject-file-viewer.cjs.entry.js +2 -2
- package/dist/cjs/limebb-live-docs-info.cjs.entry.js +1 -1
- package/dist/cjs/limebb-loader.cjs.entry.js +2 -2
- package/dist/cjs/limebb-locale-picker.cjs.entry.js +2 -2
- package/dist/cjs/limebb-mention-group-counter.cjs.entry.js +1 -1
- package/dist/cjs/limebb-mention.cjs.entry.js +2 -2
- package/dist/cjs/limebb-navigation-button_2.cjs.entry.js +1 -1
- package/dist/cjs/limebb-notification-item.cjs.entry.js +2 -2
- package/dist/cjs/limebb-notification-list.cjs.entry.js +2 -2
- package/dist/cjs/limebb-object-chip.cjs.entry.js +3 -3
- package/dist/cjs/limebb-percentage-visualizer.cjs.entry.js +2 -2
- package/dist/cjs/limebb-property-selector.cjs.entry.js +3 -3
- package/dist/cjs/limebb-rule-arg-filter-editor.cjs.entry.js +2 -2
- package/dist/cjs/limebb-rule-condition-chip.cjs.entry.js +71 -0
- package/dist/cjs/limebb-rule-condition-editor-CHWTMOmi.js +285 -0
- package/dist/cjs/limebb-rule-condition-editor.cjs.entry.js +9 -0
- package/dist/cjs/limebb-rule-editor.cjs.entry.js +217 -573
- package/dist/cjs/limebb-rule-gate.cjs.entry.js +3 -3
- package/dist/cjs/limebb-text-editor-picker.cjs.entry.js +1 -1
- package/dist/cjs/limebb-text-editor.cjs.entry.js +3 -3
- package/dist/cjs/limebb-trend-indicator.cjs.entry.js +2 -2
- package/dist/cjs/limebb-value-comparison-editor.cjs.entry.js +3 -3
- package/dist/cjs/{limetype-BPuuRLtH.js → limetype-BzVDjAKS.js} +1 -1
- package/dist/cjs/loader.cjs.js +2 -2
- package/dist/cjs/{web-component-template-DRMW9wHN.js → web-component-template-C-AkY5as.js} +1 -1
- package/dist/collection/collection-manifest.json +3 -2
- package/dist/collection/components/condition-tree/condition-tree-editor/condition-tree-editor.js +46 -5
- package/dist/collection/components/condition-tree/condition-tree-nodes.js +13 -6
- package/dist/collection/components/condition-tree/condition-tree.js +69 -18
- package/dist/collection/components/condition-tree/group-node-view.js +41 -5
- package/dist/collection/components/condition-tree/leaf-node-view.js +19 -2
- package/dist/collection/components/rule-editor/condition-tree-adapter.js +229 -0
- package/dist/collection/components/rule-editor/rule-condition-chip/rule-condition-chip.css +4 -0
- package/dist/collection/components/rule-editor/rule-condition-chip/rule-condition-chip.js +322 -0
- package/dist/collection/components/rule-editor/rule-condition-editor/rule-condition-editor.css +5 -0
- package/dist/collection/components/rule-editor/rule-condition-editor/rule-condition-editor.js +259 -0
- package/dist/collection/components/rule-editor/rule-editor.css +1 -73
- package/dist/collection/components/rule-editor/rule-editor.js +143 -153
- package/dist/collection/components/rule-editor/rule-issues.js +89 -0
- package/dist/collection/components/rule-editor/view-helpers.js +19 -41
- package/dist/collection/components/rule-gate/rule-gate.css +3 -3
- package/dist/components/condition-tree-adapter.js +1 -0
- package/dist/components/condition-tree-editor.js +1 -1
- package/dist/components/condition-tree.js +1 -0
- package/dist/components/limebb-condition-tree.js +1 -1
- package/dist/components/limebb-rule-condition-chip.d.ts +11 -0
- package/dist/components/limebb-rule-condition-chip.js +1 -0
- package/dist/components/limebb-rule-condition-editor.d.ts +11 -0
- package/dist/components/limebb-rule-condition-editor.js +1 -0
- package/dist/components/limebb-rule-editor.js +1 -1
- package/dist/components/limebb-rule-gate.js +1 -1
- package/dist/esm/{condition-tree-translate-CBeXbZ_z.js → condition-tree-translate-ZQptbaXF.js} +1 -1
- package/dist/esm/{filter-group-logic-CzThKf85.js → filter-group-logic-nqCMmV0e.js} +1 -1
- package/dist/esm/{filter-operators-u3T1PKhm.js → filter-operators-QbKK26m2.js} +1 -1
- package/dist/esm/{index-COtSgrC5.js → index-BK566_jX.js} +13 -8
- package/dist/esm/{index.esm-B9D_MXA6.js → index.esm-C__n3hug.js} +1 -1
- package/dist/esm/index.js +3 -3
- package/dist/esm/lime-crm-building-blocks.js +4 -4
- package/dist/esm/{lime-query-validation-dGoN_93p.js → lime-query-validation-BvB2v-yP.js} +1 -1
- package/dist/esm/limebb-alert-dialog.entry.js +1 -1
- package/dist/esm/limebb-browser.entry.js +2 -2
- package/dist/esm/limebb-chat-icon-list_3.entry.js +2 -2
- package/dist/esm/limebb-chat-list.entry.js +2 -2
- package/dist/esm/limebb-color-palette-picker.entry.js +1 -1
- package/dist/esm/limebb-color-palette-swatches.entry.js +1 -1
- package/dist/esm/limebb-component-config.entry.js +3 -3
- package/dist/esm/limebb-component-picker.entry.js +2 -2
- package/dist/esm/limebb-composer-toolbar.entry.js +2 -2
- package/dist/esm/limebb-condition-tree-editor.entry.js +24 -9
- package/dist/esm/limebb-condition-tree.entry.js +121 -34
- package/dist/esm/limebb-currency-picker.entry.js +2 -2
- package/dist/esm/limebb-dashboard-widget.entry.js +1 -1
- package/dist/esm/limebb-data-cells.entry.js +2 -2
- package/dist/esm/limebb-date-picker.entry.js +2 -2
- package/dist/esm/limebb-date-range.entry.js +1 -1
- package/dist/esm/limebb-document-chips.entry.js +1 -1
- package/dist/esm/limebb-document-item.entry.js +1 -1
- package/dist/esm/limebb-document-picker.entry.js +1 -1
- package/dist/esm/limebb-empty-state.entry.js +1 -1
- package/dist/esm/limebb-feed-item-thumbnail-file-info.entry.js +1 -1
- package/dist/esm/limebb-feed-timeline-item.entry.js +2 -2
- package/dist/esm/limebb-feed.entry.js +2 -2
- package/dist/esm/limebb-filter-chip_6.entry.js +4 -4
- package/dist/esm/limebb-icon-picker.entry.js +1 -1
- package/dist/esm/limebb-info-tile-currency-format.entry.js +1 -1
- package/dist/esm/limebb-info-tile-date-format.entry.js +1 -1
- package/dist/esm/limebb-info-tile-decimal-format.entry.js +1 -1
- package/dist/esm/limebb-info-tile-format.entry.js +1 -1
- package/dist/esm/limebb-info-tile-relative-date-format.entry.js +1 -1
- package/dist/esm/limebb-info-tile-unit-format.entry.js +1 -1
- package/dist/esm/limebb-info-tile.entry.js +3 -3
- package/dist/esm/limebb-inline-image.entry.js +2 -2
- package/dist/esm/limebb-kanban-group.entry.js +2 -2
- package/dist/esm/limebb-kanban-item.entry.js +2 -2
- package/dist/esm/limebb-kanban.entry.js +1 -1
- package/dist/esm/limebb-lime-query-builder.entry.js +3 -3
- package/dist/esm/limebb-lime-query-filter-builder.entry.js +3 -3
- package/dist/esm/limebb-lime-query-filter-comparison_2.entry.js +4 -4
- package/dist/esm/limebb-lime-query-order-by-editor_2.entry.js +3 -3
- package/dist/esm/limebb-lime-query-order-by-item.entry.js +1 -1
- package/dist/esm/limebb-lime-query-response-format-builder.entry.js +3 -3
- package/dist/esm/limebb-lime-query-response-format-editor_2.entry.js +1 -1
- package/dist/esm/limebb-limeobject-file-viewer.entry.js +2 -2
- package/dist/esm/limebb-live-docs-info.entry.js +1 -1
- package/dist/esm/limebb-loader.entry.js +2 -2
- package/dist/esm/limebb-locale-picker.entry.js +2 -2
- package/dist/esm/limebb-mention-group-counter.entry.js +1 -1
- package/dist/esm/limebb-mention.entry.js +2 -2
- package/dist/esm/limebb-navigation-button_2.entry.js +1 -1
- package/dist/esm/limebb-notification-item.entry.js +2 -2
- package/dist/esm/limebb-notification-list.entry.js +2 -2
- package/dist/esm/limebb-object-chip.entry.js +3 -3
- package/dist/esm/limebb-percentage-visualizer.entry.js +2 -2
- package/dist/esm/limebb-property-selector.entry.js +3 -3
- package/dist/esm/limebb-rule-arg-filter-editor.entry.js +2 -2
- package/dist/esm/limebb-rule-condition-chip.entry.js +69 -0
- package/dist/esm/limebb-rule-condition-editor-DeY758N-.js +281 -0
- package/dist/esm/limebb-rule-condition-editor.entry.js +3 -0
- package/dist/esm/limebb-rule-editor.entry.js +217 -573
- package/dist/esm/limebb-rule-gate.entry.js +3 -3
- package/dist/esm/limebb-text-editor-picker.entry.js +1 -1
- package/dist/esm/limebb-text-editor.entry.js +3 -3
- package/dist/esm/limebb-trend-indicator.entry.js +2 -2
- package/dist/esm/limebb-value-comparison-editor.entry.js +3 -3
- package/dist/esm/{limetype-BcELY1NF.js → limetype-Muf9VutX.js} +1 -1
- package/dist/esm/loader.js +3 -3
- package/dist/esm/{web-component-template-DxbwHsvw.js → web-component-template-D1JpeNy_.js} +1 -1
- package/dist/lime-crm-building-blocks/index.esm.js +1 -1
- package/dist/lime-crm-building-blocks/lime-crm-building-blocks.esm.js +1 -1
- package/dist/lime-crm-building-blocks/p-0621e884.entry.js +1 -0
- package/dist/lime-crm-building-blocks/{p-ab0f8170.entry.js → p-087d5651.entry.js} +1 -1
- package/dist/lime-crm-building-blocks/{p-ce2755a0.entry.js → p-1917956c.entry.js} +1 -1
- package/dist/lime-crm-building-blocks/{p-07a9c8f2.entry.js → p-1ae4962d.entry.js} +1 -1
- package/dist/lime-crm-building-blocks/{p-021e452a.entry.js → p-23d2632b.entry.js} +1 -1
- package/dist/lime-crm-building-blocks/{p-ffca266e.entry.js → p-251784bf.entry.js} +1 -1
- package/dist/lime-crm-building-blocks/{p-635a45ad.entry.js → p-27240bb0.entry.js} +1 -1
- package/dist/lime-crm-building-blocks/p-2adeac66.entry.js +1 -0
- package/dist/lime-crm-building-blocks/{p-6a8422d2.entry.js → p-32339f09.entry.js} +1 -1
- package/dist/lime-crm-building-blocks/{p-1990e369.entry.js → p-3446290c.entry.js} +1 -1
- package/dist/lime-crm-building-blocks/{p-d495cc19.entry.js → p-35d9b3ad.entry.js} +1 -1
- package/dist/lime-crm-building-blocks/{p-eed0b2c2.entry.js → p-3865eec4.entry.js} +1 -1
- package/dist/lime-crm-building-blocks/{p-dacf9e77.entry.js → p-394b521a.entry.js} +1 -1
- package/dist/lime-crm-building-blocks/{p-8c36b847.entry.js → p-39a36450.entry.js} +1 -1
- package/dist/lime-crm-building-blocks/{p-97e75dee.entry.js → p-3b672249.entry.js} +1 -1
- package/dist/lime-crm-building-blocks/{p-ad5dcefd.entry.js → p-47b56a75.entry.js} +1 -1
- package/dist/lime-crm-building-blocks/{p-402a9c97.entry.js → p-4af3ea2c.entry.js} +1 -1
- package/dist/lime-crm-building-blocks/{p-0cc47cad.entry.js → p-4bdaf436.entry.js} +1 -1
- package/dist/lime-crm-building-blocks/{p-cf66256a.entry.js → p-4f60b7bc.entry.js} +1 -1
- package/dist/lime-crm-building-blocks/{p-90f0c96b.entry.js → p-4fd9d615.entry.js} +1 -1
- package/dist/lime-crm-building-blocks/{p-28550961.entry.js → p-53b44865.entry.js} +1 -1
- package/dist/lime-crm-building-blocks/{p-7ae27308.entry.js → p-550606f6.entry.js} +1 -1
- package/dist/lime-crm-building-blocks/p-573f9e95.entry.js +1 -0
- package/dist/lime-crm-building-blocks/{p-a5f3913d.entry.js → p-5c541d0c.entry.js} +1 -1
- package/dist/lime-crm-building-blocks/{p-ce723c21.entry.js → p-612c6b28.entry.js} +1 -1
- package/dist/lime-crm-building-blocks/{p-6f923112.entry.js → p-621ab65a.entry.js} +1 -1
- package/dist/lime-crm-building-blocks/{p-5f682c06.entry.js → p-627b0c79.entry.js} +1 -1
- package/dist/lime-crm-building-blocks/{p-49d042aa.entry.js → p-6303201b.entry.js} +1 -1
- package/dist/lime-crm-building-blocks/{p-8e9fcf3c.entry.js → p-6bd61290.entry.js} +1 -1
- package/dist/lime-crm-building-blocks/{p-dcb49a62.entry.js → p-6d2dba20.entry.js} +1 -1
- package/dist/lime-crm-building-blocks/{p-0193ed83.entry.js → p-6e2553b4.entry.js} +1 -1
- package/dist/lime-crm-building-blocks/{p-Cz5s8qGk.js → p-7DQ7qvMa.js} +1 -1
- package/dist/lime-crm-building-blocks/p-7c3d3e06.entry.js +1 -0
- package/dist/lime-crm-building-blocks/{p-dd02821e.entry.js → p-7d53756b.entry.js} +1 -1
- package/dist/lime-crm-building-blocks/{p-79d743bb.entry.js → p-895c8966.entry.js} +1 -1
- package/dist/lime-crm-building-blocks/{p-da35bcc7.entry.js → p-8c0455e4.entry.js} +1 -1
- package/dist/lime-crm-building-blocks/{p-a201df35.entry.js → p-8f80d024.entry.js} +1 -1
- package/dist/lime-crm-building-blocks/{p-32a81271.entry.js → p-949ed056.entry.js} +1 -1
- package/dist/lime-crm-building-blocks/{p-cf03a756.entry.js → p-985ae787.entry.js} +1 -1
- package/dist/lime-crm-building-blocks/p-9959019d.entry.js +1 -0
- package/dist/lime-crm-building-blocks/{p-DLec4QaM.js → p-B7whyaAL.js} +1 -1
- package/dist/lime-crm-building-blocks/{p-COtSgrC5.js → p-BK566_jX.js} +1 -1
- package/dist/lime-crm-building-blocks/p-ClYOFrOo.js +1 -0
- package/dist/lime-crm-building-blocks/{p-DVypQWZ4.js → p-Cve-3L4y.js} +1 -1
- package/dist/lime-crm-building-blocks/p-DOULPRTn.js +1 -0
- package/dist/lime-crm-building-blocks/{p-Cj_3f9vm.js → p-DhGRAeCH.js} +1 -1
- package/dist/lime-crm-building-blocks/p-DjoMDjMo.js +1 -0
- package/dist/lime-crm-building-blocks/p-DuWEcQ7n.js +1 -0
- package/dist/lime-crm-building-blocks/{p-dfaef740.entry.js → p-a1052482.entry.js} +1 -1
- package/dist/lime-crm-building-blocks/{p-3babfbe0.entry.js → p-a14bed52.entry.js} +1 -1
- package/dist/lime-crm-building-blocks/{p-cc53a8ca.entry.js → p-a2e291b4.entry.js} +1 -1
- package/dist/lime-crm-building-blocks/{p-8a17a7ea.entry.js → p-a2ebd5a4.entry.js} +1 -1
- package/dist/lime-crm-building-blocks/{p-0cbe2180.entry.js → p-a4556649.entry.js} +1 -1
- package/dist/lime-crm-building-blocks/{p-f5c1ed0c.entry.js → p-a598f92f.entry.js} +1 -1
- package/dist/lime-crm-building-blocks/{p-b44b9dbc.entry.js → p-a938384f.entry.js} +1 -1
- package/dist/lime-crm-building-blocks/{p-f3539042.entry.js → p-ab0210b2.entry.js} +1 -1
- package/dist/lime-crm-building-blocks/{p-c0d49532.entry.js → p-b272730c.entry.js} +1 -1
- package/dist/lime-crm-building-blocks/{p-0370200d.entry.js → p-b4571d32.entry.js} +1 -1
- package/dist/lime-crm-building-blocks/{p-551a36f6.entry.js → p-b72c748b.entry.js} +1 -1
- package/dist/lime-crm-building-blocks/{p-0ed9a7cc.entry.js → p-bac9d3a9.entry.js} +1 -1
- package/dist/lime-crm-building-blocks/p-bd6c12bc.entry.js +1 -0
- package/dist/lime-crm-building-blocks/{p-81783bd4.entry.js → p-bf693702.entry.js} +1 -1
- package/dist/lime-crm-building-blocks/{p-e6cc320a.entry.js → p-c58067ec.entry.js} +1 -1
- package/dist/lime-crm-building-blocks/{p-08797129.entry.js → p-c7bfa2e4.entry.js} +1 -1
- package/dist/lime-crm-building-blocks/{p-a953d48e.entry.js → p-d4635a39.entry.js} +1 -1
- package/dist/lime-crm-building-blocks/{p-d3c58bc1.entry.js → p-d6099dc7.entry.js} +1 -1
- package/dist/lime-crm-building-blocks/{p-bf05d9de.entry.js → p-d6c7cf0f.entry.js} +1 -1
- package/dist/lime-crm-building-blocks/{p-1ebe45b8.entry.js → p-da79c5fc.entry.js} +1 -1
- package/dist/lime-crm-building-blocks/p-e18a2cef.entry.js +1 -0
- package/dist/lime-crm-building-blocks/{p-f9991c35.entry.js → p-e19f4b3b.entry.js} +1 -1
- package/dist/lime-crm-building-blocks/{p-46aec244.entry.js → p-eb95767a.entry.js} +1 -1
- package/dist/lime-crm-building-blocks/{p-ddc4ede8.entry.js → p-ec9b5e30.entry.js} +1 -1
- package/dist/lime-crm-building-blocks/{p-95ba7a84.entry.js → p-f49250f3.entry.js} +1 -1
- package/dist/types/components/condition-tree/condition-tree-editor/condition-tree-editor.d.ts +20 -3
- package/dist/types/components/condition-tree/condition-tree-nodes.d.ts +11 -4
- package/dist/types/components/condition-tree/condition-tree-view-context.d.ts +3 -2
- package/dist/types/components/condition-tree/condition-tree.d.ts +41 -8
- package/dist/types/components/condition-tree/condition-tree.types.d.ts +21 -2
- package/dist/types/components/rule-editor/condition-tree-adapter.d.ts +67 -0
- package/dist/types/components/rule-editor/rule-condition-chip/rule-condition-chip.d.ts +82 -0
- package/dist/types/components/rule-editor/rule-condition-editor/rule-condition-editor.d.ts +61 -0
- package/dist/types/components/rule-editor/rule-editor.d.ts +105 -47
- package/dist/types/components/rule-editor/rule-issues.d.ts +12 -0
- package/dist/types/components/rule-editor/view-helpers.d.ts +16 -35
- package/dist/types/components.d.ts +304 -79
- package/dist/types/stencil-public-runtime.d.ts +61 -55
- package/package.json +4 -4
- package/dist/cjs/limebb-rule-chip-popover.cjs.entry.js +0 -82
- package/dist/collection/components/rule-editor/chip-picker-view.js +0 -148
- package/dist/collection/components/rule-editor/group-node-view.js +0 -79
- package/dist/collection/components/rule-editor/rule-chip-popover/rule-chip-popover.css +0 -36
- package/dist/collection/components/rule-editor/rule-chip-popover/rule-chip-popover.js +0 -344
- package/dist/collection/components/rule-editor/rule-editor-views.js +0 -43
- package/dist/collection/components/rule-editor/rule-operations.js +0 -145
- package/dist/components/limebb-rule-chip-popover.d.ts +0 -11
- package/dist/components/limebb-rule-chip-popover.js +0 -1
- package/dist/components/rule-chip-popover.js +0 -1
- package/dist/esm/limebb-rule-chip-popover.entry.js +0 -80
- package/dist/lime-crm-building-blocks/p-1578c8f0.entry.js +0 -1
- package/dist/lime-crm-building-blocks/p-229d018c.entry.js +0 -1
- package/dist/lime-crm-building-blocks/p-6331f9c5.entry.js +0 -1
- package/dist/lime-crm-building-blocks/p-705c53c0.entry.js +0 -1
- package/dist/lime-crm-building-blocks/p-84ad9159.entry.js +0 -1
- package/dist/lime-crm-building-blocks/p-BxCq236x.js +0 -1
- package/dist/lime-crm-building-blocks/p-Css8537O.js +0 -1
- package/dist/lime-crm-building-blocks/p-a58c9e1e.entry.js +0 -1
- package/dist/lime-crm-building-blocks/p-hsyotUav.js +0 -1
- package/dist/types/components/rule-editor/chip-picker-view.d.ts +0 -35
- package/dist/types/components/rule-editor/group-node-view.d.ts +0 -11
- package/dist/types/components/rule-editor/rule-chip-popover/rule-chip-popover.d.ts +0 -43
- package/dist/types/components/rule-editor/rule-editor-views.d.ts +0 -58
- package/dist/types/components/rule-editor/rule-operations.d.ts +0 -70
|
@@ -1,179 +1,108 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var index = require('./index-
|
|
4
|
-
var index_esm = require('./index.esm-
|
|
3
|
+
var index = require('./index-Du4GyM0Y.js');
|
|
4
|
+
var index_esm = require('./index.esm-C2zw0QJK.js');
|
|
5
|
+
var conditionTreeTranslate = require('./condition-tree-translate-BQwKtiNZ.js');
|
|
6
|
+
var limebbRuleConditionEditor_entry = require('./limebb-rule-condition-editor-CHWTMOmi.js');
|
|
7
|
+
require('./limebb-rule-condition-chip.cjs.entry.js');
|
|
5
8
|
var ruleEditorModes = require('./rule-editor-modes-Dc6rnwD2.js');
|
|
6
9
|
var randomString = require('./random-string-BdZGIsGg.js');
|
|
10
|
+
require('./web-component-template-C-AkY5as.js');
|
|
7
11
|
|
|
8
12
|
/**
|
|
9
|
-
*
|
|
13
|
+
* The problems the registry found, gathered by the node each belongs to.
|
|
10
14
|
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
* @param
|
|
15
|
-
* @param
|
|
16
|
-
*/
|
|
17
|
-
function deleteNode(rule, path) {
|
|
18
|
-
if (path.length === 0) {
|
|
19
|
-
return { type: 'all', rules: [] };
|
|
20
|
-
}
|
|
21
|
-
const parentPath = path.slice(0, -1);
|
|
22
|
-
const key = path.at(-1);
|
|
23
|
-
const parent = getNode(rule, parentPath);
|
|
24
|
-
if (parent === undefined) {
|
|
25
|
-
return rule;
|
|
26
|
-
}
|
|
27
|
-
if ((parent.type === 'all' || parent.type === 'any') &&
|
|
28
|
-
typeof key === 'number') {
|
|
29
|
-
const rules = [...parent.rules];
|
|
30
|
-
rules.splice(key, 1);
|
|
31
|
-
return replaceAt(rule, parentPath, Object.assign(Object.assign({}, parent), { rules }));
|
|
32
|
-
}
|
|
33
|
-
if (parent.type === 'not' && key === 'rule') {
|
|
34
|
-
return replaceAt(rule, parentPath, { type: 'all', rules: [] });
|
|
35
|
-
}
|
|
36
|
-
return rule;
|
|
37
|
-
}
|
|
38
|
-
/**
|
|
39
|
-
* Replace the `args` of a `ref` node. Returns `rule` unchanged when
|
|
40
|
-
* `path` does not resolve to a `ref`.
|
|
41
|
-
* @param rule
|
|
42
|
-
* @param path
|
|
43
|
-
* @param args
|
|
44
|
-
*/
|
|
45
|
-
function updateArgs(rule, path, args) {
|
|
46
|
-
const node = getNode(rule, path);
|
|
47
|
-
if (node === undefined || node.type !== 'ref') {
|
|
48
|
-
return rule;
|
|
49
|
-
}
|
|
50
|
-
return replaceAt(rule, path, Object.assign(Object.assign({}, node), { args }));
|
|
51
|
-
}
|
|
52
|
-
/**
|
|
53
|
-
* Replace the node at `path` with `replacement`, returning a new rule
|
|
54
|
-
* tree. Used by callers that need to apply a non-atomic change as a
|
|
55
|
-
* single emit (e.g. updating a group's whole `rules` array at once).
|
|
56
|
-
* @param rule
|
|
57
|
-
* @param path
|
|
58
|
-
* @param replacement
|
|
59
|
-
*/
|
|
60
|
-
function replaceNode(rule, path, replacement) {
|
|
61
|
-
return replaceAt(rule, path, replacement);
|
|
62
|
-
}
|
|
63
|
-
/**
|
|
64
|
-
* Wrap `group` in a `not` when `isNegated`, otherwise return it
|
|
65
|
-
* unchanged. Used when re-emitting a group whose negation flag should
|
|
66
|
-
* be preserved.
|
|
67
|
-
* @param group
|
|
68
|
-
* @param isNegated
|
|
69
|
-
*/
|
|
70
|
-
function wrapNegated(group, isNegated) {
|
|
71
|
-
return isNegated ? { type: 'not', rule: group } : group;
|
|
72
|
-
}
|
|
73
|
-
/**
|
|
74
|
-
* Append `child` to a group's `rules`, returning a new group. The
|
|
75
|
-
* input is not mutated.
|
|
76
|
-
* @param group
|
|
77
|
-
* @param child
|
|
15
|
+
* The registry addresses an issue by path — `['rules', 0, 'rule']` for
|
|
16
|
+
* `root.rules[0].rule` — while the tree asks about one node at a time and never
|
|
17
|
+
* says where it is. Resolving the paths once, here, bridges the two.
|
|
18
|
+
* @param root
|
|
19
|
+
* @param issues
|
|
78
20
|
*/
|
|
79
|
-
function
|
|
80
|
-
|
|
21
|
+
function collectRuleIssues(root, issues) {
|
|
22
|
+
var _a, _b;
|
|
23
|
+
const owners = displayOwners(root);
|
|
24
|
+
const byNode = new Map();
|
|
25
|
+
for (const issue of issues) {
|
|
26
|
+
const node = nodeAt(root, issue.path);
|
|
27
|
+
// An empty path means the rule as a whole, and one the path cannot
|
|
28
|
+
// reach has nowhere better to go than the root either.
|
|
29
|
+
const owner = (_a = (node && owners.get(node))) !== null && _a !== void 0 ? _a : root;
|
|
30
|
+
byNode.set(owner, [...((_b = byNode.get(owner)) !== null && _b !== void 0 ? _b : []), issue.message]);
|
|
31
|
+
}
|
|
32
|
+
return byNode;
|
|
81
33
|
}
|
|
82
34
|
/**
|
|
83
|
-
*
|
|
84
|
-
*
|
|
85
|
-
*
|
|
35
|
+
* Which node each node is drawn as part of. Most stand for themselves; the
|
|
36
|
+
* exception is everything under a `not`, which is drawn as that `not` — the
|
|
37
|
+
* two are one thing on screen, and only the wrapper has somewhere to show it.
|
|
38
|
+
* @param root
|
|
86
39
|
*/
|
|
87
|
-
function
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
40
|
+
function displayOwners(root) {
|
|
41
|
+
const owners = new Map();
|
|
42
|
+
const visit = (node, owner) => {
|
|
43
|
+
// A hand-edited rule can hold a `null` where a node should be. It is
|
|
44
|
+
// drawn, as something that cannot be read, so it is walked past here.
|
|
45
|
+
if (typeof node !== 'object' || node === null) {
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
owners.set(node, owner);
|
|
49
|
+
if (node.type === 'not') {
|
|
50
|
+
visit(node.rule, owner);
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
if ((node.type === 'all' || node.type === 'any') &&
|
|
54
|
+
Array.isArray(node.rules)) {
|
|
55
|
+
for (const child of node.rules) {
|
|
56
|
+
visit(child, child);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
visit(root, root);
|
|
61
|
+
return owners;
|
|
100
62
|
}
|
|
101
63
|
/**
|
|
102
|
-
*
|
|
103
|
-
*
|
|
104
|
-
*
|
|
105
|
-
*
|
|
64
|
+
* The node a validation path addresses, or nothing when it addresses none.
|
|
65
|
+
*
|
|
66
|
+
* Walked one hop at a time because the two the registry emits have different
|
|
67
|
+
* shapes: into a negation is the single segment `rule`, into the *n*-th child
|
|
68
|
+
* of a group is the pair `rules`, *n*. Anything else is not a path this rule
|
|
69
|
+
* can be walked by.
|
|
70
|
+
* @param root
|
|
106
71
|
* @param path
|
|
107
72
|
*/
|
|
108
|
-
function
|
|
109
|
-
let node =
|
|
110
|
-
|
|
111
|
-
|
|
73
|
+
function nodeAt(root, path) {
|
|
74
|
+
let node = root;
|
|
75
|
+
let index = 0;
|
|
76
|
+
while (index < path.length) {
|
|
77
|
+
// The same `null` can be standing one hop short of the path's end,
|
|
78
|
+
// with no hop to take from it. Asked for `type`, it would throw.
|
|
79
|
+
if (node === null || typeof node !== 'object') {
|
|
112
80
|
return undefined;
|
|
113
81
|
}
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
if (path.length === 0) {
|
|
120
|
-
return replacement;
|
|
121
|
-
}
|
|
122
|
-
const [head, ...tail] = path;
|
|
123
|
-
if (root.type === 'not' && head === 'rule') {
|
|
124
|
-
return Object.assign(Object.assign({}, root), { rule: replaceAt(root.rule, tail, replacement) });
|
|
125
|
-
}
|
|
126
|
-
if ((root.type === 'all' || root.type === 'any') && head === 'rules') {
|
|
127
|
-
if (tail.length === 0) {
|
|
128
|
-
return replacement;
|
|
82
|
+
const key = path[index];
|
|
83
|
+
if (key === 'rule' && node.type === 'not') {
|
|
84
|
+
node = node.rule;
|
|
85
|
+
index += 1;
|
|
86
|
+
continue;
|
|
129
87
|
}
|
|
130
|
-
const [index
|
|
131
|
-
if (
|
|
132
|
-
|
|
88
|
+
const child = path[index + 1];
|
|
89
|
+
if (key === 'rules' &&
|
|
90
|
+
(node.type === 'all' || node.type === 'any') &&
|
|
91
|
+
Array.isArray(node.rules) &&
|
|
92
|
+
typeof child === 'number') {
|
|
93
|
+
node = node.rules[child];
|
|
94
|
+
index += 2;
|
|
95
|
+
continue;
|
|
133
96
|
}
|
|
134
|
-
|
|
135
|
-
rules[index] = replaceAt(rules[index], rest, replacement);
|
|
136
|
-
return Object.assign(Object.assign({}, root), { rules });
|
|
137
|
-
}
|
|
138
|
-
return root;
|
|
139
|
-
}
|
|
140
|
-
function stepIntoNode(node, key) {
|
|
141
|
-
if (node.type === 'not' && key === 'rule') {
|
|
142
|
-
return node.rule;
|
|
143
|
-
}
|
|
144
|
-
if ((node.type === 'all' || node.type === 'any') && key === 'rules') {
|
|
145
|
-
return node;
|
|
146
|
-
}
|
|
147
|
-
if ((node.type === 'all' || node.type === 'any') &&
|
|
148
|
-
typeof key === 'number') {
|
|
149
|
-
return node.rules[key];
|
|
97
|
+
return undefined;
|
|
150
98
|
}
|
|
151
99
|
return node;
|
|
152
100
|
}
|
|
153
101
|
|
|
154
|
-
const UNKNOWN_ICON = {
|
|
155
|
-
name: 'question',
|
|
156
|
-
color: 'rgb(var(--color-glaucous-light))',
|
|
157
|
-
};
|
|
158
|
-
/**
|
|
159
|
-
* Class map for a rule-node container. Adds the type modifier and an
|
|
160
|
-
* `invalid` flag when validation issues attach to this node.
|
|
161
|
-
* @param type
|
|
162
|
-
* @param issues
|
|
163
|
-
*/
|
|
164
|
-
function nodeClasses(type, issues) {
|
|
165
|
-
return {
|
|
166
|
-
'rule-node': true,
|
|
167
|
-
[`rule-node--${type}`]: true,
|
|
168
|
-
'rule-node--invalid': issues.length > 0,
|
|
169
|
-
};
|
|
170
|
-
}
|
|
171
102
|
/**
|
|
172
|
-
*
|
|
173
|
-
*
|
|
174
|
-
*
|
|
175
|
-
* register translation keys as metadata — plain strings travel through
|
|
176
|
-
* unchanged.
|
|
103
|
+
* The primitives the add button offers. Titles and descriptions go through the
|
|
104
|
+
* translator, so a caller can register translation keys as metadata — plain
|
|
105
|
+
* strings travel through unchanged.
|
|
177
106
|
* @param metadataById
|
|
178
107
|
* @param translator
|
|
179
108
|
*/
|
|
@@ -181,7 +110,7 @@ function createPrimitiveOptions(metadataById, translator) {
|
|
|
181
110
|
return [...metadataById.values()]
|
|
182
111
|
.map((meta) => ({
|
|
183
112
|
value: meta.id,
|
|
184
|
-
text: meta
|
|
113
|
+
text: primitiveTitle(meta, translator),
|
|
185
114
|
secondaryText: meta.description
|
|
186
115
|
? translator.get(meta.description)
|
|
187
116
|
: '',
|
|
@@ -189,6 +118,15 @@ function createPrimitiveOptions(metadataById, translator) {
|
|
|
189
118
|
}))
|
|
190
119
|
.sort((a, b) => a.text.localeCompare(b.text));
|
|
191
120
|
}
|
|
121
|
+
/**
|
|
122
|
+
* How a primitive reads: its translated title, or its bare id when it has none
|
|
123
|
+
* to give. The add menu and the chip both read it from here, so they agree.
|
|
124
|
+
* @param meta
|
|
125
|
+
* @param translator
|
|
126
|
+
*/
|
|
127
|
+
function primitiveTitle(meta, translator) {
|
|
128
|
+
return meta.title ? translator.get(meta.title) : meta.id;
|
|
129
|
+
}
|
|
192
130
|
/**
|
|
193
131
|
* Whether every context key a primitive reads is in the reachable set.
|
|
194
132
|
* A primitive that reads nothing is always covered.
|
|
@@ -199,23 +137,9 @@ function primitiveReadsCovered(meta, reachable) {
|
|
|
199
137
|
return meta.reads.every((key) => reachable.has(key));
|
|
200
138
|
}
|
|
201
139
|
/**
|
|
202
|
-
*
|
|
203
|
-
*
|
|
204
|
-
*
|
|
205
|
-
* @param id
|
|
206
|
-
*/
|
|
207
|
-
function resolveItem(allItems, id) {
|
|
208
|
-
var _a;
|
|
209
|
-
return ((_a = allItems.find((item) => item.value === id)) !== null && _a !== void 0 ? _a : {
|
|
210
|
-
value: id,
|
|
211
|
-
text: id,
|
|
212
|
-
icon: UNKNOWN_ICON,
|
|
213
|
-
});
|
|
214
|
-
}
|
|
215
|
-
/**
|
|
216
|
-
* Build a picker `searcher` bound to a fixed item list. Both the ref
|
|
217
|
-
* picker and the chip picker want exactly this — wrapping
|
|
218
|
-
* {@link searchItems} in a promise — and deserve to share it.
|
|
140
|
+
* Narrow the primitives as the user types, for the search field at the top of
|
|
141
|
+
* the add menu. Every word has to match somewhere — title, description or id —
|
|
142
|
+
* so that "deal won" finds "Won deals".
|
|
219
143
|
* @param items
|
|
220
144
|
*/
|
|
221
145
|
function createSearcher(items) {
|
|
@@ -230,273 +154,12 @@ function searchItems(allItems, query) {
|
|
|
230
154
|
var _a, _b;
|
|
231
155
|
return item.text.toLocaleLowerCase().includes(part) ||
|
|
232
156
|
((_a = item.secondaryText) === null || _a === void 0 ? void 0 : _a.toLocaleLowerCase().includes(part)) ||
|
|
233
|
-
((_b = item.value)
|
|
157
|
+
String((_b = item.value) !== null && _b !== void 0 ? _b : '')
|
|
158
|
+
.toLocaleLowerCase()
|
|
159
|
+
.includes(part);
|
|
234
160
|
}));
|
|
235
161
|
}
|
|
236
162
|
|
|
237
|
-
const CHIP_TOKEN_PREFIX = '__chip__:';
|
|
238
|
-
function chipTokenFor(index) {
|
|
239
|
-
return `${CHIP_TOKEN_PREFIX}${index}`;
|
|
240
|
-
}
|
|
241
|
-
// The address of a chip inside a group is the group's path followed
|
|
242
|
-
// by a two-segment suffix `['rules', index]`. Build and parse via
|
|
243
|
-
// these helpers so both sides stay in sync.
|
|
244
|
-
const CHIP_PATH_SUFFIX_LENGTH = 2;
|
|
245
|
-
/**
|
|
246
|
-
* Address of the chip at `index` inside a group: the group's path plus
|
|
247
|
-
* the `['rules', index]` suffix. Built here so the picker and popover
|
|
248
|
-
* address chips the same way.
|
|
249
|
-
* @param groupPath
|
|
250
|
-
* @param index
|
|
251
|
-
*/
|
|
252
|
-
function buildChipPath(groupPath, index) {
|
|
253
|
-
return [...groupPath, 'rules', index];
|
|
254
|
-
}
|
|
255
|
-
function parentGroupPath(chipPath) {
|
|
256
|
-
return chipPath.slice(0, -CHIP_PATH_SUFFIX_LENGTH);
|
|
257
|
-
}
|
|
258
|
-
/**
|
|
259
|
-
* If `node` is a `ref` or a `not(ref)`, return the underlying ref
|
|
260
|
-
* together with its negation flag. Used to decide whether a child of a
|
|
261
|
-
* group renders as a chip (this returns non-null) or as a nested box
|
|
262
|
-
* (this returns null).
|
|
263
|
-
* @param node
|
|
264
|
-
*/
|
|
265
|
-
function extractRef(node) {
|
|
266
|
-
if (node.type === 'ref') {
|
|
267
|
-
return { ref: node, isNegated: false };
|
|
268
|
-
}
|
|
269
|
-
if (node.type === 'not' && node.rule.type === 'ref') {
|
|
270
|
-
return { ref: node.rule, isNegated: true };
|
|
271
|
-
}
|
|
272
|
-
return null;
|
|
273
|
-
}
|
|
274
|
-
const GroupChipsView = ({ groupNode, groupPath, chipChildren, ctx }) => {
|
|
275
|
-
const chipsByToken = new Map();
|
|
276
|
-
const value = chipChildren.map((entry) => {
|
|
277
|
-
const token = chipTokenFor(entry.index);
|
|
278
|
-
chipsByToken.set(token, entry);
|
|
279
|
-
const base = resolveItem(ctx.allPrimitiveOptions, entry.ref.id);
|
|
280
|
-
return Object.assign(Object.assign({}, base), { text: entry.isNegated ? `¬ ${base.text}` : base.text, value: token });
|
|
281
|
-
});
|
|
282
|
-
const searcher = createSearcher(ctx.availablePrimitiveOptions);
|
|
283
|
-
const openChip = findOpenChip(chipChildren, groupPath, ctx.openChipPath);
|
|
284
|
-
const delimiter = groupNode.type === 'all' ? '&' : '|';
|
|
285
|
-
return (index.h("limel-popover", { class: "rule-node__chips-popover", open: openChip !== null, openDirection: "bottom-start", onClose: ctx.onPopoverClose }, index.h("div", { slot: "trigger", class: "rule-node__chips" }, index.h("limel-picker", { multiple: true, label: ctx.translator.get('webclient.rule-editor.rules-label'), value: value, searcher: searcher, delimiter: delimiter, readonly: ctx.readonly, disabled: ctx.disabled, onChange: chipsChangeHandler(groupNode, groupPath, chipsByToken, ctx), onInteract: chipInteractHandler(groupPath, chipsByToken, ctx) })), index.h("div", null, renderChipPopoverContent(openChip, groupPath, ctx))));
|
|
286
|
-
};
|
|
287
|
-
function renderChipPopoverContent(openChip, groupPath, ctx) {
|
|
288
|
-
if (!openChip) {
|
|
289
|
-
return null;
|
|
290
|
-
}
|
|
291
|
-
const openChipPath = buildChipPath(groupPath, openChip.index);
|
|
292
|
-
return (index.h("limebb-rule-chip-popover", { platform: ctx.platform, context: ctx.context, refNode: openChip.ref, isNegated: openChip.isNegated, metadata: ctx.metadataById.get(openChip.ref.id), readonly: ctx.readonly, disabled: ctx.disabled, isMutable: ctx.isMutable, focusOnOpen: ctx.focusOnOpen, onNegate: chipNegateHandler(openChip, openChipPath, ctx), onUpdateArgs: chipArgsHandler(openChip, openChipPath, ctx), onDeleteChip: chipDeleteHandler(openChipPath, ctx) }));
|
|
293
|
-
}
|
|
294
|
-
const chipsChangeHandler = (groupNode, groupPath, chipsByToken, ctx) => (event) => {
|
|
295
|
-
event.stopPropagation();
|
|
296
|
-
const items = Array.isArray(event.detail) ? event.detail : [];
|
|
297
|
-
const openIndex = openChipIndexInGroup(groupPath, ctx.openChipPath);
|
|
298
|
-
if (openIndex !== null) {
|
|
299
|
-
const openToken = chipTokenFor(openIndex);
|
|
300
|
-
if (items.every((item) => item.value !== openToken)) {
|
|
301
|
-
ctx.onPopoverClose();
|
|
302
|
-
}
|
|
303
|
-
}
|
|
304
|
-
const newChipNodes = items.flatMap((item) => {
|
|
305
|
-
if (typeof item.value !== 'string') {
|
|
306
|
-
return [];
|
|
307
|
-
}
|
|
308
|
-
const existing = chipsByToken.get(item.value);
|
|
309
|
-
if (existing) {
|
|
310
|
-
return [
|
|
311
|
-
existing.isNegated
|
|
312
|
-
? { type: 'not', rule: existing.ref }
|
|
313
|
-
: existing.ref,
|
|
314
|
-
];
|
|
315
|
-
}
|
|
316
|
-
return [{ type: 'ref', id: item.value }];
|
|
317
|
-
});
|
|
318
|
-
const nestedGroupRules = groupNode.rules.filter((rule) => extractRef(rule) === null);
|
|
319
|
-
ctx.onReplaceNode(groupPath, Object.assign(Object.assign({}, groupNode), { rules: [...newChipNodes, ...nestedGroupRules] }));
|
|
320
|
-
};
|
|
321
|
-
const chipInteractHandler = (groupPath, chipsByToken, ctx) => (event) => {
|
|
322
|
-
event.stopPropagation();
|
|
323
|
-
const token = interactedToken(event.detail);
|
|
324
|
-
const chip = token ? chipsByToken.get(token) : undefined;
|
|
325
|
-
if (!chip) {
|
|
326
|
-
return;
|
|
327
|
-
}
|
|
328
|
-
ctx.onChipInteract([...groupPath, 'rules', chip.index]);
|
|
329
|
-
};
|
|
330
|
-
const chipNegateHandler = (openChip, openChipPath, ctx) => (event) => {
|
|
331
|
-
event.stopPropagation();
|
|
332
|
-
const next = event.detail
|
|
333
|
-
? { type: 'not', rule: openChip.ref }
|
|
334
|
-
: openChip.ref;
|
|
335
|
-
ctx.onReplaceNode(openChipPath, next);
|
|
336
|
-
};
|
|
337
|
-
const chipArgsHandler = (openChip, openChipPath, ctx) => (event) => {
|
|
338
|
-
event.stopPropagation();
|
|
339
|
-
const argsPath = openChip.isNegated
|
|
340
|
-
? [...openChipPath, 'rule']
|
|
341
|
-
: openChipPath;
|
|
342
|
-
ctx.onUpdateArgs(argsPath, event.detail);
|
|
343
|
-
};
|
|
344
|
-
const chipDeleteHandler = (openChipPath, ctx) => () => {
|
|
345
|
-
ctx.onDelete(openChipPath);
|
|
346
|
-
};
|
|
347
|
-
/**
|
|
348
|
-
* `limel-picker` declares its `interact` event as
|
|
349
|
-
* `EventEmitter<ListItem<PickerValue>>` but the runtime actually emits
|
|
350
|
-
* the chip's value (a string) — see picker.tsx's handleInteract. This
|
|
351
|
-
* unwraps either shape into the string token.
|
|
352
|
-
* @param detail
|
|
353
|
-
*/
|
|
354
|
-
function interactedToken(detail) {
|
|
355
|
-
if (typeof detail === 'string') {
|
|
356
|
-
return detail;
|
|
357
|
-
}
|
|
358
|
-
if (detail && typeof detail === 'object' && 'value' in detail) {
|
|
359
|
-
const value = detail.value;
|
|
360
|
-
return typeof value === 'string' ? value : undefined;
|
|
361
|
-
}
|
|
362
|
-
return undefined;
|
|
363
|
-
}
|
|
364
|
-
function findOpenChip(chipChildren, groupPath, openChipPath) {
|
|
365
|
-
var _a;
|
|
366
|
-
const index = openChipIndexInGroup(groupPath, openChipPath);
|
|
367
|
-
if (index === null) {
|
|
368
|
-
return null;
|
|
369
|
-
}
|
|
370
|
-
return (_a = chipChildren.find((entry) => entry.index === index)) !== null && _a !== void 0 ? _a : null;
|
|
371
|
-
}
|
|
372
|
-
function openChipIndexInGroup(groupPath, openChipPath) {
|
|
373
|
-
if (!openChipPath || openChipPath.length < CHIP_PATH_SUFFIX_LENGTH) {
|
|
374
|
-
return null;
|
|
375
|
-
}
|
|
376
|
-
if (!pathsEqual(parentGroupPath(openChipPath), groupPath)) {
|
|
377
|
-
return null;
|
|
378
|
-
}
|
|
379
|
-
const lastKey = openChipPath.at(-1);
|
|
380
|
-
return typeof lastKey === 'number' ? lastKey : null;
|
|
381
|
-
}
|
|
382
|
-
|
|
383
|
-
const GroupNodeView = ({ node, path, isNegated, ctx }) => {
|
|
384
|
-
const groupBasePath = isNegated ? [...path, 'rule'] : path;
|
|
385
|
-
const issuesHere = isNegated
|
|
386
|
-
? [
|
|
387
|
-
...issuesAt(ctx.issues, path),
|
|
388
|
-
...issuesAt(ctx.issues, groupBasePath),
|
|
389
|
-
]
|
|
390
|
-
: issuesAt(ctx.issues, path);
|
|
391
|
-
const chipChildren = [];
|
|
392
|
-
const nestedGroups = [];
|
|
393
|
-
for (const [index, child] of node.rules.entries()) {
|
|
394
|
-
const extracted = extractRef(child);
|
|
395
|
-
if (extracted) {
|
|
396
|
-
chipChildren.push(Object.assign(Object.assign({}, extracted), { index }));
|
|
397
|
-
}
|
|
398
|
-
else {
|
|
399
|
-
nestedGroups.push({ child, index });
|
|
400
|
-
}
|
|
401
|
-
}
|
|
402
|
-
const options = combinatorOptions(ctx);
|
|
403
|
-
const selectedCombinator = options.find((option) => option.value === node.type);
|
|
404
|
-
return (index.h("div", { class: nodeClasses(node.type, issuesHere), key: pathKey(path) }, index.h("div", { class: "rule-node__header" }, index.h("limel-select", { class: "rule-node__combinator-select", value: selectedCombinator, options: options, disabled: !ctx.isMutable, onChange: combinatorChangeHandler(node, path, isNegated, ctx) }), renderMutableGroupActions(node, path, isNegated, ctx)), index.h("div", { class: "rule-node__body" }, index.h(IssuesView, { issues: issuesHere }), index.h(GroupChipsView, { groupNode: node, groupPath: groupBasePath, chipChildren: chipChildren, ctx: ctx }), renderNestedGroups(nestedGroups, groupBasePath, ctx), renderAddGroupFooter(node, path, isNegated, ctx))));
|
|
405
|
-
};
|
|
406
|
-
function pathKey(path) {
|
|
407
|
-
return path.length === 0 ? 'root' : path.join('/');
|
|
408
|
-
}
|
|
409
|
-
function combinatorOptions(ctx) {
|
|
410
|
-
return [
|
|
411
|
-
{
|
|
412
|
-
value: 'all',
|
|
413
|
-
text: ctx.translator.get('webclient.combinator.all'),
|
|
414
|
-
},
|
|
415
|
-
{
|
|
416
|
-
value: 'any',
|
|
417
|
-
text: ctx.translator.get('webclient.combinator.any'),
|
|
418
|
-
},
|
|
419
|
-
];
|
|
420
|
-
}
|
|
421
|
-
function renderMutableGroupActions(node, path, isNegated, ctx) {
|
|
422
|
-
if (!ctx.isMutable) {
|
|
423
|
-
return null;
|
|
424
|
-
}
|
|
425
|
-
return (index.h("div", { class: "rule-node__header-actions" }, index.h("limel-switch", { class: "rule-node__negate-switch", label: ctx.translator.get('webclient.negate'), value: isNegated, onChange: negateGroupHandler(node, path, ctx) }), index.h("limel-icon-button", { icon: "trash", label: ctx.translator.get('webclient.rule-editor.delete'), onClick: () => ctx.onDelete(path) })));
|
|
426
|
-
}
|
|
427
|
-
function renderNestedGroups(nestedGroups, groupBasePath, ctx) {
|
|
428
|
-
if (nestedGroups.length === 0) {
|
|
429
|
-
return null;
|
|
430
|
-
}
|
|
431
|
-
return (index.h("div", { class: "rule-node__children" }, nestedGroups.map((entry) => (index.h(RuleNodeView, { node: entry.child, path: [...groupBasePath, 'rules', entry.index], ctx: ctx })))));
|
|
432
|
-
}
|
|
433
|
-
function renderAddGroupFooter(node, path, isNegated, ctx) {
|
|
434
|
-
if (!ctx.isMutable) {
|
|
435
|
-
return null;
|
|
436
|
-
}
|
|
437
|
-
return (index.h("div", { class: "rule-node__footer" }, index.h("limel-button", { icon: "add", label: ctx.translator.get('webclient.rule-editor.add-nested-group'), onClick: addGroupHandler(node, path, isNegated, ctx) })));
|
|
438
|
-
}
|
|
439
|
-
function replaceGroup(nextGroup, path, isNegated, ctx) {
|
|
440
|
-
ctx.onReplaceNode(path, wrapNegated(nextGroup, isNegated));
|
|
441
|
-
}
|
|
442
|
-
const combinatorChangeHandler = (node, path, isNegated, ctx) => (event) => {
|
|
443
|
-
event.stopPropagation();
|
|
444
|
-
const newType = event.detail.value;
|
|
445
|
-
if (newType !== node.type) {
|
|
446
|
-
replaceGroup(Object.assign(Object.assign({}, node), { type: newType }), path, isNegated, ctx);
|
|
447
|
-
}
|
|
448
|
-
};
|
|
449
|
-
const addGroupHandler = (node, path, isNegated, ctx) => () => {
|
|
450
|
-
const expanded = appendChild(node, { type: 'all', rules: [] });
|
|
451
|
-
replaceGroup(expanded, path, isNegated, ctx);
|
|
452
|
-
};
|
|
453
|
-
const negateGroupHandler = (node, path, ctx) => (event) => {
|
|
454
|
-
event.stopPropagation();
|
|
455
|
-
ctx.onReplaceNode(path, wrapNegated(node, event.detail));
|
|
456
|
-
};
|
|
457
|
-
|
|
458
|
-
/**
|
|
459
|
-
* Render a `Rule` node and recurse into its children.
|
|
460
|
-
* @param props
|
|
461
|
-
*/
|
|
462
|
-
const RuleNodeView = (props) => {
|
|
463
|
-
const { node, path, ctx } = props;
|
|
464
|
-
const group = extractGroup(node);
|
|
465
|
-
if (!group) {
|
|
466
|
-
return null;
|
|
467
|
-
}
|
|
468
|
-
return (index.h(GroupNodeView, { node: group.node, path: path, isNegated: group.isNegated, ctx: ctx }));
|
|
469
|
-
};
|
|
470
|
-
const isNegatedGroup = (node) => node.type === 'not' &&
|
|
471
|
-
(node.rule.type === 'all' || node.rule.type === 'any');
|
|
472
|
-
/**
|
|
473
|
-
* If `node` is a group (`all`/`any`) or a negated group, return the
|
|
474
|
-
* inner group together with its negation flag. Otherwise `null`.
|
|
475
|
-
* Used by the dispatcher and by the editor's input normalization.
|
|
476
|
-
* @param node
|
|
477
|
-
*/
|
|
478
|
-
function extractGroup(node) {
|
|
479
|
-
if (node.type === 'all' || node.type === 'any') {
|
|
480
|
-
return { node, isNegated: false };
|
|
481
|
-
}
|
|
482
|
-
if (isNegatedGroup(node)) {
|
|
483
|
-
return { node: node.rule, isNegated: true };
|
|
484
|
-
}
|
|
485
|
-
if (node.type === 'not') {
|
|
486
|
-
const inner = extractGroup(node.rule);
|
|
487
|
-
if (inner) {
|
|
488
|
-
return { node: inner.node, isNegated: !inner.isNegated };
|
|
489
|
-
}
|
|
490
|
-
}
|
|
491
|
-
return null;
|
|
492
|
-
}
|
|
493
|
-
const IssuesView = ({ issues }) => {
|
|
494
|
-
if (issues.length === 0) {
|
|
495
|
-
return null;
|
|
496
|
-
}
|
|
497
|
-
return issues.map((issue) => (index.h("div", { class: "rule-node__issue" }, issue.message)));
|
|
498
|
-
};
|
|
499
|
-
|
|
500
163
|
/**
|
|
501
164
|
* The shared string each mode is labelled from. Adverbs answering "when
|
|
502
165
|
* does this apply?", so they carry no rule-editor namespace and are
|
|
@@ -529,7 +192,7 @@ const RuleModeView = (props) => {
|
|
|
529
192
|
} }));
|
|
530
193
|
};
|
|
531
194
|
|
|
532
|
-
const ruleEditorCss = () => `@charset "UTF-8";:host{display:block;position:relative}.limel-notched-outline{--limel-notched-outline-background-color:transparent;padding:0.5rem 0 0 0}limel-notched-outline:not([invalid]:not([invalid=false])) .limel-notched-outline{--limel-notched-outline-border-color:transparent}.rule-editor--disabled{opacity:0.6;pointer-events:none}
|
|
195
|
+
const ruleEditorCss = () => `@charset "UTF-8";:host{display:block;position:relative}.limel-notched-outline{--limel-notched-outline-background-color:transparent;padding:0.5rem 0 0 0}limel-notched-outline:not([invalid]:not([invalid=false])) .limel-notched-outline{--limel-notched-outline-border-color:transparent}.rule-editor--disabled{opacity:0.6;pointer-events:none}limebb-condition-tree{--popover-surface-width:min(calc(100vw - 4rem), 50rem)}:host(limebb-rule-editor:focus),:host(limebb-rule-editor:focus-visible),:host(limebb-rule-editor:focus-within){--limel-h-l-grid-template-rows-transition-speed:0.46s;--limel-h-l-grid-template-rows:1fr}:host(limebb-rule-editor){--limel-h-l-grid-template-rows-transition-speed:0.3s;--limel-h-l-grid-template-rows:0fr}:host(limebb-rule-editor:focus) limel-helper-line,:host(limebb-rule-editor:focus-visible) limel-helper-line,:host(limebb-rule-editor:focus-within) limel-helper-line,:host(limebb-rule-editor:hover) limel-helper-line{will-change:grid-template-rows}limel-help{position:absolute;top:calc(var(--form-row-gap, 1rem) * -0.5);left:calc(var(--form-column-gap, 1rem) * -0.5);z-index:1}`;
|
|
533
196
|
|
|
534
197
|
var __decorate = (undefined && undefined.__decorate) || function (decorators, target, key, desc) {
|
|
535
198
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
@@ -545,8 +208,6 @@ const RuleEditor = class {
|
|
|
545
208
|
constructor(hostRef) {
|
|
546
209
|
index.registerInstance(this, hostRef);
|
|
547
210
|
this.change = index.createEvent(this, "change");
|
|
548
|
-
this.issues = [];
|
|
549
|
-
this.openChipPath = null;
|
|
550
211
|
/**
|
|
551
212
|
* The mode the author last clicked, held until `value` reads back
|
|
552
213
|
* as it.
|
|
@@ -557,10 +218,27 @@ const RuleEditor = class {
|
|
|
557
218
|
* what the author just clicked.
|
|
558
219
|
*/
|
|
559
220
|
this.modeOverride = null;
|
|
560
|
-
this.focusOnOpen = false;
|
|
561
221
|
this.metadataById = new Map();
|
|
562
|
-
|
|
222
|
+
/**
|
|
223
|
+
* How each registered primitive reads, by id. Translated once here
|
|
224
|
+
* because the platform's translator parses the message afresh on
|
|
225
|
+
* every call, and the adapter would otherwise do that per condition,
|
|
226
|
+
* several times over, on every edit.
|
|
227
|
+
*/
|
|
228
|
+
this.primitiveTitles = new Map();
|
|
563
229
|
this.availablePrimitiveOptions = [];
|
|
230
|
+
this.searcher = createSearcher([]);
|
|
231
|
+
/**
|
|
232
|
+
* What validation found, by the node it belongs to.
|
|
233
|
+
*/
|
|
234
|
+
this.issuesByNode = new Map();
|
|
235
|
+
/**
|
|
236
|
+
* The conditions added here rather than loaded, which a `RuleRef`
|
|
237
|
+
* does not record. The adapter reads it to decide which condition
|
|
238
|
+
* opens itself. Replaced when the tree goes, since a condition still
|
|
239
|
+
* listed when the author comes back would open itself again.
|
|
240
|
+
*/
|
|
241
|
+
this.created = new WeakSet();
|
|
564
242
|
this.reachableSlots = new Set();
|
|
565
243
|
this.normalizedCache = null;
|
|
566
244
|
this.hasLoaded = false;
|
|
@@ -574,6 +252,9 @@ const RuleEditor = class {
|
|
|
574
252
|
* conditions are gone, rather than handing back the ones they
|
|
575
253
|
* removed. With nothing stashed, `conditional` emits no rule, which
|
|
576
254
|
* is how the editor already says "the author cleared this".
|
|
255
|
+
*
|
|
256
|
+
* What is not stashed is which conditions had just been added, so
|
|
257
|
+
* that none of them opens itself again on the way back.
|
|
577
258
|
* @param mode
|
|
578
259
|
*/
|
|
579
260
|
this.handleModeChange = (mode) => {
|
|
@@ -581,32 +262,28 @@ const RuleEditor = class {
|
|
|
581
262
|
if (this.currentMode === 'conditional') {
|
|
582
263
|
this.stashedTree = this.value;
|
|
583
264
|
}
|
|
265
|
+
if (mode !== 'conditional') {
|
|
266
|
+
this.created = new WeakSet();
|
|
267
|
+
}
|
|
584
268
|
this.modeOverride = mode;
|
|
585
269
|
this.change.emit((_a = ruleEditorModes.ruleForMode(mode)) !== null && _a !== void 0 ? _a : this.stashedTree);
|
|
586
270
|
};
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
this.
|
|
602
|
-
|
|
603
|
-
this.handleChipInteract = (path) => {
|
|
604
|
-
this.openChipPath = path;
|
|
605
|
-
this.focusOnOpen = false;
|
|
606
|
-
};
|
|
607
|
-
this.handlePopoverClose = () => {
|
|
608
|
-
this.openChipPath = null;
|
|
609
|
-
this.focusOnOpen = false;
|
|
271
|
+
/**
|
|
272
|
+
* Take in a tree the author changed. The tree reports `null` when
|
|
273
|
+
* the last condition goes, which for a rule means there is none —
|
|
274
|
+
* the same thing an emptied editor has always emitted.
|
|
275
|
+
*
|
|
276
|
+
* Editing the tree is only possible in `conditional`, so the edit
|
|
277
|
+
* itself records the mode: without this, a tree emptied to nothing
|
|
278
|
+
* would read back as the first offered mode and rewrite the setting
|
|
279
|
+
* under the author.
|
|
280
|
+
* @param event
|
|
281
|
+
*/
|
|
282
|
+
this.handleTreeChange = (event) => {
|
|
283
|
+
var _a;
|
|
284
|
+
event.stopPropagation();
|
|
285
|
+
this.modeOverride = 'conditional';
|
|
286
|
+
this.change.emit((_a = event.detail) !== null && _a !== void 0 ? _a : undefined);
|
|
610
287
|
};
|
|
611
288
|
}
|
|
612
289
|
componentWillLoad() {
|
|
@@ -617,6 +294,7 @@ const RuleEditor = class {
|
|
|
617
294
|
this.indexMetadata();
|
|
618
295
|
this.rebuildAvailableOptions();
|
|
619
296
|
this.runValidation();
|
|
297
|
+
this.rebuildAdapter();
|
|
620
298
|
}
|
|
621
299
|
/**
|
|
622
300
|
* Re-walk reachable slots when the editor is re-attached to the DOM,
|
|
@@ -631,6 +309,7 @@ const RuleEditor = class {
|
|
|
631
309
|
this.computeReachableSlots();
|
|
632
310
|
this.rebuildAvailableOptions();
|
|
633
311
|
this.runValidation();
|
|
312
|
+
this.rebuildAdapter();
|
|
634
313
|
}
|
|
635
314
|
componentDidLoad() {
|
|
636
315
|
this.hasLoaded = true;
|
|
@@ -647,7 +326,7 @@ const RuleEditor = class {
|
|
|
647
326
|
this.rebuildFromRegistries();
|
|
648
327
|
}
|
|
649
328
|
render() {
|
|
650
|
-
return (index.h(index.Host, { key: '
|
|
329
|
+
return (index.h(index.Host, { key: 'eb89af0c748f82d8e60b1209c4fcce3475ac2934' }, this.renderHelp(), index.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 }, index.h("div", { key: '57293e75c641d4909a4d2e1d3a3d2c20a60a4512', slot: "content", class: {
|
|
651
330
|
'rule-editor': true,
|
|
652
331
|
'rule-editor--disabled': this.disabled,
|
|
653
332
|
}, role: "group", "aria-labelledby": this.label ? this.labelId : undefined, "aria-describedby": this.helperText ? this.helperTextId : undefined }, this.renderModes(), this.renderTree())), this.renderHelperLine()));
|
|
@@ -664,13 +343,18 @@ const RuleEditor = class {
|
|
|
664
343
|
* The condition tree, shown unless a mode other than `conditional`
|
|
665
344
|
* is selected — an unconditional rule has no conditions to show.
|
|
666
345
|
* A caller offering no modes at all gets the tree, as before.
|
|
346
|
+
*
|
|
347
|
+
* An unset rule is handed over as unset, rather than as an empty
|
|
348
|
+
* group: the tree draws the group an author's first condition will
|
|
349
|
+
* land in, and drawing one here would only be a second opinion on
|
|
350
|
+
* what that looks like.
|
|
667
351
|
*/
|
|
668
352
|
renderTree() {
|
|
669
353
|
const mode = this.currentMode;
|
|
670
354
|
if (mode && mode !== 'conditional') {
|
|
671
355
|
return null;
|
|
672
356
|
}
|
|
673
|
-
return (index.h(
|
|
357
|
+
return (index.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 }));
|
|
674
358
|
}
|
|
675
359
|
renderHelperLine() {
|
|
676
360
|
if (!this.helperText) {
|
|
@@ -684,27 +368,6 @@ const RuleEditor = class {
|
|
|
684
368
|
}
|
|
685
369
|
return index.h("limel-help", { value: this.help });
|
|
686
370
|
}
|
|
687
|
-
createRenderContext() {
|
|
688
|
-
return {
|
|
689
|
-
issues: this.issues,
|
|
690
|
-
metadataById: this.metadataById,
|
|
691
|
-
allPrimitiveOptions: this.allPrimitiveOptions,
|
|
692
|
-
availablePrimitiveOptions: this.availablePrimitiveOptions,
|
|
693
|
-
isMutable: !this.readonly && !this.disabled,
|
|
694
|
-
readonly: this.readonly,
|
|
695
|
-
disabled: this.disabled,
|
|
696
|
-
platform: this.platform,
|
|
697
|
-
context: this.effectiveContext,
|
|
698
|
-
translator: this.translator,
|
|
699
|
-
openChipPath: this.openChipPath,
|
|
700
|
-
focusOnOpen: this.focusOnOpen,
|
|
701
|
-
onDelete: this.handleDelete,
|
|
702
|
-
onUpdateArgs: this.handleUpdateArgs,
|
|
703
|
-
onReplaceNode: this.handleReplaceNode,
|
|
704
|
-
onChipInteract: this.handleChipInteract,
|
|
705
|
-
onPopoverClose: this.handlePopoverClose,
|
|
706
|
-
};
|
|
707
|
-
}
|
|
708
371
|
/**
|
|
709
372
|
* The mode the editor is in, or `undefined` when it offers none —
|
|
710
373
|
* then it is the plain tree editor it was before modes existed.
|
|
@@ -738,51 +401,14 @@ const RuleEditor = class {
|
|
|
738
401
|
this.modeOverride = null;
|
|
739
402
|
}
|
|
740
403
|
}
|
|
741
|
-
/**
|
|
742
|
-
* Path of a newly added chip whose primitive declares a config
|
|
743
|
-
* component, so its args editor opens immediately on add. The new
|
|
744
|
-
* ref is found by object identity — the picker reuses existing ref
|
|
745
|
-
* objects and only the added chip is a fresh node — so adding a
|
|
746
|
-
* second instance of a primitive already in the group is still
|
|
747
|
-
* detected. Returns `null` unless exactly one ref was added and it
|
|
748
|
-
* has an editor, leaving the open chip untouched for removals,
|
|
749
|
-
* multi-adds, and negation.
|
|
750
|
-
* @param path
|
|
751
|
-
* @param replacement
|
|
752
|
-
*/
|
|
753
|
-
autoOpenPathFor(path, replacement) {
|
|
754
|
-
var _a;
|
|
755
|
-
if (replacement.type !== 'all' && replacement.type !== 'any') {
|
|
756
|
-
return null;
|
|
757
|
-
}
|
|
758
|
-
const previous = getNode(this.normalizedValue, path);
|
|
759
|
-
if (previous === undefined ||
|
|
760
|
-
(previous.type !== 'all' && previous.type !== 'any')) {
|
|
761
|
-
return null;
|
|
762
|
-
}
|
|
763
|
-
const previousRefs = new Set(previous.rules
|
|
764
|
-
.map((rule) => { var _a; return (_a = extractRef(rule)) === null || _a === void 0 ? void 0 : _a.ref; })
|
|
765
|
-
.filter((ref) => ref !== undefined));
|
|
766
|
-
const added = replacement.rules
|
|
767
|
-
.map((rule, index) => {
|
|
768
|
-
var _a;
|
|
769
|
-
const ref = (_a = extractRef(rule)) === null || _a === void 0 ? void 0 : _a.ref;
|
|
770
|
-
return ref && !previousRefs.has(ref) ? { ref, index } : null;
|
|
771
|
-
})
|
|
772
|
-
.filter((entry) => entry !== null);
|
|
773
|
-
if (added.length !== 1) {
|
|
774
|
-
return null;
|
|
775
|
-
}
|
|
776
|
-
const [{ ref, index }] = added;
|
|
777
|
-
return ((_a = this.metadataById.get(ref.id)) === null || _a === void 0 ? void 0 : _a.configComponent)
|
|
778
|
-
? buildChipPath(path, index)
|
|
779
|
-
: null;
|
|
780
|
-
}
|
|
781
404
|
indexMetadata() {
|
|
782
405
|
var _a, _b, _c;
|
|
783
406
|
const metadata = (_c = (_b = (_a = this.ruleRegistry).listMetadata) === null || _b === void 0 ? void 0 : _b.call(_a)) !== null && _c !== void 0 ? _c : [];
|
|
784
407
|
this.metadataById = new Map(metadata.map((item) => [item.id, item]));
|
|
785
|
-
this.
|
|
408
|
+
this.primitiveTitles = new Map(metadata.map((item) => [
|
|
409
|
+
item.id,
|
|
410
|
+
primitiveTitle(item, this.translator),
|
|
411
|
+
]));
|
|
786
412
|
}
|
|
787
413
|
/**
|
|
788
414
|
* Recompute the cached add-palette options. The inputs — indexed
|
|
@@ -792,6 +418,7 @@ const RuleEditor = class {
|
|
|
792
418
|
*/
|
|
793
419
|
rebuildAvailableOptions() {
|
|
794
420
|
this.availablePrimitiveOptions = createPrimitiveOptions(this.availablePrimitiveMetadata(), this.translator);
|
|
421
|
+
this.searcher = createSearcher(this.availablePrimitiveOptions);
|
|
795
422
|
}
|
|
796
423
|
/**
|
|
797
424
|
* The subset of registered metadata offered for adding in the
|
|
@@ -799,7 +426,7 @@ const RuleEditor = class {
|
|
|
799
426
|
* reachable slots are dropped, and so is the always primitive —
|
|
800
427
|
* it reads nothing, so it is always covered, but an "Always" chip
|
|
801
428
|
* among a group's conditions says nothing. Filtering only the
|
|
802
|
-
* palette —
|
|
429
|
+
* palette — the adapter still reads the whole index — keeps
|
|
803
430
|
* already-placed chips resolving to their proper title even when
|
|
804
431
|
* their read slot isn't reachable.
|
|
805
432
|
*/
|
|
@@ -839,45 +466,81 @@ const RuleEditor = class {
|
|
|
839
466
|
]);
|
|
840
467
|
}
|
|
841
468
|
runValidation() {
|
|
842
|
-
|
|
843
|
-
this.issues = [];
|
|
844
|
-
return;
|
|
845
|
-
}
|
|
846
|
-
const result = this.ruleRegistry.validate(this.normalizedValue, [
|
|
847
|
-
...this.reachableSlots,
|
|
848
|
-
]);
|
|
849
|
-
this.issues = result.ok ? [] : result.issues;
|
|
469
|
+
this.issuesByNode = this.findIssues();
|
|
850
470
|
}
|
|
851
471
|
/**
|
|
852
|
-
*
|
|
853
|
-
*
|
|
854
|
-
*
|
|
855
|
-
*
|
|
856
|
-
*
|
|
472
|
+
* What the registry finds wrong with the rule, gathered by the node
|
|
473
|
+
* each problem belongs to. Validation runs against the normalized
|
|
474
|
+
* rule, which is also what the tree is handed, so the paths the
|
|
475
|
+
* registry reports address the very nodes the tree draws.
|
|
476
|
+
*
|
|
477
|
+
* A rule the registry cannot even walk — one hand-edited into a shape
|
|
478
|
+
* that is not a rule — makes it throw rather than report. That is the
|
|
479
|
+
* rule an author most needs the editor for, so the throw is caught
|
|
480
|
+
* and the editor drawn anyway: the tree marks the offending condition
|
|
481
|
+
* unreadable itself, which is the same thing validation would have
|
|
482
|
+
* said and in the place it belongs.
|
|
857
483
|
*/
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
484
|
+
findIssues() {
|
|
485
|
+
const root = this.normalizedValue;
|
|
486
|
+
if (!root) {
|
|
487
|
+
return new Map();
|
|
488
|
+
}
|
|
489
|
+
try {
|
|
490
|
+
const result = this.ruleRegistry.validate(root, [
|
|
491
|
+
...this.reachableSlots,
|
|
492
|
+
]);
|
|
493
|
+
return result.ok
|
|
494
|
+
? new Map()
|
|
495
|
+
: collectRuleIssues(root, result.issues);
|
|
496
|
+
}
|
|
497
|
+
catch (error) {
|
|
498
|
+
// The throw names the node it choked on. What the author needs is
|
|
499
|
+
// already in the tree; this is what tells a developer an unreadable
|
|
500
|
+
// rule from a registry that could not answer for a readable one.
|
|
501
|
+
console.warn('rule-editor could not validate the rule', {
|
|
502
|
+
rule: root,
|
|
503
|
+
error,
|
|
504
|
+
});
|
|
505
|
+
return new Map();
|
|
861
506
|
}
|
|
862
|
-
this.modeOverride = 'conditional';
|
|
863
|
-
this.change.emit(collapseEmptyRoot(next));
|
|
864
507
|
}
|
|
865
508
|
/**
|
|
866
|
-
*
|
|
867
|
-
*
|
|
868
|
-
*
|
|
869
|
-
*
|
|
870
|
-
*
|
|
509
|
+
* Gather what the tree draws from into a new adapter, which is how a
|
|
510
|
+
* change the rule does not carry reaches the screen at all.
|
|
511
|
+
*
|
|
512
|
+
* Not rebuilt for a validation pass: that runs because the rule
|
|
513
|
+
* changed, and the tree is already redrawing for the same reason.
|
|
514
|
+
* Rebuilding there would sync its open state twice for one edit.
|
|
515
|
+
*/
|
|
516
|
+
rebuildAdapter() {
|
|
517
|
+
this.adapter = limebbRuleConditionEditor_entry.createRuleConditionTreeAdapter({
|
|
518
|
+
metadata: this.metadataById,
|
|
519
|
+
titles: this.primitiveTitles,
|
|
520
|
+
translate: conditionTreeTranslate.createTranslator(this.platform),
|
|
521
|
+
issues: () => this.issuesByNode,
|
|
522
|
+
created: () => this.created,
|
|
523
|
+
});
|
|
524
|
+
}
|
|
525
|
+
/**
|
|
526
|
+
* Wrap any non-group `value` in a top-level `all`, so that a lone
|
|
527
|
+
* condition has a group to grow in. An unset value stays unset: the
|
|
528
|
+
* tree draws the group a first condition will land in, and
|
|
529
|
+
* `emitNormalization` never pushes that placeholder back to the
|
|
530
|
+
* caller, so "no rule yet" stays distinguishable from "the author
|
|
531
|
+
* cleared this".
|
|
871
532
|
*
|
|
872
533
|
* An unconditional mode is the exception: its sentinel is left
|
|
873
534
|
* exactly as it came in, because wrapping it would rewrite the
|
|
874
535
|
* shape the mode is read back from.
|
|
875
536
|
*
|
|
876
|
-
* Memoized so
|
|
877
|
-
*
|
|
878
|
-
* depends on it.
|
|
537
|
+
* Memoized, so that the tree is handed the same rule on every
|
|
538
|
+
* render and redraws only when the rule itself changes.
|
|
879
539
|
*/
|
|
880
540
|
get normalizedValue() {
|
|
541
|
+
if (!this.value) {
|
|
542
|
+
return undefined;
|
|
543
|
+
}
|
|
881
544
|
const mode = this.currentMode;
|
|
882
545
|
if (this.normalizedCache !== null &&
|
|
883
546
|
this.normalizedCache.source === this.value &&
|
|
@@ -944,35 +607,16 @@ const EMPTY_CONTEXT = Object.freeze({
|
|
|
944
607
|
id: null,
|
|
945
608
|
});
|
|
946
609
|
function normalize(value, mode) {
|
|
947
|
-
if (!value) {
|
|
948
|
-
return { type: 'all', rules: [] };
|
|
949
|
-
}
|
|
950
610
|
// Neither sentinel is a group, and wrapping one would rewrite the
|
|
951
611
|
// very shape the mode is read back from.
|
|
952
612
|
if (mode === 'always' || mode === 'never') {
|
|
953
613
|
return value;
|
|
954
614
|
}
|
|
955
|
-
if (
|
|
615
|
+
if (limebbRuleConditionEditor_entry.groupOf(value)) {
|
|
956
616
|
return value;
|
|
957
617
|
}
|
|
958
618
|
return { type: 'all', rules: [value] };
|
|
959
619
|
}
|
|
960
|
-
/**
|
|
961
|
-
* Treat an empty root `all`/`any` as "no rule". Mapping that back to
|
|
962
|
-
* `undefined` on emit keeps the form contract a clean
|
|
963
|
-
* `Rule | undefined` — callers don't have to inspect rule shape to
|
|
964
|
-
* tell "user cleared this" from "user has a real rule". A negated
|
|
965
|
-
* empty group (`not(all())` etc.) is left intact — vacuous either
|
|
966
|
-
* direction, but the user explicitly opted into the wrapper, so we
|
|
967
|
-
* don't second-guess.
|
|
968
|
-
* @param rule
|
|
969
|
-
*/
|
|
970
|
-
function collapseEmptyRoot(rule) {
|
|
971
|
-
if (rule.type !== 'all' && rule.type !== 'any') {
|
|
972
|
-
return rule;
|
|
973
|
-
}
|
|
974
|
-
return rule.rules.length === 0 ? undefined : rule;
|
|
975
|
-
}
|
|
976
620
|
RuleEditor.style = ruleEditorCss();
|
|
977
621
|
|
|
978
622
|
exports.limebb_rule_editor = RuleEditor;
|