Merge pull request #7 from usebruno/feature/search-collections

feat: search collections, resolves #1
This commit is contained in:
Anoop M D 2022-10-01 18:24:32 +05:30 committed by GitHub
commit 2313afdb82
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 75 additions and 11 deletions

View File

@ -1,4 +1,4 @@
import React, { useState, useRef, forwardRef } from 'react';
import React, { useState, useRef, forwardRef, useEffect } from 'react';
import range from 'lodash/range';
import classnames from 'classnames';
import { IconChevronRight, IconDots } from '@tabler/icons';
@ -13,10 +13,11 @@ import RenameCollectionItem from './RenameCollectionItem';
import CloneCollectionItem from './CloneCollectionItem';
import DeleteCollectionItem from './DeleteCollectionItem';
import { isItemARequest, isItemAFolder, itemIsOpenedInTabs } from 'utils/tabs';
import { doesRequestMatchSearchText, doesFolderHaveItemsMatchSearchText } from 'utils/collections/search';
import StyledWrapper from './StyledWrapper';
const CollectionItem = ({item, collection}) => {
const CollectionItem = ({item, collection, searchText}) => {
const tabs = useSelector((state) => state.tabs.tabs);
const activeTabUid = useSelector((state) => state.tabs.activeTabUid);
const isDragging = useSelector((state) => state.app.isDragging);
@ -27,6 +28,15 @@ const CollectionItem = ({item, collection}) => {
const [deleteItemModalOpen, setDeleteItemModalOpen] = useState(false);
const [newRequestModalOpen, setNewRequestModalOpen] = useState(false);
const [newFolderModalOpen, setNewFolderModalOpen] = useState(false);
const [itemIsCollapsed, setItemisCollapsed] = useState(item.collapsed);
useEffect(() => {
if (searchText && searchText.length) {
setItemisCollapsed(false);
} else {
setItemisCollapsed(item.collapsed);
}
}, [searchText, item]);
const dropdownTippyRef = useRef();
const MenuIcon = forwardRef((props, ref) => {
@ -38,7 +48,7 @@ const CollectionItem = ({item, collection}) => {
});
const iconClassName = classnames({
'rotate-90': item.collapsed
'rotate-90': !itemIsCollapsed
});
const itemRowClassName = classnames('flex collection-item-name items-center', {
@ -73,6 +83,18 @@ const CollectionItem = ({item, collection}) => {
'is-dragging': isDragging
});
if(searchText && searchText.length) {
if(isItemARequest(item)) {
if(!doesRequestMatchSearchText(item, searchText)) {
return null;
}
} else {
if (!doesFolderHaveItemsMatchSearchText(item, searchText)) {
return null;
};
}
}
return (
<StyledWrapper className={className}>
{renameItemModalOpen && <RenameCollectionItem item={item} collection={collection} onClose={() => setRenameItemModalOpen(false)}/>}
@ -159,13 +181,14 @@ const CollectionItem = ({item, collection}) => {
</div>
</div>
{item.collapsed ? (
{!itemIsCollapsed ? (
<div>
{item.items && item.items.length ? item.items.map((i) => {
return <CollectionItem
key={i.uid}
item={i}
collection={collection}
searchText={searchText}
/>
}) : null}
</div>

View File

@ -1,4 +1,4 @@
import React, { useState, forwardRef, useRef } from 'react';
import React, { useState, forwardRef, useRef, useEffect } from 'react';
import classnames from 'classnames';
import { IconChevronRight, IconDots } from '@tabler/icons';
import Dropdown from 'components/Dropdown';
@ -7,14 +7,24 @@ import { useDispatch } from 'react-redux';
import NewRequest from 'components/Sidebar/NewRequest';
import NewFolder from 'components/Sidebar/NewFolder';
import CollectionItem from './CollectionItem';
import { doesCollectionHaveItemsMatchingSearchText } from 'utils/collections/search';
import StyledWrapper from './StyledWrapper';
const Collection = ({collection}) => {
const Collection = ({collection, searchText}) => {
const [showNewFolderModal, setShowNewFolderModal] = useState(false);
const [showNewRequestModal, setShowNewRequestModal] = useState(false);
const [collectionIsCollapsed, setCollectionIsCollapsed] = useState(collection.collapsed);
const dispatch = useDispatch();
useEffect(() => {
if (searchText && searchText.length) {
setCollectionIsCollapsed(false);
} else {
setCollectionIsCollapsed(collection.collapsed);
}
}, [searchText, collection]);
const menuDropdownTippyRef = useRef();
const onMenuDropdownCreate = (ref) => menuDropdownTippyRef.current = ref;
const MenuIcon = forwardRef((props, ref) => {
@ -26,13 +36,19 @@ const Collection = ({collection}) => {
});
const iconClassName = classnames({
'rotate-90': !collection.collapsed
'rotate-90': !collectionIsCollapsed
});
const handleClick = (event) => {
dispatch(collectionClicked(collection.uid));
};
if(searchText && searchText.length) {
if(!doesCollectionHaveItemsMatchingSearchText(collection, searchText)) {
return null;
}
}
return (
<StyledWrapper className="flex flex-col">
{showNewRequestModal && <NewRequest collection={collection} onClose={() => setShowNewRequestModal(false)}/>}
@ -71,13 +87,14 @@ const Collection = ({collection}) => {
</div>
<div>
{!collection.collapsed ? (
{!collectionIsCollapsed ? (
<div>
{collection.items && collection.items.length ? collection.items.map((i) => {
return <CollectionItem
key={i.uid}
item={i}
collection={collection}
searchText={searchText}
/>
}) : null}
</div>

View File

@ -1,8 +1,8 @@
import React from 'react';
import React, { useEffect, useState } from 'react';
import { useSelector } from 'react-redux';
import Collection from './Collection';
const Collections = () => {
const Collections = ({searchText}) => {
const collections = useSelector((state) => state.collections.collections);
console.log(collections);
@ -10,6 +10,7 @@ const Collections = () => {
<div className="mt-4 flex flex-col">
{collections && collections.length ? collections.map((c) => {
return <Collection
searchText={searchText}
collection={c}
key={c.uid}
/>

View File

@ -18,6 +18,7 @@ const Sidebar = () => {
const dispatch = useDispatch();
const [dragging, setDragging] = useState(false);
const [searchText, setSearchText] = useState('');
const handleMouseMove = (e) => {
if(dragging) {
@ -86,10 +87,11 @@ const Sidebar = () => {
autoComplete="off" autoCorrect="off" autoCapitalize="off" spellCheck="false"
className="block w-full pl-7 py-1 sm:text-sm"
placeholder="search"
onChange={(e) => setSearchText(e.target.value.toLowerCase())}
/>
</div>
<Collections />
<Collections searchText={searchText}/>
</div>
<div className="flex px-1 py-2 items-center cursor-pointer text-gray-500 select-none">
<div className="flex items-center ml-1 text-xs ">

View File

@ -0,0 +1,21 @@
import { flattenItems, isItemARequest } from "./index";
import filter from 'lodash/filter';
import find from 'lodash/find';
export const doesRequestMatchSearchText = (request, searchText) => {
return request.name.toLowerCase().includes(searchText.toLowerCase());
};
export const doesFolderHaveItemsMatchSearchText = (item, searchText) => {
let flattenedItems = flattenItems(item.items);
let requestItems = filter(flattenedItems, (item) => isItemARequest(item));
return find(requestItems, (request) => doesRequestMatchSearchText(request, searchText));
};
export const doesCollectionHaveItemsMatchingSearchText = (collection, searchText) => {
let flattenedItems = flattenItems(collection.items);
let requestItems = filter(flattenedItems, (item) => isItemARequest(item));
return find(requestItems, (request) => doesRequestMatchSearchText(request, searchText));
}