mirror of
https://github.com/IRBorisov/ConceptPortal.git
synced 2025-06-26 13:00:39 +03:00
UI fixes
This commit is contained in:
parent
2ab01cda42
commit
1cc41320ac
|
@ -7,7 +7,6 @@ export interface CheckboxProps
|
|||
extends Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, 'className' | 'children' | 'title' | 'value' | 'onClick' > {
|
||||
id?: string
|
||||
label?: string
|
||||
required?: boolean
|
||||
disabled?: boolean
|
||||
dimensions?: string
|
||||
tooltip?: string
|
||||
|
@ -17,7 +16,7 @@ extends Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, 'className' | 'child
|
|||
}
|
||||
|
||||
function Checkbox({
|
||||
id, required, disabled, tooltip, label,
|
||||
id, disabled, tooltip, label,
|
||||
dimensions = 'w-fit', value, setValue, ...props
|
||||
}: CheckboxProps) {
|
||||
const cursor = useMemo(
|
||||
|
@ -59,7 +58,6 @@ function Checkbox({
|
|||
<Label
|
||||
className={`${cursor} px-2 text-start`}
|
||||
text={label}
|
||||
required={required}
|
||||
htmlFor={id}
|
||||
/>}
|
||||
</button>
|
||||
|
|
|
@ -1,19 +1,19 @@
|
|||
import { LabelHTMLAttributes } from 'react';
|
||||
|
||||
interface LabelProps
|
||||
extends Omit<React.DetailedHTMLProps<LabelHTMLAttributes<HTMLLabelElement>, HTMLLabelElement>, 'children'> {
|
||||
extends Omit<React.DetailedHTMLProps<LabelHTMLAttributes<HTMLLabelElement>, HTMLLabelElement>, 'children' | 'title'> {
|
||||
text: string
|
||||
required?: boolean
|
||||
tooltip?: string
|
||||
}
|
||||
|
||||
function Label({ text, required, title, className, ...props }: LabelProps) {
|
||||
function Label({ text, tooltip, className, ...props }: LabelProps) {
|
||||
return (
|
||||
<label
|
||||
className={`text-sm font-semibold ${className}`}
|
||||
title={ (required && !title) ? 'обязательное поле' : title }
|
||||
title={tooltip}
|
||||
{...props}
|
||||
>
|
||||
{text + (required ? '*' : '')}
|
||||
{text}
|
||||
</label>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -19,9 +19,9 @@ function TextArea({
|
|||
}: TextAreaProps) {
|
||||
return (
|
||||
<div className='flex flex-col items-start gap-2'>
|
||||
{label && <Label
|
||||
{label &&
|
||||
<Label
|
||||
text={label}
|
||||
required={!props.disabled && required}
|
||||
htmlFor={id}
|
||||
/>}
|
||||
<textarea id={id}
|
||||
|
|
|
@ -23,7 +23,6 @@ function TextInput({
|
|||
{label &&
|
||||
<Label
|
||||
text={label}
|
||||
required={!props.disabled && required}
|
||||
htmlFor={id}
|
||||
/>}
|
||||
<input id={id}
|
||||
|
|
|
@ -12,7 +12,7 @@ extends Omit<CheckboxProps, 'value' | 'setValue'> {
|
|||
}
|
||||
|
||||
function Tristate({
|
||||
id, required, disabled, tooltip, label,
|
||||
id, disabled, tooltip, label,
|
||||
dimensions = 'w-fit', value, setValue, ...props
|
||||
}: TristateProps) {
|
||||
const cursor = useMemo(
|
||||
|
@ -61,7 +61,6 @@ function Tristate({
|
|||
<Label
|
||||
className={`${cursor} px-2 text-start`}
|
||||
text={label}
|
||||
required={required}
|
||||
htmlFor={id}
|
||||
/>}
|
||||
</button>
|
||||
|
|
|
@ -109,15 +109,14 @@ export default function DataTable<TData extends RowData>({
|
|||
|
||||
return (
|
||||
<div className='w-full'>
|
||||
{isEmpty && (noDataComponent ?? <DefaultNoData />)}
|
||||
{!isEmpty &&
|
||||
<div className='flex flex-col items-stretch'>
|
||||
<table>
|
||||
<thead
|
||||
className='clr-app shadow-border'
|
||||
className={`clr-app shadow-border`}
|
||||
style={{
|
||||
top: headPosition,
|
||||
position: 'sticky'
|
||||
position: 'sticky',
|
||||
visibility: !isEmpty ? 'visible' : 'hidden'
|
||||
}}
|
||||
>
|
||||
{tableImpl.getHeaderGroups().map(
|
||||
|
@ -149,7 +148,7 @@ export default function DataTable<TData extends RowData>({
|
|||
</tr>
|
||||
))}
|
||||
</thead>
|
||||
|
||||
|
||||
<tbody>
|
||||
{tableImpl.getRowModel().rows.map(
|
||||
(row: Row<TData>, index) => (
|
||||
|
@ -202,12 +201,13 @@ export default function DataTable<TData extends RowData>({
|
|||
</tfoot>
|
||||
</table>
|
||||
|
||||
{enablePagination &&
|
||||
{enablePagination && !isEmpty &&
|
||||
<PaginationTools
|
||||
table={tableImpl}
|
||||
paginationOptions={paginationOptions}
|
||||
onChangePaginationOption={onChangePaginationOption}
|
||||
/>}
|
||||
</div>}
|
||||
</div>
|
||||
{isEmpty && (noDataComponent ?? <DefaultNoData />)}
|
||||
</div>);
|
||||
}
|
||||
|
|
|
@ -134,7 +134,6 @@ function RSInput({
|
|||
{label &&
|
||||
<Label
|
||||
text={label}
|
||||
required={false}
|
||||
htmlFor={id}
|
||||
className='mb-2'
|
||||
/>}
|
||||
|
|
|
@ -203,7 +203,6 @@ function RefsInput({
|
|||
{label &&
|
||||
<Label
|
||||
text={label}
|
||||
required={false}
|
||||
htmlFor={id}
|
||||
className='mb-2'
|
||||
/>}
|
||||
|
|
|
@ -111,7 +111,7 @@
|
|||
.dark & {
|
||||
background: var(--cd-prim-bg-60);
|
||||
}
|
||||
:hover& {
|
||||
tr :hover& {
|
||||
background: var(--cl-red-bg-100);
|
||||
.dark & {
|
||||
background: var(--cd-red-bg-100);
|
||||
|
|
|
@ -15,7 +15,7 @@ function TopicsList({ activeTopic, onChangeTopic }: TopicsListProps) {
|
|||
(topic, index) => {
|
||||
return (
|
||||
<div key={`${prefixes.topic_list}${index}`}
|
||||
className={`px-3 py-1 border-y cursor-pointer clr-hover ${activeTopic === topic ? 'font-semibold clr-selected ' : ''}`}
|
||||
className={`px-3 py-1 border-y cursor-pointer clr-hover ${activeTopic === topic ? 'clr-selected ' : ''}`}
|
||||
title={describeHelpTopic(topic)}
|
||||
onClick={() => onChangeTopic(topic)}
|
||||
>
|
||||
|
|
|
@ -150,9 +150,9 @@ function EditorConstituenta({
|
|||
icon={<PenIcon size={4} color={isEnabled ? 'text-primary' : ''} />}
|
||||
/>}
|
||||
<div className='flex items-center justify-center w-full'>
|
||||
<div className='font-semibold w-fit'>
|
||||
<span className='small-caps'>Конституента</span>
|
||||
<span className='ml-2 small-caps'>{alias}</span>
|
||||
<div className='font-semibold w-fit pointer-events-none'>
|
||||
<span className='small-caps'>Конституента </span>
|
||||
<span className='ml-1 small-caps'>{alias}</span>
|
||||
</div>
|
||||
<MiniButton
|
||||
tooltip='Переименовать конституенту'
|
||||
|
|
|
@ -397,10 +397,10 @@ function EditorTermGraph({ onOpenEdit, onCreateCst, onDeleteCst }: EditorTermGra
|
|||
</div>
|
||||
<div className='flex items-center w-full gap-1'>
|
||||
<Button
|
||||
icon={<FilterCogIcon size={7} />}
|
||||
icon={<FilterCogIcon size={6} />}
|
||||
dense
|
||||
tooltip='Настройки фильтрации узлов и связей'
|
||||
dimensions='h-full'
|
||||
dimensions='min-h-[2.3rem] min-w-[2.3rem]'
|
||||
onClick={() => setShowOptions(true)}
|
||||
/>
|
||||
<SelectSingle
|
||||
|
@ -411,7 +411,6 @@ function EditorTermGraph({ onOpenEdit, onCreateCst, onDeleteCst }: EditorTermGra
|
|||
value={coloringScheme ? { value: coloringScheme, label: mapLabelColoring.get(coloringScheme) } : null}
|
||||
onChange={data => setColoringScheme(data?.value ?? SelectorGraphColoring[0].value)}
|
||||
/>
|
||||
|
||||
</div>
|
||||
<SelectSingle
|
||||
className='w-full mt-1'
|
||||
|
|
|
@ -384,13 +384,25 @@ function RSTabs() {
|
|||
showCloneDialog={promptClone}
|
||||
showUploadDialog={() => setShowUpload(true)}
|
||||
/>
|
||||
<ConceptTab className='border-x-2 min-w-[7.8rem]'>Паспорт схемы</ConceptTab>
|
||||
<ConceptTab className='border-r-2 min-w-[10rem] flex justify-between gap-2'>
|
||||
<ConceptTab
|
||||
className='border-x-2 min-w-[7.8rem]'
|
||||
title={`Название схемы: ${schema.title ?? ''}`}
|
||||
>
|
||||
Паспорт схемы
|
||||
</ConceptTab>
|
||||
<ConceptTab
|
||||
className='border-r-2 w-fit flex justify-between gap-2'
|
||||
title={`Всего конституент: ${schema.stats?.count_all ?? 0}\nКоличество ошибок: ${schema.stats?.count_errors ?? 0}`}
|
||||
>
|
||||
<span>Конституенты</span>
|
||||
<span>{`${schema.stats?.count_errors ?? 0} | ${schema.stats?.count_all ?? 0}`}</span>
|
||||
</ConceptTab>
|
||||
<ConceptTab className='border-r-2 min-w-[5.2rem]'>Редактор</ConceptTab>
|
||||
<ConceptTab className='min-w-[6.5rem]'>Граф термов</ConceptTab>
|
||||
<ConceptTab className='border-r-2 min-w-[5.2rem]'>
|
||||
Редактор
|
||||
</ConceptTab>
|
||||
<ConceptTab className='min-w-[6.5rem]'>
|
||||
Граф термов
|
||||
</ConceptTab>
|
||||
</TabList>
|
||||
|
||||
<div className='overflow-y-auto' style={{ maxHeight: panelHeight}}>
|
||||
|
|
|
@ -211,7 +211,7 @@ function ViewSideConstituents({ expression, baseHeight, activeID, onOpenEdit }:
|
|||
}, [noNavigation, baseHeight]);
|
||||
|
||||
return (<>
|
||||
<div className='sticky top-0 left-0 right-0 flex items-stretch justify-start w-full gap-1 px-2 border-b rounded clr-input'>
|
||||
<div className='sticky top-0 left-0 right-0 flex items-stretch justify-between w-full gap-1 pl-2 border-b clr-input'>
|
||||
<div className='absolute inset-y-0 left-0 flex items-center pl-3 pointer-events-none text-controls'>
|
||||
<MagnifyingGlassIcon />
|
||||
</div>
|
||||
|
@ -221,56 +221,58 @@ function ViewSideConstituents({ expression, baseHeight, activeID, onOpenEdit }:
|
|||
value={filterText}
|
||||
onChange={event => setFilterText(event.target.value)}
|
||||
/>
|
||||
<div ref={matchModeMenu.ref}>
|
||||
<SelectorButton
|
||||
tooltip='Настройка атрибутов для фильтрации'
|
||||
dimensions='w-fit h-full'
|
||||
transparent
|
||||
icon={<FilterCogIcon size={5} />}
|
||||
text={labelCstMathchMode(filterMatch)}
|
||||
tabIndex={-1}
|
||||
onClick={matchModeMenu.toggle}
|
||||
/>
|
||||
{ matchModeMenu.isActive &&
|
||||
<Dropdown stretchLeft>
|
||||
{ Object.values(CstMatchMode).filter(value => !isNaN(Number(value))).map(
|
||||
(value, index) => {
|
||||
const matchMode = value as CstMatchMode;
|
||||
return (
|
||||
<DropdownButton
|
||||
key={`${prefixes.cst_match_mode_list}${index}`}
|
||||
onClick={() => handleMatchModeChange(matchMode)}
|
||||
>
|
||||
<p><span className='font-semibold'>{labelCstMathchMode(matchMode)}:</span> {describeCstMathchMode(matchMode)}</p>
|
||||
</DropdownButton>);
|
||||
})}
|
||||
</Dropdown>}
|
||||
</div>
|
||||
<div className='flex'>
|
||||
<div ref={matchModeMenu.ref}>
|
||||
<SelectorButton
|
||||
tooltip='Настройка атрибутов для фильтрации'
|
||||
dimensions='w-fit h-full'
|
||||
transparent
|
||||
icon={<FilterCogIcon size={5} />}
|
||||
text={labelCstMathchMode(filterMatch)}
|
||||
tabIndex={-1}
|
||||
onClick={matchModeMenu.toggle}
|
||||
/>
|
||||
{ matchModeMenu.isActive &&
|
||||
<Dropdown stretchLeft>
|
||||
{ Object.values(CstMatchMode).filter(value => !isNaN(Number(value))).map(
|
||||
(value, index) => {
|
||||
const matchMode = value as CstMatchMode;
|
||||
return (
|
||||
<DropdownButton
|
||||
key={`${prefixes.cst_match_mode_list}${index}`}
|
||||
onClick={() => handleMatchModeChange(matchMode)}
|
||||
>
|
||||
<p><span className='font-semibold'>{labelCstMathchMode(matchMode)}:</span> {describeCstMathchMode(matchMode)}</p>
|
||||
</DropdownButton>);
|
||||
})}
|
||||
</Dropdown>}
|
||||
</div>
|
||||
|
||||
<div ref={sourceMenu.ref}>
|
||||
<SelectorButton
|
||||
tooltip='Настройка фильтрации по графу термов'
|
||||
dimensions='w-fit h-full'
|
||||
transparent
|
||||
icon={<CogIcon size={4} />}
|
||||
text={labelCstSource(filterSource)}
|
||||
tabIndex={-1}
|
||||
onClick={sourceMenu.toggle}
|
||||
/>
|
||||
{ sourceMenu.isActive &&
|
||||
<Dropdown stretchLeft>
|
||||
{ Object.values(CstSource).filter(value => !isNaN(Number(value))).map(
|
||||
(value, index) => {
|
||||
const source = value as CstSource;
|
||||
return (
|
||||
<DropdownButton
|
||||
key={`${prefixes.cst_source_list}${index}`}
|
||||
onClick={() => handleSourceChange(source)}
|
||||
>
|
||||
<p><span className='font-semibold'>{labelCstSource(source)}:</span> {describeCstSource(source)}</p>
|
||||
</DropdownButton>);
|
||||
})}
|
||||
</Dropdown>}
|
||||
<div ref={sourceMenu.ref}>
|
||||
<SelectorButton
|
||||
tooltip='Настройка фильтрации по графу термов'
|
||||
dimensions='w-fit h-full'
|
||||
transparent
|
||||
icon={<CogIcon size={4} />}
|
||||
text={labelCstSource(filterSource)}
|
||||
tabIndex={-1}
|
||||
onClick={sourceMenu.toggle}
|
||||
/>
|
||||
{ sourceMenu.isActive &&
|
||||
<Dropdown stretchLeft>
|
||||
{ Object.values(CstSource).filter(value => !isNaN(Number(value))).map(
|
||||
(value, index) => {
|
||||
const source = value as CstSource;
|
||||
return (
|
||||
<DropdownButton
|
||||
key={`${prefixes.cst_source_list}${index}`}
|
||||
onClick={() => handleSourceChange(source)}
|
||||
>
|
||||
<p><span className='font-semibold'>{labelCstSource(source)}:</span> {describeCstSource(source)}</p>
|
||||
</DropdownButton>);
|
||||
})}
|
||||
</Dropdown>}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className='overflow-y-auto text-sm' style={{maxHeight : `${maxHeight}`}}>
|
||||
|
|
Loading…
Reference in New Issue
Block a user