feat(frontend): accept soft approvals on secret requests

This commit is contained in:
Alfonso Hernandez
2024-07-18 01:30:40 +02:00
parent aed310b9ee
commit 8a5a295a01
3 changed files with 33 additions and 9 deletions
@@ -177,7 +177,7 @@ export const ApprovalPolicyList = ({ workspaceId }: IProps) => {
<Button <Button
variant="plain" variant="plain"
colorSchema="secondary" colorSchema="secondary"
className="text-bunker-300" className="text-bunker-300 uppercase text-xs font-semibold"
rightIcon={<FontAwesomeIcon icon={faChevronDown} size="sm" className="ml-2" />} rightIcon={<FontAwesomeIcon icon={faChevronDown} size="sm" className="ml-2" />}
> >
Type Type
@@ -1,20 +1,22 @@
import React, { useState } from "react";
import { import {
faCheck, faCheck,
faClose, faClose,
faLandMineOn,
faLockOpen, faLockOpen,
faSquareCheck, faSquareCheck,
faSquareXmark, faSquareXmark,
faUserLock faUserLock} from "@fortawesome/free-solid-svg-icons";
} from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { twMerge } from "tailwind-merge"; import { twMerge } from "tailwind-merge";
import { createNotification } from "@app/components/notifications"; import { createNotification } from "@app/components/notifications";
import { Button } from "@app/components/v2"; import { Button, Checkbox } from "@app/components/v2";
import { import {
usePerformSecretApprovalRequestMerge, usePerformSecretApprovalRequestMerge,
useUpdateSecretApprovalRequestStatus useUpdateSecretApprovalRequestStatus
} from "@app/hooks/api"; } from "@app/hooks/api";
import { EnforcementLevel } from "@app/hooks/api/policies/enums";
type Props = { type Props = {
approvalRequestId: string; approvalRequestId: string;
@@ -25,6 +27,7 @@ type Props = {
canApprove?: boolean; canApprove?: boolean;
statusChangeByEmail?: string; statusChangeByEmail?: string;
workspaceId: string; workspaceId: string;
enforcementLevel: EnforcementLevel;
}; };
export const SecretApprovalRequestAction = ({ export const SecretApprovalRequestAction = ({
@@ -34,7 +37,8 @@ export const SecretApprovalRequestAction = ({
isMergable, isMergable,
approvals, approvals,
statusChangeByEmail, statusChangeByEmail,
workspaceId, workspaceId,
enforcementLevel,
canApprove canApprove
}: Props) => { }: Props) => {
const { mutateAsync: performSecretApprovalMerge, isLoading: isMerging } = const { mutateAsync: performSecretApprovalMerge, isLoading: isMerging } =
@@ -43,6 +47,8 @@ export const SecretApprovalRequestAction = ({
const { mutateAsync: updateSecretStatusChange, isLoading: isStatusChanging } = const { mutateAsync: updateSecretStatusChange, isLoading: isStatusChanging } =
useUpdateSecretApprovalRequestStatus(); useUpdateSecretApprovalRequestStatus();
const [byPassApproval, setByPassApproval] = useState(false);
const handleSecretApprovalRequestMerge = async () => { const handleSecretApprovalRequestMerge = async () => {
try { try {
await performSecretApprovalMerge({ await performSecretApprovalMerge({
@@ -82,6 +88,8 @@ export const SecretApprovalRequestAction = ({
} }
}; };
const isSoftEnforcement = enforcementLevel === EnforcementLevel.Soft;
if (!hasMerged && status === "open") { if (!hasMerged && status === "open") {
return ( return (
<div className="flex w-full items-center justify-between"> <div className="flex w-full items-center justify-between">
@@ -96,10 +104,25 @@ export const SecretApprovalRequestAction = ({
At least {approvals} approving review required At least {approvals} approving review required
{Boolean(statusChangeByEmail) && `. Reopened by ${statusChangeByEmail}`} {Boolean(statusChangeByEmail) && `. Reopened by ${statusChangeByEmail}`}
</span> </span>
{!canApprove && isSoftEnforcement && (
<div className="mt-1">
<Checkbox
onCheckedChange={(checked) => setByPassApproval(checked === true)}
isChecked={byPassApproval}
id="byPassApproval"
checkIndicatorBg="text-white"
className={byPassApproval ? "bg-red hover:bg-red-600 border-red" : ""}
>
<span className="text-red text-sm">
Merge without waiting for approval (by pass secrets protection)
</span>
</Checkbox>
</div>
)}
</span> </span>
</div> </div>
<div className="flex items-center space-x-2"> <div className="flex items-center space-x-2">
{canApprove ? ( {canApprove || isSoftEnforcement ? (
<> <>
<Button <Button
onClick={() => handleSecretApprovalStatusChange("close")} onClick={() => handleSecretApprovalStatusChange("close")}
@@ -111,11 +134,11 @@ export const SecretApprovalRequestAction = ({
Close request Close request
</Button> </Button>
<Button <Button
leftIcon={<FontAwesomeIcon icon={faCheck} />} leftIcon={<FontAwesomeIcon icon={isSoftEnforcement && !canApprove ? faLandMineOn : faCheck} />}
isDisabled={!isMergable} isDisabled={!isMergable || (!byPassApproval && !canApprove)}
isLoading={isMerging} isLoading={isMerging}
onClick={handleSecretApprovalRequestMerge} onClick={handleSecretApprovalRequestMerge}
colorSchema="primary" colorSchema={isSoftEnforcement && !canApprove ? "danger" : "primary"}
variant="solid" variant="solid"
> >
Merge Merge
@@ -252,6 +252,7 @@ export const SecretApprovalRequestChanges = ({
status={secretApprovalRequestDetails.status} status={secretApprovalRequestDetails.status}
isMergable={isMergable} isMergable={isMergable}
statusChangeByEmail={secretApprovalRequestDetails.statusChangedByUser?.email} statusChangeByEmail={secretApprovalRequestDetails.statusChangedByUser?.email}
enforcementLevel={secretApprovalRequestDetails.policy.enforcementLevel}
workspaceId={workspaceId} workspaceId={workspaceId}
/> />
</div> </div>