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 { export interface IParam {
type: string; type: string;
dependency: Object; dependency: object;
} }
export interface Skill { export interface Skill {
SkillPackage: ISkillPackage; SkillPackage: ISkillPackage;

View file

@ -50,7 +50,6 @@ export class ExecutorProgramService
}; };
worker.send(workerDataExec); worker.send(workerDataExec);
worker.on("message", (e) => { worker.on("message", (e) => {
console.log(JSON.stringify(e));
const spawnError = SpawnError.isError(e); const spawnError = SpawnError.isError(e);
if (spawnError instanceof SpawnError) { if (spawnError instanceof SpawnError) {

View file

@ -35,7 +35,6 @@ export class RobossemblerAssetsNetworkMapperScenario extends CallbackStrategyWit
"/assets/"; "/assets/";
model.map((el) => { model.map((el) => {
const assetLibsAddress = assetAddress + "/libs/objects/" + el.name; const assetLibsAddress = assetAddress + "/libs/objects/" + el.name;
console.log(assetLibsAddress);
el.stlUrl = `${assetAddress}${el.part_path}`; el.stlUrl = `${assetAddress}${el.part_path}`;
el.glUrl = `${assetLibsAddress}.glb`; el.glUrl = `${assetLibsAddress}.glb`;
el.daeUrl = `${assetLibsAddress}.dae`; el.daeUrl = `${assetLibsAddress}.dae`;

View file

@ -1,7 +1,14 @@
/* eslint-disable no-extend-native */
import { Result } from "../helper/result"; import { Result } from "../helper/result";
/* eslint-disable @typescript-eslint/no-this-alias */ /* eslint-disable @typescript-eslint/no-this-alias */
export const ArrayExtensions = () => { export const ArrayExtensions = () => {
if (Array.prototype.plus === undefined) {
Array.prototype.plus = function (array) {
array.forEach((el) => this.push(el))
return this;
}
}
if ([].indexOfR === undefined) { if ([].indexOfR === undefined) {
Array.prototype.indexOfR = function (element) { Array.prototype.indexOfR = function (element) {
if (this.indexOf(element) === -1) { if (this.indexOf(element) === -1) {

View file

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

View file

@ -435,7 +435,7 @@ export class Skills {
acc.push(param?.dependency ?? DependencyViewModel.empty()); acc.push(param?.dependency ?? DependencyViewModel.empty());
} }
// console.log(acc);
return param; return param;
}); });
return action; return action;

View file

@ -1,3 +1,4 @@
import { message } from "antd";
import { Result } from "../helper/result"; import { Result } from "../helper/result";
import { validate, ValidationError } from "class-validator"; import { validate, ValidationError } from "class-validator";
@ -26,4 +27,12 @@ export class ValidationModel {
return Result.ok(this as unknown as T); 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

@ -141,5 +141,6 @@ export class CoreHttpRepository extends HttpRepository {
return this._jsonRequest<UUID>(HttpMethod.GET, "/projects/get/active/project/id"); return this._jsonRequest<UUID>(HttpMethod.GET, "/projects/get/active/project/id");
} }
getAllScenes = () => this._jsonRequest<SceneModel[]>(HttpMethod.GET, "/scenes"); 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) => { loadClassInstance = (instance: ClassConstructor<V>, viewModel: V) => {
this.viewModel = plainToInstance(instance, viewModel); 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 { SceneAsset } from "../../../core/model/scene_asset";
import { themeStore } from "../../.."; import { themeStore } from "../../..";
import { RunTimeActions } from "./ui/actions/runtime_actions"; import { RunTimeActions } from "./ui/actions/runtime_actions";
import { ITopicModel } from "../../topics/topic_view_model";
interface I2DArea { interface I2DArea {
x: number; x: number;
@ -83,6 +84,7 @@ export class BehaviorTreeBuilderStore extends UiDrawerFormState<BehaviorTreeView
areaPlugin?: AreaPlugin<Schemes, AreaExtra>; areaPlugin?: AreaPlugin<Schemes, AreaExtra>;
nodeUpdateObserver?: NodeRerenderObserver; nodeUpdateObserver?: NodeRerenderObserver;
primitiveViewModel: PrimitiveViewModel; primitiveViewModel: PrimitiveViewModel;
topics: ITopicModel[];
skillTree: ISkillView = { skillTree: ISkillView = {
name: "", name: "",
children: [ children: [
@ -114,7 +116,7 @@ export class BehaviorTreeBuilderStore extends UiDrawerFormState<BehaviorTreeView
this.editor = editor; this.editor = editor;
this.areaPlugin = area; this.areaPlugin = area;
}; };
getAllTopics = () => this.filledOutTemplates.topicsStack; getAllTopics = () => this.filledOutTemplates.topicsStack.plus(this.topics);
errorHandingStrategy = (_: CoreError) => {}; errorHandingStrategy = (_: CoreError) => {};
dragEnd = (e: EventTarget) => { dragEnd = (e: EventTarget) => {
@ -214,7 +216,7 @@ export class BehaviorTreeBuilderStore extends UiDrawerFormState<BehaviorTreeView
await this.mapOk("sceneAsset", this.behaviorTreeBuilderHttpRepository.getSceneAsset(model.sceneId)); await this.mapOk("sceneAsset", this.behaviorTreeBuilderHttpRepository.getSceneAsset(model.sceneId));
this.isLoading = false; this.isLoading = false;
await this.mapOk("topics", this.behaviorTreeBuilderHttpRepository.getAllTopics());
this.reteForceUpdateObserver?.emit(""); this.reteForceUpdateObserver?.emit("");
}, },
async () => { async () => {

View file

@ -21,6 +21,7 @@ export class TopicViewModel extends ValidationModel {
export interface ITopicModel { export interface ITopicModel {
digitalTwinId?: string; digitalTwinId?: string;
sid?: string; sid?: string;
_id?: string;
name: string; name: string;
type: 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"; 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 { observer } from "mobx-react-lite";
import { TopicsStore } from "./topics_store"; import { TopicsStore } from "./topics_store";
import { useStore } from "../../core/helper/use_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"; export const TopicsScreenPath = "/topics";
@ -10,12 +15,43 @@ export const TopicsScreen = observer(() => {
return ( 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) => ( {store.topics?.map((el) => (
<div style={{ margin: 10, border: "1px solid red" }}> <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.name}</div>
<div>{el.type}</div> <div>{el.type}</div>
</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"; import { TopicsHttpRepository } from "./topics_repository";
export class TopicsStore extends FormState<TopicModel, HttpError> { export class TopicsStore extends FormState<TopicModel, HttpError> {
importTopic(text: string): void {
this.loadClassInstance(TopicModel, JSON.parse(text))
this.createTopic()
}
viewModel: TopicModel = TopicModel.empty(); viewModel: TopicModel = TopicModel.empty();
topics?: ITopicModel[]; topics?: ITopicModel[];
topicsHttpRepository: TopicsHttpRepository = new TopicsHttpRepository(); topicsHttpRepository: TopicsHttpRepository = new TopicsHttpRepository();
importTopicModal = false;
constructor() { constructor() {
super(); super();
makeAutoObservable(this); makeAutoObservable(this);
} }
init = async (navigate?: NavigateFunction | undefined) => { init = async (navigate?: NavigateFunction | undefined) => {
this.modalCancel();
this.importTopicModal = false;
await this.mapOk("topics", this.topicsHttpRepository.getAllTopics()); 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())
);
} }