mirror of
https://github.com/IRBorisov/ConceptPortal.git
synced 2025-06-26 13:00:39 +03:00
UI topics list refactoring
This commit is contained in:
parent
18336cebe3
commit
22ef6b1886
2
TODO.txt
2
TODO.txt
|
@ -19,7 +19,7 @@ For more specific TODOs see comments in code
|
||||||
- User notifications on edit - consider spam prevention and change aggregation
|
- User notifications on edit - consider spam prevention and change aggregation
|
||||||
- Static analyzer for RSForm
|
- Static analyzer for RSForm
|
||||||
- Content based search in Library
|
- Content based search in Library
|
||||||
- User profile: Settings
|
- User profile: Settings + settings persistency
|
||||||
|
|
||||||
- Export PDF (Items list, Graph)
|
- Export PDF (Items list, Graph)
|
||||||
- ARIA (accessibility considerations) - for now machine reading not supported
|
- ARIA (accessibility considerations) - for now machine reading not supported
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import { HelpTopic } from '@/models/miscellaneous';
|
import { HelpTopic } from '@/models/miscellaneous';
|
||||||
|
|
||||||
import HelpAPI from '../man/HelpAPI';
|
import HelpAPI from '../man/HelpAPI';
|
||||||
|
import HelpConcept from '../man/HelpConcept';
|
||||||
import HelpConceptRelations from '../man/HelpConceptRelations';
|
import HelpConceptRelations from '../man/HelpConceptRelations';
|
||||||
import HelpConceptSystem from '../man/HelpConceptSystem';
|
import HelpConceptSystem from '../man/HelpConceptSystem';
|
||||||
import HelpCstAttributes from '../man/HelpCstAttributes';
|
import HelpCstAttributes from '../man/HelpCstAttributes';
|
||||||
|
@ -42,10 +43,12 @@ function InfoTopic({ topic }: InfoTopicProps) {
|
||||||
if (topic === HelpTopic.CST_STATUS) return <HelpCstStatus />;
|
if (topic === HelpTopic.CST_STATUS) return <HelpCstStatus />;
|
||||||
if (topic === HelpTopic.CST_CLASS) return <HelpCstClass />;
|
if (topic === HelpTopic.CST_CLASS) return <HelpCstClass />;
|
||||||
|
|
||||||
if (topic === HelpTopic.RSLANG) return <HelpRSLang />;
|
if (topic === HelpTopic.CONCEPTUAL) return <HelpConcept />;
|
||||||
if (topic === HelpTopic.CC_SYSTEM) return <HelpConceptSystem />;
|
if (topic === HelpTopic.CC_SYSTEM) return <HelpConceptSystem />;
|
||||||
if (topic === HelpTopic.CC_CONSTITUENTA) return <HelpCstAttributes />;
|
if (topic === HelpTopic.CC_CONSTITUENTA) return <HelpCstAttributes />;
|
||||||
if (topic === HelpTopic.CC_RELATIONS) return <HelpConceptRelations />;
|
if (topic === HelpTopic.CC_RELATIONS) return <HelpConceptRelations />;
|
||||||
|
|
||||||
|
if (topic === HelpTopic.RSLANG) return <HelpRSLang />;
|
||||||
if (topic === HelpTopic.RSL_TYPES) return <HelpRSLangTypes />;
|
if (topic === HelpTopic.RSL_TYPES) return <HelpRSLangTypes />;
|
||||||
if (topic === HelpTopic.RSL_CORRECT) return <HelpRSLangCorrect />;
|
if (topic === HelpTopic.RSL_CORRECT) return <HelpRSLangCorrect />;
|
||||||
if (topic === HelpTopic.RSL_INTERPRET) return <HelpRSLangInterpret />;
|
if (topic === HelpTopic.RSL_INTERPRET) return <HelpRSLangInterpret />;
|
||||||
|
|
|
@ -7,7 +7,7 @@ function HelpCstAttributes() {
|
||||||
// prettier-ignore
|
// prettier-ignore
|
||||||
return (
|
return (
|
||||||
<div className='dense'>
|
<div className='dense'>
|
||||||
<h1>Аттрибуты конституенты</h1>
|
<h1>Атрибуты конституенты</h1>
|
||||||
<p><b>Термин</b> может быть присвоен любой конституенте. Он используется в других Терминах и в Текстовых определениях</p>
|
<p><b>Термин</b> может быть присвоен любой конституенте. Он используется в других Терминах и в Текстовых определениях</p>
|
||||||
<p><b>Формальное определение</b> строится с помощью формального аппарата <TextURL text='родоструктурной экспликации' href={urls.help_topic(HelpTopic.RSLANG)}/></p>
|
<p><b>Формальное определение</b> строится с помощью формального аппарата <TextURL text='родоструктурной экспликации' href={urls.help_topic(HelpTopic.RSLANG)}/></p>
|
||||||
<p><b>Типизация</b> вычисляется автоматически на основе Формального определения и отражает структуру элементов множества, задаваемого этим определением</p>
|
<p><b>Типизация</b> вычисляется автоматически на основе Формального определения и отражает структуру элементов множества, задаваемого этим определением</p>
|
||||||
|
|
|
@ -71,7 +71,7 @@ function TableBody<TData>({
|
||||||
<tr
|
<tr
|
||||||
key={row.id}
|
key={row.id}
|
||||||
className={clsx(
|
className={clsx(
|
||||||
'cc-table-row',
|
'cc-scroll-row',
|
||||||
!noHeader && 'scroll-mt-[calc(2px+2rem)]',
|
!noHeader && 'scroll-mt-[calc(2px+2rem)]',
|
||||||
row.getIsSelected()
|
row.getIsSelected()
|
||||||
? 'clr-selected clr-hover'
|
? 'clr-selected clr-hover'
|
||||||
|
|
|
@ -10,17 +10,17 @@ import { useConceptOptions } from '@/context/OptionsContext';
|
||||||
import useDropdown from '@/hooks/useDropdown';
|
import useDropdown from '@/hooks/useDropdown';
|
||||||
import { HelpTopic } from '@/models/miscellaneous';
|
import { HelpTopic } from '@/models/miscellaneous';
|
||||||
import { animateSlideLeft } from '@/styling/animations';
|
import { animateSlideLeft } from '@/styling/animations';
|
||||||
import { prefixes } from '@/utils/constants';
|
|
||||||
import { describeHelpTopic, labelHelpTopic } from '@/utils/labels';
|
|
||||||
|
|
||||||
interface TopicsListDropDownProps {
|
import TopicsTree from './TopicsTree';
|
||||||
|
|
||||||
|
interface TopicsDropdownProps {
|
||||||
activeTopic: HelpTopic;
|
activeTopic: HelpTopic;
|
||||||
onChangeTopic: (newTopic: HelpTopic) => void;
|
onChangeTopic: (newTopic: HelpTopic) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
function TopicsListDropDown({ activeTopic, onChangeTopic }: TopicsListDropDownProps) {
|
function TopicsDropdown({ activeTopic, onChangeTopic }: TopicsDropdownProps) {
|
||||||
const menu = useDropdown();
|
const menu = useDropdown();
|
||||||
const { noNavigation } = useConceptOptions();
|
const { noNavigation, calculateHeight } = useConceptOptions();
|
||||||
|
|
||||||
const selectTheme = useCallback(
|
const selectTheme = useCallback(
|
||||||
(topic: HelpTopic) => {
|
(topic: HelpTopic) => {
|
||||||
|
@ -34,7 +34,7 @@ function TopicsListDropDown({ activeTopic, onChangeTopic }: TopicsListDropDownPr
|
||||||
<div
|
<div
|
||||||
ref={menu.ref}
|
ref={menu.ref}
|
||||||
className={clsx(
|
className={clsx(
|
||||||
'absolute left-0', // prettier: split-lines
|
'absolute left-0 w-[13rem]', // prettier: split-lines
|
||||||
'flex flex-col',
|
'flex flex-col',
|
||||||
'z-modal-tooltip',
|
'z-modal-tooltip',
|
||||||
'text-xs sm:text-sm',
|
'text-xs sm:text-sm',
|
||||||
|
@ -51,34 +51,20 @@ function TopicsListDropDown({ activeTopic, onChangeTopic }: TopicsListDropDownPr
|
||||||
title='Список тем'
|
title='Список тем'
|
||||||
hideTitle={menu.isOpen}
|
hideTitle={menu.isOpen}
|
||||||
icon={!menu.isOpen ? <IconMenuUnfold size='1.25rem' /> : <IconMenuFold size='1.25rem' />}
|
icon={!menu.isOpen ? <IconMenuUnfold size='1.25rem' /> : <IconMenuFold size='1.25rem' />}
|
||||||
className='w-[3rem] h-7'
|
className='w-[3rem] h-7 rounded-none'
|
||||||
onClick={menu.toggle}
|
onClick={menu.toggle}
|
||||||
/>
|
/>
|
||||||
<motion.div
|
<motion.div
|
||||||
className='border-x'
|
className='border divide-y rounded-none cc-scroll-y'
|
||||||
|
style={{ maxHeight: calculateHeight('4rem + 2px') }}
|
||||||
initial={false}
|
initial={false}
|
||||||
animate={menu.isOpen ? 'open' : 'closed'}
|
animate={menu.isOpen ? 'open' : 'closed'}
|
||||||
variants={animateSlideLeft}
|
variants={animateSlideLeft}
|
||||||
>
|
>
|
||||||
{Object.values(HelpTopic).map((topic, index) => (
|
<TopicsTree activeTopic={activeTopic} onChangeTopic={selectTheme} />
|
||||||
<div
|
|
||||||
key={`${prefixes.topic_list}${index}`}
|
|
||||||
className={clsx(
|
|
||||||
'px-3 py-1',
|
|
||||||
'border-y',
|
|
||||||
'clr-controls clr-hover',
|
|
||||||
'cursor-pointer',
|
|
||||||
activeTopic === topic && 'clr-selected'
|
|
||||||
)}
|
|
||||||
title={describeHelpTopic(topic)}
|
|
||||||
onClick={() => selectTheme(topic)}
|
|
||||||
>
|
|
||||||
{labelHelpTopic(topic)}
|
|
||||||
</div>
|
|
||||||
))}
|
|
||||||
</motion.div>
|
</motion.div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default TopicsListDropDown;
|
export default TopicsDropdown;
|
|
@ -3,8 +3,8 @@
|
||||||
import useWindowSize from '@/hooks/useWindowSize';
|
import useWindowSize from '@/hooks/useWindowSize';
|
||||||
import { HelpTopic } from '@/models/miscellaneous';
|
import { HelpTopic } from '@/models/miscellaneous';
|
||||||
|
|
||||||
import TopicsListDropDown from './TopicsListDropdown';
|
import TopicsDropdown from './TopicsDropdown';
|
||||||
import TopicsListStatic from './TopicsListStatic';
|
import TopicsStatic from './TopicsStatic';
|
||||||
|
|
||||||
interface TopicsListProps {
|
interface TopicsListProps {
|
||||||
activeTopic: HelpTopic;
|
activeTopic: HelpTopic;
|
||||||
|
@ -15,9 +15,9 @@ function TopicsList({ activeTopic, onChangeTopic }: TopicsListProps) {
|
||||||
const size = useWindowSize();
|
const size = useWindowSize();
|
||||||
|
|
||||||
if (!size.isSmall) {
|
if (!size.isSmall) {
|
||||||
return <TopicsListStatic activeTopic={activeTopic} onChangeTopic={onChangeTopic} />;
|
return <TopicsStatic activeTopic={activeTopic} onChangeTopic={onChangeTopic} />;
|
||||||
} else {
|
} else {
|
||||||
return <TopicsListDropDown activeTopic={activeTopic} onChangeTopic={onChangeTopic} />;
|
return <TopicsDropdown activeTopic={activeTopic} onChangeTopic={onChangeTopic} />;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
33
rsconcept/frontend/src/pages/ManualsPage/TopicsStatic.tsx
Normal file
33
rsconcept/frontend/src/pages/ManualsPage/TopicsStatic.tsx
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
import clsx from 'clsx';
|
||||||
|
|
||||||
|
import { useConceptOptions } from '@/context/OptionsContext';
|
||||||
|
import { HelpTopic } from '@/models/miscellaneous';
|
||||||
|
|
||||||
|
import TopicsTree from './TopicsTree';
|
||||||
|
|
||||||
|
interface TopicsStaticProps {
|
||||||
|
activeTopic: HelpTopic;
|
||||||
|
onChangeTopic: (newTopic: HelpTopic) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
function TopicsStatic({ activeTopic, onChangeTopic }: TopicsStaticProps) {
|
||||||
|
const { calculateHeight } = useConceptOptions();
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className={clsx(
|
||||||
|
'sticky top-0 left-0',
|
||||||
|
'w-[14rem] cc-scroll-y',
|
||||||
|
'self-start',
|
||||||
|
'border divide-y rounded-none',
|
||||||
|
'clr-controls',
|
||||||
|
'text-xs sm:text-sm',
|
||||||
|
'select-none'
|
||||||
|
)}
|
||||||
|
style={{ maxHeight: calculateHeight('2.25rem + 2px') }}
|
||||||
|
>
|
||||||
|
<TopicsTree activeTopic={activeTopic} onChangeTopic={onChangeTopic} />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default TopicsStatic;
|
|
@ -1,33 +1,26 @@
|
||||||
|
'use client';
|
||||||
|
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
|
import { AnimatePresence } from 'framer-motion';
|
||||||
|
|
||||||
import { HelpTopic } from '@/models/miscellaneous';
|
import { HelpTopic } from '@/models/miscellaneous';
|
||||||
import { prefixes } from '@/utils/constants';
|
import { prefixes } from '@/utils/constants';
|
||||||
import { describeHelpTopic, labelHelpTopic } from '@/utils/labels';
|
import { describeHelpTopic, labelHelpTopic } from '@/utils/labels';
|
||||||
|
|
||||||
interface TopicsListStaticProps {
|
interface TopicsTreeProps {
|
||||||
activeTopic: HelpTopic;
|
activeTopic: HelpTopic;
|
||||||
onChangeTopic: (newTopic: HelpTopic) => void;
|
onChangeTopic: (newTopic: HelpTopic) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
function TopicsListStatic({ activeTopic, onChangeTopic }: TopicsListStaticProps) {
|
function TopicsTree({ activeTopic, onChangeTopic }: TopicsTreeProps) {
|
||||||
return (
|
return (
|
||||||
<div
|
<AnimatePresence initial={false}>
|
||||||
className={clsx(
|
|
||||||
'sticky top-0 left-0',
|
|
||||||
'self-start',
|
|
||||||
'border-x',
|
|
||||||
'clr-controls',
|
|
||||||
'text-xs sm:text-sm',
|
|
||||||
'select-none'
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
{Object.values(HelpTopic).map((topic, index) => (
|
{Object.values(HelpTopic).map((topic, index) => (
|
||||||
<div
|
<div
|
||||||
key={`${prefixes.topic_list}${index}`}
|
key={`${prefixes.topic_list}${index}`}
|
||||||
className={clsx(
|
className={clsx(
|
||||||
'px-3 py-1',
|
'px-3 py-1 cc-scroll-row',
|
||||||
'border-y',
|
'clr-controls clr-hover',
|
||||||
'clr-hover',
|
|
||||||
'cursor-pointer',
|
'cursor-pointer',
|
||||||
activeTopic === topic && 'clr-selected'
|
activeTopic === topic && 'clr-selected'
|
||||||
)}
|
)}
|
||||||
|
@ -37,8 +30,8 @@ function TopicsListStatic({ activeTopic, onChangeTopic }: TopicsListStaticProps)
|
||||||
{labelHelpTopic(topic)}
|
{labelHelpTopic(topic)}
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
</div>
|
</AnimatePresence>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default TopicsListStatic;
|
export default TopicsTree;
|
|
@ -231,7 +231,7 @@
|
||||||
@apply flex gap-1;
|
@apply flex gap-1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.cc-table-row {
|
.cc-scroll-row {
|
||||||
scroll-snap-align: start;
|
scroll-snap-align: start;
|
||||||
scroll-snap-stop: always;
|
scroll-snap-stop: always;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user