@openremote/or-rules 1.8.0-snapshot.20250725074716 → 1.8.0-snapshot.20250725120001

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. package/README.md +30 -30
  2. package/custom-elements.json +13 -13
  3. package/dist/umd/index.bundle.js +4744 -4744
  4. package/dist/umd/index.bundle.js.map +1 -1
  5. package/lib/flow-viewer/components/confirmation-dialog.js +61 -24
  6. package/lib/flow-viewer/components/connection-container.js +35 -1
  7. package/lib/flow-viewer/components/connection-line.js +117 -28
  8. package/lib/flow-viewer/components/context-menu.js +140 -45
  9. package/lib/flow-viewer/components/editor-workspace.js +282 -20
  10. package/lib/flow-viewer/components/flow-editor.js +160 -47
  11. package/lib/flow-viewer/components/flow-node-socket.js +146 -31
  12. package/lib/flow-viewer/components/flow-node.js +192 -29
  13. package/lib/flow-viewer/components/internal-picker.js +271 -54
  14. package/lib/flow-viewer/components/node-menu-item.js +132 -32
  15. package/lib/flow-viewer/components/node-panel.js +104 -60
  16. package/lib/flow-viewer/components/notification-dialog.js +55 -23
  17. package/lib/flow-viewer/components/popup-modal.js +113 -54
  18. package/lib/flow-viewer/components/rule-browser.js +119 -30
  19. package/lib/flow-viewer/components/selectable-element.js +71 -1
  20. package/lib/flow-viewer/components/selection-box.js +119 -15
  21. package/lib/flow-viewer/components/top-bar.js +116 -49
  22. package/lib/flow-viewer/components/workspace-contextmenu-options.js +128 -5
  23. package/lib/flow-viewer/components/writable-dropdown.js +51 -5
  24. package/lib/flow-viewer/converters/node-converter.js +10 -1
  25. package/lib/flow-viewer/flow-viewer.js +19 -1
  26. package/lib/flow-viewer/models/camera.js +2 -1
  27. package/lib/flow-viewer/models/context-menu-button.js +2 -1
  28. package/lib/flow-viewer/models/light-node-collection.js +2 -1
  29. package/lib/flow-viewer/models/status.js +8 -1
  30. package/lib/flow-viewer/node-structure/copy.machine.js +34 -1
  31. package/lib/flow-viewer/node-structure/identity.assigner.js +10 -1
  32. package/lib/flow-viewer/node-structure/identity.dom.link.js +4 -1
  33. package/lib/flow-viewer/node-structure/index.js +5 -1
  34. package/lib/flow-viewer/node-structure/socket.type.matcher.js +50 -1
  35. package/lib/flow-viewer/node-structure/utils.js +109 -1
  36. package/lib/flow-viewer/services/copy-paste-manager.js +59 -1
  37. package/lib/flow-viewer/services/exporter.js +67 -1
  38. package/lib/flow-viewer/services/input.js +80 -1
  39. package/lib/flow-viewer/services/integration.js +27 -1
  40. package/lib/flow-viewer/services/modal.js +29 -8
  41. package/lib/flow-viewer/services/project.js +222 -1
  42. package/lib/flow-viewer/services/shortcuts.js +63 -1
  43. package/lib/flow-viewer/styles/editor-workspace-style.js +55 -53
  44. package/lib/flow-viewer/styles/flow-node-style.js +95 -93
  45. package/lib/flow-viewer/styles/picker-styles.js +31 -29
  46. package/lib/flow-viewer/utils.js +49 -1
  47. package/lib/index.js +953 -56
  48. package/lib/json-viewer/forms/or-rule-form-alarm.js +91 -18
  49. package/lib/json-viewer/forms/or-rule-form-email-message.js +51 -12
  50. package/lib/json-viewer/forms/or-rule-form-localized.js +269 -43
  51. package/lib/json-viewer/forms/or-rule-form-push-notification.js +152 -63
  52. package/lib/json-viewer/forms/or-rule-form-webhook.js +296 -101
  53. package/lib/json-viewer/modals/or-rule-alarm-modal.js +173 -17
  54. package/lib/json-viewer/modals/or-rule-notification-modal.js +196 -11
  55. package/lib/json-viewer/modals/or-rule-radial-modal.js +142 -17
  56. package/lib/json-viewer/modals/or-rule-webhook-modal.js +78 -8
  57. package/lib/json-viewer/or-rule-action-alarm.js +97 -5
  58. package/lib/json-viewer/or-rule-action-attribute.js +235 -33
  59. package/lib/json-viewer/or-rule-action-notification.js +465 -56
  60. package/lib/json-viewer/or-rule-action-webhook.js +49 -18
  61. package/lib/json-viewer/or-rule-asset-query.js +849 -126
  62. package/lib/json-viewer/or-rule-condition.js +216 -29
  63. package/lib/json-viewer/or-rule-json-viewer.js +393 -34
  64. package/lib/json-viewer/or-rule-then-otherwise.js +609 -113
  65. package/lib/json-viewer/or-rule-trigger-query.js +227 -57
  66. package/lib/json-viewer/or-rule-when.js +343 -126
  67. package/lib/or-rule-group-viewer.js +106 -12
  68. package/lib/or-rule-text-viewer.js +133 -22
  69. package/lib/or-rule-tree.js +601 -57
  70. package/lib/or-rule-validity.js +373 -62
  71. package/lib/or-rule-viewer.js +361 -81
  72. package/lib/style.js +89 -64
  73. package/package.json +11 -11
