Compare commits

...

4 Commits

Author SHA1 Message Date
IRBorisov
d7ee1db6a9 Fix centering when list is hidden
Some checks are pending
Frontend CI / build (18.x) (push) Waiting to run
2024-06-20 14:35:09 +03:00
IRBorisov
7d41953a8d Fix folder switch 2024-06-20 11:50:26 +03:00
IRBorisov
fdbb05df70 Update icons and help 2024-06-20 11:28:22 +03:00
IRBorisov
142f3882bb Fix folder naming 2024-06-20 11:06:47 +03:00
9 changed files with 88 additions and 37 deletions

View File

@ -32,9 +32,10 @@ export { RiMenuUnfoldFill as IconMenuUnfold } from 'react-icons/ri';
export { LuMoon as IconDarkTheme } from 'react-icons/lu';
export { LuSun as IconLightTheme } from 'react-icons/lu';
export { LuFolderTree as IconFolderTree } from 'react-icons/lu';
export { FaRegFolder as IconFolder } from 'react-icons/fa6';
export { FaRegFolderOpen as IconFolderOpened } from 'react-icons/fa6';
export { FaRegFolderClosed as IconFolderClosed } from 'react-icons/fa6';
export { LuFolder as IconFolder } from 'react-icons/lu';
export { LuFolderOpen as IconFolderOpened } from 'react-icons/lu';
export { LuFolderClosed as IconFolderClosed } from 'react-icons/lu';
export { LuFolderDot as IconFolderEmpty } from 'react-icons/lu';
export { LuLightbulb as IconHelp } from 'react-icons/lu';
export { LuLightbulbOff as IconHelpOff } from 'react-icons/lu';
export { RiPushpinFill as IconPin } from 'react-icons/ri';

View File

