This commit is contained in:
IDONTSUDO 2024-04-23 15:56:52 +03:00
parent 7e25cc216a
commit c628cdb9af
20 changed files with 654 additions and 124 deletions

View file

@ -1,6 +1,7 @@
{
"cSpell.words": [
"Ведите",
"Навыки",
"typedataset"
]
}

View file

@ -1,3 +1,4 @@
import { BehaviorTreesPresentation } from "../../features/behavior_trees/behavior_trees";
import { DatasetsPresentation } from "../../features/datasets/datasets_presentation";
import { ProjectsPresentation } from "../../features/projects/projects_presentation";
// import { ProjectsPresentation } from "../../features/_projects/projects_presentation";
@ -6,4 +7,4 @@ import { Routes } from "../interfaces/router";
extensions();
export const httpRoutes: Routes[] = [new ProjectsPresentation(), new DatasetsPresentation()].map((el) => el.call());
export const httpRoutes: Routes[] = [new ProjectsPresentation(), new DatasetsPresentation(), new BehaviorTreesPresentation()].map((el) => el.call());

View file

@ -0,0 +1,147 @@
import { IsArray, IsString, ValidateNested } from "class-validator";
import { Type } from "class-transformer";
export interface SkillPoseEstimation {
SkillPackage: ISkillPackage;
Module: IModule;
Launch: ILaunch;
ROS2: IRos2;
BTAction: IBTAction[];
Interface: IInterface;
Settings: ISetting[];
xxx: IXxx;
}
export interface IBTAction {
name: string;
format: string;
type: string;
param: string[];
result: string[];
}
export interface IInterface {
Input: IPut[];
Output: IPut[];
}
export interface IPut {
name: string;
type: string;
}
export interface ILaunch {
executable: string;
}
export interface IModule {
name: string;
description: string;
}
export interface IRos2 {
node_name: string;
}
export interface ISetting {
name: string;
value: number | string;
}
export interface ISkillPackage {
name: string;
version: string;
format: string;
}
export interface IXxx {
cameraLink: string;
topicImage: string;
topicCameraInfo: string;
}
export class SkillPackage implements ISkillPackage {
@IsString()
name: string;
@IsString()
version: string;
@IsString()
format: string;
}
export class Module implements IModule {
@IsString()
name: string;
@IsString()
description: string;
}
export class BTAction implements IBTAction {
@IsString()
name: string;
@IsString()
format: string;
@IsString()
type: string;
@IsArray()
param: string[];
@IsArray()
result: string[];
}
export class Launch implements ILaunch {
@IsString()
executable: string;
}
export class Ros2 implements IRos2 {
@IsString()
node_name: string;
}
export class Put implements IPut {
@IsString()
name: string;
@IsString()
type: string;
}
export class Interface implements IInterface {
@ValidateNested()
@Type(() => Put)
Input: IPut[];
@ValidateNested()
@Type(() => Put)
Output: IPut[];
}
export class Setting implements ISetting {
name: string;
value: string | number;
}
export class Xxx implements IXxx {
cameraLink: string;
topicImage: string;
topicCameraInfo: string;
}
export class SkillModelPoseEstimation implements SkillPoseEstimation {
@ValidateNested()
@Type(() => SkillPackage)
SkillPackage: ISkillPackage;
@ValidateNested()
@Type(() => Module)
Module: IModule;
@ValidateNested()
@Type(() => Launch)
Launch: ILaunch;
@ValidateNested()
@Type(() => Ros2)
ROS2: IRos2;
@ValidateNested()
@IsArray()
@Type(() => BTAction)
BTAction: IBTAction[];
@ValidateNested()
@Type(() => Interface)
Interface: IInterface;
@ValidateNested()
@IsArray()
@Type(() => Setting)
Settings: ISetting[];
@ValidateNested()
@Type(() => Xxx)
xxx: IXxx;
}

View file

