2
0
Эх сурвалжийг харах

Revert "add extra helper context wrapper for getting project and clus… (#3954)

ianedwards 2 жил өмнө
parent
commit
86e9cebb74

+ 0 - 51
dashboard/src/main/auth/context.tsx

@@ -1,51 +0,0 @@
-import React, { createContext, useContext } from "react";
-
-import Loading from "components/Loading";
-
-import { type ClusterType, type ProjectType } from "shared/types";
-
-type PorterUser = {
-  userId: number;
-  email: string;
-  isPorterUser: boolean;
-};
-
-type AuthContextType = {
-  currentProject: ProjectType;
-  currentCluster: ClusterType;
-  user: PorterUser;
-};
-
-export const AuthStateContext = createContext<AuthContextType | null>(null);
-
-export const useAuthState = (): AuthContextType => {
-  const context = useContext(AuthStateContext);
-  if (context === null) {
-    throw new Error("useAuthState must be used within a AuthStateProvider");
-  }
-  return context;
-};
-
-type AuthStateProviderProps = {
-  children: JSX.Element;
-  currentProject?: ProjectType;
-  currentCluster?: ClusterType;
-  user?: PorterUser;
-};
-
-export const AuthStateProvider: React.FC<AuthStateProviderProps> = ({
-  children,
-  currentProject,
-  currentCluster,
-  user,
-}) => {
-  if (!currentProject || !currentCluster || !user) {
-    return <Loading />;
-  }
-
-  return (
-    <AuthStateContext.Provider value={{ currentProject, currentCluster, user }}>
-      {children}
-    </AuthStateContext.Provider>
-  );
-};

+ 267 - 291
dashboard/src/main/home/Home.tsx

@@ -1,62 +1,53 @@
-import React, { useContext, useEffect, useRef, useState } from "react";
-import { createPortal } from "react-dom";
-import {
-  Route,
-  Switch,
-  withRouter,
-  type RouteComponentProps,
-} from "react-router";
+import React, { useEffect, useState, useContext, useRef } from "react";
+import { Route, RouteComponentProps, Switch, withRouter } from "react-router";
 import styled, { ThemeProvider } from "styled-components";
-
-import ConfirmOverlay from "components/ConfirmOverlay";
-import Loading from "components/Loading";
-import NoClusterPlaceHolder from "components/NoClusterPlaceHolder";
-import Button from "components/porter/Button";
-import Modal from "components/porter/Modal";
-import Spacer from "components/porter/Spacer";
-import Text from "components/porter/Text";
-import { AuthStateProvider } from "main/auth/context";
+import { createPortal } from "react-dom";
 
 import api from "shared/api";
-import { withAuth, type WithAuthProps } from "shared/auth/AuthorizationHoc";
-import { fakeGuardedRoute } from "shared/auth/RouteGuard";
-import ClusterResourcesProvider from "shared/ClusterResourcesContext";
-import { Context } from "shared/Context";
-import DeploymentTargetProvider from "shared/DeploymentTargetContext";
-import { pushFiltered, pushQueryParams, type PorterUrl } from "shared/routing";
 import midnight from "shared/themes/midnight";
 import standard from "shared/themes/standard";
-import {
-  type ClusterType,
-  type ProjectListType,
-  type ProjectType,
-} from "shared/types";
-import { overrideInfraTabEnabled } from "utils/infrastructure";
+import { Context } from "shared/Context";
+import { PorterUrl, pushFiltered, pushQueryParams } from "shared/routing";
+import { ClusterType, ProjectType, ProjectListType } from "shared/types";
 
