R: Unify components API for user inputs
This commit is contained in:
parent
4cf24d0200
commit
e0abbe6534
|
@ -17,6 +17,9 @@ import { describeConstituenta } from '@/utils/labels';
|
||||||
|
|
||||||
interface PickConstituentaProps extends CProps.Styling {
|
interface PickConstituentaProps extends CProps.Styling {
|
||||||
id?: string;
|
id?: string;
|
||||||
|
value?: IConstituenta;
|
||||||
|
onChange: (newValue: IConstituenta) => void;
|
||||||
|
|
||||||
prefixID: string;
|
prefixID: string;
|
||||||
data?: IConstituenta[];
|
data?: IConstituenta[];
|
||||||
rows?: number;
|
rows?: number;
|
||||||
|
@ -25,9 +28,6 @@ interface PickConstituentaProps extends CProps.Styling {
|
||||||
onBeginFilter?: (cst: IConstituenta) => boolean;
|
onBeginFilter?: (cst: IConstituenta) => boolean;
|
||||||
describeFunc?: (cst: IConstituenta) => string;
|
describeFunc?: (cst: IConstituenta) => string;
|
||||||
matchFunc?: (cst: IConstituenta, filter: string) => boolean;
|
matchFunc?: (cst: IConstituenta, filter: string) => boolean;
|
||||||
|
|
||||||
value?: IConstituenta;
|
|
||||||
onSelectValue: (newValue: IConstituenta) => void;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const columnHelper = createColumnHelper<IConstituenta>();
|
const columnHelper = createColumnHelper<IConstituenta>();
|
||||||
|
@ -42,7 +42,7 @@ function PickConstituenta({
|
||||||
describeFunc = describeConstituenta,
|
describeFunc = describeConstituenta,
|
||||||
matchFunc = (cst, filter) => matchConstituenta(cst, filter, CstMatchMode.ALL),
|
matchFunc = (cst, filter) => matchConstituenta(cst, filter, CstMatchMode.ALL),
|
||||||
onBeginFilter,
|
onBeginFilter,
|
||||||
onSelectValue,
|
onChange,
|
||||||
className,
|
className,
|
||||||
...restProps
|
...restProps
|
||||||
}: PickConstituentaProps) {
|
}: PickConstituentaProps) {
|
||||||
|
@ -110,7 +110,7 @@ function PickConstituenta({
|
||||||
<p>Измените параметры фильтра</p>
|
<p>Измените параметры фильтра</p>
|
||||||
</NoData>
|
</NoData>
|
||||||
}
|
}
|
||||||
onRowClicked={onSelectValue}
|
onRowClicked={onChange}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
@ -18,15 +18,15 @@ import ToolbarGraphSelection from './ToolbarGraphSelection';
|
||||||
|
|
||||||
interface PickMultiConstituentaProps extends CProps.Styling {
|
interface PickMultiConstituentaProps extends CProps.Styling {
|
||||||
id?: string;
|
id?: string;
|
||||||
|
value: ConstituentaID[];
|
||||||
|
onChange: React.Dispatch<React.SetStateAction<ConstituentaID[]>>;
|
||||||
|
|
||||||
schema: IRSForm;
|
schema: IRSForm;
|
||||||
data: IConstituenta[];
|
data: IConstituenta[];
|
||||||
|
|
||||||
prefixID: string;
|
prefixID: string;
|
||||||
rows?: number;
|
rows?: number;
|
||||||
noBorder?: boolean;
|
noBorder?: boolean;
|
||||||
|
|
||||||
selected: ConstituentaID[];
|
|
||||||
setSelected: React.Dispatch<React.SetStateAction<ConstituentaID[]>>;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const columnHelper = createColumnHelper<IConstituenta>();
|
const columnHelper = createColumnHelper<IConstituenta>();
|
||||||
|
@ -38,8 +38,8 @@ function PickMultiConstituenta({
|
||||||
prefixID,
|
prefixID,
|
||||||
rows,
|
rows,
|
||||||
noBorder,
|
noBorder,
|
||||||
selected,
|
value,
|
||||||
setSelected,
|
onChange,
|
||||||
className,
|
className,
|
||||||
...restProps
|
...restProps
|
||||||
}: PickMultiConstituentaProps) {
|
}: PickMultiConstituentaProps) {
|
||||||
|
@ -74,10 +74,10 @@ function PickMultiConstituenta({
|
||||||
}
|
}
|
||||||
const newRowSelection: RowSelectionState = {};
|
const newRowSelection: RowSelectionState = {};
|
||||||
filtered.forEach((cst, index) => {
|
filtered.forEach((cst, index) => {
|
||||||
newRowSelection[String(index)] = selected.includes(cst.id);
|
newRowSelection[String(index)] = value.includes(cst.id);
|
||||||
});
|
});
|
||||||
setRowSelection(newRowSelection);
|
setRowSelection(newRowSelection);
|
||||||
}, [filtered, setRowSelection, selected]);
|
}, [filtered, setRowSelection, value]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (data.length === 0) {
|
if (data.length === 0) {
|
||||||
|
@ -91,7 +91,7 @@ function PickMultiConstituenta({
|
||||||
|
|
||||||
function handleRowSelection(updater: React.SetStateAction<RowSelectionState>) {
|
function handleRowSelection(updater: React.SetStateAction<RowSelectionState>) {
|
||||||
if (!data) {
|
if (!data) {
|
||||||
setSelected([]);
|
onChange([]);
|
||||||
} else {
|
} else {
|
||||||
const newRowSelection = typeof updater === 'function' ? updater(rowSelection) : updater;
|
const newRowSelection = typeof updater === 'function' ? updater(rowSelection) : updater;
|
||||||
const newSelection: ConstituentaID[] = [];
|
const newSelection: ConstituentaID[] = [];
|
||||||
|
@ -100,7 +100,7 @@ function PickMultiConstituenta({
|
||||||
newSelection.push(cst.id);
|
newSelection.push(cst.id);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
setSelected(prev => [...prev.filter(cst_id => !filtered.find(cst => cst.id === cst_id)), ...newSelection]);
|
onChange(prev => [...prev.filter(cst_id => !filtered.find(cst => cst.id === cst_id)), ...newSelection]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -122,7 +122,7 @@ function PickMultiConstituenta({
|
||||||
<div className={clsx(noBorder ? '' : 'border', className)} {...restProps}>
|
<div className={clsx(noBorder ? '' : 'border', className)} {...restProps}>
|
||||||
<div className={clsx('px-3 flex justify-between items-center', 'clr-input', 'border-b', 'rounded-t-md')}>
|
<div className={clsx('px-3 flex justify-between items-center', 'clr-input', 'border-b', 'rounded-t-md')}>
|
||||||
<div className='w-[24ch] select-none whitespace-nowrap'>
|
<div className='w-[24ch] select-none whitespace-nowrap'>
|
||||||
{data.length > 0 ? `Выбраны ${selected.length} из ${data.length}` : 'Конституенты'}
|
{data.length > 0 ? `Выбраны ${value.length} из ${data.length}` : 'Конституенты'}
|
||||||
</div>
|
</div>
|
||||||
<SearchBar
|
<SearchBar
|
||||||
id='dlg_constituents_search'
|
id='dlg_constituents_search'
|
||||||
|
@ -135,9 +135,9 @@ function PickMultiConstituenta({
|
||||||
graph={foldedGraph}
|
graph={foldedGraph}
|
||||||
isCore={cstID => isBasicConcept(schema.cstByID.get(cstID)?.cst_type)}
|
isCore={cstID => isBasicConcept(schema.cstByID.get(cstID)?.cst_type)}
|
||||||
isOwned={cstID => !schema.cstByID.get(cstID)?.is_inherited}
|
isOwned={cstID => !schema.cstByID.get(cstID)?.is_inherited}
|
||||||
selected={selected}
|
value={value}
|
||||||
setSelected={setSelected}
|
onChange={onChange}
|
||||||
emptySelection={selected.length === 0}
|
emptySelection={value.length === 0}
|
||||||
className='w-fit'
|
className='w-fit'
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -12,36 +12,36 @@ import NoData from '@/components/ui/NoData';
|
||||||
import { IOperation, OperationID } from '@/models/oss';
|
import { IOperation, OperationID } from '@/models/oss';
|
||||||
|
|
||||||
interface PickMultiOperationProps extends CProps.Styling {
|
interface PickMultiOperationProps extends CProps.Styling {
|
||||||
rows?: number;
|
value: OperationID[];
|
||||||
|
onChange: React.Dispatch<React.SetStateAction<OperationID[]>>;
|
||||||
|
|
||||||
items: IOperation[];
|
items: IOperation[];
|
||||||
selected: OperationID[];
|
rows?: number;
|
||||||
setSelected: React.Dispatch<React.SetStateAction<OperationID[]>>;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const columnHelper = createColumnHelper<IOperation>();
|
const columnHelper = createColumnHelper<IOperation>();
|
||||||
|
|
||||||
function PickMultiOperation({ rows, items, selected, setSelected, className, ...restProps }: PickMultiOperationProps) {
|
function PickMultiOperation({ rows, items, value, onChange, className, ...restProps }: PickMultiOperationProps) {
|
||||||
const selectedItems = selected.map(itemID => items.find(item => item.id === itemID)!);
|
const selectedItems = value.map(itemID => items.find(item => item.id === itemID)!);
|
||||||
const nonSelectedItems = items.filter(item => !selected.includes(item.id));
|
const nonSelectedItems = items.filter(item => !value.includes(item.id));
|
||||||
const [lastSelected, setLastSelected] = useState<IOperation | undefined>(undefined);
|
const [lastSelected, setLastSelected] = useState<IOperation | undefined>(undefined);
|
||||||
|
|
||||||
function handleDelete(operation: OperationID) {
|
function handleDelete(operation: OperationID) {
|
||||||
setSelected(prev => prev.filter(item => item !== operation));
|
onChange(prev => prev.filter(item => item !== operation));
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleSelect(operation?: IOperation) {
|
function handleSelect(operation?: IOperation) {
|
||||||
if (operation) {
|
if (operation) {
|
||||||
setLastSelected(operation);
|
setLastSelected(operation);
|
||||||
setSelected(prev => [...prev, operation.id]);
|
onChange(prev => [...prev, operation.id]);
|
||||||
setTimeout(() => setLastSelected(undefined), 1000);
|
setTimeout(() => setLastSelected(undefined), 1000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleMoveUp(operation: OperationID) {
|
function handleMoveUp(operation: OperationID) {
|
||||||
const index = selected.indexOf(operation);
|
const index = value.indexOf(operation);
|
||||||
if (index > 0) {
|
if (index > 0) {
|
||||||
setSelected(prev => {
|
onChange(prev => {
|
||||||
const newSelected = [...prev];
|
const newSelected = [...prev];
|
||||||
newSelected[index] = newSelected[index - 1];
|
newSelected[index] = newSelected[index - 1];
|
||||||
newSelected[index - 1] = operation;
|
newSelected[index - 1] = operation;
|
||||||
|
@ -51,9 +51,9 @@ function PickMultiOperation({ rows, items, selected, setSelected, className, ...
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleMoveDown(operation: OperationID) {
|
function handleMoveDown(operation: OperationID) {
|
||||||
const index = selected.indexOf(operation);
|
const index = value.indexOf(operation);
|
||||||
if (index < selected.length - 1) {
|
if (index < value.length - 1) {
|
||||||
setSelected(prev => {
|
onChange(prev => {
|
||||||
const newSelected = [...prev];
|
const newSelected = [...prev];
|
||||||
newSelected[index] = newSelected[index + 1];
|
newSelected[index] = newSelected[index + 1];
|
||||||
newSelected[index + 1] = operation;
|
newSelected[index + 1] = operation;
|
||||||
|
@ -118,7 +118,7 @@ function PickMultiOperation({ rows, items, selected, setSelected, className, ...
|
||||||
noBorder
|
noBorder
|
||||||
items={nonSelectedItems} // prettier: split-line
|
items={nonSelectedItems} // prettier: split-line
|
||||||
value={lastSelected}
|
value={lastSelected}
|
||||||
onSelectValue={handleSelect}
|
onChange={handleSelect}
|
||||||
/>
|
/>
|
||||||
<DataTable
|
<DataTable
|
||||||
dense
|
dense
|
||||||
|
|
|
@ -19,14 +19,15 @@ import SelectLocation from './SelectLocation';
|
||||||
|
|
||||||
interface PickSchemaProps extends CProps.Styling {
|
interface PickSchemaProps extends CProps.Styling {
|
||||||
id?: string;
|
id?: string;
|
||||||
|
value?: LibraryItemID;
|
||||||
|
onChange: (newValue: LibraryItemID) => void;
|
||||||
|
|
||||||
initialFilter?: string;
|
initialFilter?: string;
|
||||||
rows?: number;
|
rows?: number;
|
||||||
|
|
||||||
items: ILibraryItem[];
|
items: ILibraryItem[];
|
||||||
itemType: LibraryItemType;
|
itemType: LibraryItemType;
|
||||||
value?: LibraryItemID;
|
|
||||||
baseFilter?: (target: ILibraryItem) => boolean;
|
baseFilter?: (target: ILibraryItem) => boolean;
|
||||||
onSelectValue: (newValue: LibraryItemID) => void;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const columnHelper = createColumnHelper<ILibraryItem>();
|
const columnHelper = createColumnHelper<ILibraryItem>();
|
||||||
|
@ -38,7 +39,7 @@ function PickSchema({
|
||||||
items,
|
items,
|
||||||
itemType,
|
itemType,
|
||||||
value,
|
value,
|
||||||
onSelectValue,
|
onChange,
|
||||||
baseFilter,
|
baseFilter,
|
||||||
className,
|
className,
|
||||||
...restProps
|
...restProps
|
||||||
|
@ -156,7 +157,7 @@ function PickSchema({
|
||||||
<p>Измените параметры фильтра</p>
|
<p>Измените параметры фильтра</p>
|
||||||
</FlexColumn>
|
</FlexColumn>
|
||||||
}
|
}
|
||||||
onRowClicked={rowData => onSelectValue(rowData.id)}
|
onRowClicked={rowData => onChange(rowData.id)}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
@ -20,8 +20,9 @@ import { errors } from '@/utils/labels';
|
||||||
import SelectLibraryItem from './SelectLibraryItem';
|
import SelectLibraryItem from './SelectLibraryItem';
|
||||||
|
|
||||||
interface PickSubstitutionsProps extends CProps.Styling {
|
interface PickSubstitutionsProps extends CProps.Styling {
|
||||||
substitutions: ICstSubstitute[];
|
value: ICstSubstitute[];
|
||||||
setSubstitutions: React.Dispatch<React.SetStateAction<ICstSubstitute[]>>;
|
onChange: React.Dispatch<React.SetStateAction<ICstSubstitute[]>>;
|
||||||
|
|
||||||
suggestions?: ICstSubstitute[];
|
suggestions?: ICstSubstitute[];
|
||||||
|
|
||||||
prefixID: string;
|
prefixID: string;
|
||||||
|
@ -35,8 +36,8 @@ interface PickSubstitutionsProps extends CProps.Styling {
|
||||||
const columnHelper = createColumnHelper<IMultiSubstitution>();
|
const columnHelper = createColumnHelper<IMultiSubstitution>();
|
||||||
|
|
||||||
function PickSubstitutions({
|
function PickSubstitutions({
|
||||||
substitutions,
|
value,
|
||||||
setSubstitutions,
|
onChange,
|
||||||
suggestions,
|
suggestions,
|
||||||
prefixID,
|
prefixID,
|
||||||
rows,
|
rows,
|
||||||
|
@ -66,7 +67,7 @@ function PickSubstitutions({
|
||||||
) ?? [];
|
) ?? [];
|
||||||
|
|
||||||
const substitutionData: IMultiSubstitution[] = [
|
const substitutionData: IMultiSubstitution[] = [
|
||||||
...substitutions.map(item => ({
|
...value.map(item => ({
|
||||||
original_source: getSchemaByCst(item.original)!,
|
original_source: getSchemaByCst(item.original)!,
|
||||||
original: getConstituenta(item.original)!,
|
original: getConstituenta(item.original)!,
|
||||||
substitution: getConstituenta(item.substitution)!,
|
substitution: getConstituenta(item.substitution)!,
|
||||||
|
@ -110,8 +111,8 @@ function PickSubstitutions({
|
||||||
original: deleteRight ? rightCst.id : leftCst.id,
|
original: deleteRight ? rightCst.id : leftCst.id,
|
||||||
substitution: deleteRight ? leftCst.id : rightCst.id
|
substitution: deleteRight ? leftCst.id : rightCst.id
|
||||||
};
|
};
|
||||||
const toDelete = substitutions.map(item => item.original);
|
const toDelete = value.map(item => item.original);
|
||||||
const replacements = substitutions.map(item => item.substitution);
|
const replacements = value.map(item => item.substitution);
|
||||||
if (
|
if (
|
||||||
toDelete.includes(newSubstitution.original) ||
|
toDelete.includes(newSubstitution.original) ||
|
||||||
toDelete.includes(newSubstitution.substitution) ||
|
toDelete.includes(newSubstitution.substitution) ||
|
||||||
|
@ -126,7 +127,7 @@ function PickSubstitutions({
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
setSubstitutions(prev => [...prev, newSubstitution]);
|
onChange(prev => [...prev, newSubstitution]);
|
||||||
setLeftCst(undefined);
|
setLeftCst(undefined);
|
||||||
setRightCst(undefined);
|
setRightCst(undefined);
|
||||||
}
|
}
|
||||||
|
@ -136,12 +137,12 @@ function PickSubstitutions({
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleAcceptSuggestion(item: IMultiSubstitution) {
|
function handleAcceptSuggestion(item: IMultiSubstitution) {
|
||||||
setSubstitutions(prev => [...prev, { original: item.original.id, substitution: item.substitution.id }]);
|
onChange(prev => [...prev, { original: item.original.id, substitution: item.substitution.id }]);
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleDeleteSubstitution(target: IMultiSubstitution) {
|
function handleDeleteSubstitution(target: IMultiSubstitution) {
|
||||||
handleDeclineSuggestion(target);
|
handleDeclineSuggestion(target);
|
||||||
setSubstitutions(prev => {
|
onChange(prev => {
|
||||||
const newItems: ICstSubstitute[] = [];
|
const newItems: ICstSubstitute[] = [];
|
||||||
prev.forEach(item => {
|
prev.forEach(item => {
|
||||||
if (item.original !== target.original.id || item.substitution !== target.substitution.id) {
|
if (item.original !== target.original.id || item.substitution !== target.substitution.id) {
|
||||||
|
@ -230,15 +231,15 @@ function PickSubstitutions({
|
||||||
placeholder='Выберите аргумент'
|
placeholder='Выберите аргумент'
|
||||||
items={allowSelfSubstitution ? schemas : schemas.filter(item => item.id !== rightArgument?.id)}
|
items={allowSelfSubstitution ? schemas : schemas.filter(item => item.id !== rightArgument?.id)}
|
||||||
value={leftArgument}
|
value={leftArgument}
|
||||||
onSelectValue={setLeftArgument}
|
onChange={setLeftArgument}
|
||||||
/>
|
/>
|
||||||
<SelectConstituenta
|
<SelectConstituenta
|
||||||
noBorder
|
noBorder
|
||||||
items={(leftArgument as IRSForm)?.items.filter(
|
items={(leftArgument as IRSForm)?.items.filter(
|
||||||
cst => !substitutions.find(item => item.original === cst.id) && (!filter || filter(cst))
|
cst => !value.find(item => item.original === cst.id) && (!filter || filter(cst))
|
||||||
)}
|
)}
|
||||||
value={leftCst}
|
value={leftCst}
|
||||||
onSelectValue={setLeftCst}
|
onChange={setLeftCst}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className='flex flex-col gap-1'>
|
<div className='flex flex-col gap-1'>
|
||||||
|
@ -268,15 +269,15 @@ function PickSubstitutions({
|
||||||
placeholder='Выберите аргумент'
|
placeholder='Выберите аргумент'
|
||||||
items={allowSelfSubstitution ? schemas : schemas.filter(item => item.id !== leftArgument?.id)}
|
items={allowSelfSubstitution ? schemas : schemas.filter(item => item.id !== leftArgument?.id)}
|
||||||
value={rightArgument}
|
value={rightArgument}
|
||||||
onSelectValue={setRightArgument}
|
onChange={setRightArgument}
|
||||||
/>
|
/>
|
||||||
<SelectConstituenta
|
<SelectConstituenta
|
||||||
noBorder
|
noBorder
|
||||||
items={(rightArgument as IRSForm)?.items.filter(
|
items={(rightArgument as IRSForm)?.items.filter(
|
||||||
cst => !substitutions.find(item => item.original === cst.id) && (!filter || filter(cst))
|
cst => !value.find(item => item.original === cst.id) && (!filter || filter(cst))
|
||||||
)}
|
)}
|
||||||
value={rightCst}
|
value={rightCst}
|
||||||
onSelectValue={setRightCst}
|
onChange={setRightCst}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -15,6 +15,7 @@ import { describeAccessPolicy, labelAccessPolicy } from '@/utils/labels';
|
||||||
interface SelectAccessPolicyProps extends CProps.Styling {
|
interface SelectAccessPolicyProps extends CProps.Styling {
|
||||||
value: AccessPolicy;
|
value: AccessPolicy;
|
||||||
onChange: (value: AccessPolicy) => void;
|
onChange: (value: AccessPolicy) => void;
|
||||||
|
|
||||||
disabled?: boolean;
|
disabled?: boolean;
|
||||||
stretchLeft?: boolean;
|
stretchLeft?: boolean;
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,10 +10,10 @@ import { matchConstituenta } from '@/models/rsformAPI';
|
||||||
import { describeConstituenta, describeConstituentaTerm } from '@/utils/labels';
|
import { describeConstituenta, describeConstituentaTerm } from '@/utils/labels';
|
||||||
|
|
||||||
interface SelectConstituentaProps extends CProps.Styling {
|
interface SelectConstituentaProps extends CProps.Styling {
|
||||||
items?: IConstituenta[];
|
|
||||||
value?: IConstituenta;
|
value?: IConstituenta;
|
||||||
onSelectValue: (newValue?: IConstituenta) => void;
|
onChange: (newValue?: IConstituenta) => void;
|
||||||
|
|
||||||
|
items?: IConstituenta[];
|
||||||
placeholder?: string;
|
placeholder?: string;
|
||||||
noBorder?: boolean;
|
noBorder?: boolean;
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,7 @@ function SelectConstituenta({
|
||||||
className,
|
className,
|
||||||
items,
|
items,
|
||||||
value,
|
value,
|
||||||
onSelectValue,
|
onChange,
|
||||||
placeholder = 'Выберите конституенту',
|
placeholder = 'Выберите конституенту',
|
||||||
...restProps
|
...restProps
|
||||||
}: SelectConstituentaProps) {
|
}: SelectConstituentaProps) {
|
||||||
|
@ -42,7 +42,7 @@ function SelectConstituenta({
|
||||||
className={clsx('text-ellipsis', className)}
|
className={clsx('text-ellipsis', className)}
|
||||||
options={options}
|
options={options}
|
||||||
value={value ? { value: value.id, label: `${value.alias}: ${describeConstituentaTerm(value)}` } : null}
|
value={value ? { value: value.id, label: `${value.alias}: ${describeConstituentaTerm(value)}` } : null}
|
||||||
onChange={data => onSelectValue(items?.find(cst => cst.id === data?.value))}
|
onChange={data => onChange(items?.find(cst => cst.id === data?.value))}
|
||||||
// @ts-expect-error: TODO: use type definitions from react-select in filter object
|
// @ts-expect-error: TODO: use type definitions from react-select in filter object
|
||||||
filterOption={filter}
|
filterOption={filter}
|
||||||
placeholder={placeholder}
|
placeholder={placeholder}
|
||||||
|
|
|
@ -15,8 +15,8 @@ import { describeCstSource, labelCstSource } from '@/utils/labels';
|
||||||
|
|
||||||
interface SelectGraphFilterProps extends CProps.Styling {
|
interface SelectGraphFilterProps extends CProps.Styling {
|
||||||
value: DependencyMode;
|
value: DependencyMode;
|
||||||
dense?: boolean;
|
|
||||||
onChange: (value: DependencyMode) => void;
|
onChange: (value: DependencyMode) => void;
|
||||||
|
dense?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
function SelectGraphFilter({ value, dense, onChange, ...restProps }: SelectGraphFilterProps) {
|
function SelectGraphFilter({ value, dense, onChange, ...restProps }: SelectGraphFilterProps) {
|
||||||
|
|
|
@ -10,7 +10,7 @@ import { matchLibraryItem } from '@/models/libraryAPI';
|
||||||
interface SelectLibraryItemProps extends CProps.Styling {
|
interface SelectLibraryItemProps extends CProps.Styling {
|
||||||
items?: ILibraryItem[];
|
items?: ILibraryItem[];
|
||||||
value?: ILibraryItem;
|
value?: ILibraryItem;
|
||||||
onSelectValue: (newValue?: ILibraryItem) => void;
|
onChange: (newValue?: ILibraryItem) => void;
|
||||||
|
|
||||||
placeholder?: string;
|
placeholder?: string;
|
||||||
noBorder?: boolean;
|
noBorder?: boolean;
|
||||||
|
@ -20,7 +20,7 @@ function SelectLibraryItem({
|
||||||
className,
|
className,
|
||||||
items,
|
items,
|
||||||
value,
|
value,
|
||||||
onSelectValue,
|
onChange,
|
||||||
placeholder = 'Выберите схему',
|
placeholder = 'Выберите схему',
|
||||||
...restProps
|
...restProps
|
||||||
}: SelectLibraryItemProps) {
|
}: SelectLibraryItemProps) {
|
||||||
|
@ -40,7 +40,7 @@ function SelectLibraryItem({
|
||||||
className={clsx('text-ellipsis', className)}
|
className={clsx('text-ellipsis', className)}
|
||||||
options={options}
|
options={options}
|
||||||
value={value ? { value: value.id, label: `${value.alias}: ${value.title}` } : null}
|
value={value ? { value: value.id, label: `${value.alias}: ${value.title}` } : null}
|
||||||
onChange={data => onSelectValue(items?.find(cst => cst.id === data?.value))}
|
onChange={data => onChange(items?.find(cst => cst.id === data?.value))}
|
||||||
// @ts-expect-error: TODO: use type definitions from react-select in filter object
|
// @ts-expect-error: TODO: use type definitions from react-select in filter object
|
||||||
filterOption={filter}
|
filterOption={filter}
|
||||||
placeholder={placeholder}
|
placeholder={placeholder}
|
||||||
|
|
|
@ -12,9 +12,10 @@ import { labelFolderNode } from '@/utils/labels';
|
||||||
|
|
||||||
interface SelectLocationProps extends CProps.Styling {
|
interface SelectLocationProps extends CProps.Styling {
|
||||||
value: string;
|
value: string;
|
||||||
|
onClick: (event: CProps.EventMouse, target: FolderNode) => void;
|
||||||
|
|
||||||
prefix: string;
|
prefix: string;
|
||||||
dense?: boolean;
|
dense?: boolean;
|
||||||
onClick: (event: CProps.EventMouse, target: FolderNode) => void;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function SelectLocation({ value, dense, prefix, onClick, className, style }: SelectLocationProps) {
|
function SelectLocation({ value, dense, prefix, onClick, className, style }: SelectLocationProps) {
|
||||||
|
|
|
@ -14,10 +14,9 @@ import SelectLocation from './SelectLocation';
|
||||||
|
|
||||||
interface SelectLocationContextProps extends CProps.Styling {
|
interface SelectLocationContextProps extends CProps.Styling {
|
||||||
value: string;
|
value: string;
|
||||||
|
onChange: (newValue: string) => void;
|
||||||
title?: string;
|
title?: string;
|
||||||
stretchTop?: boolean;
|
stretchTop?: boolean;
|
||||||
|
|
||||||
onChange: (newValue: string) => void;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function SelectLocationContext({
|
function SelectLocationContext({
|
||||||
|
|
|
@ -15,8 +15,8 @@ import { describeCstMatchMode, labelCstMatchMode } from '@/utils/labels';
|
||||||
|
|
||||||
interface SelectMatchModeProps extends CProps.Styling {
|
interface SelectMatchModeProps extends CProps.Styling {
|
||||||
value: CstMatchMode;
|
value: CstMatchMode;
|
||||||
dense?: boolean;
|
|
||||||
onChange: (value: CstMatchMode) => void;
|
onChange: (value: CstMatchMode) => void;
|
||||||
|
dense?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
function SelectMatchMode({ value, dense, onChange, ...restProps }: SelectMatchModeProps) {
|
function SelectMatchMode({ value, dense, onChange, ...restProps }: SelectMatchModeProps) {
|
||||||
|
|
|
@ -10,11 +10,11 @@ interface SelectMultiGrammemeProps
|
||||||
extends Omit<SelectMultiProps<IGrammemeOption>, 'value' | 'onChange'>,
|
extends Omit<SelectMultiProps<IGrammemeOption>, 'value' | 'onChange'>,
|
||||||
CProps.Styling {
|
CProps.Styling {
|
||||||
value: IGrammemeOption[];
|
value: IGrammemeOption[];
|
||||||
onChangeValue: (newValue: IGrammemeOption[]) => void;
|
onChange: (newValue: IGrammemeOption[]) => void;
|
||||||
placeholder?: string;
|
placeholder?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
function SelectMultiGrammeme({ value, onChangeValue, ...restProps }: SelectMultiGrammemeProps) {
|
function SelectMultiGrammeme({ value, onChange, ...restProps }: SelectMultiGrammemeProps) {
|
||||||
const [options, setOptions] = useState<IGrammemeOption[]>([]);
|
const [options, setOptions] = useState<IGrammemeOption[]>([]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
@ -28,7 +28,7 @@ function SelectMultiGrammeme({ value, onChangeValue, ...restProps }: SelectMulti
|
||||||
<SelectMulti
|
<SelectMulti
|
||||||
options={options}
|
options={options}
|
||||||
value={value}
|
value={value}
|
||||||
onChange={newValue => onChangeValue([...newValue].sort(compareGrammemeOptions))}
|
onChange={newValue => onChange([...newValue].sort(compareGrammemeOptions))}
|
||||||
{...restProps}
|
{...restProps}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
|
@ -10,7 +10,7 @@ import { matchOperation } from '@/models/ossAPI';
|
||||||
interface SelectOperationProps extends CProps.Styling {
|
interface SelectOperationProps extends CProps.Styling {
|
||||||
items?: IOperation[];
|
items?: IOperation[];
|
||||||
value?: IOperation;
|
value?: IOperation;
|
||||||
onSelectValue: (newValue?: IOperation) => void;
|
onChange: (newValue?: IOperation) => void;
|
||||||
|
|
||||||
placeholder?: string;
|
placeholder?: string;
|
||||||
noBorder?: boolean;
|
noBorder?: boolean;
|
||||||
|
@ -20,7 +20,7 @@ function SelectOperation({
|
||||||
className,
|
className,
|
||||||
items,
|
items,
|
||||||
value,
|
value,
|
||||||
onSelectValue,
|
onChange,
|
||||||
placeholder = 'Выберите операцию',
|
placeholder = 'Выберите операцию',
|
||||||
...restProps
|
...restProps
|
||||||
}: SelectOperationProps) {
|
}: SelectOperationProps) {
|
||||||
|
@ -40,7 +40,7 @@ function SelectOperation({
|
||||||
className={clsx('text-ellipsis', className)}
|
className={clsx('text-ellipsis', className)}
|
||||||
options={options}
|
options={options}
|
||||||
value={value ? { value: value.id, label: `${value.alias}: ${value.title}` } : null}
|
value={value ? { value: value.id, label: `${value.alias}: ${value.title}` } : null}
|
||||||
onChange={data => onSelectValue(items?.find(cst => cst.id === data?.value))}
|
onChange={data => onChange(items?.find(cst => cst.id === data?.value))}
|
||||||
// @ts-expect-error: TODO: use type definitions from react-select in filter object
|
// @ts-expect-error: TODO: use type definitions from react-select in filter object
|
||||||
filterOption={filter}
|
filterOption={filter}
|
||||||
placeholder={placeholder}
|
placeholder={placeholder}
|
||||||
|
|
|
@ -11,7 +11,7 @@ import { matchUser } from '@/models/userAPI';
|
||||||
|
|
||||||
interface SelectUserProps extends CProps.Styling {
|
interface SelectUserProps extends CProps.Styling {
|
||||||
value?: UserID;
|
value?: UserID;
|
||||||
onSelectValue: (newValue: UserID) => void;
|
onChange: (newValue: UserID) => void;
|
||||||
filter?: (userID: UserID) => boolean;
|
filter?: (userID: UserID) => boolean;
|
||||||
|
|
||||||
placeholder?: string;
|
placeholder?: string;
|
||||||
|
@ -22,7 +22,7 @@ function SelectUser({
|
||||||
className,
|
className,
|
||||||
filter,
|
filter,
|
||||||
value,
|
value,
|
||||||
onSelectValue,
|
onChange,
|
||||||
placeholder = 'Выберите пользователя',
|
placeholder = 'Выберите пользователя',
|
||||||
...restProps
|
...restProps
|
||||||
}: SelectUserProps) {
|
}: SelectUserProps) {
|
||||||
|
@ -46,7 +46,7 @@ function SelectUser({
|
||||||
options={options}
|
options={options}
|
||||||
value={value ? { value: value, label: getUserLabel(value) } : null}
|
value={value ? { value: value, label: getUserLabel(value) } : null}
|
||||||
onChange={data => {
|
onChange={data => {
|
||||||
if (data?.value !== undefined) onSelectValue(data.value);
|
if (data?.value !== undefined) onChange(data.value);
|
||||||
}}
|
}}
|
||||||
// @ts-expect-error: TODO: use type definitions from react-select in filter object
|
// @ts-expect-error: TODO: use type definitions from react-select in filter object
|
||||||
filterOption={filterLabel}
|
filterOption={filterLabel}
|
||||||
|
|
|
@ -11,13 +11,13 @@ interface SelectVersionProps extends CProps.Styling {
|
||||||
id?: string;
|
id?: string;
|
||||||
items?: IVersionInfo[];
|
items?: IVersionInfo[];
|
||||||
value?: VersionID;
|
value?: VersionID;
|
||||||
onSelectValue: (newValue?: VersionID) => void;
|
onChange: (newValue?: VersionID) => void;
|
||||||
|
|
||||||
placeholder?: string;
|
placeholder?: string;
|
||||||
noBorder?: boolean;
|
noBorder?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
function SelectVersion({ id, className, items, value, onSelectValue, ...restProps }: SelectVersionProps) {
|
function SelectVersion({ id, className, items, value, onChange, ...restProps }: SelectVersionProps) {
|
||||||
const options = [
|
const options = [
|
||||||
{
|
{
|
||||||
value: undefined,
|
value: undefined,
|
||||||
|
@ -40,7 +40,7 @@ function SelectVersion({ id, className, items, value, onSelectValue, ...restProp
|
||||||
className={clsx('min-w-[12rem] text-ellipsis', className)}
|
className={clsx('min-w-[12rem] text-ellipsis', className)}
|
||||||
options={options}
|
options={options}
|
||||||
value={{ value: value, label: valueLabel }}
|
value={{ value: value, label: valueLabel }}
|
||||||
onChange={data => onSelectValue(data?.value)}
|
onChange={data => onChange(data?.value)}
|
||||||
{...restProps}
|
{...restProps}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
|
@ -10,16 +10,16 @@ import { prefixes } from '@/utils/constants';
|
||||||
import { DefaultWordForms, IGrammemeOption, SelectorGrammemes } from '@/utils/selectors';
|
import { DefaultWordForms, IGrammemeOption, SelectorGrammemes } from '@/utils/selectors';
|
||||||
|
|
||||||
interface SelectWordFormProps extends CProps.Styling {
|
interface SelectWordFormProps extends CProps.Styling {
|
||||||
selected: IGrammemeOption[];
|
value: IGrammemeOption[];
|
||||||
setSelected: React.Dispatch<React.SetStateAction<IGrammemeOption[]>>;
|
onChange: React.Dispatch<React.SetStateAction<IGrammemeOption[]>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
function SelectWordForm({ selected, setSelected, className, ...restProps }: SelectWordFormProps) {
|
function SelectWordForm({ value, onChange, className, ...restProps }: SelectWordFormProps) {
|
||||||
const handleSelect = useCallback(
|
const handleSelect = useCallback(
|
||||||
(grams: Grammeme[]) => {
|
(grams: Grammeme[]) => {
|
||||||
setSelected(SelectorGrammemes.filter(({ value }) => grams.includes(value as Grammeme)));
|
onChange(SelectorGrammemes.filter(({ value }) => grams.includes(value as Grammeme)));
|
||||||
},
|
},
|
||||||
[setSelected]
|
[onChange]
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -30,7 +30,7 @@ function SelectWordForm({ selected, setSelected, className, ...restProps }: Sele
|
||||||
text={data.text}
|
text={data.text}
|
||||||
example={data.example}
|
example={data.example}
|
||||||
grams={data.grams}
|
grams={data.grams}
|
||||||
isSelected={data.grams.every(gram => selected.find(item => (item.value as Grammeme) === gram))}
|
isSelected={data.grams.every(gram => value.find(item => (item.value as Grammeme) === gram))}
|
||||||
onSelectGrams={handleSelect}
|
onSelectGrams={handleSelect}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
|
|
|
@ -17,37 +17,37 @@ import MiniButton from '@/components/ui/MiniButton';
|
||||||
import { Graph } from '@/models/Graph';
|
import { Graph } from '@/models/Graph';
|
||||||
|
|
||||||
interface ToolbarGraphSelectionProps extends CProps.Styling {
|
interface ToolbarGraphSelectionProps extends CProps.Styling {
|
||||||
|
value: number[];
|
||||||
|
onChange: (newSelection: number[]) => void;
|
||||||
graph: Graph;
|
graph: Graph;
|
||||||
selected: number[];
|
|
||||||
isCore: (item: number) => boolean;
|
isCore: (item: number) => boolean;
|
||||||
isOwned?: (item: number) => boolean;
|
isOwned?: (item: number) => boolean;
|
||||||
setSelected: (newSelection: number[]) => void;
|
|
||||||
emptySelection?: boolean;
|
emptySelection?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
function ToolbarGraphSelection({
|
function ToolbarGraphSelection({
|
||||||
className,
|
className,
|
||||||
graph,
|
graph,
|
||||||
selected,
|
value: selected,
|
||||||
isCore,
|
isCore,
|
||||||
isOwned,
|
isOwned,
|
||||||
setSelected,
|
onChange,
|
||||||
emptySelection,
|
emptySelection,
|
||||||
...restProps
|
...restProps
|
||||||
}: ToolbarGraphSelectionProps) {
|
}: ToolbarGraphSelectionProps) {
|
||||||
const handleSelectCore = useCallback(() => {
|
const handleSelectCore = useCallback(() => {
|
||||||
const core = [...graph.nodes.keys()].filter(isCore);
|
const core = [...graph.nodes.keys()].filter(isCore);
|
||||||
setSelected([...core, ...graph.expandInputs(core)]);
|
onChange([...core, ...graph.expandInputs(core)]);
|
||||||
}, [setSelected, graph, isCore]);
|
}, [onChange, graph, isCore]);
|
||||||
|
|
||||||
const handleSelectOwned = useCallback(
|
const handleSelectOwned = useCallback(
|
||||||
() => (isOwned ? setSelected([...graph.nodes.keys()].filter(isOwned)) : undefined),
|
() => (isOwned ? onChange([...graph.nodes.keys()].filter(isOwned)) : undefined),
|
||||||
[setSelected, graph, isOwned]
|
[onChange, graph, isOwned]
|
||||||
);
|
);
|
||||||
|
|
||||||
const handleInvertSelection = useCallback(
|
const handleInvertSelection = useCallback(
|
||||||
() => setSelected([...graph.nodes.keys()].filter(item => !selected.includes(item))),
|
() => onChange([...graph.nodes.keys()].filter(item => !selected.includes(item))),
|
||||||
[setSelected, selected, graph]
|
[onChange, selected, graph]
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -55,37 +55,37 @@ function ToolbarGraphSelection({
|
||||||
<MiniButton
|
<MiniButton
|
||||||
titleHtml='Сбросить выделение'
|
titleHtml='Сбросить выделение'
|
||||||
icon={<IconReset size='1.25rem' className='icon-primary' />}
|
icon={<IconReset size='1.25rem' className='icon-primary' />}
|
||||||
onClick={() => setSelected([])}
|
onClick={() => onChange([])}
|
||||||
disabled={emptySelection}
|
disabled={emptySelection}
|
||||||
/>
|
/>
|
||||||
<MiniButton
|
<MiniButton
|
||||||
titleHtml='Выделить все влияющие'
|
titleHtml='Выделить все влияющие'
|
||||||
icon={<IconGraphCollapse size='1.25rem' className='icon-primary' />}
|
icon={<IconGraphCollapse size='1.25rem' className='icon-primary' />}
|
||||||
onClick={() => setSelected([...selected, ...graph.expandAllInputs(selected)])}
|
onClick={() => onChange([...selected, ...graph.expandAllInputs(selected)])}
|
||||||
disabled={emptySelection}
|
disabled={emptySelection}
|
||||||
/>
|
/>
|
||||||
<MiniButton
|
<MiniButton
|
||||||
titleHtml='Выделить все зависимые'
|
titleHtml='Выделить все зависимые'
|
||||||
icon={<IconGraphExpand size='1.25rem' className='icon-primary' />}
|
icon={<IconGraphExpand size='1.25rem' className='icon-primary' />}
|
||||||
onClick={() => setSelected([...selected, ...graph.expandAllOutputs(selected)])}
|
onClick={() => onChange([...selected, ...graph.expandAllOutputs(selected)])}
|
||||||
disabled={emptySelection}
|
disabled={emptySelection}
|
||||||
/>
|
/>
|
||||||
<MiniButton
|
<MiniButton
|
||||||
titleHtml='<b>Максимизация</b> <br/>дополнение выделения конституентами, <br/>зависимыми только от выделенных'
|
titleHtml='<b>Максимизация</b> <br/>дополнение выделения конституентами, <br/>зависимыми только от выделенных'
|
||||||
icon={<IconGraphMaximize size='1.25rem' className='icon-primary' />}
|
icon={<IconGraphMaximize size='1.25rem' className='icon-primary' />}
|
||||||
onClick={() => setSelected(graph.maximizePart(selected))}
|
onClick={() => onChange(graph.maximizePart(selected))}
|
||||||
disabled={emptySelection}
|
disabled={emptySelection}
|
||||||
/>
|
/>
|
||||||
<MiniButton
|
<MiniButton
|
||||||
titleHtml='Выделить поставщиков'
|
titleHtml='Выделить поставщиков'
|
||||||
icon={<IconGraphInputs size='1.25rem' className='icon-primary' />}
|
icon={<IconGraphInputs size='1.25rem' className='icon-primary' />}
|
||||||
onClick={() => setSelected([...selected, ...graph.expandInputs(selected)])}
|
onClick={() => onChange([...selected, ...graph.expandInputs(selected)])}
|
||||||
disabled={emptySelection}
|
disabled={emptySelection}
|
||||||
/>
|
/>
|
||||||
<MiniButton
|
<MiniButton
|
||||||
titleHtml='Выделить потребителей'
|
titleHtml='Выделить потребителей'
|
||||||
icon={<IconGraphOutputs size='1.25rem' className='icon-primary' />}
|
icon={<IconGraphOutputs size='1.25rem' className='icon-primary' />}
|
||||||
onClick={() => setSelected([...selected, ...graph.expandOutputs(selected)])}
|
onClick={() => onChange([...selected, ...graph.expandOutputs(selected)])}
|
||||||
disabled={emptySelection}
|
disabled={emptySelection}
|
||||||
/>
|
/>
|
||||||
<MiniButton
|
<MiniButton
|
||||||
|
|
|
@ -4,7 +4,7 @@ import { CheckboxChecked } from '@/components/Icons';
|
||||||
import { CProps } from '@/components/props';
|
import { CProps } from '@/components/props';
|
||||||
import { globals } from '@/utils/constants';
|
import { globals } from '@/utils/constants';
|
||||||
|
|
||||||
export interface CheckboxProps extends Omit<CProps.Button, 'value' | 'onClick'> {
|
export interface CheckboxProps extends Omit<CProps.Button, 'value' | 'onClick' | 'onChange'> {
|
||||||
/** Label to display next to the checkbox. */
|
/** Label to display next to the checkbox. */
|
||||||
label?: string;
|
label?: string;
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@ export interface CheckboxProps extends Omit<CProps.Button, 'value' | 'onClick'>
|
||||||
value?: boolean;
|
value?: boolean;
|
||||||
|
|
||||||
/** Callback to set the `value`. */
|
/** Callback to set the `value`. */
|
||||||
setValue?: (newValue: boolean) => void;
|
onChange?: (newValue: boolean) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -29,18 +29,18 @@ function Checkbox({
|
||||||
hideTitle,
|
hideTitle,
|
||||||
className,
|
className,
|
||||||
value,
|
value,
|
||||||
setValue,
|
onChange,
|
||||||
...restProps
|
...restProps
|
||||||
}: CheckboxProps) {
|
}: CheckboxProps) {
|
||||||
const cursor = disabled ? 'cursor-arrow' : setValue ? 'cursor-pointer' : '';
|
const cursor = disabled ? 'cursor-arrow' : onChange ? 'cursor-pointer' : '';
|
||||||
|
|
||||||
function handleClick(event: CProps.EventMouse): void {
|
function handleClick(event: CProps.EventMouse): void {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
if (disabled || !setValue) {
|
if (disabled || !onChange) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
setValue(!value);
|
onChange(!value);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -6,12 +6,12 @@ import { globals } from '@/utils/constants';
|
||||||
|
|
||||||
import { CheckboxProps } from './Checkbox';
|
import { CheckboxProps } from './Checkbox';
|
||||||
|
|
||||||
export interface CheckboxTristateProps extends Omit<CheckboxProps, 'value' | 'setValue'> {
|
export interface CheckboxTristateProps extends Omit<CheckboxProps, 'value' | 'onChange'> {
|
||||||
/** Current value - `null`, `true` or `false`. */
|
/** Current value - `null`, `true` or `false`. */
|
||||||
value: boolean | null;
|
value: boolean | null;
|
||||||
|
|
||||||
/** Callback to set the `value`. */
|
/** Callback to set the `value`. */
|
||||||
setValue?: (newValue: boolean | null) => void;
|
onChange?: (newValue: boolean | null) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -25,23 +25,23 @@ function CheckboxTristate({
|
||||||
hideTitle,
|
hideTitle,
|
||||||
className,
|
className,
|
||||||
value,
|
value,
|
||||||
setValue,
|
onChange,
|
||||||
...restProps
|
...restProps
|
||||||
}: CheckboxTristateProps) {
|
}: CheckboxTristateProps) {
|
||||||
const cursor = disabled ? 'cursor-arrow' : setValue ? 'cursor-pointer' : '';
|
const cursor = disabled ? 'cursor-arrow' : onChange ? 'cursor-pointer' : '';
|
||||||
|
|
||||||
function handleClick(event: CProps.EventMouse): void {
|
function handleClick(event: CProps.EventMouse): void {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
if (disabled || !setValue) {
|
if (disabled || !onChange) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (value === false) {
|
if (value === false) {
|
||||||
setValue(null);
|
onChange(null);
|
||||||
} else if (value === null) {
|
} else if (value === null) {
|
||||||
setValue(true);
|
onChange(true);
|
||||||
} else {
|
} else {
|
||||||
setValue(false);
|
onChange(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,7 @@ function SelectAll<TData>({ table, resetLastSelected }: SelectAllProps<TData>) {
|
||||||
value={
|
value={
|
||||||
!table.getIsAllPageRowsSelected() && table.getIsSomePageRowsSelected() ? null : table.getIsAllPageRowsSelected()
|
!table.getIsAllPageRowsSelected() && table.getIsSomePageRowsSelected() ? null : table.getIsAllPageRowsSelected()
|
||||||
}
|
}
|
||||||
setValue={handleChange}
|
onChange={handleChange}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,7 @@ function SelectRow<TData>({ row, onChangeLastSelected }: SelectRowProps<TData>)
|
||||||
row.toggleSelected(value);
|
row.toggleSelected(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
return <Checkbox tabIndex={-1} value={row.getIsSelected()} setValue={handleChange} />;
|
return <Checkbox tabIndex={-1} value={row.getIsSelected()} onChange={handleChange} />;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default SelectRow;
|
export default SelectRow;
|
||||||
|
|
|
@ -3,7 +3,7 @@ import clsx from 'clsx';
|
||||||
import Checkbox, { CheckboxProps } from './Checkbox';
|
import Checkbox, { CheckboxProps } from './Checkbox';
|
||||||
|
|
||||||
/** Animated {@link Checkbox} inside a {@link Dropdown} item. */
|
/** Animated {@link Checkbox} inside a {@link Dropdown} item. */
|
||||||
function DropdownCheckbox({ setValue, disabled, ...restProps }: CheckboxProps) {
|
function DropdownCheckbox({ onChange: setValue, disabled, ...restProps }: CheckboxProps) {
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={clsx(
|
className={clsx(
|
||||||
|
@ -13,7 +13,7 @@ function DropdownCheckbox({ setValue, disabled, ...restProps }: CheckboxProps) {
|
||||||
!!setValue && !disabled && 'clr-hover'
|
!!setValue && !disabled && 'clr-hover'
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<Checkbox tabIndex={-1} disabled={disabled} setValue={setValue} {...restProps} />
|
<Checkbox tabIndex={-1} disabled={disabled} onChange={setValue} {...restProps} />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,7 @@ interface SelectTreeProps<ItemType> extends CProps.Styling {
|
||||||
prefix: string;
|
prefix: string;
|
||||||
|
|
||||||
/** Callback to be called when the value changes. */
|
/** Callback to be called when the value changes. */
|
||||||
onChangeValue: (newItem: ItemType) => void;
|
onChange: (newItem: ItemType) => void;
|
||||||
|
|
||||||
/** Callback providing the parent of the item. */
|
/** Callback providing the parent of the item. */
|
||||||
getParent: (item: ItemType) => ItemType;
|
getParent: (item: ItemType) => ItemType;
|
||||||
|
@ -40,7 +40,7 @@ function SelectTree<ItemType>({
|
||||||
getParent,
|
getParent,
|
||||||
getLabel,
|
getLabel,
|
||||||
getDescription,
|
getDescription,
|
||||||
onChangeValue,
|
onChange,
|
||||||
prefix,
|
prefix,
|
||||||
...restProps
|
...restProps
|
||||||
}: SelectTreeProps<ItemType>) {
|
}: SelectTreeProps<ItemType>) {
|
||||||
|
@ -75,7 +75,7 @@ function SelectTree<ItemType>({
|
||||||
function handleSetValue(event: CProps.EventMouse, target: ItemType) {
|
function handleSetValue(event: CProps.EventMouse, target: ItemType) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
onChangeValue(target);
|
onChange(target);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -61,7 +61,7 @@ function DlgChangeInputSchema() {
|
||||||
items={sortedItems}
|
items={sortedItems}
|
||||||
itemType={LibraryItemType.RSFORM}
|
itemType={LibraryItemType.RSFORM}
|
||||||
value={selected} // prettier: split-line
|
value={selected} // prettier: split-line
|
||||||
onSelectValue={handleSelectLocation}
|
onChange={handleSelectLocation}
|
||||||
rows={14}
|
rows={14}
|
||||||
baseFilter={baseFilter}
|
baseFilter={baseFilter}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -6,7 +6,7 @@ import { useState } from 'react';
|
||||||
import { useConceptNavigation } from '@/app/Navigation/NavigationContext';
|
import { useConceptNavigation } from '@/app/Navigation/NavigationContext';
|
||||||
import { urls } from '@/app/urls';
|
import { urls } from '@/app/urls';
|
||||||
import { useAuthSuspense } from '@/backend/auth/useAuth';
|
import { useAuthSuspense } from '@/backend/auth/useAuth';
|
||||||
import { IRSFormCloneDTO } from '@/backend/library/api';
|
import { IRCloneLibraryItemDTO } from '@/backend/library/api';
|
||||||
import { useCloneItem } from '@/backend/library/useCloneItem';
|
import { useCloneItem } from '@/backend/library/useCloneItem';
|
||||||
import { VisibilityIcon } from '@/components/DomainIcons';
|
import { VisibilityIcon } from '@/components/DomainIcons';
|
||||||
import SelectAccessPolicy from '@/components/select/SelectAccessPolicy';
|
import SelectAccessPolicy from '@/components/select/SelectAccessPolicy';
|
||||||
|
@ -59,7 +59,7 @@ function DlgCloneLibraryItem() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleSubmit() {
|
function handleSubmit() {
|
||||||
const data: IRSFormCloneDTO = {
|
const data: IRCloneLibraryItemDTO = {
|
||||||
id: base.id,
|
id: base.id,
|
||||||
item_type: base.item_type,
|
item_type: base.item_type,
|
||||||
title: title,
|
title: title,
|
||||||
|
@ -137,7 +137,7 @@ function DlgCloneLibraryItem() {
|
||||||
id='dlg_only_selected'
|
id='dlg_only_selected'
|
||||||
label={`Только выбранные конституенты [${selected.length} из ${totalCount}]`}
|
label={`Только выбранные конституенты [${selected.length} из ${totalCount}]`}
|
||||||
value={onlySelected}
|
value={onlySelected}
|
||||||
setValue={value => setOnlySelected(value)}
|
onChange={value => setOnlySelected(value)}
|
||||||
/>
|
/>
|
||||||
</Modal>
|
</Modal>
|
||||||
);
|
);
|
||||||
|
|
|
@ -98,7 +98,7 @@ function TabInputOperation({
|
||||||
</div>
|
</div>
|
||||||
<Checkbox
|
<Checkbox
|
||||||
value={createSchema}
|
value={createSchema}
|
||||||
setValue={onChangeCreateSchema}
|
onChange={onChangeCreateSchema}
|
||||||
label='Создать новую схему'
|
label='Создать новую схему'
|
||||||
titleHtml='Создать пустую схему для загрузки'
|
titleHtml='Создать пустую схему для загрузки'
|
||||||
/>
|
/>
|
||||||
|
@ -108,7 +108,7 @@ function TabInputOperation({
|
||||||
items={sortedItems}
|
items={sortedItems}
|
||||||
value={attachedID}
|
value={attachedID}
|
||||||
itemType={LibraryItemType.RSFORM}
|
itemType={LibraryItemType.RSFORM}
|
||||||
onSelectValue={onChangeAttachedID}
|
onChange={onChangeAttachedID}
|
||||||
rows={8}
|
rows={8}
|
||||||
baseFilter={baseFilter}
|
baseFilter={baseFilter}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -57,7 +57,7 @@ function TabSynthesisOperation({
|
||||||
|
|
||||||
<FlexColumn>
|
<FlexColumn>
|
||||||
<Label text={`Выбор аргументов: [ ${inputs.length} ]`} />
|
<Label text={`Выбор аргументов: [ ${inputs.length} ]`} />
|
||||||
<PickMultiOperation items={oss.items} selected={inputs} setSelected={setInputs} rows={6} />
|
<PickMultiOperation items={oss.items} value={inputs} onChange={setInputs} rows={6} />
|
||||||
</FlexColumn>
|
</FlexColumn>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
@ -64,7 +64,7 @@ function DlgCreateVersion() {
|
||||||
id='dlg_only_selected'
|
id='dlg_only_selected'
|
||||||
label={`Только выбранные конституенты [${selected.length} из ${totalCount}]`}
|
label={`Только выбранные конституенты [${selected.length} из ${totalCount}]`}
|
||||||
value={onlySelected}
|
value={onlySelected}
|
||||||
setValue={value => setOnlySelected(value)}
|
onChange={value => setOnlySelected(value)}
|
||||||
/>
|
/>
|
||||||
</Modal>
|
</Modal>
|
||||||
);
|
);
|
||||||
|
|
|
@ -190,7 +190,7 @@ function TabArguments({ state, schema, partialUpdate }: TabArgumentsProps) {
|
||||||
id='dlg_argument_picker'
|
id='dlg_argument_picker'
|
||||||
value={selectedCst}
|
value={selectedCst}
|
||||||
data={schema.items}
|
data={schema.items}
|
||||||
onSelectValue={handleSelectConstituenta}
|
onChange={handleSelectConstituenta}
|
||||||
prefixID={prefixes.cst_modal_list}
|
prefixID={prefixes.cst_modal_list}
|
||||||
rows={7}
|
rows={7}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -102,7 +102,7 @@ function TabTemplate({ state, partialUpdate, templateSchema }: TabTemplateProps)
|
||||||
id='dlg_template_picker'
|
id='dlg_template_picker'
|
||||||
value={state.prototype}
|
value={state.prototype}
|
||||||
data={filteredData}
|
data={filteredData}
|
||||||
onSelectValue={cst => partialUpdate({ prototype: cst })}
|
onChange={cst => partialUpdate({ prototype: cst })}
|
||||||
prefixID={prefixes.cst_template_ist}
|
prefixID={prefixes.cst_template_ist}
|
||||||
className='rounded-t-none'
|
className='rounded-t-none'
|
||||||
rows={8}
|
rows={8}
|
||||||
|
|
|
@ -55,7 +55,7 @@ function DlgDeleteCst() {
|
||||||
label='Удалить зависимые конституенты'
|
label='Удалить зависимые конституенты'
|
||||||
className='mb-2'
|
className='mb-2'
|
||||||
value={expandOut}
|
value={expandOut}
|
||||||
setValue={value => setExpandOut(value)}
|
onChange={value => setExpandOut(value)}
|
||||||
/>
|
/>
|
||||||
{hasInherited ? (
|
{hasInherited ? (
|
||||||
<p className='text-sm clr-text-red'>Внимание! Выбранные конституенты имеют наследников в ОСС</p>
|
<p className='text-sm clr-text-red'>Внимание! Выбранные конституенты имеют наследников в ОСС</p>
|
||||||
|
|
|
@ -39,7 +39,7 @@ function DlgDeleteOperation() {
|
||||||
label='Сохранить наследованные конституенты'
|
label='Сохранить наследованные конституенты'
|
||||||
titleHtml='Наследованные конституенты <br/>превратятся в дописанные'
|
titleHtml='Наследованные конституенты <br/>превратятся в дописанные'
|
||||||
value={keepConstituents}
|
value={keepConstituents}
|
||||||
setValue={setKeepConstituents}
|
onChange={setKeepConstituents}
|
||||||
disabled={target.result === null}
|
disabled={target.result === null}
|
||||||
/>
|
/>
|
||||||
<Checkbox
|
<Checkbox
|
||||||
|
@ -50,7 +50,7 @@ function DlgDeleteOperation() {
|
||||||
: 'Удалить схему вместе с операцией'
|
: 'Удалить схему вместе с операцией'
|
||||||
}
|
}
|
||||||
value={deleteSchema}
|
value={deleteSchema}
|
||||||
setValue={setDeleteSchema}
|
onChange={setDeleteSchema}
|
||||||
disabled={!target.is_owned || target.result === null}
|
disabled={!target.is_owned || target.result === null}
|
||||||
/>
|
/>
|
||||||
</Modal>
|
</Modal>
|
||||||
|
|
|
@ -63,7 +63,7 @@ function DlgEditEditors() {
|
||||||
<SelectUser
|
<SelectUser
|
||||||
filter={id => !selected.includes(id)}
|
filter={id => !selected.includes(id)}
|
||||||
value={undefined}
|
value={undefined}
|
||||||
onSelectValue={onAddEditor}
|
onChange={onAddEditor}
|
||||||
className='w-[25rem]'
|
className='w-[25rem]'
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -19,7 +19,7 @@ function TabArguments({ oss, inputs, target, setInputs }: TabArgumentsProps) {
|
||||||
<div className='cc-fade-in cc-column'>
|
<div className='cc-fade-in cc-column'>
|
||||||
<FlexColumn>
|
<FlexColumn>
|
||||||
<Label text={`Выбор аргументов: [ ${inputs.length} ]`} />
|
<Label text={`Выбор аргументов: [ ${inputs.length} ]`} />
|
||||||
<PickMultiOperation items={filtered} selected={inputs} setSelected={setInputs} rows={8} />
|
<PickMultiOperation items={filtered} value={inputs} onChange={setInputs} rows={8} />
|
||||||
</FlexColumn>
|
</FlexColumn>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
@ -29,8 +29,8 @@ function TabSynthesis({
|
||||||
schemas={schemas}
|
schemas={schemas}
|
||||||
prefixID={prefixes.dlg_cst_substitutes_list}
|
prefixID={prefixes.dlg_cst_substitutes_list}
|
||||||
rows={8}
|
rows={8}
|
||||||
substitutions={substitutions}
|
value={substitutions}
|
||||||
setSubstitutions={setSubstitutions}
|
onChange={setSubstitutions}
|
||||||
suggestions={suggestions}
|
suggestions={suggestions}
|
||||||
/>
|
/>
|
||||||
<TextArea
|
<TextArea
|
||||||
|
|
|
@ -64,7 +64,7 @@ function TabEntityReference({ initial, schema, onChangeValid, onChangeReference
|
||||||
initialFilter={initial.text}
|
initialFilter={initial.text}
|
||||||
value={selectedCst}
|
value={selectedCst}
|
||||||
data={schema.items}
|
data={schema.items}
|
||||||
onSelectValue={handleSelectConstituenta}
|
onChange={handleSelectConstituenta}
|
||||||
prefixID={prefixes.cst_modal_list}
|
prefixID={prefixes.cst_modal_list}
|
||||||
describeFunc={cst => cst.term_resolved}
|
describeFunc={cst => cst.term_resolved}
|
||||||
matchFunc={(cst, filter) => matchConstituenta(cst, filter, CstMatchMode.TERM)}
|
matchFunc={(cst, filter) => matchConstituenta(cst, filter, CstMatchMode.TERM)}
|
||||||
|
@ -94,7 +94,7 @@ function TabEntityReference({ initial, schema, onChangeValid, onChangeReference
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<SelectWordForm selected={selectedGrams} setSelected={setSelectedGrams} />
|
<SelectWordForm value={selectedGrams} onChange={setSelectedGrams} />
|
||||||
|
|
||||||
<div className='flex items-center gap-4'>
|
<div className='flex items-center gap-4'>
|
||||||
<Label text='Словоформа' />
|
<Label text='Словоформа' />
|
||||||
|
@ -104,7 +104,7 @@ function TabEntityReference({ initial, schema, onChangeValid, onChangeReference
|
||||||
className='flex-grow'
|
className='flex-grow'
|
||||||
menuPlacement='top'
|
menuPlacement='top'
|
||||||
value={selectedGrams}
|
value={selectedGrams}
|
||||||
onChangeValue={setSelectedGrams}
|
onChange={setSelectedGrams}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -172,7 +172,7 @@ function DlgEditWordForms() {
|
||||||
placeholder='Выберите граммемы'
|
placeholder='Выберите граммемы'
|
||||||
className='min-w-[15rem] h-fit'
|
className='min-w-[15rem] h-fit'
|
||||||
value={inputGrams}
|
value={inputGrams}
|
||||||
onChangeValue={setInputGrams}
|
onChange={setInputGrams}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -31,31 +31,31 @@ function DlgGraphParams() {
|
||||||
label='Скрыть текст'
|
label='Скрыть текст'
|
||||||
title='Не отображать термины'
|
title='Не отображать термины'
|
||||||
value={params.noText}
|
value={params.noText}
|
||||||
setValue={value => updateParams({ noText: value })}
|
onChange={value => updateParams({ noText: value })}
|
||||||
/>
|
/>
|
||||||
<Checkbox
|
<Checkbox
|
||||||
label='Скрыть несвязанные'
|
label='Скрыть несвязанные'
|
||||||
title='Неиспользуемые конституенты'
|
title='Неиспользуемые конституенты'
|
||||||
value={params.noHermits}
|
value={params.noHermits}
|
||||||
setValue={value => updateParams({ noHermits: value })}
|
onChange={value => updateParams({ noHermits: value })}
|
||||||
/>
|
/>
|
||||||
<Checkbox
|
<Checkbox
|
||||||
label='Скрыть шаблоны'
|
label='Скрыть шаблоны'
|
||||||
titleHtml='Терм-функции и предикат-функции <br/>с параметризованными аргументами'
|
titleHtml='Терм-функции и предикат-функции <br/>с параметризованными аргументами'
|
||||||
value={params.noTemplates}
|
value={params.noTemplates}
|
||||||
setValue={value => updateParams({ noTemplates: value })}
|
onChange={value => updateParams({ noTemplates: value })}
|
||||||
/>
|
/>
|
||||||
<Checkbox
|
<Checkbox
|
||||||
label='Транзитивная редукция'
|
label='Транзитивная редукция'
|
||||||
titleHtml='Удалить связи, образующие <br/>транзитивные пути в графе'
|
titleHtml='Удалить связи, образующие <br/>транзитивные пути в графе'
|
||||||
value={params.noTransitive}
|
value={params.noTransitive}
|
||||||
setValue={value => updateParams({ noTransitive: value })}
|
onChange={value => updateParams({ noTransitive: value })}
|
||||||
/>
|
/>
|
||||||
<Checkbox
|
<Checkbox
|
||||||
label='Свернуть порожденные'
|
label='Свернуть порожденные'
|
||||||
title='Не отображать порожденные понятия'
|
title='Не отображать порожденные понятия'
|
||||||
value={params.foldDerived}
|
value={params.foldDerived}
|
||||||
setValue={value => updateParams({ foldDerived: value })}
|
onChange={value => updateParams({ foldDerived: value })}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className='flex flex-col gap-1'>
|
<div className='flex flex-col gap-1'>
|
||||||
|
@ -63,42 +63,42 @@ function DlgGraphParams() {
|
||||||
<Checkbox
|
<Checkbox
|
||||||
label={labelCstType(CstType.BASE)}
|
label={labelCstType(CstType.BASE)}
|
||||||
value={params.allowBase}
|
value={params.allowBase}
|
||||||
setValue={value => updateParams({ allowBase: value })}
|
onChange={value => updateParams({ allowBase: value })}
|
||||||
/>
|
/>
|
||||||
<Checkbox
|
<Checkbox
|
||||||
label={labelCstType(CstType.STRUCTURED)}
|
label={labelCstType(CstType.STRUCTURED)}
|
||||||
value={params.allowStruct}
|
value={params.allowStruct}
|
||||||
setValue={value => updateParams({ allowStruct: value })}
|
onChange={value => updateParams({ allowStruct: value })}
|
||||||
/>
|
/>
|
||||||
<Checkbox
|
<Checkbox
|
||||||
label={labelCstType(CstType.TERM)}
|
label={labelCstType(CstType.TERM)}
|
||||||
value={params.allowTerm}
|
value={params.allowTerm}
|
||||||
setValue={value => updateParams({ allowTerm: value })}
|
onChange={value => updateParams({ allowTerm: value })}
|
||||||
/>
|
/>
|
||||||
<Checkbox
|
<Checkbox
|
||||||
label={labelCstType(CstType.AXIOM)}
|
label={labelCstType(CstType.AXIOM)}
|
||||||
value={params.allowAxiom}
|
value={params.allowAxiom}
|
||||||
setValue={value => updateParams({ allowAxiom: value })}
|
onChange={value => updateParams({ allowAxiom: value })}
|
||||||
/>
|
/>
|
||||||
<Checkbox
|
<Checkbox
|
||||||
label={labelCstType(CstType.FUNCTION)}
|
label={labelCstType(CstType.FUNCTION)}
|
||||||
value={params.allowFunction}
|
value={params.allowFunction}
|
||||||
setValue={value => updateParams({ allowFunction: value })}
|
onChange={value => updateParams({ allowFunction: value })}
|
||||||
/>
|
/>
|
||||||
<Checkbox
|
<Checkbox
|
||||||
label={labelCstType(CstType.PREDICATE)}
|
label={labelCstType(CstType.PREDICATE)}
|
||||||
value={params.allowPredicate}
|
value={params.allowPredicate}
|
||||||
setValue={value => updateParams({ allowPredicate: value })}
|
onChange={value => updateParams({ allowPredicate: value })}
|
||||||
/>
|
/>
|
||||||
<Checkbox
|
<Checkbox
|
||||||
label={labelCstType(CstType.CONSTANT)}
|
label={labelCstType(CstType.CONSTANT)}
|
||||||
value={params.allowConstant}
|
value={params.allowConstant}
|
||||||
setValue={value => updateParams({ allowConstant: value })}
|
onChange={value => updateParams({ allowConstant: value })}
|
||||||
/>
|
/>
|
||||||
<Checkbox
|
<Checkbox
|
||||||
label={labelCstType(CstType.THEOREM)}
|
label={labelCstType(CstType.THEOREM)}
|
||||||
value={params.allowTheorem}
|
value={params.allowTheorem}
|
||||||
setValue={value => updateParams({ allowTheorem: value })}
|
onChange={value => updateParams({ allowTheorem: value })}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</Modal>
|
</Modal>
|
||||||
|
|
|
@ -21,8 +21,8 @@ function TabConstituents({ itemID, selected, setSelected }: TabConstituentsProps
|
||||||
data={schema.items}
|
data={schema.items}
|
||||||
rows={13}
|
rows={13}
|
||||||
prefixID={prefixes.cst_inline_synth_list}
|
prefixID={prefixes.cst_inline_synth_list}
|
||||||
selected={selected}
|
value={selected}
|
||||||
setSelected={setSelected}
|
onChange={setSelected}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,7 @@ function TabSource({ selected, receiver, setSelected }: TabSourceProps) {
|
||||||
itemType={LibraryItemType.RSFORM}
|
itemType={LibraryItemType.RSFORM}
|
||||||
rows={14}
|
rows={14}
|
||||||
value={selected}
|
value={selected}
|
||||||
onSelectValue={setSelected}
|
onChange={setSelected}
|
||||||
/>
|
/>
|
||||||
<div className='flex items-center gap-6 '>
|
<div className='flex items-center gap-6 '>
|
||||||
<span className='select-none'>Выбрана</span>
|
<span className='select-none'>Выбрана</span>
|
||||||
|
|
|
@ -22,8 +22,8 @@ function TabSubstitutions({ sourceID, receiver, selected, substitutions, setSubs
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<PickSubstitutions
|
<PickSubstitutions
|
||||||
substitutions={substitutions}
|
value={substitutions}
|
||||||
setSubstitutions={setSubstitutions}
|
onChange={setSubstitutions}
|
||||||
rows={10}
|
rows={10}
|
||||||
prefixID={prefixes.cst_inline_synth_substitutes}
|
prefixID={prefixes.cst_inline_synth_substitutes}
|
||||||
schemas={schemas}
|
schemas={schemas}
|
||||||
|
|
|
@ -103,7 +103,7 @@ function DlgRelocateConstituents() {
|
||||||
placeholder='Выберите исходную схему'
|
placeholder='Выберите исходную схему'
|
||||||
items={sourceSchemas}
|
items={sourceSchemas}
|
||||||
value={source}
|
value={source}
|
||||||
onSelectValue={handleSelectSource}
|
onChange={handleSelectSource}
|
||||||
/>
|
/>
|
||||||
<MiniButton
|
<MiniButton
|
||||||
title='Направление перемещения'
|
title='Направление перемещения'
|
||||||
|
@ -116,7 +116,7 @@ function DlgRelocateConstituents() {
|
||||||
placeholder='Выберите целевую схему'
|
placeholder='Выберите целевую схему'
|
||||||
items={destinationSchemas}
|
items={destinationSchemas}
|
||||||
value={destination}
|
value={destination}
|
||||||
onSelectValue={handleSelectDestination}
|
onChange={handleSelectDestination}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
{sourceData.isLoading ? <Loader /> : null}
|
{sourceData.isLoading ? <Loader /> : null}
|
||||||
|
@ -127,8 +127,8 @@ function DlgRelocateConstituents() {
|
||||||
data={filteredConstituents}
|
data={filteredConstituents}
|
||||||
rows={12}
|
rows={12}
|
||||||
prefixID={prefixes.dlg_cst_constituents_list}
|
prefixID={prefixes.dlg_cst_constituents_list}
|
||||||
selected={selected}
|
value={selected}
|
||||||
setSelected={setSelected}
|
onChange={setSelected}
|
||||||
/>
|
/>
|
||||||
) : null}
|
) : null}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -40,8 +40,8 @@ function DlgSubstituteCst() {
|
||||||
>
|
>
|
||||||
<PickSubstitutions
|
<PickSubstitutions
|
||||||
allowSelfSubstitution
|
allowSelfSubstitution
|
||||||
substitutions={substitutions}
|
value={substitutions}
|
||||||
setSubstitutions={setSubstitutions}
|
onChange={setSubstitutions}
|
||||||
rows={6}
|
rows={6}
|
||||||
prefixID={prefixes.dlg_cst_substitutes_list}
|
prefixID={prefixes.dlg_cst_substitutes_list}
|
||||||
schemas={[schema]}
|
schemas={[schema]}
|
||||||
|
|
|
@ -53,7 +53,7 @@ function DlgUploadRSForm() {
|
||||||
label='Загружать название и комментарий'
|
label='Загружать название и комментарий'
|
||||||
className='py-2'
|
className='py-2'
|
||||||
value={loadMetadata}
|
value={loadMetadata}
|
||||||
setValue={value => setLoadMetadata(value)}
|
onChange={value => setLoadMetadata(value)}
|
||||||
/>
|
/>
|
||||||
</Modal>
|
</Modal>
|
||||||
);
|
);
|
||||||
|
|
|
@ -127,7 +127,7 @@ function ToolbarSearch({ total, filtered }: ToolbarSearchProps) {
|
||||||
placeholder='Выберите владельца'
|
placeholder='Выберите владельца'
|
||||||
className='min-w-[15rem] text-sm mx-1 mb-1'
|
className='min-w-[15rem] text-sm mx-1 mb-1'
|
||||||
value={filterUser}
|
value={filterUser}
|
||||||
onSelectValue={setFilterUser}
|
onChange={setFilterUser}
|
||||||
/>
|
/>
|
||||||
</Dropdown>
|
</Dropdown>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -57,7 +57,7 @@ function TopicsDropdown({ activeTopic, onChangeTopic }: TopicsDropdownProps) {
|
||||||
<SelectTree
|
<SelectTree
|
||||||
items={Object.values(HelpTopic).map(item => item as HelpTopic)}
|
items={Object.values(HelpTopic).map(item => item as HelpTopic)}
|
||||||
value={activeTopic}
|
value={activeTopic}
|
||||||
onChangeValue={handleSelectTopic}
|
onChange={handleSelectTopic}
|
||||||
prefix={prefixes.topic_list}
|
prefix={prefixes.topic_list}
|
||||||
getParent={item => topicParent.get(item) ?? item}
|
getParent={item => topicParent.get(item) ?? item}
|
||||||
getLabel={labelHelpTopic}
|
getLabel={labelHelpTopic}
|
||||||
|
|
|
@ -17,7 +17,7 @@ function TopicsStatic({ activeTopic, onChangeTopic }: TopicsStaticProps) {
|
||||||
<SelectTree
|
<SelectTree
|
||||||
items={Object.values(HelpTopic).map(item => item as HelpTopic)}
|
items={Object.values(HelpTopic).map(item => item as HelpTopic)}
|
||||||
value={activeTopic}
|
value={activeTopic}
|
||||||
onChangeValue={onChangeTopic}
|
onChange={onChangeTopic}
|
||||||
prefix={prefixes.topic_list}
|
prefix={prefixes.topic_list}
|
||||||
getParent={item => topicParent.get(item) ?? item}
|
getParent={item => topicParent.get(item) ?? item}
|
||||||
getLabel={labelHelpTopic}
|
getLabel={labelHelpTopic}
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
import { useEffect, useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
|
|
||||||
import { ILibraryUpdateDTO } from '@/backend/library/api';
|
import { IUpdateLibraryItemDTO } from '@/backend/library/api';
|
||||||
import { useUpdateItem } from '@/backend/library/useUpdateItem';
|
import { useUpdateItem } from '@/backend/library/useUpdateItem';
|
||||||
import { useMutatingOss } from '@/backend/oss/useMutatingOss';
|
import { useMutatingOss } from '@/backend/oss/useMutatingOss';
|
||||||
import { IconSave } from '@/components/Icons';
|
import { IconSave } from '@/components/Icons';
|
||||||
|
@ -73,7 +73,7 @@ function FormOSS({ id }: FormOSSProps) {
|
||||||
if (!schema) {
|
if (!schema) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const data: ILibraryUpdateDTO = {
|
const data: IUpdateLibraryItemDTO = {
|
||||||
id: schema.id,
|
id: schema.id,
|
||||||
item_type: LibraryItemType.RSFORM,
|
item_type: LibraryItemType.RSFORM,
|
||||||
title: title,
|
title: title,
|
||||||
|
|
|
@ -17,9 +17,9 @@ export function Component() {
|
||||||
const router = useConceptNavigation();
|
const router = useConceptNavigation();
|
||||||
const token = useQueryStrings().get('token') ?? '';
|
const token = useQueryStrings().get('token') ?? '';
|
||||||
|
|
||||||
const { validateToken, resetPassword, isPending, error } = useResetPassword();
|
const { validateToken, resetPassword, isPending, error: serverError } = useResetPassword();
|
||||||
|
|
||||||
const [isValidated, setIsValidated] = useState(false);
|
const [isTokenValidated, setIsTokenValidated] = useState(false);
|
||||||
const [newPassword, setNewPassword] = useState('');
|
const [newPassword, setNewPassword] = useState('');
|
||||||
const [newPasswordRepeat, setNewPasswordRepeat] = useState('');
|
const [newPasswordRepeat, setNewPasswordRepeat] = useState('');
|
||||||
|
|
||||||
|
@ -45,11 +45,11 @@ export function Component() {
|
||||||
}
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!isValidated && !isPending) {
|
if (!isTokenValidated && !isPending) {
|
||||||
validateToken({ token: token });
|
validateToken({ token: token });
|
||||||
setIsValidated(true);
|
setIsTokenValidated(true);
|
||||||
}
|
}
|
||||||
}, [token, validateToken, isValidated, isPending]);
|
}, [token, validateToken, isTokenValidated, isPending]);
|
||||||
|
|
||||||
if (isPending) {
|
if (isPending) {
|
||||||
return <Loader />;
|
return <Loader />;
|
||||||
|
@ -88,13 +88,13 @@ export function Component() {
|
||||||
loading={isPending}
|
loading={isPending}
|
||||||
disabled={!canSubmit}
|
disabled={!canSubmit}
|
||||||
/>
|
/>
|
||||||
{error ? <ProcessError error={error} /> : null}
|
{serverError ? <ServerError error={serverError} /> : null}
|
||||||
</form>
|
</form>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ====== Internals =========
|
// ====== Internals =========
|
||||||
function ProcessError({ error }: { error: ErrorData }): React.ReactElement {
|
function ServerError({ error }: { error: ErrorData }): React.ReactElement {
|
||||||
if (axios.isAxiosError(error) && error.response && error.response.status === 404) {
|
if (axios.isAxiosError(error) && error.response && error.response.status === 404) {
|
||||||
return <div className='mx-auto mt-6 text-sm select-text text-warn-600'>Данная ссылка не действительна</div>;
|
return <div className='mx-auto mt-6 text-sm select-text text-warn-600'>Данная ссылка не действительна</div>;
|
||||||
}
|
}
|
||||||
|
|
|
@ -112,7 +112,7 @@ function EditorLibraryItem({ controller }: EditorLibraryItemProps) {
|
||||||
<SelectUser
|
<SelectUser
|
||||||
className='w-[25rem] sm:w-[26rem] text-sm'
|
className='w-[25rem] sm:w-[26rem] text-sm'
|
||||||
value={controller.schema.owner ?? undefined}
|
value={controller.schema.owner ?? undefined}
|
||||||
onSelectValue={onSelectUser}
|
onChange={onSelectUser}
|
||||||
/>
|
/>
|
||||||
) : null}
|
) : null}
|
||||||
</Overlay>
|
</Overlay>
|
||||||
|
|
|
@ -5,7 +5,7 @@ import { useEffect, useState } from 'react';
|
||||||
|
|
||||||
import { useConceptNavigation } from '@/app/Navigation/NavigationContext';
|
import { useConceptNavigation } from '@/app/Navigation/NavigationContext';
|
||||||
import { urls } from '@/app/urls';
|
import { urls } from '@/app/urls';
|
||||||
import { ILibraryUpdateDTO } from '@/backend/library/api';
|
import { IUpdateLibraryItemDTO } from '@/backend/library/api';
|
||||||
import { useUpdateItem } from '@/backend/library/useUpdateItem';
|
import { useUpdateItem } from '@/backend/library/useUpdateItem';
|
||||||
import { useMutatingRSForm } from '@/backend/rsform/useMutatingRSForm';
|
import { useMutatingRSForm } from '@/backend/rsform/useMutatingRSForm';
|
||||||
import { IconSave } from '@/components/Icons';
|
import { IconSave } from '@/components/Icons';
|
||||||
|
@ -83,7 +83,7 @@ function FormRSForm({ id }: FormRSFormProps) {
|
||||||
if (!schema) {
|
if (!schema) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const data: ILibraryUpdateDTO = {
|
const data: IUpdateLibraryItemDTO = {
|
||||||
id: schema.id,
|
id: schema.id,
|
||||||
item_type: LibraryItemType.RSFORM,
|
item_type: LibraryItemType.RSFORM,
|
||||||
title: title,
|
title: title,
|
||||||
|
@ -131,7 +131,7 @@ function FormRSForm({ id }: FormRSFormProps) {
|
||||||
className='select-none'
|
className='select-none'
|
||||||
value={schema.version} //
|
value={schema.version} //
|
||||||
items={schema.versions}
|
items={schema.versions}
|
||||||
onSelectValue={handleSelectVersion}
|
onChange={handleSelectVersion}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -311,8 +311,8 @@ function TGFlow() {
|
||||||
? cstID => !controller.schema.cstByID.get(cstID)?.is_inherited
|
? cstID => !controller.schema.cstByID.get(cstID)?.is_inherited
|
||||||
: undefined
|
: undefined
|
||||||
}
|
}
|
||||||
selected={controller.selected}
|
value={controller.selected}
|
||||||
setSelected={handleSetSelected}
|
onChange={handleSetSelected}
|
||||||
emptySelection={controller.selected.length === 0}
|
emptySelection={controller.selected.length === 0}
|
||||||
/>
|
/>
|
||||||
) : null}
|
) : null}
|
||||||
|
|
|
@ -141,11 +141,11 @@ function FormSignup() {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className='flex gap-1 text-sm'>
|
<div className='flex gap-1 text-sm'>
|
||||||
<Checkbox id='accept_terms' label='Принимаю условия' value={acceptPrivacy} setValue={setAcceptPrivacy} />
|
<Checkbox id='accept_terms' label='Принимаю условия' value={acceptPrivacy} onChange={setAcceptPrivacy} />
|
||||||
<TextURL text='обработки персональных данных...' href={urls.help_topic(HelpTopic.INFO_PRIVACY)} />
|
<TextURL text='обработки персональных данных...' href={urls.help_topic(HelpTopic.INFO_PRIVACY)} />
|
||||||
</div>
|
</div>
|
||||||
<div className='flex gap-1 text-sm'>
|
<div className='flex gap-1 text-sm'>
|
||||||
<Checkbox id='accept_rules' label='Принимаю ' value={acceptRules} setValue={setAcceptRules} />
|
<Checkbox id='accept_rules' label='Принимаю ' value={acceptRules} onChange={setAcceptRules} />
|
||||||
<TextURL text='правила поведения на Портале...' href={urls.help_topic(HelpTopic.INFO_RULES)} />
|
<TextURL text='правила поведения на Портале...' href={urls.help_topic(HelpTopic.INFO_RULES)} />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@ import TextInput from '@/components/ui/TextInput';
|
||||||
import TextURL from '@/components/ui/TextURL';
|
import TextURL from '@/components/ui/TextURL';
|
||||||
|
|
||||||
export function Component() {
|
export function Component() {
|
||||||
const { requestPasswordReset, isPending, error, reset } = useRequestPasswordReset();
|
const { requestPasswordReset, isPending, error: serverError, reset: clearServerError } = useRequestPasswordReset();
|
||||||
|
|
||||||
const [isCompleted, setIsCompleted] = useState(false);
|
const [isCompleted, setIsCompleted] = useState(false);
|
||||||
const [email, setEmail] = useState('');
|
const [email, setEmail] = useState('');
|
||||||
|
@ -24,8 +24,8 @@ export function Component() {
|
||||||
}
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
reset();
|
clearServerError();
|
||||||
}, [email, reset]);
|
}, [email, clearServerError]);
|
||||||
|
|
||||||
if (isCompleted) {
|
if (isCompleted) {
|
||||||
return (
|
return (
|
||||||
|
@ -54,14 +54,14 @@ export function Component() {
|
||||||
loading={isPending}
|
loading={isPending}
|
||||||
disabled={!email}
|
disabled={!email}
|
||||||
/>
|
/>
|
||||||
{error ? <ProcessError error={error} /> : null}
|
{serverError ? <ServerError error={serverError} /> : null}
|
||||||
</form>
|
</form>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ====== Internals =========
|
// ====== Internals =========
|
||||||
function ProcessError({ error }: { error: ErrorData }): React.ReactElement {
|
function ServerError({ error }: { error: ErrorData }): React.ReactElement {
|
||||||
if (axios.isAxiosError(error) && error.response && error.response.status === 400) {
|
if (axios.isAxiosError(error) && error.response && error.response.status === 400) {
|
||||||
return (
|
return (
|
||||||
<div className='mx-auto mt-6 text-sm select-text text-warn-600'>Данный email не используется на Портале.</div>
|
<div className='mx-auto mt-6 text-sm select-text text-warn-600'>Данный email не используется на Портале.</div>
|
||||||
|
|
Loading…
Reference in New Issue
Block a user