feat: add board (#15)
* wip: Add gridstack board * wip: Centralize board pages, Add board settings page * fix: remove cyclic dependency and rename widget-sort to kind * improve: Add header actions as parallel route * feat: add item select modal, add category edit modal, * feat: add edit item modal * feat: add remove item modal * wip: add category actions * feat: add saving of board, wip: add app widget * Merge branch 'main' into add-board * chore: update turbo dependencies * chore: update mantine dependencies * chore: fix typescript errors, lint and format * feat: add confirm modal to category removal, move items of removed category to above wrapper * feat: remove app widget to continue in another branch * feat: add loading spinner until board is initialized * fix: issue with cellheight of gridstack items * feat: add translations for board * fix: issue with translation for settings page * chore: address pull request feedback
This commit is contained in:
84
apps/nextjs/src/components/board/items/item-select-modal.tsx
Normal file
84
apps/nextjs/src/components/board/items/item-select-modal.tsx
Normal file
@@ -0,0 +1,84 @@
|
||||
import type { ManagedModal } from "mantine-modal-manager";
|
||||
|
||||
import type { WidgetKind } from "@homarr/definitions";
|
||||
import { useI18n } from "@homarr/translation/client";
|
||||
import { Button, Card, Center, Grid, Stack, Text } from "@homarr/ui";
|
||||
|
||||
import { objectEntries } from "../../../../../../packages/common/src";
|
||||
import { widgetImports } from "../../../../../../packages/widgets/src";
|
||||
import type { WidgetDefinition } from "../../../../../../packages/widgets/src/definition";
|
||||
import { useItemActions } from "./item-actions";
|
||||
|
||||
export const ItemSelectModal: ManagedModal<Record<string, never>> = ({
|
||||
actions,
|
||||
}) => {
|
||||
return (
|
||||
<Grid>
|
||||
{objectEntries(widgetImports).map(([key, value]) => {
|
||||
return (
|
||||
<WidgetItem
|
||||
key={key}
|
||||
kind={key}
|
||||
definition={value.definition}
|
||||
closeModal={actions.closeModal}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</Grid>
|
||||
);
|
||||
};
|
||||
|
||||
const WidgetItem = ({
|
||||
kind,
|
||||
definition,
|
||||
closeModal,
|
||||
}: {
|
||||
kind: WidgetKind;
|
||||
definition: WidgetDefinition;
|
||||
closeModal: () => void;
|
||||
}) => {
|
||||
const t = useI18n();
|
||||
const { createItem } = useItemActions();
|
||||
const handleAdd = (kind: WidgetKind) => {
|
||||
createItem({ kind });
|
||||
closeModal();
|
||||
};
|
||||
|
||||
return (
|
||||
<Grid.Col span={{ xs: 12, sm: 4, md: 3 }}>
|
||||
<Card h="100%">
|
||||
<Stack justify="space-between" h="100%">
|
||||
<Stack gap="xs">
|
||||
<Center>
|
||||
<definition.icon />
|
||||
</Center>
|
||||
<Text lh={1.2} style={{ whiteSpace: "normal" }} ta="center">
|
||||
{t(`widget.${kind}.name`)}
|
||||
</Text>
|
||||
<Text
|
||||
lh={1.2}
|
||||
style={{ whiteSpace: "normal" }}
|
||||
size="xs"
|
||||
ta="center"
|
||||
c="dimmed"
|
||||
>
|
||||
{t(`widget.${kind}.description`)}
|
||||
</Text>
|
||||
</Stack>
|
||||
<Button
|
||||
onClick={() => {
|
||||
handleAdd(kind);
|
||||
}}
|
||||
variant="light"
|
||||
size="xs"
|
||||
mt="auto"
|
||||
radius="md"
|
||||
fullWidth
|
||||
>
|
||||
{t(`item.create.addToBoard`)}
|
||||
</Button>
|
||||
</Stack>
|
||||
</Card>
|
||||
</Grid.Col>
|
||||
);
|
||||
};
|
||||
Reference in New Issue
Block a user