Session 2026-05-30: tasks/projects unification, code consolidation, file renames
- Unified Tasks page: 3 role render blocks → 1, normalized row shape, single renderRow/sort/tabs - Fixed role scoping: external = all tasks in member projects, client = all tasks in company projects - Fixed client bug: was scoped by submitted_by, now company→project→tasks - Aligned dashboard client scope to match tasks page - Hot tasks dashboard: now filters to active statuses only (not completed/invoiced/paid) - Removed Projects.jsx (dead), fixed /project/ → /projects/ links - Renamed all page files to match folder path (Team*, External*, Client* prefixes) - Renamed: RequestsPage→Tasks, Settings→Profile, CompaniesPage→Companies, ProjectDetailPage→ProjectDetail - Dropped dead fetches from Tasks page (invoices, invoice_items, subcontractor_invoice_items) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -215,10 +215,29 @@ Deno.serve(async (req) => {
|
||||
}
|
||||
|
||||
if (op === 'download') {
|
||||
const res = await fetch(`${FBQ_URL}/api/raw?source=${SOURCE}&path=${encodeURIComponent(resolvedPath)}`, { headers: fbqHeaders });
|
||||
const ct = res.headers.get('content-type') ?? 'application/octet-stream';
|
||||
const cd = res.headers.get('content-disposition') ?? `attachment; filename="${resolvedPath.split('/').pop()}"`;
|
||||
return new Response(res.body, { status: res.status, headers: { ...cors(origin), 'Content-Type': ct, 'Content-Disposition': cd } });
|
||||
const rawUrl = `${FBQ_URL}/api/raw?source=${SOURCE}&path=${encodeURIComponent(resolvedPath)}`;
|
||||
const rawRes = await fetch(rawUrl, { headers: fbqHeaders });
|
||||
|
||||
if (rawRes.ok) {
|
||||
const ct = rawRes.headers.get('content-type') ?? 'application/octet-stream';
|
||||
const cd = rawRes.headers.get('content-disposition') ?? `attachment; filename="${resolvedPath.split('/').pop()}"`;
|
||||
return new Response(rawRes.body, { status: rawRes.status, headers: { ...cors(origin), 'Content-Type': ct, 'Content-Disposition': cd } });
|
||||
}
|
||||
|
||||
const rawErrorText = await rawRes.text();
|
||||
const shouldFallbackToResourcesDownload = rawRes.status === 400 && rawErrorText.toLowerCase().includes('no files specified');
|
||||
if (!shouldFallbackToResourcesDownload) {
|
||||
return new Response(rawErrorText, { status: rawRes.status, headers: { ...cors(origin), 'Content-Type': 'application/json' } });
|
||||
}
|
||||
|
||||
const directDownloadUrl = `${FBQ_URL}/api/resources/download?source=${SOURCE}&file=${encodeURIComponent(resolvedPath)}`;
|
||||
const directRes = await fetch(directDownloadUrl, { headers: fbqHeaders });
|
||||
const directCt = directRes.headers.get('content-type') ?? 'application/octet-stream';
|
||||
const directCd = directRes.headers.get('content-disposition') ?? `attachment; filename="${resolvedPath.split('/').pop() ?? 'download'}"`;
|
||||
return new Response(directRes.body, {
|
||||
status: directRes.status,
|
||||
headers: { ...cors(origin), 'Content-Type': directCt, 'Content-Disposition': directCd },
|
||||
});
|
||||
}
|
||||
|
||||
if (op === 'upload') {
|
||||
|
||||
Reference in New Issue
Block a user