Jelajahi Sumber

First version of delete namespace modal

jnfrati 5 tahun lalu
induk
melakukan
8a66bb5185

+ 10 - 0
dashboard/src/main/home/Home.tsx

@@ -25,6 +25,7 @@ import NewProject from "./new-project/NewProject";
 import ProjectSettings from "./project-settings/ProjectSettings";
 import Sidebar from "./sidebar/Sidebar";
 import PageNotFound from "components/PageNotFound";
+import DeleteNamespaceModal from "./modals/DeleteNamespaceModal";
 
 type PropsType = RouteComponentProps & {
   logOut: () => void;
@@ -510,6 +511,15 @@ class Home extends Component<PropsType, StateType> {
             <NamespaceModal />
           </Modal>
         )}
+        {currentModal === "DeleteNamespaceModal" && (
+          <Modal
+            onRequestClose={() => setCurrentModal(null, null)}
+            width="700px"
+            height="250px"
+          >
+            <DeleteNamespaceModal />
+          </Modal>
+        )}
 
         {this.renderSidebar()}
 

+ 24 - 16
dashboard/src/main/home/cluster-dashboard/dashboard/NamespaceList.tsx

@@ -3,7 +3,7 @@ import styled from "styled-components";
 import api from "shared/api";
 import { Context } from "shared/Context";
 
