Просмотр исходного кода

Merge pull request #1422 from porter-dev/staging

Merge fullscreen logs + provisioner CLI fix -> production
abelanger5 4 лет назад
Родитель
Сommit
94a783b6c0

BIN
dashboard/src/assets/logo.png


+ 3 - 6
dashboard/src/components/image-selector/ImageList.tsx

@@ -280,20 +280,17 @@ const BackButton = styled.div`
   }
 `;
 
-const ImageItem = styled.div`
+const ImageItem = styled.div<{ lastItem: boolean, isSelected: boolean }>`
   display: flex;
   width: 100%;
   font-size: 13px;
-  border-bottom: 1px solid
-    ${(props: { lastItem: boolean; isSelected: boolean }) =>
-      props.lastItem ? "#00000000" : "#606166"};
+  border-bottom: 1px solid ${props => props.lastItem ? "#00000000" : "#606166"};
   color: #ffffff;
   user-select: none;
   align-items: center;
   padding: 10px 0px;
   cursor: pointer;
-  background: ${(props: { isSelected: boolean; lastItem: boolean }) =>
-    props.isSelected ? "#ffffff11" : ""};
+  background: ${props => props.isSelected ? "#ffffff11" : ""};
   :hover {
     background: #ffffff22;
 

+ 3 - 5
dashboard/src/components/image-selector/TagList.tsx

@@ -169,20 +169,18 @@ const StyledTagList = styled.div`
   overflow: auto;
 `;
 
-const TagName = styled.div`
+const TagName = styled.div<{ lastItem?: boolean; isSelected?: boolean }>`
   display: flex;
   width: 100%;
   font-size: 13px;
   border-bottom: 1px solid
-    ${(props: { lastItem?: boolean; isSelected?: boolean }) =>
-      props.lastItem ? "#00000000" : "#606166"};
+    ${props => props.lastItem ? "#00000000" : "#606166"};
   color: #ffffff;
   user-select: none;
   align-items: center;
   padding: 10px 0px;
   cursor: pointer;
-  background: ${(props: { isSelected?: boolean; lastItem?: boolean }) =>
-    props.isSelected ? "#ffffff11" : ""};
+  background: ${props => props.isSelected ? "#ffffff11" : ""};
   :hover {
     background: #ffffff22;
 

+ 3 - 3
dashboard/src/main/auth/Login.tsx

@@ -436,9 +436,9 @@ const Prompt = styled.div`
 `;
 
 const Logo = styled.img`
-  width: 140px;
-  margin-top: 50px;
-  margin-bottom: 45px;
+  width: 110px;
+  margin-top: 55px;
+  margin-bottom: 40px;
   user-select: none;
 `;
 

+ 3 - 3
dashboard/src/main/auth/Register.tsx

@@ -434,9 +434,9 @@ const Prompt = styled.div`
 `;
 
 const Logo = styled.img`
-  width: 140px;
-  margin-top: 50px;
-  margin-bottom: 35px;
+  width: 110px;
+  margin-top: 45px;
+  margin-bottom: 30px;
   user-select: none;
 `;
 

+ 12 - 0
dashboard/src/main/home/ModalHandler.tsx

@@ -15,6 +15,7 @@ import RedirectToOnboardingModal from "./modals/RedirectToOnboardingModal";
 import UsageWarningModal from "./modals/UsageWarningModal";
 import api from "shared/api";
 import { AxiosError } from "axios";
+import SkipOnboardingModal from "./modals/SkipProvisioningModal";
 
 const ModalHandler: React.FC<{
   setRefreshClusters: (x: boolean) => void;
@@ -187,6 +188,17 @@ const ModalHandler: React.FC<{
           <UsageWarningModal />
         </Modal>
       )}
+
+      {modal === "SkipOnboardingModal" && (
+        <Modal
+          onRequestClose={() => setCurrentModal(null, null)}
+          width="600px"
+          height="240px"
+          title="Would you like to skip project setup?"
+        >
+          <SkipOnboardingModal />
+        </Modal>
+      )}
     </>
   );
 };

+ 11 - 1
dashboard/src/main/home/cluster-dashboard/expanded-chart/ExpandedChart.tsx

