diff --git a/frontend/src/views/SecretApprovalPage/components/AccessApprovalRequest/AccessApprovalRequest.tsx b/frontend/src/views/SecretApprovalPage/components/AccessApprovalRequest/AccessApprovalRequest.tsx
index b6d69d0c9..235737d4a 100644
--- a/frontend/src/views/SecretApprovalPage/components/AccessApprovalRequest/AccessApprovalRequest.tsx
+++ b/frontend/src/views/SecretApprovalPage/components/AccessApprovalRequest/AccessApprovalRequest.tsx
@@ -1,6 +1,6 @@
/* eslint-disable no-nested-ternary */
/* eslint-disable react/jsx-no-useless-fragment */
-import { useCallback, useMemo, useState } from "react";
+import { useMemo, useState } from "react";
import {
faCheck,
faCheckCircle,
@@ -11,10 +11,7 @@ import {
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { formatDistance } from "date-fns";
import { AnimatePresence, motion } from "framer-motion";
-import ms from "ms";
-import { twMerge } from "tailwind-merge";
-import { createNotification } from "@app/components/notifications";
import {
Button,
DropdownMenu,
@@ -23,11 +20,10 @@ import {
DropdownMenuLabel,
DropdownMenuTrigger,
EmptyState,
- Modal,
- ModalContent,
Tooltip,
UpgradePlanModal
} from "@app/components/v2";
+import { Badge } from "@app/components/v2/Badge";
import {
ProjectPermissionActions,
ProjectPermissionSub,
@@ -36,7 +32,7 @@ import {
useWorkspace
} from "@app/context";
import { usePopUp } from "@app/hooks";
-import { useGetWorkspaceUsers, useReviewAccessRequest } from "@app/hooks/api";
+import { useGetWorkspaceUsers } from "@app/hooks/api";
import {
accessApprovalKeys,
useGetAccessApprovalPolicies,
@@ -44,192 +40,11 @@ import {
useGetAccessRequestsCount
} from "@app/hooks/api/accessApproval/queries";
import { TAccessApprovalRequest } from "@app/hooks/api/accessApproval/types";
-import { ApprovalStatus, TAccessApprovalPolicy, TWorkspaceUser } from "@app/hooks/api/types";
+import { ApprovalStatus, TWorkspaceUser } from "@app/hooks/api/types";
import { queryClient } from "@app/reactQuery";
-import { SpecificPrivilegeSecretForm } from "@app/views/Project/MembersPage/components/MemberListTab/MemberRoleForm/SpecificPrivilegeSection";
-const DisplayBadge = ({ text, className }: { text: string; className?: string }) => {
- return (
-
- {text}
-
- );
-};
-
-const ReviewRequestModal = ({
- isOpen,
- onOpenChange,
- request,
- projectSlug,
- selectedRequester,
- selectedEnvSlug
-}: {
- isOpen: boolean;
- onOpenChange: (isOpen: boolean) => void;
- request: TAccessApprovalRequest & { user: TWorkspaceUser["user"] | null };
- projectSlug: string;
- selectedRequester: string | undefined;
- selectedEnvSlug: string | undefined;
-}) => {
- const [isLoading, setIsLoading] = useState<"approved" | "rejected" | null>(null);
-
- const accessDetails = {
- env: request.environmentName,
- // secret path will be inside $glob operator
- secretPath: request.policy.secretPath,
- read: request.permissions?.some(({ action }) => action.includes(ProjectPermissionActions.Read)),
- edit: request.permissions?.some(({ action }) => action.includes(ProjectPermissionActions.Edit)),
- create: request.permissions?.some(({ action }) =>
- action.includes(ProjectPermissionActions.Create)
- ),
- delete: request.permissions?.some(({ action }) =>
- action.includes(ProjectPermissionActions.Delete)
- ),
-
- temporaryAccess: {
- isTemporary: request.isTemporary,
- temporaryRange: request.temporaryRange
- }
- };
-
- const requestedAccess = useMemo(() => {
- const access: string[] = [];
- if (accessDetails.read) access.push("Read");
- if (accessDetails.edit) access.push("Edit");
- if (accessDetails.create) access.push("Create");
- if (accessDetails.delete) access.push("Delete");
-
- return access.join(", ");
- }, [accessDetails]);
-
- const getAccessLabel = () => {
- if (!accessDetails.temporaryAccess.isTemporary || !accessDetails.temporaryAccess.temporaryRange)
- return "Permanent";
-
- // convert the range to human readable format
- ms(ms(accessDetails.temporaryAccess.temporaryRange), { long: true });
-
- return (
-
- );
- };
-
- const reviewAccessRequest = useReviewAccessRequest();
-
- const handleReview = useCallback(async (status: "approved" | "rejected") => {
- setIsLoading(status);
- try {
- await reviewAccessRequest.mutateAsync({
- requestId: request.id,
- status,
- projectSlug,
- envSlug: selectedEnvSlug,
- requestedBy: selectedRequester
- });
- } catch (error) {
- console.error(error);
- setIsLoading(null);
- return;
- }
-
- createNotification({
- title: `Request ${status}`,
- text: `The request has been ${status}`,
- type: status === "approved" ? "success" : "info"
- });
-
- setIsLoading(null);
- onOpenChange(false);
- }, []);
-
- return (
-
-
-
-
-
- {request.user?.firstName} {request.user?.lastName} ({request.user?.email})
- {" "}
- is requesting access to the following resource:
-
-
-
-
- Requested path:
-
-
-
-
- Permissions:
-
-
-
-
- Access Type:
- {getAccessLabel()}
-
-
-
-
-
-
-
-
-
-
- );
-};
-
-const SelectAccessModal = ({
- isOpen,
- onOpenChange,
- policies
-}: {
- isOpen: boolean;
- onOpenChange: (isOpen: boolean) => void;
- policies: TAccessApprovalPolicy[];
-}) => {
- return (
-
-
- onOpenChange(false)} policies={policies} />
-
-
- );
-};
+import { RequestAccessModal } from "./components/RequestAccessModal";
+import { ReviewAccessRequestModal } from "./components/ReviewAccessModal";
const generateRequestText = (request: TAccessApprovalRequest, membershipId: string) => {
const { isTemporary } = request;
@@ -249,7 +64,7 @@ const generateRequestText = (request: TAccessApprovalRequest, membershipId: stri
{request.requestedBy === membershipId && (
-
+ Requested By You
)}
@@ -331,29 +146,30 @@ export const AccessApprovalRequest = ({
({ member }) => member === membership.id
)?.status;
- let displayData: { label: string; colorClass: string } = { label: "", colorClass: "" };
+ let displayData: { label: string; type: "primary" | "danger" | "success" } = {
+ label: "",
+ type: "primary"
+ };
const isExpired =
request.privilege &&
request.isApproved &&
new Date() > new Date(request.privilege.temporaryAccessEndTime || ("" as string));
- if (isExpired) displayData = { label: "Access Expired", colorClass: "bg-red/20 text-red" };
- else if (isAccepted)
- displayData = { label: "Access Granted", colorClass: "bg-green/20 text-green" };
- else if (isRejectedByAnyone)
- displayData = { label: "Rejected", colorClass: "bg-red/20 text-red" };
+ if (isExpired) displayData = { label: "Access Expired", type: "danger" };
+ else if (isAccepted) displayData = { label: "Access Granted", type: "success" };
+ else if (isRejectedByAnyone) displayData = { label: "Rejected", type: "danger" };
else if (userReviewStatus === ApprovalStatus.APPROVED) {
displayData = {
label: `Pending ${request.policy.approvals - request.reviewers.length} review${
request.policy.approvals - request.reviewers.length > 1 ? "s" : ""
}`,
- colorClass: "bg-yellow/20 text-yellow"
+ type: "primary"
};
} else if (!isReviewedByUser)
displayData = {
label: "Review Required",
- colorClass: "bg-yellow/20 text-yellow"
+ type: "primary"
};
return {
@@ -486,7 +302,7 @@ export const AccessApprovalRequest = ({
icon={requestedByFilter === id && }
iconPos="right"
>
- {user.email}
+ {user.username}
))}
@@ -564,10 +380,9 @@ export const AccessApprovalRequest = ({
{details.isApprover && (
-
+
+ {details.displayData.label}
+
)}
@@ -581,7 +396,7 @@ export const AccessApprovalRequest = ({
{!!policies && (
- {
@@ -598,7 +413,7 @@ export const AccessApprovalRequest = ({
)}
{!!selectedRequest && (
-