From 5f66184d5577f082dbd906e701834539dc9f0a77 Mon Sep 17 00:00:00 2001 From: Peter Makowski Date: Tue, 7 May 2024 13:34:12 +0200 Subject: [PATCH] fix: ssh key display lp#2064920 (#5426) - display the entire ssh key comment text - show the full SSH key value on hover --- .../components/SSHKeyList/SSHKeyList.test.tsx | 22 +++++++++---- .../base/components/SSHKeyList/SSHKeyList.tsx | 32 ++++++++----------- .../base/components/SSHKeyList/_index.scss | 13 +++++--- .../views/APIKeys/APIKeyList/APIKeyList.tsx | 2 +- .../views/SSLKeys/SSLKeyList/SSLKeyList.tsx | 2 +- 5 files changed, 41 insertions(+), 30 deletions(-) diff --git a/src/app/base/components/SSHKeyList/SSHKeyList.test.tsx b/src/app/base/components/SSHKeyList/SSHKeyList.test.tsx index 208c46c825..7f936c02d5 100644 --- a/src/app/base/components/SSHKeyList/SSHKeyList.test.tsx +++ b/src/app/base/components/SSHKeyList/SSHKeyList.test.tsx @@ -86,12 +86,22 @@ describe("SSHKeyList", () => { // Two of the keys should be grouped together. expect(rows).toHaveLength(state.sshkey.items.length - 1); // The grouped keys should be displayed in sub cols. - expect(within(rows[0]).getByText("ssh-rsa aabb...")).toBeInTheDocument(); + expect(within(rows[0]).getByText("ssh-rsa aabb")).toBeInTheDocument(); - expect(within(rows[1]).getByText("ssh-rsa ccdd...")).toBeInTheDocument(); - expect(within(rows[1]).getByText("ssh-rsa gghh...")).toBeInTheDocument(); + expect(within(rows[1]).getByText("ssh-rsa ccdd")).toBeInTheDocument(); + expect(within(rows[1]).getByText("ssh-rsa gghh")).toBeInTheDocument(); - expect(within(rows[2]).getByText("ssh-rsa eeff...")).toBeInTheDocument(); + expect(within(rows[2]).getByText("ssh-rsa eeff")).toBeInTheDocument(); + }); + + it("full SSH key value is displayed", () => { + renderWithBrowserRouter(, { + route: "/account/prefs/ssh-keys", + state, + }); + const keyValue = "ssh-rsa eeff"; + // verifies that the full value is exposed in the title attribute + expect(screen.getByText(keyValue)).toHaveAccessibleName(keyValue); }); it("can display uploaded keys", () => { @@ -103,7 +113,7 @@ describe("SSHKeyList", () => { expect(within(uploadedKeyRow).getByText("Upload")).toBeInTheDocument(); expect( - within(uploadedKeyRow).getByText("ssh-rsa gghh...") + within(uploadedKeyRow).getByText("ssh-rsa gghh") ).toBeInTheDocument(); }); @@ -117,7 +127,7 @@ describe("SSHKeyList", () => { expect(within(importedKeyRow).getByText("Launchpad")).toBeInTheDocument(); expect(within(importedKeyRow).getByText("koalaparty")).toBeInTheDocument(); expect( - within(importedKeyRow).getByText("ssh-rsa aabb...") + within(importedKeyRow).getByText("ssh-rsa aabb") ).toBeInTheDocument(); }); diff --git a/src/app/base/components/SSHKeyList/SSHKeyList.tsx b/src/app/base/components/SSHKeyList/SSHKeyList.tsx index 65120d7d30..2450943506 100644 --- a/src/app/base/components/SSHKeyList/SSHKeyList.tsx +++ b/src/app/base/components/SSHKeyList/SSHKeyList.tsx @@ -1,5 +1,3 @@ -import type { ReactNode } from "react"; - import { Button, Notification } from "@canonical/react-components"; import { useSelector } from "react-redux"; import type { NavigateFunction } from "react-router-dom"; @@ -17,10 +15,10 @@ type Props = Partial; const formatKey = (key: SSHKey["key"]) => { const parts = key.split(" "); - if (parts.length === 3) { - return parts[2]; + if (parts.length >= 3) { + return parts.slice(2).join(" "); } - return `${key.slice(0, 20)}...`; + return key; }; const groupBySource = (sshkeys: SSHKey[]) => { @@ -57,14 +55,13 @@ const groupBySource = (sshkeys: SSHKey[]) => { return Array.from(groups); }; -const generateKeyCols = (keys: SSHKey[], deleteButton: ReactNode) => { +const generateKeyCols = (keys: SSHKey[]) => { return (
    - {keys.map((key, i) => ( + {keys.map((key) => (
    -
    {formatKey(key.key)}
    -
    - {i === 0 && deleteButton} +
    + {formatKey(key.key)}
    ))} @@ -84,8 +81,10 @@ const generateRows = (sshkeys: SSHKey[], navigate: NavigateFunction) => { content: group.id }, { className: "p-table-sub-cols", - content: generateKeyCols( - group.keys, + content: generateKeyCols(group.keys), + }, + { + content: ( ), + className: "u-align--right", }, ], "data-testid": "sshkey-row", @@ -140,13 +140,9 @@ const SSHKeyList = ({ ...tableProps }: Props): JSX.Element => { sortKey: "id", }, { - content: ( - <> - Key - Actions - - ), + content: "Key", }, + { content: "Actions", className: "u-align--right" }, ]} loaded={sshkeyLoaded} loading={sshkeyLoading} diff --git a/src/app/base/components/SSHKeyList/_index.scss b/src/app/base/components/SSHKeyList/_index.scss index ffb0274b42..1c32c7f86e 100644 --- a/src/app/base/components/SSHKeyList/_index.scss +++ b/src/app/base/components/SSHKeyList/_index.scss @@ -17,17 +17,22 @@ .sshkey-list th { // Source &:nth-child(1) { - flex: 0.3 0 0; + flex: 0.2 0 0; } // ID &:nth-child(2) { - flex: 0.3 0 0; + flex: 0.2 0 0; } - // Key + actions + // Key &:nth-child(3) { - flex: 0.4 0 0; + flex: 0.5 0 0; + } + + // Actions + &:nth-child(4) { + flex: 0.1 0 0; } } diff --git a/src/app/preferences/views/APIKeys/APIKeyList/APIKeyList.tsx b/src/app/preferences/views/APIKeys/APIKeyList/APIKeyList.tsx index 08bd285bcf..8da8ec2f4e 100644 --- a/src/app/preferences/views/APIKeys/APIKeyList/APIKeyList.tsx +++ b/src/app/preferences/views/APIKeys/APIKeyList/APIKeyList.tsx @@ -25,7 +25,7 @@ const generateRows = (tokens: Token[]) => role: "rowheader", }, { - content: token, + content: {token}, }, { content: ( diff --git a/src/app/preferences/views/SSLKeys/SSLKeyList/SSLKeyList.tsx b/src/app/preferences/views/SSLKeys/SSLKeyList/SSLKeyList.tsx index 84f7f9c40b..4d1edfad0e 100644 --- a/src/app/preferences/views/SSLKeys/SSLKeyList/SSLKeyList.tsx +++ b/src/app/preferences/views/SSLKeys/SSLKeyList/SSLKeyList.tsx @@ -22,7 +22,7 @@ const generateRows = (sslkeys: SSLKey[]) => columns: [ { className: "u-truncate", - content: display, + content: , role: "rowheader", }, {