You've already forked obsidian-visualiser
Finished project configuration page with reorder
This commit is contained in:
@@ -21,6 +21,7 @@ export default defineEventHandler(async (e) => {
|
||||
'content': sql<string>`cast(${explorerContentTable.content} as TEXT)`.as('content'),
|
||||
'navigable': explorerContentTable.navigable,
|
||||
'private': explorerContentTable.private,
|
||||
'order': explorerContentTable.order,
|
||||
}).from(explorerContentTable).where(eq(explorerContentTable.path, sql.placeholder('path'))).prepare().get({ path });
|
||||
|
||||
if(content !== undefined)
|
||||
|
||||
@@ -6,11 +6,6 @@ export type NavigationTreeItem = NavigationItem & { children?: NavigationTreeIte
|
||||
export default defineEventHandler(async (e) => {
|
||||
const { user } = await getUserSession(e);
|
||||
|
||||
/*if(!user)
|
||||
{
|
||||
throw createError({ statusCode: 401, statusText: 'Unauthorized' });
|
||||
}*/
|
||||
|
||||
const db = useDatabase();
|
||||
const content = db.select({
|
||||
path: explorerContentTable.path,
|
||||
@@ -52,6 +47,7 @@ export default defineEventHandler(async (e) => {
|
||||
}
|
||||
|
||||
setResponseStatus(e, 404);
|
||||
return;
|
||||
});
|
||||
|
||||
function addChild(arr: NavigationTreeItem[], e: NavigationItem): void
|
||||
@@ -69,7 +65,7 @@ function addChild(arr: NavigationTreeItem[], e: NavigationItem): void
|
||||
{
|
||||
arr.push({ ...e });
|
||||
arr.sort((a, b) => {
|
||||
if(a.order && b.order)
|
||||
if(a.order !== b.order)
|
||||
return a.order - b.order;
|
||||
return a.title.localeCompare(b.title);
|
||||
});
|
||||
|
||||
@@ -1,49 +0,0 @@
|
||||
import { hasPermissions } from "#shared/auth.util";
|
||||
import useDatabase from '~/composables/useDatabase';
|
||||
import { explorerContentTable } from '~/db/schema';
|
||||
import { table } from '~/schemas/navigation';
|
||||
|
||||
export default defineEventHandler(async (e) => {
|
||||
const { user } = await getUserSession(e);
|
||||
|
||||
if(!user || !hasPermissions(user.permissions, ['admin', 'editor']))
|
||||
{
|
||||
throw createError({ statusCode: 401, statusText: 'Unauthorized' });
|
||||
}
|
||||
|
||||
const body = await readValidatedBody(e, table.safeParse);
|
||||
|
||||
if(!body.success)
|
||||
{
|
||||
throw body.error;
|
||||
}
|
||||
|
||||
const db = useDatabase();
|
||||
db.transaction((tx) => {
|
||||
for(let i = 0; i < body.data.length; i++)
|
||||
{
|
||||
tx.insert(explorerContentTable).values({
|
||||
path: body.data[i].path,
|
||||
owner: body.data[i].owner,
|
||||
title: body.data[i].title,
|
||||
type: body.data[i].type,
|
||||
navigable: body.data[i].navigable,
|
||||
private: body.data[i].private,
|
||||
order: body.data[i].order,
|
||||
content: Buffer.from('', 'utf-8'),
|
||||
}).onConflictDoUpdate({
|
||||
set: {
|
||||
owner: body.data[i].owner,
|
||||
title: body.data[i].title,
|
||||
type: body.data[i].type,
|
||||
navigable: body.data[i].navigable,
|
||||
private: body.data[i].private,
|
||||
order: body.data[i].order,
|
||||
},
|
||||
target: explorerContentTable.path,
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
setResponseStatus(e, 404);
|
||||
});
|
||||
76
server/api/project.get.ts
Normal file
76
server/api/project.get.ts
Normal file
@@ -0,0 +1,76 @@
|
||||
import useDatabase from '~/composables/useDatabase';
|
||||
import { explorerContentTable } from '~/db/schema';
|
||||
import type { NavigationItem } from '~/schemas/navigation';
|
||||
import type { ProjectItem, Project } from '~/schemas/project';
|
||||
import { hasPermissions } from '~/shared/auth.util';
|
||||
|
||||
export default defineEventHandler(async (e) => {
|
||||
const { user } = await getUserSession(e);
|
||||
|
||||
if(!user || !hasPermissions(user.permissions, ['editor', 'admin']))
|
||||
{
|
||||
throw createError({
|
||||
statusCode: 401,
|
||||
statusMessage: 'Unauthorized',
|
||||
});
|
||||
}
|
||||
|
||||
const db = useDatabase();
|
||||
const content = db.select({
|
||||
path: explorerContentTable.path,
|
||||
type: explorerContentTable.type,
|
||||
owner: explorerContentTable.owner,
|
||||
title: explorerContentTable.title,
|
||||
navigable: explorerContentTable.navigable,
|
||||
private: explorerContentTable.private,
|
||||
order: explorerContentTable.order,
|
||||
}).from(explorerContentTable).prepare().all();
|
||||
|
||||
if(content.length > 0)
|
||||
{
|
||||
const project: Project = {
|
||||
items: [],
|
||||
}
|
||||
|
||||
for(const item of content.filter(e => !!e))
|
||||
{
|
||||
addChild(project.items, item);
|
||||
}
|
||||
|
||||
return project;
|
||||
}
|
||||
|
||||
setResponseStatus(e, 404);
|
||||
return;
|
||||
});
|
||||
|
||||
function addChild(arr: ProjectItem[], e: NavigationItem): void
|
||||
{
|
||||
const parent = arr.find(f => e.path.startsWith(f.path));
|
||||
|
||||
if(parent)
|
||||
{
|
||||
if(!parent.children)
|
||||
parent.children = [];
|
||||
|
||||
addChild(parent.children, e);
|
||||
}
|
||||
else
|
||||
{
|
||||
arr.push({
|
||||
path: e.path,
|
||||
parent: e.path.substring(0, e.path.lastIndexOf('/')),
|
||||
name: e.path.substring(e.path.lastIndexOf('/') + 1),
|
||||
title: e.title,
|
||||
type: e.type,
|
||||
navigable: e.navigable,
|
||||
private: e.private,
|
||||
order: e.order,
|
||||
});
|
||||
arr.sort((a, b) => {
|
||||
if(a.order !== b.order)
|
||||
return a.order - b.order;
|
||||
return a.title.localeCompare(b.title);
|
||||
});
|
||||
}
|
||||
}
|
||||
62
server/api/project.post.ts
Normal file
62
server/api/project.post.ts
Normal file
@@ -0,0 +1,62 @@
|
||||
import { hasPermissions } from "#shared/auth.util";
|
||||
import useDatabase from '~/composables/useDatabase';
|
||||
import { explorerContentTable } from '~/db/schema';
|
||||
import { project, type ProjectItem } from '~/schemas/project';
|
||||
import { parsePath } from "#shared/general.utils";
|
||||
|
||||
export default defineEventHandler(async (e) => {
|
||||
const { user } = await getUserSession(e);
|
||||
|
||||
if(!user || !hasPermissions(user.permissions, ['admin', 'editor']))
|
||||
{
|
||||
throw createError({ statusCode: 401, statusText: 'Unauthorized' });
|
||||
}
|
||||
|
||||
const body = await readValidatedBody(e, project.safeParse);
|
||||
|
||||
if(!body.success)
|
||||
{
|
||||
throw body.error;
|
||||
}
|
||||
|
||||
const items = buildOrder(body.data.items);
|
||||
|
||||
const db = useDatabase();
|
||||
db.transaction((tx) => {
|
||||
for(let i = 0; i < items.length; i++)
|
||||
{
|
||||
const item = items[i];
|
||||
|
||||
tx.insert(explorerContentTable).values({
|
||||
path: item.path,
|
||||
owner: user.id,
|
||||
title: item.title,
|
||||
type: item.type,
|
||||
navigable: item.navigable,
|
||||
private: item.private,
|
||||
order: item.order,
|
||||
content: Buffer.from('', 'utf-8'),
|
||||
}).onConflictDoUpdate({
|
||||
set: {
|
||||
path: [item.parent, parsePath(item?.name ?? item.title)].filter(e => !!e).join('/'),
|
||||
title: item.title,
|
||||
type: item.type,
|
||||
navigable: item.navigable,
|
||||
private: item.private,
|
||||
order: item.order,
|
||||
},
|
||||
target: explorerContentTable.path,
|
||||
}).run();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
function buildOrder(items: ProjectItem[]): ProjectItem[]
|
||||
{
|
||||
items.forEach((e, i) => {
|
||||
e.order = i;
|
||||
if(e.children) e.children = buildOrder(e.children);
|
||||
});
|
||||
|
||||
return items.flatMap(e => [e, ...(e.children ?? [])]);
|
||||
}
|
||||
Reference in New Issue
Block a user