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 e8bd59c4233b..0a1126ee2991 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_query"); + FileTabs.closeTab("new"); // 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 2557436a1b35..24bfa7bb53e1 100644 --- a/app/client/cypress/support/Pages/IDE/FileTabs.ts +++ b/app/client/cypress/support/Pages/IDE/FileTabs.ts @@ -1,10 +1,8 @@ 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-${sanitizeString(name)}']`, + tabName: (name: string) => `[data-testid='t--ide-tab-${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 deleted file mode 100644 index ec32b7739666..000000000000 --- a/app/client/src/IDE/Components/FileTab.tsx +++ /dev/null @@ -1,98 +0,0 @@ -import React from "react"; -import styled from "styled-components"; -import clsx from "classnames"; - -import { Flex, Icon } from "design-system"; -import { sanitizeString } from "utils/URLUtils"; - -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/ce/pages/Editor/IDE/EditorPane/JS/hooks.ts b/app/client/src/ce/pages/Editor/IDE/EditorPane/JS/hooks.ts index 6d5a2c96abb3..71130f46e1cf 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,7 +17,6 @@ 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); @@ -96,7 +95,7 @@ export const useJSSegmentRoutes = (path: string): UseRoutes => { }, { key: "JSEmpty", - component: JSBlankState, + component: ListJS, exact: true, path: [path], }, 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 3eedf95b8740..90b37aee232f 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,7 +38,6 @@ 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(); @@ -162,7 +161,7 @@ export const useQuerySegmentRoutes = (path: string): UseRoutes => { }, { key: "QueryEmpty", - component: QueriesBlankState, + component: ListQuery, exact: true, path: [path], }, diff --git a/app/client/src/ce/selectors/appIDESelectors.ts b/app/client/src/ce/selectors/appIDESelectors.ts index af37fe267181..dfd9faa67873 100644 --- a/app/client/src/ce/selectors/appIDESelectors.ts +++ b/app/client/src/ce/selectors/appIDESelectors.ts @@ -6,7 +6,6 @@ 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"; @@ -46,22 +45,28 @@ export const selectJSSegmentEditorList = createSelector( }, ); -export const selectJSSegmentEditorTabs = (state: AppState) => { - const items = getJSSegmentItems(state); - const tabs = getJSTabs(state); - - 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); +export const selectJSSegmentEditorTabs = createSelector( + getJSSegmentItems, + getJSTabs, + (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) => keyedItems[tab]).filter(Boolean); -}; +export const selectQuerySegmentEditorTabs = createSelector( + getQuerySegmentItems, + getQueryTabs, + (items, tabs) => { + const keyedItems = keyBy(items, "key"); + return tabs + .map((tab) => { + return keyedItems[tab]; + }) + .filter(Boolean); + }, +); diff --git a/app/client/src/pages/Editor/IDE/EditorPane/EditorPaneSegments.tsx b/app/client/src/pages/Editor/IDE/EditorPane/EditorPaneSegments.tsx index 5d44ec5edf28..c2daef1f8322 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"; +import EditorTabs from "../EditorTabs/SplitScreenTabs"; import { jsSegmentRoutes, querySegmentRoutes, @@ -17,23 +17,19 @@ 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} + { ).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/JS/List.tsx b/app/client/src/pages/Editor/IDE/EditorPane/JS/List.tsx index b3e21a8014eb..ccf56595ff1d 100644 --- a/app/client/src/pages/Editor/IDE/EditorPane/JS/List.tsx +++ b/app/client/src/pages/Editor/IDE/EditorPane/JS/List.tsx @@ -51,7 +51,6 @@ const ListJSObjects = () => { return ( { > { getByText("New datasource"); getByText("REST API"); // Check new tab presence - const newTab = getByTestId("t--ide-tab-new_query"); + const newTab = getByTestId("t--ide-tab-new"); 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_query"); + const newTab = getByTestId("t--ide-tab-new"); 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_query"); + const newTab = getByTestId("t--ide-tab-new"); 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_query"); + const newTab = getByTestId("t--ide-tab-new"); 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_query"); + const newTab = getByTestId("t--ide-tab-new"); 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_query"); + const newTab = getByTestId("t--ide-tab-new"); 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_query"); + const newTab = getByTestId("t--ide-tab-new"); 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_query"); + const newTab = getByTestId("t--ide-tab-new"); expect(newTab).not.toBeNull(); // Close button is rendered expect( diff --git a/app/client/src/pages/Editor/IDE/EditorTabs/AddTab.tsx b/app/client/src/pages/Editor/IDE/EditorTabs/AddTab.tsx deleted file mode 100644 index f5d3564a88bb..000000000000 --- a/app/client/src/pages/Editor/IDE/EditorTabs/AddTab.tsx +++ /dev/null @@ -1,38 +0,0 @@ -import React from "react"; - -import { FileTab } from "IDE/Components/FileTab"; -import { useCurrentEditorState } from "../hooks"; -import { - EditorEntityTab, - EditorEntityTabState, -} from "@appsmith/entities/IDE/constants"; - -const AddTab = ({ - isListActive, - newTabClickCallback, - onClose, -}: { - newTabClickCallback: () => void; - onClose: (actionId?: string) => void; - isListActive: boolean; -}) => { - 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/Container.tsx b/app/client/src/pages/Editor/IDE/EditorTabs/Container.tsx index dbc77dd103f6..b248f9e5f969 100644 --- a/app/client/src/pages/Editor/IDE/EditorTabs/Container.tsx +++ b/app/client/src/pages/Editor/IDE/EditorTabs/Container.tsx @@ -9,7 +9,6 @@ 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.test.tsx b/app/client/src/pages/Editor/IDE/EditorTabs/FileTabs.test.tsx index be5f41c683ac..8b00ea582459 100644 --- a/app/client/src/pages/Editor/IDE/EditorTabs/FileTabs.test.tsx +++ b/app/client/src/pages/Editor/IDE/EditorTabs/FileTabs.test.tsx @@ -1,10 +1,8 @@ import React from "react"; import { fireEvent, render } from "test/testUtils"; import FileTabs from "./FileTabs"; -import { EditorState, type EntityItem } from "@appsmith/entities/IDE/constants"; +import 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[] = [ @@ -16,26 +14,22 @@ 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( , ); + 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)}`); + const tabElement = getByTestId(`t--ide-tab-${tab.title}`); expect(tabElement).not.toBeNull(); const tabTitleElement = getByText(tab.title); @@ -46,15 +40,12 @@ describe("FileTabs", () => { it("check tab click", () => { const { getByTestId } = render( , ); - const tabElement = getByTestId( - `t--ide-tab-${sanitizeString(mockTabs[0].title)}`, - ); + const tabElement = getByTestId(`t--ide-tab-${mockTabs[0].title}`); fireEvent.click(tabElement); expect(mockNavigateToTab).toHaveBeenCalledWith(mockTabs[0]); @@ -63,15 +54,12 @@ describe("FileTabs", () => { it("check for close click", () => { const { getByTestId } = render( , ); - const tabElement = getByTestId( - `t--ide-tab-${sanitizeString(mockTabs[1].title)}`, - ); + const tabElement = getByTestId(`t--ide-tab-${mockTabs[1].title}`); const closeElement = tabElement.querySelector( "[data-testid='t--tab-close-btn']", ) as HTMLElement; diff --git a/app/client/src/pages/Editor/IDE/EditorTabs/FileTabs.tsx b/app/client/src/pages/Editor/IDE/EditorTabs/FileTabs.tsx index 215ccca50c17..90499d2b984f 100644 --- a/app/client/src/pages/Editor/IDE/EditorTabs/FileTabs.tsx +++ b/app/client/src/pages/Editor/IDE/EditorTabs/FileTabs.tsx @@ -1,24 +1,54 @@ -import React from "react"; +import React, { useEffect } from "react"; +import { useLocation } from "react-router"; +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 { identifyEntityFromPath } from "navigation/FocusEntity"; import { useCurrentEditorState } from "../hooks"; -import { FileTab } from "IDE/Components/FileTab"; -import type { FocusEntityInfo } from "navigation/FocusEntity"; interface Props { tabs: EntityItem[]; navigateToTab: (tab: EntityItem) => void; onClose: (actionId?: string) => void; - currentEntity: FocusEntityInfo; - isListActive?: boolean; } +const FILE_TABS_CONTAINER_ID = "file-tabs-container"; + const FileTabs = (props: Props) => { - const { currentEntity, isListActive, navigateToTab, onClose, tabs } = props; - const { segmentMode } = useCurrentEditorState(); + const { 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) { + activetab.scrollIntoView({ + inline: "nearest", + }); + } + }, [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(); @@ -26,22 +56,59 @@ const FileTabs = (props: Props) => { }; return ( - <> - {tabs.map((tab: EntityItem) => ( - navigateToTab(tab)} - onClose={(e) => onCloseClick(e, tab.key)} - title={tab.title} - /> - ))} - + + + {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} + + ); }; diff --git a/app/client/src/pages/Editor/IDE/EditorTabs/FullScreenTabs.tsx b/app/client/src/pages/Editor/IDE/EditorTabs/FullScreenTabs.tsx new file mode 100644 index 000000000000..f9a3f14c5f0f --- /dev/null +++ b/app/client/src/pages/Editor/IDE/EditorTabs/FullScreenTabs.tsx @@ -0,0 +1,67 @@ +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} + +