From 8c35dcc66707ea3cebda74f7eec4491f0876c3b7 Mon Sep 17 00:00:00 2001
From: Maina Wycliffe <12270550+mainawycliffe@users.noreply.github.com>
Date: Fri, 13 Sep 2024 10:54:03 +0300
Subject: [PATCH] fix: Don't allow edit/delete for CRD created
notifications/connections
* fix: Don't allow edit/delete for CRD created notifications
Fixes #2260
* fix: don't allow editing crd sourced connections
* fix: fix missing crd source for checks modal
* fix: missing test connection for crd generated connectiosn
---
src/components/Connections/ConnectionForm.tsx | 97 ++++++++++++-------
.../Connections/ConnectionFormModal.tsx | 1 +
src/components/Forms/SpecEditorForm.tsx | 10 +-
.../Topology/TopologyResourceForm.tsx | 10 +-
.../Notifications/NotificationsForm.tsx | 48 +++++----
src/components/Settings/CRDSource.tsx | 50 +++++++---
src/components/Settings/CanEditResource.tsx | 46 +++++----
7 files changed, 174 insertions(+), 88 deletions(-)
diff --git a/src/components/Connections/ConnectionForm.tsx b/src/components/Connections/ConnectionForm.tsx
index ad0267f77..ec7eb0c7f 100644
--- a/src/components/Connections/ConnectionForm.tsx
+++ b/src/components/Connections/ConnectionForm.tsx
@@ -6,10 +6,11 @@ import { useMemo } from "react";
import { FaSpinner, FaTrash } from "react-icons/fa";
import { Button } from "../../ui/Buttons/Button";
import { AuthorizationAccessCheck } from "../Permissions/AuthorizationAccessCheck";
+import CanEditResource from "../Settings/CanEditResource";
import { Connection } from "./ConnectionFormModal";
+import { ConnectionType, connectionTypes } from "./connectionTypes";
import RenderConnectionFormFields from "./RenderConnectionFormFields";
import { TestConnection } from "./TestConnection";
-import { ConnectionType, connectionTypes } from "./connectionTypes";
interface ConnectionFormProps {
connectionType: ConnectionType;
@@ -138,44 +139,74 @@ export function ConnectionForm({
- {formValue?.id && (
-
+
+ {connectionType && !formValue?.id && (
}
- onClick={handleDelete}
- className="btn-danger"
+ text="Back"
+ onClick={handleBack}
+ className="btn-secondary"
/>
-
- )}
- {connectionType && !formValue?.id && (
-
- )}
-
- {formValue?.id &&
}
+ )}
+
+ {formValue?.id && (
+
+
+ }
+ onClick={handleDelete}
+ className="btn-danger"
+ />
+
+
+ )}
+ {/* We want to push test connection next to save button, if we have delete and update buttons */}
+ {(formValue?.source === "UI" || !formValue?.source) && (
+
+ )}
+ {formValue?.id && (
+ <>
+
+ {/* We want to show Test Connection Button at the start, we we won't show delete button */}
+ {formValue.source !== "UI" && formValue.source && (
+
+ )}
+ >
+ )}
-
- ) : undefined
- }
- text={Boolean(formValue?.id) ? "Update" : "Save"}
- className="btn-primary"
- />
+
+
+ ) : undefined
+ }
+ text={Boolean(formValue?.id) ? "Update" : "Save"}
+ className="btn-primary"
+ />
+
diff --git a/src/components/Connections/ConnectionFormModal.tsx b/src/components/Connections/ConnectionFormModal.tsx
index b4134ec37..8db2a6dd4 100644
--- a/src/components/Connections/ConnectionFormModal.tsx
+++ b/src/components/Connections/ConnectionFormModal.tsx
@@ -54,6 +54,7 @@ export type Connection = {
properties?: Record;
ref?: string;
namespace?: string;
+ source?: string;
};
type ConnectionFormProps = React.HTMLProps & {
diff --git a/src/components/Forms/SpecEditorForm.tsx b/src/components/Forms/SpecEditorForm.tsx
index f7f68d126..187770f95 100644
--- a/src/components/Forms/SpecEditorForm.tsx
+++ b/src/components/Forms/SpecEditorForm.tsx
@@ -219,7 +219,15 @@ export default function SpecEditorForm({
agentId={initialValues.agent_details?.id}
agentName={initialValues.agent_details?.name}
source={initialValues.source}
- onBack={onBack}
+ extraButtons={
+ onBack && (
+
+ )
+ }
>
{!!initialValues.id && (
+ )
+ }
>
{!!topology?.id && (
<>
diff --git a/src/components/Notifications/NotificationsForm.tsx b/src/components/Notifications/NotificationsForm.tsx
index 1c26cc334..48240e0c9 100644
--- a/src/components/Notifications/NotificationsForm.tsx
+++ b/src/components/Notifications/NotificationsForm.tsx
@@ -7,6 +7,7 @@ import FormikNotificationsTemplateField from "../Forms/Formik/FormikNotification
import FormikTextInput from "../Forms/Formik/FormikTextInput";
import NotificationsRecipientsTabs from "../Forms/Notifications/NotificationsRecipientsTabs";
import DeleteResource from "../SchemaResourcePage/Delete/DeleteResource";
+import CanEditResource from "../Settings/CanEditResource";
import { Notification } from "./notificationsTableColumns";
type NotificationsFormProps = {
@@ -74,26 +75,33 @@ export default function NotificationsForm({
/>
-
- {!!notification && (
-
- )}
- {(notification?.source === "UI" || !notification?.source) && (
-
- )}
-
+
+
+ {!!notification && (
+
+ )}
+
+ {(notification?.source === "UI" || !notification?.source) && (
+
+ )}
+
+
)}
diff --git a/src/components/Settings/CRDSource.tsx b/src/components/Settings/CRDSource.tsx
index 0f6a792c8..64cb7f21c 100644
--- a/src/components/Settings/CRDSource.tsx
+++ b/src/components/Settings/CRDSource.tsx
@@ -2,11 +2,12 @@ import { Link } from "react-router-dom";
import { Icon } from "../../ui/Icons/Icon";
type CRDSourceProps = {
- id: string;
- namespace: string;
- name: string;
+ id?: string;
+ namespace?: string;
+ name?: string;
source?: string;
showMinimal?: boolean;
+ hideSourceLink?: boolean;
};
export default function CRDSource({
@@ -14,9 +15,17 @@ export default function CRDSource({
name,
namespace,
source,
- showMinimal = false
+ showMinimal = false,
+ hideSourceLink = false
}: CRDSourceProps) {
- if (source?.toLowerCase() !== "KubernetesCRD".toLowerCase()) {
+ if (
+ source?.toLowerCase() !== "KubernetesCRD".toLowerCase() &&
+ !source?.toLowerCase().startsWith("kubernetes")
+ ) {
+ return null;
+ }
+
+ if (hideSourceLink) {
return null;
}
@@ -33,16 +42,27 @@ export default function CRDSource({
) : (
<>
- CRD linked to{" "}
-
-
- {namespace ? <>{namespace}/> : ""}
- {name}
-
-
+ {name ? (
+ <>
+ CRD linked to{" "}
+
+
+ {namespace ? <>{namespace}/> : ""}
+ {name}
+
+
+ >
+ ) : (
+
+ Linked to CRD
+
+ )}
>
)}
diff --git a/src/components/Settings/CanEditResource.tsx b/src/components/Settings/CanEditResource.tsx
index 5d84423f6..b4155bb7b 100644
--- a/src/components/Settings/CanEditResource.tsx
+++ b/src/components/Settings/CanEditResource.tsx
@@ -1,4 +1,3 @@
-import { Button } from "@flanksource-ui/ui/Buttons/Button";
import { Link } from "react-router-dom";
import { SchemaResourceType } from "../SchemaResourcePage/resourceTypes";
import CRDSource from "./CRDSource";
@@ -11,9 +10,11 @@ type CanEditResourceProps = {
agentId?: string;
agentName?: string;
children: React.ReactNode;
- id: string;
- namespace: string;
- name: string;
+ id?: string;
+ namespace?: string;
+ name?: string;
+ // do not render alternate content, if crd
+ hideSourceLink?: boolean;
};
export function CanEditResourceInner({
@@ -22,6 +23,7 @@ export function CanEditResourceInner({
agentId,
agentName,
children,
+ hideSourceLink = false,
...props
}: CanEditResourceProps) {
// if Agent isn't local, we can't edit it
@@ -29,6 +31,10 @@ export function CanEditResourceInner({
agentId !== "00000000-0000-0000-0000-000000000000" &&
agentId !== undefined
) {
+ if (hideSourceLink) {
+ return null;
+ }
+
return (
Linked to {" "}
@@ -43,14 +49,23 @@ export function CanEditResourceInner({
}
if (source?.startsWith("component")) {
+ if (hideSourceLink) {
+ return null;
+ }
return
;
}
if (source?.startsWith("kubernetes")) {
+ if (hideSourceLink) {
+ return null;
+ }
return
;
}
if (source === "ConfigFile") {
+ if (hideSourceLink) {
+ return null;
+ }
return (
@@ -61,7 +76,9 @@ export function CanEditResourceInner({
}
if (source && source !== "UI") {
- return
;
+ return (
+
+ );
}
// eslint-disable-next-line react/jsx-no-useless-fragment
@@ -69,23 +86,16 @@ export function CanEditResourceInner({
}
export default function CanEditResource({
- onBack,
+ extraButtons,
+ className = "flex flex-1 flex-row justify-end gap-2",
...props
}: CanEditResourceProps & {
- onBack?: () => void;
+ className?: string;
+ extraButtons?: React.ReactNode;
}) {
return (
-
-
- {onBack && (
-
- )}
-
+
+ {extraButtons &&
{extraButtons}
}
);