@emailmaker/filemanager 0.10.92 → 0.10.93
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/{file-manager-IconsTab-BMy0LDoU.js → file-manager-IconsTab-CpDNFgOG.js} +2 -2
- package/{file-manager-ImageCodeGenerator-CBdZ5eV3.js → file-manager-ImageCodeGenerator-BEN0Q89z.js} +2 -2
- package/{file-manager-JsBarcode-Bk9cl2mc.js → file-manager-JsBarcode-Doi0kSN7.js} +2 -2
- package/{file-manager-browser-D-EORGqh.js → file-manager-browser-0JPlv5xy.js} +2 -2
- package/{file-manager-index-Z8TrA-pu.js → file-manager-index-6WE8OVI9.js} +2 -2
- package/file-manager.esm.js +1 -1
- package/file-manager.js +542 -524
- package/package.json +1 -1
- package/utils/mapWithConcurrency.d.ts +1 -0
package/file-manager.js
CHANGED
|
@@ -22726,8 +22726,8 @@ __webpack_require__.d(__webpack_exports__, {
|
|
|
22726
22726
|
|
|
22727
22727
|
// EXTERNAL MODULE: ./src/hooks/core/context.tsx
|
|
22728
22728
|
var context = __webpack_require__(8361);
|
|
22729
|
-
// EXTERNAL MODULE: ./src/hooks/core/files/index.ts +
|
|
22730
|
-
var core_files = __webpack_require__(
|
|
22729
|
+
// EXTERNAL MODULE: ./src/hooks/core/files/index.ts + 18 modules
|
|
22730
|
+
var core_files = __webpack_require__(8573);
|
|
22731
22731
|
;// ./src/hooks/core/useFiles.ts
|
|
22732
22732
|
|
|
22733
22733
|
|
|
@@ -27028,8 +27028,8 @@ __webpack_require__.d(__webpack_exports__, {
|
|
|
27028
27028
|
var core = __webpack_require__(4002);
|
|
27029
27029
|
// EXTERNAL MODULE: external {"root":"React","commonjs2":"react","commonjs":"react","amd":"react"}
|
|
27030
27030
|
var external_root_React_commonjs2_react_commonjs_react_amd_react_ = __webpack_require__(5442);
|
|
27031
|
-
// EXTERNAL MODULE: ./src/hooks/core/files/index.ts +
|
|
27032
|
-
var core_files = __webpack_require__(
|
|
27031
|
+
// EXTERNAL MODULE: ./src/hooks/core/files/index.ts + 18 modules
|
|
27032
|
+
var core_files = __webpack_require__(8573);
|
|
27033
27033
|
;// ./src/hooks/useFileActions.ts
|
|
27034
27034
|
|
|
27035
27035
|
|
|
@@ -28282,513 +28282,229 @@ const FileManagerProvider = ({ children, options }) => {
|
|
|
28282
28282
|
|
|
28283
28283
|
/***/ }),
|
|
28284
28284
|
|
|
28285
|
-
/***/
|
|
28285
|
+
/***/ 8573:
|
|
28286
28286
|
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
|
28287
28287
|
|
|
28288
28288
|
"use strict";
|
|
28289
|
-
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
28290
|
-
/* harmony export */ $5: () => (/* binding */ getUniqueFileName),
|
|
28291
|
-
/* harmony export */ mF: () => (/* binding */ encodeUrlForImageSrc),
|
|
28292
|
-
/* harmony export */ nF: () => (/* binding */ formatFileSizeDisplay),
|
|
28293
|
-
/* harmony export */ v7: () => (/* binding */ formatFileSize),
|
|
28294
|
-
/* harmony export */ w3: () => (/* binding */ MAX_FILE_SIZE)
|
|
28295
|
-
/* harmony export */ });
|
|
28296
|
-
/* unused harmony exports MIN_FILE_SIZE, ALLOWED_FILE_TYPES, ALL_ALLOWED_TYPES, validateFile, validateFiles, validateFileUrl, getFileCategory, formatFileSizeShort, sanitizeFileName */
|
|
28297
|
-
/* harmony import */ var antd__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(550);
|
|
28298
|
-
/* harmony import */ var antd__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(antd__WEBPACK_IMPORTED_MODULE_0__);
|
|
28299
|
-
/* harmony import */ var _i18n__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(3829);
|
|
28300
28289
|
|
|
28290
|
+
// EXPORTS
|
|
28291
|
+
__webpack_require__.d(__webpack_exports__, {
|
|
28292
|
+
fp: () => (/* reexport */ useFileSelectionStore),
|
|
28293
|
+
vD: () => (/* reexport */ useFilesAPI),
|
|
28294
|
+
l_: () => (/* reexport */ useFilesModals),
|
|
28295
|
+
nC: () => (/* reexport */ useFilesSelection)
|
|
28296
|
+
});
|
|
28301
28297
|
|
|
28302
|
-
|
|
28303
|
-
|
|
28304
|
-
|
|
28305
|
-
|
|
28306
|
-
|
|
28307
|
-
|
|
28308
|
-
|
|
28309
|
-
|
|
28310
|
-
|
|
28311
|
-
|
|
28312
|
-
archives: ['application/zip', 'application/x-rar-compressed', 'application/x-7z-compressed'],
|
|
28313
|
-
videos: ['video/mp4', 'video/avi', 'video/quicktime', 'video/x-msvideo'],
|
|
28314
|
-
audio: ['audio/mpeg', 'audio/wav', 'audio/ogg'],
|
|
28298
|
+
// UNUSED EXPORTS: addSubfoldersToFiles
|
|
28299
|
+
|
|
28300
|
+
// EXTERNAL MODULE: external {"root":"React","commonjs2":"react","commonjs":"react","amd":"react"}
|
|
28301
|
+
var external_root_React_commonjs2_react_commonjs_react_amd_react_ = __webpack_require__(5442);
|
|
28302
|
+
var external_root_React_commonjs2_react_commonjs_react_amd_react_default = /*#__PURE__*/__webpack_require__.n(external_root_React_commonjs2_react_commonjs_react_amd_react_);
|
|
28303
|
+
// EXTERNAL MODULE: ./node_modules/react-i18next/dist/es/index.js + 15 modules
|
|
28304
|
+
var es = __webpack_require__(2389);
|
|
28305
|
+
;// ./src/hooks/core/files/useFilesAPIHelpers.ts
|
|
28306
|
+
const isRootFolder = (folderId) => {
|
|
28307
|
+
return !folderId || folderId === 'root' || folderId === 'folders' || folderId === 'null' || folderId === null;
|
|
28315
28308
|
};
|
|
28316
|
-
const
|
|
28317
|
-
|
|
28318
|
-
|
|
28319
|
-
|
|
28320
|
-
const
|
|
28321
|
-
if (
|
|
28322
|
-
|
|
28309
|
+
const isRootFolderItem = (folder) => {
|
|
28310
|
+
return folder.parentId === null || folder.parentId === 'null' || !folder.parentId;
|
|
28311
|
+
};
|
|
28312
|
+
const filterFolders = (allFolders, params) => {
|
|
28313
|
+
const safeFolders = Array.isArray(allFolders) ? allFolders : [];
|
|
28314
|
+
if (isRootFolder(params.folderId)) {
|
|
28315
|
+
return safeFolders.filter(isRootFolderItem);
|
|
28323
28316
|
}
|
|
28324
|
-
|
|
28325
|
-
|
|
28317
|
+
return safeFolders.filter(folder => folder.parentId === params.folderId);
|
|
28318
|
+
};
|
|
28319
|
+
const addSubfoldersToFiles = async (files, params, getFolders) => {
|
|
28320
|
+
var _a;
|
|
28321
|
+
if ((params === null || params === void 0 ? void 0 : params.itemType) === 'file')
|
|
28322
|
+
return files;
|
|
28323
|
+
let allFolders = [];
|
|
28324
|
+
if (getFolders) {
|
|
28325
|
+
const foldersData = await getFolders({ parentId: params.folderId });
|
|
28326
|
+
allFolders = Array.isArray(foldersData) ? foldersData : [];
|
|
28326
28327
|
}
|
|
28327
|
-
|
|
28328
|
-
|
|
28328
|
+
else {
|
|
28329
|
+
return files;
|
|
28329
28330
|
}
|
|
28330
|
-
|
|
28331
|
-
|
|
28331
|
+
let subfolders = filterFolders(allFolders, params);
|
|
28332
|
+
if ((_a = params === null || params === void 0 ? void 0 : params.search) === null || _a === void 0 ? void 0 : _a.trim()) {
|
|
28333
|
+
const search = params.search.trim().toLowerCase();
|
|
28334
|
+
subfolders = subfolders.filter(f => { var _a; return (_a = f.name) === null || _a === void 0 ? void 0 : _a.toLowerCase().includes(search); });
|
|
28332
28335
|
}
|
|
28333
|
-
|
|
28334
|
-
|
|
28335
|
-
const code = char.charCodeAt(0);
|
|
28336
|
-
return code >= 0 && code <= 31;
|
|
28337
|
-
});
|
|
28338
|
-
if (invalidChars.test(file.name) || hasControlChars) {
|
|
28339
|
-
errors.push(i18n.t('File name contains invalid characters'));
|
|
28336
|
+
if (subfolders.length === 0) {
|
|
28337
|
+
return files;
|
|
28340
28338
|
}
|
|
28341
|
-
|
|
28342
|
-
|
|
28339
|
+
const folderItems = subfolders.map((folder) => ({
|
|
28340
|
+
id: folder.id,
|
|
28341
|
+
name: folder.name,
|
|
28342
|
+
size: undefined,
|
|
28343
|
+
date: '-',
|
|
28344
|
+
isFolder: true,
|
|
28345
|
+
folderId: folder.parentId || '',
|
|
28346
|
+
type: '',
|
|
28347
|
+
selected: false,
|
|
28348
|
+
extension: '',
|
|
28349
|
+
childCount: folder.childCount,
|
|
28350
|
+
}));
|
|
28351
|
+
if ((params === null || params === void 0 ? void 0 : params.itemType) === 'folder') {
|
|
28352
|
+
return folderItems;
|
|
28343
28353
|
}
|
|
28344
|
-
|
|
28345
|
-
|
|
28346
|
-
|
|
28347
|
-
|
|
28348
|
-
};
|
|
28349
|
-
};
|
|
28350
|
-
const validateFiles = (files, options = {}) => {
|
|
28351
|
-
const valid = [];
|
|
28352
|
-
const invalid = [];
|
|
28353
|
-
files.forEach(file => {
|
|
28354
|
-
const result = validateFile(file, options);
|
|
28355
|
-
if (result.isValid) {
|
|
28356
|
-
valid.push(file);
|
|
28357
|
-
}
|
|
28358
|
-
else {
|
|
28359
|
-
invalid.push({ file, result });
|
|
28360
|
-
}
|
|
28361
|
-
});
|
|
28362
|
-
return { valid, invalid };
|
|
28354
|
+
// getFiles(itemType:'all') может возвращать папки — исключаем их, т.к. folderItems уже содержит папки из getFolders
|
|
28355
|
+
const filesOnly = files.filter(f => !f.isFolder);
|
|
28356
|
+
const result = [...folderItems, ...filesOnly];
|
|
28357
|
+
return result;
|
|
28363
28358
|
};
|
|
28364
|
-
|
|
28365
|
-
|
|
28366
|
-
|
|
28367
|
-
|
|
28368
|
-
|
|
28369
|
-
|
|
28370
|
-
|
|
28371
|
-
|
|
28372
|
-
|
|
28373
|
-
|
|
28374
|
-
|
|
28375
|
-
|
|
28376
|
-
|
|
28377
|
-
|
|
28378
|
-
|
|
28379
|
-
|
|
28380
|
-
|
|
28381
|
-
|
|
28382
|
-
|
|
28383
|
-
|
|
28384
|
-
|
|
28385
|
-
|
|
28386
|
-
|
|
28359
|
+
|
|
28360
|
+
// EXTERNAL MODULE: ./src/hooks/core/useSortAndFilter.ts
|
|
28361
|
+
var useSortAndFilter = __webpack_require__(7228);
|
|
28362
|
+
// EXTERNAL MODULE: ./src/hooks/core/useFolders.ts
|
|
28363
|
+
var useFolders = __webpack_require__(5018);
|
|
28364
|
+
// EXTERNAL MODULE: ./src/hooks/useNotifications.tsx
|
|
28365
|
+
var useNotifications = __webpack_require__(3435);
|
|
28366
|
+
// EXTERNAL MODULE: ./src/hooks/core/files/actions/useFilesDelete.ts
|
|
28367
|
+
var useFilesDelete = __webpack_require__(1591);
|
|
28368
|
+
// EXTERNAL MODULE: ./src/utils/errorMessages.ts
|
|
28369
|
+
var errorMessages = __webpack_require__(6377);
|
|
28370
|
+
// EXTERNAL MODULE: ./src/utils/fileValidation.ts
|
|
28371
|
+
var fileValidation = __webpack_require__(9142);
|
|
28372
|
+
// EXTERNAL MODULE: ./src/utils/urlValidation.ts
|
|
28373
|
+
var urlValidation = __webpack_require__(69);
|
|
28374
|
+
// EXTERNAL MODULE: ./src/utils/imageCompression.ts
|
|
28375
|
+
var imageCompression = __webpack_require__(3270);
|
|
28376
|
+
// EXTERNAL MODULE: ./src/utils/cacheClear.ts
|
|
28377
|
+
var cacheClear = __webpack_require__(2332);
|
|
28378
|
+
// EXTERNAL MODULE: ./src/utils/resolveItemMeta.ts
|
|
28379
|
+
var resolveItemMeta = __webpack_require__(1069);
|
|
28380
|
+
// EXTERNAL MODULE: ./src/utils/nameNormalization.ts
|
|
28381
|
+
var nameNormalization = __webpack_require__(7407);
|
|
28382
|
+
// EXTERNAL MODULE: ./src/utils/mimeUtils.ts
|
|
28383
|
+
var mimeUtils = __webpack_require__(3662);
|
|
28384
|
+
;// ./src/utils/urlNormalization.ts
|
|
28385
|
+
const TRACKING_QUERY_PARAM_PATTERN = /^(utm_[a-z0-9_]+|fbclid|gclid|igshid|mc_cid|mc_eid)$/i;
|
|
28386
|
+
/**
|
|
28387
|
+
* Нормализует внешний URL для детерминированного поиска файла по источнику.
|
|
28388
|
+
* Убирает hash, трекинговые query-параметры, нормализует host и сортирует query.
|
|
28389
|
+
*/
|
|
28390
|
+
function normalizeExternalFileUrl(url) {
|
|
28391
|
+
const parsed = new URL(url.trim());
|
|
28392
|
+
parsed.hash = '';
|
|
28393
|
+
parsed.hostname = parsed.hostname.toLowerCase();
|
|
28394
|
+
if ((parsed.protocol === 'https:' && parsed.port === '443') ||
|
|
28395
|
+
(parsed.protocol === 'http:' && parsed.port === '80')) {
|
|
28396
|
+
parsed.port = '';
|
|
28387
28397
|
}
|
|
28398
|
+
const normalizedParams = Array.from(parsed.searchParams.entries())
|
|
28399
|
+
.filter(([key]) => !TRACKING_QUERY_PARAM_PATTERN.test(key))
|
|
28400
|
+
.sort(([keyA, valueA], [keyB, valueB]) => {
|
|
28401
|
+
const keyCompare = keyA.localeCompare(keyB);
|
|
28402
|
+
return keyCompare !== 0 ? keyCompare : valueA.localeCompare(valueB);
|
|
28403
|
+
});
|
|
28404
|
+
parsed.search = '';
|
|
28405
|
+
normalizedParams.forEach(([key, value]) => parsed.searchParams.append(key, value));
|
|
28406
|
+
return parsed.toString();
|
|
28407
|
+
}
|
|
28408
|
+
/**
|
|
28409
|
+
* Совпадает ли origin URL с текущей страницей (protocol + host + port).
|
|
28410
|
+
* Для same-origin прокси не используем — загрузка напрямую.
|
|
28411
|
+
*/
|
|
28412
|
+
function isUrlSameOriginAsCurrentPage(url) {
|
|
28413
|
+
if (typeof window === 'undefined')
|
|
28414
|
+
return false;
|
|
28388
28415
|
try {
|
|
28389
|
-
|
|
28390
|
-
if (!response.ok) {
|
|
28391
|
-
errors.push(i18n.t('File unavailable: {{status}} {{statusText}}', {
|
|
28392
|
-
status: response.status,
|
|
28393
|
-
statusText: response.statusText,
|
|
28394
|
-
}));
|
|
28395
|
-
}
|
|
28396
|
-
const contentLength = response.headers.get('content-length');
|
|
28397
|
-
if (contentLength && parseInt(contentLength) > MAX_FILE_SIZE) {
|
|
28398
|
-
errors.push(i18n.t('File too large: {{size}}', { size: formatFileSize(parseInt(contentLength)) }));
|
|
28399
|
-
}
|
|
28400
|
-
const contentType = response.headers.get('content-type');
|
|
28401
|
-
if (contentType && !ALL_ALLOWED_TYPES.includes(contentType)) {
|
|
28402
|
-
errors.push(i18n.t('Unsupported file type: {{contentType}}', { contentType }));
|
|
28403
|
-
}
|
|
28416
|
+
return new URL(url).origin === window.location.origin;
|
|
28404
28417
|
}
|
|
28405
|
-
catch (
|
|
28406
|
-
|
|
28407
|
-
lastError = error;
|
|
28408
|
-
const message = i18n.t('Unable to validate file URL');
|
|
28409
|
-
errors.push(message);
|
|
28410
|
-
notifyError(message);
|
|
28418
|
+
catch (_a) {
|
|
28419
|
+
return false;
|
|
28411
28420
|
}
|
|
28412
|
-
|
|
28413
|
-
|
|
28421
|
+
}
|
|
28422
|
+
|
|
28423
|
+
// EXTERNAL MODULE: ./src/utils/remoteFileFetchPipeline.ts + 1 modules
|
|
28424
|
+
var remoteFileFetchPipeline = __webpack_require__(5597);
|
|
28425
|
+
// EXTERNAL MODULE: ./src/utils/dedupeUploadNamesOnClient.ts
|
|
28426
|
+
var dedupeUploadNamesOnClient = __webpack_require__(3795);
|
|
28427
|
+
// EXTERNAL MODULE: ./src/utils/resolveUniqueUploadName.ts
|
|
28428
|
+
var utils_resolveUniqueUploadName = __webpack_require__(7742);
|
|
28429
|
+
// EXTERNAL MODULE: ./src/utils/fileFormatUtils.ts
|
|
28430
|
+
var fileFormatUtils = __webpack_require__(6825);
|
|
28431
|
+
;// ./src/utils/mapWithConcurrency.ts
|
|
28432
|
+
async function mapWithConcurrency(items, limit, fn) {
|
|
28433
|
+
if (items.length === 0) {
|
|
28434
|
+
return [];
|
|
28414
28435
|
}
|
|
28415
|
-
|
|
28416
|
-
|
|
28417
|
-
|
|
28436
|
+
const results = new Array(items.length);
|
|
28437
|
+
let nextIndex = 0;
|
|
28438
|
+
const poolSize = Math.max(1, Math.min(limit, items.length));
|
|
28439
|
+
const worker = async () => {
|
|
28440
|
+
while (true) {
|
|
28441
|
+
const currentIndex = nextIndex++;
|
|
28442
|
+
if (currentIndex >= items.length) {
|
|
28443
|
+
return;
|
|
28444
|
+
}
|
|
28445
|
+
results[currentIndex] = await fn(items[currentIndex], currentIndex);
|
|
28446
|
+
}
|
|
28418
28447
|
};
|
|
28419
|
-
};
|
|
28420
|
-
|
|
28421
|
-
|
|
28422
|
-
|
|
28423
|
-
|
|
28424
|
-
|
|
28425
|
-
|
|
28426
|
-
|
|
28427
|
-
|
|
28428
|
-
|
|
28429
|
-
|
|
28430
|
-
if (ALLOWED_FILE_TYPES.audio.includes(type))
|
|
28431
|
-
return 'audio';
|
|
28432
|
-
return 'other';
|
|
28433
|
-
};
|
|
28434
|
-
const formatFileSize = (bytes) => {
|
|
28435
|
-
if (bytes === 0)
|
|
28436
|
-
return '0 Bytes';
|
|
28437
|
-
const k = 1024;
|
|
28438
|
-
const sizes = ['Bytes', 'KB', 'MB', 'GB'];
|
|
28439
|
-
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
|
28440
|
-
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
|
|
28441
|
-
};
|
|
28442
|
-
const formatFileSizeShort = (bytes) => {
|
|
28443
|
-
if (!bytes || bytes <= 0)
|
|
28444
|
-
return '';
|
|
28445
|
-
const KILOBYTE = 1024;
|
|
28446
|
-
const MEGABYTE = KILOBYTE * 1024;
|
|
28447
|
-
if (bytes < MEGABYTE) {
|
|
28448
|
-
const kb = Math.round(bytes / KILOBYTE);
|
|
28449
|
-
return `${kb} Kb`;
|
|
28450
|
-
}
|
|
28451
|
-
const mb = bytes / MEGABYTE;
|
|
28452
|
-
return `${mb.toFixed(2)} Mb`;
|
|
28453
|
-
};
|
|
28454
|
-
const formatFileSizeDisplay = (value) => {
|
|
28455
|
-
if (value === undefined || value === null)
|
|
28456
|
-
return '';
|
|
28457
|
-
if (typeof value === 'number') {
|
|
28458
|
-
return formatFileSizeShort(value);
|
|
28459
|
-
}
|
|
28460
|
-
const normalized = String(value).trim();
|
|
28461
|
-
if (!normalized)
|
|
28462
|
-
return '';
|
|
28463
|
-
const parsed = Number(normalized);
|
|
28464
|
-
if (!Number.isNaN(parsed)) {
|
|
28465
|
-
return formatFileSizeShort(parsed);
|
|
28466
|
-
}
|
|
28467
|
-
return normalized;
|
|
28468
|
-
};
|
|
28469
|
-
/**
|
|
28470
|
-
* Генерирует уникальное имя файла: если name уже есть в existingNames, добавляет _1 (или _2, _3 и т.д.).
|
|
28471
|
-
* @param name — исходное имя файла (с расширением)
|
|
28472
|
-
* @param existingNames — массив имён файлов/папок в целевой директории
|
|
28473
|
-
*/
|
|
28474
|
-
const getUniqueFileName = (name, existingNames) => {
|
|
28475
|
-
const safeNames = existingNames.filter((n) => typeof n === 'string');
|
|
28476
|
-
const set = new Set(safeNames.map(n => n.toLowerCase()));
|
|
28477
|
-
const safeName = typeof name === 'string' ? name : String(name !== null && name !== void 0 ? name : '');
|
|
28478
|
-
if (!set.has(safeName.toLowerCase()))
|
|
28479
|
-
return safeName;
|
|
28480
|
-
const lastDot = safeName.lastIndexOf('.');
|
|
28481
|
-
const baseName = lastDot > 0 ? safeName.slice(0, lastDot) : safeName;
|
|
28482
|
-
const ext = lastDot > 0 ? safeName.slice(lastDot) : '';
|
|
28483
|
-
let suffix = 1;
|
|
28484
|
-
let candidate;
|
|
28485
|
-
do {
|
|
28486
|
-
candidate = `${baseName}_${suffix}${ext}`;
|
|
28487
|
-
suffix++;
|
|
28488
|
-
} while (set.has(candidate.toLowerCase()));
|
|
28489
|
-
return candidate;
|
|
28490
|
-
};
|
|
28491
|
-
/**
|
|
28492
|
-
* Кодирует URL для безопасного использования в img src. Решает проблему с кириллицей и другими
|
|
28493
|
-
* не-ASCII символами в пути (например, emcdn.ru/.../Снимок_экрана.png).
|
|
28494
|
-
* data: и blob: URLs возвращаются без изменений.
|
|
28495
|
-
*/
|
|
28496
|
-
const encodeUrlForImageSrc = (url) => {
|
|
28497
|
-
if (!url || typeof url !== 'string')
|
|
28498
|
-
return undefined;
|
|
28499
|
-
if (url.startsWith('data:') || url.startsWith('blob:'))
|
|
28500
|
-
return url;
|
|
28501
|
-
try {
|
|
28502
|
-
if (url.startsWith('http://') || url.startsWith('https://') || url.startsWith('/')) {
|
|
28503
|
-
const parsed = new URL(url.startsWith('/') ? `https://x${url}` : url);
|
|
28504
|
-
const origin = url.startsWith('/') ? '' : `${parsed.protocol}//${parsed.host}`;
|
|
28505
|
-
const pathEncoded = parsed.pathname
|
|
28506
|
-
.split('/')
|
|
28507
|
-
.map(seg => {
|
|
28508
|
-
if (!seg)
|
|
28509
|
-
return '';
|
|
28510
|
-
try {
|
|
28511
|
-
return encodeURIComponent(decodeURIComponent(seg));
|
|
28512
|
-
}
|
|
28513
|
-
catch (_a) {
|
|
28514
|
-
return encodeURIComponent(seg);
|
|
28515
|
-
}
|
|
28516
|
-
})
|
|
28517
|
-
.join('/');
|
|
28518
|
-
const result = url.startsWith('/') ? pathEncoded + (parsed.search || '') + (parsed.hash || '') : `${origin}${pathEncoded}${parsed.search}${parsed.hash}`;
|
|
28519
|
-
return result;
|
|
28520
|
-
}
|
|
28521
|
-
}
|
|
28522
|
-
catch (_a) {
|
|
28523
|
-
// если парсинг не удался, возвращаем как есть
|
|
28524
|
-
}
|
|
28525
|
-
return url;
|
|
28526
|
-
};
|
|
28527
|
-
/**
|
|
28528
|
-
* @deprecated Эта функция оставлена только для обратной совместимости.
|
|
28529
|
-
* Используйте {@link normalizeFileName} из `nameNormalization.ts` для настраиваемой нормализации имен файлов.
|
|
28530
|
-
*
|
|
28531
|
-
* Упрощенная санитизация имени файла:
|
|
28532
|
-
* - Заменяет запрещенные символы на `_`
|
|
28533
|
-
* - Заменяет пробелы на `_`
|
|
28534
|
-
* - Удаляет множественные подчеркивания
|
|
28535
|
-
* - Ограничивает длину до 255 символов
|
|
28536
|
-
*/
|
|
28537
|
-
const sanitizeFileName = (fileName) => {
|
|
28538
|
-
return fileName
|
|
28539
|
-
.replace(/[<>:"/\\|?*()#]/g, '_')
|
|
28540
|
-
.split('')
|
|
28541
|
-
.map(char => {
|
|
28542
|
-
const code = char.charCodeAt(0);
|
|
28543
|
-
return code >= 0 && code <= 31 ? '_' : char;
|
|
28544
|
-
})
|
|
28545
|
-
.join('')
|
|
28546
|
-
.replace(/\s+/g, '_')
|
|
28547
|
-
.replace(/_{2,}/g, '_')
|
|
28548
|
-
.substring(0, 255);
|
|
28549
|
-
};
|
|
28448
|
+
await Promise.all(Array.from({ length: poolSize }, () => worker()));
|
|
28449
|
+
return results;
|
|
28450
|
+
}
|
|
28451
|
+
|
|
28452
|
+
// EXTERNAL MODULE: ./src/hooks/core/context.tsx
|
|
28453
|
+
var context = __webpack_require__(8361);
|
|
28454
|
+
// EXTERNAL MODULE: ./src/constants/index.tsx
|
|
28455
|
+
var constants = __webpack_require__(133);
|
|
28456
|
+
// EXTERNAL MODULE: ./src/shared/fileManagerApiError.ts
|
|
28457
|
+
var fileManagerApiError = __webpack_require__(7036);
|
|
28458
|
+
;// ./src/hooks/core/files/useFilesAPI.ts
|
|
28550
28459
|
|
|
28551
28460
|
|
|
28552
|
-
/***/ }),
|
|
28553
28461
|
|
|
28554
|
-
/***/ 9287:
|
|
28555
|
-
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
|
28556
28462
|
|
|
28557
|
-
// Imports
|
|
28558
|
-
var ___CSS_LOADER_API_SOURCEMAP_IMPORT___ = __webpack_require__(1354);
|
|
28559
|
-
var ___CSS_LOADER_API_IMPORT___ = __webpack_require__(6314);
|
|
28560
|
-
var ___CSS_LOADER_EXPORT___ = ___CSS_LOADER_API_IMPORT___(___CSS_LOADER_API_SOURCEMAP_IMPORT___);
|
|
28561
|
-
// Module
|
|
28562
|
-
___CSS_LOADER_EXPORT___.push([module.id, `.FolderSidebar-module__button__Yf2rX.ant-btn.ant-btn-icon-only{padding:calc(var(--paddingXXS)*1px) calc(var(--paddingSM)*1px);cursor:pointer;color:var(--colorTextSecondary);display:flex;gap:calc(var(--marginXS)*1px);align-items:center;justify-content:center;border-radius:calc(var(--borderRadiusSM)*1px);transition:all var(--motionDurationFast);box-shadow:none;border:none;width:32px;height:32px}.FolderSidebar-module__button__Yf2rX.ant-btn.ant-btn-icon-only:hover{background-color:var(--colorBgLayout);color:inherit}.FolderSidebar-module__button__Yf2rX:hover{background-color:var(--colorBgContainer);color:var(--colorPrimary)}.FolderSidebar-module__foldersTitle__Uh6u7{display:flex;align-items:center;flex:1;cursor:pointer}.FolderSidebar-module__folderActions__qA2Bk{position:absolute;top:4px;right:4px;display:flex;align-items:center;gap:4px;z-index:10}.FolderSidebar-module__folderActions__qA2Bk .FolderSidebar-module__button__Yf2rX.FolderSidebar-module__ant-btn__LXAXm.FolderSidebar-module__ant-btn-icon-only__j_wVF{padding:calc(var(--paddingXXS)*1px) calc(var(--paddingSM)*1px);cursor:pointer;color:var(--colorTextSecondary);display:flex;gap:calc(var(--marginXS)*1px);align-items:center;justify-content:center;border-radius:calc(var(--borderRadiusSM)*1px);transition:all var(--motionDurationFast);box-shadow:none;border:none;width:32px;height:32px}.FolderSidebar-module__folderActions__qA2Bk .FolderSidebar-module__button__Yf2rX.FolderSidebar-module__ant-btn__LXAXm.FolderSidebar-module__ant-btn-icon-only__j_wVF:hover{background-color:var(--colorBgLayout);color:inherit}.FolderSidebar-module__customExpandIcon__IhZJl{display:inline-flex;align-items:center;justify-content:center;width:16px;height:16px;margin-right:8px;cursor:pointer;color:#666;font-size:10px;transition:transform .2s ease}.FolderSidebar-module__customExpandIcon__IhZJl:hover{color:var(--colorPrimary)}.FolderSidebar-module__fileCount__bD9DD{display:inline-flex;align-items:center;justify-content:center;min-width:20px;height:100%;padding:0 6px;margin-left:8px;color:#8d8d8d;font-size:14px;font-weight:500;transition:all .2s ease;white-space:nowrap;cursor:default;flex-shrink:0;margin-right:10px}.ant-tree .ant-tree-node-content-wrapper.ant-tree-node-selected{background-color:rgba(0,0,0,0) !important}.FolderSidebar-module__folderMenu__JCzLF .ant-tree-treenode-selected .folder-label span,.FolderSidebar-module__folderMenu__JCzLF .ant-tree .ant-tree-node-content-wrapper.ant-tree-node-selected .folderLabelItem,.FolderSidebar-module__folderMenu__JCzLF .ant-tree-treenode-selected .folderLabelItem,.FolderSidebar-module__folderMenu__JCzLF .ant-tree-node-selected .folderLabelItem{font-weight:600 !important}.FolderSidebar-module__uploadButton__QQUid{width:100%;justify-content:flex-start}.FolderSidebar-module__uploadButton__QQUid button:hover{background-color:var(--colorPrimaryHover) !important}.FolderSidebar-module__folderMenu__JCzLF{padding-left:0;padding-right:0}.FolderSidebar-module__folderMenu__JCzLF .ant-tree-treenode{display:flex;align-items:center;justify-content:space-between;padding:4px 0;border-radius:4px;transition:background-color .2s ease;width:100%;margin-bottom:0}.FolderSidebar-module__folderMenu__JCzLF .ant-tree-node-content-wrapper{flex:1;align-items:center;padding:0;transition:background-color .2s ease}.FolderSidebar-module__folderMenu__JCzLF .ant-tree-node-content-wrapper:hover{background-color:rgba(0,0,0,0)}.FolderSidebar-module__folderMenu__JCzLF .ant-tree-switcher{height:24px;width:24px;margin-top:5px;display:flex !important;align-items:center;justify-content:center;transition:color .2s ease;flex-shrink:0}.FolderSidebar-module__folderMenu__JCzLF .ant-tree-switcher-noop{width:24px}.FolderSidebar-module__folderMenu__JCzLF .ant-tree-switcher-line-icon{color:#d9d9d9}.FolderSidebar-module__folderMenu__JCzLF .FolderSidebar-module__folderItemContainer__byl5b{width:100%;display:flex;align-items:center;justify-content:space-between;padding:2px 0;min-width:0}.FolderSidebar-module__folderMenu__JCzLF .folder-label{display:flex;align-items:center;flex:1;color:#595959;font-size:14px;min-width:0;overflow:hidden}.FolderSidebar-module__folderMenu__JCzLF .ant-tree-treenode[data-key="folders"]{border-bottom:1px solid var(--colorBorderSecondary);margin-bottom:8px;padding-bottom:8px}.FolderSidebar-module__folderMenu__JCzLF .ant-tree-treenode[data-key="folders"].ant-tree-treenode-selected{background-color:rgba(0,0,0,0) !important}.FolderSidebar-module__folderMenu__JCzLF .ant-tree-treenode[data-key="folders"] .ant-tree-node-content-wrapper{padding:0}.FolderSidebar-module__folderMenu__JCzLF .ant-tree-treenode[data-key="folders"] .ant-tree-node-content-wrapper:hover{background-color:rgba(0,0,0,0) !important}.FolderSidebar-module__folderMenu__JCzLF .ellipsis{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;flex:1;min-width:0}.FolderSidebar-module__folderMenu__JCzLF .FolderSidebar-module__emptyFolderContainer__WK6tx{padding:20px;text-align:center}.FolderSidebar-module__folderMenu__JCzLF .ant-tree > .ant-tree-treenode{padding-left:0 !important}.FolderSidebar-module__folderIcon__UoZzH{margin-right:8px;font-size:18px;flex-shrink:0}.FolderSidebar-module__folderLabelItem__uJ062{font-size:14px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;flex:1;min-width:0;user-select:none}.FolderSidebar-module__foldersTitleItem__gapOI{display:flex;align-items:center;flex:1;cursor:pointer;min-width:0;overflow:hidden}.FolderSidebar-module__folderLabel__fHWMp{display:flex;align-items:center;flex:1;min-width:0;overflow:hidden}.FolderSidebar-module__foldersContainer__zdBVU{position:relative;width:100%}.FolderSidebar-module__uploadButton__QQUid .FolderSidebar-module__ant-btn__LXAXm,.FolderSidebar-module__uploadButton__QQUid .ant-btn{display:flex;align-items:center;justify-content:center;gap:3px}.FolderSidebar-module__buttonWrapper__a9Qi5{margin-bottom:24px;display:flex;gap:4px}.FolderSidebar-module__buttonWrapper__a9Qi5>:first-child{flex:1;height:40px;padding-left:10px}.FolderSidebar-module__buttonWrapper__a9Qi5>:last-child{width:40px;height:40px;flex-shrink:0}.FolderSidebar-module__uploadButtonIcon__mWQmq{font-size:20px}.FolderSidebar-module__uploadButtonTitle__wk_o6{line-height:1em}.FolderSidebar-module__emptyFolderContainer__WK6tx{user-select:none;cursor:default;color:var(--colorTextTertiary)}.FolderSidebar-module__folderItemContainer__byl5b{width:100%;display:flex;align-items:center;justify-content:space-between;padding:2px 0;min-width:0}`, "",{"version":3,"sources":["webpack://./src/components/FolderSidebar/FolderSidebar.module.scss"],"names":[],"mappings":"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","sourcesContent":[".button:global(.ant-btn.ant-btn-icon-only) {\r\n padding: calc(var(--paddingXXS) * 1px) calc(var(--paddingSM) * 1px);\r\n cursor: pointer;\r\n color: var(--colorTextSecondary);\r\n display: flex;\r\n gap: calc(var(--marginXS) * 1px);\r\n align-items: center;\r\n justify-content: center;\r\n border-radius: calc(var(--borderRadiusSM) * 1px);\r\n transition: all var(--motionDurationFast);\r\n box-shadow: none;\r\n\r\n border: none;\r\n width: 32px;\r\n height: 32px;\r\n\r\n &:hover {\r\n background-color: var(--colorBgLayout);\r\n color: inherit;\r\n }\r\n}\r\n\r\n.button:hover {\r\n background-color: var(--colorBgContainer);\r\n color: var(--colorPrimary);\r\n}\r\n\r\n.foldersTitle {\r\n display: flex;\r\n align-items: center;\r\n flex: 1;\r\n cursor: pointer;\r\n}\r\n\r\n.folderActions {\r\n position: absolute;\r\n top: 4px; /* Выравниваем по заголовку Folders */\r\n right: 4px;\r\n display: flex;\r\n align-items: center;\r\n gap: 4px;\r\n z-index: 10;\r\n\r\n .button.ant-btn.ant-btn-icon-only {\r\n padding: calc(var(--paddingXXS) * 1px) calc(var(--paddingSM) * 1px);\r\n cursor: pointer;\r\n color: var(--colorTextSecondary);\r\n display: flex;\r\n gap: calc(var(--marginXS) * 1px);\r\n align-items: center;\r\n justify-content: center;\r\n border-radius: calc(var(--borderRadiusSM) * 1px);\r\n transition: all var(--motionDurationFast);\r\n box-shadow: none;\r\n\r\n border: none;\r\n width: 32px;\r\n height: 32px;\r\n\r\n &:hover {\r\n background-color: var(--colorBgLayout);\r\n color: inherit;\r\n }\r\n }\r\n}\r\n\r\n.customExpandIcon {\r\n display: inline-flex;\r\n align-items: center;\r\n justify-content: center;\r\n width: 16px;\r\n height: 16px;\r\n margin-right: 8px;\r\n cursor: pointer;\r\n color: #666;\r\n font-size: 10px;\r\n transition: transform 0.2s ease;\r\n}\r\n\r\n.customExpandIcon:hover {\r\n color: var(--colorPrimary);\r\n}\r\n\r\n.fileCount {\r\n display: inline-flex;\r\n align-items: center;\r\n justify-content: center;\r\n min-width: 20px;\r\n height: 100%;\r\n padding: 0 6px;\r\n margin-left: 8px;\r\n color: #8D8D8D;\r\n font-size: 14px;\r\n font-weight: 500;\r\n transition: all 0.2s ease;\r\n white-space: nowrap;\r\n cursor: default;\r\n flex-shrink: 0; /* Запрещаем сжатие счетчика */\r\n margin-right: 10px;\r\n}\r\n\r\n// .fileCount:hover {\r\n// border-color: var(--colorPrimary);\r\n// color: var(--colorPrimary);\r\n// }\r\n\r\n:global(.ant-tree .ant-tree-node-content-wrapper.ant-tree-node-selected) {\r\n background-color: transparent !important;\r\n}\r\n\r\n/* :global(.ant-tree .ant-tree-node-content-wrapper.ant-tree-node-selected):hover {\r\n color: red !important;\r\n} */\r\n\r\n/* Стили для выделения текста в выбранной папке */\r\n.folderMenu :global(.ant-tree-treenode-selected .folder-label span),\r\n.folderMenu :global(.ant-tree .ant-tree-node-content-wrapper.ant-tree-node-selected .folderLabelItem),\r\n.folderMenu :global(.ant-tree-treenode-selected .folderLabelItem),\r\n.folderMenu :global(.ant-tree-node-selected .folderLabelItem) {\r\n font-weight: 600 !important;\r\n}\r\n\r\n/* Стили для иконки в выбранной папке */\r\n/* .folderMenu :global(.ant-tree-treenode-selected .folderIcon),\r\n.folderMenu :global(.ant-tree-node-selected .folderIcon) {\r\n color: red !important;\r\n} */\r\n\r\n/* CSS переменные для упрощения расчетов */\r\n\r\n.uploadButton {\r\n width: 100%;\r\n justify-content: flex-start;\r\n\r\n & button:hover {\r\n background-color: var(--colorPrimaryHover) !important;\r\n }\r\n}\r\n\r\n.folderMenu {\r\n padding-left: 0;\r\n padding-right: 0; /* Место для кнопки справа */\r\n}\r\n\r\n.folderMenu :global(.ant-tree-treenode) {\r\n display: flex;\r\n align-items: center;\r\n justify-content: space-between;\r\n padding: 4px 0;\r\n border-radius: 4px;\r\n transition: background-color 0.2s ease;\r\n width: 100%;\r\n margin-bottom: 0;\r\n}\r\n\r\n.folderMenu :global(.ant-tree-node-content-wrapper) {\r\n flex: 1;\r\n /* display: flex; */\r\n align-items: center;\r\n padding: 0;\r\n /* border-radius: 4px; */\r\n transition: background-color 0.2s ease;\r\n}\r\n\r\n.folderMenu :global(.ant-tree-node-content-wrapper:hover) {\r\n background-color: transparent;\r\n}\r\n\r\n.folderMenu :global(.ant-tree-switcher) {\r\n height: 24px;\r\n width: 24px;\r\n margin-top: 5px;\r\n display: flex !important;\r\n align-items: center;\r\n justify-content: center;\r\n transition: color 0.2s ease;\r\n flex-shrink: 0; /* Запрещаем сжатие переключателя */\r\n}\r\n\r\n.folderMenu :global(.ant-tree-switcher-noop) {\r\n width: 24px;\r\n}\r\n\r\n/* Стили для линий дерева */\r\n.folderMenu :global(.ant-tree-switcher-line-icon) {\r\n color: #d9d9d9;\r\n}\r\n\r\n/* Улучшение отображения folder-item-container */\r\n.folderMenu .folderItemContainer {\r\n width: 100%;\r\n display: flex;\r\n align-items: center;\r\n justify-content: space-between;\r\n padding: 2px 0;\r\n min-width: 0; /* Позволяет flex-элементам сжиматься */\r\n}\r\n\r\n.folderMenu :global(.folder-label) {\r\n display: flex;\r\n align-items: center;\r\n flex: 1;\r\n color: #595959;\r\n font-size: 14px;\r\n min-width: 0;\r\n overflow: hidden;\r\n}\r\n\r\n/* Стили для корневого элемента Folders */\r\n.folderMenu :global(.ant-tree-treenode[data-key='folders']) {\r\n border-bottom: 1px solid var(--colorBorderSecondary);\r\n margin-bottom: 8px;\r\n padding-bottom: 8px;\r\n}\r\n\r\n.folderMenu :global(.ant-tree-treenode[data-key='folders'].ant-tree-treenode-selected) {\r\n background-color: transparent !important;\r\n}\r\n\r\n.folderMenu :global(.ant-tree-treenode[data-key='folders'] .ant-tree-node-content-wrapper) {\r\n padding: 0;\r\n}\r\n\r\n.folderMenu :global(.ant-tree-treenode[data-key='folders'] .ant-tree-node-content-wrapper:hover) {\r\n background-color: transparent !important;\r\n}\r\n\r\n/* Стили для ellipsis - удаляем max-width для гибкости */\r\n.folderMenu :global(.ellipsis) {\r\n overflow: hidden;\r\n text-overflow: ellipsis;\r\n white-space: nowrap;\r\n flex: 1;\r\n min-width: 0;\r\n}\r\n\r\n/* Стили для пустого состояния */\r\n.folderMenu .emptyFolderContainer {\r\n padding: 20px;\r\n text-align: center;\r\n}\r\n\r\n/* Убираем отступы у корневого узла */\r\n.folderMenu :global(.ant-tree > .ant-tree-treenode) {\r\n padding-left: 0 !important;\r\n}\r\n.folderIcon {\r\n margin-right: 8px;\r\n font-size: 18px;\r\n flex-shrink: 0; /* Запрещаем сжатие иконки */\r\n}\r\n\r\n.folderLabelItem {\r\n font-size: 14px;\r\n white-space: nowrap; /* Запрещаем перенос строк */\r\n overflow: hidden; /* Скрываем переполнение */\r\n text-overflow: ellipsis; /* Показываем троеточие */\r\n flex: 1; /* Занимает доступное место */\r\n min-width: 0; /* Позволяет сжиматься */\r\n user-select: none;\r\n}\r\n\r\n.foldersTitleItem {\r\n display: flex;\r\n align-items: center;\r\n flex: 1;\r\n cursor: pointer;\r\n min-width: 0; /* Позволяет сжиматься */\r\n overflow: hidden; /* Скрываем переполнение */\r\n}\r\n\r\n/* .foldersTitleItem .folderLabelItem {\r\n font-weight: 500;\r\n color: #262626;\r\n} */\r\n\r\n/* Класс для заголовка папок */\r\n.folderLabel {\r\n display: flex;\r\n align-items: center;\r\n flex: 1;\r\n min-width: 0;\r\n overflow: hidden;\r\n}\r\n\r\n.foldersContainer {\r\n position: relative;\r\n width: 100%;\r\n}\r\n\r\n/* Дополнительные стили для улучшения визуала */\r\n/* .folderMenu :global(.ant-tree-treenode:hover .folder-label span) {\r\n color: #1890ff;\r\n} */\r\n\r\n/* Стили для дивайдера между папками */\r\n\r\n\r\n.uploadButton .ant-btn,\r\n.uploadButton :global(.ant-btn) {\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n gap: 3px;\r\n}\r\n/* .folderMenu :global(.ant-tree-treenode-selected) .folderLabelItem {\r\n color: #1890ff !important;\r\n} */\r\n\r\n// .folderMenu :global(.ant-tree-treenode-selected) .folderLabel .folderLabelItem,\r\n// .folderMenu :global(.ant-tree-treenode-selected) .folderLabel .folderIcon,\r\n// .folderMenu :global(.ant-tree-treenode-selected) .folderLabelItem {\r\n// color: var(--colorLink);\r\n// }\r\n\r\n\r\n.buttonWrapper {\r\n // overflow: hidden;\r\n margin-bottom: 24px;\r\n display: flex;\r\n gap: 4px;\r\n // border-radius: calc(var(--borderRadius) * 1px);\r\n \r\n // Левая кнопка занимает всю доступную ширину\r\n > :first-child {\r\n flex: 1;\r\n height: 40px;\r\n padding-left: 10px;\r\n }\r\n \r\n // Правая кнопка строго 40px\r\n > :last-child {\r\n width: 40px;\r\n height: 40px;\r\n flex-shrink: 0;\r\n }\r\n}\r\n\r\n.uploadButtonIcon {\r\n font-size: 20px;\r\n}\r\n\r\n.uploadButtonTitle {\r\n line-height: 1em;\r\n}\r\n\r\n.emptyFolderContainer {\r\n user-select: none;\r\n cursor: default;\r\n color: var(--colorTextTertiary);\r\n}\r\n\r\n.folderItemContainer {\r\n width: 100%;\r\n display: flex;\r\n align-items: center;\r\n justify-content: space-between;\r\n padding: 2px 0;\r\n min-width: 0; /* Позволяет flex-элементам сжиматься */\r\n}\r\n"],"sourceRoot":""}]);
|
|
28563
|
-
// Exports
|
|
28564
|
-
___CSS_LOADER_EXPORT___.locals = {
|
|
28565
|
-
"button": `FolderSidebar-module__button__Yf2rX`,
|
|
28566
|
-
"foldersTitle": `FolderSidebar-module__foldersTitle__Uh6u7`,
|
|
28567
|
-
"folderActions": `FolderSidebar-module__folderActions__qA2Bk`,
|
|
28568
|
-
"ant-btn": `FolderSidebar-module__ant-btn__LXAXm`,
|
|
28569
|
-
"antBtn": `FolderSidebar-module__ant-btn__LXAXm`,
|
|
28570
|
-
"ant-btn-icon-only": `FolderSidebar-module__ant-btn-icon-only__j_wVF`,
|
|
28571
|
-
"antBtnIconOnly": `FolderSidebar-module__ant-btn-icon-only__j_wVF`,
|
|
28572
|
-
"customExpandIcon": `FolderSidebar-module__customExpandIcon__IhZJl`,
|
|
28573
|
-
"fileCount": `FolderSidebar-module__fileCount__bD9DD`,
|
|
28574
|
-
"folderMenu": `FolderSidebar-module__folderMenu__JCzLF`,
|
|
28575
|
-
"uploadButton": `FolderSidebar-module__uploadButton__QQUid`,
|
|
28576
|
-
"folderItemContainer": `FolderSidebar-module__folderItemContainer__byl5b`,
|
|
28577
|
-
"emptyFolderContainer": `FolderSidebar-module__emptyFolderContainer__WK6tx`,
|
|
28578
|
-
"folderIcon": `FolderSidebar-module__folderIcon__UoZzH`,
|
|
28579
|
-
"folderLabelItem": `FolderSidebar-module__folderLabelItem__uJ062`,
|
|
28580
|
-
"foldersTitleItem": `FolderSidebar-module__foldersTitleItem__gapOI`,
|
|
28581
|
-
"folderLabel": `FolderSidebar-module__folderLabel__fHWMp`,
|
|
28582
|
-
"foldersContainer": `FolderSidebar-module__foldersContainer__zdBVU`,
|
|
28583
|
-
"buttonWrapper": `FolderSidebar-module__buttonWrapper__a9Qi5`,
|
|
28584
|
-
"uploadButtonIcon": `FolderSidebar-module__uploadButtonIcon__mWQmq`,
|
|
28585
|
-
"uploadButtonTitle": `FolderSidebar-module__uploadButtonTitle__wk_o6`
|
|
28586
|
-
};
|
|
28587
|
-
module.exports = ___CSS_LOADER_EXPORT___;
|
|
28588
28463
|
|
|
28589
28464
|
|
|
28590
|
-
/***/ }),
|
|
28591
28465
|
|
|
28592
|
-
/***/ 9557:
|
|
28593
|
-
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
|
28594
28466
|
|
|
28595
|
-
"use strict";
|
|
28596
28467
|
|
|
28597
|
-
// EXPORTS
|
|
28598
|
-
__webpack_require__.d(__webpack_exports__, {
|
|
28599
|
-
fp: () => (/* reexport */ useFileSelectionStore),
|
|
28600
|
-
vD: () => (/* reexport */ useFilesAPI),
|
|
28601
|
-
l_: () => (/* reexport */ useFilesModals),
|
|
28602
|
-
nC: () => (/* reexport */ useFilesSelection)
|
|
28603
|
-
});
|
|
28604
28468
|
|
|
28605
|
-
// UNUSED EXPORTS: addSubfoldersToFiles
|
|
28606
28469
|
|
|
28607
|
-
|
|
28608
|
-
|
|
28609
|
-
|
|
28610
|
-
|
|
28611
|
-
|
|
28612
|
-
|
|
28613
|
-
|
|
28614
|
-
|
|
28615
|
-
|
|
28616
|
-
|
|
28617
|
-
|
|
28618
|
-
|
|
28619
|
-
|
|
28620
|
-
|
|
28621
|
-
|
|
28622
|
-
|
|
28623
|
-
|
|
28624
|
-
|
|
28625
|
-
|
|
28626
|
-
|
|
28627
|
-
|
|
28628
|
-
|
|
28629
|
-
|
|
28630
|
-
|
|
28631
|
-
|
|
28632
|
-
|
|
28633
|
-
|
|
28634
|
-
|
|
28635
|
-
else {
|
|
28636
|
-
return files;
|
|
28470
|
+
|
|
28471
|
+
|
|
28472
|
+
|
|
28473
|
+
|
|
28474
|
+
|
|
28475
|
+
|
|
28476
|
+
|
|
28477
|
+
|
|
28478
|
+
|
|
28479
|
+
|
|
28480
|
+
|
|
28481
|
+
|
|
28482
|
+
|
|
28483
|
+
|
|
28484
|
+
const UPLOAD_IMAGE_PREPARE_CONCURRENCY = 4;
|
|
28485
|
+
/**
|
|
28486
|
+
* Проверяет, нужно ли сжимать изображение
|
|
28487
|
+
*/
|
|
28488
|
+
function shouldCompressImage(fileType) {
|
|
28489
|
+
return !!(fileType === null || fileType === void 0 ? void 0 : fileType.startsWith('image/')) && fileType !== 'image/gif';
|
|
28490
|
+
}
|
|
28491
|
+
/**
|
|
28492
|
+
* Создаёт новый File объект с нормализованным именем
|
|
28493
|
+
* Если имя не изменилось, возвращает оригинальный файл
|
|
28494
|
+
*/
|
|
28495
|
+
function createNormalizedFile(file, normalizedName) {
|
|
28496
|
+
if (normalizedName === file.name) {
|
|
28497
|
+
return file;
|
|
28637
28498
|
}
|
|
28638
|
-
|
|
28639
|
-
|
|
28640
|
-
|
|
28641
|
-
|
|
28499
|
+
try {
|
|
28500
|
+
return new File([file], normalizedName, {
|
|
28501
|
+
type: file.type,
|
|
28502
|
+
lastModified: file.lastModified,
|
|
28503
|
+
});
|
|
28642
28504
|
}
|
|
28643
|
-
|
|
28644
|
-
|
|
28645
|
-
|
|
28646
|
-
const folderItems = subfolders.map((folder) => ({
|
|
28647
|
-
id: folder.id,
|
|
28648
|
-
name: folder.name,
|
|
28649
|
-
size: undefined,
|
|
28650
|
-
date: '-',
|
|
28651
|
-
isFolder: true,
|
|
28652
|
-
folderId: folder.parentId || '',
|
|
28653
|
-
type: '',
|
|
28654
|
-
selected: false,
|
|
28655
|
-
extension: '',
|
|
28656
|
-
childCount: folder.childCount,
|
|
28657
|
-
}));
|
|
28658
|
-
if ((params === null || params === void 0 ? void 0 : params.itemType) === 'folder') {
|
|
28659
|
-
return folderItems;
|
|
28660
|
-
}
|
|
28661
|
-
// getFiles(itemType:'all') может возвращать папки — исключаем их, т.к. folderItems уже содержит папки из getFolders
|
|
28662
|
-
const filesOnly = files.filter(f => !f.isFolder);
|
|
28663
|
-
const result = [...folderItems, ...filesOnly];
|
|
28664
|
-
return result;
|
|
28665
|
-
};
|
|
28666
|
-
|
|
28667
|
-
// EXTERNAL MODULE: ./src/hooks/core/useSortAndFilter.ts
|
|
28668
|
-
var useSortAndFilter = __webpack_require__(7228);
|
|
28669
|
-
// EXTERNAL MODULE: ./src/hooks/core/useFolders.ts
|
|
28670
|
-
var useFolders = __webpack_require__(5018);
|
|
28671
|
-
// EXTERNAL MODULE: ./src/hooks/useNotifications.tsx
|
|
28672
|
-
var useNotifications = __webpack_require__(3435);
|
|
28673
|
-
// EXTERNAL MODULE: ./src/hooks/core/files/actions/useFilesDelete.ts
|
|
28674
|
-
var useFilesDelete = __webpack_require__(1591);
|
|
28675
|
-
// EXTERNAL MODULE: ./src/utils/errorMessages.ts
|
|
28676
|
-
var errorMessages = __webpack_require__(6377);
|
|
28677
|
-
// EXTERNAL MODULE: ./src/utils/fileValidation.ts
|
|
28678
|
-
var fileValidation = __webpack_require__(9142);
|
|
28679
|
-
// EXTERNAL MODULE: ./src/utils/urlValidation.ts
|
|
28680
|
-
var urlValidation = __webpack_require__(69);
|
|
28681
|
-
// EXTERNAL MODULE: ./src/utils/imageCompression.ts
|
|
28682
|
-
var imageCompression = __webpack_require__(3270);
|
|
28683
|
-
// EXTERNAL MODULE: ./src/utils/cacheClear.ts
|
|
28684
|
-
var cacheClear = __webpack_require__(2332);
|
|
28685
|
-
// EXTERNAL MODULE: ./src/utils/resolveItemMeta.ts
|
|
28686
|
-
var resolveItemMeta = __webpack_require__(1069);
|
|
28687
|
-
// EXTERNAL MODULE: ./src/utils/nameNormalization.ts
|
|
28688
|
-
var nameNormalization = __webpack_require__(7407);
|
|
28689
|
-
// EXTERNAL MODULE: ./src/utils/mimeUtils.ts
|
|
28690
|
-
var mimeUtils = __webpack_require__(3662);
|
|
28691
|
-
;// ./src/utils/urlNormalization.ts
|
|
28692
|
-
const TRACKING_QUERY_PARAM_PATTERN = /^(utm_[a-z0-9_]+|fbclid|gclid|igshid|mc_cid|mc_eid)$/i;
|
|
28693
|
-
/**
|
|
28694
|
-
* Нормализует внешний URL для детерминированного поиска файла по источнику.
|
|
28695
|
-
* Убирает hash, трекинговые query-параметры, нормализует host и сортирует query.
|
|
28696
|
-
*/
|
|
28697
|
-
function normalizeExternalFileUrl(url) {
|
|
28698
|
-
const parsed = new URL(url.trim());
|
|
28699
|
-
parsed.hash = '';
|
|
28700
|
-
parsed.hostname = parsed.hostname.toLowerCase();
|
|
28701
|
-
if ((parsed.protocol === 'https:' && parsed.port === '443') ||
|
|
28702
|
-
(parsed.protocol === 'http:' && parsed.port === '80')) {
|
|
28703
|
-
parsed.port = '';
|
|
28704
|
-
}
|
|
28705
|
-
const normalizedParams = Array.from(parsed.searchParams.entries())
|
|
28706
|
-
.filter(([key]) => !TRACKING_QUERY_PARAM_PATTERN.test(key))
|
|
28707
|
-
.sort(([keyA, valueA], [keyB, valueB]) => {
|
|
28708
|
-
const keyCompare = keyA.localeCompare(keyB);
|
|
28709
|
-
return keyCompare !== 0 ? keyCompare : valueA.localeCompare(valueB);
|
|
28710
|
-
});
|
|
28711
|
-
parsed.search = '';
|
|
28712
|
-
normalizedParams.forEach(([key, value]) => parsed.searchParams.append(key, value));
|
|
28713
|
-
return parsed.toString();
|
|
28714
|
-
}
|
|
28715
|
-
/**
|
|
28716
|
-
* Совпадает ли origin URL с текущей страницей (protocol + host + port).
|
|
28717
|
-
* Для same-origin прокси не используем — загрузка напрямую.
|
|
28718
|
-
*/
|
|
28719
|
-
function isUrlSameOriginAsCurrentPage(url) {
|
|
28720
|
-
if (typeof window === 'undefined')
|
|
28721
|
-
return false;
|
|
28722
|
-
try {
|
|
28723
|
-
return new URL(url).origin === window.location.origin;
|
|
28724
|
-
}
|
|
28725
|
-
catch (_a) {
|
|
28726
|
-
return false;
|
|
28727
|
-
}
|
|
28728
|
-
}
|
|
28729
|
-
|
|
28730
|
-
// EXTERNAL MODULE: ./src/utils/remoteFileFetchPipeline.ts + 1 modules
|
|
28731
|
-
var remoteFileFetchPipeline = __webpack_require__(5597);
|
|
28732
|
-
// EXTERNAL MODULE: ./src/utils/dedupeUploadNamesOnClient.ts
|
|
28733
|
-
var dedupeUploadNamesOnClient = __webpack_require__(3795);
|
|
28734
|
-
// EXTERNAL MODULE: ./src/utils/resolveUniqueUploadName.ts
|
|
28735
|
-
var utils_resolveUniqueUploadName = __webpack_require__(7742);
|
|
28736
|
-
// EXTERNAL MODULE: ./src/utils/fileFormatUtils.ts
|
|
28737
|
-
var fileFormatUtils = __webpack_require__(6825);
|
|
28738
|
-
// EXTERNAL MODULE: ./src/hooks/core/context.tsx
|
|
28739
|
-
var context = __webpack_require__(8361);
|
|
28740
|
-
// EXTERNAL MODULE: ./src/constants/index.tsx
|
|
28741
|
-
var constants = __webpack_require__(133);
|
|
28742
|
-
// EXTERNAL MODULE: ./src/shared/fileManagerApiError.ts
|
|
28743
|
-
var fileManagerApiError = __webpack_require__(7036);
|
|
28744
|
-
;// ./src/hooks/core/files/useFilesAPI.ts
|
|
28745
|
-
|
|
28746
|
-
|
|
28747
|
-
|
|
28748
|
-
|
|
28749
|
-
|
|
28750
|
-
|
|
28751
|
-
|
|
28752
|
-
|
|
28753
|
-
|
|
28754
|
-
|
|
28755
|
-
|
|
28756
|
-
|
|
28757
|
-
|
|
28758
|
-
|
|
28759
|
-
|
|
28760
|
-
|
|
28761
|
-
|
|
28762
|
-
|
|
28763
|
-
|
|
28764
|
-
|
|
28765
|
-
|
|
28766
|
-
|
|
28767
|
-
|
|
28768
|
-
|
|
28769
|
-
/**
|
|
28770
|
-
* Проверяет, нужно ли сжимать изображение
|
|
28771
|
-
*/
|
|
28772
|
-
function shouldCompressImage(fileType) {
|
|
28773
|
-
return !!(fileType === null || fileType === void 0 ? void 0 : fileType.startsWith('image/')) && fileType !== 'image/gif';
|
|
28774
|
-
}
|
|
28775
|
-
/**
|
|
28776
|
-
* Создаёт новый File объект с нормализованным именем
|
|
28777
|
-
* Если имя не изменилось, возвращает оригинальный файл
|
|
28778
|
-
*/
|
|
28779
|
-
function createNormalizedFile(file, normalizedName) {
|
|
28780
|
-
if (normalizedName === file.name) {
|
|
28781
|
-
return file;
|
|
28782
|
-
}
|
|
28783
|
-
try {
|
|
28784
|
-
return new File([file], normalizedName, {
|
|
28785
|
-
type: file.type,
|
|
28786
|
-
lastModified: file.lastModified,
|
|
28787
|
-
});
|
|
28788
|
-
}
|
|
28789
|
-
catch (e) {
|
|
28790
|
-
console.warn('Failed to create normalized File:', e);
|
|
28791
|
-
return file; // fallback на оригинал
|
|
28505
|
+
catch (e) {
|
|
28506
|
+
console.warn('Failed to create normalized File:', e);
|
|
28507
|
+
return file; // fallback на оригинал
|
|
28792
28508
|
}
|
|
28793
28509
|
}
|
|
28794
28510
|
function blobToDataUrl(blob) {
|
|
@@ -29674,7 +29390,7 @@ const useFilesAPI = () => {
|
|
|
29674
29390
|
}
|
|
29675
29391
|
}, [resolveTargetFolderId]);
|
|
29676
29392
|
const uploadFilesBatch = (0,external_root_React_commonjs2_react_commonjs_react_amd_react_.useCallback)(async (filesToUpload, progressCallbacks) => {
|
|
29677
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0
|
|
29393
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0;
|
|
29678
29394
|
if (filesToUpload.length === 0) {
|
|
29679
29395
|
return { successCount: 0, failCount: 0, successes: [], errors: [], totalCount: 0 };
|
|
29680
29396
|
}
|
|
@@ -29684,9 +29400,8 @@ const useFilesAPI = () => {
|
|
|
29684
29400
|
const filtered = names.filter(Boolean);
|
|
29685
29401
|
return filtered.length > 0 && filtered.length <= MAX_NAMES_PREVIEW ? filtered.join(', ') : null;
|
|
29686
29402
|
};
|
|
29687
|
-
const
|
|
29688
|
-
|
|
29689
|
-
const file = filesToUpload[index];
|
|
29403
|
+
const preparedResults = await mapWithConcurrency(filesToUpload, UPLOAD_IMAGE_PREPARE_CONCURRENCY, async (file, index) => {
|
|
29404
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
|
|
29690
29405
|
if (!(0,mimeUtils/* isAllowedImageUploadFile */.rc)(file)) {
|
|
29691
29406
|
const payload = await notification.warning({
|
|
29692
29407
|
id: 'FILES_UPLOAD_UNSUPPORTED_TYPE',
|
|
@@ -29698,8 +29413,8 @@ const useFilesAPI = () => {
|
|
|
29698
29413
|
folderId: selectedFolder || null,
|
|
29699
29414
|
},
|
|
29700
29415
|
});
|
|
29701
|
-
(
|
|
29702
|
-
|
|
29416
|
+
(_a = progressCallbacks === null || progressCallbacks === void 0 ? void 0 : progressCallbacks.onError) === null || _a === void 0 ? void 0 : _a.call(progressCallbacks, file.name, payload.message);
|
|
29417
|
+
return null;
|
|
29703
29418
|
}
|
|
29704
29419
|
// Нормализуем имя файла заранее для подготовки изображения и fallback
|
|
29705
29420
|
const normalizedFileName = (0,nameNormalization/* normalizeFileName */.Px)(file.name, options === null || options === void 0 ? void 0 : options.config);
|
|
@@ -29707,24 +29422,19 @@ const useFilesAPI = () => {
|
|
|
29707
29422
|
// eslint-disable-next-line sonarjs/no-dead-store
|
|
29708
29423
|
let fileToUpload = file;
|
|
29709
29424
|
try {
|
|
29710
|
-
|
|
29711
|
-
|
|
29712
|
-
|
|
29713
|
-
|
|
29714
|
-
|
|
29715
|
-
|
|
29716
|
-
|
|
29717
|
-
|
|
29718
|
-
|
|
29719
|
-
|
|
29720
|
-
|
|
29721
|
-
|
|
29722
|
-
|
|
29723
|
-
});
|
|
29724
|
-
}
|
|
29725
|
-
else {
|
|
29726
|
-
fileToUpload = createNormalizedFile(file, normalizedFileName);
|
|
29727
|
-
}
|
|
29425
|
+
const maxSizeMB = (_c = (_b = options === null || options === void 0 ? void 0 : options.config) === null || _b === void 0 ? void 0 : _b.compressMaxSize) !== null && _c !== void 0 ? _c : fileFormatUtils/* IMAGE_COMPRESSION_DEFAULTS */.a9.MAX_SIZE_MB;
|
|
29426
|
+
const maxWidthOrHeight = (_e = (_d = options === null || options === void 0 ? void 0 : options.config) === null || _d === void 0 ? void 0 : _d.compressMaxWidthOrHeight) !== null && _e !== void 0 ? _e : 2000;
|
|
29427
|
+
const compressorUrl = (_g = (_f = options === null || options === void 0 ? void 0 : options.config) === null || _f === void 0 ? void 0 : _f.compessorUrl) !== null && _g !== void 0 ? _g : (_h = options === null || options === void 0 ? void 0 : options.config) === null || _h === void 0 ? void 0 : _h.compressorUrl;
|
|
29428
|
+
const effectiveMime = ((_j = file.type) === null || _j === void 0 ? void 0 : _j.trim()) || (0,mimeUtils/* inferImageMimeFromFileName */.xU)(file.name) || file.type;
|
|
29429
|
+
fileToUpload = await (0,imageCompression/* prepareImageForUpload */.j)(file, {
|
|
29430
|
+
maxSizeMB,
|
|
29431
|
+
maxWidthOrHeight,
|
|
29432
|
+
mimeType: effectiveMime,
|
|
29433
|
+
fileName: normalizedFileName,
|
|
29434
|
+
libURL: compressorUrl,
|
|
29435
|
+
enableCompression: shouldCompressImage(effectiveMime),
|
|
29436
|
+
convertSvgToPng: true,
|
|
29437
|
+
});
|
|
29728
29438
|
}
|
|
29729
29439
|
catch (e) {
|
|
29730
29440
|
console.warn('Image preparation failed, uploading original file', e);
|
|
@@ -29735,15 +29445,16 @@ const useFilesAPI = () => {
|
|
|
29735
29445
|
// тогда результат будет сопоставлен по индексу массива.
|
|
29736
29446
|
const requestId = `${Date.now()}-${index}-${Math.random().toString(36).slice(2, 8)}`;
|
|
29737
29447
|
const targetFolderId = await resolveTargetFolderId(fileToUpload, selectedFolder);
|
|
29738
|
-
(
|
|
29739
|
-
|
|
29448
|
+
(_k = progressCallbacks === null || progressCallbacks === void 0 ? void 0 : progressCallbacks.onStart) === null || _k === void 0 ? void 0 : _k.call(progressCallbacks, fileToUpload);
|
|
29449
|
+
return {
|
|
29740
29450
|
file: fileToUpload,
|
|
29741
29451
|
targetFolderId,
|
|
29742
29452
|
requestId,
|
|
29743
29453
|
originalFileName: file.name,
|
|
29744
29454
|
originalIndex: index,
|
|
29745
|
-
}
|
|
29746
|
-
}
|
|
29455
|
+
};
|
|
29456
|
+
});
|
|
29457
|
+
const preparedItems = preparedResults.filter((item) => item !== null);
|
|
29747
29458
|
const totalCount = preparedItems.length;
|
|
29748
29459
|
if (totalCount === 0) {
|
|
29749
29460
|
return { successCount: 0, failCount: 0, successes: [], errors: [], totalCount: 0 };
|
|
@@ -29825,7 +29536,7 @@ const useFilesAPI = () => {
|
|
|
29825
29536
|
},
|
|
29826
29537
|
}, silent || !shouldEmitAnyNotifications);
|
|
29827
29538
|
};
|
|
29828
|
-
const maxFileSize = (
|
|
29539
|
+
const maxFileSize = (_c = (_b = options === null || options === void 0 ? void 0 : options.config) === null || _b === void 0 ? void 0 : _b.maxFileSize) !== null && _c !== void 0 ? _c : fileValidation/* MAX_FILE_SIZE */.w3;
|
|
29829
29540
|
const emitErrorNotification = (fileName, folderId, innerException, silent, context) => {
|
|
29830
29541
|
var _a, _b, _c, _d, _e, _f, _g;
|
|
29831
29542
|
const apiError = (0,errorMessages/* asFileManagerApiError */.sj)(innerException);
|
|
@@ -29929,17 +29640,17 @@ const useFilesAPI = () => {
|
|
|
29929
29640
|
});
|
|
29930
29641
|
progressIntervals.forEach(id => window.clearInterval(id));
|
|
29931
29642
|
progressIntervals.length = 0;
|
|
29932
|
-
const detailedList = (
|
|
29643
|
+
const detailedList = (_d = batchResult.detailed) !== null && _d !== void 0 ? _d : [];
|
|
29933
29644
|
const detailedMap = new Map(detailedList.filter(detail => detail.requestId).map(detail => [detail.requestId, detail]));
|
|
29934
29645
|
if (detailedList.length > 0) {
|
|
29935
29646
|
for (let index = 0; index < uploadItems.length; index++) {
|
|
29936
29647
|
const item = uploadItems[index];
|
|
29937
29648
|
// Пытаемся сопоставить по requestId, а при его отсутствии — по порядку.
|
|
29938
|
-
const detail = (
|
|
29649
|
+
const detail = (_e = (item.requestId ? detailedMap.get(item.requestId) : undefined)) !== null && _e !== void 0 ? _e : detailedList[index];
|
|
29939
29650
|
if (detail && detail.success) {
|
|
29940
29651
|
const data = detail.data;
|
|
29941
|
-
const normalizedFileName = (
|
|
29942
|
-
const folderId = (
|
|
29652
|
+
const normalizedFileName = (_f = data === null || data === void 0 ? void 0 : data.name) !== null && _f !== void 0 ? _f : item.resolvedUploadName;
|
|
29653
|
+
const folderId = (_j = (_h = (_g = data === null || data === void 0 ? void 0 : data.folderId) !== null && _g !== void 0 ? _g : item.targetFolderId) !== null && _h !== void 0 ? _h : selectedFolder) !== null && _j !== void 0 ? _j : null;
|
|
29943
29654
|
const fileId = data === null || data === void 0 ? void 0 : data.id;
|
|
29944
29655
|
// Сохраняем информацию о загруженном файле (включая size для корректного отображения в попапе)
|
|
29945
29656
|
uploadedFilesMap.set(normalizedFileName, {
|
|
@@ -29956,9 +29667,9 @@ const useFilesAPI = () => {
|
|
|
29956
29667
|
}
|
|
29957
29668
|
else {
|
|
29958
29669
|
const data = detail === null || detail === void 0 ? void 0 : detail.data;
|
|
29959
|
-
const normalizedFileName = (
|
|
29960
|
-
const folderId = (
|
|
29961
|
-
await handleFailure(normalizedFileName, folderId, (
|
|
29670
|
+
const normalizedFileName = (_k = data === null || data === void 0 ? void 0 : data.name) !== null && _k !== void 0 ? _k : item.resolvedUploadName;
|
|
29671
|
+
const folderId = (_o = (_m = (_l = data === null || data === void 0 ? void 0 : data.folderId) !== null && _l !== void 0 ? _l : item.targetFolderId) !== null && _m !== void 0 ? _m : selectedFolder) !== null && _o !== void 0 ? _o : null;
|
|
29672
|
+
await handleFailure(normalizedFileName, folderId, (_p = detail === null || detail === void 0 ? void 0 : detail.error) !== null && _p !== void 0 ? _p : new Error(t('Error uploading file')), {
|
|
29962
29673
|
emitNotification: shouldEmitPerItemNotifications,
|
|
29963
29674
|
fileSize: item.file.size,
|
|
29964
29675
|
progressCallbackName: item.originalFileName,
|
|
@@ -29970,17 +29681,17 @@ const useFilesAPI = () => {
|
|
|
29970
29681
|
else if (batchResult.success) {
|
|
29971
29682
|
for (const item of uploadItems) {
|
|
29972
29683
|
const normalizedFileName = item.resolvedUploadName;
|
|
29973
|
-
const folderId = (
|
|
29684
|
+
const folderId = (_r = (_q = item.targetFolderId) !== null && _q !== void 0 ? _q : selectedFolder) !== null && _r !== void 0 ? _r : null;
|
|
29974
29685
|
await handleSuccess(normalizedFileName, folderId, undefined, {
|
|
29975
29686
|
emitNotification: shouldEmitPerItemNotifications,
|
|
29976
29687
|
});
|
|
29977
29688
|
}
|
|
29978
29689
|
}
|
|
29979
29690
|
else {
|
|
29980
|
-
const batchError = (
|
|
29691
|
+
const batchError = (_s = batchResult.error) !== null && _s !== void 0 ? _s : new Error(t('Error uploading file'));
|
|
29981
29692
|
for (const item of uploadItems) {
|
|
29982
29693
|
const normalizedFileName = item.resolvedUploadName;
|
|
29983
|
-
const folderId = (
|
|
29694
|
+
const folderId = (_u = (_t = item.targetFolderId) !== null && _t !== void 0 ? _t : selectedFolder) !== null && _u !== void 0 ? _u : null;
|
|
29984
29695
|
await handleFailure(normalizedFileName, folderId, batchError, {
|
|
29985
29696
|
emitNotification: shouldEmitPerItemNotifications,
|
|
29986
29697
|
fileSize: item.file.size,
|
|
@@ -29993,7 +29704,7 @@ const useFilesAPI = () => {
|
|
|
29993
29704
|
catch (error) {
|
|
29994
29705
|
for (const item of uploadItems) {
|
|
29995
29706
|
const normalizedFileName = item.resolvedUploadName;
|
|
29996
|
-
const folderId = (
|
|
29707
|
+
const folderId = (_w = (_v = item.targetFolderId) !== null && _v !== void 0 ? _v : selectedFolder) !== null && _w !== void 0 ? _w : null;
|
|
29997
29708
|
await handleFailure(normalizedFileName, folderId, error !== null && error !== void 0 ? error : new Error(t('Error uploading file')), {
|
|
29998
29709
|
emitNotification: shouldEmitPerItemNotifications,
|
|
29999
29710
|
fileSize: item.file.size,
|
|
@@ -30061,10 +29772,10 @@ const useFilesAPI = () => {
|
|
|
30061
29772
|
},
|
|
30062
29773
|
});
|
|
30063
29774
|
}
|
|
30064
|
-
else if (totalCount === 1 && errorDetails.length > 0 && ((
|
|
29775
|
+
else if (totalCount === 1 && errorDetails.length > 0 && ((_x = errorDetails[0].error) === null || _x === void 0 ? void 0 : _x.code)) {
|
|
30065
29776
|
// Для одного файла используем конкретное сообщение об ошибке
|
|
30066
|
-
const codeMessage = (0,errorMessages/* getErrorMessageFromCode */.j2)((
|
|
30067
|
-
const failedFileName = (
|
|
29777
|
+
const codeMessage = (0,errorMessages/* getErrorMessageFromCode */.j2)((_y = errorDetails[0].error) === null || _y === void 0 ? void 0 : _y.code, t);
|
|
29778
|
+
const failedFileName = (_0 = (_z = errors[0]) === null || _z === void 0 ? void 0 : _z.fileName) !== null && _0 !== void 0 ? _0 : '';
|
|
30068
29779
|
const failureMessage = codeMessage !== null && codeMessage !== void 0 ? codeMessage : (failedFileName ? `${t('Failed to upload files')}: ${failedFileName}` : t('Failed to upload files'));
|
|
30069
29780
|
notification.error({
|
|
30070
29781
|
id: 'FILES_UPLOAD_BATCH_FAILED',
|
|
@@ -32020,6 +31731,313 @@ const useFilesModals = (fetchFiles) => {
|
|
|
32020
31731
|
|
|
32021
31732
|
|
|
32022
31733
|
|
|
31734
|
+
/***/ }),
|
|
31735
|
+
|
|
31736
|
+
/***/ 9142:
|
|
31737
|
+
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
|
31738
|
+
|
|
31739
|
+
"use strict";
|
|
31740
|
+
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
31741
|
+
/* harmony export */ $5: () => (/* binding */ getUniqueFileName),
|
|
31742
|
+
/* harmony export */ mF: () => (/* binding */ encodeUrlForImageSrc),
|
|
31743
|
+
/* harmony export */ nF: () => (/* binding */ formatFileSizeDisplay),
|
|
31744
|
+
/* harmony export */ v7: () => (/* binding */ formatFileSize),
|
|
31745
|
+
/* harmony export */ w3: () => (/* binding */ MAX_FILE_SIZE)
|
|
31746
|
+
/* harmony export */ });
|
|
31747
|
+
/* unused harmony exports MIN_FILE_SIZE, ALLOWED_FILE_TYPES, ALL_ALLOWED_TYPES, validateFile, validateFiles, validateFileUrl, getFileCategory, formatFileSizeShort, sanitizeFileName */
|
|
31748
|
+
/* harmony import */ var antd__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(550);
|
|
31749
|
+
/* harmony import */ var antd__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(antd__WEBPACK_IMPORTED_MODULE_0__);
|
|
31750
|
+
/* harmony import */ var _i18n__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(3829);
|
|
31751
|
+
|
|
31752
|
+
|
|
31753
|
+
const MAX_FILE_SIZE = 50 * 1024 * 1024;
|
|
31754
|
+
const MIN_FILE_SIZE = 1;
|
|
31755
|
+
const ALLOWED_FILE_TYPES = {
|
|
31756
|
+
images: ['image/jpeg', 'image/png', 'image/gif', 'image/webp', 'image/svg+xml', 'image/bmp', 'image/tiff'],
|
|
31757
|
+
documents: [
|
|
31758
|
+
'application/pdf',
|
|
31759
|
+
'text/plain',
|
|
31760
|
+
'application/msword',
|
|
31761
|
+
'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
|
|
31762
|
+
],
|
|
31763
|
+
archives: ['application/zip', 'application/x-rar-compressed', 'application/x-7z-compressed'],
|
|
31764
|
+
videos: ['video/mp4', 'video/avi', 'video/quicktime', 'video/x-msvideo'],
|
|
31765
|
+
audio: ['audio/mpeg', 'audio/wav', 'audio/ogg'],
|
|
31766
|
+
};
|
|
31767
|
+
const ALL_ALLOWED_TYPES = Object.values(ALLOWED_FILE_TYPES).flat();
|
|
31768
|
+
const validateFile = (file, options = {}) => {
|
|
31769
|
+
const { maxSize = MAX_FILE_SIZE, minSize = MIN_FILE_SIZE, allowedTypes = ALL_ALLOWED_TYPES, allowAllTypes = false, maxFileNameLength = 255, } = options;
|
|
31770
|
+
const errors = [];
|
|
31771
|
+
const warnings = [];
|
|
31772
|
+
if (file.size > maxSize) {
|
|
31773
|
+
errors.push(i18n.t('File too large. Maximum size: {{size}}', { size: formatFileSize(maxSize) }));
|
|
31774
|
+
}
|
|
31775
|
+
if (file.size < minSize) {
|
|
31776
|
+
errors.push(i18n.t('File too small. Minimum size: {{size}}', { size: formatFileSize(minSize) }));
|
|
31777
|
+
}
|
|
31778
|
+
if (!allowAllTypes && !allowedTypes.includes(file.type)) {
|
|
31779
|
+
errors.push(i18n.t('Unsupported file type: {{type}}', { type: file.type || i18n.t('unknown') }));
|
|
31780
|
+
}
|
|
31781
|
+
if (file.name.length > maxFileNameLength) {
|
|
31782
|
+
errors.push(i18n.t('File name is too long. Maximum {{max}} characters', { max: maxFileNameLength }));
|
|
31783
|
+
}
|
|
31784
|
+
const invalidChars = /[<>:"/\\|?*()#]/;
|
|
31785
|
+
const hasControlChars = file.name.split('').some(char => {
|
|
31786
|
+
const code = char.charCodeAt(0);
|
|
31787
|
+
return code >= 0 && code <= 31;
|
|
31788
|
+
});
|
|
31789
|
+
if (invalidChars.test(file.name) || hasControlChars) {
|
|
31790
|
+
errors.push(i18n.t('File name contains invalid characters'));
|
|
31791
|
+
}
|
|
31792
|
+
if (file.size > 10 * 1024 * 1024) {
|
|
31793
|
+
warnings.push(i18n.t('Large file may take a long time to upload'));
|
|
31794
|
+
}
|
|
31795
|
+
return {
|
|
31796
|
+
isValid: errors.length === 0,
|
|
31797
|
+
errors,
|
|
31798
|
+
warnings,
|
|
31799
|
+
};
|
|
31800
|
+
};
|
|
31801
|
+
const validateFiles = (files, options = {}) => {
|
|
31802
|
+
const valid = [];
|
|
31803
|
+
const invalid = [];
|
|
31804
|
+
files.forEach(file => {
|
|
31805
|
+
const result = validateFile(file, options);
|
|
31806
|
+
if (result.isValid) {
|
|
31807
|
+
valid.push(file);
|
|
31808
|
+
}
|
|
31809
|
+
else {
|
|
31810
|
+
invalid.push({ file, result });
|
|
31811
|
+
}
|
|
31812
|
+
});
|
|
31813
|
+
return { valid, invalid };
|
|
31814
|
+
};
|
|
31815
|
+
const validateFileUrl = async (url) => {
|
|
31816
|
+
const errors = [];
|
|
31817
|
+
let notified = false;
|
|
31818
|
+
let lastError = undefined;
|
|
31819
|
+
const notifyError = (message) => {
|
|
31820
|
+
notified = true;
|
|
31821
|
+
notification.error({
|
|
31822
|
+
key: 'FILE_URL_VALIDATION_FAILED',
|
|
31823
|
+
title: message,
|
|
31824
|
+
placement: 'bottomRight',
|
|
31825
|
+
description: url,
|
|
31826
|
+
});
|
|
31827
|
+
};
|
|
31828
|
+
try {
|
|
31829
|
+
new URL(url);
|
|
31830
|
+
}
|
|
31831
|
+
catch (error) {
|
|
31832
|
+
console.error('Invalid URL:', error);
|
|
31833
|
+
lastError = error;
|
|
31834
|
+
const message = i18n.t('Invalid file URL');
|
|
31835
|
+
errors.push(message);
|
|
31836
|
+
notifyError(message);
|
|
31837
|
+
return { isValid: false, errors };
|
|
31838
|
+
}
|
|
31839
|
+
try {
|
|
31840
|
+
const response = await fetch(url, { method: 'HEAD' });
|
|
31841
|
+
if (!response.ok) {
|
|
31842
|
+
errors.push(i18n.t('File unavailable: {{status}} {{statusText}}', {
|
|
31843
|
+
status: response.status,
|
|
31844
|
+
statusText: response.statusText,
|
|
31845
|
+
}));
|
|
31846
|
+
}
|
|
31847
|
+
const contentLength = response.headers.get('content-length');
|
|
31848
|
+
if (contentLength && parseInt(contentLength) > MAX_FILE_SIZE) {
|
|
31849
|
+
errors.push(i18n.t('File too large: {{size}}', { size: formatFileSize(parseInt(contentLength)) }));
|
|
31850
|
+
}
|
|
31851
|
+
const contentType = response.headers.get('content-type');
|
|
31852
|
+
if (contentType && !ALL_ALLOWED_TYPES.includes(contentType)) {
|
|
31853
|
+
errors.push(i18n.t('Unsupported file type: {{contentType}}', { contentType }));
|
|
31854
|
+
}
|
|
31855
|
+
}
|
|
31856
|
+
catch (error) {
|
|
31857
|
+
console.error('Failed to validate file URL:', error);
|
|
31858
|
+
lastError = error;
|
|
31859
|
+
const message = i18n.t('Unable to validate file URL');
|
|
31860
|
+
errors.push(message);
|
|
31861
|
+
notifyError(message);
|
|
31862
|
+
}
|
|
31863
|
+
if (errors.length > 0 && !notified) {
|
|
31864
|
+
notifyError(i18n.t('Unable to validate file URL'));
|
|
31865
|
+
}
|
|
31866
|
+
return {
|
|
31867
|
+
isValid: errors.length === 0,
|
|
31868
|
+
errors,
|
|
31869
|
+
};
|
|
31870
|
+
};
|
|
31871
|
+
const getFileCategory = (file) => {
|
|
31872
|
+
const type = file.type;
|
|
31873
|
+
if (ALLOWED_FILE_TYPES.images.includes(type))
|
|
31874
|
+
return 'image';
|
|
31875
|
+
if (ALLOWED_FILE_TYPES.documents.includes(type))
|
|
31876
|
+
return 'document';
|
|
31877
|
+
if (ALLOWED_FILE_TYPES.archives.includes(type))
|
|
31878
|
+
return 'archive';
|
|
31879
|
+
if (ALLOWED_FILE_TYPES.videos.includes(type))
|
|
31880
|
+
return 'video';
|
|
31881
|
+
if (ALLOWED_FILE_TYPES.audio.includes(type))
|
|
31882
|
+
return 'audio';
|
|
31883
|
+
return 'other';
|
|
31884
|
+
};
|
|
31885
|
+
const formatFileSize = (bytes) => {
|
|
31886
|
+
if (bytes === 0)
|
|
31887
|
+
return '0 Bytes';
|
|
31888
|
+
const k = 1024;
|
|
31889
|
+
const sizes = ['Bytes', 'KB', 'MB', 'GB'];
|
|
31890
|
+
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
|
31891
|
+
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
|
|
31892
|
+
};
|
|
31893
|
+
const formatFileSizeShort = (bytes) => {
|
|
31894
|
+
if (!bytes || bytes <= 0)
|
|
31895
|
+
return '';
|
|
31896
|
+
const KILOBYTE = 1024;
|
|
31897
|
+
const MEGABYTE = KILOBYTE * 1024;
|
|
31898
|
+
if (bytes < MEGABYTE) {
|
|
31899
|
+
const kb = Math.round(bytes / KILOBYTE);
|
|
31900
|
+
return `${kb} Kb`;
|
|
31901
|
+
}
|
|
31902
|
+
const mb = bytes / MEGABYTE;
|
|
31903
|
+
return `${mb.toFixed(2)} Mb`;
|
|
31904
|
+
};
|
|
31905
|
+
const formatFileSizeDisplay = (value) => {
|
|
31906
|
+
if (value === undefined || value === null)
|
|
31907
|
+
return '';
|
|
31908
|
+
if (typeof value === 'number') {
|
|
31909
|
+
return formatFileSizeShort(value);
|
|
31910
|
+
}
|
|
31911
|
+
const normalized = String(value).trim();
|
|
31912
|
+
if (!normalized)
|
|
31913
|
+
return '';
|
|
31914
|
+
const parsed = Number(normalized);
|
|
31915
|
+
if (!Number.isNaN(parsed)) {
|
|
31916
|
+
return formatFileSizeShort(parsed);
|
|
31917
|
+
}
|
|
31918
|
+
return normalized;
|
|
31919
|
+
};
|
|
31920
|
+
/**
|
|
31921
|
+
* Генерирует уникальное имя файла: если name уже есть в existingNames, добавляет _1 (или _2, _3 и т.д.).
|
|
31922
|
+
* @param name — исходное имя файла (с расширением)
|
|
31923
|
+
* @param existingNames — массив имён файлов/папок в целевой директории
|
|
31924
|
+
*/
|
|
31925
|
+
const getUniqueFileName = (name, existingNames) => {
|
|
31926
|
+
const safeNames = existingNames.filter((n) => typeof n === 'string');
|
|
31927
|
+
const set = new Set(safeNames.map(n => n.toLowerCase()));
|
|
31928
|
+
const safeName = typeof name === 'string' ? name : String(name !== null && name !== void 0 ? name : '');
|
|
31929
|
+
if (!set.has(safeName.toLowerCase()))
|
|
31930
|
+
return safeName;
|
|
31931
|
+
const lastDot = safeName.lastIndexOf('.');
|
|
31932
|
+
const baseName = lastDot > 0 ? safeName.slice(0, lastDot) : safeName;
|
|
31933
|
+
const ext = lastDot > 0 ? safeName.slice(lastDot) : '';
|
|
31934
|
+
let suffix = 1;
|
|
31935
|
+
let candidate;
|
|
31936
|
+
do {
|
|
31937
|
+
candidate = `${baseName}_${suffix}${ext}`;
|
|
31938
|
+
suffix++;
|
|
31939
|
+
} while (set.has(candidate.toLowerCase()));
|
|
31940
|
+
return candidate;
|
|
31941
|
+
};
|
|
31942
|
+
/**
|
|
31943
|
+
* Кодирует URL для безопасного использования в img src. Решает проблему с кириллицей и другими
|
|
31944
|
+
* не-ASCII символами в пути (например, emcdn.ru/.../Снимок_экрана.png).
|
|
31945
|
+
* data: и blob: URLs возвращаются без изменений.
|
|
31946
|
+
*/
|
|
31947
|
+
const encodeUrlForImageSrc = (url) => {
|
|
31948
|
+
if (!url || typeof url !== 'string')
|
|
31949
|
+
return undefined;
|
|
31950
|
+
if (url.startsWith('data:') || url.startsWith('blob:'))
|
|
31951
|
+
return url;
|
|
31952
|
+
try {
|
|
31953
|
+
if (url.startsWith('http://') || url.startsWith('https://') || url.startsWith('/')) {
|
|
31954
|
+
const parsed = new URL(url.startsWith('/') ? `https://x${url}` : url);
|
|
31955
|
+
const origin = url.startsWith('/') ? '' : `${parsed.protocol}//${parsed.host}`;
|
|
31956
|
+
const pathEncoded = parsed.pathname
|
|
31957
|
+
.split('/')
|
|
31958
|
+
.map(seg => {
|
|
31959
|
+
if (!seg)
|
|
31960
|
+
return '';
|
|
31961
|
+
try {
|
|
31962
|
+
return encodeURIComponent(decodeURIComponent(seg));
|
|
31963
|
+
}
|
|
31964
|
+
catch (_a) {
|
|
31965
|
+
return encodeURIComponent(seg);
|
|
31966
|
+
}
|
|
31967
|
+
})
|
|
31968
|
+
.join('/');
|
|
31969
|
+
const result = url.startsWith('/') ? pathEncoded + (parsed.search || '') + (parsed.hash || '') : `${origin}${pathEncoded}${parsed.search}${parsed.hash}`;
|
|
31970
|
+
return result;
|
|
31971
|
+
}
|
|
31972
|
+
}
|
|
31973
|
+
catch (_a) {
|
|
31974
|
+
// если парсинг не удался, возвращаем как есть
|
|
31975
|
+
}
|
|
31976
|
+
return url;
|
|
31977
|
+
};
|
|
31978
|
+
/**
|
|
31979
|
+
* @deprecated Эта функция оставлена только для обратной совместимости.
|
|
31980
|
+
* Используйте {@link normalizeFileName} из `nameNormalization.ts` для настраиваемой нормализации имен файлов.
|
|
31981
|
+
*
|
|
31982
|
+
* Упрощенная санитизация имени файла:
|
|
31983
|
+
* - Заменяет запрещенные символы на `_`
|
|
31984
|
+
* - Заменяет пробелы на `_`
|
|
31985
|
+
* - Удаляет множественные подчеркивания
|
|
31986
|
+
* - Ограничивает длину до 255 символов
|
|
31987
|
+
*/
|
|
31988
|
+
const sanitizeFileName = (fileName) => {
|
|
31989
|
+
return fileName
|
|
31990
|
+
.replace(/[<>:"/\\|?*()#]/g, '_')
|
|
31991
|
+
.split('')
|
|
31992
|
+
.map(char => {
|
|
31993
|
+
const code = char.charCodeAt(0);
|
|
31994
|
+
return code >= 0 && code <= 31 ? '_' : char;
|
|
31995
|
+
})
|
|
31996
|
+
.join('')
|
|
31997
|
+
.replace(/\s+/g, '_')
|
|
31998
|
+
.replace(/_{2,}/g, '_')
|
|
31999
|
+
.substring(0, 255);
|
|
32000
|
+
};
|
|
32001
|
+
|
|
32002
|
+
|
|
32003
|
+
/***/ }),
|
|
32004
|
+
|
|
32005
|
+
/***/ 9287:
|
|
32006
|
+
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
|
32007
|
+
|
|
32008
|
+
// Imports
|
|
32009
|
+
var ___CSS_LOADER_API_SOURCEMAP_IMPORT___ = __webpack_require__(1354);
|
|
32010
|
+
var ___CSS_LOADER_API_IMPORT___ = __webpack_require__(6314);
|
|
32011
|
+
var ___CSS_LOADER_EXPORT___ = ___CSS_LOADER_API_IMPORT___(___CSS_LOADER_API_SOURCEMAP_IMPORT___);
|
|
32012
|
+
// Module
|
|
32013
|
+
___CSS_LOADER_EXPORT___.push([module.id, `.FolderSidebar-module__button__Yf2rX.ant-btn.ant-btn-icon-only{padding:calc(var(--paddingXXS)*1px) calc(var(--paddingSM)*1px);cursor:pointer;color:var(--colorTextSecondary);display:flex;gap:calc(var(--marginXS)*1px);align-items:center;justify-content:center;border-radius:calc(var(--borderRadiusSM)*1px);transition:all var(--motionDurationFast);box-shadow:none;border:none;width:32px;height:32px}.FolderSidebar-module__button__Yf2rX.ant-btn.ant-btn-icon-only:hover{background-color:var(--colorBgLayout);color:inherit}.FolderSidebar-module__button__Yf2rX:hover{background-color:var(--colorBgContainer);color:var(--colorPrimary)}.FolderSidebar-module__foldersTitle__Uh6u7{display:flex;align-items:center;flex:1;cursor:pointer}.FolderSidebar-module__folderActions__qA2Bk{position:absolute;top:4px;right:4px;display:flex;align-items:center;gap:4px;z-index:10}.FolderSidebar-module__folderActions__qA2Bk .FolderSidebar-module__button__Yf2rX.FolderSidebar-module__ant-btn__LXAXm.FolderSidebar-module__ant-btn-icon-only__j_wVF{padding:calc(var(--paddingXXS)*1px) calc(var(--paddingSM)*1px);cursor:pointer;color:var(--colorTextSecondary);display:flex;gap:calc(var(--marginXS)*1px);align-items:center;justify-content:center;border-radius:calc(var(--borderRadiusSM)*1px);transition:all var(--motionDurationFast);box-shadow:none;border:none;width:32px;height:32px}.FolderSidebar-module__folderActions__qA2Bk .FolderSidebar-module__button__Yf2rX.FolderSidebar-module__ant-btn__LXAXm.FolderSidebar-module__ant-btn-icon-only__j_wVF:hover{background-color:var(--colorBgLayout);color:inherit}.FolderSidebar-module__customExpandIcon__IhZJl{display:inline-flex;align-items:center;justify-content:center;width:16px;height:16px;margin-right:8px;cursor:pointer;color:#666;font-size:10px;transition:transform .2s ease}.FolderSidebar-module__customExpandIcon__IhZJl:hover{color:var(--colorPrimary)}.FolderSidebar-module__fileCount__bD9DD{display:inline-flex;align-items:center;justify-content:center;min-width:20px;height:100%;padding:0 6px;margin-left:8px;color:#8d8d8d;font-size:14px;font-weight:500;transition:all .2s ease;white-space:nowrap;cursor:default;flex-shrink:0;margin-right:10px}.ant-tree .ant-tree-node-content-wrapper.ant-tree-node-selected{background-color:rgba(0,0,0,0) !important}.FolderSidebar-module__folderMenu__JCzLF .ant-tree-treenode-selected .folder-label span,.FolderSidebar-module__folderMenu__JCzLF .ant-tree .ant-tree-node-content-wrapper.ant-tree-node-selected .folderLabelItem,.FolderSidebar-module__folderMenu__JCzLF .ant-tree-treenode-selected .folderLabelItem,.FolderSidebar-module__folderMenu__JCzLF .ant-tree-node-selected .folderLabelItem{font-weight:600 !important}.FolderSidebar-module__uploadButton__QQUid{width:100%;justify-content:flex-start}.FolderSidebar-module__uploadButton__QQUid button:hover{background-color:var(--colorPrimaryHover) !important}.FolderSidebar-module__folderMenu__JCzLF{padding-left:0;padding-right:0}.FolderSidebar-module__folderMenu__JCzLF .ant-tree-treenode{display:flex;align-items:center;justify-content:space-between;padding:4px 0;border-radius:4px;transition:background-color .2s ease;width:100%;margin-bottom:0}.FolderSidebar-module__folderMenu__JCzLF .ant-tree-node-content-wrapper{flex:1;align-items:center;padding:0;transition:background-color .2s ease}.FolderSidebar-module__folderMenu__JCzLF .ant-tree-node-content-wrapper:hover{background-color:rgba(0,0,0,0)}.FolderSidebar-module__folderMenu__JCzLF .ant-tree-switcher{height:24px;width:24px;margin-top:5px;display:flex !important;align-items:center;justify-content:center;transition:color .2s ease;flex-shrink:0}.FolderSidebar-module__folderMenu__JCzLF .ant-tree-switcher-noop{width:24px}.FolderSidebar-module__folderMenu__JCzLF .ant-tree-switcher-line-icon{color:#d9d9d9}.FolderSidebar-module__folderMenu__JCzLF .FolderSidebar-module__folderItemContainer__byl5b{width:100%;display:flex;align-items:center;justify-content:space-between;padding:2px 0;min-width:0}.FolderSidebar-module__folderMenu__JCzLF .folder-label{display:flex;align-items:center;flex:1;color:#595959;font-size:14px;min-width:0;overflow:hidden}.FolderSidebar-module__folderMenu__JCzLF .ant-tree-treenode[data-key="folders"]{border-bottom:1px solid var(--colorBorderSecondary);margin-bottom:8px;padding-bottom:8px}.FolderSidebar-module__folderMenu__JCzLF .ant-tree-treenode[data-key="folders"].ant-tree-treenode-selected{background-color:rgba(0,0,0,0) !important}.FolderSidebar-module__folderMenu__JCzLF .ant-tree-treenode[data-key="folders"] .ant-tree-node-content-wrapper{padding:0}.FolderSidebar-module__folderMenu__JCzLF .ant-tree-treenode[data-key="folders"] .ant-tree-node-content-wrapper:hover{background-color:rgba(0,0,0,0) !important}.FolderSidebar-module__folderMenu__JCzLF .ellipsis{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;flex:1;min-width:0}.FolderSidebar-module__folderMenu__JCzLF .FolderSidebar-module__emptyFolderContainer__WK6tx{padding:20px;text-align:center}.FolderSidebar-module__folderMenu__JCzLF .ant-tree > .ant-tree-treenode{padding-left:0 !important}.FolderSidebar-module__folderIcon__UoZzH{margin-right:8px;font-size:18px;flex-shrink:0}.FolderSidebar-module__folderLabelItem__uJ062{font-size:14px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;flex:1;min-width:0;user-select:none}.FolderSidebar-module__foldersTitleItem__gapOI{display:flex;align-items:center;flex:1;cursor:pointer;min-width:0;overflow:hidden}.FolderSidebar-module__folderLabel__fHWMp{display:flex;align-items:center;flex:1;min-width:0;overflow:hidden}.FolderSidebar-module__foldersContainer__zdBVU{position:relative;width:100%}.FolderSidebar-module__uploadButton__QQUid .FolderSidebar-module__ant-btn__LXAXm,.FolderSidebar-module__uploadButton__QQUid .ant-btn{display:flex;align-items:center;justify-content:center;gap:3px}.FolderSidebar-module__buttonWrapper__a9Qi5{margin-bottom:24px;display:flex;gap:4px}.FolderSidebar-module__buttonWrapper__a9Qi5>:first-child{flex:1;height:40px;padding-left:10px}.FolderSidebar-module__buttonWrapper__a9Qi5>:last-child{width:40px;height:40px;flex-shrink:0}.FolderSidebar-module__uploadButtonIcon__mWQmq{font-size:20px}.FolderSidebar-module__uploadButtonTitle__wk_o6{line-height:1em}.FolderSidebar-module__emptyFolderContainer__WK6tx{user-select:none;cursor:default;color:var(--colorTextTertiary)}.FolderSidebar-module__folderItemContainer__byl5b{width:100%;display:flex;align-items:center;justify-content:space-between;padding:2px 0;min-width:0}`, "",{"version":3,"sources":["webpack://./src/components/FolderSidebar/FolderSidebar.module.scss"],"names":[],"mappings":"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","sourcesContent":[".button:global(.ant-btn.ant-btn-icon-only) {\r\n padding: calc(var(--paddingXXS) * 1px) calc(var(--paddingSM) * 1px);\r\n cursor: pointer;\r\n color: var(--colorTextSecondary);\r\n display: flex;\r\n gap: calc(var(--marginXS) * 1px);\r\n align-items: center;\r\n justify-content: center;\r\n border-radius: calc(var(--borderRadiusSM) * 1px);\r\n transition: all var(--motionDurationFast);\r\n box-shadow: none;\r\n\r\n border: none;\r\n width: 32px;\r\n height: 32px;\r\n\r\n &:hover {\r\n background-color: var(--colorBgLayout);\r\n color: inherit;\r\n }\r\n}\r\n\r\n.button:hover {\r\n background-color: var(--colorBgContainer);\r\n color: var(--colorPrimary);\r\n}\r\n\r\n.foldersTitle {\r\n display: flex;\r\n align-items: center;\r\n flex: 1;\r\n cursor: pointer;\r\n}\r\n\r\n.folderActions {\r\n position: absolute;\r\n top: 4px; /* Выравниваем по заголовку Folders */\r\n right: 4px;\r\n display: flex;\r\n align-items: center;\r\n gap: 4px;\r\n z-index: 10;\r\n\r\n .button.ant-btn.ant-btn-icon-only {\r\n padding: calc(var(--paddingXXS) * 1px) calc(var(--paddingSM) * 1px);\r\n cursor: pointer;\r\n color: var(--colorTextSecondary);\r\n display: flex;\r\n gap: calc(var(--marginXS) * 1px);\r\n align-items: center;\r\n justify-content: center;\r\n border-radius: calc(var(--borderRadiusSM) * 1px);\r\n transition: all var(--motionDurationFast);\r\n box-shadow: none;\r\n\r\n border: none;\r\n width: 32px;\r\n height: 32px;\r\n\r\n &:hover {\r\n background-color: var(--colorBgLayout);\r\n color: inherit;\r\n }\r\n }\r\n}\r\n\r\n.customExpandIcon {\r\n display: inline-flex;\r\n align-items: center;\r\n justify-content: center;\r\n width: 16px;\r\n height: 16px;\r\n margin-right: 8px;\r\n cursor: pointer;\r\n color: #666;\r\n font-size: 10px;\r\n transition: transform 0.2s ease;\r\n}\r\n\r\n.customExpandIcon:hover {\r\n color: var(--colorPrimary);\r\n}\r\n\r\n.fileCount {\r\n display: inline-flex;\r\n align-items: center;\r\n justify-content: center;\r\n min-width: 20px;\r\n height: 100%;\r\n padding: 0 6px;\r\n margin-left: 8px;\r\n color: #8D8D8D;\r\n font-size: 14px;\r\n font-weight: 500;\r\n transition: all 0.2s ease;\r\n white-space: nowrap;\r\n cursor: default;\r\n flex-shrink: 0; /* Запрещаем сжатие счетчика */\r\n margin-right: 10px;\r\n}\r\n\r\n// .fileCount:hover {\r\n// border-color: var(--colorPrimary);\r\n// color: var(--colorPrimary);\r\n// }\r\n\r\n:global(.ant-tree .ant-tree-node-content-wrapper.ant-tree-node-selected) {\r\n background-color: transparent !important;\r\n}\r\n\r\n/* :global(.ant-tree .ant-tree-node-content-wrapper.ant-tree-node-selected):hover {\r\n color: red !important;\r\n} */\r\n\r\n/* Стили для выделения текста в выбранной папке */\r\n.folderMenu :global(.ant-tree-treenode-selected .folder-label span),\r\n.folderMenu :global(.ant-tree .ant-tree-node-content-wrapper.ant-tree-node-selected .folderLabelItem),\r\n.folderMenu :global(.ant-tree-treenode-selected .folderLabelItem),\r\n.folderMenu :global(.ant-tree-node-selected .folderLabelItem) {\r\n font-weight: 600 !important;\r\n}\r\n\r\n/* Стили для иконки в выбранной папке */\r\n/* .folderMenu :global(.ant-tree-treenode-selected .folderIcon),\r\n.folderMenu :global(.ant-tree-node-selected .folderIcon) {\r\n color: red !important;\r\n} */\r\n\r\n/* CSS переменные для упрощения расчетов */\r\n\r\n.uploadButton {\r\n width: 100%;\r\n justify-content: flex-start;\r\n\r\n & button:hover {\r\n background-color: var(--colorPrimaryHover) !important;\r\n }\r\n}\r\n\r\n.folderMenu {\r\n padding-left: 0;\r\n padding-right: 0; /* Место для кнопки справа */\r\n}\r\n\r\n.folderMenu :global(.ant-tree-treenode) {\r\n display: flex;\r\n align-items: center;\r\n justify-content: space-between;\r\n padding: 4px 0;\r\n border-radius: 4px;\r\n transition: background-color 0.2s ease;\r\n width: 100%;\r\n margin-bottom: 0;\r\n}\r\n\r\n.folderMenu :global(.ant-tree-node-content-wrapper) {\r\n flex: 1;\r\n /* display: flex; */\r\n align-items: center;\r\n padding: 0;\r\n /* border-radius: 4px; */\r\n transition: background-color 0.2s ease;\r\n}\r\n\r\n.folderMenu :global(.ant-tree-node-content-wrapper:hover) {\r\n background-color: transparent;\r\n}\r\n\r\n.folderMenu :global(.ant-tree-switcher) {\r\n height: 24px;\r\n width: 24px;\r\n margin-top: 5px;\r\n display: flex !important;\r\n align-items: center;\r\n justify-content: center;\r\n transition: color 0.2s ease;\r\n flex-shrink: 0; /* Запрещаем сжатие переключателя */\r\n}\r\n\r\n.folderMenu :global(.ant-tree-switcher-noop) {\r\n width: 24px;\r\n}\r\n\r\n/* Стили для линий дерева */\r\n.folderMenu :global(.ant-tree-switcher-line-icon) {\r\n color: #d9d9d9;\r\n}\r\n\r\n/* Улучшение отображения folder-item-container */\r\n.folderMenu .folderItemContainer {\r\n width: 100%;\r\n display: flex;\r\n align-items: center;\r\n justify-content: space-between;\r\n padding: 2px 0;\r\n min-width: 0; /* Позволяет flex-элементам сжиматься */\r\n}\r\n\r\n.folderMenu :global(.folder-label) {\r\n display: flex;\r\n align-items: center;\r\n flex: 1;\r\n color: #595959;\r\n font-size: 14px;\r\n min-width: 0;\r\n overflow: hidden;\r\n}\r\n\r\n/* Стили для корневого элемента Folders */\r\n.folderMenu :global(.ant-tree-treenode[data-key='folders']) {\r\n border-bottom: 1px solid var(--colorBorderSecondary);\r\n margin-bottom: 8px;\r\n padding-bottom: 8px;\r\n}\r\n\r\n.folderMenu :global(.ant-tree-treenode[data-key='folders'].ant-tree-treenode-selected) {\r\n background-color: transparent !important;\r\n}\r\n\r\n.folderMenu :global(.ant-tree-treenode[data-key='folders'] .ant-tree-node-content-wrapper) {\r\n padding: 0;\r\n}\r\n\r\n.folderMenu :global(.ant-tree-treenode[data-key='folders'] .ant-tree-node-content-wrapper:hover) {\r\n background-color: transparent !important;\r\n}\r\n\r\n/* Стили для ellipsis - удаляем max-width для гибкости */\r\n.folderMenu :global(.ellipsis) {\r\n overflow: hidden;\r\n text-overflow: ellipsis;\r\n white-space: nowrap;\r\n flex: 1;\r\n min-width: 0;\r\n}\r\n\r\n/* Стили для пустого состояния */\r\n.folderMenu .emptyFolderContainer {\r\n padding: 20px;\r\n text-align: center;\r\n}\r\n\r\n/* Убираем отступы у корневого узла */\r\n.folderMenu :global(.ant-tree > .ant-tree-treenode) {\r\n padding-left: 0 !important;\r\n}\r\n.folderIcon {\r\n margin-right: 8px;\r\n font-size: 18px;\r\n flex-shrink: 0; /* Запрещаем сжатие иконки */\r\n}\r\n\r\n.folderLabelItem {\r\n font-size: 14px;\r\n white-space: nowrap; /* Запрещаем перенос строк */\r\n overflow: hidden; /* Скрываем переполнение */\r\n text-overflow: ellipsis; /* Показываем троеточие */\r\n flex: 1; /* Занимает доступное место */\r\n min-width: 0; /* Позволяет сжиматься */\r\n user-select: none;\r\n}\r\n\r\n.foldersTitleItem {\r\n display: flex;\r\n align-items: center;\r\n flex: 1;\r\n cursor: pointer;\r\n min-width: 0; /* Позволяет сжиматься */\r\n overflow: hidden; /* Скрываем переполнение */\r\n}\r\n\r\n/* .foldersTitleItem .folderLabelItem {\r\n font-weight: 500;\r\n color: #262626;\r\n} */\r\n\r\n/* Класс для заголовка папок */\r\n.folderLabel {\r\n display: flex;\r\n align-items: center;\r\n flex: 1;\r\n min-width: 0;\r\n overflow: hidden;\r\n}\r\n\r\n.foldersContainer {\r\n position: relative;\r\n width: 100%;\r\n}\r\n\r\n/* Дополнительные стили для улучшения визуала */\r\n/* .folderMenu :global(.ant-tree-treenode:hover .folder-label span) {\r\n color: #1890ff;\r\n} */\r\n\r\n/* Стили для дивайдера между папками */\r\n\r\n\r\n.uploadButton .ant-btn,\r\n.uploadButton :global(.ant-btn) {\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n gap: 3px;\r\n}\r\n/* .folderMenu :global(.ant-tree-treenode-selected) .folderLabelItem {\r\n color: #1890ff !important;\r\n} */\r\n\r\n// .folderMenu :global(.ant-tree-treenode-selected) .folderLabel .folderLabelItem,\r\n// .folderMenu :global(.ant-tree-treenode-selected) .folderLabel .folderIcon,\r\n// .folderMenu :global(.ant-tree-treenode-selected) .folderLabelItem {\r\n// color: var(--colorLink);\r\n// }\r\n\r\n\r\n.buttonWrapper {\r\n // overflow: hidden;\r\n margin-bottom: 24px;\r\n display: flex;\r\n gap: 4px;\r\n // border-radius: calc(var(--borderRadius) * 1px);\r\n \r\n // Левая кнопка занимает всю доступную ширину\r\n > :first-child {\r\n flex: 1;\r\n height: 40px;\r\n padding-left: 10px;\r\n }\r\n \r\n // Правая кнопка строго 40px\r\n > :last-child {\r\n width: 40px;\r\n height: 40px;\r\n flex-shrink: 0;\r\n }\r\n}\r\n\r\n.uploadButtonIcon {\r\n font-size: 20px;\r\n}\r\n\r\n.uploadButtonTitle {\r\n line-height: 1em;\r\n}\r\n\r\n.emptyFolderContainer {\r\n user-select: none;\r\n cursor: default;\r\n color: var(--colorTextTertiary);\r\n}\r\n\r\n.folderItemContainer {\r\n width: 100%;\r\n display: flex;\r\n align-items: center;\r\n justify-content: space-between;\r\n padding: 2px 0;\r\n min-width: 0; /* Позволяет flex-элементам сжиматься */\r\n}\r\n"],"sourceRoot":""}]);
|
|
32014
|
+
// Exports
|
|
32015
|
+
___CSS_LOADER_EXPORT___.locals = {
|
|
32016
|
+
"button": `FolderSidebar-module__button__Yf2rX`,
|
|
32017
|
+
"foldersTitle": `FolderSidebar-module__foldersTitle__Uh6u7`,
|
|
32018
|
+
"folderActions": `FolderSidebar-module__folderActions__qA2Bk`,
|
|
32019
|
+
"ant-btn": `FolderSidebar-module__ant-btn__LXAXm`,
|
|
32020
|
+
"antBtn": `FolderSidebar-module__ant-btn__LXAXm`,
|
|
32021
|
+
"ant-btn-icon-only": `FolderSidebar-module__ant-btn-icon-only__j_wVF`,
|
|
32022
|
+
"antBtnIconOnly": `FolderSidebar-module__ant-btn-icon-only__j_wVF`,
|
|
32023
|
+
"customExpandIcon": `FolderSidebar-module__customExpandIcon__IhZJl`,
|
|
32024
|
+
"fileCount": `FolderSidebar-module__fileCount__bD9DD`,
|
|
32025
|
+
"folderMenu": `FolderSidebar-module__folderMenu__JCzLF`,
|
|
32026
|
+
"uploadButton": `FolderSidebar-module__uploadButton__QQUid`,
|
|
32027
|
+
"folderItemContainer": `FolderSidebar-module__folderItemContainer__byl5b`,
|
|
32028
|
+
"emptyFolderContainer": `FolderSidebar-module__emptyFolderContainer__WK6tx`,
|
|
32029
|
+
"folderIcon": `FolderSidebar-module__folderIcon__UoZzH`,
|
|
32030
|
+
"folderLabelItem": `FolderSidebar-module__folderLabelItem__uJ062`,
|
|
32031
|
+
"foldersTitleItem": `FolderSidebar-module__foldersTitleItem__gapOI`,
|
|
32032
|
+
"folderLabel": `FolderSidebar-module__folderLabel__fHWMp`,
|
|
32033
|
+
"foldersContainer": `FolderSidebar-module__foldersContainer__zdBVU`,
|
|
32034
|
+
"buttonWrapper": `FolderSidebar-module__buttonWrapper__a9Qi5`,
|
|
32035
|
+
"uploadButtonIcon": `FolderSidebar-module__uploadButtonIcon__mWQmq`,
|
|
32036
|
+
"uploadButtonTitle": `FolderSidebar-module__uploadButtonTitle__wk_o6`
|
|
32037
|
+
};
|
|
32038
|
+
module.exports = ___CSS_LOADER_EXPORT___;
|
|
32039
|
+
|
|
32040
|
+
|
|
32023
32041
|
/***/ }),
|
|
32024
32042
|
|
|
32025
32043
|
/***/ 9589:
|
|
@@ -33361,8 +33379,8 @@ const SearchInput = ({ onSearch, placeholder, className }) => {
|
|
|
33361
33379
|
;// ./src/components/SearchInput/index.ts
|
|
33362
33380
|
|
|
33363
33381
|
|
|
33364
|
-
// EXTERNAL MODULE: ./src/hooks/core/files/index.ts +
|
|
33365
|
-
var core_files = __webpack_require__(
|
|
33382
|
+
// EXTERNAL MODULE: ./src/hooks/core/files/index.ts + 18 modules
|
|
33383
|
+
var core_files = __webpack_require__(8573);
|
|
33366
33384
|
;// ./src/hooks/core/types.ts
|
|
33367
33385
|
/** Полный список опций сортировки в дропдауне (порядок отображения). */
|
|
33368
33386
|
const ALL_SORT_OPTIONS = [
|