-import discordLogo from "../../assets/discord.svg";
-import AddOnDashboard from "./add-on-dashboard/AddOnDashboard";
-import NewAddOnFlow from "./add-on-dashboard/NewAddOnFlow";
-import AppView from "./app-dashboard/app-view/AppView";
-import AppDashboard from "./app-dashboard/AppDashboard";
-import Apps from "./app-dashboard/apps/Apps";
-import CreateApp from "./app-dashboard/create-app/CreateApp";
-import ExpandedApp from "./app-dashboard/expanded-app/ExpandedApp";
-import NewAppFlow from "./app-dashboard/new-app-flow/NewAppFlow";
+import ConfirmOverlay from "components/ConfirmOverlay";
+import Loading from "components/Loading";
 import DashboardRouter from "./cluster-dashboard/DashboardRouter";
-import PreviewEnvs from "./cluster-dashboard/preview-environments/v2/PreviewEnvs";
-import SetupApp from "./cluster-dashboard/preview-environments/v2/setup-app/SetupApp";
 import Dashboard from "./dashboard/Dashboard";
-import CreateDatabase from "./database-dashboard/CreateDatabase";
-import DatabaseDashboard from "./database-dashboard/DatabaseDashboard";
-import InfrastructureRouter from "./infrastructure/InfrastructureRouter";
 import Integrations from "./integrations/Integrations";
 import LaunchWrapper from "./launch/LaunchWrapper";
-import ModalHandler from "./ModalHandler";
+
 import Navbar from "./navbar/Navbar";
-import { NewProjectFC } from "./new-project/NewProject";
-import Onboarding from "./onboarding/Onboarding";
 import ProjectSettings from "./project-settings/ProjectSettings";
 import Sidebar from "./sidebar/Sidebar";
