feat: add dynamic section (#842)

* chore: add parent_section_id and change position to x and y_offset for sqlite section table

* chore: rename existing positions to x_offset and y_offset

* chore: add related mysql migration

* chore: add missing height and width to section table

* fix: missing width and height in migration copy script

* fix: typecheck issues

* fix: test not working caused by unsimilar schemas

* wip: add dynamic section

* refactor: improve structure of gridstack sections

* feat: add rendering of dynamic sections

* feat: add saving of moved sections

* wip: add static row count, restrict min-width and height

* chore: address pull request feedback

* fix: format issues

* fix: size calculation within dynamic sections

* fix: on resize not called when min width or height is reached

* fix: size of items while dragging is to big

* chore: temporarly remove migration files

* chore: readd migrations

* fix: format and deepsource issues

* chore: remove db_dev.sqlite file

* chore: add *.sqlite to .gitignore

* chore: address pull request feedback

* feat: add dynamic section actions for adding and removing them
This commit is contained in:
Meier Lukas
2024-08-10 12:37:16 +02:00
committed by GitHub
parent a9d87e4e6b
commit 9ce172e78a
38 changed files with 3765 additions and 395 deletions

View File

@@ -109,7 +109,8 @@ export const boardRouter = createTRPCRouter({
await transaction.insert(sections).values({
id: createId(),
kind: "empty",
position: 0,
xOffset: 0,
yOffset: 0,
boardId,
});
});
@@ -206,7 +207,11 @@ export const boardRouter = createTRPCRouter({
addedSections.map((section) => ({
id: section.id,
kind: section.kind,
position: section.position,
yOffset: section.yOffset,
xOffset: section.kind === "dynamic" ? section.xOffset : 0,
height: "height" in section ? section.height : null,
width: "width" in section ? section.width : null,
parentSectionId: "parentSectionId" in section ? section.parentSectionId : null,
name: "name" in section ? section.name : null,
boardId: dbBoard.id,
})),
@@ -292,7 +297,11 @@ export const boardRouter = createTRPCRouter({
await transaction
.update(sections)
.set({
position: section.position,
yOffset: section.yOffset,
xOffset: section.xOffset,
height: prev?.kind === "dynamic" && "height" in section ? section.height : null,
width: prev?.kind === "dynamic" && "width" in section ? section.width : null,
parentSectionId: prev?.kind === "dynamic" && "parentSectionId" in section ? section.parentSectionId : null,
name: prev?.kind === "category" && "name" in section ? section.name : null,
})
.where(eq(sections.id, section.id));
@@ -538,6 +547,7 @@ const outputItemSchema = zodUnionFromArray(widgetKinds.map((kind) => forKind(kin
const parseSection = (section: unknown) => {
const result = createSectionSchema(outputItemSchema).safeParse(section);
if (!result.success) {
throw new Error(result.error.message);
}

View File

@@ -619,7 +619,8 @@ describe("saveBoard should save full board", () => {
{
id: createId(),
kind: "empty",
position: 0,
yOffset: 0,
xOffset: 0,
items: [],
},
],
@@ -655,7 +656,8 @@ describe("saveBoard should save full board", () => {
{
id: sectionId,
kind: "empty",
position: 0,
yOffset: 0,
xOffset: 0,
items: [
{
id: createId(),
@@ -716,7 +718,8 @@ describe("saveBoard should save full board", () => {
{
id: sectionId,
kind: "empty",
position: 0,
xOffset: 0,
yOffset: 0,
items: [
{
id: itemId,
@@ -778,14 +781,16 @@ describe("saveBoard should save full board", () => {
sections: [
{
id: newSectionId,
position: 1,
xOffset: 0,
yOffset: 1,
items: [],
...partialSection,
},
{
id: sectionId,
kind: "empty",
position: 0,
xOffset: 0,
yOffset: 0,
items: [],
},
],
@@ -808,7 +813,7 @@ describe("saveBoard should save full board", () => {
expect(addedSection).toBeDefined();
expect(addedSection.id).toBe(newSectionId);
expect(addedSection.kind).toBe(partialSection.kind);
expect(addedSection.position).toBe(1);
expect(addedSection.yOffset).toBe(1);
if ("name" in partialSection) {
expect(addedSection.name).toBe(partialSection.name);
}
@@ -830,7 +835,8 @@ describe("saveBoard should save full board", () => {
{
id: sectionId,
kind: "empty",
position: 0,
yOffset: 0,
xOffset: 0,
items: [
{
id: newItemId,
@@ -899,7 +905,8 @@ describe("saveBoard should save full board", () => {
{
id: sectionId,
kind: "empty",
position: 0,
xOffset: 0,
yOffset: 0,
items: [
{
id: itemId,
@@ -956,7 +963,8 @@ describe("saveBoard should save full board", () => {
id: newSectionId,
kind: "category",
name: "Before",
position: 1,
yOffset: 1,
xOffset: 0,
boardId,
});
@@ -966,7 +974,8 @@ describe("saveBoard should save full board", () => {
{
id: sectionId,
kind: "category",
position: 1,
yOffset: 1,
xOffset: 0,
name: "Test",
items: [],
},
@@ -974,7 +983,8 @@ describe("saveBoard should save full board", () => {
id: newSectionId,
kind: "category",
name: "After",
position: 0,
yOffset: 0,
xOffset: 0,
items: [],
},
],
@@ -992,12 +1002,12 @@ describe("saveBoard should save full board", () => {
const firstSection = expectToBeDefined(definedBoard.sections.find((section) => section.id === sectionId));
expect(firstSection.id).toBe(sectionId);
expect(firstSection.kind).toBe("empty");
expect(firstSection.position).toBe(1);
expect(firstSection.yOffset).toBe(1);
expect(firstSection.name).toBe(null);
const secondSection = expectToBeDefined(definedBoard.sections.find((section) => section.id === newSectionId));
expect(secondSection.id).toBe(newSectionId);
expect(secondSection.kind).toBe("category");
expect(secondSection.position).toBe(0);
expect(secondSection.yOffset).toBe(0);
expect(secondSection.name).toBe("After");
});
it("should update item when present in input", async () => {
@@ -1013,7 +1023,8 @@ describe("saveBoard should save full board", () => {
{
id: sectionId,
kind: "empty",
position: 0,
yOffset: 0,
xOffset: 0,
items: [
{
id: itemId,
@@ -1268,7 +1279,8 @@ const createFullBoardAsync = async (db: Database, name: string) => {
await db.insert(sections).values({
id: sectionId,
kind: "empty",
position: 0,
yOffset: 0,
xOffset: 0,
boardId,
});