diff --git a/backend/migrations/202503240003_add_metadata_to_document_versions/down.sql b/backend/migrations/202503240003_add_metadata_to_document_versions/down.sql new file mode 100644 index 0000000..1df5398 --- /dev/null +++ b/backend/migrations/202503240003_add_metadata_to_document_versions/down.sql @@ -0,0 +1,2 @@ +ALTER TABLE document_versions + DROP COLUMN metadata; diff --git a/backend/migrations/202503240003_add_metadata_to_document_versions/up.sql b/backend/migrations/202503240003_add_metadata_to_document_versions/up.sql new file mode 100644 index 0000000..7b941e3 --- /dev/null +++ b/backend/migrations/202503240003_add_metadata_to_document_versions/up.sql @@ -0,0 +1,2 @@ +ALTER TABLE document_versions + ADD COLUMN metadata JSONB NOT NULL DEFAULT '{}'::jsonb; diff --git a/backend/migrations/202503240004_drop_folder_path_cache/down.sql b/backend/migrations/202503240004_drop_folder_path_cache/down.sql new file mode 100644 index 0000000..41af8f9 --- /dev/null +++ b/backend/migrations/202503240004_drop_folder_path_cache/down.sql @@ -0,0 +1,2 @@ +ALTER TABLE folders + ADD COLUMN path_cache VARCHAR(1000); diff --git a/backend/migrations/202503240004_drop_folder_path_cache/up.sql b/backend/migrations/202503240004_drop_folder_path_cache/up.sql new file mode 100644 index 0000000..fc3cfcf --- /dev/null +++ b/backend/migrations/202503240004_drop_folder_path_cache/up.sql @@ -0,0 +1,2 @@ +ALTER TABLE folders + DROP COLUMN path_cache; diff --git a/frontend/public/folder.svg b/frontend/public/folder.svg new file mode 100644 index 0000000..d89d7c3 --- /dev/null +++ b/frontend/public/folder.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/frontend/src/documents/DocumentsTable.jsx b/frontend/src/documents/DocumentsTable.jsx index 0480956..26b8e69 100644 --- a/frontend/src/documents/DocumentsTable.jsx +++ b/frontend/src/documents/DocumentsTable.jsx @@ -1,7 +1,9 @@ import React, { useCallback, useEffect, useMemo, useRef } from 'react'; import { resolveDocumentAssetUrl } from '../asset_manager'; import { getTagColorStyle } from '../utils/colors'; -import { DownloadIcon, FolderIcon, EditIcon, ViewListIcon, ViewGridIcon } from '../ui/icons'; +import { DownloadIcon, EditIcon, ViewListIcon, ViewGridIcon } from '../ui/icons'; + +const FOLDER_ICON_SRC = '/folder.svg'; const TAG_MIME_TYPES = ['application/x-papercrate-tag', 'text/papercrate-tag']; @@ -368,13 +370,16 @@ const DocumentsTable = ({ }} >
- + Folder
{folder.name}
-
Folder
); @@ -545,7 +550,11 @@ const DocumentsTable = ({ >
- + Folder
diff --git a/frontend/src/index.jsx b/frontend/src/index.jsx index cecd90e..5bf57b6 100644 --- a/frontend/src/index.jsx +++ b/frontend/src/index.jsx @@ -1295,13 +1295,18 @@ const AppLayout = () => { const ensureFolderData = useCallback( - async (folderId, { force = false } = {}) => { + async (folderId, { force = false, includeDocuments = true } = {}) => { if (!force && folderContents.has(folderId)) { return folderContents.get(folderId); } const path = folderId === 'root' ? 'root' : folderId; - const { data } = await api.get(`/folders/${path}/contents`); + const params = includeDocuments + ? undefined + : { include_documents: false }; + const { data } = await api.get(`/folders/${path}/contents`, { + params, + }); const hydrated = assetManager.hydrateFolderContents(data); setFolderNodes((prev) => { @@ -1363,7 +1368,10 @@ const AppLayout = () => { visited.add(nextId); try { - const contents = await ensureFolderData(nextId, { force: false }); + const contents = await ensureFolderData(nextId, { + force: false, + includeDocuments: false, + }); const subfolders = Array.isArray(contents?.subfolders) ? contents.subfolders : []; subfolders.forEach((entry) => { if (entry?.id && !visited.has(entry.id)) { @@ -4090,7 +4098,7 @@ const AppLayout = () => { const node = folderNodes.get(folderId); if (node && !node.loaded) { try { - await ensureFolderData(folderId); + await ensureFolderData(folderId, { includeDocuments: false }); } catch (error) { notifyApiError(error, 'Failed to load folder.'); } diff --git a/frontend/src/sidebar/Sidebar.jsx b/frontend/src/sidebar/Sidebar.jsx index c373a88..508fc4d 100644 --- a/frontend/src/sidebar/Sidebar.jsx +++ b/frontend/src/sidebar/Sidebar.jsx @@ -1,5 +1,7 @@ import React, { useCallback, useMemo } from 'react'; -import { ChevronIcon, FolderIcon, TrashIcon, EditIcon } from '../ui/icons'; +import { ChevronIcon, TrashIcon, EditIcon } from '../ui/icons'; + +const FOLDER_ICON_SRC = '/folder.svg'; import { getTagColorStyle } from '../utils/colors'; const FolderNode = ({ @@ -66,7 +68,7 @@ const FolderNode = ({ )} - + Folder {node.name} {node.id !== 'root' && ( diff --git a/frontend/src/styles.css b/frontend/src/styles.css index 91abd46..4657cb7 100644 --- a/frontend/src/styles.css +++ b/frontend/src/styles.css @@ -858,11 +858,10 @@ button.icon-button.ghost:hover:not([disabled]) { padding-right: 3rem; } -.folder-row span.name .folder-icon { +.folder-row span.name .folder-icon-image { width: 1rem; height: 1rem; flex-shrink: 0; - color: var(--accent); } .folder-row:hover { @@ -1242,12 +1241,12 @@ button.icon-button.ghost:hover:not([disabled]) { display: inline-flex; align-items: center; justify-content: center; - color: var(--accent); } -.thumb-icon svg { +.thumb-icon__image { width: 32px; height: 32px; + display: block; } .documents-panel th.actions-column, @@ -1380,12 +1379,12 @@ button.icon-button.ghost:hover:not([disabled]) { justify-content: center; width: 128px; height: 128px; - color: var(--accent); } .folder-card__icon-svg { width: 100%; height: 100%; + object-fit: contain; } .folder-card__meta { @@ -1396,12 +1395,10 @@ button.icon-button.ghost:hover:not([disabled]) { } .folder-card__name { - font-weight: 600; - font-size: 0.95rem; color: var(--fg); overflow: hidden; text-overflow: ellipsis; - white-space: nowrap; + white-space: break-word; }