Make notebook editable with database

This commit is contained in:
Meier Lukas
2023-10-02 21:16:51 +02:00
parent 527fea8ff6
commit 4ad87fcf89
2 changed files with 61 additions and 48 deletions

View File

@@ -1,46 +1,52 @@
import { TRPCError } from '@trpc/server';
import fs from 'fs';
import path from 'path';
import { and, eq } from 'drizzle-orm';
import { z } from 'zod';
import { getConfig } from '~/tools/config/getConfig';
import { BackendConfigType } from '~/types/config';
import { INotebookWidget } from '~/widgets/notebook/NotebookWidgetTile';
import { db } from '~/server/db';
import { items, widgetOptions } from '~/server/db/schema';
import { createTRPCRouter, publicProcedure } from '../trpc';
export const notebookRouter = createTRPCRouter({
update: publicProcedure
.input(z.object({ widgetId: z.string(), content: z.string(), configName: z.string() }))
.input(z.object({ widgetId: z.string(), content: z.string(), boardName: z.string() }))
.mutation(async ({ input }) => {
//TODO: #1305 Remove use of DISABLE_EDIT_MODE for auth update
if (process.env.DISABLE_EDIT_MODE?.toLowerCase() === 'true') {
throw new TRPCError({
code: 'METHOD_NOT_SUPPORTED',
message: 'Edit is not allowed, because edit mode is disabled',
});
}
const item = await db.query.items.findFirst({
where: and(eq(items.id, input.widgetId), eq(items.type, 'widget')),
with: {
widget: {
with: {
options: {
where: eq(widgetOptions.path, 'content'),
},
},
},
},
});
const config = getConfig(input.configName);
const widget = config.widgets.find((widget) => widget.id === input.widgetId) as
| INotebookWidget
| undefined;
if (!widget) {
if (!item?.widget) {
throw new TRPCError({
code: 'BAD_REQUEST',
code: 'NOT_FOUND',
message: 'Specified widget was not found',
});
}
widget.options.content = input.content;
// Update existing content
if (item.widget.options.some((o) => o.path === 'content')) {
await db
.update(widgetOptions)
.set({ value: input.content })
.where(
and(eq(widgetOptions.widgetId, item.widget.id), eq(widgetOptions.path, 'content'))
);
return;
}
// TODO: Make this work
/*const newConfig: BackendConfigType = {
...config,
widgets: [...config.widgets.filter((w) => w.id !== widget.id), widget],
};
const targetPath = path.join('data/configs', `${input.configName}.json`);
fs.writeFileSync(targetPath, JSON.stringify(newConfig, null, 2), 'utf8');*/
// Or create new content
await db.insert(widgetOptions).values({
widgetId: item.widget.id,
path: 'content',
value: input.content,
type: 'string',
});
}),
});

View File

@@ -7,7 +7,6 @@ import StarterKit from '@tiptap/starter-kit';
import { useState } from 'react';
import { useRequiredBoard } from '~/components/Board/context';
import { useEditModeStore } from '~/components/Dashboard/Views/useEditModeStore';
import { useConfigStore } from '~/config/store';
import { useColorTheme } from '~/tools/color';
import { api } from '~/utils/api';
@@ -25,7 +24,7 @@ export function Editor({ widget }: { widget: INotebookWidget }) {
const [isEditing, setIsEditing] = useState(false);
const board = useRequiredBoard();
const updateConfig = useConfigStore((x) => x.updateConfig);
const utils = api.useContext();
const { primaryColor } = useColorTheme();
const { mutateAsync } = api.notebook.update.useMutation();
@@ -45,26 +44,34 @@ export function Editor({ widget }: { widget: INotebookWidget }) {
const current = !previous;
if (!editor) return current;
editor.setEditable(current);
if (current) return current;
updateConfig(
board.name!,
(previous) => {
const currentWidget = previous.widgets.find((x) => x.id === widget.id);
currentWidget!.properties.content = debouncedContent;
return {
...previous,
widgets: [
...previous.widgets.filter((iterationWidget) => iterationWidget.id !== widget.id),
currentWidget!,
],
};
},
true
);
utils.boards.byName.setData({ boardName: board.name }, (previous) => {
if (!previous) return previous;
return {
...previous,
sections: previous.sections.map((section) => {
if (!section.items.some((item) => item.id === widget.id)) return section;
return {
...section,
items: section.items.map((item) => {
if (item.id !== widget.id) return item;
const notebookEditor = item as INotebookWidget;
return {
...notebookEditor,
options: {
...notebookEditor.options,
content: debouncedContent,
},
};
}),
};
}),
};
});
void mutateAsync({
configName: board.name!,
boardName: board.name!,
content: debouncedContent,
widgetId: widget.id,
});