From 4f2ef4913974c540bd259b52e5dc4f1d788c423a Mon Sep 17 00:00:00 2001
From: albinAppsmith <87797149+albinAppsmith@users.noreply.github.com>
Date: Mon, 10 Jun 2024 13:45:10 +0530
Subject: [PATCH 01/12] feat: New ui for overflow tabs
---
.../Editor/IDE/EditorPane/Query/hooks.tsx | 3 +-
.../IDE/EditorPane/EditorPaneSegments.tsx | 11 +-
.../Editor/IDE/EditorTabs/FileTabs.test.tsx | 3 +
.../pages/Editor/IDE/EditorTabs/FileTabs.tsx | 16 +-
.../Editor/IDE/EditorTabs/FullScreenTabs.tsx | 67 --------
.../Editor/IDE/EditorTabs/SplitScreenTabs.tsx | 79 ---------
.../src/pages/Editor/IDE/EditorTabs/index.tsx | 158 ++++++++++++++++++
.../src/pages/Editor/IDE/MainPane/index.tsx | 8 +-
app/client/src/pages/Editor/IDE/hooks.ts | 2 +-
9 files changed, 182 insertions(+), 165 deletions(-)
delete mode 100644 app/client/src/pages/Editor/IDE/EditorTabs/FullScreenTabs.tsx
delete mode 100644 app/client/src/pages/Editor/IDE/EditorTabs/SplitScreenTabs.tsx
create mode 100644 app/client/src/pages/Editor/IDE/EditorTabs/index.tsx
diff --git a/app/client/src/ce/pages/Editor/IDE/EditorPane/Query/hooks.tsx b/app/client/src/ce/pages/Editor/IDE/EditorPane/Query/hooks.tsx
index 90b37aee232..3eedf95b874 100644
--- a/app/client/src/ce/pages/Editor/IDE/EditorPane/Query/hooks.tsx
+++ b/app/client/src/ce/pages/Editor/IDE/EditorPane/Query/hooks.tsx
@@ -38,6 +38,7 @@ import { Tag, type ListItemProps } from "design-system";
import { useCurrentEditorState } from "pages/Editor/IDE/hooks";
import CurlImportEditor from "pages/Editor/APIEditor/CurlImportEditor";
import { createAddClassName } from "pages/Editor/IDE/EditorPane/utils";
+import { QueriesBlankState } from "pages/Editor/QueryEditor/QueriesBlankState";
export const useQueryAdd = () => {
const location = useLocation();
@@ -161,7 +162,7 @@ export const useQuerySegmentRoutes = (path: string): UseRoutes => {
},
{
key: "QueryEmpty",
- component: ListQuery,
+ component: QueriesBlankState,
exact: true,
path: [path],
},
diff --git a/app/client/src/pages/Editor/IDE/EditorPane/EditorPaneSegments.tsx b/app/client/src/pages/Editor/IDE/EditorPane/EditorPaneSegments.tsx
index c2daef1f832..34a89ee61f1 100644
--- a/app/client/src/pages/Editor/IDE/EditorPane/EditorPaneSegments.tsx
+++ b/app/client/src/pages/Editor/IDE/EditorPane/EditorPaneSegments.tsx
@@ -6,7 +6,7 @@ import QueriesSegment from "./Query";
import WidgetsSegment from "./UI";
import JSSegment from "./JS";
import SegmentedHeader from "./components/SegmentedHeader";
-import EditorTabs from "../EditorTabs/SplitScreenTabs";
+import EditorTabs from "../EditorTabs";
import {
jsSegmentRoutes,
querySegmentRoutes,
@@ -17,19 +17,24 @@ import {
BUILDER_PATH,
BUILDER_PATH_DEPRECATED,
} from "@appsmith/constants/routes/appRoutes";
+import { useSelector } from "react-redux";
+import { getIDEViewMode } from "selectors/ideSelectors";
+import { EditorViewMode } from "@appsmith/entities/IDE/constants";
const EditorPaneSegments = () => {
const { path } = useRouteMatch();
+ const ideViewMode = useSelector(getIDEViewMode);
return (
-
+ {ideViewMode === EditorViewMode.SplitScreen ? : null}
{
it("renders tabs correctly", () => {
const { getByTestId, getByText } = render(
{
it("check tab click", () => {
const { getByTestId } = render(
{
it("check for close click", () => {
const { getByTestId } = render(
void;
onClose: (actionId?: string) => void;
+ currentTab: string;
}
const FILE_TABS_CONTAINER_ID = "file-tabs-container";
const FileTabs = (props: Props) => {
- const { navigateToTab, onClose, tabs } = props;
+ const { currentTab, navigateToTab, onClose, tabs } = props;
const { segment, segmentMode } = useCurrentEditorState();
- const location = useLocation();
-
- const currentEntity = identifyEntityFromPath(location.pathname);
-
useEffect(() => {
const activetab = document.querySelector(".editor-tab.active");
if (activetab) {
@@ -70,10 +65,7 @@ const FileTabs = (props: Props) => {
{tabs.map((tab: EntityItem) => (
navigateToTab(tab)}
@@ -92,7 +84,7 @@ const FileTabs = (props: Props) => {
{/* New Tab */}
{segmentMode === EditorEntityTabState.Add ? (
diff --git a/app/client/src/pages/Editor/IDE/EditorTabs/FullScreenTabs.tsx b/app/client/src/pages/Editor/IDE/EditorTabs/FullScreenTabs.tsx
deleted file mode 100644
index f9a3f14c5f0..00000000000
--- a/app/client/src/pages/Editor/IDE/EditorTabs/FullScreenTabs.tsx
+++ /dev/null
@@ -1,67 +0,0 @@
-import React, { useCallback } from "react";
-import { useDispatch, useSelector } from "react-redux";
-import { Button, Tooltip } from "design-system";
-import { getIDEViewMode, getIsSideBySideEnabled } from "selectors/ideSelectors";
-import {
- EditorEntityTab,
- EditorViewMode,
-} from "@appsmith/entities/IDE/constants";
-import { setIdeEditorViewMode } from "actions/ideActions";
-import FileTabs from "./FileTabs";
-import Container from "./Container";
-import { useCurrentEditorState, useIDETabClickHandlers } from "../hooks";
-import { TabSelectors } from "./constants";
-import {
- MINIMIZE_BUTTON_TOOLTIP,
- createMessage,
-} from "@appsmith/constants/messages";
-import AnalyticsUtil from "@appsmith/utils/AnalyticsUtil";
-import { AddButton } from "./AddButton";
-
-const FullScreenTabs = () => {
- const dispatch = useDispatch();
- const isSideBySideEnabled = useSelector(getIsSideBySideEnabled);
- const ideViewMode = useSelector(getIDEViewMode);
- const { segment } = useCurrentEditorState();
- const { closeClickHandler, tabClickHandler } = useIDETabClickHandlers();
-
- const setSplitScreenMode = useCallback(() => {
- dispatch(setIdeEditorViewMode(EditorViewMode.SplitScreen));
- AnalyticsUtil.logEvent("EDITOR_MODE_CHANGE", {
- to: EditorViewMode.SplitScreen,
- });
- }, []);
- const tabsConfig = TabSelectors[segment];
-
- const files = useSelector(tabsConfig.tabsSelector);
-
- if (!isSideBySideEnabled) return null;
- if (ideViewMode === EditorViewMode.SplitScreen) return null;
- if (segment === EditorEntityTab.UI) return null;
- return (
-
-
- {files.length > 0 ? : null}
-
-
-
-
- );
-};
-
-export default FullScreenTabs;
diff --git a/app/client/src/pages/Editor/IDE/EditorTabs/SplitScreenTabs.tsx b/app/client/src/pages/Editor/IDE/EditorTabs/SplitScreenTabs.tsx
deleted file mode 100644
index dd4f490b1bc..00000000000
--- a/app/client/src/pages/Editor/IDE/EditorTabs/SplitScreenTabs.tsx
+++ /dev/null
@@ -1,79 +0,0 @@
-import React, { useCallback } from "react";
-
-import FileTabs from "./FileTabs";
-import { useDispatch, useSelector } from "react-redux";
-import { getIDEViewMode, getIsSideBySideEnabled } from "selectors/ideSelectors";
-import Container from "./Container";
-import { useCurrentEditorState, useIDETabClickHandlers } from "../hooks";
-import {
- EditorEntityTab,
- EditorViewMode,
-} from "@appsmith/entities/IDE/constants";
-import { TabSelectors } from "./constants";
-import { Announcement } from "../EditorPane/components/Announcement";
-import { SearchableFilesList } from "./SearchableFilesList";
-import { AddButton } from "./AddButton";
-import { Button, Tooltip } from "design-system";
-import {
- MAXIMIZE_BUTTON_TOOLTIP,
- createMessage,
-} from "@appsmith/constants/messages";
-import AnalyticsUtil from "@appsmith/utils/AnalyticsUtil";
-import { setIdeEditorViewMode } from "actions/ideActions";
-
-const SplitScreenTabs = () => {
- const dispatch = useDispatch();
- const isSideBySideEnabled = useSelector(getIsSideBySideEnabled);
- const ideViewMode = useSelector(getIDEViewMode);
- const { segment } = useCurrentEditorState();
- const { closeClickHandler, tabClickHandler } = useIDETabClickHandlers();
-
- const tabsConfig = TabSelectors[segment];
-
- const files = useSelector(tabsConfig.tabsSelector);
- const allFilesList = useSelector(tabsConfig.listSelector);
-
- const handleMaximizeButtonClick = useCallback(() => {
- AnalyticsUtil.logEvent("EDITOR_MODE_CHANGE", {
- to: EditorViewMode.FullScreen,
- });
- dispatch(setIdeEditorViewMode(EditorViewMode.FullScreen));
- }, []);
-
- if (!isSideBySideEnabled) return null;
- if (ideViewMode === EditorViewMode.FullScreen) return null;
- if (segment === EditorEntityTab.UI) return null;
-
- return (
- <>
- {/* {files.length > 0 ? ( */}
-
-
-
- {files.length > 0 ? : null}
-
-
-
-
-
-
- >
- );
-};
-
-export default SplitScreenTabs;
diff --git a/app/client/src/pages/Editor/IDE/EditorTabs/index.tsx b/app/client/src/pages/Editor/IDE/EditorTabs/index.tsx
new file mode 100644
index 00000000000..34bac68c39e
--- /dev/null
+++ b/app/client/src/pages/Editor/IDE/EditorTabs/index.tsx
@@ -0,0 +1,158 @@
+import React, { useCallback, useEffect, useState } from "react";
+import { useDispatch, useSelector } from "react-redux";
+import { Button, Flex, ToggleButton, Tooltip } from "design-system";
+import { getIDEViewMode, getIsSideBySideEnabled } from "selectors/ideSelectors";
+import type { EntityItem } from "@appsmith/entities/IDE/constants";
+import {
+ EditorEntityTab,
+ EditorEntityTabState,
+ EditorViewMode,
+} from "@appsmith/entities/IDE/constants";
+import { setIdeEditorViewMode } from "actions/ideActions";
+import FileTabs from "./FileTabs";
+import Container from "./Container";
+import { useCurrentEditorState, useIDETabClickHandlers } from "../hooks";
+import { TabSelectors } from "./constants";
+import {
+ MAXIMIZE_BUTTON_TOOLTIP,
+ MINIMIZE_BUTTON_TOOLTIP,
+ createMessage,
+} from "@appsmith/constants/messages";
+import AnalyticsUtil from "@appsmith/utils/AnalyticsUtil";
+import { AddButton } from "./AddButton";
+import { Announcement } from "../EditorPane/components/Announcement";
+import ListQuery from "../EditorPane/Query/List";
+import styled from "styled-components";
+import { useLocation } from "react-router";
+import { identifyEntityFromPath } from "navigation/FocusEntity";
+
+const ListContainer = styled(Flex)`
+ & .t--entity-item {
+ grid-template-columns: 0 auto 1fr auto auto auto auto auto;
+ height: 32px;
+
+ & .t--entity-name {
+ padding-left: var(--ads-v2-spaces-3);
+ }
+ }
+`;
+
+const EditorTabs = () => {
+ const dispatch = useDispatch();
+ const [showListView, setShowListView] = useState(false);
+ const isSideBySideEnabled = useSelector(getIsSideBySideEnabled);
+ const ideViewMode = useSelector(getIDEViewMode);
+ const { segment, segmentMode } = useCurrentEditorState();
+ const { closeClickHandler, tabClickHandler } = useIDETabClickHandlers();
+
+ const tabsConfig = TabSelectors[segment];
+ const files = useSelector(tabsConfig.tabsSelector);
+
+ const location = useLocation();
+ const currentEntity = identifyEntityFromPath(location.pathname);
+ const activeTab = showListView
+ ? ""
+ : segmentMode === EditorEntityTabState.Add
+ ? "add"
+ : currentEntity.id;
+
+ useEffect(() => {
+ if (files.length === 0 && segmentMode !== EditorEntityTabState.Add) {
+ setShowListView(true);
+ } else if (showListView) {
+ setShowListView(false);
+ }
+ }, [files, segmentMode]);
+
+ const toggleEditorMode = useCallback(() => {
+ const newMode =
+ ideViewMode === EditorViewMode.SplitScreen
+ ? EditorViewMode.FullScreen
+ : EditorViewMode.SplitScreen;
+
+ AnalyticsUtil.logEvent("EDITOR_MODE_CHANGE", {
+ to: newMode,
+ });
+ dispatch(setIdeEditorViewMode(newMode));
+ }, [ideViewMode, dispatch]);
+
+ const handleHamburgerClick = () => {
+ if (files.length === 0 && segmentMode !== EditorEntityTabState.Add) return;
+ setShowListView(!showListView);
+ };
+
+ if (!isSideBySideEnabled) return null;
+ if (segment === EditorEntityTab.UI) return null;
+
+ const onTabClick = (tab: EntityItem) => {
+ setShowListView(false);
+ tabClickHandler(tab);
+ };
+
+ return (
+ <>
+
+ {ideViewMode === EditorViewMode.SplitScreen && (
+
+ )}
+
+ {files.length > 0 ? : null}
+
+
+
+
+ {showListView &&
+ ideViewMode === EditorViewMode.SplitScreen &&
+ segmentMode !== EditorEntityTabState.Add && (
+
+
+
+ )}
+ {ideViewMode === EditorViewMode.SplitScreen && }
+ >
+ );
+};
+
+export default EditorTabs;
diff --git a/app/client/src/pages/Editor/IDE/MainPane/index.tsx b/app/client/src/pages/Editor/IDE/MainPane/index.tsx
index 23973c915b6..edae34902ad 100644
--- a/app/client/src/pages/Editor/IDE/MainPane/index.tsx
+++ b/app/client/src/pages/Editor/IDE/MainPane/index.tsx
@@ -3,12 +3,16 @@ import { BUILDER_PATH } from "constants/routes";
import { Route, Switch, useRouteMatch } from "react-router";
import * as Sentry from "@sentry/react";
import useRoutes from "@appsmith/pages/Editor/IDE/MainPane/useRoutes";
-import EditorTabs from "pages/Editor/IDE/EditorTabs/FullScreenTabs";
+import EditorTabs from "pages/Editor/IDE/EditorTabs";
import { useWidgetSelectionBlockListener } from "pages/Editor/IDE/hooks";
+import { useSelector } from "react-redux";
+import { getIDEViewMode } from "selectors/ideSelectors";
+import { EditorViewMode } from "@appsmith/entities/IDE/constants";
const SentryRoute = Sentry.withSentryRouting(Route);
export const MainPane = (props: { id: string }) => {
const { path } = useRouteMatch();
+ const ideViewMode = useSelector(getIDEViewMode);
const routes = useRoutes(path);
useWidgetSelectionBlockListener();
@@ -18,7 +22,7 @@ export const MainPane = (props: { id: string }) => {
data-testid="t--ide-main-pane"
id={props.id}
>
-
+ {ideViewMode === EditorViewMode.FullScreen ? : null}
{routes.map((route) => (
diff --git a/app/client/src/pages/Editor/IDE/hooks.ts b/app/client/src/pages/Editor/IDE/hooks.ts
index cd2b4e9a2db..75fcb7776df 100644
--- a/app/client/src/pages/Editor/IDE/hooks.ts
+++ b/app/client/src/pages/Editor/IDE/hooks.ts
@@ -255,7 +255,7 @@ export const useIDETabClickHandlers = () => {
);
const closeClickHandler = useCallback(
- (actionId: string | undefined) => {
+ (actionId?: string) => {
if (!actionId) {
// handle JS
return segment === EditorEntityTab.JS ? closeAddJS() : closeAddQuery();
From 30319202d46585b327b7b722eff2cf7663eea5c6 Mon Sep 17 00:00:00 2001
From: albinAppsmith <87797149+albinAppsmith@users.noreply.github.com>
Date: Mon, 10 Jun 2024 23:14:03 +0530
Subject: [PATCH 02/12] fix: new tab click fix
---
.../pages/Editor/IDE/EditorTabs/FileTabs.tsx | 5 +++-
.../src/pages/Editor/IDE/EditorTabs/index.tsx | 29 ++++++++++---------
2 files changed, 20 insertions(+), 14 deletions(-)
diff --git a/app/client/src/pages/Editor/IDE/EditorTabs/FileTabs.tsx b/app/client/src/pages/Editor/IDE/EditorTabs/FileTabs.tsx
index 8fbd21fbdac..30ff4d5baea 100644
--- a/app/client/src/pages/Editor/IDE/EditorTabs/FileTabs.tsx
+++ b/app/client/src/pages/Editor/IDE/EditorTabs/FileTabs.tsx
@@ -19,12 +19,14 @@ interface Props {
navigateToTab: (tab: EntityItem) => void;
onClose: (actionId?: string) => void;
currentTab: string;
+ newTabClickCallback?: () => void;
}
const FILE_TABS_CONTAINER_ID = "file-tabs-container";
const FileTabs = (props: Props) => {
- const { currentTab, navigateToTab, onClose, tabs } = props;
+ const { currentTab, navigateToTab, newTabClickCallback, onClose, tabs } =
+ props;
const { segment, segmentMode } = useCurrentEditorState();
useEffect(() => {
@@ -86,6 +88,7 @@ const FileTabs = (props: Props) => {
New {segment === EditorEntityTab.JS ? "JS" : "Query"}
diff --git a/app/client/src/pages/Editor/IDE/EditorTabs/index.tsx b/app/client/src/pages/Editor/IDE/EditorTabs/index.tsx
index 34bac68c39e..56370f2f4aa 100644
--- a/app/client/src/pages/Editor/IDE/EditorTabs/index.tsx
+++ b/app/client/src/pages/Editor/IDE/EditorTabs/index.tsx
@@ -89,6 +89,10 @@ const EditorTabs = () => {
tabClickHandler(tab);
};
+ const newTabClickHandler = () => {
+ setShowListView(false);
+ };
+
return (
<>
@@ -103,6 +107,7 @@ const EditorTabs = () => {
@@ -137,19 +142,17 @@ const EditorTabs = () => {
/>
- {showListView &&
- ideViewMode === EditorViewMode.SplitScreen &&
- segmentMode !== EditorEntityTabState.Add && (
-
-
-
- )}
+ {showListView && ideViewMode === EditorViewMode.SplitScreen && (
+
+
+
+ )}
{ideViewMode === EditorViewMode.SplitScreen && }
>
);
From f98571d3157a620e6cd8a2308d4460893a402347 Mon Sep 17 00:00:00 2001
From: albinAppsmith <87797149+albinAppsmith@users.noreply.github.com>
Date: Mon, 17 Jun 2024 13:02:23 +0530
Subject: [PATCH 03/12] fix: optmised editortab component
---
.../pages/Editor/IDE/EditorPane/JS/List.tsx | 1 +
.../src/pages/Editor/IDE/EditorTabs/List.tsx | 35 +++++++
.../IDE/EditorTabs/ScreenModeToggle.tsx | 62 +++++++++++++
.../src/pages/Editor/IDE/EditorTabs/index.tsx | 93 +++----------------
4 files changed, 113 insertions(+), 78 deletions(-)
create mode 100644 app/client/src/pages/Editor/IDE/EditorTabs/List.tsx
create mode 100644 app/client/src/pages/Editor/IDE/EditorTabs/ScreenModeToggle.tsx
diff --git a/app/client/src/pages/Editor/IDE/EditorPane/JS/List.tsx b/app/client/src/pages/Editor/IDE/EditorPane/JS/List.tsx
index ccf56595ff1..0d26d1ce056 100644
--- a/app/client/src/pages/Editor/IDE/EditorPane/JS/List.tsx
+++ b/app/client/src/pages/Editor/IDE/EditorPane/JS/List.tsx
@@ -51,6 +51,7 @@ const ListJSObjects = () => {
return (
{
+ const { segment } = useCurrentEditorState();
+
+ return (
+
+ {segment === EditorEntityTab.QUERIES ? : }
+
+ );
+};
diff --git a/app/client/src/pages/Editor/IDE/EditorTabs/ScreenModeToggle.tsx b/app/client/src/pages/Editor/IDE/EditorTabs/ScreenModeToggle.tsx
new file mode 100644
index 00000000000..13eb9dd1c77
--- /dev/null
+++ b/app/client/src/pages/Editor/IDE/EditorTabs/ScreenModeToggle.tsx
@@ -0,0 +1,62 @@
+import React, { useCallback } from "react";
+import { useDispatch, useSelector } from "react-redux";
+import { Button, Tooltip } from "design-system";
+
+import { getIDEViewMode } from "selectors/ideSelectors";
+import { EditorViewMode } from "@appsmith/entities/IDE/constants";
+import AnalyticsUtil from "@appsmith/utils/AnalyticsUtil";
+import {
+ MAXIMIZE_BUTTON_TOOLTIP,
+ MINIMIZE_BUTTON_TOOLTIP,
+ createMessage,
+} from "@appsmith/constants/messages";
+import { setIdeEditorViewMode } from "actions/ideActions";
+
+export const ScreenModeToggle = () => {
+ const dispatch = useDispatch();
+ const ideViewMode = useSelector(getIDEViewMode);
+
+ const toggleEditorMode = useCallback(() => {
+ const newMode =
+ ideViewMode === EditorViewMode.SplitScreen
+ ? EditorViewMode.FullScreen
+ : EditorViewMode.SplitScreen;
+
+ AnalyticsUtil.logEvent("EDITOR_MODE_CHANGE", {
+ to: newMode,
+ });
+ dispatch(setIdeEditorViewMode(newMode));
+ }, [ideViewMode, dispatch]);
+
+ return (
+
+
+
+ );
+};
diff --git a/app/client/src/pages/Editor/IDE/EditorTabs/index.tsx b/app/client/src/pages/Editor/IDE/EditorTabs/index.tsx
index 56370f2f4aa..c932e391daf 100644
--- a/app/client/src/pages/Editor/IDE/EditorTabs/index.tsx
+++ b/app/client/src/pages/Editor/IDE/EditorTabs/index.tsx
@@ -1,6 +1,6 @@
-import React, { useCallback, useEffect, useState } from "react";
-import { useDispatch, useSelector } from "react-redux";
-import { Button, Flex, ToggleButton, Tooltip } from "design-system";
+import React, { useEffect, useState } from "react";
+import { useSelector } from "react-redux";
+import { ToggleButton } from "design-system";
import { getIDEViewMode, getIsSideBySideEnabled } from "selectors/ideSelectors";
import type { EntityItem } from "@appsmith/entities/IDE/constants";
import {
@@ -8,37 +8,18 @@ import {
EditorEntityTabState,
EditorViewMode,
} from "@appsmith/entities/IDE/constants";
-import { setIdeEditorViewMode } from "actions/ideActions";
import FileTabs from "./FileTabs";
import Container from "./Container";
import { useCurrentEditorState, useIDETabClickHandlers } from "../hooks";
import { TabSelectors } from "./constants";
-import {
- MAXIMIZE_BUTTON_TOOLTIP,
- MINIMIZE_BUTTON_TOOLTIP,
- createMessage,
-} from "@appsmith/constants/messages";
-import AnalyticsUtil from "@appsmith/utils/AnalyticsUtil";
import { AddButton } from "./AddButton";
import { Announcement } from "../EditorPane/components/Announcement";
-import ListQuery from "../EditorPane/Query/List";
-import styled from "styled-components";
import { useLocation } from "react-router";
import { identifyEntityFromPath } from "navigation/FocusEntity";
-
-const ListContainer = styled(Flex)`
- & .t--entity-item {
- grid-template-columns: 0 auto 1fr auto auto auto auto auto;
- height: 32px;
-
- & .t--entity-name {
- padding-left: var(--ads-v2-spaces-3);
- }
- }
-`;
+import { List } from "./List";
+import { ScreenModeToggle } from "./ScreenModeToggle";
const EditorTabs = () => {
- const dispatch = useDispatch();
const [showListView, setShowListView] = useState(false);
const isSideBySideEnabled = useSelector(getIsSideBySideEnabled);
const ideViewMode = useSelector(getIDEViewMode);
@@ -64,26 +45,14 @@ const EditorTabs = () => {
}
}, [files, segmentMode]);
- const toggleEditorMode = useCallback(() => {
- const newMode =
- ideViewMode === EditorViewMode.SplitScreen
- ? EditorViewMode.FullScreen
- : EditorViewMode.SplitScreen;
-
- AnalyticsUtil.logEvent("EDITOR_MODE_CHANGE", {
- to: newMode,
- });
- dispatch(setIdeEditorViewMode(newMode));
- }, [ideViewMode, dispatch]);
+ if (!isSideBySideEnabled) return null;
+ if (segment === EditorEntityTab.UI) return null;
const handleHamburgerClick = () => {
if (files.length === 0 && segmentMode !== EditorEntityTabState.Add) return;
setShowListView(!showListView);
};
- if (!isSideBySideEnabled) return null;
- if (segment === EditorEntityTab.UI) return null;
-
const onTabClick = (tab: EntityItem) => {
setShowListView(false);
tabClickHandler(tab);
@@ -112,47 +81,15 @@ const EditorTabs = () => {
tabs={files}
/>
{files.length > 0 ? : null}
-
-
-
+
+ {/* Switch screen mode button */}
+
- {showListView && ideViewMode === EditorViewMode.SplitScreen && (
-
-
-
- )}
+
+ {/* Overflow list */}
+ {showListView && ideViewMode === EditorViewMode.SplitScreen &&
}
+
+ {/* Announcement modal */}
{ideViewMode === EditorViewMode.SplitScreen && }
>
);
From 22b2dfbf966d3229df054c661c3ff8e54f1fc64c Mon Sep 17 00:00:00 2001
From: albinAppsmith <87797149+albinAppsmith@users.noreply.github.com>
Date: Wed, 19 Jun 2024 17:45:35 +0530
Subject: [PATCH 04/12] chore: Optimisations
---
app/client/src/IDE/Components/FileTab.tsx | 97 +++++++++++++++++++
.../IDE/EditorPane/EditorPaneSegments.tsx | 1 -
.../pages/Editor/IDE/EditorTabs/AddButton.tsx | 87 +++++++++++------
.../pages/Editor/IDE/EditorTabs/Container.tsx | 1 +
.../pages/Editor/IDE/EditorTabs/FileTabs.tsx | 94 +++---------------
.../Editor/IDE/EditorTabs/ListButton.tsx | 4 +-
.../IDE/EditorTabs/SearchableFilesList.tsx | 4 +-
.../IDE/EditorTabs/StyledComponents.tsx | 80 ++-------------
.../src/pages/Editor/IDE/EditorTabs/index.tsx | 40 ++++++--
9 files changed, 214 insertions(+), 194 deletions(-)
create mode 100644 app/client/src/IDE/Components/FileTab.tsx
diff --git a/app/client/src/IDE/Components/FileTab.tsx b/app/client/src/IDE/Components/FileTab.tsx
new file mode 100644
index 00000000000..af2012b0fe3
--- /dev/null
+++ b/app/client/src/IDE/Components/FileTab.tsx
@@ -0,0 +1,97 @@
+import React from "react";
+import styled from "styled-components";
+import clsx from "classnames";
+
+import { Flex, Icon } from "design-system";
+
+interface FileTabProps {
+ isActive: boolean;
+ title: string;
+ onClick: () => void;
+ onClose: (e: React.MouseEvent) => void;
+ icon?: React.ReactNode;
+}
+
+export const StyledTab = styled(Flex)`
+ position: relative;
+ height: 100%;
+ font-size: 12px;
+ color: var(--ads-v2-colors-text-default);
+ cursor: pointer;
+ gap: var(--ads-v2-spaces-2);
+ border-top: 1px solid transparent;
+ border-top-left-radius: var(--ads-v2-border-radius);
+ border-top-right-radius: var(--ads-v2-border-radius);
+ align-items: center;
+ justify-content: center;
+ padding: var(--ads-v2-spaces-3);
+ border-left: 1px solid transparent;
+ border-right: 1px solid transparent;
+ border-top: 2px solid transparent;
+
+ &.active {
+ background: var(--ads-v2-colors-control-field-default-bg);
+ border-top-color: var(--ads-v2-color-bg-brand);
+ border-left-color: var(--ads-v2-color-border-muted);
+ border-right-color: var(--ads-v2-color-border-muted);
+ }
+
+ & > .tab-close {
+ position: relative;
+ right: -2px;
+ visibility: hidden;
+ }
+
+ &:hover > .tab-close {
+ visibility: visible;
+ }
+
+ &.active > .tab-close {
+ visibility: visible;
+ }
+`;
+
+export const TabTextContainer = styled.span`
+ width: 100%;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ overflow: hidden;
+`;
+
+export const TabIconContainer = styled.div`
+ height: 12px;
+ width: 12px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ flex-shrink: 0;
+ img {
+ width: 12px;
+ }
+`;
+
+export const FileTab = ({
+ icon,
+ isActive,
+ onClick,
+ onClose,
+ title,
+}: FileTabProps) => {
+ return (
+
+ {icon ? {icon} : null}
+ {title}
+ {/* not using button component because of the size not matching design */}
+
+
+ );
+};
diff --git a/app/client/src/pages/Editor/IDE/EditorPane/EditorPaneSegments.tsx b/app/client/src/pages/Editor/IDE/EditorPane/EditorPaneSegments.tsx
index 34a89ee61f1..5d44ec5edf2 100644
--- a/app/client/src/pages/Editor/IDE/EditorPane/EditorPaneSegments.tsx
+++ b/app/client/src/pages/Editor/IDE/EditorPane/EditorPaneSegments.tsx
@@ -29,7 +29,6 @@ const EditorPaneSegments = () => {
diff --git a/app/client/src/pages/Editor/IDE/EditorTabs/AddButton.tsx b/app/client/src/pages/Editor/IDE/EditorTabs/AddButton.tsx
index b79340e5d6d..08211551128 100644
--- a/app/client/src/pages/Editor/IDE/EditorTabs/AddButton.tsx
+++ b/app/client/src/pages/Editor/IDE/EditorTabs/AddButton.tsx
@@ -1,36 +1,67 @@
-import React from "react";
+import type { Ref } from "react";
+import React, { forwardRef } from "react";
import { Flex, Spinner, Button } from "design-system";
import { useCurrentEditorState, useIDETabClickHandlers } from "../hooks";
import { useIsJSAddLoading } from "@appsmith/pages/Editor/IDE/EditorPane/JS/hooks";
-import { EditorEntityTabState } from "@appsmith/entities/IDE/constants";
+import {
+ EditorEntityTab,
+ EditorEntityTabState,
+} from "@appsmith/entities/IDE/constants";
+import { FileTab } from "IDE/Components/FileTab";
-const AddButton = () => {
- const { addClickHandler } = useIDETabClickHandlers();
- const isJSLoading = useIsJSAddLoading();
- const { segmentMode } = useCurrentEditorState();
+const AddButton = forwardRef(
+ (
+ {
+ newTabClickCallback,
+ onClose,
+ }: {
+ newTabClickCallback: () => void;
+ onClose: (actionId?: string) => void;
+ },
+ ref: Ref,
+ ) => {
+ const { addClickHandler } = useIDETabClickHandlers();
+ const isJSLoading = useIsJSAddLoading();
+ const { segment, segmentMode } = useCurrentEditorState();
- if (segmentMode === EditorEntityTabState.Add) {
- return null;
- }
- if (isJSLoading) {
- return (
-
-
-
+ if (isJSLoading) {
+ return (
+
+
+
+ );
+ }
+
+ const onCloseClick = (e: React.MouseEvent) => {
+ e.stopPropagation();
+ onClose();
+ };
+
+ return segmentMode === EditorEntityTabState.Add ? (
+ onCloseClick(e)}
+ title={`New ${segment === EditorEntityTab.JS ? "JS" : "Query"}`}
+ />
+ ) : (
+
+
+
);
- }
- return (
-
- );
-};
+ },
+);
export { AddButton };
diff --git a/app/client/src/pages/Editor/IDE/EditorTabs/Container.tsx b/app/client/src/pages/Editor/IDE/EditorTabs/Container.tsx
index b248f9e5f96..dbc77dd103f 100644
--- a/app/client/src/pages/Editor/IDE/EditorTabs/Container.tsx
+++ b/app/client/src/pages/Editor/IDE/EditorTabs/Container.tsx
@@ -9,6 +9,7 @@ const Container = (props: { children: ReactNode }) => {
backgroundColor="#FFFFFF"
borderBottom="1px solid var(--ads-v2-color-border-muted)"
gap="spaces-2"
+ id="ide-tabs-container"
maxHeight="32px"
minHeight="32px"
px="spaces-2"
diff --git a/app/client/src/pages/Editor/IDE/EditorTabs/FileTabs.tsx b/app/client/src/pages/Editor/IDE/EditorTabs/FileTabs.tsx
index 30ff4d5baea..b6c7a557f03 100644
--- a/app/client/src/pages/Editor/IDE/EditorTabs/FileTabs.tsx
+++ b/app/client/src/pages/Editor/IDE/EditorTabs/FileTabs.tsx
@@ -1,33 +1,19 @@
import React, { useEffect } from "react";
-import clsx from "classnames";
-import { Flex, Icon, ScrollArea } from "design-system";
-import {
- EditorEntityTab,
- EditorEntityTabState,
- type EntityItem,
-} from "@appsmith/entities/IDE/constants";
-import {
- StyledTab,
- TabIconContainer,
- TabTextContainer,
-} from "./StyledComponents";
+import type { EntityItem } from "@appsmith/entities/IDE/constants";
import { useCurrentEditorState } from "../hooks";
+import { FileTab } from "IDE/Components/FileTab";
interface Props {
tabs: EntityItem[];
navigateToTab: (tab: EntityItem) => void;
onClose: (actionId?: string) => void;
currentTab: string;
- newTabClickCallback?: () => void;
}
-const FILE_TABS_CONTAINER_ID = "file-tabs-container";
-
const FileTabs = (props: Props) => {
- const { currentTab, navigateToTab, newTabClickCallback, onClose, tabs } =
- props;
- const { segment, segmentMode } = useCurrentEditorState();
+ const { currentTab, navigateToTab, onClose, tabs } = props;
+ const { segmentMode } = useCurrentEditorState();
useEffect(() => {
const activetab = document.querySelector(".editor-tab.active");
@@ -38,72 +24,24 @@ const FileTabs = (props: Props) => {
}
}, [tabs, segmentMode]);
- useEffect(() => {
- const ele = document.getElementById(FILE_TABS_CONTAINER_ID)?.parentElement;
- if (ele && ele.scrollWidth > ele.clientWidth) {
- ele.style.borderRight = "1px solid var(--ads-v2-color-border)";
- } else if (ele) {
- ele.style.borderRight = "unset";
- }
- }, [tabs]);
-
const onCloseClick = (e: React.MouseEvent, id?: string) => {
e.stopPropagation();
onClose(id);
};
return (
-
-
- {tabs.map((tab: EntityItem) => (
- navigateToTab(tab)}
- >
- {tab.icon}
- {tab.title}
- {/* not using button component because of the size not matching design */}
- onCloseClick(e, tab.key)}
- />
-
- ))}
- {/* New Tab */}
- {segmentMode === EditorEntityTabState.Add ? (
-
-
- New {segment === EditorEntityTab.JS ? "JS" : "Query"}
-
- {/* not using button component because of the size not matching design */}
- onCloseClick(e)}
- />
-
- ) : null}
-
-
+ <>
+ {tabs.map((tab: EntityItem) => (
+ navigateToTab(tab)}
+ onClose={(e) => onCloseClick(e, tab.key)}
+ title={tab.title}
+ />
+ ))}
+ >
);
};
diff --git a/app/client/src/pages/Editor/IDE/EditorTabs/ListButton.tsx b/app/client/src/pages/Editor/IDE/EditorTabs/ListButton.tsx
index 503f0908896..1f6abf2f6a6 100644
--- a/app/client/src/pages/Editor/IDE/EditorTabs/ListButton.tsx
+++ b/app/client/src/pages/Editor/IDE/EditorTabs/ListButton.tsx
@@ -9,7 +9,7 @@ import {
MenuTrigger,
Text,
} from "design-system";
-import { ListIconContainer, TabTextContainer } from "./StyledComponents";
+import { ListIconContainer, ListTitle } from "./StyledComponents";
interface Props {
items: EntityItem[];
@@ -50,7 +50,7 @@ const ListButton = (props: Props) => {
gap="spaces-2"
>
{item.icon}
- {item.title}
+ {item.title}
))}
diff --git a/app/client/src/pages/Editor/IDE/EditorTabs/SearchableFilesList.tsx b/app/client/src/pages/Editor/IDE/EditorTabs/SearchableFilesList.tsx
index 8b058b55ebd..62358727c47 100644
--- a/app/client/src/pages/Editor/IDE/EditorTabs/SearchableFilesList.tsx
+++ b/app/client/src/pages/Editor/IDE/EditorTabs/SearchableFilesList.tsx
@@ -13,7 +13,7 @@ import {
MenuTrigger,
SearchInput,
} from "design-system";
-import { ListIconContainer, TabTextContainer } from "./StyledComponents";
+import { ListIconContainer, ListTitle } from "./StyledComponents";
interface Props {
allItems: EntityItem[];
@@ -64,7 +64,7 @@ const SearchableFilesList = (props: Props) => {
gap="spaces-2"
>
{file.icon}
- {file.title}
+ {file.title}
));
diff --git a/app/client/src/pages/Editor/IDE/EditorTabs/StyledComponents.tsx b/app/client/src/pages/Editor/IDE/EditorTabs/StyledComponents.tsx
index 66e40cd3935..d396860bfde 100644
--- a/app/client/src/pages/Editor/IDE/EditorTabs/StyledComponents.tsx
+++ b/app/client/src/pages/Editor/IDE/EditorTabs/StyledComponents.tsx
@@ -1,77 +1,4 @@
import styled from "styled-components";
-import { Flex } from "design-system";
-
-/**
- * Logic for 54px in max width
- *
- * 4px tabs + add icon container left padding
- * 4px tabs + add icon container right padding
- * 4px gap between tabs and add icon
- * 16px 4px gap between every tabs * 4 (since max tab count is 5,
- * there will be 5 gaps)
- * 26px Add button width
- * 62px show more list button(considering 3 digit width as max)
- * ======================================
- * 127px
- *
- */
-export const StyledTab = styled(Flex)`
- position: relative;
- top: 1px;
- font-size: 12px;
- color: var(--ads-v2-colors-text-default);
- cursor: pointer;
- gap: var(--ads-v2-spaces-2);
- border-top: 1px solid transparent;
- border-top-left-radius: var(--ads-v2-border-radius);
- border-top-right-radius: var(--ads-v2-border-radius);
- align-items: center;
- justify-content: center;
- padding: var(--ads-v2-spaces-3);
- border-left: 1px solid transparent;
- border-right: 1px solid transparent;
- border-top: 2px solid transparent;
-
- &.active {
- background: var(--ads-v2-colors-control-field-default-bg);
- border-top-color: var(--ads-v2-color-bg-brand);
- border-left-color: var(--ads-v2-color-border-muted);
- border-right-color: var(--ads-v2-color-border-muted);
- }
-
- & > .tab-close {
- position: relative;
- right: -2px;
- visibility: hidden;
- }
-
- &:hover > .tab-close {
- visibility: visible;
- }
-
- &.active > .tab-close {
- visibility: visible;
- }
-`;
-
-export const TabTextContainer = styled.span`
- width: 100%;
- text-overflow: ellipsis;
- white-space: nowrap;
- overflow: hidden;
-`;
-
-export const TabIconContainer = styled.div`
- height: 12px;
- width: 12px;
- display: flex;
- align-items: center;
- justify-content: center;
- flex-shrink: 0;
- img {
- width: 12px;
- }
-`;
export const ListIconContainer = styled.div`
height: 18px;
@@ -84,3 +11,10 @@ export const ListIconContainer = styled.div`
width: 18px;
}
`;
+
+export const ListTitle = styled.span`
+ width: 100%;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ overflow: hidden;
+`;
diff --git a/app/client/src/pages/Editor/IDE/EditorTabs/index.tsx b/app/client/src/pages/Editor/IDE/EditorTabs/index.tsx
index c932e391daf..f74193e206c 100644
--- a/app/client/src/pages/Editor/IDE/EditorTabs/index.tsx
+++ b/app/client/src/pages/Editor/IDE/EditorTabs/index.tsx
@@ -1,6 +1,6 @@
-import React, { useEffect, useState } from "react";
+import React, { useEffect, useRef, useState } from "react";
import { useSelector } from "react-redux";
-import { ToggleButton } from "design-system";
+import { Flex, ScrollArea, ToggleButton } from "design-system";
import { getIDEViewMode, getIsSideBySideEnabled } from "selectors/ideSelectors";
import type { EntityItem } from "@appsmith/entities/IDE/constants";
import {
@@ -20,6 +20,7 @@ import { List } from "./List";
import { ScreenModeToggle } from "./ScreenModeToggle";
const EditorTabs = () => {
+ const stickyRef = useRef(null);
const [showListView, setShowListView] = useState(false);
const isSideBySideEnabled = useSelector(getIsSideBySideEnabled);
const ideViewMode = useSelector(getIDEViewMode);
@@ -73,14 +74,33 @@ const EditorTabs = () => {
size="md"
/>
)}
-
- {files.length > 0 ? : null}
+
+
+
+ {files.length > 0 ? (
+
+ ) : null}
+
+
{/* Switch screen mode button */}
From 000cde829c7757bb485728352d243cca1f46fedf Mon Sep 17 00:00:00 2001
From: albinAppsmith <87797149+albinAppsmith@users.noreply.github.com>
Date: Thu, 20 Jun 2024 09:58:12 +0530
Subject: [PATCH 05/12] removed refs
---
.../pages/Editor/IDE/EditorTabs/AddButton.tsx | 95 +++++++++----------
.../src/pages/Editor/IDE/EditorTabs/index.tsx | 4 +-
2 files changed, 44 insertions(+), 55 deletions(-)
diff --git a/app/client/src/pages/Editor/IDE/EditorTabs/AddButton.tsx b/app/client/src/pages/Editor/IDE/EditorTabs/AddButton.tsx
index 08211551128..1a0e83a5dbe 100644
--- a/app/client/src/pages/Editor/IDE/EditorTabs/AddButton.tsx
+++ b/app/client/src/pages/Editor/IDE/EditorTabs/AddButton.tsx
@@ -1,5 +1,4 @@
-import type { Ref } from "react";
-import React, { forwardRef } from "react";
+import React from "react";
import { Flex, Spinner, Button } from "design-system";
import { useCurrentEditorState, useIDETabClickHandlers } from "../hooks";
import { useIsJSAddLoading } from "@appsmith/pages/Editor/IDE/EditorPane/JS/hooks";
@@ -9,59 +8,51 @@ import {
} from "@appsmith/entities/IDE/constants";
import { FileTab } from "IDE/Components/FileTab";
-const AddButton = forwardRef(
- (
- {
- newTabClickCallback,
- onClose,
- }: {
- newTabClickCallback: () => void;
- onClose: (actionId?: string) => void;
- },
- ref: Ref,
- ) => {
- const { addClickHandler } = useIDETabClickHandlers();
- const isJSLoading = useIsJSAddLoading();
- const { segment, segmentMode } = useCurrentEditorState();
+const AddButton = ({
+ newTabClickCallback,
+ onClose,
+}: {
+ newTabClickCallback: () => void;
+ onClose: (actionId?: string) => void;
+}) => {
+ const { addClickHandler } = useIDETabClickHandlers();
+ const isJSLoading = useIsJSAddLoading();
+ const { segment, segmentMode } = useCurrentEditorState();
- if (isJSLoading) {
- return (
-
-
-
- );
- }
+ if (isJSLoading) {
+ return (
+
+
+
+ );
+ }
- const onCloseClick = (e: React.MouseEvent) => {
- e.stopPropagation();
- onClose();
- };
+ const onCloseClick = (e: React.MouseEvent) => {
+ e.stopPropagation();
+ onClose();
+ };
- return segmentMode === EditorEntityTabState.Add ? (
- onCloseClick(e)}
- title={`New ${segment === EditorEntityTab.JS ? "JS" : "Query"}`}
+ return segmentMode === EditorEntityTabState.Add ? (
+ onCloseClick(e)}
+ title={`New ${segment === EditorEntityTab.JS ? "JS" : "Query"}`}
+ />
+ ) : (
+
+
- ) : (
-
-
-
- );
- },
-);
+
+ );
+};
export { AddButton };
diff --git a/app/client/src/pages/Editor/IDE/EditorTabs/index.tsx b/app/client/src/pages/Editor/IDE/EditorTabs/index.tsx
index f74193e206c..c3b06ff5669 100644
--- a/app/client/src/pages/Editor/IDE/EditorTabs/index.tsx
+++ b/app/client/src/pages/Editor/IDE/EditorTabs/index.tsx
@@ -1,4 +1,4 @@
-import React, { useEffect, useRef, useState } from "react";
+import React, { useEffect, useState } from "react";
import { useSelector } from "react-redux";
import { Flex, ScrollArea, ToggleButton } from "design-system";
import { getIDEViewMode, getIsSideBySideEnabled } from "selectors/ideSelectors";
@@ -20,7 +20,6 @@ import { List } from "./List";
import { ScreenModeToggle } from "./ScreenModeToggle";
const EditorTabs = () => {
- const stickyRef = useRef(null);
const [showListView, setShowListView] = useState(false);
const isSideBySideEnabled = useSelector(getIsSideBySideEnabled);
const ideViewMode = useSelector(getIDEViewMode);
@@ -96,7 +95,6 @@ const EditorTabs = () => {
) : null}
From d31c64f1360c01ba68503ea5eddd7f889157c5f0 Mon Sep 17 00:00:00 2001
From: albinAppsmith <87797149+albinAppsmith@users.noreply.github.com>
Date: Thu, 20 Jun 2024 11:30:17 +0530
Subject: [PATCH 06/12] fix: seperated add button and tab
---
.../pages/Editor/IDE/EditorTabs/AddButton.tsx | 54 ++++++-------------
.../pages/Editor/IDE/EditorTabs/AddTab.tsx | 36 +++++++++++++
.../src/pages/Editor/IDE/EditorTabs/index.tsx | 13 ++---
3 files changed, 59 insertions(+), 44 deletions(-)
create mode 100644 app/client/src/pages/Editor/IDE/EditorTabs/AddTab.tsx
diff --git a/app/client/src/pages/Editor/IDE/EditorTabs/AddButton.tsx b/app/client/src/pages/Editor/IDE/EditorTabs/AddButton.tsx
index 1a0e83a5dbe..b79340e5d6d 100644
--- a/app/client/src/pages/Editor/IDE/EditorTabs/AddButton.tsx
+++ b/app/client/src/pages/Editor/IDE/EditorTabs/AddButton.tsx
@@ -2,23 +2,16 @@ import React from "react";
import { Flex, Spinner, Button } from "design-system";
import { useCurrentEditorState, useIDETabClickHandlers } from "../hooks";
import { useIsJSAddLoading } from "@appsmith/pages/Editor/IDE/EditorPane/JS/hooks";
-import {
- EditorEntityTab,
- EditorEntityTabState,
-} from "@appsmith/entities/IDE/constants";
-import { FileTab } from "IDE/Components/FileTab";
+import { EditorEntityTabState } from "@appsmith/entities/IDE/constants";
-const AddButton = ({
- newTabClickCallback,
- onClose,
-}: {
- newTabClickCallback: () => void;
- onClose: (actionId?: string) => void;
-}) => {
+const AddButton = () => {
const { addClickHandler } = useIDETabClickHandlers();
const isJSLoading = useIsJSAddLoading();
- const { segment, segmentMode } = useCurrentEditorState();
+ const { segmentMode } = useCurrentEditorState();
+ if (segmentMode === EditorEntityTabState.Add) {
+ return null;
+ }
if (isJSLoading) {
return (
@@ -26,32 +19,17 @@ const AddButton = ({
);
}
-
- const onCloseClick = (e: React.MouseEvent) => {
- e.stopPropagation();
- onClose();
- };
-
- return segmentMode === EditorEntityTabState.Add ? (
- onCloseClick(e)}
- title={`New ${segment === EditorEntityTab.JS ? "JS" : "Query"}`}
+ return (
+
- ) : (
-
-
-
);
};
diff --git a/app/client/src/pages/Editor/IDE/EditorTabs/AddTab.tsx b/app/client/src/pages/Editor/IDE/EditorTabs/AddTab.tsx
new file mode 100644
index 00000000000..02e54f040da
--- /dev/null
+++ b/app/client/src/pages/Editor/IDE/EditorTabs/AddTab.tsx
@@ -0,0 +1,36 @@
+import React from "react";
+
+import { FileTab } from "IDE/Components/FileTab";
+import { useCurrentEditorState } from "../hooks";
+import {
+ EditorEntityTab,
+ EditorEntityTabState,
+} from "@appsmith/entities/IDE/constants";
+
+const AddTab = ({
+ newTabClickCallback,
+ onClose,
+}: {
+ newTabClickCallback: () => void;
+ onClose: (actionId?: string) => void;
+}) => {
+ const { segment, segmentMode } = useCurrentEditorState();
+
+ if (segmentMode !== EditorEntityTabState.Add) return null;
+
+ const onCloseClick = (e: React.MouseEvent) => {
+ e.stopPropagation();
+ onClose();
+ };
+
+ return (
+ onCloseClick(e)}
+ title={`New ${segment === EditorEntityTab.JS ? "JS" : "Query"}`}
+ />
+ );
+};
+
+export { AddTab };
diff --git a/app/client/src/pages/Editor/IDE/EditorTabs/index.tsx b/app/client/src/pages/Editor/IDE/EditorTabs/index.tsx
index c3b06ff5669..e2a68eb9aa2 100644
--- a/app/client/src/pages/Editor/IDE/EditorTabs/index.tsx
+++ b/app/client/src/pages/Editor/IDE/EditorTabs/index.tsx
@@ -18,6 +18,7 @@ import { useLocation } from "react-router";
import { identifyEntityFromPath } from "navigation/FocusEntity";
import { List } from "./List";
import { ScreenModeToggle } from "./ScreenModeToggle";
+import { AddTab } from "./AddTab";
const EditorTabs = () => {
const [showListView, setShowListView] = useState(false);
@@ -76,6 +77,7 @@ const EditorTabs = () => {
{
onClose={closeClickHandler}
tabs={files}
/>
- {files.length > 0 ? (
-
- ) : null}
+
+ {files.length > 0 ? : null}
{/* Switch screen mode button */}
From 8b982013ba565be20aebfc56346ac181b118248a Mon Sep 17 00:00:00 2001
From: albinAppsmith <87797149+albinAppsmith@users.noreply.github.com>
Date: Fri, 21 Jun 2024 12:41:55 +0530
Subject: [PATCH 07/12] added border for sticky button
---
app/client/src/pages/Editor/IDE/EditorTabs/index.tsx | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/app/client/src/pages/Editor/IDE/EditorTabs/index.tsx b/app/client/src/pages/Editor/IDE/EditorTabs/index.tsx
index e2a68eb9aa2..8f008f5dcca 100644
--- a/app/client/src/pages/Editor/IDE/EditorTabs/index.tsx
+++ b/app/client/src/pages/Editor/IDE/EditorTabs/index.tsx
@@ -46,6 +46,17 @@ const EditorTabs = () => {
}
}, [files, segmentMode]);
+ useEffect(() => {
+ const ele = document.querySelector(
+ '[data-testid="t--editor-tabs"] > [data-overlayscrollbars-viewport]',
+ );
+ if (ele && ele.scrollWidth > ele.clientWidth) {
+ ele.style.borderRight = "1px solid var(--ads-v2-color-border)";
+ } else if (ele) {
+ ele.style.borderRight = "unset";
+ }
+ }, [files]);
+
if (!isSideBySideEnabled) return null;
if (segment === EditorEntityTab.UI) return null;
From c1d07952db73004f1094c0b99b8aad7d7d9c44cd Mon Sep 17 00:00:00 2001
From: albinAppsmith <87797149+albinAppsmith@users.noreply.github.com>
Date: Fri, 21 Jun 2024 12:45:00 +0530
Subject: [PATCH 08/12] added missing dependency
---
app/client/src/pages/Editor/IDE/EditorTabs/index.tsx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/app/client/src/pages/Editor/IDE/EditorTabs/index.tsx b/app/client/src/pages/Editor/IDE/EditorTabs/index.tsx
index 8f008f5dcca..cfc70749cb8 100644
--- a/app/client/src/pages/Editor/IDE/EditorTabs/index.tsx
+++ b/app/client/src/pages/Editor/IDE/EditorTabs/index.tsx
@@ -44,7 +44,7 @@ const EditorTabs = () => {
} else if (showListView) {
setShowListView(false);
}
- }, [files, segmentMode]);
+ }, [files, segmentMode, showListView]);
useEffect(() => {
const ele = document.querySelector(
From f89cecc03b632ccc04346fada164fa10a48c174e Mon Sep 17 00:00:00 2001
From: albinAppsmith <87797149+albinAppsmith@users.noreply.github.com>
Date: Fri, 21 Jun 2024 13:39:48 +0530
Subject: [PATCH 09/12] fix: removed scrollbar defer
---
app/client/src/pages/Editor/IDE/EditorTabs/index.tsx | 1 -
1 file changed, 1 deletion(-)
diff --git a/app/client/src/pages/Editor/IDE/EditorTabs/index.tsx b/app/client/src/pages/Editor/IDE/EditorTabs/index.tsx
index cfc70749cb8..43e3e81e8c7 100644
--- a/app/client/src/pages/Editor/IDE/EditorTabs/index.tsx
+++ b/app/client/src/pages/Editor/IDE/EditorTabs/index.tsx
@@ -88,7 +88,6 @@ const EditorTabs = () => {
Date: Mon, 24 Jun 2024 12:58:39 +0530
Subject: [PATCH 10/12] fix: show list issues
---
.../pages/Editor/IDE/EditorPane/JS/hooks.ts | 3 +-
.../src/ce/selectors/appIDESelectors.ts | 43 ++++++++-----------
.../pages/Editor/IDE/EditorPane/JS/List.tsx | 1 -
.../pages/Editor/IDE/EditorTabs/AddTab.tsx | 4 +-
.../Editor/IDE/EditorTabs/FileTabs.test.tsx | 15 +++++--
.../pages/Editor/IDE/EditorTabs/FileTabs.tsx | 28 ++++++------
.../src/pages/Editor/IDE/EditorTabs/index.tsx | 35 +++++++++------
7 files changed, 72 insertions(+), 57 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 71130f46e1c..6d5a2c96abb 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
@@ -17,6 +17,7 @@ import history from "utils/history";
import { FocusEntity, identifyEntityFromPath } from "navigation/FocusEntity";
import { useModuleOptions } from "@appsmith/utils/moduleInstanceHelpers";
import { getJSUrl } from "@appsmith/pages/Editor/IDE/EditorPane/JS/utils";
+import { JSBlankState } from "pages/Editor/JSEditor/JSBlankState";
export const useJSAdd = () => {
const pageId = useSelector(getCurrentPageId);
@@ -95,7 +96,7 @@ export const useJSSegmentRoutes = (path: string): UseRoutes => {
},
{
key: "JSEmpty",
- component: ListJS,
+ component: JSBlankState,
exact: true,
path: [path],
},
diff --git a/app/client/src/ce/selectors/appIDESelectors.ts b/app/client/src/ce/selectors/appIDESelectors.ts
index dfd9faa6787..af37fe26718 100644
--- a/app/client/src/ce/selectors/appIDESelectors.ts
+++ b/app/client/src/ce/selectors/appIDESelectors.ts
@@ -6,6 +6,7 @@ import {
getQuerySegmentItems,
} from "@appsmith/selectors/entitiesSelector";
import { getJSTabs, getQueryTabs } from "selectors/ideSelectors";
+import type { AppState } from "@appsmith/reducers";
export type EditorSegmentList = Array<{
group: string | "NA";
@@ -45,28 +46,22 @@ export const selectJSSegmentEditorList = createSelector(
},
);
-export const selectJSSegmentEditorTabs = createSelector(
- getJSSegmentItems,
- getJSTabs,
- (items, tabs) => {
- const keyedItems = keyBy(items, "key");
- return tabs
- .map((tab) => {
- return keyedItems[tab];
- })
- .filter(Boolean);
- },
-);
+export const selectJSSegmentEditorTabs = (state: AppState) => {
+ const items = getJSSegmentItems(state);
+ const tabs = getJSTabs(state);
-export const selectQuerySegmentEditorTabs = createSelector(
- getQuerySegmentItems,
- getQueryTabs,
- (items, tabs) => {
- const keyedItems = keyBy(items, "key");
- return tabs
- .map((tab) => {
- return keyedItems[tab];
- })
- .filter(Boolean);
- },
-);
+ const keyedItems = keyBy(items, "key");
+ return tabs
+ .map((tab) => {
+ return keyedItems[tab];
+ })
+ .filter(Boolean);
+};
+
+export const selectQuerySegmentEditorTabs = (state: AppState) => {
+ const items = getQuerySegmentItems(state);
+ const tabs = getQueryTabs(state);
+
+ const keyedItems = keyBy(items, "key");
+ return tabs.map((tab) => keyedItems[tab]).filter(Boolean);
+};
diff --git a/app/client/src/pages/Editor/IDE/EditorPane/JS/List.tsx b/app/client/src/pages/Editor/IDE/EditorPane/JS/List.tsx
index 0d26d1ce056..b3e21a8014e 100644
--- a/app/client/src/pages/Editor/IDE/EditorPane/JS/List.tsx
+++ b/app/client/src/pages/Editor/IDE/EditorPane/JS/List.tsx
@@ -78,7 +78,6 @@ const ListJSObjects = () => {
>
void;
onClose: (actionId?: string) => void;
+ isListActive: boolean;
}) => {
const { segment, segmentMode } = useCurrentEditorState();
@@ -25,7 +27,7 @@ const AddTab = ({
return (
onCloseClick(e)}
title={`New ${segment === EditorEntityTab.JS ? "JS" : "Query"}`}
diff --git a/app/client/src/pages/Editor/IDE/EditorTabs/FileTabs.test.tsx b/app/client/src/pages/Editor/IDE/EditorTabs/FileTabs.test.tsx
index cf2aa76563b..7974bc3357b 100644
--- a/app/client/src/pages/Editor/IDE/EditorTabs/FileTabs.test.tsx
+++ b/app/client/src/pages/Editor/IDE/EditorTabs/FileTabs.test.tsx
@@ -1,8 +1,9 @@
import React from "react";
import { fireEvent, render } from "test/testUtils";
import FileTabs from "./FileTabs";
-import type { EntityItem } from "@appsmith/entities/IDE/constants";
+import { EditorState, type EntityItem } from "@appsmith/entities/IDE/constants";
import { PluginType } from "entities/Action";
+import { FocusEntity } from "navigation/FocusEntity";
describe("FileTabs", () => {
const mockTabs: EntityItem[] = [
@@ -14,11 +15,17 @@ describe("FileTabs", () => {
const mockNavigateToTab = jest.fn();
const mockOnClose = jest.fn();
+ const activeEntity = {
+ entity: FocusEntity.API,
+ id: "File 1",
+ appState: EditorState.EDITOR,
+ params: {},
+ };
it("renders tabs correctly", () => {
const { getByTestId, getByText } = render(
{
it("check tab click", () => {
const { getByTestId } = render(
{
it("check for close click", () => {
const { getByTestId } = render(
void;
onClose: (actionId?: string) => void;
- currentTab: string;
+ currentEntity: FocusEntityInfo;
+ isListActive?: boolean;
}
const FileTabs = (props: Props) => {
- const { currentTab, navigateToTab, onClose, tabs } = props;
+ const { currentEntity, isListActive, navigateToTab, onClose, tabs } = props;
const { segmentMode } = useCurrentEditorState();
- useEffect(() => {
- const activetab = document.querySelector(".editor-tab.active");
- if (activetab) {
- activetab.scrollIntoView({
- inline: "nearest",
- });
- }
- }, [tabs, segmentMode]);
-
const onCloseClick = (e: React.MouseEvent, id?: string) => {
e.stopPropagation();
onClose(id);
@@ -34,7 +30,11 @@ const FileTabs = (props: Props) => {
{tabs.map((tab: EntityItem) => (
navigateToTab(tab)}
onClose={(e) => onCloseClick(e, tab.key)}
diff --git a/app/client/src/pages/Editor/IDE/EditorTabs/index.tsx b/app/client/src/pages/Editor/IDE/EditorTabs/index.tsx
index 43e3e81e8c7..b3e1bd10773 100644
--- a/app/client/src/pages/Editor/IDE/EditorTabs/index.tsx
+++ b/app/client/src/pages/Editor/IDE/EditorTabs/index.tsx
@@ -1,5 +1,5 @@
import React, { useEffect, useState } from "react";
-import { useSelector } from "react-redux";
+import { shallowEqual, useSelector } from "react-redux";
import { Flex, ScrollArea, ToggleButton } from "design-system";
import { getIDEViewMode, getIsSideBySideEnabled } from "selectors/ideSelectors";
import type { EntityItem } from "@appsmith/entities/IDE/constants";
@@ -26,26 +26,35 @@ const EditorTabs = () => {
const ideViewMode = useSelector(getIDEViewMode);
const { segment, segmentMode } = useCurrentEditorState();
const { closeClickHandler, tabClickHandler } = useIDETabClickHandlers();
-
const tabsConfig = TabSelectors[segment];
- const files = useSelector(tabsConfig.tabsSelector);
+ const files = useSelector(tabsConfig.tabsSelector, shallowEqual);
const location = useLocation();
const currentEntity = identifyEntityFromPath(location.pathname);
- const activeTab = showListView
- ? ""
- : segmentMode === EditorEntityTabState.Add
- ? "add"
- : currentEntity.id;
+ // Turn off list view while changing segment, files
+ useEffect(() => {
+ setShowListView(false);
+ }, [currentEntity.id, currentEntity.entity, files, segmentMode]);
+
+ // Show list view if all tabs is closed
useEffect(() => {
if (files.length === 0 && segmentMode !== EditorEntityTabState.Add) {
setShowListView(true);
- } else if (showListView) {
- setShowListView(false);
}
- }, [files, segmentMode, showListView]);
+ }, [files, segmentMode, currentEntity.entity]);
+
+ // scroll to the active tab
+ useEffect(() => {
+ const activetab = document.querySelector(".editor-tab.active");
+ if (activetab) {
+ activetab.scrollIntoView({
+ inline: "nearest",
+ });
+ }
+ }, [files, segmentMode]);
+ // show border if add button is sticky
useEffect(() => {
const ele = document.querySelector(
'[data-testid="t--editor-tabs"] > [data-overlayscrollbars-viewport]',
@@ -98,12 +107,14 @@ const EditorTabs = () => {
>
From 296c9765746f377d31415cad66aff64c2110cf1c Mon Sep 17 00:00:00 2001
From: albinAppsmith <87797149+albinAppsmith@users.noreply.github.com>
Date: Tue, 25 Jun 2024 11:15:15 +0530
Subject: [PATCH 11/12] fix: cypress failures
---
.../IDE/IDE_Add_Pane_Interactions_spec.ts | 2 +-
.../cypress/support/Pages/IDE/FileTabs.ts | 4 ++-
app/client/src/IDE/Components/FileTab.tsx | 3 +-
.../IDE/EditorPane/JS/JSRender.test.tsx | 8 ++---
.../IDE/EditorPane/Query/QueryRender.test.tsx | 34 +++++++++----------
.../Editor/IDE/EditorTabs/FileTabs.test.tsx | 11 ++++--
app/client/src/utils/URLUtils.ts | 4 +++
7 files changed, 39 insertions(+), 27 deletions(-)
diff --git a/app/client/cypress/e2e/Regression/ClientSide/IDE/IDE_Add_Pane_Interactions_spec.ts b/app/client/cypress/e2e/Regression/ClientSide/IDE/IDE_Add_Pane_Interactions_spec.ts
index 0a1126ee299..e8bd59c4233 100644
--- a/app/client/cypress/e2e/Regression/ClientSide/IDE/IDE_Add_Pane_Interactions_spec.ts
+++ b/app/client/cypress/e2e/Regression/ClientSide/IDE/IDE_Add_Pane_Interactions_spec.ts
@@ -68,7 +68,7 @@ describe("IDE add pane interactions", { tags: ["@tag.IDE"] }, () => {
// check add pane
PageLeftPane.assertInAddView();
// close add tab
- FileTabs.closeTab("new");
+ FileTabs.closeTab("new_query");
// open add pane to add item
PageLeftPane.switchToAddNew();
// add item
diff --git a/app/client/cypress/support/Pages/IDE/FileTabs.ts b/app/client/cypress/support/Pages/IDE/FileTabs.ts
index 24bfa7bb53e..2557436a1b3 100644
--- a/app/client/cypress/support/Pages/IDE/FileTabs.ts
+++ b/app/client/cypress/support/Pages/IDE/FileTabs.ts
@@ -1,8 +1,10 @@
import { ObjectsRegistry } from "../../Objects/Registry";
+import { sanitizeString } from "../../../../src/utils/URLUtils";
class FileTabs {
locators = {
container: "[data-testid='t--editor-tabs']",
- tabName: (name: string) => `[data-testid='t--ide-tab-${name}']`,
+ tabName: (name: string) =>
+ `[data-testid='t--ide-tab-${sanitizeString(name)}']`,
tabs: ".editor-tab",
addItem: "[data-testid='t--ide-tabs-add-button']",
closeTab: "[data-testid='t--tab-close-btn']",
diff --git a/app/client/src/IDE/Components/FileTab.tsx b/app/client/src/IDE/Components/FileTab.tsx
index af2012b0fe3..ec32b773966 100644
--- a/app/client/src/IDE/Components/FileTab.tsx
+++ b/app/client/src/IDE/Components/FileTab.tsx
@@ -3,6 +3,7 @@ import styled from "styled-components";
import clsx from "classnames";
import { Flex, Icon } from "design-system";
+import { sanitizeString } from "utils/URLUtils";
interface FileTabProps {
isActive: boolean;
@@ -80,7 +81,7 @@ export const FileTab = ({
return (
{icon ? {icon} : null}
diff --git a/app/client/src/pages/Editor/IDE/EditorPane/JS/JSRender.test.tsx b/app/client/src/pages/Editor/IDE/EditorPane/JS/JSRender.test.tsx
index 9990efc79d6..848999f4266 100644
--- a/app/client/src/pages/Editor/IDE/EditorPane/JS/JSRender.test.tsx
+++ b/app/client/src/pages/Editor/IDE/EditorPane/JS/JSRender.test.tsx
@@ -151,7 +151,7 @@ describe("IDE Render: JS", () => {
).toBe(true);
// Tabs active state
expect(
- getByTestId("t--ide-tab-JSObject1").classList.contains("active"),
+ getByTestId("t--ide-tab-jsobject1").classList.contains("active"),
).toBe(true);
// Check if the form is rendered
expect(container.querySelector(".js-editor-tab")).not.toBeNull();
@@ -201,7 +201,7 @@ describe("IDE Render: JS", () => {
expect(getAllByText("JSObject2").length).toBe(2);
// Tabs active state
expect(
- getByTestId("t--ide-tab-JSObject2").classList.contains("active"),
+ getByTestId("t--ide-tab-jsobject2").classList.contains("active"),
).toBe(true);
// Check if the form is rendered
@@ -245,7 +245,7 @@ describe("IDE Render: JS", () => {
expect(getAllByText("JSObject3").length).toEqual(2);
// Tabs active state
expect(
- getByTestId("t--ide-tab-JSObject3").classList.contains("active"),
+ getByTestId("t--ide-tab-jsobject3").classList.contains("active"),
).toBe(false);
// Check js object is not rendered. Instead new tab should render
expect(container.querySelector(".js-editor-tab")).toBeNull();
@@ -283,7 +283,7 @@ describe("IDE Render: JS", () => {
expect(getAllByText("JSObject4").length).toEqual(1);
// Tabs active state
expect(
- getByTestId("t--ide-tab-JSObject4").classList.contains("active"),
+ getByTestId("t--ide-tab-jsobject4").classList.contains("active"),
).toBe(false);
// Check if the form is not rendered
diff --git a/app/client/src/pages/Editor/IDE/EditorPane/Query/QueryRender.test.tsx b/app/client/src/pages/Editor/IDE/EditorPane/Query/QueryRender.test.tsx
index 186ae24fdfb..2bd611ae258 100644
--- a/app/client/src/pages/Editor/IDE/EditorPane/Query/QueryRender.test.tsx
+++ b/app/client/src/pages/Editor/IDE/EditorPane/Query/QueryRender.test.tsx
@@ -88,7 +88,7 @@ describe("IDE URL rendering of Queries", () => {
getByText("New datasource");
getByText("REST API");
// Check new tab presence
- const newTab = getByTestId("t--ide-tab-new");
+ const newTab = getByTestId("t--ide-tab-new_query");
expect(newTab).not.toBeNull();
// Close button is rendered
expect(
@@ -121,7 +121,7 @@ describe("IDE URL rendering of Queries", () => {
getByText("New datasource");
getByText("REST API");
// Check new tab presence
- const newTab = getByTestId("t--ide-tab-new");
+ const newTab = getByTestId("t--ide-tab-new_query");
expect(newTab).not.toBeNull();
// Close button is rendered
expect(
@@ -161,7 +161,7 @@ describe("IDE URL rendering of Queries", () => {
getByTestId("t--entity-item-Api1").classList.contains("active"),
).toBe(true);
// Tabs active state
- expect(getByTestId("t--ide-tab-Api1").classList.contains("active")).toBe(
+ expect(getByTestId("t--ide-tab-api1").classList.contains("active")).toBe(
true,
);
// Check if the form is rendered
@@ -205,7 +205,7 @@ describe("IDE URL rendering of Queries", () => {
// Check if api is rendered in side by side
expect(getAllByText("Api2").length).toBe(2);
// Tabs active state
- expect(getByTestId("t--ide-tab-Api2").classList.contains("active")).toBe(
+ expect(getByTestId("t--ide-tab-api2").classList.contains("active")).toBe(
true,
);
// Check if the form is rendered
@@ -244,7 +244,7 @@ describe("IDE URL rendering of Queries", () => {
getByText("New datasource");
getByText("REST API");
// Check new tab presence
- const newTab = getByTestId("t--ide-tab-new");
+ const newTab = getByTestId("t--ide-tab-new_query");
expect(newTab).not.toBeNull();
// Close button is rendered
expect(
@@ -278,7 +278,7 @@ describe("IDE URL rendering of Queries", () => {
// There will be 1 Api4 text ( The tab )
expect(getAllByText("Api4").length).toEqual(1);
// Tabs active state
- expect(getByTestId("t--ide-tab-Api4").classList.contains("active")).toBe(
+ expect(getByTestId("t--ide-tab-api4").classList.contains("active")).toBe(
false,
);
// Add button should not present
@@ -291,7 +291,7 @@ describe("IDE URL rendering of Queries", () => {
getByText("New datasource");
getByText("REST API");
// Check new tab presence
- const newTab = getByTestId("t--ide-tab-new");
+ const newTab = getByTestId("t--ide-tab-new_query");
expect(newTab).not.toBeNull();
// Close button is rendered
expect(
@@ -336,7 +336,7 @@ describe("IDE URL rendering of Queries", () => {
).toBe(true);
// Tabs active state
expect(
- getByTestId("t--ide-tab-Query1").classList.contains("active"),
+ getByTestId("t--ide-tab-query1").classList.contains("active"),
).toBe(true);
await userEvent.click(getByRole("tab", { name: "Query" }));
@@ -384,7 +384,7 @@ describe("IDE URL rendering of Queries", () => {
expect(getAllByText("Query2").length).toBe(2);
// Tabs active state
expect(
- getByTestId("t--ide-tab-Query2").classList.contains("active"),
+ getByTestId("t--ide-tab-query2").classList.contains("active"),
).toBe(true);
await userEvent.click(getByRole("tab", { name: "Query" }));
@@ -430,7 +430,7 @@ describe("IDE URL rendering of Queries", () => {
getByText("New datasource");
getByText("REST API");
// Check new tab presence
- const newTab = getByTestId("t--ide-tab-new");
+ const newTab = getByTestId("t--ide-tab-new_query");
expect(newTab).not.toBeNull();
// Close button is rendered
expect(
@@ -469,7 +469,7 @@ describe("IDE URL rendering of Queries", () => {
expect(getAllByText("Query4").length).toEqual(1);
// Tabs active state
expect(
- getByTestId("t--ide-tab-Query4").classList.contains("active"),
+ getByTestId("t--ide-tab-query4").classList.contains("active"),
).toBe(false);
// Add button should not present
expect(queryByTestId("t--ide-tabs-add-button")).toBeNull();
@@ -481,7 +481,7 @@ describe("IDE URL rendering of Queries", () => {
getByText("New datasource");
getByText("REST API");
// Check new tab presence
- const newTab = getByTestId("t--ide-tab-new");
+ const newTab = getByTestId("t--ide-tab-new_query");
expect(newTab).not.toBeNull();
// Close button is rendered
expect(
@@ -527,7 +527,7 @@ describe("IDE URL rendering of Queries", () => {
).toBe(true);
// Tabs active state
expect(
- getByTestId("t--ide-tab-Sheets1").classList.contains("active"),
+ getByTestId("t--ide-tab-sheets1").classList.contains("active"),
).toBe(true);
await userEvent.click(getByRole("tab", { name: "Query" }));
@@ -576,7 +576,7 @@ describe("IDE URL rendering of Queries", () => {
expect(getAllByText("Sheets2").length).toBe(2);
// Tabs active state
expect(
- getByTestId("t--ide-tab-Sheets2").classList.contains("active"),
+ getByTestId("t--ide-tab-sheets2").classList.contains("active"),
).toBe(true);
await userEvent.click(getByRole("tab", { name: "Query" }));
@@ -625,7 +625,7 @@ describe("IDE URL rendering of Queries", () => {
getByText("New datasource");
getByText("REST API");
// Check new tab presence
- const newTab = getByTestId("t--ide-tab-new");
+ const newTab = getByTestId("t--ide-tab-new_query");
expect(newTab).not.toBeNull();
// Close button is rendered
expect(
@@ -665,7 +665,7 @@ describe("IDE URL rendering of Queries", () => {
expect(getAllByText("Sheets4").length).toEqual(1);
// Tabs active state
expect(
- getByTestId("t--ide-tab-Sheets4").classList.contains("active"),
+ getByTestId("t--ide-tab-sheets4").classList.contains("active"),
).toBe(false);
// Add button active state
expect(queryByTestId("t--ide-tabs-add-button")).toBeNull();
@@ -677,7 +677,7 @@ describe("IDE URL rendering of Queries", () => {
getByText("New datasource");
getByText("REST API");
// Check new tab presence
- const newTab = getByTestId("t--ide-tab-new");
+ const newTab = getByTestId("t--ide-tab-new_query");
expect(newTab).not.toBeNull();
// Close button is rendered
expect(
diff --git a/app/client/src/pages/Editor/IDE/EditorTabs/FileTabs.test.tsx b/app/client/src/pages/Editor/IDE/EditorTabs/FileTabs.test.tsx
index 7974bc3357b..67612352abe 100644
--- a/app/client/src/pages/Editor/IDE/EditorTabs/FileTabs.test.tsx
+++ b/app/client/src/pages/Editor/IDE/EditorTabs/FileTabs.test.tsx
@@ -4,6 +4,7 @@ import FileTabs from "./FileTabs";
import { EditorState, type EntityItem } from "@appsmith/entities/IDE/constants";
import { PluginType } from "entities/Action";
import { FocusEntity } from "navigation/FocusEntity";
+import { sanitizeString } from "utils/URLUtils";
describe("FileTabs", () => {
const mockTabs: EntityItem[] = [
@@ -37,7 +38,7 @@ describe("FileTabs", () => {
// Check if each tab is rendered with correct content
mockTabs.forEach((tab) => {
- const tabElement = getByTestId(`t--ide-tab-${tab.title}`);
+ const tabElement = getByTestId(`t--ide-tab-${sanitizeString(tab.title)}`);
expect(tabElement).not.toBeNull();
const tabTitleElement = getByText(tab.title);
@@ -54,7 +55,9 @@ describe("FileTabs", () => {
tabs={mockTabs}
/>,
);
- const tabElement = getByTestId(`t--ide-tab-${mockTabs[0].title}`);
+ const tabElement = getByTestId(
+ `t--ide-tab-${sanitizeString(mockTabs[0].title)}`,
+ );
fireEvent.click(tabElement);
expect(mockNavigateToTab).toHaveBeenCalledWith(mockTabs[0]);
@@ -69,7 +72,9 @@ describe("FileTabs", () => {
tabs={mockTabs}
/>,
);
- const tabElement = getByTestId(`t--ide-tab-${mockTabs[1].title}`);
+ const tabElement = getByTestId(
+ `t--ide-tab-${sanitizeString(mockTabs[1].title)}`,
+ );
const closeElement = tabElement.querySelector(
"[data-testid='t--tab-close-btn']",
) as HTMLElement;
diff --git a/app/client/src/utils/URLUtils.ts b/app/client/src/utils/URLUtils.ts
index 55b6b1a2d3e..b986f8aeb37 100644
--- a/app/client/src/utils/URLUtils.ts
+++ b/app/client/src/utils/URLUtils.ts
@@ -39,3 +39,7 @@ export function matchesURLPattern(url: string) {
) !== null
);
}
+
+export const sanitizeString = (str: string): string => {
+ return str.toLowerCase().replace(/[^a-z0-9]/g, "_");
+};
From fb8addb5a6fae5c9d68c0164d8332105bfa88ec9 Mon Sep 17 00:00:00 2001
From: albinAppsmith <87797149+albinAppsmith@users.noreply.github.com>
Date: Tue, 25 Jun 2024 15:09:25 +0530
Subject: [PATCH 12/12] fix: jest test fix
---
app/client/src/pages/Editor/IDE/EditorTabs/FileTabs.test.tsx | 3 ---
1 file changed, 3 deletions(-)
diff --git a/app/client/src/pages/Editor/IDE/EditorTabs/FileTabs.test.tsx b/app/client/src/pages/Editor/IDE/EditorTabs/FileTabs.test.tsx
index 67612352abe..be5f41c683a 100644
--- a/app/client/src/pages/Editor/IDE/EditorTabs/FileTabs.test.tsx
+++ b/app/client/src/pages/Editor/IDE/EditorTabs/FileTabs.test.tsx
@@ -33,9 +33,6 @@ describe("FileTabs", () => {
/>,
);
- const editorTabsContainer = getByTestId("t--editor-tabs");
- expect(editorTabsContainer).not.toBeNull();
-
// Check if each tab is rendered with correct content
mockTabs.forEach((tab) => {
const tabElement = getByTestId(`t--ide-tab-${sanitizeString(tab.title)}`);