2023-12-13 14:32:57 +03:00
|
|
|
'use client';
|
2023-08-26 19:39:49 +03:00
|
|
|
|
2023-12-15 17:34:50 +03:00
|
|
|
import clsx from 'clsx';
|
2023-08-27 15:39:49 +03:00
|
|
|
|
2025-02-26 00:16:41 +03:00
|
|
|
import { SelectUser } from '@/features/users/components';
|
2025-02-12 21:36:25 +03:00
|
|
|
|
2025-03-12 11:55:43 +03:00
|
|
|
import { MiniButton, SelectorButton } from '@/components/control1';
|
|
|
|
import { Dropdown, DropdownButton, useDropdown } from '@/components/dropdown1';
|
2024-09-27 12:04:10 +03:00
|
|
|
import {
|
|
|
|
IconEditor,
|
|
|
|
IconFilterReset,
|
|
|
|
IconFolder,
|
|
|
|
IconFolderSearch,
|
|
|
|
IconFolderTree,
|
|
|
|
IconOwner,
|
|
|
|
IconUserSearch
|
2025-03-12 11:55:43 +03:00
|
|
|
} from '@/components/icons1';
|
|
|
|
import { SearchBar } from '@/components/input1';
|
2024-06-21 11:17:50 +03:00
|
|
|
import { prefixes } from '@/utils/constants';
|
2024-06-02 23:41:46 +03:00
|
|
|
import { tripleToggleColor } from '@/utils/utils';
|
2023-08-26 19:39:49 +03:00
|
|
|
|
2025-03-12 11:55:43 +03:00
|
|
|
import { IconItemVisibility } from '../../components/icon-item-visibility';
|
|
|
|
import { IconLocationHead } from '../../components/icon-location-head';
|
2025-02-11 20:56:24 +03:00
|
|
|
import { describeLocationHead, labelLocationHead } from '../../labels';
|
2025-02-10 01:32:55 +03:00
|
|
|
import { LocationHead } from '../../models/library';
|
2025-03-12 11:55:43 +03:00
|
|
|
import { useHasCustomFilter, useLibrarySearchStore } from '../../stores/library-search';
|
2025-02-10 01:32:55 +03:00
|
|
|
|
2024-06-26 19:47:31 +03:00
|
|
|
interface ToolbarSearchProps {
|
2025-03-11 14:42:41 +03:00
|
|
|
className?: string;
|
2023-12-28 14:04:44 +03:00
|
|
|
total: number;
|
|
|
|
filtered: number;
|
2023-08-26 19:39:49 +03:00
|
|
|
}
|
|
|
|
|
2025-03-11 14:42:41 +03:00
|
|
|
export function ToolbarSearch({ className, total, filtered }: ToolbarSearchProps) {
|
2024-06-02 23:41:46 +03:00
|
|
|
const headMenu = useDropdown();
|
2024-09-27 12:04:10 +03:00
|
|
|
const userMenu = useDropdown();
|
|
|
|
|
2025-01-15 16:06:42 +03:00
|
|
|
const query = useLibrarySearchStore(state => state.query);
|
|
|
|
const setQuery = useLibrarySearchStore(state => state.setQuery);
|
|
|
|
const path = useLibrarySearchStore(state => state.path);
|
|
|
|
const setPath = useLibrarySearchStore(state => state.setPath);
|
|
|
|
const head = useLibrarySearchStore(state => state.head);
|
|
|
|
const setHead = useLibrarySearchStore(state => state.setHead);
|
|
|
|
const folderMode = useLibrarySearchStore(state => state.folderMode);
|
|
|
|
const toggleFolderMode = useLibrarySearchStore(state => state.toggleFolderMode);
|
|
|
|
const isOwned = useLibrarySearchStore(state => state.isOwned);
|
|
|
|
const toggleOwned = useLibrarySearchStore(state => state.toggleOwned);
|
|
|
|
const isEditor = useLibrarySearchStore(state => state.isEditor);
|
|
|
|
const toggleEditor = useLibrarySearchStore(state => state.toggleEditor);
|
|
|
|
const isVisible = useLibrarySearchStore(state => state.isVisible);
|
|
|
|
const toggleVisible = useLibrarySearchStore(state => state.toggleVisible);
|
|
|
|
const filterUser = useLibrarySearchStore(state => state.filterUser);
|
|
|
|
const setFilterUser = useLibrarySearchStore(state => state.setFilterUser);
|
|
|
|
|
|
|
|
const resetFilter = useLibrarySearchStore(state => state.resetFilter);
|
|
|
|
const hasCustomFilter = useHasCustomFilter();
|
|
|
|
|
2025-02-19 22:33:09 +03:00
|
|
|
const userActive = isOwned !== null || isEditor !== null || filterUser !== null;
|
2023-08-27 15:39:49 +03:00
|
|
|
|
2025-02-19 22:33:09 +03:00
|
|
|
function handleChange(newValue: LocationHead | null) {
|
2024-12-13 21:31:09 +03:00
|
|
|
headMenu.hide();
|
2025-01-15 16:06:42 +03:00
|
|
|
setHead(newValue);
|
2024-12-13 21:31:09 +03:00
|
|
|
}
|
2024-05-02 17:04:18 +03:00
|
|
|
|
2024-12-13 21:31:09 +03:00
|
|
|
function handleToggleFolder() {
|
2024-06-19 22:10:15 +03:00
|
|
|
headMenu.hide();
|
|
|
|
toggleFolderMode();
|
2024-12-13 21:31:09 +03:00
|
|
|
}
|
|
|
|
|
2025-02-22 14:04:01 +03:00
|
|
|
function handleFolderClick(event: React.MouseEvent<Element>) {
|
2024-12-13 21:31:09 +03:00
|
|
|
if (event.ctrlKey || event.metaKey) {
|
|
|
|
toggleFolderMode();
|
|
|
|
} else {
|
|
|
|
headMenu.toggle();
|
|
|
|
}
|
|
|
|
}
|
2024-06-19 22:10:15 +03:00
|
|
|
|
2023-08-26 19:39:49 +03:00
|
|
|
return (
|
2025-03-11 14:42:41 +03:00
|
|
|
<div className={clsx('flex gap-3 border-b text-sm clr-input items-center', className)}>
|
2025-03-10 16:02:53 +03:00
|
|
|
<div className='ml-3 min-w-18 sm:min-w-30 select-none whitespace-nowrap'>
|
2024-06-05 19:42:48 +03:00
|
|
|
{filtered} из {total}
|
2023-12-28 14:04:44 +03:00
|
|
|
</div>
|
2024-06-02 23:41:46 +03:00
|
|
|
|
2025-03-10 16:02:53 +03:00
|
|
|
<div className='cc-icons h-full items-center'>
|
2024-09-27 12:04:10 +03:00
|
|
|
<MiniButton
|
|
|
|
title='Видимость'
|
2025-02-26 00:16:41 +03:00
|
|
|
icon={<IconItemVisibility value={true} className={tripleToggleColor(isVisible)} />}
|
2024-09-27 12:04:10 +03:00
|
|
|
onClick={toggleVisible}
|
|
|
|
/>
|
2024-06-18 15:07:41 +03:00
|
|
|
|
2025-03-07 02:46:19 +03:00
|
|
|
<div ref={userMenu.ref} className='relative flex'>
|
2024-06-18 15:07:41 +03:00
|
|
|
<MiniButton
|
2024-09-27 12:04:10 +03:00
|
|
|
title='Поиск пользователя'
|
|
|
|
hideTitle={userMenu.isOpen}
|
|
|
|
icon={<IconUserSearch size='1.25rem' className={userActive ? 'icon-green' : 'icon-primary'} />}
|
|
|
|
onClick={userMenu.toggle}
|
2024-06-18 15:07:41 +03:00
|
|
|
/>
|
2025-03-10 16:02:53 +03:00
|
|
|
<Dropdown isOpen={userMenu.isOpen}>
|
2024-09-27 12:04:10 +03:00
|
|
|
<DropdownButton
|
|
|
|
text='Я - Владелец'
|
|
|
|
icon={<IconOwner size='1.25rem' className={tripleToggleColor(isOwned)} />}
|
|
|
|
onClick={toggleOwned}
|
|
|
|
/>
|
|
|
|
<DropdownButton
|
|
|
|
text='Я - Редактор'
|
|
|
|
icon={<IconEditor size='1.25rem' className={tripleToggleColor(isEditor)} />}
|
|
|
|
onClick={toggleEditor}
|
|
|
|
/>
|
2024-12-12 13:19:12 +03:00
|
|
|
<SelectUser
|
|
|
|
noBorder
|
|
|
|
placeholder='Выберите владельца'
|
2025-03-09 21:59:21 +03:00
|
|
|
className='min-w-60 text-sm mx-1 mb-1'
|
2024-12-12 13:19:12 +03:00
|
|
|
value={filterUser}
|
2025-02-04 20:35:55 +03:00
|
|
|
onChange={setFilterUser}
|
2024-12-12 13:19:12 +03:00
|
|
|
/>
|
2024-09-27 12:04:10 +03:00
|
|
|
</Dropdown>
|
2024-06-14 21:43:37 +03:00
|
|
|
</div>
|
2024-06-02 23:41:46 +03:00
|
|
|
|
2024-09-27 12:04:10 +03:00
|
|
|
<MiniButton
|
|
|
|
title='Сбросить фильтры'
|
|
|
|
icon={<IconFilterReset size='1.25rem' className='icon-primary' />}
|
|
|
|
onClick={resetFilter}
|
|
|
|
disabled={!hasCustomFilter}
|
|
|
|
/>
|
|
|
|
</div>
|
|
|
|
|
2025-02-21 21:15:05 +03:00
|
|
|
<div className='flex h-full grow pr-4'>
|
2024-06-02 23:41:46 +03:00
|
|
|
<SearchBar
|
|
|
|
id='library_search'
|
2024-06-05 19:42:48 +03:00
|
|
|
placeholder='Поиск'
|
2024-06-02 23:41:46 +03:00
|
|
|
noBorder
|
2025-03-09 21:59:21 +03:00
|
|
|
className={clsx('min-w-28 sm:min-w-40 max-w-80', folderMode && 'grow')}
|
2024-11-21 15:09:51 +03:00
|
|
|
query={query}
|
2025-01-15 16:06:42 +03:00
|
|
|
onChangeQuery={setQuery}
|
2024-06-02 23:41:46 +03:00
|
|
|
/>
|
2024-06-19 22:10:15 +03:00
|
|
|
{!folderMode ? (
|
2025-03-10 16:02:53 +03:00
|
|
|
<div ref={headMenu.ref} className='relative flex items-center h-full select-none'>
|
2024-06-19 22:10:15 +03:00
|
|
|
<SelectorButton
|
|
|
|
transparent
|
2025-03-10 16:02:53 +03:00
|
|
|
className='rounded-lg py-1'
|
2024-06-19 22:10:15 +03:00
|
|
|
titleHtml={(head ? describeLocationHead(head) : 'Выберите каталог') + '<br/>Ctrl + клик - Проводник'}
|
|
|
|
hideTitle={headMenu.isOpen}
|
|
|
|
icon={
|
|
|
|
head ? (
|
2025-02-26 00:16:41 +03:00
|
|
|
<IconLocationHead value={head} size='1.25rem' />
|
2024-06-19 22:10:15 +03:00
|
|
|
) : (
|
2024-09-27 12:04:10 +03:00
|
|
|
<IconFolderSearch size='1.25rem' className='clr-text-controls' />
|
2024-06-19 22:10:15 +03:00
|
|
|
)
|
|
|
|
}
|
|
|
|
onClick={handleFolderClick}
|
|
|
|
text={head ?? '//'}
|
|
|
|
/>
|
|
|
|
|
2025-03-07 20:38:40 +03:00
|
|
|
<Dropdown isOpen={headMenu.isOpen} stretchLeft>
|
2025-03-09 21:59:21 +03:00
|
|
|
<DropdownButton
|
|
|
|
title='Переключение в режим Проводник'
|
|
|
|
text='проводник...'
|
|
|
|
icon={<IconFolderTree size='1rem' className='clr-text-controls' />}
|
|
|
|
onClick={handleToggleFolder}
|
|
|
|
/>
|
|
|
|
<DropdownButton
|
|
|
|
text='отображать все'
|
|
|
|
icon={<IconFolder size='1rem' className='clr-text-controls' />}
|
|
|
|
onClick={() => handleChange(null)}
|
|
|
|
/>
|
2024-06-19 22:10:15 +03:00
|
|
|
{Object.values(LocationHead).map((head, index) => {
|
|
|
|
return (
|
|
|
|
<DropdownButton
|
|
|
|
key={`${prefixes.location_head_list}${index}`}
|
|
|
|
onClick={() => handleChange(head)}
|
|
|
|
title={describeLocationHead(head)}
|
2025-03-09 21:59:21 +03:00
|
|
|
text={labelLocationHead(head)}
|
|
|
|
icon={<IconLocationHead value={head} size='1rem' />}
|
|
|
|
/>
|
2024-06-19 22:10:15 +03:00
|
|
|
);
|
|
|
|
})}
|
|
|
|
</Dropdown>
|
|
|
|
</div>
|
|
|
|
) : null}
|
|
|
|
{!folderMode ? (
|
|
|
|
<SearchBar
|
|
|
|
id='path_search'
|
|
|
|
placeholder='Путь'
|
|
|
|
noIcon
|
|
|
|
noBorder
|
2025-03-09 21:59:21 +03:00
|
|
|
className='w-18 sm:w-20 grow'
|
2024-11-21 15:09:51 +03:00
|
|
|
query={path}
|
2025-01-15 16:06:42 +03:00
|
|
|
onChangeQuery={setPath}
|
2024-06-02 23:41:46 +03:00
|
|
|
/>
|
2024-06-19 22:10:15 +03:00
|
|
|
) : null}
|
2024-06-02 23:41:46 +03:00
|
|
|
</div>
|
2023-11-27 11:33:34 +03:00
|
|
|
</div>
|
2023-12-28 14:04:44 +03:00
|
|
|
);
|
2023-08-26 19:39:49 +03:00
|
|
|
}
|