@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,20 +1,282 @@
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
+ 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,47 +1,160 @@
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};
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