diff --git a/frontend/src/pages/secret-manager/SecretApprovalsPage/SecretApprovalsPage.tsx b/frontend/src/pages/secret-manager/SecretApprovalsPage/SecretApprovalsPage.tsx index 5483dc597..a70a6a901 100644 --- a/frontend/src/pages/secret-manager/SecretApprovalsPage/SecretApprovalsPage.tsx +++ b/frontend/src/pages/secret-manager/SecretApprovalsPage/SecretApprovalsPage.tsx @@ -44,8 +44,7 @@ export const SecretApprovalsPage = () => {
-
- +
+
+
+ +
- {isMergable ? "Good to merge" : "Review required"} - - At least {approvals} approving review required - {Boolean(statusChangeByEmail) && `. Reopened by ${statusChangeByEmail}`} - - {isSoftEnforcement && !isMergable && canBypassApprovalPermission && ( -
- setByPassApproval(checked === true)} - isChecked={byPassApproval} - id="byPassApproval" - checkIndicatorBg="text-white" - className={twMerge( - "mr-2", - byPassApproval ? "border-red bg-red hover:bg-red-600" : "" - )} - > - - Merge without waiting for approval (bypass secret change policy) - - - {byPassApproval && ( - - setBypassReason(e.target.value)} - placeholder="Enter reason for bypass (min 10 chars)" - leftIcon={} - /> - - )} -
+

+ {isMergable ? "Good to merge" : "Merging is blocked"} +

+ {!isMergable && ( + + At least {approvals} approving review{`${approvals > 1 ? "s" : ""}`} required by + eligible reviewers. + {Boolean(statusChangeByEmail) && `. Reopened by ${statusChangeByEmail}`} + )}
-
+
+ {isSoftEnforcement && !isMergable && canBypassApprovalPermission && ( +
+ setByPassApproval(checked === true)} + isChecked={byPassApproval} + id="byPassApproval" + checkIndicatorBg="text-white" + className={twMerge( + "mr-2", + byPassApproval ? "border-red bg-red hover:bg-red-600" : "" + )} + > + + Merge without waiting for approval (bypass secret change policy) + + + {byPassApproval && ( + + setBypassReason(e.target.value)} + placeholder="Enter reason for bypass (min 10 chars)" + leftIcon={} + /> + + )} +
+ )} +
+
{canApprove || isSoftEnforcement ? ( - <> +
@@ -186,7 +199,7 @@ export const SecretApprovalRequestAction = ({ > Merge - +
) : (
Only approvers can merge
)} @@ -197,13 +210,13 @@ export const SecretApprovalRequestAction = ({ if (hasMerged && status === "close") return ( -
-
+
+
- Secret approval merged + Change request merged - Merged by {statusChangeByEmail} + Merged by {statusChangeByEmail}.
diff --git a/frontend/src/pages/secret-manager/SecretApprovalsPage/components/SecretApprovalRequest/components/SecretApprovalRequestChangeItem.tsx b/frontend/src/pages/secret-manager/SecretApprovalsPage/components/SecretApprovalRequest/components/SecretApprovalRequestChangeItem.tsx index 212f929f7..b7a6a8149 100644 --- a/frontend/src/pages/secret-manager/SecretApprovalsPage/components/SecretApprovalRequest/components/SecretApprovalRequestChangeItem.tsx +++ b/frontend/src/pages/secret-manager/SecretApprovalsPage/components/SecretApprovalRequest/components/SecretApprovalRequestChangeItem.tsx @@ -1,18 +1,18 @@ -import { faExclamationTriangle, faInfo, faKey } from "@fortawesome/free-solid-svg-icons"; +/* eslint-disable jsx-a11y/no-static-element-interactions */ +/* eslint-disable jsx-a11y/click-events-have-key-events */ +/* eslint-disable no-nested-ternary */ +import { useState } from "react"; +import { + faCircleXmark, + faExclamationTriangle, + faEye, + faEyeSlash, + faInfo, + faKey +} from "@fortawesome/free-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import { - SecretInput, - Table, - TableContainer, - Tag, - TBody, - Td, - Th, - THead, - Tooltip, - Tr -} from "@app/components/v2"; +import { Tag, Tooltip } from "@app/components/v2"; import { CommitType, SecretV3Raw, TSecretApprovalSecChange, WsTag } from "@app/hooks/api/types"; export type Props = { @@ -29,19 +29,19 @@ export type Props = { const generateItemTitle = (op: CommitType) => { let text = { label: "", color: "" }; - if (op === CommitType.CREATE) text = { label: "create", color: "#16a34a" }; - else if (op === CommitType.UPDATE) text = { label: "change", color: "#ea580c" }; - else text = { label: "deletion", color: "#b91c1c" }; + if (op === CommitType.CREATE) text = { label: "create", color: "#60DD00" }; + else if (op === CommitType.UPDATE) text = { label: "change", color: "#F8EB30" }; + else text = { label: "deletion", color: "#F83030" }; return ( - +
Request for secret {text.label} - +
); }; const generateConflictText = (op: CommitType) => { - if (op === CommitType.CREATE) return
Secret already exist
; + if (op === CommitType.CREATE) return
Secret already exists
; if (op === CommitType.UPDATE) return
Secret not found
; return null; }; @@ -59,10 +59,12 @@ export const SecretApprovalRequestChangeItem = ({ const itemConflict = hasMerged && conflicts.find((el) => el.op === op && el.secretId === newVersion?.id); const hasConflict = Boolean(itemConflict); + const [isOldSecretValueVisible, setIsOldSecretValueVisible] = useState(false); + const [isNewSecretValueVisible, setIsNewSecretValueVisible] = useState(false); return ( -
-
+
+
{generateItemTitle(op)}
{!hasMerged && isStale && (
@@ -79,48 +81,86 @@ export const SecretApprovalRequestChangeItem = ({
)}
- - - - - {op === CommitType.UPDATE && - - - - - - - {op === CommitType.UPDATE ? ( - - - - - - - - - - - - - - - - - - - ) : ( - - - - - - - - - + + +
+
Metadata
+ {newVersion?.secretMetadata?.length ? ( +
+ {newVersion.secretMetadata?.map((el) => ( +
+ + +
{el.key}
+
+ +
+ {el.value} +
+
+
+ ))} +
+ ) : ( +

-

+ )} +
+ + ) : ( +
+ {" "} + Secret not existent in the new version. +
)} -
} - SecretValueCommentTagsMetadata
OLD{secretVersion?.secretKey} +
+
+ {op === CommitType.UPDATE || op === CommitType.DELETE ? ( +
+
+ Legacy Secret +
+ + Deprecated +
+
+
+
Key
+
{secretVersion?.secretKey}
+
+
+
Value
+
{newVersion?.isRotatedSecret ? ( Rotated Secret value will not be affected ) : ( - - )} -
{secretVersion?.secretComment} - {secretVersion?.tags?.map(({ slug, id: tagId, color }) => ( - setIsOldSecretValueVisible(!isOldSecretValueVisible)} + className="flex flex-row items-center justify-between rounded-md border border-mineshaft-500 bg-mineshaft-900 pl-2" >
-
{slug}
- - ))} -
+ className={`flex font-mono ${isOldSecretValueVisible || !secretVersion?.secretValue ? "text-md py-[0.55rem]" : "text-lg"}`} + > + {isOldSecretValueVisible + ? secretVersion?.secretValue || "EMPTY" + : secretVersion?.secretValue + ? secretVersion?.secretValue?.split("").map(() => "•") + : "EMPTY"}{" "} + + {secretVersion?.secretValue && ( +
+ +
+ )} + + )} + + +
+
Comment
+
+ {secretVersion?.secretComment || ( + - + )}{" "} +
+
+
+
Tags
+
+ {(secretVersion?.tags?.length ?? 0) ? ( + secretVersion?.tags?.map(({ slug, id: tagId, color }) => ( + +
+
{slug}
+ + )) + ) : ( + - + )} +
+
+
+
Metadata
+
{secretVersion?.secretMetadata?.length ? (
{secretVersion.secretMetadata?.map((el) => ( @@ -146,93 +186,77 @@ export const SecretApprovalRequestChangeItem = ({ ) : (

-

)} -
NEW{newVersion?.secretKey} + + + + ) : ( +
+ {" "} + Secret not existent in the previous version. +
+ )} + {op === CommitType.UPDATE || op === CommitType.CREATE ? ( +
+
+ New Secret +
+ + Current +
+
+
+
Key
+
{newVersion?.secretKey}
+
+
+
Value
+
{newVersion?.isRotatedSecret ? ( Rotated Secret value will not be affected ) : ( - - )} -
{newVersion?.secretComment} - {newVersion?.tags?.map(({ slug, id: tagId, color }) => ( - setIsNewSecretValueVisible(!isNewSecretValueVisible)} + className="flex flex-row items-center justify-between rounded-md border border-mineshaft-500 bg-mineshaft-900 pl-2" >
-
{slug}
- - ))} -
- {newVersion?.secretMetadata?.length ? ( -
- {newVersion.secretMetadata?.map((el) => ( -
- - -
{el.key}
-
- -
- {el.value} -
-
+ className={`flex font-mono ${isNewSecretValueVisible || !newVersion?.secretValue ? "text-md py-[0.55rem]" : "text-lg"}`} + > + {isNewSecretValueVisible + ? newVersion?.secretValue || "EMPTY" + : newVersion?.secretValue + ? newVersion?.secretValue?.split("").map(() => "•") + : "EMPTY"}{" "} +
+ {newVersion?.secretValue && ( +
+
- ))} + )}
- ) : ( -

-

)} -
- {op === CommitType.CREATE ? newVersion?.secretKey : secretVersion?.secretKey} - - - - {op === CommitType.CREATE - ? newVersion?.secretComment - : secretVersion?.secretComment} - - {(op === CommitType.CREATE ? newVersion?.tags : secretVersion?.tags)?.map( - ({ slug, id: tagId, color }) => ( + + +
+
Comment
+
+ {newVersion?.secretComment || ( + - + )}{" "} +
+
+
+
Tags
+
+ {(newVersion?.tags?.length ?? 0) ? ( + newVersion?.tags?.map(({ slug, id: tagId, color }) => (
{slug}
- ) - )} -
- {newVersion?.secretMetadata?.length ? ( -
- {newVersion.secretMetadata?.map((el) => ( -
- - -
{el.key}
-
- -
- {el.value} -
-
-
- ))} -
+ )) ) : ( -

-

+ - )} -
-
+
+
); }; diff --git a/frontend/src/pages/secret-manager/SecretApprovalsPage/components/SecretApprovalRequest/components/SecretApprovalRequestChanges.tsx b/frontend/src/pages/secret-manager/SecretApprovalsPage/components/SecretApprovalRequest/components/SecretApprovalRequestChanges.tsx index 4eebc65f4..17046450e 100644 --- a/frontend/src/pages/secret-manager/SecretApprovalsPage/components/SecretApprovalRequest/components/SecretApprovalRequestChanges.tsx +++ b/frontend/src/pages/secret-manager/SecretApprovalsPage/components/SecretApprovalRequest/components/SecretApprovalRequestChanges.tsx @@ -13,6 +13,7 @@ import { import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { zodResolver } from "@hookform/resolvers/zod"; import { RadioGroup, RadioGroupIndicator, RadioGroupItem } from "@radix-ui/react-radio-group"; +import { format } from "date-fns"; import { twMerge } from "tailwind-merge"; import z from "zod"; @@ -51,7 +52,7 @@ export const generateCommitText = (commits: { op: CommitType }[] = []) => { text.push( {score[CommitType.CREATE]} secret{score[CommitType.CREATE] !== 1 && "s"} - created + created ); if (score[CommitType.UPDATE]) @@ -59,7 +60,7 @@ export const generateCommitText = (commits: { op: CommitType }[] = []) => { {Boolean(text.length) && ","} {score[CommitType.UPDATE]} secret{score[CommitType.UPDATE] !== 1 && "s"} - + {" "} updated @@ -70,7 +71,7 @@ export const generateCommitText = (commits: { op: CommitType }[] = []) => { {Boolean(text.length) && "and"} {score[CommitType.DELETE]} secret{score[CommitType.UPDATE] !== 1 && "s"} - deleted + deleted ); @@ -221,29 +222,32 @@ export const SecretApprovalRequestChanges = ({
-
+
{generateCommitText(secretApprovalRequestDetails.commits)} {secretApprovalRequestDetails.isReplicated && ( (replication) )}
-
- {secretApprovalRequestDetails?.committerUser?.firstName || ""} - {secretApprovalRequestDetails?.committerUser?.lastName || ""} ( - {secretApprovalRequestDetails?.committerUser?.email}) wants to change{" "} - {secretApprovalRequestDetails.commits.length} secret values in - +
+

+ {secretApprovalRequestDetails?.committerUser?.firstName || ""} + {secretApprovalRequestDetails?.committerUser?.lastName || ""} ( + {secretApprovalRequestDetails?.committerUser?.email}) wants to change{" "} + {secretApprovalRequestDetails.commits.length} secret values in +

+

{secretApprovalRequestDetails.environment} - -

-
+

+
+

-

- -
- {formatReservedPaths(secretApprovalRequestDetails.secretPath)} -
-
+

+

+ {formatReservedPaths(secretApprovalRequestDetails.secretPath)} +

@@ -255,17 +259,14 @@ export const SecretApprovalRequestChanges = ({ onOpenChange={(isOpen) => handlePopUpToggle("reviewChanges", isOpen)} > -
-
-
Finish your review
+
+
Finish your review
)} @@ -320,7 +321,7 @@ export const SecretApprovalRequestChanges = ({
@@ -376,14 +377,14 @@ export const SecretApprovalRequestChanges = ({ ) )}
-
+
{secretApprovalRequestDetails?.policy?.approvers .filter((requiredApprover) => reviewedUsers?.[requiredApprover.userId]) .map((requiredApprover) => { const reviewer = reviewedUsers?.[requiredApprover.userId]; return (
@@ -396,10 +397,11 @@ export const SecretApprovalRequestChanges = ({ > {reviewer?.status === ApprovalStatus.APPROVED ? "approved" : "rejected"} {" "} - the request. + the request on{" "} + {format(new Date(secretApprovalRequestDetails.createdAt), "PPpp zzz")}.
{reviewer?.comment && ( - + @@ -409,7 +411,7 @@ export const SecretApprovalRequestChanges = ({ ); })}
-
+
-
+
Reviewers
{secretApprovalRequestDetails?.policy?.approvers @@ -435,10 +437,10 @@ export const SecretApprovalRequestChanges = ({ const reviewer = reviewedUsers?.[requiredApprover.userId]; return (
-
+
)} - + {getReviewedStatusSymbol(reviewer?.status)}