-const OptionsDropdown = () => {
+const OptionsDropdown: React.FC = ({ children }) => {
   const [isOpen, setIsOpen] = useState(false);
   return (
     <OptionsButton
@@ -11,37 +11,40 @@ const OptionsDropdown = () => {
       onBlur={() => setIsOpen(false)}
     >
       <i className="material-icons-outlined">more_vert</i>
-      {isOpen && (
-        <DropdownMenu>
-          <DropdownOption>
-            <i className="material-icons-outlined">delete</i>
-            <span>Delete</span>
-          </DropdownOption>
-        </DropdownMenu>
-      )}
+      {isOpen && <DropdownMenu>{children}</DropdownMenu>}
     </OptionsButton>
   );
 };
 
-export const NamespaceList = () => {
-  const context = useContext(Context);
+export const NamespaceList: React.FunctionComponent = () => {
+  const {
+    currentCluster,
+    currentProject,
+    setCurrentModal,
+    setCurrentError,
+  } = useContext(Context);
   const [namespaces, setNamespaces] = useState([]);
 
   useEffect(() => {
     api
       .getNamespaces(
         "<token>",
-        { cluster_id: context.currentCluster.id },
-        { id: context.currentProject.id }
+        { cluster_id: currentCluster.id },
+        { id: currentProject.id }
       )
       .then(({ data }) => {
         setNamespaces(data.items);
       });
-  }, [context, setNamespaces]);
+  }, [currentCluster?.id, currentProject?.id, setNamespaces]);
+
+  const onDelete = (namespace: any) => {
+    setCurrentModal("DeleteNamespaceModal", namespace);
+  };
+
   return (
     <NamespaceListWrapper>
       <ControlRow>
-        <Button onClick={() => context.setCurrentModal("NamespaceModal")}>
+        <Button onClick={() => setCurrentModal("NamespaceModal")}>
           <i className="material-icons">add</i> Add namespace
         </Button>
       </ControlRow>
@@ -50,7 +53,12 @@ export const NamespaceList = () => {
         return (
           <StyledCard key={namespace?.metadata?.name}>
             {namespace?.metadata?.name}
-            <OptionsDropdown />
+            <OptionsDropdown>
+              <DropdownOption onClick={() => onDelete(namespace)}>
+                <i className="material-icons-outlined">delete</i>
+                <span>Delete</span>
+              </DropdownOption>
+            </OptionsDropdown>
           </StyledCard>
         );
       })}

+ 179 - 0
dashboard/src/main/home/modals/DeleteNamespaceModal.tsx

@@ -0,0 +1,179 @@
+import React, { Component, useContext, useMemo, useState } from "react";
+import styled from "styled-components";
+import close from "assets/close.png";
+
+import api from "shared/api";
+import { Context } from "shared/Context";
+
+import SaveButton from "components/SaveButton";
+import InputRow from "components/values-form/InputRow";
+
+const DeleteNamespaceModal = () => {
+  const {
+    currentModalData,
+    currentCluster,
+    currentProject,
+    setCurrentError,
+    setCurrentModal,
+  } = useContext(Context);
+  const [namespaceNameForDelition, setNamespaceNameForDelition] = useState("");
+  const [status, setStatus] = useState<string>(null as string);
+  const deleteNamespace = () => {
+    if (namespaceNameForDelition !== currentModalData.metadata.name) {
+      setStatus("Please insert the name of the namespace to confirm deletion");
+      return;
+    }
+
+    api
+      .deleteNamespace(
+        "<token>",
+        { name: currentModalData.metadata.name, cluster_id: currentCluster.id },
+        {
+          id: currentProject.id,
+        }
+      )
+      .then((res) => {
+        if (res.status === 200) {
+          setStatus("successful");
+          setTimeout(() => {
+            setCurrentModal(null, null);
+          }, 1000);
+        }
+      })
+      .catch((err) => {
+        setCurrentError(err);
+      });
+  };
+
+  return (
+    <StyledUpdateProjectModal>
+      <CloseButton
+        onClick={() => {
+          setCurrentModal(null, null);
+        }}
+      >
+        <CloseButtonImg src={close} />
+      </CloseButton>
+
+      <ModalTitle>Remove Namespace {currentModalData.metadata.name}</ModalTitle>
+      <Subtitle>
+        Please insert the name of the namespace to delete it:
+        <DangerText>{currentModalData.metadata.name}</DangerText>
+      </Subtitle>
+
+      <InputWrapper>
+        <DashboardIcon>
+          <i className="material-icons">warning</i>
+        </DashboardIcon>
+        <InputRow
+          type="string"
+          value={namespaceNameForDelition}
+          setValue={(x: string) => setNamespaceNameForDelition(x)}
+          placeholder={currentModalData.metadata.name}
+          width="480px"
+        />
+      </InputWrapper>
+
+      <SaveButton
+        text="Delete Namespace"
+        color="#e62659"
+        onClick={() => deleteNamespace()}
+        status={status}
+      />
+    </StyledUpdateProjectModal>
+  );
+};
+
+export default DeleteNamespaceModal;
+
+const DangerText = styled.div`
+  color: #ed5f85;
+`;
+
+const DashboardIcon = styled.div`
+  width: 32px;
+  margin-top: 6px;
+  min-width: 25px;
+  height: 32px;
+  border-radius: 3px;
+  overflow: hidden;
+  position: relative;
+  margin-right: 15px;
+  font-weight: 400;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  background: #676c7c;
+  border: 2px solid #8e94aa;
+  color: white;
+
+  > i {
+    font-size: 17px;
+  }
+`;
+
+const InputWrapper = styled.div`
+  display: flex;
+  align-items: center;
+  margin-bottom: 30px;
+`;
+
+const Subtitle = styled.div`
+  margin-top: 23px;
+  font-family: "Work Sans", sans-serif;
+  font-size: 13px;
+  color: #aaaabb;
+  overflow: hidden;
+  white-space: nowrap;
+  text-overflow: ellipsis;
+  margin-bottom: -10px;
+`;
+
+const ModalTitle = styled.div`
+  margin: 0px 0px 13px;
+  display: flex;
+  flex: 1;
+  font-family: "Assistant";
+  font-size: 18px;
+  color: #ffffff;
+  user-select: none;
+  font-weight: 700;
+  align-items: center;
+  position: relative;
+  white-space: nowrap;
+  text-overflow: ellipsis;
+`;
+
+const CloseButton = styled.div`
+  position: absolute;
+  display: block;
+  width: 40px;
+  height: 40px;
+  padding: 13px 0 12px 0;
+  z-index: 1;
+  text-align: center;
+  border-radius: 50%;
+  right: 15px;
+  top: 12px;
+  cursor: pointer;
+  :hover {
+    background-color: #ffffff11;
+  }
+`;
+
+const CloseButtonImg = styled.img`
+  width: 14px;
+  margin: 0 auto;
+`;
+
+const StyledUpdateProjectModal = styled.div`
+  width: 100%;
+  position: absolute;
+  left: 0;
+  top: 0;
+  height: 100%;
+  padding: 25px 30px;
+  overflow: hidden;
+  border-radius: 6px;
+  background: #202227;
+`;