initial commit
This commit is contained in:
209
src/routes/folders/[...path]/+page.server.ts
Normal file
209
src/routes/folders/[...path]/+page.server.ts
Normal file
@ -0,0 +1,209 @@
|
||||
import { db } from '$lib/server/db';
|
||||
import { items, folders, categories, reservations } from '$lib/server/db/schema';
|
||||
import { eq, and, isNull, inArray, sql } from 'drizzle-orm';
|
||||
import { error } from '@sveltejs/kit';
|
||||
import { processProperties } from '$lib/utils/propertyUtils';
|
||||
|
||||
export const load = async ({ params, url }: { params: { path: string }, url: URL }) => {
|
||||
const pathSegments = params.path.split('/').filter(Boolean);
|
||||
let currentFolder = null;
|
||||
const breadcrumbs: any[] = [];
|
||||
let parentId = null;
|
||||
|
||||
for (const segment of pathSegments) {
|
||||
const folder = await db.select().from(folders)
|
||||
.where(and(
|
||||
eq(folders.name, decodeURIComponent(segment)),
|
||||
parentId ? eq(folders.parentId, parentId) : isNull(folders.parentId)
|
||||
))
|
||||
.limit(1);
|
||||
|
||||
if (folder.length === 0) {
|
||||
throw error(404, 'Folder not found');
|
||||
}
|
||||
|
||||
currentFolder = folder[0];
|
||||
parentId = currentFolder.id;
|
||||
const parentPath = breadcrumbs.map(b => b.name).join('/');
|
||||
breadcrumbs.push({
|
||||
name: currentFolder.name,
|
||||
url: `/folders${parentPath ? '/' + parentPath : ''}/${currentFolder.name}`
|
||||
});
|
||||
}
|
||||
|
||||
// Fetch subfolders
|
||||
const subfolders = await db.select().from(folders)
|
||||
.where(currentFolder ? eq(folders.parentId, currentFolder.id) : isNull(folders.parentId));
|
||||
|
||||
// Fetch items
|
||||
const folderItems = await db.select({
|
||||
id: items.id,
|
||||
name: items.name,
|
||||
count: items.count,
|
||||
categoryName: categories.name,
|
||||
categoryId: items.categoryId,
|
||||
folderId: items.folderId,
|
||||
tags: items.tags,
|
||||
properties: items.properties,
|
||||
reservedCount: sql<number>`(SELECT COALESCE(SUM(count), 0) FROM reservations WHERE item_id = ${items.id})`.mapWith(Number)
|
||||
})
|
||||
.from(items)
|
||||
.leftJoin(categories, eq(items.categoryId, categories.id))
|
||||
.where(currentFolder ? eq(items.folderId, currentFolder.id) : isNull(items.folderId));
|
||||
|
||||
const allCategories = await db.select().from(categories);
|
||||
const allFolders = await db.select().from(folders);
|
||||
|
||||
return {
|
||||
currentFolder,
|
||||
breadcrumbs,
|
||||
items: folderItems,
|
||||
subfolders,
|
||||
categories: allCategories,
|
||||
allFolders
|
||||
};
|
||||
};
|
||||
|
||||
export const actions = {
|
||||
createFolder: async ({ request }: { request: Request }) => {
|
||||
const data = await request.formData();
|
||||
const name = data.get('name') as string;
|
||||
const parentId = data.get('parentId') as string || null;
|
||||
|
||||
await db.insert(folders).values({
|
||||
name,
|
||||
parentId
|
||||
});
|
||||
|
||||
return { success: true };
|
||||
},
|
||||
createItem: async ({ request }: { request: Request }) => {
|
||||
const data = await request.formData();
|
||||
const name = data.get('name') as string;
|
||||
const folderId = data.get('folderId') as string;
|
||||
const categoryId = data.get('categoryId') as string;
|
||||
const count = parseInt(data.get('count') as string) || 0;
|
||||
|
||||
const properties = processProperties(data);
|
||||
|
||||
await db.insert(items).values({
|
||||
name,
|
||||
folderId: folderId || null,
|
||||
categoryId,
|
||||
count,
|
||||
properties
|
||||
});
|
||||
|
||||
return { success: true };
|
||||
},
|
||||
updateItem: async ({ request }: { request: Request }) => {
|
||||
const data = await request.formData();
|
||||
const id = data.get('id') as string;
|
||||
const name = data.get('name') as string;
|
||||
const categoryId = data.get('categoryId') as string;
|
||||
const count = parseInt(data.get('count') as string) || 0;
|
||||
const folderId = data.get('folderId') as string;
|
||||
|
||||
const properties = processProperties(data);
|
||||
|
||||
const updateData: any = {
|
||||
name,
|
||||
categoryId,
|
||||
count,
|
||||
properties,
|
||||
updatedAt: new Date()
|
||||
};
|
||||
|
||||
if (folderId !== undefined) {
|
||||
updateData.folderId = folderId || null;
|
||||
}
|
||||
|
||||
await db.update(items)
|
||||
.set(updateData)
|
||||
.where(eq(items.id, id));
|
||||
|
||||
return { success: true };
|
||||
},
|
||||
deleteItem: async ({ request }: { request: Request }) => {
|
||||
const data = await request.formData();
|
||||
const id = data.get('id') as string;
|
||||
await db.delete(items).where(eq(items.id, id));
|
||||
return { success: true };
|
||||
},
|
||||
moveItem: async ({ request }: { request: Request }) => {
|
||||
const data = await request.formData();
|
||||
const id = data.get('id') as string;
|
||||
const folderId = data.get('folderId') as string;
|
||||
await db.update(items).set({ folderId: folderId || null }).where(eq(items.id, id));
|
||||
return { success: true };
|
||||
},
|
||||
bulkDelete: async ({ request }: { request: Request }) => {
|
||||
const data = await request.formData();
|
||||
const ids = JSON.parse(data.get('ids') as string);
|
||||
if (ids.length > 0) {
|
||||
await db.delete(items).where(inArray(items.id, ids));
|
||||
}
|
||||
return { success: true };
|
||||
},
|
||||
bulkMove: async ({ request }: { request: Request }) => {
|
||||
const data = await request.formData();
|
||||
const ids = JSON.parse(data.get('ids') as string);
|
||||
const folderId = data.get('folderId') as string;
|
||||
if (ids.length > 0) {
|
||||
await db.update(items).set({ folderId: folderId || null }).where(inArray(items.id, ids));
|
||||
}
|
||||
return { success: true };
|
||||
},
|
||||
updateCount: async ({ request }: { request: Request }) => {
|
||||
const data = await request.formData();
|
||||
const id = data.get('id') as string;
|
||||
const delta = parseInt(data.get('delta') as string) || 0;
|
||||
|
||||
const item = await db.select({ count: items.count }).from(items).where(eq(items.id, id)).limit(1);
|
||||
|
||||
if (item.length > 0) {
|
||||
const newCount = Math.max(0, (item[0].count || 0) + delta);
|
||||
await db.update(items).set({ count: newCount }).where(eq(items.id, id));
|
||||
}
|
||||
|
||||
return { success: true };
|
||||
},
|
||||
renameFolder: async ({ request }: { request: Request }) => {
|
||||
const data = await request.formData();
|
||||
const id = data.get('id') as string;
|
||||
const name = data.get('name') as string;
|
||||
|
||||
await db.update(folders)
|
||||
.set({ name })
|
||||
.where(eq(folders.id, id));
|
||||
|
||||
return { success: true };
|
||||
},
|
||||
moveFolder: async ({ request }: { request: Request }) => {
|
||||
const data = await request.formData();
|
||||
const id = data.get('id') as string;
|
||||
const parentId = data.get('folderId') as string; // Reusing folderId param name from item move
|
||||
|
||||
// Prevent moving folder into itself or its children (basic check: not into itself)
|
||||
if (id === parentId) {
|
||||
// In a real app we'd check for cycles, but for now just prevent direct self-parenting
|
||||
return { success: false, error: "Cannot move folder into itself" };
|
||||
}
|
||||
|
||||
await db.update(folders)
|
||||
.set({ parentId: parentId || null })
|
||||
.where(eq(folders.id, id));
|
||||
|
||||
return { success: true };
|
||||
},
|
||||
deleteFolder: async ({ request }: { request: Request }) => {
|
||||
const data = await request.formData();
|
||||
const id = data.get('id') as string;
|
||||
|
||||
// Note: This assumes cascading delete or that the user has emptied the folder.
|
||||
// If not cascading, this might fail. For now, we assume simple delete.
|
||||
await db.delete(folders).where(eq(folders.id, id));
|
||||
|
||||
return { success: true };
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user