feat(phase-4): frontend data layer — API client (13 new functions), folders store, documents store extensions, routes
- Extended listDocuments to accept folderId, q, sort, order query params - Added 6 folder API functions: listFolders, createFolder, getFolder, renameFolder, deleteFolder, moveDocument - Added 4 share API functions: createShare, listShares, deleteShare, getSharedWithMe - Added 2 preference API functions: getMyPreferences, updateMyPreferences - Added getDocumentContentUrl helper (returns URL string, no fetch) - Created useFoldersStore with full CRUD, navigation state, and breadcrumb support - Extended useDocumentsStore with currentFolderId, searchQuery, sortField, sortOrder refs - Added debounced searchQuery watcher (300ms, 2-char minimum, T-04-08-03) - Added shareDocument, revokeShare, listShares actions to documents store - Added /folders/:folderId and /shared routes with requiresAuth guard
This commit is contained in:
@@ -57,9 +57,13 @@ async function request(path, options = {}) {
|
||||
|
||||
// ── Documents ────────────────────────────────────────────────────────────────
|
||||
|
||||
export function listDocuments({ topic, page = 1, perPage = 20 } = {}) {
|
||||
export function listDocuments({ topic, page = 1, perPage = 20, folderId = null, q = null, sort = null, order = null } = {}) {
|
||||
const params = new URLSearchParams({ page, per_page: perPage })
|
||||
if (topic) params.set('topic', topic)
|
||||
if (folderId != null) params.set('folder_id', folderId)
|
||||
if (q) params.set('q', q)
|
||||
if (sort) params.set('sort', sort)
|
||||
if (order) params.set('order', order)
|
||||
return request(`/api/documents?${params}`)
|
||||
}
|
||||
|
||||
@@ -263,3 +267,86 @@ export function adminUpdateAiConfig(id, provider, model) {
|
||||
body: JSON.stringify({ ai_provider: provider, ai_model: model }),
|
||||
})
|
||||
}
|
||||
|
||||
// ── Folders ───────────────────────────────────────────────────────────────────
|
||||
|
||||
export function listFolders(parentId = null) {
|
||||
const params = new URLSearchParams()
|
||||
if (parentId != null) params.set('parent_id', parentId)
|
||||
const qs = params.toString()
|
||||
return request(`/api/folders${qs ? `?${qs}` : ''}`)
|
||||
}
|
||||
|
||||
export function createFolder(name, parentId = null) {
|
||||
return request('/api/folders', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ name, parent_id: parentId || null }),
|
||||
})
|
||||
}
|
||||
|
||||
export function getFolder(folderId) {
|
||||
return request(`/api/folders/${folderId}`)
|
||||
}
|
||||
|
||||
export function renameFolder(folderId, name) {
|
||||
return request(`/api/folders/${folderId}`, {
|
||||
method: 'PATCH',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ name }),
|
||||
})
|
||||
}
|
||||
|
||||
export function deleteFolder(folderId) {
|
||||
return request(`/api/folders/${folderId}`, { method: 'DELETE' })
|
||||
}
|
||||
|
||||
export function moveDocument(docId, folderId) {
|
||||
return request(`/api/documents/${docId}/folder`, {
|
||||
method: 'PATCH',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ folder_id: folderId || null }),
|
||||
})
|
||||
}
|
||||
|
||||
// ── Shares ────────────────────────────────────────────────────────────────────
|
||||
|
||||
export function createShare(docId, recipientHandle) {
|
||||
return request('/api/shares', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ document_id: docId, recipient_handle: recipientHandle }),
|
||||
})
|
||||
}
|
||||
|
||||
export function listShares(docId) {
|
||||
return request(`/api/shares?document_id=${docId}`)
|
||||
}
|
||||
|
||||
export function deleteShare(shareId) {
|
||||
return request(`/api/shares/${shareId}`, { method: 'DELETE' })
|
||||
}
|
||||
|
||||
export function getSharedWithMe() {
|
||||
return request('/api/shares/received')
|
||||
}
|
||||
|
||||
// ── Preferences ───────────────────────────────────────────────────────────────
|
||||
|
||||
export function getMyPreferences() {
|
||||
return request('/api/auth/me/preferences')
|
||||
}
|
||||
|
||||
export function updateMyPreferences(payload) {
|
||||
return request('/api/auth/me/preferences', {
|
||||
method: 'PATCH',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(payload),
|
||||
})
|
||||
}
|
||||
|
||||
// ── Document content proxy URL ────────────────────────────────────────────────
|
||||
|
||||
export function getDocumentContentUrl(docId) {
|
||||
return `/api/documents/${docId}/content`
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user