feat: add app widget (#206)

* refactor: move server api to api package

* feat: add app widget

* refactor: add element size for widget components on board

* feat: add resize listener for widget width

* feat: add widget app input

* refactor: add better responsibe layout, add missing translations

* fix: ci issues

* fix: deepsource issues

* chore: address pull request feedback
This commit is contained in:
Meier Lukas
2024-03-12 21:23:25 +01:00
committed by GitHub
parent 7d5b999ab8
commit c4ff968cbc
31 changed files with 561 additions and 78 deletions

View File

@@ -2,6 +2,7 @@
// Ignored because of gridstack attributes
import type { RefObject } from "react";
import { useElementSize } from "@mantine/hooks";
import cx from "clsx";
import { useAtomValue } from "jotai";
@@ -36,6 +37,8 @@ interface Props {
export const SectionContent = ({ items, refs }: Props) => {
const board = useRequiredBoard();
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
const { ref, width, height } = useElementSize<HTMLDivElement>();
return (
<>
@@ -56,6 +59,7 @@ export const SectionContent = ({ items, refs }: Props) => {
ref={refs.items.current[item.id] as RefObject<HTMLDivElement>}
>
<Card
ref={ref as RefObject<HTMLDivElement>}
className={cx(classes.itemCard, "grid-stack-item-content")}
withBorder
styles={{
@@ -63,8 +67,9 @@ export const SectionContent = ({ items, refs }: Props) => {
"--opacity": board.opacity / 100,
},
}}
p={width >= 96 ? undefined : "xs"}
>
<BoardItem item={item} />
<BoardItem item={item} width={width + 32} height={height + 32} />
</Card>
</div>
);
@@ -75,9 +80,12 @@ export const SectionContent = ({ items, refs }: Props) => {
interface ItemProps {
item: Item;
width: number;
height: number;
}
const BoardItem = ({ item }: ItemProps) => {
const BoardItem = ({ item, ...dimensions }: ItemProps) => {
const editMode = useAtomValue(editModeAtom);
const serverData = useServerDataFor(item.id);
const Comp = loadWidgetDynamic(item.kind);
const options = reduceWidgetOptionsWithDefaultValues(item.kind, item.options);
@@ -92,6 +100,8 @@ const BoardItem = ({ item }: ItemProps) => {
options={options as never}
integrations={item.integrations}
serverData={serverData?.data as never}
isEditMode={editMode}
{...dimensions}
/>
</>
);

View File

@@ -46,7 +46,7 @@ export const useGridstack = ({
// reference of the gridstack object for modifications after initialization
const gridRef = useRef<GridStack>();
useCssVariableConfiguration({ section, mainRef, gridRef });
useCssVariableConfiguration({ mainRef, gridRef });
const board = useRequiredBoard();
@@ -146,7 +146,6 @@ export const useGridstack = ({
};
interface UseCssVariableConfiguration {
section: Section;
mainRef?: RefObject<HTMLDivElement>;
gridRef: UseGridstackRefs["gridstack"];
}
@@ -155,12 +154,10 @@ interface UseCssVariableConfiguration {
* This hook is used to configure the css variables for the gridstack
* Those css variables are used to define the size of the gridstack items
* @see gridstack.scss
* @param section section of the board
* @param mainRef reference to the main div wrapping all sections
* @param gridRef reference to the gridstack object
*/
const useCssVariableConfiguration = ({
section,
mainRef,
gridRef,
}: UseCssVariableConfiguration) => {
@@ -175,14 +172,25 @@ const useCssVariableConfiguration = ({
// Define widget-width by calculating the width of one column with mainRef width and column count
useEffect(() => {
if (!mainRef?.current) return;
const widgetWidth = mainRef.current.clientWidth / board.columnCount;
// widget width is used to define sizes of gridstack items within global.scss
root?.style.setProperty("--gridstack-widget-width", widgetWidth.toString());
gridRef.current?.cellHeight(widgetWidth);
// gridRef.current is required otherwise the cellheight is run on production as undefined
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [board.columnCount, root, section.kind, mainRef, gridRef.current]);
if (typeof document === "undefined") return;
const onResize = () => {
if (!mainRef?.current) return;
const widgetWidth = mainRef.current.clientWidth / board.columnCount;
// widget width is used to define sizes of gridstack items within global.scss
root?.style.setProperty(
"--gridstack-widget-width",
widgetWidth.toString(),
);
gridRef.current?.cellHeight(widgetWidth);
};
onResize();
if (typeof window === "undefined") return;
window.addEventListener("resize", onResize);
return () => {
if (typeof window === "undefined") return;
window.removeEventListener("resize", onResize);
};
}, [board.columnCount, mainRef, root, gridRef]);
// Define column count by using the sectionColumnCount
useEffect(() => {