+import AppDashboard from "./app-dashboard/AppDashboard";
+import AddOnDashboard from "./add-on-dashboard/AddOnDashboard";
+import DatabaseDashboard from "./database-dashboard/DatabaseDashboard";
+import CreateDatabase from "./database-dashboard/CreateDatabase";
+
+import { fakeGuardedRoute } from "shared/auth/RouteGuard";
+import { withAuth, WithAuthProps } from "shared/auth/AuthorizationHoc";
+import discordLogo from "../../assets/discord.svg";
+import Onboarding from "./onboarding/Onboarding";
+import ModalHandler from "./ModalHandler";
+import { NewProjectFC } from "./new-project/NewProject";
+import InfrastructureRouter from "./infrastructure/InfrastructureRouter";
+import { overrideInfraTabEnabled } from "utils/infrastructure";
+import NoClusterPlaceHolder from "components/NoClusterPlaceHolder";
+import NewAddOnFlow from "./add-on-dashboard/NewAddOnFlow";
+import Modal from "components/porter/Modal";
+import Text from "components/porter/Text";
+import Spacer from "components/porter/Spacer";
+import Button from "components/porter/Button";
+import NewAppFlow from "./app-dashboard/new-app-flow/NewAppFlow";
+import ExpandedApp from "./app-dashboard/expanded-app/ExpandedApp";
+import CreateApp from "./app-dashboard/create-app/CreateApp";
+import AppView from "./app-dashboard/app-view/AppView";
+import Apps from "./app-dashboard/apps/Apps";
+import DeploymentTargetProvider from "shared/DeploymentTargetContext";
+import PreviewEnvs from "./cluster-dashboard/preview-environments/v2/PreviewEnvs";
+import SetupApp from "./cluster-dashboard/preview-environments/v2/setup-app/SetupApp";
+import ClusterResourcesProvider from "shared/ClusterResourcesContext";
 
 // Guarded components
 const GuardedProjectSettings = fakeGuardedRoute("settings", "", [
@@ -132,10 +123,10 @@ const Home: React.FC<Props> = (props) => {
   };
 
   const getProjects = async (id?: number) => {
-    const { currentProject } = props;
-    const queryString = window.location.search;
-    const urlParams = new URLSearchParams(queryString);
-    const projectId = urlParams.get("project_id");
+    let { currentProject } = props;
+    let queryString = window.location.search;
+    let urlParams = new URLSearchParams(queryString);
+    let projectId = urlParams.get("project_id");
     if (!projectId && currentProject?.id) {
       pushQueryParams(props, { project_id: currentProject.id.toString() });
     }
@@ -163,7 +154,7 @@ const Home: React.FC<Props> = (props) => {
         }
 
         const project = await api
-          .getProject("<token>", {}, { id })
+          .getProject("<token>", {}, { id: id })
           .then((res) => res.data as ProjectType);
 
         setCurrentProject(project);
@@ -213,18 +204,18 @@ const Home: React.FC<Props> = (props) => {
   useEffect(() => {
     checkOnboarding();
     checkIfCanCreateProject();
-    const { match } = props;
+    let { match } = props;
 
     // Handle redirect from DO
-    const queryString = window.location.search;
-    const urlParams = new URLSearchParams(queryString);
+    let queryString = window.location.search;
+    let urlParams = new URLSearchParams(queryString);
 
-    const err = urlParams.get("error");
+    let err = urlParams.get("error");
     if (err) {
       setCurrentError(err);
     }
 
-    const defaultProjectId = parseInt(urlParams.get("project_id"));
+    let defaultProjectId = parseInt(urlParams.get("project_id"));
 
     setGhRedirect(urlParams.get("gh_oauth") !== null);
     urlParams.delete("gh_oauth");
@@ -297,9 +288,9 @@ const Home: React.FC<Props> = (props) => {
   }, [props.currentProject?.id]);
 
   useEffect(() => {
-    const queryString = window.location.search;
-    const urlParams = new URLSearchParams(queryString);
-    const err = urlParams.get("error");
+    let queryString = window.location.search;
+    let urlParams = new URLSearchParams(queryString);
+    let err = urlParams.get("error");
     if (
       !hasFinishedOnboarding &&
       props.history.location.pathname &&
@@ -335,9 +326,7 @@ const Home: React.FC<Props> = (props) => {
 
       setProjects(projectList);
       if (!projectList.length) {
-        setCurrentProject(null, () => {
-          redirectToNewProject();
-        });
+        setCurrentProject(null, () => redirectToNewProject());
       } else {
         const project = await api
           .getProject("<token>", {}, { id: projectList[0].id })
@@ -371,18 +360,18 @@ const Home: React.FC<Props> = (props) => {
 
     try {
       const res = await api.getClusters<
-        Array<{
+        {
           infra_id?: number;
           name: string;
-        }>
+        }[]
       >("<token>", {}, { id: currentProject?.id });
 
-      const destroyInfraPromises = res.data.map(async (cluster) => {
+      const destroyInfraPromises = res.data.map((cluster) => {
         if (!cluster.infra_id) {
           return undefined;
         }
 
-        return await api.destroyInfra(
+        return api.destroyInfra(
           "<token>",
           {},
           { project_id: currentProject.id, infra_id: cluster.infra_id }
@@ -399,244 +388,233 @@ const Home: React.FC<Props> = (props) => {
 
   const { cluster, baseRoute } = props.match.params as any;
   return (
-    <AuthStateProvider
-    user={user}
-      currentCluster={currentCluster}
-      currentProject={currentProject}
+    <ThemeProvider
+      theme={currentProject?.simplified_view_enabled ? midnight : standard}
     >
-      <ThemeProvider
-        theme={currentProject?.simplified_view_enabled ? midnight : standard}
-      >
-        <ClusterResourcesProvider>
-          <DeploymentTargetProvider>
-            <StyledHome>
-              <ModalHandler setRefreshClusters={setForceRefreshClusters} />
-              {currentOverlay &&
-                createPortal(
-                  <ConfirmOverlay
-                    show={true}
-                    message={currentOverlay.message}
-                    onYes={currentOverlay.onYes}
-                    onNo={currentOverlay.onNo}
-                  />,
-                  document.body
-                )}
-              {/* Render sidebar when there's at least one project */}
-              {projects?.length > 0 && baseRoute !== "new-project" ? (
-                <Sidebar
-                  key="sidebar"
-                  forceSidebar={forceSidebar}
-                  setWelcome={setShowWelcome}
-                  currentView={props.currentRoute}
-                  forceRefreshClusters={forceRefreshClusters}
-                  setRefreshClusters={setForceRefreshClusters}
-                />
-              ) : (
-                <DiscordButton
-                  href="https://discord.gg/34n7NN7FJ7"
-                  target="_blank"
-                >
-                  <Icon src={discordLogo} />
-                  Join Our Discord
-                </DiscordButton>
+      <ClusterResourcesProvider>
+        <DeploymentTargetProvider>
+          <StyledHome>
+            <ModalHandler setRefreshClusters={setForceRefreshClusters} />
+            {currentOverlay &&
+              createPortal(
+                <ConfirmOverlay
+                  show={true}
+                  message={currentOverlay.message}
+                  onYes={currentOverlay.onYes}
+                  onNo={currentOverlay.onNo}
+                />,
+                document.body
               )}
-              <ViewWrapper id="HomeViewWrapper">
-                <Navbar
-                  logOut={props.logOut}
-                  currentView={props.currentRoute} // For form feedback
-                />
-
-                <Switch>
-                  <Route path="/apps/new/app">
-                    {currentProject?.validate_apply_v2 ? (
-                      <CreateApp />
-                    ) : (
-                      <NewAppFlow />
-                    )}
-                  </Route>
-                  <Route path="/apps/:appName/:tab">
-                    {currentProject?.validate_apply_v2 ? (
-                      <AppView />
-                    ) : (
-                      <ExpandedApp />
-                    )}
-                  </Route>
-                  <Route path="/apps/:appName">
-                    {currentProject?.validate_apply_v2 ? (
-                      <AppView />
-                    ) : (
-                      <ExpandedApp />
-                    )}
-                  </Route>
-                  <Route path="/apps">
-                    {currentProject?.validate_apply_v2 ? (
-                      <Apps />
-                    ) : (
-                      <AppDashboard />
-                    )}
-                  </Route>
-
-                  <Route path="/databases/new">
-                    <CreateDatabase />
-                  </Route>
-                  <Route path="/databases">
-                    <DatabaseDashboard />
-                  </Route>
-
-                  <Route path="/addons/new">
-                    <NewAddOnFlow />
-                  </Route>
-                  <Route path="/addons">
-                    <AddOnDashboard />
-                  </Route>
-                  <Route
-                    path="/new-project"
-                    render={() => {
-                      return <NewProjectFC />;
-                    }}
-                  ></Route>
-                  <Route
-                    path="/onboarding"
-                    render={() => {
-                      return <Onboarding />;
-                    }}
-                  />
-                  {(user?.isPorterUser ||
-                    overrideInfraTabEnabled({
-                      projectID: currentProject?.id,
-                    })) && (
-                    <Route
-                      path="/infrastructure"
-                      render={() => {
-                        return (
-                          <DashboardWrapper>
-                            <InfrastructureRouter />
-                          </DashboardWrapper>
-                        );
-                      }}
-                    />
+            {/* Render sidebar when there's at least one project */}
+            {projects?.length > 0 && baseRoute !== "new-project" ? (
+              <Sidebar
+                key="sidebar"
+                forceSidebar={forceSidebar}
+                setWelcome={setShowWelcome}
+                currentView={props.currentRoute}
+                forceRefreshClusters={forceRefreshClusters}
+                setRefreshClusters={setForceRefreshClusters}
+              />
+            ) : (
+              <DiscordButton href="https://discord.gg/34n7NN7FJ7" target="_blank">
+                <Icon src={discordLogo} />
+                Join Our Discord
+              </DiscordButton>
+            )}
+            <ViewWrapper id="HomeViewWrapper">
+              <Navbar
+                logOut={props.logOut}
+                currentView={props.currentRoute} // For form feedback
+              />
+
+              <Switch>
+                <Route path="/apps/new/app">
+                  {currentProject?.validate_apply_v2 ? (
+                    <CreateApp />
+                  ) : (
+                    <NewAppFlow />
+                  )}
+                </Route>
+                <Route path="/apps/:appName/:tab">
+                  {currentProject?.validate_apply_v2 ? (
+                    <AppView />
+                  ) : (
+                    <ExpandedApp />
+                  )}
+                </Route>
+                <Route path="/apps/:appName">
+                  {currentProject?.validate_apply_v2 ? (
+                    <AppView />
+                  ) : (
+                    <ExpandedApp />
+                  )}
+                </Route>
+                <Route path="/apps">
+                  {currentProject?.validate_apply_v2 ? (
+                    <Apps />
+                  ) : (
+                    <AppDashboard />
                   )}
+                </Route>
+
+                <Route path="/databases/new">
+                  <CreateDatabase />
+                </Route>
+                <Route path="/databases">
+                  <DatabaseDashboard />
+                </Route>
+
+                <Route path="/addons/new">
+                  <NewAddOnFlow />
+                </Route>
+                <Route path="/addons">
+                  <AddOnDashboard />
+                </Route>
+                <Route
+                  path="/new-project"
+                  render={() => {
+                    return <NewProjectFC />;
+                  }}
+                ></Route>
+                <Route
+                  path="/onboarding"
+                  render={() => {
+                    return <Onboarding />;
+                  }}
+                />
+                {(user?.isPorterUser ||
+                  overrideInfraTabEnabled({
+                    projectID: currentProject?.id,
+                  })) && (
                   <Route
-                    path="/dashboard"
+                    path="/infrastructure"
                     render={() => {
                       return (
                         <DashboardWrapper>
-                          <Dashboard
-                            projectId={currentProject?.id}
-                            setRefreshClusters={setForceRefreshClusters}
-                          />
+                          <InfrastructureRouter />
                         </DashboardWrapper>
                       );
                     }}
                   />
-                  <Route
-                    path={[
-                      "/cluster-dashboard",
-                      "/applications",
-                      "/jobs",
-                      "/env-groups",
-                      "/databases",
-                      ...(!currentProject?.validate_apply_v2
-                        ? ["/preview-environments"]
-                        : []),
-                      "/stacks",
-                    ]}
-                    render={() => {
-                      if (currentCluster?.id === -1) {
-                        return <Loading />;
-                      } else if (!currentCluster?.name) {
-                        return (
-                          <DashboardWrapper>
-                            <NoClusterPlaceHolder></NoClusterPlaceHolder>
-                          </DashboardWrapper>
-                        );
-                      }
+                )}
+                <Route
+                  path="/dashboard"
+                  render={() => {
+                    return (
+                      <DashboardWrapper>
+                        <Dashboard
+                          projectId={currentProject?.id}
+                          setRefreshClusters={setForceRefreshClusters}
+                        />
+                      </DashboardWrapper>
+                    );
+                  }}
+                />
+                <Route
+                  path={[
+                    "/cluster-dashboard",
+                    "/applications",
+                    "/jobs",
+                    "/env-groups",
+                    "/databases",
+                    ...(!currentProject?.validate_apply_v2
+                      ? ["/preview-environments"]
+                      : []),
+                    "/stacks",
+                  ]}
+                  render={() => {
+                    if (currentCluster?.id === -1) {
+                      return <Loading />;
+                    } else if (!currentCluster || !currentCluster.name) {
                       return (
                         <DashboardWrapper>
-                          <DashboardRouter
-                            currentCluster={currentCluster}
-                            setSidebar={setForceSidebar}
-                            currentView={props.currentRoute}
-                          />
+                          <NoClusterPlaceHolder></NoClusterPlaceHolder>
                         </DashboardWrapper>
                       );
-                    }}
-                  />
-                  <Route
-                    path={"/integrations"}
-                    render={() => <GuardedIntegrations />}
-                  />
-                  <Route
-                    exact
-                    path={"/project-settings"}
-                    render={() => <GuardedProjectSettings />}
-                  />
-                  {currentProject?.validate_apply_v2 &&
-                  currentProject.preview_envs_enabled ? (
-                    <>
-                      <Route exact path="/preview-environments/configure">
-                        <SetupApp />
-                      </Route>
-                      <Route
-                        exact
-                        path={`/preview-environments/apps/:appName/:tab`}
-                      >
-                        <AppView />
-                      </Route>
-                      <Route exact path="/preview-environments/apps/:appName">
-                        <AppView />
-                      </Route>
-                      <Route exact path={`/preview-environments/apps`}>
-                        <Apps />
-                      </Route>
-                      <Route exact path={`/preview-environments`}>
-                        <PreviewEnvs />
-                      </Route>
-                    </>
-                  ) : null}
-                  <Route path={"*"} render={() => <LaunchWrapper />} />
-                </Switch>
-              </ViewWrapper>
-              {createPortal(
-                <ConfirmOverlay
-                  show={currentModal === "UpdateProjectModal"}
-                  message={
-                    currentProject
-                      ? `Are you sure you want to delete ${currentProject.name}?`
-                      : ""
-                  }
-                  onYes={handleDelete}
-                  onNo={() => {
-                    setCurrentModal(null, null);
+                    }
+                    return (
+                      <DashboardWrapper>
+                        <DashboardRouter
+                          currentCluster={currentCluster}
+                          setSidebar={setForceSidebar}
+                          currentView={props.currentRoute}
+                        />
+                      </DashboardWrapper>
+                    );
                   }}
-                />,
-                document.body
-              )}
-              {showWrongEmailModal && (
-                <Modal>
-                  <Text size={16}>
-                    Oops! This invite link wasn't for {user?.email}
-                  </Text>
-                  <Spacer y={1} />
-                  <Text color="helper">
-                    Your account email does not match the email associated with
-                    this project invite. Please log out and sign up again with
-                    the correct email using the invite link.
-                  </Text>
-                  <Spacer y={1} />
-                  <Text color="helper">
-                    You should reach out to the person who sent you the invite
-                    link to get the correct email.
-                  </Text>
-                  <Spacer y={1} />
-                  <Button onClick={props.logOut}>Log out</Button>
-                </Modal>
-              )}
-            </StyledHome>
-          </DeploymentTargetProvider>
-        </ClusterResourcesProvider>
-      </ThemeProvider>
-    </AuthStateProvider>
+                />
+                <Route
+                  path={"/integrations"}
+                  render={() => <GuardedIntegrations />}
+                />
+                <Route
+                  exact
+                  path={"/project-settings"}
+                  render={() => <GuardedProjectSettings />}
+                />
+                {currentProject?.validate_apply_v2 &&
+                currentProject.preview_envs_enabled ? (
+                  <>
+                    <Route exact path="/preview-environments/configure">
+                      <SetupApp />
+                    </Route>
+                    <Route
+                      exact
+                      path={`/preview-environments/apps/:appName/:tab`}
+                    >
+                      <AppView />
+                    </Route>
+                    <Route exact path="/preview-environments/apps/:appName">
+                      <AppView />
+                    </Route>
+                    <Route exact path={`/preview-environments/apps`}>
+                      <Apps />
+                    </Route>
+                    <Route exact path={`/preview-environments`}>
+                      <PreviewEnvs />
+                    </Route>
+                  </>
+                ) : null}
+                <Route path={"*"} render={() => <LaunchWrapper />} />
+              </Switch>
+            </ViewWrapper>
+            {createPortal(
+              <ConfirmOverlay
+                show={currentModal === "UpdateProjectModal"}
+                message={
+                  currentProject
+                    ? `Are you sure you want to delete ${currentProject.name}?`
+                    : ""
+                }
+                onYes={handleDelete}
+                onNo={() => setCurrentModal(null, null)}
+              />,
+              document.body
+            )}
+            {showWrongEmailModal && (
+              <Modal>
+                <Text size={16}>
+                  Oops! This invite link wasn't for {user?.email}
+                </Text>
+                <Spacer y={1} />
+                <Text color="helper">
+                  Your account email does not match the email associated with this
+                  project invite. Please log out and sign up again with the
+                  correct email using the invite link.
+                </Text>
+                <Spacer y={1} />
+                <Text color="helper">
+                  You should reach out to the person who sent you the invite link
+                  to get the correct email.
+                </Text>
+                <Spacer y={1} />
+                <Button onClick={props.logOut}>Log out</Button>
+              </Modal>
+            )}
+          </StyledHome>
+        </DeploymentTargetProvider>
+      </ClusterResourcesProvider>
+    </ThemeProvider>
   );
 };
 
@@ -696,9 +674,7 @@ const DiscordButton = styled.a`
   border-radius: 3px;
   color: #ffffff44;
   height: 40px;
-  font-family:
-    Work Sans,
-    sans-serif;
+  font-family: Work Sans, sans-serif;
   font-size: 14px;
   font-weight: bold;
   cursor: pointer;

+ 16 - 8
dashboard/src/main/home/app-dashboard/app-view/LatestRevisionContext.tsx

@@ -16,7 +16,6 @@ import Container from "components/porter/Container";
 import Link from "components/porter/Link";
 import Spacer from "components/porter/Spacer";
 import Text from "components/porter/Text";
-import { useAuthState } from "main/auth/context";
 import { usePorterYaml } from "lib/hooks/usePorterYaml";
 import { clientAppFromProto, type SourceOptions } from "lib/porter-apps";
 import {
@@ -26,6 +25,7 @@ import {
 import { appRevisionValidator, type AppRevision } from "lib/revisions/types";
 
 import api from "shared/api";
+import { Context } from "shared/Context";
 import {
   useDeploymentTarget,
   type DeploymentTarget,
@@ -79,13 +79,17 @@ export const LatestRevisionProvider: React.FC<LatestRevisionProviderProps> = ({
   const [previewRevision, setPreviewRevision] = useState<AppRevision | null>(
     null
   );
-  const { currentCluster, currentProject } = useAuthState();
+  const { currentCluster, currentProject } = useContext(Context);
   const { currentDeploymentTarget } = useDeploymentTarget();
 
-  const appParamsExist = !!appName && !!currentDeploymentTarget;
+  const appParamsExist =
+    !!appName &&
+    !!currentCluster &&
+    !!currentProject &&
+    !!currentDeploymentTarget;
 
   const { data: porterApp, status: porterAppStatus } = useQuery(
-    ["getPorterApp", currentCluster.id, currentProject.id, appName],
+    ["getPorterApp", currentCluster?.id, currentProject?.id, appName],
     async () => {
       if (!appParamsExist) {
         return;
@@ -112,8 +116,8 @@ export const LatestRevisionProvider: React.FC<LatestRevisionProviderProps> = ({
   const { data: latestRevision, status } = useQuery(
     [
       "getLatestRevision",
-      currentProject.id,
-      currentCluster.id,
+      currentProject?.id,
+      currentCluster?.id,
       currentDeploymentTarget,
       appName,
     ],
@@ -157,7 +161,7 @@ export const LatestRevisionProvider: React.FC<LatestRevisionProviderProps> = ({
       },
     ],
     async () => {
-      if (!currentDeploymentTarget) {
+      if (!currentCluster || !currentProject || !currentDeploymentTarget) {
         return;
       }
       const res = await api.getDeploymentTarget(
@@ -181,6 +185,9 @@ export const LatestRevisionProvider: React.FC<LatestRevisionProviderProps> = ({
         .parseAsync(res.data);
 
       return deploymentTarget;
+    },
+    {
+      enabled: !!currentCluster && !!currentProject,
     }
   );
 
@@ -224,7 +231,8 @@ export const LatestRevisionProvider: React.FC<LatestRevisionProviderProps> = ({
       };
     },
     {
-      enabled: !!appName && !!revisionId,
+      enabled:
+        !!appName && !!revisionId && !!currentCluster && !!currentProject,
     }
   );