mirror of
https://github.com/IRBorisov/ConceptPortal.git
synced 2025-06-26 21:10:38 +03:00
Improve dynamic sizes in ConstituentaEdit
This commit is contained in:
parent
27f515f5d3
commit
e9eed37aee
|
@ -1,9 +1,18 @@
|
||||||
import { ThreeDots } from 'react-loader-spinner';
|
import { ThreeDots } from 'react-loader-spinner';
|
||||||
|
|
||||||
export function Loader() {
|
interface LoaderProps {
|
||||||
|
size?: number
|
||||||
|
}
|
||||||
|
|
||||||
|
export function Loader({size=10}: LoaderProps) {
|
||||||
return (
|
return (
|
||||||
<div className='flex justify-center w-full h-full'>
|
<div className='flex justify-center w-full h-full'>
|
||||||
<ThreeDots color='rgb(96 165 250)' height='100' width='100' radius='10' />
|
<ThreeDots
|
||||||
|
color='rgb(96 165 250)'
|
||||||
|
height={size*10}
|
||||||
|
width={size*10}
|
||||||
|
radius={size}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,9 @@ import { getCstTypeLabel, getCstTypificationLabel, mapStatusInfo } from '../../u
|
||||||
import EditorRSExpression from './EditorRSExpression';
|
import EditorRSExpression from './EditorRSExpression';
|
||||||
import ViewSideConstituents from './elements/ViewSideConstituents';
|
import ViewSideConstituents from './elements/ViewSideConstituents';
|
||||||
|
|
||||||
|
// Max height of content for left enditor pane
|
||||||
|
const UNFOLDED_HEIGHT = '59.1rem';
|
||||||
|
|
||||||
interface EditorConstituentaProps {
|
interface EditorConstituentaProps {
|
||||||
activeID?: number
|
activeID?: number
|
||||||
onOpenEdit: (cstID: number) => void
|
onOpenEdit: (cstID: number) => void
|
||||||
|
@ -109,8 +112,8 @@ function EditorConstituenta({ activeID, onShowAST, onCreateCst, onOpenEdit, onDe
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='flex items-stretch w-full gap-2 mb-2'>
|
<div className='flex items-stretch w-full gap-2 mb-2 justify-stretch'>
|
||||||
<form onSubmit={handleSubmit} className='flex-grow min-w-[50rem] max-w-min max-h-fit px-4 py-2 border'>
|
<form onSubmit={handleSubmit} className='min-w-[50rem] max-w-min px-4 py-2 border'>
|
||||||
<div className='flex items-start justify-between'>
|
<div className='flex items-start justify-between'>
|
||||||
<button type='submit'
|
<button type='submit'
|
||||||
title='Сохранить изменения'
|
title='Сохранить изменения'
|
||||||
|
@ -238,11 +241,14 @@ function EditorConstituenta({ activeID, onShowAST, onCreateCst, onOpenEdit, onDe
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
<ViewSideConstituents
|
<div className='self-stretch border w-full pb-1'>
|
||||||
expression={expression}
|
<ViewSideConstituents
|
||||||
activeID={activeID}
|
expression={expression}
|
||||||
onOpenEdit={onOpenEdit}
|
baseHeight={UNFOLDED_HEIGHT}
|
||||||
/>
|
activeID={activeID}
|
||||||
|
onOpenEdit={onOpenEdit}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -247,9 +247,9 @@ function EditorRSExpression({
|
||||||
</div>
|
</div>
|
||||||
{isActive && !disabled && EditButtons}
|
{isActive && !disabled && EditButtons}
|
||||||
</div>
|
</div>
|
||||||
{ (loading || parseData) &&
|
{ (isActive || loading || parseData) &&
|
||||||
<div className='w-full overflow-y-auto border mt-2 max-h-[14rem] min-h-[7rem]'>
|
<div className='w-full overflow-y-auto border mt-2 max-h-[14rem] min-h-[4.2rem]'>
|
||||||
{ loading && <Loader />}
|
{ loading && <Loader size={6} />}
|
||||||
{ !loading && parseData &&
|
{ !loading && parseData &&
|
||||||
<ParsingResult
|
<ParsingResult
|
||||||
data={parseData}
|
data={parseData}
|
||||||
|
|
|
@ -33,9 +33,8 @@ function ParsingResult({ data, onShowAST, onShowError }: ParsingResultProps) {
|
||||||
title='отобразить дерево разбора'
|
title='отобразить дерево разбора'
|
||||||
onClick={handleShowAST}
|
onClick={handleShowAST}
|
||||||
>
|
>
|
||||||
Дерево разбора:
|
Дерево разбора
|
||||||
</button>
|
</button>
|
||||||
<span> {data.astText}</span>
|
|
||||||
</p>}
|
</p>}
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|
|
@ -11,14 +11,18 @@ import ConstituentaTooltip from './ConstituentaTooltip';
|
||||||
import DependencyModePicker from './DependencyModePicker';
|
import DependencyModePicker from './DependencyModePicker';
|
||||||
import MatchModePicker from './MatchModePicker';
|
import MatchModePicker from './MatchModePicker';
|
||||||
|
|
||||||
|
// Height that should be left to accomodate navigation panel + bottom margin
|
||||||
|
const LOCAL_NAVIGATION_H = '2.6rem';
|
||||||
|
|
||||||
interface ViewSideConstituentsProps {
|
interface ViewSideConstituentsProps {
|
||||||
expression: string
|
expression: string
|
||||||
|
baseHeight: string
|
||||||
activeID?: number
|
activeID?: number
|
||||||
onOpenEdit: (cstID: number) => void
|
onOpenEdit: (cstID: number) => void
|
||||||
}
|
}
|
||||||
|
|
||||||
function ViewSideConstituents({ expression, activeID, onOpenEdit }: ViewSideConstituentsProps) {
|
function ViewSideConstituents({ expression, baseHeight, activeID, onOpenEdit }: ViewSideConstituentsProps) {
|
||||||
const { darkMode } = useConceptTheme();
|
const { darkMode, noNavigation } = useConceptTheme();
|
||||||
const { schema } = useRSForm();
|
const { schema } = useRSForm();
|
||||||
|
|
||||||
const [filterMatch, setFilterMatch] = useLocalStorage('side-filter-match', CstMatchMode.ALL);
|
const [filterMatch, setFilterMatch] = useLocalStorage('side-filter-match', CstMatchMode.ALL);
|
||||||
|
@ -27,7 +31,8 @@ function ViewSideConstituents({ expression, activeID, onOpenEdit }: ViewSideCons
|
||||||
|
|
||||||
const [filteredData, setFilteredData] = useState<IConstituenta[]>(schema?.items ?? []);
|
const [filteredData, setFilteredData] = useState<IConstituenta[]>(schema?.items ?? []);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(
|
||||||
|
() => {
|
||||||
if (!schema?.items) {
|
if (!schema?.items) {
|
||||||
setFilteredData([]);
|
setFilteredData([]);
|
||||||
return;
|
return;
|
||||||
|
@ -67,8 +72,8 @@ function ViewSideConstituents({ expression, activeID, onOpenEdit }: ViewSideCons
|
||||||
}
|
}
|
||||||
}, [onOpenEdit]);
|
}, [onOpenEdit]);
|
||||||
|
|
||||||
const conditionalRowStyles = useMemo(() =>
|
const conditionalRowStyles = useMemo(
|
||||||
[
|
() => [
|
||||||
{
|
{
|
||||||
when: (cst: IConstituenta) => cst.id === activeID,
|
when: (cst: IConstituenta) => cst.id === activeID,
|
||||||
style: {
|
style: {
|
||||||
|
@ -77,92 +82,101 @@ function ViewSideConstituents({ expression, activeID, onOpenEdit }: ViewSideCons
|
||||||
}
|
}
|
||||||
], [activeID, darkMode]);
|
], [activeID, darkMode]);
|
||||||
|
|
||||||
const columns = useMemo(() =>
|
const columns = useMemo(
|
||||||
[
|
() => [
|
||||||
{
|
{
|
||||||
id: 'id',
|
id: 'id',
|
||||||
selector: (cst: IConstituenta) => cst.id,
|
selector: (cst: IConstituenta) => cst.id,
|
||||||
omit: true
|
omit: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'ID',
|
||||||
|
id: 'alias',
|
||||||
|
cell: (cst: IConstituenta) => {
|
||||||
|
const info = mapStatusInfo.get(cst.status)!;
|
||||||
|
return (<>
|
||||||
|
<div
|
||||||
|
id={`${prefixes.cst_list}${cst.alias}`}
|
||||||
|
className={`w-full rounded-md text-center ${info.color}`}
|
||||||
|
>
|
||||||
|
{cst.alias}
|
||||||
|
</div>
|
||||||
|
<ConstituentaTooltip data={cst} anchor={`#${prefixes.cst_list}${cst.alias}`} />
|
||||||
|
</>);
|
||||||
},
|
},
|
||||||
{
|
width: '65px',
|
||||||
name: 'ID',
|
maxWidth: '65px',
|
||||||
id: 'alias',
|
conditionalCellStyles: [
|
||||||
cell: (cst: IConstituenta) => {
|
{
|
||||||
const info = mapStatusInfo.get(cst.status)!;
|
when: (cst: IConstituenta) => cst.id <= 0,
|
||||||
return (<>
|
classNames: ['bg-[#ffc9c9]', 'dark:bg-[#592b2b]']
|
||||||
<div
|
}
|
||||||
id={`${prefixes.cst_list}${cst.alias}`}
|
]
|
||||||
className={`w-full rounded-md text-center ${info.color}`}
|
},
|
||||||
>
|
{
|
||||||
{cst.alias}
|
name: 'Описание',
|
||||||
</div>
|
id: 'description',
|
||||||
<ConstituentaTooltip data={cst} anchor={`#${prefixes.cst_list}${cst.alias}`} />
|
selector: (cst: IConstituenta) => getCstDescription(cst),
|
||||||
</>);
|
minWidth: '350px',
|
||||||
},
|
wrap: true,
|
||||||
width: '65px',
|
conditionalCellStyles: [
|
||||||
maxWidth: '65px',
|
{
|
||||||
conditionalCellStyles: [
|
when: (cst: IConstituenta) => cst.id <= 0,
|
||||||
{
|
classNames: ['bg-[#ffc9c9]', 'dark:bg-[#592b2b]']
|
||||||
when: (cst: IConstituenta) => cst.id <= 0,
|
}
|
||||||
classNames: ['bg-[#ffc9c9]', 'dark:bg-[#592b2b]']
|
]
|
||||||
}
|
},
|
||||||
]
|
{
|
||||||
},
|
name: 'Выражение',
|
||||||
{
|
id: 'expression',
|
||||||
name: 'Описание',
|
selector: (cst: IConstituenta) => cst.definition?.formal ?? '',
|
||||||
id: 'description',
|
minWidth: '200px',
|
||||||
selector: (cst: IConstituenta) => getCstDescription(cst),
|
hide: 1600,
|
||||||
minWidth: '350px',
|
grow: 2,
|
||||||
wrap: true,
|
wrap: true,
|
||||||
conditionalCellStyles: [
|
conditionalCellStyles: [
|
||||||
{
|
{
|
||||||
when: (cst: IConstituenta) => cst.id <= 0,
|
when: (cst: IConstituenta) => cst.id <= 0,
|
||||||
classNames: ['bg-[#ffc9c9]', 'dark:bg-[#592b2b]']
|
classNames: ['bg-[#ffc9c9]', 'dark:bg-[#592b2b]']
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
}
|
||||||
{
|
], []);
|
||||||
name: 'Выражение',
|
|
||||||
id: 'expression',
|
|
||||||
selector: (cst: IConstituenta) => cst.definition?.formal ?? '',
|
|
||||||
minWidth: '200px',
|
|
||||||
hide: 1600,
|
|
||||||
grow: 2,
|
|
||||||
wrap: true,
|
|
||||||
conditionalCellStyles: [
|
|
||||||
{
|
|
||||||
when: (cst: IConstituenta) => cst.id <= 0,
|
|
||||||
classNames: ['bg-[#ffc9c9]', 'dark:bg-[#592b2b]']
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
], []
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
const maxHeight = useMemo(
|
||||||
<div className='max-h-[calc(100vh-10.3rem)] min-h-[40rem] overflow-y-scroll border flex-grow w-full'>
|
() => {
|
||||||
<div className='sticky top-0 left-0 right-0 z-10 flex items-center justify-between w-full gap-1 px-2 py-1 bg-white border-b rounded clr-bg-pop clr-border'>
|
const siblingHeight = `${baseHeight} - ${LOCAL_NAVIGATION_H}`
|
||||||
<div className='flex items-center justify-between w-full'>
|
return (noNavigation ?
|
||||||
<MatchModePicker value={filterMatch} onChange={setFilterMatch}/>
|
`calc(min(100vh - 5.2rem, ${siblingHeight}))`
|
||||||
<input type='text'
|
: `calc(min(100vh - 8.7rem, ${siblingHeight}))`);
|
||||||
className='w-full px-2 bg-white outline-none hover:text-clip clr-bg-pop clr-border'
|
}, [noNavigation, baseHeight]);
|
||||||
placeholder='наберите текст фильтра'
|
|
||||||
value={filterText}
|
return (<>
|
||||||
onChange={event => { setFilterText(event.target.value); }}
|
<div className='px-2 py-1 sticky top-0 left-0 right-0 z-10 gap-1 flex items-center justify-between w-full bg-white border-b rounded clr-bg-pop clr-border'>
|
||||||
/>
|
<MatchModePicker
|
||||||
<DependencyModePicker value={filterSource} onChange={setFilterSource}/>
|
value={filterMatch}
|
||||||
</div>
|
onChange={setFilterMatch}
|
||||||
</div>
|
/>
|
||||||
|
<input type='text'
|
||||||
|
className='w-full px-2 bg-white outline-none hover:text-clip clr-bg-pop clr-border'
|
||||||
|
placeholder='наберите текст фильтра'
|
||||||
|
value={filterText}
|
||||||
|
onChange={event => setFilterText(event.target.value)}
|
||||||
|
/>
|
||||||
|
<DependencyModePicker value={filterSource} onChange={setFilterSource}/>
|
||||||
|
</div>
|
||||||
|
<div className='overflow-y-auto' style={{maxHeight : `${maxHeight}`}}>
|
||||||
<ConceptDataTable
|
<ConceptDataTable
|
||||||
data={filteredData}
|
data={filteredData}
|
||||||
columns={columns}
|
columns={columns}
|
||||||
conditionalRowStyles={conditionalRowStyles}
|
|
||||||
keyField='id'
|
keyField='id'
|
||||||
noContextMenu
|
conditionalRowStyles={conditionalRowStyles}
|
||||||
noDataComponent={<span className='flex flex-col justify-center p-2 text-center'>
|
noDataComponent={
|
||||||
<p>Список конституент пуст</p>
|
<span className='flex flex-col justify-center p-2 text-center min-h-[5rem]'>
|
||||||
<p>Измените параметры фильтра</p>
|
<p>Список конституент пуст</p>
|
||||||
</span>}
|
<p>Измените параметры фильтра</p>
|
||||||
|
</span>
|
||||||
|
}
|
||||||
|
|
||||||
striped
|
striped
|
||||||
highlightOnHover
|
highlightOnHover
|
||||||
|
@ -173,7 +187,7 @@ function ViewSideConstituents({ expression, activeID, onOpenEdit }: ViewSideCons
|
||||||
dense
|
dense
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
</>);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default ViewSideConstituents;
|
export default ViewSideConstituents;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user