mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-14 18:41:21 +00:00
Merge branch 'main' into secret-approval-filterable-selects
This commit is contained in:
@@ -1,11 +1,17 @@
|
||||
import { ParsedUrlQuery } from "querystring";
|
||||
|
||||
import { useState } from "react";
|
||||
import Link from "next/link";
|
||||
import { useRouter } from "next/router";
|
||||
import { faAngleRight, faLock } from "@fortawesome/free-solid-svg-icons";
|
||||
import { faAngleRight, faCheck, faCopy, faLock } from "@fortawesome/free-solid-svg-icons";
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
import { twMerge } from "tailwind-merge";
|
||||
|
||||
import { useOrganization, useWorkspace } from "@app/context";
|
||||
import { useToggle } from "@app/hooks";
|
||||
|
||||
import { Select, SelectItem, Tooltip } from "../v2";
|
||||
import { createNotification } from "../notifications";
|
||||
import { IconButton, Select, SelectItem, Tooltip } from "../v2";
|
||||
|
||||
type Props = {
|
||||
pageName: string;
|
||||
@@ -50,6 +56,10 @@ export default function NavHeader({
|
||||
}: Props): JSX.Element {
|
||||
const { currentWorkspace } = useWorkspace();
|
||||
const { currentOrg } = useOrganization();
|
||||
|
||||
const [isCopied, { timedToggle: toggleIsCopied }] = useToggle(false);
|
||||
const [isHoveringCopyButton, setIsHoveringCopyButton] = useState(false);
|
||||
|
||||
const router = useRouter();
|
||||
|
||||
const secretPathSegments = secretPath.split("/").filter(Boolean);
|
||||
@@ -132,8 +142,10 @@ export default function NavHeader({
|
||||
)}
|
||||
{isFolderMode &&
|
||||
secretPathSegments?.map((folderName, index) => {
|
||||
const query = { ...router.query };
|
||||
query.secretPath = `/${secretPathSegments.slice(0, index + 1).join("/")}`;
|
||||
const query: ParsedUrlQuery & { secretPath: string } = {
|
||||
...router.query,
|
||||
secretPath: `/${secretPathSegments.slice(0, index + 1).join("/")}`
|
||||
};
|
||||
|
||||
return (
|
||||
<div
|
||||
@@ -142,14 +154,59 @@ export default function NavHeader({
|
||||
>
|
||||
<FontAwesomeIcon icon={faAngleRight} className="ml-3 mr-1.5 text-xs text-gray-400" />
|
||||
{index + 1 === secretPathSegments?.length ? (
|
||||
<span className="text-sm font-semibold text-bunker-300">{folderName}</span>
|
||||
<div className="flex items-center space-x-2">
|
||||
<span
|
||||
className={twMerge(
|
||||
"text-sm font-semibold transition-all",
|
||||
isHoveringCopyButton ? "text-bunker-200" : "text-bunker-300"
|
||||
)}
|
||||
>
|
||||
{folderName}
|
||||
</span>
|
||||
<Tooltip
|
||||
className="relative right-2"
|
||||
position="bottom"
|
||||
content="Copy secret path"
|
||||
>
|
||||
<IconButton
|
||||
variant="plain"
|
||||
ariaLabel="copy"
|
||||
onMouseEnter={() => setIsHoveringCopyButton(true)}
|
||||
onMouseLeave={() => setIsHoveringCopyButton(false)}
|
||||
onClick={() => {
|
||||
if (isCopied) return;
|
||||
|
||||
navigator.clipboard.writeText(query.secretPath);
|
||||
|
||||
createNotification({
|
||||
text: "Copied secret path to clipboard",
|
||||
type: "info"
|
||||
});
|
||||
|
||||
toggleIsCopied(2000);
|
||||
}}
|
||||
className="hover:bg-bunker-100/10"
|
||||
>
|
||||
<FontAwesomeIcon
|
||||
icon={!isCopied ? faCopy : faCheck}
|
||||
size="sm"
|
||||
className="cursor-pointer"
|
||||
/>
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
</div>
|
||||
) : (
|
||||
<Link
|
||||
passHref
|
||||
legacyBehavior
|
||||
href={{ pathname: "/project/[id]/secrets/[env]", query }}
|
||||
>
|
||||
<a className="text-sm font-semibold text-primary/80 hover:text-primary">
|
||||
<a
|
||||
className={twMerge(
|
||||
"text-sm font-semibold transition-all hover:text-primary",
|
||||
isHoveringCopyButton ? "text-primary" : "text-primary/80"
|
||||
)}
|
||||
>
|
||||
{folderName}
|
||||
</a>
|
||||
</Link>
|
||||
|
||||
@@ -32,7 +32,13 @@ export const FilterableSelect = <T,>({
|
||||
})
|
||||
}}
|
||||
tabSelectsValue={tabSelectsValue}
|
||||
components={{ DropdownIndicator, ClearIndicator, MultiValueRemove, Option }}
|
||||
components={{
|
||||
DropdownIndicator,
|
||||
ClearIndicator,
|
||||
MultiValueRemove,
|
||||
Option,
|
||||
...props.components
|
||||
}}
|
||||
classNames={{
|
||||
container: ({ isDisabled }) =>
|
||||
twMerge("w-full text-sm font-inter", isDisabled && "!pointer-events-auto opacity-50"),
|
||||
@@ -58,14 +64,15 @@ export const FilterableSelect = <T,>({
|
||||
clearIndicator: () => "p-1 hover:text-red text-bunker-400",
|
||||
indicatorSeparator: () => "bg-bunker-400",
|
||||
dropdownIndicator: () => "text-bunker-200 p-1",
|
||||
menuList: () => "flex flex-col gap-1",
|
||||
menu: () =>
|
||||
"my-2 border text-sm text-mineshaft-200 thin-scrollbar bg-mineshaft-900 border-mineshaft-600 rounded-md",
|
||||
"my-2 p-2 border text-sm text-mineshaft-200 thin-scrollbar bg-mineshaft-900 border-mineshaft-600 rounded-md",
|
||||
groupHeading: () => "ml-3 mt-2 mb-1 text-mineshaft-400 text-sm",
|
||||
option: ({ isFocused, isSelected }) =>
|
||||
twMerge(
|
||||
isFocused && "bg-mineshaft-700 active:bg-mineshaft-600",
|
||||
isSelected && "text-mineshaft-200",
|
||||
"hover:cursor-pointer text-xs px-3 py-2"
|
||||
"hover:cursor-pointer rounded text-xs px-3 py-2"
|
||||
),
|
||||
noOptionsMessage: () => "text-mineshaft-400 p-2 rounded-md"
|
||||
}}
|
||||
|
||||
@@ -54,7 +54,7 @@ export const Pagination = ({
|
||||
)}
|
||||
>
|
||||
{startAdornment}
|
||||
<div className="ml-auto mr-6 flex items-center space-x-2">
|
||||
<div className={twMerge("mr-4 flex items-center space-x-2", startAdornment && "ml-auto")}>
|
||||
<div className="text-xs">
|
||||
{(page - 1) * perPage + 1} - {Math.min((page - 1) * perPage + perPage, count)} of {count}
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user