Add DashboardComponentType enum and refactor dashboard component interfaces for improved type safety

This commit is contained in:
Simon Larsen 2024-11-14 18:10:03 +00:00
parent e279da47bf
commit fe0dc51bef
No known key found for this signature in database
GPG Key ID: 96C5DCA24769DBCA
17 changed files with 71 additions and 47 deletions

View File

@ -1,7 +1,7 @@
{{> Start this}}
{{> CustomLogo this}}
{{> EmailTitle title=(concat "Incident: " incidentTitle) }}
{{> EmailTitle title=(concat emailTitle) }}
{{> InfoBlock info="Incident state has changed. Here are the details: "}}

View File

@ -8,6 +8,7 @@ export enum ComponentInputType {
Number = "Number",
Decimal = "Decimal",
MetricsEditor = "MetricsEditor",
LongText = "Long Text",
}
@ -16,7 +17,7 @@ export interface ComponentArgument<T extends DashboardBaseComponent> {
description: string;
required: boolean;
type: ComponentInputType;
id: keyof T;
id: keyof T["arguments"];
isAdvanced?: boolean | undefined;
placeholder?: string | undefined;
}

View File

@ -1,11 +1,13 @@
import GenericObject from "../../GenericObject";
import { ObjectType } from "../../JSON";
import ObjectID from "../../ObjectID";
import DashboardComponentType from "../DashboardComponentType";
export default interface DashboardBaseComponent {
_type: ObjectType;
_type: ObjectType.DashboardComponent;
componentId: ObjectID;
componentType: DashboardComponentType;
topInDashboardUnits: number;
leftInDashboardUnits: number;
widthInDashboardUnits: number;

View File

@ -1,10 +1,10 @@
import { ObjectType } from "../../JSON";
import MetricsViewConfig from "../../Metrics/MetricsViewConfig";
import ObjectID from "../../ObjectID";
import DashboardComponentType from "../DashboardComponentType";
import BaseComponent from "./DashboardBaseComponent";
export default interface DashboardChartComponent extends BaseComponent {
_type: ObjectType.DashboardChartComponent;
componentType: DashboardComponentType.Chart;
componentId: ObjectID;
arguments: {
metricsViewConfig?: MetricsViewConfig | undefined;

View File

@ -1,9 +1,9 @@
import { ObjectType } from "../../JSON";
import ObjectID from "../../ObjectID";
import DashboardComponentType from "../DashboardComponentType";
import BaseComponent from "./DashboardBaseComponent";
export default interface DashboardTextComponent extends BaseComponent {
_type: ObjectType.DashboardTextComponent;
componentType: DashboardComponentType.Text;
componentId: ObjectID;
arguments: {
text: string;

View File

@ -1,10 +1,10 @@
import { ObjectType } from "../../JSON";
import MetricsViewConfig from "../../Metrics/MetricsViewConfig";
import ObjectID from "../../ObjectID";
import DashboardComponentType from "../DashboardComponentType";
import BaseComponent from "./DashboardBaseComponent";
export default interface DashboardValueComponent extends BaseComponent {
_type: ObjectType.DashboardValueComponent;
componentType: DashboardComponentType.Value;
componentId: ObjectID;
arguments: {
metricsViewConfig?: MetricsViewConfig | undefined;

View File

@ -0,0 +1,8 @@
enum DashboardComponentType {
Chart = 'Chart',
Value = 'Value',
Text = 'Text',
}
export default DashboardComponentType;

View File

@ -65,12 +65,8 @@ export enum ObjectType {
IsNull = "IsNull",
Includes = "Includes",
// Dashboard Components.
DashboardComponent = "DashboardComponent",
DashboardViewConfig = "DashboardViewConfig",
DashboardTextComponent = "DashboardTextComponent",
DashboardValueComponent = "DashboardValueComponent",
DashboardChartComponent = "DashboardChartComponent",
}
export type JSONValue =

View File

@ -7,7 +7,7 @@ export default class DashboardBaseComponentUtil {
throw new NotImplementedException();
}
public static getComponentConfigArguments(): Array<ComponentArgument> {
public static getComponentConfigArguments(): Array<ComponentArgument<any>> {
return [];
}
}

View File

@ -2,7 +2,6 @@ import DashboardChartComponent from "../../../Types/Dashboard/DashboardComponent
import { ObjectType } from "../../../Types/JSON";
import ObjectID from "../../../Types/ObjectID";
import DashboardBaseComponentUtil from "./DashboardBaseComponent";
import DashboardChartType from "../../../Types/Dashboard/Chart/ChartType";
import { ComponentArgument, ComponentInputType } from "../../../Types/Dashboard/DashboardComponents/ComponentArgument";
export default class DashboardChartComponentUtil extends DashboardBaseComponentUtil {
@ -14,9 +13,9 @@ export default class DashboardChartComponentUtil extends DashboardBaseComponentU
topInDashboardUnits: 0,
leftInDashboardUnits: 0,
componentId: ObjectID.generate(),
chartType: DashboardChartType.Line,
minHeightInDashboardUnits: 3,
minWidthInDashboardUnits: 6
minWidthInDashboardUnits: 6,
arguments: {}
};
}
@ -28,7 +27,7 @@ export default class DashboardChartComponentUtil extends DashboardBaseComponentU
description: "Please select the metrics to display on the chart",
required: true,
type: ComponentInputType.MetricsEditor,
key: "metricsViewConfig"
id: "metricsViewConfig"
});
return componentArguments;

View File

@ -12,11 +12,13 @@ export default class DashboardTextComponentUtil extends DashboardBaseComponentUt
heightInDashboardUnits: 1,
topInDashboardUnits: 0,
leftInDashboardUnits: 0,
text: "Hello, World!",
arguments: {
text: "Hello, World!",
isBold: false,
isItalic: false,
isUnderline: false
},
componentId: ObjectID.generate(),
isBold: false,
isItalic: false,
isUnderline: false,
minHeightInDashboardUnits: 1,
minWidthInDashboardUnits: 3
};
@ -30,7 +32,7 @@ export default class DashboardTextComponentUtil extends DashboardBaseComponentUt
description: "The text to display",
required: true,
type: ComponentInputType.LongText,
key: "text",
id: "text",
placeholder: "Hello, World!"
});
@ -39,7 +41,7 @@ export default class DashboardTextComponentUtil extends DashboardBaseComponentUt
description: "Whether the text should be bold",
required: false,
type: ComponentInputType.Boolean,
key: "isBold",
id: "isBold",
placeholder: "false"
});
@ -48,7 +50,7 @@ export default class DashboardTextComponentUtil extends DashboardBaseComponentUt
description: "Whether the text should be italic",
required: false,
type: ComponentInputType.Boolean,
key: "isItalic",
id: "isItalic",
placeholder: "false"
});
@ -57,7 +59,7 @@ export default class DashboardTextComponentUtil extends DashboardBaseComponentUt
description: "Whether the text should be underlined",
required: false,
type: ComponentInputType.Boolean,
key: "isUnderline",
id: "isUnderline",
placeholder: "false"
});

