From addf1b3d64337501e01f872ff6740fbf657ebff2 Mon Sep 17 00:00:00 2001
From: Mohan Dholu <54059494+mohandholu43@users.noreply.github.com>
Date: Tue, 7 Jan 2025 17:38:41 +0530
Subject: [PATCH] Feature/custom dns tab (#483)
* custom dns for public for icon
* custom dns
* custom dns add tab other ui change for in
* custom dns add status chips
* bug fix in border color bg color
* border shadow add
* all elint and other fix
* remove unuse
* commit fix done
* icon fix
* circle icon fix
* remove rect
* fix in custom dns multiple show
---
.../[resourceId]/[resourceInstanceId].js | 42 +-
.../CustomStatusChips/CustomStatusChips.tsx | 57 +++
.../AlertTrianglePITR/AlertTrianglePITR.jsx | 26 ++
.../CircleCheck/CircleCheckWithBorderIcon.jsx | 31 ++
src/components/Icons/DNSIcon/PrivateIcon.tsx | 131 ++++++
src/components/Icons/DNSIcon/PublicIcon.tsx | 180 ++++++++
.../Connectivity/ConnectivityCustomDNS.tsx | 40 +-
.../Connectivity/ConnectivityEndpoint.tsx | 21 +
.../Connectivity/CustomDNS.tsx | 389 ++++++++++++++++++
.../Connectivity/CustomDNSDetails.tsx | 175 ++++++++
.../Connectivity/CustomDNSDetailsModal.tsx | 98 -----
.../Connectivity/CustomDNSEndPoint.tsx | 91 ++++
.../Connectivity/ResourceCustomDNS.tsx | 130 ++++++
13 files changed, 1280 insertions(+), 131 deletions(-)
create mode 100644 src/components/CustomStatusChips/CustomStatusChips.tsx
create mode 100644 src/components/Icons/AlertTrianglePITR/AlertTrianglePITR.jsx
create mode 100644 src/components/Icons/CircleCheck/CircleCheckWithBorderIcon.jsx
create mode 100644 src/components/Icons/DNSIcon/PrivateIcon.tsx
create mode 100644 src/components/Icons/DNSIcon/PublicIcon.tsx
create mode 100644 src/components/ResourceInstance/Connectivity/CustomDNS.tsx
create mode 100644 src/components/ResourceInstance/Connectivity/CustomDNSDetails.tsx
delete mode 100644 src/components/ResourceInstance/Connectivity/CustomDNSDetailsModal.tsx
create mode 100644 src/components/ResourceInstance/Connectivity/CustomDNSEndPoint.tsx
create mode 100644 src/components/ResourceInstance/Connectivity/ResourceCustomDNS.tsx
diff --git a/pages/access/[serviceId]/[environmentId]/[resourceId]/[resourceInstanceId].js b/pages/access/[serviceId]/[environmentId]/[resourceId]/[resourceInstanceId].js
index 46a2fc9d..25d99504 100644
--- a/pages/access/[serviceId]/[environmentId]/[resourceId]/[resourceInstanceId].js
+++ b/pages/access/[serviceId]/[environmentId]/[resourceId]/[resourceInstanceId].js
@@ -43,6 +43,7 @@ import {
selectInstanceDetailsSummaryVisibility,
toggleInstanceDetailsSummaryVisibility,
} from "src/slices/genericSlice";
+import ResourceCustomDNS from "src/components/ResourceInstance/Connectivity/ResourceCustomDNS";
export const getServerSideProps = async () => {
return {
@@ -148,6 +149,25 @@ function ResourceInstance() {
[resourceType]
);
+ const checkCustomDNSEndpoint = (resources) => {
+ if (
+ resources.primary?.customDNSEndpoint &&
+ resources.primary?.customDNSEndpoint.enabled === true
+ ) {
+ return true;
+ }
+
+ if (Array.isArray(resources.others)) {
+ return resources.others.some(
+ (resource) =>
+ resource?.customDNSEndpoint &&
+ resource?.customDNSEndpoint.enabled === true
+ );
+ }
+
+ return false;
+ };
+
const tabs = getTabs(
resourceInstanceData?.isMetricsEnabled,
resourceInstanceData?.isLogsEnabled,
@@ -155,7 +175,12 @@ function ResourceInstance() {
isResourceBYOA,
isCliManagedResource,
resourceType,
- resourceInstanceData?.backupStatus?.backupPeriodInHours
+ resourceInstanceData?.backupStatus?.backupPeriodInHours,
+ checkCustomDNSEndpoint(
+ resourceInstanceData
+ ? resourceInstanceData?.connectivity?.globalEndpoints
+ : {}
+ )
);
let pageTitle = "Resource";
@@ -542,6 +567,15 @@ function ResourceInstance() {
}
/>
)}
+ {currentTab === tabs.customDNS && (
+
+ )}
+
;
+ textStyles?: SxProps;
+ iconStyles?: SxProps & { alignItems?: string; display?: string };
+};
+
+export default function CustomStatusChips(props: CustomStatusChipsProps) {
+ const {
+ icon,
+ children,
+ containerStyles = {},
+ textStyles = {},
+ iconStyles = {},
+ } = props;
+ const theme = useTheme();
+
+ return (
+
+ {icon && (
+
+ {icon}
+
+ )}
+
+ {children}
+
+
+ );
+}
diff --git a/src/components/Icons/AlertTrianglePITR/AlertTrianglePITR.jsx b/src/components/Icons/AlertTrianglePITR/AlertTrianglePITR.jsx
new file mode 100644
index 00000000..b0ac0224
--- /dev/null
+++ b/src/components/Icons/AlertTrianglePITR/AlertTrianglePITR.jsx
@@ -0,0 +1,26 @@
+import React from "react";
+
+function AlertTrianglePITR(props) {
+ const { height = 21, width = 24, color = "#B54708", ...restProps } = props;
+
+ return (
+
+ );
+}
+
+export default AlertTrianglePITR;
diff --git a/src/components/Icons/CircleCheck/CircleCheckWithBorderIcon.jsx b/src/components/Icons/CircleCheck/CircleCheckWithBorderIcon.jsx
new file mode 100644
index 00000000..0c79f96a
--- /dev/null
+++ b/src/components/Icons/CircleCheck/CircleCheckWithBorderIcon.jsx
@@ -0,0 +1,31 @@
+function CircleCheckWithBorderIcon(props) {
+ const { height = 16, width = 16, ...restProps } = props;
+
+ return (
+
+ );
+}
+
+export default CircleCheckWithBorderIcon;
diff --git a/src/components/Icons/DNSIcon/PrivateIcon.tsx b/src/components/Icons/DNSIcon/PrivateIcon.tsx
new file mode 100644
index 00000000..98ab3dd1
--- /dev/null
+++ b/src/components/Icons/DNSIcon/PrivateIcon.tsx
@@ -0,0 +1,131 @@
+const PrivateIcon = (props: any) => (
+
+);
+export default PrivateIcon;
diff --git a/src/components/Icons/DNSIcon/PublicIcon.tsx b/src/components/Icons/DNSIcon/PublicIcon.tsx
new file mode 100644
index 00000000..1a7036d4
--- /dev/null
+++ b/src/components/Icons/DNSIcon/PublicIcon.tsx
@@ -0,0 +1,180 @@
+const PublicIcon = (props: any) => (
+
+);
+export default PublicIcon;
diff --git a/src/components/ResourceInstance/Connectivity/ConnectivityCustomDNS.tsx b/src/components/ResourceInstance/Connectivity/ConnectivityCustomDNS.tsx
index a5030338..d4125d38 100644
--- a/src/components/ResourceInstance/Connectivity/ConnectivityCustomDNS.tsx
+++ b/src/components/ResourceInstance/Connectivity/ConnectivityCustomDNS.tsx
@@ -22,7 +22,6 @@ import EditIcon from "src/components/Icons/Edit/Edit";
import DeleteIcon from "src/components/Icons/Delete/Delete";
import TextConfirmationDialog from "src/components/TextConfirmationDialog/TextConfirmationDialog";
import LoadingSpinnerSmall from "src/components/CircularProgress/CircularProgress";
-import CustomDNSDetailsModal from "./CustomDNSDetailsModal";
import StatusChip from "src/components/StatusChip/StatusChip";
import { getCustomDNSStatusStylesAndLabel } from "src/constants/statusChipStyles/customDNS";
import { useMutation } from "@tanstack/react-query";
@@ -47,6 +46,7 @@ type ResourceConnectivityEndpointProps = {
status?: string;
cnameTarget?: string;
aRecordTarget?: string;
+ name?: string;
};
queryData: {
serviceProviderId: string;
@@ -75,7 +75,6 @@ const ResourceConnectivityCustomDNS: FC = (
const [showDeleteConfirmationDialog, setShowDeleteConfirmationDialog] =
useState(false);
- const [showConfigurationDialog, setShowConfigurationDialog] = useState(false);
const [deleteMessage, setDeleteMessage] = useState("");
const [isTextfieldDisabled, setIsTextFieldDisabled] = useState(false);
const [shouldShowConfigDialog, setShouldShowConfigDialog] = useState(false);
@@ -109,6 +108,8 @@ const ResourceConnectivityCustomDNS: FC = (
},
onSuccess: () => {
refetchInstance();
+ setShouldShowConfigDialog(true);
+ setIsTextFieldDisabled(true);
},
});
@@ -128,6 +129,8 @@ const ResourceConnectivityCustomDNS: FC = (
},
onSuccess: () => {
pollInstanceQueryToVerifyDNSRemoval();
+ setShowDeleteConfirmationDialog(false);
+ removeCustomDNSFormik.resetForm();
},
});
@@ -209,24 +212,13 @@ const ResourceConnectivityCustomDNS: FC = (
},
onSubmit: async (values) => {
if (values.confirmationText === "deleteme") {
- try {
- await removeCustomDNSMutation?.mutateAsync();
- setShowDeleteConfirmationDialog(false);
- removeCustomDNSFormik.resetForm();
- } catch {}
+ removeCustomDNSMutation?.mutate();
}
},
});
async function handleAddDNS(payload: AddCustomDNSToResourceInstancePayload) {
- try {
- await addCustomDNSMutation?.mutateAsync(payload);
- setShouldShowConfigDialog(true);
- setIsTextFieldDisabled(true);
-
- } catch (err) {
- console.error(err);
- }
+ addCustomDNSMutation?.mutate(payload);
}
useEffect(() => {
@@ -240,7 +232,6 @@ const ResourceConnectivityCustomDNS: FC = (
useEffect(() => {
if (isCustomDNSSetup && shouldShowConfigDialog) {
- setShowConfigurationDialog(true);
setShouldShowConfigDialog(false);
}
}, [isCustomDNSSetup, shouldShowConfigDialog, setShouldShowConfigDialog]);
@@ -304,7 +295,7 @@ const ResourceConnectivityCustomDNS: FC = (
}}
/>
-
+
= (
/>
{isTextfieldDisabled ? (
<>
- {
- setShowConfigurationDialog(true);
- }}
- >
+ {}}>
= (
isDeleteEnable={true}
/>
)}
- {
- setShowConfigurationDialog(false);
- }}
- />
>
);
};
diff --git a/src/components/ResourceInstance/Connectivity/ConnectivityEndpoint.tsx b/src/components/ResourceInstance/Connectivity/ConnectivityEndpoint.tsx
index 9a829c27..f20cea49 100644
--- a/src/components/ResourceInstance/Connectivity/ConnectivityEndpoint.tsx
+++ b/src/components/ResourceInstance/Connectivity/ConnectivityEndpoint.tsx
@@ -12,6 +12,7 @@ import CopyButton from "src/components/Button/CopyButton";
import Button from "src/components/Button/Button";
import AddCircleOutlineIcon from "@mui/icons-material/AddCircleOutline";
import RemoveCircleOutlineIcon from "@mui/icons-material/RemoveCircleOutline";
+import CustomDNSEndPoint from "./CustomDNSEndPoint";
const TableCell = styled(MuiTableCell)({
borderBottom: "none",
});
@@ -25,6 +26,14 @@ type ResourceConnectivityEndpointProps = {
containerStyles: SxProps;
context: "access" | "fleet";
ResourceConnectivityCustomDNS?: any;
+ customDNSData?: {
+ enabled: boolean;
+ dnsName?: string;
+ status?: string;
+ cnameTarget?: string;
+ aRecordTarget?: string;
+ name?: string;
+ };
};
// Define the expected type for each port item
@@ -44,6 +53,7 @@ const ResourceConnectivityEndpoint: FC = (
viewType,
isPrimaryResource = false,
ResourceConnectivityCustomDNS,
+ customDNSData,
} = props;
const [isEndpointsExpanded, setIsEndpointsExpanded] = useState(false);
const toggleExpanded = () => setIsEndpointsExpanded((prev) => !prev);
@@ -212,6 +222,17 @@ const ResourceConnectivityEndpoint: FC = (
+ {customDNSData?.dnsName && customDNSData && (
+
+
+
+ )}
>
);
diff --git a/src/components/ResourceInstance/Connectivity/CustomDNS.tsx b/src/components/ResourceInstance/Connectivity/CustomDNS.tsx
new file mode 100644
index 00000000..b90257e1
--- /dev/null
+++ b/src/components/ResourceInstance/Connectivity/CustomDNS.tsx
@@ -0,0 +1,389 @@
+import { SxProps, Theme, Stack, Box } from "@mui/material";
+import { Text } from "src/components/Typography/Typography";
+import { FC, useEffect, useRef, useState } from "react";
+import FieldContainer from "src/components/FormElementsv2/FieldContainer/FieldContainer";
+import TextField from "src/components/FormElementsv2/TextField/TextField";
+import Button from "src/components/Button/Button";
+import { useFormik } from "formik";
+import {
+ addCustomDNSToResourceInstance,
+ removeCustomDNSFromResourceInstance,
+ getResourceInstanceDetails,
+} from "src/api/resourceInstance";
+
+import * as Yup from "yup";
+import FieldError from "src/components/FormElementsv2/FieldError/FieldError";
+import IconButtonSquare from "src/components/IconButtonSquare/IconButtonSquare";
+import EditIcon from "src/components/Icons/Edit/Edit";
+import DeleteIcon from "src/components/Icons/Delete/Delete";
+import TextConfirmationDialog from "src/components/TextConfirmationDialog/TextConfirmationDialog";
+import LoadingSpinnerSmall from "src/components/CircularProgress/CircularProgress";
+import { useMutation } from "@tanstack/react-query";
+import Card from "src/components/Card/Card";
+import PublicIcon from "src/components/Icons/DNSIcon/PublicIcon";
+import { AddCustomDNSToResourceInstancePayload } from "./ConnectivityCustomDNS";
+import CustomDNSDetails from "./CustomDNSDetails";
+import AlertTrianglePITR from "src/components/Icons/AlertTrianglePITR/AlertTrianglePITR";
+import CircleCheckWithBorderIcon from "src/components/Icons/CircleCheck/CircleCheckWithBorderIcon";
+import CustomStatusChips from "src/components/CustomStatusChips/CustomStatusChips";
+import PlayIcon from "src/components/Icons/Play/Play";
+
+type EndpointProps = {
+ resourceName: string;
+ containerStyles?: SxProps;
+ resourceKey: string;
+ resourceId: string;
+ resourceHasCompute: boolean;
+ customDNSData?: {
+ enabled: boolean;
+ dnsName?: string;
+ status?: string;
+ cnameTarget?: string;
+ aRecordTarget?: string;
+ };
+ accessQueryParams?: {
+ serviceProviderId: string;
+ serviceKey: string;
+ serviceAPIVersion: string;
+ serviceEnvironmentKey: string;
+ serviceModelKey: string;
+ productTierKey: string;
+ subscriptionId: string;
+ resourceInstanceId: string;
+ };
+
+ refetchInstance: () => void;
+};
+
+const CustomDNS: FC = (props) => {
+ const {
+ resourceName,
+ customDNSData = { enabled: false },
+ accessQueryParams,
+ resourceKey,
+ resourceId,
+ refetchInstance,
+ resourceHasCompute,
+ } = props;
+
+ const [showDeleteConfirmationDialog, setShowDeleteConfirmationDialog] =
+ useState(false);
+ const [deleteMessage, setDeleteMessage] = useState("");
+ const [isTextfieldDisabled, setIsTextFieldDisabled] = useState(false);
+ const textfieldRef = useRef();
+ const timeoutID = useRef(null);
+ const pollCount = useRef(0);
+
+ const { dnsName } = customDNSData;
+ let isCustomDNSSetup = false;
+ if (dnsName) {
+ isCustomDNSSetup = true;
+ }
+
+ const addCustomDNSMutation = useMutation({
+ mutationFn: (payload: AddCustomDNSToResourceInstancePayload) => {
+ return addCustomDNSToResourceInstance(
+ accessQueryParams.serviceProviderId,
+ accessQueryParams.serviceKey,
+ accessQueryParams.serviceAPIVersion,
+ accessQueryParams.serviceEnvironmentKey,
+ accessQueryParams.serviceModelKey,
+ accessQueryParams.productTierKey,
+ resourceKey,
+ accessQueryParams.resourceInstanceId,
+ accessQueryParams.subscriptionId,
+ payload
+ );
+ },
+ onSuccess: () => {
+ refetchInstance();
+ setIsTextFieldDisabled(true);
+ },
+ });
+
+ const removeCustomDNSMutation = useMutation({
+ mutationFn: () => {
+ return removeCustomDNSFromResourceInstance(
+ accessQueryParams.serviceProviderId,
+ accessQueryParams.serviceKey,
+ accessQueryParams.serviceAPIVersion,
+ accessQueryParams.serviceEnvironmentKey,
+ accessQueryParams.serviceModelKey,
+ accessQueryParams.productTierKey,
+ resourceKey,
+ accessQueryParams.resourceInstanceId,
+ accessQueryParams.subscriptionId
+ );
+ },
+ onSuccess: () => {
+ pollInstanceQueryToVerifyDNSRemoval();
+ setShowDeleteConfirmationDialog(false);
+ removeCustomDNSFormik.resetForm();
+ },
+ });
+
+ function clearExistingTimeout() {
+ if (timeoutID.current) {
+ clearTimeout(timeoutID.current);
+ }
+ }
+
+ function pollInstanceQueryToVerifyDNSRemoval() {
+ clearExistingTimeout();
+ pollCount.current = 0;
+ verifyDNSRemoval();
+
+ function verifyDNSRemoval() {
+ if (pollCount.current < 5) {
+ pollCount.current++;
+ const id = setTimeout(() => {
+ getResourceInstanceDetails(
+ accessQueryParams.serviceProviderId,
+ accessQueryParams.serviceKey,
+ accessQueryParams.serviceAPIVersion,
+ accessQueryParams.serviceEnvironmentKey,
+ accessQueryParams.serviceModelKey,
+ accessQueryParams.productTierKey,
+ resourceKey,
+ accessQueryParams.resourceInstanceId,
+ accessQueryParams.subscriptionId
+ )
+ .then((response) => {
+ const topologyDetails =
+ response.data?.detailedNetworkTopology?.[resourceId];
+ //check for dnsName field in the response, absence means dns removal complete
+ if (!Boolean(topologyDetails?.customDNSEndpoint.dnsName)) {
+ refetchInstance();
+ } else {
+ verifyDNSRemoval();
+ }
+ })
+ .catch(() => {
+ verifyDNSRemoval();
+ });
+ }, 1500);
+ timeoutID.current = id;
+ } else {
+ }
+ }
+ }
+
+ useEffect(() => {
+ return () => {
+ clearExistingTimeout();
+ };
+ }, []);
+
+ const customDNSFormik = useFormik({
+ initialValues: {
+ customDNSEndpoint: dnsName ?? "",
+ },
+ onSubmit: (values) => {
+ handleAddDNS({
+ customDNS: values.customDNSEndpoint,
+ });
+ },
+ validationSchema: Yup.object().shape({
+ customDNSEndpoint: Yup.string()
+ //.url("Please enter a valid URL")
+ .required("Target Alias is required"),
+ }),
+ enableReinitialize: true,
+ });
+
+ const removeCustomDNSFormik = useFormik({
+ initialValues: {
+ confirmationText: "",
+ },
+ onSubmit: async (values) => {
+ if (values.confirmationText === "deleteme") {
+ removeCustomDNSMutation?.mutate();
+ }
+ },
+ });
+
+ async function handleAddDNS(payload: AddCustomDNSToResourceInstancePayload) {
+ addCustomDNSMutation?.mutate(payload);
+ }
+
+ useEffect(() => {
+ if (customDNSData.enabled === true && customDNSData.dnsName) {
+ setIsTextFieldDisabled(true);
+ } else if (customDNSData.enabled === true && !customDNSData.dnsName) {
+ setIsTextFieldDisabled(false);
+ }
+ }, [customDNSData]);
+
+ return (
+ <>
+ {resourceHasCompute && customDNSData?.enabled && (
+
+
+
+
+
+
+ {resourceName}
+
+
+
+ <>
+
+ {(customDNSData?.aRecordTarget || customDNSData?.cnameTarget) && (
+
+ )}
+
+
+
+ {isTextfieldDisabled ? (
+ <>
+ {
+ setIsTextFieldDisabled(false);
+ //textfieldRef.current.focus();
+ }}
+ >
+
+
+ {
+ setDeleteMessage(
+ "Are you sure you want to delete this endpoint alias?"
+ );
+ setShowDeleteConfirmationDialog(true);
+ }}
+ >
+
+
+ >
+ ) : (
+ <>
+
+ >
+ )}
+
+
+ {customDNSFormik.touched.customDNSEndpoint &&
+ customDNSFormik.errors.customDNSEndpoint}
+
+
+ {isCustomDNSSetup && (
+
+ ) : (
+
+ )
+ }
+ containerStyles={
+ customDNSData?.status === "READY"
+ ? {
+ backgroundColor: "rgba(237, 252, 242, 1)",
+ border: "1px solid rgba(170, 240, 196, 1)",
+ }
+ : {
+ backgroundColor: "rgba(254, 251, 232, 1)",
+ border: "1px solid rgba(254, 247, 195, 1)",
+ }
+ }
+ >
+
+ {customDNSData?.status === "READY"
+ ? "Domain Verified"
+ : "Pending Verification"}
+
+
+ )}
+
+ >
+ {isCustomDNSSetup && (
+ {
+ setShowDeleteConfirmationDialog(false);
+ removeCustomDNSFormik.resetForm();
+ }}
+ formData={removeCustomDNSFormik}
+ title={`Delete Endpoint Alias`}
+ subtitle={deleteMessage}
+ message={
+ "To confirm deletion, please enter deleteme, in the field below:"
+ }
+ isLoading={removeCustomDNSMutation?.isLoading}
+ isDeleteEnable={true}
+ />
+ )}
+
+ )}
+ >
+ );
+};
+
+export default CustomDNS;
diff --git a/src/components/ResourceInstance/Connectivity/CustomDNSDetails.tsx b/src/components/ResourceInstance/Connectivity/CustomDNSDetails.tsx
new file mode 100644
index 00000000..db694d30
--- /dev/null
+++ b/src/components/ResourceInstance/Connectivity/CustomDNSDetails.tsx
@@ -0,0 +1,175 @@
+import React from "react";
+import { Box, styled } from "@mui/material";
+import CopyButton from "src/components/Button/CopyButton";
+import { Text } from "src/components/Typography/Typography";
+import ArrowForwardIcon from "@mui/icons-material/ArrowForward";
+
+type CustomDNSDetailsProps = {
+ aRecordTarget?: string;
+ cnameTarget?: string;
+ domainName: string;
+};
+
+const RecordContainer = styled(Box)({
+ display: "flex",
+ flexDirection: "column",
+ width: "100%",
+ padding: "24px",
+ border: "1px solid #EAECF0",
+ marginBottom: "16px",
+ boxShadow: "0px 1px 2px 0px rgba(16, 24, 40, 0.05)",
+});
+
+const RecordRowContainer = styled(Box)({
+ display: "flex",
+ flexDirection: "row",
+ alignItems: "center",
+ width: "100%",
+ marginBottom: "16px",
+});
+const RecordColumn = styled(Box)<{ hasBorder?: boolean }>(({ hasBorder }) => ({
+ display: "flex",
+ alignItems: "center",
+ border: hasBorder ? "1px solid #EAECF0" : "none",
+ borderRadius: "8px",
+ flex: 1,
+ minHeight: "40px",
+ backgroundColor: "#fff",
+ overflow: "hidden",
+ boxShadow: hasBorder ? "0px 1px 2px 0px rgba(16, 24, 40, 0.05)" : "none",
+}));
+
+const CustomDNSDetails: React.FC = ({
+ aRecordTarget,
+ cnameTarget,
+ domainName,
+}) => {
+ const records = [];
+ if (aRecordTarget) {
+ records.push({
+ recordLabel: "A",
+ domainValue: domainName,
+ recordValue: aRecordTarget,
+ });
+ }
+
+ if (cnameTarget) {
+ records.push({
+ recordLabel: "CNAME",
+ domainValue: domainName,
+ recordValue: cnameTarget,
+ });
+ }
+
+ return (
+
+ {records.map((record, index) => (
+
+
+
+
+ Record Name
+
+
+
+
+
+
+ Record Value
+
+
+
+
+
+
+
+
+
+ {record.recordLabel}
+
+
+
+
+
+ {record.domainValue}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {record.recordValue}
+
+
+
+
+
+
+
+
+
+ ))}
+
+ );
+};
+
+export default CustomDNSDetails;
diff --git a/src/components/ResourceInstance/Connectivity/CustomDNSDetailsModal.tsx b/src/components/ResourceInstance/Connectivity/CustomDNSDetailsModal.tsx
deleted file mode 100644
index 0d14261c..00000000
--- a/src/components/ResourceInstance/Connectivity/CustomDNSDetailsModal.tsx
+++ /dev/null
@@ -1,98 +0,0 @@
-import {
- Box,
- Dialog,
- DialogActions,
- DialogContent,
- DialogTitle,
- Stack,
-} from "@mui/material";
-import { FC } from "react";
-import Accordian from "src/components/Accordian/Accordian";
-import AccordionKeyValueCopyTable from "src/components/AccordionKeyValueCopyTable/AccordionKeyValueCopyTable";
-import Button from "src/components/Button/Button";
-import Divider from "src/components/Divider/Divider";
-import InfoIcon from "src/components/Icons/Info/Info";
-import { Text } from "src/components/Typography/Typography";
-
-type CustomDNSDetailsModalProps = {
- open: boolean;
- handleClose: () => void;
- aRecordTarget?: string;
- cnameTarget?: string;
- domainName: string;
-};
-
-const CustomDNSDetailsModal: FC = (props) => {
- const { open, handleClose, aRecordTarget, cnameTarget, domainName } = props;
-
- const rows = [
- {
- label: "Domain Name",
- value: domainName,
- },
- {
- label: cnameTarget ? "Target Endpoint" : "Target IP",
- value: cnameTarget ? cnameTarget : aRecordTarget,
- },
- ];
-
- const title = cnameTarget ? "CNAME" : "A Record";
-
- return (
-
- );
-};
-
-export default CustomDNSDetailsModal;
diff --git a/src/components/ResourceInstance/Connectivity/CustomDNSEndPoint.tsx b/src/components/ResourceInstance/Connectivity/CustomDNSEndPoint.tsx
new file mode 100644
index 00000000..e4bd258a
--- /dev/null
+++ b/src/components/ResourceInstance/Connectivity/CustomDNSEndPoint.tsx
@@ -0,0 +1,91 @@
+import { Box, styled, SxProps, Theme } from "@mui/material";
+import Image from "next/image";
+import Table from "@mui/material/Table";
+import TableBody from "@mui/material/TableBody";
+import TableRow from "@mui/material/TableRow";
+import MuiTableCell from "@mui/material/TableCell";
+import { Text } from "src/components/Typography/Typography";
+import resourceEndpointIcon from "../../../../public/assets/images/dashboard/resource-instance-nodes/resource-endpoint.svg";
+import CopyButton from "src/components/Button/CopyButton";
+const TableCell = styled(MuiTableCell)({
+ borderBottom: "none",
+});
+type CustomDNSEndPointProps = {
+ isPrimaryResource: boolean;
+ endpointURL: string;
+ containerStyles?: SxProps;
+ endpointName: string;
+};
+
+const CustomDNSEndPoint: React.FC = ({
+ isPrimaryResource,
+ endpointURL,
+ containerStyles,
+ endpointName,
+}) => {
+ return (
+
+
+
+
+
+
+
+
+
+ {endpointName}
+
+
+
+
+ {endpointURL}
+
+
+
+
+
+
+
+
+ );
+};
+
+export default CustomDNSEndPoint;
diff --git a/src/components/ResourceInstance/Connectivity/ResourceCustomDNS.tsx b/src/components/ResourceInstance/Connectivity/ResourceCustomDNS.tsx
new file mode 100644
index 00000000..3c006109
--- /dev/null
+++ b/src/components/ResourceInstance/Connectivity/ResourceCustomDNS.tsx
@@ -0,0 +1,130 @@
+import { Box } from "@mui/material";
+import { useMemo } from "react";
+import PropertyTable from "./PropertyTable";
+import CustomDNS from "./CustomDNS";
+
+function ResourceCustomDNS(props) {
+ const {
+ globalEndpoints,
+ context,
+ addCustomDNSMutation,
+ removeCustomDNSMutation,
+ accessQueryParams,
+ refetchInstance,
+ } = props;
+
+ const primaryResourceName = globalEndpoints?.primary?.resourceName;
+ const primaryResourceEndpoint = globalEndpoints?.primary?.endpoint;
+
+ const [otherResourceFilteredEndpoints] = useMemo(() => {
+ const otherEndpoints = globalEndpoints?.others;
+
+ const otherResourceFilteredEndpoints = [];
+
+ otherEndpoints?.forEach((endpointData) => {
+ const { resourceName, endpoint } = endpointData;
+ if (resourceName && endpoint) {
+ // filter out omnistrate observability
+ if (resourceName === "Omnistrate Observability") {
+ return;
+ }
+ otherResourceFilteredEndpoints.push(endpointData);
+ }
+ });
+ return [otherResourceFilteredEndpoints];
+ }, [globalEndpoints]);
+
+ const rows = useMemo(() => {
+ let sectionLabel = "Resource";
+
+ if (context === "inventory") {
+ sectionLabel = "Service Component";
+ }
+
+ const res = [];
+
+ if (primaryResourceName || otherResourceFilteredEndpoints?.length > 0) {
+ const customDNSEndpointName =
+ globalEndpoints?.primary?.customDNSEndpoint?.name ?? "";
+ if (
+ globalEndpoints?.primary?.resourceHasCompute &&
+ globalEndpoints?.primary?.customDNSEndpoint?.enabled
+ ) {
+ res.push({
+ label: primaryResourceName,
+ description: `The global endpoint of the ${sectionLabel.toLowerCase()}`,
+ valueType: "custom",
+ value: (
+ <>
+ {primaryResourceName && (
+
+ )}
+ >
+ ),
+ });
+ }
+ }
+
+ if (otherResourceFilteredEndpoints?.length > 0) {
+ otherResourceFilteredEndpoints.forEach(
+ ({
+ resourceName,
+ resourceKey,
+ resourceId,
+ resourceHasCompute,
+ customDNSEndpoint,
+ }) => {
+ const customDNSEndpointName = customDNSEndpoint?.name ?? "";
+ if (resourceHasCompute && customDNSEndpoint?.enabled) {
+ res.push({
+ label: resourceName,
+ description: `The global endpoint of the ${sectionLabel.toLowerCase()}`,
+ valueType: "custom",
+ value: (
+
+ ),
+ });
+ }
+ }
+ );
+ }
+
+ return res;
+ }, [
+ context,
+ primaryResourceName,
+ primaryResourceEndpoint,
+ otherResourceFilteredEndpoints,
+ globalEndpoints?.primary?.customDNSEndpoint,
+ addCustomDNSMutation,
+ removeCustomDNSMutation,
+ ]);
+
+ return (
+ rows.length > 0 && (
+
+
+
+ )
+ );
+}
+
+export default ResourceCustomDNS;