Browse Source

Update Spacing (#3338)

sdess09 2 năm trước cách đây
mục cha
commit
6a272ff7c0

+ 73 - 21
dashboard/src/main/home/sidebar/ClusterList.tsx

@@ -10,6 +10,7 @@ import { RouteComponentProps, withRouter } from "react-router";
 import Icon from "components/porter/Icon";
 import Spacer from "components/porter/Spacer";
 import { pushFiltered } from "shared/routing";
+import SidebarLink from "./SidebarLink";
 
 const ClusterList: React.FC<PropsType> = (props) => {
   const { setCurrentCluster, user, currentCluster, currentProject } = useContext(Context);
@@ -55,6 +56,7 @@ const ClusterList: React.FC<PropsType> = (props) => {
         });
     }
   }, [currentProject]);
+  const truncate = (input: string) => input.length > 21 ? `${input.substring(0, 21)}...` : input;
 
   const renderOptionList = () =>
     options.map((option, i: number) => (
@@ -69,8 +71,7 @@ const ClusterList: React.FC<PropsType> = (props) => {
         }}
       >
 
-        <Icon src={infra} height={"13px"} />
-        <Spacer inline x={1} />
+        <Icon src={infra} height={"14px"} />
         <ClusterLabel>{option.label}</ClusterLabel>
       </Option>
     ));
@@ -90,17 +91,15 @@ const ClusterList: React.FC<PropsType> = (props) => {
           expanded={expanded}
         >
 
-          <ClusterName>
+          <NavButton>
+            <Img src={infra} />
+            <ClusterName>{truncate(currentCluster.vanity_name ? currentCluster.vanity_name : currentCluster?.name)}</ClusterName>
 
-            {/* //<Spacer inline x={.5} /> */}
-            <Icon src={infra} height={"15px"} />
-            <Spacer inline x={1} />
-            {currentCluster.vanity_name ? currentCluster.vanity_name : currentCluster?.name}
-          </ClusterName>
-          {clusters.length > 1 && <i className="material-icons">arrow_drop_down</i>}
+            {clusters.length > 1 && <i className="material-icons">arrow_drop_down</i>}
+          </NavButton>
         </MainSelector>
         {clusters.length > 1 && renderDropdown()}
-      </StyledClusterSection>
+      </StyledClusterSection >
     );
   }
 
@@ -123,6 +122,8 @@ const ClusterLabel = styled.div`
   overflow: hidden;
   white-space: nowrap;
   text-overflow: ellipsis;
+  flex-grow: 1;
+  margin-left: 5px
 `;
 
 const Plus = styled.div`
@@ -200,22 +201,18 @@ const ClusterName = styled.div`
   text-overflow: ellipsis;
   display: flex;
   align-items: center;
-  max-width: calc(100% - 50px); // Reserve space for the arrow drop down and some padding
-`;
-const StyledClusterSection = styled.div`
-  position: relative;
-  margin-left: 3px;
-  background: #545ec7;
-  border-right: 1px solid #2c2e31;
+  max-width: 180px; // You can adjust this value according to your needs
 `;
+
 const MainSelector = styled.div`
   display: flex;
   align-items: center;
-  margin: 10px 0 0;
+  justify-content: space-between;
+
   font-size: 14px;
   cursor: pointer;
   padding: 10px 0;
