mirror of
https://github.com/IRBorisov/ConceptPortal.git
synced 2025-06-26 04:50:36 +03:00
F: Refactor z-index and stacking
This commit is contained in:
parent
293f1cad6f
commit
81fa0c5796
|
@ -15,6 +15,7 @@ interface OverlayProps extends Styling {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Displays a transparent overlay over the main content.
|
* Displays a transparent overlay over the main content.
|
||||||
|
* Note: Overlay should be inside a relative container.
|
||||||
*/
|
*/
|
||||||
export function Overlay({
|
export function Overlay({
|
||||||
children,
|
children,
|
||||||
|
@ -24,10 +25,8 @@ export function Overlay({
|
||||||
...restProps
|
...restProps
|
||||||
}: React.PropsWithChildren<OverlayProps>) {
|
}: React.PropsWithChildren<OverlayProps>) {
|
||||||
return (
|
return (
|
||||||
<div className='relative'>
|
|
||||||
<div className={clsx('absolute', className, position, layer)} {...restProps}>
|
<div className={clsx('absolute', className, position, layer)} {...restProps}>
|
||||||
{children}
|
{children}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,6 +39,7 @@ export function Tooltip({
|
||||||
delayHide={100}
|
delayHide={100}
|
||||||
opacity={1}
|
opacity={1}
|
||||||
className={clsx(
|
className={clsx(
|
||||||
|
'relative',
|
||||||
'max-h-[calc(100svh-6rem)]',
|
'max-h-[calc(100svh-6rem)]',
|
||||||
'overflow-y-auto overflow-x-hidden sm:overflow-hidden overscroll-contain',
|
'overflow-y-auto overflow-x-hidden sm:overflow-hidden overscroll-contain',
|
||||||
'border shadow-md',
|
'border shadow-md',
|
||||||
|
|
|
@ -23,6 +23,7 @@ interface DropdownProps extends Styling {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Animated list of children with optional positioning and visibility control.
|
* Animated list of children with optional positioning and visibility control.
|
||||||
|
* Note: Dropdown should be inside a relative container.
|
||||||
*/
|
*/
|
||||||
export function Dropdown({
|
export function Dropdown({
|
||||||
isOpen,
|
isOpen,
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
|
|
||||||
import { Overlay } from '@/components/Container';
|
|
||||||
import { IconSearch } from '@/components/Icons';
|
import { IconSearch } from '@/components/Icons';
|
||||||
import { type Styling } from '@/components/props';
|
import { type Styling } from '@/components/props';
|
||||||
|
|
||||||
|
@ -35,15 +34,17 @@ export function SearchBar({
|
||||||
noIcon,
|
noIcon,
|
||||||
onChangeQuery,
|
onChangeQuery,
|
||||||
noBorder,
|
noBorder,
|
||||||
|
className,
|
||||||
placeholder = 'Поиск',
|
placeholder = 'Поиск',
|
||||||
...restProps
|
...restProps
|
||||||
}: SearchBarProps) {
|
}: SearchBarProps) {
|
||||||
return (
|
return (
|
||||||
<div {...restProps}>
|
<div className={clsx('relative', className)} {...restProps}>
|
||||||
{!noIcon ? (
|
{!noIcon ? (
|
||||||
<Overlay position='top-[-0.125rem] left-3 translate-y-1/2' className='pointer-events-none clr-text-controls'>
|
<IconSearch
|
||||||
<IconSearch size='1.25rem' />
|
className='absolute top-[-0.125rem] left-3 translate-y-1/2 pointer-events-none clr-text-controls'
|
||||||
</Overlay>
|
size='1.25rem'
|
||||||
|
/>
|
||||||
) : null}
|
) : null}
|
||||||
<TextInput
|
<TextInput
|
||||||
id={id}
|
id={id}
|
||||||
|
|
|
@ -3,7 +3,6 @@ import clsx from 'clsx';
|
||||||
|
|
||||||
import { globalIDs, PARAMETER } from '@/utils/constants';
|
import { globalIDs, PARAMETER } from '@/utils/constants';
|
||||||
|
|
||||||
import { Overlay } from '../Container';
|
|
||||||
import { MiniButton } from '../Control';
|
import { MiniButton } from '../Control';
|
||||||
import { IconDropArrow, IconPageRight } from '../Icons';
|
import { IconDropArrow, IconPageRight } from '../Icons';
|
||||||
import { type Styling } from '../props';
|
import { type Styling } from '../props';
|
||||||
|
@ -86,6 +85,7 @@ export function SelectTree<ItemType>({
|
||||||
<div
|
<div
|
||||||
key={`${prefix}${index}`}
|
key={`${prefix}${index}`}
|
||||||
className={clsx(
|
className={clsx(
|
||||||
|
'relative',
|
||||||
'pr-3 pl-6 border-b',
|
'pr-3 pl-6 border-b',
|
||||||
'cc-scroll-row',
|
'cc-scroll-row',
|
||||||
'bg-prim-200 clr-hover cc-animate-color',
|
'bg-prim-200 clr-hover cc-animate-color',
|
||||||
|
@ -108,14 +108,13 @@ export function SelectTree<ItemType>({
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{foldable.has(item) ? (
|
{foldable.has(item) ? (
|
||||||
<Overlay position='left-[-1.3rem]' className={clsx(!folded.includes(item) && 'top-[0.1rem]')}>
|
|
||||||
<MiniButton
|
<MiniButton
|
||||||
|
className={clsx('absolute left-[0.3rem]', !folded.includes(item) ? 'top-[0.4rem]' : 'top-1')}
|
||||||
noPadding
|
noPadding
|
||||||
noHover
|
noHover
|
||||||
icon={!folded.includes(item) ? <IconDropArrow size='1rem' /> : <IconPageRight size='1.25rem' />}
|
icon={!folded.includes(item) ? <IconDropArrow size='1rem' /> : <IconPageRight size='1.25rem' />}
|
||||||
onClick={event => handleClickFold(event, item, folded.includes(item))}
|
onClick={event => handleClickFold(event, item, folded.includes(item))}
|
||||||
/>
|
/>
|
||||||
</Overlay>
|
|
||||||
) : null}
|
) : null}
|
||||||
{getParent(item) === item ? getLabel(item) : `- ${getLabel(item).toLowerCase()}`}
|
{getParent(item) === item ? getLabel(item) : `- ${getLabel(item).toLowerCase()}`}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -9,9 +9,9 @@ interface ModalBackdropProps {
|
||||||
export function ModalBackdrop({ onHide }: ModalBackdropProps) {
|
export function ModalBackdrop({ onHide }: ModalBackdropProps) {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className={clsx('z-navigation', 'fixed top-0 left-0', 'w-full h-full', 'backdrop-blur-[3px] opacity-50')} />
|
<div className={clsx('z-bottom', 'fixed top-0 left-0', 'w-full h-full', 'backdrop-blur-[3px] opacity-50')} />
|
||||||
<div
|
<div
|
||||||
className={clsx('z-navigation', 'fixed top-0 left-0', 'w-full h-full', 'bg-prim-0 opacity-25')}
|
className={clsx('z-bottom', 'fixed top-0 left-0', 'w-full h-full', 'bg-prim-0 opacity-25')}
|
||||||
onClick={onHide}
|
onClick={onHide}
|
||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
|
|
|
@ -10,7 +10,6 @@ import { useDialogsStore } from '@/stores/dialogs';
|
||||||
import { PARAMETER } from '@/utils/constants';
|
import { PARAMETER } from '@/utils/constants';
|
||||||
import { prepareTooltip } from '@/utils/utils';
|
import { prepareTooltip } from '@/utils/utils';
|
||||||
|
|
||||||
import { Overlay } from '../Container';
|
|
||||||
import { Button, MiniButton, SubmitButton } from '../Control';
|
import { Button, MiniButton, SubmitButton } from '../Control';
|
||||||
import { IconClose } from '../Icons';
|
import { IconClose } from '../Icons';
|
||||||
import { type Styling } from '../props';
|
import { type Styling } from '../props';
|
||||||
|
@ -89,12 +88,12 @@ export function ModalForm({
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='fixed top-0 left-0 w-full h-full z-modal cursor-default'>
|
<div className='fixed top-0 left-0 w-full h-full z-modal isolate cursor-default'>
|
||||||
<ModalBackdrop onHide={handleCancel} />
|
<ModalBackdrop onHide={handleCancel} />
|
||||||
<form
|
<form
|
||||||
className={clsx(
|
className={clsx(
|
||||||
'cc-animate-modal',
|
'cc-animate-modal',
|
||||||
'z-modal absolute bottom-1/2 left-1/2 -translate-x-1/2 translate-y-1/2',
|
'absolute bottom-1/2 left-1/2 -translate-x-1/2 translate-y-1/2',
|
||||||
'border rounded-xl bg-prim-100'
|
'border rounded-xl bg-prim-100'
|
||||||
)}
|
)}
|
||||||
onSubmit={handleSubmit}
|
onSubmit={handleSubmit}
|
||||||
|
@ -105,7 +104,6 @@ export function ModalForm({
|
||||||
</div>
|
</div>
|
||||||
) : null}
|
) : null}
|
||||||
|
|
||||||
<Overlay className='z-modalOverlay'>
|
|
||||||
<MiniButton
|
<MiniButton
|
||||||
noPadding
|
noPadding
|
||||||
titleHtml={prepareTooltip('Закрыть диалоговое окно', 'ESC')}
|
titleHtml={prepareTooltip('Закрыть диалоговое окно', 'ESC')}
|
||||||
|
@ -113,7 +111,6 @@ export function ModalForm({
|
||||||
className='float-right mt-2 mr-2'
|
className='float-right mt-2 mr-2'
|
||||||
onClick={handleCancel}
|
onClick={handleCancel}
|
||||||
/>
|
/>
|
||||||
</Overlay>
|
|
||||||
|
|
||||||
{header ? <h1 className='px-12 py-2 select-none'>{header}</h1> : null}
|
{header ? <h1 className='px-12 py-2 select-none'>{header}</h1> : null}
|
||||||
|
|
||||||
|
@ -133,7 +130,7 @@ export function ModalForm({
|
||||||
{children}
|
{children}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className='z-modal-controls my-2 flex gap-12 justify-center text-sm'>
|
<div className='z-pop my-2 flex gap-12 justify-center text-sm'>
|
||||||
<SubmitButton
|
<SubmitButton
|
||||||
autoFocus
|
autoFocus
|
||||||
text={submitText}
|
text={submitText}
|
||||||
|
|
|
@ -4,9 +4,9 @@ import { Loader } from '@/components/Loader';
|
||||||
|
|
||||||
export function ModalLoader() {
|
export function ModalLoader() {
|
||||||
return (
|
return (
|
||||||
<div className='fixed top-0 left-0 w-full h-full z-modal cursor-default'>
|
<div className='fixed top-0 left-0 w-full h-full z-modal isolate cursor-default'>
|
||||||
<div className={clsx('z-navigation', 'fixed top-0 left-0', 'w-full h-full', 'backdrop-blur-[3px] opacity-50')} />
|
<div className={clsx('z-bottom fixed top-0 left-0', 'w-full h-full', 'backdrop-blur-[3px] opacity-50')} />
|
||||||
<div className={clsx('z-navigation', 'fixed top-0 left-0', 'w-full h-full', 'bg-prim-0 opacity-25')} />
|
<div className={clsx('z-bottom fixed top-0 left-0', 'w-full h-full', 'bg-prim-0 opacity-25')} />
|
||||||
<div
|
<div
|
||||||
className={clsx(
|
className={clsx(
|
||||||
'cc-animate-modal p-20',
|
'cc-animate-modal p-20',
|
||||||
|
|
|
@ -9,7 +9,6 @@ import { useDialogsStore } from '@/stores/dialogs';
|
||||||
import { PARAMETER } from '@/utils/constants';
|
import { PARAMETER } from '@/utils/constants';
|
||||||
import { prepareTooltip } from '@/utils/utils';
|
import { prepareTooltip } from '@/utils/utils';
|
||||||
|
|
||||||
import { Overlay } from '../Container';
|
|
||||||
import { Button, MiniButton } from '../Control';
|
import { Button, MiniButton } from '../Control';
|
||||||
import { IconClose } from '../Icons';
|
import { IconClose } from '../Icons';
|
||||||
|
|
||||||
|
@ -34,7 +33,7 @@ export function ModalView({
|
||||||
useEscapeKey(hideDialog);
|
useEscapeKey(hideDialog);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='fixed top-0 left-0 w-full h-full z-modal cursor-default'>
|
<div className='fixed top-0 left-0 w-full h-full z-modal isolate cursor-default'>
|
||||||
<ModalBackdrop onHide={hideDialog} />
|
<ModalBackdrop onHide={hideDialog} />
|
||||||
<div
|
<div
|
||||||
className={clsx(
|
className={clsx(
|
||||||
|
@ -49,7 +48,6 @@ export function ModalView({
|
||||||
</div>
|
</div>
|
||||||
) : null}
|
) : null}
|
||||||
|
|
||||||
<Overlay className='z-modalOverlay'>
|
|
||||||
<MiniButton
|
<MiniButton
|
||||||
noPadding
|
noPadding
|
||||||
titleHtml={prepareTooltip('Закрыть диалоговое окно', 'ESC')}
|
titleHtml={prepareTooltip('Закрыть диалоговое окно', 'ESC')}
|
||||||
|
@ -57,7 +55,6 @@ export function ModalView({
|
||||||
className='float-right mt-2 mr-2'
|
className='float-right mt-2 mr-2'
|
||||||
onClick={hideDialog}
|
onClick={hideDialog}
|
||||||
/>
|
/>
|
||||||
</Overlay>
|
|
||||||
|
|
||||||
{header ? <h1 className='px-12 py-2 select-none'>{header}</h1> : null}
|
{header ? <h1 className='px-12 py-2 select-none'>{header}</h1> : null}
|
||||||
|
|
||||||
|
@ -77,7 +74,7 @@ export function ModalView({
|
||||||
{children}
|
{children}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className='z-modal-controls my-2 flex gap-12 justify-center text-sm'>
|
<div className='z-pop my-2 flex gap-12 justify-center text-sm'>
|
||||||
<Button text='Закрыть' className='min-w-[7rem]' onClick={hideDialog} />
|
<Button text='Закрыть' className='min-w-[7rem]' onClick={hideDialog} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -39,13 +39,11 @@ export function BadgeHelp({ topic, padding = 'p-1', ...restProps }: BadgeHelpPro
|
||||||
return (
|
return (
|
||||||
<div tabIndex={-1} id={`help-${topic}`} className={padding}>
|
<div tabIndex={-1} id={`help-${topic}`} className={padding}>
|
||||||
<IconHelp 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-topmost' {...restProps}>
|
||||||
<Suspense fallback={<Loader />}>
|
<Suspense fallback={<Loader />}>
|
||||||
<div className='relative' onClick={event => event.stopPropagation()}>
|
<div className='absolute right-1 text-sm top-[0.4rem] clr-input' onClick={event => event.stopPropagation()}>
|
||||||
<div className='absolute right-0 text-sm top-[0.4rem] clr-input'>
|
|
||||||
<TextURL text='Справка...' href={`/manuals?topic=${topic}`} />
|
<TextURL text='Справка...' href={`/manuals?topic=${topic}`} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
<TopicPage topic={topic} />
|
<TopicPage topic={topic} />
|
||||||
</Suspense>
|
</Suspense>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
|
|
|
@ -33,7 +33,7 @@ export function TopicsDropdown({ activeTopic, onChangeTopic }: TopicsDropdownPro
|
||||||
className={clsx(
|
className={clsx(
|
||||||
'absolute left-0 w-[13.5rem]', // prettier: split-lines
|
'absolute left-0 w-[13.5rem]', // prettier: split-lines
|
||||||
'flex flex-col',
|
'flex flex-col',
|
||||||
'z-modal-tooltip',
|
'z-topmost',
|
||||||
'text-xs sm:text-sm',
|
'text-xs sm:text-sm',
|
||||||
'select-none',
|
'select-none',
|
||||||
{
|
{
|
||||||
|
|
|
@ -5,7 +5,7 @@ import { urls, useConceptNavigation } from '@/app';
|
||||||
import { useLabelUser, useRoleStore, UserRole } from '@/features/users';
|
import { useLabelUser, useRoleStore, UserRole } from '@/features/users';
|
||||||
import { InfoUsers, SelectUser } from '@/features/users/components';
|
import { InfoUsers, SelectUser } from '@/features/users/components';
|
||||||
|
|
||||||
import { Overlay, Tooltip } from '@/components/Container';
|
import { Tooltip } from '@/components/Container';
|
||||||
import { MiniButton } from '@/components/Control';
|
import { MiniButton } from '@/components/Control';
|
||||||
import { useDropdown } from '@/components/Dropdown';
|
import { useDropdown } from '@/components/Dropdown';
|
||||||
import {
|
import {
|
||||||
|
@ -83,7 +83,7 @@ export function EditorLibraryItem({ schema, isAttachedToOSS }: EditorLibraryItem
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='flex flex-col'>
|
<div className='flex flex-col'>
|
||||||
<div className='flex justify-stretch sm:mb-1 max-w-[30rem] gap-3'>
|
<div className='relative flex justify-stretch sm:mb-1 max-w-[30rem] gap-3'>
|
||||||
<MiniButton
|
<MiniButton
|
||||||
noHover
|
noHover
|
||||||
noPadding
|
noPadding
|
||||||
|
@ -101,12 +101,11 @@ export function EditorLibraryItem({ schema, isAttachedToOSS }: EditorLibraryItem
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div className='relative'>
|
||||||
{ownerSelector.isOpen ? (
|
{ownerSelector.isOpen ? (
|
||||||
<Overlay position='top-[-0.5rem] left-[4rem] cc-icons'>
|
<div className='absolute top-[-0.5rem] left-[4rem]'>
|
||||||
{ownerSelector.isOpen ? (
|
|
||||||
<SelectUser className='w-[25rem] sm:w-[26rem] text-sm' value={schema.owner} onChange={onSelectUser} />
|
<SelectUser className='w-[25rem] sm:w-[26rem] text-sm' value={schema.owner} onChange={onSelectUser} />
|
||||||
) : null}
|
</div>
|
||||||
</Overlay>
|
|
||||||
) : null}
|
) : null}
|
||||||
<ValueIcon
|
<ValueIcon
|
||||||
className='sm:mb-1'
|
className='sm:mb-1'
|
||||||
|
@ -116,6 +115,7 @@ export function EditorLibraryItem({ schema, isAttachedToOSS }: EditorLibraryItem
|
||||||
onClick={ownerSelector.toggle}
|
onClick={ownerSelector.toggle}
|
||||||
disabled={isModified || isProcessing || isAttachedToOSS || role < UserRole.OWNER}
|
disabled={isModified || isProcessing || isAttachedToOSS || role < UserRole.OWNER}
|
||||||
/>
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div className='sm:mb-1 flex justify-between items-center'>
|
<div className='sm:mb-1 flex justify-between items-center'>
|
||||||
<ValueIcon
|
<ValueIcon
|
||||||
|
@ -126,7 +126,7 @@ export function EditorLibraryItem({ schema, isAttachedToOSS }: EditorLibraryItem
|
||||||
onClick={handleEditEditors}
|
onClick={handleEditEditors}
|
||||||
disabled={isModified || isProcessing || role < UserRole.OWNER}
|
disabled={isModified || isProcessing || role < UserRole.OWNER}
|
||||||
/>
|
/>
|
||||||
<Tooltip anchorSelect='#editor_stats' layer='z-modal-tooltip'>
|
<Tooltip anchorSelect='#editor_stats'>
|
||||||
<Suspense fallback={<Loader scale={2} />}>
|
<Suspense fallback={<Loader scale={2} />}>
|
||||||
<InfoUsers items={schema.editors} prefix={prefixes.user_editors} header='Редакторы' />
|
<InfoUsers items={schema.editors} prefix={prefixes.user_editors} header='Редакторы' />
|
||||||
</Suspense>
|
</Suspense>
|
||||||
|
|
|
@ -120,7 +120,7 @@ export function PickSchema({
|
||||||
className='mt-1'
|
className='mt-1'
|
||||||
onClick={() => locationMenu.toggle()}
|
onClick={() => locationMenu.toggle()}
|
||||||
/>
|
/>
|
||||||
<Dropdown isOpen={locationMenu.isOpen} stretchLeft className='w-[20rem] h-[12.5rem] z-modal-tooltip'>
|
<Dropdown isOpen={locationMenu.isOpen} stretchLeft className='w-[20rem] h-[12.5rem]'>
|
||||||
<SelectLocation
|
<SelectLocation
|
||||||
value={filterLocation}
|
value={filterLocation}
|
||||||
prefix={prefixes.folders_list}
|
prefix={prefixes.folders_list}
|
||||||
|
|
|
@ -48,7 +48,7 @@ export function SelectLocationContext({
|
||||||
/>
|
/>
|
||||||
<Dropdown
|
<Dropdown
|
||||||
isOpen={menu.isOpen}
|
isOpen={menu.isOpen}
|
||||||
className={clsx('w-[20rem] h-[12.5rem] z-modal-tooltip', dropdownHeight)}
|
className={clsx('w-[20rem] h-[12.5rem] z-tooltip', dropdownHeight)}
|
||||||
margin='mt-[-0.25rem]'
|
margin='mt-[-0.25rem]'
|
||||||
>
|
>
|
||||||
<SelectLocation
|
<SelectLocation
|
||||||
|
|
|
@ -45,7 +45,7 @@ export function SelectLocationHead({
|
||||||
onClick={menu.toggle}
|
onClick={menu.toggle}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Dropdown isOpen={menu.isOpen} className='z-modal-tooltip' margin='mt-2'>
|
<Dropdown isOpen={menu.isOpen} margin='mt-2'>
|
||||||
{Object.values(LocationHead)
|
{Object.values(LocationHead)
|
||||||
.filter(head => !excluded.includes(head))
|
.filter(head => !excluded.includes(head))
|
||||||
.map((head, index) => {
|
.map((head, index) => {
|
||||||
|
|
|
@ -42,7 +42,7 @@ export function ToolbarItemAccess({
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Overlay position='top-[4.5rem] right-0 w-[12rem] pr-2' className='flex' layer='z-bottom'>
|
<Overlay position='top-[4.5rem] right-0' className='w-[12rem] flex pr-2' layer='z-bottom'>
|
||||||
<Label text='Доступ' className='self-center select-none' />
|
<Label text='Доступ' className='self-center select-none' />
|
||||||
<div className='ml-auto cc-icons'>
|
<div className='ml-auto cc-icons'>
|
||||||
<SelectAccessPolicy
|
<SelectAccessPolicy
|
||||||
|
|
|
@ -155,7 +155,7 @@ export function DlgCloneLibraryItem() {
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<TextArea id='dlg_comment' {...register('comment')} label='Описание' error={errors.comment} />
|
<TextArea id='dlg_comment' {...register('comment')} label='Описание' rows={4} error={errors.comment} />
|
||||||
|
|
||||||
{selected.length > 0 ? (
|
{selected.length > 0 ? (
|
||||||
<Controller
|
<Controller
|
||||||
|
|
|
@ -8,7 +8,6 @@ import clsx from 'clsx';
|
||||||
import { urls, useConceptNavigation } from '@/app';
|
import { urls, useConceptNavigation } from '@/app';
|
||||||
import { useAuthSuspense } from '@/features/auth';
|
import { useAuthSuspense } from '@/features/auth';
|
||||||
|
|
||||||
import { Overlay } from '@/components/Container';
|
|
||||||
import { Button, MiniButton, SubmitButton } from '@/components/Control';
|
import { Button, MiniButton, SubmitButton } from '@/components/Control';
|
||||||
import { IconDownload } from '@/components/Icons';
|
import { IconDownload } from '@/components/Icons';
|
||||||
import { InfoError } from '@/components/InfoError';
|
import { InfoError } from '@/components/InfoError';
|
||||||
|
@ -108,9 +107,9 @@ export function FormCreateItem() {
|
||||||
onSubmit={event => void handleSubmit(onSubmit)(event)}
|
onSubmit={event => void handleSubmit(onSubmit)(event)}
|
||||||
onChange={resetErrors}
|
onChange={resetErrors}
|
||||||
>
|
>
|
||||||
<h1 className='select-none'>
|
<h1 className='select-none relative'>
|
||||||
{itemType == LibraryItemType.RSFORM ? (
|
{itemType == LibraryItemType.RSFORM ? (
|
||||||
<Overlay position='top-0 right-[0.5rem]'>
|
<>
|
||||||
<Controller
|
<Controller
|
||||||
control={control}
|
control={control}
|
||||||
name='file'
|
name='file'
|
||||||
|
@ -127,10 +126,11 @@ export function FormCreateItem() {
|
||||||
/>
|
/>
|
||||||
<MiniButton
|
<MiniButton
|
||||||
title='Загрузить из Экстеор'
|
title='Загрузить из Экстеор'
|
||||||
|
className='absolute top-0 right-0'
|
||||||
icon={<IconDownload size='1.25rem' className='icon-primary' />}
|
icon={<IconDownload size='1.25rem' className='icon-primary' />}
|
||||||
onClick={() => inputRef.current?.click()}
|
onClick={() => inputRef.current?.click()}
|
||||||
/>
|
/>
|
||||||
</Overlay>
|
</>
|
||||||
) : null}
|
) : null}
|
||||||
Создание схемы
|
Создание схемы
|
||||||
</h1>
|
</h1>
|
||||||
|
|
|
@ -3,10 +3,8 @@
|
||||||
import { toast } from 'react-toastify';
|
import { toast } from 'react-toastify';
|
||||||
import fileDownload from 'js-file-download';
|
import fileDownload from 'js-file-download';
|
||||||
|
|
||||||
import { Overlay } from '@/components/Container';
|
|
||||||
import { MiniButton } from '@/components/Control';
|
import { MiniButton } from '@/components/Control';
|
||||||
import { IconCSV } from '@/components/Icons';
|
import { IconCSV } from '@/components/Icons';
|
||||||
import { useAppLayoutStore } from '@/stores/appLayout';
|
|
||||||
import { useDialogsStore } from '@/stores/dialogs';
|
import { useDialogsStore } from '@/stores/dialogs';
|
||||||
import { infoMsg } from '@/utils/labels';
|
import { infoMsg } from '@/utils/labels';
|
||||||
import { convertToCSV } from '@/utils/utils';
|
import { convertToCSV } from '@/utils/utils';
|
||||||
|
@ -24,8 +22,6 @@ export function LibraryPage() {
|
||||||
const { items: libraryItems } = useLibrarySuspense();
|
const { items: libraryItems } = useLibrarySuspense();
|
||||||
const { renameLocation } = useRenameLocation();
|
const { renameLocation } = useRenameLocation();
|
||||||
|
|
||||||
const noNavigation = useAppLayoutStore(state => state.noNavigation);
|
|
||||||
|
|
||||||
const folderMode = useLibrarySearchStore(state => state.folderMode);
|
const folderMode = useLibrarySearchStore(state => state.folderMode);
|
||||||
const location = useLibrarySearchStore(state => state.location);
|
const location = useLibrarySearchStore(state => state.location);
|
||||||
const setLocation = useLibrarySearchStore(state => state.setLocation);
|
const setLocation = useLibrarySearchStore(state => state.setLocation);
|
||||||
|
@ -57,20 +53,15 @@ export function LibraryPage() {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Overlay
|
<ToolbarSearch total={libraryItems.length} filtered={filtered.length} />
|
||||||
position={noNavigation ? 'top-[0.25rem] right-[3rem]' : 'top-[0.25rem] right-0'}
|
<div className='relative cc-fade-in flex'>
|
||||||
layer='z-tooltip'
|
|
||||||
className='cc-animate-position'
|
|
||||||
>
|
|
||||||
<MiniButton
|
<MiniButton
|
||||||
|
className='absolute z-tooltip top-[0.25rem] right-0 cc-animate-position'
|
||||||
title='Выгрузить в формате CSV'
|
title='Выгрузить в формате CSV'
|
||||||
icon={<IconCSV size='1.25rem' className='icon-green' />}
|
icon={<IconCSV size='1.25rem' className='icon-green' />}
|
||||||
onClick={handleDownloadCSV}
|
onClick={handleDownloadCSV}
|
||||||
/>
|
/>
|
||||||
</Overlay>
|
|
||||||
<ToolbarSearch total={libraryItems.length} filtered={filtered.length} />
|
|
||||||
|
|
||||||
<div className='cc-fade-in flex'>
|
|
||||||
<ViewSideLocation
|
<ViewSideLocation
|
||||||
isVisible={folderMode}
|
isVisible={folderMode}
|
||||||
onRenameLocation={() => showChangeLocation({ initial: location, onChangeLocation: handleRenameLocation })}
|
onRenameLocation={() => showChangeLocation({ initial: location, onChangeLocation: handleRenameLocation })}
|
||||||
|
|
|
@ -166,7 +166,7 @@ export function ToolbarSearch({ total, filtered }: ToolbarSearchProps) {
|
||||||
text={head ?? '//'}
|
text={head ?? '//'}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Dropdown isOpen={headMenu.isOpen} stretchLeft className='z-modal-tooltip'>
|
<Dropdown isOpen={headMenu.isOpen} stretchLeft>
|
||||||
<DropdownButton title='Переключение в режим Проводник' onClick={handleToggleFolder}>
|
<DropdownButton title='Переключение в режим Проводник' onClick={handleToggleFolder}>
|
||||||
<div className='inline-flex items-center gap-3'>
|
<div className='inline-flex items-center gap-3'>
|
||||||
<IconFolderTree size='1rem' className='clr-text-controls' />
|
<IconFolderTree size='1rem' className='clr-text-controls' />
|
||||||
|
|
|
@ -69,7 +69,7 @@ export function FormOSS() {
|
||||||
disabled={!isMutable}
|
disabled={!isMutable}
|
||||||
error={errors.title}
|
error={errors.title}
|
||||||
/>
|
/>
|
||||||
<div className='flex justify-between gap-3 mb-3'>
|
<div className='relative flex justify-between gap-3 mb-3'>
|
||||||
<TextInput
|
<TextInput
|
||||||
id='schema_alias'
|
id='schema_alias'
|
||||||
{...register('alias')}
|
{...register('alias')}
|
||||||
|
|
|
@ -190,7 +190,7 @@ export function OssFlow() {
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div tabIndex={-1} onKeyDown={handleKeyDown}>
|
<div tabIndex={-1} className='relative' onKeyDown={handleKeyDown}>
|
||||||
<Overlay
|
<Overlay
|
||||||
position='top-[1.9rem] pt-1 right-1/2 translate-x-1/2'
|
position='top-[1.9rem] pt-1 right-1/2 translate-x-1/2'
|
||||||
className='rounded-b-2xl cc-blur hover:bg-prim-100 hover:bg-opacity-50'
|
className='rounded-b-2xl cc-blur hover:bg-prim-100 hover:bg-opacity-50'
|
||||||
|
|
|
@ -23,7 +23,12 @@ export function NodeCore({ node }: NodeCoreProps) {
|
||||||
const longLabel = node.data.label.length > LONG_LABEL_CHARS;
|
const longLabel = node.data.label.length > LONG_LABEL_CHARS;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<div
|
||||||
|
className='relative h-[34px] w-[144px] flex items-center justify-center'
|
||||||
|
data-tooltip-id={globalIDs.operation_tooltip}
|
||||||
|
data-tooltip-hidden={node.dragging}
|
||||||
|
onMouseEnter={() => setHover(node.data.operation)}
|
||||||
|
>
|
||||||
<Overlay position='top-0 right-0' className='flex flex-col gap-1 p-[2px]'>
|
<Overlay position='top-0 right-0' className='flex flex-col gap-1 p-[2px]'>
|
||||||
<Indicator
|
<Indicator
|
||||||
noPadding
|
noPadding
|
||||||
|
@ -40,23 +45,13 @@ export function NodeCore({ node }: NodeCoreProps) {
|
||||||
</Overlay>
|
</Overlay>
|
||||||
|
|
||||||
{node.data.operation.operation_type === OperationType.INPUT ? (
|
{node.data.operation.operation_type === OperationType.INPUT ? (
|
||||||
<Overlay position='top-[1px] right-1/2 translate-x-1/2' className='flex'>
|
<div className='absolute top-[1px] right-1/2 translate-x-1/2 border-t w-[30px]' />
|
||||||
<div className='border-t w-[30px]'></div>
|
|
||||||
</Overlay>
|
|
||||||
) : null}
|
) : null}
|
||||||
|
|
||||||
{!node.data.operation.is_owned ? (
|
{!node.data.operation.is_owned ? (
|
||||||
<Overlay position='left-[2px] top-[6px]'>
|
<div className='absolute left-[2px] top-[6px] border-r rounded-none clr-input h-[22px]' />
|
||||||
<div className='border-r rounded-none clr-input h-[22px]'></div>
|
|
||||||
</Overlay>
|
|
||||||
) : null}
|
) : null}
|
||||||
|
|
||||||
<div
|
|
||||||
className='h-[34px] w-[144px] flex items-center justify-center'
|
|
||||||
data-tooltip-id={globalIDs.operation_tooltip}
|
|
||||||
data-tooltip-hidden={node.dragging}
|
|
||||||
onMouseEnter={() => setHover(node.data.operation)}
|
|
||||||
>
|
|
||||||
<div
|
<div
|
||||||
className='text-center line-clamp-2'
|
className='text-center line-clamp-2'
|
||||||
style={{
|
style={{
|
||||||
|
@ -69,6 +64,5 @@ export function NodeCore({ node }: NodeCoreProps) {
|
||||||
{node.data.label}
|
{node.data.label}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,6 @@ import clsx from 'clsx';
|
||||||
|
|
||||||
import { useConceptNavigation } from '@/app/Navigation/NavigationContext';
|
import { useConceptNavigation } from '@/app/Navigation/NavigationContext';
|
||||||
|
|
||||||
import { Overlay } from '@/components/Container';
|
|
||||||
import { TabLabel, TabList, TabPanel, Tabs } from '@/components/Tabs';
|
import { TabLabel, TabList, TabPanel, Tabs } from '@/components/Tabs';
|
||||||
import { useAppLayoutStore } from '@/stores/appLayout';
|
import { useAppLayoutStore } from '@/stores/appLayout';
|
||||||
|
|
||||||
|
@ -61,16 +60,22 @@ export function OssTabs({ activeTab }: OssTabsProps) {
|
||||||
onSelect={onSelectTab}
|
onSelect={onSelectTab}
|
||||||
defaultFocus
|
defaultFocus
|
||||||
selectedTabClassName='clr-selected'
|
selectedTabClassName='clr-selected'
|
||||||
className='flex flex-col mx-auto min-w-fit items-center'
|
className='relative flex flex-col mx-auto min-w-fit items-center'
|
||||||
|
>
|
||||||
|
<TabList
|
||||||
|
className={clsx(
|
||||||
|
'absolute z-sticky',
|
||||||
|
'top-0 right-1/2 w-fit translate-x-1/2',
|
||||||
|
'flex items-stretch',
|
||||||
|
'border-b-2 border-x-2 divide-x-2',
|
||||||
|
'bg-prim-200'
|
||||||
|
)}
|
||||||
>
|
>
|
||||||
<Overlay position='top-0 right-1/2 translate-x-1/2' layer='z-sticky'>
|
|
||||||
<TabList className={clsx('w-fit', 'flex items-stretch', 'border-b-2 border-x-2 divide-x-2', 'bg-prim-200')}>
|
|
||||||
<MenuOssTabs />
|
<MenuOssTabs />
|
||||||
|
|
||||||
<TabLabel label='Карточка' title={schema.title ?? ''} />
|
<TabLabel label='Карточка' title={schema.title ?? ''} />
|
||||||
<TabLabel label='Граф' />
|
<TabLabel label='Граф' />
|
||||||
</TabList>
|
</TabList>
|
||||||
</Overlay>
|
|
||||||
|
|
||||||
<div className='overflow-x-hidden'>
|
<div className='overflow-x-hidden'>
|
||||||
<TabPanel>
|
<TabPanel>
|
||||||
|
|
|
@ -26,13 +26,10 @@ export function DlgShowAST() {
|
||||||
const [isDragging, setIsDragging] = useState(false);
|
const [isDragging, setIsDragging] = useState(false);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ModalView
|
<ModalView className='relative w-[calc(100dvw-3rem)] h-[calc(100dvh-6rem)]' helpTopic={HelpTopic.UI_FORMULA_TREE}>
|
||||||
className='flex flex-col justify-stretch w-[calc(100dvw-3rem)] h-[calc(100dvh-6rem)]'
|
|
||||||
helpTopic={HelpTopic.UI_FORMULA_TREE}
|
|
||||||
>
|
|
||||||
<Overlay
|
<Overlay
|
||||||
position='top-2 right-1/2 translate-x-1/2'
|
position='top-0 -mt-1 right-1/2 translate-x-1/2'
|
||||||
className='px-2 py-1 rounded-2xl cc-blur bg-prim-100 max-w-[60ch] text-lg text-center'
|
className='px-2 rounded-2xl cc-blur bg-prim-100 max-w-[60ch] text-lg text-center'
|
||||||
>
|
>
|
||||||
{!hoverNode || isDragging ? expression : null}
|
{!hoverNode || isDragging ? expression : null}
|
||||||
{!isDragging && hoverNode ? (
|
{!isDragging && hoverNode ? (
|
||||||
|
@ -43,6 +40,7 @@ export function DlgShowAST() {
|
||||||
</div>
|
</div>
|
||||||
) : null}
|
) : null}
|
||||||
</Overlay>
|
</Overlay>
|
||||||
|
|
||||||
<ReactFlowProvider>
|
<ReactFlowProvider>
|
||||||
<ASTFlow
|
<ASTFlow
|
||||||
data={syntaxTree}
|
data={syntaxTree}
|
||||||
|
|
|
@ -5,17 +5,14 @@ import clsx from 'clsx';
|
||||||
|
|
||||||
import { useWindowSize } from '@/hooks/useWindowSize';
|
import { useWindowSize } from '@/hooks/useWindowSize';
|
||||||
import { useMainHeight } from '@/stores/appLayout';
|
import { useMainHeight } from '@/stores/appLayout';
|
||||||
import { useDialogsStore } from '@/stores/dialogs';
|
|
||||||
import { useModificationStore } from '@/stores/modification';
|
import { useModificationStore } from '@/stores/modification';
|
||||||
import { usePreferencesStore } from '@/stores/preferences';
|
import { usePreferencesStore } from '@/stores/preferences';
|
||||||
import { globalIDs } from '@/utils/constants';
|
import { globalIDs } from '@/utils/constants';
|
||||||
import { promptUnsaved } from '@/utils/utils';
|
|
||||||
|
|
||||||
import { useMutatingRSForm } from '../../../backend/useMutatingRSForm';
|
import { useMutatingRSForm } from '../../../backend/useMutatingRSForm';
|
||||||
import { useRSEdit } from '../RSEditContext';
|
import { useRSEdit } from '../RSEditContext';
|
||||||
import { ViewConstituents } from '../ViewConstituents';
|
import { ViewConstituents } from '../ViewConstituents';
|
||||||
|
|
||||||
import { EditorControls } from './EditorControls';
|
|
||||||
import { FormConstituenta } from './FormConstituenta';
|
import { FormConstituenta } from './FormConstituenta';
|
||||||
import { ToolbarConstituenta } from './ToolbarConstituenta';
|
import { ToolbarConstituenta } from './ToolbarConstituenta';
|
||||||
|
|
||||||
|
@ -28,7 +25,6 @@ export function EditorConstituenta() {
|
||||||
const mainHeight = useMainHeight();
|
const mainHeight = useMainHeight();
|
||||||
|
|
||||||
const showList = usePreferencesStore(state => state.showCstSideList);
|
const showList = usePreferencesStore(state => state.showCstSideList);
|
||||||
const showEditTerm = useDialogsStore(state => state.showEditWordForms);
|
|
||||||
const { isModified } = useModificationStore();
|
const { isModified } = useModificationStore();
|
||||||
|
|
||||||
const [toggleReset, setToggleReset] = useState(false);
|
const [toggleReset, setToggleReset] = useState(false);
|
||||||
|
@ -57,16 +53,6 @@ export function EditorConstituenta() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleEditTermForms() {
|
|
||||||
if (!activeCst) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (isModified && !promptUnsaved()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
showEditTerm({ itemID: schema.id, target: activeCst });
|
|
||||||
}
|
|
||||||
|
|
||||||
function initiateSubmit() {
|
function initiateSubmit() {
|
||||||
const element = document.getElementById(globalIDs.constituenta_editor) as HTMLFormElement;
|
const element = document.getElementById(globalIDs.constituenta_editor) as HTMLFormElement;
|
||||||
if (element) {
|
if (element) {
|
||||||
|
@ -85,16 +71,10 @@ export function EditorConstituenta() {
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
|
||||||
<ToolbarConstituenta
|
|
||||||
activeCst={activeCst}
|
|
||||||
disabled={disabled}
|
|
||||||
onSubmit={initiateSubmit}
|
|
||||||
onReset={() => setToggleReset(prev => !prev)}
|
|
||||||
/>
|
|
||||||
<div
|
<div
|
||||||
tabIndex={-1}
|
tabIndex={-1}
|
||||||
className={clsx(
|
className={clsx(
|
||||||
|
'relative',
|
||||||
'cc-fade-in',
|
'cc-fade-in',
|
||||||
'min-h-[20rem] max-w-[calc(min(100vw,95rem))] mx-auto',
|
'min-h-[20rem] max-w-[calc(min(100vw,95rem))] mx-auto',
|
||||||
'flex pt-[1.9rem]',
|
'flex pt-[1.9rem]',
|
||||||
|
@ -104,17 +84,16 @@ export function EditorConstituenta() {
|
||||||
style={{ maxHeight: mainHeight }}
|
style={{ maxHeight: mainHeight }}
|
||||||
onKeyDown={handleInput}
|
onKeyDown={handleInput}
|
||||||
>
|
>
|
||||||
|
<ToolbarConstituenta
|
||||||
|
activeCst={activeCst}
|
||||||
|
disabled={disabled}
|
||||||
|
onSubmit={initiateSubmit}
|
||||||
|
onReset={() => setToggleReset(prev => !prev)}
|
||||||
|
/>
|
||||||
<div className='mx-0 md:mx-auto pt-[2rem] md:w-[48.8rem] shrink-0 xs:pt-0'>
|
<div className='mx-0 md:mx-auto pt-[2rem] md:w-[48.8rem] shrink-0 xs:pt-0'>
|
||||||
{activeCst ? (
|
|
||||||
<EditorControls
|
|
||||||
disabled={disabled} //
|
|
||||||
constituenta={activeCst}
|
|
||||||
onEditTerm={handleEditTermForms}
|
|
||||||
/>
|
|
||||||
) : null}
|
|
||||||
{activeCst ? (
|
{activeCst ? (
|
||||||
<FormConstituenta
|
<FormConstituenta
|
||||||
id={globalIDs.constituenta_editor} //
|
id={globalIDs.constituenta_editor}
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
toggleReset={toggleReset}
|
toggleReset={toggleReset}
|
||||||
activeCst={activeCst}
|
activeCst={activeCst}
|
||||||
|
@ -125,6 +104,5 @@ export function EditorConstituenta() {
|
||||||
</div>
|
</div>
|
||||||
<ViewConstituents isMounted={showList} isBottom={isNarrow} />
|
<ViewConstituents isMounted={showList} isBottom={isNarrow} />
|
||||||
</div>
|
</div>
|
||||||
</>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,7 +29,7 @@ export function EditorControls({ constituenta, disabled, onEditTerm }: EditorCon
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Overlay position='top-1 left-[4.7rem]' className='flex select-none'>
|
<Overlay position='top-0 left-[4.7rem]' className='flex select-none'>
|
||||||
{!disabled || isProcessing ? (
|
{!disabled || isProcessing ? (
|
||||||
<MiniButton
|
<MiniButton
|
||||||
title={isModified ? tooltipText.unsaved : `Редактировать словоформы термина`}
|
title={isModified ? tooltipText.unsaved : `Редактировать словоформы термина`}
|
||||||
|
|
|
@ -14,6 +14,7 @@ import { Indicator } from '@/components/View';
|
||||||
import { useDialogsStore } from '@/stores/dialogs';
|
import { useDialogsStore } from '@/stores/dialogs';
|
||||||
import { useModificationStore } from '@/stores/modification';
|
import { useModificationStore } from '@/stores/modification';
|
||||||
import { errorMsg } from '@/utils/labels';
|
import { errorMsg } from '@/utils/labels';
|
||||||
|
import { promptUnsaved } from '@/utils/utils';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
CstType,
|
CstType,
|
||||||
|
@ -30,6 +31,8 @@ import { type IConstituenta, type IRSForm } from '../../../models/rsform';
|
||||||
import { isBaseSet, isBasicConcept, isFunctional } from '../../../models/rsformAPI';
|
import { isBaseSet, isBasicConcept, isFunctional } from '../../../models/rsformAPI';
|
||||||
import { EditorRSExpression } from '../EditorRSExpression';
|
import { EditorRSExpression } from '../EditorRSExpression';
|
||||||
|
|
||||||
|
import { EditorControls } from './EditorControls';
|
||||||
|
|
||||||
interface FormConstituentaProps {
|
interface FormConstituentaProps {
|
||||||
id?: string;
|
id?: string;
|
||||||
disabled: boolean;
|
disabled: boolean;
|
||||||
|
@ -41,8 +44,6 @@ interface FormConstituentaProps {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function FormConstituenta({ disabled, id, toggleReset, schema, activeCst, onOpenEdit }: FormConstituentaProps) {
|
export function FormConstituenta({ disabled, id, toggleReset, schema, activeCst, onOpenEdit }: FormConstituentaProps) {
|
||||||
const { cstUpdate } = useCstUpdate();
|
|
||||||
const showTypification = useDialogsStore(state => state.showShowTypeGraph);
|
|
||||||
const { isModified, setIsModified } = useModificationStore();
|
const { isModified, setIsModified } = useModificationStore();
|
||||||
const isProcessing = useMutatingRSForm();
|
const isProcessing = useMutatingRSForm();
|
||||||
|
|
||||||
|
@ -54,6 +55,10 @@ export function FormConstituenta({ disabled, id, toggleReset, schema, activeCst,
|
||||||
formState: { isDirty }
|
formState: { isDirty }
|
||||||
} = useForm<ICstUpdateDTO>({ resolver: zodResolver(schemaCstUpdate) });
|
} = useForm<ICstUpdateDTO>({ resolver: zodResolver(schemaCstUpdate) });
|
||||||
|
|
||||||
|
const { cstUpdate } = useCstUpdate();
|
||||||
|
const showTypification = useDialogsStore(state => state.showShowTypeGraph);
|
||||||
|
const showEditTerm = useDialogsStore(state => state.showEditWordForms);
|
||||||
|
|
||||||
const [localParse, setLocalParse] = useState<IExpressionParseDTO | null>(null);
|
const [localParse, setLocalParse] = useState<IExpressionParseDTO | null>(null);
|
||||||
|
|
||||||
const typification = useMemo(
|
const typification = useMemo(
|
||||||
|
@ -115,8 +120,20 @@ export function FormConstituenta({ disabled, id, toggleReset, schema, activeCst,
|
||||||
showTypification({ items: typeInfo ? [typeInfo] : [] });
|
showTypification({ items: typeInfo ? [typeInfo] : [] });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function handleEditTermForms() {
|
||||||
|
if (!activeCst) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (isModified && !promptUnsaved()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
showEditTerm({ itemID: schema.id, target: activeCst });
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<form id={id} className='cc-column mt-1 px-6 py-1' onSubmit={event => void handleSubmit(onSubmit)(event)}>
|
<form id={id} className='relative cc-column mt-1 px-6 py-1' onSubmit={event => void handleSubmit(onSubmit)(event)}>
|
||||||
|
<EditorControls disabled={disabled} constituenta={activeCst} onEditTerm={handleEditTermForms} />
|
||||||
|
|
||||||
<Controller
|
<Controller
|
||||||
control={control}
|
control={control}
|
||||||
name='item_data.term_raw'
|
name='item_data.term_raw'
|
||||||
|
@ -228,13 +245,13 @@ export function FormConstituenta({ disabled, id, toggleReset, schema, activeCst,
|
||||||
) : null}
|
) : null}
|
||||||
|
|
||||||
{!disabled || isProcessing ? (
|
{!disabled || isProcessing ? (
|
||||||
<div className='mx-auto flex'>
|
<div className='relative mx-auto flex'>
|
||||||
<SubmitButton
|
<SubmitButton
|
||||||
text='Сохранить изменения'
|
text='Сохранить изменения'
|
||||||
disabled={disabled || !isModified}
|
disabled={disabled || !isModified}
|
||||||
icon={<IconSave size='1.25rem' />}
|
icon={<IconSave size='1.25rem' />}
|
||||||
/>
|
/>
|
||||||
<Overlay position='top-[0.1rem] left-[0.4rem]' className='cc-icons'>
|
<Overlay position='top-[0.1rem] left-full' className='cc-icons'>
|
||||||
{activeCst.has_inherited_children && !activeCst.is_inherited ? (
|
{activeCst.has_inherited_children && !activeCst.is_inherited ? (
|
||||||
<Indicator
|
<Indicator
|
||||||
icon={<IconPredecessor size='1.25rem' className='text-sec-600' />}
|
icon={<IconPredecessor size='1.25rem' className='text-sec-600' />}
|
||||||
|
|
|
@ -4,10 +4,6 @@ import { useEffect, useRef, useState } from 'react';
|
||||||
import { toast } from 'react-toastify';
|
import { toast } from 'react-toastify';
|
||||||
import { type ReactCodeMirrorRef } from '@uiw/react-codemirror';
|
import { type ReactCodeMirrorRef } from '@uiw/react-codemirror';
|
||||||
|
|
||||||
import { HelpTopic } from '@/features/help';
|
|
||||||
import { BadgeHelp } from '@/features/help/components';
|
|
||||||
|
|
||||||
import { Overlay } from '@/components/Container';
|
|
||||||
import { useDialogsStore } from '@/stores/dialogs';
|
import { useDialogsStore } from '@/stores/dialogs';
|
||||||
import { usePreferencesStore } from '@/stores/preferences';
|
import { usePreferencesStore } from '@/stores/preferences';
|
||||||
import { errorMsg } from '@/utils/labels';
|
import { errorMsg } from '@/utils/labels';
|
||||||
|
@ -158,14 +154,9 @@ export function EditorRSExpression({
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='cc-fade-in'>
|
<div className='relative cc-fade-in'>
|
||||||
<ToolbarRSExpression disabled={disabled} showAST={handleShowAST} showTypeGraph={onShowTypeGraph} />
|
<ToolbarRSExpression disabled={disabled} showAST={handleShowAST} showTypeGraph={onShowTypeGraph} />
|
||||||
|
|
||||||
<Overlay
|
|
||||||
position='top-[-0.5rem] right-1/2 translate-x-1/2'
|
|
||||||
layer='z-pop'
|
|
||||||
className='w-fit pl-[8.5rem] xs:pl-[2rem] flex gap-1'
|
|
||||||
>
|
|
||||||
<StatusBar
|
<StatusBar
|
||||||
processing={isPending}
|
processing={isPending}
|
||||||
isModified={isModified}
|
isModified={isModified}
|
||||||
|
@ -173,8 +164,6 @@ export function EditorRSExpression({
|
||||||
parseData={parseData}
|
parseData={parseData}
|
||||||
onAnalyze={() => handleCheckExpression()}
|
onAnalyze={() => handleCheckExpression()}
|
||||||
/>
|
/>
|
||||||
<BadgeHelp topic={HelpTopic.UI_CST_STATUS} offset={4} />
|
|
||||||
</Overlay>
|
|
||||||
|
|
||||||
<RSInput
|
<RSInput
|
||||||
ref={rsInput}
|
ref={rsInput}
|
||||||
|
|
|
@ -2,6 +2,10 @@
|
||||||
|
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
|
|
||||||
|
import { HelpTopic } from '@/features/help';
|
||||||
|
import { BadgeHelp } from '@/features/help/components';
|
||||||
|
|
||||||
|
import { Overlay } from '@/components/Container';
|
||||||
import { Loader } from '@/components/Loader';
|
import { Loader } from '@/components/Loader';
|
||||||
import { APP_COLORS } from '@/styling/colors';
|
import { APP_COLORS } from '@/styling/colors';
|
||||||
import { globalIDs } from '@/utils/constants';
|
import { globalIDs } from '@/utils/constants';
|
||||||
|
@ -35,6 +39,11 @@ export function StatusBar({ isModified, processing, activeCst, parseData, onAnal
|
||||||
})();
|
})();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
<Overlay
|
||||||
|
position='top-[-0.5rem] right-1/2 translate-x-1/2'
|
||||||
|
layer='z-pop'
|
||||||
|
className='w-fit pl-[8.5rem] xs:pl-[2rem] flex gap-1'
|
||||||
|
>
|
||||||
<div
|
<div
|
||||||
tabIndex={0}
|
tabIndex={0}
|
||||||
className={clsx(
|
className={clsx(
|
||||||
|
@ -43,7 +52,7 @@ export function StatusBar({ isModified, processing, activeCst, parseData, onAnal
|
||||||
'border',
|
'border',
|
||||||
'select-none',
|
'select-none',
|
||||||
'cursor-pointer',
|
'cursor-pointer',
|
||||||
'focus-frame',
|
'focus-frame outline-none',
|
||||||
'transition-colors duration-500'
|
'transition-colors duration-500'
|
||||||
)}
|
)}
|
||||||
style={{ backgroundColor: processing ? APP_COLORS.bgDefault : colorStatusBar(status) }}
|
style={{ backgroundColor: processing ? APP_COLORS.bgDefault : colorStatusBar(status) }}
|
||||||
|
@ -53,7 +62,6 @@ export function StatusBar({ isModified, processing, activeCst, parseData, onAnal
|
||||||
>
|
>
|
||||||
{processing ? (
|
{processing ? (
|
||||||
<div className='cc-fade-in'>
|
<div className='cc-fade-in'>
|
||||||
{' '}
|
|
||||||
<Loader scale={3} />
|
<Loader scale={3} />
|
||||||
</div>
|
</div>
|
||||||
) : null}
|
) : null}
|
||||||
|
@ -64,5 +72,7 @@ export function StatusBar({ isModified, processing, activeCst, parseData, onAnal
|
||||||
</div>
|
</div>
|
||||||
) : null}
|
) : null}
|
||||||
</div>
|
</div>
|
||||||
|
<BadgeHelp topic={HelpTopic.UI_CST_STATUS} offset={4} />
|
||||||
|
</Overlay>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,16 +35,17 @@ export function EditorRSFormCard() {
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
|
||||||
<ToolbarRSFormCard onSubmit={initiateSubmit} schema={schema} isMutable={isMutable} deleteSchema={deleteSchema} />
|
|
||||||
<div
|
<div
|
||||||
onKeyDown={handleInput}
|
onKeyDown={handleInput}
|
||||||
className={clsx(
|
className={clsx(
|
||||||
|
'relative',
|
||||||
'cc-fade-in',
|
'cc-fade-in',
|
||||||
'md:w-fit md:max-w-fit max-w-[32rem]',
|
'md:w-fit md:max-w-fit max-w-[32rem]',
|
||||||
'flex flex-row flex-wrap px-6 pt-[1.9rem]'
|
'flex flex-row flex-wrap px-6 pt-[1.9rem]'
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
|
<ToolbarRSFormCard onSubmit={initiateSubmit} schema={schema} isMutable={isMutable} deleteSchema={deleteSchema} />
|
||||||
|
|
||||||
<FlexColumn className='shrink'>
|
<FlexColumn className='shrink'>
|
||||||
<FormRSForm />
|
<FormRSForm />
|
||||||
<EditorLibraryItem schema={schema} isAttachedToOSS={isAttachedToOSS} />
|
<EditorLibraryItem schema={schema} isAttachedToOSS={isAttachedToOSS} />
|
||||||
|
@ -52,6 +53,5 @@ export function EditorRSFormCard() {
|
||||||
|
|
||||||
<RSFormStats stats={schema.stats} isArchive={isArchive} />
|
<RSFormStats stats={schema.stats} isArchive={isArchive} />
|
||||||
</div>
|
</div>
|
||||||
</>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -91,7 +91,7 @@ export function FormRSForm() {
|
||||||
disabled={!isContentEditable}
|
disabled={!isContentEditable}
|
||||||
error={errors.alias}
|
error={errors.alias}
|
||||||
/>
|
/>
|
||||||
<div className='flex flex-col'>
|
<div className='relative flex flex-col'>
|
||||||
<ToolbarVersioning blockReload={schema.oss.length > 0} />
|
<ToolbarVersioning blockReload={schema.oss.length > 0} />
|
||||||
<ToolbarItemAccess
|
<ToolbarItemAccess
|
||||||
visible={visible}
|
visible={visible}
|
||||||
|
|
|
@ -4,7 +4,6 @@ import { useState } from 'react';
|
||||||
import { toast } from 'react-toastify';
|
import { toast } from 'react-toastify';
|
||||||
import fileDownload from 'js-file-download';
|
import fileDownload from 'js-file-download';
|
||||||
|
|
||||||
import { Overlay } from '@/components/Container';
|
|
||||||
import { MiniButton } from '@/components/Control';
|
import { MiniButton } from '@/components/Control';
|
||||||
import { type RowSelectionState } from '@/components/DataTable';
|
import { type RowSelectionState } from '@/components/DataTable';
|
||||||
import { IconCSV } from '@/components/Icons';
|
import { IconCSV } from '@/components/Icons';
|
||||||
|
@ -127,9 +126,16 @@ export function EditorRSList() {
|
||||||
const tableHeight = useFitHeight('4.05rem + 5px');
|
const tableHeight = useFitHeight('4.05rem + 5px');
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<div tabIndex={-1} onKeyDown={handleKeyDown} className='relative cc-fade-in pt-[1.9rem]'>
|
||||||
{isContentEditable ? <ToolbarRSList /> : null}
|
{isContentEditable ? <ToolbarRSList /> : null}
|
||||||
<div tabIndex={-1} onKeyDown={handleKeyDown} className='cc-fade-in pt-[1.9rem]'>
|
|
||||||
|
<MiniButton
|
||||||
|
className='absolute z-tooltip top-[2.15rem] right-[1rem]'
|
||||||
|
title='Выгрузить в формате CSV'
|
||||||
|
icon={<IconCSV size='1.25rem' className='icon-green' />}
|
||||||
|
onClick={handleDownloadCSV}
|
||||||
|
/>
|
||||||
|
|
||||||
{isContentEditable ? (
|
{isContentEditable ? (
|
||||||
<div className='flex items-center border-b'>
|
<div className='flex items-center border-b'>
|
||||||
<div className='px-2'>
|
<div className='px-2'>
|
||||||
|
@ -145,14 +151,6 @@ export function EditorRSList() {
|
||||||
</div>
|
</div>
|
||||||
) : null}
|
) : null}
|
||||||
|
|
||||||
<Overlay position='top-[0.25rem] right-[1rem]' layer='z-tooltip'>
|
|
||||||
<MiniButton
|
|
||||||
title='Выгрузить в формате CSV'
|
|
||||||
icon={<IconCSV size='1.25rem' className='icon-green' />}
|
|
||||||
onClick={handleDownloadCSV}
|
|
||||||
/>
|
|
||||||
</Overlay>
|
|
||||||
|
|
||||||
<TableRSList
|
<TableRSList
|
||||||
items={filtered}
|
items={filtered}
|
||||||
maxHeight={tableHeight}
|
maxHeight={tableHeight}
|
||||||
|
@ -163,6 +161,5 @@ export function EditorRSList() {
|
||||||
onCreateNew={createCstDefault}
|
onCreateNew={createCstDefault}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,7 @@ export function GraphSelectors() {
|
||||||
const setColoring = useTermGraphStore(state => state.setColoring);
|
const setColoring = useTermGraphStore(state => state.setColoring);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='border rounded-b-none select-none clr-input rounded-t-md pointer-events-auto'>
|
<div className='relative border rounded-b-none select-none clr-input rounded-t-md pointer-events-auto'>
|
||||||
<Overlay position='right-[2.5rem] top-[0.25rem]'>
|
<Overlay position='right-[2.5rem] top-[0.25rem]'>
|
||||||
{coloring === 'status' ? <BadgeHelp topic={HelpTopic.UI_CST_STATUS} className='min-w-[25rem]' /> : null}
|
{coloring === 'status' ? <BadgeHelp topic={HelpTopic.UI_CST_STATUS} className='min-w-[25rem]' /> : null}
|
||||||
{coloring === 'type' ? <BadgeHelp topic={HelpTopic.UI_CST_CLASS} className='min-w-[25rem]' /> : null}
|
{coloring === 'type' ? <BadgeHelp topic={HelpTopic.UI_CST_CLASS} className='min-w-[25rem]' /> : null}
|
||||||
|
|
|
@ -40,7 +40,6 @@ export function SchemasGuide() {
|
||||||
<IconHelp size='1.25rem' className='icon-primary' />
|
<IconHelp size='1.25rem' className='icon-primary' />
|
||||||
<Tooltip
|
<Tooltip
|
||||||
anchorSelect={`#${globalIDs.graph_schemas}`}
|
anchorSelect={`#${globalIDs.graph_schemas}`}
|
||||||
layer='z-modal-tooltip'
|
|
||||||
place='right'
|
place='right'
|
||||||
className='max-w-[25rem] break-words text-base'
|
className='max-w-[25rem] break-words text-base'
|
||||||
>
|
>
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
|
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
|
|
||||||
import { Overlay } from '@/components/Container';
|
|
||||||
import { MiniButton } from '@/components/Control';
|
import { MiniButton } from '@/components/Control';
|
||||||
import { IconDropArrow, IconDropArrowUp } from '@/components/Icons';
|
import { IconDropArrow, IconDropArrowUp } from '@/components/Icons';
|
||||||
import { useWindowSize } from '@/hooks/useWindowSize';
|
import { useWindowSize } from '@/hooks/useWindowSize';
|
||||||
|
@ -47,16 +46,16 @@ export function ViewHidden({ items }: ViewHiddenProps) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<div className='flex flex-col'>
|
<div className='flex flex-col relative'>
|
||||||
<Overlay position='right-[calc(0.7rem-2px)] top-2 pointer-events-auto'>
|
|
||||||
<MiniButton
|
<MiniButton
|
||||||
|
className='absolute right-[calc(0.7rem-2px)] top-2 pointer-events-auto'
|
||||||
noPadding
|
noPadding
|
||||||
noHover
|
noHover
|
||||||
title={!isFolded ? 'Свернуть' : 'Развернуть'}
|
title={!isFolded ? 'Свернуть' : 'Развернуть'}
|
||||||
icon={!isFolded ? <IconDropArrowUp size='1.25rem' /> : <IconDropArrow size='1.25rem' />}
|
icon={!isFolded ? <IconDropArrowUp size='1.25rem' /> : <IconDropArrow size='1.25rem' />}
|
||||||
onClick={toggleFolded}
|
onClick={toggleFolded}
|
||||||
/>
|
/>
|
||||||
</Overlay>
|
|
||||||
<div className={clsx('pt-2 clr-input border-x pb-2', { 'border-b rounded-b-md': isFolded })}>
|
<div className={clsx('pt-2 clr-input border-x pb-2', { 'border-b rounded-b-md': isFolded })}>
|
||||||
<div
|
<div
|
||||||
className='w-fit select-none'
|
className='w-fit select-none'
|
||||||
|
|
|
@ -5,7 +5,6 @@ import clsx from 'clsx';
|
||||||
|
|
||||||
import { useConceptNavigation } from '@/app/Navigation/NavigationContext';
|
import { useConceptNavigation } from '@/app/Navigation/NavigationContext';
|
||||||
|
|
||||||
import { Overlay } from '@/components/Container';
|
|
||||||
import { TabLabel, TabList, TabPanel, Tabs } from '@/components/Tabs';
|
import { TabLabel, TabList, TabPanel, Tabs } from '@/components/Tabs';
|
||||||
import { useAppLayoutStore } from '@/stores/appLayout';
|
import { useAppLayoutStore } from '@/stores/appLayout';
|
||||||
import { useModificationStore } from '@/stores/modification';
|
import { useModificationStore } from '@/stores/modification';
|
||||||
|
@ -72,17 +71,21 @@ export function RSTabs({ activeID, activeTab }: RSTabsProps) {
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
|
||||||
<Tabs
|
<Tabs
|
||||||
selectedIndex={activeTab}
|
selectedIndex={activeTab}
|
||||||
onSelect={onSelectTab}
|
onSelect={onSelectTab}
|
||||||
defaultFocus
|
defaultFocus
|
||||||
selectedTabClassName='clr-selected'
|
selectedTabClassName='clr-selected'
|
||||||
className='flex flex-col mx-auto min-w-fit items-center'
|
className='relative flex flex-col mx-auto min-w-fit items-center'
|
||||||
>
|
>
|
||||||
<Overlay position='top-0 right-1/2 translate-x-1/2' layer='z-sticky'>
|
|
||||||
<TabList
|
<TabList
|
||||||
className={clsx('mx-auto w-fit', 'flex items-stretch', 'border-b-2 border-x-2 divide-x-2', 'bg-prim-200')}
|
className={clsx(
|
||||||
|
'absolute z-sticky',
|
||||||
|
'mx-auto w-fit top-0 right-1/2 translate-x-1/2',
|
||||||
|
'flex items-stretch',
|
||||||
|
'border-b-2 border-x-2 divide-x-2',
|
||||||
|
'bg-prim-200'
|
||||||
|
)}
|
||||||
>
|
>
|
||||||
<MenuRSTabs />
|
<MenuRSTabs />
|
||||||
|
|
||||||
|
@ -97,7 +100,6 @@ export function RSTabs({ activeID, activeTab }: RSTabsProps) {
|
||||||
<TabLabel label='Редактор' />
|
<TabLabel label='Редактор' />
|
||||||
<TabLabel label='Граф термов' />
|
<TabLabel label='Граф термов' />
|
||||||
</TabList>
|
</TabList>
|
||||||
</Overlay>
|
|
||||||
|
|
||||||
<div className='overflow-x-hidden'>
|
<div className='overflow-x-hidden'>
|
||||||
<TabPanel>
|
<TabPanel>
|
||||||
|
@ -117,6 +119,5 @@ export function RSTabs({ activeID, activeTab }: RSTabsProps) {
|
||||||
</TabPanel>
|
</TabPanel>
|
||||||
</div>
|
</div>
|
||||||
</Tabs>
|
</Tabs>
|
||||||
</>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@ import { urls, useConceptNavigation } from '@/app';
|
||||||
import { HelpTopic } from '@/features/help';
|
import { HelpTopic } from '@/features/help';
|
||||||
|
|
||||||
import { isAxiosError } from '@/backend/apiTransport';
|
import { isAxiosError } from '@/backend/apiTransport';
|
||||||
import { FlexColumn, Overlay, Tooltip } from '@/components/Container';
|
import { FlexColumn, Tooltip } from '@/components/Container';
|
||||||
import { Button, SubmitButton, TextURL } from '@/components/Control';
|
import { Button, SubmitButton, TextURL } from '@/components/Control';
|
||||||
import { IconHelp } from '@/components/Icons';
|
import { IconHelp } from '@/components/Icons';
|
||||||
import { type ErrorData } from '@/components/InfoError';
|
import { type ErrorData } from '@/components/InfoError';
|
||||||
|
@ -60,15 +60,7 @@ export function FormSignup() {
|
||||||
onSubmit={event => void handleSubmit(onSubmit)(event)}
|
onSubmit={event => void handleSubmit(onSubmit)(event)}
|
||||||
onChange={resetErrors}
|
onChange={resetErrors}
|
||||||
>
|
>
|
||||||
<h1>
|
<h1>Новый пользователь</h1>
|
||||||
<span>Новый пользователь</span>
|
|
||||||
<Overlay id={globalIDs.email_tooltip} position='top-[0.5rem] right-[1.75rem]'>
|
|
||||||
<IconHelp size='1.25rem' className='icon-primary' />
|
|
||||||
</Overlay>
|
|
||||||
<Tooltip anchorSelect={`#${globalIDs.email_tooltip}`} offset={6}>
|
|
||||||
электронная почта используется для восстановления пароля
|
|
||||||
</Tooltip>
|
|
||||||
</h1>
|
|
||||||
<div className='flex gap-12'>
|
<div className='flex gap-12'>
|
||||||
<FlexColumn>
|
<FlexColumn>
|
||||||
<TextInput
|
<TextInput
|
||||||
|
@ -102,7 +94,11 @@ export function FormSignup() {
|
||||||
/>
|
/>
|
||||||
</FlexColumn>
|
</FlexColumn>
|
||||||
|
|
||||||
<FlexColumn className='w-[15rem]'>
|
<FlexColumn className='w-[15rem] relative'>
|
||||||
|
<IconHelp id={globalIDs.email_tooltip} className='absolute top-0 right-0 icon-primary' size='1.25rem' />
|
||||||
|
<Tooltip anchorSelect={`#${globalIDs.email_tooltip}`} offset={6}>
|
||||||
|
электронная почта используется для восстановления пароля
|
||||||
|
</Tooltip>
|
||||||
<TextInput
|
<TextInput
|
||||||
id='email'
|
id='email'
|
||||||
{...register('email')}
|
{...register('email')}
|
||||||
|
|
|
@ -42,8 +42,6 @@
|
||||||
--z-index-tooltip: 30;
|
--z-index-tooltip: 30;
|
||||||
--z-index-navigation: 50;
|
--z-index-navigation: 50;
|
||||||
--z-index-modal: 60;
|
--z-index-modal: 60;
|
||||||
--z-index-modal-controls: 70;
|
|
||||||
--z-index-modal-tooltip: 90;
|
|
||||||
|
|
||||||
--breakpoint-*: initial;
|
--breakpoint-*: initial;
|
||||||
--breakpoint-xs: 475px;
|
--breakpoint-xs: 475px;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user