Skip to content

Commit

Permalink
feat: ui changes for secret approval group
Browse files Browse the repository at this point in the history
  • Loading branch information
akhilmhdh committed Jul 3, 2024
1 parent 612cf4f commit ef3cdd1
Show file tree
Hide file tree
Showing 9 changed files with 124 additions and 102 deletions.
8 changes: 4 additions & 4 deletions frontend/src/hooks/api/secretApproval/mutation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@ export const useCreateSecretApprovalPolicy = () => {
const queryClient = useQueryClient();

return useMutation<{}, {}, TCreateSecretPolicyDTO>({
mutationFn: async ({ environment, workspaceId, approvals, approvers, secretPath, name }) => {
mutationFn: async ({ environment, workspaceId, approvals, approverUserIds, secretPath, name }) => {
const { data } = await apiRequest.post("/api/v1/secret-approvals", {
environment,
workspaceId,
approvals,
approvers,
approverUserIds,
secretPath,
name
});
Expand All @@ -30,10 +30,10 @@ export const useUpdateSecretApprovalPolicy = () => {
const queryClient = useQueryClient();

return useMutation<{}, {}, TUpdateSecretPolicyDTO>({
mutationFn: async ({ id, approvers, approvals, secretPath, name }) => {
mutationFn: async ({ id, approverUserIds, approvals, secretPath, name }) => {
const { data } = await apiRequest.patch(`/api/v1/secret-approvals/${id}`, {
approvals,
approvers,
approverUserIds,
secretPath,
name
});
Expand Down
6 changes: 3 additions & 3 deletions frontend/src/hooks/api/secretApproval/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ export type TSecretApprovalPolicy = {
envId: string;
environment: WorkspaceEnv;
secretPath?: string;
approvers: string[];
approvals: number;
userApprovers: { userId: string }[];
};

export type TGetSecretApprovalPoliciesDTO = {
Expand All @@ -26,14 +26,14 @@ export type TCreateSecretPolicyDTO = {
name?: string;
environment: string;
secretPath?: string | null;
approvers?: string[];
approverUserIds?: string[];
approvals?: number;
};

export type TUpdateSecretPolicyDTO = {
id: string;
name?: string;
approvers?: string[];
approverUserIds?: string[];
secretPath?: string | null;
approvals?: number;
// for invalidating list
Expand Down
34 changes: 30 additions & 4 deletions frontend/src/hooks/api/secretApprovalRequest/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,19 +47,45 @@ export type TSecretApprovalRequest<J extends unknown = EncryptedSecret> = {
isReplicated?: boolean;
slug: string;
createdAt: string;
committerId: string;
committerUserId: string;
reviewers: {
member: string;
userId: string;
status: ApprovalStatus;
email: string;
firstName: string;
lastName: string;
username: string;
}[];
workspace: string;
environment: string;
folderId: string;
secretPath: string;
hasMerged: boolean;
status: "open" | "close";
policy: TSecretApprovalPolicy;
statusChangeBy: string;
policy: Omit<TSecretApprovalPolicy, "approvers"> & {
approvers: {
userId: string;
email: string;
firstName: string;
lastName: string;
username: string;
}[];
};
statusChangedByUserId: string;
statusChangedByUser?: {
userId: string;
email: string;
firstName: string;
lastName: string;
username: string;
};
committerUser: {
userId: string;
email: string;
firstName: string;
lastName: string;
username: string;
};
conflicts: Array<{ secretId: string; op: CommitType.UPDATE }>;
commits: ({
// if there is no secret means it was creation
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import {
Button,
DeleteActionModal,
EmptyState,
Modal,
ModalContent,
Table,
TableContainer,
TableSkeleton,
Expand Down Expand Up @@ -145,13 +147,20 @@ export const SecretApprovalPolicyList = ({ workspaceId }: Props) => {
</TBody>
</Table>
</TableContainer>
<SecretPolicyForm
workspaceId={workspaceId}
<Modal
isOpen={popUp.secretPolicyForm.isOpen}
onToggle={(isOpen) => handlePopUpToggle("secretPolicyForm", isOpen)}
members={members}
editValues={popUp.secretPolicyForm.data as TSecretApprovalPolicy}
/>
onOpenChange={(isOpen) => handlePopUpToggle("secretPolicyForm", isOpen)}
>
<ModalContent title={popUp.secretPolicyForm.data ? "Edit policy" : "Create policy"}>
<SecretPolicyForm
workspaceId={workspaceId}
isOpen={popUp.secretPolicyForm.isOpen}
onToggle={(isOpen) => handlePopUpToggle("secretPolicyForm", isOpen)}
members={members}
editValues={popUp.secretPolicyForm.data as TSecretApprovalPolicy}
/>
</ModalContent>
</Modal>
<DeleteActionModal
isOpen={popUp.deletePolicy.isOpen}
deleteKey="remove"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ export const SecretApprovalPolicyRow = ({
{
workspaceId,
id: policy.id,
approvers: selectedApprovers
approverUserIds: selectedApprovers
},
{
onSettled: () => {
Expand All @@ -60,7 +60,7 @@ export const SecretApprovalPolicyRow = ({
}
);
} else {
setSelectedApprovers(policy.approvers);
setSelectedApprovers(policy.userApprovers.map(({ userId }) => userId));
}
}}
>
Expand All @@ -73,7 +73,9 @@ export const SecretApprovalPolicyRow = ({
>
<Input
isReadOnly
value={policy.approvers?.length ? `${policy.approvers.length} selected` : "None"}
value={
policy?.userApprovers.length ? `${policy.userApprovers.length} selected` : "None"
}
className="text-left"
/>
</DropdownMenuTrigger>
Expand All @@ -84,17 +86,17 @@ export const SecretApprovalPolicyRow = ({
<DropdownMenuLabel>
Select members that are allowed to approve changes
</DropdownMenuLabel>
{members?.map(({ id, user }) => {
const isChecked = selectedApprovers.includes(id);
{members?.map(({ user }) => {
const isChecked = selectedApprovers.includes(user.id);
return (
<DropdownMenuItem
onClick={(evt) => {
evt.preventDefault();
setSelectedApprovers((state) =>
isChecked ? state.filter((el) => el !== id) : [...state, id]
isChecked ? state.filter((el) => el !== user.id) : [...state, user.id]
);
}}
key={`create-policy-members-${id}`}
key={`create-policy-members-${user.id}`}
iconPos="right"
icon={isChecked && <FontAwesomeIcon icon={faCheckCircle} />}
>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { useEffect } from "react";
import { Controller, useForm } from "react-hook-form";
import { faCheckCircle } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
Expand All @@ -15,8 +14,6 @@ import {
DropdownMenuTrigger,
FormControl,
Input,
Modal,
ModalContent,
Select,
SelectItem
} from "@app/components/v2";
Expand All @@ -40,17 +37,16 @@ const formSchema = z
name: z.string().optional(),
secretPath: z.string().optional().nullable(),
approvals: z.number().min(1),
approvers: z.string().array().min(1)
approverUserIds: z.string().array().min(1)
})
.refine((data) => data.approvals <= data.approvers.length, {
.refine((data) => data.approvals <= data.approverUserIds.length, {
path: ["approvals"],
message: "The number of approvals should be lower than the number of approvers."
});

type TFormSchema = z.infer<typeof formSchema>;

export const SecretPolicyForm = ({
isOpen,
onToggle,
members = [],
workspaceId,
Expand All @@ -59,20 +55,22 @@ export const SecretPolicyForm = ({
const {
control,
handleSubmit,
reset,
watch,
formState: { isSubmitting }
} = useForm<TFormSchema>({
resolver: zodResolver(formSchema),
values: editValues ? { ...editValues, environment: editValues.environment.slug } : undefined
values: editValues
? {
...editValues,
approverUserIds: editValues.userApprovers.map(({ userId }) => userId),
environment: editValues.environment.slug
}
: undefined
});
const { currentWorkspace } = useWorkspace();
const selectedEnvironment = watch("environment");

const environments = currentWorkspace?.environments || [];
useEffect(() => {
if (!isOpen) reset({});
}, [isOpen]);

const isEditMode = Boolean(editValues);

Expand Down Expand Up @@ -131,8 +129,6 @@ export const SecretPolicyForm = ({
};

return (
<Modal isOpen={isOpen} onOpenChange={onToggle}>
<ModalContent title={isEditMode ? "Edit policy" : "Create policy"}>
<form onSubmit={handleSubmit(handleFormSubmit)}>
<Controller
control={control}
Expand All @@ -155,6 +151,7 @@ export const SecretPolicyForm = ({
errorText={error?.message}
>
<Select
isDisabled={isEditMode}
value={value}
onValueChange={(val) => onChange(val)}
className="w-full border border-mineshaft-500"
Expand Down Expand Up @@ -186,7 +183,7 @@ export const SecretPolicyForm = ({
/>
<Controller
control={control}
name="approvers"
name="approverUserIds"
render={({ field: { value, onChange }, fieldState: { error } }) => (
<FormControl
label="Approvers Required"
Expand All @@ -208,17 +205,19 @@ export const SecretPolicyForm = ({
<DropdownMenuLabel>
Select members that are allowed to approve changes
</DropdownMenuLabel>
{members.map(({ id, user }) => {
const isChecked = value?.includes(id);
{members.map(({ user }) => {
const isChecked = value?.includes(user.id);
return (
<DropdownMenuItem
onClick={(evt) => {
evt.preventDefault();
onChange(
isChecked ? value?.filter((el) => el !== id) : [...(value || []), id]
isChecked
? value?.filter((el) => el !== user.id)
: [...(value || []), user.id]
);
}}
key={`create-policy-members-${id}`}
key={`create-policy-members-${user.id}`}
iconPos="right"
icon={isChecked && <FontAwesomeIcon icon={faCheckCircle} />}
>
Expand Down Expand Up @@ -258,7 +257,6 @@ export const SecretPolicyForm = ({
</Button>
</div>
</form>
</ModalContent>
</Modal>

);
};
Loading

0 comments on commit ef3cdd1

Please sign in to comment.