feishin/src/renderer/features/search/components/search-header.tsx

125 lines
4.8 KiB
TypeScript
Raw Normal View History

2023-05-19 22:26:43 -07:00
import type { AgGridReact as AgGridReactType } from '@ag-grid-community/react/lib/agGridReact';
2023-07-20 00:37:05 -07:00
import { Flex, Group, Stack } from '@mantine/core';
2023-05-19 22:26:43 -07:00
import debounce from 'lodash/debounce';
import { ChangeEvent, MutableRefObject } from 'react';
import { useTranslation } from 'react-i18next';
2023-05-19 22:26:43 -07:00
import { generatePath, Link, useParams, useSearchParams } from 'react-router-dom';
2023-05-19 22:26:43 -07:00
import { Button, PageHeader, SearchInput } from '/@/renderer/components';
import { FilterBar, LibraryHeaderBar } from '/@/renderer/features/shared';
import { useContainerQuery } from '/@/renderer/hooks';
2023-07-20 00:37:05 -07:00
import { useListFilterRefresh } from '/@/renderer/hooks/use-list-filter-refresh';
2023-05-19 22:26:43 -07:00
import { AppRoute } from '/@/renderer/router/routes';
2025-05-20 19:23:36 -07:00
import { useCurrentServer, useListStoreByKey } from '/@/renderer/store';
import {
AlbumArtistListQuery,
AlbumListQuery,
LibraryItem,
SongListQuery,
} from '/@/shared/types/domain-types';
2023-05-19 22:26:43 -07:00
interface SearchHeaderProps {
2023-07-01 19:10:05 -07:00
navigationId: string;
tableRef: MutableRefObject<AgGridReactType | null>;
2023-05-19 22:26:43 -07:00
}
export const SearchHeader = ({ navigationId, tableRef }: SearchHeaderProps) => {
const { t } = useTranslation();
2023-07-01 19:10:05 -07:00
const { itemType } = useParams() as { itemType: LibraryItem };
const [searchParams, setSearchParams] = useSearchParams();
const cq = useContainerQuery();
2023-07-20 00:37:05 -07:00
const server = useCurrentServer();
const { filter } = useListStoreByKey<AlbumArtistListQuery | AlbumListQuery | SongListQuery>({
2024-09-26 04:23:08 +00:00
key: itemType,
});
2023-07-20 00:37:05 -07:00
const { handleRefreshTable } = useListFilterRefresh({
itemType,
server,
});
2023-05-19 22:26:43 -07:00
2023-07-01 19:10:05 -07:00
const handleSearch = debounce((e: ChangeEvent<HTMLInputElement>) => {
setSearchParams({ query: e.target.value }, { replace: true, state: { navigationId } });
handleRefreshTable(tableRef, { ...filter, searchTerm: e.target.value });
2023-07-01 19:10:05 -07:00
}, 200);
2023-05-19 22:26:43 -07:00
2023-07-01 19:10:05 -07:00
return (
<Stack
ref={cq.ref}
spacing={0}
2023-05-19 22:26:43 -07:00
>
2023-07-01 19:10:05 -07:00
<PageHeader>
<Flex
justify="space-between"
w="100%"
>
<LibraryHeaderBar>
<LibraryHeaderBar.Title>Search</LibraryHeaderBar.Title>
</LibraryHeaderBar>
<Group>
<SearchInput
defaultValue={searchParams.get('query') || ''}
onChange={handleSearch}
openedWidth={cq.isMd ? 250 : cq.isSm ? 200 : 150}
2023-07-01 19:10:05 -07:00
/>
</Group>
</Flex>
</PageHeader>
<FilterBar>
<Group>
<Button
compact
component={Link}
fw={600}
replace
2023-07-01 19:10:05 -07:00
size="md"
state={{ navigationId }}
to={{
pathname: generatePath(AppRoute.SEARCH, { itemType: LibraryItem.SONG }),
search: searchParams.toString(),
}}
variant={itemType === LibraryItem.SONG ? 'filled' : 'subtle'}
>
{t('entity.track_other', { postProcess: 'sentenceCase' })}
2023-07-01 19:10:05 -07:00
</Button>
<Button
compact
component={Link}
fw={600}
replace
2023-07-01 19:10:05 -07:00
size="md"
state={{ navigationId }}
to={{
pathname: generatePath(AppRoute.SEARCH, {
itemType: LibraryItem.ALBUM,
}),
search: searchParams.toString(),
}}
variant={itemType === LibraryItem.ALBUM ? 'filled' : 'subtle'}
>
{t('entity.album_other', { postProcess: 'sentenceCase' })}
2023-07-01 19:10:05 -07:00
</Button>
<Button
compact
component={Link}
fw={600}
replace
2023-07-01 19:10:05 -07:00
size="md"
state={{ navigationId }}
to={{
pathname: generatePath(AppRoute.SEARCH, {
itemType: LibraryItem.ALBUM_ARTIST,
}),
search: searchParams.toString(),
}}
variant={itemType === LibraryItem.ALBUM_ARTIST ? 'filled' : 'subtle'}
>
{t('entity.artist_other', { postProcess: 'sentenceCase' })}
2023-07-01 19:10:05 -07:00
</Button>
</Group>
</FilterBar>
</Stack>
);
2023-05-19 22:26:43 -07:00
};