Justin Rhee 3 лет назад
Родитель
Сommit
736c2ed053

+ 2 - 4
dashboard/src/components/CredentialsForm.tsx

@@ -12,6 +12,7 @@ import Heading from "components/form-components/Heading";
 import Helper from "./form-components/Helper";
 import InputRow from "./form-components/InputRow";
 import SaveButton from "./SaveButton";
+import Loading from "./Loading";
 
 type Props = {
   goBack: () => void;
@@ -41,7 +42,6 @@ const CredentialsForm: React.FC<Props> = ({
   const [createStatus, setCreateStatus] = useState("");
 
   useEffect(() => {
-    console.log("great creds")
     api
       .getAWSIntegration(
         "<token>",
@@ -51,9 +51,7 @@ const CredentialsForm: React.FC<Props> = ({
         }
       )
       .then(({ data }) => {
-        console.log("creds data", data);
         if (!Array.isArray(data)) {
-          console.log("no creds");
           setAWSCredentials([]);
         } else {
           setAWSCredentials(data);
@@ -192,7 +190,7 @@ const CredentialsForm: React.FC<Props> = ({
       </Helper>
       {
         isLoading ? (
-          <>Loading . . .</>
+          <Loading height="150px" />
         ) : (
           renderContent()
         )

+ 0 - 2
dashboard/src/components/TitleSection.tsx

@@ -69,10 +69,8 @@ const BackButton = styled.div`
 `;
 
 const StyledTitleSection = styled.div`
-  margin-bottom: 15px;
   display: flex;
   align-items: center;
-  height: 35px;
 `;
 
 const Icon = styled.img<{ width: string }>`

+ 20 - 6
dashboard/src/components/porter/LoadingBar.tsx

@@ -5,16 +5,28 @@ type Props = {
   percent?: number;
   completed?: number;
   total?: number;
+  color?: string;
 };
 
 const LoadingBar: React.FC<Props> = ({
   percent,
   completed,
   total,
+  color,
 }) => {
+  const getColor = () => {
+    switch (color) {
+      case "failed":
+        return "#cc3d42";
+      default:
+        return color;
+    }
+  };
+  
   return (
     <StyledLoadingBar>
-      <LoadingFill 
+      <LoadingFill
+        color={getColor()}
         percent={(percent || ((100.0 * completed) / total)) + "%"}
       />
     </StyledLoadingBar>
@@ -33,17 +45,19 @@ const StyledLoadingBar = styled.div`
 
 const movingGradient = keyframes`
   0% {
-      background-position: left bottom;
+    background-position: left bottom;
   }
-
   100% {
-      background-position: right bottom;
+    background-position: right bottom;
   }
 `;
 
-const LoadingFill = styled.div<{ percent: string }>`
+const LoadingFill = styled.div<{ 
+  percent: string;
+  color?: string;
+}>`
   width: ${props => props.percent};
-  background: linear-gradient(to right, #8ce1ff, #616FEE);
+  background: ${props => props.color || "linear-gradient(to right, #8ce1ff, #616FEE)"};
   height: 100%;
   background-size: 250% 100%;
   animation: ${movingGradient} 2s infinite;

+ 1 - 1
dashboard/src/main/home/cluster-dashboard/ClusterDashboard.tsx

@@ -240,7 +240,7 @@ class ClusterDashboard extends Component<PropsType, StateType> {
 
     return (
       <>
-        <ControlRow style={{ marginTop: "35px" }}>
+        <ControlRow>
           <FilterWrapper>
             <LastRunStatusSelector
               lastRunStatus={this.state.lastRunStatus}

+ 14 - 19
dashboard/src/main/home/cluster-dashboard/DashboardHeader.tsx

@@ -4,6 +4,7 @@ import styled from "styled-components";
 import { Context } from "shared/Context";
 
 import TitleSection from "components/TitleSection";
+import Spacer from "components/porter/Spacer";
 
 type PropsType = {
   image?: any;
@@ -28,20 +29,20 @@ export default class DashboardHeader extends Component<PropsType, StateType> {
           {this.props.title}
         </TitleSection>
 
-        <Br />
-
         {this.props.description && (
-          <InfoSection>
-            <TopRow>
-              <InfoLabel>
-                <i className="material-icons">info</i> Info
-              </InfoLabel>
-            </TopRow>
-            <Description>{this.props.description}</Description>
-          </InfoSection>
+          <>
+            <Spacer height="35px" />
+            <InfoSection>
+              <TopRow>
+                <InfoLabel>
+                  <i className="material-icons">info</i> Info
+                </InfoLabel>
+              </TopRow>
+              <Description>{this.props.description}</Description>
+            </InfoSection>
+          </>
         )}
-
-        {!this.props.disableLineBreak && <LineBreak />}
+        <Spacer height="35px" />
       </>
     );
   }
@@ -49,11 +50,6 @@ export default class DashboardHeader extends Component<PropsType, StateType> {
 
 DashboardHeader.contextType = Context;
 
-const Br = styled.div`
-  width: 100%;
-  height: 1px;
-`;
-
 const LineBreak = styled.div`
   width: calc(100% - 0px);
   height: 1px;
@@ -89,10 +85,9 @@ const InfoLabel = styled.div`
 `;
 
 const InfoSection = styled.div`
-  margin-top: 15px;
+
   font-family: "Work Sans", sans-serif;
   margin-left: 0px;
-  margin-bottom: 35px;
 `;
 
 const ClusterLabel = styled.div`

+ 57 - 49
dashboard/src/main/home/cluster-dashboard/dashboard/ClusterRevisionSelector.tsx

@@ -16,17 +16,20 @@ import {
   EnumKubernetesKind, 
   EnumCloudProvider 
 } from "@porter-dev/api-contracts";
+import Spacer from "components/porter/Spacer";
 
 type Props = {
   selectedClusterVersion: any;
   setSelectedClusterVersion: any;
   setShowProvisionerStatus: any;
+  setProvisionFailureReason: any;
 };
 
 const ClusterRevisionSelector: React.FC<Props> = ({
   selectedClusterVersion,
   setSelectedClusterVersion,
   setShowProvisionerStatus,
+  setProvisionFailureReason,
 }) => {
   const { currentProject, currentCluster } = useContext(Context);
   const [versions, setVersions] = useState<any[]>(null);
@@ -37,6 +40,7 @@ const ClusterRevisionSelector: React.FC<Props> = ({
 
   const processVersions = (data: any) => {
     setFailedContractId("");
+    setProvisionFailureReason("");
     data.sort((a: any, b: any) => {
       return Date.parse(a.CreatedAt) > Date.parse(b.CreatedAt) ? -1 : 1;
     });
@@ -47,6 +51,7 @@ const ClusterRevisionSelector: React.FC<Props> = ({
 
       if (data[0].condition !== "") {
         setFailedContractId(data[0].id);
+        setProvisionFailureReason(data[0].condition);
       }
     }
 
@@ -206,59 +211,62 @@ const deleteContract = () => {
         hideSelector ? (
           <></>
         ) : (
-          <StyledClusterRevisionSelector>
-            <ExpandableSection
-              isInitiallyExpanded={false}
-              color={selectedId <= 0 ? "#ffffff66" : "#f5cb42"}
-              Header={(
-                <>
-                  <Label isCurrent={selectedId <= 0}>
-                    {
-                      selectedId === 0 ? (
-                        "Current version -"
-                      ) : (
-                        selectedId === -1 ? (
-                          failedContractId ? (
-                            ""
+          <>
+            <StyledClusterRevisionSelector>
+              <ExpandableSection
+                isInitiallyExpanded={false}
+                color={selectedId <= 0 ? "#ffffff66" : "#f5cb42"}
+                Header={(
+                  <>
+                    <Label isCurrent={selectedId <= 0}>
+                      {
+                        selectedId === 0 ? (
+                          "Current version -"
+                        ) : (
+                          selectedId === -1 ? (
+                            failedContractId ? (
+                              ""
+                            ) : (
+                              "In progress -"
+                            )
                           ) : (
-                            "In progress -"
+                            "Previewing version (not deployed) -"
                           )
+                        )
+                      }
+                    </Label>
+                    {
+                      selectedId === -1 ? (
+                        failedContractId ? (
+                          <><WarningIcon src={warning} /> Last update failed</>
                         ) : (
-                          "Previewing version (not deployed) -"
+                          <><Img src={loading} /> Updating</>
                         )
-                      )
-                    }
-                  </Label>
-                  {
-                    selectedId === -1 ? (
-                      failedContractId ? (
-                        <><WarningIcon src={warning} /> Last update failed</>
                       ) : (
-                        <><Img src={loading} /> Updating</>
+                        `No. ${versions?.length - selectedId}`
                       )
-                    ) : (
-                      `No. ${versions?.length - selectedId}`
-                    )
-                  }
-                </>
-              )}
-              ExpandedSection={(
-                <TableWrapper>
-                  <RevisionsTable>
-                    <tbody>
-                      <Tr disableHover={true}>
-                        <Th>Version no.</Th>
-                        <Th>Created</Th>
-                        {/* <Th>Rollback</Th> */}
-                      </Tr>
-                      {(pendingContract || failedContractId) && renderActiveAttempt()}
-                      {renderVersionList()}
-                    </tbody>
-                  </RevisionsTable>
-                </TableWrapper>
-              )}
-            />
-          </StyledClusterRevisionSelector>
+                    }
+                  </>
+                )}
+                ExpandedSection={(
+                  <TableWrapper>
+                    <RevisionsTable>
+                      <tbody>
+                        <Tr disableHover={true}>
+                          <Th>Version no.</Th>
+                          <Th>Created</Th>
+                          {/* <Th>Rollback</Th> */}
+                        </Tr>
+                        {(pendingContract || failedContractId) && renderActiveAttempt()}
+                        {renderVersionList()}
+                      </tbody>
+                    </RevisionsTable>
+                  </TableWrapper>
+                )}
+              />
+            </StyledClusterRevisionSelector>
+            <Spacer y={1} />
+          </>
         )
       }
     </>
@@ -286,9 +294,9 @@ const DeleteButton = styled.div`
 `;
 
 const WarningIcon = styled.img`
-  height: 20px;
+  height: 18px;
   margin-right: 10px;
-  margin-left: -4px;
+  margin-left: -8px;
 `;
 
 const Failed = styled.div`

+ 6 - 1
dashboard/src/main/home/cluster-dashboard/dashboard/Dashboard.tsx

@@ -37,6 +37,7 @@ export const Dashboard: React.FunctionComponent = () => {
   const location = useLocation();
   const [selectedClusterVersion, setSelectedClusterVersion] = useState(null);
   const [showProvisionerStatus, setShowProvisionerStatus] = useState(false);
+  const [provisionFailureReason, setProvisionFailureReason] = useState("");
   const [ingressIp, setIngressIp] = useState(null);
   const [ingressError, setIngressError] = useState(null);
 
@@ -104,6 +105,7 @@ export const Dashboard: React.FunctionComponent = () => {
 
   // Need to reset tab to reset views that don't auto-update on cluster switch (esp namespaces + settings)
   useEffect(() => {
+    setShowProvisionerStatus(false);
     if (context.currentProject.capi_provisioner_enabled) {
       setCurrentTab("configuration");
     } else {
@@ -187,6 +189,7 @@ export const Dashboard: React.FunctionComponent = () => {
             selectedClusterVersion={selectedClusterVersion}
             setSelectedClusterVersion={setSelectedClusterVersion}
             setShowProvisionerStatus={setShowProvisionerStatus}
+            setProvisionFailureReason={setProvisionFailureReason}
           />
           {(
             showProvisionerStatus && (
@@ -195,8 +198,10 @@ export const Dashboard: React.FunctionComponent = () => {
             )
           ) && (
             <>
+              <ProvisionerStatus
+                provisionFailureReason={provisionFailureReason}
+              />
               <Spacer y={1} />
-              <ProvisionerStatus />
             </>
           )}
           <TabSelector

+ 14 - 9
dashboard/src/main/home/cluster-dashboard/dashboard/ProvisionerStatus.tsx

@@ -12,9 +12,13 @@ import Spacer from "components/porter/Spacer";
 import Helper from "components/form-components/Helper";
 import Text from "components/porter/Text";
 
-type Props = {};
+type Props = {
+  provisionFailureReason: string;
+};
 
-const ProvisionerStatus: React.FC<Props> = ({}) => {
+const ProvisionerStatus: React.FC<Props> = ({
+  provisionFailureReason,
+}) => {
   const { currentProject, currentCluster } = useContext(Context);
   const [progress, setProgress] = useState(1);
 
@@ -54,15 +58,19 @@ const ProvisionerStatus: React.FC<Props> = ({}) => {
           AWS provisioning status
         </Flex>
         <Spacer height="18px" />
-        <LoadingBar completed={progress} total={4} />
+        <LoadingBar
+          color={provisionFailureReason && "failed"}
+          completed={progress} 
+          total={5} 
+        />
         <Spacer height="18px" />
         <Text color="#aaaabb">
           Setup can take up to 20 minutes. You can close this window and come back later. 
         </Text>
       </HeaderSection>
       {
-        false && (
-          <DummyLogs>[Logs unimplemented]</DummyLogs>
+        provisionFailureReason && (
+          <DummyLogs>Error: {provisionFailureReason}</DummyLogs>
         )
       }
     </StyledProvisionerStatus>
@@ -82,11 +90,9 @@ const HeaderSection = styled.div`
 `;
 
 const DummyLogs = styled.div`
-  height: 150px;
+  padding: 15px;
   width: 100%;
   display: flex;
-  align-items: center;
-  justify-content: center;
   font-size: 13px;
   background: #101420;
   font-family: monospace;
@@ -111,7 +117,6 @@ const Status = styled.div`
 `;
 
 const StyledProvisionerStatus = styled.div`
-  margin-bottom: 22px;
   border-radius: 5px;
   background: #26292e;
   border: 1px solid #494b4f;

+ 1 - 1
dashboard/src/main/home/cluster-dashboard/preview-environments/environments/EnvironmentsList.tsx

@@ -136,7 +136,7 @@ const ControlRow = styled.div`
   margin-left: auto;
   justify-content: space-between;
   align-items: center;
-  margin: 35px 0 30px;
+  margin-bottom: 30px;
   padding-left: 0px;
 `;
 

+ 2 - 1
dashboard/src/main/home/dashboard/Dashboard.tsx

@@ -19,6 +19,7 @@ import Banner from "components/Banner";
 
 import { pushFiltered, pushQueryParams } from "shared/routing";
 import { withAuth, WithAuthProps } from "shared/auth/AuthorizationHoc";
+import Spacer from "components/porter/Spacer";
 
 type PropsType = RouteComponentProps &
   WithAuthProps & {
@@ -179,7 +180,7 @@ class Dashboard extends Component<PropsType, StateType> {
                     </i>
                   )}
                 </TitleSection>
-                <Br />
+                <Spacer height="15px" />
 
                 <InfoSection>
                   <TopRow>

+ 1 - 1
dashboard/src/main/home/infrastructure/InfrastructureList.tsx

@@ -178,7 +178,7 @@ const InfrastructureList = () => {
         <DashboardIcon>
           <i className="material-icons">build_circle</i>
         </DashboardIcon>
-        Managed Infrastructure
+        Managed infrastructure (legacy)
       </StyledTitleSection>
       <InfoSection>
         <Description>

+ 0 - 1
dashboard/src/main/home/integrations/IntegrationList.tsx

@@ -267,7 +267,6 @@ const Placeholder = styled.div`
 `;
 
 const StyledIntegrationList = styled.div`
-  margin-top: 30px;
   margin-bottom: 80px;
 `;
 

+ 2 - 1
dashboard/src/main/home/integrations/Integrations.tsx

@@ -10,6 +10,7 @@ import IntegrationCategories from "./IntegrationCategories";
 import IntegrationList from "./IntegrationList";
 import TitleSection from "components/TitleSection";
 import { Context } from "shared/Context";
+import Spacer from "components/porter/Spacer";
 
 type PropsType = RouteComponentProps;
 
@@ -75,7 +76,7 @@ const Integrations: React.FC<PropsType> = (props) => {
         <Route>
           <div>
             <TitleSection>Integrations</TitleSection>
-
+            <Spacer y={1} />
             <IntegrationList
               currentCategory={""}
               integrations={IntegrationCategoryStrings}

+ 2 - 0
dashboard/src/main/home/launch/Launch.tsx

@@ -18,6 +18,7 @@ import { RouteComponentProps, withRouter } from "react-router";
 import { getQueryParam, getQueryParams } from "shared/routing";
 import TemplateList from "./TemplateList";
 import { capitalize } from "lodash";
+import Spacer from "components/porter/Spacer";
 
 const initialTabOptions = [
   { label: "New application", value: "porter" },
@@ -421,6 +422,7 @@ class Templates extends Component<PropsType, StateType> {
               <i className="material-icons">help_outline</i>
             </a>
           </TitleSection>
+          <Spacer height="20px" />
           {this.renderContents()}
         </TemplatesWrapper>
       );

+ 2 - 0
dashboard/src/main/home/project-settings/ProjectSettings.tsx

@@ -14,6 +14,7 @@ import { getQueryParam } from "shared/routing";
 import BillingPage from "./BillingPage";
 import APITokensSection from "./APITokensSection";
 import _ from "lodash";
+import Spacer from "components/porter/Spacer";
 
 type PropsType = RouteComponentProps & WithAuthProps & {};
 
@@ -185,6 +186,7 @@ class ProjectSettings extends Component<PropsType, StateType> {
     return (
       <StyledProjectSettings>
         <TitleSection>Project settings</TitleSection>
+        <Spacer height="20px" />
         <TabRegion
           currentTab={this.state.currentTab}
           setCurrentTab={(x: string) => this.setState({ currentTab: x })}