2026-07-01 16:54:32 +02:00
|
|
|
/**
|
|
|
|
|
* DMS plugin API client.
|
|
|
|
|
*
|
|
|
|
|
* All requests use the shared `apiClient` (`baseURL: '/api/v1'`) and target the
|
|
|
|
|
* DMS plugin routes under `/dms/...`.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
import { apiClient, apiDelete, apiGet, apiPatch, apiPost } from './client';
|
|
|
|
|
|
|
|
|
|
// ─── Types ─────────────────────────────────────────────────────────────────
|
|
|
|
|
|
|
|
|
|
export interface DmsFolder {
|
|
|
|
|
id: string;
|
|
|
|
|
name: string;
|
|
|
|
|
parent_id: string | null;
|
|
|
|
|
created_by: string;
|
|
|
|
|
created_at?: string | null;
|
|
|
|
|
updated_at?: string | null;
|
|
|
|
|
children?: DmsFolder[];
|
|
|
|
|
file_count?: number;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface DmsFile {
|
|
|
|
|
id: string;
|
|
|
|
|
folder_id: string | null;
|
|
|
|
|
name: string;
|
|
|
|
|
mime_type: string;
|
2026-07-20 17:31:04 +02:00
|
|
|
size_bytes?: number;
|
2026-07-01 16:54:32 +02:00
|
|
|
storage_path: string;
|
2026-08-17 14:09:00 +02:00
|
|
|
content_hash?: string | null;
|
2026-07-01 16:54:32 +02:00
|
|
|
deleted_at: string | null;
|
2026-07-20 17:31:04 +02:00
|
|
|
uploaded_by?: string;
|
2026-07-01 16:54:32 +02:00
|
|
|
created_at?: string | null;
|
|
|
|
|
updated_at?: string | null;
|
|
|
|
|
shared_with?: string[];
|
|
|
|
|
permissions?: FilePermission[];
|
2026-07-20 17:31:04 +02:00
|
|
|
access_level?: string;
|
|
|
|
|
/** @deprecated Use size_bytes instead */
|
|
|
|
|
size?: number;
|
|
|
|
|
/** @deprecated Use uploaded_by instead */
|
|
|
|
|
created_by?: string;
|
2026-08-17 14:09:00 +02:00
|
|
|
/** @deprecated Use content_hash instead */
|
|
|
|
|
checksum?: string | null;
|
2026-07-01 16:54:32 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface FilePermission {
|
|
|
|
|
id: string;
|
|
|
|
|
file_id: string;
|
|
|
|
|
user_id: string | null;
|
|
|
|
|
group_id: string | null;
|
|
|
|
|
permission: 'read' | 'write' | 'admin';
|
|
|
|
|
created_at?: string | null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface DmsShare {
|
|
|
|
|
id: string;
|
|
|
|
|
file_id: string;
|
|
|
|
|
user_id?: string | null;
|
|
|
|
|
group_id?: string | null;
|
|
|
|
|
permission: 'read' | 'write';
|
|
|
|
|
created_at?: string | null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface ShareLink {
|
|
|
|
|
id: string;
|
|
|
|
|
file_id: string;
|
|
|
|
|
token: string;
|
|
|
|
|
url: string;
|
|
|
|
|
password_protected: boolean;
|
|
|
|
|
expires_at: string | null;
|
|
|
|
|
created_at?: string | null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface EditSession {
|
|
|
|
|
id: string;
|
|
|
|
|
file_id: string;
|
|
|
|
|
session_token: string;
|
|
|
|
|
editor_url: string;
|
|
|
|
|
expires_at: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface SearchResult {
|
|
|
|
|
files: DmsFile[];
|
|
|
|
|
total: number;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ─── Payloads ──────────────────────────────────────────────────────────────
|
|
|
|
|
|
|
|
|
|
export interface CreateFolderPayload {
|
|
|
|
|
name: string;
|
|
|
|
|
parent_id?: string | null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface UpdateFolderPayload {
|
|
|
|
|
name?: string;
|
|
|
|
|
parent_id?: string | null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface UpdateFilePayload {
|
|
|
|
|
name?: string;
|
|
|
|
|
folder_id?: string | null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface SharePayload {
|
|
|
|
|
user_id?: string;
|
|
|
|
|
group_id?: string;
|
|
|
|
|
permission: 'read' | 'write';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface BulkMovePayload {
|
|
|
|
|
file_ids: string[];
|
|
|
|
|
target_folder_id: string | null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface BulkDeletePayload {
|
|
|
|
|
file_ids: string[];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface ShareLinkPayload {
|
|
|
|
|
password?: string;
|
|
|
|
|
expires_at?: string | null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ─── Folders ───────────────────────────────────────────────────────────────
|
|
|
|
|
|
|
|
|
|
export function fetchFolders(): Promise<DmsFolder[]> {
|
|
|
|
|
return apiGet<DmsFolder[]>('/dms/folders');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function createFolder(payload: CreateFolderPayload): Promise<DmsFolder> {
|
|
|
|
|
return apiPost<DmsFolder>('/dms/folders', payload);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function updateFolder(folderId: string, payload: UpdateFolderPayload): Promise<DmsFolder> {
|
|
|
|
|
return apiPatch<DmsFolder>(`/dms/folders/${folderId}`, payload);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function deleteFolder(folderId: string): Promise<void> {
|
|
|
|
|
return apiDelete<void>(`/dms/folders/${folderId}`);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ─── Files ─────────────────────────────────────────────────────────────────
|
|
|
|
|
|
|
|
|
|
export function uploadFile(
|
|
|
|
|
file: File,
|
|
|
|
|
folderId?: string | null
|
|
|
|
|
): Promise<DmsFile> {
|
|
|
|
|
const form = new FormData();
|
|
|
|
|
form.append('file', file);
|
|
|
|
|
if (folderId) form.append('folder_id', folderId);
|
|
|
|
|
return apiPost<DmsFile>('/dms/files/upload', form, {
|
|
|
|
|
headers: { 'Content-Type': 'multipart/form-data' },
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function getFile(fileId: string): Promise<DmsFile> {
|
|
|
|
|
return apiGet<DmsFile>(`/dms/files/${fileId}`);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function updateFile(fileId: string, payload: UpdateFilePayload): Promise<DmsFile> {
|
|
|
|
|
return apiPatch<DmsFile>(`/dms/files/${fileId}`, payload);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function deleteFile(fileId: string): Promise<void> {
|
|
|
|
|
return apiDelete<void>(`/dms/files/${fileId}`);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function restoreFile(fileId: string): Promise<DmsFile> {
|
|
|
|
|
return apiPost<DmsFile>(`/dms/files/${fileId}/restore`);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function getFilePreviewUrl(fileId: string): string {
|
|
|
|
|
return `/api/v1/dms/files/${fileId}/preview`;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function createEditSession(fileId: string): Promise<EditSession> {
|
|
|
|
|
return apiPost<EditSession>(`/dms/files/${fileId}/edit-session`);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function shareFile(fileId: string, payload: SharePayload): Promise<DmsShare> {
|
|
|
|
|
return apiPost<DmsShare>(`/dms/files/${fileId}/share`, payload);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function removeShare(fileId: string, shareId: string): Promise<void> {
|
|
|
|
|
return apiDelete<void>(`/dms/files/${fileId}/share`, { data: { share_id: shareId } });
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ─── Search & Shared ───────────────────────────────────────────────────────
|
|
|
|
|
|
|
|
|
|
export function searchFiles(query: string): Promise<SearchResult> {
|
|
|
|
|
const qs = new URLSearchParams({ q: query }).toString();
|
|
|
|
|
return apiGet<SearchResult>(`/dms/search?${qs}`);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function getSharedWithMe(): Promise<DmsFile[]> {
|
2026-07-26 01:35:03 +02:00
|
|
|
return apiGet<DmsFile[] | { items: DmsFile[] }>('/dms/shared-with-me').then(r => Array.isArray(r) ? r : r.items ?? []);
|
2026-07-01 16:54:32 +02:00
|
|
|
}
|
|
|
|
|
|
2026-07-20 17:31:04 +02:00
|
|
|
export function fetchSharedWithMe(): Promise<DmsFile[]> {
|
|
|
|
|
return getSharedWithMe();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function fetchFilesByFolder(folderId: string): Promise<DmsFile[]> {
|
|
|
|
|
return apiGet<DmsFile[]>(`/dms/folders/${folderId}/files`);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function fetchAllFiles(): Promise<DmsFile[]> {
|
|
|
|
|
return apiGet<DmsFile[]>('/dms/files');
|
|
|
|
|
}
|
|
|
|
|
|
2026-07-01 16:54:32 +02:00
|
|
|
// ─── Bulk Operations ───────────────────────────────────────────────────────
|
|
|
|
|
|
|
|
|
|
export function bulkMoveFiles(payload: BulkMovePayload): Promise<void> {
|
|
|
|
|
return apiPost<void>('/dms/files/bulk-move', payload);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function bulkDeleteFiles(payload: BulkDeletePayload): Promise<void> {
|
|
|
|
|
return apiPost<void>('/dms/files/bulk-delete', payload);
|
|
|
|
|
}
|