@ -0,0 +1,12 @@
import { CoreHttpController } from "../../core/controllers/http_controller";
import { DatasetValidationModel } from "../datasets/models/dataset_validation_model";
import { GetBehaviorTreeSkillsUseCase } from "./get_bt_usecase";
export class BehaviorTreesPresentation extends CoreHttpController<DatasetValidationModel> {
constructor() {
super({
url: "behavior/trees",
validationModel: DatasetValidationModel,
});
super.get(new GetBehaviorTreeSkillsUseCase().call);
}
}

View file

@ -0,0 +1,154 @@
import { Result } from "../../core/helpers/result";
export class GetBehaviorTreeSkillsUseCase {
call = () => {
return Result.ok({
skills: [
{
SkillPackage: {
name: "Robossembler",
version: "1.0",
format: "1",
},
Module: {
name: "PoseEstimation",
description: "Pose Estimation skill with DOPE",
},
Launch: {
executable: "pe_dope_lc.py",
},
ROS2: {
node_name: "lc_dope",
},
BTAction: [
{
name: "peConfigure",
format: "yaml",
type: "run",
param: ["object_name", "weights_file"],
result: ["Pose"],
},
{
name: "peStop",
format: "yaml",
type: "stop",
param: [],
result: [],
},
],
Interface: {
Input: [
{
name: "cameraLink",
type: "CAMERA",
},
{
name: "object_name",
type: "MODEL",
},
],
Output: [
{
name: "pose_estimation_topic",
type: "POSE",
},
],
},
Settings: [
{
name: "cameraLink",
value: "inner_rgbd_camera",
},
{
name: "pose",
value: "",
},
{
name: "publishDelay",
value: 0.5,
},
{
name: "tf2_send_pose",
value: 1,
},
{
name: "mesh_scale",
value: 0.001,
},
],
xxx: {
cameraLink: "inner_rgbd_camera",
topicImage: "/inner_rgbd_camera/image",
topicCameraInfo: "/inner_rgbd_camera/camera_info",
},
},
{
SkillPackage: {
name: "Robossembler",
version: "1.0",
format: "1",
},
Module: {
name: "ObjectDetection",
description: "Object detection skill with YOLOv8",
},
Launch: {
executable: "detection_lifecycle.py",
},
ROS2: {
node_name: "lc_detection",
},
BTAction: [
{
name: "odConfigure",
format: "yaml",
args: ["SettingPath", "server_name", "server_timeout"],
result: ["boundBox"],
},
{
name: "odStop",
format: "yaml",
args: ["server_name", "server_timeout"],
result: [],
},
],
Interface: {
Input: [
{
name: "cameraLink",
type: "string",
group: "STD_USER",
},
{
name: "topicImage",
type: "Image",
group: "sensor_msgs.msg",
},
],
Output: [
{
name: "boundBox",
type: "BoundBox",
group: ".msg",
},
],
},
Settings: [
{
name: "publishDelay",
value: 0.5,
},
{
name: "server_timeout",
value: 1000,
},
{
name: "server_name",
value: "/object_detection/change_state",
},
],
},
],
});
};
}

View file

