progress
This commit is contained in:
parent
c10cdb8158
commit
78ebb748ea
19 changed files with 2032 additions and 124 deletions
3
.prettierrc
Normal file
3
.prettierrc
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
{
|
||||||
|
"printWidth":120
|
||||||
|
}
|
1
p.ts
1
p.ts
|
@ -1 +0,0 @@
|
||||||
|
|
1873
server/package-lock.json
generated
1873
server/package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
@ -24,13 +24,13 @@
|
||||||
"chai": "latest",
|
"chai": "latest",
|
||||||
"eslint": "^8.47.0",
|
"eslint": "^8.47.0",
|
||||||
"mocha": "latest",
|
"mocha": "latest",
|
||||||
|
"node-watch": "^0.7.4",
|
||||||
|
"nodemon": "^3.0.1",
|
||||||
"nyc": "latest",
|
"nyc": "latest",
|
||||||
"source-map-support": "latest",
|
"source-map-support": "latest",
|
||||||
"ts-node": "^10.9.1",
|
"ts-node": "^10.9.1",
|
||||||
"tslint": "latest",
|
"tslint": "latest",
|
||||||
"typescript": "^5.1.6",
|
"typescript": "^5.1.6"
|
||||||
"node-watch": "^0.7.4",
|
|
||||||
"nodemon": "^3.0.1"
|
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@grpc/grpc-js": "^1.9.0",
|
"@grpc/grpc-js": "^1.9.0",
|
||||||
|
@ -45,13 +45,14 @@
|
||||||
"md5": "^2.3.0",
|
"md5": "^2.3.0",
|
||||||
"mongoose": "^7.6.2",
|
"mongoose": "^7.6.2",
|
||||||
"mongoose-autopopulate": "^1.1.0",
|
"mongoose-autopopulate": "^1.1.0",
|
||||||
|
"pm2": "^5.3.1",
|
||||||
"reflect-metadata": "^0.1.13",
|
"reflect-metadata": "^0.1.13",
|
||||||
|
"rimraf": "^5.0.5",
|
||||||
"socket.io": "^4.7.2",
|
"socket.io": "^4.7.2",
|
||||||
"socket.io-client": "^4.7.2",
|
"socket.io-client": "^4.7.2",
|
||||||
"spark-md5": "^3.0.2",
|
"spark-md5": "^3.0.2",
|
||||||
"ts-md5": "^1.3.1",
|
"ts-md5": "^1.3.1",
|
||||||
"tsc-watch": "^6.0.4",
|
"tsc-watch": "^6.0.4",
|
||||||
"uuid": "^9.0.1",
|
"uuid": "^9.0.1"
|
||||||
"pm2": "^5.3.1"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import * as fs from "fs";
|
import * as fs from "fs";
|
||||||
import { promisify } from "node:util";
|
import { promisify } from "node:util";
|
||||||
|
import { rimraf } from 'rimraf'
|
||||||
|
|
||||||
export class FileSystemRepository {
|
export class FileSystemRepository {
|
||||||
public createDir = promisify(fs.mkdir);
|
public createDir = promisify(fs.mkdir);
|
||||||
|
@ -9,7 +10,7 @@ export class FileSystemRepository {
|
||||||
public stat = promisify(fs.stat);
|
public stat = promisify(fs.stat);
|
||||||
public readFileAsync = promisify(fs.readFile);
|
public readFileAsync = promisify(fs.readFile);
|
||||||
public readdir = promisify(fs.readdir);
|
public readdir = promisify(fs.readdir);
|
||||||
|
public deleteDirRecursive = rimraf;
|
||||||
async readFileAtBuffer(path: string): Promise<Buffer> {
|
async readFileAtBuffer(path: string): Promise<Buffer> {
|
||||||
if ((await this.lsStat(path)).isDirectory()) {
|
if ((await this.lsStat(path)).isDirectory()) {
|
||||||
return (
|
return (
|
||||||
|
@ -40,4 +41,5 @@ export class FileSystemRepository {
|
||||||
});
|
});
|
||||||
return filesToDir;
|
return filesToDir;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
12
server/src/core/usecases/delete_recursive_folder_usecase.ts
Normal file
12
server/src/core/usecases/delete_recursive_folder_usecase.ts
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
import { Result } from "../helpers/result";
|
||||||
|
import { FileSystemRepository } from "../repository/file_system_repository";
|
||||||
|
|
||||||
|
export class DeleteRecursiveFolderUseCase{
|
||||||
|
repository:FileSystemRepository = new FileSystemRepository()
|
||||||
|
call = async (path:string):Promise<Result<void,void>> =>{
|
||||||
|
console.log(path)
|
||||||
|
await this.repository.deleteDirRecursive(path)
|
||||||
|
return Result.ok()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,6 +1,7 @@
|
||||||
import { CrudController } from "../../core/controllers/crud_controller";
|
import { CrudController } from "../../core/controllers/crud_controller";
|
||||||
import { IsHaveActiveProcessUseCase, KillLastProcessUseCase } from "../../core/usecases/exec_process_usecase";
|
import { IsHaveActiveProcessUseCase, KillLastProcessUseCase } from "../../core/usecases/exec_process_usecase";
|
||||||
import { CreateDataSetScenario } from "./domain/create_dataset_scenario";
|
import { CreateDataSetScenario } from "./domain/create_dataset_scenario";
|
||||||
|
import { DeleteDatasetUseCase } from "./domain/delete_dataset_use_case";
|
||||||
import { ExecDatasetProcessScenario } from "./domain/exec_process_scenario";
|
import { ExecDatasetProcessScenario } from "./domain/exec_process_scenario";
|
||||||
import { GetDatasetActiveProjectScenario } from "./domain/get_dataset_active_project_scenario";
|
import { GetDatasetActiveProjectScenario } from "./domain/get_dataset_active_project_scenario";
|
||||||
import { DatasetDBModel } from "./models/dataset_database_model";
|
import { DatasetDBModel } from "./models/dataset_database_model";
|
||||||
|
@ -15,6 +16,7 @@ export class DatasetsPresentation extends CrudController<DatasetValidationModel,
|
||||||
});
|
});
|
||||||
super.post(new CreateDataSetScenario().call);
|
super.post(new CreateDataSetScenario().call);
|
||||||
super.get(new GetDatasetActiveProjectScenario().call);
|
super.get(new GetDatasetActiveProjectScenario().call);
|
||||||
|
super.delete(null)
|
||||||
this.subRoutes.push({
|
this.subRoutes.push({
|
||||||
method: "POST",
|
method: "POST",
|
||||||
subUrl: "exec",
|
subUrl: "exec",
|
||||||
|
@ -30,5 +32,11 @@ export class DatasetsPresentation extends CrudController<DatasetValidationModel,
|
||||||
subUrl: "delete/process",
|
subUrl: "delete/process",
|
||||||
fn: new KillLastProcessUseCase(),
|
fn: new KillLastProcessUseCase(),
|
||||||
});
|
});
|
||||||
|
this.subRoutes.push({
|
||||||
|
method: "DELETE",
|
||||||
|
subUrl: "dataset",
|
||||||
|
fn: new DeleteDatasetUseCase()
|
||||||
|
})
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
import { CallbackStrategyWithIdQuery, ResponseBase } from "../../../core/controllers/http_controller";
|
||||||
|
import { Result } from "../../../core/helpers/result";
|
||||||
|
import { DeleteDataBaseModelUseCase } from "../../../core/usecases/delete_database_model_usecase";
|
||||||
|
import { DeleteRecursiveFolderUseCase } from "../../../core/usecases/delete_recursive_folder_usecase";
|
||||||
|
import { ReadByIdDataBaseModelUseCase } from "../../../core/usecases/read_by_id_database_model_usecase";
|
||||||
|
import { MongoIdValidation } from "../../../core/validations/mongo_id_validation";
|
||||||
|
import { DatasetDBModel } from "../models/dataset_database_model";
|
||||||
|
import { IDatasetModel } from "../models/dataset_validation_model";
|
||||||
|
|
||||||
|
export class DeleteDatasetUseCase extends CallbackStrategyWithIdQuery {
|
||||||
|
idValidationExpression = new MongoIdValidation();
|
||||||
|
call = async (id: string): ResponseBase =>
|
||||||
|
(await new ReadByIdDataBaseModelUseCase<IDatasetModel>(DatasetDBModel).call(id)).map(async (model) =>
|
||||||
|
(await new DeleteRecursiveFolderUseCase().call(`${model.local_path}/${model.name}/`)).map(async () =>
|
||||||
|
(await new DeleteDataBaseModelUseCase(model).call(model._id)).map(() => Result.ok({ status: "delete dataset" }))
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
|
@ -6,16 +6,18 @@ import { MongoIdValidation } from "../../../core/validations/mongo_id_validation
|
||||||
import { DatasetDBModel } from "../models/dataset_database_model";
|
import { DatasetDBModel } from "../models/dataset_database_model";
|
||||||
import { IDatasetModel } from "../models/dataset_validation_model";
|
import { IDatasetModel } from "../models/dataset_validation_model";
|
||||||
import { ProcessWatcherAndDatabaseUpdateService } from "./create_dataset_scenario";
|
import { ProcessWatcherAndDatabaseUpdateService } from "./create_dataset_scenario";
|
||||||
|
import { UpdateDataBaseModelUseCase } from "../../../core/usecases/update_database_model_usecase";
|
||||||
|
|
||||||
export class ExecDatasetProcessScenario extends CallbackStrategyWithIdQuery {
|
export class ExecDatasetProcessScenario extends CallbackStrategyWithIdQuery {
|
||||||
idValidationExpression = new MongoIdValidation();
|
idValidationExpression = new MongoIdValidation();
|
||||||
|
|
||||||
call = async (id: string): ResponseBase => {
|
call = async (id: string): ResponseBase => {
|
||||||
return (await new ReadByIdDataBaseModelUseCase<IDatasetModel>(DatasetDBModel).call(id)).map(async (model) => {
|
return (await new ReadByIdDataBaseModelUseCase<IDatasetModel>(DatasetDBModel).call(id)).map(async (model) => {
|
||||||
return (await new IsHaveActiveProcessUseCase().call()).map(() => {
|
return (await new IsHaveActiveProcessUseCase().call()).map(async () => {
|
||||||
return new ExecProcessUseCase().call(
|
await DatasetDBModel.findById(id).updateOne({processStatus:"RUN"})
|
||||||
|
return new ExecProcessUseCase().call(
|
||||||
`${model.project.rootDir}/`,
|
`${model.project.rootDir}/`,
|
||||||
`python3 $PYTHON_BLENDER_PROC --cfg '${JSON.stringify(model)}' `,
|
`python3 $PYTHON_BLENDER_PROC --path '${model.project.rootDir}/${model.name}/'`,
|
||||||
new ProcessWatcherAndDatabaseUpdateService(id as unknown as ObjectId)
|
new ProcessWatcherAndDatabaseUpdateService(id as unknown as ObjectId)
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { Type } from "class-transformer";
|
import { Type } from "class-transformer";
|
||||||
import { IsArray, IsString, ValidateNested } from "class-validator";
|
import { IsArray, IsOptional, IsString, ValidateNested } from "class-validator";
|
||||||
import { IProjectModel } from "../../_projects/models/project_database_model";
|
import { IProjectModel } from "../../_projects/models/project_database_model";
|
||||||
|
|
||||||
export class FormBuilderValidationModel {
|
export class FormBuilderValidationModel {
|
||||||
|
@ -16,6 +16,7 @@ export enum ProcessStatus {
|
||||||
NEW = "NEW",
|
NEW = "NEW",
|
||||||
}
|
}
|
||||||
export interface IDatasetModel {
|
export interface IDatasetModel {
|
||||||
|
_id?:string;
|
||||||
name: string;
|
name: string;
|
||||||
local_path: string;
|
local_path: string;
|
||||||
dataSetObjects: string[];
|
dataSetObjects: string[];
|
||||||
|
@ -34,6 +35,8 @@ export class DatasetValidationModel implements IDatasetModel {
|
||||||
@Type(() => FormBuilderValidationModel)
|
@Type(() => FormBuilderValidationModel)
|
||||||
public formBuilder: FormBuilderValidationModel;
|
public formBuilder: FormBuilderValidationModel;
|
||||||
public local_path: string;
|
public local_path: string;
|
||||||
|
@IsOptional()
|
||||||
|
@IsString()
|
||||||
public processStatus: ProcessStatus;
|
public processStatus: ProcessStatus;
|
||||||
public projectId: string;
|
public projectId: string;
|
||||||
public processLogs: string;
|
public processLogs: string;
|
||||||
|
|
|
@ -4,6 +4,8 @@ import { Result } from "../helper/result";
|
||||||
export enum HttpMethod {
|
export enum HttpMethod {
|
||||||
GET = "GET",
|
GET = "GET",
|
||||||
POST = "POST",
|
POST = "POST",
|
||||||
|
DELETE = "DELETE",
|
||||||
|
PUT = "PUT"
|
||||||
}
|
}
|
||||||
export class HttpError extends Error {
|
export class HttpError extends Error {
|
||||||
status: number;
|
status: number;
|
||||||
|
|
|
@ -6,13 +6,14 @@ export interface IButtonProps {
|
||||||
filled?: boolean;
|
filled?: boolean;
|
||||||
text?: string;
|
text?: string;
|
||||||
onClick?: any;
|
onClick?: any;
|
||||||
|
style?:React.CSSProperties
|
||||||
}
|
}
|
||||||
|
|
||||||
export function CoreButton(props: IButtonProps) {
|
export function CoreButton(props: IButtonProps) {
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
onClick={() => props.onClick?.call()}
|
onClick={() => props.onClick?.call()}
|
||||||
style={{
|
style={Object.assign({
|
||||||
backgroundColor: props.filled ? "rgba(103, 80, 164, 1)" : "",
|
backgroundColor: props.filled ? "rgba(103, 80, 164, 1)" : "",
|
||||||
paddingRight: 20,
|
paddingRight: 20,
|
||||||
paddingLeft: 20,
|
paddingLeft: 20,
|
||||||
|
@ -20,7 +21,7 @@ export function CoreButton(props: IButtonProps) {
|
||||||
paddingBottom: 10,
|
paddingBottom: 10,
|
||||||
borderRadius: 24,
|
borderRadius: 24,
|
||||||
border: props.block ? "1px solid rgba(29, 27, 32, 0.12)" : props.filled ? "" : "1px solid black",
|
border: props.block ? "1px solid rgba(29, 27, 32, 0.12)" : props.filled ? "" : "1px solid black",
|
||||||
}}
|
},props.style)}
|
||||||
>
|
>
|
||||||
<CoreText
|
<CoreText
|
||||||
text={props.text ?? ""}
|
text={props.text ?? ""}
|
||||||
|
|
|
@ -54,13 +54,15 @@ export class FormViewModel {
|
||||||
this.inputs = inputs;
|
this.inputs = inputs;
|
||||||
makeAutoObservable(this);
|
makeAutoObservable(this);
|
||||||
}
|
}
|
||||||
|
public json(){
|
||||||
|
return JSON.parse(this.toResult().replaceAll("\n", "").replaceAll("\\", "").replaceAll("/", ""))
|
||||||
|
}
|
||||||
public fromFormBuilderValidationModel() {
|
public fromFormBuilderValidationModel() {
|
||||||
return new FormBuilderValidationModel(
|
return new FormBuilderValidationModel(
|
||||||
this.context,
|
this.context,
|
||||||
this.result,
|
this.result,
|
||||||
this.inputs.map((el) => el.toJson()),
|
this.inputs.map((el) => el.toJson()),
|
||||||
JSON.parse(this.toResult().replaceAll("\n", "").replaceAll("\\", "").replaceAll("/", ""))
|
this.json() as any
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
public toResult(): string {
|
public toResult(): string {
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { CoreText, CoreTextType } from "../text/text";
|
import { CoreText, CoreTextType } from "../text/text";
|
||||||
|
import { Input } from "antd";
|
||||||
|
|
||||||
interface IInputProps {
|
interface IInputProps {
|
||||||
label: string;
|
label: string;
|
||||||
|
@ -9,18 +10,16 @@ interface IInputProps {
|
||||||
validation?: (value: string) => boolean;
|
validation?: (value: string) => boolean;
|
||||||
error?: string;
|
error?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const CoreInput = (props: IInputProps) => {
|
export const CoreInput = (props: IInputProps) => {
|
||||||
const [value, setValue] = React.useState<string>(() => props.value ?? "");
|
const [key, setKey] = React.useState<undefined | string>(undefined);
|
||||||
const ref = React.useRef<HTMLDivElement>(null);
|
|
||||||
const [isAppendInnerText, setAppendInnerText] = React.useState(true);
|
|
||||||
React.useEffect(() => {
|
|
||||||
if (ref.current && isAppendInnerText) {
|
|
||||||
ref.current.innerText = value;
|
|
||||||
setAppendInnerText(false);
|
|
||||||
}
|
|
||||||
}, [ref, value, isAppendInnerText, setAppendInnerText]);
|
|
||||||
|
|
||||||
|
React.useEffect(() => {
|
||||||
|
setKey(props.value);
|
||||||
|
return () => {
|
||||||
|
setKey(undefined);
|
||||||
|
};
|
||||||
|
}, [key, setKey, props]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
style={Object.assign(
|
style={Object.assign(
|
||||||
|
@ -36,28 +35,36 @@ export const CoreInput = (props: IInputProps) => {
|
||||||
>
|
>
|
||||||
<CoreText type={CoreTextType.small} text={props.label} />
|
<CoreText type={CoreTextType.small} text={props.label} />
|
||||||
|
|
||||||
<div
|
<Input
|
||||||
ref={ref}
|
key={key}
|
||||||
onInput={(e) => {
|
defaultValue={props.value}
|
||||||
if (e.currentTarget.textContent) {
|
style={{
|
||||||
setValue(e.currentTarget.textContent);
|
backgroundColor: "#00008000",
|
||||||
if (props.validation !== undefined && props.validation(value) && props.onChange) {
|
border: 1,
|
||||||
props.onChange(value);
|
fontSize: 16,
|
||||||
|
fontFamily: "Roboto",
|
||||||
|
color: "#1D1B20",
|
||||||
|
height: 24,
|
||||||
|
width: "100%",
|
||||||
|
}}
|
||||||
|
onChange={(e) => {
|
||||||
|
const val = e.target.value;
|
||||||
|
if (val) {
|
||||||
|
if (props.validation !== undefined && props.validation(val) && props.onChange) {
|
||||||
|
props.onChange(val);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (props.onChange && props.validation === undefined) {
|
if (props.onChange && props.validation === undefined) {
|
||||||
props.onChange(value);
|
props.onChange(val);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
style={{ fontSize: 16, fontFamily: "Roboto", color: "#1D1B20", height: 24 }}
|
|
||||||
contentEditable="true"
|
|
||||||
/>
|
/>
|
||||||
{value ? (
|
{props.value ? (
|
||||||
props.validation ? (
|
props.validation ? (
|
||||||
props.validation(value) ? null : (
|
props.validation(props.value) ? null : (
|
||||||
<div style={{ color: "#ff1d0c" }}>{props.error ? props.error : "error"}</div>
|
<div style={{ color: "#ff1d0c" }}>{props.error ? props.error : "error"}</div>
|
||||||
)
|
)
|
||||||
) : null
|
) : null
|
||||||
|
|
|
@ -34,13 +34,24 @@ interface ICardDataSetProps {
|
||||||
|
|
||||||
export const CardDataSet = (props: ICardDataSetProps) => {
|
export const CardDataSet = (props: ICardDataSetProps) => {
|
||||||
const menu: IMenuItem[] = [
|
const menu: IMenuItem[] = [
|
||||||
{ onClick: () => props.onEdit?.call(props.id), name: "Редактировать" },
|
{
|
||||||
{ onClick: () => props.onDelete?.call(props.id), name: "Удалить" },
|
onClick: () => {
|
||||||
|
if (props.onEdit) props.onEdit(props.id);
|
||||||
|
},
|
||||||
|
name: "Редактировать",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
onClick: () => {
|
||||||
|
if (props.onDelete) props.onDelete(props.id);
|
||||||
|
},
|
||||||
|
name: "Удалить",
|
||||||
|
},
|
||||||
];
|
];
|
||||||
const items: MenuProps["items"] = menu.map((el, index) => {
|
const items: MenuProps["items"] = menu.map((el, index) => {
|
||||||
return {
|
return {
|
||||||
key: String(index),
|
key: String(index),
|
||||||
label: <CoreText text={el.name} type={CoreTextType.medium} />,
|
label: <CoreText text={el.name} type={CoreTextType.medium} />,
|
||||||
|
onClick: () => el.onClick(props.id),
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
return (
|
return (
|
||||||
|
@ -95,7 +106,7 @@ export const CardDataSet = (props: ICardDataSetProps) => {
|
||||||
<CoreText text={props.objects?.join(", ") ?? ""} type={CoreTextType.medium} color="#49454F" />
|
<CoreText text={props.objects?.join(", ") ?? ""} type={CoreTextType.medium} color="#49454F" />
|
||||||
</div>
|
</div>
|
||||||
<div style={{ display: "flex", flexDirection: "row", justifyContent: "flex-end", alignItems: "center" }}>
|
<div style={{ display: "flex", flexDirection: "row", justifyContent: "flex-end", alignItems: "center" }}>
|
||||||
{props.processStatus === "exec" ? (
|
{props.processStatus === ProcessStatus.RUN ? (
|
||||||
<Spin indicator={<LoadingOutlined style={{ fontSize: 34, color: "rgba(103, 80, 164, 1)" }} spin />} />
|
<Spin indicator={<LoadingOutlined style={{ fontSize: 34, color: "rgba(103, 80, 164, 1)" }} spin />} />
|
||||||
) : null}
|
) : null}
|
||||||
<div style={{ width: 20 }} />
|
<div style={{ width: 20 }} />
|
||||||
|
@ -110,9 +121,33 @@ export const CardDataSet = (props: ICardDataSetProps) => {
|
||||||
text="Старт"
|
text="Старт"
|
||||||
/>
|
/>
|
||||||
) : null}
|
) : null}
|
||||||
|
{props.processStatus === ProcessStatus.END ? ( <CoreButton
|
||||||
|
|
||||||
|
onClick={() => {
|
||||||
|
if (props.type.isEqual(CardDataSetType.COMPLETED) && props.onClickButton && props.id) {
|
||||||
|
props.onClickButton(props.id);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
|
||||||
|
text="Завершен"
|
||||||
|
/>):null}
|
||||||
|
{props.processStatus === ProcessStatus.RUN ? (<>
|
||||||
|
<CoreButton
|
||||||
|
|
||||||
|
onClick={() => {
|
||||||
|
if (props.type.isEqual(CardDataSetType.COMPLETED) && props.onClickButton && props.id) {
|
||||||
|
props.onClickButton(props.id);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
block={true}
|
||||||
|
text="Стоп"
|
||||||
|
/>
|
||||||
|
</>):null}
|
||||||
{props.processStatus === ProcessStatus.ERROR ? (
|
{props.processStatus === ProcessStatus.ERROR ? (
|
||||||
<CoreButton
|
<CoreButton
|
||||||
|
style={{
|
||||||
|
backgroundColor: "red",
|
||||||
|
}}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
if (props.type.isEqual(CardDataSetType.COMPLETED) && props.onClickButton && props.id) {
|
if (props.type.isEqual(CardDataSetType.COMPLETED) && props.onClickButton && props.id) {
|
||||||
props.onClickButton(props.id);
|
props.onClickButton(props.id);
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
import { InputBuilderViewModel } from "../../core/ui/form_builder/form_view_model";
|
import { InputBuilderViewModel } from "../../core/ui/form_builder/form_view_model";
|
||||||
import { Result } from "../../core/helper/result";
|
import { Result } from "../../core/helper/result";
|
||||||
import makeAutoObservable from "mobx-store-inheritance";
|
import makeAutoObservable from "mobx-store-inheritance";
|
||||||
|
|
||||||
export enum ProcessStatus {
|
export enum ProcessStatus {
|
||||||
END = "END",
|
END = "END",
|
||||||
ERROR = "ERROR",
|
ERROR = "ERROR",
|
||||||
NEW = "NEW",
|
NEW = "NEW",
|
||||||
|
RUN = "RUN",
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IDatasetModel {
|
export interface IDatasetModel {
|
||||||
|
@ -48,7 +50,7 @@ export class FormBuilderValidationModel {
|
||||||
public result: string;
|
public result: string;
|
||||||
public context: string;
|
public context: string;
|
||||||
public form: string[];
|
public form: string[];
|
||||||
public output: string;
|
public output: any;
|
||||||
constructor(context: string, result: string, form: string[], output: string) {
|
constructor(context: string, result: string, form: string[], output: string) {
|
||||||
this.context = context;
|
this.context = context;
|
||||||
this.result = result;
|
this.result = result;
|
||||||
|
@ -56,7 +58,7 @@ export class FormBuilderValidationModel {
|
||||||
this.output = output;
|
this.output = output;
|
||||||
}
|
}
|
||||||
static empty() {
|
static empty() {
|
||||||
return new FormBuilderValidationModel(datasetFormMockContext, datasetFormMockResult, [], "");
|
return new FormBuilderValidationModel(datasetFormMockContext, datasetFormMockResult, [], defaultFormValue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,18 +68,24 @@ export class DataSetModel {
|
||||||
name: string;
|
name: string;
|
||||||
formBuilder: FormBuilderValidationModel = FormBuilderValidationModel.empty();
|
formBuilder: FormBuilderValidationModel = FormBuilderValidationModel.empty();
|
||||||
project?: string;
|
project?: string;
|
||||||
constructor(dataSetObjects: string[], datasetType = datasetTypes[0], datasetName: string) {
|
processStatus?:string
|
||||||
|
isNew:boolean;
|
||||||
|
_id?:string;
|
||||||
|
constructor(dataSetObjects: string[], datasetType = datasetTypes[0], datasetName: string, isNew = true, id:string | undefined = undefined) {
|
||||||
this.dataSetObjects = dataSetObjects;
|
this.dataSetObjects = dataSetObjects;
|
||||||
this.datasetType = datasetType;
|
this.datasetType = datasetType;
|
||||||
this.name = datasetName;
|
this.name = datasetName;
|
||||||
|
this.isNew = isNew;
|
||||||
|
this._id = id;
|
||||||
makeAutoObservable(this);
|
makeAutoObservable(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
static empty() {
|
static empty() {
|
||||||
return new DataSetModel([], "", "");
|
return new DataSetModel([], "", "", true);
|
||||||
}
|
}
|
||||||
|
|
||||||
isValid(): Result<string, void> {
|
isValid(): Result<string, void> {
|
||||||
|
|
||||||
if (this.project === undefined) {
|
if (this.project === undefined) {
|
||||||
return Result.error("project is unknow");
|
return Result.error("project is unknow");
|
||||||
}
|
}
|
||||||
|
@ -92,6 +100,10 @@ export class DataSetModel {
|
||||||
}
|
}
|
||||||
return Result.ok();
|
return Result.ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static fromIDatasetModel(model: IDatasetModel) {
|
||||||
|
return new DataSetModel(model.dataSetObjects, model.datasetType, model.name, false, model._id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const datasetTypes = ["Object Detection - YOLOv8", "Pose Estimation - DOPE"];
|
export const datasetTypes = ["Object Detection - YOLOv8", "Pose Estimation - DOPE"];
|
||||||
|
@ -162,3 +174,11 @@ type LIGHTS = {
|
||||||
"energy_range":[\${ENERGY_RANGE_1:number:400},\${ENERGY_RANGE_2:number:900}]
|
"energy_range":[\${ENERGY_RANGE_1:number:400},\${ENERGY_RANGE_2:number:900}]
|
||||||
};
|
};
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
export const defaultFormValue: any = {
|
||||||
|
typedataset: "PoseEstimation",
|
||||||
|
models_randomization: { loc_range_low: [-1, -1, 0], loc_range_high: [1, 1, 2] },
|
||||||
|
scene: { objects: [], lights: [] },
|
||||||
|
camera_position: { center_shell: [0, 0, 0], radius_range: [1, 1.4], elevation_range: [10, 90] },
|
||||||
|
generation: { n_cam_pose: 5, n_sample_on_pose: 3, n_series: 100, image_format: "jpg", image_size_wh: [640, 480] },
|
||||||
|
};
|
||||||
|
|
|
@ -1,9 +1,16 @@
|
||||||
import { Result } from "../../core/helper/result";
|
import { Result } from "../../core/helper/result";
|
||||||
import { HttpError, HttpMethod, HttpRepository } from "../../core/repository/http_repository";
|
import { HttpError, HttpMethod, HttpRepository } from "../../core/repository/http_repository";
|
||||||
import { UUID } from "../all_projects/data/project_repository";
|
import { UUID } from "../all_projects/data/project_repository";
|
||||||
import { Assets, DataSetModel, Dataset, IDatasetModel } from "./dataset_model";
|
import { Assets, DataSetModel, Dataset, IDatasetModel, ProcessStatus } from "./dataset_model";
|
||||||
|
|
||||||
export class DataSetRepository extends HttpRepository {
|
export class DataSetRepository extends HttpRepository {
|
||||||
|
editDataset(dataSetModel: DataSetModel) {
|
||||||
|
dataSetModel.processStatus = ProcessStatus.NEW;
|
||||||
|
return this._jsonRequest<void>(HttpMethod.PUT, `/datasets`, dataSetModel);
|
||||||
|
}
|
||||||
|
deleteDataset(id: string) {
|
||||||
|
return this._jsonRequest<void>(HttpMethod.DELETE, `/datasets/dataset?id=${id}`);
|
||||||
|
}
|
||||||
getActiveProjectId(): Promise<Result<HttpError, UUID>> {
|
getActiveProjectId(): Promise<Result<HttpError, UUID>> {
|
||||||
return this._jsonRequest<UUID>(HttpMethod.GET, "/projects/get/active/project/id");
|
return this._jsonRequest<UUID>(HttpMethod.GET, "/projects/get/active/project/id");
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,8 @@ import { datasetTypes } from "./dataset_model";
|
||||||
import { CoreText, CoreTextType } from "../../core/ui/text/text";
|
import { CoreText, CoreTextType } from "../../core/ui/text/text";
|
||||||
|
|
||||||
export const DatasetsScreenPath = "/dataset";
|
export const DatasetsScreenPath = "/dataset";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
export const DataSetScreen: React.FunctionComponent = observer(() => {
|
export const DataSetScreen: React.FunctionComponent = observer(() => {
|
||||||
const [store] = React.useState(() => new DataSetStore());
|
const [store] = React.useState(() => new DataSetStore());
|
||||||
|
@ -55,9 +57,9 @@ export const DataSetScreen: React.FunctionComponent = observer(() => {
|
||||||
<CardDataSet
|
<CardDataSet
|
||||||
type={CardDataSetType.EMPTY}
|
type={CardDataSetType.EMPTY}
|
||||||
onClickEmptyCard={() => {
|
onClickEmptyCard={() => {
|
||||||
store.editDrawer(DrawersDataset.NewDataset, true);
|
store.openEmptyCard()
|
||||||
}}
|
}}
|
||||||
/>
|
/>ч
|
||||||
<Drawer
|
<Drawer
|
||||||
title={DrawersDataset.FormBuilderDrawer}
|
title={DrawersDataset.FormBuilderDrawer}
|
||||||
onClose={() => store.editDrawer(DrawersDataset.FormBuilderDrawer, false)}
|
onClose={() => store.editDrawer(DrawersDataset.FormBuilderDrawer, false)}
|
||||||
|
@ -67,11 +69,15 @@ export const DataSetScreen: React.FunctionComponent = observer(() => {
|
||||||
context={store.dataSetModel.formBuilder.context}
|
context={store.dataSetModel.formBuilder.context}
|
||||||
result={store.dataSetModel.formBuilder.result}
|
result={store.dataSetModel.formBuilder.result}
|
||||||
onChange={(el) => {
|
onChange={(el) => {
|
||||||
if (el) store.dataSetModel.formBuilder = el;
|
store.dataSetModel.formBuilder = el;
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<div style={{ display: "flex" }}>
|
<div style={{ display: "flex" }}>
|
||||||
<CoreButton text="Сохранить" filled={true} />
|
<CoreButton
|
||||||
|
text="Сохранить"
|
||||||
|
filled={true}
|
||||||
|
onClick={() => store.editDrawer(DrawersDataset.FormBuilderDrawer, false)}
|
||||||
|
/>
|
||||||
<div style={{ width: 10 }} />
|
<div style={{ width: 10 }} />
|
||||||
<CoreButton text="Отмена" onClick={() => store.editDrawer(DrawersDataset.FormBuilderDrawer, false)} />
|
<CoreButton text="Отмена" onClick={() => store.editDrawer(DrawersDataset.FormBuilderDrawer, false)} />
|
||||||
</div>
|
</div>
|
||||||
|
@ -80,12 +86,12 @@ export const DataSetScreen: React.FunctionComponent = observer(() => {
|
||||||
title={DrawersDataset.NewDataset}
|
title={DrawersDataset.NewDataset}
|
||||||
onClose={() => store.editDrawer(DrawersDataset.NewDataset, false)}
|
onClose={() => store.editDrawer(DrawersDataset.NewDataset, false)}
|
||||||
open={store.drawers.find((el) => el.name === DrawersDataset.NewDataset)?.status}
|
open={store.drawers.find((el) => el.name === DrawersDataset.NewDataset)?.status}
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
style={{ display: "flex", flexDirection: "column", justifyContent: "space-between", height: "100%" }}
|
style={{ display: "flex", flexDirection: "column", justifyContent: "space-between", height: "100%" }}
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
<CoreInput label={"Имя датасета"} onChange={(e) => store.setNewDatasetName(e)} />
|
<CoreInput value={store.dataSetModel.name} label={"Имя датасета"} onChange={(e) => store.setNewDatasetName(e)} />
|
||||||
<div>
|
<div>
|
||||||
<CoreText type={CoreTextType.header} text="Тип навыка" />
|
<CoreText type={CoreTextType.header} text="Тип навыка" />
|
||||||
{datasetTypes.map((el) => {
|
{datasetTypes.map((el) => {
|
||||||
|
|
|
@ -34,6 +34,11 @@ export class DataSetStore extends UiErrorState<HttpError> {
|
||||||
makeAutoObservable(this);
|
makeAutoObservable(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
openEmptyCard() {
|
||||||
|
this.dataSetModel = DataSetModel.empty();
|
||||||
|
this.editDrawer(DrawersDataset.NewDataset, true);
|
||||||
|
}
|
||||||
|
|
||||||
setNewDatasetName(e: string): void {
|
setNewDatasetName(e: string): void {
|
||||||
this.dataSetModel.name = e;
|
this.dataSetModel.name = e;
|
||||||
}
|
}
|
||||||
|
@ -66,9 +71,22 @@ export class DataSetStore extends UiErrorState<HttpError> {
|
||||||
return el;
|
return el;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
editDataset(id: string) {}
|
|
||||||
|
|
||||||
deleteDataset(id: string) {}
|
editDataset(id: string) {
|
||||||
|
this.dataSetModel = DataSetModel.fromIDatasetModel(this.datasets?.find((el) => el._id === id) as IDatasetModel);
|
||||||
|
console.log(this.dataSetModel.name);
|
||||||
|
this.editDrawer(DrawersDataset.NewDataset, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
deleteDataset = async (id: string) => {
|
||||||
|
(await this.dataSetRepository.deleteDataset(id)).fold(
|
||||||
|
async () => {
|
||||||
|
message.success("датасет удален");
|
||||||
|
await this.getDatasets();
|
||||||
|
},
|
||||||
|
async (e) => message.error(e.message)
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
runProcess = async (id: string): Promise<void> => {
|
runProcess = async (id: string): Promise<void> => {
|
||||||
(await this.dataSetRepository.isRunningProcess()).fold(
|
(await this.dataSetRepository.isRunningProcess()).fold(
|
||||||
|
@ -91,12 +109,23 @@ export class DataSetStore extends UiErrorState<HttpError> {
|
||||||
this.dataSetModel.project = this.activeProject.id;
|
this.dataSetModel.project = this.activeProject.id;
|
||||||
this.dataSetModel.isValid().fold(
|
this.dataSetModel.isValid().fold(
|
||||||
async () => {
|
async () => {
|
||||||
(await this.dataSetRepository.saveDataSet(this.dataSetModel)).fold(
|
if (this.dataSetModel.isNew) {
|
||||||
() => {
|
(await this.dataSetRepository.saveDataSet(this.dataSetModel)).fold(
|
||||||
message.success("Датасет сохранен");
|
async () => {
|
||||||
},
|
message.success("Датасет сохранен");
|
||||||
(error) => message.error(error.message)
|
await this.getDatasets();
|
||||||
);
|
},
|
||||||
|
async (error) => message.error(error.message)
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
(await this.dataSetRepository.editDataset(this.dataSetModel)).fold(
|
||||||
|
async () => {
|
||||||
|
message.success("Настройки датасета измнены");
|
||||||
|
await this.getDatasets();
|
||||||
|
},
|
||||||
|
async (error) => message.error(error.message)
|
||||||
|
);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
async (error) => message.error(error)
|
async (error) => message.error(error)
|
||||||
);
|
);
|
||||||
|
@ -104,7 +133,10 @@ export class DataSetStore extends UiErrorState<HttpError> {
|
||||||
|
|
||||||
init = async () => {
|
init = async () => {
|
||||||
await this.mapOk("assets", this.dataSetRepository.getAssetsActiveProject());
|
await this.mapOk("assets", this.dataSetRepository.getAssetsActiveProject());
|
||||||
await this.mapOk("datasets", this.dataSetRepository.getDatasetsActiveProject());
|
await this.getDatasets();
|
||||||
await this.mapOk("activeProject", this.dataSetRepository.getActiveProjectId());
|
await this.mapOk("activeProject", this.dataSetRepository.getActiveProjectId());
|
||||||
};
|
};
|
||||||
|
getDatasets = async () => {
|
||||||
|
await this.mapOk("datasets", this.dataSetRepository.getDatasetsActiveProject());
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue