progress
This commit is contained in:
parent
d70253d6a6
commit
fa645dde92
51 changed files with 657 additions and 281 deletions
1
.vscode/settings.json
vendored
1
.vscode/settings.json
vendored
|
@ -17,6 +17,7 @@
|
||||||
},
|
},
|
||||||
"cSpell.words": [
|
"cSpell.words": [
|
||||||
"antd",
|
"antd",
|
||||||
|
"fileupload",
|
||||||
"uuidv"
|
"uuidv"
|
||||||
]
|
]
|
||||||
}
|
}
|
|
@ -37,6 +37,7 @@
|
||||||
"concurrently": "^8.2.0",
|
"concurrently": "^8.2.0",
|
||||||
"cors": "^2.8.5",
|
"cors": "^2.8.5",
|
||||||
"express": "^4.18.2",
|
"express": "^4.18.2",
|
||||||
|
"express-fileupload": "^1.4.2",
|
||||||
"first-di": "^1.0.11",
|
"first-di": "^1.0.11",
|
||||||
"md5": "^2.3.0",
|
"md5": "^2.3.0",
|
||||||
"mongoose": "^7.6.2",
|
"mongoose": "^7.6.2",
|
||||||
|
|
|
@ -1,13 +1,14 @@
|
||||||
import express from "express";
|
import express from "express";
|
||||||
import { Routes } from "../interfaces/router";
|
import { Routes } from "../interfaces/router";
|
||||||
import cors from "cors";
|
import cors from "cors";
|
||||||
import mongoose from "mongoose";
|
|
||||||
import { Server } from "socket.io";
|
import { Server } from "socket.io";
|
||||||
import { createServer } from "http";
|
import { createServer } from "http";
|
||||||
import { SocketSubscriber } from "./socket_controller";
|
import { SocketSubscriber } from "./socket_controller";
|
||||||
import { dirname } from "path";
|
import { dirname } from "path";
|
||||||
import { CreateFolderUseCase } from "../usecases/crete_folder_usecase";
|
import fileUpload from "express-fileupload";
|
||||||
import { dirIsExists } from "../repository/fs";
|
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 {
|
export class App {
|
||||||
public app: express.Application;
|
public app: express.Application;
|
||||||
|
@ -60,6 +61,11 @@ export class App {
|
||||||
this.app.use(express.json());
|
this.app.use(express.json());
|
||||||
this.app.use(express.urlencoded({ extended: true }));
|
this.app.use(express.urlencoded({ extended: true }));
|
||||||
this.app.use(express.static("public"));
|
this.app.use(express.static("public"));
|
||||||
|
this.app.use(
|
||||||
|
fileUpload({
|
||||||
|
createParentPath: true,
|
||||||
|
})
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private initializeRoutes(routes: Routes[]) {
|
private initializeRoutes(routes: Routes[]) {
|
||||||
|
@ -68,37 +74,11 @@ export class App {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
async loadAppDependencies() {
|
async loadAppDependencies() {
|
||||||
// await locator(
|
await new DataBaseConnectUseCase().call();
|
||||||
// this.env == "development"
|
await new CheckAndCreateStaticFilesFolderUseCase().call();
|
||||||
// ? new DevEnv(this.computedFolder)
|
await new SetLastActivePipelineToRealTimeServiceUseCase().call();
|
||||||
// : new UnitTestEnv(this.computedFolder)
|
|
||||||
// );
|
|
||||||
await this.appStartController();
|
|
||||||
|
|
||||||
mongoose
|
|
||||||
.connect("mongodb://127.0.0.1:27017/test")
|
|
||||||
.then(() => {})
|
|
||||||
.catch((e) => {
|
|
||||||
console.log("ERROR:", e);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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 = () => {
|
static staticFilesStoreDir = () => {
|
||||||
const dir = dirname(__filename);
|
const dir = dirname(__filename);
|
||||||
const rootDir = dir.slice(0, dir.length - 20);
|
const rootDir = dir.slice(0, dir.length - 20);
|
||||||
|
|
|
@ -13,14 +13,19 @@ type Method =
|
||||||
| "options"
|
| "options"
|
||||||
| "head";
|
| "head";
|
||||||
|
|
||||||
export type CallbackStrategyWithValidationModel<T> = (
|
export type ResponseBase = Promise<Result<any, any>>;
|
||||||
a: T
|
|
||||||
) => Promise<Result<any, any>>;
|
// TODO(IDONTSUDO): rewrite the router for the strategy
|
||||||
// TODO(IDOTSUDO):NEED IMPLEMENTS
|
export type CallbackStrategyWithEmpty = () => ResponseBase;
|
||||||
// interface ISubSetFeatureRouter<T>{
|
export type CallbackStrategyWithValidationModel<T> = (a: T) => ResponseBase;
|
||||||
// method:Method,
|
export type CallbackStrategyWithIdQuery = (id: string) => ResponseBase;
|
||||||
// fn:CallbackStrategyWithValidationModel<T>
|
export type CallBackStrategyWithQueryPage = (page: string) => ResponseBase;
|
||||||
// }
|
export type CallbackStrategyWithFileUpload = (file: File) => ResponseBase;
|
||||||
|
|
||||||
|
interface ISubSetFeatureRouter<T> {
|
||||||
|
method: Method;
|
||||||
|
fn: CallbackStrategyWithValidationModel<T>;
|
||||||
|
}
|
||||||
|
|
||||||
abstract class ICoreHttpController {
|
abstract class ICoreHttpController {
|
||||||
abstract mainURL: string;
|
abstract mainURL: string;
|
||||||
|
@ -31,6 +36,7 @@ abstract class ICoreHttpController {
|
||||||
export class CoreHttpController<V> implements ICoreHttpController {
|
export class CoreHttpController<V> implements ICoreHttpController {
|
||||||
mainURL: string;
|
mainURL: string;
|
||||||
validationModel: any;
|
validationModel: any;
|
||||||
|
subRoutes: ISubSetFeatureRouter<any>[] = [];
|
||||||
|
|
||||||
routes = {
|
routes = {
|
||||||
POST: null,
|
POST: null,
|
||||||
|
@ -47,6 +53,11 @@ export class CoreHttpController<V> implements ICoreHttpController {
|
||||||
}
|
}
|
||||||
|
|
||||||
call(): Routes {
|
call(): Routes {
|
||||||
|
if (this.subRoutes.isNotEmpty()) {
|
||||||
|
this.subRoutes.map((el) => {
|
||||||
|
console.log(this.router[el.method]);
|
||||||
|
});
|
||||||
|
}
|
||||||
if (this.routes["POST"] != null) {
|
if (this.routes["POST"] != null) {
|
||||||
this.router.post(
|
this.router.post(
|
||||||
this.mainURL,
|
this.mainURL,
|
||||||
|
|
|
@ -1,44 +1,44 @@
|
||||||
import { Service } from "typedi";
|
// import { Service } from "typedi";
|
||||||
|
|
||||||
@Service()
|
// @Service()
|
||||||
export class IEnv{
|
// export class IEnv{
|
||||||
rootFolder!: string;
|
// rootFolder!: string;
|
||||||
constructor(){
|
// constructor(){
|
||||||
|
|
||||||
}
|
// }
|
||||||
toStringEnv(){
|
// toStringEnv(){
|
||||||
return ''
|
// return ''
|
||||||
}
|
// }
|
||||||
static env(){
|
// static env(){
|
||||||
return ''
|
// return ''
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
@Service()
|
// @Service()
|
||||||
export class DevEnv implements IEnv {
|
// export class DevEnv implements IEnv {
|
||||||
rootFolder:string;
|
// rootFolder:string;
|
||||||
constructor(rootFolder:string){
|
// constructor(rootFolder:string){
|
||||||
this.rootFolder = rootFolder
|
// this.rootFolder = rootFolder
|
||||||
}
|
// }
|
||||||
toStringEnv(): string {
|
// toStringEnv(): string {
|
||||||
return DevEnv.env()
|
// return DevEnv.env()
|
||||||
}
|
// }
|
||||||
static env(){
|
// static env(){
|
||||||
return 'DevEnv'
|
// return 'DevEnv'
|
||||||
|
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
@Service()
|
// @Service()
|
||||||
export class UnitTestEnv implements IEnv{
|
// export class UnitTestEnv implements IEnv{
|
||||||
rootFolder:string;
|
// rootFolder:string;
|
||||||
constructor(rootFolder:string){
|
// constructor(rootFolder:string){
|
||||||
this.rootFolder = rootFolder
|
// this.rootFolder = rootFolder
|
||||||
}
|
// }
|
||||||
toStringEnv(): string {
|
// toStringEnv(): string {
|
||||||
return UnitTestEnv.env()
|
// return UnitTestEnv.env()
|
||||||
}
|
// }
|
||||||
static env(){
|
// static env(){
|
||||||
return 'UnitTestEnv'
|
// return 'UnitTestEnv'
|
||||||
|
|
||||||
}
|
// }
|
||||||
}
|
// }
|
|
@ -1,53 +1,53 @@
|
||||||
import { DevEnv, IEnv, UnitTestEnv } from "./env";
|
// import { DevEnv, IEnv, UnitTestEnv } from "./env";
|
||||||
import { extensions } from "../extensions/extensions";
|
// import { extensions } from "../extensions/extensions";
|
||||||
// import { Container, Service } from 'typedi';
|
// // import { Container, Service } from 'typedi';
|
||||||
|
|
||||||
export default function locator(env: IEnv) {
|
// export default function locator(env: IEnv) {
|
||||||
extensions();
|
// extensions();
|
||||||
envRegister(env);
|
// envRegister(env);
|
||||||
registerRepository(env);
|
// registerRepository(env);
|
||||||
registerController(env);
|
// registerController(env);
|
||||||
registerService(env);
|
// registerService(env);
|
||||||
// override(MetaDataFileManagerModel, MetaDataFileManagerModel);
|
// // override(MetaDataFileManagerModel, MetaDataFileManagerModel);
|
||||||
}
|
// }
|
||||||
|
|
||||||
const envRegister = (env: IEnv) => {
|
// const envRegister = (env: IEnv) => {
|
||||||
switch (env.toStringEnv()) {
|
// switch (env.toStringEnv()) {
|
||||||
case UnitTestEnv.env():
|
// case UnitTestEnv.env():
|
||||||
// override(IEnv, UnitTestEnv);
|
// // override(IEnv, UnitTestEnv);
|
||||||
return;
|
// return;
|
||||||
case "DevEnv":
|
// case "DevEnv":
|
||||||
// override(IEnv, DevEnv);
|
// // override(IEnv, DevEnv);
|
||||||
return;
|
// return;
|
||||||
}
|
// }
|
||||||
};
|
// };
|
||||||
|
|
||||||
const registerRepository = (env: IEnv) => {
|
// const registerRepository = (env: IEnv) => {
|
||||||
switch (env.toStringEnv()) {
|
// switch (env.toStringEnv()) {
|
||||||
case UnitTestEnv.env():
|
// case UnitTestEnv.env():
|
||||||
// override(IEnv, UnitTestEnv);
|
// // override(IEnv, UnitTestEnv);
|
||||||
|
|
||||||
return;
|
// return;
|
||||||
case DevEnv.env():
|
// case DevEnv.env():
|
||||||
// override(IEnv, DevEnv);
|
// // override(IEnv, DevEnv);
|
||||||
return;
|
// return;
|
||||||
}
|
// }
|
||||||
};
|
// };
|
||||||
|
|
||||||
const registerController = (env: IEnv) => {
|
// const registerController = (env: IEnv) => {
|
||||||
switch (env.toStringEnv()) {
|
// switch (env.toStringEnv()) {
|
||||||
case UnitTestEnv.env():
|
// case UnitTestEnv.env():
|
||||||
return;
|
// return;
|
||||||
case DevEnv.env():
|
// case DevEnv.env():
|
||||||
return;
|
// return;
|
||||||
}
|
// }
|
||||||
};
|
// };
|
||||||
|
|
||||||
const registerService = (env: IEnv) => {
|
// const registerService = (env: IEnv) => {
|
||||||
switch (env.toStringEnv()) {
|
// switch (env.toStringEnv()) {
|
||||||
case UnitTestEnv.env():
|
// case UnitTestEnv.env():
|
||||||
return;
|
// return;
|
||||||
case DevEnv.env():
|
// case DevEnv.env():
|
||||||
return;
|
// return;
|
||||||
}
|
// }
|
||||||
};
|
// };
|
||||||
|
|
|
@ -1,25 +1,18 @@
|
||||||
export {};
|
/* eslint-disable @typescript-eslint/no-this-alias */
|
||||||
|
export const ArrayExtensions = () => {
|
||||||
declare global {
|
if ([].equals === undefined) {
|
||||||
interface Array<T> {
|
// eslint-disable-next-line no-extend-native
|
||||||
// @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<T>, strict: boolean): boolean;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export const ArrayEquals = () => {
|
|
||||||
if ([].equals == undefined) {
|
|
||||||
Array.prototype.equals = function (array, strict = true) {
|
Array.prototype.equals = function (array, strict = true) {
|
||||||
if (!array) return false;
|
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++) {
|
for (let i = 0; i < this.length; i++) {
|
||||||
if (this[i] instanceof Array && array[i] instanceof Array) {
|
if (this[i] instanceof Array && array[i] instanceof Array) {
|
||||||
if (!this[i].equals(array[i], strict)) return false;
|
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;
|
return false;
|
||||||
} else if (!strict) {
|
} else if (!strict) {
|
||||||
return this.sort().equals(array.sort(), true);
|
return this.sort().equals(array.sort(), true);
|
||||||
|
@ -28,4 +21,27 @@ export const ArrayEquals = () => {
|
||||||
return true;
|
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;
|
||||||
|
};
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,6 +1,20 @@
|
||||||
import { ArrayEquals } from "./array";
|
import { ArrayExtensions } from "./array";
|
||||||
|
import { StringExtensions } from "./string";
|
||||||
|
|
||||||
export const extensions = () =>{
|
declare global {
|
||||||
ArrayEquals()
|
interface Array<T> {
|
||||||
|
// @strict: The parameter is determined whether the arrays must be exactly the same in content and order of this relationship or simply follow the same requirements.
|
||||||
|
equals(array: Array<T>, strict: boolean): boolean;
|
||||||
|
lastElement(): T | undefined;
|
||||||
|
isEmpty(): boolean;
|
||||||
|
isNotEmpty(): boolean;
|
||||||
|
}
|
||||||
|
interface String {
|
||||||
|
isEmpty(): boolean;
|
||||||
|
isNotEmpty(): boolean;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
export const extensions = () => {
|
||||||
|
ArrayExtensions();
|
||||||
|
StringExtensions();
|
||||||
|
};
|
||||||
|
|
14
server/src/core/extensions/string.ts
Normal file
14
server/src/core/extensions/string.ts
Normal file
|
@ -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;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
20
server/src/core/model/active_pipeline_model.ts
Normal file
20
server/src/core/model/active_pipeline_model.ts
Normal file
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,24 +1,21 @@
|
||||||
import { TypedEvent } from "../helper/typed_event";
|
import { TypedEvent } from "../helper/typed_event";
|
||||||
import { ExecError } from "../model/exec_error_model";
|
import { ExecError } from "../model/exec_error_model";
|
||||||
import { ExecutorResult } from "../model/executor_result";
|
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 { IPipeline } from "../model/process_model";
|
||||||
import { Iteration, StackService } from "./stack_service";
|
import { Iteration, StackService } from "./stack_service";
|
||||||
|
|
||||||
export class PipelineRealTimeService extends TypedEvent<IPipelineMeta> {
|
export class PipelineRealTimeService extends TypedEvent<ActivePipeline> {
|
||||||
status: IPipelineMeta;
|
status: ActivePipeline;
|
||||||
pipelineModels?: IPipeline[];
|
pipelineModels?: IPipeline[];
|
||||||
|
path: string;
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
this.init();
|
this.init();
|
||||||
}
|
}
|
||||||
private init(): void {
|
private init(): void {
|
||||||
this.status = {
|
this.status = ActivePipeline.empty();
|
||||||
pipelineIsRunning: false,
|
|
||||||
projectUUID: null,
|
|
||||||
lastProcessCompleteCount: null,
|
|
||||||
error: null,
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
pipelineSubscriber = (iterations: Iteration[]): void => {
|
pipelineSubscriber = (iterations: Iteration[]): void => {
|
||||||
if (this.status["lastProcessCompleteCount"] === 0) {
|
if (this.status["lastProcessCompleteCount"] === 0) {
|
||||||
|
@ -65,16 +62,21 @@ export class PipelineRealTimeService extends TypedEvent<IPipelineMeta> {
|
||||||
this.status.pipelineIsRunning = false;
|
this.status.pipelineIsRunning = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
setPipelineDependency(
|
||||||
runPipeline(
|
|
||||||
pipelineModels: IPipeline[],
|
pipelineModels: IPipeline[],
|
||||||
path: string,
|
path: string,
|
||||||
projectUUID: string
|
projectUUID: string
|
||||||
): void {
|
) {
|
||||||
const stack = new StackService(pipelineModels, path);
|
this.pipelineModels = pipelineModels;
|
||||||
|
this.path = path;
|
||||||
this.status["projectUUID"] = projectUUID;
|
this.status["projectUUID"] = projectUUID;
|
||||||
this.status["pipelineIsRunning"] = true;
|
}
|
||||||
stack.on(this.pipelineSubscriber);
|
runPipeline(): void {
|
||||||
stack.call();
|
|
||||||
|
// const stack = new StackService(this.pipelineModels, this.path);
|
||||||
|
|
||||||
|
// this.status["pipelineIsRunning"] = true;
|
||||||
|
// stack.on(this.pipelineSubscriber);
|
||||||
|
// stack.call();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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<void> => {
|
||||||
|
if (await dirIsExists(App.staticFilesStoreDir())) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const createFolderUseCase = await new CreateFolderUseCase().call(
|
||||||
|
App.staticFilesStoreDir()
|
||||||
|
);
|
||||||
|
|
||||||
|
createFolderUseCase.fold(
|
||||||
|
(_s) => {},
|
||||||
|
(e) => {
|
||||||
|
console.log(e);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
13
server/src/core/usecases/database_connect_usecase.ts
Normal file
13
server/src/core/usecases/database_connect_usecase.ts
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
import mongoose from "mongoose";
|
||||||
|
import { Result } from "../helper/result";
|
||||||
|
|
||||||
|
export class DataBaseConnectUseCase {
|
||||||
|
call = async (): Promise<Result<Error, void>> => {
|
||||||
|
try {
|
||||||
|
await mongoose.connect("mongodb://127.0.0.1:27017/test");
|
||||||
|
return Result.ok();
|
||||||
|
} catch (error) {
|
||||||
|
return Result.error(error as Error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
|
@ -1,3 +1,18 @@
|
||||||
export class RegExpSearchDataBaseModelUseCase {
|
import { Result } from "../helper/result";
|
||||||
call = () => {};
|
|
||||||
|
export class SearchDataBaseModelUseCase<T> {
|
||||||
|
model: any;
|
||||||
|
|
||||||
|
constructor(model: any) {
|
||||||
|
this.model = model;
|
||||||
|
}
|
||||||
|
|
||||||
|
call = async (findFilter: Partial<T>): Promise<Result<null, T>> => {
|
||||||
|
const result = await this.model.findOne(findFilter);
|
||||||
|
if (result === null) {
|
||||||
|
return Result.error(null);
|
||||||
|
} else {
|
||||||
|
return Result.ok(result);
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -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<void> => {
|
||||||
|
const result = await new SearchDataBaseModelUseCase<IProjectInstanceModel>(
|
||||||
|
ProjectInstanceDbModel
|
||||||
|
).call({
|
||||||
|
isActive: true,
|
||||||
|
});
|
||||||
|
if (result.isSuccess()) {
|
||||||
|
const projectModel = result.value.project;
|
||||||
|
pipelineRealTimeService.setPipelineDependency(
|
||||||
|
projectModel.pipelines,
|
||||||
|
App.staticFilesStoreDir() + projectModel.rootDir + "/",
|
||||||
|
projectModel._id
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
|
@ -1,8 +1,13 @@
|
||||||
import { IsMongoId, IsOptional } from "class-validator";
|
import { IsMongoId, IsOptional, ValidateNested } from "class-validator";
|
||||||
import { Schema, model } from "mongoose";
|
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 { 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({
|
export const PipelineSchema = new Schema({
|
||||||
process: {
|
process: {
|
||||||
|
@ -17,21 +22,21 @@ export const PipelineSchema = new Schema({
|
||||||
autopopulate: true,
|
autopopulate: true,
|
||||||
default: null,
|
default: null,
|
||||||
},
|
},
|
||||||
|
stackGenerateType: {
|
||||||
|
type: String,
|
||||||
|
default: null,
|
||||||
|
},
|
||||||
}).plugin(require("mongoose-autopopulate"));
|
}).plugin(require("mongoose-autopopulate"));
|
||||||
|
|
||||||
export const schemaPipeline = "Pipeline";
|
export const schemaPipeline = "Pipeline";
|
||||||
|
|
||||||
export const PipelineDBModel = model<PipelineModel>(
|
export const PipelineDBModel = model<IPipeline>(schemaPipeline, PipelineSchema);
|
||||||
schemaPipeline,
|
|
||||||
PipelineSchema
|
|
||||||
);
|
|
||||||
|
|
||||||
export class PipelineModel {
|
export class PipelineValidationModel {
|
||||||
@IsMongoId()
|
@IsMongoId()
|
||||||
public process: IProcess;
|
public process: IProcess;
|
||||||
|
|
||||||
@IsMongoId()
|
@IsMongoId()
|
||||||
//TODO(IDONTSUDO):NEED OPTION DECORATOR??
|
|
||||||
public trigger: TriggerModel;
|
public trigger: TriggerModel;
|
||||||
|
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
|
@ -40,3 +45,17 @@ export class PipelineModel {
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
public stackGenerateType: StackGenerateType;
|
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;
|
||||||
|
}
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
import { CrudController } from "../../core/controllers/crud_controller";
|
import { CrudController } from "../../core/controllers/crud_controller";
|
||||||
import { PipelineDBModel, PipelineModel } from "./pipeline_model";
|
import { PipelineDBModel, PipelineValidationModel } from "./pipeline_model";
|
||||||
|
|
||||||
export class PipelinePresentation extends CrudController<
|
export class PipelinePresentation extends CrudController<
|
||||||
PipelineModel,
|
PipelineValidationModel,
|
||||||
typeof PipelineDBModel
|
typeof PipelineDBModel
|
||||||
> {
|
> {
|
||||||
constructor() {
|
constructor() {
|
||||||
super({
|
super({
|
||||||
url: "pipeline",
|
url: "pipeline",
|
||||||
validationModel: PipelineModel,
|
validationModel: PipelineValidationModel,
|
||||||
databaseModel: PipelineDBModel,
|
databaseModel: PipelineDBModel,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,11 +2,16 @@ import { App } from "../../core/controllers/app";
|
||||||
import { Result } from "../../core/helper/result";
|
import { Result } from "../../core/helper/result";
|
||||||
import { CreateDataBaseModelUseCase } from "../../core/usecases/create_database_model_usecase";
|
import { CreateDataBaseModelUseCase } from "../../core/usecases/create_database_model_usecase";
|
||||||
import { CreateFolderUseCase } from "../../core/usecases/crete_folder_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";
|
import { v4 as uuidv4 } from "uuid";
|
||||||
|
|
||||||
export class CreateNewProjectScenario {
|
export class CreateNewProjectInstanceScenario {
|
||||||
call = async (model: ProjectValidationModel): Promise<Result<Error, any>> => {
|
call = async (
|
||||||
|
model: ProjectInstanceValidationModel
|
||||||
|
): Promise<Result<Error, any>> => {
|
||||||
try {
|
try {
|
||||||
const folderName = uuidv4() + "/";
|
const folderName = uuidv4() + "/";
|
||||||
const createFolderUseCase = await new CreateFolderUseCase().call(
|
const createFolderUseCase = await new CreateFolderUseCase().call(
|
||||||
|
@ -15,10 +20,10 @@ export class CreateNewProjectScenario {
|
||||||
if (createFolderUseCase.isFailure()) {
|
if (createFolderUseCase.isFailure()) {
|
||||||
return createFolderUseCase.forward();
|
return createFolderUseCase.forward();
|
||||||
}
|
}
|
||||||
|
|
||||||
model.rootDir = folderName;
|
model.rootDir = folderName;
|
||||||
|
|
||||||
const createDataBaseModelUseCase = await new CreateDataBaseModelUseCase(
|
const createDataBaseModelUseCase = await new CreateDataBaseModelUseCase(
|
||||||
ProjectDBModel
|
ProjectInstanceDbModel
|
||||||
).call(model);
|
).call(model);
|
||||||
|
|
||||||
if (createDataBaseModelUseCase.isFailure()) {
|
if (createDataBaseModelUseCase.isFailure()) {
|
|
@ -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<IProjectInstanceModel>(
|
||||||
|
schemaProjectInstance,
|
||||||
|
ProjectInstanceSchema
|
||||||
|
);
|
||||||
|
|
||||||
|
export class ProjectInstanceValidationModel {
|
||||||
|
@IsMongoId()
|
||||||
|
public project: string;
|
||||||
|
@IsString()
|
||||||
|
public description: string;
|
||||||
|
@IsOptional()
|
||||||
|
public rootDir: string;
|
||||||
|
}
|
|
@ -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:
|
||||||
|
// });
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,12 +1,13 @@
|
||||||
import { Schema, model } from "mongoose";
|
import { Schema, model } from "mongoose";
|
||||||
import { PipelineModel, schemaPipeline } from "../pipelines/pipeline_model";
|
import { PipelineValidationModel, schemaPipeline } from "../pipelines/pipeline_model";
|
||||||
import { IsArray, IsOptional, IsString } from "class-validator";
|
import { IsArray, IsString } from "class-validator";
|
||||||
|
|
||||||
export interface IProjectModel {
|
export interface IProjectModel {
|
||||||
_id?:string;
|
_id?: string;
|
||||||
pipelines: [PipelineModel];
|
pipelines: [PipelineValidationModel];
|
||||||
rootDir: string;
|
rootDir: string;
|
||||||
description: string;
|
description: string;
|
||||||
|
isActive:boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const ProjectSchema = new Schema({
|
export const ProjectSchema = new Schema({
|
||||||
|
@ -16,23 +17,23 @@ export const ProjectSchema = new Schema({
|
||||||
autopopulate: true,
|
autopopulate: true,
|
||||||
default: null,
|
default: null,
|
||||||
},
|
},
|
||||||
rootDir: {
|
|
||||||
type: String,
|
|
||||||
},
|
|
||||||
description: {
|
description: {
|
||||||
type: String,
|
type: String,
|
||||||
},
|
},
|
||||||
|
isActive: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
}).plugin(require("mongoose-autopopulate"));
|
}).plugin(require("mongoose-autopopulate"));
|
||||||
|
|
||||||
const schema = "Projects";
|
export const projectSchema = "Projects";
|
||||||
|
|
||||||
export const ProjectDBModel = model<IProjectModel>(schema, ProjectSchema);
|
export const ProjectDBModel = model<IProjectModel>(projectSchema, ProjectSchema);
|
||||||
|
|
||||||
export class ProjectValidationModel {
|
export class ProjectValidationModel {
|
||||||
@IsArray()
|
@IsArray()
|
||||||
public pipelines: [string];
|
public pipelines: [string];
|
||||||
@IsString()
|
@IsString()
|
||||||
public description: string;
|
public description: string;
|
||||||
@IsOptional()
|
|
||||||
public rootDir: string;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
import { CrudController } from "../../core/controllers/crud_controller";
|
import { CrudController } from "../../core/controllers/crud_controller";
|
||||||
import { CreateNewProjectScenario } from "./create_new_project_scenario";
|
|
||||||
import { ProjectDBModel, ProjectValidationModel } from "./projects_model";
|
import { ProjectDBModel, ProjectValidationModel } from "./projects_model";
|
||||||
|
|
||||||
export class ProjectsPresentation extends CrudController<
|
export class ProjectsPresentation extends CrudController<
|
||||||
|
@ -12,6 +11,5 @@ export class ProjectsPresentation extends CrudController<
|
||||||
validationModel: ProjectValidationModel,
|
validationModel: ProjectValidationModel,
|
||||||
databaseModel: ProjectDBModel,
|
databaseModel: ProjectDBModel,
|
||||||
});
|
});
|
||||||
super.post(new CreateNewProjectScenario().call);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@ import { CoreHttpController } from "../../core/controllers/http_controller";
|
||||||
import { PipelineRealTimeService } from "../../core/services/pipeline_real_time_service";
|
import { PipelineRealTimeService } from "../../core/services/pipeline_real_time_service";
|
||||||
import { RunInstancePipelineUseCase } from "./usecases/run_instance_pipeline_usecase";
|
import { RunInstancePipelineUseCase } from "./usecases/run_instance_pipeline_usecase";
|
||||||
import { PipelineStatusUseCase } from "./usecases/pipeline_status_usecase";
|
import { PipelineStatusUseCase } from "./usecases/pipeline_status_usecase";
|
||||||
|
|
||||||
export const pipelineRealTimeService = new PipelineRealTimeService();
|
export const pipelineRealTimeService = new PipelineRealTimeService();
|
||||||
|
|
||||||
export class RealTimeValidationModel {
|
export class RealTimeValidationModel {
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
import { Result } from "../../../core/helper/result";
|
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";
|
import { pipelineRealTimeService } from "../realtime_presentation";
|
||||||
|
|
||||||
export class PipelineStatusUseCase {
|
export class PipelineStatusUseCase {
|
||||||
async call(): Promise<Result<Error, IPipelineMeta>> {
|
async call(): Promise<Result<Error, ActivePipeline>> {
|
||||||
try {
|
try {
|
||||||
return Result.ok(pipelineRealTimeService.status);
|
return Result.ok(pipelineRealTimeService.status);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|
|
@ -1,8 +1,11 @@
|
||||||
import { App } from "../../../core/controllers/app";
|
import { App } from "../../../core/controllers/app";
|
||||||
import { Result } from "../../../core/helper/result";
|
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 { 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 {
|
import {
|
||||||
RealTimeValidationModel,
|
RealTimeValidationModel,
|
||||||
pipelineRealTimeService,
|
pipelineRealTimeService,
|
||||||
|
@ -10,29 +13,35 @@ import {
|
||||||
|
|
||||||
export class RunInstancePipelineUseCase {
|
export class RunInstancePipelineUseCase {
|
||||||
async call(model: RealTimeValidationModel): Promise<Result<Error, any>> {
|
async call(model: RealTimeValidationModel): Promise<Result<Error, any>> {
|
||||||
const id = model.id;
|
const { id } = model;
|
||||||
|
|
||||||
const readByIdDataBaseModelUseCase =
|
const readByIdDataBaseModelUseCase =
|
||||||
await new ReadByIdDataBaseModelUseCase<IProjectModel>(
|
await new ReadByIdDataBaseModelUseCase<IProjectInstanceModel>(
|
||||||
ProjectDBModel
|
ProjectInstanceDbModel
|
||||||
).call(id);
|
).call(id);
|
||||||
|
|
||||||
if (readByIdDataBaseModelUseCase.isFailure()) {
|
if (readByIdDataBaseModelUseCase.isFailure()) {
|
||||||
return readByIdDataBaseModelUseCase.forward();
|
return readByIdDataBaseModelUseCase.forward();
|
||||||
}
|
}
|
||||||
|
|
||||||
const projectModel = readByIdDataBaseModelUseCase.value;
|
const projectModel = readByIdDataBaseModelUseCase.value.project;
|
||||||
projectModel.pipelines.map((el) => {
|
projectModel.isActive = true;
|
||||||
el.process.type = EXEC_TYPE.EXEC;
|
|
||||||
});
|
const updateDataBaseModelUseCase = await new UpdateDataBaseModelUseCase<
|
||||||
|
IProjectInstanceModel,
|
||||||
pipelineRealTimeService.runPipeline(
|
any
|
||||||
|
>(ProjectInstanceDbModel).call(projectModel);
|
||||||
|
|
||||||
|
if (updateDataBaseModelUseCase.isFailure()) {
|
||||||
|
return updateDataBaseModelUseCase.forward();
|
||||||
|
}
|
||||||
|
pipelineRealTimeService.setPipelineDependency(
|
||||||
projectModel.pipelines,
|
projectModel.pipelines,
|
||||||
App.staticFilesStoreDir() + projectModel.rootDir + "/",
|
App.staticFilesStoreDir() + projectModel.rootDir + "/",
|
||||||
projectModel._id
|
projectModel._id
|
||||||
);
|
);
|
||||||
|
pipelineRealTimeService.runPipeline();
|
||||||
|
|
||||||
return Result.ok({ status: "ok" });
|
return Result.ok({ status: "ok" });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// /Users/idontsudo/Desktop/testdeck-mocha-seed/server/build/public/ce4e7710-73dc-47fc-87ee-d448ea2412ce
|
|
||||||
// new ObjectId("6554c22d2ef337587505a494")
|
|
||||||
|
|
|
@ -10,13 +10,18 @@ import {
|
||||||
RealTimePresentation,
|
RealTimePresentation,
|
||||||
pipelineRealTimeService,
|
pipelineRealTimeService,
|
||||||
} from "./features/realtime/realtime_presentation";
|
} from "./features/realtime/realtime_presentation";
|
||||||
|
import { extensions } from "./core/extensions/extensions";
|
||||||
|
import { ProjectInstancePresentation } from "./features/project_instance/project_instance_presentation";
|
||||||
|
|
||||||
|
extensions();
|
||||||
|
|
||||||
const httpRoutes: Routes[] = [
|
const httpRoutes: Routes[] = [
|
||||||
new TriggerPresentation(),
|
new TriggerPresentation(),
|
||||||
new ProjectsPresentation(),
|
new ProjectsPresentation(),
|
||||||
new ProcessPresentation(),
|
new ProcessPresentation(),
|
||||||
new PipelinePresentation(),
|
new PipelinePresentation(),
|
||||||
new RealTimePresentation(),
|
new RealTimePresentation(),
|
||||||
|
new ProjectInstancePresentation(),
|
||||||
].map((el) => el.call());
|
].map((el) => el.call());
|
||||||
|
|
||||||
const socketSubscribers = [
|
const socketSubscribers = [
|
||||||
|
@ -24,4 +29,3 @@ const socketSubscribers = [
|
||||||
];
|
];
|
||||||
|
|
||||||
new App(httpRoutes, socketSubscribers).listen();
|
new App(httpRoutes, socketSubscribers).listen();
|
||||||
|
|
|
@ -7,6 +7,6 @@ export class PipelineRealTimeServiceTest extends PipelineRealTimeService {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
async test() {
|
async test() {
|
||||||
this.runPipeline(mockSimplePipeline, dirname__, "");
|
// this.runPipeline(mockSimplePipeline, dirname__, "");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
5
server/todo.md
Normal file
5
server/todo.md
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
создание инстанца [ OK ]
|
||||||
|
получение всех инастанцев проектов и изменнение их [ OK ]
|
||||||
|
запуск инастанца проекта? [ OK ]
|
||||||
|
|
||||||
|
загрузка FILE [ ]
|
|
@ -1,3 +1,4 @@
|
||||||
|
/* eslint-disable @typescript-eslint/no-this-alias */
|
||||||
export const ArrayExtensions = () => {
|
export const ArrayExtensions = () => {
|
||||||
if ([].equals === undefined) {
|
if ([].equals === undefined) {
|
||||||
// eslint-disable-next-line no-extend-native
|
// eslint-disable-next-line no-extend-native
|
||||||
|
@ -23,11 +24,11 @@ export const ArrayExtensions = () => {
|
||||||
if ([].lastElement === undefined) {
|
if ([].lastElement === undefined) {
|
||||||
// eslint-disable-next-line no-extend-native
|
// eslint-disable-next-line no-extend-native
|
||||||
Array.prototype.lastElement = function () {
|
Array.prototype.lastElement = function () {
|
||||||
let instanceCheck = this;
|
const instanceCheck = this;
|
||||||
if (instanceCheck === undefined) {
|
if (instanceCheck === undefined) {
|
||||||
return undefined;
|
return undefined;
|
||||||
} else {
|
} else {
|
||||||
let instance = instanceCheck as [];
|
const instance = instanceCheck as [];
|
||||||
return instance[instance.length - 1];
|
return instance[instance.length - 1];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -38,4 +39,10 @@ export const ArrayExtensions = () => {
|
||||||
return this.length === 0;
|
return this.length === 0;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
if ([].isNotEmpty === undefined) {
|
||||||
|
// eslint-disable-next-line no-extend-native
|
||||||
|
Array.prototype.isNotEmpty = function () {
|
||||||
|
return this.length !== 0;
|
||||||
|
};
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -7,6 +7,7 @@ declare global {
|
||||||
equals(array: Array<T>, strict: boolean): boolean;
|
equals(array: Array<T>, strict: boolean): boolean;
|
||||||
lastElement(): T | undefined;
|
lastElement(): T | undefined;
|
||||||
isEmpty(): boolean;
|
isEmpty(): boolean;
|
||||||
|
isNotEmpty():boolean;
|
||||||
}
|
}
|
||||||
interface String {
|
interface String {
|
||||||
isEmpty(): boolean;
|
isEmpty(): boolean;
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
export interface IPipelineMeta {
|
|
||||||
|
export interface ActivePipeline {
|
||||||
pipelineIsRunning: boolean;
|
pipelineIsRunning: boolean;
|
||||||
projectUUID?: string | null;
|
projectUUID?: string | null;
|
||||||
lastProcessCompleteCount: number | null;
|
lastProcessCompleteCount: number | null;
|
|
@ -23,15 +23,27 @@ import {
|
||||||
CreateTriggerScreenPath,
|
CreateTriggerScreenPath,
|
||||||
TriggerScreen,
|
TriggerScreen,
|
||||||
} from "../../features/create_trigger/presentation/create_trigger_screen";
|
} 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([
|
export const router = createBrowserRouter([
|
||||||
{
|
{
|
||||||
path: AllProjectScreenPath,
|
path: AllProjectScreenPath,
|
||||||
|
loader: new ProjectRepository().loader,
|
||||||
element: <AllProjectScreen />,
|
element: <AllProjectScreen />,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: PipelineInstanceScreenPath,
|
path: PipelineInstanceScreenPath + idURL,
|
||||||
element: <PipelineInstanceScreen />,
|
element: <PipelineInstanceScreen />,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -54,4 +66,8 @@ export const router = createBrowserRouter([
|
||||||
path: CreateProcessScreenPath,
|
path: CreateProcessScreenPath,
|
||||||
element: <CreateProcessScreen />,
|
element: <CreateProcessScreen />,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: CreateProjectInstancePath + idURL,
|
||||||
|
element: <CreateProjectInstanceScreen />,
|
||||||
|
},
|
||||||
]);
|
]);
|
||||||
|
|
22
ui/src/core/store/base_store.ts
Normal file
22
ui/src/core/store/base_store.ts
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
// TODO(IDONTSUDO): нужно переписать все запросы под BaseStore
|
||||||
|
|
||||||
|
import { Result } from "../helper/result";
|
||||||
|
|
||||||
|
export class BaseStore {
|
||||||
|
isLoading = false;
|
||||||
|
isError = false;
|
||||||
|
|
||||||
|
async loadingHelper<T>(callBack: Promise<Result<any, T>>) {
|
||||||
|
this.isLoading = true;
|
||||||
|
|
||||||
|
const result = await callBack;
|
||||||
|
if (result.isFailure()) {
|
||||||
|
this.isError = true;
|
||||||
|
this.isLoading = false;
|
||||||
|
return result.forward();
|
||||||
|
}
|
||||||
|
|
||||||
|
this.isLoading = false;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
|
@ -8,7 +8,7 @@ import { useNavigate } from "react-router-dom";
|
||||||
const { Title } = Typography;
|
const { Title } = Typography;
|
||||||
|
|
||||||
export interface IHeader {
|
export interface IHeader {
|
||||||
largeText: string;
|
largeText?: string;
|
||||||
minText?: string;
|
minText?: string;
|
||||||
path?: string;
|
path?: string;
|
||||||
needBackButton?: undefined | any;
|
needBackButton?: undefined | any;
|
||||||
|
@ -25,7 +25,7 @@ export const Header: React.FunctionComponent<IHeader> = (props: IHeader) => {
|
||||||
marginTop: "20px",
|
marginTop: "20px",
|
||||||
marginRight: "20px",
|
marginRight: "20px",
|
||||||
display: "contents",
|
display: "contents",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{needBackButton ? (
|
{needBackButton ? (
|
||||||
<>
|
<>
|
||||||
|
|
|
@ -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";
|
import { IProjectModel } from "../model/project_model";
|
||||||
|
|
||||||
export class ProjectRepository extends HttpRepository {
|
export class ProjectRepository extends HttpRepository {
|
||||||
async getAllProject() {
|
async getAllProject() {
|
||||||
return this.jsonRequest<IProjectModel[]>(HttpMethod.GET,'/project')
|
return this.jsonRequest<IProjectModel[]>(HttpMethod.GET, "/project");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async getActivePipeline() {
|
||||||
|
return this.jsonRequest<ActivePipeline>(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;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@ import { observer } from "mobx-react-lite";
|
||||||
import { SelectProjectScreenPath } from "../../select_project/presentation/select_project";
|
import { SelectProjectScreenPath } from "../../select_project/presentation/select_project";
|
||||||
|
|
||||||
export const AllProjectScreenPath = "/";
|
export const AllProjectScreenPath = "/";
|
||||||
|
|
||||||
export const AllProjectScreen: React.FunctionComponent = observer(() => {
|
export const AllProjectScreen: React.FunctionComponent = observer(() => {
|
||||||
const [allProjectStore] = React.useState(
|
const [allProjectStore] = React.useState(
|
||||||
() => new AllProjectStore(new ProjectRepository())
|
() => new AllProjectStore(new ProjectRepository())
|
||||||
|
@ -15,7 +15,6 @@ export const AllProjectScreen: React.FunctionComponent = observer(() => {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<LoadPage
|
<LoadPage
|
||||||
|
|
||||||
largeText={"Projects"}
|
largeText={"Projects"}
|
||||||
needBackButton={false}
|
needBackButton={false}
|
||||||
minText="create project?"
|
minText="create project?"
|
||||||
|
|
|
@ -1,42 +1,24 @@
|
||||||
import makeAutoObservable from "mobx-store-inheritance";
|
import makeAutoObservable from "mobx-store-inheritance";
|
||||||
import { ProjectRepository } from "../data/project_repository";
|
import { ProjectRepository } from "../data/project_repository";
|
||||||
import { IProjectModel } from "../model/project_model";
|
import { IProjectModel } from "../model/project_model";
|
||||||
import { Result } from "../../../core/helper/result";
|
import { BaseStore } from "../../../core/store/base_store";
|
||||||
|
|
||||||
// TODO(IDONTSUDO): нужно переписать все сторы под BaseStore
|
|
||||||
class BaseStore {
|
|
||||||
isLoading = false;
|
|
||||||
isError = false;
|
|
||||||
|
|
||||||
async loadingHelper<T>(callBack: Promise<Result<any, T>>) {
|
|
||||||
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 {
|
export class AllProjectStore extends BaseStore {
|
||||||
projectsModels?: IProjectModel[];
|
projectsModels?: IProjectModel[];
|
||||||
repository: ProjectRepository;
|
repository: ProjectRepository;
|
||||||
|
redirect = false;
|
||||||
constructor(repository: ProjectRepository) {
|
constructor(repository: ProjectRepository) {
|
||||||
super();
|
super();
|
||||||
this.repository = repository;
|
this.repository = repository;
|
||||||
this.getProjects();
|
|
||||||
makeAutoObservable(this);
|
makeAutoObservable(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
async getProjects() {
|
async getProjects() {
|
||||||
const result = await this.loadingHelper(this.repository.getAllProject());
|
const result = await this.loadingHelper(this.repository.getAllProject());
|
||||||
if (result.isSuccess()) {
|
if (result.isSuccess()) {
|
||||||
this.projectsModels = result.value;
|
this.projectsModels = result.value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
import { makeAutoObservable } from "mobx";
|
import makeAutoObservable from "mobx-store-inheritance";
|
||||||
import { CreatePipelineRepository } from "../data/create_pipeline_repository";
|
import { CreatePipelineRepository } from "../data/create_pipeline_repository";
|
||||||
import { ITriggerModel } from "../../../core/model/trigger_model";
|
import { ITriggerModel } from "../../../core/model/trigger_model";
|
||||||
import { IProcess } from "../../create_process/model/process_model";
|
import { IProcess } from "../../create_process/model/process_model";
|
||||||
import { message } from "antd";
|
import { message } from "antd";
|
||||||
|
import { BaseStore } from "../../../core/store/base_store";
|
||||||
|
|
||||||
enum Type {
|
enum Type {
|
||||||
PROCESS,
|
PROCESS,
|
||||||
TRIGGER,
|
TRIGGER,
|
||||||
|
@ -15,20 +16,23 @@ export interface UnionView {
|
||||||
uuid?: string;
|
uuid?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class CreatePipelineStore {
|
export class CreatePipelineStore extends BaseStore {
|
||||||
repository: CreatePipelineRepository;
|
repository: CreatePipelineRepository;
|
||||||
triggersModels: ITriggerModel[] = [];
|
triggersModels: ITriggerModel[] = [];
|
||||||
processModels: IProcess[] = [];
|
processModels: IProcess[] = [];
|
||||||
pipelineViewModels: UnionView[] = [];
|
pipelineViewModels: UnionView[] = [];
|
||||||
isLoading = false;
|
|
||||||
isError = false;
|
|
||||||
|
|
||||||
constructor(repository: CreatePipelineRepository) {
|
constructor(repository: CreatePipelineRepository) {
|
||||||
|
super();
|
||||||
this.repository = repository;
|
this.repository = repository;
|
||||||
makeAutoObservable(this);
|
makeAutoObservable(this);
|
||||||
|
this.init();
|
||||||
|
}
|
||||||
|
private init() {
|
||||||
this.loadTriggers();
|
this.loadTriggers();
|
||||||
this.loadProcess();
|
this.loadProcess();
|
||||||
}
|
}
|
||||||
|
|
||||||
filterPipelineViewModel(index: number): void {
|
filterPipelineViewModel(index: number): void {
|
||||||
this.pipelineViewModels = this.pipelineViewModels.filter(
|
this.pipelineViewModels = this.pipelineViewModels.filter(
|
||||||
(_el, i) => i !== index
|
(_el, i) => i !== index
|
||||||
|
|
|
@ -1,19 +1,20 @@
|
||||||
import { makeAutoObservable } from "mobx";
|
import makeAutoObservable from "mobx-store-inheritance";
|
||||||
import {
|
import {
|
||||||
CreateProjectRepository,
|
CreateProjectRepository,
|
||||||
PipelineModel,
|
PipelineModel,
|
||||||
} from "./create_project_repository";
|
} from "./create_project_repository";
|
||||||
import { message } from "antd";
|
import { message } from "antd";
|
||||||
|
import { BaseStore } from "../../core/store/base_store";
|
||||||
|
|
||||||
class CreateProjectStore {
|
class CreateProjectStore extends BaseStore {
|
||||||
repository: CreateProjectRepository;
|
repository: CreateProjectRepository;
|
||||||
isLoading = false;
|
|
||||||
isError = false;
|
|
||||||
pipelineModels?: PipelineModel[];
|
pipelineModels?: PipelineModel[];
|
||||||
newProjectDescription: string = "";
|
newProjectDescription: string = "";
|
||||||
newProjectViews: PipelineModel[] = [];
|
newProjectViews: PipelineModel[] = [];
|
||||||
|
|
||||||
constructor(repository: CreateProjectRepository) {
|
constructor(repository: CreateProjectRepository) {
|
||||||
|
super();
|
||||||
this.repository = repository;
|
this.repository = repository;
|
||||||
makeAutoObservable(this);
|
makeAutoObservable(this);
|
||||||
this.loadPipelines();
|
this.loadPipelines();
|
||||||
|
@ -74,4 +75,3 @@ class CreateProjectStore {
|
||||||
export const createProjectStore = new CreateProjectStore(
|
export const createProjectStore = new CreateProjectStore(
|
||||||
new CreateProjectRepository()
|
new CreateProjectRepository()
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -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 (
|
||||||
|
<>
|
||||||
|
<Upload
|
||||||
|
onChange={(e) => {
|
||||||
|
console.log(e);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Button>Upload root entity</Button>
|
||||||
|
</Upload>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
});
|
|
@ -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, "");
|
||||||
|
}
|
||||||
|
}
|
|
@ -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()){
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,17 +1,18 @@
|
||||||
import { makeAutoObservable } from "mobx";
|
import makeAutoObservable from "mobx-store-inheritance";
|
||||||
import { v4 as uuidv4 } from "uuid";
|
import { v4 as uuidv4 } from "uuid";
|
||||||
import { TriggerType } from "../../../core/model/trigger_model";
|
import { TriggerType } from "../../../core/model/trigger_model";
|
||||||
import { TriggerRepository } from "../data/trigger_repository";
|
import { TriggerRepository } from "../data/trigger_repository";
|
||||||
import { TriggerViewModel } from "../model/trigger_form_view_model";
|
import { TriggerViewModel } from "../model/trigger_form_view_model";
|
||||||
|
import { BaseStore } from "../../../core/store/base_store";
|
||||||
|
|
||||||
class TriggerStore {
|
class TriggerStore extends BaseStore {
|
||||||
constructor(repository: TriggerRepository) {
|
constructor(repository: TriggerRepository) {
|
||||||
|
super();
|
||||||
this.triggerType = TriggerType.FILE;
|
this.triggerType = TriggerType.FILE;
|
||||||
this.repository = repository;
|
this.repository = repository;
|
||||||
makeAutoObservable(this);
|
makeAutoObservable(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
isLoading = false;
|
|
||||||
triggerDescription: string = "";
|
triggerDescription: string = "";
|
||||||
triggerType: TriggerType;
|
triggerType: TriggerType;
|
||||||
codeTriggerValue = "";
|
codeTriggerValue = "";
|
||||||
|
@ -71,7 +72,7 @@ class TriggerStore {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
async saveResult(): Promise<void> {
|
async saveResult(): Promise<void> {
|
||||||
this.isLoading = true
|
this.isLoading = true;
|
||||||
await this.repository.save({
|
await this.repository.save({
|
||||||
type: this.getTriggerDescription(),
|
type: this.getTriggerDescription(),
|
||||||
description: this.triggerDescription,
|
description: this.triggerDescription,
|
||||||
|
@ -79,7 +80,7 @@ class TriggerStore {
|
||||||
return el.value;
|
return el.value;
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
this.isLoading = false
|
this.isLoading = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
export class PipelineInstanceRepository {}
|
|
@ -1,14 +1,19 @@
|
||||||
import * as React from "react";
|
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/";
|
||||||
|
|
||||||
export const PipelineInstanceScreenPath = '/pipeline_instance/:id'
|
|
||||||
export const PipelineInstanceScreen: React.FunctionComponent = () => {
|
export const PipelineInstanceScreen: React.FunctionComponent = () => {
|
||||||
|
const [pipelineInstanceStore] = React.useState(
|
||||||
|
() => new PipelineInstanceStore()
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<LoadPage
|
||||||
|
needBackButton={false}
|
||||||
<Button></Button>
|
isError={pipelineInstanceStore.isError}
|
||||||
</>
|
isLoading={pipelineInstanceStore.isLoading}
|
||||||
|
children={<div></div>}
|
||||||
|
/>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,6 +1,7 @@
|
||||||
|
import { DatabaseModel } from "../../../core/model/database_model";
|
||||||
import { IProcess } from "../../create_process/model/process_model";
|
import { IProcess } from "../../create_process/model/process_model";
|
||||||
|
|
||||||
export interface IProjectModel {
|
export interface IProjectModel extends DatabaseModel {
|
||||||
pipelines: [IProcess];
|
pipelines: [IProcess];
|
||||||
rootDir: string;
|
rootDir: string;
|
||||||
description: string;
|
description: string;
|
||||||
|
|
|
@ -1,17 +1,19 @@
|
||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
|
|
||||||
import { observer } from "mobx-react-lite";
|
import { observer } from "mobx-react-lite";
|
||||||
import { LoadPage } from "../../../core/ui/pages/load_page";
|
import { LoadPage } from "../../../core/ui/pages/load_page";
|
||||||
import { CreateProjectScreenPath } from "../../create_project/create_project_screen";
|
import { CreateProjectScreenPath } from "../../create_project/create_project_screen";
|
||||||
import { SelectProjectStore } from "./select_project_store";
|
import { SelectProjectStore } from "./select_project_store";
|
||||||
import { SelectProjectRepository } from "../data/select_project_repository";
|
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 SelectProjectScreenPath = "/select_project";
|
||||||
|
|
||||||
export const SelectProjectScreen: React.FunctionComponent = observer(() => {
|
export const SelectProjectScreen: React.FunctionComponent = observer(() => {
|
||||||
const [selectProjectStore] = React.useState(
|
const [selectProjectStore] = React.useState(
|
||||||
() => new SelectProjectStore(new SelectProjectRepository())
|
() => new SelectProjectStore(new SelectProjectRepository())
|
||||||
);
|
);
|
||||||
|
const navigate = useNavigate();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
@ -25,7 +27,13 @@ export const SelectProjectScreen: React.FunctionComponent = observer(() => {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div>{el.description}</div>
|
<div>{el.description}</div>
|
||||||
<div>+(РЕАЛИЗУЙ ТУТ ПЛЮСИК БЛЯТЬ ИЛИ КНОПКУ)</div>
|
<div>
|
||||||
|
<Button
|
||||||
|
onClick={() => navigate(CreateProjectInstancePath + el._id)}
|
||||||
|
>
|
||||||
|
create instance
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
|
|
|
@ -1,15 +1,16 @@
|
||||||
import { makeAutoObservable } from "mobx";
|
import makeAutoObservable from "mobx-store-inheritance";
|
||||||
import { SelectProjectRepository } from "../data/select_project_repository";
|
import { SelectProjectRepository } from "../data/select_project_repository";
|
||||||
import { IProjectModel } from "../model/project_model";
|
import { IProjectModel } from "../model/project_model";
|
||||||
|
import { BaseStore } from "../../../core/store/base_store";
|
||||||
|
|
||||||
export class SelectProjectStore {
|
export class SelectProjectStore extends BaseStore {
|
||||||
repository: SelectProjectRepository;
|
repository: SelectProjectRepository;
|
||||||
isLoading = false;
|
|
||||||
isError = false;
|
|
||||||
page = 1;
|
page = 1;
|
||||||
projects: IProjectModel[] = [];
|
projects: IProjectModel[] = [];
|
||||||
|
|
||||||
constructor(repository: SelectProjectRepository) {
|
constructor(repository: SelectProjectRepository) {
|
||||||
|
super()
|
||||||
this.repository = repository;
|
this.repository = repository;
|
||||||
makeAutoObservable(this);
|
makeAutoObservable(this);
|
||||||
this.getPipelines();
|
this.getPipelines();
|
||||||
|
|
|
@ -10,7 +10,7 @@ export interface ISocketListerProps {
|
||||||
export const SocketLister = observer((props: ISocketListerProps) => {
|
export const SocketLister = observer((props: ISocketListerProps) => {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{socketListerStore.socketDisconnect ? (
|
{socketListerStore.socketHasDisconnect ? (
|
||||||
<ReloadIcon
|
<ReloadIcon
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
socketListerStore.reconnect();
|
socketListerStore.reconnect();
|
||||||
|
|
|
@ -3,7 +3,7 @@ import { SocketRepository } from "../../core/repository/socket_repository";
|
||||||
|
|
||||||
class SocketListerStore {
|
class SocketListerStore {
|
||||||
repository: SocketRepository;
|
repository: SocketRepository;
|
||||||
socketDisconnect = false;
|
socketHasDisconnect = false;
|
||||||
|
|
||||||
constructor(repository: SocketRepository) {
|
constructor(repository: SocketRepository) {
|
||||||
this.repository = repository;
|
this.repository = repository;
|
||||||
|
@ -13,7 +13,7 @@ class SocketListerStore {
|
||||||
|
|
||||||
async reconnect() {
|
async reconnect() {
|
||||||
await this.repository.connect()
|
await this.repository.connect()
|
||||||
this.socketDisconnect = false
|
this.socketHasDisconnect = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue