mirror of
https://github.com/IRBorisov/ConceptPortal.git
synced 2025-06-26 13:00:39 +03:00
Refactor Checkbox and add Tristate
This commit is contained in:
parent
c58743bdb0
commit
75fd9a855c
|
@ -1,5 +1,6 @@
|
||||||
import { useRef } from 'react';
|
import { useMemo } from 'react';
|
||||||
|
|
||||||
|
import { CheckboxChecked } from '../Icons';
|
||||||
import Label from './Label';
|
import Label from './Label';
|
||||||
|
|
||||||
export interface CheckboxProps {
|
export interface CheckboxProps {
|
||||||
|
@ -9,51 +10,52 @@ export interface CheckboxProps {
|
||||||
disabled?: boolean
|
disabled?: boolean
|
||||||
widthClass?: string
|
widthClass?: string
|
||||||
tooltip?: string
|
tooltip?: string
|
||||||
value?: boolean
|
|
||||||
onChange?: (event: React.ChangeEvent<HTMLInputElement>) => void
|
value: boolean
|
||||||
|
setValue?: (newValue: boolean) => void
|
||||||
}
|
}
|
||||||
|
|
||||||
function Checkbox({ id, required, disabled, tooltip, label, widthClass = 'w-fit', value, onChange }: CheckboxProps) {
|
function Checkbox({ id, required, disabled, tooltip, label, widthClass = 'w-fit', value, setValue }: CheckboxProps) {
|
||||||
const inputRef = useRef<HTMLInputElement | null>(null);
|
const cursor = useMemo(
|
||||||
|
() => {
|
||||||
const cursor = disabled ? 'cursor-not-allowed' : 'cursor-pointer';
|
if (disabled) {
|
||||||
|
return 'cursor-not-allowed';
|
||||||
|
} else if (setValue) {
|
||||||
|
return 'cursor-pointer';
|
||||||
|
} else {
|
||||||
|
return ''
|
||||||
|
}
|
||||||
|
}, [disabled, setValue]);
|
||||||
|
const bgColor = useMemo(
|
||||||
|
() => {
|
||||||
|
return value !== false ? 'clr-primary' : 'clr-app'
|
||||||
|
}, [value]);
|
||||||
|
|
||||||
function handleClick(event: React.MouseEvent<HTMLButtonElement, MouseEvent>): void {
|
function handleClick(event: React.MouseEvent<HTMLButtonElement, MouseEvent>): void {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
if (!disabled) {
|
if (disabled || !setValue) {
|
||||||
inputRef.current?.click();
|
return;
|
||||||
}
|
}
|
||||||
|
setValue(!value);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<button
|
<button
|
||||||
className={'flex [&:not(:first-child)]:mt-3 clr-outline focus:outline-dotted focus:outline-1 ' + widthClass}
|
id={id}
|
||||||
|
className={`flex items-center [&:not(:first-child)]:mt-3 clr-outline focus:outline-dotted focus:outline-1 ${widthClass}`}
|
||||||
title={tooltip}
|
title={tooltip}
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
onClick={handleClick}
|
onClick={handleClick}
|
||||||
>
|
>
|
||||||
<input id={id} type='checkbox' ref={inputRef}
|
<div className={`relative peer w-4 h-4 shrink-0 mt-0.5 border rounded-sm appearance-none ${bgColor} ${cursor}`} />
|
||||||
className={`relative peer w-4 h-4 shrink-0 mt-0.5 border rounded-sm appearance-none clr-checkbox ${cursor}`}
|
|
||||||
required={required}
|
|
||||||
disabled={disabled}
|
|
||||||
checked={value}
|
|
||||||
onChange={onChange}
|
|
||||||
tabIndex={-1}
|
|
||||||
/>
|
|
||||||
{ label &&
|
{ label &&
|
||||||
<Label
|
<Label
|
||||||
className={`${cursor} px-2`}
|
className={`${cursor} px-2 text-start`}
|
||||||
text={label}
|
text={label}
|
||||||
required={required}
|
required={required}
|
||||||
htmlFor={id}
|
htmlFor={id}
|
||||||
/>}
|
/>}
|
||||||
<svg
|
{value && <CheckboxChecked />}
|
||||||
className='absolute hidden w-3 h-3 mt-1 ml-0.5 text-white pointer-events-none peer-checked:block'
|
|
||||||
viewBox='0 0 512 512'
|
|
||||||
fill='currentColor'
|
|
||||||
>
|
|
||||||
<path d='M470.6 105.4c12.5 12.5 12.5 32.8 0 45.3l-256 256c-12.5 12.5-32.8 12.5-45.3 0l-128-128c-12.5-12.5-12.5-32.8 0-45.3s32.8-12.5 45.3 0L192 338.7l233.4-233.3c12.5-12.5 32.8-12.5 45.3 0z' />
|
|
||||||
</svg>
|
|
||||||
</button>
|
</button>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,15 +1,15 @@
|
||||||
import Checkbox from './Checkbox';
|
import Checkbox from './Checkbox';
|
||||||
|
|
||||||
interface DropdownCheckboxProps {
|
interface DropdownCheckboxProps {
|
||||||
|
value: boolean
|
||||||
label?: string
|
label?: string
|
||||||
tooltip?: string
|
tooltip?: string
|
||||||
disabled?: boolean
|
disabled?: boolean
|
||||||
value?: boolean
|
setValue?: (newValue: boolean) => void
|
||||||
onChange?: (event: React.ChangeEvent<HTMLInputElement>) => void
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function DropdownCheckbox({ tooltip, onChange, disabled, ...props }: DropdownCheckboxProps) {
|
function DropdownCheckbox({ tooltip, setValue, disabled, ...props }: DropdownCheckboxProps) {
|
||||||
const behavior = (onChange && !disabled ? 'clr-hover' : '');
|
const behavior = (setValue && !disabled ? 'clr-hover' : '');
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
title={tooltip}
|
title={tooltip}
|
||||||
|
@ -18,7 +18,7 @@ function DropdownCheckbox({ tooltip, onChange, disabled, ...props }: DropdownChe
|
||||||
<Checkbox
|
<Checkbox
|
||||||
widthClass='w-full'
|
widthClass='w-full'
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
onChange={onChange}
|
setValue={setValue}
|
||||||
{...props}
|
{...props}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -4,18 +4,22 @@ import { UploadIcon } from '../Icons';
|
||||||
import Button from './Button';
|
import Button from './Button';
|
||||||
import Label from './Label';
|
import Label from './Label';
|
||||||
|
|
||||||
interface FileInputProps {
|
interface FileInputProps
|
||||||
id?: string
|
extends Omit<React.InputHTMLAttributes<HTMLInputElement>, 'className' | 'title' | 'style' | 'accept' | 'type'> {
|
||||||
required?: boolean
|
|
||||||
label: string
|
label: string
|
||||||
|
tooltip?: string
|
||||||
acceptType?: string
|
acceptType?: string
|
||||||
widthClass?: string
|
widthClass?: string
|
||||||
onChange?: (event: React.ChangeEvent<HTMLInputElement>) => void
|
onChange?: (event: React.ChangeEvent<HTMLInputElement>) => void
|
||||||
}
|
}
|
||||||
|
|
||||||
function FileInput({ id, required, label, acceptType, widthClass = 'w-full', onChange }: FileInputProps) {
|
function FileInput({
|
||||||
|
label, acceptType, tooltip,
|
||||||
|
widthClass = 'w-fit', onChange,
|
||||||
|
...props
|
||||||
|
}: FileInputProps) {
|
||||||
const inputRef = useRef<HTMLInputElement | null>(null);
|
const inputRef = useRef<HTMLInputElement | null>(null);
|
||||||
const [labelText, setLabelText] = useState('');
|
const [fileName, setFileName] = useState('');
|
||||||
|
|
||||||
const handleUploadClick = () => {
|
const handleUploadClick = () => {
|
||||||
inputRef.current?.click();
|
inputRef.current?.click();
|
||||||
|
@ -23,9 +27,9 @@ function FileInput({ id, required, label, acceptType, widthClass = 'w-full', onC
|
||||||
|
|
||||||
const handleFileChange = (event: React.ChangeEvent<HTMLInputElement>) => {
|
const handleFileChange = (event: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
if (event.target.files && event.target.files.length > 0) {
|
if (event.target.files && event.target.files.length > 0) {
|
||||||
setLabelText(event.target.files[0].name)
|
setFileName(event.target.files[0].name)
|
||||||
} else {
|
} else {
|
||||||
setLabelText('')
|
setFileName('')
|
||||||
}
|
}
|
||||||
if (onChange) {
|
if (onChange) {
|
||||||
onChange(event);
|
onChange(event);
|
||||||
|
@ -33,21 +37,22 @@ function FileInput({ id, required, label, acceptType, widthClass = 'w-full', onC
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={'flex flex-col gap-2 py-2 [&:not(:first-child)]:mt-3 items-start ' + widthClass}>
|
<div className={`flex flex-col gap-2 py-2 mt-3 items-start ${widthClass}`}>
|
||||||
<input id={id} type='file'
|
<input type='file'
|
||||||
ref={inputRef}
|
ref={inputRef}
|
||||||
required={required}
|
|
||||||
style={{ display: 'none' }}
|
style={{ display: 'none' }}
|
||||||
accept={acceptType}
|
accept={acceptType}
|
||||||
onChange={handleFileChange}
|
onChange={handleFileChange}
|
||||||
|
{...props}
|
||||||
/>
|
/>
|
||||||
<Button
|
<Button
|
||||||
text={label}
|
text={label}
|
||||||
icon={<UploadIcon/>}
|
icon={<UploadIcon/>}
|
||||||
onClick={handleUploadClick}
|
onClick={handleUploadClick}
|
||||||
|
tooltip={tooltip}
|
||||||
/>
|
/>
|
||||||
<Label
|
<Label
|
||||||
text={labelText}
|
text={fileName}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
@ -14,7 +14,7 @@ function SubmitButton({
|
||||||
return (
|
return (
|
||||||
<button type='submit'
|
<button type='submit'
|
||||||
title={tooltip}
|
title={tooltip}
|
||||||
className={`px-4 py-2 inline-flex items-center gap-2 align-middle justify-center font-bold select-none disabled:cursor-not-allowed border rounded clr-btn-primary ${widthClass} ${loading ? ' cursor-progress' : ''}`}
|
className={`px-4 py-2 inline-flex items-center gap-2 align-middle justify-center font-semibold select-none disabled:cursor-not-allowed border rounded clr-btn-primary ${widthClass} ${loading ? ' cursor-progress' : ''}`}
|
||||||
disabled={disabled ?? loading}
|
disabled={disabled ?? loading}
|
||||||
>
|
>
|
||||||
{icon && <span>{icon}</span>}
|
{icon && <span>{icon}</span>}
|
||||||
|
|
|
@ -1,9 +1,7 @@
|
||||||
import { type InputHTMLAttributes } from 'react';
|
|
||||||
|
|
||||||
import Label from './Label';
|
import Label from './Label';
|
||||||
|
|
||||||
interface TextInputProps
|
interface TextInputProps
|
||||||
extends Omit<InputHTMLAttributes<HTMLInputElement>, 'className' | 'title'> {
|
extends Omit<React.InputHTMLAttributes<HTMLInputElement>, 'className' | 'title'> {
|
||||||
id: string
|
id: string
|
||||||
label: string
|
label: string
|
||||||
tooltip?: string
|
tooltip?: string
|
||||||
|
|
64
rsconcept/frontend/src/components/Common/Tristate.tsx
Normal file
64
rsconcept/frontend/src/components/Common/Tristate.tsx
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
|
||||||
|
import { useMemo } from 'react';
|
||||||
|
|
||||||
|
import { CheckboxChecked, CheckboxNull } from '../Icons';
|
||||||
|
import { CheckboxProps } from './Checkbox';
|
||||||
|
import Label from './Label';
|
||||||
|
|
||||||
|
export interface TristateProps
|
||||||
|
extends Omit<CheckboxProps, 'value' | 'setValue'> {
|
||||||
|
value: boolean | null
|
||||||
|
setValue?: (newValue: boolean | null) => void
|
||||||
|
}
|
||||||
|
|
||||||
|
function Checkbox({ id, required, disabled, tooltip, label, widthClass = 'w-fit', value, setValue }: TristateProps) {
|
||||||
|
const cursor = useMemo(
|
||||||
|
() => {
|
||||||
|
if (disabled) {
|
||||||
|
return 'cursor-not-allowed';
|
||||||
|
} else if (setValue) {
|
||||||
|
return 'cursor-pointer';
|
||||||
|
} else {
|
||||||
|
return ''
|
||||||
|
}
|
||||||
|
}, [disabled, setValue]);
|
||||||
|
const bgColor = useMemo(
|
||||||
|
() => {
|
||||||
|
return value !== false ? 'clr-primary' : 'clr-app'
|
||||||
|
}, [value]);
|
||||||
|
|
||||||
|
function handleClick(event: React.MouseEvent<HTMLButtonElement, MouseEvent>): void {
|
||||||
|
event.preventDefault();
|
||||||
|
if (disabled || !setValue) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (value === false) {
|
||||||
|
setValue(null);
|
||||||
|
} else {
|
||||||
|
setValue(!value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<button
|
||||||
|
id={id}
|
||||||
|
className={`flex items-center [&:not(:first-child)]:mt-3 clr-outline focus:outline-dotted focus:outline-1 ${widthClass}`}
|
||||||
|
title={tooltip}
|
||||||
|
disabled={disabled}
|
||||||
|
onClick={handleClick}
|
||||||
|
>
|
||||||
|
<div className={`relative peer w-4 h-4 shrink-0 mt-0.5 border rounded-sm appearance-none ${bgColor} ${cursor}`} />
|
||||||
|
{ label &&
|
||||||
|
<Label
|
||||||
|
className={`${cursor} px-2 text-start`}
|
||||||
|
text={label}
|
||||||
|
required={required}
|
||||||
|
htmlFor={id}
|
||||||
|
/>}
|
||||||
|
{value && <CheckboxChecked />}
|
||||||
|
{value === null && <CheckboxNull />}
|
||||||
|
</button>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Checkbox;
|
|
@ -317,3 +317,27 @@ export function InDoor(props: IconProps) {
|
||||||
</IconSVG>
|
</IconSVG>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function CheckboxChecked() {
|
||||||
|
return (
|
||||||
|
<svg
|
||||||
|
className='absolute w-3 h-3 mt-1 ml-0.5'
|
||||||
|
viewBox='0 0 512 512'
|
||||||
|
fill='#ffffff'
|
||||||
|
>
|
||||||
|
<path d='M470.6 105.4c12.5 12.5 12.5 32.8 0 45.3l-256 256c-12.5 12.5-32.8 12.5-45.3 0l-128-128c-12.5-12.5-12.5-32.8 0-45.3s32.8-12.5 45.3 0L192 338.7l233.4-233.3c12.5-12.5 32.8-12.5 45.3 0z' />
|
||||||
|
</svg>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function CheckboxNull() {
|
||||||
|
return (
|
||||||
|
<svg
|
||||||
|
className='absolute w-3 h-3 mt-1 ml-0.5'
|
||||||
|
viewBox='0 0 512 512'
|
||||||
|
fill='#ffffff'
|
||||||
|
>
|
||||||
|
<path d='M2 7.75A.75.75 0 012.75 7h10a.75.75 0 010 1.5h-10A.75.75 0 012 7.75z' />
|
||||||
|
</svg>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
|
@ -140,7 +140,6 @@
|
||||||
.clr-footer,
|
.clr-footer,
|
||||||
.clr-modal-backdrop,
|
.clr-modal-backdrop,
|
||||||
.clr-btn-nav,
|
.clr-btn-nav,
|
||||||
.clr-checkbox,
|
|
||||||
.clr-input:disabled
|
.clr-input:disabled
|
||||||
) {
|
) {
|
||||||
background-color: var(--cl-bg-100);
|
background-color: var(--cl-bg-100);
|
||||||
|
@ -168,8 +167,7 @@
|
||||||
|
|
||||||
:is(.clr-primary,
|
:is(.clr-primary,
|
||||||
.clr-btn-primary:hover,
|
.clr-btn-primary:hover,
|
||||||
.clr-btn-primary:focus,
|
.clr-btn-primary:focus
|
||||||
.clr-checkbox:checked
|
|
||||||
) {
|
) {
|
||||||
color: var(--cl-prim-fg-100);
|
color: var(--cl-prim-fg-100);
|
||||||
background-color: var(--cl-prim-bg-100);
|
background-color: var(--cl-prim-bg-100);
|
||||||
|
|
|
@ -93,7 +93,7 @@ function CreateRSFormPage() {
|
||||||
/>
|
/>
|
||||||
<Checkbox id='common' label='Общедоступная схема'
|
<Checkbox id='common' label='Общедоступная схема'
|
||||||
value={common}
|
value={common}
|
||||||
onChange={event => setCommon(event.target.checked)}
|
setValue={value => setCommon(value ?? false)}
|
||||||
/>
|
/>
|
||||||
<FileInput id='trs' label='Загрузить из Экстеор'
|
<FileInput id='trs' label='Загрузить из Экстеор'
|
||||||
acceptType='.trs'
|
acceptType='.trs'
|
||||||
|
|
|
@ -36,38 +36,38 @@ function PickerStrategy({ value, onChange }: PickerStrategyProps) {
|
||||||
{ pickerMenu.isActive &&
|
{ pickerMenu.isActive &&
|
||||||
<Dropdown>
|
<Dropdown>
|
||||||
<DropdownCheckbox
|
<DropdownCheckbox
|
||||||
onChange={() => handleChange(LibraryFilterStrategy.MANUAL)}
|
setValue={() => handleChange(LibraryFilterStrategy.MANUAL)}
|
||||||
value={value === LibraryFilterStrategy.MANUAL}
|
value={value === LibraryFilterStrategy.MANUAL}
|
||||||
label='Отображать все'
|
label='Отображать все'
|
||||||
/>
|
/>
|
||||||
<DropdownCheckbox
|
<DropdownCheckbox
|
||||||
onChange={() => handleChange(LibraryFilterStrategy.COMMON)}
|
setValue={() => handleChange(LibraryFilterStrategy.COMMON)}
|
||||||
value={value === LibraryFilterStrategy.COMMON}
|
value={value === LibraryFilterStrategy.COMMON}
|
||||||
label='Общедоступные'
|
label='Общедоступные'
|
||||||
tooltip='Отображать только общедоступные схемы'
|
tooltip='Отображать только общедоступные схемы'
|
||||||
/>
|
/>
|
||||||
<DropdownCheckbox
|
<DropdownCheckbox
|
||||||
onChange={() => handleChange(LibraryFilterStrategy.CANONICAL)}
|
setValue={() => handleChange(LibraryFilterStrategy.CANONICAL)}
|
||||||
value={value === LibraryFilterStrategy.CANONICAL}
|
value={value === LibraryFilterStrategy.CANONICAL}
|
||||||
label='Неизменные'
|
label='Неизменные'
|
||||||
tooltip='Отображать только стандартные схемы'
|
tooltip='Отображать только стандартные схемы'
|
||||||
/>
|
/>
|
||||||
<DropdownCheckbox
|
<DropdownCheckbox
|
||||||
onChange={() => handleChange(LibraryFilterStrategy.PERSONAL)}
|
setValue={() => handleChange(LibraryFilterStrategy.PERSONAL)}
|
||||||
value={value === LibraryFilterStrategy.PERSONAL}
|
value={value === LibraryFilterStrategy.PERSONAL}
|
||||||
label='Личные'
|
label='Личные'
|
||||||
disabled={!user}
|
disabled={!user}
|
||||||
tooltip='Отображать только подписки и владеемые схемы'
|
tooltip='Отображать только подписки и владеемые схемы'
|
||||||
/>
|
/>
|
||||||
<DropdownCheckbox
|
<DropdownCheckbox
|
||||||
onChange={() => handleChange(LibraryFilterStrategy.SUBSCRIBE)}
|
setValue={() => handleChange(LibraryFilterStrategy.SUBSCRIBE)}
|
||||||
value={value === LibraryFilterStrategy.SUBSCRIBE}
|
value={value === LibraryFilterStrategy.SUBSCRIBE}
|
||||||
label='Подписки'
|
label='Подписки'
|
||||||
disabled={!user}
|
disabled={!user}
|
||||||
tooltip='Отображать только подписки'
|
tooltip='Отображать только подписки'
|
||||||
/>
|
/>
|
||||||
<DropdownCheckbox
|
<DropdownCheckbox
|
||||||
onChange={() => handleChange(LibraryFilterStrategy.OWNED)}
|
setValue={() => handleChange(LibraryFilterStrategy.OWNED)}
|
||||||
value={value === LibraryFilterStrategy.OWNED}
|
value={value === LibraryFilterStrategy.OWNED}
|
||||||
disabled={!user}
|
disabled={!user}
|
||||||
label='Я - Владелец!'
|
label='Я - Владелец!'
|
||||||
|
|
|
@ -79,7 +79,7 @@ function DlgCloneRSForm({ hideWindow }: DlgCloneRSFormProps) {
|
||||||
/>
|
/>
|
||||||
<Checkbox id='common' label='Общедоступная схема'
|
<Checkbox id='common' label='Общедоступная схема'
|
||||||
value={common}
|
value={common}
|
||||||
onChange={event => setCommon(event.target.checked)}
|
setValue={value => setCommon(value)}
|
||||||
/>
|
/>
|
||||||
</Modal>
|
</Modal>
|
||||||
);
|
);
|
||||||
|
|
|
@ -52,7 +52,7 @@ function DlgDeleteCst({ hideWindow, selected, onDelete }: DlgDeleteCstProps) {
|
||||||
<Checkbox
|
<Checkbox
|
||||||
label='Удалить зависимые конституенты'
|
label='Удалить зависимые конституенты'
|
||||||
value={expandOut}
|
value={expandOut}
|
||||||
onChange={data => setExpandOut(data.target.checked)}
|
setValue={value => setExpandOut(value)}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</Modal>
|
</Modal>
|
||||||
|
|
|
@ -81,25 +81,25 @@ function DlgGraphOptions({ hideWindow, initial, onConfirm }:DlgGraphOptionsProps
|
||||||
label='Скрыть текст'
|
label='Скрыть текст'
|
||||||
tooltip='Не отображать термины'
|
tooltip='Не отображать термины'
|
||||||
value={noTerms}
|
value={noTerms}
|
||||||
onChange={ event => setNoTerms(event.target.checked) }
|
setValue={ value => setNoTerms(value) }
|
||||||
/>
|
/>
|
||||||
<Checkbox
|
<Checkbox
|
||||||
label='Скрыть несвязанные'
|
label='Скрыть несвязанные'
|
||||||
tooltip='Неиспользуемые конституенты'
|
tooltip='Неиспользуемые конституенты'
|
||||||
value={noHermits}
|
value={noHermits}
|
||||||
onChange={ event => setNoHermits(event.target.checked) }
|
setValue={ value => setNoHermits(value) }
|
||||||
/>
|
/>
|
||||||
<Checkbox
|
<Checkbox
|
||||||
label='Скрыть шаблоны'
|
label='Скрыть шаблоны'
|
||||||
tooltip='Терм-функции и предикат-функции с параметризованными аргументами'
|
tooltip='Терм-функции и предикат-функции с параметризованными аргументами'
|
||||||
value={noTemplates}
|
value={noTemplates}
|
||||||
onChange={ event => setNoTemplates(event.target.checked) }
|
setValue={ value => setNoTemplates(value) }
|
||||||
/>
|
/>
|
||||||
<Checkbox
|
<Checkbox
|
||||||
label='Транзитивная редукция'
|
label='Транзитивная редукция'
|
||||||
tooltip='Удалить связи, образующие транзитивные пути в графе'
|
tooltip='Удалить связи, образующие транзитивные пути в графе'
|
||||||
value={noTransitive}
|
value={noTransitive}
|
||||||
onChange={ event => setNoTransitive(event.target.checked) }
|
setValue={ value => setNoTransitive(value) }
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className='flex flex-col'>
|
<div className='flex flex-col'>
|
||||||
|
@ -107,42 +107,42 @@ function DlgGraphOptions({ hideWindow, initial, onConfirm }:DlgGraphOptionsProps
|
||||||
<Checkbox
|
<Checkbox
|
||||||
label={getCstTypeLabel(CstType.BASE)}
|
label={getCstTypeLabel(CstType.BASE)}
|
||||||
value={allowBase}
|
value={allowBase}
|
||||||
onChange={ event => setAllowBase(event.target.checked) }
|
setValue={ value => setAllowBase(value) }
|
||||||
/>
|
/>
|
||||||
<Checkbox
|
<Checkbox
|
||||||
label={getCstTypeLabel(CstType.STRUCTURED)}
|
label={getCstTypeLabel(CstType.STRUCTURED)}
|
||||||
value={allowStruct}
|
value={allowStruct}
|
||||||
onChange={ event => setAllowStruct(event.target.checked) }
|
setValue={ value => setAllowStruct(value) }
|
||||||
/>
|
/>
|
||||||
<Checkbox
|
<Checkbox
|
||||||
label={getCstTypeLabel(CstType.TERM)}
|
label={getCstTypeLabel(CstType.TERM)}
|
||||||
value={allowTerm}
|
value={allowTerm}
|
||||||
onChange={ event => setAllowTerm(event.target.checked) }
|
setValue={ value => setAllowTerm(value) }
|
||||||
/>
|
/>
|
||||||
<Checkbox
|
<Checkbox
|
||||||
label={getCstTypeLabel(CstType.AXIOM)}
|
label={getCstTypeLabel(CstType.AXIOM)}
|
||||||
value={allowAxiom}
|
value={allowAxiom}
|
||||||
onChange={ event => setAllowAxiom(event.target.checked) }
|
setValue={ value => setAllowAxiom(value) }
|
||||||
/>
|
/>
|
||||||
<Checkbox
|
<Checkbox
|
||||||
label={getCstTypeLabel(CstType.FUNCTION)}
|
label={getCstTypeLabel(CstType.FUNCTION)}
|
||||||
value={allowFunction}
|
value={allowFunction}
|
||||||
onChange={ event => setAllowFunction(event.target.checked) }
|
setValue={ value => setAllowFunction(value) }
|
||||||
/>
|
/>
|
||||||
<Checkbox
|
<Checkbox
|
||||||
label={getCstTypeLabel(CstType.PREDICATE)}
|
label={getCstTypeLabel(CstType.PREDICATE)}
|
||||||
value={allowPredicate}
|
value={allowPredicate}
|
||||||
onChange={ event => setAllowPredicate(event.target.checked) }
|
setValue={ value => setAllowPredicate(value) }
|
||||||
/>
|
/>
|
||||||
<Checkbox
|
<Checkbox
|
||||||
label={getCstTypeLabel(CstType.CONSTANT)}
|
label={getCstTypeLabel(CstType.CONSTANT)}
|
||||||
value={allowConstant}
|
value={allowConstant}
|
||||||
onChange={ event => setAllowConstant(event.target.checked) }
|
setValue={ value => setAllowConstant(value) }
|
||||||
/>
|
/>
|
||||||
<Checkbox
|
<Checkbox
|
||||||
label={getCstTypeLabel(CstType.THEOREM)}
|
label={getCstTypeLabel(CstType.THEOREM)}
|
||||||
value={allowTheorem}
|
value={allowTheorem}
|
||||||
onChange={ event => setAllowTheorem(event.target.checked) }
|
setValue ={ value => setAllowTheorem(value) }
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -44,17 +44,18 @@ function DlgUploadRSForm({ hideWindow }: DlgUploadRSFormProps) {
|
||||||
onSubmit={handleSubmit}
|
onSubmit={handleSubmit}
|
||||||
submitText='Загрузить'
|
submitText='Загрузить'
|
||||||
>
|
>
|
||||||
<div className='max-w-[20rem]'>
|
<div className='flex flex-col items-center'>
|
||||||
<FileInput
|
<FileInput
|
||||||
label='Выбрать файл'
|
label='Выбрать файл'
|
||||||
acceptType='.trs'
|
acceptType='.trs'
|
||||||
onChange={handleFile}
|
onChange={handleFile}
|
||||||
/>
|
/>
|
||||||
<Checkbox
|
<Checkbox
|
||||||
label='Загружать название и комментарий'
|
label='Загружать название и комментарий'
|
||||||
value={loadMetadata}
|
value={loadMetadata}
|
||||||
onChange={event => setLoadMetadata(event.target.checked)}
|
setValue={value => setLoadMetadata(value)}
|
||||||
/>
|
widthClass='w-fit pb-2'
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</Modal>
|
</Modal>
|
||||||
);
|
);
|
||||||
|
|
|
@ -136,14 +136,14 @@ function EditorRSForm({ onDestroy, onClaim, onShare, isModified, setIsModified,
|
||||||
value={common}
|
value={common}
|
||||||
widthClass='w-fit mt-3'
|
widthClass='w-fit mt-3'
|
||||||
disabled={!isEditable}
|
disabled={!isEditable}
|
||||||
onChange={event => setCommon(event.target.checked)}
|
setValue={value => setCommon(value)}
|
||||||
/>
|
/>
|
||||||
<Checkbox id='canonical' label='Неизменная схема'
|
<Checkbox id='canonical' label='Неизменная схема'
|
||||||
widthClass='w-fit'
|
widthClass='w-fit'
|
||||||
value={canonical}
|
value={canonical}
|
||||||
tooltip='Только администраторы могут присваивать схемам неизменный статус'
|
tooltip='Только администраторы могут присваивать схемам неизменный статус'
|
||||||
disabled={!isEditable || !isForceAdmin}
|
disabled={!isEditable || !isForceAdmin}
|
||||||
onChange={event => setCanonical(event.target.checked)}
|
setValue={value => setCanonical(value)}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -415,18 +415,18 @@ function EditorTermGraph({ onOpenEdit, onCreateCst, onDeleteCst }: EditorTermGra
|
||||||
<Checkbox
|
<Checkbox
|
||||||
label='Скрыть текст'
|
label='Скрыть текст'
|
||||||
value={noTerms}
|
value={noTerms}
|
||||||
onChange={ event => setNoTerms(event.target.checked) }
|
setValue={ value => setNoTerms(value) }
|
||||||
/>
|
/>
|
||||||
<Checkbox
|
<Checkbox
|
||||||
label='Транзитивная редукция'
|
label='Транзитивная редукция'
|
||||||
value={noTransitive}
|
value={noTransitive}
|
||||||
onChange={ event => setNoTransitive(event.target.checked) }
|
setValue={ value => setNoTransitive(value) }
|
||||||
/>
|
/>
|
||||||
<Checkbox
|
<Checkbox
|
||||||
disabled={!is3D}
|
disabled={!is3D}
|
||||||
label='Анимация вращения'
|
label='Анимация вращения'
|
||||||
value={orbit}
|
value={orbit}
|
||||||
onChange={ event => setOrbit(event.target.checked) }
|
setValue={ value => setOrbit(value) }
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Divider margins='mt-3 mb-2' />
|
<Divider margins='mt-3 mb-2' />
|
||||||
|
|
|
@ -146,14 +146,14 @@ function RSTabsMenu({
|
||||||
{(isOwned || user?.is_staff) &&
|
{(isOwned || user?.is_staff) &&
|
||||||
<DropdownCheckbox
|
<DropdownCheckbox
|
||||||
value={isReadonly}
|
value={isReadonly}
|
||||||
onChange={toggleReadonly}
|
setValue={toggleReadonly}
|
||||||
label='Я — читатель!'
|
label='Я — читатель!'
|
||||||
tooltip='Режим чтения'
|
tooltip='Режим чтения'
|
||||||
/>}
|
/>}
|
||||||
{user?.is_staff &&
|
{user?.is_staff &&
|
||||||
<DropdownCheckbox
|
<DropdownCheckbox
|
||||||
value={isForceAdmin}
|
value={isForceAdmin}
|
||||||
onChange={toggleForceAdmin}
|
setValue={toggleForceAdmin}
|
||||||
label='Я — администратор!'
|
label='Я — администратор!'
|
||||||
tooltip='Режим редактирования для администраторов'
|
tooltip='Режим редактирования для администраторов'
|
||||||
/>}
|
/>}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user