feat: Updated new tab ui with search and load more (#34981)
## Description Updated new tab ui with search, load more and updated titles. Fixes #34809, #34530 ## Automation /ok-to-test tags="@tag.All" ### 🔍 Cypress test results <!-- This is an auto-generated comment: Cypress test results --> > [!TIP] > 🟢 🟢 🟢 All cypress tests have passed! 🎉 🎉 🎉 > Workflow run: <https://github.com/appsmithorg/appsmith/actions/runs/10036807357> > Commit: 2d37c01455f48de14510fa17cae104dd7578091c > <a href="https://internal.appsmith.com/app/cypress-dashboard/rundetails-65890b3c81d7400d08fa9ee5?branch=master&workflowId=10036807357&attempt=1" target="_blank">Cypress dashboard</a>. > Tags: `@tag.All` > Spec: > <hr>Mon, 22 Jul 2024 08:46:24 UTC <!-- end of auto-generated comment: Cypress test results --> ## Communication Should the DevRel and Marketing teams inform users about this change? - [ ] Yes - [x] No <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit ## Summary by CodeRabbit - **New Features** - Added search functionality in the JS and Query Editor Panes to filter and display grouped items based on search terms. - Introduced a new component to render grouped lists with dynamic load more functionality. - **Enhancements** - Improved text and terminology for clearer user understanding in various modules. - Enhanced layout alignment by adjusting component heights to account for editor tabs. - **Refactor** - Improved type safety and refined logic in multiple functions for better performance and maintainability. - Replaced hardcoded values with constants for consistent and easier management. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
parent
a38ef9a096
commit
5127005129
|
|
@ -2312,10 +2312,17 @@ export const EDITOR_PANE_TEXTS = {
|
|||
query_create_tab_title: () => "Create new query from",
|
||||
widgets_create_tab_title: () => "Drag & drop UI elements",
|
||||
js_create_tab_title: () => "Create JS object from",
|
||||
queries_create_from_existing: () => "From existing datasource",
|
||||
queries_create_new: () => "New API",
|
||||
js_create_modules: () => "JS modules (Beta)",
|
||||
queries_create_from_existing: () => "Datasources",
|
||||
queries_create_new: () => "Quick actions",
|
||||
queries_create_modules: () => "Query modules (Beta)",
|
||||
loading_building_blocks: () => "Loading building blocks",
|
||||
empty_search_result: (type: string) => `No ${type} match your search`,
|
||||
search_objects: {
|
||||
jsObject: () => "JS object",
|
||||
queries: () => "queries",
|
||||
datasources: () => "datasources",
|
||||
},
|
||||
};
|
||||
|
||||
export const PARTIAL_IMPORT_EXPORT = {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import React, { useCallback, useMemo } from "react";
|
||||
import { useCallback, useMemo } from "react";
|
||||
import history from "utils/history";
|
||||
import { useLocation } from "react-router";
|
||||
import { FocusEntity, identifyEntityFromPath } from "navigation/FocusEntity";
|
||||
|
|
@ -33,7 +33,7 @@ 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 { Tag, type ListItemProps } from "design-system";
|
||||
import type { ListItemProps } from "design-system";
|
||||
import { useCurrentEditorState } from "pages/Editor/IDE/hooks";
|
||||
import { createAddClassName } from "pages/Editor/IDE/EditorPane/utils";
|
||||
import { QueriesBlankState } from "pages/Editor/QueryEditor/QueriesBlankState";
|
||||
|
|
@ -182,12 +182,16 @@ export const useAddQueryListItems = () => {
|
|||
[pageId, dispatch],
|
||||
);
|
||||
|
||||
const getListItems = (data: any[]) => {
|
||||
const getListItems = (data: ActionOperation[]) => {
|
||||
return data.map((fileOperation) => {
|
||||
const title =
|
||||
let title =
|
||||
fileOperation.entityExplorerTitle ||
|
||||
fileOperation.dsName ||
|
||||
fileOperation.title;
|
||||
title =
|
||||
fileOperation.focusEntityType === FocusEntity.QUERY_MODULE_INSTANCE
|
||||
? fileOperation.title
|
||||
: title;
|
||||
const className = createAddClassName(title);
|
||||
const icon =
|
||||
fileOperation.icon ||
|
||||
|
|
@ -197,11 +201,10 @@ export const useAddQueryListItems = () => {
|
|||
startIcon: icon,
|
||||
wrapperClassName: className,
|
||||
title,
|
||||
description: !!fileOperation.isBeta ? (
|
||||
<Tag isClosable={false}>Beta</Tag>
|
||||
) : (
|
||||
""
|
||||
),
|
||||
description:
|
||||
fileOperation.focusEntityType === FocusEntity.QUERY_MODULE_INSTANCE
|
||||
? fileOperation.dsName
|
||||
: "",
|
||||
descriptionType: "inline",
|
||||
onClick: onCreateItemClick.bind(null, fileOperation),
|
||||
} as ListItemProps;
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
import React, { useCallback } from "react";
|
||||
import React, { useCallback, useState } from "react";
|
||||
import SegmentAddHeader from "../components/SegmentAddHeader";
|
||||
import { EDITOR_PANE_TEXTS } from "@appsmith/constants/messages";
|
||||
import { EDITOR_PANE_TEXTS, createMessage } from "@appsmith/constants/messages";
|
||||
import type { ListItemProps } from "design-system";
|
||||
import { Flex, Tag } from "design-system";
|
||||
import { Flex, SearchInput } from "design-system";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
import { getCurrentPageId } from "selectors/editorSelectors";
|
||||
import GroupedList from "../components/GroupedList";
|
||||
|
|
@ -12,11 +12,15 @@ import {
|
|||
} 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";
|
||||
import { createAddClassName, fuzzySearchInObjectItems } from "../utils";
|
||||
import { FocusEntity } from "navigation/FocusEntity";
|
||||
import type { GroupedListProps } from "../components/types";
|
||||
import { EmptySearchResult } from "../components/EmptySearchResult";
|
||||
|
||||
const AddJS = ({ containerProps, innerContainerProps }: AddProps) => {
|
||||
const dispatch = useDispatch();
|
||||
const pageId = useSelector(getCurrentPageId);
|
||||
const [searchTerm, setSearchTerm] = useState("");
|
||||
|
||||
const groupedJsOperations = useGroupedAddJsOperations();
|
||||
|
||||
|
|
@ -35,13 +39,29 @@ const AddJS = ({ containerProps, innerContainerProps }: AddProps) => {
|
|||
return {
|
||||
startIcon: data.icon,
|
||||
title,
|
||||
description: !!data.isBeta ? <Tag isClosable={false}>Beta</Tag> : "",
|
||||
description:
|
||||
data.focusEntityType === FocusEntity.JS_MODULE_INSTANCE
|
||||
? data.dsName
|
||||
: "",
|
||||
descriptionType: "inline",
|
||||
onClick: onCreateItemClick.bind(null, data),
|
||||
wrapperClassName: createAddClassName(title),
|
||||
} as ListItemProps;
|
||||
};
|
||||
|
||||
const groups = groupedJsOperations.map(
|
||||
({ className, operations, title }) => ({
|
||||
groupTitle: title,
|
||||
className: className,
|
||||
items: operations.map(getListItems),
|
||||
}),
|
||||
);
|
||||
|
||||
const localGroups = fuzzySearchInObjectItems<GroupedListProps[]>(
|
||||
searchTerm,
|
||||
groups,
|
||||
);
|
||||
|
||||
return (
|
||||
<Flex
|
||||
data-testid="t--ide-add-pane"
|
||||
|
|
@ -61,14 +81,13 @@ const AddJS = ({ containerProps, innerContainerProps }: AddProps) => {
|
|||
onCloseClick={closeAddJS}
|
||||
titleMessage={EDITOR_PANE_TEXTS.js_create_tab_title}
|
||||
/>
|
||||
|
||||
<GroupedList
|
||||
groups={groupedJsOperations.map((op) => ({
|
||||
groupTitle: op.title,
|
||||
className: op.className,
|
||||
items: op.operations.map(getListItems),
|
||||
}))}
|
||||
/>
|
||||
<SearchInput onChange={setSearchTerm} value={searchTerm} />
|
||||
{localGroups.length > 0 ? <GroupedList groups={localGroups} /> : null}
|
||||
{localGroups.length === 0 && searchTerm !== "" ? (
|
||||
<EmptySearchResult
|
||||
type={createMessage(EDITOR_PANE_TEXTS.search_objects.jsObject)}
|
||||
/>
|
||||
) : null}
|
||||
</Flex>
|
||||
</Flex>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ import { useSelector } from "react-redux";
|
|||
import { Flex, Text } from "design-system";
|
||||
import styled from "styled-components";
|
||||
|
||||
import type { EditorSegmentList } from "@appsmith/selectors/appIDESelectors";
|
||||
import { selectJSSegmentEditorList } from "@appsmith/selectors/appIDESelectors";
|
||||
import { useActiveAction } from "@appsmith/pages/Editor/Explorer/hooks";
|
||||
import {
|
||||
|
|
@ -19,7 +20,8 @@ import { useJSAdd } from "@appsmith/pages/Editor/IDE/EditorPane/JS/hooks";
|
|||
import { JSListItem } from "@appsmith/pages/Editor/IDE/EditorPane/JS/ListItem";
|
||||
import { BlankState } from "./BlankState";
|
||||
import { AddAndSearchbar } from "../components/AddAndSearchbar";
|
||||
import { fuzzySearchInFiles } from "../utils";
|
||||
import { fuzzySearchInObjectItems } from "../utils";
|
||||
import { EmptySearchResult } from "../components/EmptySearchResult";
|
||||
import { EDITOR_PANE_TEXTS, createMessage } from "@appsmith/constants/messages";
|
||||
|
||||
const JSContainer = styled(Flex)`
|
||||
|
|
@ -44,7 +46,10 @@ const ListJSObjects = () => {
|
|||
|
||||
const isFeatureEnabled = useFeatureFlag(FEATURE_FLAG.license_gac_enabled);
|
||||
|
||||
const localFiles = fuzzySearchInFiles(searchTerm, files);
|
||||
const localFiles = fuzzySearchInObjectItems<EditorSegmentList>(
|
||||
searchTerm,
|
||||
files,
|
||||
);
|
||||
|
||||
const canCreateActions = getHasCreateActionPermission(
|
||||
isFeatureEnabled,
|
||||
|
|
@ -112,13 +117,9 @@ const ListJSObjects = () => {
|
|||
);
|
||||
})}
|
||||
{localFiles.length === 0 && searchTerm !== "" ? (
|
||||
<Text
|
||||
className="font-normal text-center"
|
||||
color="var(--ads-v2-color-fg-muted)"
|
||||
kind="body-s"
|
||||
>
|
||||
{createMessage(EDITOR_PANE_TEXTS.empty_search_result, "JS")}
|
||||
</Text>
|
||||
<EmptySearchResult
|
||||
type={createMessage(EDITOR_PANE_TEXTS.search_objects.jsObject)}
|
||||
/>
|
||||
) : null}
|
||||
</Flex>
|
||||
</FilesContextProvider>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import React from "react";
|
||||
import { Flex } from "design-system";
|
||||
import React, { useState } from "react";
|
||||
import { Flex, SearchInput } from "design-system";
|
||||
|
||||
import { EDITOR_PANE_TEXTS } from "@appsmith/constants/messages";
|
||||
import { EDITOR_PANE_TEXTS, createMessage } from "@appsmith/constants/messages";
|
||||
import SegmentAddHeader from "../components/SegmentAddHeader";
|
||||
import GroupedList from "../components/GroupedList";
|
||||
import {
|
||||
|
|
@ -10,12 +10,27 @@ import {
|
|||
useQueryAdd,
|
||||
} from "@appsmith/pages/Editor/IDE/EditorPane/Query/hooks";
|
||||
import type { AddProps } from "../types/AddProps";
|
||||
import { fuzzySearchInObjectItems } from "../utils";
|
||||
import type { GroupedListProps } from "../components/types";
|
||||
import { EmptySearchResult } from "../components/EmptySearchResult";
|
||||
|
||||
const AddQuery = ({ containerProps, innerContainerProps }: AddProps) => {
|
||||
const [searchTerm, setSearchTerm] = useState("");
|
||||
const { getListItems } = useAddQueryListItems();
|
||||
const groupedActionOperations = useGroupedAddQueryOperations();
|
||||
const { closeAddQuery } = useQueryAdd();
|
||||
|
||||
const groups = groupedActionOperations.map((group) => ({
|
||||
groupTitle: group.title,
|
||||
className: group.className,
|
||||
items: getListItems(group.operations),
|
||||
}));
|
||||
|
||||
const localGroups = fuzzySearchInObjectItems<GroupedListProps[]>(
|
||||
searchTerm,
|
||||
groups,
|
||||
);
|
||||
|
||||
return (
|
||||
<Flex
|
||||
data-testid="t--ide-add-pane"
|
||||
|
|
@ -35,13 +50,13 @@ const AddQuery = ({ containerProps, innerContainerProps }: AddProps) => {
|
|||
onCloseClick={closeAddQuery}
|
||||
titleMessage={EDITOR_PANE_TEXTS.query_create_tab_title}
|
||||
/>
|
||||
<GroupedList
|
||||
groups={groupedActionOperations.map((group) => ({
|
||||
groupTitle: group.title,
|
||||
className: group.className,
|
||||
items: getListItems(group.operations),
|
||||
}))}
|
||||
/>
|
||||
<SearchInput autofocus onChange={setSearchTerm} value={searchTerm} />
|
||||
{localGroups.length > 0 ? <GroupedList groups={localGroups} /> : null}
|
||||
{localGroups.length === 0 && searchTerm !== "" ? (
|
||||
<EmptySearchResult
|
||||
type={createMessage(EDITOR_PANE_TEXTS.search_objects.datasources)}
|
||||
/>
|
||||
) : null}
|
||||
</Flex>
|
||||
</Flex>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ import {
|
|||
import { useFeatureFlag } from "utils/hooks/useFeatureFlag";
|
||||
import { FEATURE_FLAG } from "@appsmith/entities/FeatureFlag";
|
||||
import { getCurrentPageId } from "@appsmith/selectors/entitiesSelector";
|
||||
import type { EditorSegmentList } from "@appsmith/selectors/appIDESelectors";
|
||||
import { selectQuerySegmentEditorList } from "@appsmith/selectors/appIDESelectors";
|
||||
import { ActionParentEntityType } from "@appsmith/entities/Engine/actionHelpers";
|
||||
import { FilesContextProvider } from "pages/Editor/Explorer/Files/FilesContextProvider";
|
||||
|
|
@ -19,7 +20,8 @@ import { QueryListItem } from "@appsmith/pages/Editor/IDE/EditorPane/Query/ListI
|
|||
import { getShowWorkflowFeature } from "@appsmith/selectors/workflowSelectors";
|
||||
import { BlankState } from "./BlankState";
|
||||
import { AddAndSearchbar } from "../components/AddAndSearchbar";
|
||||
import { fuzzySearchInFiles } from "../utils";
|
||||
import { fuzzySearchInObjectItems } from "../utils";
|
||||
import { EmptySearchResult } from "../components/EmptySearchResult";
|
||||
import { EDITOR_PANE_TEXTS, createMessage } from "@appsmith/constants/messages";
|
||||
|
||||
const ListQuery = () => {
|
||||
|
|
@ -30,7 +32,10 @@ const ListQuery = () => {
|
|||
const pagePermissions = useSelector(getPagePermissions);
|
||||
const isFeatureEnabled = useFeatureFlag(FEATURE_FLAG.license_gac_enabled);
|
||||
|
||||
const localFiles = fuzzySearchInFiles(searchTerm, files);
|
||||
const localFiles = fuzzySearchInObjectItems<EditorSegmentList>(
|
||||
searchTerm,
|
||||
files,
|
||||
);
|
||||
|
||||
const canCreateActions = getHasCreateActionPermission(
|
||||
isFeatureEnabled,
|
||||
|
|
@ -92,13 +97,9 @@ const ListQuery = () => {
|
|||
);
|
||||
})}
|
||||
{localFiles.length === 0 && searchTerm !== "" ? (
|
||||
<Text
|
||||
className="font-normal text-center"
|
||||
color="var(--ads-v2-color-fg-muted)"
|
||||
kind="body-s"
|
||||
>
|
||||
{createMessage(EDITOR_PANE_TEXTS.empty_search_result, "queries")}
|
||||
</Text>
|
||||
<EmptySearchResult
|
||||
type={createMessage(EDITOR_PANE_TEXTS.search_objects.jsObject)}
|
||||
/>
|
||||
) : null}
|
||||
</Flex>
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,17 @@
|
|||
import React from "react";
|
||||
import { Text } from "design-system";
|
||||
import { EDITOR_PANE_TEXTS, createMessage } from "@appsmith/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 };
|
||||
|
|
@ -0,0 +1,81 @@
|
|||
import React, { useMemo, useState } from "react";
|
||||
import type { GroupedListProps } from "./types";
|
||||
import { DEFAULT_GROUP_LIST_SIZE } from "./constants";
|
||||
import { Flex, List, Text } from "design-system";
|
||||
import styled from "styled-components";
|
||||
|
||||
interface GroupProps {
|
||||
group: GroupedListProps;
|
||||
}
|
||||
|
||||
const StyledList = styled(List)`
|
||||
padding: 0;
|
||||
gap: 0;
|
||||
|
||||
& .ds-load-more .ads-v2-listitem__title {
|
||||
--color: var(--ads-v2-color-fg-subtle);
|
||||
}
|
||||
& .ads-v2-listitem__wrapper .ads-v2-listitem__idesc {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
& .ads-v2-listitem__wrapper:hover .ads-v2-listitem__idesc {
|
||||
opacity: 1;
|
||||
}
|
||||
`;
|
||||
|
||||
const Group: React.FC<GroupProps> = ({ group }) => {
|
||||
const [visibleItemsCount, setVisibleItemsCount] = useState<number>(
|
||||
DEFAULT_GROUP_LIST_SIZE,
|
||||
);
|
||||
const { className, groupTitle, items: groupItems } = group;
|
||||
|
||||
const items = useMemo(() => {
|
||||
const items = groupItems.slice(0, visibleItemsCount);
|
||||
const hasMoreItems = groupItems.length > visibleItemsCount;
|
||||
|
||||
const handleLoadMore = () => {
|
||||
setVisibleItemsCount(groupItems.length);
|
||||
};
|
||||
|
||||
if (hasMoreItems) {
|
||||
items.push({
|
||||
title: "Load more...",
|
||||
description: "",
|
||||
descriptionType: "inline",
|
||||
onClick: handleLoadMore,
|
||||
className: "ds-load-more",
|
||||
});
|
||||
}
|
||||
|
||||
// TODO: try to avoid this
|
||||
if (hasMoreItems && groupTitle === "Datasources") {
|
||||
items.push(groupItems[groupItems.length - 1]);
|
||||
}
|
||||
|
||||
return items;
|
||||
}, [groupItems, visibleItemsCount, groupTitle]);
|
||||
|
||||
return (
|
||||
<Flex
|
||||
borderBottom="1px solid var(--ads-v2-color-border-muted)"
|
||||
className="groups-list-group"
|
||||
flexDirection="column"
|
||||
key={groupTitle}
|
||||
pb="spaces-3"
|
||||
>
|
||||
{groupTitle ? (
|
||||
<Text
|
||||
className="px-0 py-[var(--ads-v2-spaces-1)]"
|
||||
color="var(--ads-v2-color-fg-muted)"
|
||||
kind="body-s"
|
||||
>
|
||||
{groupTitle}
|
||||
</Text>
|
||||
) : null}
|
||||
<StyledList className={className} items={items} />
|
||||
</Flex>
|
||||
);
|
||||
};
|
||||
|
||||
export { Group };
|
||||
|
|
@ -1,27 +1,24 @@
|
|||
import React from "react";
|
||||
import type { FlexProps } from "design-system";
|
||||
import { Flex } from "design-system";
|
||||
import styled from "styled-components";
|
||||
import type { FlexProps, ListItemProps } from "design-system";
|
||||
import { Flex, List, Text } from "design-system";
|
||||
|
||||
const StyledList = styled(List)`
|
||||
padding: 0;
|
||||
gap: 0;
|
||||
`;
|
||||
|
||||
export type GroupedListProps = Array<{
|
||||
groupTitle?: string;
|
||||
className: string;
|
||||
items: ListItemProps[];
|
||||
}>;
|
||||
import type { GroupedListProps } from "./types";
|
||||
import { Group } from "./Group";
|
||||
|
||||
interface Props {
|
||||
groups: GroupedListProps;
|
||||
groups: GroupedListProps[];
|
||||
flexProps?: FlexProps;
|
||||
}
|
||||
|
||||
const StyledFlex = styled(Flex)`
|
||||
& .groups-list-group:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
`;
|
||||
|
||||
const GroupedList = (props: Props) => {
|
||||
return (
|
||||
<Flex
|
||||
<StyledFlex
|
||||
flex="1"
|
||||
flexDirection="column"
|
||||
gap="spaces-4"
|
||||
|
|
@ -29,20 +26,9 @@ const GroupedList = (props: Props) => {
|
|||
{...props.flexProps}
|
||||
>
|
||||
{props.groups.map((group) => (
|
||||
<Flex flexDirection="column" key={group.groupTitle}>
|
||||
{group.groupTitle ? (
|
||||
<Text
|
||||
className="px-0 py-[var(--ads-v2-spaces-1)]"
|
||||
color="var(--ads-v2-color-fg-muted)"
|
||||
kind="body-s"
|
||||
>
|
||||
{group.groupTitle}
|
||||
</Text>
|
||||
) : null}
|
||||
<StyledList className={group.className} items={group.items} />
|
||||
</Flex>
|
||||
<Group group={group} key={group.groupTitle} />
|
||||
))}
|
||||
</Flex>
|
||||
</StyledFlex>
|
||||
);
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -20,7 +20,6 @@ const SegmentAddHeader = (props: Props) => {
|
|||
: "var(--ads-v2-color-gray-50)"
|
||||
}
|
||||
justifyContent="space-between"
|
||||
py="spaces-2"
|
||||
>
|
||||
<Text color="var(--ads-v2-color-fg)" kind="heading-xs">
|
||||
{createMessage(props.titleMessage)}
|
||||
|
|
|
|||
|
|
@ -0,0 +1 @@
|
|||
export const DEFAULT_GROUP_LIST_SIZE = 5;
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
import type { ListItemProps } from "design-system";
|
||||
|
||||
export interface GroupedListProps {
|
||||
groupTitle?: string;
|
||||
className: string;
|
||||
items: ListItemProps[];
|
||||
}
|
||||
1
app/client/src/pages/Editor/IDE/EditorPane/constants.ts
Normal file
1
app/client/src/pages/Editor/IDE/EditorPane/constants.ts
Normal file
|
|
@ -0,0 +1 @@
|
|||
export const EDITOR_TABS_HEIGHT = "32px";
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
import type { EditorSegmentList } from "@appsmith/selectors/appIDESelectors";
|
||||
import { fuzzySearchInFiles } from "./utils";
|
||||
import { fuzzySearchInObjectItems } from "./utils";
|
||||
import { PluginType } from "entities/Action";
|
||||
|
||||
const sampleFiles: EditorSegmentList = [
|
||||
|
|
@ -19,14 +19,14 @@ const sampleFiles: EditorSegmentList = [
|
|||
},
|
||||
];
|
||||
|
||||
describe("fuzzySearchInFiles", () => {
|
||||
describe("fuzzySearchInObjectItems", () => {
|
||||
it("should return all files when the search string is empty", () => {
|
||||
const result = fuzzySearchInFiles("", sampleFiles);
|
||||
const result = fuzzySearchInObjectItems("", sampleFiles);
|
||||
expect(result).toEqual(sampleFiles);
|
||||
});
|
||||
|
||||
it("should return the correct file when the search string exactly matches a file title", () => {
|
||||
const result = fuzzySearchInFiles("file1", sampleFiles);
|
||||
const result = fuzzySearchInObjectItems("file1", sampleFiles);
|
||||
expect(result).toEqual([
|
||||
{
|
||||
group: "Group 1",
|
||||
|
|
@ -36,12 +36,12 @@ describe("fuzzySearchInFiles", () => {
|
|||
});
|
||||
|
||||
it("should return an empty array when no files match the search string", () => {
|
||||
const result = fuzzySearchInFiles("nonexistentfile", sampleFiles);
|
||||
const result = fuzzySearchInObjectItems("nonexistentfile", sampleFiles);
|
||||
expect(result).toEqual([]);
|
||||
});
|
||||
|
||||
it("should return all files containing the common substring in their titles", () => {
|
||||
const result = fuzzySearchInFiles("file", sampleFiles);
|
||||
const result = fuzzySearchInObjectItems("file", sampleFiles);
|
||||
expect(result).toEqual(sampleFiles);
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
import Fuse from "fuse.js";
|
||||
import type { EditorSegmentList } from "@appsmith/selectors/appIDESelectors";
|
||||
|
||||
export const createAddClassName = (name: string) => {
|
||||
return "t--datasoucre-create-option-" + name.toLowerCase().replace(/ /g, "_");
|
||||
|
|
@ -11,19 +10,20 @@ const FUSE_OPTIONS = {
|
|||
keys: ["title"],
|
||||
};
|
||||
|
||||
export const fuzzySearchInFiles = (
|
||||
export const fuzzySearchInObjectItems = <T extends any[]>(
|
||||
searchStr: string,
|
||||
files: EditorSegmentList,
|
||||
) => {
|
||||
files: T,
|
||||
): T => {
|
||||
if (searchStr && searchStr !== "") {
|
||||
const newFiles = files
|
||||
.map((group) => {
|
||||
const fuse = new Fuse(group.items, FUSE_OPTIONS);
|
||||
const items = group["items"];
|
||||
const fuse = new Fuse(items, FUSE_OPTIONS);
|
||||
const resultItems = fuse.search(searchStr);
|
||||
return { ...group, items: resultItems };
|
||||
})
|
||||
.filter((group) => group.items.length > 0);
|
||||
return newFiles;
|
||||
return newFiles as T;
|
||||
}
|
||||
|
||||
return files;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import type { ReactNode } from "react";
|
||||
import React from "react";
|
||||
import { Flex } from "design-system";
|
||||
import { EDITOR_TABS_HEIGHT } from "../EditorPane/constants";
|
||||
|
||||
const Container = (props: { children: ReactNode }) => {
|
||||
return (
|
||||
|
|
@ -10,8 +11,8 @@ const Container = (props: { children: ReactNode }) => {
|
|||
borderBottom="1px solid var(--ads-v2-color-border-muted)"
|
||||
gap="spaces-2"
|
||||
id="ide-tabs-container"
|
||||
maxHeight="32px"
|
||||
minHeight="32px"
|
||||
maxHeight={EDITOR_TABS_HEIGHT}
|
||||
minHeight={EDITOR_TABS_HEIGHT}
|
||||
px="spaces-2"
|
||||
width="100%"
|
||||
>
|
||||
|
|
|
|||
|
|
@ -1,10 +1,11 @@
|
|||
import React from "react";
|
||||
import { Flex } from "design-system";
|
||||
import AddJS from "pages/Editor/IDE/EditorPane/JS/Add";
|
||||
import { EDITOR_TABS_HEIGHT } from "../IDE/EditorPane/constants";
|
||||
|
||||
const JSAddState = () => {
|
||||
return (
|
||||
<Flex height="100%" justifyContent="center">
|
||||
<Flex height={`calc(100% - ${EDITOR_TABS_HEIGHT})`} justifyContent="center">
|
||||
<AddJS
|
||||
containerProps={{
|
||||
px: "spaces-4",
|
||||
|
|
|
|||
|
|
@ -1,10 +1,11 @@
|
|||
import React from "react";
|
||||
import { Flex } from "design-system";
|
||||
import AddQuery from "pages/Editor/IDE/EditorPane/Query/Add";
|
||||
import { EDITOR_TABS_HEIGHT } from "../IDE/EditorPane/constants";
|
||||
|
||||
const QueriesAddState = () => {
|
||||
return (
|
||||
<Flex height="100%" justifyContent="center">
|
||||
<Flex height={`calc(100% - ${EDITOR_TABS_HEIGHT})`} justifyContent="center">
|
||||
<AddQuery
|
||||
containerProps={{
|
||||
px: "spaces-4",
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user