@5minds/node-red-dashboard-2-processcube-dynamic-form 2.2.1-feature-f3865e-mf6maz40 → 2.2.1-file-preview-2-247fbf-mfdx0ry5
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.
|
@@ -235,14 +235,12 @@ export default {
|
|
|
235
235
|
return !!this.userTask;
|
|
236
236
|
},
|
|
237
237
|
totalOutputs() {
|
|
238
|
-
const confirmOutputs = this.props.handle_confirmation_dialogs
|
|
239
|
-
?
|
|
238
|
+
const confirmOutputs = this.props.handle_confirmation_dialogs
|
|
239
|
+
? this.props.confirm_actions
|
|
240
|
+
? this.props.confirm_actions.length
|
|
241
|
+
: 2
|
|
240
242
|
: 0;
|
|
241
|
-
return (
|
|
242
|
-
this.props.options.length +
|
|
243
|
-
confirmOutputs +
|
|
244
|
-
(this.props.trigger_on_change ? 1 : 0)
|
|
245
|
-
);
|
|
243
|
+
return this.props.options.length + confirmOutputs + (this.props.trigger_on_change ? 1 : 0);
|
|
246
244
|
},
|
|
247
245
|
isConfirmDialog() {
|
|
248
246
|
return this.userTask.userTaskConfig.formFields.some((field) => field.type === 'confirm');
|
|
@@ -891,6 +889,8 @@ export default {
|
|
|
891
889
|
const formFields = this.userTask.userTaskConfig.formFields;
|
|
892
890
|
const formFieldIds = formFields.map((ff) => ff.id);
|
|
893
891
|
const initialValues = this.userTask.startToken;
|
|
892
|
+
console.log('Initial Values:', initialValues);
|
|
893
|
+
console.log('Form Fields:', formFields);
|
|
894
894
|
const finishedFormData = msg.payload.formData;
|
|
895
895
|
this.formIsFinished = !!msg.payload.formData;
|
|
896
896
|
if (this.formIsFinished) {
|
|
@@ -908,55 +908,55 @@ export default {
|
|
|
908
908
|
const confirmText = customForm.confirmButtonText ?? 'Confirm';
|
|
909
909
|
const declineText = customForm.declineButtonText ?? 'Decline';
|
|
910
910
|
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
911
|
+
const confirmActions = [
|
|
912
|
+
{
|
|
913
|
+
alignment: this.props.confirm_actions[1]?.alignment || 'left',
|
|
914
|
+
primary: this.props.confirm_actions[1]?.primary || 'destructive',
|
|
915
|
+
label: declineText,
|
|
916
|
+
condition: '',
|
|
917
|
+
isConfirmAction: true,
|
|
918
|
+
confirmFieldId: field.id,
|
|
919
|
+
confirmValue: false,
|
|
920
|
+
},
|
|
921
|
+
{
|
|
922
|
+
alignment: this.props.confirm_actions[0]?.alignment || 'right',
|
|
923
|
+
primary: this.props.confirm_actions[0]?.primary || 'primary',
|
|
924
|
+
label: confirmText,
|
|
925
|
+
condition: '',
|
|
926
|
+
isConfirmAction: true,
|
|
927
|
+
confirmFieldId: field.id,
|
|
928
|
+
confirmValue: true,
|
|
929
|
+
},
|
|
930
|
+
];
|
|
931
931
|
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
932
|
+
const filteredActions = this.props.options.filter((action) => {
|
|
933
|
+
if (!action.condition) return true;
|
|
934
|
+
try {
|
|
935
|
+
const usertaskWithContext = {
|
|
936
|
+
...this.userTask,
|
|
937
|
+
isConfirmDialog: true,
|
|
938
|
+
};
|
|
939
|
+
const func = Function('fields', 'usertask', 'msg', '"use strict"; return (' + action.condition + ')');
|
|
940
|
+
const result = func(this.formData, usertaskWithContext, this.msg);
|
|
941
|
+
return Boolean(result);
|
|
942
|
+
} catch (err) {
|
|
943
|
+
console.error('Error while evaluating condition: ' + err);
|
|
944
|
+
return false;
|
|
945
|
+
}
|
|
946
|
+
});
|
|
947
947
|
|
|
948
|
-
|
|
949
|
-
|
|
948
|
+
this.actions = [...filteredActions, ...confirmActions];
|
|
949
|
+
}
|
|
950
950
|
});
|
|
951
951
|
}
|
|
952
952
|
|
|
953
953
|
if (!hasConfirmField && this.props.handle_confirmation_dialogs) {
|
|
954
|
-
this.actions = this.props.options.filter(action => {
|
|
954
|
+
this.actions = this.props.options.filter((action) => {
|
|
955
955
|
if (!action.condition) return true;
|
|
956
956
|
try {
|
|
957
957
|
const usertaskWithContext = {
|
|
958
958
|
...this.userTask,
|
|
959
|
-
isConfirmDialog: false
|
|
959
|
+
isConfirmDialog: false,
|
|
960
960
|
};
|
|
961
961
|
const func = Function('fields', 'usertask', 'msg', '"use strict"; return (' + action.condition + ')');
|
|
962
962
|
const result = func(this.formData, usertaskWithContext, this.msg);
|
|
@@ -988,33 +988,30 @@ export default {
|
|
|
988
988
|
this.focusFirstFormField();
|
|
989
989
|
});
|
|
990
990
|
},
|
|
991
|
-
actionFn(action) {
|
|
991
|
+
async actionFn(action) {
|
|
992
992
|
if (action.isConfirmAction && action.confirmFieldId) {
|
|
993
993
|
this.formData[action.confirmFieldId] = action.confirmValue;
|
|
994
994
|
}
|
|
995
995
|
|
|
996
|
-
if (action.label === 'Speichern' || action.label === 'Speichern und nächster') {
|
|
997
|
-
const formkitInputs = this.$refs.form.$el.querySelectorAll('.formkit-outer');
|
|
998
|
-
let allComplete = true;
|
|
999
|
-
|
|
1000
|
-
formkitInputs.forEach((input) => {
|
|
1001
|
-
const dataComplete = input.getAttribute('data-complete');
|
|
1002
|
-
const dataInvalid = input.getAttribute('data-invalid');
|
|
1003
|
-
|
|
1004
|
-
if (dataComplete == null && dataInvalid === 'true') {
|
|
1005
|
-
allComplete = false;
|
|
1006
|
-
}
|
|
1007
|
-
});
|
|
1008
|
-
|
|
1009
|
-
if (!allComplete) return;
|
|
1010
|
-
}
|
|
1011
|
-
|
|
1012
996
|
if (this.checkCondition(action.condition, { isConfirmDialog: this.isConfirmDialog })) {
|
|
1013
997
|
this.showError('');
|
|
1014
998
|
|
|
1015
|
-
|
|
999
|
+
let processedFormData = { ...this.formData };
|
|
1016
1000
|
const formFields = this.userTask.userTaskConfig.formFields;
|
|
1017
1001
|
|
|
1002
|
+
try {
|
|
1003
|
+
console.log(
|
|
1004
|
+
'Processing file fields:',
|
|
1005
|
+
formFields.filter((f) => f.type === 'file')
|
|
1006
|
+
);
|
|
1007
|
+
processedFormData = await this.processFileFields(processedFormData, formFields);
|
|
1008
|
+
console.log('File processing completed successfully');
|
|
1009
|
+
} catch (error) {
|
|
1010
|
+
console.error('Error processing file fields:', error);
|
|
1011
|
+
this.showError('Fehler beim Verarbeiten der Dateien');
|
|
1012
|
+
return;
|
|
1013
|
+
}
|
|
1014
|
+
|
|
1018
1015
|
formFields.forEach((field) => {
|
|
1019
1016
|
const fieldValue = processedFormData[field.id];
|
|
1020
1017
|
|
|
@@ -1040,8 +1037,8 @@ export default {
|
|
|
1040
1037
|
|
|
1041
1038
|
let outputIndex;
|
|
1042
1039
|
if (action.isConfirmAction) {
|
|
1043
|
-
|
|
1044
|
-
|
|
1040
|
+
const confirmActionIndex = action.confirmValue ? 1 : 0;
|
|
1041
|
+
outputIndex = this.props.options.length + confirmActionIndex;
|
|
1045
1042
|
} else {
|
|
1046
1043
|
outputIndex = this.props.options.findIndex((element) => element.label === action.label);
|
|
1047
1044
|
}
|
|
@@ -1055,7 +1052,7 @@ export default {
|
|
|
1055
1052
|
try {
|
|
1056
1053
|
const usertaskWithContext = {
|
|
1057
1054
|
...this.userTask,
|
|
1058
|
-
isConfirmDialog: context.isConfirmDialog || false
|
|
1055
|
+
isConfirmDialog: context.isConfirmDialog || false,
|
|
1059
1056
|
};
|
|
1060
1057
|
|
|
1061
1058
|
const func = Function('fields', 'usertask', 'msg', '"use strict"; return (' + condition + ')');
|
|
@@ -1094,6 +1091,99 @@ export default {
|
|
|
1094
1091
|
}
|
|
1095
1092
|
}
|
|
1096
1093
|
},
|
|
1094
|
+
async convertFileToBase64(file) {
|
|
1095
|
+
return new Promise((resolve, reject) => {
|
|
1096
|
+
const reader = new FileReader();
|
|
1097
|
+
reader.onload = () => {
|
|
1098
|
+
const base64 = reader.result.split(',')[1];
|
|
1099
|
+
resolve({
|
|
1100
|
+
name: file.name,
|
|
1101
|
+
size: file.size,
|
|
1102
|
+
type: file.type,
|
|
1103
|
+
lastModified: file.lastModified,
|
|
1104
|
+
data: base64,
|
|
1105
|
+
});
|
|
1106
|
+
};
|
|
1107
|
+
reader.onerror = reject;
|
|
1108
|
+
reader.readAsDataURL(file);
|
|
1109
|
+
});
|
|
1110
|
+
},
|
|
1111
|
+
async processFileFields(formData, formFields) {
|
|
1112
|
+
const processedData = { ...formData };
|
|
1113
|
+
|
|
1114
|
+
for (const field of formFields) {
|
|
1115
|
+
if (field.type === 'file') {
|
|
1116
|
+
const fieldValue = processedData[field.id];
|
|
1117
|
+
|
|
1118
|
+
if (fieldValue) {
|
|
1119
|
+
const multiple = field.customForm
|
|
1120
|
+
? JSON.parse(JSON.stringify(field.customForm)).multiple === 'true'
|
|
1121
|
+
: false;
|
|
1122
|
+
|
|
1123
|
+
if (multiple && Array.isArray(fieldValue)) {
|
|
1124
|
+
// Handle multiple files
|
|
1125
|
+
const base64Files = [];
|
|
1126
|
+
for (const file of fieldValue) {
|
|
1127
|
+
const processedFile = await this.processIndividualFile(file);
|
|
1128
|
+
if (processedFile) {
|
|
1129
|
+
base64Files.push(processedFile);
|
|
1130
|
+
}
|
|
1131
|
+
}
|
|
1132
|
+
processedData[field.id] = base64Files;
|
|
1133
|
+
} else if (Array.isArray(fieldValue)) {
|
|
1134
|
+
const base64Files = [];
|
|
1135
|
+
for (const file of fieldValue) {
|
|
1136
|
+
const processedFile = await this.processIndividualFile(file);
|
|
1137
|
+
if (processedFile) {
|
|
1138
|
+
base64Files.push(processedFile);
|
|
1139
|
+
}
|
|
1140
|
+
}
|
|
1141
|
+
processedData[field.id] = multiple ? base64Files : base64Files[0] || null;
|
|
1142
|
+
} else if (fieldValue) {
|
|
1143
|
+
const processedFile = await this.processIndividualFile(fieldValue);
|
|
1144
|
+
if (processedFile) {
|
|
1145
|
+
processedData[field.id] = processedFile;
|
|
1146
|
+
}
|
|
1147
|
+
}
|
|
1148
|
+
}
|
|
1149
|
+
}
|
|
1150
|
+
}
|
|
1151
|
+
|
|
1152
|
+
return processedData;
|
|
1153
|
+
},
|
|
1154
|
+
async processIndividualFile(fileData) {
|
|
1155
|
+
let actualFile = null;
|
|
1156
|
+
|
|
1157
|
+
if (fileData instanceof File) {
|
|
1158
|
+
actualFile = fileData;
|
|
1159
|
+
} else if (fileData instanceof FileList && fileData.length > 0) {
|
|
1160
|
+
actualFile = fileData[0];
|
|
1161
|
+
} else if (fileData && fileData.file instanceof File) {
|
|
1162
|
+
actualFile = fileData.file;
|
|
1163
|
+
} else if (fileData && fileData.file instanceof FileList && fileData.file.length > 0) {
|
|
1164
|
+
actualFile = fileData.file[0];
|
|
1165
|
+
} else if (Array.isArray(fileData) && fileData.length > 0) {
|
|
1166
|
+
if (fileData[0] instanceof File) {
|
|
1167
|
+
actualFile = fileData[0];
|
|
1168
|
+
} else if (fileData[0] && fileData[0].file instanceof File) {
|
|
1169
|
+
actualFile = fileData[0].file;
|
|
1170
|
+
} else if (fileData[0] && fileData[0].file instanceof FileList && fileData[0].file.length > 0) {
|
|
1171
|
+
actualFile = fileData[0].file[0];
|
|
1172
|
+
}
|
|
1173
|
+
} else if (typeof fileData === 'object' && fileData.data && fileData.name) {
|
|
1174
|
+
return fileData;
|
|
1175
|
+
}
|
|
1176
|
+
|
|
1177
|
+
if (actualFile instanceof File) {
|
|
1178
|
+
return await this.convertFileToBase64(actualFile);
|
|
1179
|
+
}
|
|
1180
|
+
|
|
1181
|
+
if (fileData && typeof fileData === 'object' && !fileData.data) {
|
|
1182
|
+
console.warn('Could not process file data:', fileData);
|
|
1183
|
+
}
|
|
1184
|
+
|
|
1185
|
+
return fileData;
|
|
1186
|
+
},
|
|
1097
1187
|
},
|
|
1098
1188
|
};
|
|
1099
1189
|
|
|
@@ -1110,6 +1200,5 @@ function mapItems(type, field) {
|
|
|
1110
1200
|
</script>
|
|
1111
1201
|
|
|
1112
1202
|
<style>
|
|
1113
|
-
/* CSS is auto scoped, but using named classes is still recommended */
|
|
1114
1203
|
@import '../stylesheets/ui-dynamic-form.css';
|
|
1115
1204
|
</style>
|
|
@@ -168,7 +168,8 @@ code {
|
|
|
168
168
|
min-height: 36px;
|
|
169
169
|
padding: 8px 12px;
|
|
170
170
|
box-sizing: border-box;
|
|
171
|
-
|
|
171
|
+
white-space: normal;
|
|
172
|
+
word-wrap: break-word;
|
|
172
173
|
}
|
|
173
174
|
|
|
174
175
|
@media screen and (min-width: 600px) {
|
|
@@ -177,10 +178,8 @@ code {
|
|
|
177
178
|
}
|
|
178
179
|
|
|
179
180
|
.ui-dynamic-form-footer-action-button {
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
overflow: hidden;
|
|
183
|
-
text-overflow: ellipsis;
|
|
181
|
+
white-space: normal;
|
|
182
|
+
word-wrap: break-word;
|
|
184
183
|
}
|
|
185
184
|
}
|
|
186
185
|
|
|
@@ -287,15 +286,13 @@ code {
|
|
|
287
286
|
font-size: 16px;
|
|
288
287
|
width: 100%;
|
|
289
288
|
box-sizing: border-box;
|
|
290
|
-
white-space:
|
|
291
|
-
|
|
292
|
-
text-overflow: ellipsis;
|
|
289
|
+
white-space: normal;
|
|
290
|
+
word-wrap: break-word;
|
|
293
291
|
}
|
|
294
292
|
|
|
295
293
|
.ui-dynamic-form-footer-action-button .v-btn__content {
|
|
296
|
-
white-space:
|
|
297
|
-
|
|
298
|
-
text-overflow: ellipsis !important;
|
|
294
|
+
white-space: normal !important;
|
|
295
|
+
word-wrap: break-word !important;
|
|
299
296
|
max-width: 100% !important;
|
|
300
297
|
display: block !important;
|
|
301
298
|
}
|
|
@@ -310,9 +307,8 @@ code {
|
|
|
310
307
|
|
|
311
308
|
.ui-dynamic-form-footer-action-primary .v-btn__content,
|
|
312
309
|
.ui-dynamic-form-footer-action-secondary .v-btn__content {
|
|
313
|
-
white-space:
|
|
314
|
-
|
|
315
|
-
text-overflow: ellipsis !important;
|
|
310
|
+
white-space: normal !important;
|
|
311
|
+
word-wrap: break-word !important;
|
|
316
312
|
max-width: 100% !important;
|
|
317
313
|
display: block !important;
|
|
318
314
|
}
|