This commit is contained in:
IDONTSUDO 2025-02-17 21:30:09 +03:00
parent d7e8c825cb
commit 7d3b8ff0cb
14 changed files with 117 additions and 25 deletions

View file

@ -18,7 +18,7 @@ export class TopicViewModel {
export interface IParam {
type: string;
dependency: Object;
dependency: object;
}
export interface Skill {
SkillPackage: ISkillPackage;

View file

@ -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) {

View file

@ -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`;

View file

@ -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) {

View file

@ -31,6 +31,7 @@ declare global {
updateAll(value: Partial<T>): Array<T>;
atR(index: number | undefined): Result<void, T>;
whereOne(predicate: (value: T) => boolean): Result<void, T>;
plus(array: any[]): Array<T>
}
interface Date {
formatDate(): string;

View file

@ -425,26 +425,26 @@ export class Skills {
.filter((el) => el !== "");
getDependencyBySkillLabelAndType = (skillType: string, sid: string): DependencyViewModel => this.skills
.reduce<DependencyViewModel[]>((acc, skill) => {
if (skill.sid?.isEqual(sid)) {
skill.BTAction.map((action) => {
action.param.map((param) => {
.reduce<DependencyViewModel[]>((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<void, void> {
if (model.skills.isEmpty()) {
return Result.error(undefined);

View file

@ -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<T>(): Promise<Result<string, T>> => {
const result = await this.valid<T>();
if (result.isFailure()) {
message.error(result.error);
}
return result;
}
}

View file

@ -132,7 +132,7 @@ export class CoreHttpRepository extends HttpRepository {
getAssetsActiveProject = async (): Promise<Result<HttpError, Parts[]>> => {
return this._jsonRequest<Parts[]>(HttpMethod.GET, "/projects/assets");
};
getSceneAsset = (id: string) =>
this._jsonToClassInstanceRequest(HttpMethod.GET, `/scenes/by_id?id=${id}`, SceneAsset) as Promise<
Result<HttpError, SceneAsset>
@ -141,5 +141,6 @@ export class CoreHttpRepository extends HttpRepository {
return this._jsonRequest<UUID>(HttpMethod.GET, "/projects/get/active/project/id");
}
getAllScenes = () => this._jsonRequest<SceneModel[]>(HttpMethod.GET, "/scenes");
getAllTopics = () => this._jsonRequest(HttpMethod.GET, `/topics`);
}

View file

@ -127,4 +127,17 @@ export abstract class FormState<V, E> extends UiErrorState<E> {
loadClassInstance = (instance: ClassConstructor<V>, viewModel: V) => {
this.viewModel = plainToInstance(instance, viewModel);
};
isModalOpen: boolean = false;
modalShow = () => {
this.isModalOpen = true;
};
modalClickOk = () => {
this.isModalOpen = false;
};
modalCancel = () => {
this.isModalOpen = false;
};
}

View file

@ -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<BehaviorTreeView
areaPlugin?: AreaPlugin<Schemes, AreaExtra>;
nodeUpdateObserver?: NodeRerenderObserver;
primitiveViewModel: PrimitiveViewModel;
topics: ITopicModel[];
skillTree: ISkillView = {
name: "",
children: [
@ -114,7 +116,7 @@ export class BehaviorTreeBuilderStore extends UiDrawerFormState<BehaviorTreeView
this.editor = editor;
this.areaPlugin = area;
};
getAllTopics = () => this.filledOutTemplates.topicsStack;
getAllTopics = () => this.filledOutTemplates.topicsStack.plus(this.topics);
errorHandingStrategy = (_: CoreError) => {};
dragEnd = (e: EventTarget) => {
@ -214,7 +216,7 @@ export class BehaviorTreeBuilderStore extends UiDrawerFormState<BehaviorTreeView
await this.mapOk("sceneAsset", this.behaviorTreeBuilderHttpRepository.getSceneAsset(model.sceneId));
this.isLoading = false;
await this.mapOk("topics", this.behaviorTreeBuilderHttpRepository.getAllTopics());
this.reteForceUpdateObserver?.emit("");
},
async () => {

View file

@ -21,6 +21,7 @@ export class TopicViewModel extends ValidationModel {
export interface ITopicModel {
digitalTwinId?: string;
sid?: string;
_id?: string;
name: string;
type: string;
}

View file

@ -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);
}

View file

@ -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 (
<>
<div style={{ display: "flex" }}>
<CoreButton text="добавить новый топик" style={{ width: 200 }} onClick={() => store.modalShow()} />
<CoreButton text="импорт топика" style={{ width: 200 }} onClick={() => store.openTopicModal()} />
</div>
{store.topics?.map((el) => (
<div style={{ margin: 10, border: "1px solid red" }}>
<CoreText text="Delete" type={CoreTextType.header} onClick={() => store.deleteTopic(el._id ?? "")} />
<CoreText
text="Copy"
type={CoreTextType.header}
onClick={() => window.prompt("Copy to clipboard: Ctrl+C, Enter", JSON.stringify(el))}
/>
<div>{el.name}</div>
<div>{el.type}</div>
</div>
))}
<CoreModal
isOpen={store.isModalOpen}
onClose={() => store.modalCancel()}
children={
<div>
<InputV2 label={"type"} onChange={(text) => store.updateForm({ type: text })} />
<InputV2 label={"name"} onChange={(text) => store.updateForm({ name: text })} />
<CoreButton text="new" onClick={() => store.createTopic()} />
</div>
}
/>
<CoreModal
isOpen={store.importTopicModal}
onClose={() => store.cancelImportTopicModal()}
children={
<div>
<InputV2 onChange={(text) => store.importTopic(text)} label="import" />
</div>
}
/>
</>
);
});

View file

@ -6,14 +6,35 @@ import { NavigateFunction } from "react-router-dom";
import { TopicsHttpRepository } from "./topics_repository";
export class TopicsStore extends FormState<TopicModel, HttpError> {
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<TopicModel>()).map(async (model) =>
(await this.topicsHttpRepository.createTopics(model)).map(() => this.init())
);
}