Migration to SpringBoot 2.1.6 and Angular 8.

This commit is contained in:
2019-08-11 19:47:43 +02:00
parent 53f49ab13f
commit d919f86233
28 changed files with 425 additions and 221 deletions

19
pom.xml
View File

@@ -14,14 +14,14 @@
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.0.RELEASE</version>
<version>2.1.6.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<java.version>11</java.version>
</properties>
<dependencies>
@@ -33,7 +33,6 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
@@ -53,19 +52,8 @@
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<scope>runtime</scope>
<version>42.2.6</version>
</dependency>
<!-- <dependency> -->
<!-- <groupId>commons-lang</groupId> -->
<!-- <artifactId>commons-lang</artifactId> -->
<!-- <version>2.3</version> -->
<!-- </dependency> -->
<!-- https://mvnrepository.com/artifact/commons-lang/commons-lang -->
<!-- <dependency> -->
<!-- <groupId>org.apache.commons</groupId> -->
<!-- <artifactId>commons-lang3</artifactId> -->
<!-- <version>3.7</version> -->
<!-- </dependency> -->
</dependencies>
<build>
@@ -80,5 +68,4 @@
</plugins>
</build>
</project>

View File

@@ -15,7 +15,7 @@ import org.springframework.transaction.annotation.EnableTransactionManagement;
@EntityScan("org.minager")
@EnableTransactionManagement
@EnableJpaRepositories("org.minager")
@PropertySource("classpath:application.properties")
@PropertySource("classpath:application.yml")
public class JpaConfiguration {
@Value("${spring.datasource.driverClassName}")

View File

@@ -12,7 +12,7 @@ public enum ResultCode {
val = pVal;
}
public int val() {
public final int val() {
return val;
}
}

View File

@@ -1,59 +1,54 @@
package org.minager.serverhandling;
import java.io.IOException;
import javax.servlet.http.HttpServletResponse;
import org.minager.core.constant.ResultCode;
import org.minager.core.entities.business.SystemResult;
import org.minager.core.services.business.SystemService;
import org.minager.core.utils.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@Service
public class ServerHandlingService {
@Autowired
private SystemService systemService;
@Value("${minecraft.server.path}")
private String minecraftServerPath;
@Value("${minecraft.server.shell.name}")
private String minecraftServerShellName;
private String buildMinecraftServerShellPath() {
return StringUtils.concat(minecraftServerPath,
minecraftServerPath.charAt(minecraftServerPath.length() - 1) == '/' ? "" : '/',
minecraftServerShellName);
}
@Value("${minecraft.service.name}")
private String minecraftServiceName;
public int getStatus() {
final SystemResult shellResult = systemService.executeCommand(buildMinecraftServerShellPath(), "api_status");
return Integer.parseInt(shellResult.getStdOut());
final SystemResult shellResult = systemService.executeCommand("sudo service", minecraftServiceName, "status");
return shellResult.getResultCode();
}
private void startOrStopServer(final HttpServletResponse pResponse, final String pAction) throws IOException {
final SystemResult shellResult = systemService.executeCommand(buildMinecraftServerShellPath(), pAction);
if(shellResult.getResultCode() == ResultCode.FAILED.val()) {
pResponse.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE);
} else if(shellResult.getResultCode() == ResultCode.STATE_UNCHANGED.val()) {
int serviceStatus = getStatus();
if("start".equals(pAction) && serviceStatus == 0
|| "stop".equals(pAction) && serviceStatus != 0) {
pResponse.sendError(HttpServletResponse.SC_CONFLICT);
} // else -> SUCCESS, so code 200
} else {
final SystemResult shellResult = systemService.executeCommand("sudo service", minecraftServiceName, pAction);
if(shellResult.getResultCode() == ResultCode.SUCCESS.val()) {
pResponse.setStatus(HttpServletResponse.SC_NO_CONTENT);
} else { // FAILED
pResponse.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE);
}
}
}
public void startServer(final HttpServletResponse pResponse) throws IOException {
startOrStopServer(pResponse, "api_start");
startOrStopServer(pResponse, "start");
}
public void stopServer(final HttpServletResponse pResponse) throws IOException {
startOrStopServer(pResponse, "api_stop");
startOrStopServer(pResponse, "stop");
}
public void restartServer(final HttpServletResponse pResponse) throws IOException {
startOrStopServer(pResponse, "api_restart");
startOrStopServer(pResponse, "restart");
}
}

