diff --git a/ui/src/core/model/form.ts b/ui/src/core/model/form.ts new file mode 100644 index 0000000..380ef62 --- /dev/null +++ b/ui/src/core/model/form.ts @@ -0,0 +1,8 @@ +export enum FormType { + weights = "weights", + robotName = "robot_name", + cameraDeviceForm = "camera", + topic = "topic", + formBuilder = "formBuilder", + moveToPose = "move_to_pose", +} diff --git a/ui/src/core/model/form_builder_validation_model.tsx b/ui/src/core/model/form_builder_validation_model.tsx index f888f4e..0cf3fb8 100644 --- a/ui/src/core/model/form_builder_validation_model.tsx +++ b/ui/src/core/model/form_builder_validation_model.tsx @@ -3,56 +3,57 @@ import { BehaviorTreeBuilderStore } from "../../features/behavior_tree_builder/p import { datasetFormMockContext, datasetFormMockResult, defaultFormValue } from "../../features/dataset/dataset_model"; import { DependencyViewModel } from "./skill_model"; import { ValidationModel } from "./validation_model"; - +import { FormType } from "./form"; + export class FormBuilderValidationModel extends ValidationModel implements DependencyViewModel { - @IsNotEmpty() - @IsString() - public result: string; - @IsNotEmpty() - @IsString() - public context: string; - public form: string[]; - public output: any; - constructor(context: string, result: string, form: string[], output: string) { - super(); - this.context = context; - this.result = result; - this.form = form; - this.output = output; - } - toView = (store: BehaviorTreeBuilderStore | undefined) => <>IsFilled; - static isEmpty = (formBuilderValidationModel: FormBuilderValidationModel) => - formBuilderValidationModel.context.isEmpty() && - formBuilderValidationModel.result.isEmpty() && - formBuilderValidationModel.form.isEmpty(); - - static datasetEmpty() { - return new FormBuilderValidationModel(datasetFormMockContext, datasetFormMockResult, [], defaultFormValue); - } - static empty() { - return new FormBuilderValidationModel("", "", [], ""); - } - static emptyTest() { - return new FormBuilderValidationModel(``, ``, [], defaultFormValue); - } - static creteDataSetTest() { - return new FormBuilderValidationModel(``, scene, [], ""); - } - static vision(): FormBuilderValidationModel { - return new FormBuilderValidationModel( - `ENUM PRETRAIN = "true","false";`, - `{ + @IsNotEmpty() + @IsString() + public result: string; + @IsNotEmpty() + @IsString() + public context: string; + public form: string[]; + public output: any; + constructor(context: string, result: string, form: string[], output: string) { + super(); + this.context = context; + this.result = result; + this.form = form; + this.output = output; + } + type: FormType = FormType.formBuilder; + toView = (store: BehaviorTreeBuilderStore | undefined) => <>IsFilled; + static isEmpty = (formBuilderValidationModel: FormBuilderValidationModel) => + formBuilderValidationModel.context.isEmpty() && + formBuilderValidationModel.result.isEmpty() && + formBuilderValidationModel.form.isEmpty(); + + static datasetEmpty() { + return new FormBuilderValidationModel(datasetFormMockContext, datasetFormMockResult, [], defaultFormValue); + } + static empty() { + return new FormBuilderValidationModel("", "", [], ""); + } + static emptyTest() { + return new FormBuilderValidationModel(``, ``, [], defaultFormValue); + } + static creteDataSetTest() { + return new FormBuilderValidationModel(``, scene, [], ""); + } + static vision(): FormBuilderValidationModel { + return new FormBuilderValidationModel( + `ENUM PRETRAIN = "true","false";`, + `{ "numberOfEpochs": \${numberOfEpochs:number:10}, "selectDataset": \${:OBJECT:{"dataset": {}}, "pretrain": \${pretrain:Enum:true} }`, - [], - "" - ); - } + [], + "" + ); } - export const scene = `{ +} +export const scene = `{ "center_shell": [\${CENTER_SHELL_1:number:0}, \${CENTER_SHELL_2:number:0}, \${CENTER_SHELL_3:number:0}], "scene":\${:OBJECT:{"details": []} }`; - \ No newline at end of file diff --git a/ui/src/core/model/skill_model.ts b/ui/src/core/model/skill_model.ts index 352881b..5ef57b0 100644 --- a/ui/src/core/model/skill_model.ts +++ b/ui/src/core/model/skill_model.ts @@ -1,3 +1,5 @@ +import makeAutoObservable from "mobx-store-inheritance"; +import clone from "just-clone"; import { IsArray, IsEnum, IsNotEmpty, IsOptional, IsString, ValidateNested } from "class-validator"; import { Type } from "class-transformer"; import { ISkillView } from "../../features/behavior_tree_builder/presentation/ui/skill_tree/skill_tree"; @@ -6,8 +8,10 @@ import { Result } from "../helper/result"; import { ValidationModel } from "./validation_model"; import { ITopicModel, TopicViewModel } from "../../features/topics/topic_view_model"; import { BehaviorTreeBuilderStore } from "../../features/behavior_tree_builder/presentation/behavior_tree_builder_store"; -import makeAutoObservable from "mobx-store-inheritance"; -import clone from "just-clone"; +import { TopicDependencyViewModel } from "../../features/behavior_tree_builder/presentation/ui/forms/topics_form/topic_dependency_view_model"; +import { FormBuilderValidationModel } from "./form_builder_validation_model"; +import { FormType } from "./form"; + export interface IDependency { skills: ISkillDependency[]; } @@ -22,8 +26,6 @@ export interface ISkill { SkillPackage: ISkillPackage; Module: IModule; BTAction: IBTAction[]; - // Interface: IInterface; - // Settings: ISetting[]; } export interface IWeightsDependency { weights_name: string; @@ -40,14 +42,28 @@ export interface IParam { type: string; dependency?: DependencyViewModel; } -export class DependencyViewModel { + +abstract class IDependencyViewModel { + abstract type: FormType; +} +export class DependencyViewModel implements IDependencyViewModel { + type: FormType; static empty = () => new DependencyViewModel(); - toView = (store: BehaviorTreeBuilderStore | undefined): React.ReactNode => "string"; + toView = (store: BehaviorTreeBuilderStore | undefined): React.ReactNode => "Dependency view model error"; } export class ParamViewModel implements IParam { type: string; - @Type(() => DependencyViewModel) + @Type(() => DependencyViewModel, { + discriminator: { + property: "type", + subTypes: [ + { value: TopicDependencyViewModel, name: FormType.topic }, + { value: FormBuilderValidationModel, name: FormType.formBuilder }, + ], + }, + keepDiscriminatorProperty: true, + }) dependency: DependencyViewModel; isFilled: boolean = false; constructor(type: string, dependency: DependencyViewModel) { diff --git a/ui/src/core/ui/pages/main_page.tsx b/ui/src/core/ui/pages/main_page.tsx index 4754053..50656ad 100644 --- a/ui/src/core/ui/pages/main_page.tsx +++ b/ui/src/core/ui/pages/main_page.tsx @@ -8,7 +8,6 @@ import { SceneManagerPath } from "../../../features/scene_manager/presentation/s import { AssemblesScreenPath } from "../../../features/assembles/assembles_screen"; import { SimulationScreenPath } from "../../../features/simulations/simulations_screen"; import { EstimateScreenPath } from "../../../features/estimate/estimate_screen"; -import { BehaviorTreeBuilderPath } from "../../../features/behavior_tree_builder/presentation/behavior_tree_builder_screen"; import { CalculationInstanceScreenPath as SkillScreenPath } from "../../../features/calculation_instance/presentation/calculation_instance_screen"; import { UiBaseError } from "../../model/ui_base_error"; import { DetailsScreenPath } from "../../../features/details/details_screen"; @@ -54,7 +53,6 @@ export interface IMainPageProps { bodyChildren?: JSX.Element; panelChildren?: JSX.Element; panelStyle?: React.CSSProperties; - isLoading?: boolean; maskLoader?: boolean; error?: UiBaseError[]; diff --git a/ui/src/features/behavior_tree_builder/model/editor_view.ts b/ui/src/features/behavior_tree_builder/model/editor_view.ts index bf0aaea..aef8acd 100644 --- a/ui/src/features/behavior_tree_builder/model/editor_view.ts +++ b/ui/src/features/behavior_tree_builder/model/editor_view.ts @@ -52,16 +52,22 @@ export class BehaviorTreeBuilderModel { } public static xmlFormat = (result: string, btRootTag: string): Result => { try { - return Result.ok(xmlFormat(btRootTag.replace("${bt}", result))); + return Result.ok( + xmlFormat( + '${bt}'.replace( + "${bt}", + btRootTag.replace("${bt}", result) + ) + ) + ); } catch (error) { console.log(result); console.log(btRootTag); console.log(error); - console.log(btRootTag.replace("${bt}", result)) return Result.error(error as string); } }; - public static getNodeLabelAtId(editor: NodeEditor, id: string, skills?: Skills,) { + public static getNodeLabelAtId(editor: NodeEditor, id: string, skills?: Skills) { try { if (skills?.getSkillsNames().find((el) => el.name.isEqual(editor.getNode(id)!.label))) { return `Action ID="RbsAction" do="${skills.getSkillDo(editor.getNode(id)!.label)}" command="${ diff --git a/ui/src/features/behavior_tree_builder/presentation/behavior_tree_builder_store.tsx b/ui/src/features/behavior_tree_builder/presentation/behavior_tree_builder_store.tsx index 97e8486..88062ea 100644 --- a/ui/src/features/behavior_tree_builder/presentation/behavior_tree_builder_store.tsx +++ b/ui/src/features/behavior_tree_builder/presentation/behavior_tree_builder_store.tsx @@ -1,9 +1,9 @@ import React from "react"; +import makeAutoObservable from "mobx-store-inheritance"; +import clone from "just-clone"; import { message } from "antd"; import { NavigateFunction } from "react-router-dom"; -import makeAutoObservable from "mobx-store-inheritance"; import { v4 } from "uuid"; -import clone from "just-clone"; import { CoreError, UiDrawerFormState } from "../../../core/store/base_store"; import { BehaviorTreeBuilderModel, @@ -21,7 +21,7 @@ import { DependencyViewModel, IParam, Skills } from "../../../core/model/skill_m import { ISkillView } from "./ui/skill_tree/skill_tree"; import { BehaviorTreeViewModel } from "../model/behavior_tree_view_model"; import { UiBaseError } from "../../../core/model/ui_base_error"; -import { BehaviorTreeBuilderPath, behaviorTreeBuilderStore } from "./behavior_tree_builder_screen"; +import { behaviorTreeBuilderStore } from "./behavior_tree_builder_screen"; import { BehaviorTreeModel } from "../model/behavior_tree_model"; import { PrimitiveViewModel, SystemPrimitive } from "../model/primitive_view_model"; import { SceneAsset } from "../../../core/model/scene_asset"; @@ -149,12 +149,10 @@ export class BehaviorTreeBuilderStore extends UiDrawerFormState { - (await this.behaviorTreeBuilderHttpRepository.getActiveProjectId()) - // eslint-disable-next-line array-callback-return - .map((el) => { - this.activeProject = el.id; - this.viewModel.project = this.activeProject; - }); + (await this.behaviorTreeBuilderHttpRepository.getActiveProjectId()).map((el) => { + this.activeProject = el.id; + this.viewModel.project = this.activeProject; + }); (await this.behaviorTreeBuilderHttpRepository.getBtSkills()).fold( (model) => { this.skillTemplates = Skills.fromSkills(model); @@ -164,7 +162,6 @@ export class BehaviorTreeBuilderStore extends UiDrawerFormState console.log(e) ); diff --git a/ui/src/features/behavior_tree_builder/presentation/ui/editor/editor.tsx b/ui/src/features/behavior_tree_builder/presentation/ui/editor/editor.tsx index 72e0d2a..b11be1f 100644 --- a/ui/src/features/behavior_tree_builder/presentation/ui/editor/editor.tsx +++ b/ui/src/features/behavior_tree_builder/presentation/ui/editor/editor.tsx @@ -137,7 +137,11 @@ export async function createEditor(container: HTMLElement) { el.source.isEqual(event.id) || el.target.isEqual(event.id) ? editor.removeConnection(el.id) : null ); areaContainer.removeNodeView(event.id); + + editor.removeNode(event.id) + } + }); AreaExtensions.selectableNodes(areaContainer, AreaExtensions.selector(), { diff --git a/ui/src/features/behavior_tree_builder/presentation/ui/forms/form_builder/form_builder_form.tsx b/ui/src/features/behavior_tree_builder/presentation/ui/forms/form_builder/form_builder_form.tsx index 3ef3075..a333242 100644 --- a/ui/src/features/behavior_tree_builder/presentation/ui/forms/form_builder/form_builder_form.tsx +++ b/ui/src/features/behavior_tree_builder/presentation/ui/forms/form_builder/form_builder_form.tsx @@ -1,17 +1,17 @@ -import React, { useEffect } from "react"; +import { useEffect } from "react"; import { observer } from "mobx-react-lite"; -import { FormBuilderStore } from "./form_builder_store"; +import { Modal, message } from "antd"; +import { FormsFormBuilderStore } from "./form_builder_store"; import { IPropsForm } from "../forms"; import { useStore } from "../../../../../../core/helper/use_store"; import { isBtScreen } from "../../../behavior_tree_builder_screen"; import { CoreInput } from "../../../../../../core/ui/input/input"; import { CoreButton } from "../../../../../../core/ui/button/button"; -import { Modal, message } from "antd"; import { FormBuilder } from "../../../../../../core/ui/form_builder/form_builder"; import { FormBuilderValidationModel } from "../../../../../../core/model/form_builder_validation_model"; export const FormBuilderForm = observer((props: IPropsForm>) => { - const store = useStore(FormBuilderStore); + const store = useStore(FormsFormBuilderStore); useEffect(() => { store.initParam(isBtScreen(), props.store); }, []); diff --git a/ui/src/features/behavior_tree_builder/presentation/ui/forms/form_builder/form_builder_store.ts b/ui/src/features/behavior_tree_builder/presentation/ui/forms/form_builder/form_builder_store.ts index d40863e..65f8e69 100644 --- a/ui/src/features/behavior_tree_builder/presentation/ui/forms/form_builder/form_builder_store.ts +++ b/ui/src/features/behavior_tree_builder/presentation/ui/forms/form_builder/form_builder_store.ts @@ -3,11 +3,8 @@ import { NavigateFunction } from "react-router-dom"; import { FormState, CoreError } from "../../../../../../core/store/base_store"; import { BehaviorTreeBuilderStore } from "../../../behavior_tree_builder_store"; import { FormBuilderValidationModel } from "../../../../../../core/model/form_builder_validation_model"; - -export class FormBuilderStore extends FormState { - openModal() { - this.isModalOpen = true; - } + +export class FormsFormBuilderStore extends FormState { isBtScreen = false; isModalOpen = false; viewModel: FormBuilderValidationModel = FormBuilderValidationModel.empty(); @@ -18,6 +15,9 @@ export class FormBuilderStore extends FormState {}; init = async (navigate?: NavigateFunction | undefined) => {}; initParam = (isSkillScreen: boolean, store: BehaviorTreeBuilderStore | undefined) => { - this.isBtScreen = true; + this.isBtScreen = isSkillScreen; }; + openModal() { + this.isModalOpen = true; + } } diff --git a/ui/src/features/behavior_tree_builder/presentation/ui/forms/forms.tsx b/ui/src/features/behavior_tree_builder/presentation/ui/forms/forms.tsx index bbcf06f..43c8b1a 100644 --- a/ui/src/features/behavior_tree_builder/presentation/ui/forms/forms.tsx +++ b/ui/src/features/behavior_tree_builder/presentation/ui/forms/forms.tsx @@ -1,3 +1,4 @@ +import { FormType } from "../../../../../core/model/form"; import { FormBuilderValidationModel } from "../../../../../core/model/form_builder_validation_model"; import { DependencyViewModel } from "../../../../../core/model/skill_model"; import { BehaviorTreeBuilderStore } from "../../behavior_tree_builder_store"; @@ -15,27 +16,20 @@ export interface IForms { name: string; component: JSX.Element; } -export enum Form { - weights = "weights", - robotName = "robot_name", - cameraDeviceForm = "camera", - topic = "topic", - formBuilder = "formBuilder", - moveToPose = "move_to_pose", -} + export interface BtDependencyFormBuilder { - form: Form; + form: FormType; component?: React.ReactNode; } export const btDependencyFormBuilder = (onChange: (dependency: DependencyViewModel) => void) => [ - { form: Form.weights, component: null }, + { form: FormType.weights, component: null }, { - form: Form.topic, + form: FormType.topic, component: , }, { - form: Form.formBuilder, + form: FormType.formBuilder, component: ( ), @@ -46,6 +40,6 @@ export const forms = ( onChange: (dependency: DependencyViewModel) => void, store: BehaviorTreeBuilderStore ): IForms[] => [ - { name: Form.topic, component: }, - { name: Form.formBuilder, component: }, + { name: FormType.topic, component: }, + { name: FormType.formBuilder, component: }, ]; diff --git a/ui/src/features/behavior_tree_builder/presentation/ui/forms/topics_form/topic_dependency_view_model.tsx b/ui/src/features/behavior_tree_builder/presentation/ui/forms/topics_form/topic_dependency_view_model.tsx index d7c4dc9..a2a5d34 100644 --- a/ui/src/features/behavior_tree_builder/presentation/ui/forms/topics_form/topic_dependency_view_model.tsx +++ b/ui/src/features/behavior_tree_builder/presentation/ui/forms/topics_form/topic_dependency_view_model.tsx @@ -5,19 +5,20 @@ import { StoreTopicType } from "./topics_form_store"; import { DependencyViewModel } from "../../../../../../core/model/skill_model"; import { BehaviorTreeBuilderStore } from "../../../behavior_tree_builder_store"; import { CoreText, CoreTextType } from "../../../../../../core/ui/text/text"; - +import { FormType } from "../../../../../../core/model/form"; + export class TopicDependencyViewModel extends ValidationModel implements DependencyViewModel { @IsNotEmpty() @IsString() - type: string; + type = FormType.topic; + topicType?: string; + mode?: StoreTopicType; sid?: string; topicOut?: string; - constructor(type: string, mode: StoreTopicType) { + constructor() { super(); makeAutoObservable(this); - this.type = type; - this.mode = mode; } toView = (store: BehaviorTreeBuilderStore | undefined): React.ReactNode => { if (store && this.sid) { @@ -31,6 +32,6 @@ export class TopicDependencyViewModel extends ValidationModel implements Depende }; static empty() { - return new TopicDependencyViewModel("", StoreTopicType.specifiesDependencies); + return new TopicDependencyViewModel(); } } diff --git a/ui/src/features/behavior_tree_builder/presentation/ui/forms/topics_form/topics_form.tsx b/ui/src/features/behavior_tree_builder/presentation/ui/forms/topics_form/topics_form.tsx index b4339c1..811b955 100644 --- a/ui/src/features/behavior_tree_builder/presentation/ui/forms/topics_form/topics_form.tsx +++ b/ui/src/features/behavior_tree_builder/presentation/ui/forms/topics_form/topics_form.tsx @@ -29,8 +29,8 @@ export const TopicsForm = observer((props: IPropsForm - {match(store.type) - .with(StoreTopicType.btExecute, () => ( + {match(isBtScreen()) + .with(true, () => ( <> )) - .with(StoreTopicType.specifiesDependencies, () => ( + .with(false, () => ( <> - store.updateForm({ type: text })} /> + store.updateForm({ topicType: text })} />
{ // await this.mapOk('topics', this.cameraDeviceHttpRepository.getAllTopics()) }; - getAllTopicsMatched = () => this.topics?.filter((el) => el.type.isEqual(this.viewModel.type)); + getAllTopicsMatched = () => this.topics?.filter((el) => el.type.isEqual(this.viewModel.topicType ?? "")); + initParam = (isBtScreen: boolean, behaviorTreeBuilderStore: BehaviorTreeBuilderStore | undefined) => { isBtScreen ? (this.type = StoreTopicType.btExecute) : (this.type = StoreTopicType.specifiesDependencies); this.behaviorTreeBuilderStore = behaviorTreeBuilderStore; diff --git a/ui/src/features/skills/skills_store.ts b/ui/src/features/skills/skills_store.ts index bd4fc5c..7a48be6 100644 --- a/ui/src/features/skills/skills_store.ts +++ b/ui/src/features/skills/skills_store.ts @@ -3,9 +3,10 @@ import { UiDrawerFormState } from "../../core/store/base_store"; import { NavigateFunction } from "react-router-dom"; import { HttpError } from "../../core/repository/core_http_repository"; import { DependencyViewModel, ParamViewModel, SkillModel } from "../../core/model/skill_model"; -import { Form } from "../behavior_tree_builder/presentation/ui/forms/forms"; import { message } from "antd"; import { SkillsHttpRepository } from "./skills_http_repository"; +import { FormType } from "../../core/model/form"; + export enum DrawersSkills { newSkill = "Новый навык", } @@ -14,7 +15,7 @@ export class SkillsStore extends UiDrawerFormState { activeIndex?: number; viewModel: SkillModel = SkillModel.empty(); selectParam?: { - form: Form; + form: FormType; component?: React.ReactNode; }; skills: SkillModel[]; @@ -66,7 +67,7 @@ export class SkillsStore extends UiDrawerFormState { } ); - clickParam(el: { form: Form; component: null } | { form: Form; component: React.JSX.Element }): void { + clickParam(el: { form: FormType; component: null } | { form: FormType; component: React.JSX.Element }): void { this.selectParam = el; if (el.component === null) this.onChangeBtDependency(DependencyViewModel.empty()); }