Skip to content
Snippets Groups Projects
Commit 1dbee646 authored by Chris Hines's avatar Chris Hines
Browse files

new layout plus working on cloudcmd as an app

parent b5d82c9b
No related branches found
No related tags found
2 merge requests!21New css dev,!20Dev
Pipeline #7902 passed
......@@ -12,11 +12,11 @@
<mat-sidenav closed>
</mat-sidenav>
<mat-sidenav-content>
<div fxLayout="column" fxLayoutAlign="space-between stretch" style="height: 100%; width: 100%">
<div fxLayout="column" fxLayoutAlign="none" style="height: 100%; width: 100%">
<mat-toolbar color="primary">
<div fxLayout="row" style="width: 100%">
<mat-toolbar-row style="width: 100%">
<button mat-icon-button aria-label="toggle menu" (click)=toggleMenu()><mat-icon>menu</mat-icon></button>
<button mat-icon-button *ngIf="settingsService.useMenu$ | async" aria-label="toggle menu" (click)=toggleMenu()><mat-icon>menu</mat-icon></button>
<img src="assets/MASSIVElogoTransparent128x128.png" style="width: auto; height: 90%">
<span>Strudel2</span>
<span fxFlex></span>
......@@ -31,11 +31,35 @@
</div>
<button mat-menu-item routerLink="/settings"><mat-icon>settings</mat-icon>Settings</button>
<button *ngIf="(authService.loggedOutAuthZ | async).length > 0" mat-menu-item routerLink="/login"><mat-icon>exit_to_app</mat-icon>More services</button>
<div *ngFor="let id of (computeSitesService.appidentities | async)">
<button mat-button fxFlex
[routerLink]="['/launch',id.displayName()]"
routerLinkActive #rla="routerLinkActive"
[disabled]="rla.isActive"
[routerLinkActiveOptions]="{'exact': false}"
style="text-align: left"
>
<mat-icon></mat-icon>
<span
matBadge="{{ countErrors((id.systemalerts | async), (id.accountalerts | async)) }}"
[matBadgeHidden]= "countErrors((id.systemalerts | async), (id.accountalerts | async)) == 0"
matBadgePosition="above before"
matBadgeColor="warn"
matBadgeOverlap="false" matBadgeSize="small"
style="text-align: left; margin-left: 15px; margin-top: 10px">
<!--<span>-->
{{ id.displayName() }}
</span>
</button>
</div>
</mat-menu>
</mat-toolbar-row>
</div>
</mat-toolbar>
<div style="height: 100%">
<div>
<router-outlet></router-outlet>
</div>
</div>
......
......@@ -27,7 +27,7 @@ export class AppComponent {
constructor(private tesService: TesService,
private authService: AuthorisationService,
private computesitesService: ComputesitesService,
private computeSitesService: ComputesitesService,
private settingsService: SettingsService,
public snackBar: MatSnackBar) {
......@@ -38,7 +38,7 @@ export class AppComponent {
// this.testingAuth = false;
this.statusMsg = new BehaviorSubject<any>('');
this.tesService.setStatusMsg(this.statusMsg);
this.computesitesService.setStatusMsg(this.statusMsg);
this.computeSitesService.setStatusMsg(this.statusMsg);
this.authService.setStatusMsg(this.statusMsg);
this.statusMsg.subscribe(msg => this.displayMessage(msg));
this.settingsService.theme$.subscribe((v) => this.setTheme(v))
......
......@@ -14,6 +14,6 @@ export class Job {
public batch_host: string;
public identity: Identity;
public app: Strudelapp;
public appinst: string;
public appinst: any;
public connectionState: number;
}
<!--<div fxFlex style="flex: 1 1 0%; box-sizing: border-box">-->
<mat-sidenav-container style="height: 100%" autosize>
<mat-sidenav #idSideNav mode="side" [opened]="(settingsService.menuToggle$ | async) && (settingsService.useMenu$ | async)">
<div fxLayout="column" fxLayout="stretch" style="height: 100%">
<nav>
<mat-accordion style="width: 100%" [displayMode]="flat">
<div *ngFor="let id of (computeSitesService.appidentities | async)">
<!--<mat-expansion-panel (afterExpand)="selectId(id)" (closed)="selectId(id)" style="width: 100%">-->
<mat-expansion-panel style="width: 100%" [expanded]="(identity$ | async) === id">
<mat-expansion-panel-header>
<mat-panel-title>
<span fxFlex matBadge="{{ countErrors((id.systemalerts | async), (id.accountalerts | async)) }}"
[matBadgeHidden]= "countErrors((id.systemalerts | async), (id.accountalerts | async)) == 0"
matBadgePosition="above before"
matBadgeColor="warn"
matBadgeOverlap="false" matBadgeSize="small"
style="text-align: left; margin-left: 20px; margin-top: 10px" >
{{ id.displayName() }}
</span>
</mat-panel-title>
</mat-expansion-panel-header>
<mat-list style="width: 100%">
<mat-list-item>
<button mat-button style="width: 100%; text-align: left"
[routerLink]="['/launch',id.displayName(),'accountinfo']"
routerLinkActive #rla="routerLinkActive">
Account Info
</button>
</mat-list-item>
<app-strudelapplist [applist]=id.site.appCatalog [identity]="id" (appChange)="selectApp($event)" style="width: 100%"></app-strudelapplist>
</mat-list>
</mat-expansion-panel>
</div>
</mat-accordion>
</nav>
<div fxLayout="column" fxLayoutAlign="none" style="height: 100%">
<div *ngIf="!(settingsService.useMenu$ | async)">
<mat-divider></mat-divider>
<div *ngIf="(identity$ | async) !== null" style="width: 100%">
<nav mat-tab-nav-bar color=accent backgroundColor=primary>
<a mat-tab-link
[routerLink]="['/launch',identity$.value.displayName(),'accountinfo']"
routerLinkActive #rla="routerLinkActive"
[active]="rla.isActive">
Account Info
</a>
<a mat-tab-link
*ngFor="let app of (identity$.value.site.appCatalog | async)"
[routerLink]="['/launch',identity$.value.displayName(),app.name]"
routerLinkActive #rla="routerLinkActive"
[active]="rla.isActive">
{{ app.name }}
</a>
</nav>
</div>
</div>
<div fxFlex></div>
</mat-sidenav>
<mat-sidenav-content style="height: 100%">
<div *ngIf="!(settingsService.useMenu$ | async)" class=darker-theme>
<nav mat-tab-nav-bar color="accent" backgroundColor="primary">
<a mat-tab-link
*ngFor="let id of (computeSitesService.appidentities | async)"
[routerLink]="['/launch',id.displayName()]"
routerLinkActive #rla="routerLinkActive"
[routerLinkActiveOptions]="{'exact': false}"
[active]="rla.isActive">
<span fxFlex matBadge="{{ countErrors((id.systemalerts | async), (id.accountalerts | async)) }}"
[matBadgeHidden]= "countErrors((id.systemalerts | async), (id.accountalerts | async)) == 0"
matBadgePosition="above before"
matBadgeColor="warn"
matBadgeOverlap="false" matBadgeSize="small"
style="text-align: left; margin-left: 20px; margin-top: 10px" >
{{ id.displayName() }}
</span>
</a>
</nav>
<div *ngIf="(identity$ | async) !== null" style="width: 100%" class=darker-theme>
<nav mat-tab-nav-bar color=accent backgroundColor=primary>
<a mat-tab-link
[routerLink]="['/launch',identity$.value.displayName(),'accountinfo']"
routerLinkActive #rla="routerLinkActive"
[active]="rla.isActive">
Account Info
</a>
<a mat-tab-link
*ngFor="let app of (identity$.value.site.appCatalog | async)"
[routerLink]="['/launch',identity$.value.displayName(),app.name]"
routerLinkActive #rla="routerLinkActive"
[active]="rla.isActive">
{{ app.name }}
</a>
</nav>
</div>
</div>
<div fxLayout="column" fxLayoutAlign="space-between stretch" style="width: 100%; height: 100%" >
<!--<div *ngIf="identitySubject.value !== undefined && identitySubject.value !== null && appSubject.value === null" style="padding-left: 5%; padding-right: 5%; padding-top: 5%;">-->
<div *ngIf="(app$ | async) == null" style="padding-left: 5%; padding-right: 5%; padding-top: 5%;">
<div *ngIf="(app$ | async) == null" style="padding-left: 5%; padding-right: 5%; padding-top: 5%; overflow-y: scroll">
<app-accountinfo [identity$]="identity$" [app$]="app$"></app-accountinfo>
</div>
<div *ngIf="identity$.value !== undefined && identity$.value !== null && app$.value !== undefined && app$.value !== null" style="padding-left: 5%; padding-right: 5%; padding-top: 5%;">
<app-launch-dialog [identity]="identity$ | async" [appSubject]="app$"></app-launch-dialog>
<app-joblist [identitySubject]="identity$" [appSubject]="app$"></app-joblist>
<div style="height: 5%"></div>
<mat-divider ></mat-divider>
<div style="overflow-y: scroll">
<app-joblist [identitySubject]="identity$" [appSubject]="app$"></app-joblist>
</div>
</div>
</div>
</mat-sidenav-content>
</mat-sidenav-container>
......@@ -168,7 +168,7 @@ export class LauncherComponent implements OnInit {
refreshId() {
var ids: string;
var id: Identity;
if (this.identity$ !== null) {
if (this.identity$.value !== null) {
ids = this.identity$.value.site.name;
} else {
return
......@@ -195,7 +195,7 @@ export class LauncherComponent implements OnInit {
}
if (apps === null) {
apps = 'acocuntinfo';
apps = 'accountinfo';
}
if (id.site.appCatalog.value === undefined || id.site.appCatalog.value === null || (id.site.appCatalog.value).length == 0) {
id.site.appCatalog.pipe(filter((v) => v !== null && v.length > 0)).subscribe(() => this.updateIdApp(params));
......@@ -220,13 +220,23 @@ export class LauncherComponent implements OnInit {
}
if (this.computeSitesService.appidentities.value === null || this.computeSitesService.appidentities.value == []) {
console.error('no appidentities yet? call back latter');
this.computeSitesService.appidentities.pipe(filter((v) => v !== null)).subscribe(() => this.getId(v));
//this.computeSitesService.appidentities.pipe(filter((v) => v !== null)).subscribe(() => this.getId(v));
return null
}
for ( let id of this.computeSitesService.appidentities.value) {
if (v == id.displayName()) {
return id
} else {
console.log(v,'is not the same as ',id.displayName());
}
}
for ( let id of this.computeSitesService.appidentities.value) {
if (v == id.site.name) {
return id
} else {
console.log(v,'is not the same as ',id.displayName());
}
}
......@@ -242,6 +252,8 @@ export class LauncherComponent implements OnInit {
for ( let id of this.computeSitesService.appidentities.value) {
if (sitename == id.site.name) {
return id
} else {
console.log('sitename',sitename,'is not the same as ',id.site.name);
}
}
......
......@@ -12,7 +12,7 @@ export class SettingsService {
constructor() {
this.menuToggle$ = new BehaviorSubject<boolean>(true);
this.theme$ = new BehaviorSubject<string>('strudel-theme-light');
this.useMenu$ = new BehaviorSubject<boolean>(true);
this.useMenu$ = new BehaviorSubject<boolean>(false);
this.getTheme();
}
......
export class AppAction {
name: string;
paramscmd: string;
client: {cmd: string[], redir: string};
client: {cmd: string[], redir: string, usebasicauth: boolean};
states: string[]; // list of stats such as 'RUNNING' in which the action is valid. null||undefined if its always valid
}
export class Strudelapp {
......
......@@ -440,7 +440,7 @@ addUserHealth(identity,resp) {
//params.set('cmd',JSON.stringify(action.paramscmd));
let paramstr = params.toString();
this.http.post<string>(this.Base+'/createtunnel/'+username+'/'+loginhost+'/'+batchhost+'?'+paramstr, job.appinst, options)
.subscribe(() => { this.getAppUrl(job, action) } )
.subscribe(() => { this.getAppUrl(job, action) }, error => {this.handleTunnelError(job,error)} )
}
public getAppUrl(job: Job, action: AppAction) {
......@@ -454,7 +454,7 @@ addUserHealth(identity,resp) {
job.connectionState = 3;
this.http.get<string>(this.Base+'/appurl?'+paramstr,options)
.pipe(catchError(this.handleError))
.subscribe(resp => { job.connectionState = 0; this.openAppWindow(resp,job)});
.subscribe(resp => { job.connectionState = 0; this.openAppWindow(resp,job,action)});
}
......@@ -463,10 +463,23 @@ addUserHealth(identity,resp) {
this.getAppInstance(job, action);
}
public openAppWindow(url: any, job: Job) {
public openAppWindow(url: any, job: Job, action: AppAction) {
var re = /^https:\/\/([a-z0-9\.-]+)\/?/;
let twshost = this.twsproxy.replace(re,"$1");
console.log('in openappwindow url is ',url);
let windowloc = url.replace(/\{twsproxy\}/g,this.twsproxy).replace(/twshost/g,twshost);
console.log('window loc is',windowloc);
let user='chines';
let pass='pass';
var authwindow = null;
if (action.client.usebasicauth) {
let authwindowloc = windowloc.replace(/^https:\/\//,'https://'+job.appinst.username+':'+job.appinst.password+'@');
console.log('authwindowloc is',authwindowloc);
console.log(job.appinst);
authwindow = window.open(authwindowloc);
//windowloc = authwindowloc;
}
let appwindow = window.open(windowloc);
if (appwindow == null) {
......@@ -477,6 +490,9 @@ addUserHealth(identity,resp) {
return
}
this.openapps.push({'window':appwindow,'job':job})
if (authwindow !== null) {
authwindow.close();
}
}
......@@ -549,6 +565,16 @@ private httperror(errorstr: string) {
// }
private handleTunnelError(job: Job, error: any) {
job.connectionState=0;
if (error.stats == 500) {
this.statusMsg.next(error.error.message);
return;
}
this.statusMsg.next('Failed to create a tunnel. Please try again');
return;
}
private handleAppInstanceError(job: Job, error: any) {
console.log(error);
job.connectionState=0;
......
......@@ -147,5 +147,37 @@
"client": {"cmd": null, "redir": null },
"localbind": true,
"applist": null
},
{ "url": null,
"name": "File Explorer",
"startscript": "#!/bin/bash\n/usr/local/sv2/cloudcmd/start.sh\n ",
"actions": [
{
"name": "Connect",
"paramscmd": "/usr/local/sv2/dev/cloudcmd/params.py {jobid}",
"client": {"cmd": null, "redir": "", "usebasicauth": true },
"states": ["RUNNING"]
},
{
"name": "View log",
"paramscmd": "/usr/local/sv2/dev/desktop/logparams.py {jobid}",
"client": {"cmd": null, "redir": "index.html?token={token}" },
"states": ["RUNNING","Finished"]
},
{
"name": "View Usage",
"paramscmd": "/usr/local/sv2/dev/desktop/usageparams.py {jobid}",
"client": {"cmd": null, "redir": "index.html?token={token}" },
"states": ["Finished"]
},
{
"name": "Remove log",
"paramscmd": "/usr/local/sv2/dev/rmlog.py {jobid}",
"client": null,
"states": ["Finished"]
}
],
"localbind": true,
"applist": null
}
]
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment