Merge branch 'daniel/scim-deprovisioning-ui' of https://github.com/Infisical/infisical into daniel/scim-deprovisioning-ui

This commit is contained in:
Daniel Hougaard
2025-08-13 02:48:22 +04:00
3 changed files with 62 additions and 6 deletions
@@ -43,6 +43,8 @@ import {
import { EnforcementLevel, PolicyType } from "@app/hooks/api/policies/enums";
import { TWorkspaceUser } from "@app/hooks/api/users/types";
import { PolicyMemberOption } from "./PolicyMemberOption";
type Props = {
isOpen?: boolean;
onToggle: (isOpen: boolean) => void;
@@ -59,7 +61,11 @@ const formSchema = z
secretPath: z.string().trim().min(1),
approvals: z.number().min(1).default(1),
userApprovers: z
.object({ type: z.literal(ApproverType.User), id: z.string() })
.object({
type: z.literal(ApproverType.User),
id: z.string(),
isOrgMembershipActive: z.boolean()
})
.array()
.default([]),
groupApprovers: z
@@ -80,7 +86,11 @@ const formSchema = z
sequenceApprovers: z
.object({
user: z
.object({ type: z.literal(ApproverType.User), id: z.string() })
.object({
type: z.literal(ApproverType.User),
id: z.string(),
isOrgMembershipActive: z.boolean()
})
.array()
.default([]),
group: z
@@ -139,7 +149,11 @@ const Form = ({
userApprovers:
editValues?.approvers
?.filter((approver) => approver.type === ApproverType.User)
.map(({ id, type }) => ({ id, type: type as ApproverType.User })) || [],
.map(({ id, type, isOrgMembershipActive }) => ({
id,
type: type as ApproverType.User,
isOrgMembershipActive
})) || [],
groupApprovers:
editValues?.approvers
?.filter((approver) => approver.type === ApproverType.Group)
@@ -333,7 +347,8 @@ const Form = ({
() =>
members.map((member) => ({
id: member.user.id,
type: ApproverType.User
type: ApproverType.User,
isOrgMembershipActive: member.user.isOrgMembershipActive
})),
[members]
);
@@ -612,6 +627,7 @@ const Form = ({
isMulti
placeholder="Select members..."
options={memberOptions}
components={{ Option: PolicyMemberOption }}
getOptionValue={(option) => option.id}
getOptionLabel={(option) => {
const member = members?.find((m) => m.user.id === option.id);
@@ -689,6 +705,7 @@ const Form = ({
menuPlacement="top"
isMulti
placeholder="Select members..."
components={{ Option: PolicyMemberOption }}
options={memberOptions}
getOptionValue={(option) => option.id}
getOptionLabel={(option) => {
@@ -0,0 +1,39 @@
import { components, OptionProps } from "react-select";
import { faCheckCircle } from "@fortawesome/free-regular-svg-icons";
import { faBan } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { twMerge } from "tailwind-merge";
import { Badge } from "@app/components/v2";
import { ApproverType } from "@app/hooks/api/accessApproval/types";
export const PolicyMemberOption = ({
isSelected,
children,
...props
}: OptionProps<{
id: string;
isOrgMembershipActive: boolean;
type: ApproverType;
}>) => {
return (
<components.Option isSelected={isSelected} {...props}>
<div className="flex flex-row items-center justify-between">
<p
className={twMerge("truncate", !props.data.isOrgMembershipActive && "text-mineshaft-400")}
>
{children}
</p>
{!props.data.isOrgMembershipActive && (
<Badge className="pointer-events-none ml-1 mr-auto flex h-5 w-min items-center gap-1.5 whitespace-nowrap bg-mineshaft-400/50 text-bunker-300">
<FontAwesomeIcon icon={faBan} />
Inactive
</Badge>
)}
{isSelected && (
<FontAwesomeIcon className="ml-2 text-primary" icon={faCheckCircle} size="sm" />
)}
</div>
</components.Option>
);
};
@@ -539,7 +539,7 @@ export const SecretApprovalRequestChanges = ({
)
.map((requiredApprover) => {
const reviewer = reviewedUsers?.[requiredApprover.userId];
const isOrgMembershipActive = requiredApprover.isOrgMembershipActive;
const { isOrgMembershipActive } = requiredApprover;
return (
<div
@@ -618,7 +618,7 @@ export const SecretApprovalRequestChanges = ({
)
.map((reviewer) => {
const status = reviewedUsers?.[reviewer.userId].status;
const isOrgMembershipActive = reviewer.isOrgMembershipActive;
const { isOrgMembershipActive } = reviewer;
return (
<div
className="flex flex-nowrap items-center justify-between space-x-2 rounded bg-mineshaft-800 px-2 py-1"