mirror of
https://github.com/OneUptime/oneuptime
synced 2024-11-21 22:59:07 +00:00
Refactor DashboardViewConfig enum to use explicit types for default height and width
This commit is contained in:
parent
b31ffab577
commit
75ab4bd946
@ -1,7 +1,8 @@
|
||||
import { ObjectType } from "../../JSON";
|
||||
import ObjectID from "../../ObjectID";
|
||||
|
||||
export default interface DashboardBaseComponent {
|
||||
_type: string;
|
||||
_type: ObjectType;
|
||||
componentId: ObjectID;
|
||||
topInDashboardUnits: number;
|
||||
leftInDashboardUnits: number;
|
||||
|
@ -1,9 +1,10 @@
|
||||
import { ObjectType } from "../../JSON";
|
||||
import ObjectID from "../../ObjectID";
|
||||
import ChartType from "../Chart/ChartType";
|
||||
import BaseComponent from "./DashboardBaseComponent";
|
||||
|
||||
export default interface DashboardChartComponent extends BaseComponent {
|
||||
_type: "DashboardChartComponent";
|
||||
_type: ObjectType.DashboardChartComponent;
|
||||
componentId: ObjectID;
|
||||
chartType: ChartType;
|
||||
}
|
||||
|
@ -1,8 +1,9 @@
|
||||
import { ObjectType } from "../../JSON";
|
||||
import ObjectID from "../../ObjectID";
|
||||
import BaseComponent from "./DashboardBaseComponent";
|
||||
|
||||
export default interface DashboardTextComponent extends BaseComponent {
|
||||
_type: "DashboardTextComponent";
|
||||
_type: ObjectType.DashboardTextComponent;
|
||||
componentId: ObjectID;
|
||||
text: string;
|
||||
}
|
||||
|
@ -1,7 +1,8 @@
|
||||
import { ObjectType } from "../../JSON";
|
||||
import ObjectID from "../../ObjectID";
|
||||
import BaseComponent from "./DashboardBaseComponent";
|
||||
|
||||
export default interface DashboardValueComponent extends BaseComponent {
|
||||
_type: "DashboardValueComponent";
|
||||
_type: ObjectType.DashboardValueComponent;
|
||||
componentId: ObjectID;
|
||||
}
|
||||
|
@ -1,6 +1,9 @@
|
||||
import { ObjectType } from "../JSON";
|
||||
import DashboardBaseComponent from "./DashboardComponents/DashboardBaseComponent";
|
||||
|
||||
export default interface DashboardViewConfig {
|
||||
_type: "DashboardViewConfig";
|
||||
_type: ObjectType.DashboardViewConfig;
|
||||
components: Array<DashboardBaseComponent>;
|
||||
heightInDashboardUnits: number;
|
||||
widthInDashboardUnits: number;
|
||||
}
|
||||
|
@ -66,6 +66,7 @@ export enum ObjectType {
|
||||
Includes = "Includes",
|
||||
|
||||
// Dashboard Components.
|
||||
|
||||
DashboardViewConfig = "DashboardViewConfig",
|
||||
DashboardTextComponent = "DashboardTextComponent",
|
||||
DashboardValueComponent = "DashboardValueComponent",
|
||||
|
@ -1,12 +1,65 @@
|
||||
import DashboardViewConfig from "../../Types/Dashboard/DashboardViewConfig";
|
||||
import { ObjectType } from "../../Types/JSON";
|
||||
import DashboardSize from "../../Types/Dashboard/DashboardSize";
|
||||
import DashboardBaseComponent from "../../Types/Dashboard/DashboardComponents/DashboardBaseComponent";
|
||||
|
||||
export default class DashboardViewConfigUtil {
|
||||
public static createDefaultDashboardViewConfig(): DashboardViewConfig {
|
||||
return {
|
||||
_type: "DashboardViewConfig",
|
||||
_type: ObjectType.DashboardViewConfig,
|
||||
components: [],
|
||||
widthInDashboardUnits: DashboardSize.widthInDashboardUnits,
|
||||
heightInDashboardUnits: DashboardSize.heightInDashboardUnits,
|
||||
};
|
||||
}
|
||||
|
||||
public static addDefaultChartComponent(): DashboardViewConfig {}
|
||||
public static addComponentToDashboard(data: {
|
||||
component: DashboardBaseComponent;
|
||||
dashboardViewConfig: DashboardViewConfig;
|
||||
}): DashboardViewConfig {
|
||||
const heightOfComponent: number = data.component.heightInDashboardUnits;
|
||||
|
||||
// find the last row that has enough space to fit the component. If there is no such row, create a new row or rows to fit the component.
|
||||
const allComponentsFromDashboard: Array<DashboardBaseComponent> =
|
||||
data.dashboardViewConfig.components;
|
||||
|
||||
let componentTopPosition: number = 0;
|
||||
let componentLeftPosition: number = 0;
|
||||
|
||||
// find the last row that has the component.
|
||||
|
||||
let lastRowThatHasComponent: number = 0;
|
||||
|
||||
for (const dashboardComponent of allComponentsFromDashboard) {
|
||||
if (dashboardComponent.topInDashboardUnits < componentTopPosition) {
|
||||
lastRowThatHasComponent = componentTopPosition;
|
||||
}
|
||||
}
|
||||
|
||||
componentTopPosition = lastRowThatHasComponent + 1;
|
||||
|
||||
// check height of the component. If it is bigger than the last row that has the component, create more rows and udate the height of dashboardViewConfig.
|
||||
|
||||
if (
|
||||
componentTopPosition + heightOfComponent >
|
||||
data.dashboardViewConfig.heightInDashboardUnits
|
||||
) {
|
||||
data.dashboardViewConfig.heightInDashboardUnits =
|
||||
componentTopPosition + heightOfComponent;
|
||||
}
|
||||
|
||||
// left position of the component is always 0.
|
||||
componentLeftPosition = 0;
|
||||
|
||||
const newComponent: DashboardBaseComponent = {
|
||||
...data.component,
|
||||
topInDashboardUnits: componentTopPosition,
|
||||
leftInDashboardUnits: componentLeftPosition,
|
||||
};
|
||||
|
||||
// Add the new component to the dashboard configuration
|
||||
data.dashboardViewConfig.components.push(newComponent);
|
||||
|
||||
return { ...data.dashboardViewConfig };
|
||||
}
|
||||
}
|
||||
|
@ -1,29 +1,34 @@
|
||||
import React, { FunctionComponent, ReactElement } from "react";
|
||||
import DefaultDashboardSize from "Common/Types/Dashboard/DashboardSize";
|
||||
import BlankRowElement from "./BlankRow";
|
||||
import DashboardViewConfig from "Common/Types/Dashboard/DashboardViewConfig";
|
||||
|
||||
export interface ComponentProps {
|
||||
dashboardViewConfig: DashboardViewConfig;
|
||||
onDrop: (top: number, left: number) => void;
|
||||
}
|
||||
|
||||
const BlankCanvasElement: FunctionComponent<ComponentProps> = (
|
||||
props: ComponentProps,
|
||||
porps: ComponentProps,
|
||||
): ReactElement => {
|
||||
const defaultHeight: number = DefaultDashboardSize.heightInDashboardUnits;
|
||||
const height: number =
|
||||
porps.dashboardViewConfig.heightInDashboardUnits ||
|
||||
DefaultDashboardSize.heightInDashboardUnits;
|
||||
|
||||
return (
|
||||
<div className="">
|
||||
{Array.from(Array(defaultHeight).keys()).map(
|
||||
(_: number, index: number) => {
|
||||
return (
|
||||
<BlankRowElement
|
||||
key={index}
|
||||
rowNumber={index}
|
||||
onDrop={props.onDrop}
|
||||
/>
|
||||
);
|
||||
},
|
||||
)}
|
||||
{Array.from(Array(height).keys()).map((_: number, index: number) => {
|
||||
return (
|
||||
<BlankRowElement
|
||||
dashboardViewConfig={porps.dashboardViewConfig}
|
||||
key={index}
|
||||
rowNumber={index}
|
||||
onDrop={(top: number, left: number) => {
|
||||
porps.onDrop(top, left);
|
||||
}}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
@ -1,16 +1,20 @@
|
||||
import React, { FunctionComponent, ReactElement } from "react";
|
||||
import DefaultDashboardSize from "Common/Types/Dashboard/DashboardSize";
|
||||
import DashboardUnitElement from "./DashboardUnit";
|
||||
import DashboardViewConfig from "Common/Types/Dashboard/DashboardViewConfig";
|
||||
|
||||
export interface ComponentProps {
|
||||
rowNumber: number;
|
||||
onDrop: (top: number, left: number) => void;
|
||||
dashboardViewConfig: DashboardViewConfig;
|
||||
}
|
||||
|
||||
const BlankRowElement: FunctionComponent<ComponentProps> = (
|
||||
props: ComponentProps,
|
||||
): ReactElement => {
|
||||
const defaultRowLength: number = DefaultDashboardSize.widthInDashboardUnits;
|
||||
const defaultRowLength: number =
|
||||
props.dashboardViewConfig.widthInDashboardUnits ||
|
||||
DefaultDashboardSize.widthInDashboardUnits;
|
||||
|
||||
return (
|
||||
<div className="flex">
|
||||
|
@ -1,12 +1,20 @@
|
||||
import React, { FunctionComponent, ReactElement } from "react";
|
||||
import BlankCanvasElement from "./BlankCanvas";
|
||||
import DashboardViewConfig from "Common/Types/Dashboard/DashboardViewConfig";
|
||||
|
||||
export interface ComponentProps {}
|
||||
export interface ComponentProps {
|
||||
dashboardViewConfig: DashboardViewConfig;
|
||||
onDashboardViewConfigChange: (newConfig: DashboardViewConfig) => void;
|
||||
}
|
||||
|
||||
const DashboardCanvas: FunctionComponent<ComponentProps> = (
|
||||
_props: ComponentProps,
|
||||
props: ComponentProps,
|
||||
): ReactElement => {
|
||||
return <BlankCanvasElement onDrop={() => {}} />;
|
||||
if (!props.dashboardViewConfig) {
|
||||
return <BlankCanvasElement onDrop={() => {}} dashboardViewConfig={props.dashboardViewConfig} />;
|
||||
}
|
||||
|
||||
return <BlankCanvasElement onDrop={() => {}} dashboardViewConfig={props.dashboardViewConfig} />;
|
||||
};
|
||||
|
||||
export default DashboardCanvas;
|
||||
|
@ -1,18 +1,93 @@
|
||||
import React, { FunctionComponent, ReactElement, useState } from "react";
|
||||
import React, {
|
||||
FunctionComponent,
|
||||
ReactElement,
|
||||
useEffect,
|
||||
useState,
|
||||
} from "react";
|
||||
import DashboardToolbar from "./Toolbar/DashboardToolbar";
|
||||
import DashboardCanvas from "./Canvas/Index";
|
||||
import DashboardMode from "Common/Types/Dashboard/DashboardMode";
|
||||
import DashboardComponentType from "Common/Types/Dashboard/DashboardComponentType";
|
||||
import DashboardViewConfig from "Common/Types/Dashboard/DashboardViewConfig";
|
||||
import { ObjectType } from "Common/Types/JSON";
|
||||
import DashboardBaseComponent from "Common/Types/Dashboard/DashboardComponents/DashboardBaseComponent";
|
||||
import DashboardChartComponentUtil from "Common/Utils/Dashboard/Components/DashboardChartComponent";
|
||||
import DashboardValueComponentUtil from "Common/Utils/Dashboard/Components/DashboardValueComponent";
|
||||
import DashboardTextComponentUtil from "Common/Utils/Dashboard/Components/DashboardTextComponent";
|
||||
import BadDataException from "Common/Types/Exception/BadDataException";
|
||||
import ObjectID from "Common/Types/ObjectID";
|
||||
import Dashboard from "Common/Models/DatabaseModels/Dashboard";
|
||||
import ModelAPI from "Common/UI/Utils/ModelAPI/ModelAPI";
|
||||
import API from "Common/UI/Utils/API/API";
|
||||
import ErrorMessage from "Common/UI/Components/ErrorMessage/ErrorMessage";
|
||||
import PageLoader from "Common/UI/Components/Loader/PageLoader";
|
||||
import DashboardViewConfigUtil from "Common/Utils/Dashboard/DashboardViewConfig";
|
||||
import DefaultDashboardSize from "Common/Types/Dashboard/DashboardSize";
|
||||
import { PromiseVoidFunction } from "Common/Types/FunctionTypes";
|
||||
|
||||
export interface ComponentProps {}
|
||||
export interface ComponentProps {
|
||||
dashboardId: ObjectID;
|
||||
}
|
||||
|
||||
const DashboardViewer: FunctionComponent<ComponentProps> = (
|
||||
_props: ComponentProps,
|
||||
props: ComponentProps,
|
||||
): ReactElement => {
|
||||
const [dashboardMode, setDashboardMode] = useState<DashboardMode>(
|
||||
DashboardMode.View,
|
||||
);
|
||||
|
||||
const [dashboardViewConfig, setDashboardViewConfig] =
|
||||
useState<DashboardViewConfig>({
|
||||
_type: ObjectType.DashboardViewConfig,
|
||||
components: [],
|
||||
heightInDashboardUnits: DefaultDashboardSize.heightInDashboardUnits,
|
||||
widthInDashboardUnits: DefaultDashboardSize.widthInDashboardUnits,
|
||||
});
|
||||
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
const [isLoading, setIsLoading] = useState<boolean>(false);
|
||||
|
||||
const fetchDashboardViewConfig: PromiseVoidFunction = async (): Promise<void> => {
|
||||
try {
|
||||
setIsLoading(true);
|
||||
const dashboard: Dashboard | null = await ModelAPI.getItem({
|
||||
modelType: Dashboard,
|
||||
id: props.dashboardId,
|
||||
select: {
|
||||
dashboardViewConfig: true,
|
||||
name: true,
|
||||
description: true,
|
||||
},
|
||||
});
|
||||
|
||||
if (!dashboard) {
|
||||
setError("Dashboard not found");
|
||||
return;
|
||||
}
|
||||
|
||||
setDashboardViewConfig(dashboard.dashboardViewConfig!);
|
||||
} catch (err) {
|
||||
setError(API.getFriendlyErrorMessage(err as Error));
|
||||
}
|
||||
|
||||
setIsLoading(false);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
// Fetch the dashboard view config from the server
|
||||
fetchDashboardViewConfig().catch((err: Error) => {
|
||||
setError(API.getFriendlyErrorMessage(err as Error));
|
||||
});
|
||||
}, []);
|
||||
|
||||
if (error) {
|
||||
return <ErrorMessage error={error} />;
|
||||
}
|
||||
|
||||
if (isLoading) {
|
||||
return <PageLoader isVisible={true} />;
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<DashboardToolbar
|
||||
@ -26,9 +101,42 @@ const DashboardViewer: FunctionComponent<ComponentProps> = (
|
||||
onEditClick={() => {
|
||||
setDashboardMode(DashboardMode.Edit);
|
||||
}}
|
||||
onAddComponentClick={(componentType: DashboardComponentType) => {}}
|
||||
onAddComponentClick={(componentType: DashboardComponentType) => {
|
||||
let newComponent: DashboardBaseComponent | null = null;
|
||||
|
||||
if (componentType === DashboardComponentType.Chart) {
|
||||
newComponent = DashboardChartComponentUtil.getDefaultComponent();
|
||||
}
|
||||
|
||||
if (componentType === DashboardComponentType.Value) {
|
||||
newComponent = DashboardValueComponentUtil.getDefaultComponent();
|
||||
}
|
||||
|
||||
if (componentType === DashboardComponentType.Text) {
|
||||
newComponent = DashboardTextComponentUtil.getDefaultComponent();
|
||||
}
|
||||
|
||||
if (!newComponent) {
|
||||
throw new BadDataException(
|
||||
`Unknown component type: ${componentType}`,
|
||||
);
|
||||
}
|
||||
|
||||
const newDashboardConfig: DashboardViewConfig =
|
||||
DashboardViewConfigUtil.addComponentToDashboard({
|
||||
component: newComponent,
|
||||
dashboardViewConfig: dashboardViewConfig,
|
||||
});
|
||||
|
||||
setDashboardViewConfig(newDashboardConfig);
|
||||
}}
|
||||
/>
|
||||
<DashboardCanvas
|
||||
dashboardViewConfig={dashboardViewConfig}
|
||||
onDashboardViewConfigChange={(newConfig: DashboardViewConfig) => {
|
||||
setDashboardViewConfig(newConfig);
|
||||
}}
|
||||
/>
|
||||
<DashboardCanvas />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
@ -118,7 +118,7 @@ const DashboardView: FunctionComponent<
|
||||
}}
|
||||
/>
|
||||
|
||||
<DashboardViewer />
|
||||
<DashboardViewer dashboardId={modelId} />
|
||||
</Fragment>
|
||||
);
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user