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

@@ -44,7 +44,9 @@ export const ClientBoard = () => {
const board = useRequiredBoard();
const isReady = useIsBoardReady();
const sortedSections = board.sections.sort((sectionA, sectionB) => sectionA.position - sectionB.position);
const fullWidthSortedSections = board.sections
.filter((section) => section.kind === "empty" || section.kind === "category")
.sort((sectionA, sectionB) => sectionA.yOffset - sectionB.yOffset);
const ref = useRef<HTMLDivElement>(null);
@@ -58,11 +60,11 @@ export const ClientBoard = () => {
h={fullHeightWithoutHeaderAndFooter}
/>
<Stack ref={ref} h="100%" style={{ visibility: isReady ? "visible" : "hidden" }}>
{sortedSections.map((section) =>
{fullWidthSortedSections.map((section) =>
section.kind === "empty" ? (
<BoardEmptySection key={section.id} section={section} mainRef={ref} />
<BoardEmptySection key={section.id} section={section} />
) : (
<BoardCategorySection key={section.id} section={section} mainRef={ref} />
<BoardCategorySection key={section.id} section={section} />
),
)}
</Stack>

View File

@@ -10,6 +10,7 @@ import {
IconPencil,
IconPencilOff,
IconPlus,
IconResize,
IconSettings,
} from "@tabler/icons-react";
@@ -23,6 +24,7 @@ import { ItemSelectModal } from "~/components/board/items/item-select-modal";
import { useBoardPermissions } from "~/components/board/permissions/client";
import { useCategoryActions } from "~/components/board/sections/category/category-actions";
import { CategoryEditModal } from "~/components/board/sections/category/category-edit-modal";
import { useDynamicSectionActions } from "~/components/board/sections/dynamic/dynamic-actions";
import { HeaderButton } from "~/components/layout/header/button";
import { useEditMode, useRequiredBoard } from "./_context";
@@ -52,6 +54,7 @@ const AddMenu = () => {
const { openModal: openCategoryEditModal } = useModalAction(CategoryEditModal);
const { openModal: openItemSelectModal } = useModalAction(ItemSelectModal);
const { addCategoryToEnd } = useCategoryActions();
const { addDynamicSection } = useDynamicSectionActions();
const t = useI18n();
const handleAddCategory = useCallback(
@@ -99,6 +102,10 @@ const AddMenu = () => {
<Menu.Item leftSection={<IconBoxAlignTop size={20} />} onClick={handleAddCategory}>
{t("section.category.action.create")}
</Menu.Item>
<Menu.Item leftSection={<IconResize size={20} />} onClick={addDynamicSection}>
{t("section.dynamic.action.create")}
</Menu.Item>
</Menu.Dropdown>
</Menu>
);

View File

@@ -7,5 +7,6 @@ export type Item = Section["items"][number];
export type CategorySection = Extract<Section, { kind: "category" }>;
export type EmptySection = Extract<Section, { kind: "empty" }>;
export type DynamicSection = Extract<Section, { kind: "dynamic" }>;
export type ItemOfKind<TKind extends WidgetKind> = Extract<Item, { kind: TKind }>;