From dcfee2e1e4eeb4d52bb69c6c0a042606d148748e Mon Sep 17 00:00:00 2001 From: Mary Hipp Date: Thu, 15 Jun 2023 14:26:40 -0400 Subject: [PATCH] add searching to boards list --- .../gallery/components/Boards/BoardsList.tsx | 38 +++++++++++++++---- .../components/ImageGalleryContent.tsx | 5 +-- .../features/gallery/store/boardSelectors.ts | 22 ++++++++++- .../src/features/gallery/store/boardSlice.ts | 13 ++++++- 4 files changed, 64 insertions(+), 14 deletions(-) diff --git a/invokeai/frontend/web/src/features/gallery/components/Boards/BoardsList.tsx b/invokeai/frontend/web/src/features/gallery/components/Boards/BoardsList.tsx index 8603f28c9c..9e7d1ab960 100644 --- a/invokeai/frontend/web/src/features/gallery/components/Boards/BoardsList.tsx +++ b/invokeai/frontend/web/src/features/gallery/components/Boards/BoardsList.tsx @@ -1,16 +1,19 @@ -import { Grid } from '@chakra-ui/react'; +import { Box, Grid, Input, Spacer } from '@chakra-ui/react'; import { createSelector } from '@reduxjs/toolkit'; -import { useAppSelector } from 'app/store/storeHooks'; +import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions'; import { boardsSelector, selectBoardsAll, + setBoardSearchText, } from 'features/gallery/store/boardSlice'; -import { memo, useState } from 'react'; +import { memo, useEffect, useState } from 'react'; import HoverableBoard from './HoverableBoard'; import { OverlayScrollbarsComponent } from 'overlayscrollbars-react'; import AddBoardButton from './AddBoardButton'; import AllImagesBoard from './AllImagesBoard'; +import { searchBoardsSelector } from '../../store/boardSelectors'; +import { useSelector } from 'react-redux'; const selector = createSelector( [selectBoardsAll, boardsSelector], @@ -21,7 +24,16 @@ const selector = createSelector( ); const BoardsList = () => { - const { boards, selectedBoardId } = useAppSelector(selector); + const dispatch = useAppDispatch(); + const { selectedBoardId } = useAppSelector(selector); + const filteredBoards = useSelector(searchBoardsSelector); + + const [searchMode, setSearchMode] = useState(false); + + const handleBoardSearch = (searchTerm: string) => { + setSearchMode(searchTerm.length > 0); + dispatch(setBoardSearchText(searchTerm)); + }; return ( { }, }} > + + { + handleBoardSearch(e.target.value); + }} + /> + { gridAutoColumns: '4rem', }} > - - - {boards.map((board) => ( + {!searchMode && ( + <> + + + + )} + {filteredBoards.map((board) => ( { + (gallery, ui, boards) => { const { galleryImageMinimumWidth, galleryImageObjectFit, @@ -101,9 +101,6 @@ const mainSelector = createSelector( } = gallery; const { shouldPinGallery } = ui; - - const { entities: boards } = boardState; - return { shouldPinGallery, galleryImageMinimumWidth, diff --git a/invokeai/frontend/web/src/features/gallery/store/boardSelectors.ts b/invokeai/frontend/web/src/features/gallery/store/boardSelectors.ts index 4bc98553af..3dac2b6e50 100644 --- a/invokeai/frontend/web/src/features/gallery/store/boardSelectors.ts +++ b/invokeai/frontend/web/src/features/gallery/store/boardSelectors.ts @@ -1,3 +1,23 @@ +import { createSelector } from '@reduxjs/toolkit'; import { RootState } from 'app/store/store'; +import { selectBoardsAll } from './boardSlice'; -export const boardSelector = (state: RootState) => state.boards; +export const boardSelector = (state: RootState) => state.boards.entities; + +export const searchBoardsSelector = createSelector( + (state: RootState) => state, + (state) => { + const { + boards: { searchText }, + } = state; + + if (!searchText) { + // If no search text provided, return all entities + return selectBoardsAll(state); + } + + return selectBoardsAll(state).filter((i) => + i.board_name.toLowerCase().includes(searchText.toLowerCase()) + ); + } +); diff --git a/invokeai/frontend/web/src/features/gallery/store/boardSlice.ts b/invokeai/frontend/web/src/features/gallery/store/boardSlice.ts index d2e9a451d3..fc67b4f26a 100644 --- a/invokeai/frontend/web/src/features/gallery/store/boardSlice.ts +++ b/invokeai/frontend/web/src/features/gallery/store/boardSlice.ts @@ -26,6 +26,7 @@ type AdditionalBoardsState = { total: number; isLoading: boolean; selectedBoardId: EntityId | null; + searchText?: string; }; export const initialBoardsState = @@ -55,6 +56,9 @@ const boardsSlice = createSlice({ boardIdSelected: (state, action: PayloadAction) => { state.selectedBoardId = action.payload; }, + setBoardSearchText: (state, action: PayloadAction) => { + state.searchText = action.payload; + }, }, extraReducers: (builder) => { builder.addCase(receivedBoards.pending, (state) => { @@ -95,8 +99,13 @@ export const { selectTotal: selectBoardsTotal, } = boardsAdapter.getSelectors((state) => state.boards); -export const { boardUpserted, boardUpdatedOne, boardRemoved, boardIdSelected } = - boardsSlice.actions; +export const { + boardUpserted, + boardUpdatedOne, + boardRemoved, + boardIdSelected, + setBoardSearchText, +} = boardsSlice.actions; export const boardsSelector = (state: RootState) => state.boards;