This commit is contained in:
Scott Wilson
2025-07-18 22:54:18 -07:00
parent 80743997e1
commit 0dba359f96
6 changed files with 219 additions and 164 deletions
@@ -20,7 +20,7 @@ export const getDefaultOnPremFeatures = (): TFeatureSet => ({
identitiesUsed: 0, identitiesUsed: 0,
dynamicSecret: false, dynamicSecret: false,
secretVersioning: true, secretVersioning: true,
pitRecovery: false, pitRecovery: true,
ipAllowlisting: false, ipAllowlisting: false,
rbac: false, rbac: false,
githubOrgSync: false, githubOrgSync: false,
@@ -40,7 +40,7 @@ export const getDefaultOnPremFeatures = (): TFeatureSet => ({
status: null, status: null,
trial_end: null, trial_end: null,
has_used_trial: true, has_used_trial: true,
secretApproval: false, secretApproval: true,
secretRotation: false, secretRotation: false,
caCrl: false, caCrl: false,
instanceUserManagement: false, instanceUserManagement: false,
@@ -156,11 +156,11 @@ 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">
{(secretVersion?.tags?.length ?? 0) ? ( {(secretVersion?.tags?.length ?? 0) ? (
secretVersion?.tags?.map(({ slug, id: tagId, color }) => ( secretVersion?.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={`${secretVersion.id}-${tagId}`} key={`${secretVersion.id}-${tagId}`}
> >
<div <div
@@ -291,7 +291,7 @@ const createBatchModeStore: StateCreator<CombinedState, [], [], BatchModeState>
if (change.type === PendingAction.Create && existingFolder) { if (change.type === PendingAction.Create && existingFolder) {
createNotification({ createNotification({
text: "Another folder with same name already exists", text: "A folder with this name already exists",
type: "error" type: "error"
}); });
return { pendingChanges: newChanges }; return { pendingChanges: newChanges };
@@ -302,7 +302,7 @@ const createBatchModeStore: StateCreator<CombinedState, [], [], BatchModeState>
existingFolder existingFolder
) { ) {
createNotification({ createNotification({
text: "Another folder with same name already exists", text: "A folder with this name already exists",
type: "error" type: "error"
}); });
return { pendingChanges: newChanges }; return { pendingChanges: newChanges };
@@ -322,7 +322,7 @@ const createBatchModeStore: StateCreator<CombinedState, [], [], BatchModeState>
if (change.type === PendingAction.Create && existingSecret) { if (change.type === PendingAction.Create && existingSecret) {
createNotification({ createNotification({
text: "Another secret with same name already exists", text: "A secret with this name already exists",
type: "error" type: "error"
}); });
return { pendingChanges: newChanges }; return { pendingChanges: newChanges };
@@ -343,7 +343,7 @@ const createBatchModeStore: StateCreator<CombinedState, [], [], BatchModeState>
if (existingNewSecretName) { if (existingNewSecretName) {
createNotification({ createNotification({
text: "Another secret with same name already exists", text: "A secret with this name already exists",
type: "error" type: "error"
}); });
return { pendingChanges: newChanges }; return { pendingChanges: newChanges };
@@ -1,9 +1,19 @@
/* eslint-disable jsx-a11y/label-has-associated-control */ /* eslint-disable jsx-a11y/label-has-associated-control */
import React, { useState } from "react"; import React, { useState } from "react";
import { faCodeCommit, faEye, faFolder, faKey, faTrash } from "@fortawesome/free-solid-svg-icons"; import {
faChevronDown,
faChevronRight,
faCodeCommit,
faEye,
faFolder,
faKey,
faTrash
} from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { twMerge } from "tailwind-merge";
import { Badge, Button, IconButton, Input, Modal, ModalContent, Tooltip } from "@app/components/v2"; import { Badge, Button, IconButton, Input, Modal, ModalContent, Tooltip } from "@app/components/v2";
import { useToggle } from "@app/hooks";
import { PendingAction } from "@app/hooks/api/secretFolders/types"; import { PendingAction } from "@app/hooks/api/secretFolders/types";
import { import {
@@ -39,7 +49,7 @@ const TagsList: React.FC<{ tags?: { id: string; slug: string }[]; className?: st
return ( return (
<div className={`flex flex-wrap gap-1 ${className}`}> <div className={`flex flex-wrap gap-1 ${className}`}>
{tags.map((tag) => ( {tags.map((tag) => (
<Badge key={tag.id} variant="primary" className="text-xs"> <Badge key={tag.id} variant="success" className="text-xs">
{tag.slug} {tag.slug}
</Badge> </Badge>
))} ))}
@@ -79,12 +89,14 @@ const ComparisonTableRow: React.FC<{
return ( return (
<tr className="border-b border-mineshaft-700 last:border-b-0"> <tr className="border-b border-mineshaft-700 last:border-b-0">
<td className="w-24 py-3 pl-4 align-top font-medium text-mineshaft-300">{label}:</td> <td className="w-[12%] border-r border-mineshaft-600 px-4 py-3 align-top font-medium text-mineshaft-300">
<td className="w-1/2 px-3 py-3 align-top"> {label}
</td>
<td className="w-1/2 border-r border-mineshaft-600 px-4 py-3 align-top">
<div className="text-red-400 opacity-80">{previousValue}</div> <div className="text-red-400 opacity-80">{previousValue}</div>
</td> </td>
<td className="w-1/2 py-3 pr-4 align-top"> <td className="w-1/2 py-3 pr-4 align-top">
<div className="text-green-400">{newValue}</div> <div className="px-4 text-green-400">{newValue}</div>
</td> </td>
</tr> </tr>
); );
@@ -96,6 +108,8 @@ const ChangeTable: React.FC<ChangeTableProps> = ({
workspaceId, workspaceId,
secretPath secretPath
}) => { }) => {
const [isOpen, setIsOpen] = useToggle(true);
const getChangeBadge = (type: PendingChange["type"]) => { const getChangeBadge = (type: PendingChange["type"]) => {
switch (type) { switch (type) {
case PendingAction.Create: case PendingAction.Create:
@@ -114,7 +128,7 @@ const ChangeTable: React.FC<ChangeTableProps> = ({
if (change.type === PendingAction.Create) { if (change.type === PendingAction.Create) {
return ( return (
<div className="mt-3 overflow-hidden rounded-md border border-mineshaft-700 bg-mineshaft-900"> <div className="overflow-hidden rounded-md bg-mineshaft-900/80">
<table className="w-full text-sm"> <table className="w-full text-sm">
<tbody> <tbody>
<tr className="border-b border-mineshaft-700"> <tr className="border-b border-mineshaft-700">
@@ -185,83 +199,85 @@ const ChangeTable: React.FC<ChangeTableProps> = ({
if (!hasChanges) return null; if (!hasChanges) return null;
return ( return (
<div className="mt-3 overflow-hidden rounded-md border border-mineshaft-700 bg-mineshaft-900"> <table className="w-full text-sm">
<table className="w-full text-sm"> <tbody>
<tbody> {hasKeyChange && (
{hasKeyChange && ( <ComparisonTableRow
<ComparisonTableRow label="Key"
label="Key" previousValue={<span className="font-mono">{change.existingSecret.key}</span>}
previousValue={<span className="font-mono">{change.existingSecret.key}</span>} newValue={<span className="font-mono">{change.newSecretName}</span>}
newValue={<span className="font-mono">{change.newSecretName}</span>} />
/> )}
)} {hasValueChange && (
{hasValueChange && ( <ComparisonTableRow
<ComparisonTableRow label="Value"
label="Value" previousValue={
previousValue={ <div className="max-w-md break-all rounded">
<div className="max-w-md break-all rounded"> {change.existingSecret.value || (
{change.existingSecret.value || <span className="italic">(empty)</span>} <span className="italic text-mineshaft-400">(empty)</span>
</div> )}
} </div>
newValue={ }
<div className="max-w-md break-all rounded"> newValue={
{change.secretValue || <span className="italic">(empty)</span>} <div className="max-w-md break-all rounded">
</div> {change.secretValue || (
} <span className="italic text-mineshaft-400">(empty)</span>
/> )}
)} </div>
{hasCommentChange && ( }
<ComparisonTableRow />
label="Comment" )}
previousValue={ {hasCommentChange && (
change.existingSecret.comment || <span className="italic">(empty)</span> <ComparisonTableRow
} label="Comment"
newValue={change.secretComment || <span className="italic">(empty)</span>} previousValue={
/> change.existingSecret.comment || (
)} <span className="italic text-mineshaft-400">(empty)</span>
{hasMultilineChange && ( )
<ComparisonTableRow }
label="Multi-line Encoding" newValue={
previousValue={ change.secretComment || <span className="italic text-mineshaft-400">(empty)</span>
change.existingSecret.skipMultilineEncoding ? "Enabled" : "Disabled" }
} />
newValue={change.skipMultilineEncoding ? "Enabled" : "Disabled"} )}
/> {hasMultilineChange && (
)} <ComparisonTableRow
{hasTagsChange && ( label="Multi-line Encoding"
<ComparisonTableRow previousValue={change.existingSecret.skipMultilineEncoding ? "Enabled" : "Disabled"}
label="Tags" newValue={change.skipMultilineEncoding ? "Enabled" : "Disabled"}
previousValue={<TagsList tags={change.existingSecret.tags} />} />
newValue={<TagsList tags={change.tags} />} )}
/> {hasTagsChange && (
)} <ComparisonTableRow
{hasMetadataChange && ( label="Tags"
<ComparisonTableRow previousValue={<TagsList tags={change.existingSecret.tags} />}
label="Metadata" newValue={<TagsList tags={change.tags} />}
previousValue={<MetadataList metadata={change.existingSecret.secretMetadata} />} />
newValue={<MetadataList metadata={change.secretMetadata} />} )}
/> {hasMetadataChange && (
)} <ComparisonTableRow
</tbody> label="Metadata"
</table> previousValue={<MetadataList metadata={change.existingSecret.secretMetadata} />}
</div> newValue={<MetadataList metadata={change.secretMetadata} />}
/>
)}
</tbody>
</table>
); );
} }
if (change.type === PendingAction.Delete) { if (change.type === PendingAction.Delete) {
return ( return (
<div className="mt-3 overflow-hidden rounded-md border border-mineshaft-700 bg-mineshaft-900"> <table className="w-full text-sm">
<table className="w-full text-sm"> <tbody>
<tbody> <tr className="border-b border-mineshaft-700">
<tr className="border-b border-mineshaft-700"> <td className="w-24 py-3 pl-4 font-medium text-red-400">Key:</td>
<td className="w-24 py-3 pl-4 font-medium text-red-400">Key:</td> <td className="px-3 py-3 font-mono text-red-400 line-through" colSpan={2}>
<td className="px-3 py-3 font-mono text-red-400 line-through" colSpan={2}> {change.secretKey}
{change.secretKey} </td>
</td> </tr>
</tr> </tbody>
</tbody> </table>
</table>
</div>
); );
} }
@@ -273,26 +289,24 @@ const ChangeTable: React.FC<ChangeTableProps> = ({
if (change.type === PendingAction.Create) { if (change.type === PendingAction.Create) {
return ( return (
<div className="mt-3 overflow-hidden rounded-md border border-mineshaft-700 bg-mineshaft-900"> <table className="w-full text-sm">
<table className="w-full text-sm"> <tbody>
<tbody> <tr className="border-b border-mineshaft-700">
<tr className="border-b border-mineshaft-700"> <td className="w-24 py-3 pl-4 font-medium text-mineshaft-300">Name:</td>
<td className="w-24 py-3 pl-4 font-medium text-mineshaft-300">Name:</td> <td className="px-3 py-3 font-mono text-mineshaft-100" colSpan={2}>
<td className="px-3 py-3 font-mono text-mineshaft-100" colSpan={2}> {change.folderName}
{change.folderName} </td>
</tr>
{change.description !== undefined && change.description !== "" && (
<tr className="border-b border-mineshaft-700 last:border-b-0">
<td className="w-24 py-3 pl-4 font-medium text-mineshaft-300">Description:</td>
<td className="px-3 py-3 text-mineshaft-100" colSpan={2}>
{change.description}
</td> </td>
</tr> </tr>
{change.description !== undefined && change.description !== "" && ( )}
<tr className="border-b border-mineshaft-700 last:border-b-0"> </tbody>
<td className="w-24 py-3 pl-4 font-medium text-mineshaft-300">Description:</td> </table>
<td className="px-3 py-3 text-mineshaft-100" colSpan={2}>
{change.description}
</td>
</tr>
)}
</tbody>
</table>
</div>
); );
} }
@@ -305,45 +319,41 @@ const ChangeTable: React.FC<ChangeTableProps> = ({
if (!hasChanges) return null; if (!hasChanges) return null;
return ( return (
<div className="mt-3 overflow-hidden rounded-md border border-mineshaft-700 bg-mineshaft-900"> <table className="w-full text-sm">
<table className="w-full text-sm"> <tbody>
<tbody> {hasNameChange && (
{hasNameChange && ( <ComparisonTableRow
<ComparisonTableRow label="Name"
label="Name" previousValue={<span className="font-mono">{change.originalFolderName}</span>}
previousValue={<span className="font-mono">{change.originalFolderName}</span>} newValue={<span className="font-mono">{change.folderName}</span>}
newValue={<span className="font-mono">{change.folderName}</span>} />
/> )}
)} {hasDescriptionChange && (
{hasDescriptionChange && ( <ComparisonTableRow
<ComparisonTableRow label="Description"
label="Description" previousValue={
previousValue={ change.originalDescription || <span className="italic">(empty)</span>
change.originalDescription || <span className="italic">(empty)</span> }
} newValue={change.description || <span className="italic">(empty)</span>}
newValue={change.description || <span className="italic">(empty)</span>} />
/> )}
)} </tbody>
</tbody> </table>
</table>
</div>
); );
} }
if (change.type === PendingAction.Delete) { if (change.type === PendingAction.Delete) {
return ( return (
<div className="mt-3 overflow-hidden rounded-md border border-mineshaft-700 bg-mineshaft-900"> <table className="w-full text-sm">
<table className="w-full text-sm"> <tbody>
<tbody> <tr className="border-b border-mineshaft-700">
<tr className="border-b border-mineshaft-700"> <td className="w-24 py-3 pl-4 font-medium text-red-400">Name:</td>
<td className="w-24 py-3 pl-4 font-medium text-red-400">Name:</td> <td className="px-3 py-3 font-mono text-red-400 line-through" colSpan={2}>
<td className="px-3 py-3 font-mono text-red-400 line-through" colSpan={2}> {change.folderName}
{change.folderName} </td>
</td> </tr>
</tr> </tbody>
</tbody> </table>
</table>
</div>
); );
} }
@@ -372,6 +382,49 @@ const ChangeTable: React.FC<ChangeTableProps> = ({
}); });
}; };
return (
<div className="overflow-clip rounded-t-none border border-t-0 border-mineshaft-600 bg-mineshaft-800 first:rounded-t-md first:border-t last:rounded-b-md last:border-b">
<div
className={twMerge(
"flex h-12 cursor-pointer items-center border-mineshaft-600 px-3.5 py-2 text-sm text-gray-300",
isOpen && "border-b"
)}
role="button"
tabIndex={0}
onClick={() => setIsOpen.toggle()}
onKeyDown={(e) => {
if (e.key === "Enter") {
setIsOpen.toggle();
}
}}
>
<FontAwesomeIcon className="mr-3 w-4" icon={isOpen ? faChevronDown : faChevronRight} />
<div className="flex flex-1 items-center gap-1.5 text-sm">
{getChangeName()}
{getChangeBadge(change.type)}
</div>
<Tooltip content="Discard change">
<IconButton
ariaLabel="delete-change"
variant="plain"
colorSchema="danger"
size="sm"
onClick={() => handleDeletePending(change.resourceType, change.id)}
>
<FontAwesomeIcon icon={faTrash} />
</IconButton>
</Tooltip>
</div>
{isOpen ? (
<div className="overflow-hidden bg-mineshaft-900">
{change.resourceType === "secret" ? renderSecretChanges() : renderFolderChanges()}
</div>
) : null}
</div>
);
return ( return (
<div className="py-2 shadow-sm"> <div className="py-2 shadow-sm">
<div className="flex items-center justify-between"> <div className="flex items-center justify-between">
@@ -432,32 +485,35 @@ export const CommitForm: React.FC<CommitFormProps> = ({
{/* Floating Panel */} {/* Floating Panel */}
{!isModalOpen && ( {!isModalOpen && (
<div className="fixed bottom-4 z-40 w-64 self-center rounded-lg border border-mineshaft-600 bg-mineshaft-800 shadow-2xl"> <div className="fixed bottom-4 z-40 w-64 self-center rounded-lg border border-mineshaft-600 bg-mineshaft-800 shadow-2xl">
<div className="flex w-full justify-center border-b border-mineshaft-600 px-4 py-3"> <div className="flex w-full justify-center border-b border-mineshaft-600 p-2">
<div className="flex w-full items-center justify-between"> <div className="flex w-full items-center justify-between">
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
<FontAwesomeIcon icon={faCodeCommit} className="text-primary" /> <FontAwesomeIcon icon={faCodeCommit} className="text-mineshaft-400" />
<span className="font-medium text-mineshaft-100">Ready to Commit</span> <span className="font-medium text-mineshaft-100">Pending Changes</span>
</div> </div>
<Badge variant="primary" className="text-xs"> <Badge variant="primary" className="text-xs">
{totalChangesCount} change{totalChangesCount !== 1 ? "s" : ""} {totalChangesCount} Change{totalChangesCount !== 1 ? "s" : ""}
</Badge> </Badge>
</div> </div>
</div> </div>
<div className="flex justify-center gap-4 p-3"> <div className="flex justify-center gap-2 p-2">
<Button <Button
size="sm"
leftIcon={<FontAwesomeIcon icon={faTrash} />} leftIcon={<FontAwesomeIcon icon={faTrash} />}
onClick={() => clearAllPendingChanges({ workspaceId, environment, secretPath })} onClick={() => clearAllPendingChanges({ workspaceId, environment, secretPath })}
isDisabled={totalChangesCount === 0} isDisabled={totalChangesCount === 0}
colorSchema="secondary" variant="outline_bg"
className="h-8 flex-1 hover:border-red/40 hover:bg-red/[0.1]"
> >
Discard Discard
</Button> </Button>
<Button <Button
variant="outline_bg"
leftIcon={<FontAwesomeIcon icon={faEye} />} leftIcon={<FontAwesomeIcon icon={faEye} />}
onClick={() => setIsModalOpen(true)} onClick={() => setIsModalOpen(true)}
isDisabled={totalChangesCount === 0} isDisabled={totalChangesCount === 0}
colorSchema="secondary" className="h-8 flex-1"
> >
Review Review
</Button> </Button>
@@ -470,23 +526,20 @@ export const CommitForm: React.FC<CommitFormProps> = ({
<ModalContent <ModalContent
title={ title={
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
<FontAwesomeIcon icon={faCodeCommit} className="text-primary" /> <FontAwesomeIcon icon={faCodeCommit} className="text-mineshaft-400" />
Commit Changes Commit Changes
<Badge variant="primary" className="ml-2"> <Badge variant="primary" className="mt-[0.05rem]">
{totalChangesCount} change{totalChangesCount !== 1 ? "s" : ""} {totalChangesCount} Change{totalChangesCount !== 1 ? "s" : ""}
</Badge> </Badge>
</div> </div>
} }
subTitle={"Write a commit message and review the changes you&apos;re about to commit."}
className="max-h-[90vh] max-w-5xl" className="max-h-[90vh] max-w-5xl"
> >
<div className="space-y-6"> <div className="space-y-6">
<p className="text-mineshaft-300">
Write a commit message and review the changes you&apos;re about to commit.
</p>
{/* Changes List */} {/* Changes List */}
<div className="space-y-6"> <div className="space-y-6">
<div className="max-h-96 space-y-4 overflow-y-auto pr-2"> <div className="max-h-[50vh] space-y-4 overflow-y-auto rounded-md border border-mineshaft-600 bg-bunker-800 p-4 shadow-inner">
{/* Folder Changes */} {/* Folder Changes */}
{pendingChanges.folders.length > 0 && ( {pendingChanges.folders.length > 0 && (
<div> <div>
@@ -494,7 +547,7 @@ export const CommitForm: React.FC<CommitFormProps> = ({
<FontAwesomeIcon icon={faFolder} className="text-mineshaft-300" /> <FontAwesomeIcon icon={faFolder} className="text-mineshaft-300" />
Folders ({pendingChanges.folders.length}) Folders ({pendingChanges.folders.length})
</h4> </h4>
<div className="space-y-3"> <div>
{pendingChanges.folders.map((change) => ( {pendingChanges.folders.map((change) => (
<ChangeTable <ChangeTable
key={change.id} key={change.id}
@@ -511,11 +564,11 @@ export const CommitForm: React.FC<CommitFormProps> = ({
{/* Secret Changes */} {/* Secret Changes */}
{pendingChanges.secrets.length > 0 && ( {pendingChanges.secrets.length > 0 && (
<div> <div>
<h4 className="mb-4 flex items-center gap-2 border-b border-mineshaft-700 pb-2 text-sm font-semibold text-mineshaft-200"> <h4 className="mb-2 flex items-center gap-2 px-2 text-sm text-mineshaft-300">
<FontAwesomeIcon icon={faKey} className="text-mineshaft-300" /> <FontAwesomeIcon icon={faKey} className="mr-1 text-mineshaft-300" />
Secrets ({pendingChanges.secrets.length}) Secrets ({pendingChanges.secrets.length})
</h4> </h4>
<div className="space-y-3"> <div>
{pendingChanges.secrets.map((change) => ( {pendingChanges.secrets.map((change) => (
<ChangeTable <ChangeTable
key={change.id} key={change.id}
@@ -546,9 +599,10 @@ export const CommitForm: React.FC<CommitFormProps> = ({
</div> </div>
{/* Action Buttons */} {/* Action Buttons */}
<div className="flex justify-end gap-3 border-t border-mineshaft-600 pt-4"> <div className="flex justify-end gap-3">
<Button <Button
variant="outline_bg" variant="plain"
colorSchema="secondary"
onClick={() => setIsModalOpen(false)} onClick={() => setIsModalOpen(false)}
isDisabled={isCommitting} isDisabled={isCommitting}
> >
@@ -560,6 +614,7 @@ export const CommitForm: React.FC<CommitFormProps> = ({
isDisabled={isCommitting || !commitMessage.trim()} isDisabled={isCommitting || !commitMessage.trim()}
leftIcon={<FontAwesomeIcon icon={faCodeCommit} />} leftIcon={<FontAwesomeIcon icon={faCodeCommit} />}
colorSchema="primary" colorSchema="primary"
variant="outline_bg"
> >
{isCommitting ? "Committing..." : "Commit Changes"} {isCommitting ? "Committing..." : "Commit Changes"}
</Button> </Button>
@@ -1088,7 +1088,7 @@ export const SecretDetailSidebar = ({
isDisabled={isSubmitting || !isDirty || !isAllowed} isDisabled={isSubmitting || !isDirty || !isAllowed}
isLoading={isSubmitting} isLoading={isSubmitting}
> >
Save Changes Apply Changes
</Button> </Button>
)} )}
</ProjectPermissionCan> </ProjectPermissionCan>
@@ -38,7 +38,7 @@ import { WsTag } from "@app/hooks/api/types";
import { subject } from "@casl/ability"; import { subject } from "@casl/ability";
import { zodResolver } from "@hookform/resolvers/zod"; import { zodResolver } from "@hookform/resolvers/zod";
import { AnimatePresence, motion } from "framer-motion"; import { AnimatePresence, motion } from "framer-motion";
import { memo, useEffect, useRef, useCallback } from "react"; import { memo, useCallback, useEffect, useRef } from "react";
import { Controller, useFieldArray, useForm } from "react-hook-form"; import { Controller, useFieldArray, useForm } from "react-hook-form";
import { twMerge } from "tailwind-merge"; import { twMerge } from "tailwind-merge";
import { import {
@@ -799,7 +799,7 @@ export const SecretItem = memo(
isPending ? ( isPending ? (
<motion.div <motion.div
key="options" key="options"
className="flex h-10 flex-shrink-0 items-center space-x-4 px-[0.64rem]" className="mt-0.5 flex h-10 flex-shrink-0 items-center space-x-3 px-[0.84rem]"
initial={{ x: 0, opacity: 0 }} initial={{ x: 0, opacity: 0 }}
animate={{ x: 0, opacity: 1 }} animate={{ x: 0, opacity: 1 }}
exit={{ x: 10, opacity: 0 }} exit={{ x: 10, opacity: 0 }}
@@ -839,7 +839,7 @@ export const SecretItem = memo(
) : ( ) : (
<motion.div <motion.div
key="options" key="options"
className="flex h-10 flex-shrink-0 items-center space-x-4 px-[0.64rem]" className="mt-0.5 flex h-10 flex-shrink-0 items-center space-x-3 px-[0.84rem]"
initial={{ x: 0, opacity: 0 }} initial={{ x: 0, opacity: 0 }}
animate={{ x: 0, opacity: 1 }} animate={{ x: 0, opacity: 1 }}
exit={{ x: 10, opacity: 0 }} exit={{ x: 10, opacity: 0 }}
@@ -881,7 +881,7 @@ export const SecretItem = memo(
> >
<FontAwesomeSymbol <FontAwesomeSymbol
symbolName={FontAwesomeSpriteName.Trash} symbolName={FontAwesomeSpriteName.Trash}
className="h-5 w-4" className="h-3.5 w-4"
/> />
</IconButton> </IconButton>
)} )}