R: Remove redundant containers
Some checks failed
Frontend CI / build (22.x) (push) Has been cancelled

This commit is contained in:
Ivan 2025-03-07 22:05:12 +03:00
parent 81fa0c5796
commit 2ad5fd4c39
38 changed files with 182 additions and 254 deletions

View File

@ -1,13 +0,0 @@
import clsx from 'clsx';
/**
* `flex` column container.
* This component is useful for creating vertical layouts with flexbox.
*/
export function FlexColumn({ className, children, ...restProps }: React.ComponentProps<'div'>) {
return (
<div className={clsx('cc-column', className)} {...restProps}>
{children}
</div>
);
}

View File

@ -1,32 +0,0 @@
import clsx from 'clsx';
import { type Styling } from '../props';
interface OverlayProps extends Styling {
/** Id of the overlay. */
id?: string;
/** Classnames for position of the overlay. */
position?: string;
/** Classname for z-index of the overlay. */
layer?: string;
}
/**
* Displays a transparent overlay over the main content.
* Note: Overlay should be inside a relative container.
*/
export function Overlay({
children,
className,
position = 'top-0 right-0',
layer = 'z-pop',
...restProps
}: React.PropsWithChildren<OverlayProps>) {
return (
<div className={clsx('absolute', className, position, layer)} {...restProps}>
{children}
</div>
);
}

View File

@ -1,4 +1,2 @@
export { Divider } from './Divider';
export { FlexColumn } from './FlexColumn';
export { Overlay } from './Overlay';
export { type PlacesType, Tooltip } from './Tooltip';

View File

