This commit is contained in:
IDONTSUDO 2024-04-15 18:24:44 +03:00
parent c10cdb8158
commit 78ebb748ea
19 changed files with 2032 additions and 124 deletions

3
.prettierrc Normal file
View file

@ -0,0 +1,3 @@
{
"printWidth":120
}

1
p.ts
View file

@ -1 +0,0 @@

1873
server/package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -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"
} }
} }

View file

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

View 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()
}
}

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -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 ?? ""}

View file

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

View file

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

View file

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

View file

@ -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] },
};

View file

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

View file

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

View file

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