Merge branch 'main' into fix/cli-jwt-issue

This commit is contained in:
x032205
2025-06-19 19:19:12 -04:00
5 changed files with 457 additions and 461 deletions
@@ -35,7 +35,7 @@ export type Approver = {
id: string; id: string;
type: ApproverType; type: ApproverType;
sequence?: number; sequence?: number;
approvals?: number; approvalsRequired?: number;
}; };
export type Bypasser = { export type Bypasser = {
@@ -185,7 +185,7 @@ export const ReviewAccessRequestModal = ({
return acc; return acc;
} }
const approvals = curr.approvals || policy.approvals; const approvals = curr.approvalsRequired || policy.approvals;
const sequence = curr.sequence || 1; const sequence = curr.sequence || 1;
acc.push( acc.push(
@@ -19,6 +19,8 @@ import {
DropdownMenuLabel, DropdownMenuLabel,
DropdownMenuTrigger, DropdownMenuTrigger,
EmptyState, EmptyState,
Modal,
ModalContent,
Table, Table,
TableContainer, TableContainer,
TableSkeleton, TableSkeleton,
@@ -264,6 +266,19 @@ export const ApprovalPolicyList = ({ workspaceId }: IProps) => {
</TBody> </TBody>
</Table> </Table>
</TableContainer> </TableContainer>
<Modal
isOpen={popUp.policyForm.isOpen}
onOpenChange={(isOpen) => handlePopUpToggle("policyForm", isOpen)}
>
<ModalContent
className="max-w-3xl"
title={
popUp.policyForm.data
? `Edit ${popUp?.policyForm?.data?.name || "Policy"}`
: "Create Policy"
}
id="policy-form"
>
<AccessPolicyForm <AccessPolicyForm
projectId={currentWorkspace.id} projectId={currentWorkspace.id}
projectSlug={currentWorkspace.slug} projectSlug={currentWorkspace.slug}
@@ -272,6 +287,8 @@ export const ApprovalPolicyList = ({ workspaceId }: IProps) => {
members={members} members={members}
editValues={popUp.policyForm.data as TAccessApprovalPolicy} editValues={popUp.policyForm.data as TAccessApprovalPolicy}
/> />
</ModalContent>
</Modal>
<DeleteActionModal <DeleteActionModal
isOpen={popUp.deletePolicy.isOpen} isOpen={popUp.deletePolicy.isOpen}
deleteKey="remove" deleteKey="remove"
@@ -1,4 +1,4 @@
import { useEffect, useMemo, useRef, useState } from "react"; import { useEffect, useMemo, useState } from "react";
import { Controller, useFieldArray, useForm } from "react-hook-form"; import { Controller, useFieldArray, useForm } from "react-hook-form";
import { faGripVertical, faTrash } from "@fortawesome/free-solid-svg-icons"; import { faGripVertical, faTrash } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
@@ -13,8 +13,6 @@ import {
FormControl, FormControl,
IconButton, IconButton,
Input, Input,
Modal,
ModalContent,
Select, Select,
SelectItem, SelectItem,
Switch, Switch,
@@ -122,7 +120,6 @@ export const AccessPolicyForm = ({
}: Props) => { }: Props) => {
const [draggedItem, setDraggedItem] = useState<number | null>(null); const [draggedItem, setDraggedItem] = useState<number | null>(null);
const [dragOverItem, setDragOverItem] = useState<number | null>(null); const [dragOverItem, setDragOverItem] = useState<number | null>(null);
const modalContainer = useRef<HTMLDivElement>(null);
const { const {
control, control,
handleSubmit, handleSubmit,
@@ -153,15 +150,13 @@ export const AccessPolicyForm = ({
.map(({ id, type }) => ({ id, type: type as BypasserType.Group })) || [], .map(({ id, type }) => ({ id, type: type as BypasserType.Group })) || [],
approvals: editValues?.approvals, approvals: editValues?.approvals,
allowedSelfApprovals: editValues?.allowedSelfApprovals, allowedSelfApprovals: editValues?.allowedSelfApprovals,
sequenceApprovers: editValues.approvers sequenceApprovers: editValues.approvers?.reduce(
?.sort((a, b) => (a?.sequence || 0) - (b?.sequence || 0))
.reduce(
(acc, curr) => { (acc, curr) => {
if (acc.length && acc[acc.length - 1].sequence === curr.sequence) { if (acc.length && acc[acc.length - 1].sequence === curr.sequence) {
acc[acc.length - 1][curr.type]?.push(curr); acc[acc.length - 1][curr.type]?.push(curr);
return acc; return acc;
} }
const approvals = curr.approvals || editValues.approvals; const approvals = curr.approvalsRequired || editValues.approvals;
acc.push( acc.push(
curr.type === ApproverType.User curr.type === ApproverType.User
? { ? {
@@ -178,9 +173,11 @@ export const AccessPolicyForm = ({
) )
} as TFormSchema) } as TFormSchema)
: undefined, : undefined,
defaultValues: { defaultValues: !editValues
? {
sequenceApprovers: [{ approvals: 1 }] sequenceApprovers: [{ approvals: 1 }]
} }
: undefined
}); });
const sequenceApproversFieldArray = useFieldArray({ const sequenceApproversFieldArray = useFieldArray({
control, control,
@@ -204,7 +201,6 @@ export const AccessPolicyForm = ({
const { mutateAsync: createSecretApprovalPolicy } = useCreateSecretApprovalPolicy(); const { mutateAsync: createSecretApprovalPolicy } = useCreateSecretApprovalPolicy();
const { mutateAsync: updateSecretApprovalPolicy } = useUpdateSecretApprovalPolicy(); const { mutateAsync: updateSecretApprovalPolicy } = useUpdateSecretApprovalPolicy();
const policyName = policyDetails[watch("policyType")]?.name || "Policy";
const enforcementLevel = watch("enforcementLevel"); const enforcementLevel = watch("enforcementLevel");
const formUserBypassers = watch("userBypassers"); const formUserBypassers = watch("userBypassers");
@@ -391,14 +387,7 @@ export const AccessPolicyForm = ({
setDraggedItem(null); setDraggedItem(null);
setDragOverItem(null); setDragOverItem(null);
}; };
return ( return (
<Modal isOpen={isOpen} onOpenChange={onToggle}>
<ModalContent
className="max-w-3xl"
ref={modalContainer}
title={isEditMode ? `Edit ${policyName}` : "Create Policy"}
>
<div className="flex flex-col space-y-3"> <div className="flex flex-col space-y-3">
<form onSubmit={handleSubmit(handleFormSubmit)}> <form onSubmit={handleSubmit(handleFormSubmit)}>
<div className="flex items-center gap-x-3"> <div className="flex items-center gap-x-3">
@@ -583,7 +572,7 @@ export const AccessPolicyForm = ({
className="flex-grow" className="flex-grow"
> >
<FilterableSelect <FilterableSelect
menuPortalTarget={modalContainer.current} menuPortalTarget={document.getElementById("policy-form")}
menuPlacement="top" menuPlacement="top"
isMulti isMulti
placeholder="Select members..." placeholder="Select members..."
@@ -613,7 +602,7 @@ export const AccessPolicyForm = ({
className="flex-grow" className="flex-grow"
> >
<FilterableSelect <FilterableSelect
menuPortalTarget={modalContainer.current} menuPortalTarget={document.getElementById("policy-form")}
menuPlacement="top" menuPlacement="top"
isMulti isMulti
placeholder="Select groups..." placeholder="Select groups..."
@@ -697,8 +686,7 @@ export const AccessPolicyForm = ({
options={groupOptions} options={groupOptions}
getOptionValue={(option) => option.id} getOptionValue={(option) => option.id}
getOptionLabel={(option) => getOptionLabel={(option) =>
groups?.find(({ group }) => group.id === option.id)?.group.name ?? groups?.find(({ group }) => group.id === option.id)?.group.name ?? option.id
option.id
} }
value={value} value={value}
onChange={onChange} onChange={onChange}
@@ -713,11 +701,7 @@ export const AccessPolicyForm = ({
name="allowedSelfApprovals" name="allowedSelfApprovals"
defaultValue defaultValue
render={({ field: { value, onChange }, fieldState: { error } }) => ( render={({ field: { value, onChange }, fieldState: { error } }) => (
<FormControl <FormControl label="Self Approvals" isError={Boolean(error)} errorText={error?.message}>
label="Self Approvals"
isError={Boolean(error)}
errorText={error?.message}
>
<Switch <Switch
id="self-approvals" id="self-approvals"
thumbClassName="bg-mineshaft-800" thumbClassName="bg-mineshaft-800"
@@ -744,9 +728,7 @@ export const AccessPolicyForm = ({
id="bypass-approvals" id="bypass-approvals"
thumbClassName="bg-mineshaft-800" thumbClassName="bg-mineshaft-800"
isChecked={value === EnforcementLevel.Soft} isChecked={value === EnforcementLevel.Soft}
onCheckedChange={(v) => onCheckedChange={(v) => onChange(v ? EnforcementLevel.Soft : EnforcementLevel.Hard)}
onChange(v ? EnforcementLevel.Soft : EnforcementLevel.Hard)
}
> >
Allow certain users to bypass policy in break-glass situations Allow certain users to bypass policy in break-glass situations
</Switch> </Switch>
@@ -802,8 +784,7 @@ export const AccessPolicyForm = ({
options={bypasserGroupOptions} options={bypasserGroupOptions}
getOptionValue={(option) => option.id} getOptionValue={(option) => option.id}
getOptionLabel={(option) => getOptionLabel={(option) =>
groups?.find(({ group }) => group.id === option.id)?.group.name ?? groups?.find(({ group }) => group.id === option.id)?.group.name ?? option.id
option.id
} }
value={value} value={value}
onChange={onChange} onChange={onChange}
@@ -830,7 +811,5 @@ export const AccessPolicyForm = ({
</div> </div>
</form> </form>
</div> </div>
</ModalContent>
</Modal>
); );
}; };
@@ -59,11 +59,11 @@ export const ApprovalPolicyRow = ({
const sortedSteps = policy.approvers?.sort((a, b) => (a?.sequence || 0) - (b?.sequence || 0)); const sortedSteps = policy.approvers?.sort((a, b) => (a?.sequence || 0) - (b?.sequence || 0));
const entityInSameSequence = sortedSteps?.reduce( const entityInSameSequence = sortedSteps?.reduce(
(acc, curr) => { (acc, curr) => {
if (acc.length && acc[acc.length - 1].sequence === curr.sequence) { if (acc.length && acc[acc.length - 1].sequence === (curr.sequence || 1)) {
acc[acc.length - 1][curr.type]?.push(curr); acc[acc.length - 1][curr.type]?.push(curr);
return acc; return acc;
} }
const approvals = curr.approvals || policy.approvals; const approvals = curr.approvalsRequired || policy.approvals;
acc.push( acc.push(
curr.type === ApproverType.User curr.type === ApproverType.User
? { user: [curr], group: [], sequence: 1, approvals } ? { user: [curr], group: [], sequence: 1, approvals }