Mega push vol1
This commit is contained in:
@@ -22,9 +22,12 @@
|
||||
let documents = $state(data.documents);
|
||||
let selectedDoc = $state<Document | null>(null);
|
||||
let showCreateModal = $state(false);
|
||||
let showEditModal = $state(false);
|
||||
let editingDoc = $state<Document | null>(null);
|
||||
let newDocName = $state("");
|
||||
let newDocType = $state<"folder" | "document">("document");
|
||||
let parentFolderId = $state<string | null>(null);
|
||||
let isEditing = $state(false);
|
||||
|
||||
const documentTree = $derived(buildDocumentTree(documents));
|
||||
|
||||
@@ -99,8 +102,72 @@
|
||||
d.id === selectedDoc!.id ? { ...d, content } : d,
|
||||
);
|
||||
}
|
||||
|
||||
function handleEdit(doc: Document) {
|
||||
editingDoc = doc;
|
||||
newDocName = doc.name;
|
||||
showEditModal = true;
|
||||
}
|
||||
|
||||
async function handleRename() {
|
||||
if (!editingDoc || !newDocName.trim()) return;
|
||||
|
||||
const { error } = await supabase
|
||||
.from("documents")
|
||||
.update({ name: newDocName, updated_at: new Date().toISOString() })
|
||||
.eq("id", editingDoc.id);
|
||||
|
||||
if (!error) {
|
||||
documents = documents.map((d) =>
|
||||
d.id === editingDoc!.id ? { ...d, name: newDocName } : d,
|
||||
);
|
||||
if (selectedDoc?.id === editingDoc.id) {
|
||||
selectedDoc = { ...selectedDoc, name: newDocName };
|
||||
}
|
||||
}
|
||||
showEditModal = false;
|
||||
editingDoc = null;
|
||||
newDocName = "";
|
||||
}
|
||||
|
||||
async function handleDelete(doc: Document) {
|
||||
const itemType =
|
||||
doc.type === "folder" ? "folder and all its contents" : "document";
|
||||
if (!confirm(`Delete this ${itemType}?`)) return;
|
||||
|
||||
// If deleting a folder, delete all children first
|
||||
if (doc.type === "folder") {
|
||||
const childIds = documents
|
||||
.filter((d) => d.parent_id === doc.id)
|
||||
.map((d) => d.id);
|
||||
if (childIds.length > 0) {
|
||||
await supabase.from("documents").delete().in("id", childIds);
|
||||
}
|
||||
}
|
||||
|
||||
const { error } = await supabase
|
||||
.from("documents")
|
||||
.delete()
|
||||
.eq("id", doc.id);
|
||||
|
||||
if (!error) {
|
||||
documents = documents.filter(
|
||||
(d) => d.id !== doc.id && d.parent_id !== doc.id,
|
||||
);
|
||||
if (selectedDoc?.id === doc.id) {
|
||||
selectedDoc = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<title
|
||||
>{selectedDoc ? `${selectedDoc.name} - ` : ""}Documents - {data.org
|
||||
.name} | Root</title
|
||||
>
|
||||
</svelte:head>
|
||||
|
||||
<div class="flex h-full">
|
||||
<aside class="w-72 border-r border-light/10 flex flex-col">
|
||||
<div
|
||||
@@ -109,7 +176,7 @@
|
||||
<h2 class="font-semibold text-light">Documents</h2>
|
||||
<Button size="sm" onclick={() => (showCreateModal = true)}>
|
||||
<svg
|
||||
class="w-4 h-4 mr-1"
|
||||
class="w-4 h-4"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
@@ -118,7 +185,6 @@
|
||||
<line x1="12" y1="5" x2="12" y2="19" />
|
||||
<line x1="5" y1="12" x2="19" y2="12" />
|
||||
</svg>
|
||||
New
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
@@ -135,14 +201,37 @@
|
||||
onSelect={handleSelect}
|
||||
onAdd={handleAdd}
|
||||
onMove={handleMove}
|
||||
onEdit={handleEdit}
|
||||
onDelete={handleDelete}
|
||||
/>
|
||||
{/if}
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
<main class="flex-1 overflow-hidden">
|
||||
<main class="flex-1 overflow-hidden flex flex-col">
|
||||
{#if selectedDoc}
|
||||
<Editor document={selectedDoc} onSave={handleSave} />
|
||||
<div
|
||||
class="flex items-center justify-between p-4 border-b border-light/10"
|
||||
>
|
||||
<h2 class="text-lg font-semibold text-light">
|
||||
{selectedDoc.name}
|
||||
</h2>
|
||||
<button
|
||||
class="px-4 py-2 rounded-lg text-sm font-medium transition-colors {isEditing
|
||||
? 'bg-primary text-white'
|
||||
: 'bg-light/10 text-light hover:bg-light/20'}"
|
||||
onclick={() => (isEditing = !isEditing)}
|
||||
>
|
||||
{isEditing ? "Preview" : "Edit"}
|
||||
</button>
|
||||
</div>
|
||||
<div class="flex-1 overflow-auto">
|
||||
<Editor
|
||||
document={selectedDoc}
|
||||
onSave={handleSave}
|
||||
editable={isEditing}
|
||||
/>
|
||||
</div>
|
||||
{:else}
|
||||
<div class="h-full flex items-center justify-center text-light/40">
|
||||
<div class="text-center">
|
||||
@@ -210,3 +299,35 @@
|
||||
</div>
|
||||
</div>
|
||||
</Modal>
|
||||
|
||||
<Modal
|
||||
isOpen={showEditModal}
|
||||
onClose={() => {
|
||||
showEditModal = false;
|
||||
editingDoc = null;
|
||||
newDocName = "";
|
||||
}}
|
||||
title="Rename"
|
||||
>
|
||||
<div class="space-y-4">
|
||||
<Input
|
||||
label="Name"
|
||||
bind:value={newDocName}
|
||||
placeholder="Enter new name"
|
||||
/>
|
||||
|
||||
<div class="flex justify-end gap-2 pt-2">
|
||||
<Button
|
||||
variant="ghost"
|
||||
onclick={() => {
|
||||
showEditModal = false;
|
||||
editingDoc = null;
|
||||
newDocName = "";
|
||||
}}>Cancel</Button
|
||||
>
|
||||
<Button onclick={handleRename} disabled={!newDocName.trim()}
|
||||
>Save</Button
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</Modal>
|
||||
|
||||
Reference in New Issue
Block a user