@ -39,18 +39,17 @@ export function Dropdown({
<div
tabIndex={-1}
className={clsx(
'z-topmost',
'absolute',
'flex flex-col',
'border rounded-md shadow-lg',
'text-sm',
'clr-input',
'z-topmost absolute',
{
'right-0': stretchLeft,
'left-0': !stretchLeft,
'bottom-0': stretchTop,
'top-full': !stretchTop
},
'grid',
'border rounded-md shadow-lg',
'clr-input',
'text-sm',
margin,
className
)}

View File

@ -7,7 +7,6 @@ import { BadgeHelp } from '@/features/help/components';
import { useEscapeKey } from '@/hooks/useEscapeKey';
import { useDialogsStore } from '@/stores/dialogs';
import { PARAMETER } from '@/utils/constants';
import { prepareTooltip } from '@/utils/utils';
import { Button, MiniButton, SubmitButton } from '../Control';
@ -99,9 +98,12 @@ export function ModalForm({
onSubmit={handleSubmit}
>
{helpTopic && !hideHelpWhen?.() ? (
<div className='float-left mt-2 ml-2'>
<BadgeHelp topic={helpTopic} className={clsx(PARAMETER.TOOLTIP_WIDTH, 'sm:max-w-[40rem]')} padding='p-0' />
</div>
<BadgeHelp
topic={helpTopic} //
className='float-left mt-2 ml-2'
padding='p-0'
contentClass='sm:max-w-[40rem]'
/>
) : null}
<MiniButton

View File

@ -6,7 +6,6 @@ import { BadgeHelp } from '@/features/help/components';
import { useEscapeKey } from '@/hooks/useEscapeKey';
import { useDialogsStore } from '@/stores/dialogs';
import { PARAMETER } from '@/utils/constants';
import { prepareTooltip } from '@/utils/utils';
import { Button, MiniButton } from '../Control';
@ -43,9 +42,7 @@ export function ModalView({
)}
>
{helpTopic && !hideHelpWhen?.() ? (
<div className='float-left mt-2 ml-2'>
<BadgeHelp topic={helpTopic} className={clsx(PARAMETER.TOOLTIP_WIDTH, 'sm:max-w-[40rem]')} padding='p-0' />
</div>
<BadgeHelp topic={helpTopic} className='float-left mt-2 ml-2' padding='p-0' contentClass='sm:max-w-[40rem]' />
) : null}
<MiniButton

View File

@ -1,4 +1,5 @@
import React, { Suspense } from 'react';
import clsx from 'clsx';
import { type PlacesType, Tooltip } from '@/components/Container';
import { TextURL } from '@/components/Control';
@ -6,6 +7,7 @@ import { IconHelp } from '@/components/Icons';
import { Loader } from '@/components/Loader';
import { type Styling } from '@/components/props';
import { usePreferencesStore } from '@/stores/preferences';
import { PARAMETER } from '@/utils/constants';
import { type HelpTopic } from '../models/helpTopic';
@ -25,21 +27,30 @@ interface BadgeHelpProps extends Styling {
/** Place of the tooltip in relation to the cursor. */
place?: PlacesType;
/** Classname for content wrapper. */
contentClass?: string;
}
/**
* Display help icon with a manual page tooltip.
*/
export function BadgeHelp({ topic, padding = 'p-1', ...restProps }: BadgeHelpProps) {
export function BadgeHelp({ topic, padding = 'p-1', className, contentClass, style, ...restProps }: BadgeHelpProps) {
const showHelp = usePreferencesStore(state => state.showHelp);
if (!showHelp) {
return null;
}
return (
<div tabIndex={-1} id={`help-${topic}`} className={padding}>
<div tabIndex={-1} id={`help-${topic}`} className={clsx(padding, className)} style={style}>
<IconHelp size='1.25rem' className='icon-primary' />
<Tooltip clickable anchorSelect={`#help-${topic}`} layer='z-topmost' {...restProps}>
<Tooltip
clickable
anchorSelect={`#help-${topic}`}
layer='z-topmost'
className={clsx(PARAMETER.TOOLTIP_WIDTH, contentClass)}
{...restProps}
>
<Suspense fallback={<Loader />}>
<div className='absolute right-1 text-sm top-[0.4rem] clr-input' onClick={event => event.stopPropagation()}>
<TextURL text='Справка...' href={`/manuals?topic=${topic}`} />

View File

@ -2,7 +2,6 @@ import { useState } from 'react';
import { useIntl } from 'react-intl';
import clsx from 'clsx';
import { FlexColumn } from '@/components/Container';
import { MiniButton } from '@/components/Control';
import { createColumnHelper, DataTable, type IConditionalStyle } from '@/components/DataTable';
import { Dropdown, useDropdown } from '@/components/Dropdown';
@ -148,10 +147,10 @@ export function PickSchema({
columns={columns}
conditionalRowStyles={conditionalRowStyles}
noDataComponent={
<FlexColumn className='dense p-3 items-center min-h-[6rem]'>
<div className='cc-column dense p-3 items-center min-h-[6rem]'>
<p>Список схем пуст</p>
<p>Измените параметры фильтра</p>
</FlexColumn>
</div>
}
onRowClicked={rowData => onChange(rowData.id)}
/>

View File

@ -2,11 +2,9 @@ import { HelpTopic } from '@/features/help';
import { BadgeHelp } from '@/features/help/components';
import { useRoleStore, UserRole } from '@/features/users';
import { Overlay } from '@/components/Container';
import { MiniButton } from '@/components/Control';
import { IconImmutable, IconMutable } from '@/components/Icons';
import { Label } from '@/components/Input';
import { PARAMETER } from '@/utils/constants';
import { type AccessPolicy, type ILibraryItem } from '../backend/types';
import { useMutatingLibrary } from '../backend/useMutatingLibrary';
@ -42,7 +40,7 @@ export function ToolbarItemAccess({
}
return (
<Overlay position='top-[4.5rem] right-0' className='w-[12rem] flex pr-2' layer='z-bottom'>
<div className='absolute z-bottom top-[4.5rem] right-0 w-[12rem] flex pr-2'>
<Label text='Доступ' className='self-center select-none' />
<div className='ml-auto cc-icons'>
<SelectAccessPolicy
@ -70,10 +68,8 @@ export function ToolbarItemAccess({
onClick={toggleReadOnly}
disabled={role === UserRole.READER || isProcessing}
/>
<div className='pt-[0.125rem]'>
<BadgeHelp topic={HelpTopic.ACCESS} className={PARAMETER.TOOLTIP_WIDTH} offset={4} />
<BadgeHelp topic={HelpTopic.ACCESS} className='mt-[0.125rem]' offset={4} />
</div>
</div>
</Overlay>
);
}

View File

@ -3,29 +3,28 @@
import { urls, useConceptNavigation } from '@/app';
import { HelpTopic } from '@/features/help';
import { BadgeHelp } from '@/features/help/components';
import { AccessPolicy, type ILibraryItem, LibraryItemType } from '@/features/library';
import { useMutatingLibrary } from '@/features/library/backend/useMutatingLibrary';
import { MiniSelectorOSS } from '@/features/library/components';
import { type IRSForm } from '@/features/rsform';
import { useRoleStore, UserRole } from '@/features/users';
import { Overlay } from '@/components/Container';
import { MiniButton } from '@/components/Control';
import { IconDestroy, IconSave, IconShare } from '@/components/Icons';
import { useModificationStore } from '@/stores/modification';
import { PARAMETER } from '@/utils/constants';
import { tooltipText } from '@/utils/labels';
import { prepareTooltip, sharePage } from '@/utils/utils';
import { type IRSForm } from '../models/rsform';
import { AccessPolicy, type ILibraryItem, LibraryItemType } from '../backend/types';
import { useMutatingLibrary } from '../backend/useMutatingLibrary';
interface ToolbarRSFormCardProps {
import { MiniSelectorOSS } from './MiniSelectorOSS';
interface ToolbarItemCardProps {
onSubmit: () => void;
isMutable: boolean;
schema: ILibraryItem;
deleteSchema: () => void;
}
export function ToolbarRSFormCard({ schema, onSubmit, isMutable, deleteSchema }: ToolbarRSFormCardProps) {
export function ToolbarItemCard({ schema, onSubmit, isMutable, deleteSchema }: ToolbarItemCardProps) {
const role = useRoleStore(state => state.role);
const router = useConceptNavigation();
const { isModified } = useModificationStore();
@ -49,7 +48,7 @@ export function ToolbarRSFormCard({ schema, onSubmit, isMutable, deleteSchema }:
})();
return (
<Overlay position='cc-tab-tools' className='cc-icons'>
<div className='cc-tab-tools cc-icons'>
{ossSelector}
{isMutable || isModified ? (
<MiniButton
@ -73,7 +72,7 @@ export function ToolbarRSFormCard({ schema, onSubmit, isMutable, deleteSchema }:
onClick={deleteSchema}
/>
) : null}
<BadgeHelp topic={HelpTopic.UI_RS_CARD} offset={4} className={PARAMETER.TOOLTIP_WIDTH} />
</Overlay>
<BadgeHelp topic={HelpTopic.UI_RS_CARD} offset={4} />
</div>
);
}

View File

@ -5,3 +5,4 @@ export { PickSchema } from './PickSchema';
export { SelectLibraryItem } from './SelectLibraryItem';
export { SelectVersion } from './SelectVersion';
export { ToolbarItemAccess } from './ToolbarItemAccess';
export { ToolbarItemCard } from './ToolbarItemCard';

View File

@ -4,7 +4,6 @@ import clsx from 'clsx';
import { urls, useConceptNavigation } from '@/app';
import { FlexColumn } from '@/components/Container';
import { TextURL } from '@/components/Control';
import { DataTable, type IConditionalStyle, type VisibilityState } from '@/components/DataTable';
import { useWindowSize } from '@/hooks/useWindowSize';
@ -64,13 +63,13 @@ export function TableLibraryItems({ items }: TableLibraryItemsProps) {
className={clsx('text-xs sm:text-sm cc-scroll-y h-fit border-b', { 'border-l': folderMode })}
style={{ maxHeight: tableHeight }}
noDataComponent={
<FlexColumn className='dense p-3 items-center min-h-[6rem]'>
<div className='cc-column dense p-3 items-center min-h-[6rem]'>
<p>Список схем пуст</p>
<p className='flex gap-6'>
<TextURL text='Создать схему' href='/library/create' />
<TextURL text='Очистить фильтр' onClick={resetFilter} />
</p>
</FlexColumn>
</div>
}
columnVisibility={columnVisibility}
onRowClicked={handleOpenItem}

View File

@ -74,12 +74,7 @@ export function ViewSideLocation({ isVisible, onRenameLocation }: ViewSideLocati
}}
>
<div className='h-[2.08rem] flex justify-between items-center pr-1 pl-[0.125rem]'>
<BadgeHelp
topic={HelpTopic.UI_LIBRARY}
className={clsx(PARAMETER.TOOLTIP_WIDTH, 'text-sm')}
offset={5}
place='right-start'
/>
<BadgeHelp topic={HelpTopic.UI_LIBRARY} contentClass='text-sm' offset={5} place='right-start' />
<div className='cc-icons'>
{canRename ? (
<MiniButton

View File

@ -1,6 +1,5 @@
import { Controller, useFormContext, useWatch } from 'react-hook-form';
import { FlexColumn } from '@/components/Container';
import { Label, TextArea, TextInput } from '@/components/Input';
import { useDialogsStore } from '@/stores/dialogs';
@ -45,7 +44,7 @@ export function TabSynthesisOperation() {
/>
</div>
<FlexColumn>
<div className='cc-column'>
<Label text={`Выбор аргументов: [ ${inputs.length} ]`} />
<Controller
name='arguments'
@ -54,7 +53,7 @@ export function TabSynthesisOperation() {
<PickMultiOperation items={oss.items} value={field.value} onChange={field.onChange} rows={6} />
)}
/>
</FlexColumn>
</div>
</div>
);
}

View File

@ -1,7 +1,6 @@
'use client';
import { Controller, useFormContext } from 'react-hook-form';
import { FlexColumn } from '@/components/Container';
import { Label } from '@/components/Input';
import { useDialogsStore } from '@/stores/dialogs';
@ -25,7 +24,6 @@ export function TabArguments() {
return (
<div className='cc-fade-in cc-column'>
<FlexColumn>
<Controller
name='arguments'
control={control}
@ -41,7 +39,6 @@ export function TabArguments() {
</>
)}
/>
</FlexColumn>
</div>
);
}

View File

@ -2,10 +2,8 @@
import clsx from 'clsx';
import { EditorLibraryItem } from '@/features/library/components';
import { ToolbarRSFormCard } from '@/features/rsform/components';
import { EditorLibraryItem, ToolbarItemCard } from '@/features/library/components';
import { FlexColumn } from '@/components/Container';
import { useModificationStore } from '@/stores/modification';
import { globalIDs } from '@/utils/constants';
@ -36,7 +34,7 @@ export function EditorOssCard() {
return (
<>
<ToolbarRSFormCard onSubmit={initiateSubmit} schema={schema} isMutable={isMutable} deleteSchema={deleteSchema} />
<ToolbarItemCard onSubmit={initiateSubmit} schema={schema} isMutable={isMutable} deleteSchema={deleteSchema} />
<div
onKeyDown={handleInput}
className={clsx(
@ -46,10 +44,10 @@ export function EditorOssCard() {
'flex flex-row flex-wrap px-6 justify-center'
)}
>
<FlexColumn className='px-3'>
<div className='cc-column px-3'>
<FormOSS />
<EditorLibraryItem schema={schema} isAttachedToOSS={false} />
</FlexColumn>
</div>
<OssStats stats={schema.stats} />
</div>

View File

@ -10,8 +10,8 @@ import {
useOnSelectionChange,
useReactFlow
} from 'reactflow';
import clsx from 'clsx';
import { Overlay } from '@/components/Container';
import { useMainHeight } from '@/stores/appLayout';
import { useDialogsStore } from '@/stores/dialogs';
import { PARAMETER } from '@/utils/constants';
@ -191,16 +191,20 @@ export function OssFlow() {
return (
<div tabIndex={-1} className='relative' onKeyDown={handleKeyDown}>
<Overlay
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'
<div
className={clsx(
'absolute z-pop top-[1.9rem] right-1/2 translate-x-1/2',
'pt-1 rounded-b-2xl',
'cc-blur',
'hover:bg-prim-100 hover:bg-opacity-50'
)}
>
<ToolbarOssGraph
onCreate={handleCreateOperation}
onDelete={handleDeleteSelected}
onResetPositions={() => setToggleReset(prev => !prev)}
/>
</Overlay>
</div>
<NodeContextMenu isOpen={isContextMenuOpen} onHide={() => setIsContextMenuOpen(false)} {...menuProps} />

View File

@ -1,7 +1,6 @@
'use client';
import { useReactFlow } from 'reactflow';
import clsx from 'clsx';
import { HelpTopic } from '@/features/help';
import { BadgeHelp } from '@/features/help/components';
@ -165,11 +164,7 @@ export function ToolbarOssGraph({ onCreate, onDelete, onResetPositions }: Toolba
}
onClick={toggleEdgeAnimate}
/>
<BadgeHelp
topic={HelpTopic.UI_OSS_GRAPH}
className={clsx(PARAMETER.TOOLTIP_WIDTH, 'sm:max-w-[40rem]')}
offset={4}
/>
<BadgeHelp topic={HelpTopic.UI_OSS_GRAPH} contentClass='sm:max-w-[40rem]' offset={4} />
</div>
{isMutable ? (
<div className='cc-icons'>

View File

@ -1,6 +1,5 @@
'use client';
import { Overlay } from '@/components/Container';
import { IconConsolidation, IconRSForm } from '@/components/Icons';
import { Indicator } from '@/components/View';
import { globalIDs } from '@/utils/constants';
@ -29,7 +28,7 @@ export function NodeCore({ node }: NodeCoreProps) {
data-tooltip-hidden={node.dragging}
onMouseEnter={() => setHover(node.data.operation)}
>
<Overlay position='top-0 right-0' className='flex flex-col gap-1 p-[2px]'>
<div className='absolute z-pop top-0 right-0 flex flex-col gap-1 p-[2px]'>
<Indicator
noPadding
title={hasFile ? 'Связанная КС' : 'Нет связанной КС'}
@ -42,7 +41,7 @@ export function NodeCore({ node }: NodeCoreProps) {
icon={<IconConsolidation className='text-sec-600' size='12px' />}
/>
) : null}
</Overlay>
</div>
{node.data.operation.operation_type === OperationType.INPUT ? (
<div className='absolute top-[1px] right-1/2 translate-x-1/2 border-t w-[30px]' />

View File

@ -1,4 +1,3 @@
export { ConstituentaTooltip } from './ConstituentaTooltip';
export { PickMultiConstituenta } from './PickMultiConstituenta';
export { PickSubstitutions } from './PickSubstitutions';
export { ToolbarRSFormCard } from './ToolbarRSFormCard';

View File

@ -2,13 +2,11 @@
import { useState } from 'react';
import { Controller, useFormContext, useWatch } from 'react-hook-form';
import clsx from 'clsx';
import { HelpTopic } from '@/features/help';
import { BadgeHelp } from '@/features/help/components';
import { TextArea, TextInput } from '@/components/Input';
import { PARAMETER } from '@/utils/constants';
import { CstType, type ICstCreateDTO } from '../../backend/types';
import { RSInput } from '../../components/RSInput';
@ -54,11 +52,7 @@ export function FormCreateCst({ schema }: FormCreateCstProps) {
{...register('alias')}
error={errors.alias}
/>
<BadgeHelp
topic={HelpTopic.CC_CONSTITUENTA}
offset={16}
className={clsx(PARAMETER.TOOLTIP_WIDTH, 'sm:max-w-[40rem]')}
/>
<BadgeHelp topic={HelpTopic.CC_CONSTITUENTA} offset={16} contentClass='sm:max-w-[40rem]' />
</div>
<TextArea

View File

@ -2,10 +2,10 @@
import { useState } from 'react';
import { ReactFlowProvider } from 'reactflow';
import clsx from 'clsx';
import { HelpTopic } from '@/features/help';
import { Overlay } from '@/components/Container';
import { ModalView } from '@/components/Modal';
import { useDialogsStore } from '@/stores/dialogs';
@ -27,9 +27,13 @@ export function DlgShowAST() {
return (
<ModalView className='relative w-[calc(100dvw-3rem)] h-[calc(100dvh-6rem)]' helpTopic={HelpTopic.UI_FORMULA_TREE}>
<Overlay
position='top-0 -mt-1 right-1/2 translate-x-1/2'
className='px-2 rounded-2xl cc-blur bg-prim-100 max-w-[60ch] text-lg text-center'
<div
className={clsx(
'absolute z-pop top-0 -mt-1 right-1/2 translate-x-1/2 max-w-[60ch]',
'px-2 rounded-2xl',
'cc-blur bg-prim-100',
'text-lg text-center'
)}
>
{!hoverNode || isDragging ? expression : null}
{!isDragging && hoverNode ? (
@ -39,7 +43,7 @@ export function DlgShowAST() {
<span>{expression.slice(hoverNode.finish)}</span>
</div>
) : null}
</Overlay>
</div>
<ReactFlowProvider>
<ASTFlow

View File

@ -1,6 +1,5 @@
import clsx from 'clsx';
import { Overlay } from '@/components/Container';
import { MiniButton } from '@/components/Control';
import { IconEdit } from '@/components/Icons';
import { useDialogsStore } from '@/stores/dialogs';
@ -29,7 +28,7 @@ export function EditorControls({ constituenta, disabled, onEditTerm }: EditorCon
}
return (
<Overlay position='top-0 left-[4.7rem]' className='flex select-none'>
<div className='absolute z-pop top-0 left-[4.7rem] flex select-none'>
{!disabled || isProcessing ? (
<MiniButton
title={isModified ? tooltipText.unsaved : `Редактировать словоформы термина`}
@ -59,6 +58,6 @@ export function EditorControls({ constituenta, disabled, onEditTerm }: EditorCon
disabled={isModified}
/>
) : null}
</Overlay>
</div>
);
}

View File

@ -6,7 +6,6 @@ import { Controller, useForm } from 'react-hook-form';
import { toast } from 'react-toastify';
import { zodResolver } from '@hookform/resolvers/zod';
import { Overlay } from '@/components/Container';
import { SubmitButton } from '@/components/Control';
import { IconChild, IconPredecessor, IconSave } from '@/components/Icons';
import { TextArea } from '@/components/Input';
@ -251,7 +250,7 @@ export function FormConstituenta({ disabled, id, toggleReset, schema, activeCst,
disabled={disabled || !isModified}
icon={<IconSave size='1.25rem' />}
/>
<Overlay position='top-[0.1rem] left-full' className='cc-icons'>
<div className='absolute z-pop top-[0.1rem] left-full cc-icons'>
{activeCst.has_inherited_children && !activeCst.is_inherited ? (
<Indicator
icon={<IconPredecessor size='1.25rem' className='text-sec-600' />}
@ -264,7 +263,7 @@ export function FormConstituenta({ disabled, id, toggleReset, schema, activeCst,
titleHtml='Внимание!</br> Конституента является наследником<br/>'
/>
) : null}
</Overlay>
</div>
</div>
) : null}
</form>

View File

@ -8,7 +8,6 @@ import { BadgeHelp } from '@/features/help/components';
import { MiniSelectorOSS } from '@/features/library/components';
import { useFindPredecessor } from '@/features/oss/backend/useFindPredecessor';
import { Overlay } from '@/components/Container';
import { MiniButton } from '@/components/Control';
import {
IconClone,
@ -24,7 +23,6 @@ import {
} from '@/components/Icons';
import { useModificationStore } from '@/stores/modification';
import { usePreferencesStore } from '@/stores/preferences';
import { PARAMETER } from '@/utils/constants';
import { tooltipText } from '@/utils/labels';
import { prepareTooltip } from '@/utils/utils';
@ -80,9 +78,13 @@ export function ToolbarConstituenta({
}
return (
<Overlay
position='cc-tab-tools right-1/2 translate-x-0 xs:right-4 xs:-translate-x-1/2 md:right-1/2 md:translate-x-0'
className='cc-icons cc-animate-position outline-hidden cc-blur px-1 rounded-b-2xl'
<div
className={clsx(
'absolute z-pop right-1/2 translate-x-0 xs:right-4 xs:-translate-x-1/2 md:right-1/2 md:translate-x-0',
'px-1 rounded-b-2xl',
'cc-blur',
'cc-tab-tools cc-icons cc-animate-position outline-hidden'
)}
>
{schema.oss.length > 0 ? (
<MiniSelectorOSS
@ -154,11 +156,7 @@ export function ToolbarConstituenta({
/>
</>
) : null}
<BadgeHelp
topic={HelpTopic.UI_RS_EDITOR}
offset={4}
className={clsx(PARAMETER.TOOLTIP_WIDTH, 'sm:max-w-[40rem]')}
/>
</Overlay>
<BadgeHelp topic={HelpTopic.UI_RS_EDITOR} offset={4} contentClass='sm:max-w-[40rem]' />
</div>
);
}

View File

@ -5,7 +5,6 @@ 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 { APP_COLORS } from '@/styling/colors';
import { globalIDs } from '@/utils/constants';
@ -39,10 +38,11 @@ export function StatusBar({ isModified, processing, activeCst, parseData, onAnal
})();
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
className={clsx(
'absolute z-pop top-[-0.5rem] right-1/2 translate-x-1/2 w-fit',
'pl-[8.5rem] xs:pl-[2rem] flex gap-1'
)}
>
<div
tabIndex={0}
@ -73,6 +73,6 @@ export function StatusBar({ isModified, processing, activeCst, parseData, onAnal
) : null}
</div>
<BadgeHelp topic={HelpTopic.UI_CST_STATUS} offset={4} />
</Overlay>
</div>
);
}

View File

@ -1,4 +1,3 @@
import { Overlay } from '@/components/Container';
import { MiniButton } from '@/components/Control';
import { IconControls, IconTree, IconTypeGraph } from '@/components/Icons';
import { usePreferencesStore } from '@/stores/preferences';
@ -17,7 +16,7 @@ export function ToolbarRSExpression({ disabled, showTypeGraph, showAST }: Toolba
const toggleControls = usePreferencesStore(state => state.toggleShowExpressionControls);
return (
<Overlay position='top-[-0.5rem] right-0' layer='z-pop' className='cc-icons'>
<div className='absolute z-pop top-[-0.5rem] right-0 cc-icons'>
{!disabled || isProcessing ? (
<MiniButton
title='Отображение специальной клавиатуры'
@ -35,6 +34,6 @@ export function ToolbarRSExpression({ disabled, showTypeGraph, showAST }: Toolba
onClick={showAST}
icon={<IconTree size='1.25rem' className='icon-primary' />}
/>
</Overlay>
</div>
);
}

View File

@ -2,13 +2,11 @@
import clsx from 'clsx';
import { EditorLibraryItem } from '@/features/library/components';
import { EditorLibraryItem, ToolbarItemCard } from '@/features/library/components';
import { FlexColumn } from '@/components/Container';
import { useModificationStore } from '@/stores/modification';
import { globalIDs } from '@/utils/constants';
import { ToolbarRSFormCard } from '../../../components/ToolbarRSFormCard';
import { useRSEdit } from '../RSEditContext';
import { FormRSForm } from './FormRSForm';
@ -44,12 +42,12 @@ export function EditorRSFormCard() {
'flex flex-row flex-wrap px-6 pt-[1.9rem]'
)}
>
<ToolbarRSFormCard onSubmit={initiateSubmit} schema={schema} isMutable={isMutable} deleteSchema={deleteSchema} />
<ToolbarItemCard onSubmit={initiateSubmit} schema={schema} isMutable={isMutable} deleteSchema={deleteSchema} />
<FlexColumn className='shrink'>
<div className='cc-column shrink'>
<FormRSForm />
<EditorLibraryItem schema={schema} isAttachedToOSS={isAttachedToOSS} />
</FlexColumn>
</div>
<RSFormStats stats={schema.stats} isArchive={isArchive} />
</div>

View File

@ -4,12 +4,10 @@ import { HelpTopic } from '@/features/help';
import { BadgeHelp } from '@/features/help/components';
import { useVersionRestore } from '@/features/library/backend/useVersionRestore';
import { Overlay } from '@/components/Container';
import { MiniButton } from '@/components/Control';
import { IconNewVersion, IconUpload, IconVersions } from '@/components/Icons';
import { useDialogsStore } from '@/stores/dialogs';
import { useModificationStore } from '@/stores/modification';
import { PARAMETER } from '@/utils/constants';
import { promptText } from '@/utils/labels';
import { promptUnsaved } from '@/utils/utils';
@ -57,7 +55,7 @@ export function ToolbarVersioning({ blockReload }: ToolbarVersioningProps) {
}
return (
<Overlay position='top-[-0.4rem] right-[0rem]' className='pr-2 cc-icons' layer='z-bottom'>
<div className='absolute z-bottom top-[-0.4rem] right-[0rem] pr-2 cc-icons'>
{isMutable ? (
<>
<MiniButton
@ -86,7 +84,7 @@ export function ToolbarVersioning({ blockReload }: ToolbarVersioningProps) {
/>
</>
) : null}
<BadgeHelp topic={HelpTopic.VERSIONS} className={PARAMETER.TOOLTIP_WIDTH} offset={4} />
</Overlay>
<BadgeHelp topic={HelpTopic.VERSIONS} offset={4} />
</div>
);
}

View File

@ -128,14 +128,6 @@ export function EditorRSList() {
return (
<div tabIndex={-1} onKeyDown={handleKeyDown} className='relative cc-fade-in pt-[1.9rem]'>
{isContentEditable ? <ToolbarRSList /> : null}
<MiniButton
className='absolute z-tooltip top-[2.15rem] right-[1rem]'
title='Выгрузить в формате CSV'
icon={<IconCSV size='1.25rem' className='icon-green' />}
onClick={handleDownloadCSV}
/>
{isContentEditable ? (
<div className='flex items-center border-b'>
<div className='px-2'>
@ -151,6 +143,13 @@ export function EditorRSList() {
</div>
) : null}
<MiniButton
className='absolute z-pop top-[4.45rem] md:top-[2.15rem] right-[1rem] cc-animate-position'
title='Выгрузить в формате CSV'
icon={<IconCSV size='1.25rem' className='icon-green' />}
onClick={handleDownloadCSV}
/>
<TableRSList
items={filtered}
maxHeight={tableHeight}

View File

@ -1,9 +1,10 @@
import clsx from 'clsx';
import { HelpTopic } from '@/features/help';
import { BadgeHelp } from '@/features/help/components';
import { MiniSelectorOSS } from '@/features/library/components';
import { CstType } from '@/features/rsform';
import { Overlay } from '@/components/Container';
import { MiniButton } from '@/components/Control';
import { Dropdown, DropdownButton, useDropdown } from '@/components/Dropdown';
import {
@ -41,9 +42,12 @@ export function ToolbarRSList() {
} = useRSEdit();
return (
<Overlay
position='cc-tab-tools right-4 md:right-1/2 -translate-x-1/2 md:translate-x-0'
className='cc-icons cc-animate-position items-start outline-hidden'
<div
className={clsx(
'cc-tab-tools right-4 md:right-1/2 -translate-x-1/2 md:translate-x-0',
'cc-icons items-start',
'outline-hidden cc-animate-position'
)}
>
{schema.oss.length > 0 ? (
<MiniSelectorOSS
@ -108,6 +112,6 @@ export function ToolbarRSList() {
onClick={promptDeleteCst}
/>
<BadgeHelp topic={HelpTopic.UI_RS_LIST} offset={5} />
</Overlay>
</div>
);
}

View File

@ -1,7 +1,6 @@
import { HelpTopic } from '@/features/help';
import { BadgeHelp } from '@/features/help/components';
import { Overlay } from '@/components/Container';
import { SelectSingle } from '@/components/Input';
import { mapLabelColoring } from '../../../labels';
@ -21,11 +20,11 @@ export function GraphSelectors() {
return (
<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]'>
{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}
<div className='absolute z-pop right-[2.5rem] top-[0.25rem]'>
{coloring === 'status' ? <BadgeHelp topic={HelpTopic.UI_CST_STATUS} contentClass='min-w-[25rem]' /> : null}
{coloring === 'type' ? <BadgeHelp topic={HelpTopic.UI_CST_CLASS} contentClass='min-w-[25rem]' /> : null}
{coloring === 'schemas' ? <SchemasGuide /> : null}
</Overlay>
</div>
<SelectSingle
noBorder
placeholder='Цветовая схема'

View File

@ -12,8 +12,8 @@ import {
useReactFlow,
useStoreApi
} from 'reactflow';
import clsx from 'clsx';
import { Overlay } from '@/components/Container';
import { useMainHeight } from '@/stores/appLayout';
import { PARAMETER } from '@/utils/constants';
@ -163,8 +163,8 @@ export function TGFlow() {
}
return (
<>
<Overlay position='cc-tab-tools' className='flex flex-col items-center rounded-b-2xl cc-blur'>
<div className='cc-fade-in relative' tabIndex={-1} onKeyDown={handleKeyDown}>
<div className='cc-tab-tools flex flex-col items-center rounded-b-2xl cc-blur'>
<ToolbarTermGraph />
<ToolbarFocusedCst />
{!focusCst ? (
@ -179,19 +179,20 @@ export function TGFlow() {
onChange={handleSetSelected}
/>
) : null}
</Overlay>
</div>
<div className='cc-fade-in' tabIndex={-1} onKeyDown={handleKeyDown}>
<Overlay
position='top-[4.4rem] sm:top-[4.1rem] left-[0.5rem] sm:left-[0.65rem] w-[13.5rem]'
className='flex flex-col pointer-events-none'
<div
className={clsx(
'absolute z-pop top-[4.4rem] sm:top-[4.1rem] left-[0.5rem] sm:left-[0.65rem] w-[13.5rem]',
'flex flex-col pointer-events-none'
)}
>
<div className='px-2 pb-1 select-none whitespace-nowrap cc-blur rounded-xl'>
Выбор {selected.length} из {schema.stats?.count_all ?? 0}
</div>
<GraphSelectors />
<ViewHidden items={hidden} />
</Overlay>
</div>
<div className='relative outline-hidden w-[100dvw]' style={{ height: mainHeight }}>
<ReactFlow
@ -210,6 +211,5 @@ export function TGFlow() {
/>
</div>
</div>
</>
);
}

View File

@ -1,5 +1,4 @@
import { useReactFlow } from 'reactflow';
import clsx from 'clsx';
import { HelpTopic } from '@/features/help';
import { BadgeHelp } from '@/features/help/components';
@ -147,11 +146,7 @@ export function ToolbarTermGraph() {
title='Граф ступеней'
onClick={handleShowTypeGraph}
/>
<BadgeHelp
topic={HelpTopic.UI_GRAPH_TERM}
className={clsx(PARAMETER.TOOLTIP_WIDTH, 'sm:max-w-[40rem]')}
offset={4}
/>
<BadgeHelp topic={HelpTopic.UI_GRAPH_TERM} contentClass='sm:max-w-[40rem]' offset={4} />
</div>
);
}

View File

@ -3,13 +3,12 @@
import { useState } from 'react';
import { useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import clsx from 'clsx';
import { urls, useConceptNavigation } from '@/app';
import { HelpTopic } from '@/features/help';
import { isAxiosError } from '@/backend/apiTransport';
import { FlexColumn, Tooltip } from '@/components/Container';
import { Tooltip } from '@/components/Container';
import { Button, SubmitButton, TextURL } from '@/components/Control';
import { IconHelp } from '@/components/Icons';
import { type ErrorData } from '@/components/InfoError';
@ -56,13 +55,13 @@ export function FormSignup() {
return (
<form
className={clsx('cc-fade-in cc-column', 'mx-auto w-[36rem]', 'px-6 py-3')}
className='cc-column cc-fade-in mx-auto w-[36rem] px-6 py-3'
onSubmit={event => void handleSubmit(onSubmit)(event)}
onChange={resetErrors}
>
<h1>Новый пользователь</h1>
<div className='flex gap-12'>
<FlexColumn>
<div className='cc-column'>
<TextInput
id='username'
{...register('username')}
@ -92,9 +91,9 @@ export function FormSignup() {
className='w-[15rem]'
error={errors.password2}
/>
</FlexColumn>
</div>
<FlexColumn className='w-[15rem] relative'>
<div className='cc-column 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}>
электронная почта используется для восстановления пароля
@ -123,7 +122,7 @@ export function FormSignup() {
autoComplete='family-name'
error={errors.last_name}
/>
</FlexColumn>
</div>
</div>
<div className='flex gap-1 text-sm'>

View File

@ -9,7 +9,6 @@ import { type IChangePasswordDTO, schemaChangePassword } from '@/features/auth';
import { useChangePassword } from '@/features/auth/backend/useChangePassword';
import { isAxiosError } from '@/backend/apiTransport';
import { FlexColumn } from '@/components/Container';
import { SubmitButton } from '@/components/Control';
import { type ErrorData } from '@/components/InfoError';
import { TextInput } from '@/components/Input';
@ -41,7 +40,7 @@ export function EditorPassword() {
onSubmit={event => void handleSubmit(onSubmit)(event)}
onChange={resetErrors}
>
<FlexColumn>
<div className='cc-column'>
<TextInput
id='old_password'
type='password'
@ -70,7 +69,7 @@ export function EditorPassword() {
error={errors.new_password2}
/>
{serverError ? <ServerError error={serverError} /> : null}
</FlexColumn>
</div>
<SubmitButton text='Сменить пароль' className='self-center mt-2' loading={isPending} />
</form>
);

View File

@ -144,6 +144,8 @@
}
@utility cc-tab-tools {
z-index: var(--z-index-pop);
position: absolute;
top: 1.7rem;
right: 50%;
padding-top: 0.4rem;

View File

@ -4,6 +4,6 @@ test('should load the homepage and display login button', async ({ page }) => {
await page.goto('/');
await expect(page).toHaveTitle('Концепт Портал');
await page.locator('.h-full > .mr-1').click();
await page.getByRole('button', { name: 'Перейти на страницу логина' }).click();
await expect(page.getByText('Логин или email')).toBeVisible();
});