mirror of
https://github.com/OneUptime/oneuptime.git
synced 2026-04-06 00:32:12 +02:00
refactor: Update Select.ts and Project.ts for better code organization and readability
This commit is contained in:
@@ -21,6 +21,7 @@ import ProjectSSOService from "CommonServer/Services/ProjectSsoService";
|
||||
import TeamMemberService from "CommonServer/Services/TeamMemberService";
|
||||
import UserService from "CommonServer/Services/UserService";
|
||||
import QueryHelper from "CommonServer/Types/Database/QueryHelper";
|
||||
import Select from "CommonServer/Types/Database/Select";
|
||||
import CookieUtil from "CommonServer/Utils/Cookie";
|
||||
import Express, {
|
||||
ExpressRequest,
|
||||
@@ -30,6 +31,7 @@ import Express, {
|
||||
} from "CommonServer/Utils/Express";
|
||||
import logger from "CommonServer/Utils/Logger";
|
||||
import Response from "CommonServer/Utils/Response";
|
||||
import Project from "Model/Models/Project";
|
||||
import ProjectSSO from "Model/Models/ProjectSso";
|
||||
import TeamMember from "Model/Models/TeamMember";
|
||||
import User from "Model/Models/User";
|
||||
@@ -129,7 +131,7 @@ router.get(
|
||||
projectId: true,
|
||||
project: {
|
||||
name: true,
|
||||
},
|
||||
} as Select<Project>,
|
||||
},
|
||||
props: {
|
||||
isRoot: true,
|
||||
|
||||
@@ -11,10 +11,13 @@ import { EVERY_MINUTE } from "Common/Utils/CronTime";
|
||||
import IncidentService from "CommonServer/Services/IncidentService";
|
||||
import ProjectService from "CommonServer/Services/ProjectService";
|
||||
import UserNotificationSettingService from "CommonServer/Services/UserNotificationSettingService";
|
||||
import Select from "CommonServer/Types/Database/Select";
|
||||
import Markdown, { MarkdownContentType } from "CommonServer/Types/Markdown";
|
||||
import logger from "CommonServer/Utils/Logger";
|
||||
import Incident from "Model/Models/Incident";
|
||||
import IncidentState from "Model/Models/IncidentState";
|
||||
import Monitor from "Model/Models/Monitor";
|
||||
import Project from "Model/Models/Project";
|
||||
import User from "Model/Models/User";
|
||||
|
||||
RunCron(
|
||||
@@ -38,11 +41,11 @@ RunCron(
|
||||
projectId: true,
|
||||
project: {
|
||||
name: true,
|
||||
},
|
||||
} as Select<Project>,
|
||||
remediationNotes: true,
|
||||
currentIncidentState: {
|
||||
name: true,
|
||||
},
|
||||
} as Select<IncidentState>,
|
||||
incidentSeverity: {
|
||||
name: true,
|
||||
},
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
import { IsBillingEnabled } from "../EnvironmentConfig";
|
||||
import UserMiddleware from "../Middleware/UserAuthorization";
|
||||
import ProjectService, {
|
||||
Service as ProjectServiceType,
|
||||
} from "../Services/ProjectService";
|
||||
import ResellerService from "../Services/ResellerService";
|
||||
import TeamMemberService from "../Services/TeamMemberService";
|
||||
import Select from "../Types/Database/Select";
|
||||
import {
|
||||
ExpressRequest,
|
||||
ExpressResponse,
|
||||
@@ -38,6 +40,17 @@ export default class ProjectAPI extends BaseAPI<Project, ProjectServiceType> {
|
||||
);
|
||||
}
|
||||
|
||||
const projectSelect: Select<Project> = {
|
||||
_id: true,
|
||||
name: true,
|
||||
trialEndsAt: true,
|
||||
paymentProviderPlanId: true,
|
||||
resellerId: true,
|
||||
isFeatureFlagMonitorGroupsEnabled: true,
|
||||
paymentProviderMeteredSubscriptionStatus: true,
|
||||
paymentProviderSubscriptionStatus: true,
|
||||
};
|
||||
|
||||
const teamMembers: Array<TeamMember> = await TeamMemberService.findBy(
|
||||
{
|
||||
query: {
|
||||
@@ -45,16 +58,7 @@ export default class ProjectAPI extends BaseAPI<Project, ProjectServiceType> {
|
||||
hasAcceptedInvitation: true,
|
||||
},
|
||||
select: {
|
||||
project: {
|
||||
_id: true,
|
||||
name: true,
|
||||
trialEndsAt: true,
|
||||
paymentProviderPlanId: true,
|
||||
resellerId: true,
|
||||
isFeatureFlagMonitorGroupsEnabled: true,
|
||||
paymentProviderMeteredSubscriptionStatus: true,
|
||||
paymentProviderSubscriptionStatus: true,
|
||||
},
|
||||
project: projectSelect,
|
||||
},
|
||||
limit: LIMIT_PER_PROJECT,
|
||||
skip: 0,
|
||||
@@ -66,6 +70,47 @@ export default class ProjectAPI extends BaseAPI<Project, ProjectServiceType> {
|
||||
|
||||
const projects: Array<Project> = [];
|
||||
|
||||
// if billing enabled and is master admin then get all the projects with customer support enabled.
|
||||
|
||||
if (
|
||||
IsBillingEnabled &&
|
||||
(req as OneUptimeRequest).userAuthorization?.isMasterAdmin
|
||||
) {
|
||||
const customerSupportProjects: Array<Project> =
|
||||
await ProjectService.findBy({
|
||||
query: {
|
||||
letCustomerSupportAccessProject: true,
|
||||
},
|
||||
select: projectSelect,
|
||||
limit: LIMIT_PER_PROJECT,
|
||||
skip: 0,
|
||||
props: {
|
||||
isRoot: true,
|
||||
},
|
||||
});
|
||||
|
||||
for (const customerSupportProject of customerSupportProjects) {
|
||||
if (!customerSupportProject) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!customerSupportProject._id) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (
|
||||
projects.findIndex((project: Project) => {
|
||||
return (
|
||||
project._id?.toString() ===
|
||||
customerSupportProject!._id?.toString()
|
||||
);
|
||||
}) === -1
|
||||
) {
|
||||
projects.push(customerSupportProject);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (const teamMember of teamMembers) {
|
||||
if (!teamMember.project) {
|
||||
continue;
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
import { MigrationInterface, QueryRunner } from "typeorm";
|
||||
|
||||
export class MigrationName1719348009053 implements MigrationInterface {
|
||||
public name = "MigrationName1719348009053";
|
||||
|
||||
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(
|
||||
`ALTER TABLE "Project" ADD "letCustomerSupportAccessProject" boolean DEFAULT false`,
|
||||
);
|
||||
}
|
||||
|
||||
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(
|
||||
`ALTER TABLE "Project" DROP COLUMN "letCustomerSupportAccessProject"`,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -18,6 +18,7 @@ import { MigrationName1718879960254 } from "./1718879960254-MigrationName";
|
||||
import { MigrationName1719227548476 } from "./1719227548476-MigrationName";
|
||||
import { MigrationName1719228104620 } from "./1719228104620-MigrationName";
|
||||
import { MigrationName1719247426296 } from "./1719247426296-MigrationName";
|
||||
import { MigrationName1719348009053 } from "./1719348009053-MigrationName";
|
||||
|
||||
export default [
|
||||
InitialMigration,
|
||||
@@ -40,4 +41,5 @@ export default [
|
||||
MigrationName1719227548476,
|
||||
MigrationName1719228104620,
|
||||
MigrationName1719247426296,
|
||||
MigrationName1719348009053,
|
||||
];
|
||||
|
||||
@@ -39,6 +39,7 @@ import MonitorStatus from "Model/Models/MonitorStatus";
|
||||
import MonitorStatusTimeline from "Model/Models/MonitorStatusTimeline";
|
||||
import Probe from "Model/Models/Probe";
|
||||
import User from "Model/Models/User";
|
||||
import Select from "../Types/Database/Select";
|
||||
|
||||
export class Service extends DatabaseService<Model> {
|
||||
public constructor(postgresDatabase?: PostgresDatabase) {
|
||||
@@ -295,7 +296,7 @@ export class Service extends DatabaseService<Model> {
|
||||
email: true,
|
||||
name: true,
|
||||
timezone: true,
|
||||
},
|
||||
} as Select<User>,
|
||||
},
|
||||
props: {
|
||||
isRoot: true,
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import ResellerPlan from "Model/Models/ResellerPlan";
|
||||
import { IsBillingEnabled, getAllEnvVars } from "../EnvironmentConfig";
|
||||
import PostgresDatabase from "../Infrastructure/PostgresDatabase";
|
||||
import AllMeteredPlans from "../Types/Billing/MeteredPlan/AllMeteredPlans";
|
||||
@@ -49,6 +50,7 @@ import TeamMember from "Model/Models/TeamMember";
|
||||
import TeamPermission from "Model/Models/TeamPermission";
|
||||
import User from "Model/Models/User";
|
||||
import { In } from "typeorm";
|
||||
import Select from "../Types/Database/Select";
|
||||
|
||||
export interface CurrentPlan {
|
||||
plan: PlanSelect | null;
|
||||
@@ -134,7 +136,7 @@ export class Service extends DatabaseService<Model> {
|
||||
planType: true,
|
||||
monitorLimit: true,
|
||||
teamMemberLimit: true,
|
||||
},
|
||||
} as Select<ResellerPlan>,
|
||||
resellerId: true,
|
||||
resellerLicenseId: true,
|
||||
planType: true,
|
||||
|
||||
@@ -5,6 +5,7 @@ import CreateBy from "../Types/Database/CreateBy";
|
||||
import DeleteBy from "../Types/Database/DeleteBy";
|
||||
import { OnCreate, OnDelete, OnUpdate } from "../Types/Database/Hooks";
|
||||
import QueryHelper from "../Types/Database/QueryHelper";
|
||||
import Select from "../Types/Database/Select";
|
||||
import UpdateBy from "../Types/Database/UpdateBy";
|
||||
import Errors from "../Utils/Errors";
|
||||
import logger from "../Utils/Logger";
|
||||
@@ -206,7 +207,7 @@ export class TeamMemberService extends DatabaseService<TeamMember> {
|
||||
user: {
|
||||
email: true,
|
||||
isEmailVerified: true,
|
||||
},
|
||||
} as Select<User>,
|
||||
projectId: true,
|
||||
},
|
||||
limit: LIMIT_MAX,
|
||||
@@ -249,7 +250,7 @@ export class TeamMemberService extends DatabaseService<TeamMember> {
|
||||
team: {
|
||||
_id: true,
|
||||
shouldHaveAtLeastOneMember: true,
|
||||
},
|
||||
} as Select<TeamMember>,
|
||||
},
|
||||
limit: LIMIT_MAX,
|
||||
skip: 0,
|
||||
@@ -351,7 +352,7 @@ export class TeamMemberService extends DatabaseService<TeamMember> {
|
||||
email: true,
|
||||
name: true,
|
||||
timezone: true,
|
||||
},
|
||||
} as Select<User>,
|
||||
},
|
||||
|
||||
skip: 0,
|
||||
@@ -387,7 +388,7 @@ export class TeamMemberService extends DatabaseService<TeamMember> {
|
||||
_id: true,
|
||||
email: true,
|
||||
name: true,
|
||||
},
|
||||
} as Select<User>,
|
||||
},
|
||||
|
||||
skip: 0,
|
||||
|
||||
@@ -1,14 +1,13 @@
|
||||
import BaseModel from "Common/Models/BaseModel";
|
||||
import Dictionary from "Common/Types/Dictionary";
|
||||
|
||||
export type SelectPropertyOptions = boolean | Dictionary<boolean>;
|
||||
export type SelectPropertyOptions<T> = boolean | SelectOptions<T> | undefined;
|
||||
|
||||
/**
|
||||
* Select find options.
|
||||
*/
|
||||
|
||||
export declare type SelectOptions<Entity> = {
|
||||
[P in keyof Entity]?: SelectPropertyOptions;
|
||||
[P in keyof Entity]?: SelectPropertyOptions<any>;
|
||||
};
|
||||
|
||||
type Select<TBaseModel extends BaseModel> = SelectOptions<TBaseModel>;
|
||||
|
||||
@@ -2,9 +2,11 @@ import DashboardNavigation from "../../Utils/Navigation";
|
||||
import PageComponentProps from "../PageComponentProps";
|
||||
import FormFieldSchemaType from "CommonUI/src/Components/Forms/Types/FormFieldSchemaType";
|
||||
import CardModelDetail from "CommonUI/src/Components/ModelDetail/CardModelDetail";
|
||||
import FieldType from "CommonUI/src/Components/Types/FieldType";
|
||||
import Navigation from "CommonUI/src/Utils/Navigation";
|
||||
import Project from "Model/Models/Project";
|
||||
import React, { Fragment, FunctionComponent, ReactElement } from "react";
|
||||
import { BILLING_ENABLED } from "CommonUI/src/Config";
|
||||
|
||||
const Settings: FunctionComponent<PageComponentProps> = (): ReactElement => {
|
||||
return (
|
||||
@@ -54,6 +56,47 @@ const Settings: FunctionComponent<PageComponentProps> = (): ReactElement => {
|
||||
modelId: DashboardNavigation.getProjectId()!,
|
||||
}}
|
||||
/>
|
||||
|
||||
{/* Project Settings View */}
|
||||
{BILLING_ENABLED && (
|
||||
<CardModelDetail
|
||||
name="Enable Customer Support Access"
|
||||
cardProps={{
|
||||
title: "Enable Customer Support Access",
|
||||
description:
|
||||
"Enable Customer Support Access to this project. This will allow Customer Support to access this project for troubleshooting purposes.",
|
||||
}}
|
||||
isEditable={true}
|
||||
formFields={[
|
||||
{
|
||||
field: {
|
||||
letCustomerSupportAccessProject: true,
|
||||
},
|
||||
title: "Let Customer Support Access Project",
|
||||
fieldType: FormFieldSchemaType.Toggle,
|
||||
required: false,
|
||||
},
|
||||
]}
|
||||
onSaveSuccess={() => {
|
||||
Navigation.reload();
|
||||
}}
|
||||
modelDetailProps={{
|
||||
modelType: Project,
|
||||
id: "model-detail-project",
|
||||
fields: [
|
||||
{
|
||||
field: {
|
||||
letCustomerSupportAccessProject: true,
|
||||
},
|
||||
fieldType: FieldType.Boolean,
|
||||
title: "Let Customer Support Access Project",
|
||||
placeholder: "No",
|
||||
},
|
||||
],
|
||||
modelId: DashboardNavigation.getProjectId()!,
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</Fragment>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1140,4 +1140,29 @@ export default class Model extends TenantModel {
|
||||
type: ColumnType.Number,
|
||||
})
|
||||
public enterpriseAnnualContractValue?: number = undefined;
|
||||
|
||||
@ColumnAccessControl({
|
||||
create: [],
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadProject,
|
||||
Permission.UnAuthorizedSsoUser,
|
||||
],
|
||||
update: [Permission.ProjectOwner, Permission.ProjectAdmin],
|
||||
})
|
||||
@TableColumn({
|
||||
required: false,
|
||||
type: TableColumnType.Boolean,
|
||||
title: "Let Customer Support Access Project",
|
||||
description:
|
||||
"OneUptime customer support can access this project. This is used for debugging purposes.",
|
||||
})
|
||||
@Column({
|
||||
nullable: true,
|
||||
default: false,
|
||||
type: ColumnType.Boolean,
|
||||
})
|
||||
public letCustomerSupportAccessProject?: boolean = undefined;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user