@openremote/or-rules 1.8.0-snapshot.20250725120002 → 1.8.0-snapshot.20250728102340

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 +24 -61
  6. package/lib/flow-viewer/components/connection-container.js +1 -35
  7. package/lib/flow-viewer/components/connection-line.js +28 -117
  8. package/lib/flow-viewer/components/context-menu.js +45 -140
  9. package/lib/flow-viewer/components/editor-workspace.js +20 -282
  10. package/lib/flow-viewer/components/flow-editor.js +47 -160
  11. package/lib/flow-viewer/components/flow-node-socket.js +31 -146
  12. package/lib/flow-viewer/components/flow-node.js +29 -192
  13. package/lib/flow-viewer/components/internal-picker.js +54 -271
  14. package/lib/flow-viewer/components/node-menu-item.js +32 -132
  15. package/lib/flow-viewer/components/node-panel.js +60 -104
  16. package/lib/flow-viewer/components/notification-dialog.js +23 -55
  17. package/lib/flow-viewer/components/popup-modal.js +54 -113
  18. package/lib/flow-viewer/components/rule-browser.js +30 -119
  19. package/lib/flow-viewer/components/selectable-element.js +1 -71
  20. package/lib/flow-viewer/components/selection-box.js +15 -119
  21. package/lib/flow-viewer/components/top-bar.js +49 -116
  22. package/lib/flow-viewer/components/workspace-contextmenu-options.js +5 -128
  23. package/lib/flow-viewer/components/writable-dropdown.js +5 -51
  24. package/lib/flow-viewer/converters/node-converter.js +1 -10
  25. package/lib/flow-viewer/flow-viewer.js +1 -19
  26. package/lib/flow-viewer/models/camera.js +1 -2
  27. package/lib/flow-viewer/models/context-menu-button.js +1 -2
  28. package/lib/flow-viewer/models/light-node-collection.js +1 -2
  29. package/lib/flow-viewer/models/status.js +1 -8
  30. package/lib/flow-viewer/node-structure/copy.machine.js +1 -34
  31. package/lib/flow-viewer/node-structure/identity.assigner.js +1 -10
  32. package/lib/flow-viewer/node-structure/identity.dom.link.js +1 -4
  33. package/lib/flow-viewer/node-structure/index.js +1 -5
  34. package/lib/flow-viewer/node-structure/socket.type.matcher.js +1 -50
  35. package/lib/flow-viewer/node-structure/utils.js +1 -109
  36. package/lib/flow-viewer/services/copy-paste-manager.js +1 -59
  37. package/lib/flow-viewer/services/exporter.js +1 -67
  38. package/lib/flow-viewer/services/input.js +1 -80
  39. package/lib/flow-viewer/services/integration.js +1 -27
  40. package/lib/flow-viewer/services/modal.js +8 -29
  41. package/lib/flow-viewer/services/project.js +1 -222
  42. package/lib/flow-viewer/services/shortcuts.js +1 -63
  43. package/lib/flow-viewer/styles/editor-workspace-style.js +53 -55
  44. package/lib/flow-viewer/styles/flow-node-style.js +93 -95
  45. package/lib/flow-viewer/styles/picker-styles.js +29 -31
  46. package/lib/flow-viewer/utils.js +1 -49
  47. package/lib/index.js +56 -953
  48. package/lib/json-viewer/forms/or-rule-form-alarm.js +18 -91
  49. package/lib/json-viewer/forms/or-rule-form-email-message.js +12 -51
  50. package/lib/json-viewer/forms/or-rule-form-localized.js +43 -269
  51. package/lib/json-viewer/forms/or-rule-form-push-notification.js +63 -152
  52. package/lib/json-viewer/forms/or-rule-form-webhook.js +101 -296
  53. package/lib/json-viewer/modals/or-rule-alarm-modal.js +17 -173
  54. package/lib/json-viewer/modals/or-rule-notification-modal.js +11 -196
  55. package/lib/json-viewer/modals/or-rule-radial-modal.js +17 -142
  56. package/lib/json-viewer/modals/or-rule-webhook-modal.js +8 -78
  57. package/lib/json-viewer/or-rule-action-alarm.js +5 -97
  58. package/lib/json-viewer/or-rule-action-attribute.js +33 -235
  59. package/lib/json-viewer/or-rule-action-notification.js +56 -465
  60. package/lib/json-viewer/or-rule-action-webhook.js +18 -49
  61. package/lib/json-viewer/or-rule-asset-query.js +126 -849
  62. package/lib/json-viewer/or-rule-condition.js +29 -216
  63. package/lib/json-viewer/or-rule-json-viewer.js +34 -393
  64. package/lib/json-viewer/or-rule-then-otherwise.js +113 -609
  65. package/lib/json-viewer/or-rule-trigger-query.js +57 -227
  66. package/lib/json-viewer/or-rule-when.js +126 -343
  67. package/lib/or-rule-group-viewer.js +12 -106
  68. package/lib/or-rule-text-viewer.js +22 -133
  69. package/lib/or-rule-tree.js +57 -601
  70. package/lib/or-rule-validity.js +62 -373
  71. package/lib/or-rule-viewer.js +81 -361
  72. package/lib/style.js +64 -89
  73. package/package.json +11 -11
