@5minds/node-red-contrib-processcube 2.0.0-feature-629c78-m2dq1ygt → 7.6.0-develop-51b534-mjy3s4sm
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 +3 -58
- package/check-authorization.html +138 -0
- package/check-authorization.js +27 -0
- package/dataobject-instance-query.html +141 -0
- package/dataobject-instance-query.js +45 -0
- package/endevent-finished-listener.js +14 -25
- package/examples/Check-Authorization-Sample.json +109 -0
- package/examples/Dataobject-Instance-Query-Sample.json +109 -0
- package/externaltask-error.html +8 -3
- package/externaltask-error.js +43 -29
- package/externaltask-event-listener.js +11 -28
- package/externaltask-input.html +48 -3
- package/externaltask-input.js +581 -114
- package/externaltask-output.js +20 -16
- package/icons/data-object-query.svg +5 -0
- package/message-event-trigger.html +1 -1
- package/message-event-trigger.js +8 -7
- package/package.json +74 -67
- package/process-event-listener.js +166 -225
- package/process-start.html +6 -0
- package/process-start.js +29 -6
- package/process-terminate.html +1 -1
- package/process-terminate.js +7 -5
- package/processcube-engine-config.html +25 -7
- package/processcube-engine-config.js +25 -135
- package/processcube-google-docs-mail-template.html +150 -0
- package/processcube-google-docs-mail-template.js +158 -0
- package/processdefinition-deploy.html +44 -0
- package/processdefinition-deploy.js +28 -0
- package/processdefinition-query.html +18 -13
- package/processdefinition-query.js +33 -31
- package/processinstance-delete-advanced.html +82 -0
- package/processinstance-delete-advanced.js +33 -0
- package/processinstance-delete.html +60 -8
- package/processinstance-delete.js +84 -30
- package/processinstance-query.html +116 -109
- package/processinstance-query.js +28 -5
- package/signal-event-trigger.js +8 -6
- package/usertask-event-listener.html +123 -1
- package/usertask-event-listener.js +30 -45
- package/usertask-input.html +119 -0
- package/usertask-input.js +7 -9
- package/usertask-output.js +15 -8
- package/wait-for-usertask.html +122 -6
- package/wait-for-usertask.js +44 -47
- package/.github/workflows/build-and-publish.yml +0 -72
- package/.processcube/authority/config/config.json +0 -36
- package/.processcube/authority/config/upeSeedingData.json +0 -12
- package/Dockerfile +0 -9
- package/doc_generator/_process_instances_query.md +0 -115
- package/doc_generator/generator.js +0 -41
- package/doc_generator/generator_with_swagger.js +0 -72
- package/doc_generator/package-lock.json +0 -176
- package/doc_generator/package.json +0 -15
- package/doc_generator/query_template.mustache +0 -20
- package/doc_generator/swagger.json +0 -4110
- package/docker-compose.yml +0 -44
- package/nodered/flows.json +0 -2156
- package/nodered/flows_cred.json +0 -3
- package/nodered/settings.js +0 -562
- package/nodered/static/ProcessCube_Logo.svg +0 -53
- package/processes/Call-Activity-Sample.bpmn +0 -88
- package/processes/External-Task-Auth-Sample.bpmn +0 -82
- package/processes/External-Task-Sample.bpmn +0 -94
- package/processes/SampleEvent.bpmn +0 -73
- package/processes/User-Task-Auth-Sample.bpmn +0 -63
- package/processes/User-Task-Sample.bpmn +0 -76
- package/processes/Wait-For-Usertask.bpmn +0 -74
package/README.md
CHANGED
|
@@ -1,60 +1,5 @@
|
|
|
1
|
-
# ProcessCube Node-RED
|
|
1
|
+
# Some Nodes to integrate the ProcessCube Engine into the ProcessCube LowCode component (Node-RED)
|
|
2
2
|
|
|
3
|
-
This repository contains
|
|
3
|
+
This repository contains some nodes to integrate the ProcessCube Engine into the ProcessCube LowCode component (Node-RED).
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
Before running the Node-RED flows, make sure you have the following prerequisites installed:
|
|
8
|
-
|
|
9
|
-
- Docker
|
|
10
|
-
- Docker Compose
|
|
11
|
-
|
|
12
|
-
## Installation
|
|
13
|
-
|
|
14
|
-
To install and run the Node-RED flows, follow these steps:
|
|
15
|
-
|
|
16
|
-
1. Clone this repository to your local machine:
|
|
17
|
-
|
|
18
|
-
```bash
|
|
19
|
-
git clone https://github.com/5minds/processcube_nodered.git
|
|
20
|
-
```
|
|
21
|
-
|
|
22
|
-
2. Change to the project directory:
|
|
23
|
-
|
|
24
|
-
```bash
|
|
25
|
-
cd processcube_nodered
|
|
26
|
-
```
|
|
27
|
-
|
|
28
|
-
3. Build the Docker containers:
|
|
29
|
-
|
|
30
|
-
```bash
|
|
31
|
-
docker-compose build
|
|
32
|
-
```
|
|
33
|
-
|
|
34
|
-
4. Start the Docker containers:
|
|
35
|
-
|
|
36
|
-
```bash
|
|
37
|
-
docker-compose up -d
|
|
38
|
-
```
|
|
39
|
-
|
|
40
|
-
## Usage
|
|
41
|
-
|
|
42
|
-
Once the Docker containers are running, you can access the ProcessCube Node-RED interface using the following URLs:
|
|
43
|
-
|
|
44
|
-
- Engine: [http://localhost:8000](http://localhost:8000)
|
|
45
|
-
- Node-RED: [http://localhost:1880](http://localhost:1880)
|
|
46
|
-
|
|
47
|
-
In the Node-RED interface, you will find pre-configured flows for starting processes and handling external tasks. You can customize these flows to fit your specific requirements.
|
|
48
|
-
|
|
49
|
-
## Contributing
|
|
50
|
-
|
|
51
|
-
If you would like to contribute to this project, please follow these guidelines:
|
|
52
|
-
|
|
53
|
-
1. Fork the repository on GitHub.
|
|
54
|
-
2. Create a new branch for your feature or bug fix.
|
|
55
|
-
3. Commit your changes and push the branch to your fork.
|
|
56
|
-
4. Submit a pull request to the main repository.
|
|
57
|
-
|
|
58
|
-
## License
|
|
59
|
-
|
|
60
|
-
This project is licensed under the MIT License. See the [LICENSE](LICENSE) file for more information.
|
|
5
|
+
Details see @ [ProcessCub.io - LowCode Integration Nodes](https://processcube.io/docs/node-red/integration-nodes) and [ProcessCub.io - LowCode Event Nodes](https://processcube.io/docs/node-red/event-nodes).
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
<script type="text/javascript">
|
|
2
|
+
RED.nodes.registerType('check-authorization', {
|
|
3
|
+
category: 'ProcessCube',
|
|
4
|
+
color: '#02AFD6',
|
|
5
|
+
defaults: {
|
|
6
|
+
name: { value: '' },
|
|
7
|
+
options: {
|
|
8
|
+
value: [{ claim: '' }],
|
|
9
|
+
},
|
|
10
|
+
},
|
|
11
|
+
inputs: 1,
|
|
12
|
+
outputs: 2,
|
|
13
|
+
outputLabels: function (index) {
|
|
14
|
+
if (index === 0) {
|
|
15
|
+
return 'Authorized'
|
|
16
|
+
} else {
|
|
17
|
+
return 'Unauthorized'
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
icon: 'font-awesome/fa-sign-in',
|
|
21
|
+
label: function () {
|
|
22
|
+
return this.name || 'check-authorization';
|
|
23
|
+
},
|
|
24
|
+
oneditprepare: function () {
|
|
25
|
+
$('#node-input-size').elementSizer({
|
|
26
|
+
width: '#node-input-width',
|
|
27
|
+
height: '#node-input-height',
|
|
28
|
+
group: '#node-input-group',
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
function generateOption(i, option) {
|
|
32
|
+
const container = $('<li/>', {
|
|
33
|
+
style: 'background: var(--red-ui-secondary-background, #fff); margin:0; padding:8px 0px 0px;',
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
const row = $('<div/>').appendTo(container);
|
|
37
|
+
|
|
38
|
+
$('<input/>', {
|
|
39
|
+
class: 'node-input-option-claim',
|
|
40
|
+
type: 'text',
|
|
41
|
+
style: 'margin-left:7px; width:calc(85%);',
|
|
42
|
+
placeholder: 'Claim',
|
|
43
|
+
value: option.claim,
|
|
44
|
+
})
|
|
45
|
+
.appendTo(row)
|
|
46
|
+
.typedInput({
|
|
47
|
+
type: 'str',
|
|
48
|
+
types: ['str'],
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
// Create delete button for the option
|
|
52
|
+
const finalSpan = $('<span/>', {
|
|
53
|
+
style: 'float:right; margin-right:8px;',
|
|
54
|
+
}).appendTo(row);
|
|
55
|
+
const deleteButton = $('<a/>', {
|
|
56
|
+
href: '#',
|
|
57
|
+
class: 'editor-button editor-button-small',
|
|
58
|
+
style: 'margin-top:7px; margin-left:5px;',
|
|
59
|
+
}).appendTo(finalSpan);
|
|
60
|
+
$('<i/>', { class: 'fa fa-remove' }).appendTo(deleteButton);
|
|
61
|
+
|
|
62
|
+
deleteButton.click(function () {
|
|
63
|
+
container.css({
|
|
64
|
+
background: 'var(--red-ui-secondary-background-inactive, #fee)',
|
|
65
|
+
});
|
|
66
|
+
container.fadeOut(300, function () {
|
|
67
|
+
$(this).remove();
|
|
68
|
+
});
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
$('#node-input-option-container').append(container);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
$('#node-input-add-option').click(function () {
|
|
75
|
+
generateOption($('#node-input-option-container').children().length + 1, {});
|
|
76
|
+
$('#node-input-option-container-div').scrollTop(
|
|
77
|
+
$('#node-input-option-container-div').get(0).scrollHeight
|
|
78
|
+
);
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
for (let i = 0; i < this.options.length; i++) {
|
|
82
|
+
const option = this.options[i];
|
|
83
|
+
generateOption(i + 1, option);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
$('#node-input-option-container').sortable({
|
|
87
|
+
axis: 'y',
|
|
88
|
+
handle: '.node-input-option-handle',
|
|
89
|
+
cursor: 'move',
|
|
90
|
+
});
|
|
91
|
+
},
|
|
92
|
+
oneditsave: function () {
|
|
93
|
+
const options = $('#node-input-option-container').children();
|
|
94
|
+
const node = this;
|
|
95
|
+
node.options = [];
|
|
96
|
+
options.each(function (i) {
|
|
97
|
+
const option = $(this);
|
|
98
|
+
const o = {
|
|
99
|
+
claim: option.find('.node-input-option-claim').val(),
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
node.options.push(o);
|
|
103
|
+
});
|
|
104
|
+
},
|
|
105
|
+
});
|
|
106
|
+
</script>
|
|
107
|
+
|
|
108
|
+
<script type="text/html" data-template-name="check-authorization">
|
|
109
|
+
<div class="form-row">
|
|
110
|
+
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label>
|
|
111
|
+
<input type="text" id="node-input-name" placeholder="Name" />
|
|
112
|
+
</div>
|
|
113
|
+
|
|
114
|
+
<div class="form-row form-row-flex node-input-option-container-row" style="margin-bottom: 0px;width: 100%">
|
|
115
|
+
<label for="node-input-width" style="vertical-align:top"><i class="fa fa-list-alt"></i> Claims</label>
|
|
116
|
+
<div id="node-input-option-container-div" style="box-sizing:border-box; border-radius:5px; height:257px; padding:5px; border:1px solid var(--red-ui-form-input-border-color, #ccc); overflow-y:scroll; display:inline-block; width: 70%;">
|
|
117
|
+
<ol id="node-input-option-container" style="list-style-type:none; margin:0;"></ol>
|
|
118
|
+
</div>
|
|
119
|
+
</div>
|
|
120
|
+
<!-- Add Claim Button -->
|
|
121
|
+
<div class="form-row">
|
|
122
|
+
<a href="#" class="editor-button editor-button-small" id="node-input-add-option" style="margin-top:4px; margin-left:103px;"><i class="fa fa-plus"></i> <span>action</span></a>
|
|
123
|
+
</div>
|
|
124
|
+
</script>
|
|
125
|
+
|
|
126
|
+
<script type="text/markdown" data-help-name="check-authorization">
|
|
127
|
+
A Node that checks if a user has the specified claims
|
|
128
|
+
|
|
129
|
+
## Configs
|
|
130
|
+
|
|
131
|
+
: name (string): name of the node
|
|
132
|
+
: claims (list of strings): the claims the user needs to be authorized
|
|
133
|
+
|
|
134
|
+
### References
|
|
135
|
+
|
|
136
|
+
- [The ProcessCube© Developer Network](https://processcube.io) - All documentation for the ProcessCube© platform
|
|
137
|
+
- [ProcessCube© LowCode Integration](https://processcube.io/docs/node-red) - LowCode integration in ProcessCube©
|
|
138
|
+
</script>
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
module.exports = function (RED) {
|
|
2
|
+
function CheckAuthorization(config) {
|
|
3
|
+
RED.nodes.createNode(this, config);
|
|
4
|
+
const node = this;
|
|
5
|
+
|
|
6
|
+
const claimsToCheck = (config.options || []).map((option) => option.claim);
|
|
7
|
+
|
|
8
|
+
node.on('input', function (msg) {
|
|
9
|
+
if (!msg._client || !msg._client.user || typeof msg._client.user.claims !== "object") {
|
|
10
|
+
node.error("Invalid client claims in the input message", msg);
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const userClaims = msg._client.user.claims;
|
|
15
|
+
|
|
16
|
+
const isAuthorized = claimsToCheck.every((claim) => claim in userClaims);
|
|
17
|
+
|
|
18
|
+
if (isAuthorized) {
|
|
19
|
+
node.send([msg, undefined]);
|
|
20
|
+
} else {
|
|
21
|
+
node.send([undefined, msg]);
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
RED.nodes.registerType('check-authorization', CheckAuthorization);
|
|
27
|
+
};
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
<script type="text/javascript">
|
|
2
|
+
RED.nodes.registerType('dataobject-instance-query', {
|
|
3
|
+
category: 'ProcessCube',
|
|
4
|
+
color: '#02AFD6',
|
|
5
|
+
defaults: {
|
|
6
|
+
name: { value: '' },
|
|
7
|
+
engine: { value: '', type: 'processcube-engine-config' },
|
|
8
|
+
query: { value: 'payload' },
|
|
9
|
+
query_type: { value: 'msg' },
|
|
10
|
+
onlyNewest: { value: true },
|
|
11
|
+
},
|
|
12
|
+
inputs: 1,
|
|
13
|
+
outputs: 1,
|
|
14
|
+
icon: 'data-object-query.svg',
|
|
15
|
+
label: function () {
|
|
16
|
+
return this.name || 'dataobject-instance-query';
|
|
17
|
+
},
|
|
18
|
+
oneditprepare: function () {
|
|
19
|
+
$('#node-input-query').typedInput({
|
|
20
|
+
default: 'msg',
|
|
21
|
+
types: ['msg', 'json'],
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
$('#node-input-query').typedInput('value', this.query);
|
|
25
|
+
$('#node-input-query').typedInput('type', this.query_type);
|
|
26
|
+
},
|
|
27
|
+
oneditsave: function () {
|
|
28
|
+
(this.query = $('#node-input-query').typedInput('value')),
|
|
29
|
+
(this.query_type = $('#node-input-query').typedInput('type'));
|
|
30
|
+
},
|
|
31
|
+
});
|
|
32
|
+
</script>
|
|
33
|
+
|
|
34
|
+
<script type="text/html" data-template-name="dataobject-instance-query">
|
|
35
|
+
<div class="form-row">
|
|
36
|
+
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label>
|
|
37
|
+
<input type="text" id="node-input-name" placeholder="Name" />
|
|
38
|
+
</div>
|
|
39
|
+
<div class="form-row">
|
|
40
|
+
<label for="node-input-engine"><i class="fa fa-tag"></i> Engine-URL</label>
|
|
41
|
+
<input type="text" id="node-input-engine" placeholder="http://engine:8000" />
|
|
42
|
+
</div>
|
|
43
|
+
<div class="form-row">
|
|
44
|
+
<label for="node-input-query"><i class="fa fa-tag"></i> Query</label>
|
|
45
|
+
<input type="text" id="node-input-query" />
|
|
46
|
+
</div>
|
|
47
|
+
<div class="form-row">
|
|
48
|
+
<label for="node-input-onlyNewest"><i class="fa fa-hand"></i>Only current instance per dataObject</label>
|
|
49
|
+
<input type="checkbox" id="node-input-onlyNewest" title="Applys a client-side filter, that returns just the newest instance per dataObject">
|
|
50
|
+
</div>
|
|
51
|
+
</script>
|
|
52
|
+
|
|
53
|
+
<script type="text/markdown" data-help-name="dataobject-instance-query">
|
|
54
|
+
A node to query dataobject instances on the ProcessCube Engine.
|
|
55
|
+
|
|
56
|
+
## Inputs
|
|
57
|
+
|
|
58
|
+
: msg (Object | JSON) : The selected field of the *msg*, eg *payload*, will be used as the input for the query or can be directly set as JSON.
|
|
59
|
+
: query (Object) : The query that was used.
|
|
60
|
+
|
|
61
|
+
## Outputs
|
|
62
|
+
|
|
63
|
+
: dataObjectInstances (Array) : The dataobject instances that matched the query.
|
|
64
|
+
: totalCount (number) : The number of matches.
|
|
65
|
+
|
|
66
|
+
### Query fields
|
|
67
|
+
|
|
68
|
+
**Summary**:
|
|
69
|
+
|
|
70
|
+
**Description**: Gets all DataObjectInstances that match the given query.
|
|
71
|
+
|
|
72
|
+
#### Parameters:
|
|
73
|
+
- Name: `offset` Required: `false`
|
|
74
|
+
- Type: number
|
|
75
|
+
- Description: The index of the first DataObjectInstance to include in the result set.
|
|
76
|
+
- Name: `limit` Required: `false`
|
|
77
|
+
- Type: number
|
|
78
|
+
- Description: The maximum number of DataObjectInstances to return.
|
|
79
|
+
- Name: `dataObjectId` Required: ``
|
|
80
|
+
- Type: Array<string> | string | SearchQuery
|
|
81
|
+
- string: myDataObjectId_12345678
|
|
82
|
+
- Array<string>: myDataObjectId_12345678,myDataObjectId_87654321
|
|
83
|
+
- object:
|
|
84
|
+
- Description: Filter by the ID of the DataObject.
|
|
85
|
+
- Name: `flowNodeInstanceId` Required: ``
|
|
86
|
+
- Type: Array<string> | string | SearchQuery
|
|
87
|
+
- string: myFlowNodeInstanceId_12345678
|
|
88
|
+
- Array<string>: myFlowNodeInstanceId_12345678,myFlowNodeInstanceId_87654321
|
|
89
|
+
- object:
|
|
90
|
+
- Description: Filter by the ID of the FlowNodeInstance that wrote to the DataObject.
|
|
91
|
+
- Name: `processInstanceId` Required: ``
|
|
92
|
+
- Type: Array<string> | string | SearchQuery
|
|
93
|
+
- string: myProcessInstance_12345678
|
|
94
|
+
- Array<string>: myProcessInstance_12345678,myProcessInstance_87654321
|
|
95
|
+
- object:
|
|
96
|
+
- Description: Filter by the ID of the ProcessInstances.
|
|
97
|
+
- Name: `processDefinitionId` Required: ``
|
|
98
|
+
- Type: Array<string> | string | SearchQuery
|
|
99
|
+
- string: myProcess_12345678
|
|
100
|
+
- Array<string>: myProcess_12345678,myProcess_87654321
|
|
101
|
+
- object:
|
|
102
|
+
- Description: Filter by the ID of the ProcessDefinition that the DataObjectInstances belong to.
|
|
103
|
+
- Name: `processModelId` Required: ``
|
|
104
|
+
- Type: Array<string> | string | SearchQuery
|
|
105
|
+
- string: myProcessModel_12345678
|
|
106
|
+
- Array<string>: myProcessModel_12345678,myProcessModel_87654321
|
|
107
|
+
- object:
|
|
108
|
+
- Description: Filter by the ID of the ProcessModel that the DataObjectInstances belong to.
|
|
109
|
+
- Name: `embeddedProcessModelId` Required: ``
|
|
110
|
+
- Type: Array<string> | string | SearchQuery
|
|
111
|
+
- string: myProcessModel_12345678
|
|
112
|
+
- Array<string>: myProcessModel_12345678,myProcessModel_87654321
|
|
113
|
+
- object:
|
|
114
|
+
- Description: Filter by the ID of the EmbeededProcessModel that the DataObjectInstances belong to.
|
|
115
|
+
- Name: `createdAt` Required: ``
|
|
116
|
+
- Type: Array<string> | string
|
|
117
|
+
- string: 2021-01-01T00:00:00.000Z
|
|
118
|
+
- array: 2021-01-01T00:00:00.000Z,2021-01-02T00:00:00.000Z
|
|
119
|
+
- Description: The created date of the DataObjectInstances to include in the results.
|
|
120
|
+
|
|
121
|
+
### Only current instance per dataObject
|
|
122
|
+
|
|
123
|
+
When checked, an additional filter is applied to the result of the query.
|
|
124
|
+
For each `dataObjectId`+`processInstanceId` in the result set, only the instance with the newest `createdAt` timestamp will be returned.
|
|
125
|
+
Therefore, it creates a list containing only the current values of each dataObject.
|
|
126
|
+
|
|
127
|
+
**Note**: This is not guranteed to work as described above. Since this is a client-side filter, that is applied after executing the server side query, there are some limitations.
|
|
128
|
+
Depending on your query, you might not load all instances of an dataObject. I.e. when setting a limit or offset. Or when querying such an amount of instances, that the engine applies an automatic limit.
|
|
129
|
+
In these cases, this filter will still be applied and return the newest instance from the result set, but that might not be the actual newest value for this dataObject, which would be available in the engines database.
|
|
130
|
+
To avoid thoses problems, make sure to write strict queries, which are guranteed to have a small result set, that can be retrieved in one request.
|
|
131
|
+
The `totalCount` property will, as well, not work as expected. Since this is a value created by the engine, it will not line up with the actual amount of instances, that are returned.
|
|
132
|
+
|
|
133
|
+
**Note**: This feature will be removed in a future version.
|
|
134
|
+
Due to the problems described above, this functionality should rather be provided by the engines interface.
|
|
135
|
+
As soon as the engine supports querying for the newest dataObject values, this filter becomes obsolete and you should instead alter your query to apply this filter server-side.
|
|
136
|
+
|
|
137
|
+
### References
|
|
138
|
+
|
|
139
|
+
- [The ProcessCube© Developer Network](https://processcube.io) - All documentation for the ProcessCube© platform
|
|
140
|
+
- [ProcessCube© LowCode Integration](https://processcube.io/docs/node-red) - LowCode integration in ProcessCube©
|
|
141
|
+
</script>
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
module.exports = function (RED) {
|
|
2
|
+
function DataobjectInstanceQuery(config) {
|
|
3
|
+
RED.nodes.createNode(this, config);
|
|
4
|
+
var node = this;
|
|
5
|
+
|
|
6
|
+
node.on('input', function (msg) {
|
|
7
|
+
let query = RED.util.evaluateNodeProperty(config.query, config.query_type, node, msg);
|
|
8
|
+
|
|
9
|
+
node.engine = RED.nodes.getNode(config.engine);
|
|
10
|
+
const client = node.engine.engineClient;
|
|
11
|
+
const isUser = !!msg._client?.user && !!msg._client.user.accessToken;
|
|
12
|
+
const userIdentity = isUser ? { userId: msg._client.user.id, token: msg._client.user.accessToken } : null;
|
|
13
|
+
|
|
14
|
+
if (!client) {
|
|
15
|
+
node.error('No engine configured.', msg);
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
client.dataObjectInstances
|
|
20
|
+
.query(query, { identity: userIdentity })
|
|
21
|
+
.then((matchingInstances) => {
|
|
22
|
+
msg.payload = matchingInstances;
|
|
23
|
+
|
|
24
|
+
if (config.onlyNewest) {
|
|
25
|
+
const newestInstances = {};
|
|
26
|
+
|
|
27
|
+
matchingInstances.dataObjectInstances.forEach(instance => {
|
|
28
|
+
newestInstances[instance.processInstanceId] ??= {};
|
|
29
|
+
if (!newestInstances[instance.processInstanceId][instance.dataObjectId] || newestInstances[instance.processInstanceId][instance.dataObjectId].createdAt < instance.createdAt) {
|
|
30
|
+
newestInstances[instance.processInstanceId][instance.dataObjectId] = instance;
|
|
31
|
+
}
|
|
32
|
+
})
|
|
33
|
+
|
|
34
|
+
msg.payload.dataObjectInstances = Object.values(newestInstances).flatMap(v => Object.values(v));
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
node.send(msg);
|
|
38
|
+
})
|
|
39
|
+
.catch((error) => {
|
|
40
|
+
node.error(`Dataobject Instance Query failed: ${error.message}`, msg);
|
|
41
|
+
});
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
RED.nodes.registerType('dataobject-instance-query', DataobjectInstanceQuery);
|
|
45
|
+
};
|
|
@@ -4,48 +4,37 @@ module.exports = function (RED) {
|
|
|
4
4
|
var node = this;
|
|
5
5
|
node.engine = RED.nodes.getNode(config.engine);
|
|
6
6
|
|
|
7
|
+
let subscription = null;
|
|
8
|
+
|
|
7
9
|
const register = async () => {
|
|
8
10
|
const client = node.engine.engineClient;
|
|
9
11
|
|
|
10
12
|
if (!client) {
|
|
11
|
-
node.error('No engine configured.');
|
|
13
|
+
node.error('No engine configured.', {});
|
|
12
14
|
return;
|
|
13
15
|
}
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
(endEventFinished) => {
|
|
16
|
+
|
|
17
|
+
try {
|
|
18
|
+
subscription = await client.events.onEndEventFinished((endEventFinished) => {
|
|
18
19
|
node.send({
|
|
19
20
|
payload: endEventFinished,
|
|
20
21
|
});
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
node.engine.registerOnIdentityChanged(async (identity) => {
|
|
26
|
-
client.events.removeSubscription(subscription, currentIdentity);
|
|
27
|
-
|
|
28
|
-
currentIdentity = identity;
|
|
29
|
-
|
|
30
|
-
subscription = await client.events.onEndEventFinished(
|
|
31
|
-
(endEventFinished) => {
|
|
32
|
-
node.send({
|
|
33
|
-
payload: endEventFinished
|
|
34
|
-
});
|
|
35
|
-
},
|
|
36
|
-
{ identity: currentIdentity },
|
|
37
|
-
);
|
|
38
|
-
});
|
|
22
|
+
});
|
|
23
|
+
} catch (error) {
|
|
24
|
+
node.error(error, {});
|
|
25
|
+
}
|
|
39
26
|
|
|
40
27
|
node.on('close', async () => {
|
|
41
28
|
if (node.engine && node.engine.engineClient && client) {
|
|
42
|
-
client.events.removeSubscription(subscription
|
|
29
|
+
client.events.removeSubscription(subscription);
|
|
43
30
|
}
|
|
44
31
|
});
|
|
45
32
|
};
|
|
46
33
|
|
|
47
34
|
if (node.engine) {
|
|
48
|
-
register()
|
|
35
|
+
register().catch((error) => {
|
|
36
|
+
node.error(error, {});
|
|
37
|
+
});
|
|
49
38
|
}
|
|
50
39
|
}
|
|
51
40
|
RED.nodes.registerType('endevent-finished-listener', EndEventFinishedListener);
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
[
|
|
2
|
+
{
|
|
3
|
+
"id": "3cb65f6178d62207",
|
|
4
|
+
"type": "tab",
|
|
5
|
+
"label": "Flow 1",
|
|
6
|
+
"disabled": false,
|
|
7
|
+
"info": "",
|
|
8
|
+
"env": []
|
|
9
|
+
},
|
|
10
|
+
{
|
|
11
|
+
"id": "466e6c33e4389342",
|
|
12
|
+
"type": "processcube-engine-config",
|
|
13
|
+
"name": "",
|
|
14
|
+
"url": "http://engine:8000",
|
|
15
|
+
"urlType": "str",
|
|
16
|
+
"clientId": "external_task_worker",
|
|
17
|
+
"clientIdType": "str",
|
|
18
|
+
"clientSecret": "external_task_worker_secret",
|
|
19
|
+
"clientSecretType": "str"
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
"id": "bf6699e3fcef19f7",
|
|
23
|
+
"type": "check-authorization",
|
|
24
|
+
"z": "3cb65f6178d62207",
|
|
25
|
+
"name": "",
|
|
26
|
+
"engine": "466e6c33e4389342",
|
|
27
|
+
"options": [
|
|
28
|
+
{
|
|
29
|
+
"claim": "gender"
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
"claim": "notavalidclaim"
|
|
33
|
+
}
|
|
34
|
+
],
|
|
35
|
+
"x": 460,
|
|
36
|
+
"y": 280,
|
|
37
|
+
"wires": [
|
|
38
|
+
[
|
|
39
|
+
"5d331a2c7a214465"
|
|
40
|
+
],
|
|
41
|
+
[
|
|
42
|
+
"931f5bf8a9c528cd"
|
|
43
|
+
]
|
|
44
|
+
]
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
"id": "5d331a2c7a214465",
|
|
48
|
+
"type": "debug",
|
|
49
|
+
"z": "3cb65f6178d62207",
|
|
50
|
+
"name": "debug 1",
|
|
51
|
+
"active": true,
|
|
52
|
+
"tosidebar": true,
|
|
53
|
+
"console": false,
|
|
54
|
+
"tostatus": false,
|
|
55
|
+
"complete": "payload",
|
|
56
|
+
"targetType": "msg",
|
|
57
|
+
"statusVal": "",
|
|
58
|
+
"statusType": "auto",
|
|
59
|
+
"x": 660,
|
|
60
|
+
"y": 260,
|
|
61
|
+
"wires": []
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
"id": "e3c38e3f6c38f58d",
|
|
65
|
+
"type": "inject",
|
|
66
|
+
"z": "3cb65f6178d62207",
|
|
67
|
+
"name": "",
|
|
68
|
+
"props": [
|
|
69
|
+
{
|
|
70
|
+
"p": "_client",
|
|
71
|
+
"v": "{\"user\":{\"id\":\"e54f73d2-b003-4454-ae50-dbd7c41e8bff\",\"displayName\":\"admin\",\"username\":\"admin\",\"profileUrl\":\"\",\"emails\":[{\"value\":\"admin@admin.de\"}],\"claims\":{\"sub\":\"e54f73d2-b003-4454-ae50-dbd7c41e8bff\",\"company\":\"\",\"locale\":\"\",\"website\":\"\",\"picture\":\"\",\"gender\":\"\",\"family_name\":\"\",\"zoneinfo\":\"\",\"preferred_username\":\"\",\"name\":\"admin\",\"nickname\":\"\",\"email\":\"admin@admin.de\",\"middle_name\":\"\",\"given_name\":\"\",\"updated_at\":null,\"email_verified\":true,\"birthdate\":\"\",\"profile\":\"\",\"jti\":\"zvImE0Nm96kxGJEjbyrh2\",\"iat\":1738847665,\"exp\":1738851265,\"scope\":\"openid profile email lanes\",\"client_id\":\"PassportTestClient\",\"iss\":\"http://authority:11560/\",\"aud\":\"PassportTestClient\"}}}",
|
|
72
|
+
"vt": "json"
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
"p": "payload"
|
|
76
|
+
}
|
|
77
|
+
],
|
|
78
|
+
"repeat": "",
|
|
79
|
+
"crontab": "",
|
|
80
|
+
"once": false,
|
|
81
|
+
"onceDelay": 0.1,
|
|
82
|
+
"topic": "",
|
|
83
|
+
"payload": "user data",
|
|
84
|
+
"payloadType": "str",
|
|
85
|
+
"x": 240,
|
|
86
|
+
"y": 280,
|
|
87
|
+
"wires": [
|
|
88
|
+
[
|
|
89
|
+
"bf6699e3fcef19f7"
|
|
90
|
+
]
|
|
91
|
+
]
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
"id": "931f5bf8a9c528cd",
|
|
95
|
+
"type": "debug",
|
|
96
|
+
"z": "3cb65f6178d62207",
|
|
97
|
+
"name": "debug 2",
|
|
98
|
+
"active": true,
|
|
99
|
+
"tosidebar": true,
|
|
100
|
+
"console": false,
|
|
101
|
+
"tostatus": false,
|
|
102
|
+
"complete": "false",
|
|
103
|
+
"statusVal": "",
|
|
104
|
+
"statusType": "auto",
|
|
105
|
+
"x": 660,
|
|
106
|
+
"y": 300,
|
|
107
|
+
"wires": []
|
|
108
|
+
}
|
|
109
|
+
]
|