Refactor Dashboard components for improved code consistency and readability

This commit is contained in:
Simon Larsen
2024-11-29 19:17:47 +00:00
parent b8fc933acb
commit c4256a0dea
11 changed files with 248 additions and 183 deletions

View File

@@ -73,5 +73,3 @@ export const ChartColors: Color[] = [
Cyan500,
Gray500,
];

View File

@@ -1,28 +1,27 @@
enum ColorSwatch {
Zinc = "zinc",
Neutra = "neutra",
Stone = "stone",
Slate = "slate",
Purple = "purple",
Pink = "pink",
Red = "red",
Orange = "orange",
Yellow = "yellow",
Green = "green",
Teal = "teal",
Cyan = "cyan",
Gray = "gray",
Moroon = "moroon",
Blue = "blue",
Indigo = "indigo",
Amber = "amber",
Lime = "lime",
Emerald = "emerald",
Sky = "sky",
Violet = "violet",
Fuchsia = "fuchsia",
Rose = "rose",
}
export default ColorSwatch;
Zinc = "zinc",
Neutra = "neutra",
Stone = "stone",
Slate = "slate",
Purple = "purple",
Pink = "pink",
Red = "red",
Orange = "orange",
Yellow = "yellow",
Green = "green",
Teal = "teal",
Cyan = "cyan",
Gray = "gray",
Moroon = "moroon",
Blue = "blue",
Indigo = "indigo",
Amber = "amber",
Lime = "lime",
Emerald = "emerald",
Sky = "sky",
Violet = "violet",
Fuchsia = "fuchsia",
Rose = "rose",
}
export default ColorSwatch;

View File

