chore: Move smaller Entity Explorer components into ADS (#38321)

This commit is contained in:
Hetu Nandu 2024-12-24 11:30:58 +05:30 committed by GitHub
parent d3ea54d6a2
commit ddb83c0094
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
28 changed files with 406 additions and 138 deletions

View File

@ -0,0 +1,35 @@
import { Canvas, Meta } from "@storybook/blocks";
import * as EmptyStateStories from "./EmptyState.stories";
<Meta of={EmptyStateStories} />
# 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.
<Canvas of={EmptyStateStories.Basic} />
### With Button
Button kind can be supplied. If no kind is supplied, default is "secondary".
<Canvas of={EmptyStateStories.WithButton} />
### With Button but no onClick is supplied
onClick is optional. If not supplied, the button will not be shown.
<Canvas of={EmptyStateStories.WithButtonWithoutOnClick} />

View File

@ -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<typeof EmptyState> = {
title: "ADS/Templates/Entity Explorer/Empty State",
component: EmptyState,
};
export default meta;
const Template = (props: EmptyStateProps) => {
const { button, description, icon } = props;
return (
<EmptyState
{...{
description,
icon,
button,
}}
/>
);
};
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",
},
};

View File

@ -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 (
<Flex
alignItems={"center"}
flexDirection="column"
gap="spaces-4"
justifyContent={"center"}
px="spaces-3"
py="spaces-7"
>
<Flex
alignItems="center"
backgroundColor="var(--ads-v2-color-bg-subtle)"
borderRadius="var(--ads-v2-border-radius)"
height="var(--ads-v2-spaces-11)"
justifyContent="center"
padding="spaces-3"
width="var(--ads-v2-spaces-11)"
>
<Icon name={icon} size="lg" />
</Flex>
<Text
className="text-center"
color="var(--ads-v2-color-fg)"
kind="heading-xs"
>
{description}
</Text>
{button && button.onClick ? (
<Button
className={button.className}
data-testid={button.testId}
kind={button.kind || "secondary"}
onClick={button.onClick}
size="sm"
>
{button.text}
</Button>
) : null}
</Flex>
);
};
export { EmptyState };

View File

@ -0,0 +1,13 @@
import { type IconNames, type ButtonKind } from "../../..";
export interface EmptyStateProps {
icon: IconNames;
description: string;
button?: {
text: string;
onClick?: () => void;
kind?: Extract<ButtonKind, "primary" | "secondary">;
className?: string;
testId?: string;
};
}

View File

@ -0,0 +1,2 @@
export { EmptyState } from "./EmptyState";
export * from "./EmptyState.types";

View File

@ -0,0 +1,4 @@
export const ExplorerContainerBorder = {
STANDARD: "1px solid var(--ads-v2-color-border)",
NONE: "",
};

View File

@ -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<typeof ExplorerContainer> = {
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 (
<ExplorerContainer
{...{
children,
width,
height,
className,
borderRight,
}}
/>
);
};
export const Basic = Template.bind({}) as StoryObj;
const Children = () => {
return (
<Flex flexDirection="column" p="spaces-2">
<SearchAndAdd showAddButton={false} />
</Flex>
);
};
Basic.args = {
children: <Children />,
borderRight: "STANDARD",
height: "300px",
width: "255px",
};

View File

@ -0,0 +1,18 @@
import React from "react";
import { ExplorerContainerBorder, Flex } from "../../..";
import type { ExplorerContainerProps } from "./ExplorerContainer.types";
export const ExplorerContainer = (props: ExplorerContainerProps) => {
return (
<Flex
borderRight={ExplorerContainerBorder[props.borderRight]}
className={`relative ${props.className}`}
flexDirection="column"
height={props.height}
overflow="hidden"
width={props.width}
>
{props.children}
</Flex>
);
};

View File

@ -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;
}

View File

@ -0,0 +1,3 @@
export { ExplorerContainer } from "./ExplorerContainer";
export * from "./ExplorerContainer.types";
export { ExplorerContainerBorder } from "./ExplorerContainer.constants";

View File

@ -0,0 +1,16 @@
import { Canvas, Meta } from "@storybook/blocks";
import * as NoSearchResultStories from "./NoSearchResults.stories";
<Meta of={NoSearchResultStories} />
# 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
<Canvas of={NoSearchResultStories.Basic} />

View File

@ -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<typeof NoSearchResults> = {
title: "ADS/Templates/Entity Explorer/No Search Results",
component: NoSearchResults,
};
export default meta;
const Template = (props: NoSearchResultsProps) => {
const { text } = props;
return <NoSearchResults text={text} />;
};
export const Basic = Template.bind({}) as StoryObj;
Basic.args = {
text: "No files found",
};

View File

@ -0,0 +1,17 @@
import React from "react";
import { Text } from "../../..";
import type { NoSearchResultsProps } from "./NoSearchResults.types";
const NoSearchResults = ({ text }: NoSearchResultsProps) => {
return (
<Text
className="font-normal text-center"
color="var(--ads-v2-color-fg-muted)"
kind="body-s"
>
{text}
</Text>
);
};
export { NoSearchResults };

View File

@ -0,0 +1,3 @@
export interface NoSearchResultsProps {
text: string;
}

View File

@ -0,0 +1,2 @@
export { NoSearchResults } from "./NoSearchResults";
export * from "./NoSearchResults.types";

View File

@ -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";

View File

