diff --git a/frontend/src/pages/pam/PamAccountsPage/components/PamAccessAccountModal.tsx b/frontend/src/pages/pam/PamAccountsPage/components/PamAccessAccountModal.tsx index be3d40001..9049001e6 100644 --- a/frontend/src/pages/pam/PamAccountsPage/components/PamAccessAccountModal.tsx +++ b/frontend/src/pages/pam/PamAccountsPage/components/PamAccessAccountModal.tsx @@ -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 ( @@ -57,7 +47,27 @@ export const PamAccessAccountModal = ({ isOpen, onOpenChange, account }: Props) isError={!isDurationValid} /> - +
+ + { + navigator.clipboard.writeText(command); + + createNotification({ + text: "Command copied to clipboard", + type: "info" + }); + + onOpenChange(false); + }} + className="w-10" + > + + +
Install the Infisical CLI -
- - - - -
); diff --git a/frontend/src/pages/pam/PamAccountsPage/components/PamAccountRow.tsx b/frontend/src/pages/pam/PamAccountsPage/components/PamAccountRow.tsx index 1a6f917e5..8798e8897 100644 --- a/frontend/src/pages/pam/PamAccountsPage/components/PamAccountRow.tsx +++ b/frontend/src/pages/pam/PamAccountsPage/components/PamAccountRow.tsx @@ -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 }: + {isFlatView && accountPath && ( + + + + + + + )} diff --git a/frontend/src/pages/pam/PamAccountsPage/components/PamAccountsTable.tsx b/frontend/src/pages/pam/PamAccountsPage/components/PamAccountsTable.tsx index 7aa6eb291..9138d7ba8 100644 --- a/frontend/src/pages/pam/PamAccountsPage/components/PamAccountsTable.tsx +++ b/frontend/src/pages/pam/PamAccountsPage/components/PamAccountsTable.tsx @@ -114,10 +114,11 @@ export const PamAccountsTable = ({ accounts, folders, projectId }: Props) => { setOrderBy } = usePagination(OrderBy.Name, { initPerPage: 20, initSearch }); - const { foldersByParentId, pathMap } = useMemo(() => { + const { foldersByParentId, pathMap, folderPaths } = useMemo(() => { const foldersById: Record = {}; const tempFoldersByParentId: Record = { null: [] }; const tempPathMap: Record = { "/": "null" }; + const tempFolderPaths: Record = {}; 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); }} diff --git a/frontend/src/pages/pam/PamSessionsByIDPage/components/PamSessionLogsSection.tsx b/frontend/src/pages/pam/PamSessionsByIDPage/components/PamSessionLogsSection.tsx index c07e0d1ab..a25db4c3c 100644 --- a/frontend/src/pages/pam/PamSessionsByIDPage/components/PamSessionLogsSection.tsx +++ b/frontend/src/pages/pam/PamSessionsByIDPage/components/PamSessionLogsSection.tsx @@ -13,7 +13,7 @@ export const PamSessionLogsSection = ({ session }: Props) => {

Session Logs

-
+
{session.commandLogs.length > 0 ? ( session.commandLogs.map((log) => (