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 93a644fbe31..0a1126ee299 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
@@ -5,6 +5,7 @@ import EditorNavigation, {
} from "../../../../support/Pages/EditorNavigation";
import { ObjectsRegistry } from "../../../../support/Objects/Registry";
import FileTabs from "../../../../support/Pages/IDE/FileTabs";
+import AddView from "../../../../support/Pages/IDE/AddView";
const agHelper = ObjectsRegistry.AggregateHelper;
const commonLocators = ObjectsRegistry.CommonLocators;
@@ -66,8 +67,8 @@ describe("IDE add pane interactions", { tags: ["@tag.IDE"] }, () => {
PageLeftPane.switchToAddNew();
// check add pane
PageLeftPane.assertInAddView();
- // close add pane
- PageLeftPane.closeAddView();
+ // close add tab
+ FileTabs.closeTab("new");
// open add pane to add item
PageLeftPane.switchToAddNew();
// add item
diff --git a/app/client/cypress/support/Pages/AggregateHelper.ts b/app/client/cypress/support/Pages/AggregateHelper.ts
index ac156b1c21a..aeba30a4acc 100644
--- a/app/client/cypress/support/Pages/AggregateHelper.ts
+++ b/app/client/cypress/support/Pages/AggregateHelper.ts
@@ -1806,4 +1806,18 @@ export class AggregateHelper {
// }
// return items;
// }, { timeout: 5000 });
+
+ public GetChildrenNClick(
+ selector: string,
+ childSelector: string,
+ index = 0,
+ force = false,
+ waitTimeInterval = 500,
+ ctrlKey = false,
+ ) {
+ return this.ScrollIntoView(selector, index)
+ .children(childSelector)
+ .click({ force: force, ctrlKey: ctrlKey })
+ .wait(waitTimeInterval);
+ }
}
diff --git a/app/client/cypress/support/Pages/EntityExplorer.ts b/app/client/cypress/support/Pages/EntityExplorer.ts
index e48751444ba..7a8386f8b59 100644
--- a/app/client/cypress/support/Pages/EntityExplorer.ts
+++ b/app/client/cypress/support/Pages/EntityExplorer.ts
@@ -8,6 +8,7 @@ import EditorNavigation, {
PageLeftPane,
PagePaneSegment,
} from "./EditorNavigation";
+import AddView from "./IDE/AddView";
import PageList from "./PageList";
type templateActions =
@@ -247,8 +248,7 @@ export class EntityExplorer {
this.agHelper.ClickOutside(); //to close the evaluated pop-up
PageLeftPane.switchSegment(PagePaneSegment.Queries);
PageLeftPane.switchToAddNew();
- let overlayItem = this._visibleTextSpan(dsName);
- this.agHelper.GetNClick(overlayItem);
+ AddView.clickCreateOption(dsName);
}
public CopyPasteWidget(widgetName: string) {
diff --git a/app/client/cypress/support/Pages/IDE/AddView.ts b/app/client/cypress/support/Pages/IDE/AddView.ts
index cedba70bec3..cc6cde95db1 100644
--- a/app/client/cypress/support/Pages/IDE/AddView.ts
+++ b/app/client/cypress/support/Pages/IDE/AddView.ts
@@ -2,8 +2,10 @@ import { ObjectsRegistry } from "../../Objects/Registry";
class AddView {
public locators = {
+ addPane: "[data-testid='t--ide-add-pane']",
closePaneButton: "[data-testid='t--add-pane-close-icon']",
- createOption: "[data-testid='t--create-option']",
+ createOption: (name: string) =>
+ ".t--datasoucre-create-option-" + name.toLowerCase().replace(/ /g, "_"),
};
constructor() {
@@ -12,7 +14,7 @@ class AddView {
public assertInAddView() {
ObjectsRegistry.AggregateHelper.AssertElementVisibility(
- this.locators.closePaneButton,
+ this.locators.addPane,
);
}
@@ -20,9 +22,9 @@ class AddView {
ObjectsRegistry.AggregateHelper.GetNClick(this.locators.closePaneButton);
}
- public getCreateOptions(): Cypress.Chainable {
- return cy.get(this.locators.createOption);
+ public clickCreateOption(name: string) {
+ ObjectsRegistry.AggregateHelper.GetNClick(this.locators.createOption(name));
}
}
-export default AddView;
+export default new AddView();
diff --git a/app/client/cypress/support/Pages/IDE/FileTabs.ts b/app/client/cypress/support/Pages/IDE/FileTabs.ts
index 7eb95702114..24bfa7bb53e 100644
--- a/app/client/cypress/support/Pages/IDE/FileTabs.ts
+++ b/app/client/cypress/support/Pages/IDE/FileTabs.ts
@@ -4,7 +4,8 @@ class FileTabs {
container: "[data-testid='t--editor-tabs']",
tabName: (name: string) => `[data-testid='t--ide-tab-${name}']`,
tabs: ".editor-tab",
- addItem: "[data-testid='t--ide-split-screen-add-button']",
+ addItem: "[data-testid='t--ide-tabs-add-button']",
+ closeTab: "[data-testid='t--tab-close-btn']",
};
assertVisibility() {
@@ -32,6 +33,17 @@ class FileTabs {
}
});
}
+
+ closeTab(name: string) {
+ const tab = this.locators.tabName(name);
+ ObjectsRegistry.AggregateHelper.HoverElement(tab);
+ ObjectsRegistry.AggregateHelper.GetChildrenNClick(
+ tab,
+ this.locators.closeTab,
+ 0,
+ true,
+ );
+ }
}
export default new FileTabs();
diff --git a/app/client/cypress/support/Pages/IDE/LeftPane.ts b/app/client/cypress/support/Pages/IDE/LeftPane.ts
index 09c52297204..d0d0903f620 100644
--- a/app/client/cypress/support/Pages/IDE/LeftPane.ts
+++ b/app/client/cypress/support/Pages/IDE/LeftPane.ts
@@ -1,5 +1,7 @@
import { ObjectsRegistry } from "../../Objects/Registry";
+import { PagePaneSegment } from "../EditorNavigation";
import AddView from "./AddView";
+import FileTabs from "./FileTabs";
import ListView from "./ListView";
export class LeftPane {
@@ -15,8 +17,6 @@ export class LeftPane {
activeItemSelector: "",
selector: "",
};
-
- private addView: AddView;
private listView: ListView;
constructor(
@@ -29,7 +29,6 @@ export class LeftPane {
this.segments = segments;
this.locators.selector = selector;
this.locators.activeItemSelector = activeItemSelector;
- this.addView = new AddView();
this.listView = new ListView();
}
@@ -109,15 +108,15 @@ export class LeftPane {
}
public assertInAddView() {
- this.addView.assertInAddView();
+ AddView.assertInAddView();
}
public closeAddView() {
- this.addView.closeAddView();
+ AddView.closeAddView();
}
- public getCreateOptions() {
- return this.addView.getCreateOptions();
+ public clickCreateOption(name: string) {
+ return AddView.clickCreateOption(name);
}
public assertInListView() {
diff --git a/app/client/src/ce/constants/messages.ts b/app/client/src/ce/constants/messages.ts
index e7e310e2dde..ed1269c6291 100644
--- a/app/client/src/ce/constants/messages.ts
+++ b/app/client/src/ce/constants/messages.ts
@@ -2326,9 +2326,9 @@ export const EDITOR_PANE_TEXTS = {
js_add_button: () => "New JS object",
js_blank_object_item: () => "Blank JS object",
widget_add_button: () => "New UI element",
- query_create_tab_title: () => "Create new query / API",
+ query_create_tab_title: () => "Create new query from",
widgets_create_tab_title: () => "Drag & drop UI elements",
- js_create_tab_title: () => "Create JS object",
+ js_create_tab_title: () => "Create JS object from",
queries_create_from_existing: () => "From existing datasource",
queries_create_new: () => "New API",
loading_building_blocks: () => "Loading building blocks",
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 04992169650..71130f46e1c 100644
--- a/app/client/src/ce/pages/Editor/IDE/EditorPane/JS/hooks.ts
+++ b/app/client/src/ce/pages/Editor/IDE/EditorPane/JS/hooks.ts
@@ -7,16 +7,12 @@ import { createMessage, EDITOR_PANE_TEXTS } from "@appsmith/constants/messages";
import { JsFileIconV2 } from "pages/Editor/Explorer/ExplorerIcons";
import { SEARCH_ITEM_TYPES } from "components/editorComponents/GlobalSearch/utils";
import type { UseRoutes } from "@appsmith/entities/IDE/constants";
-import {
- EditorEntityTabState,
- EditorViewMode,
-} from "@appsmith/entities/IDE/constants";
+import { EditorViewMode } from "@appsmith/entities/IDE/constants";
import { getIDEViewMode, getIsSideBySideEnabled } from "selectors/ideSelectors";
import JSEditor from "pages/Editor/JSEditor";
import AddJS from "pages/Editor/IDE/EditorPane/JS/Add";
import { ADD_PATH } from "@appsmith/constants/routes/appRoutes";
import ListJS from "pages/Editor/IDE/EditorPane/JS/List";
-import { useCurrentEditorState } from "pages/Editor/IDE/hooks";
import history from "utils/history";
import { FocusEntity, identifyEntityFromPath } from "navigation/FocusEntity";
import { useModuleOptions } from "@appsmith/utils/moduleInstanceHelpers";
@@ -26,34 +22,29 @@ export const useJSAdd = () => {
const pageId = useSelector(getCurrentPageId);
const dispatch = useDispatch();
const currentEntityInfo = identifyEntityFromPath(location.pathname);
- const { segmentMode } = useCurrentEditorState();
const moduleCreationOptions = useModuleOptions();
const jsModuleCreationOptions = moduleCreationOptions.filter(
(opt) => opt.focusEntityType === FocusEntity.JS_MODULE_INSTANCE,
);
- return useCallback(() => {
+ const openAddJS = useCallback(() => {
if (jsModuleCreationOptions.length === 0) {
- if (segmentMode === EditorEntityTabState.Add) {
- const url = getJSUrl(currentEntityInfo, false);
- history.push(url);
- } else {
- dispatch(createNewJSCollection(pageId, "ENTITY_EXPLORER"));
- }
+ dispatch(createNewJSCollection(pageId, "ENTITY_EXPLORER"));
} else {
- const url = getJSUrl(
- currentEntityInfo,
- !(segmentMode === EditorEntityTabState.Add),
- );
+ if (currentEntityInfo.entity === FocusEntity.JS_OBJECT_ADD) {
+ return;
+ }
+ const url = getJSUrl(currentEntityInfo, true);
history.push(url);
}
- }, [
- dispatch,
- pageId,
- segmentMode,
- currentEntityInfo,
- jsModuleCreationOptions,
- ]);
+ }, [jsModuleCreationOptions, pageId, dispatch, currentEntityInfo]);
+
+ const closeAddJS = useCallback(() => {
+ const url = getJSUrl(currentEntityInfo, false);
+ history.push(url);
+ }, [pageId, currentEntityInfo]);
+
+ return { openAddJS, closeAddJS };
};
export const useIsJSAddLoading = () => {
@@ -111,17 +102,11 @@ export const useJSSegmentRoutes = (path: string): UseRoutes => {
];
}
return [
- {
- exact: true,
- key: "AddJS",
- component: AddJS,
- path: [`${path}${ADD_PATH}`, `${path}/:collectionId${ADD_PATH}`],
- },
{
exact: false,
key: "ListJS",
component: ListJS,
- path: [path],
+ path: [path, `${path}${ADD_PATH}`, `${path}/:collectionId${ADD_PATH}`],
},
];
};
diff --git a/app/client/src/ce/pages/Editor/IDE/EditorPane/Query/hooks.ts b/app/client/src/ce/pages/Editor/IDE/EditorPane/Query/hooks.tsx
similarity index 85%
rename from app/client/src/ce/pages/Editor/IDE/EditorPane/Query/hooks.ts
rename to app/client/src/ce/pages/Editor/IDE/EditorPane/Query/hooks.tsx
index 450ddfd7de8..90b37aee232 100644
--- a/app/client/src/ce/pages/Editor/IDE/EditorPane/Query/hooks.ts
+++ b/app/client/src/ce/pages/Editor/IDE/EditorPane/Query/hooks.tsx
@@ -1,4 +1,4 @@
-import { useCallback, useMemo } from "react";
+import React, { useCallback, useMemo } from "react";
import history from "utils/history";
import { useLocation } from "react-router";
import { FocusEntity, identifyEntityFromPath } from "navigation/FocusEntity";
@@ -27,37 +27,39 @@ import {
import { SAAS_EDITOR_API_ID_PATH } from "pages/Editor/SaaSEditor/constants";
import ApiEditor from "pages/Editor/APIEditor";
import type { UseRoutes } from "@appsmith/entities/IDE/constants";
-import {
- EditorEntityTabState,
- EditorViewMode,
-} from "@appsmith/entities/IDE/constants";
+import { EditorViewMode } from "@appsmith/entities/IDE/constants";
import QueryEditor from "pages/Editor/QueryEditor";
import AddQuery from "pages/Editor/IDE/EditorPane/Query/Add";
import ListQuery from "pages/Editor/IDE/EditorPane/Query/List";
import type { AppState } from "@appsmith/reducers";
import keyBy from "lodash/keyBy";
import { getPluginEntityIcon } from "pages/Editor/Explorer/ExplorerIcons";
-import type { ListItemProps } from "design-system";
+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";
export const useQueryAdd = () => {
const location = useLocation();
const currentEntityInfo = identifyEntityFromPath(location.pathname);
const { segmentMode } = useCurrentEditorState();
- const addButtonClickHandler = useCallback(() => {
- let url = "";
- if (segmentMode === EditorEntityTabState.Add) {
- // Already in add mode, back to the previous active item
- url = getQueryUrl(currentEntityInfo, false);
- } else {
- url = getQueryUrl(currentEntityInfo);
+ const openAddQuery = useCallback(() => {
+ if (currentEntityInfo.entity === FocusEntity.QUERY_ADD) {
+ return;
}
+ let url = "";
+ url = getQueryUrl(currentEntityInfo);
+ history.push(url);
+ }, [currentEntityInfo, segmentMode, location]);
+
+ const closeAddQuery = useCallback(() => {
+ let url = "";
+ url = getQueryUrl(currentEntityInfo, false);
history.push(url);
- }, [currentEntityInfo, segmentMode]);
+ }, [currentEntityInfo, segmentMode, location]);
- return addButtonClickHandler;
+ return { openAddQuery, closeAddQuery };
};
export type GroupedAddOperations = Array<{
@@ -166,17 +168,11 @@ export const useQuerySegmentRoutes = (path: string): UseRoutes => {
];
}
return [
- {
- key: "AddQuery",
- exact: true,
- component: AddQuery,
- path: [`${path}${ADD_PATH}`, `${path}/:queryId${ADD_PATH}`],
- },
{
key: "ListQuery",
exact: false,
component: ListQuery,
- path: [path],
+ path: [path, `${path}${ADD_PATH}`, `${path}/:queryId${ADD_PATH}`],
},
];
};
@@ -202,17 +198,24 @@ export const useAddQueryListItems = () => {
const getListItems = (data: any[]) => {
return data.map((fileOperation) => {
+ const title =
+ fileOperation.entityExplorerTitle ||
+ fileOperation.dsName ||
+ fileOperation.title;
+ const className = createAddClassName(title);
const icon =
fileOperation.icon ||
(fileOperation.pluginId &&
getPluginEntityIcon(pluginGroups[fileOperation.pluginId]));
return {
startIcon: icon,
- title:
- fileOperation.entityExplorerTitle ||
- fileOperation.dsName ||
- fileOperation.title,
- description: !!fileOperation.isBeta ? "Beta" : "",
+ wrapperClassName: className,
+ title,
+ description: !!fileOperation.isBeta ? (
+ Beta
+ ) : (
+ ""
+ ),
descriptionType: "inline",
onClick: onCreateItemClick.bind(null, fileOperation),
} as ListItemProps;
diff --git a/app/client/src/ce/pages/Editor/IDE/EditorPane/__tests__/JS/JSSegment.test.tsx b/app/client/src/ce/pages/Editor/IDE/EditorPane/__tests__/JS/JSSegment.test.tsx
index f3e1e2875d6..a7cfa06dc47 100644
--- a/app/client/src/ce/pages/Editor/IDE/EditorPane/__tests__/JS/JSSegment.test.tsx
+++ b/app/client/src/ce/pages/Editor/IDE/EditorPane/__tests__/JS/JSSegment.test.tsx
@@ -43,7 +43,7 @@ describe("JS Segment", () => {
expect(result.current).toBeDefined();
act(() => {
- result.current();
+ result.current.openAddJS();
});
expect(mockDispatchFn).toBeCalledWith({
@@ -66,7 +66,7 @@ describe("JS Segment", () => {
// Call the function now from a different page
act(() => {
- result.current();
+ result.current.openAddJS();
});
// Now the creation action should have the new page id
diff --git a/app/client/src/ce/pages/Editor/IDE/MainPane/useRoutes.ts b/app/client/src/ce/pages/Editor/IDE/MainPane/useRoutes.ts
index 279e216572a..449bb799404 100644
--- a/app/client/src/ce/pages/Editor/IDE/MainPane/useRoutes.ts
+++ b/app/client/src/ce/pages/Editor/IDE/MainPane/useRoutes.ts
@@ -46,6 +46,8 @@ import { QueriesBlankState } from "pages/Editor/QueryEditor/QueriesBlankState";
import { useSelector } from "react-redux";
import { getIDEViewMode, getIsSideBySideEnabled } from "selectors/ideSelectors";
import { EditorViewMode } from "@appsmith/entities/IDE/constants";
+import { JSAddState } from "pages/Editor/JSEditor/JSAddState";
+import { QueriesAddState } from "pages/Editor/QueryEditor/QueriesAddState";
export interface RouteReturnType extends RouteProps {
key: string;
@@ -170,58 +172,61 @@ function useRoutes(path: string): RouteReturnType[] {
path: `${path}${BUILDER_CHECKLIST_PATH}`,
},
{
- key: "ApiEditor",
- component: ApiEditor,
+ key: "QueryEditorAdd",
+ component: QueriesAddState,
exact: true,
path: [
- `${path}${API_EDITOR_ID_PATH}`,
+ `${path}${QUERIES_EDITOR_BASE_PATH}${ADD_PATH}`,
+ `${path}${QUERIES_EDITOR_ID_ADD_PATH}`,
`${path}${API_EDITOR_ID_ADD_PATH}`,
+ `${path}${CURL_IMPORT_PAGE_PATH}${ADD_PATH}`,
+ `${path}${SAAS_EDITOR_API_ID_ADD_PATH}`,
],
},
+ {
+ key: "ApiEditor",
+ component: ApiEditor,
+ exact: true,
+ path: [`${path}${API_EDITOR_ID_PATH}`],
+ },
{
key: "QueryEditorList",
component: QueriesBlankState,
exact: true,
- path: [
- `${path}${QUERIES_EDITOR_BASE_PATH}`,
- `${path}${QUERIES_EDITOR_BASE_PATH}${ADD_PATH}`,
- ],
+ path: [`${path}${QUERIES_EDITOR_BASE_PATH}`],
},
{
key: "QueryEditor",
component: QueryEditor,
exact: true,
+ path: [`${path}${QUERIES_EDITOR_ID_PATH}`],
+ },
+ {
+ key: "JSEditorAdd",
+ component: JSAddState,
+ exact: true,
path: [
- `${path}${QUERIES_EDITOR_ID_PATH}`,
- `${path}${QUERIES_EDITOR_ID_ADD_PATH}`,
+ `${path}${JS_COLLECTION_EDITOR_PATH}${ADD_PATH}`,
+ `${path}${JS_COLLECTION_ID_PATH}${ADD_PATH}`,
],
},
{
key: "JSEditorList",
component: JSBlankState,
exact: true,
- path: [
- `${path}${JS_COLLECTION_EDITOR_PATH}`,
- `${path}${JS_COLLECTION_EDITOR_PATH}${ADD_PATH}`,
- ],
+ path: [`${path}${JS_COLLECTION_EDITOR_PATH}`],
},
{
key: "JSEditor File",
component: JSEditor,
exact: true,
- path: [
- `${path}${JS_COLLECTION_ID_PATH}`,
- `${path}${JS_COLLECTION_ID_PATH}${ADD_PATH}`,
- ],
+ path: [`${path}${JS_COLLECTION_ID_PATH}`],
},
{
key: "CurlImportEditor",
component: CurlImportEditor,
exact: true,
- path: [
- `${path}${CURL_IMPORT_PAGE_PATH}`,
- `${path}${CURL_IMPORT_PAGE_PATH}${ADD_PATH}`,
- ],
+ path: [`${path}${CURL_IMPORT_PAGE_PATH}`],
},
{
key: "SAASList",
@@ -239,10 +244,7 @@ function useRoutes(path: string): RouteReturnType[] {
key: "SAASEditor",
component: QueryEditor,
exact: true,
- path: [
- `${path}${SAAS_EDITOR_API_ID_PATH}`,
- `${path}${SAAS_EDITOR_API_ID_ADD_PATH}`,
- ],
+ path: [`${path}${SAAS_EDITOR_API_ID_PATH}`],
},
{
key: "DatasourceEditor",
diff --git a/app/client/src/pages/Editor/IDE/EditorPane/JS/Add.tsx b/app/client/src/pages/Editor/IDE/EditorPane/JS/Add.tsx
index 9d188bd1687..eb704e8eb3c 100644
--- a/app/client/src/pages/Editor/IDE/EditorPane/JS/Add.tsx
+++ b/app/client/src/pages/Editor/IDE/EditorPane/JS/Add.tsx
@@ -2,20 +2,18 @@ import React, { useCallback } from "react";
import SegmentAddHeader from "../components/SegmentAddHeader";
import { EDITOR_PANE_TEXTS } from "@appsmith/constants/messages";
import type { ListItemProps } from "design-system";
-import { Flex } from "design-system";
+import { Flex, Tag } from "design-system";
import { useDispatch, useSelector } from "react-redux";
import { getCurrentPageId } from "selectors/editorSelectors";
import GroupedList from "../components/GroupedList";
-import {
- useGroupedAddJsOperations,
- useJSAdd,
-} from "@appsmith/pages/Editor/IDE/EditorPane/JS/hooks";
+import { useGroupedAddJsOperations } from "@appsmith/pages/Editor/IDE/EditorPane/JS/hooks";
import type { ActionOperation } from "components/editorComponents/GlobalSearch/utils";
+import type { AddProps } from "../types/AddProps";
+import { createAddClassName } from "../utils";
-const AddJS = () => {
+const AddJS = ({ containerProps, innerContainerProps }: AddProps) => {
const dispatch = useDispatch();
const pageId = useSelector(getCurrentPageId);
- const closeButtonClickHandler = useJSAdd();
const groupedJsOperations = useGroupedAddJsOperations();
@@ -29,32 +27,47 @@ const AddJS = () => {
);
const getListItems = (data: ActionOperation) => {
+ const title = data.entityExplorerTitle || data.title;
return {
startIcon: data.icon,
- title: data.entityExplorerTitle || data.title,
- description: !!data.isBeta ? "Beta" : "",
+ title,
+ description: !!data.isBeta ? Beta : "",
descriptionType: "inline",
onClick: onCreateItemClick.bind(null, data),
+ wrapperClassName: createAddClassName(title),
} as ListItemProps;
};
return (
-
-
- ({
- groupTitle: op.title,
- className: op.className,
- items: op.operations.map(getListItems),
- }))}
- />
+
+
+
+
+ ({
+ groupTitle: op.title,
+ className: op.className,
+ items: op.operations.map(getListItems),
+ }))}
+ />
+
);
};
diff --git a/app/client/src/pages/Editor/IDE/EditorPane/JS/BlankState.tsx b/app/client/src/pages/Editor/IDE/EditorPane/JS/BlankState.tsx
index 4ed17367a69..411fcc2ebfb 100644
--- a/app/client/src/pages/Editor/IDE/EditorPane/JS/BlankState.tsx
+++ b/app/client/src/pages/Editor/IDE/EditorPane/JS/BlankState.tsx
@@ -16,7 +16,7 @@ const BlankState: React.FC = () => {
isFeatureEnabled,
pagePermissions,
);
- const addButtonClickHandler = useJSAdd();
+ const { openAddJS } = useJSAdd();
return (
{
buttonText={createMessage(EDITOR_PANE_TEXTS.js_add_button)}
description={createMessage(EDITOR_PANE_TEXTS.js_blank_state_description)}
icon={"js-square-v3"}
- onClick={canCreateActions ? addButtonClickHandler : undefined}
+ onClick={canCreateActions ? openAddJS : undefined}
/>
);
};
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 8485c729ac7..2ac2ba18063 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
@@ -69,7 +69,7 @@ describe("IDE Render: JS", () => {
});
it("Renders Fullscreen Add in Blank State", () => {
- const { getByRole, getByText } = render(
+ const { getByTestId, getByText } = render(
,
@@ -80,20 +80,20 @@ describe("IDE Render: JS", () => {
);
// Main pane text
- getByText(createMessage(EDITOR_PANE_TEXTS.js_blank_state));
-
- // Left pane header
getByText(createMessage(EDITOR_PANE_TEXTS.js_create_tab_title));
+ // Left pane description
+ getByText(createMessage(EDITOR_PANE_TEXTS.js_blank_state_description));
+
// Create options are rendered
getByText(createMessage(EDITOR_PANE_TEXTS.js_blank_object_item));
- // Close button is rendered
- getByRole("button", { name: "Close pane" });
+ // Tab close button is rendered
+ getByTestId("t--tab-close-btn");
});
it("Renders Split Screen Add in Blank State", () => {
const state = getIDETestState({ ideView: EditorViewMode.SplitScreen });
- const { getByRole, getByTestId, getByText } = render(
+ const { getByTestId, getByText } = render(
,
@@ -113,8 +113,6 @@ describe("IDE Render: JS", () => {
// Create options are rendered
getByText(createMessage(EDITOR_PANE_TEXTS.js_blank_object_item));
- // Close button is rendered
- getByRole("button", { name: "Close pane" });
});
});
@@ -212,7 +210,7 @@ describe("IDE Render: JS", () => {
// Check if run button is visible
getByRole("button", { name: /run/i });
// Check if the Add new button is shown
- getByTestId("t--ide-split-screen-add-button");
+ getByTestId("t--ide-tabs-add-button");
});
it("Renders JS add routes in Full Screen", () => {
@@ -230,17 +228,16 @@ describe("IDE Render: JS", () => {
},
});
- const { container, getAllByText, getByRole, getByTestId, getByText } =
- render(
-
-
- ,
- {
- url: "/app/applicationSlug/pageSlug-page_id/edit/jsObjects/js_id3/add",
- initialState: state,
- featureFlags: FeatureFlags,
- },
- );
+ const { container, getAllByText, getByTestId, getByText } = render(
+
+
+ ,
+ {
+ url: "/app/applicationSlug/pageSlug-page_id/edit/jsObjects/js_id3/add",
+ initialState: state,
+ featureFlags: FeatureFlags,
+ },
+ );
// There will be 2 JSObject3 text (editor tab and Editor form)
expect(getAllByText("JSObject3").length).toEqual(2);
@@ -248,17 +245,12 @@ describe("IDE Render: JS", () => {
expect(
getByTestId("t--ide-tab-JSObject3").classList.contains("active"),
).toBe(false);
- // Check if the form is rendered
- expect(container.querySelector(".js-editor-tab")).not.toBeNull();
- // Check if the code and settings tabs is visible
- getByRole("tab", { name: /code/i });
- getByRole("tab", { name: /settings/i });
- // Check if run button is visible
- getByRole("button", { name: /run/i });
+ // Check js object is not rendered. Instead new tab should render
+ expect(container.querySelector(".js-editor-tab")).toBeNull();
+ // Check is new tab is visible
+ getByText("New JS");
// Create options are rendered
getByText(createMessage(EDITOR_PANE_TEXTS.js_blank_object_item));
- // Close button is rendered
- getByRole("button", { name: "Close pane" });
});
it("Renders JS add routes in Split Screen", () => {
@@ -274,17 +266,16 @@ describe("IDE Render: JS", () => {
ideView: EditorViewMode.SplitScreen,
});
- const { container, getAllByText, getByRole, getByTestId, getByText } =
- render(
-
-
- ,
- {
- url: "/app/applicationSlug/pageSlug-page_id/edit/jsObjects/js_id4/add",
- initialState: state,
- featureFlags: FeatureFlags,
- },
- );
+ const { container, getAllByText, getByTestId, getByText } = render(
+
+
+ ,
+ {
+ url: "/app/applicationSlug/pageSlug-page_id/edit/jsObjects/js_id4/add",
+ initialState: state,
+ featureFlags: FeatureFlags,
+ },
+ );
// There will be 1 JSObject3 text ( The tab )
expect(getAllByText("JSObject4").length).toEqual(1);
@@ -292,19 +283,11 @@ describe("IDE Render: JS", () => {
expect(
getByTestId("t--ide-tab-JSObject4").classList.contains("active"),
).toBe(false);
- // Add button active state
- expect(
- getByTestId("t--ide-split-screen-add-button").getAttribute(
- "data-selected",
- ),
- ).toBe("true");
// Check if the form is not rendered
expect(container.querySelector(".js-editor-tab")).toBeNull();
// Create options are rendered
getByText(createMessage(EDITOR_PANE_TEXTS.js_blank_object_item));
- // Close button is rendered
- getByRole("button", { name: "Close pane" });
});
it("Prevents edit of main JS object", () => {
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 2956d611e34..ccf56595ff1 100644
--- a/app/client/src/pages/Editor/IDE/EditorPane/JS/List.tsx
+++ b/app/client/src/pages/Editor/IDE/EditorPane/JS/List.tsx
@@ -46,7 +46,7 @@ const ListJSObjects = () => {
pagePermissions,
);
- const addButtonClickHandler = useJSAdd();
+ const { openAddJS } = useJSAdd();
return (
{
);
diff --git a/app/client/src/pages/Editor/IDE/EditorTabs/FullScreenTabs.tsx b/app/client/src/pages/Editor/IDE/EditorTabs/FullScreenTabs.tsx
index fc5f292fd96..f9a3f14c5f0 100644
--- a/app/client/src/pages/Editor/IDE/EditorTabs/FullScreenTabs.tsx
+++ b/app/client/src/pages/Editor/IDE/EditorTabs/FullScreenTabs.tsx
@@ -16,6 +16,7 @@ import {
createMessage,
} from "@appsmith/constants/messages";
import AnalyticsUtil from "@appsmith/utils/AnalyticsUtil";
+import { AddButton } from "./AddButton";
const FullScreenTabs = () => {
const dispatch = useDispatch();
@@ -44,12 +45,13 @@ const FullScreenTabs = () => {
onClose={closeClickHandler}
tabs={files}
/>
+ {files.length > 0 ? : null}
{
,
);
});
@@ -43,7 +42,6 @@ describe("SearchableFilesList", () => {
,
);
@@ -62,7 +60,6 @@ describe("SearchableFilesList", () => {
,
);
@@ -82,7 +79,6 @@ describe("SearchableFilesList", () => {
,
);
@@ -102,7 +98,6 @@ describe("SearchableFilesList", () => {
,
);
diff --git a/app/client/src/pages/Editor/IDE/EditorTabs/SearchableFilesList.tsx b/app/client/src/pages/Editor/IDE/EditorTabs/SearchableFilesList.tsx
index 340e66d6424..8b058b55ebd 100644
--- a/app/client/src/pages/Editor/IDE/EditorTabs/SearchableFilesList.tsx
+++ b/app/client/src/pages/Editor/IDE/EditorTabs/SearchableFilesList.tsx
@@ -17,7 +17,6 @@ import { ListIconContainer, TabTextContainer } from "./StyledComponents";
interface Props {
allItems: EntityItem[];
- openTabs: EntityItem[];
navigateToTab: (item: EntityItem) => void;
}
diff --git a/app/client/src/pages/Editor/IDE/EditorTabs/SplitScreenTabs.tsx b/app/client/src/pages/Editor/IDE/EditorTabs/SplitScreenTabs.tsx
index 889e6fe89ac..dd4f490b1bc 100644
--- a/app/client/src/pages/Editor/IDE/EditorTabs/SplitScreenTabs.tsx
+++ b/app/client/src/pages/Editor/IDE/EditorTabs/SplitScreenTabs.tsx
@@ -1,75 +1,76 @@
-import React from "react";
-import { Flex, Spinner, ToggleButton } from "design-system";
+import React, { useCallback } from "react";
import FileTabs from "./FileTabs";
-import { useSelector } from "react-redux";
+import { useDispatch, useSelector } from "react-redux";
import { getIDEViewMode, getIsSideBySideEnabled } from "selectors/ideSelectors";
import Container from "./Container";
import { useCurrentEditorState, useIDETabClickHandlers } from "../hooks";
import {
EditorEntityTab,
- EditorEntityTabState,
EditorViewMode,
} from "@appsmith/entities/IDE/constants";
-import { useIsJSAddLoading } from "@appsmith/pages/Editor/IDE/EditorPane/JS/hooks";
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, segmentMode } = useCurrentEditorState();
- const { addClickHandler, closeClickHandler, tabClickHandler } =
- useIDETabClickHandlers();
- const isJSLoading = useIsJSAddLoading();
+ 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;
- const AddButton = () => {
- if (isJSLoading) {
- return (
-
-
-
- );
- }
- return (
-
- );
- };
-
return (
<>
- {files.length > 0 ? (
-
-
- 0 ? ( */}
+
+
+
+ {files.length > 0 ? : null}
+
+
+
-
-
- ) : null}
+
+
>
);
diff --git a/app/client/src/pages/Editor/IDE/EditorTabs/StyledComponents.tsx b/app/client/src/pages/Editor/IDE/EditorTabs/StyledComponents.tsx
index 51cbf22ce2e..d281a6bfbdb 100644
--- a/app/client/src/pages/Editor/IDE/EditorTabs/StyledComponents.tsx
+++ b/app/client/src/pages/Editor/IDE/EditorTabs/StyledComponents.tsx
@@ -56,6 +56,10 @@ export const StyledTab = styled(Flex)`
&:hover > .tab-close {
visibility: visible;
}
+
+ &.active > .tab-close {
+ visibility: visible;
+ }
`;
export const TabTextContainer = styled.span`
diff --git a/app/client/src/pages/Editor/IDE/hooks.ts b/app/client/src/pages/Editor/IDE/hooks.ts
index 9ef34a30803..cd2b4e9a2db 100644
--- a/app/client/src/pages/Editor/IDE/hooks.ts
+++ b/app/client/src/pages/Editor/IDE/hooks.ts
@@ -233,16 +233,16 @@ export function useWidgetSelectionBlockListener() {
export const useIDETabClickHandlers = () => {
const dispatch = useDispatch();
- const onJSAddClick = useJSAdd();
- const onQueryAddClick = useQueryAdd();
+ const { closeAddJS, openAddJS } = useJSAdd();
+ const { closeAddQuery, openAddQuery } = useQueryAdd();
const { segment, segmentMode } = useCurrentEditorState();
const tabsConfig = TabSelectors[segment];
const pageId = useSelector(getCurrentPageId);
const addClickHandler = useCallback(() => {
- if (segment === EditorEntityTab.JS) onJSAddClick();
- if (segment === EditorEntityTab.QUERIES) onQueryAddClick();
- }, [segment, segmentMode, onQueryAddClick, onJSAddClick]);
+ if (segment === EditorEntityTab.JS) openAddJS();
+ if (segment === EditorEntityTab.QUERIES) openAddQuery();
+ }, [segment, segmentMode, openAddQuery, openAddJS]);
const tabClickHandler = useCallback(
(item: EntityItem) => {
@@ -255,7 +255,11 @@ export const useIDETabClickHandlers = () => {
);
const closeClickHandler = useCallback(
- (actionId: string) => {
+ (actionId: string | undefined) => {
+ if (!actionId) {
+ // handle JS
+ return segment === EditorEntityTab.JS ? closeAddJS() : closeAddQuery();
+ }
if (segment === EditorEntityTab.JS)
dispatch(closeJSActionTab({ id: actionId, parentId: pageId }));
if (segment === EditorEntityTab.QUERIES)
diff --git a/app/client/src/pages/Editor/JSEditor/JSAddState.tsx b/app/client/src/pages/Editor/JSEditor/JSAddState.tsx
new file mode 100644
index 00000000000..6f10d21951f
--- /dev/null
+++ b/app/client/src/pages/Editor/JSEditor/JSAddState.tsx
@@ -0,0 +1,21 @@
+import React from "react";
+import { Flex } from "design-system";
+import AddJS from "pages/Editor/IDE/EditorPane/JS/Add";
+
+const JSAddState = () => {
+ return (
+
+
+
+ );
+};
+
+export { JSAddState };
diff --git a/app/client/src/pages/Editor/QueryEditor/QueriesAddState.tsx b/app/client/src/pages/Editor/QueryEditor/QueriesAddState.tsx
new file mode 100644
index 00000000000..97d7dfa99ac
--- /dev/null
+++ b/app/client/src/pages/Editor/QueryEditor/QueriesAddState.tsx
@@ -0,0 +1,21 @@
+import React from "react";
+import { Flex } from "design-system";
+import AddQuery from "pages/Editor/IDE/EditorPane/Query/Add";
+
+const QueriesAddState = () => {
+ return (
+
+
+
+ );
+};
+
+export { QueriesAddState };