From 643f43c81925fe948fec3fce2d9d1cc8564ebcb7 Mon Sep 17 00:00:00 2001 From: IRBorisov <8611739+IRBorisov@users.noreply.github.com> Date: Mon, 6 Nov 2023 18:44:14 +0300 Subject: [PATCH] Finalize templated constituents UI --- .../frontend/src/components/RSInput/index.tsx | 7 +- .../DlgConstituentaTemplate/ArgumentsTab.tsx | 12 ++-- .../dialogs/DlgConstituentaTemplate/index.tsx | 70 ++++++++++++------- rsconcept/frontend/src/models/rsform.ts | 20 +++++- 4 files changed, 73 insertions(+), 36 deletions(-) diff --git a/rsconcept/frontend/src/components/RSInput/index.tsx b/rsconcept/frontend/src/components/RSInput/index.tsx index 4e0a5f25..1cd079b7 100644 --- a/rsconcept/frontend/src/components/RSInput/index.tsx +++ b/rsconcept/frontend/src/components/RSInput/index.tsx @@ -50,12 +50,13 @@ extends Pick | undefined onChange?: (newValue: string) => void } function RSInput({ - id, label, innerref, onChange, disabled, + id, label, innerref, onChange, disabled, noTooltip, dimensions = 'w-full', ...props }: RSInputProps) { @@ -94,8 +95,8 @@ function RSInput({ EditorView.lineWrapping, RSLanguage, ccBracketMatching(darkMode), - rsHoverTooltip(schema?.items || []), - ], [darkMode, schema?.items]); + ... noTooltip ? [] : [rsHoverTooltip(schema?.items || [])], + ], [darkMode, schema?.items, noTooltip]); const handleInput = useCallback( (event: React.KeyboardEvent) => { diff --git a/rsconcept/frontend/src/dialogs/DlgConstituentaTemplate/ArgumentsTab.tsx b/rsconcept/frontend/src/dialogs/DlgConstituentaTemplate/ArgumentsTab.tsx index 8c38ffd8..d989bfd6 100644 --- a/rsconcept/frontend/src/dialogs/DlgConstituentaTemplate/ArgumentsTab.tsx +++ b/rsconcept/frontend/src/dialogs/DlgConstituentaTemplate/ArgumentsTab.tsx @@ -132,15 +132,17 @@ function ArgumentsTab({ state, schema, partialUpdate }: ArgumentsTabProps) { /> -
- {selectedArgument?.alias || 'ARG'} +
+ + {selectedArgument?.alias || 'ARG'} + = setArgumentValue(newValue)} /> ({}); - const [ argumentsData, updateArgumentsData ] = usePartialUpdate({ + const [ template, updateTemplate ] = usePartialUpdate({}); + const [ substitutes, updateSubstitutes ] = usePartialUpdate({ definition: '', arguments: [] }); - const [cstData, updateCstData] = usePartialUpdate({ + const [constituenta, updateConstituenta] = usePartialUpdate({ cst_type: CstType.TERM, insert_after: null, alias: '', @@ -45,40 +45,40 @@ function DlgConstituentaTemplate({ hideWindow, schema, onCreate }: DlgConstituen const [ activeTab, setActiveTab ] = useState(TabID.TEMPLATE); - const handleSubmit = () => onCreate(cstData); + const handleSubmit = () => onCreate(constituenta); useLayoutEffect( () => { - updateCstData({ alias: createAliasFor(cstData.cst_type, schema) }); - }, [cstData.cst_type, updateCstData, schema]); + updateConstituenta({ alias: createAliasFor(constituenta.cst_type, schema) }); + }, [constituenta.cst_type, updateConstituenta, schema]); useEffect( () => { - setValidated(validateCstAlias(cstData.alias, cstData.cst_type, schema)); - }, [cstData.alias, cstData.cst_type, schema]); + setValidated(validateCstAlias(constituenta.alias, constituenta.cst_type, schema)); + }, [constituenta.alias, constituenta.cst_type, schema]); useLayoutEffect( () => { - if (!templateData.prototype) { - updateCstData({ + if (!template.prototype) { + updateConstituenta({ definition_raw: '', definition_formal: '', term_raw: '' }); - updateArgumentsData({ + updateSubstitutes({ definition: '', arguments: [] }); } else { - updateCstData({ - cst_type: templateData.prototype.cst_type, - definition_raw: templateData.prototype.definition_raw, - definition_formal: templateData.prototype.definition_formal, - term_raw: templateData.prototype.term_raw + updateConstituenta({ + cst_type: template.prototype.cst_type, + definition_raw: template.prototype.definition_raw, + definition_formal: template.prototype.definition_formal, + term_raw: template.prototype.term_raw }); - updateArgumentsData({ - definition: templateData.prototype.definition_formal, - arguments: templateData.prototype.parse.args.map( + updateSubstitutes({ + definition: template.prototype.definition_formal, + arguments: template.prototype.parse.args.map( arg => ({ alias: arg.alias, typification: arg.typification, @@ -87,7 +87,23 @@ function DlgConstituentaTemplate({ hideWindow, schema, onCreate }: DlgConstituen ) }); } - }, [templateData.prototype, updateCstData, updateArgumentsData]); + }, [template.prototype, updateConstituenta, updateSubstitutes]); + + useLayoutEffect( + () => { + if (substitutes.arguments.length === 0 || !template.prototype) { + return; + } + const definition = substituteTemplateArgs(template.prototype.definition_formal, substitutes.arguments); + const type = inferTemplatedType(template.prototype.cst_type, substitutes.arguments); + updateConstituenta({ + cst_type: type, + definition_formal: definition, + }); + updateSubstitutes({ + definition: definition, + }); + }, [substitutes.arguments, template.prototype, updateConstituenta, updateSubstitutes]); return (
diff --git a/rsconcept/frontend/src/models/rsform.ts b/rsconcept/frontend/src/models/rsform.ts index 686a86ed..ff19c40e 100644 --- a/rsconcept/frontend/src/models/rsform.ts +++ b/rsconcept/frontend/src/models/rsform.ts @@ -3,7 +3,7 @@ import { TextMatcher } from '../utils/utils' import { ILibraryUpdateData } from './library' import { ILibraryItem } from './library' import { CstMatchMode } from './miscelanious' -import { IArgumentInfo, ParsingStatus, ValueClass } from './rslang' +import { IArgumentInfo, IArgumentValue, ParsingStatus, ValueClass } from './rslang' export enum CstType { BASE = 'basic', @@ -148,6 +148,24 @@ export function extractGlobals(expression: string): Set { return new Set(expression.match(/[XCSADFPT]\d+/g) ?? []); } +export function inferTemplatedType(templateType: CstType, args: IArgumentValue[]): CstType { + if (args.length === 0 || args.some(arg => !arg.value)) { + return templateType; + } else if (templateType === CstType.PREDICATE) { + return CstType.AXIOM; + } else { + return CstType.TERM; + } +} + +export function substituteTemplateArgs(expression: string, args: IArgumentValue[]): string { + if (args.every(arg => !arg.value)) { + return expression; + } + // TODO: figure out actual substitution + return expression; +} + export function loadRSFormData(schema: IRSFormData): IRSForm { const result = schema as IRSForm result.graph = new Graph;