Refactoring: extract incapsulate icon usage. Iconset rework

This commit is contained in:
IRBorisov 2024-04-03 21:05:53 +03:00
parent abd88ccdbf
commit b3a4b8e034
32 changed files with 212 additions and 174 deletions

View File

@ -3,7 +3,7 @@ import { motion } from 'framer-motion';
import { FaSquarePlus } from 'react-icons/fa6'; import { FaSquarePlus } from 'react-icons/fa6';
import { IoLibrary } from 'react-icons/io5'; import { IoLibrary } from 'react-icons/io5';
import { EducationIcon } from '@/components/Icons'; import { IconManuals } from '@/components/Icons';
import { useConceptNavigation } from '@/context/NavigationContext'; import { useConceptNavigation } from '@/context/NavigationContext';
import { useConceptOptions } from '@/context/OptionsContext'; import { useConceptOptions } from '@/context/OptionsContext';
import { animateNavigation } from '@/styling/animations'; import { animateNavigation } from '@/styling/animations';
@ -59,12 +59,7 @@ function Navigation() {
icon={<IoLibrary size='1.5rem' />} icon={<IoLibrary size='1.5rem' />}
onClick={navigateLibrary} onClick={navigateLibrary}
/> />
<NavigationButton <NavigationButton text='Справка' title='Справочные материалы' icon={<IconManuals />} onClick={navigateHelp} />
text='Справка'
title='Справочные материалы'
icon={<EducationIcon />}
onClick={navigateHelp}
/>
<UserMenu /> <UserMenu />
</div> </div>
</motion.div> </motion.div>

View File

@ -1,7 +1,7 @@
import clsx from 'clsx'; import clsx from 'clsx';
import { motion } from 'framer-motion'; import { motion } from 'framer-motion';
import { RiPushpinFill, RiUnpinLine } from 'react-icons/ri';
import { IconPin, IconUnpin } from '@/components/Icons';
import { useConceptOptions } from '@/context/OptionsContext'; import { useConceptOptions } from '@/context/OptionsContext';
import { animateNavigationToggle } from '@/styling/animations'; import { animateNavigationToggle } from '@/styling/animations';
@ -22,8 +22,8 @@ function ToggleNavigationButton() {
animate={noNavigationAnimation ? 'off' : 'on'} animate={noNavigationAnimation ? 'off' : 'on'}
variants={animateNavigationToggle} variants={animateNavigationToggle}
> >
{!noNavigationAnimation ? <RiPushpinFill /> : null} {!noNavigationAnimation ? <IconPin /> : null}
{noNavigationAnimation ? <RiUnpinLine /> : null} {noNavigationAnimation ? <IconUnpin /> : null}
</motion.button> </motion.button>
); );
} }

View File