View File

@@ -1,16 +0,0 @@
# ***********************************************
# Hibernate database configuration
# ***********************************************
spring.datasource.driverClassName=org.postgresql.Driver
spring.datasource.url=jdbc:postgresql://localhost:5432/db_minager
spring.datasource.username=minager
spring.datasource.password=P@ssword
# Disable feature detection by this undocumented parameter. Check the org.hibernate.engine.jdbc.internal.JdbcServiceImpl.configure method for more details.
spring.jpa.properties.hibernate.temp.use_jdbc_metadata_defaults = false
# ***********************************************
# Application custom parameters
# ***********************************************
minager.version=1.0.0
minecraft.server.path=/home/minecraft/server
minecraft.server.shell.name=minecraft-server.sh

View File

@@ -0,0 +1,21 @@
minager:
version: 1.2.0
minecraft:
service:
name: minecraft
spring:
datasource:
driverClassName: org.postgresql.Driver
url: jdbc:postgresql://localhost:5432/db_minager
username: minager
password: P@ssword
jpa:
open-in-view: false
properties:
hibernate:
temp:
# Disable feature detection by this undocumented parameter.
# Check the org.hibernate.engine.jdbc.internal.JdbcServiceImpl.configure method for more details.
use_jdbc_metadata_defaults: false

View File

@@ -0,0 +1,14 @@
#*******&
#***************%
#***********************
***/*********************/*
*(************************# __ __ _
###*#*************$****#### | \/ (_)
#######/****/**$$$$$$$##### | \ / |_ _ __ __ _ __ _ ___ _ __
###########$$$$$$$$$$$$$$$$ | |\/| | | '_ \ / _` |/ _` |/ _ \ '__|
###########$$$$$$$$$$$$$$$$ | | | | | | | | (_| | (_| | __/ |
###########$$$$$$$$$$$$$$$$ |_| |_|_|_| |_|\__,_|\__, |\___|_|
############$$$$$$$$$$$$$$# __/ |
############$$$$$$$$$$$$$ |___/
#########$$$$$$$$$$$
######($$$$$$$

View File

@@ -3,7 +3,7 @@
"version": 1,
"newProjectRoot": "projects",
"projects": {
"ts": {
"minager": {
"root": "",
"sourceRoot": "src",
"projectType": "application",
@@ -27,9 +27,12 @@
"src/assets"
],
"styles": [
"node_modules/font-awesome/scss/font-awesome.scss",
"node_modules/angular-bootstrap-md/scss/bootstrap/bootstrap.scss",
"node_modules/angular-bootstrap-md/scss/mdb-free.scss",
"node_modules/@fortawesome/fontawesome-free/scss/fontawesome.scss",
"node_modules/@fortawesome/fontawesome-free/scss/solid.scss",
"node_modules/@fortawesome/fontawesome-free/scss/regular.scss",
"node_modules/@fortawesome/fontawesome-free/scss/brands.scss",
"node_modules/angular-bootstrap-md/assets/scss/bootstrap/bootstrap.scss",
"node_modules/angular-bootstrap-md/assets/scss/mdb.scss",
"src/styles.scss"
],
"scripts": [
@@ -77,18 +80,18 @@
"serve": {
"builder": "@angular-devkit/build-angular:dev-server",
"options": {
"browserTarget": "ts:build"
"browserTarget": "minager:build"
},
"configurations": {
"production": {
"browserTarget": "ts:build:production"
"browserTarget": "minager:build:production"
}
}
},
"extract-i18n": {
"builder": "@angular-devkit/build-angular:extract-i18n",
"options": {
"browserTarget": "ts:build"
"browserTarget": "minager:build"
}
},
"test": {
@@ -122,7 +125,7 @@
}
}
},
"ts-e2e": {
"minager-e2e": {
"root": "e2e/",
"projectType": "application",
"architect": {
@@ -130,11 +133,11 @@
"builder": "@angular-devkit/build-angular:protractor",
"options": {
"protractorConfig": "e2e/protractor.conf.js",
"devServerTarget": "ts:serve"
"devServerTarget": "minager:serve"
},
"configurations": {
"production": {
"devServerTarget": "ts:serve:production"
"devServerTarget": "minager:serve:production"
}
}
},
@@ -150,5 +153,5 @@
}
}
},
"defaultProject": "ts"
"defaultProject": "minager"
}