@ -0,0 +1,183 @@
import { IsArray, IsString, ValidateNested } from "class-validator";
import { Type } from "class-transformer";
import { ISkillView } from "../../features/behavior_tree_builder/presentation/ui/skill_tree/skill_tree";
import { v4 } from "uuid";
export interface ISkillPoseEstimation {
SkillPackage: ISkillPackage;
Module: IModule;
Launch: ILaunch;
ROS2: IRos2;
BTAction: IBTAction[];
Interface: IInterface;
Settings: ISetting[];
xxx: IXxx;
}
export interface IBTAction {
name: string;
format: string;
type: string;
param: string[];
result: string[];
}
export interface IInterface {
Input: IPut[];
Output: IPut[];
}
export interface IPut {
name: string;
type: string;
}
export interface ILaunch {
executable: string;
}
export interface IModule {
name: string;
description: string;
}
export interface IRos2 {
node_name: string;
}
export interface ISetting {
name: string;
value: number | string;
}
export interface ISkillPackage {
name: string;
version: string;
format: string;
}
export interface IXxx {
cameraLink: string;
topicImage: string;
topicCameraInfo: string;
}
export class SkillPackage implements ISkillPackage {
@IsString()
name: string;
@IsString()
version: string;
@IsString()
format: string;
}
export class Module implements IModule {
@IsString()
name: string;
@IsString()
description: string;
}
export class BTAction implements IBTAction {
@IsString()
name: string;
@IsString()
format: string;
@IsString()
type: string;
@IsArray()
param: string[];
@IsArray()
result: string[];
}
export class Launch implements ILaunch {
@IsString()
executable: string;
}
export class Ros2 implements IRos2 {
@IsString()
node_name: string;
}
export class Put implements IPut {
@IsString()
name: string;
@IsString()
type: string;
}
export class Interface implements IInterface {
@ValidateNested()
@Type(() => Put)
Input: IPut[];
@ValidateNested()
@Type(() => Put)
Output: IPut[];
}
export class Setting implements ISetting {
name: string;
value: string | number;
}
export class Xxx implements IXxx {
cameraLink: string;
topicImage: string;
topicCameraInfo: string;
}
export class SkillModelPoseEstimation implements ISkillPoseEstimation {
@ValidateNested()
@Type(() => SkillPackage)
SkillPackage: ISkillPackage;
@ValidateNested()
@Type(() => Module)
Module: IModule;
@ValidateNested()
@Type(() => Launch)
Launch: ILaunch;
@ValidateNested()
@Type(() => Ros2)
ROS2: IRos2;
@ValidateNested()
@IsArray()
@Type(() => BTAction)
BTAction: IBTAction[];
@ValidateNested()
@Type(() => Interface)
Interface: IInterface;
@ValidateNested()
@IsArray()
@Type(() => Setting)
Settings: ISetting[];
@ValidateNested()
@Type(() => Xxx)
xxx: IXxx;
}
export class Skills {
@IsArray()
@Type(() => SkillModelPoseEstimation)
skills: SkillModelPoseEstimation[];
toSkillView(): ISkillView[] {
return this.skills.map((el) => {
return {
name: el.Module.name,
children: el.BTAction.map((act) => {
// return { name: `${el.Module.name} - ${act.name}` };
return { name: act.name, uuid: v4() };
}),
};
});
}
getSkillDo(name: string) {
return this.skills.reduce((acc, el) => {
if (el.BTAction.find((el) => el.name.isEqual(name))) {
acc = el.Module.name;
}
return acc;
}, "error");
}
getSkillsNames() {
return this.skills
.map((el) => {
return el.BTAction.map((act) => {
return { name: act.name };
});
})
.flat(1);
}
}

View file

@ -21,6 +21,7 @@ import DetailsScreen, { DetailsScreenPath } from "../../features/details/details
import { AssemblesScreen, AssemblesScreenPath } from "../../features/assembles/assembles_screen";
import SimulationScreen, { SimulationScreenPath } from "../../features/simulations/simulations_screen";
import { EstimateScreen, EstimateScreenPath } from "../../features/estimate/estimate_screen";
import { SkillPath, SkillScreen } from "../../features/skils/skills_screen";
const idURL = ":id";
@ -67,9 +68,12 @@ export const router = createBrowserRouter([
path: SimulationScreenPath,
element: <SimulationScreen />,
},
{
path: EstimateScreenPath,
element: <EstimateScreen />,
},
{
path: SkillPath,
element: <SkillScreen />,
},
]);

View file

@ -31,3 +31,6 @@ export function CoreButton(props: IButtonProps) {
</div>
);
}

View file

