Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: IDE tab list search view #34759

Merged
merged 18 commits into from
Jul 10, 2024
Merged
Show file tree
Hide file tree
Changes from 15 commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
c6b51da
fix: Removed searchable files list
albinAppsmith Jul 1, 2024
9ec92b4
Merge branch 'release' of https://github.com/appsmithorg/appsmith int…
albinAppsmith Jul 1, 2024
86bc62e
Merge branch 'release' of https://github.com/appsmithorg/appsmith int…
albinAppsmith Jul 5, 2024
4d8516e
feat: Added searchbar to the overflow list
albinAppsmith Jul 5, 2024
ac04312
Merge branch 'release' of https://github.com/appsmithorg/appsmith int…
albinAppsmith Jul 5, 2024
aa4c87a
Merge branch 'release' of https://github.com/appsmithorg/appsmith int…
albinAppsmith Jul 8, 2024
9600269
Merge branch 'release' of https://github.com/appsmithorg/appsmith int…
albinAppsmith Jul 9, 2024
4569848
fix: cypress failures
albinAppsmith Jul 9, 2024
bd1a481
fix: updated test descriptions
albinAppsmith Jul 9, 2024
557a0b4
Merge branch 'release' of https://github.com/appsmithorg/appsmith int…
albinAppsmith Jul 9, 2024
4f17e33
chore: renamed handler as per naming convention
albinAppsmith Jul 9, 2024
ff0355b
Merge branch 'release' of https://github.com/appsmithorg/appsmith int…
albinAppsmith Jul 9, 2024
215c162
Merge branch 'release' of https://github.com/appsmithorg/appsmith int…
albinAppsmith Jul 10, 2024
257eb48
fix: code review comment
albinAppsmith Jul 10, 2024
b93b2e8
fix: removed unnecessary comment
albinAppsmith Jul 10, 2024
7755e3a
Merge branch 'release' of https://github.com/appsmithorg/appsmith int…
albinAppsmith Jul 10, 2024
126197d
fix: jest test failure
albinAppsmith Jul 10, 2024
c09ae9f
fix: JS render unit test
albinAppsmith Jul 10, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion app/client/cypress/support/Pages/JSEditor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ export class JSEditor {
this.agHelper.ClickOutside(); //to enable click of below!
AppSidebar.navigate(AppSidebarButton.Editor);
PageLeftPane.switchSegment(PagePaneSegment.JS);
cy.get(this._newJSobj).eq(0).click({ force: true });
PageLeftPane.switchToAddNew();

this.agHelper.RemoveUIElement(
"Tooltip",
Expand Down
2 changes: 1 addition & 1 deletion app/client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@
"d3-geo": "^3.1.0",
"dayjs": "^1.10.6",
"deep-diff": "^1.0.2",
"design-system": "npm:@appsmithorg/[email protected].42",
"design-system": "npm:@appsmithorg/[email protected].43",
"design-system-old": "npm:@appsmithorg/[email protected]",
"downloadjs": "^1.4.7",
"echarts": "^5.4.2",
Expand Down
1 change: 1 addition & 0 deletions app/client/src/ce/constants/messages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2315,6 +2315,7 @@ export const EDITOR_PANE_TEXTS = {
queries_create_from_existing: () => "From existing datasource",
queries_create_new: () => "New API",
loading_building_blocks: () => "Loading building blocks",
empty_search_result: (type: string) => `No ${type} match your search`,
};

export const PARTIAL_IMPORT_EXPORT = {
Expand Down
46 changes: 27 additions & 19 deletions app/client/src/pages/Editor/IDE/EditorPane/JS/List.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from "react";
import React, { useState } from "react";
import { useSelector } from "react-redux";
import { Button, Flex, Text } from "design-system";
import { Flex, Text } from "design-system";
import styled from "styled-components";

import { selectJSSegmentEditorList } from "@appsmith/selectors/appIDESelectors";
Expand All @@ -13,12 +13,14 @@ import {
import { useFeatureFlag } from "utils/hooks/useFeatureFlag";
import { FEATURE_FLAG } from "@appsmith/entities/FeatureFlag";
import { getHasCreateActionPermission } from "@appsmith/utils/BusinessFeatures/permissionPageHelpers";
import { createMessage, EDITOR_PANE_TEXTS } from "@appsmith/constants/messages";
import { ActionParentEntityType } from "@appsmith/entities/Engine/actionHelpers";
import { FilesContextProvider } from "pages/Editor/Explorer/Files/FilesContextProvider";
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 { EDITOR_PANE_TEXTS, createMessage } from "@appsmith/constants/messages";

const JSContainer = styled(Flex)`
& .t--entity-item {
Expand All @@ -32,15 +34,18 @@ const JSContainer = styled(Flex)`
`;

const ListJSObjects = () => {
const [searchTerm, setSearchTerm] = useState("");
const pageId = useSelector(getCurrentPageId);
const jsList = useSelector(selectJSSegmentEditorList);
const files = useSelector(selectJSSegmentEditorList);
const activeActionId = useActiveAction();
const applicationId = useSelector(getCurrentApplicationId);

const pagePermissions = useSelector(getPagePermissions);

const isFeatureEnabled = useFeatureFlag(FEATURE_FLAG.license_gac_enabled);

const localFiles = fuzzySearchInFiles(searchTerm, files);

const canCreateActions = getHasCreateActionPermission(
isFeatureEnabled,
pagePermissions,
Expand All @@ -57,19 +62,13 @@ const ListJSObjects = () => {
overflow="hidden"
py="spaces-3"
>
{jsList && jsList.length > 0 && canCreateActions && (
<Flex flexDirection="column" px="spaces-3">
<Button
className="t--add-item"
kind={"secondary"}
onClick={openAddJS}
size={"sm"}
startIcon={"add-line"}
>
{createMessage(EDITOR_PANE_TEXTS.js_add_button)}
</Button>
</Flex>
)}
{files && files.length > 0 ? (
<AddAndSearchbar
hasAddPermission={canCreateActions}
onAddClick={openAddJS}
onSearch={setSearchTerm}
/>
) : null}
<FilesContextProvider
canCreateActions={canCreateActions}
editorId={applicationId}
Expand All @@ -83,7 +82,7 @@ const ListJSObjects = () => {
overflowY="auto"
px="spaces-3"
>
{jsList.map(({ group, items }) => {
{localFiles.map(({ group, items }) => {
return (
<Flex flexDirection={"column"} key={group}>
{group !== "NA" ? (
Expand Down Expand Up @@ -112,10 +111,19 @@ const ListJSObjects = () => {
</Flex>
);
})}
{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>
) : null}
</Flex>
</FilesContextProvider>

{(!jsList || jsList.length === 0) && <BlankState />}
{(!files || files.length === 0) && <BlankState />}
</JSContainer>
);
};
Expand Down
42 changes: 25 additions & 17 deletions app/client/src/pages/Editor/IDE/EditorPane/Query/List.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from "react";
import { Button, Flex, Text } from "design-system";
import React, { useState } from "react";
import { Flex, Text } from "design-system";
import { useSelector } from "react-redux";

import { getHasCreateActionPermission } from "@appsmith/utils/BusinessFeatures/permissionPageHelpers";
Expand All @@ -14,19 +14,24 @@ import { getCurrentPageId } from "@appsmith/selectors/entitiesSelector";
import { selectQuerySegmentEditorList } from "@appsmith/selectors/appIDESelectors";
import { ActionParentEntityType } from "@appsmith/entities/Engine/actionHelpers";
import { FilesContextProvider } from "pages/Editor/Explorer/Files/FilesContextProvider";
import { createMessage, EDITOR_PANE_TEXTS } from "@appsmith/constants/messages";
import { useQueryAdd } from "@appsmith/pages/Editor/IDE/EditorPane/Query/hooks";
import { QueryListItem } from "@appsmith/pages/Editor/IDE/EditorPane/Query/ListItem";
import { getShowWorkflowFeature } from "@appsmith/selectors/workflowSelectors";
import { BlankState } from "./BlankState";
import { AddAndSearchbar } from "../components/AddAndSearchbar";
import { fuzzySearchInFiles } from "../utils";
import { EDITOR_PANE_TEXTS, createMessage } from "@appsmith/constants/messages";

const ListQuery = () => {
const [searchTerm, setSearchTerm] = useState("");
const pageId = useSelector(getCurrentPageId) as string;
const files = useSelector(selectQuerySegmentEditorList);
const activeActionId = useActiveAction();
const pagePermissions = useSelector(getPagePermissions);
const isFeatureEnabled = useFeatureFlag(FEATURE_FLAG.license_gac_enabled);

const localFiles = fuzzySearchInFiles(searchTerm, files);

const canCreateActions = getHasCreateActionPermission(
isFeatureEnabled,
pagePermissions,
Expand All @@ -44,26 +49,20 @@ const ListQuery = () => {
overflow="hidden"
py="spaces-3"
>
{files.length > 0 && canCreateActions && (
<Flex flexDirection={"column"} px="spaces-3">
<Button
className="t--add-item"
kind={"secondary"}
onClick={openAddQuery}
size={"sm"}
startIcon={"add-line"}
>
{createMessage(EDITOR_PANE_TEXTS.query_add_button)}
</Button>
</Flex>
)}
{files.length > 0 ? (
<AddAndSearchbar
hasAddPermission={canCreateActions}
onAddClick={openAddQuery}
onSearch={setSearchTerm}
/>
) : null}
<Flex
flexDirection={"column"}
gap="spaces-4"
overflowY="auto"
px="spaces-3"
>
{files.map(({ group, items }) => {
{localFiles.map(({ group, items }) => {
return (
<Flex flexDirection={"column"} key={group}>
<Flex px="spaces-3" py="spaces-1">
Expand Down Expand Up @@ -96,6 +95,15 @@ const ListQuery = () => {
</Flex>
);
})}
{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>
) : null}
</Flex>

{Object.keys(files).length === 0 && <BlankState />}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import React from "react";
import { Flex, Button, SearchInput } from "design-system";

interface Props {
onAddClick: () => void;
hasAddPermission: boolean;
onSearch: (value: string) => void;
}

const AddAndSearchbar = ({ hasAddPermission, onAddClick, onSearch }: Props) => {
return (
<Flex alignItems="center" flexDirection="row" gap="spaces-3" px="spaces-3">
<SearchInput onChange={onSearch} size="sm" />
{hasAddPermission ? (
<Button
className="t--add-item !min-w-[24px]"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use data-testid for t--add-item instead of className.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will take this up in a separate PR since this change is not introduced by this PR rather this is a change in location. Also, this update will cause updates in some cypress files as well.

isIconButton
kind={"secondary"}
onClick={onAddClick}
size={"sm"}
startIcon={"add-line"}
/>
) : null}
</Flex>
);
};

export { AddAndSearchbar };
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import type { EditorSegmentList } from "@appsmith/selectors/appIDESelectors";
import { fuzzySearchInFiles } from "./utils";
import { PluginType } from "entities/Action";

const sampleFiles: EditorSegmentList = [
{
group: "Group 1",
items: [
{ title: "file1.js", type: PluginType.API, key: "file1" },
{ title: "file2.js", type: PluginType.API, key: "file2" },
],
},
{
group: "Group 2",
items: [
{ title: "file3.js", type: PluginType.API, key: "file3" },
{ title: "file4.js", type: PluginType.API, key: "file4" },
],
},
];

describe("fuzzySearchInFiles", () => {
it("should return all files when the search string is empty", () => {
const result = fuzzySearchInFiles("", 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);
expect(result).toEqual([
{
group: "Group 1",
items: [{ title: "file1.js", type: PluginType.API, key: "file1" }],
},
]);
});

it("should return an empty array when no files match the search string", () => {
const result = fuzzySearchInFiles("nonexistentfile", sampleFiles);
expect(result).toEqual([]);
});

it("should return all files containing the common substring in their titles", () => {
const result = fuzzySearchInFiles("file", sampleFiles);
expect(result).toEqual(sampleFiles);
});
});
27 changes: 27 additions & 0 deletions app/client/src/pages/Editor/IDE/EditorPane/utils.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,30 @@
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, "_");
};

const FUSE_OPTIONS = {
shouldSort: true,
threshold: 0.1,
keys: ["title"],
};

export const fuzzySearchInFiles = (
searchStr: string,
files: EditorSegmentList,
) => {
if (searchStr && searchStr !== "") {
const newFiles = files
.map((group) => {
const fuse = new Fuse(group.items, FUSE_OPTIONS);
const resultItems = fuse.search(searchStr);
return { ...group, items: resultItems };
})
.filter((group) => group.items.length > 0);
return newFiles;
}

return files;
};
Loading
Loading