From 4b75383460db2887808c2d8556af2c6bff3209ec Mon Sep 17 00:00:00 2001 From: Philipinho <16838612+Philipinho@users.noreply.github.com> Date: Tue, 28 Apr 2026 18:34:12 +0100 Subject: [PATCH] fix(base): store file-cell URLs in the editor's /api/files/{id}/{name} shape MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The file-cell value was storing the raw S3 storage path returned by attachmentService (e.g. "01944.../files/019dd.../AlgoExpert_Receipt.pdf"), which the browser can't fetch as-is — and the cell never built it into a clickable link anyway. Match the editor's attachment node-view pattern: store url as "/api/files/{id}/{fileName}" on upload and resolve it through getFileUrl when rendering. The dropdown's file rows are now links so the user can actually open the attached file. `buildFileUrl` falls back to constructing the path from id+fileName for any pre-existing values that still carry the old shape, so already-uploaded attachments don't break. --- .../base/components/cells/cell-file.tsx | 29 ++++++++++++++++--- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/apps/client/src/features/base/components/cells/cell-file.tsx b/apps/client/src/features/base/components/cells/cell-file.tsx index b279fee35..0a6522fb6 100644 --- a/apps/client/src/features/base/components/cells/cell-file.tsx +++ b/apps/client/src/features/base/components/cells/cell-file.tsx @@ -9,15 +9,26 @@ import { import { IBaseProperty } from "@/features/base/types/base.types"; import cellClasses from "@/features/base/styles/cells.module.css"; import { uploadFile } from "@/features/page/services/page-service"; +import { getFileUrl } from "@/lib/config"; export type FileValue = { id: string; fileName: string; mimeType?: string; fileSize?: number; - filePath?: string; + // `/api/files/{id}/{fileName}` — same shape the editor's attachment + // node view uses. `getFileUrl` strips the `/api/` prefix and + // prepends the backend host to produce a fetchable URL. Stored on + // upload so the original filename round-trips even if the cell + // value is moved to a row where the file's storage path no longer + // resolves from the cell's pageId. + url?: string; }; +function buildFileUrl(file: Pick): string { + return file.url ?? `/api/files/${file.id}/${encodeURIComponent(file.fileName)}`; +} + type CellFileProps = { value: unknown; property: IBaseProperty; @@ -82,7 +93,7 @@ export function CellFile({ fileName: attachment.fileName, mimeType: attachment.mimeType, fileSize: attachment.fileSize, - filePath: attachment.filePath, + url: `/api/files/${attachment.id}/${encodeURIComponent(attachment.fileName)}`, }); } catch (err) { console.error("File upload failed:", err); @@ -147,7 +158,17 @@ export function CellFile({ color: "var(--mantine-color-gray-6)", }} /> -
+ {file.fileName} @@ -156,7 +177,7 @@ export function CellFile({ {formatFileSize(file.fileSize)} )} -
+