1 Commits

Author SHA1 Message Date
Manuel Romero
0283850cce Assign user to provision 2020-07-06 14:33:17 +02:00
13 changed files with 151 additions and 20 deletions

View File

@@ -9,5 +9,5 @@
<link rel="stylesheet" href="styles.5de5451578cdd1ad7eb0.css"></head>
<body>
<app-root></app-root>
<script src="runtime.689ba4fd6cadb82c1ac2.js" defer></script><script src="polyfills-es5.f752a17531a45fe93c1f.js" nomodule defer></script><script src="polyfills.06ba8d1a3d9dd3a8e8b9.js" defer></script><script src="scripts.5520a99f673924c17e00.js" defer></script><script src="main.2f12033ef901222b1e83.js" defer></script></body>
<script src="runtime.689ba4fd6cadb82c1ac2.js" defer></script><script src="polyfills-es5.f752a17531a45fe93c1f.js" nomodule defer></script><script src="polyfills.06ba8d1a3d9dd3a8e8b9.js" defer></script><script src="scripts.5520a99f673924c17e00.js" defer></script><script src="main.e9f73c1cbb9915107acb.js" defer></script></body>
</html>

File diff suppressed because one or more lines are too long

View File

@@ -1,6 +1,6 @@
{
"name": "qmi-cloud-app",
"version": "1.1.4",
"version": "1.1.5",
"scripts": {
"start": "node -r esm server/server.js",
"start:dev": "nodemon -r esm server/server.js",

View File

@@ -229,6 +229,39 @@ router.delete('/:id', passport.ensureAuthenticatedAndAdmin, async (req, res, nex
}
});
/**
* @swagger
* /provisions/{id}:
* put:
* description: Update Provision by ID
* summary: Update Provision by ID
* tags:
* - admin
* parameters:
* - name: id
* in: path
* type: string
* required: true
* - in: body
* name: body
* description: Provision object
* required: true
* produces:
* - application/json
* responses:
* 200:
* description: Provision
*/
router.put('/:id', passport.ensureAuthenticatedAndAdmin, async (req, res, next) => {
try {
const result = await db.provision.update(req.params.id, req.body);
return res.json(result);
} catch (error) {
next(error);
}
});
/**
* @swagger
* /provisions/{id}/logs:

View File

@@ -41,6 +41,7 @@ import { SubscriptionsService } from './services/deployopts.service';
import { TableApiKeysComponent } from './tables/table-apikeys.component';
import { ApikeyModalComponent } from './modals/edit-apikey.component';
import { VmTypeModalComponent } from './modals/edit-vmtype.component';
import { ProvisionModalComponent } from './modals/edit-provision.component';
@@ -81,7 +82,8 @@ export function markedOptions(): MarkedOptions {
TableApiKeysComponent,
ApikeyModalComponent,
TableVmTypesComponent,
VmTypeModalComponent
VmTypeModalComponent,
ProvisionModalComponent
],
imports: [
BrowserModule,

View File

@@ -2,7 +2,7 @@
<div class="modal-content text-center">
<!--Header-->
<div class="modal-header d-flex justify-content-center">
<p class="heading">{{info.title}}</p>
<p class="heading" [innerHTML]="info.title"></p>
</div>
<!--Body-->

View File

@@ -24,13 +24,13 @@ export class ApikeyModalComponent implements OnInit, OnDestroy {
ngOnInit() {
this._usersService.getUsers().subscribe(res=> {
this.users = res.results;
console.log("apiKey",this.apiKey);
if (this.apiKey) {
this.sendData = JSON.parse(JSON.stringify(this.apiKey))
}
if (this.apiKey.user ) {
this.selectedUser = this.apiKey.user._id;
}
this.users = this.users.sort(function(a, b){return a.displayName.localeCompare(b.displayName);});
if (this.apiKey) {
this.sendData = JSON.parse(JSON.stringify(this.apiKey))
}
if (this.apiKey.user ) {
this.selectedUser = this.apiKey.user._id;
}
})
}

View File

@@ -0,0 +1,26 @@
<!--Content-->
<div class="modal-content">
<div class="modal-header text-center">
<button type="button" class="close pull-right" aria-label="Close" (click)="modalRef.hide()">
<span aria-hidden="true">×</span>
</button>
<h4 class="modal-title w-100 font-weight-bold">Edit Provision</h4>
</div>
<div class="modal-body" style="max-height: 650px; overflow: auto;">
<div>
<section style="padding: 20px 0px;">
<label>Onwer (*):</label>
<select class="browser-default custom-select custom-select-sm" [(ngModel)]="selectedUser">
<option *ngFor="let item of users" [value]="item._id">{{item.displayName}}</option>
</select>
</section>
</div>
</div>
<div class="modal-footer d-flex justify-content-center">
<button style="margin-right: 100px;" *ngIf="sendData._id" mdbBtn color="danger" outline="true" class="waves-light" size="sm" mdbWavesEffect (click)="delete();">Delete</button>
<button mdbBtn color="dark-green" size="sm" outline="true" class="waves-effect" mdbWavesEffect (click)="modalRef.hide()">Cancel</button>
<button mdbBtn color="dark-green" class="waves-light" size="sm" mdbWavesEffect (click)="confirm();">Save</button>
</div>
</div>
<!--/.Content-->

View File

@@ -0,0 +1,45 @@
import { Component, OnInit, OnDestroy } from '@angular/core';
import { MDBModalRef } from 'angular-bootstrap-md';
import { Subject } from 'rxjs';
import { UsersService } from '../services/users.service';
import { ProvisionsService } from '../services/provisions.service';
@Component({
selector: 'qmi-edit-provision',
templateUrl: './edit-provision.component.html',
styleUrls: ['./edit-provision.component.scss']
})
export class ProvisionModalComponent implements OnInit, OnDestroy {
provision;
action: Subject<any> = new Subject();
users;
selectedUser;
sendData : any = {};
constructor( public modalRef: MDBModalRef, private _usersService: UsersService, private _provisionsService: ProvisionsService ) {}
ngOnInit() {
var sub = this._usersService.getUsers().subscribe(res=> {
this.users = res.results;
this.users = this.users.sort(function(a, b){return a.displayName.localeCompare(b.displayName);});
sub.unsubscribe();
if (this.provision.user ) {
this.selectedUser = this.provision.user._id;
}
});
}
ngOnDestroy() {
}
confirm() : void {
this._provisionsService.updateProvisionAdmin(this.provision._id, { user: this.selectedUser } ).subscribe( res=>{
this.action.next(res);
this.modalRef.hide();
});
}
}

View File

@@ -43,6 +43,10 @@ export class ProvisionsService {
return this.httpClient.delete(`${environment.apiVersionPath}/users/${userId}/provisions/${id}`);
}
updateProvisionAdmin(id, patch): Observable<any> {
return this.httpClient.put(`${environment.apiVersionPath}/provisions/${id}`, patch);
}
newDestroy(id, userId) : Observable<any> {
return this.httpClient.post(`${environment.apiVersionPath}/users/${userId}/provisions/${id}/destroy`, null);
}

View File

@@ -23,7 +23,7 @@
<tr>
<th>ProvisionID</th>
<th [mdbTableSort]="elements" sortBy="created" >Prov. Date <mdb-icon fas icon="sort"></mdb-icon></th>
<th [mdbTableSort]="elements" sortBy="user.displayName">User <mdb-icon fas icon="sort"></mdb-icon></th>
<th [mdbTableSort]="elements" sortBy="user.displayName">Owner <mdb-icon fas icon="sort"></mdb-icon></th>
<th [mdbTableSort]="elements" sortBy="scenario">Scenario (v)<mdb-icon fas icon="sort"></mdb-icon></th>
<th [mdbTableSort]="elements" sortBy="isExternalAccess">Ext. Access? <mdb-icon fas icon="sort"></mdb-icon></th>
<th [mdbTableSort]="elements" sortBy="statusVms">VMs (Running time)<mdb-icon fas icon="sort"></mdb-icon></th>
@@ -40,7 +40,9 @@
<a href (click)="showLogs($event, provision, 'provision')" class="lui-text-info">{{ provision._id }}</a>
</td>
<td (click)="openInfoModal(provision)" *ngIf="pagingIsDisabled || (i+1 >= mdbTablePagination.firstItemIndex && i < mdbTablePagination.lastItemIndex)">{{provision.created | date: 'MMM dd, yyyy - H:mm'}}</td>
<td (click)="openInfoModal(provision)" *ngIf="pagingIsDisabled || (i+1 >= mdbTablePagination.firstItemIndex && i < mdbTablePagination.lastItemIndex)" class="ell" title="{{provision.path}}" >{{provision.user.displayName}}</td>
<td *ngIf="pagingIsDisabled || (i+1 >= mdbTablePagination.firstItemIndex && i < mdbTablePagination.lastItemIndex)" class="ell" title="{{provision.path}}" >
<a href (click)="openOwnerChange($event, provision)" class="lui-text-info">{{provision.user.displayName}}</a>
</td>
<td (click)="openInfoModal(provision)"*ngIf="pagingIsDisabled || (i+1 >= mdbTablePagination.firstItemIndex && i < mdbTablePagination.lastItemIndex)">{{provision.scenario}} (v{{provision.scenarioVersion}})</td>
<td style="text-align: center;" (click)="openInfoModal(provision)"*ngIf="pagingIsDisabled || (i+1 >= mdbTablePagination.firstItemIndex && i < mdbTablePagination.lastItemIndex)"><mdb-icon *ngIf="provision.isExternalAccess" fas icon="check"></mdb-icon></td>
<td (click)="openInfoModal(provision)" *ngIf="pagingIsDisabled || (i+1 >= mdbTablePagination.firstItemIndex && i < mdbTablePagination.lastItemIndex)">

View File

@@ -1,12 +1,12 @@
import { Component, OnInit, ElementRef, HostListener, AfterViewInit, ViewChild, ChangeDetectorRef, Input, OnDestroy } from '@angular/core';
import { Component, OnInit, HostListener, AfterViewInit, ViewChild, ChangeDetectorRef, OnDestroy } from '@angular/core';
import { MdbTableDirective, MdbTablePaginationComponent, MDBModalService } from 'angular-bootstrap-md';
import { ProvisionsService } from '../services/provisions.service';
import { AlertService } from '../services/alert.service';
import { ModalInfoComponent } from '../modals/modalinfo.component';
import { ModalConfirmComponent } from '../modals/confirm.component';
import { Subscription, timer } from 'rxjs';
import { switchMap } from 'rxjs/operators';
import { ScenariosService } from '../services/scenarios.service';
import { ProvisionModalComponent } from '../modals/edit-provision.component';
@Component({
selector: 'table-provisions',
templateUrl: './table-provisions.component.html',
@@ -39,7 +39,6 @@ export class TableProvisionsAdminComponent implements OnInit, OnDestroy, AfterVi
this.mdbTablePagination.searchText = this.searchText;
}
selectedprov: any = null;
showInfo: boolean = false;
logShow: boolean = false;
@@ -59,10 +58,11 @@ export class TableProvisionsAdminComponent implements OnInit, OnDestroy, AfterVi
}
private _process(provisions) : void {
provisions.forEach(p=>{
provisions.forEach( p=> {
p.user.currentUserId = p.user._id;
p._scenario = this.scenarios.filter(s => s.name === p.scenario);
this._provisionsService.timeRunning(p);
});
} );
if ( this.elements.length === 0 ) {
this.elements = provisions;
} else {
@@ -93,7 +93,6 @@ export class TableProvisionsAdminComponent implements OnInit, OnDestroy, AfterVi
}
ngOnInit() {
var scenariosSub = this._scenariosService.getScenariosAll().subscribe( res => {
scenariosSub.unsubscribe();
this.scenarios = res.results;
@@ -126,6 +125,26 @@ export class TableProvisionsAdminComponent implements OnInit, OnDestroy, AfterVi
}
}
openOwnerChange($event, provision){
$event.preventDefault();
var modalRef = this.modalService.show(ProvisionModalComponent, {
class: 'modal-md modal-notify',
containerClass: '',
data: {
provision: provision
}
} );
var sub = modalRef.content.action.subscribe( (result: any) => {
sub.unsubscribe();
provision.user = result.user;
this._alertService.showAlert({
type: 'alert-primary',
text: `New owner ${provision.user.displayName} assigned to this provision`
});
});
}
searchItems() {
const prev = this.mdbTable.getDataSource();