@ -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 (
<Flex
<ExplorerContainer
borderRight={
ideViewMode === EditorViewMode.SplitScreen
? ""
: "1px solid var(--ads-v2-color-border)"
ideViewMode === EditorViewMode.SplitScreen ? "NONE" : "STANDARD"
}
className="relative ide-editor-left-pane__content"
flexDirection="column"
overflow="hidden"
className="ide-editor-left-pane__content"
width={
ideViewMode === EditorViewMode.FullScreen
? DEFAULT_EXPLORER_PANE_WIDTH
@ -61,7 +57,7 @@ const EditorPaneExplorer = () => {
]}
/>
</Switch>
</Flex>
</ExplorerContainer>
);
};

View File

@ -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 = () => {
<GroupedList groups={filteredItemGroups} />
) : null}
{filteredItemGroups.length === 0 && searchTerm !== "" ? (
<EmptySearchResult
type={createMessage(EDITOR_PANE_TEXTS.search_objects.jsObject)}
<NoSearchResults
text={createMessage(
EDITOR_PANE_TEXTS.empty_search_result,
createMessage(EDITOR_PANE_TEXTS.search_objects.jsObject),
)}
/>
) : null}
</Flex>

View File

@ -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 (
<EmptyState
buttonClassName="t--add-item"
buttonTestId="t--add-item"
buttonText={createMessage(EDITOR_PANE_TEXTS.js_add_button)}
button={buttonProps}
description={createMessage(EDITOR_PANE_TEXTS.js_blank_state_description)}
icon={"js-square-v3"}
onClick={canCreateActions ? openAddJS : undefined}
/>
);
};

View File

@ -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 !== "" ? (
<EmptySearchResult
type={createMessage(EDITOR_PANE_TEXTS.search_objects.jsObject)}
<NoSearchResults
text={createMessage(
EDITOR_PANE_TEXTS.empty_search_result,
createMessage(EDITOR_PANE_TEXTS.search_objects.jsObject),
)}
/>
) : null}
</Flex>

View File

@ -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 = () => {
<GroupedList groups={filteredItemGroups} />
) : null}
{filteredItemGroups.length === 0 && searchTerm !== "" ? (
<EmptySearchResult
type={createMessage(EDITOR_PANE_TEXTS.search_objects.datasources)}
<NoSearchResults
text={createMessage(
EDITOR_PANE_TEXTS.empty_search_result,
createMessage(EDITOR_PANE_TEXTS.search_objects.datasources),
)}
/>
) : null}
</Flex>

View File

@ -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 (
<EmptyState
buttonClassName="t--add-item"
buttonTestId="t--add-item"
buttonText={createMessage(EDITOR_PANE_TEXTS.query_add_button)}
button={buttonProps}
description={createMessage(
EDITOR_PANE_TEXTS.query_blank_state_description,
)}
icon={"queries-v3"}
onClick={canCreateActions ? openAddQuery : undefined}
/>
);
};

View File

@ -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 !== "" ? (
<EmptySearchResult
type={createMessage(EDITOR_PANE_TEXTS.search_objects.queries)}
<NoSearchResults
text={createMessage(
EDITOR_PANE_TEXTS.empty_search_result,
createMessage(EDITOR_PANE_TEXTS.search_objects.queries),
)}
/>
) : null}
</Flex>

View File

@ -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 (
<ListContainer
@ -62,14 +76,11 @@ const ListWidgets = (props: {
{!widgetsExist ? (
/* If no widgets exist, show the blank state */
<EmptyState
buttonClassName="t--add-item"
buttonTestId="t--add-item"
buttonText={createMessage(EDITOR_PANE_TEXTS.widget_add_button)}
button={blankStateButtonProps}
description={createMessage(
EDITOR_PANE_TEXTS.widget_blank_state_description,
)}
icon={"widgets-v3"}
onClick={canManagePages ? addButtonClickHandler : undefined}
/>
) : canManagePages ? (
/* We show the List Add button when side by side is not enabled */

View File

@ -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 (
<Text
className="font-normal text-center"
color="var(--ads-v2-color-fg-muted)"
kind="body-s"
>
{createMessage(EDITOR_PANE_TEXTS.empty_search_result, type)}
</Text>
);
};
export { EmptySearchResult };

View File

@ -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 (
<Flex
alignItems={"center"}
flexDirection="column"
gap="spaces-4"
justifyContent={"center"}
px="spaces-3"
py="spaces-7"
>
<Flex
alignItems={"center"}
backgroundColor={"var(--ads-v2-color-bg-subtle)"}
borderRadius={"var(--ads-v2-border-radius)"}
height={"40px"}
justifyContent={"center"}
padding={"spaces-3"}
width={"40px"}
>
<Icon name={icon} size={"lg"} />
</Flex>
<Text
className={"text-center"}
color={"var(--ads-v2-color-fg)"}
kind={"heading-xs"}
>
{description}
</Text>
{onClick && (
<Button
className={buttonClassName}
data-testid={buttonTestId}
kind={"secondary"}
onClick={onClick}
size={"sm"}
>
{buttonText}
</Button>
)}
</Flex>
);
};
export { EmptyState };

View File

@ -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 = () => {
<Flex
borderRight={
ideViewMode === EditorViewMode.SplitScreen
? "1px solid var(--ads-v2-color-border)"
: ""
? ExplorerContainerBorder.STANDARD
: ExplorerContainerBorder.NONE
}
className="ide-editor-left-pane"
flexDirection={
@ -24,7 +24,7 @@ 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.

View File

@ -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 (
<Flex
@ -112,11 +123,9 @@ const DataSidePane = (props: DataSidePaneProps) => {
<PaneBody>
{datasources.length === 0 ? (
<EmptyState
buttonClassName={"t--add-datasource-button-blank-screen"}
buttonText={"Bring your data"}
button={blankStateButtonProps}
description={createMessage(DATASOURCE_LIST_BLANK_DESCRIPTION)}
icon={"datasource-v3"}
onClick={canCreateDatasource ? addButtonClickHandler : undefined}
/>
) : null}
<Flex