alex find bugs
This commit is contained in:
parent
d804aa2edf
commit
4e6132a872
27 changed files with 485 additions and 296 deletions
|
@ -1,15 +1,17 @@
|
|||
import { ClassConstructor } from "class-transformer";
|
||||
import React from "react";
|
||||
import { NavigateFunction, useNavigate } from "react-router-dom";
|
||||
|
||||
interface LifeCycleStore {
|
||||
init?: () => void;
|
||||
init?: (navigate?: NavigateFunction | undefined) => void;
|
||||
dispose?: () => void;
|
||||
}
|
||||
|
||||
export const useStore = <S extends LifeCycleStore>(storeConstructor: ClassConstructor<S>) => {
|
||||
const [store] = React.useState(new storeConstructor());
|
||||
const navigate = useNavigate();
|
||||
React.useEffect(() => {
|
||||
store?.init?.();
|
||||
store?.init?.(navigate);
|
||||
return () => {
|
||||
store?.dispose?.();
|
||||
};
|
||||
|
|
58
ui/src/core/model/form_builder_validation_model.tsx
Normal file
58
ui/src/core/model/form_builder_validation_model.tsx
Normal file
|
@ -0,0 +1,58 @@
|
|||
import { IsNotEmpty, IsString } from "class-validator";
|
||||
import { BehaviorTreeBuilderStore } from "../../features/behavior_tree_builder/presentation/behavior_tree_builder_store";
|
||||
import { datasetFormMockContext, datasetFormMockResult, defaultFormValue } from "../../features/dataset/dataset_model";
|
||||
import { DependencyViewModel } from "./skill_model";
|
||||
import { ValidationModel } from "./validation_model";
|
||||
|
||||
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";`,
|
||||
`{
|
||||
"numberOfEpochs": \${numberOfEpochs:number:10},
|
||||
"selectDataset": \${<SelectDataset/>:OBJECT:{"dataset": {}},
|
||||
"pretrain": \${pretrain:Enum<PRETRAIN>:true}
|
||||
}`,
|
||||
[],
|
||||
""
|
||||
);
|
||||
}
|
||||
}
|
||||
export const scene = `{
|
||||
"center_shell": [\${CENTER_SHELL_1:number:0}, \${CENTER_SHELL_2:number:0}, \${CENTER_SHELL_3:number:0}],
|
||||
"scene":\${<SelectScene/>:OBJECT:{"details": []}
|
||||
}`;
|
||||
|
|
@ -70,9 +70,7 @@ export class BtActionViewModel extends ValidationModel implements IBTAction {
|
|||
@IsNotEmpty()
|
||||
@IsString()
|
||||
name: string;
|
||||
@IsNotEmpty()
|
||||
@IsString()
|
||||
format: string;
|
||||
|
||||
@IsNotEmpty()
|
||||
@IsString()
|
||||
type: string;
|
||||
|
@ -84,16 +82,15 @@ export class BtActionViewModel extends ValidationModel implements IBTAction {
|
|||
@IsNotEmpty()
|
||||
@IsEnum(BtAction)
|
||||
typeAction: BtAction;
|
||||
constructor(name: string, format: string, type: string, param: IParam[], result: string[], typeAction: BtAction) {
|
||||
constructor(name: string, type: string, param: IParam[], result: string[], typeAction: BtAction) {
|
||||
super();
|
||||
this.name = name;
|
||||
this.format = format;
|
||||
this.type = type;
|
||||
this.param = param;
|
||||
this.result = result;
|
||||
this.typeAction = typeAction;
|
||||
}
|
||||
static empty = () => new BtActionViewModel("", "", "", [], [], BtAction.ACTION);
|
||||
static empty = () => new BtActionViewModel("", "", [], [], BtAction.ACTION);
|
||||
public validParam = (type: string) => this.param.someR((param) => param.type === type);
|
||||
}
|
||||
export interface IInterface {
|
||||
|
@ -228,6 +225,8 @@ export class SkillModel extends ValidationModel implements ISkill {
|
|||
@ValidateNested()
|
||||
@Type(() => Module)
|
||||
Module: IModule;
|
||||
@IsNotEmpty()
|
||||
@IsArray()
|
||||
@Type(() => BtActionViewModel)
|
||||
BTAction: BtActionViewModel[];
|
||||
topicsOut: TopicViewModel[] = [];
|
||||
|
@ -337,7 +336,7 @@ export class Skills {
|
|||
toSkillView = (): ISkillView[] =>
|
||||
this.skills.map((el) => {
|
||||
return {
|
||||
name: el.SkillPackage.name,
|
||||
name: el.Module.name,
|
||||
children: el.BTAction.map((act) => {
|
||||
return { name: act.name, uuid: v4() };
|
||||
}),
|
||||
|
@ -487,4 +486,3 @@ export class Skills {
|
|||
() => Result.error(false)
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -18,6 +18,7 @@ import { DigitalTwinsScreen, DigitalTwinsScreenPath } from "../../features/digit
|
|||
import { TopicsScreen, TopicsScreenPath } from "../../features/topics/topics_screen";
|
||||
import { SkillsScreen, SkillsScreenPath } from "../../features/skills/skills_screen";
|
||||
import { CalculationsTemplateScreenPath } from "../../features/calculations_template/calculations_template_screen";
|
||||
import { BehaviorTreeManagerScreen, BehaviorTreeManagerScreenPath } from "../../features/behavior_tree_manager/behavior_tree_manager_screen";
|
||||
|
||||
const idURL = ":id";
|
||||
export const router = createBrowserRouter([
|
||||
|
@ -85,4 +86,8 @@ export const router = createBrowserRouter([
|
|||
path: CalculationsTemplateScreenPath,
|
||||
element: <CalculationInstanceScreen />,
|
||||
},
|
||||
{
|
||||
path: BehaviorTreeManagerScreenPath,
|
||||
element: <BehaviorTreeManagerScreen />,
|
||||
},
|
||||
]);
|
||||
|
|
|
@ -2,12 +2,12 @@ import * as React from "react";
|
|||
import { FormViewModel, InputBuilderViewModel, InputType } from "./form_view_model";
|
||||
import { observer } from "mobx-react-lite";
|
||||
import { FormBuilderStore } from "./form_builder_store";
|
||||
import { FormBuilderValidationModel } from "../../../features/dataset/dataset_model";
|
||||
import { CoreSelect } from "../select/select";
|
||||
import { CoreSelect } from "../select/select";
|
||||
import { CoreInput } from "../input/input";
|
||||
import { Icon } from "../icons/icons";
|
||||
import { CoreText, CoreTextType } from "../text/text";
|
||||
import { getFormBuilderComponents } from "./forms/form_builder_components";
|
||||
import { FormBuilderValidationModel } from "../../model/form_builder_validation_model";
|
||||
|
||||
export interface IFormBuilder {
|
||||
formBuilder: FormBuilderValidationModel;
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import { makeAutoObservable } from "mobx";
|
||||
import { FormViewModel } from "./form_view_model";
|
||||
import { TypedEvent } from "../../helper/typed_event";
|
||||
import { FormBuilderValidationModel } from "../../../features/dataset/dataset_model";
|
||||
|
||||
import { FormBuilderValidationModel } from "../../model/form_builder_validation_model";
|
||||
|
||||
export class ChangerForm extends TypedEvent<FormBuilderValidationModel | undefined> {}
|
||||
|
||||
export class FormBuilderStore {
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import { makeAutoObservable, observable } from "mobx";
|
||||
import { Result } from "../../helper/result";
|
||||
import { v4 as uuidv4 } from "uuid";
|
||||
import { FormBuilderValidationModel } from "../../../features/dataset/dataset_model";
|
||||
|
||||
import { FormBuilderValidationModel } from "../../model/form_builder_validation_model";
|
||||
|
||||
export enum InputType {
|
||||
NUMBER = "number",
|
||||
STRING = "string",
|
||||
|
|
|
@ -14,6 +14,7 @@ interface IInputProps extends IStyle {
|
|||
validation?: (value: string) => boolean;
|
||||
error?: string;
|
||||
type?: CoreInputType;
|
||||
trim?: boolean;
|
||||
}
|
||||
|
||||
export const CoreInput = (props: IInputProps) => {
|
||||
|
@ -49,7 +50,7 @@ export const CoreInput = (props: IInputProps) => {
|
|||
<div
|
||||
ref={ref}
|
||||
contentEditable={true}
|
||||
style={{
|
||||
style={{
|
||||
backgroundColor: "#00008000",
|
||||
border: 1,
|
||||
fontSize: isSmall ? 12 : 16,
|
||||
|
@ -63,10 +64,13 @@ export const CoreInput = (props: IInputProps) => {
|
|||
top: isSmall ? -8 : undefined,
|
||||
}}
|
||||
onInput={(e) => {
|
||||
const val = e.currentTarget.innerText;
|
||||
let val = e.currentTarget.innerText;
|
||||
|
||||
setValue(val);
|
||||
if (val) {
|
||||
if (props.trim) {
|
||||
val = val.trim().replaceAll("\n", "");
|
||||
}
|
||||
if (props.validation !== undefined && props.validation(val) && props.onChange) {
|
||||
props.onChange(val);
|
||||
return;
|
||||
|
|
|
@ -5,10 +5,11 @@ import { CoreText, CoreTextType, FontType } from "../text/text";
|
|||
interface InputV2Props {
|
||||
label: string;
|
||||
value?: string;
|
||||
trim?: boolean;
|
||||
height?: number;
|
||||
onChange?: (text: string) => void;
|
||||
}
|
||||
export const InputV2: React.FC<InputV2Props> = ({ label, height, value, onChange }) => {
|
||||
export const InputV2: React.FC<InputV2Props> = ({ label, height, value, onChange, trim }) => {
|
||||
return (
|
||||
<div
|
||||
style={{
|
||||
|
@ -29,7 +30,9 @@ export const InputV2: React.FC<InputV2Props> = ({ label, height, value, onChange
|
|||
/>
|
||||
<CoreText
|
||||
onChange={(text) => {
|
||||
if (onChange) onChange(text);
|
||||
let result = text;
|
||||
if (trim) result = result.trim().replaceAll("\n", "");
|
||||
if (onChange) onChange(result);
|
||||
}}
|
||||
style={{
|
||||
backgroundColor: themeStore.theme.surfaceContainerHighest,
|
||||
|
|
|
@ -15,7 +15,6 @@ export class BehaviorTreeBuilderHttpRepository extends CoreHttpRepository {
|
|||
SkillModel
|
||||
)) as unknown as Promise<Result<HttpError, SkillModel[]>>;
|
||||
};
|
||||
saveNewBt = async (model: BehaviorTreeViewModel) => this._jsonRequest(HttpMethod.POST, this.featureApi, model);
|
||||
getBtById = async (id: string): Promise<Result<HttpError, BehaviorTreeModel>> =>
|
||||
this._jsonToClassInstanceRequest<BehaviorTreeModel>(
|
||||
HttpMethod.GET,
|
||||
|
|
|
@ -2,7 +2,7 @@ import * as React from "react";
|
|||
import { useRete } from "rete-react-plugin";
|
||||
import { createEditor } from "./ui/editor/editor";
|
||||
import { SkillTree } from "./ui/skill_tree/skill_tree";
|
||||
import { BehaviorTreeBuilderStore, DrawerState, StoreUIType } from "./behavior_tree_builder_store";
|
||||
import { BehaviorTreeBuilderStore, DrawerState } from "./behavior_tree_builder_store";
|
||||
import { observer } from "mobx-react-lite";
|
||||
import { match } from "ts-pattern";
|
||||
import { Icon } from "../../../core/ui/icons/icons";
|
||||
|
@ -51,179 +51,97 @@ export const BehaviorTreeBuilderScreen = observer(() => {
|
|||
const domReact: DOMReact = ref.current.getBoundingClientRect();
|
||||
store.dragZoneSetOffset(0, domReact.y, domReact.width, domReact.height);
|
||||
}
|
||||
}, [store.type]);
|
||||
}, [ref.current]);
|
||||
|
||||
React.useEffect(() => {
|
||||
store.init(navigate).then(() => {
|
||||
store.initParam(id).then(() => {});
|
||||
store.initParam(id);
|
||||
});
|
||||
return () => {
|
||||
store.dispose();
|
||||
};
|
||||
}, [id, navigate, ref, store]);
|
||||
}, []);
|
||||
return (
|
||||
<MainPageV2
|
||||
rightChild={
|
||||
<>
|
||||
{match(store.type)
|
||||
.with(StoreUIType.ViewBehaviorTree, () => (
|
||||
<div
|
||||
style={{
|
||||
width: "100%",
|
||||
display: "flex",
|
||||
flexDirection: "row",
|
||||
justifyContent: "end",
|
||||
alignItems: "center",
|
||||
}}
|
||||
>
|
||||
<ButtonV2 style={{ height: 40 }} onClick={() => {}} text="Запуск" textColor={themeStore.theme.black} />
|
||||
<div style={{ width: 10 }} />
|
||||
<ButtonV2
|
||||
style={{ height: 40 }}
|
||||
onClick={() => {}}
|
||||
text="Стоп"
|
||||
type={ButtonV2Type.empty}
|
||||
textColor={themeStore.theme.greenWhite}
|
||||
/>
|
||||
<div style={{ width: 10 }} />
|
||||
<div
|
||||
style={{
|
||||
backgroundColor: store.isNeedSaveBtn ? themeStore.theme.greenWhite : undefined,
|
||||
height: 40,
|
||||
textAlign: "center",
|
||||
alignContent: "center",
|
||||
width: 40,
|
||||
borderRadius: 100,
|
||||
}}
|
||||
>
|
||||
{store.isNeedSaveBtn ? (
|
||||
<Icon style={{ height: 21 }} onClick={() => store.onClickSaveBehaviorTree()} type="Floppy" />
|
||||
) : undefined}
|
||||
</div>
|
||||
</div>
|
||||
))
|
||||
.with(StoreUIType.SelectBehaviorTree, () => <></>)
|
||||
.otherwise(() => (
|
||||
<></>
|
||||
))}
|
||||
<div
|
||||
style={{
|
||||
width: "100%",
|
||||
display: "flex",
|
||||
flexDirection: "row",
|
||||
justifyContent: "end",
|
||||
alignItems: "center",
|
||||
}}
|
||||
>
|
||||
<ButtonV2 style={{ height: 40 }} onClick={() => {}} text="Запуск" textColor={themeStore.theme.black} />
|
||||
<div style={{ width: 10 }} />
|
||||
<ButtonV2
|
||||
style={{ height: 40 }}
|
||||
onClick={() => {}}
|
||||
text="Стоп"
|
||||
type={ButtonV2Type.empty}
|
||||
textColor={themeStore.theme.greenWhite}
|
||||
/>
|
||||
<div style={{ width: 10 }} />
|
||||
<div
|
||||
style={{
|
||||
backgroundColor: store.isNeedSaveBtn ? themeStore.theme.greenWhite : undefined,
|
||||
height: 40,
|
||||
textAlign: "center",
|
||||
alignContent: "center",
|
||||
width: 40,
|
||||
borderRadius: 100,
|
||||
}}
|
||||
>
|
||||
{store.isNeedSaveBtn ? (
|
||||
<Icon style={{ height: 21 }} onClick={() => store.onClickSaveBehaviorTree()} type="Floppy" />
|
||||
) : undefined}
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
}
|
||||
style={{ position: "absolute", height: "100%", overflow: "hidden" }}
|
||||
bgColor={themeStore.theme.black}
|
||||
children={
|
||||
<>
|
||||
{match(store.type)
|
||||
.with(StoreUIType.ViewBehaviorTree, () => (
|
||||
<>
|
||||
<div
|
||||
style={{
|
||||
height: "100%",
|
||||
width: 300,
|
||||
zIndex: 10,
|
||||
position: "absolute",
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
justifyContent: "space-between",
|
||||
backgroundColor: themeStore.theme.surfaceContainerLow,
|
||||
}}
|
||||
>
|
||||
<div style={{ margin: 20 }}>
|
||||
<div style={{ height: 58, alignContent: "center" }}>
|
||||
<CoreText
|
||||
text="Поведение"
|
||||
type={CoreTextType.mediumV2}
|
||||
color={themeStore.theme.onSurfaceVariant}
|
||||
style={{ marginLeft: 20 }}
|
||||
/>
|
||||
<div style={{ width: "100%", height: 1, backgroundColor: themeStore.theme.outlineVariant }} />
|
||||
</div>
|
||||
{store.skillTemplates ? <SkillTree skills={store.skillTree} dragEnd={store.dragEnd} /> : null}
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
ref={ref}
|
||||
className="dotted"
|
||||
style={{
|
||||
width: "100%",
|
||||
height: "100%",
|
||||
backgroundSize: "20px 20px",
|
||||
}}
|
||||
/>
|
||||
</>
|
||||
))
|
||||
.with(StoreUIType.SelectBehaviorTree, () => (
|
||||
<div style={{ height: "100%", overflowY: "auto", overflowX: "hidden" }}>
|
||||
<div style={{ height: 20 }} />
|
||||
<ButtonV2
|
||||
icon={<Icon type={"Plus"} style={{ alignSelf: "center", marginLeft: 10, marginRight: 10 }} />}
|
||||
text="СОЗДАТЬ ДЕРЕВО ПОВЕДЕНИЯ"
|
||||
onClick={() => store.modalShow()}
|
||||
/>
|
||||
<div style={{ height: 50 }} />
|
||||
|
||||
<div style={{ display: "inline-grid", gridTemplateColumns: "1fr 1fr 1fr", width: "100%" }}>
|
||||
{store.btTreeModels?.map((el, index) => (
|
||||
<CoreCard
|
||||
key={index}
|
||||
clickDeleteIcon={() => store.deleteBt(el._id)}
|
||||
clickGoToIcon={() => store.goToBt(el._id)}
|
||||
descriptionMiddle={el.description}
|
||||
descriptionTop={el.name}
|
||||
date={el.unixTime}
|
||||
/>
|
||||
))}
|
||||
<>
|
||||
<div
|
||||
style={{
|
||||
height: "100%",
|
||||
width: 300,
|
||||
zIndex: 10,
|
||||
position: "absolute",
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
justifyContent: "space-between",
|
||||
backgroundColor: themeStore.theme.surfaceContainerLow,
|
||||
}}
|
||||
>
|
||||
<div style={{ margin: 20 }}>
|
||||
<div style={{ height: 58, alignContent: "center" }}>
|
||||
<CoreText
|
||||
text="Поведение"
|
||||
type={CoreTextType.mediumV2}
|
||||
color={themeStore.theme.onSurfaceVariant}
|
||||
style={{ marginLeft: 20 }}
|
||||
/>
|
||||
<div style={{ width: "100%", height: 1, backgroundColor: themeStore.theme.outlineVariant }} />
|
||||
</div>
|
||||
{store.skillTemplates ? <SkillTree skills={store.skillTree} dragEnd={store.dragEnd} /> : null}
|
||||
</div>
|
||||
))
|
||||
.otherwise(() => (
|
||||
<></>
|
||||
))}
|
||||
<CoreModal
|
||||
isOpen={store.isModalOpen}
|
||||
onClose={() => store.modalCancel()}
|
||||
children={
|
||||
<>
|
||||
<div style={{ height: 30 }} />
|
||||
<CoreText
|
||||
text="Создание дерева поведения"
|
||||
type={CoreTextType.header}
|
||||
color={themeStore.theme.white}
|
||||
style={{ textAlignLast: "center" }}
|
||||
/>
|
||||
<div style={{ height: 30 }} />
|
||||
<div
|
||||
style={{
|
||||
height: 1,
|
||||
width: "calc(100% - 30px)",
|
||||
backgroundColor: themeStore.theme.outlineVariant,
|
||||
}}
|
||||
/>
|
||||
<div style={{ height: 20 }} />
|
||||
<InputV2 label={"Название"} onChange={(text) => store.updateForm({ name: text })} />
|
||||
<div style={{ height: 20 }} />
|
||||
<InputV2 label={"Описание"} onChange={(text) => store.updateForm({ description: text })} />
|
||||
<div style={{ height: 20 }} />
|
||||
<SelectV2
|
||||
items={store.scenes?.map((el) => ({ name: el.name, value: el._id })) ?? []}
|
||||
initialValue={""}
|
||||
label={"Сцена"}
|
||||
onChange={(value: string) => store.updateForm({ sceneId: value })}
|
||||
/>
|
||||
<div style={{ height: 30 }} />
|
||||
<div
|
||||
style={{
|
||||
height: 1,
|
||||
width: "calc(100% - 30px)",
|
||||
backgroundColor: themeStore.theme.outlineVariant,
|
||||
}}
|
||||
/>
|
||||
<div style={{ display: "flex", paddingTop: 20, justifyContent: "center" }}>
|
||||
<ButtonV2 text="Сохранить" onClick={() => store.saveNewBt()} type={ButtonV2Type.default} />
|
||||
<div style={{ width: 20 }} />
|
||||
<ButtonV2 text="Отменить" onClick={() => store.modalCancel()} type={ButtonV2Type.default} />
|
||||
</div>
|
||||
</>
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
ref={ref}
|
||||
className="dotted"
|
||||
style={{
|
||||
width: "100%",
|
||||
height: "100%",
|
||||
backgroundSize: "20px 20px",
|
||||
}}
|
||||
/>
|
||||
</>
|
||||
|
||||
<DrawerV2
|
||||
title={store.titleDrawer}
|
||||
onClose={() => store.editDrawer(DrawerState.editThreadBehaviorTree, false)}
|
||||
|
|
|
@ -24,7 +24,6 @@ import { UiBaseError } from "../../../core/model/ui_base_error";
|
|||
import { BehaviorTreeBuilderPath, behaviorTreeBuilderStore } from "./behavior_tree_builder_screen";
|
||||
import { BehaviorTreeModel } from "../model/behavior_tree_model";
|
||||
import { PrimitiveViewModel, SystemPrimitive } from "../model/primitive_view_model";
|
||||
import { SceneModel } from "../../scene_manager/model/scene_model";
|
||||
import { SceneAsset } from "../../../core/model/scene_asset";
|
||||
import { themeStore } from "../../..";
|
||||
|
||||
|
@ -36,20 +35,12 @@ interface I2DArea {
|
|||
}
|
||||
|
||||
export enum DrawerState {
|
||||
newBehaviorTree = "Новое дерево поведения",
|
||||
editThreadBehaviorTree = "Редактирование",
|
||||
}
|
||||
|
||||
export enum StoreUIType {
|
||||
SelectBehaviorTree,
|
||||
ViewBehaviorTree,
|
||||
}
|
||||
|
||||
export class BehaviorTreeBuilderStore extends UiDrawerFormState<BehaviorTreeViewModel, CoreError> {
|
||||
type: StoreUIType = StoreUIType.ViewBehaviorTree;
|
||||
sceneAsset?: SceneAsset;
|
||||
viewModel: BehaviorTreeViewModel = BehaviorTreeViewModel.empty();
|
||||
scenes?: SceneModel[];
|
||||
behaviorTreeModel: BehaviorTreeModel = BehaviorTreeModel.empty();
|
||||
skillTemplates: Skills = Skills.empty();
|
||||
filledOutTemplates: Skills = Skills.empty();
|
||||
|
@ -68,7 +59,6 @@ export class BehaviorTreeBuilderStore extends UiDrawerFormState<BehaviorTreeView
|
|||
editor?: NodeEditor<Schemes>;
|
||||
areaPlugin?: AreaPlugin<Schemes, AreaExtra>;
|
||||
nodeUpdateObserver?: NodeRerenderObserver;
|
||||
isModalOpen: boolean = false;
|
||||
primitiveViewModel: PrimitiveViewModel;
|
||||
skillTree: ISkillView = {
|
||||
name: "",
|
||||
|
@ -144,7 +134,20 @@ export class BehaviorTreeBuilderStore extends UiDrawerFormState<BehaviorTreeView
|
|||
}
|
||||
}
|
||||
};
|
||||
dispose(): void {
|
||||
this.sceneAsset = undefined;
|
||||
this.behaviorTreeModel = BehaviorTreeModel.empty();
|
||||
this.skillTemplates = Skills.empty();
|
||||
this.filledOutTemplates = Skills.empty();
|
||||
this.area = undefined;
|
||||
this.reteForceUpdateObserver = undefined;
|
||||
this.btTreeModels = [];
|
||||
|
||||
this.nodeBehaviorTree = [];
|
||||
this.editor = undefined;
|
||||
this.areaPlugin = undefined;
|
||||
this.nodeUpdateObserver = undefined;
|
||||
}
|
||||
async init(navigate: NavigateFunction): Promise<void> {
|
||||
(await this.behaviorTreeBuilderHttpRepository.getActiveProjectId())
|
||||
// eslint-disable-next-line array-callback-return
|
||||
|
@ -180,16 +183,13 @@ export class BehaviorTreeBuilderStore extends UiDrawerFormState<BehaviorTreeView
|
|||
|
||||
await this.mapOk("sceneAsset", this.behaviorTreeBuilderHttpRepository.getSceneAsset(model.sceneId));
|
||||
this.isLoading = false;
|
||||
|
||||
this.reteForceUpdateObserver?.emit("");
|
||||
this.type = StoreUIType.ViewBehaviorTree;
|
||||
},
|
||||
async () => {
|
||||
this.errors.push(new UiBaseError(`не найдено дерево с id:${id}`));
|
||||
}
|
||||
);
|
||||
} else {
|
||||
this.type = StoreUIType.SelectBehaviorTree;
|
||||
await this.mapOk("scenes", this.behaviorTreeBuilderHttpRepository.getAllScenes());
|
||||
}
|
||||
};
|
||||
dragZoneSetOffset(offsetTop: number, offsetWidth: number, width: number, height: number) {
|
||||
|
@ -211,7 +211,7 @@ export class BehaviorTreeBuilderStore extends UiDrawerFormState<BehaviorTreeView
|
|||
)
|
||||
).fold(
|
||||
(xml) => {
|
||||
console.log(xml)
|
||||
console.log(xml);
|
||||
this.behaviorTreeModel.skills = this.filledOutTemplates;
|
||||
this.behaviorTreeModel.scene = NodeBehaviorTree.fromReteScene(
|
||||
this.editor as NodeEditor<Schemes>,
|
||||
|
@ -356,29 +356,4 @@ export class BehaviorTreeBuilderStore extends UiDrawerFormState<BehaviorTreeView
|
|||
return this.filledOutTemplates.getCssAtLabel(label);
|
||||
}
|
||||
changeSceneViewModel = (text: string) => {};
|
||||
modalShow = () => {
|
||||
this.isModalOpen = true;
|
||||
};
|
||||
|
||||
modalCancel = () => {
|
||||
this.isModalOpen = false;
|
||||
};
|
||||
deleteBt = async (id: string) => (
|
||||
await this.behaviorTreeBuilderHttpRepository.deleteBt(id),
|
||||
await this.mapOk("btTreeModels", this.behaviorTreeBuilderHttpRepository.getAllBtInstances())
|
||||
);
|
||||
saveNewBt = async () =>
|
||||
(await this.viewModel.valid<BehaviorTreeViewModel>()).fold(
|
||||
async (model) => {
|
||||
await this.messageHttp(this.behaviorTreeBuilderHttpRepository.saveNewBt(model), {
|
||||
successMessage: "Новое дерево создано",
|
||||
});
|
||||
await this.mapOk("btTreeModels", this.behaviorTreeBuilderHttpRepository.getAllBtInstances());
|
||||
this.modalCancel();
|
||||
},
|
||||
async (error) => message.error(error)
|
||||
);
|
||||
goToBt = (id: string) => {
|
||||
if (this.navigate) this.navigate(BehaviorTreeBuilderPath(id));
|
||||
};
|
||||
}
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
import React, { useEffect } from "react";
|
||||
import { observer } from "mobx-react-lite";
|
||||
import { FormBuilderStore } 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<Partial<FormBuilderValidationModel>>) => {
|
||||
const store = useStore(FormBuilderStore);
|
||||
useEffect(() => {
|
||||
store.initParam(isBtScreen(), props.store);
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div>FormBuilder</div>
|
||||
{store.isBtScreen ? (
|
||||
<>
|
||||
<CoreInput label="Result" onChange={(text) => store.updateForm({ context: text })} />
|
||||
<CoreInput label="Context" onChange={(text) => store.updateForm({ result: text })} />
|
||||
<div style={{ width: 100 }}>
|
||||
<CoreButton text="preview" onClick={() => store.openModal()} />
|
||||
<CoreButton
|
||||
text="save"
|
||||
onClick={async () =>
|
||||
(await store.viewModel.valid<FormBuilderValidationModel>()).fold(
|
||||
(model) => props.onChange(model),
|
||||
(error) => message.error(error)
|
||||
)
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
<Modal
|
||||
destroyOnClose={true}
|
||||
open={store.isModalOpen}
|
||||
footer={null}
|
||||
closable={false}
|
||||
closeIcon={null}
|
||||
onCancel={() => {
|
||||
store.isModalOpen = false;
|
||||
}}
|
||||
>
|
||||
<FormBuilder formBuilder={store.viewModel} onChange={() => {}} />
|
||||
</Modal>
|
||||
</>
|
||||
) : (
|
||||
<></>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
});
|
|
@ -0,0 +1,23 @@
|
|||
import makeAutoObservable from "mobx-store-inheritance";
|
||||
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<FormBuilderValidationModel, CoreError> {
|
||||
openModal() {
|
||||
this.isModalOpen = true;
|
||||
}
|
||||
isBtScreen = false;
|
||||
isModalOpen = false;
|
||||
viewModel: FormBuilderValidationModel = FormBuilderValidationModel.empty();
|
||||
constructor() {
|
||||
super();
|
||||
makeAutoObservable(this);
|
||||
}
|
||||
errorHandingStrategy = (error: CoreError) => {};
|
||||
init = async (navigate?: NavigateFunction | undefined) => {};
|
||||
initParam = (isSkillScreen: boolean, store: BehaviorTreeBuilderStore | undefined) => {
|
||||
this.isBtScreen = true;
|
||||
};
|
||||
}
|
|
@ -1,11 +1,9 @@
|
|||
import { FormBuilderValidationModel } from "../../../../../core/model/form_builder_validation_model";
|
||||
import { DependencyViewModel } from "../../../../../core/model/skill_model";
|
||||
import { BehaviorTreeBuilderStore } from "../../behavior_tree_builder_store";
|
||||
import { CameraDeviceForm } from "./camera_device_form/camera_device_form_form";
|
||||
import { MoveToPose } from "./move_to_pose/move_to_pose_form";
|
||||
import { RobotDeviceForm } from "./robot_device_form/robot_device_form_form";
|
||||
import { BehaviorTreeBuilderStore } from "../../behavior_tree_builder_store";
|
||||
import { FormBuilderForm } from "./form_builder/form_builder_form";
|
||||
import { TopicDependencyViewModel } from "./topics_form/topic_dependency_view_model";
|
||||
import { TopicsForm } from "./topics_form/topics_form";
|
||||
import { WeightsForm } from "./weights_form/weights_form";
|
||||
|
||||
export interface IPropsForm<T> {
|
||||
dependency: T;
|
||||
|
@ -22,6 +20,7 @@ export enum Form {
|
|||
robotName = "robot_name",
|
||||
cameraDeviceForm = "camera",
|
||||
topic = "topic",
|
||||
formBuilder = "formBuilder",
|
||||
moveToPose = "move_to_pose",
|
||||
}
|
||||
export interface BtDependencyFormBuilder {
|
||||
|
@ -35,15 +34,18 @@ export const btDependencyFormBuilder = (onChange: (dependency: DependencyViewMod
|
|||
form: Form.topic,
|
||||
component: <TopicsForm store={undefined} dependency={TopicDependencyViewModel.empty()} onChange={onChange} />,
|
||||
},
|
||||
{
|
||||
form: Form.formBuilder,
|
||||
component: (
|
||||
<FormBuilderForm store={undefined} dependency={FormBuilderValidationModel.empty()} onChange={onChange} />
|
||||
),
|
||||
},
|
||||
];
|
||||
export const forms = (
|
||||
props: any,
|
||||
onChange: (dependency: DependencyViewModel) => void,
|
||||
store: BehaviorTreeBuilderStore
|
||||
): IForms[] => [
|
||||
// { name: Form.weights, component: <WeightsForm dependency={props} onChange={onChange} /> },
|
||||
// { name: Form.robotName, component: <RobotDeviceForm store={store} dependency={props} onChange={onChange} /> },
|
||||
// { name: Form.cameraDeviceForm, component: <CameraDeviceForm store={store} dependency={props} onChange={onChange} /> },
|
||||
{ name: Form.topic, component: <TopicsForm store={store} dependency={props} onChange={onChange} /> },
|
||||
// { name: Form.moveToPose, component: <MoveToPose store={store} dependency={props} onChange={onChange} /> },
|
||||
{ name: Form.formBuilder, component: <FormBuilderForm store={store} dependency={props} onChange={onChange} /> },
|
||||
];
|
||||
|
|
|
@ -22,7 +22,7 @@ export class TopicDependencyViewModel extends ValidationModel implements Depende
|
|||
toView = (store: BehaviorTreeBuilderStore | undefined): React.ReactNode => {
|
||||
if (store && this.sid) {
|
||||
if (store.filledOutTemplates.topicsStack.some((el) => el.sid?.isEqual(this.sid ?? ""))) {
|
||||
return <CoreText type={CoreTextType.header} text={this.topicOut} color="red" />;
|
||||
return <div style={{ color: "white" }}>{this.topicOut}</div>;
|
||||
} else {
|
||||
return <CoreText type={CoreTextType.header} text="Error" color="red" />;
|
||||
}
|
||||
|
|
|
@ -33,7 +33,7 @@ export const TopicsForm = observer((props: IPropsForm<Partial<TopicDependencyVie
|
|||
.with(StoreTopicType.btExecute, () => (
|
||||
<>
|
||||
<CoreText
|
||||
text={"Выберите тип топика"}
|
||||
text={"Выберите топик"}
|
||||
type={CoreTextType.header}
|
||||
style={{ padding: 10 }}
|
||||
color={themeStore.theme.darkOnSurfaceVariant}
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
import { CoreHttpRepository, HttpMethod } from "../../core/repository/core_http_repository";
|
||||
import { BehaviorTreeModel } from "../behavior_tree_builder/model/behavior_tree_model";
|
||||
import { BehaviorTreeViewModel } from "../behavior_tree_builder/model/behavior_tree_view_model";
|
||||
|
||||
export class BehaviorTreeManagerHttpRepository extends CoreHttpRepository {
|
||||
featureApi = `/behavior/trees`;
|
||||
deleteBt = (id: string) => this._jsonRequest(HttpMethod.DELETE, `${this.featureApi}?id=${id}`);
|
||||
saveNewBt = async (model: BehaviorTreeViewModel) => this._jsonRequest(HttpMethod.POST, this.featureApi, model);
|
||||
getAllBtInstances = async () => this._jsonRequest<BehaviorTreeModel[]>(HttpMethod.GET, this.featureApi);
|
||||
}
|
|
@ -0,0 +1,100 @@
|
|||
import { observer } from "mobx-react-lite";
|
||||
import { BehaviorTreeManagerStore } from "./behavior_tree_manager_store";
|
||||
import React from "react";
|
||||
import { useStore } from "../../core/helper/use_store";
|
||||
import { ButtonV2, ButtonV2Type } from "../../core/ui/button/button_v2";
|
||||
import { CoreCard } from "../../core/ui/card/card";
|
||||
import { Icon } from "../../core/ui/icons/icons";
|
||||
import { themeStore } from "../..";
|
||||
import { InputV2 } from "../../core/ui/input/input_v2";
|
||||
import { CoreModal } from "../../core/ui/modal/modal";
|
||||
import { SelectV2 } from "../../core/ui/select/select_v2";
|
||||
import { CoreText, CoreTextType } from "../../core/ui/text/text";
|
||||
import { MainPageV2 } from "../../core/ui/pages/main_page_v2";
|
||||
|
||||
export const BehaviorTreeManagerScreenPath = "/behavior/tree/manager";
|
||||
|
||||
export const BehaviorTreeManagerScreen = observer(() => {
|
||||
const store = useStore(BehaviorTreeManagerStore);
|
||||
|
||||
return (
|
||||
<>
|
||||
<MainPageV2
|
||||
children={
|
||||
<>
|
||||
<div style={{ height: "100%", overflowY: "auto", overflowX: "hidden" }}>
|
||||
<div style={{ height: 20 }} />
|
||||
<ButtonV2
|
||||
icon={<Icon type={"Plus"} style={{ alignSelf: "center", marginLeft: 10, marginRight: 10 }} />}
|
||||
text="СОЗДАТЬ ДЕРЕВО ПОВЕДЕНИЯ"
|
||||
onClick={() => store.modalShow()}
|
||||
/>
|
||||
<div style={{ height: 50 }} />
|
||||
|
||||
<div style={{ display: "inline-grid", gridTemplateColumns: "1fr 1fr 1fr", width: "100%" }}>
|
||||
{store.btTreeModels?.map((el, index) => (
|
||||
<CoreCard
|
||||
key={index}
|
||||
clickDeleteIcon={() => store.deleteBt(el._id)}
|
||||
clickGoToIcon={() => store.goToBt(el._id)}
|
||||
descriptionMiddle={el.description}
|
||||
descriptionTop={el.name}
|
||||
date={el.unixTime}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
<CoreModal
|
||||
isOpen={store.isModalOpen}
|
||||
onClose={() => store.modalCancel()}
|
||||
children={
|
||||
<>
|
||||
<div style={{ height: 30 }} />
|
||||
<CoreText
|
||||
text="Создание дерева поведения"
|
||||
type={CoreTextType.header}
|
||||
color={themeStore.theme.white}
|
||||
style={{ textAlignLast: "center" }}
|
||||
/>
|
||||
<div style={{ height: 30 }} />
|
||||
<div
|
||||
style={{
|
||||
height: 1,
|
||||
width: "calc(100% - 30px)",
|
||||
backgroundColor: themeStore.theme.outlineVariant,
|
||||
}}
|
||||
/>
|
||||
<div style={{ height: 20 }} />
|
||||
<InputV2 trim={true} label={"Название"} onChange={(text) => store.updateForm({ name: text })} />
|
||||
<div style={{ height: 20 }} />
|
||||
<InputV2 trim={true} label={"Описание"} onChange={(text) => store.updateForm({ description: text })} />
|
||||
<div style={{ height: 20 }} />
|
||||
<SelectV2
|
||||
items={store.scenes?.map((el) => ({ name: el.name, value: el._id })) ?? []}
|
||||
initialValue={""}
|
||||
label={"Сцена"}
|
||||
onChange={(value: string) => store.updateForm({ sceneId: value })}
|
||||
/>
|
||||
<div style={{ height: 30 }} />
|
||||
<div
|
||||
style={{
|
||||
height: 1,
|
||||
width: "calc(100% - 30px)",
|
||||
backgroundColor: themeStore.theme.outlineVariant,
|
||||
}}
|
||||
/>
|
||||
<div style={{ display: "flex", paddingTop: 20, justifyContent: "center" }}>
|
||||
<ButtonV2 text="Сохранить" onClick={() => store.saveNewBt()} type={ButtonV2Type.default} />
|
||||
<div style={{ width: 20 }} />
|
||||
<ButtonV2 text="Отменить" onClick={() => store.modalCancel()} type={ButtonV2Type.default} />
|
||||
</div>
|
||||
</>
|
||||
}
|
||||
/>
|
||||
</>
|
||||
}
|
||||
bgColor={themeStore.theme.black}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
});
|
|
@ -0,0 +1,60 @@
|
|||
import makeAutoObservable from "mobx-store-inheritance";
|
||||
import { UiDrawerFormState, CoreError } from "../../core/store/base_store";
|
||||
import { BehaviorTreeViewModel } from "../behavior_tree_builder/model/behavior_tree_view_model";
|
||||
import { NavigateFunction } from "react-router-dom";
|
||||
import { BehaviorTreeBuilderPath } from "../behavior_tree_builder/presentation/behavior_tree_builder_screen";
|
||||
import { BehaviorTreeModel } from "../behavior_tree_builder/model/behavior_tree_model";
|
||||
import { SceneModel } from "../scene_manager/model/scene_model";
|
||||
import { BehaviorTreeManagerHttpRepository } from "./behavior_tree_manager_repository";
|
||||
import { message } from "antd";
|
||||
export enum DrawerState {
|
||||
newBehaviorTree = "Новое дерево поведения",
|
||||
}
|
||||
export class BehaviorTreeManagerStore extends UiDrawerFormState<BehaviorTreeViewModel, CoreError> {
|
||||
viewModel: BehaviorTreeViewModel = BehaviorTreeViewModel.empty();
|
||||
navigate?: NavigateFunction;
|
||||
btTreeModels: BehaviorTreeModel[] = [];
|
||||
scenes?: SceneModel[];
|
||||
behaviorTreeManagerHttpRepository = new BehaviorTreeManagerHttpRepository();
|
||||
isModalOpen: boolean = false;
|
||||
activeProject?: string;
|
||||
constructor() {
|
||||
super(DrawerState);
|
||||
makeAutoObservable(this);
|
||||
}
|
||||
init = async (navigate?: NavigateFunction | undefined): Promise<void> => {
|
||||
this.navigate = navigate;
|
||||
(await this.behaviorTreeManagerHttpRepository.getActiveProjectId()).map((el) => {
|
||||
this.activeProject = el.id;
|
||||
this.viewModel.project = this.activeProject;
|
||||
});
|
||||
|
||||
await this.mapOk("btTreeModels", this.behaviorTreeManagerHttpRepository.getAllBtInstances());
|
||||
await this.mapOk("scenes", this.behaviorTreeManagerHttpRepository.getAllScenes());
|
||||
};
|
||||
deleteBt = async (id: string) => (
|
||||
await this.behaviorTreeManagerHttpRepository.deleteBt(id),
|
||||
await this.mapOk("btTreeModels", this.behaviorTreeManagerHttpRepository.getAllBtInstances())
|
||||
);
|
||||
saveNewBt = async () =>
|
||||
(await this.viewModel.valid<BehaviorTreeViewModel>()).fold(
|
||||
async (model) => {
|
||||
await this.messageHttp(this.behaviorTreeManagerHttpRepository.saveNewBt(model), {
|
||||
successMessage: "Новое дерево создано",
|
||||
});
|
||||
await this.mapOk("btTreeModels", this.behaviorTreeManagerHttpRepository.getAllBtInstances());
|
||||
},
|
||||
async (error) => message.error(error)
|
||||
);
|
||||
goToBt = (id: string) => {
|
||||
console.log(this.navigate);
|
||||
if (this.navigate) this.navigate(BehaviorTreeBuilderPath(id));
|
||||
};
|
||||
modalShow = () => {
|
||||
this.isModalOpen = true;
|
||||
};
|
||||
|
||||
modalCancel = () => {
|
||||
this.isModalOpen = false;
|
||||
};
|
||||
}
|
11
ui/src/features/behavior_tree_manager/number_trivia.ts
Normal file
11
ui/src/features/behavior_tree_manager/number_trivia.ts
Normal file
|
@ -0,0 +1,11 @@
|
|||
import { Result } from "../../core/helper/result";
|
||||
|
||||
export class NumberTriviaModel {
|
||||
constructor() {}
|
||||
isValid(): Result<string, void> {
|
||||
return Result.ok();
|
||||
}
|
||||
static empty() {
|
||||
return new NumberTriviaModel();
|
||||
}
|
||||
}
|
|
@ -2,7 +2,7 @@ import { TypedEvent } from "../../../core/helper/typed_event";
|
|||
import { SocketRepository, socketRepository } from "../../../core/repository/core_socket_repository";
|
||||
import { ProcessStatus } from "../../dataset/dataset_model";
|
||||
|
||||
export interface ProcessUpdate {
|
||||
export interface ProcessUpdate {
|
||||
id: string;
|
||||
status: ProcessStatus;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { FormBuilderValidationModel } from "../../dataset/dataset_model";
|
||||
import { IsNotEmpty, IsString } from "class-validator";
|
||||
import { IsNotEmpty, IsString } from "class-validator";
|
||||
import { ValidationModel } from "../../../core/model/validation_model";
|
||||
import { FormBuilderValidationModel } from "../../../core/model/form_builder_validation_model";
|
||||
|
||||
export enum ModelMachineLearningTypes {
|
||||
OBJECT_DETECTION = "OBJECT_DETECTION",
|
||||
|
|
|
@ -13,8 +13,8 @@ import { FormBuilder } from "../../../core/ui/form_builder/form_builder";
|
|||
import { match } from "ts-pattern";
|
||||
import { TemplateModelCard } from "./ui/template_model_card";
|
||||
import { Icon } from "../../../core/ui/icons/icons";
|
||||
import { FormBuilderValidationModel } from "../../dataset/dataset_model";
|
||||
import { useStore } from "../../../core/helper/use_store";
|
||||
import { useStore } from "../../../core/helper/use_store";
|
||||
import { FormBuilderValidationModel } from "../../../core/model/form_builder_validation_model";
|
||||
|
||||
interface IItem {
|
||||
name: string;
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import { Result } from "../../core/helper/result";
|
||||
import makeAutoObservable from "mobx-store-inheritance";
|
||||
import { FormBuilderValidationModel } from "../../core/model/form_builder_validation_model";
|
||||
|
||||
export enum ProcessStatus {
|
||||
END = "END",
|
||||
|
@ -37,52 +38,7 @@ export interface Asset {
|
|||
image: string;
|
||||
}
|
||||
|
||||
export class FormBuilderValidationModel {
|
||||
public result: string;
|
||||
public context: string;
|
||||
public form: string[];
|
||||
public output: any;
|
||||
constructor(context: string, result: string, form: string[], output: string) {
|
||||
this.context = context;
|
||||
this.result = result;
|
||||
this.form = form;
|
||||
this.output = output;
|
||||
}
|
||||
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": \${<SelectDataset/>:OBJECT:{"dataset": {}},
|
||||
"pretrain": \${pretrain:Enum<PRETRAIN>:true}
|
||||
}`,
|
||||
[],
|
||||
""
|
||||
);
|
||||
}
|
||||
}
|
||||
export const scene = `{
|
||||
"center_shell": [\${CENTER_SHELL_1:number:0}, \${CENTER_SHELL_2:number:0}, \${CENTER_SHELL_3:number:0}],
|
||||
"scene":\${<SelectScene/>:OBJECT:{"details": []}
|
||||
}`;
|
||||
|
||||
|
||||
export class DataSetModel {
|
||||
dataSetObjects: string[];
|
||||
datasetType: string;
|
||||
|
@ -209,5 +165,3 @@ export const defaultFormValue: any = {
|
|||
camera_position: { center_shell: [0, 0, 0], radius_range: [1, 1.4], elevation_range: [10, 90] },
|
||||
generation: { n_cam_pose: 5, n_sample_on_pose: 3, n_series: 100, image_format: "JPEG", image_size_wh: [640, 480] },
|
||||
};
|
||||
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
import { ValidationModel } from "../../core/model/validation_model";
|
||||
import { Type } from "class-transformer";
|
||||
import { IsEnum, IsNotEmpty, IsString } from "class-validator";
|
||||
import { FormBuilderValidationModel } from "../dataset/dataset_model";
|
||||
|
||||
import { FormBuilderValidationModel } from "../../core/model/form_builder_validation_model";
|
||||
|
||||
export enum DigitalTwinsTypes {
|
||||
CAMERA = "CAMERA",
|
||||
ROBOT = "ROBOT",
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
import React from "react";
|
||||
import { observer } from "mobx-react-lite";
|
||||
import { DrawersSkills, SkillsStore } from "./skills_store";
|
||||
import { Drawer, Modal } from "antd";
|
||||
|
@ -73,44 +72,58 @@ export const SkillsScreen = observer(() => {
|
|||
<div style={{ display: "flex", flexDirection: "column", justifyContent: "space-between", height: "100%" }}>
|
||||
<div>
|
||||
<CoreInput
|
||||
trim={true}
|
||||
label={"name"}
|
||||
onChange={(text) =>
|
||||
store.updateForm({ SkillPackage: Object.assign(store.viewModel.SkillPackage, { name: text }) })
|
||||
}
|
||||
/>
|
||||
<CoreInput
|
||||
trim={true}
|
||||
label={"format"}
|
||||
onChange={(text) =>
|
||||
store.updateForm({ SkillPackage: Object.assign(store.viewModel.SkillPackage, { format: text }) })
|
||||
}
|
||||
/>
|
||||
<CoreInput
|
||||
trim={true}
|
||||
label="version"
|
||||
onChange={(text) =>
|
||||
store.updateForm({ SkillPackage: Object.assign(store.viewModel.SkillPackage, { version: text }) })
|
||||
}
|
||||
/>
|
||||
<CoreInput
|
||||
trim={true}
|
||||
label={"Module description"}
|
||||
onChange={(text) =>
|
||||
store.updateForm({ Module: Object.assign(store.viewModel.Module, { description: text }) })
|
||||
}
|
||||
/>
|
||||
<CoreInput
|
||||
trim={true}
|
||||
label={"Module name"}
|
||||
onChange={(text) => store.updateForm({ Module: Object.assign(store.viewModel.Module, { name: text }) })}
|
||||
/>
|
||||
<CoreInput
|
||||
<CoreInput
|
||||
trim={true}
|
||||
label={"Module node name"}
|
||||
onChange={(text) => store.updateForm({ Module: Object.assign(store.viewModel.Module, { node_name: text }) })}
|
||||
onChange={(text) =>
|
||||
store.updateForm({ Module: Object.assign(store.viewModel.Module, { node_name: text }) })
|
||||
}
|
||||
/>
|
||||
<CoreInput
|
||||
trim={true}
|
||||
label="Launch package"
|
||||
onChange={(text) => store.updateForm({ Launch: Object.assign(store.viewModel.Launch, { package: text }) })}
|
||||
onChange={(text) =>
|
||||
store.updateForm({ Launch: Object.assign(store.viewModel.Launch, { package: text }) })
|
||||
}
|
||||
/>
|
||||
<CoreInput
|
||||
trim={true}
|
||||
label="Launch executable"
|
||||
onChange={(text) => store.updateForm({ Launch: Object.assign(store.viewModel.Launch, { executable: text }) })}
|
||||
onChange={(text) =>
|
||||
store.updateForm({ Launch: Object.assign(store.viewModel.Launch, { executable: text }) })
|
||||
}
|
||||
/>
|
||||
|
||||
<CoreText
|
||||
|
@ -122,6 +135,7 @@ export const SkillsScreen = observer(() => {
|
|||
{store.viewModel.topicsOut.map((el, index) => (
|
||||
<div key={index} style={{ marginTop: 10 }}>
|
||||
<CoreInput
|
||||
trim={true}
|
||||
value={el.name}
|
||||
label={"name"}
|
||||
onChange={(text) =>
|
||||
|
@ -129,6 +143,7 @@ export const SkillsScreen = observer(() => {
|
|||
}
|
||||
/>
|
||||
<CoreInput
|
||||
trim={true}
|
||||
value={el.type}
|
||||
label={"type"}
|
||||
onChange={(text) =>
|
||||
|
@ -146,6 +161,7 @@ export const SkillsScreen = observer(() => {
|
|||
{store.viewModel.BTAction.map((el, index) => (
|
||||
<div key={index} style={{ marginTop: 10 }}>
|
||||
<CoreInput
|
||||
trim={true}
|
||||
value={el.name}
|
||||
label={"name"}
|
||||
onChange={(text) =>
|
||||
|
@ -153,20 +169,14 @@ export const SkillsScreen = observer(() => {
|
|||
}
|
||||
/>
|
||||
<CoreInput
|
||||
trim={true}
|
||||
value={el.type}
|
||||
label={"type"}
|
||||
onChange={(text) =>
|
||||
store.updateForm({ BTAction: store.viewModel.BTAction.replacePropIndex({ type: text }, index) })
|
||||
}
|
||||
/>
|
||||
<CoreInput
|
||||
value={el.format}
|
||||
label={"format"}
|
||||
onChange={(text) =>
|
||||
store.updateForm({ BTAction: store.viewModel.BTAction.replacePropIndex({ format: text }, index) })
|
||||
}
|
||||
/>
|
||||
|
||||
|
||||
<CoreSelect
|
||||
items={Object.keys(BtAction)}
|
||||
value={el.typeAction}
|
||||
|
@ -214,3 +224,4 @@ export const SkillsScreen = observer(() => {
|
|||
</>
|
||||
);
|
||||
});
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue