Refactor DashboardService to include DashboardViewConfig

This commit is contained in:
Simon Larsen 2024-10-23 13:07:47 +01:00
parent 7bcecd0a1d
commit 97de3ff6c7
No known key found for this signature in database
GPG Key ID: 96C5DCA24769DBCA
10 changed files with 96 additions and 12 deletions

View File

@ -13,6 +13,7 @@ import TelemetryAPI from "Common/Server/API/TelemetryAPI";
import Ingestor from "Common/Server/API/ProbeAPI";
import ProjectAPI from "Common/Server/API/ProjectAPI";
import ProjectSsoAPI from "Common/Server/API/ProjectSSO";
// Import API
import ResellerPlanAPI from "Common/Server/API/ResellerPlanAPI";
import ShortLinkAPI from "Common/Server/API/ShortLinkAPI";
@ -59,6 +60,11 @@ import AlertNoteTemplateService, {
import AlertOwnerTeamService, {
Service as AlertOwnerTeamServiceType,
} from "Common/Server/Services/AlertOwnerTeamService";
import DashboardService, {
Service as DashboardServiceType,
} from "Common/Server/Services/DashboardService";
import AlertOwnerUserService, {
Service as AlertOwnerUserServiceType,
} from "Common/Server/Services/AlertOwnerUserService";
@ -374,6 +380,7 @@ import CallLog from "Common/Models/DatabaseModels/CallLog";
import Domain from "Common/Models/DatabaseModels/Domain";
import EmailLog from "Common/Models/DatabaseModels/EmailLog";
import EmailVerificationToken from "Common/Models/DatabaseModels/EmailVerificationToken";
import Dashboard from "Common/Models/DatabaseModels/Dashboard";
import Alert from "Common/Models/DatabaseModels/Alert";
import AlertCustomField from "Common/Models/DatabaseModels/AlertCustomField";
@ -638,6 +645,14 @@ const BaseAPIFeatureSet: FeatureSet = {
).getRouter(),
);
app.use(
`/${APP_NAME.toLocaleLowerCase()}`,
new BaseAPI<Dashboard, DashboardServiceType>(
Dashboard,
DashboardService,
).getRouter(),
);
app.use(
`/${APP_NAME.toLocaleLowerCase()}`,
new BaseAnalyticsAPI<Metric, MetricServiceType>(

View File

@ -0,0 +1,50 @@
import CreateBy from "../Types/Database/CreateBy";
import { OnCreate } from "../Types/Database/Hooks";
import DatabaseService from "./DatabaseService";
import BadDataException from "../../Types/Exception/BadDataException";
import Model from "Common/Models/DatabaseModels/Dashboard";
import { IsBillingEnabled } from "../EnvironmentConfig";
import { PlanType } from "../../Types/Billing/SubscriptionPlan";
import DashboardViewConfigUtil from "../../Utils/Dashboard/DashboardViewConfig";
export class Service extends DatabaseService<Model> {
public constructor() {
super(Model);
}
protected override async onBeforeCreate(
createBy: CreateBy<Model>,
): Promise<OnCreate<Model>> {
if (IsBillingEnabled) {
// then if free plan, make sure it can only have 1 dashboard.
if (createBy.props.currentPlan === PlanType.Free) {
// get count by project id.
const count: number = (
await this.countBy({
query: {
projectId: createBy.data.projectId,
},
props: {
isRoot: true,
},
})
).toNumber();
if (count > 0) {
throw new BadDataException(
"Free plan can only have 1 dashboard. Please upgrade your plan.",
);
}
}
}
// make sure dashboard config is empty.
createBy.data.dashboardViewConfig =
DashboardViewConfigUtil.createDefaultDashboardViewConfig();
return Promise.resolve({ createBy, carryForward: null });
}
}
export default new Service();

View File

@ -263,7 +263,13 @@ describe("SubscriptionPlan", () => {
});
describe("isUnpaid", () => {
it("should return true if the subscription status is unpaid", () => {
const subscriptionStatuses: Array<string> = ["incomplete", "incomplete_expired", "past_due", "canceled", "unpaid"];
const subscriptionStatuses: Array<string> = [
"incomplete",
"incomplete_expired",
"past_due",
"canceled",
"unpaid",
];
for (const subscriptionStatus of subscriptionStatuses) {
const result: boolean = SubscriptionPlan.isUnpaid(subscriptionStatus);

View File

@ -1,6 +1,6 @@
import ObjectID from "../../ObjectID";
import ChartType from "../Chart/ChartType";
import BaseComponent from "./BaseComponent";
import BaseComponent from "./DashboardBaseComponent";
export default interface ChartDashboardComponent extends BaseComponent {
type: "chart";

View File

@ -1,6 +1,6 @@
import ObjectID from "../../ObjectID";
export default interface BaseComponent {
export default interface DashboardBaseComponent {
type: string;
componentId: ObjectID;
}

View File

@ -1,3 +1,3 @@
import BaseComponent from "./BaseComponent";
import BaseComponent from "./DashboardBaseComponent";
export interface ValueDashboardComponent extends BaseComponent {}

View File

@ -1,3 +1,6 @@
import DashboardBaseComponent from "./DashboardComponents/DashboardBaseComponent";
export default interface DashboardViewConfig {
_type: "DashboardViewConfig";
components: Array<DashboardBaseComponent>;
}

View File

@ -47,12 +47,12 @@ const CategoryCheckbox: FunctionComponent<CategoryCheckboxProps> = (
Array<CategoryCheckboxValue>
>(sanitizeInitialValues(props.initialValue));
const [categories] = React.useState<Array<CheckboxCategory>>(
[...props.categories],
);
const [options] = React.useState<Array<CategoryCheckboxOption>>(
[...props.options],
);
const [categories] = React.useState<Array<CheckboxCategory>>([
...props.categories,
]);
const [options] = React.useState<Array<CategoryCheckboxOption>>([
...props.options,
]);
useEffect(() => {
// whenevent currentValue changes, make sure all the values are unique.

View File

@ -692,7 +692,7 @@ const LineChart: React.ForwardRefExoticComponent<
<ResponsiveContainer>
<RechartsLineChart
data={data}
syncId={props.syncId?.toString() || ''}
syncId={props.syncId?.toString() || ""}
onClick={
hasOnValueChange && (activeLegend || activeDot)
? () => {
@ -700,7 +700,7 @@ const LineChart: React.ForwardRefExoticComponent<
setActiveLegend(undefined);
onValueChange?.(null);
}
: ()=>{} // do nothing
: () => {} // do nothing
}
margin={{
bottom: (xAxisLabel ? 30 : undefined) as unknown as number,

View File

@ -0,0 +1,10 @@
import DashboardViewConfig from "../../Types/Dashboard/DashboardViewConfig";
export default class DashboardViewConfigUtil {
public static createDefaultDashboardViewConfig(): DashboardViewConfig {
return {
_type: "DashboardViewConfig",
components: [],
};
}
}