mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-15 07:35:09 +00:00
feat: improved migration wizard to info user prerequisite check list
This commit is contained in:
@@ -14,6 +14,7 @@ export type CheckboxProps = Omit<
|
||||
isChecked?: boolean;
|
||||
isRequired?: boolean;
|
||||
checkIndicatorBg?: string | undefined;
|
||||
isError?: boolean;
|
||||
};
|
||||
|
||||
export const Checkbox = ({
|
||||
@@ -24,6 +25,7 @@ export const Checkbox = ({
|
||||
isDisabled,
|
||||
isRequired,
|
||||
checkIndicatorBg,
|
||||
isError,
|
||||
...props
|
||||
}: CheckboxProps): JSX.Element => {
|
||||
return (
|
||||
@@ -46,7 +48,10 @@ export const Checkbox = ({
|
||||
<FontAwesomeIcon icon={faCheck} size="sm" />
|
||||
</CheckboxPrimitive.Indicator>
|
||||
</CheckboxPrimitive.Root>
|
||||
<label className="truncate whitespace-nowrap text-sm" htmlFor={id}>
|
||||
<label
|
||||
className={twMerge("truncate whitespace-nowrap text-sm", isError && "text-red-400")}
|
||||
htmlFor={id}
|
||||
>
|
||||
{children}
|
||||
{isRequired && <span className="pl-1 text-red">*</span>}
|
||||
</label>
|
||||
|
||||
@@ -28,6 +28,7 @@ import {
|
||||
useGetWsTags
|
||||
} from "@app/hooks/api";
|
||||
|
||||
import { SecretV2MigrationSection } from "../SecretOverviewPage/components/SecretV2MigrationSection";
|
||||
import { ActionBar } from "./components/ActionBar";
|
||||
import { CreateSecretForm } from "./components/CreateSecretForm";
|
||||
import { DynamicSecretListView } from "./components/DynamicSecretListView";
|
||||
@@ -231,6 +232,7 @@ export const SecretMainPage = () => {
|
||||
return (
|
||||
<StoreProvider>
|
||||
<div className="container mx-auto flex h-full flex-col px-6 text-mineshaft-50 dark:[color-scheme:dark]">
|
||||
<SecretV2MigrationSection />
|
||||
<div className="relative right-6 -top-2 mb-2 ml-6">
|
||||
<NavHeader
|
||||
pageName={t("dashboard.title")}
|
||||
|
||||
+128
-9
@@ -1,6 +1,14 @@
|
||||
import { useEffect } from "react";
|
||||
import { Controller, useForm } from "react-hook-form";
|
||||
import { faTriangleExclamation } from "@fortawesome/free-solid-svg-icons";
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
import { zodResolver } from "@hookform/resolvers/zod";
|
||||
import { z } from "zod";
|
||||
|
||||
import { createNotification } from "@app/components/notifications";
|
||||
import { Button, Spinner } from "@app/components/v2";
|
||||
import { Button, Checkbox, Modal, ModalContent, Spinner } from "@app/components/v2";
|
||||
import { useProjectPermission, useWorkspace } from "@app/context";
|
||||
import { usePopUp } from "@app/hooks";
|
||||
import { useGetWorkspaceById, useMigrateProjectToV3 } from "@app/hooks/api";
|
||||
import { ProjectMembershipRole } from "@app/hooks/api/roles/types";
|
||||
import { ProjectVersion } from "@app/hooks/api/workspace/types";
|
||||
@@ -11,9 +19,17 @@ enum ProjectUpgradeStatus {
|
||||
Failed = "FAILED"
|
||||
}
|
||||
|
||||
const formSchema = z.object({
|
||||
isCLIChecked: z.literal(true),
|
||||
isOperatorChecked: z.literal(true),
|
||||
doesKnowSnapshotLimit: z.literal(true),
|
||||
shouldCloseOpenApprovals: z.literal(true)
|
||||
});
|
||||
|
||||
export const SecretV2MigrationSection = () => {
|
||||
const { popUp, handlePopUpOpen, handlePopUpToggle } = usePopUp(["migrationInfo"] as const);
|
||||
const { currentWorkspace } = useWorkspace();
|
||||
const { data: workspaceDetails } = useGetWorkspaceById(
|
||||
const { data: workspaceDetails, refetch } = useGetWorkspaceById(
|
||||
// if v3 no need to fetch
|
||||
currentWorkspace?.version === ProjectVersion.V3 ? "" : currentWorkspace?.id || "",
|
||||
{
|
||||
@@ -23,17 +39,26 @@ export const SecretV2MigrationSection = () => {
|
||||
);
|
||||
const { membership } = useProjectPermission();
|
||||
const migrateProjectToV3 = useMigrateProjectToV3();
|
||||
const { handleSubmit, control, reset } = useForm({ resolver: zodResolver(formSchema) });
|
||||
useEffect(() => {
|
||||
if (!popUp.migrationInfo.isOpen) {
|
||||
reset();
|
||||
}
|
||||
}, [popUp.migrationInfo.isOpen]);
|
||||
|
||||
const isProjectUpgraded = workspaceDetails?.version === ProjectVersion.V3;
|
||||
|
||||
if (isProjectUpgraded || currentWorkspace?.version === ProjectVersion.V3) return null;
|
||||
const isUpgrading = workspaceDetails?.upgradeStatus === ProjectUpgradeStatus.InProgress;
|
||||
const didProjectUpgradeFailed = workspaceDetails?.upgradeStatus === ProjectUpgradeStatus.Failed;
|
||||
|
||||
const handleMigrationSecretV2 = async () => {
|
||||
try {
|
||||
handlePopUpToggle("migrationInfo");
|
||||
await migrateProjectToV3.mutateAsync({ workspaceId: currentWorkspace?.id || "" });
|
||||
refetch();
|
||||
createNotification({
|
||||
text: "Migrated project to new KMS",
|
||||
text: "Project upgrade started",
|
||||
type: "success"
|
||||
});
|
||||
} catch {
|
||||
@@ -46,7 +71,7 @@ export const SecretV2MigrationSection = () => {
|
||||
|
||||
const isAdmin = membership?.roles.includes(ProjectMembershipRole.Admin);
|
||||
return (
|
||||
<div className="mt-4 rounded-lg border border-mineshaft-600 bg-mineshaft-900 p-4">
|
||||
<div className="mt-4 rounded-lg border border-primary-600 bg-mineshaft-900 p-4">
|
||||
{isUpgrading && (
|
||||
<div className="absolute top-0 left-0 z-50 flex h-screen w-screen items-center justify-center bg-bunker-500 bg-opacity-80">
|
||||
<Spinner size="lg" className="text-primary" />
|
||||
@@ -58,19 +83,113 @@ export const SecretV2MigrationSection = () => {
|
||||
)}
|
||||
<p className="mb-2 text-lg font-semibold">Action Required</p>
|
||||
<p className="mb-4 leading-7 text-gray-400">
|
||||
There is a new update for your project. Introducing Infisical KMS.
|
||||
Your project can now leverage Infisical KMS! Ready to enhance your security?
|
||||
<b>{!isAdmin && "This is an admin only operation."}</b>
|
||||
</p>
|
||||
|
||||
<Button
|
||||
onClick={handleMigrationSecretV2}
|
||||
onClick={() => handlePopUpOpen("migrationInfo")}
|
||||
isDisabled={!isAdmin || isUpgrading}
|
||||
color="mineshaft"
|
||||
type="submit"
|
||||
isLoading={migrateProjectToV3.isLoading}
|
||||
>
|
||||
Start Migration
|
||||
Update Now
|
||||
</Button>
|
||||
{didProjectUpgradeFailed && (
|
||||
<p className="mt-2 text-sm leading-7 text-red-400">
|
||||
<FontAwesomeIcon icon={faTriangleExclamation} className="mr-2" />
|
||||
Project upgrade unsuccessful. For assistance, please contact the Infisical support team.
|
||||
</p>
|
||||
)}
|
||||
<Modal
|
||||
isOpen={popUp.migrationInfo.isOpen}
|
||||
onOpenChange={(isOpen) => handlePopUpToggle("migrationInfo", isOpen)}
|
||||
>
|
||||
<ModalContent
|
||||
title="Upgrade Checklist"
|
||||
subTitle="Before proceeding with the upgrade, please ensure the following requirements are met:"
|
||||
>
|
||||
<div>
|
||||
<form onSubmit={handleSubmit(handleMigrationSecretV2)}>
|
||||
<div className="flex flex-col space-y-4">
|
||||
<Controller
|
||||
control={control}
|
||||
name="isCLIChecked"
|
||||
defaultValue={false}
|
||||
render={({ field: { onBlur, value, onChange }, fieldState: { error } }) => (
|
||||
<Checkbox
|
||||
id="is-cli-checked"
|
||||
isChecked={value}
|
||||
onCheckedChange={onChange}
|
||||
onBlur={onBlur}
|
||||
isError={Boolean(error?.message)}
|
||||
>
|
||||
CLI version: v0.25.0 or above
|
||||
</Checkbox>
|
||||
)}
|
||||
/>
|
||||
<Controller
|
||||
control={control}
|
||||
name="isOperatorChecked"
|
||||
defaultValue={false}
|
||||
render={({ field: { onBlur, value, onChange }, fieldState: { error } }) => (
|
||||
<Checkbox
|
||||
id="is-operator-checked"
|
||||
isChecked={value}
|
||||
onCheckedChange={onChange}
|
||||
onBlur={onBlur}
|
||||
isError={Boolean(error?.message)}
|
||||
>
|
||||
Operator version: v0.25.0 or above
|
||||
</Checkbox>
|
||||
)}
|
||||
/>
|
||||
<Controller
|
||||
control={control}
|
||||
name="doesKnowSnapshotLimit"
|
||||
defaultValue={false}
|
||||
render={({ field: { onBlur, value, onChange }, fieldState: { error } }) => (
|
||||
<Checkbox
|
||||
id="is-snapshot-checked"
|
||||
isChecked={value}
|
||||
onCheckedChange={onChange}
|
||||
onBlur={onBlur}
|
||||
isError={Boolean(error?.message)}
|
||||
>
|
||||
Folders keep 10 latest snapshots due to migration time limit.
|
||||
</Checkbox>
|
||||
)}
|
||||
/>
|
||||
<Controller
|
||||
control={control}
|
||||
name="shouldCloseOpenApprovals"
|
||||
defaultValue={false}
|
||||
render={({ field: { onBlur, value, onChange }, fieldState: { error } }) => (
|
||||
<Checkbox
|
||||
id="is-approvals-checked"
|
||||
isChecked={value}
|
||||
onCheckedChange={onChange}
|
||||
onBlur={onBlur}
|
||||
isError={Boolean(error?.message)}
|
||||
>
|
||||
Close/Merge all open approval requests as it will be reset.
|
||||
</Checkbox>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
<div className="mt-4 text-sm">
|
||||
Meeting these prerequisites will ensure system compatibility and a smooth upgrade
|
||||
process.
|
||||
</div>
|
||||
<div className="mt-8 flex space-x-4">
|
||||
<Button type="submit">Update</Button>
|
||||
<Button variant="outline_bg" onClick={() => handlePopUpToggle("migrationInfo")}>
|
||||
Cancel
|
||||
</Button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</ModalContent>
|
||||
</Modal>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user