diff --git a/frontend/web/components/EnvironmentReadyChecker.tsx b/frontend/web/components/EnvironmentReadyChecker.tsx
index 9e32893f2bf9..6f065fe66be1 100644
--- a/frontend/web/components/EnvironmentReadyChecker.tsx
+++ b/frontend/web/components/EnvironmentReadyChecker.tsx
@@ -1,8 +1,9 @@
-import { PropsWithChildren, useEffect, useState } from 'react'
+import { PropsWithChildren } from 'react'
import { useGetEnvironmentQuery } from 'common/services/useEnvironment'
import { useRouteMatch } from 'react-router-dom'
interface RouteParams {
+ projectId?: string
environmentId?: string
}
@@ -10,44 +11,61 @@ type EnvironmentReadyCheckerType = {
children: React.ReactNode
}
+const POLL_INTERVAL_MS = 1000
+
+const LoadingState = () => (
+
+
+
+)
+
+const CreatingState = () => (
+
+
+
+
Preparing your environment
+
We are setting up your new environment...
+
+
+)
+
+const NotFoundState = () => (
+
+
Environment not found
+
+ This environment may have been deleted, or you may not have permission to
+ access it. Check the URL and try again.
+
+
+)
+
const EnvironmentReadyChecker = ({
children,
}: PropsWithChildren) => {
const match = useRouteMatch()
- const [environmentCreated, setEnvironmentCreated] = useState(false)
+ const environmentId = match?.params?.environmentId
+ const projectId = match?.params?.projectId
+ // 'create' is the new-env form route sentinel, not an env ID.
+ const hasEnvironmentId = !!environmentId && environmentId !== 'create'
- const { data, isLoading } = useGetEnvironmentQuery(
- {
- id: match?.params?.environmentId || '',
- },
+ const { data, isError } = useGetEnvironmentQuery(
+ { id: environmentId || '' },
{
- pollingInterval: 1000,
- skip: !match?.params?.environmentId || environmentCreated,
+ pollingInterval: data?.is_creating ? POLL_INTERVAL_MS : 0,
+ skip: !hasEnvironmentId,
},
)
- useEffect(() => {
- if (!!data && !data?.is_creating) {
- setEnvironmentCreated(true)
- }
- }, [data])
- if (!match?.params?.environmentId) {
- return children
- }
- return isLoading ? (
-
-
-
- ) : data?.is_creating ? (
-
-
-
-
Preparing your environment
-
We are setting up your new environment...
-
-
- ) : (
- children
- )
+
+ // Env-by-api_key endpoint isn't project-scoped — verify the match client-side.
+ const wrongProject =
+ !!data && !!projectId && data.project !== Number(projectId)
+ const environmentNotFound = hasEnvironmentId && (wrongProject || isError)
+
+ if (!hasEnvironmentId) return children
+ if (environmentNotFound) return
+ if (!data) return
+ if (data.is_creating) return
+ return children
}
export default EnvironmentReadyChecker
diff --git a/frontend/web/components/navigation/EnvironmentAside.tsx b/frontend/web/components/navigation/EnvironmentAside.tsx
index 07fa75f28111..45ec3eda32a1 100644
--- a/frontend/web/components/navigation/EnvironmentAside.tsx
+++ b/frontend/web/components/navigation/EnvironmentAside.tsx
@@ -16,11 +16,12 @@ import AppActions from 'common/dispatcher/app-actions'
import EnvironmentSelect from 'components/EnvironmentSelect'
import { components } from 'react-select'
import BuildVersion from 'components/BuildVersion'
+import { useGetEnvironmentsQuery } from 'common/services/useEnvironment'
import { useGetHealthEventsQuery } from 'common/services/useHealthEvents'
import Constants from 'common/constants'
import EnvironmentNavbar from './navbars/EnvironmentNavbar'
import OverflowNav from './OverflowNav'
-import { ProjectPermission } from 'common/types/permissions.types';
+import { ProjectPermission } from 'common/types/permissions.types'
type HomeAsideType = {
environmentId: string
@@ -102,6 +103,8 @@ const CustomSingleValue = ({ hasWarning, ...rest }: CustomSingleValueProps) => {
const EnvironmentAside: FC = ({ environmentId, projectId }) => {
const history = useHistory()
+ const { data: environments, isSuccess: environmentsLoaded } =
+ useGetEnvironmentsQuery({ projectId }, { skip: !projectId })
const { data: healthEvents } = useGetHealthEventsQuery(
{ projectId: projectId },
{ skip: !projectId },
@@ -126,9 +129,18 @@ const EnvironmentAside: FC = ({ environmentId, projectId }) => {
? null
: (ProjectStore.getEnvironment(environmentId) as any)
+ const environmentNotFound =
+ environmentId !== 'create' &&
+ environmentsLoaded &&
+ !environments?.results?.some((env) => env.api_key === environmentId)
+
const onProjectSave = () => {
AppActions.refreshOrganisation()
}
+
+ if (environmentNotFound) {
+ return null
+ }
return (
<>
diff --git a/frontend/web/components/navigation/navbars/EnvironmentNavbar.tsx b/frontend/web/components/navigation/navbars/EnvironmentNavbar.tsx
index 3dccf9503c7d..15ee18c8d47d 100644
--- a/frontend/web/components/navigation/navbars/EnvironmentNavbar.tsx
+++ b/frontend/web/components/navigation/navbars/EnvironmentNavbar.tsx
@@ -21,30 +21,36 @@ const EnvironmentNavbar: FC = ({
}) => {
const date = useRef(moment().toISOString())
- const { data: environments } = useGetEnvironmentsQuery(
+ const { data: environments, isSuccess: environmentsLoaded } =
+ useGetEnvironmentsQuery({ projectId }, { skip: !projectId })
+
+ const environment = environments?.results?.find(
+ (v) => v.api_key === environmentId,
+ )
+
+ const { data: scheduledData } = useGetChangeRequestsQuery(
{
- projectId: `${projectId}`,
+ committed: true,
+ environmentId,
+ live_from_after: date.current,
+ page_size: 1,
},
- { skip: !projectId },
+ { skip: !environment },
)
- const { data: scheduledData } = useGetChangeRequestsQuery({
- committed: true,
- environmentId,
- live_from_after: date.current,
- page_size: 1,
- })
-
- const { data: changeRequestsData } = useGetChangeRequestsQuery({
- committed: false,
- environmentId,
- page_size: 1,
- })
-
- const environment = environments?.results?.find(
- (v) => v.api_key === environmentId,
+ const { data: changeRequestsData } = useGetChangeRequestsQuery(
+ {
+ committed: false,
+ environmentId,
+ page_size: 1,
+ },
+ { skip: !environment },
)
+ if (environmentsLoaded && !environment) {
+ return null
+ }
+
const changeRequests =
(Utils.changeRequestsEnabled(
environment?.minimum_change_request_approvals,