feat: integrate files and portal surfaces

This commit is contained in:
2026-08-07 14:53:46 +02:00
parent 60f50f7906
commit 11f175cbb3
13 changed files with 512 additions and 13 deletions
+49
View File
@@ -2,6 +2,8 @@ import {
apiFetch,
apiPath,
apiPostJson,
apiUrl,
authHeaders,
type ApiSettings
} from "@govoplan/core-webui";
@@ -62,6 +64,15 @@ export type PostboxAttachment = {
metadata: Record<string, unknown>;
};
export type PostboxAttachmentResolution = PostboxAttachment & {
available: boolean;
reason_code: string;
file_asset_id?: string | null;
file_version_id?: string | null;
download_path?: string | null;
provenance: Record<string, unknown>;
};
export type PostboxMessage = {
id: string;
tenant_id: string;
@@ -200,6 +211,7 @@ export type PostboxTemplateRevision = {
address_pattern: string;
classification: string;
allow_vacant_delivery: boolean;
portal_visible: boolean;
encryption_profile: string;
history_policy: Record<string, unknown>;
routing_policy: PostboxRoutingPolicy;
@@ -235,6 +247,7 @@ export type PostboxTemplateRevisionPayload = Pick<
| "address_pattern"
| "classification"
| "allow_vacant_delivery"
| "portal_visible"
| "routing_policy"
>;
@@ -276,6 +289,7 @@ export type PostboxExactCreatePayload = {
function_id: string;
address_key?: string | null;
classification: string;
portal_visible: boolean;
};
export type PostboxMessageAuthoringPayload = {
@@ -328,6 +342,41 @@ export function getPostboxMessage(
return apiFetch(settings, `/api/v1/postbox/messages/${encodeURIComponent(messageId)}`);
}
export async function resolvePostboxAttachments(
settings: ApiSettings,
messageId: string
): Promise<PostboxAttachmentResolution[]> {
const response = await apiFetch<{ attachments: PostboxAttachmentResolution[] }>(
settings,
`/api/v1/postbox/messages/${encodeURIComponent(messageId)}/attachment-resolutions`
);
return response.attachments;
}
export async function downloadPostboxAttachment(
settings: ApiSettings,
attachment: PostboxAttachmentResolution
): Promise<void> {
if (!attachment.available || !attachment.download_path) {
throw new Error("This attachment payload is not available.");
}
const response = await fetch(apiUrl(settings, attachment.download_path), {
headers: authHeaders(settings),
credentials: "include"
});
if (!response.ok) {
throw new Error(`Attachment download failed (${response.status}).`);
}
const objectUrl = URL.createObjectURL(await response.blob());
const link = document.createElement("a");
link.href = objectUrl;
link.download = attachment.name || attachment.reference_id;
document.body.appendChild(link);
link.click();
link.remove();
URL.revokeObjectURL(objectUrl);
}
export function markPostboxMessage(
settings: ApiSettings,
messageId: string,