From e19187f1a8bb04849af924f6b58b87095c1bf42e Mon Sep 17 00:00:00 2001 From: ecarrill Date: Thu, 21 Nov 2024 08:37:53 -0800 Subject: [PATCH 1/5] fix: [M3-8538] - Fix Linode clone CLI Modal --- .../ApiAwarenessModal/CurlTabPanel.tsx | 22 +++++++++++++++---- .../ApiAwarenessModal/LinodeCLIPanel.tsx | 18 ++++++++++++++- .../utilities/codesnippets/generate-cli.ts | 18 +++++++++++---- 3 files changed, 49 insertions(+), 9 deletions(-) diff --git a/packages/manager/src/features/Linodes/LinodeCreate/ApiAwarenessModal/CurlTabPanel.tsx b/packages/manager/src/features/Linodes/LinodeCreate/ApiAwarenessModal/CurlTabPanel.tsx index c310d06cb95..a5b81af8c58 100644 --- a/packages/manager/src/features/Linodes/LinodeCreate/ApiAwarenessModal/CurlTabPanel.tsx +++ b/packages/manager/src/features/Linodes/LinodeCreate/ApiAwarenessModal/CurlTabPanel.tsx @@ -1,5 +1,6 @@ import { useTheme } from '@mui/material/styles'; import React, { useMemo } from 'react'; +import { useFormContext } from 'react-hook-form'; import { CodeBlock } from 'src/components/CodeBlock/CodeBlock'; import { Link } from 'src/components/Link'; @@ -8,6 +9,9 @@ import { Typography } from 'src/components/Typography'; import { sendApiAwarenessClickEvent } from 'src/utilities/analytics/customEventAnalytics'; import { generateCurlCommand } from 'src/utilities/codesnippets/generate-cURL'; +import { useLinodeCreateQueryParams } from '../utilities'; + +import type { LinodeCreateFormValues } from '../utilities'; import type { CreateLinodeRequest } from '@linode/api-v4/lib/linodes'; export interface CurlTabPanelProps { @@ -19,10 +23,20 @@ export interface CurlTabPanelProps { export const CurlTabPanel = ({ index, payLoad, title }: CurlTabPanelProps) => { const theme = useTheme(); - const curlCommand = useMemo( - () => generateCurlCommand(payLoad, '/linode/instances'), - [payLoad] - ); + const { getValues } = useFormContext(); + const sourceLinodeID = getValues('linode.id'); + + const { params } = useLinodeCreateQueryParams(); + const linodeCLIAction = params.type === 'Clone Linode' ? 'clone' : 'create'; + const path = + linodeCLIAction === 'create' + ? '/linode/instances' + : `linode/instances/${sourceLinodeID}/clone`; + + const curlCommand = useMemo(() => generateCurlCommand(payLoad, path), [ + path, + payLoad, + ]); return ( diff --git a/packages/manager/src/features/Linodes/LinodeCreate/ApiAwarenessModal/LinodeCLIPanel.tsx b/packages/manager/src/features/Linodes/LinodeCreate/ApiAwarenessModal/LinodeCLIPanel.tsx index 2819616ddf0..3d28738eaf4 100644 --- a/packages/manager/src/features/Linodes/LinodeCreate/ApiAwarenessModal/LinodeCLIPanel.tsx +++ b/packages/manager/src/features/Linodes/LinodeCreate/ApiAwarenessModal/LinodeCLIPanel.tsx @@ -1,4 +1,5 @@ import React, { useMemo } from 'react'; +import { useFormContext } from 'react-hook-form'; import { CodeBlock } from 'src/components/CodeBlock/CodeBlock'; import { Link } from 'src/components/Link'; @@ -7,6 +8,9 @@ import { Typography } from 'src/components/Typography'; import { sendApiAwarenessClickEvent } from 'src/utilities/analytics/customEventAnalytics'; import { generateCLICommand } from 'src/utilities/codesnippets/generate-cli'; +import { useLinodeCreateQueryParams } from '../utilities'; + +import type { LinodeCreateFormValues } from '../utilities'; import type { CreateLinodeRequest } from '@linode/api-v4/lib/linodes'; export interface LinodeCLIPanelProps { @@ -20,7 +24,19 @@ export const LinodeCLIPanel = ({ payLoad, title, }: LinodeCLIPanelProps) => { - const cliCommand = useMemo(() => generateCLICommand(payLoad), [payLoad]); + const { params } = useLinodeCreateQueryParams(); + const linodeCLIAction = params.type; + // === 'Clone Linode' ? 'clone' : 'create'; + + const { getValues } = useFormContext(); + // const xx = getValues(); + const sourceLinodeID = getValues('linode.id'); + // console.log('sourceLinodeID', sourceLinodeID); + + const cliCommand = useMemo( + () => generateCLICommand(payLoad, sourceLinodeID, linodeCLIAction), + [linodeCLIAction, payLoad, sourceLinodeID] + ); return ( diff --git a/packages/manager/src/utilities/codesnippets/generate-cli.ts b/packages/manager/src/utilities/codesnippets/generate-cli.ts index 088016e5107..b613928f385 100644 --- a/packages/manager/src/utilities/codesnippets/generate-cli.ts +++ b/packages/manager/src/utilities/codesnippets/generate-cli.ts @@ -1,10 +1,9 @@ -import { +import type { PlacementGroup } from '@linode/api-v4'; +import type { ConfigInterfaceIPv4, UserData, } from '@linode/api-v4/lib/linodes/types'; -import type { PlacementGroup } from '@linode/api-v4'; - // Credit: https://github.com/xxorax/node-shell-escape function escapeStringForCLI(s: string): string { if (/[^A-Za-z0-9_\/:=-]/.test(s)) { @@ -111,7 +110,18 @@ const dataEntriesReduce = (acc: string[], [key, value]: JSONFieldToArray) => { return acc; }; -export const generateCLICommand = (data: {}) => { +export const generateCLICommand = ( + data: {}, + sourceLinodeID?: number, + linodeCLIAction?: string +) => { const dataForCLI = Object.entries(data).reduce(dataEntriesReduce, []); + + if (linodeCLIAction === 'Clone Linode') { + return `linode-cli linodes ${linodeCLIAction} ${sourceLinodeID} \\\n${dataForCLI.join( + ' \\\n' + )}`; + } + return `linode-cli linodes create \\\n${dataForCLI.join(' \\\n')}`; }; From bfe6f5148444c8a5a868320b6140dd301a444d63 Mon Sep 17 00:00:00 2001 From: ecarrill Date: Thu, 21 Nov 2024 08:50:08 -0800 Subject: [PATCH 2/5] remove comments --- .../Linodes/LinodeCreate/ApiAwarenessModal/LinodeCLIPanel.tsx | 3 --- 1 file changed, 3 deletions(-) diff --git a/packages/manager/src/features/Linodes/LinodeCreate/ApiAwarenessModal/LinodeCLIPanel.tsx b/packages/manager/src/features/Linodes/LinodeCreate/ApiAwarenessModal/LinodeCLIPanel.tsx index 3d28738eaf4..d22575aac11 100644 --- a/packages/manager/src/features/Linodes/LinodeCreate/ApiAwarenessModal/LinodeCLIPanel.tsx +++ b/packages/manager/src/features/Linodes/LinodeCreate/ApiAwarenessModal/LinodeCLIPanel.tsx @@ -26,12 +26,9 @@ export const LinodeCLIPanel = ({ }: LinodeCLIPanelProps) => { const { params } = useLinodeCreateQueryParams(); const linodeCLIAction = params.type; - // === 'Clone Linode' ? 'clone' : 'create'; const { getValues } = useFormContext(); - // const xx = getValues(); const sourceLinodeID = getValues('linode.id'); - // console.log('sourceLinodeID', sourceLinodeID); const cliCommand = useMemo( () => generateCLICommand(payLoad, sourceLinodeID, linodeCLIAction), From d054c7e376c1845e3d7f9a74ade0f39e252fdd34 Mon Sep 17 00:00:00 2001 From: ecarrill Date: Thu, 21 Nov 2024 10:04:42 -0800 Subject: [PATCH 3/5] Fix cli command --- packages/manager/src/utilities/codesnippets/generate-cli.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/manager/src/utilities/codesnippets/generate-cli.ts b/packages/manager/src/utilities/codesnippets/generate-cli.ts index b613928f385..aea5a483275 100644 --- a/packages/manager/src/utilities/codesnippets/generate-cli.ts +++ b/packages/manager/src/utilities/codesnippets/generate-cli.ts @@ -118,7 +118,7 @@ export const generateCLICommand = ( const dataForCLI = Object.entries(data).reduce(dataEntriesReduce, []); if (linodeCLIAction === 'Clone Linode') { - return `linode-cli linodes ${linodeCLIAction} ${sourceLinodeID} \\\n${dataForCLI.join( + return `linode-cli linodes clone ${sourceLinodeID} \\\n${dataForCLI.join( ' \\\n' )}`; } From 94089ff60992c23287796967aef5a2d4dd5daa91 Mon Sep 17 00:00:00 2001 From: ecarrill Date: Mon, 2 Dec 2024 12:53:36 -0800 Subject: [PATCH 4/5] Fix typos and unit tests and add missing slash in api url --- .../ApiAwarenessModal/ApiAwarenessModal.test.tsx | 14 +++++++++----- .../ApiAwarenessModal/CurlTabPanel.tsx | 2 +- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/packages/manager/src/features/Linodes/LinodeCreate/ApiAwarenessModal/ApiAwarenessModal.test.tsx b/packages/manager/src/features/Linodes/LinodeCreate/ApiAwarenessModal/ApiAwarenessModal.test.tsx index 75acedc1b43..ad88f63e3cc 100644 --- a/packages/manager/src/features/Linodes/LinodeCreate/ApiAwarenessModal/ApiAwarenessModal.test.tsx +++ b/packages/manager/src/features/Linodes/LinodeCreate/ApiAwarenessModal/ApiAwarenessModal.test.tsx @@ -2,10 +2,11 @@ import { screen } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import React from 'react'; -import { renderWithTheme } from 'src/utilities/testHelpers'; +import { renderWithThemeAndHookFormContext } from 'src/utilities/testHelpers'; import { ApiAwarenessModal } from './ApiAwarenessModal'; +import type { LinodeCreateFormValues } from '../utilities'; import type { ApiAwarenessModalProps } from './ApiAwarenessModal'; const defaultProps: ApiAwarenessModalProps = { @@ -19,19 +20,22 @@ const renderComponent = (overrideProps?: Partial) => { ...defaultProps, ...overrideProps, }; - return renderWithTheme(); + + return renderWithThemeAndHookFormContext({ + component: , + }); }; describe('ApiAwarenessModal', () => { - it('Should not render ApiAwarenessModal componet', () => { + it('Should not render ApiAwarenessModal component', () => { renderComponent(); expect(screen.queryByText('Create Linode')).not.toBeInTheDocument(); }); - it('Should render ApiAwarenessModal componet when enabled', () => { + it('Should render ApiAwarenessModal component when enabled', () => { renderComponent({ isOpen: true }); screen.getByText('Create Linode'); }); - it('Should invoke onClose handler upon cliking close button', async () => { + it('Should invoke onClose handler upon clicking close button', async () => { renderComponent({ isOpen: true }); await userEvent.click(screen.getByTestId('close-button')); expect(defaultProps.onClose).toHaveBeenCalledTimes(1); diff --git a/packages/manager/src/features/Linodes/LinodeCreate/ApiAwarenessModal/CurlTabPanel.tsx b/packages/manager/src/features/Linodes/LinodeCreate/ApiAwarenessModal/CurlTabPanel.tsx index 71a3864a49f..a9a7ffa38d6 100644 --- a/packages/manager/src/features/Linodes/LinodeCreate/ApiAwarenessModal/CurlTabPanel.tsx +++ b/packages/manager/src/features/Linodes/LinodeCreate/ApiAwarenessModal/CurlTabPanel.tsx @@ -31,7 +31,7 @@ export const CurlTabPanel = ({ index, payLoad, title }: CurlTabPanelProps) => { const path = linodeCLIAction === 'create' ? '/linode/instances' - : `linode/instances/${sourceLinodeID}/clone`; + : `/linode/instances/${sourceLinodeID}/clone`; const curlCommand = useMemo(() => generateCurlCommand(payLoad, path), [ path, From 11590a3cb5696b9f32cf9d390313b471a372f00c Mon Sep 17 00:00:00 2001 From: ecarrill Date: Thu, 5 Dec 2024 10:23:20 -0800 Subject: [PATCH 5/5] Add changeset --- packages/manager/.changeset/pr-11303-fixed-1733422977888.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 packages/manager/.changeset/pr-11303-fixed-1733422977888.md diff --git a/packages/manager/.changeset/pr-11303-fixed-1733422977888.md b/packages/manager/.changeset/pr-11303-fixed-1733422977888.md new file mode 100644 index 00000000000..6819bf30796 --- /dev/null +++ b/packages/manager/.changeset/pr-11303-fixed-1733422977888.md @@ -0,0 +1,5 @@ +--- +"@linode/manager": Fixed +--- + +Incorrect Cloning Commands in Linode CLI Modal ([#11303](https://github.com/linode/manager/pull/11303))