diff --git a/app/client/packages/design-system/ads/src/Templates/EntityExplorer/EmptyState/EmptyState.mdx b/app/client/packages/design-system/ads/src/Templates/EntityExplorer/EmptyState/EmptyState.mdx
new file mode 100644
index 0000000000..3eef0d1cb2
--- /dev/null
+++ b/app/client/packages/design-system/ads/src/Templates/EntityExplorer/EmptyState/EmptyState.mdx
@@ -0,0 +1,35 @@
+import { Canvas, Meta } from "@storybook/blocks";
+
+import * as EmptyStateStories from "./EmptyState.stories";
+
+
+
+# Empty State
+
+A placeholder for when there is no data to display. It can be used to guide users on what to do next.
+
+## Anatomy
+
+icon: The icon of the file type or the entity type that is being displayed.
+
+description: The details of the empty state. It should be a short and clear message.
+
+button: A button that can be used to trigger an action. This is optional.
+
+### Default implementation
+
+Below is the default implementation of the Empty State component. It does not have a button.
+
+
+
+### With Button
+
+Button kind can be supplied. If no kind is supplied, default is "secondary".
+
+
+
+### With Button but no onClick is supplied
+
+onClick is optional. If not supplied, the button will not be shown.
+
+
diff --git a/app/client/packages/design-system/ads/src/Templates/EntityExplorer/EmptyState/EmptyState.stories.tsx b/app/client/packages/design-system/ads/src/Templates/EntityExplorer/EmptyState/EmptyState.stories.tsx
new file mode 100644
index 0000000000..9b756418db
--- /dev/null
+++ b/app/client/packages/design-system/ads/src/Templates/EntityExplorer/EmptyState/EmptyState.stories.tsx
@@ -0,0 +1,54 @@
+/* eslint-disable no-console */
+import React from "react";
+import type { Meta, StoryObj } from "@storybook/react";
+
+import { EmptyState, type EmptyStateProps } from ".";
+
+const meta: Meta = {
+ title: "ADS/Templates/Entity Explorer/Empty State",
+ component: EmptyState,
+};
+
+export default meta;
+
+const Template = (props: EmptyStateProps) => {
+ const { button, description, icon } = props;
+
+ return (
+
+ );
+};
+
+export const Basic = Template.bind({}) as StoryObj;
+
+Basic.args = {
+ description: "No data available",
+ icon: "folder-line",
+};
+
+export const WithButton = Template.bind({}) as StoryObj;
+
+WithButton.args = {
+ description: "No data available",
+ icon: "file-line",
+ button: {
+ text: "Add new",
+ onClick: () => console.log("Add clicked"),
+ },
+};
+
+export const WithButtonWithoutOnClick = Template.bind({}) as StoryObj;
+
+WithButtonWithoutOnClick.args = {
+ description: "No data available",
+ icon: "file-line",
+ button: {
+ text: "Add new",
+ },
+};
diff --git a/app/client/packages/design-system/ads/src/Templates/EntityExplorer/EmptyState/EmptyState.tsx b/app/client/packages/design-system/ads/src/Templates/EntityExplorer/EmptyState/EmptyState.tsx
new file mode 100644
index 0000000000..269bc1ecdc
--- /dev/null
+++ b/app/client/packages/design-system/ads/src/Templates/EntityExplorer/EmptyState/EmptyState.tsx
@@ -0,0 +1,48 @@
+import React from "react";
+import { Button, Flex, Icon, Text } from "../../..";
+import type { EmptyStateProps } from "./EmptyState.types";
+
+const EmptyState = ({ button, description, icon }: EmptyStateProps) => {
+ return (
+
+
+
+
+
+ {description}
+
+ {button && button.onClick ? (
+
+ ) : null}
+
+ );
+};
+
+export { EmptyState };
diff --git a/app/client/packages/design-system/ads/src/Templates/EntityExplorer/EmptyState/EmptyState.types.ts b/app/client/packages/design-system/ads/src/Templates/EntityExplorer/EmptyState/EmptyState.types.ts
new file mode 100644
index 0000000000..e77047e508
--- /dev/null
+++ b/app/client/packages/design-system/ads/src/Templates/EntityExplorer/EmptyState/EmptyState.types.ts
@@ -0,0 +1,13 @@
+import { type IconNames, type ButtonKind } from "../../..";
+
+export interface EmptyStateProps {
+ icon: IconNames;
+ description: string;
+ button?: {
+ text: string;
+ onClick?: () => void;
+ kind?: Extract;
+ className?: string;
+ testId?: string;
+ };
+}
diff --git a/app/client/packages/design-system/ads/src/Templates/EntityExplorer/EmptyState/index.ts b/app/client/packages/design-system/ads/src/Templates/EntityExplorer/EmptyState/index.ts
new file mode 100644
index 0000000000..73c3c2eaf9
--- /dev/null
+++ b/app/client/packages/design-system/ads/src/Templates/EntityExplorer/EmptyState/index.ts
@@ -0,0 +1,2 @@
+export { EmptyState } from "./EmptyState";
+export * from "./EmptyState.types";
diff --git a/app/client/packages/design-system/ads/src/Templates/EntityExplorer/ExplorerContainer/ExplorerContainer.constants.ts b/app/client/packages/design-system/ads/src/Templates/EntityExplorer/ExplorerContainer/ExplorerContainer.constants.ts
new file mode 100644
index 0000000000..989f72dd54
--- /dev/null
+++ b/app/client/packages/design-system/ads/src/Templates/EntityExplorer/ExplorerContainer/ExplorerContainer.constants.ts
@@ -0,0 +1,4 @@
+export const ExplorerContainerBorder = {
+ STANDARD: "1px solid var(--ads-v2-color-border)",
+ NONE: "",
+};
diff --git a/app/client/packages/design-system/ads/src/Templates/EntityExplorer/ExplorerContainer/ExplorerContainer.stories.tsx b/app/client/packages/design-system/ads/src/Templates/EntityExplorer/ExplorerContainer/ExplorerContainer.stories.tsx
new file mode 100644
index 0000000000..7a9560cef7
--- /dev/null
+++ b/app/client/packages/design-system/ads/src/Templates/EntityExplorer/ExplorerContainer/ExplorerContainer.stories.tsx
@@ -0,0 +1,54 @@
+/* eslint-disable no-console */
+import React from "react";
+import type { Meta, StoryObj } from "@storybook/react";
+
+import { type ExplorerContainerProps, ExplorerContainer } from ".";
+
+import { SearchAndAdd } from "..";
+import { Flex } from "../../../Flex";
+
+const meta: Meta = {
+ title: "ADS/Templates/Entity Explorer/Container",
+ component: ExplorerContainer,
+ argTypes: {
+ borderRight: {
+ options: ["STANDARD", "NONE"],
+ control: { type: "select" },
+ },
+ },
+};
+
+export default meta;
+
+const Template = (props: ExplorerContainerProps) => {
+ const { borderRight, children, className, height, width } = props;
+
+ return (
+
+ );
+};
+
+export const Basic = Template.bind({}) as StoryObj;
+
+const Children = () => {
+ return (
+
+
+
+ );
+};
+
+Basic.args = {
+ children: ,
+ borderRight: "STANDARD",
+ height: "300px",
+ width: "255px",
+};
diff --git a/app/client/packages/design-system/ads/src/Templates/EntityExplorer/ExplorerContainer/ExplorerContainer.tsx b/app/client/packages/design-system/ads/src/Templates/EntityExplorer/ExplorerContainer/ExplorerContainer.tsx
new file mode 100644
index 0000000000..2674552b44
--- /dev/null
+++ b/app/client/packages/design-system/ads/src/Templates/EntityExplorer/ExplorerContainer/ExplorerContainer.tsx
@@ -0,0 +1,18 @@
+import React from "react";
+import { ExplorerContainerBorder, Flex } from "../../..";
+import type { ExplorerContainerProps } from "./ExplorerContainer.types";
+
+export const ExplorerContainer = (props: ExplorerContainerProps) => {
+ return (
+
+ {props.children}
+
+ );
+};
diff --git a/app/client/packages/design-system/ads/src/Templates/EntityExplorer/ExplorerContainer/ExplorerContainer.types.ts b/app/client/packages/design-system/ads/src/Templates/EntityExplorer/ExplorerContainer/ExplorerContainer.types.ts
new file mode 100644
index 0000000000..b9638fc983
--- /dev/null
+++ b/app/client/packages/design-system/ads/src/Templates/EntityExplorer/ExplorerContainer/ExplorerContainer.types.ts
@@ -0,0 +1,10 @@
+import { type ReactNode } from "react";
+import type { ExplorerContainerBorder } from "./ExplorerContainer.constants";
+
+export interface ExplorerContainerProps {
+ children: ReactNode | ReactNode[];
+ borderRight: keyof typeof ExplorerContainerBorder;
+ className?: string;
+ width?: string | number;
+ height?: string | number;
+}
diff --git a/app/client/packages/design-system/ads/src/Templates/EntityExplorer/ExplorerContainer/index.ts b/app/client/packages/design-system/ads/src/Templates/EntityExplorer/ExplorerContainer/index.ts
new file mode 100644
index 0000000000..eeb571c08c
--- /dev/null
+++ b/app/client/packages/design-system/ads/src/Templates/EntityExplorer/ExplorerContainer/index.ts
@@ -0,0 +1,3 @@
+export { ExplorerContainer } from "./ExplorerContainer";
+export * from "./ExplorerContainer.types";
+export { ExplorerContainerBorder } from "./ExplorerContainer.constants";
diff --git a/app/client/packages/design-system/ads/src/Templates/EntityExplorer/NoSearchResults/NoSearchResults.mdx b/app/client/packages/design-system/ads/src/Templates/EntityExplorer/NoSearchResults/NoSearchResults.mdx
new file mode 100644
index 0000000000..5f817ae34c
--- /dev/null
+++ b/app/client/packages/design-system/ads/src/Templates/EntityExplorer/NoSearchResults/NoSearchResults.mdx
@@ -0,0 +1,16 @@
+import { Canvas, Meta } from "@storybook/blocks";
+
+import * as NoSearchResultStories from "./NoSearchResults.stories";
+
+
+
+# No Search Results
+
+A placeholder for when there are no search results to display. It can be used to guide users on what to do next.
+What you get is an ADS styled message from this component.
+
+### Default implementation
+
+Below is the default implementation
+
+
diff --git a/app/client/packages/design-system/ads/src/Templates/EntityExplorer/NoSearchResults/NoSearchResults.stories.tsx b/app/client/packages/design-system/ads/src/Templates/EntityExplorer/NoSearchResults/NoSearchResults.stories.tsx
new file mode 100644
index 0000000000..4110b78586
--- /dev/null
+++ b/app/client/packages/design-system/ads/src/Templates/EntityExplorer/NoSearchResults/NoSearchResults.stories.tsx
@@ -0,0 +1,24 @@
+/* eslint-disable no-console */
+import React from "react";
+import type { Meta, StoryObj } from "@storybook/react";
+
+import { NoSearchResults, type NoSearchResultsProps } from ".";
+
+const meta: Meta = {
+ title: "ADS/Templates/Entity Explorer/No Search Results",
+ component: NoSearchResults,
+};
+
+export default meta;
+
+const Template = (props: NoSearchResultsProps) => {
+ const { text } = props;
+
+ return ;
+};
+
+export const Basic = Template.bind({}) as StoryObj;
+
+Basic.args = {
+ text: "No files found",
+};
diff --git a/app/client/packages/design-system/ads/src/Templates/EntityExplorer/NoSearchResults/NoSearchResults.tsx b/app/client/packages/design-system/ads/src/Templates/EntityExplorer/NoSearchResults/NoSearchResults.tsx
new file mode 100644
index 0000000000..645b4c5d1a
--- /dev/null
+++ b/app/client/packages/design-system/ads/src/Templates/EntityExplorer/NoSearchResults/NoSearchResults.tsx
@@ -0,0 +1,17 @@
+import React from "react";
+import { Text } from "../../..";
+import type { NoSearchResultsProps } from "./NoSearchResults.types";
+
+const NoSearchResults = ({ text }: NoSearchResultsProps) => {
+ return (
+
+ {text}
+
+ );
+};
+
+export { NoSearchResults };
diff --git a/app/client/packages/design-system/ads/src/Templates/EntityExplorer/NoSearchResults/NoSearchResults.types.ts b/app/client/packages/design-system/ads/src/Templates/EntityExplorer/NoSearchResults/NoSearchResults.types.ts
new file mode 100644
index 0000000000..74e9a3faf3
--- /dev/null
+++ b/app/client/packages/design-system/ads/src/Templates/EntityExplorer/NoSearchResults/NoSearchResults.types.ts
@@ -0,0 +1,3 @@
+export interface NoSearchResultsProps {
+ text: string;
+}
diff --git a/app/client/packages/design-system/ads/src/Templates/EntityExplorer/NoSearchResults/index.ts b/app/client/packages/design-system/ads/src/Templates/EntityExplorer/NoSearchResults/index.ts
new file mode 100644
index 0000000000..d63aea8808
--- /dev/null
+++ b/app/client/packages/design-system/ads/src/Templates/EntityExplorer/NoSearchResults/index.ts
@@ -0,0 +1,2 @@
+export { NoSearchResults } from "./NoSearchResults";
+export * from "./NoSearchResults.types";
diff --git a/app/client/packages/design-system/ads/src/Templates/EntityExplorer/index.ts b/app/client/packages/design-system/ads/src/Templates/EntityExplorer/index.ts
index 2c77164ada..5e42c9c115 100644
--- a/app/client/packages/design-system/ads/src/Templates/EntityExplorer/index.ts
+++ b/app/client/packages/design-system/ads/src/Templates/EntityExplorer/index.ts
@@ -2,3 +2,6 @@ export { ListItemContainer, ListHeaderContainer } from "./styles";
export { ListWithHeader } from "./ListWithHeader";
export { EditorSegments } from "./EditorSegments";
export * from "./SearchAndAdd";
+export { EmptyState } from "./EmptyState";
+export { NoSearchResults } from "./NoSearchResults";
+export * from "./ExplorerContainer";
diff --git a/app/client/src/pages/Editor/IDE/EditorPane/Explorer.tsx b/app/client/src/pages/Editor/IDE/EditorPane/Explorer.tsx
index 7896b28f3a..25f31d1b19 100644
--- a/app/client/src/pages/Editor/IDE/EditorPane/Explorer.tsx
+++ b/app/client/src/pages/Editor/IDE/EditorPane/Explorer.tsx
@@ -1,5 +1,5 @@
import React from "react";
-import { Flex } from "@appsmith/ads";
+import { ExplorerContainer } from "@appsmith/ads";
import { Switch, useRouteMatch } from "react-router";
import { SentryRoute } from "ee/AppRouter";
import {
@@ -26,15 +26,11 @@ const EditorPaneExplorer = () => {
const ideViewMode = useSelector(getIDEViewMode);
return (
- {
]}
/>
-
+
);
};
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 077100ed56..88c686152a 100644
--- a/app/client/src/pages/Editor/IDE/EditorPane/JS/Add.tsx
+++ b/app/client/src/pages/Editor/IDE/EditorPane/JS/Add.tsx
@@ -2,7 +2,7 @@ import React, { useCallback, useState } from "react";
import SegmentAddHeader from "../components/SegmentAddHeader";
import { EDITOR_PANE_TEXTS, createMessage } from "ee/constants/messages";
import type { ListItemProps } from "@appsmith/ads";
-import { Flex, SearchInput } from "@appsmith/ads";
+import { Flex, SearchInput, NoSearchResults } from "@appsmith/ads";
import { useDispatch, useSelector } from "react-redux";
import { getCurrentPageId } from "selectors/editorSelectors";
import GroupedList from "../components/GroupedList";
@@ -13,7 +13,6 @@ import {
import type { ActionOperation } from "components/editorComponents/GlobalSearch/utils";
import { createAddClassName } from "../utils";
import { FocusEntity } from "navigation/FocusEntity";
-import { EmptySearchResult } from "../components/EmptySearchResult";
import { getIDEViewMode } from "selectors/ideSelectors";
import type { FlexProps } from "@appsmith/ads";
import { EditorViewMode } from "ee/entities/IDE/constants";
@@ -98,8 +97,11 @@ const AddJS = () => {
) : null}
{filteredItemGroups.length === 0 && searchTerm !== "" ? (
-
) : null}
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 f1858a8f66..7aa6667e02 100644
--- a/app/client/src/pages/Editor/IDE/EditorPane/JS/BlankState.tsx
+++ b/app/client/src/pages/Editor/IDE/EditorPane/JS/BlankState.tsx
@@ -1,4 +1,4 @@
-import React from "react";
+import React, { useMemo } from "react";
import { useSelector } from "react-redux";
import { EDITOR_PANE_TEXTS, createMessage } from "ee/constants/messages";
@@ -7,7 +7,7 @@ import { useFeatureFlag } from "utils/hooks/useFeatureFlag";
import { getHasCreateActionPermission } from "ee/utils/BusinessFeatures/permissionPageHelpers";
import { FEATURE_FLAG } from "ee/entities/FeatureFlag";
import { useJSAdd } from "ee/pages/Editor/IDE/EditorPane/JS/hooks";
-import { EmptyState } from "../components/EmptyState";
+import { EmptyState } from "@appsmith/ads";
const BlankState: React.FC = () => {
const pagePermissions = useSelector(getPagePermissions);
@@ -18,14 +18,21 @@ const BlankState: React.FC = () => {
);
const { openAddJS } = useJSAdd();
+ const buttonProps = useMemo(
+ () => ({
+ className: "t--add-item",
+ testId: "t--add-item",
+ text: createMessage(EDITOR_PANE_TEXTS.js_add_button),
+ onClick: canCreateActions ? openAddJS : undefined,
+ }),
+ [canCreateActions, openAddJS],
+ );
+
return (
);
};
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 7812572bc7..e068499e4b 100644
--- a/app/client/src/pages/Editor/IDE/EditorPane/JS/List.tsx
+++ b/app/client/src/pages/Editor/IDE/EditorPane/JS/List.tsx
@@ -1,6 +1,6 @@
import React, { useState } from "react";
import { useSelector } from "react-redux";
-import { Flex, Text, SearchAndAdd } from "@appsmith/ads";
+import { Flex, Text, SearchAndAdd, NoSearchResults } from "@appsmith/ads";
import styled from "styled-components";
import { selectJSSegmentEditorList } from "ee/selectors/appIDESelectors";
@@ -18,7 +18,6 @@ import { FilesContextProvider } from "pages/Editor/Explorer/Files/FilesContextPr
import { useJSAdd } from "ee/pages/Editor/IDE/EditorPane/JS/hooks";
import { JSListItem } from "ee/pages/Editor/IDE/EditorPane/JS/ListItem";
import { BlankState } from "./BlankState";
-import { EmptySearchResult } from "../components/EmptySearchResult";
import { EDITOR_PANE_TEXTS, createMessage } from "ee/constants/messages";
import { filterEntityGroupsBySearchTerm } from "IDE/utils";
@@ -111,8 +110,11 @@ const ListJSObjects = () => {
);
})}
{filteredItemGroups.length === 0 && searchTerm !== "" ? (
-
) : null}
diff --git a/app/client/src/pages/Editor/IDE/EditorPane/Query/Add.tsx b/app/client/src/pages/Editor/IDE/EditorPane/Query/Add.tsx
index b28548f126..b262ea2ad4 100644
--- a/app/client/src/pages/Editor/IDE/EditorPane/Query/Add.tsx
+++ b/app/client/src/pages/Editor/IDE/EditorPane/Query/Add.tsx
@@ -1,5 +1,10 @@
import React, { useState } from "react";
-import { Flex, SearchInput } from "@appsmith/ads";
+import {
+ Flex,
+ SearchInput,
+ NoSearchResults,
+ type FlexProps,
+} from "@appsmith/ads";
import { createMessage, EDITOR_PANE_TEXTS } from "ee/constants/messages";
import SegmentAddHeader from "../components/SegmentAddHeader";
@@ -9,10 +14,8 @@ import {
useGroupedAddQueryOperations,
useQueryAdd,
} from "ee/pages/Editor/IDE/EditorPane/Query/hooks";
-import { EmptySearchResult } from "../components/EmptySearchResult";
import { useSelector } from "react-redux";
import { getIDEViewMode } from "selectors/ideSelectors";
-import type { FlexProps } from "@appsmith/ads";
import { EditorViewMode } from "ee/entities/IDE/constants";
import { filterEntityGroupsBySearchTerm } from "IDE/utils";
@@ -66,8 +69,11 @@ const AddQuery = () => {
) : null}
{filteredItemGroups.length === 0 && searchTerm !== "" ? (
-
) : null}
diff --git a/app/client/src/pages/Editor/IDE/EditorPane/Query/BlankState.tsx b/app/client/src/pages/Editor/IDE/EditorPane/Query/BlankState.tsx
index 06fff7e028..623b0fafed 100644
--- a/app/client/src/pages/Editor/IDE/EditorPane/Query/BlankState.tsx
+++ b/app/client/src/pages/Editor/IDE/EditorPane/Query/BlankState.tsx
@@ -1,4 +1,4 @@
-import React from "react";
+import React, { useMemo } from "react";
import { useSelector } from "react-redux";
import { EDITOR_PANE_TEXTS, createMessage } from "ee/constants/messages";
@@ -6,7 +6,7 @@ import { getHasCreateActionPermission } from "ee/utils/BusinessFeatures/permissi
import { getPagePermissions } from "selectors/editorSelectors";
import { useFeatureFlag } from "utils/hooks/useFeatureFlag";
import { FEATURE_FLAG } from "ee/entities/FeatureFlag";
-import { EmptyState } from "../components/EmptyState";
+import { EmptyState } from "@appsmith/ads";
import { useQueryAdd } from "ee/pages/Editor/IDE/EditorPane/Query/hooks";
const BlankState: React.FC = () => {
@@ -18,16 +18,23 @@ const BlankState: React.FC = () => {
);
const { openAddQuery } = useQueryAdd();
+ const buttonProps = useMemo(
+ () => ({
+ className: "t--add-item",
+ testId: "t--add-item",
+ text: createMessage(EDITOR_PANE_TEXTS.query_add_button),
+ onClick: canCreateActions ? openAddQuery : undefined,
+ }),
+ [canCreateActions, openAddQuery],
+ );
+
return (
);
};
diff --git a/app/client/src/pages/Editor/IDE/EditorPane/Query/List.tsx b/app/client/src/pages/Editor/IDE/EditorPane/Query/List.tsx
index 789711f873..6c169fabb6 100644
--- a/app/client/src/pages/Editor/IDE/EditorPane/Query/List.tsx
+++ b/app/client/src/pages/Editor/IDE/EditorPane/Query/List.tsx
@@ -1,5 +1,5 @@
import React, { useState } from "react";
-import { Flex, Text, SearchAndAdd } from "@appsmith/ads";
+import { Flex, Text, SearchAndAdd, NoSearchResults } from "@appsmith/ads";
import { useSelector } from "react-redux";
import { getHasCreateActionPermission } from "ee/utils/BusinessFeatures/permissionPageHelpers";
@@ -18,7 +18,6 @@ import { useQueryAdd } from "ee/pages/Editor/IDE/EditorPane/Query/hooks";
import { QueryListItem } from "ee/pages/Editor/IDE/EditorPane/Query/ListItem";
import { getShowWorkflowFeature } from "ee/selectors/workflowSelectors";
import { BlankState } from "./BlankState";
-import { EmptySearchResult } from "../components/EmptySearchResult";
import { EDITOR_PANE_TEXTS, createMessage } from "ee/constants/messages";
import { filterEntityGroupsBySearchTerm } from "IDE/utils";
@@ -95,8 +94,11 @@ const ListQuery = () => {
);
})}
{filteredItemGroups.length === 0 && searchTerm !== "" ? (
-
) : null}
diff --git a/app/client/src/pages/Editor/IDE/EditorPane/UI/List.tsx b/app/client/src/pages/Editor/IDE/EditorPane/UI/List.tsx
index 491d89ce9a..7bd081a473 100644
--- a/app/client/src/pages/Editor/IDE/EditorPane/UI/List.tsx
+++ b/app/client/src/pages/Editor/IDE/EditorPane/UI/List.tsx
@@ -12,7 +12,7 @@ import { useFeatureFlag } from "utils/hooks/useFeatureFlag";
import { FEATURE_FLAG } from "ee/entities/FeatureFlag";
import { getHasManagePagePermission } from "ee/utils/BusinessFeatures/permissionPageHelpers";
import { createMessage, EDITOR_PANE_TEXTS } from "ee/constants/messages";
-import { EmptyState } from "../components/EmptyState";
+import { EmptyState } from "@appsmith/ads";
import history from "utils/history";
import { builderURL } from "ee/RouteBuilder";
import styled from "styled-components";
@@ -26,6 +26,7 @@ const ListContainer = styled(Flex)`
const ListWidgets = (props: {
setFocusSearchInput: (focusSearchInput: boolean) => void;
}) => {
+ const { setFocusSearchInput } = props;
const basePageId = useSelector(getCurrentBasePageId) as string;
const widgets = useSelector(selectWidgetsForCurrentPage);
const pagePermissions = useSelector(getPagePermissions);
@@ -41,16 +42,29 @@ const ListWidgets = (props: {
}, [widgets?.children]);
const addButtonClickHandler = useCallback(() => {
- props.setFocusSearchInput(true);
+ setFocusSearchInput(true);
history.push(builderURL({}));
- }, []);
+ }, [setFocusSearchInput]);
const widgetsExist =
widgets && widgets.children && widgets.children.length > 0;
- useEffect(() => {
- props.setFocusSearchInput(false);
- }, []);
+ useEffect(
+ function resetFocusOnSearch() {
+ setFocusSearchInput(false);
+ },
+ [setFocusSearchInput],
+ );
+
+ const blankStateButtonProps = useMemo(
+ () => ({
+ className: "t--add-item",
+ testId: "t--add-item",
+ text: createMessage(EDITOR_PANE_TEXTS.widget_add_button),
+ onClick: canManagePages ? addButtonClickHandler : undefined,
+ }),
+ [addButtonClickHandler, canManagePages],
+ );
return (
) : canManagePages ? (
/* We show the List Add button when side by side is not enabled */
diff --git a/app/client/src/pages/Editor/IDE/EditorPane/components/EmptySearchResult.tsx b/app/client/src/pages/Editor/IDE/EditorPane/components/EmptySearchResult.tsx
deleted file mode 100644
index 007aee2e14..0000000000
--- a/app/client/src/pages/Editor/IDE/EditorPane/components/EmptySearchResult.tsx
+++ /dev/null
@@ -1,17 +0,0 @@
-import React from "react";
-import { Text } from "@appsmith/ads";
-import { EDITOR_PANE_TEXTS, createMessage } from "ee/constants/messages";
-
-const EmptySearchResult = ({ type }: { type: string }) => {
- return (
-
- {createMessage(EDITOR_PANE_TEXTS.empty_search_result, type)}
-
- );
-};
-
-export { EmptySearchResult };
diff --git a/app/client/src/pages/Editor/IDE/EditorPane/components/EmptyState.tsx b/app/client/src/pages/Editor/IDE/EditorPane/components/EmptyState.tsx
deleted file mode 100644
index 8347215b93..0000000000
--- a/app/client/src/pages/Editor/IDE/EditorPane/components/EmptyState.tsx
+++ /dev/null
@@ -1,63 +0,0 @@
-import React from "react";
-import { Button, Flex, Text, Icon } from "@appsmith/ads";
-
-interface EmptyStateProps {
- icon: string;
- description: string;
- buttonText: string;
- onClick?: () => void;
- buttonClassName?: string;
- buttonTestId?: string;
-}
-
-const EmptyState = ({
- buttonClassName,
- buttonTestId,
- buttonText,
- description,
- icon,
- onClick,
-}: EmptyStateProps) => {
- return (
-
-
-
-
-
- {description}
-
- {onClick && (
-
- )}
-
- );
-};
-
-export { EmptyState };
diff --git a/app/client/src/pages/Editor/IDE/EditorPane/index.tsx b/app/client/src/pages/Editor/IDE/EditorPane/index.tsx
index 03e4755aa9..5f52076057 100644
--- a/app/client/src/pages/Editor/IDE/EditorPane/index.tsx
+++ b/app/client/src/pages/Editor/IDE/EditorPane/index.tsx
@@ -1,5 +1,5 @@
import React from "react";
-import { Flex } from "@appsmith/ads";
+import { ExplorerContainerBorder, Flex } from "@appsmith/ads";
import EditorPaneExplorer from "./Explorer";
import Editor from "./Editor";
import { useSelector } from "react-redux";
@@ -14,8 +14,8 @@ const EditorPane = () => {
{
// @ts-expect-error Fix this the next time the file is edited
gap="spacing-2"
height="100%"
- width={"100%"}
+ width="100%"
>
{/** Entity Properties component is necessary to render
the Bindings popover in the context menu.
diff --git a/app/client/src/pages/Editor/IDE/LeftPane/DataSidePane.tsx b/app/client/src/pages/Editor/IDE/LeftPane/DataSidePane.tsx
index 6f590fea20..914f070f81 100644
--- a/app/client/src/pages/Editor/IDE/LeftPane/DataSidePane.tsx
+++ b/app/client/src/pages/Editor/IDE/LeftPane/DataSidePane.tsx
@@ -1,4 +1,4 @@
-import React, { useCallback, useEffect, useState } from "react";
+import React, { useCallback, useEffect, useMemo, useState } from "react";
import styled from "styled-components";
import { Flex, List, Text } from "@appsmith/ads";
import { useSelector } from "react-redux";
@@ -27,7 +27,7 @@ import { getCurrentAppWorkspace } from "ee/selectors/selectedWorkspaceSelectors"
import { useFeatureFlag } from "utils/hooks/useFeatureFlag";
import { FEATURE_FLAG } from "ee/entities/FeatureFlag";
import { getHasCreateDatasourcePermission } from "ee/utils/BusinessFeatures/permissionPageHelpers";
-import { EmptyState } from "../EditorPane/components/EmptyState";
+import { EmptyState } from "@appsmith/ads";
import { getAssetUrl } from "ee/utils/airgapHelpers";
import { getCurrentBasePageId } from "selectors/editorSelectors";
@@ -86,13 +86,24 @@ const DataSidePane = (props: DataSidePaneProps) => {
userWorkspacePermissions,
);
- const addButtonClickHandler = () =>
+ const addButtonClickHandler = useCallback(() => {
history.push(
integrationEditorURL({
basePageId,
selectedTab: INTEGRATION_TABS.NEW,
}),
);
+ }, [basePageId]);
+
+ const blankStateButtonProps = useMemo(
+ () => ({
+ className: "t--add-datasource-button-blank-screen",
+ testId: "t--add-datasource-button-blank-screen",
+ text: createMessage(DATA_PANE_TITLE),
+ onClick: canCreateDatasource ? addButtonClickHandler : undefined,
+ }),
+ [addButtonClickHandler, canCreateDatasource],
+ );
return (
{
{datasources.length === 0 ? (
) : null}