From 555b9d45324462bfd27e175048e9638cc9511b37 Mon Sep 17 00:00:00 2001 From: Florian THIERRY Date: Mon, 2 Aug 2021 09:35:36 +0200 Subject: [PATCH] Fix modal displaying and add image to application entity. --- cerberus/src/app/app.component.html | 1 + cerberus/src/app/app.module.ts | 4 +- .../create-application.component.html | 10 ++- .../create-application.component.scss | 18 +++++- .../create-application.component.ts | 11 +++- .../applications/status/status.component.ts | 4 +- .../add-application-button.component.ts | 12 +++- .../components/modal/modal.component.html | 8 +++ .../components/modal/modal.component.scss | 63 +++++++++++++++++++ .../core/components/modal/modal.component.ts | 35 +++++++++++ .../src/app/core/services/modal.service.ts | 21 +++++++ cerberus/src/app/header/header.component.scss | 2 + cerberus/src/app/header/header.component.ts | 3 +- .../controller/ApplicationController.java | 7 +++ .../cerberusapp/model/Application.java | 16 ++++- .../cerberusapp/model/ApplicationStatus.java | 45 +++++++++++++ .../mapper/ApplicationEntityMapper.java | 4 +- .../persistence/model/ApplicationEntity.java | 15 +++-- .../service/ApplicationService.java | 15 +++++ src/main/sql/ddl.sql | 1 + 20 files changed, 275 insertions(+), 20 deletions(-) create mode 100644 cerberus/src/app/core/components/modal/modal.component.html create mode 100644 cerberus/src/app/core/components/modal/modal.component.scss create mode 100644 cerberus/src/app/core/components/modal/modal.component.ts create mode 100644 cerberus/src/app/core/services/modal.service.ts create mode 100644 src/main/java/org/takiguchi/cerberus/cerberusapp/model/ApplicationStatus.java diff --git a/cerberus/src/app/app.component.html b/cerberus/src/app/app.component.html index 89c98b9..95a67da 100644 --- a/cerberus/src/app/app.component.html +++ b/cerberus/src/app/app.component.html @@ -2,3 +2,4 @@
+ \ No newline at end of file diff --git a/cerberus/src/app/app.module.ts b/cerberus/src/app/app.module.ts index b1d6819..e1cd04a 100644 --- a/cerberus/src/app/app.module.ts +++ b/cerberus/src/app/app.module.ts @@ -10,6 +10,7 @@ import { StatusComponent } from './applications/status/status.component'; import { ApplicationCardComponent } from './core/components/application-card/application-card.component'; import {MatTooltipModule} from '@angular/material/tooltip'; import { AddApplicationButtonComponent } from './core/components/add-application-button/add-application-button.component'; +import { ModalComponent } from './core/components/modal/modal.component'; @NgModule({ declarations: [ @@ -19,7 +20,8 @@ import { AddApplicationButtonComponent } from './core/components/add-application UiKitComponent, StatusComponent, ApplicationCardComponent, - AddApplicationButtonComponent + AddApplicationButtonComponent, + ModalComponent ], imports: [ RouterModule, diff --git a/cerberus/src/app/applications/create-application/create-application.component.html b/cerberus/src/app/applications/create-application/create-application.component.html index 36582a9..0f405ee 100644 --- a/cerberus/src/app/applications/create-application/create-application.component.html +++ b/cerberus/src/app/applications/create-application/create-application.component.html @@ -1,4 +1,4 @@ -
+

Add a new application

@@ -10,15 +10,19 @@
- +
+
+ + +
- +
diff --git a/cerberus/src/app/applications/create-application/create-application.component.scss b/cerberus/src/app/applications/create-application/create-application.component.scss index 228dca3..e30a025 100644 --- a/cerberus/src/app/applications/create-application/create-application.component.scss +++ b/cerberus/src/app/applications/create-application/create-application.component.scss @@ -1,3 +1,17 @@ -.card { +.content { + width: 300px; margin: auto; -} + + form { + .action { + display: flex; + justify-content: space-between; + + button { + margin: 0; + width: 100px; + flex: 0 0; + } + } + } +} \ No newline at end of file diff --git a/cerberus/src/app/applications/create-application/create-application.component.ts b/cerberus/src/app/applications/create-application/create-application.component.ts index 21518b3..92a8b03 100644 --- a/cerberus/src/app/applications/create-application/create-application.component.ts +++ b/cerberus/src/app/applications/create-application/create-application.component.ts @@ -3,6 +3,7 @@ import { FormBuilder, FormGroup, Validators } from '@angular/forms'; import { Application } from 'src/app/core/entities/Application'; import { ReferentialData } from 'src/app/core/entities/ReferentialData'; import { ApplicationService } from 'src/app/core/services/application.service'; +import { ModalService } from 'src/app/core/services/modal.service'; import { ReferentialDataService } from 'src/app/core/services/referential-data.service'; @Component({ @@ -14,14 +15,16 @@ export class CreateApplicationComponent implements OnInit { form: FormGroup = this._formBuilder.group({ name: [undefined, Validators.required], serviceName: [undefined, Validators.required], - serviceType: [undefined, Validators.required] + serviceType: [undefined, Validators.required], + image: [undefined, Validators.required] }); serviceTypes: ReferentialData[] = []; constructor( private _formBuilder: FormBuilder, private _referentialDataService: ReferentialDataService, - private _applicationService: ApplicationService + private _applicationService: ApplicationService, + private _modalService: ModalService ) { } ngOnInit(): void { @@ -40,4 +43,8 @@ export class CreateApplicationComponent implements OnInit { console.error('Form is invalid'); } } + + onCancel(): void { + this._modalService.close(); + } } diff --git a/cerberus/src/app/applications/status/status.component.ts b/cerberus/src/app/applications/status/status.component.ts index aead6be..899b099 100644 --- a/cerberus/src/app/applications/status/status.component.ts +++ b/cerberus/src/app/applications/status/status.component.ts @@ -1,6 +1,7 @@ import { Component, OnInit } from '@angular/core'; import { Application } from 'src/app/core/entities/Application'; import { ApplicationService } from 'src/app/core/services/application.service'; +import { ModalService } from 'src/app/core/services/modal.service'; @Component({ selector: 'app-status', @@ -11,7 +12,8 @@ export class StatusComponent implements OnInit { applications: Application[] = []; constructor( - private _applicationService: ApplicationService + private _applicationService: ApplicationService, + private _modalService: ModalService ) {} ngOnInit(): void { diff --git a/cerberus/src/app/core/components/add-application-button/add-application-button.component.ts b/cerberus/src/app/core/components/add-application-button/add-application-button.component.ts index 7f9fd4f..760c823 100644 --- a/cerberus/src/app/core/components/add-application-button/add-application-button.component.ts +++ b/cerberus/src/app/core/components/add-application-button/add-application-button.component.ts @@ -1,15 +1,23 @@ import { Component, OnInit } from '@angular/core'; +import { CreateApplicationComponent } from 'src/app/applications/create-application/create-application.component'; +import { ModalService } from '../../services/modal.service'; @Component({ selector: 'app-add-application-button', template: ` - ` }) export class AddApplicationButtonComponent { - + constructor( + private _modalService: ModalService + ) {} + + onClick(): void { + this._modalService.open(CreateApplicationComponent); + } } diff --git a/cerberus/src/app/core/components/modal/modal.component.html b/cerberus/src/app/core/components/modal/modal.component.html new file mode 100644 index 0000000..37c882b --- /dev/null +++ b/cerberus/src/app/core/components/modal/modal.component.html @@ -0,0 +1,8 @@ + \ No newline at end of file diff --git a/cerberus/src/app/core/components/modal/modal.component.scss b/cerberus/src/app/core/components/modal/modal.component.scss new file mode 100644 index 0000000..329b53e --- /dev/null +++ b/cerberus/src/app/core/components/modal/modal.component.scss @@ -0,0 +1,63 @@ +#modal-container { + &.hidden { + #overlay { + display: none; + } + + #modal-frame { + height: 0; + + #modal-window { + top: -500px; + } + } + } + + &.displayed { + display: flex; + + #overlay { + display: flex; + } + + #modal-frame { + #modal-window { + top: 58px; + } + } + } + + #overlay { + position: fixed; + top: 56px; + left: 0; + width: 100%; + height: 100%; + z-index: 100; + } + + #modal-frame { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + z-index: 101; + display: flex; + justify-content: center; + transition: height 1s ease; + + #modal-window { + position: absolute; + background-color: #f6f6f6; + z-index: 102; + padding: 1rem; + border: 1px solid #bfbfbf; + border-top: none; + min-width: 600px; + max-height: 500px; + box-shadow: inset 0px 5px 5px -3px rgba(0,0,0,.2), 0px 5px 10px 1px rgba(0,0,0,.2); + transition: top 1s ease; + } + } +} \ No newline at end of file diff --git a/cerberus/src/app/core/components/modal/modal.component.ts b/cerberus/src/app/core/components/modal/modal.component.ts new file mode 100644 index 0000000..4dfb1e8 --- /dev/null +++ b/cerberus/src/app/core/components/modal/modal.component.ts @@ -0,0 +1,35 @@ +import { Component, ComponentFactoryResolver, ElementRef, OnInit, Type, ViewChild, ViewContainerRef } from "@angular/core"; +import { ModalService } from "../../services/modal.service"; + +@Component({ + selector: 'app-modal', + templateUrl: './modal.component.html', + styleUrls: ['./modal.component.scss'] +}) +export class ModalComponent implements OnInit { + displayed: boolean = false; + modalContentClass: Type | undefined; + @ViewChild('modalFrame', { static: true }) modalFrame: ElementRef | undefined; + @ViewChild('modalContent', { read: ViewContainerRef }) modalContent: ViewContainerRef | undefined; + + constructor( + private _componentFactoryResolver: ComponentFactoryResolver, + private _modalService: ModalService + ) {} + + ngOnInit(): void { + this._modalService.modalContent.subscribe(modalContentClass => { + if (!modalContentClass) { + this.displayed = false; + window.setTimeout(() => { + this.modalContent?.detach(); + }, 1000); + } else { + this.displayed = true; + this.modalContent?.detach(); + const componentFactory = this._componentFactoryResolver.resolveComponentFactory(modalContentClass); + this.modalContent?.createComponent(componentFactory); + } + }) + } +} \ No newline at end of file diff --git a/cerberus/src/app/core/services/modal.service.ts b/cerberus/src/app/core/services/modal.service.ts new file mode 100644 index 0000000..22ffe4b --- /dev/null +++ b/cerberus/src/app/core/services/modal.service.ts @@ -0,0 +1,21 @@ +import { Injectable, Type } from "@angular/core"; +import { BehaviorSubject, Observable } from "rxjs"; + +@Injectable({ + providedIn: 'root' +}) +export class ModalService { + _modalContent: BehaviorSubject | undefined> = new BehaviorSubject | undefined>(undefined); + + open(componentClass: Type): void { + this._modalContent.next(componentClass); + } + + close(): void { + this._modalContent.next(undefined); + } + + get modalContent(): Observable | undefined> { + return this._modalContent.asObservable(); + } +} \ No newline at end of file diff --git a/cerberus/src/app/header/header.component.scss b/cerberus/src/app/header/header.component.scss index 8d4322d..0b53724 100644 --- a/cerberus/src/app/header/header.component.scss +++ b/cerberus/src/app/header/header.component.scss @@ -11,6 +11,8 @@ header { height: 56px; justify-content: center; align-items: center; + border: 1px solid #bfbfbf; + z-index: 102; img { width: 42px; diff --git a/cerberus/src/app/header/header.component.ts b/cerberus/src/app/header/header.component.ts index 9ace5f4..1221b65 100644 --- a/cerberus/src/app/header/header.component.ts +++ b/cerberus/src/app/header/header.component.ts @@ -1,11 +1,10 @@ import { Component } from "@angular/core"; - @Component({ selector: 'app-header', templateUrl: './header.component.html', styleUrls: ['./header.component.scss'] }) export class HeaderComponent { - + } \ No newline at end of file diff --git a/src/main/java/org/takiguchi/cerberus/cerberusapp/controller/ApplicationController.java b/src/main/java/org/takiguchi/cerberus/cerberusapp/controller/ApplicationController.java index 8fcaa86..b8e890f 100644 --- a/src/main/java/org/takiguchi/cerberus/cerberusapp/controller/ApplicationController.java +++ b/src/main/java/org/takiguchi/cerberus/cerberusapp/controller/ApplicationController.java @@ -3,6 +3,7 @@ package org.takiguchi.cerberus.cerberusapp.controller; import org.springframework.http.HttpStatus; import org.springframework.web.bind.annotation.*; import org.takiguchi.cerberus.cerberusapp.model.Application; +import org.takiguchi.cerberus.cerberusapp.model.ApplicationStatus; import org.takiguchi.cerberus.cerberusapp.model.ServiceStatus; import org.takiguchi.cerberus.cerberusapp.service.ApplicationService; @@ -37,6 +38,7 @@ public class ApplicationController { .withName(application.getName()) .withServiceName(application.getServiceName()) .withServiceType(application.getServiceType()) + .withImage(application.getImage()) .build(); return service.add(applicationToAdd); } @@ -80,4 +82,9 @@ public class ApplicationController { public void restart(@PathVariable("applicationId") UUID applicationId) { service.restart(applicationId); } + + @GetMapping("/status") + public List getAllApplicationStatus() { + return service.checkAllStatus(); + } } diff --git a/src/main/java/org/takiguchi/cerberus/cerberusapp/model/Application.java b/src/main/java/org/takiguchi/cerberus/cerberusapp/model/Application.java index b7e1503..c17200d 100644 --- a/src/main/java/org/takiguchi/cerberus/cerberusapp/model/Application.java +++ b/src/main/java/org/takiguchi/cerberus/cerberusapp/model/Application.java @@ -9,16 +9,18 @@ public class Application { /** The technical service name, like a docker container name or a system V service name. */ private final String serviceName; private final ServiceType serviceType; + private final String image; public static Builder anApplication() { return new Builder(); } - private Application(UUID id, String name, String serviceName, ServiceType serviceType) { + private Application(UUID id, String name, String serviceName, ServiceType serviceType, String image) { this.id = id; this.name = name; this.serviceName = serviceName; this.serviceType = serviceType; + this.image = image; } public UUID getId() { @@ -37,11 +39,16 @@ public class Application { return serviceType; } + public String getImage() { + return image; + } + public static class Builder { private UUID id; private String name; private String serviceName; private ServiceType serviceType; + private String image; private Builder() { } @@ -66,8 +73,13 @@ public class Application { return this; } + public Builder withImage(String image) { + this.image = image; + return this; + } + public Application build() { - return new Application(id, name, serviceName, serviceType); + return new Application(id, name, serviceName, serviceType, image); } } } diff --git a/src/main/java/org/takiguchi/cerberus/cerberusapp/model/ApplicationStatus.java b/src/main/java/org/takiguchi/cerberus/cerberusapp/model/ApplicationStatus.java new file mode 100644 index 0000000..ab8c0e1 --- /dev/null +++ b/src/main/java/org/takiguchi/cerberus/cerberusapp/model/ApplicationStatus.java @@ -0,0 +1,45 @@ +package org.takiguchi.cerberus.cerberusapp.model; + +public class ApplicationStatus { + private final Application application; + private final ServiceStatus status; + + public static Builder anApplicationStatus() { + return new Builder(); + } + + public ApplicationStatus(Application application, ServiceStatus status) { + this.application = application; + this.status = status; + } + + public Application getApplication() { + return application; + } + + public ServiceStatus getStatus() { + return status; + } + + public static class Builder { + private Application application; + private ServiceStatus status; + + private Builder() { + } + + public Builder withApplication(Application application) { + this.application = application; + return this; + } + + public Builder withStatus(ServiceStatus status) { + this.status = status; + return this; + } + + public ApplicationStatus build() { + return new ApplicationStatus(application, status); + } + } +} diff --git a/src/main/java/org/takiguchi/cerberus/cerberusapp/persistence/mapper/ApplicationEntityMapper.java b/src/main/java/org/takiguchi/cerberus/cerberusapp/persistence/mapper/ApplicationEntityMapper.java index 9988eb3..afa1004 100644 --- a/src/main/java/org/takiguchi/cerberus/cerberusapp/persistence/mapper/ApplicationEntityMapper.java +++ b/src/main/java/org/takiguchi/cerberus/cerberusapp/persistence/mapper/ApplicationEntityMapper.java @@ -15,6 +15,7 @@ public class ApplicationEntityMapper { .withName(entity.getName()) .withServiceName(entity.getServiceName()) .withServiceType(entity.getServiceType()) + .withImage(entity.getImage()) .build(); } @@ -23,7 +24,8 @@ public class ApplicationEntityMapper { application.getId(), application.getName(), application.getServiceName(), - application.getServiceType() + application.getServiceType(), + application.getImage() ); } } diff --git a/src/main/java/org/takiguchi/cerberus/cerberusapp/persistence/model/ApplicationEntity.java b/src/main/java/org/takiguchi/cerberus/cerberusapp/persistence/model/ApplicationEntity.java index e0e6596..1934cfb 100644 --- a/src/main/java/org/takiguchi/cerberus/cerberusapp/persistence/model/ApplicationEntity.java +++ b/src/main/java/org/takiguchi/cerberus/cerberusapp/persistence/model/ApplicationEntity.java @@ -1,13 +1,10 @@ package org.takiguchi.cerberus.cerberusapp.persistence.model; -import com.fasterxml.jackson.annotation.JsonView; import org.takiguchi.cerberus.cerberusapp.model.ServiceType; import javax.persistence.*; import java.util.UUID; -import static javax.persistence.EnumType.ORDINAL; - @Entity @Table(name = "application") public class ApplicationEntity { @@ -18,15 +15,17 @@ public class ApplicationEntity { private String serviceName; @Enumerated private ServiceType serviceType; + private String image; public ApplicationEntity() { } - public ApplicationEntity(UUID id, String name, String serviceName, ServiceType serviceType) { + public ApplicationEntity(UUID id, String name, String serviceName, ServiceType serviceType, String image) { this.id = id; this.name = name; this.serviceName = serviceName; this.serviceType = serviceType; + this.image = image; } public UUID getId() { @@ -57,6 +56,14 @@ public class ApplicationEntity { return serviceType; } + public String getImage() { + return image; + } + + public void setImage(String image) { + this.image = image; + } + public void setServiceType(ServiceType serviceType) { this.serviceType = serviceType; } diff --git a/src/main/java/org/takiguchi/cerberus/cerberusapp/service/ApplicationService.java b/src/main/java/org/takiguchi/cerberus/cerberusapp/service/ApplicationService.java index 4f98fa8..0f654f0 100644 --- a/src/main/java/org/takiguchi/cerberus/cerberusapp/service/ApplicationService.java +++ b/src/main/java/org/takiguchi/cerberus/cerberusapp/service/ApplicationService.java @@ -3,6 +3,7 @@ package org.takiguchi.cerberus.cerberusapp.service; import org.springframework.stereotype.Service; import org.takiguchi.cerberus.cerberusapp.exception.NotFoundException; import org.takiguchi.cerberus.cerberusapp.model.Application; +import org.takiguchi.cerberus.cerberusapp.model.ApplicationStatus; import org.takiguchi.cerberus.cerberusapp.model.ServiceStatus; import org.takiguchi.cerberus.cerberusapp.service.servicemanager.ServiceManagerProvider; import org.takiguchi.cerberus.cerberusapp.service.validator.ApplicationValidator; @@ -10,8 +11,10 @@ import org.takiguchi.cerberus.cerberusapp.service.validator.ApplicationValidator import java.util.List; import java.util.Optional; import java.util.UUID; +import java.util.stream.Collectors; import static org.takiguchi.cerberus.cerberusapp.model.Application.anApplication; +import static org.takiguchi.cerberus.cerberusapp.model.ApplicationStatus.anApplicationStatus; @Service public class ApplicationService { @@ -94,4 +97,16 @@ public class ApplicationService { NotFoundException::new ); } + + public List checkAllStatus() { + return getAll().stream() + .map(application -> { + ServiceStatus status = checkStatus(application.getId()); + return anApplicationStatus() + .withApplication(application) + .withStatus(status) + .build(); + }) + .collect(Collectors.toList()); + } } diff --git a/src/main/sql/ddl.sql b/src/main/sql/ddl.sql index 709f32d..002dfc5 100644 --- a/src/main/sql/ddl.sql +++ b/src/main/sql/ddl.sql @@ -5,5 +5,6 @@ CREATE TABLE IF NOT EXISTS application ( name VARCHAR NOT NULL, service_name VARCHAR NOT NULL, service_type SMALLINT NOT NULL, + image VARCHAR NOT NULL, CONSTRAINT application_pk PRIMARY KEY (id) ); \ No newline at end of file