From f90acb8296603a22cb698366835302b395151365 Mon Sep 17 00:00:00 2001 From: albinAppsmith <87797149+albinAppsmith@users.noreply.github.com> Date: Fri, 15 Nov 2024 08:29:56 +0530 Subject: [PATCH 01/17] fix: eslint warnings in schema --- .../cypress/support/Pages/DataSources.ts | 2 +- .../components/Schema.tsx | 64 +++++++++++-------- .../DatasourceViewModeSchema.tsx | 2 +- .../DatasourceInfo/GoogleSheetSchema.tsx | 2 +- 4 files changed, 42 insertions(+), 28 deletions(-) diff --git a/app/client/cypress/support/Pages/DataSources.ts b/app/client/cypress/support/Pages/DataSources.ts index b56ad7792f35..e9813ba0fe83 100644 --- a/app/client/cypress/support/Pages/DataSources.ts +++ b/app/client/cypress/support/Pages/DataSources.ts @@ -295,7 +295,7 @@ export class DataSources { _imgFireStoreLogo = "//img[contains(@src, 'firestore.svg')]"; _dsVirtuosoElement = `div .t--schema-virtuoso-container`; private _dsVirtuosoList = `[data-test-id="virtuoso-item-list"]`; - private _dsSchemaContainer = `[data-testid="datasource-schema-container"]`; + private _dsSchemaContainer = `[data-testid="t--datasource-schema-container"]`; private _dsVirtuosoElementTable = (targetTableName: string) => `${this._dsSchemaEntityItem}[data-testid='t--entity-item-${targetTableName}']`; private _dsPageTabListItem = (buttonText: string) => diff --git a/app/client/src/PluginActionEditor/components/PluginActionResponse/components/Schema.tsx b/app/client/src/PluginActionEditor/components/PluginActionResponse/components/Schema.tsx index 7305c7a13927..31473bcbaf7b 100644 --- a/app/client/src/PluginActionEditor/components/PluginActionResponse/components/Schema.tsx +++ b/app/client/src/PluginActionEditor/components/PluginActionResponse/components/Schema.tsx @@ -74,31 +74,45 @@ const Schema = (props: Props) => { getPluginDatasourceComponentFromId(state, pluginId || ""), ); - useEffect(() => { - setSelectedTable(undefined); - }, [props.datasourceId]); + useEffect( + function resetSelectedTable() { + setSelectedTable(undefined); + }, + [props.datasourceId], + ); + + useEffect( + function fetchDatasourceStructureEffect() { + function fetchStructure() { + if ( + props.datasourceId && + datasourceStructure === undefined && + pluginDatasourceForm !== + DatasourceComponentTypes.RestAPIDatasourceForm + ) { + dispatch( + fetchDatasourceStructure( + props.datasourceId, + true, + DatasourceStructureContext.QUERY_EDITOR, + ), + ); + } + } - useEffect(() => { - if ( - props.datasourceId && - datasourceStructure === undefined && - pluginDatasourceForm !== DatasourceComponentTypes.RestAPIDatasourceForm - ) { - dispatch( - fetchDatasourceStructure( - props.datasourceId, - true, - DatasourceStructureContext.QUERY_EDITOR, - ), - ); - } - }, [props.datasourceId, datasourceStructure, dispatch, pluginDatasourceForm]); - - useEffect(() => { - if (!selectedTable && datasourceStructure?.tables?.length && !isLoading) { - setSelectedTable(datasourceStructure.tables[0].name); - } - }, [selectedTable, props.datasourceId, isLoading, datasourceStructure]); + fetchStructure(); + }, + [props.datasourceId, datasourceStructure, dispatch, pluginDatasourceForm], + ); + + useEffect( + function selectFirstTable() { + if (!selectedTable && datasourceStructure?.tables?.length && !isLoading) { + setSelectedTable(datasourceStructure.tables[0].name); + } + }, + [selectedTable, props.datasourceId, isLoading, datasourceStructure], + ); const refreshStructure = useCallback(() => { dispatch( @@ -134,7 +148,7 @@ const Schema = (props: Props) => { overflow="hidden" > { return ( - + {props.datasource && ( - + {datasource && ( Date: Fri, 15 Nov 2024 08:31:18 +0530 Subject: [PATCH 02/17] fix: changed schema location --- .../components/{Schema.tsx => Schema/index.tsx} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename app/client/src/PluginActionEditor/components/PluginActionResponse/components/{Schema.tsx => Schema/index.tsx} (100%) diff --git a/app/client/src/PluginActionEditor/components/PluginActionResponse/components/Schema.tsx b/app/client/src/PluginActionEditor/components/PluginActionResponse/components/Schema/index.tsx similarity index 100% rename from app/client/src/PluginActionEditor/components/PluginActionResponse/components/Schema.tsx rename to app/client/src/PluginActionEditor/components/PluginActionResponse/components/Schema/index.tsx From 6d77b2e2daa8e3a75bb7316f4522cedb62535daf Mon Sep 17 00:00:00 2001 From: albinAppsmith <87797149+albinAppsmith@users.noreply.github.com> Date: Fri, 15 Nov 2024 08:33:30 +0530 Subject: [PATCH 03/17] fix: import issue getPluginActionDevuggerState in schema --- .../components/PluginActionResponse/components/Schema/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/client/src/PluginActionEditor/components/PluginActionResponse/components/Schema/index.tsx b/app/client/src/PluginActionEditor/components/PluginActionResponse/components/Schema/index.tsx index 31473bcbaf7b..0bb205aef1a9 100644 --- a/app/client/src/PluginActionEditor/components/PluginActionResponse/components/Schema/index.tsx +++ b/app/client/src/PluginActionEditor/components/PluginActionResponse/components/Schema/index.tsx @@ -18,7 +18,6 @@ import DatasourceField from "pages/Editor/DatasourceInfo/DatasourceField"; import { find } from "lodash"; import type { AppState } from "ee/reducers"; import RenderInterimDataState from "pages/Editor/DatasourceInfo/RenderInterimDataState"; -import { getPluginActionDebuggerState } from "../../../store"; import { fetchDatasourceStructure, refreshDatasourceStructure, @@ -28,6 +27,7 @@ import { datasourcesEditorIdURL } from "ee/RouteBuilder"; import { EntityIcon } from "pages/Editor/Explorer/ExplorerIcons"; import { getAssetUrl } from "ee/utils/airgapHelpers"; import { DatasourceComponentTypes } from "api/PluginApi"; +import { getPluginActionDebuggerState } from "PluginActionEditor/store"; interface Props { datasourceId: string; From 3f7e26b753800a820bc580a85904fbd99ee1e43a Mon Sep 17 00:00:00 2001 From: albinAppsmith <87797149+albinAppsmith@users.noreply.github.com> Date: Fri, 15 Nov 2024 12:39:52 +0530 Subject: [PATCH 04/17] fix: added status-display --- .../components/Schema/StatusDisplay.tsx | 91 +++++++++++++++++++ .../components/Schema/index.tsx | 65 +++++++------ 2 files changed, 128 insertions(+), 28 deletions(-) create mode 100644 app/client/src/PluginActionEditor/components/PluginActionResponse/components/Schema/StatusDisplay.tsx diff --git a/app/client/src/PluginActionEditor/components/PluginActionResponse/components/Schema/StatusDisplay.tsx b/app/client/src/PluginActionEditor/components/PluginActionResponse/components/Schema/StatusDisplay.tsx new file mode 100644 index 000000000000..47391e37fd32 --- /dev/null +++ b/app/client/src/PluginActionEditor/components/PluginActionResponse/components/Schema/StatusDisplay.tsx @@ -0,0 +1,91 @@ +import React, { type ReactNode } from "react"; + +import { Flex, Spinner, Text } from "@appsmith/ads"; + +import { + createMessage, + EMPTY_TABLE_MESSAGE_TEXT, + EMPTY_TABLE_TITLE_TEXT, + FAILED_RECORDS_MESSAGE_TEXT, + FAILED_RECORDS_TITLE_TEXT, + LOADING_RECORDS_MESSAGE_TEXT, + LOADING_RECORDS_TITLE_TEXT, + NO_COLUMNS_MESSAGE_TEXT, +} from "ee/constants/messages"; +import { getAssetUrl } from "ee/utils/airgapHelpers"; +import { ASSETS_CDN_URL } from "constants/ThirdPartyConstants"; + +type IStates = "LOADING" | "NODATA" | "FAILED" | "NOCOLUMNS"; + +interface IProps { + state: IStates; + height?: string; +} + +const StateData: Record< + IStates, + { title: string; message: string; image: string | ReactNode } +> = { + LOADING: { + title: createMessage(LOADING_RECORDS_TITLE_TEXT), + message: createMessage(LOADING_RECORDS_MESSAGE_TEXT), + image: , + }, + NODATA: { + title: createMessage(EMPTY_TABLE_TITLE_TEXT), + message: createMessage(EMPTY_TABLE_MESSAGE_TEXT), + image: getAssetUrl(`${ASSETS_CDN_URL}/empty-state.svg`), + }, + FAILED: { + title: createMessage(FAILED_RECORDS_TITLE_TEXT), + message: createMessage(FAILED_RECORDS_MESSAGE_TEXT), + image: getAssetUrl(`${ASSETS_CDN_URL}/failed-state.svg`), + }, + NOCOLUMNS: { + title: createMessage(EMPTY_TABLE_TITLE_TEXT), + message: createMessage(NO_COLUMNS_MESSAGE_TEXT), + image: getAssetUrl(`${ASSETS_CDN_URL}/empty-state.svg`), + }, +}; + +const StatusDisplay = ({ height, state }: IProps) => { + const { image, message, title } = StateData[state]; + + return ( + + + {typeof image === "string" ? ( + {title} + ) : ( + image + )} + + {title} + {message} + + + + ); +}; + +export { StatusDisplay }; diff --git a/app/client/src/PluginActionEditor/components/PluginActionResponse/components/Schema/index.tsx b/app/client/src/PluginActionEditor/components/PluginActionResponse/components/Schema/index.tsx index 0bb205aef1a9..d4ea109a244f 100644 --- a/app/client/src/PluginActionEditor/components/PluginActionResponse/components/Schema/index.tsx +++ b/app/client/src/PluginActionEditor/components/PluginActionResponse/components/Schema/index.tsx @@ -1,33 +1,34 @@ -import { Button, Flex, Link } from "@appsmith/ads"; -import React, { useCallback, useEffect, useState } from "react"; +import { Flex } from "@appsmith/ads"; +import React, { useEffect, useState } from "react"; import { DatasourceStructureContext, type DatasourceColumns, type DatasourceKeys, } from "entities/Datasource"; -import { DatasourceStructureContainer as DatasourceStructureList } from "pages/Editor/DatasourceInfo/DatasourceStructureContainer"; +// import { DatasourceStructureContainer as DatasourceStructureList } from "pages/Editor/DatasourceInfo/DatasourceStructureContainer"; import { useDispatch, useSelector } from "react-redux"; import { getDatasourceStructureById, getIsFetchingDatasourceStructure, - getPluginImages, + // getPluginImages, getPluginIdFromDatasourceId, getPluginDatasourceComponentFromId, } from "ee/selectors/entitiesSelector"; -import DatasourceField from "pages/Editor/DatasourceInfo/DatasourceField"; +// import DatasourceField from "pages/Editor/DatasourceInfo/DatasourceField"; import { find } from "lodash"; import type { AppState } from "ee/reducers"; import RenderInterimDataState from "pages/Editor/DatasourceInfo/RenderInterimDataState"; import { fetchDatasourceStructure, - refreshDatasourceStructure, + // refreshDatasourceStructure, } from "actions/datasourceActions"; -import history from "utils/history"; -import { datasourcesEditorIdURL } from "ee/RouteBuilder"; -import { EntityIcon } from "pages/Editor/Explorer/ExplorerIcons"; -import { getAssetUrl } from "ee/utils/airgapHelpers"; +// import history from "utils/history"; +// import { datasourcesEditorIdURL } from "ee/RouteBuilder"; +// import { EntityIcon } from "pages/Editor/Explorer/ExplorerIcons"; +// import { getAssetUrl } from "ee/utils/airgapHelpers"; import { DatasourceComponentTypes } from "api/PluginApi"; import { getPluginActionDebuggerState } from "PluginActionEditor/store"; +import { StatusDisplay } from "./StatusDisplay"; interface Props { datasourceId: string; @@ -46,8 +47,8 @@ const Schema = (props: Props) => { const pluginId = useSelector((state) => getPluginIdFromDatasourceId(state, props.datasourceId), ); - const pluginImages = useSelector((state) => getPluginImages(state)); - const datasourceIcon = pluginId ? pluginImages[pluginId] : undefined; + // const pluginImages = useSelector((state) => getPluginImages(state)); + // const datasourceIcon = pluginId ? pluginImages[pluginId] : undefined; const [selectedTable, setSelectedTable] = useState(); @@ -63,8 +64,8 @@ const Schema = (props: Props) => { columnsAndKeys.push(...selectedTableItems.columns); } - const columns = - find(datasourceStructure?.tables, ["name", selectedTable])?.columns || []; + // const columns = + // find(datasourceStructure?.tables, ["name", selectedTable])?.columns || []; const isLoading = useSelector((state: AppState) => getIsFetchingDatasourceStructure(state, props.datasourceId), @@ -114,18 +115,18 @@ const Schema = (props: Props) => { [selectedTable, props.datasourceId, isLoading, datasourceStructure], ); - const refreshStructure = useCallback(() => { - dispatch( - refreshDatasourceStructure( - props.datasourceId, - DatasourceStructureContext.QUERY_EDITOR, - ), - ); - }, [dispatch, props.datasourceId]); + // const refreshStructure = useCallback(() => { + // dispatch( + // refreshDatasourceStructure( + // props.datasourceId, + // DatasourceStructureContext.QUERY_EDITOR, + // ), + // ); + // }, [dispatch, props.datasourceId]); - const goToDatasource = useCallback(() => { - history.push(datasourcesEditorIdURL({ datasourceId: props.datasourceId })); - }, [props.datasourceId]); + // const goToDatasource = useCallback(() => { + // history.push(datasourcesEditorIdURL({ datasourceId: props.datasourceId })); + // }, [props.datasourceId]); if (!datasourceStructure) { return ( @@ -139,15 +140,23 @@ const Schema = (props: Props) => { ); } + const renderContent = () => { + // if (isLoading) { + return ( + + ); + // } + }; + return ( - { /> ); })} - + */} ); }; From c58f5d93618b320d02e876c7c3e48d8ece671fa1 Mon Sep 17 00:00:00 2001 From: albinAppsmith <87797149+albinAppsmith@users.noreply.github.com> Date: Mon, 18 Nov 2024 12:08:50 +0530 Subject: [PATCH 05/17] fix: New changes to schema UI --- .../components/Schema/CurrentDataSource.tsx | 51 +++++ .../components/Schema/DatasourceSelector.tsx | 185 +++++++++++++++ .../components/Schema/SchemaTables.tsx | 93 ++++++++ .../components/Schema/StatusDisplay.tsx | 81 ++++--- .../components/Schema/TableColumns.tsx | 69 ++++++ .../components/Schema/index.tsx | 210 +++++++----------- app/client/src/ce/constants/messages.ts | 9 +- .../Editor/DatasourceInfo/DatasourceField.tsx | 33 +-- .../DatasourceStructureNotFound.tsx | 1 + 9 files changed, 557 insertions(+), 175 deletions(-) create mode 100644 app/client/src/PluginActionEditor/components/PluginActionResponse/components/Schema/CurrentDataSource.tsx create mode 100644 app/client/src/PluginActionEditor/components/PluginActionResponse/components/Schema/DatasourceSelector.tsx create mode 100644 app/client/src/PluginActionEditor/components/PluginActionResponse/components/Schema/SchemaTables.tsx create mode 100644 app/client/src/PluginActionEditor/components/PluginActionResponse/components/Schema/TableColumns.tsx diff --git a/app/client/src/PluginActionEditor/components/PluginActionResponse/components/Schema/CurrentDataSource.tsx b/app/client/src/PluginActionEditor/components/PluginActionResponse/components/Schema/CurrentDataSource.tsx new file mode 100644 index 000000000000..f01d40e6aec2 --- /dev/null +++ b/app/client/src/PluginActionEditor/components/PluginActionResponse/components/Schema/CurrentDataSource.tsx @@ -0,0 +1,51 @@ +import React, { useCallback } from "react"; +import { Flex, Link } from "@appsmith/ads"; +import { getAssetUrl } from "ee/utils/airgapHelpers"; +import { EntityIcon } from "pages/Editor/Explorer/ExplorerIcons"; +import history from "utils/history"; +import { datasourcesEditorIdURL } from "ee/RouteBuilder"; +import { useSelector } from "react-redux"; +import { + getPluginIdFromDatasourceId, + getPluginImages, +} from "ee/selectors/entitiesSelector"; + +interface iProps { + type: "link" | "trigger"; + datasourceId: string; + datasourceName: string; +} + +const CurrentDataSource = ({ datasourceId, datasourceName, type }: iProps) => { + const { pluginId, pluginImages } = useSelector((state) => ({ + pluginId: getPluginIdFromDatasourceId(state, datasourceId), + pluginImages: getPluginImages(state), + })); + + const goToDatasource = useCallback(() => { + history.push(datasourcesEditorIdURL({ datasourceId })); + }, [datasourceId]); + + const datasourceIcon = pluginId ? pluginImages?.[pluginId] : undefined; + + const content = ( + + + entityIcon + + {datasourceName} + + ); + + return type === "link" ? ( + {content} + ) : ( + content + ); +}; + +export { CurrentDataSource }; diff --git a/app/client/src/PluginActionEditor/components/PluginActionResponse/components/Schema/DatasourceSelector.tsx b/app/client/src/PluginActionEditor/components/PluginActionResponse/components/Schema/DatasourceSelector.tsx new file mode 100644 index 000000000000..b102716a27ff --- /dev/null +++ b/app/client/src/PluginActionEditor/components/PluginActionResponse/components/Schema/DatasourceSelector.tsx @@ -0,0 +1,185 @@ +import React, { useCallback } from "react"; +import { useSelector } from "react-redux"; +import { + Button, + Flex, + Icon, + Menu, + MenuContent, + MenuGroup, + MenuGroupName, + MenuItem, + MenuTrigger, + Text, +} from "@appsmith/ads"; +import { + CREATE_NEW_DATASOURCE, + createMessage, + DATASOURCE_SWITCHER_MENU_GROUP_NAME, +} from "ee/constants/messages"; +import { useFeatureFlag } from "utils/hooks/useFeatureFlag"; +import { FEATURE_FLAG } from "ee/entities/FeatureFlag"; +import { + getHasCreateDatasourcePermission, + getHasManageActionPermission, +} from "ee/utils/BusinessFeatures/permissionPageHelpers"; +import { doesPluginRequireDatasource } from "ee/entities/Engine/actionHelpers"; +import { + getActionByBaseId, + getDatasourceByPluginId, + getPlugin, + getPluginImages, +} from "ee/selectors/entitiesSelector"; +import type { Datasource } from "entities/Datasource"; +import type { AppState } from "ee/reducers"; +import { getCurrentAppWorkspace } from "ee/selectors/selectedWorkspaceSelectors"; +import { CurrentDataSource } from "./CurrentDataSource"; +import { useActiveActionBaseId } from "ee/pages/Editor/Explorer/hooks"; +import history from "utils/history"; +import { integrationEditorURL } from "ee/RouteBuilder"; +import { INTEGRATION_TABS } from "constants/routes"; +import { DatasourceCreateEntryPoints } from "constants/Datasource"; +import AnalyticsUtil from "ee/utils/AnalyticsUtil"; +import { getAssetUrl } from "ee/utils/airgapHelpers"; + +interface Props { + datasourceId: string; + datasourceName: string; +} + +interface DATASOURCES_OPTIONS_TYPE { + label: string; + value: string; + image: string; +} + +const DatasourceSelector = ({ datasourceId, datasourceName }: Props) => { + const [open, setIsOpen] = React.useState(false); + const activeActionBaseId = useActiveActionBaseId(); + const currentActionConfig = useSelector((state) => + activeActionBaseId + ? getActionByBaseId(state, activeActionBaseId) + : undefined, + ); + const plugin = useSelector((state: AppState) => + getPlugin(state, currentActionConfig?.pluginId || ""), + ); + + const dataSources = useSelector((state: AppState) => + getDatasourceByPluginId(state, currentActionConfig?.pluginId || ""), + ); + + const isFeatureEnabled = useFeatureFlag(FEATURE_FLAG.license_gac_enabled); + const userWorkspacePermissions = useSelector( + (state: AppState) => getCurrentAppWorkspace(state).userPermissions ?? [], + ); + const isChangePermitted = getHasManageActionPermission( + isFeatureEnabled, + currentActionConfig?.userPermissions, + ); + const canCreateDatasource = getHasCreateDatasourcePermission( + isFeatureEnabled, + userWorkspacePermissions, + ); + const showDatasourceSelector = doesPluginRequireDatasource(plugin); + const pluginImages = useSelector(getPluginImages); + + const onCreateDatasourceClick = useCallback(() => { + history.push( + integrationEditorURL({ + basePageId: currentActionConfig?.pageId, + selectedTab: INTEGRATION_TABS.NEW, + }), + ); + // Event for datasource creation click + const entryPoint = DatasourceCreateEntryPoints.QUERY_EDITOR; + + AnalyticsUtil.logEvent("NAVIGATE_TO_CREATE_NEW_DATASOURCE_PAGE", { + entryPoint, + }); + }, [currentActionConfig?.pageId]); + + const DATASOURCES_OPTIONS: Array = + dataSources.reduce( + (acc: Array, dataSource: Datasource) => { + if (dataSource.pluginId === plugin?.id) { + acc.push({ + label: dataSource.name, + value: dataSource.id, + image: pluginImages[dataSource.pluginId], + }); + } + + return acc; + }, + [], + ); + + // eslint-disable-next-line no-console + console.log(`AB -> showDatasourceSelector = ${showDatasourceSelector}`); + + if (!showDatasourceSelector || !isChangePermitted) { + return ( + + ); + } + + const onOpenChange = (newOpen: boolean) => { + setIsOpen(newOpen); + }; + + return ( + + + + + + + + + {createMessage(DATASOURCE_SWITCHER_MENU_GROUP_NAME)} + + + + {DATASOURCES_OPTIONS.map((option) => ( + {}}> + + Datasource + {option.label} + + + ))} + + {canCreateDatasource && ( + onCreateDatasourceClick()}> + + + {createMessage(CREATE_NEW_DATASOURCE)} + + + )} + + + + ); +}; + +export { DatasourceSelector }; diff --git a/app/client/src/PluginActionEditor/components/PluginActionResponse/components/Schema/SchemaTables.tsx b/app/client/src/PluginActionEditor/components/PluginActionResponse/components/Schema/SchemaTables.tsx new file mode 100644 index 000000000000..2b7a3c63615d --- /dev/null +++ b/app/client/src/PluginActionEditor/components/PluginActionResponse/components/Schema/SchemaTables.tsx @@ -0,0 +1,93 @@ +import { Flex, Button } from "@appsmith/ads"; +import { + DatasourceStructureContext, + type DatasourceStructure, +} from "entities/Datasource"; +import { DatasourceStructureContainer as DatasourceStructureList } from "pages/Editor/DatasourceInfo/DatasourceStructureContainer"; +import React, { useCallback } from "react"; +import { DatasourceSelector } from "./DatasourceSelector"; +import { refreshDatasourceStructure } from "actions/datasourceActions"; +import { useDispatch } from "react-redux"; +import styled from "styled-components"; + +interface Props { + datasourceId: string; + datasourceName: string; + currentActionId: string; + datasourceStructure: DatasourceStructure; + setSelectedTable: (table: string) => void; + selectedTable: string | undefined; +} + +const StyledFlex = styled(Flex)` + & .t--entity-item { + height: 28px; + grid-template-columns: 0 auto 1fr auto auto auto auto auto; + + .entity-icon > .ads-v2-icon { + display: none; + } + } +`; + +const SchemaTables = ({ + currentActionId, + datasourceId, + datasourceName, + datasourceStructure, + selectedTable, + setSelectedTable, +}: Props) => { + const dispatch = useDispatch(); + + const refreshStructure = useCallback(() => { + dispatch( + refreshDatasourceStructure( + datasourceId, + DatasourceStructureContext.QUERY_EDITOR, + ), + ); + }, [dispatch, datasourceId]); + + return ( + + + + )} - - {title} - {message} - ); diff --git a/app/client/src/PluginActionEditor/components/PluginActionResponse/components/Schema/TableColumns.tsx b/app/client/src/PluginActionEditor/components/PluginActionResponse/components/Schema/TableColumns.tsx new file mode 100644 index 000000000000..9ea22e21f941 --- /dev/null +++ b/app/client/src/PluginActionEditor/components/PluginActionResponse/components/Schema/TableColumns.tsx @@ -0,0 +1,69 @@ +import React from "react"; +import { Flex } from "@appsmith/ads"; +import { find } from "lodash"; + +import type { + DatasourceColumns, + DatasourceKeys, + DatasourceStructure, +} from "entities/Datasource"; +import { StatusDisplay } from "./StatusDisplay"; +import DatasourceField from "pages/Editor/DatasourceInfo/DatasourceField"; + +interface Props { + isLoading: boolean; + datasourceStructure: DatasourceStructure; + selectedTable: string | undefined; +} + +const TableColumns = ({ + datasourceStructure, + isLoading, + selectedTable, +}: Props) => { + const columns = + find(datasourceStructure?.tables, ["name", selectedTable])?.columns || []; + + const selectedTableItems = find(datasourceStructure?.tables, [ + "name", + selectedTable, + ]); + + const columnsAndKeys: Array = []; + + if (selectedTableItems) { + columnsAndKeys.push(...selectedTableItems.keys); + columnsAndKeys.push(...selectedTableItems.columns); + } + + return ( + + {isLoading ? : null} + {!isLoading && columns.length === 0 ? ( + + ) : null} + {!isLoading && + columnsAndKeys.map((field, index) => { + return ( + + ); + })} + + ); +}; + +export { TableColumns }; diff --git a/app/client/src/PluginActionEditor/components/PluginActionResponse/components/Schema/index.tsx b/app/client/src/PluginActionEditor/components/PluginActionResponse/components/Schema/index.tsx index d4ea109a244f..b45dbd9f307c 100644 --- a/app/client/src/PluginActionEditor/components/PluginActionResponse/components/Schema/index.tsx +++ b/app/client/src/PluginActionEditor/components/PluginActionResponse/components/Schema/index.tsx @@ -1,34 +1,28 @@ import { Flex } from "@appsmith/ads"; import React, { useEffect, useState } from "react"; -import { - DatasourceStructureContext, - type DatasourceColumns, - type DatasourceKeys, -} from "entities/Datasource"; -// import { DatasourceStructureContainer as DatasourceStructureList } from "pages/Editor/DatasourceInfo/DatasourceStructureContainer"; +import { DatasourceStructureContext } from "entities/Datasource"; import { useDispatch, useSelector } from "react-redux"; import { getDatasourceStructureById, getIsFetchingDatasourceStructure, - // getPluginImages, getPluginIdFromDatasourceId, getPluginDatasourceComponentFromId, } from "ee/selectors/entitiesSelector"; -// import DatasourceField from "pages/Editor/DatasourceInfo/DatasourceField"; -import { find } from "lodash"; import type { AppState } from "ee/reducers"; -import RenderInterimDataState from "pages/Editor/DatasourceInfo/RenderInterimDataState"; -import { - fetchDatasourceStructure, - // refreshDatasourceStructure, -} from "actions/datasourceActions"; -// import history from "utils/history"; -// import { datasourcesEditorIdURL } from "ee/RouteBuilder"; -// import { EntityIcon } from "pages/Editor/Explorer/ExplorerIcons"; -// import { getAssetUrl } from "ee/utils/airgapHelpers"; +import { fetchDatasourceStructure } from "actions/datasourceActions"; +import history from "utils/history"; +import { datasourcesEditorIdURL } from "ee/RouteBuilder"; import { DatasourceComponentTypes } from "api/PluginApi"; import { getPluginActionDebuggerState } from "PluginActionEditor/store"; import { StatusDisplay } from "./StatusDisplay"; +import { DatasourceSelector } from "./DatasourceSelector"; +import { SchemaTables } from "./SchemaTables"; +import { DatasourceEditEntryPoints } from "constants/Datasource"; +import AnalyticsUtil from "ee/utils/AnalyticsUtil"; +import { omit } from "lodash"; +import { getQueryParams } from "utils/URLUtils"; +import { getCurrentPageId } from "selectors/editorSelectors"; +import { TableColumns } from "./TableColumns"; interface Props { datasourceId: string; @@ -42,30 +36,16 @@ const Schema = (props: Props) => { const datasourceStructure = useSelector((state) => getDatasourceStructureById(state, props.datasourceId), ); + const { responseTabHeight } = useSelector(getPluginActionDebuggerState); const pluginId = useSelector((state) => getPluginIdFromDatasourceId(state, props.datasourceId), ); - // const pluginImages = useSelector((state) => getPluginImages(state)); - // const datasourceIcon = pluginId ? pluginImages[pluginId] : undefined; - - const [selectedTable, setSelectedTable] = useState(); - const selectedTableItems = find(datasourceStructure?.tables, [ - "name", - selectedTable, - ]); + const currentPageId = useSelector(getCurrentPageId); - const columnsAndKeys: Array = []; - - if (selectedTableItems) { - columnsAndKeys.push(...selectedTableItems.keys); - columnsAndKeys.push(...selectedTableItems.columns); - } - - // const columns = - // find(datasourceStructure?.tables, ["name", selectedTable])?.columns || []; + const [selectedTable, setSelectedTable] = useState(); const isLoading = useSelector((state: AppState) => getIsFetchingDatasourceStructure(state, props.datasourceId), @@ -115,117 +95,89 @@ const Schema = (props: Props) => { [selectedTable, props.datasourceId, isLoading, datasourceStructure], ); - // const refreshStructure = useCallback(() => { - // dispatch( - // refreshDatasourceStructure( - // props.datasourceId, - // DatasourceStructureContext.QUERY_EDITOR, - // ), - // ); - // }, [dispatch, props.datasourceId]); + // eslint-disable-next-line react-perf/jsx-no-new-function-as-prop + const editDatasource = () => { + const entryPoint = DatasourceEditEntryPoints.QUERY_EDITOR_DATASOURCE_SCHEMA; + + AnalyticsUtil.logEvent("EDIT_DATASOURCE_CLICK", { + datasourceId: props.datasourceId, + pluginName: "", + entryPoint: entryPoint, + }); + + const url = datasourcesEditorIdURL({ + basePageId: currentPageId, + datasourceId: props.datasourceId, + params: { ...omit(getQueryParams(), "viewMode"), viewMode: false }, + generateEditorPath: true, + }); + + history.push(url); + }; + + const getStatusState = () => { + if (isLoading) return "SCHEMA_LOADING"; + + if (!datasourceStructure) return "NOSCHEMA"; + + if (datasourceStructure && "error" in datasourceStructure) return "FAILED"; + + return null; + }; + + const statusState = getStatusState(); - // const goToDatasource = useCallback(() => { - // history.push(datasourcesEditorIdURL({ datasourceId: props.datasourceId })); - // }, [props.datasourceId]); + const renderStatus = () => { + if (!statusState) { + return null; + } - if (!datasourceStructure) { return ( - - {isLoading ? ( - - ) : ( - - )} - + <> + + + + + ); - } + }; const renderContent = () => { - // if (isLoading) { + if (statusState) { + return null; + } + return ( - + + + + ); - // } }; return ( + {renderStatus()} {renderContent()} - {/* - - - - - entityIcon - - {props.datasourceName} - - - - - - - - {createMessage(DATASOURCE_SWITCHER_MENU_GROUP_NAME)} - - - - {DATASOURCES_OPTIONS.map((option) => ( - handleMenuSelect(option.value)} - > - - Datasource - {option.label} - - - ))} - - {canCreateDatasource && ( - - onCreateDatasourceClick( - INTEGRATION_TABS.NEW, - currentActionConfig?.pageId, - ) - } - > - - - {createMessage(CREATE_NEW_DATASOURCE)} - - - )} - - + + + ); }; -export { DatasourceSelector }; +export default reduxForm({ + form: QUERY_EDITOR_FORM_NAME, // Unique form name +})(DatasourceSelector); diff --git a/app/client/src/PluginActionEditor/components/PluginActionResponse/components/Schema/SchemaTables.tsx b/app/client/src/PluginActionEditor/components/PluginActionResponse/components/Schema/SchemaTables.tsx index 2b7a3c63615d..2c371540fd9c 100644 --- a/app/client/src/PluginActionEditor/components/PluginActionResponse/components/Schema/SchemaTables.tsx +++ b/app/client/src/PluginActionEditor/components/PluginActionResponse/components/Schema/SchemaTables.tsx @@ -5,7 +5,7 @@ import { } from "entities/Datasource"; import { DatasourceStructureContainer as DatasourceStructureList } from "pages/Editor/DatasourceInfo/DatasourceStructureContainer"; import React, { useCallback } from "react"; -import { DatasourceSelector } from "./DatasourceSelector"; +import DatasourceSelector from "./DatasourceSelector"; import { refreshDatasourceStructure } from "actions/datasourceActions"; import { useDispatch } from "react-redux"; import styled from "styled-components"; diff --git a/app/client/src/PluginActionEditor/components/PluginActionResponse/components/Schema/index.tsx b/app/client/src/PluginActionEditor/components/PluginActionResponse/components/Schema/index.tsx index d4fb31078a48..d0fe7f55d777 100644 --- a/app/client/src/PluginActionEditor/components/PluginActionResponse/components/Schema/index.tsx +++ b/app/client/src/PluginActionEditor/components/PluginActionResponse/components/Schema/index.tsx @@ -15,7 +15,7 @@ import { datasourcesEditorIdURL } from "ee/RouteBuilder"; import { DatasourceComponentTypes } from "api/PluginApi"; import { getPluginActionDebuggerState } from "PluginActionEditor/store"; import { StatusDisplay } from "./StatusDisplay"; -import { DatasourceSelector } from "./DatasourceSelector"; +import DatasourceSelector from "./DatasourceSelector"; import { SchemaTables } from "./SchemaTables"; import { DatasourceEditEntryPoints } from "constants/Datasource"; import AnalyticsUtil from "ee/utils/AnalyticsUtil"; diff --git a/app/client/src/components/editorComponents/form/fields/MenuField.tsx b/app/client/src/components/editorComponents/form/fields/MenuField.tsx new file mode 100644 index 000000000000..96ad94156bdb --- /dev/null +++ b/app/client/src/components/editorComponents/form/fields/MenuField.tsx @@ -0,0 +1,87 @@ +import { + Button, + Menu, + MenuContent, + MenuGroupName, + MenuTrigger, + Text, + MenuGroup, + MenuItem, + Flex, + Icon, +} from "@appsmith/ads"; +import { getAssetUrl } from "ee/utils/airgapHelpers"; +import React from "react"; +import { type WrappedFieldProps, type BaseFieldProps, Field } from "redux-form"; + +interface iOption { + value: string; + label: string; + icon?: string; + image?: string; + onSelect?: (value: string) => void; +} + +interface iMenuFieldProps { + options: iOption[]; + children: React.ReactNode; + className?: string; + groupName?: string; +} + +const MenuFieldRender = (props: iMenuFieldProps & WrappedFieldProps) => { + const { children, groupName, input, options } = props; + + const handleMenuSelect = (option: iOption) => { + if (option.onSelect) { + option.onSelect(option.value); // Trigger custom onSelect + } else { + input.onChange(option.value); // Default behavior + } + }; + + return ( + + + + + + {groupName && ( + + {groupName} + + )} + + {options.map((option) => ( + handleMenuSelect(option)} + > + + {option.image && ( + Datasource + )} + {option.icon && } + {option.label} + + + ))} + + + + ); +}; + +const MenuField = ( + props: BaseFieldProps & iMenuFieldProps & { formName: string }, +) => ( + +); + +export default MenuField; From ee41a3a283b240734348af840bb36442b61102ef Mon Sep 17 00:00:00 2001 From: albinAppsmith <87797149+albinAppsmith@users.noreply.github.com> Date: Tue, 19 Nov 2024 18:10:06 +0530 Subject: [PATCH 12/17] fix: reduc form destroy false added for unmount --- .../components/Schema/DatasourceSelector.tsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/client/src/PluginActionEditor/components/PluginActionResponse/components/Schema/DatasourceSelector.tsx b/app/client/src/PluginActionEditor/components/PluginActionResponse/components/Schema/DatasourceSelector.tsx index 9a5548151c2e..0fb571d32069 100644 --- a/app/client/src/PluginActionEditor/components/PluginActionResponse/components/Schema/DatasourceSelector.tsx +++ b/app/client/src/PluginActionEditor/components/PluginActionResponse/components/Schema/DatasourceSelector.tsx @@ -133,5 +133,7 @@ const DatasourceSelector = ({ datasourceId, datasourceName }: Props) => { }; export default reduxForm({ - form: QUERY_EDITOR_FORM_NAME, // Unique form name + form: QUERY_EDITOR_FORM_NAME, + destroyOnUnmount: false, + enableReinitialize: true, })(DatasourceSelector); From 6b53a5e5f015d2c5195753410db44ca00eac9f53 Mon Sep 17 00:00:00 2001 From: albinAppsmith <87797149+albinAppsmith@users.noreply.github.com> Date: Wed, 20 Nov 2024 17:03:53 +0530 Subject: [PATCH 13/17] feat: search added for columns in schema --- .../components/Schema/TableColumns.tsx | 170 +++++++++++++----- app/client/src/ce/constants/messages.ts | 3 + app/client/src/entities/Datasource/index.ts | 1 + .../Editor/DatasourceInfo/DatasourceField.tsx | 30 +++- 4 files changed, 153 insertions(+), 51 deletions(-) diff --git a/app/client/src/PluginActionEditor/components/PluginActionResponse/components/Schema/TableColumns.tsx b/app/client/src/PluginActionEditor/components/PluginActionResponse/components/Schema/TableColumns.tsx index 9ea22e21f941..3bab53455ea1 100644 --- a/app/client/src/PluginActionEditor/components/PluginActionResponse/components/Schema/TableColumns.tsx +++ b/app/client/src/PluginActionEditor/components/PluginActionResponse/components/Schema/TableColumns.tsx @@ -1,14 +1,17 @@ -import React from "react"; -import { Flex } from "@appsmith/ads"; +import React, { useCallback, useEffect, useMemo, useState } from "react"; +import { Flex, type FlexProps, SearchInput, Text } from "@appsmith/ads"; import { find } from "lodash"; -import type { - DatasourceColumns, - DatasourceKeys, - DatasourceStructure, -} from "entities/Datasource"; +import type { DatasourceStructure } from "entities/Datasource"; import { StatusDisplay } from "./StatusDisplay"; import DatasourceField from "pages/Editor/DatasourceInfo/DatasourceField"; +import { + COLUMNS_SEARCH_PLACEHOLDER, + COLUMNS_TITLE, + createMessage, +} from "ee/constants/messages"; +import styled from "styled-components"; +import Fuse from "fuse.js"; interface Props { isLoading: boolean; @@ -16,54 +19,135 @@ interface Props { selectedTable: string | undefined; } -const TableColumns = ({ - datasourceStructure, - isLoading, - selectedTable, -}: Props) => { - const columns = - find(datasourceStructure?.tables, ["name", selectedTable])?.columns || []; - - const selectedTableItems = find(datasourceStructure?.tables, [ - "name", - selectedTable, - ]); +const FieldContainer = styled(Flex)` + & .t--datasource-column { + padding: 0; - const columnsAndKeys: Array = []; - - if (selectedTableItems) { - columnsAndKeys.push(...selectedTableItems.keys); - columnsAndKeys.push(...selectedTableItems.columns); + & > div { + margin: 0; + } } +`; +const Wrapper: React.FC = (props) => { return ( - {isLoading ? : null} - {!isLoading && columns.length === 0 ? ( - - ) : null} - {!isLoading && - columnsAndKeys.map((field, index) => { - return ( - - ); - })} + {props.children} ); }; +const TableColumns: React.FC = ({ + datasourceStructure, + isLoading, + selectedTable, +}) => { + // Find selected table items + const selectedTableItems = useMemo( + () => + find(datasourceStructure?.tables, { name: selectedTable }) ?? { + columns: [], + keys: [], + }, + [datasourceStructure, selectedTable], + ); + + // Combine columns and keys + const columns = useMemo(() => { + return selectedTableItems.columns.map((column) => ({ + name: column.name, + type: column.type, + keys: selectedTableItems.keys + .filter( + (key) => + key.columnNames?.includes(column.name) || + key.fromColumns?.includes(column.name), + ) + .map((key) => key.type), + })); + }, [selectedTableItems]); + + // search + const columnsFuzy = useMemo( + () => + new Fuse(columns, { + keys: ["name"], + shouldSort: true, + threshold: 0.5, + location: 0, + }), + [columns], + ); + + const [term, setTerm] = useState(""); + const filteredColumns = useMemo( + () => (term ? columnsFuzy.search(term) : columns), + [term, columns, columnsFuzy], + ); + + const handleSearch = useCallback((value: string) => setTerm(value), []); + + // Reset term whenever selectedTable changes + useEffect( + function clearTerm() { + setTerm(""); + }, + [selectedTable], + ); + + // loading status + if (isLoading) { + return ( + + + + ); + } + + // no columns status + if (columns.length === 0) { + return ( + + + + ); + } + + return ( + + + {createMessage(COLUMNS_TITLE)} + + + + + + {filteredColumns.map((field, index) => ( + + ))} + + + ); +}; + export { TableColumns }; diff --git a/app/client/src/ce/constants/messages.ts b/app/client/src/ce/constants/messages.ts index 3535c956a331..994b49aefefd 100644 --- a/app/client/src/ce/constants/messages.ts +++ b/app/client/src/ce/constants/messages.ts @@ -2285,6 +2285,9 @@ export const FAILED_RECORDS_MESSAGE_TEXT = () => export const DATASOURCE_SWITCHER_MENU_GROUP_NAME = () => "Select a datasource"; export const CANT_SHOW_SCHEMA = () => "We can’t show the schema for this datasource"; +export const COLUMNS_TITLE = () => "Columns"; +export const COLUMNS_SEARCH_PLACEHOLDER = (tableName: string) => + `Search columns in ${tableName}`; export const DATA_PANE_TITLE = () => "Datasources in your workspace"; export const DATASOURCE_LIST_BLANK_DESCRIPTION = () => diff --git a/app/client/src/entities/Datasource/index.ts b/app/client/src/entities/Datasource/index.ts index 9a0c30c352a4..2bb69a96b9d5 100644 --- a/app/client/src/entities/Datasource/index.ts +++ b/app/client/src/entities/Datasource/index.ts @@ -66,6 +66,7 @@ export interface DatasourceKeys { name: string; type: string; columnNames: string[]; + fromColumns: string[]; } export interface DatasourceStructure { diff --git a/app/client/src/pages/Editor/DatasourceInfo/DatasourceField.tsx b/app/client/src/pages/Editor/DatasourceInfo/DatasourceField.tsx index 26df6c1d9868..1897cd216622 100644 --- a/app/client/src/pages/Editor/DatasourceInfo/DatasourceField.tsx +++ b/app/client/src/pages/Editor/DatasourceInfo/DatasourceField.tsx @@ -1,7 +1,6 @@ import React, { useRef } from "react"; import { DATASOURCE_FIELD_ICONS_MAP } from "../Explorer/ExplorerIcons"; import styled from "styled-components"; -import type { DatasourceColumns, DatasourceKeys } from "entities/Datasource"; import { Tooltip, Tag, Flex } from "@appsmith/ads"; import { isEllipsisActive } from "utils/helpers"; @@ -39,8 +38,20 @@ const Content = styled.div` gap: var(--ads-v2-spaces-2); `; +const FieldKeyLabel = styled.span` + &:first-letter { + text-transform: capitalize; + } +`; + +interface FieldProps { + name: string; + type: string; + keys?: string[]; +} + interface DatabaseFieldProps { - field: DatasourceColumns | DatasourceKeys; + field: FieldProps; step: number; } @@ -48,7 +59,11 @@ export function DatabaseColumns(props: DatabaseFieldProps) { const field = props.field; const fieldName = field.name; const fieldType = field.type; - const icon = DATASOURCE_FIELD_ICONS_MAP[fieldType]; + const fieldKeys = field.keys; + const icon = + fieldKeys && fieldKeys.length > 0 + ? DATASOURCE_FIELD_ICONS_MAP[fieldKeys[0]] + : null; const nameRef = useRef(null); return ( @@ -62,15 +77,14 @@ export function DatabaseColumns(props: DatabaseFieldProps) { > {fieldName} - {icon ? ( + {fieldType} + {icon && fieldKeys && ( - + {icon} - {fieldType} + {fieldKeys[0]} - ) : ( - {fieldType} )} From a73195567780003fd4376e20f1d8f4d8538a09cf Mon Sep 17 00:00:00 2001 From: albinAppsmith <87797149+albinAppsmith@users.noreply.github.com> Date: Wed, 20 Nov 2024 23:48:21 +0530 Subject: [PATCH 14/17] fix: Paddings and copy changes --- app/client/cypress/support/Pages/DataSources.ts | 2 +- app/client/src/IDE/Components/BottomView.tsx | 1 + .../PluginActionResponse/components/Schema/SchemaTables.tsx | 1 + .../PluginActionResponse/components/Schema/index.tsx | 2 +- app/client/src/ce/constants/messages.ts | 2 +- .../src/pages/Editor/DatasourceInfo/DatasourceField.tsx | 4 +++- 6 files changed, 8 insertions(+), 4 deletions(-) diff --git a/app/client/cypress/support/Pages/DataSources.ts b/app/client/cypress/support/Pages/DataSources.ts index 36b2940f3c61..003193e2e9a8 100644 --- a/app/client/cypress/support/Pages/DataSources.ts +++ b/app/client/cypress/support/Pages/DataSources.ts @@ -265,7 +265,7 @@ export class DataSources { "')]/ancestor::div[@class='form-config-top']/following-sibling::div//div[contains(@class, 'rc-select-multiple')]"; private _datasourceSchemaRefreshBtn = ".datasourceStructure-refresh"; private _datasourceStructureHeader = ".datasourceStructure-header"; - _datasourceSchemaColumn = ".t--datasource-column"; + _datasourceSchemaColumn = ".t--datasource-column .t--field-name"; _datasourceStructureSearchInput = ".datasourceStructure-search input"; _jsModeSortingControl = ".t--actionConfiguration\\.formData\\.sortBy\\.data"; public _queryEditorCollapsibleIcon = ".collapsible-icon"; diff --git a/app/client/src/IDE/Components/BottomView.tsx b/app/client/src/IDE/Components/BottomView.tsx index 1c8b8f870190..7ed23f18beee 100644 --- a/app/client/src/IDE/Components/BottomView.tsx +++ b/app/client/src/IDE/Components/BottomView.tsx @@ -38,6 +38,7 @@ const ViewWrapper = styled.div` & { .ads-v2-tabs__list { padding: var(--ads-v2-spaces-1) var(--ads-v2-spaces-7); + padding-left: var(--ads-v2-spaces-3); } } diff --git a/app/client/src/PluginActionEditor/components/PluginActionResponse/components/Schema/SchemaTables.tsx b/app/client/src/PluginActionEditor/components/PluginActionResponse/components/Schema/SchemaTables.tsx index 2c371540fd9c..f012919103d6 100644 --- a/app/client/src/PluginActionEditor/components/PluginActionResponse/components/Schema/SchemaTables.tsx +++ b/app/client/src/PluginActionEditor/components/PluginActionResponse/components/Schema/SchemaTables.tsx @@ -56,6 +56,7 @@ const SchemaTables = ({ gap="spaces-3" overflow="hidden" padding="spaces-3" + paddingBottom="spaces-0" w="400px" > { {renderStatus()} diff --git a/app/client/src/ce/constants/messages.ts b/app/client/src/ce/constants/messages.ts index 994b49aefefd..d3dc228d3f1a 100644 --- a/app/client/src/ce/constants/messages.ts +++ b/app/client/src/ce/constants/messages.ts @@ -804,7 +804,7 @@ export const SCHEMA_NOT_AVAILABLE = () => "We can't show schema for this datasource"; export const TABLE_NOT_FOUND = () => "Table not found."; export const DATASOURCE_STRUCTURE_INPUT_PLACEHOLDER_TEXT = (name: string) => - `Tables in ${name}`; + `Search tables in ${name}`; export const SCHEMA_LABEL = () => "Schema"; export const STRUCTURE_NOT_FETCHED = () => "We could not fetch the schema of the database."; diff --git a/app/client/src/pages/Editor/DatasourceInfo/DatasourceField.tsx b/app/client/src/pages/Editor/DatasourceInfo/DatasourceField.tsx index 1897cd216622..98355cf2bfb7 100644 --- a/app/client/src/pages/Editor/DatasourceInfo/DatasourceField.tsx +++ b/app/client/src/pages/Editor/DatasourceInfo/DatasourceField.tsx @@ -75,7 +75,9 @@ export function DatabaseColumns(props: DatabaseFieldProps) { mouseEnterDelay={2} showArrow={false} > - {fieldName} + + {fieldName} + {fieldType} {icon && fieldKeys && ( From 21f86a4b12adc4a64f1bc3bd91d70e4c29c6d5b0 Mon Sep 17 00:00:00 2001 From: albinAppsmith <87797149+albinAppsmith@users.noreply.github.com> Date: Thu, 21 Nov 2024 23:45:31 +0530 Subject: [PATCH 15/17] fix: schema cypress fix --- .../e2e/Regression/ClientSide/BugTests/DatasourceSchema_spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/client/cypress/e2e/Regression/ClientSide/BugTests/DatasourceSchema_spec.ts b/app/client/cypress/e2e/Regression/ClientSide/BugTests/DatasourceSchema_spec.ts index 9608ee564cbd..0ed9a482eb3a 100644 --- a/app/client/cypress/e2e/Regression/ClientSide/BugTests/DatasourceSchema_spec.ts +++ b/app/client/cypress/e2e/Regression/ClientSide/BugTests/DatasourceSchema_spec.ts @@ -79,7 +79,7 @@ describe( "public.users", ); dataSources.SelectTableFromPreviewSchemaList("public.users"); - dataSources.VerifyColumnSchemaOnQueryEditor("id", 1); + dataSources.VerifyColumnSchemaOnQueryEditor("id", 0); }, ); From 52240c5a1e232960676474a3b600a5d638f05fcf Mon Sep 17 00:00:00 2001 From: albinAppsmith <87797149+albinAppsmith@users.noreply.github.com> Date: Mon, 25 Nov 2024 11:52:43 +0530 Subject: [PATCH 16/17] fix: updated code as per code review --- .../components/Schema/CurrentDataSource.tsx | 24 +-- .../Schema/CurrentDataSourceLink.tsx | 30 +++ .../components/Schema/DatasourceSelector.tsx | 11 +- .../components/Schema/Schema.tsx | 197 ++++++++++++++++++ .../components/Schema/SchemaTables.tsx | 17 +- .../components/Schema/StatusDisplay.tsx | 27 +-- .../components/Schema/TableColumns.tsx | 22 +- .../components/Schema/constants.tsx | 2 + .../components/Schema/index.tsx | 196 +---------------- .../components/Schema/styles.ts | 23 ++ .../hooks/usePluginActionResponseTabs.tsx | 2 +- ...ceNavigation.ts => useCreateDatasource.ts} | 17 +- .../hooks/useGoToDatasource.ts | 15 ++ .../hooks/useCreateDatasource.ts | 1 + .../hooks/useDataSourceNavigation.ts | 1 - .../hooks/useGoToDatasource.ts | 1 + .../DatasourceStructureNotFound.tsx | 7 +- .../Editor/QueryEditor/QueryDebuggerTabs.tsx | 2 +- 18 files changed, 313 insertions(+), 282 deletions(-) create mode 100644 app/client/src/PluginActionEditor/components/PluginActionResponse/components/Schema/CurrentDataSourceLink.tsx create mode 100644 app/client/src/PluginActionEditor/components/PluginActionResponse/components/Schema/Schema.tsx create mode 100644 app/client/src/PluginActionEditor/components/PluginActionResponse/components/Schema/constants.tsx create mode 100644 app/client/src/PluginActionEditor/components/PluginActionResponse/components/Schema/styles.ts rename app/client/src/ce/PluginActionEditor/hooks/{useDataSourceNavigation.ts => useCreateDatasource.ts} (60%) create mode 100644 app/client/src/ce/PluginActionEditor/hooks/useGoToDatasource.ts create mode 100644 app/client/src/ee/PluginActionEditor/hooks/useCreateDatasource.ts delete mode 100644 app/client/src/ee/PluginActionEditor/hooks/useDataSourceNavigation.ts create mode 100644 app/client/src/ee/PluginActionEditor/hooks/useGoToDatasource.ts diff --git a/app/client/src/PluginActionEditor/components/PluginActionResponse/components/Schema/CurrentDataSource.tsx b/app/client/src/PluginActionEditor/components/PluginActionResponse/components/Schema/CurrentDataSource.tsx index 38cf2f0d59f1..e2ed7ece141d 100644 --- a/app/client/src/PluginActionEditor/components/PluginActionResponse/components/Schema/CurrentDataSource.tsx +++ b/app/client/src/PluginActionEditor/components/PluginActionResponse/components/Schema/CurrentDataSource.tsx @@ -1,5 +1,5 @@ import React from "react"; -import { Flex, Link } from "@appsmith/ads"; +import { Flex } from "@appsmith/ads"; import { getAssetUrl } from "ee/utils/airgapHelpers"; import { EntityIcon } from "pages/Editor/Explorer/ExplorerIcons"; import { useSelector } from "react-redux"; @@ -7,42 +7,28 @@ import { getPluginIdFromDatasourceId, getPluginImages, } from "ee/selectors/entitiesSelector"; -import { useDataSourceNavigation } from "ee/PluginActionEditor/hooks/useDataSourceNavigation"; -interface iProps { - type: "link" | "trigger"; +interface Props { datasourceId: string; datasourceName: string; } -const CurrentDataSource = ({ datasourceId, datasourceName, type }: iProps) => { +const CurrentDataSource = ({ datasourceId, datasourceName }: Props) => { const { pluginId, pluginImages } = useSelector((state) => ({ pluginId: getPluginIdFromDatasourceId(state, datasourceId), pluginImages: getPluginImages(state), })); - const { goToDatasource } = useDataSourceNavigation(); - const datasourceIcon = pluginId ? pluginImages?.[pluginId] : undefined; - const content = ( - + return ( + entityIcon {datasourceName} ); - - return type === "link" ? ( - goToDatasource(datasourceId)}>{content} - ) : ( - content - ); }; export { CurrentDataSource }; diff --git a/app/client/src/PluginActionEditor/components/PluginActionResponse/components/Schema/CurrentDataSourceLink.tsx b/app/client/src/PluginActionEditor/components/PluginActionResponse/components/Schema/CurrentDataSourceLink.tsx new file mode 100644 index 000000000000..83cce22fa9aa --- /dev/null +++ b/app/client/src/PluginActionEditor/components/PluginActionResponse/components/Schema/CurrentDataSourceLink.tsx @@ -0,0 +1,30 @@ +import React, { useCallback } from "react"; +import { Link } from "@appsmith/ads"; +import { CurrentDataSource } from "./CurrentDataSource"; +import { useGoToDatasource } from "ee/PluginActionEditor/hooks/useGoToDatasource"; + +const CurrentDataSourceLink = ({ + datasourceId, + datasourceName, +}: { + datasourceId: string; + datasourceName: string; +}) => { + const { goToDatasource } = useGoToDatasource(); + + const handleClick = useCallback( + () => goToDatasource(datasourceId), + [datasourceId, goToDatasource], + ); + + return ( + + + + ); +}; + +export { CurrentDataSourceLink }; diff --git a/app/client/src/PluginActionEditor/components/PluginActionResponse/components/Schema/DatasourceSelector.tsx b/app/client/src/PluginActionEditor/components/PluginActionResponse/components/Schema/DatasourceSelector.tsx index 0fb571d32069..75e2c0cd81bf 100644 --- a/app/client/src/PluginActionEditor/components/PluginActionResponse/components/Schema/DatasourceSelector.tsx +++ b/app/client/src/PluginActionEditor/components/PluginActionResponse/components/Schema/DatasourceSelector.tsx @@ -18,15 +18,16 @@ import { import type { Datasource } from "entities/Datasource"; import type { AppState } from "ee/reducers"; import { getCurrentAppWorkspace } from "ee/selectors/selectedWorkspaceSelectors"; -import { CurrentDataSource } from "./CurrentDataSource"; import { useActiveActionBaseId } from "ee/pages/Editor/Explorer/hooks"; import { INTEGRATION_TABS } from "constants/routes"; import { QUERY_EDITOR_FORM_NAME } from "ee/constants/forms"; -import { useDataSourceNavigation } from "ee/PluginActionEditor/hooks/useDataSourceNavigation"; import MenuField from "components/editorComponents/form/fields/MenuField"; import type { InjectedFormProps } from "redux-form"; import { reduxForm } from "redux-form"; import type { Action } from "entities/Action"; +import { CurrentDataSourceLink } from "./CurrentDataSourceLink"; +import { CurrentDataSource } from "./CurrentDataSource"; +import { useCreateDatasource } from "ee/PluginActionEditor/hooks/useCreateDatasource"; interface CustomProps { datasourceId: string; @@ -73,7 +74,7 @@ const DatasourceSelector = ({ datasourceId, datasourceName }: Props) => { const showDatasourceSelector = doesPluginRequireDatasource(plugin); const pluginImages = useSelector(getPluginImages); - const { onCreateDatasourceClick } = useDataSourceNavigation(); + const { onCreateDatasourceClick } = useCreateDatasource(); const DATASOURCES_OPTIONS: Array = dataSources.reduce( @@ -106,10 +107,9 @@ const DatasourceSelector = ({ datasourceId, datasourceName }: Props) => { if (!showDatasourceSelector || !isChangePermitted) { return ( - ); } @@ -125,7 +125,6 @@ const DatasourceSelector = ({ datasourceId, datasourceName }: Props) => { diff --git a/app/client/src/PluginActionEditor/components/PluginActionResponse/components/Schema/Schema.tsx b/app/client/src/PluginActionEditor/components/PluginActionResponse/components/Schema/Schema.tsx new file mode 100644 index 000000000000..eb293dc12bad --- /dev/null +++ b/app/client/src/PluginActionEditor/components/PluginActionResponse/components/Schema/Schema.tsx @@ -0,0 +1,197 @@ +import { Flex } from "@appsmith/ads"; +import React, { useEffect, useState } from "react"; +import { DatasourceStructureContext } from "entities/Datasource"; +import { useDispatch, useSelector } from "react-redux"; +import { + getDatasourceStructureById, + getIsFetchingDatasourceStructure, + getPluginIdFromDatasourceId, + getPluginDatasourceComponentFromId, +} from "ee/selectors/entitiesSelector"; +import type { AppState } from "ee/reducers"; +import { fetchDatasourceStructure } from "actions/datasourceActions"; +import history from "utils/history"; +import { datasourcesEditorIdURL } from "ee/RouteBuilder"; +import { DatasourceComponentTypes } from "api/PluginApi"; +import { getPluginActionDebuggerState } from "PluginActionEditor/store"; +import { SchemaDisplayStatus, StatusDisplay } from "./StatusDisplay"; +import DatasourceSelector from "./DatasourceSelector"; +import { SchemaTables } from "./SchemaTables"; +import { DatasourceEditEntryPoints } from "constants/Datasource"; +import AnalyticsUtil from "ee/utils/AnalyticsUtil"; +import { isEmpty, omit } from "lodash"; +import { getQueryParams } from "utils/URLUtils"; +import { getCurrentPageId } from "selectors/editorSelectors"; +import { TableColumns } from "./TableColumns"; +import { BOTTOMBAR_HEIGHT } from "./constants"; + +interface Props { + datasourceId: string; + datasourceName: string; + currentActionId: string; +} + +const Schema = (props: Props) => { + const dispatch = useDispatch(); + + const datasourceStructure = useSelector((state) => + getDatasourceStructureById(state, props.datasourceId), + ); + + const { responseTabHeight } = useSelector(getPluginActionDebuggerState); + + const pluginId = useSelector((state) => + getPluginIdFromDatasourceId(state, props.datasourceId), + ); + + const currentPageId = useSelector(getCurrentPageId); + + const [selectedTable, setSelectedTable] = useState(); + + const isLoading = useSelector((state: AppState) => + getIsFetchingDatasourceStructure(state, props.datasourceId), + ); + + const pluginDatasourceForm = useSelector((state) => + getPluginDatasourceComponentFromId(state, pluginId || ""), + ); + + useEffect( + function resetSelectedTable() { + setSelectedTable(undefined); + }, + [props.datasourceId], + ); + + useEffect( + function fetchDatasourceStructureEffect() { + function fetchStructure() { + if ( + props.datasourceId && + datasourceStructure === undefined && + pluginDatasourceForm !== + DatasourceComponentTypes.RestAPIDatasourceForm + ) { + dispatch( + fetchDatasourceStructure( + props.datasourceId, + true, + DatasourceStructureContext.QUERY_EDITOR, + ), + ); + } + } + + fetchStructure(); + }, + [props.datasourceId, datasourceStructure, dispatch, pluginDatasourceForm], + ); + + useEffect( + function selectFirstTable() { + if (!selectedTable && datasourceStructure?.tables?.length && !isLoading) { + setSelectedTable(datasourceStructure.tables[0].name); + } + }, + [selectedTable, props.datasourceId, isLoading, datasourceStructure], + ); + + // eslint-disable-next-line react-perf/jsx-no-new-function-as-prop + const editDatasource = () => { + const entryPoint = DatasourceEditEntryPoints.QUERY_EDITOR_DATASOURCE_SCHEMA; + + AnalyticsUtil.logEvent("EDIT_DATASOURCE_CLICK", { + datasourceId: props.datasourceId, + pluginName: "", + entryPoint: entryPoint, + }); + + const url = datasourcesEditorIdURL({ + basePageId: currentPageId, + datasourceId: props.datasourceId, + params: { ...omit(getQueryParams(), "viewMode"), viewMode: false }, + generateEditorPath: true, + }); + + history.push(url); + }; + + const getStatusState = () => { + if (isLoading) return SchemaDisplayStatus.SCHEMA_LOADING; + + if (!datasourceStructure) return SchemaDisplayStatus.NOSCHEMA; + + if (datasourceStructure && "error" in datasourceStructure) + return SchemaDisplayStatus.FAILED; + + if (isEmpty(datasourceStructure)) return SchemaDisplayStatus.CANTSHOW; + + return null; + }; + + const statusState = getStatusState(); + + const renderStatus = () => { + if (!statusState) { + return null; + } + + return ( + <> + + + + + + ); + }; + + const renderContent = () => { + if (statusState) { + return null; + } + + return ( + + + + + ); + }; + + return ( + + {renderStatus()} + {renderContent()} + + ); +}; + +export { Schema }; diff --git a/app/client/src/PluginActionEditor/components/PluginActionResponse/components/Schema/SchemaTables.tsx b/app/client/src/PluginActionEditor/components/PluginActionResponse/components/Schema/SchemaTables.tsx index f012919103d6..1ee99e4c959c 100644 --- a/app/client/src/PluginActionEditor/components/PluginActionResponse/components/Schema/SchemaTables.tsx +++ b/app/client/src/PluginActionEditor/components/PluginActionResponse/components/Schema/SchemaTables.tsx @@ -8,7 +8,7 @@ import React, { useCallback } from "react"; import DatasourceSelector from "./DatasourceSelector"; import { refreshDatasourceStructure } from "actions/datasourceActions"; import { useDispatch } from "react-redux"; -import styled from "styled-components"; +import { SchemaTableContainer } from "./styles"; interface Props { datasourceId: string; @@ -19,17 +19,6 @@ interface Props { selectedTable: string | undefined; } -const StyledFlex = styled(Flex)` - & .t--entity-item { - height: 28px; - grid-template-columns: 0 auto 1fr auto auto auto auto auto; - - .entity-icon > .ads-v2-icon { - display: none; - } - } -`; - const SchemaTables = ({ currentActionId, datasourceId, @@ -50,7 +39,7 @@ const SchemaTables = ({ }, [dispatch, datasourceId]); return ( - - + ); }; diff --git a/app/client/src/PluginActionEditor/components/PluginActionResponse/components/Schema/StatusDisplay.tsx b/app/client/src/PluginActionEditor/components/PluginActionResponse/components/Schema/StatusDisplay.tsx index c66b2e3cf364..6f7dc87fb22f 100644 --- a/app/client/src/PluginActionEditor/components/PluginActionResponse/components/Schema/StatusDisplay.tsx +++ b/app/client/src/PluginActionEditor/components/PluginActionResponse/components/Schema/StatusDisplay.tsx @@ -20,23 +20,24 @@ import { import { getAssetUrl } from "ee/utils/airgapHelpers"; import { ASSETS_CDN_URL } from "constants/ThirdPartyConstants"; -type IStates = - | "SCHEMA_LOADING" - | "LOADING" - | "NOSCHEMA" - | "NODATA" - | "FAILED" - | "NOCOLUMNS" - | "CANTSHOW"; +enum SchemaDisplayStatus { + SCHEMA_LOADING = "SCHEMA_LOADING", + LOADING = "LOADING", + NOSCHEMA = "NOSCHEMA", + NODATA = "NODATA", + FAILED = "FAILED", + NOCOLUMNS = "NOCOLUMNS", + CANTSHOW = "CANTSHOW", +} -interface IProps { - state: IStates; +interface Props { + state: SchemaDisplayStatus; editDatasource?: () => void; errorMessage?: string; } const StateData: Record< - IStates, + SchemaDisplayStatus, { title?: string; message?: string; image: string | ReactNode } > = { SCHEMA_LOADING: { @@ -75,7 +76,7 @@ const StateData: Record< }, }; -const StatusDisplay = ({ editDatasource, errorMessage, state }: IProps) => { +const StatusDisplay = ({ editDatasource, errorMessage, state }: Props) => { const { image, message, title } = StateData[state]; return ( @@ -122,4 +123,4 @@ const StatusDisplay = ({ editDatasource, errorMessage, state }: IProps) => { ); }; -export { StatusDisplay }; +export { StatusDisplay, SchemaDisplayStatus }; diff --git a/app/client/src/PluginActionEditor/components/PluginActionResponse/components/Schema/TableColumns.tsx b/app/client/src/PluginActionEditor/components/PluginActionResponse/components/Schema/TableColumns.tsx index 3bab53455ea1..9acc816d3173 100644 --- a/app/client/src/PluginActionEditor/components/PluginActionResponse/components/Schema/TableColumns.tsx +++ b/app/client/src/PluginActionEditor/components/PluginActionResponse/components/Schema/TableColumns.tsx @@ -3,15 +3,15 @@ import { Flex, type FlexProps, SearchInput, Text } from "@appsmith/ads"; import { find } from "lodash"; import type { DatasourceStructure } from "entities/Datasource"; -import { StatusDisplay } from "./StatusDisplay"; +import { StatusDisplay, SchemaDisplayStatus } from "./StatusDisplay"; import DatasourceField from "pages/Editor/DatasourceInfo/DatasourceField"; import { COLUMNS_SEARCH_PLACEHOLDER, COLUMNS_TITLE, createMessage, } from "ee/constants/messages"; -import styled from "styled-components"; import Fuse from "fuse.js"; +import { TableColumn } from "./styles"; interface Props { isLoading: boolean; @@ -19,16 +19,6 @@ interface Props { selectedTable: string | undefined; } -const FieldContainer = styled(Flex)` - & .t--datasource-column { - padding: 0; - - & > div { - margin: 0; - } - } -`; - const Wrapper: React.FC = (props) => { return ( = ({ if (isLoading) { return ( - + ); } @@ -116,7 +106,7 @@ const TableColumns: React.FC = ({ if (columns.length === 0) { return ( - + ); } @@ -137,7 +127,7 @@ const TableColumns: React.FC = ({ value={term} /> - + {filteredColumns.map((field, index) => ( = ({ step={0} /> ))} - + ); }; diff --git a/app/client/src/PluginActionEditor/components/PluginActionResponse/components/Schema/constants.tsx b/app/client/src/PluginActionEditor/components/PluginActionResponse/components/Schema/constants.tsx new file mode 100644 index 000000000000..15cad6174cd6 --- /dev/null +++ b/app/client/src/PluginActionEditor/components/PluginActionResponse/components/Schema/constants.tsx @@ -0,0 +1,2 @@ +// This is bottom bar height + paddings +export const BOTTOMBAR_HEIGHT = 42; diff --git a/app/client/src/PluginActionEditor/components/PluginActionResponse/components/Schema/index.tsx b/app/client/src/PluginActionEditor/components/PluginActionResponse/components/Schema/index.tsx index 806e0c450fce..5501a546df7f 100644 --- a/app/client/src/PluginActionEditor/components/PluginActionResponse/components/Schema/index.tsx +++ b/app/client/src/PluginActionEditor/components/PluginActionResponse/components/Schema/index.tsx @@ -1,195 +1 @@ -import { Flex } from "@appsmith/ads"; -import React, { useEffect, useState } from "react"; -import { DatasourceStructureContext } from "entities/Datasource"; -import { useDispatch, useSelector } from "react-redux"; -import { - getDatasourceStructureById, - getIsFetchingDatasourceStructure, - getPluginIdFromDatasourceId, - getPluginDatasourceComponentFromId, -} from "ee/selectors/entitiesSelector"; -import type { AppState } from "ee/reducers"; -import { fetchDatasourceStructure } from "actions/datasourceActions"; -import history from "utils/history"; -import { datasourcesEditorIdURL } from "ee/RouteBuilder"; -import { DatasourceComponentTypes } from "api/PluginApi"; -import { getPluginActionDebuggerState } from "PluginActionEditor/store"; -import { StatusDisplay } from "./StatusDisplay"; -import DatasourceSelector from "./DatasourceSelector"; -import { SchemaTables } from "./SchemaTables"; -import { DatasourceEditEntryPoints } from "constants/Datasource"; -import AnalyticsUtil from "ee/utils/AnalyticsUtil"; -import { isEmpty, omit } from "lodash"; -import { getQueryParams } from "utils/URLUtils"; -import { getCurrentPageId } from "selectors/editorSelectors"; -import { TableColumns } from "./TableColumns"; - -interface Props { - datasourceId: string; - datasourceName: string; - currentActionId: string; -} - -const Schema = (props: Props) => { - const dispatch = useDispatch(); - - const datasourceStructure = useSelector((state) => - getDatasourceStructureById(state, props.datasourceId), - ); - - const { responseTabHeight } = useSelector(getPluginActionDebuggerState); - - const pluginId = useSelector((state) => - getPluginIdFromDatasourceId(state, props.datasourceId), - ); - - const currentPageId = useSelector(getCurrentPageId); - - const [selectedTable, setSelectedTable] = useState(); - - const isLoading = useSelector((state: AppState) => - getIsFetchingDatasourceStructure(state, props.datasourceId), - ); - - const pluginDatasourceForm = useSelector((state) => - getPluginDatasourceComponentFromId(state, pluginId || ""), - ); - - useEffect( - function resetSelectedTable() { - setSelectedTable(undefined); - }, - [props.datasourceId], - ); - - useEffect( - function fetchDatasourceStructureEffect() { - function fetchStructure() { - if ( - props.datasourceId && - datasourceStructure === undefined && - pluginDatasourceForm !== - DatasourceComponentTypes.RestAPIDatasourceForm - ) { - dispatch( - fetchDatasourceStructure( - props.datasourceId, - true, - DatasourceStructureContext.QUERY_EDITOR, - ), - ); - } - } - - fetchStructure(); - }, - [props.datasourceId, datasourceStructure, dispatch, pluginDatasourceForm], - ); - - useEffect( - function selectFirstTable() { - if (!selectedTable && datasourceStructure?.tables?.length && !isLoading) { - setSelectedTable(datasourceStructure.tables[0].name); - } - }, - [selectedTable, props.datasourceId, isLoading, datasourceStructure], - ); - - // eslint-disable-next-line react-perf/jsx-no-new-function-as-prop - const editDatasource = () => { - const entryPoint = DatasourceEditEntryPoints.QUERY_EDITOR_DATASOURCE_SCHEMA; - - AnalyticsUtil.logEvent("EDIT_DATASOURCE_CLICK", { - datasourceId: props.datasourceId, - pluginName: "", - entryPoint: entryPoint, - }); - - const url = datasourcesEditorIdURL({ - basePageId: currentPageId, - datasourceId: props.datasourceId, - params: { ...omit(getQueryParams(), "viewMode"), viewMode: false }, - generateEditorPath: true, - }); - - history.push(url); - }; - - const getStatusState = () => { - if (isLoading) return "SCHEMA_LOADING"; - - if (!datasourceStructure) return "NOSCHEMA"; - - if (datasourceStructure && "error" in datasourceStructure) return "FAILED"; - - if (isEmpty(datasourceStructure)) return "CANTSHOW"; - - return null; - }; - - const statusState = getStatusState(); - - const renderStatus = () => { - if (!statusState) { - return null; - } - - return ( - <> - - - - - - ); - }; - - const renderContent = () => { - if (statusState) { - return null; - } - - return ( - - - - - ); - }; - - return ( - - {renderStatus()} - {renderContent()} - - ); -}; - -export default Schema; +export * from "./Schema"; diff --git a/app/client/src/PluginActionEditor/components/PluginActionResponse/components/Schema/styles.ts b/app/client/src/PluginActionEditor/components/PluginActionResponse/components/Schema/styles.ts new file mode 100644 index 000000000000..991b30c25e8d --- /dev/null +++ b/app/client/src/PluginActionEditor/components/PluginActionResponse/components/Schema/styles.ts @@ -0,0 +1,23 @@ +import styled from "styled-components"; +import { Flex } from "@appsmith/ads"; + +export const TableColumn = styled(Flex)` + & .t--datasource-column { + padding: 0; + + & > div { + margin: 0; + } + } +`; + +export const SchemaTableContainer = styled(Flex)` + & .t--entity-item { + height: 28px; + grid-template-columns: 0 auto 1fr auto auto auto auto auto; + + .entity-icon > .ads-v2-icon { + display: none; + } + } +`; diff --git a/app/client/src/ce/PluginActionEditor/components/PluginActionResponse/hooks/usePluginActionResponseTabs.tsx b/app/client/src/ce/PluginActionEditor/components/PluginActionResponse/hooks/usePluginActionResponseTabs.tsx index 0b44436bf908..35a87e5341a1 100644 --- a/app/client/src/ce/PluginActionEditor/components/PluginActionResponse/hooks/usePluginActionResponseTabs.tsx +++ b/app/client/src/ce/PluginActionEditor/components/PluginActionResponse/hooks/usePluginActionResponseTabs.tsx @@ -25,7 +25,7 @@ import { } from "PluginActionEditor/store"; import { doesPluginRequireDatasource } from "ee/entities/Engine/actionHelpers"; import useShowSchema from "PluginActionEditor/components/PluginActionResponse/hooks/useShowSchema"; -import Schema from "PluginActionEditor/components/PluginActionResponse/components/Schema"; +import { Schema } from "PluginActionEditor/components/PluginActionResponse/components/Schema"; import QueryResponseTab from "PluginActionEditor/components/PluginActionResponse/components/QueryResponseTab"; import type { SourceEntity } from "entities/AppsmithConsole"; import { ENTITY_TYPE as SOURCE_ENTITY_TYPE } from "ee/entities/AppsmithConsole/utils"; diff --git a/app/client/src/ce/PluginActionEditor/hooks/useDataSourceNavigation.ts b/app/client/src/ce/PluginActionEditor/hooks/useCreateDatasource.ts similarity index 60% rename from app/client/src/ce/PluginActionEditor/hooks/useDataSourceNavigation.ts rename to app/client/src/ce/PluginActionEditor/hooks/useCreateDatasource.ts index cd6b67dd0c17..7ee726376222 100644 --- a/app/client/src/ce/PluginActionEditor/hooks/useDataSourceNavigation.ts +++ b/app/client/src/ce/PluginActionEditor/hooks/useCreateDatasource.ts @@ -1,17 +1,10 @@ import { useCallback } from "react"; - -import { datasourcesEditorIdURL, integrationEditorURL } from "ee/RouteBuilder"; +import { integrationEditorURL } from "ee/RouteBuilder"; import AnalyticsUtil from "ee/utils/AnalyticsUtil"; -import history from "utils/history"; import { DatasourceCreateEntryPoints } from "constants/Datasource"; +import history from "utils/history"; -function useDataSourceNavigation() { - const goToDatasource = useCallback((datasourceId: string) => { - history.push( - datasourcesEditorIdURL({ datasourceId, generateEditorPath: true }), - ); - }, []); - +function useCreateDatasource() { const onCreateDatasourceClick = useCallback( (selectedTab, pageId?: string) => { history.push( @@ -28,7 +21,7 @@ function useDataSourceNavigation() { [], ); - return { goToDatasource, onCreateDatasourceClick }; + return { onCreateDatasourceClick }; } -export { useDataSourceNavigation }; +export { useCreateDatasource }; diff --git a/app/client/src/ce/PluginActionEditor/hooks/useGoToDatasource.ts b/app/client/src/ce/PluginActionEditor/hooks/useGoToDatasource.ts new file mode 100644 index 000000000000..f28ef61c23e0 --- /dev/null +++ b/app/client/src/ce/PluginActionEditor/hooks/useGoToDatasource.ts @@ -0,0 +1,15 @@ +import { useCallback } from "react"; +import { datasourcesEditorIdURL } from "ee/RouteBuilder"; +import history from "utils/history"; + +function useGoToDatasource() { + const goToDatasource = useCallback((datasourceId: string) => { + history.push( + datasourcesEditorIdURL({ datasourceId, generateEditorPath: true }), + ); + }, []); + + return { goToDatasource }; +} + +export { useGoToDatasource }; diff --git a/app/client/src/ee/PluginActionEditor/hooks/useCreateDatasource.ts b/app/client/src/ee/PluginActionEditor/hooks/useCreateDatasource.ts new file mode 100644 index 000000000000..8f932b705461 --- /dev/null +++ b/app/client/src/ee/PluginActionEditor/hooks/useCreateDatasource.ts @@ -0,0 +1 @@ +export * from "ce/PluginActionEditor/hooks/useCreateDatasource"; diff --git a/app/client/src/ee/PluginActionEditor/hooks/useDataSourceNavigation.ts b/app/client/src/ee/PluginActionEditor/hooks/useDataSourceNavigation.ts deleted file mode 100644 index e41fd669749a..000000000000 --- a/app/client/src/ee/PluginActionEditor/hooks/useDataSourceNavigation.ts +++ /dev/null @@ -1 +0,0 @@ -export * from "ce/PluginActionEditor/hooks/useDataSourceNavigation"; diff --git a/app/client/src/ee/PluginActionEditor/hooks/useGoToDatasource.ts b/app/client/src/ee/PluginActionEditor/hooks/useGoToDatasource.ts new file mode 100644 index 000000000000..097b72da418e --- /dev/null +++ b/app/client/src/ee/PluginActionEditor/hooks/useGoToDatasource.ts @@ -0,0 +1 @@ +export * from "ce/PluginActionEditor/hooks/useGoToDatasource"; diff --git a/app/client/src/pages/Editor/DatasourceInfo/DatasourceStructureNotFound.tsx b/app/client/src/pages/Editor/DatasourceInfo/DatasourceStructureNotFound.tsx index 91a6bb1cd3ab..e7225a364e22 100644 --- a/app/client/src/pages/Editor/DatasourceInfo/DatasourceStructureNotFound.tsx +++ b/app/client/src/pages/Editor/DatasourceInfo/DatasourceStructureNotFound.tsx @@ -1,4 +1,4 @@ -import React from "react"; +import React, { useCallback } from "react"; import { useSelector } from "react-redux"; import styled from "styled-components"; import { Text, Button } from "@appsmith/ads"; @@ -42,8 +42,7 @@ const DatasourceStructureNotFound = (props: Props) => { const basePageId = useSelector(getCurrentBasePageId); - // eslint-disable-next-line react-perf/jsx-no-new-function-as-prop - const editDatasource = () => { + const editDatasource = useCallback(() => { let entryPoint = DatasourceEditEntryPoints.QUERY_EDITOR_DATASOURCE_SCHEMA; if (props.context === DatasourceStructureContext.DATASOURCE_VIEW_MODE) { @@ -70,7 +69,7 @@ const DatasourceStructureNotFound = (props: Props) => { }); history.push(url); - }; + }, [basePageId, datasourceId, pluginName, props]); return ( diff --git a/app/client/src/pages/Editor/QueryEditor/QueryDebuggerTabs.tsx b/app/client/src/pages/Editor/QueryEditor/QueryDebuggerTabs.tsx index 9dd4c29ead0a..1f72399d5c82 100644 --- a/app/client/src/pages/Editor/QueryEditor/QueryDebuggerTabs.tsx +++ b/app/client/src/pages/Editor/QueryEditor/QueryDebuggerTabs.tsx @@ -14,7 +14,7 @@ import { } from "ee/constants/messages"; import DebuggerLogs from "components/editorComponents/Debugger/DebuggerLogs"; import ErrorLogs from "components/editorComponents/Debugger/Errors"; -import Schema from "PluginActionEditor/components/PluginActionResponse/components/Schema"; +import { Schema } from "PluginActionEditor/components/PluginActionResponse/components/Schema"; import type { ActionResponse } from "api/ActionAPI"; import { isString } from "lodash"; import type { SourceEntity } from "entities/AppsmithConsole"; From c38fc9948554344a45c172fe291f49a0a5cd9b61 Mon Sep 17 00:00:00 2001 From: albinAppsmith <87797149+albinAppsmith@users.noreply.github.com> Date: Tue, 26 Nov 2024 07:15:25 +0530 Subject: [PATCH 17/17] fix: Moved useGoToDatasource to non CE folder --- .../components/Schema/CurrentDataSourceLink.tsx | 2 +- .../components/PluginActionResponse}/hooks/useGoToDatasource.ts | 0 app/client/src/ee/PluginActionEditor/hooks/useGoToDatasource.ts | 1 - 3 files changed, 1 insertion(+), 2 deletions(-) rename app/client/src/{ce/PluginActionEditor => PluginActionEditor/components/PluginActionResponse}/hooks/useGoToDatasource.ts (100%) delete mode 100644 app/client/src/ee/PluginActionEditor/hooks/useGoToDatasource.ts diff --git a/app/client/src/PluginActionEditor/components/PluginActionResponse/components/Schema/CurrentDataSourceLink.tsx b/app/client/src/PluginActionEditor/components/PluginActionResponse/components/Schema/CurrentDataSourceLink.tsx index 83cce22fa9aa..8ba3acdf1e1c 100644 --- a/app/client/src/PluginActionEditor/components/PluginActionResponse/components/Schema/CurrentDataSourceLink.tsx +++ b/app/client/src/PluginActionEditor/components/PluginActionResponse/components/Schema/CurrentDataSourceLink.tsx @@ -1,7 +1,7 @@ import React, { useCallback } from "react"; import { Link } from "@appsmith/ads"; import { CurrentDataSource } from "./CurrentDataSource"; -import { useGoToDatasource } from "ee/PluginActionEditor/hooks/useGoToDatasource"; +import { useGoToDatasource } from "PluginActionEditor/components/PluginActionResponse/hooks/useGoToDatasource"; const CurrentDataSourceLink = ({ datasourceId, diff --git a/app/client/src/ce/PluginActionEditor/hooks/useGoToDatasource.ts b/app/client/src/PluginActionEditor/components/PluginActionResponse/hooks/useGoToDatasource.ts similarity index 100% rename from app/client/src/ce/PluginActionEditor/hooks/useGoToDatasource.ts rename to app/client/src/PluginActionEditor/components/PluginActionResponse/hooks/useGoToDatasource.ts diff --git a/app/client/src/ee/PluginActionEditor/hooks/useGoToDatasource.ts b/app/client/src/ee/PluginActionEditor/hooks/useGoToDatasource.ts deleted file mode 100644 index 097b72da418e..000000000000 --- a/app/client/src/ee/PluginActionEditor/hooks/useGoToDatasource.ts +++ /dev/null @@ -1 +0,0 @@ -export * from "ce/PluginActionEditor/hooks/useGoToDatasource";