From eac743ff6d3d6096362c658a82fca45d963a71e1 Mon Sep 17 00:00:00 2001 From: Ayangade Adeoluwa <37867493+Irongade@users.noreply.github.com> Date: Fri, 2 Jun 2023 12:15:12 +0100 Subject: [PATCH] fix: Fix dropdown bug issue (#23923) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The saas datasource editor page re-renders whenever the name of the datasource is changed causing selected options to be cleared off. This PR fixes that issue. #### PR fixes following issue(s) Fixes #22576 #### Media > A video or a GIF is preferred. when using Loom, don’t embed because it looks like it’s a GIF. instead, just link to the video > > #### Type of change > Please delete options that are not relevant. - Bug fix (non-breaking change which fixes an issue) - [x] Manual - [ ] Jest - [ ] Cypress > > #### Test Plan 1) Navigate to create new DS 2) Rename the DS and click on white space 3) Select scope to authorize the datasource and then change the name of the datasource and click on white space 4) Rename the DS and click on white space and check if the scope of other datasource gets changed 5) Rename the DS and click on the white space click on the back button to ensure the pop-up is displayed to the user 6) rename the DS from entity explore and observe the scope of the same DS and other DS 7) Ensure user is able to create new API 8) Ensure user is able to edit the DS (Scope , authorise to different Gmail Account) #### Issues raised during DP testing > Link issues raised during DP testing for better visibility and tracking (copy link from comments dropped on this PR) > > > ## Checklist: #### Dev activity - [ ] My code follows the style guidelines of this project - [ ] I have performed a self-review of my own code - [ ] I have commented my code, particularly in hard-to-understand areas - [ ] I have made corresponding changes to the documentation - [ ] My changes generate no new warnings - [ ] I have added tests that prove my fix is effective or that my feature works - [ ] New and existing unit tests pass locally with my changes - [ ] PR is being merged under a feature flag #### QA activity: - [ ] [Speedbreak features](https://github.com/appsmithorg/TestSmith/wiki/Test-plan-implementation#speedbreaker-features-to-consider-for-every-change) have been covered - [x] Test plan covers all impacted features and [areas of interest](https://github.com/appsmithorg/TestSmith/wiki/Guidelines-for-test-plans/_edit#areas-of-interest) - [x] Test plan has been peer reviewed by project stakeholders and other QA members - [x] Manually tested functionality on DP - [ ] We had an implementation alignment call with stakeholders post QA Round 2 - [ ] Cypress test cases have been added and approved by SDET/manual QA - [ ] Added `Test Plan Approved` label after Cypress tests were reviewed - [ ] Added `Test Plan Approved` label after JUnit tests were reviewed --- .../Editor/SaaSEditor/DatasourceForm.tsx | 42 ++++++++++++++----- app/client/src/sagas/SaaSPaneSagas.ts | 7 +++- 2 files changed, 38 insertions(+), 11 deletions(-) diff --git a/app/client/src/pages/Editor/SaaSEditor/DatasourceForm.tsx b/app/client/src/pages/Editor/SaaSEditor/DatasourceForm.tsx index 380ea94cda..b1065e24dc 100644 --- a/app/client/src/pages/Editor/SaaSEditor/DatasourceForm.tsx +++ b/app/client/src/pages/Editor/SaaSEditor/DatasourceForm.tsx @@ -1,10 +1,16 @@ import React from "react"; -import _, { merge } from "lodash"; +import _, { isEqual, omit } from "lodash"; import { DATASOURCE_SAAS_FORM } from "@appsmith/constants/forms"; import type { Datasource } from "entities/Datasource"; import { ActionType } from "entities/Datasource"; import type { InjectedFormProps } from "redux-form"; -import { getFormValues, isDirty, reduxForm } from "redux-form"; +import { + getFormValues, + isDirty, + reduxForm, + initialize, + getFormInitialValues, +} from "redux-form"; import type { RouteComponentProps } from "react-router"; import { connect } from "react-redux"; import type { AppState } from "@appsmith/reducers"; @@ -62,7 +68,6 @@ import { import { getDatasourceErrorMessage } from "./errorUtils"; import GoogleSheetFilePicker from "./GoogleSheetFilePicker"; import DatasourceInformation from "./../DataSourceEditor/DatasourceSection"; -import { getConfigInitialValues } from "components/formControls/utils"; import type { ControlProps } from "components/formControls/BaseControl"; import { DSFormHeader } from "../DataSourceEditor/DSFormHeader"; import Debugger, { @@ -112,6 +117,7 @@ interface DatasourceFormFunctions { setDatasourceViewMode: (viewMode: boolean) => void; loadFilePickerAction: () => void; datasourceDiscardAction: (pluginId: string) => void; + initializeDatasource: (values: any) => void; } type DatasourceSaaSEditorProps = StateProps & @@ -223,6 +229,17 @@ class DatasourceSaaSEditor extends JSONtoForm { const pluginId = urlObject?.searchParams?.get("pluginId"); // update block state when form becomes dirty/view mode is switched on + // if the datasource configurations (except the name) has changed, we reinitialize the form. + // this is to allow for cases when the datasource has been authorized + if ( + !isEqual( + omit(this.props.datasource, "name"), + omit(prevProps.datasource, "name"), + ) + ) { + this.props.initializeDatasource(omit(this.props.datasource, "name")); + } + if ( prevProps.viewMode !== this.props.viewMode && !this.props.viewMode && @@ -252,6 +269,12 @@ class DatasourceSaaSEditor extends JSONtoForm { componentDidMount() { const urlObject = new URL(window?.location?.href); const pluginId = urlObject?.searchParams?.get("pluginId"); + + // if there are no initial values, it means the form has not been initialized, hence we initialize the form. + if (!this.props.initialValues) { + this.props.initializeDatasource(omit(this.props.datasource, "name")); + } + // Create Temp Datasource on component mount, // if user hasnt saved datasource for the first time and refreshed the page if ( @@ -524,12 +547,9 @@ const mapStateToProps = (state: AppState, props: any) => { const pluginId = _.get(datasource, "pluginId", ""); const plugin = getPlugin(state, pluginId); const formConfig = formConfigs[pluginId]; - const initialValues = {}; - if (formConfig) { - merge(initialValues, getConfigInitialValues(formConfig)); - } - - merge(initialValues, datasource); + const initialValues = getFormInitialValues(DATASOURCE_SAAS_FORM)( + state, + ) as Datasource; // get scopeValue to be shown in analytical events const scopeValue = getDatasourceScopeValue( @@ -540,7 +560,7 @@ const mapStateToProps = (state: AppState, props: any) => { const datasourceButtonConfiguration = getDatasourceFormButtonConfig( state, - formData?.pluginId, + pluginId, ); const isFormDirty = datasourceId === TEMP_DATASOURCE_ID @@ -639,6 +659,8 @@ const mapDispatchToProps = (dispatch: any): DatasourceFormFunctions => ({ loadFilePickerAction: () => dispatch(loadFilePickerAction()), datasourceDiscardAction: (pluginId) => dispatch(datasourceDiscardAction(pluginId)), + initializeDatasource: (values: any) => + dispatch(initialize(DATASOURCE_SAAS_FORM, values)), }); const SaaSEditor = connect( diff --git a/app/client/src/sagas/SaaSPaneSagas.ts b/app/client/src/sagas/SaaSPaneSagas.ts index 693682a40d..7a5a39b332 100644 --- a/app/client/src/sagas/SaaSPaneSagas.ts +++ b/app/client/src/sagas/SaaSPaneSagas.ts @@ -1,4 +1,4 @@ -import { all, select, takeEvery } from "redux-saga/effects"; +import { all, put, select, takeEvery } from "redux-saga/effects"; import type { ReduxAction } from "@appsmith/constants/ReduxActionConstants"; import { ReduxActionTypes } from "@appsmith/constants/ReduxActionConstants"; import history from "utils/history"; @@ -18,6 +18,9 @@ import { getCurrentPageId } from "selectors/editorSelectors"; import type { CreateDatasourceSuccessAction } from "actions/datasourceActions"; import { getQueryParams } from "utils/URLUtils"; import { getIsGeneratePageInitiator } from "utils/GenerateCrudUtil"; +import { DATASOURCE_SAAS_FORM } from "ce/constants/forms"; +import { initialize } from "redux-form"; +import { omit } from "lodash"; function* handleDatasourceCreatedSaga( actionPayload: CreateDatasourceSuccessAction, @@ -29,6 +32,8 @@ function* handleDatasourceCreatedSaga( if (!plugin) return; if (plugin.type !== PluginType.SAAS) return; + yield put(initialize(DATASOURCE_SAAS_FORM, omit(payload, "name"))); + const queryParams = getQueryParams(); const updatedDatasource = payload;