Naming refactoring and minor UI fixes

This commit is contained in:
IRBorisov 2024-03-17 19:24:12 +03:00
parent 8e7491b2e2
commit 38cd91765a
22 changed files with 106 additions and 81 deletions

View File

@ -10,7 +10,7 @@ function Logo() {
return ( return (
<img <img
alt='Логотип КонцептПортал' alt='Логотип КонцептПортал'
className={clsx('max-h-[1.6rem] min-w-fit', 'text-start', { className={clsx('max-h-[1.6rem] min-w-fit', {
'min-w-[11.5rem]': size.isSmall 'min-w-[11.5rem]': size.isSmall
})} })}
src={size.isSmall ? '/logo_sign.svg' : !darkMode ? '/logo_full.svg' : '/logo_full_dark.svg'} src={size.isSmall ? '/logo_sign.svg' : !darkMode ? '/logo_full.svg' : '/logo_full_dark.svg'}

View File

@ -3,7 +3,7 @@
import { useCallback, useMemo } from 'react'; import { useCallback, useMemo } from 'react';
import { CstMatchMode } from '@/models/miscellaneous'; import { CstMatchMode } from '@/models/miscellaneous';
import { EntityID, IConstituenta } from '@/models/rsform'; import { ConstituentaID, IConstituenta } from '@/models/rsform';
import { matchConstituenta } from '@/models/rsformAPI'; import { matchConstituenta } from '@/models/rsformAPI';
import { describeConstituenta, describeConstituentaTerm } from '@/utils/labels'; import { describeConstituenta, describeConstituentaTerm } from '@/utils/labels';
@ -26,7 +26,7 @@ function ConstituentaSelector({ items, value, onSelectValue }: ConstituentaSelec
}, [items]); }, [items]);
const filter = useCallback( const filter = useCallback(
(option: { value: EntityID | undefined; label: string }, inputValue: string) => { (option: { value: ConstituentaID | undefined; label: string }, inputValue: string) => {
const cst = items?.find(item => item.id === option.value); const cst = items?.find(item => item.id === option.value);
return !cst ? false : matchConstituenta(cst, inputValue, CstMatchMode.ALL); return !cst ? false : matchConstituenta(cst, inputValue, CstMatchMode.ALL);
}, },

View File

@ -51,7 +51,6 @@ function Checkbox({
className={clsx( className={clsx(
'flex items-center gap-2', // prettier: split lines 'flex items-center gap-2', // prettier: split lines
'outline-none', 'outline-none',
'text-start',
cursor, cursor,
className className
)} )}
@ -79,7 +78,7 @@ function Checkbox({
</div> </div>
) : null} ) : null}
</div> </div>
<label className={clsx('text-sm whitespace-nowrap', cursor)} htmlFor={id}> <label className={clsx('text-start text-sm whitespace-nowrap', cursor)} htmlFor={id}>
{label} {label}
</label> </label>
</button> </button>

View File

@ -52,7 +52,7 @@ function CheckboxTristate({
type='button' type='button'
id={id} id={id}
className={clsx( className={clsx(
'flex items-center gap-2 text-start', // prettier: split lines 'flex items-center gap-2', // prettier: split lines
'outline-none', 'outline-none',
cursor, cursor,
className className
@ -86,7 +86,7 @@ function CheckboxTristate({
</div> </div>
) : null} ) : null}
</div> </div>
<label className={clsx('text-sm whitespace-nowrap', cursor)} htmlFor={id}> <label className={clsx('text-start text-sm whitespace-nowrap', cursor)} htmlFor={id}>
{label} {label}
</label> </label>
</button> </button>

View File

@ -8,9 +8,7 @@ interface LabeledValueProps {
function LabeledValue({ id, label, text, title }: LabeledValueProps) { function LabeledValue({ id, label, text, title }: LabeledValueProps) {
return ( return (
<div className='flex justify-between gap-3'> <div className='flex justify-between gap-3'>
<label title={title} htmlFor={id}> <label title={title}>{label}</label>
{label}
</label>
<span id={id}>{text}</span> <span id={id}>{text}</span>
</div> </div>
); );

View File

@ -7,7 +7,7 @@ import useRSFormDetails from '@/hooks/useRSFormDetails';
import { ILibraryItem, IVersionData } from '@/models/library'; import { ILibraryItem, IVersionData } from '@/models/library';
import { ILibraryUpdateData } from '@/models/library'; import { ILibraryUpdateData } from '@/models/library';
import { import {
EntityID, ConstituentaID,
IConstituentaList, IConstituentaList,
IConstituentaMeta, IConstituentaMeta,
ICstCreateData, ICstCreateData,
@ -64,7 +64,7 @@ interface IRSFormContext {
upload: (data: IRSFormUploadData, callback: () => void) => void; upload: (data: IRSFormUploadData, callback: () => void) => void;
resetAliases: (callback: () => void) => void; resetAliases: (callback: () => void) => void;
produceStructure: (data: ICstID, callback?: DataCallback<EntityID[]>) => void; produceStructure: (data: ICstID, callback?: DataCallback<ConstituentaID[]>) => void;
cstCreate: (data: ICstCreateData, callback?: DataCallback<IConstituentaMeta>) => void; cstCreate: (data: ICstCreateData, callback?: DataCallback<IConstituentaMeta>) => void;
cstRename: (data: ICstRenameData, callback?: DataCallback<IConstituentaMeta>) => void; cstRename: (data: ICstRenameData, callback?: DataCallback<IConstituentaMeta>) => void;
@ -265,7 +265,7 @@ export const RSFormState = ({ schemaID, versionID, children }: RSFormStateProps)
); );
const produceStructure = useCallback( const produceStructure = useCallback(
(data: ICstID, callback?: DataCallback<EntityID[]>) => { (data: ICstID, callback?: DataCallback<ConstituentaID[]>) => {
setError(undefined); setError(undefined);
patchProduceStructure(schemaID, { patchProduceStructure(schemaID, {
data: data, data: data,

View File

@ -2,7 +2,7 @@
import { createColumnHelper } from '@tanstack/react-table'; import { createColumnHelper } from '@tanstack/react-table';
import clsx from 'clsx'; import clsx from 'clsx';
import { Dispatch, useCallback, useEffect, useMemo, useState } from 'react'; import { useCallback, useEffect, useMemo, useState } from 'react';
import { BiCheck, BiRefresh, BiX } from 'react-icons/bi'; import { BiCheck, BiRefresh, BiX } from 'react-icons/bi';
import ConstituentaPicker from '@/components/ConstituentaPicker'; import ConstituentaPicker from '@/components/ConstituentaPicker';
@ -17,7 +17,7 @@ import { prefixes } from '@/utils/constants';
interface ArgumentsTabProps { interface ArgumentsTabProps {
state: IArgumentsState; state: IArgumentsState;
schema: IRSForm; schema: IRSForm;
partialUpdate: Dispatch<Partial<IArgumentsState>>; partialUpdate: React.Dispatch<Partial<IArgumentsState>>;
} }
export interface IArgumentsState { export interface IArgumentsState {

View File

@ -1,7 +1,5 @@
'use client'; 'use client';
import { Dispatch } from 'react';
import RSInput from '@/components/RSInput'; import RSInput from '@/components/RSInput';
import SelectSingle from '@/components/ui/SelectSingle'; import SelectSingle from '@/components/ui/SelectSingle';
import TextArea from '@/components/ui/TextArea'; import TextArea from '@/components/ui/TextArea';
@ -12,7 +10,7 @@ import { SelectorCstType } from '@/utils/selectors';
interface ConstituentaTabProps { interface ConstituentaTabProps {
state: ICstCreateData; state: ICstCreateData;
partialUpdate: Dispatch<Partial<ICstCreateData>>; partialUpdate: React.Dispatch<Partial<ICstCreateData>>;
} }
function ConstituentaTab({ state, partialUpdate }: ConstituentaTabProps) { function ConstituentaTab({ state, partialUpdate }: ConstituentaTabProps) {

View File

@ -1,7 +1,7 @@
'use client'; 'use client';
import clsx from 'clsx'; import clsx from 'clsx';
import { useLayoutEffect, useState } from 'react'; import { useLayoutEffect, useMemo, useState } from 'react';
import { TabList, TabPanel, Tabs } from 'react-tabs'; import { TabList, TabPanel, Tabs } from 'react-tabs';
import HelpButton from '@/components/Help/HelpButton'; import HelpButton from '@/components/Help/HelpButton';
@ -32,7 +32,8 @@ export enum TabID {
} }
function DlgConstituentaTemplate({ hideWindow, schema, onCreate, insertAfter }: DlgConstituentaTemplateProps) { function DlgConstituentaTemplate({ hideWindow, schema, onCreate, insertAfter }: DlgConstituentaTemplateProps) {
const [validated, setValidated] = useState(false); const [activeTab, setActiveTab] = useState(TabID.TEMPLATE);
const [template, updateTemplate] = usePartialUpdate<ITemplateState>({}); const [template, updateTemplate] = usePartialUpdate<ITemplateState>({});
const [substitutes, updateSubstitutes] = usePartialUpdate<IArgumentsState>({ const [substitutes, updateSubstitutes] = usePartialUpdate<IArgumentsState>({
definition: '', definition: '',
@ -49,7 +50,10 @@ function DlgConstituentaTemplate({ hideWindow, schema, onCreate, insertAfter }:
term_forms: [] term_forms: []
}); });
const [activeTab, setActiveTab] = useState(TabID.TEMPLATE); const validated = useMemo(
() => validateNewAlias(constituenta.alias, constituenta.cst_type, schema),
[constituenta.alias, constituenta.cst_type, schema]
);
const handleSubmit = () => onCreate(constituenta); const handleSubmit = () => onCreate(constituenta);
@ -57,10 +61,6 @@ function DlgConstituentaTemplate({ hideWindow, schema, onCreate, insertAfter }:
updateConstituenta({ alias: generateAlias(constituenta.cst_type, schema) }); updateConstituenta({ alias: generateAlias(constituenta.cst_type, schema) });
}, [constituenta.cst_type, updateConstituenta, schema]); }, [constituenta.cst_type, updateConstituenta, schema]);
useLayoutEffect(() => {
setValidated(validateNewAlias(constituenta.alias, constituenta.cst_type, schema));
}, [constituenta.alias, constituenta.cst_type, schema]);
useLayoutEffect(() => { useLayoutEffect(() => {
if (!template.prototype) { if (!template.prototype) {
updateConstituenta({ updateConstituenta({

View File

@ -96,6 +96,11 @@ export interface IVersionInfo {
time_create: string; time_create: string;
} }
/**
* Represents {@link LibraryItem} identifier type.
*/
export type LibraryItemID = number;
/** /**
* Represents user data, intended to create or update version metadata in persistent storage. * Represents user data, intended to create or update version metadata in persistent storage.
*/ */
@ -105,7 +110,7 @@ export interface IVersionData extends Omit<IVersionInfo, 'id' | 'time_create'> {
* Represents library item common data typical for all item types. * Represents library item common data typical for all item types.
*/ */
export interface ILibraryItem { export interface ILibraryItem {
id: number; id: LibraryItemID;
item_type: LibraryItemType; item_type: LibraryItemType;
title: string; title: string;
alias: string; alias: string;

View File

@ -4,7 +4,7 @@
import { Graph } from '@/models/Graph'; import { Graph } from '@/models/Graph';
import { ILibraryItemEx, ILibraryUpdateData } from './library'; import { ILibraryItemEx, ILibraryUpdateData, LibraryItemID } from './library';
import { IArgumentInfo, ParsingStatus, ValueClass } from './rslang'; import { IArgumentInfo, ParsingStatus, ValueClass } from './rslang';
/** /**
@ -25,9 +25,14 @@ export enum CstType {
export const CATEGORY_CST_TYPE = CstType.THEOREM; export const CATEGORY_CST_TYPE = CstType.THEOREM;
/** /**
* Represents Entity identifier type. * Represents position in linear order.
*/ */
export type EntityID = number; export type Position = number;
/**
* Represents {@link Constituenta} identifier type.
*/
export type ConstituentaID = number;
/** /**
* Represents Constituenta classification in terms of system of concepts. * Represents Constituenta classification in terms of system of concepts.
@ -63,9 +68,9 @@ export interface TermForm {
* Represents Constituenta basic persistent data. * Represents Constituenta basic persistent data.
*/ */
export interface IConstituentaMeta { export interface IConstituentaMeta {
id: EntityID; id: ConstituentaID;
schema: number; schema: LibraryItemID;
order: number; order: Position;
alias: string; alias: string;
convention: string; convention: string;
cst_type: CstType; cst_type: CstType;
@ -102,7 +107,7 @@ export interface IConstituenta extends IConstituentaMeta {
* Represents Constituenta list. * Represents Constituenta list.
*/ */
export interface IConstituentaList { export interface IConstituentaList {
items: EntityID[]; items: ConstituentaID[];
} }
/** /**
@ -113,14 +118,14 @@ export interface ICstCreateData
IConstituentaMeta, IConstituentaMeta,
'alias' | 'cst_type' | 'definition_raw' | 'term_raw' | 'convention' | 'definition_formal' | 'term_forms' 'alias' | 'cst_type' | 'definition_raw' | 'term_raw' | 'convention' | 'definition_formal' | 'term_forms'
> { > {
insert_after: number | null; insert_after: ConstituentaID | null;
} }
/** /**
* Represents data, used in ordering constituents in a list. * Represents data, used in ordering constituents in a list.
*/ */
export interface ICstMovetoData extends IConstituentaList { export interface ICstMovetoData extends IConstituentaList {
move_to: number; move_to: Position;
} }
/** /**
@ -144,8 +149,8 @@ export interface ICstRenameData extends Pick<IConstituentaMeta, 'id' | 'alias' |
* Represents data, used in merging {@link IConstituenta}. * Represents data, used in merging {@link IConstituenta}.
*/ */
export interface ICstSubstituteData { export interface ICstSubstituteData {
original: EntityID; original: ConstituentaID;
substitution: EntityID; substitution: ConstituentaID;
transfer_term: boolean; transfer_term: boolean;
} }
@ -161,7 +166,7 @@ export interface ICstCreatedResponse {
* Represents data response when creating producing structure of {@link IConstituenta}. * Represents data response when creating producing structure of {@link IConstituenta}.
*/ */
export interface IProduceStructureResponse { export interface IProduceStructureResponse {
cst_list: EntityID[]; cst_list: ConstituentaID[];
schema: IRSFormData; schema: IRSFormData;
} }
@ -226,3 +231,13 @@ export interface IVersionCreatedResponse {
version: number; version: number;
schema: IRSFormData; schema: IRSFormData;
} }
/**
* Represents input data for inline synthesis.
*/
export interface IRSFormInlineData {
receiver: LibraryItemID;
source: LibraryItemID;
items: ConstituentaID[];
substitutions: ICstSubstituteData[];
}

View File

@ -6,7 +6,16 @@ import { Graph } from '@/models/Graph';
import { TextMatcher } from '@/utils/utils'; import { TextMatcher } from '@/utils/utils';
import { CstMatchMode } from './miscellaneous'; import { CstMatchMode } from './miscellaneous';
import { CATEGORY_CST_TYPE, CstClass, CstType, ExpressionStatus, IConstituenta, IRSForm, IRSFormData } from './rsform'; import {
CATEGORY_CST_TYPE,
ConstituentaID,
CstClass,
CstType,
ExpressionStatus,
IConstituenta,
IRSForm,
IRSFormData
} from './rsform';
import { ParsingStatus, ValueClass } from './rslang'; import { ParsingStatus, ValueClass } from './rslang';
import { extractGlobals } from './rslangAPI'; import { extractGlobals } from './rslangAPI';
@ -185,7 +194,7 @@ export function inferClass(type: CstType, isTemplate: boolean): CstClass {
/** /**
* Creates a mock {@link IConstituenta} object with the provided parameters and default values for other properties. * Creates a mock {@link IConstituenta} object with the provided parameters and default values for other properties.
*/ */
export function createMockConstituenta(id: number, alias: string, comment: string): IConstituenta { export function createMockConstituenta(id: ConstituentaID, alias: string, comment: string): IConstituenta {
return { return {
id: id, id: id,
order: -1, order: -1,

View File

@ -6,7 +6,7 @@ import { useMemo, useState } from 'react';
import useLocalStorage from '@/hooks/useLocalStorage'; import useLocalStorage from '@/hooks/useLocalStorage';
import useWindowSize from '@/hooks/useWindowSize'; import useWindowSize from '@/hooks/useWindowSize';
import { IConstituenta } from '@/models/rsform'; import { ConstituentaID, IConstituenta } from '@/models/rsform';
import { globalIDs } from '@/utils/constants'; import { globalIDs } from '@/utils/constants';
import { useRSEdit } from '../RSEditContext'; import { useRSEdit } from '../RSEditContext';
@ -24,7 +24,7 @@ interface EditorConstituentaProps {
activeCst?: IConstituenta; activeCst?: IConstituenta;
isModified: boolean; isModified: boolean;
setIsModified: React.Dispatch<React.SetStateAction<boolean>>; setIsModified: React.Dispatch<React.SetStateAction<boolean>>;
onOpenEdit: (cstID: number) => void; onOpenEdit: (cstID: ConstituentaID) => void;
} }
function EditorConstituenta({ activeCst, isModified, setIsModified, onOpenEdit }: EditorConstituentaProps) { function EditorConstituenta({ activeCst, isModified, setIsModified, onOpenEdit }: EditorConstituentaProps) {

View File

@ -5,16 +5,16 @@ import { useLayoutEffect, useState } from 'react';
import { type RowSelectionState } from '@/components/DataTable'; import { type RowSelectionState } from '@/components/DataTable';
import SelectedCounter from '@/components/SelectedCounter'; import SelectedCounter from '@/components/SelectedCounter';
import { CstType } from '@/models/rsform'; import { ConstituentaID, CstType } from '@/models/rsform';
import { useRSEdit } from '../RSEditContext'; import { useRSEdit } from '../RSEditContext';
import RSListToolbar from './RSListToolbar'; import RSListToolbar from './RSListToolbar';
import RSTable from './RSTable'; import RSTable from './RSTable';
interface EditorRSListProps { interface EditorRSListProps {
selected: number[]; selected: ConstituentaID[];
setSelected: React.Dispatch<React.SetStateAction<number[]>>; setSelected: React.Dispatch<React.SetStateAction<ConstituentaID[]>>;
onOpenEdit: (cstID: number) => void; onOpenEdit: (cstID: ConstituentaID) => void;
} }
function EditorRSList({ selected, setSelected, onOpenEdit }: EditorRSListProps) { function EditorRSList({ selected, setSelected, onOpenEdit }: EditorRSListProps) {
@ -38,7 +38,7 @@ function EditorRSList({ selected, setSelected, onOpenEdit }: EditorRSListProps)
setSelected([]); setSelected([]);
} else { } else {
const newRowSelection = typeof updater === 'function' ? updater(rowSelection) : updater; const newRowSelection = typeof updater === 'function' ? updater(rowSelection) : updater;
const newSelection: number[] = []; const newSelection: ConstituentaID[] = [];
controller.schema.items.forEach((cst, index) => { controller.schema.items.forEach((cst, index) => {
if (newRowSelection[String(index)] === true) { if (newRowSelection[String(index)] === true) {
newSelection.push(cst.id); newSelection.push(cst.id);

View File

@ -8,7 +8,7 @@ import DataTable, { createColumnHelper, RowSelectionState, VisibilityState } fro
import FlexColumn from '@/components/ui/FlexColumn'; import FlexColumn from '@/components/ui/FlexColumn';
import { useConceptTheme } from '@/context/ThemeContext'; import { useConceptTheme } from '@/context/ThemeContext';
import useWindowSize from '@/hooks/useWindowSize'; import useWindowSize from '@/hooks/useWindowSize';
import { IConstituenta } from '@/models/rsform'; import { ConstituentaID, IConstituenta } from '@/models/rsform';
import { prefixes } from '@/utils/constants'; import { prefixes } from '@/utils/constants';
import { labelCstTypification } from '@/utils/labels'; import { labelCstTypification } from '@/utils/labels';
@ -18,7 +18,7 @@ interface RSTableProps {
selected: RowSelectionState; selected: RowSelectionState;
setSelected: React.Dispatch<React.SetStateAction<RowSelectionState>>; setSelected: React.Dispatch<React.SetStateAction<RowSelectionState>>;
onEdit: (cstID: number) => void; onEdit: (cstID: ConstituentaID) => void;
onCreateNew: () => void; onCreateNew: () => void;
} }

View File

@ -12,7 +12,7 @@ import { useConceptTheme } from '@/context/ThemeContext';
import DlgGraphParams from '@/dialogs/DlgGraphParams'; import DlgGraphParams from '@/dialogs/DlgGraphParams';
import useLocalStorage from '@/hooks/useLocalStorage'; import useLocalStorage from '@/hooks/useLocalStorage';
import { GraphColoringScheme, GraphFilterParams } from '@/models/miscellaneous'; import { GraphColoringScheme, GraphFilterParams } from '@/models/miscellaneous';
import { CstType } from '@/models/rsform'; import { ConstituentaID, CstType } from '@/models/rsform';
import { colorBgGraphNode } from '@/styling/color'; import { colorBgGraphNode } from '@/styling/color';
import { classnames, TIMEOUT_GRAPH_REFRESH } from '@/utils/constants'; import { classnames, TIMEOUT_GRAPH_REFRESH } from '@/utils/constants';
@ -24,9 +24,9 @@ import useGraphFilter from './useGraphFilter';
import ViewHidden from './ViewHidden'; import ViewHidden from './ViewHidden';
interface EditorTermGraphProps { interface EditorTermGraphProps {
selected: number[]; selected: ConstituentaID[];
setSelected: React.Dispatch<React.SetStateAction<number[]>>; setSelected: React.Dispatch<React.SetStateAction<ConstituentaID[]>>;
onOpenEdit: (cstID: number) => void; onOpenEdit: (cstID: ConstituentaID) => void;
} }
function EditorTermGraph({ selected, setSelected, onOpenEdit }: EditorTermGraphProps) { function EditorTermGraph({ selected, setSelected, onOpenEdit }: EditorTermGraphProps) {
@ -51,7 +51,7 @@ function EditorTermGraph({ selected, setSelected, onOpenEdit }: EditorTermGraphP
const [showParamsDialog, setShowParamsDialog] = useState(false); const [showParamsDialog, setShowParamsDialog] = useState(false);
const filtered = useGraphFilter(controller.schema, filterParams); const filtered = useGraphFilter(controller.schema, filterParams);
const [hidden, setHidden] = useState<number[]>([]); const [hidden, setHidden] = useState<ConstituentaID[]>([]);
const nothingSelected = useMemo(() => selected.length === 0, [selected]); const nothingSelected = useMemo(() => selected.length === 0, [selected]);
@ -60,7 +60,7 @@ function EditorTermGraph({ selected, setSelected, onOpenEdit }: EditorTermGraphP
const [coloringScheme, setColoringScheme] = useLocalStorage<GraphColoringScheme>('graph_coloring', 'type'); const [coloringScheme, setColoringScheme] = useLocalStorage<GraphColoringScheme>('graph_coloring', 'type');
const [orbit, setOrbit] = useState(false); const [orbit, setOrbit] = useState(false);
const [hoverID, setHoverID] = useState<number | undefined>(undefined); const [hoverID, setHoverID] = useState<ConstituentaID | undefined>(undefined);
const hoverCst = useMemo(() => { const hoverCst = useMemo(() => {
return controller.schema?.items.find(cst => cst.id === hoverID); return controller.schema?.items.find(cst => cst.id === hoverID);
}, [controller.schema?.items, hoverID]); }, [controller.schema?.items, hoverID]);
@ -71,7 +71,7 @@ function EditorTermGraph({ selected, setSelected, onOpenEdit }: EditorTermGraphP
if (!controller.schema) { if (!controller.schema) {
return; return;
} }
const newDismissed: number[] = []; const newDismissed: ConstituentaID[] = [];
controller.schema.items.forEach(cst => { controller.schema.items.forEach(cst => {
if (!filtered.nodes.has(cst.id)) { if (!filtered.nodes.has(cst.id)) {
newDismissed.push(cst.id); newDismissed.push(cst.id);
@ -116,13 +116,13 @@ function EditorTermGraph({ selected, setSelected, onOpenEdit }: EditorTermGraphP
}, [filtered.nodes]); }, [filtered.nodes]);
const handleGraphSelection = useCallback( const handleGraphSelection = useCallback(
(newID: number) => { (newID: ConstituentaID) => {
setSelected(prev => [...prev, newID]); setSelected(prev => [...prev, newID]);
}, },
[setSelected] [setSelected]
); );
function toggleDismissed(cstID: number) { function toggleDismissed(cstID: ConstituentaID) {
setSelected(prev => { setSelected(prev => {
if (prev.includes(cstID)) { if (prev.includes(cstID)) {
return [...prev.filter(id => id !== cstID)]; return [...prev.filter(id => id !== cstID)];

View File

@ -4,21 +4,22 @@ import { useCallback, useLayoutEffect, useMemo, useRef } from 'react';
import GraphUI, { GraphCanvasRef, GraphEdge, GraphNode, LayoutTypes, useSelection } from '@/components/GraphUI'; import GraphUI, { GraphCanvasRef, GraphEdge, GraphNode, LayoutTypes, useSelection } from '@/components/GraphUI';
import { useConceptTheme } from '@/context/ThemeContext'; import { useConceptTheme } from '@/context/ThemeContext';
import { ConstituentaID } from '@/models/rsform';
import { graphDarkT, graphLightT } from '@/styling/color'; import { graphDarkT, graphLightT } from '@/styling/color';
import { resources } from '@/utils/constants'; import { resources } from '@/utils/constants';
interface TermGraphProps { interface TermGraphProps {
nodes: GraphNode[]; nodes: GraphNode[];
edges: GraphEdge[]; edges: GraphEdge[];
selectedIDs: number[]; selectedIDs: ConstituentaID[];
layout: LayoutTypes; layout: LayoutTypes;
is3D: boolean; is3D: boolean;
orbit: boolean; orbit: boolean;
setHoverID: (newID: number | undefined) => void; setHoverID: (newID: ConstituentaID | undefined) => void;
onEdit: (cstID: number) => void; onEdit: (cstID: ConstituentaID) => void;
onSelect: (newID: number) => void; onSelect: (newID: ConstituentaID) => void;
onDeselectAll: () => void; onDeselectAll: () => void;
toggleResetView: boolean; toggleResetView: boolean;

View File

@ -5,18 +5,18 @@ import { useCallback, useMemo } from 'react';
import ConstituentaTooltip from '@/components/ConstituentaTooltip'; import ConstituentaTooltip from '@/components/ConstituentaTooltip';
import { useConceptTheme } from '@/context/ThemeContext'; import { useConceptTheme } from '@/context/ThemeContext';
import { GraphColoringScheme } from '@/models/miscellaneous'; import { GraphColoringScheme } from '@/models/miscellaneous';
import { IRSForm } from '@/models/rsform'; import { ConstituentaID, IRSForm } from '@/models/rsform';
import { colorBgGraphNode } from '@/styling/color'; import { colorBgGraphNode } from '@/styling/color';
import { prefixes } from '@/utils/constants'; import { prefixes } from '@/utils/constants';
interface ViewHiddenProps { interface ViewHiddenProps {
items: number[]; items: ConstituentaID[];
selected: number[]; selected: ConstituentaID[];
schema?: IRSForm; schema?: IRSForm;
coloringScheme: GraphColoringScheme; coloringScheme: GraphColoringScheme;
toggleSelection: (cstID: number) => void; toggleSelection: (cstID: ConstituentaID) => void;
onEdit: (cstID: number) => void; onEdit: (cstID: ConstituentaID) => void;
} }
function ViewHidden({ items, selected, toggleSelection, schema, coloringScheme, onEdit }: ViewHiddenProps) { function ViewHidden({ items, selected, toggleSelection, schema, coloringScheme, onEdit }: ViewHiddenProps) {
@ -27,7 +27,7 @@ function ViewHidden({ items, selected, toggleSelection, schema, coloringScheme,
}, [noNavigation]); }, [noNavigation]);
const dismissedStyle = useCallback( const dismissedStyle = useCallback(
(cstID: number) => { (cstID: ConstituentaID) => {
return selected.includes(cstID) ? { outlineWidth: '2px', outlineStyle: 'solid' } : {}; return selected.includes(cstID) ? { outlineWidth: '2px', outlineStyle: 'solid' } : {};
}, },
[selected] [selected]

View File

@ -12,7 +12,7 @@ import { useBlockNavigation, useConceptNavigation } from '@/context/NavigationCo
import { useRSForm } from '@/context/RSFormContext'; import { useRSForm } from '@/context/RSFormContext';
import { useConceptTheme } from '@/context/ThemeContext'; import { useConceptTheme } from '@/context/ThemeContext';
import useQueryStrings from '@/hooks/useQueryStrings'; import useQueryStrings from '@/hooks/useQueryStrings';
import { IConstituenta, IConstituentaMeta } from '@/models/rsform'; import { ConstituentaID, IConstituenta, IConstituentaMeta } from '@/models/rsform';
import { prefixes, TIMEOUT_UI_REFRESH } from '@/utils/constants'; import { prefixes, TIMEOUT_UI_REFRESH } from '@/utils/constants';
import { labelVersion } from '@/utils/labels'; import { labelVersion } from '@/utils/labels';
@ -44,7 +44,7 @@ function RSTabs() {
const [isModified, setIsModified] = useState(false); const [isModified, setIsModified] = useState(false);
useBlockNavigation(isModified); useBlockNavigation(isModified);
const [selected, setSelected] = useState<number[]>([]); const [selected, setSelected] = useState<ConstituentaID[]>([]);
const activeCst: IConstituenta | undefined = useMemo(() => { const activeCst: IConstituenta | undefined = useMemo(() => {
if (!schema || selected.length === 0) { if (!schema || selected.length === 0) {
return undefined; return undefined;
@ -80,7 +80,7 @@ function RSTabs() {
}, [activeTab, cstQuery, setSelected, schema, setNoFooter, setIsModified]); }, [activeTab, cstQuery, setSelected, schema, setNoFooter, setIsModified]);
const navigateTab = useCallback( const navigateTab = useCallback(
(tab: RSTabID, activeID?: number) => { (tab: RSTabID, activeID?: ConstituentaID) => {
if (!schema) { if (!schema) {
return; return;
} }
@ -125,7 +125,7 @@ function RSTabs() {
); );
const onDeleteCst = useCallback( const onDeleteCst = useCallback(
(newActive?: number) => { (newActive?: ConstituentaID) => {
if (!newActive) { if (!newActive) {
navigateTab(RSTabID.CST_LIST); navigateTab(RSTabID.CST_LIST);
} else if (activeTab === RSTabID.CST_EDIT) { } else if (activeTab === RSTabID.CST_EDIT) {
@ -138,7 +138,7 @@ function RSTabs() {
); );
const onOpenCst = useCallback( const onOpenCst = useCallback(
(cstID: number) => { (cstID: ConstituentaID) => {
setSelected([cstID]); setSelected([cstID]);
navigateTab(RSTabID.CST_EDIT, cstID); navigateTab(RSTabID.CST_EDIT, cstID);
}, },

View File

@ -11,7 +11,7 @@ import useDropdown from '@/hooks/useDropdown';
import useLocalStorage from '@/hooks/useLocalStorage'; import useLocalStorage from '@/hooks/useLocalStorage';
import { CstMatchMode, DependencyMode } from '@/models/miscellaneous'; import { CstMatchMode, DependencyMode } from '@/models/miscellaneous';
import { applyGraphFilter } from '@/models/miscellaneousAPI'; import { applyGraphFilter } from '@/models/miscellaneousAPI';
import { IConstituenta, IRSForm } from '@/models/rsform'; import { ConstituentaID, IConstituenta, IRSForm } from '@/models/rsform';
import { createMockConstituenta, matchConstituenta } from '@/models/rsformAPI'; import { createMockConstituenta, matchConstituenta } from '@/models/rsformAPI';
import { extractGlobals } from '@/models/rslangAPI'; import { extractGlobals } from '@/models/rslangAPI';
import { prefixes } from '@/utils/constants'; import { prefixes } from '@/utils/constants';
@ -19,7 +19,7 @@ import { describeCstMatchMode, describeCstSource, labelCstMatchMode, labelCstSou
interface ConstituentsSearchProps { interface ConstituentsSearchProps {
schema?: IRSForm; schema?: IRSForm;
activeID?: number; activeID?: ConstituentaID;
activeExpression: string; activeExpression: string;
setFiltered: React.Dispatch<React.SetStateAction<IConstituenta[]>>; setFiltered: React.Dispatch<React.SetStateAction<IConstituenta[]>>;
} }

View File

@ -7,15 +7,15 @@ import ConstituentaBadge from '@/components/ConstituentaBadge';
import DataTable, { createColumnHelper, IConditionalStyle, VisibilityState } from '@/components/DataTable'; import DataTable, { createColumnHelper, IConditionalStyle, VisibilityState } from '@/components/DataTable';
import { useConceptTheme } from '@/context/ThemeContext'; import { useConceptTheme } from '@/context/ThemeContext';
import useWindowSize from '@/hooks/useWindowSize'; import useWindowSize from '@/hooks/useWindowSize';
import { IConstituenta } from '@/models/rsform'; import { ConstituentaID, IConstituenta } from '@/models/rsform';
import { isMockCst } from '@/models/rsformAPI'; import { isMockCst } from '@/models/rsformAPI';
import { prefixes } from '@/utils/constants'; import { prefixes } from '@/utils/constants';
import { describeConstituenta } from '@/utils/labels'; import { describeConstituenta } from '@/utils/labels';
interface ConstituentsTableProps { interface ConstituentsTableProps {
items: IConstituenta[]; items: IConstituenta[];
activeID?: number; activeID?: ConstituentaID;
onOpenEdit: (cstID: number) => void; onOpenEdit: (cstID: ConstituentaID) => void;
denseThreshold?: number; denseThreshold?: number;
maxHeight: string; maxHeight: string;
} }

View File

@ -5,7 +5,7 @@ import { motion } from 'framer-motion';
import { useMemo, useState } from 'react'; import { useMemo, useState } from 'react';
import { useConceptTheme } from '@/context/ThemeContext'; import { useConceptTheme } from '@/context/ThemeContext';
import { IConstituenta, IRSForm } from '@/models/rsform'; import { ConstituentaID, IConstituenta, IRSForm } from '@/models/rsform';
import { animateSideView } from '@/styling/animations'; import { animateSideView } from '@/styling/animations';
import ConstituentsSearch from './ConstituentsSearch'; import ConstituentsSearch from './ConstituentsSearch';
@ -21,9 +21,9 @@ interface ViewConstituentsProps {
expression: string; expression: string;
isBottom?: boolean; isBottom?: boolean;
baseHeight: string; baseHeight: string;
activeID?: number; activeID?: ConstituentaID;
schema?: IRSForm; schema?: IRSForm;
onOpenEdit: (cstID: number) => void; onOpenEdit: (cstID: ConstituentaID) => void;
} }
function ViewConstituents({ expression, schema, activeID, isBottom, baseHeight, onOpenEdit }: ViewConstituentsProps) { function ViewConstituents({ expression, schema, activeID, isBottom, baseHeight, onOpenEdit }: ViewConstituentsProps) {