@@ -82,6 +82,7 @@ const ExpandedChart: React.FC<Props> = (props) => {
   const [isLoadingChartData, setIsLoadingChartData] = useState<boolean>(true);
   const [showRepoTooltip, setShowRepoTooltip] = useState(false);
   const [isAuthorized] = useAuth();
+  const [fullScreenLogs, setFullScreenLogs] = useState<boolean>(false);
 
   const {
     newWebsocket,
@@ -383,7 +384,7 @@ const ExpandedChart: React.FC<Props> = (props) => {
             </Placeholder>
           );
         } else {
-          return <StatusSection currentChart={chart} />;
+          return <StatusSection currentChart={chart} setFullScreenLogs={() => setFullScreenLogs(true)} />;
         }
       case "settings":
         return (
@@ -662,6 +663,14 @@ const ExpandedChart: React.FC<Props> = (props) => {
 
   return (
     <>
+      { 
+        fullScreenLogs ? (
+          <StatusSection
+            fullscreen={true} 
+            currentChart={currentChart} 
+            setFullScreenLogs={() => setFullScreenLogs(false)}
+          />
+        ) : (
       <StyledExpandedChart>
         <HeaderWrapper>
           <BackButton onClick={props.closeChart}>
@@ -758,6 +767,7 @@ const ExpandedChart: React.FC<Props> = (props) => {
           </>
         )}
       </StyledExpandedChart>
+    )}
     </>
   );
 };

+ 1 - 0
dashboard/src/main/home/cluster-dashboard/expanded-chart/status/Logs.tsx

@@ -434,6 +434,7 @@ const LogStream = styled.div`
   flex: 1;
   float: right;
   height: 100%;
+  font-size: 13px;
   background: #121318;
   user-select: text;
   max-width: 65%;

+ 112 - 1
dashboard/src/main/home/cluster-dashboard/expanded-chart/status/StatusSection.tsx

@@ -5,6 +5,7 @@ import api from "shared/api";
 import { Context } from "shared/Context";
 import { ChartType, StorageType } from "shared/types";
 import Loading from "components/Loading";
+import backArrow from "assets/back_arrow.png";
 
 import Logs from "./Logs";
 import ControllerTab from "./ControllerTab";
@@ -12,10 +13,14 @@ import ControllerTab from "./ControllerTab";
 type Props = {
   selectors?: string[];
   currentChart: ChartType;
+  fullscreen?: boolean;
+  setFullScreenLogs?: any;
 };
 
 const StatusSectionFC: React.FunctionComponent<Props> = ({
   currentChart,
+  fullscreen,
+  setFullScreenLogs,
   selectors,
 }) => {
   const [selectedPod, setSelectedPod] = useState<any>({});
@@ -126,11 +131,108 @@ const StatusSectionFC: React.FunctionComponent<Props> = ({
     );
   };
 
-  return <StyledStatusSection>{renderStatusSection()}</StyledStatusSection>;
+  return (
+    <>
+      {
+        fullscreen ? (
+          <FullScreen>
+            <AbsoluteTitle>
+              <BackButton
+                onClick={setFullScreenLogs}
+              >
+                <i className="material-icons">navigate_before</i>
+              </BackButton>
+              Status ({currentChart.name})
+            </AbsoluteTitle>
+            <FullScreenButton top="70px" onClick={setFullScreenLogs}>
+              <i className="material-icons">close_fullscreen</i>
+            </FullScreenButton>
+            {renderStatusSection()}
+          </FullScreen>
+        ) : (
+          <StyledStatusSection>
+            <FullScreenButton onClick={setFullScreenLogs}>
+              <i className="material-icons">open_in_full</i>
+            </FullScreenButton>
+            {renderStatusSection()}
+          </StyledStatusSection>
+        )
+      }
+    </>
+  );
 };
 
 export default StatusSectionFC;
 
+const FullScreenButton = styled.div<{ top?: string }>`
+  position: absolute;
+  top: ${props => props.top || "10px"};
+  right: 10px;
+  width: 24px;
+  height: 24px;
+  cursor: pointer;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  border-radius: 5px;
+  background: #ffffff11;
+  border: 1px solid #aaaabb;
+
+  :hover {
+    background: #ffffff22;
+  }
+
+  > i {
+    font-size: 14px;
+  }
+`;
+
+const BackButton = styled.div`
+  display: flex;
+  width: 30px;
+  z-index: 999;
+  cursor: pointer;
+  height: 30px;
+  align-items: center;
+  margin-right: 15px;
+  justify-content: center;
+  cursor: pointer;
+  border: 1px solid #ffffff55;
+  border-radius: 100px;
+  background: #ffffff11;
+
+  > i {
+    font-size: 18px;
+  }
+
+  :hover {
+    background: #ffffff22;
+    > img {
+      opacity: 1;
+    }
+  }
+`;
+
+const BackButtonImg = styled.img`
+  width: 12px;
+  opacity: 0.75;
+`;
+
+
+const AbsoluteTitle = styled.div`
+  position: absolute;
+  top: 0px;
+  left: 0px;
+  width: 100%;
+  height: 60px;
+  display: flex;
+  align-items: center;
+  padding-left: 20px;
+  font-size: 18px;
+  font-weight: 500;
+  user-select: text;
+`;
+
 const TabWrapper = styled.div`
   width: 35%;
   min-width: 250px;
@@ -163,6 +265,15 @@ const StyledStatusSection = styled.div`
   }
 `;
 
+const FullScreen = styled.div`
+  position: absolute;
+  top: 0;
+  left: 0;
+  width: 100%;
+  height: 100%;
+  padding-top: 60px;
+`;
+
 const Wrapper = styled.div`
   width: 100%;
   height: 100%;

+ 58 - 0
dashboard/src/main/home/modals/SkipProvisioningModal.tsx

@@ -0,0 +1,58 @@
+import InputRow from "components/form-components/InputRow";
+import SaveButton from "components/SaveButton";
+import React, { useContext } from "react";
+import { Context } from "shared/Context";
+import styled from "styled-components";
+
+/**
+ * If user goes to /onboarding and has clusters, the Onboarding component
+ * will open this modal to let user skip onboarding and keep using porter.
+ */
+const SkipOnboardingModal = () => {
+  const { currentModalData, setCurrentModal } = useContext(Context);
+
+  return (
+    <>
+      <Subtitle>
+        Porter has detected an existing Kubernetes cluster that was connected
+        via the CLI. For custom setups, you can skip the project setup flow.
+      </Subtitle>
+      <Subtitle>Do you want to skip project setup?</Subtitle>
+      <ActionsWrapper>
+        <ActionButton
+          text="Yes, skip setup"
+          color="#616FEEcc"
+          onClick={() =>
+            typeof currentModalData?.skipOnboarding === "function" &&
+            currentModalData.skipOnboarding()
+          }
+          status={""}
+          clearPosition
+        />
+      </ActionsWrapper>
+    </>
+  );
+};
+
+export default SkipOnboardingModal;
+
+const ActionButton = styled(SaveButton)``;
+
+const ActionsWrapper = styled.div`
+  position: absolute;
+  bottom: 14px;
+  right: 14px;
+  display: flex;
+  ${ActionButton} {
+    margin-left: 5px;
+  }
+`;
+
+const Subtitle = styled.div`
+  margin-top: 23px;
+  font-family: "Work Sans", sans-serif;
+  font-size: 14px;
+  color: #aaaabb;
+  overflow: hidden;
+  margin-bottom: -10px;
+`;

+ 32 - 0
dashboard/src/main/home/onboarding/Onboarding.tsx

@@ -115,6 +115,38 @@ const Onboarding = () => {
     }
   }, [context.user]);
 
+  const skipOnboarding = () => {
+    OFState.actions.goTo("clean_up");
+  };
+
+  const checkIfUserHasClusters = async () => {
+    const { setCurrentModal, currentProject } = context;
+
+    const project_id = currentProject?.id;
+
+    try {
+      if (typeof project_id !== "number") {
+        return;
+      }
+
+      const clusters = await api
+        .getClusters("<token>", {}, { id: project_id })
+        .then((res) => res?.data);
+
+      const hasClusters = Array.isArray(clusters) && clusters.length;
+
+      if (hasClusters) {
+        setCurrentModal("SkipOnboardingModal", { skipOnboarding });
+      }
+    } catch (error) {
+      console.error(error);
+    }
+  };
+
+  useEffect(() => {
+    checkIfUserHasClusters();
+  }, [context?.currentProject?.id]);
+
   return (
     <StyledOnboarding>{isLoading ? <Loading /> : <Routes />}</StyledOnboarding>
   );