feat: initial move secret integration

This commit is contained in:
Sheen Capadngan
2024-07-09 17:48:39 +08:00
parent 05bf2e4696
commit d20ae39f32
6 changed files with 274 additions and 23 deletions
@@ -2,6 +2,7 @@ import { useState } from "react";
import { subject } from "@casl/ability";
import {
faAngleDown,
faAnglesRight,
faCheckCircle,
faChevronRight,
faCodeCommit,
@@ -46,7 +47,12 @@ import {
import { ProjectPermissionActions, ProjectPermissionSub, useSubscription } from "@app/context";
import { interpolateSecrets } from "@app/helpers/secret";
import { usePopUp } from "@app/hooks";
import { useCreateFolder, useDeleteSecretBatch, useGetUserWsKey } from "@app/hooks/api";
import {
useCreateFolder,
useDeleteSecretBatch,
useGetUserWsKey,
useMoveSecrets
} from "@app/hooks/api";
import { DecryptedSecret, SecretType, TImportedSecrets, WsTag } from "@app/hooks/api/types";
import { debounce } from "@app/lib/fn/debounce";
@@ -60,6 +66,7 @@ import { Filter, GroupBy } from "../../SecretMainPage.types";
import { CreateDynamicSecretForm } from "./CreateDynamicSecretForm";
import { CreateSecretImportForm } from "./CreateSecretImportForm";
import { FolderForm } from "./FolderForm";
import { MoveSecretsModal } from "./MoveSecretsModal";
type Props = {
secrets?: DecryptedSecret[];
@@ -105,6 +112,7 @@ export const ActionBar = ({
"addDynamicSecret",
"addSecretImport",
"bulkDeleteSecrets",
"moveSecrets",
"misc",
"upgradePlan"
] as const);
@@ -114,6 +122,7 @@ export const ActionBar = ({
const { mutateAsync: createFolder } = useCreateFolder();
const { mutateAsync: deleteBatchSecretV3 } = useDeleteSecretBatch();
const { mutateAsync: moveSecrets } = useMoveSecrets();
const { data: decryptFileKey } = useGetUserWsKey(workspaceId);
const selectedSecrets = useSelectedSecrets();
@@ -228,6 +237,37 @@ export const ActionBar = ({
}
};
const handleSecretsMove = async ({
destinationEnvironment,
destinationSecretPath
}: {
destinationEnvironment: string;
destinationSecretPath: string;
}) => {
try {
const secretsToMove = secrets.filter(({ id }) => Boolean(selectedSecrets?.[id]));
await moveSecrets({
projectSlug,
sourceEnvironment: environment,
sourceSecretPath: secretPath,
destinationEnvironment,
destinationSecretPath,
projectId: workspaceId,
secretIds: secretsToMove.map((sec) => sec.id)
});
createNotification({
type: "success",
text: "Successfully moved selected secrets"
});
} catch (error) {
createNotification({
type: "error",
text: "Error moving selected secrets"
});
}
};
return (
<>
<div className="mt-4 flex items-center space-x-2">
@@ -455,6 +495,25 @@ export const ActionBar = ({
<div className="ml-4 flex-grow px-2 text-sm">
{Object.keys(selectedSecrets).length} Selected
</div>
<ProjectPermissionCan
I={ProjectPermissionActions.Delete}
a={subject(ProjectPermissionSub.Secrets, { environment, secretPath })}
renderTooltip
allowedLabel="Move"
>
{(isAllowed) => (
<Button
variant="outline_bg"
leftIcon={<FontAwesomeIcon icon={faAnglesRight} />}
className="ml-4"
onClick={() => handlePopUpOpen("moveSecrets")}
isDisabled={!isAllowed}
size="xs"
>
Move
</Button>
)}
</ProjectPermissionCan>
<ProjectPermissionCan
I={ProjectPermissionActions.Delete}
a={subject(ProjectPermissionSub.Secrets, { environment, secretPath })}
@@ -466,7 +525,7 @@ export const ActionBar = ({
variant="outline_bg"
colorSchema="danger"
leftIcon={<FontAwesomeIcon icon={faTrash} />}
className="ml-4"
className="ml-2"
onClick={() => handlePopUpOpen("bulkDeleteSecrets")}
isDisabled={!isAllowed}
size="xs"
@@ -509,6 +568,11 @@ export const ActionBar = ({
onChange={(isOpen) => handlePopUpToggle("bulkDeleteSecrets", isOpen)}
onDeleteApproved={handleSecretBulkDelete}
/>
<MoveSecretsModal
popUp={popUp}
handlePopUpToggle={handlePopUpToggle}
onMoveApproved={handleSecretsMove}
/>
{subscription && (
<UpgradePlanModal
isOpen={popUp.upgradePlan.isOpen}