@openremote/or-rules 1.8.0-snapshot.20250725120000 → 1.8.0-snapshot.20250725123024

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,282 +1,20 @@
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 { LitElement, html } from "lit";
17
- import { customElement, property } from "lit/decorators.js";
18
- import { repeat } from "lit/directives/repeat.js";
19
- import { IdentityDomLink } from "../node-structure";
20
- import { List } from "linqts";
21
- import { EditorWorkspaceStyle } from "../styles/editor-workspace-style";
22
- import { i18next, translate } from "@openremote/or-translate";
23
- import { ContextMenu } from "./context-menu";
24
- import { project, input, copyPasteManager } from "./flow-editor";
25
- import { createContextMenuButtons } from "./workspace-contextmenu-options";
26
- import { InputType } from "@openremote/or-mwc-components/or-mwc-input";
27
- let EditorWorkspace = class EditorWorkspace extends translate(i18next)(LitElement) {
28
- get clientRect() {
29
- return this.cachedClientRect;
30
- }
31
- static get styles() {
32
- return EditorWorkspaceStyle;
33
- }
34
- get halfSize() {
35
- const box = this.cachedClientRect;
36
- return { x: box.width / 2, y: box.height / 2 };
37
- }
38
- get isCameraInDefaultPosition() {
39
- const errorMargin = 0.05;
40
- return (Math.abs(this.camera.x) < errorMargin && Math.abs(this.camera.y) < errorMargin && this.camera.zoom > (1 - errorMargin) && this.camera.zoom < (1 + errorMargin));
41
- }
42
- constructor() {
43
- super();
44
- this.camera = { x: 0, y: 0, zoom: 1 };
45
- this.topNodeZindex = 1;
46
- this.scrollSensitivity = 1.25;
47
- this.zoomLowerBound = .2;
48
- this.zoomUpperBound = 10;
49
- this.connectionDragging = false;
50
- this.connectionFrom = { x: 0, y: 0 };
51
- this.connectionTo = { x: 0, y: 0 };
52
- this.isPanning = false;
53
- this.onMove = (event) => {
54
- const documentZoom = window.devicePixelRatio;
55
- this.camera = {
56
- x: this.camera.x + event.movementX / this.camera.zoom / documentZoom,
57
- y: this.camera.y + event.movementY / this.camera.zoom / documentZoom,
58
- zoom: this.camera.zoom
59
- };
60
- this.dispatchEvent(new CustomEvent("pan"));
61
- };
62
- this.onZoom = (event) => {
63
- if (this.connectionDragging) {
64
- return;
65
- }
66
- if (this.isPanning) {
67
- return;
68
- }
69
- const magnification = 0.9 * this.scrollSensitivity;
70
- const rz = event.deltaY < 0 ? this.camera.zoom * magnification : this.camera.zoom / magnification;
71
- if (rz < this.zoomLowerBound || rz > this.zoomUpperBound) {
72
- return;
73
- }
74
- this.camera = {
75
- x: this.camera.x,
76
- y: this.camera.y,
77
- zoom: rz
78
- };
79
- this.dispatchEvent(new CustomEvent("zoom"));
80
- };
81
- this.onEmptyConnectionRelease = (ee) => {
82
- if (project.isCurrentlyConnecting) {
83
- project.endConnectionDrag(ee, null, false);
84
- }
85
- };
86
- this.stopPan = () => {
87
- if (!this.isPanning) {
88
- return;
89
- }
90
- window.removeEventListener("mousemove", this.onMove);
91
- this.isPanning = false;
92
- };
93
- project.addListener("nodeadded", (n) => { this.requestUpdate(); });
94
- project.addListener("noderemoved", (n) => { this.requestUpdate(); });
95
- project.addListener("cleared", () => { this.requestUpdate(); });
96
- project.addListener("connectionstart", (e, s) => {
97
- if (e.buttons !== 1) {
98
- return;
99
- }
100
- const pos = IdentityDomLink.map[s.id].connectionPosition;
101
- this.connectionFrom = this.pageToOffset(pos);
102
- this.addEventListener("mousemove", project.connectionDragging);
103
- this.addEventListener("mouseup", this.onEmptyConnectionRelease);
104
- });
105
- project.addListener("connecting", (e) => {
106
- this.connectionTo = { x: e.pageX - this.clientRect.left, y: e.pageY - this.clientRect.top };
107
- this.connectionDragging = true;
108
- });
109
- project.addListener("connectionend", () => {
110
- this.connectionDragging = false;
111
- this.removeEventListener("mousemove", project.connectionDragging);
112
- });
113
- project.addListener("fitview", () => {
114
- this.fitCamera(project.nodes);
115
- });
116
- window.addEventListener("resize", () => {
117
- this.cachedClientRect = this.getBoundingClientRect();
118
- this.dispatchEvent(new CustomEvent("pan"));
119
- });
120
- this.addEventListener("mousedown", (e) => {
121
- this.startPan(e);
122
- if (e.buttons === 1) {
123
- input.clearSelection();
124
- }
125
- });
126
- this.addEventListener("contextmenu", (e) => {
127
- const buttons = createContextMenuButtons(this, e);
128
- ContextMenu.open(e.pageX, e.pageY, this, buttons);
129
- e.preventDefault();
130
- });
131
- project.workspace = this;
132
- this.addEventListener("wheel", this.onZoom, { passive: true });
133
- }
134
- resetCamera() {
135
- this.camera = { x: 0, y: 0, zoom: 1 };
136
- this.dispatchEvent(new CustomEvent("pan"));
137
- this.dispatchEvent(new CustomEvent("zoom"));
138
- }
139
- fitCamera(nodes, padding = 25) {
140
- const enumerable = new List();
141
- enumerable.AddRange(nodes);
142
- if (enumerable.Count() == 0)
143
- return;
144
- const XouterleastNode = enumerable.OrderBy((a) => a.position.x).First();
145
- const YouterleastNode = enumerable.OrderBy((a) => a.position.y).First();
146
- const XoutermostNode = enumerable.OrderByDescending((a) => a.position.x + IdentityDomLink.map[a.id].scrollWidth).First();
147
- const YoutermostNode = enumerable.OrderByDescending((a) => a.position.y + IdentityDomLink.map[a.id].scrollHeight).First();
148
- const XoutermostWidth = IdentityDomLink.map[XoutermostNode.id].scrollWidth;
149
- const YoutermostHeight = IdentityDomLink.map[YoutermostNode.id].scrollHeight;
150
- const fitBounds = {
151
- left: XouterleastNode.position.x - padding,
152
- right: XoutermostNode.position.x + padding + XoutermostWidth,
153
- top: YoutermostNode.position.y + padding + YoutermostHeight,
154
- bottom: YouterleastNode.position.y - padding,
155
- };
156
- const fitWidth = fitBounds.right - fitBounds.left;
157
- const fitHeight = fitBounds.top - fitBounds.bottom;
158
- const totalBounds = this.clientRect;
159
- const center = {
160
- x: (fitBounds.left + fitBounds.right) / 2.0,
161
- y: (fitBounds.top + fitBounds.bottom) / 2.0
162
- };
163
- const targetZoom = Math.min(totalBounds.width / fitWidth, totalBounds.height / fitHeight);
164
- this.camera = {
165
- x: -center.x,
166
- y: -center.y,
167
- zoom: Math.min(Math.max(this.zoomLowerBound, targetZoom), this.zoomUpperBound)
168
- };
169
- this.dispatchEvent(new CustomEvent("pan"));
170
- this.dispatchEvent(new CustomEvent("zoom"));
171
- }
172
- offsetToWorld(point) {
173
- const halfSize = this.halfSize;
174
- return {
175
- x: (point.x - halfSize.x) / this.camera.zoom - this.camera.x,
176
- y: (point.y - halfSize.y) / this.camera.zoom - this.camera.y
177
- };
178
- }
179
- worldToOffset(point) {
180
- const halfSize = this.halfSize;
181
- return {
182
- x: (point.x + this.camera.x) * this.camera.zoom + halfSize.x,
183
- y: (point.y + this.camera.y) * this.camera.zoom + halfSize.y
184
- };
185
- }
186
- pageToOffset(point) {
187
- const box = this.clientRect;
188
- return {
189
- x: point.x - box.left,
190
- y: point.y - box.top
191
- };
192
- }
193
- pasteAt(x, y) {
194
- return __awaiter(this, void 0, void 0, function* () {
195
- const clone = copyPasteManager.getFromClipboard({ x, y });
196
- clone.nodes.forEach((n) => {
197
- project.addNode(n);
198
- });
199
- yield this.updateComplete;
200
- clone.connections.forEach((c) => {
201
- project.createConnection(c.from, c.to);
202
- });
203
- });
204
- }
205
- firstUpdated() {
206
- this.cachedClientRect = this.getBoundingClientRect();
207
- if (this.application.nodePanel.drawer) {
208
- this.application.nodePanel.drawer.addEventListener("or-mwc-drawer-changed", (e) => __awaiter(this, void 0, void 0, function* () {
209
- this.style.width = e.detail ? "calc(100% - 255px)" : "";
210
- yield this.updateComplete;
211
- this.cachedClientRect = this.getBoundingClientRect();
212
- this.dispatchEvent(new CustomEvent("pan"));
213
- }));
214
- }
215
- }
216
- render() {
217
- return html `
218
- ${repeat(project.nodes, (i) => i.id, (n) => html `<flow-node .node="${n}" .workspace="${this}"></flow-node>`)}
219
- <connection-container .workspace="${this}"></connection-container>
220
- <svg>
221
- <line style="display:
222
- ${this.connectionDragging ? null : `none`};
223
- stroke-dasharray: ${20 * this.camera.zoom}, ${10 * this.camera.zoom};
224
- stroke-opacity: 0.25; stroke-width: ${this.camera.zoom * 4}px"
225
-
226
- x1="${this.connectionFrom.x}"
227
- y1="${this.connectionFrom.y}"
228
- x2="${this.connectionTo.x}"
229
- y2="${this.connectionTo.y}"></line>
230
- </svg>
231
- <selection-box .workspace="${this}"></selection-box>
232
- <div class="view-options" style="z-index: ${this.topNodeZindex + 1}">
233
- ${!this.isCameraInDefaultPosition ? html `<or-mwc-input type="${InputType.BUTTON}" icon="vector-square" @or-mwc-input-changed="${this.resetCamera}" label="${i18next.t("resetView", "Reset view")}"></or-mwc-input>` : null}
234
- ${project.nodes.length !== 0 ? html `<or-mwc-input type="button" icon="fit-to-page-outline" @or-mwc-input-changed="${() => this.fitCamera(project.nodes)}" label="${i18next.t("fitView", "Fit view")}"></or-mwc-input>` : null}
235
- </div>
236
- `;
237
- }
238
- startPan(event) {
239
- if (this.connectionDragging) {
240
- return false;
241
- }
242
- if (event.buttons !== 4) {
243
- return false;
244
- }
245
- this.isPanning = true;
246
- window.addEventListener("mousemove", this.onMove);
247
- window.addEventListener("mouseup", this.stopPan);
248
- event.preventDefault();
249
- }
250
- };
251
- __decorate([
252
- property({ attribute: false })
253
- ], EditorWorkspace.prototype, "camera", void 0);
254
- __decorate([
255
- property({ attribute: false })
256
- ], EditorWorkspace.prototype, "topNodeZindex", void 0);
257
- __decorate([
258
- property({ attribute: false })
259
- ], EditorWorkspace.prototype, "scrollSensitivity", void 0);
260
- __decorate([
261
- property({ attribute: false })
262
- ], EditorWorkspace.prototype, "zoomLowerBound", void 0);
263
- __decorate([
264
- property({ attribute: false })
265
- ], EditorWorkspace.prototype, "zoomUpperBound", void 0);
266
- __decorate([
267
- property({ attribute: false })
268
- ], EditorWorkspace.prototype, "application", void 0);
269
- __decorate([
270
- property({ attribute: false })
271
- ], EditorWorkspace.prototype, "connectionDragging", void 0);
272
- __decorate([
273
- property({ attribute: false })
274
- ], EditorWorkspace.prototype, "connectionFrom", void 0);
275
- __decorate([
276
- property({ attribute: false })
277
- ], EditorWorkspace.prototype, "connectionTo", void 0);
278
- EditorWorkspace = __decorate([
279
- customElement("editor-workspace")
280
- ], EditorWorkspace);
281
- export { EditorWorkspace };
282
- //# sourceMappingURL=editor-workspace.js.map
1
+ var __decorate=this&&this.__decorate||function(t,e,o,i){var n,r=arguments.length,s=r<3?e:null===i?i=Object.getOwnPropertyDescriptor(e,o):i;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(t,e,o,i);else for(var a=t.length-1;a>=0;a--)(n=t[a])&&(s=(r<3?n(s):r>3?n(e,o,s):n(e,o))||s);return r>3&&s&&Object.defineProperty(e,o,s),s},__awaiter=this&&this.__awaiter||function(t,e,o,i){return new(o||(o=Promise))(function(n,r){function s(t){try{c(i.next(t))}catch(t){r(t)}}function a(t){try{c(i.throw(t))}catch(t){r(t)}}function c(t){var e;t.done?n(t.value):((e=t.value)instanceof o?e:new o(function(t){t(e)})).then(s,a)}c((i=i.apply(t,e||[])).next())})};import{LitElement as t,html as e}from"lit";import{customElement as o,property as i}from"lit/decorators.js";import{repeat as n}from"lit/directives/repeat.js";import{IdentityDomLink as r}from"../node-structure";import{List as s}from"linqts";import{EditorWorkspaceStyle as a}from"../styles/editor-workspace-style";import{i18next as c,translate as d}from"@openremote/or-translate";import{ContextMenu as h}from"./context-menu";import{project as m,input as p,copyPasteManager as l}from"./flow-editor";import{createContextMenuButtons as u}from"./workspace-contextmenu-options";import{InputType as v}from"@openremote/or-mwc-components/or-mwc-input";let EditorWorkspace=class extends d(c)(t){get clientRect(){return this.cachedClientRect}static get styles(){return a}get halfSize(){let t=this.cachedClientRect;return{x:t.width/2,y:t.height/2}}get isCameraInDefaultPosition(){return .05>Math.abs(this.camera.x)&&.05>Math.abs(this.camera.y)&&this.camera.zoom>.95&&this.camera.zoom<1.05}constructor(){super(),this.camera={x:0,y:0,zoom:1},this.topNodeZindex=1,this.scrollSensitivity=1.25,this.zoomLowerBound=.2,this.zoomUpperBound=10,this.connectionDragging=!1,this.connectionFrom={x:0,y:0},this.connectionTo={x:0,y:0},this.isPanning=!1,this.onMove=t=>{let e=window.devicePixelRatio;this.camera={x:this.camera.x+t.movementX/this.camera.zoom/e,y:this.camera.y+t.movementY/this.camera.zoom/e,zoom:this.camera.zoom},this.dispatchEvent(new CustomEvent("pan"))},this.onZoom=t=>{if(this.connectionDragging||this.isPanning)return;let e=.9*this.scrollSensitivity,o=t.deltaY<0?this.camera.zoom*e:this.camera.zoom/e;o<this.zoomLowerBound||o>this.zoomUpperBound||(this.camera={x:this.camera.x,y:this.camera.y,zoom:o},this.dispatchEvent(new CustomEvent("zoom")))},this.onEmptyConnectionRelease=t=>{m.isCurrentlyConnecting&&m.endConnectionDrag(t,null,!1)},this.stopPan=()=>{this.isPanning&&(window.removeEventListener("mousemove",this.onMove),this.isPanning=!1)},m.addListener("nodeadded",t=>{this.requestUpdate()}),m.addListener("noderemoved",t=>{this.requestUpdate()}),m.addListener("cleared",()=>{this.requestUpdate()}),m.addListener("connectionstart",(t,e)=>{if(1!==t.buttons)return;let o=r.map[e.id].connectionPosition;this.connectionFrom=this.pageToOffset(o),this.addEventListener("mousemove",m.connectionDragging),this.addEventListener("mouseup",this.onEmptyConnectionRelease)}),m.addListener("connecting",t=>{this.connectionTo={x:t.pageX-this.clientRect.left,y:t.pageY-this.clientRect.top},this.connectionDragging=!0}),m.addListener("connectionend",()=>{this.connectionDragging=!1,this.removeEventListener("mousemove",m.connectionDragging)}),m.addListener("fitview",()=>{this.fitCamera(m.nodes)}),window.addEventListener("resize",()=>{this.cachedClientRect=this.getBoundingClientRect(),this.dispatchEvent(new CustomEvent("pan"))}),this.addEventListener("mousedown",t=>{this.startPan(t),1===t.buttons&&p.clearSelection()}),this.addEventListener("contextmenu",t=>{let e=u(this,t);h.open(t.pageX,t.pageY,this,e),t.preventDefault()}),m.workspace=this,this.addEventListener("wheel",this.onZoom,{passive:!0})}resetCamera(){this.camera={x:0,y:0,zoom:1},this.dispatchEvent(new CustomEvent("pan")),this.dispatchEvent(new CustomEvent("zoom"))}fitCamera(t,e=25){let o=new s;if(o.AddRange(t),0==o.Count())return;let i=o.OrderBy(t=>t.position.x).First(),n=o.OrderBy(t=>t.position.y).First(),a=o.OrderByDescending(t=>t.position.x+r.map[t.id].scrollWidth).First(),c=o.OrderByDescending(t=>t.position.y+r.map[t.id].scrollHeight).First(),d=r.map[a.id].scrollWidth,h=r.map[c.id].scrollHeight,m={left:i.position.x-e,right:a.position.x+e+d,top:c.position.y+e+h,bottom:n.position.y-e},p=m.right-m.left,l=m.top-m.bottom,u=this.clientRect,v={x:(m.left+m.right)/2,y:(m.top+m.bottom)/2},g=Math.min(u.width/p,u.height/l);this.camera={x:-v.x,y:-v.y,zoom:Math.min(Math.max(this.zoomLowerBound,g),this.zoomUpperBound)},this.dispatchEvent(new CustomEvent("pan")),this.dispatchEvent(new CustomEvent("zoom"))}offsetToWorld(t){let e=this.halfSize;return{x:(t.x-e.x)/this.camera.zoom-this.camera.x,y:(t.y-e.y)/this.camera.zoom-this.camera.y}}worldToOffset(t){let e=this.halfSize;return{x:(t.x+this.camera.x)*this.camera.zoom+e.x,y:(t.y+this.camera.y)*this.camera.zoom+e.y}}pageToOffset(t){let e=this.clientRect;return{x:t.x-e.left,y:t.y-e.top}}pasteAt(t,e){return __awaiter(this,void 0,void 0,function*(){let o=l.getFromClipboard({x:t,y:e});o.nodes.forEach(t=>{m.addNode(t)}),yield this.updateComplete,o.connections.forEach(t=>{m.createConnection(t.from,t.to)})})}firstUpdated(){this.cachedClientRect=this.getBoundingClientRect(),this.application.nodePanel.drawer&&this.application.nodePanel.drawer.addEventListener("or-mwc-drawer-changed",t=>__awaiter(this,void 0,void 0,function*(){this.style.width=t.detail?"calc(100% - 255px)":"",yield this.updateComplete,this.cachedClientRect=this.getBoundingClientRect(),this.dispatchEvent(new CustomEvent("pan"))}))}render(){return e`
2
+ ${n(m.nodes,t=>t.id,t=>e`<flow-node .node="${t}" .workspace="${this}"></flow-node>`)}
3
+ <connection-container .workspace="${this}"></connection-container>
4
+ <svg>
5
+ <line style="display:
6
+ ${this.connectionDragging?null:"none"};
7
+ stroke-dasharray: ${20*this.camera.zoom}, ${10*this.camera.zoom};
8
+ stroke-opacity: 0.25; stroke-width: ${4*this.camera.zoom}px"
9
+
10
+ x1="${this.connectionFrom.x}"
11
+ y1="${this.connectionFrom.y}"
12
+ x2="${this.connectionTo.x}"
13
+ y2="${this.connectionTo.y}"></line>
14
+ </svg>
15
+ <selection-box .workspace="${this}"></selection-box>
16
+ <div class="view-options" style="z-index: ${this.topNodeZindex+1}">
17
+ ${!this.isCameraInDefaultPosition?e`<or-mwc-input type="${v.BUTTON}" icon="vector-square" @or-mwc-input-changed="${this.resetCamera}" label="${c.t("resetView","Reset view")}"></or-mwc-input>`:null}
18
+ ${0!==m.nodes.length?e`<or-mwc-input type="button" icon="fit-to-page-outline" @or-mwc-input-changed="${()=>this.fitCamera(m.nodes)}" label="${c.t("fitView","Fit view")}"></or-mwc-input>`:null}
19
+ </div>
20
+ `}startPan(t){if(this.connectionDragging||4!==t.buttons)return!1;this.isPanning=!0,window.addEventListener("mousemove",this.onMove),window.addEventListener("mouseup",this.stopPan),t.preventDefault()}};__decorate([i({attribute:!1})],EditorWorkspace.prototype,"camera",void 0),__decorate([i({attribute:!1})],EditorWorkspace.prototype,"topNodeZindex",void 0),__decorate([i({attribute:!1})],EditorWorkspace.prototype,"scrollSensitivity",void 0),__decorate([i({attribute:!1})],EditorWorkspace.prototype,"zoomLowerBound",void 0),__decorate([i({attribute:!1})],EditorWorkspace.prototype,"zoomUpperBound",void 0),__decorate([i({attribute:!1})],EditorWorkspace.prototype,"application",void 0),__decorate([i({attribute:!1})],EditorWorkspace.prototype,"connectionDragging",void 0),__decorate([i({attribute:!1})],EditorWorkspace.prototype,"connectionFrom",void 0),__decorate([i({attribute:!1})],EditorWorkspace.prototype,"connectionTo",void 0),EditorWorkspace=__decorate([o("editor-workspace")],EditorWorkspace);export{EditorWorkspace};
@@ -1,160 +1,47 @@
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 { LitElement, html, css } from "lit";
17
- import { customElement, property, query } from "lit/decorators.js";
18
- import { Integration } from "../services/integration";
19
- import { CopyPasteManager } from "../services/copy-paste-manager";
20
- import { Project } from "../services/project";
21
- import { Input } from "../services/input";
22
- import { ModalService } from "../services/modal";
23
- import { Exporter } from "../services/exporter";
24
- import { Shortcuts } from "../services/shortcuts";
25
- import { OrRulesRuleChangedEvent } from "../..";
26
- import { translate, i18next } from "@openremote/or-translate";
27
- import { NodeUtilities } from "../node-structure";
28
- export const integration = new Integration();
29
- export const copyPasteManager = new CopyPasteManager();
30
- export const project = new Project();
31
- export const input = new Input();
32
- export const modal = new ModalService();
33
- export const exporter = new Exporter();
34
- export const shortcuts = new Shortcuts();
35
- export const newIds = new Set();
36
- let FlowEditor = class FlowEditor extends translate(i18next)(LitElement) {
37
- constructor() {
38
- super();
39
- this.showTopbar = false;
40
- }
41
- validate() {
42
- return NodeUtilities.validate(exporter.jsonToFlow(this._ruleset.rules || "{}"));
43
- }
44
- beforeSave() {
45
- if (this.readonly) {
46
- return;
47
- }
48
- this.serialiseRule();
49
- }
50
- set ruleset(ruleset) {
51
- if (this._ruleset === ruleset) {
52
- return;
53
- }
54
- this._ruleset = ruleset;
55
- if (ruleset.rules) {
56
- const collection = exporter.jsonToFlow(ruleset.rules);
57
- project.fromNodeCollection(collection);
58
- project.setCurrentProject(ruleset.id, ruleset.name, collection.description);
59
- }
60
- else {
61
- project.clear(true);
62
- }
63
- }
64
- static get styles() {
65
- return [
66
- css `
67
- :host{
68
- user-select: none;
69
- display: grid;
70
- grid-template-columns: 1fr auto;
71
- grid-template-rows: 100%;
72
- grid-template-areas:
73
- "workspace node-panel";
74
-
75
- width: 100%;
76
- height: 100%;
77
-
78
- --or-app-color4: rgb(76,76,76);
79
-
80
- --socket-size: 24px;
81
- --socket-display-size: 14px;
82
-
83
- --topbar-height: 50px;
84
- --nodepanel-width: 195px;
85
- --roundness: 3px;
86
-
87
- --highlight-faded: hsla(102, 100%, 31%, 0.2);
88
- --highlight: hsla(102, 100%, 31%, 0.5);
89
- --highlight-opaque: hsla(102, 100%, 31%);
90
-
91
- --any: rgb(162, 0, 255);
92
- --number: rgb(165, 228, 50);
93
- --boolean: rgb(0, 102, 255);
94
- --string: rgb(45, 180, 221);
95
- --color: rgb(255, 228, 78);
96
-
97
- --input-color: hsl(222, 60%, 46%);
98
- --processor-color: hsl(102, 58%, 39%);
99
- --output-color: hsl(282, 60%, 47%);
100
-
101
- --input-color-h: hsl(222, 58%, 54%);
102
- --processor-color-h: hsl(102, 48%, 49%);
103
- --output-color-h: hsl(282, 58%, 54%);
104
-
105
- overflow: hidden;
106
- }`
107
- ];
108
- }
109
- firstUpdated() {
110
- return __awaiter(this, void 0, void 0, function* () {
111
- yield integration.refreshNodes();
112
- this.requestUpdate();
113
- yield this.updateComplete;
114
- project.emit("fitview");
115
- project.addListener("changed", () => {
116
- this.serialiseRule();
117
- this.dispatchEvent(new OrRulesRuleChangedEvent(this.validate()));
118
- });
119
- });
120
- }
121
- render() {
122
- if (this.showTopbar) {
123
- this.style.gridTemplateRows = "var(--topbar-height) 1fr";
124
- this.style.gridTemplateAreas = '"topbar topbar" "workspace node-panel";';
125
- }
126
- return html `
127
- ${(this.showTopbar ? html `<top-bar .application="${this}" style="grid-area: topbar"></top-bar>` : ``)}
128
- <node-panel .application="${this}" style="grid-area: node-panel; overflow:auto;" .nodes= "${integration.nodes}"></node-panel>
129
- <editor-workspace .application="${this}" id="workspace" style="grid-area: workspace"></editor-workspace>
130
- <context-menu></context-menu>
131
- <popup-modal id="popup-modal"></popup-modal>
132
- `;
133
- }
134
- serialiseRule() {
135
- this._ruleset.rules = exporter.flowToJson(project.toNodeCollection(this._ruleset.name, project.existingFlowRuleDesc));
136
- }
137
- };
138
- __decorate([
139
- query("node-panel")
140
- ], FlowEditor.prototype, "nodePanel", void 0);
141
- __decorate([
142
- query("top-bar")
143
- ], FlowEditor.prototype, "topBar", void 0);
144
- __decorate([
145
- query("editor-workspace")
146
- ], FlowEditor.prototype, "editorWorkspace", void 0);
147
- __decorate([
148
- property({ type: Boolean })
149
- ], FlowEditor.prototype, "showTopbar", void 0);
150
- __decorate([
151
- property({ attribute: false })
152
- ], FlowEditor.prototype, "readonly", void 0);
153
- __decorate([
154
- property({ attribute: false })
155
- ], FlowEditor.prototype, "_ruleset", void 0);
156
- FlowEditor = __decorate([
157
- customElement("flow-editor")
158
- ], FlowEditor);
159
- export { FlowEditor };
160
- //# sourceMappingURL=flow-editor.js.map
1
+ var __decorate=this&&this.__decorate||function(e,t,o,r){var i,s=arguments.length,a=s<3?t:null===r?r=Object.getOwnPropertyDescriptor(t,o):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)a=Reflect.decorate(e,t,o,r);else for(var p=e.length-1;p>=0;p--)(i=e[p])&&(a=(s<3?i(a):s>3?i(t,o,a):i(t,o))||a);return s>3&&a&&Object.defineProperty(t,o,a),a},__awaiter=this&&this.__awaiter||function(e,t,o,r){return new(o||(o=Promise))(function(i,s){function a(e){try{n(r.next(e))}catch(e){s(e)}}function p(e){try{n(r.throw(e))}catch(e){s(e)}}function n(e){var t;e.done?i(e.value):((t=e.value)instanceof o?t:new o(function(e){e(t)})).then(a,p)}n((r=r.apply(e,t||[])).next())})};import{LitElement as e,html as t,css as o}from"lit";import{customElement as r,property as i,query as s}from"lit/decorators.js";import{Integration as a}from"../services/integration";import{CopyPasteManager as p}from"../services/copy-paste-manager";import{Project as n}from"../services/project";import{Input as l}from"../services/input";import{ModalService as c}from"../services/modal";import{Exporter as d}from"../services/exporter";import{Shortcuts as h}from"../services/shortcuts";import{OrRulesRuleChangedEvent as u}from"../..";import{translate as w,i18next as m}from"@openremote/or-translate";import{NodeUtilities as f}from"../node-structure";export const integration=new a;export const copyPasteManager=new p;export const project=new n;export const input=new l;export const modal=new c;export const exporter=new d;export const shortcuts=new h;export const newIds=new Set;let FlowEditor=class extends w(m)(e){constructor(){super(),this.showTopbar=!1}validate(){return f.validate(exporter.jsonToFlow(this._ruleset.rules||"{}"))}beforeSave(){this.readonly||this.serialiseRule()}set ruleset(e){if(this._ruleset!==e)if(this._ruleset=e,e.rules){let t=exporter.jsonToFlow(e.rules);project.fromNodeCollection(t),project.setCurrentProject(e.id,e.name,t.description)}else project.clear(!0)}static get styles(){return[o`
2
+ :host{
3
+ user-select: none;
4
+ display: grid;
5
+ grid-template-columns: 1fr auto;
6
+ grid-template-rows: 100%;
7
+ grid-template-areas:
8
+ "workspace node-panel";
9
+
10
+ width: 100%;
11
+ height: 100%;
12
+
13
+ --or-app-color4: rgb(76,76,76);
14
+
15
+ --socket-size: 24px;
16
+ --socket-display-size: 14px;
17
+
18
+ --topbar-height: 50px;
19
+ --nodepanel-width: 195px;
20
+ --roundness: 3px;
21
+
22
+ --highlight-faded: hsla(102, 100%, 31%, 0.2);
23
+ --highlight: hsla(102, 100%, 31%, 0.5);
24
+ --highlight-opaque: hsla(102, 100%, 31%);
25
+
26
+ --any: rgb(162, 0, 255);
27
+ --number: rgb(165, 228, 50);
28
+ --boolean: rgb(0, 102, 255);
29
+ --string: rgb(45, 180, 221);
30
+ --color: rgb(255, 228, 78);
31
+
32
+ --input-color: hsl(222, 60%, 46%);
33
+ --processor-color: hsl(102, 58%, 39%);
34
+ --output-color: hsl(282, 60%, 47%);
35
+
36
+ --input-color-h: hsl(222, 58%, 54%);
37
+ --processor-color-h: hsl(102, 48%, 49%);
38
+ --output-color-h: hsl(282, 58%, 54%);
39
+
40
+ overflow: hidden;
41
+ }`]}firstUpdated(){return __awaiter(this,void 0,void 0,function*(){yield integration.refreshNodes(),this.requestUpdate(),yield this.updateComplete,project.emit("fitview"),project.addListener("changed",()=>{this.serialiseRule(),this.dispatchEvent(new u(this.validate()))})})}render(){return this.showTopbar&&(this.style.gridTemplateRows="var(--topbar-height) 1fr",this.style.gridTemplateAreas='"topbar topbar" "workspace node-panel";'),t`
42
+ ${this.showTopbar?t`<top-bar .application="${this}" style="grid-area: topbar"></top-bar>`:""}
43
+ <node-panel .application="${this}" style="grid-area: node-panel; overflow:auto;" .nodes= "${integration.nodes}"></node-panel>
44
+ <editor-workspace .application="${this}" id="workspace" style="grid-area: workspace"></editor-workspace>
45
+ <context-menu></context-menu>
46
+ <popup-modal id="popup-modal"></popup-modal>
47
+ `}serialiseRule(){this._ruleset.rules=exporter.flowToJson(project.toNodeCollection(this._ruleset.name,project.existingFlowRuleDesc))}};__decorate([s("node-panel")],FlowEditor.prototype,"nodePanel",void 0),__decorate([s("top-bar")],FlowEditor.prototype,"topBar",void 0),__decorate([s("editor-workspace")],FlowEditor.prototype,"editorWorkspace",void 0),__decorate([i({type:Boolean})],FlowEditor.prototype,"showTopbar",void 0),__decorate([i({attribute:!1})],FlowEditor.prototype,"readonly",void 0),__decorate([i({attribute:!1})],FlowEditor.prototype,"_ruleset",void 0),FlowEditor=__decorate([r("flow-editor")],FlowEditor);export{FlowEditor};