fix: clicking on + in list view does not create a new query (#36467)

## Description
This change adds a new state in ideReducer 'isListViewActive' to verify
the active status of the list view on split screen mode. I am updating
isListViewActive state to false when we click on `+` icon and are
already in QUERY_ADD mode, to close the list view and switch back to the
new query tab.

Fixes https://github.com/appsmithorg/appsmith/issues/36066
_or_  
Fixes `Issue URL`
> [!WARNING]  
> _If no issue exists, please create an issue first, and check with the
maintainers if the issue is valid._

## Automation

/ok-to-test tags=""

### 🔍 Cypress test results
<!-- This is an auto-generated comment: Cypress test results  -->
> [!CAUTION]  
> If you modify the content in this section, you are likely to disrupt
the CI result for your PR.

<!-- end of auto-generated comment: Cypress test results  -->


## Communication
Should the DevRel and Marketing teams inform users about this change?
- [ ] Yes
- [ ] No


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **New Features**
- Introduced a new action to manage the active state of the list view,
enhancing user interface control.
	- Added a selector to retrieve the current state of the list view.

- **Improvements**
- Updated the `useQueryAdd` and `useJSAdd` hooks to respond to the IDE's
view mode, improving functionality when adding queries.
- Shifted state management for the list view from local to global,
ensuring consistent visibility across the application.

- **Bug Fixes**
- Enhanced responsiveness of the list view based on the current
interface state.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
Abhishek Pandey 2024-09-30 16:24:59 +05:30 committed by GitHub
parent dc2ab49963
commit 37c2cf5afb
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 67 additions and 15 deletions

View File

@ -54,3 +54,10 @@ export const recordAnalyticsForSideBySideNavigation = () => ({
export const resetAnalyticsForSideBySideHover = () => ({ export const resetAnalyticsForSideBySideHover = () => ({
type: ReduxActionTypes.RESET_ANALYTICS_FOR_SIDE_BY_SIDE_HOVER, type: ReduxActionTypes.RESET_ANALYTICS_FOR_SIDE_BY_SIDE_HOVER,
}); });
export const setListViewActiveState = (payload: boolean) => {
return {
type: ReduxActionTypes.SET_IS_LIST_VIEW_ACTIVE,
payload,
};
};

View File

@ -496,6 +496,7 @@ const IDEActionTypes = {
CLOSE_JS_ACTION_TAB_SUCCESS: "CLOSE_JS_ACTION_TAB_SUCCESS", CLOSE_JS_ACTION_TAB_SUCCESS: "CLOSE_JS_ACTION_TAB_SUCCESS",
CLOSE_QUERY_ACTION_TAB: "CLOSE_QUERY_ACTION_TAB", CLOSE_QUERY_ACTION_TAB: "CLOSE_QUERY_ACTION_TAB",
CLOSE_QUERY_ACTION_TAB_SUCCESS: "CLOSE_QUERY_ACTION_TAB_SUCCESS", CLOSE_QUERY_ACTION_TAB_SUCCESS: "CLOSE_QUERY_ACTION_TAB_SUCCESS",
SET_IS_LIST_VIEW_ACTIVE: "SET_IS_LIST_VIEW_ACTIVE",
}; };
const IDEActionErrorTypes = { const IDEActionErrorTypes = {

View File

@ -15,6 +15,9 @@ import { FocusEntity, identifyEntityFromPath } from "navigation/FocusEntity";
import { useModuleOptions } from "ee/utils/moduleInstanceHelpers"; import { useModuleOptions } from "ee/utils/moduleInstanceHelpers";
import { getJSUrl } from "ee/pages/Editor/IDE/EditorPane/JS/utils"; import { getJSUrl } from "ee/pages/Editor/IDE/EditorPane/JS/utils";
import { JSBlankState } from "pages/Editor/JSEditor/JSBlankState"; import { JSBlankState } from "pages/Editor/JSEditor/JSBlankState";
import { getIDEViewMode } from "selectors/ideSelectors";
import { EditorViewMode } from "ee/entities/IDE/constants";
import { setListViewActiveState } from "actions/ideActions";
export const useJSAdd = () => { export const useJSAdd = () => {
const pageId = useSelector(getCurrentPageId); const pageId = useSelector(getCurrentPageId);
@ -24,12 +27,17 @@ export const useJSAdd = () => {
const jsModuleCreationOptions = moduleCreationOptions.filter( const jsModuleCreationOptions = moduleCreationOptions.filter(
(opt) => opt.focusEntityType === FocusEntity.JS_MODULE_INSTANCE, (opt) => opt.focusEntityType === FocusEntity.JS_MODULE_INSTANCE,
); );
const ideViewMode = useSelector(getIDEViewMode);
const openAddJS = useCallback(() => { const openAddJS = useCallback(() => {
if (jsModuleCreationOptions.length === 0) { if (jsModuleCreationOptions.length === 0) {
dispatch(createNewJSCollection(pageId, "ENTITY_EXPLORER")); dispatch(createNewJSCollection(pageId, "ENTITY_EXPLORER"));
} else { } else {
if (currentEntityInfo.entity === FocusEntity.JS_OBJECT_ADD) { if (currentEntityInfo.entity === FocusEntity.JS_OBJECT_ADD) {
if (ideViewMode === EditorViewMode.SplitScreen) {
dispatch(setListViewActiveState(false));
}
return; return;
} }
@ -37,7 +45,13 @@ export const useJSAdd = () => {
history.push(url); history.push(url);
} }
}, [jsModuleCreationOptions, pageId, dispatch, currentEntityInfo]); }, [
jsModuleCreationOptions,
pageId,
dispatch,
currentEntityInfo,
ideViewMode,
]);
const closeAddJS = useCallback(() => { const closeAddJS = useCallback(() => {
const url = getJSUrl(currentEntityInfo, false); const url = getJSUrl(currentEntityInfo, false);

View File

@ -33,13 +33,22 @@ import { getPluginEntityIcon } from "pages/Editor/Explorer/ExplorerIcons";
import type { ListItemProps } from "@appsmith/ads"; import type { ListItemProps } from "@appsmith/ads";
import { createAddClassName } from "pages/Editor/IDE/EditorPane/utils"; import { createAddClassName } from "pages/Editor/IDE/EditorPane/utils";
import { QueriesBlankState } from "pages/Editor/QueryEditor/QueriesBlankState"; import { QueriesBlankState } from "pages/Editor/QueryEditor/QueriesBlankState";
import { getIDEViewMode } from "selectors/ideSelectors";
import { EditorViewMode } from "ee/entities/IDE/constants";
import { setListViewActiveState } from "actions/ideActions";
export const useQueryAdd = () => { export const useQueryAdd = () => {
const location = useLocation(); const location = useLocation();
const dispatch = useDispatch();
const currentEntityInfo = identifyEntityFromPath(location.pathname); const currentEntityInfo = identifyEntityFromPath(location.pathname);
const ideViewMode = useSelector(getIDEViewMode);
const openAddQuery = useCallback(() => { const openAddQuery = useCallback(() => {
if (currentEntityInfo.entity === FocusEntity.QUERY_ADD) { if (currentEntityInfo.entity === FocusEntity.QUERY_ADD) {
if (ideViewMode === EditorViewMode.SplitScreen) {
dispatch(setListViewActiveState(false));
}
return; return;
} }
@ -54,7 +63,7 @@ export const useQueryAdd = () => {
url = getQueryUrl(currentEntityInfo, false); url = getQueryUrl(currentEntityInfo, false);
history.push(url); history.push(url);
}, [currentEntityInfo]); }, [currentEntityInfo, ideViewMode]);
return { openAddQuery, closeAddQuery }; return { openAddQuery, closeAddQuery };
}; };

View File

@ -1,7 +1,11 @@
import React, { useEffect, useState } from "react"; import React, { useEffect } from "react";
import { shallowEqual, useSelector } from "react-redux"; import { shallowEqual, useDispatch, useSelector } from "react-redux";
import { Flex, ScrollArea, ToggleButton } from "@appsmith/ads"; import { Flex, ScrollArea, ToggleButton } from "@appsmith/ads";
import { getIDEViewMode, getIsSideBySideEnabled } from "selectors/ideSelectors"; import {
getIDEViewMode,
getIsSideBySideEnabled,
getListViewActiveState,
} from "selectors/ideSelectors";
import type { EntityItem } from "ee/entities/IDE/constants"; import type { EntityItem } from "ee/entities/IDE/constants";
import { import {
EditorEntityTab, EditorEntityTab,
@ -19,28 +23,30 @@ import { identifyEntityFromPath } from "navigation/FocusEntity";
import { List } from "./List"; import { List } from "./List";
import { ScreenModeToggle } from "./ScreenModeToggle"; import { ScreenModeToggle } from "./ScreenModeToggle";
import { AddTab } from "./AddTab"; import { AddTab } from "./AddTab";
import { setListViewActiveState } from "actions/ideActions";
const EditorTabs = () => { const EditorTabs = () => {
const [showListView, setShowListView] = useState(false);
const isSideBySideEnabled = useSelector(getIsSideBySideEnabled); const isSideBySideEnabled = useSelector(getIsSideBySideEnabled);
const ideViewMode = useSelector(getIDEViewMode); const ideViewMode = useSelector(getIDEViewMode);
const { segment, segmentMode } = useCurrentEditorState(); const { segment, segmentMode } = useCurrentEditorState();
const { closeClickHandler, tabClickHandler } = useIDETabClickHandlers(); const { closeClickHandler, tabClickHandler } = useIDETabClickHandlers();
const tabsConfig = TabSelectors[segment]; const tabsConfig = TabSelectors[segment];
const files = useSelector(tabsConfig.tabsSelector, shallowEqual); const files = useSelector(tabsConfig.tabsSelector, shallowEqual);
const isListViewActive = useSelector(getListViewActiveState);
const location = useLocation(); const location = useLocation();
const dispatch = useDispatch();
const currentEntity = identifyEntityFromPath(location.pathname); const currentEntity = identifyEntityFromPath(location.pathname);
// Turn off list view while changing segment, files // Turn off list view while changing segment, files
useEffect(() => { useEffect(() => {
setShowListView(false); dispatch(setListViewActiveState(false));
}, [currentEntity.id, currentEntity.entity, files, segmentMode]); }, [currentEntity.id, currentEntity.entity, files, segmentMode]);
// Show list view if all tabs is closed // Show list view if all tabs is closed
useEffect(() => { useEffect(() => {
if (files.length === 0 && segmentMode !== EditorEntityTabState.Add) { if (files.length === 0 && segmentMode !== EditorEntityTabState.Add) {
setShowListView(true); dispatch(setListViewActiveState(true));
} }
}, [files, segmentMode, currentEntity.entity]); }, [files, segmentMode, currentEntity.entity]);
@ -75,16 +81,16 @@ const EditorTabs = () => {
const handleHamburgerClick = () => { const handleHamburgerClick = () => {
if (files.length === 0 && segmentMode !== EditorEntityTabState.Add) return; if (files.length === 0 && segmentMode !== EditorEntityTabState.Add) return;
setShowListView(!showListView); dispatch(setListViewActiveState(!isListViewActive));
}; };
const onTabClick = (tab: EntityItem) => { const onTabClick = (tab: EntityItem) => {
setShowListView(false); dispatch(setListViewActiveState(false));
tabClickHandler(tab); tabClickHandler(tab);
}; };
const newTabClickHandler = () => { const newTabClickHandler = () => {
setShowListView(false); dispatch(setListViewActiveState(false));
}; };
return ( return (
@ -94,7 +100,7 @@ const EditorTabs = () => {
<ToggleButton <ToggleButton
data-testid="t--list-toggle" data-testid="t--list-toggle"
icon="hamburger" icon="hamburger"
isSelected={showListView} isSelected={isListViewActive}
onClick={handleHamburgerClick} onClick={handleHamburgerClick}
size="md" size="md"
/> />
@ -118,13 +124,13 @@ const EditorTabs = () => {
> >
<FileTabs <FileTabs
currentEntity={currentEntity} currentEntity={currentEntity}
isListActive={showListView} isListActive={isListViewActive}
navigateToTab={onTabClick} navigateToTab={onTabClick}
onClose={closeClickHandler} onClose={closeClickHandler}
tabs={files} tabs={files}
/> />
<AddTab <AddTab
isListActive={showListView} isListActive={isListViewActive}
newTabClickCallback={newTabClickHandler} newTabClickCallback={newTabClickHandler}
onClose={closeClickHandler} onClose={closeClickHandler}
/> />
@ -137,7 +143,9 @@ const EditorTabs = () => {
</Container> </Container>
{/* Overflow list */} {/* Overflow list */}
{showListView && ideViewMode === EditorViewMode.SplitScreen && <List />} {isListViewActive && ideViewMode === EditorViewMode.SplitScreen && (
<List />
)}
{/* Announcement modal */} {/* Announcement modal */}
{ideViewMode === EditorViewMode.SplitScreen && <Announcement />} {ideViewMode === EditorViewMode.SplitScreen && <Announcement />}

View File

@ -13,6 +13,7 @@ export const IDETabsDefaultValue = {
const initialState: IDEState = { const initialState: IDEState = {
view: EditorViewMode.FullScreen, view: EditorViewMode.FullScreen,
tabs: {}, tabs: {},
isListViewActive: false,
showCreateModal: false, showCreateModal: false,
ideCanvasSideBySideHover: { ideCanvasSideBySideHover: {
navigated: false, navigated: false,
@ -101,10 +102,19 @@ const ideReducer = createImmerReducer(initialState, {
) => { ) => {
state.ideCanvasSideBySideHover.widgetTypes.push(action.payload); state.ideCanvasSideBySideHover.widgetTypes.push(action.payload);
}, },
[ReduxActionTypes.SET_IS_LIST_VIEW_ACTIVE]: (
state: IDEState,
action: {
payload: boolean;
},
) => {
state.isListViewActive = action.payload;
},
}); });
export interface IDEState { export interface IDEState {
view: EditorViewMode; view: EditorViewMode;
isListViewActive: boolean;
tabs: ParentEntityIDETabs; tabs: ParentEntityIDETabs;
showCreateModal: boolean; showCreateModal: boolean;
ideCanvasSideBySideHover: IDECanvasSideBySideHover; ideCanvasSideBySideHover: IDECanvasSideBySideHover;

View File

@ -61,3 +61,6 @@ export const getShowCreateNewModal = (state: AppState) =>
export const getIdeCanvasSideBySideHoverState = (state: AppState) => export const getIdeCanvasSideBySideHoverState = (state: AppState) =>
state.ui.ide.ideCanvasSideBySideHover; state.ui.ide.ideCanvasSideBySideHover;
export const getListViewActiveState = (state: AppState) =>
state.ui.ide.isListViewActive;