This commit is contained in:
2025-10-30 14:41:15 +01:00
parent 86be6256a4
commit 67fd787a14
9 changed files with 23 additions and 60 deletions
+1 -18
View File
@@ -49,24 +49,7 @@ services:
command: >
/bin/sh -c "
echo 'Running database migrations' &&
diesel migration run &&
echo 'Ensuring tenant admin exists' &&
if papercrate-admin list-tenants | grep -q '^admin '; then
echo 'tenant admin already exists';
else
papercrate-admin create-tenant admin;
fi &&
ADMIN_TENANT_ID=$(papercrate-admin list-tenants | awk '/^admin / {print $2; exit}') &&
if [ -z "$ADMIN_TENANT_ID" ]; then
echo 'failed to resolve admin tenant id' >&2;
exit 1;
fi &&
echo 'Ensuring demo user credentials' &&
(papercrate-admin create-user admin adminadmin || papercrate-admin set-password admin adminadmin) &&
echo 'Ensuring demo membership' &&
papercrate-admin add-user-to-tenant admin "$ADMIN_TENANT_ID" &&
echo 'Ensuring Quickwit index for admin tenant' &&
papercrate-admin quickwit-create-index "$ADMIN_TENANT_ID"
diesel migration run
"
user: root
restart: "no"
+1 -18
View File
@@ -84,24 +84,7 @@ services:
command: >
/bin/sh -c "
echo 'Running database migrations' &&
diesel migration run &&
echo 'Ensuring tenant admin exists' &&
if papercrate-admin list-tenants | grep -q '^admin '; then
echo 'tenant admin already exists';
else
papercrate-admin create-tenant admin;
fi &&
ADMIN_TENANT_ID=$(papercrate-admin list-tenants | awk '/^admin / {print $2; exit}') &&
if [ -z "$ADMIN_TENANT_ID" ]; then
echo 'failed to resolve admin tenant id' >&2;
exit 1;
fi &&
echo 'Ensuring demo user credentials' &&
(papercrate-admin create-user admin adminadmin || papercrate-admin set-password admin adminadmin) &&
echo 'Ensuring demo membership' &&
papercrate-admin add-user-to-tenant admin "$ADMIN_TENANT_ID" &&
echo 'Ensuring Quickwit index for admin tenant' &&
papercrate-admin quickwit-create-index "$ADMIN_TENANT_ID"
diesel migration run
"
user: root
restart: "no"
+1 -1
View File
@@ -39,7 +39,7 @@ npm run build
- Drag-and-drop moves (documents between folders) and file uploads (window-wide or onto a folder)
- Search box plus tag chips filter documents across the selected folder and all descendants
- Tag management (create/assign/remove) from the detail panel
- Login via the seeded admin account (`admin` / `adminadmin`) with stored JWT session
- Login with a WebAuthn passkey created through the signup flow (no baked-in demo account)
- Inline status banner for quick feedback on API interactions
## Assets
+1 -4
View File
@@ -23,9 +23,6 @@ const DEFAULT_CANVAS_WIDTH = 1024;
const DEFAULT_CANVAS_HEIGHT = 680;
const TAG_MIME_TYPES = ['application/x-papercrate-tag', 'text/papercrate-tag'];
const resolveSizeKey = (doc) =>
doc?.id || doc?.document_id || doc?.uuid || doc?.original_name || doc?.title || 'doc';
const CARD_MIN = 240;
const CARD_MAX = 340;
const TAG_REMOVE_DISTANCE = 160;
@@ -1170,7 +1167,7 @@ const syncLayoutSnapshot = useCallback(() => {
id: doc.id,
width: docWidth,
height: docHeight,
seedKey: resolveSizeKey(doc),
seedKey: doc.id,
});
});
+6 -6
View File
@@ -125,7 +125,7 @@ const TagSection = ({
{datalistId ? (
<datalist id={datalistId}>
{datalistOptions.map((option) => (
<option key={option.id || option.label || option} value={option.label || option} />
<option key={option.id} />
))}
</datalist>
) : null}
@@ -456,7 +456,7 @@ const DetailPanel = ({
id: doc.id,
url,
orientation,
alt: doc.title || doc.original_name || 'Document preview',
alt: doc.title,
};
},
[ensureAssetUrl, getDocumentAsset],
@@ -500,7 +500,7 @@ const DetailPanel = ({
id: singleDoc.id,
url,
orientation,
alt: singleDoc.title || singleDoc.original_name || 'Document preview',
alt: singleDoc.title,
},
];
}, [singleDoc, singlePreviewNavigator.currentUrl, singlePreviewNavigator.currentMetadata]);
@@ -522,7 +522,7 @@ const DetailPanel = ({
id: doc.id,
url,
orientation,
alt: doc.title || doc.original_name || 'Document preview',
alt: doc.title,
};
}
return makePreviewItem(doc, 1);
@@ -724,7 +724,7 @@ const DetailPanel = ({
) {
return {
url: singlePreviewNavigator.currentUrl,
alt: singleDoc.title || singleDoc.original_name || 'Document preview',
alt: singleDoc.title,
canGoPrev:
singleEffectiveCardinality > 1 && Boolean(singlePreviewNavigator.canGoPrev),
canGoNext:
@@ -743,7 +743,7 @@ const DetailPanel = ({
) {
return {
url: stackPreviewNavigator.currentUrl,
alt: stackTopDocument.title || stackTopDocument.original_name || 'Document preview',
alt: stackTopDocument.title,
canGoPrev:
topEffectiveCardinality > 1 && Boolean(stackPreviewNavigator.canGoPrev),
canGoNext:
+5 -5
View File
@@ -34,8 +34,8 @@ const resolveCorrespondents = (doc) => {
doc.correspondents.forEach((entry, index) => {
if (!entry) return;
const id = entry.id ?? entry.correspondent_id ?? null;
const name = (entry.name || entry.label || entry.slug || '').trim();
const id = entry.id;
const name = entry.name.trim();
if (!name) return;
if (id && seen.has(id)) {
@@ -951,7 +951,7 @@ const DocumentsTable = ({
</td>
<td>
{(() => {
const issuedAt = doc.issued_at || doc.updated_at || null;
const issuedAt = doc.issued_at || null;
if (!issuedAt) {
return '—';
}
@@ -974,13 +974,13 @@ const DocumentsTable = ({
event.stopPropagation();
const nextName = window.prompt(
'Rename document',
doc.title || doc.original_name || '',
doc.title
);
if (!nextName) {
return;
}
const trimmed = nextName.trim();
if (!trimmed || trimmed === (doc.title || doc.original_name)) {
if (!trimmed || trimmed === doc.title) {
return;
}
onDocumentRename(doc.id, trimmed);
+1 -1
View File
@@ -4498,7 +4498,7 @@ const AppLayout = () => {
}
const doc = documentLookup.get(documentId) || null;
const label = doc?.title || doc?.original_name || 'this document';
const label = doc?.title;
const confirmed = window.confirm(`Move "${label}" to trash? You can restore it from trash later.`);
if (!confirmed) {
+6 -6
View File
@@ -11,14 +11,14 @@ const PreviewWorkspace = ({
return null;
}
const title = document.title || document.original_name || 'Document';
const mime = previewEntry?.contentType || document.content_type || 'application/pdf';
const title = document.title;
const mime = document.content_type;
const sizeBytes = Number(document.current_version?.size_bytes) || 0;
const sizeLabel = sizeBytes > 0 ? formatFileSize(sizeBytes) : null;
const metadata =
document.metadata && Object.keys(document.metadata).length > 0 ? document.metadata : null;
const folderName = document.folder_path || document.folder_name || null;
const issuedAt = document.issued_at || document.current_version?.issued_at || null;
const issuedAt = document.issued_at || null;
const createdAt = document.created_at || null;
const updatedAt = document.updated_at || null;
const tags = Array.isArray(document.tags) ? document.tags : [];
@@ -33,13 +33,13 @@ const PreviewWorkspace = ({
if (updatedAt) rows.push(['Updated', new Date(updatedAt).toLocaleString()]);
if (folderName) rows.push(['Folder', folderName]);
if (tags.length) {
rows.push(['Tags', tags.map((tag) => tag.label || tag.name || tag.slug).filter(Boolean).join(', ')]);
rows.push(['Tags', tags.map((tag) => tag.label).filter(Boolean).join(', ')]);
}
if (correspondents.length) {
rows.push([
'Correspondents',
correspondents
.map((entry) => entry.name || entry.label || entry.slug)
.map((entry) => entry.name)
.filter(Boolean)
.join(', '),
]);
@@ -173,7 +173,7 @@ export const createPreviewSurface = ({
return null;
}
const title = document.title || document.original_name || 'Document preview';
const title = document.title;
const sidebarToggle = renderSidebarToggle ? renderSidebarToggle() : null;
const closeButton = onClose
? (
+1 -1
View File
@@ -382,7 +382,7 @@ const Sidebar = ({
{tenants.map((tenant) => {
const tenantId = tenant?.id || null;
const isActive = tenantId === activeTenantId;
const tenantLabel = tenant?.name || tenant?.slug || tenantId || 'Tenant';
const tenantLabel = tenant?.name;
return (
<button
key={tenantId || tenantLabel}