mirror of
https://github.com/IRBorisov/ConceptPortal.git
synced 2025-06-25 20:40:36 +03:00
This commit is contained in:
parent
869de34fc5
commit
6deedb3afd
|
@ -5,13 +5,14 @@ import { useDebounce } from 'use-debounce';
|
|||
import { Loader } from '@/components/Loader';
|
||||
import { PARAMETER } from '@/utils/constants';
|
||||
|
||||
// TODO: add animation
|
||||
export function GlobalLoader() {
|
||||
const navigation = useNavigation();
|
||||
|
||||
const isLoading = navigation.state === 'loading';
|
||||
const [loadingDebounced] = useDebounce(isLoading, PARAMETER.navigationPopupDelay);
|
||||
|
||||
if (!loadingDebounced || !isLoading) {
|
||||
if (!loadingDebounced) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
|
@ -31,9 +31,9 @@ export function SelectLibraryItem({
|
|||
label: `${cst.alias}: ${cst.title}`
|
||||
})) ?? [];
|
||||
|
||||
function filter(option: { value: number | undefined; label: string }, inputValue: string) {
|
||||
const item = items?.find(item => item.id === option.value);
|
||||
return !item ? false : matchLibraryItem(item, inputValue);
|
||||
function filter(option: { value: string | undefined; label: string }, query: string) {
|
||||
const item = items?.find(item => item.id === Number(option.value));
|
||||
return !item ? false : matchLibraryItem(item, query);
|
||||
}
|
||||
|
||||
return (
|
||||
|
@ -42,7 +42,6 @@ export function SelectLibraryItem({
|
|||
options={options}
|
||||
value={value ? { value: value.id, label: `${value.alias}: ${value.title}` } : null}
|
||||
onChange={data => onChange(items?.find(cst => cst.id === data?.value))}
|
||||
// @ts-expect-error: TODO: use type definitions from react-select in filter object
|
||||
filterOption={filter}
|
||||
placeholder={placeholder}
|
||||
{...restProps}
|
||||
|
|
|
@ -9,13 +9,13 @@ import { IconMoveDown, IconMoveUp, IconRemove } from '@/components/Icons';
|
|||
import { CProps } from '@/components/props';
|
||||
import { NoData } from '@/components/View';
|
||||
|
||||
import { IOperation, OperationID } from '../models/oss';
|
||||
import { IOperation } from '../models/oss';
|
||||
|
||||
import SelectOperation from './SelectOperation';
|
||||
|
||||
interface PickMultiOperationProps extends CProps.Styling {
|
||||
value: OperationID[];
|
||||
onChange: (newValue: OperationID[]) => void;
|
||||
value: number[];
|
||||
onChange: (newValue: number[]) => void;
|
||||
items: IOperation[];
|
||||
rows?: number;
|
||||
}
|
||||
|
@ -27,7 +27,7 @@ export function PickMultiOperation({ rows, items, value, onChange, className, ..
|
|||
const nonSelectedItems = items.filter(item => !value.includes(item.id));
|
||||
const [lastSelected, setLastSelected] = useState<IOperation | undefined>(undefined);
|
||||
|
||||
function handleDelete(operation: OperationID) {
|
||||
function handleDelete(operation: number) {
|
||||
onChange(value.filter(item => item !== operation));
|
||||
}
|
||||
|
||||
|
@ -39,7 +39,7 @@ export function PickMultiOperation({ rows, items, value, onChange, className, ..
|
|||
}
|
||||
}
|
||||
|
||||
function handleMoveUp(operation: OperationID) {
|
||||
function handleMoveUp(operation: number) {
|
||||
const index = value.indexOf(operation);
|
||||
if (index > 0) {
|
||||
const newSelected = [...value];
|
||||
|
@ -49,7 +49,7 @@ export function PickMultiOperation({ rows, items, value, onChange, className, ..
|
|||
}
|
||||
}
|
||||
|
||||
function handleMoveDown(operation: OperationID) {
|
||||
function handleMoveDown(operation: number) {
|
||||
const index = value.indexOf(operation);
|
||||
if (index < value.length - 1) {
|
||||
const newSelected = [...value];
|
||||
|
|
|
@ -5,7 +5,7 @@ import clsx from 'clsx';
|
|||
import { SelectSingle } from '@/components/Input';
|
||||
import { CProps } from '@/components/props';
|
||||
|
||||
import { IOperation, OperationID } from '../models/oss';
|
||||
import { IOperation } from '../models/oss';
|
||||
import { matchOperation } from '../models/ossAPI';
|
||||
|
||||
interface SelectOperationProps extends CProps.Styling {
|
||||
|
@ -31,9 +31,9 @@ function SelectOperation({
|
|||
label: `${cst.alias}: ${cst.title}`
|
||||
})) ?? [];
|
||||
|
||||
function filter(option: { value: OperationID | undefined; label: string }, inputValue: string) {
|
||||
const operation = items?.find(item => item.id === option.value);
|
||||
return !operation ? false : matchOperation(operation, inputValue);
|
||||
function filter(option: { value: string | undefined; label: string }, query: string) {
|
||||
const operation = items?.find(item => item.id === Number(option.value));
|
||||
return !operation ? false : matchOperation(operation, query);
|
||||
}
|
||||
|
||||
return (
|
||||
|
@ -42,7 +42,6 @@ function SelectOperation({
|
|||
options={options}
|
||||
value={value ? { value: value.id, label: `${value.alias}: ${value.title}` } : null}
|
||||
onChange={data => onChange(items?.find(cst => cst.id === data?.value))}
|
||||
// @ts-expect-error: TODO: use type definitions from react-select in filter object
|
||||
filterOption={filter}
|
||||
placeholder={placeholder}
|
||||
{...restProps}
|
||||
|
|
|
@ -14,7 +14,7 @@ import { useDialogsStore } from '@/stores/dialogs';
|
|||
import { IOperationCreateDTO, IOperationPosition, schemaOperationCreate } from '../../backend/types';
|
||||
import { useOperationCreate } from '../../backend/useOperationCreate';
|
||||
import { describeOperationType, labelOperationType } from '../../labels';
|
||||
import { IOperationSchema, OperationID, OperationType } from '../../models/oss';
|
||||
import { IOperationSchema, OperationType } from '../../models/oss';
|
||||
import { calculateInsertPosition } from '../../models/ossAPI';
|
||||
|
||||
import TabInputOperation from './TabInputOperation';
|
||||
|
@ -23,10 +23,10 @@ import TabSynthesisOperation from './TabSynthesisOperation';
|
|||
export interface DlgCreateOperationProps {
|
||||
oss: IOperationSchema;
|
||||
positions: IOperationPosition[];
|
||||
initialInputs: OperationID[];
|
||||
initialInputs: number[];
|
||||
defaultX: number;
|
||||
defaultY: number;
|
||||
onCreate?: (newID: OperationID) => void;
|
||||
onCreate?: (newID: number) => void;
|
||||
}
|
||||
|
||||
export enum TabID {
|
||||
|
|
|
@ -6,11 +6,6 @@ import { ICstSubstitute } from '@/features/rsform';
|
|||
|
||||
import { Graph } from '@/models/Graph';
|
||||
|
||||
/**
|
||||
* Represents {@link IOperation} identifier type.
|
||||
*/
|
||||
export type OperationID = number;
|
||||
|
||||
/**
|
||||
* Represents {@link IOperation} type.
|
||||
*/
|
||||
|
@ -23,7 +18,7 @@ export enum OperationType {
|
|||
* Represents Operation.
|
||||
*/
|
||||
export interface IOperation {
|
||||
id: OperationID;
|
||||
id: number;
|
||||
operation_type: OperationType;
|
||||
oss: number;
|
||||
|
||||
|
@ -39,22 +34,22 @@ export interface IOperation {
|
|||
is_owned: boolean;
|
||||
is_consolidation: boolean; // aka 'diamond synthesis'
|
||||
substitutions: ICstSubstituteEx[];
|
||||
arguments: OperationID[];
|
||||
arguments: number[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents {@link IOperation} Argument.
|
||||
*/
|
||||
export interface IArgument {
|
||||
operation: OperationID;
|
||||
argument: OperationID;
|
||||
operation: number;
|
||||
argument: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents {@link ICstSubstitute} extended data.
|
||||
*/
|
||||
export interface ICstSubstituteEx extends ICstSubstitute {
|
||||
operation: OperationID;
|
||||
operation: number;
|
||||
original_alias: string;
|
||||
original_term: string;
|
||||
substitution_alias: string;
|
||||
|
@ -83,7 +78,7 @@ export interface IOperationSchema extends ILibraryItemData {
|
|||
graph: Graph;
|
||||
schemas: number[];
|
||||
stats: IOperationSchemaStats;
|
||||
operationByID: Map<OperationID, IOperation>;
|
||||
operationByID: Map<number, IOperation>;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -21,7 +21,7 @@ import { Graph } from '../../../models/Graph';
|
|||
import { IOperationPosition } from '../backend/types';
|
||||
import { describeSubstitutionError } from '../labels';
|
||||
|
||||
import { IOperation, IOperationSchema, OperationID, OperationType, SubstitutionErrorType } from './oss';
|
||||
import { IOperation, IOperationSchema, OperationType, SubstitutionErrorType } from './oss';
|
||||
import { Position2D } from './ossLayout';
|
||||
|
||||
/**
|
||||
|
@ -439,8 +439,8 @@ export class SubstitutionValidator {
|
|||
* Filter relocate candidates from gives schema.
|
||||
*/
|
||||
export function getRelocateCandidates(
|
||||
source: OperationID,
|
||||
destination: OperationID,
|
||||
source: number,
|
||||
destination: number,
|
||||
schema: IRSForm,
|
||||
oss: IOperationSchema
|
||||
): IConstituenta[] {
|
||||
|
@ -482,7 +482,7 @@ export function getRelocateCandidates(
|
|||
export function calculateInsertPosition(
|
||||
oss: IOperationSchema,
|
||||
operationType: OperationType,
|
||||
argumentsOps: OperationID[],
|
||||
argumentsOps: number[],
|
||||
positions: IOperationPosition[],
|
||||
defaultPosition: Position2D
|
||||
): Position2D {
|
||||
|
|
|
@ -31,7 +31,6 @@ import { useInputCreate } from '../../../backend/useInputCreate';
|
|||
import { useMutatingOss } from '../../../backend/useMutatingOss';
|
||||
import { useOperationExecute } from '../../../backend/useOperationExecute';
|
||||
import { useUpdatePositions } from '../../../backend/useUpdatePositions';
|
||||
import { OperationID } from '../../../models/oss';
|
||||
import { OssNode } from '../../../models/ossLayout';
|
||||
import { useOSSGraphStore } from '../../../stores/ossGraph';
|
||||
import { useOssEdit } from '../OssEditContext';
|
||||
|
@ -137,7 +136,7 @@ function OssFlow() {
|
|||
});
|
||||
}
|
||||
|
||||
function handleCreateOperation(inputs: OperationID[]) {
|
||||
function handleCreateOperation(inputs: number[]) {
|
||||
const positions = getPositions();
|
||||
const target = flow.project({ x: window.innerWidth / 2, y: window.innerHeight / 2 });
|
||||
controller.promptCreateOperation({
|
||||
|
@ -149,7 +148,7 @@ function OssFlow() {
|
|||
});
|
||||
}
|
||||
|
||||
function handleDeleteOperation(target: OperationID) {
|
||||
function handleDeleteOperation(target: number) {
|
||||
if (!controller.canDelete(target)) {
|
||||
return;
|
||||
}
|
||||
|
@ -163,7 +162,7 @@ function OssFlow() {
|
|||
handleDeleteOperation(controller.selected[0]);
|
||||
}
|
||||
|
||||
function handleInputCreate(target: OperationID) {
|
||||
function handleInputCreate(target: number) {
|
||||
const operation = controller.schema.operationByID.get(target);
|
||||
if (!operation) {
|
||||
return;
|
||||
|
@ -178,15 +177,15 @@ function OssFlow() {
|
|||
}).then(new_schema => router.push(urls.schema(new_schema.id)));
|
||||
}
|
||||
|
||||
function handleEditSchema(target: OperationID) {
|
||||
function handleEditSchema(target: number) {
|
||||
controller.promptEditInput(target, getPositions());
|
||||
}
|
||||
|
||||
function handleEditOperation(target: OperationID) {
|
||||
function handleEditOperation(target: number) {
|
||||
controller.promptEditOperation(target, getPositions());
|
||||
}
|
||||
|
||||
function handleOperationExecute(target: OperationID) {
|
||||
function handleOperationExecute(target: number) {
|
||||
void operationExecute({
|
||||
itemID: controller.schema.id, //
|
||||
data: { target: target, positions: getPositions() }
|
||||
|
@ -200,7 +199,7 @@ function OssFlow() {
|
|||
handleOperationExecute(controller.selected[0]);
|
||||
}
|
||||
|
||||
function handleRelocateConstituents(target: OperationID) {
|
||||
function handleRelocateConstituents(target: number) {
|
||||
controller.promptRelocateConstituents(target, getPositions());
|
||||
}
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ import { promptText } from '@/utils/labels';
|
|||
|
||||
import { IOperationPosition } from '../../backend/types';
|
||||
import { useOssSuspense } from '../../backend/useOSS';
|
||||
import { IOperationSchema, OperationID, OperationType } from '../../models/oss';
|
||||
import { IOperationSchema, OperationType } from '../../models/oss';
|
||||
|
||||
export enum OssTabID {
|
||||
CARD = 0,
|
||||
|
@ -24,14 +24,14 @@ export enum OssTabID {
|
|||
export interface ICreateOperationPrompt {
|
||||
defaultX: number;
|
||||
defaultY: number;
|
||||
inputs: OperationID[];
|
||||
inputs: number[];
|
||||
positions: IOperationPosition[];
|
||||
callback: (newID: OperationID) => void;
|
||||
callback: (newID: number) => void;
|
||||
}
|
||||
|
||||
export interface IOssEditContext extends ILibraryItemEditor {
|
||||
schema: IOperationSchema;
|
||||
selected: OperationID[];
|
||||
selected: number[];
|
||||
|
||||
isOwned: boolean;
|
||||
isMutable: boolean;
|
||||
|
@ -41,17 +41,17 @@ export interface IOssEditContext extends ILibraryItemEditor {
|
|||
setShowTooltip: (newValue: boolean) => void;
|
||||
|
||||
navigateTab: (tab: OssTabID) => void;
|
||||
navigateOperationSchema: (target: OperationID) => void;
|
||||
navigateOperationSchema: (target: number) => void;
|
||||
|
||||
deleteSchema: () => void;
|
||||
setSelected: React.Dispatch<React.SetStateAction<OperationID[]>>;
|
||||
setSelected: React.Dispatch<React.SetStateAction<number[]>>;
|
||||
|
||||
canDelete: (target: OperationID) => boolean;
|
||||
canDelete: (target: number) => boolean;
|
||||
promptCreateOperation: (props: ICreateOperationPrompt) => void;
|
||||
promptDeleteOperation: (target: OperationID, positions: IOperationPosition[]) => void;
|
||||
promptEditInput: (target: OperationID, positions: IOperationPosition[]) => void;
|
||||
promptEditOperation: (target: OperationID, positions: IOperationPosition[]) => void;
|
||||
promptRelocateConstituents: (target: OperationID | undefined, positions: IOperationPosition[]) => void;
|
||||
promptDeleteOperation: (target: number, positions: IOperationPosition[]) => void;
|
||||
promptEditInput: (target: number, positions: IOperationPosition[]) => void;
|
||||
promptEditOperation: (target: number, positions: IOperationPosition[]) => void;
|
||||
promptRelocateConstituents: (target: number | undefined, positions: IOperationPosition[]) => void;
|
||||
}
|
||||
|
||||
const OssEditContext = createContext<IOssEditContext | null>(null);
|
||||
|
@ -83,7 +83,7 @@ export const OssEditState = ({ itemID, children }: React.PropsWithChildren<OssEd
|
|||
const isMutable = role > UserRole.READER && !schema.read_only;
|
||||
|
||||
const [showTooltip, setShowTooltip] = useState(true);
|
||||
const [selected, setSelected] = useState<OperationID[]>([]);
|
||||
const [selected, setSelected] = useState<number[]>([]);
|
||||
|
||||
const showEditInput = useDialogsStore(state => state.showChangeInputSchema);
|
||||
const showEditOperation = useDialogsStore(state => state.showEditOperation);
|
||||
|
@ -112,7 +112,7 @@ export const OssEditState = ({ itemID, children }: React.PropsWithChildren<OssEd
|
|||
router.push(url);
|
||||
}
|
||||
|
||||
function navigateOperationSchema(target: OperationID) {
|
||||
function navigateOperationSchema(target: number) {
|
||||
const node = schema.operationByID.get(target);
|
||||
if (!node?.result) {
|
||||
return;
|
||||
|
@ -143,7 +143,7 @@ export const OssEditState = ({ itemID, children }: React.PropsWithChildren<OssEd
|
|||
});
|
||||
}
|
||||
|
||||
function canDelete(target: OperationID) {
|
||||
function canDelete(target: number) {
|
||||
const operation = schema.operationByID.get(target);
|
||||
if (!operation) {
|
||||
return false;
|
||||
|
@ -154,7 +154,7 @@ export const OssEditState = ({ itemID, children }: React.PropsWithChildren<OssEd
|
|||
return schema.graph.expandOutputs([target]).length === 0;
|
||||
}
|
||||
|
||||
function promptEditOperation(target: OperationID, positions: IOperationPosition[]) {
|
||||
function promptEditOperation(target: number, positions: IOperationPosition[]) {
|
||||
const operation = schema.operationByID.get(target);
|
||||
if (!operation) {
|
||||
return;
|
||||
|
@ -166,7 +166,7 @@ export const OssEditState = ({ itemID, children }: React.PropsWithChildren<OssEd
|
|||
});
|
||||
}
|
||||
|
||||
function promptDeleteOperation(target: OperationID, positions: IOperationPosition[]) {
|
||||
function promptDeleteOperation(target: number, positions: IOperationPosition[]) {
|
||||
const operation = schema.operationByID.get(target);
|
||||
if (!operation) {
|
||||
return;
|
||||
|
@ -178,7 +178,7 @@ export const OssEditState = ({ itemID, children }: React.PropsWithChildren<OssEd
|
|||
});
|
||||
}
|
||||
|
||||
function promptEditInput(target: OperationID, positions: IOperationPosition[]) {
|
||||
function promptEditInput(target: number, positions: IOperationPosition[]) {
|
||||
const operation = schema.operationByID.get(target);
|
||||
if (!operation) {
|
||||
return;
|
||||
|
@ -190,7 +190,7 @@ export const OssEditState = ({ itemID, children }: React.PropsWithChildren<OssEd
|
|||
});
|
||||
}
|
||||
|
||||
function promptRelocateConstituents(target: OperationID | undefined, positions: IOperationPosition[]) {
|
||||
function promptRelocateConstituents(target: number | undefined, positions: IOperationPosition[]) {
|
||||
const operation = target ? schema.operationByID.get(target) : undefined;
|
||||
showRelocateConstituents({
|
||||
oss: schema,
|
||||
|
|
|
@ -33,9 +33,9 @@ function SelectConstituenta({
|
|||
label: `${cst.alias}${cst.is_inherited ? '*' : ''}: ${describeConstituenta(cst)}`
|
||||
})) ?? [];
|
||||
|
||||
function filter(option: { value: number | undefined; label: string }, inputValue: string) {
|
||||
const cst = items?.find(item => item.id === option.value);
|
||||
return !cst ? false : matchConstituenta(cst, inputValue, CstMatchMode.ALL);
|
||||
function filter(option: { value: string | undefined; label: string }, query: string) {
|
||||
const cst = items?.find(item => item.id === Number(option.value));
|
||||
return !cst ? false : matchConstituenta(cst, query, CstMatchMode.ALL);
|
||||
}
|
||||
|
||||
return (
|
||||
|
@ -44,7 +44,6 @@ function SelectConstituenta({
|
|||
options={options}
|
||||
value={value ? { value: value.id, label: `${value.alias}: ${describeConstituentaTerm(value)}` } : null}
|
||||
onChange={data => onChange(items?.find(cst => cst.id === data?.value))}
|
||||
// @ts-expect-error: TODO: use type definitions from react-select in filter object
|
||||
filterOption={filter}
|
||||
placeholder={placeholder}
|
||||
{...restProps}
|
||||
|
|
|
@ -212,6 +212,13 @@ export function isFunctional(type: CstType): boolean {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluate if {@link IConstituenta} can be used produce structure.
|
||||
*/
|
||||
export function canProduceStructure(cst: IConstituenta): boolean {
|
||||
return !!cst.parse.typification && cst.cst_type !== CstType.BASE && cst.cst_type !== CstType.CONSTANT;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate new alias against {@link CstType} and {@link IRSForm}.
|
||||
*/
|
||||
|
|
|
@ -46,7 +46,7 @@ import { useMutatingRSForm } from '../../backend/useMutatingRSForm';
|
|||
import { useProduceStructure } from '../../backend/useProduceStructure';
|
||||
import { useResetAliases } from '../../backend/useResetAliases';
|
||||
import { useRestoreOrder } from '../../backend/useRestoreOrder';
|
||||
import { CstType } from '../../models/rsform';
|
||||
import { canProduceStructure } from '../../models/rsformAPI';
|
||||
|
||||
import { useRSEdit } from './RSEditContext';
|
||||
|
||||
|
@ -75,12 +75,7 @@ function MenuRSTabs() {
|
|||
const editMenu = useDropdown();
|
||||
const accessMenu = useDropdown();
|
||||
|
||||
// TODO: move into separate function
|
||||
const canProduceStructure =
|
||||
!!controller.activeCst &&
|
||||
!!controller.activeCst.parse.typification &&
|
||||
controller.activeCst.cst_type !== CstType.BASE &&
|
||||
controller.activeCst.cst_type !== CstType.CONSTANT;
|
||||
const structureEnabled = !!controller.activeCst && canProduceStructure(controller.activeCst);
|
||||
|
||||
function calculateCloneLocation() {
|
||||
const location = controller.schema.location;
|
||||
|
@ -344,7 +339,7 @@ function MenuRSTabs() {
|
|||
text='Порождение структуры'
|
||||
titleHtml='Раскрыть структуру типизации <br/>выделенной конституенты'
|
||||
icon={<IconGenerateStructure size='1rem' className='icon-primary' />}
|
||||
disabled={!controller.isContentEditable || !canProduceStructure || isProcessing}
|
||||
disabled={!controller.isContentEditable || !structureEnabled || isProcessing}
|
||||
onClick={handleProduceStructure}
|
||||
/>
|
||||
<DropdownButton
|
||||
|
|
|
@ -3,10 +3,9 @@ import clsx from 'clsx';
|
|||
import { CProps } from '@/components/props';
|
||||
|
||||
import { useLabelUser } from '../backend/useLabelUser';
|
||||
import { UserID } from '../models/user';
|
||||
|
||||
interface InfoUsersProps extends CProps.Styling {
|
||||
items: UserID[];
|
||||
items: number[];
|
||||
prefix: string;
|
||||
header?: string;
|
||||
}
|
||||
|
|
|
@ -7,13 +7,12 @@ import { CProps } from '@/components/props';
|
|||
|
||||
import { useLabelUser } from '../backend/useLabelUser';
|
||||
import { useUsers } from '../backend/useUsers';
|
||||
import { UserID } from '../models/user';
|
||||
import { matchUser } from '../models/userAPI';
|
||||
|
||||
interface SelectUserProps extends CProps.Styling {
|
||||
value?: UserID;
|
||||
onChange: (newValue: UserID) => void;
|
||||
filter?: (userID: UserID) => boolean;
|
||||
value?: number;
|
||||
onChange: (newValue: number) => void;
|
||||
filter?: (userID: number) => boolean;
|
||||
|
||||
placeholder?: string;
|
||||
noBorder?: boolean;
|
||||
|
@ -36,9 +35,9 @@ export function SelectUser({
|
|||
label: getUserLabel(user.id)
|
||||
}));
|
||||
|
||||
function filterLabel(option: { value: UserID | undefined; label: string }, inputValue: string) {
|
||||
const user = items.find(item => item.id === option.value);
|
||||
return !user ? false : matchUser(user, inputValue);
|
||||
function filterLabel(option: { value: string | undefined; label: string }, query: string) {
|
||||
const user = items.find(item => item.id === Number(option.value));
|
||||
return !user ? false : matchUser(user, query);
|
||||
}
|
||||
|
||||
return (
|
||||
|
@ -49,7 +48,6 @@ export function SelectUser({
|
|||
onChange={data => {
|
||||
if (data?.value !== undefined) onChange(data.value);
|
||||
}}
|
||||
// @ts-expect-error: TODO: use type definitions from react-select in filter object
|
||||
filterOption={filterLabel}
|
||||
placeholder={placeholder}
|
||||
{...restProps}
|
||||
|
|
|
@ -2,17 +2,12 @@
|
|||
* Module: Models for Users.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Represents {@link User} identifier type.
|
||||
*/
|
||||
export type UserID = number;
|
||||
|
||||
/**
|
||||
* Represents user detailed information.
|
||||
* Some information should only be accessible to authorized users
|
||||
*/
|
||||
export interface IUser {
|
||||
id: UserID;
|
||||
id: number;
|
||||
username: string;
|
||||
is_staff: boolean;
|
||||
email: string;
|
||||
|
|
|
@ -12,7 +12,7 @@ export const PARAMETER = {
|
|||
minimalTimeout: 10, // milliseconds delay for fast updates
|
||||
zoomDuration: 500, // milliseconds animation duration
|
||||
navigationDuration: 300, // milliseconds navigation duration
|
||||
navigationPopupDelay: 200, // milliseconds delay for navigation popup
|
||||
navigationPopupDelay: 300, // milliseconds delay for navigation popup
|
||||
|
||||
ossImageWidth: 1280, // pixels - size of OSS image
|
||||
ossImageHeight: 960, // pixels - size of OSS image
|
||||
|
|
|
@ -6,8 +6,8 @@ test('should load the homepage and display login button', async ({ page }) => {
|
|||
await authAnonymous(page);
|
||||
|
||||
await page.goto('/');
|
||||
await page.waitForSelector('.h-full > .mr-1');
|
||||
await expect(page).toHaveTitle('Концепт Портал');
|
||||
await expect(page.getByRole('heading', { name: 'Портал' })).toBeVisible();
|
||||
|
||||
await page.click('.h-full > .mr-1');
|
||||
await expect(page.getByText('Логин или email')).toBeVisible();
|
||||
|
|
Loading…
Reference in New Issue
Block a user