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 (
<img
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
})}
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 { CstMatchMode } from '@/models/miscellaneous';
import { EntityID, IConstituenta } from '@/models/rsform';
import { ConstituentaID, IConstituenta } from '@/models/rsform';
import { matchConstituenta } from '@/models/rsformAPI';
import { describeConstituenta, describeConstituentaTerm } from '@/utils/labels';
@ -26,7 +26,7 @@ function ConstituentaSelector({ items, value, onSelectValue }: ConstituentaSelec
}, [items]);
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);
return !cst ? false : matchConstituenta(cst, inputValue, CstMatchMode.ALL);
},

View File

@ -51,7 +51,6 @@ function Checkbox({
className={clsx(
'flex items-center gap-2', // prettier: split lines
'outline-none',
'text-start',
cursor,
className
)}
@ -79,7 +78,7 @@ function Checkbox({
</div>
) : null}
</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>
</button>

View File

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

View File

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

View File

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

View File

@ -2,7 +2,7 @@
import { createColumnHelper } from '@tanstack/react-table';
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 ConstituentaPicker from '@/components/ConstituentaPicker';
@ -17,7 +17,7 @@ import { prefixes } from '@/utils/constants';
interface ArgumentsTabProps {
state: IArgumentsState;
schema: IRSForm;
partialUpdate: Dispatch<Partial<IArgumentsState>>;
partialUpdate: React.Dispatch<Partial<IArgumentsState>>;
}
export interface IArgumentsState {

View File

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

View File

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

View File

@ -96,6 +96,11 @@ export interface IVersionInfo {
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.
*/
@ -105,7 +110,7 @@ export interface IVersionData extends Omit<IVersionInfo, 'id' | 'time_create'> {
* Represents library item common data typical for all item types.
*/
export interface ILibraryItem {
id: number;
id: LibraryItemID;
item_type: LibraryItemType;
title: string;
alias: string;

View File

@ -4,7 +4,7 @@
import { Graph } from '@/models/Graph';
import { ILibraryItemEx, ILibraryUpdateData } from './library';
import { ILibraryItemEx, ILibraryUpdateData, LibraryItemID } from './library';
import { IArgumentInfo, ParsingStatus, ValueClass } from './rslang';
/**
@ -25,9 +25,14 @@ export enum CstType {
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.
@ -63,9 +68,9 @@ export interface TermForm {
* Represents Constituenta basic persistent data.
*/
export interface IConstituentaMeta {
id: EntityID;
schema: number;
order: number;
id: ConstituentaID;
schema: LibraryItemID;
order: Position;
alias: string;
convention: string;
cst_type: CstType;
@ -102,7 +107,7 @@ export interface IConstituenta extends IConstituentaMeta {
* Represents Constituenta list.
*/
export interface IConstituentaList {
items: EntityID[];
items: ConstituentaID[];
}
/**
@ -113,14 +118,14 @@ export interface ICstCreateData
IConstituentaMeta,
'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.
*/
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}.
*/
export interface ICstSubstituteData {
original: EntityID;
substitution: EntityID;
original: ConstituentaID;
substitution: ConstituentaID;
transfer_term: boolean;
}
@ -161,7 +166,7 @@ export interface ICstCreatedResponse {
* Represents data response when creating producing structure of {@link IConstituenta}.
*/
export interface IProduceStructureResponse {
cst_list: EntityID[];
cst_list: ConstituentaID[];
schema: IRSFormData;
}
@ -226,3 +231,13 @@ export interface IVersionCreatedResponse {
version: number;
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 { 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 { 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.
*/
export function createMockConstituenta(id: number, alias: string, comment: string): IConstituenta {
export function createMockConstituenta(id: ConstituentaID, alias: string, comment: string): IConstituenta {
return {
id: id,
order: -1,

View File

@ -6,7 +6,7 @@ import { useMemo, useState } from 'react';
import useLocalStorage from '@/hooks/useLocalStorage';
import useWindowSize from '@/hooks/useWindowSize';
import { IConstituenta } from '@/models/rsform';
import { ConstituentaID, IConstituenta } from '@/models/rsform';
import { globalIDs } from '@/utils/constants';
import { useRSEdit } from '../RSEditContext';
@ -24,7 +24,7 @@ interface EditorConstituentaProps {
activeCst?: IConstituenta;
isModified: boolean;
setIsModified: React.Dispatch<React.SetStateAction<boolean>>;
onOpenEdit: (cstID: number) => void;
onOpenEdit: (cstID: ConstituentaID) => void;
}
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 SelectedCounter from '@/components/SelectedCounter';
import { CstType } from '@/models/rsform';
import { ConstituentaID, CstType } from '@/models/rsform';
import { useRSEdit } from '../RSEditContext';
import RSListToolbar from './RSListToolbar';
import RSTable from './RSTable';
interface EditorRSListProps {
selected: number[];
setSelected: React.Dispatch<React.SetStateAction<number[]>>;
onOpenEdit: (cstID: number) => void;
selected: ConstituentaID[];
setSelected: React.Dispatch<React.SetStateAction<ConstituentaID[]>>;
onOpenEdit: (cstID: ConstituentaID) => void;
}
function EditorRSList({ selected, setSelected, onOpenEdit }: EditorRSListProps) {
@ -38,7 +38,7 @@ function EditorRSList({ selected, setSelected, onOpenEdit }: EditorRSListProps)
setSelected([]);
} else {
const newRowSelection = typeof updater === 'function' ? updater(rowSelection) : updater;
const newSelection: number[] = [];
const newSelection: ConstituentaID[] = [];
controller.schema.items.forEach((cst, index) => {
if (newRowSelection[String(index)] === true) {
newSelection.push(cst.id);

View File

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

View File

@ -12,7 +12,7 @@ import { useConceptTheme } from '@/context/ThemeContext';
import DlgGraphParams from '@/dialogs/DlgGraphParams';
import useLocalStorage from '@/hooks/useLocalStorage';
import { GraphColoringScheme, GraphFilterParams } from '@/models/miscellaneous';
import { CstType } from '@/models/rsform';
import { ConstituentaID, CstType } from '@/models/rsform';
import { colorBgGraphNode } from '@/styling/color';
import { classnames, TIMEOUT_GRAPH_REFRESH } from '@/utils/constants';
@ -24,9 +24,9 @@ import useGraphFilter from './useGraphFilter';
import ViewHidden from './ViewHidden';
interface EditorTermGraphProps {
selected: number[];
setSelected: React.Dispatch<React.SetStateAction<number[]>>;
onOpenEdit: (cstID: number) => void;
selected: ConstituentaID[];
setSelected: React.Dispatch<React.SetStateAction<ConstituentaID[]>>;
onOpenEdit: (cstID: ConstituentaID) => void;
}
function EditorTermGraph({ selected, setSelected, onOpenEdit }: EditorTermGraphProps) {
@ -51,7 +51,7 @@ function EditorTermGraph({ selected, setSelected, onOpenEdit }: EditorTermGraphP
const [showParamsDialog, setShowParamsDialog] = useState(false);
const filtered = useGraphFilter(controller.schema, filterParams);
const [hidden, setHidden] = useState<number[]>([]);
const [hidden, setHidden] = useState<ConstituentaID[]>([]);
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 [orbit, setOrbit] = useState(false);
const [hoverID, setHoverID] = useState<number | undefined>(undefined);
const [hoverID, setHoverID] = useState<ConstituentaID | undefined>(undefined);
const hoverCst = useMemo(() => {
return controller.schema?.items.find(cst => cst.id === hoverID);
}, [controller.schema?.items, hoverID]);
@ -71,7 +71,7 @@ function EditorTermGraph({ selected, setSelected, onOpenEdit }: EditorTermGraphP
if (!controller.schema) {
return;
}
const newDismissed: number[] = [];
const newDismissed: ConstituentaID[] = [];
controller.schema.items.forEach(cst => {
if (!filtered.nodes.has(cst.id)) {
newDismissed.push(cst.id);
@ -116,13 +116,13 @@ function EditorTermGraph({ selected, setSelected, onOpenEdit }: EditorTermGraphP
}, [filtered.nodes]);
const handleGraphSelection = useCallback(
(newID: number) => {
(newID: ConstituentaID) => {
setSelected(prev => [...prev, newID]);
},
[setSelected]
);
function toggleDismissed(cstID: number) {
function toggleDismissed(cstID: ConstituentaID) {
setSelected(prev => {
if (prev.includes(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 { useConceptTheme } from '@/context/ThemeContext';
import { ConstituentaID } from '@/models/rsform';
import { graphDarkT, graphLightT } from '@/styling/color';
import { resources } from '@/utils/constants';
interface TermGraphProps {
nodes: GraphNode[];
edges: GraphEdge[];
selectedIDs: number[];
selectedIDs: ConstituentaID[];
layout: LayoutTypes;
is3D: boolean;
orbit: boolean;
setHoverID: (newID: number | undefined) => void;
onEdit: (cstID: number) => void;
onSelect: (newID: number) => void;
setHoverID: (newID: ConstituentaID | undefined) => void;
onEdit: (cstID: ConstituentaID) => void;
onSelect: (newID: ConstituentaID) => void;
onDeselectAll: () => void;
toggleResetView: boolean;

View File

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

View File

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

View File

@ -11,7 +11,7 @@ import useDropdown from '@/hooks/useDropdown';
import useLocalStorage from '@/hooks/useLocalStorage';
import { CstMatchMode, DependencyMode } from '@/models/miscellaneous';
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 { extractGlobals } from '@/models/rslangAPI';
import { prefixes } from '@/utils/constants';
@ -19,7 +19,7 @@ import { describeCstMatchMode, describeCstSource, labelCstMatchMode, labelCstSou
interface ConstituentsSearchProps {
schema?: IRSForm;
activeID?: number;
activeID?: ConstituentaID;
activeExpression: string;
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 { useConceptTheme } from '@/context/ThemeContext';
import useWindowSize from '@/hooks/useWindowSize';
import { IConstituenta } from '@/models/rsform';
import { ConstituentaID, IConstituenta } from '@/models/rsform';
import { isMockCst } from '@/models/rsformAPI';
import { prefixes } from '@/utils/constants';
import { describeConstituenta } from '@/utils/labels';
interface ConstituentsTableProps {
items: IConstituenta[];
activeID?: number;
onOpenEdit: (cstID: number) => void;
activeID?: ConstituentaID;
onOpenEdit: (cstID: ConstituentaID) => void;
denseThreshold?: number;
maxHeight: string;
}

View File

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