feat: add title to dynamic section (#2614)
* feat: add title to dynamic section * fix: formatting * feat: use badge rather than text * fix: use board radius * fix: use shared.ts validation --------- Co-authored-by: Meier Lukas <meierschlumpf@gmail.com>
This commit is contained in:
@@ -10,6 +10,7 @@ export class DynamicSectionMockBuilder {
|
|||||||
id: createId(),
|
id: createId(),
|
||||||
kind: "dynamic",
|
kind: "dynamic",
|
||||||
options: {
|
options: {
|
||||||
|
title: "",
|
||||||
borderColor: "",
|
borderColor: "",
|
||||||
},
|
},
|
||||||
layouts: [],
|
layouts: [],
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { Box, Card } from "@mantine/core";
|
import { Badge, Box, Card } from "@mantine/core";
|
||||||
|
|
||||||
import { useCurrentLayout, useRequiredBoard } from "@homarr/boards/context";
|
import { useCurrentLayout, useRequiredBoard } from "@homarr/boards/context";
|
||||||
|
|
||||||
@@ -17,7 +17,12 @@ export const BoardDynamicSection = ({ section }: Props) => {
|
|||||||
const options = section.options;
|
const options = section.options;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box className="grid-stack-item-content">
|
<Box
|
||||||
|
className="grid-stack-item-content"
|
||||||
|
style={{
|
||||||
|
overflow: "visible",
|
||||||
|
}}
|
||||||
|
>
|
||||||
<Card
|
<Card
|
||||||
className={classes.itemCard}
|
className={classes.itemCard}
|
||||||
w="100%"
|
w="100%"
|
||||||
@@ -25,14 +30,28 @@ export const BoardDynamicSection = ({ section }: Props) => {
|
|||||||
withBorder
|
withBorder
|
||||||
styles={{
|
styles={{
|
||||||
root: {
|
root: {
|
||||||
|
overflow: "visible",
|
||||||
"--opacity": board.opacity / 100,
|
"--opacity": board.opacity / 100,
|
||||||
overflow: "hidden",
|
"--border-color": options.borderColor || undefined,
|
||||||
"--border-color": options.borderColor !== "" ? options.borderColor : undefined,
|
|
||||||
},
|
},
|
||||||
}}
|
}}
|
||||||
radius={board.itemRadius}
|
radius={board.itemRadius}
|
||||||
p={0}
|
p={0}
|
||||||
>
|
>
|
||||||
|
{options.title && (
|
||||||
|
<Badge
|
||||||
|
pos="absolute"
|
||||||
|
top={-15}
|
||||||
|
left={10}
|
||||||
|
size="md"
|
||||||
|
radius={board.itemRadius}
|
||||||
|
color="var(--background-color)"
|
||||||
|
c="var(--mantine-color-text)"
|
||||||
|
bd="1px solid var(--border-color)"
|
||||||
|
>
|
||||||
|
{options.title}
|
||||||
|
</Badge>
|
||||||
|
)}
|
||||||
{/* Use unique key by layout to reinitialize gridstack */}
|
{/* Use unique key by layout to reinitialize gridstack */}
|
||||||
<GridStack key={`${currentLayoutId}-${section.id}`} section={section} className="min-row" />
|
<GridStack key={`${currentLayoutId}-${section.id}`} section={section} className="min-row" />
|
||||||
</Card>
|
</Card>
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ export const addDynamicSectionCallback = () => (board: Board) => {
|
|||||||
id: createId(),
|
id: createId(),
|
||||||
kind: "dynamic",
|
kind: "dynamic",
|
||||||
options: {
|
options: {
|
||||||
|
title: "",
|
||||||
borderColor: "",
|
borderColor: "",
|
||||||
},
|
},
|
||||||
layouts: createDynamicSectionLayouts(board, firstSection),
|
layouts: createDynamicSectionLayouts(board, firstSection),
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import { Button, CloseButton, ColorInput, Group, Stack, useMantineTheme } from "@mantine/core";
|
import { Button, CloseButton, ColorInput, Group, Stack, TextInput, useMantineTheme } from "@mantine/core";
|
||||||
import type { z } from "zod";
|
import type { z } from "zod";
|
||||||
|
|
||||||
import { useZodForm } from "@homarr/form";
|
import { useZodForm } from "@homarr/form";
|
||||||
@@ -30,6 +30,7 @@ export const DynamicSectionEditModal = createModal<ModalProps>(({ actions, inner
|
|||||||
})}
|
})}
|
||||||
>
|
>
|
||||||
<Stack>
|
<Stack>
|
||||||
|
<TextInput label={t("section.dynamic.option.title.label")} {...form.getInputProps("title")} />
|
||||||
<ColorInput
|
<ColorInput
|
||||||
label={t("section.dynamic.option.borderColor.label")}
|
label={t("section.dynamic.option.borderColor.label")}
|
||||||
format="hex"
|
format="hex"
|
||||||
|
|||||||
@@ -980,6 +980,9 @@
|
|||||||
"remove": "Remove dynamic section"
|
"remove": "Remove dynamic section"
|
||||||
},
|
},
|
||||||
"option": {
|
"option": {
|
||||||
|
"title": {
|
||||||
|
"label": "Title"
|
||||||
|
},
|
||||||
"borderColor": {
|
"borderColor": {
|
||||||
"label": "Border color"
|
"label": "Border color"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -60,6 +60,7 @@ const emptySectionSchema = z.object({
|
|||||||
});
|
});
|
||||||
|
|
||||||
export const dynamicSectionOptionsSchema = z.object({
|
export const dynamicSectionOptionsSchema = z.object({
|
||||||
|
title: z.string().max(20).default(""),
|
||||||
borderColor: z.string().default(""),
|
borderColor: z.string().default(""),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user