@ -77,11 +77,12 @@ export const LibraryState = ({ children }: LibraryStateProps) => {
const [cachedTemplates, setCachedTemplates] = useState<IRSForm[]>([]);
const folders = useMemo(() => {
const result = new FolderTree(items.map(item => item.location));
const result = new FolderTree();
result.addPath(LocationHead.USER, 0);
result.addPath(LocationHead.COMMON, 0);
result.addPath(LocationHead.LIBRARY, 0);
result.addPath(LocationHead.PROJECTS, 0);
items.forEach(item => result.addPath(item.location));
return result;
}, [items]);

View File

@ -102,7 +102,9 @@ export class FolderTree {
private visitNode(target: FolderNode, result: FolderNode[]) {
result.push(target);
target.children.forEach(child => this.visitNode(child, result));
[...target.children.keys()]
.sort((a, b) => a.localeCompare(b))
.forEach(key => this.visitNode(target.children.get(key)!, result));
}
addPath(path: string, filesCount: number = 1): FolderNode {

View File

@ -4,12 +4,14 @@ import clsx from 'clsx';
import { AnimatePresence, motion } from 'framer-motion';
import { useCallback, useLayoutEffect, useMemo, useState } from 'react';
import { IconFolder, IconFolderClosed, IconFolderOpened, IconFolderTree } from '@/components/Icons';
import { IconFolder, IconFolderClosed, IconFolderEmpty, IconFolderOpened, IconFolderTree } from '@/components/Icons';
import BadgeHelp from '@/components/info/BadgeHelp';
import { CProps } from '@/components/props';
import MiniButton from '@/components/ui/MiniButton';
import { FolderNode, FolderTree } from '@/models/FolderTree';
import { HelpTopic } from '@/models/miscellaneous';
import { animateSideAppear, animateSideView } from '@/styling/animations';
import { globals, prefixes } from '@/utils/constants';
import { globals, PARAMETER, prefixes } from '@/utils/constants';
import { describeFolderNode, labelFolderNode } from '@/utils/labels';
interface LibraryTableProps {
@ -72,10 +74,16 @@ function LibraryFolders({ folders, currentFolder, setFolder, toggleFolderMode }:
animate={{ ...animateSideView.animate }}
exit={{ ...animateSideView.exit }}
>
<div className='h-[2.08rem] flex justify-end pr-1'>
<div className='h-[2.08rem] flex justify-between items-center pr-1'>
<BadgeHelp
topic={HelpTopic.UI_LIBRARY}
className={clsx(PARAMETER.TOOLTIP_WIDTH, 'text-sm')}
offset={5}
place='right-start'
/>
<MiniButton
icon={<IconFolderTree size='1.25rem' className='icon-green' />}
title='Режим: проводник'
title='Переключение в режим Поиск'
onClick={toggleFolderMode}
/>
</div>
@ -114,7 +122,11 @@ function LibraryFolders({ folders, currentFolder, setFolder, toggleFolderMode }:
noHover
icon={
folded.includes(item) ? (
<IconFolderClosed size='1rem' className='icon-primary' />
item.filesInside ? (
<IconFolderClosed size='1rem' className='icon-primary' />
) : (
<IconFolderEmpty size='1rem' className='icon-primary' />
)
) : (
<IconFolderOpened size='1rem' className='icon-green' />
)
@ -123,7 +135,11 @@ function LibraryFolders({ folders, currentFolder, setFolder, toggleFolderMode }:
/>
) : (
<div>
<IconFolder size='1rem' />
{item.filesInside ? (
<IconFolder size='1rem' className='clr-text-default' />
) : (
<IconFolderEmpty size='1rem' className='clr-text-controls' />
)}
</div>
)}
<div className='self-center'>{labelFolderNode(item)}</div>

View File

@ -5,7 +5,7 @@ import { useCallback, useLayoutEffect, useMemo, useState } from 'react';
import { useIntl } from 'react-intl';
import { urls } from '@/app/urls';
import { IconFolder } from '@/components/Icons';
import { IconFolderTree } from '@/components/Icons';
import BadgeLocation from '@/components/info/BadgeLocation';
import { CProps } from '@/components/props';
import DataTable, { createColumnHelper, IConditionalStyle, VisibilityState } from '@/components/ui/DataTable';
@ -56,11 +56,9 @@ function LibraryTable({ items, resetQuery, folderMode, toggleFolderMode }: Libra
const handleToggleFolder = useCallback(
(event: CProps.EventMouse) => {
if (event.ctrlKey) {
event.preventDefault();
event.stopPropagation();
toggleFolderMode();
}
event.preventDefault();
event.stopPropagation();
toggleFolderMode();
},
[toggleFolderMode]
);
@ -74,12 +72,12 @@ function LibraryTable({ items, resetQuery, folderMode, toggleFolderMode }: Libra
id: 'location',
header: () => (
<MiniButton
noHover
noPadding
noHover
className='pl-2 max-h-[1rem] translate-y-[-0.125rem]'
onClick={handleToggleFolder}
titleHtml='Ctrl + клик для переключения </br>в режим папок'
icon={<IconFolder size='1.25rem' className='clr-text-controls' />}
titleHtml='Переключение в режим Проводник'
icon={<IconFolderTree size='1.25rem' className='clr-text-controls' />}
/>
),
size: 50,

View File

@ -176,6 +176,12 @@ function SearchPanel({
/>
<Dropdown isOpen={headMenu.isOpen} stretchLeft className='z-modalTooltip'>
<DropdownButton className='w-[10rem]' title='Переключение в режим Проводник' onClick={handleToggleFolder}>
<div className='inline-flex items-center gap-3'>
<IconFolderTree size='1rem' className='clr-text-controls' />
<span>проводник...</span>
</div>
</DropdownButton>
<DropdownButton className='w-[10rem]' onClick={() => handleChange(undefined)}>
<div className='inline-flex items-center gap-3'>
<IconFolder size='1rem' className='clr-text-controls' />
@ -197,16 +203,6 @@ function SearchPanel({
</DropdownButton>
);
})}
<DropdownButton
className='w-[10rem]'
title='переключение в режим выбора папок'
onClick={handleToggleFolder}
>
<div className='inline-flex items-center gap-3'>
<IconFolderTree size='1rem' className='clr-text-controls' />
<span>проводник...</span>
</div>
</DropdownButton>
</Dropdown>
</div>
) : null}

View File

@ -1,4 +1,14 @@
import { IconFolder, IconSearch, IconShow, IconSortAsc, IconSortDesc } from '@/components/Icons';
import {
IconFolder,
IconFolderClosed,
IconFolderEmpty,
IconFolderOpened,
IconFolderTree,
IconSearch,
IconShow,
IconSortAsc,
IconSortDesc
} from '@/components/Icons';
function HelpLibrary() {
return (
@ -21,6 +31,28 @@ function HelpLibrary() {
<li>
<IconFolder size='1rem' className='inline-icon' /> фильтр по расположению
</li>
<h2>Проводник</h2>
<li>клик по папке отображает справа файлы в ней</li>
<li>клик по иконке сворачивает/разворачивает вложенные</li>
<li>
<IconFolderTree size='1rem' className='inline-icon' /> переключение между Проводник и Поиск
</li>
<li>
<IconFolderEmpty size='1rem' className='inline-icon clr-text-default' /> папка без файлов
</li>
<li>
<IconFolderEmpty size='1rem' className='inline-icon' /> папка с вложенными без файлов
</li>
<li>
<IconFolder size='1rem' className='inline-icon' /> папка без вложенных
</li>
<li>
<IconFolderClosed size='1rem' className='inline-icon' /> папка с вложенными и файлами
</li>
<li>
<IconFolderOpened size='1rem' className='inline-icon icon-green' /> развернутая папка
</li>
</div>
);
}

View File

@ -125,7 +125,7 @@ function FormConstituenta({
}
return (
<AnimateFade>
<AnimateFade className='mx-0 md:mx-auto'>
<ControlsOverlay
disabled={disabled}
modified={isModified}

View File

@ -8,6 +8,7 @@ import { GraphLayout } from '@/components/ui/GraphUI';
import { FolderNode } from '@/models/FolderTree';
import { GramData, Grammeme, ReferenceType } from '@/models/language';
import { AccessPolicy, LibraryItemType, LocationHead } from '@/models/library';
import { validateLocation } from '@/models/libraryAPI';
import { CstMatchMode, DependencyMode, GraphColoring, GraphSizing, HelpTopic } from '@/models/miscellaneous';
import { CstClass, CstType, ExpressionStatus, IConstituenta, IRSForm } from '@/models/rsform';
import {
@ -271,10 +272,10 @@ export function describeCstSource(mode: DependencyMode): string {
export function labelLocationHead(head: LocationHead): string {
// prettier-ignore
switch (head) {
case LocationHead.USER: return 'личные (/U)';
case LocationHead.COMMON: return 'общие (/S)';
case LocationHead.LIBRARY: return 'примеры (/L)';
case LocationHead.PROJECTS: return 'проекты (/P)';
case LocationHead.USER: return '/U : личные';
case LocationHead.COMMON: return '/S : общие';
case LocationHead.LIBRARY: return '/L : примеры';
case LocationHead.PROJECTS: return '/P : проекты';
}
}
@ -825,7 +826,11 @@ export function describeAccessMode(mode: UserLevel): string {
* Retrieves label for {@link FolderNode}.
*/
export function labelFolderNode(node: FolderNode): string {
return node.text;
if (node.parent || !validateLocation('/' + node.text)) {
return node.text;
} else {
return labelLocationHead(('/' + node.text) as LocationHead);
}
}
/**