From 12e7ee0c94cbfc81e5f7ef270ab08740378c36be Mon Sep 17 00:00:00 2001 From: Rishabh Rathod Date: Fri, 20 Aug 2021 12:27:01 +0530 Subject: [PATCH 01/76] Add s3 support for generate CRUD (#6264) * Add s3 support for generate CRUD - Dropdown enhancement to open options on initial load - Hide column selection option for s3 * Refactor the prop name * Add useS3BucketList hook WIP * Dropdown enchancement & Fix small issues * Add fetch all sheets query * Add Query to get all S3 buckets * Fix dropdown open issue * Remove defaultIsOpen prop from dropdown * Resolve comments - Remove debugger - mockSheetUrl -> getSheetUrl * Add S3 cypress test * Fix cypress test yml config * Fix generate page cypress test --- .github/workflows/client-test.yml | 2 + .github/workflows/external-client-test.yml | 2 + .../GenerateCRUD/GenerateCRUDPage_Spec.js | 23 +- .../GenerateCRUD/S3_CRUDPage_Spec.js | 62 +++ .../cypress/locators/DatasourcesEditor.json | 3 +- app/client/cypress/locators/GeneratePage.json | 3 +- app/client/cypress/support/commands.js | 19 + app/client/src/actions/datasourceActions.ts | 14 +- app/client/src/api/DatasourcesApi.ts | 2 +- app/client/src/components/ads/Dropdown.tsx | 22 +- .../GeneratePageForm/GeneratePageForm.tsx | 334 +++++++++------- .../components/GeneratePageForm/hooks.ts | 77 +++- .../components/GeneratePageForm/styles.ts | 16 + .../components/GoogleSheetForm.tsx | 376 ++++++++++-------- .../GeneratePage/components/constants.ts | 22 + .../entityReducers/datasourceReducer.ts | 20 + app/client/src/sagas/DatasourcesSagas.ts | 2 +- app/client/src/selectors/entitiesSelector.ts | 10 +- 18 files changed, 680 insertions(+), 329 deletions(-) create mode 100644 app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/GenerateCRUD/S3_CRUDPage_Spec.js create mode 100644 app/client/src/pages/Editor/GeneratePage/components/GeneratePageForm/styles.ts diff --git a/.github/workflows/client-test.yml b/.github/workflows/client-test.yml index 16d631b232bf..a42688f1fac0 100644 --- a/.github/workflows/client-test.yml +++ b/.github/workflows/client-test.yml @@ -371,6 +371,8 @@ jobs: CYPRESS_TESTPASSWORD1: ${{ secrets.CYPRESS_TESTPASSWORD1 }} CYPRESS_TESTUSERNAME2: ${{ secrets.CYPRESS_TESTUSERNAME2 }} CYPRESS_TESTPASSWORD2: ${{ secrets.CYPRESS_TESTPASSWORD1 }} + CYPRESS_S3_ACCESS_KEY: ${{ secrets.CYPRESS_S3_ACCESS_KEY }} + CYPRESS_S3_SECRET_KEY: ${{ secrets.CYPRESS_S3_SECRET_KEY }} APPSMITH_DISABLE_TELEMETRY: true APPSMITH_GOOGLE_MAPS_API_KEY: ${{ secrets.APPSMITH_GOOGLE_MAPS_API_KEY }} POSTGRES_PASSWORD: postgres diff --git a/.github/workflows/external-client-test.yml b/.github/workflows/external-client-test.yml index aff3f8086289..61cd6176bed3 100644 --- a/.github/workflows/external-client-test.yml +++ b/.github/workflows/external-client-test.yml @@ -354,6 +354,8 @@ jobs: CYPRESS_TESTPASSWORD1: ${{ secrets.CYPRESS_TESTPASSWORD1 }} CYPRESS_TESTUSERNAME2: ${{ secrets.CYPRESS_TESTUSERNAME2 }} CYPRESS_TESTPASSWORD2: ${{ secrets.CYPRESS_TESTPASSWORD1 }} + CYPRESS_S3_ACCESS_KEY: ${{ secrets.CYPRESS_S3_ACCESS_KEY }} + CYPRESS_S3_SECRET_KEY: ${{ secrets.CYPRESS_S3_SECRET_KEY }} APPSMITH_DISABLE_TELEMETRY: true APPSMITH_GOOGLE_MAPS_API_KEY: ${{ secrets.APPSMITH_GOOGLE_MAPS_API_KEY }} POSTGRES_PASSWORD: postgres diff --git a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/GenerateCRUD/GenerateCRUDPage_Spec.js b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/GenerateCRUD/GenerateCRUDPage_Spec.js index edd1694e3c6f..da151ed02560 100644 --- a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/GenerateCRUD/GenerateCRUDPage_Spec.js +++ b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/GenerateCRUD/GenerateCRUDPage_Spec.js @@ -4,9 +4,15 @@ import homePage from "../../../../locators/HomePage.json"; import datasource from "../../../../locators/DatasourcesEditor.json"; describe("Generate New CRUD Page Inside from entity explorer", function() { + let datasourceName; + before(() => { cy.startRoutesForDatasource(); cy.createPostgresDatasource(); + + cy.get("@createDatasource").then((httpResponse) => { + datasourceName = httpResponse.response.body.data.name; + }); // TODO // 1. Add INVALID credential for a datasource and test the invalid datasource structure flow. // 2. Add 2 supported datasource and 1 not supported datasource with a fixed name to search. @@ -27,7 +33,7 @@ describe("Generate New CRUD Page Inside from entity explorer", function() { cy.get(generatePage.selectDatasourceDropdown).click(); cy.get(generatePage.datasourceDropdownOption) - .first() + .contains(datasourceName) .click(); cy.wait("@getDatasourceStructure").should( @@ -81,7 +87,8 @@ describe("Generate New CRUD Page Inside from entity explorer", function() { cy.fillPostgresDatasourceForm(); cy.generateUUID().then((UUID) => { - cy.renameDatasource(`PostgresSQL CRUD Demo ${UUID}`); + datasourceName = `PostgresSQL CRUD Demo ${UUID}`; + cy.renameDatasource(datasourceName); }); cy.startRoutesForDatasource(); @@ -124,10 +131,16 @@ describe("Generate New CRUD Page Inside from entity explorer", function() { cy.get(pages.integrationActiveTab) .should("be.visible") .click({ force: true }); + cy.wait(1000); - cy.get(generatePage.datasourceCardGeneratePageBtn) - .first() - .click(); + cy.get(datasource.datasourceCard) + .contains(datasourceName) + .scrollIntoView() + .should("be.visible") + .closest(datasource.datasourceCard) + .within(() => { + cy.get(datasource.datasourceCardGeneratePageBtn).click(); + }); cy.wait("@getDatasourceStructure").should( "have.nested.property", diff --git a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/GenerateCRUD/S3_CRUDPage_Spec.js b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/GenerateCRUD/S3_CRUDPage_Spec.js new file mode 100644 index 000000000000..c549ad09f02d --- /dev/null +++ b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/GenerateCRUD/S3_CRUDPage_Spec.js @@ -0,0 +1,62 @@ +const pages = require("../../../../locators/Pages.json"); +const generatePage = require("../../../../locators/GeneratePage.json"); + +describe("Generate New CRUD Page Inside from entity explorer", function() { + let datasourceName; + before(() => { + cy.startRoutesForDatasource(); + cy.createAmazonS3Datasource(); + + cy.get("@createDatasource").then((httpResponse) => { + datasourceName = httpResponse.response.body.data.name; + }); + }); + + it("Add new Page and generate CRUD template using existing supported datasource", function() { + cy.get(pages.AddPage) + .first() + .click(); + cy.wait("@createPage").should( + "have.nested.property", + "response.body.responseMeta.status", + 201, + ); + + cy.get(generatePage.generateCRUDPageActionCard).click(); + + cy.get(generatePage.selectDatasourceDropdown).click(); + + cy.get(generatePage.datasourceDropdownOption) + .contains(datasourceName) + .click(); + + // fetch bucket + cy.wait("@datasourceQuery").should( + "have.nested.property", + "response.body.responseMeta.status", + 200, + ); + + cy.get(generatePage.selectTableDropdown).click(); + + cy.get(generatePage.dropdownOption) + .contains("assets-test.appsmith.com") + .scrollIntoView() + .should("be.visible") + .click(); + // skip optional search column selection. + cy.get(generatePage.generatePageFormSubmitBtn).click(); + + cy.wait("@replaceLayoutWithCRUDPage").should( + "have.nested.property", + "response.body.responseMeta.status", + 201, + ); + cy.wait("@getActions"); + cy.wait("@postExecute").should( + "have.nested.property", + "response.body.responseMeta.status", + 200, + ); + }); +}); diff --git a/app/client/cypress/locators/DatasourcesEditor.json b/app/client/cypress/locators/DatasourcesEditor.json index e292a0c5fb1c..1674290d3154 100644 --- a/app/client/cypress/locators/DatasourcesEditor.json +++ b/app/client/cypress/locators/DatasourcesEditor.json @@ -16,6 +16,7 @@ "activeDatasourceList": ".t--active-datasource-list", "datasourceCard": ".t--datasource", "datasourceCardMenu": ".t--datasource-menu-option", + "datasourceCardGeneratePageBtn": ".t--generate-template", "datasourceMenuOptionEdit": "t--datasource-option-edit", "datasourceMenuOptionDelete":"t--datasource-option-delete", "editDatasource": ".t--edit-datasource", @@ -30,7 +31,7 @@ "MsSQL": ".t--plugin-name:contains('MsSQL')", "Firestore": ".t--plugin-name:contains('Firestore')", "Redshift": ".t--plugin-name:contains('Redshift')", - "AmazonS3": ".t--plugin-name:contains('Amazon S3')", + "AmazonS3": ".t--plugin-name:contains('S3')", "authType": "[data-cy=authType]", "OAuth2": "//div[contains(@class,'option') and text()='OAuth 2.0']", "accessTokenUrl": "[data-cy='authentication.accessTokenUrl'] input", diff --git a/app/client/cypress/locators/GeneratePage.json b/app/client/cypress/locators/GeneratePage.json index f2326fa67259..68708b082bea 100644 --- a/app/client/cypress/locators/GeneratePage.json +++ b/app/client/cypress/locators/GeneratePage.json @@ -6,6 +6,5 @@ "selectTableDropdown":"[data-cy=t--table-dropdown]", "dropdownOption": ".bp3-popover-content .t--dropdown-option", "selectSearchColumnDropdown":"[data-cy=t--searchColumn-dropdown]", - "generatePageFormSubmitBtn":"[data-cy=t--generate-page-form-submit]", - "datasourceCardGeneratePageBtn": ".t--generate-template" + "generatePageFormSubmitBtn":"[data-cy=t--generate-page-form-submit]" } \ No newline at end of file diff --git a/app/client/cypress/support/commands.js b/app/client/cypress/support/commands.js index 96a585432a72..48092fe5fcff 100644 --- a/app/client/cypress/support/commands.js +++ b/app/client/cypress/support/commands.js @@ -2464,6 +2464,9 @@ Cypress.Commands.add("startServerAndRoutes", () => { cy.route("GET", "/api/v1/datasources/*/structure?ignoreCache=*").as( "getDatasourceStructure", ); + cy.route("PUT", "/api/v1/datasources/datasource-query/*").as( + "datasourceQuery", + ); cy.route("PUT", "/api/v1/pages/crud-page/*").as("replaceLayoutWithCRUDPage"); cy.route("POST", "/api/v1/pages/crud-page").as("generateCRUDPage"); @@ -2683,3 +2686,19 @@ Cypress.Commands.add("renameDatasource", (datasourceName) => { Cypress.Commands.add("skipGenerateCRUDPage", () => { cy.get(generatePage.buildFromScratchActionCard).click(); }); + +Cypress.Commands.add("fillAmazonS3DatasourceForm", () => { + cy.get(datasourceEditor.projectID).type(Cypress.env("S3_ACCESS_KEY")); + cy.get(datasourceEditor.serviceAccCredential) + .clear() + .type(Cypress.env("S3_SECRET_KEY")); +}); + +Cypress.Commands.add("createAmazonS3Datasource", () => { + cy.NavigateToDatasourceEditor(); + cy.get(datasourceEditor.AmazonS3).click(); + + cy.fillAmazonS3DatasourceForm(); + + cy.testSaveDatasource(); +}); diff --git a/app/client/src/actions/datasourceActions.ts b/app/client/src/actions/datasourceActions.ts index 131a626ec47d..612693496a4e 100644 --- a/app/client/src/actions/datasourceActions.ts +++ b/app/client/src/actions/datasourceActions.ts @@ -199,10 +199,10 @@ export const getOAuthAccessToken = (datasourceId: string) => { }; }; -export type executeDatasourceQuerySuccessPayload = { +export type executeDatasourceQuerySuccessPayload = { responseMeta: ResponseMeta; data: { - body: Array<{ id: string; name: string }>; + body: T; headers: Record; statusCode: string; isExecutionSuccess: boolean; @@ -210,9 +210,9 @@ export type executeDatasourceQuerySuccessPayload = { }; type errorPayload = unknown; -export type executeDatasourceQueryReduxAction = ReduxActionWithCallbacks< +export type executeDatasourceQueryReduxAction = ReduxActionWithCallbacks< executeDatasourceQueryRequest, - executeDatasourceQuerySuccessPayload, + executeDatasourceQuerySuccessPayload, errorPayload >; @@ -222,9 +222,11 @@ export const executeDatasourceQuery = ({ payload, }: { onErrorCallback?: (payload: errorPayload) => void; - onSuccessCallback?: (payload: executeDatasourceQuerySuccessPayload) => void; + onSuccessCallback?: ( + payload: executeDatasourceQuerySuccessPayload, + ) => void; payload: executeDatasourceQueryRequest; -}): executeDatasourceQueryReduxAction => { +}): executeDatasourceQueryReduxAction => { return { type: ReduxActionTypes.EXECUTE_DATASOURCE_QUERY_INIT, payload, diff --git a/app/client/src/api/DatasourcesApi.ts b/app/client/src/api/DatasourcesApi.ts index 9e625bc1ee13..0993c5bbb8af 100644 --- a/app/client/src/api/DatasourcesApi.ts +++ b/app/client/src/api/DatasourcesApi.ts @@ -25,7 +25,7 @@ export interface EmbeddedRestDatasourceRequest { pluginId: string; } -type executeQueryData = Array<{ key: string; value?: string }>; +type executeQueryData = Array<{ key?: string; value?: string }>; export interface executeDatasourceQueryRequest { datasourceId: string; diff --git a/app/client/src/components/ads/Dropdown.tsx b/app/client/src/components/ads/Dropdown.tsx index e899b4210b15..9a81086a535b 100644 --- a/app/client/src/components/ads/Dropdown.tsx +++ b/app/client/src/components/ads/Dropdown.tsx @@ -66,6 +66,7 @@ export type DropdownProps = CommonComponentProps & renderOption?: RenderOption; isLoading?: boolean; errorMsg?: string; // If errorMsg is defined, we show dropDown's error state with the message. + helperText?: string; }; export interface DefaultDropDownValueNodeProps { selected: DropdownOption; @@ -309,7 +310,7 @@ const SelectedIcon = styled(Icon)` const ErrorMsg = styled.span` ${(props) => getTypographyByKey(props, "p3")}; color: ${Colors.POMEGRANATE2}; - margin: 6px 0px 10px; + margin-top: 8px; `; const ErrorLabel = styled.span` @@ -317,6 +318,12 @@ const ErrorLabel = styled.span` color: ${Colors.POMEGRANATE2}; `; +const HelperText = styled.span` + ${(props) => getTypographyByKey(props, "p3")}; + color: ${Colors.GRAY}; + margin-top: 8px; +`; + function DefaultDropDownValueNode({ errorMsg, renderNode, @@ -455,12 +462,20 @@ export default function Dropdown(props: DropdownProps) { SelectedValueNode = DefaultDropDownValueNode, renderOption, errorMsg = "", + helperText = "", } = { ...props }; const [isOpen, setIsOpen] = useState(false); const [selected, setSelected] = useState(props.selected); + const closeIfOpen = () => { + if (isOpen) { + setIsOpen(false); + } + }; + useEffect(() => { setSelected(props.selected); + closeIfOpen(); }, [props.selected]); const optionClickHandler = useCallback( @@ -474,7 +489,7 @@ export default function Dropdown(props: DropdownProps) { ); const disabled = props.disabled || isLoading || !!errorMsg; - const downIconColor = errorMsg ? Colors.POMEGRANATE2 : ""; + const downIconColor = errorMsg ? Colors.POMEGRANATE2 : Colors.DARK_GRAY; const dropdownTrigger = props.dropdownTriggerIcon ? ( {errorMsg && {errorMsg}} + {helperText && !isOpen && !errorMsg && ( + {helperText} + )} ); return ( diff --git a/app/client/src/pages/Editor/GeneratePage/components/GeneratePageForm/GeneratePageForm.tsx b/app/client/src/pages/Editor/GeneratePage/components/GeneratePageForm/GeneratePageForm.tsx index 964b185215b5..0a07f5af587b 100644 --- a/app/client/src/pages/Editor/GeneratePage/components/GeneratePageForm/GeneratePageForm.tsx +++ b/app/client/src/pages/Editor/GeneratePage/components/GeneratePageForm/GeneratePageForm.tsx @@ -2,16 +2,20 @@ import React, { useEffect, useState, useCallback, useRef } from "react"; import styled from "styled-components"; import { Colors } from "constants/Colors"; import Dropdown, { DropdownOption } from "components/ads/Dropdown"; -import { getTypographyByKey } from "../../../../../constants/DefaultTheme"; +import { getTypographyByKey } from "constants/DefaultTheme"; import Button, { Category, Size } from "components/ads/Button"; import { useSelector, useDispatch } from "react-redux"; import { getDatasources, getIsFetchingDatasourceStructure, -} from "../../../../../selectors/entitiesSelector"; + getGenerateCRUDEnabledPluginMap, + getIsFetchingSinglePluginForm, + getDatasourcesStructure, + getIsExecutingDatasourceQuery, +} from "selectors/entitiesSelector"; + import { Datasource } from "entities/Datasource"; -import { fetchDatasourceStructure } from "../../../../../actions/datasourceActions"; -import { getDatasourcesStructure } from "selectors/entitiesSelector"; +import { fetchDatasourceStructure } from "actions/datasourceActions"; import { generateTemplateToUpdatePage } from "actions/pageActions"; import { useParams, useLocation } from "react-router"; import { ExplorerURLParams } from "../../../Explorer/helpers"; @@ -27,39 +31,23 @@ import DataSourceOption from "../DataSourceOption"; import { convertToQueryParams } from "constants/routes"; import { IconName, IconSize } from "components/ads/Icon"; import GoogleSheetForm from "../GoogleSheetForm"; -import { GENERATE_PAGE_FORM_TITLE } from "../../../../../constants/messages"; -import { GenerateCRUDEnabledPluginMap } from "../../../../../api/PluginApi"; -import { getGenerateCRUDEnabledPluginMap } from "../../../../../selectors/entitiesSelector"; -import { useDatasourceOptions } from "./hooks"; +import { GENERATE_PAGE_FORM_TITLE } from "constants/messages"; +import { GenerateCRUDEnabledPluginMap } from "api/PluginApi"; +import { useDatasourceOptions, useS3BucketList } from "./hooks"; import AnalyticsUtil from "utils/AnalyticsUtil"; +import { AppState } from "reducers/index"; import { DropdownOptions, DatasourceTableDropdownOption, PluginFormInputFieldMap, PLUGIN_PACKAGE_NAME, + DEFAULT_DROPDOWN_OPTION, + DROPDOWN_DIMENSION, + ALLOWED_SEARCH_DATATYPE, } from "../constants"; -const DROPDOWN_DIMENSION = { - HEIGHT: "36px", - WIDTH: "404px", -}; - -const DEFAULT_DROPDOWN_OPTION = { - id: "- Select -", - label: "- Select -", - value: "", - onSelect: () => null, - data: {}, -}; +import { Bold, Label, SelectWrapper } from "./styles"; -const ALLOWED_SEARCH_DATATYPE = [ - "text", - "string", - "char", - "varchar", - "character", - "text string", -]; // ---------- Styles ---------- const Wrapper = styled.div` @@ -71,14 +59,6 @@ const Wrapper = styled.div` border: none; `; -const SelectWrapper = styled.div` - margin: 10px; -`; - -const Label = styled.p` - ${(props) => `${getTypographyByKey(props, "p1")}`} -`; - const FormWrapper = styled.div` display: flex; flex-direction: column; @@ -96,10 +76,6 @@ const EditDatasourceButton = styled(Button)` margin-top: 30px; `; -const Bold = styled.span` - font-weight: 500; -`; - const DescWrapper = styled.div` flex: 1; display: flex; @@ -113,15 +89,18 @@ const Title = styled.p` color: ${Colors.CODE_GRAY}; font-size: 24px; `; -// ---------- Types ---------- -// ---------- GeneratePageForm Component ---------- +// Constants + +const datasourceIcon: IconName = "tables"; const GENERATE_PAGE_MODE = { NEW: "NEW", // a new page is created for the template. (new pageId created) REPLACE_EMPTY: "REPLACE_EMPTY", // current page's content (DSL) is updated to template DSL. (same pageId) }; +// ---------- GeneratePageForm Component ---------- + function GeneratePageForm() { const dispatch = useDispatch(); const querySearch = useLocation().search; @@ -160,6 +139,28 @@ function GeneratePageForm() { DEFAULT_DROPDOWN_OPTION, ); + const selectedDatasourcePluginId: string = selectedDatasource.data?.pluginId; + const selectedDatasourcePluginPackageName: string = + generateCRUDSupportedPlugin[selectedDatasourcePluginId]; + + const isGoogleSheetPlugin = + selectedDatasourcePluginPackageName === PLUGIN_PACKAGE_NAME.GOOGLE_SHEETS; + + const isS3Plugin = + selectedDatasourcePluginPackageName === PLUGIN_PACKAGE_NAME.S3; + + const isFetchingSheetPluginForm = useSelector((state: AppState) => { + if (isGoogleSheetPlugin) { + return getIsFetchingSinglePluginForm( + state, + selectedDatasource.data?.pluginId, + ); + } + return false; + }); + + const isExecutingDatasourceQuery = useSelector(getIsExecutingDatasourceQuery); + const [selectedTable, selectTable] = useState( DEFAULT_DROPDOWN_OPTION, ); @@ -173,12 +174,23 @@ function GeneratePageForm() { DEFAULT_DROPDOWN_OPTION, ); + const { + bucketList, + failedFetchingBucketList, + fetchBucketList, + isFetchingBucketList, + } = useS3BucketList(); + const onSelectDataSource = useCallback( ( datasource: string | undefined, dataSourceObj: DropdownOption | undefined, ) => { - if (datasource && dataSourceObj) { + if ( + datasource && + dataSourceObj && + selectedDatasource.id !== dataSourceObj.id + ) { const pluginId: string = dataSourceObj.data.pluginId; const pluginPackageName: string = generateCRUDSupportedPlugin[pluginId]; AnalyticsUtil.logEvent("GEN_CRUD_PAGE_SELECT_DATASOURCE", { @@ -189,8 +201,18 @@ function GeneratePageForm() { setSelectedTableColumnOptions([]); selectTable(DEFAULT_DROPDOWN_OPTION); selectColumn(DEFAULT_DROPDOWN_OPTION); - if (dataSourceObj.id) { - dispatch(fetchDatasourceStructure(dataSourceObj.id, true)); + + switch (pluginPackageName) { + case PLUGIN_PACKAGE_NAME.S3: + fetchBucketList({ selectedDatasource: dataSourceObj }); + break; + case PLUGIN_PACKAGE_NAME.GOOGLE_SHEETS: + break; + default: { + if (dataSourceObj.id) { + dispatch(fetchDatasourceStructure(dataSourceObj.id, true)); + } + } } } }, @@ -202,6 +224,7 @@ function GeneratePageForm() { selectTable, selectColumn, dispatch, + generateCRUDSupportedPlugin, ], ); @@ -211,35 +234,43 @@ function GeneratePageForm() { AnalyticsUtil.logEvent("GEN_CRUD_PAGE_SELECT_TABLE"); selectTable(TableObj); selectColumn(DEFAULT_DROPDOWN_OPTION); - const { data } = TableObj; - const columnIcon: IconName = "column"; - if (data.columns && Array.isArray(data.columns)) { - const newSelectedTableColumnOptions: DropdownOption[] = []; - data.columns.map((column) => { - if ( - column.type && - ALLOWED_SEARCH_DATATYPE.includes(column.type.toLowerCase()) - ) { - newSelectedTableColumnOptions.push({ - id: column.name, - label: column.name, - value: column.name, - subText: column.type, - icon: columnIcon, - iconSize: IconSize.LARGE, - iconColor: Colors.GOLD, - }); + if (!isGoogleSheetPlugin && !isS3Plugin) { + const { data } = TableObj; + const columnIcon: IconName = "column"; + if (data.columns && Array.isArray(data.columns)) { + const newSelectedTableColumnOptions: DropdownOption[] = []; + data.columns.map((column) => { + if ( + column.type && + ALLOWED_SEARCH_DATATYPE.includes(column.type.toLowerCase()) + ) { + newSelectedTableColumnOptions.push({ + id: column.name, + label: column.name, + value: column.name, + subText: column.type, + icon: columnIcon, + iconSize: IconSize.LARGE, + iconColor: Colors.GOLD, + }); + } + }); + if (newSelectedTableColumnOptions) { + setSelectedTableColumnOptions(newSelectedTableColumnOptions); } - }); - if (newSelectedTableColumnOptions) { - setSelectedTableColumnOptions(newSelectedTableColumnOptions); + } else { + setSelectedTableColumnOptions([]); } - } else { - setSelectedTableColumnOptions([]); } } }, - [selectTable, setSelectedTableColumnOptions, selectColumn], + [ + selectTable, + setSelectedTableColumnOptions, + selectColumn, + isGoogleSheetPlugin, + isS3Plugin, + ], ); const onSelectColumn = useCallback( @@ -257,6 +288,20 @@ function GeneratePageForm() { generateCRUDSupportedPlugin, }); + useEffect(() => { + if (isS3Plugin && bucketList && bucketList.length) { + const tables = bucketList.map((bucketName) => ({ + id: bucketName, + label: bucketName, + value: bucketName, + icon: datasourceIcon, + iconSize: IconSize.LARGE, + iconColor: Colors.BURNING_ORANGE, + })); + setSelectedDatasourceTableOptions(tables); + } + }, [bucketList, isS3Plugin]); + useEffect(() => { if ( selectedDatasource.id && @@ -267,7 +312,6 @@ function GeneratePageForm() { const selectedDatasourceStructure = datasourcesStructure[selectedDatasource.id] || {}; - const datasourceIcon: IconName = "tables"; const hasError = selectedDatasourceStructure?.error; if (hasError) { @@ -380,13 +424,10 @@ function GeneratePageForm() { history.push(redirectURL); }; - const showSubmitButton = selectedTable.value; const submitButtonDisable = !selectedTable.value; // if the datasource has basic information to connect to db it is considered as a valid structure hence isValid true. const isValidDatasourceConfig = selectedDatasource.data?.isValid; - const selectedDatasourcePluginId: string = selectedDatasource.data?.pluginId; - const selectedDatasourcePluginPackageName: string = - generateCRUDSupportedPlugin[selectedDatasourcePluginId]; + const pluginField: { TABLE: string; COLUMN: string; @@ -399,17 +440,37 @@ function GeneratePageForm() { const columnLabel = pluginField.COLUMN; let tableDropdownErrorMsg = ""; - if (!isFetchingDatasourceStructure) { + + const fetchingDatasourceConfigs = + isFetchingDatasourceStructure || + (isFetchingBucketList && isS3Plugin) || + ((isFetchingSheetPluginForm || isExecutingDatasourceQuery) && + isGoogleSheetPlugin); + + const fetchingDatasourceConfigError = + selectedDatasourceIsInvalid || + !isValidDatasourceConfig || + (failedFetchingBucketList && isS3Plugin); + + if (!fetchingDatasourceConfigs) { if (datasourceTableOptions.length === 0) { tableDropdownErrorMsg = `Couldn't find any ${tableLabel}, Please select another datasource`; } - if (selectedDatasourceIsInvalid || !isValidDatasourceConfig) { + if (fetchingDatasourceConfigError) { tableDropdownErrorMsg = `Failed fetching datasource structure, Please check your datasource configuration`; } } - const isGoogleSheetPlugin = - selectedDatasourcePluginPackageName === PLUGIN_PACKAGE_NAME.GOOGLE_SHEETS; + const showEditDatasourceBtn = + !fetchingDatasourceConfigs && + fetchingDatasourceConfigError && + !!selectedDatasource.value; + + const showSubmitButton = selectedTable.value && !showEditDatasourceBtn; + + const showSearchableColumnDropdown = + !!selectedTable.value && + PLUGIN_PACKAGE_NAME.S3 !== selectedDatasourcePluginPackageName; return (
@@ -419,7 +480,7 @@ function GeneratePageForm() { - + + {selectedDatasource.value ? ( + + + + + ) : null} + {showEditDatasourceBtn && ( + + )} {!isGoogleSheetPlugin ? ( - <> - {selectedDatasource.value ? ( - - - - - ) : null} - {!isFetchingDatasourceStructure && - (selectedDatasourceIsInvalid || !isValidDatasourceConfig) && - selectedDatasource.value && ( - - )} - {selectedTable.value ? ( - - - - - ) : null} - + showSearchableColumnDropdown && ( + + + + + ) ) : ( )} - {showSubmitButton ? ( ; + statusCode: string; + isExecutionSuccess: boolean; + }; +}; + +export const useS3BucketList = () => { + const dispatch = useDispatch(); + + const [bucketList, setBucketList] = useState>([]); + const [isFetchingBucketList, setIsFetchingBucketList] = useState( + false, + ); + const [failedFetchingBucketList, setFailedFetchingBucketList] = useState< + boolean + >(false); + const onFetchBucketSuccess = useCallback( + (payload: executeDatasourceQuerySuccessPayload) => { + setIsFetchingBucketList(false); + if (payload.data && payload.data.body) { + const payloadBody = payload.data.body; + const { bucketList: list = [] } = payloadBody; + setBucketList(list); + } + }, + [setBucketList, setIsFetchingBucketList], + ); + + const onFetchBucketFailure = useCallback(() => { + setIsFetchingBucketList(false); + setFailedFetchingBucketList(true); + }, [setIsFetchingBucketList]); + + const fetchBucketList = useCallback( + ({ selectedDatasource }: { selectedDatasource: DropdownOption }) => { + if (selectedDatasource.id) { + setIsFetchingBucketList(true); + setFailedFetchingBucketList(false); + dispatch( + executeDatasourceQuery({ + payload: { + datasourceId: selectedDatasource.id, + data: payload, + }, + onSuccessCallback: onFetchBucketSuccess, + onErrorCallback: onFetchBucketFailure, + }), + ); + } + }, + [onFetchBucketSuccess, onFetchBucketFailure, setIsFetchingBucketList], + ); + + return { + bucketList, + isFetchingBucketList, + failedFetchingBucketList, + fetchBucketList, + }; +}; diff --git a/app/client/src/pages/Editor/GeneratePage/components/GeneratePageForm/styles.ts b/app/client/src/pages/Editor/GeneratePage/components/GeneratePageForm/styles.ts new file mode 100644 index 000000000000..7817dde0db9a --- /dev/null +++ b/app/client/src/pages/Editor/GeneratePage/components/GeneratePageForm/styles.ts @@ -0,0 +1,16 @@ +import styled from "styled-components"; +import { getTypographyByKey } from "constants/DefaultTheme"; + +export const SelectWrapper = styled.div<{ width: string }>` + margin: 10px; + max-width: ${(props) => props.width}; +`; + +export const Label = styled.p` + flex: 1; + ${(props) => `${getTypographyByKey(props, "p1")}`} +`; + +export const Bold = styled.span` + font-weight: 500; +`; diff --git a/app/client/src/pages/Editor/GeneratePage/components/GoogleSheetForm.tsx b/app/client/src/pages/Editor/GeneratePage/components/GoogleSheetForm.tsx index ba2088260cfe..81e36f5d271a 100644 --- a/app/client/src/pages/Editor/GeneratePage/components/GoogleSheetForm.tsx +++ b/app/client/src/pages/Editor/GeneratePage/components/GoogleSheetForm.tsx @@ -1,181 +1,131 @@ -import React, { useEffect } from "react"; -import styled from "styled-components"; -import Dropdown from "components/ads/Dropdown"; -import { getTypographyByKey } from "constants/DefaultTheme"; +import React, { useState, useEffect, useCallback } from "react"; import { useSelector, useDispatch } from "react-redux"; -import { - getEditorConfig, - getIsFetchingSinglePluginForm, -} from "selectors/entitiesSelector"; +import { getEditorConfig } from "selectors/entitiesSelector"; import { AppState } from "reducers/index"; -import { DropdownOption } from "components/ads/Dropdown"; +import Dropdown, { DropdownOption } from "components/ads/Dropdown"; import { fetchPluginFormConfig } from "actions/pluginActions"; import { executeDatasourceQuery, executeDatasourceQuerySuccessPayload, } from "../../../../actions/datasourceActions"; -import { DropdownOptions, DatasourceTableDropdownOption } from "./constants"; +import { + DropdownOptions, + DROPDOWN_DIMENSION, + DEFAULT_DROPDOWN_OPTION, +} from "./constants"; +import { SelectWrapper, Label, Bold } from "./GeneratePageForm/styles"; import log from "loglevel"; -// const GOOGLE_SHEET_METHODS = { -// GET_ALL_SPREADSHEETS: "LIST", // Get all the spreadsheets -// GET_ALL_SHEETS: "INFO", // fetch all the sub-sheets -// GET_ALL_COLUMNS: "GET", // Get column names -// }; - -const DEMO_LIST_DATA = [ - { - key: "method", - value: "LIST", - }, - { - key: "sheetUrl", - }, - { - key: "range", - value: "", - }, - { - key: "spreadsheetName", - value: "", - }, - { - key: "tableHeaderIndex", - value: "1", - }, - { - key: "queryFormat", - value: "ROWS", - }, - { - key: "rowLimit", - value: "", - }, - { - key: "sheetName", - value: "", - }, - { - key: "rowOffset", - value: "", - }, - { - key: "rowObject", - }, - { - key: "rowObjects", - }, - { - key: "rowIndex", - value: "", - }, - { - key: "deleteFormat", - value: "SHEET", - }, -]; - -const DROPDOWN_DIMENSION = { - HEIGHT: "36px", - WIDTH: "404px", +const GOOGLE_SHEET_METHODS = { + GET_ALL_SPREADSHEETS: "LIST", // Get all the spreadsheets + GET_ALL_SHEETS: "INFO", // fetch all the sub-sheets + GET_ALL_COLUMNS: "GET", // Get column names }; -// ---------- Styles ---------- -const SelectWrapper = styled.div` - margin: 10px; -`; - -const Label = styled.p` - ${(props) => `${getTypographyByKey(props, "p1")}`} -`; +const demoRequest = { + method: "", + sheetUrl: "", + range: "", + spreadsheetName: "", + tableHeaderIndex: "1", + queryFormat: "ROWS", + rowLimit: "", + sheetsName: "", + rowOffset: "", + rowObject: "", + rowObjects: "", + rowIndex: "", + deleteFormat: "SHEET", +}; -const Bold = styled.span` - font-weight: 500; -`; +const getSheetUrl = (sheetId: string): string => + `https://docs.google.com/spreadsheets/d/${sheetId}/edit#gid=0`; // Types +export interface GridProperties { + rowCount: number; + columnCount: number; +} + +export interface Sheet { + sheetId: number; + title: string; + index: number; + sheetType: string; + gridProperties: GridProperties; +} + +export type Sheets = Sheet[]; + type Props = { - columnLabel: string; - datasourceTableOptions: DropdownOptions; googleSheetPluginId: string; - isFetchingDatasourceStructure: boolean; - onSelectColumn: ( - table: string | undefined, - ColumnObj: DropdownOption | undefined, - ) => void; - onSelectTable: ( - table: string | undefined, - TableObj: DatasourceTableDropdownOption, - ) => void; - selectedColumn: DropdownOption; selectedDatasource: DropdownOption; - selectedTable: DropdownOption; - selectedTableColumnOptions: DropdownOptions; - tableDropdownErrorMsg: string; - tableLabel: string; + setSelectedDatasourceIsInvalid: (isInvalid: boolean) => void; setSelectedDatasourceTableOptions: React.Dispatch< React.SetStateAction >; + selectedSpreadsheet: DropdownOption; }; // ---------- GoogleSheetForm Component ------- function GoogleSheetForm(props: Props) { const { - columnLabel, - datasourceTableOptions, googleSheetPluginId, - isFetchingDatasourceStructure, - onSelectColumn, - onSelectTable, - selectedColumn, selectedDatasource, - selectedTable, - selectedTableColumnOptions, + selectedSpreadsheet, + setSelectedDatasourceIsInvalid, setSelectedDatasourceTableOptions, - tableDropdownErrorMsg, - tableLabel, } = props; + const [sheetsList, setSheetsList] = useState([]); + + const [selectedSheet, setSelectedSheet] = useState( + DEFAULT_DROPDOWN_OPTION, + ); const dispatch = useDispatch(); const googleSheetEditorConfig = useSelector((state: AppState) => getEditorConfig(state, googleSheetPluginId), ); - const isFetchingSheetPluginForm = useSelector((state: AppState) => - getIsFetchingSinglePluginForm(state, googleSheetPluginId), - ); - // TODO :- Create loading state and set Loading state false on success or error const onFetchAllSpreadsheetFailure = (error: any) => { log.error(error); }; - const onFetchAllSpreadsheetSuccess = ( - payload: executeDatasourceQuerySuccessPayload, - ) => { - const tableOptions: DropdownOptions = []; - if (payload.data && payload.data.body) { - const spreadSheets = payload.data.body; - spreadSheets.map(({ id, name }) => { - tableOptions.push({ - id, - label: name, - value: id, - }); - setSelectedDatasourceTableOptions(tableOptions); - }); - } - }; + const onFetchAllSpreadsheetSuccess = useCallback( + ( + payload: executeDatasourceQuerySuccessPayload< + Array<{ id: string; name: string }> + >, + ) => { + const tableOptions: DropdownOptions = []; + if (payload.data && payload.data.body) { + const spreadSheets = payload.data.body; + + if (Array.isArray(spreadSheets)) { + spreadSheets.map(({ id, name }) => { + tableOptions.push({ + id, + label: name, + value: name, + }); + setSelectedDatasourceTableOptions(tableOptions); + }); + } else { + // to handle error like "401 Unauthorized" + setSelectedDatasourceIsInvalid(true); + } + } + }, + [setSelectedDatasourceIsInvalid, setSelectedDatasourceTableOptions], + ); useEffect(() => { - // On change of datasource selection // Check if google sheet editor config is fetched. - // if NO, Check if new selected datasource is google sheet. - // if YES => fetch google sheet editor config. - // if YES, Get all spreadsheets + // if not, fetch it. if (!googleSheetEditorConfig) { dispatch( @@ -183,56 +133,156 @@ function GoogleSheetForm(props: Props) { pluginId: selectedDatasource.data?.pluginId, }), ); - } else { - // Get all the spreadsheets - if (selectedDatasource.id) { - dispatch( - executeDatasourceQuery({ - payload: { - datasourceId: selectedDatasource.id, - data: DEMO_LIST_DATA, - }, - onSuccessCallback: onFetchAllSpreadsheetSuccess, - onErrorCallback: onFetchAllSpreadsheetFailure, - }), - ); - } + } + }, [googleSheetEditorConfig]); + + useEffect(() => { + // On change of datasource selection + // if googleSheetEditorConfig if fetched then get all spreadsheets + + if ( + selectedDatasource.value && + selectedDatasource.id && + googleSheetEditorConfig + ) { + const requestData = { ...demoRequest }; + requestData.method = GOOGLE_SHEET_METHODS.GET_ALL_SPREADSHEETS; + const formattedRequestData = Object.entries( + requestData, + ).map(([dataKey, dataValue]) => ({ key: dataKey, value: dataValue })); + dispatch( + executeDatasourceQuery({ + payload: { + datasourceId: selectedDatasource.id, + data: formattedRequestData, + }, + onSuccessCallback: onFetchAllSpreadsheetSuccess, + onErrorCallback: onFetchAllSpreadsheetFailure, + }), + ); } }, [selectedDatasource.value, googleSheetEditorConfig, dispatch]); + // TODO :- Create loading state and set Loading state false on success or error + const onFetchAllSheetFailure = (error: any) => { + log.error(error); + }; + + const onFetchAllSheetSuccess = useCallback( + ( + payload: executeDatasourceQuerySuccessPayload<{ + sheets: Sheets; + name: string; + id: string; + }>, + ) => { + const sheetOptions: DropdownOptions = []; + if (payload.data && payload.data.body) { + const responseBody = payload.data.body; + const { sheets = [] } = responseBody; + if (Array.isArray(sheets)) { + sheets.map(({ title }) => { + sheetOptions.push({ + id: title, + label: title, + value: title, + }); + setSheetsList(sheetOptions); + }); + } else { + // to handle error like "401 Unauthorized" + } + } + }, + [setSelectedDatasourceIsInvalid, setSelectedDatasourceTableOptions], + ); + + // When user selects a spreadsheet + // Fetch all sheets inside that spreadsheet + useEffect(() => { + if ( + selectedDatasource.value && + selectedDatasource.id && + selectedSpreadsheet.value && + selectedSpreadsheet.id + ) { + const requestData = { ...demoRequest }; + requestData.method = GOOGLE_SHEET_METHODS.GET_ALL_SHEETS; + requestData.sheetUrl = getSheetUrl(selectedSpreadsheet.id); + const formattedRequestData = Object.entries( + requestData, + ).map(([dataKey, dataValue]) => ({ key: dataKey, value: dataValue })); + dispatch( + executeDatasourceQuery({ + payload: { + datasourceId: selectedDatasource.id, + data: formattedRequestData, + }, + onSuccessCallback: onFetchAllSheetSuccess, + onErrorCallback: onFetchAllSheetFailure, + }), + ); + } + }, [ + selectedSpreadsheet.id, + selectedSpreadsheet.value, + selectedDatasource.id, + selectedDatasource.value, + dispatch, + ]); + + const onSelectSheetOption = ( + sheetValue: string | undefined, + sheetObj: DropdownOption | undefined, + ) => { + if (sheetValue && sheetObj) { + setSelectedSheet(sheetObj); + } + }; + + const onSelectColumn = () => { + // + }; + + const selectedColumn = DEFAULT_DROPDOWN_OPTION; + + const selectedTableColumnOptions: DropdownOptions = []; + return ( - <> - {selectedDatasource.value ? ( - +
+ {selectedSpreadsheet.value ? ( + ) : null} - {selectedTable.value ? ( - + {selectedSheet.value && ( + + - ) : null} - + )} +
); } diff --git a/app/client/src/pages/Editor/GeneratePage/components/constants.ts b/app/client/src/pages/Editor/GeneratePage/components/constants.ts index 970c19df3ffc..8a37641ee8eb 100644 --- a/app/client/src/pages/Editor/GeneratePage/components/constants.ts +++ b/app/client/src/pages/Editor/GeneratePage/components/constants.ts @@ -39,3 +39,25 @@ export const PluginFormInputFieldMap: Record< COLUMN: "column", }, }; + +export const DROPDOWN_DIMENSION = { + HEIGHT: "36px", + WIDTH: "404px", +}; + +export const DEFAULT_DROPDOWN_OPTION = { + id: "- Select -", + label: "- Select -", + value: "", + onSelect: () => null, + data: {}, +}; + +export const ALLOWED_SEARCH_DATATYPE = [ + "text", + "string", + "char", + "varchar", + "character", + "text string", +]; diff --git a/app/client/src/reducers/entityReducers/datasourceReducer.ts b/app/client/src/reducers/entityReducers/datasourceReducer.ts index 02b4272b0db9..95eec94f2d6c 100644 --- a/app/client/src/reducers/entityReducers/datasourceReducer.ts +++ b/app/client/src/reducers/entityReducers/datasourceReducer.ts @@ -20,6 +20,7 @@ export interface DatasourceDataState { structure: Record; isFetchingMockDataSource: false; mockDatasourceList: any[]; + executingDatasourceQuery: boolean; } const initialState: DatasourceDataState = { @@ -32,6 +33,7 @@ const initialState: DatasourceDataState = { structure: {}, isFetchingMockDataSource: false, mockDatasourceList: [], + executingDatasourceQuery: false, }; const datasourceReducer = createReducer(initialState, { @@ -97,6 +99,16 @@ const datasourceReducer = createReducer(initialState, { ) => { return { ...state, isRefreshingStructure: true }; }, + [ReduxActionTypes.EXECUTE_DATASOURCE_QUERY_INIT]: ( + state: DatasourceDataState, + ) => { + return { ...state, executingDatasourceQuery: true }; + }, + [ReduxActionTypes.EXECUTE_DATASOURCE_QUERY_SUCCESS]: ( + state: DatasourceDataState, + ) => { + return { ...state, executingDatasourceQuery: false }; + }, [ReduxActionTypes.FETCH_DATASOURCE_STRUCTURE_INIT]: ( state: DatasourceDataState, ) => { @@ -279,6 +291,14 @@ const datasourceReducer = createReducer(initialState, { isRefreshingStructure: false, }; }, + [ReduxActionErrorTypes.EXECUTE_DATASOURCE_QUERY_ERROR]: ( + state: DatasourceDataState, + ) => { + return { + ...state, + executingDatasourceQuery: false, + }; + }, }); export default datasourceReducer; diff --git a/app/client/src/sagas/DatasourcesSagas.ts b/app/client/src/sagas/DatasourcesSagas.ts index 7fb4d8e4251e..5cd94d78a300 100644 --- a/app/client/src/sagas/DatasourcesSagas.ts +++ b/app/client/src/sagas/DatasourcesSagas.ts @@ -902,7 +902,7 @@ function* refreshDatasourceStructure(action: ReduxAction<{ id: string }>) { } function* executeDatasourceQuerySaga( - action: executeDatasourceQueryReduxAction, + action: executeDatasourceQueryReduxAction, ) { try { const response: GenericApiResponse = yield DatasourcesApi.executeDatasourceQuery( diff --git a/app/client/src/selectors/entitiesSelector.ts b/app/client/src/selectors/entitiesSelector.ts index c2563f5780ae..29e036a79168 100644 --- a/app/client/src/selectors/entitiesSelector.ts +++ b/app/client/src/selectors/entitiesSelector.ts @@ -17,7 +17,7 @@ import { CanvasWidgetsReduxState } from "../reducers/entityReducers/canvasWidget import { MAIN_CONTAINER_WIDGET_ID } from "constants/WidgetConstants"; import { AppStoreState } from "reducers/entityReducers/appReducer"; import { GenerateCRUDEnabledPluginMap } from "../api/PluginApi"; -import { PLUGIN_PACKAGE_NAME } from "../pages/Editor/GeneratePage/components/constants"; +import { PLUGIN_PACKAGE_NAME } from "pages/Editor/GeneratePage/components/constants"; import { APP_MODE } from "entities/App"; @@ -124,6 +124,10 @@ export const getIsFetchingSinglePluginForm = ( return !!state.entities.plugins.fetchingSinglePluginForm[pluginId]; }; +export const getIsExecutingDatasourceQuery = (state: AppState): boolean => { + return state.entities.datasources.executingDatasourceQuery; +}; + export const getEditorConfig = (state: AppState, pluginId: string): any[] => { return state.entities.plugins.editorConfigs[pluginId]; }; @@ -252,12 +256,10 @@ export const getGenerateCRUDEnabledPluginMap = createSelector( getPlugins, (plugins) => { const pluginIdGenerateCRUDPageEnabled: GenerateCRUDEnabledPluginMap = {}; - // Disable google sheet plugin plugins.map((plugin) => { if ( plugin.generateCRUDPageComponent && - plugin.packageName !== PLUGIN_PACKAGE_NAME.GOOGLE_SHEETS && - plugin.packageName !== PLUGIN_PACKAGE_NAME.S3 + plugin.packageName !== PLUGIN_PACKAGE_NAME.GOOGLE_SHEETS ) { pluginIdGenerateCRUDPageEnabled[plugin.id] = plugin.packageName; } From add2127dad6908bac25efd0c96a914e41f6d1061 Mon Sep 17 00:00:00 2001 From: Rishabh Saxena Date: Fri, 20 Aug 2021 13:00:36 +0530 Subject: [PATCH 02/76] Remove onboarding typeform (#6752) --- app/client/src/configs/index.ts | 3 - app/client/src/configs/types.ts | 1 - .../src/pages/Applications/OnboardingForm.tsx | 43 ------------- app/client/src/pages/Applications/index.tsx | 63 ++++--------------- app/client/src/utils/storage.ts | 23 ------- 5 files changed, 13 insertions(+), 120 deletions(-) delete mode 100644 app/client/src/pages/Applications/OnboardingForm.tsx diff --git a/app/client/src/configs/index.ts b/app/client/src/configs/index.ts index 133d5ad60c4c..6bc8a12edf16 100644 --- a/app/client/src/configs/index.ts +++ b/app/client/src/configs/index.ts @@ -43,7 +43,6 @@ export type INJECTED_CONFIGS = { disableTelemetry: boolean; cloudServicesBaseUrl: string; googleRecaptchaSiteKey: string; - onboardingFormEnabled: boolean; supportEmail: string; }; declare global { @@ -120,7 +119,6 @@ const getConfigsFromEnvVars = (): INJECTED_CONFIGS => { cloudServicesBaseUrl: process.env.REACT_APP_CLOUD_SERVICES_BASE_URL || "", googleRecaptchaSiteKey: process.env.REACT_APP_GOOGLE_RECAPTCHA_SITE_KEY || "", - onboardingFormEnabled: !!process.env.REACT_APP_SHOW_ONBOARDING_FORM, supportEmail: process.env.APPSMITH_SUPPORT_EMAIL || "support@appsmith.com", }; }; @@ -285,7 +283,6 @@ export const getAppsmithConfigs = (): AppsmithUIConfigs => { cloudServicesBaseUrl: ENV_CONFIG.cloudServicesBaseUrl || APPSMITH_FEATURE_CONFIGS.cloudServicesBaseUrl, - onboardingFormEnabled: ENV_CONFIG.onboardingFormEnabled, appsmithSupportEmail: ENV_CONFIG.supportEmail, }; }; diff --git a/app/client/src/configs/types.ts b/app/client/src/configs/types.ts index 71b4e71c2f1c..21459345eaac 100644 --- a/app/client/src/configs/types.ts +++ b/app/client/src/configs/types.ts @@ -77,6 +77,5 @@ export type AppsmithUIConfigs = { enabled: boolean; apiKey: string; }; - onboardingFormEnabled: boolean; appsmithSupportEmail: string; }; diff --git a/app/client/src/pages/Applications/OnboardingForm.tsx b/app/client/src/pages/Applications/OnboardingForm.tsx deleted file mode 100644 index f573d62b103b..000000000000 --- a/app/client/src/pages/Applications/OnboardingForm.tsx +++ /dev/null @@ -1,43 +0,0 @@ -import React, { useEffect } from "react"; -import { useSelector } from "react-redux"; -import { useScript, ScriptStatus } from "utils/hooks/useScript"; -import { getCurrentUser } from "selectors/usersSelectors"; -import styled from "styled-components"; -import { setOnboardingFormInProgress } from "utils/storage"; - -export const TypeformContainer = styled.div` - & iframe { - position: absolute; - left: 0; - right: 0; - bottom: 0; - top: 0; - border: 0; - } -`; - -function OnboardingForm() { - const status = useScript(`https://embed.typeform.com/embed.js`); - const currentUser = useSelector(getCurrentUser); - - useEffect(() => { - setOnboardingFormInProgress(true); - }, []); - - if (status !== ScriptStatus.READY || !currentUser) return null; - - return ( - -