chore: Disable editing and deleting of probes in ProbePage component

This commit disables the editing and deleting functionality for probes in the ProbePage component. The isEditable and isDeleteable props are set to false, preventing users from modifying or removing probes. This change ensures that probes cannot be accidentally modified or deleted, improving the data integrity of the application.
This commit is contained in:
Simon Larsen
2024-07-01 14:41:25 +01:00
parent 17bf63e83b
commit 82601a3e8f
7 changed files with 431 additions and 3 deletions

View File

@@ -0,0 +1,388 @@
import LabelsElement from "../../Components/Label/Labels";
import UserElement from "../../Components/User/User";
import DashboardNavigation from "../../Utils/Navigation";
import PageMap from "../../Utils/PageMap";
import ProjectUser from "../../Utils/ProjectUser";
import RouteMap from "../../Utils/RouteMap";
import PageComponentProps from "../PageComponentProps";
import Route from "Common/Types/API/Route";
import BadDataException from "Common/Types/Exception/BadDataException";
import ObjectID from "Common/Types/ObjectID";
import FormFieldSchemaType from "CommonUI/src/Components/Forms/Types/FormFieldSchemaType";
import ModelDelete from "CommonUI/src/Components/ModelDelete/ModelDelete";
import CardModelDetail from "CommonUI/src/Components/ModelDetail/CardModelDetail";
import ModelTable from "CommonUI/src/Components/ModelTable/ModelTable";
import FieldType from "CommonUI/src/Components/Types/FieldType";
import Navigation from "CommonUI/src/Utils/Navigation";
import Label from "Model/Models/Label";
import Probe from "Model/Models/Probe";
import ProbeOwnerTeam from "Model/Models/ProbeOwnerTeam";
import ProbeOwnerUser from "Model/Models/ProbeOwnerUser";
import User from "Model/Models/User";
import React, { Fragment, FunctionComponent, ReactElement } from "react";
import TeamElement from "../../Components/Team/Team";
import Team from "Model/Models/Team";
import ResetObjectID from "CommonUI/src/Components/ResetObjectID/ResetObjectID";
export enum PermissionType {
AllowPermissions = "AllowPermissions",
BlockPermissions = "BlockPermissions",
}
const TeamView: FunctionComponent<PageComponentProps> = (
_props: PageComponentProps,
): ReactElement => {
const modelId: ObjectID = Navigation.getLastParamAsObjectID();
return (
<Fragment>
{/* API Key View */}
<CardModelDetail<Probe>
name="Probe Details"
cardProps={{
title: "Probe Details",
description: "Here are more details for this probe.",
}}
isEditable={true}
formSteps={[
{
title: "Basic Info",
id: "basic-info",
},
{
title: "More",
id: "more",
},
]}
formFields={[
{
field: {
name: true,
},
stepId: "basic-info",
title: "Name",
fieldType: FormFieldSchemaType.Text,
required: true,
placeholder: "internal-probe",
validation: {
minLength: 2,
},
},
{
field: {
description: true,
},
title: "Description",
stepId: "basic-info",
fieldType: FormFieldSchemaType.LongText,
required: true,
placeholder: "This probe is to monitor all the internal services.",
},
{
field: {
iconFile: true,
},
title: "Probe Logo",
stepId: "basic-info",
fieldType: FormFieldSchemaType.ImageFile,
required: false,
placeholder: "Upload logo",
},
{
field: {
shouldAutoEnableProbeOnNewMonitors: true,
},
stepId: "more",
title: "Enable monitoring automatically on new monitors",
fieldType: FormFieldSchemaType.Toggle,
required: false,
},
{
field: {
labels: true,
},
title: "Labels ",
stepId: "more",
description:
"Team members with access to these labels will only be able to access this resource. This is optional and an advanced feature.",
fieldType: FormFieldSchemaType.MultiSelectDropdown,
dropdownModal: {
type: Label,
labelField: "name",
valueField: "_id",
},
required: false,
placeholder: "Labels",
},
]}
modelDetailProps={{
modelType: Probe,
id: "model-detail-team",
fields: [
{
field: {
_id: true,
},
title: "Probe ID",
},
{
field: {
name: true,
},
title: "Name",
},
{
field: {
description: true,
},
title: "Description",
},
{
field: {
key: true,
},
title: "Probe Key",
fieldType: FieldType.HiddenText,
},
{
field: {
labels: {
name: true,
color: true,
},
},
title: "Labels",
fieldType: FieldType.Element,
getElement: (item: Probe): ReactElement => {
return <LabelsElement labels={item["labels"] || []} />;
},
},
],
modelId: Navigation.getLastParamAsObjectID(),
}}
/>
<ModelTable<ProbeOwnerTeam>
modelType={ProbeOwnerTeam}
id="table-monitor-owner-team"
name="Probe > Owner Team"
singularName="Team"
isDeleteable={true}
createVerb={"Add"}
isCreateable={true}
isViewable={false}
showViewIdButton={true}
query={{
probeId: modelId,
projectId: DashboardNavigation.getProjectId()?.toString(),
}}
onBeforeCreate={(item: ProbeOwnerTeam): Promise<ProbeOwnerTeam> => {
item.probeId = modelId;
item.projectId = DashboardNavigation.getProjectId()!;
return Promise.resolve(item);
}}
cardProps={{
title: "Owners (Teams)",
description:
"Here is list of teams that own this probe. They will be alerted when this probe status changes.",
}}
noItemsMessage={"No teams associated with this probe so far."}
formFields={[
{
field: {
team: true,
},
title: "Team",
fieldType: FormFieldSchemaType.Dropdown,
required: true,
placeholder: "Select Team",
dropdownModal: {
type: Team,
labelField: "name",
valueField: "_id",
},
},
]}
showRefreshButton={true}
viewPageRoute={Navigation.getCurrentRoute()}
filters={[
{
field: {
team: true,
},
type: FieldType.Entity,
title: "Team",
filterEntityType: Team,
filterQuery: {
projectId: DashboardNavigation.getProjectId()?.toString(),
},
filterDropdownField: {
label: "name",
value: "_id",
},
},
{
field: {
createdAt: true,
},
title: "Owner since",
type: FieldType.Date,
},
]}
columns={[
{
field: {
team: {
name: true,
},
},
title: "Team",
type: FieldType.Entity,
getElement: (item: ProbeOwnerTeam): ReactElement => {
if (!item["team"]) {
throw new BadDataException("Team not found");
}
return <TeamElement team={item["team"] as Team} />;
},
},
{
field: {
createdAt: true,
},
title: "Owner since",
type: FieldType.DateTime,
},
]}
/>
<ModelTable<ProbeOwnerUser>
modelType={ProbeOwnerUser}
id="table-monitor-owner-team"
name="Probe > Owner Team"
isDeleteable={true}
singularName="User"
isCreateable={true}
isViewable={false}
showViewIdButton={true}
createVerb={"Add"}
query={{
probeId: modelId,
projectId: DashboardNavigation.getProjectId()?.toString(),
}}
onBeforeCreate={(item: ProbeOwnerUser): Promise<ProbeOwnerUser> => {
item.probeId = modelId;
item.projectId = DashboardNavigation.getProjectId()!;
return Promise.resolve(item);
}}
cardProps={{
title: "Owners (Users)",
description:
"Here is list of users that own this probe. They will be alerted when this probe status changes.",
}}
noItemsMessage={"No users associated with this probe so far."}
formFields={[
{
field: {
user: true,
},
title: "User",
fieldType: FormFieldSchemaType.Dropdown,
required: true,
placeholder: "Select User",
fetchDropdownOptions: async () => {
return await ProjectUser.fetchProjectUsersAsDropdownOptions(
DashboardNavigation.getProjectId()!,
);
},
},
]}
showRefreshButton={true}
viewPageRoute={Navigation.getCurrentRoute()}
filters={[
{
field: {
user: true,
},
title: "User",
type: FieldType.Entity,
filterEntityType: User,
fetchFilterDropdownOptions: async () => {
return await ProjectUser.fetchProjectUsersAsDropdownOptions(
DashboardNavigation.getProjectId()!,
);
},
filterDropdownField: {
label: "name",
value: "_id",
},
},
{
field: {
createdAt: true,
},
title: "Owner since",
type: FieldType.Date,
},
]}
columns={[
{
field: {
user: {
name: true,
email: true,
profilePictureId: true,
},
},
title: "User",
type: FieldType.Entity,
getElement: (item: ProbeOwnerUser): ReactElement => {
if (!item["user"]) {
throw new BadDataException("User not found");
}
return <UserElement user={item["user"] as User} />;
},
},
{
field: {
createdAt: true,
},
title: "Owner since",
type: FieldType.DateTime,
},
]}
/>
<ResetObjectID<Probe>
modelType={Probe}
onUpdateComplete={async () => {
Navigation.reload();
}}
fieldName={"key"}
title={"Reset Probe Key"}
description={
<p className="mt-2">
Resetting the secret key will generate a new key. Secret is
used to authenticate probe requests.
</p>
}
modelId={modelId}
/>
{/* Delete Probe */}
<ModelDelete
modelType={Probe}
modelId={Navigation.getLastParamAsObjectID()}
onDeleteSuccess={() => {
Navigation.navigate(RouteMap[PageMap.SETTINGS_PROBES] as Route);
}}
/>
</Fragment>
);
};
export default TeamView;

