Compare commits
4 Commits
21a304701e
...
168ff94c42
Author | SHA1 | Date | |
---|---|---|---|
![]() |
168ff94c42 | ||
![]() |
8035a604bd | ||
![]() |
05ef45fac8 | ||
![]() |
68cc96a779 |
|
@ -4,29 +4,32 @@ import { IConstituenta } from '@/models/rsform';
|
|||
import { isMockCst } from '@/models/rsformAPI';
|
||||
import { colorFgCstStatus, IColorTheme } from '@/styling/color';
|
||||
|
||||
import { CProps } from '../props';
|
||||
import TooltipConstituenta from './TooltipConstituenta';
|
||||
|
||||
interface BadgeConstituentaProps {
|
||||
interface BadgeConstituentaProps extends CProps.Styling {
|
||||
prefixID?: string;
|
||||
value: IConstituenta;
|
||||
theme: IColorTheme;
|
||||
}
|
||||
|
||||
function BadgeConstituenta({ value, prefixID, theme }: BadgeConstituentaProps) {
|
||||
function BadgeConstituenta({ value, prefixID, className, style, theme }: BadgeConstituentaProps) {
|
||||
return (
|
||||
<div
|
||||
id={`${prefixID}${value.alias}`}
|
||||
className={clsx(
|
||||
'min-w-[3.1rem] max-w-[3.1rem]', // prettier: split lines
|
||||
'min-w-[3.1rem] max-w-[3.1rem]',
|
||||
'px-1',
|
||||
'border rounded-md',
|
||||
value.is_inherited && 'border-dashed',
|
||||
'text-center font-medium whitespace-nowrap'
|
||||
'text-center font-medium whitespace-nowrap',
|
||||
className
|
||||
)}
|
||||
style={{
|
||||
borderColor: colorFgCstStatus(value.status, theme),
|
||||
color: colorFgCstStatus(value.status, theme),
|
||||
backgroundColor: isMockCst(value) ? theme.bgWarning : theme.bgInput
|
||||
backgroundColor: isMockCst(value) ? theme.bgWarning : theme.bgInput,
|
||||
...style
|
||||
}}
|
||||
>
|
||||
{value.alias}
|
||||
|
|
|
@ -91,12 +91,14 @@ function Modal({
|
|||
{header ? <h1 className='px-12 py-2 select-none'>{header}</h1> : null}
|
||||
|
||||
<div
|
||||
className={clsx('overflow-auto overscroll-contain', className)}
|
||||
style={{
|
||||
overflow: overflowVisible ? 'visible' : 'auto',
|
||||
maxHeight: 'calc(100svh - 8rem)',
|
||||
maxWidth: 'calc(100svw - 2rem)'
|
||||
}}
|
||||
className={clsx(
|
||||
'overscroll-contain max-h-[calc(100svh-8rem)] max-w-[100svw] xs:max-w-[calc(100svw-2rem)]',
|
||||
{
|
||||
'overflow-auto': !overflowVisible,
|
||||
'overflow-visible': overflowVisible
|
||||
},
|
||||
className
|
||||
)}
|
||||
>
|
||||
{children}
|
||||
</div>
|
||||
|
|
|
@ -78,7 +78,7 @@ function FormCreateCst({ schema, state, partialUpdate, setValidated }: FormCreat
|
|||
fitContent
|
||||
spellCheck
|
||||
label='Термин'
|
||||
placeholder='Обозначение, используемое в текстовых определениях'
|
||||
placeholder='Обозначение для текстовых определений'
|
||||
className='max-h-[3.6rem]'
|
||||
value={state.term_raw}
|
||||
onChange={event => partialUpdate({ term_raw: event.target.value })}
|
||||
|
|
|
@ -18,10 +18,11 @@ import { SelectorCstType } from '@/utils/selectors';
|
|||
|
||||
interface DlgRenameCstProps extends Pick<ModalProps, 'hideWindow'> {
|
||||
initial: ICstRenameData;
|
||||
allowChangeType: boolean;
|
||||
onRename: (data: ICstRenameData) => void;
|
||||
}
|
||||
|
||||
function DlgRenameCst({ hideWindow, initial, onRename }: DlgRenameCstProps) {
|
||||
function DlgRenameCst({ hideWindow, initial, allowChangeType, onRename }: DlgRenameCstProps) {
|
||||
const { schema } = useRSForm();
|
||||
const [validated, setValidated] = useState(false);
|
||||
const [cstData, updateData] = usePartialUpdate(initial);
|
||||
|
@ -52,6 +53,7 @@ function DlgRenameCst({ hideWindow, initial, onRename }: DlgRenameCstProps) {
|
|||
id='dlg_cst_type'
|
||||
placeholder='Выберите тип'
|
||||
className='min-w-[16rem] self-center'
|
||||
isDisabled={!allowChangeType}
|
||||
options={SelectorCstType}
|
||||
value={{
|
||||
value: cstData.cst_type,
|
||||
|
|
|
@ -255,7 +255,20 @@ export function isFunctional(type: CstType): boolean {
|
|||
* Validate new alias against {@link CstType} and {@link IRSForm}.
|
||||
*/
|
||||
export function validateNewAlias(alias: string, type: CstType, schema: IRSForm): boolean {
|
||||
return alias.length >= 2 && alias.startsWith(getCstTypePrefix(type)) && !schema.cstByAlias.has(alias);
|
||||
if (alias.length < 2) {
|
||||
return false;
|
||||
}
|
||||
const prefix = getCstTypePrefix(type);
|
||||
if (!alias.startsWith(prefix)) {
|
||||
return false;
|
||||
}
|
||||
if (schema.cstByAlias.has(alias)) {
|
||||
return false;
|
||||
}
|
||||
if (!/^\d+$/.exec(alias.substring(prefix.length))) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -3,7 +3,7 @@ import { HelpTopic } from '@/models/miscellaneous';
|
|||
|
||||
function HelpConceptRelations() {
|
||||
return (
|
||||
<div>
|
||||
<div className='text-justify'>
|
||||
<h1>Связи между конституентами</h1>
|
||||
<p>
|
||||
Конституенты связаны между собой через использование одних конституент при определении других. Такую связь в
|
||||
|
|
|
@ -3,7 +3,7 @@ import { HelpTopic } from '@/models/miscellaneous';
|
|||
|
||||
function HelpConceptSynthesis() {
|
||||
return (
|
||||
<div>
|
||||
<div className='text-justify'>
|
||||
<h1>Синтез концептуальных схем</h1>
|
||||
<p>
|
||||
Работа с крупными предметными областями требуют рассмотрения различных точек зрения в рамках одной предметной
|
||||
|
|
|
@ -3,7 +3,7 @@ import { HelpTopic } from '@/models/miscellaneous';
|
|||
|
||||
function HelpConceptSystem() {
|
||||
return (
|
||||
<div>
|
||||
<div className='text-justify'>
|
||||
<h1>Концептуальная схема – Система определений</h1>
|
||||
<p>
|
||||
Данный раздел вводит <b>систему определений</b> как предмет концептуализации предметных областей. Под системой
|
||||
|
|
|
@ -4,7 +4,7 @@ import { external_urls } from '@/utils/constants';
|
|||
|
||||
function HelpRules() {
|
||||
return (
|
||||
<div>
|
||||
<div className='text-justify'>
|
||||
<h1>Правила поведения участников Портала</h1>
|
||||
|
||||
<p>
|
||||
|
|
|
@ -56,7 +56,11 @@ function OssFlow({ isModified, setIsModified }: OssFlowProps) {
|
|||
|
||||
const onSelectionChange = useCallback(
|
||||
({ nodes }: { nodes: Node[] }) => {
|
||||
controller.setSelected(nodes.map(node => Number(node.id)));
|
||||
const ids = nodes.map(node => Number(node.id));
|
||||
controller.setSelected(prev => [
|
||||
...prev.filter(nodeID => ids.includes(nodeID)),
|
||||
...ids.filter(nodeID => !prev.includes(Number(nodeID)))
|
||||
]);
|
||||
},
|
||||
[controller]
|
||||
);
|
||||
|
|
|
@ -149,7 +149,7 @@ function FormConstituenta({
|
|||
id='cst_term'
|
||||
label='Термин'
|
||||
maxHeight='8rem'
|
||||
placeholder='Обозначение, используемое в текстовых определениях'
|
||||
placeholder='Обозначение для текстовых определений'
|
||||
schema={schema}
|
||||
onOpenEdit={onOpenEdit}
|
||||
value={term}
|
||||
|
@ -240,7 +240,7 @@ function FormConstituenta({
|
|||
</AnimateFade>
|
||||
|
||||
{!disabled || processing ? (
|
||||
<div className='self-center flex'>
|
||||
<div className='mx-auto flex'>
|
||||
<SubmitButton
|
||||
key='cst_form_submit'
|
||||
id='cst_form_submit'
|
||||
|
|
|
@ -165,7 +165,7 @@ function EditorRSExpression({
|
|||
toggleControls={() => setShowControls(prev => !prev)}
|
||||
/>
|
||||
|
||||
<Overlay position='top-[-0.5rem] pl-[8rem] sm:pl-[4rem] right-1/2 translate-x-1/2 flex'>
|
||||
<Overlay position='top-[-0.5rem]' className='pl-[8.5rem] xs:pl-[2rem] flex justify-center w-full gap-1'>
|
||||
<StatusBar
|
||||
processing={parser.processing}
|
||||
isModified={isModified}
|
||||
|
|
|
@ -92,7 +92,7 @@ function RSEditorControls({ isOpen, disabled, onEdit }: RSEditorControlsProps) {
|
|||
return (
|
||||
<motion.div
|
||||
className={clsx(
|
||||
'max-w-[38.5rem] sm:max-w-[40rem] sm:min-w-[40rem] md:max-w-fit mx-1 sm:mx-0',
|
||||
'max-w-[28rem] min-w-[28rem] xs:max-w-[38.5rem] xs:min-w-[38.5rem] sm:max-w-[40rem] sm:min-w-[40rem] md:max-w-fit mx-1 sm:mx-0',
|
||||
'flex-wrap',
|
||||
'divide-solid',
|
||||
'text-xs md:text-sm',
|
||||
|
@ -112,6 +112,7 @@ function RSEditorControls({ isOpen, disabled, onEdit }: RSEditorControlsProps) {
|
|||
title={title}
|
||||
onInsert={onEdit}
|
||||
disabled={disabled}
|
||||
className='hidden xs:inline'
|
||||
/>
|
||||
))}
|
||||
|
||||
|
@ -121,6 +122,7 @@ function RSEditorControls({ isOpen, disabled, onEdit }: RSEditorControlsProps) {
|
|||
{SECONDARY_SECOND_ROW.map(({ text, title }) => (
|
||||
<RSLocalButton
|
||||
key={`${prefixes.rsedit_btn}${title}`}
|
||||
className='hidden xs:inline'
|
||||
text={text}
|
||||
title={title}
|
||||
onInsert={onEdit}
|
||||
|
@ -134,6 +136,7 @@ function RSEditorControls({ isOpen, disabled, onEdit }: RSEditorControlsProps) {
|
|||
{SECONDARY_THIRD_ROW.map(({ text, title }) => (
|
||||
<RSLocalButton
|
||||
key={`${prefixes.rsedit_btn}${title}`}
|
||||
className='hidden xs:inline'
|
||||
text={text}
|
||||
title={title}
|
||||
onInsert={onEdit}
|
||||
|
|
|
@ -4,13 +4,22 @@ import { CProps } from '@/components/props';
|
|||
import { TokenID } from '@/models/rslang';
|
||||
import { globals } from '@/utils/constants';
|
||||
|
||||
interface RSLocalButtonProps extends CProps.Titled {
|
||||
interface RSLocalButtonProps extends CProps.Titled, CProps.Styling {
|
||||
text: string;
|
||||
disabled?: boolean;
|
||||
onInsert: (token: TokenID, key?: string) => void;
|
||||
}
|
||||
|
||||
function RSLocalButton({ text, title, titleHtml, hideTitle, disabled, onInsert }: RSLocalButtonProps) {
|
||||
function RSLocalButton({
|
||||
text,
|
||||
title,
|
||||
titleHtml,
|
||||
hideTitle,
|
||||
disabled,
|
||||
className,
|
||||
onInsert,
|
||||
...restProps
|
||||
}: RSLocalButtonProps) {
|
||||
return (
|
||||
<button
|
||||
type='button'
|
||||
|
@ -25,9 +34,11 @@ function RSLocalButton({ text, title, titleHtml, hideTitle, disabled, onInsert }
|
|||
'cursor-pointer disabled:cursor-default',
|
||||
'rounded-none',
|
||||
'clr-hover clr-btn-clear',
|
||||
'font-math'
|
||||
'font-math',
|
||||
className
|
||||
)}
|
||||
onClick={() => onInsert(TokenID.ID_LOCAL, text)}
|
||||
{...restProps}
|
||||
>
|
||||
{text}
|
||||
</button>
|
||||
|
|
|
@ -41,12 +41,10 @@ function StatusBar({ isModified, processing, activeCst, parseData, onAnalyze }:
|
|||
tabIndex={0}
|
||||
className={clsx(
|
||||
'w-[10rem] h-[1.75rem]',
|
||||
'scale-75 sm:scale-100 mx-[-2.5rem] sm:m-0',
|
||||
'px-2 flex items-center justify-center gap-2',
|
||||
'border',
|
||||
'select-none',
|
||||
'cursor-pointer',
|
||||
'translate-x-[-1.5rem]',
|
||||
'focus-frame',
|
||||
'duration-500 transition-colors'
|
||||
)}
|
||||
|
|
|
@ -689,10 +689,11 @@ export const RSEditState = ({
|
|||
initial={createInitialData}
|
||||
/>
|
||||
) : null}
|
||||
{showRenameCst && renameInitialData ? (
|
||||
{activeCst && showRenameCst && renameInitialData ? (
|
||||
<DlgRenameCst
|
||||
hideWindow={() => setShowRenameCst(false)}
|
||||
onRename={handleRenameCst}
|
||||
allowChangeType={!activeCst.is_inherited}
|
||||
initial={renameInitialData}
|
||||
/>
|
||||
) : null}
|
||||
|
|
|
@ -69,7 +69,12 @@ function TableSideConstituents({
|
|||
minSize: 65,
|
||||
footer: undefined,
|
||||
cell: props => (
|
||||
<BadgeConstituenta theme={colors} value={props.row.original} prefixID={prefixes.cst_side_table} />
|
||||
<BadgeConstituenta
|
||||
className='mr-[-0.5rem]'
|
||||
theme={colors}
|
||||
value={props.row.original}
|
||||
prefixID={prefixes.cst_side_table}
|
||||
/>
|
||||
)
|
||||
}),
|
||||
columnHelper.accessor(cst => describeConstituenta(cst), {
|
||||
|
|
Loading…
Reference in New Issue
Block a user