From c6b09defe90369f53bfb083030b46928c98ad3eb Mon Sep 17 00:00:00 2001 From: albinAppsmith <87797149+albinAppsmith@users.noreply.github.com> Date: Thu, 7 Mar 2024 17:56:58 +0530 Subject: [PATCH] feat: Changed add button to toggle button in left pane (#31523) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Description Changes add button in left pane to toggle button. #### PR fixes following issue(s) Fixes https://github.com/appsmithorg/appsmith/issues/31522 #### Media > A video or a GIF is preferred. when using Loom, don’t embed because it looks like it’s a GIF. instead, just link to the video > > #### Type of change - Bug fix (non-breaking change which fixes an issue) - New feature (non-breaking change which adds functionality) ## Testing > #### How Has This Been Tested? > Please describe the tests that you ran to verify your changes. Also list any relevant details for your test configuration. > Delete anything that is not relevant - [ ] Manual - [ ] JUnit - [ ] Jest - [ ] Cypress > > #### Test Plan > Add Testsmith test cases links that relate to this PR > > #### Issues raised during DP testing > Link issues raised during DP testing for better visiblity and tracking (copy link from comments dropped on this PR) > > > ## Checklist: #### Dev activity - [x] My code follows the style guidelines of this project - [x] I have performed a self-review of my own code - [ ] I have commented my code, particularly in hard-to-understand areas - [ ] I have made corresponding changes to the documentation - [x] My changes generate no new warnings - [ ] I have added tests that prove my fix is effective or that my feature works - [x] New and existing unit tests pass locally with my changes - [ ] PR is being merged under a feature flag #### QA activity: - [ ] [Speedbreak features](https://github.com/appsmithorg/TestSmith/wiki/Guidelines-for-test-plans#speedbreakers-) have been covered - [ ] Test plan covers all impacted features and [areas of interest](https://github.com/appsmithorg/TestSmith/wiki/Guidelines-for-test-plans#areas-of-interest-) - [ ] Test plan has been peer reviewed by project stakeholders and other QA members - [ ] Manually tested functionality on DP - [ ] We had an implementation alignment call with stakeholders post QA Round 2 - [ ] Cypress test cases have been added and approved by SDET/manual QA - [ ] Added `Test Plan Approved` label after Cypress tests were reviewed - [ ] Added `Test Plan Approved` label after JUnit tests were reviewed ## Summary by CodeRabbit - **New Features** - Improved entity identification in navigation based on URL path and query parameters. - **Refactor** - Updated the editor tabs to use `ToggleButton` for enhanced user interaction. - **Bug Fixes** - Modified logic in hooks for creating a new JS collection to handle segment mode appropriately. - Adjusted URL generation logic in the `useQueryAdd` hook for better functionality. - Enhanced conditions in the `identifyEntityFromPath` function to identify entities based on URL path endings and query ID values. - **Tests** - Updated test setup for the `JS Segment` component to include specific `pathname` for `useLocation` mocking. --- .../pages/Editor/IDE/EditorPane/JS/hooks.ts | 17 +++++-- .../Editor/IDE/EditorPane/Query/hooks.ts | 18 +++++-- .../__tests__/JS/JSSegment.test.tsx | 8 ++++ app/client/src/navigation/FocusEntity.ts | 48 +++++++++++++------ .../Editor/IDE/EditorTabs/SplitScreenTabs.tsx | 11 ++--- 5 files changed, 76 insertions(+), 26 deletions(-) diff --git a/app/client/src/ce/pages/Editor/IDE/EditorPane/JS/hooks.ts b/app/client/src/ce/pages/Editor/IDE/EditorPane/JS/hooks.ts index 6e5aa8288e..3aa9889993 100644 --- a/app/client/src/ce/pages/Editor/IDE/EditorPane/JS/hooks.ts +++ b/app/client/src/ce/pages/Editor/IDE/EditorPane/JS/hooks.ts @@ -7,20 +7,31 @@ import { createMessage, EDITOR_PANE_TEXTS } from "@appsmith/constants/messages"; import { JsFileIconV2 } from "pages/Editor/Explorer/ExplorerIcons"; import { SEARCH_ITEM_TYPES } from "components/editorComponents/GlobalSearch/utils"; import type { UseRoutes } from "@appsmith/entities/IDE/constants"; -import { EditorViewMode } from "@appsmith/entities/IDE/constants"; +import { + EditorEntityTabState, + EditorViewMode, +} from "@appsmith/entities/IDE/constants"; import { getIDEViewMode, getIsSideBySideEnabled } from "selectors/ideSelectors"; import JSEditor from "pages/Editor/JSEditor"; import AddJS from "pages/Editor/IDE/EditorPane/JS/Add"; import { ADD_PATH } from "@appsmith/constants/routes/appRoutes"; import ListJS from "pages/Editor/IDE/EditorPane/JS/List"; import { BlankStateContainer } from "pages/Editor/IDE/EditorPane/JS/BlankStateContainer"; +import { useCurrentEditorState } from "pages/Editor/IDE/hooks"; export const useJSAdd = () => { const pageId = useSelector(getCurrentPageId); const dispatch = useDispatch(); + const { segmentMode } = useCurrentEditorState(); + return useCallback(() => { - dispatch(createNewJSCollection(pageId, "ENTITY_EXPLORER")); - }, [dispatch, pageId]); + if (segmentMode === EditorEntityTabState.Add) { + // since js don't have a add mode in CE + return; + } else { + dispatch(createNewJSCollection(pageId, "ENTITY_EXPLORER")); + } + }, [dispatch, pageId, segmentMode]); }; export const useGroupedAddJsOperations = (): GroupedAddOperations => { diff --git a/app/client/src/ce/pages/Editor/IDE/EditorPane/Query/hooks.ts b/app/client/src/ce/pages/Editor/IDE/EditorPane/Query/hooks.ts index c57fa80e9c..b3cfd77d36 100644 --- a/app/client/src/ce/pages/Editor/IDE/EditorPane/Query/hooks.ts +++ b/app/client/src/ce/pages/Editor/IDE/EditorPane/Query/hooks.ts @@ -26,7 +26,10 @@ import { import { SAAS_EDITOR_API_ID_PATH } from "pages/Editor/SaaSEditor/constants"; import ApiEditor from "pages/Editor/APIEditor"; import type { UseRoutes } from "@appsmith/entities/IDE/constants"; -import { EditorViewMode } from "@appsmith/entities/IDE/constants"; +import { + EditorEntityTabState, + EditorViewMode, +} from "@appsmith/entities/IDE/constants"; import QueryEditor from "pages/Editor/QueryEditor"; import AddQuery from "pages/Editor/IDE/EditorPane/Query/Add"; import ListQuery from "pages/Editor/IDE/EditorPane/Query/List"; @@ -35,18 +38,27 @@ import keyBy from "lodash/keyBy"; import { getPluginEntityIcon } from "pages/Editor/Explorer/ExplorerIcons"; import type { ListItemProps } from "design-system"; import { BlankStateContainer } from "pages/Editor/IDE/EditorPane/Query/BlankStateContainer"; +import { useCurrentEditorState } from "pages/Editor/IDE/hooks"; export const useQueryAdd = () => { const location = useLocation(); const currentEntityInfo = identifyEntityFromPath(location.pathname); + const { segmentMode } = useCurrentEditorState(); const addButtonClickHandler = useCallback(() => { - const url = getQueryAddUrl(currentEntityInfo); + let url = ""; + if (segmentMode === EditorEntityTabState.Add) { + // Already in add mode, back to the previous active item + url = location.pathname.replace(`${ADD_PATH}`, ""); + } else { + url = getQueryAddUrl(currentEntityInfo); + } history.push(url); - }, [currentEntityInfo.id]); + }, [currentEntityInfo.id, segmentMode]); return addButtonClickHandler; }; +//history.push(location.pathname.replace(`${ADD_PATH}`, "")); export type GroupedAddOperations = Array<{ title?: string; diff --git a/app/client/src/ce/pages/Editor/IDE/EditorPane/__tests__/JS/JSSegment.test.tsx b/app/client/src/ce/pages/Editor/IDE/EditorPane/__tests__/JS/JSSegment.test.tsx index a277f42b23..f3e1e2875d 100644 --- a/app/client/src/ce/pages/Editor/IDE/EditorPane/__tests__/JS/JSSegment.test.tsx +++ b/app/client/src/ce/pages/Editor/IDE/EditorPane/__tests__/JS/JSSegment.test.tsx @@ -15,6 +15,14 @@ function getWrapper(store: Store): React.FC { ); } +// Mock react-router-dom +jest.mock("react-router", () => ({ + ...jest.requireActual("react-router"), + useLocation: jest.fn().mockReturnValue({ + pathname: "/app/untitled-application-1/page1-1/edit/jsObjects", + }), +})); + describe("JS Segment", () => { it("creates JS in the correct page", () => { const store = createStore(rootReducer, { diff --git a/app/client/src/navigation/FocusEntity.ts b/app/client/src/navigation/FocusEntity.ts index 6d21083528..176e091bb9 100644 --- a/app/client/src/navigation/FocusEntity.ts +++ b/app/client/src/navigation/FocusEntity.ts @@ -92,6 +92,24 @@ export function matchEntityFromPath( }); } +const getQueryAddPathObj = (match: match) => { + return { + entity: FocusEntity.QUERY_ADD, + id: "", + appState: EditorState.EDITOR, + params: match.params, + }; +}; + +const getJSAddPathObj = (match: match) => { + return { + entity: FocusEntity.JS_OBJECT_ADD, + id: "", + appState: EditorState.EDITOR, + params: match.params, + }; +}; + export function identifyEntityFromPath(path: string): FocusEntityInfo { const match = matchEntityFromPath(path); if (!match) { @@ -104,6 +122,9 @@ export function identifyEntityFromPath(path: string): FocusEntityInfo { } if (match.params.apiId) { if (match.params.pluginPackageName) { + if (match.url.endsWith(ADD_PATH)) { + return getQueryAddPathObj(match); + } return { entity: FocusEntity.QUERY, id: match.params.apiId, @@ -111,6 +132,9 @@ export function identifyEntityFromPath(path: string): FocusEntityInfo { params: match.params, }; } + if (match.url.endsWith(ADD_PATH)) { + return getQueryAddPathObj(match); + } return { entity: FocusEntity.QUERY, id: match.params.apiId, @@ -152,13 +176,8 @@ export function identifyEntityFromPath(path: string): FocusEntityInfo { }; } if (match.params.queryId) { - if (match.params.queryId == "add") { - return { - entity: FocusEntity.QUERY_ADD, - id: "", - appState: EditorState.EDITOR, - params: match.params, - }; + if (match.params.queryId == "add" || match.url.endsWith(ADD_PATH)) { + return getQueryAddPathObj(match); } return { entity: FocusEntity.QUERY, @@ -169,6 +188,9 @@ export function identifyEntityFromPath(path: string): FocusEntityInfo { } if (match.params.moduleType && match.params.moduleInstanceId) { if (match.params.moduleType === MODULE_TYPE.QUERY) { + if (match.url.endsWith(ADD_PATH)) { + return getQueryAddPathObj(match); + } return { entity: FocusEntity.QUERY_MODULE_INSTANCE, id: match.params.moduleInstanceId, @@ -177,6 +199,9 @@ export function identifyEntityFromPath(path: string): FocusEntityInfo { }; } if (match.params.moduleType === MODULE_TYPE.JS) { + if (match.url.endsWith(ADD_PATH)) { + return getJSAddPathObj(match); + } return { entity: FocusEntity.JS_MODULE_INSTANCE, id: match.params.moduleInstanceId, @@ -186,13 +211,8 @@ export function identifyEntityFromPath(path: string): FocusEntityInfo { } } if (match.params.collectionId) { - if (match.params.collectionId == "add") { - return { - entity: FocusEntity.JS_OBJECT_ADD, - id: "", - appState: EditorState.EDITOR, - params: match.params, - }; + if (match.params.collectionId == "add" || match.url.endsWith(ADD_PATH)) { + return getJSAddPathObj(match); } return { entity: FocusEntity.JS_OBJECT, diff --git a/app/client/src/pages/Editor/IDE/EditorTabs/SplitScreenTabs.tsx b/app/client/src/pages/Editor/IDE/EditorTabs/SplitScreenTabs.tsx index 6bf5f782a2..1418b643e9 100644 --- a/app/client/src/pages/Editor/IDE/EditorTabs/SplitScreenTabs.tsx +++ b/app/client/src/pages/Editor/IDE/EditorTabs/SplitScreenTabs.tsx @@ -1,5 +1,5 @@ import React, { useCallback } from "react"; -import { Button } from "design-system"; +import { ToggleButton } from "design-system"; import FileTabs from "./FileTabs"; import { useSelector } from "react-redux"; @@ -28,7 +28,6 @@ const SplitScreenTabs = () => { const onJSAddClick = useJSAdd(); const onQueryAddClick = useQueryAdd(); const onAddClick = useCallback(() => { - if (segmentMode === EditorEntityTabState.Add) return; if (segment === EditorEntityTab.JS) onJSAddClick(); if (segment === EditorEntityTab.QUERIES) onQueryAddClick(); }, [segment, segmentMode, onQueryAddClick, onJSAddClick]); @@ -56,11 +55,11 @@ const SplitScreenTabs = () => { if (segment === EditorEntityTab.UI) return null; return files.length > 0 ? ( -