View File

@@ -116,8 +116,9 @@ const ProbePage: FunctionComponent<PageComponentProps> = (): ReactElement => {
}}
id="probes-table"
name="Settings > Probes"
isDeleteable={true}
isEditable={true}
isDeleteable={false}
isEditable={false}
isViewable={true}
isCreateable={true}
cardProps={{
title: "Custom Probes",

View File

@@ -49,6 +49,12 @@ const SettingsTeamView: LazyExoticComponent<FunctionComponent<ComponentProps>> =
lazy(() => {
return import("../Pages/Settings/TeamView");
});
const SettingsProbeView: LazyExoticComponent<
FunctionComponent<ComponentProps>
> = lazy(() => {
return import("../Pages/Settings/ProbeView");
});
const SettingsMonitors: LazyExoticComponent<FunctionComponent<ComponentProps>> =
lazy(() => {
return import("../Pages/Settings/MonitorStatus");
@@ -644,6 +650,18 @@ const SettingsRoutes: FunctionComponent<ComponentProps> = (
</Suspense>
}
/>
<PageRoute
path={RouteUtil.getLastPathForKey(PageMap.SETTINGS_PROBE_VIEW, 2)}
element={
<Suspense fallback={Loader}>
<SettingsProbeView
{...props}
pageRoute={RouteMap[PageMap.SETTINGS_PROBE_VIEW] as Route}
/>
</Suspense>
}
/>
</PageRoute>
</Routes>
);

View File

@@ -129,6 +129,12 @@ export function getSettingsBreadcrumbs(path: string): Array<Link> | undefined {
"Settings",
"Probes",
]),
...BuildBreadcrumbLinksByTitles(PageMap.SETTINGS_PROBE_VIEW, [
"Project",
"Settings",
"Probes",
"View Probe",
]),
...BuildBreadcrumbLinksByTitles(PageMap.SETTINGS_DOMAINS, [
"Project",
"Settings",

View File

@@ -170,6 +170,9 @@ enum PageMap {
SETTINGS_TEAMS = "SETTINGS_TEAMS",
SETTINGS_TEAM_VIEW = "SETTINGS_TEAM_VIEW",
// Probe
SETTINGS_PROBE_VIEW = "SETTINGS_PROBE_VIEW",
// Resource settings.
SETTINGS_INCIDENTS_STATE = "SETTINGS_INCIDENTS_STATE",
SETTINGS_INCIDENTS_SEVERITY = "SETTINGS_INCIDENTS_SEVERITY",

View File

@@ -145,6 +145,7 @@ export const SettingsRoutePath: Dictionary<string> = {
[PageMap.SETTINGS_BILLING_INVOICES]: "invoices",
[PageMap.SETTINGS_USAGE_HISTORY]: "usage-history",
[PageMap.SETTINGS_TEAM_VIEW]: `teams/${RouteParams.ModelID}`,
[PageMap.SETTINGS_PROBE_VIEW]: `probes/${RouteParams.ModelID}`,
[PageMap.SETTINGS_LABELS]: "labels",
[PageMap.SETTINGS_PROBES]: "probes",
};
@@ -1016,6 +1017,12 @@ const RouteMap: Dictionary<Route> = {
}`,
),
[PageMap.SETTINGS_PROBE_VIEW]: new Route(
`/dashboard/${RouteParams.ProjectID}/settings/${
SettingsRoutePath[PageMap.SETTINGS_PROBE_VIEW]
}`,
),
// labels.
[PageMap.SETTINGS_LABELS]: new Route(
`/dashboard/${RouteParams.ProjectID}/settings/${

View File

@@ -88,7 +88,12 @@ export default class Probe extends BaseModel {
Permission.CreateProjectProbe,
],
read: [Permission.ProjectOwner, Permission.ProjectAdmin],
update: [],
update: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.EditProjectProbe,
],
})
@TableColumn({
required: true,