-  padding-left: 20px;
+  
   :hover {
     > i {
       background: #ffffff22;
@@ -223,8 +220,8 @@ const MainSelector = styled.div`
   }
 
   > i {
-    margin-left: 7px;
-    margin-right: 12px;
+    margin-left: 0px;
+    margin-right: 0px;
     font-size: 20px;
     display: flex;
     align-items: center;
@@ -234,3 +231,58 @@ const MainSelector = styled.div`
     props.expanded ? "#ffffff22" : ""};
   }
 `;
+
+const StyledClusterSection = styled.div`
+  position: relative;
+  margin-left: 3px;
+  background: #545ec7;
+  border-right: 1px solid #2c2e31;
+`;
+const NavButton = styled(SidebarLink)`
+  display: flex;
+  align-items: center;
+  position: relative;
+  text-decoration: none;
+  border-radius: 5px;
+  margin-left: 16px;
+  font-size: 13px;
+  color: ${props => props.theme.text.primary};
+  cursor: ${(props: { disabled?: boolean }) =>
+    props.disabled ? "not-allowed" : "pointer"};
+
+  background: ${(props: any) => (props.active ? "#ffffff11" : "")};
+
+  :hover {
+    background: ${(props: any) => (props.active ? "#ffffff11" : "#ffffff08")};
+  }
+
+  &.active {
+    background: #ffffff11;
+
+    :hover {
+      background: #ffffff11;
+    }
+  }
+
+  :hover {
+    background: #ffffff08;
+  }
+
+  > i {
+    font-size: 18px;
+    border-radius: 0px;
+    margin-left: 2px;
+    margin-right: 0px;
+  }
+`;
+
+
+const Img = styled.img<{ enlarge?: boolean }>`
+  padding: ${(props) => (props.enlarge ? "0 0 0 1px" : "4px")};
+  height: 22px;
+  padding-top: 4px;
+  border-radius: 3px;
+  margin-right: 8px;
+  margin-left: 2px;
+  opacity: 0.8;
+`;

+ 22 - 58
dashboard/src/main/home/sidebar/ProjectButton.tsx

@@ -22,7 +22,7 @@ const ProjectButton: React.FC<PropsType> = (props) => {
   const context = useContext(Context);
   const [showGHAModal, setShowGHAModal] = useState<boolean>(false);
 
-  const { setCurrentProject, setCurrentCluster } = context;
+  const { setCurrentProject, setCurrentCluster, user } = context;
 
   useEffect(() => {
     document.addEventListener("mousedown", handleClickOutside);
@@ -54,15 +54,21 @@ const ProjectButton: React.FC<PropsType> = (props) => {
         <MainSelector
           onClick={handleExpand}
           expanded={expanded}
+          hasMultipleProjects={props.projects.length > 1}
         >
           <ProjectIcon>
             <ProjectImage src={gradient} />
             <Letter>{currentProject.name[0].toUpperCase()}</Letter>
           </ProjectIcon>
-          <ProjectName>{currentProject.name}</ProjectName>
+          <ProjectName
+            hasMultipleProjects={props.projects.length > 1}
+            title={currentProject.name} // Add this line
+          >
+            {currentProject.name}
+          </ProjectName>
           <Spacer inline x={.5} />
 
-          {props.projects.length > 1 && <RefreshButton onClick={() => setShowGHAModal(true)}>
+          {(props.projects.length > 1 || user?.isPorterUser) && <RefreshButton onClick={() => setShowGHAModal(true)}>
             <img src={swap} />
           </RefreshButton>}
           {showGHAModal && currentProject != null && (
@@ -72,7 +78,6 @@ const ProjectButton: React.FC<PropsType> = (props) => {
               closeModal={() => setShowGHAModal(false)}
             />
           )}
-          {/* <i className="material-icons">arrow_drop_down</i> */}
         </MainSelector>
         {/* {renderDropdown()} */}
       </StyledProjectSection >
@@ -126,48 +131,7 @@ const InitializeButton = styled.div`
   }
 `;
 
-const Option = styled.div`
-  width: 100%;
-  border-top: 1px solid #00000000;
-  border-bottom: 1px solid
-    ${(props: { selected: boolean; lastItem?: boolean }) =>
-    props.lastItem ? "#ffffff00" : "#ffffff15"};
-  height: 45px;
-  display: flex;
-  align-items: center;
-  font-size: 13px;
-  align-items: center;
-  padding-left: 10px;
-  cursor: pointer;
-  padding-right: 10px;
-  background: ${(props: { selected: boolean; lastItem?: boolean }) =>
-    props.selected ? "#ffffff11" : ""};
-  :hover {
-    background: ${(props: { selected: boolean; lastItem?: boolean }) =>
-    props.selected ? "" : "#ffffff22"};
-  }
 
-  > i {
-    font-size: 18px;
-    margin-right: 12px;
-    margin-left: 5px;
-    color: #ffffff44;
-  }
-`;
-
-const Dropdown = styled.div`
-  position: absolute;
-  right: 13px;
-  top: calc(100% + 5px);
-  background: #26282f;
-  width: 210px;
-  max-height: 500px;
-  border-radius: 3px;
-  z-index: 999;
-  overflow-y: auto;
-  margin-bottom: 10px;
-  box-shadow: 0 5px 15px 5px #00000077;
-`;
 
 const Letter = styled.div`
   height: 100%;
