linting, tenant slug -> name
This commit is contained in:
+59
-219
@@ -53,10 +53,9 @@ if (storage) {
|
||||
if (rawTenant) {
|
||||
STORED_TENANT = JSON.parse(rawTenant);
|
||||
}
|
||||
} catch (
|
||||
// eslint-disable-next-line no-empty
|
||||
error
|
||||
) {}
|
||||
} catch (error) {
|
||||
console.warn('[app] Failed to parse stored tenant metadata', error);
|
||||
}
|
||||
}
|
||||
if (STORED_TOKEN) {
|
||||
api.defaults.headers.common.Authorization = `Bearer ${STORED_TOKEN}`;
|
||||
@@ -428,7 +427,7 @@ const LoginView = ({
|
||||
: 'login-card__tenant-button'
|
||||
}
|
||||
>
|
||||
{tenant.slug}
|
||||
{tenant.name}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
@@ -492,7 +491,7 @@ const AppLayout = () => {
|
||||
const routeDocumentId = docMatch?.params?.documentId || null;
|
||||
const previewDocumentId = routeDocumentId;
|
||||
const { status: appStatus, token, tenant, tenants: tenantOptions = [] } = appState;
|
||||
const tenantSlug = tenant?.slug || null;
|
||||
const tenantName = tenant?.name || tenant?.slug || null;
|
||||
const currentTenantId = tenant?.id || null;
|
||||
const [status, setStatus] = useState(null);
|
||||
const setStatusMessage = useCallback((message, variant = 'info') => {
|
||||
@@ -586,6 +585,8 @@ const AppLayout = () => {
|
||||
}
|
||||
}, [appDispatch]);
|
||||
const [searchResults, setSearchResults] = useState(null);
|
||||
const [previewEntries, setPreviewEntries] = useState(() => new Map());
|
||||
const previewInflightRef = useRef(new Map());
|
||||
const [tags, setTags] = useState([]);
|
||||
const [correspondents, setCorrespondents] = useState([]);
|
||||
const [webdavTokens, setWebdavTokens] = useState([]);
|
||||
@@ -596,6 +597,7 @@ const AppLayout = () => {
|
||||
const [searchQuery, setSearchQuery] = useState('');
|
||||
const [activeTagFilters, setActiveTagFilters] = useState([]);
|
||||
const [activeCorrespondentFilters, setActiveCorrespondentFilters] = useState([]);
|
||||
const [searchLoading, setSearchLoading] = useState(false);
|
||||
const documentsRouteMatch = useMatch('/documents');
|
||||
const documentsFolderRouteMatch = useMatch('/documents/folder/:folderId');
|
||||
const documentsDetailRouteMatch = useMatch('/documents/:documentId');
|
||||
@@ -656,7 +658,6 @@ const AppLayout = () => {
|
||||
folderName: DEFAULT_FOLDER_NAME,
|
||||
});
|
||||
const [activePreviewId, setActivePreviewId] = useState(routeDocumentId || null);
|
||||
const [searchLoading, setSearchLoading] = useState(false);
|
||||
const shellRef = useRef(null);
|
||||
const assetManagerRef = useRef(null);
|
||||
if (!assetManagerRef.current) {
|
||||
@@ -1951,6 +1952,21 @@ const AppLayout = () => {
|
||||
[refreshCorrespondents, notifyApiError, setStatusMessage, mapDocumentCaches],
|
||||
);
|
||||
|
||||
const refreshCurrentFolder = useCallback(async () => {
|
||||
setLoading(true);
|
||||
try {
|
||||
const contents = await ensureFolderData(selectedFolder, {
|
||||
force: true,
|
||||
prefetchDepth: 1,
|
||||
});
|
||||
applySelectedFolder(selectedFolder, contents);
|
||||
} catch (error) {
|
||||
notifyApiError(error, 'Failed to refresh folder.');
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
}, [selectedFolder, ensureFolderData, applySelectedFolder, notifyApiError]);
|
||||
|
||||
const handleDocumentCorrespondentAttach = useCallback(
|
||||
async ({ documentId, correspondentId }, { notify = true, refresh = true } = {}) => {
|
||||
if (!documentId || !correspondentId) {
|
||||
@@ -2033,10 +2049,10 @@ const AppLayout = () => {
|
||||
if (input) {
|
||||
input.value = '';
|
||||
}
|
||||
} catch (
|
||||
// eslint-disable-next-line no-empty
|
||||
error
|
||||
) {}
|
||||
} catch (error) {
|
||||
setStatusMessage('Failed to assign correspondent.', 'error');
|
||||
console.error('[documents] assign correspondent failed', error);
|
||||
}
|
||||
},
|
||||
[
|
||||
handleCorrespondentCreate,
|
||||
@@ -2286,21 +2302,6 @@ const AppLayout = () => {
|
||||
selectFolder,
|
||||
]);
|
||||
|
||||
const refreshCurrentFolder = useCallback(async () => {
|
||||
setLoading(true);
|
||||
try {
|
||||
const contents = await ensureFolderData(selectedFolder, {
|
||||
force: true,
|
||||
prefetchDepth: 1,
|
||||
});
|
||||
applySelectedFolder(selectedFolder, contents);
|
||||
} catch (error) {
|
||||
notifyApiError(error, 'Failed to refresh folder.');
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
}, [selectedFolder, ensureFolderData, applySelectedFolder, notifyApiError]);
|
||||
|
||||
const resolveTargetDocumentIds = useCallback(
|
||||
(candidateIds) => {
|
||||
const normalized = Array.isArray(candidateIds)
|
||||
@@ -2671,8 +2672,6 @@ const AppLayout = () => {
|
||||
);
|
||||
|
||||
const folderPathCacheRef = useRef(new Map());
|
||||
const [previewEntries, setPreviewEntries] = useState(() => new Map());
|
||||
const previewInflightRef = useRef(new Map());
|
||||
|
||||
const ensureFolderPathOnServer = useCallback(
|
||||
async (baseFolderId, segments) => {
|
||||
@@ -2919,10 +2918,9 @@ const AppLayout = () => {
|
||||
event.dataTransfer.setData('application/x-papercrate-folder', folderSelection[0]);
|
||||
}
|
||||
}
|
||||
} catch (
|
||||
// eslint-disable-next-line no-empty
|
||||
error
|
||||
) {}
|
||||
} catch (error) {
|
||||
console.warn('[documents] Failed to populate drag payload', error);
|
||||
}
|
||||
if (previewNode) {
|
||||
const width = previewNode.offsetWidth || 96;
|
||||
const height = previewNode.offsetHeight || 96;
|
||||
@@ -2993,10 +2991,9 @@ const AppLayout = () => {
|
||||
JSON.stringify(effectiveDocumentSelection),
|
||||
);
|
||||
}
|
||||
} catch (
|
||||
// eslint-disable-next-line no-empty
|
||||
error
|
||||
) {}
|
||||
} catch (error) {
|
||||
console.warn('[folders] Failed to set drag payload', error);
|
||||
}
|
||||
|
||||
const previewDocs = effectiveDocumentSelection
|
||||
.map((id) => documentLookup.get(id) || null)
|
||||
@@ -3112,14 +3109,14 @@ const AppLayout = () => {
|
||||
|
||||
const readAllEntries = async (reader) => {
|
||||
const entries = [];
|
||||
while (true) {
|
||||
let batch = [];
|
||||
do {
|
||||
// eslint-disable-next-line no-await-in-loop
|
||||
const batch = await new Promise((resolve, reject) => reader.readEntries(resolve, reject));
|
||||
if (!batch.length) {
|
||||
break;
|
||||
batch = await new Promise((resolve, reject) => reader.readEntries(resolve, reject));
|
||||
if (batch.length) {
|
||||
entries.push(...batch);
|
||||
}
|
||||
entries.push(...batch);
|
||||
}
|
||||
} while (batch.length);
|
||||
return entries;
|
||||
};
|
||||
|
||||
@@ -4424,10 +4421,9 @@ const AppLayout = () => {
|
||||
folderIds = parsed.filter(Boolean);
|
||||
}
|
||||
}
|
||||
} catch (
|
||||
// eslint-disable-next-line no-empty
|
||||
error
|
||||
) {}
|
||||
} catch (error) {
|
||||
console.warn('[folders] Failed to parse folder list drag payload', error);
|
||||
}
|
||||
|
||||
if (!folderIds.length) {
|
||||
let folderSourceId = draggedFolderId;
|
||||
@@ -4436,10 +4432,9 @@ const AppLayout = () => {
|
||||
if (event.dataTransfer.types?.includes('application/x-papercrate-folder')) {
|
||||
folderSourceId = event.dataTransfer.getData('application/x-papercrate-folder');
|
||||
}
|
||||
} catch (
|
||||
// eslint-disable-next-line no-empty
|
||||
error
|
||||
) {}
|
||||
} catch (error) {
|
||||
console.warn('[folders] Failed to read folder id from drag payload', error);
|
||||
}
|
||||
}
|
||||
|
||||
if (folderSourceId) {
|
||||
@@ -4480,21 +4475,19 @@ const AppLayout = () => {
|
||||
docIds = parsed.filter(Boolean);
|
||||
}
|
||||
}
|
||||
} catch (
|
||||
// eslint-disable-next-line no-empty
|
||||
error
|
||||
) {}
|
||||
} catch (error) {
|
||||
console.warn('[documents] Failed to parse document list drag payload', error);
|
||||
}
|
||||
|
||||
if (!docIds.length) {
|
||||
try {
|
||||
const single = event.dataTransfer.getData('application/x-papercrate-doc');
|
||||
if (single) {
|
||||
docIds = [single];
|
||||
}
|
||||
} catch (
|
||||
// eslint-disable-next-line no-empty
|
||||
error
|
||||
) {}
|
||||
try {
|
||||
const single = event.dataTransfer.getData('application/x-papercrate-doc');
|
||||
if (single) {
|
||||
docIds = [single];
|
||||
}
|
||||
} catch (error) {
|
||||
console.warn('[documents] Failed to read single document drag payload', error);
|
||||
}
|
||||
}
|
||||
|
||||
if (!docIds.length && draggedDocumentIds.length) {
|
||||
@@ -4551,159 +4544,6 @@ const AppLayout = () => {
|
||||
setStatusMessage,
|
||||
],
|
||||
);
|
||||
const node = folderNodes.get(folderId);
|
||||
const nextExpanded = !(node?.expanded ?? false);
|
||||
if (nextExpanded) {
|
||||
try {
|
||||
await ensureFolderData(folderId, {
|
||||
includeDocuments: false,
|
||||
prefetchDepth: 1,
|
||||
});
|
||||
} catch (error) {
|
||||
notifyApiError(error, 'Failed to load folder.');
|
||||
}
|
||||
} else if (node && !node.loaded) {
|
||||
try {
|
||||
await ensureFolderData(folderId, {
|
||||
includeDocuments: false,
|
||||
prefetchDepth: 1,
|
||||
});
|
||||
} catch (error) {
|
||||
notifyApiError(error, 'Failed to load folder.');
|
||||
}
|
||||
}
|
||||
setFolderNodes((prev) => {
|
||||
const next = new Map(prev);
|
||||
const current = next.get(folderId);
|
||||
if (!current) return prev;
|
||||
next.set(folderId, { ...current, expanded: nextExpanded });
|
||||
return next;
|
||||
});
|
||||
},
|
||||
onSelect: selectFolder,
|
||||
onDrop: async (event, folderId) => {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
event.currentTarget.classList.remove('is-drop-target');
|
||||
|
||||
let folderIds = [];
|
||||
try {
|
||||
const rawFolderList = event.dataTransfer.getData('application/x-papercrate-folder-list');
|
||||
if (rawFolderList) {
|
||||
const parsed = JSON.parse(rawFolderList);
|
||||
if (Array.isArray(parsed)) {
|
||||
folderIds = parsed.filter(Boolean);
|
||||
}
|
||||
}
|
||||
} catch (
|
||||
// eslint-disable-next-line no-empty
|
||||
error
|
||||
) {}
|
||||
|
||||
if (!folderIds.length) {
|
||||
let folderSourceId = draggedFolderId;
|
||||
if (!folderSourceId) {
|
||||
try {
|
||||
if (event.dataTransfer.types?.includes('application/x-papercrate-folder')) {
|
||||
folderSourceId = event.dataTransfer.getData('application/x-papercrate-folder');
|
||||
}
|
||||
} catch (
|
||||
// eslint-disable-next-line no-empty
|
||||
error
|
||||
) {}
|
||||
}
|
||||
|
||||
if (folderSourceId) {
|
||||
folderIds = [folderSourceId];
|
||||
}
|
||||
}
|
||||
|
||||
folderIds = Array.from(new Set(folderIds.filter(Boolean)));
|
||||
|
||||
if (folderIds.length) {
|
||||
setDraggedFolderId(null);
|
||||
const invalidMove = folderIds.some((sourceId) => isInvalidFolderDrop(sourceId, folderId));
|
||||
if (invalidMove) {
|
||||
setStatusMessage(
|
||||
'Cannot move a folder into itself or one of its descendants.',
|
||||
'error',
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
for (const sourceId of folderIds) {
|
||||
// eslint-disable-next-line no-await-in-loop
|
||||
await moveFolder(sourceId, folderId);
|
||||
}
|
||||
}
|
||||
|
||||
if (hasFiles(event)) {
|
||||
await handleFileDrop(event.dataTransfer, folderId);
|
||||
return;
|
||||
}
|
||||
|
||||
let docIds = [];
|
||||
try {
|
||||
const raw = event.dataTransfer.getData('application/x-papercrate-doc-list');
|
||||
if (raw) {
|
||||
const parsed = JSON.parse(raw);
|
||||
if (Array.isArray(parsed)) {
|
||||
docIds = parsed.filter(Boolean);
|
||||
}
|
||||
}
|
||||
} catch (
|
||||
// eslint-disable-next-line no-empty
|
||||
error
|
||||
) {}
|
||||
|
||||
if (!docIds.length) {
|
||||
try {
|
||||
const single = event.dataTransfer.getData('application/x-papercrate-doc');
|
||||
if (single) {
|
||||
docIds = [single];
|
||||
}
|
||||
} catch (
|
||||
// eslint-disable-next-line no-empty
|
||||
error
|
||||
) {}
|
||||
}
|
||||
|
||||
if (!docIds.length && draggedDocumentIds.length) {
|
||||
docIds = draggedDocumentIds;
|
||||
}
|
||||
|
||||
docIds = Array.from(new Set(docIds));
|
||||
|
||||
if (!docIds.length || folderId === selectedFolder) {
|
||||
return;
|
||||
}
|
||||
|
||||
setDraggedDocumentIds([]);
|
||||
await moveDocumentsToFolder(docIds, folderId);
|
||||
},
|
||||
onDragOver: (event, folderId) => {
|
||||
const folderDragActive = Boolean(draggedFolderId);
|
||||
if (folderDragActive && isInvalidFolderDrop(draggedFolderId, folderId)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (hasFiles(event)) {
|
||||
event.preventDefault();
|
||||
event.dataTransfer.dropEffect = 'copy';
|
||||
event.currentTarget.classList.add('is-drop-target');
|
||||
return;
|
||||
}
|
||||
|
||||
if (draggedDocumentIds.length || folderDragActive) {
|
||||
event.preventDefault();
|
||||
event.dataTransfer.dropEffect = 'move';
|
||||
event.currentTarget.classList.add('is-drop-target');
|
||||
}
|
||||
},
|
||||
onDragLeave: (event) => {
|
||||
event.currentTarget.classList.remove('is-drop-target');
|
||||
},
|
||||
};
|
||||
|
||||
const selectedDocument = useMemo(() => {
|
||||
if (!focusedDocumentId) {
|
||||
@@ -5163,7 +5003,7 @@ const AppLayout = () => {
|
||||
await Promise.all([refreshTags(), refreshCorrespondents()]);
|
||||
await loadFolder('root', { showLoading: false, preserveSearch: false });
|
||||
|
||||
const tenantLabel = data?.tenant?.slug || data?.tenant?.id || 'tenant';
|
||||
const tenantLabel = data?.tenant?.name || data?.tenant?.id || 'tenant';
|
||||
setStatusMessage(`Switched to ${tenantLabel}.`, 'info');
|
||||
} catch (error) {
|
||||
notifyApiError(error, 'Failed to switch tenant.');
|
||||
@@ -5314,7 +5154,7 @@ const AppLayout = () => {
|
||||
isFilterActive,
|
||||
onLogout: handleLogout,
|
||||
status,
|
||||
tenantSlug,
|
||||
tenantName,
|
||||
tenants: tenantOptions,
|
||||
activeTenantId: currentTenantId,
|
||||
onSelectTenant: handleTenantSelect,
|
||||
@@ -5347,7 +5187,7 @@ const AppLayout = () => {
|
||||
status,
|
||||
tags,
|
||||
tenantOptions,
|
||||
tenantSlug,
|
||||
tenantName,
|
||||
toggleCorrespondentFilter,
|
||||
toggleTagFilter,
|
||||
],
|
||||
|
||||
Reference in New Issue
Block a user