mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-06 07:26:45 +00:00
improvement: color/layout styling adjustments to change request page
This commit is contained in:
+1
-1
@@ -445,7 +445,7 @@ export const ReviewAccessRequestModal = ({
|
|||||||
onCheckedChange={(checked) => setBypassApproval(checked === true)}
|
onCheckedChange={(checked) => setBypassApproval(checked === true)}
|
||||||
isChecked={bypassApproval}
|
isChecked={bypassApproval}
|
||||||
id="byPassApproval"
|
id="byPassApproval"
|
||||||
className={twMerge("mr-2", bypassApproval ? "border-red/30 bg-red/10" : "")}
|
className={twMerge("mr-2", bypassApproval ? "!border-red/30 !bg-red/10" : "")}
|
||||||
>
|
>
|
||||||
<span className="text-xs text-red">
|
<span className="text-xs text-red">
|
||||||
Approve without waiting for requirements to be met (bypass policy protection)
|
Approve without waiting for requirements to be met (bypass policy protection)
|
||||||
|
|||||||
+75
-78
@@ -102,43 +102,73 @@ export const SecretApprovalRequestAction = ({
|
|||||||
|
|
||||||
if (!hasMerged && status === "open") {
|
if (!hasMerged && status === "open") {
|
||||||
return (
|
return (
|
||||||
<div className="flex w-full flex-col items-start justify-between py-4 transition-all">
|
<div className="flex w-full flex-col items-start justify-between py-4 text-mineshaft-100 transition-all">
|
||||||
<div className="flex items-center space-x-4 px-4">
|
<div className="flex w-full items-center justify-between">
|
||||||
<div
|
<div className="mr-auto flex items-center space-x-4 px-4">
|
||||||
className={`flex items-center justify-center rounded-full ${isMergable ? "h-10 w-10 bg-green" : "h-11 w-11 bg-red-600"}`}
|
<div
|
||||||
>
|
className={`flex items-center justify-center rounded-full ${isMergable ? "h-8 w-8 bg-green" : "h-10 w-10 bg-red-600"}`}
|
||||||
<FontAwesomeIcon
|
>
|
||||||
icon={isMergable ? faCheck : faXmark}
|
<FontAwesomeIcon
|
||||||
className={isMergable ? "text-lg text-black" : "text-2xl text-white"}
|
icon={isMergable ? faCheck : faXmark}
|
||||||
/>
|
className={isMergable ? "text-lg text-white" : "text-2xl text-white"}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<span className="flex flex-col">
|
||||||
|
<p className={`text-md font-medium ${isMergable && "text-lg"}`}>
|
||||||
|
{isMergable ? "Good to merge" : "Merging is blocked"}
|
||||||
|
</p>
|
||||||
|
{!isMergable && (
|
||||||
|
<span className="inline-block text-xs text-mineshaft-300">
|
||||||
|
At least {approvals} approving review{`${approvals > 1 ? "s" : ""}`} required by
|
||||||
|
eligible reviewers.
|
||||||
|
{Boolean(statusChangeByEmail) && `. Reopened by ${statusChangeByEmail}`}
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<span className="flex flex-col">
|
<div className="flex items-center justify-end space-x-2 px-4">
|
||||||
<p className={`text-md font-medium ${isMergable && "text-lg"}`}>
|
{canApprove || isSoftEnforcement ? (
|
||||||
{isMergable ? "Good to merge" : "Merging is blocked"}
|
<div className="flex items-center space-x-4">
|
||||||
</p>
|
<Button
|
||||||
{!isMergable && (
|
onClick={() => handleSecretApprovalStatusChange("close")}
|
||||||
<span className="inline-block text-xs text-bunker-200">
|
isLoading={isStatusChanging}
|
||||||
At least {approvals} approving review{`${approvals > 1 ? "s" : ""}`} required by
|
variant="outline_bg"
|
||||||
eligible reviewers.
|
colorSchema="primary"
|
||||||
{Boolean(statusChangeByEmail) && `. Reopened by ${statusChangeByEmail}`}
|
leftIcon={<FontAwesomeIcon icon={faClose} />}
|
||||||
</span>
|
className="hover:border-red/60 hover:bg-red/10"
|
||||||
|
>
|
||||||
|
Close request
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
leftIcon={<FontAwesomeIcon icon={!canApprove ? faLandMineOn : faCheck} />}
|
||||||
|
isDisabled={
|
||||||
|
!(
|
||||||
|
(isMergable && canApprove) ||
|
||||||
|
(isSoftEnforcement && byPassApproval && isValidBypassReason(bypassReason))
|
||||||
|
)
|
||||||
|
}
|
||||||
|
isLoading={isMerging}
|
||||||
|
onClick={handleSecretApprovalRequestMerge}
|
||||||
|
colorSchema={isSoftEnforcement && !canApprove ? "danger" : "primary"}
|
||||||
|
variant="outline_bg"
|
||||||
|
>
|
||||||
|
Merge
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<div className="text-sm text-mineshaft-400">Only approvers can merge</div>
|
||||||
)}
|
)}
|
||||||
</span>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{isSoftEnforcement && !isMergable && isBypasser && (
|
{isSoftEnforcement && !isMergable && isBypasser && (
|
||||||
<div
|
<div className="mt-4 w-full border-t border-mineshaft-600 px-5">
|
||||||
className={`mt-4 w-full border-mineshaft-600 px-5 ${isMergable ? "border-t pb-2" : "border-y pb-4"}`}
|
|
||||||
>
|
|
||||||
<div className="mt-2 flex flex-col space-y-2 pt-2">
|
<div className="mt-2 flex flex-col space-y-2 pt-2">
|
||||||
<Checkbox
|
<Checkbox
|
||||||
onCheckedChange={(checked) => setByPassApproval(checked === true)}
|
onCheckedChange={(checked) => setByPassApproval(checked === true)}
|
||||||
isChecked={byPassApproval}
|
isChecked={byPassApproval}
|
||||||
id="byPassApproval"
|
id="byPassApproval"
|
||||||
checkIndicatorBg="text-white"
|
checkIndicatorBg="text-white"
|
||||||
className={twMerge(
|
className={twMerge("mr-2", byPassApproval ? "!border-red/30 !bg-red/10" : "")}
|
||||||
"mr-2",
|
|
||||||
byPassApproval ? "border-red bg-red hover:bg-red-600" : ""
|
|
||||||
)}
|
|
||||||
>
|
>
|
||||||
<span className="text-sm">
|
<span className="text-sm">
|
||||||
Merge without waiting for approval (bypass secret change policy)
|
Merge without waiting for approval (bypass secret change policy)
|
||||||
@@ -162,51 +192,18 @@ export const SecretApprovalRequestAction = ({
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
<div className="mt-2 flex w-full items-center justify-end space-x-2 px-4">
|
|
||||||
{canApprove || isSoftEnforcement ? (
|
|
||||||
<div className="flex items-center space-x-4">
|
|
||||||
<Button
|
|
||||||
onClick={() => handleSecretApprovalStatusChange("close")}
|
|
||||||
isLoading={isStatusChanging}
|
|
||||||
variant="outline_bg"
|
|
||||||
colorSchema="primary"
|
|
||||||
leftIcon={<FontAwesomeIcon icon={faClose} />}
|
|
||||||
className="hover:border-red/60 hover:bg-red/10"
|
|
||||||
>
|
|
||||||
Close request
|
|
||||||
</Button>
|
|
||||||
<Button
|
|
||||||
leftIcon={<FontAwesomeIcon icon={!canApprove ? faLandMineOn : faCheck} />}
|
|
||||||
isDisabled={
|
|
||||||
!(
|
|
||||||
(isMergable && canApprove) ||
|
|
||||||
(isSoftEnforcement && byPassApproval && isValidBypassReason(bypassReason))
|
|
||||||
)
|
|
||||||
}
|
|
||||||
isLoading={isMerging}
|
|
||||||
onClick={handleSecretApprovalRequestMerge}
|
|
||||||
colorSchema={isSoftEnforcement && !canApprove ? "danger" : "primary"}
|
|
||||||
variant="solid"
|
|
||||||
>
|
|
||||||
Merge
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
) : (
|
|
||||||
<div>Only approvers can merge</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hasMerged && status === "close")
|
if (hasMerged && status === "close")
|
||||||
return (
|
return (
|
||||||
<div className="flex w-full items-center justify-between rounded-md border border-primary/60 bg-primary/10">
|
<div className="flex w-full items-center justify-between rounded-md border border-green/60 bg-green/10">
|
||||||
<div className="flex items-start space-x-4 p-4">
|
<div className="flex items-start space-x-2 p-4">
|
||||||
<FontAwesomeIcon icon={faCheck} className="pt-1 text-2xl text-primary" />
|
<FontAwesomeIcon icon={faCheck} className="mt-0.5 text-xl text-green" />
|
||||||
<span className="flex flex-col">
|
<span className="flex flex-col">
|
||||||
Change request merged
|
Change request merged
|
||||||
<span className="inline-block text-xs text-bunker-200">
|
<span className="inline-block text-xs text-mineshaft-300">
|
||||||
Merged by {statusChangeByEmail}.
|
Merged by {statusChangeByEmail}.
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
@@ -215,26 +212,26 @@ export const SecretApprovalRequestAction = ({
|
|||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex w-full items-center justify-between">
|
<div className="flex w-full items-center justify-between rounded-md border border-yellow/60 bg-yellow/10">
|
||||||
<div className="flex items-start space-x-4">
|
<div className="flex items-start space-x-2 p-4">
|
||||||
<FontAwesomeIcon icon={faUserLock} className="pt-1 text-2xl text-primary" />
|
<FontAwesomeIcon icon={faUserLock} className="mt-0.5 text-xl text-yellow" />
|
||||||
<span className="flex flex-col">
|
<span className="flex flex-col">
|
||||||
Secret approval has been closed
|
Secret approval has been closed
|
||||||
<span className="inline-block text-xs text-bunker-200">
|
<span className="inline-block text-xs text-mineshaft-300">
|
||||||
Closed by {statusChangeByEmail}
|
Closed by {statusChangeByEmail}
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex items-center space-x-6">
|
<Button
|
||||||
<Button
|
onClick={() => handleSecretApprovalStatusChange("open")}
|
||||||
onClick={() => handleSecretApprovalStatusChange("open")}
|
isLoading={isStatusChanging}
|
||||||
isLoading={isStatusChanging}
|
variant="plain"
|
||||||
variant="outline_bg"
|
colorSchema="secondary"
|
||||||
leftIcon={<FontAwesomeIcon icon={faLockOpen} />}
|
className="mr-4 text-yellow/60 hover:text-yellow"
|
||||||
>
|
leftIcon={<FontAwesomeIcon icon={faLockOpen} />}
|
||||||
Reopen request
|
>
|
||||||
</Button>
|
Reopen request
|
||||||
</div>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
+10
-9
@@ -3,6 +3,7 @@
|
|||||||
/* eslint-disable no-nested-ternary */
|
/* eslint-disable no-nested-ternary */
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import {
|
import {
|
||||||
|
faCircleCheck,
|
||||||
faCircleXmark,
|
faCircleXmark,
|
||||||
faExclamationTriangle,
|
faExclamationTriangle,
|
||||||
faEye,
|
faEye,
|
||||||
@@ -29,14 +30,14 @@ export type Props = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const generateItemTitle = (op: CommitType) => {
|
const generateItemTitle = (op: CommitType) => {
|
||||||
let text = { label: "", color: "" };
|
let text = { label: "", className: "" };
|
||||||
if (op === CommitType.CREATE) text = { label: "create", color: "#60DD00" };
|
if (op === CommitType.CREATE) text = { label: "create", className: "text-green-600" };
|
||||||
else if (op === CommitType.UPDATE) text = { label: "change", color: "#F8EB30" };
|
else if (op === CommitType.UPDATE) text = { label: "change", className: "text-yellow-600" };
|
||||||
else text = { label: "deletion", color: "#F83030" };
|
else text = { label: "deletion", className: "text-red-600" };
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="text-md pb-2 font-medium">
|
<div className="text-md pb-2 font-medium">
|
||||||
Request for <span style={{ color: text.color }}>secret {text.label}</span>
|
Request for <span className={text.className}>secret {text.label}</span>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
@@ -215,7 +216,7 @@ export const SecretApprovalRequestChangeItem = ({
|
|||||||
<div className="mb-4 flex flex-row justify-between">
|
<div className="mb-4 flex flex-row justify-between">
|
||||||
<span className="text-md font-medium">New Secret</span>
|
<span className="text-md font-medium">New Secret</span>
|
||||||
<div className="rounded-full bg-green-600 px-2 pb-[0.14rem] pt-[0.2rem] text-xs font-medium">
|
<div className="rounded-full bg-green-600 px-2 pb-[0.14rem] pt-[0.2rem] text-xs font-medium">
|
||||||
<FontAwesomeIcon icon={faCircleXmark} className="pr-1 text-white" />
|
<FontAwesomeIcon icon={faCircleCheck} className="pr-1 text-white" />
|
||||||
New
|
New
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -281,15 +282,15 @@ export const SecretApprovalRequestChangeItem = ({
|
|||||||
</div>
|
</div>
|
||||||
<div className="mb-2">
|
<div className="mb-2">
|
||||||
<div className="text-sm font-medium text-mineshaft-300">Tags</div>
|
<div className="text-sm font-medium text-mineshaft-300">Tags</div>
|
||||||
<div className="flex flex-wrap gap-2">
|
<div className="flex flex-wrap gap-y-2">
|
||||||
{(newVersion?.tags?.length ?? 0) ? (
|
{(newVersion?.tags?.length ?? 0) ? (
|
||||||
newVersion?.tags?.map(({ slug, id: tagId, color }) => (
|
newVersion?.tags?.map(({ slug, id: tagId, color }) => (
|
||||||
<Tag
|
<Tag
|
||||||
className="flex w-min items-center space-x-2"
|
className="flex w-min items-center space-x-1.5 border border-mineshaft-500 bg-mineshaft-800"
|
||||||
key={`${newVersion.id}-${tagId}`}
|
key={`${newVersion.id}-${tagId}`}
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
className="h-3 w-3 rounded-full"
|
className="h-2.5 w-2.5 rounded-full"
|
||||||
style={{ backgroundColor: color || "#bec2c8" }}
|
style={{ backgroundColor: color || "#bec2c8" }}
|
||||||
/>
|
/>
|
||||||
<div className="text-sm">{slug}</div>
|
<div className="text-sm">{slug}</div>
|
||||||
|
|||||||
+108
-97
@@ -3,12 +3,12 @@ import { Controller, useForm } from "react-hook-form";
|
|||||||
import {
|
import {
|
||||||
faAngleDown,
|
faAngleDown,
|
||||||
faArrowLeft,
|
faArrowLeft,
|
||||||
faCheckCircle,
|
faBan,
|
||||||
faCircle,
|
faCheck,
|
||||||
faCodeBranch,
|
faCodeBranch,
|
||||||
faComment,
|
faComment,
|
||||||
faFolder,
|
faFolder,
|
||||||
faXmarkCircle
|
faHourglass
|
||||||
} 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 { zodResolver } from "@hookform/resolvers/zod";
|
import { zodResolver } from "@hookform/resolvers/zod";
|
||||||
@@ -26,6 +26,7 @@ import {
|
|||||||
DropdownMenuTrigger,
|
DropdownMenuTrigger,
|
||||||
EmptyState,
|
EmptyState,
|
||||||
FormControl,
|
FormControl,
|
||||||
|
GenericFieldLabel,
|
||||||
IconButton,
|
IconButton,
|
||||||
TextArea,
|
TextArea,
|
||||||
Tooltip
|
Tooltip
|
||||||
@@ -81,10 +82,10 @@ export const generateCommitText = (commits: { op: CommitType }[] = [], isReplica
|
|||||||
|
|
||||||
const getReviewedStatusSymbol = (status?: ApprovalStatus) => {
|
const getReviewedStatusSymbol = (status?: ApprovalStatus) => {
|
||||||
if (status === ApprovalStatus.APPROVED)
|
if (status === ApprovalStatus.APPROVED)
|
||||||
return <FontAwesomeIcon icon={faCheckCircle} size="xs" style={{ color: "#15803d" }} />;
|
return <FontAwesomeIcon icon={faCheck} size="xs" className="text-green" />;
|
||||||
if (status === ApprovalStatus.REJECTED)
|
if (status === ApprovalStatus.REJECTED)
|
||||||
return <FontAwesomeIcon icon={faXmarkCircle} size="xs" style={{ color: "#b91c1c" }} />;
|
return <FontAwesomeIcon icon={faBan} size="xs" className="text-red" />;
|
||||||
return <FontAwesomeIcon icon={faCircle} size="xs" style={{ color: "#c2410c" }} />;
|
return <FontAwesomeIcon icon={faHourglass} size="xs" className="text-yellow" />;
|
||||||
};
|
};
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
@@ -242,17 +243,17 @@ export const SecretApprovalRequestChanges = ({
|
|||||||
: secretApprovalRequestDetails.status}
|
: secretApprovalRequestDetails.status}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex-grow flex-col">
|
<div className="-mt-0.5 flex-grow flex-col">
|
||||||
<div className="text-xl">
|
<div className="text-xl">
|
||||||
{generateCommitText(
|
{generateCommitText(
|
||||||
secretApprovalRequestDetails.commits,
|
secretApprovalRequestDetails.commits,
|
||||||
secretApprovalRequestDetails.isReplicated
|
secretApprovalRequestDetails.isReplicated
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div className="flex items-center space-x-2 text-xs text-gray-400">
|
<span className="-mt-1 flex items-center space-x-2 text-xs text-gray-400">
|
||||||
By {secretApprovalRequestDetails?.committerUser?.firstName} (
|
By {secretApprovalRequestDetails?.committerUser?.firstName} (
|
||||||
{secretApprovalRequestDetails?.committerUser?.email})
|
{secretApprovalRequestDetails?.committerUser?.email})
|
||||||
</div>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
{!hasMerged &&
|
{!hasMerged &&
|
||||||
secretApprovalRequestDetails.status === "open" &&
|
secretApprovalRequestDetails.status === "open" &&
|
||||||
@@ -262,7 +263,10 @@ export const SecretApprovalRequestChanges = ({
|
|||||||
onOpenChange={(isOpen) => handlePopUpToggle("reviewChanges", isOpen)}
|
onOpenChange={(isOpen) => handlePopUpToggle("reviewChanges", isOpen)}
|
||||||
>
|
>
|
||||||
<DropdownMenuTrigger asChild>
|
<DropdownMenuTrigger asChild>
|
||||||
<Button rightIcon={<FontAwesomeIcon className="ml-2" icon={faAngleDown} />}>
|
<Button
|
||||||
|
colorSchema="secondary"
|
||||||
|
rightIcon={<FontAwesomeIcon className="ml-2" icon={faAngleDown} />}
|
||||||
|
>
|
||||||
Review
|
Review
|
||||||
</Button>
|
</Button>
|
||||||
</DropdownMenuTrigger>
|
</DropdownMenuTrigger>
|
||||||
@@ -279,82 +283,87 @@ export const SecretApprovalRequestChanges = ({
|
|||||||
{...field}
|
{...field}
|
||||||
placeholder="Leave a comment..."
|
placeholder="Leave a comment..."
|
||||||
reSize="none"
|
reSize="none"
|
||||||
className="text-md mt-2 h-40 border border-mineshaft-600 bg-bunker-800"
|
className="text-md mt-2 h-40 border border-mineshaft-600 bg-mineshaft-800 placeholder:text-mineshaft-400"
|
||||||
/>
|
/>
|
||||||
</FormControl>
|
</FormControl>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
<Controller
|
<div className="flex justify-between">
|
||||||
control={control}
|
<Controller
|
||||||
name="status"
|
control={control}
|
||||||
defaultValue={ApprovalStatus.APPROVED}
|
name="status"
|
||||||
render={({ field, fieldState: { error } }) => (
|
defaultValue={ApprovalStatus.APPROVED}
|
||||||
<FormControl errorText={error?.message} isError={Boolean(error)}>
|
render={({ field, fieldState: { error } }) => (
|
||||||
<RadioGroup
|
<FormControl
|
||||||
value={field.value}
|
className="mb-0"
|
||||||
onValueChange={field.onChange}
|
errorText={error?.message}
|
||||||
className="mb-4 space-y-2"
|
isError={Boolean(error)}
|
||||||
aria-label="Status"
|
|
||||||
>
|
>
|
||||||
<div className="flex items-center gap-2">
|
<RadioGroup
|
||||||
<RadioGroupItem
|
value={field.value}
|
||||||
id="approve"
|
onValueChange={field.onChange}
|
||||||
className="h-4 w-4 rounded-full border border-gray-300 text-primary focus:ring-2 focus:ring-mineshaft-500"
|
className="space-y-2"
|
||||||
value={ApprovalStatus.APPROVED}
|
aria-label="Status"
|
||||||
aria-labelledby="approve-label"
|
>
|
||||||
>
|
<div className="flex items-center gap-2">
|
||||||
<RadioGroupIndicator className="flex h-full w-full items-center justify-center after:h-2 after:w-2 after:rounded-full after:bg-current" />
|
<RadioGroupItem
|
||||||
</RadioGroupItem>
|
id="approve"
|
||||||
<span
|
className="h-4 w-4 rounded-full border border-gray-400 text-green focus:ring-2 focus:ring-mineshaft-500"
|
||||||
id="approve-label"
|
value={ApprovalStatus.APPROVED}
|
||||||
className="cursor-pointer"
|
aria-labelledby="approve-label"
|
||||||
onClick={() => field.onChange(ApprovalStatus.APPROVED)}
|
>
|
||||||
onKeyDown={(e) => {
|
<RadioGroupIndicator className="flex h-full w-full items-center justify-center after:h-2 after:w-2 after:rounded-full after:bg-current" />
|
||||||
if (e.key === "Enter" || e.key === " ") {
|
</RadioGroupItem>
|
||||||
e.preventDefault();
|
<span
|
||||||
field.onChange(ApprovalStatus.APPROVED);
|
id="approve-label"
|
||||||
}
|
className="cursor-pointer"
|
||||||
}}
|
onClick={() => field.onChange(ApprovalStatus.APPROVED)}
|
||||||
tabIndex={0}
|
onKeyDown={(e) => {
|
||||||
role="button"
|
if (e.key === "Enter" || e.key === " ") {
|
||||||
>
|
e.preventDefault();
|
||||||
Approve
|
field.onChange(ApprovalStatus.APPROVED);
|
||||||
</span>
|
}
|
||||||
</div>
|
}}
|
||||||
<div className="flex items-center gap-2">
|
tabIndex={0}
|
||||||
<RadioGroupItem
|
role="button"
|
||||||
id="reject"
|
>
|
||||||
className="h-4 w-4 rounded-full border border-gray-300 text-red focus:ring-2 focus:ring-mineshaft-500"
|
Approve
|
||||||
value={ApprovalStatus.REJECTED}
|
</span>
|
||||||
aria-labelledby="reject-label"
|
</div>
|
||||||
>
|
<div className="flex items-center gap-2">
|
||||||
<RadioGroupIndicator className="flex h-full w-full items-center justify-center after:h-2 after:w-2 after:rounded-full after:bg-current" />
|
<RadioGroupItem
|
||||||
</RadioGroupItem>
|
id="reject"
|
||||||
<span
|
className="h-4 w-4 rounded-full border border-gray-400 text-red focus:ring-2 focus:ring-mineshaft-500"
|
||||||
id="reject-label"
|
value={ApprovalStatus.REJECTED}
|
||||||
className="cursor-pointer"
|
aria-labelledby="reject-label"
|
||||||
onClick={() => field.onChange(ApprovalStatus.REJECTED)}
|
>
|
||||||
onKeyDown={(e) => {
|
<RadioGroupIndicator className="flex h-full w-full items-center justify-center after:h-2 after:w-2 after:rounded-full after:bg-current" />
|
||||||
if (e.key === "Enter" || e.key === " ") {
|
</RadioGroupItem>
|
||||||
e.preventDefault();
|
<span
|
||||||
field.onChange(ApprovalStatus.REJECTED);
|
id="reject-label"
|
||||||
}
|
className="cursor-pointer"
|
||||||
}}
|
onClick={() => field.onChange(ApprovalStatus.REJECTED)}
|
||||||
tabIndex={0}
|
onKeyDown={(e) => {
|
||||||
role="button"
|
if (e.key === "Enter" || e.key === " ") {
|
||||||
>
|
e.preventDefault();
|
||||||
Reject
|
field.onChange(ApprovalStatus.REJECTED);
|
||||||
</span>
|
}
|
||||||
</div>
|
}}
|
||||||
</RadioGroup>
|
tabIndex={0}
|
||||||
</FormControl>
|
role="button"
|
||||||
)}
|
>
|
||||||
/>
|
Reject
|
||||||
<div className="flex justify-end">
|
</span>
|
||||||
|
</div>
|
||||||
|
</RadioGroup>
|
||||||
|
</FormControl>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
<Button
|
<Button
|
||||||
type="submit"
|
type="submit"
|
||||||
isLoading={isApproving || isRejecting || isSubmitting}
|
isLoading={isApproving || isRejecting || isSubmitting}
|
||||||
variant="outline_bg"
|
variant="outline_bg"
|
||||||
|
className="mt-auto h-min"
|
||||||
>
|
>
|
||||||
Submit Review
|
Submit Review
|
||||||
</Button>
|
</Button>
|
||||||
@@ -371,14 +380,14 @@ export const SecretApprovalRequestChanges = ({
|
|||||||
<div className="text-sm text-bunker-300">
|
<div className="text-sm text-bunker-300">
|
||||||
A secret import in
|
A secret import in
|
||||||
<p
|
<p
|
||||||
className="mx-1 inline rounded bg-primary-600/40 text-primary-300"
|
className="mx-1 inline rounded bg-mineshaft-600/80 text-mineshaft-300"
|
||||||
style={{ padding: "2px 4px" }}
|
style={{ padding: "2px 4px" }}
|
||||||
>
|
>
|
||||||
{secretApprovalRequestDetails?.environment}
|
{secretApprovalRequestDetails?.environment}
|
||||||
</p>
|
</p>
|
||||||
<div className="mr-2 inline-flex w-min items-center rounded border border-mineshaft-500 pl-1 pr-2">
|
<div className="mr-1 inline-flex w-min items-center rounded border border-mineshaft-500 pl-1.5 pr-2">
|
||||||
<p className="cursor-default border-r border-mineshaft-500 pr-1">
|
<p className="cursor-default border-r border-mineshaft-500 pr-1.5">
|
||||||
<FontAwesomeIcon icon={faFolder} className="text-primary" size="sm" />
|
<FontAwesomeIcon icon={faFolder} className="text-yellow" size="sm" />
|
||||||
</p>
|
</p>
|
||||||
<Tooltip content={approvalSecretPath}>
|
<Tooltip content={approvalSecretPath}>
|
||||||
<p
|
<p
|
||||||
@@ -391,14 +400,14 @@ export const SecretApprovalRequestChanges = ({
|
|||||||
</div>
|
</div>
|
||||||
has pending changes to be accepted from its source at{" "}
|
has pending changes to be accepted from its source at{" "}
|
||||||
<p
|
<p
|
||||||
className="mx-1 inline rounded bg-primary-600/40 text-primary-300"
|
className="mx-1 inline rounded bg-mineshaft-600/80 text-mineshaft-300"
|
||||||
style={{ padding: "2px 4px" }}
|
style={{ padding: "2px 4px" }}
|
||||||
>
|
>
|
||||||
{replicatedImport?.importEnv?.slug}
|
{replicatedImport?.importEnv?.slug}
|
||||||
</p>
|
</p>
|
||||||
<div className="inline-flex w-min items-center rounded border border-mineshaft-500 pl-1 pr-2">
|
<div className="mr-1 inline-flex w-min items-center rounded border border-mineshaft-500 pl-1.5 pr-2">
|
||||||
<p className="cursor-default border-r border-mineshaft-500 pr-1">
|
<p className="cursor-default border-r border-mineshaft-500 pr-1.5">
|
||||||
<FontAwesomeIcon icon={faFolder} className="text-primary" size="sm" />
|
<FontAwesomeIcon icon={faFolder} className="text-yellow" size="sm" />
|
||||||
</p>
|
</p>
|
||||||
<Tooltip content={replicatedImport?.importPath}>
|
<Tooltip content={replicatedImport?.importPath}>
|
||||||
<p
|
<p
|
||||||
@@ -415,14 +424,14 @@ export const SecretApprovalRequestChanges = ({
|
|||||||
<div className="text-sm text-bunker-300">
|
<div className="text-sm text-bunker-300">
|
||||||
<p className="inline">Secret(s) in</p>
|
<p className="inline">Secret(s) in</p>
|
||||||
<p
|
<p
|
||||||
className="mx-1 inline rounded bg-primary-600/40 text-primary-300"
|
className="mx-1 inline rounded bg-mineshaft-600/80 text-mineshaft-300"
|
||||||
style={{ padding: "2px 4px" }}
|
style={{ padding: "2px 4px" }}
|
||||||
>
|
>
|
||||||
{secretApprovalRequestDetails?.environment}
|
{secretApprovalRequestDetails?.environment}
|
||||||
</p>
|
</p>
|
||||||
<div className="mr-1 inline-flex w-min items-center rounded border border-mineshaft-500 pl-1 pr-2">
|
<div className="mr-1 inline-flex w-min items-center rounded border border-mineshaft-500 pl-1.5 pr-2">
|
||||||
<p className="cursor-default border-r border-mineshaft-500 pr-1">
|
<p className="cursor-default border-r border-mineshaft-500 pr-1.5">
|
||||||
<FontAwesomeIcon icon={faFolder} className="text-primary" size="sm" />
|
<FontAwesomeIcon icon={faFolder} className="text-yellow" size="sm" />
|
||||||
</p>
|
</p>
|
||||||
<Tooltip content={formatReservedPaths(secretApprovalRequestDetails.secretPath)}>
|
<Tooltip content={formatReservedPaths(secretApprovalRequestDetails.secretPath)}>
|
||||||
<p
|
<p
|
||||||
@@ -463,7 +472,7 @@ export const SecretApprovalRequestChanges = ({
|
|||||||
const reviewer = reviewedUsers?.[requiredApprover.userId];
|
const reviewer = reviewedUsers?.[requiredApprover.userId];
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className="flex w-full flex-col rounded-md bg-mineshaft-800 p-4"
|
className="flex w-full flex-col rounded-md bg-mineshaft-800 p-4 text-sm text-mineshaft-100"
|
||||||
key={`required-approver-${requiredApprover.userId}`}
|
key={`required-approver-${requiredApprover.userId}`}
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
@@ -477,14 +486,16 @@ export const SecretApprovalRequestChanges = ({
|
|||||||
{reviewer?.status === ApprovalStatus.APPROVED ? "approved" : "rejected"}
|
{reviewer?.status === ApprovalStatus.APPROVED ? "approved" : "rejected"}
|
||||||
</span>{" "}
|
</span>{" "}
|
||||||
the request on{" "}
|
the request on{" "}
|
||||||
{format(new Date(secretApprovalRequestDetails.createdAt), "PPpp zzz")}.
|
{format(
|
||||||
|
new Date(secretApprovalRequestDetails.createdAt),
|
||||||
|
"MM/dd/yyyy h:mm:ss aa"
|
||||||
|
)}
|
||||||
|
.
|
||||||
</div>
|
</div>
|
||||||
{reviewer?.comment && (
|
{reviewer?.comment && (
|
||||||
<FormControl label="Comment" className="mb-0 mt-4">
|
<GenericFieldLabel label="Comment" className="mt-2">
|
||||||
<TextArea value={reviewer.comment} isDisabled reSize="none">
|
{reviewer?.comment && reviewer.comment}
|
||||||
{reviewer?.comment && reviewer.comment}
|
</GenericFieldLabel>
|
||||||
</TextArea>
|
|
||||||
</FormControl>
|
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
@@ -505,7 +516,7 @@ export const SecretApprovalRequestChanges = ({
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="sticky top-0 w-1/5 cursor-default pt-4" style={{ minWidth: "240px" }}>
|
<div className="sticky top-0 w-1/5 cursor-default pt-2" style={{ minWidth: "240px" }}>
|
||||||
<div className="text-sm text-bunker-300">Reviewers</div>
|
<div className="text-sm text-bunker-300">Reviewers</div>
|
||||||
<div className="mt-2 flex flex-col space-y-2 text-sm">
|
<div className="mt-2 flex flex-col space-y-2 text-sm">
|
||||||
{secretApprovalRequestDetails?.policy?.approvers
|
{secretApprovalRequestDetails?.policy?.approvers
|
||||||
|
|||||||
Reference in New Issue
Block a user