linting, tenant slug -> name

This commit is contained in:
2025-10-29 18:26:59 +01:00
parent b6bcb72165
commit abc0116945
23 changed files with 324 additions and 487 deletions
+32 -33
View File
@@ -123,10 +123,11 @@ const readTransferData = (dataTransfer, mimeTypes) => {
if (raw) {
return raw;
}
} catch (
// eslint-disable-next-line no-empty
error
) {}
} catch (error) {
if (DEBUG_DROP) {
console.warn('[skeuo] readTransferData failed for type', type, error);
}
}
}
return null;
};
@@ -141,10 +142,9 @@ const parseTagTransferPayload = (event) => {
}
try {
return JSON.parse(raw);
} catch (
// eslint-disable-next-line no-empty
error
) {}
} catch (error) {
console.warn('[skeuo] parseTagTransferPayload failed', error);
}
return null;
};
@@ -465,10 +465,9 @@ const usePreviewMetadata = (documents, getDocumentAsset, ensureAssetUrl) => {
view = createAssetView(asset);
metadata = view.getPrimaryMetadata();
}
} catch (
// eslint-disable-next-line no-empty
error
) {}
} catch (error) {
console.warn('[skeuo] ensureDocumentSize metadata fetch failed', error);
}
}
if (!hasDimensions(metadata)) {
@@ -509,7 +508,7 @@ const usePreviewMetadata = (documents, getDocumentAsset, ensureAssetUrl) => {
return metadataMap;
};
const seededRandom = (input) => {
function seededRandom(input) {
const text = String(input);
let hash = 2166136261;
for (let index = 0; index < text.length; index += 1) {
@@ -517,16 +516,18 @@ const seededRandom = (input) => {
hash = Math.imul(hash, 16777619);
}
return (hash >>> 0) / 4294967295;
};
}
const randomRangeFromSeed = (seedKey, min, max) => {
function randomRangeFromSeed(seedKey, min, max) {
const span = max - min;
if (span <= 0) return min;
const seed = seededRandom(seedKey);
return min + seed * span;
};
}
const buildKey = (docId, suffix) => `${docId}::${suffix}`;
function buildKey(docId, suffix) {
return `${docId}::${suffix}`;
}
const clampCardDimensions = (width, height) => {
const w = Number(width);
@@ -758,10 +759,11 @@ const DesktopWorkspace = ({
if (DEBUG_FOCUS) {
console.log('[skeuo] focusCanvas: applied focus. activeElement:', document?.activeElement);
}
} catch (
// eslint-disable-next-line no-empty
error
) {}
} catch (error) {
if (DEBUG_FOCUS) {
console.warn('[skeuo] focusTarget failed to focus canvas', error);
}
}
};
if (typeof window === 'undefined') {
@@ -1551,20 +1553,18 @@ const syncLayoutSnapshot = useCallback(() => {
if (event.dataTransfer) {
event.dataTransfer.effectAllowed = 'copyMove';
}
} catch (
// eslint-disable-next-line no-empty
error
) {}
} catch (error) {
console.warn('[skeuo] Failed to set drag effect', error);
}
const payload = JSON.stringify({ id: tag.id, label: tag.label, sourceDocId: doc.id });
try {
event.dataTransfer?.setData('application/x-papercrate-tag', payload);
event.dataTransfer?.setData('text/papercrate-tag', payload);
event.dataTransfer?.setData('text/plain', tag.label || 'Tag');
} catch (
// eslint-disable-next-line no-empty
error
) {}
} catch (error) {
console.warn('[skeuo] Failed to populate drag data for tag', error);
}
const pending = pendingDocTagDragRef.current;
const node = event.currentTarget;
@@ -1593,10 +1593,9 @@ const syncLayoutSnapshot = useCallback(() => {
if (preview && event.dataTransfer) {
try {
event.dataTransfer.setDragImage(preview.clone, preview.offsetX, preview.offsetY);
} catch (
// eslint-disable-next-line no-empty
error
) {}
} catch (error) {
console.warn('[skeuo] Failed to set drag image', error);
}
}
}
draggingTagRef.current = {
@@ -38,10 +38,11 @@ function CorrespondentsPanel({
try {
await onUpdate(editingId, { name: trimmed });
cancelEdit();
} catch (
// eslint-disable-next-line no-empty
error
) {}
} catch (error) {
onNotify?.('Failed to update correspondent.', 'error');
console.error('[correspondents] update failed', error);
setSaving(false);
}
}, [editingId, draftName, onUpdate, cancelEdit, onNotify]);
const handleDelete = useCallback(
@@ -53,16 +54,14 @@ function CorrespondentsPanel({
if (editingId === correspondent.id) {
cancelEdit();
}
} catch (
// eslint-disable-next-line no-empty
error
) {
return;
} catch (error) {
onNotify?.('Failed to delete correspondent.', 'error');
console.error('[correspondents] delete failed', error);
} finally {
setDeletingId(null);
}
},
[onDelete, editingId, cancelEdit],
[onDelete, editingId, cancelEdit, onNotify],
);
const handleCreate = useCallback(
@@ -77,11 +76,9 @@ function CorrespondentsPanel({
try {
await onCreate({ name: trimmed });
setCreateName('');
} catch (
// eslint-disable-next-line no-empty
error
) {
return;
} catch (error) {
onNotify?.('Failed to create correspondent.', 'error');
console.error('[correspondents] create failed', error);
} finally {
setCreating(false);
}
+6 -8
View File
@@ -4,14 +4,12 @@ export const preventAll = (event) => {
}
try {
event.preventDefault();
} catch (
// eslint-disable-next-line no-empty
error
) {}
} catch (error) {
console.warn('[events] preventDefault failed', error);
}
try {
event.stopPropagation();
} catch (
// eslint-disable-next-line no-empty
error
) {}
} catch (error) {
console.warn('[events] stopPropagation failed', error);
}
};
+11 -9
View File
@@ -35,16 +35,17 @@ const useDocumentDrag = () => {
if (capturedTarget && typeof capturedTarget.releasePointerCapture === 'function') {
try {
capturedTarget.releasePointerCapture(pointerId);
} catch (
// eslint-disable-next-line no-empty
error
) {}
} catch (error) {
if (debugDrag) {
console.warn('[skeuo] releasePointerCapture failed', error);
}
}
}
dragStateRef.current = null;
setDraggingId((current) => (current === state.docId ? null : current));
syncLayoutSnapshot();
},
[setDraggingId, syncLayoutSnapshot],
[debugDrag, setDraggingId, syncLayoutSnapshot],
);
const handlePointerDown = useCallback(
@@ -83,10 +84,11 @@ const useDocumentDrag = () => {
if (capturedTarget && typeof capturedTarget.setPointerCapture === 'function') {
try {
capturedTarget.setPointerCapture(event.pointerId);
} catch (
// eslint-disable-next-line no-empty
error
) {}
} catch (error) {
if (debugDrag) {
console.warn('[skeuo] setPointerCapture failed', error);
}
}
}
dragStateRef.current = {
docId,
+12 -7
View File
@@ -200,11 +200,7 @@ const PreviewStack = ({
onOpenPreview,
onZoomPreview,
}) => {
if (!items.length) {
return <span className="meta">{emptyMessage}</span>;
}
const limited = items.slice(0, maxItems);
const limited = useMemo(() => items.slice(0, maxItems), [items, maxItems]);
const hasMultiple = limited.length > 1;
const preparedItems = useMemo(
() =>
@@ -215,6 +211,10 @@ const PreviewStack = ({
[limited],
);
if (!limited.length) {
return <span className="meta">{emptyMessage}</span>;
}
return (
<div className="preview-stack preview-stack--stacked">
{preparedItems.map(({ entry, angle }, index) => {
@@ -329,6 +329,11 @@ const DetailPanel = ({
const [titleError, setTitleError] = useState(null);
const [zoomedPreview, setZoomedPreview] = useState(null);
const bulkDocumentIds = useMemo(
() => selectedDocuments.map((doc) => doc?.id).filter(Boolean),
[selectedDocuments],
);
useEffect(() => {
if (!singleDoc) {
setTitleEditDocId(null);
@@ -1097,7 +1102,7 @@ const DetailPanel = ({
event.preventDefault();
event.stopPropagation();
};
const documentIds = Array.from(new Set(selectedDocuments.map((doc) => doc?.id).filter(Boolean)));
const documentIds = bulkDocumentIds;
return (
<>
@@ -1224,7 +1229,7 @@ const DetailPanel = ({
className="icon-button ghost"
onClick={(event) => {
event.stopPropagation();
onBulkReanalyze(documentIds);
onBulkReanalyze(bulkDocumentIds);
}}
aria-label="Re-run analysis for selection"
title="Re-run analysis for selection"
+20 -23
View File
@@ -392,10 +392,9 @@ const DocumentsTable = ({
if (parsed?.id && onDocumentTagDrop) {
onDocumentTagDrop(documentId, parsed);
}
} catch (
// eslint-disable-next-line no-empty
error
) {}
} catch (error) {
console.warn('[documents] Failed to parse tag drop payload', error);
}
},
[isTagDragEvent, onDocumentTagDrop],
);
@@ -714,10 +713,9 @@ const DocumentsTable = ({
event.dataTransfer?.setData('application/x-papercrate-tag', payload);
event.dataTransfer?.setData('text/papercrate-tag', payload);
event.dataTransfer?.setData('text/plain', tag.label || 'Tag');
} catch (
// eslint-disable-next-line no-empty
error
) {}
} catch (error) {
console.warn('[documents] Failed to configure tag drag payload', error);
}
}}
onDragEnd={(event) => {
event.stopPropagation();
@@ -925,21 +923,20 @@ const DocumentsTable = ({
onDragStart={(event) => {
event.stopPropagation();
try {
if (event.dataTransfer) {
event.dataTransfer.effectAllowed = 'copyMove';
}
const payload = JSON.stringify({
id: tag.id,
label: tag.label,
sourceDocId: doc.id,
});
event.dataTransfer?.setData('application/x-papercrate-tag', payload);
event.dataTransfer?.setData('text/papercrate-tag', payload);
event.dataTransfer?.setData('text/plain', tag.label || 'Tag');
} catch (
// eslint-disable-next-line no-empty
error
) {}
if (event.dataTransfer) {
event.dataTransfer.effectAllowed = 'copyMove';
}
const payload = JSON.stringify({
id: tag.id,
label: tag.label,
sourceDocId: doc.id,
});
event.dataTransfer?.setData('application/x-papercrate-tag', payload);
event.dataTransfer?.setData('text/papercrate-tag', payload);
event.dataTransfer?.setData('text/plain', tag.label || 'Tag');
} catch (error) {
console.warn('[documents] Failed to configure tag drag payload', error);
}
}}
onDragEnd={(event) => {
event.stopPropagation();
+59 -219
View File
@@ -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,
],
+24 -26
View File
@@ -154,7 +154,7 @@ const Sidebar = ({
onLogout,
status,
onCollapse,
tenantSlug,
tenantName,
tenants = [],
activeTenantId = null,
onSelectTenant,
@@ -308,7 +308,7 @@ const Sidebar = ({
>
<span className="sidebar__title">
Papercrate
{tenantSlug ? <span className="sidebar__tenant"> / {tenantSlug}</span> : null}
{tenantName ? <span className="sidebar__tenant"> / {tenantName}</span> : null}
</span>
<ChevronDownIcon
className={`sidebar__title-chevron${tenantMenuOpen ? ' is-open' : ''}`}
@@ -324,9 +324,10 @@ const Sidebar = ({
tenants.map((tenant) => {
const tenantId = tenant?.id || null;
const isActive = tenantId === activeTenantId;
const tenantLabel = tenant?.name || tenant?.slug || tenantId || 'Tenant';
return (
<button
key={tenantId || tenant?.slug || tenant?.name}
key={tenantId || tenantLabel}
type="button"
className={`menu__item${isActive ? ' active' : ''}`}
onClick={() => handleTenantSelect(tenant)}
@@ -335,9 +336,7 @@ const Sidebar = ({
<span className="menu__check-slot">
{isActive ? <CheckIcon size={16} /> : null}
</span>
<span className="menu__label">
{tenant?.slug || tenant?.name || tenantId || 'Tenant'}
</span>
<span className="menu__label">{tenantLabel}</span>
</button>
);
})
@@ -437,26 +436,25 @@ const Sidebar = ({
style={style || undefined}
onClick={() => handleToggleTag(tag.id)}
aria-pressed={isActive}
draggable
onDragStart={(event) => {
try {
const payload = JSON.stringify({
id: tag.id,
label: tag.label,
color: tag.color || null,
});
event.dataTransfer.effectAllowed = 'copy';
event.dataTransfer.setData('application/x-papercrate-tag', payload);
event.dataTransfer.setData('text/papercrate-tag', payload);
} catch (
// eslint-disable-next-line no-empty
error
) {}
}}
>
{tag.label}
</button>
);
draggable
onDragStart={(event) => {
try {
const payload = JSON.stringify({
id: tag.id,
label: tag.label,
color: tag.color || null,
});
event.dataTransfer.effectAllowed = 'copy';
event.dataTransfer.setData('application/x-papercrate-tag', payload);
event.dataTransfer.setData('text/papercrate-tag', payload);
} catch (error) {
console.warn('[sidebar] Failed to set tag drag payload', error);
}
}}
>
{tag.label}
</button>
);
})}
</div>
</div>
+4 -8
View File
@@ -23,15 +23,11 @@ export async function resolveOcrTextUrl({
let asset = pickAsset(docRef, getDocumentAsset);
if (!asset && typeof ensurePreviewData === 'function') {
try {
const refreshed = await ensurePreviewData(docRef.id);
if (refreshed) {
docRef = refreshed;
}
asset = pickAsset(docRef, getDocumentAsset);
} catch (error) {
throw error;
const refreshed = await ensurePreviewData(docRef.id);
if (refreshed) {
docRef = refreshed;
}
asset = pickAsset(docRef, getDocumentAsset);
}
if (!asset) {