Mega push vol 5, working on messaging now
This commit is contained in:
@@ -1,15 +1,16 @@
|
||||
import type { PageServerLoad } from './$types';
|
||||
import type { OrgLayoutData } from '$lib/types/layout';
|
||||
import { createLogger } from '$lib/utils/logger';
|
||||
|
||||
const log = createLogger('page.documents');
|
||||
|
||||
export const load: PageServerLoad = async ({ parent, locals }) => {
|
||||
const { org } = await parent();
|
||||
const { org } = await parent() as OrgLayoutData;
|
||||
const { supabase } = locals;
|
||||
|
||||
const { data: documents, error } = await supabase
|
||||
.from('documents')
|
||||
.select('*')
|
||||
.select('id, name, type, parent_id, path, position, created_at, updated_at, created_by, org_id')
|
||||
.eq('org_id', org.id)
|
||||
.order('name');
|
||||
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
import type { PageServerLoad } from './$types';
|
||||
import type { OrgLayoutData } from '$lib/types/layout';
|
||||
import { error, redirect } from '@sveltejs/kit';
|
||||
import { createLogger } from '$lib/utils/logger';
|
||||
|
||||
const log = createLogger('page.document');
|
||||
|
||||
export const load: PageServerLoad = async ({ parent, locals, params }) => {
|
||||
const { org } = await parent() as { org: { id: string; slug: string } };
|
||||
const { org } = await parent() as OrgLayoutData;
|
||||
const { supabase } = locals;
|
||||
const { id } = params;
|
||||
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
import type { PageServerLoad } from './$types';
|
||||
import type { OrgLayoutData } from '$lib/types/layout';
|
||||
import { error, redirect } from '@sveltejs/kit';
|
||||
import { createLogger } from '$lib/utils/logger';
|
||||
|
||||
const log = createLogger('page.file');
|
||||
|
||||
export const load: PageServerLoad = async ({ parent, locals, params }) => {
|
||||
const { org, user } = await parent() as { org: { id: string; slug: string }; user: { id: string } | null };
|
||||
const { org, user } = await parent() as OrgLayoutData;
|
||||
const { supabase } = locals;
|
||||
const { id } = params;
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<script lang="ts">
|
||||
import { getContext, onDestroy, onMount } from "svelte";
|
||||
import { Button, Modal, Input } from "$lib/components/ui";
|
||||
import { Button, Modal, Input, ContextMenu } from "$lib/components/ui";
|
||||
import { DocumentViewer } from "$lib/components/documents";
|
||||
import { KanbanBoard, CardDetailModal } from "$lib/components/kanban";
|
||||
import {
|
||||
@@ -197,9 +197,11 @@
|
||||
$effect(() => {
|
||||
if (!kanbanBoard) return;
|
||||
|
||||
const colIds = kanbanBoard.columns.map((c) => c.id);
|
||||
const channel = subscribeToBoard(
|
||||
supabase,
|
||||
kanbanBoard.id,
|
||||
colIds,
|
||||
() => loadKanbanBoard(),
|
||||
() => loadKanbanBoard(),
|
||||
);
|
||||
@@ -212,15 +214,34 @@
|
||||
};
|
||||
});
|
||||
|
||||
// Reliable lock release via sendBeacon (survives page unload)
|
||||
function beaconReleaseLock() {
|
||||
if (hasLock && data.user) {
|
||||
navigator.sendBeacon(
|
||||
"/api/release-lock",
|
||||
JSON.stringify({ documentId: data.document.id }),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
onMount(() => {
|
||||
window.addEventListener("beforeunload", beaconReleaseLock);
|
||||
return () =>
|
||||
window.removeEventListener("beforeunload", beaconReleaseLock);
|
||||
});
|
||||
|
||||
onDestroy(() => {
|
||||
if (realtimeChannel) {
|
||||
supabase.removeChannel(realtimeChannel);
|
||||
}
|
||||
// Release document lock
|
||||
// Release document lock (SPA navigation — sendBeacon as fallback)
|
||||
if (hasLock && data.user) {
|
||||
stopHeartbeat?.();
|
||||
releaseLock(supabase, data.document.id, data.user.id);
|
||||
}
|
||||
if (typeof window !== "undefined") {
|
||||
window.removeEventListener("beforeunload", beaconReleaseLock);
|
||||
}
|
||||
});
|
||||
|
||||
async function handleCardMove(
|
||||
@@ -441,23 +462,27 @@
|
||||
<h1 class="flex-1 font-heading text-h1 text-white truncate">
|
||||
{data.document.name}
|
||||
</h1>
|
||||
<Button
|
||||
variant="tertiary"
|
||||
size="sm"
|
||||
icon="upload"
|
||||
onclick={triggerImport}
|
||||
loading={isImporting}
|
||||
>
|
||||
Import JSON
|
||||
</Button>
|
||||
<Button
|
||||
variant="tertiary"
|
||||
size="sm"
|
||||
icon="download"
|
||||
onclick={handleExportJson}
|
||||
>
|
||||
Export JSON
|
||||
</Button>
|
||||
<ContextMenu
|
||||
items={[
|
||||
{
|
||||
label: "Import JSON",
|
||||
icon: "upload",
|
||||
onclick: triggerImport,
|
||||
},
|
||||
{
|
||||
label: "Export JSON",
|
||||
icon: "download",
|
||||
onclick: handleExportJson,
|
||||
},
|
||||
{ divider: true, label: "", icon: "", onclick: () => {} },
|
||||
{
|
||||
label: "Rename Board",
|
||||
icon: "edit",
|
||||
onclick: () =>
|
||||
toasts.info("Rename from the documents list."),
|
||||
},
|
||||
]}
|
||||
/>
|
||||
</header>
|
||||
|
||||
<div class="flex-1 overflow-auto min-h-0">
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
import type { PageServerLoad } from './$types';
|
||||
import type { OrgLayoutData } from '$lib/types/layout';
|
||||
import { error } from '@sveltejs/kit';
|
||||
import { createLogger } from '$lib/utils/logger';
|
||||
|
||||
const log = createLogger('page.folder');
|
||||
|
||||
export const load: PageServerLoad = async ({ parent, locals, params }) => {
|
||||
const { org, user } = await parent() as { org: { id: string; slug: string }; user: { id: string } | null };
|
||||
const { org, user } = await parent() as OrgLayoutData;
|
||||
const { supabase } = locals;
|
||||
const { id } = params;
|
||||
|
||||
@@ -13,7 +14,7 @@ export const load: PageServerLoad = async ({ parent, locals, params }) => {
|
||||
|
||||
const { data: document, error: docError } = await supabase
|
||||
.from('documents')
|
||||
.select('*')
|
||||
.select('id, name, type, parent_id, path, position, created_at, updated_at, created_by, org_id')
|
||||
.eq('org_id', org.id)
|
||||
.eq('id', id)
|
||||
.single();
|
||||
@@ -31,7 +32,7 @@ export const load: PageServerLoad = async ({ parent, locals, params }) => {
|
||||
// Load all documents in this org (for breadcrumb building and file listing)
|
||||
const { data: allDocuments } = await supabase
|
||||
.from('documents')
|
||||
.select('*')
|
||||
.select('id, name, type, parent_id, path, position, created_at, updated_at, created_by, org_id')
|
||||
.eq('org_id', org.id)
|
||||
.order('name');
|
||||
|
||||
|
||||
Reference in New Issue
Block a user