mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-06 16:27:46 +00:00
Lint
This commit is contained in:
@@ -52,7 +52,6 @@ import { WsTag } from "@app/hooks/api/types";
|
|||||||
import { formSchema, SecretActionType, TFormSchema } from "./SecretListView.utils";
|
import { formSchema, SecretActionType, TFormSchema } from "./SecretListView.utils";
|
||||||
import { CreateReminderForm } from "./CreateReminderForm";
|
import { CreateReminderForm } from "./CreateReminderForm";
|
||||||
|
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
secret: DecryptedSecret;
|
secret: DecryptedSecret;
|
||||||
onSaveSecret: (
|
onSaveSecret: (
|
||||||
@@ -71,8 +70,6 @@ type Props = {
|
|||||||
secretPath: string;
|
secretPath: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
export const SecretItem = memo(
|
export const SecretItem = memo(
|
||||||
({
|
({
|
||||||
secret,
|
secret,
|
||||||
@@ -189,346 +186,344 @@ export const SecretItem = memo(
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
<CreateReminderForm
|
||||||
|
isOpen={createReminderFormOpen}
|
||||||
|
onClose={(data) => {
|
||||||
|
if (data) {
|
||||||
|
setValue("reminderCron", data.cron, { shouldDirty: true });
|
||||||
|
setValue("reminderNote", data.note, { shouldDirty: true });
|
||||||
|
}
|
||||||
|
setCreateReminderFormOpen.off();
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
|
||||||
<CreateReminderForm
|
<form onSubmit={handleSubmit(handleFormSubmit)}>
|
||||||
isOpen={createReminderFormOpen}
|
<div
|
||||||
onClose={data => {
|
className={twMerge(
|
||||||
if(data) {
|
"border-b border-mineshaft-600 bg-mineshaft-800 shadow-none hover:bg-mineshaft-700",
|
||||||
setValue("reminderCron", data.cron, {shouldDirty: true});
|
isDirty && "border-primary-400/50"
|
||||||
setValue("reminderNote", data.note, {shouldDirty: true});
|
)}
|
||||||
}
|
>
|
||||||
setCreateReminderFormOpen.off();
|
<div className="group flex">
|
||||||
}}
|
<div
|
||||||
/>
|
className={twMerge(
|
||||||
|
"flex h-11 w-11 items-center justify-center px-4 py-3",
|
||||||
<form onSubmit={handleSubmit(handleFormSubmit)}>
|
isDirty && "text-primary"
|
||||||
<div
|
)}
|
||||||
className={twMerge(
|
>
|
||||||
"border-b border-mineshaft-600 bg-mineshaft-800 shadow-none hover:bg-mineshaft-700",
|
<Checkbox
|
||||||
isDirty && "border-primary-400/50"
|
id={`checkbox-${secret._id}`}
|
||||||
)}
|
isChecked={isSelected}
|
||||||
>
|
onCheckedChange={() => onToggleSecretSelect(secret._id)}
|
||||||
<div className="group flex">
|
className={twMerge("ml-3 hidden group-hover:flex", isSelected && "flex")}
|
||||||
<div
|
/>
|
||||||
className={twMerge(
|
<FontAwesomeIcon
|
||||||
"flex h-11 w-11 items-center justify-center px-4 py-3",
|
icon={faKey}
|
||||||
isDirty && "text-primary"
|
className={twMerge("ml-3 block group-hover:hidden", isSelected && "hidden")}
|
||||||
)}
|
/>
|
||||||
>
|
</div>
|
||||||
<Checkbox
|
<div className="flex h-11 w-80 flex-shrink-0 items-center px-4 py-2">
|
||||||
id={`checkbox-${secret._id}`}
|
<Controller
|
||||||
isChecked={isSelected}
|
name="key"
|
||||||
onCheckedChange={() => onToggleSecretSelect(secret._id)}
|
control={control}
|
||||||
className={twMerge("ml-3 hidden group-hover:flex", isSelected && "flex")}
|
render={({ field }) => (
|
||||||
/>
|
<Input
|
||||||
<FontAwesomeIcon
|
autoComplete="off"
|
||||||
icon={faKey}
|
isReadOnly={isReadOnly}
|
||||||
className={twMerge("ml-3 block group-hover:hidden", isSelected && "hidden")}
|
autoCapitalization={currentWorkspace?.autoCapitalization}
|
||||||
/>
|
variant="plain"
|
||||||
</div>
|
isDisabled={isOverriden}
|
||||||
<div className="flex h-11 w-80 flex-shrink-0 items-center px-4 py-2">
|
{...field}
|
||||||
<Controller
|
className="w-full px-0 focus:text-bunker-100 focus:ring-transparent"
|
||||||
name="key"
|
/>
|
||||||
control={control}
|
)}
|
||||||
render={({ field }) => (
|
/>
|
||||||
<Input
|
</div>
|
||||||
autoComplete="off"
|
<div
|
||||||
isReadOnly={isReadOnly}
|
className="flex flex-grow items-center border-x border-mineshaft-600 py-1 pl-4 pr-2"
|
||||||
autoCapitalization={currentWorkspace?.autoCapitalization}
|
tabIndex={0}
|
||||||
variant="plain"
|
role="button"
|
||||||
isDisabled={isOverriden}
|
>
|
||||||
{...field}
|
{isOverriden ? (
|
||||||
className="w-full px-0 focus:text-bunker-100 focus:ring-transparent"
|
<Controller
|
||||||
|
name="valueOverride"
|
||||||
|
key="value-overriden"
|
||||||
|
control={control}
|
||||||
|
render={({ field }) => (
|
||||||
|
<SecretInput
|
||||||
|
key="value-overriden"
|
||||||
|
isVisible={isVisible}
|
||||||
|
isReadOnly={isReadOnly}
|
||||||
|
{...field}
|
||||||
|
containerClassName="py-1.5 rounded-md transition-all group-hover:mr-2"
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<Controller
|
||||||
|
name="value"
|
||||||
|
key="secret-value"
|
||||||
|
control={control}
|
||||||
|
render={({ field }) => (
|
||||||
|
<SecretInput
|
||||||
|
isReadOnly={isReadOnly}
|
||||||
|
key="secret-value"
|
||||||
|
isVisible={isVisible}
|
||||||
|
{...field}
|
||||||
|
containerClassName="py-1.5 rounded-md transition-all group-hover:mr-2"
|
||||||
|
/>
|
||||||
|
)}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
/>
|
<div key="actions" className="flex h-8 flex-shrink-0 self-start transition-all">
|
||||||
</div>
|
<Tooltip content="Copy secret">
|
||||||
<div
|
|
||||||
className="flex flex-grow items-center border-x border-mineshaft-600 py-1 pl-4 pr-2"
|
|
||||||
tabIndex={0}
|
|
||||||
role="button"
|
|
||||||
>
|
|
||||||
{isOverriden ? (
|
|
||||||
<Controller
|
|
||||||
name="valueOverride"
|
|
||||||
key="value-overriden"
|
|
||||||
control={control}
|
|
||||||
render={({ field }) => (
|
|
||||||
<SecretInput
|
|
||||||
key="value-overriden"
|
|
||||||
isVisible={isVisible}
|
|
||||||
isReadOnly={isReadOnly}
|
|
||||||
{...field}
|
|
||||||
containerClassName="py-1.5 rounded-md transition-all group-hover:mr-2"
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
) : (
|
|
||||||
<Controller
|
|
||||||
name="value"
|
|
||||||
key="secret-value"
|
|
||||||
control={control}
|
|
||||||
render={({ field }) => (
|
|
||||||
<SecretInput
|
|
||||||
isReadOnly={isReadOnly}
|
|
||||||
key="secret-value"
|
|
||||||
isVisible={isVisible}
|
|
||||||
{...field}
|
|
||||||
containerClassName="py-1.5 rounded-md transition-all group-hover:mr-2"
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
<div key="actions" className="flex h-8 flex-shrink-0 self-start transition-all">
|
|
||||||
<Tooltip content="Copy secret">
|
|
||||||
<IconButton
|
|
||||||
ariaLabel="copy-value"
|
|
||||||
variant="plain"
|
|
||||||
size="sm"
|
|
||||||
className="w-0 overflow-hidden p-0 group-hover:mr-2 group-hover:w-5"
|
|
||||||
onClick={copyTokenToClipboard}
|
|
||||||
>
|
|
||||||
<FontAwesomeIcon icon={isSecValueCopied ? faCheck : faCopy} />
|
|
||||||
</IconButton>
|
|
||||||
</Tooltip>
|
|
||||||
<DropdownMenu>
|
|
||||||
<ProjectPermissionCan
|
|
||||||
I={ProjectPermissionActions.Edit}
|
|
||||||
a={subject(ProjectPermissionSub.Secrets, { environment, secretPath })}
|
|
||||||
>
|
|
||||||
{(isAllowed) => (
|
|
||||||
<DropdownMenuTrigger asChild disabled={!isAllowed}>
|
|
||||||
<IconButton
|
|
||||||
ariaLabel="tags"
|
|
||||||
variant="plain"
|
|
||||||
size="sm"
|
|
||||||
className={twMerge(
|
|
||||||
"w-0 overflow-hidden p-0 group-hover:mr-2 group-hover:w-5 data-[state=open]:w-5",
|
|
||||||
hasTagsApplied && "w-5 text-primary"
|
|
||||||
)}
|
|
||||||
isDisabled={!isAllowed}
|
|
||||||
>
|
|
||||||
<Tooltip content="Tags">
|
|
||||||
<FontAwesomeIcon icon={faTags} />
|
|
||||||
</Tooltip>
|
|
||||||
</IconButton>
|
|
||||||
</DropdownMenuTrigger>
|
|
||||||
)}
|
|
||||||
</ProjectPermissionCan>
|
|
||||||
<DropdownMenuContent align="end">
|
|
||||||
<DropdownMenuLabel>Apply tags to this secrets</DropdownMenuLabel>
|
|
||||||
{tags.map((tag) => {
|
|
||||||
const { _id: tagId, name, tagColor } = tag;
|
|
||||||
|
|
||||||
const isTagSelected = selectedTagsGroupById?.[tagId];
|
|
||||||
return (
|
|
||||||
<DropdownMenuItem
|
|
||||||
onClick={() => handleTagSelect(tag)}
|
|
||||||
key={tagId}
|
|
||||||
icon={isTagSelected && <FontAwesomeIcon icon={faCheckCircle} />}
|
|
||||||
iconPos="right"
|
|
||||||
>
|
|
||||||
<div className="flex items-center">
|
|
||||||
<div
|
|
||||||
className="mr-2 h-2 w-2 rounded-full"
|
|
||||||
style={{ background: tagColor || "#bec2c8" }}
|
|
||||||
/>
|
|
||||||
{name}
|
|
||||||
</div>
|
|
||||||
</DropdownMenuItem>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
<DropdownMenuItem className="px-1.5">
|
|
||||||
<Button
|
|
||||||
size="xs"
|
|
||||||
className="w-full"
|
|
||||||
colorSchema="primary"
|
|
||||||
variant="outline_bg"
|
|
||||||
leftIcon={<FontAwesomeIcon icon={faTag} />}
|
|
||||||
onClick={onCreateTag}
|
|
||||||
>
|
|
||||||
Create a tag
|
|
||||||
</Button>
|
|
||||||
</DropdownMenuItem>
|
|
||||||
</DropdownMenuContent>
|
|
||||||
</DropdownMenu>
|
|
||||||
<ProjectPermissionCan
|
|
||||||
I={ProjectPermissionActions.Edit}
|
|
||||||
a={subject(ProjectPermissionSub.Secrets, { environment, secretPath })}
|
|
||||||
renderTooltip
|
|
||||||
allowedLabel="Override"
|
|
||||||
>
|
|
||||||
{(isAllowed) => (
|
|
||||||
<IconButton
|
<IconButton
|
||||||
ariaLabel="override-value"
|
ariaLabel="copy-value"
|
||||||
isDisabled={!isAllowed}
|
|
||||||
variant="plain"
|
variant="plain"
|
||||||
size="sm"
|
size="sm"
|
||||||
onClick={handleOverrideClick}
|
className="w-0 overflow-hidden p-0 group-hover:mr-2 group-hover:w-5"
|
||||||
className={twMerge(
|
onClick={copyTokenToClipboard}
|
||||||
"w-0 overflow-hidden p-0 group-hover:mr-2 group-hover:w-5",
|
|
||||||
isOverriden && "w-5 text-primary"
|
|
||||||
)}
|
|
||||||
>
|
>
|
||||||
<FontAwesomeIcon icon={faCodeBranch} />
|
<FontAwesomeIcon icon={isSecValueCopied ? faCheck : faCopy} />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
)}
|
</Tooltip>
|
||||||
</ProjectPermissionCan>
|
<DropdownMenu>
|
||||||
|
<ProjectPermissionCan
|
||||||
|
I={ProjectPermissionActions.Edit}
|
||||||
|
a={subject(ProjectPermissionSub.Secrets, { environment, secretPath })}
|
||||||
|
>
|
||||||
|
{(isAllowed) => (
|
||||||
|
<DropdownMenuTrigger asChild disabled={!isAllowed}>
|
||||||
|
<IconButton
|
||||||
|
ariaLabel="tags"
|
||||||
|
variant="plain"
|
||||||
|
size="sm"
|
||||||
|
className={twMerge(
|
||||||
|
"w-0 overflow-hidden p-0 group-hover:mr-2 group-hover:w-5 data-[state=open]:w-5",
|
||||||
|
hasTagsApplied && "w-5 text-primary"
|
||||||
|
)}
|
||||||
|
isDisabled={!isAllowed}
|
||||||
|
>
|
||||||
|
<Tooltip content="Tags">
|
||||||
|
<FontAwesomeIcon icon={faTags} />
|
||||||
|
</Tooltip>
|
||||||
|
</IconButton>
|
||||||
|
</DropdownMenuTrigger>
|
||||||
|
)}
|
||||||
|
</ProjectPermissionCan>
|
||||||
|
<DropdownMenuContent align="end">
|
||||||
|
<DropdownMenuLabel>Apply tags to this secrets</DropdownMenuLabel>
|
||||||
|
{tags.map((tag) => {
|
||||||
|
const { _id: tagId, name, tagColor } = tag;
|
||||||
|
|
||||||
|
const isTagSelected = selectedTagsGroupById?.[tagId];
|
||||||
<IconButton
|
return (
|
||||||
className={twMerge(
|
<DropdownMenuItem
|
||||||
"w-0 overflow-hidden p-0 group-hover:mr-2 group-hover:w-5 data-[state=open]:w-6",
|
onClick={() => handleTagSelect(tag)}
|
||||||
hasReminder && "w-5 text-primary"
|
key={tagId}
|
||||||
)}
|
icon={isTagSelected && <FontAwesomeIcon icon={faCheckCircle} />}
|
||||||
variant="plain"
|
iconPos="right"
|
||||||
size="md"
|
>
|
||||||
ariaLabel="add-reminder"
|
<div className="flex items-center">
|
||||||
>
|
<div
|
||||||
<Tooltip content="Reminder">
|
className="mr-2 h-2 w-2 rounded-full"
|
||||||
<FontAwesomeIcon
|
style={{ background: tagColor || "#bec2c8" }}
|
||||||
onClick={() => {
|
/>
|
||||||
if(!hasReminder) {
|
{name}
|
||||||
setCreateReminderFormOpen.on();
|
</div>
|
||||||
}
|
</DropdownMenuItem>
|
||||||
else {
|
);
|
||||||
setValue("reminderCron", null, {shouldDirty: true});
|
})}
|
||||||
setValue("reminderNote", null, {shouldDirty: true});
|
<DropdownMenuItem className="px-1.5">
|
||||||
}
|
<Button
|
||||||
}}
|
size="xs"
|
||||||
icon={faClock} />
|
className="w-full"
|
||||||
</Tooltip>
|
colorSchema="primary"
|
||||||
</IconButton>
|
variant="outline_bg"
|
||||||
|
leftIcon={<FontAwesomeIcon icon={faTag} />}
|
||||||
<Popover>
|
onClick={onCreateTag}
|
||||||
|
>
|
||||||
|
Create a tag
|
||||||
|
</Button>
|
||||||
|
</DropdownMenuItem>
|
||||||
|
</DropdownMenuContent>
|
||||||
|
</DropdownMenu>
|
||||||
<ProjectPermissionCan
|
<ProjectPermissionCan
|
||||||
I={ProjectPermissionActions.Edit}
|
I={ProjectPermissionActions.Edit}
|
||||||
a={subject(ProjectPermissionSub.Secrets, { environment, secretPath })}
|
a={subject(ProjectPermissionSub.Secrets, { environment, secretPath })}
|
||||||
>
|
|
||||||
{(isAllowed) => (
|
|
||||||
<PopoverTrigger asChild disabled={!isAllowed}>
|
|
||||||
<IconButton
|
|
||||||
className={twMerge(
|
|
||||||
"w-0 overflow-hidden p-0 group-hover:mr-2 group-hover:w-5 data-[state=open]:w-6",
|
|
||||||
hasComment && "w-5 text-primary"
|
|
||||||
)}
|
|
||||||
variant="plain"
|
|
||||||
size="md"
|
|
||||||
ariaLabel="add-comment"
|
|
||||||
isDisabled={!isAllowed}
|
|
||||||
>
|
|
||||||
<Tooltip content="Comment">
|
|
||||||
<FontAwesomeIcon icon={faComment} />
|
|
||||||
</Tooltip>
|
|
||||||
</IconButton>
|
|
||||||
</PopoverTrigger>
|
|
||||||
)}
|
|
||||||
</ProjectPermissionCan>
|
|
||||||
<PopoverContent
|
|
||||||
className="w-auto border border-mineshaft-600 bg-mineshaft-800 p-2 drop-shadow-2xl"
|
|
||||||
sticky="always"
|
|
||||||
>
|
|
||||||
<FormControl label="Comment" className="mb-0">
|
|
||||||
<TextArea
|
|
||||||
className="border border-mineshaft-600 text-sm"
|
|
||||||
rows={8}
|
|
||||||
cols={30}
|
|
||||||
{...register("comment")}
|
|
||||||
/>
|
|
||||||
</FormControl>
|
|
||||||
</PopoverContent>
|
|
||||||
</Popover>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<AnimatePresence exitBeforeEnter>
|
|
||||||
{!isDirty ? (
|
|
||||||
<motion.div
|
|
||||||
key="options"
|
|
||||||
className="flex h-10 flex-shrink-0 items-center space-x-4 px-3"
|
|
||||||
initial={{ x: 0, opacity: 0 }}
|
|
||||||
animate={{ x: 0, opacity: 1 }}
|
|
||||||
exit={{ x: 10, opacity: 0 }}
|
|
||||||
>
|
|
||||||
<Tooltip content="More">
|
|
||||||
<IconButton
|
|
||||||
ariaLabel="more"
|
|
||||||
variant="plain"
|
|
||||||
size="md"
|
|
||||||
className="p-0 opacity-0 group-hover:opacity-100"
|
|
||||||
onClick={() => onDetailViewSecret(secret)}
|
|
||||||
>
|
|
||||||
<FontAwesomeIcon icon={faEllipsis} size="lg" />
|
|
||||||
</IconButton>
|
|
||||||
</Tooltip>
|
|
||||||
<ProjectPermissionCan
|
|
||||||
I={ProjectPermissionActions.Delete}
|
|
||||||
a={subject(ProjectPermissionSub.Secrets, { environment, secretPath })}
|
|
||||||
renderTooltip
|
renderTooltip
|
||||||
allowedLabel="Delete"
|
allowedLabel="Override"
|
||||||
>
|
>
|
||||||
{(isAllowed) => (
|
{(isAllowed) => (
|
||||||
<IconButton
|
<IconButton
|
||||||
ariaLabel="delete-value"
|
ariaLabel="override-value"
|
||||||
variant="plain"
|
|
||||||
colorSchema="danger"
|
|
||||||
size="md"
|
|
||||||
className="p-0 opacity-0 group-hover:opacity-100"
|
|
||||||
onClick={() => onDeleteSecret(secret)}
|
|
||||||
isDisabled={!isAllowed}
|
isDisabled={!isAllowed}
|
||||||
|
variant="plain"
|
||||||
|
size="sm"
|
||||||
|
onClick={handleOverrideClick}
|
||||||
|
className={twMerge(
|
||||||
|
"w-0 overflow-hidden p-0 group-hover:mr-2 group-hover:w-5",
|
||||||
|
isOverriden && "w-5 text-primary"
|
||||||
|
)}
|
||||||
>
|
>
|
||||||
<FontAwesomeIcon icon={faClose} size="lg" />
|
<FontAwesomeIcon icon={faCodeBranch} />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
)}
|
)}
|
||||||
</ProjectPermissionCan>
|
</ProjectPermissionCan>
|
||||||
</motion.div>
|
|
||||||
) : (
|
<IconButton
|
||||||
<motion.div
|
className={twMerge(
|
||||||
key="options-save"
|
"w-0 overflow-hidden p-0 group-hover:mr-2 group-hover:w-5 data-[state=open]:w-6",
|
||||||
className="flex h-10 flex-shrink-0 items-center space-x-4 px-3"
|
hasReminder && "w-5 text-primary"
|
||||||
initial={{ x: -10, opacity: 0 }}
|
)}
|
||||||
animate={{ x: 0, opacity: 1 }}
|
variant="plain"
|
||||||
exit={{ x: -10, opacity: 0 }}
|
size="md"
|
||||||
>
|
ariaLabel="add-reminder"
|
||||||
<Tooltip content="Save">
|
>
|
||||||
<IconButton
|
<Tooltip content="Reminder">
|
||||||
ariaLabel="more"
|
<FontAwesomeIcon
|
||||||
variant="plain"
|
onClick={() => {
|
||||||
type="submit"
|
if (!hasReminder) {
|
||||||
size="md"
|
setCreateReminderFormOpen.on();
|
||||||
className={twMerge(
|
} else {
|
||||||
"p-0 text-primary opacity-0 group-hover:opacity-100",
|
setValue("reminderCron", null, { shouldDirty: true });
|
||||||
isDirty && "opacity-100"
|
setValue("reminderNote", null, { shouldDirty: true });
|
||||||
)}
|
}
|
||||||
isDisabled={isSubmitting}
|
}}
|
||||||
|
icon={faClock}
|
||||||
|
/>
|
||||||
|
</Tooltip>
|
||||||
|
</IconButton>
|
||||||
|
|
||||||
|
<Popover>
|
||||||
|
<ProjectPermissionCan
|
||||||
|
I={ProjectPermissionActions.Edit}
|
||||||
|
a={subject(ProjectPermissionSub.Secrets, { environment, secretPath })}
|
||||||
>
|
>
|
||||||
{isSubmitting ? (
|
{(isAllowed) => (
|
||||||
<Spinner className="m-0 h-4 w-4 p-0" />
|
<PopoverTrigger asChild disabled={!isAllowed}>
|
||||||
) : (
|
<IconButton
|
||||||
<FontAwesomeIcon icon={faCheck} size="lg" className="text-primary" />
|
className={twMerge(
|
||||||
|
"w-0 overflow-hidden p-0 group-hover:mr-2 group-hover:w-5 data-[state=open]:w-6",
|
||||||
|
hasComment && "w-5 text-primary"
|
||||||
|
)}
|
||||||
|
variant="plain"
|
||||||
|
size="md"
|
||||||
|
ariaLabel="add-comment"
|
||||||
|
isDisabled={!isAllowed}
|
||||||
|
>
|
||||||
|
<Tooltip content="Comment">
|
||||||
|
<FontAwesomeIcon icon={faComment} />
|
||||||
|
</Tooltip>
|
||||||
|
</IconButton>
|
||||||
|
</PopoverTrigger>
|
||||||
)}
|
)}
|
||||||
</IconButton>
|
</ProjectPermissionCan>
|
||||||
</Tooltip>
|
<PopoverContent
|
||||||
<Tooltip content="Cancel">
|
className="w-auto border border-mineshaft-600 bg-mineshaft-800 p-2 drop-shadow-2xl"
|
||||||
<IconButton
|
sticky="always"
|
||||||
ariaLabel="more"
|
|
||||||
variant="plain"
|
|
||||||
size="md"
|
|
||||||
className={twMerge(
|
|
||||||
"p-0 opacity-0 group-hover:opacity-100",
|
|
||||||
isDirty && "opacity-100"
|
|
||||||
)}
|
|
||||||
onClick={() => reset()}
|
|
||||||
isDisabled={isSubmitting}
|
|
||||||
>
|
>
|
||||||
<FontAwesomeIcon icon={faClose} size="lg" />
|
<FormControl label="Comment" className="mb-0">
|
||||||
</IconButton>
|
<TextArea
|
||||||
</Tooltip>
|
className="border border-mineshaft-600 text-sm"
|
||||||
</motion.div>
|
rows={8}
|
||||||
)}
|
cols={30}
|
||||||
</AnimatePresence>
|
{...register("comment")}
|
||||||
|
/>
|
||||||
|
</FormControl>
|
||||||
|
</PopoverContent>
|
||||||
|
</Popover>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<AnimatePresence exitBeforeEnter>
|
||||||
|
{!isDirty ? (
|
||||||
|
<motion.div
|
||||||
|
key="options"
|
||||||
|
className="flex h-10 flex-shrink-0 items-center space-x-4 px-3"
|
||||||
|
initial={{ x: 0, opacity: 0 }}
|
||||||
|
animate={{ x: 0, opacity: 1 }}
|
||||||
|
exit={{ x: 10, opacity: 0 }}
|
||||||
|
>
|
||||||
|
<Tooltip content="More">
|
||||||
|
<IconButton
|
||||||
|
ariaLabel="more"
|
||||||
|
variant="plain"
|
||||||
|
size="md"
|
||||||
|
className="p-0 opacity-0 group-hover:opacity-100"
|
||||||
|
onClick={() => onDetailViewSecret(secret)}
|
||||||
|
>
|
||||||
|
<FontAwesomeIcon icon={faEllipsis} size="lg" />
|
||||||
|
</IconButton>
|
||||||
|
</Tooltip>
|
||||||
|
<ProjectPermissionCan
|
||||||
|
I={ProjectPermissionActions.Delete}
|
||||||
|
a={subject(ProjectPermissionSub.Secrets, { environment, secretPath })}
|
||||||
|
renderTooltip
|
||||||
|
allowedLabel="Delete"
|
||||||
|
>
|
||||||
|
{(isAllowed) => (
|
||||||
|
<IconButton
|
||||||
|
ariaLabel="delete-value"
|
||||||
|
variant="plain"
|
||||||
|
colorSchema="danger"
|
||||||
|
size="md"
|
||||||
|
className="p-0 opacity-0 group-hover:opacity-100"
|
||||||
|
onClick={() => onDeleteSecret(secret)}
|
||||||
|
isDisabled={!isAllowed}
|
||||||
|
>
|
||||||
|
<FontAwesomeIcon icon={faClose} size="lg" />
|
||||||
|
</IconButton>
|
||||||
|
)}
|
||||||
|
</ProjectPermissionCan>
|
||||||
|
</motion.div>
|
||||||
|
) : (
|
||||||
|
<motion.div
|
||||||
|
key="options-save"
|
||||||
|
className="flex h-10 flex-shrink-0 items-center space-x-4 px-3"
|
||||||
|
initial={{ x: -10, opacity: 0 }}
|
||||||
|
animate={{ x: 0, opacity: 1 }}
|
||||||
|
exit={{ x: -10, opacity: 0 }}
|
||||||
|
>
|
||||||
|
<Tooltip content="Save">
|
||||||
|
<IconButton
|
||||||
|
ariaLabel="more"
|
||||||
|
variant="plain"
|
||||||
|
type="submit"
|
||||||
|
size="md"
|
||||||
|
className={twMerge(
|
||||||
|
"p-0 text-primary opacity-0 group-hover:opacity-100",
|
||||||
|
isDirty && "opacity-100"
|
||||||
|
)}
|
||||||
|
isDisabled={isSubmitting}
|
||||||
|
>
|
||||||
|
{isSubmitting ? (
|
||||||
|
<Spinner className="m-0 h-4 w-4 p-0" />
|
||||||
|
) : (
|
||||||
|
<FontAwesomeIcon icon={faCheck} size="lg" className="text-primary" />
|
||||||
|
)}
|
||||||
|
</IconButton>
|
||||||
|
</Tooltip>
|
||||||
|
<Tooltip content="Cancel">
|
||||||
|
<IconButton
|
||||||
|
ariaLabel="more"
|
||||||
|
variant="plain"
|
||||||
|
size="md"
|
||||||
|
className={twMerge(
|
||||||
|
"p-0 opacity-0 group-hover:opacity-100",
|
||||||
|
isDirty && "opacity-100"
|
||||||
|
)}
|
||||||
|
onClick={() => reset()}
|
||||||
|
isDisabled={isSubmitting}
|
||||||
|
>
|
||||||
|
<FontAwesomeIcon icon={faClose} size="lg" />
|
||||||
|
</IconButton>
|
||||||
|
</Tooltip>
|
||||||
|
</motion.div>
|
||||||
|
)}
|
||||||
|
</AnimatePresence>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</form>
|
||||||
</form>
|
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user