View File

@@ -1,9 +1,9 @@
{
"name": "ts",
"version": "0.0.0",
"version": "0.0.1",
"scripts": {
"ng": "ng",
"start": "ng serve",
"start": "ng serve --proxy-config proxy.conf.json",
"build": "ng build",
"test": "ng test",
"lint": "ng lint",
@@ -11,44 +11,44 @@
},
"private": true,
"dependencies": {
"@angular/animations": "^6.1.0",
"@angular/common": "^6.1.0",
"@angular/compiler": "^6.1.0",
"@angular/core": "^6.1.0",
"@angular/forms": "^6.1.0",
"@angular/http": "^6.1.0",
"@angular/platform-browser": "^6.1.0",
"@angular/platform-browser-dynamic": "^6.1.0",
"@angular/router": "^6.1.0",
"@types/chart.js": "^2.7.36",
"angular-bootstrap-md": "^6.2.4",
"angular5-csv": "^0.2.10",
"chart.js": "^2.5.0",
"core-js": "^2.5.4",
"font-awesome": "^4.7.0",
"@angular/animations": "^8.2.1",
"@angular/common": "^8.2.1",
"@angular/compiler": "^8.2.1",
"@angular/core": "^8.2.1",
"@angular/forms": "^8.2.1",
"@angular/http": "^7.2.15",
"@angular/platform-browser": "^8.2.1",
"@angular/platform-browser-dynamic": "^8.2.1",
"@angular/router": "^8.2.1",
"@types/chart.js": "^2.7.56",
"@fortawesome/fontawesome-free": "^5.10.1",
"angular-bootstrap-md": "^8.1.1",
"chart.js": "^2.8.0",
"core-js": "^3.1.4",
"hammerjs": "^2.0.8",
"rxjs": "~6.2.0",
"zone.js": "~0.8.26"
"rxjs": "~6.5.2",
"tslib": "^1.10.0",
"zone.js": "~0.10.1"
},
"devDependencies": {
"@angular-devkit/build-angular": "~0.8.0",
"@angular/cli": "~6.2.3",
"@angular/compiler-cli": "^6.1.0",
"@angular/language-service": "^6.1.0",
"@types/jasmine": "~2.8.8",
"@types/jasminewd2": "~2.0.3",
"@types/node": "~8.9.4",
"codelyzer": "~4.3.0",
"jasmine-core": "~2.99.1",
"@angular-devkit/build-angular": "~0.802.1",
"@angular/cli": "~8.2.1",
"@angular/compiler-cli": "^8.2.1",
"@angular/language-service": "^8.2.1",
"@types/jasmine": "~3.4.0",
"@types/jasminewd2": "~2.0.6",
"@types/node": "~12.7.1",
"codelyzer": "~5.1.0",
"jasmine-core": "~3.4.0",
"jasmine-spec-reporter": "~4.2.1",
"karma": "~3.0.0",
"karma-chrome-launcher": "~2.2.0",
"karma-coverage-istanbul-reporter": "~2.0.1",
"karma-jasmine": "~1.1.2",
"karma-jasmine-html-reporter": "^0.2.2",
"protractor": "~5.4.0",
"ts-node": "~7.0.0",
"tslint": "~5.11.0",
"typescript": "~2.9.2"
"karma": "~4.2.0",
"karma-chrome-launcher": "~3.0.0",
"karma-coverage-istanbul-reporter": "~2.1.0",
"karma-jasmine": "~2.0.1",
"karma-jasmine-html-reporter": "^1.4.2",
"protractor": "~5.4.2",
"ts-node": "~8.3.0",
"tslint": "~5.18.0",
"typescript": "~3.5.3"
}
}

View File

@@ -0,0 +1,6 @@
{
"/api": {
"target": "http://localhost:8080",
"secure": false
}
}

View File

@@ -1,4 +1,5 @@
<app-header></app-header>
<app-notifications></app-notifications>
<div id="versionDiv" *ngIf="!loading && connectedToApi">
APP Version : {{appVersion}} - API Version : {{apiVersion}}
</div>

View File

