From 8f6b1138b07278567f8b7029fa4fb1fbe13b44f7 Mon Sep 17 00:00:00 2001 From: Isaiah Becker-Mayer Date: Tue, 11 Jun 2024 13:27:24 -0500 Subject: [PATCH] Fixes `DocumentNodes.story.tsx` (#42788) * Fixes DocumentNodes.story.tsx and corresponding test (hopefully) * eliminate fetchNodes and fetchClusters in favor of calling services directly --- .../ClusterSelector/ClusterSelector.story.tsx | 6 +- .../ClusterSelector/ClusterSelector.tsx | 8 +- .../DocumentNodes/DocumentNodes.story.tsx | 26 +- .../DocumentNodes.story.test.tsx.snap | 321 ++++++++++++------ .../teleport/src/Console/consoleContext.tsx | 10 +- 5 files changed, 231 insertions(+), 140 deletions(-) diff --git a/web/packages/teleport/src/Console/DocumentNodes/ClusterSelector/ClusterSelector.story.tsx b/web/packages/teleport/src/Console/DocumentNodes/ClusterSelector/ClusterSelector.story.tsx index 5b3594068982e..ffa8b60540f87 100644 --- a/web/packages/teleport/src/Console/DocumentNodes/ClusterSelector/ClusterSelector.story.tsx +++ b/web/packages/teleport/src/Console/DocumentNodes/ClusterSelector/ClusterSelector.story.tsx @@ -36,7 +36,7 @@ export const Component = () => { export const Loading = () => { const ctx = mockContext(); - ctx.fetchClusters = () => { + ctx.clustersService.fetchClusters = () => { return new Promise(() => null); }; @@ -47,7 +47,7 @@ export const Loading = () => { export const Failed = () => { const ctx = mockContext(); - ctx.fetchClusters = () => { + ctx.clustersService.fetchClusters = () => { return Promise.reject(new Error('server error')); }; @@ -74,7 +74,7 @@ function renderlusterSelector(ctx, { ...props } = {}) { function mockContext() { const ctx = new ConsoleContext(); - ctx.fetchClusters = () => { + ctx.clustersService.fetchClusters = () => { return Promise.resolve(clusters); }; diff --git a/web/packages/teleport/src/Console/DocumentNodes/ClusterSelector/ClusterSelector.tsx b/web/packages/teleport/src/Console/DocumentNodes/ClusterSelector/ClusterSelector.tsx index d516884114c62..d57fafb144bd4 100644 --- a/web/packages/teleport/src/Console/DocumentNodes/ClusterSelector/ClusterSelector.tsx +++ b/web/packages/teleport/src/Console/DocumentNodes/ClusterSelector/ClusterSelector.tsx @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -import React from 'react'; +import React, { useState } from 'react'; import { Box, LabelInput } from 'design'; import { SelectAsync } from 'shared/components/Select'; @@ -29,8 +29,8 @@ export default function ClusterSelector({ ...styles }) { const consoleCtx = useConsoleContext(); - const [errorMessage, setError] = React.useState(null); - const [options, setOptions] = React.useState([]); + const [errorMessage, setError] = useState(null); + const [options, setOptions] = useState([]); const selectedOption = { value, @@ -44,7 +44,7 @@ export default function ClusterSelector({ function onLoadOptions(inputValue: string) { let promise = Promise.resolve(options); if (options.length === 0) { - promise = consoleCtx + promise = consoleCtx.clustersService .fetchClusters() .then(clusters => clusters.map(o => ({ diff --git a/web/packages/teleport/src/Console/DocumentNodes/DocumentNodes.story.tsx b/web/packages/teleport/src/Console/DocumentNodes/DocumentNodes.story.tsx index 60479166e172d..58dbb1ab37a9b 100644 --- a/web/packages/teleport/src/Console/DocumentNodes/DocumentNodes.story.tsx +++ b/web/packages/teleport/src/Console/DocumentNodes/DocumentNodes.story.tsx @@ -40,7 +40,7 @@ export const Document = ({ value }: { value: ConsoleCtx }) => { export const Loading = () => { const ctx = createContext(); - ctx.fetchNodes = () => new Promise(() => null); + ctx.nodesService.fetchNodes = () => new Promise(() => null); return ( @@ -50,7 +50,8 @@ export const Loading = () => { export const Failed = () => { const ctx = createContext(); - ctx.fetchNodes = () => Promise.reject(new Error('Failed to load nodes')); + ctx.nodesService.fetchNodes = () => + Promise.reject(new Error('Failed to load nodes')); return ( @@ -58,12 +59,13 @@ export const Failed = () => { ); }; -export function createContext() { +export function createContext(): ConsoleCtx { const ctx = new ConsoleCtx(); - ctx.fetchClusters = () => { + ctx.clustersService.fetchClusters = () => { return Promise.resolve(clusters); }; + ctx.nodesService.fetchNodes = () => { return Promise.resolve({ agents: nodes, totalCount: nodes.length }); }; @@ -72,7 +74,7 @@ export function createContext() { } const doc = { - clusterId: 'cluseter-1', + clusterId: 'cluster-1', created: new Date('2019-05-13T20:18:09Z'), kind: 'nodes', url: 'localhost', @@ -84,14 +86,14 @@ const doc = { const clusters = [ { - clusterId: 'cluseter-1', + clusterId: 'cluster-1', connected: new Date(), connectedText: '', status: '', url: '', }, { - clusterId: 'cluseter-2', + clusterId: 'cluster-2', connected: new Date(), connectedText: '', status: '', @@ -106,7 +108,7 @@ const nodes: Node[] = [ tunnel: false, sshLogins: ['dev', 'root'], id: '104', - clusterId: 'cluseter-1', + clusterId: 'cluster-1', hostname: 'fujedu', addr: '172.10.1.20:3022', labels: [ @@ -126,7 +128,7 @@ const nodes: Node[] = [ tunnel: false, sshLogins: ['dev', 'root'], id: '170', - clusterId: 'cluseter-1', + clusterId: 'cluster-1', hostname: 'facuzguv', addr: '172.10.1.42:3022', labels: [ @@ -146,7 +148,7 @@ const nodes: Node[] = [ tunnel: true, sshLogins: ['dev', 'root'], id: '192', - clusterId: 'cluseter-1', + clusterId: 'cluster-1', hostname: 'duzsevkig', addr: '172.10.1.156:3022', labels: [ @@ -166,7 +168,7 @@ const nodes: Node[] = [ tunnel: true, sshLogins: ['dev', 'root'], id: '64', - clusterId: 'cluseter-1', + clusterId: 'cluster-1', hostname: 'kuhinur', addr: '172.10.1.145:3022', labels: [ @@ -186,7 +188,7 @@ const nodes: Node[] = [ tunnel: false, sshLogins: ['dev', 'root'], id: '81', - clusterId: 'cluseter-1', + clusterId: 'cluster-1', hostname: 'zebpecda', addr: '172.10.1.24:3022', labels: [ diff --git a/web/packages/teleport/src/Console/DocumentNodes/__snapshots__/DocumentNodes.story.test.tsx.snap b/web/packages/teleport/src/Console/DocumentNodes/__snapshots__/DocumentNodes.story.test.tsx.snap index ea766088c5d00..eb1905c39fb02 100644 --- a/web/packages/teleport/src/Console/DocumentNodes/__snapshots__/DocumentNodes.story.test.tsx.snap +++ b/web/packages/teleport/src/Console/DocumentNodes/__snapshots__/DocumentNodes.story.test.tsx.snap @@ -29,21 +29,70 @@ exports[`render DocumentNodes 1`] = ` .c7 { box-sizing: border-box; + text-align: center; } -.c14 { +.c9 { + box-sizing: border-box; +} + +.c19 { box-sizing: border-box; padding-left: 24px; padding-right: 24px; } -.c24 { +.c29 { box-sizing: border-box; margin-bottom: 4px; margin-right: 8px; } -.c31 { +.c10 { + line-height: 1.5; + margin: 0; + display: inline-flex; + justify-content: center; + align-items: center; + box-sizing: border-box; + border: none; + border-radius: 4px; + cursor: pointer; + font-family: inherit; + font-weight: 600; + outline: none; + position: relative; + text-align: center; + text-decoration: none; + text-transform: uppercase; + transition: all 0.3s; + -webkit-font-smoothing: antialiased; + color: #FFFFFF; + background: rgba(255,255,255,0.07); + font-size: 10px; + min-height: 24px; + padding: 0px 16px; + padding-left: 8px; + padding-right: 8px; + text-transform: none; +} + +.c10:hover, +.c10:focus { + background: rgba(255,255,255,0.13); +} + +.c10:active { + background: rgba(255,255,255,0.18); +} + +.c10:disabled { + background: rgba(255,255,255,0.12); + color: rgba(255,255,255,0.3); + cursor: auto; +} + +.c36 { line-height: 1.5; margin: 0; display: inline-flex; @@ -71,28 +120,36 @@ exports[`render DocumentNodes 1`] = ` height: 24px; } -.c31:hover, -.c31:focus { +.c36:hover, +.c36:focus { background: rgba(255,255,255,0.07); } -.c31:active { +.c36:active { background: rgba(255,255,255,0.13); } -.c31:disabled { +.c36:disabled { background: rgba(255,255,255,0.12); color: rgba(255,255,255,0.3); cursor: auto; } -.c22 { +.c12 { display: inline-flex; align-items: center; justify-content: center; + color: rgba(255,255,255,0.72); + margin-left: 8px; } -.c32 { +.c27 { + display: inline-flex; + align-items: center; + justify-content: center; +} + +.c37 { display: inline-flex; align-items: center; justify-content: center; @@ -108,7 +165,7 @@ exports[`render DocumentNodes 1`] = ` margin: 0px; } -.c20 { +.c25 { overflow: hidden; text-overflow: ellipsis; font-weight: 400; @@ -117,7 +174,7 @@ exports[`render DocumentNodes 1`] = ` margin: 0px; } -.c26 { +.c31 { overflow: hidden; text-overflow: ellipsis; font-weight: 400; @@ -128,7 +185,7 @@ exports[`render DocumentNodes 1`] = ` font-weight: 500; } -.c29 { +.c34 { box-sizing: border-box; border-radius: 10px; display: inline-block; @@ -148,38 +205,43 @@ exports[`render DocumentNodes 1`] = ` } .c8 { + display: flex; + align-items: center; +} + +.c13 { display: flex; flex-direction: column; } -.c15 { +.c20 { display: flex; align-items: center; gap: 8px; } -.c25 { +.c30 { display: flex; justify-content: flex-end; } -.c28 { +.c33 { display: flex; flex-wrap: wrap; } -.c16 { +.c21 { position: relative; display: flex; align-items: center; cursor: pointer; } -.c16[disabled] { +.c21[disabled] { cursor: default; } -.c19 { +.c24 { width: 32px; height: 16px; border-radius: 10px; @@ -189,15 +251,15 @@ exports[`render DocumentNodes 1`] = ` transition: background 0.15s ease-in-out; } -.c19:hover { +.c24:hover { background: rgba(255,255,255,0.13); } -.c19:active { +.c24:active { background: rgba(255,255,255,0.18); } -.c19:before { +.c24:before { content: ''; position: absolute; top: 50%; @@ -210,59 +272,63 @@ exports[`render DocumentNodes 1`] = ` transition: transform 0.05s ease-in; } -.c17 { +.c22 { opacity: 0; position: absolute; cursor: inherit; z-index: -1; } -.c17:checked + .c18:before { +.c22:checked + .c23:before { transform: translate(18px,-50%); } -.c17:enabled:checked + .c18 { +.c22:enabled:checked + .c23 { background: #00BFA6; } -.c17:enabled:checked + .c18:hover { +.c22:enabled:checked + .c23:hover { background: #33CCB8; } -.c17:enabled:checked + .c18:active { +.c22:enabled:checked + .c23:active { background: #66D9CA; } -.c17:disabled + .c18 { +.c22:disabled + .c23 { background: rgba(255,255,255,0.07); } -.c17:disabled + .c18:before { +.c22:disabled + .c23:before { opacity: 0.36; box-shadow: none; } -.c17:disabled:checked + .c18 { +.c22:disabled:checked + .c23 { background: rgba(0,191,166,0.25); } -.c23 { +.c28 { height: 18px; width: 18px; color: inherit; } -.c21 { +.c26 { vertical-align: middle; display: inline-block; height: 18px; } -.c21:hover { +.c26:hover { cursor: pointer; } -.c27 { +.c11 { + border-color: rgba(255,255,255,0.07); +} + +.c32 { border-collapse: collapse; border-spacing: 0; border-style: hidden; @@ -270,39 +336,39 @@ exports[`render DocumentNodes 1`] = ` width: 100%; } -.c27 > thead > tr > th, -.c27 > tbody > tr > th, -.c27 > tfoot > tr > th, -.c27 > thead > tr > td, -.c27 > tbody > tr > td, -.c27 > tfoot > tr > td { +.c32 > thead > tr > th, +.c32 > tbody > tr > th, +.c32 > tfoot > tr > th, +.c32 > thead > tr > td, +.c32 > tbody > tr > td, +.c32 > tfoot > tr > td { padding: 8px 8px; vertical-align: middle; } -.c27 > thead > tr > th:first-child, -.c27 > tbody > tr > th:first-child, -.c27 > tfoot > tr > th:first-child, -.c27 > thead > tr > td:first-child, -.c27 > tbody > tr > td:first-child, -.c27 > tfoot > tr > td:first-child { +.c32 > thead > tr > th:first-child, +.c32 > tbody > tr > th:first-child, +.c32 > tfoot > tr > th:first-child, +.c32 > thead > tr > td:first-child, +.c32 > tbody > tr > td:first-child, +.c32 > tfoot > tr > td:first-child { padding-left: 24px; } -.c27 > thead > tr > th:last-child, -.c27 > tbody > tr > th:last-child, -.c27 > tfoot > tr > th:last-child, -.c27 > thead > tr > td:last-child, -.c27 > tbody > tr > td:last-child, -.c27 > tfoot > tr > td:last-child { +.c32 > thead > tr > th:last-child, +.c32 > tbody > tr > th:last-child, +.c32 > tfoot > tr > th:last-child, +.c32 > thead > tr > td:last-child, +.c32 > tbody > tr > td:last-child, +.c32 > tfoot > tr > td:last-child { padding-right: 24px; } -.c27 > tbody > tr > td { +.c32 > tbody > tr > td { vertical-align: middle; } -.c27 > thead > tr > th { +.c32 > thead > tr > th { color: #FFFFFF; font-weight: 600; font-size: 14px; @@ -314,11 +380,11 @@ exports[`render DocumentNodes 1`] = ` white-space: nowrap; } -.c27 > thead > tr > th svg { +.c32 > thead > tr > th svg { height: 12px; } -.c27 > tbody > tr > td { +.c32 > tbody > tr > td { color: #FFFFFF; font-weight: 300; font-size: 14px; @@ -326,18 +392,18 @@ exports[`render DocumentNodes 1`] = ` letter-spacing: 0.035px; } -.c27 tbody tr { +.c32 tbody tr { transition: all 150ms; position: relative; border-top: 2px solid rgba(255,255,255,0.07); } -.c27 tbody tr:hover { +.c32 tbody tr:hover { border-top: 2px solid rgba(0,0,0,0); background-color: #222C59; } -.c27 tbody tr:hover:after { +.c32 tbody tr:hover:after { box-shadow: 0px 1px 10px 0px rgba(0,0,0,0.12),0px 4px 5px 0px rgba(0,0,0,0.14),0px 2px 4px -1px rgba(0,0,0,0.20); content: ''; position: absolute; @@ -348,19 +414,19 @@ exports[`render DocumentNodes 1`] = ` height: 100%; } -.c27 tbody tr:hover + tr { +.c32 tbody tr:hover + tr { border-top: 2px solid rgba(0,0,0,0); } -.c30 { +.c35 { cursor: pointer; } -.c30:hover { +.c35:hover { background-color: rgba(255,255,255,0.13); } -.c13 { +.c18 { position: relative; height: 100%; right: 0; @@ -370,7 +436,7 @@ exports[`render DocumentNodes 1`] = ` border-radius: 0 200px 200px 0; } -.c12 { +.c17 { position: absolute; height: 100%; right: 0; @@ -381,7 +447,7 @@ exports[`render DocumentNodes 1`] = ` border-radius: 0 200px 200px 0; } -.c10 { +.c15 { position: relative; display: flex; overflow: hidden; @@ -391,14 +457,14 @@ exports[`render DocumentNodes 1`] = ` max-width: 725px; } -.c9 { +.c14 { border-radius: 200px; width: 100%; height: 56px; margin-bottom: 12px; } -.c11 { +.c16 { border: none; outline: none; box-sizing: border-box; @@ -448,53 +514,84 @@ exports[`render DocumentNodes 1`] = ` > Clusters: +
+
+ +
+