@underpostnet/underpost 2.97.5 → 2.98.0
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 +2 -2
- package/cli.md +1 -1
- package/manifests/deployment/dd-default-development/deployment.yaml +2 -2
- package/manifests/deployment/dd-test-development/deployment.yaml +2 -2
- package/package.json +1 -1
- package/scripts/rocky-pwa.sh +200 -0
- package/src/api/document/document.model.js +1 -1
- package/src/api/document/document.service.js +89 -99
- package/src/client/components/core/Auth.js +2 -0
- package/src/client/components/core/Content.js +2 -2
- package/src/client/components/core/Css.js +30 -0
- package/src/client/components/core/FileExplorer.js +699 -42
- package/src/client/components/core/Input.js +3 -1
- package/src/client/components/core/Panel.js +2 -1
- package/src/client/components/core/Responsive.js +15 -7
- package/src/client/components/core/SearchBox.js +0 -110
- package/src/client/components/core/Translate.js +50 -0
- package/src/client/services/default/default.management.js +3 -12
- package/src/client/sw/default.sw.js +107 -184
- package/src/index.js +1 -1
|
@@ -5,17 +5,17 @@ import { AgGrid } from './AgGrid.js';
|
|
|
5
5
|
import { Auth } from './Auth.js';
|
|
6
6
|
import { BtnIcon } from './BtnIcon.js';
|
|
7
7
|
import { getSubpaths, uniqueArray } from './CommonJs.js';
|
|
8
|
-
import { darkTheme, renderCssAttr } from './Css.js';
|
|
8
|
+
import { Css, darkTheme, dynamicCol, renderCssAttr, Themes } from './Css.js';
|
|
9
9
|
import { EventsUI } from './EventsUI.js';
|
|
10
10
|
import { fileFormDataFactory, Input, InputFile } from './Input.js';
|
|
11
11
|
import { loggerFactory } from './Logger.js';
|
|
12
|
-
import { Modal } from './Modal.js';
|
|
12
|
+
import { Modal, renderViewTitle } from './Modal.js';
|
|
13
13
|
import { NotificationManager } from './NotificationManager.js';
|
|
14
14
|
import { RouterEvents } from './Router.js';
|
|
15
15
|
import { Translate } from './Translate.js';
|
|
16
16
|
import { Validator } from './Validator.js';
|
|
17
17
|
import { copyData, downloadFile, s } from './VanillaJs.js';
|
|
18
|
-
import { getProxyPath, getQueryParams, setPath } from './Router.js';
|
|
18
|
+
import { getProxyPath, getQueryParams, setPath, setQueryParams, listenQueryParamsChange } from './Router.js';
|
|
19
19
|
|
|
20
20
|
const logger = loggerFactory(import.meta);
|
|
21
21
|
|
|
@@ -94,6 +94,22 @@ const FileExplorer = {
|
|
|
94
94
|
const query = getQueryParams();
|
|
95
95
|
let location = query?.location ? this.locationFormat({ f: query }) : '/';
|
|
96
96
|
let files, folders, documentId, documentInstance;
|
|
97
|
+
|
|
98
|
+
// Simple pagination state
|
|
99
|
+
const PAGE_SIZE = 5;
|
|
100
|
+
let currentPage = query?.page ? parseInt(query.page) - 1 : 0;
|
|
101
|
+
if (currentPage < 0) currentPage = 0;
|
|
102
|
+
let displayedFiles = [];
|
|
103
|
+
|
|
104
|
+
// Search filter state - initialize from URL query param
|
|
105
|
+
let searchFilters = {
|
|
106
|
+
title: query?.title || '',
|
|
107
|
+
mdFile: query?.mdFile || '',
|
|
108
|
+
file: query?.file || '',
|
|
109
|
+
};
|
|
110
|
+
let filteredFiles = [];
|
|
111
|
+
let isProcessingQueryChange = false; // Prevent recursion during URL sync
|
|
112
|
+
const queryParamsListenerId = `file-explorer-${idModal}`;
|
|
97
113
|
const cleanData = () => {
|
|
98
114
|
files = [];
|
|
99
115
|
folders = [];
|
|
@@ -101,27 +117,89 @@ const FileExplorer = {
|
|
|
101
117
|
documentInstance = [];
|
|
102
118
|
};
|
|
103
119
|
cleanData();
|
|
120
|
+
const applySearchFilter = () => {
|
|
121
|
+
filteredFiles = files;
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
const updatePaginationUI = () => {
|
|
125
|
+
const paginationInfo = s(`.file-explorer-pagination-info`);
|
|
126
|
+
const prevBtn = s(`.file-explorer-prev-btn`);
|
|
127
|
+
const nextBtn = s(`.file-explorer-next-btn`);
|
|
128
|
+
if (paginationInfo) {
|
|
129
|
+
const totalPages = Math.ceil(filteredFiles.length / PAGE_SIZE);
|
|
130
|
+
const showing =
|
|
131
|
+
searchFilters.title || searchFilters.mdFile || searchFilters.file
|
|
132
|
+
? `${filteredFiles.length}/${files.length}`
|
|
133
|
+
: `${files.length}`;
|
|
134
|
+
paginationInfo.textContent = `${currentPage + 1} / ${totalPages || 1} (${showing} files)`;
|
|
135
|
+
}
|
|
136
|
+
if (prevBtn) {
|
|
137
|
+
prevBtn.disabled = currentPage === 0;
|
|
138
|
+
prevBtn.style.opacity = currentPage === 0 ? '0.5' : '1';
|
|
139
|
+
prevBtn.style.cursor = currentPage === 0 ? 'not-allowed' : 'pointer';
|
|
140
|
+
}
|
|
141
|
+
if (nextBtn) {
|
|
142
|
+
const isDisabled = (currentPage + 1) * PAGE_SIZE >= filteredFiles.length;
|
|
143
|
+
nextBtn.disabled = isDisabled;
|
|
144
|
+
nextBtn.style.opacity = isDisabled ? '0.5' : '1';
|
|
145
|
+
nextBtn.style.cursor = isDisabled ? 'not-allowed' : 'pointer';
|
|
146
|
+
}
|
|
147
|
+
};
|
|
148
|
+
|
|
149
|
+
const getPagedFiles = () => {
|
|
150
|
+
const start = currentPage * PAGE_SIZE;
|
|
151
|
+
const end = start + PAGE_SIZE;
|
|
152
|
+
return filteredFiles.slice(start, end);
|
|
153
|
+
};
|
|
154
|
+
|
|
104
155
|
FileExplorer.Api[idModal].displayList = async () => {
|
|
105
156
|
if (!s(`.${idModal}`)) return;
|
|
106
157
|
const query = getQueryParams();
|
|
107
158
|
location = query?.location ? this.locationFormat({ f: query }) : '/';
|
|
108
159
|
s(`.file-explorer-query-nav`).value = location;
|
|
109
|
-
|
|
160
|
+
|
|
161
|
+
// Sync search filters from URL
|
|
162
|
+
searchFilters = {
|
|
163
|
+
title: query?.title || '',
|
|
164
|
+
mdFile: query?.mdFile || '',
|
|
165
|
+
file: query?.file || '',
|
|
166
|
+
};
|
|
167
|
+
|
|
168
|
+
if (s(`.file-explorer-search-title`)) s(`.file-explorer-search-title`).value = searchFilters.title;
|
|
169
|
+
if (s(`.file-explorer-search-md-file`)) s(`.file-explorer-search-md-file`).value = searchFilters.mdFile;
|
|
170
|
+
if (s(`.file-explorer-search-file`)) s(`.file-explorer-search-file`).value = searchFilters.file;
|
|
171
|
+
|
|
172
|
+
const format = this.documentDataFormat({ document: documentInstance, location, searchFilters });
|
|
110
173
|
files = format.files;
|
|
111
174
|
folders = format.folders;
|
|
112
|
-
|
|
175
|
+
applySearchFilter();
|
|
176
|
+
const queryPage = query?.page ? parseInt(query.page) - 1 : 0;
|
|
177
|
+
currentPage = queryPage >= 0 ? queryPage : 0;
|
|
178
|
+
displayedFiles = getPagedFiles();
|
|
179
|
+
AgGrid.grids[gridFileId].setGridOption('rowData', displayedFiles);
|
|
113
180
|
AgGrid.grids[gridFolderId].setGridOption('rowData', folders);
|
|
181
|
+
updatePaginationUI();
|
|
114
182
|
};
|
|
115
183
|
FileExplorer.Api[idModal].updateData = async (optionsUpdate = { display: false }) => {
|
|
116
184
|
if (!s(`.${idModal}`)) return;
|
|
117
185
|
if (Auth.getToken()) {
|
|
118
186
|
try {
|
|
119
|
-
const { status, data:
|
|
120
|
-
|
|
187
|
+
const { status, data: responseData } = await DocumentService.get({
|
|
188
|
+
params: {
|
|
189
|
+
searchTitle: searchFilters.title,
|
|
190
|
+
searchMdFile: searchFilters.mdFile,
|
|
191
|
+
searchFile: searchFilters.file,
|
|
192
|
+
location,
|
|
193
|
+
},
|
|
194
|
+
});
|
|
195
|
+
// Handle both old format (array) and new format with pagination
|
|
196
|
+
const document = Array.isArray(responseData) ? responseData : responseData.data || [];
|
|
197
|
+
const format = this.documentDataFormat({ document, location, searchFilters });
|
|
121
198
|
files = format.files;
|
|
122
199
|
documentId = format.documentId;
|
|
123
200
|
folders = format.folders;
|
|
124
201
|
documentInstance = document;
|
|
202
|
+
applySearchFilter();
|
|
125
203
|
} catch (error) {
|
|
126
204
|
logger.error(error);
|
|
127
205
|
NotificationManager.Push({
|
|
@@ -143,6 +221,180 @@ const FileExplorer = {
|
|
|
143
221
|
});
|
|
144
222
|
};
|
|
145
223
|
|
|
224
|
+
// Listen for query param changes (browser back/forward navigation)
|
|
225
|
+
listenQueryParamsChange({
|
|
226
|
+
id: queryParamsListenerId,
|
|
227
|
+
event: async (queryParams) => {
|
|
228
|
+
if (!s(`.${idModal}`)) return;
|
|
229
|
+
if (isProcessingQueryChange) return;
|
|
230
|
+
|
|
231
|
+
const tab = queryParams?.tab || '';
|
|
232
|
+
if (tab === 'upload') {
|
|
233
|
+
s(`.file-explorer-nav`).style.display = 'none';
|
|
234
|
+
s(`.file-explorer-uploader`).style.display = 'block';
|
|
235
|
+
} else {
|
|
236
|
+
s(`.file-explorer-nav`).style.display = 'block';
|
|
237
|
+
s(`.file-explorer-uploader`).style.display = 'none';
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
const page = queryParams?.page ? parseInt(queryParams.page) - 1 : 0;
|
|
241
|
+
if (page !== currentPage) {
|
|
242
|
+
currentPage = page >= 0 ? page : 0;
|
|
243
|
+
displayedFiles = getPagedFiles();
|
|
244
|
+
if (AgGrid.grids[gridFileId]) {
|
|
245
|
+
AgGrid.grids[gridFileId].setGridOption('rowData', displayedFiles);
|
|
246
|
+
}
|
|
247
|
+
updatePaginationUI();
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
const newFilters = {
|
|
251
|
+
title: queryParams?.title || '',
|
|
252
|
+
mdFile: queryParams?.mdFile || '',
|
|
253
|
+
file: queryParams?.file || '',
|
|
254
|
+
};
|
|
255
|
+
|
|
256
|
+
if (
|
|
257
|
+
newFilters.title !== searchFilters.title ||
|
|
258
|
+
newFilters.mdFile !== searchFilters.mdFile ||
|
|
259
|
+
newFilters.file !== searchFilters.file
|
|
260
|
+
) {
|
|
261
|
+
isProcessingQueryChange = true;
|
|
262
|
+
searchFilters = newFilters;
|
|
263
|
+
|
|
264
|
+
if (s(`.file-explorer-search-title`)) s(`.file-explorer-search-title`).value = searchFilters.title;
|
|
265
|
+
if (s(`.file-explorer-search-md-file`)) s(`.file-explorer-search-md-file`).value = searchFilters.mdFile;
|
|
266
|
+
if (s(`.file-explorer-search-file`)) s(`.file-explorer-search-file`).value = searchFilters.file;
|
|
267
|
+
|
|
268
|
+
await FileExplorer.Api[idModal].updateData({ display: true });
|
|
269
|
+
|
|
270
|
+
setTimeout(() => {
|
|
271
|
+
isProcessingQueryChange = false;
|
|
272
|
+
}, 100);
|
|
273
|
+
}
|
|
274
|
+
},
|
|
275
|
+
});
|
|
276
|
+
|
|
277
|
+
// Pagination button event handlers
|
|
278
|
+
setTimeout(() => {
|
|
279
|
+
EventsUI.onClick(`.file-explorer-prev-btn`, (e) => {
|
|
280
|
+
e.preventDefault();
|
|
281
|
+
if (currentPage > 0) {
|
|
282
|
+
setQueryParams({ page: currentPage }, { replace: false });
|
|
283
|
+
}
|
|
284
|
+
});
|
|
285
|
+
|
|
286
|
+
EventsUI.onClick(`.file-explorer-next-btn`, (e) => {
|
|
287
|
+
e.preventDefault();
|
|
288
|
+
if ((currentPage + 1) * PAGE_SIZE < filteredFiles.length) {
|
|
289
|
+
setQueryParams({ page: currentPage + 2 }, { replace: false });
|
|
290
|
+
}
|
|
291
|
+
});
|
|
292
|
+
|
|
293
|
+
// Search input handlers
|
|
294
|
+
let searchTimeout;
|
|
295
|
+
|
|
296
|
+
const setupSearchInput = (selector, key) => {
|
|
297
|
+
const el = s(selector);
|
|
298
|
+
if (el) {
|
|
299
|
+
if (searchFilters[key]) el.value = searchFilters[key];
|
|
300
|
+
el.addEventListener('input', (e) => {
|
|
301
|
+
clearTimeout(searchTimeout);
|
|
302
|
+
searchTimeout = setTimeout(async () => {
|
|
303
|
+
const val = e.target.value.trim();
|
|
304
|
+
if (val === searchFilters[key]) return;
|
|
305
|
+
|
|
306
|
+
isProcessingQueryChange = true;
|
|
307
|
+
searchFilters[key] = val;
|
|
308
|
+
await FileExplorer.Api[idModal].updateData({ display: true });
|
|
309
|
+
|
|
310
|
+
const queryParams = {};
|
|
311
|
+
if (searchFilters.title) queryParams.title = searchFilters.title;
|
|
312
|
+
if (searchFilters.mdFile) queryParams.mdFile = searchFilters.mdFile;
|
|
313
|
+
if (searchFilters.file) queryParams.file = searchFilters.file;
|
|
314
|
+
|
|
315
|
+
if (!searchFilters.title) queryParams.title = null;
|
|
316
|
+
if (!searchFilters.mdFile) queryParams.mdFile = null;
|
|
317
|
+
if (!searchFilters.file) queryParams.file = null;
|
|
318
|
+
|
|
319
|
+
queryParams.page = 1;
|
|
320
|
+
|
|
321
|
+
setQueryParams(queryParams, { replace: false });
|
|
322
|
+
|
|
323
|
+
setTimeout(() => {
|
|
324
|
+
isProcessingQueryChange = false;
|
|
325
|
+
}, 100);
|
|
326
|
+
}, 300);
|
|
327
|
+
});
|
|
328
|
+
el.addEventListener('keydown', (e) => {
|
|
329
|
+
if (e.key === 'Enter') e.preventDefault();
|
|
330
|
+
});
|
|
331
|
+
}
|
|
332
|
+
};
|
|
333
|
+
|
|
334
|
+
setupSearchInput(`.file-explorer-search-title`, 'title');
|
|
335
|
+
setupSearchInput(`.file-explorer-search-md-file`, 'mdFile');
|
|
336
|
+
setupSearchInput(`.file-explorer-search-file`, 'file');
|
|
337
|
+
|
|
338
|
+
// Submit search button
|
|
339
|
+
EventsUI.onClick(`.file-explorer-search-submit`, async (e) => {
|
|
340
|
+
e.preventDefault();
|
|
341
|
+
clearTimeout(searchTimeout);
|
|
342
|
+
|
|
343
|
+
const titleVal = s(`.file-explorer-search-title`)?.value.trim() || '';
|
|
344
|
+
const mdFileVal = s(`.file-explorer-search-md-file`)?.value.trim() || '';
|
|
345
|
+
const fileVal = s(`.file-explorer-search-file`)?.value.trim() || '';
|
|
346
|
+
|
|
347
|
+
searchFilters = { title: titleVal, mdFile: mdFileVal, file: fileVal };
|
|
348
|
+
|
|
349
|
+
isProcessingQueryChange = true;
|
|
350
|
+
|
|
351
|
+
const queryParams = {};
|
|
352
|
+
if (searchFilters.title) queryParams.title = searchFilters.title;
|
|
353
|
+
if (searchFilters.mdFile) queryParams.mdFile = searchFilters.mdFile;
|
|
354
|
+
if (searchFilters.file) queryParams.file = searchFilters.file;
|
|
355
|
+
|
|
356
|
+
if (!searchFilters.title) queryParams.title = null;
|
|
357
|
+
if (!searchFilters.mdFile) queryParams.mdFile = null;
|
|
358
|
+
if (!searchFilters.file) queryParams.file = null;
|
|
359
|
+
|
|
360
|
+
queryParams.page = 1;
|
|
361
|
+
|
|
362
|
+
setQueryParams(queryParams, { replace: false });
|
|
363
|
+
|
|
364
|
+
await FileExplorer.Api[idModal].updateData({ display: true });
|
|
365
|
+
|
|
366
|
+
setTimeout(() => {
|
|
367
|
+
isProcessingQueryChange = false;
|
|
368
|
+
}, 100);
|
|
369
|
+
});
|
|
370
|
+
|
|
371
|
+
// Clear search button
|
|
372
|
+
EventsUI.onClick(`.file-explorer-search-clear`, (e) => {
|
|
373
|
+
e.preventDefault();
|
|
374
|
+
|
|
375
|
+
if (!searchFilters.title && !searchFilters.mdFile && !searchFilters.file) return;
|
|
376
|
+
|
|
377
|
+
isProcessingQueryChange = true;
|
|
378
|
+
if (s(`.file-explorer-search-title`)) s(`.file-explorer-search-title`).value = '';
|
|
379
|
+
if (s(`.file-explorer-search-md-file`)) s(`.file-explorer-search-md-file`).value = '';
|
|
380
|
+
if (s(`.file-explorer-search-file`)) s(`.file-explorer-search-file`).value = '';
|
|
381
|
+
|
|
382
|
+
searchFilters = { title: '', mdFile: '', file: '' };
|
|
383
|
+
|
|
384
|
+
applySearchFilter();
|
|
385
|
+
currentPage = 0;
|
|
386
|
+
displayedFiles = getPagedFiles();
|
|
387
|
+
AgGrid.grids[gridFileId].setGridOption('rowData', displayedFiles);
|
|
388
|
+
updatePaginationUI();
|
|
389
|
+
|
|
390
|
+
setQueryParams({ title: null, mdFile: null, file: null, page: 1 }, { replace: false });
|
|
391
|
+
|
|
392
|
+
setTimeout(() => {
|
|
393
|
+
isProcessingQueryChange = false;
|
|
394
|
+
}, 100);
|
|
395
|
+
});
|
|
396
|
+
});
|
|
397
|
+
|
|
146
398
|
setTimeout(async () => {
|
|
147
399
|
FileExplorer.Api[idModal].updateData({ display: true });
|
|
148
400
|
const formData = [
|
|
@@ -204,15 +456,25 @@ const FileExplorer = {
|
|
|
204
456
|
const format = this.documentDataFormat({ document: documentInstance, location });
|
|
205
457
|
files = format.files;
|
|
206
458
|
folders = format.folders;
|
|
207
|
-
|
|
459
|
+
applySearchFilter();
|
|
460
|
+
currentPage = 0;
|
|
461
|
+
displayedFiles = getPagedFiles();
|
|
462
|
+
AgGrid.grids[gridFileId].setGridOption('rowData', displayedFiles);
|
|
208
463
|
AgGrid.grids[gridFolderId].setGridOption('rowData', folders);
|
|
464
|
+
updatePaginationUI();
|
|
209
465
|
NotificationManager.Push({
|
|
210
466
|
html: Translate.Render(`${status}-upload-file`),
|
|
211
467
|
status,
|
|
212
468
|
});
|
|
213
469
|
if (status === 'success') {
|
|
214
|
-
|
|
470
|
+
// Clear the file input
|
|
215
471
|
s(`.btn-clear-input-file-${idDropFileInput}`).click();
|
|
472
|
+
// Switch to explorer view with the uploaded location
|
|
473
|
+
setQueryParams({ tab: null, location: location }, { replace: false });
|
|
474
|
+
// Show explorer view, hide upload view
|
|
475
|
+
s(`.file-explorer-nav`).style.display = 'block';
|
|
476
|
+
s(`.file-explorer-uploader`).style.display = 'none';
|
|
477
|
+
s(`.file-explorer-query-nav`).value = location;
|
|
216
478
|
}
|
|
217
479
|
}
|
|
218
480
|
});
|
|
@@ -229,19 +491,26 @@ const FileExplorer = {
|
|
|
229
491
|
});
|
|
230
492
|
EventsUI.onClick(`.btn-input-home-directory`, async (e) => {
|
|
231
493
|
e.preventDefault();
|
|
494
|
+
|
|
495
|
+
if (getQueryParams()?.tab === 'upload') {
|
|
496
|
+
setQueryParams({ tab: null }, { replace: false });
|
|
497
|
+
return;
|
|
498
|
+
}
|
|
499
|
+
|
|
232
500
|
let newLocation = '/';
|
|
233
|
-
if (
|
|
234
|
-
|
|
235
|
-
s(`.file-explorer-nav`).style.display = 'block';
|
|
236
|
-
} else if (newLocation === location) return;
|
|
237
|
-
else location = newLocation;
|
|
501
|
+
if (newLocation === location) return;
|
|
502
|
+
location = newLocation;
|
|
238
503
|
setPath(`${window.location.pathname}?location=${location}`);
|
|
239
504
|
s(`.file-explorer-query-nav`).value = location;
|
|
240
505
|
const format = this.documentDataFormat({ document: documentInstance, location });
|
|
241
506
|
files = format.files;
|
|
242
507
|
folders = format.folders;
|
|
243
|
-
|
|
508
|
+
applySearchFilter();
|
|
509
|
+
currentPage = 0;
|
|
510
|
+
displayedFiles = getPagedFiles();
|
|
511
|
+
AgGrid.grids[gridFileId].setGridOption('rowData', displayedFiles);
|
|
244
512
|
AgGrid.grids[gridFolderId].setGridOption('rowData', folders);
|
|
513
|
+
updatePaginationUI();
|
|
245
514
|
});
|
|
246
515
|
EventsUI.onClick(`.btn-input-copy-directory`, async (e) => {
|
|
247
516
|
e.preventDefault();
|
|
@@ -261,8 +530,7 @@ const FileExplorer = {
|
|
|
261
530
|
});
|
|
262
531
|
EventsUI.onClick(`.btn-input-upload-file`, async (e) => {
|
|
263
532
|
e.preventDefault();
|
|
264
|
-
|
|
265
|
-
s(`.file-explorer-uploader`).style.display = 'block';
|
|
533
|
+
setQueryParams({ tab: 'upload' }, { replace: false });
|
|
266
534
|
});
|
|
267
535
|
});
|
|
268
536
|
|
|
@@ -298,6 +566,11 @@ const FileExplorer = {
|
|
|
298
566
|
label: html`<i class="fas fa-copy"></i>`,
|
|
299
567
|
type: 'button',
|
|
300
568
|
})}
|
|
569
|
+
${await BtnIcon.Render({
|
|
570
|
+
class: `in fll management-table-btn-mini btn-file-edit-${params.data._id}`,
|
|
571
|
+
label: html`<i class="fas fa-edit"></i>`,
|
|
572
|
+
type: 'button',
|
|
573
|
+
})}
|
|
301
574
|
${await BtnIcon.Render({
|
|
302
575
|
class: `in fll management-table-btn-mini ${toggleId}`,
|
|
303
576
|
label: isPublic
|
|
@@ -313,7 +586,10 @@ const FileExplorer = {
|
|
|
313
586
|
const url = `${window.location.origin}${uri}`;
|
|
314
587
|
|
|
315
588
|
const originObj = documentInstance.find((d) => d._id === params.data._id);
|
|
316
|
-
const blobUri =
|
|
589
|
+
const blobUri =
|
|
590
|
+
originObj && originObj.fileId
|
|
591
|
+
? getApiBaseUrl({ id: originObj.fileId._id, endpoint: 'file/blob' })
|
|
592
|
+
: undefined;
|
|
317
593
|
|
|
318
594
|
if (!originObj) {
|
|
319
595
|
s(`.btn-file-view-${params.data._id}`).classList.add('hide');
|
|
@@ -396,10 +672,12 @@ const FileExplorer = {
|
|
|
396
672
|
const format = FileExplorer.documentDataFormat({ document: documentInstance, location });
|
|
397
673
|
files = format.files;
|
|
398
674
|
folders = format.folders;
|
|
675
|
+
applySearchFilter();
|
|
399
676
|
// AgGrid.grids[gridFileId].setGridOption('rowData', files);
|
|
400
677
|
// const selectedData = gridApi.getSelectedRows();
|
|
401
678
|
AgGrid.grids[gridFileId].applyTransaction({ remove: [params.data] });
|
|
402
679
|
AgGrid.grids[gridFolderId].setGridOption('rowData', folders);
|
|
680
|
+
updatePaginationUI();
|
|
403
681
|
},
|
|
404
682
|
{ context: 'modal' },
|
|
405
683
|
);
|
|
@@ -477,6 +755,287 @@ const FileExplorer = {
|
|
|
477
755
|
},
|
|
478
756
|
{ context: 'modal' },
|
|
479
757
|
);
|
|
758
|
+
|
|
759
|
+
// Edit document button
|
|
760
|
+
EventsUI.onClick(
|
|
761
|
+
`.btn-file-edit-${params.data._id}`,
|
|
762
|
+
async (e) => {
|
|
763
|
+
e.preventDefault();
|
|
764
|
+
|
|
765
|
+
// Get the original document data from documentInstance
|
|
766
|
+
const originDoc = documentInstance.find((d) => d._id === params.data._id);
|
|
767
|
+
const editModalId = `edit-doc-${params.data._id}`;
|
|
768
|
+
|
|
769
|
+
// Check file existence for proper UX
|
|
770
|
+
const hasMdFile = !!(originDoc && originDoc.mdFileId);
|
|
771
|
+
const hasGenericFile = !!(originDoc && originDoc.fileId);
|
|
772
|
+
|
|
773
|
+
const mdFileMimetype = hasMdFile ? originDoc.mdFileId.mimetype : '';
|
|
774
|
+
const genericFileMimetype = hasGenericFile ? originDoc.fileId.mimetype : '';
|
|
775
|
+
|
|
776
|
+
const editFormHtml = async () => {
|
|
777
|
+
return html`
|
|
778
|
+
<div class="in edit-document-form" style="max-width: 600px; margin: 0 auto; padding: 20px;">
|
|
779
|
+
<!-- Header -->
|
|
780
|
+
<div
|
|
781
|
+
class="in"
|
|
782
|
+
style="text-align: center; margin-bottom: 25px; padding-bottom: 15px; border-bottom: 1px solid rgba(128,128,128,0.3);"
|
|
783
|
+
>
|
|
784
|
+
<p style="color: #888; font-size: 14px; margin: 0;">
|
|
785
|
+
${Translate.Render('editing')}: <strong style="color: inherit;">${params.data.title}</strong>
|
|
786
|
+
</p>
|
|
787
|
+
</div>
|
|
788
|
+
|
|
789
|
+
<!-- Document Title -->
|
|
790
|
+
<div class="in section-mp" style="margin-bottom: 20px;">
|
|
791
|
+
${await Input.Render({
|
|
792
|
+
id: `edit-doc-title-${params.data._id}`,
|
|
793
|
+
type: 'text',
|
|
794
|
+
label: html`<i class="fas fa-heading"></i> ${Translate.Render('doc-title')}`,
|
|
795
|
+
containerClass: 'in section-mp input-container-width',
|
|
796
|
+
placeholder: true,
|
|
797
|
+
value: params.data.title || '',
|
|
798
|
+
})}
|
|
799
|
+
</div>
|
|
800
|
+
|
|
801
|
+
<!-- MD File Name -->
|
|
802
|
+
<div class="in section-mp" style="margin-bottom: 20px;">
|
|
803
|
+
${hasMdFile
|
|
804
|
+
? await Input.Render({
|
|
805
|
+
id: `edit-doc-md-file-${params.data._id}`,
|
|
806
|
+
type: 'text',
|
|
807
|
+
label: html`<i class="fas fa-file-code"></i> ${Translate.Render('md-file-name')}
|
|
808
|
+
<span style="font-size: 11px; color: #888; margin-left: 8px;">(${mdFileMimetype})</span>`,
|
|
809
|
+
containerClass: 'in section-mp input-container-width',
|
|
810
|
+
placeholder: true,
|
|
811
|
+
value: params.data.mdFileName || '',
|
|
812
|
+
})
|
|
813
|
+
: html`
|
|
814
|
+
<div class="in section-mp input-container-width" style="opacity: 0.6;">
|
|
815
|
+
<label style="display: block; margin-bottom: 5px;">
|
|
816
|
+
<i class="fas fa-file-code"></i> ${Translate.Render('md-file-name')}
|
|
817
|
+
</label>
|
|
818
|
+
<div
|
|
819
|
+
style="padding: 10px 12px; border: 1px dashed rgba(128,128,128,0.5); border-radius: 4px; color: #888; font-style: italic;"
|
|
820
|
+
>
|
|
821
|
+
<i class="fas fa-info-circle"></i> ${Translate.Render('no-md-file-attached')}
|
|
822
|
+
</div>
|
|
823
|
+
</div>
|
|
824
|
+
`}
|
|
825
|
+
</div>
|
|
826
|
+
|
|
827
|
+
<!-- Generic File Name -->
|
|
828
|
+
<div class="in section-mp" style="margin-bottom: 20px;">
|
|
829
|
+
${hasGenericFile
|
|
830
|
+
? await Input.Render({
|
|
831
|
+
id: `edit-doc-file-${params.data._id}`,
|
|
832
|
+
type: 'text',
|
|
833
|
+
label: html`<i class="fas fa-file"></i> ${Translate.Render('generic-file-name')}
|
|
834
|
+
<span style="font-size: 11px; color: #888; margin-left: 8px;"
|
|
835
|
+
>(${genericFileMimetype})</span
|
|
836
|
+
>`,
|
|
837
|
+
containerClass: 'in section-mp input-container-width',
|
|
838
|
+
placeholder: true,
|
|
839
|
+
value: params.data.fileName || '',
|
|
840
|
+
})
|
|
841
|
+
: html`
|
|
842
|
+
<div class="in section-mp input-container-width" style="opacity: 0.6;">
|
|
843
|
+
<label style="display: block; margin-bottom: 5px;">
|
|
844
|
+
<i class="fas fa-file"></i> ${Translate.Render('generic-file-name')}
|
|
845
|
+
</label>
|
|
846
|
+
<div
|
|
847
|
+
style="padding: 10px 12px; border: 1px dashed rgba(128,128,128,0.5); border-radius: 4px; color: #888; font-style: italic;"
|
|
848
|
+
>
|
|
849
|
+
<i class="fas fa-info-circle"></i> ${Translate.Render('no-generic-file-attached')}
|
|
850
|
+
</div>
|
|
851
|
+
</div>
|
|
852
|
+
`}
|
|
853
|
+
</div>
|
|
854
|
+
|
|
855
|
+
<!-- Location -->
|
|
856
|
+
<div class="in section-mp" style="margin-bottom: 25px;">
|
|
857
|
+
${await Input.Render({
|
|
858
|
+
id: `edit-doc-location-${params.data._id}`,
|
|
859
|
+
type: 'text',
|
|
860
|
+
label: html`<i class="fas fa-folder"></i> ${Translate.Render('location')}`,
|
|
861
|
+
containerClass: 'in section-mp input-container-width',
|
|
862
|
+
placeholder: true,
|
|
863
|
+
value: params.data.location || '/',
|
|
864
|
+
})}
|
|
865
|
+
</div>
|
|
866
|
+
|
|
867
|
+
<!-- Buttons -->
|
|
868
|
+
<div
|
|
869
|
+
class="fl"
|
|
870
|
+
style="margin-top: 30px; border-top: 1px solid rgba(128,128,128,0.3); padding-top: 20px;"
|
|
871
|
+
>
|
|
872
|
+
<div class="in fll" style="width: 50%; padding: 5px;">
|
|
873
|
+
${await BtnIcon.Render({
|
|
874
|
+
class: `in wfa btn-edit-doc-cancel-${params.data._id}`,
|
|
875
|
+
label: html`<i class="fas fa-times"></i> ${Translate.Render('cancel')}`,
|
|
876
|
+
type: 'button',
|
|
877
|
+
})}
|
|
878
|
+
</div>
|
|
879
|
+
<div class="in fll" style="width: 50%; padding: 5px;">
|
|
880
|
+
${await BtnIcon.Render({
|
|
881
|
+
class: `in wfa btn-edit-doc-submit-${params.data._id}`,
|
|
882
|
+
label: html`<i class="fas fa-save"></i> ${Translate.Render('save')}`,
|
|
883
|
+
type: 'button',
|
|
884
|
+
})}
|
|
885
|
+
</div>
|
|
886
|
+
</div>
|
|
887
|
+
</div>
|
|
888
|
+
`;
|
|
889
|
+
};
|
|
890
|
+
|
|
891
|
+
const { barConfig } = await Themes[Css.currentTheme]();
|
|
892
|
+
|
|
893
|
+
await Modal.Render({
|
|
894
|
+
id: editModalId,
|
|
895
|
+
barConfig,
|
|
896
|
+
title: renderViewTitle({
|
|
897
|
+
icon: html`<i class="fas fa-edit"></i>`,
|
|
898
|
+
text: Translate.Render('edit-document'),
|
|
899
|
+
}),
|
|
900
|
+
html: editFormHtml,
|
|
901
|
+
handleType: 'bar',
|
|
902
|
+
maximize: true,
|
|
903
|
+
mode: 'view',
|
|
904
|
+
slideMenu: 'modal-menu',
|
|
905
|
+
RouterInstance: Modal.Data[options.idModal].options.RouterInstance,
|
|
906
|
+
barMode: Modal.Data[options.idModal].options.barMode,
|
|
907
|
+
});
|
|
908
|
+
|
|
909
|
+
// Handle submit button
|
|
910
|
+
setTimeout(() => {
|
|
911
|
+
EventsUI.onClick(
|
|
912
|
+
`.btn-edit-doc-submit-${params.data._id}`,
|
|
913
|
+
async (ev) => {
|
|
914
|
+
ev.preventDefault();
|
|
915
|
+
|
|
916
|
+
const newTitle = s(`.edit-doc-title-${params.data._id}`).value.trim();
|
|
917
|
+
const newLocation = s(`.edit-doc-location-${params.data._id}`).value.trim();
|
|
918
|
+
|
|
919
|
+
// Get file names only if files exist
|
|
920
|
+
const newMdFileName = hasMdFile ? s(`.edit-doc-md-file-${params.data._id}`)?.value.trim() : null;
|
|
921
|
+
const newFileName = hasGenericFile ? s(`.edit-doc-file-${params.data._id}`)?.value.trim() : null;
|
|
922
|
+
|
|
923
|
+
if (!newTitle) {
|
|
924
|
+
NotificationManager.Push({
|
|
925
|
+
html: Translate.Render('error-title-required'),
|
|
926
|
+
status: 'error',
|
|
927
|
+
});
|
|
928
|
+
return;
|
|
929
|
+
}
|
|
930
|
+
|
|
931
|
+
const formattedLocation = FileExplorer.locationFormat({ f: { location: newLocation || '/' } });
|
|
932
|
+
|
|
933
|
+
try {
|
|
934
|
+
const updateBody = {
|
|
935
|
+
title: newTitle,
|
|
936
|
+
location: formattedLocation,
|
|
937
|
+
};
|
|
938
|
+
|
|
939
|
+
// Preserve existing fields from the original document
|
|
940
|
+
if (originDoc) {
|
|
941
|
+
if (originDoc.fileId) updateBody.fileId = originDoc.fileId._id || originDoc.fileId;
|
|
942
|
+
if (originDoc.mdFileId) updateBody.mdFileId = originDoc.mdFileId._id || originDoc.mdFileId;
|
|
943
|
+
if (originDoc.tags) updateBody.tags = originDoc.tags;
|
|
944
|
+
if (typeof originDoc.isPublic !== 'undefined') updateBody.isPublic = originDoc.isPublic;
|
|
945
|
+
}
|
|
946
|
+
|
|
947
|
+
// Include file name updates if files exist and names changed
|
|
948
|
+
if (hasMdFile && newMdFileName && newMdFileName !== params.data.mdFileName) {
|
|
949
|
+
updateBody.mdFileName = newMdFileName;
|
|
950
|
+
}
|
|
951
|
+
if (hasGenericFile && newFileName && newFileName !== params.data.fileName) {
|
|
952
|
+
updateBody.fileName = newFileName;
|
|
953
|
+
}
|
|
954
|
+
|
|
955
|
+
const { data, status } = await DocumentService.put({
|
|
956
|
+
id: params.data._id,
|
|
957
|
+
body: updateBody,
|
|
958
|
+
});
|
|
959
|
+
|
|
960
|
+
if (status === 'success') {
|
|
961
|
+
// Check if location changed
|
|
962
|
+
const locationChanged = formattedLocation !== params.data.location;
|
|
963
|
+
|
|
964
|
+
// Update local data
|
|
965
|
+
params.data.title = newTitle;
|
|
966
|
+
params.data.name = newTitle;
|
|
967
|
+
params.data.location = formattedLocation;
|
|
968
|
+
if (hasMdFile && newMdFileName) params.data.mdFileName = newMdFileName;
|
|
969
|
+
if (hasGenericFile && newFileName) params.data.fileName = newFileName;
|
|
970
|
+
|
|
971
|
+
// Update documentInstance
|
|
972
|
+
const docIndex = documentInstance.findIndex((d) => d._id === params.data._id);
|
|
973
|
+
if (docIndex !== -1) {
|
|
974
|
+
documentInstance[docIndex].title = newTitle;
|
|
975
|
+
documentInstance[docIndex].location = formattedLocation;
|
|
976
|
+
// Update file names in the referenced file objects
|
|
977
|
+
if (hasMdFile && newMdFileName && documentInstance[docIndex].mdFileId) {
|
|
978
|
+
documentInstance[docIndex].mdFileId.name = newMdFileName;
|
|
979
|
+
}
|
|
980
|
+
if (hasGenericFile && newFileName && documentInstance[docIndex].fileId) {
|
|
981
|
+
documentInstance[docIndex].fileId.name = newFileName;
|
|
982
|
+
}
|
|
983
|
+
}
|
|
984
|
+
|
|
985
|
+
// Refresh the grid with new location
|
|
986
|
+
const format = FileExplorer.documentDataFormat({ document: documentInstance, location });
|
|
987
|
+
files = format.files;
|
|
988
|
+
folders = format.folders;
|
|
989
|
+
applySearchFilter();
|
|
990
|
+
currentPage = 0;
|
|
991
|
+
displayedFiles = getPagedFiles();
|
|
992
|
+
AgGrid.grids[gridFileId].setGridOption('rowData', displayedFiles);
|
|
993
|
+
AgGrid.grids[gridFolderId].setGridOption('rowData', folders);
|
|
994
|
+
updatePaginationUI();
|
|
995
|
+
|
|
996
|
+
NotificationManager.Push({
|
|
997
|
+
html: Translate.Render('success-update-document'),
|
|
998
|
+
status: 'success',
|
|
999
|
+
});
|
|
1000
|
+
|
|
1001
|
+
// If location changed, navigate to the new location
|
|
1002
|
+
if (!s(`.file-explorer-query-nav`)) s(`.main-btn-cloud`).click();
|
|
1003
|
+
|
|
1004
|
+
if (locationChanged)
|
|
1005
|
+
setTimeout(() => {
|
|
1006
|
+
location = formattedLocation;
|
|
1007
|
+
setPath(`${window.location.pathname}?location=${location}`);
|
|
1008
|
+
s(`.file-explorer-query-nav`).value = location;
|
|
1009
|
+
});
|
|
1010
|
+
|
|
1011
|
+
Modal.removeModal(editModalId);
|
|
1012
|
+
} else {
|
|
1013
|
+
throw new Error('Failed to update document');
|
|
1014
|
+
}
|
|
1015
|
+
} catch (error) {
|
|
1016
|
+
logger.error('Update document failed:', error);
|
|
1017
|
+
NotificationManager.Push({
|
|
1018
|
+
html: Translate.Render('error-update-document'),
|
|
1019
|
+
status: 'error',
|
|
1020
|
+
});
|
|
1021
|
+
}
|
|
1022
|
+
},
|
|
1023
|
+
{ context: 'modal' },
|
|
1024
|
+
);
|
|
1025
|
+
|
|
1026
|
+
// Handle cancel button
|
|
1027
|
+
EventsUI.onClick(
|
|
1028
|
+
`.btn-edit-doc-cancel-${params.data._id}`,
|
|
1029
|
+
async (ev) => {
|
|
1030
|
+
ev.preventDefault();
|
|
1031
|
+
Modal.removeModal(editModalId);
|
|
1032
|
+
},
|
|
1033
|
+
{ context: 'modal' },
|
|
1034
|
+
);
|
|
1035
|
+
});
|
|
1036
|
+
},
|
|
1037
|
+
{ context: 'modal' },
|
|
1038
|
+
);
|
|
480
1039
|
});
|
|
481
1040
|
}
|
|
482
1041
|
|
|
@@ -552,8 +1111,12 @@ const FileExplorer = {
|
|
|
552
1111
|
const format = FileExplorer.documentDataFormat({ document: documentInstance, location });
|
|
553
1112
|
files = format.files;
|
|
554
1113
|
folders = format.folders;
|
|
555
|
-
|
|
1114
|
+
applySearchFilter();
|
|
1115
|
+
currentPage = 0;
|
|
1116
|
+
displayedFiles = getPagedFiles();
|
|
1117
|
+
AgGrid.grids[gridFileId].setGridOption('rowData', displayedFiles);
|
|
556
1118
|
AgGrid.grids[gridFolderId].setGridOption('rowData', folders);
|
|
1119
|
+
updatePaginationUI();
|
|
557
1120
|
},
|
|
558
1121
|
{ context: 'modal' },
|
|
559
1122
|
);
|
|
@@ -620,6 +1183,57 @@ const FileExplorer = {
|
|
|
620
1183
|
value: location,
|
|
621
1184
|
})}
|
|
622
1185
|
</div>
|
|
1186
|
+
${dynamicCol({
|
|
1187
|
+
containerSelector: 'file-explorer-search-container',
|
|
1188
|
+
id: 'file-explorer-search',
|
|
1189
|
+
type: 'search-inputs',
|
|
1190
|
+
})}
|
|
1191
|
+
<div class="fl file-explorer-search-container">
|
|
1192
|
+
<div class="in fll file-explorer-search-col-a">
|
|
1193
|
+
${await Input.Render({
|
|
1194
|
+
id: `file-explorer-search-title`,
|
|
1195
|
+
type: 'text',
|
|
1196
|
+
label: html`<i class="fas fa-search"></i> ${Translate.Render('doc-title')}`,
|
|
1197
|
+
containerClass: 'in section-mp input-container-width',
|
|
1198
|
+
placeholder: true,
|
|
1199
|
+
})}
|
|
1200
|
+
</div>
|
|
1201
|
+
<div class="in fll file-explorer-search-col-b">
|
|
1202
|
+
${await Input.Render({
|
|
1203
|
+
id: `file-explorer-search-md-file`,
|
|
1204
|
+
type: 'text',
|
|
1205
|
+
label: html`<i class="fas fa-file-code"></i> ${Translate.Render('md-file-name')}`,
|
|
1206
|
+
containerClass: 'in section-mp input-container-width',
|
|
1207
|
+
placeholder: true,
|
|
1208
|
+
})}
|
|
1209
|
+
</div>
|
|
1210
|
+
<div class="in fll file-explorer-search-col-c">
|
|
1211
|
+
${await Input.Render({
|
|
1212
|
+
id: `file-explorer-search-file`,
|
|
1213
|
+
type: 'text',
|
|
1214
|
+
label: html`<i class="fas fa-file"></i> ${Translate.Render('generic-file-name')}`,
|
|
1215
|
+
containerClass: 'in section-mp input-container-width',
|
|
1216
|
+
placeholder: true,
|
|
1217
|
+
})}
|
|
1218
|
+
</div>
|
|
1219
|
+
<div
|
|
1220
|
+
class="in fll file-explorer-search-col-d"
|
|
1221
|
+
style="display: flex; align-items: center; justify-content: center; height: 100%;"
|
|
1222
|
+
>
|
|
1223
|
+
${await BtnIcon.Render({
|
|
1224
|
+
class: 'in management-table-btn-mini file-explorer-search-submit',
|
|
1225
|
+
label: html`<i class="fas fa-search"></i>`,
|
|
1226
|
+
type: 'button',
|
|
1227
|
+
style: 'top: 10px; margin-right: 5px;',
|
|
1228
|
+
})}
|
|
1229
|
+
${await BtnIcon.Render({
|
|
1230
|
+
class: 'in management-table-btn-mini file-explorer-search-clear',
|
|
1231
|
+
label: html`<i class="fas fa-broom"></i>`,
|
|
1232
|
+
type: 'button',
|
|
1233
|
+
style: 'top: 10px',
|
|
1234
|
+
})}
|
|
1235
|
+
</div>
|
|
1236
|
+
</div>
|
|
623
1237
|
</form>
|
|
624
1238
|
<div class="fl file-explorer-nav">
|
|
625
1239
|
<div class="in fll explorer-file-col">
|
|
@@ -659,8 +1273,12 @@ const FileExplorer = {
|
|
|
659
1273
|
const format = this.documentDataFormat({ document: documentInstance, location });
|
|
660
1274
|
files = format.files;
|
|
661
1275
|
folders = format.folders;
|
|
662
|
-
|
|
1276
|
+
applySearchFilter();
|
|
1277
|
+
currentPage = 0;
|
|
1278
|
+
displayedFiles = getPagedFiles();
|
|
1279
|
+
AgGrid.grids[gridFileId].setGridOption('rowData', displayedFiles);
|
|
663
1280
|
AgGrid.grids[gridFolderId].setGridOption('rowData', folders);
|
|
1281
|
+
updatePaginationUI();
|
|
664
1282
|
},
|
|
665
1283
|
},
|
|
666
1284
|
{
|
|
@@ -694,8 +1312,12 @@ const FileExplorer = {
|
|
|
694
1312
|
const format = this.documentDataFormat({ document: documentInstance, location });
|
|
695
1313
|
files = format.files;
|
|
696
1314
|
folders = format.folders;
|
|
697
|
-
|
|
1315
|
+
applySearchFilter();
|
|
1316
|
+
currentPage = 0;
|
|
1317
|
+
displayedFiles = getPagedFiles();
|
|
1318
|
+
AgGrid.grids[gridFileId].setGridOption('rowData', displayedFiles);
|
|
698
1319
|
AgGrid.grids[gridFolderId].setGridOption('rowData', folders);
|
|
1320
|
+
updatePaginationUI();
|
|
699
1321
|
}
|
|
700
1322
|
},
|
|
701
1323
|
},
|
|
@@ -722,13 +1344,37 @@ const FileExplorer = {
|
|
|
722
1344
|
// rowData: files,
|
|
723
1345
|
rowData: undefined,
|
|
724
1346
|
columnDefs: [
|
|
725
|
-
{ field: 'name', flex: 2, headerName: '
|
|
726
|
-
{ field: '
|
|
727
|
-
{
|
|
1347
|
+
{ field: 'name', flex: 2, headerName: 'Title', cellRenderer: LoadFileNameRenderer },
|
|
1348
|
+
{ field: 'mdFileName', flex: 1, headerName: 'MD File Name' },
|
|
1349
|
+
{ field: 'fileName', flex: 1, headerName: 'Generic File Name' },
|
|
1350
|
+
{ headerName: '', width: 150, cellRenderer: LoadFileActionsRenderer },
|
|
728
1351
|
],
|
|
729
1352
|
},
|
|
730
1353
|
})}
|
|
731
1354
|
</div>
|
|
1355
|
+
<div class="fl file-explorer-pagination" style="padding: 5px 0;">
|
|
1356
|
+
<div class="in fll" style="width: 33.33%;">
|
|
1357
|
+
${await BtnIcon.Render({
|
|
1358
|
+
class: 'in wfa file-explorer-prev-btn',
|
|
1359
|
+
label: html`<i class="fa-solid fa-chevron-left"></i> ${Translate.Render('previous')}`,
|
|
1360
|
+
type: 'button',
|
|
1361
|
+
})}
|
|
1362
|
+
</div>
|
|
1363
|
+
<div class="in fll" style="width: 33.33%; text-align: center;">
|
|
1364
|
+
<span
|
|
1365
|
+
class="file-explorer-pagination-info"
|
|
1366
|
+
style="display: inline-block; padding: 8px 0; min-width: 100px;"
|
|
1367
|
+
>1 / 1 (0 files)</span
|
|
1368
|
+
>
|
|
1369
|
+
</div>
|
|
1370
|
+
<div class="in fll" style="width: 33.33%;">
|
|
1371
|
+
${await BtnIcon.Render({
|
|
1372
|
+
class: 'in wfa file-explorer-next-btn',
|
|
1373
|
+
label: html`${Translate.Render('next')} <i class="fa-solid fa-chevron-right"></i>`,
|
|
1374
|
+
type: 'button',
|
|
1375
|
+
})}
|
|
1376
|
+
</div>
|
|
1377
|
+
</div>
|
|
732
1378
|
</div>
|
|
733
1379
|
</div>
|
|
734
1380
|
</div>
|
|
@@ -771,22 +1417,21 @@ const FileExplorer = {
|
|
|
771
1417
|
if (f.location !== '/' && f.location[f.location.length - 1] === '/') f.location = f.location.slice(0, -1);
|
|
772
1418
|
return f.location;
|
|
773
1419
|
},
|
|
774
|
-
documentDataFormat: function ({ document, location }) {
|
|
1420
|
+
documentDataFormat: function ({ document, location, searchFilters }) {
|
|
775
1421
|
let files = document.map((f) => {
|
|
776
|
-
if (!f.fileId)
|
|
777
|
-
f.fileId = {
|
|
778
|
-
name: f.title + '.md',
|
|
779
|
-
mimetype: 'text/markdown',
|
|
780
|
-
_id: f.mdFileId,
|
|
781
|
-
};
|
|
782
1422
|
return {
|
|
783
1423
|
location: this.locationFormat({ f }),
|
|
784
|
-
name: f.
|
|
785
|
-
|
|
786
|
-
|
|
1424
|
+
name: f.title,
|
|
1425
|
+
mdFileName: f.mdFileId?.name || '',
|
|
1426
|
+
fileName: f.fileId?.name || '',
|
|
1427
|
+
// Use the actual file ID for operations (prefer generic file, fallback to md file)
|
|
1428
|
+
fileId: f.fileId?._id || f.mdFileId?._id || null,
|
|
787
1429
|
_id: f._id,
|
|
788
1430
|
title: f.title,
|
|
789
1431
|
isPublic: f.isPublic || false,
|
|
1432
|
+
// Track file existence for edit form
|
|
1433
|
+
hasMdFile: !!f.mdFileId,
|
|
1434
|
+
hasGenericFile: !!f.fileId,
|
|
790
1435
|
};
|
|
791
1436
|
});
|
|
792
1437
|
let documentId = document._id;
|
|
@@ -799,14 +1444,26 @@ const FileExplorer = {
|
|
|
799
1444
|
locationId: `loc-${i}`,
|
|
800
1445
|
};
|
|
801
1446
|
});
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
1447
|
+
|
|
1448
|
+
const isSearching = searchFilters && (searchFilters.title || searchFilters.mdFile || searchFilters.file);
|
|
1449
|
+
|
|
1450
|
+
if (!isSearching) {
|
|
1451
|
+
files = files.filter((f) => f.location === location);
|
|
1452
|
+
folders = folders
|
|
1453
|
+
.filter((f) => f.location.startsWith(location))
|
|
1454
|
+
.map((f) => {
|
|
1455
|
+
f.fileCount = document.filter((file) => file.location === f.location).length;
|
|
1456
|
+
return f;
|
|
1457
|
+
})
|
|
1458
|
+
.filter((f) => f.fileCount > 0);
|
|
1459
|
+
} else {
|
|
1460
|
+
folders = folders
|
|
1461
|
+
.map((f) => {
|
|
1462
|
+
f.fileCount = files.filter((file) => file.location === f.location).length;
|
|
1463
|
+
return f;
|
|
1464
|
+
})
|
|
1465
|
+
.filter((f) => f.fileCount > 0);
|
|
1466
|
+
}
|
|
810
1467
|
return { files, documentId, folders };
|
|
811
1468
|
},
|
|
812
1469
|
};
|