@ -1,5 +1,6 @@
import { LuLightbulb, LuLightbulbOff, LuLogOut, LuMoon, LuSun, LuUserCircle2 } from 'react-icons/lu'; import { LuLogOut, LuMoon, LuSun } from 'react-icons/lu';
import { IconHelp, IconHelpOff, IconUser } from '@/components/Icons';
import Dropdown from '@/components/ui/Dropdown'; import Dropdown from '@/components/ui/Dropdown';
import DropdownButton from '@/components/ui/DropdownButton'; import DropdownButton from '@/components/ui/DropdownButton';
import { useAuth } from '@/context/AuthContext'; import { useAuth } from '@/context/AuthContext';
@ -38,7 +39,7 @@ function UserDropdown({ isOpen, hideDropdown }: UserDropdownProps) {
<DropdownButton <DropdownButton
text={user?.username} text={user?.username}
title='Профиль пользователя' title='Профиль пользователя'
icon={<LuUserCircle2 size='1rem' />} icon={<IconUser size='1rem' />}
onClick={navigateProfile} onClick={navigateProfile}
/> />
<DropdownButton <DropdownButton
@ -49,7 +50,7 @@ function UserDropdown({ isOpen, hideDropdown }: UserDropdownProps) {
/> />
<DropdownButton <DropdownButton
text={showHelp ? 'Помощь: Вкл' : 'Помощь: Выкл'} text={showHelp ? 'Помощь: Вкл' : 'Помощь: Выкл'}
icon={showHelp ? <LuLightbulb size='1rem' /> : <LuLightbulbOff size='1rem' />} icon={showHelp ? <IconHelp size='1rem' /> : <IconHelpOff size='1rem' />}
title='Отображение иконок подсказок' title='Отображение иконок подсказок'
onClick={toggleShowHelp} onClick={toggleShowHelp}
/> />

View File

@ -1,6 +1,6 @@
import { FaCircleUser } from 'react-icons/fa6'; import { FaCircleUser } from 'react-icons/fa6';
import { InDoorIcon } from '@/components/Icons'; import { IconLogin } from '@/components/Icons';
import { useAuth } from '@/context/AuthContext'; import { useAuth } from '@/context/AuthContext';
import { useConceptNavigation } from '@/context/NavigationContext'; import { useConceptNavigation } from '@/context/NavigationContext';
import useDropdown from '@/hooks/useDropdown'; import useDropdown from '@/hooks/useDropdown';
@ -20,7 +20,7 @@ function UserMenu() {
{!user ? ( {!user ? (
<NavigationButton <NavigationButton
title='Перейти на страницу логина' title='Перейти на страницу логина'
icon={<InDoorIcon size='1.5rem' className='icon-primary' />} icon={<IconLogin size='1.5rem' className='icon-primary' />}
onClick={navigateLogin} onClick={navigateLogin}
/> />
) : null} ) : null}

View File

@ -1,5 +1,50 @@
// Search new icons at https://reactsvgicons.com/ // Search new icons at https://reactsvgicons.com/
export { FiSave as IconSave } from 'react-icons/fi';
export { BiCheck as IconAccept } from 'react-icons/bi';
export { BiX as IconClose } from 'react-icons/bi';
export { BiX as IconRemove } from 'react-icons/bi';
export { BiTrash as IconDestroy } from 'react-icons/bi';
export { BiReset as IconReset } from 'react-icons/bi';
export { BiPlusCircle as IconNewItem } from 'react-icons/bi';
export { BiDuplicate as IconClone } from 'react-icons/bi';
export { LuReplace as IconReplace } from 'react-icons/lu';
export { BiDownload as IconDownload } from 'react-icons/bi';
export { BiUpload as IconUpload } from 'react-icons/bi';
export { LiaEdit as IconEdit } from 'react-icons/lia';
export { RiPushpinFill as IconPin } from 'react-icons/ri';
export { RiUnpinLine as IconUnpin } from 'react-icons/ri';
export { BiCog as IconSettings } from 'react-icons/bi';
export { LuUserCircle2 as IconUser } from 'react-icons/lu';
export { LuCrown as IconOwner } from 'react-icons/lu';
export { BiMeteor as IconAdmin } from 'react-icons/bi';
export { LuGlasses as IconReader } from 'react-icons/lu';
export { FiBell as IconFollow } from 'react-icons/fi';
export { FiBellOff as IconFollowOff } from 'react-icons/fi';
export { BiListUl as IconList } from 'react-icons/bi';
export { BiFontFamily as IconText } from 'react-icons/bi';
export { BiFont as IconTextOff } from 'react-icons/bi';
export { RiTreeLine as IconTree } from 'react-icons/ri';
export { LuMinimize as IconGraphClosure } from 'react-icons/lu';
export { LuMaximize as IconGraphMaximize } from 'react-icons/lu';
export { LuExpand as IconGraphExpand } from 'react-icons/lu';
export { BiGitBranch as IconGraphInputs } from 'react-icons/bi';
export { BiGitMerge as IconGraphOutputs } from 'react-icons/bi';
export { BiCheckShield as IconImmutable } from 'react-icons/bi';
export { RiOpenSourceLine as IconPublic } from 'react-icons/ri';
export { BiShareAlt as IconShare } from 'react-icons/bi';
export { LuLightbulb as IconHelp } from 'react-icons/lu';
export { LuLightbulbOff as IconHelpOff } from 'react-icons/lu';
export { BiFilterAlt as IconFilter } from 'react-icons/bi';
export { BiUpvote as IconMoveUp } from 'react-icons/bi';
export { BiDownvote as IconMoveDown } from 'react-icons/bi';
export { LuRotate3D as IconRotate3D } from 'react-icons/lu';
export { MdOutlineFitScreen as IconFitImage } from 'react-icons/md';
interface IconSVGProps { interface IconSVGProps {
viewBox: string; viewBox: string;
size?: string; size?: string;
@ -28,7 +73,7 @@ function IconSVG({ viewBox, size = '1.5rem', className, props, children }: IconS
); );
} }
export function EducationIcon(props: IconProps) { export function IconManuals(props: IconProps) {
return ( return (
<IconSVG viewBox='0 0 20 20' {...props}> <IconSVG viewBox='0 0 20 20' {...props}>
<path d='M3.33 8L10 12l10-6-10-6L0 6h10v2H3.33zM0 8v8l2-2.22V9.2L0 8zm10 12l-5-3-2-1.2v-6l7 4.2 7-4.2v6L10 20z' /> <path d='M3.33 8L10 12l10-6-10-6L0 6h10v2H3.33zM0 8v8l2-2.22V9.2L0 8zm10 12l-5-3-2-1.2v-6l7 4.2 7-4.2v6L10 20z' />
@ -36,7 +81,7 @@ export function EducationIcon(props: IconProps) {
); );
} }
export function InDoorIcon(props: IconProps) { export function IconLogin(props: IconProps) {
return ( return (
<IconSVG viewBox='0 0 24 24' {...props}> <IconSVG viewBox='0 0 24 24' {...props}>
<path fill='none' d='M0 0h24v24H0z' /> <path fill='none' d='M0 0h24v24H0z' />
@ -45,7 +90,7 @@ export function InDoorIcon(props: IconProps) {
); );
} }
export function CheckboxCheckedIcon() { export function CheckboxChecked() {
return ( return (
<svg className='w-3 h-3' viewBox='0 0 512 512' fill='#ffffff'> <svg className='w-3 h-3' viewBox='0 0 512 512' fill='#ffffff'>
<path d='M470.6 105.4c12.5 12.5 12.5 32.8 0 45.3l-256 256c-12.5 12.5-32.8 12.5-45.3 0l-128-128c-12.5-12.5-12.5-32.8 0-45.3s32.8-12.5 45.3 0L192 338.7l233.4-233.3c12.5-12.5 32.8-12.5 45.3 0z' /> <path d='M470.6 105.4c12.5 12.5 12.5 32.8 0 45.3l-256 256c-12.5 12.5-32.8 12.5-45.3 0l-128-128c-12.5-12.5-12.5-32.8 0-45.3s32.8-12.5 45.3 0L192 338.7l233.4-233.3c12.5-12.5 32.8-12.5 45.3 0z' />
@ -53,7 +98,7 @@ export function CheckboxCheckedIcon() {
); );
} }
export function CheckboxNullIcon() { export function CheckboxNull() {
return ( return (
<svg className='w-3 h-3' viewBox='0 0 16 16' fill='#ffffff'> <svg className='w-3 h-3' viewBox='0 0 16 16' fill='#ffffff'>
<path d='M2 7.75A.75.75 0 012.75 7h10a.75.75 0 010 1.5h-10A.75.75 0 012 7.75z' /> <path d='M2 7.75A.75.75 0 012.75 7h10a.75.75 0 010 1.5h-10A.75.75 0 012 7.75z' />

View File

@ -1,10 +1,9 @@
import { LuLightbulb } from 'react-icons/lu';
import TextURL from '@/components/ui/TextURL'; import TextURL from '@/components/ui/TextURL';
import Tooltip, { PlacesType } from '@/components/ui/Tooltip'; import Tooltip, { PlacesType } from '@/components/ui/Tooltip';
import { useConceptOptions } from '@/context/OptionsContext'; import { useConceptOptions } from '@/context/OptionsContext';
import { HelpTopic } from '@/models/miscellaneous'; import { HelpTopic } from '@/models/miscellaneous';
import { IconHelp } from '../Icons';
import InfoTopic from '../info/InfoTopic'; import InfoTopic from '../info/InfoTopic';
import { CProps } from '../props'; import { CProps } from '../props';
@ -22,7 +21,7 @@ function BadgeHelp({ topic, ...restProps }: BadgeHelpProps) {
} }
return ( return (
<div id={`help-${topic}`} className='p-1'> <div id={`help-${topic}`} className='p-1'>
<LuLightbulb size='1.25rem' className='icon-primary' /> <IconHelp size='1.25rem' className='icon-primary' />
<Tooltip clickable anchorSelect={`#help-${topic}`} layer='z-modal-tooltip' {...restProps}> <Tooltip clickable anchorSelect={`#help-${topic}`} layer='z-modal-tooltip' {...restProps}>
<div className='relative' onClick={event => event.stopPropagation()}> <div className='relative' onClick={event => event.stopPropagation()}>
<div className='absolute right-0 text-sm top-[0.4rem] clr-input'> <div className='absolute right-0 text-sm top-[0.4rem] clr-input'>

View File

@ -1,5 +1,4 @@
import { BiCheckShield, BiShareAlt } from 'react-icons/bi'; import { IconFollow, IconImmutable, IconPublic } from '../Icons';
import { FiBell } from 'react-icons/fi';
function HelpLibrary() { function HelpLibrary() {
// prettier-ignore // prettier-ignore
@ -11,15 +10,15 @@ function HelpLibrary() {
<p>Сортировка по клику на заголовок таблицы</p> <p>Сортировка по клику на заголовок таблицы</p>
<h2>Отображение статусов</h2> <h2>Отображение статусов</h2>
<div className='flex items-center gap-2'> <div className='flex items-center gap-2'>
<FiBell size='1rem'/> <IconFollow size='1rem'/>
<p><b>отслеживаемая</b> обозначает отслеживание схемы</p> <p><b>отслеживаемая</b> обозначает отслеживание схемы</p>
</div> </div>
<div className='flex items-center gap-2'> <div className='flex items-center gap-2'>
<BiShareAlt size='1rem'/> <IconPublic size='1rem'/>
<p><b>общедоступная</b> отображает схему всем пользователям</p> <p><b>общедоступная</b> отображает схему всем пользователям</p>
</div> </div>
<div className='flex items-center gap-2'> <div className='flex items-center gap-2'>
<BiCheckShield size='1rem'/> <IconImmutable size='1rem'/>
<p><b>неизменная</b> выделяет стандартные схемы</p> <p><b>неизменная</b> выделяет стандартные схемы</p>
</div> </div>
</div>); </div>);

View File

@ -1,8 +1,8 @@
'use client'; 'use client';
import { useCallback, useMemo, useState } from 'react'; import { useCallback, useMemo, useState } from 'react';
import { BiChevronLeft, BiChevronRight, BiFirstPage, BiLastPage, BiX } from 'react-icons/bi'; import { BiChevronLeft, BiChevronRight, BiFirstPage, BiLastPage } from 'react-icons/bi';
import { LuFlag, LuFlagOff, LuPower, LuPowerOff, LuReplace } from 'react-icons/lu'; import { LuFlag, LuFlagOff, LuPower, LuPowerOff } from 'react-icons/lu';
import ConstituentaBadge from '@/components/info/ConstituentaBadge'; import ConstituentaBadge from '@/components/info/ConstituentaBadge';
import ConstituentaSelector from '@/components/select/ConstituentaSelector'; import ConstituentaSelector from '@/components/select/ConstituentaSelector';
@ -13,6 +13,8 @@ import { useConceptOptions } from '@/context/OptionsContext';
import { IConstituenta, IRSForm, ISubstitution } from '@/models/rsform'; import { IConstituenta, IRSForm, ISubstitution } from '@/models/rsform';
import { describeConstituenta } from '@/utils/labels'; import { describeConstituenta } from '@/utils/labels';
import { IconRemove, IconReplace } from '../Icons';
interface SubstitutionsPickerProps { interface SubstitutionsPickerProps {
prefixID: string; prefixID: string;
rows?: number; rows?: number;
@ -141,7 +143,7 @@ function SubstitutionsPicker({
<MiniButton <MiniButton
noHover noHover
title='Удалить' title='Удалить'
icon={<BiX size='1rem' className='icon-red' />} icon={<IconRemove size='1rem' className='icon-red' />}
onClick={() => handleDeleteRow(props.row.index)} onClick={() => handleDeleteRow(props.row.index)}
/> />
) )
@ -194,7 +196,7 @@ function SubstitutionsPicker({
noHover noHover
title='Добавить в таблицу отождествлений' title='Добавить в таблицу отождествлений'
className='mb-[0.375rem] grow-0' className='mb-[0.375rem] grow-0'
icon={<LuReplace size='1.5rem' className='icon-primary' />} icon={<IconReplace size='1.5rem' className='icon-primary' />}
disabled={!leftCst || !rightCst || leftCst === rightCst} disabled={!leftCst || !rightCst || leftCst === rightCst}
onClick={addSubstitution} onClick={addSubstitution}
/> />

View File

@ -3,7 +3,7 @@ import { useMemo } from 'react';
import { globals } from '@/utils/constants'; import { globals } from '@/utils/constants';
import { CheckboxCheckedIcon } from '../Icons'; import { CheckboxChecked } from '../Icons';
import { CProps } from '../props'; import { CProps } from '../props';
export interface CheckboxProps extends Omit<CProps.Button, 'value' | 'onClick'> { export interface CheckboxProps extends Omit<CProps.Button, 'value' | 'onClick'> {
@ -72,7 +72,7 @@ function Checkbox({
> >
{value ? ( {value ? (
<div className='mt-[1px] ml-[1px]'> <div className='mt-[1px] ml-[1px]'>
<CheckboxCheckedIcon /> <CheckboxChecked />
</div> </div>
) : null} ) : null}
</div> </div>

View File

@ -3,7 +3,7 @@ import { useMemo } from 'react';
import { globals } from '@/utils/constants'; import { globals } from '@/utils/constants';
import { CheckboxCheckedIcon, CheckboxNullIcon } from '../Icons'; import { CheckboxChecked, CheckboxNull } from '../Icons';
import { CheckboxProps } from './Checkbox'; import { CheckboxProps } from './Checkbox';
export interface CheckboxTristateProps extends Omit<CheckboxProps, 'value' | 'setValue'> { export interface CheckboxTristateProps extends Omit<CheckboxProps, 'value' | 'setValue'> {
@ -75,12 +75,12 @@ function CheckboxTristate({
> >
{value ? ( {value ? (
<div className='mt-[1px] ml-[1px]'> <div className='mt-[1px] ml-[1px]'>
<CheckboxCheckedIcon /> <CheckboxChecked />
</div> </div>
) : null} ) : null}
{value == null ? ( {value == null ? (
<div className='mt-[1px] ml-[1px]'> <div className='mt-[1px] ml-[1px]'>
<CheckboxNullIcon /> <CheckboxNull />
</div> </div>
) : null} ) : null}
</div> </div>

View File

@ -2,8 +2,8 @@
import clsx from 'clsx'; import clsx from 'clsx';
import { useRef, useState } from 'react'; import { useRef, useState } from 'react';
import { BiUpload } from 'react-icons/bi';
import { IconUpload } from '../Icons';
import { CProps } from '../props'; import { CProps } from '../props';
import Button from './Button'; import Button from './Button';
import Label from './Label'; import Label from './Label';
@ -45,7 +45,7 @@ function FileInput({ id, label, acceptType, title, className, style, onChange, .
onChange={handleFileChange} onChange={handleFileChange}
{...restProps} {...restProps}
/> />
<Button text={label} icon={<BiUpload size='1.25rem' />} onClick={handleUploadClick} title={title} /> <Button text={label} icon={<IconUpload size='1.25rem' />} onClick={handleUploadClick} title={title} />
<Label text={fileName} htmlFor={id} /> <Label text={fileName} htmlFor={id} />
</div> </div>
); );

View File

@ -3,12 +3,12 @@
import clsx from 'clsx'; import clsx from 'clsx';
import { motion } from 'framer-motion'; import { motion } from 'framer-motion';
import { useRef } from 'react'; import { useRef } from 'react';
import { BiX } from 'react-icons/bi';
import useEscapeKey from '@/hooks/useEscapeKey'; import useEscapeKey from '@/hooks/useEscapeKey';
import { animateModal } from '@/styling/animations'; import { animateModal } from '@/styling/animations';
import { prepareTooltip } from '@/utils/labels'; import { prepareTooltip } from '@/utils/labels';
import { IconClose } from '../Icons';
import { CProps } from '../props'; import { CProps } from '../props';
import Button from './Button'; import Button from './Button';
import MiniButton from './MiniButton'; import MiniButton from './MiniButton';
@ -75,7 +75,7 @@ function Modal({
<MiniButton <MiniButton
noPadding noPadding
titleHtml={prepareTooltip('Закрыть диалоговое окно', 'ESC')} titleHtml={prepareTooltip('Закрыть диалоговое окно', 'ESC')}
icon={<BiX size='1.25rem' />} icon={<IconClose size='1.25rem' />}
onClick={handleCancel} onClick={handleCancel}
/> />
</Overlay> </Overlay>

View File

@ -3,8 +3,8 @@
import { createColumnHelper } from '@tanstack/react-table'; import { createColumnHelper } from '@tanstack/react-table';
import clsx from 'clsx'; import clsx from 'clsx';
import { useCallback, useEffect, useMemo, useState } from 'react'; import { useCallback, useEffect, useMemo, useState } from 'react';
import { BiCheck, BiRefresh, BiX } from 'react-icons/bi';
import { IconAccept, IconRemove, IconReset } from '@/components/Icons';
import RSInput from '@/components/RSInput'; import RSInput from '@/components/RSInput';
import ConstituentaPicker from '@/components/select/ConstituentaPicker'; import ConstituentaPicker from '@/components/select/ConstituentaPicker';
import DataTable, { IConditionalStyle } from '@/components/ui/DataTable'; import DataTable, { IConditionalStyle } from '@/components/ui/DataTable';
@ -122,7 +122,7 @@ function ArgumentsTab({ state, schema, partialUpdate }: ArgumentsTabProps) {
title='Очистить значение' title='Очистить значение'
noPadding noPadding
noHover noHover
icon={<BiX size='1.25rem' className='icon-red' />} icon={<IconRemove size='1.25rem' className='icon-red' />}
onClick={() => handleClearArgument(props.row.original)} onClick={() => handleClearArgument(props.row.original)}
/> />
) : null} ) : null}
@ -188,7 +188,7 @@ function ArgumentsTab({ state, schema, partialUpdate }: ArgumentsTabProps) {
title='Подставить значение аргумента' title='Подставить значение аргумента'
noHover noHover
className='py-0' className='py-0'
icon={<BiCheck size='2rem' className='icon-green' />} icon={<IconAccept size='2rem' className='icon-green' />}
disabled={!argumentValue || !selectedArgument} disabled={!argumentValue || !selectedArgument}
onClick={() => handleAssignArgument(selectedArgument!, argumentValue)} onClick={() => handleAssignArgument(selectedArgument!, argumentValue)}
/> />
@ -198,7 +198,7 @@ function ArgumentsTab({ state, schema, partialUpdate }: ArgumentsTabProps) {
className='py-0' className='py-0'
disabled={!isModified} disabled={!isModified}
onClick={handleReset} onClick={handleReset}
icon={<BiRefresh size='2rem' className='icon-primary' />} icon={<IconReset size='2rem' className='icon-primary' />}
/> />
</div> </div>
</div> </div>

View File

@ -1,9 +1,8 @@
'use client'; 'use client';
import { useLayoutEffect, useMemo, useState } from 'react'; import { useLayoutEffect, useMemo, useState } from 'react';
import { BiReset } from 'react-icons/bi';
import { FiSave } from 'react-icons/fi';
import { IconReset, IconSave } from '@/components/Icons';
import MiniButton from '@/components/ui/MiniButton'; import MiniButton from '@/components/ui/MiniButton';
import Modal from '@/components/ui/Modal'; import Modal from '@/components/ui/Modal';
import TextArea from '@/components/ui/TextArea'; import TextArea from '@/components/ui/TextArea';
@ -92,14 +91,14 @@ function DlgEditVersions({ hideWindow, versions, onDelete, onUpdate }: DlgEditVe
<MiniButton <MiniButton
title='Сохранить изменения' title='Сохранить изменения'
disabled={!isModified || !isValid || processing} disabled={!isModified || !isValid || processing}
icon={<FiSave size='1.25rem' className='icon-primary' />} icon={<IconSave size='1.25rem' className='icon-primary' />}
onClick={handleUpdate} onClick={handleUpdate}
/> />
<MiniButton <MiniButton
title='Сбросить несохраненные изменения' title='Сбросить несохраненные изменения'
disabled={!isModified} disabled={!isModified}
onClick={handleReset} onClick={handleReset}
icon={<BiReset size='1.25rem' className='icon-primary' />} icon={<IconReset size='1.25rem' className='icon-primary' />}
/> />
</div> </div>
</div> </div>

View File

@ -2,9 +2,9 @@
import clsx from 'clsx'; import clsx from 'clsx';
import { useMemo } from 'react'; import { useMemo } from 'react';
import { BiX } from 'react-icons/bi';
import { useIntl } from 'react-intl'; import { useIntl } from 'react-intl';
import { IconRemove } from '@/components/Icons';
import DataTable, { createColumnHelper, IConditionalStyle } from '@/components/ui/DataTable'; import DataTable, { createColumnHelper, IConditionalStyle } from '@/components/ui/DataTable';
import MiniButton from '@/components/ui/MiniButton'; import MiniButton from '@/components/ui/MiniButton';
import { useConceptOptions } from '@/context/OptionsContext'; import { useConceptOptions } from '@/context/OptionsContext';
@ -66,7 +66,7 @@ function VersionsTable({ processing, items, onDelete, selected, onSelect }: Vers
noHover noHover
noPadding noPadding
disabled={processing} disabled={processing}
icon={<BiX size='1.25rem' className='icon-red' />} icon={<IconRemove size='1.25rem' className='icon-red' />}
onClick={() => onDelete(props.row.original.id)} onClick={() => onDelete(props.row.original.id)}
/> />
</div> </div>

View File

@ -2,8 +2,9 @@
import clsx from 'clsx'; import clsx from 'clsx';
import { useLayoutEffect, useState } from 'react'; import { useLayoutEffect, useState } from 'react';
import { BiCheck, BiChevronsDown, BiLeftArrow, BiRightArrow, BiX } from 'react-icons/bi'; import { BiChevronsDown, BiLeftArrow, BiRightArrow } from 'react-icons/bi';
import { IconAccept, IconRemove } from '@/components/Icons';
import BadgeHelp from '@/components/man/BadgeHelp'; import BadgeHelp from '@/components/man/BadgeHelp';
import SelectGrammeme from '@/components/select/SelectGrammeme'; import SelectGrammeme from '@/components/select/SelectGrammeme';
import Label from '@/components/ui/Label'; import Label from '@/components/ui/Label';
@ -182,7 +183,7 @@ function DlgEditWordForms({ hideWindow, target, onSave }: DlgEditWordFormsProps)
<MiniButton <MiniButton
noHover noHover
title='Внести словоформу' title='Внести словоформу'
icon={<BiCheck size='1.5rem' className='icon-green' />} icon={<IconAccept size='1.5rem' className='icon-green' />}
disabled={textProcessor.loading || !inputText || inputGrams.length == 0} disabled={textProcessor.loading || !inputText || inputGrams.length == 0}
onClick={handleAddForm} onClick={handleAddForm}
/> />
@ -201,7 +202,7 @@ function DlgEditWordForms({ hideWindow, target, onSave }: DlgEditWordFormsProps)
noHover noHover
title='Сбросить все словоформы' title='Сбросить все словоформы'
className='py-0' className='py-0'
icon={<BiX size='1.5rem' className='icon-red' />} icon={<IconRemove size='1.5rem' className='icon-red' />}
disabled={textProcessor.loading || forms.length === 0} disabled={textProcessor.loading || forms.length === 0}
onClick={handleResetAll} onClick={handleResetAll}
/> />

View File

@ -2,8 +2,8 @@
import clsx from 'clsx'; import clsx from 'clsx';
import { useCallback, useMemo } from 'react'; import { useCallback, useMemo } from 'react';
import { BiX } from 'react-icons/bi';
import { IconRemove } from '@/components/Icons';
import WordFormBadge from '@/components/info/WordFormBadge'; import WordFormBadge from '@/components/info/WordFormBadge';
import DataTable, { createColumnHelper } from '@/components/ui/DataTable'; import DataTable, { createColumnHelper } from '@/components/ui/DataTable';
import MiniButton from '@/components/ui/MiniButton'; import MiniButton from '@/components/ui/MiniButton';
@ -60,7 +60,7 @@ function WordFormsTable({ forms, setForms, onFormSelect }: WordFormsTableProps)
noHover noHover
noPadding noPadding
title='Удалить словоформу' title='Удалить словоформу'
icon={<BiX size='1.25rem' className='icon-red' />} icon={<IconRemove size='1.25rem' className='icon-red' />}
onClick={() => handleDeleteRow(props.row.index)} onClick={() => handleDeleteRow(props.row.index)}
/> />
</div> </div>

View File

@ -2,10 +2,10 @@
import clsx from 'clsx'; import clsx from 'clsx';
import { useEffect, useRef, useState } from 'react'; import { useEffect, useRef, useState } from 'react';
import { BiDownload } from 'react-icons/bi';
import { toast } from 'react-toastify'; import { toast } from 'react-toastify';
import { urls } from '@/app/urls'; import { urls } from '@/app/urls';
import { IconDownload } from '@/components/Icons';
import InfoError from '@/components/info/InfoError'; import InfoError from '@/components/info/InfoError';
import Button from '@/components/ui/Button'; import Button from '@/components/ui/Button';
import Checkbox from '@/components/ui/Checkbox'; import Checkbox from '@/components/ui/Checkbox';
@ -95,7 +95,7 @@ function CreateRSFormPage() {
/> />
<MiniButton <MiniButton
title='Загрузить из Экстеор' title='Загрузить из Экстеор'
icon={<BiDownload size='1.25rem' className='icon-primary' />} icon={<IconDownload size='1.25rem' className='icon-primary' />}
onClick={() => inputRef.current?.click()} onClick={() => inputRef.current?.click()}
/> />
</Overlay> </Overlay>

View File

@ -1,7 +1,6 @@
import clsx from 'clsx'; import clsx from 'clsx';
import { BiCheckShield, BiShareAlt } from 'react-icons/bi';
import { FiBell } from 'react-icons/fi';
import { IconFollow, IconImmutable, IconPublic } from '@/components/Icons';
import { ICurrentUser, ILibraryItem } from '@/models/library'; import { ICurrentUser, ILibraryItem } from '@/models/library';
import { prefixes } from '@/utils/constants'; import { prefixes } from '@/utils/constants';
@ -15,17 +14,17 @@ function ItemIcons({ user, item }: ItemIconsProps) {
<div className={clsx('min-w-[3.3rem]', 'inline-flex gap-1 align-middle')} id={`${prefixes.library_list}${item.id}`}> <div className={clsx('min-w-[3.3rem]', 'inline-flex gap-1 align-middle')} id={`${prefixes.library_list}${item.id}`}>
{user && user.subscriptions.includes(item.id) ? ( {user && user.subscriptions.includes(item.id) ? (
<span title='Отслеживаемая'> <span title='Отслеживаемая'>
<FiBell size='1rem' /> <IconFollow size='1rem' />
</span> </span>
) : null} ) : null}
{item.is_common ? ( {item.is_common ? (
<span title='Общедоступная'> <span title='Общедоступная'>
<BiShareAlt size='1em' /> <IconPublic size='1rem' />
</span> </span>
) : null} ) : null}
{item.is_canonical ? ( {item.is_canonical ? (
<span title='Неизменная'> <span title='Неизменная'>
<BiCheckShield size='1rem' /> <IconImmutable size='1rem' />
</span> </span>
) : null} ) : null}
</div> </div>

View File

@ -1,8 +1,8 @@
'use client'; 'use client';
import { useCallback } from 'react'; import { useCallback } from 'react';
import { BiFilterAlt } from 'react-icons/bi';
import { IconFilter } from '@/components/Icons';
import Dropdown from '@/components/ui/Dropdown'; import Dropdown from '@/components/ui/Dropdown';
import DropdownCheckbox from '@/components/ui/DropdownCheckbox'; import DropdownCheckbox from '@/components/ui/DropdownCheckbox';
import SelectorButton from '@/components/ui/SelectorButton'; import SelectorButton from '@/components/ui/SelectorButton';
@ -49,7 +49,7 @@ function PickerStrategy({ value, onChange }: PickerStrategyProps) {
title='Список фильтров' title='Список фильтров'
hideTitle={strategyMenu.isOpen} hideTitle={strategyMenu.isOpen}
className='h-full' className='h-full'
icon={<BiFilterAlt size='1.25rem' />} icon={<IconFilter size='1.25rem' />}
text={labelLibraryFilter(value)} text={labelLibraryFilter(value)}
onClick={strategyMenu.toggle} onClick={strategyMenu.toggle}
/> />

View File

@ -1,6 +1,4 @@
import { BiDownvote, BiDuplicate, BiPlusCircle, BiReset, BiTrash, BiUpvote } from 'react-icons/bi'; import { IconClone, IconDestroy, IconMoveDown, IconMoveUp, IconNewItem, IconReset, IconSave } from '@/components/Icons';
import { FiSave } from 'react-icons/fi';
import MiniButton from '@/components/ui/MiniButton'; import MiniButton from '@/components/ui/MiniButton';
import Overlay from '@/components/ui/Overlay'; import Overlay from '@/components/ui/Overlay';
import { messages, prepareTooltip } from '@/utils/labels'; import { messages, prepareTooltip } from '@/utils/labels';
@ -34,25 +32,25 @@ function ConstituentaToolbar({
<Overlay position='top-1 right-4 sm:right-1/2 sm:translate-x-1/2' className='cc-icons'> <Overlay position='top-1 right-4 sm:right-1/2 sm:translate-x-1/2' className='cc-icons'>
<MiniButton <MiniButton
titleHtml={prepareTooltip('Сохранить изменения', 'Ctrl + S')} titleHtml={prepareTooltip('Сохранить изменения', 'Ctrl + S')}
icon={<FiSave size='1.25rem' className='icon-primary' />} icon={<IconSave size='1.25rem' className='icon-primary' />}
disabled={disabled || !modified} disabled={disabled || !modified}
onClick={onSubmit} onClick={onSubmit}
/> />
<MiniButton <MiniButton
title='Сбросить несохраненные изменения' title='Сбросить несохраненные изменения'
icon={<BiReset size='1.25rem' className='icon-primary' />} icon={<IconReset size='1.25rem' className='icon-primary' />}
disabled={disabled || !modified} disabled={disabled || !modified}
onClick={onReset} onClick={onReset}
/> />
<MiniButton <MiniButton
title='Создать конституенту после данной' title='Создать конституенту после данной'
icon={<BiPlusCircle size={'1.25rem'} className='icon-green' />} icon={<IconNewItem size={'1.25rem'} className='icon-green' />}
disabled={disabled} disabled={disabled}
onClick={onCreate} onClick={onCreate}
/> />
<MiniButton <MiniButton
titleHtml={modified ? messages.unsaved : prepareTooltip('Клонировать конституенту', 'Alt + V')} titleHtml={modified ? messages.unsaved : prepareTooltip('Клонировать конституенту', 'Alt + V')}
icon={<BiDuplicate size='1.25rem' className='icon-green' />} icon={<IconClone size='1.25rem' className='icon-green' />}
disabled={disabled || modified} disabled={disabled || modified}
onClick={onClone} onClick={onClone}
/> />
@ -60,17 +58,17 @@ function ConstituentaToolbar({
title='Удалить редактируемую конституенту' title='Удалить редактируемую конституенту'
disabled={disabled} disabled={disabled}
onClick={onDelete} onClick={onDelete}
icon={<BiTrash size='1.25rem' className='icon-red' />} icon={<IconDestroy size='1.25rem' className='icon-red' />}
/> />
<MiniButton <MiniButton
titleHtml={prepareTooltip('Переместить вверх', 'Alt + вверх')} titleHtml={prepareTooltip('Переместить вверх', 'Alt + вверх')}
icon={<BiUpvote size='1.25rem' className='icon-primary' />} icon={<IconMoveUp size='1.25rem' className='icon-primary' />}
disabled={disabled || modified} disabled={disabled || modified}
onClick={onMoveUp} onClick={onMoveUp}
/> />
<MiniButton <MiniButton
titleHtml={prepareTooltip('Переместить вниз', 'Alt + вниз')} titleHtml={prepareTooltip('Переместить вниз', 'Alt + вниз')}
icon={<BiDownvote size='1.25rem' className='icon-primary' />} icon={<IconMoveDown size='1.25rem' className='icon-primary' />}
disabled={disabled || modified} disabled={disabled || modified}
onClick={onMoveDown} onClick={onMoveDown}
/> />

View File

@ -1,6 +1,6 @@
import clsx from 'clsx'; import clsx from 'clsx';
import { LiaEdit } from 'react-icons/lia';
import { IconEdit } from '@/components/Icons';
import MiniButton from '@/components/ui/MiniButton'; import MiniButton from '@/components/ui/MiniButton';
import Overlay from '@/components/ui/Overlay'; import Overlay from '@/components/ui/Overlay';
import { IConstituenta } from '@/models/rsform'; import { IConstituenta } from '@/models/rsform';
@ -26,7 +26,7 @@ function ControlsOverlay({ constituenta, disabled, modified, processing, onRenam
} }
noHover noHover
onClick={onEditTerm} onClick={onEditTerm}
icon={<LiaEdit size='1rem' className='icon-primary' />} icon={<IconEdit size='1rem' className='icon-primary' />}
disabled={modified} disabled={modified}
/> />
) : null} ) : null}
@ -46,7 +46,7 @@ function ControlsOverlay({ constituenta, disabled, modified, processing, onRenam
noHover noHover
title={modified ? messages.unsaved : 'Переименовать конституенту'} title={modified ? messages.unsaved : 'Переименовать конституенту'}
onClick={onRename} onClick={onRename}
icon={<LiaEdit size='1rem' className='icon-primary' />} icon={<IconEdit size='1rem' className='icon-primary' />}
disabled={modified} disabled={modified}
/> />
) : null} ) : null}

View File

@ -3,9 +3,9 @@
import clsx from 'clsx'; import clsx from 'clsx';
import { AnimatePresence } from 'framer-motion'; import { AnimatePresence } from 'framer-motion';
import { useEffect, useLayoutEffect, useMemo, useState } from 'react'; import { useEffect, useLayoutEffect, useMemo, useState } from 'react';
import { FiSave } from 'react-icons/fi';
import { toast } from 'react-toastify'; import { toast } from 'react-toastify';
import { IconSave } from '@/components/Icons';
import RefsInput from '@/components/RefsInput'; import RefsInput from '@/components/RefsInput';
import SubmitButton from '@/components/ui/SubmitButton'; import SubmitButton from '@/components/ui/SubmitButton';
import TextArea from '@/components/ui/TextArea'; import TextArea from '@/components/ui/TextArea';
@ -237,7 +237,7 @@ function FormConstituenta({
text='Сохранить изменения' text='Сохранить изменения'
className='self-center' className='self-center'
disabled={disabled || !isModified} disabled={disabled || !isModified}
icon={<FiSave size='1.25rem' />} icon={<IconSave size='1.25rem' />}
/> />
) : null} ) : null}
</AnimatePresence> </AnimatePresence>

View File

@ -3,11 +3,10 @@
import { ReactCodeMirrorRef } from '@uiw/react-codemirror'; import { ReactCodeMirrorRef } from '@uiw/react-codemirror';
import { AnimatePresence } from 'framer-motion'; import { AnimatePresence } from 'framer-motion';
import { useCallback, useLayoutEffect, useRef, useState } from 'react'; import { useCallback, useLayoutEffect, useRef, useState } from 'react';
import { BiFontFamily, BiListUl } from 'react-icons/bi';
import { FaRegKeyboard } from 'react-icons/fa6'; import { FaRegKeyboard } from 'react-icons/fa6';
import { RiNodeTree } from 'react-icons/ri';
import { toast } from 'react-toastify'; import { toast } from 'react-toastify';
import { IconList, IconText, IconTree } from '@/components/Icons';
import BadgeHelp from '@/components/man/BadgeHelp'; import BadgeHelp from '@/components/man/BadgeHelp';
import RSInput from '@/components/RSInput'; import RSInput from '@/components/RSInput';
import { RSTextWrapper } from '@/components/RSInput/textEditing'; import { RSTextWrapper } from '@/components/RSInput/textEditing';
@ -165,7 +164,7 @@ function EditorRSExpression({
<MiniButton <MiniButton
title='Изменить шрифт' title='Изменить шрифт'
onClick={toggleFont} onClick={toggleFont}
icon={<BiFontFamily size='1.25rem' className={mathFont === 'math' ? 'icon-primary' : ''} />} icon={<IconText size='1.25rem' className={mathFont === 'math' ? 'icon-primary' : ''} />}
/> />
{!disabled || model.processing ? ( {!disabled || model.processing ? (
<MiniButton <MiniButton
@ -177,12 +176,12 @@ function EditorRSExpression({
<MiniButton <MiniButton
title='Отображение списка конституент' title='Отображение списка конституент'
onClick={onToggleList} onClick={onToggleList}
icon={<BiListUl size='1.25rem' className={showList ? 'icon-primary' : ''} />} icon={<IconList size='1.25rem' className={showList ? 'icon-primary' : ''} />}
/> />
<MiniButton <MiniButton
title='Дерево разбора выражения' title='Дерево разбора выражения'
onClick={handleShowAST} onClick={handleShowAST}
icon={<RiNodeTree size='1.25rem' className='icon-primary' />} icon={<IconTree size='1.25rem' className='icon-primary' />}
/> />
</Overlay> </Overlay>

View File

@ -2,10 +2,9 @@
import clsx from 'clsx'; import clsx from 'clsx';
import { useEffect, useLayoutEffect, useState } from 'react'; import { useEffect, useLayoutEffect, useState } from 'react';
import { FiSave } from 'react-icons/fi';
import { LuGitBranchPlus, LuPencilLine } from 'react-icons/lu';
import { toast } from 'react-toastify'; import { toast } from 'react-toastify';
import { IconList, IconNewItem, IconSave } from '@/components/Icons';
import BadgeHelp from '@/components/man/BadgeHelp'; import BadgeHelp from '@/components/man/BadgeHelp';
import VersionSelector from '@/components/select/VersionSelector'; import VersionSelector from '@/components/select/VersionSelector';
import Checkbox from '@/components/ui/Checkbox'; import Checkbox from '@/components/ui/Checkbox';
@ -124,13 +123,13 @@ function FormRSForm({ id, isModified, setIsModified }: FormRSFormProps) {
title={controller.isContentEditable ? 'Создать версию' : 'Переключитесь на актуальную версию'} title={controller.isContentEditable ? 'Создать версию' : 'Переключитесь на актуальную версию'}
disabled={!controller.isContentEditable} disabled={!controller.isContentEditable}
onClick={controller.createVersion} onClick={controller.createVersion}
icon={<LuGitBranchPlus size='1.25rem' className='icon-green' />} icon={<IconNewItem size='1.25rem' className='icon-green' />}
/> />
<MiniButton <MiniButton
title={schema?.versions.length === 0 ? 'Список версий пуст' : 'Редактировать версии'} title={schema?.versions.length === 0 ? 'Список версий пуст' : 'Редактировать версии'}
disabled={!schema || schema?.versions.length === 0} disabled={!schema || schema?.versions.length === 0}
onClick={controller.editVersions} onClick={controller.editVersions}
icon={<LuPencilLine size='1.25rem' className='icon-primary' />} icon={<IconList size='1.25rem' className='icon-primary' />}
/> />
</> </>
) : null} ) : null}
@ -177,7 +176,7 @@ function FormRSForm({ id, isModified, setIsModified }: FormRSFormProps) {
className='self-center' className='self-center'
loading={processing} loading={processing}
disabled={!isModified} disabled={!isModified}
icon={<FiSave size='1.25rem' />} icon={<IconSave size='1.25rem' />}
/> />
) : null} ) : null}
</form> </form>

View File

@ -1,10 +1,16 @@
'use client'; 'use client';
import { useMemo } from 'react'; import { useMemo } from 'react';
import { BiDownload, BiShareAlt, BiTrash } from 'react-icons/bi';
import { FiBell, FiBellOff, FiSave } from 'react-icons/fi';
import { LuCrown } from 'react-icons/lu';
import {
IconDestroy,
IconDownload,
IconFollow,
IconFollowOff,
IconOwner,
IconSave,
IconShare
} from '@/components/Icons';
import BadgeHelp from '@/components/man/BadgeHelp'; import BadgeHelp from '@/components/man/BadgeHelp';
import MiniButton from '@/components/ui/MiniButton'; import MiniButton from '@/components/ui/MiniButton';
import Overlay from '@/components/ui/Overlay'; import Overlay from '@/components/ui/Overlay';
@ -31,18 +37,18 @@ function RSFormToolbar({ modified, anonymous, subscribed, claimable, onSubmit, o
<MiniButton <MiniButton
titleHtml={prepareTooltip('Сохранить изменения', 'Ctrl + S')} titleHtml={prepareTooltip('Сохранить изменения', 'Ctrl + S')}
disabled={!canSave} disabled={!canSave}
icon={<FiSave size='1.25rem' className='icon-primary' />} icon={<IconSave size='1.25rem' className='icon-primary' />}
onClick={onSubmit} onClick={onSubmit}
/> />
) : null} ) : null}
<MiniButton <MiniButton
title='Поделиться схемой' title='Поделиться схемой'
icon={<BiShareAlt size='1.25rem' className='icon-primary' />} icon={<IconShare size='1.25rem' className='icon-primary' />}
onClick={controller.share} onClick={controller.share}
/> />
<MiniButton <MiniButton
title='Скачать TRS файл' title='Скачать TRS файл'
icon={<BiDownload size='1.25rem' className='icon-primary' />} icon={<IconDownload size='1.25rem' className='icon-primary' />}
onClick={controller.download} onClick={controller.download}
/> />
{!anonymous ? ( {!anonymous ? (
@ -50,9 +56,9 @@ function RSFormToolbar({ modified, anonymous, subscribed, claimable, onSubmit, o
titleHtml={`Отслеживание <b>${subscribed ? 'включено' : 'выключено'}</b>`} titleHtml={`Отслеживание <b>${subscribed ? 'включено' : 'выключено'}</b>`}
icon={ icon={
subscribed ? ( subscribed ? (
<FiBell size='1.25rem' className='icon-primary' /> <IconFollow size='1.25rem' className='icon-primary' />
) : ( ) : (
<FiBellOff size='1.25rem' className='clr-text-controls' /> <IconFollowOff size='1.25rem' className='clr-text-controls' />
) )
} }
disabled={controller.isProcessing} disabled={controller.isProcessing}
@ -62,7 +68,7 @@ function RSFormToolbar({ modified, anonymous, subscribed, claimable, onSubmit, o
{!anonymous && claimable ? ( {!anonymous && claimable ? (
<MiniButton <MiniButton
title='Стать владельцем' title='Стать владельцем'
icon={<LuCrown size='1.25rem' className='icon-green' />} icon={<IconOwner size='1.25rem' className='icon-green' />}
disabled={controller.isProcessing} disabled={controller.isProcessing}
onClick={controller.claim} onClick={controller.claim}
/> />
@ -70,7 +76,7 @@ function RSFormToolbar({ modified, anonymous, subscribed, claimable, onSubmit, o
{controller.isMutable ? ( {controller.isMutable ? (
<MiniButton <MiniButton
title='Удалить схему' title='Удалить схему'
icon={<BiTrash size='1.25rem' className='icon-red' />} icon={<IconDestroy size='1.25rem' className='icon-red' />}
disabled={!controller.isContentEditable || controller.isProcessing} disabled={!controller.isContentEditable || controller.isProcessing}
onClick={onDestroy} onClick={onDestroy}
/> />

View File

@ -1,5 +1,6 @@
import { BiDownArrowCircle, BiDownvote, BiDuplicate, BiPlusCircle, BiTrash, BiUpvote } from 'react-icons/bi'; import { BiDownArrowCircle } from 'react-icons/bi';
import { IconClone, IconDestroy, IconMoveDown, IconMoveUp, IconNewItem } from '@/components/Icons';
import BadgeHelp from '@/components/man/BadgeHelp'; import BadgeHelp from '@/components/man/BadgeHelp';
import Dropdown from '@/components/ui/Dropdown'; import Dropdown from '@/components/ui/Dropdown';
import DropdownButton from '@/components/ui/DropdownButton'; import DropdownButton from '@/components/ui/DropdownButton';
@ -22,25 +23,25 @@ function RSListToolbar() {
<Overlay position='top-1 right-1/2 translate-x-1/2' className='items-start cc-icons'> <Overlay position='top-1 right-1/2 translate-x-1/2' className='items-start cc-icons'>
<MiniButton <MiniButton
titleHtml={prepareTooltip('Переместить вверх', 'Alt + вверх')} titleHtml={prepareTooltip('Переместить вверх', 'Alt + вверх')}
icon={<BiUpvote size='1.25rem' className='icon-primary' />} icon={<IconMoveUp size='1.25rem' className='icon-primary' />}
disabled={controller.isProcessing || controller.nothingSelected} disabled={controller.isProcessing || controller.nothingSelected}
onClick={controller.moveUp} onClick={controller.moveUp}
/> />
<MiniButton <MiniButton
titleHtml={prepareTooltip('Переместить вниз', 'Alt + вниз')} titleHtml={prepareTooltip('Переместить вниз', 'Alt + вниз')}
icon={<BiDownvote size='1.25rem' className='icon-primary' />} icon={<IconMoveDown size='1.25rem' className='icon-primary' />}
disabled={controller.isProcessing || controller.nothingSelected} disabled={controller.isProcessing || controller.nothingSelected}
onClick={controller.moveDown} onClick={controller.moveDown}
/> />
<MiniButton <MiniButton
titleHtml={prepareTooltip('Клонировать конституенту', 'Alt + V')} titleHtml={prepareTooltip('Клонировать конституенту', 'Alt + V')}
icon={<BiDuplicate size='1.25rem' className='icon-green' />} icon={<IconClone size='1.25rem' className='icon-green' />}
disabled={controller.isProcessing || controller.selected.length !== 1} disabled={controller.isProcessing || controller.selected.length !== 1}
onClick={controller.cloneCst} onClick={controller.cloneCst}
/> />
<MiniButton <MiniButton
titleHtml={prepareTooltip('Добавить новую конституенту...', 'Alt + `')} titleHtml={prepareTooltip('Добавить новую конституенту...', 'Alt + `')}
icon={<BiPlusCircle size='1.25rem' className='icon-green' />} icon={<IconNewItem size='1.25rem' className='icon-green' />}
disabled={controller.isProcessing} disabled={controller.isProcessing}
onClick={() => controller.createCst(undefined, false)} onClick={() => controller.createCst(undefined, false)}
/> />
@ -65,7 +66,7 @@ function RSListToolbar() {
</div> </div>
<MiniButton <MiniButton
titleHtml={prepareTooltip('Удалить выбранные', 'Delete')} titleHtml={prepareTooltip('Удалить выбранные', 'Delete')}
icon={<BiTrash size='1.25rem' className='icon-red' />} icon={<IconDestroy size='1.25rem' className='icon-red' />}
disabled={controller.isProcessing || controller.nothingSelected} disabled={controller.isProcessing || controller.nothingSelected}
onClick={controller.deleteCst} onClick={controller.deleteCst}
/> />

View File

@ -1,18 +1,20 @@
'use client'; 'use client';
import { import {
BiFilterAlt, IconDestroy,
BiFont, IconFilter,
BiFontFamily, IconFitImage,
BiGitBranch, IconGraphClosure,
BiGitMerge, IconGraphExpand,
BiPlanet, IconGraphInputs,
BiPlusCircle, IconGraphMaximize,
BiReset, IconGraphOutputs,
BiTrash IconNewItem,
} from 'react-icons/bi'; IconReset,
import { LuExpand, LuImage, LuMaximize, LuMinimize } from 'react-icons/lu'; IconRotate3D,
IconText,
IconTextOff
} from '@/components/Icons';
import BadgeHelp from '@/components/man/BadgeHelp'; import BadgeHelp from '@/components/man/BadgeHelp';
import MiniButton from '@/components/ui/MiniButton'; import MiniButton from '@/components/ui/MiniButton';
import Overlay from '@/components/ui/Overlay'; import Overlay from '@/components/ui/Overlay';
@ -56,27 +58,27 @@ function GraphToolbar({
<div className='cc-icons'> <div className='cc-icons'>
<MiniButton <MiniButton
title='Настройки фильтрации узлов и связей' title='Настройки фильтрации узлов и связей'
icon={<BiFilterAlt size='1.25rem' className='icon-primary' />} icon={<IconFilter size='1.25rem' className='icon-primary' />}
onClick={showParamsDialog} onClick={showParamsDialog}
/> />
<MiniButton <MiniButton
title={!noText ? 'Скрыть текст' : 'Отобразить текст'} title={!noText ? 'Скрыть текст' : 'Отобразить текст'}
icon={ icon={
!noText ? ( !noText ? (
<BiFontFamily size='1.25rem' className='icon-green' /> <IconText size='1.25rem' className='icon-green' />
) : ( ) : (
<BiFont size='1.25rem' className='icon-primary' /> <IconTextOff size='1.25rem' className='icon-primary' />
) )
} }
onClick={toggleNoText} onClick={toggleNoText}
/> />
<MiniButton <MiniButton
icon={<LuImage size='1.25rem' className='icon-primary' />} icon={<IconFitImage size='1.25rem' className='icon-primary' />}
title='Восстановить камеру' title='Граф целиком'
onClick={onResetViewpoint} onClick={onResetViewpoint}
/> />
<MiniButton <MiniButton
icon={<BiPlanet size='1.25rem' className={orbit ? 'icon-green' : 'icon-primary'} />} icon={<IconRotate3D size='1.25rem' className={orbit ? 'icon-green' : 'icon-primary'} />}
title='Анимация вращения' title='Анимация вращения'
disabled={!is3D} disabled={!is3D}
onClick={toggleOrbit} onClick={toggleOrbit}
@ -84,7 +86,7 @@ function GraphToolbar({
{controller.isContentEditable ? ( {controller.isContentEditable ? (
<MiniButton <MiniButton
title='Новая конституента' title='Новая конституента'
icon={<BiPlusCircle size='1.25rem' className='icon-green' />} icon={<IconNewItem size='1.25rem' className='icon-green' />}
disabled={controller.isProcessing} disabled={controller.isProcessing}
onClick={onCreate} onClick={onCreate}
/> />
@ -92,7 +94,7 @@ function GraphToolbar({
{controller.isContentEditable ? ( {controller.isContentEditable ? (
<MiniButton <MiniButton
title='Удалить выбранные' title='Удалить выбранные'
icon={<BiTrash size='1.25rem' className='icon-red' />} icon={<IconDestroy size='1.25rem' className='icon-red' />}
disabled={controller.nothingSelected || controller.isProcessing} disabled={controller.nothingSelected || controller.isProcessing}
onClick={onDelete} onClick={onDelete}
/> />
@ -102,36 +104,36 @@ function GraphToolbar({
<div className='cc-icons'> <div className='cc-icons'>
<MiniButton <MiniButton
titleHtml='<b>[ESC]</b><br/>Сбросить выделение' titleHtml='<b>[ESC]</b><br/>Сбросить выделение'
icon={<BiReset size='1.25rem' className='icon-primary' />} icon={<IconReset size='1.25rem' className='icon-primary' />}
onClick={controller.deselectAll} onClick={controller.deselectAll}
/> />
<MiniButton <MiniButton
titleHtml='<b>Замыкание</b> - дополнение выделения влияющими конституентами' titleHtml='<b>Замыкание</b> - дополнение выделения влияющими конституентами'
icon={<LuMinimize size='1.25rem' className='icon-primary' />} icon={<IconGraphClosure size='1.25rem' className='icon-primary' />}
disabled={controller.nothingSelected} disabled={controller.nothingSelected}
onClick={controller.selectAllInputs} onClick={controller.selectAllInputs}
/> />
<MiniButton <MiniButton
titleHtml='<b>Максимизация</b> - дополнение выделения конституентами, зависимыми только от выделенных' titleHtml='<b>Максимизация</b> - дополнение выделения конституентами, зависимыми только от выделенных'
icon={<LuMaximize size='1.25rem' className='icon-primary' />} icon={<IconGraphMaximize size='1.25rem' className='icon-primary' />}
disabled={controller.nothingSelected} disabled={controller.nothingSelected}
onClick={controller.selectMax} onClick={controller.selectMax}
/> />
<MiniButton <MiniButton
titleHtml='Выделить все зависимые' titleHtml='Выделить все зависимые'
icon={<LuExpand size='1.25rem' className='icon-primary' />} icon={<IconGraphExpand size='1.25rem' className='icon-primary' />}
disabled={controller.nothingSelected} disabled={controller.nothingSelected}
onClick={controller.selectAllOutputs} onClick={controller.selectAllOutputs}
/> />
<MiniButton <MiniButton
titleHtml='Выделить поставщиков' titleHtml='Выделить поставщиков'
icon={<BiGitBranch size='1.25rem' className='icon-primary' />} icon={<IconGraphInputs size='1.25rem' className='icon-primary' />}
disabled={controller.nothingSelected} disabled={controller.nothingSelected}
onClick={controller.selectInputs} onClick={controller.selectInputs}
/> />
<MiniButton <MiniButton
titleHtml='Выделить потребителей' titleHtml='Выделить потребителей'
icon={<BiGitMerge size='1.25rem' className='icon-primary' />} icon={<IconGraphOutputs size='1.25rem' className='icon-primary' />}
disabled={controller.nothingSelected} disabled={controller.nothingSelected}
onClick={controller.selectOutputs} onClick={controller.selectOutputs}
/> />

View File

@ -1,30 +1,23 @@
'use client'; 'use client';
import { import { BiDiamond, BiMenu } from 'react-icons/bi';
BiDiamond,
BiDownload,
BiDuplicate,
BiMenu,
BiMeteor,
BiPlusCircle,
BiShareAlt,
BiTrash,
BiUpload
} from 'react-icons/bi';
import { FiEdit } from 'react-icons/fi'; import { FiEdit } from 'react-icons/fi';
import { import { LuAlertTriangle, LuArchive, LuBookCopy, LuNetwork, LuWand2 } from 'react-icons/lu';
LuAlertTriangle,
LuArchive,
LuBookCopy,
LuCrown,
LuGlasses,
LuNetwork,
LuReplace,
LuWand2
} from 'react-icons/lu';
import { VscLibrary } from 'react-icons/vsc'; import { VscLibrary } from 'react-icons/vsc';
import { urls } from '@/app/urls'; import { urls } from '@/app/urls';
import {
IconAdmin,
IconClone,
IconDestroy,
IconDownload,
IconNewItem,
IconOwner,
IconReader,
IconReplace,
IconShare,
IconUpload
} from '@/components/Icons';
import Button from '@/components/ui/Button'; import Button from '@/components/ui/Button';
import Dropdown from '@/components/ui/Dropdown'; import Dropdown from '@/components/ui/Dropdown';
import DropdownButton from '@/components/ui/DropdownButton'; import DropdownButton from '@/components/ui/DropdownButton';
@ -140,33 +133,33 @@ function RSTabsMenu({ onDestroy }: RSTabsMenuProps) {
{user ? ( {user ? (
<DropdownButton <DropdownButton
text={model.isOwned ? 'Вы — владелец' : 'Стать владельцем'} text={model.isOwned ? 'Вы — владелец' : 'Стать владельцем'}
icon={<LuCrown size='1rem' className='icon-green' />} icon={<IconOwner size='1rem' className='icon-green' />}
disabled={!model.isClaimable && !model.isOwned} disabled={!model.isClaimable && !model.isOwned}
onClick={!model.isOwned && model.isClaimable ? handleClaimOwner : undefined} onClick={!model.isOwned && model.isClaimable ? handleClaimOwner : undefined}
/> />
) : null} ) : null}
<DropdownButton <DropdownButton
text='Поделиться' text='Поделиться'
icon={<BiShareAlt size='1rem' className='icon-primary' />} icon={<IconShare size='1rem' className='icon-primary' />}
onClick={handleShare} onClick={handleShare}
/> />
{user ? ( {user ? (
<DropdownButton <DropdownButton
text='Клонировать' text='Клонировать'
icon={<BiDuplicate size='1rem' className='icon-primary' />} icon={<IconClone size='1rem' className='icon-primary' />}
disabled={model.isArchive} disabled={model.isArchive}
onClick={handleClone} onClick={handleClone}
/> />
) : null} ) : null}
<DropdownButton <DropdownButton
text='Выгрузить в Экстеор' text='Выгрузить в Экстеор'
icon={<BiDownload size='1rem' className='icon-primary' />} icon={<IconDownload size='1rem' className='icon-primary' />}
onClick={handleDownload} onClick={handleDownload}
/> />
{controller.isContentEditable ? ( {controller.isContentEditable ? (
<DropdownButton <DropdownButton
text='Загрузить из Экстеора' text='Загрузить из Экстеора'
icon={<BiUpload size='1rem' className='icon-red' />} icon={<IconUpload size='1rem' className='icon-red' />}
disabled={controller.isProcessing} disabled={controller.isProcessing}
onClick={handleUpload} onClick={handleUpload}
/> />
@ -174,7 +167,7 @@ function RSTabsMenu({ onDestroy }: RSTabsMenuProps) {
{controller.isMutable ? ( {controller.isMutable ? (
<DropdownButton <DropdownButton
text='Удалить схему' text='Удалить схему'
icon={<BiTrash size='1rem' className='icon-red' />} icon={<IconDestroy size='1rem' className='icon-red' />}
disabled={controller.isProcessing} disabled={controller.isProcessing}
onClick={handleDelete} onClick={handleDelete}
/> />
@ -183,7 +176,7 @@ function RSTabsMenu({ onDestroy }: RSTabsMenuProps) {
<DropdownButton <DropdownButton
className='border-t-2' className='border-t-2'
text='Создать новую схему' text='Создать новую схему'
icon={<BiPlusCircle size='1rem' className='icon-primary' />} icon={<IconNewItem size='1rem' className='icon-primary' />}
onClick={handleCreateNew} onClick={handleCreateNew}
/> />
) : null} ) : null}
@ -241,7 +234,7 @@ function RSTabsMenu({ onDestroy }: RSTabsMenuProps) {
<DropdownButton <DropdownButton
text='Отождествление' text='Отождествление'
title='Заменить вхождения одной конституенты на другую' title='Заменить вхождения одной конституенты на другую'
icon={<LuReplace size='1rem' className='icon-red' />} icon={<IconReplace size='1rem' className='icon-red' />}
onClick={handleSubstituteCst} onClick={handleSubstituteCst}
disabled={!controller.isContentEditable || controller.isProcessing} disabled={!controller.isContentEditable || controller.isProcessing}
/> />
@ -274,11 +267,11 @@ function RSTabsMenu({ onDestroy }: RSTabsMenuProps) {
className='h-full pr-2' className='h-full pr-2'
icon={ icon={
mode === UserAccessMode.ADMIN ? ( mode === UserAccessMode.ADMIN ? (
<BiMeteor size='1.25rem' className='icon-primary' /> <IconAdmin size='1.25rem' className='icon-primary' />
) : mode === UserAccessMode.OWNER ? ( ) : mode === UserAccessMode.OWNER ? (
<LuCrown size='1.25rem' className='icon-primary' /> <IconOwner size='1.25rem' className='icon-primary' />
) : ( ) : (
<LuGlasses size='1.25rem' className='icon-primary' /> <IconReader size='1.25rem' className='icon-primary' />
) )
} }
onClick={accessMenu.toggle} onClick={accessMenu.toggle}
@ -287,20 +280,20 @@ function RSTabsMenu({ onDestroy }: RSTabsMenuProps) {
<DropdownButton <DropdownButton
text={labelAccessMode(UserAccessMode.READER)} text={labelAccessMode(UserAccessMode.READER)}
title={describeAccessMode(UserAccessMode.READER)} title={describeAccessMode(UserAccessMode.READER)}
icon={<LuGlasses size='1rem' className='icon-primary' />} icon={<IconReader size='1rem' className='icon-primary' />}
onClick={() => handleChangeMode(UserAccessMode.READER)} onClick={() => handleChangeMode(UserAccessMode.READER)}
/> />
<DropdownButton <DropdownButton
text={labelAccessMode(UserAccessMode.OWNER)} text={labelAccessMode(UserAccessMode.OWNER)}
title={describeAccessMode(UserAccessMode.OWNER)} title={describeAccessMode(UserAccessMode.OWNER)}
icon={<LuCrown size='1rem' className='icon-primary' />} icon={<IconOwner size='1rem' className='icon-primary' />}
disabled={!model.isOwned} disabled={!model.isOwned}
onClick={() => handleChangeMode(UserAccessMode.OWNER)} onClick={() => handleChangeMode(UserAccessMode.OWNER)}
/> />
<DropdownButton <DropdownButton
text={labelAccessMode(UserAccessMode.ADMIN)} text={labelAccessMode(UserAccessMode.ADMIN)}
title={describeAccessMode(UserAccessMode.ADMIN)} title={describeAccessMode(UserAccessMode.ADMIN)}
icon={<BiMeteor size='1rem' className='icon-primary' />} icon={<IconAdmin size='1rem' className='icon-primary' />}
disabled={!user?.is_staff} disabled={!user?.is_staff}
onClick={() => handleChangeMode(UserAccessMode.ADMIN)} onClick={() => handleChangeMode(UserAccessMode.ADMIN)}
/> />

View File

@ -1,8 +1,8 @@
'use client'; 'use client';
import { useCallback, useLayoutEffect, useState } from 'react'; import { useCallback, useLayoutEffect, useState } from 'react';
import { BiCog, BiFilterAlt } from 'react-icons/bi';
import { IconFilter, IconSettings } from '@/components/Icons';
import Dropdown from '@/components/ui/Dropdown'; import Dropdown from '@/components/ui/Dropdown';
import DropdownButton from '@/components/ui/DropdownButton'; import DropdownButton from '@/components/ui/DropdownButton';
import SearchBar from '@/components/ui/SearchBar'; import SearchBar from '@/components/ui/SearchBar';
@ -90,7 +90,7 @@ function ConstituentsSearch({ schema, activeID, activeExpression, setFiltered }:
title='Настройка атрибутов для фильтрации' title='Настройка атрибутов для фильтрации'
hideTitle={matchModeMenu.isOpen} hideTitle={matchModeMenu.isOpen}
className='h-full' className='h-full'
icon={<BiFilterAlt size='1.25rem' />} icon={<IconFilter size='1.25rem' />}
text={labelCstMatchMode(filterMatch)} text={labelCstMatchMode(filterMatch)}
onClick={matchModeMenu.toggle} onClick={matchModeMenu.toggle}
/> />
@ -121,7 +121,7 @@ function ConstituentsSearch({ schema, activeID, activeExpression, setFiltered }:
title='Настройка фильтрации по графу термов' title='Настройка фильтрации по графу термов'
hideTitle={sourceMenu.isOpen} hideTitle={sourceMenu.isOpen}
className='h-full pr-2' className='h-full pr-2'
icon={<BiCog size='1.25rem' />} icon={<IconSettings size='1.25rem' />}
text={labelCstSource(filterSource)} text={labelCstSource(filterSource)}
onClick={sourceMenu.toggle} onClick={sourceMenu.toggle}
/> />

View File

@ -2,10 +2,10 @@
import clsx from 'clsx'; import clsx from 'clsx';
import { useEffect, useState } from 'react'; import { useEffect, useState } from 'react';
import { BiInfoCircle } from 'react-icons/bi';
import { toast } from 'react-toastify'; import { toast } from 'react-toastify';
import { urls } from '@/app/urls'; import { urls } from '@/app/urls';
import { IconHelp } from '@/components/Icons';
import InfoError from '@/components/info/InfoError'; import InfoError from '@/components/info/InfoError';
import Button from '@/components/ui/Button'; import Button from '@/components/ui/Button';
import Checkbox from '@/components/ui/Checkbox'; import Checkbox from '@/components/ui/Checkbox';
@ -80,7 +80,7 @@ function RegisterPage() {
<FlexColumn> <FlexColumn>
<div className='absolute'> <div className='absolute'>
<Overlay id={globals.password_tooltip} position='top-[4.8rem] left-[3.4rem] absolute'> <Overlay id={globals.password_tooltip} position='top-[4.8rem] left-[3.4rem] absolute'>
<BiInfoCircle size='1.25rem' className='icon-primary' /> <IconHelp size='1.25rem' className='icon-primary' />
</Overlay> </Overlay>
<Tooltip anchorSelect={`#${globals.password_tooltip}`} offset={6}> <Tooltip anchorSelect={`#${globals.password_tooltip}`} offset={6}>
<p>- используйте уникальный пароль</p> <p>- используйте уникальный пароль</p>

View File

@ -2,8 +2,8 @@
import { AnimatePresence } from 'framer-motion'; import { AnimatePresence } from 'framer-motion';
import { useMemo, useState } from 'react'; import { useMemo, useState } from 'react';
import { FiBell, FiBellOff } from 'react-icons/fi';
import { IconFollow, IconFollowOff } from '@/components/Icons';
import MiniButton from '@/components/ui/MiniButton'; import MiniButton from '@/components/ui/MiniButton';
import Overlay from '@/components/ui/Overlay'; import Overlay from '@/components/ui/Overlay';
import AnimateFade from '@/components/wrap/AnimateFade'; import AnimateFade from '@/components/wrap/AnimateFade';
@ -41,9 +41,9 @@ function UserTabs() {
title='Отслеживаемые схемы' title='Отслеживаемые схемы'
icon={ icon={
showSubs ? ( showSubs ? (
<FiBell size='1.25rem' className='icon-primary' /> <IconFollow size='1.25rem' className='icon-primary' />
) : ( ) : (
<FiBellOff size='1.25rem' className='icon-primary' /> <IconFollowOff size='1.25rem' className='icon-primary' />
) )
} }
onClick={() => setShowSubs(prev => !prev)} onClick={() => setShowSubs(prev => !prev)}