mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-09-22 13:39:35 +00:00
improve access account styling, add folder path badge to flat view,
increase log gap
This commit is contained in:
@@ -1,10 +1,11 @@
|
||||
import { useMemo, useState } from "react";
|
||||
import { faCopy } from "@fortawesome/free-regular-svg-icons";
|
||||
import { faUpRightFromSquare } from "@fortawesome/free-solid-svg-icons";
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
import ms from "ms";
|
||||
|
||||
import { createNotification } from "@app/components/notifications";
|
||||
import { Button, FormLabel, Input, Modal, ModalClose, ModalContent } from "@app/components/v2";
|
||||
import { FormLabel, IconButton, Input, Modal, ModalContent } from "@app/components/v2";
|
||||
import { PamResourceType, TPamAccount } from "@app/hooks/api/pam";
|
||||
|
||||
type Props = {
|
||||
@@ -28,21 +29,10 @@ export const PamAccessAccountModal = ({ isOpen, onOpenChange, account }: Props)
|
||||
|
||||
if (!account) return null;
|
||||
|
||||
const copyCommand = () => {
|
||||
navigator.clipboard.writeText(command);
|
||||
|
||||
createNotification({
|
||||
text: "Command copied to clipboard",
|
||||
type: "info"
|
||||
});
|
||||
|
||||
onOpenChange(false);
|
||||
};
|
||||
|
||||
return (
|
||||
<Modal isOpen={isOpen} onOpenChange={onOpenChange}>
|
||||
<ModalContent
|
||||
className="max-w-2xl"
|
||||
className="max-w-2xl pb-2"
|
||||
title="Access Account"
|
||||
subTitle={`Access ${account.name} using a CLI command.`}
|
||||
>
|
||||
@@ -57,7 +47,27 @@ export const PamAccessAccountModal = ({ isOpen, onOpenChange, account }: Props)
|
||||
isError={!isDurationValid}
|
||||
/>
|
||||
<FormLabel label="CLI Command" className="mt-4" />
|
||||
<Input value={command} isDisabled />
|
||||
<div className="flex gap-2">
|
||||
<Input value={command} isDisabled className="opacity-50" />
|
||||
<IconButton
|
||||
ariaLabel="copy"
|
||||
variant="outline_bg"
|
||||
colorSchema="secondary"
|
||||
onClick={() => {
|
||||
navigator.clipboard.writeText(command);
|
||||
|
||||
createNotification({
|
||||
text: "Command copied to clipboard",
|
||||
type: "info"
|
||||
});
|
||||
|
||||
onOpenChange(false);
|
||||
}}
|
||||
className="w-10"
|
||||
>
|
||||
<FontAwesomeIcon icon={faCopy} />
|
||||
</IconButton>
|
||||
</div>
|
||||
<a
|
||||
href="https://infisical.com/docs/cli/overview"
|
||||
target="_blank"
|
||||
@@ -67,22 +77,6 @@ export const PamAccessAccountModal = ({ isOpen, onOpenChange, account }: Props)
|
||||
<span>Install the Infisical CLI</span>
|
||||
<FontAwesomeIcon icon={faUpRightFromSquare} className="size-3" />
|
||||
</a>
|
||||
<div className="mt-6 flex items-center">
|
||||
<Button
|
||||
isDisabled={!isDurationValid}
|
||||
className="mr-4"
|
||||
size="sm"
|
||||
colorSchema="secondary"
|
||||
onClick={copyCommand}
|
||||
>
|
||||
Copy Command
|
||||
</Button>
|
||||
<ModalClose asChild>
|
||||
<Button colorSchema="secondary" variant="plain">
|
||||
Cancel
|
||||
</Button>
|
||||
</ModalClose>
|
||||
</div>
|
||||
</ModalContent>
|
||||
</Modal>
|
||||
);
|
||||
|
||||
@@ -5,6 +5,7 @@ import {
|
||||
faCopy,
|
||||
faEdit,
|
||||
faEllipsisV,
|
||||
faFolder,
|
||||
faRightToBracket,
|
||||
faTrash
|
||||
} from "@fortawesome/free-solid-svg-icons";
|
||||
@@ -37,9 +38,19 @@ type Props = {
|
||||
onUpdate: (resource: TPamAccount) => void;
|
||||
onDelete: (resource: TPamAccount) => void;
|
||||
search: string;
|
||||
isFlatView: boolean;
|
||||
accountPath?: string;
|
||||
};
|
||||
|
||||
export const PamAccountRow = ({ account, search, onAccess, onUpdate, onDelete }: Props) => {
|
||||
export const PamAccountRow = ({
|
||||
account,
|
||||
search,
|
||||
onAccess,
|
||||
onUpdate,
|
||||
onDelete,
|
||||
isFlatView,
|
||||
accountPath
|
||||
}: Props) => {
|
||||
const { id, name } = account;
|
||||
|
||||
const { image, name: resourceTypeName } = PAM_RESOURCE_TYPE_MAP[account.resource.resourceType];
|
||||
@@ -81,6 +92,14 @@ export const PamAccountRow = ({ account, search, onAccess, onUpdate, onDelete }:
|
||||
<HighlightText text={account.resource.name} highlight={search} />
|
||||
</span>
|
||||
</Badge>
|
||||
{isFlatView && accountPath && (
|
||||
<Badge className="flex h-5 w-min items-center gap-1.5 whitespace-nowrap bg-bunker-300/20 text-bunker-300">
|
||||
<FontAwesomeIcon icon={faFolder} />
|
||||
<span>
|
||||
<HighlightText text={accountPath} highlight={search} />
|
||||
</span>
|
||||
</Badge>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</Td>
|
||||
|
||||
@@ -114,10 +114,11 @@ export const PamAccountsTable = ({ accounts, folders, projectId }: Props) => {
|
||||
setOrderBy
|
||||
} = usePagination<OrderBy>(OrderBy.Name, { initPerPage: 20, initSearch });
|
||||
|
||||
const { foldersByParentId, pathMap } = useMemo(() => {
|
||||
const { foldersByParentId, pathMap, folderPaths } = useMemo(() => {
|
||||
const foldersById: Record<string, TPamFolder> = {};
|
||||
const tempFoldersByParentId: Record<string, TPamFolder[]> = { null: [] };
|
||||
const tempPathMap: Record<string, string> = { "/": "null" };
|
||||
const tempFolderPaths: Record<string, string> = {};
|
||||
|
||||
folders.forEach((folder) => {
|
||||
foldersById[folder.id] = folder;
|
||||
@@ -131,13 +132,18 @@ export const PamAccountsTable = ({ accounts, folders, projectId }: Props) => {
|
||||
(tempFoldersByParentId[parentId || "null"] || []).forEach((folder) => {
|
||||
const newPath = `${currentPath}${folder.name}/`;
|
||||
tempPathMap[newPath] = folder.id;
|
||||
tempFolderPaths[folder.id] = newPath;
|
||||
buildPaths(folder.id, newPath);
|
||||
});
|
||||
};
|
||||
|
||||
buildPaths(null, "/");
|
||||
|
||||
return { foldersByParentId: tempFoldersByParentId, pathMap: tempPathMap };
|
||||
return {
|
||||
foldersByParentId: tempFoldersByParentId,
|
||||
pathMap: tempPathMap,
|
||||
folderPaths: tempFolderPaths
|
||||
};
|
||||
}, [folders]);
|
||||
|
||||
const effectiveFolderIdForFiltering = useMemo(() => {
|
||||
@@ -181,11 +187,13 @@ export const PamAccountsTable = ({ accounts, folders, projectId }: Props) => {
|
||||
}
|
||||
|
||||
const searchValue = search.trim().toLowerCase();
|
||||
const path = (account.folderId && folderPaths[account.folderId]) || "";
|
||||
|
||||
return (
|
||||
name.toLowerCase().includes(searchValue) ||
|
||||
resourceName.toLowerCase().includes(searchValue) ||
|
||||
(description || "").toLowerCase().includes(searchValue)
|
||||
(description || "").toLowerCase().includes(searchValue) ||
|
||||
path.toLowerCase().includes(searchValue)
|
||||
);
|
||||
})
|
||||
.sort((a, b) => {
|
||||
@@ -197,7 +205,7 @@ export const PamAccountsTable = ({ accounts, folders, projectId }: Props) => {
|
||||
return accOne.name.toLowerCase().localeCompare(accTwo.name.toLowerCase());
|
||||
}
|
||||
}),
|
||||
[accountsToProcess, orderDirection, search, orderBy, filters]
|
||||
[accountsToProcess, orderDirection, search, orderBy, filters, folderPaths]
|
||||
);
|
||||
|
||||
useResetPageHelper({
|
||||
@@ -434,6 +442,10 @@ export const PamAccountsTable = ({ accounts, folders, projectId }: Props) => {
|
||||
key={account.id}
|
||||
account={account}
|
||||
search={search}
|
||||
isFlatView={accountView === AccountView.Flat}
|
||||
accountPath={
|
||||
account.folderId ? folderPaths[account.folderId]?.slice(0, -1) : undefined
|
||||
}
|
||||
onAccess={(e) => {
|
||||
handlePopUpOpen("accessAccount", e);
|
||||
}}
|
||||
|
||||
@@ -13,7 +13,7 @@ export const PamSessionLogsSection = ({ session }: Props) => {
|
||||
<div className="flex items-center border-b border-mineshaft-400 pb-4">
|
||||
<h3 className="text-lg font-semibold text-mineshaft-100">Session Logs</h3>
|
||||
</div>
|
||||
<div className="flex grow flex-col gap-4 overflow-y-auto text-xs">
|
||||
<div className="flex grow flex-col gap-8 overflow-y-auto text-xs">
|
||||
{session.commandLogs.length > 0 ? (
|
||||
session.commandLogs.map((log) => (
|
||||
<div key={log.timestamp} className="flex flex-col">
|
||||
|
||||
Reference in New Issue
Block a user