mirror of
https://github.com/IRBorisov/ConceptPortal.git
synced 2025-06-26 21:10:38 +03:00
Minor UI fixes
This commit is contained in:
parent
70737410c2
commit
41bb83b784
|
@ -17,7 +17,7 @@ function TextInput({
|
|||
colorClass = 'clr-input',
|
||||
...props
|
||||
}: TextInputProps) {
|
||||
const borderClass = noBorder ? '': 'border';
|
||||
const borderClass = noBorder ? '': 'border shadow';
|
||||
return (
|
||||
<div className={`flex ${singleRow ? 'items-center gap-4 ' + dimensions : 'flex-col items-start gap-2'}`}>
|
||||
{label &&
|
||||
|
@ -28,7 +28,7 @@ function TextInput({
|
|||
/>}
|
||||
<input id={id}
|
||||
title={tooltip}
|
||||
className={`px-3 py-2 leading-tight ${borderClass} shadow truncate hover:text-clip clr-outline ${colorClass} ${singleRow ? 'w-full' : dimensions}`}
|
||||
className={`px-3 py-2 leading-tight ${borderClass} truncate hover:text-clip clr-outline ${colorClass} ${singleRow ? 'w-full' : dimensions}`}
|
||||
required={required}
|
||||
{...props}
|
||||
/>
|
||||
|
|
|
@ -26,6 +26,7 @@ extends Pick<TableOptions<TData>,
|
|||
'onRowSelectionChange' | 'onColumnVisibilityChange'
|
||||
> {
|
||||
dense?: boolean
|
||||
headPosition?: string
|
||||
conditionalRowStyles?: IConditionalStyle<TData>[]
|
||||
onRowClicked?: (rowData: TData, event: React.MouseEvent<Element, MouseEvent>) => void
|
||||
onRowDoubleClicked?: (rowData: TData, event: React.MouseEvent<Element, MouseEvent>) => void
|
||||
|
@ -46,8 +47,14 @@ extends Pick<TableOptions<TData>,
|
|||
initialSorting?: ColumnSort
|
||||
}
|
||||
|
||||
/**
|
||||
* UI element: data representation as a table.
|
||||
*
|
||||
* @param headPosition - Top position of sticky header (0 if no other sticky elements are present).
|
||||
* No sticky header if omitted
|
||||
*/
|
||||
export default function DataTable<TData extends RowData>({
|
||||
dense, conditionalRowStyles,
|
||||
dense, headPosition, conditionalRowStyles,
|
||||
onRowClicked, onRowDoubleClicked, noDataComponent,
|
||||
|
||||
enableRowSelection,
|
||||
|
@ -106,7 +113,13 @@ export default function DataTable<TData extends RowData>({
|
|||
|
||||
{!isEmpty &&
|
||||
<table>
|
||||
<thead>
|
||||
<thead
|
||||
className='clr-app shadow-border'
|
||||
style={{
|
||||
top: headPosition,
|
||||
position: 'sticky'
|
||||
}}
|
||||
>
|
||||
{tableImpl.getHeaderGroups().map(
|
||||
(headerGroup: HeaderGroup<TData>) => (
|
||||
<tr key={headerGroup.id}>
|
||||
|
@ -122,7 +135,7 @@ export default function DataTable<TData extends RowData>({
|
|||
style={{
|
||||
textAlign: header.getSize() > 100 ? 'left': 'center',
|
||||
width: header.getSize(),
|
||||
cursor: enableSorting && header.column.getCanSort() ? 'pointer': 'auto'
|
||||
cursor: enableSorting && header.column.getCanSort() ? 'pointer': 'auto',
|
||||
}}
|
||||
onClick={enableSorting ? header.column.getToggleSortingHandler() : undefined}
|
||||
>
|
||||
|
@ -144,8 +157,7 @@ export default function DataTable<TData extends RowData>({
|
|||
key={row.id}
|
||||
className={
|
||||
row.getIsSelected() ? 'clr-selected clr-hover' :
|
||||
index % 2 === 0 ? 'clr-controls clr-hover' :
|
||||
'clr-app clr-hover'
|
||||
index % 2 === 0 ? 'clr-controls clr-hover' : 'clr-app clr-hover'
|
||||
}
|
||||
style={conditionalRowStyles && getRowStyles(row)}
|
||||
>
|
||||
|
|
|
@ -174,7 +174,7 @@ function DlgEditReference({ hideWindow, items, initialRef, initialText, initialT
|
|||
const cst = props.row.original;
|
||||
return (<>
|
||||
<div
|
||||
id={`${prefixes.cst_list}${cst.alias}`}
|
||||
id={`${prefixes.cst_wordform_list}${cst.alias}`}
|
||||
className='min-w-[3.1rem] max-w-[3.1rem] px-1 text-center rounded-md whitespace-nowrap'
|
||||
style={{
|
||||
borderWidth: '1px',
|
||||
|
@ -185,7 +185,7 @@ function DlgEditReference({ hideWindow, items, initialRef, initialText, initialT
|
|||
>
|
||||
{cst.alias}
|
||||
</div>
|
||||
<ConstituentaTooltip data={cst} anchor={`#${prefixes.cst_list}${cst.alias}`} />
|
||||
<ConstituentaTooltip data={cst} anchor={`#${prefixes.cst_wordform_list}${cst.alias}`} />
|
||||
</>);
|
||||
}
|
||||
}),
|
||||
|
@ -217,7 +217,7 @@ function DlgEditReference({ hideWindow, items, initialRef, initialText, initialT
|
|||
onSubmit={handleSubmit}
|
||||
>
|
||||
<div className='min-w-[40rem] flex flex-col gap-4 mb-4 mt-2'>
|
||||
<div className='flex self-center flex-start'>
|
||||
<div className='flex items-center self-center flex-start'>
|
||||
<SelectSingle
|
||||
className='z-modal-top min-w-[20rem] w-fit'
|
||||
options={SelectorReferenceType}
|
||||
|
@ -231,7 +231,7 @@ function DlgEditReference({ hideWindow, items, initialRef, initialText, initialT
|
|||
</div>
|
||||
<ConceptTooltip
|
||||
anchorSelect='#terminology-help'
|
||||
className='max-w-[30rem]'
|
||||
className='max-w-[30rem] z-modal-tooltip'
|
||||
offset={4}
|
||||
>
|
||||
<HelpTerminologyControl />
|
||||
|
@ -269,6 +269,8 @@ function DlgEditReference({ hideWindow, items, initialRef, initialText, initialT
|
|||
data={filteredData}
|
||||
columns={columnsConstituenta}
|
||||
conditionalRowStyles={conditionalRowStyles}
|
||||
|
||||
headPosition='0'
|
||||
dense
|
||||
|
||||
noDataComponent={
|
||||
|
@ -289,16 +291,20 @@ function DlgEditReference({ hideWindow, items, initialRef, initialText, initialT
|
|||
value={alias}
|
||||
onChange={event => setAlias(event.target.value)}
|
||||
/>
|
||||
<div className='flex items-center w-full flex-start'>
|
||||
<div className='self-center text-sm font-semibold'>
|
||||
Термин:
|
||||
</div>
|
||||
<TextInput
|
||||
label='Термин'
|
||||
singleRow
|
||||
disabled
|
||||
noBorder
|
||||
value={term}
|
||||
tooltip={term}
|
||||
dimensions='w-full'
|
||||
dimensions='w-full text-sm'
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
{FormButtons}
|
||||
<div className='flex items-center gap-10 flex-start'>
|
||||
<Label text='Отсылаемая словоформа'/>
|
||||
|
|
|
@ -123,6 +123,10 @@
|
|||
@apply rounded
|
||||
}
|
||||
|
||||
.shadow-border {
|
||||
@apply shadow-sm shadow-[var(--cl-bg-40)] dark:shadow-[var(--cd-bg-40)]
|
||||
}
|
||||
|
||||
.clr-modal-backdrop {
|
||||
opacity: 0.75;
|
||||
}
|
||||
|
|
|
@ -69,7 +69,7 @@ function SearchPanel({ total, filtered, query, setQuery, strategy, setStrategy,
|
|||
}, [strategy, navigateTo]);
|
||||
|
||||
return (
|
||||
<div className='sticky top-0 left-0 right-0 flex items-center justify-start w-full border-b clr-input'>
|
||||
<div className='sticky top-0 left-0 right-0 flex items-center justify-start w-full border-b clr-input max-h-[2.3rem]'>
|
||||
<div className='px-2 py-1 select-none whitespace-nowrap min-w-[10rem]'>
|
||||
Фильтр
|
||||
<span className='ml-2'>
|
||||
|
|
|
@ -96,7 +96,7 @@ function ViewLibrary({ items, resetQuery: cleanQuery }: ViewLibraryProps) {
|
|||
return (
|
||||
<div>
|
||||
{items.length > 0 &&
|
||||
<div className='relative w-full'>
|
||||
<div className='sticky top-[2.3rem] w-full'>
|
||||
<div className='absolute top-[-0.125rem] left-0 flex gap-1 ml-3 z-pop'>
|
||||
<div id='library-help' className='py-2 '>
|
||||
<HelpIcon color='text-primary' size={5} />
|
||||
|
@ -112,6 +112,7 @@ function ViewLibrary({ items, resetQuery: cleanQuery }: ViewLibraryProps) {
|
|||
columns={columns}
|
||||
data={items}
|
||||
|
||||
headPosition='2.3rem'
|
||||
noDataComponent={
|
||||
<div className='flex flex-col gap-4 justify-center p-2 text-center min-h-[6rem]'>
|
||||
<p>Список схем пуст</p>
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import { useEffect, useLayoutEffect, useMemo, useState } from 'react';
|
||||
|
||||
import ConceptTooltip from '../../components/Common/ConceptTooltip';
|
||||
import Divider from '../../components/Common/Divider';
|
||||
import MiniButton from '../../components/Common/MiniButton';
|
||||
import Modal from '../../components/Common/Modal';
|
||||
import SelectMulti from '../../components/Common/SelectMulti';
|
||||
|
@ -107,9 +106,8 @@ function DlgEditWordForms({ hideWindow, target, onSave }: DlgEditWordFormsProps)
|
|||
setInputGrams(SelectorGrammems.filter(gram => form.grams.find(test => test === gram.value)));
|
||||
}
|
||||
|
||||
function handleResetForm() {
|
||||
setInputText('');
|
||||
setInputGrams([]);
|
||||
function handleResetAll() {
|
||||
setForms([]);
|
||||
}
|
||||
|
||||
function handleInflect() {
|
||||
|
@ -232,7 +230,7 @@ function DlgEditWordForms({ hideWindow, target, onSave }: DlgEditWordFormsProps)
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div className='min-w-[40rem]'>
|
||||
<div className='min-w-[40rem] max-w-[40rem]'>
|
||||
<TextArea id='nominal' label='Начальная форма'
|
||||
placeholder='Начальная форма'
|
||||
rows={1}
|
||||
|
@ -242,84 +240,97 @@ function DlgEditWordForms({ hideWindow, target, onSave }: DlgEditWordFormsProps)
|
|||
spellCheck
|
||||
/>
|
||||
|
||||
<Divider margins='my-4'/>
|
||||
<div className='text-sm mt-4 mb-2 font-semibold'>
|
||||
Параметры словоформы
|
||||
</div>
|
||||
|
||||
<div className='flex items-start gap-2 justify-stretch min-h-[6.3rem]'>
|
||||
<div className='flex flex-col gap-1'>
|
||||
<div className='flex items-start justify-between w-full'>
|
||||
<TextArea
|
||||
placeholder='Введите текст'
|
||||
rows={2}
|
||||
dimensions='min-w-[20rem] min-h-[4.2rem]'
|
||||
dimensions='min-w-[18rem] w-full min-h-[4.2rem]'
|
||||
|
||||
disabled={textProcessor.loading}
|
||||
value={inputText}
|
||||
onChange={event => setInputText(event.target.value)}
|
||||
/>
|
||||
<div className='flex items-center justify-between select-none'>
|
||||
<div className='flex items-center justify-start'>
|
||||
<MiniButton
|
||||
tooltip='Добавить словоформу'
|
||||
icon={<CheckIcon size={6} color={!inputText || inputGrams.length == 0 ? 'text-disabled' : 'text-success'}/>}
|
||||
disabled={textProcessor.loading || !inputText || inputGrams.length == 0}
|
||||
onClick={handleAddForm}
|
||||
/>
|
||||
<MiniButton
|
||||
tooltip='Сбросить словоформу'
|
||||
icon={<CrossIcon size={6} color='text-warning'/>}
|
||||
disabled={textProcessor.loading}
|
||||
onClick={handleResetForm}
|
||||
/>
|
||||
<MiniButton
|
||||
tooltip='Генерировать все словоформы'
|
||||
icon={<ChevronDoubleDownIcon size={6} color='text-primary'/>}
|
||||
disabled={textProcessor.loading}
|
||||
onClick={handleGenerateLexeme}
|
||||
/>
|
||||
</div>
|
||||
<div className='text-sm'>
|
||||
Словоформ: {forms.length}
|
||||
</div>
|
||||
<div className='flex items-center justify-start'>
|
||||
<div className='max-w-min'>
|
||||
<MiniButton
|
||||
tooltip='Генерировать словоформу'
|
||||
icon={<ArrowLeftIcon size={6} color={inputGrams.length == 0 ? 'text-disabled' : 'text-primary'}/>}
|
||||
icon={<ArrowLeftIcon
|
||||
size={6}
|
||||
color={inputGrams.length == 0 ? 'text-disabled' : 'text-primary'}
|
||||
/>}
|
||||
disabled={textProcessor.loading || inputGrams.length == 0}
|
||||
onClick={handleInflect}
|
||||
/>
|
||||
<MiniButton
|
||||
tooltip='Определить граммемы'
|
||||
icon={<ArrowRightIcon size={6} color={!inputText ? 'text-disabled' : 'text-primary'}/>}
|
||||
icon={<ArrowRightIcon
|
||||
size={6}
|
||||
color={!inputText ? 'text-disabled' : 'text-primary'}
|
||||
/>}
|
||||
disabled={textProcessor.loading || !inputText}
|
||||
onClick={handleParse}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<SelectMulti
|
||||
className='z-modal-top min-w-[20rem] max-w-[20rem] h-full flex-grow'
|
||||
options={options}
|
||||
placeholder='Выберите граммемы'
|
||||
|
||||
value={inputGrams}
|
||||
isDisabled={textProcessor.loading}
|
||||
onChange={newValue => setInputGrams([...newValue].sort(compareGrammemeOptions))}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className='border overflow-y-auto max-h-[17.4rem] min-h-[17.4rem]'>
|
||||
<div className='flex flex-start justify-between'>
|
||||
<div className='flex items-center justify-start'>
|
||||
<MiniButton
|
||||
tooltip='Внести словоформу'
|
||||
icon={<CheckIcon
|
||||
size={6}
|
||||
color={!inputText || inputGrams.length == 0 ? 'text-disabled' : 'text-success'}
|
||||
/>}
|
||||
disabled={textProcessor.loading || !inputText || inputGrams.length == 0}
|
||||
onClick={handleAddForm}
|
||||
/>
|
||||
<MiniButton
|
||||
tooltip='Генерировать все словоформы'
|
||||
icon={<ChevronDoubleDownIcon
|
||||
size={6}
|
||||
color={!inputText ? 'text-disabled' : 'text-primary'}
|
||||
/>}
|
||||
disabled={textProcessor.loading || !inputText}
|
||||
onClick={handleGenerateLexeme}
|
||||
/>
|
||||
</div>
|
||||
<div className='text-sm mt-2 mb-1 font-semibold w-full text-center'>
|
||||
Заданные вручную словоформы: [{forms.length}]
|
||||
</div>
|
||||
<MiniButton
|
||||
tooltip='Сбросить ВСЕ словоформы'
|
||||
icon={<CrossIcon
|
||||
size={6}
|
||||
color={forms.length === 0 ? 'text-disabled' : 'text-warning'}
|
||||
/>}
|
||||
disabled={textProcessor.loading || forms.length === 0}
|
||||
onClick={handleResetAll}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className='border overflow-y-auto max-h-[17.4rem] min-h-[17.4rem] mb-2'>
|
||||
<DataTable
|
||||
data={forms}
|
||||
columns={columns}
|
||||
headPosition='0'
|
||||
dense
|
||||
|
||||
noDataComponent={
|
||||
<span className='flex flex-col justify-center p-2 text-center min-h-[2rem]'>
|
||||
<p>Список пуст</p>
|
||||
<p>Добавьте словоформу</p>
|
||||
</span>
|
||||
}
|
||||
|
||||
onRowDoubleClicked={handleRowClicked}
|
||||
onRowClicked={handleRowClicked}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -362,6 +362,7 @@ function EditorItems({ onOpenEdit, onCreateCst, onDeleteCst }: EditorItemsProps)
|
|||
<DataTable
|
||||
data={schema?.items ?? []}
|
||||
columns={columns}
|
||||
headPosition='2.2rem'
|
||||
dense
|
||||
|
||||
onRowDoubleClicked={handleRowDoubleClicked}
|
||||
|
|
|
@ -209,6 +209,7 @@ function ViewSideConstituents({ expression, baseHeight, activeID, onOpenEdit }:
|
|||
data={filteredData}
|
||||
columns={columns}
|
||||
conditionalRowStyles={conditionalRowStyles}
|
||||
headPosition='0'
|
||||
dense
|
||||
|
||||
enableHiding
|
||||
|
|
|
@ -47,12 +47,13 @@ function ViewSubscriptions({items}: ViewSubscriptionsProps) {
|
|||
], [intl]);
|
||||
|
||||
return (
|
||||
<div className='h-full overflow-auto text-sm border w-fit'>
|
||||
<div className='max-h-[23.8rem] overflow-auto text-sm border w-fit'>
|
||||
<DataTable
|
||||
columns={columns}
|
||||
data={items}
|
||||
|
||||
headPosition='0'
|
||||
dense
|
||||
|
||||
enableSorting
|
||||
initialSorting={{
|
||||
id: 'time_update',
|
||||
|
|
|
@ -210,7 +210,7 @@ export function domTooltipSyntacticReference(ref: ISyntacticReference, masterRef
|
|||
dom.className = `${DIMENSIONS} ${LAYOUT} border shadow-md text-sm select-none cursor-auto`;
|
||||
|
||||
const title = document.createElement('p');
|
||||
title.innerHTML = '<b>Синтаксическая ссылка</b>';
|
||||
title.innerHTML = '<b>Связывание слов</b>';
|
||||
dom.appendChild(title);
|
||||
|
||||
const offset = document.createElement('p');
|
||||
|
|
|
@ -34,6 +34,7 @@ export const globalIDs = {
|
|||
|
||||
export const prefixes = {
|
||||
cst_list: 'cst-list-',
|
||||
cst_wordform_list: 'cst-wordform-list-',
|
||||
cst_status_list: 'cst-status-list-',
|
||||
topic_list: 'topic-list-',
|
||||
library_list: 'library-list-',
|
||||
|
|
|
@ -239,7 +239,7 @@ export function labelCstType(type: CstType): string {
|
|||
export function labelReferenceType(type: ReferenceType): string {
|
||||
switch(type) {
|
||||
case ReferenceType.ENTITY: return 'Использование термина';
|
||||
case ReferenceType.SYNTACTIC: return 'Синтаксическая зависимость';
|
||||
case ReferenceType.SYNTACTIC: return 'Связывание слов';
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user