@@ -191,10 +155,10 @@ const ProjectIcon = styled.div`
   width: 25px;
   min-width: 25px;
   height: 25px;
-  border-radius: 3px;
+  border-radius: 2px;
   overflow: hidden;
   position: relative;
-  margin-right: 10px;
+  margin-right: 6px;
   font-weight: 400;
 `;
 const ProjectIconAlt = styled(ProjectIcon)`
@@ -206,18 +170,18 @@ const ProjectIconAlt = styled(ProjectIcon)`
 
 const StyledProjectSection = styled.div`
   position: relative;
-  margin-left: 3px;
+  margin-left: 2px;
   color: ${props => props.theme.text.primary};
 `;
 
-const MainSelector = styled.div`
+const MainSelector = styled.div<{ expanded: boolean, hasMultipleProjects: boolean }>`
   display: flex;
   align-items: center;
-  justify-content: space-between; // <-- Changed from center to space-between
+  justify-content: ${props => props.hasMultipleProjects ? 'space-between' : 'flex-start'};
   margin: 10px 0 0;
   font-size: 14px;
   cursor: pointer;
-  padding: 10px 20px; // <-- Add padding-right here
+  padding: 10px 20px;
   position: relative;
   :hover {
     > i {
@@ -233,17 +197,17 @@ const MainSelector = styled.div`
     align-items: center;
     justify-content: center;
     border-radius: 20px;
-    background: ${(props: { expanded: boolean }) =>
-    props.expanded ? "#ffffff22" : ""};
+    background: ${props => props.expanded ? "#ffffff22" : ""};
   }
 `;
 
-const ProjectName = styled.div`
+const ProjectName = styled.div<{ hasMultipleProjects: boolean }>`
   overflow: hidden;
   white-space: nowrap;
-  text-overflow: ellipsis;
-  flex-grow: 1; // <-- Add flex-grow here
-  padding-right: 20px; // <-- Add padding-right here
+  text-overflow: ${props => props.hasMultipleProjects ? 'ellipsis' : 'clip'};
+  flex-grow: ${props => props.hasMultipleProjects ? 1 : 0};
+  padding-right: ${props => props.hasMultipleProjects ? '1px' : '0'};
+  max-width: ${props => props.hasMultipleProjects ? 'auto' : '26ch'}; // Limit to max 25 characters when no multiple projects
 `;
 
 const RefreshButton = styled.div`
@@ -261,6 +225,6 @@ const RefreshButton = styled.div`
     display: flex;
     align-items: center;
     justify-content: center;
-    height: 15px;
+    height: 14px;
   }
 `;

+ 25 - 19
dashboard/src/main/home/sidebar/ProjectSelectionModal.tsx

@@ -133,29 +133,35 @@ const ProjectSelectionModal: React.FC<Props> = ({
     const totalProjects = projects.length;
     const totalPages = Math.ceil(totalProjects / projectsPerPage);
 
-    return (
-      <PaginationButtonsContainer>
-        <Button
-          disabled={currentPage === 1}
-          onClick={() => setCurrentPage((page) => Math.max(page - 1, 1))}
-        >
-          Previous
-        </Button>
-
-        <span>{currentPage} / {totalPages}</span>
+    // Only render pagination buttons if there are multiple pages
+    if (totalPages > 1) {
+      return (
+        <PaginationButtonsContainer>
+          <Button
+            disabled={currentPage === 1}
+            onClick={() => setCurrentPage((page) => Math.max(page - 1, 1))}
+          >
+            Previous
+          </Button>
+
+          <span>{currentPage} / {totalPages}</span>
+
+          <Button
+            disabled={currentPage === totalPages}
+            onClick={() => setCurrentPage((page) => Math.min(page + 1, totalPages))}
+          >
+            Next
+          </Button>
+        </PaginationButtonsContainer>
+      );
+    }
 
-        <Button
-          disabled={currentPage === totalPages}
-          onClick={() => setCurrentPage((page) => Math.min(page + 1, totalPages))}
-        >
-          Next
-        </Button>
-      </PaginationButtonsContainer>
-    );
+    // If there is only one page, don't render the buttons
+    return null;
   };
 
   return (
-    <Modal closeModal={closeModal} width="1000px">
+    <Modal closeModal={closeModal} width={'900px'}>
       <Text size={16} style={{ marginRight: '10px' }}>
         Switch Project
       </Text>

+ 0 - 17
dashboard/src/main/home/sidebar/Sidebar.tsx

@@ -186,12 +186,10 @@ class Sidebar extends Component<PropsType, StateType> {
               "delete",
             ]) && (
                 <NavButton path={"/project-settings"}
-                  style={{ marginLeft: '25px' }}
                 >
                   <Img src={settings} />
                   Project settings
                 </NavButton>
-
               )}
             {this.props.isAuthorized("integrations", "", [
               "get",
@@ -200,7 +198,6 @@ class Sidebar extends Component<PropsType, StateType> {
               "delete",
             ]) && (
                 <NavButton path={"/integrations"}
-                  style={{ marginLeft: '25px' }}
                 >
                   <Img src={integrations} />
                   Integrations
@@ -215,7 +212,6 @@ class Sidebar extends Component<PropsType, StateType> {
             <NavButton
               path="/apps"
               active={window.location.pathname.startsWith("/apps")}
-              style={{ marginLeft: '25px' }}
             >
               <Img src={web} />
               Applications
@@ -223,8 +219,6 @@ class Sidebar extends Component<PropsType, StateType> {
             <NavButton
               path="/addons"
               active={window.location.pathname.startsWith("/addons")}
-              style={{ marginLeft: '25px' }}
-
             >
               <Img src={addOns} />
               Add-ons
@@ -234,7 +228,6 @@ class Sidebar extends Component<PropsType, StateType> {
               active={
                 window.location.pathname.startsWith("/env-groups")
               }
-              style={{ marginLeft: '25px' }}
             >
               <Img src={sliders} />
 
@@ -245,10 +238,8 @@ class Sidebar extends Component<PropsType, StateType> {
               "update",
               "delete",
             ]) && (
-
                 <NavButton
                   path={"/cluster-dashboard"}
-                  style={{ marginLeft: '25px' }}
                   active={
                     window.location.pathname.startsWith("/cluster-dashboard")
                   }
@@ -276,7 +267,6 @@ class Sidebar extends Component<PropsType, StateType> {
             <NavButton
               path="/apps"
               active={window.location.pathname.startsWith("/apps")}
-              style={{ marginLeft: '25px' }}
             >
               <Img src={web} />
               Applications
@@ -284,8 +274,6 @@ class Sidebar extends Component<PropsType, StateType> {
             <NavButton
               path="/addons"
               active={window.location.pathname.startsWith("/addons")}
-              style={{ marginLeft: '25px' }}
-
             >
               <Img src={addOns} />
               Add-ons
@@ -295,10 +283,8 @@ class Sidebar extends Component<PropsType, StateType> {
               active={
                 window.location.pathname.startsWith("/env-groups")
               }
-              style={{ marginLeft: '25px' }}
             >
               <Img src={sliders} />
-
               Env groups
             </NavButton>}
             {this.props.isAuthorized("settings", "", [
@@ -309,7 +295,6 @@ class Sidebar extends Component<PropsType, StateType> {
 
                 <NavButton
                   path={"/cluster-dashboard"}
-                  style={{ marginLeft: '25px' }}
                   active={
                     window.location.pathname.startsWith("/cluster-dashboard")
                   }
@@ -326,7 +311,6 @@ class Sidebar extends Component<PropsType, StateType> {
               "delete",
             ]) && (
                 <NavButton path={"/integrations"}
-                  style={{ marginLeft: '25px' }}
                 >
                   <Img src={integrations} />
                   Integrations
@@ -339,7 +323,6 @@ class Sidebar extends Component<PropsType, StateType> {
               "delete",
             ]) && (
                 <NavButton path={"/project-settings"}
-                  style={{ marginLeft: '25px' }}
                 >
                   <Img src={settings} />
                   Project settings