Mega push vol 5, working on messaging now

This commit is contained in:
AlacrisDevs
2026-02-07 01:31:55 +02:00
parent d8bbfd9dc3
commit e55881b38b
77 changed files with 8478 additions and 1554 deletions

View File

@@ -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');

View File

@@ -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;

View File

@@ -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;

View File

@@ -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">

View File

@@ -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');