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 = ({
}}
>
-
+
);
@@ -545,7 +550,11 @@ const DocumentsTable = ({
>
-
+
|
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 = ({
)}
-
+
{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;
}
|