Commit cc24d582 authored by Sabino Papagna's avatar Sabino Papagna
Browse files

remove web folder to restore the original one

parent f162db8c
.idea
node_modules
dist
typings
\ No newline at end of file
Test
\ No newline at end of file
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { RouterModule } from '@angular/router';
import { HttpModule } from '@angular/http';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
//import { LocalStorageService, LOCAL_STORAGE_SERVICE_CONFIG } from 'angular-2-local-storage';
import { AppComponent } from './components/app.component';
import { HomeComponent } from './components/home.component';
import { DashboardComponent } from './components/dashboard.component';
import { ExecutionsInfoComponent } from './components/executions/info.component';
import { ExecutionsListComponent } from './components/executions/list.component';
import { ExecutionsNewComponent } from './components/executions/new.component';
import { NavbarComponent } from './components/navbar.component';
import { ApiService } from './services/api.service';
import { StorageService } from './services/storage.service';
import { ToDatePipe } from './pipes/todate.pipe'
import { CapitalizePipe } from './pipes/capitalize.pipe'
// Create config options (see ILocalStorageServiceConfigOptions) for deets:
let localStorageServiceConfig = {
prefix: 'zoe',
storageType: 'sessionStorage'
};
@NgModule({
imports: [
BrowserModule,
FormsModule,
ReactiveFormsModule,
HttpModule,
RouterModule.forRoot([
{ path: '', component: HomeComponent, pathMatch: 'full' },
{ path: 'dashboard', component: DashboardComponent, pathMatch: 'full' },
{ path: 'executions/list', component: ExecutionsListComponent, pathMatch: 'full' },
{ path: 'executions/new', component: ExecutionsNewComponent, pathMatch: 'full' },
{ path: 'executions/:id', component: ExecutionsInfoComponent }
])
],
declarations: [
CapitalizePipe,
ToDatePipe,
AppComponent,
NavbarComponent,
HomeComponent,
DashboardComponent,
ExecutionsListComponent,
ExecutionsInfoComponent,
ExecutionsNewComponent
],
providers: [
ApiService,
StorageService,
// LocalStorageService,
// {
// provide: LOCAL_STORAGE_SERVICE_CONFIG, useValue: localStorageServiceConfig
// }
],
bootstrap: [
AppComponent
]
})
export class AppModule { }
import { ModuleWithProviders } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { HomeComponent } from './components/home.component';
import { DashboardComponent } from './components/dashboard.component';
import { ExecutionsInfoComponent } from './components/executions/info.component';
import { ExecutionsListComponent } from './components/executions/list.component';
import { ExecutionsNewComponent } from './components/executions/new.component';
const appRoutes: Routes = [
{ path: '', component: HomeComponent, pathMatch: 'full' },
{ path: 'dashboard', component: DashboardComponent, pathMatch: 'full' },
{ path: 'executions/list', component: ExecutionsListComponent, pathMatch: 'full' },
{ path: 'executions/new', component: ExecutionsNewComponent, pathMatch: 'full' },
{ path: 'executions/:id', component: ExecutionsInfoComponent }
];
export const routing: ModuleWithProviders = RouterModule.forRoot(appRoutes);
\ No newline at end of file
import { Component } from '@angular/core';
@Component({
selector: 'zoe',
template: `
<navbar></navbar>
<div class="container body">
<div class="main_container">
<router-outlet></router-outlet>
</div>
</div>
`
})
export class AppComponent {
}
\ No newline at end of file
import { Component } from '@angular/core';
@Component({
selector: 'dashboard',
template: `
<h1>Dashboard page</h1>
`
})
export class DashboardComponent {
}
\ No newline at end of file
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, Params } from '@angular/router';
import { Execution } from '../../entities/execution.entity';
import { Service } from '../../entities/service.entity';
import { ApiService } from '../../services/api.service';
@Component({
selector: 'executions-info',
template: `
<p *ngIf="errorMessage" class="bg-danger">{{errorMessage}}</p>
<p *ngIf="warningMessage" class="bg-warning">{{warningMessage}}</p>
<div *ngIf="loading" class="spinner-block">
<div class="spinner-title">Loading...</div> <i class="spinner-icon"></i>
</div>
<div *ngIf="!loading && execution">
<h1>Execution <em>{{execution.id}}</em></h1>
<hr />
<h3>Details</h3>
<dl class="dl-horizontal">
<dt>Name</dt>
<dd>{{execution.name}}</dd>
<dt>Application name</dt>
<dd>{{execution.applicationName()}}</dd>
<dt>Owner</dt>
<dd>{{execution.owner}}</dd>
<dt>Status</dt>
<dd>{{execution.status}}</dd>
<dt>Submitted</dt>
<dd *ngIf="execution.submitted">{{execution.submitted | toDate | date:'medium'}}</dd>
<dd *ngIf="!execution.submitted">Not yet</dd>
<dt *ngIf="execution.scheduled">Scheduled</dt>
<dd *ngIf="execution.scheduled">{{execution.scheduled | toDate | date:'medium'}}</dd>
<dt>Started</dt>
<dd *ngIf="execution.started">{{execution.started | toDate | date:'medium'}}</dd>
<dd *ngIf="!execution.started">Not yet</dd>
<dt>Finished</dt>
<dd *ngIf="execution.finished">{{execution.finished | toDate | date:'medium'}}</dd>
<dd *ngIf="!execution.finished">Not yet</dd>
</dl>
<h3>Services</h3>
<div *ngIf="!hasServices()" class="row">
<div class="text-danger col-md-3 col-md-offset-1">No services</div>
</div>
<div *ngIf="hasServices()" class="row service-list">
<div class="col-md-6">
<dl *ngFor="let service of services" class="dl-horizontal">
<dt>Id</dt>
<dd>{{service.id}}</dd>
<dt>Name</dt>
<dd>{{service.name}}</dd>
<dt>Zoe Status</dt>
<dd>{{service.status | capitalize}}</dd>
<dt>Docker Status</dt>
<dd>{{service.dockerStatus | capitalize}}</dd>
<dt *ngIf="service.link()">Link</dt>
<dd *ngIf="service.link()"><a [href]="service.link().url" target="_blank">{{service.link().name}}</a></dd>
</dl>
</div>
</div>
</div>
`
})
export class ExecutionsInfoComponent implements OnInit {
private loading = true
private errorMessage: string
private warningMessage: string
private execution: Execution;
private services: Service[]
constructor(
private route: ActivatedRoute,
private apiService: ApiService
) { }
ngOnInit(): void {
this.route.params.forEach((params: Params) => {
let id = params['id'];
this.apiService.getExecutionDetails(id)
.then(execution => this.setExecutionDetails(execution))
.catch(error => this.showError('Execution not found.'));
});
}
hasServices(): Boolean {
return this.services && (this.services.length > 0)
}
setExecutionDetails(execution: Execution) {
this.execution = execution
this.getServicesDetails(execution)
}
getServicesDetails(execution: Execution) {
if (execution.services && execution.services.length > 0) {
this.services = []
var errors = false
for (let srv of execution.services) {
this.apiService.getServiceDetails(srv.toString())
.then(service => this.services.push(service))
.catch(error => errors = true);
}
if (errors)
this.showWarning('Failed to retrieve one or more services.');
this.hideLoading()
}
}
showLoading() {
this.loading = true
}
hideLoading() {
this.loading = false
}
showError(msg: string) {
this.hideLoading()
this.errorMessage = msg
}
showWarning(msg: string) {
this.hideLoading()
this.warningMessage = msg
}
}
\ No newline at end of file
import { Component, OnInit } from '@angular/core';
import { Execution } from '../../entities/execution.entity';
import { ApiService } from '../../services/api.service';
import { StorageService } from '../../services/storage.service';
import { Router } from '@angular/router'
@Component({
selector: 'executions-list',
template: `
<div *ngIf="!executionToDisplay()" class="spinner-block">
<div class="spinner-title">Loading...</div> <i class="spinner-icon"></i>
</div>
<div *ngIf="executionToDisplay()">
<div *ngIf="loading" class="spinner-block">
<div class="spinner-title">Loading...</div> <i class="spinner-icon"></i>
</div>
<div *ngIf="executionToDisplay().length > 0">
<h1 style="display:inline-block">Executions list</h1>
<button type="button" class="btn btn-default" [class.active]="adminMode" style="display:inline-block;float:right;" (click)="changeAdminMode()">{{ buttonTitle() }}</button>
<div class="table-responsive" id="executions-list-table">
<table class="table table-hover table-striped">
<thead>
<tr>
<th>ID</th>
<th>Execution Name</th>
<th>User</th>
<th>Status</th>
<th>Scheduled</th>
<th>Started</th>
<th>Finished</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let execution of executionToDisplay()" [id]="['execution-'+execution.id]">
<td><a [routerLink]="['/executions/'+execution.id]">{{execution.id}}</a></td>
<td>{{execution.name}}</td>
<td>{{execution.owner}}</td>
<td>{{execution.status | capitalize}}</td>
<td><div *ngIf="execution.scheduled">{{execution.scheduled | toDate | date:'medium'}}</div></td>
<td><div *ngIf="execution.started">{{execution.started | toDate | date:'medium'}}</div></td>
<td><div *ngIf="execution.ended">{{execution.ended | date:'medium'}}</div></td>
<td>
<a href="javascript:void(0)" *ngIf="execution.canBeRestarted()" (click)="restartExecution(execution)">Restart</a>
<a href="javascript:void(0)" *ngIf="execution.canBeDeleted()" (click)="deleteExecution(execution.id)">Delete</a>
<a href="javascript:void(0)" *ngIf="execution.canBeTerminated()" (click)="terminateExecution(execution.id)">Terminate</a>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div *ngIf="executionToDisplay().length <= 0">
<h1>No Executions</h1>
</div>
</div>
`
})
export class ExecutionsListComponent implements OnInit {
private adminMode = true
private loading = false
private executionsList: Execution[]
closeResult: string;
constructor(
private apiService: ApiService,
private router: Router,
private storageService: StorageService
) { }
ngOnInit(): void {
this.getExecutions()
}
getExecutions() : void {
this.showLoading()
this.apiService.getAllExecutions()
.then(executions => {
this.executionsList = executions
this.hideLoading()
// check if any execution has "starting" status, if so, refresh the list after 2sec
if (this.executionsList.filter(execution => execution.status == 'starting').length > 0) {
setTimeout(this.getExecutions(), 2000);
}
// check if any execution has "cleaning up" status, if so, refresh the list after 1sec
else if (this.executionsList.filter(execution => execution.status == 'cleaning up').length > 0) {
setTimeout(this.getExecutions(), 1000);
}
});
}
restartExecution(execution: Execution) {
this.showLoading()
this.apiService.startExecution(execution.name, execution.description.rawObject)
.then(executionId => this.router.navigateByUrl('executions/' + executionId))
.catch(error => {
alert('There was an error while trying to restart this execution. Please try again.')
this.hideLoading()
})
}
deleteExecution(id: string) {
this.apiService.deleteExecution(id)
.then(terminated => {
if (terminated)
this.getExecutions()
else {
alert('Error while trying to delete execution ' + id)
this.hideLoading()
}
});
}
terminateExecution(id: string) {
this.apiService.terminateExecution(id)
.then(terminated => {
if (terminated)
this.getExecutions()
else {
alert('Error while trying to terminate execution ' + id)
this.hideLoading()
}
});
}
changeAdminMode() {
this.adminMode = !this.adminMode
}
buttonTitle() : string {
if (this.adminMode)
return 'View all'
else
return 'View mine'
}
showLoading() {
this.loading = true
}
hideLoading() {
this.loading = false
}
executionToDisplay(): Execution[] {
if (this.executionsList) {
if (this.adminMode)
return this.executionsList
else
return this.executionsList.filter(execution => execution.owner == this.storageService.getUsername())
}
else
return null
}
}
\ No newline at end of file
import { Component, ViewChild, ElementRef, AfterViewInit } from '@angular/core';
import { ApiService } from '../../services/api.service';
import { Router } from '@angular/router'
@Component({
selector: 'executions-new',
template: `
<h1>New Execution</h1>
<form class="form-horizontal" id="execution-new" (ngSubmit)="startExecution($event)">
<div class="form-group">
<label for="inputName" class="col-sm-2 control-label">Name</label>
<div class="col-sm-10">
<input type="name" class="form-control" id="inputName" placeholder="Enter a name" (keyup)="onNameKeyup($event)" (keypress)="onNameKeypress($event)">
</div>
</div>
<div class="form-group">
<label for="inputDescription" class="col-sm-2 control-label">Description</label>
<div class="col-sm-10">
<label class="btn btn-default btn-file">
Browse <input type="file" style="display: none;" accept="application/json" (change)="onFileChange($event)">
</label>
<span #fileMessage style="margin-left: 10px;">Please select a valid JSON file</span>
</div>
</div>
<button type="submit" class="btn btn-success" style="margin-top:20px;" [disabled]="!canBeSubmitted()">Submit</button>
</form>
`
})
export class ExecutionsNewComponent implements AfterViewInit {
@ViewChild('fileMessage') fileMessage: ElementRef;
private executionName: string
private application: Object
constructor(
private apiService: ApiService,
private router: Router
) { }
ngAfterViewInit() {
}
startExecution() {
this.apiService.startExecution(this.executionName, this.application)
.then(executionId => this.router.navigateByUrl('executions/' + executionId))
.catch(error => alert('There was a problem creating the new execution, please try again.'));
}
onNameKeypress(e): boolean {
e = e || window.event;
var charCode = (typeof e.which == "undefined") ? e.keyCode : e.which;
var charStr = String.fromCharCode(charCode);
return /^([A-Za-z0-9\-]+)$/.test(charStr)
}
onNameKeyup(event) {
this.executionName = event.srcElement.value
}
onFileChange(event) {
let file = event.srcElement.files[0]
let component = this
var myReader: FileReader = new FileReader();
myReader.onloadend = function(e){
let data: string = myReader.result
try {
component.application = JSON.parse(data)
component.setFilenameToDisplay(file.name)
} catch(e) {
component.setFilenameToDisplay('Selected file is not a valid JSON file.')
}
}
myReader.readAsText(file)
}
setFilenameToDisplay(text: string) {
this.fileMessage.nativeElement.textContent = text
}
canBeSubmitted(): boolean {
return ((this.executionName != null) && this.executionName.length > 3 && (this.application != null))
}
}
\ No newline at end of file
import { Component } from '@angular/core';
import { FormGroup, FormControl, Validators, FormBuilder } from '@angular/forms';
import { Router } from '@angular/router'
import { ApiService } from '../services/api.service';
@Component({
selector: 'home',
template: `
<h1>Login</h1>
<form [formGroup]="loginForm" class="form-horizontal" id="login" (ngSubmit)="doLogin()">
<div class="form-group">
<label for="inputUsername" class="col-sm-2 control-label">Username</label>
<div class="col-sm-4">
<input type="text" class="form-control" id="inputUsername" formControlName="username">
</div>
</div>
<div class="form-group">
<label for="inputPassword" class="col-sm-2 control-label">Password</label>
<div class="col-sm-4">
<input type="password" class="form-control" id="inputPassword" formControlName="password">
</div>
</div>
<button type="submit" class="btn btn-success" style="margin-top:20px;">Submit</button>
</form>
`
})
export class HomeComponent {
loginForm = new FormGroup({
username: new FormControl(),
password: new FormControl()
})
constructor(
private apiService: ApiService,
private router: Router
) {
if (this.apiService.isUserLoggedIn())
this.router.navigateByUrl('executions/list')
}
doLogin() {
let username = this.loginForm.controls['username'].value
let password = this.loginForm.controls['password'].value
this.apiService.login(username, password)
.then(logged => this.loginHandler(logged))
.catch(error => this.showError('There was an error while trying to contact the server. Please try again later.'));
}
loginHandler(logged: Boolean) {
if (logged)
this.router.navigateByUrl('executions/list');
else
this.showError('Login failed. Please verify username and/or password.')
}
showError(msg: string) {
alert(msg)
}
}
export class Credentials {
constructor(
public username: string,
public password: string
) { }
}
\ No newline at end of file
import { Component } from '@angular/core';
import { ApiService } from '../services/api.service'
@Component({
selector: 'navbar',
template: `
<nav class="navbar navbar-default navbar-fixed-top">
<div class="container-fluid">
<div class="navbar-header">
<button type="button" class="collapsed navbar-toggle" data-toggle="collapse" data-target="#navbar-collapse" aria-expanded="false">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a [routerLink]="['']" class="navbar-brand">Zoe</a>
</div>
<div class="collapse navbar-collapse" id="navbar-collapse">
<ul class="nav navbar-nav">