From 3960582baa80141073d9fdbea2e8c0a6db761d1f Mon Sep 17 00:00:00 2001 From: Ankita Kinger Date: Fri, 18 Oct 2024 11:18:08 +0530 Subject: [PATCH] chore: Moving action settings from editor form to toolbar (#36894) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Description Moving action settings from editor form to toolbar to follow the new designs under action redesign project. Fixes [#35512](https://github.com/appsmithorg/appsmith/issues/35512) [#34670](https://github.com/appsmithorg/appsmith/issues/34670) [#35535](https://github.com/appsmithorg/appsmith/issues/35535) ## Automation /ok-to-test tags="@tag.Sanity" ### :mag: Cypress test results > [!TIP] > 🟢 🟢 🟢 All cypress tests have passed! 🎉 🎉 🎉 > Workflow run: > Commit: 027e2a33685e50c2cb16e513993fff62b0d62e08 > Cypress dashboard. > Tags: `@tag.Sanity` > Spec: >
Thu, 17 Oct 2024 12:40:29 UTC ## Communication Should the DevRel and Marketing teams inform users about this change? - [ ] Yes - [ ] No ## Summary by CodeRabbit ## Summary by CodeRabbit ## Release Notes - **New Features** - Introduced new components for managing API and query settings in the Plugin Action Settings. - Added functionality to open plugin action settings directly from the toolbar. - Implemented a settings popover interface for improved user interaction. - Added documentation links for QUERY_SETTINGS to enhance user guidance. - **Improvements** - Simplified rendering logic in the Plugin Action Form for better performance. - Updated form naming conventions for consistency across API and GraphQL editors. - Streamlined configuration settings by replacing `subtitle` with `tooltipText` for clarity. - Enhanced styling in Action Settings for better layout and user experience. - **Bug Fixes** - Corrected the navigation logic to open plugin action settings instead of debugger state. These enhancements aim to improve user experience and streamline plugin action management. --- .../ads/src/Popover/Popover.styles.tsx | 2 +- .../PluginActionForm/PluginActionForm.tsx | 8 +- .../ActionForm/Zone/styles.module.css | 4 + .../components/ApiEditor/APIEditorForm.tsx | 11 +- .../GraphQLEditor/GraphQLEditorForm.tsx | 13 +- .../components/QueryResponseTab.tsx | 17 ++- .../PluginActionSettings/ApiSettings.tsx | 10 ++ .../PluginActionSettings/QuerySettings.tsx | 10 ++ .../PluginActionSettings/SettingsPopover.tsx | 142 ++++++++++++++++++ .../components/PluginActionSettings/index.tsx | 30 ++++ .../components/PluginActionToolbar.tsx | 8 +- .../constants/PluginActionConstants.ts | 3 + src/PluginActionEditor/store/constants.ts | 3 + .../store/pluginActionEditorActions.ts | 7 + .../store/pluginActionEditorSelectors.ts | 3 + .../store/pluginEditorReducer.ts | 10 ++ src/ce/constants/ReduxActionConstants.tsx | 1 + src/ce/constants/messages.ts | 2 +- .../CodeEditor/EvaluatedValuePopup.tsx | 2 +- .../PartialExportModal/unitTestUtils.ts | 35 ++--- .../form/fields/StyledFormComponents.tsx | 9 +- .../formConfig/ApiSettingsConfig.ts | 9 +- .../formConfig/GoogleSheetsSettingsConfig.ts | 3 +- .../formConfig/QuerySettingsConfig.ts | 3 +- src/constants/DocumentationLinks.ts | 3 + .../APIEditor/GraphQL/GraphQLEditorForm.tsx | 10 +- src/pages/Editor/APIEditor/RestAPIForm.tsx | 8 +- src/pages/Editor/ActionSettings.tsx | 28 ++-- src/pages/Editor/FormConfig.tsx | 5 +- .../SaaSEditor/__data__/FinalState.json | 55 +++---- .../SaaSEditor/__data__/InitialState.json | 53 +++---- test/factories/MockPluginsState.ts | 33 ++-- 32 files changed, 374 insertions(+), 166 deletions(-) create mode 100644 src/PluginActionEditor/components/PluginActionSettings/ApiSettings.tsx create mode 100644 src/PluginActionEditor/components/PluginActionSettings/QuerySettings.tsx create mode 100644 src/PluginActionEditor/components/PluginActionSettings/SettingsPopover.tsx create mode 100644 src/PluginActionEditor/components/PluginActionSettings/index.tsx create mode 100644 src/PluginActionEditor/constants/PluginActionConstants.ts diff --git a/packages/design-system/ads/src/Popover/Popover.styles.tsx b/packages/design-system/ads/src/Popover/Popover.styles.tsx index 50cb5421ae81..a5a23e329458 100644 --- a/packages/design-system/ads/src/Popover/Popover.styles.tsx +++ b/packages/design-system/ads/src/Popover/Popover.styles.tsx @@ -65,5 +65,5 @@ export const StyledBody = styled.div` max-height: calc( var(--popover-max-height) - calc(var(--popover-padding) * 2 + 25.5px) ); - overflow-y: scroll; + overflow-y: auto; `; diff --git a/src/PluginActionEditor/components/PluginActionForm/PluginActionForm.tsx b/src/PluginActionEditor/components/PluginActionForm/PluginActionForm.tsx index d7ac7a21385a..4a85da9d0ee4 100644 --- a/src/PluginActionEditor/components/PluginActionForm/PluginActionForm.tsx +++ b/src/PluginActionEditor/components/PluginActionForm/PluginActionForm.tsx @@ -19,10 +19,10 @@ const PluginActionForm = () => { {plugin.uiComponent === UIComponentTypes.GraphQLEditorForm && ( )} - {plugin.uiComponent === UIComponentTypes.DbEditorForm || - (plugin.uiComponent === UIComponentTypes.UQIDbEditorForm && ( - - ))} + {(plugin.uiComponent === UIComponentTypes.DbEditorForm || + plugin.uiComponent === UIComponentTypes.UQIDbEditorForm) && ( + + )} ); }; diff --git a/src/PluginActionEditor/components/PluginActionForm/components/ActionForm/Zone/styles.module.css b/src/PluginActionEditor/components/PluginActionForm/components/ActionForm/Zone/styles.module.css index 8268c1cd02a3..b63260f2d7d1 100644 --- a/src/PluginActionEditor/components/PluginActionForm/components/ActionForm/Zone/styles.module.css +++ b/src/PluginActionEditor/components/PluginActionForm/components/ActionForm/Zone/styles.module.css @@ -12,6 +12,10 @@ grid-template-columns: 1fr; } + & > div:empty { + display: none; + } + /* This section can be removed once the condition abouve each is resolved */ diff --git a/src/PluginActionEditor/components/PluginActionForm/components/ApiEditor/APIEditorForm.tsx b/src/PluginActionEditor/components/PluginActionForm/components/ApiEditor/APIEditorForm.tsx index 1546fcef01a0..f76893dc6f9c 100644 --- a/src/PluginActionEditor/components/PluginActionForm/components/ApiEditor/APIEditorForm.tsx +++ b/src/PluginActionEditor/components/PluginActionForm/components/ApiEditor/APIEditorForm.tsx @@ -15,8 +15,6 @@ import { useAnalyticsOnRunClick, } from "PluginActionEditor/hooks"; -const FORM_NAME = API_EDITOR_FORM_NAME; - const APIEditorForm = () => { const { action } = usePluginActionContext(); const { handleRunClick } = useHandleRunClick(); @@ -43,7 +41,7 @@ const APIEditorForm = () => { theme={EditorTheme.LIGHT} /> } - formName={FORM_NAME} + formName={API_EDITOR_FORM_NAME} httpMethodOptions={HTTP_METHOD_OPTIONS} isChangePermitted={isChangePermitted} paginationUiComponent={ @@ -58,6 +56,7 @@ const APIEditorForm = () => { ); }; -export default reduxForm({ form: FORM_NAME, enableReinitialize: true })( - APIEditorForm, -); +export default reduxForm({ + form: API_EDITOR_FORM_NAME, + enableReinitialize: true, +})(APIEditorForm); diff --git a/src/PluginActionEditor/components/PluginActionForm/components/GraphQLEditor/GraphQLEditorForm.tsx b/src/PluginActionEditor/components/PluginActionForm/components/GraphQLEditor/GraphQLEditorForm.tsx index 677bf16e032e..35323cbece55 100644 --- a/src/PluginActionEditor/components/PluginActionForm/components/GraphQLEditor/GraphQLEditorForm.tsx +++ b/src/PluginActionEditor/components/PluginActionForm/components/GraphQLEditor/GraphQLEditorForm.tsx @@ -12,8 +12,6 @@ import { getHasManageActionPermission } from "ee/utils/BusinessFeatures/permissi import { EditorTheme } from "components/editorComponents/CodeEditor/EditorConfig"; import useGetFormActionValues from "../CommonEditorForm/hooks/useGetFormActionValues"; -const FORM_NAME = API_EDITOR_FORM_NAME; - function GraphQLEditorForm() { const { action } = usePluginActionContext(); const theme = EditorTheme.LIGHT; @@ -30,13 +28,13 @@ function GraphQLEditorForm() { } - formName={FORM_NAME} + formName={API_EDITOR_FORM_NAME} httpMethodOptions={GRAPHQL_HTTP_METHOD_OPTIONS} isChangePermitted={isChangePermitted} paginationUiComponent={ { } = props; const dispatch = useDispatch(); + const isActionRedesignEnabled = useFeatureFlag( + FEATURE_FLAG.release_actions_redesign_enabled, + ); + const actionResponse = useSelector((state) => getActionData(state, currentActionConfig.id), ); @@ -211,8 +218,12 @@ const QueryResponseTab = (props: Props) => { } const navigateToSettings = useCallback(() => { - dispatch(setPluginActionEditorSelectedTab(EDITOR_TABS.SETTINGS)); - }, [dispatch]); + if (isActionRedesignEnabled) { + dispatch(openPluginActionSettings(true)); + } else { + dispatch(setPluginActionEditorSelectedTab(EDITOR_TABS.SETTINGS)); + } + }, [dispatch, isActionRedesignEnabled]); const preparedStatementCalloutLinks: CalloutLinkProps[] = [ { diff --git a/src/PluginActionEditor/components/PluginActionSettings/ApiSettings.tsx b/src/PluginActionEditor/components/PluginActionSettings/ApiSettings.tsx new file mode 100644 index 000000000000..37ef02e21153 --- /dev/null +++ b/src/PluginActionEditor/components/PluginActionSettings/ApiSettings.tsx @@ -0,0 +1,10 @@ +import { API_EDITOR_FORM_NAME } from "ee/constants/forms"; +import { reduxForm } from "redux-form"; +import PluginActionSettingsPopover, { + type SettingsProps, +} from "./SettingsPopover"; + +export default reduxForm({ + form: API_EDITOR_FORM_NAME, + enableReinitialize: true, +})(PluginActionSettingsPopover); diff --git a/src/PluginActionEditor/components/PluginActionSettings/QuerySettings.tsx b/src/PluginActionEditor/components/PluginActionSettings/QuerySettings.tsx new file mode 100644 index 000000000000..9f8984afb7df --- /dev/null +++ b/src/PluginActionEditor/components/PluginActionSettings/QuerySettings.tsx @@ -0,0 +1,10 @@ +import { QUERY_EDITOR_FORM_NAME } from "ee/constants/forms"; +import { reduxForm } from "redux-form"; +import PluginActionSettingsPopover, { + type SettingsProps, +} from "./SettingsPopover"; + +export default reduxForm({ + form: QUERY_EDITOR_FORM_NAME, + enableReinitialize: true, +})(PluginActionSettingsPopover); diff --git a/src/PluginActionEditor/components/PluginActionSettings/SettingsPopover.tsx b/src/PluginActionEditor/components/PluginActionSettings/SettingsPopover.tsx new file mode 100644 index 000000000000..ef4045f01913 --- /dev/null +++ b/src/PluginActionEditor/components/PluginActionSettings/SettingsPopover.tsx @@ -0,0 +1,142 @@ +import React, { useCallback, useEffect, useState } from "react"; +import { + Link, + Popover, + PopoverBody, + PopoverContent, + PopoverHeader, + PopoverTrigger, + ToggleButton, +} from "@appsmith/ads"; +import ActionSettings from "pages/Editor/ActionSettings"; +import { usePluginActionContext } from "../../PluginActionContext"; +import styled, { css } from "styled-components"; +import { + API_EDITOR_TAB_TITLES, + createMessage, + LEARN_MORE, +} from "ee/constants/messages"; +import { useDispatch, useSelector } from "react-redux"; +import { + isPluginActionSettingsOpen, + openPluginActionSettings, +} from "../../store"; +import { THEME } from "../../constants/PluginActionConstants"; +import { type DocsLink, openDoc } from "constants/DocumentationLinks"; + +export interface SettingsProps { + formName: string; + docsLink?: DocsLink; +} + +const Variables = css` + --popover-width: 280px; +`; + +/* TODO: Remove this after removing custom width from server side (Ankita) */ +const SettingsWrapper = styled.div` + display: flex; + flex-direction: column; + gap: var(--ads-v2-spaces-4); + + .t--form-control-INPUT_TEXT, + .t--form-control-DROP_DOWN { + > div { + min-width: unset; + width: 100%; + } + } +`; + +const StyledPopoverHeader = styled(PopoverHeader)` + margin-bottom: var(--ads-v2-spaces-5); +`; + +const StyledPopoverContent = styled(PopoverContent)` + ${Variables}; +`; + +const LearnMoreLink = styled(Link)` + span { + font-weight: bold; + } +`; + +const PluginActionSettingsPopover = (props: SettingsProps) => { + const { settingsConfig } = usePluginActionContext(); + const openSettings = useSelector(isPluginActionSettingsOpen); + const [isOpen, setIsOpen] = useState(false); + const dispatch = useDispatch(); + + useEffect(() => { + if (openSettings) { + handleOpenChange(true); + } + }, [openSettings]); + + const handleOpenChange = useCallback( + (open: boolean) => { + setIsOpen(open); + + if (openSettings && !open) { + dispatch(openPluginActionSettings(false)); + } + }, + [openSettings], + ); + + const handleEscapeKeyDown = () => { + handleOpenChange(false); + }; + + const handleButtonClick = () => { + handleOpenChange(true); + }; + + const handleLearnMoreClick = () => { + openDoc(props.docsLink as DocsLink); + }; + + return ( + + + + + + + {createMessage(API_EDITOR_TAB_TITLES.SETTINGS)} + + + + + {props.docsLink && ( + + {createMessage(LEARN_MORE)} + + )} + + + + + ); +}; + +export default PluginActionSettingsPopover; diff --git a/src/PluginActionEditor/components/PluginActionSettings/index.tsx b/src/PluginActionEditor/components/PluginActionSettings/index.tsx new file mode 100644 index 000000000000..7c8a886b7894 --- /dev/null +++ b/src/PluginActionEditor/components/PluginActionSettings/index.tsx @@ -0,0 +1,30 @@ +import React from "react"; +import { UIComponentTypes } from "api/PluginApi"; +import { usePluginActionContext } from "../../PluginActionContext"; +import ApiSettings from "./ApiSettings"; +import QuerySettings from "./QuerySettings"; +import { + API_EDITOR_FORM_NAME, + QUERY_EDITOR_FORM_NAME, +} from "ee/constants/forms"; +import { DocsLink } from "constants/DocumentationLinks"; + +const API_FORM_COMPONENTS = [ + UIComponentTypes.ApiEditorForm, + UIComponentTypes.GraphQLEditorForm, +]; + +const PluginActionSettings = () => { + const { plugin } = usePluginActionContext(); + + return API_FORM_COMPONENTS.includes(plugin.uiComponent) ? ( + + ) : ( + + ); +}; + +export default PluginActionSettings; diff --git a/src/PluginActionEditor/components/PluginActionToolbar.tsx b/src/PluginActionEditor/components/PluginActionToolbar.tsx index c60a751490cc..43f3679e78c8 100644 --- a/src/PluginActionEditor/components/PluginActionToolbar.tsx +++ b/src/PluginActionEditor/components/PluginActionToolbar.tsx @@ -11,6 +11,7 @@ import { import { useToggle } from "@mantine/hooks"; import { useSelector } from "react-redux"; import { isActionRunning } from "../store"; +import PluginActionSettings from "./PluginActionSettings"; interface PluginActionToolbarProps { runOptions?: React.ReactNode; @@ -51,12 +52,7 @@ const PluginActionToolbar = (props: PluginActionToolbarProps) => { Run -