Sfoglia il codice sorgente

clean up preview env settings

Justin Rhee 3 anni fa
parent
commit
5a462408f7

+ 4 - 4
dashboard/src/components/Placeholder.tsx

@@ -8,9 +8,9 @@ interface Props {
   title?: string;
 }
 
-const Placeholder: React.FC<Props> = ({ 
-  height, 
-  minHeight, 
+const Placeholder: React.FC<Props> = ({
+  height,
+  minHeight,
   children,
   title,
 }) => {
@@ -51,7 +51,7 @@ const StyledPlaceholder = styled.div<{
   min-height: ${(props) => props.minHeight || ""};
   display: flex;
   align-items: center;
-  color: #8D949E;
+  color: #8d949e;
   padding: 50px;
   justify-content: center;
   font-size: 13px;

+ 4 - 7
dashboard/src/components/TitleSection.tsx

@@ -41,10 +41,7 @@ const TitleSection: React.FC<Props> = ({
           <Icon width={iconWidth} src={icon} />
         ))}
 
-      <StyledTitle
-        capitalize={capitalize}
-        onClick={onClick}
-      >
+      <StyledTitle capitalize={capitalize} onClick={onClick}>
         {children}
       </StyledTitle>
     </StyledTitleSection>
@@ -85,7 +82,7 @@ const MaterialIcon = styled.span<{ width: string }>`
   margin-right: 16px;
 `;
 
-const StyledTitle = styled.div<{ 
+const StyledTitle = styled.div<{
   capitalize: boolean;
   onClick?: any;
 }>`
@@ -95,9 +92,9 @@ const StyledTitle = styled.div<{
   text-transform: ${(props) => (props.capitalize ? "capitalize" : "")};
   display: flex;
   align-items: center;
-  cursor: ${props => props.onClick ? "pointer" : ""};
+  cursor: ${(props) => (props.onClick ? "pointer" : "")};
   :hover {
-    text-decoration: ${props => props.onClick ? "underline" : ""};
+    text-decoration: ${(props) => (props.onClick ? "underline" : "")};
   }
 
   > i {

+ 3 - 1
dashboard/src/main/home/cluster-dashboard/DashboardHeader.tsx

@@ -21,7 +21,9 @@ export default class DashboardHeader extends Component<PropsType, StateType> {
     return (
       <>
         <TitleSection
-          capitalize={this.props.capitalize === undefined || this.props.capitalize}
+          capitalize={
+            this.props.capitalize === undefined || this.props.capitalize
+          }
           icon={this.props.image}
           materialIconClass={this.props.materialIconClass}
         >

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

@@ -156,4 +156,4 @@ const StyledNamespaceSelector = styled.div`
   display: flex;
   align-items: center;
   font-size: 13px;
-`;
+`;

+ 3 - 3
dashboard/src/main/home/cluster-dashboard/expanded-chart/events/EventList.tsx

@@ -373,9 +373,9 @@ const EventList: React.FC<Props> = ({ filters, namespace, setLogData }) => {
         </LoadWrapper>
       ) : (
         <TableWrapper>
-          <Table 
-            columns={columns} 
-            data={events} 
+          <Table
+            columns={columns}
+            data={events}
             placeholder="No events found."
           />
           <FlexRow>

+ 2 - 66
dashboard/src/main/home/cluster-dashboard/preview-environments/ConnectNewRepo.tsx

@@ -193,7 +193,7 @@ const ConnectNewRepo: React.FC = () => {
               alignItems: "center",
             }}
           >
-            Enable Preview Environments on a Repository
+            Enable preview environments on a repository
             <DocsHelper
               tooltipText="Learn more about preview environments"
               link="https://docs.porter.run/preview-environments/overview/"
@@ -203,7 +203,7 @@ const ConnectNewRepo: React.FC = () => {
         </Title>
       </HeaderSection>
 
-      <Heading>Select a Repository</Heading>
+      <Heading>Select a repository</Heading>
       <br />
       <RepoList
         actionConfig={actionConfig}
@@ -224,70 +224,6 @@ const ConnectNewRepo: React.FC = () => {
         />
       </HelperContainer>
 
-      <Heading>Automatic pull request deployments</Heading>
-      <Helper>
-        If you enable this option, the new pull requests will be automatically
-        deployed.
-      </Helper>
-      <CheckboxWrapper>
-        <CheckboxRow
-          label="Enable automatic deploys"
-          checked={enableAutomaticDeployments}
-          toggle={() =>
-            setEnableAutomaticDeployments(!enableAutomaticDeployments)
-          }
-          wrapperStyles={{
-            disableMargin: true,
-          }}
-        />
-      </CheckboxWrapper>
-
-      <Heading>Disable new comments for new deployments</Heading>
-      <Helper>
-        When enabled new comments will not be created for new deployments.
-        Instead the last comment will be updated.
-      </Helper>
-      <CheckboxWrapper>
-        <CheckboxRow
-          label="Disable new comments for deployments"
-          checked={isNewCommentsDisabled}
-          toggle={() => setIsNewCommentsDisabled(!isNewCommentsDisabled)}
-          wrapperStyles={{
-            disableMargin: true,
-          }}
-        />
-      </CheckboxWrapper>
-
-      <Heading>Select allowed branches</Heading>
-      <Helper>
-        If the pull request has a base branch included in this list, it will be
-        allowed to be deployed.
-        <br />
-        (Leave empty to allow all branches)
-      </Helper>
-      <BranchFilterSelector
-        onChange={setSelectedBranches}
-        options={availableBranches}
-        value={selectedBranches}
-        showLoading={isLoadingBranches}
-      />
-
-      <Heading>Namespace annotations</Heading>
-      <Helper>
-        Custom annotations to be injected into the Kubernetes namespace created
-        for each deployment.
-      </Helper>
-      <NamespaceAnnotations
-        values={namespaceAnnotations}
-        setValues={(x: KeyValueType[]) => {
-          let annotations: KeyValueType[] = [];
-          x.forEach((entry) => {
-            annotations.push({ key: entry.key, value: entry.value });
-          });
-          setNamespaceAnnotations(annotations);
-        }}
-      />
-
       <ActionContainer>
         <SaveButton
           text="Add repository"

+ 37 - 14
dashboard/src/main/home/cluster-dashboard/preview-environments/components/BranchFilterSelector.tsx

@@ -1,6 +1,7 @@
 import SearchSelector from "components/SearchSelector";
 import React, { useMemo } from "react";
 import styled from "styled-components";
+import branch_icon from "assets/branch.png";
 
 const BranchFilterSelector = ({
   value,
@@ -55,14 +56,15 @@ const BranchFilterSelector = ({
       {/* List selected branches  */}
 
       <BranchRowList>
-      {value.map((branch) => (
-        <BranchRow key={branch}>
-          <div>{branch}</div>
-          <RemoveBranchButton onClick={() => handleDeleteBranch(branch)}>
-            x
-          </RemoveBranchButton>
-        </BranchRow>
-      ))}
+        {value.map((branch, i) => (
+          <BranchRow key={branch} isLast={value.length - 1 === i}>
+            <img src={branch_icon} />
+            <div>{branch}</div>
+            <RemoveBranchButton onClick={() => handleDeleteBranch(branch)}>
+              <i className="material-icons-round">close</i>
+            </RemoveBranchButton>
+          </BranchRow>
+        ))}
       </BranchRowList>
     </>
   );
@@ -71,20 +73,41 @@ const BranchFilterSelector = ({
 export default BranchFilterSelector;
 
 const BranchRowList = styled.div`
-  margin-block: 15px;
+  border: 1px solid #494b4f;
+  border-radius: 5px;
   max-height: 200px;
+  margin-top: 22px;
   overflow-y: auto;
 `;
 
-const BranchRow = styled.div`
-  padding-inline: 8px;
-  gap: 10px;
+const BranchRow = styled.div<{ isLast?: boolean; isSelected?: boolean }>`
   width: 100%;
+  padding: 10px;
   display: flex;
-  flex-direction: row;
-  justify-content: space-between;
+  align-items: center;
+  cursor: pointer;
+  border-bottom: ${(props) => (props.isLast ? "" : "1px solid #494b4f")};
+
+  > img {
+    width: 17px;
+    margin-right: 8px;
+  }
 `;
 
 const RemoveBranchButton = styled.div`
   cursor: pointer;
+  width: 20px;
+  display: flex;
+  align-items: center;
+  border-radius: 20px;
+  justify-content: center;
+  color: #aaaabb;
+  height: 20px;
+  margin-left: 12px;
+  :hover {
+    background: #ffffff11;
+  }
+  > i {
+    font-size: 14px;
+  }
 `;

+ 1 - 2
dashboard/src/main/home/cluster-dashboard/preview-environments/components/ButtonEnablePREnvironments.tsx

@@ -169,5 +169,4 @@ const Button = styled(DynamicLink)`
   }
 `;
 
-const Container = styled.div`
-`;
+const Container = styled.div``;

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

@@ -159,6 +159,6 @@ const Input = styled.input`
 `;
 
 const StyledInputArray = styled.div`
-  margin-bottom: 15px;
+  margin-bottom: 5px;
   margin-top: 22px;
 `;

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

@@ -44,7 +44,7 @@ export const PreviewEnvironmentsHeader = () => {
 
 const StyledLink = styled.a`
   text-decoration: underline;
-  margin-left: 7px;  
+  margin-left: 7px;
 `;
 
 const AlertCard = styled.div`

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

@@ -259,7 +259,7 @@ const DeploymentCard: React.FC<{
             {deployment.status === DeploymentStatus.Failed ||
             deployment.status === DeploymentStatus.TimedOut ? (
               <>
-                <MaterialTooltip title="Re run last github workflow">
+                <MaterialTooltip title="Re-run last GitHub workflow">
                   <ReRunButton
                     onClick={() => reRunWorkflow()}
                     disabled={isReRunningWorkflow}

+ 2 - 2
dashboard/src/main/home/cluster-dashboard/preview-environments/deployments/DeploymentList.tsx

@@ -300,7 +300,7 @@ const DeploymentList = () => {
             <DynamicLink
               to={`/preview-environments/deployments/${environment_id}/${repo_owner}/${repo_name}/settings`}
             >
-              <I className="material-icons">more_vert</I>
+              <I className="material-icons">settings</I>
             </DynamicLink>
           </Flex>
         }
@@ -400,7 +400,7 @@ const I = styled.i`
   font-size: 18px;
   user-select: none;
   margin-left: 15px;
-  color: #aaaabb;
+  color: #ffffff44;
   margin-bottom: -3px;
   cursor: pointer;
   width: 30px;

+ 165 - 79
dashboard/src/main/home/cluster-dashboard/preview-environments/environments/EnvironmentSettings.tsx

@@ -12,6 +12,7 @@ import CheckboxRow from "components/form-components/CheckboxRow";
 import { Environment, EnvironmentDeploymentMode } from "../types";
 import SaveButton from "components/SaveButton";
 import _ from "lodash";
+import TabRegion from "components/TabRegion";
 import { Context } from "shared/Context";
 import PageNotFound from "components/PageNotFound";
 import Banner from "components/Banner";
@@ -33,6 +34,7 @@ const EnvironmentSettings = () => {
     Context
   );
   const [selectedBranches, setSelectedBranches] = useState([]);
+  const [currentTab, setCurrentTab] = useState("pull-request");
   const [environment, setEnvironment] = useState<Environment>();
   const [saveStatus, setSaveStatus] = useState("");
   const [newCommentsDisabled, setNewCommentsDisabled] = useState(false);
@@ -174,6 +176,55 @@ const EnvironmentSettings = () => {
     setSaveStatus("");
   };
 
+  const handleSavePullRequest = async () => {
+    let annotations: Record<string, string> = {};
+
+    setSaveStatus("loading");
+
+    namespaceAnnotations
+      .filter((elem: KeyValueType, index: number, self: KeyValueType[]) => {
+        // remove any collisions that are duplicates
+        let numCollisions = self.reduce((n, _elem: KeyValueType) => {
+          return n + (_elem.key === elem.key ? 1 : 0);
+        }, 0);
+
+        if (numCollisions == 1) {
+          return true;
+        } else {
+          return (
+            index ===
+            self.findIndex((_elem: KeyValueType) => _elem.key === elem.key)
+          );
+        }
+      })
+      .forEach((elem: KeyValueType) => {
+        if (elem.key !== "" && elem.value !== "") {
+          annotations[elem.key] = elem.value;
+        }
+      });
+
+    try {
+      await api.updateEnvironment(
+        "<token>",
+        {
+          mode: deploymentMode,
+          disable_new_comments: newCommentsDisabled,
+          git_repo_branches: selectedBranches,
+          namespace_annotations: annotations,
+        },
+        {
+          project_id: currentProject.id,
+          cluster_id: currentCluster.id,
+          environment_id: Number(environmentId),
+        }
+      );
+    } catch (err) {
+      setCurrentError(err);
+    }
+
+    setSaveStatus("");
+  };
+
   const closeDeleteConfirmationModal = () => {
     setShowDeleteModal(false);
     setDeleteConfirmationPrompt("");
@@ -211,6 +262,108 @@ const EnvironmentSettings = () => {
     }
   };
 
+  const renderTabContents = () => {
+    if (currentTab === "additional-settings") {
+      return (
+        <StyledPlaceholder>
+          <Heading isAtTop>Delete preview environment</Heading>
+          <Helper>
+            Remove the Porter preview environment integration for this repo. All
+            associated preview deployments will also be destroyed.
+          </Helper>
+          <DeleteButton
+            disabled={saveStatus === "loading"}
+            onClick={() => {
+              setShowDeleteModal(true);
+            }}
+          >
+            Delete preview environment
+          </DeleteButton>
+        </StyledPlaceholder>
+      );
+    }
+    if (currentTab === "advanced") {
+      return (
+        <>
+          <StyledPlaceholder>
+            <Heading isAtTop>Allowed branches</Heading>
+            <Helper>
+              Only allow preview deployments for branches in this list. Leave
+              empty to allow all branches.
+            </Helper>
+            <BranchFilterSelector
+              onChange={setSelectedBranches}
+              options={availableBranches}
+              value={selectedBranches}
+              showLoading={isLoadingBranches}
+            />
+            <Br />
+            <Heading>Namespace annotations</Heading>
+            <Helper>
+              Custom annotations to be injected into the Kubernetes namespace
+              created for each deployment.
+            </Helper>
+            <NamespaceAnnotations
+              values={namespaceAnnotations}
+              setValues={(x: KeyValueType[]) => {
+                let annotations: KeyValueType[] = [];
+                x.forEach((entry) => {
+                  annotations.push({ key: entry.key, value: entry.value });
+                });
+                setNamespaceAnnotations(annotations);
+              }}
+            />
+          </StyledPlaceholder>
+          <SavePreviewEnvironmentSettings
+            text={"Save settings"}
+            status={saveStatus}
+            clearPosition={true}
+            statusPosition={"right"}
+            onClick={handleSave}
+          />
+        </>
+      );
+    }
+    return (
+      <>
+        <StyledPlaceholder>
+          <Heading isAtTop>Pull request comment settings</Heading>
+          <Helper>
+            Update the most recent PR comment on every deploy. If disabled, a
+            new PR comment is made per deploy.
+          </Helper>
+          <CheckboxRow
+            label="Update the most recent PR comment"
+            checked={newCommentsDisabled}
+            toggle={() => setNewCommentsDisabled(!newCommentsDisabled)}
+          />
+          <Br />
+          <Heading>Automatic preview deployments</Heading>
+          <Helper>
+            When enabled, preview deployments are automatically created for all
+            new pull requests.
+          </Helper>
+          <CheckboxRow
+            label="Automatically create preview deployments"
+            checked={deploymentMode === "auto"}
+            toggle={() =>
+              setDeploymentMode((deploymentMode) =>
+                deploymentMode === "auto" ? "manual" : "auto"
+              )
+            }
+          />
+        </StyledPlaceholder>
+        <SavePreviewEnvironmentSettings
+          text={"Save settings"}
+          status={saveStatus}
+          clearPosition={true}
+          statusPosition={"right"}
+          onClick={handleSavePullRequest}
+        />
+      </>
+    );
+  };
+
   return (
     <>
       {showDeleteModal ? (
@@ -250,84 +403,17 @@ const EnvironmentSettings = () => {
           environment.
         </Banner>
       </WarningBannerWrapper>
-      <StyledPlaceholder>
-        <Heading isAtTop>Pull request comment settings</Heading>
-        <Helper>
-          Update the most recent PR comment on every deploy. If disabled, a new
-          PR comment is made per deploy.
-        </Helper>
-        <CheckboxRow
-          label="Update the most recent PR comment"
-          checked={newCommentsDisabled}
-          toggle={() => setNewCommentsDisabled(!newCommentsDisabled)}
-        />
-        <Br />
-        <Heading>Automatic preview deployments</Heading>
-        <Helper>
-          When enabled, preview deployments are automatically created for all
-          new pull requests.
-        </Helper>
-        <CheckboxRow
-          label="Automatically create preview deployments"
-          checked={deploymentMode === "auto"}
-          toggle={() =>
-            setDeploymentMode((deploymentMode) =>
-              deploymentMode === "auto" ? "manual" : "auto"
-            )
-          }
-        />
-        <Br />
-        <Heading>Select allowed branches</Heading>
-        <Helper>
-          If the pull request has a base branch included in this list, it will
-          be allowed to be deployed.
-          <br />
-          (Leave empty to allow all branches)
-        </Helper>
-        <BranchFilterSelector
-          onChange={setSelectedBranches}
-          options={availableBranches}
-          value={selectedBranches}
-          showLoading={isLoadingBranches}
-        />
-        <Br />
-        <Heading>Namespace annotations</Heading>
-        <Helper>
-          Custom annotations to be injected into the Kubernetes namespace
-          created for each deployment.
-        </Helper>
-        <NamespaceAnnotations
-          values={namespaceAnnotations}
-          setValues={(x: KeyValueType[]) => {
-            let annotations: KeyValueType[] = [];
-            x.forEach((entry) => {
-              annotations.push({ key: entry.key, value: entry.value });
-            });
-            setNamespaceAnnotations(annotations);
-          }}
-        />
-        <SavePreviewEnvironmentSettings
-          text={"Save"}
-          status={saveStatus}
-          clearPosition={true}
-          statusPosition={"right"}
-          onClick={handleSave}
-        />
-        <Br />
-        <Heading>Delete preview environment</Heading>
-        <Helper>
-          Delete the Porter preview environment integration for this repo. All
-          preview deployments will also be destroyed.
-        </Helper>
-        <DeleteButton
-          disabled={saveStatus === "loading"}
-          onClick={() => {
-            setShowDeleteModal(true);
-          }}
-        >
-          Delete preview environment
-        </DeleteButton>
-      </StyledPlaceholder>
+      <TabRegion
+        currentTab={currentTab}
+        setCurrentTab={(x: string) => setCurrentTab(x)}
+        options={[
+          { value: "pull-request", label: "Pull request" },
+          { value: "advanced", label: "Advanced" },
+          { value: "additional-settings", label: "Additional settings" },
+        ]}
+      >
+        {renderTabContents()}
+      </TabRegion>
     </>
   );
 };
@@ -480,5 +566,5 @@ const Breadcrumb = styled(DynamicLink)`
 `;
 
 const WarningBannerWrapper = styled.div`
-  margin-block: 20px;
+  margin-bottom: 30px;
 `;

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

@@ -117,9 +117,7 @@ class Dashboard extends Component<PropsType, StateType> {
     } else if (this.currentTab() === "create-cluster") {
       let helperText = "Create a cluster to link to this project";
       let helperType = "info";
-      if (
-        true
-      ) {
+      if (true) {
         helperText =
           "You need to update your billing to provision or connect a new cluster";
         helperType = "warning";

+ 16 - 18
dashboard/src/main/home/provisioner/ProvisionerSettings.tsx

@@ -288,24 +288,22 @@ const ProvisionerSettings: React.FC<Props> = ({
               </Block>
             );
           })}
-          {
-            window.location.href.includes("dashboard.staging.getporter.dev") && (
-              <Block
-                key={3}
-                disabled={isUsageExceeded}
-                onClick={() => {
-                  if (!isUsageExceeded) {
-                    handleSelectProvider("azure");
-                    setHighlightCosts(false);
-                  }
-                }}
-              >
-                <Icon src={azure} />
-                <BlockTitle>Azure</BlockTitle>
-                <BlockDescription>Hosted in your own cloud</BlockDescription>
-              </Block>
-            )
-          }
+          {window.location.href.includes("dashboard.staging.getporter.dev") && (
+            <Block
+              key={3}
+              disabled={isUsageExceeded}
+              onClick={() => {
+                if (!isUsageExceeded) {
+                  handleSelectProvider("azure");
+                  setHighlightCosts(false);
+                }
+              }}
+            >
+              <Icon src={azure} />
+              <BlockTitle>Azure</BlockTitle>
+              <BlockDescription>Hosted in your own cloud</BlockDescription>
+            </Block>
+          )}
         </BlockList>
       ) : (
         <>{renderSelectedProvider()}</>