@@ -1,34 +1,393 @@
1
- var __decorate=this&&this.__decorate||function(e,t,s,r){var i,n=arguments.length,o=n<3?t:null===r?r=Object.getOwnPropertyDescriptor(t,s):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)o=Reflect.decorate(e,t,s,r);else for(var a=e.length-1;a>=0;a--)(i=e[a])&&(o=(n<3?i(o):n>3?i(t,s,o):i(t,s))||o);return n>3&&o&&Object.defineProperty(t,s,o),o},__awaiter=this&&this.__awaiter||function(e,t,s,r){return new(s||(s=Promise))(function(i,n){function o(e){try{u(r.next(e))}catch(e){n(e)}}function a(e){try{u(r.throw(e))}catch(e){n(e)}}function u(e){var t;e.done?i(e.value):((t=e.value)instanceof s?t:new s(function(e){e(t)})).then(o,a)}u((r=r.apply(e,t||[])).next())})};import{css as e,html as t,LitElement as s}from"lit";import{customElement as r,property as i,state as n}from"lit/decorators.js";import{getAssetInfos as o,getAssetsByType as a,getAssetTypeFromQuery as u,OrRulesRuleChangedEvent as l,OrRulesRuleUnsupportedEvent as d}from"../index";import{Util as h}from"@openremote/core";import"./or-rule-when";import"./or-rule-then-otherwise";import"@openremote/or-components/or-panel";import c from"i18next";import{translate as p}from"@openremote/or-translate";export class OrRulesJsonRuleChangedEvent extends CustomEvent{constructor(){super(OrRulesJsonRuleChangedEvent.NAME,{bubbles:!0,composed:!0})}}function getTypeAndTagsFromGroup(e){if(!e)return[];let t=[];if(e.items)for(let s of e.items){let e=u(s.assets);e&&t.push([e,s.tag])}if(e.groups)for(let s of e.groups)t=t.concat(getTypeAndTagsFromGroup(s));return t}OrRulesJsonRuleChangedEvent.NAME="or-rules-json-rule-changed";export function getTargetTypeMap(e){return e.when?getTypeAndTagsFromGroup(e.when):[]}let style=e`
2
- :host {
3
- display: flex;
4
- width: calc(100% - 20px);
5
- padding: 0px 10px;
6
- margin-top: -10px;
7
- }
8
-
9
- :host > * {
10
- flex: 1;
11
- }
12
-
13
- @media screen and (max-width: 1400px) {
14
- :host > * {
15
- flex-grow: 0;
16
- }
17
-
18
- :host {
19
- flex-direction: column;
20
- }
21
- }
22
- `,OrRuleJsonViewer=class extends p(c)(s){static get styles(){return style}constructor(){super(),this._loadedAssets=new Map,this._unsupported=!1,this._activeAssetPromises=new Map,this.addEventListener(OrRulesJsonRuleChangedEvent.NAME,this._onJsonRuleChanged)}connectedCallback(){super.connectedCallback(),this._unsupported&&this.dispatchEvent(new d)}disconnectedCallback(){return this.removeEventListener(OrRulesJsonRuleChangedEvent.NAME,this._onJsonRuleChanged),super.disconnectedCallback()}set ruleset(e){if(this._ruleset!==e)if(this._unsupported=!1,this._ruleset=e,e.rules)try{let t=JSON.parse(e.rules);if(!t.rules||t.rules.length>1)return void(this.isConnected?this.dispatchEvent(new d):this._unsupported=!0);this._rule=t.rules[0],this.requestUpdate()}catch(e){console.error("Invalid JSON rules, failed to parse: "+e),this.isConnected?this.dispatchEvent(new d):this._unsupported=!0}else this.config&&this.config.json&&this.config.json.rule?this._rule=JSON.parse(JSON.stringify(this.config.json.rule)):this._rule={recurrence:{mins:0}}}updated(e){e.has("config")&&(this.loadAssetDescriptors(!1),this.loadAssetDescriptors(!0))}render(){if(!this._rule)return t``;let e=getTargetTypeMap(this._rule);return t`
23
- <div class="section-container">
24
- <or-rule-when .rule="${this._rule}" .config="${this.config}" .assetInfos="${this._whenAssetInfos}" ?readonly="${this.readonly}"
25
- .assetProvider="${e=>__awaiter(this,void 0,void 0,function*(){return this.loadAssets(e)})}"
26
- ></or-rule-when>
27
- </div>
28
-
29
- <div class="section-container">
30
- <or-rule-then-otherwise .rule="${this._rule}" .config="${this.config}" .targetTypeMap="${e}" .assetInfos="${this._actionAssetInfos}" ?readonly="${this.readonly}"
31
- .assetProvider="${e=>__awaiter(this,void 0,void 0,function*(){return this.loadAssets(e)})}"
32
- ></or-rule-then-otherwise>
33
- </div>
34
- `}loadAssets(e){return __awaiter(this,void 0,void 0,function*(){if(this._activeAssetPromises.has(e))return(yield this._activeAssetPromises.get(e)).assets;{let t=a(e,"realm"==this._ruleset.type?this._ruleset.realm:void 0,this._loadedAssets);this._activeAssetPromises.set(e,t);let s=yield t;return this._activeAssetPromises.delete(e),s.assets}})}loadAssetDescriptors(e){o(this.config,e).then(t=>{e?this._actionAssetInfos=[...t]:this._whenAssetInfos=[...t],this.requestUpdate()})}beforeSave(){if(!this._rule)return;this._rule.name=this._ruleset.name;let e={rules:[this._rule]};this._ruleset.rules=JSON.stringify(e)}validate(){let e=this._rule;return!!e&&!!e.when&&!!e.then&&0!==e.then.length&&!!this._validateConditionGroup(e.when)&&!!this._validateRuleActions(e,e.then)}_onJsonRuleChanged(){let e=this.validate();this.dispatchEvent(new l(e))}_validateConditionGroup(e){if((!e.items||0===e.items.length)&&(!e.groups||0===e.groups.length))return!1;if(e.items){for(let t of e.items)if(!t.assets&&!t.cron&&!t.sun||t.cron&&!h.cronStringToISOString(t.cron,!0)||t.sun&&(!t.sun.position||!t.sun.location)||t.assets&&!this._validateAssetQuery(t.assets,!0,!1))return!1}if(e.groups){for(let t of e.groups)if(!this._validateConditionGroup(t))return!1}return!0}_validateRuleActions(e,t){var s;if(!t)return!0;for(let r of t)switch(r.action){case"wait":if(!r.millis)return!1;break;case"write-attribute":if(!r.attributeName||!this._validateAssetTarget(e,r.target))return!1;break;case"notification":case"alarm":break;case"webhook":if(!(null==(s=r.webhook)?void 0:s.url)||!r.webhook.httpMethod)return!1;break;case"update-attribute":if(!r.attributeName||!r.updateAction||!this._validateAssetTarget(e,r.target))return!1;break;default:return!1}return!0}_validateAssetTarget(e,t){return!t||(t.assets?this._validateAssetQuery(t.assets,!1,!1):t.matchedAssets?this._validateAssetQuery(t.matchedAssets,!1,!0):!(t.conditionAssets&&0>getTypeAndTagsFromGroup(e.when).findIndex(e=>t.conditionAssets===e[1])))}_validateAssetQuery(e,t,s){if(!e.types||0===e.types.length)return!1;if(t){if(!e.attributes||!e.attributes.items||0===e.attributes.items.length)return!1}else if(!s&&(!e.ids||0===e.ids.length))return!1;if(e.attributes&&e.attributes.items){for(let t of e.attributes.items)if(!t.name||!t.name.match||!t.name.value||!t.timestampOlderThan&&(!t.value||!this._validateValuePredicate(t.value)))return!1}return!0}_validateValuePredicate(e){switch(e.predicateType){case"string":return void 0!==e.match&&void 0!==e.value;case"boolean":return void 0!==e.value;case"datetime":case"number":return void 0!==e.operator&&void 0!==e.value&&("BETWEEN"!==e.operator||void 0!==e.rangeValue);case"radial":return void 0!==e.radius&&void 0!==e.lat&&void 0!==e.lng;case"rect":return void 0!==e.lngMax&&void 0!==e.latMax&&void 0!==e.lngMin&&void 0!==e.latMin;case"array":return e.index&&!e.value||e.value||e.lengthEquals||e.lengthLessThan||e.lengthGreaterThan;case"value-empty":return!0;default:return!1}}};__decorate([i({attribute:!1})],OrRuleJsonViewer.prototype,"readonly",void 0),__decorate([i({attribute:!1})],OrRuleJsonViewer.prototype,"config",void 0),__decorate([i({attribute:!1})],OrRuleJsonViewer.prototype,"_ruleset",void 0),__decorate([n()],OrRuleJsonViewer.prototype,"_loadedAssets",void 0),OrRuleJsonViewer=__decorate([r("or-rule-json-viewer")],OrRuleJsonViewer);export{OrRuleJsonViewer};
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
8
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
9
+ return new (P || (P = Promise))(function (resolve, reject) {
10
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
11
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
12
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
13
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
14
+ });
15
+ };
16
+ import { css, html, LitElement } from "lit";
17
+ import { customElement, property, state } from "lit/decorators.js";
18
+ import { getAssetInfos, getAssetsByType, getAssetTypeFromQuery, OrRulesRuleChangedEvent, OrRulesRuleUnsupportedEvent } from "../index";
19
+ import { Util } from "@openremote/core";
20
+ import "./or-rule-when";
21
+ import "./or-rule-then-otherwise";
22
+ import "@openremote/or-components/or-panel";
23
+ import i18next from "i18next";
24
+ import { translate } from "@openremote/or-translate";
25
+ export class OrRulesJsonRuleChangedEvent extends CustomEvent {
26
+ constructor() {
27
+ super(OrRulesJsonRuleChangedEvent.NAME, {
28
+ bubbles: true,
29
+ composed: true
30
+ });
31
+ }
32
+ }
33
+ OrRulesJsonRuleChangedEvent.NAME = "or-rules-json-rule-changed";
34
+ function getTypeAndTagsFromGroup(group) {
35
+ if (!group) {
36
+ return [];
37
+ }
38
+ let typesAndTags = [];
39
+ if (group.items) {
40
+ for (const condition of group.items) {
41
+ const type = getAssetTypeFromQuery(condition.assets);
42
+ if (type) {
43
+ typesAndTags.push([type, condition.tag]);
44
+ }
45
+ }
46
+ }
47
+ if (group.groups) {
48
+ for (const condition of group.groups) {
49
+ typesAndTags = typesAndTags.concat(getTypeAndTagsFromGroup(condition));
50
+ }
51
+ }
52
+ return typesAndTags;
53
+ }
54
+ export function getTargetTypeMap(rule) {
55
+ if (!rule.when) {
56
+ return [];
57
+ }
58
+ return getTypeAndTagsFromGroup(rule.when);
59
+ }
60
+ const style = css `
61
+ :host {
62
+ display: flex;
63
+ width: calc(100% - 20px);
64
+ padding: 0px 10px;
65
+ margin-top: -10px;
66
+ }
67
+
68
+ :host > * {
69
+ flex: 1;
70
+ }
71
+
72
+ @media screen and (max-width: 1400px) {
73
+ :host > * {
74
+ flex-grow: 0;
75
+ }
76
+
77
+ :host {
78
+ flex-direction: column;
79
+ }
80
+ }
81
+ `;
82
+ let OrRuleJsonViewer = class OrRuleJsonViewer extends translate(i18next)(LitElement) {
83
+ static get styles() {
84
+ return style;
85
+ }
86
+ constructor() {
87
+ super();
88
+ this._loadedAssets = new Map();
89
+ this._unsupported = false;
90
+ this._activeAssetPromises = new Map();
91
+ this.addEventListener(OrRulesJsonRuleChangedEvent.NAME, this._onJsonRuleChanged);
92
+ }
93
+ connectedCallback() {
94
+ super.connectedCallback();
95
+ if (this._unsupported) {
96
+ this.dispatchEvent(new OrRulesRuleUnsupportedEvent());
97
+ }
98
+ }
99
+ disconnectedCallback() {
100
+ this.removeEventListener(OrRulesJsonRuleChangedEvent.NAME, this._onJsonRuleChanged);
101
+ return super.disconnectedCallback();
102
+ }
103
+ set ruleset(ruleset) {
104
+ if (this._ruleset === ruleset) {
105
+ return;
106
+ }
107
+ this._unsupported = false;
108
+ this._ruleset = ruleset;
109
+ if (!ruleset.rules) {
110
+ // New ruleset so start a new rule
111
+ if (this.config && this.config.json && this.config.json.rule) {
112
+ this._rule = JSON.parse(JSON.stringify(this.config.json.rule));
113
+ }
114
+ else {
115
+ this._rule = {
116
+ recurrence: {
117
+ mins: 0 // always
118
+ }
119
+ };
120
+ }
121
+ }
122
+ else {
123
+ try {
124
+ const rules = JSON.parse(ruleset.rules);
125
+ if (!rules.rules || rules.rules.length > 1) {
126
+ if (this.isConnected) {
127
+ this.dispatchEvent(new OrRulesRuleUnsupportedEvent());
128
+ }
129
+ else {
130
+ this._unsupported = true;
131
+ }
132
+ return;
133
+ }
134
+ this._rule = rules.rules[0];
135
+ this.requestUpdate();
136
+ }
137
+ catch (e) {
138
+ console.error("Invalid JSON rules, failed to parse: " + e);
139
+ if (this.isConnected) {
140
+ this.dispatchEvent(new OrRulesRuleUnsupportedEvent());
141
+ }
142
+ else {
143
+ this._unsupported = true;
144
+ }
145
+ }
146
+ }
147
+ }
148
+ updated(changedProperties) {
149
+ if (changedProperties.has('config')) {
150
+ this.loadAssetDescriptors(false);
151
+ this.loadAssetDescriptors(true);
152
+ }
153
+ }
154
+ render() {
155
+ if (!this._rule) {
156
+ return html ``;
157
+ }
158
+ const targetTypeMap = getTargetTypeMap(this._rule);
159
+ return html `
160
+ <div class="section-container">
161
+ <or-rule-when .rule="${this._rule}" .config="${this.config}" .assetInfos="${this._whenAssetInfos}" ?readonly="${this.readonly}"
162
+ .assetProvider="${(type) => __awaiter(this, void 0, void 0, function* () { return this.loadAssets(type); })}"
163
+ ></or-rule-when>
164
+ </div>
165
+
166
+ <div class="section-container">
167
+ <or-rule-then-otherwise .rule="${this._rule}" .config="${this.config}" .targetTypeMap="${targetTypeMap}" .assetInfos="${this._actionAssetInfos}" ?readonly="${this.readonly}"
168
+ .assetProvider="${(type) => __awaiter(this, void 0, void 0, function* () { return this.loadAssets(type); })}"
169
+ ></or-rule-then-otherwise>
170
+ </div>
171
+ `;
172
+ }
173
+ // loadAssets function that also tracks what promises/fetches are active.
174
+ // If so, await for those to finish to prevent multiple API requests.
175
+ // Also using caching with the _loadedAssets object.
176
+ loadAssets(type) {
177
+ return __awaiter(this, void 0, void 0, function* () {
178
+ if (this._activeAssetPromises.has(type)) {
179
+ const data = yield (this._activeAssetPromises.get(type)); // await for the already existing fetch
180
+ return data.assets;
181
+ }
182
+ else {
183
+ const promise = getAssetsByType(type, (this._ruleset.type == "realm" ? this._ruleset.realm : undefined), this._loadedAssets);
184
+ this._activeAssetPromises.set(type, promise);
185
+ const data = yield promise;
186
+ this._activeAssetPromises.delete(type);
187
+ return data.assets;
188
+ }
189
+ });
190
+ }
191
+ loadAssetDescriptors(useActionConfig) {
192
+ getAssetInfos(this.config, useActionConfig).then(result => {
193
+ if (useActionConfig) {
194
+ this._actionAssetInfos = [...result];
195
+ this.requestUpdate();
196
+ }
197
+ else {
198
+ this._whenAssetInfos = [...result];
199
+ this.requestUpdate();
200
+ }
201
+ });
202
+ }
203
+ beforeSave() {
204
+ if (!this._rule) {
205
+ return;
206
+ }
207
+ this._rule.name = this._ruleset.name;
208
+ const jsonRules = {
209
+ rules: [this._rule]
210
+ };
211
+ this._ruleset.rules = JSON.stringify(jsonRules);
212
+ }
213
+ validate() {
214
+ const rule = this._rule;
215
+ if (!rule) {
216
+ return false;
217
+ }
218
+ if (!rule.when) {
219
+ return false;
220
+ }
221
+ if (!rule.then || rule.then.length === 0) {
222
+ return false;
223
+ }
224
+ if (!this._validateConditionGroup(rule.when)) {
225
+ return false;
226
+ }
227
+ if (!this._validateRuleActions(rule, rule.then)) {
228
+ return false;
229
+ }
230
+ // TODO: Validate other rule sections
231
+ return true;
232
+ }
233
+ _onJsonRuleChanged() {
234
+ const valid = this.validate();
235
+ this.dispatchEvent(new OrRulesRuleChangedEvent(valid));
236
+ }
237
+ _validateConditionGroup(group) {
238
+ if ((!group.items || group.items.length === 0) && (!group.groups || group.groups.length === 0)) {
239
+ return false;
240
+ }
241
+ if (group.items) {
242
+ for (const condition of group.items) {
243
+ if (!condition.assets && !condition.cron && !condition.sun) {
244
+ return false;
245
+ }
246
+ if (condition.cron && !Util.cronStringToISOString(condition.cron, true)) {
247
+ return false;
248
+ }
249
+ if (condition.sun && (!condition.sun.position || !condition.sun.location)) {
250
+ return false;
251
+ }
252
+ if (condition.assets && !this._validateAssetQuery(condition.assets, true, false)) {
253
+ return false;
254
+ }
255
+ }
256
+ }
257
+ if (group.groups) {
258
+ for (const childGroup of group.groups) {
259
+ if (!this._validateConditionGroup(childGroup)) {
260
+ return false;
261
+ }
262
+ }
263
+ }
264
+ return true;
265
+ }
266
+ _validateRuleActions(rule, actions) {
267
+ var _a;
268
+ if (!actions) {
269
+ return true;
270
+ }
271
+ for (const action of actions) {
272
+ switch (action.action) {
273
+ case "wait":
274
+ if (!action.millis) {
275
+ return false;
276
+ }
277
+ break;
278
+ case "write-attribute":
279
+ if (!action.attributeName) {
280
+ return false;
281
+ }
282
+ if (!this._validateAssetTarget(rule, action.target)) {
283
+ return false;
284
+ }
285
+ break;
286
+ case "notification":
287
+ // TODO: validate notification rule action
288
+ break;
289
+ case "alarm":
290
+ // TODO: validate alarm rule action
291
+ break;
292
+ case "webhook":
293
+ if (!((_a = action.webhook) === null || _a === void 0 ? void 0 : _a.url) || !action.webhook.httpMethod) {
294
+ return false;
295
+ }
296
+ break;
297
+ case "update-attribute":
298
+ if (!action.attributeName) {
299
+ return false;
300
+ }
301
+ if (!action.updateAction) {
302
+ return false;
303
+ }
304
+ if (!this._validateAssetTarget(rule, action.target)) {
305
+ return false;
306
+ }
307
+ break;
308
+ default:
309
+ return false;
310
+ }
311
+ }
312
+ return true;
313
+ }
314
+ _validateAssetTarget(rule, target) {
315
+ if (!target) {
316
+ return true;
317
+ }
318
+ if (target.assets) {
319
+ return this._validateAssetQuery(target.assets, false, false);
320
+ }
321
+ if (target.matchedAssets) {
322
+ return this._validateAssetQuery(target.matchedAssets, false, true);
323
+ }
324
+ if (target.conditionAssets && getTypeAndTagsFromGroup(rule.when).findIndex((typeAndTag) => target.conditionAssets === typeAndTag[1]) < 0) {
325
+ return false;
326
+ }
327
+ return true;
328
+ }
329
+ _validateAssetQuery(query, isWhen, isMatchedAssets) {
330
+ if (!query.types || query.types.length === 0) {
331
+ return false;
332
+ }
333
+ if (isWhen) {
334
+ if (!query.attributes || !query.attributes.items || query.attributes.items.length === 0) {
335
+ return false;
336
+ }
337
+ }
338
+ else if (!isMatchedAssets) {
339
+ if (!query.ids || query.ids.length === 0) {
340
+ return false;
341
+ }
342
+ }
343
+ if (query.attributes && query.attributes.items) {
344
+ for (const attribute of query.attributes.items) {
345
+ if (!attribute.name || !attribute.name.match || !attribute.name.value) {
346
+ return false;
347
+ }
348
+ if (!attribute.timestampOlderThan && (!attribute.value || !this._validateValuePredicate(attribute.value))) {
349
+ return false;
350
+ }
351
+ }
352
+ }
353
+ return true;
354
+ }
355
+ _validateValuePredicate(valuePredicate) {
356
+ switch (valuePredicate.predicateType) {
357
+ case "string":
358
+ return valuePredicate.match !== undefined && valuePredicate.value !== undefined;
359
+ case "boolean":
360
+ return valuePredicate.value !== undefined;
361
+ case "datetime":
362
+ case "number":
363
+ return valuePredicate.operator !== undefined && valuePredicate.value !== undefined && (valuePredicate.operator !== "BETWEEN" /* AQO.BETWEEN */ || valuePredicate.rangeValue !== undefined);
364
+ case "radial":
365
+ return valuePredicate.radius !== undefined && valuePredicate.lat !== undefined && valuePredicate.lng !== undefined;
366
+ case "rect":
367
+ return valuePredicate.lngMax !== undefined && valuePredicate.latMax !== undefined && valuePredicate.lngMin !== undefined && valuePredicate.latMin !== undefined;
368
+ case "array":
369
+ return (valuePredicate.index && !valuePredicate.value) || valuePredicate.value || valuePredicate.lengthEquals || valuePredicate.lengthLessThan || valuePredicate.lengthGreaterThan;
370
+ case "value-empty":
371
+ return true;
372
+ default:
373
+ return false;
374
+ }
375
+ }
376
+ };
377
+ __decorate([
378
+ property({ attribute: false })
379
+ ], OrRuleJsonViewer.prototype, "readonly", void 0);
380
+ __decorate([
381
+ property({ attribute: false })
382
+ ], OrRuleJsonViewer.prototype, "config", void 0);
383
+ __decorate([
384
+ property({ attribute: false })
385
+ ], OrRuleJsonViewer.prototype, "_ruleset", void 0);
386
+ __decorate([
387
+ state() // to be exact: Map<AssetType name, Asset[]>
388
+ ], OrRuleJsonViewer.prototype, "_loadedAssets", void 0);
389
+ OrRuleJsonViewer = __decorate([
390
+ customElement("or-rule-json-viewer")
391
+ ], OrRuleJsonViewer);
392
+ export { OrRuleJsonViewer };
393
+ //# sourceMappingURL=or-rule-json-viewer.js.map