mirror of
https://github.com/IRBorisov/ConceptPortal.git
synced 2025-06-26 04:50:36 +03:00
Improve UI, start refactoring colors
This commit is contained in:
parent
337c037e99
commit
2feebec64d
8
.vscode/settings.json
vendored
8
.vscode/settings.json
vendored
|
@ -29,5 +29,13 @@
|
||||||
"name": "django",
|
"name": "django",
|
||||||
"depth": 5
|
"depth": 5
|
||||||
}
|
}
|
||||||
|
],
|
||||||
|
"colorize.include": [".tsx", ".jsx", ".ts", ".js"],
|
||||||
|
"colorize.languages": [
|
||||||
|
"typescript",
|
||||||
|
"javascript",
|
||||||
|
"css",
|
||||||
|
"typescriptreact",
|
||||||
|
"javascriptreact"
|
||||||
]
|
]
|
||||||
}
|
}
|
|
@ -53,7 +53,7 @@ This readme file is used mostly to document project dependencies
|
||||||
<summary>VS Code plugins</summary>
|
<summary>VS Code plugins</summary>
|
||||||
<pre>
|
<pre>
|
||||||
- ESLint
|
- ESLint
|
||||||
-
|
- Colorize
|
||||||
</pre>
|
</pre>
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@ function Footer() {
|
||||||
<Link to='/manuals' tabIndex={-1}>Справка</Link> <br/>
|
<Link to='/manuals' tabIndex={-1}>Справка</Link> <br/>
|
||||||
</div>
|
</div>
|
||||||
<div className=''>
|
<div className=''>
|
||||||
<a href={urls.concept} tabIndex={-1} className='underline'>Центр Концепт</a>
|
<p className='w-full text-center underline'><a href={urls.concept} tabIndex={-1} >Центр Концепт</a></p>
|
||||||
<p className='mt-0.5 text-center'>© 2023 ЦИВТ КОНЦЕПТ</p>
|
<p className='mt-0.5 text-center'>© 2023 ЦИВТ КОНЦЕПТ</p>
|
||||||
</div>
|
</div>
|
||||||
<div className='flex flex-col underline'>
|
<div className='flex flex-col underline'>
|
||||||
|
|
98
rsconcept/frontend/src/components/GraphThemes.ts
Normal file
98
rsconcept/frontend/src/components/GraphThemes.ts
Normal file
|
@ -0,0 +1,98 @@
|
||||||
|
export const lightTheme = {
|
||||||
|
canvas: {
|
||||||
|
background: '#f9fafb',
|
||||||
|
},
|
||||||
|
node: {
|
||||||
|
fill: '#7CA0AB',
|
||||||
|
activeFill: '#1DE9AC',
|
||||||
|
opacity: 1,
|
||||||
|
selectedOpacity: 1,
|
||||||
|
inactiveOpacity: 0.2,
|
||||||
|
label: {
|
||||||
|
color: '#2A6475',
|
||||||
|
stroke: '#fff',
|
||||||
|
activeColor: '#1DE9AC'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
lasso: {
|
||||||
|
border: '1px solid #55aaff',
|
||||||
|
background: 'rgba(75, 160, 255, 0.1)'
|
||||||
|
},
|
||||||
|
ring: {
|
||||||
|
fill: '#D8E6EA',
|
||||||
|
activeFill: '#1DE9AC'
|
||||||
|
},
|
||||||
|
edge: {
|
||||||
|
fill: '#D8E6EA',
|
||||||
|
activeFill: '#1DE9AC',
|
||||||
|
opacity: 1,
|
||||||
|
selectedOpacity: 1,
|
||||||
|
inactiveOpacity: 0.1,
|
||||||
|
label: {
|
||||||
|
stroke: '#fff',
|
||||||
|
color: '#2A6475',
|
||||||
|
activeColor: '#1DE9AC'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
arrow: {
|
||||||
|
fill: '#D8E6EA',
|
||||||
|
activeFill: '#1DE9AC'
|
||||||
|
},
|
||||||
|
cluster: {
|
||||||
|
stroke: '#D8E6EA',
|
||||||
|
label: {
|
||||||
|
stroke: '#fff',
|
||||||
|
color: '#2A6475'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export const darkTheme = {
|
||||||
|
canvas: {
|
||||||
|
background: '#1f2937'
|
||||||
|
},
|
||||||
|
node: {
|
||||||
|
fill: '#7A8C9E',
|
||||||
|
activeFill: '#1DE9AC',
|
||||||
|
opacity: 1,
|
||||||
|
selectedOpacity: 1,
|
||||||
|
inactiveOpacity: 0.2,
|
||||||
|
label: {
|
||||||
|
stroke: '#1E2026',
|
||||||
|
color: '#ACBAC7',
|
||||||
|
activeColor: '#1DE9AC'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
lasso: {
|
||||||
|
border: '1px solid #55aaff',
|
||||||
|
background: 'rgba(75, 160, 255, 0.1)'
|
||||||
|
},
|
||||||
|
ring: {
|
||||||
|
fill: '#54616D',
|
||||||
|
activeFill: '#1DE9AC'
|
||||||
|
},
|
||||||
|
edge: {
|
||||||
|
fill: '#474B56',
|
||||||
|
activeFill: '#1DE9AC',
|
||||||
|
opacity: 1,
|
||||||
|
selectedOpacity: 1,
|
||||||
|
inactiveOpacity: 0.1,
|
||||||
|
label: {
|
||||||
|
stroke: '#1E2026',
|
||||||
|
color: '#ACBAC7',
|
||||||
|
activeColor: '#1DE9AC'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
arrow: {
|
||||||
|
fill: '#474B56',
|
||||||
|
activeFill: '#1DE9AC'
|
||||||
|
},
|
||||||
|
cluster: {
|
||||||
|
stroke: '#474B56',
|
||||||
|
label: {
|
||||||
|
stroke: '#1E2026',
|
||||||
|
color: '#ACBAC7'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,19 +1,26 @@
|
||||||
|
import { useConceptTheme } from '../../context/ThemeContext';
|
||||||
import { prefixes } from '../../utils/constants';
|
import { prefixes } from '../../utils/constants';
|
||||||
import { mapCstClassInfo } from '../../utils/staticUI';
|
import { getCstClassColor, mapCstClassInfo } from '../../utils/staticUI';
|
||||||
|
|
||||||
interface InfoCstClassProps {
|
interface InfoCstClassProps {
|
||||||
title?: string
|
title?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
function InfoCstClass({ title }: InfoCstClassProps) {
|
function InfoCstClass({ title }: InfoCstClassProps) {
|
||||||
|
const { colors } = useConceptTheme();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='flex flex-col gap-1'>
|
<div className='flex flex-col gap-1'>
|
||||||
{ title && <h1>{title}</h1>}
|
{ title && <h1>{title}</h1>}
|
||||||
{ [... mapCstClassInfo.values()].map(
|
{ [... mapCstClassInfo.entries()].map(
|
||||||
(info, index) => {
|
([cstClass, info], index) => {
|
||||||
return (
|
return (
|
||||||
<p key={`${prefixes.cst_status_list}${index}`}>
|
<p key={`${prefixes.cst_status_list}${index}`}>
|
||||||
<span className={`px-1 inline-block font-semibold min-w-[6.5rem] text-center border ${info.color}`}>
|
<span
|
||||||
|
className='px-1 inline-block font-semibold min-w-[6.5rem] text-center borde'
|
||||||
|
style={{backgroundColor: getCstClassColor(cstClass, colors)}}
|
||||||
|
|
||||||
|
>
|
||||||
{info.text}
|
{info.text}
|
||||||
</span>
|
</span>
|
||||||
<span> - </span>
|
<span> - </span>
|
||||||
|
|
|
@ -1,19 +1,25 @@
|
||||||
|
import { useConceptTheme } from '../../context/ThemeContext';
|
||||||
import { prefixes } from '../../utils/constants';
|
import { prefixes } from '../../utils/constants';
|
||||||
import { mapStatusInfo } from '../../utils/staticUI';
|
import { getCstStatusColor, mapStatusInfo } from '../../utils/staticUI';
|
||||||
|
|
||||||
interface InfoCstStatusProps {
|
interface InfoCstStatusProps {
|
||||||
title?: string
|
title?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
function InfoCstStatus({ title }: InfoCstStatusProps) {
|
function InfoCstStatus({ title }: InfoCstStatusProps) {
|
||||||
|
const { colors } = useConceptTheme();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='flex flex-col gap-1'>
|
<div className='flex flex-col gap-1'>
|
||||||
{ title && <h1>{title}</h1>}
|
{ title && <h1>{title}</h1>}
|
||||||
{ [... mapStatusInfo.values()].map(
|
{ [... mapStatusInfo.entries()].map(
|
||||||
(info, index) => {
|
([status, info], index) => {
|
||||||
return (
|
return (
|
||||||
<p key={`${prefixes.cst_status_list}${index}`}>
|
<p key={`${prefixes.cst_status_list}${index}`}>
|
||||||
<span className={`px-1 inline-block font-semibold min-w-[4rem] text-center border ${info.color}`}>
|
<span
|
||||||
|
className='px-1 inline-block font-semibold min-w-[4rem] text-center border'
|
||||||
|
style={{backgroundColor: getCstStatusColor(status, colors)}}
|
||||||
|
>
|
||||||
{info.text}
|
{info.text}
|
||||||
</span>
|
</span>
|
||||||
<span> - </span>
|
<span> - </span>
|
||||||
|
|
|
@ -43,16 +43,23 @@ export const LibraryState = ({ children }: LibraryStateProps) => {
|
||||||
const filter = useCallback(
|
const filter = useCallback(
|
||||||
(params: ILibraryFilter) => {
|
(params: ILibraryFilter) => {
|
||||||
let result = items;
|
let result = items;
|
||||||
if (params.ownedBy) {
|
if (params.is_owned) {
|
||||||
result = result.filter(item =>
|
result = result.filter(item => item.owner === user?.id);
|
||||||
item.owner === params.ownedBy
|
|
||||||
|| user?.subscriptions.includes(item.id));
|
|
||||||
}
|
}
|
||||||
if (params.is_common !== undefined) {
|
if (params.is_common !== undefined) {
|
||||||
result = result.filter(item => item.is_common === params.is_common);
|
result = result.filter(item => item.is_common === params.is_common);
|
||||||
}
|
}
|
||||||
if (params.queryMeta) {
|
if (params.is_canonical !== undefined) {
|
||||||
result = result.filter(item => matchLibraryItem(params.queryMeta!, item));
|
result = result.filter(item => item.is_canonical === params.is_canonical);
|
||||||
|
}
|
||||||
|
if (params.is_subscribed !== undefined) {
|
||||||
|
result = result.filter(item => user?.subscriptions.includes(item.id));
|
||||||
|
}
|
||||||
|
if (params.is_personal !== undefined) {
|
||||||
|
result = result.filter(item => user?.subscriptions.includes(item.id) || item.owner === user?.id);
|
||||||
|
}
|
||||||
|
if (params.query) {
|
||||||
|
result = result.filter(item => matchLibraryItem(params.query!, item));
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}, [items, user]);
|
}, [items, user]);
|
||||||
|
|
|
@ -1,12 +1,14 @@
|
||||||
import { createContext, useContext, useLayoutEffect, useMemo, useState } from 'react';
|
import { createContext, useContext, useLayoutEffect, useMemo, useState } from 'react';
|
||||||
|
|
||||||
import useLocalStorage from '../hooks/useLocalStorage';
|
import useLocalStorage from '../hooks/useLocalStorage';
|
||||||
|
import { darkT, IColorTheme, lightT } from '../utils/color';
|
||||||
|
|
||||||
interface IThemeContext {
|
interface IThemeContext {
|
||||||
darkMode: boolean
|
darkMode: boolean
|
||||||
noNavigation: boolean
|
noNavigation: boolean
|
||||||
viewportHeight: string
|
viewportHeight: string
|
||||||
mainHeight: string
|
mainHeight: string
|
||||||
|
colors: IColorTheme
|
||||||
toggleDarkMode: () => void
|
toggleDarkMode: () => void
|
||||||
toggleNoNavigation: () => void
|
toggleNoNavigation: () => void
|
||||||
}
|
}
|
||||||
|
@ -28,6 +30,7 @@ interface ThemeStateProps {
|
||||||
|
|
||||||
export const ThemeState = ({ children }: ThemeStateProps) => {
|
export const ThemeState = ({ children }: ThemeStateProps) => {
|
||||||
const [darkMode, setDarkMode] = useLocalStorage('darkMode', false);
|
const [darkMode, setDarkMode] = useLocalStorage('darkMode', false);
|
||||||
|
const [colors, setColors] = useState<IColorTheme>(lightT);
|
||||||
const [noNavigation, setNoNavigation] = useState(false);
|
const [noNavigation, setNoNavigation] = useState(false);
|
||||||
|
|
||||||
const setDarkClass = (isDark: boolean) => {
|
const setDarkClass = (isDark: boolean) => {
|
||||||
|
@ -44,6 +47,10 @@ export const ThemeState = ({ children }: ThemeStateProps) => {
|
||||||
setDarkClass(darkMode)
|
setDarkClass(darkMode)
|
||||||
}, [darkMode]);
|
}, [darkMode]);
|
||||||
|
|
||||||
|
useLayoutEffect(() => {
|
||||||
|
setColors(darkMode ? darkT : lightT)
|
||||||
|
}, [darkMode, setColors]);
|
||||||
|
|
||||||
const mainHeight = useMemo(
|
const mainHeight = useMemo(
|
||||||
() => {
|
() => {
|
||||||
return !noNavigation ?
|
return !noNavigation ?
|
||||||
|
@ -60,7 +67,7 @@ export const ThemeState = ({ children }: ThemeStateProps) => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ThemeContext.Provider value={{
|
<ThemeContext.Provider value={{
|
||||||
darkMode,
|
darkMode, colors,
|
||||||
noNavigation,
|
noNavigation,
|
||||||
toggleDarkMode: () => setDarkMode(prev => !prev),
|
toggleDarkMode: () => setDarkMode(prev => !prev),
|
||||||
toggleNoNavigation: () => setNoNavigation(prev => !prev),
|
toggleNoNavigation: () => setNoNavigation(prev => !prev),
|
||||||
|
|
|
@ -6,15 +6,29 @@ import { useAuth } from '../../context/AuthContext';
|
||||||
import { ILibraryFilter } from '../../utils/models';
|
import { ILibraryFilter } from '../../utils/models';
|
||||||
|
|
||||||
interface SearchPanelProps {
|
interface SearchPanelProps {
|
||||||
filter: ILibraryFilter
|
|
||||||
setFilter: React.Dispatch<React.SetStateAction<ILibraryFilter>>
|
setFilter: React.Dispatch<React.SetStateAction<ILibraryFilter>>
|
||||||
}
|
}
|
||||||
|
|
||||||
function SearchPanel({ filter, setFilter }: SearchPanelProps) {
|
function SearchPanel({ setFilter }: SearchPanelProps) {
|
||||||
const search = useLocation().search;
|
const search = useLocation().search;
|
||||||
const { user } = useAuth();
|
const { user } = useAuth();
|
||||||
|
|
||||||
const [query, setQuery] = useState('')
|
const [query, setQuery] = useState('');
|
||||||
|
|
||||||
|
function handleChangeQuery(event: React.ChangeEvent<HTMLInputElement>) {
|
||||||
|
const newQuery = event.target.value;
|
||||||
|
setQuery(newQuery);
|
||||||
|
setFilter(prev => {
|
||||||
|
return {
|
||||||
|
query: newQuery,
|
||||||
|
is_owned: prev.is_owned,
|
||||||
|
is_common: prev.is_common,
|
||||||
|
is_canonical: prev.is_canonical,
|
||||||
|
is_subscribed: prev.is_subscribed,
|
||||||
|
is_personal: prev.is_personal
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
useLayoutEffect(() => {
|
useLayoutEffect(() => {
|
||||||
const filterType = new URLSearchParams(search).get('filter');
|
const filterType = new URLSearchParams(search).get('filter');
|
||||||
|
@ -26,23 +40,23 @@ function SearchPanel({ filter, setFilter }: SearchPanelProps) {
|
||||||
} else if (filterType === 'personal' && user) {
|
} else if (filterType === 'personal' && user) {
|
||||||
setQuery('');
|
setQuery('');
|
||||||
setFilter({
|
setFilter({
|
||||||
ownedBy: user.id!
|
is_personal: true
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}, [user, search, setQuery, setFilter]);
|
}, [user, search, setQuery, setFilter]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='sticky top-0 left-0 right-0 z-10 flex justify-center w-full border-b clr-bg-pop'>
|
<div className='sticky top-0 left-0 right-0 z-10 flex justify-center w-full border-b clr-input'>
|
||||||
<div className='relative w-96'>
|
<div className='relative w-96 min-w-[10rem]'>
|
||||||
<div className='absolute inset-y-0 left-0 flex items-center pl-3 pointer-events-none'>
|
<div className='absolute inset-y-0 left-0 flex items-center pl-3 pointer-events-none'>
|
||||||
<MagnifyingGlassIcon />
|
<MagnifyingGlassIcon />
|
||||||
</div>
|
</div>
|
||||||
<input
|
<input
|
||||||
type='text'
|
type='text'
|
||||||
value={query}
|
value={query}
|
||||||
className='w-full p-2 pl-10 text-sm outline-none clr-bg-pop border-x clr-border'
|
className='w-full p-2 pl-10 text-sm outline-none clr-input border-x clr-border'
|
||||||
placeholder='Поиск схемы...'
|
placeholder='Поиск схемы...'
|
||||||
onChange={data => setQuery(data.target.value)}
|
onChange={handleChangeQuery}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -10,13 +10,13 @@ import ViewLibrary from './ViewLibrary';
|
||||||
function LibraryPage() {
|
function LibraryPage() {
|
||||||
const library = useLibrary();
|
const library = useLibrary();
|
||||||
|
|
||||||
const [ filterParams, setFilterParams ] = useState<ILibraryFilter>({});
|
const [ filter, setFilter ] = useState<ILibraryFilter>({});
|
||||||
const [ items, setItems ] = useState<ILibraryItem[]>([]);
|
const [ items, setItems ] = useState<ILibraryItem[]>([]);
|
||||||
|
|
||||||
useLayoutEffect(() => {
|
useLayoutEffect(
|
||||||
const filter = filterParams;
|
() => {
|
||||||
setItems(library.filter(filter));
|
setItems(library.filter(filter));
|
||||||
}, [library, filterParams]);
|
}, [library, filter, filter.query]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='w-full'>
|
<div className='w-full'>
|
||||||
|
@ -25,11 +25,10 @@ function LibraryPage() {
|
||||||
{ !library.loading && library.items &&
|
{ !library.loading && library.items &&
|
||||||
<div className='flex flex-col w-full'>
|
<div className='flex flex-col w-full'>
|
||||||
<SearchPanel
|
<SearchPanel
|
||||||
filter={filterParams}
|
setFilter={setFilter}
|
||||||
setFilter={setFilterParams}
|
|
||||||
/>
|
/>
|
||||||
<ViewLibrary
|
<ViewLibrary
|
||||||
cleanQuery={() => setFilterParams({})}
|
cleanQuery={() => setFilter({})}
|
||||||
items={items}
|
items={items}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -8,9 +8,10 @@ import Divider from '../../components/Common/Divider';
|
||||||
import HelpRSFormItems from '../../components/Help/HelpRSFormItems';
|
import HelpRSFormItems from '../../components/Help/HelpRSFormItems';
|
||||||
import { ArrowDownIcon, ArrowsRotateIcon, ArrowUpIcon, DumpBinIcon, HelpIcon, SmallPlusIcon } from '../../components/Icons';
|
import { ArrowDownIcon, ArrowsRotateIcon, ArrowUpIcon, DumpBinIcon, HelpIcon, SmallPlusIcon } from '../../components/Icons';
|
||||||
import { useRSForm } from '../../context/RSFormContext';
|
import { useRSForm } from '../../context/RSFormContext';
|
||||||
|
import { useConceptTheme } from '../../context/ThemeContext';
|
||||||
import { prefixes } from '../../utils/constants';
|
import { prefixes } from '../../utils/constants';
|
||||||
import { CstType, IConstituenta, ICstCreateData, ICstMovetoData } from '../../utils/models'
|
import { CstType, IConstituenta, ICstCreateData, ICstMovetoData } from '../../utils/models'
|
||||||
import { getCstTypePrefix, getCstTypeShortcut, getCstTypificationLabel, mapStatusInfo } from '../../utils/staticUI';
|
import { getCstStatusColor, getCstTypePrefix, getCstTypeShortcut, getCstTypificationLabel, mapStatusInfo } from '../../utils/staticUI';
|
||||||
|
|
||||||
interface EditorItemsProps {
|
interface EditorItemsProps {
|
||||||
onOpenEdit: (cstID: number) => void
|
onOpenEdit: (cstID: number) => void
|
||||||
|
@ -19,6 +20,7 @@ interface EditorItemsProps {
|
||||||
}
|
}
|
||||||
|
|
||||||
function EditorItems({ onOpenEdit, onCreateCst, onDeleteCst }: EditorItemsProps) {
|
function EditorItems({ onOpenEdit, onCreateCst, onDeleteCst }: EditorItemsProps) {
|
||||||
|
const { colors } = useConceptTheme();
|
||||||
const { schema, isEditable, cstMoveTo, resetAliases } = useRSForm();
|
const { schema, isEditable, cstMoveTo, resetAliases } = useRSForm();
|
||||||
const [selected, setSelected] = useState<number[]>([]);
|
const [selected, setSelected] = useState<number[]>([]);
|
||||||
const nothingSelected = useMemo(() => selected.length === 0, [selected]);
|
const nothingSelected = useMemo(() => selected.length === 0, [selected]);
|
||||||
|
@ -180,7 +182,8 @@ function EditorItems({ onOpenEdit, onCreateCst, onDeleteCst }: EditorItemsProps)
|
||||||
return (<>
|
return (<>
|
||||||
<div
|
<div
|
||||||
id={`${prefixes.cst_list}${cst.alias}`}
|
id={`${prefixes.cst_list}${cst.alias}`}
|
||||||
className={`w-full rounded-md text-center ${info.color}`}
|
className='w-full text-center rounded-md'
|
||||||
|
style={{backgroundColor: getCstStatusColor(cst.status, colors)}}
|
||||||
>
|
>
|
||||||
{cst.alias}
|
{cst.alias}
|
||||||
</div>
|
</div>
|
||||||
|
@ -248,7 +251,7 @@ function EditorItems({ onOpenEdit, onCreateCst, onDeleteCst }: EditorItemsProps)
|
||||||
reorder: true,
|
reorder: true,
|
||||||
hide: 1800
|
hide: 1800
|
||||||
}
|
}
|
||||||
], []);
|
], [colors]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='w-full'>
|
<div className='w-full'>
|
||||||
|
|
|
@ -79,7 +79,7 @@ function EditorRSForm({ onDestroy, onClaim, onShare, onDownload }: EditorRSFormP
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<form onSubmit={handleSubmit} className='flex-grow max-w-xl px-4 py-2 border min-w-fit'>
|
<form onSubmit={handleSubmit} className='flex-grow max-w-[34.7rem] px-4 py-2 border min-w-fit'>
|
||||||
<div className='relative w-full'>
|
<div className='relative w-full'>
|
||||||
<div className='absolute top-0 right-0 flex'>
|
<div className='absolute top-0 right-0 flex'>
|
||||||
<MiniButton
|
<MiniButton
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { useCallback, useLayoutEffect, useMemo, useRef, useState } from 'react';
|
import { useCallback, useLayoutEffect, useMemo, useRef, useState } from 'react';
|
||||||
import { darkTheme, GraphCanvas, GraphCanvasRef, GraphEdge,
|
import { GraphCanvas, GraphCanvasRef, GraphEdge,
|
||||||
GraphNode, LayoutTypes, lightTheme, Sphere, useSelection
|
GraphNode, LayoutTypes, Sphere, useSelection
|
||||||
} from 'reagraph';
|
} from 'reagraph';
|
||||||
|
|
||||||
import Button from '../../components/Common/Button';
|
import Button from '../../components/Common/Button';
|
||||||
|
@ -9,12 +9,14 @@ import ConceptSelect from '../../components/Common/ConceptSelect';
|
||||||
import ConceptTooltip from '../../components/Common/ConceptTooltip';
|
import ConceptTooltip from '../../components/Common/ConceptTooltip';
|
||||||
import Divider from '../../components/Common/Divider';
|
import Divider from '../../components/Common/Divider';
|
||||||
import MiniButton from '../../components/Common/MiniButton';
|
import MiniButton from '../../components/Common/MiniButton';
|
||||||
|
import { darkTheme, lightTheme } from '../../components/GraphThemes';
|
||||||
import HelpTermGraph from '../../components/Help/HelpTermGraph';
|
import HelpTermGraph from '../../components/Help/HelpTermGraph';
|
||||||
import InfoConstituenta from '../../components/Help/InfoConstituenta';
|
import InfoConstituenta from '../../components/Help/InfoConstituenta';
|
||||||
import { ArrowsRotateIcon, DumpBinIcon, FilterCogIcon, HelpIcon, SmallPlusIcon } from '../../components/Icons';
|
import { ArrowsRotateIcon, DumpBinIcon, FilterCogIcon, HelpIcon, SmallPlusIcon } from '../../components/Icons';
|
||||||
import { useRSForm } from '../../context/RSFormContext';
|
import { useRSForm } from '../../context/RSFormContext';
|
||||||
import { useConceptTheme } from '../../context/ThemeContext';
|
import { useConceptTheme } from '../../context/ThemeContext';
|
||||||
import useLocalStorage from '../../hooks/useLocalStorage';
|
import useLocalStorage from '../../hooks/useLocalStorage';
|
||||||
|
import { IColorTheme } from '../../utils/color';
|
||||||
import { prefixes, resources } from '../../utils/constants';
|
import { prefixes, resources } from '../../utils/constants';
|
||||||
import { Graph } from '../../utils/Graph';
|
import { Graph } from '../../utils/Graph';
|
||||||
import { CstType, IConstituenta, ICstCreateData } from '../../utils/models';
|
import { CstType, IConstituenta, ICstCreateData } from '../../utils/models';
|
||||||
|
@ -28,12 +30,12 @@ import ConstituentaTooltip from './elements/ConstituentaTooltip';
|
||||||
export type ColoringScheme = 'none' | 'status' | 'type';
|
export type ColoringScheme = 'none' | 'status' | 'type';
|
||||||
const TREE_SIZE_MILESTONE = 50;
|
const TREE_SIZE_MILESTONE = 50;
|
||||||
|
|
||||||
function getCstNodeColor(cst: IConstituenta, coloringScheme: ColoringScheme, darkMode: boolean): string {
|
function getCstNodeColor(cst: IConstituenta, coloringScheme: ColoringScheme, darkMode: boolean, colors: IColorTheme): string {
|
||||||
if (coloringScheme === 'type') {
|
if (coloringScheme === 'type') {
|
||||||
return getCstClassColor(cst.cstClass, darkMode);
|
return getCstClassColor(cst.cstClass, colors);
|
||||||
}
|
}
|
||||||
if (coloringScheme === 'status') {
|
if (coloringScheme === 'status') {
|
||||||
return getCstStatusColor(cst.status, darkMode);
|
return getCstStatusColor(cst.status, colors);
|
||||||
}
|
}
|
||||||
return (darkMode ? '#7a8c9e' :'#7ca0ab');
|
return (darkMode ? '#7a8c9e' :'#7ca0ab');
|
||||||
}
|
}
|
||||||
|
@ -62,7 +64,7 @@ interface EditorTermGraphProps {
|
||||||
|
|
||||||
function EditorTermGraph({ onOpenEdit, onCreateCst, onDeleteCst }: EditorTermGraphProps) {
|
function EditorTermGraph({ onOpenEdit, onCreateCst, onDeleteCst }: EditorTermGraphProps) {
|
||||||
const { schema, isEditable } = useRSForm();
|
const { schema, isEditable } = useRSForm();
|
||||||
const { darkMode, noNavigation } = useConceptTheme();
|
const { darkMode, colors, noNavigation } = useConceptTheme();
|
||||||
|
|
||||||
const [ layout, setLayout ] = useLocalStorage<LayoutTypes>('graph_layout', 'treeTd2d');
|
const [ layout, setLayout ] = useLocalStorage<LayoutTypes>('graph_layout', 'treeTd2d');
|
||||||
const [ coloringScheme, setColoringScheme ] = useLocalStorage<ColoringScheme>('graph_coloring', 'none');
|
const [ coloringScheme, setColoringScheme ] = useLocalStorage<ColoringScheme>('graph_coloring', 'none');
|
||||||
|
@ -171,13 +173,13 @@ function EditorTermGraph({ onOpenEdit, onCreateCst, onDeleteCst }: EditorTermGra
|
||||||
if (cst) {
|
if (cst) {
|
||||||
result.push({
|
result.push({
|
||||||
id: String(node.id),
|
id: String(node.id),
|
||||||
fill: getCstNodeColor(cst, coloringScheme, darkMode),
|
fill: getCstNodeColor(cst, coloringScheme, darkMode, colors),
|
||||||
label: cst.term.resolved && !noTerms ? `${cst.alias}: ${cst.term.resolved}` : cst.alias
|
label: cst.term.resolved && !noTerms ? `${cst.alias}: ${cst.term.resolved}` : cst.alias
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return result;
|
return result;
|
||||||
}, [schema, coloringScheme, filtered.nodes, darkMode, noTerms]);
|
}, [schema, coloringScheme, filtered.nodes, darkMode, noTerms, colors]);
|
||||||
|
|
||||||
const edges: GraphEdge[] = useMemo(
|
const edges: GraphEdge[] = useMemo(
|
||||||
() => {
|
() => {
|
||||||
|
@ -337,8 +339,8 @@ function EditorTermGraph({ onOpenEdit, onCreateCst, onDeleteCst }: EditorTermGra
|
||||||
const canvasHeight = useMemo(
|
const canvasHeight = useMemo(
|
||||||
() => {
|
() => {
|
||||||
return !noNavigation ?
|
return !noNavigation ?
|
||||||
'calc(100vh - 9.8rem)'
|
'calc(100vh - 10.1rem)'
|
||||||
: 'calc(100vh - 1.8rem)';
|
: 'calc(100vh - 2.1rem)';
|
||||||
}, [noNavigation]);
|
}, [noNavigation]);
|
||||||
|
|
||||||
const dismissedStyle = useCallback(
|
const dismissedStyle = useCallback(
|
||||||
|
@ -354,7 +356,7 @@ function EditorTermGraph({ onOpenEdit, onCreateCst, onDeleteCst }: EditorTermGra
|
||||||
initial={getOptions()}
|
initial={getOptions()}
|
||||||
onConfirm={handleChangeOptions}
|
onConfirm={handleChangeOptions}
|
||||||
/>}
|
/>}
|
||||||
<div className='flex flex-col border-t border-r max-w-[12.5rem] pr-2 pb-2 text-sm select-none' style={{height: canvasHeight}}>
|
<div className='flex flex-col border-r border-b min-w-[13rem] pr-2 pb-2 text-sm select-none clr-border' style={{height: canvasHeight}}>
|
||||||
{hoverCst &&
|
{hoverCst &&
|
||||||
<div className='relative'>
|
<div className='relative'>
|
||||||
<InfoConstituenta
|
<InfoConstituenta
|
||||||
|
@ -394,7 +396,7 @@ function EditorTermGraph({ onOpenEdit, onCreateCst, onDeleteCst }: EditorTermGra
|
||||||
onClick={() => setShowOptions(true)}
|
onClick={() => setShowOptions(true)}
|
||||||
/>
|
/>
|
||||||
<ConceptSelect
|
<ConceptSelect
|
||||||
className='min-w-[9.3rem]'
|
className='min-w-[9.8rem]'
|
||||||
options={GraphColoringSelector}
|
options={GraphColoringSelector}
|
||||||
searchable={false}
|
searchable={false}
|
||||||
placeholder='Выберите цвет'
|
placeholder='Выберите цвет'
|
||||||
|
@ -441,7 +443,10 @@ function EditorTermGraph({ onOpenEdit, onCreateCst, onDeleteCst }: EditorTermGra
|
||||||
key={`${cst.alias}`}
|
key={`${cst.alias}`}
|
||||||
id={`${prefixes.cst_list}${cst.alias}`}
|
id={`${prefixes.cst_list}${cst.alias}`}
|
||||||
className='w-fit min-w-[3rem] rounded-md text-center cursor-pointer'
|
className='w-fit min-w-[3rem] rounded-md text-center cursor-pointer'
|
||||||
style={ { backgroundColor: getCstNodeColor(cst, adjustedColoring, darkMode), ...dismissedStyle(cstID) }}
|
style={{
|
||||||
|
backgroundColor: getCstNodeColor(cst, adjustedColoring, darkMode, colors),
|
||||||
|
...dismissedStyle(cstID)
|
||||||
|
}}
|
||||||
onClick={() => toggleDismissed(cstID)}
|
onClick={() => toggleDismissed(cstID)}
|
||||||
onDoubleClick={() => onOpenEdit(cstID)}
|
onDoubleClick={() => onOpenEdit(cstID)}
|
||||||
>
|
>
|
||||||
|
@ -458,7 +463,7 @@ function EditorTermGraph({ onOpenEdit, onCreateCst, onDeleteCst }: EditorTermGra
|
||||||
</div>
|
</div>
|
||||||
<div className='w-full h-full overflow-auto'>
|
<div className='w-full h-full overflow-auto'>
|
||||||
<div
|
<div
|
||||||
className='relative border-r border-y'
|
className='relative'
|
||||||
style={{width: canvasWidth, height: canvasHeight, borderBottomWidth: noNavigation ? '1px': ''}}
|
style={{width: canvasWidth, height: canvasHeight, borderBottomWidth: noNavigation ? '1px': ''}}
|
||||||
>
|
>
|
||||||
<div className='relative top-0 right-0 z-10 flex mt-1 ml-2 flex-start'>
|
<div className='relative top-0 right-0 z-10 flex mt-1 ml-2 flex-start'>
|
||||||
|
|
|
@ -283,7 +283,7 @@ function RSTabs() {
|
||||||
defaultFocus={true}
|
defaultFocus={true}
|
||||||
selectedTabClassName='font-bold'
|
selectedTabClassName='font-bold'
|
||||||
>
|
>
|
||||||
<TabList className='flex items-start pl-2 select-none w-fit clr-bg-pop'>
|
<TabList className='flex items-start pl-2 border-b select-none w-fit clr-bg-pop clr-border'>
|
||||||
<RSTabsMenu
|
<RSTabsMenu
|
||||||
onDownload={onDownloadSchema}
|
onDownload={onDownloadSchema}
|
||||||
onDestroy={onDestroySchema}
|
onDestroy={onDestroySchema}
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
import { useMemo } from 'react';
|
import { useMemo } from 'react';
|
||||||
|
|
||||||
|
import { useConceptTheme } from '../../../context/ThemeContext';
|
||||||
import { ExpressionStatus, type IConstituenta, IExpressionParse,inferStatus, ParsingStatus } from '../../../utils/models';
|
import { ExpressionStatus, type IConstituenta, IExpressionParse,inferStatus, ParsingStatus } from '../../../utils/models';
|
||||||
import { mapStatusInfo } from '../../../utils/staticUI';
|
import { getCstStatusColor, mapStatusInfo } from '../../../utils/staticUI';
|
||||||
|
|
||||||
interface StatusBarProps {
|
interface StatusBarProps {
|
||||||
isModified?: boolean
|
isModified?: boolean
|
||||||
|
@ -10,6 +11,7 @@ interface StatusBarProps {
|
||||||
}
|
}
|
||||||
|
|
||||||
function StatusBar({ isModified, constituenta, parseData }: StatusBarProps) {
|
function StatusBar({ isModified, constituenta, parseData }: StatusBarProps) {
|
||||||
|
const { colors } = useConceptTheme();
|
||||||
const status = useMemo(() => {
|
const status = useMemo(() => {
|
||||||
if (isModified) {
|
if (isModified) {
|
||||||
return ExpressionStatus.UNKNOWN;
|
return ExpressionStatus.UNKNOWN;
|
||||||
|
@ -24,7 +26,9 @@ function StatusBar({ isModified, constituenta, parseData }: StatusBarProps) {
|
||||||
const data = mapStatusInfo.get(status)!;
|
const data = mapStatusInfo.get(status)!;
|
||||||
return (
|
return (
|
||||||
<div title={data.tooltip}
|
<div title={data.tooltip}
|
||||||
className={`text-sm h-[1.6rem] w-[10rem] font-semibold inline-flex border items-center select-none justify-center align-middle ${data.color}`}>
|
className='text-sm h-[1.6rem] w-[10rem] font-semibold inline-flex border items-center select-none justify-center align-middle'
|
||||||
|
style={{backgroundColor: getCstStatusColor(status, colors)}}
|
||||||
|
>
|
||||||
Статус: [ {data.text} ]
|
Статус: [ {data.text} ]
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|
|
@ -6,7 +6,7 @@ import { useConceptTheme } from '../../../context/ThemeContext';
|
||||||
import useLocalStorage from '../../../hooks/useLocalStorage';
|
import useLocalStorage from '../../../hooks/useLocalStorage';
|
||||||
import { prefixes } from '../../../utils/constants';
|
import { prefixes } from '../../../utils/constants';
|
||||||
import { applyGraphFilter, CstMatchMode, CstType, DependencyMode, extractGlobals, IConstituenta, matchConstituenta } from '../../../utils/models';
|
import { applyGraphFilter, CstMatchMode, CstType, DependencyMode, extractGlobals, IConstituenta, matchConstituenta } from '../../../utils/models';
|
||||||
import { getCstDescription, getMockConstituenta, mapStatusInfo } from '../../../utils/staticUI';
|
import { getCstDescription, getCstStatusColor, getMockConstituenta } from '../../../utils/staticUI';
|
||||||
import ConstituentaTooltip from './ConstituentaTooltip';
|
import ConstituentaTooltip from './ConstituentaTooltip';
|
||||||
import DependencyModePicker from './DependencyModePicker';
|
import DependencyModePicker from './DependencyModePicker';
|
||||||
import MatchModePicker from './MatchModePicker';
|
import MatchModePicker from './MatchModePicker';
|
||||||
|
@ -26,7 +26,7 @@ function isMockCst(cst: IConstituenta) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function ViewSideConstituents({ expression, baseHeight, activeID, onOpenEdit }: ViewSideConstituentsProps) {
|
function ViewSideConstituents({ expression, baseHeight, activeID, onOpenEdit }: ViewSideConstituentsProps) {
|
||||||
const { darkMode, noNavigation } = useConceptTheme();
|
const { darkMode, noNavigation, colors } = 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);
|
||||||
|
@ -97,11 +97,11 @@ function ViewSideConstituents({ expression, baseHeight, activeID, onOpenEdit }:
|
||||||
name: 'ID',
|
name: 'ID',
|
||||||
id: 'alias',
|
id: 'alias',
|
||||||
cell: (cst: IConstituenta) => {
|
cell: (cst: IConstituenta) => {
|
||||||
const info = mapStatusInfo.get(cst.status)!;
|
|
||||||
return (<>
|
return (<>
|
||||||
<div
|
<div
|
||||||
id={`${prefixes.cst_list}${cst.alias}`}
|
id={`${prefixes.cst_list}${cst.alias}`}
|
||||||
className={`w-full rounded-md text-center ${info.color}`}
|
className='w-full text-center rounded-md'
|
||||||
|
style={{backgroundColor: getCstStatusColor(cst.status, colors)}}
|
||||||
>
|
>
|
||||||
{cst.alias}
|
{cst.alias}
|
||||||
</div>
|
</div>
|
||||||
|
@ -145,7 +145,7 @@ function ViewSideConstituents({ expression, baseHeight, activeID, onOpenEdit }:
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
], []);
|
], [colors]);
|
||||||
|
|
||||||
const maxHeight = useMemo(
|
const maxHeight = useMemo(
|
||||||
() => {
|
() => {
|
||||||
|
@ -156,13 +156,13 @@ function ViewSideConstituents({ expression, baseHeight, activeID, onOpenEdit }:
|
||||||
}, [noNavigation, baseHeight]);
|
}, [noNavigation, baseHeight]);
|
||||||
|
|
||||||
return (<>
|
return (<>
|
||||||
<div className='sticky top-0 left-0 right-0 z-10 flex items-start justify-between w-full gap-1 px-2 py-1 bg-white border-b rounded clr-bg-pop clr-border'>
|
<div className='sticky top-0 left-0 right-0 z-10 flex items-start justify-between w-full gap-1 px-2 py-1 border-b rounded clr-input clr-border'>
|
||||||
<MatchModePicker
|
<MatchModePicker
|
||||||
value={filterMatch}
|
value={filterMatch}
|
||||||
onChange={setFilterMatch}
|
onChange={setFilterMatch}
|
||||||
/>
|
/>
|
||||||
<input type='text'
|
<input type='text'
|
||||||
className='w-full px-2 bg-white outline-none select-none hover:text-clip clr-bg-pop'
|
className='w-full px-2 outline-none select-none hover:text-clip clr-input'
|
||||||
placeholder='наберите текст фильтра'
|
placeholder='наберите текст фильтра'
|
||||||
value={filterText}
|
value={filterText}
|
||||||
onChange={event => setFilterText(event.target.value)}
|
onChange={event => setFilterText(event.target.value)}
|
||||||
|
|
|
@ -16,7 +16,7 @@ function UserTabs() {
|
||||||
const { user: auth } = useAuth();
|
const { user: auth } = useAuth();
|
||||||
const { items } = useLibrary();
|
const { items } = useLibrary();
|
||||||
|
|
||||||
const [showSubs, setShowSubs] = useState(true);
|
const [showSubs, setShowSubs] = useState(false);
|
||||||
|
|
||||||
const subscriptions = useMemo(
|
const subscriptions = useMemo(
|
||||||
() => {
|
() => {
|
||||||
|
|
34
rsconcept/frontend/src/utils/color.ts
Normal file
34
rsconcept/frontend/src/utils/color.ts
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
export interface IColorTheme {
|
||||||
|
red: string
|
||||||
|
green: string
|
||||||
|
blue: string
|
||||||
|
teal: string
|
||||||
|
orange: string
|
||||||
|
|
||||||
|
// bg100: string
|
||||||
|
// bg70: string
|
||||||
|
// bg50: string
|
||||||
|
|
||||||
|
// fg100: string
|
||||||
|
// fg70: string
|
||||||
|
// fg50: string
|
||||||
|
|
||||||
|
// primary: string
|
||||||
|
// secondary: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export const lightT: IColorTheme = {
|
||||||
|
red: '#ffc9c9',
|
||||||
|
green: '#aaff80',
|
||||||
|
blue: '#b3bdff',
|
||||||
|
teal: '#a5e9fa',
|
||||||
|
orange: '#ffbb80',
|
||||||
|
};
|
||||||
|
|
||||||
|
export const darkT: IColorTheme = {
|
||||||
|
red: '#bf0d00',
|
||||||
|
green: '#2b8000',
|
||||||
|
blue: '#394bbf',
|
||||||
|
teal: '#0099bf',
|
||||||
|
orange: '#964600',
|
||||||
|
};
|
|
@ -282,9 +282,12 @@ export interface IRSFormUploadData {
|
||||||
|
|
||||||
// ========== Library =====
|
// ========== Library =====
|
||||||
export interface ILibraryFilter {
|
export interface ILibraryFilter {
|
||||||
ownedBy?: number
|
query?: string
|
||||||
|
is_personal?: boolean
|
||||||
|
is_owned?: boolean
|
||||||
is_common?: boolean
|
is_common?: boolean
|
||||||
queryMeta?: string
|
is_canonical?: boolean
|
||||||
|
is_subscribed?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
// ================ Misc types ================
|
// ================ Misc types ================
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import { LayoutTypes } from 'reagraph';
|
import { LayoutTypes } from 'reagraph';
|
||||||
|
|
||||||
import { ColoringScheme } from '../pages/RSFormPage/EditorTermGraph';
|
import { ColoringScheme } from '../pages/RSFormPage/EditorTermGraph';
|
||||||
|
import { IColorTheme } from './color';
|
||||||
import { resolveErrorClass,RSErrorClass, RSErrorType, TokenID } from './enums';
|
import { resolveErrorClass,RSErrorClass, RSErrorType, TokenID } from './enums';
|
||||||
import {
|
import {
|
||||||
CstClass, CstMatchMode, CstType,
|
CstClass, CstMatchMode, CstType,
|
||||||
|
@ -9,18 +10,7 @@ import {
|
||||||
ISyntaxTreeNode, ParsingStatus, ValueClass
|
ISyntaxTreeNode, ParsingStatus, ValueClass
|
||||||
} from './models';
|
} from './models';
|
||||||
|
|
||||||
export interface IRSButtonData {
|
export interface IDescriptor {
|
||||||
text: string
|
|
||||||
tooltip: string
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface IFormatInfo {
|
|
||||||
text: string
|
|
||||||
color: string
|
|
||||||
tooltip: string
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface ITopicInfo {
|
|
||||||
text: string
|
text: string
|
||||||
tooltip: string
|
tooltip: string
|
||||||
}
|
}
|
||||||
|
@ -64,7 +54,7 @@ export function getCstExpressionPrefix(cst: IConstituenta): string {
|
||||||
return cst.alias + (cst.cstType === CstType.STRUCTURED ? '::=' : ':==');
|
return cst.alias + (cst.cstType === CstType.STRUCTURED ? '::=' : ':==');
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getRSButtonData(id: TokenID): IRSButtonData {
|
export function getRSButtonData(id: TokenID): IDescriptor {
|
||||||
switch (id) {
|
switch (id) {
|
||||||
case TokenID.BOOLEAN: return {
|
case TokenID.BOOLEAN: return {
|
||||||
text: 'ℬ()',
|
text: 'ℬ()',
|
||||||
|
@ -323,51 +313,45 @@ export const GraphColoringSelector: {value: ColoringScheme, label: string}[] = [
|
||||||
{ value: 'type', label: 'Цвет: класс'},
|
{ value: 'type', label: 'Цвет: класс'},
|
||||||
];
|
];
|
||||||
|
|
||||||
export function getCstStatusColor(status: ExpressionStatus, darkMode: boolean): string {
|
export function getCstStatusColor(status: ExpressionStatus, colors: IColorTheme): string {
|
||||||
switch (status) {
|
switch (status) {
|
||||||
case ExpressionStatus.VERIFIED: return darkMode ? '#2b8000': '#aaff80';
|
case ExpressionStatus.VERIFIED: return colors.green;
|
||||||
case ExpressionStatus.INCORRECT: return darkMode ? '#592b2b': '#ffc9c9';
|
case ExpressionStatus.INCORRECT: return colors.red;
|
||||||
case ExpressionStatus.INCALCULABLE: return darkMode ? '#964600': '#ffbb80';
|
case ExpressionStatus.INCALCULABLE: return colors.orange;
|
||||||
case ExpressionStatus.PROPERTY: return darkMode ? '#36899e': '#a5e9fa';
|
case ExpressionStatus.PROPERTY: return colors.teal;
|
||||||
case ExpressionStatus.UNKNOWN: return darkMode ? '#1e00b3': '#b3bdff';
|
case ExpressionStatus.UNKNOWN: return colors.blue;
|
||||||
case ExpressionStatus.UNDEFINED: return darkMode ? '#1e00b3': '#b3bdff';
|
case ExpressionStatus.UNDEFINED: return colors.blue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const mapStatusInfo: Map<ExpressionStatus, IFormatInfo> = new Map([
|
export const mapStatusInfo: Map<ExpressionStatus, IDescriptor> = new Map([
|
||||||
[ ExpressionStatus.VERIFIED, {
|
[ ExpressionStatus.VERIFIED, {
|
||||||
text: 'ок',
|
text: 'ок',
|
||||||
color: 'bg-[#aaff80] dark:bg-[#2b8000]',
|
|
||||||
tooltip: 'выражение корректно и вычислимо'
|
tooltip: 'выражение корректно и вычислимо'
|
||||||
}],
|
}],
|
||||||
[ ExpressionStatus.INCORRECT, {
|
[ ExpressionStatus.INCORRECT, {
|
||||||
text: 'ошибка',
|
text: 'ошибка',
|
||||||
color: 'bg-[#ffc9c9] dark:bg-[#592b2b]',
|
|
||||||
tooltip: 'ошибка в выражении'
|
tooltip: 'ошибка в выражении'
|
||||||
}],
|
}],
|
||||||
[ ExpressionStatus.INCALCULABLE, {
|
[ ExpressionStatus.INCALCULABLE, {
|
||||||
text: 'невыч',
|
text: 'невыч',
|
||||||
color: 'bg-[#ffbb80] dark:bg-[#964600]',
|
|
||||||
tooltip: 'выражение не вычислимо'
|
tooltip: 'выражение не вычислимо'
|
||||||
}],
|
}],
|
||||||
[ ExpressionStatus.PROPERTY, {
|
[ ExpressionStatus.PROPERTY, {
|
||||||
text: 'св-во',
|
text: 'св-во',
|
||||||
color: 'bg-[#a5e9fa] dark:bg-[#36899e]',
|
|
||||||
tooltip: 'можно проверить принадлежность, но нельзя получить значение'
|
tooltip: 'можно проверить принадлежность, но нельзя получить значение'
|
||||||
}],
|
}],
|
||||||
[ ExpressionStatus.UNKNOWN, {
|
[ ExpressionStatus.UNKNOWN, {
|
||||||
text: 'неизв',
|
text: 'неизв',
|
||||||
color: 'bg-[#b3bdff] dark:bg-[#1e00b3]',
|
|
||||||
tooltip: 'требует проверки выражения'
|
tooltip: 'требует проверки выражения'
|
||||||
}],
|
}],
|
||||||
[ ExpressionStatus.UNDEFINED, {
|
[ ExpressionStatus.UNDEFINED, {
|
||||||
text: 'N/A',
|
text: 'N/A',
|
||||||
color: 'bg-[#b3bdff] dark:bg-[#1e00b3]',
|
|
||||||
tooltip: 'произошла ошибка при проверке выражения'
|
tooltip: 'произошла ошибка при проверке выражения'
|
||||||
}]
|
}]
|
||||||
]);
|
]);
|
||||||
|
|
||||||
export const mapTopicInfo: Map<HelpTopic, ITopicInfo> = new Map([
|
export const mapTopicInfo: Map<HelpTopic, IDescriptor> = new Map([
|
||||||
[ HelpTopic.MAIN, {
|
[ HelpTopic.MAIN, {
|
||||||
text: 'Портал',
|
text: 'Портал',
|
||||||
tooltip: 'Общая справка по порталу'
|
tooltip: 'Общая справка по порталу'
|
||||||
|
@ -406,34 +390,30 @@ export const mapTopicInfo: Map<HelpTopic, ITopicInfo> = new Map([
|
||||||
}],
|
}],
|
||||||
]);
|
]);
|
||||||
|
|
||||||
export function getCstClassColor(cstClass: CstClass, darkMode: boolean): string {
|
export function getCstClassColor(cstClass: CstClass, colors: IColorTheme): string {
|
||||||
switch (cstClass) {
|
switch (cstClass) {
|
||||||
case CstClass.TEMPLATE: return darkMode ? '#36899e': '#a5e9fa';
|
case CstClass.BASIC: return colors.green;
|
||||||
case CstClass.BASIC: return darkMode ? '#2b8000': '#aaff80';
|
case CstClass.DERIVED: return colors.blue;
|
||||||
case CstClass.DERIVED: return darkMode ? '#1e00b3': '#b3bdff';
|
case CstClass.STATEMENT: return colors.red;
|
||||||
case CstClass.STATEMENT: return darkMode ? '#592b2b': '#ffc9c9';
|
case CstClass.TEMPLATE: return colors.teal;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const mapCstClassInfo: Map<CstClass, IFormatInfo> = new Map([
|
export const mapCstClassInfo: Map<CstClass, IDescriptor> = new Map([
|
||||||
[ CstClass.BASIC, {
|
[ CstClass.BASIC, {
|
||||||
text: 'базовый',
|
text: 'базовый',
|
||||||
color: 'bg-[#aaff80] dark:bg-[#2b8000]',
|
|
||||||
tooltip: 'неопределяемое понятие, требует конвенции'
|
tooltip: 'неопределяемое понятие, требует конвенции'
|
||||||
}],
|
}],
|
||||||
[ CstClass.DERIVED, {
|
[ CstClass.DERIVED, {
|
||||||
text: 'производный',
|
text: 'производный',
|
||||||
color: 'bg-[#b3bdff] dark:bg-[#1e00b3]',
|
|
||||||
tooltip: 'выводимое понятие, задаваемое определением'
|
tooltip: 'выводимое понятие, задаваемое определением'
|
||||||
}],
|
}],
|
||||||
[ CstClass.STATEMENT, {
|
[ CstClass.STATEMENT, {
|
||||||
text: 'утверждение',
|
text: 'утверждение',
|
||||||
color: 'bg-[#ffc9c9] dark:bg-[#592b2b]',
|
|
||||||
tooltip: 'неопределяемое понятие, требует конвенции'
|
tooltip: 'неопределяемое понятие, требует конвенции'
|
||||||
}],
|
}],
|
||||||
[ CstClass.TEMPLATE, {
|
[ CstClass.TEMPLATE, {
|
||||||
text: 'шаблон',
|
text: 'шаблон',
|
||||||
color: 'bg-[#a5e9fa] dark:bg-[#36899e]',
|
|
||||||
tooltip: 'параметризованный шаблон определения'
|
tooltip: 'параметризованный шаблон определения'
|
||||||
}],
|
}],
|
||||||
]);
|
]);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user