@@ -20,6 +20,8 @@ import { HeaderComponent } from './header/header.component';
import { ServerComponent } from './server/server.component';
import { LoginComponent } from './login/login.component';
import { DisconnectionComponent } from './disconnection/disconnection.component';
import { NotificationsComponent } from './core/notifications/notifications.component';
import { NotificationElement } from './core/notifications/notification-element/notification-element.component';
// **********************************************
// App Services
@@ -40,7 +42,9 @@ import { TokenInterceptor } from './core/interceptors/token-interceptor';
HeaderComponent,
ServerComponent,
LoginComponent,
DisconnectionComponent
DisconnectionComponent,
NotificationsComponent,
NotificationElement
],
imports: [
BrowserModule,

View File

@@ -0,0 +1,26 @@
/**
* Class which represents a notification class.
* It serves to set the notification appearence.
*/
export class NotificationClass {
/**
* Default constructor.
* @param {string} icon Class name of font-awsome icon.
* @param {string} clazz The class to set notification style.
*/
constructor(
public icon: string,
public clazz: string,
) {}
}
/**
* Constant instances of NotificationClass.
*/
export const NotificationClasses = Object.freeze({
'Error': new NotificationClass('exclamation-circle ', 'alert-danger'),
'Warn': new NotificationClass('exclamation-triangle', 'alert-warning'),
'Info': new NotificationClass('info-circle', 'alert-info'),
'Success': new NotificationClass('check-circle', 'alert-success')
});

View File

@@ -0,0 +1,7 @@
<div id="notification" #notification class="alert {{model.notificationClass.clazz}}" role="alert">
<mdb-icon fas [icon]="model.notificationClass.icon"></mdb-icon> {{model.content}}
<span id="close">
<i class="fa fa-times-circle fas close"
(click)="model.hide()"></i>
</span>
</div>

View File

@@ -0,0 +1,78 @@
import { NotificationClass } from './../notification-class';
import { Component, Input, OnInit, ViewChild, ElementRef } from '@angular/core';
/**
* Class which represents a notification in the notifications list.
*/
@Component({
selector: 'app-notification-element',
templateUrl: 'notification-element.component.html',
styles: [`
#notification {
transition: all 0.7s ease-out;
position: relative;
}
.close {
position: absolute;
right: 7px;
top: 12px;
font-size: 19px;
opacity: 0;
}
#notification:hover .close {
opacity: 0.5;
}
`]
})
export class NotificationElement implements OnInit {
/**
* The notification model.
*/
@Input() model: NotificationModel;
/**
* The notification DOM element.
*/
@ViewChild('notification', {static: true}) notification: ElementRef;
/**
* Sets the DOM element in the model object and plays with opacity.
*/
ngOnInit(): void {
this.model.notification = this.notification;
this.notification.nativeElement.style.opacity = 0;
setTimeout(() => {
this.notification.nativeElement.style.opacity = 1;
}, 100);
}
}
/**
* Class which represents the notification model.
*/
export class NotificationModel {
/**
* Element which represents the DOM element of the notification element.
*/
notification: ElementRef;
/**
* Default constructor.
* @param {string} content The message of the notification.
* @param {NotificationClass} notificationClass The category of the notification (info, error...).
*/
constructor(
public content: string,
public notificationClass: NotificationClass
) {}
/**
* Hides the notification DOM element.
*/
public hide(): void {
this.notification.nativeElement.style.opacity = 0;
setTimeout(() => {
this.notification.nativeElement.style.display = 'none';
}, 800);
}
}

View File

@@ -0,0 +1,5 @@
<div id="notification-container">
<app-notification-element *ngFor="let notification of notificationList"
[model]="notification"></app-notification-element>
</div>

View File

@@ -0,0 +1,108 @@
import { NotificationClass, NotificationClasses } from './notification-class';
import { NotificationModel } from './notification-element/notification-element.component';
import { Component, OnInit } from '@angular/core';
/**
* Class which offers the notifications service.
*/
@Component({
selector: 'app-notifications',
templateUrl: 'notifications.component.html',
styles: [`
#notification-container {
position: fixed;
top: 50px;
right: 20px;
width: 300px;
z-index: 1100;
}
`]
})
export class NotificationsComponent implements OnInit {
/**
* Singleton of the notification service.
*/
private static component: NotificationsComponent;
/**
* List of notifications model.
*/
notificationList: Array<NotificationModel> = [];
/**
* Creates an error notification.
* @param {string} message The content of the notification.
*/
public static error(message: string): void {
NotificationsComponent.notif(message, NotificationClasses.Error);
}
/**
* Creates a warning notification.
* @param {string} message The content of the notification.
*/
public static warn(message: string): void {
NotificationsComponent.notif(message, NotificationClasses.Warn);
}
/**
* Creates an info notification.
* @param {string} message The content of the notification.
*/
public static info(message: string): void {
NotificationsComponent.notif(message, NotificationClasses.Info);
}
/**
* Creates a success notification.
* @param {string} message The content of the notification.
*/
public static success(message: string): void {
NotificationsComponent.notif(message, NotificationClasses.Success);
}
/**
* Create a notification. The {@code notifClass} param defines the category of
* the notification (info, error...).
* @param {string} message The content of the notification.
* @param {NotificationClass} notifClass The category of the notification.
*/
private static notif(message: string, notifClass: NotificationClass): void {
const elem = new NotificationModel(message, notifClass);
NotificationsComponent.component.notificationList.push(elem);
setTimeout(() => {
elem.hide();
setTimeout(() => {
NotificationsComponent.clearNotificationList();
}, 900);
}, 4500);
}
/**
* Clears the consumed notifications in the list.
* When a notification is created, a cooldown is set to hide it after a certain time period.
* In this cooldown, the notification have only its display as {@code none}, but the
* notification isn't remove from the list. This method removes it.
*/
private static clearNotificationList(): void {
NotificationsComponent.component.notificationList.forEach(elem => {
if (elem.notification.nativeElement.style.display === 'none') {
const index = NotificationsComponent.component.notificationList.indexOf(elem);
if (index > -1) {
NotificationsComponent.component.notificationList.splice(index, 1);
}
}
});
}
/**
* Set the reference of the singleton here because this component
* is created at the application startup.
*/
ngOnInit(): void {
NotificationsComponent.component = this;
}
}

View File

@@ -7,18 +7,21 @@
</a>
</logo>
<links>
<form class="form-inline waves-light waves-light ml-auto" mdbWavesEffect>
<form class="form-inline waves-light waves-light ml-auto">
<a routerLink="/login"
*ngIf="!isAuthenticated()"
class="nav-link waves-light"
mdbRippleRadius>
<i class="fa fa-sign-in"></i> Connexion
class="btn waves-effect waves-light"
mdbWavesEffect>
<i class="fa fa-sign-in-alt"></i> Connexion
</a>
<a routerLink="/disconnection"
*ngIf="isAuthenticated()"
class="nav-link waves-light danger-color-dark"
mdbRippleRadius >
<i class="fa fa-sign-out"></i> Déconnexion
id="sign-out"
class="btn waves-effect waves-light"
mdbTooltip="Déconnexion"
placement="bottom"
mdbWavesEffect>
<i class="fa fa-sign-out-alt fa-sm"></i> Déconnexion
</a>
</form>
</links>

View File

@@ -10,10 +10,13 @@ import { environment } from '../../environments/environment';
width: 50px;
height: 50px;
}
a, a:visited {
color: white;
}
#sign-out:hover {
color: white;
background-color: #f44336 !important;
}
`]
})
export class HeaderComponent {

View File

@@ -4,7 +4,7 @@
<form id="form" (ngSubmit)="submitLogin()" #loginForm="ngForm">
<div class="md-form">
<i class="fa fa-envelope prefix grey-text"></i>
<input mdbActive
<input mdbInputDirective
id="email"
name="email"
type="email"
@@ -12,13 +12,13 @@
[(ngModel)]="model.email"
#email="ngModel"
data-error="Veuillez saisir une adresse email valide"
data-sucess=""
[validateSuccess]="false"
required />
<label for="email">Email</label>
</div>
<div class="md-form">
<i class="fa fa-lock prefix grey-text"></i>
<input mdbActive
<input mdbInputDirective
id="password"
name="password"
type="password"
@@ -26,17 +26,12 @@
[(ngModel)]="model.password"
#password="ngModel"
data-error="Veuillez saisir votre mot de passe"
data-sucess=""
[validateSuccess]="false"
required />
<label for="password">Password</label>
</div>
<div id="errorMsg" class="card red lighten-2 text-center z-depth-2">
<div class="card-body">
<p class="white-text mb-0">{{loginError}}</p>
</div>
<label for="password">Mot de passe</label>
</div>
<div class="col submitFormArea">
<button class="float-right waves-effect waves-light indigo btn"
<button class="float-right waves-effect waves-light indigo white-text btn"
type="submit"
[disabled]="!loginForm.form.valid">
Suivant

View File

@@ -1,8 +1,9 @@
import { Component } from '@angular/core';
import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { User } from '../core/entities';
import { LoginService } from './login.service';
import { AuthService } from '../core/services/auth.service';
import { NotificationsComponent } from '../core/notifications/notifications.component';
@Component({
selector: 'app-login',
@@ -24,37 +25,34 @@ import { AuthService } from '../core/services/auth.service';
}
`]
})
export class LoginComponent {
export class LoginComponent implements OnInit {
model: User = new User('', '', '', '', undefined, '');
loginError;
constructor(
private loginService: LoginService,
private authService: AuthService,
private router: Router
private router: Router,
) {}
ngOnInit(): void {
if (this.authService.isAuthenticated()) {
this.navigateToServerPage();
}
}
submitLogin(): void {
this.loginService.login(this.model).subscribe(user => {
this.authService.setToken(user.token);
this.authService.setUser(user);
this.router.navigate(['/server']);
this.navigateToServerPage();
}, error => {
this.setMessage('Email ou password incorrect.');
console.error(error);
NotificationsComponent.error('Email ou password incorrect.');
});
}
setMessage(message: string): void {
this.loginError = message;
const resultMsgDiv = document.getElementById('errorMsg');
resultMsgDiv.style.maxHeight = '64px';
setTimeout(() => {
resultMsgDiv.style.maxHeight = '0px';
setTimeout(() => {
this.loginError = undefined;
}, 550);
}, 3000);
private navigateToServerPage(): void {
this.router.navigate(['/server']);
}
}

View File

@@ -5,13 +5,12 @@
<h1 class="card-title">Serveur Minecraft</h1>
<div>
Status du serveur :
<span *ngIf="!serverStartedChecked" class="badge badge-warning">
<mdb-badge *ngIf="!serverStartedChecked" color="amber darken-2">
Vérification
</span>
<span *ngIf="serverStartedChecked" class="badge"
[ngClass]="serverStarted ? 'badge-success' : 'badge-danger'">
</mdb-badge>
<mdb-badge *ngIf="serverStartedChecked" [ngClass]="serverStarted ? 'green' : 'red'">
{{serverStarted ? 'Démarré' : 'Éteint'}}
</span>
</mdb-badge>
</div>
<div>
Adresse du serveur de jeu :
@@ -26,42 +25,22 @@
Copié !
</span>
</div>
<div style="text-align:center; margin-top: 15px;" *ngIf="isAuthenticated()">
<button mdbBtn
*ngIf="serverStarted"
<div id="action-btn-div" *ngIf="isAuthenticated()">
<button class="waves-effect waves-light indigo white-text btn"
type="button"
class="waves-light indigo btn-rounded"
[disabled]="restarting"
(click)="restartServer()"
[disabled]="restarting || !serverStarted"
mdbWavesEffect>
<i class="fa fa-refresh"></i>&nbsp;
Redémarrer
</button>
<button mdbBtn
<button class="waves-effect waves-light white-text btn"
type="button"
class="waves-light btn-rounded"
[ngClass]="serverStarted ? 'red' : 'green'"
[disabled]="restarting"
(click)="startOrStopServer()"
[disabled]="restarting"
mdbWavesEffect>
<i class="fa" [ngClass]="serverStarted ? 'fa-stop-circle' : 'fa-play-circle'"></i>&nbsp;
{{serverStarted ? 'Éteindre' : 'Démarrer'}}
</button>
<div id="errorMsg" class="msg card red lighten-2 text-center z-depth-2">
<div class="card-body">
<p class="white-text mb-0">{{errorMsg}}</p>
</div>
</div>
<div id="warnMsg" class="msg card orange lighten-2 text-center z-depth-2">
<div class="card-body">
<p class="white-text mb-0">{{warnMsg}}</p>
</div>
</div>
<div id="successMsg" class="msg card green lighten-2 text-center z-depth-2">
<div class="card-body">
<p class="white-text mb-0">{{successMsg}}</p>
</div>
</div>
</div>
</div>
</div>

View File

@@ -1,6 +1,7 @@
import { Component, OnInit } from '@angular/core';
import { ServerService } from './server.service';
import { AuthService } from '../core/services/auth.service';
import { NotificationsComponent } from '../core/notifications/notifications.component';
@Component({
selector: 'app-server',
@@ -16,15 +17,19 @@ import { AuthService } from '../core/services/auth.service';
margin-top: 25px;
cursor: pointer;
}
#action-btn-div {
text-align:center;
margin-top: 15px;
}
#action-btn-div button {
margin-right: 15px;
}
`]
})
export class ServerComponent implements OnInit {
serverAddress = '176.188.217.1:54311';
serverStartedChecked = false;
serverStarted = false;
errorMsg;
warnMsg;
successMsg;
restarting = false;
constructor(
@@ -35,7 +40,7 @@ export class ServerComponent implements OnInit {
ngOnInit(): void {
this.serverService.getStatus().subscribe(pServerStatus => {
this.serverStartedChecked = true;
this.serverStarted = pServerStatus === 1;
this.serverStarted = pServerStatus === 0;
});
}
@@ -47,10 +52,10 @@ export class ServerComponent implements OnInit {
this.restarting = true;
this.serverService.restartServer().subscribe(() => {
this.setMessage('Serveur redémarré.', 'successMsg');
NotificationsComponent.success('Serveur redémarré.');
}, error => {
this.setMessage('Une erreur est survenue lors du redémarrage du serveur.',
'errorMsg');
console.error(error);
NotificationsComponent.error('Une erreur est survenue lors du redémarrage du serveur.');
}, () => {
this.restarting = false;
});
@@ -58,36 +63,18 @@ export class ServerComponent implements OnInit {
startOrStopServer(): void {
this.serverService[(this.serverStarted ? 'stop' : 'start') + 'Server']().subscribe(() => {
this.setMessage('Serveur ' + (this.serverStarted ? 'éteint' : 'démarré') + '.', 'successMsg');
NotificationsComponent.success(`Serveur ${this.serverStarted ? 'éteint' : 'démarré'}.`);
this.serverStarted = !this.serverStarted;
}, error => {
if (error.status === 409) {
this.setMessage('Le serveur est déjà '
+ (this.serverStarted ? 'éteint' : 'démarré') + '.',
'warnMsg');
NotificationsComponent.warn(`Le serveur est déjà ${this.serverStarted ? 'éteint' : 'démarré'}.`);
} else {
this.setMessage('Une erreur est survenue lors '
+ (this.serverStarted ? 'de l\'extinction' : 'du démarrage')
+ 'du serveur.',
'errorMsg');
NotificationsComponent.error(`Une erreur est survenue lors ${this.serverStarted
? 'de l\'extinction' : 'du démarrage'} du serveur.`);
}
});
}
setMessage(message: string, type: string): void {
this[type] = message;
const resultMsgDiv = document.getElementById(type);
resultMsgDiv.style.maxHeight = '64px';
setTimeout(() => {
resultMsgDiv.style.maxHeight = '0px';
setTimeout(() => {
this[type] = undefined;
}, 550);
}, 3000);
}
copyToClipBoard(): void {
document.addEventListener('copy', (e: ClipboardEvent) => {
e.clipboardData.setData('text/plain', (this.serverAddress));

Binary file not shown.

After

Width:  |  Height:  |  Size: 160 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 MiB

View File

@@ -4,7 +4,7 @@
export const environment = {
production: false,
appVersion: '1.0.1',
appVersion: '1.2.0',
title: 'LOCAL'
};

View File

@@ -43,7 +43,7 @@
/** Evergreen browsers require these. **/
// Used for reflect-metadata in JIT. If you use AOT (and only Angular decorators), you can remove.
import 'core-js/es7/reflect';
// import 'core-js/es7/reflect';
/**

View File

@@ -12,7 +12,7 @@ body {
flex-direction: column;
justify-content:space-between;
min-height: 100%;
background-image: url("./assets/images/background.png");
background-image: url("./assets/images/background.jpg");
background-color: #fff;
background-position: center;
background-repeat: no-repeat;