8000 feat(ui): add maintenance page (#4651) · ovh/cds@bd8c3f8 · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Commit bd8c3f8

Browse files
sguiheuxbnjjj
authored andcommitted
feat(ui): add maintenance page (#4651)
1 parent bef82cb commit bd8c3f8

19 files changed

+1760
-18
lines changed

engine/api/event/publish_system.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package event
2+
3+
import (
4+
"fmt"
5+
"time"
6+
7+
"github.com/fatih/structs"
8+
9+
"github.com/ovh/cds/sdk"
10+
)
11+
12+
// PublishMaintenanceEvent publish maintenance event
13+
func PublishMaintenanceEvent(payload interface{}) {
14+
event := sdk.Event{
15+
Timestamp: time.Now(),
16+
Hostname: hostname,
17+
CDSName: cdsname,
18+
EventType: fmt.Sprintf("%T", payload),
19+
Payload: structs.Map(payload),
20+
}
21+
_ = publishEvent(event)
22+
}

engine/api/events.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,10 @@ func (b *eventsBroker) ServeHTTP() service.Handler {
238238
}
239239

240240
func (client *eventsBrokerSubscribe) manageEvent(event sdk.Event) bool {
241+
if strings.HasPrefix(event.EventType, "sdk.EventMaintenance") {
242+
return true
243+
}
244+
241245
var isSharedInfra bool
242246
for _, g := range client.User.Groups {
243247
if g.ID == group.SharedInfraGroup.ID {

engine/api/maintenance.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"strconv"
66
"time"
77

8+
"github.com/ovh/cds/engine/api/event"
89
"github.com/ovh/cds/sdk"
910
"github.com/ovh/cds/sdk/log"
1011
)
@@ -33,6 +34,7 @@ func (a *API) listenMaintenance(c context.Context) error {
3334
log.Warning("listenMaintenance> Cannot parse value %s: %s", msg, err)
3435
}
3536
a.Maintenance = b
37+
event.PublishMaintenanceEvent(sdk.EventMaintenance{Enable: b})
3638
}
3739
}
3840
}

engine/api/status.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,12 @@ func (api *API) computeGlobalStatus(srvs []sdk.Service) sdk.MonitoringStatus {
173173
})
174174
}
175175

176+
linesGlobal = append(linesGlobal, sdk.MonitoringStatusLine{
177+
Status: sdk.MonitoringStatusOK,
178+
Component: "Global/Maintenance",
179+
Value: fmt.Sprintf("%v", api.Maintenance),
180+
})
181+
176182
for stype, r := range resume {
177183
if r.minInstance == 0 {
178184
continue

sdk/event.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,3 +162,9 @@ type EventNotif struct {
162162
Subject string `json:"subject,omitempty"`
163163
Body string `json:"body,omitempty"`
164164
}
165+
166+
// EventMaintenance contains event data for maintenance event
167+
//easyjson:json
168+
type EventMaintenance struct {
169+
Enable bool `json:"enable"`
170+
}

ui/angular.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,8 @@
5858
"node_modules/ansi_up/ansi_up.js",
5959
"node_modules/sanitize-html/dist/sanitize-html.min.js",
6060
"node_modules/duration-js/duration.js",
61-
"node_modules/prismjs/prism.js"
61+
"node_modules/prismjs/prism.js",
62+
"src/assets/js/pacman.js"
6263
]
6364
},
6465
"configurations": {
@@ -142,7 +143,8 @@
142143
"resources/cds-hint.js",
143144
"node_modules/ansi_up/ansi_up.js",
144145
"node_modules/sanitize-html/dist/sanitize-html.min.js",
145-
"node_modules/duration-js/duration.js"
146+
"node_modules/duration-js/duration.js",
147+
"src/assets/js/pacman.js"
146148
],
147149
"styles": [
148150
"node_modules/dragula/dist/dragula.css",

ui/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@
7272
"immutable": "4.0.0-rc.12",
7373
"js-beautify": "1.8.9",
7474
"lodash-es": "4.17.14",
75+
"modernizr": "^3.7.1",
7576
"moment": "2.24.0",
7677
"ng-event-source": "1.0.14",
7778
"ng-semantic": "https://github.com/sguiheux/ngSemantic/tarball/sgu-master",

ui/src/app/app.component.html

Lines changed: 25 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,31 @@
11
<div id="AppComponent">
2-
<div id="navbar" *ngIf="isConnected" [class.connected]="isConnected">
3-
<app-navbar></app-navbar>
4-
</div>
5-
<div id="banner" class="pointing" (click)="refresh()" *ngIf="showUIUpdatedBanner">
6-
{{ 'ui_updated' | translate }}
7-
</div>
2+
<ng-container *ngIf="!maintenance">
3+
<div id="navbar" *ngIf="isConnected" [class.connected]="isConnected">
4+
<app-navbar></app-navbar>
5+
</div>
6+
<div id="banner" class="pointing" (click)="refresh()" *ngIf="showUIUpdatedBanner">
7+
{{ 'ui_updated' | translate }}
8+
</div>
89

9-
<div class="page" [class.connected]="isConnected">
10-
<div class="content" [class.connected]="isConnected">
11-
<div class="toast">
12-
<toaster-container [toasterconfig]="toasterConfig"></toaster-container>
10+
<div class="page" [class.connected]="isConnected">
11+
<div class="content" [class.connected]="isConnected">
12+
<div class="toast">
13+
<toaster-container [toasterconfig]="toasterConfig"></toaster-container>
14+
</div>
15+
<router-outlet></router-outlet>
16+
<div class="ui active text loader" *ngIf="displayResolver">{{ 'common_loading_project' | translate }}</div>
1317
</div>
14-
<router-outlet></router-outlet>
15-
<div class="ui active text loader" *ngIf="displayResolver">{{ 'common_loading_project' | translate }}</div>
1618
</div>
17-
</div>
19+
</ng-container>
20+
<ng-container *ngIf="maintenance">
21+
<div class="maintenance">
22+
<h2>{{ 'maintenance_title' | translate }}</h2>
23+
<div class="logo">
24+
<img src="assets/images/maintenance.svg">
25+
</div>
26+
</div>
27+
</ng-container>
28+
29+
<div class="gamification" #gamification></div>
1830
<app-node-edit-modal></app-node-edit-modal>
1931
</div>

ui/src/app/app.component.scss

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,4 +34,47 @@
3434
padding-top: 0px;
3535
}
3636
}
37+
38+
.maintenance {
39+
40+
h2 {
41+
margin: 50px 0;
42+
text-align: center;
43+
}
44+
45+
.logo {
46+
width: 400px;
47+
margin: auto;
48+
img {
49+
height: 150px;
50+
animation: slidein 10s infinite;
51+
}
52+
}
53+
}
54+
.gamification {
55+
width: 450px;
56+
height: 450px;
57+
margin: auto;
58+
}
59+
}
60+
61+
@keyframes slidein {
62+
from {
63+
margin-left: -50%;
64+
transform: scaleX(1);
65+
}
66+
67+
50% {
68+
margin-left: 100%;
69+
transform: scaleX(1);
70+
}
71+
51% {
72+
margin-left: 100%;
73+
transform: scaleX(-1);
74+
}
75+
76+
to {
77+
margin-left: -50%;
78+
transform: scaleX(-1);
79+
}
3780
}

