From 6861b2f70ba00cb63d92aa60abc2c7ef2433b2c1 Mon Sep 17 00:00:00 2001 From: solovevayaroslavna Date: Tue, 4 Apr 2023 10:56:10 +0400 Subject: [PATCH 1/4] PMM-11773-Templates-select-issues: fix templates reloading --- .../components/DBCluster/DBCluster.service.ts | 13 -------- .../components/DBCluster/DBCluster.types.ts | 14 +------- .../Templates/Templates.service.ts | 23 ++++++------- .../Templates/Templates.tsx | 32 +++++++++++++++---- .../Templates/Templates.types.ts | 19 +++++++++++ .../Templates/Templates.utils.ts | 14 ++++++++ .../DBCluster/__mocks__/dbClustersStubs.ts | 2 +- .../dbaas/addDBCluster/addDBCluster.ts | 13 ++++---- .../app/percona/shared/core/reducers/index.ts | 11 +++++++ public/app/percona/shared/core/selectors.ts | 1 + 10 files changed, 90 insertions(+), 52 deletions(-) create mode 100644 public/app/percona/dbaas/components/DBCluster/EditDBClusterPage/DBClusterAdvancedOptions/Templates/Templates.utils.ts diff --git a/public/app/percona/dbaas/components/DBCluster/DBCluster.service.ts b/public/app/percona/dbaas/components/DBCluster/DBCluster.service.ts index 82a6ce5b0ee65..6ba1571f0c426 100644 --- a/public/app/percona/dbaas/components/DBCluster/DBCluster.service.ts +++ b/public/app/percona/dbaas/components/DBCluster/DBCluster.service.ts @@ -22,9 +22,6 @@ import { DBClusterListResponse, DBClusterSecretsResponse, DBClusterSecretsRequest, - DBClusterTemplatesResponse, - DBClusterTemplatesRequest, - DBClusterType, DBClusterResponse, } from './DBCluster.types'; import { formatResources } from './DBCluster.utils'; @@ -112,14 +109,4 @@ export abstract class DBClusterService { }; }); } - static async getDBClusterTemplates( - kubernetesClusterName: string, - k8sClusterType: DBClusterType - ): Promise { - return apiManagement.post( - '/DBaaS/Templates/List', - { kubernetes_cluster_name: kubernetesClusterName, cluster_type: k8sClusterType }, - true - ); - } } diff --git a/public/app/percona/dbaas/components/DBCluster/DBCluster.types.ts b/public/app/percona/dbaas/components/DBCluster/DBCluster.types.ts index c65aa036d4c98..95dff17863227 100644 --- a/public/app/percona/dbaas/components/DBCluster/DBCluster.types.ts +++ b/public/app/percona/dbaas/components/DBCluster/DBCluster.types.ts @@ -3,6 +3,7 @@ import { BadgeColor } from '@grafana/ui'; import { Databases } from 'app/percona/shared/core'; import { DBClusterService } from './DBCluster.service'; +import { DBClusterTemplate } from './EditDBClusterPage/DBClusterAdvancedOptions/Templates/Templates.types'; import { Operators } from './EditDBClusterPage/DBClusterBasicOptions/DBClusterBasicOptions.types'; export type AddDBClusterAction = (dbCluster: DBCluster) => void; @@ -267,19 +268,6 @@ export interface DBClusterSecretsRequest { kubernetes_cluster_name: string; } -export interface DBClusterTemplate { - name: string; - kind: string; -} -export interface DBClusterTemplatesResponse { - templates: DBClusterTemplate[]; -} - -export interface DBClusterTemplatesRequest { - kubernetes_cluster_name: string; - cluster_type: DBClusterType; -} - export interface DBClusterSecret { name: string; } diff --git a/public/app/percona/dbaas/components/DBCluster/EditDBClusterPage/DBClusterAdvancedOptions/Templates/Templates.service.ts b/public/app/percona/dbaas/components/DBCluster/EditDBClusterPage/DBClusterAdvancedOptions/Templates/Templates.service.ts index acbd5212290fe..b7744d74df129 100644 --- a/public/app/percona/dbaas/components/DBCluster/EditDBClusterPage/DBClusterAdvancedOptions/Templates/Templates.service.ts +++ b/public/app/percona/dbaas/components/DBCluster/EditDBClusterPage/DBClusterAdvancedOptions/Templates/Templates.service.ts @@ -1,18 +1,15 @@ -import { SelectableValue } from '@grafana/data'; +import { apiManagement } from 'app/percona/shared/helpers/api'; -import { Databases } from '../../../../../../shared/core'; -import { DBClusterService } from '../../../DBCluster.service'; -import { DatabaseToDBClusterTypeMapping } from '../../../DBCluster.types'; +import { DBClusterType } from '../../../DBCluster.types'; + +import { DBClusterTemplatesRequest, DBClusterTemplatesResponse } from './Templates.types'; export const TemplatesService = { - async loadTemplatesOptions(k8sClusterName: string, databaseType: Databases): Promise>> { - const dbClusterType = DatabaseToDBClusterTypeMapping[databaseType]; - const templatesResponse = - dbClusterType && (await DBClusterService.getDBClusterTemplates(k8sClusterName, dbClusterType)); - const templates = templatesResponse?.templates || []; - return templates.map((template) => ({ - label: template.name, - value: template.kind, - })); + getDBaaSTemplates(kubernetesClusterName: string, k8sClusterType: DBClusterType): Promise { + return apiManagement.post( + '/DBaaS/Templates/List', + { kubernetes_cluster_name: kubernetesClusterName, cluster_type: k8sClusterType }, + true + ); }, }; diff --git a/public/app/percona/dbaas/components/DBCluster/EditDBClusterPage/DBClusterAdvancedOptions/Templates/Templates.tsx b/public/app/percona/dbaas/components/DBCluster/EditDBClusterPage/DBClusterAdvancedOptions/Templates/Templates.tsx index b7e2681dd4906..ed5b72cbac417 100644 --- a/public/app/percona/dbaas/components/DBCluster/EditDBClusterPage/DBClusterAdvancedOptions/Templates/Templates.tsx +++ b/public/app/percona/dbaas/components/DBCluster/EditDBClusterPage/DBClusterAdvancedOptions/Templates/Templates.tsx @@ -1,19 +1,39 @@ -import { AsyncSelectField } from '@percona/platform-core'; -import React, { FC } from 'react'; +import React, { FC, useEffect, useMemo } from 'react'; +import { Field } from 'react-final-form'; +import { useDispatch, useSelector } from 'app/types'; + +import { AsyncSelectFieldAdapter } from '../../../../../../shared/components/Form/FieldAdapters/FieldAdapters'; +import { fetchDBaaSTemplatesAction } from '../../../../../../shared/core/reducers'; +import { getDbaaSTemplates } from '../../../../../../shared/core/selectors'; +import { DatabaseToDBClusterTypeMapping } from '../../../DBCluster.types'; import { AdvancedOptionsFields } from '../DBClusterAdvancedOptions.types'; import { Messages } from './Templates.messages'; -import { TemplatesService } from './Templates.service'; import { TemplatesProps } from './Templates.types'; +import { getTemplatesOptions } from './Templates.utils'; export const Templates: FC = ({ k8sClusterName, databaseType }) => { + const dispatch = useDispatch(); + const { result, loading } = useSelector(getDbaaSTemplates); + + const templatesOptions = useMemo(() => getTemplatesOptions(result), [result]); + + useEffect(() => { + const dbClusterType = DatabaseToDBClusterTypeMapping[databaseType]; + if (dbClusterType) { + dispatch(fetchDBaaSTemplatesAction({ k8sClusterName, dbClusterType })); + } + }, [databaseType, dispatch, k8sClusterName]); + return ( - TemplatesService.loadTemplatesOptions(k8sClusterName, databaseType)} - defaultOptions + component={AsyncSelectFieldAdapter} + loading={loading} + options={templatesOptions} /> ); }; diff --git a/public/app/percona/dbaas/components/DBCluster/EditDBClusterPage/DBClusterAdvancedOptions/Templates/Templates.types.ts b/public/app/percona/dbaas/components/DBCluster/EditDBClusterPage/DBClusterAdvancedOptions/Templates/Templates.types.ts index 0755f0b8631e3..c449af48d8a97 100644 --- a/public/app/percona/dbaas/components/DBCluster/EditDBClusterPage/DBClusterAdvancedOptions/Templates/Templates.types.ts +++ b/public/app/percona/dbaas/components/DBCluster/EditDBClusterPage/DBClusterAdvancedOptions/Templates/Templates.types.ts @@ -1,6 +1,25 @@ import { Databases } from '../../../../../../shared/core'; +import { DBClusterType } from '../../../DBCluster.types'; export interface TemplatesProps { k8sClusterName: string; databaseType: Databases; } + +export interface DBClusterTemplate { + name: string; + kind: string; +} +export interface DBClusterTemplatesResponse { + templates: DBClusterTemplate[]; +} + +export interface DBClusterTemplatesRequest { + kubernetes_cluster_name: string; + cluster_type: DBClusterType; +} + +export interface DBClusterTemplate { + name: string; + kind: string; +} diff --git a/public/app/percona/dbaas/components/DBCluster/EditDBClusterPage/DBClusterAdvancedOptions/Templates/Templates.utils.ts b/public/app/percona/dbaas/components/DBCluster/EditDBClusterPage/DBClusterAdvancedOptions/Templates/Templates.utils.ts new file mode 100644 index 0000000000000..ccda856342bab --- /dev/null +++ b/public/app/percona/dbaas/components/DBCluster/EditDBClusterPage/DBClusterAdvancedOptions/Templates/Templates.utils.ts @@ -0,0 +1,14 @@ +import { SelectableValue } from '@grafana/data'; + +import { DBClusterTemplatesResponse } from './Templates.types'; + +export const getTemplatesOptions = ( + templatesResponce: DBClusterTemplatesResponse | undefined +): Array> => { + const templates = templatesResponce?.templates || []; + const options = templates.map((template) => ({ + label: template.name, + value: template.kind, + })); + return options?.length ? [...options, { label: 'Not selected', value: '' }] : []; +}; diff --git a/public/app/percona/dbaas/components/DBCluster/__mocks__/dbClustersStubs.ts b/public/app/percona/dbaas/components/DBCluster/__mocks__/dbClustersStubs.ts index 953bdc71c3de2..4de6b7c21a386 100644 --- a/public/app/percona/dbaas/components/DBCluster/__mocks__/dbClustersStubs.ts +++ b/public/app/percona/dbaas/components/DBCluster/__mocks__/dbClustersStubs.ts @@ -9,8 +9,8 @@ import { DBClusterComponentVersionStatus, DBClusterAllocatedResources, ResourcesWithUnits, - DBClusterTemplate, } from '../DBCluster.types'; +import { DBClusterTemplate } from '../EditDBClusterPage/DBClusterAdvancedOptions/Templates/Templates.types'; import { Operators } from '../EditDBClusterPage/DBClusterBasicOptions/DBClusterBasicOptions.types'; export const dbClustersStub: DBCluster[] = [ diff --git a/public/app/percona/shared/core/reducers/dbaas/addDBCluster/addDBCluster.ts b/public/app/percona/shared/core/reducers/dbaas/addDBCluster/addDBCluster.ts index 2c84432645295..521fac66deb04 100644 --- a/public/app/percona/shared/core/reducers/dbaas/addDBCluster/addDBCluster.ts +++ b/public/app/percona/shared/core/reducers/dbaas/addDBCluster/addDBCluster.ts @@ -124,12 +124,13 @@ export const addDbClusterAction = createAsyncThunk( secretsName: secretsName?.value || '', }, }), - ...(template && { - template: { - name: template.label, - kind: template.value, - }, - }), + ...(template && + template.value && { + template: { + name: template.label, + kind: template.value, + }, + }), }), { successMessage: 'Cluster was successfully added', diff --git a/public/app/percona/shared/core/reducers/index.ts b/public/app/percona/shared/core/reducers/index.ts index 4aaede21240b6..7bfdd7656341c 100644 --- a/public/app/percona/shared/core/reducers/index.ts +++ b/public/app/percona/shared/core/reducers/index.ts @@ -3,6 +3,7 @@ import { combineReducers, createAsyncThunk, createSlice, PayloadAction } from '@ import { CancelToken } from 'axios'; import { createAsyncSlice, withAppEvents, withSerializedError } from 'app/features/alerting/unified/utils/redux'; +import { DBClusterTemplatesResponse } from 'app/percona/dbaas/components/DBCluster/EditDBClusterPage/DBClusterAdvancedOptions/Templates/Templates.types'; import { KubernetesService } from 'app/percona/dbaas/components/Kubernetes/Kubernetes.service'; import { ComponentToUpdate, Kubernetes } from 'app/percona/dbaas/components/Kubernetes/Kubernetes.types'; import { AlertRuleTemplateService } from 'app/percona/integrated-alerting/components/AlertRuleTemplate/AlertRuleTemplate.service'; @@ -12,6 +13,8 @@ import { Settings, SettingsAPIChangePayload } from 'app/percona/settings/Setting import { PlatformService } from 'app/percona/settings/components/Platform/Platform.service'; import { api } from 'app/percona/shared/helpers/api'; +import { DBClusterType } from '../../../dbaas/components/DBCluster/DBCluster.types'; +import { TemplatesService } from '../../../dbaas/components/DBCluster/EditDBClusterPage/DBClusterAdvancedOptions/Templates/Templates.service'; import { ServerInfo } from '../types'; import advisorsReducers from './advisors/advisors'; @@ -213,6 +216,12 @@ export const fetchTemplatesAction = createAsyncThunk( ) ); +export const fetchDBaaSTemplatesAction = createAsyncThunk( + 'percona/fetchDbaaSTemplates', + async (args: { k8sClusterName: string; dbClusterType: DBClusterType }): Promise => + withSerializedError(TemplatesService.getDBaaSTemplates(args?.k8sClusterName, args?.dbClusterType)) +); + const deleteKubernetesReducer = createAsyncSlice('deleteKubernetes', deleteKubernetesAction).reducer; const installKubernetesOperatorReducer = createAsyncSlice( 'instalKuberneteslOperator', @@ -221,6 +230,7 @@ const installKubernetesOperatorReducer = createAsyncSlice( const settingsReducer = createAsyncSlice('settings', fetchSettingsAction, initialSettingsState).reducer; const updateSettingsReducer = createAsyncSlice('updateSettings', updateSettingsAction).reducer; const templatesReducer = createAsyncSlice('templates', fetchTemplatesAction).reducer; +const dbaasTemplatesReducer = createAsyncSlice('dbaasTemplates', fetchDBaaSTemplatesAction).reducer; export default { percona: combineReducers({ @@ -228,6 +238,7 @@ export default { updateSettings: updateSettingsReducer, user: perconaUserReducers, dbaas: perconaDBaaSReducer, + dbaasTemplates: dbaasTemplatesReducer, kubernetes: perconaK8SClusterListReducer, deleteKubernetes: deleteKubernetesReducer, addKubernetes: perconaK8SCluster, diff --git a/public/app/percona/shared/core/selectors.ts b/public/app/percona/shared/core/selectors.ts index deb89f692289a..0093b608237ca 100644 --- a/public/app/percona/shared/core/selectors.ts +++ b/public/app/percona/shared/core/selectors.ts @@ -10,6 +10,7 @@ export const getPerconaSettingFlag = (setting: keyof Settings) => (state: StoreS !!state.percona.settings.result?.[setting]; export const getPerconaUser = (state: StoreState) => state.percona.user; export const getDBaaS = (state: StoreState) => state.percona.dbaas; +export const getDbaaSTemplates = (state: StoreState) => state.percona.dbaasTemplates; export const getKubernetes = (state: StoreState) => state.percona.kubernetes; export const getDeleteKubernetes = (state: StoreState) => state.percona.deleteKubernetes; export const getAddKubernetes = (state: StoreState) => state.percona.addKubernetes; From 029b0d8801d3aee5285a4c241591a534f2c3e192 Mon Sep 17 00:00:00 2001 From: solovevayaroslavna Date: Tue, 4 Apr 2023 15:22:29 +0400 Subject: [PATCH 2/4] PMM-11773-Templates-select-issues: fix empty option --- .../DBClusterAdvancedOptions/Templates/Templates.utils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/app/percona/dbaas/components/DBCluster/EditDBClusterPage/DBClusterAdvancedOptions/Templates/Templates.utils.ts b/public/app/percona/dbaas/components/DBCluster/EditDBClusterPage/DBClusterAdvancedOptions/Templates/Templates.utils.ts index ccda856342bab..42b91457fe197 100644 --- a/public/app/percona/dbaas/components/DBCluster/EditDBClusterPage/DBClusterAdvancedOptions/Templates/Templates.utils.ts +++ b/public/app/percona/dbaas/components/DBCluster/EditDBClusterPage/DBClusterAdvancedOptions/Templates/Templates.utils.ts @@ -10,5 +10,5 @@ export const getTemplatesOptions = ( label: template.name, value: template.kind, })); - return options?.length ? [...options, { label: 'Not selected', value: '' }] : []; + return options?.length ? [...options, { label: 'Not selected', value: '' }] : [{ label: 'Not selected', value: '' }]; }; From 32856b92e7ad2b00c8df92aba5f2cac12cdb5884 Mon Sep 17 00:00:00 2001 From: solovevayaroslavna Date: Wed, 5 Apr 2023 13:44:21 +0400 Subject: [PATCH 3/4] PMM-11773-Templates-select-issues: code review fix --- .../DBClusterAdvancedOptions/Templates/Templates.utils.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/public/app/percona/dbaas/components/DBCluster/EditDBClusterPage/DBClusterAdvancedOptions/Templates/Templates.utils.ts b/public/app/percona/dbaas/components/DBCluster/EditDBClusterPage/DBClusterAdvancedOptions/Templates/Templates.utils.ts index 42b91457fe197..6138fa85f3465 100644 --- a/public/app/percona/dbaas/components/DBCluster/EditDBClusterPage/DBClusterAdvancedOptions/Templates/Templates.utils.ts +++ b/public/app/percona/dbaas/components/DBCluster/EditDBClusterPage/DBClusterAdvancedOptions/Templates/Templates.utils.ts @@ -10,5 +10,7 @@ export const getTemplatesOptions = ( label: template.name, value: template.kind, })); - return options?.length ? [...options, { label: 'Not selected', value: '' }] : [{ label: 'Not selected', value: '' }]; + const notSelectedOption = { label: 'Not selected', value: '' }; + + return options?.length ? [...options, notSelectedOption] : [notSelectedOption]; }; From 37e8ff995eeea0d5672f7d7dd25bd8639299a23f Mon Sep 17 00:00:00 2001 From: solovevayaroslavna Date: Fri, 19 May 2023 20:04:09 +0400 Subject: [PATCH 4/4] PMM-11773-Templates-select-issues: fix default value --- .../DBClusterAdvancedOptions.tsx | 1 + .../Templates/Templates.tsx | 13 +++++++++++-- .../Templates/Templates.types.ts | 3 +++ .../Templates/Templates.utils.ts | 4 +--- .../EditDBClusterPage/EditDBClusterPage.tsx | 5 +++++ 5 files changed, 21 insertions(+), 5 deletions(-) diff --git a/public/app/percona/dbaas/components/DBCluster/EditDBClusterPage/DBClusterAdvancedOptions/DBClusterAdvancedOptions.tsx b/public/app/percona/dbaas/components/DBCluster/EditDBClusterPage/DBClusterAdvancedOptions/DBClusterAdvancedOptions.tsx index b40b63ad25735..464358dfd479c 100644 --- a/public/app/percona/dbaas/components/DBCluster/EditDBClusterPage/DBClusterAdvancedOptions/DBClusterAdvancedOptions.tsx +++ b/public/app/percona/dbaas/components/DBCluster/EditDBClusterPage/DBClusterAdvancedOptions/DBClusterAdvancedOptions.tsx @@ -211,6 +211,7 @@ export const DBClusterAdvancedOptions: FC = ({
= ({ k8sClusterName, databaseType }) => { +export const Templates: FC = ({ k8sClusterName, databaseType, form }) => { const dispatch = useDispatch(); const { result, loading } = useSelector(getDbaaSTemplates); @@ -24,8 +24,16 @@ export const Templates: FC = ({ k8sClusterName, databaseType }) if (dbClusterType) { dispatch(fetchDBaaSTemplatesAction({ k8sClusterName, dbClusterType })); } + // eslint-disable-next-line react-hooks/exhaustive-deps }, [databaseType, dispatch, k8sClusterName]); + useEffect(() => { + if (templatesOptions.length === 1) { + form.mutators.resetTemplate(notSelectedOption); + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [templatesOptions]); + return ( = ({ k8sClusterName, databaseType }) component={AsyncSelectFieldAdapter} loading={loading} options={templatesOptions} + defaultValue={notSelectedOption} /> ); }; diff --git a/public/app/percona/dbaas/components/DBCluster/EditDBClusterPage/DBClusterAdvancedOptions/Templates/Templates.types.ts b/public/app/percona/dbaas/components/DBCluster/EditDBClusterPage/DBClusterAdvancedOptions/Templates/Templates.types.ts index c449af48d8a97..d2538ba4ea472 100644 --- a/public/app/percona/dbaas/components/DBCluster/EditDBClusterPage/DBClusterAdvancedOptions/Templates/Templates.types.ts +++ b/public/app/percona/dbaas/components/DBCluster/EditDBClusterPage/DBClusterAdvancedOptions/Templates/Templates.types.ts @@ -1,9 +1,12 @@ +import { FormApi } from 'final-form'; + import { Databases } from '../../../../../../shared/core'; import { DBClusterType } from '../../../DBCluster.types'; export interface TemplatesProps { k8sClusterName: string; databaseType: Databases; + form: FormApi, Partial>>; } export interface DBClusterTemplate { diff --git a/public/app/percona/dbaas/components/DBCluster/EditDBClusterPage/DBClusterAdvancedOptions/Templates/Templates.utils.ts b/public/app/percona/dbaas/components/DBCluster/EditDBClusterPage/DBClusterAdvancedOptions/Templates/Templates.utils.ts index 6138fa85f3465..fdf6b63546df0 100644 --- a/public/app/percona/dbaas/components/DBCluster/EditDBClusterPage/DBClusterAdvancedOptions/Templates/Templates.utils.ts +++ b/public/app/percona/dbaas/components/DBCluster/EditDBClusterPage/DBClusterAdvancedOptions/Templates/Templates.utils.ts @@ -1,7 +1,7 @@ import { SelectableValue } from '@grafana/data'; import { DBClusterTemplatesResponse } from './Templates.types'; - +export const notSelectedOption = { label: 'Not selected', value: '' }; export const getTemplatesOptions = ( templatesResponce: DBClusterTemplatesResponse | undefined ): Array> => { @@ -10,7 +10,5 @@ export const getTemplatesOptions = ( label: template.name, value: template.kind, })); - const notSelectedOption = { label: 'Not selected', value: '' }; - return options?.length ? [...options, notSelectedOption] : [notSelectedOption]; }; diff --git a/public/app/percona/dbaas/components/DBCluster/EditDBClusterPage/EditDBClusterPage.tsx b/public/app/percona/dbaas/components/DBCluster/EditDBClusterPage/EditDBClusterPage.tsx index 3ef56109b314c..ffc1499580066 100644 --- a/public/app/percona/dbaas/components/DBCluster/EditDBClusterPage/EditDBClusterPage.tsx +++ b/public/app/percona/dbaas/components/DBCluster/EditDBClusterPage/EditDBClusterPage.tsx @@ -4,7 +4,9 @@ import React, { FC, useCallback, useEffect, useState } from 'react'; import { Form } from 'react-final-form'; import { Redirect, useHistory } from 'react-router-dom'; +import { SelectableValue } from '@grafana/data'; import { Spinner, useStyles2 } from '@grafana/ui/src'; +import { AdvancedOptionsFields } from 'app/percona/dbaas/components/DBCluster/EditDBClusterPage/DBClusterAdvancedOptions/DBClusterAdvancedOptions.types'; import { useShowPMMAddressWarning } from 'app/percona/shared/components/hooks/showPMMAddressWarning'; import { useSelector, useDispatch } from 'app/types'; @@ -93,6 +95,9 @@ export const EditDBClusterPage: FC = () => { trimConfiguration: ([configuration]: string[], state, { changeValue }) => { changeValue(state, ConfigurationFields.configuration, () => configuration.trim()); }, + resetTemplate: (templateValue: SelectableValue, state, { changeValue }) => { + changeValue(state, AdvancedOptionsFields.template, () => templateValue); + }, ...arrayMutators, }} render={({ form, handleSubmit, valid, pristine, ...props }) => (