From 53b746f3c441bfba8689b2a80339b8957e6b4afd Mon Sep 17 00:00:00 2001 From: Ivan <8611739+IRBorisov@users.noreply.github.com> Date: Wed, 19 Feb 2025 22:33:09 +0300 Subject: [PATCH] R: Distinguish undefined semantics vs null --- rsconcept/frontend/src/app/GlobalDialogs.tsx | 2 +- .../frontend/src/backend/apiTransport.ts | 2 - .../src/backend/useMutationErrors.tsx | 4 +- .../src/components/DataTable/DataTable.tsx | 4 +- .../src/components/DataTable/SelectRow.tsx | 2 +- .../src/components/DataTable/TableBody.tsx | 8 ++-- .../frontend/src/components/InfoError.tsx | 2 +- .../src/components/Input/SearchBar.tsx | 2 +- .../src/features/library/backend/types.ts | 4 +- .../library/backend/useApplyLibraryFilter.tsx | 19 ++++------ .../library/components/EditorLibraryItem.tsx | 2 +- .../library/components/SelectLibraryItem.tsx | 8 ++-- .../library/components/SelectVersion.tsx | 6 +-- .../library/dialogs/DlgCloneLibraryItem.tsx | 6 +-- .../library/dialogs/DlgCreateVersion.tsx | 6 +-- .../dialogs/DlgEditEditors/DlgEditEditors.tsx | 4 +- .../src/features/library/models/FolderTree.ts | 6 +-- .../src/features/library/models/library.ts | 23 +++++------ .../pages/LibraryPage/ToolbarSearch.tsx | 6 +-- .../features/library/stores/librarySearch.ts | 38 +++++++++---------- .../oss/components/PickMultiOperation.tsx | 8 ++-- .../oss/components/SelectOperation.tsx | 12 +++--- .../oss/dialogs/DlgDeleteOperation.tsx | 2 +- .../DlgEditOperation/DlgEditOperation.tsx | 1 - .../oss/dialogs/DlgRelocateConstituents.tsx | 10 ++--- .../rsform/components/BadgeConstituenta.tsx | 4 +- .../rsform/components/PickConstituenta.tsx | 4 +- .../components/PickMultiConstituenta.tsx | 7 +++- .../rsform/components/PickSubstitutions.tsx | 20 +++++----- .../rsform/components/RefsInput/tooltip.ts | 12 ++---- .../rsform/components/SelectConstituenta.tsx | 10 ++--- .../dialogs/DlgCstTemplate/TabArguments.tsx | 6 +-- .../dialogs/DlgCstTemplate/TabTemplate.tsx | 6 +-- .../DlgCstTemplate/TemplateContext.tsx | 20 +++++----- .../DlgEditReference/TabEntityReference.tsx | 2 +- .../rsform/dialogs/DlgShowAST/DlgShowAST.tsx | 4 +- .../dialogs/DlgShowAST/graph/ASTLayout.ts | 3 +- .../DlgShowTypeGraph/graph/MGraphLayout.ts | 3 +- .../rsform/dialogs/DlgUploadRSForm.tsx | 4 +- .../frontend/src/features/rsform/labels.ts | 4 +- .../src/features/rsform/models/TMGraph.ts | 12 +++--- .../src/features/rsform/models/rsformAPI.ts | 3 +- .../EditorConstituenta/EditorConstituenta.tsx | 2 +- .../EditorConstituenta/FormConstituenta.tsx | 12 +++--- .../ToolbarConstituenta.tsx | 6 ++- .../EditorRSExpression/EditorRSExpression.tsx | 23 +++++------ .../EditorRSExpression/ParsingResult.tsx | 6 +-- .../EditorRSExpression/RSEditControls.tsx | 4 +- .../EditorRSExpression/StatusBar.tsx | 10 ++--- .../ToolbarRSExpression.tsx | 4 +- .../RSFormPage/EditorRSExpression/index.tsx | 2 +- .../EditorRSFormCard/ToolbarVersioning.tsx | 4 +- .../RSFormPage/EditorRSList/EditorRSList.tsx | 4 +- .../RSFormPage/EditorRSList/TableRSList.tsx | 2 +- .../RSFormPage/EditorRSList/ToolbarRSList.tsx | 2 +- .../RSFormPage/EditorTermGraph/TGFlow.tsx | 33 +++++++++------- .../EditorTermGraph/graph/TGLayout.ts | 3 +- .../rsform/pages/RSFormPage/RSEditContext.tsx | 28 +++++++------- .../ViewConstituents/ConstituentsSearch.tsx | 3 +- .../ViewConstituents/SelectGraphFilter.tsx | 2 +- .../TableSideConstituents.tsx | 11 +++--- .../ViewConstituents/ViewConstituents.tsx | 2 +- .../features/users/components/SelectUser.tsx | 2 +- rsconcept/frontend/src/stores/dialogs.ts | 12 +++--- rsconcept/frontend/src/stores/tooltips.ts | 6 +-- rsconcept/frontend/src/utils/utils.ts | 12 +++--- 66 files changed, 237 insertions(+), 269 deletions(-) diff --git a/rsconcept/frontend/src/app/GlobalDialogs.tsx b/rsconcept/frontend/src/app/GlobalDialogs.tsx index 45b19a74..c49ed7d8 100644 --- a/rsconcept/frontend/src/app/GlobalDialogs.tsx +++ b/rsconcept/frontend/src/app/GlobalDialogs.tsx @@ -31,7 +31,7 @@ const DlgUploadRSForm = React.lazy(() => import('@/features/rsform/dialogs/DlgUp export const GlobalDialogs = () => { const active = useDialogsStore(state => state.active); - if (active === undefined) { + if (active === null) { return null; } switch (active) { diff --git a/rsconcept/frontend/src/backend/apiTransport.ts b/rsconcept/frontend/src/backend/apiTransport.ts index 7de4de9e..26aea995 100644 --- a/rsconcept/frontend/src/backend/apiTransport.ts +++ b/rsconcept/frontend/src/backend/apiTransport.ts @@ -32,8 +32,6 @@ axiosInstance.interceptors.request.use(config => { }); // ================ Data transfer types ================ -export type DataCallback = (data: ResponseData) => void; - export interface IFrontRequest { data?: RequestData; successMessage?: string | ((data: ResponseData) => string); diff --git a/rsconcept/frontend/src/backend/useMutationErrors.tsx b/rsconcept/frontend/src/backend/useMutationErrors.tsx index 0cacd254..ab72a334 100644 --- a/rsconcept/frontend/src/backend/useMutationErrors.tsx +++ b/rsconcept/frontend/src/backend/useMutationErrors.tsx @@ -5,10 +5,10 @@ import { KEYS } from './configuration'; export const useMutationErrors = () => { const queryClient = useQueryClient(); - const [ignored, setIgnored] = useState<(Error | null)[]>([]); + const [ignored, setIgnored] = useState([]); const mutationErrors = useMutationState({ filters: { mutationKey: [KEYS.global_mutation], status: 'error' }, - select: mutation => mutation.state.error + select: mutation => mutation.state.error! }); console.log(queryClient.getMutationCache().getAll()); diff --git a/rsconcept/frontend/src/components/DataTable/DataTable.tsx b/rsconcept/frontend/src/components/DataTable/DataTable.tsx index cb38630d..0d62c213 100644 --- a/rsconcept/frontend/src/components/DataTable/DataTable.tsx +++ b/rsconcept/frontend/src/components/DataTable/DataTable.tsx @@ -141,7 +141,7 @@ function DataTable({ ...restProps }: DataTableProps) { const [sorting, setSorting] = useState(initialSorting ? [initialSorting] : []); - const [lastSelected, setLastSelected] = useState(undefined); + const [lastSelected, setLastSelected] = useState(null); const [pagination, setPagination] = useState({ pageIndex: 0, @@ -198,7 +198,7 @@ function DataTable({ enableRowSelection={enableRowSelection} enableSorting={enableSorting} headPosition={headPosition} - resetLastSelected={() => setLastSelected(undefined)} + resetLastSelected={() => setLastSelected(null)} /> ) : null} diff --git a/rsconcept/frontend/src/components/DataTable/SelectRow.tsx b/rsconcept/frontend/src/components/DataTable/SelectRow.tsx index ba9bd2ef..f1d4c503 100644 --- a/rsconcept/frontend/src/components/DataTable/SelectRow.tsx +++ b/rsconcept/frontend/src/components/DataTable/SelectRow.tsx @@ -6,7 +6,7 @@ import { Checkbox } from '../Input'; interface SelectRowProps { row: Row; - onChangeLastSelected: (newValue: string | undefined) => void; + onChangeLastSelected: (newValue: string) => void; } function SelectRow({ row, onChangeLastSelected }: SelectRowProps) { diff --git a/rsconcept/frontend/src/components/DataTable/TableBody.tsx b/rsconcept/frontend/src/components/DataTable/TableBody.tsx index 247d4591..d5ebbebb 100644 --- a/rsconcept/frontend/src/components/DataTable/TableBody.tsx +++ b/rsconcept/frontend/src/components/DataTable/TableBody.tsx @@ -15,8 +15,8 @@ interface TableBodyProps { enableRowSelection?: boolean; conditionalRowStyles?: IConditionalStyle[]; - lastSelected: string | undefined; - onChangeLastSelected: (newValue: string | undefined) => void; + lastSelected: string | null; + onChangeLastSelected: (newValue: string | null) => void; onRowClicked?: (rowData: TData, event: CProps.EventMouse) => void; onRowDoubleClicked?: (rowData: TData, event: CProps.EventMouse) => void; @@ -49,7 +49,7 @@ function TableBody({ newSelection[row.id] = !target.getIsSelected(); }); table.setRowSelection(prev => ({ ...prev, ...newSelection })); - onChangeLastSelected(undefined); + onChangeLastSelected(null); } else { onChangeLastSelected(target.id); target.toggleSelected(!target.getIsSelected()); @@ -94,7 +94,7 @@ function TableBody({ width: noHeader && index === 0 ? `calc(var(--col-${cell.column.id}-size) * 1px)` : 'auto' }} onClick={event => handleRowClicked(row, event)} - onDoubleClick={event => (onRowDoubleClicked ? onRowDoubleClicked(row.original, event) : undefined)} + onDoubleClick={event => onRowDoubleClicked?.(row.original, event)} > {flexRender(cell.column.columnDef.cell, cell.getContext())} diff --git a/rsconcept/frontend/src/components/InfoError.tsx b/rsconcept/frontend/src/components/InfoError.tsx index dbf879cc..80efbaa6 100644 --- a/rsconcept/frontend/src/components/InfoError.tsx +++ b/rsconcept/frontend/src/components/InfoError.tsx @@ -6,7 +6,7 @@ import { isResponseHtml } from '@/utils/utils'; import { PrettyJson } from './View'; -export type ErrorData = string | Error | AxiosError | ZodError | undefined | null; +export type ErrorData = string | Error | AxiosError | ZodError; interface InfoErrorProps { error: ErrorData; diff --git a/rsconcept/frontend/src/components/Input/SearchBar.tsx b/rsconcept/frontend/src/components/Input/SearchBar.tsx index cb4812e1..8febc7d7 100644 --- a/rsconcept/frontend/src/components/Input/SearchBar.tsx +++ b/rsconcept/frontend/src/components/Input/SearchBar.tsx @@ -53,7 +53,7 @@ export function SearchBar({ className={clsx('outline-none bg-transparent', !noIcon && 'pl-10')} noBorder={noBorder} value={query} - onChange={event => (onChangeQuery ? onChangeQuery(event.target.value) : undefined)} + onChange={event => onChangeQuery?.(event.target.value)} /> ); diff --git a/rsconcept/frontend/src/features/library/backend/types.ts b/rsconcept/frontend/src/features/library/backend/types.ts index 58358a49..8bd1a4e2 100644 --- a/rsconcept/frontend/src/features/library/backend/types.ts +++ b/rsconcept/frontend/src/features/library/backend/types.ts @@ -86,7 +86,7 @@ export const schemaCloneLibraryItem = schemaLibraryItem alias: z.string().nonempty(errorMsg.requiredField), location: z.string().refine(data => validateLocation(data), { message: errorMsg.invalidLocation }), - items: z.array(z.number()).optional() + items: z.array(z.number()) }); export const schemaCreateLibraryItem = z @@ -138,5 +138,5 @@ export const schemaVersionUpdate = z.object({ export const schemaVersionCreate = z.object({ version: z.string(), description: z.string(), - items: z.array(z.number()).optional() + items: z.array(z.number()) }); diff --git a/rsconcept/frontend/src/features/library/backend/useApplyLibraryFilter.tsx b/rsconcept/frontend/src/features/library/backend/useApplyLibraryFilter.tsx index 2f37cfb5..4e8ba95f 100644 --- a/rsconcept/frontend/src/features/library/backend/useApplyLibraryFilter.tsx +++ b/rsconcept/frontend/src/features/library/backend/useApplyLibraryFilter.tsx @@ -16,32 +16,29 @@ export function useApplyLibraryFilter(filter: ILibraryFilter) { if (filter.folderMode && filter.location) { if (filter.subfolders) { result = result.filter( - item => item.location == filter.location || item.location.startsWith(filter.location! + '/') + item => item.location == filter.location || item.location.startsWith(filter.location + '/') ); } else { result = result.filter(item => item.location == filter.location); } } - if (filter.type) { - result = result.filter(item => item.item_type === filter.type); - } - if (filter.isVisible !== undefined) { + if (filter.isVisible !== null) { result = result.filter(item => filter.isVisible === item.visible); } - if (filter.isOwned !== undefined) { + if (filter.isOwned !== null) { result = result.filter(item => filter.isOwned === (item.owner === user.id)); } - if (filter.isEditor !== undefined) { + if (filter.isEditor !== null) { result = result.filter(item => filter.isEditor == user.editor.includes(item.id)); } - if (filter.filterUser !== undefined) { + if (filter.filterUser !== null) { result = result.filter(item => filter.filterUser === item.owner); } - if (!filter.folderMode && filter.path) { - result = result.filter(item => matchLibraryItemLocation(item, filter.path!)); + if (!filter.folderMode && !!filter.path) { + result = result.filter(item => matchLibraryItemLocation(item, filter.path)); } if (filter.query) { - result = result.filter(item => matchLibraryItem(item, filter.query!)); + result = result.filter(item => matchLibraryItem(item, filter.query)); } return { filtered: result }; diff --git a/rsconcept/frontend/src/features/library/components/EditorLibraryItem.tsx b/rsconcept/frontend/src/features/library/components/EditorLibraryItem.tsx index 94edda53..2f8271ff 100644 --- a/rsconcept/frontend/src/features/library/components/EditorLibraryItem.tsx +++ b/rsconcept/frontend/src/features/library/components/EditorLibraryItem.tsx @@ -116,7 +116,7 @@ export function EditorLibraryItem({ controller }: EditorLibraryItemProps) { {ownerSelector.isOpen ? ( ) : null} diff --git a/rsconcept/frontend/src/features/library/components/SelectLibraryItem.tsx b/rsconcept/frontend/src/features/library/components/SelectLibraryItem.tsx index 0d80deb3..a7e14a70 100644 --- a/rsconcept/frontend/src/features/library/components/SelectLibraryItem.tsx +++ b/rsconcept/frontend/src/features/library/components/SelectLibraryItem.tsx @@ -9,10 +9,10 @@ import { ILibraryItem } from '../backend/types'; import { matchLibraryItem } from '../models/libraryAPI'; interface SelectLibraryItemProps extends CProps.Styling { - items?: ILibraryItem[]; - value?: ILibraryItem; - onChange: (newValue?: ILibraryItem) => void; + value: ILibraryItem | null; + onChange: (newValue: ILibraryItem | null) => void; + items?: ILibraryItem[]; placeholder?: string; noBorder?: boolean; } @@ -41,7 +41,7 @@ export function SelectLibraryItem({ className={clsx('text-ellipsis', className)} options={options} value={value ? { value: value.id, label: `${value.alias}: ${value.title}` } : null} - onChange={data => onChange(items?.find(cst => cst.id === data?.value))} + onChange={data => onChange(items?.find(cst => cst.id === data?.value) ?? null)} filterOption={filter} placeholder={placeholder} {...restProps} diff --git a/rsconcept/frontend/src/features/library/components/SelectVersion.tsx b/rsconcept/frontend/src/features/library/components/SelectVersion.tsx index 5fd14144..1b2f08d3 100644 --- a/rsconcept/frontend/src/features/library/components/SelectVersion.tsx +++ b/rsconcept/frontend/src/features/library/components/SelectVersion.tsx @@ -10,10 +10,10 @@ import { IVersionInfo } from '../backend/types'; interface SelectVersionProps extends CProps.Styling { id?: string; - items?: IVersionInfo[]; - value?: number; - onChange: (newValue?: number) => void; + value: number | undefined; + onChange: (newValue: number | undefined) => void; + items?: IVersionInfo[]; placeholder?: string; noBorder?: boolean; } diff --git a/rsconcept/frontend/src/features/library/dialogs/DlgCloneLibraryItem.tsx b/rsconcept/frontend/src/features/library/dialogs/DlgCloneLibraryItem.tsx index ab3fb74e..d0717cd2 100644 --- a/rsconcept/frontend/src/features/library/dialogs/DlgCloneLibraryItem.tsx +++ b/rsconcept/frontend/src/features/library/dialogs/DlgCloneLibraryItem.tsx @@ -53,7 +53,7 @@ function DlgCloneLibraryItem() { read_only: false, access_policy: AccessPolicy.PUBLIC, location: initialLocation, - items: undefined + items: [] }, mode: 'onChange', reValidateMode: 'onChange' @@ -165,8 +165,8 @@ function DlgCloneLibraryItem() { field.onChange(value ? selected : undefined)} + value={field.value.length > 0} + onChange={value => field.onChange(value ? selected : [])} /> )} /> diff --git a/rsconcept/frontend/src/features/library/dialogs/DlgCreateVersion.tsx b/rsconcept/frontend/src/features/library/dialogs/DlgCreateVersion.tsx index c50fdf1c..2d783666 100644 --- a/rsconcept/frontend/src/features/library/dialogs/DlgCreateVersion.tsx +++ b/rsconcept/frontend/src/features/library/dialogs/DlgCreateVersion.tsx @@ -32,7 +32,7 @@ function DlgCreateVersion() { defaultValues: { version: versions.length > 0 ? nextVersion(versions[versions.length - 1].version) : '1.0.0', description: '', - items: undefined + items: [] } }); const version = useWatch({ control, name: 'version' }); @@ -61,8 +61,8 @@ function DlgCreateVersion() { field.onChange(value ? selected : undefined)} + value={field.value.length > 0} + onChange={value => field.onChange(value ? selected : [])} /> )} /> diff --git a/rsconcept/frontend/src/features/library/dialogs/DlgEditEditors/DlgEditEditors.tsx b/rsconcept/frontend/src/features/library/dialogs/DlgEditEditors/DlgEditEditors.tsx index e1d38c85..a213e3d2 100644 --- a/rsconcept/frontend/src/features/library/dialogs/DlgEditEditors/DlgEditEditors.tsx +++ b/rsconcept/frontend/src/features/library/dialogs/DlgEditEditors/DlgEditEditors.tsx @@ -61,8 +61,8 @@ function DlgEditEditors() {
- handleChange(undefined)}> + handleChange(null)}>
отображать все diff --git a/rsconcept/frontend/src/features/library/stores/librarySearch.ts b/rsconcept/frontend/src/features/library/stores/librarySearch.ts index 81f4d111..75acc3d3 100644 --- a/rsconcept/frontend/src/features/library/stores/librarySearch.ts +++ b/rsconcept/frontend/src/features/library/stores/librarySearch.ts @@ -21,20 +21,20 @@ interface LibrarySearchStore { location: string; setLocation: (value: string) => void; - head: LocationHead | undefined; - setHead: (value: LocationHead | undefined) => void; + head: LocationHead | null; + setHead: (value: LocationHead | null) => void; - isVisible: boolean | undefined; + isVisible: boolean | null; toggleVisible: () => void; - isOwned: boolean | undefined; + isOwned: boolean | null; toggleOwned: () => void; - isEditor: boolean | undefined; + isEditor: boolean | null; toggleEditor: () => void; - filterUser: number | undefined; - setFilterUser: (value: number | undefined) => void; + filterUser: number | null; + setFilterUser: (value: number | null) => void; resetFilter: () => void; } @@ -57,19 +57,19 @@ export const useLibrarySearchStore = create()( location: '', setLocation: value => set(!!value ? { location: value, folderMode: true } : { location: '' }), - head: undefined, + head: null, setHead: value => set({ head: value }), isVisible: true, toggleVisible: () => set(state => ({ isVisible: toggleTristateFlag(state.isVisible) })), - isOwned: undefined, + isOwned: null, toggleOwned: () => set(state => ({ isOwned: toggleTristateFlag(state.isOwned) })), - isEditor: undefined, + isEditor: null, toggleEditor: () => set(state => ({ isEditor: toggleTristateFlag(state.isEditor) })), - filterUser: undefined, + filterUser: null, setFilterUser: value => set({ filterUser: value }), resetFilter: () => @@ -77,11 +77,11 @@ export const useLibrarySearchStore = create()( query: '', path: '', location: '', - head: undefined, + head: null, isVisible: true, - isOwned: undefined, - isEditor: undefined, - filterUser: undefined + isOwned: null, + isEditor: null, + filterUser: null })) }), { @@ -116,11 +116,11 @@ export function useHasCustomFilter(): boolean { !!path || !!query || !!location || - head !== undefined || - isEditor !== undefined || - isOwned !== undefined || + head !== null || + isEditor !== null || + isOwned !== null || isVisible !== true || - filterUser !== undefined + filterUser !== null ); } diff --git a/rsconcept/frontend/src/features/oss/components/PickMultiOperation.tsx b/rsconcept/frontend/src/features/oss/components/PickMultiOperation.tsx index 9560eeb5..18dae4cf 100644 --- a/rsconcept/frontend/src/features/oss/components/PickMultiOperation.tsx +++ b/rsconcept/frontend/src/features/oss/components/PickMultiOperation.tsx @@ -11,7 +11,7 @@ import { NoData } from '@/components/View'; import { IOperation } from '../models/oss'; -import SelectOperation from './SelectOperation'; +import { SelectOperation } from './SelectOperation'; interface PickMultiOperationProps extends CProps.Styling { value: number[]; @@ -25,17 +25,17 @@ const columnHelper = createColumnHelper(); export function PickMultiOperation({ rows, items, value, onChange, className, ...restProps }: PickMultiOperationProps) { const selectedItems = value.map(itemID => items.find(item => item.id === itemID)!); const nonSelectedItems = items.filter(item => !value.includes(item.id)); - const [lastSelected, setLastSelected] = useState(undefined); + const [lastSelected, setLastSelected] = useState(null); function handleDelete(operation: number) { onChange(value.filter(item => item !== operation)); } - function handleSelect(operation?: IOperation) { + function handleSelect(operation: IOperation | null) { if (operation) { setLastSelected(operation); onChange([...value, operation.id]); - setTimeout(() => setLastSelected(undefined), 1000); + setTimeout(() => setLastSelected(null), 1000); } } diff --git a/rsconcept/frontend/src/features/oss/components/SelectOperation.tsx b/rsconcept/frontend/src/features/oss/components/SelectOperation.tsx index 33869c5e..e6024fb6 100644 --- a/rsconcept/frontend/src/features/oss/components/SelectOperation.tsx +++ b/rsconcept/frontend/src/features/oss/components/SelectOperation.tsx @@ -9,15 +9,15 @@ import { IOperation } from '../models/oss'; import { matchOperation } from '../models/ossAPI'; interface SelectOperationProps extends CProps.Styling { - items?: IOperation[]; - value?: IOperation; - onChange: (newValue?: IOperation) => void; + value: IOperation | null; + onChange: (newValue: IOperation | null) => void; + items?: IOperation[]; placeholder?: string; noBorder?: boolean; } -function SelectOperation({ +export function SelectOperation({ className, items, value, @@ -41,12 +41,10 @@ function SelectOperation({ className={clsx('text-ellipsis', className)} options={options} value={value ? { value: value.id, label: `${value.alias}: ${value.title}` } : null} - onChange={data => onChange(items?.find(cst => cst.id === data?.value))} + onChange={data => onChange(items?.find(cst => cst.id === data?.value) ?? null)} filterOption={filter} placeholder={placeholder} {...restProps} /> ); } - -export default SelectOperation; diff --git a/rsconcept/frontend/src/features/oss/dialogs/DlgDeleteOperation.tsx b/rsconcept/frontend/src/features/oss/dialogs/DlgDeleteOperation.tsx index 6233d601..4b289052 100644 --- a/rsconcept/frontend/src/features/oss/dialogs/DlgDeleteOperation.tsx +++ b/rsconcept/frontend/src/features/oss/dialogs/DlgDeleteOperation.tsx @@ -69,7 +69,7 @@ function DlgDeleteOperation() { item.id === destination) : undefined; + const destinationItem = destination ? libraryItems.find(item => item.id === destination) ?? null : null; const [directionUp, setDirectionUp] = useState(true); - const [source, setSource] = useState( - libraryItems.find(item => item.id === initialTarget?.result) + const [source, setSource] = useState( + libraryItems.find(item => item.id === initialTarget?.result) ?? null ); const operation = oss.items.find(item => item.result === source?.id); @@ -80,13 +80,13 @@ function DlgRelocateConstituents() { setValue('destination', null); } - function handleSelectSource(newValue: ILibraryItem | undefined) { + function handleSelectSource(newValue: ILibraryItem | null) { setSource(newValue); setValue('destination', null); setValue('items', []); } - function handleSelectDestination(newValue: ILibraryItem | undefined) { + function handleSelectDestination(newValue: ILibraryItem | null) { if (newValue) { setValue('destination', newValue.id); } else { diff --git a/rsconcept/frontend/src/features/rsform/components/BadgeConstituenta.tsx b/rsconcept/frontend/src/features/rsform/components/BadgeConstituenta.tsx index 2d296bea..6cb118b8 100644 --- a/rsconcept/frontend/src/features/rsform/components/BadgeConstituenta.tsx +++ b/rsconcept/frontend/src/features/rsform/components/BadgeConstituenta.tsx @@ -19,7 +19,7 @@ interface BadgeConstituentaProps extends CProps.Styling { /** * Displays a badge with a constituenta alias and information tooltip. */ -function BadgeConstituenta({ value, prefixID, className, style }: BadgeConstituentaProps) { +export function BadgeConstituenta({ value, prefixID, className, style }: BadgeConstituentaProps) { const setActiveCst = useTooltipsStore(state => state.setActiveCst); return ( @@ -46,5 +46,3 @@ function BadgeConstituenta({ value, prefixID, className, style }: BadgeConstitue
); } - -export default BadgeConstituenta; diff --git a/rsconcept/frontend/src/features/rsform/components/PickConstituenta.tsx b/rsconcept/frontend/src/features/rsform/components/PickConstituenta.tsx index 236ab569..a81edde3 100644 --- a/rsconcept/frontend/src/features/rsform/components/PickConstituenta.tsx +++ b/rsconcept/frontend/src/features/rsform/components/PickConstituenta.tsx @@ -14,12 +14,12 @@ import { IConstituenta } from '../models/rsform'; import { matchConstituenta } from '../models/rsformAPI'; import { CstMatchMode } from '../stores/cstSearch'; -import BadgeConstituenta from './BadgeConstituenta'; +import { BadgeConstituenta } from './BadgeConstituenta'; interface PickConstituentaProps extends CProps.Styling { id?: string; items: IConstituenta[]; - value?: IConstituenta; + value: IConstituenta | null; onChange: (newValue: IConstituenta) => void; rows?: number; diff --git a/rsconcept/frontend/src/features/rsform/components/PickMultiConstituenta.tsx b/rsconcept/frontend/src/features/rsform/components/PickMultiConstituenta.tsx index d1568c32..063a335a 100644 --- a/rsconcept/frontend/src/features/rsform/components/PickMultiConstituenta.tsx +++ b/rsconcept/frontend/src/features/rsform/components/PickMultiConstituenta.tsx @@ -14,7 +14,7 @@ import { IConstituenta, IRSForm } from '../models/rsform'; import { isBasicConcept, matchConstituenta } from '../models/rsformAPI'; import { CstMatchMode } from '../stores/cstSearch'; -import BadgeConstituenta from './BadgeConstituenta'; +import { BadgeConstituenta } from './BadgeConstituenta'; import ToolbarGraphSelection from './ToolbarGraphSelection'; interface PickMultiConstituentaProps extends CProps.Styling { @@ -112,7 +112,10 @@ export function PickMultiConstituenta({ /> isBasicConcept(schema.cstByID.get(cstID)?.cst_type)} + isCore={cstID => { + const cst = schema.cstByID.get(cstID); + return !!cst && isBasicConcept(cst.cst_type); + }} isOwned={cstID => !schema.cstByID.get(cstID)?.is_inherited} value={value} onChange={onChange} diff --git a/rsconcept/frontend/src/features/rsform/components/PickSubstitutions.tsx b/rsconcept/frontend/src/features/rsform/components/PickSubstitutions.tsx index 2a018da4..cc8c5f6e 100644 --- a/rsconcept/frontend/src/features/rsform/components/PickSubstitutions.tsx +++ b/rsconcept/frontend/src/features/rsform/components/PickSubstitutions.tsx @@ -17,8 +17,8 @@ import { errorMsg } from '@/utils/labels'; import { ICstSubstitute } from '../backend/types'; import { IConstituenta, IRSForm } from '../models/rsform'; -import BadgeConstituenta from './BadgeConstituenta'; -import SelectConstituenta from './SelectConstituenta'; +import { BadgeConstituenta } from './BadgeConstituenta'; +import { SelectConstituenta } from './SelectConstituenta'; interface IMultiSubstitution { original_source: ILibraryItem; @@ -54,15 +54,13 @@ export function PickSubstitutions({ className, ...restProps }: PickSubstitutionsProps) { - const [leftArgument, setLeftArgument] = useState( - schemas.length === 1 ? schemas[0] : undefined - ); - const [rightArgument, setRightArgument] = useState( - schemas.length === 1 && allowSelfSubstitution ? schemas[0] : undefined + const [leftArgument, setLeftArgument] = useState(schemas.length === 1 ? schemas[0] : null); + const [rightArgument, setRightArgument] = useState( + schemas.length === 1 && allowSelfSubstitution ? schemas[0] : null ); - const [leftCst, setLeftCst] = useState(undefined); - const [rightCst, setRightCst] = useState(undefined); + const [leftCst, setLeftCst] = useState(null); + const [rightCst, setRightCst] = useState(null); const [deleteRight, setDeleteRight] = useState(true); const toggleDelete = () => setDeleteRight(prev => !prev); @@ -135,8 +133,8 @@ export function PickSubstitutions({ } } onChange([...value, newSubstitution]); - setLeftCst(undefined); - setRightCst(undefined); + setLeftCst(null); + setRightCst(null); } function handleDeclineSuggestion(item: IMultiSubstitution) { diff --git a/rsconcept/frontend/src/features/rsform/components/RefsInput/tooltip.ts b/rsconcept/frontend/src/features/rsform/components/RefsInput/tooltip.ts index 80c41a1b..1c39f397 100644 --- a/rsconcept/frontend/src/features/rsform/components/RefsInput/tooltip.ts +++ b/rsconcept/frontend/src/features/rsform/components/RefsInput/tooltip.ts @@ -23,7 +23,7 @@ export const tooltipProducer = (schema: IRSForm, canClick?: boolean) => { } if ('entity' in parse.ref) { - const cst = schema.cstByAlias.get(parse.ref.entity); + const cst = schema.cstByAlias.get(parse.ref.entity) ?? null; return { pos: parse.start, end: parse.end, @@ -31,7 +31,7 @@ export const tooltipProducer = (schema: IRSForm, canClick?: boolean) => { create: () => domTooltipEntityReference(parse.ref as IEntityReference, cst, canClick) }; } else { - let masterText: string | undefined = undefined; + let masterText: string | null = null; if (parse.ref.offset > 0) { const entities = findContainedNodes(parse.end, view.state.doc.length, syntaxTree(view.state), [RefEntity]); if (parse.ref.offset <= entities.length) { @@ -62,11 +62,7 @@ export function refsHoverTooltip(schema: IRSForm, canClick?: boolean): Extension /** * Create DOM tooltip for {@link IEntityReference}. */ -function domTooltipEntityReference( - ref: IEntityReference, - cst: IConstituenta | undefined, - canClick?: boolean -): TooltipView { +function domTooltipEntityReference(ref: IEntityReference, cst: IConstituenta | null, canClick?: boolean): TooltipView { const dom = document.createElement('div'); dom.className = clsx( 'max-h-[25rem] max-w-[25rem] min-w-[10rem]', @@ -122,7 +118,7 @@ function domTooltipEntityReference( */ function domTooltipSyntacticReference( ref: ISyntacticReference, - masterRef: string | undefined, + masterRef: string | null, canClick?: boolean ): TooltipView { const dom = document.createElement('div'); diff --git a/rsconcept/frontend/src/features/rsform/components/SelectConstituenta.tsx b/rsconcept/frontend/src/features/rsform/components/SelectConstituenta.tsx index 55f8610e..67c26c53 100644 --- a/rsconcept/frontend/src/features/rsform/components/SelectConstituenta.tsx +++ b/rsconcept/frontend/src/features/rsform/components/SelectConstituenta.tsx @@ -11,15 +11,15 @@ import { matchConstituenta } from '../models/rsformAPI'; import { CstMatchMode } from '../stores/cstSearch'; interface SelectConstituentaProps extends CProps.Styling { - value?: IConstituenta; - onChange: (newValue?: IConstituenta) => void; + value: IConstituenta | null; + onChange: (newValue: IConstituenta | null) => void; items?: IConstituenta[]; placeholder?: string; noBorder?: boolean; } -function SelectConstituenta({ +export function SelectConstituenta({ className, items, value, @@ -43,12 +43,10 @@ function SelectConstituenta({ className={clsx('text-ellipsis', className)} options={options} value={value ? { value: value.id, label: `${value.alias}: ${describeConstituentaTerm(value)}` } : null} - onChange={data => onChange(items?.find(cst => cst.id === data?.value))} + onChange={data => onChange(items?.find(cst => cst.id === data?.value) ?? null)} filterOption={filter} placeholder={placeholder} {...restProps} /> ); } - -export default SelectConstituenta; diff --git a/rsconcept/frontend/src/features/rsform/dialogs/DlgCstTemplate/TabArguments.tsx b/rsconcept/frontend/src/features/rsform/dialogs/DlgCstTemplate/TabArguments.tsx index eb2ec43a..e09cf2e0 100644 --- a/rsconcept/frontend/src/features/rsform/dialogs/DlgCstTemplate/TabArguments.tsx +++ b/rsconcept/frontend/src/features/rsform/dialogs/DlgCstTemplate/TabArguments.tsx @@ -29,10 +29,8 @@ function TabArguments() { const { args, onChangeArguments } = useTemplateContext(); const definition = useWatch({ control, name: 'definition_formal' }); - const [selectedCst, setSelectedCst] = useState(undefined); - const [selectedArgument, setSelectedArgument] = useState( - args.length > 0 ? args[0] : undefined - ); + const [selectedCst, setSelectedCst] = useState(null); + const [selectedArgument, setSelectedArgument] = useState(args.length > 0 ? args[0] : null); const [argumentValue, setArgumentValue] = useState(''); diff --git a/rsconcept/frontend/src/features/rsform/dialogs/DlgCstTemplate/TabTemplate.tsx b/rsconcept/frontend/src/features/rsform/dialogs/DlgCstTemplate/TabTemplate.tsx index c6e6f9d4..e3a6040d 100644 --- a/rsconcept/frontend/src/features/rsform/dialogs/DlgCstTemplate/TabTemplate.tsx +++ b/rsconcept/frontend/src/features/rsform/dialogs/DlgCstTemplate/TabTemplate.tsx @@ -23,7 +23,7 @@ function TabTemplate() { } = useTemplateContext(); const { templates } = useTemplatesSuspense(); - const { schema: templateSchema } = useRSForm({ itemID: templateID }); + const { schema: templateSchema } = useRSForm({ itemID: templateID ?? undefined }); if (!templateID) { onChangeTemplateID(templates[0].id); @@ -63,7 +63,7 @@ function TabTemplate() { className='w-[12rem]' options={templateSelector} value={templateID ? { value: templateID, label: templates.find(item => item.id == templateID)!.title } : null} - onChange={data => onChangeTemplateID(data ? data.value : undefined)} + onChange={data => onChangeTemplateID(data ? data.value : null)} /> onChangeFilterCategory(data ? templateSchema?.cstByID.get(data?.value) : undefined)} + onChange={data => onChangeFilterCategory(data ? templateSchema?.cstByID.get(data?.value) ?? null : null)} isClearable /> diff --git a/rsconcept/frontend/src/features/rsform/dialogs/DlgCstTemplate/TemplateContext.tsx b/rsconcept/frontend/src/features/rsform/dialogs/DlgCstTemplate/TemplateContext.tsx index 9f2d69dc..50fea6e7 100644 --- a/rsconcept/frontend/src/features/rsform/dialogs/DlgCstTemplate/TemplateContext.tsx +++ b/rsconcept/frontend/src/features/rsform/dialogs/DlgCstTemplate/TemplateContext.tsx @@ -15,14 +15,14 @@ import { DlgCstTemplateProps } from './DlgCstTemplate'; export interface ITemplateContext { args: IArgumentValue[]; - prototype?: IConstituenta; - templateID?: number; - filterCategory?: IConstituenta; + prototype: IConstituenta | null; + templateID: number | null; + filterCategory: IConstituenta | null; onChangeArguments: (newArgs: IArgumentValue[]) => void; onChangePrototype: (newPrototype: IConstituenta) => void; - onChangeTemplateID: (newTemplateID: number | undefined) => void; - onChangeFilterCategory: (newFilterCategory: IConstituenta | undefined) => void; + onChangeTemplateID: (newTemplateID: number | null) => void; + onChangeFilterCategory: (newFilterCategory: IConstituenta | null) => void; } const TemplateContext = createContext(null); @@ -37,10 +37,10 @@ export const useTemplateContext = () => { export const TemplateState = ({ children }: React.PropsWithChildren) => { const { schema } = useDialogsStore(state => state.props as DlgCstTemplateProps); const { setValue } = useFormContext(); - const [templateID, setTemplateID] = useState(undefined); + const [templateID, setTemplateID] = useState(null); const [args, setArguments] = useState([]); - const [prototype, setPrototype] = useState(undefined); - const [filterCategory, setFilterCategory] = useState(undefined); + const [prototype, setPrototype] = useState(null); + const [filterCategory, setFilterCategory] = useState(null); function onChangeArguments(newArgs: IArgumentValue[]) { setArguments(newArgs); @@ -70,9 +70,9 @@ export const TemplateState = ({ children }: React.PropsWithChildren) => { setValue('definition_raw', newPrototype.definition_raw); } - function onChangeTemplateID(newTemplateID: number | undefined) { + function onChangeTemplateID(newTemplateID: number | null) { setTemplateID(newTemplateID); - setPrototype(undefined); + setPrototype(null); setArguments([]); } diff --git a/rsconcept/frontend/src/features/rsform/dialogs/DlgEditReference/TabEntityReference.tsx b/rsconcept/frontend/src/features/rsform/dialogs/DlgEditReference/TabEntityReference.tsx index dc597611..3f3993cb 100644 --- a/rsconcept/frontend/src/features/rsform/dialogs/DlgEditReference/TabEntityReference.tsx +++ b/rsconcept/frontend/src/features/rsform/dialogs/DlgEditReference/TabEntityReference.tsx @@ -19,7 +19,7 @@ export function TabEntityReference() { const { setValue, control, register } = useFormContext(); const alias = useWatch({ control, name: 'entity.entity' }); - const selectedCst = schema.cstByAlias.get(alias); + const selectedCst = schema.cstByAlias.get(alias) ?? null; const term = selectedCst?.term_resolved ?? ''; function handleSelectConstituenta(cst: IConstituenta) { diff --git a/rsconcept/frontend/src/features/rsform/dialogs/DlgShowAST/DlgShowAST.tsx b/rsconcept/frontend/src/features/rsform/dialogs/DlgShowAST/DlgShowAST.tsx index c24cd0c8..cf280171 100644 --- a/rsconcept/frontend/src/features/rsform/dialogs/DlgShowAST/DlgShowAST.tsx +++ b/rsconcept/frontend/src/features/rsform/dialogs/DlgShowAST/DlgShowAST.tsx @@ -20,7 +20,7 @@ export interface DlgShowASTProps { function DlgShowAST() { const { syntaxTree, expression } = useDialogsStore(state => state.props as DlgShowASTProps); - const [hoverID, setHoverID] = useState(undefined); + const [hoverID, setHoverID] = useState(null); const hoverNode = syntaxTree.find(node => node.uid === hoverID); const [isDragging, setIsDragging] = useState(false); @@ -47,7 +47,7 @@ function DlgShowAST() { setHoverID(Number(node.id))} - onNodeLeave={() => setHoverID(undefined)} + onNodeLeave={() => setHoverID(null)} onChangeDragging={setIsDragging} /> diff --git a/rsconcept/frontend/src/features/rsform/dialogs/DlgShowAST/graph/ASTLayout.ts b/rsconcept/frontend/src/features/rsform/dialogs/DlgShowAST/graph/ASTLayout.ts index ca68f230..55f8814a 100644 --- a/rsconcept/frontend/src/features/rsform/dialogs/DlgShowAST/graph/ASTLayout.ts +++ b/rsconcept/frontend/src/features/rsform/dialogs/DlgShowAST/graph/ASTLayout.ts @@ -11,8 +11,7 @@ export function applyLayout(nodes: Node[], edges: Edge[]) { rankdir: 'TB', ranksep: 40, nodesep: 40, - ranker: 'network-simplex', - align: undefined + ranker: 'network-simplex' }); nodes.forEach(node => { dagreGraph.setNode(node.id, { width: 2 * PARAMETER.graphNodeRadius, height: 2 * PARAMETER.graphNodeRadius }); diff --git a/rsconcept/frontend/src/features/rsform/dialogs/DlgShowTypeGraph/graph/MGraphLayout.ts b/rsconcept/frontend/src/features/rsform/dialogs/DlgShowTypeGraph/graph/MGraphLayout.ts index b7f16566..03d48d14 100644 --- a/rsconcept/frontend/src/features/rsform/dialogs/DlgShowTypeGraph/graph/MGraphLayout.ts +++ b/rsconcept/frontend/src/features/rsform/dialogs/DlgShowTypeGraph/graph/MGraphLayout.ts @@ -17,8 +17,7 @@ export function applyLayout(nodes: Node[], edges: Edge[]) { rankdir: 'BT', ranksep: VERT_SEPARATION, nodesep: HOR_SEPARATION, - ranker: 'network-simplex', - align: undefined + ranker: 'network-simplex' }); nodes.forEach(node => { dagreGraph.setNode(node.id, { width: NODE_WIDTH, height: NODE_HEIGHT }); diff --git a/rsconcept/frontend/src/features/rsform/dialogs/DlgUploadRSForm.tsx b/rsconcept/frontend/src/features/rsform/dialogs/DlgUploadRSForm.tsx index 188aaf39..53c11ac0 100644 --- a/rsconcept/frontend/src/features/rsform/dialogs/DlgUploadRSForm.tsx +++ b/rsconcept/frontend/src/features/rsform/dialogs/DlgUploadRSForm.tsx @@ -17,7 +17,7 @@ function DlgUploadRSForm() { const { itemID } = useDialogsStore(state => state.props as DlgUploadRSFormProps); const { upload } = useUploadTRS(); const [loadMetadata, setLoadMetadata] = useState(false); - const [file, setFile] = useState(); + const [file, setFile] = useState(null); const handleSubmit = () => { if (file) { @@ -34,7 +34,7 @@ function DlgUploadRSForm() { if (event.target.files && event.target.files.length > 0) { setFile(event.target.files[0]); } else { - setFile(undefined); + setFile(null); } }; diff --git a/rsconcept/frontend/src/features/rsform/labels.ts b/rsconcept/frontend/src/features/rsform/labels.ts index 8eace1af..f6fd1d02 100644 --- a/rsconcept/frontend/src/features/rsform/labels.ts +++ b/rsconcept/frontend/src/features/rsform/labels.ts @@ -40,7 +40,7 @@ export function describeConstituenta(cst: IConstituenta): string { /** * Generates description for term of a given {@link IConstituenta}. */ -export function describeConstituentaTerm(cst?: IConstituenta): string { +export function describeConstituentaTerm(cst: IConstituenta | null): string { if (!cst) { return '!Конституента отсутствует!'; } @@ -61,7 +61,7 @@ export function labelConstituenta(cst: IConstituenta) { /** * Generates label for {@link IVersionInfo} of {@link IRSForm}. */ -export function labelVersion(schema?: IRSForm) { +export function labelVersion(schema: IRSForm | undefined) { const version = schema?.versions.find(ver => ver.id === schema?.version); return version ? version.version : 'актуальная'; } diff --git a/rsconcept/frontend/src/features/rsform/models/TMGraph.ts b/rsconcept/frontend/src/features/rsform/models/TMGraph.ts index d728cea9..6e597f09 100644 --- a/rsconcept/frontend/src/features/rsform/models/TMGraph.ts +++ b/rsconcept/frontend/src/features/rsform/models/TMGraph.ts @@ -122,9 +122,9 @@ export class TMGraph { this.nodeByAlias.set(alias, nodeToAnnotate); } - private processArguments(args: IArgumentInfo[]): TMGraphNode | undefined { + private processArguments(args: IArgumentInfo[]): TMGraphNode | null { if (args.length === 0) { - return undefined; + return null; } const argsNodes = args.map(argument => this.parseToNode(argument.typification)); if (args.length === 1) { @@ -133,16 +133,16 @@ export class TMGraph { return this.addCartesianNode(argsNodes.map(node => node.id)); } - private processResult(result: string): TMGraphNode | undefined { + private processResult(result: string): TMGraphNode | null { if (!result || result === PARAMETER.logicLabel) { - return undefined; + return null; } return this.parseToNode(result); } - private combineResults(result: TMGraphNode | undefined, args: TMGraphNode | undefined): TMGraphNode | undefined { + private combineResults(result: TMGraphNode | null, args: TMGraphNode | null): TMGraphNode | null { if (!result && !args) { - return undefined; + return null; } if (!result) { return this.addBooleanNode(args!.id); diff --git a/rsconcept/frontend/src/features/rsform/models/rsformAPI.ts b/rsconcept/frontend/src/features/rsform/models/rsformAPI.ts index 84c87fb7..fdf8e1ce 100644 --- a/rsconcept/frontend/src/features/rsform/models/rsformAPI.ts +++ b/rsconcept/frontend/src/features/rsform/models/rsformAPI.ts @@ -164,7 +164,7 @@ export function guessCstType(hint: string, defaultType: CstType = CstType.TERM): /** * Evaluate if {@link CstType} is basic concept. */ -export function isBasicConcept(type?: CstType): boolean { +export function isBasicConcept(type: CstType): boolean { // prettier-ignore switch (type) { case CstType.BASE: return true; @@ -175,7 +175,6 @@ export function isBasicConcept(type?: CstType): boolean { case CstType.FUNCTION: return false; case CstType.PREDICATE: return false; case CstType.THEOREM: return false; - case undefined: return false; } } diff --git a/rsconcept/frontend/src/features/rsform/pages/RSFormPage/EditorConstituenta/EditorConstituenta.tsx b/rsconcept/frontend/src/features/rsform/pages/RSFormPage/EditorConstituenta/EditorConstituenta.tsx index a8329bc2..49a7f700 100644 --- a/rsconcept/frontend/src/features/rsform/pages/RSFormPage/EditorConstituenta/EditorConstituenta.tsx +++ b/rsconcept/frontend/src/features/rsform/pages/RSFormPage/EditorConstituenta/EditorConstituenta.tsx @@ -16,7 +16,7 @@ import { useRSEdit } from '../RSEditContext'; import { ViewConstituents } from '../ViewConstituents'; import EditorControls from './EditorControls'; -import FormConstituenta from './FormConstituenta'; +import { FormConstituenta } from './FormConstituenta'; import ToolbarConstituenta from './ToolbarConstituenta'; // Threshold window width to switch layout. diff --git a/rsconcept/frontend/src/features/rsform/pages/RSFormPage/EditorConstituenta/FormConstituenta.tsx b/rsconcept/frontend/src/features/rsform/pages/RSFormPage/EditorConstituenta/FormConstituenta.tsx index 97eaa9f1..1b947a7f 100644 --- a/rsconcept/frontend/src/features/rsform/pages/RSFormPage/EditorConstituenta/FormConstituenta.tsx +++ b/rsconcept/frontend/src/features/rsform/pages/RSFormPage/EditorConstituenta/FormConstituenta.tsx @@ -23,7 +23,7 @@ import { RefsInput } from '../../../components/RefsInput'; import { labelCstTypification, labelTypification } from '../../../labels'; import { IConstituenta, IRSForm } from '../../../models/rsform'; import { isBaseSet, isBasicConcept, isFunctional } from '../../../models/rsformAPI'; -import EditorRSExpression from '../EditorRSExpression'; +import { EditorRSExpression } from '../EditorRSExpression'; interface FormConstituentaProps { id?: string; @@ -32,10 +32,10 @@ interface FormConstituentaProps { activeCst: IConstituenta; schema: IRSForm; - onOpenEdit?: (cstID: number) => void; + onOpenEdit: (cstID: number) => void; } -function FormConstituenta({ disabled, id, toggleReset, schema, activeCst, onOpenEdit }: FormConstituentaProps) { +export function FormConstituenta({ disabled, id, toggleReset, schema, activeCst, onOpenEdit }: FormConstituentaProps) { const { cstUpdate } = useCstUpdate(); const showTypification = useDialogsStore(state => state.showShowTypeGraph); const { isModified, setIsModified } = useModificationStore(); @@ -49,7 +49,7 @@ function FormConstituenta({ disabled, id, toggleReset, schema, activeCst, onOpen formState: { isDirty } } = useForm({ resolver: zodResolver(schemaCstUpdate) }); - const [localParse, setLocalParse] = useState(undefined); + const [localParse, setLocalParse] = useState(null); const typification = useMemo( () => @@ -88,7 +88,7 @@ function FormConstituenta({ disabled, id, toggleReset, schema, activeCst, onOpen } }); setForceComment(false); - setLocalParse(undefined); + setLocalParse(null); }, [activeCst, schema, toggleReset, reset]); useLayoutEffect(() => { @@ -252,5 +252,3 @@ function FormConstituenta({ disabled, id, toggleReset, schema, activeCst, onOpen ); } - -export default FormConstituenta; diff --git a/rsconcept/frontend/src/features/rsform/pages/RSFormPage/EditorConstituenta/ToolbarConstituenta.tsx b/rsconcept/frontend/src/features/rsform/pages/RSFormPage/EditorConstituenta/ToolbarConstituenta.tsx index 6dc9537d..31785340 100644 --- a/rsconcept/frontend/src/features/rsform/pages/RSFormPage/EditorConstituenta/ToolbarConstituenta.tsx +++ b/rsconcept/frontend/src/features/rsform/pages/RSFormPage/EditorConstituenta/ToolbarConstituenta.tsx @@ -32,7 +32,7 @@ import { IConstituenta } from '../../../models/rsform'; import { RSTabID, useRSEdit } from '../RSEditContext'; interface ToolbarConstituentaProps { - activeCst?: IConstituenta; + activeCst: IConstituenta | null; disabled: boolean; onSubmit: () => void; @@ -103,7 +103,9 @@ function ToolbarConstituenta({ title='Создать конституенту после данной' icon={} disabled={!controller.isContentEditable || isProcessing} - onClick={() => controller.createCst(activeCst?.cst_type, false)} + onClick={() => + activeCst ? controller.createCst(activeCst.cst_type, false) : controller.createCstDefault() + } /> void; - onOpenEdit?: (cstID: number) => void; + onChangeLocalParse: (typification: IExpressionParseDTO) => void; + onOpenEdit: (cstID: number) => void; onShowTypeGraph: (event: CProps.EventMouse) => void; } -function EditorRSExpression({ +export function EditorRSExpression({ activeCst, disabled, value, @@ -61,7 +60,7 @@ function EditorRSExpression({ const [isModified, setIsModified] = useState(false); const rsInput = useRef(null); - const [parseData, setParseData] = useState(undefined); + const [parseData, setParseData] = useState(null); const isProcessing = useMutatingRSForm(); const showControls = usePreferencesStore(state => state.showExpressionControls); @@ -72,7 +71,7 @@ function EditorRSExpression({ function checkConstituenta( expression: string, activeCst: IConstituenta, - onSuccess?: DataCallback + onSuccess?: (data: IExpressionParseDTO) => void ) { const data: ICheckConstituentaDTO = { definition_formal: expression, @@ -87,7 +86,7 @@ function EditorRSExpression({ useEffect(() => { setIsModified(false); - setParseData(undefined); + setParseData(null); }, [activeCst, toggleReset]); function handleChange(newValue: string) { @@ -200,5 +199,3 @@ function EditorRSExpression({ ); } - -export default EditorRSExpression; diff --git a/rsconcept/frontend/src/features/rsform/pages/RSFormPage/EditorRSExpression/ParsingResult.tsx b/rsconcept/frontend/src/features/rsform/pages/RSFormPage/EditorRSExpression/ParsingResult.tsx index 9df598a5..8da84640 100644 --- a/rsconcept/frontend/src/features/rsform/pages/RSFormPage/EditorRSExpression/ParsingResult.tsx +++ b/rsconcept/frontend/src/features/rsform/pages/RSFormPage/EditorRSExpression/ParsingResult.tsx @@ -3,13 +3,13 @@ import { describeRSError } from '../../../labels'; import { getRSErrorPrefix } from '../../../models/rslangAPI'; interface ParsingResultProps { - data: IExpressionParseDTO | undefined; + data: IExpressionParseDTO | null; disabled?: boolean; isOpen: boolean; onShowError: (error: IRSErrorDescription) => void; } -function ParsingResult({ isOpen, data, disabled, onShowError }: ParsingResultProps) { +export function ParsingResult({ isOpen, data, disabled, onShowError }: ParsingResultProps) { const errorCount = data ? data.errors.reduce((total, error) => (error.isCritical ? total + 1 : total), 0) : 0; const warningsCount = data ? data.errors.length - errorCount : 0; @@ -46,5 +46,3 @@ function ParsingResult({ isOpen, data, disabled, onShowError }: ParsingResultPro ); } - -export default ParsingResult; diff --git a/rsconcept/frontend/src/features/rsform/pages/RSFormPage/EditorRSExpression/RSEditControls.tsx b/rsconcept/frontend/src/features/rsform/pages/RSFormPage/EditorRSExpression/RSEditControls.tsx index 845d288f..69bc0138 100644 --- a/rsconcept/frontend/src/features/rsform/pages/RSFormPage/EditorRSExpression/RSEditControls.tsx +++ b/rsconcept/frontend/src/features/rsform/pages/RSFormPage/EditorRSExpression/RSEditControls.tsx @@ -87,7 +87,7 @@ interface RSEditorControlsProps { onEdit: (id: TokenID, key?: string) => void; } -function RSEditorControls({ isOpen, disabled, onEdit }: RSEditorControlsProps) { +export function RSEditorControls({ isOpen, disabled, onEdit }: RSEditorControlsProps) { return (
); } - -export default RSEditorControls; diff --git a/rsconcept/frontend/src/features/rsform/pages/RSFormPage/EditorRSExpression/StatusBar.tsx b/rsconcept/frontend/src/features/rsform/pages/RSFormPage/EditorRSExpression/StatusBar.tsx index 6a5b433e..c38b0726 100644 --- a/rsconcept/frontend/src/features/rsform/pages/RSFormPage/EditorRSExpression/StatusBar.tsx +++ b/rsconcept/frontend/src/features/rsform/pages/RSFormPage/EditorRSExpression/StatusBar.tsx @@ -15,14 +15,14 @@ import { ExpressionStatus, IConstituenta } from '../../../models/rsform'; import { inferStatus } from '../../../models/rsformAPI'; interface StatusBarProps { - processing?: boolean; - isModified?: boolean; - parseData?: IExpressionParseDTO; + processing: boolean; + isModified: boolean; + parseData: IExpressionParseDTO | null; activeCst: IConstituenta; onAnalyze: () => void; } -function StatusBar({ isModified, processing, activeCst, parseData, onAnalyze }: StatusBarProps) { +export function StatusBar({ isModified, processing, activeCst, parseData, onAnalyze }: StatusBarProps) { const status = (() => { if (isModified) { return ExpressionStatus.UNKNOWN; @@ -66,5 +66,3 @@ function StatusBar({ isModified, processing, activeCst, parseData, onAnalyze }:
); } - -export default StatusBar; diff --git a/rsconcept/frontend/src/features/rsform/pages/RSFormPage/EditorRSExpression/ToolbarRSExpression.tsx b/rsconcept/frontend/src/features/rsform/pages/RSFormPage/EditorRSExpression/ToolbarRSExpression.tsx index b78a13b3..94ff6aed 100644 --- a/rsconcept/frontend/src/features/rsform/pages/RSFormPage/EditorRSExpression/ToolbarRSExpression.tsx +++ b/rsconcept/frontend/src/features/rsform/pages/RSFormPage/EditorRSExpression/ToolbarRSExpression.tsx @@ -12,7 +12,7 @@ interface ToolbarRSExpressionProps { showTypeGraph: (event: CProps.EventMouse) => void; } -function ToolbarRSExpression({ disabled, showTypeGraph, showAST }: ToolbarRSExpressionProps) { +export function ToolbarRSExpression({ disabled, showTypeGraph, showAST }: ToolbarRSExpressionProps) { const isProcessing = useMutatingRSForm(); const showControls = usePreferencesStore(state => state.showExpressionControls); const toggleControls = usePreferencesStore(state => state.toggleShowExpressionControls); @@ -39,5 +39,3 @@ function ToolbarRSExpression({ disabled, showTypeGraph, showAST }: ToolbarRSExpr ); } - -export default ToolbarRSExpression; diff --git a/rsconcept/frontend/src/features/rsform/pages/RSFormPage/EditorRSExpression/index.tsx b/rsconcept/frontend/src/features/rsform/pages/RSFormPage/EditorRSExpression/index.tsx index f9269351..0305d9a0 100644 --- a/rsconcept/frontend/src/features/rsform/pages/RSFormPage/EditorRSExpression/index.tsx +++ b/rsconcept/frontend/src/features/rsform/pages/RSFormPage/EditorRSExpression/index.tsx @@ -1 +1 @@ -export { default } from './EditorRSExpression'; +export { EditorRSExpression } from './EditorRSExpression'; diff --git a/rsconcept/frontend/src/features/rsform/pages/RSFormPage/EditorRSFormCard/ToolbarVersioning.tsx b/rsconcept/frontend/src/features/rsform/pages/RSFormPage/EditorRSFormCard/ToolbarVersioning.tsx index 821ad78a..ff023770 100644 --- a/rsconcept/frontend/src/features/rsform/pages/RSFormPage/EditorRSFormCard/ToolbarVersioning.tsx +++ b/rsconcept/frontend/src/features/rsform/pages/RSFormPage/EditorRSFormCard/ToolbarVersioning.tsx @@ -30,7 +30,7 @@ function ToolbarVersioning({ blockReload }: ToolbarVersioningProps) { if (!controller.schema.version || !window.confirm(promptText.restoreArchive)) { return; } - void versionRestore({ versionID: controller.schema.version }).then(() => controller.navigateVersion(undefined)); + void versionRestore({ versionID: controller.schema.version }).then(() => controller.navigateVersion()); } function handleCreateVersion() { @@ -50,7 +50,7 @@ function ToolbarVersioning({ blockReload }: ToolbarVersioningProps) { showEditVersions({ itemID: controller.schema.id, afterDelete: targetVersion => { - if (targetVersion === controller.activeVersion) controller.navigateVersion(undefined); + if (targetVersion === controller.activeVersion) controller.navigateVersion(); } }); } diff --git a/rsconcept/frontend/src/features/rsform/pages/RSFormPage/EditorRSList/EditorRSList.tsx b/rsconcept/frontend/src/features/rsform/pages/RSFormPage/EditorRSList/EditorRSList.tsx index d857935d..bcf5a6bd 100644 --- a/rsconcept/frontend/src/features/rsform/pages/RSFormPage/EditorRSList/EditorRSList.tsx +++ b/rsconcept/frontend/src/features/rsform/pages/RSFormPage/EditorRSList/EditorRSList.tsx @@ -100,7 +100,7 @@ function EditorRSList() { } // prettier-ignore switch (code) { - case 'Backquote': controller.createCst(undefined, false); return true; + case 'Backquote': controller.createCstDefault(); return true; case 'Digit1': controller.createCst(CstType.BASE, true); return true; case 'Digit2': controller.createCst(CstType.STRUCTURED, true); return true; @@ -150,7 +150,7 @@ function EditorRSList() { selected={rowSelection} setSelected={handleRowSelection} onEdit={controller.navigateCst} - onCreateNew={() => controller.createCst(undefined, false)} + onCreateNew={controller.createCstDefault} /> diff --git a/rsconcept/frontend/src/features/rsform/pages/RSFormPage/EditorRSList/TableRSList.tsx b/rsconcept/frontend/src/features/rsform/pages/RSFormPage/EditorRSList/TableRSList.tsx index b3970758..4c0666bb 100644 --- a/rsconcept/frontend/src/features/rsform/pages/RSFormPage/EditorRSList/TableRSList.tsx +++ b/rsconcept/frontend/src/features/rsform/pages/RSFormPage/EditorRSList/TableRSList.tsx @@ -11,7 +11,7 @@ import useWindowSize from '@/hooks/useWindowSize'; import { PARAMETER, prefixes } from '@/utils/constants'; import { truncateToSymbol } from '@/utils/utils'; -import BadgeConstituenta from '../../../components/BadgeConstituenta'; +import { BadgeConstituenta } from '../../../components/BadgeConstituenta'; import { labelCstTypification } from '../../../labels'; import { IConstituenta } from '../../../models/rsform'; diff --git a/rsconcept/frontend/src/features/rsform/pages/RSFormPage/EditorRSList/ToolbarRSList.tsx b/rsconcept/frontend/src/features/rsform/pages/RSFormPage/EditorRSList/ToolbarRSList.tsx index aad06873..346d94cf 100644 --- a/rsconcept/frontend/src/features/rsform/pages/RSFormPage/EditorRSList/ToolbarRSList.tsx +++ b/rsconcept/frontend/src/features/rsform/pages/RSFormPage/EditorRSList/ToolbarRSList.tsx @@ -96,7 +96,7 @@ export function ToolbarRSList() { titleHtml={prepareTooltip('Добавить новую конституенту...', 'Alt + `')} icon={} disabled={isProcessing} - onClick={() => controller.createCst(undefined, false)} + onClick={controller.createCstDefault} /> (undefined); + const [focusCst, setFocusCst] = useState(null); const filteredGraph = produceFilteredGraph(controller.schema, filter, focusCst); const [hidden, setHidden] = useState([]); const [isDragging, setIsDragging] = useState(false); - const [hoverID, setHoverID] = useState(undefined); + const [hoverID, setHoverID] = useState(null); const hoverCst = hoverID && controller.schema.cstByID.get(hoverID); const [hoverCstDebounced] = useDebounce(hoverCst, PARAMETER.graphPopupDelay); const [hoverLeft, setHoverLeft] = useState(true); @@ -102,7 +102,7 @@ function TGFlow() { } }); setHidden(newDismissed); - setHoverID(undefined); + setHoverID(null); }, [controller.schema, filteredGraph]); const resetNodes = useCallback(() => { @@ -227,7 +227,7 @@ function TGFlow() { if (event.key === 'Escape') { event.preventDefault(); event.stopPropagation(); - setFocusCst(undefined); + setFocusCst(null); handleSetSelected([]); return; } @@ -252,11 +252,15 @@ function TGFlow() { }, PARAMETER.graphRefreshDelay); } - function handleSetFocus(cstID: number | undefined) { - const target = cstID !== undefined ? controller.schema.cstByID.get(cstID) : cstID; - setFocusCst(prev => (prev === target ? undefined : target)); - if (target) { - controller.setSelected([]); + function handleSetFocus(cstID: number | null) { + if (cstID === null) { + setFocusCst(null); + } else { + const target = controller.schema.cstByID.get(cstID) ?? null; + setFocusCst(prev => (prev === target ? null : target)); + if (target) { + controller.setSelected([]); + } } } @@ -304,7 +308,10 @@ function TGFlow() { {!focusCst ? ( isBasicConcept(controller.schema.cstByID.get(cstID)?.cst_type)} + isCore={cstID => { + const cst = controller.schema.cstByID.get(cstID); + return !!cst && isBasicConcept(cst.cst_type); + }} isOwned={ controller.schema.inheritance.length > 0 ? cstID => !controller.schema.cstByID.get(cstID)?.is_inherited @@ -318,7 +325,7 @@ function TGFlow() { {focusCst ? ( handleSetFocus(undefined)} + reset={() => handleSetFocus(null)} showInputs={filter.focusShowInputs} showOutputs={filter.focusShowOutputs} toggleShowInputs={() => @@ -395,7 +402,7 @@ function TGFlow() { onNodeDragStart={() => setIsDragging(true)} onNodeDragStop={() => setIsDragging(false)} onNodeMouseEnter={(event, node) => handleNodeEnter(event, Number(node.id))} - onNodeMouseLeave={() => setHoverID(undefined)} + onNodeMouseLeave={() => setHoverID(null)} onNodeClick={(event, node) => handleNodeClick(event, Number(node.id))} onNodeDoubleClick={(event, node) => handleNodeDoubleClick(event, Number(node.id))} /> @@ -408,7 +415,7 @@ function TGFlow() { export default TGFlow; // ====== Internals ========= -function produceFilteredGraph(schema: IRSForm, params: GraphFilterParams, focusCst: IConstituenta | undefined) { +function produceFilteredGraph(schema: IRSForm, params: GraphFilterParams, focusCst: IConstituenta | null) { const filtered = schema.graph.clone(); const allowedTypes: CstType[] = (() => { const result: CstType[] = []; diff --git a/rsconcept/frontend/src/features/rsform/pages/RSFormPage/EditorTermGraph/graph/TGLayout.ts b/rsconcept/frontend/src/features/rsform/pages/RSFormPage/EditorTermGraph/graph/TGLayout.ts index 4b577efb..5aad616f 100644 --- a/rsconcept/frontend/src/features/rsform/pages/RSFormPage/EditorTermGraph/graph/TGLayout.ts +++ b/rsconcept/frontend/src/features/rsform/pages/RSFormPage/EditorTermGraph/graph/TGLayout.ts @@ -11,8 +11,7 @@ export function applyLayout(nodes: Node[], edges: Edge[], subLabels? rankdir: 'TB', ranksep: subLabels ? 60 : 40, nodesep: subLabels ? 100 : 20, - ranker: 'network-simplex', - align: undefined + ranker: 'network-simplex' }); nodes.forEach(node => { dagreGraph.setNode(node.id, { width: 2 * PARAMETER.graphNodeRadius, height: 2 * PARAMETER.graphNodeRadius }); diff --git a/rsconcept/frontend/src/features/rsform/pages/RSFormPage/RSEditContext.tsx b/rsconcept/frontend/src/features/rsform/pages/RSFormPage/RSEditContext.tsx index 2d8517d6..3dc61087 100644 --- a/rsconcept/frontend/src/features/rsform/pages/RSFormPage/RSEditContext.tsx +++ b/rsconcept/frontend/src/features/rsform/pages/RSFormPage/RSEditContext.tsx @@ -31,7 +31,7 @@ export enum RSTabID { export interface IRSEditContext extends ILibraryItemEditor { schema: IRSForm; selected: number[]; - activeCst?: IConstituenta; + activeCst: IConstituenta | null; activeVersion?: number; isOwned: boolean; @@ -41,7 +41,7 @@ export interface IRSEditContext extends ILibraryItemEditor { isAttachedToOSS: boolean; canDeleteSelected: boolean; - navigateVersion: (versionID: number | undefined) => void; + navigateVersion: (versionID?: number) => void; navigateRSForm: ({ tab, activeID }: { tab: RSTabID; activeID?: number }) => void; navigateCst: (cstID: number) => void; navigateOss: (ossID: number, newTab?: boolean) => void; @@ -56,7 +56,8 @@ export interface IRSEditContext extends ILibraryItemEditor { moveUp: () => void; moveDown: () => void; - createCst: (type: CstType | undefined, skipDialog: boolean, definition?: string) => void; + createCst: (type: CstType, skipDialog: boolean, definition?: string) => void; + createCstDefault: () => void; cloneCst: () => void; promptDeleteCst: () => void; promptTemplate: () => void; @@ -103,7 +104,7 @@ export const RSEditState = ({ const [selected, setSelected] = useState([]); const canDeleteSelected = selected.length > 0 && selected.every(id => !schema.cstByID.get(id)?.is_inherited); - const activeCst = selected.length === 0 ? undefined : schema.cstByID.get(selected[selected.length - 1]); + const activeCst = selected.length === 0 ? null : schema.cstByID.get(selected[selected.length - 1])!; const { cstCreate } = useCstCreate(); const { cstMove } = useCstMove(); @@ -124,7 +125,7 @@ export const RSEditState = ({ [schema, adjustRole, isOwned, user, adminMode] ); - function navigateVersion(versionID: number | undefined) { + function navigateVersion(versionID?: number) { router.push(urls.schema(schema.id, versionID)); } @@ -164,7 +165,7 @@ export const RSEditState = ({ if (!window.confirm(promptText.deleteLibraryItem)) { return; } - const ossID = schema.oss.length > 0 ? schema.oss[0].id : undefined; + const ossID = schema.oss.length > 0 ? schema.oss[0].id : null; void deleteItem(schema.id).then(() => { if (ossID) { router.push(urls.oss(ossID)); @@ -242,7 +243,7 @@ export const RSEditState = ({ }); } - function createCst(type: CstType | undefined, skipDialog: boolean, definition?: string) { + function createCst(type: CstType | null, skipDialog: boolean, definition?: string) { const targetType = type ?? activeCst?.cst_type ?? CstType.BASE; const data: ICstCreateDTO = { insert_after: activeCst?.id ?? null, @@ -286,7 +287,7 @@ export const RSEditState = ({ selected: selected, afterDelete: (schema, deleted) => { const isEmpty = deleted.length === schema.items.length; - const nextActive = isEmpty ? undefined : getNextActiveOnDelete(activeCst?.id, schema.items, deleted); + const nextActive = isEmpty ? null : getNextActiveOnDelete(activeCst?.id ?? null, schema.items, deleted); setSelected(nextActive ? [nextActive] : []); if (!nextActive) { navigateRSForm({ tab: RSTabID.CST_LIST }); @@ -338,6 +339,7 @@ export const RSEditState = ({ moveUp, moveDown, createCst, + createCstDefault: () => createCst(null, false), cloneCst, promptDeleteCst, @@ -350,18 +352,14 @@ export const RSEditState = ({ }; // ====== Internals ========= -function getNextActiveOnDelete( - activeID: number | undefined, - items: IConstituenta[], - deleted: number[] -): number | undefined { +function getNextActiveOnDelete(activeID: number | null, items: IConstituenta[], deleted: number[]): number | null { if (items.length === deleted.length) { - return undefined; + return null; } let activeIndex = items.findIndex(cst => cst.id === activeID); if (activeIndex === -1) { - return undefined; + return null; } while (activeIndex < items.length && deleted.find(id => id === items[activeIndex].id)) { diff --git a/rsconcept/frontend/src/features/rsform/pages/RSFormPage/ViewConstituents/ConstituentsSearch.tsx b/rsconcept/frontend/src/features/rsform/pages/RSFormPage/ViewConstituents/ConstituentsSearch.tsx index 786d15a4..5071c5ff 100644 --- a/rsconcept/frontend/src/features/rsform/pages/RSFormPage/ViewConstituents/ConstituentsSearch.tsx +++ b/rsconcept/frontend/src/features/rsform/pages/RSFormPage/ViewConstituents/ConstituentsSearch.tsx @@ -71,7 +71,7 @@ function applyGraphQuery(target: IRSForm, pivot: number, mode: DependencyMode): if (mode === DependencyMode.ALL) { return target.items; } - const ids: number[] | undefined = (() => { + const ids = (() => { switch (mode) { case DependencyMode.OUTPUTS: { return target.graph.nodes.get(pivot)?.outputs; @@ -86,7 +86,6 @@ function applyGraphQuery(target: IRSForm, pivot: number, mode: DependencyMode): return target.graph.expandAllInputs([pivot]); } } - return undefined; })(); if (ids) { return target.items.filter(cst => ids.find(id => id === cst.id)); diff --git a/rsconcept/frontend/src/features/rsform/pages/RSFormPage/ViewConstituents/SelectGraphFilter.tsx b/rsconcept/frontend/src/features/rsform/pages/RSFormPage/ViewConstituents/SelectGraphFilter.tsx index 15dc12e4..f7fedb2f 100644 --- a/rsconcept/frontend/src/features/rsform/pages/RSFormPage/ViewConstituents/SelectGraphFilter.tsx +++ b/rsconcept/frontend/src/features/rsform/pages/RSFormPage/ViewConstituents/SelectGraphFilter.tsx @@ -34,7 +34,7 @@ function SelectGraphFilter({ value, dense, onChange, ...restProps }: SelectGraph hideTitle={menu.isOpen} className='h-full pr-2' icon={} - text={dense || size.isSmall ? undefined : labelCstSource(value)} + text={!dense && !size.isSmall ? labelCstSource(value) : undefined} onClick={menu.toggle} /> diff --git a/rsconcept/frontend/src/features/rsform/pages/RSFormPage/ViewConstituents/TableSideConstituents.tsx b/rsconcept/frontend/src/features/rsform/pages/RSFormPage/ViewConstituents/TableSideConstituents.tsx index 5f237433..a6656064 100644 --- a/rsconcept/frontend/src/features/rsform/pages/RSFormPage/ViewConstituents/TableSideConstituents.tsx +++ b/rsconcept/frontend/src/features/rsform/pages/RSFormPage/ViewConstituents/TableSideConstituents.tsx @@ -7,7 +7,7 @@ import { NoData, TextContent } from '@/components/View'; import { APP_COLORS } from '@/styling/colors'; import { PARAMETER, prefixes } from '@/utils/constants'; -import BadgeConstituenta from '../../../components/BadgeConstituenta'; +import { BadgeConstituenta } from '../../../components/BadgeConstituenta'; import { describeConstituenta } from '../../../labels'; import { IConstituenta } from '../../../models/rsform'; @@ -15,7 +15,7 @@ const DESCRIPTION_MAX_SYMBOLS = 280; interface TableSideConstituentsProps { items: IConstituenta[]; - activeCst?: IConstituenta; + activeCst: IConstituenta | null; onOpenEdit: (cstID: number) => void; autoScroll?: boolean; maxHeight: string; @@ -54,7 +54,6 @@ function TableSideConstituents({ header: () => Имя, size: 65, minSize: 65, - footer: undefined, cell: props => ( ) @@ -81,19 +80,19 @@ function TableSideConstituents({ const conditionalRowStyles: IConditionalStyle[] = [ { - when: (cst: IConstituenta) => !!activeCst && cst.id === activeCst?.id, + when: (cst: IConstituenta) => !!activeCst && cst.id === activeCst.id, style: { backgroundColor: APP_COLORS.bgSelected } }, { - when: (cst: IConstituenta) => !!activeCst && cst.spawner === activeCst?.id && cst.id !== activeCst?.id, + when: (cst: IConstituenta) => !!activeCst && cst.spawner === activeCst.id && cst.id !== activeCst.id, style: { backgroundColor: APP_COLORS.bgOrange50 } }, { - when: (cst: IConstituenta) => activeCst?.id !== undefined && cst.spawn.includes(activeCst.id), + when: (cst: IConstituenta) => !!activeCst && cst.spawn.includes(activeCst.id), style: { backgroundColor: APP_COLORS.bgGreen50 } diff --git a/rsconcept/frontend/src/features/rsform/pages/RSFormPage/ViewConstituents/ViewConstituents.tsx b/rsconcept/frontend/src/features/rsform/pages/RSFormPage/ViewConstituents/ViewConstituents.tsx index bf128697..4c8b80ed 100644 --- a/rsconcept/frontend/src/features/rsform/pages/RSFormPage/ViewConstituents/ViewConstituents.tsx +++ b/rsconcept/frontend/src/features/rsform/pages/RSFormPage/ViewConstituents/ViewConstituents.tsx @@ -49,7 +49,7 @@ export function ViewConstituents({ isBottom, isMounted }: ViewConstituentsProps) }} > void; filter?: (userID: number) => boolean; diff --git a/rsconcept/frontend/src/stores/dialogs.ts b/rsconcept/frontend/src/stores/dialogs.ts index 1b0ffd77..efe37bbc 100644 --- a/rsconcept/frontend/src/stores/dialogs.ts +++ b/rsconcept/frontend/src/stores/dialogs.ts @@ -57,7 +57,7 @@ export interface GenericDialogProps { } interface DialogsStore { - active: DialogType | undefined; + active: DialogType | null; props: unknown; hideDialog: () => void; @@ -87,12 +87,12 @@ interface DialogsStore { } export const useDialogsStore = create()(set => ({ - active: undefined, - props: undefined, + active: null, + props: null, hideDialog: () => { set(state => { - (state.props as GenericDialogProps | undefined)?.onHide?.(); - return { active: undefined, props: undefined }; + (state.props as GenericDialogProps | null)?.onHide?.(); + return { active: null, props: null }; }); }, @@ -113,7 +113,7 @@ export const useDialogsStore = create()(set => ({ showCloneLibraryItem: props => set({ active: DialogType.CLONE_LIBRARY_ITEM, props: props }), showCreateVersion: props => set({ active: DialogType.CREATE_VERSION, props: props }), showDeleteOperation: props => set({ active: DialogType.DELETE_OPERATION, props: props }), - showGraphParams: () => set({ active: DialogType.GRAPH_PARAMETERS, props: undefined }), + showGraphParams: () => set({ active: DialogType.GRAPH_PARAMETERS, props: null }), showRelocateConstituents: props => set({ active: DialogType.RELOCATE_CONSTITUENTS, props: props }), showRenameCst: props => set({ active: DialogType.RENAME_CONSTITUENTA, props: props }), showQR: props => set({ active: DialogType.SHOW_QR_CODE, props: props }), diff --git a/rsconcept/frontend/src/stores/tooltips.ts b/rsconcept/frontend/src/stores/tooltips.ts index 38db9c18..0ddac364 100644 --- a/rsconcept/frontend/src/stores/tooltips.ts +++ b/rsconcept/frontend/src/stores/tooltips.ts @@ -3,11 +3,11 @@ import { create } from 'zustand'; import { IConstituenta } from '@/features/rsform/models/rsform'; interface TooltipsStore { - activeCst: IConstituenta | undefined; - setActiveCst: (value: IConstituenta | undefined) => void; + activeCst: IConstituenta | null; + setActiveCst: (value: IConstituenta | null) => void; } export const useTooltipsStore = create()(set => ({ - activeCst: undefined, + activeCst: null, setActiveCst: value => set({ activeCst: value }) })); diff --git a/rsconcept/frontend/src/utils/utils.ts b/rsconcept/frontend/src/utils/utils.ts index fb26491e..df7b787f 100644 --- a/rsconcept/frontend/src/utils/utils.ts +++ b/rsconcept/frontend/src/utils/utils.ts @@ -110,20 +110,20 @@ export function promptUnsaved(): boolean { } /** - * Toggle tristate flag: undefined - true - false. + * Toggle tristate flag: null - true - false. */ -export function toggleTristateFlag(prev: boolean | undefined): boolean | undefined { - if (prev === undefined) { +export function toggleTristateFlag(prev: boolean | null): boolean | null { + if (prev === null) { return true; } - return prev ? false : undefined; + return prev ? false : null; } /** * Toggle tristate color: gray - green - red . */ -export function tripleToggleColor(value: boolean | undefined): string { - if (value === undefined) { +export function tripleToggleColor(value: boolean | null): string { + if (value === null) { return 'clr-text-controls'; } return value ? 'text-ok-600' : 'text-warn-600';