🎨 Improved changeability of wrappers with new wrapper content component

This commit is contained in:
Meierschlumpf
2022-12-19 18:03:52 +01:00
parent 8f7a3111ca
commit 383a7fa04b
6 changed files with 91 additions and 117 deletions

View File

@@ -8,13 +8,14 @@ import { GridstackTileWrapper } from '../../Tiles/TileWrapper';
import { useEditModeStore } from '../../Views/useEditModeStore';
import { useGridstack } from '../gridstack/use-gridstack';
import { CategoryEditMenu } from './CategoryEditMenu';
import { WrapperContent } from '../WrapperContent';
interface DashboardCategoryProps {
category: CategoryType;
}
export const DashboardCategory = ({ category }: DashboardCategoryProps) => {
const { refs, items, widgets } = useGridstack('category', category.id);
const { refs, apps, widgets } = useGridstack('category', category.id);
const isEditMode = useEditModeStore((x) => x.enabled);
return (
@@ -29,42 +30,7 @@ export const DashboardCategory = ({ category }: DashboardCategoryProps) => {
data-category={category.id}
ref={refs.wrapper}
>
{items?.map((app) => {
const { component: TileComponent, ...tile } = Tiles['app'];
return (
<GridstackTileWrapper
id={app.id}
type="app"
key={app.id}
itemRef={refs.items.current[app.id]}
{...tile}
{...app.shape.location}
{...app.shape.size}
>
<TileComponent className="grid-stack-item-content" app={app} />
</GridstackTileWrapper>
);
})}
{widgets.map((widget) => {
const definition = Widgets[widget.id as keyof typeof Widgets] as
| IWidgetDefinition
| undefined;
if (!definition) return null;
return (
<GridstackTileWrapper
type="widget"
key={widget.id}
itemRef={refs.items.current[widget.id]}
id={definition.id}
{...definition.gridstack}
{...widget.shape.location}
{...widget.shape.size}
>
<definition.component className="grid-stack-item-content" widget={widget} />
</GridstackTileWrapper>
);
})}
<WrapperContent apps={apps} refs={refs} widgets={widgets} />
</div>
</HomarrCardWrapper>
);

View File

@@ -5,13 +5,14 @@ import { Tiles } from '../../Tiles/tilesDefinitions';
import Widgets from '../../../../widgets';
import { GridstackTileWrapper } from '../../Tiles/TileWrapper';
import { useGridstack } from '../gridstack/use-gridstack';
import { WrapperContent } from '../WrapperContent';
interface DashboardSidebarProps {
location: 'right' | 'left';
}
export const DashboardSidebar = ({ location }: DashboardSidebarProps) => {
const { refs, items, widgets } = useGridstack('sidebar', location);
const { refs, apps, widgets } = useGridstack('sidebar', location);
const minRow = useMinRowForFullHeight(refs.wrapper);
@@ -31,42 +32,7 @@ export const DashboardSidebar = ({ location }: DashboardSidebarProps) => {
gs-min-row={minRow}
ref={refs.wrapper}
>
{items.map((app) => {
const { component: TileComponent, ...tile } = Tiles['app'];
return (
<GridstackTileWrapper
id={app.id}
type="app"
key={app.id}
itemRef={refs.items.current[app.id]}
{...tile}
{...app.shape.location}
{...app.shape.size}
>
<TileComponent className="grid-stack-item-content" app={app} />
</GridstackTileWrapper>
);
})}
{widgets.map((widget) => {
const definition = Widgets[widget.id as keyof typeof Widgets] as
| IWidgetDefinition
| undefined;
if (!definition) return null;
return (
<GridstackTileWrapper
type="widget"
key={widget.id}
itemRef={refs.items.current[widget.id]}
id={definition.id}
{...definition.gridstack}
{...widget.shape.location}
{...widget.shape.size}
>
<definition.component className="grid-stack-item-content" widget={widget} />
</GridstackTileWrapper>
);
})}
<WrapperContent apps={apps} refs={refs} widgets={widgets} />
</div>
</Card>
);

View File

@@ -1,16 +1,13 @@
import { WrapperType } from '../../../../types/wrapper';
import Widgets from '../../../../widgets';
import { IWidget, IWidgetDefinition } from '../../../../widgets/widgets';
import { Tiles } from '../../Tiles/tilesDefinitions';
import { GridstackTileWrapper } from '../../Tiles/TileWrapper';
import { useGridstack } from '../gridstack/use-gridstack';
import { WrapperContent } from '../WrapperContent';
interface DashboardWrapperProps {
wrapper: WrapperType;
}
export const DashboardWrapper = ({ wrapper }: DashboardWrapperProps) => {
const { refs, items, widgets } = useGridstack('wrapper', wrapper.id);
const { refs, apps, widgets } = useGridstack('wrapper', wrapper.id);
return (
<div
@@ -19,42 +16,7 @@ export const DashboardWrapper = ({ wrapper }: DashboardWrapperProps) => {
data-wrapper={wrapper.id}
ref={refs.wrapper}
>
{items?.map((app) => {
const { component: TileComponent, ...tile } = Tiles['app'];
return (
<GridstackTileWrapper
id={app.id}
type="app"
key={app.id}
itemRef={refs.items.current[app.id]}
{...tile}
{...app.shape.location}
{...app.shape.size}
>
<TileComponent className="grid-stack-item-content" app={app} />
</GridstackTileWrapper>
);
})}
{widgets.map((widget) => {
const definition = Widgets[widget.id as keyof typeof Widgets] as
| IWidgetDefinition
| undefined;
if (!definition) return null;
return (
<GridstackTileWrapper
type="widget"
key={widget.id}
itemRef={refs.items.current[widget.id]}
id={definition.id}
{...definition.gridstack}
{...widget.shape.location}
{...widget.shape.size}
>
<definition.component className="grid-stack-item-content" widget={widget} />
</GridstackTileWrapper>
);
})}
<WrapperContent apps={apps} refs={refs} widgets={widgets} />
</div>
);
};

View File

@@ -0,0 +1,60 @@
import { GridStack } from 'fily-publish-gridstack';
import { MutableRefObject, RefObject } from 'react';
import { AppType } from '../../../types/app';
import Widgets from '../../../widgets';
import { IWidget, IWidgetDefinition } from '../../../widgets/widgets';
import { Tiles } from '../Tiles/tilesDefinitions';
import { GridstackTileWrapper } from '../Tiles/TileWrapper';
interface WrapperContentProps {
apps: AppType[];
widgets: IWidget<string, any>[];
refs: {
wrapper: RefObject<HTMLDivElement>;
items: MutableRefObject<Record<string, RefObject<HTMLDivElement>>>;
gridstack: MutableRefObject<GridStack | undefined>;
};
}
export const WrapperContent = ({ apps, refs, widgets }: WrapperContentProps) => {
return (
<>
{apps?.map((app) => {
const { component: TileComponent, ...tile } = Tiles['app'];
return (
<GridstackTileWrapper
id={app.id}
type="app"
key={app.id}
itemRef={refs.items.current[app.id]}
{...tile}
{...app.shape.location}
{...app.shape.size}
>
<TileComponent className="grid-stack-item-content" app={app} />
</GridstackTileWrapper>
);
})}
{widgets.map((widget) => {
const definition = Widgets[widget.id as keyof typeof Widgets] as
| IWidgetDefinition
| undefined;
if (!definition) return null;
return (
<GridstackTileWrapper
type="widget"
key={widget.id}
itemRef={refs.items.current[widget.id]}
id={definition.id}
{...definition.gridstack}
{...widget.shape.location}
{...widget.shape.size}
>
<definition.component className="grid-stack-item-content" widget={widget} />
</GridstackTileWrapper>
);
})}
</>
);
};

View File

@@ -17,7 +17,7 @@ import { useEditModeStore } from '../../Views/useEditModeStore';
import { initializeGridstack } from './init-gridstack';
interface UseGristackReturnType {
items: AppType[];
apps: AppType[];
widgets: IWidget<string, any>[];
refs: {
wrapper: RefObject<HTMLDivElement>;
@@ -211,7 +211,7 @@ export const useGridstack = (
}, [items.length, wrapperRef.current, (widgets ?? []).length]);
return {
items,
apps: items,
widgets: widgets ?? [],
refs: {
items: itemRefs,

View File

@@ -0,0 +1,20 @@
import { ReactNode } from 'react';
import { HomarrCardWrapper } from '../components/Dashboard/Tiles/HomarrCardWrapper';
import { WidgetsMenu } from '../components/Dashboard/Tiles/Widgets/WidgetsMenu';
import { IWidget } from './widgets';
interface WidgetWrapperProps {
widgetId: string;
widget: IWidget<string, any>;
className: string;
children: ReactNode;
}
export const WidgetWrapper = ({ widgetId, widget, className, children }: WidgetWrapperProps) => {
return (
<HomarrCardWrapper className={className}>
<WidgetsMenu integration={widgetId} widget={widget} />
{children}
</HomarrCardWrapper>
);
};