@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.
- package/README.md +30 -30
- package/custom-elements.json +13 -13
- package/dist/umd/index.bundle.js +4744 -4744
- package/dist/umd/index.bundle.js.map +1 -1
- package/lib/flow-viewer/components/confirmation-dialog.js +61 -24
- package/lib/flow-viewer/components/connection-container.js +35 -1
- package/lib/flow-viewer/components/connection-line.js +117 -28
- package/lib/flow-viewer/components/context-menu.js +140 -45
- package/lib/flow-viewer/components/editor-workspace.js +282 -20
- package/lib/flow-viewer/components/flow-editor.js +160 -47
- package/lib/flow-viewer/components/flow-node-socket.js +146 -31
- package/lib/flow-viewer/components/flow-node.js +192 -29
- package/lib/flow-viewer/components/internal-picker.js +271 -54
- package/lib/flow-viewer/components/node-menu-item.js +132 -32
- package/lib/flow-viewer/components/node-panel.js +104 -60
- package/lib/flow-viewer/components/notification-dialog.js +55 -23
- package/lib/flow-viewer/components/popup-modal.js +113 -54
- package/lib/flow-viewer/components/rule-browser.js +119 -30
- package/lib/flow-viewer/components/selectable-element.js +71 -1
- package/lib/flow-viewer/components/selection-box.js +119 -15
- package/lib/flow-viewer/components/top-bar.js +116 -49
- package/lib/flow-viewer/components/workspace-contextmenu-options.js +128 -5
- package/lib/flow-viewer/components/writable-dropdown.js +51 -5
- package/lib/flow-viewer/converters/node-converter.js +10 -1
- package/lib/flow-viewer/flow-viewer.js +19 -1
- package/lib/flow-viewer/models/camera.js +2 -1
- package/lib/flow-viewer/models/context-menu-button.js +2 -1
- package/lib/flow-viewer/models/light-node-collection.js +2 -1
- package/lib/flow-viewer/models/status.js +8 -1
- package/lib/flow-viewer/node-structure/copy.machine.js +34 -1
- package/lib/flow-viewer/node-structure/identity.assigner.js +10 -1
- package/lib/flow-viewer/node-structure/identity.dom.link.js +4 -1
- package/lib/flow-viewer/node-structure/index.js +5 -1
- package/lib/flow-viewer/node-structure/socket.type.matcher.js +50 -1
- package/lib/flow-viewer/node-structure/utils.js +109 -1
- package/lib/flow-viewer/services/copy-paste-manager.js +59 -1
- package/lib/flow-viewer/services/exporter.js +67 -1
- package/lib/flow-viewer/services/input.js +80 -1
- package/lib/flow-viewer/services/integration.js +27 -1
- package/lib/flow-viewer/services/modal.js +29 -8
- package/lib/flow-viewer/services/project.js +222 -1
- package/lib/flow-viewer/services/shortcuts.js +63 -1
- package/lib/flow-viewer/styles/editor-workspace-style.js +55 -53
- package/lib/flow-viewer/styles/flow-node-style.js +95 -93
- package/lib/flow-viewer/styles/picker-styles.js +31 -29
- package/lib/flow-viewer/utils.js +49 -1
- package/lib/index.js +953 -56
- package/lib/json-viewer/forms/or-rule-form-alarm.js +91 -18
- package/lib/json-viewer/forms/or-rule-form-email-message.js +51 -12
- package/lib/json-viewer/forms/or-rule-form-localized.js +269 -43
- package/lib/json-viewer/forms/or-rule-form-push-notification.js +152 -63
- package/lib/json-viewer/forms/or-rule-form-webhook.js +296 -101
- package/lib/json-viewer/modals/or-rule-alarm-modal.js +173 -17
- package/lib/json-viewer/modals/or-rule-notification-modal.js +196 -11
- package/lib/json-viewer/modals/or-rule-radial-modal.js +142 -17
- package/lib/json-viewer/modals/or-rule-webhook-modal.js +78 -8
- package/lib/json-viewer/or-rule-action-alarm.js +97 -5
- package/lib/json-viewer/or-rule-action-attribute.js +235 -33
- package/lib/json-viewer/or-rule-action-notification.js +465 -56
- package/lib/json-viewer/or-rule-action-webhook.js +49 -18
- package/lib/json-viewer/or-rule-asset-query.js +849 -126
- package/lib/json-viewer/or-rule-condition.js +216 -29
- package/lib/json-viewer/or-rule-json-viewer.js +393 -34
- package/lib/json-viewer/or-rule-then-otherwise.js +609 -113
- package/lib/json-viewer/or-rule-trigger-query.js +227 -57
- package/lib/json-viewer/or-rule-when.js +343 -126
- package/lib/or-rule-group-viewer.js +106 -12
- package/lib/or-rule-text-viewer.js +133 -22
- package/lib/or-rule-tree.js +601 -57
- package/lib/or-rule-validity.js +373 -62
- package/lib/or-rule-viewer.js +361 -81
- package/lib/style.js +89 -64
- package/package.json +11 -11
|
@@ -1 +1,8 @@
|
|
|
1
|
-
export var Status
|
|
1
|
+
export var Status;
|
|
2
|
+
(function (Status) {
|
|
3
|
+
Status[Status["Idle"] = 0] = "Idle";
|
|
4
|
+
Status[Status["Loading"] = 1] = "Loading";
|
|
5
|
+
Status[Status["Success"] = 2] = "Success";
|
|
6
|
+
Status[Status["Failure"] = 3] = "Failure";
|
|
7
|
+
})(Status || (Status = {}));
|
|
8
|
+
//# sourceMappingURL=status.js.map
|
|
@@ -1 +1,34 @@
|
|
|
1
|
-
import{IdentityAssigner
|
|
1
|
+
import { IdentityAssigner } from "./identity.assigner";
|
|
2
|
+
export class CopyMachine {
|
|
3
|
+
static copy(node) {
|
|
4
|
+
const minimalNode = {};
|
|
5
|
+
minimalNode.inputs = (node.inputs || []).map((i) => {
|
|
6
|
+
return {
|
|
7
|
+
name: i.name, type: i.type
|
|
8
|
+
};
|
|
9
|
+
});
|
|
10
|
+
minimalNode.internals = node.internals || [];
|
|
11
|
+
minimalNode.name = node.name;
|
|
12
|
+
minimalNode.displayCharacter = node.displayCharacter;
|
|
13
|
+
minimalNode.outputs = (node.outputs || []).map((i) => {
|
|
14
|
+
return {
|
|
15
|
+
name: i.name, type: i.type
|
|
16
|
+
};
|
|
17
|
+
});
|
|
18
|
+
minimalNode.type = node.type;
|
|
19
|
+
minimalNode.position = { x: 0, y: 0 };
|
|
20
|
+
minimalNode.size = { x: 0, y: 0 };
|
|
21
|
+
const clone = JSON.parse(JSON.stringify(minimalNode));
|
|
22
|
+
clone.id = IdentityAssigner.generateIdentity();
|
|
23
|
+
clone.inputs.forEach((socket) => {
|
|
24
|
+
socket.nodeId = clone.id;
|
|
25
|
+
socket.id = IdentityAssigner.generateIdentity();
|
|
26
|
+
});
|
|
27
|
+
clone.outputs.forEach((socket) => {
|
|
28
|
+
socket.nodeId = clone.id;
|
|
29
|
+
socket.id = IdentityAssigner.generateIdentity();
|
|
30
|
+
});
|
|
31
|
+
return clone;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=copy.machine.js.map
|
|
@@ -1 +1,10 @@
|
|
|
1
|
-
import
|
|
1
|
+
import ShortID from "shortid";
|
|
2
|
+
export class IdentityAssigner {
|
|
3
|
+
static generateIdentity() {
|
|
4
|
+
return ShortID.generate();
|
|
5
|
+
}
|
|
6
|
+
static getSocketElementIdentity(socket) {
|
|
7
|
+
return socket.id;
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=identity.assigner.js.map
|
|
@@ -1 +1,5 @@
|
|
|
1
|
-
export{NodeUtilities}from"./utils";
|
|
1
|
+
export { NodeUtilities } from "./utils";
|
|
2
|
+
export { IdentityAssigner } from "./identity.assigner";
|
|
3
|
+
export { IdentityDomLink } from "./identity.dom.link";
|
|
4
|
+
export { CopyMachine } from "./copy.machine";
|
|
5
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1,50 @@
|
|
|
1
|
-
export class SocketTypeMatcher
|
|
1
|
+
export class SocketTypeMatcher {
|
|
2
|
+
static match(a, b) {
|
|
3
|
+
return a === "ANY" /* NodeDataType.ANY */ ||
|
|
4
|
+
b === "ANY" /* NodeDataType.ANY */ ||
|
|
5
|
+
SocketTypeMatcher.matches.find((t) => t.type === a).matches.includes(b);
|
|
6
|
+
}
|
|
7
|
+
}
|
|
8
|
+
SocketTypeMatcher.matches = [
|
|
9
|
+
{
|
|
10
|
+
type: "NUMBER" /* NodeDataType.NUMBER */,
|
|
11
|
+
matches: [
|
|
12
|
+
"NUMBER" /* NodeDataType.NUMBER */,
|
|
13
|
+
"STRING" /* NodeDataType.STRING */,
|
|
14
|
+
"NUMBER_ARRAY" /* NodeDataType.NUMBER_ARRAY */
|
|
15
|
+
]
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
type: "STRING" /* NodeDataType.STRING */,
|
|
19
|
+
matches: [
|
|
20
|
+
"STRING" /* NodeDataType.STRING */,
|
|
21
|
+
]
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
type: "TRIGGER" /* NodeDataType.TRIGGER */,
|
|
25
|
+
matches: [
|
|
26
|
+
"TRIGGER" /* NodeDataType.TRIGGER */,
|
|
27
|
+
]
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
type: "BOOLEAN" /* NodeDataType.BOOLEAN */,
|
|
31
|
+
matches: [
|
|
32
|
+
"BOOLEAN" /* NodeDataType.BOOLEAN */,
|
|
33
|
+
"STRING" /* NodeDataType.STRING */,
|
|
34
|
+
]
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
type: "COLOR" /* NodeDataType.COLOR */,
|
|
38
|
+
matches: [
|
|
39
|
+
"COLOR" /* NodeDataType.COLOR */,
|
|
40
|
+
"STRING" /* NodeDataType.STRING */,
|
|
41
|
+
]
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
type: "NUMBER_ARRAY" /* NodeDataType.NUMBER_ARRAY */,
|
|
45
|
+
matches: [
|
|
46
|
+
"NUMBER" /* NodeDataType.NUMBER */
|
|
47
|
+
]
|
|
48
|
+
}
|
|
49
|
+
];
|
|
50
|
+
//# sourceMappingURL=socket.type.matcher.js.map
|
|
@@ -1 +1,109 @@
|
|
|
1
|
-
export class NodeUtilities
|
|
1
|
+
export class NodeUtilities {
|
|
2
|
+
static getNodeFromID(id, nodes) {
|
|
3
|
+
const node = nodes.find((n) => n.id === id);
|
|
4
|
+
if (!node) {
|
|
5
|
+
console.warn(`Node with ID ${id} not found`);
|
|
6
|
+
}
|
|
7
|
+
return node;
|
|
8
|
+
}
|
|
9
|
+
static getSocketFromID(id, nodes) {
|
|
10
|
+
for (const node of nodes) {
|
|
11
|
+
for (const input of node.inputs) {
|
|
12
|
+
if (input.id === id) {
|
|
13
|
+
return input;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
for (const output of node.outputs) {
|
|
17
|
+
if (output.id === id) {
|
|
18
|
+
return output;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
static convertValueTypeToSocketType(value) {
|
|
24
|
+
switch (value.jsonType) {
|
|
25
|
+
case "boolean": return "BOOLEAN" /* NodeDataType.BOOLEAN */;
|
|
26
|
+
case "number":
|
|
27
|
+
case "bigint": return "NUMBER" /* NodeDataType.NUMBER */;
|
|
28
|
+
case "string": return "STRING" /* NodeDataType.STRING */;
|
|
29
|
+
default: return "ANY" /* NodeDataType.ANY */;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
static backtrackFrom(collection, nodeId) {
|
|
33
|
+
if (!collection) {
|
|
34
|
+
throw new Error("Collection has to exist");
|
|
35
|
+
}
|
|
36
|
+
if (!collection.nodes) {
|
|
37
|
+
throw new Error("Collection has to have existing nodes");
|
|
38
|
+
}
|
|
39
|
+
if (!collection.connections) {
|
|
40
|
+
throw new Error("Collection has to have existing connections");
|
|
41
|
+
}
|
|
42
|
+
const node = this.getNodeFromID(nodeId, collection.nodes);
|
|
43
|
+
if (!node) {
|
|
44
|
+
throw new Error("Node has to exist");
|
|
45
|
+
}
|
|
46
|
+
if (!node.inputs) {
|
|
47
|
+
throw new Error("Node has to have existing inputs");
|
|
48
|
+
}
|
|
49
|
+
if (!node.outputs) {
|
|
50
|
+
throw new Error("Node has to have existing outputs");
|
|
51
|
+
}
|
|
52
|
+
let total = [];
|
|
53
|
+
let children = [];
|
|
54
|
+
for (const s of node.inputs) {
|
|
55
|
+
children = children.concat(collection.connections.
|
|
56
|
+
filter((c) => c.to === s.id).
|
|
57
|
+
map((c) => this.getNodeFromID(this.getSocketFromID(c.from, collection.nodes).nodeId, collection.nodes)));
|
|
58
|
+
}
|
|
59
|
+
for (const child of children) {
|
|
60
|
+
total.push(child);
|
|
61
|
+
const result = this.backtrackFrom(collection, child.id);
|
|
62
|
+
total = total.concat(result);
|
|
63
|
+
}
|
|
64
|
+
return total;
|
|
65
|
+
}
|
|
66
|
+
static validate(collection) {
|
|
67
|
+
if (!collection) {
|
|
68
|
+
return false;
|
|
69
|
+
}
|
|
70
|
+
if (!collection.nodes) {
|
|
71
|
+
return false;
|
|
72
|
+
}
|
|
73
|
+
if (!collection.connections) {
|
|
74
|
+
return false;
|
|
75
|
+
}
|
|
76
|
+
const outputNodes = collection.nodes.filter((n) => n.type === "OUTPUT" /* NodeType.OUTPUT */);
|
|
77
|
+
if (outputNodes.length === 0) {
|
|
78
|
+
return false;
|
|
79
|
+
}
|
|
80
|
+
for (const output of outputNodes) {
|
|
81
|
+
const tree = this.backtrackFrom(collection, output.id);
|
|
82
|
+
if (tree.length === 0) {
|
|
83
|
+
return false;
|
|
84
|
+
}
|
|
85
|
+
if (tree.filter((n) => n.type === "INPUT" /* NodeType.INPUT */).length === 0) {
|
|
86
|
+
return false;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
return true;
|
|
90
|
+
}
|
|
91
|
+
static add(a, b) {
|
|
92
|
+
return { x: a.x + b.x, y: a.y + b.y };
|
|
93
|
+
}
|
|
94
|
+
static subtract(a, b) {
|
|
95
|
+
return { x: a.x - b.x, y: a.y - b.y };
|
|
96
|
+
}
|
|
97
|
+
static multiply(a, b) {
|
|
98
|
+
return { x: a.x * b, y: a.y * b };
|
|
99
|
+
}
|
|
100
|
+
static lerpNumber(x, y, t) {
|
|
101
|
+
return x * (1 - t) + y * t;
|
|
102
|
+
}
|
|
103
|
+
static lerp(a, b, t) {
|
|
104
|
+
const x = this.lerpNumber(a.x, b.x, t);
|
|
105
|
+
const y = this.lerpNumber(a.y, b.y, t);
|
|
106
|
+
return { x, y };
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
//# sourceMappingURL=utils.js.map
|
|
@@ -1 +1,59 @@
|
|
|
1
|
-
import{IdentityAssigner
|
|
1
|
+
import { IdentityAssigner } from "../node-structure";
|
|
2
|
+
import { input } from "../components/flow-editor";
|
|
3
|
+
import { FlowNode, ConnectionLine } from "../flow-viewer";
|
|
4
|
+
export class CopyPasteManager {
|
|
5
|
+
get isFull() { return !!!this.clipboard; }
|
|
6
|
+
putInClipboard(obj, origin) {
|
|
7
|
+
this.copyOrigin = origin;
|
|
8
|
+
this.clipboard = obj;
|
|
9
|
+
}
|
|
10
|
+
getFromClipboard(newOrigin) {
|
|
11
|
+
const clone = this.cloneIsolated(this.clipboard, 0);
|
|
12
|
+
const offset = {
|
|
13
|
+
x: newOrigin.x - this.copyOrigin.x,
|
|
14
|
+
y: newOrigin.y - this.copyOrigin.y,
|
|
15
|
+
};
|
|
16
|
+
clone.nodes.forEach((node) => {
|
|
17
|
+
node.position.x += offset.x;
|
|
18
|
+
node.position.y += offset.y;
|
|
19
|
+
});
|
|
20
|
+
return clone;
|
|
21
|
+
}
|
|
22
|
+
cloneIsolated(obj, positionOffset = 50) {
|
|
23
|
+
const remapped = {};
|
|
24
|
+
const clone = JSON.parse(JSON.stringify(obj));
|
|
25
|
+
clone.nodes.forEach((node) => {
|
|
26
|
+
const newNodeID = IdentityAssigner.generateIdentity();
|
|
27
|
+
remapped[node.id] = newNodeID;
|
|
28
|
+
node.position.x += positionOffset;
|
|
29
|
+
node.position.y += positionOffset;
|
|
30
|
+
node.id = newNodeID;
|
|
31
|
+
node.inputs.forEach((inputSocket) => {
|
|
32
|
+
const newSocketID = IdentityAssigner.generateIdentity();
|
|
33
|
+
remapped[inputSocket.id] = newSocketID;
|
|
34
|
+
inputSocket.id = newSocketID;
|
|
35
|
+
inputSocket.nodeId = newNodeID;
|
|
36
|
+
});
|
|
37
|
+
node.outputs.forEach((outputSocket) => {
|
|
38
|
+
const newSocketID = IdentityAssigner.generateIdentity();
|
|
39
|
+
remapped[outputSocket.id] = newSocketID;
|
|
40
|
+
outputSocket.id = newSocketID;
|
|
41
|
+
outputSocket.nodeId = newNodeID;
|
|
42
|
+
});
|
|
43
|
+
});
|
|
44
|
+
clone.connections.forEach((connection) => {
|
|
45
|
+
connection.from = remapped[connection.from];
|
|
46
|
+
connection.to = remapped[connection.to];
|
|
47
|
+
});
|
|
48
|
+
return clone;
|
|
49
|
+
}
|
|
50
|
+
copy(x, y) {
|
|
51
|
+
const selectedNodes = input.selected.filter((s) => s instanceof FlowNode && s.selected);
|
|
52
|
+
const selectedConnections = input.selected.filter((s) => s instanceof ConnectionLine && s.selected);
|
|
53
|
+
this.putInClipboard({
|
|
54
|
+
nodes: selectedNodes.map((n) => n.node),
|
|
55
|
+
connections: selectedConnections.map((c) => c.connection)
|
|
56
|
+
}, { x, y });
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=copy-paste-manager.js.map
|
|
@@ -1 +1,67 @@
|
|
|
1
|
-
import
|
|
1
|
+
import manager from "@openremote/core";
|
|
2
|
+
import { project, modal } from "../components/flow-editor";
|
|
3
|
+
export class Exporter {
|
|
4
|
+
flowToJson(collection) {
|
|
5
|
+
return JSON.stringify(collection);
|
|
6
|
+
}
|
|
7
|
+
jsonToFlow(json) {
|
|
8
|
+
return JSON.parse(json);
|
|
9
|
+
}
|
|
10
|
+
collectionToRuleset(collection, type) {
|
|
11
|
+
const ruleset = {
|
|
12
|
+
lang: "FLOW" /* RulesetLang.FLOW */,
|
|
13
|
+
name: collection.name,
|
|
14
|
+
type,
|
|
15
|
+
rules: this.flowToJson(collection),
|
|
16
|
+
};
|
|
17
|
+
return ruleset;
|
|
18
|
+
}
|
|
19
|
+
rulesetToCollection(ruleset) {
|
|
20
|
+
return this.jsonToFlow(ruleset.rules);
|
|
21
|
+
}
|
|
22
|
+
exportAsNew(collection) {
|
|
23
|
+
const json = this.flowToJson(collection);
|
|
24
|
+
const ruleApi = manager.rest.api.RulesResource;
|
|
25
|
+
const rs = {
|
|
26
|
+
lang: "FLOW" /* RulesetLang.FLOW */,
|
|
27
|
+
name: collection.name,
|
|
28
|
+
type: "global",
|
|
29
|
+
rules: json
|
|
30
|
+
};
|
|
31
|
+
ruleApi.createGlobalRuleset(rs).then((e) => {
|
|
32
|
+
if (e.status === 200) {
|
|
33
|
+
project.setCurrentProject(e.data, collection.name, collection.description);
|
|
34
|
+
console.log("Successfully saved new ruleset");
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
console.log("Something went wrong while saving NEW ruleset\nHTTP status " + e.status);
|
|
38
|
+
modal.notification("Failure", `Something went wrong while saving ${rs.name}`);
|
|
39
|
+
}
|
|
40
|
+
}).catch((e) => {
|
|
41
|
+
console.log("Something went wrong while saving NEW ruleset\nHTTP status " + e);
|
|
42
|
+
modal.notification("Failure", `Something went wrong while saving ${rs.name}`);
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
exportAsExisting(id, collection) {
|
|
46
|
+
const json = this.flowToJson(collection);
|
|
47
|
+
const ruleApi = manager.rest.api.RulesResource;
|
|
48
|
+
ruleApi.getGlobalRuleset(project.existingFlowRuleId).then((response) => {
|
|
49
|
+
const existing = response.data;
|
|
50
|
+
existing.rules = json;
|
|
51
|
+
ruleApi.updateGlobalRuleset(existing.id, existing).then((e) => {
|
|
52
|
+
if (e.status === 204) {
|
|
53
|
+
project.unsavedState = false;
|
|
54
|
+
console.log("Successfully saved ruleset");
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
console.log("Something went wrong while saving EXISTING ruleset\n" + e.status);
|
|
58
|
+
modal.notification("Failure", `Something went wrong while saving ${collection.name}`);
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
}).catch((e) => {
|
|
62
|
+
console.log("Something went wrong while saving EXISTING ruleset\n" + e);
|
|
63
|
+
modal.notification("Failure", `Something went wrong while saving ${collection.name}`);
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=exporter.js.map
|
|
@@ -1 +1,80 @@
|
|
|
1
|
-
import{EventEmitter
|
|
1
|
+
import { EventEmitter } from "events";
|
|
2
|
+
import { project } from "../components/flow-editor";
|
|
3
|
+
export class Input extends EventEmitter {
|
|
4
|
+
constructor() {
|
|
5
|
+
super();
|
|
6
|
+
this.selected = [];
|
|
7
|
+
this.selectables = [];
|
|
8
|
+
this.keysCurrentlyHeld = [];
|
|
9
|
+
this.onkeydown = (e) => {
|
|
10
|
+
if (this.keysCurrentlyHeld.includes(e.key)) {
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
this.keysCurrentlyHeld.push(e.key);
|
|
14
|
+
};
|
|
15
|
+
this.onkeyup = (e) => {
|
|
16
|
+
const index = this.keysCurrentlyHeld.indexOf(e.key);
|
|
17
|
+
if (index === -1) {
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
this.keysCurrentlyHeld.splice(index, 1);
|
|
21
|
+
};
|
|
22
|
+
window.addEventListener("keydown", this.onkeydown);
|
|
23
|
+
window.addEventListener("keyup", this.onkeyup);
|
|
24
|
+
window.addEventListener("blur", () => {
|
|
25
|
+
this.clearSelection();
|
|
26
|
+
this.keysCurrentlyHeld = [];
|
|
27
|
+
});
|
|
28
|
+
project.addListener("cleared", () => { this.clearSelection(); });
|
|
29
|
+
this.setMaxListeners(1024);
|
|
30
|
+
}
|
|
31
|
+
select(element, forceMultipleSelection = false) {
|
|
32
|
+
if (!this.multiSelectedEnabled && !forceMultipleSelection) {
|
|
33
|
+
this.clearSelection();
|
|
34
|
+
}
|
|
35
|
+
if (this.selected.includes(element)) {
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
this.emit("selected", element);
|
|
39
|
+
if (element.selected) {
|
|
40
|
+
this.selected.push(element);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
deselect(element) {
|
|
44
|
+
const index = this.selected.indexOf(element);
|
|
45
|
+
if (index === -1) {
|
|
46
|
+
console.warn("Attempt to deselect nonexistent node");
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
this.emit("deselected", element);
|
|
50
|
+
if (!element.selected) {
|
|
51
|
+
this.selected.splice(index, 1);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
handleSelection(element, neverDeselect = false) {
|
|
55
|
+
if (!this.multiSelectedEnabled && this.selected.length > 1) {
|
|
56
|
+
this.select(element);
|
|
57
|
+
}
|
|
58
|
+
else if (this.selected.includes(element) && !neverDeselect) {
|
|
59
|
+
this.deselect(element);
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
this.select(element);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
clearSelection(ignoreMultiselect = false) {
|
|
66
|
+
if (this.multiSelectedEnabled && !ignoreMultiselect) {
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
this.selected.forEach((e) => this.emit("deselected", e));
|
|
70
|
+
this.selected = [];
|
|
71
|
+
this.emit("selectioncleared");
|
|
72
|
+
}
|
|
73
|
+
isHeld(key) {
|
|
74
|
+
return this.keysCurrentlyHeld.includes(key);
|
|
75
|
+
}
|
|
76
|
+
get multiSelectedEnabled() {
|
|
77
|
+
return this.isHeld("Shift") || this.isHeld("Control");
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=input.js.map
|
|
@@ -1 +1,27 @@
|
|
|
1
|
-
var __awaiter=this&&this.__awaiter
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
import rest from "@openremote/rest";
|
|
11
|
+
import { EventEmitter } from "events";
|
|
12
|
+
export class Integration extends EventEmitter {
|
|
13
|
+
constructor() {
|
|
14
|
+
super(...arguments);
|
|
15
|
+
this.nodes = [];
|
|
16
|
+
}
|
|
17
|
+
refreshNodes() {
|
|
18
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
19
|
+
this.nodes = [];
|
|
20
|
+
const allNodes = (yield rest.api.FlowResource.getAllNodeDefinitions()).data;
|
|
21
|
+
for (const n of allNodes) {
|
|
22
|
+
this.nodes.push(n);
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=integration.js.map
|
|
@@ -1,8 +1,29 @@
|
|
|
1
|
-
import{html
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
.
|
|
7
|
-
@
|
|
8
|
-
|
|
1
|
+
import { html } from "lit";
|
|
2
|
+
import { i18next } from "@openremote/or-translate";
|
|
3
|
+
export class ModalService {
|
|
4
|
+
confirmation(agreeCallback, header = i18next.t("flowEditor", "Flow editor"), question = i18next.t("areYouSure", "Are you sure?")) {
|
|
5
|
+
this.element.content = html `<confirmation-dialog
|
|
6
|
+
.question = "${question}"
|
|
7
|
+
@agreed="${() => { if (agreeCallback) {
|
|
8
|
+
agreeCallback();
|
|
9
|
+
} this.element.close(); }}"
|
|
10
|
+
@disagreed="${this.element.close}"
|
|
11
|
+
></confirmation-dialog>`;
|
|
12
|
+
this.element.header = header;
|
|
13
|
+
this.element.open();
|
|
14
|
+
}
|
|
15
|
+
notification(header, message, buttonText = i18next.t("ok", "OK")) {
|
|
16
|
+
this.element.content = html `<notification-dialog
|
|
17
|
+
.message = "${message}"
|
|
18
|
+
@closed = "${this.element.close}"
|
|
19
|
+
></notification-dialog>`;
|
|
20
|
+
this.element.header = header;
|
|
21
|
+
this.element.open();
|
|
22
|
+
}
|
|
23
|
+
anything(header, content) {
|
|
24
|
+
this.element.content = content;
|
|
25
|
+
this.element.header = header;
|
|
26
|
+
this.element.open();
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=modal.js.map
|