Finished migration

This commit is contained in:
Daniel Hougaard
2024-02-22 05:00:25 +01:00
parent 8333250b0b
commit 4802a36473
18 changed files with 660 additions and 369 deletions
@@ -0,0 +1,90 @@
import { useCallback, useEffect, useState } from "react";
import { useNotificationContext } from "@app/components/context/Notifications/NotificationProvider";
import { useGetUpgradeProjectStatus, useUpgradeProject } from "@app/hooks/api";
import { Workspace } from "@app/hooks/api/types";
import { Alert } from "../Alert";
import { Button } from "../Button";
export type UpgradeProjectAlertProps = {
project: Workspace;
};
export const UpgradeProjectAlert = ({ project }: UpgradeProjectAlertProps): JSX.Element | null => {
const { createNotification } = useNotificationContext();
const upgradeProject = useUpgradeProject();
const [currentStatus, setCurrentStatus] = useState<string | null>(null);
const {
data: projectStatus,
refetch: getLatestProjectStatus,
isLoading: statusIsLoading
} = useGetUpgradeProjectStatus(project.id);
const onUpgradeProject = useCallback(async () => {
const PRIVATE_KEY = localStorage.getItem("PRIVATE_KEY");
if (!PRIVATE_KEY) {
createNotification({
type: "error",
text: "Private key not found"
});
return;
}
await upgradeProject.mutateAsync({
projectId: project.id,
privateKey: PRIVATE_KEY
});
await getLatestProjectStatus();
}, []);
useEffect(() => {
if (project.version === "v1") {
getLatestProjectStatus();
}
if (projectStatus && projectStatus?.status !== null) {
if (projectStatus.status === "IN_PROGRESS") {
setCurrentStatus("Your upgrade is being processed.");
} else if (projectStatus.status === "FAILED") {
setCurrentStatus("Upgrade failed, please try again.");
}
}
const interval = setInterval(() => {
if (project.version === "v1") {
getLatestProjectStatus();
}
}, 5_000);
return () => {
clearInterval(interval);
};
}, [projectStatus]);
const isLoading =
(upgradeProject.isLoading ||
currentStatus !== null ||
(currentStatus === null && statusIsLoading)) &&
projectStatus?.status !== "FAILED";
if (project.version !== "v1") return null;
return (
<div className="my-8">
<Alert title="Upgrade your project" variant="warning">
<div className="max-w-md">
Upgrade your project version to continue receiving the latest improvements and patches.
{currentStatus && <p className="mt-2 opacity-80">Status: {currentStatus}</p>}
</div>
<div className="mt-2">
<Button isLoading={isLoading} isDisabled={isLoading} onClick={onUpgradeProject}>
Upgrade
</Button>
</div>
</Alert>
</div>
);
};
@@ -0,0 +1 @@
export { UpgradeProjectAlert } from "./UpgradeProjectAlert";
@@ -7,6 +7,7 @@ export {
useDeleteUserFromWorkspace,
useDeleteWorkspace,
useDeleteWsEnvironment,
useGetUpgradeProjectStatus,
useGetUserWorkspaceMemberships,
useGetUserWorkspaces,
useGetWorkspaceAuthorizations,
@@ -24,6 +24,7 @@ export const workspaceKeys = {
getWorkspaceSecrets: (workspaceId: string) => [{ workspaceId }, "workspace-secrets"] as const,
getWorkspaceIndexStatus: (workspaceId: string) =>
[{ workspaceId }, "workspace-index-status"] as const,
getProjectUpgradeStatus: (workspaceId: string) => [{ workspaceId }, "workspace-upgrade-status"],
getWorkspaceMemberships: (orgId: string) => [{ orgId }, "workspace-memberships"],
getWorkspaceAuthorization: (workspaceId: string) => [{ workspaceId }, "workspace-authorizations"],
getWorkspaceIntegrations: (workspaceId: string) => [{ workspaceId }, "workspace-integrations"],
@@ -51,6 +52,14 @@ const fetchWorkspaceIndexStatus = async (workspaceId: string) => {
return data;
};
const fetchProjectUpgradeStatus = async (projectId: string) => {
const { data } = await apiRequest.get<{ status: string }>(
`/api/v2/workspace/${projectId}/upgrade/status`
);
return data;
};
export const fetchWorkspaceSecrets = async (workspaceId: string) => {
const {
data: { secrets }
@@ -76,6 +85,14 @@ export const useUpgradeProject = () => {
});
};
export const useGetUpgradeProjectStatus = (projectId: string) => {
return useQuery({
queryKey: workspaceKeys.getProjectUpgradeStatus(projectId),
queryFn: () => fetchProjectUpgradeStatus(projectId),
enabled: true
});
};
const fetchUserWorkspaces = async () => {
const { data } = await apiRequest.get<{ workspaces: Workspace[] }>("/api/v1/workspace");
return data.workspaces;
@@ -4,6 +4,7 @@ export type Workspace = {
name: string;
orgId: string;
version: "v1" | "v2";
upgradeStatus: string | null;
autoCapitalization: boolean;
environments: WorkspaceEnv[];
slug: string;
@@ -1,4 +1,4 @@
import { useCallback, useEffect, useRef, useState } from "react";
import { useEffect, useRef, useState } from "react";
import { useTranslation } from "react-i18next";
import Link from "next/link";
import { useRouter } from "next/router";
@@ -14,8 +14,6 @@ import { useNotificationContext } from "@app/components/context/Notifications/No
import NavHeader from "@app/components/navigation/NavHeader";
import { PermissionDeniedBanner } from "@app/components/permissions";
import {
Alert,
AlertDescription,
Button,
EmptyState,
IconButton,
@@ -31,6 +29,7 @@ import {
Tooltip,
Tr
} from "@app/components/v2";
import { UpgradeProjectAlert } from "@app/components/v2/UpgradeProjectAlert";
import { useOrganization, useWorkspace } from "@app/context";
import {
useCreateFolder,
@@ -39,8 +38,7 @@ import {
useGetFoldersByEnv,
useGetProjectSecretsAllEnv,
useGetUserWsKey,
useUpdateSecretV3,
useUpgradeProject
useUpdateSecretV3
} from "@app/hooks/api";
import { FolderBreadCrumbs } from "./components/FolderBreadCrumbs";
@@ -107,7 +105,6 @@ export const SecretOverviewPage = () => {
environments: userAvailableEnvs.map(({ slug }) => slug)
});
const upgradeProject = useUpgradeProject();
const { mutateAsync: createSecretV3 } = useCreateSecretV3();
const { mutateAsync: updateSecretV3 } = useUpdateSecretV3();
const { mutateAsync: deleteSecretV3 } = useDeleteSecretV3();
@@ -201,24 +198,6 @@ export const SecretOverviewPage = () => {
}
};
const onUpgradeProject = useCallback(async () => {
const PRIVATE_KEY = localStorage.getItem("PRIVATE_KEY");
if (!PRIVATE_KEY) {
createNotification({
type: "error",
text: "Private key not found"
});
return;
}
await upgradeProject.mutateAsync({
projectId: workspaceId,
privateKey: PRIVATE_KEY
});
}, []);
const handleResetSearch = () => setSearchFilter("");
const handleFolderClick = (path: string) => {
@@ -338,22 +317,7 @@ export const SecretOverviewPage = () => {
</p>
</div>
{currentWorkspace?.version === "v1" && (
<div className="mt-8">
<Alert variant="danger">
<AlertDescription className="prose">
Upgrade your project. More filler text More filler text More filler text More filler
text More filler text More filler text More filler text More filler text More filler
text More filler text More filler text More filler text{" "}
</AlertDescription>
<div className="mt-2">
<Button isLoading={upgradeProject.isLoading} onClick={onUpgradeProject}>
Upgrade
</Button>
</div>
</Alert>
</div>
)}
{currentWorkspace?.version === "v1" && <UpgradeProjectAlert project={currentWorkspace} />}
<div className="mt-8 flex items-center justify-between">
<FolderBreadCrumbs secretPath={secretPath} onResetSearch={handleResetSearch} />
<div className="w-80">