@5minds/node-red-dashboard-2-processcube-dynamic-table 1.1.16-feature-a4c979-m0ngyqg4 → 1.1.17

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.
@@ -1,354 +1,362 @@
1
1
  <script type="text/javascript">
2
- (function () {
3
- function hasProperty(obj, prop) {
4
- return Object.prototype.hasOwnProperty.call(obj, prop);
2
+ (function () {
3
+ function hasProperty(obj, prop) {
4
+ return Object.prototype.hasOwnProperty.call(obj, prop);
5
+ }
6
+
7
+ RED.nodes.registerType("ui-dynamic-table", {
8
+ category: "ProcessCube UI",
9
+ color: "#00aed7",
10
+ defaults: {
11
+ name: { value: "" },
12
+ tableName: { value: "" },
13
+ group: { type: "ui-group", required: true },
14
+ order: { value: 1 },
15
+ data: { value: "payload" },
16
+ data_type: { value: "msg" },
17
+ options: {
18
+ value: [{ label: "", condition: "" }],
19
+ validate: function (v) {
20
+ const unique = new Set(
21
+ v.map(function (o) {
22
+ return o.label;
23
+ })
24
+ );
25
+ return v.length === unique.size;
26
+ },
27
+ },
28
+ columns: {
29
+ value: [{ value: "", label: "" }],
30
+ validate: function (v) {
31
+ const unique = new Set(
32
+ v.map(function (o) {
33
+ return o.value;
34
+ })
35
+ );
36
+ return v.length === unique.size;
37
+ },
38
+ },
39
+ width: {
40
+ value: 0,
41
+ validate: function (v) {
42
+ const width = v || 0;
43
+ const currentGroup = $("#node-input-group").val() || this.group;
44
+ const groupNode = RED.nodes.node(currentGroup);
45
+ const valid = !groupNode || +width <= +groupNode.width;
46
+ $("#node-input-size").toggleClass("input-error", !valid);
47
+ return valid;
48
+ },
49
+ },
50
+ height: { value: 0 },
51
+ outputs: { value: 1 },
52
+ },
53
+ inputs: 1,
54
+ outputs: 1,
55
+ outputLabels: function (index) {
56
+ return this.options[index].label;
57
+ },
58
+ icon: "ui_dynamic_table.svg",
59
+ paletteLbel: "file",
60
+ label: function () {
61
+ return this.name || "dynamic-table";
62
+ },
63
+ oneditprepare: function () {
64
+ $("#node-input-size").elementSizer({
65
+ width: "#node-input-width",
66
+ height: "#node-input-height",
67
+ group: "#node-input-group",
68
+ });
69
+
70
+ function generateOption(i, option) {
71
+ const container = $("<li/>", {
72
+ style:
73
+ "background: var(--red-ui-secondary-background, #fff); margin:0; padding:8px 0px 0px;",
74
+ });
75
+
76
+ // Create input fields for value and label
77
+ const row = $("<div/>").appendTo(container);
78
+ $("<input/>", {
79
+ class: "node-input-option-label",
80
+ type: "text",
81
+ style: "margin-left:7px; width:calc(50% - 32px);",
82
+ placeholder: "Label",
83
+ value: option.label,
84
+ })
85
+ .appendTo(row)
86
+ .typedInput({
87
+ type: "str",
88
+ types: ["str"],
89
+ });
90
+
91
+ $("<input/>", {
92
+ class: "node-input-option-condition",
93
+ type: "text",
94
+ style: "margin-left:7px; width:calc(50% - 32px);",
95
+ placeholder: "Condition",
96
+ value: option.condition,
97
+ })
98
+ .appendTo(row)
99
+ .typedInput({
100
+ type: "str",
101
+ types: ["str"],
102
+ });
103
+
104
+ // Create delete button for the option
105
+ const finalSpan = $("<span/>", {
106
+ style: "float:right; margin-right:8px;",
107
+ }).appendTo(row);
108
+ const deleteButton = $("<a/>", {
109
+ href: "#",
110
+ class: "editor-button editor-button-small",
111
+ style: "margin-top:7px; margin-left:5px;",
112
+ }).appendTo(finalSpan);
113
+ $("<i/>", { class: "fa fa-remove" }).appendTo(deleteButton);
114
+
115
+ deleteButton.click(function () {
116
+ container.css({
117
+ background: "var(--red-ui-secondary-background-inactive, #fee)",
118
+ });
119
+ container.fadeOut(300, function () {
120
+ $(this).remove();
121
+ });
122
+ });
123
+
124
+ $("#node-input-option-container").append(container);
125
+ }
126
+
127
+ function generateColumn(i, column) {
128
+ const container = $("<li/>", {
129
+ style:
130
+ "background: var(--red-ui-secondary-background, #fff); margin:0; padding:8px 0px 0px;",
131
+ });
132
+
133
+ // Create input fields for value and label
134
+ const row = $("<div/>").appendTo(container);
135
+ $("<input/>", {
136
+ class: "node-input-column-value",
137
+ type: "text",
138
+ style: "margin-left:7px; width:calc(50% - 32px);",
139
+ placeholder: "Value",
140
+ value: column.value,
141
+ })
142
+ .appendTo(row)
143
+ .typedInput({ default: column.type || "str", types: ["str"] });
144
+
145
+ $("<input/>", {
146
+ class: "node-input-column-label",
147
+ type: "text",
148
+ style: "margin-left:7px; width:calc(50% - 32px);",
149
+ placeholder: "Label",
150
+ value: column.label,
151
+ })
152
+ .appendTo(row)
153
+ .typedInput({
154
+ type: "str",
155
+ types: ["str"],
156
+ });
157
+
158
+ // Create delete button for the column
159
+ const finalSpan = $("<span/>", {
160
+ style: "float:right; margin-right:8px;",
161
+ }).appendTo(row);
162
+ const deleteButton = $("<a/>", {
163
+ href: "#",
164
+ class: "editor-button editor-button-small",
165
+ style: "margin-top:7px; margin-left:5px;",
166
+ }).appendTo(finalSpan);
167
+ $("<i/>", { class: "fa fa-remove" }).appendTo(deleteButton);
168
+
169
+ deleteButton.click(function () {
170
+ container.css({
171
+ background: "var(--red-ui-secondary-background-inactive, #fee)",
172
+ });
173
+ container.fadeOut(300, function () {
174
+ $(this).remove();
175
+ });
176
+ });
177
+
178
+ $("#node-input-column-container").append(container);
179
+ }
180
+
181
+ $("#node-input-add-column").click(function () {
182
+ generateColumn(
183
+ $("#node-input-column-container").children().length + 1,
184
+ {}
185
+ );
186
+ $("#node-input-column-container-div").scrollTop(
187
+ $("#node-input-column-container-div").get(0).scrollHeight
188
+ );
189
+ });
190
+
191
+ for (let i = 0; i < this.columns.length; i++) {
192
+ const column = this.columns[i];
193
+ generateColumn(i + 1, column);
194
+ }
195
+
196
+ $("#node-input-column-container").sortable({
197
+ axis: "y",
198
+ handle: ".node-input-column-handle",
199
+ cursor: "move",
200
+ });
201
+
202
+ $("#node-input-add-option").click(function () {
203
+ generateOption(
204
+ $("#node-input-option-container").children().length + 1,
205
+ {}
206
+ );
207
+ $("#node-input-option-container-div").scrollTop(
208
+ $("#node-input-option-container-div").get(0).scrollHeight
209
+ );
210
+ });
211
+
212
+ for (let i = 0; i < this.options.length; i++) {
213
+ const option = this.options[i];
214
+ generateOption(i + 1, option);
5
215
  }
6
216
 
7
- RED.nodes.registerType('ui-dynamic-table', {
8
- category: 'ProcessCube UI',
9
- color: '#00aed7',
10
- defaults: {
11
- name: { value: '' },
12
- tableName: { value: '' },
13
- group: { type: 'ui-group', required: true },
14
- order: { value: 1 },
15
- data: { value: 'payload' },
16
- data_type: { value: 'msg' },
17
- options: {
18
- value: [{ label: '', condition: '' }],
19
- validate: function (v) {
20
- const unique = new Set(
21
- v.map(function (o) {
22
- return o.label;
23
- })
24
- );
25
- return v.length === unique.size;
26
- },
27
- },
28
- columns: {
29
- value: [{ value: '', label: '' }],
30
- validate: function (v) {
31
- const unique = new Set(
32
- v.map(function (o) {
33
- return o.value;
34
- })
35
- );
36
- return v.length === unique.size;
37
- },
38
- },
39
- width: {
40
- value: 0,
41
- validate: function (v) {
42
- const width = v || 0;
43
- const currentGroup = $('#node-input-group').val() || this.group;
44
- const groupNode = RED.nodes.node(currentGroup);
45
- const valid = !groupNode || +width <= +groupNode.width;
46
- $('#node-input-size').toggleClass('input-error', !valid);
47
- return valid;
48
- },
49
- },
50
- height: { value: 0 },
51
- outputs: { value: 1 },
52
- },
53
- inputs: 1,
54
- outputs: 1,
55
- outputLabels: function (index) {
56
- return this.options[index].label;
57
- },
58
- icon: 'ui_dynamic_table.svg',
59
- paletteLbel: 'file',
60
- label: function () {
61
- return this.name || 'dynamic-table';
62
- },
63
- oneditprepare: function () {
64
- $('#node-input-size').elementSizer({
65
- width: '#node-input-width',
66
- height: '#node-input-height',
67
- group: '#node-input-group',
68
- });
69
-
70
- function generateOption(i, option) {
71
- const container = $('<li/>', {
72
- style: 'background: var(--red-ui-secondary-background, #fff); margin:0; padding:8px 0px 0px;',
73
- });
74
-
75
- // Create input fields for value and label
76
- const row = $('<div/>').appendTo(container);
77
- $('<input/>', {
78
- class: 'node-input-option-label',
79
- type: 'text',
80
- style: 'margin-left:7px; width:calc(50% - 32px);',
81
- placeholder: 'Label',
82
- value: option.label,
83
- })
84
- .appendTo(row)
85
- .typedInput({
86
- type: 'str',
87
- types: ['str'],
88
- });
89
-
90
- $('<input/>', {
91
- class: 'node-input-option-condition',
92
- type: 'text',
93
- style: 'margin-left:7px; width:calc(50% - 32px);',
94
- placeholder: 'Condition',
95
- value: option.condition,
96
- })
97
- .appendTo(row)
98
- .typedInput({
99
- type: 'str',
100
- types: ['str'],
101
- });
102
-
103
- // Create delete button for the option
104
- const finalSpan = $('<span/>', {
105
- style: 'float:right; margin-right:8px;',
106
- }).appendTo(row);
107
- const deleteButton = $('<a/>', {
108
- href: '#',
109
- class: 'editor-button editor-button-small',
110
- style: 'margin-top:7px; margin-left:5px;',
111
- }).appendTo(finalSpan);
112
- $('<i/>', { class: 'fa fa-remove' }).appendTo(deleteButton);
113
-
114
- deleteButton.click(function () {
115
- container.css({
116
- background: 'var(--red-ui-secondary-background-inactive, #fee)',
117
- });
118
- container.fadeOut(300, function () {
119
- $(this).remove();
120
- });
121
- });
122
-
123
- $('#node-input-option-container').append(container);
124
- }
125
-
126
- function generateColumn(i, column) {
127
- const container = $('<li/>', {
128
- style: 'background: var(--red-ui-secondary-background, #fff); margin:0; padding:8px 0px 0px;',
129
- });
130
-
131
- // Create input fields for value and label
132
- const row = $('<div/>').appendTo(container);
133
- $('<input/>', {
134
- class: 'node-input-column-value',
135
- type: 'text',
136
- style: 'margin-left:7px; width:calc(50% - 32px);',
137
- placeholder: 'Value',
138
- value: column.value,
139
- })
140
- .appendTo(row)
141
- .typedInput({ default: column.type || 'str', types: ['str'] });
142
-
143
- $('<input/>', {
144
- class: 'node-input-column-label',
145
- type: 'text',
146
- style: 'margin-left:7px; width:calc(50% - 32px);',
147
- placeholder: 'Label',
148
- value: column.label,
149
- })
150
- .appendTo(row)
151
- .typedInput({
152
- type: 'str',
153
- types: ['str'],
154
- });
155
-
156
- // Create delete button for the column
157
- const finalSpan = $('<span/>', {
158
- style: 'float:right; margin-right:8px;',
159
- }).appendTo(row);
160
- const deleteButton = $('<a/>', {
161
- href: '#',
162
- class: 'editor-button editor-button-small',
163
- style: 'margin-top:7px; margin-left:5px;',
164
- }).appendTo(finalSpan);
165
- $('<i/>', { class: 'fa fa-remove' }).appendTo(deleteButton);
166
-
167
- deleteButton.click(function () {
168
- container.css({
169
- background: 'var(--red-ui-secondary-background-inactive, #fee)',
170
- });
171
- container.fadeOut(300, function () {
172
- $(this).remove();
173
- });
174
- });
175
-
176
- $('#node-input-column-container').append(container);
177
- }
178
-
179
- $('#node-input-add-column').click(function () {
180
- generateColumn($('#node-input-column-container').children().length + 1, {});
181
- $('#node-input-column-container-div').scrollTop(
182
- $('#node-input-column-container-div').get(0).scrollHeight
183
- );
184
- });
185
-
186
- for (let i = 0; i < this.columns.length; i++) {
187
- const column = this.columns[i];
188
- generateColumn(i + 1, column);
189
- }
190
-
191
- $('#node-input-column-container').sortable({
192
- axis: 'y',
193
- handle: '.node-input-column-handle',
194
- cursor: 'move',
195
- });
196
-
197
- $('#node-input-add-option').click(function () {
198
- generateOption($('#node-input-option-container').children().length + 1, {});
199
- $('#node-input-option-container-div').scrollTop(
200
- $('#node-input-option-container-div').get(0).scrollHeight
201
- );
202
- });
203
-
204
- for (let i = 0; i < this.options.length; i++) {
205
- const option = this.options[i];
206
- generateOption(i + 1, option);
207
- }
208
-
209
- $('#node-input-option-container').sortable({
210
- axis: 'y',
211
- handle: '.node-input-option-handle',
212
- cursor: 'move',
213
- });
214
-
215
- $('#node-input-data').typedInput({
216
- default: 'msg',
217
- types: ['msg', 'json', 'flow', 'global'],
218
- });
219
-
220
- $('#node-input-data').typedInput('value', this.data);
221
- $('#node-input-data').typedInput('type', this.data_type);
222
- },
223
- oneditsave: function () {
224
- const options = $('#node-input-option-container').children();
225
- const node = this;
226
- node.options = [];
227
- options.each(function (i) {
228
- const option = $(this);
229
- const o = {
230
- label: option.find('.node-input-option-label').val(),
231
- condition: option.find('.node-input-option-condition').val(),
232
- };
233
-
234
- node.options.push(o);
235
- });
236
-
237
- const columns = $('#node-input-column-container').children();
238
- node.columns = [];
239
- columns.each(function (i) {
240
- const column = $(this);
241
- const c = {
242
- label: column.find('.node-input-column-label').val(),
243
- value: column.find('.node-input-column-value').typedInput('value'),
244
- type: column.find('.node-input-column-value').typedInput('type'),
245
- };
246
- if (column.find('.node-input-column-value').typedInput('type') === 'num') {
247
- c.value = Number(c.value);
248
- }
249
- if (column.find('.node-input-column-value').typedInput('type') === 'bool') {
250
- c.value = c.value === 'true';
251
- }
252
- node.columns.push(c);
253
- });
254
-
255
- this.outputs = node.options.length || 1;
256
-
257
- (this.data = $('#node-input-data').typedInput('value')),
258
- (this.data_type = $('#node-input-data').typedInput('type'));
259
- },
217
+ $("#node-input-option-container").sortable({
218
+ axis: "y",
219
+ handle: ".node-input-option-handle",
220
+ cursor: "move",
221
+ });
222
+
223
+ $("#node-input-data").typedInput({
224
+ default: "msg",
225
+ types: ["msg", "json", "flow", "global"],
226
+ });
227
+
228
+ $("#node-input-data").typedInput("value", this.data);
229
+ $("#node-input-data").typedInput("type", this.data_type);
230
+ },
231
+ oneditsave: function () {
232
+ const options = $("#node-input-option-container").children();
233
+ const node = this;
234
+ node.options = [];
235
+ options.each(function (i) {
236
+ const option = $(this);
237
+ const o = {
238
+ label: option.find(".node-input-option-label").val(),
239
+ condition: option.find(".node-input-option-condition").val(),
240
+ };
241
+
242
+ node.options.push(o);
260
243
  });
261
- })();
244
+
245
+ const columns = $("#node-input-column-container").children();
246
+ node.columns = [];
247
+ columns.each(function (i) {
248
+ const column = $(this);
249
+ const c = {
250
+ label: column.find(".node-input-column-label").val(),
251
+ value: column.find(".node-input-column-value").typedInput("value"),
252
+ type: column.find(".node-input-column-value").typedInput("type"),
253
+ };
254
+ if (
255
+ column.find(".node-input-column-value").typedInput("type") === "num"
256
+ ) {
257
+ c.value = Number(c.value);
258
+ }
259
+ if (
260
+ column.find(".node-input-column-value").typedInput("type") ===
261
+ "bool"
262
+ ) {
263
+ c.value = c.value === "true";
264
+ }
265
+ node.columns.push(c);
266
+ });
267
+
268
+ this.outputs = node.options.length || 1;
269
+
270
+ (this.data = $("#node-input-data").typedInput("value")),
271
+ (this.data_type = $("#node-input-data").typedInput("type"));
272
+ },
273
+ });
274
+ })();
262
275
  </script>
263
276
 
264
277
  <script type="text/html" data-template-name="ui-dynamic-table">
265
- <div class="form-row">
266
- <label for="node-input-name"><i class="fa fa-tag"></i> Name</label>
267
- <input type="text" id="node-input-name" placeholder="Name">
268
- </div>
269
- <div class="form-row">
270
- <label for="node-input-tableName"><i class="fa fa-tag"></i> Table name</label>
271
- <input type="text" id="node-input-tableName" placeholder="My Table">
272
- </div>
273
- <div class="form-row">
274
- <label for="node-input-group"><i class="fa fa-table"></i> Group</label>
275
- <input type="text" id="node-input-group">
276
- </div>
277
- <div class="form-row">
278
- <label><i class="fa fa-object-group"></i> <span data-i18n="ui-dynamic-table.label.size"></label>
279
- <input type="hidden" id="node-input-width">
280
- <input type="hidden" id="node-input-height">
281
- <button class="editor-button" id="node-input-size"></button>
282
- </div>
283
- <div class="form-row">
284
- <label for="node-input-data"><i class="fa fa-tag"></i> Data</label>
285
- <input type="text" id="node-input-data" placeholder="Data">
286
- </div>
287
- <div class="form-row form-row-flex node-input-option-container-row" style="margin-bottom: 0px;width: 100%">
288
- <label for="node-input-width" style="vertical-align:top"><i class="fa fa-list-alt"></i> Actions</label>
289
- <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%;">
290
- <span id="valWarning" style="color: var(--red-ui-text-color-error, #910000)"><b>All Values must be unique.</b></span>
291
- <ol id="node-input-option-container" style="list-style-type:none; margin:0;"></ol>
292
- </div>
293
- <a
294
- data-html="true"
295
- title="Dynamic Property: Send 'msg.options' in order to override this property."
296
- class="red-ui-button ui-node-popover-title"
297
- style="margin-left: 4px; cursor: help; font-size: 0.625rem; border-radius: 50%; width: 24px; height: 24px; display: inline-flex; justify-content: center; align-items: center;">
298
- <i style="font-family: ui-serif;">fx</i>
299
- </a>
300
- </div>
301
- <!-- Add Option Button -->
302
- <div class="form-row">
303
- <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>
304
- </div>
305
-
306
- <div class="form-row form-row-flex node-input-column-container-row" style="margin-bottom: 0px;width: 100%">
307
- <label for="node-input-width" style="vertical-align:top"><i class="fa fa-list-alt"></i> Columns</label>
308
- <div id="node-input-column-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%;">
309
- <span id="valWarning" style="color: var(--red-ui-text-color-error, #910000)"><b>All Values must be unique.</b></span>
310
- <ol id="node-input-column-container" style="list-style-type:none; margin:0;"></ol>
311
- </div>
312
- <a
313
- data-html="true"
314
- title="Dynamic Property: Send 'msg.columns' in order to override this property."
315
- class="red-ui-button ui-node-popover-title"
316
- style="margin-left: 4px; cursor: help; font-size: 0.625rem; border-radius: 50%; width: 24px; height: 24px; display:inline-flex; justify-content: center; align-items: center;">
317
- <i style="font-family: ui-serif;">fx</i>
318
- </a>
319
- </div>
320
- <!-- Add Column Button -->
321
- <div class="form-row">
322
- <a href="#" class="editor-button editor-button-small" id="node-input-add-column" style="margin-top:4px; margin-left:103px;"><i class="fa fa-plus"></i> <span>column</span></a>
323
- </div>
278
+ <div class="form-row">
279
+ <label for="node-input-name"><i class="fa fa-tag"></i> Name</label>
280
+ <input type="text" id="node-input-name" placeholder="Name">
281
+ </div>
282
+ <div class="form-row">
283
+ <label for="node-input-tableName"><i class="fa fa-tag"></i> Table name</label>
284
+ <input type="text" id="node-input-tableName" placeholder="My Table">
285
+ </div>
286
+ <div class="form-row">
287
+ <label for="node-input-group"><i class="fa fa-table"></i> Group</label>
288
+ <input type="text" id="node-input-group">
289
+ </div>
290
+ <div class="form-row">
291
+ <label><i class="fa fa-object-group"></i> <span data-i18n="ui-dynamic-table.label.size"></label>
292
+ <input type="hidden" id="node-input-width">
293
+ <input type="hidden" id="node-input-height">
294
+ <button class="editor-button" id="node-input-size"></button>
295
+ </div>
296
+ <div class="form-row">
297
+ <label for="node-input-data"><i class="fa fa-tag"></i> Data</label>
298
+ <input type="text" id="node-input-data" placeholder="Data">
299
+ </div>
300
+ <div class="form-row form-row-flex node-input-option-container-row" style="margin-bottom: 0px;width: 100%">
301
+ <label for="node-input-width" style="vertical-align:top"><i class="fa fa-list-alt"></i> Actions</label>
302
+ <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%;">
303
+ <span id="valWarning" style="color: var(--red-ui-text-color-error, #910000)"><b>All Values must be unique.</b></span>
304
+ <ol id="node-input-option-container" style="list-style-type:none; margin:0;"></ol>
305
+ </div>
306
+ <a
307
+ data-html="true"
308
+ title="Dynamic Property: Send 'msg.options' in order to override this property."
309
+ class="red-ui-button ui-node-popover-title"
310
+ style="margin-left: 4px; cursor: help; font-size: 0.625rem; border-radius: 50%; width: 24px; height: 24px; display: inline-flex; justify-content: center; align-items: center;">
311
+ <i style="font-family: ui-serif;">fx</i>
312
+ </a>
313
+ </div>
314
+ <!-- Add Option Button -->
315
+ <div class="form-row">
316
+ <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>
317
+ </div>
318
+
319
+ <div class="form-row form-row-flex node-input-column-container-row" style="margin-bottom: 0px;width: 100%">
320
+ <label for="node-input-width" style="vertical-align:top"><i class="fa fa-list-alt"></i> Columns</label>
321
+ <div id="node-input-column-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%;">
322
+ <span id="valWarning" style="color: var(--red-ui-text-color-error, #910000)"><b>All Values must be unique.</b></span>
323
+ <ol id="node-input-column-container" style="list-style-type:none; margin:0;"></ol>
324
+ </div>
325
+ <a
326
+ data-html="true"
327
+ title="Dynamic Property: Send 'msg.columns' in order to override this property."
328
+ class="red-ui-button ui-node-popover-title"
329
+ style="margin-left: 4px; cursor: help; font-size: 0.625rem; border-radius: 50%; width: 24px; height: 24px; display:inline-flex; justify-content: center; align-items: center;">
330
+ <i style="font-family: ui-serif;">fx</i>
331
+ </a>
332
+ </div>
333
+ <!-- Add Column Button -->
334
+ <div class="form-row">
335
+ <a href="#" class="editor-button editor-button-small" id="node-input-add-column" style="margin-top:4px; margin-left:103px;"><i class="fa fa-plus"></i> <span>column</span></a>
336
+ </div>
324
337
  </script>
325
338
 
326
339
  <script type="text/markdown" data-help-name="ui-dynamic-table">
327
- A Node to dynamicly display arrays of data in a table with actions for every row.
328
-
329
- ## Actions
330
-
331
- Define a label for the action button that is going be displayed and a condition for when it should be displayed.
332
- Inside the condition you have access to every key from the current row.
340
+ Dyanmic-Table ProcessCube UI-Component
333
341
 
334
- ### Inputs
342
+ ### Inputs
335
343
 
336
- : Table name (string) : The name of the table.
337
- : Group (string) : The groud in which the Component is rendered.
338
- : Size (string) : The size of the table within the group.
339
- : Data (string) : The property of msg.payload from where the table data is sourced.
340
- : Actions (string) : The actions of each row. Each action corresponds to an output of the node.
341
- : Columns (string) : The columns of the table. Must correspond to a key of the data property.
344
+ : Table name (string) : The name of the table.
345
+ : Group (string) : The groud in which the Component is rendered.
346
+ : Size (string) : The size of the table within the group.
347
+ : Data (string) : The property of msg.payload from where the table data is sourced.
348
+ : Actions (string) : The actions of each row. Each action corresponds to an output of the node.
349
+ : Columns (string) : The columns of the table. Must correspond to a key of the data property.
342
350
 
343
- ### Outputs
351
+ ### Outputs
344
352
 
345
- The outputs are generated dynamicly based on the actions of the table.
353
+ The outputs are generated dynamicly based on the actions of the table.
346
354
 
347
- ### Details
355
+ ### Details
348
356
 
349
- `msg.payload` is used as the base for the data form there on the data source can be specified further with the `data` input field.
357
+ `msg.payload` is used as the base for the data form there on the data source can be specified further with the `data` input field.
350
358
 
351
- ### Referece
359
+ ### Referece
352
360
 
353
- [https://processcube.io/docs/solutions/node-red](https://processcube.io/docs/solutions/node-red)
361
+ [https://processcube.io/docs/solutions/node-red](https://processcube.io/docs/solutions/node-red)
354
362
  </script>
@@ -8,49 +8,17 @@ module.exports = function (RED) {
8
8
 
9
9
  const base = group.getBase();
10
10
 
11
- const timeToLive = 24 * 60 * 60 * 1000; // one day
12
-
13
- function ageOf(obj) {
14
- return new Date().getTime() - obj.timestamp;
15
- }
16
-
17
11
  //server-side event handlers
18
12
  const evts = {
19
13
  onAction: true,
20
14
  beforeSend: function (msg) {
21
15
  if (Array.isArray(msg)) return msg;
22
- msg.payload = RED.util.evaluateNodeProperty(config.data, config.data_type, node, msg);
23
-
24
- if (msg._client != undefined) {
25
- let socketId = msg._client.socketId;
26
-
27
- let currentSession = {
28
- ...msg,
29
- timestamp: new Date().getTime(),
30
- };
31
-
32
- node.context().set(socketId, currentSession);
33
- } else {
34
- const keys = node.context().keys();
35
- const modifiedObjects = [];
36
-
37
- keys.forEach((key) => {
38
- let obj = node.context().get(key);
39
-
40
- if (obj && obj.payload) {
41
- obj.payload = msg.payload;
42
-
43
- node.context().set(key, obj);
44
- modifiedObjects.push(obj);
45
- }
46
-
47
- if (ageOf(obj) > timeToLive) {
48
- node.context().set(key, undefined);
49
- }
50
- });
51
-
52
- msg = modifiedObjects;
53
- }
16
+ msg.payload = RED.util.evaluateNodeProperty(
17
+ config.data,
18
+ config.data_type,
19
+ node,
20
+ msg
21
+ );
54
22
 
55
23
  return msg;
56
24
  },
@@ -62,11 +30,11 @@ module.exports = function (RED) {
62
30
  if (group) {
63
31
  group.register(node, config, evts);
64
32
  } else {
65
- node.error('No group configured');
33
+ node.error("No group configured");
66
34
  }
67
35
  }
68
36
 
69
- RED.nodes.registerType('ui-dynamic-table', UIDynamicTableNode, {
37
+ RED.nodes.registerType("ui-dynamic-table", UIDynamicTableNode, {
70
38
  defaults: {
71
39
  outputs: { value: 1 },
72
40
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@5minds/node-red-dashboard-2-processcube-dynamic-table",
3
- "version": "1.1.16-feature-a4c979-m0ngyqg4",
3
+ "version": "1.1.17",
4
4
  "description": "A ui component for showing dynamic Data with actions in a table",
5
5
  "keywords": [
6
6
  "processcube",
@@ -1,2 +1,2 @@
1
- (function(){"use strict";try{if(typeof document<"u"){var e=document.createElement("style");e.appendChild(document.createTextNode("h1[data-v-f265f54e]{margin-bottom:10px}h2[data-v-f265f54e]{margin-top:1.5rem;margin-bottom:.75rem}h3[data-v-f265f54e]{margin-top:1rem}p[data-v-f265f54e]{margin-bottom:5px}ul li[data-v-f265f54e]{list-style-type:circle;list-style-position:inside;margin-left:15px}pre[data-v-f265f54e]{padding:12px;margin:12px;background-color:#eee}code[data-v-f265f54e]{font-size:.825rem;color:#ae0000}input[data-v-f265f54e]{padding:12px;margin:12px;background-color:#eee}.task-div[data-v-f265f54e]{padding:8px;margin:16px;border:solid;border-radius:4px;border-color:#303030}.action-button-container[data-v-f265f54e]{width:100%;display:flex;justify-content:center}")),document.head.appendChild(e)}}catch(t){console.error("vite-plugin-css-injected-by-js",t)}})();
2
- (function(o,a){typeof exports=="object"&&typeof module<"u"?a(exports,require("vuex"),require("vue")):typeof define=="function"&&define.amd?define(["exports","vuex","vue"],a):(o=typeof globalThis<"u"?globalThis:o||self,a(o["ui-dynamic-table"]={},o.vuex,o.Vue))})(this,function(o,a,t){"use strict";const p=(e,i)=>{const n=e.__vccOpts||e;for(const[r,s]of i)n[r]=s;return n},m={name:"UIDynamicTable",inject:["$socket"],props:{id:{type:String,required:!0},props:{type:Object,default:()=>({})},state:{type:Object,default:()=>({enabled:!0,visible:!0})}},computed:{...a.mapState("data",["messages"])},data(){return{search:"",actions:[],tasks:[],headers:[]}},mounted(){this.$socket.on("widget-load:"+this.id,e=>{this.initialize(e),this.$store.commit("data/bind",{widgetId:this.id,msg:e})}),this.$socket.on("msg-input:"+this.id,e=>{Array.isArray(e)&&(e=e.filter(i=>i._client.socketId==this.$socket.id)[0]),this.initialize(e),this.messages[this.id]=e,this.$store.commit("data/bind",{widgetId:this.id,msg:e})}),this.$socket.emit("widget-load",this.id)},unmounted(){var e,i;(e=this.$socket)==null||e.off("widget-load"+this.id),(i=this.$socket)==null||i.off("msg-input:"+this.id)},methods:{send(e,i){const n=[];n[i]=e,this.$socket.emit("widget-action",this.id,n)},actionFn(e,i){const n=this.messages[this.id]||{};n.payload=i,this.send(n,this.actions.findIndex(r=>r.label===e.label))},initialize(e){this.tasks=e.payload,this.actions=this.props.options,this.headers=this.props.columns.map(i=>({title:i.label,key:i.value})),this.headers.push({title:"Actions",align:"center",key:"actions"})},conditionCheck(e,i){if(e=="")return!0;try{return new Function("row",`return ${e}`)(i)}catch(n){return console.error("Error evaluating condition:",n),!1}}}};function f(e,i,n,r,s,d){const u=t.resolveComponent("v-text-field"),k=t.resolveComponent("v-toolbar"),y=t.resolveComponent("v-btn"),h=t.resolveComponent("v-container"),x=t.resolveComponent("v-alert"),b=t.resolveComponent("v-data-table");return t.openBlock(),t.createBlock(b,{headers:s.headers,items:s.tasks,search:s.search,class:"full-width-table"},{top:t.withCtx(()=>[t.createVNode(k,{flat:"",class:"py-2"},{default:t.withCtx(()=>[t.createVNode(u,{class:"mx-3",modelValue:s.search,"onUpdate:modelValue":i[0]||(i[0]=c=>s.search=c),label:"Search","prepend-inner-icon":"mdi-magnify",variant:"outlined","hide-details":"","single-line":""},null,8,["modelValue"])]),_:1})]),"item.actions":t.withCtx(({item:c})=>[t.createVNode(h,{class:"action-button-container"},{default:t.withCtx(()=>[(t.openBlock(!0),t.createElementBlock(t.Fragment,null,t.renderList(s.actions,(l,g)=>(t.openBlock(),t.createBlock(h,{style:{padding:"0px",display:"inline",width:"fit-content",margin:"0px"}},{default:t.withCtx(()=>[d.conditionCheck(l.condition,c)?(t.openBlock(),t.createBlock(y,{style:{margin:"0px 2px"},key:g,size:"small",onClick:C=>d.actionFn(l,c)},{default:t.withCtx(()=>[t.createTextVNode(t.toDisplayString(l.label),1)]),_:2},1032,["onClick"])):t.createCommentVNode("",!0)]),_:2},1024))),256))]),_:2},1024)]),"no-data":t.withCtx(()=>[t.createVNode(x,{text:"No Data",style:{margin:"12px"}})]),_:1},8,["headers","items","search"])}const _=p(m,[["render",f],["__scopeId","data-v-f265f54e"]]);o.UIDynamicTable=_,Object.defineProperty(o,Symbol.toStringTag,{value:"Module"})});
1
+ (function(){"use strict";try{if(typeof document<"u"){var t=document.createElement("style");t.appendChild(document.createTextNode("h1[data-v-86dfbccf]{margin-bottom:10px}h2[data-v-86dfbccf]{margin-top:1.5rem;margin-bottom:.75rem}h3[data-v-86dfbccf]{margin-top:1rem}p[data-v-86dfbccf]{margin-bottom:5px}ul li[data-v-86dfbccf]{list-style-type:circle;list-style-position:inside;margin-left:15px}pre[data-v-86dfbccf]{padding:12px;margin:12px;background-color:#eee}code[data-v-86dfbccf]{font-size:.825rem;color:#ae0000}input[data-v-86dfbccf]{padding:12px;margin:12px;background-color:#eee}.task-div[data-v-86dfbccf]{padding:8px;margin:16px;border:solid;border-radius:4px;border-color:#303030}.action-button-container[data-v-86dfbccf]{width:100%;display:flex;justify-content:center}")),document.head.appendChild(t)}}catch(d){console.error("vite-plugin-css-injected-by-js",d)}})();
2
+ (function(o,a){typeof exports=="object"&&typeof module<"u"?a(exports,require("vuex"),require("vue")):typeof define=="function"&&define.amd?define(["exports","vuex","vue"],a):(o=typeof globalThis<"u"?globalThis:o||self,a(o["ui-dynamic-table"]={},o.vuex,o.Vue))})(this,function(o,a,t){"use strict";const h=(e,n)=>{const i=e.__vccOpts||e;for(const[r,s]of n)i[r]=s;return i},m={name:"UIDynamicTable",inject:["$socket"],props:{id:{type:String,required:!0},props:{type:Object,default:()=>({})},state:{type:Object,default:()=>({enabled:!0,visible:!0})}},computed:{...a.mapState("data",["messages"])},data(){return{search:"",actions:[],tasks:[],headers:[]}},mounted(){this.$socket.on("widget-load:"+this.id,e=>{this.initialize(e),this.$store.commit("data/bind",{widgetId:this.id,msg:e})}),this.$socket.on("msg-input:"+this.id,e=>{this.initialize(e),this.messages[this.id]=e,this.$store.commit("data/bind",{widgetId:this.id,msg:e})}),this.$socket.emit("widget-load",this.id)},unmounted(){var e,n;(e=this.$socket)==null||e.off("widget-load"+this.id),(n=this.$socket)==null||n.off("msg-input:"+this.id)},methods:{send(e,n){const i=[];i[n]=e,this.$socket.emit("widget-action",this.id,i)},actionFn(e,n){const i=this.messages[this.id]||{};i.payload=n,this.send(i,this.actions.findIndex(r=>r.label===e.label))},initialize(e){this.tasks=e.payload,this.actions=this.props.options,this.headers=this.props.columns.map(n=>({title:n.label,key:n.value})),this.headers.push({title:"Actions",align:"center",key:"actions"})},conditionCheck(e,n){if(e=="")return!0;try{return new Function("row",`return ${e}`)(n)}catch(i){return console.error("Error evaluating condition:",i),!1}}}};function f(e,n,i,r,s,d){const u=t.resolveComponent("v-text-field"),k=t.resolveComponent("v-toolbar"),b=t.resolveComponent("v-btn"),p=t.resolveComponent("v-container"),x=t.resolveComponent("v-alert"),y=t.resolveComponent("v-data-table");return t.openBlock(),t.createBlock(y,{headers:s.headers,items:s.tasks,search:s.search,class:"full-width-table"},{top:t.withCtx(()=>[t.createVNode(k,{flat:"",class:"py-2"},{default:t.withCtx(()=>[t.createVNode(u,{class:"mx-3",modelValue:s.search,"onUpdate:modelValue":n[0]||(n[0]=c=>s.search=c),label:"Search","prepend-inner-icon":"mdi-magnify",variant:"outlined","hide-details":"","single-line":""},null,8,["modelValue"])]),_:1})]),"item.actions":t.withCtx(({item:c})=>[t.createVNode(p,{class:"action-button-container"},{default:t.withCtx(()=>[(t.openBlock(!0),t.createElementBlock(t.Fragment,null,t.renderList(s.actions,(l,g)=>(t.openBlock(),t.createBlock(p,{style:{padding:"0px",display:"inline",width:"fit-content",margin:"0px"}},{default:t.withCtx(()=>[d.conditionCheck(l.condition,c)?(t.openBlock(),t.createBlock(b,{style:{margin:"0px 2px"},key:g,size:"small",onClick:C=>d.actionFn(l,c)},{default:t.withCtx(()=>[t.createTextVNode(t.toDisplayString(l.label),1)]),_:2},1032,["onClick"])):t.createCommentVNode("",!0)]),_:2},1024))),256))]),_:2},1024)]),"no-data":t.withCtx(()=>[t.createVNode(x,{text:"No Data",style:{margin:"12px"}})]),_:1},8,["headers","items","search"])}const _=h(m,[["render",f],["__scopeId","data-v-86dfbccf"]]);o.UIDynamicTable=_,Object.defineProperty(o,Symbol.toStringTag,{value:"Module"})});
@@ -54,7 +54,7 @@ export default {
54
54
  },
55
55
  },
56
56
  computed: {
57
- ...mapState('data', ['messages']),
57
+ ...mapState('data', ['messages'])
58
58
  },
59
59
  data() {
60
60
  return {
@@ -73,14 +73,9 @@ export default {
73
73
  });
74
74
  });
75
75
  this.$socket.on('msg-input:' + this.id, (msg) => {
76
- if (Array.isArray(msg)) {
77
- msg = msg.filter((obj) => obj._client.socketId == this.$socket.id)[0];
78
- }
79
-
80
76
  this.initialize(msg);
81
77
 
82
78
  this.messages[this.id] = msg;
83
-
84
79
  this.$store.commit('data/bind', {
85
80
  widgetId: this.id,
86
81
  msg,