improve access account styling, add folder path badge to flat view,

increase log gap
This commit is contained in:
x032205
2025-10-03 13:04:36 -04:00
parent db6e30a0bf
commit 178a5494f2
4 changed files with 61 additions and 36 deletions

View File

@@ -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>
);

View File

@@ -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>

View File

@@ -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);
}}

View File

@@ -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">