ui/src/app/app.component.ts

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
import { registerLocaleData } from '@angular/common';
22
import localeEN from '@angular/common/locales/en';
33
import localeFR from '@angular/common/locales/fr';
4-
import { Component, NgZone, OnInit } from '@angular/core';
4+
import { Component, ElementRef, NgZone, OnInit, ViewChild } from '@angular/core';
55
import { Title } from '@angular/platform-browser';
66
import { ActivatedRoute, NavigationEnd, ResolveEnd, ResolveStart, Router } from '@angular/router';
77
import { TranslateService } from '@ngx-translate/core';
8+
import { Store } from '@ngxs/store';
9+
import { GetCDSStatus } from 'app/store/cds.action';
10+
import { CDSState } from 'app/store/cds.state';
811
import { Observable } from 'rxjs';
912
import { bufferTime, filter, map, mergeMap } from 'rxjs/operators';
1013
import { Subscription } from 'rxjs/Subscription';
@@ -22,6 +25,8 @@ import { CDSSharedWorker } from './shared/worker/shared.worker';
2225
import { CDSWebWorker } from './shared/worker/web.worker';
2326
import { CDSWorker } from './shared/worker/worker';
2427

28+
declare var PACMAN: any;
29+
2530
@Component({
2631
selector: 'app-root',
2732
templateUrl: './app.component.html',
@@ -47,6 +52,12 @@ export class AppComponent implements OnInit {
4752
toasterConfig: any;
4853
lastPing: number;
4954
currentTheme: string;
55+
maintenance: boolean;
56+
cdsstateSub: Subscription;
57+
58+
@ViewChild('gamification', {static: false})
59+
eltGamification: ElementRef;
60+
gameInit: boolean;
5061

5162
constructor(
5263
_translate: TranslateService,
@@ -58,7 +69,8 @@ export class AppComponent implements OnInit {
5869
private _router: Router,
5970
private _notification: NotificationService,
6071
private _appService: AppService,
61-
private _toastService: ToastService
72+
private _toastService: ToastService,
73+
private _store: Store
6274
) {
6375
this.zone = new NgZone({ enableLongStackTrace: false });
6476
this.toasterConfig = this._toastService.getConfig();
@@ -87,7 +99,10 @@ export class AppComponent implements OnInit {
8799
this._notification.requestPermission();
88100
}
89101

102+
103+
90104
ngOnInit(): void {
105+
this._store.dispatch(new GetCDSStatus());
91106
this._authStore.getUserlst().subscribe(user => {
92107
if (!user) {
93108
this.isConnected = false;
@@ -135,6 +150,17 @@ export class AppComponent implements OnInit {
135150
this._titleService.setTitle('CDS');
136151
}
137152
});
153+
154+
this.cdsstateSub = this._store.select(CDSState.getCurrentState()).subscribe( m => {
155+
// Switch maintenance ON
156+
if (!this.maintenance && m.maintenance && !this.gameInit) {
157+
setTimeout(() => {
158+
this.gameInit = true;
159+
PACMAN.init(this.eltGamification.nativeElement, '/assets/js/');
160+
}, 1000);
161+
}
162+
this.maintenance = m.maintenance;
163+
});
138164
}
139165

140166
stopWorker(w: CDSWorker, s: Subscription): void {

0 commit comments

Comments
 (0)
0