@ -10,6 +10,7 @@ import { DetailsScreenPath } from "../../../features/details/details_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 { SkillPath as SkillScreenPath } from "../../../features/skils/skills_screen";
export interface IBlockProps {
name: string;
isActive: boolean;
@ -45,6 +46,7 @@ const Block = (props: IBlockProps) => {
export interface IMainPageProps {
page: string;
bodyChildren?: JSX.Element;
panelChildren?: JSX.Element;
isLoading?: boolean;
}
export const MainPage = (props: IMainPageProps) => {
@ -53,7 +55,8 @@ export const MainPage = (props: IMainPageProps) => {
{ name: "Сборки", path: AssemblesScreenPath, icon: "Assembly" },
{ name: "Датасеты", path: DatasetsScreenPath, icon: "Datasets" },
{ name: "Сцена", path: SceneManagerPath, icon: "Layers" },
{ name: "Навыки", path: BehaviorTreeBuilderPath, icon: "Rocket" },
{ name: "Навыки", path: SkillScreenPath, icon: "Layers" },
{ name: "Поведение", path: BehaviorTreeBuilderPath, icon: "Rocket" },
{ name: "Симуляция", path: SimulationScreenPath, icon: "Simulation" },
{ name: "Оценка", path: EstimateScreenPath, icon: "Grade" },
];
@ -118,7 +121,9 @@ export const MainPage = (props: IMainPageProps) => {
</div>
) : (
<>
<div style={{ width: 241, height: window.innerHeight, backgroundColor: "#F7F2FA", borderRadius: 16 }}> </div>
<div style={{ width: 241, height: window.innerHeight, backgroundColor: "#F7F2FA", borderRadius: 16 }}>
{props.panelChildren}{" "}
</div>
{props.bodyChildren}
</>
)}

View file

@ -0,0 +1,9 @@
import { Result } from "../../../core/helper/result";
import { Skills } from "../../../core/model/skill_model";
import { HttpError, HttpMethod, HttpRepository } from "../../../core/repository/http_repository";
export class BehaviorTreeBuilderRepository extends HttpRepository {
getBtSkills = async ():Promise<Result<HttpError, Skills>> => {
return await this._jsonToClassInstanceRequest<Skills>(HttpMethod.GET, "/behavior/trees", Skills) as unknown as Promise<Result<HttpError, Skills>>;
};
}

View file

@ -3,6 +3,7 @@ import { NodeEditor } from "rete";
import { AreaExtra, Schemes } from "../presentation/ui/editor/editor";
import { Result } from "../../../core/helper/result";
import { AreaPlugin } from "rete-area-plugin";
import { Skills } from "../../../core/model/skill_model";
export interface BtDrawDragAndDropView {
x: number;
@ -15,21 +16,31 @@ export class BtNodeView extends TypedEvent<BtDrawDragAndDropView> {}
export class ReteObserver extends TypedEvent<any> {}
export class BtBuilderModel {
public static result = "";
static fromReteScene(editor: NodeEditor<Schemes>, area: AreaPlugin<Schemes, AreaExtra>): Result<string, string> {
static fromReteScene(
editor: NodeEditor<Schemes>,
area: AreaPlugin<Schemes, AreaExtra>,
skills?: Skills
): Result<string, string> {
try {
this.result = "";
this.getFirstSequence(editor).map((sortedSequence) => {
const firstNodeId = sortedSequence.getKeyFromValueIsExists(1) as string;
this.findSequence(firstNodeId, editor, sortedSequence, 2);
this.result += `<${this.getNodeLabelAtId(editor, firstNodeId)} id="${firstNodeId}">`;
this.toXML(sortedSequence as Map<string, number>, editor, area, firstNodeId);
this.result += `</${this.getNodeLabelAtId(editor, firstNodeId)}>`;
this.result += `<${this.getNodeLabelAtId(editor, firstNodeId, skills)}>`;
this.toXML(sortedSequence as Map<string, number>, editor, area, firstNodeId, skills);
this.result += `</${this.getNodeLabelAtId(editor, firstNodeId, skills)}>`;
});
return Result.ok(this.result);
} catch (error) {
return Result.error("BtBuilderModel fromReteScene error");
}
}
public static getNodeLabelAtId(editor: NodeEditor<Schemes>, id: string) {
public static getNodeLabelAtId(editor: NodeEditor<Schemes>, id: string, skills?: Skills) {
if (skills?.getSkillsNames().find((el) => el.name.isEqual(editor.getNode(id).label))) {
return `Action ID="RbsBtAction" do="${skills.getSkillDo(editor.getNode(id).label)}" command="${
editor.getNode(id).label
}" server_name="rbs_interface" server_timeout="1000"`;
}
return editor.getNode(id).label;
}
@ -37,18 +48,20 @@ export class BtBuilderModel {
sortedSequence: Map<string, number>,
editor: NodeEditor<Schemes>,
area: AreaPlugin<Schemes, AreaExtra>,
activeElementId = ""
activeElementId = "",
skills?: Skills
) {
editor.getConnections().forEach((el) => {
if (el.source === activeElementId) {
this.result += `<${this.getNodeLabelAtId(editor, el.target)} id="${el.target}">`;
this.toXML(sortedSequence, editor, area, el.target);
this.result += `<${this.getNodeLabelAtId(editor, el.target, skills)}>`;
this.toXML(sortedSequence, editor, area, el.target, skills);
this.result += `</${this.getNodeLabelAtId(editor, el.target)}>`;
}
});
}
public static getBtPriorities(ids: string[]) {}
public static findSequence(
nodeId: string,
editor: NodeEditor<Schemes>,

View file

@ -1,51 +1,37 @@
import * as React from "react";
import { CoreText, CoreTextType } from "../../../core/ui/text/text";
import { Button, Input } from "antd";
import { useRete } from "rete-react-plugin";
import { createEditor } from "./ui/editor/editor";
import { SkillTree } from "./ui/skill_tree/skill_tree";
import { BehaviorTreeBuilderStore } from "./behavior_tree_builder_store";
import { MainPage } from "../../../core/ui/pages/main_page";
import { CoreButton } from "../../../core/ui/button/button";
import { observer } from "mobx-react-lite";
export const behaviorTreeBuilderScreenPath = "behavior/tree/screen/path";
const skills = {
name: "",
children: [
{
name: "Actions",
children: [{ name: "MoveToPose", interface: "Vector3", out: "vo" }],
},
{
name: "Control",
children: [
{ name: "Fallback", interface: "Vector3", out: "vo" },
{ name: "Sequence", interface: "Vector3", out: "vo" },
],
},
],
};
export const behaviorTreeBuilderStore = new BehaviorTreeBuilderStore();
export const BehaviorTreeBuilderPath = "/behavior/tree/";
export function BehaviorTreeBuilderScreen() {
export const BehaviorTreeBuilderScreen = observer(() => {
const store = behaviorTreeBuilderStore;
const [ref] = useRete(createEditor);
// @ts-expect-error
const [ref] = useRete<HTMLDivElement>(createEditor);
React.useEffect(() => {
store.init();
store.dragZoneSetOffset(
// @ts-expect-error
ref.current.offsetTop,
// @ts-expect-error
ref.current.offsetLeft,
// @ts-expect-error
ref.current.clientWidth,
// @ts-expect-error
ref.current.clientHeight
);
if (ref.current)
store.dragZoneSetOffset(
// @ts-expect-error
ref.current.offsetTop,
// @ts-expect-error
ref.current.offsetLeft,
// @ts-expect-error
ref.current.clientWidth,
// @ts-expect-error
ref.current.clientHeight
);
return () => {
store.dispose();
};
@ -54,11 +40,17 @@ export function BehaviorTreeBuilderScreen() {
return (
<MainPage
page={"Навыки"}
panelChildren={
<>
{store.skills ? <SkillTree skills={store.skillTree} dragEnd={store.dragEnd} /> : null}
<div style={{ width: 100, height: 40 }}>
<CoreButton onClick={() => store.saveBt()} text="SAVE BT" />
</div>
</>
}
bodyChildren={
<>
<div style={{ display: "flex", width: "100%" }}>
{/* <SkillTree dragEnd={store.dragEnd} skills={skills} /> */}
<div
ref={ref}
style={{
@ -72,4 +64,4 @@ export function BehaviorTreeBuilderScreen() {
}
/>
);
}
});

View file

@ -7,6 +7,9 @@ import { NodeEditor } from "rete";
import { AreaExtra, Schemes } from "./ui/editor/editor";
import { AreaPlugin } from "rete-area-plugin";
import { NodeBehaviorTree } from "../model/node_behavior_tree";
import { BehaviorTreeBuilderRepository } from "../data/behavior_tree_builder_repository";
import { Skills } from "../../../core/model/skill_model";
import { ISkillView } from "./ui/skill_tree/skill_tree";
interface I2DArea {
x: number;
@ -20,9 +23,11 @@ export class BehaviorTreeBuilderStore extends UiErrorState<HttpError> {
this.reteNode?.emit("200");
}
validateBt() {}
skills?: Skills;
area?: I2DArea;
btNodeView: BtNodeView = new BtNodeView();
reteNode?: ReteObserver;
behaviorTreeBuilderRepository = new BehaviorTreeBuilderRepository();
canRun = true;
nodes: NodeBehaviorTree[] = [
{
@ -32,64 +37,24 @@ export class BehaviorTreeBuilderStore extends UiErrorState<HttpError> {
inputs: ["a"],
position: { x: -488.1303402823156, y: -227.90861570911895 },
},
{
label: "Sequence",
id: "2",
outputs: ["a"],
inputs: ["a"],
connectTo: "1",
position: { x: 119.95735514023244, y: -182.24902817216878 },
},
{
label: "Sequence",
id: "6",
outputs: ["a"],
inputs: ["a"],
connectTo: "2",
position: { x: 402.06111561958505, y: -100.97814086372247 },
},
{
label: "MoveToPose",
id: "7",
outputs: ["a"],
inputs: ["a"],
connectTo: "6",
position: { x: 932.0688448287292, y: 90.10780461923443 },
},
{
label: "MoveToPose",
id: "8",
outputs: ["a"],
inputs: ["a"],
connectTo: "6",
position: { x: 898.1684213039546, y: -119.80545806921208 },
},
{
label: "MoveToPose",
id: "3",
outputs: [],
inputs: ["a"],
connectTo: "1",
position: { x: 208.65749743442188, y: 16.256489050033785 },
},
{
label: "MoveToPose",
id: "4",
outputs: [],
inputs: ["a"],
connectTo: "1",
position: { x: -50.46426323140673, y: 99.22642447650014 },
},
{
label: "Sequence",
id: "5",
outputs: ["a"],
inputs: ["a"],
connectTo: "1",
position: { x: -234.54554662642457, y: 245.4012710608967 },
},
];
skillTree: ISkillView = {
name: "",
children: [
{
name: "Actions",
children: [],
},
{
name: "Control",
children: [
{ name: "Fallback", interface: "Vector3", out: "vo" },
{ name: "Sequence", interface: "Vector3", out: "vo" },
],
},
],
};
constructor() {
super();
makeAutoObservable(this);
@ -99,10 +64,9 @@ export class BehaviorTreeBuilderStore extends UiErrorState<HttpError> {
JSON.parse(value) as BtNodeView[];
}
bt = async (editor: NodeEditor<Schemes>, area: AreaPlugin<Schemes, AreaExtra>) => {
(await BtBuilderModel.fromReteScene(editor, area)).fold(
(await BtBuilderModel.fromReteScene(editor, area, this.skills)).fold(
(s) => {
console.log(
xmlFormat(`<?xml version="1.0" encoding="UTF-8"?>
console.log(xmlFormat(`<?xml version="1.0" encoding="UTF-8"?>
<root main_tree_to_execute="Main">
<BehaviorTree ID="Main">
${s}
@ -117,15 +81,12 @@ export class BehaviorTreeBuilderStore extends UiErrorState<HttpError> {
</Action>
</TreeNodesModel>
</root>`)
);
</root>`));
},
(_) => _
);
};
copyBt = () => {
this.reteNode?.emit("200");
};
errorHandingStrategy: (error: HttpError) => void;
dragEnd = (e: EventTarget) => {
@ -155,7 +116,20 @@ export class BehaviorTreeBuilderStore extends UiErrorState<HttpError> {
}
}
async init(): Promise<any> {}
async init(): Promise<any> {
(await this.behaviorTreeBuilderRepository.getBtSkills()).fold(
(model) => {
this.skills = model;
this.skillTree.children = this.skillTree.children?.map((el) => {
if (el.name === "Actions") {
el.children = model.toSkillView();
}
return el;
});
},
(e) => console.log(e)
);
}
dragZoneSetOffset(offsetTop: number, offsetWidth: number, width: number, height: number) {
this.area = {
x: offsetTop,

View file

@ -93,7 +93,7 @@ export function CustomNode<Scheme extends ClassicScheme>(props: Props<Scheme>) {
const controls = Object.entries(props.data.controls);
const selected = props.data.selected || false;
const { id, label, width, height } = props.data;
console.log(label)
sortByIndex(inputs);
sortByIndex(outputs);
sortByIndex(controls);

View file

@ -21,6 +21,7 @@ export async function createEditor(container: HTMLElement) {
behaviorTreeBuilderStore.btNodeView.on(async (event) => {
setTimeout(async () => {
console.log(event)
const node = new ClassicPreset.Node(event.name);
const { x, y } = areaContainer.area.pointer;
@ -33,6 +34,7 @@ export async function createEditor(container: HTMLElement) {
});
observer.on(() => {
console.log(200)
behaviorTreeBuilderStore.bt(editor, areaContainer);
});

View file

@ -8,7 +8,7 @@ const { RefSocket, RefControl } = Presets.classic;
type NodeExtraData = { width?: number; height?: number };
export const NodeStyles = styled.div<NodeExtraData & { selected: boolean; styles?: (props: any) => any }>`
background: blue;
background: red;
border: 2px solid grey;
cursor: pointer;
@ -97,7 +97,6 @@ export function SequenceNode<Scheme extends ClassicScheme>(props: Props<Scheme>)
const selected = props.data.selected || false;
const { id, label, width, height } = props.data;
sortByIndex(inputs);
sortByIndex(outputs);
sortByIndex(controls);

View file

@ -2,8 +2,16 @@ import * as React from "react";
import TreeView, { EventCallback, IBranchProps, INode, LeafProps, flattenTree } from "react-accessible-treeview";
import { IFlatMetadata } from "react-accessible-treeview/dist/TreeView/utils";
import { CallBackEventTarget } from "../../../../../core/extensions/extensions";
export interface ISkillView {
name: string;
children?: ISkillView[];
id?: string;
interface?: string;
out?: string;
}
export interface ISkillTreeProps {
skills: any;
skills: ISkillView;
dragEnd: CallBackEventTarget;
}
@ -16,12 +24,12 @@ interface IRefListerProps {
}
export const RefListener = (props: IRefListerProps) => {
const ref = React.useRef<HTMLDataElement>(null);
const ref = React.useRef<HTMLSpanElement>(null);
React.useEffect(() => {
if (ref.current) {
ref.current.addEventListener("dragend", (e) => {
// @ts-expect-error
if (e.target.innerHTML) {
if (e && e.target && e.target.innerHTML) {
// @ts-expect-error
props.dragEnd(e);
}
@ -36,13 +44,13 @@ export const RefListener = (props: IRefListerProps) => {
props.handleSelect(e);
}}
/>
<span ref={ref} style={{ color: "white" }} draggable="true">
<span ref={ref} style={{ color: "black" }} draggable="true">
{props.element.name}
</span>
</div>
);
};
export function SkillTree(props: ISkillTreeProps) {
export const SkillTree = (props: ISkillTreeProps) => {
return (
<div>
<TreeView
@ -66,4 +74,4 @@ export function SkillTree(props: ISkillTreeProps) {
/>
</div>
);
}
};

View file

@ -0,0 +1,20 @@
import { MainPage } from "../../core/ui/pages/main_page";
export const SkillPath = "/skills";
export const SkillScreen = () => {
return (
<>
<MainPage
page={"Навыки"}
bodyChildren={
<>
<div style={{ display: "flex", width: "100%" }}>
</div>
</>
}
/>
</>
);
};

View file

@ -0,0 +1,3 @@
export class SkillStore{
}

View file

@ -10,7 +10,7 @@ export interface ISocketListerProps {
export const SocketLister = observer((props: ISocketListerProps) => {
return (
<div>
{socketListerStore.socketHasDisconnect ? (
{/* {socketListerStore.socketHasDisconnect ? (
<ReloadIcon
onClick={() => {
socketListerStore.reconnect();
@ -25,7 +25,7 @@ export const SocketLister = observer((props: ISocketListerProps) => {
/>
) : (
<></>
)}
)} */}
{props.children}
</div>