From fa645dde923d26ee148c6d1b585fee5ae34b69da Mon Sep 17 00:00:00 2001 From: IDONTSUDO Date: Mon, 20 Nov 2023 00:48:40 +0300 Subject: [PATCH] progress --- .vscode/settings.json | 1 + server/package.json | 1 + server/src/core/controllers/app.ts | 44 +++------ .../src/core/controllers/http_controller.ts | 27 ++++-- server/src/core/di/env.ts | 78 +++++++-------- server/src/core/di/register_di.ts | 94 +++++++++---------- server/src/core/extensions/array.ts | 44 ++++++--- server/src/core/extensions/extensions.ts | 22 ++++- server/src/core/extensions/string.ts | 14 +++ .../src/core/model/active_pipeline_model.ts | 20 ++++ .../services/pipeline_real_time_service.ts | 34 +++---- ..._and_create_static_files_folder_usecase.ts | 22 +++++ .../core/usecases/database_connect_usecase.ts | 13 +++ .../usecases/search_database_model_usecase.ts | 19 +++- ...ve_pipeline_to_realtime_service_usecase.ts | 26 +++++ .../src/features/pipelines/pipeline_model.ts | 37 ++++++-- .../pipelines/pipeline_presentation.ts | 6 +- .../create_new_project_scenario.ts | 15 ++- .../project_instance_model.ts | 45 +++++++++ .../project_instance_presentation.ts | 23 +++++ .../src/features/projects/projects_model.ts | 23 ++--- .../projects/projects_presentation.ts | 2 - .../realtime/realtime_presentation.ts | 2 +- .../usecases/pipeline_status_usecase.ts | 4 +- .../usecases/run_instance_pipeline_usecase.ts | 37 +++++--- server/src/main.ts | 8 +- .../pipeline_real_time_service_test.ts | 2 +- server/todo.md | 5 + ui/src/core/extensions/array.ts | 11 ++- ui/src/core/extensions/extensions.ts | 1 + .../src/core/model/active_pipiline.ts | 3 +- ui/src/core/routers/routers.tsx | 20 +++- ui/src/core/store/base_store.ts | 22 +++++ ui/src/core/ui/header/header.tsx | 4 +- .../all_projects/data/project_repository.ts | 23 ++++- .../presentation/all_projects_screen.tsx | 3 +- .../presentation/all_projects_store.ts | 28 +----- .../presentation/create_pipeline_store.ts | 14 ++- .../create_project/create_project_store.ts | 10 +- .../create_project_instance.tsx | 27 ++++++ .../create_project_instance_repository.ts | 10 ++ .../create_project_instance_store.ts | 18 ++++ .../presentation/trigger_store.ts | 11 ++- .../pipeline_instance_repository.ts | 1 + .../pipeline_instance_screen.tsx | 21 +++-- .../pipeline_instance_store.ts | 9 ++ .../select_project/model/project_model.ts | 3 +- .../presentation/select_project.tsx | 16 +++- .../presentation/select_project_store.ts | 9 +- .../features/socket_lister/socket_lister.tsx | 2 +- .../socket_lister/socket_lister_store.ts | 4 +- 51 files changed, 657 insertions(+), 281 deletions(-) create mode 100644 server/src/core/extensions/string.ts create mode 100644 server/src/core/model/active_pipeline_model.ts create mode 100644 server/src/core/usecases/check_and_create_static_files_folder_usecase.ts create mode 100644 server/src/core/usecases/database_connect_usecase.ts create mode 100644 server/src/core/usecases/set_active_pipeline_to_realtime_service_usecase.ts rename server/src/features/{projects => project_instance}/create_new_project_scenario.ts (77%) create mode 100644 server/src/features/project_instance/project_instance_model.ts create mode 100644 server/src/features/project_instance/project_instance_presentation.ts create mode 100644 server/todo.md rename server/src/core/model/pipeline_meta.ts => ui/src/core/model/active_pipiline.ts (77%) create mode 100644 ui/src/core/store/base_store.ts create mode 100644 ui/src/features/create_project_instance/create_project_instance.tsx create mode 100644 ui/src/features/create_project_instance/create_project_instance_repository.ts create mode 100644 ui/src/features/create_project_instance/create_project_instance_store.ts create mode 100644 ui/src/features/pipeline_instance_main_screen/pipeline_instance_repository.ts create mode 100644 ui/src/features/pipeline_instance_main_screen/pipeline_instance_store.ts diff --git a/.vscode/settings.json b/.vscode/settings.json index c6bb237..fd6d6c0 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -17,6 +17,7 @@ }, "cSpell.words": [ "antd", + "fileupload", "uuidv" ] } \ No newline at end of file diff --git a/server/package.json b/server/package.json index 766580a..d77916b 100644 --- a/server/package.json +++ b/server/package.json @@ -37,6 +37,7 @@ "concurrently": "^8.2.0", "cors": "^2.8.5", "express": "^4.18.2", + "express-fileupload": "^1.4.2", "first-di": "^1.0.11", "md5": "^2.3.0", "mongoose": "^7.6.2", diff --git a/server/src/core/controllers/app.ts b/server/src/core/controllers/app.ts index 36037a5..dd59362 100644 --- a/server/src/core/controllers/app.ts +++ b/server/src/core/controllers/app.ts @@ -1,13 +1,14 @@ import express from "express"; import { Routes } from "../interfaces/router"; import cors from "cors"; -import mongoose from "mongoose"; import { Server } from "socket.io"; import { createServer } from "http"; import { SocketSubscriber } from "./socket_controller"; import { dirname } from "path"; -import { CreateFolderUseCase } from "../usecases/crete_folder_usecase"; -import { dirIsExists } from "../repository/fs"; +import fileUpload from "express-fileupload"; +import { SetLastActivePipelineToRealTimeServiceUseCase } from "../usecases/set_active_pipeline_to_realtime_service_usecase"; +import { CheckAndCreateStaticFilesFolderUseCase } from "../usecases/check_and_create_static_files_folder_usecase"; +import { DataBaseConnectUseCase } from "../usecases/database_connect_usecase"; export class App { public app: express.Application; @@ -60,6 +61,11 @@ export class App { this.app.use(express.json()); this.app.use(express.urlencoded({ extended: true })); this.app.use(express.static("public")); + this.app.use( + fileUpload({ + createParentPath: true, + }) + ); } private initializeRoutes(routes: Routes[]) { @@ -68,37 +74,11 @@ export class App { }); } async loadAppDependencies() { - // await locator( - // this.env == "development" - // ? new DevEnv(this.computedFolder) - // : new UnitTestEnv(this.computedFolder) - // ); - await this.appStartController(); - - mongoose - .connect("mongodb://127.0.0.1:27017/test") - .then(() => {}) - .catch((e) => { - console.log("ERROR:", e); - }); + await new DataBaseConnectUseCase().call(); + await new CheckAndCreateStaticFilesFolderUseCase().call(); + await new SetLastActivePipelineToRealTimeServiceUseCase().call(); } - async appStartController() { - if (await dirIsExists(App.staticFilesStoreDir())) { - return; - } - const createFolderUseCase = await new CreateFolderUseCase().call( - App.staticFilesStoreDir() - ); - - createFolderUseCase.fold( - (_s) => {}, - (e) => { - // TODO:(IDONTSUDO) need logger - console.log(e); - } - ); - } static staticFilesStoreDir = () => { const dir = dirname(__filename); const rootDir = dir.slice(0, dir.length - 20); diff --git a/server/src/core/controllers/http_controller.ts b/server/src/core/controllers/http_controller.ts index fc760cf..f2cb1fb 100644 --- a/server/src/core/controllers/http_controller.ts +++ b/server/src/core/controllers/http_controller.ts @@ -13,14 +13,19 @@ type Method = | "options" | "head"; -export type CallbackStrategyWithValidationModel = ( - a: T -) => Promise>; -// TODO(IDOTSUDO):NEED IMPLEMENTS -// interface ISubSetFeatureRouter{ -// method:Method, -// fn:CallbackStrategyWithValidationModel -// } +export type ResponseBase = Promise>; + +// TODO(IDONTSUDO): rewrite the router for the strategy +export type CallbackStrategyWithEmpty = () => ResponseBase; +export type CallbackStrategyWithValidationModel = (a: T) => ResponseBase; +export type CallbackStrategyWithIdQuery = (id: string) => ResponseBase; +export type CallBackStrategyWithQueryPage = (page: string) => ResponseBase; +export type CallbackStrategyWithFileUpload = (file: File) => ResponseBase; + +interface ISubSetFeatureRouter { + method: Method; + fn: CallbackStrategyWithValidationModel; +} abstract class ICoreHttpController { abstract mainURL: string; @@ -31,6 +36,7 @@ abstract class ICoreHttpController { export class CoreHttpController implements ICoreHttpController { mainURL: string; validationModel: any; + subRoutes: ISubSetFeatureRouter[] = []; routes = { POST: null, @@ -47,6 +53,11 @@ export class CoreHttpController implements ICoreHttpController { } call(): Routes { + if (this.subRoutes.isNotEmpty()) { + this.subRoutes.map((el) => { + console.log(this.router[el.method]); + }); + } if (this.routes["POST"] != null) { this.router.post( this.mainURL, diff --git a/server/src/core/di/env.ts b/server/src/core/di/env.ts index 55841e6..3c1786c 100644 --- a/server/src/core/di/env.ts +++ b/server/src/core/di/env.ts @@ -1,44 +1,44 @@ -import { Service } from "typedi"; +// import { Service } from "typedi"; -@Service() -export class IEnv{ - rootFolder!: string; - constructor(){ +// @Service() +// export class IEnv{ +// rootFolder!: string; +// constructor(){ - } - toStringEnv(){ - return '' - } - static env(){ - return '' - } -} +// } +// toStringEnv(){ +// return '' +// } +// static env(){ +// return '' +// } +// } -@Service() -export class DevEnv implements IEnv { - rootFolder:string; - constructor(rootFolder:string){ - this.rootFolder = rootFolder - } - toStringEnv(): string { - return DevEnv.env() - } - static env(){ - return 'DevEnv' +// @Service() +// export class DevEnv implements IEnv { +// rootFolder:string; +// constructor(rootFolder:string){ +// this.rootFolder = rootFolder +// } +// toStringEnv(): string { +// return DevEnv.env() +// } +// static env(){ +// return 'DevEnv' - } -} -@Service() -export class UnitTestEnv implements IEnv{ - rootFolder:string; - constructor(rootFolder:string){ - this.rootFolder = rootFolder - } - toStringEnv(): string { - return UnitTestEnv.env() - } - static env(){ - return 'UnitTestEnv' +// } +// } +// @Service() +// export class UnitTestEnv implements IEnv{ +// rootFolder:string; +// constructor(rootFolder:string){ +// this.rootFolder = rootFolder +// } +// toStringEnv(): string { +// return UnitTestEnv.env() +// } +// static env(){ +// return 'UnitTestEnv' - } -} \ No newline at end of file +// } +// } \ No newline at end of file diff --git a/server/src/core/di/register_di.ts b/server/src/core/di/register_di.ts index 77c6b6d..684bd08 100644 --- a/server/src/core/di/register_di.ts +++ b/server/src/core/di/register_di.ts @@ -1,53 +1,53 @@ -import { DevEnv, IEnv, UnitTestEnv } from "./env"; -import { extensions } from "../extensions/extensions"; -// import { Container, Service } from 'typedi'; +// import { DevEnv, IEnv, UnitTestEnv } from "./env"; +// import { extensions } from "../extensions/extensions"; +// // import { Container, Service } from 'typedi'; -export default function locator(env: IEnv) { - extensions(); - envRegister(env); - registerRepository(env); - registerController(env); - registerService(env); - // override(MetaDataFileManagerModel, MetaDataFileManagerModel); -} +// export default function locator(env: IEnv) { +// extensions(); +// envRegister(env); +// registerRepository(env); +// registerController(env); +// registerService(env); +// // override(MetaDataFileManagerModel, MetaDataFileManagerModel); +// } -const envRegister = (env: IEnv) => { - switch (env.toStringEnv()) { - case UnitTestEnv.env(): - // override(IEnv, UnitTestEnv); - return; - case "DevEnv": - // override(IEnv, DevEnv); - return; - } -}; +// const envRegister = (env: IEnv) => { +// switch (env.toStringEnv()) { +// case UnitTestEnv.env(): +// // override(IEnv, UnitTestEnv); +// return; +// case "DevEnv": +// // override(IEnv, DevEnv); +// return; +// } +// }; -const registerRepository = (env: IEnv) => { - switch (env.toStringEnv()) { - case UnitTestEnv.env(): - // override(IEnv, UnitTestEnv); +// const registerRepository = (env: IEnv) => { +// switch (env.toStringEnv()) { +// case UnitTestEnv.env(): +// // override(IEnv, UnitTestEnv); - return; - case DevEnv.env(): - // override(IEnv, DevEnv); - return; - } -}; +// return; +// case DevEnv.env(): +// // override(IEnv, DevEnv); +// return; +// } +// }; -const registerController = (env: IEnv) => { - switch (env.toStringEnv()) { - case UnitTestEnv.env(): - return; - case DevEnv.env(): - return; - } -}; +// const registerController = (env: IEnv) => { +// switch (env.toStringEnv()) { +// case UnitTestEnv.env(): +// return; +// case DevEnv.env(): +// return; +// } +// }; -const registerService = (env: IEnv) => { - switch (env.toStringEnv()) { - case UnitTestEnv.env(): - return; - case DevEnv.env(): - return; - } -}; +// const registerService = (env: IEnv) => { +// switch (env.toStringEnv()) { +// case UnitTestEnv.env(): +// return; +// case DevEnv.env(): +// return; +// } +// }; diff --git a/server/src/core/extensions/array.ts b/server/src/core/extensions/array.ts index 46e38d1..b07130d 100644 --- a/server/src/core/extensions/array.ts +++ b/server/src/core/extensions/array.ts @@ -1,25 +1,18 @@ -export {}; - -declare global { - interface Array { - // @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. - equals(array: Array, strict: boolean): boolean; - } -} - -export const ArrayEquals = () => { - if ([].equals == undefined) { +/* eslint-disable @typescript-eslint/no-this-alias */ +export const ArrayExtensions = () => { + if ([].equals === undefined) { + // eslint-disable-next-line no-extend-native Array.prototype.equals = function (array, strict = true) { if (!array) return false; - if (arguments.length == 1) strict = true; + if (arguments.length === 1) strict = true; - if (this.length != array.length) return false; + if (this.length !== array.length) return false; for (let i = 0; i < this.length; i++) { if (this[i] instanceof Array && array[i] instanceof Array) { if (!this[i].equals(array[i], strict)) return false; - } else if (strict && this[i] != array[i]) { + } else if (strict && this[i] !== array[i]) { return false; } else if (!strict) { return this.sort().equals(array.sort(), true); @@ -28,4 +21,27 @@ export const ArrayEquals = () => { return true; }; } + if ([].lastElement === undefined) { + // eslint-disable-next-line no-extend-native + Array.prototype.lastElement = function () { + const instanceCheck = this; + if (instanceCheck === undefined) { + return undefined; + } else { + const instance = instanceCheck as []; + return instance[instance.length - 1]; + } + }; + } + if ([].isEmpty === undefined) { + // eslint-disable-next-line no-extend-native + Array.prototype.isEmpty = function () { + return this.length === 0; + }; + } + if ([].isNotEmpty === undefined) { + Array.prototype.isNotEmpty = function () { + return this.length !== 0; + }; + } }; diff --git a/server/src/core/extensions/extensions.ts b/server/src/core/extensions/extensions.ts index c02556b..5e33eb8 100644 --- a/server/src/core/extensions/extensions.ts +++ b/server/src/core/extensions/extensions.ts @@ -1,6 +1,20 @@ -import { ArrayEquals } from "./array"; +import { ArrayExtensions } from "./array"; +import { StringExtensions } from "./string"; -export const extensions = () =>{ - ArrayEquals() +declare global { + interface Array { + // @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. + equals(array: Array, strict: boolean): boolean; + lastElement(): T | undefined; + isEmpty(): boolean; + isNotEmpty(): boolean; + } + interface String { + isEmpty(): boolean; + isNotEmpty(): boolean; + } } - \ No newline at end of file +export const extensions = () => { + ArrayExtensions(); + StringExtensions(); +}; diff --git a/server/src/core/extensions/string.ts b/server/src/core/extensions/string.ts new file mode 100644 index 0000000..86b5246 --- /dev/null +++ b/server/src/core/extensions/string.ts @@ -0,0 +1,14 @@ +export const StringExtensions = () => { + if ("".isEmpty === undefined) { + // eslint-disable-next-line no-extend-native + String.prototype.isEmpty = function () { + return this.length === 0; + }; + } + if ("".isNotEmpty === undefined) { + // eslint-disable-next-line no-extend-native + String.prototype.isNotEmpty = function () { + return this.length !== 0; + }; + } +}; diff --git a/server/src/core/model/active_pipeline_model.ts b/server/src/core/model/active_pipeline_model.ts new file mode 100644 index 0000000..3862adf --- /dev/null +++ b/server/src/core/model/active_pipeline_model.ts @@ -0,0 +1,20 @@ +export class ActivePipeline { + pipelineIsRunning: boolean; + projectUUID?: string | null; + lastProcessCompleteCount: number | null; + error: any; + constructor( + pipelineIsRunning: boolean, + lastProcessCompleteCount: number | null, + error: any, + projectUUID?: string | null + ) { + this.pipelineIsRunning = pipelineIsRunning; + this.projectUUID = projectUUID; + this.lastProcessCompleteCount = lastProcessCompleteCount; + this.error = error; + } + static empty() { + return new ActivePipeline(false, null, null, null); + } +} diff --git a/server/src/core/services/pipeline_real_time_service.ts b/server/src/core/services/pipeline_real_time_service.ts index 070ac61..ea41c08 100644 --- a/server/src/core/services/pipeline_real_time_service.ts +++ b/server/src/core/services/pipeline_real_time_service.ts @@ -1,24 +1,21 @@ import { TypedEvent } from "../helper/typed_event"; import { ExecError } from "../model/exec_error_model"; import { ExecutorResult } from "../model/executor_result"; -import { IPipelineMeta } from "../model/pipeline_meta"; +import { ActivePipeline } from "../model/active_pipeline_model"; import { IPipeline } from "../model/process_model"; import { Iteration, StackService } from "./stack_service"; -export class PipelineRealTimeService extends TypedEvent { - status: IPipelineMeta; +export class PipelineRealTimeService extends TypedEvent { + status: ActivePipeline; pipelineModels?: IPipeline[]; + path: string; constructor() { super(); this.init(); } private init(): void { - this.status = { - pipelineIsRunning: false, - projectUUID: null, - lastProcessCompleteCount: null, - error: null, - }; + this.status = ActivePipeline.empty(); + } pipelineSubscriber = (iterations: Iteration[]): void => { if (this.status["lastProcessCompleteCount"] === 0) { @@ -65,16 +62,21 @@ export class PipelineRealTimeService extends TypedEvent { this.status.pipelineIsRunning = false; } } - - runPipeline( + setPipelineDependency( pipelineModels: IPipeline[], path: string, projectUUID: string - ): void { - const stack = new StackService(pipelineModels, path); + ) { + this.pipelineModels = pipelineModels; + this.path = path; this.status["projectUUID"] = projectUUID; - this.status["pipelineIsRunning"] = true; - stack.on(this.pipelineSubscriber); - stack.call(); + } + runPipeline(): void { + + // const stack = new StackService(this.pipelineModels, this.path); + + // this.status["pipelineIsRunning"] = true; + // stack.on(this.pipelineSubscriber); + // stack.call(); } } diff --git a/server/src/core/usecases/check_and_create_static_files_folder_usecase.ts b/server/src/core/usecases/check_and_create_static_files_folder_usecase.ts new file mode 100644 index 0000000..6350228 --- /dev/null +++ b/server/src/core/usecases/check_and_create_static_files_folder_usecase.ts @@ -0,0 +1,22 @@ +import { App } from "../controllers/app"; +import { dirIsExists } from "../repository/fs"; +import { CreateFolderUseCase } from "./crete_folder_usecase"; + +export class CheckAndCreateStaticFilesFolderUseCase { + call = async (): Promise => { + if (await dirIsExists(App.staticFilesStoreDir())) { + return; + } + const createFolderUseCase = await new CreateFolderUseCase().call( + App.staticFilesStoreDir() + ); + + createFolderUseCase.fold( + (_s) => {}, + (e) => { + console.log(e); + } + ); + }; + } + \ No newline at end of file diff --git a/server/src/core/usecases/database_connect_usecase.ts b/server/src/core/usecases/database_connect_usecase.ts new file mode 100644 index 0000000..c2a8c65 --- /dev/null +++ b/server/src/core/usecases/database_connect_usecase.ts @@ -0,0 +1,13 @@ +import mongoose from "mongoose"; +import { Result } from "../helper/result"; + +export class DataBaseConnectUseCase { + call = async (): Promise> => { + try { + await mongoose.connect("mongodb://127.0.0.1:27017/test"); + return Result.ok(); + } catch (error) { + return Result.error(error as Error); + } + }; +} diff --git a/server/src/core/usecases/search_database_model_usecase.ts b/server/src/core/usecases/search_database_model_usecase.ts index 860c9f0..a184be7 100644 --- a/server/src/core/usecases/search_database_model_usecase.ts +++ b/server/src/core/usecases/search_database_model_usecase.ts @@ -1,3 +1,18 @@ -export class RegExpSearchDataBaseModelUseCase { - call = () => {}; +import { Result } from "../helper/result"; + +export class SearchDataBaseModelUseCase { + model: any; + + constructor(model: any) { + this.model = model; + } + + call = async (findFilter: Partial): Promise> => { + const result = await this.model.findOne(findFilter); + if (result === null) { + return Result.error(null); + } else { + return Result.ok(result); + } + }; } diff --git a/server/src/core/usecases/set_active_pipeline_to_realtime_service_usecase.ts b/server/src/core/usecases/set_active_pipeline_to_realtime_service_usecase.ts new file mode 100644 index 0000000..4f84feb --- /dev/null +++ b/server/src/core/usecases/set_active_pipeline_to_realtime_service_usecase.ts @@ -0,0 +1,26 @@ +import { + IProjectInstanceModel, + ProjectInstanceDbModel, +} from "../../features/project_instance/project_instance_model"; + +import { pipelineRealTimeService } from "../../features/realtime/realtime_presentation"; +import { App } from "../controllers/app"; +import { SearchDataBaseModelUseCase } from "./search_database_model_usecase"; + +export class SetLastActivePipelineToRealTimeServiceUseCase { + call = async (): Promise => { + const result = await new SearchDataBaseModelUseCase( + ProjectInstanceDbModel + ).call({ + isActive: true, + }); + if (result.isSuccess()) { + const projectModel = result.value.project; + pipelineRealTimeService.setPipelineDependency( + projectModel.pipelines, + App.staticFilesStoreDir() + projectModel.rootDir + "/", + projectModel._id + ); + } + }; +} diff --git a/server/src/features/pipelines/pipeline_model.ts b/server/src/features/pipelines/pipeline_model.ts index 28170cf..0a1a29e 100644 --- a/server/src/features/pipelines/pipeline_model.ts +++ b/server/src/features/pipelines/pipeline_model.ts @@ -1,8 +1,13 @@ -import { IsMongoId, IsOptional } from "class-validator"; +import { IsMongoId, IsOptional, ValidateNested } from "class-validator"; import { Schema, model } from "mongoose"; -import { IProcess, StackGenerateType } from "../../core/model/process_model"; +import { + IPipeline, + IProcess, + StackGenerateType, +} from "../../core/model/process_model"; import { TriggerModel, triggerSchema } from "../triggers/trigger_model"; -import { schemaProcess } from "../process/process_model"; +import { ProcessModel, schemaProcess } from "../process/process_model"; +import { Type } from "class-transformer"; export const PipelineSchema = new Schema({ process: { @@ -17,21 +22,21 @@ export const PipelineSchema = new Schema({ autopopulate: true, default: null, }, + stackGenerateType: { + type: String, + default: null, + }, }).plugin(require("mongoose-autopopulate")); export const schemaPipeline = "Pipeline"; -export const PipelineDBModel = model( - schemaPipeline, - PipelineSchema -); +export const PipelineDBModel = model(schemaPipeline, PipelineSchema); -export class PipelineModel { +export class PipelineValidationModel { @IsMongoId() public process: IProcess; @IsMongoId() - //TODO(IDONTSUDO):NEED OPTION DECORATOR?? public trigger: TriggerModel; @IsOptional() @@ -40,3 +45,17 @@ export class PipelineModel { @IsOptional() public stackGenerateType: StackGenerateType; } + +export class PipelineModel implements IPipeline { + @ValidateNested() + @Type(() => ProcessModel) + public process: IProcess; + + @ValidateNested() + @Type(() => TriggerModel) + public trigger: TriggerModel; + @IsOptional() + public env = null; + @IsOptional() + public stackGenerateType: StackGenerateType; +} diff --git a/server/src/features/pipelines/pipeline_presentation.ts b/server/src/features/pipelines/pipeline_presentation.ts index d213884..68a88d9 100644 --- a/server/src/features/pipelines/pipeline_presentation.ts +++ b/server/src/features/pipelines/pipeline_presentation.ts @@ -1,14 +1,14 @@ import { CrudController } from "../../core/controllers/crud_controller"; -import { PipelineDBModel, PipelineModel } from "./pipeline_model"; +import { PipelineDBModel, PipelineValidationModel } from "./pipeline_model"; export class PipelinePresentation extends CrudController< - PipelineModel, + PipelineValidationModel, typeof PipelineDBModel > { constructor() { super({ url: "pipeline", - validationModel: PipelineModel, + validationModel: PipelineValidationModel, databaseModel: PipelineDBModel, }); } diff --git a/server/src/features/projects/create_new_project_scenario.ts b/server/src/features/project_instance/create_new_project_scenario.ts similarity index 77% rename from server/src/features/projects/create_new_project_scenario.ts rename to server/src/features/project_instance/create_new_project_scenario.ts index b4aa832..bd959ac 100644 --- a/server/src/features/projects/create_new_project_scenario.ts +++ b/server/src/features/project_instance/create_new_project_scenario.ts @@ -2,11 +2,16 @@ import { App } from "../../core/controllers/app"; import { Result } from "../../core/helper/result"; import { CreateDataBaseModelUseCase } from "../../core/usecases/create_database_model_usecase"; import { CreateFolderUseCase } from "../../core/usecases/crete_folder_usecase"; -import { ProjectDBModel, ProjectValidationModel } from "./projects_model"; +import { + ProjectInstanceDbModel, + ProjectInstanceValidationModel, +} from "./project_instance_model"; import { v4 as uuidv4 } from "uuid"; -export class CreateNewProjectScenario { - call = async (model: ProjectValidationModel): Promise> => { +export class CreateNewProjectInstanceScenario { + call = async ( + model: ProjectInstanceValidationModel + ): Promise> => { try { const folderName = uuidv4() + "/"; const createFolderUseCase = await new CreateFolderUseCase().call( @@ -15,10 +20,10 @@ export class CreateNewProjectScenario { if (createFolderUseCase.isFailure()) { return createFolderUseCase.forward(); } - model.rootDir = folderName; + const createDataBaseModelUseCase = await new CreateDataBaseModelUseCase( - ProjectDBModel + ProjectInstanceDbModel ).call(model); if (createDataBaseModelUseCase.isFailure()) { diff --git a/server/src/features/project_instance/project_instance_model.ts b/server/src/features/project_instance/project_instance_model.ts new file mode 100644 index 0000000..e0df091 --- /dev/null +++ b/server/src/features/project_instance/project_instance_model.ts @@ -0,0 +1,45 @@ +import { Schema, model } from "mongoose"; +import { IProjectModel, projectSchema } from "../projects/projects_model"; +import { IsMongoId, IsOptional, IsString } from "class-validator"; + +export interface IProjectInstanceModel { + project: IProjectModel; + description: string; + rootDir: string; + isActive: boolean; +} + +export const ProjectInstanceSchema = new Schema({ + project: { + type: Schema.Types.ObjectId, + ref: projectSchema, + autopopulate: true, + default: null, + }, + description: { + type: String, + }, + rootDir: { + type: String, + }, + isActive: { + type: Boolean, + default: false, + }, +}).plugin(require("mongoose-autopopulate")); + +export const schemaProjectInstance = "instance_project"; + +export const ProjectInstanceDbModel = model( + schemaProjectInstance, + ProjectInstanceSchema +); + +export class ProjectInstanceValidationModel { + @IsMongoId() + public project: string; + @IsString() + public description: string; + @IsOptional() + public rootDir: string; +} diff --git a/server/src/features/project_instance/project_instance_presentation.ts b/server/src/features/project_instance/project_instance_presentation.ts new file mode 100644 index 0000000..475f241 --- /dev/null +++ b/server/src/features/project_instance/project_instance_presentation.ts @@ -0,0 +1,23 @@ +import { CrudController } from "../../core/controllers/crud_controller"; +import { CreateNewProjectInstanceScenario } from "./create_new_project_scenario"; +import { + ProjectInstanceDbModel, + ProjectInstanceValidationModel, +} from "./project_instance_model"; + +export class ProjectInstancePresentation extends CrudController< + ProjectInstanceValidationModel, + typeof ProjectInstanceDbModel +> { + constructor() { + super({ + validationModel: ProjectInstanceValidationModel, + url: "project_instance", + databaseModel: ProjectInstanceDbModel, + }); + super.post(new CreateNewProjectInstanceScenario().call); + // super.router.post(this.mainURL + "/file", (req, res) => { + // TODO: + // }); + } +} diff --git a/server/src/features/projects/projects_model.ts b/server/src/features/projects/projects_model.ts index 5aa7f6a..0bea360 100644 --- a/server/src/features/projects/projects_model.ts +++ b/server/src/features/projects/projects_model.ts @@ -1,12 +1,13 @@ import { Schema, model } from "mongoose"; -import { PipelineModel, schemaPipeline } from "../pipelines/pipeline_model"; -import { IsArray, IsOptional, IsString } from "class-validator"; +import { PipelineValidationModel, schemaPipeline } from "../pipelines/pipeline_model"; +import { IsArray, IsString } from "class-validator"; export interface IProjectModel { - _id?:string; - pipelines: [PipelineModel]; + _id?: string; + pipelines: [PipelineValidationModel]; rootDir: string; description: string; + isActive:boolean; } export const ProjectSchema = new Schema({ @@ -16,23 +17,23 @@ export const ProjectSchema = new Schema({ autopopulate: true, default: null, }, - rootDir: { - type: String, - }, description: { type: String, }, + isActive: { + type: Boolean, + default: false, + }, }).plugin(require("mongoose-autopopulate")); -const schema = "Projects"; +export const projectSchema = "Projects"; -export const ProjectDBModel = model(schema, ProjectSchema); +export const ProjectDBModel = model(projectSchema, ProjectSchema); export class ProjectValidationModel { @IsArray() public pipelines: [string]; @IsString() public description: string; - @IsOptional() - public rootDir: string; + } diff --git a/server/src/features/projects/projects_presentation.ts b/server/src/features/projects/projects_presentation.ts index abd4b45..9d72b50 100644 --- a/server/src/features/projects/projects_presentation.ts +++ b/server/src/features/projects/projects_presentation.ts @@ -1,5 +1,4 @@ import { CrudController } from "../../core/controllers/crud_controller"; -import { CreateNewProjectScenario } from "./create_new_project_scenario"; import { ProjectDBModel, ProjectValidationModel } from "./projects_model"; export class ProjectsPresentation extends CrudController< @@ -12,6 +11,5 @@ export class ProjectsPresentation extends CrudController< validationModel: ProjectValidationModel, databaseModel: ProjectDBModel, }); - super.post(new CreateNewProjectScenario().call); } } diff --git a/server/src/features/realtime/realtime_presentation.ts b/server/src/features/realtime/realtime_presentation.ts index 06ed145..e9f70e8 100644 --- a/server/src/features/realtime/realtime_presentation.ts +++ b/server/src/features/realtime/realtime_presentation.ts @@ -3,7 +3,7 @@ import { CoreHttpController } from "../../core/controllers/http_controller"; import { PipelineRealTimeService } from "../../core/services/pipeline_real_time_service"; import { RunInstancePipelineUseCase } from "./usecases/run_instance_pipeline_usecase"; import { PipelineStatusUseCase } from "./usecases/pipeline_status_usecase"; - + export const pipelineRealTimeService = new PipelineRealTimeService(); export class RealTimeValidationModel { diff --git a/server/src/features/realtime/usecases/pipeline_status_usecase.ts b/server/src/features/realtime/usecases/pipeline_status_usecase.ts index b07870d..c173e61 100644 --- a/server/src/features/realtime/usecases/pipeline_status_usecase.ts +++ b/server/src/features/realtime/usecases/pipeline_status_usecase.ts @@ -1,9 +1,9 @@ import { Result } from "../../../core/helper/result"; -import { IPipelineMeta } from "../../../core/model/pipeline_meta"; +import { ActivePipeline } from "../../../core/model/active_pipeline_model"; import { pipelineRealTimeService } from "../realtime_presentation"; export class PipelineStatusUseCase { - async call(): Promise> { + async call(): Promise> { try { return Result.ok(pipelineRealTimeService.status); } catch (error) { diff --git a/server/src/features/realtime/usecases/run_instance_pipeline_usecase.ts b/server/src/features/realtime/usecases/run_instance_pipeline_usecase.ts index 8dd4497..2f05efa 100644 --- a/server/src/features/realtime/usecases/run_instance_pipeline_usecase.ts +++ b/server/src/features/realtime/usecases/run_instance_pipeline_usecase.ts @@ -1,8 +1,11 @@ import { App } from "../../../core/controllers/app"; import { Result } from "../../../core/helper/result"; -import { EXEC_TYPE } from "../../../core/model/exec_error_model"; import { ReadByIdDataBaseModelUseCase } from "../../../core/usecases/read_by_id_database_model_usecase"; -import { IProjectModel, ProjectDBModel } from "../../projects/projects_model"; +import { UpdateDataBaseModelUseCase } from "../../../core/usecases/update_database_model_usecase"; +import { + IProjectInstanceModel, + ProjectInstanceDbModel, +} from "../../project_instance/project_instance_model"; import { RealTimeValidationModel, pipelineRealTimeService, @@ -10,29 +13,35 @@ import { export class RunInstancePipelineUseCase { async call(model: RealTimeValidationModel): Promise> { - const id = model.id; + const { id } = model; + const readByIdDataBaseModelUseCase = - await new ReadByIdDataBaseModelUseCase( - ProjectDBModel + await new ReadByIdDataBaseModelUseCase( + ProjectInstanceDbModel ).call(id); + if (readByIdDataBaseModelUseCase.isFailure()) { return readByIdDataBaseModelUseCase.forward(); } - const projectModel = readByIdDataBaseModelUseCase.value; - projectModel.pipelines.map((el) => { - el.process.type = EXEC_TYPE.EXEC; - }); - - pipelineRealTimeService.runPipeline( + const projectModel = readByIdDataBaseModelUseCase.value.project; + projectModel.isActive = true; + + const updateDataBaseModelUseCase = await new UpdateDataBaseModelUseCase< + IProjectInstanceModel, + any + >(ProjectInstanceDbModel).call(projectModel); + + if (updateDataBaseModelUseCase.isFailure()) { + return updateDataBaseModelUseCase.forward(); + } + pipelineRealTimeService.setPipelineDependency( projectModel.pipelines, App.staticFilesStoreDir() + projectModel.rootDir + "/", projectModel._id ); + pipelineRealTimeService.runPipeline(); return Result.ok({ status: "ok" }); } } - -// /Users/idontsudo/Desktop/testdeck-mocha-seed/server/build/public/ce4e7710-73dc-47fc-87ee-d448ea2412ce -// new ObjectId("6554c22d2ef337587505a494") diff --git a/server/src/main.ts b/server/src/main.ts index c75c97a..48eefe2 100644 --- a/server/src/main.ts +++ b/server/src/main.ts @@ -10,13 +10,18 @@ import { RealTimePresentation, pipelineRealTimeService, } from "./features/realtime/realtime_presentation"; - +import { extensions } from "./core/extensions/extensions"; +import { ProjectInstancePresentation } from "./features/project_instance/project_instance_presentation"; + +extensions(); + const httpRoutes: Routes[] = [ new TriggerPresentation(), new ProjectsPresentation(), new ProcessPresentation(), new PipelinePresentation(), new RealTimePresentation(), + new ProjectInstancePresentation(), ].map((el) => el.call()); const socketSubscribers = [ @@ -24,4 +29,3 @@ const socketSubscribers = [ ]; new App(httpRoutes, socketSubscribers).listen(); - \ No newline at end of file diff --git a/server/test/services/pipeline_real_time_service_test.ts b/server/test/services/pipeline_real_time_service_test.ts index e39e374..7aa28a1 100644 --- a/server/test/services/pipeline_real_time_service_test.ts +++ b/server/test/services/pipeline_real_time_service_test.ts @@ -7,6 +7,6 @@ export class PipelineRealTimeServiceTest extends PipelineRealTimeService { super(); } async test() { - this.runPipeline(mockSimplePipeline, dirname__, ""); + // this.runPipeline(mockSimplePipeline, dirname__, ""); } } diff --git a/server/todo.md b/server/todo.md new file mode 100644 index 0000000..095960d --- /dev/null +++ b/server/todo.md @@ -0,0 +1,5 @@ +создание инстанца [ OK ] +получение всех инастанцев проектов и изменнение их [ OK ] +запуск инастанца проекта? [ OK ] + +загрузка FILE [ ] \ No newline at end of file diff --git a/ui/src/core/extensions/array.ts b/ui/src/core/extensions/array.ts index 65ba388..0259bbe 100644 --- a/ui/src/core/extensions/array.ts +++ b/ui/src/core/extensions/array.ts @@ -1,3 +1,4 @@ +/* eslint-disable @typescript-eslint/no-this-alias */ export const ArrayExtensions = () => { if ([].equals === undefined) { // eslint-disable-next-line no-extend-native @@ -23,11 +24,11 @@ export const ArrayExtensions = () => { if ([].lastElement === undefined) { // eslint-disable-next-line no-extend-native Array.prototype.lastElement = function () { - let instanceCheck = this; + const instanceCheck = this; if (instanceCheck === undefined) { return undefined; } else { - let instance = instanceCheck as []; + const instance = instanceCheck as []; return instance[instance.length - 1]; } }; @@ -38,4 +39,10 @@ export const ArrayExtensions = () => { return this.length === 0; }; } + if ([].isNotEmpty === undefined) { + // eslint-disable-next-line no-extend-native + Array.prototype.isNotEmpty = function () { + return this.length !== 0; + }; + } }; diff --git a/ui/src/core/extensions/extensions.ts b/ui/src/core/extensions/extensions.ts index 9afea5e..b3476a5 100644 --- a/ui/src/core/extensions/extensions.ts +++ b/ui/src/core/extensions/extensions.ts @@ -7,6 +7,7 @@ declare global { equals(array: Array, strict: boolean): boolean; lastElement(): T | undefined; isEmpty(): boolean; + isNotEmpty():boolean; } interface String { isEmpty(): boolean; diff --git a/server/src/core/model/pipeline_meta.ts b/ui/src/core/model/active_pipiline.ts similarity index 77% rename from server/src/core/model/pipeline_meta.ts rename to ui/src/core/model/active_pipiline.ts index 749f0d3..2079613 100644 --- a/server/src/core/model/pipeline_meta.ts +++ b/ui/src/core/model/active_pipiline.ts @@ -1,4 +1,5 @@ -export interface IPipelineMeta { + +export interface ActivePipeline { pipelineIsRunning: boolean; projectUUID?: string | null; lastProcessCompleteCount: number | null; diff --git a/ui/src/core/routers/routers.tsx b/ui/src/core/routers/routers.tsx index 0223c37..ac7f418 100644 --- a/ui/src/core/routers/routers.tsx +++ b/ui/src/core/routers/routers.tsx @@ -23,15 +23,27 @@ import { CreateTriggerScreenPath, TriggerScreen, } from "../../features/create_trigger/presentation/create_trigger_screen"; -import { CreateProcessScreen, CreateProcessScreenPath } from "../../features/create_process/presentation/create_process_screen"; +import { + CreateProcessScreen, + CreateProcessScreenPath, +} from "../../features/create_process/presentation/create_process_screen"; +import { ProjectRepository } from "../../features/all_projects/data/project_repository"; +import { + CreateProjectInstancePath, + CreateProjectInstanceScreen, +} from "../../features/create_project_instance/create_project_instance"; + + +const idURL = ":id"; export const router = createBrowserRouter([ { path: AllProjectScreenPath, + loader: new ProjectRepository().loader, element: , }, { - path: PipelineInstanceScreenPath, + path: PipelineInstanceScreenPath + idURL, element: , }, { @@ -54,4 +66,8 @@ export const router = createBrowserRouter([ path: CreateProcessScreenPath, element: , }, + { + path: CreateProjectInstancePath + idURL, + element: , + }, ]); diff --git a/ui/src/core/store/base_store.ts b/ui/src/core/store/base_store.ts new file mode 100644 index 0000000..825a76e --- /dev/null +++ b/ui/src/core/store/base_store.ts @@ -0,0 +1,22 @@ +// TODO(IDONTSUDO): нужно переписать все запросы под BaseStore + +import { Result } from "../helper/result"; + +export class BaseStore { + isLoading = false; + isError = false; + + async loadingHelper(callBack: Promise>) { + this.isLoading = true; + + const result = await callBack; + if (result.isFailure()) { + this.isError = true; + this.isLoading = false; + return result.forward(); + } + + this.isLoading = false; + return result; + } +} diff --git a/ui/src/core/ui/header/header.tsx b/ui/src/core/ui/header/header.tsx index 3312300..a2810a0 100644 --- a/ui/src/core/ui/header/header.tsx +++ b/ui/src/core/ui/header/header.tsx @@ -8,7 +8,7 @@ import { useNavigate } from "react-router-dom"; const { Title } = Typography; export interface IHeader { - largeText: string; + largeText?: string; minText?: string; path?: string; needBackButton?: undefined | any; @@ -25,7 +25,7 @@ export const Header: React.FunctionComponent = (props: IHeader) => { marginTop: "20px", marginRight: "20px", display: "contents", - }} + }} > {needBackButton ? ( <> diff --git a/ui/src/features/all_projects/data/project_repository.ts b/ui/src/features/all_projects/data/project_repository.ts index 4d4609e..19641a9 100644 --- a/ui/src/features/all_projects/data/project_repository.ts +++ b/ui/src/features/all_projects/data/project_repository.ts @@ -1,8 +1,27 @@ -import { HttpMethod, HttpRepository } from "../../../core/repository/http_repository"; +import { redirect } from "react-router-dom"; +import { ActivePipeline } from "../../../core/model/active_pipiline"; +import { + HttpMethod, + HttpRepository, +} from "../../../core/repository/http_repository"; +import { PipelineInstanceScreenPath } from "../../pipeline_instance_main_screen/pipeline_instance_screen"; import { IProjectModel } from "../model/project_model"; export class ProjectRepository extends HttpRepository { async getAllProject() { - return this.jsonRequest(HttpMethod.GET,'/project') + return this.jsonRequest(HttpMethod.GET, "/project"); } + + async getActivePipeline() { + return this.jsonRequest(HttpMethod.GET, "/realtime"); + } + loader = async () => { + const result = await this.getActivePipeline(); + + // if (result.isSuccess() && result.value.projectUUID !== null) { + // return redirect(PipelineInstanceScreenPath + result.value.projectUUID); + // } + + return null; + }; } diff --git a/ui/src/features/all_projects/presentation/all_projects_screen.tsx b/ui/src/features/all_projects/presentation/all_projects_screen.tsx index fd5af5b..6248f6b 100644 --- a/ui/src/features/all_projects/presentation/all_projects_screen.tsx +++ b/ui/src/features/all_projects/presentation/all_projects_screen.tsx @@ -6,7 +6,7 @@ import { observer } from "mobx-react-lite"; import { SelectProjectScreenPath } from "../../select_project/presentation/select_project"; export const AllProjectScreenPath = "/"; - + export const AllProjectScreen: React.FunctionComponent = observer(() => { const [allProjectStore] = React.useState( () => new AllProjectStore(new ProjectRepository()) @@ -15,7 +15,6 @@ export const AllProjectScreen: React.FunctionComponent = observer(() => { return ( <> (callBack: Promise>) { - this.isLoading = true; - - const result = await callBack; - if (result.isFailure()) { - this.isError = true; - this.isLoading = false; - return result.forward(); - } - - this.isLoading = false; - return result; - } -} export class AllProjectStore extends BaseStore { projectsModels?: IProjectModel[]; repository: ProjectRepository; + redirect = false; constructor(repository: ProjectRepository) { super(); this.repository = repository; - this.getProjects(); makeAutoObservable(this); } + async getProjects() { const result = await this.loadingHelper(this.repository.getAllProject()); if (result.isSuccess()) { this.projectsModels = result.value; } } -} - \ No newline at end of file + +} diff --git a/ui/src/features/create_pipeline/presentation/create_pipeline_store.ts b/ui/src/features/create_pipeline/presentation/create_pipeline_store.ts index 71c3266..73ec514 100644 --- a/ui/src/features/create_pipeline/presentation/create_pipeline_store.ts +++ b/ui/src/features/create_pipeline/presentation/create_pipeline_store.ts @@ -1,9 +1,10 @@ -import { makeAutoObservable } from "mobx"; +import makeAutoObservable from "mobx-store-inheritance"; import { CreatePipelineRepository } from "../data/create_pipeline_repository"; import { ITriggerModel } from "../../../core/model/trigger_model"; import { IProcess } from "../../create_process/model/process_model"; import { message } from "antd"; - +import { BaseStore } from "../../../core/store/base_store"; + enum Type { PROCESS, TRIGGER, @@ -15,20 +16,23 @@ export interface UnionView { uuid?: string; } -export class CreatePipelineStore { +export class CreatePipelineStore extends BaseStore { repository: CreatePipelineRepository; triggersModels: ITriggerModel[] = []; processModels: IProcess[] = []; pipelineViewModels: UnionView[] = []; - isLoading = false; - isError = false; constructor(repository: CreatePipelineRepository) { + super(); this.repository = repository; makeAutoObservable(this); + this.init(); + } + private init() { this.loadTriggers(); this.loadProcess(); } + filterPipelineViewModel(index: number): void { this.pipelineViewModels = this.pipelineViewModels.filter( (_el, i) => i !== index diff --git a/ui/src/features/create_project/create_project_store.ts b/ui/src/features/create_project/create_project_store.ts index 49bcf62..73f634a 100644 --- a/ui/src/features/create_project/create_project_store.ts +++ b/ui/src/features/create_project/create_project_store.ts @@ -1,19 +1,20 @@ -import { makeAutoObservable } from "mobx"; +import makeAutoObservable from "mobx-store-inheritance"; import { CreateProjectRepository, PipelineModel, } from "./create_project_repository"; import { message } from "antd"; +import { BaseStore } from "../../core/store/base_store"; -class CreateProjectStore { +class CreateProjectStore extends BaseStore { repository: CreateProjectRepository; - isLoading = false; - isError = false; + pipelineModels?: PipelineModel[]; newProjectDescription: string = ""; newProjectViews: PipelineModel[] = []; constructor(repository: CreateProjectRepository) { + super(); this.repository = repository; makeAutoObservable(this); this.loadPipelines(); @@ -74,4 +75,3 @@ class CreateProjectStore { export const createProjectStore = new CreateProjectStore( new CreateProjectRepository() ); - diff --git a/ui/src/features/create_project_instance/create_project_instance.tsx b/ui/src/features/create_project_instance/create_project_instance.tsx new file mode 100644 index 0000000..cc0463b --- /dev/null +++ b/ui/src/features/create_project_instance/create_project_instance.tsx @@ -0,0 +1,27 @@ +import * as React from "react"; +import { CreateProjectInstanceStore } from "./create_project_instance_store"; +import { CreateProjectInstanceRepository } from "./create_project_instance_repository"; +import { observer } from "mobx-react-lite"; +import { Upload, Button } from "antd"; +import { useParams } from "react-router-dom"; + +export const CreateProjectInstancePath = "/create/project/instance/"; + +export const CreateProjectInstanceScreen = observer(() => { + const [createProjectInstanceStore] = React.useState( + () => new CreateProjectInstanceStore(new CreateProjectInstanceRepository()) + ); + const id = useParams().id; + createProjectInstanceStore.getProjectById(id as string) + return ( + <> + { + console.log(e); + }} + > + + + + ); +}); diff --git a/ui/src/features/create_project_instance/create_project_instance_repository.ts b/ui/src/features/create_project_instance/create_project_instance_repository.ts new file mode 100644 index 0000000..6b6d1b9 --- /dev/null +++ b/ui/src/features/create_project_instance/create_project_instance_repository.ts @@ -0,0 +1,10 @@ +import { + HttpMethod, + HttpRepository, +} from "../../core/repository/http_repository"; + +export class CreateProjectInstanceRepository extends HttpRepository { + async getProjectInstance(id: string) { + return await this.jsonRequest(HttpMethod.GET, ""); + } +} diff --git a/ui/src/features/create_project_instance/create_project_instance_store.ts b/ui/src/features/create_project_instance/create_project_instance_store.ts new file mode 100644 index 0000000..be7a346 --- /dev/null +++ b/ui/src/features/create_project_instance/create_project_instance_store.ts @@ -0,0 +1,18 @@ +import makeAutoObservable from "mobx-store-inheritance"; +import { BaseStore } from "../../core/store/base_store"; +import { CreateProjectInstanceRepository } from "./create_project_instance_repository"; + +export class CreateProjectInstanceStore extends BaseStore { + constructor(repository: CreateProjectInstanceRepository) { + super(); + this.repository = repository; + makeAutoObservable(this); + } + repository: CreateProjectInstanceRepository; + async getProjectById(id: string) { + const result = await this.loadingHelper(this.repository.getProjectInstance(id)) + if(result.isSuccess()){ + + } + } +} diff --git a/ui/src/features/create_trigger/presentation/trigger_store.ts b/ui/src/features/create_trigger/presentation/trigger_store.ts index f5b122b..efbfde7 100644 --- a/ui/src/features/create_trigger/presentation/trigger_store.ts +++ b/ui/src/features/create_trigger/presentation/trigger_store.ts @@ -1,17 +1,18 @@ -import { makeAutoObservable } from "mobx"; +import makeAutoObservable from "mobx-store-inheritance"; import { v4 as uuidv4 } from "uuid"; import { TriggerType } from "../../../core/model/trigger_model"; import { TriggerRepository } from "../data/trigger_repository"; import { TriggerViewModel } from "../model/trigger_form_view_model"; +import { BaseStore } from "../../../core/store/base_store"; -class TriggerStore { +class TriggerStore extends BaseStore { constructor(repository: TriggerRepository) { + super(); this.triggerType = TriggerType.FILE; this.repository = repository; makeAutoObservable(this); } - isLoading = false; triggerDescription: string = ""; triggerType: TriggerType; codeTriggerValue = ""; @@ -71,7 +72,7 @@ class TriggerStore { } } async saveResult(): Promise { - this.isLoading = true + this.isLoading = true; await this.repository.save({ type: this.getTriggerDescription(), description: this.triggerDescription, @@ -79,7 +80,7 @@ class TriggerStore { return el.value; }), }); - this.isLoading = false + this.isLoading = false; } } diff --git a/ui/src/features/pipeline_instance_main_screen/pipeline_instance_repository.ts b/ui/src/features/pipeline_instance_main_screen/pipeline_instance_repository.ts new file mode 100644 index 0000000..c43eff2 --- /dev/null +++ b/ui/src/features/pipeline_instance_main_screen/pipeline_instance_repository.ts @@ -0,0 +1 @@ +export class PipelineInstanceRepository {} diff --git a/ui/src/features/pipeline_instance_main_screen/pipeline_instance_screen.tsx b/ui/src/features/pipeline_instance_main_screen/pipeline_instance_screen.tsx index 196fff4..6efdf6d 100644 --- a/ui/src/features/pipeline_instance_main_screen/pipeline_instance_screen.tsx +++ b/ui/src/features/pipeline_instance_main_screen/pipeline_instance_screen.tsx @@ -1,14 +1,19 @@ import * as React from "react"; -import { Button } from "antd"; +import { LoadPage } from "../../core/ui/pages/load_page"; +import { PipelineInstanceStore } from "./pipeline_instance_store"; - - -export const PipelineInstanceScreenPath = '/pipeline_instance/:id' +export const PipelineInstanceScreenPath = "/pipeline_instance/"; export const PipelineInstanceScreen: React.FunctionComponent = () => { + const [pipelineInstanceStore] = React.useState( + () => new PipelineInstanceStore() + ); + return ( - <> - - - + } + /> ); }; diff --git a/ui/src/features/pipeline_instance_main_screen/pipeline_instance_store.ts b/ui/src/features/pipeline_instance_main_screen/pipeline_instance_store.ts new file mode 100644 index 0000000..e51c874 --- /dev/null +++ b/ui/src/features/pipeline_instance_main_screen/pipeline_instance_store.ts @@ -0,0 +1,9 @@ +import makeAutoObservable from "mobx-store-inheritance"; +import { BaseStore } from "../../core/store/base_store"; + +export class PipelineInstanceStore extends BaseStore { + constructor() { + super(); + makeAutoObservable(this); + } +} diff --git a/ui/src/features/select_project/model/project_model.ts b/ui/src/features/select_project/model/project_model.ts index 056d1d8..6b98740 100644 --- a/ui/src/features/select_project/model/project_model.ts +++ b/ui/src/features/select_project/model/project_model.ts @@ -1,6 +1,7 @@ +import { DatabaseModel } from "../../../core/model/database_model"; import { IProcess } from "../../create_process/model/process_model"; -export interface IProjectModel { +export interface IProjectModel extends DatabaseModel { pipelines: [IProcess]; rootDir: string; description: string; diff --git a/ui/src/features/select_project/presentation/select_project.tsx b/ui/src/features/select_project/presentation/select_project.tsx index 1329709..543820d 100644 --- a/ui/src/features/select_project/presentation/select_project.tsx +++ b/ui/src/features/select_project/presentation/select_project.tsx @@ -1,17 +1,19 @@ import * as React from "react"; - import { observer } from "mobx-react-lite"; import { LoadPage } from "../../../core/ui/pages/load_page"; import { CreateProjectScreenPath } from "../../create_project/create_project_screen"; import { SelectProjectStore } from "./select_project_store"; import { SelectProjectRepository } from "../data/select_project_repository"; - +import { useNavigate } from "react-router-dom"; +import { CreateProjectInstancePath } from "../../create_project_instance/create_project_instance"; +import { Button } from "antd"; export const SelectProjectScreenPath = "/select_project"; export const SelectProjectScreen: React.FunctionComponent = observer(() => { const [selectProjectStore] = React.useState( () => new SelectProjectStore(new SelectProjectRepository()) - ); + ); + const navigate = useNavigate(); return ( <> @@ -25,7 +27,13 @@ export const SelectProjectScreen: React.FunctionComponent = observer(() => { return ( <>
{el.description}
-
+(РЕАЛИЗУЙ ТУТ ПЛЮСИК БЛЯТЬ ИЛИ КНОПКУ)
+
+ +
); })} diff --git a/ui/src/features/select_project/presentation/select_project_store.ts b/ui/src/features/select_project/presentation/select_project_store.ts index 7dfec71..e950a7f 100644 --- a/ui/src/features/select_project/presentation/select_project_store.ts +++ b/ui/src/features/select_project/presentation/select_project_store.ts @@ -1,15 +1,16 @@ -import { makeAutoObservable } from "mobx"; +import makeAutoObservable from "mobx-store-inheritance"; import { SelectProjectRepository } from "../data/select_project_repository"; import { IProjectModel } from "../model/project_model"; +import { BaseStore } from "../../../core/store/base_store"; -export class SelectProjectStore { +export class SelectProjectStore extends BaseStore { repository: SelectProjectRepository; - isLoading = false; - isError = false; + page = 1; projects: IProjectModel[] = []; constructor(repository: SelectProjectRepository) { + super() this.repository = repository; makeAutoObservable(this); this.getPipelines(); diff --git a/ui/src/features/socket_lister/socket_lister.tsx b/ui/src/features/socket_lister/socket_lister.tsx index 42d2e83..abc7004 100644 --- a/ui/src/features/socket_lister/socket_lister.tsx +++ b/ui/src/features/socket_lister/socket_lister.tsx @@ -10,7 +10,7 @@ export interface ISocketListerProps { export const SocketLister = observer((props: ISocketListerProps) => { return ( <> - {socketListerStore.socketDisconnect ? ( + {socketListerStore.socketHasDisconnect ? ( { socketListerStore.reconnect(); diff --git a/ui/src/features/socket_lister/socket_lister_store.ts b/ui/src/features/socket_lister/socket_lister_store.ts index b8f9969..d744af9 100644 --- a/ui/src/features/socket_lister/socket_lister_store.ts +++ b/ui/src/features/socket_lister/socket_lister_store.ts @@ -3,7 +3,7 @@ import { SocketRepository } from "../../core/repository/socket_repository"; class SocketListerStore { repository: SocketRepository; - socketDisconnect = false; + socketHasDisconnect = false; constructor(repository: SocketRepository) { this.repository = repository; @@ -13,7 +13,7 @@ class SocketListerStore { async reconnect() { await this.repository.connect() - this.socketDisconnect = false + this.socketHasDisconnect = false } }