Explorar el Código

allow for routing to different tabs (#3193)

Feroze Mohideen hace 2 años
padre
commit
ac66bb44a5

+ 18 - 12
dashboard/src/main/home/Home.tsx

@@ -192,7 +192,7 @@ const Home: React.FC<Props> = (props) => {
       } else {
         setHasFinishedOnboarding(true);
       }
-    } catch (error) {}
+    } catch (error) { }
   };
 
   useEffect(() => {
@@ -407,6 +407,12 @@ const Home: React.FC<Props> = (props) => {
             <Route path="/apps/new/app">
               <NewAppFlow />
             </Route>
+            <Route path="/apps/:appName/events/:eventId">
+              <ExpandedApp />
+            </Route>
+            <Route path="/apps/:appName/:tab">
+              <ExpandedApp />
+            </Route>
             <Route path="/apps/:appName">
               <ExpandedApp />
             </Route>
@@ -435,17 +441,17 @@ const Home: React.FC<Props> = (props) => {
               overrideInfraTabEnabled({
                 projectID: currentProject?.id,
               })) && (
-              <Route
-                path="/infrastructure"
-                render={() => {
-                  return (
-                    <DashboardWrapper>
-                      <InfrastructureRouter />
-                    </DashboardWrapper>
-                  );
-                }}
-              />
-            )}
+                <Route
+                  path="/infrastructure"
+                  render={() => {
+                    return (
+                      <DashboardWrapper>
+                        <InfrastructureRouter />
+                      </DashboardWrapper>
+                    );
+                  }}
+                />
+              )}
             <Route
               path="/dashboard"
               render={() => {

+ 57 - 73
dashboard/src/main/home/app-dashboard/expanded-app/ExpandedApp.tsx

@@ -1,5 +1,5 @@
 import React, { useEffect, useState, useContext, useCallback } from "react";
-import { RouteComponentProps, withRouter } from "react-router";
+import { RouteComponentProps, useParams, withRouter } from "react-router";
 import styled from "styled-components";
 import yaml from "js-yaml";
 
@@ -62,6 +62,23 @@ const icons = [
   web,
 ];
 
+const validTabs = [
+  "activity",
+  "overview",
+  "logs",
+  "metrics",
+  "debug",
+  "environment",
+  "build-settings",
+  "settings",
+] as const;
+const DEFAULT_TAB = "activity";
+type ValidTab = typeof validTabs[number];
+interface Params {
+  eventId?: string;
+  tab?: ValidTab;
+}
+
 const ExpandedApp: React.FC<Props> = ({ ...props }) => {
   const {
     currentCluster,
@@ -82,7 +99,6 @@ const ExpandedApp: React.FC<Props> = ({ ...props }) => {
     false
   );
 
-  const [tab, setTab] = useState("activity");
   const [saveValuesStatus, setSaveValueStatus] = useState<string>("");
   const [loading, setLoading] = useState<boolean>(false);
   const [bannerLoading, setBannerLoading] = useState<boolean>(false);
@@ -98,7 +114,6 @@ const ExpandedApp: React.FC<Props> = ({ ...props }) => {
 
   const [expandedJob, setExpandedJob] = useState(null);
   const [logs, setLogs] = useState<Log[]>([]);
-  const [modalVisible, setModalVisible] = useState(false);
 
   const [services, setServices] = useState<Service[]>([]);
   const [envVars, setEnvVars] = useState<KeyValueType[]>([]);
@@ -109,6 +124,32 @@ const ExpandedApp: React.FC<Props> = ({ ...props }) => {
   // this is the version of the porterApp that is being edited. on save, we set the real porter app to be this version
   const [tempPorterApp, setTempPorterApp] = useState<PorterApp>();
 
+  const { eventId, tab } = useParams<Params>();
+  const selectedTab: ValidTab = tab != null && validTabs.includes(tab) ? tab : DEFAULT_TAB;
+
+  useEffect(() => {
+    setBannerLoading(true);
+    getBuildLogs().then(() => {
+      setBannerLoading(false);
+    });
+  }, [appData]);
+
+  useEffect(() => {
+    if (!_.isEqual(_.omitBy(porterApp, _.isEmpty), _.omitBy(tempPorterApp, _.isEmpty))) {
+      setButtonStatus("");
+      setShowUnsavedChangesBanner(true);
+    } else {
+      setShowUnsavedChangesBanner(false);
+    }
+  }, [tempPorterApp, porterApp]);
+
+  useEffect(() => {
+    const { appName } = props.match.params as any;
+    if (currentCluster && appName && currentProject) {
+      getPorterApp();
+    }
+  }, [currentCluster]);
+
   // this method fetches and reconstructs the porter yaml as well as the DB info (stored in PorterApp)
   const getPorterApp = async () => {
     setBannerLoading(true);
@@ -331,22 +372,6 @@ const ExpandedApp: React.FC<Props> = ({ ...props }) => {
     }
   };
 
-  useEffect(() => {
-    setBannerLoading(true);
-    getBuildLogs().then(() => {
-      setBannerLoading(false);
-    });
-  }, [appData]);
-
-  useEffect(() => {
-    if (!_.isEqual(_.omitBy(porterApp, _.isEmpty), _.omitBy(tempPorterApp, _.isEmpty))) {
-      setButtonStatus("");
-      setShowUnsavedChangesBanner(true);
-    } else {
-      setShowUnsavedChangesBanner(false);
-    }
-  }, [tempPorterApp, porterApp]);
-
   const getBuildLogs = async () => {
     try {
       const res = await api.getGHWorkflowLogs(
@@ -635,13 +660,6 @@ const ExpandedApp: React.FC<Props> = ({ ...props }) => {
     [appData?.chart]
   );
 
-  useEffect(() => {
-    const { appName } = props.match.params as any;
-    if (currentCluster && appName && currentProject) {
-      getPorterApp();
-    }
-  }, [currentCluster]);
-
   const getReadableDate = (s: string) => {
     const ts = new Date(s);
     const date = ts.toLocaleDateString();
@@ -669,7 +687,7 @@ const ExpandedApp: React.FC<Props> = ({ ...props }) => {
   };
 
   const renderTabContents = () => {
-    switch (tab) {
+    switch (selectedTab) {
       case "overview":
         return (
           <>
@@ -766,23 +784,13 @@ const ExpandedApp: React.FC<Props> = ({ ...props }) => {
             </Button>
           </>
         );
-      case "events":
-        return <EventsTab currentChart={appData.chart} />;
-      case "activity":
-        return (
-          <ActivityFeed
-            chart={appData.chart}
-            stackName={appData?.app?.name}
-            appData={appData}
-          />
-        );
       case "logs":
         return <LogSection currentChart={appData.chart} services={services} />;
       case "metrics":
         return <MetricsSection currentChart={appData.chart} />;
-      case "status":
+      case "debug":
         return <StatusSectionFC currentChart={appData.chart} />;
-      case "environment-variables":
+      case "environment":
         return (
           <EnvVariablesTab
             envVars={envVars}
@@ -795,37 +803,13 @@ const ExpandedApp: React.FC<Props> = ({ ...props }) => {
             clearStatus={() => setButtonStatus("")}
           />
         );
-      case "pre-deploy":
-        return (
-          <>
-            {!isLoading && !services.some(Service.isRelease) && (
-              <>
-                <Fieldset>
-                  <Container row>
-                    <PlaceholderIcon src={notFound} />
-                    <Text color="helper">
-                      No pre-deploy jobs were found. You can add a pre-deploy
-                      job in the Overview tab to perform an operation before
-                      your application services deploy, like a database
-                      migration.
-                    </Text>
-                  </Container>
-                </Fieldset>
-                <Spacer y={0.5} />
-              </>
-            )}
-            {services.some(Service.isRelease) && (
-              <JobRuns
-                lastRunStatus="all"
-                namespace={appData.chart?.namespace}
-                sortType="Newest"
-                releaseName={appData.app.name + "-r"}
-              />
-            )}
-          </>
-        );
       default:
-        return <div>Tab not found</div>;
+        return <ActivityFeed
+          chart={appData.chart}
+          stackName={appData?.app?.name}
+          appData={appData}
+          eventId={eventId}
+        />;
     }
   };
 
@@ -1029,10 +1013,10 @@ const ExpandedApp: React.FC<Props> = ({ ...props }) => {
                   { label: "Overview", value: "overview" },
                   hasBuiltImage && { label: "Logs", value: "logs" },
                   hasBuiltImage && { label: "Metrics", value: "metrics" },
-                  hasBuiltImage && { label: "Debug", value: "status" },
+                  hasBuiltImage && { label: "Debug", value: "debug" },
                   {
                     label: "Environment",
-                    value: "environment-variables",
+                    value: "environment",
                   },
                   appData.app.git_repo_id && {
                     label: "Build settings",
@@ -1040,12 +1024,12 @@ const ExpandedApp: React.FC<Props> = ({ ...props }) => {
                   },
                   { label: "Settings", value: "settings" },
                 ].filter((x) => x)}
-                currentTab={tab}
+                currentTab={selectedTab}
                 setCurrentTab={(tab: string) => {
                   if (buttonStatus !== "") {
                     setButtonStatus("");
                   }
-                  setTab(tab);
+                  props.history.push(`/apps/${appData.app.name}/${tab}`);
                 }}
               />
               <Spacer y={1} />

+ 11 - 2
dashboard/src/main/home/app-dashboard/expanded-app/activity-feed/ActivityFeed.tsx

@@ -23,10 +23,11 @@ import Container from "components/porter/Container";
 type Props = {
   chart: any;
   stackName: string;
-  appData: string;
+  appData: any;
+  eventId?: string;
 };
 
-const ActivityFeed: React.FC<Props> = ({ chart, stackName, appData }) => {
+const ActivityFeed: React.FC<Props> = ({ chart, stackName, appData, eventId }) => {
   const { currentProject, currentCluster } = useContext(Context);
 
   const [events, setEvents] = useState<any[]>([]);
@@ -138,6 +139,14 @@ const ActivityFeed: React.FC<Props> = ({ chart, stackName, appData }) => {
     );
   }
 
+  if (eventId != null) {
+    return (
+      <StyledActivityFeed>
+        {eventId}
+      </StyledActivityFeed>
+    )
+  }
+
   if (!hasPorterAgent) {
     return (
       <Fieldset>

+ 4 - 9
dashboard/src/main/home/app-dashboard/expanded-app/activity-feed/events/BuildEventCard.tsx

@@ -1,7 +1,6 @@
-import React, { useEffect, useState } from "react";
+import React, { useState } from "react";
 import styled from "styled-components";
 
-import app_event from "assets/app_event.png";
 import build from "assets/build.png";
 
 import run_for from "assets/run_for.png";
@@ -12,13 +11,12 @@ import Container from "components/porter/Container";
 import Spacer from "components/porter/Spacer";
 import Link from "components/porter/Link";
 import Icon from "components/porter/Icon";
-import Modal from "components/porter/Modal";
 import api from "shared/api";
 import { Log } from "main/home/cluster-dashboard/expanded-chart/logs-section/useAgentLogs";
 import JSZip from "jszip";
 import Anser, { AnserJsonEntry } from "anser";
 import GHALogsModal from "../../status/GHALogsModal";
-import { PorterAppEvent, PorterAppEventType } from "shared/types";
+import { PorterAppEvent } from "shared/types";
 import { getDuration, getStatusIcon, triggerWorkflow } from './utils';
 import { StyledEventCard } from "./EventCard";
 
@@ -28,8 +26,6 @@ type Props = {
 };
 
 const BuildEventCard: React.FC<Props> = ({ event, appData }) => {
-  const [showModal, setShowModal] = useState<boolean>(false);
-  const [modalContent, setModalContent] = useState<React.ReactNode>(null);
   const [logModalVisible, setLogModalVisible] = useState(false);
   const [logs, setLogs] = useState<Log[]>([]);
 
@@ -203,11 +199,10 @@ const BuildEventCard: React.FC<Props> = ({ event, appData }) => {
           {renderStatusText(event)}
           <Spacer inline x={1} />
           {renderInfoCta(event)}
+          <Spacer inline x={1} />
+          {/* <Link to={`/apps/${appData.app.name}/events/${event.id}`} hasunderline>View event</Link> */}
         </Container>
       </Container>
-      {showModal && (
-        <Modal closeModal={() => setShowModal(false)}>{modalContent}</Modal>
-      )}
     </StyledEventCard>
   );
 };