Parcourir la source

namespace placeholder

Justin Rhee il y a 3 ans
Parent
commit
71d9bb8d6c

BIN
dashboard/src/assets/add-ons-bold.png


BIN
dashboard/src/assets/add-ons.png


BIN
dashboard/src/assets/integrations-bold.png


BIN
dashboard/src/assets/integrations.png


BIN
dashboard/src/assets/settings-bold.png


BIN
dashboard/src/assets/settings.png


+ 5 - 0
dashboard/src/components/porter/Container.tsx

@@ -4,16 +4,19 @@ import styled from "styled-components";
 type Props = {
   children: React.ReactNode;
   row?: boolean;
+  spaced?: boolean;
 };
 
 const Container: React.FC<Props> = ({
   children,
   row,
+  spaced,
 }) => {
   const [isExpanded, setIsExpanded] = useState(false);
 
   return (
     <StyledContainer
+      spaced={spaced}
       row={row}
     >
       {children}
@@ -25,7 +28,9 @@ export default Container;
 
 const StyledContainer = styled.div<{
   row: boolean;
+  spaced: boolean;
 }>`
   display: ${props => props.row ? "flex" : "block"};
   align-items: center;
+  justify-content: ${props => props.spaced ? "space-between" : "flex-start"};
 `;

+ 11 - 1
dashboard/src/main/home/Home.tsx

@@ -21,6 +21,7 @@ import Navbar from "./navbar/Navbar";
 import ProjectSettings from "./project-settings/ProjectSettings";
 import Sidebar from "./sidebar/Sidebar";
 import PageNotFound from "components/PageNotFound";
+import AppDashboard from "./app-dashboard/AppDashboard";
 
 import { fakeGuardedRoute } from "shared/auth/RouteGuard";
 import { withAuth, WithAuthProps } from "shared/auth/AuthorizationHoc";
@@ -346,7 +347,6 @@ const Home: React.FC<Props> = (props) => {
   };
 
   const { cluster, baseRoute } = props.match.params as any;
-  console.log(currentProject)
   return (
     <ThemeProvider theme={currentProject?.simplified_view_enabled ? midnight : standard}>
       <StyledHome>
@@ -384,6 +384,16 @@ const Home: React.FC<Props> = (props) => {
           />
 
           <Switch>
+            <Route
+              path="/apps"
+            >
+              <AppDashboard />
+            </Route>
+            <Route
+              path="/addons"
+            >
+              test
+            </Route>
             <Route
               path="/new-project"
               render={() => {

+ 82 - 0
dashboard/src/main/home/app-dashboard/AppDashboard.tsx

@@ -0,0 +1,82 @@
+import React, { useEffect, useState, useContext } from "react";
+import styled from "styled-components";
+
+import web from "assets/web.png";
+
+import { Context } from "shared/Context";
+import api from "shared/api";
+
+import DashboardHeader from "../cluster-dashboard/DashboardHeader";
+import Container from "components/porter/Container";
+import Button from "components/porter/Button";
+import Spacer from "components/porter/Spacer";
+
+type Props = {
+};
+
+const AppDashboard: React.FC<Props> = ({
+}) => {
+  const { currentProject, currentCluster } = useContext(Context);
+  const [apps, setApps] = useState([]);
+  const [isLoading, setIsLoading] = useState(true);
+
+  const getApps = async () => {
+    
+    // TODO: Currently using namespaces as placeholder (replace with apps)
+    try {
+      const res = await api.getNamespaces(
+        "<token>",
+        {},
+        {
+          id: currentProject.id,
+          cluster_id: currentCluster.id,
+        }
+      )
+      setApps(res.data);
+    }
+    catch (err) {}
+  };
+
+  useEffect(() => {
+    getApps();
+  }, []);
+
+  return (
+    <StyledAppDashboard>
+      <DashboardHeader
+        image={web}
+        title="Applications"
+        description="Continuously running web services, workers, and add-ons."
+        disableLineBreak
+      />
+      <Container row spaced>
+        <Button onClick={() => console.log("cool")} height="30px">
+          <I className="material-icons">add</I> Add application
+        </Button>
+        <div>x/o</div>
+      </Container>
+      <Spacer y={1} />
+      {apps.map((app: any) => {
+        return (
+          <div>{app.name}</div>
+        );
+      })}
+    </StyledAppDashboard>
+  );
+};
+
+export default AppDashboard;
+
+const I = styled.i`
+  color: white;
+  font-size: 14px;
+  display: flex;
+  align-items: center;
+  margin-right: 5px;
+  justify-content: center;
+`;
+
+const StyledAppDashboard = styled.div`
+  width: 100%;
+  height: 100%;
+`;

+ 1 - 1
dashboard/src/main/home/cluster-dashboard/apps/AppDashboard.tsx

@@ -61,7 +61,7 @@ const AppDashboard: React.FC<Props> = ({
                 currentView={currentView}
               />
               <Spacer inline width="10px" />
-              {!currentProject.capi_provisioner_enabled && (
+              {!currentProject?.capi_provisioner_enabled && (
                 <NamespaceSelector
                   setNamespace={(x) => {
                     setNamespace(x);

+ 4 - 4
dashboard/src/main/home/cluster-dashboard/dashboard/Dashboard.tsx

@@ -72,7 +72,7 @@ export const Dashboard: React.FunctionComponent = () => {
       context.currentCluster.status !== "UPDATING_UNAVAILABLE" &&
       !tabOptions.find((tab) => tab.value === "nodes")
     ) {  
-      if (!context.currentProject.capi_provisioner_enabled) {
+      if (!context.currentProject?.capi_provisioner_enabled) {
         tabOptions.unshift({ label: "Namespaces", value: "namespaces" });
       }
       tabOptions.unshift({ label: "Metrics", value: "metrics" });
@@ -80,7 +80,7 @@ export const Dashboard: React.FunctionComponent = () => {
     }
     
     if (
-      context.currentProject.capi_provisioner_enabled &&
+      context.currentProject?.capi_provisioner_enabled &&
       !tabOptions.find((tab) => tab.value === "configuration")
     ) {
       tabOptions.unshift({ value: "configuration", label: "Configuration" });
@@ -108,7 +108,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) {
+    if (context.currentProject?.capi_provisioner_enabled) {
       setCurrentTab("configuration");
     } else {
       setCurrentTab("nodes");
@@ -184,7 +184,7 @@ export const Dashboard: React.FunctionComponent = () => {
   }, []);
 
   const renderContents = () => {
-    if (context.currentProject.capi_provisioner_enabled) {
+    if (context.currentProject?.capi_provisioner_enabled) {
       return (
         <>
           <ClusterRevisionSelector

+ 2 - 2
dashboard/src/main/home/cluster-dashboard/env-groups/EnvGroupDashboard.tsx

@@ -107,7 +107,7 @@ const EnvGroupDashboard = (props: PropsType) => {
                 sortType={state.sortType}
               />
               <Spacer inline width="10px" />
-              {!currentProject.capi_provisioner_enabled && (
+              {!currentProject?.capi_provisioner_enabled && (
                 <NamespaceSelector
                   setNamespace={setNamespace}
                   namespace={state.namespace}
@@ -125,7 +125,7 @@ const EnvGroupDashboard = (props: PropsType) => {
 
           <EnvGroupList
             currentCluster={props.currentCluster}
-            namespace={currentProject.capi_provisioner_enabled ? "default" : state.namespace}
+            namespace={currentProject?.capi_provisioner_enabled ? "default" : state.namespace}
             sortType={state.sortType}
             setExpandedEnvGroup={setExpandedEnvGroup}
           />

+ 2 - 2
dashboard/src/main/home/cluster-dashboard/jobs/JobDashboard.tsx

@@ -59,7 +59,7 @@ const JobDashboard: React.FC<Props> = ({
                 lastRunStatus={lastRunStatus}
                 setLastRunStatus={setLastRunStatus}
               />
-              {!currentProject.capi_provisioner_enabled && (
+              {!currentProject?.capi_provisioner_enabled && (
                 <NamespaceSelector
                   setNamespace={(x) => {
                     setNamespace(x);
@@ -117,7 +117,7 @@ const JobDashboard: React.FC<Props> = ({
               currentView={currentView}
               currentCluster={currentCluster}
               lastRunStatus={lastRunStatus}
-              namespace={currentProject.capi_provisioner_enabled ? "default" : namespace}
+              namespace={currentProject?.capi_provisioner_enabled ? "default" : namespace}
               sortType={sortType}
               selectedTag={selectedTag}
             />

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

@@ -194,7 +194,7 @@ class Dashboard extends Component<PropsType, StateType> {
                   </Description>
                 </InfoSection>
                 {
-                  currentProject.capi_provisioner_enabled ? (
+                  currentProject?.capi_provisioner_enabled ? (
                     <ClusterSection />
                   ) : (
                     <TabRegion

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

@@ -4,7 +4,7 @@ import { Route, RouteComponentProps, Switch, withRouter } from "react-router";
 import { integrationList } from "shared/common";
 import styled from "styled-components";
 import { pushFiltered } from "shared/routing";
-import integrations from "assets/integrations.svg";
+import integrations from "assets/integrations.png";
 
 import CreateIntegrationForm from "./create-integration/CreateIntegrationForm";
 import IntegrationCategories from "./IntegrationCategories";

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

@@ -14,7 +14,6 @@ import TitleSection from "components/TitleSection";
 import ClusterProvisioningPlaceholder from "components/ClusterProvisioningPlaceholder";
 import DashboardHeader from "../cluster-dashboard/DashboardHeader";
 
-import rocket from "assets/rocket.png";
 import semver from "semver";
 import { RouteComponentProps, withRouter } from "react-router";
 import { getQueryParam, getQueryParams, pushFiltered } from "shared/routing";

+ 1 - 1
dashboard/src/main/home/launch/launch-flow/SettingsPage.tsx

@@ -248,7 +248,7 @@ class SettingsPage extends Component<PropsType, StateType> {
         <StyledSettingsPage>
           {this.renderHeaderSection()}
           {this.props.isCloning && this.getNameInput()}
-          {!currentProject.capi_provisioner_enabled && (
+          {!currentProject?.capi_provisioner_enabled && (
             <>
               <Heading>Destination</Heading>
               <Helper>

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

@@ -2,7 +2,7 @@ import React, { Component } from "react";
 import styled from "styled-components";
 
 import { Context } from "shared/Context";
-import settings from "assets/settings-centered.svg";
+import settings from "assets/settings.png";
 
 import InvitePage from "./InviteList";
 import TabRegion from "components/TabRegion";

+ 10 - 5
dashboard/src/main/home/sidebar/Clusters.tsx

@@ -20,6 +20,7 @@ type PropsType = RouteComponentProps & {
   currentView: string;
   isSelected: boolean;
   forceRefreshClusters: boolean;
+  display?: string;
   setRefreshClusters: (x: boolean) => void;
 };
 
@@ -47,7 +48,7 @@ class Clusters extends Component<PropsType, StateType> {
 
     // TODO: query with selected filter once implemented
     api
-      .getClusters("<token>", {}, { id: currentProject.id })
+      .getClusters("<token>", {}, { id: currentProject?.id })
       .then((res) => {
         window.analytics?.identify(user.userId, {
           currentProject,
@@ -82,7 +83,7 @@ class Clusters extends Component<PropsType, StateType> {
 
             this.setState({ clusters });
             let saved = JSON.parse(
-              localStorage.getItem(currentProject.id + "-cluster")
+              localStorage.getItem(currentProject?.id + "-cluster")
             );
             if (!defaultCluster && saved && saved !== "null") {
               // Ensures currentCluster isn't prematurely set (causes issues downstream)
@@ -146,7 +147,7 @@ class Clusters extends Component<PropsType, StateType> {
     if (
       clusters.length > 0 &&
       currentCluster &&
-      !currentProject.capi_provisioner_enabled
+      !currentProject?.capi_provisioner_enabled
     ) {
       clusters.sort((a, b) => a.id - b.id);
 
@@ -168,7 +169,7 @@ class Clusters extends Component<PropsType, StateType> {
           />
         );
       });
-    } else if (currentProject.capi_provisioner_enabled) {
+    } else if (currentProject?.capi_provisioner_enabled) {
       const cluster = clusters[0];
       return (
         <>
@@ -252,7 +253,7 @@ class Clusters extends Component<PropsType, StateType> {
   };
 
   render() {
-    return <>{this.renderContents()}</>;
+    return <Wrapper display={this.props.display}>{this.renderContents()}</Wrapper>;
   }
 }
 
@@ -260,6 +261,10 @@ Clusters.contextType = Context;
 
 export default withRouter(Clusters);
 
+const Wrapper = styled.div<{ display: string }>`
+  display: ${props => props.display || ""};
+`;
+
 const InlineSVGWrapper = styled.svg`
   width: 32px;
   height: 32px;

+ 63 - 6
dashboard/src/main/home/sidebar/Sidebar.tsx

@@ -1,9 +1,11 @@
 import React, { Component } from "react";
 import styled from "styled-components";
 import category from "assets/category.svg";
-import integrations from "assets/integrations.svg";
+import integrations from "assets/integrations-bold.png";
 import rocket from "assets/rocket.png";
-import settings from "assets/settings.svg";
+import settings from "assets/settings-bold.png";
+import web from "assets/web-bold.png";
+import addOns from "assets/add-ons-bold.png";
 
 import { Context } from "shared/Context";
 
@@ -103,7 +105,7 @@ class Sidebar extends Component<PropsType, StateType> {
   renderProjectContents = () => {
     let { currentView } = this.props;
     let { currentProject, user, currentCluster, hasFinishedOnboarding } = this.context;
-    if (currentProject) {
+    if (!currentProject?.simplified_view_enabled) {
       return (
         <ScrollWrapper>
           <SidebarLabel>Home</SidebarLabel>
@@ -141,7 +143,7 @@ class Sidebar extends Component<PropsType, StateType> {
             "delete",
           ]) && (
             <NavButton path={"/project-settings"}>
-              <Img enlarge={true} src={settings} />
+              <Img src={settings} />
               Project settings
             </NavButton>
           )}
@@ -149,7 +151,7 @@ class Sidebar extends Component<PropsType, StateType> {
           <br />
 
           <SidebarLabel>
-            {currentProject.capi_provisioner_enabled ? (
+            {currentProject?.capi_provisioner_enabled ? (
               "Your team"
             ) : (
               "Clusters"
@@ -164,6 +166,56 @@ class Sidebar extends Component<PropsType, StateType> {
           />
         </ScrollWrapper>
       );
+    } else if (currentProject.simplified_view_enabled) {
+      return (
+        <ScrollWrapper>
+          <NavButton
+            path="/apps"
+            active={window.location.pathname.startsWith("/apps")}
+          >
+            <Img src={web} />
+            Applications
+          </NavButton>
+          <NavButton
+            path="/addons"
+            active={window.location.pathname.startsWith("/addons")}
+          >
+            <Img src={addOns} />
+            Add-ons
+          </NavButton>
+          {this.props.isAuthorized("integrations", "", [
+            "get",
+            "create",
+            "update",
+            "delete",
+          ]) && (
+            <NavButton path={"/integrations"}>
+              <Img src={integrations} />
+              Integrations
+            </NavButton>
+          )}
+          {this.props.isAuthorized("settings", "", [
+            "get",
+            "update",
+            "delete",
+          ]) && (
+            <NavButton path={"/project-settings"}>
+              <Img src={settings} />
+              Project settings
+            </NavButton>
+          )}
+
+          {/* Hacky workaround for setting currentCluster with legacy method */}
+          <Clusters
+            display="none"
+            setWelcome={this.props.setWelcome}
+            currentView={currentView}
+            isSelected={false}
+            forceRefreshClusters={this.props.forceRefreshClusters}
+            setRefreshClusters={this.props.setRefreshClusters}
+          />
+        </ScrollWrapper>
+      );
     }
 
     // Render placeholder if no project exists
@@ -245,6 +297,12 @@ const NavButton = styled(SidebarLink)`
   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;
 
@@ -268,7 +326,6 @@ const NavButton = styled(SidebarLink)`
 const Img = styled.img<{ enlarge?: boolean }>`
   padding: ${(props) => (props.enlarge ? "0 0 0 1px" : "4px")};
   height: 22px;
-  width: 22px;
   padding-top: 4px;
   border-radius: 3px;
   margin-right: 8px;

+ 4 - 0
dashboard/src/shared/routing.tsx

@@ -14,6 +14,8 @@ export type PorterUrl =
   | "onboarding"
   | "databases"
   | "preview-environments"
+  | "apps"
+  | "addons"
   | "stacks";
 
 export const PorterUrls = [
@@ -30,6 +32,8 @@ export const PorterUrls = [
   "onboarding",
   "databases",
   "preview-environments",
+  "apps",
+  "addons",
   "stacks",
 ];