@@ -1,373 +1,93 @@
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
- /*
17
- * Copyright 2025, OpenRemote Inc.
18
- *
19
- * See the CONTRIBUTORS.txt file in the distribution for a
20
- * full listing of individual contributors.
21
- *
22
- * This program is free software: you can redistribute it and/or modify
23
- * it under the terms of the GNU Affero General Public License as
24
- * published by the Free Software Foundation, either version 3 of the
25
- * License, or (at your option) any later version.
26
- *
27
- * This program is distributed in the hope that it will be useful,
28
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
29
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30
- * GNU Affero General Public License for more details.
31
- *
32
- * You should have received a copy of the GNU Affero General Public License
33
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
34
- */
35
- import { css, html, LitElement } from "lit";
36
- import { customElement, property, query } from "lit/decorators.js";
37
- import { OrRulesRequestSaveEvent, OrRulesRuleChangedEvent, OrRulesRuleUnsupportedEvent, OrRulesSaveEvent, RuleViewInfoMap } from "./index";
38
- import manager, { Util } from "@openremote/core";
39
- import "./json-viewer/or-rule-json-viewer";
40
- import "./or-rule-text-viewer";
41
- import "./or-rule-validity";
42
- import "./flow-viewer/components/flow-editor";
43
- import "@openremote/or-mwc-components/or-mwc-input";
44
- import { translate } from "@openremote/or-translate";
45
- import { InputType } from "@openremote/or-mwc-components/or-mwc-input";
46
- import i18next from "i18next";
47
- import { showErrorDialog } from "@openremote/or-mwc-components/or-mwc-dialog";
48
- import { project } from "./flow-viewer/components/flow-editor";
49
- // language=CSS
50
- export const style = css `
51
-
52
- :host {
53
- display: block;
54
- height: 100%;
55
- width: 100%;
56
- overflow-y: auto;
57
- }
58
-
59
- or-rule-validity {
60
- margin-left: 10px;
61
- margin-right: 20px;
62
- }
63
-
64
- .wrapper {
65
- display: flex;
66
- flex-direction: column;
67
- align-items: center;
68
- height: 100%;
69
- }
70
-
71
- #main-wrapper.saving {
72
- opacity: 0.5;
73
- pointer-events: none;
74
- }
75
-
76
- #rule-name {
77
- max-width: 400px;
78
- flex: 1 1 0;
79
- display: flex;
80
- }
81
-
82
- #rule-header {
83
- display: flex;
84
- align-items: center;
85
- width: 100%;
86
- box-sizing: border-box;
87
- min-height: var(--internal-or-rules-header-height);
88
- height: var(--internal-or-rules-header-height);
89
- z-index: 7;
90
- padding: 15px 20px;
91
- --or-icon-fill: var(--internal-or-rules-panel-color);
92
- }
93
-
94
- #rule-header-controls {
95
- margin-left: auto;
96
- display: flex;
97
- align-items: center;
98
- }
99
-
100
- #rule-id {
101
- margin-left: 10px;
102
- font-size: small;
103
- }
104
-
105
- #active-wrapper {
106
- display: flex;
107
- align-items: center;
108
- }
109
-
110
- #rule-view {
111
- flex-grow: 1;
112
- background-color: var(--internal-or-rules-background-color);
113
- }
114
-
115
- .iconfill-gray {
116
- margin-left: 10px;
117
- --or-icon-fill: var(--internal-or-rules-list-icon-color-ok);
118
- }
119
-
120
- .iconfill-red {
121
- margin-left: 10px;
122
- --or-icon-fill: var(--internal-or-rules-list-icon-color-error);
123
- }
124
- `;
125
- let OrRuleViewer = class OrRuleViewer extends translate(i18next)(LitElement) {
126
- static get styles() {
127
- return [
128
- style
129
- ];
1
+ var __decorate=this&&this.__decorate||function(e,t,r,i){var l,s=arguments.length,a=s<3?t:null===i?i=Object.getOwnPropertyDescriptor(t,r):i;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)a=Reflect.decorate(e,t,r,i);else for(var o=e.length-1;o>=0;o--)(l=e[o])&&(a=(s<3?l(a):s>3?l(t,r,a):l(t,r))||a);return s>3&&a&&Object.defineProperty(t,r,a),a},__awaiter=this&&this.__awaiter||function(e,t,r,i){return new(r||(r=Promise))(function(l,s){function a(e){try{n(i.next(e))}catch(e){s(e)}}function o(e){try{n(i.throw(e))}catch(e){s(e)}}function n(e){var t;e.done?l(e.value):((t=e.value)instanceof r?t:new r(function(e){e(t)})).then(a,o)}n((i=i.apply(e,t||[])).next())})};import{css as e,html as t,LitElement as r}from"lit";import{customElement as i,property as l,query as s}from"lit/decorators.js";import{OrRulesRequestSaveEvent as a,OrRulesRuleChangedEvent as o,OrRulesRuleUnsupportedEvent as n,OrRulesSaveEvent as d,RuleViewInfoMap as u}from"./index";import c,{Util as p}from"@openremote/core";import"./json-viewer/or-rule-json-viewer";import"./or-rule-text-viewer";import"./or-rule-validity";import"./flow-viewer/components/flow-editor";import"@openremote/or-mwc-components/or-mwc-input";import{translate as h}from"@openremote/or-translate";import{InputType as m}from"@openremote/or-mwc-components/or-mwc-input";import v from"i18next";import{showErrorDialog as f}from"@openremote/or-mwc-components/or-mwc-dialog";import{project as w}from"./flow-viewer/components/flow-editor";export const style=e`
2
+
3
+ :host {
4
+ display: block;
5
+ height: 100%;
6
+ width: 100%;
7
+ overflow-y: auto;
130
8
  }
131
- constructor() {
132
- super();
133
- this.readonly = false;
134
- this.disabled = false;
135
- this.modified = false;
136
- this._ruleValid = false;
137
- this._supported = true;
138
- this._focusName = false;
139
- this.addEventListener(OrRulesRuleChangedEvent.NAME, this._onRuleChanged);
140
- this.addEventListener(OrRulesRuleUnsupportedEvent.NAME, this._onRuleUnsupported);
9
+
10
+ or-rule-validity {
11
+ margin-left: 10px;
12
+ margin-right: 20px;
141
13
  }
142
- get valid() {
143
- return this.ruleset && this.view && this._ruleValid && this.ruleset.name && this.ruleset.name.length >= 1 && this.ruleset.name.length < 255;
14
+
15
+ .wrapper {
16
+ display: flex;
17
+ flex-direction: column;
18
+ align-items: center;
19
+ height: 100%;
144
20
  }
145
- shouldUpdate(_changedProperties) {
146
- if (_changedProperties.has("ruleset")) {
147
- this._supported = true;
148
- this.modified = false;
149
- this._ruleValid = false;
150
- if (this.ruleset) {
151
- this._focusName = true;
152
- this.modified = !this.ruleset.id;
153
- }
154
- }
155
- return super.shouldUpdate(_changedProperties);
21
+
22
+ #main-wrapper.saving {
23
+ opacity: 0.5;
24
+ pointer-events: none;
156
25
  }
157
- render() {
158
- if (!this.ruleset) {
159
- return html `<div class="wrapper" style="justify-content: center"><or-translate value="noRuleSelected"></or-translate></div>`;
160
- }
161
- let viewer = RuleViewInfoMap[this.ruleset.lang].viewTemplateProvider(this.ruleset, this.config, this.readonly);
162
- let statusIcon = "help";
163
- let statusClass = "iconfill-gray";
164
- let statusText = "NOSTATUS";
165
- if (this.ruleset.status)
166
- statusText = this.ruleset.status;
167
- switch (this.ruleset.status) {
168
- case "DEPLOYED":
169
- statusIcon = "play";
170
- statusClass = "iconfill-gray";
171
- break;
172
- case "READY":
173
- statusIcon = "check";
174
- statusClass = "iconfill-gray";
175
- break;
176
- case "COMPILATION_ERROR":
177
- case "LOOP_ERROR":
178
- case "VALIDITY_PERIOD_ERROR":
179
- case "EXECUTION_ERROR":
180
- statusIcon = "alert-octagon";
181
- statusClass = "iconfill-red";
182
- statusText = this.ruleset.error;
183
- break;
184
- case "DISABLED":
185
- statusIcon = "minus-circle";
186
- statusClass = "iconfill-gray";
187
- break;
188
- case "PAUSED":
189
- statusIcon = "calendar-arrow-right";
190
- statusClass = "iconfill-gray";
191
- break;
192
- case "EXPIRED":
193
- statusIcon = "calendar-remove";
194
- statusClass = "iconfill-gray";
195
- break;
196
- case "REMOVED":
197
- statusIcon = "close";
198
- statusClass = "iconfill-gray";
199
- break;
200
- default:
201
- statusIcon = "stop";
202
- statusClass = "iconfill-gray";
203
- statusText = "NOSTATUS";
204
- }
205
- return html `
206
- <div id="main-wrapper" class="wrapper">
207
- <div id="rule-header">
208
- <or-mwc-input id="rule-name" outlined .type="${InputType.TEXT}" .label="${i18next.t("ruleName")}" ?focused="${this._focusName}" .value="${this.ruleset ? this.ruleset.name : null}" ?disabled="${this._isReadonly()}" required minlength="1" maxlength="255" @or-mwc-input-changed="${(e) => this._changeName(e.detail.value)}"></or-mwc-input>
209
- <or-icon class="${statusClass}" title="${i18next.t("rulesetStatus." + statusText)}" icon="${statusIcon}"></or-icon>
210
- <span id="rule-id">${this.ruleset.id ? "ID: " + this.ruleset.id : ""}</span>
211
- <div id="rule-header-controls">
212
- <span id="active-wrapper">
213
- <or-translate value="enabled"></or-translate>
214
- <or-mwc-input .type="${InputType.CHECKBOX}" .value="${this.ruleset && this.ruleset.enabled}" ?disabled="${!this.ruleset.id}" @or-mwc-input-changed="${this._toggleEnabled}"></or-mwc-input>
215
- </span>
216
- <or-rule-validity id="rule-header-validity" .ruleset="${this.ruleset}"></or-rule-validity>
217
- <or-mwc-input .type="${InputType.BUTTON}" id="save-btn" label="save" raised ?disabled="${this._cannotSave()}" @or-mwc-input-changed="${this._onSaveClicked}"></or-mwc-input>
218
- </div>
219
- </div>
220
-
221
- ${viewer}
222
- </div>
223
- `;
26
+
27
+ #rule-name {
28
+ max-width: 400px;
29
+ flex: 1 1 0;
30
+ display: flex;
224
31
  }
225
- updated(_changedProperties) {
226
- if (_changedProperties.has("ruleset") || _changedProperties.has("modified")) {
227
- if (this.ruleset && this.view) {
228
- this._ruleValid = this.view.validate();
229
- }
230
- }
32
+
33
+ #rule-header {
34
+ display: flex;
35
+ align-items: center;
36
+ width: 100%;
37
+ box-sizing: border-box;
38
+ min-height: var(--internal-or-rules-header-height);
39
+ height: var(--internal-or-rules-header-height);
40
+ z-index: 7;
41
+ padding: 15px 20px;
42
+ --or-icon-fill: var(--internal-or-rules-panel-color);
231
43
  }
232
- _isReadonly() {
233
- return this.readonly || !manager.hasRole("write:rules" /* ClientRole.WRITE_RULES */);
44
+
45
+ #rule-header-controls {
46
+ margin-left: auto;
47
+ display: flex;
48
+ align-items: center;
234
49
  }
235
- _cannotSave() {
236
- return this._isReadonly() || !this.ruleset || !this.modified || !this.valid;
50
+
51
+ #rule-id {
52
+ margin-left: 10px;
53
+ font-size: small;
237
54
  }
238
- _changeName(name) {
239
- if (this.ruleset && this.ruleset.name !== name) {
240
- this.ruleset.name = name;
241
- this.modified = true;
242
- this.requestUpdate();
243
- }
55
+
56
+ #active-wrapper {
57
+ display: flex;
58
+ align-items: center;
244
59
  }
245
- _onRuleChanged(e) {
246
- this.modified = true;
247
- this._ruleValid = e.detail;
60
+
61
+ #rule-view {
62
+ flex-grow: 1;
63
+ background-color: var(--internal-or-rules-background-color);
248
64
  }
249
- _onSaveClicked() {
250
- if (!this.ruleset || !this.view) {
251
- return;
252
- }
253
- project.emit("fitview");
254
- if (this.config && this.config.rulesetSaveHandler && !this.config.rulesetSaveHandler(this.ruleset)) {
255
- return;
256
- }
257
- Util.dispatchCancellableEvent(this, new OrRulesRequestSaveEvent(this.ruleset))
258
- .then((detail) => {
259
- if (detail.allow) {
260
- this._doSave();
261
- }
262
- });
65
+
66
+ .iconfill-gray {
67
+ margin-left: 10px;
68
+ --or-icon-fill: var(--internal-or-rules-list-icon-color-ok);
263
69
  }
264
- _doSave() {
265
- return __awaiter(this, void 0, void 0, function* () {
266
- const ruleset = this.ruleset;
267
- if (!ruleset || !this.view) {
268
- return;
269
- }
270
- let fail = false;
271
- const isNew = !ruleset.id;
272
- this.saveBtnElem.disabled = true;
273
- this.wrapperElem.classList.add("saving");
274
- this.view.beforeSave();
275
- let response;
276
- try {
277
- switch (ruleset.type) {
278
- case "asset":
279
- if (isNew) {
280
- response = yield manager.rest.api.RulesResource.createAssetRuleset(ruleset);
281
- }
282
- else {
283
- response = yield manager.rest.api.RulesResource.updateAssetRuleset(ruleset.id, ruleset);
284
- }
285
- break;
286
- case "realm":
287
- if (isNew) {
288
- response = yield manager.rest.api.RulesResource.createRealmRuleset(ruleset);
289
- }
290
- else {
291
- response = yield manager.rest.api.RulesResource.updateRealmRuleset(ruleset.id, ruleset);
292
- }
293
- break;
294
- case "global":
295
- if (isNew) {
296
- response = yield manager.rest.api.RulesResource.createGlobalRuleset(ruleset);
297
- }
298
- else {
299
- response = yield manager.rest.api.RulesResource.updateGlobalRuleset(ruleset.id, ruleset);
300
- }
301
- break;
302
- }
303
- if (response.status !== (isNew ? 200 : 204)) {
304
- fail = true;
305
- showErrorDialog("Create ruleset returned unexpected status: " + response.status);
306
- return;
307
- }
308
- else if (response.data) {
309
- ruleset.id = response.data;
310
- }
311
- }
312
- catch (e) {
313
- fail = true;
314
- console.error("Failed to save ruleset", e);
315
- }
316
- this.wrapperElem.classList.remove("saving");
317
- this.saveBtnElem.disabled = false;
318
- if (fail) {
319
- showErrorDialog(i18next.t("saveRulesetFailed"));
320
- }
321
- this.dispatchEvent(new OrRulesSaveEvent({
322
- ruleset: ruleset,
323
- isNew: isNew,
324
- success: !fail
325
- }));
326
- });
70
+
71
+ .iconfill-red {
72
+ margin-left: 10px;
73
+ --or-icon-fill: var(--internal-or-rules-list-icon-color-error);
327
74
  }
328
- _onRuleUnsupported() {
329
- this._supported = false;
330
- }
331
- _toggleEnabled() {
332
- if (this.ruleset) {
333
- this.ruleset.enabled = !this.ruleset.enabled;
334
- this.modified = true;
335
- this.requestUpdate();
336
- }
337
- }
338
- };
339
- __decorate([
340
- property({ type: Object })
341
- ], OrRuleViewer.prototype, "ruleset", void 0);
342
- __decorate([
343
- property({ type: Boolean })
344
- ], OrRuleViewer.prototype, "readonly", void 0);
345
- __decorate([
346
- property({ type: Boolean })
347
- ], OrRuleViewer.prototype, "disabled", void 0);
348
- __decorate([
349
- property({ type: Object })
350
- ], OrRuleViewer.prototype, "config", void 0);
351
- __decorate([
352
- property({ attribute: false })
353
- ], OrRuleViewer.prototype, "modified", void 0);
354
- __decorate([
355
- property({ attribute: false })
356
- ], OrRuleViewer.prototype, "_ruleValid", void 0);
357
- __decorate([
358
- property({ attribute: false })
359
- ], OrRuleViewer.prototype, "_supported", void 0);
360
- __decorate([
361
- query("#rule-view")
362
- ], OrRuleViewer.prototype, "view", void 0);
363
- __decorate([
364
- query("#main-wrapper")
365
- ], OrRuleViewer.prototype, "wrapperElem", void 0);
366
- __decorate([
367
- query("#save-btn")
368
- ], OrRuleViewer.prototype, "saveBtnElem", void 0);
369
- OrRuleViewer = __decorate([
370
- customElement("or-rule-viewer")
371
- ], OrRuleViewer);
372
- export { OrRuleViewer };
373
- //# sourceMappingURL=or-rule-viewer.js.map
75
+ `;let OrRuleViewer=class extends h(v)(r){static get styles(){return[style]}constructor(){super(),this.readonly=!1,this.disabled=!1,this.modified=!1,this._ruleValid=!1,this._supported=!0,this._focusName=!1,this.addEventListener(o.NAME,this._onRuleChanged),this.addEventListener(n.NAME,this._onRuleUnsupported)}get valid(){return this.ruleset&&this.view&&this._ruleValid&&this.ruleset.name&&this.ruleset.name.length>=1&&this.ruleset.name.length<255}shouldUpdate(e){return e.has("ruleset")&&(this._supported=!0,this.modified=!1,this._ruleValid=!1,this.ruleset&&(this._focusName=!0,this.modified=!this.ruleset.id)),super.shouldUpdate(e)}render(){if(!this.ruleset)return t`<div class="wrapper" style="justify-content: center"><or-translate value="noRuleSelected"></or-translate></div>`;let e=u[this.ruleset.lang].viewTemplateProvider(this.ruleset,this.config,this.readonly),r="help",i="iconfill-gray",l="NOSTATUS";switch(this.ruleset.status&&(l=this.ruleset.status),this.ruleset.status){case"DEPLOYED":r="play",i="iconfill-gray";break;case"READY":r="check",i="iconfill-gray";break;case"COMPILATION_ERROR":case"LOOP_ERROR":case"VALIDITY_PERIOD_ERROR":case"EXECUTION_ERROR":r="alert-octagon",i="iconfill-red",l=this.ruleset.error;break;case"DISABLED":r="minus-circle",i="iconfill-gray";break;case"PAUSED":r="calendar-arrow-right",i="iconfill-gray";break;case"EXPIRED":r="calendar-remove",i="iconfill-gray";break;case"REMOVED":r="close",i="iconfill-gray";break;default:r="stop",i="iconfill-gray",l="NOSTATUS"}return t`
76
+ <div id="main-wrapper" class="wrapper">
77
+ <div id="rule-header">
78
+ <or-mwc-input id="rule-name" outlined .type="${m.TEXT}" .label="${v.t("ruleName")}" ?focused="${this._focusName}" .value="${this.ruleset?this.ruleset.name:null}" ?disabled="${this._isReadonly()}" required minlength="1" maxlength="255" @or-mwc-input-changed="${e=>this._changeName(e.detail.value)}"></or-mwc-input>
79
+ <or-icon class="${i}" title="${v.t("rulesetStatus."+l)}" icon="${r}"></or-icon>
80
+ <span id="rule-id">${this.ruleset.id?"ID: "+this.ruleset.id:""}</span>
81
+ <div id="rule-header-controls">
82
+ <span id="active-wrapper">
83
+ <or-translate value="enabled"></or-translate>
84
+ <or-mwc-input .type="${m.CHECKBOX}" .value="${this.ruleset&&this.ruleset.enabled}" ?disabled="${!this.ruleset.id}" @or-mwc-input-changed="${this._toggleEnabled}"></or-mwc-input>
85
+ </span>
86
+ <or-rule-validity id="rule-header-validity" .ruleset="${this.ruleset}"></or-rule-validity>
87
+ <or-mwc-input .type="${m.BUTTON}" id="save-btn" label="save" raised ?disabled="${this._cannotSave()}" @or-mwc-input-changed="${this._onSaveClicked}"></or-mwc-input>
88
+ </div>
89
+ </div>
90
+
91
+ ${e}
92
+ </div>
93
+ `}updated(e){(e.has("ruleset")||e.has("modified"))&&this.ruleset&&this.view&&(this._ruleValid=this.view.validate())}_isReadonly(){return this.readonly||!c.hasRole("write:rules")}_cannotSave(){return this._isReadonly()||!this.ruleset||!this.modified||!this.valid}_changeName(e){this.ruleset&&this.ruleset.name!==e&&(this.ruleset.name=e,this.modified=!0,this.requestUpdate())}_onRuleChanged(e){this.modified=!0,this._ruleValid=e.detail}_onSaveClicked(){this.ruleset&&this.view&&(w.emit("fitview"),(!this.config||!this.config.rulesetSaveHandler||this.config.rulesetSaveHandler(this.ruleset))&&p.dispatchCancellableEvent(this,new a(this.ruleset)).then(e=>{e.allow&&this._doSave()}))}_doSave(){return __awaiter(this,void 0,void 0,function*(){let e,t=this.ruleset;if(!t||!this.view)return;let r=!1,i=!t.id;this.saveBtnElem.disabled=!0,this.wrapperElem.classList.add("saving"),this.view.beforeSave();try{switch(t.type){case"asset":e=i?yield c.rest.api.RulesResource.createAssetRuleset(t):yield c.rest.api.RulesResource.updateAssetRuleset(t.id,t);break;case"realm":e=i?yield c.rest.api.RulesResource.createRealmRuleset(t):yield c.rest.api.RulesResource.updateRealmRuleset(t.id,t);break;case"global":e=i?yield c.rest.api.RulesResource.createGlobalRuleset(t):yield c.rest.api.RulesResource.updateGlobalRuleset(t.id,t)}if(e.status!==(i?200:204)){r=!0,f("Create ruleset returned unexpected status: "+e.status);return}e.data&&(t.id=e.data)}catch(e){r=!0,console.error("Failed to save ruleset",e)}this.wrapperElem.classList.remove("saving"),this.saveBtnElem.disabled=!1,r&&f(v.t("saveRulesetFailed")),this.dispatchEvent(new d({ruleset:t,isNew:i,success:!r}))})}_onRuleUnsupported(){this._supported=!1}_toggleEnabled(){this.ruleset&&(this.ruleset.enabled=!this.ruleset.enabled,this.modified=!0,this.requestUpdate())}};__decorate([l({type:Object})],OrRuleViewer.prototype,"ruleset",void 0),__decorate([l({type:Boolean})],OrRuleViewer.prototype,"readonly",void 0),__decorate([l({type:Boolean})],OrRuleViewer.prototype,"disabled",void 0),__decorate([l({type:Object})],OrRuleViewer.prototype,"config",void 0),__decorate([l({attribute:!1})],OrRuleViewer.prototype,"modified",void 0),__decorate([l({attribute:!1})],OrRuleViewer.prototype,"_ruleValid",void 0),__decorate([l({attribute:!1})],OrRuleViewer.prototype,"_supported",void 0),__decorate([s("#rule-view")],OrRuleViewer.prototype,"view",void 0),__decorate([s("#main-wrapper")],OrRuleViewer.prototype,"wrapperElem",void 0),__decorate([s("#save-btn")],OrRuleViewer.prototype,"saveBtnElem",void 0),OrRuleViewer=__decorate([i("or-rule-viewer")],OrRuleViewer);export{OrRuleViewer};
package/lib/style.js CHANGED
@@ -1,89 +1,64 @@
1
- /*
2
- * Copyright 2025, OpenRemote Inc.
3
- *
4
- * See the CONTRIBUTORS.txt file in the distribution for a
5
- * full listing of individual contributors.
6
- *
7
- * This program is free software: you can redistribute it and/or modify
8
- * it under the terms of the GNU Affero General Public License as
9
- * published by the Free Software Foundation, either version 3 of the
10
- * License, or (at your option) any later version.
11
- *
12
- * This program is distributed in the hope that it will be useful,
13
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
- * GNU Affero General Public License for more details.
16
- *
17
- * You should have received a copy of the GNU Affero General Public License
18
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
19
- */
20
- import { DefaultColor5 } from "@openremote/core";
21
- import { css, unsafeCSS } from "lit";
22
- // language=CSS
23
- export const invalidStyle = css `
24
- *:invalid {
25
- border-bottom: 2px solid var(--internal-or-rules-invalid-color);
26
- }
27
- `;
28
- // language=CSS
29
- export const buttonStyle = css `
30
- .button-clear {
31
- background: none;
32
- color: ${unsafeCSS(DefaultColor5)};
33
- --or-icon-fill: ${unsafeCSS(DefaultColor5)};
34
- visibility: hidden;
35
- display: inline-block;
36
- border: none;
37
- padding: 0;
38
- cursor: pointer;
39
- }
40
-
41
- .button-clear:hover {
42
- --or-icon-fill: var(--internal-or-rules-button-color);
43
- }
44
-
45
- .button-clear:focus {
46
- outline: 0;
47
- }
48
-
49
- .button-clear.hidden {
50
- visibility: hidden;
51
- }
52
-
53
- .plus-button {
54
- --or-icon-fill: var(--internal-or-rules-button-color);
55
- }
56
-
57
- .add-button {
58
- display: inline-block;
59
- font-weight: bold;
60
- font-size: 15px;
61
- line-height: 24px;
62
- }
63
-
64
- .add-buttons-container {
65
- display: flex;
66
- flex-direction: column;
67
- margin-top: 10px;
68
- margin-bottom: -10px;
69
- padding-top: 5px;
70
- border-top-width: 1px;
71
- border-top-style: solid;
72
- border-color: var(--internal-or-rules-line-color);
73
- }
74
-
75
- .add-buttons-container.hidden {
76
- border: none;
77
- margin: 0;
78
- padding: 0;
79
- }
80
-
81
- .add-buttons-container > button {
82
- display: inline-flex;
83
- }
84
-
85
- .add-buttons-container > button > or-icon {
86
- margin-right: 5px;
87
- }
88
- `;
89
- //# sourceMappingURL=style.js.map
1
+ import{DefaultColor5 as o}from"@openremote/core";import{css as n,unsafeCSS as t}from"lit";export const invalidStyle=n`
2
+ *:invalid {
3
+ border-bottom: 2px solid var(--internal-or-rules-invalid-color);
4
+ }
5
+ `;export const buttonStyle=n`
6
+ .button-clear {
7
+ background: none;
8
+ color: ${t(o)};
9
+ --or-icon-fill: ${t(o)};
10
+ visibility: hidden;
11
+ display: inline-block;
12
+ border: none;
13
+ padding: 0;
14
+ cursor: pointer;
15
+ }
16
+
17
+ .button-clear:hover {
18
+ --or-icon-fill: var(--internal-or-rules-button-color);
19
+ }
20
+
21
+ .button-clear:focus {
22
+ outline: 0;
23
+ }
24
+
25
+ .button-clear.hidden {
26
+ visibility: hidden;
27
+ }
28
+
29
+ .plus-button {
30
+ --or-icon-fill: var(--internal-or-rules-button-color);
31
+ }
32
+
33
+ .add-button {
34
+ display: inline-block;
35
+ font-weight: bold;
36
+ font-size: 15px;
37
+ line-height: 24px;
38
+ }
39
+
40
+ .add-buttons-container {
41
+ display: flex;
42
+ flex-direction: column;
43
+ margin-top: 10px;
44
+ margin-bottom: -10px;
45
+ padding-top: 5px;
46
+ border-top-width: 1px;
47
+ border-top-style: solid;
48
+ border-color: var(--internal-or-rules-line-color);
49
+ }
50
+
51
+ .add-buttons-container.hidden {
52
+ border: none;
53
+ margin: 0;
54
+ padding: 0;
55
+ }
56
+
57
+ .add-buttons-container > button {
58
+ display: inline-flex;
59
+ }
60
+
61
+ .add-buttons-container > button > or-icon {
62
+ margin-right: 5px;
63
+ }
64
+ `;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openremote/or-rules",
3
- "version": "1.8.0-snapshot.20250725120002",
3
+ "version": "1.8.0-snapshot.20250728102340",
4
4
  "description": "OpenRemote rules related UI components",
5
5
  "customElements": "custom-elements.json",
6
6
  "main": "dist/umd/index.bundle.js",
@@ -18,15 +18,15 @@
18
18
  "author": "OpenRemote",
19
19
  "license": "AGPL-3.0-or-later",
20
20
  "dependencies": {
21
- "@openremote/core": "1.8.0-snapshot.20250725120002",
22
- "@openremote/model": "1.8.0-snapshot.20250725120002",
23
- "@openremote/or-attribute-input": "1.8.0-snapshot.20250725120002",
24
- "@openremote/or-components": "1.8.0-snapshot.20250725120002",
25
- "@openremote/or-icon": "1.8.0-snapshot.20250725120002",
26
- "@openremote/or-mwc-components": "1.8.0-snapshot.20250725120002",
27
- "@openremote/or-translate": "1.8.0-snapshot.20250725120002",
28
- "@openremote/or-tree-menu": "1.8.0-snapshot.20250725120002",
29
- "@openremote/rest": "1.8.0-snapshot.20250725120002",
21
+ "@openremote/core": "1.8.0-snapshot.20250728102340",
22
+ "@openremote/model": "1.8.0-snapshot.20250728102340",
23
+ "@openremote/or-attribute-input": "1.8.0-snapshot.20250728102340",
24
+ "@openremote/or-components": "1.8.0-snapshot.20250728102340",
25
+ "@openremote/or-icon": "1.8.0-snapshot.20250728102340",
26
+ "@openremote/or-mwc-components": "1.8.0-snapshot.20250728102340",
27
+ "@openremote/or-translate": "1.8.0-snapshot.20250728102340",
28
+ "@openremote/or-tree-menu": "1.8.0-snapshot.20250728102340",
29
+ "@openremote/rest": "1.8.0-snapshot.20250728102340",
30
30
  "ace-builds": "^1.41.0",
31
31
  "iso-639-1": "^3.1.3",
32
32
  "linqts": "^1.12.6",
@@ -37,7 +37,7 @@
37
37
  "shortid": "^2.2.15"
38
38
  },
39
39
  "devDependencies": {
40
- "@openremote/util": "1.8.0-snapshot.20250725120002",
40
+ "@openremote/util": "1.8.0-snapshot.20250728102340",
41
41
  "@types/shortid": "^0.0.29"
42
42
  },
43
43
  "publishConfig": {