diff --git a/server/src/core/models/skill_model.ts b/server/src/core/models/skill_model.ts index c22ab7d..57baf8c 100644 --- a/server/src/core/models/skill_model.ts +++ b/server/src/core/models/skill_model.ts @@ -18,7 +18,7 @@ export class TopicViewModel { export interface IParam { type: string; - dependency: Object; + dependency: object; } export interface Skill { SkillPackage: ISkillPackage; diff --git a/server/src/core/services/executor_program_service.ts b/server/src/core/services/executor_program_service.ts index 2f5dc7b..3b1a609 100644 --- a/server/src/core/services/executor_program_service.ts +++ b/server/src/core/services/executor_program_service.ts @@ -50,7 +50,6 @@ export class ExecutorProgramService }; worker.send(workerDataExec); worker.on("message", (e) => { - console.log(JSON.stringify(e)); const spawnError = SpawnError.isError(e); if (spawnError instanceof SpawnError) { diff --git a/server/src/features/projects/domain/robossembler_assets_network_mapper_scenario.ts b/server/src/features/projects/domain/robossembler_assets_network_mapper_scenario.ts index 8b24b30..368b00b 100644 --- a/server/src/features/projects/domain/robossembler_assets_network_mapper_scenario.ts +++ b/server/src/features/projects/domain/robossembler_assets_network_mapper_scenario.ts @@ -35,7 +35,6 @@ export class RobossemblerAssetsNetworkMapperScenario extends CallbackStrategyWit "/assets/"; model.map((el) => { const assetLibsAddress = assetAddress + "/libs/objects/" + el.name; - console.log(assetLibsAddress); el.stlUrl = `${assetAddress}${el.part_path}`; el.glUrl = `${assetLibsAddress}.glb`; el.daeUrl = `${assetLibsAddress}.dae`; diff --git a/ui/src/core/extensions/array.ts b/ui/src/core/extensions/array.ts index 6ea9308..2c4cf2a 100644 --- a/ui/src/core/extensions/array.ts +++ b/ui/src/core/extensions/array.ts @@ -1,7 +1,14 @@ +/* eslint-disable no-extend-native */ import { Result } from "../helper/result"; /* eslint-disable @typescript-eslint/no-this-alias */ export const ArrayExtensions = () => { + if (Array.prototype.plus === undefined) { + Array.prototype.plus = function (array) { + array.forEach((el) => this.push(el)) + return this; + } + } if ([].indexOfR === undefined) { Array.prototype.indexOfR = function (element) { if (this.indexOf(element) === -1) { diff --git a/ui/src/core/extensions/extensions.ts b/ui/src/core/extensions/extensions.ts index acacdd9..2eb2ff7 100644 --- a/ui/src/core/extensions/extensions.ts +++ b/ui/src/core/extensions/extensions.ts @@ -31,6 +31,7 @@ declare global { updateAll(value: Partial): Array; atR(index: number | undefined): Result; whereOne(predicate: (value: T) => boolean): Result; + plus(array: any[]): Array } interface Date { formatDate(): string; diff --git a/ui/src/core/model/skill_model.ts b/ui/src/core/model/skill_model.ts index b2b78cf..cbc311d 100644 --- a/ui/src/core/model/skill_model.ts +++ b/ui/src/core/model/skill_model.ts @@ -425,26 +425,26 @@ export class Skills { .filter((el) => el !== ""); getDependencyBySkillLabelAndType = (skillType: string, sid: string): DependencyViewModel => this.skills - .reduce((acc, skill) => { - if (skill.sid?.isEqual(sid)) { - skill.BTAction.map((action) => { - action.param.map((param) => { + .reduce((acc, skill) => { + if (skill.sid?.isEqual(sid)) { + skill.BTAction.map((action) => { + action.param.map((param) => { - if (param.type.isEqual(skillType)) { + if (param.type.isEqual(skillType)) { - acc.push(param?.dependency ?? DependencyViewModel.empty()); - } - // console.log(acc); - return param; + acc.push(param?.dependency ?? DependencyViewModel.empty()); + } + + return param; + }); + return action; }); - return action; - }); - } + } - return acc; - }, []) - .at(0) ?? DependencyViewModel.empty() + return acc; + }, []) + .at(0) ?? DependencyViewModel.empty() static isEmpty(model: Skills): Result { if (model.skills.isEmpty()) { return Result.error(undefined); diff --git a/ui/src/core/model/validation_model.ts b/ui/src/core/model/validation_model.ts index 7e41b5e..f28d353 100644 --- a/ui/src/core/model/validation_model.ts +++ b/ui/src/core/model/validation_model.ts @@ -1,3 +1,4 @@ +import { message } from "antd"; import { Result } from "../helper/result"; import { validate, ValidationError } from "class-validator"; @@ -26,4 +27,12 @@ export class ValidationModel { return Result.ok(this as unknown as T); } }; + validMessage = async(): Promise> => { + const result = await this.valid(); + + if (result.isFailure()) { + message.error(result.error); + } + return result; + } } diff --git a/ui/src/core/repository/core_http_repository.ts b/ui/src/core/repository/core_http_repository.ts index 48eb520..37ed2bb 100644 --- a/ui/src/core/repository/core_http_repository.ts +++ b/ui/src/core/repository/core_http_repository.ts @@ -132,7 +132,7 @@ export class CoreHttpRepository extends HttpRepository { getAssetsActiveProject = async (): Promise> => { return this._jsonRequest(HttpMethod.GET, "/projects/assets"); }; - + getSceneAsset = (id: string) => this._jsonToClassInstanceRequest(HttpMethod.GET, `/scenes/by_id?id=${id}`, SceneAsset) as Promise< Result @@ -141,5 +141,6 @@ export class CoreHttpRepository extends HttpRepository { return this._jsonRequest(HttpMethod.GET, "/projects/get/active/project/id"); } getAllScenes = () => this._jsonRequest(HttpMethod.GET, "/scenes"); + getAllTopics = () => this._jsonRequest(HttpMethod.GET, `/topics`); + } - \ No newline at end of file diff --git a/ui/src/core/store/base_store.ts b/ui/src/core/store/base_store.ts index be176e8..d9eafaf 100644 --- a/ui/src/core/store/base_store.ts +++ b/ui/src/core/store/base_store.ts @@ -127,4 +127,17 @@ export abstract class FormState extends UiErrorState { loadClassInstance = (instance: ClassConstructor, viewModel: V) => { this.viewModel = plainToInstance(instance, viewModel); }; + isModalOpen: boolean = false; + modalShow = () => { + this.isModalOpen = true; + }; + + modalClickOk = () => { + this.isModalOpen = false; + }; + + modalCancel = () => { + this.isModalOpen = false; + }; } + 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 2e8a6fd..f3658d3 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 @@ -27,6 +27,7 @@ import { PrimitiveViewModel, SystemPrimitive } from "../model/primitive_view_mod import { SceneAsset } from "../../../core/model/scene_asset"; import { themeStore } from "../../.."; import { RunTimeActions } from "./ui/actions/runtime_actions"; +import { ITopicModel } from "../../topics/topic_view_model"; interface I2DArea { x: number; @@ -83,6 +84,7 @@ export class BehaviorTreeBuilderStore extends UiDrawerFormState; nodeUpdateObserver?: NodeRerenderObserver; primitiveViewModel: PrimitiveViewModel; + topics: ITopicModel[]; skillTree: ISkillView = { name: "", children: [ @@ -114,7 +116,7 @@ export class BehaviorTreeBuilderStore extends UiDrawerFormState this.filledOutTemplates.topicsStack; + getAllTopics = () => this.filledOutTemplates.topicsStack.plus(this.topics); errorHandingStrategy = (_: CoreError) => {}; dragEnd = (e: EventTarget) => { @@ -214,7 +216,7 @@ export class BehaviorTreeBuilderStore extends UiDrawerFormState { diff --git a/ui/src/features/topics/topic_view_model.ts b/ui/src/features/topics/topic_view_model.ts index 44c8bc2..74551db 100644 --- a/ui/src/features/topics/topic_view_model.ts +++ b/ui/src/features/topics/topic_view_model.ts @@ -21,6 +21,7 @@ export class TopicViewModel extends ValidationModel { export interface ITopicModel { digitalTwinId?: string; sid?: string; + _id?: string; name: string; type: string; } diff --git a/ui/src/features/topics/topics_repository.ts b/ui/src/features/topics/topics_repository.ts index 852926b..e06412c 100644 --- a/ui/src/features/topics/topics_repository.ts +++ b/ui/src/features/topics/topics_repository.ts @@ -1,6 +1,9 @@ -import { HttpMethod, HttpRepository } from "../../core/repository/core_http_repository"; +import { CoreHttpRepository, HttpMethod, HttpRepository } from "../../core/repository/core_http_repository"; +import { TopicViewModel } from "./topic_view_model"; -export class TopicsHttpRepository extends HttpRepository { +export class TopicsHttpRepository extends CoreHttpRepository { + deleteTopic = (id: any) => this._jsonRequest(HttpMethod.DELETE, `${this.featureApi}?id=${id}`); featureApi = "/topics"; - getAllTopics = () => this._jsonRequest(HttpMethod.GET, this.featureApi); + createTopics = (model: TopicViewModel) => this._jsonRequest(HttpMethod.POST, this.featureApi, model); + } diff --git a/ui/src/features/topics/topics_screen.tsx b/ui/src/features/topics/topics_screen.tsx index 2fb82c8..f61fc7b 100644 --- a/ui/src/features/topics/topics_screen.tsx +++ b/ui/src/features/topics/topics_screen.tsx @@ -2,6 +2,11 @@ import React from "react"; import { observer } from "mobx-react-lite"; import { TopicsStore } from "./topics_store"; import { useStore } from "../../core/helper/use_store"; +import { CoreButton } from "../../core/ui/button/button"; +import { CoreModal } from "../../core/ui/modal/modal"; +import { InputV2 } from "../../core/ui/input/input_v2"; +import { CoreText, CoreTextType } from "../../core/ui/text/text"; +import { CoreInput } from "../../core/ui/input/input"; export const TopicsScreenPath = "/topics"; @@ -10,12 +15,43 @@ export const TopicsScreen = observer(() => { return ( <> +
+ store.modalShow()} /> + store.openTopicModal()} /> +
{store.topics?.map((el) => (
+ store.deleteTopic(el._id ?? "")} /> + window.prompt("Copy to clipboard: Ctrl+C, Enter", JSON.stringify(el))} + /> +
{el.name}
{el.type}
))} + store.modalCancel()} + children={ +
+ store.updateForm({ type: text })} /> + store.updateForm({ name: text })} /> + store.createTopic()} /> +
+ } + /> + store.cancelImportTopicModal()} + children={ +
+ store.importTopic(text)} label="import" /> +
+ } + /> ); }); diff --git a/ui/src/features/topics/topics_store.ts b/ui/src/features/topics/topics_store.ts index eb680b1..d9e4157 100644 --- a/ui/src/features/topics/topics_store.ts +++ b/ui/src/features/topics/topics_store.ts @@ -6,14 +6,35 @@ import { NavigateFunction } from "react-router-dom"; import { TopicsHttpRepository } from "./topics_repository"; export class TopicsStore extends FormState { + importTopic(text: string): void { + this.loadClassInstance(TopicModel, JSON.parse(text)) + + this.createTopic() + } + + viewModel: TopicModel = TopicModel.empty(); topics?: ITopicModel[]; topicsHttpRepository: TopicsHttpRepository = new TopicsHttpRepository(); + importTopicModal = false; constructor() { super(); makeAutoObservable(this); } init = async (navigate?: NavigateFunction | undefined) => { + this.modalCancel(); + this.importTopicModal = false; await this.mapOk("topics", this.topicsHttpRepository.getAllTopics()); }; + cancelImportTopicModal = () => { + this.importTopicModal = false; + } + openTopicModal = () => { + this.importTopicModal = true; + } + deleteTopic = async (id: string) => (await (this.topicsHttpRepository.deleteTopic(id))).map(() => this.init()); + createTopic = async () => + (await this.viewModel.validMessage()).map(async (model) => + (await this.topicsHttpRepository.createTopics(model)).map(() => this.init()) + ); }