@topconsultnpm/sdkui-react-beta 6.8.81 → 6.8.83
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/lib/assets/icomoon.svg +96 -96
- package/lib/assets/thumbnails/index.d.ts +19 -0
- package/lib/assets/thumbnails/index.js +19 -0
- package/lib/components/base/TMAreaManager.d.ts +25 -0
- package/lib/components/base/TMAreaManager.js +583 -0
- package/lib/components/base/TMCounterBar.js +2 -0
- package/lib/helper/SDKUI_Localizator.d.ts +11 -0
- package/lib/helper/SDKUI_Localizator.js +109 -0
- package/package.json +1 -1
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import IconFolder from './folder.png';
|
|
2
|
+
import IconPdf from './pdf.png';
|
|
3
|
+
import IconTxt from './txt.png';
|
|
4
|
+
import IconXls from './xls.png';
|
|
5
|
+
import IconDocx from './doc.png';
|
|
6
|
+
import IconImage from './image.png';
|
|
7
|
+
import IconZip from './zip.png';
|
|
8
|
+
import IconXml from './xml.png';
|
|
9
|
+
import IconMp4 from './mp4.png';
|
|
10
|
+
import IconEmail from './email.png';
|
|
11
|
+
import IconPpt from './ppt.png';
|
|
12
|
+
import IconSigned from './p7m.png';
|
|
13
|
+
import IconOther from './other.png';
|
|
14
|
+
import IconExe from './exe.png';
|
|
15
|
+
import IconHtml from './html.png';
|
|
16
|
+
import IconDwg from './dwg.png';
|
|
17
|
+
import IconDicom from './dicom.png';
|
|
18
|
+
import IconSlddrw from './slddrw.png';
|
|
19
|
+
export { IconFolder, IconPdf, IconTxt, IconXls, IconDocx, IconImage, IconZip, IconXml, IconMp4, IconEmail, IconPpt, IconSigned, IconOther, IconExe, IconHtml, IconDwg, IconDicom, IconSlddrw };
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { ITopMediaSession } from '@topconsultnpm/sdk-ts-beta';
|
|
3
|
+
export declare class TMFileSystemItem {
|
|
4
|
+
dataItem: any;
|
|
5
|
+
name: string;
|
|
6
|
+
thumbnail: string;
|
|
7
|
+
isDirectory: boolean;
|
|
8
|
+
size: number | undefined;
|
|
9
|
+
dateModified: Date | undefined;
|
|
10
|
+
}
|
|
11
|
+
interface ITMAreaManager {
|
|
12
|
+
width?: string;
|
|
13
|
+
height?: string;
|
|
14
|
+
areaChoose?: any;
|
|
15
|
+
initialPath?: string;
|
|
16
|
+
areaStatus?: boolean;
|
|
17
|
+
isPathChooser?: boolean;
|
|
18
|
+
showOnlyFolders?: boolean;
|
|
19
|
+
tmSession?: ITopMediaSession;
|
|
20
|
+
selectionMode?: 'single' | 'multiple';
|
|
21
|
+
onFileChanged?: (event: string) => void;
|
|
22
|
+
onFolderChanged?: (event: string) => void;
|
|
23
|
+
}
|
|
24
|
+
declare const TMAreaManager: React.FC<ITMAreaManager>;
|
|
25
|
+
export default TMAreaManager;
|
|
@@ -0,0 +1,583 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useCallback, useEffect, useRef, useState } from 'react';
|
|
3
|
+
import FileManager, { Column, Details, ItemView, Permissions, Notifications, ContextMenu } from 'devextreme-react/file-manager';
|
|
4
|
+
import { FileDescriptor, FileFormats, FileTransferModes, SDK_Localizator, SDK_Globals } from '@topconsultnpm/sdk-ts-beta';
|
|
5
|
+
import CustomFileSystemProvider from 'devextreme/file_management/custom_provider';
|
|
6
|
+
import FileSystemError from "devextreme/file_management/error";
|
|
7
|
+
import Button from "devextreme/ui/button";
|
|
8
|
+
import { alert, confirm } from "devextreme/ui/dialog";
|
|
9
|
+
import { loadMessages } from 'devextreme/localization';
|
|
10
|
+
import { Globalization, IconAll, IconSelected, SDKUI_Localizator } from '../../helper';
|
|
11
|
+
import { TMExceptionBoxManager } from './TMPopUp';
|
|
12
|
+
import ShowAlert from './TMAlert';
|
|
13
|
+
import { IconFolder, IconPdf, IconTxt, IconXls, IconDocx, IconImage, IconZip, IconXml, IconMp4, IconEmail, IconPpt, IconSigned, IconExe, IconHtml, IconDwg, IconDicom, IconSlddrw } from '../../assets/thumbnails';
|
|
14
|
+
import { TMLayoutWaitingContainer } from './TMWaitPanel';
|
|
15
|
+
import TMCounterBar from './TMCounterBar';
|
|
16
|
+
export class TMFileSystemItem {
|
|
17
|
+
constructor() {
|
|
18
|
+
this.name = "";
|
|
19
|
+
this.thumbnail = "";
|
|
20
|
+
this.isDirectory = false;
|
|
21
|
+
this.size = 0;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
let abortController = new AbortController();
|
|
25
|
+
const TMAreaManager = (props = { selectionMode: 'multiple', isPathChooser: false }) => {
|
|
26
|
+
const [counter, setCounter] = useState(0);
|
|
27
|
+
const [areaFile, setAreaFile] = useState('');
|
|
28
|
+
const [areaFolder, setAreaFolder] = useState('');
|
|
29
|
+
const [currentRoute, setCurrentRoute] = useState('');
|
|
30
|
+
const [parentDir, setParentDir] = useState(null);
|
|
31
|
+
const [areas, setAreas] = useState([]);
|
|
32
|
+
const [selectedItemsCount, setSelectedItemsCount] = useState(0);
|
|
33
|
+
const [areaProvider, setAreaProvider] = useState();
|
|
34
|
+
const [selectionMode, setSelectionMode] = useState('single');
|
|
35
|
+
const [showWaitPanel, setShowWaitPanel] = useState(false);
|
|
36
|
+
const [waitPanelTitle, setWaitPanelTitle] = useState('');
|
|
37
|
+
const [showPrimary, setShowPrimary] = useState(false);
|
|
38
|
+
const [waitPanelTextPrimary, setWaitPanelTextPrimary] = useState('');
|
|
39
|
+
const [waitPanelValuePrimary, setWaitPanelValuePrimary] = useState(0);
|
|
40
|
+
const [waitPanelMaxValuePrimary, setWaitPanelMaxValuePrimary] = useState(0);
|
|
41
|
+
const [showSecondary, setShowSecondary] = useState(false);
|
|
42
|
+
const [waitPanelTextSecondary, setWaitPanelTextSecondary] = useState('');
|
|
43
|
+
const [waitPanelValueSecondary, setWaitPanelValueSecondary] = useState(0);
|
|
44
|
+
const [waitPanelMaxValueSecondary, setWaitPanelMaxValueSecondary] = useState(0);
|
|
45
|
+
let timerId = null;
|
|
46
|
+
const AreaFolderNamePrefix = "AID_";
|
|
47
|
+
const AreaPathPrefix = "tmarea:\\\\";
|
|
48
|
+
let resolvesForExistingFiles = [];
|
|
49
|
+
let resolvesForNonExistingFiles = [];
|
|
50
|
+
let destinationDirectoryContentPromise = null;
|
|
51
|
+
const fileManagerRef = useRef(null);
|
|
52
|
+
let _cacheUploadFileId = new Map();
|
|
53
|
+
useEffect(() => {
|
|
54
|
+
if (areaProvider)
|
|
55
|
+
return;
|
|
56
|
+
setAreaProvider(new CustomFileSystemProvider({
|
|
57
|
+
copyItem,
|
|
58
|
+
getItems,
|
|
59
|
+
moveItem,
|
|
60
|
+
renameItem,
|
|
61
|
+
deleteItem,
|
|
62
|
+
downloadItems,
|
|
63
|
+
uploadFileChunk,
|
|
64
|
+
createDirectory
|
|
65
|
+
}));
|
|
66
|
+
loadMessages({
|
|
67
|
+
"it": {
|
|
68
|
+
"dxFileManager-dialogDeleteItemSingleItemConfirmation": "Sei sicuro di voler eliminare {0}?",
|
|
69
|
+
"dxFileManager-dialogDeleteItemMultipleItemsConfirmation": "Sei sicuro di voler eliminare {0} elementi?"
|
|
70
|
+
},
|
|
71
|
+
"fr": {
|
|
72
|
+
"dxFileManager-dialogDeleteItemSingleItemConfirmation": "Êtes-vous sûr de vouloir supprimer {0}?",
|
|
73
|
+
"dxFileManager-dialogDeleteItemMultipleItemsConfirmation": "Êtes-vous sûr de vouloir supprimer {0} éléments?"
|
|
74
|
+
},
|
|
75
|
+
"pt": {
|
|
76
|
+
"dxFileManager-dialogDeleteItemSingleItemConfirmation": "Tem a certeza de que pretende eliminar {0}?",
|
|
77
|
+
"dxFileManager-dialogDeleteItemMultipleItemsConfirmation": "Tem a certeza de que pretende eliminar {0} itens?"
|
|
78
|
+
},
|
|
79
|
+
"de": {
|
|
80
|
+
"dxFileManager-dialogDeleteItemSingleItemConfirmation": "Möchten Sie {0} wirklich löschen?",
|
|
81
|
+
"dxFileManager-dialogDeleteItemMultipleItemsConfirmation": "Möchten Sie {0} Elemente wirklich löschen?"
|
|
82
|
+
},
|
|
83
|
+
"es": {
|
|
84
|
+
"dxFileManager-dialogDeleteItemSingleItemConfirmation": "¿Estás seguro de que quieres eliminar {0}?",
|
|
85
|
+
"dxFileManager-dialogDeleteItemMultipleItemsConfirmation": "¿Estás seguro de que quieres eliminar {0} artículos?"
|
|
86
|
+
},
|
|
87
|
+
"en": {
|
|
88
|
+
"dxFileManager-dialogDeleteItemSingleItemConfirmation": "Are you sure you want to delete {0}?",
|
|
89
|
+
"dxFileManager-dialogDeleteItemMultipleItemsConfirmation": "Are you sure you want to delete {0} items?"
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
}, []);
|
|
93
|
+
useEffect(() => {
|
|
94
|
+
const btnNewDir = document.querySelector(".dx-filemanager-wrapper [aria-label='Nuova cartella']");
|
|
95
|
+
const instanceBtnNewDir = Button.getInstance(btnNewDir);
|
|
96
|
+
const btnSearchFile = document.querySelector(".dx-filemanager-wrapper [aria-label='Carica i files']");
|
|
97
|
+
const instanceBtnSearchFile = Button.getInstance(btnSearchFile);
|
|
98
|
+
if (currentRoute === '') {
|
|
99
|
+
initCounter();
|
|
100
|
+
instanceBtnNewDir?.option("disabled", true);
|
|
101
|
+
instanceBtnSearchFile?.option("disabled", true);
|
|
102
|
+
}
|
|
103
|
+
else {
|
|
104
|
+
instanceBtnNewDir?.option("disabled", false);
|
|
105
|
+
instanceBtnSearchFile?.option("disabled", false);
|
|
106
|
+
}
|
|
107
|
+
}, [parentDir, currentRoute]);
|
|
108
|
+
useEffect(() => {
|
|
109
|
+
if (!props.initialPath?.startsWith(AreaPathPrefix))
|
|
110
|
+
return;
|
|
111
|
+
//Rimuovere i prefissi
|
|
112
|
+
let curFld = props.initialPath?.replace(AreaPathPrefix, '').replace(AreaFolderNamePrefix, '');
|
|
113
|
+
const keys = curFld?.split("\\");
|
|
114
|
+
if (!keys || keys.length === 0)
|
|
115
|
+
return;
|
|
116
|
+
const aid = keys[0];
|
|
117
|
+
const ad = areas.find(ad => ad.id?.toString() == aid);
|
|
118
|
+
//sostituire ID Area con il nome
|
|
119
|
+
curFld = curFld?.replace(keys[0], ad?.name ?? '').replaceAll("\\", "/");
|
|
120
|
+
if (!props.showOnlyFolders) {
|
|
121
|
+
fileManagerRef.current?.instance().option("focusedItemKey", curFld);
|
|
122
|
+
// Se lavoriamo con i files impostiamo la folder parent
|
|
123
|
+
curFld = curFld.replace(keys[keys.length - 1], "");
|
|
124
|
+
}
|
|
125
|
+
fileManagerRef.current?.instance().option("currentPath", curFld);
|
|
126
|
+
}, [areas]);
|
|
127
|
+
useEffect(() => {
|
|
128
|
+
props.onFolderChanged?.(areaFolder);
|
|
129
|
+
}, [areaFolder]);
|
|
130
|
+
useEffect(() => {
|
|
131
|
+
props.onFileChanged?.(areaFile);
|
|
132
|
+
}, [areaFile]);
|
|
133
|
+
useEffect(() => {
|
|
134
|
+
setSelectionMode('multiple');
|
|
135
|
+
fileManagerRef.current?.instance().refresh();
|
|
136
|
+
}, [props.areaStatus]);
|
|
137
|
+
const initCounter = async () => {
|
|
138
|
+
const tms = props.tmSession ?? SDK_Globals.tmSession;
|
|
139
|
+
const adlist = await tms?.NewAreaEngine().RetrieveAllAsync();
|
|
140
|
+
if (adlist)
|
|
141
|
+
setCounter(adlist.length);
|
|
142
|
+
};
|
|
143
|
+
const checkTargetDirectory = (operationType, e, data, resolve) => {
|
|
144
|
+
const fileExists = !!data.find((x) => x.name === (operationType === 'copyOrMove' ? e.item.name : e.fileData.name));
|
|
145
|
+
if (fileExists) {
|
|
146
|
+
resolvesForExistingFiles.push(resolve);
|
|
147
|
+
}
|
|
148
|
+
else {
|
|
149
|
+
resolvesForNonExistingFiles.push(resolve);
|
|
150
|
+
}
|
|
151
|
+
if (!timerId) {
|
|
152
|
+
timerId = setTimeout(() => {
|
|
153
|
+
const showDialog = resolvesForExistingFiles.length > 0;
|
|
154
|
+
if (showDialog) {
|
|
155
|
+
let msg = '';
|
|
156
|
+
if (resolvesForExistingFiles.length === 1) {
|
|
157
|
+
msg = SDKUI_Localizator.FileManager_QuestionAlreadyExistsFile.replaceParams(operationType === 'copyOrMove' ? e.item.name : e.fileData.name);
|
|
158
|
+
}
|
|
159
|
+
else {
|
|
160
|
+
msg = SDKUI_Localizator.FileManager_QuestionAlreadyExistsFiles.replaceParams(resolvesForExistingFiles.length.toString());
|
|
161
|
+
}
|
|
162
|
+
const result = confirm(msg, SDKUI_Localizator.Attention);
|
|
163
|
+
result.then((dialogResult) => {
|
|
164
|
+
resolvesForNonExistingFiles.forEach((res) => {
|
|
165
|
+
res({
|
|
166
|
+
cancel: false,
|
|
167
|
+
});
|
|
168
|
+
});
|
|
169
|
+
if (dialogResult) {
|
|
170
|
+
resolvesForExistingFiles.forEach((res) => {
|
|
171
|
+
res({
|
|
172
|
+
cancel: false,
|
|
173
|
+
});
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
else {
|
|
177
|
+
resolvesForExistingFiles.forEach((res) => {
|
|
178
|
+
res({
|
|
179
|
+
cancel: fileExists,
|
|
180
|
+
errorCode: fileExists ? 1 : 0,
|
|
181
|
+
errorText: fileExists ? SDKUI_Localizator.OverwritingCanceled : "",
|
|
182
|
+
});
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
clearTempData();
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
else {
|
|
189
|
+
resolvesForNonExistingFiles.forEach((res) => {
|
|
190
|
+
res({
|
|
191
|
+
cancel: false,
|
|
192
|
+
});
|
|
193
|
+
});
|
|
194
|
+
clearTempData();
|
|
195
|
+
}
|
|
196
|
+
}, 200);
|
|
197
|
+
}
|
|
198
|
+
};
|
|
199
|
+
const onItemCopying = (e) => {
|
|
200
|
+
new Promise((resolve) => {
|
|
201
|
+
const provider = e.component.option("fileSystemProvider");
|
|
202
|
+
if (!destinationDirectoryContentPromise) {
|
|
203
|
+
destinationDirectoryContentPromise = new Promise((res) => {
|
|
204
|
+
provider.getItems(e.destinationDirectory).then((data) => {
|
|
205
|
+
res(data);
|
|
206
|
+
checkTargetDirectory('copyOrMove', e, data, resolve);
|
|
207
|
+
});
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
else {
|
|
211
|
+
destinationDirectoryContentPromise.then((data) => {
|
|
212
|
+
checkTargetDirectory('copyOrMove', e, data, resolve);
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
});
|
|
216
|
+
};
|
|
217
|
+
const onFileUploading = (e) => {
|
|
218
|
+
new Promise((resolve) => {
|
|
219
|
+
const provider = e.component.option("fileSystemProvider");
|
|
220
|
+
if (!destinationDirectoryContentPromise) {
|
|
221
|
+
destinationDirectoryContentPromise = new Promise((res) => {
|
|
222
|
+
provider.getItems(e.destinationDirectory).then((data) => {
|
|
223
|
+
res(data);
|
|
224
|
+
checkTargetDirectory('upload', e, data, resolve);
|
|
225
|
+
});
|
|
226
|
+
});
|
|
227
|
+
}
|
|
228
|
+
else {
|
|
229
|
+
destinationDirectoryContentPromise.then((data) => {
|
|
230
|
+
checkTargetDirectory('upload', e, data, resolve);
|
|
231
|
+
});
|
|
232
|
+
}
|
|
233
|
+
});
|
|
234
|
+
};
|
|
235
|
+
const clearTempData = () => {
|
|
236
|
+
timerId = null;
|
|
237
|
+
resolvesForExistingFiles = [];
|
|
238
|
+
resolvesForNonExistingFiles = [];
|
|
239
|
+
destinationDirectoryContentPromise = null;
|
|
240
|
+
};
|
|
241
|
+
const getAreaPath = (aid, subFolder) => {
|
|
242
|
+
if (aid <= 0)
|
|
243
|
+
return '';
|
|
244
|
+
if (subFolder === undefined)
|
|
245
|
+
subFolder = '';
|
|
246
|
+
let areaPath = `${AreaPathPrefix}${AreaFolderNamePrefix}${aid}\\${subFolder.replaceAll("/", "\\")}`;
|
|
247
|
+
if (props.showOnlyFolders && !areaPath.toLowerCase().endsWith("\\"))
|
|
248
|
+
areaPath += "\\";
|
|
249
|
+
return areaPath;
|
|
250
|
+
};
|
|
251
|
+
const blobToBase64Async = async (file) => {
|
|
252
|
+
return new Promise((resolve, reject) => {
|
|
253
|
+
const fileReader = new FileReader();
|
|
254
|
+
fileReader.onerror = () => reject(fileReader.error);
|
|
255
|
+
fileReader.onloadend = () => {
|
|
256
|
+
const dataUrl = fileReader.result;
|
|
257
|
+
// remove "data:mime/type;base64," prefix from data url
|
|
258
|
+
const base64 = dataUrl.substring(dataUrl.indexOf(',') + 1);
|
|
259
|
+
resolve(base64);
|
|
260
|
+
};
|
|
261
|
+
fileReader.readAsDataURL(file);
|
|
262
|
+
});
|
|
263
|
+
};
|
|
264
|
+
const createDirectory = async (parentDirectory, name) => {
|
|
265
|
+
if (parentDirectory.path === '' && parentDirectory.name === '') {
|
|
266
|
+
throw new FileSystemError(5, parentDirectory, "Selezionare un'area di appoggio");
|
|
267
|
+
}
|
|
268
|
+
const ad = parentDirectory.dataItem.dataItem;
|
|
269
|
+
const aid = ad.id;
|
|
270
|
+
const subFolder = parentDirectory.path === ad.name ? '' : parentDirectory.path.replace(ad.name + '/', '');
|
|
271
|
+
const tms = props.tmSession ?? SDK_Globals.tmSession;
|
|
272
|
+
await tms?.NewAreaEngine().AddFolderAsync(aid, subFolder, name);
|
|
273
|
+
};
|
|
274
|
+
const copyItem = async (item, destinationDirectory) => {
|
|
275
|
+
copyOrMoveItem(item, destinationDirectory, false);
|
|
276
|
+
};
|
|
277
|
+
const moveItem = async (item, destinationDirectory) => {
|
|
278
|
+
copyOrMoveItem(item, destinationDirectory, true);
|
|
279
|
+
};
|
|
280
|
+
const copyOrMoveItem = async (itemSource, destinationDirectory, deleteSource) => {
|
|
281
|
+
const adSource = itemSource.dataItem.dataItem;
|
|
282
|
+
const aidSource = adSource.id;
|
|
283
|
+
let subFolderSource = '';
|
|
284
|
+
const adDest = destinationDirectory.dataItem.dataItem;
|
|
285
|
+
const aidDest = adDest.id;
|
|
286
|
+
const subFolderDest = destinationDirectory.path === adDest.name ? '' : destinationDirectory.path.replace(adDest.name + '/', '');
|
|
287
|
+
const tms = props.tmSession ?? SDK_Globals.tmSession;
|
|
288
|
+
if (itemSource.isDirectory) {
|
|
289
|
+
subFolderSource = itemSource.path === adSource.name ? '' : itemSource.path.replace(adSource.name + '/', '');
|
|
290
|
+
await tms?.NewAreaEngine().CopyFolderAsync(aidSource, subFolderSource, aidDest, subFolderDest, deleteSource, true).catch((err) => { TMExceptionBoxManager.show({ exception: err }); });
|
|
291
|
+
}
|
|
292
|
+
else {
|
|
293
|
+
subFolderSource = itemSource.parentPath === adSource.name ? '' : itemSource.parentPath.replace(adSource.name + '/', '');
|
|
294
|
+
await tms?.NewAreaEngine().CopyFilesAsync(aidSource, subFolderSource, [itemSource.name], aidDest, subFolderDest, deleteSource, true).catch((err) => { TMExceptionBoxManager.show({ exception: err }); });
|
|
295
|
+
}
|
|
296
|
+
};
|
|
297
|
+
const deleteItem = async (item) => {
|
|
298
|
+
const ad = item.dataItem.dataItem;
|
|
299
|
+
const aid = ad.id;
|
|
300
|
+
const subFolder = item.parentPath === ad.name ? '' : item.parentPath.replace(ad.name + '/', '');
|
|
301
|
+
const tms = props.tmSession ?? SDK_Globals.tmSession;
|
|
302
|
+
if (item.isDirectory) {
|
|
303
|
+
await tms?.NewAreaEngine().DeleteFoldersAsync(aid, subFolder, [item.name]).catch((err) => TMExceptionBoxManager.show({ exception: err }));
|
|
304
|
+
}
|
|
305
|
+
else {
|
|
306
|
+
await tms?.NewAreaEngine().DeleteFilesAsync(aid, subFolder, [item.name]).catch((err) => TMExceptionBoxManager.show({ exception: err }));
|
|
307
|
+
}
|
|
308
|
+
};
|
|
309
|
+
const downloadItems = async (items) => {
|
|
310
|
+
try {
|
|
311
|
+
setShowWaitPanel(true);
|
|
312
|
+
setShowPrimary(items.length > 1);
|
|
313
|
+
setShowSecondary(true);
|
|
314
|
+
setWaitPanelTitle("Download");
|
|
315
|
+
abortController = new AbortController();
|
|
316
|
+
let i = 0;
|
|
317
|
+
setWaitPanelMaxValuePrimary(items.length);
|
|
318
|
+
let firstBlock = true;
|
|
319
|
+
let maxFileSize = 0;
|
|
320
|
+
for (const item of items) {
|
|
321
|
+
if (item.isDirectory)
|
|
322
|
+
continue;
|
|
323
|
+
if (abortController.signal.aborted) {
|
|
324
|
+
ShowAlert({ message: 'Operazione interrotta', mode: 'warning', title: "Download files", duration: 3000 });
|
|
325
|
+
return;
|
|
326
|
+
}
|
|
327
|
+
setWaitPanelTextPrimary(`Download ${item.name}`);
|
|
328
|
+
const ad = item.dataItem.dataItem;
|
|
329
|
+
const aid = ad?.id;
|
|
330
|
+
const subFolder = item.parentPath === ad.name ? '' : item.parentPath.replace(ad.name + '/', '');
|
|
331
|
+
const tms = props.tmSession ?? SDK_Globals.tmSession;
|
|
332
|
+
const file = await tms?.NewAreaEngine().RetrieveFileAsync(aid, subFolder, item.name, FileFormats.None, abortController.signal, (pd) => {
|
|
333
|
+
if (firstBlock) {
|
|
334
|
+
maxFileSize = pd.ProgressBarMaximum ?? 0;
|
|
335
|
+
setWaitPanelMaxValueSecondary(maxFileSize);
|
|
336
|
+
firstBlock = false;
|
|
337
|
+
}
|
|
338
|
+
setWaitPanelValueSecondary(pd.ProgressBarValue);
|
|
339
|
+
setWaitPanelTextSecondary(`Downloading... ${Globalization.getNumberDisplayValue(pd.ProgressBarValue, true)} / ${Globalization.getNumberDisplayValue(maxFileSize, true)}`);
|
|
340
|
+
if (pd.ProgressBarValue === pd.ProgressBarMaximum) {
|
|
341
|
+
setWaitPanelMaxValueSecondary(0);
|
|
342
|
+
setWaitPanelValueSecondary(0);
|
|
343
|
+
setWaitPanelTextSecondary('');
|
|
344
|
+
firstBlock = true;
|
|
345
|
+
}
|
|
346
|
+
});
|
|
347
|
+
setWaitPanelValuePrimary(i + 1);
|
|
348
|
+
const fileURL = window.URL.createObjectURL(file);
|
|
349
|
+
const alink2 = document.createElement('a');
|
|
350
|
+
alink2.href = fileURL;
|
|
351
|
+
alink2.download = file?.name;
|
|
352
|
+
alink2.target = "_blank";
|
|
353
|
+
alink2.rel = "noreferrer";
|
|
354
|
+
alink2.click();
|
|
355
|
+
i++;
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
catch (ex) {
|
|
359
|
+
const err = ex;
|
|
360
|
+
if (err.name === 'CanceledError') {
|
|
361
|
+
ShowAlert({ message: err.message, mode: 'warning', duration: 3000, title: 'Abort' });
|
|
362
|
+
}
|
|
363
|
+
else
|
|
364
|
+
TMExceptionBoxManager.show({ exception: ex });
|
|
365
|
+
}
|
|
366
|
+
finally {
|
|
367
|
+
setWaitPanelTextPrimary('');
|
|
368
|
+
setWaitPanelMaxValuePrimary(0);
|
|
369
|
+
setWaitPanelValuePrimary(0);
|
|
370
|
+
setWaitPanelTextSecondary('');
|
|
371
|
+
setWaitPanelMaxValueSecondary(0);
|
|
372
|
+
setWaitPanelValueSecondary(0);
|
|
373
|
+
setShowWaitPanel(false);
|
|
374
|
+
}
|
|
375
|
+
};
|
|
376
|
+
const getItems = async (parentDirectory) => {
|
|
377
|
+
setParentDir(parentDirectory);
|
|
378
|
+
const fileSystem = [];
|
|
379
|
+
const tms = props.tmSession ?? SDK_Globals.tmSession;
|
|
380
|
+
if (parentDirectory.name === "") {
|
|
381
|
+
const adlist = await tms?.NewAreaEngine().RetrieveAllAsync().catch((err) => TMExceptionBoxManager.show({ exception: err }));
|
|
382
|
+
setAreas(adlist);
|
|
383
|
+
for (const ad of adlist) {
|
|
384
|
+
ad.name = SDK_Globals.useLocalizedName ? ad?.nameLoc : ad?.name;
|
|
385
|
+
const fsi = new TMFileSystemItem();
|
|
386
|
+
fsi.name = ad.name ?? '';
|
|
387
|
+
fsi.dataItem = ad;
|
|
388
|
+
fsi.dateModified = ad.lastUpdateTime;
|
|
389
|
+
fsi.isDirectory = true;
|
|
390
|
+
fileSystem.push(fsi);
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
else {
|
|
394
|
+
const ad = parentDirectory.dataItem.dataItem;
|
|
395
|
+
const aid = ad?.id;
|
|
396
|
+
const path = parentDirectory.pathKeys.length === 1 ? "" : parentDirectory.path;
|
|
397
|
+
const files = await tms?.NewAreaEngine().RetrieveAllFilesAsync(aid, path.replace(ad.name + '/', '')).catch((err) => TMExceptionBoxManager.show({ exception: err }));
|
|
398
|
+
files.forEach((file) => {
|
|
399
|
+
const fsi = new TMFileSystemItem();
|
|
400
|
+
fsi.name = file.name ?? '';
|
|
401
|
+
fsi.dataItem = ad;
|
|
402
|
+
fsi.dateModified = file.lastUpdateTime;
|
|
403
|
+
fsi.isDirectory = file.isFld == 1;
|
|
404
|
+
fsi.size = file.size;
|
|
405
|
+
fileSystem.push(fsi);
|
|
406
|
+
});
|
|
407
|
+
}
|
|
408
|
+
return fileSystem;
|
|
409
|
+
};
|
|
410
|
+
const renameItem = async (item, newName) => {
|
|
411
|
+
const ad = item.dataItem.dataItem;
|
|
412
|
+
const aid = ad.id;
|
|
413
|
+
const msg = `${SDKUI_Localizator.FromTime} "${item.name}" ${SDKUI_Localizator.ToTime} "${newName}"`;
|
|
414
|
+
const tms = props.tmSession ?? SDK_Globals.tmSession;
|
|
415
|
+
if (item.isDirectory) {
|
|
416
|
+
const oldSubFolder = item.path === ad.name ? '' : item.path.replace(ad.name + '/', '');
|
|
417
|
+
const newSubFolder = item.parentPath.replace(ad.name, '') + '/' + newName;
|
|
418
|
+
await tms?.NewAreaEngine().RenameFolderAsync(aid, oldSubFolder, newSubFolder).then(() => ShowAlert({ message: `${msg}`, mode: 'info', title: SDKUI_Localizator.RenameFolder, duration: 3000 })).catch((err) => TMExceptionBoxManager.show({ exception: err }));
|
|
419
|
+
}
|
|
420
|
+
else {
|
|
421
|
+
const subFolder = item.parentPath === ad.name ? '' : item.parentPath.replace(ad.name + '/', '');
|
|
422
|
+
await tms?.NewAreaEngine().RenameFileAsync(aid, subFolder, item.name, newName).then(() => ShowAlert({ message: `${msg}`, mode: 'info', title: SDKUI_Localizator.RenameFile, duration: 3000 })).catch((err) => TMExceptionBoxManager.show({ exception: err }));
|
|
423
|
+
}
|
|
424
|
+
};
|
|
425
|
+
// aumentare chunk size
|
|
426
|
+
const uploadFileChunk = async (file, uploadInfo, destinationDirectory) => {
|
|
427
|
+
try {
|
|
428
|
+
const tms = props.tmSession ?? SDK_Globals.tmSession;
|
|
429
|
+
if (!tms)
|
|
430
|
+
return;
|
|
431
|
+
const ufe = tms.NewUploadFileEngine();
|
|
432
|
+
const key = `${file.name}_${file.size}_${file.lastModified}`;
|
|
433
|
+
let uploadFileId = _cacheUploadFileId.get(key);
|
|
434
|
+
if (uploadInfo.chunkIndex === 0) {
|
|
435
|
+
uploadFileId = await ufe.UploadFileBegin(file.name, file.size, true);
|
|
436
|
+
_cacheUploadFileId.set(key, uploadFileId);
|
|
437
|
+
}
|
|
438
|
+
let fd = new FileDescriptor();
|
|
439
|
+
fd.fileTransferMode = FileTransferModes.Base64;
|
|
440
|
+
fd.base64Content = await blobToBase64Async(uploadInfo.chunkBlob);
|
|
441
|
+
await ufe.UploadFileSendChunk(uploadFileId, fd);
|
|
442
|
+
if (uploadInfo.chunkIndex === uploadInfo.chunkCount - 1) {
|
|
443
|
+
const ad = destinationDirectory?.dataItem?.dataItem;
|
|
444
|
+
const aid = ad.id;
|
|
445
|
+
const subFolder = destinationDirectory.path === ad.name ? '' : destinationDirectory.path.replace(ad.name + '/', '');
|
|
446
|
+
fd = new FileDescriptor();
|
|
447
|
+
fd.uploadFileIDContent = uploadFileId;
|
|
448
|
+
fd.fileTransferMode = FileTransferModes.UploadFileID;
|
|
449
|
+
await tms?.NewAreaEngine().AddFileAsync(aid, subFolder, fd, true, abortController?.signal);
|
|
450
|
+
_cacheUploadFileId.delete(key);
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
catch (err) {
|
|
454
|
+
TMExceptionBoxManager.show({ exception: err });
|
|
455
|
+
}
|
|
456
|
+
};
|
|
457
|
+
const onCurrentDirectoryChanged = (e) => {
|
|
458
|
+
setCurrentRoute(e.directory.path);
|
|
459
|
+
if (e.directory.path === '' && e.directory.name === '')
|
|
460
|
+
return;
|
|
461
|
+
let ad = e.directory.dataItem.dataItem;
|
|
462
|
+
if (!ad)
|
|
463
|
+
return;
|
|
464
|
+
let aid = ad.id;
|
|
465
|
+
let subFolder = e.directory.path.replace(ad.name + '/', '').replace(ad.name, '');
|
|
466
|
+
setAreaFolder(getAreaPath(aid, subFolder));
|
|
467
|
+
e.component.option("fileSystemProvider").getItems(e.directory).then((items) => {
|
|
468
|
+
setCounter(items.length);
|
|
469
|
+
});
|
|
470
|
+
};
|
|
471
|
+
const onSelectionChanged = async (e) => {
|
|
472
|
+
setSelectedItemsCount(e.selectedItems.length);
|
|
473
|
+
};
|
|
474
|
+
const onFocusedItemChanged = (e) => {
|
|
475
|
+
if (!e.item)
|
|
476
|
+
return;
|
|
477
|
+
let ad = e.item.dataItem.dataItem;
|
|
478
|
+
if (!ad)
|
|
479
|
+
return;
|
|
480
|
+
let aid = ad.id;
|
|
481
|
+
let path = e.item.path.replace(ad.name + '/', '');
|
|
482
|
+
if (e.item.isDirectory) {
|
|
483
|
+
setAreaFile('');
|
|
484
|
+
setAreaFolder(getAreaPath(aid, path));
|
|
485
|
+
}
|
|
486
|
+
else {
|
|
487
|
+
setAreaFolder('');
|
|
488
|
+
setAreaFile(getAreaPath(aid, path));
|
|
489
|
+
}
|
|
490
|
+
};
|
|
491
|
+
const customizeIcon = useCallback((fileSystemItem) => {
|
|
492
|
+
if (fileSystemItem.isDirectory) {
|
|
493
|
+
return IconFolder;
|
|
494
|
+
}
|
|
495
|
+
else {
|
|
496
|
+
const fileExtension = fileSystemItem.getFileExtension();
|
|
497
|
+
switch (fileExtension.toLowerCase()) {
|
|
498
|
+
case '.pdf':
|
|
499
|
+
return IconPdf;
|
|
500
|
+
case '.xls':
|
|
501
|
+
case '.xlsx':
|
|
502
|
+
case '.csv':
|
|
503
|
+
return IconXls;
|
|
504
|
+
case '.txt':
|
|
505
|
+
return IconTxt;
|
|
506
|
+
case '.xml':
|
|
507
|
+
return IconXml;
|
|
508
|
+
case '.dwg':
|
|
509
|
+
return IconDwg;
|
|
510
|
+
case '.dcm':
|
|
511
|
+
return IconDicom;
|
|
512
|
+
case '.slddrw':
|
|
513
|
+
return IconSlddrw;
|
|
514
|
+
case '.mp4':
|
|
515
|
+
return IconMp4;
|
|
516
|
+
case '.doc':
|
|
517
|
+
case '.docx':
|
|
518
|
+
case '.dotx':
|
|
519
|
+
case '.rtf':
|
|
520
|
+
return IconDocx;
|
|
521
|
+
case '.ppt':
|
|
522
|
+
case '.pptx':
|
|
523
|
+
return IconPpt;
|
|
524
|
+
case '.msg':
|
|
525
|
+
case '.eml':
|
|
526
|
+
return IconEmail;
|
|
527
|
+
case '.exe':
|
|
528
|
+
return IconExe;
|
|
529
|
+
case '.htm':
|
|
530
|
+
case '.html':
|
|
531
|
+
return IconHtml;
|
|
532
|
+
case '.p7m':
|
|
533
|
+
return IconSigned;
|
|
534
|
+
case '.png':
|
|
535
|
+
case '.jpg':
|
|
536
|
+
case '.jpeg':
|
|
537
|
+
case '.svg':
|
|
538
|
+
case '.tiff':
|
|
539
|
+
case '.tif':
|
|
540
|
+
case '.ico':
|
|
541
|
+
case '.gif':
|
|
542
|
+
case '.webp':
|
|
543
|
+
return IconImage;
|
|
544
|
+
case '.zip':
|
|
545
|
+
case '.rar':
|
|
546
|
+
case '.7z':
|
|
547
|
+
return IconZip;
|
|
548
|
+
default:
|
|
549
|
+
return IconTxt;
|
|
550
|
+
}
|
|
551
|
+
}
|
|
552
|
+
}, []);
|
|
553
|
+
const onSelectedFileOpened = async (e) => {
|
|
554
|
+
if (props.isPathChooser)
|
|
555
|
+
props.areaChoose();
|
|
556
|
+
else
|
|
557
|
+
downloadItems([e.file]);
|
|
558
|
+
};
|
|
559
|
+
const onContextMenuItemClick = async (e) => {
|
|
560
|
+
if (e.viewArea === 'navPane' && e.itemData === 'refresh') {
|
|
561
|
+
const tms = props.tmSession ?? SDK_Globals.tmSession;
|
|
562
|
+
await tms?.NewAreaEngine().RetrieveAllAsync(true);
|
|
563
|
+
}
|
|
564
|
+
};
|
|
565
|
+
const getSubFolders = async (dir) => {
|
|
566
|
+
const ad = dir.dataItem.dataItem;
|
|
567
|
+
const aid = ad?.id;
|
|
568
|
+
const tms = props.tmSession ?? SDK_Globals.tmSession;
|
|
569
|
+
const path = dir.pathKeys.length === 1 ? "" : dir.path;
|
|
570
|
+
const allFilesAndFolders = await tms?.NewAreaEngine().RetrieveAllFilesAsync(aid, path.replace(ad.name + '/', ''));
|
|
571
|
+
const folders = allFilesAndFolders?.filter(item => item.isFld === 1).map(item => item.name);
|
|
572
|
+
return folders;
|
|
573
|
+
};
|
|
574
|
+
const onDirectoryCreating = async (e) => {
|
|
575
|
+
const folders = await getSubFolders(e.parentDirectory);
|
|
576
|
+
if (folders?.includes(e.name)) {
|
|
577
|
+
alert(`"${e.name}" ${SDKUI_Localizator.FolderExist}`, SDKUI_Localizator.Attention);
|
|
578
|
+
}
|
|
579
|
+
};
|
|
580
|
+
const counters = [{ icon: _jsx(IconAll, {}), text: counter.toString(), tooltip: SDKUI_Localizator.AllItems }, { icon: _jsx(IconSelected, {}), text: selectedItemsCount.toString(), tooltip: SDKUI_Localizator.SelectedItems }];
|
|
581
|
+
return (_jsxs(TMLayoutWaitingContainer, { direction: 'vertical', showWaitPanel: showWaitPanel, showWaitPanelPrimary: showPrimary, showWaitPanelSecondary: showSecondary, waitPanelTitle: waitPanelTitle, waitPanelTextPrimary: waitPanelTextPrimary, waitPanelValuePrimary: waitPanelValuePrimary, waitPanelMaxValuePrimary: waitPanelMaxValuePrimary, waitPanelTextSecondary: waitPanelTextSecondary, waitPanelValueSecondary: waitPanelValueSecondary, waitPanelMaxValueSecondary: waitPanelMaxValueSecondary, isCancelable: true, abortController: abortController, children: [_jsxs(FileManager, { width: props.width, ref: fileManagerRef, height: props.height, onItemMoving: onItemCopying, onItemCopying: onItemCopying, onFileUploading: onFileUploading, fileSystemProvider: areaProvider, customizeThumbnail: customizeIcon, rootFolderName: SDK_Localizator.Areas, onSelectionChanged: onSelectionChanged, onDirectoryCreating: onDirectoryCreating, onFocusedItemChanged: onFocusedItemChanged, onSelectedFileOpened: onSelectedFileOpened, onContextMenuItemClick: onContextMenuItemClick, onItemMoved: () => setCounter(counter => counter + 1), onItemCopied: () => setCounter(counter => counter + 1), onItemDeleted: () => setCounter(counter => counter - 1), onFileUploaded: () => setCounter(counter => counter + 1), onCurrentDirectoryChanged: onCurrentDirectoryChanged, selectionMode: props.selectionMode === 'single' ? 'single' : selectionMode, children: [_jsx(ContextMenu, { items: ["create", "upload", "rename", "move", "copy", "delete", "refresh", "download"] }), _jsx(Permissions, { copy: true, move: true, create: true, upload: true, rename: true, delete: true, download: true }), _jsx(ItemView, { children: _jsxs(Details, { children: [_jsx(Column, { dataField: "thumbnail", cssClass: 'file-thumbnail' }, "thumbnail"), _jsx(Column, { dataField: "name", caption: SDKUI_Localizator.Name }, "name"), _jsx(Column, { dataField: 'size', width: '120px', alignment: 'center', dataType: 'number', caption: SDKUI_Localizator.File_Size }, "size"), _jsx(Column, { dataField: 'dateModified', width: '160px', alignment: 'center', dataType: 'datetime', caption: SDKUI_Localizator.Date_Modified }, "dateModified")] }) }), _jsx(Notifications, { showPopup: false })] }), _jsx(TMCounterBar, { items: counters })] }));
|
|
582
|
+
};
|
|
583
|
+
export default TMAreaManager;
|