ConceptPortal-public/rsconcept/frontend/src/features/library/pages/LibraryPage/ViewSideLocation.tsx

116 lines
4.3 KiB
TypeScript
Raw Normal View History

2024-06-19 22:10:15 +03:00
import clsx from 'clsx';
2024-06-20 21:11:40 +03:00
import { toast } from 'react-toastify';
2024-06-19 22:10:15 +03:00
import { MiniButton } from '@/components/Control';
import { SubfoldersIcon } from '@/components/DomainIcons';
import { IconFolderEdit, IconFolderTree } from '@/components/Icons';
2024-06-19 22:10:15 +03:00
import { CProps } from '@/components/props';
2025-02-11 20:56:24 +03:00
import { BadgeHelp } from '@/components/shared/BadgeHelp';
import { useAuthSuspense } from '@/features/auth/backend/useAuth';
import { HelpTopic } from '@/features/help/models/helpTopic';
2025-02-11 20:56:24 +03:00
import { FolderNode } from '@/features/library/models/FolderTree';
2024-07-25 23:32:24 +03:00
import useWindowSize from '@/hooks/useWindowSize';
import { useFitHeight } from '@/stores/appLayout';
2024-06-20 22:06:35 +03:00
import { PARAMETER, prefixes } from '@/utils/constants';
import { infoMsg } from '@/utils/labels';
2024-06-19 22:10:15 +03:00
import { useLibrary } from '../../backend/useLibrary';
import SelectLocation from '../../components/SelectLocation';
import { useLibrarySearchStore } from '../../stores/librarySearch';
2024-06-27 11:35:26 +03:00
interface ViewSideLocationProps {
isVisible: boolean;
onRenameLocation: () => void;
2024-06-19 22:10:15 +03:00
}
function ViewSideLocation({ isVisible, onRenameLocation }: ViewSideLocationProps) {
const { user, isAnonymous } = useAuthSuspense();
const { items } = useLibrary();
2024-07-25 23:32:24 +03:00
const windowSize = useWindowSize();
2024-09-12 13:27:20 +03:00
const location = useLibrarySearchStore(state => state.location);
const setLocation = useLibrarySearchStore(state => state.setLocation);
const toggleFolderMode = useLibrarySearchStore(state => state.toggleFolderMode);
const subfolders = useLibrarySearchStore(state => state.subfolders);
const toggleSubfolders = useLibrarySearchStore(state => state.toggleSubfolders);
const canRename = (() => {
if (location.length <= 3 || isAnonymous) {
2024-09-12 13:27:20 +03:00
return false;
}
if (user.is_staff) {
return true;
}
const owned = items.filter(item => item.owner == user.id);
const located = owned.filter(item => item.location == location || item.location.startsWith(`${location}/`));
2024-09-12 13:27:20 +03:00
return located.length !== 0;
})();
2024-09-12 13:27:20 +03:00
const maxHeight = useFitHeight('4.5rem');
2024-09-12 13:27:20 +03:00
function handleClickFolder(event: CProps.EventMouse, target: FolderNode) {
event.preventDefault();
event.stopPropagation();
if (event.ctrlKey || event.metaKey) {
navigator.clipboard
.writeText(target.getPath())
.then(() => toast.success(infoMsg.pathReady))
.catch(console.error);
} else {
setLocation(target.getPath());
}
}
2024-06-19 22:10:15 +03:00
return (
<div
2024-07-25 23:32:24 +03:00
className={clsx('max-w-[10rem] sm:max-w-[15rem]', 'flex flex-col', 'text:xs sm:text-sm', 'select-none')}
style={{
transitionProperty: 'width, min-width, opacity',
transitionDuration: `${PARAMETER.moveDuration}ms`,
transitionTimingFunction: 'ease-out',
minWidth: isVisible ? (windowSize.isSmall ? '10rem' : '15rem') : '0',
width: isVisible ? '100%' : '0',
opacity: isVisible ? 1 : 0
}}
2024-06-19 22:10:15 +03:00
>
2024-07-19 20:43:09 +03:00
<div className='h-[2.08rem] flex justify-between items-center pr-1 pl-[0.125rem]'>
2024-06-20 11:28:35 +03:00
<BadgeHelp
topic={HelpTopic.UI_LIBRARY}
className={clsx(PARAMETER.TOOLTIP_WIDTH, 'text-sm')}
offset={5}
place='right-start'
/>
<div className='cc-icons'>
2024-09-27 12:04:10 +03:00
{canRename ? (
<MiniButton
icon={<IconFolderEdit size='1.25rem' className='icon-primary' />}
titleHtml='<b>Редактирование пути</b><br/>Перемещаются только Ваши схемы<br/>в указанной папке (и подпапках)'
onClick={onRenameLocation}
/>
) : null}
{!!location ? (
2024-12-13 13:22:21 +03:00
<MiniButton
title={subfolders ? 'Вложенные папки: Вкл' : 'Вложенные папки: Выкл'} // prettier: split-lines
icon={<SubfoldersIcon value={subfolders} />}
onClick={toggleSubfolders}
/>
) : null}
<MiniButton
icon={<IconFolderTree size='1.25rem' className='icon-green' />}
title='Переключение в режим Поиск'
onClick={toggleFolderMode}
/>
</div>
2024-06-19 22:10:15 +03:00
</div>
2024-06-26 19:00:29 +03:00
<SelectLocation
value={location}
2024-06-26 19:00:29 +03:00
prefix={prefixes.folders_list}
onClick={handleClickFolder}
2024-09-19 20:52:37 +03:00
style={{ maxHeight: maxHeight }}
2024-06-26 19:00:29 +03:00
/>
</div>
2024-06-19 22:10:15 +03:00
);
}
2024-06-27 11:35:26 +03:00
export default ViewSideLocation;