@limetech/lime-crm-building-blocks 1.124.0 → 1.126.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.
- package/CHANGELOG.md +19 -0
- package/dist/cjs/color-palettes-BWuwMtwv.js +334 -0
- package/dist/cjs/index.cjs.js +5 -0
- package/dist/cjs/lime-crm-building-blocks.cjs.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 +4 -4
- package/dist/cjs/limebb-chat-list.cjs.entry.js +1 -1
- package/dist/cjs/limebb-color-palette-picker.cjs.entry.js +85 -0
- package/dist/cjs/limebb-color-palette-swatches.cjs.entry.js +21 -0
- package/dist/cjs/limebb-component-config.cjs.entry.js +2 -14
- package/dist/cjs/limebb-composer-toolbar.cjs.entry.js +3 -3
- package/dist/cjs/limebb-currency-picker.cjs.entry.js +1 -1
- package/dist/cjs/limebb-dashboard-widget.cjs.entry.js +1 -1
- package/dist/cjs/limebb-date-picker.cjs.entry.js +1 -1
- 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 +2 -2
- package/dist/cjs/limebb-document-picker.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 +1 -1
- package/dist/cjs/limebb-feed.cjs.entry.js +1 -1
- package/dist/cjs/limebb-icon-picker.cjs.entry.js +1 -1
- package/dist/cjs/limebb-info-tile-format.cjs.entry.js +1 -1
- package/dist/cjs/limebb-info-tile.cjs.entry.js +1 -1
- package/dist/cjs/limebb-kanban-group.cjs.entry.js +1 -1
- package/dist/cjs/limebb-kanban-item.cjs.entry.js +1 -1
- package/dist/cjs/limebb-lime-query-builder.cjs.entry.js +1 -1
- package/dist/cjs/limebb-lime-query-filter-builder_3.cjs.entry.js +2 -2
- package/dist/cjs/limebb-lime-query-filter-comparison_2.cjs.entry.js +1 -1
- package/dist/cjs/limebb-lime-query-filter-group_3.cjs.entry.js +3 -3
- package/dist/cjs/limebb-lime-query-order-by-item.cjs.entry.js +2 -2
- package/dist/cjs/limebb-lime-query-response-format-builder.cjs.entry.js +1 -1
- package/dist/cjs/limebb-lime-query-response-format-editor_2.cjs.entry.js +1 -1
- package/dist/cjs/limebb-live-docs-info.cjs.entry.js +2 -2
- package/dist/cjs/limebb-locale-picker.cjs.entry.js +1 -1
- package/dist/cjs/limebb-mention-group-counter.cjs.entry.js +2 -2
- package/dist/cjs/limebb-navigation-button_2.cjs.entry.js +2 -2
- package/dist/cjs/limebb-notification-item.cjs.entry.js +1 -1
- package/dist/cjs/limebb-percentage-visualizer.cjs.entry.js +2 -2
- package/dist/cjs/limebb-rule-chip-popover.cjs.entry.js +59 -0
- package/dist/cjs/limebb-rule-editor.cjs.entry.js +646 -0
- package/dist/cjs/limebb-rule-gate.cjs.entry.js +5 -1
- package/dist/cjs/limebb-text-editor.cjs.entry.js +1 -1
- package/dist/cjs/limebb-trend-indicator.cjs.entry.js +1 -1
- package/dist/cjs/loader.cjs.js +1 -1
- package/dist/cjs/web-component-template-BWCutZB6.js +18 -0
- package/dist/collection/collection-manifest.json +4 -0
- package/dist/collection/components/alert-dialog/alert-dialog.js +1 -1
- package/dist/collection/components/browser/browser.js +2 -2
- package/dist/collection/components/chat-list/chat-icon-list/chat-icon-list.js +1 -1
- package/dist/collection/components/chat-list/chat-item/chat-item.js +2 -2
- package/dist/collection/components/chat-list/chat-list.js +1 -1
- package/dist/collection/components/chat-list/typing-indicator/typing-indicator.js +1 -1
- package/dist/collection/components/color-palette-picker/color-palette-picker.css +5 -0
- package/dist/collection/components/color-palette-picker/color-palette-picker.js +295 -0
- package/dist/collection/components/color-palette-picker/color-palette-swatches/color-palette-swatches.css +28 -0
- package/dist/collection/components/color-palette-picker/color-palette-swatches/color-palette-swatches.js +61 -0
- package/dist/collection/components/composer-toolbar/composer-toolbar.js +3 -3
- package/dist/collection/components/currency-picker/currency-picker.js +1 -1
- package/dist/collection/components/dashboard-widget/dashboard-widget.js +1 -1
- package/dist/collection/components/date-picker/date-picker.js +1 -1
- package/dist/collection/components/date-range/date-range.js +1 -1
- package/dist/collection/components/document-chips/document-chips.js +1 -1
- package/dist/collection/components/document-picker/document-item/document-item.js +2 -2
- package/dist/collection/components/document-picker/document-picker.js +1 -1
- package/dist/collection/components/feed/feed-item/feed-timeline-item.js +1 -1
- package/dist/collection/components/feed/feed-item-thumbnail-file-info/feed-item-thumbnail-file-info.js +1 -1
- package/dist/collection/components/feed/feed.js +1 -1
- package/dist/collection/components/icon-picker/icon-picker.js +1 -1
- package/dist/collection/components/info-tile/format/config/info-tile-format.js +1 -1
- package/dist/collection/components/info-tile/info-tile.js +1 -1
- package/dist/collection/components/kanban/kanban-group/kanban-group.js +1 -1
- package/dist/collection/components/kanban/kanban-item/kanban-item.js +1 -1
- package/dist/collection/components/lime-query-builder/expressions/lime-query-filter-comparison.js +1 -1
- package/dist/collection/components/lime-query-builder/expressions/lime-query-filter-group.js +2 -2
- package/dist/collection/components/lime-query-builder/expressions/lime-query-filter-not.js +1 -1
- package/dist/collection/components/lime-query-builder/lime-query-builder.js +1 -1
- package/dist/collection/components/lime-query-builder/lime-query-response-format-builder.js +1 -1
- package/dist/collection/components/lime-query-builder/limetype-field/limetype-field.js +1 -1
- package/dist/collection/components/lime-query-builder/order-by/order-by-editor.js +1 -1
- package/dist/collection/components/lime-query-builder/order-by/order-by-item.js +2 -2
- package/dist/collection/components/lime-query-builder/response-format/response-format-item.js +1 -1
- package/dist/collection/components/limeobject/file-viewer/live-docs-info.js +2 -2
- package/dist/collection/components/locale-picker/locale-picker.js +1 -1
- package/dist/collection/components/notification-list/notification-item/notification-item.js +1 -1
- package/dist/collection/components/percentage-visualizer/percentage-visualizer.js +2 -2
- package/dist/collection/components/rule-editor/chip-picker-view.js +141 -0
- package/dist/collection/components/rule-editor/group-node-view.js +79 -0
- package/dist/collection/components/rule-editor/rule-chip-popover/rule-chip-popover.css +36 -0
- package/dist/collection/components/rule-editor/rule-chip-popover/rule-chip-popover.js +301 -0
- package/dist/collection/components/rule-editor/rule-editor-views.js +43 -0
- package/dist/collection/components/rule-editor/rule-editor.css +96 -0
- package/dist/collection/components/rule-editor/rule-editor.js +457 -0
- package/dist/collection/components/rule-editor/rule-operations.js +132 -0
- package/dist/collection/components/rule-editor/view-helpers.js +70 -0
- package/dist/collection/components/rule-gate/rule-gate.js +9 -4
- package/dist/collection/components/summary-popover/summary-popover.js +2 -2
- package/dist/collection/components/text-editor/mention-group-counter.js +2 -2
- package/dist/collection/components/text-editor/text-editor.js +1 -1
- package/dist/collection/components/trend-indicator/trend-indicator.js +1 -1
- package/dist/collection/index.js +1 -0
- package/dist/collection/util/color-palettes.js +329 -0
- package/dist/components/chat-icon-list.js +1 -1
- package/dist/components/chat-item.js +1 -1
- package/dist/components/color-palettes.js +1 -0
- package/dist/components/currency-picker.js +1 -1
- package/dist/components/date-picker.js +1 -1
- package/dist/components/document-item.js +1 -1
- package/dist/components/feed-item-thumbnail-file-info.js +1 -1
- package/dist/components/feed-timeline-item.js +1 -1
- package/dist/components/index.js +1 -1
- package/dist/components/kanban-group.js +1 -1
- package/dist/components/kanban-item.js +1 -1
- package/dist/components/lime-query-filter-comparison.js +1 -1
- package/dist/components/lime-query-filter-expression.js +1 -1
- package/dist/components/limebb-alert-dialog.js +1 -1
- package/dist/components/limebb-browser.js +1 -1
- package/dist/components/limebb-chat-list.js +1 -1
- package/dist/components/limebb-color-palette-picker.d.ts +11 -0
- package/dist/components/limebb-color-palette-picker.js +1 -0
- package/dist/components/limebb-color-palette-swatches.d.ts +11 -0
- package/dist/components/limebb-color-palette-swatches.js +1 -0
- package/dist/components/limebb-component-config.js +1 -1
- package/dist/components/limebb-composer-toolbar.js +1 -1
- package/dist/components/limebb-dashboard-widget.js +1 -1
- package/dist/components/limebb-date-range.js +1 -1
- package/dist/components/limebb-document-chips.js +1 -1
- package/dist/components/limebb-document-picker.js +1 -1
- package/dist/components/limebb-feed.js +1 -1
- package/dist/components/limebb-icon-picker.js +1 -1
- package/dist/components/limebb-info-tile-format.js +1 -1
- package/dist/components/limebb-info-tile.js +1 -1
- package/dist/components/limebb-lime-query-builder.js +1 -1
- package/dist/components/limebb-lime-query-response-format-builder.js +1 -1
- package/dist/components/limebb-locale-picker.js +1 -1
- package/dist/components/limebb-mention-group-counter.js +1 -1
- package/dist/components/limebb-rule-chip-popover.d.ts +11 -0
- package/dist/components/limebb-rule-chip-popover.js +1 -0
- package/dist/components/limebb-rule-editor.d.ts +11 -0
- package/dist/components/limebb-rule-editor.js +1 -0
- package/dist/components/limebb-rule-gate.js +1 -1
- package/dist/components/limebb-text-editor.js +1 -1
- package/dist/components/limebb-trend-indicator.js +1 -1
- package/dist/components/limetype-field.js +1 -1
- package/dist/components/live-docs-info.js +1 -1
- package/dist/components/notification-item.js +1 -1
- package/dist/components/order-by-editor.js +1 -1
- package/dist/components/order-by-item.js +1 -1
- package/dist/components/percentage-visualizer.js +1 -1
- package/dist/components/response-format-item.js +1 -1
- package/dist/components/rule-chip-popover.js +1 -0
- package/dist/components/summary-popover.js +1 -1
- package/dist/components/typing-indicator.js +1 -1
- package/dist/components/web-component-template.js +1 -0
- package/dist/esm/color-palettes-1N3bZuHj.js +331 -0
- package/dist/esm/index.js +1 -0
- package/dist/esm/lime-crm-building-blocks.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 +4 -4
- package/dist/esm/limebb-chat-list.entry.js +1 -1
- package/dist/esm/limebb-color-palette-picker.entry.js +83 -0
- package/dist/esm/limebb-color-palette-swatches.entry.js +19 -0
- package/dist/esm/limebb-component-config.entry.js +2 -14
- package/dist/esm/limebb-composer-toolbar.entry.js +3 -3
- package/dist/esm/limebb-currency-picker.entry.js +1 -1
- package/dist/esm/limebb-dashboard-widget.entry.js +1 -1
- package/dist/esm/limebb-date-picker.entry.js +1 -1
- 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 +2 -2
- package/dist/esm/limebb-document-picker.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 +1 -1
- package/dist/esm/limebb-feed.entry.js +1 -1
- package/dist/esm/limebb-icon-picker.entry.js +1 -1
- package/dist/esm/limebb-info-tile-format.entry.js +1 -1
- package/dist/esm/limebb-info-tile.entry.js +1 -1
- package/dist/esm/limebb-kanban-group.entry.js +1 -1
- package/dist/esm/limebb-kanban-item.entry.js +1 -1
- package/dist/esm/limebb-lime-query-builder.entry.js +1 -1
- package/dist/esm/limebb-lime-query-filter-builder_3.entry.js +2 -2
- package/dist/esm/limebb-lime-query-filter-comparison_2.entry.js +1 -1
- package/dist/esm/limebb-lime-query-filter-group_3.entry.js +3 -3
- package/dist/esm/limebb-lime-query-order-by-item.entry.js +2 -2
- package/dist/esm/limebb-lime-query-response-format-builder.entry.js +1 -1
- package/dist/esm/limebb-lime-query-response-format-editor_2.entry.js +1 -1
- package/dist/esm/limebb-live-docs-info.entry.js +2 -2
- package/dist/esm/limebb-locale-picker.entry.js +1 -1
- package/dist/esm/limebb-mention-group-counter.entry.js +2 -2
- package/dist/esm/limebb-navigation-button_2.entry.js +2 -2
- package/dist/esm/limebb-notification-item.entry.js +1 -1
- package/dist/esm/limebb-percentage-visualizer.entry.js +2 -2
- package/dist/esm/limebb-rule-chip-popover.entry.js +57 -0
- package/dist/esm/limebb-rule-editor.entry.js +644 -0
- package/dist/esm/limebb-rule-gate.entry.js +5 -1
- package/dist/esm/limebb-text-editor.entry.js +1 -1
- package/dist/esm/limebb-trend-indicator.entry.js +1 -1
- package/dist/esm/loader.js +1 -1
- package/dist/esm/web-component-template-6zRYia86.js +16 -0
- 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-e8425a2c.entry.js → p-057e1638.entry.js} +1 -1
- package/dist/lime-crm-building-blocks/{p-0f2d1ea7.entry.js → p-0c572fe9.entry.js} +1 -1
- package/dist/lime-crm-building-blocks/{p-f0a5076c.entry.js → p-11494f30.entry.js} +1 -1
- package/dist/lime-crm-building-blocks/p-1747221f.entry.js +1 -0
- package/dist/lime-crm-building-blocks/p-1831e571.entry.js +1 -0
- package/dist/lime-crm-building-blocks/{p-8f8108c1.entry.js → p-184ae23d.entry.js} +1 -1
- package/dist/lime-crm-building-blocks/p-1N3bZuHj.js +1 -0
- package/dist/lime-crm-building-blocks/{p-4f042496.entry.js → p-20206710.entry.js} +1 -1
- package/dist/lime-crm-building-blocks/{p-529dbe46.entry.js → p-24fc049c.entry.js} +1 -1
- package/dist/lime-crm-building-blocks/{p-e3e2852a.entry.js → p-277b6ad4.entry.js} +1 -1
- package/dist/lime-crm-building-blocks/{p-e4ff2906.entry.js → p-2cb31064.entry.js} +1 -1
- package/dist/lime-crm-building-blocks/{p-2caf01c8.entry.js → p-3313e357.entry.js} +1 -1
- package/dist/lime-crm-building-blocks/{p-ad27bd5d.entry.js → p-3781a766.entry.js} +1 -1
- package/dist/lime-crm-building-blocks/{p-85caaf36.entry.js → p-43a7facd.entry.js} +1 -1
- package/dist/lime-crm-building-blocks/{p-5f97c392.entry.js → p-6cceabf1.entry.js} +1 -1
- package/dist/lime-crm-building-blocks/{p-67326d92.entry.js → p-6d3a9ed3.entry.js} +1 -1
- package/dist/lime-crm-building-blocks/{p-09c63bce.entry.js → p-71a6f624.entry.js} +1 -1
- package/dist/lime-crm-building-blocks/{p-25c4e389.entry.js → p-731820f0.entry.js} +1 -1
- package/dist/lime-crm-building-blocks/p-74455a30.entry.js +1 -0
- package/dist/lime-crm-building-blocks/p-7922726c.entry.js +1 -0
- package/dist/lime-crm-building-blocks/{p-9214b92e.entry.js → p-7a125570.entry.js} +1 -1
- package/dist/lime-crm-building-blocks/{p-dd07a1ac.entry.js → p-7d51a34c.entry.js} +1 -1
- package/dist/lime-crm-building-blocks/{p-287780c1.entry.js → p-7fee7ef3.entry.js} +1 -1
- package/dist/lime-crm-building-blocks/{p-27798ace.entry.js → p-8084e825.entry.js} +1 -1
- package/dist/lime-crm-building-blocks/p-861ac606.entry.js +1 -0
- package/dist/lime-crm-building-blocks/{p-fcedbc77.entry.js → p-8d3fa274.entry.js} +1 -1
- package/dist/lime-crm-building-blocks/{p-b0567904.entry.js → p-9f7992b0.entry.js} +1 -1
- package/dist/lime-crm-building-blocks/p-C_tMNOSt.js +1 -0
- package/dist/lime-crm-building-blocks/{p-bb5d40b1.entry.js → p-abcb1e49.entry.js} +1 -1
- package/dist/lime-crm-building-blocks/{p-f7114acb.entry.js → p-b1a8d1a0.entry.js} +1 -1
- package/dist/lime-crm-building-blocks/p-b8d9ff68.entry.js +1 -0
- package/dist/lime-crm-building-blocks/{p-52bddb06.entry.js → p-bec4231f.entry.js} +1 -1
- package/dist/lime-crm-building-blocks/{p-5fa5e7f4.entry.js → p-c139ab98.entry.js} +1 -1
- package/dist/lime-crm-building-blocks/{p-774cd93c.entry.js → p-c4f41ec4.entry.js} +1 -1
- package/dist/lime-crm-building-blocks/{p-4b275818.entry.js → p-c609b5ec.entry.js} +1 -1
- package/dist/lime-crm-building-blocks/{p-6a05192a.entry.js → p-c6a913af.entry.js} +1 -1
- package/dist/lime-crm-building-blocks/p-dd38e0ba.entry.js +1 -0
- package/dist/lime-crm-building-blocks/{p-6cb2d9dd.entry.js → p-de6f4670.entry.js} +1 -1
- package/dist/lime-crm-building-blocks/{p-0cbe7498.entry.js → p-e6ed33ff.entry.js} +1 -1
- package/dist/lime-crm-building-blocks/p-e717bdff.entry.js +1 -0
- package/dist/lime-crm-building-blocks/{p-9d56503d.entry.js → p-ef62c7d8.entry.js} +1 -1
- package/dist/lime-crm-building-blocks/{p-9a42ae42.entry.js → p-f0a567f3.entry.js} +1 -1
- package/dist/lime-crm-building-blocks/{p-b07b3ae3.entry.js → p-fd6dcfe3.entry.js} +1 -1
- package/dist/types/components/color-palette-picker/color-palette-picker.d.ts +89 -0
- package/dist/types/components/color-palette-picker/color-palette-swatches/color-palette-swatches.d.ts +23 -0
- package/dist/types/components/rule-editor/chip-picker-view.d.ts +27 -0
- package/dist/types/components/rule-editor/group-node-view.d.ts +11 -0
- package/dist/types/components/rule-editor/rule-chip-popover/rule-chip-popover.d.ts +31 -0
- package/dist/types/components/rule-editor/rule-editor-views.d.ts +51 -0
- package/dist/types/components/rule-editor/rule-editor.d.ts +118 -0
- package/dist/types/components/rule-editor/rule-operations.d.ts +62 -0
- package/dist/types/components/rule-editor/view-helpers.d.ts +40 -0
- package/dist/types/components/rule-gate/rule-gate.d.ts +5 -2
- package/dist/types/components.d.ts +588 -6
- package/dist/types/index.d.ts +1 -0
- package/dist/types/util/color-palettes.d.ts +67 -0
- package/package.json +4 -4
- package/dist/lime-crm-building-blocks/p-51ab9d60.entry.js +0 -1
- package/dist/lime-crm-building-blocks/p-628ce56b.entry.js +0 -1
- package/dist/lime-crm-building-blocks/p-6318fd46.entry.js +0 -1
- package/dist/lime-crm-building-blocks/p-c6caa3f9.entry.js +0 -1
|
@@ -0,0 +1,457 @@
|
|
|
1
|
+
import { h, } from "@stencil/core";
|
|
2
|
+
import { PlatformServiceName, } from "@limetech/lime-web-components";
|
|
3
|
+
import { deleteNode, replaceNode, updateArgs, } from "./rule-operations";
|
|
4
|
+
import { extractGroup, RuleNodeView, } from "./rule-editor-views";
|
|
5
|
+
import { createPrimitiveOptions } from "./view-helpers";
|
|
6
|
+
/**
|
|
7
|
+
* Tree editor for {@link Rule}.
|
|
8
|
+
*
|
|
9
|
+
* Renders a `Rule` value as a tree of nodes. Lets an author pick
|
|
10
|
+
* primitive refs in `all` / `any` groups, toggle negation, delete
|
|
11
|
+
* nodes, and edit per-primitive args via the editor declared on each
|
|
12
|
+
* primitive's metadata.
|
|
13
|
+
*
|
|
14
|
+
* The component is value-in / value-out. Pass `value` and listen for
|
|
15
|
+
* `change`; persistence is the caller's concern.
|
|
16
|
+
*
|
|
17
|
+
* Pass `availableSubjects` to forward the list of subject slots the
|
|
18
|
+
* caller knows will be available where the rule runs. The component
|
|
19
|
+
* forwards it to `RuleRegistry.validate` so `missing-slot` diagnostics
|
|
20
|
+
* surface inline on the offending nodes.
|
|
21
|
+
*
|
|
22
|
+
* @exampleComponent limebb-example-rule-editor
|
|
23
|
+
*
|
|
24
|
+
* @alpha
|
|
25
|
+
* @private
|
|
26
|
+
*/
|
|
27
|
+
export class RuleEditor {
|
|
28
|
+
constructor() {
|
|
29
|
+
this.issues = [];
|
|
30
|
+
this.openChipPath = null;
|
|
31
|
+
this.metadataById = new Map();
|
|
32
|
+
this.primitiveOptions = [];
|
|
33
|
+
this.normalizedCache = null;
|
|
34
|
+
this.handleDelete = (path) => {
|
|
35
|
+
this.openChipPath = null;
|
|
36
|
+
this.emitIfChanged(deleteNode(this.normalizedValue, path));
|
|
37
|
+
};
|
|
38
|
+
this.handleUpdateArgs = (path, args) => {
|
|
39
|
+
this.emitIfChanged(updateArgs(this.normalizedValue, path, args));
|
|
40
|
+
};
|
|
41
|
+
this.handleReplaceNode = (path, replacement) => {
|
|
42
|
+
this.emitIfChanged(replaceNode(this.normalizedValue, path, replacement));
|
|
43
|
+
};
|
|
44
|
+
this.handleChipInteract = (path) => {
|
|
45
|
+
this.openChipPath = path;
|
|
46
|
+
};
|
|
47
|
+
this.handlePopoverClose = () => {
|
|
48
|
+
this.openChipPath = null;
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
componentWillLoad() {
|
|
52
|
+
this.indexMetadata();
|
|
53
|
+
this.runValidation();
|
|
54
|
+
}
|
|
55
|
+
componentDidLoad() {
|
|
56
|
+
this.emitNormalization();
|
|
57
|
+
}
|
|
58
|
+
onValueChange() {
|
|
59
|
+
if (this.emitNormalization()) {
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
this.runValidation();
|
|
63
|
+
}
|
|
64
|
+
onAvailableSubjectsChange() {
|
|
65
|
+
this.runValidation();
|
|
66
|
+
}
|
|
67
|
+
render() {
|
|
68
|
+
const containerClasses = {
|
|
69
|
+
'rule-editor': true,
|
|
70
|
+
'rule-editor--disabled': this.disabled,
|
|
71
|
+
};
|
|
72
|
+
return (h("div", { key: 'd179f399433b3c80aa09e52baa19713eef7c1921', class: containerClasses }, this.renderLabel(), h(RuleNodeView, { key: '14cac42e37f52f0a32390a1f374f014b60e31dde', node: this.normalizedValue, path: [], ctx: this.createRenderContext() }), this.renderHelperText()));
|
|
73
|
+
}
|
|
74
|
+
renderLabel() {
|
|
75
|
+
if (!this.label) {
|
|
76
|
+
return null;
|
|
77
|
+
}
|
|
78
|
+
return h("div", { class: "rule-editor__label" }, this.label);
|
|
79
|
+
}
|
|
80
|
+
renderHelperText() {
|
|
81
|
+
if (!this.helperText) {
|
|
82
|
+
return null;
|
|
83
|
+
}
|
|
84
|
+
return h("div", { class: "rule-editor__helper-text" }, this.helperText);
|
|
85
|
+
}
|
|
86
|
+
createRenderContext() {
|
|
87
|
+
return {
|
|
88
|
+
issues: this.issues,
|
|
89
|
+
metadataById: this.metadataById,
|
|
90
|
+
primitiveOptions: this.primitiveOptions,
|
|
91
|
+
isMutable: !this.readonly && !this.disabled,
|
|
92
|
+
readonly: this.readonly,
|
|
93
|
+
disabled: this.disabled,
|
|
94
|
+
platform: this.platform,
|
|
95
|
+
context: this.context,
|
|
96
|
+
translator: this.platform.get(PlatformServiceName.Translate),
|
|
97
|
+
openChipPath: this.openChipPath,
|
|
98
|
+
onDelete: this.handleDelete,
|
|
99
|
+
onUpdateArgs: this.handleUpdateArgs,
|
|
100
|
+
onReplaceNode: this.handleReplaceNode,
|
|
101
|
+
onChipInteract: this.handleChipInteract,
|
|
102
|
+
onPopoverClose: this.handlePopoverClose,
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
indexMetadata() {
|
|
106
|
+
var _a, _b, _c;
|
|
107
|
+
const metadata = (_c = (_b = (_a = this.ruleRegistry).listMetadata) === null || _b === void 0 ? void 0 : _b.call(_a)) !== null && _c !== void 0 ? _c : [];
|
|
108
|
+
this.metadataById = new Map(metadata.map((item) => [item.id, item]));
|
|
109
|
+
this.primitiveOptions = createPrimitiveOptions(this.metadataById);
|
|
110
|
+
}
|
|
111
|
+
runValidation() {
|
|
112
|
+
if (!this.value) {
|
|
113
|
+
this.issues = [];
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
const result = this.ruleRegistry.validate(this.normalizedValue, this.availableSubjects);
|
|
117
|
+
this.issues = result.ok ? [] : result.issues;
|
|
118
|
+
}
|
|
119
|
+
emitIfChanged(next) {
|
|
120
|
+
if (next === this.normalizedValue) {
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
this.change.emit(collapseEmptyRoot(next));
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Wrap any non-group `value` in a top-level `all` so the editor
|
|
127
|
+
* always has a group to render against. When `value` is unset,
|
|
128
|
+
* returns a fresh empty `all`-group as a render-only placeholder —
|
|
129
|
+
* `emitNormalization` will *not* push that placeholder back to the
|
|
130
|
+
* caller, so an unset value stays unset until the user edits.
|
|
131
|
+
*
|
|
132
|
+
* Memoized so callers that read this several times in one handler
|
|
133
|
+
* see the same reference — the identity check in `emitIfChanged`
|
|
134
|
+
* depends on it.
|
|
135
|
+
*/
|
|
136
|
+
get normalizedValue() {
|
|
137
|
+
if (this.normalizedCache !== null &&
|
|
138
|
+
this.normalizedCache.source === this.value) {
|
|
139
|
+
return this.normalizedCache.normalized;
|
|
140
|
+
}
|
|
141
|
+
const normalized = normalize(this.value);
|
|
142
|
+
this.normalizedCache = { source: this.value, normalized };
|
|
143
|
+
return normalized;
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* If `value` wasn't already a group, emit the normalized form so
|
|
147
|
+
* the caller's stored state catches up. Skipped when `value` is
|
|
148
|
+
* unset — we render a placeholder group locally but don't push it
|
|
149
|
+
* back to the caller, so callers can't tell "no rule yet" apart
|
|
150
|
+
* from "user cleared a rule" by inspecting the emitted shape.
|
|
151
|
+
* Returns `true` when an emit happened so callers can short-circuit.
|
|
152
|
+
*/
|
|
153
|
+
emitNormalization() {
|
|
154
|
+
if (!this.value) {
|
|
155
|
+
return false;
|
|
156
|
+
}
|
|
157
|
+
const normalized = this.normalizedValue;
|
|
158
|
+
if (normalized === this.value) {
|
|
159
|
+
return false;
|
|
160
|
+
}
|
|
161
|
+
this.change.emit(normalized);
|
|
162
|
+
return true;
|
|
163
|
+
}
|
|
164
|
+
get ruleRegistry() {
|
|
165
|
+
return this.platform.get(PlatformServiceName.RuleRegistry);
|
|
166
|
+
}
|
|
167
|
+
static get is() { return "limebb-rule-editor"; }
|
|
168
|
+
static get encapsulation() { return "shadow"; }
|
|
169
|
+
static get originalStyleUrls() {
|
|
170
|
+
return {
|
|
171
|
+
"$": ["rule-editor.scss"]
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
static get styleUrls() {
|
|
175
|
+
return {
|
|
176
|
+
"$": ["rule-editor.css"]
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
static get properties() {
|
|
180
|
+
return {
|
|
181
|
+
"platform": {
|
|
182
|
+
"type": "unknown",
|
|
183
|
+
"mutable": false,
|
|
184
|
+
"complexType": {
|
|
185
|
+
"original": "LimeWebComponentPlatform",
|
|
186
|
+
"resolved": "LimeWebComponentPlatform",
|
|
187
|
+
"references": {
|
|
188
|
+
"LimeWebComponentPlatform": {
|
|
189
|
+
"location": "import",
|
|
190
|
+
"path": "@limetech/lime-web-components",
|
|
191
|
+
"id": "node_modules::LimeWebComponentPlatform",
|
|
192
|
+
"referenceLocation": "LimeWebComponentPlatform"
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
},
|
|
196
|
+
"required": false,
|
|
197
|
+
"optional": false,
|
|
198
|
+
"docs": {
|
|
199
|
+
"tags": [],
|
|
200
|
+
"text": "Reference to the platform service container.\n\nUse this to access all platform services like repositories, HTTP client,\ncommand bus, navigator, and more. The platform instance is shared across\nall components in the same application context."
|
|
201
|
+
},
|
|
202
|
+
"getter": false,
|
|
203
|
+
"setter": false
|
|
204
|
+
},
|
|
205
|
+
"context": {
|
|
206
|
+
"type": "unknown",
|
|
207
|
+
"mutable": false,
|
|
208
|
+
"complexType": {
|
|
209
|
+
"original": "LimeWebComponentContext",
|
|
210
|
+
"resolved": "LimeWebComponentContext",
|
|
211
|
+
"references": {
|
|
212
|
+
"LimeWebComponentContext": {
|
|
213
|
+
"location": "import",
|
|
214
|
+
"path": "@limetech/lime-web-components",
|
|
215
|
+
"id": "node_modules::LimeWebComponentContext",
|
|
216
|
+
"referenceLocation": "LimeWebComponentContext"
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
},
|
|
220
|
+
"required": false,
|
|
221
|
+
"optional": false,
|
|
222
|
+
"docs": {
|
|
223
|
+
"tags": [],
|
|
224
|
+
"text": "The context describing where this component is running.\n\nThe context provides information about the current limetype and record ID\n(if viewing/editing a specific record). Components can use this to load\nrelevant data and understand their operating environment."
|
|
225
|
+
},
|
|
226
|
+
"getter": false,
|
|
227
|
+
"setter": false
|
|
228
|
+
},
|
|
229
|
+
"value": {
|
|
230
|
+
"type": "unknown",
|
|
231
|
+
"mutable": false,
|
|
232
|
+
"complexType": {
|
|
233
|
+
"original": "Rule | undefined",
|
|
234
|
+
"resolved": "RuleAll | RuleAny | RuleNot | RuleRef | undefined",
|
|
235
|
+
"references": {
|
|
236
|
+
"Rule": {
|
|
237
|
+
"location": "import",
|
|
238
|
+
"path": "@limetech/lime-web-components",
|
|
239
|
+
"id": "node_modules::Rule",
|
|
240
|
+
"referenceLocation": "Rule"
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
},
|
|
244
|
+
"required": false,
|
|
245
|
+
"optional": false,
|
|
246
|
+
"docs": {
|
|
247
|
+
"tags": [{
|
|
248
|
+
"name": "inheritdoc",
|
|
249
|
+
"text": undefined
|
|
250
|
+
}],
|
|
251
|
+
"text": "The value of the current property"
|
|
252
|
+
},
|
|
253
|
+
"getter": false,
|
|
254
|
+
"setter": false
|
|
255
|
+
},
|
|
256
|
+
"availableSubjects": {
|
|
257
|
+
"type": "unknown",
|
|
258
|
+
"mutable": false,
|
|
259
|
+
"complexType": {
|
|
260
|
+
"original": "(keyof SubjectRegistry)[]",
|
|
261
|
+
"resolved": "(keyof SubjectRegistry)[] | undefined",
|
|
262
|
+
"references": {
|
|
263
|
+
"SubjectRegistry": {
|
|
264
|
+
"location": "import",
|
|
265
|
+
"path": "@limetech/lime-web-components",
|
|
266
|
+
"id": "node_modules::SubjectRegistry",
|
|
267
|
+
"referenceLocation": "SubjectRegistry"
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
},
|
|
271
|
+
"required": false,
|
|
272
|
+
"optional": true,
|
|
273
|
+
"docs": {
|
|
274
|
+
"tags": [],
|
|
275
|
+
"text": "Subject slots the caller knows will be available where the rule\nruns. Forwarded to the rule registry's `validate` method so\n`missing-slot` issues surface inline. Leave unset when the\nevaluation context is not known (typical for editors that target\nthe saved-rule library)."
|
|
276
|
+
},
|
|
277
|
+
"getter": false,
|
|
278
|
+
"setter": false
|
|
279
|
+
},
|
|
280
|
+
"required": {
|
|
281
|
+
"type": "boolean",
|
|
282
|
+
"mutable": false,
|
|
283
|
+
"complexType": {
|
|
284
|
+
"original": "boolean",
|
|
285
|
+
"resolved": "boolean",
|
|
286
|
+
"references": {}
|
|
287
|
+
},
|
|
288
|
+
"required": false,
|
|
289
|
+
"optional": false,
|
|
290
|
+
"docs": {
|
|
291
|
+
"tags": [{
|
|
292
|
+
"name": "inheritdoc",
|
|
293
|
+
"text": undefined
|
|
294
|
+
}],
|
|
295
|
+
"text": "Whether or not the current property is required"
|
|
296
|
+
},
|
|
297
|
+
"getter": false,
|
|
298
|
+
"setter": false,
|
|
299
|
+
"reflect": true,
|
|
300
|
+
"attribute": "required"
|
|
301
|
+
},
|
|
302
|
+
"readonly": {
|
|
303
|
+
"type": "boolean",
|
|
304
|
+
"mutable": false,
|
|
305
|
+
"complexType": {
|
|
306
|
+
"original": "boolean",
|
|
307
|
+
"resolved": "boolean",
|
|
308
|
+
"references": {}
|
|
309
|
+
},
|
|
310
|
+
"required": false,
|
|
311
|
+
"optional": false,
|
|
312
|
+
"docs": {
|
|
313
|
+
"tags": [{
|
|
314
|
+
"name": "inheritdoc",
|
|
315
|
+
"text": undefined
|
|
316
|
+
}],
|
|
317
|
+
"text": "Whether or not the current property is readonly\nThe mutation UI (delete and negate toggles, add-group button) is\nhidden when set. The args editor for each ref is still rendered,\nwith `readonly` forwarded to it."
|
|
318
|
+
},
|
|
319
|
+
"getter": false,
|
|
320
|
+
"setter": false,
|
|
321
|
+
"reflect": true,
|
|
322
|
+
"attribute": "readonly"
|
|
323
|
+
},
|
|
324
|
+
"disabled": {
|
|
325
|
+
"type": "boolean",
|
|
326
|
+
"mutable": false,
|
|
327
|
+
"complexType": {
|
|
328
|
+
"original": "boolean",
|
|
329
|
+
"resolved": "boolean",
|
|
330
|
+
"references": {}
|
|
331
|
+
},
|
|
332
|
+
"required": false,
|
|
333
|
+
"optional": false,
|
|
334
|
+
"docs": {
|
|
335
|
+
"tags": [{
|
|
336
|
+
"name": "inheritdoc",
|
|
337
|
+
"text": undefined
|
|
338
|
+
}],
|
|
339
|
+
"text": "Whether or not the current property is disabled\nThe mutation UI is hidden when set. The args editor is rendered\nwith `disabled` forwarded to it."
|
|
340
|
+
},
|
|
341
|
+
"getter": false,
|
|
342
|
+
"setter": false,
|
|
343
|
+
"reflect": true,
|
|
344
|
+
"attribute": "disabled"
|
|
345
|
+
},
|
|
346
|
+
"label": {
|
|
347
|
+
"type": "string",
|
|
348
|
+
"mutable": false,
|
|
349
|
+
"complexType": {
|
|
350
|
+
"original": "string",
|
|
351
|
+
"resolved": "string",
|
|
352
|
+
"references": {}
|
|
353
|
+
},
|
|
354
|
+
"required": false,
|
|
355
|
+
"optional": false,
|
|
356
|
+
"docs": {
|
|
357
|
+
"tags": [{
|
|
358
|
+
"name": "inheritdoc",
|
|
359
|
+
"text": undefined
|
|
360
|
+
}],
|
|
361
|
+
"text": "The label of the current property"
|
|
362
|
+
},
|
|
363
|
+
"getter": false,
|
|
364
|
+
"setter": false,
|
|
365
|
+
"reflect": true,
|
|
366
|
+
"attribute": "label"
|
|
367
|
+
},
|
|
368
|
+
"helperText": {
|
|
369
|
+
"type": "string",
|
|
370
|
+
"mutable": false,
|
|
371
|
+
"complexType": {
|
|
372
|
+
"original": "string",
|
|
373
|
+
"resolved": "string",
|
|
374
|
+
"references": {}
|
|
375
|
+
},
|
|
376
|
+
"required": false,
|
|
377
|
+
"optional": false,
|
|
378
|
+
"docs": {
|
|
379
|
+
"tags": [{
|
|
380
|
+
"name": "inheritdoc",
|
|
381
|
+
"text": undefined
|
|
382
|
+
}],
|
|
383
|
+
"text": "The helper text for the current property"
|
|
384
|
+
},
|
|
385
|
+
"getter": false,
|
|
386
|
+
"setter": false,
|
|
387
|
+
"reflect": false,
|
|
388
|
+
"attribute": "helper-text"
|
|
389
|
+
}
|
|
390
|
+
};
|
|
391
|
+
}
|
|
392
|
+
static get states() {
|
|
393
|
+
return {
|
|
394
|
+
"issues": {},
|
|
395
|
+
"openChipPath": {}
|
|
396
|
+
};
|
|
397
|
+
}
|
|
398
|
+
static get events() {
|
|
399
|
+
return [{
|
|
400
|
+
"method": "change",
|
|
401
|
+
"name": "change",
|
|
402
|
+
"bubbles": true,
|
|
403
|
+
"cancelable": true,
|
|
404
|
+
"composed": true,
|
|
405
|
+
"docs": {
|
|
406
|
+
"tags": [],
|
|
407
|
+
"text": "Emitted when the rule tree is mutated. Detail is the new rule, or\n`undefined` when the user has cleared the editor to an empty root\ngroup \u2014 callers can persist `undefined` as \"no rule\" without\nhaving to inspect the rule shape themselves."
|
|
408
|
+
},
|
|
409
|
+
"complexType": {
|
|
410
|
+
"original": "Rule | undefined",
|
|
411
|
+
"resolved": "RuleAll | RuleAny | RuleNot | RuleRef | undefined",
|
|
412
|
+
"references": {
|
|
413
|
+
"Rule": {
|
|
414
|
+
"location": "import",
|
|
415
|
+
"path": "@limetech/lime-web-components",
|
|
416
|
+
"id": "node_modules::Rule",
|
|
417
|
+
"referenceLocation": "Rule"
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
}];
|
|
422
|
+
}
|
|
423
|
+
static get watchers() {
|
|
424
|
+
return [{
|
|
425
|
+
"propName": "value",
|
|
426
|
+
"methodName": "onValueChange"
|
|
427
|
+
}, {
|
|
428
|
+
"propName": "availableSubjects",
|
|
429
|
+
"methodName": "onAvailableSubjectsChange"
|
|
430
|
+
}];
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
function normalize(value) {
|
|
434
|
+
if (!value) {
|
|
435
|
+
return { type: 'all', rules: [] };
|
|
436
|
+
}
|
|
437
|
+
if (extractGroup(value)) {
|
|
438
|
+
return value;
|
|
439
|
+
}
|
|
440
|
+
return { type: 'all', rules: [value] };
|
|
441
|
+
}
|
|
442
|
+
/**
|
|
443
|
+
* Treat an empty root `all`/`any` as "no rule". Mapping that back to
|
|
444
|
+
* `undefined` on emit keeps the form contract a clean
|
|
445
|
+
* `Rule | undefined` — callers don't have to inspect rule shape to
|
|
446
|
+
* tell "user cleared this" from "user has a real rule". A negated
|
|
447
|
+
* empty group (`not(all())` etc.) is left intact — vacuous either
|
|
448
|
+
* direction, but the user explicitly opted into the wrapper, so we
|
|
449
|
+
* don't second-guess.
|
|
450
|
+
* @param rule
|
|
451
|
+
*/
|
|
452
|
+
function collapseEmptyRoot(rule) {
|
|
453
|
+
if (rule.type !== 'all' && rule.type !== 'any') {
|
|
454
|
+
return rule;
|
|
455
|
+
}
|
|
456
|
+
return rule.rules.length === 0 ? undefined : rule;
|
|
457
|
+
}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Remove the node at `path`.
|
|
3
|
+
*
|
|
4
|
+
* Removing the root yields an empty `all`-group so the tree always has
|
|
5
|
+
* something to render. Returns `rule` unchanged when `path` does not
|
|
6
|
+
* address a removable node.
|
|
7
|
+
* @param rule
|
|
8
|
+
* @param path
|
|
9
|
+
*/
|
|
10
|
+
export function deleteNode(rule, path) {
|
|
11
|
+
if (path.length === 0) {
|
|
12
|
+
return { type: 'all', rules: [] };
|
|
13
|
+
}
|
|
14
|
+
const parentPath = path.slice(0, -1);
|
|
15
|
+
const key = path.at(-1);
|
|
16
|
+
const parent = getNode(rule, parentPath);
|
|
17
|
+
if ((parent.type === 'all' || parent.type === 'any') &&
|
|
18
|
+
typeof key === 'number') {
|
|
19
|
+
const rules = [...parent.rules];
|
|
20
|
+
rules.splice(key, 1);
|
|
21
|
+
return replaceAt(rule, parentPath, Object.assign(Object.assign({}, parent), { rules }));
|
|
22
|
+
}
|
|
23
|
+
if (parent.type === 'not' && key === 'rule') {
|
|
24
|
+
return replaceAt(rule, parentPath, { type: 'all', rules: [] });
|
|
25
|
+
}
|
|
26
|
+
return rule;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Replace the `args` of a `ref` node. Returns `rule` unchanged when
|
|
30
|
+
* `path` does not resolve to a `ref`.
|
|
31
|
+
* @param rule
|
|
32
|
+
* @param path
|
|
33
|
+
* @param args
|
|
34
|
+
*/
|
|
35
|
+
export function updateArgs(rule, path, args) {
|
|
36
|
+
const node = getNode(rule, path);
|
|
37
|
+
if (node.type !== 'ref') {
|
|
38
|
+
return rule;
|
|
39
|
+
}
|
|
40
|
+
return replaceAt(rule, path, Object.assign(Object.assign({}, node), { args }));
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Replace the node at `path` with `replacement`, returning a new rule
|
|
44
|
+
* tree. Used by callers that need to apply a non-atomic change as a
|
|
45
|
+
* single emit (e.g. updating a group's whole `rules` array at once).
|
|
46
|
+
* @param rule
|
|
47
|
+
* @param path
|
|
48
|
+
* @param replacement
|
|
49
|
+
*/
|
|
50
|
+
export function replaceNode(rule, path, replacement) {
|
|
51
|
+
return replaceAt(rule, path, replacement);
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Wrap `group` in a `not` when `isNegated`, otherwise return it
|
|
55
|
+
* unchanged. Used when re-emitting a group whose negation flag should
|
|
56
|
+
* be preserved.
|
|
57
|
+
* @param group
|
|
58
|
+
* @param isNegated
|
|
59
|
+
*/
|
|
60
|
+
export function wrapNegated(group, isNegated) {
|
|
61
|
+
return isNegated ? { type: 'not', rule: group } : group;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Append `child` to a group's `rules`, returning a new group. The
|
|
65
|
+
* input is not mutated.
|
|
66
|
+
* @param group
|
|
67
|
+
* @param child
|
|
68
|
+
*/
|
|
69
|
+
export function appendChild(group, child) {
|
|
70
|
+
return Object.assign(Object.assign({}, group), { rules: [...group.rules, child] });
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Structural equality on two paths.
|
|
74
|
+
* @param a
|
|
75
|
+
* @param b
|
|
76
|
+
*/
|
|
77
|
+
export function pathsEqual(a, b) {
|
|
78
|
+
if (a.length !== b.length) {
|
|
79
|
+
return false;
|
|
80
|
+
}
|
|
81
|
+
return a.every((value, index) => value === b[index]);
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Filter validation issues to those whose `path` matches `path`.
|
|
85
|
+
* @param issues
|
|
86
|
+
* @param path
|
|
87
|
+
*/
|
|
88
|
+
export function issuesAt(issues, path) {
|
|
89
|
+
return issues.filter((issue) => pathsEqual(issue.path, path));
|
|
90
|
+
}
|
|
91
|
+
function getNode(rule, path) {
|
|
92
|
+
let node = rule;
|
|
93
|
+
for (const key of path) {
|
|
94
|
+
node = stepIntoNode(node, key);
|
|
95
|
+
}
|
|
96
|
+
return node;
|
|
97
|
+
}
|
|
98
|
+
function replaceAt(root, path, replacement) {
|
|
99
|
+
if (path.length === 0) {
|
|
100
|
+
return replacement;
|
|
101
|
+
}
|
|
102
|
+
const [head, ...tail] = path;
|
|
103
|
+
if (root.type === 'not' && head === 'rule') {
|
|
104
|
+
return Object.assign(Object.assign({}, root), { rule: replaceAt(root.rule, tail, replacement) });
|
|
105
|
+
}
|
|
106
|
+
if ((root.type === 'all' || root.type === 'any') && head === 'rules') {
|
|
107
|
+
if (tail.length === 0) {
|
|
108
|
+
return replacement;
|
|
109
|
+
}
|
|
110
|
+
const [index, ...rest] = tail;
|
|
111
|
+
if (typeof index !== 'number') {
|
|
112
|
+
return root;
|
|
113
|
+
}
|
|
114
|
+
const rules = [...root.rules];
|
|
115
|
+
rules[index] = replaceAt(rules[index], rest, replacement);
|
|
116
|
+
return Object.assign(Object.assign({}, root), { rules });
|
|
117
|
+
}
|
|
118
|
+
return root;
|
|
119
|
+
}
|
|
120
|
+
function stepIntoNode(node, key) {
|
|
121
|
+
if (node.type === 'not' && key === 'rule') {
|
|
122
|
+
return node.rule;
|
|
123
|
+
}
|
|
124
|
+
if ((node.type === 'all' || node.type === 'any') && key === 'rules') {
|
|
125
|
+
return node;
|
|
126
|
+
}
|
|
127
|
+
if ((node.type === 'all' || node.type === 'any') &&
|
|
128
|
+
typeof key === 'number') {
|
|
129
|
+
return node.rules[key];
|
|
130
|
+
}
|
|
131
|
+
return node;
|
|
132
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
const UNKNOWN_ICON = {
|
|
2
|
+
name: 'question',
|
|
3
|
+
color: 'rgb(var(--color-glaucous-light))',
|
|
4
|
+
};
|
|
5
|
+
/**
|
|
6
|
+
* Class map for a rule-node container. Adds the type modifier and an
|
|
7
|
+
* `invalid` flag when validation issues attach to this node.
|
|
8
|
+
* @param type
|
|
9
|
+
* @param issues
|
|
10
|
+
*/
|
|
11
|
+
export function nodeClasses(type, issues) {
|
|
12
|
+
return {
|
|
13
|
+
'rule-node': true,
|
|
14
|
+
[`rule-node--${type}`]: true,
|
|
15
|
+
'rule-node--invalid': issues.length > 0,
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Build the searchable list shown by the primitive pickers. Cached on
|
|
20
|
+
* the render context so it isn't recomputed per node.
|
|
21
|
+
* @param metadataById
|
|
22
|
+
*/
|
|
23
|
+
export function createPrimitiveOptions(metadataById) {
|
|
24
|
+
return [...metadataById.values()]
|
|
25
|
+
.map((meta) => {
|
|
26
|
+
var _a, _b;
|
|
27
|
+
return ({
|
|
28
|
+
value: meta.id,
|
|
29
|
+
text: (_a = meta.title) !== null && _a !== void 0 ? _a : meta.id,
|
|
30
|
+
secondaryText: (_b = meta.description) !== null && _b !== void 0 ? _b : '',
|
|
31
|
+
icon: meta.icon,
|
|
32
|
+
});
|
|
33
|
+
})
|
|
34
|
+
.sort((a, b) => a.text.localeCompare(b.text));
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Find the picker item for `id`, falling back to a placeholder marked
|
|
38
|
+
* with the unknown-primitive icon when the id isn't in the registry.
|
|
39
|
+
* @param allItems
|
|
40
|
+
* @param id
|
|
41
|
+
*/
|
|
42
|
+
export function resolveItem(allItems, id) {
|
|
43
|
+
var _a;
|
|
44
|
+
return ((_a = allItems.find((item) => item.value === id)) !== null && _a !== void 0 ? _a : {
|
|
45
|
+
value: id,
|
|
46
|
+
text: id,
|
|
47
|
+
icon: UNKNOWN_ICON,
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Build a picker `searcher` bound to a fixed item list. Both the ref
|
|
52
|
+
* picker and the chip picker want exactly this — wrapping
|
|
53
|
+
* {@link searchItems} in a promise — and deserve to share it.
|
|
54
|
+
* @param items
|
|
55
|
+
*/
|
|
56
|
+
export function createSearcher(items) {
|
|
57
|
+
return (query) => Promise.resolve(searchItems(items, query));
|
|
58
|
+
}
|
|
59
|
+
function searchItems(allItems, query) {
|
|
60
|
+
if (!query) {
|
|
61
|
+
return allItems;
|
|
62
|
+
}
|
|
63
|
+
const parts = query.toLocaleLowerCase().split(/\s+/);
|
|
64
|
+
return allItems.filter((item) => parts.every((part) => {
|
|
65
|
+
var _a, _b;
|
|
66
|
+
return item.text.toLocaleLowerCase().includes(part) ||
|
|
67
|
+
((_a = item.secondaryText) === null || _a === void 0 ? void 0 : _a.toLocaleLowerCase().includes(part)) ||
|
|
68
|
+
((_b = item.value) === null || _b === void 0 ? void 0 : _b.toLocaleLowerCase().includes(part));
|
|
69
|
+
}));
|
|
70
|
+
}
|