From 37372440abbb069196f0d2d21863909c7ae32460 Mon Sep 17 00:00:00 2001 From: Matej Kubinec <32638572+matejkubinec@users.noreply.github.com> Date: Mon, 28 Aug 2023 13:09:32 +0200 Subject: [PATCH] PMM-11148 Service management - Add/Edit service (#599) * PMM-1148 initial inventory management rework * PMM-11148 Refactor AddInstance * PMM-11148 remove unnecessary tooltip icon * PMM-11148 Fix discovery tests * PMM-11148 Fix add instance submission * PMM-11148 Integrate service editing api * PMM-11148 fix custom labels field * PMM-11148 add success modal * PMM-11148 fix inventory test * PMM-11148 add labels tooltip & fix description * PMM-11148 refactor * PMM-11148 add required property * PMM-11148 add feature check * PMM-11148 adjust services delete * PMM-11148 remove documentation links * PMM-11148 Wording, boolean state, etc. * PMM-11148 update tablestat options name * PMM-11148 Extract messages for service tab * PMM-11148 Add warning when changing cluster label * PMM-11148 Add docs link to confirm edit service dialog * PMM-11148 Update api endpoint name * PMM-11148 Move delete services modal to component * PMM-11148 Fix bugs * PMM-11148 Call onSucces when single service is deleted * PMM-11148 Import FC directly * PMM-11148 Fix spacing * PMM-11148 Fix errors from component library integration * PMM-11148 Fix DeleteServicesModal tests * PMM-11148 Use correct urls for services * PMM-11148 Use shortened docs link * PMM-11148 Increase width for azure instance form * PMM-11148 Jump straight to add instance page & reorder --- .../AddInstance/AddInstance.messages.ts | 2 + .../AddInstance/AddInstance.styles.ts | 52 ++---- .../AddInstance/AddInstance.test.tsx | 20 +- .../components/AddInstance/AddInstance.tsx | 52 +++--- .../AddInstance/AddInstance.types.ts | 19 +- .../AddRemoteInstance.messages.ts | 15 ++ .../AddRemoteInstance.styles.ts | 2 +- .../AddRemoteInstance.test.tsx | 6 +- .../AddRemoteInstance/AddRemoteInstance.tsx | 39 ++-- .../AddRemoteInstance.types.ts | 1 + .../AdditionalOptions/AdditionalOptions.tsx | 43 +++-- .../ExternalServiceConnectionDetails.tsx | 162 ++++++++-------- .../FormParts/FormParts.messages.ts | 13 +- .../FormParts/FormParts.styles.tsx | 50 ++++- .../FormParts/FormParts.test.tsx | 1 + .../HAProxyConnectionDetails.tsx | 94 +++++----- .../FormParts/Labels/Labels.tsx | 98 ++++++---- .../FormParts/Labels/Labels.types.ts | 3 + .../FormParts/MainDetails/MainDetails.tsx | 87 +++++---- .../MongoDBConnectionDetails.tsx | 106 +++++------ .../MySQLConnectionDetails.tsx | 107 +++++------ .../PostgreSQLConnectionDetails.tsx | 122 ++++++------ .../AzureDiscovery/Discovery.test.tsx | 5 +- .../components/AzureDiscovery/Discovery.tsx | 2 +- .../AzureDiscovery/Discovery.types.ts | 1 + .../Credentials/Credentials.styles.ts | 1 + .../components/Credentials/Credentials.tsx | 8 +- .../components/Discovery/Discovery.test.tsx | 4 +- .../components/Discovery/Discovery.tsx | 4 +- .../components/Discovery/Discovery.types.ts | 1 + .../Discovery/__mocks__/Discovery.service.ts | 10 + .../Credentials/Credentials.test.tsx | 4 +- .../components/Credentials/Credentials.tsx | 21 +-- .../Credentials/Credentials.types.ts | 3 - .../percona/add-instance/panel.constants.ts | 1 + .../app/percona/add-instance/panel.styles.ts | 10 +- public/app/percona/add-instance/panel.tsx | 111 +++++++---- .../app/percona/add-instance/panel.types.ts | 4 + .../edit-instance/EditInstance.constants.ts | 2 + .../edit-instance/EditInstance.messages.ts | 26 +++ .../edit-instance/EditInstance.styles.ts | 12 ++ .../edit-instance/EditInstance.test.tsx | 35 ++++ .../percona/edit-instance/EditInstance.tsx | 151 +++++++++++++++ .../edit-instance/EditInstance.types.ts | 10 + .../edit-instance/EditInstance.utils.ts | 41 ++++ .../percona/inventory/Inventory.messages.ts | 1 + .../percona/inventory/Inventory.service.ts | 6 + public/app/percona/inventory/Tabs/Nodes.tsx | 4 +- .../app/percona/inventory/Tabs/Services.tsx | 130 ++++--------- .../app/percona/inventory/Tabs/Tabs.styles.ts | 6 +- .../inventory/__mocks__/Inventory.service.ts | 29 ++- .../DeleteServiceModal.messages.ts | 13 ++ .../DeleteServiceModal.test.tsx | 119 ++++++++++++ .../DeleteServiceModal/DeleteServiceModal.tsx | 70 +++++++ .../DeleteServiceModal.types.ts | 7 + .../components/DeleteServiceModal/index.ts | 3 + .../DeleteServicesModal.messages.ts | 14 ++ .../DeleteServicesModal.test.tsx | 175 ++++++++++++++++++ .../DeleteServicesModal.tsx | 74 ++++++++ .../DeleteServicesModal.types.ts | 10 + .../components/DeleteServicesModal/index.ts | 3 + .../PerconaNavigation.constants.ts | 8 + .../PerconaNavigation/PerconaNavigation.tsx | 2 + .../shared/core/reducers/services/services.ts | 60 +++++- .../core/reducers/services/services.types.ts | 14 +- .../core/reducers/services/services.utils.ts | 78 +++++++- .../services/services/Services.service.ts | 19 +- .../services/services/Services.types.ts | 18 ++ .../services/__mocks__/Services.service.ts | 12 ++ public/app/routes/routes.tsx | 12 ++ 70 files changed, 1786 insertions(+), 662 deletions(-) create mode 100644 public/app/percona/add-instance/components/AddRemoteInstance/FormParts/Labels/Labels.types.ts create mode 100644 public/app/percona/add-instance/components/Discovery/__mocks__/Discovery.service.ts create mode 100644 public/app/percona/add-instance/panel.constants.ts create mode 100644 public/app/percona/edit-instance/EditInstance.constants.ts create mode 100644 public/app/percona/edit-instance/EditInstance.messages.ts create mode 100644 public/app/percona/edit-instance/EditInstance.styles.ts create mode 100644 public/app/percona/edit-instance/EditInstance.test.tsx create mode 100644 public/app/percona/edit-instance/EditInstance.tsx create mode 100644 public/app/percona/edit-instance/EditInstance.types.ts create mode 100644 public/app/percona/edit-instance/EditInstance.utils.ts create mode 100644 public/app/percona/inventory/components/DeleteServiceModal/DeleteServiceModal.messages.ts create mode 100644 public/app/percona/inventory/components/DeleteServiceModal/DeleteServiceModal.test.tsx create mode 100644 public/app/percona/inventory/components/DeleteServiceModal/DeleteServiceModal.tsx create mode 100644 public/app/percona/inventory/components/DeleteServiceModal/DeleteServiceModal.types.ts create mode 100644 public/app/percona/inventory/components/DeleteServiceModal/index.ts create mode 100644 public/app/percona/inventory/components/DeleteServicesModal/DeleteServicesModal.messages.ts create mode 100644 public/app/percona/inventory/components/DeleteServicesModal/DeleteServicesModal.test.tsx create mode 100644 public/app/percona/inventory/components/DeleteServicesModal/DeleteServicesModal.tsx create mode 100644 public/app/percona/inventory/components/DeleteServicesModal/DeleteServicesModal.types.ts create mode 100644 public/app/percona/inventory/components/DeleteServicesModal/index.ts create mode 100644 public/app/percona/shared/services/services/__mocks__/Services.service.ts diff --git a/public/app/percona/add-instance/components/AddInstance/AddInstance.messages.ts b/public/app/percona/add-instance/components/AddInstance/AddInstance.messages.ts index 3f8b44e707235..6ce0866fce218 100644 --- a/public/app/percona/add-instance/components/AddInstance/AddInstance.messages.ts +++ b/public/app/percona/add-instance/components/AddInstance/AddInstance.messages.ts @@ -1,4 +1,6 @@ export const Messages = { + sectionTitle: 'Select service type', + description: 'Select the service type you want to configure and then add it to your inventory.', titles: { rds: 'Amazon RDS', azure: 'Microsoft Azure MySQL or PostgreSQL', diff --git a/public/app/percona/add-instance/components/AddInstance/AddInstance.styles.ts b/public/app/percona/add-instance/components/AddInstance/AddInstance.styles.ts index 7a68c6d2aa1df..d53786ce51856 100644 --- a/public/app/percona/add-instance/components/AddInstance/AddInstance.styles.ts +++ b/public/app/percona/add-instance/components/AddInstance/AddInstance.styles.ts @@ -1,52 +1,30 @@ import { css } from '@emotion/css'; -import { GrafanaTheme } from '@grafana/data'; +import { GrafanaTheme2 } from '@grafana/data'; -export const getStyles = ({ border, colors, spacing, typography }: GrafanaTheme) => ({ - navigationButton: css` +export const getStyles = (theme: GrafanaTheme2) => ({ + Content: css` display: flex; flex-direction: column; - justify-content: flex-end; - align-items: center; - padding-bottom: 1.2em; - margin: ${spacing.sm}; - border-radius: ${border.radius.md}; - width: 230px; - height: 160px; - text-align: center; - background-color: transparent; - border: ${border.width.sm} dashed ${colors.border2}; - - :hover { - cursor: pointer; - background-color: ${colors.dropdownOptionHoverBg}; - border: ${border.width.sm} solid ${colors.border2}; - } + align-items: flex-start; `, - navigationPanel: css` + NavigationPanel: css` display: flex; flex-direction: row; - justify-content: center; + justify-content: flex-start; flex-wrap: wrap; - max-width: 800px; + max-width: 825px; width: 100%; overflow: hidden; + gap: ${theme.spacing(2)}; + padding: 3px; + margin: -3px; `, - content: css` - display: flex; - flex-direction: column; - align-items: center; - margin-top: 2em; + InstanceCard: css` + width: 375px; + margin: 0; `, - addInstance: css` - margin-top: ${spacing.sm}; - font-size: ${typography.size.sm}; - `, - addInstanceTitle: css` - margin-top: ${spacing.sm}; - overflow: hidden; - line-height: ${typography.lineHeight.md}; - width: 65%; - height: 3em; + Description: css` + color: ${theme.colors.text.secondary}; `, }); diff --git a/public/app/percona/add-instance/components/AddInstance/AddInstance.test.tsx b/public/app/percona/add-instance/components/AddInstance/AddInstance.test.tsx index c599bed11cdb8..8210fc97ebc54 100644 --- a/public/app/percona/add-instance/components/AddInstance/AddInstance.test.tsx +++ b/public/app/percona/add-instance/components/AddInstance/AddInstance.test.tsx @@ -5,14 +5,20 @@ import { Provider } from 'react-redux'; import { configureStore } from 'app/store/configureStore'; import { StoreState } from 'app/types'; +import { InstanceAvailable } from '../../panel.types'; + import { AddInstance } from './AddInstance'; import { instanceList } from './AddInstance.constants'; jest.mock('app/percona/settings/Settings.service'); +const selectedInstanceType: InstanceAvailable = { type: '' }; + describe('AddInstance page::', () => { it('should render a given number of links', async () => { - const ui = withStore( {}} />); + const ui = withStore( + {}} selectedInstanceType={selectedInstanceType} /> + ); await waitFor(() => render(ui)); expect(screen.getAllByRole('button')).toHaveLength(instanceList.length); @@ -22,7 +28,9 @@ describe('AddInstance page::', () => { }); it('should render azure option', async () => { - const ui = withStore( {}} />); + const ui = withStore( + {}} selectedInstanceType={selectedInstanceType} /> + ); await waitFor(() => render(ui)); expect(screen.getAllByRole('button')).toHaveLength(instanceList.length + 1); @@ -35,13 +43,15 @@ describe('AddInstance page::', () => { it('should invoke a callback with a proper instance type', async () => { const onSelectInstanceType = jest.fn(); - const ui = withStore(); + const ui = withStore( + + ); render(ui); expect(onSelectInstanceType).toBeCalledTimes(0); - const button = await screen.findByTestId('rds-instance'); - fireEvent.click(button); + const button = (await screen.findByTestId('rds-instance')).querySelector('button'); + fireEvent.click(button!); expect(onSelectInstanceType).toBeCalledTimes(1); expect(onSelectInstanceType.mock.calls[0][0]).toStrictEqual({ type: 'rds' }); diff --git a/public/app/percona/add-instance/components/AddInstance/AddInstance.tsx b/public/app/percona/add-instance/components/AddInstance/AddInstance.tsx index 0ade58abc3544..19f5d4b9b95e0 100644 --- a/public/app/percona/add-instance/components/AddInstance/AddInstance.tsx +++ b/public/app/percona/add-instance/components/AddInstance/AddInstance.tsx @@ -2,8 +2,7 @@ import React, { FC, useMemo } from 'react'; import { v4 as uuidv4 } from 'uuid'; -import { useStyles } from '@grafana/ui'; -import { Database } from 'app/percona/shared/components/Elements/Icons/Database'; +import { Card, Icon, useStyles2 } from '@grafana/ui'; import { Databases } from 'app/percona/shared/core'; import * as UserFlow from 'app/percona/shared/core/reducers/userFlow'; import { useDispatch } from 'app/types'; @@ -12,37 +11,34 @@ import { InstanceAvailableType, InstanceTypesExtra } from '../../panel.types'; import { Messages } from './AddInstance.messages'; import { getStyles } from './AddInstance.styles'; -import { AddInstanceProps, SelectInstanceProps } from './AddInstance.types'; +import { AddInstanceProps, InstanceListItem, SelectInstanceProps } from './AddInstance.types'; -export const SelectInstance: FC = ({ type, selectInstanceType, title }) => { - const styles = useStyles(getStyles); +export const SelectInstance: FC = ({ type, isSelected, icon, selectInstanceType, title }) => { + const styles = useStyles2(getStyles); return ( - + + {title} + {Messages.titles.addInstance} + + + + ); }; -export const AddInstance: FC = ({ onSelectInstanceType, showAzure }) => { - const styles = useStyles(getStyles); - const instanceList = useMemo( +export const AddInstance: FC = ({ selectedInstanceType, onSelectInstanceType, showAzure }) => { + const styles2 = useStyles2(getStyles); + const instanceList = useMemo( () => [ { type: InstanceTypesExtra.rds, title: Messages.titles.rds }, - { type: InstanceTypesExtra.azure, title: Messages.titles.azure, isHidden: !showAzure }, - { type: Databases.postgresql, title: Messages.titles.postgresql }, - { type: Databases.mysql, title: Messages.titles.mysql }, - { type: Databases.mongodb, title: Messages.titles.mongodb }, - { type: Databases.proxysql, title: Messages.titles.proxysql }, + { type: Databases.mysql, title: Messages.titles.mysql, icon: 'percona-database-mysql' }, + { type: Databases.mongodb, title: Messages.titles.mongodb, icon: 'percona-database-mongodb' }, + { type: Databases.postgresql, title: Messages.titles.postgresql, icon: 'percona-database-postgresql' }, + { type: Databases.proxysql, title: Messages.titles.proxysql, icon: 'percona-database-proxysql' }, + { type: Databases.haproxy, title: Messages.titles.haproxy, icon: 'percona-database-haproxy' }, { type: InstanceTypesExtra.external, title: Messages.titles.external }, - { type: Databases.haproxy, title: Messages.titles.haproxy }, + { type: InstanceTypesExtra.azure, title: Messages.titles.azure, isHidden: !showAzure }, ], [showAzure] ); @@ -61,14 +57,18 @@ export const AddInstance: FC = ({ onSelectInstanceType, showAz }; return ( -
-