bt builder
This commit is contained in:
parent
5162612a77
commit
c5ae89d18a
52 changed files with 1013 additions and 441 deletions
|
@ -63,11 +63,20 @@ export const ArrayExtensions = () => {
|
|||
// eslint-disable-next-line no-extend-native
|
||||
Array.prototype.rFind = function (predicate) {
|
||||
const result = this.find(predicate as any);
|
||||
console.log(result)
|
||||
if (result === undefined) {
|
||||
return Result.error(undefined);
|
||||
}
|
||||
return Result.ok(result);
|
||||
};
|
||||
}
|
||||
if ([].maxLength === undefined) {
|
||||
// eslint-disable-next-line no-extend-native
|
||||
Array.prototype.maxLength = function (length) {
|
||||
if (this.length > length) {
|
||||
return this;
|
||||
} else {
|
||||
return this.slice(0, length);
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
|
|
|
@ -12,7 +12,6 @@ export type OptionalProperties<T> = {
|
|||
[P in keyof T]?: T[P];
|
||||
};
|
||||
|
||||
|
||||
declare global {
|
||||
interface Array<T> {
|
||||
// @strict: The parameter is determined whether the arrays must be exactly the same in content and order of this relationship or simply follow the same requirements.
|
||||
|
@ -22,10 +21,8 @@ declare global {
|
|||
isNotEmpty(): boolean;
|
||||
hasIncludeElement(element: T): boolean;
|
||||
repeat(quantity: number): Array<T>;
|
||||
rFind<T>(
|
||||
predicate: (value: T, index: number, obj: never[]) => boolean,
|
||||
thisArg?: any
|
||||
): Result<void, T>;
|
||||
rFind<T>(predicate: (value: T, index: number, obj: never[]) => boolean, thisArg?: any): Result<void, T>;
|
||||
maxLength(length: number): Array<T>;
|
||||
}
|
||||
interface Number {
|
||||
fromArray(): number[];
|
||||
|
@ -43,7 +40,10 @@ declare global {
|
|||
replaceMany(searchValues: string[], replaceValue: string): string;
|
||||
isEqual(str: string): boolean;
|
||||
isEqualMany(str: string[]): boolean;
|
||||
hasPattern(pattern: string): boolean;
|
||||
hasNoPattern(pattern: string): boolean;
|
||||
}
|
||||
|
||||
interface Map<K, V> {
|
||||
addValueOrMakeCallback(key: K, value: V, callBack: CallBackVoidFunction): void;
|
||||
getKeyFromValueIsExists(value: V): K | undefined;
|
||||
|
@ -51,6 +51,7 @@ declare global {
|
|||
keysToJson(): string;
|
||||
toArray(): V[];
|
||||
getPredicateValue(callBack: (value: V) => boolean): K[];
|
||||
incrementValue(key: K): void;
|
||||
}
|
||||
interface Vector3 {}
|
||||
}
|
||||
|
|
|
@ -58,4 +58,14 @@ export const MapExtensions = () => {
|
|||
return result;
|
||||
};
|
||||
}
|
||||
if (Map.prototype.incrementValue === undefined) {
|
||||
// eslint-disable-next-line no-extend-native
|
||||
Map.prototype.incrementValue = function (key) {
|
||||
if (this.get(key)) {
|
||||
this.set(key, this.get(key) + 1);
|
||||
} else {
|
||||
this.set(key, 1);
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
|
|
|
@ -36,4 +36,14 @@ export const StringExtensions = () => {
|
|||
return false;
|
||||
};
|
||||
}
|
||||
if ("".hasPattern === undefined) {
|
||||
String.prototype.hasPattern = function (pattern) {
|
||||
return new RegExp(pattern).test(this as string);
|
||||
};
|
||||
}
|
||||
if ("".hasNoPattern === undefined) {
|
||||
String.prototype.hasNoPattern = function (pattern) {
|
||||
return !this.hasPattern(pattern);
|
||||
};
|
||||
}
|
||||
};
|
||||
|
|
|
@ -1,9 +1,21 @@
|
|||
import { IsArray, IsString, ValidateNested } from "class-validator";
|
||||
import { IsArray, IsOptional, 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";
|
||||
import { Result } from "../helper/result";
|
||||
import clone from "just-clone";
|
||||
|
||||
export interface ISkillPoseEstimation {
|
||||
export interface IDependency {
|
||||
skills: ISkillDependency[];
|
||||
}
|
||||
|
||||
export interface ISkillDependency {
|
||||
sid: string;
|
||||
dependency: Object;
|
||||
}
|
||||
|
||||
export interface ISkill {
|
||||
sid?: string;
|
||||
SkillPackage: ISkillPackage;
|
||||
Module: IModule;
|
||||
Launch: ILaunch;
|
||||
|
@ -14,17 +26,21 @@ export interface ISkillPoseEstimation {
|
|||
xxx: IXxx;
|
||||
}
|
||||
export interface IWeightsDependency {
|
||||
objectName: string;
|
||||
weightsPath: string;
|
||||
weights_name:string;
|
||||
object_name: string;
|
||||
weights_file: string;
|
||||
dimensions: number[];
|
||||
}
|
||||
|
||||
export interface IParam {
|
||||
type: string;
|
||||
dependency: IWeightsDependency;
|
||||
dependency: Object;
|
||||
}
|
||||
export interface IBTAction {
|
||||
name: string;
|
||||
format: string;
|
||||
// TODO: Нужно выпилить его отсюда
|
||||
// sid?: string;
|
||||
type: string;
|
||||
param: IParam[];
|
||||
result: string[];
|
||||
|
@ -91,6 +107,7 @@ export class BTAction implements IBTAction {
|
|||
format: string;
|
||||
@IsString()
|
||||
type: string;
|
||||
sid?: string;
|
||||
@IsArray()
|
||||
param: IParam[];
|
||||
@IsArray()
|
||||
|
@ -127,7 +144,10 @@ export class Xxx implements IXxx {
|
|||
topicImage: string;
|
||||
topicCameraInfo: string;
|
||||
}
|
||||
export class SkillModelPoseEstimation implements ISkillPoseEstimation {
|
||||
export class SkillModel implements ISkill {
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
sid?: string;
|
||||
@ValidateNested()
|
||||
@Type(() => SkillPackage)
|
||||
SkillPackage: ISkillPackage;
|
||||
|
@ -154,12 +174,71 @@ export class SkillModelPoseEstimation implements ISkillPoseEstimation {
|
|||
@ValidateNested()
|
||||
@Type(() => Xxx)
|
||||
xxx: IXxx;
|
||||
static empty() {
|
||||
const skillModel = new SkillModel();
|
||||
skillModel.BTAction = [];
|
||||
return skillModel;
|
||||
}
|
||||
public static isEmpty(skill: SkillModel): Result<void, SkillModel> {
|
||||
if (skill.BTAction.isEmpty()) {
|
||||
return Result.error(undefined);
|
||||
}
|
||||
return Result.ok(Object.assign(skill, {}));
|
||||
}
|
||||
|
||||
public getSid = () => this.sid;
|
||||
public setSid = (sid: string) => {
|
||||
const result = clone(this);
|
||||
result.sid = sid;
|
||||
return result;
|
||||
};
|
||||
}
|
||||
|
||||
export class SkillDependency implements IDependency {
|
||||
constructor(public skills: ISkillDependency[]) {}
|
||||
static empty() {
|
||||
return new SkillDependency([]);
|
||||
}
|
||||
static isEmpty = (skill: SkillDependency) => {
|
||||
if (skill.skills.isEmpty()) {
|
||||
return Result.error(undefined);
|
||||
}
|
||||
return Result.ok(skill);
|
||||
};
|
||||
}
|
||||
|
||||
export class Skills {
|
||||
@IsArray()
|
||||
@Type(() => SkillModelPoseEstimation)
|
||||
skills: SkillModelPoseEstimation[];
|
||||
@Type(() => SkillModel)
|
||||
skills: SkillModel[];
|
||||
validation = (): Result<string[], void> => {
|
||||
const errors: string[] = [];
|
||||
this.skills.forEach((skill) => {
|
||||
skill.BTAction.forEach((action) => {
|
||||
if (action.param.isNotEmpty()) {
|
||||
action.param.forEach((param) => {
|
||||
if (Object.keys(param.dependency).isEmpty()) {
|
||||
errors.push(param.type);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
if (errors.isNotEmpty()) {
|
||||
return Result.error(errors);
|
||||
}
|
||||
return Result.ok(undefined);
|
||||
};
|
||||
skillBySid = (sid: string) =>
|
||||
SkillModel.isEmpty(
|
||||
this.skills.reduce<SkillModel>((acc, el) => {
|
||||
if (el.sid?.isEqual(sid)) {
|
||||
acc = el;
|
||||
}
|
||||
return acc;
|
||||
}, SkillModel.empty())
|
||||
);
|
||||
|
||||
toSkillView = (): ISkillView[] =>
|
||||
this.skills.map((el) => {
|
||||
return {
|
||||
|
@ -169,6 +248,20 @@ export class Skills {
|
|||
}),
|
||||
};
|
||||
});
|
||||
getSkill = (name: string) =>
|
||||
SkillModel.isEmpty(
|
||||
this.skills.reduce<SkillModel>((acc, el) => {
|
||||
if (el.BTAction.find((el) => el.name.isEqual(name))) {
|
||||
el.BTAction.map((action) => {
|
||||
action.param.map((param) => {
|
||||
return param;
|
||||
});
|
||||
});
|
||||
acc = el;
|
||||
}
|
||||
return acc;
|
||||
}, SkillModel.empty())
|
||||
);
|
||||
|
||||
getSkilsOut = (name: string) =>
|
||||
this.skills
|
||||
|
@ -207,7 +300,7 @@ export class Skills {
|
|||
|
||||
getForms = (skillLabel: string) =>
|
||||
this.skills
|
||||
.reduce<SkillModelPoseEstimation[]>((acc, el) => {
|
||||
.reduce<SkillModel[]>((acc, el) => {
|
||||
if (el.BTAction.find((el) => el.name.isEqual(skillLabel))) {
|
||||
acc.push(el);
|
||||
}
|
||||
|
@ -217,17 +310,83 @@ export class Skills {
|
|||
.flat(1)
|
||||
.flat(1)
|
||||
.filter((el) => el !== "");
|
||||
getDependencyBySkillLabelAndType = <T>(skillLabel: string, skillType: string) =>
|
||||
|
||||
getDependencyBySkillLabelAndType = <T>(skillType: string, sid: string) =>
|
||||
this.skills
|
||||
.reduce<SkillModelPoseEstimation[]>((acc, el) => {
|
||||
if (el.BTAction.find((el) => el.name.isEqual(skillLabel))) {
|
||||
acc.push(el);
|
||||
.reduce<Object[]>((acc, skill) => {
|
||||
if (skill.sid?.isEqual(sid)) {
|
||||
skill.BTAction.map((action) => {
|
||||
action.param.map((param) => {
|
||||
if (param.type.isEqual(skillType)) {
|
||||
acc.push(param.dependency);
|
||||
}
|
||||
return param;
|
||||
});
|
||||
return action;
|
||||
});
|
||||
}
|
||||
|
||||
return acc;
|
||||
}, [])
|
||||
.map((el) => el.BTAction.map((act) => act.param.filter((el) => el.type.isEqual(skillType))))
|
||||
.flat(1)
|
||||
.flat(1)
|
||||
.map((el) => el.dependency)
|
||||
.at(0) as T;
|
||||
static isEmpty(model: Skills): Result<void, void> {
|
||||
if (model.skills.isEmpty()) {
|
||||
return Result.error(undefined);
|
||||
}
|
||||
return Result.ok(undefined);
|
||||
}
|
||||
static empty() {
|
||||
const skills = new Skills();
|
||||
skills.skills = [];
|
||||
return skills;
|
||||
}
|
||||
|
||||
public dependencyIsFilled = (skillType: string, sid: string) =>
|
||||
this.skills.reduce((acc, skill) => {
|
||||
if (skill.sid?.isEqual(sid)) {
|
||||
skill.BTAction.forEach((action) => {
|
||||
action.param.forEach((param) => {
|
||||
if (param.type.isEqual(skillType)) {
|
||||
// console.log('SKILL TYPE')
|
||||
// console.log(skillType);
|
||||
// console.log("SID")
|
||||
// console.log(sid)
|
||||
// console.log("DEPENDENCY")
|
||||
// console.log(param.dependency)
|
||||
acc = Object.keys(param.dependency).isNotEmpty();
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
return acc;
|
||||
}, false);
|
||||
|
||||
getAllSids = () =>
|
||||
this.skills.reduce((acc, skill) => {
|
||||
skill.BTAction.forEach((action) =>
|
||||
action.param.forEach((param) => {
|
||||
// acc.incrementValue(param.sid ?? "empty");
|
||||
return param;
|
||||
})
|
||||
);
|
||||
return acc;
|
||||
}, new Map<string, number>());
|
||||
|
||||
deleteSid(sid: string): SkillModel[] {
|
||||
return this.skills.filter((skill) => !skill.sid?.isEqual(sid));
|
||||
}
|
||||
updateSkill = (skill: SkillModel) => {
|
||||
console.log(skill);
|
||||
this.skills = this.skills.map((el) => {
|
||||
if (el.sid?.isEqual(skill.sid ?? "")) {
|
||||
el = skill;
|
||||
}
|
||||
return el;
|
||||
});
|
||||
};
|
||||
skillHasForm = (label: string): boolean => {
|
||||
// TODO:NEED IMPLEMENTS
|
||||
return true;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -96,4 +96,5 @@ export class HttpRepository {
|
|||
return Result.error(new HttpError(error, 0));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@ import { FormViewModel, InputBuilderViewModel, InputType } from "./form_view_mod
|
|||
import { observer } from "mobx-react-lite";
|
||||
import { FormBuilderStore } from "./form_builder_store";
|
||||
import { FormBuilderValidationModel } from "../../../features/dataset/dataset_model";
|
||||
import { SelectCore } from "../select/select";
|
||||
import { CoreSelect } from "../select/select";
|
||||
import { CoreInput } from "../input/input";
|
||||
import { Icon } from "../icons/icons";
|
||||
import { CoreText, CoreTextType } from "../text/text";
|
||||
|
@ -41,7 +41,7 @@ export const FormBuilder = observer((props: IFormBuilder) => {
|
|||
if (element.type.isEqual(InputType.ENUM)) {
|
||||
const values = element.values as string[];
|
||||
return (
|
||||
<SelectCore
|
||||
<CoreSelect
|
||||
items={values}
|
||||
value={element.totalValue ?? element.defaultValue}
|
||||
onChange={(value) => store.changeTotalValue(element.id, value)}
|
||||
|
@ -88,7 +88,7 @@ export const FormBuilder = observer((props: IFormBuilder) => {
|
|||
if (subSubArrayItem.type.isEqual(InputType.ENUM)) {
|
||||
return (
|
||||
<>
|
||||
<SelectCore
|
||||
<CoreSelect
|
||||
items={subSubArrayItem.values?.map((el) => String(el)) ?? []}
|
||||
value={subSubArrayItem.totalValue ?? subSubArrayItem.defaultValue}
|
||||
onChange={(value) => store.changeTotalSubValue(element.id, subIndex, value)}
|
||||
|
|
|
@ -5,6 +5,7 @@ import { IStyle } from "../../model/style";
|
|||
interface IInputProps extends IStyle {
|
||||
label: string;
|
||||
value?: string;
|
||||
subLabel?: React.ReactNode;
|
||||
onChange?: (value: string) => void;
|
||||
validation?: (value: string) => boolean;
|
||||
error?: string;
|
||||
|
@ -19,8 +20,7 @@ export const CoreInput = (props: IInputProps) => {
|
|||
ref.current.innerText = value;
|
||||
setAppendInnerText(false);
|
||||
}
|
||||
}, [ref, value, isAppendInnerText, setAppendInnerText]);
|
||||
|
||||
}, [ref, value, isAppendInnerText, setAppendInnerText, props]);
|
||||
|
||||
return (
|
||||
<div
|
||||
|
@ -47,12 +47,13 @@ export const CoreInput = (props: IInputProps) => {
|
|||
color: "#1D1B20",
|
||||
height: 24,
|
||||
width: "100%",
|
||||
userSelect: 'none',
|
||||
outline:'none'
|
||||
userSelect: "none",
|
||||
outline: "none",
|
||||
}}
|
||||
onChange={(e) => {
|
||||
const val = e.target.value;
|
||||
setValue(val)
|
||||
|
||||
setValue(val);
|
||||
if (val) {
|
||||
if (props.validation !== undefined && props.validation(val) && props.onChange) {
|
||||
props.onChange(val);
|
||||
|
|
|
@ -50,6 +50,7 @@ export interface IMainPageProps {
|
|||
panelChildren?: JSX.Element;
|
||||
panelStyle?: React.CSSProperties;
|
||||
isLoading?: boolean;
|
||||
maskLoader?: boolean;
|
||||
error?: UiBaseError[];
|
||||
}
|
||||
export const MainPage = (props: IMainPageProps) => {
|
||||
|
@ -132,6 +133,22 @@ export const MainPage = (props: IMainPageProps) => {
|
|||
</>
|
||||
) : (
|
||||
<>
|
||||
{props.maskLoader ? (
|
||||
<div
|
||||
style={{
|
||||
width: "100vw",
|
||||
left: 241,
|
||||
height: "100vh",
|
||||
backgroundColor: "#000000b0",
|
||||
position: "absolute",
|
||||
zIndex: 100,
|
||||
alignContent: "center",
|
||||
textAlignLast: "center",
|
||||
}}
|
||||
>
|
||||
<Spin />
|
||||
</div>
|
||||
) : null}
|
||||
<div
|
||||
style={Object.assign(
|
||||
{ width: 241, height: window.innerHeight, backgroundColor: "#F7F2FA", borderRadius: 16 },
|
||||
|
|
|
@ -2,13 +2,13 @@ import React from "react";
|
|||
import { CoreText, CoreTextType } from "../text/text";
|
||||
import { IStyle } from "../../model/style";
|
||||
|
||||
interface ISelectCoreProps extends IStyle {
|
||||
interface ICoreSelectProps extends IStyle {
|
||||
items: string[];
|
||||
value: string;
|
||||
label: string;
|
||||
onChange: (value: string) => void;
|
||||
}
|
||||
export const SelectCore = (props: ISelectCoreProps) => {
|
||||
export const CoreSelect = (props: ICoreSelectProps) => {
|
||||
const ref = React.useRef<HTMLDivElement>(null);
|
||||
const [cursorIsCorses, setCursorIsCorses] = React.useState(false);
|
||||
const [value, setValue] = React.useState(props.value);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue