@controleonline/ui-common 1.2.83 → 1.2.85
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/package.json
CHANGED
|
@@ -15,7 +15,42 @@ import DefaultUpload from '@controleonline/ui-default/src/react/components/uploa
|
|
|
15
15
|
import { resolveSystemErrorMessage } from '@controleonline/ui-common/src/react/utils/systemErrorMessage';
|
|
16
16
|
import styles from './AddImportModal.styles';
|
|
17
17
|
|
|
18
|
-
const AddImportModal = ({
|
|
18
|
+
const AddImportModal = ({
|
|
19
|
+
visible,
|
|
20
|
+
onClose,
|
|
21
|
+
onSuccess,
|
|
22
|
+
context = {},
|
|
23
|
+
allowedExtensions = [], // default will be set to ['csv'] if empty
|
|
24
|
+
// acceptedTypes will be derived from allowedExtensions for security
|
|
25
|
+
helperLabel,
|
|
26
|
+
modalTitle,
|
|
27
|
+
fileLabel,
|
|
28
|
+
selectFileLabel,
|
|
29
|
+
cancelLabel,
|
|
30
|
+
importSuccessLabel,
|
|
31
|
+
importErrorLabel,
|
|
32
|
+
importType = null,
|
|
33
|
+
}) => {
|
|
34
|
+
const fallbackModalTitle = global.t?.t('imports', 'title', 'new_import');
|
|
35
|
+
const fallbackFileLabel = global.t?.t('imports', 'label', 'file');
|
|
36
|
+
const fallbackSelectFileLabel = global.t?.t('imports', 'button', 'select_file');
|
|
37
|
+
const fallbackCancelLabel = global.t?.t('imports', 'button', 'cancel');
|
|
38
|
+
const fallbackSuccessLabel = global.t?.t('imports', 'success', 'import_sent_successfully');
|
|
39
|
+
const fallbackErrorLabel = global.t?.t('imports', 'error', 'error_sending_import');
|
|
40
|
+
const fallbackInvalidFileLabel = global.t?.t('imports', 'message', 'invalid_file_extension');
|
|
41
|
+
const _modalTitle = modalTitle ?? fallbackModalTitle;
|
|
42
|
+
const _fileLabel = fileLabel ?? fallbackFileLabel;
|
|
43
|
+
const _selectFileLabel = selectFileLabel ?? fallbackSelectFileLabel;
|
|
44
|
+
const _cancelLabel = cancelLabel ?? fallbackCancelLabel;
|
|
45
|
+
const _importSuccessLabel = importSuccessLabel ?? fallbackSuccessLabel;
|
|
46
|
+
const _importErrorLabel = importErrorLabel ?? fallbackErrorLabel;
|
|
47
|
+
const _helperLabel = helperLabel ?? fallbackInvalidFileLabel;
|
|
48
|
+
// Resolve allowed extensions securely – default to CSV only
|
|
49
|
+
const _allowedExtensions = (allowedExtensions && allowedExtensions.length > 0) ? allowedExtensions : ['csv'];
|
|
50
|
+
// Build acceptedTypes string for file input (e.g., ".csv,.xml,.zip")
|
|
51
|
+
const _acceptedTypes = _allowedExtensions.map(ext => `.${ext}`).join(',');
|
|
52
|
+
// Determine import type: prioritize prop, then infer from allowed extensions, default to 'csv'
|
|
53
|
+
const _importType = importType ?? (_allowedExtensions.includes('xml') ? 'xml' : (_allowedExtensions.includes('zip') ? 'zip' : 'csv'));
|
|
19
54
|
const { showError, showSuccess } = useMessage();
|
|
20
55
|
const peopleStore = useStore('people');
|
|
21
56
|
const importsStore = useStore('imports');
|
|
@@ -31,32 +66,29 @@ const AddImportModal = ({ visible, onClose, onSuccess, context = {} }) => {
|
|
|
31
66
|
buttonIcon: themeColors.buttonIcon || themeColors.buttonText,
|
|
32
67
|
};
|
|
33
68
|
|
|
34
|
-
|
|
35
|
-
const csvLabel = global.t?.t('imports', 'label', 'csv_file');
|
|
36
|
-
const selectFileLabel = global.t?.t('imports', 'button', 'select_file');
|
|
37
|
-
const cancelLabel = global.t?.t('imports', 'button', 'cancel');
|
|
38
|
-
const csvOnlyLabel = global.t?.t('imports', 'message', 'only_csv_files_are_allowed');
|
|
39
|
-
const importSuccessLabel = global.t?.t('imports', 'success', 'import_sent_successfully');
|
|
40
|
-
const importErrorLabel = global.t?.t('imports', 'error', 'error_sending_import');
|
|
69
|
+
|
|
41
70
|
|
|
42
71
|
const handleUploadImportFile = async ({ file }) => {
|
|
43
|
-
if (
|
|
44
|
-
|
|
72
|
+
if (_allowedExtensions.length > 0) {
|
|
73
|
+
const extensionRegex = new RegExp(`\\.(${_allowedExtensions.join('|')})$`, 'i');
|
|
74
|
+
if (!file?.name?.toLowerCase().match(extensionRegex)) {
|
|
75
|
+
throw new Error(_helperLabel);
|
|
76
|
+
}
|
|
45
77
|
}
|
|
46
78
|
|
|
47
79
|
try {
|
|
48
80
|
await importActions.uploadImportFile({
|
|
49
81
|
file,
|
|
50
|
-
importType:
|
|
82
|
+
importType: _importType,
|
|
51
83
|
peopleId: currentCompany.id,
|
|
52
84
|
});
|
|
53
|
-
showSuccess(
|
|
85
|
+
showSuccess(_importSuccessLabel);
|
|
54
86
|
if (onSuccess) onSuccess();
|
|
55
87
|
handleClose();
|
|
56
88
|
return file;
|
|
57
89
|
} catch (error) {
|
|
58
90
|
const importFeedback =
|
|
59
|
-
resolveSystemErrorMessage(error) ||
|
|
91
|
+
resolveSystemErrorMessage(error) || _importErrorLabel;
|
|
60
92
|
showError(importFeedback);
|
|
61
93
|
throw new Error(importFeedback);
|
|
62
94
|
}
|
|
@@ -74,31 +106,30 @@ const AddImportModal = ({ visible, onClose, onSuccess, context = {} }) => {
|
|
|
74
106
|
>
|
|
75
107
|
<View style={styles.sheet}>
|
|
76
108
|
<View style={styles.header}>
|
|
77
|
-
<Text style={styles.title}>{
|
|
109
|
+
<Text style={styles.title}>{_modalTitle}</Text>
|
|
78
110
|
<TouchableOpacity onPress={handleClose}>
|
|
79
111
|
<Icon name="close" size={24} />
|
|
80
112
|
</TouchableOpacity>
|
|
81
113
|
</View>
|
|
82
114
|
|
|
83
115
|
<ScrollView style={styles.content}>
|
|
84
|
-
<Text style={styles.label}>{
|
|
116
|
+
<Text style={styles.label}>{_fileLabel}</Text>
|
|
85
117
|
<DefaultUpload
|
|
86
|
-
relationStoreName="imports"
|
|
87
118
|
relationField="import"
|
|
88
119
|
relationResource="imports"
|
|
89
120
|
entityId={context.context || 'import'}
|
|
90
121
|
companyId={currentCompany.id}
|
|
91
122
|
context={`imports-${context.context || 'default'}`}
|
|
92
123
|
libraryContexts={[`imports-${context.context || 'default'}`]}
|
|
93
|
-
acceptedTypes=
|
|
124
|
+
acceptedTypes={_acceptedTypes}
|
|
94
125
|
fileType=""
|
|
95
|
-
title={
|
|
96
|
-
triggerLabel={
|
|
97
|
-
managerTitle={
|
|
98
|
-
searchPlaceholder={
|
|
99
|
-
uploadButtonLabel={
|
|
126
|
+
title={_fileLabel}
|
|
127
|
+
triggerLabel={_selectFileLabel}
|
|
128
|
+
managerTitle={_modalTitle}
|
|
129
|
+
searchPlaceholder={_selectFileLabel}
|
|
130
|
+
uploadButtonLabel={_selectFileLabel}
|
|
100
131
|
emptyAttachmentLabel=""
|
|
101
|
-
emptyLibraryLabel={
|
|
132
|
+
emptyLibraryLabel={_selectFileLabel}
|
|
102
133
|
showInlineContent={false}
|
|
103
134
|
uploadResultAlreadyAttached
|
|
104
135
|
requireEntity={false}
|
|
@@ -126,14 +157,12 @@ const AddImportModal = ({ visible, onClose, onSuccess, context = {} }) => {
|
|
|
126
157
|
</TouchableOpacity>
|
|
127
158
|
)}
|
|
128
159
|
/>
|
|
129
|
-
|
|
130
|
-
{csvOnlyLabel}
|
|
131
|
-
</Text>
|
|
160
|
+
|
|
132
161
|
</ScrollView>
|
|
133
162
|
|
|
134
163
|
<View style={styles.footer}>
|
|
135
164
|
<TouchableOpacity onPress={handleClose} style={styles.secondaryButton}>
|
|
136
|
-
<Text>{
|
|
165
|
+
<Text>{_cancelLabel}</Text>
|
|
137
166
|
</TouchableOpacity>
|
|
138
167
|
</View>
|
|
139
168
|
</View>
|