@@ -25,7 +25,7 @@ import MetricNameAndUnit from "../../Metrics/Types/MetricNameAndUnit";
import { GetReactElementFunction } from "Common/UI/Types/FunctionTypes";
export interface ComponentProps {
//eslint-disable react/no-unused-prop-types
// eslint-disable-next-line react/no-unused-prop-types
metrics: {
metricNameAndUnits: Array<MetricNameAndUnit>;
telemetryAttributes: string[];
@@ -75,7 +75,7 @@ const ArgumentsForm: FunctionComponent<ComponentProps> = (
value: FormValues<JSONObject>,
componentProps: CustomElementProps,
) => ReactElement) => {
//eslint-disable react/display-name
// eslint-disable-next-line react/display-name
return (
value: FormValues<JSONObject>,
componentProps: CustomElementProps,

View File

@@ -33,7 +33,7 @@ export interface DashboardBaseComponentProps {
dashboardCanvasWidthInPx: number;
dashboardCanvasHeightInPx: number;
dashboardViewConfig: DashboardViewConfig;
dashboardStartAndEndDate: DashboardStartAndEndDate;
dashboardStartAndEndDate: DashboardStartAndEndDate;
metricNameAndUnits: Array<MetricNameAndUnit>;
}

View File

@@ -18,21 +18,24 @@ export interface ComponentProps extends DashboardBaseComponentProps {
const DashboardChartComponentElement: FunctionComponent<ComponentProps> = (
props: ComponentProps,
): ReactElement => {
const [metricResults, setMetricResults] = React.useState<Array<AggregatedResult>>([]);
const [metricResults, setMetricResults] = React.useState<
Array<AggregatedResult>
>([]);
const [error, setError] = React.useState<string | null>(null);
const [isLoading, setIsLoading] = React.useState<boolean>(true);
const metricViewData: MetricViewData = {
queryConfigs: props.component.arguments.metricQueryConfig ? [props.component.arguments.metricQueryConfig] : [],
startAndEndDate: DashboardStartAndEndDateUtil.getStartAndEndDate(props.dashboardStartAndEndDate),
formulaConfigs: []
}
queryConfigs: props.component.arguments.metricQueryConfig
? [props.component.arguments.metricQueryConfig]
: [],
startAndEndDate: DashboardStartAndEndDateUtil.getStartAndEndDate(
props.dashboardStartAndEndDate,
),
formulaConfigs: [],
};
const fetchAggregatedResults: PromiseVoidFunction =
async (): Promise<void> => {
setIsLoading(true);
if (
@@ -66,17 +69,21 @@ const DashboardChartComponentElement: FunctionComponent<ComponentProps> = (
useEffect(() => {
fetchAggregatedResults();
}, [props.dashboardStartAndEndDate, props.component.arguments.metricQueryConfig, props.metricNameAndUnits]);
}, [
props.dashboardStartAndEndDate,
props.component.arguments.metricQueryConfig,
props.metricNameAndUnits,
]);
return <div>
<MetricCharts
metricResults={metricResults}
metricNamesAndUnits={props.metricNameAndUnits}
metricViewData={metricViewData}
/>
</div>;
return (
<div>
<MetricCharts
metricResults={metricResults}
metricNamesAndUnits={props.metricNameAndUnits}
metricViewData={metricViewData}
/>
</div>
);
};
export default DashboardChartComponentElement;

View File

@@ -4,49 +4,47 @@ import DashboardStartAndEndDateRange from "../Types/DashboardStartAndEndDateRang
import OneUptimeDate from "Common/Types/Date";
import IconProp from "Common/Types/Icon/IconProp";
import { GetReactElementFunction } from "Common/UI/Types/FunctionTypes";
import HeaderAlert, { HeaderAlertType } from "Common/UI/Components/HeaderAlert/HeaderAlert";
import HeaderAlert, {
HeaderAlertType,
} from "Common/UI/Components/HeaderAlert/HeaderAlert";
import ColorSwatch from "Common/Types/ColorSwatch";
export interface ComponentProps {
dashboardStartAndEndDate: DashboardStartAndEndDate;
onClick: () => void;
dashboardStartAndEndDate: DashboardStartAndEndDate;
onClick: () => void;
}
const DashboardStartAndEndDateView: FunctionComponent<ComponentProps> = (
props: ComponentProps,
props: ComponentProps,
): ReactElement => {
const isCustomRange: boolean =
props.dashboardStartAndEndDate.range ===
DashboardStartAndEndDateRange.CUSTOM;
const isCustomRange: boolean =
props.dashboardStartAndEndDate.range ===
DashboardStartAndEndDateRange.CUSTOM;
const getContent: GetReactElementFunction = (): ReactElement => {
const title: string = isCustomRange ? `${OneUptimeDate.getDateAsLocalFormattedString(
props.dashboardStartAndEndDate.startAndEndDate?.startValue ||
const getContent: GetReactElementFunction = (): ReactElement => {
const title: string = isCustomRange
? `${OneUptimeDate.getDateAsLocalFormattedString(
props.dashboardStartAndEndDate.startAndEndDate?.startValue ||
OneUptimeDate.getCurrentDate(),
)} - ${OneUptimeDate.getDateAsLocalFormattedString(
props.dashboardStartAndEndDate.startAndEndDate?.endValue ||
props.dashboardStartAndEndDate.startAndEndDate?.endValue ||
OneUptimeDate.getCurrentDate(),
)}` : props.dashboardStartAndEndDate.range
return (
<HeaderAlert
icon={IconProp.Clock}
onClick={props.onClick}
title={title}
alertType={HeaderAlertType.INFO}
colorSwatch={ColorSwatch.Blue}
tooltip="Click to change the date and time range of data on this dashboard."
/>
);
};
)}`
: props.dashboardStartAndEndDate.range;
return (
<div>
{getContent()}
</div>
);
<HeaderAlert
icon={IconProp.Clock}
onClick={props.onClick}
title={title}
alertType={HeaderAlertType.INFO}
colorSwatch={ColorSwatch.Blue}
tooltip="Click to change the date and time range of data on this dashboard."
/>
);
};
return <div>{getContent()}</div>;
};
export default DashboardStartAndEndDateView;

View File

@@ -46,7 +46,7 @@ const DashboardToolbar: FunctionComponent<ComponentProps> = (
</div>
{!props.isSaving && (
<div className="flex">
<div className="mt-2">
<div className="mt-2">
<DashboardStartAndEndDateView
dashboardStartAndEndDate={props.startAndEndDate}
onClick={() => {
@@ -54,8 +54,7 @@ const DashboardToolbar: FunctionComponent<ComponentProps> = (
setShowTimeSelectModal(true);
}}
/>
</div>
</div>
{isEditMode ? (
<MoreMenu menuIcon={IconProp.Add} text="Add Component">

View File

@@ -7,58 +7,122 @@ export default interface DashboardStartAndEndDate {
range: DashboardStartAndEndDateRange;
}
export class DashboardStartAndEndDateUtil {
public static getStartAndEndDate(dashboardStartAndEndDate: DashboardStartAndEndDate): InBetween<Date> {
const currentDate: Date = OneUptimeDate.getCurrentDate();
// 30 mins.
if(dashboardStartAndEndDate.range === DashboardStartAndEndDateRange.PAST_THIRTY_MINS) {
return new InBetween<Date>(OneUptimeDate.addRemoveMinutes(currentDate, -30), currentDate);
export class DashboardStartAndEndDateUtil {
public static getStartAndEndDate(
dashboardStartAndEndDate: DashboardStartAndEndDate,
): InBetween<Date> {
const currentDate: Date = OneUptimeDate.getCurrentDate();
// 30 mins.
if (
dashboardStartAndEndDate.range ===
DashboardStartAndEndDateRange.PAST_THIRTY_MINS
) {
return new InBetween<Date>(
OneUptimeDate.addRemoveMinutes(currentDate, -30),
currentDate,
);
}
if(dashboardStartAndEndDate.range === DashboardStartAndEndDateRange.PAST_ONE_HOUR) {
return new InBetween<Date>(OneUptimeDate.addRemoveHours(currentDate, -1), currentDate);
if (
dashboardStartAndEndDate.range ===
DashboardStartAndEndDateRange.PAST_ONE_HOUR
) {
return new InBetween<Date>(
OneUptimeDate.addRemoveHours(currentDate, -1),
currentDate,
);
}
// two hours.
if(dashboardStartAndEndDate.range === DashboardStartAndEndDateRange.PAST_TWO_HOURS) {
return new InBetween<Date>(OneUptimeDate.addRemoveHours(currentDate, -2), currentDate);
// two hours.
if (
dashboardStartAndEndDate.range ===
DashboardStartAndEndDateRange.PAST_TWO_HOURS
) {
return new InBetween<Date>(
OneUptimeDate.addRemoveHours(currentDate, -2),
currentDate,
);
}
// three hours
if(dashboardStartAndEndDate.range === DashboardStartAndEndDateRange.PAST_THREE_HOURS) {
return new InBetween<Date>(OneUptimeDate.addRemoveHours(currentDate, -3), currentDate);
// three hours
if (
dashboardStartAndEndDate.range ===
DashboardStartAndEndDateRange.PAST_THREE_HOURS
) {
return new InBetween<Date>(
OneUptimeDate.addRemoveHours(currentDate, -3),
currentDate,
);
}
if(dashboardStartAndEndDate.range === DashboardStartAndEndDateRange.PAST_ONE_DAY) {
return new InBetween<Date>(OneUptimeDate.addRemoveDays(currentDate, -1), currentDate);
if (
dashboardStartAndEndDate.range ===
DashboardStartAndEndDateRange.PAST_ONE_DAY
) {
return new InBetween<Date>(
OneUptimeDate.addRemoveDays(currentDate, -1),
currentDate,
);
}
// two days .
if(dashboardStartAndEndDate.range === DashboardStartAndEndDateRange.PAST_TWO_DAYS) {
return new InBetween<Date>(OneUptimeDate.addRemoveDays(currentDate, -2), currentDate);
if (
dashboardStartAndEndDate.range ===
DashboardStartAndEndDateRange.PAST_TWO_DAYS
) {
return new InBetween<Date>(
OneUptimeDate.addRemoveDays(currentDate, -2),
currentDate,
);
}
if(dashboardStartAndEndDate.range === DashboardStartAndEndDateRange.PAST_ONE_WEEK) {
return new InBetween<Date>(OneUptimeDate.addRemoveDays(currentDate, -7), currentDate);
if (
dashboardStartAndEndDate.range ===
DashboardStartAndEndDateRange.PAST_ONE_WEEK
) {
return new InBetween<Date>(
OneUptimeDate.addRemoveDays(currentDate, -7),
currentDate,
);
}
// two weeks.
if(dashboardStartAndEndDate.range === DashboardStartAndEndDateRange.PAST_TWO_WEEKS) {
return new InBetween<Date>(OneUptimeDate.addRemoveDays(currentDate, -14), currentDate);
// two weeks.
if (
dashboardStartAndEndDate.range ===
DashboardStartAndEndDateRange.PAST_TWO_WEEKS
) {
return new InBetween<Date>(
OneUptimeDate.addRemoveDays(currentDate, -14),
currentDate,
);
}
if(dashboardStartAndEndDate.range === DashboardStartAndEndDateRange.PAST_ONE_MONTH) {
return new InBetween<Date>(OneUptimeDate.addRemoveMonths(currentDate, -1), currentDate);
if (
dashboardStartAndEndDate.range ===
DashboardStartAndEndDateRange.PAST_ONE_MONTH
) {
return new InBetween<Date>(
OneUptimeDate.addRemoveMonths(currentDate, -1),
currentDate,
);
}
// three months.
if(dashboardStartAndEndDate.range === DashboardStartAndEndDateRange.PAST_THREE_MONTHS) {
return new InBetween<Date>(OneUptimeDate.addRemoveMonths(currentDate, -3), currentDate);
if (
dashboardStartAndEndDate.range ===
DashboardStartAndEndDateRange.PAST_THREE_MONTHS
) {
return new InBetween<Date>(
OneUptimeDate.addRemoveMonths(currentDate, -3),
currentDate,
);
}
// custom
return dashboardStartAndEndDate.startAndEndDate || new InBetween<Date>(currentDate, currentDate);
return (
dashboardStartAndEndDate.startAndEndDate ||
new InBetween<Date>(currentDate, currentDate)
);
}
}
}

View File

@@ -1,14 +1,14 @@
enum DashboardStartAndEndDateRange {
PAST_THIRTY_MINS = "Past 30 Mins",
PAST_ONE_HOUR = "Past 1 Hour",
PAST_TWO_HOURS = "Past 2 Hours",
PAST_THREE_HOURS = "Past 3 Hours",
PAST_ONE_DAY = "Past 1 Day",
PAST_TWO_DAYS = "Past 2 Days",
PAST_ONE_WEEK = "Past 1 Week",
PAST_TWO_WEEKS = "Past 2 Weeks",
PAST_ONE_MONTH = "Past 1 Month",
PAST_THREE_MONTHS = "Past 3 Months",
PAST_THIRTY_MINS = "Past 30 Mins",
PAST_ONE_HOUR = "Past 1 Hour",
PAST_TWO_HOURS = "Past 2 Hours",
PAST_THREE_HOURS = "Past 3 Hours",
PAST_ONE_DAY = "Past 1 Day",
PAST_TWO_DAYS = "Past 2 Days",
PAST_ONE_WEEK = "Past 1 Week",
PAST_TWO_WEEKS = "Past 2 Weeks",
PAST_ONE_MONTH = "Past 1 Month",
PAST_THREE_MONTHS = "Past 3 Months",
CUSTOM = "Custom",
}

View File

@@ -11,6 +11,7 @@ import MetricNameAndUnit from "./Types/MetricNameAndUnit";
import MetricQueryConfigData from "Common/Types/Metrics/MetricQueryConfigData";
import MetricAliasData from "Common/Types/Metrics/MetricAliasData";
import MetricQueryData from "Common/Types/Metrics/MetricQueryData";
import { GetReactElementFunction } from "Common/UI/Types/FunctionTypes";
export interface ComponentProps {
data: MetricQueryConfigData;
@@ -36,64 +37,65 @@ const MetricGraphConfig: FunctionComponent<ComponentProps> = (
throw new BadDataException("MetricQueryData is required");
}
const getContent = (): ReactElement => {
const getContent: GetReactElementFunction = (): ReactElement => {
return (
<div>{props.data.metricAliasData && (
<MetricAlias
data={props.data.metricAliasData}
onDataChanged={(data: MetricAliasData) => {
props.onBlur?.();
props.onFocus?.();
props.onChange &&
props.onChange({ ...props.data, metricAliasData: data });
}}
isFormula={false}
/>
)}
{props.data.metricQueryData && (
<MetricQuery
data={props.data.metricQueryData}
onDataChanged={(data: MetricQueryData) => {
props.onBlur?.();
props.onFocus?.();
props.onChange &&
props.onChange({ ...props.data, metricQueryData: data });
}}
metricNameAndUnits={props.metricNameAndUnits}
telemetryAttributes={props.telemetryAttributes}
/>
)}
{props.onRemove && (
<div className="-ml-3">
<Button
title={"Remove"}
onClick={() => {
props.onBlur?.();
props.onFocus?.();
return props.onRemove && props.onRemove();
}}
buttonSize={ButtonSize.Small}
buttonStyle={ButtonStyleType.DANGER_OUTLINE}
/>
<div>
{props.data.metricAliasData && (
<MetricAlias
data={props.data.metricAliasData}
onDataChanged={(data: MetricAliasData) => {
props.onBlur?.();
props.onFocus?.();
props.onChange &&
props.onChange({ ...props.data, metricAliasData: data });
}}
isFormula={false}
/>
)}
{props.data.metricQueryData && (
<MetricQuery
data={props.data.metricQueryData}
onDataChanged={(data: MetricQueryData) => {
props.onBlur?.();
props.onFocus?.();
props.onChange &&
props.onChange({ ...props.data, metricQueryData: data });
}}
metricNameAndUnits={props.metricNameAndUnits}
telemetryAttributes={props.telemetryAttributes}
/>
)}
{props.onRemove && (
<div className="-ml-3">
<Button
title={"Remove"}
onClick={() => {
props.onBlur?.();
props.onFocus?.();
return props.onRemove && props.onRemove();
}}
buttonSize={ButtonSize.Small}
buttonStyle={ButtonStyleType.DANGER_OUTLINE}
/>
</div>
)}
{props.error && (
<p data-testid="error-message" className="mt-1 text-sm text-red-400">
{props.error}
</p>
)}
</div>
)}
{props.error && (
<p data-testid="error-message" className="mt-1 text-sm text-red-400">
{props.error}
</p>
)}
</div>);
}
);
};
if(props.hideCard) {
if (props.hideCard) {
return getContent();
}
return (
<Card>
<div className="-mt-5" tabIndex={props.tabIndex}>
{getContent()}
{getContent()}
</div>
</Card>
);

View File

@@ -19,8 +19,6 @@ import MetricViewData from "../Types/MetricViewData";
import OneUptimeDate from "Common/Types/Date";
export default class MetricUtil {
public static async fetchResults(data: {
metricViewData: MetricViewData;
}): Promise<Array<AggregatedResult>> {
@@ -122,14 +120,14 @@ export default class MetricUtil {
const metricAttributesResponse:
| HTTPResponse<JSONObject>
| HTTPErrorResponse = await API.post(
URL.fromString(APP_API_URL.toString()).addRoute(
"/telemetry/metrics/get-attributes",
),
{},
{
...ModelAPI.getCommonHeaders(),
},
);
URL.fromString(APP_API_URL.toString()).addRoute(
"/telemetry/metrics/get-attributes",
),
{},
{
...ModelAPI.getCommonHeaders(),
},
);
let attributes: Array<string> = [];