implemented search bar

This commit is contained in:
nishthaAhujaa
2026-01-02 15:53:32 +05:30
parent 6167f94bc3
commit ab219d5a3f
4 changed files with 45 additions and 21 deletions

View File

@@ -1,5 +1,5 @@
import { Tree, TreeItemValue, TreeOpenChangeData, TreeOpenChangeEvent } from "@fluentui/react-components"; import { Input, Tree, TreeItemValue, TreeOpenChangeData, TreeOpenChangeEvent } from "@fluentui/react-components";
import { Home16Regular } from "@fluentui/react-icons"; import { Home16Regular, Search20Regular } from "@fluentui/react-icons";
import { AuthType } from "AuthType"; import { AuthType } from "AuthType";
import { useTreeStyles } from "Explorer/Controls/TreeComponent/Styles"; import { useTreeStyles } from "Explorer/Controls/TreeComponent/Styles";
import { TreeNode, TreeNodeComponent } from "Explorer/Controls/TreeComponent/TreeNodeComponent"; import { TreeNode, TreeNodeComponent } from "Explorer/Controls/TreeComponent/TreeNodeComponent";
@@ -55,6 +55,8 @@ export const ResourceTree: React.FC<ResourceTreeProps> = ({ explorer }: Resource
sampleDataResourceTokenCollection: state.sampleDataResourceTokenCollection, sampleDataResourceTokenCollection: state.sampleDataResourceTokenCollection,
})); }));
const databasesFetchedSuccessfully = useDatabases((state) => state.databasesFetchedSuccessfully); const databasesFetchedSuccessfully = useDatabases((state) => state.databasesFetchedSuccessfully);
const searchText = useDatabases((state) => state.searchText);
const setSearchText = useDatabases((state) => state.setSearchText);
const { isCopilotEnabled, isCopilotSampleDBEnabled } = useQueryCopilot((state) => ({ const { isCopilotEnabled, isCopilotSampleDBEnabled } = useQueryCopilot((state) => ({
isCopilotEnabled: state.copilotEnabled, isCopilotEnabled: state.copilotEnabled,
isCopilotSampleDBEnabled: state.copilotSampleDBEnabled, isCopilotSampleDBEnabled: state.copilotSampleDBEnabled,
@@ -63,8 +65,8 @@ export const ResourceTree: React.FC<ResourceTreeProps> = ({ explorer }: Resource
const databaseTreeNodes = useMemo(() => { const databaseTreeNodes = useMemo(() => {
return userContext.authType === AuthType.ResourceToken return userContext.authType === AuthType.ResourceToken
? createResourceTokenTreeNodes(resourceTokenCollection) ? createResourceTokenTreeNodes(resourceTokenCollection)
: createDatabaseTreeNodes(explorer, isNotebookEnabled, databases, refreshActiveTab); : createDatabaseTreeNodes(explorer, isNotebookEnabled, databases, refreshActiveTab, searchText);
}, [resourceTokenCollection, databases, isNotebookEnabled, refreshActiveTab]); }, [resourceTokenCollection, databases, isNotebookEnabled, refreshActiveTab, searchText]);
const isSampleDataEnabled = const isSampleDataEnabled =
isCopilotEnabled && isCopilotEnabled &&
@@ -81,19 +83,19 @@ export const ResourceTree: React.FC<ResourceTreeProps> = ({ explorer }: Resource
const headerNodes: TreeNode[] = isFabricMirrored() const headerNodes: TreeNode[] = isFabricMirrored()
? [] ? []
: [ : [
{ {
id: "home", id: "home",
iconSrc: <Home16Regular />, iconSrc: <Home16Regular />,
label: "Home", label: "Home",
isSelected: () => isSelected: () =>
useSelectedNode.getState().selectedNode === undefined && useSelectedNode.getState().selectedNode === undefined &&
useTabs.getState().activeReactTab === ReactTabKind.Home, useTabs.getState().activeReactTab === ReactTabKind.Home,
onClick: () => { onClick: () => {
useSelectedNode.getState().setSelectedNode(undefined); useSelectedNode.getState().setSelectedNode(undefined);
useTabs.getState().openAndActivateReactTab(ReactTabKind.Home); useTabs.getState().openAndActivateReactTab(ReactTabKind.Home);
},
}, },
]; },
];
const rootNodes: TreeNode[] = useMemo(() => { const rootNodes: TreeNode[] = useMemo(() => {
if (sampleDataNodes.length > 0) { if (sampleDataNodes.length > 0) {
@@ -154,6 +156,17 @@ export const ResourceTree: React.FC<ResourceTreeProps> = ({ explorer }: Resource
return ( return (
<div className={treeStyles.treeContainer}> <div className={treeStyles.treeContainer}>
{userContext.authType !== AuthType.ResourceToken && databases.length > 0 && (
<div style={{ padding: "8px" }}>
<Input
placeholder="Search databases only"
value={searchText}
onChange={(_, data) => setSearchText(data?.value || "")}
size="small"
contentBefore={<Search20Regular />}
/>
</div>
)}
<Tree <Tree
aria-label="CosmosDB resources" aria-label="CosmosDB resources"
openItems={openItems} openItems={openItems}

View File

@@ -363,7 +363,7 @@ describe("createDatabaseTreeNodes", () => {
}, },
} as never, } as never,
}); });
nodes = createDatabaseTreeNodes(explorer, false, useDatabases.getState().databases, refreshActiveTab); nodes = createDatabaseTreeNodes(explorer, false, useDatabases.getState().databases, refreshActiveTab, "");
}); });
it("creates expected tree", () => { it("creates expected tree", () => {
@@ -445,6 +445,7 @@ describe("createDatabaseTreeNodes", () => {
isNotebookEnabled, isNotebookEnabled,
useDatabases.getState().databases, useDatabases.getState().databases,
refreshActiveTab, refreshActiveTab,
"",
); );
expect(nodes).toMatchSnapshot(); expect(nodes).toMatchSnapshot();
}, },
@@ -455,7 +456,7 @@ describe("createDatabaseTreeNodes", () => {
// The goal is to cover some key behaviors like loading child nodes, opening tabs/side panels, etc. // The goal is to cover some key behaviors like loading child nodes, opening tabs/side panels, etc.
it("adds new collections to database as they appear", () => { it("adds new collections to database as they appear", () => {
const nodes = createDatabaseTreeNodes(explorer, false, useDatabases.getState().databases, refreshActiveTab); const nodes = createDatabaseTreeNodes(explorer, false, useDatabases.getState().databases, refreshActiveTab, "");
const giganticDbNode = nodes.find((node) => node.label === giganticDb.id()); const giganticDbNode = nodes.find((node) => node.label === giganticDb.id());
expect(giganticDbNode).toBeDefined(); expect(giganticDbNode).toBeDefined();
expect(giganticDbNode.children.map((node) => node.label)).toStrictEqual(["schemaCollection", "load more"]); expect(giganticDbNode.children.map((node) => node.label)).toStrictEqual(["schemaCollection", "load more"]);
@@ -487,7 +488,7 @@ describe("createDatabaseTreeNodes", () => {
}, },
} as unknown as DataModels.DatabaseAccount, } as unknown as DataModels.DatabaseAccount,
}); });
nodes = createDatabaseTreeNodes(explorer, false, useDatabases.getState().databases, refreshActiveTab); nodes = createDatabaseTreeNodes(explorer, false, useDatabases.getState().databases, refreshActiveTab, "");
standardDbNode = nodes.find((node) => node.label === standardDb.id()); standardDbNode = nodes.find((node) => node.label === standardDb.id());
sharedDbNode = nodes.find((node) => node.label === sharedDb.id()); sharedDbNode = nodes.find((node) => node.label === sharedDb.id());
giganticDbNode = nodes.find((node) => node.label === giganticDb.id()); giganticDbNode = nodes.find((node) => node.label === giganticDb.id());
@@ -642,7 +643,7 @@ describe("createDatabaseTreeNodes", () => {
setup(); setup();
// Rebuild the nodes after changing the user/config context. // Rebuild the nodes after changing the user/config context.
nodes = createDatabaseTreeNodes(explorer, false, useDatabases.getState().databases, refreshActiveTab); nodes = createDatabaseTreeNodes(explorer, false, useDatabases.getState().databases, refreshActiveTab, "");
standardDbNode = nodes.find((node) => node.label === standardDb.id()); standardDbNode = nodes.find((node) => node.label === standardDb.id());
standardCollectionNode = standardDbNode.children.find((node) => node.label === standardCollection.id()); standardCollectionNode = standardDbNode.children.find((node) => node.label === standardCollection.id());

View File

@@ -131,8 +131,14 @@ export const createDatabaseTreeNodes = (
isNotebookEnabled: boolean, isNotebookEnabled: boolean,
databases: ViewModels.Database[], databases: ViewModels.Database[],
refreshActiveTab: (comparator: (tab: TabsBase) => boolean) => void, refreshActiveTab: (comparator: (tab: TabsBase) => boolean) => void,
searchText = "",
): TreeNode[] => { ): TreeNode[] => {
const databaseTreeNodes: TreeNode[] = databases.map((database: ViewModels.Database) => { // Filter databases based on search text
const filteredDatabases = searchText
? databases.filter((db) => db.id().toLowerCase().includes(searchText.toLowerCase()))
: databases;
const databaseTreeNodes: TreeNode[] = filteredDatabases.map((database: ViewModels.Database) => {
const buildDatabaseChildNodes = (databaseNode: TreeNode) => { const buildDatabaseChildNodes = (databaseNode: TreeNode) => {
databaseNode.children = []; databaseNode.children = [];
if (database.isDatabaseShared() && configContext.platform !== Platform.Fabric) { if (database.isDatabaseShared() && configContext.platform !== Platform.Fabric) {

View File

@@ -10,6 +10,8 @@ interface DatabasesState {
resourceTokenCollection: ViewModels.CollectionBase; resourceTokenCollection: ViewModels.CollectionBase;
sampleDataResourceTokenCollection: ViewModels.CollectionBase; sampleDataResourceTokenCollection: ViewModels.CollectionBase;
databasesFetchedSuccessfully: boolean; // Track if last database fetch was successful databasesFetchedSuccessfully: boolean; // Track if last database fetch was successful
searchText: string;
setSearchText: (searchText: string) => void;
updateDatabase: (database: ViewModels.Database) => void; updateDatabase: (database: ViewModels.Database) => void;
addDatabases: (databases: ViewModels.Database[]) => void; addDatabases: (databases: ViewModels.Database[]) => void;
deleteDatabase: (database: ViewModels.Database) => void; deleteDatabase: (database: ViewModels.Database) => void;
@@ -32,6 +34,8 @@ export const useDatabases: UseStore<DatabasesState> = create((set, get) => ({
resourceTokenCollection: undefined, resourceTokenCollection: undefined,
sampleDataResourceTokenCollection: undefined, sampleDataResourceTokenCollection: undefined,
databasesFetchedSuccessfully: false, databasesFetchedSuccessfully: false,
searchText: "",
setSearchText: (searchText: string) => set({ searchText }),
updateDatabase: (updatedDatabase: ViewModels.Database) => updateDatabase: (updatedDatabase: ViewModels.Database) =>
set((state) => { set((state) => {
const updatedDatabases = state.databases.map((database: ViewModels.Database) => { const updatedDatabases = state.databases.map((database: ViewModels.Database) => {