View File

@ -15,6 +15,7 @@ export default class DashboardValueComponentUtil extends DashboardBaseComponentU
componentId: ObjectID.generate(),
minHeightInDashboardUnits: 1,
minWidthInDashboardUnits: 1,
arguments: {}
};
}
@ -26,7 +27,7 @@ export default class DashboardValueComponentUtil extends DashboardBaseComponentU
description: "Please select the metrics to display on the chart",
required: true,
type: ComponentInputType.MetricsEditor,
key: "metricsViewConfig"
id: "metricsViewConfig"
});
return componentArguments;

View File

@ -43,6 +43,12 @@ export default class ComponentInputTypeToFormFieldType {
};
}
if(componentInputType === ComponentInputType.LongText) {
return {
fieldType: FormFieldSchemaType.LongText,
};
}
return {
fieldType: FormFieldSchemaType.Text,
dropdownOptions: [],

View File

@ -1,5 +1,4 @@
import FiltersForm from "Common/UI/Components/Filters/FiltersForm";
import FilterData from "Common/UI/Components/Filters/Types/FilterData";
import FieldType from "Common/UI/Components/Types/FieldType";
import React, { Fragment, FunctionComponent, ReactElement } from "react";
import DropdownUtil from "Common/UI/Utils/Dropdown";
@ -7,8 +6,7 @@ import MetricsAggregationType from "Common/Types/Metrics/MetricsAggregationType"
import Query from "Common/Types/BaseDatabase/Query";
import MetricsQuery from "Common/Types/Metrics/MetricsQuery";
import MetricNameAndUnit from "./Types/MetricNameAndUnit";
import GroupBy from "Common/UI/Utils/BaseDatabase/GroupBy";
import Metric from "Common/Models/AnalyticsModels/Metric";
import MetricQueryData from "Common/Types/Metrics/MetricQueryData";

View File

@ -1,6 +1,6 @@
import React, { FunctionComponent, ReactElement } from "react";
import MetricAlias, { MetricAliasData } from "./MetricAlias";
import MetricQuery, { MetricQueryData } from "./MetricQuery";
import MetricAlias from "./MetricAlias";
import MetricQuery from "./MetricQuery";
import BadDataException from "Common/Types/Exception/BadDataException";
import Card from "Common/UI/Components/Card/Card";
import Button, {
@ -9,6 +9,8 @@ import Button, {
} from "Common/UI/Components/Button/Button";
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";

View File

@ -9,10 +9,6 @@ import MonitorMetricTypeUtil from "Common/Utils/Monitor/MonitorMetricType";
import OneUptimeDate from "Common/Types/Date";
import InBetween from "Common/Types/BaseDatabase/InBetween";
import MetricView from "../Metrics/MetricView";
import {
ChartSeries,
MetricQueryConfigData,
} from "../Metrics/MetricQueryConfig";
import DashboardNavigation from "../../Utils/Navigation";
import MonitorMetricType from "Common/Types/Monitor/MonitorMetricType";
import MonitorType, {
@ -29,6 +25,7 @@ import Probe from "Common/Models/DatabaseModels/Probe";
import AggregateModel from "Common/Types/BaseDatabase/AggregatedModel";
import { JSONObject } from "Common/Types/JSON";
import JSONFunctions from "Common/Types/JSONFunctions";
import MetricQueryConfigData, { ChartSeries } from "Common/Types/Metrics/MetricQueryConfigData";
export interface ComponentProps {
monitorId: ObjectID;

View File

@ -211,8 +211,8 @@ RunCron(
const sms: SMS = {
message: `
Incident ${Text.uppercaseFirstLetter(
incidentStateTimeline.incidentState.name,
)} - ${statusPageName}
incidentStateTimeline.incidentState.name,
)} - ${statusPageName}
To view this incident, visit ${statusPageURL}
@ -232,6 +232,21 @@ RunCron(
});
}
let emailTitle = `Incident `;
const resourcesAffected = statusPageToResources[statuspage._id!]
?.map((r: StatusPageResource) => {
return r.displayName;
})
.join(", ") || '';
if (resourcesAffected) {
emailTitle += `on ${resourcesAffected} `;
}
emailTitle += `is ${incidentStateTimeline.incidentState.name}`;
if (subscriber.subscriberEmail) {
// send email here.
@ -240,23 +255,20 @@ RunCron(
toEmail: subscriber.subscriberEmail,
templateType: EmailTemplateType.SubscriberIncidentStateChanged,
vars: {
emailTitle: `Incident on `,
statusPageName: statusPageName,
statusPageUrl: statusPageURL,
logoUrl: statuspage.logoFileId
? new URL(httpProtocol, host)
.addRoute(FileRoute)
.addRoute("/image/" + statuspage.logoFileId)
.toString()
.addRoute(FileRoute)
.addRoute("/image/" + statuspage.logoFileId)
.toString()
: "",
isPublicStatusPage: statuspage.isPublicStatusPage
? "true"
: "false",
resourcesAffected:
statusPageToResources[statuspage._id!]
?.map((r: StatusPageResource) => {
return r.displayName;
})
.join(", ") || "None",
resourcesAffected || "None",
incidentSeverity: incident.incidentSeverity?.name || " - ",
incidentTitle: incident.title || "",
incidentDescription: incident.description || "",