diff --git a/src/app/connecting/connecting.component.css b/junk/connecting/connecting.component.css
similarity index 100%
rename from src/app/connecting/connecting.component.css
rename to junk/connecting/connecting.component.css
diff --git a/src/app/connecting/connecting.component.html b/junk/connecting/connecting.component.html
similarity index 100%
rename from src/app/connecting/connecting.component.html
rename to junk/connecting/connecting.component.html
diff --git a/src/app/connecting/connecting.component.spec.ts b/junk/connecting/connecting.component.spec.ts
similarity index 100%
rename from src/app/connecting/connecting.component.spec.ts
rename to junk/connecting/connecting.component.spec.ts
diff --git a/src/app/connecting/connecting.component.ts b/junk/connecting/connecting.component.ts
similarity index 100%
rename from src/app/connecting/connecting.component.ts
rename to junk/connecting/connecting.component.ts
diff --git a/src/app/tokenextractor/tokenextractor.component.css b/junk/sshauthz-callback/sshauthz-callback.component.css
similarity index 100%
rename from src/app/tokenextractor/tokenextractor.component.css
rename to junk/sshauthz-callback/sshauthz-callback.component.css
diff --git a/junk/sshauthz-callback/sshauthz-callback.component.html b/junk/sshauthz-callback/sshauthz-callback.component.html
new file mode 100644
index 0000000000000000000000000000000000000000..3b784e538a2cf87ac7f13bc4fd89e938795c02d6
--- /dev/null
+++ b/junk/sshauthz-callback/sshauthz-callback.component.html
@@ -0,0 +1,3 @@
+<p>
+  sshauthz-callback works!
+</p>
diff --git a/junk/sshauthz-callback/sshauthz-callback.component.spec.ts b/junk/sshauthz-callback/sshauthz-callback.component.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..7fe75f624fc3e281b472e2b40971f902483bf46d
--- /dev/null
+++ b/junk/sshauthz-callback/sshauthz-callback.component.spec.ts
@@ -0,0 +1,25 @@
+import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { SshauthzCallbackComponent } from './sshauthz-callback.component';
+
+describe('SshauthzCallbackComponent', () => {
+  let component: SshauthzCallbackComponent;
+  let fixture: ComponentFixture<SshauthzCallbackComponent>;
+
+  beforeEach(async(() => {
+    TestBed.configureTestingModule({
+      declarations: [ SshauthzCallbackComponent ]
+    })
+    .compileComponents();
+  }));
+
+  beforeEach(() => {
+    fixture = TestBed.createComponent(SshauthzCallbackComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});
diff --git a/junk/sshauthz-callback/sshauthz-callback.component.ts b/junk/sshauthz-callback/sshauthz-callback.component.ts
new file mode 100644
index 0000000000000000000000000000000000000000..8c604aa57bd66b14c7082dc50a9bdd7b68610d49
--- /dev/null
+++ b/junk/sshauthz-callback/sshauthz-callback.component.ts
@@ -0,0 +1,19 @@
+import { Component, OnInit } from '@angular/core';
+import { ActivatedRoute, Router, NavigationStart } from '@angular/router';
+
+
+@Component({
+  selector: 'app-sshauthz-callback',
+  templateUrl: './sshauthz-callback.component.html',
+  styleUrls: ['./sshauthz-callback.component.css']
+})
+export class SshauthzCallbackComponent implements OnInit {
+
+  constructor(private route: ActivatedRoute) { }
+
+  ngOnInit() {
+    console.log('sshauthz callback activated, posting route up the window chain');
+    window.parent.postMessage({'fragment': this.route.fragment},'*');
+  }
+
+}
diff --git a/junk/tokenextractor/tokenextractor.component.css b/junk/tokenextractor/tokenextractor.component.css
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/src/app/tokenextractor/tokenextractor.component.html b/junk/tokenextractor/tokenextractor.component.html
similarity index 100%
rename from src/app/tokenextractor/tokenextractor.component.html
rename to junk/tokenextractor/tokenextractor.component.html
diff --git a/src/app/tokenextractor/tokenextractor.component.spec.ts b/junk/tokenextractor/tokenextractor.component.spec.ts
similarity index 100%
rename from src/app/tokenextractor/tokenextractor.component.spec.ts
rename to junk/tokenextractor/tokenextractor.component.spec.ts
diff --git a/src/app/tokenextractor/tokenextractor.component.ts b/junk/tokenextractor/tokenextractor.component.ts
similarity index 100%
rename from src/app/tokenextractor/tokenextractor.component.ts
rename to junk/tokenextractor/tokenextractor.component.ts
diff --git a/src/.styles.css.swp b/src/.styles.css.swp
new file mode 100644
index 0000000000000000000000000000000000000000..382dcb9ef5c2d977ee4ecd47f09ae7b710ddc9c8
Binary files /dev/null and b/src/.styles.css.swp differ
diff --git a/src/app/app-routing.module.ts b/src/app/app-routing.module.ts
index bb6fdc4b5e01f34b1d486a82425cabb1fd799355..d6b0cd53c3316c4c95b59119e28885eb5411f9ba 100644
--- a/src/app/app-routing.module.ts
+++ b/src/app/app-routing.module.ts
@@ -2,7 +2,6 @@ import { NgModule } from '@angular/core';
 import { RouterModule, Routes } from '@angular/router';
 import { LauncherComponent } from './launcher/launcher.component';
 import { KeygenComponent } from './keygen/keygen.component';
-import { ConnectingComponent } from './connecting/connecting.component';
 import { TransferComponent } from './transfer/transfer.component';
 import { ShareconnectComponent } from './shareconnect/shareconnect.component';
 
@@ -16,7 +15,6 @@ const routes: Routes = [
   { path: 'finishlaunch', component: LauncherComponent},
   { path: 'cancellaunch', component: LauncherComponent},
   { path: 'sshauthz_callback', component: KeygenComponent},
-  { path: 'connecting', component: ConnectingComponent },
   { path: 'transfer', component: TransferComponent },
   { path: 'shareconnect', component: ShareconnectComponent }
 
diff --git a/src/app/app.module.ts b/src/app/app.module.ts
index 4c53c93acf9bcac7cb9ff1aa2d20b1aa31e321cd..f7713c32e58258408db5d9f6a8ef8397b03b13e5 100644
--- a/src/app/app.module.ts
+++ b/src/app/app.module.ts
@@ -34,19 +34,18 @@ import { JobComponent } from './job/job.component';
 // import { SiteselectionComponent } from './siteselection/siteselection.component';
 // import { TeserrorsComponent } from './teserrors/teserrors.component';
 import { AppRoutingModule } from './/app-routing.module';
-import { TokenextractorComponent } from './tokenextractor/tokenextractor.component';
 // import { LogindialogComponent } from './logindialog/logindialog.component';
 import { LogoutdialogComponent } from './logoutdialog/logoutdialog.component';
 // import { LaunchdialogComponent } from './launchdialog/launchdialog.component';
 
-import { ModaldialogComponent } from './modaldialog/modaldialog.component';
 import { MatSidenavModule, MatExpansionModule, MatIconModule } from '@angular/material';
 import { StrudelapplistComponent } from './strudelapplist/strudelapplist.component';
 import { KeygenComponent } from './keygen/keygen.component';
-import { ConnectingComponent } from './connecting/connecting.component';
 import { TransferComponent } from './transfer/transfer.component';
 import { Sv2SideNavComponent } from './sv2-side-nav/sv2-side-nav.component';
 import { ShareconnectComponent } from './shareconnect/shareconnect.component';
+import { LaunchDialogComponent } from './launch-dialog/launch-dialog.component';
+import { ModaldialogComponent } from './modaldialog/modaldialog.component'
 // import { FileExplorerModule } from './file-explorer/file-explorer.module';
 
 
@@ -60,16 +59,14 @@ import { ShareconnectComponent } from './shareconnect/shareconnect.component';
     JobComponent,
     // SiteselectionComponent,
     // TeserrorsComponent,
-    TokenextractorComponent,
     LogoutdialogComponent,
-    ModaldialogComponent,
     // LaunchdialogComponent,
     StrudelapplistComponent,
     KeygenComponent,
-    ConnectingComponent,
     TransferComponent,
     Sv2SideNavComponent,
-    ShareconnectComponent
+    ShareconnectComponent,
+    LaunchDialogComponent,
   ],
   imports: [
   BrowserModule,
@@ -98,7 +95,7 @@ import { ShareconnectComponent } from './shareconnect/shareconnect.component';
 
 
   ],
-  entryComponents: [ ModaldialogComponent, LogoutdialogComponent,  ],
+  entryComponents: [ LogoutdialogComponent, LaunchDialogComponent ],
   providers: [ StrudelappsService, ComputesitesService, TesService, SubmitAppService, MatDialog, AuthorisationService],
   bootstrap: [AppComponent]
 })
diff --git a/src/app/authorisation.service.ts b/src/app/authorisation.service.ts
index 0047aa7d65e6b5558fbd15fb2f08165ece7252e4..c85b7d44ce487295a4762226dad96339ba17df7e 100644
--- a/src/app/authorisation.service.ts
+++ b/src/app/authorisation.service.ts
@@ -126,7 +126,7 @@ export class AuthorisationService {
 
     console.log('posting to getcert',this.backendURI);
     this.http.post<any>(this.backendURI+'/getcert',data, options)
-                       // .pipe(catchError(this.handleError([])))
+                       .pipe(catchError(this.handleError([])))
                        .subscribe(resp => this.makeKeyCert(newkeypair.private, resp, token.sshauthzservice),
                                   error => this.httperrorLogout(error,token.sshauthzservice));
    console.log('getcert complete');
@@ -174,6 +174,8 @@ public getKeys(id?: Identity) {
    if (error.status == 0) {
      this.statusMsg.next("A network error occured. Are you connected to the internet?")
    }
+   this.statusMsg.next("Error querying ssh agent");
+   console.log(error);
  }
 
  public updateAgentContents() {
@@ -182,7 +184,7 @@ public getKeys(id?: Identity) {
    let options = { headers: headers, withCredentials: true};
    var anyvar: any;
    this.http.get<any>(this.backendURI+'/sshagent',options)
-                     // .pipe(catchError(this.handleError(anyvar)))
+                     .pipe(catchError(this.handleError(anyvar)))
                      .subscribe(resp => { console.log('sshagent returned',resp); this.agentContents.next(resp); this.statusMsg.next("") },
                                 error => this.querySshAgentError(error));
                      // .subscribe(resp => this.computeSitesService.updateIdentities(resp),
@@ -265,10 +267,12 @@ public getKeys(id?: Identity) {
  //   }
 
  private httperror(error: any) {
+   console.log('authorsation service got an error');
    this.statusMsg.next(error);
    console.log(error);
  }
  private httperrorLogout(error: any,sshauthzservice: SshAuthzServer) {
+   console.log('authorsation service got an error');
    this.statusMsg.next(error);
    console.log(error);
    if (!(sshauthzservice.logout === null)) {
@@ -279,6 +283,7 @@ public getKeys(id?: Identity) {
  private handleError<T> (result?: T) {
    return (error: any): Observable<T> => {
      console.log(error)
+     console.log('handleError activated')
      if (error.status == 500) {
        return throwError("The backend server encountered and error. Please try again in a few minutes")
      }
diff --git a/src/app/computesite.ts b/src/app/computesite.ts
index f5d81fcf58386347c3b84e751ec1194d20b9efbd..e543e6f80a53d97609d38b6d7ebe16ab075538f4 100644
--- a/src/app/computesite.ts
+++ b/src/app/computesite.ts
@@ -15,6 +15,8 @@ export class Computesite {
   appCatalog: BehaviorSubject<Strudelapp[]>;
   appCatalogUri: string;
   internalfirewall: boolean; // Does a firewall exist within the site necessitating an extra level of ssh tunnel
+  cancelcmd: string;
+  statcmd: string;
 
 }
 
diff --git a/src/app/computesites.service.ts b/src/app/computesites.service.ts
index a8d0dcd58b751e55ef8fd0fb50626c7e98267188..d45f7334cc0e0f435ee9d502811cfe037eb4bdb1 100644
--- a/src/app/computesites.service.ts
+++ b/src/app/computesites.service.ts
@@ -38,6 +38,7 @@ export class ComputesitesService {
 
   getStrudelApps(computesites: Computesite[]) {
     for (let s of computesites) {
+      console.log('retrieving apps');
       let headers = new HttpHeaders();
       let options = { headers: headers, withCredentials: false};
       if (s.appCatalogUri !== null) {
diff --git a/src/app/joblist/joblist.component.css b/src/app/joblist/joblist.component.css
index 0c6efabb438ac61b93bb5959301e4e760b7fe8d8..a318c820cfdcef458a98ae3dae81ff3cff34d373 100644
--- a/src/app/joblist/joblist.component.css
+++ b/src/app/joblist/joblist.component.css
@@ -1,7 +1,10 @@
 html, body {
   height: 100%;
+  margin: 0;
+  box-sizing: border-box;
 }
 
+
 .wrapper {
   /* display: flex;
   flex-direction: column; */
diff --git a/src/app/joblist/joblist.component.html b/src/app/joblist/joblist.component.html
index be296f316f457dc85dac60e83b948af72642ec42..aaa183cd5bcf1ef6ba50620c7969f614795325d5 100644
--- a/src/app/joblist/joblist.component.html
+++ b/src/app/joblist/joblist.component.html
@@ -4,7 +4,7 @@
   </mat-card>
 </div>
 <div *ngFor="let id of identities"> -->
-<mat-card style="width: 100%">
+<mat-card style="width: 100%" style="box-sizing: border-box;">
     <div *ngIf="identity == undefined" >
       Select your username an compute site on the left to see running jobs or start new jobs.
     </div>
@@ -15,3 +15,5 @@
       </div>
     </div>
 </mat-card>
+
+<!-- <iframe src="http://localhost:5200" frameborder="0" style="width: 100%"></iframe> -->
diff --git a/src/app/joblist/joblist.component.ts b/src/app/joblist/joblist.component.ts
index 883fec0bb149d8430bde43da6f0d889a0b500418..aba90ea2d5138fce8b8ff8dd62f02654a32fc555 100644
--- a/src/app/joblist/joblist.component.ts
+++ b/src/app/joblist/joblist.component.ts
@@ -1,9 +1,10 @@
-import { Component, OnInit, Input } from '@angular/core';
+import { Component, OnInit, Input, OnDestroy } from '@angular/core';
 import {TesService} from '../tes.service';
 import { Job } from '../job';
 import { Observable } from 'rxjs/Observable';
 import { Subscription, interval } from 'rxjs';
 import { Identity } from '../identity';
+import { Renderer2} from '@angular/core';
 
 
 
@@ -21,9 +22,11 @@ export class JoblistComponent implements OnInit {
   // private jobsSubscription: Subscription;
   // private idSubscription: any;
   private timerSub: Subscription;
+  private iframeListener: any;
+  private batchListen: any;
 
 
-  constructor(private tesService: TesService,) {
+  constructor(private tesService: TesService, private renderer: Renderer2) {
 }
 
   ngOnInit() {
@@ -33,12 +36,34 @@ export class JoblistComponent implements OnInit {
     }
     this.timerSub = interval(5000).subscribe(() => this.refreshJobs())
     // this.jobsSubscription = this.tesService.joblist.subscribe(jobs => this.updateJobs(jobs));
+    // this.batchListen = this.renderer.listen('window','message',event => this.receiveBatchCmd(event));
+    // window.addEventListener('message',this.receiveBatchCmd);
+
+  }
+
+  // receiveBatchCmd(event) {
+  //   // window.alert("I recieved the batchcmd message");
+  //   console.log("I received a batch cmd");
+  //   console.log(event);
+  // }
+  //
+  // customProcessor(event) {
+  //   // window.alert("I recieved the batchcmd message");
+  //   console.log("I received a batch cmd via customProcessor");
+  //   console.log(event);
+  // }
+
+  mouseOverHandel(event) {
+    console.log(
+      'recieved mouse over'
+    );
   }
 
   public ngOnDestroy(): void {
       if (this.timerSub) {
           this.timerSub.unsubscribe();
       }
+      this.batchListen();
 
   }
   //
@@ -49,7 +74,6 @@ export class JoblistComponent implements OnInit {
   // }
 
   public refreshJobs(): void {
-    console.log('hit refresh with identitiy', this.identity);
     this.tesService.getJobs(this.identity);
   }
 }
diff --git a/src/app/launch-dialog/launch-dialog.component.css b/src/app/launch-dialog/launch-dialog.component.css
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/src/app/launch-dialog/launch-dialog.component.html b/src/app/launch-dialog/launch-dialog.component.html
new file mode 100644
index 0000000000000000000000000000000000000000..7d6690ac3b92bc26d929b9df57899ed66f06036f
--- /dev/null
+++ b/src/app/launch-dialog/launch-dialog.component.html
@@ -0,0 +1,30 @@
+<!--
+<div gdAreas="appconfig  appconfig |
+                batchconfig batchconfig |
+                cancel launch"
+     gdRows="auto auto auto">
+<div gdArea="appconfig">
+  <iframe></iframe>
+</div>
+<div gdArea="batchconfig" style="width: 100%">
+  <iframe></iframe>
+</div>
+<div gdArea="launch">
+  <button mat-button (click)="launch()" enabled="submitAppService.readyToLaunch | async">Launch</button>
+</div>
+<div gdArea="cancel">
+  <button mat-button (click)="cancel()" >Cancel</button>
+</div>
+</div> -->
+
+<div fxLayout="column" fxLayoutAlign="space-between stretch" style="height: 100%; width: 100%">
+    <!-- <div fxFlex style="background: blue">app config</div> -->
+    <iframe *ngIf="appconfigurl != null"  fxGrow=10 fxFlex [src]="appconfigsafeurl" style="border: none"></iframe>
+    <iframe *ngIf="appconfigurl != null" [src]="batchcmdsafeurl" style="height: 1px; min-height: 0px; border: none"></iframe>
+
+    <iframe *ngIf="appconfigurl == null" fxFlex [src]="batchcmdsafeurl" fxGrow=1 style="border: none"></iframe>
+
+    <div fxLayout="row" fxLayoutAlign="space-around">
+      <button mat-button (click)="cancel()">Cancel</button><button mat-button (click)="launch()" #launchbtn>Launch</button>
+    </div>
+</div>
diff --git a/src/app/launch-dialog/launch-dialog.component.spec.ts b/src/app/launch-dialog/launch-dialog.component.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..442582a0fd098001425f69b3c80d968e3b99b771
--- /dev/null
+++ b/src/app/launch-dialog/launch-dialog.component.spec.ts
@@ -0,0 +1,25 @@
+import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { LaunchDialogComponent } from './launch-dialog.component';
+
+describe('LaunchDialogComponent', () => {
+  let component: LaunchDialogComponent;
+  let fixture: ComponentFixture<LaunchDialogComponent>;
+
+  beforeEach(async(() => {
+    TestBed.configureTestingModule({
+      declarations: [ LaunchDialogComponent ]
+    })
+    .compileComponents();
+  }));
+
+  beforeEach(() => {
+    fixture = TestBed.createComponent(LaunchDialogComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});
diff --git a/src/app/launch-dialog/launch-dialog.component.ts b/src/app/launch-dialog/launch-dialog.component.ts
new file mode 100644
index 0000000000000000000000000000000000000000..ae4c5ecbfedc2e8c06ad96f1270274a80cd5422a
--- /dev/null
+++ b/src/app/launch-dialog/launch-dialog.component.ts
@@ -0,0 +1,95 @@
+import { Component, OnInit, AfterViewInit, ViewChild, ElementRef, Inject } from '@angular/core';
+import { DomSanitizer} from '@angular/platform-browser';
+import { Renderer2 } from '@angular/core';
+import { MatDialogRef,MAT_DIALOG_DATA } from '@angular/material';
+import { SubmitAppService } from '../submit-app.service';
+import { timer } from 'rxjs';
+
+
+@Component({
+  selector: 'app-launch-dialog',
+  templateUrl: './launch-dialog.component.html',
+  styleUrls: ['./launch-dialog.component.css']
+})
+export class LaunchDialogComponent implements OnInit {
+  batchcmdurl: string;
+  appconfigurl: string;
+  batchcmdsafeurl: any;
+  appconfigsafeurl: any;
+  rmListen: any;
+  @ViewChild('launchbtn', { read: ElementRef })
+  launchbtn: ElementRef;
+  setFocus: Boolean;
+
+  constructor( public dialogRef: MatDialogRef<LaunchDialogComponent>,
+               private domSanitizer: DomSanitizer,
+               private renderer: Renderer2,
+               private submitAppService: SubmitAppService) {
+      this.batchcmdurl = this.submitAppService.identity.value.site.url+"/"+this.submitAppService.app.value.name;
+      this.batchcmdsafeurl = this.domSanitizer.bypassSecurityTrustResourceUrl(this.batchcmdurl);
+      this.appconfigurl = this.submitAppService.app.value.url;
+      if (!(this.appconfigurl == null)) {
+       this.appconfigsafeurl = this.domSanitizer.bypassSecurityTrustResourceUrl(this.appconfigurl);
+      }
+      console.log('creating the laucnch dialog with urls',this.batchcmdsafeurl,this.appconfigsafeurl);
+      this.setFocus = false;
+      this.submitAppService.readyToLaunch.subscribe((ready) => this.becomesReady(ready))
+
+  }
+
+  ngOnInit() {
+    this.rmListen = this.renderer.listen('window','message',(event) => this.receiveMessage(event));
+  }
+
+  ngAfterViewInit() {
+    console.log('in AfterViewInit, disabling the button');
+    this.launchbtn.nativeElement._disabled = true;
+  }
+      
+
+  cancel() {
+    console.log('cause app cancel');
+    this.submitAppService.submitcmd.next(null);
+    this.submitAppService.appData.next(null)
+    this.dialogRef.close()
+  }
+
+  launch() {
+    console.log('cause app submission');
+    this.dialogRef.close();
+    this.submitAppService.launch();
+  }
+
+  
+  ngOnDestroy() {
+    console.log('dialog in onDestroy');
+    this.rmListen();
+  }
+
+
+
+
+
+  becomesReady(ready) {
+      
+      if (ready && !(this.setFocus)) {
+        console.log('reenabling the launch button');
+        this.launchbtn.nativeElement._disabled = false;
+        this.launchbtn.nativeElement.focus();
+        this.setFocus = true;
+      } else {
+        this.launchbtn.nativeElement._disabled = true;
+          console.log('launch is still disabled');
+      }
+  }
+
+
+  receiveMessage(event) {
+      if (event.data['batchcmd'] !== undefined)  {
+        this.submitAppService.submitcmd.next(event.data['batchcmd']);
+      }
+      if (event.data['appData'] !== undefined)  {
+        this.submitAppService.appData.next(event.data['appData']);
+      }
+  }
+}
diff --git a/src/app/launcher/launcher.component.ts b/src/app/launcher/launcher.component.ts
index dea07c425d78242f9e6aa785acd678c1290d4c1e..dc8d65a52dc2fd777ba7949e82762db9db048a81 100644
--- a/src/app/launcher/launcher.component.ts
+++ b/src/app/launcher/launcher.component.ts
@@ -14,13 +14,11 @@ import { AuthorisationService } from '../authorisation.service';
 import { Identity } from '../identity';
 import { Computesite } from '../computesite';
 import { LogoutdialogComponent } from '../logoutdialog/logoutdialog.component';
-// import { LogindialogComponent } from '../logindialog/logindialog.component';
-// import { LaunchdialogComponent } from '../launchdialog/launchdialog.component';
-import { BatchInterface} from '../batchinterface';
+
 import { SshAuthzServer } from '../identity';
 import { ComputesitesService } from '../computesites.service';
-import { Router } from '@angular/router';
-import {BehaviorSubject} from 'rxjs/BehaviorSubject';
+import { BehaviorSubject } from 'rxjs/BehaviorSubject';
+
 
 
 
@@ -48,86 +46,34 @@ export class LauncherComponent implements OnInit {
                 private tesService: TesService,
                 private authService: AuthorisationService,
                 public computeSitesService: ComputesitesService,
-                private router: Router) {
-    authService.SshAuthzServers.subscribe(o => {this.sshauthzservers = o});
-    this.launchwindowWatcher = null;
+                ) {
+    this.authService.SshAuthzServers.subscribe(o => {this.sshauthzservers = o});
     this.identitySubject = new BehaviorSubject(undefined);
   }
 
   ngOnInit() {
     this.strudelapps = [];
-    // this.identities = [];
-    // this.computeSitesService.identities.subscribe(identities => this.updateIdentities(identities)
-    // this.tesService.identities.subscribe(identities => this.updateIdentities(identities));
-    // setTimeout( () => { this.tesService.identities.subscribe(identities => this.updateIdentities(identities)); });
     setTimeout( () => this.authService.updateAgentContents() )
   }
 
-  // compareFn = (o1, o2) => {
-  //   // Funny "=>" function syntax gives me access to "this" as LauncherComponent
-  //   // otherwise "this" would be set to the mat-select object.
-  //   if (o2 === undefined) {
-  //
-  //     if (o1 === this.identity) {
-  //       return true;
-  //     }
-  //   }
-  //   if (o1 === o2) {
-  //     return true;
-  //   }
-  //   return false;
-  // }
-
-  updateIdentities(identities) {
-    this.identities = identities;
-    console.log(this.identities);
-    if (this.identities.length > 0) {
-      this.identity = this.identities[0];
-      // this.identity.site.appCatalog.subscribe(resp => this.updateApps());
-      // this.updateApps();
-    } else {
-      this.strudelapps = [];
-    }
-  }
+  //updateIdentities(identities) {
+  //  this.identities = identities;
+  //  console.log(this.identities);
+  //  if (this.identities.length > 0) {
+  //    this.identity = this.identities[0];
 
-login (sshauthzserver) {
-  this.authService.login(sshauthzserver);
-}
+  //  } else {
+  //    this.strudelapps = [];
+  //  }
+  //}
 
-navTransfer() {
-  this.router.navigate(['transfer'])
-}
-
-logout() {
-    let dialogRef = this.dialog.open(LogoutdialogComponent, {
-      width: '250px',
-      height: '400px',
-    });
-}
-
-  private buildParams(app: Strudelapp, identity: Identity, redirect): string {
-    let params = new URLSearchParams();
-    let id = identity.copy_skip_catalog();
-    id.site.appCatalog = null;
-
-    params.set('app',JSON.stringify(app));
-    params.set('identity',JSON.stringify(id));
-    params.set('redirect',redirect);
-    return params.toString();
-  }
 
 
 
   selectId(id: Identity) {
     this.identity=id;
-    console.log('set identity subject');
     this.identitySubject.next(id);
     this.tesService.getJobs(id);
   }
 
-
-  configureResources() {
-    let configwindow = window.open(this.identity.site.url+'configure/'+this.app.name);
-  }
-
 }
diff --git a/src/app/strudelapplist/strudelapplist.component.html b/src/app/strudelapplist/strudelapplist.component.html
index 36b909819109c7fd84fb09094869dc33edca0c66..836982dceeb8d721a07e84c221ab04ea09646ae1 100644
--- a/src/app/strudelapplist/strudelapplist.component.html
+++ b/src/app/strudelapplist/strudelapplist.component.html
@@ -1,6 +1,6 @@
 <div *ngFor="let app of applist | async">
   <div *ngIf="app.startscript != null">
-    <button mat-button (click)=openLaunchWindow(app)>{{ app.name }}</button>
+    <button mat-button (click)=configure(app)>{{ app.name }}</button>
   </div>
   <!-- The following allows for a nested set of apps -->
   <div *ngIf="app.applist != null">
diff --git a/src/app/strudelapplist/strudelapplist.component.ts b/src/app/strudelapplist/strudelapplist.component.ts
index 33bf71954102f28a2fbb9e106db74e13b836df8a..d2add9f2b1faac2edf9e414ccd2e7cf1dfc0e941 100644
--- a/src/app/strudelapplist/strudelapplist.component.ts
+++ b/src/app/strudelapplist/strudelapplist.component.ts
@@ -7,7 +7,9 @@ import { Identity } from '../identity';
 import { repeat } from 'rxjs/operators';
 import { BatchInterface} from '../batchinterface';
 import { timer } from 'rxjs/observable/timer';
-
+import { LaunchDialogComponent } from '../launch-dialog/launch-dialog.component';
+import { MatDialog, MatDialogRef, MAT_DIALOG_DATA, MatDialogModule } from '@angular/material';
+import { DomSanitizer} from '@angular/platform-browser';
 
 
 
@@ -22,16 +24,33 @@ export class StrudelapplistComponent implements OnInit {
   @Input() identity: Identity;
 
 
-  constructor(private submitAppService: SubmitAppService ) {
+  constructor(private submitAppService: SubmitAppService, public dialog: MatDialog,
+  private domSanitizer: DomSanitizer) {
   }
 
   ngOnInit() {
   }
 
-  openLaunchWindow(app, Strudelapp) {
-    console.log('strudel applist openLaunchWindow');
-    console.log(this.submitAppService);
-    this.submitAppService.launchApp(app,this.identity);
+  // openLaunchWindow(app: Strudelapp) {
+  //   this.submitAppService.launchAppModal(app,this.identity);
+  // }
+
+  configure(app: Strudelapp) {
+    // this.submitAppService.configApp.next({app: app, this.identity});
+    this.submitAppService.app.next(app);
+    this.submitAppService.identity.next(this.identity);
+    if (app.url == null) {
+      let dialogRef = this.dialog.open(LaunchDialogComponent, {
+          width: '40vw',
+          height: '60vh'
+          })
+        } else {
+          let dialogRef = this.dialog.open(LaunchDialogComponent, {
+              width: '95vw',
+              height: '95vh'
+              })
+        }
+    // this.route.navigate['configlaunch'];
   }
 
 
diff --git a/src/app/submit-app.service.ts b/src/app/submit-app.service.ts
index 0efaccb418b9a9a1ac1b7addd8b9112d0b1ca767..ef081e036bf874300a6b3ad5d91e5afd3e11518f 100644
--- a/src/app/submit-app.service.ts
+++ b/src/app/submit-app.service.ts
@@ -7,6 +7,11 @@ import {Strudelapp} from './strudelapp';
 import { TesService } from './tes.service';
 import { Identity } from './identity';
 import { BatchInterface} from './batchinterface';
+import { LaunchDialogComponent } from './launch-dialog/launch-dialog.component';
+import { MatDialog, MatDialogRef, MAT_DIALOG_DATA, MatDialogModule } from '@angular/material';
+import { DomSanitizer} from '@angular/platform-browser';
+import{ BehaviorSubject } from 'rxjs';
+
 
 // This service is responsible for starting applications
 // Along the way it opens new windows/tabs to
@@ -25,134 +30,191 @@ query string
 export class SubmitAppService {
   private configwindow: any;
   private appparams: string;
-  private submitcmd: string;
+  // private submitcmd: string;
 
 
   private windowWatcher: any;
   private watchingForSubmit: boolean;
-
-
-  constructor(private tesService: TesService) {
-    this.appparams = null;
-    this.submitcmd = null;
-    this.watchingForSubmit = false;
+  public configApp: BehaviorSubject<any>;
+  public appData: BehaviorSubject<any>;
+  public submitcmd: BehaviorSubject<string>;
+  public identity: BehaviorSubject<Identity>;
+  public app: BehaviorSubject<Strudelapp>;
+  public readyToLaunch: BehaviorSubject<Boolean>;
+
+
+  constructor(private tesService: TesService,
+              public dialog: MatDialog,
+              private domSanitizer: DomSanitizer,
+              ) {
+    // this.appparams = null;
+    // // this.submitcmd = null;
+    // this.watchingForSubmit = false;
+    this.app = new BehaviorSubject(null);
+    this.appData = new BehaviorSubject(null);
+    this.submitcmd = new BehaviorSubject(null);
+    this.identity = new BehaviorSubject(null);
+    this.readyToLaunch = new BehaviorSubject(false);
+    this.app.subscribe(() => this.clearInfo());
+    this.identity.subscribe(() => this.clearInfo());
+    this.submitcmd.subscribe(() => this.canILaunch());
+    this.appData.subscribe(()=> this.canILaunch());
   }
 
-  public launchApp(app: Strudelapp, identity: Identity) {
-    if (!(app.url === null) && !(app.url =='')) {
-      this.openWindow(app,app.url,identity);
+  launch() {
+    let bi = new BatchInterface();
+    bi.submitcmd = this.submitcmd.value;
+    console.log('in launch,',bi);
+    console.log(this.appData.value);
+    if (this.appData.value != null){ 
+        //      let appparams = JSON.stringify(this.appData.value);
+      let appparams = this.appData.value;
+      this.tesService.submit(this.app.value,this.identity.value,bi,appparams);
     } else {
-      this.appparams = JSON.stringify([]);
-      let redirect = window.location.toString();
-      redirect = redirect.replace(/launch/,'finishlaunch');
-      let paramstr = this.buildParams(app,identity,redirect);
-      let windowloc = identity.site.url+'configure/'+app.name+"?"+paramstr;
-      this.openWindow(app,windowloc,identity);
+        this.tesService.submit(this.app.value,this.identity.value,bi);
     }
-    // this.openLaunchWindow(app, identitiy);
   }
 
-
-  public openWindow(app: any,url: string, identity: Identity) {
-    console.log('in openLaunchDialog');
-    console.log(app);
-
-    let headers = new HttpHeaders();
-    let options = { headers: headers, withCredentials: true};
-    let redirect = window.location.toString();
-    redirect = redirect.replace(/launch/,'finishlaunch');
-    let paramstr = this.buildParams(app,identity,redirect);
-    this.configwindow = window.open(url);
-    if (!(this.windowWatcher === null) && !(this.windowWatcher === undefined)) {
-      this.windowWatcher.unsubscribe()
-    }
-    this.windowWatcher = timer(500).pipe(repeat()).subscribe(() => this.watchWindow(this.configwindow, identity, app,redirect));
-    this.configwindow.focus();
-
+  clearInfo() {
+      this.appData.next(null);
+      this.submitcmd.next(null);
   }
 
-  public watchWindow(configwindow, id, app, redirect) {
-    // Watch another window for url changes
-    // if the url changes to include the submit parameters, submit the job
-    // if the url changes to include appparameters, save them and open
-    // a new window to get the submit parameters
-    var location: string;
-    try {
-      location = configwindow.location.href;
-      // if we can read the location and it contains a submitcmd arameter save it
-      // and close the window
-      if (configwindow.closed) { // if the window is closed without our help, presumable the user wanted to cancel the launch
-        return
-      }
-      let match = location.match(/submitcmd\=([^&]+)(&|$)/);
-      if (match) {
-          this.submitcmd = decodeURIComponent(match[1]);
-          if (!(configwindow.closed)) {
-            configwindow.close()
-          }
-          this.windowWatcher.unsubscribe();
-      }
-      // if we can read the location and it contains an appparams parameter, save it
-      // and close the window
-      match = location.match(/appparams\=([^&]+)(&|$)/);
-      if (match) {
-          this.appparams = decodeURIComponent(match[1]);
-          if (!(configwindow.closed)) {
-            configwindow.close()
-          }
-          this.windowWatcher.unsubscribe();
-      }
-      // if we can read the location and it contains the redireURI, close the window
-      let idx = location.indexOf(redirect);
-      if (idx == 0) {
-        configwindow.close();
-      }
-    } catch {
-      location = null;
-    }
-    if (configwindow.closed) {
-      this.windowWatcher.unsubscribe();
-      // if the window is closed, see if we need to override appparams from localStorage
-      try {
-        let appparams = localStorage.getItem('appparams');
-        if (appparams != null) {
-          localStorage.removeItem('appparams');
-          this.appparams = appparams;
-        }
-      } catch {
-      }
-      // if the window is closed and we have an appparams value but not a submitcmd
-      // open a new window to get the submitcmd
-
-
-      if (!(this.appparams === null) && (this.submitcmd === null)) {
-        let paramstr = this.buildParams(app,id,redirect);
-        let windowloc = id.site.url+'configure/'+app.name+"?"+paramstr;
-        this.windowWatcher.unsubscribe();
-        this.openWindow(app,windowloc,id);
-      }
-      // if the window is closed and we have an appparams valud AND a submitcmd
-      // submit
-      if (!(this.appparams == null) && !(this.submitcmd == null )) {
-
-        let bi = new BatchInterface();
-        bi.submitcmd = this.submitcmd;
-        this.tesService.submit(app,id,bi,this.appparams);
-        this.appparams = null;
-        this.submitcmd = null;
-      }
+  canILaunch() {
+    console.log('in submitAppService, evaluatin can I launch');
+    if (this.submitcmd.value != null) {
+        if (this.app.value.url == null || this.appData.value != null ) {
+            this.readyToLaunch.next(true);
+            return;
+        } 
     }
+    this.readyToLaunch.next(false);
   }
 
-  private buildParams(app: Strudelapp, identity: Identity, redirect): string {
-    let params = new URLSearchParams();
-    let id = identity.copy_skip_catalog();
-    id.site.appCatalog = null;
-
-    params.set('app',JSON.stringify(app));
-    params.set('identity',JSON.stringify(id));
-    params.set('redirect',redirect);
-    return params.toString();
-  }
+  // public launchAppModal(app: Strudelapp, identity: Identity) {
+  //   let dialogRef = this.dialog.open(LaunchDialogComponent, {
+  //     width: '600px',
+  //     height: '300px',
+  //     data: { batchcmdsafeurl: this.domSanitizer.bypassSecurityTrustResourceUrl(identity.site.url),
+  //             app: app.name}
+  //     })
+  // }
+
+  // public launchApp(app: Strudelapp, identity: Identity) {
+  //   if (!(app.url === null) && !(app.url =='')) {
+  //     this.openWindow(app,app.url,identity);
+  //   } else {
+  //     this.appparams = JSON.stringify([]);
+  //     let redirect = window.location.toString();
+  //     redirect = redirect.replace(/launch/,'finishlaunch');
+  //     let paramstr = this.buildParams(app,identity,redirect);
+  //     let windowloc = identity.site.url+'configure/'+app.name+"?"+paramstr;
+  //     this.openWindow(app,windowloc,identity);
+  //   }
+  //   // this.openLaunchWindow(app, identitiy);
+  // }
+  //
+  //
+  // public openWindow(app: any,url: string, identity: Identity) {
+  //   console.log('in openLaunchDialog');
+  //   console.log(app);
+  //
+  //   let headers = new HttpHeaders();
+  //   let options = { headers: headers, withCredentials: true};
+  //   let redirect = window.location.toString();
+  //   redirect = redirect.replace(/launch/,'finishlaunch');
+  //   let paramstr = this.buildParams(app,identity,redirect);
+  //   this.configwindow = window.open(url+"?"+paramstr);
+  //   if (!(this.windowWatcher === null) && !(this.windowWatcher === undefined)) {
+  //     this.windowWatcher.unsubscribe()
+  //   }
+  //   this.windowWatcher = timer(500).pipe(repeat()).subscribe(() => this.watchWindow(this.configwindow, identity, app,redirect));
+  //   this.configwindow.focus();
+  //
+  // }
+  //
+  // public watchWindow(configwindow, id, app, redirect) {
+  //   // Watch another window for url changes
+  //   // if the url changes to include the submit parameters, submit the job
+  //   // if the url changes to include appparameters, save them and open
+  //   // a new window to get the submit parameters
+  //   var location: string;
+  //   try {
+  //     location = configwindow.location.href;
+  //     // if we can read the location and it contains a submitcmd arameter save it
+  //     // and close the window
+  //     if (configwindow.closed) { // if the window is closed without our help, presumable the user wanted to cancel the launch
+  //       return
+  //     }
+  //     let match = location.match(/submitcmd\=([^&]+)(&|$)/);
+  //     if (match) {
+  //         this.submitcmd = decodeURIComponent(match[1]);
+  //         if (!(configwindow.closed)) {
+  //           configwindow.close()
+  //         }
+  //         this.windowWatcher.unsubscribe();
+  //     }
+  //     // if we can read the location and it contains an appparams parameter, save it
+  //     // and close the window
+  //     match = location.match(/appparams\=([^&]+)(&|$)/);
+  //     if (match) {
+  //         this.appparams = decodeURIComponent(match[1]);
+  //         if (!(configwindow.closed)) {
+  //           configwindow.close()
+  //         }
+  //         this.windowWatcher.unsubscribe();
+  //     }
+  //     // if we can read the location and it contains the redireURI, close the window
+  //     let idx = location.indexOf(redirect);
+  //     if (idx == 0) {
+  //       configwindow.close();
+  //     }
+  //   } catch {
+  //     location = null;
+  //   }
+  //   if (configwindow.closed) {
+  //     this.windowWatcher.unsubscribe();
+  //     // if the window is closed, see if we need to override appparams from localStorage
+  //     try {
+  //       let appparams = localStorage.getItem('appparams');
+  //       if (appparams != null) {
+  //         localStorage.removeItem('appparams');
+  //         this.appparams = appparams;
+  //       }
+  //     } catch {
+  //     }
+  //     // if the window is closed and we have an appparams value but not a submitcmd
+  //     // open a new window to get the submitcmd
+  //
+  //
+  //     if (!(this.appparams === null) && (this.submitcmd === null)) {
+  //       let paramstr = this.buildParams(app,id,redirect);
+  //       let windowloc = id.site.url+'configure/'+app.name+"?"+paramstr;
+  //       this.windowWatcher.unsubscribe();
+  //       this.openWindow(app,windowloc,id);
+  //     }
+  //     // if the window is closed and we have an appparams valud AND a submitcmd
+  //     // submit
+  //     if (!(this.appparams == null) && !(this.submitcmd == null )) {
+  //
+  //       let bi = new BatchInterface();
+  //       bi.submitcmd = this.submitcmd;
+  //       this.tesService.submit(app,id,bi,this.appparams);
+  //       this.appparams = null;
+  //       this.submitcmd = null;
+  //     }
+  //   }
+  // }
+  //
+  // private buildParams(app: Strudelapp, identity: Identity, redirect): string {
+  //   let params = new URLSearchParams();
+  //   let id = identity.copy_skip_catalog();
+  //   id.site.appCatalog = null;
+  //
+  //   params.set('app',JSON.stringify(app));
+  //   params.set('identity',JSON.stringify(id));
+  //   params.set('redirect',redirect);
+  //   return params.toString();
+  // }
 
 }
diff --git a/src/app/tes.service.ts b/src/app/tes.service.ts
index 3ef42fcbfb78ea57b32b8cd061909c106318e3ca..84b916698aa5c93379857f49130ec06db9b43b36 100644
--- a/src/app/tes.service.ts
+++ b/src/app/tes.service.ts
@@ -42,7 +42,7 @@ public joblist: BehaviorSubject<Job[]>;
 private timerSubscription: any;
 private appwindow: any;
 private appwindowWatcher: any;
-public batchinterface: {[id: string] : BatchInterface};
+// public batchinterface: {[id: string] : BatchInterface};
 
   constructor(private http: HttpClient,
               public dialog: MatDialog,
@@ -57,7 +57,7 @@ public batchinterface: {[id: string] : BatchInterface};
 
     this.timerSubscription = null;
     this.appwindowWatcher = null;
-    this.batchinterface = {};
+    // this.batchinterface = {};
     // this.computesitesService.identities.subscribe(identities => this.startPolling(identities));
  }
 
@@ -93,7 +93,6 @@ public setStatusMsg(statusMsg: BehaviorSubject<any>) {
  }
 
  private getBatchInterfaceError(error: any) {
-   console.log('in getBatchInterfaceError');
    console.error(error);
  }
 
@@ -104,10 +103,12 @@ public setStatusMsg(statusMsg: BehaviorSubject<any>) {
      return
    }
    console.log(error);
-   if (error.status == 404) {
+   if (error.status == 404 || error.status == 400) {
      this.statusMsg.next("Login expired. Please log in again.");
+     this.authorisationService.updateAgentContents();
      return
    }
+
  }
 
  getJobs(identity: Identity) {
@@ -119,21 +120,29 @@ public setStatusMsg(statusMsg: BehaviorSubject<any>) {
     this.joblist.next([]);
     return
   }
-  if (this.batchinterface[identity.repr()] === undefined) {
-         this.getconfig(new Strudelapp(),identity)
-          // .pipe(catchError(this.handleError))
-          .subscribe(resp => { this.batchinterface[identity.repr()] = resp; this.getJobs(identity) },
-                     error => this.getBatchInterfaceError(error));
-                     // error => this.getJobsError(error,identity));
-
-
-  } else {
-    let paramstr = this.buildParams(null,identity,this.batchinterface[identity.repr()]);
-    this.http.get<Job[]>(this.Base+'/stat'+'?'+paramstr,options)
-                      // .pipe(catchError(this.networkError))
-                      .subscribe(resp => this.updateJoblist(resp, identity),
-                                 error => this.getJobsError(error));
-  }
+  let bi = new BatchInterface();
+  bi.cancelcmd = identity.site.cancelcmd;
+  bi.statcmd = identity.site.statcmd;
+  // if (this.batchinterface[identity.repr()] === undefined) {
+  //        this.getconfig(new Strudelapp(),identity)
+  //         // .pipe(catchError(this.handleError))
+  //         .subscribe(resp => { this.batchinterface[identity.repr()] = resp; this.getJobs(identity) },
+  //                    error => this.getBatchInterfaceError(error));
+  //                    // error => this.getJobsError(error,identity));
+  //
+  //
+  // } else {
+  //   let paramstr = this.buildParams(null,identity,this.batchinterface[identity.repr()]);
+  //   this.http.get<Job[]>(this.Base+'/stat'+'?'+paramstr,options)
+  //                     // .pipe(catchError(this.networkError))
+  //                     .subscribe(resp => this.updateJoblist(resp, identity),
+  //                                error => this.getJobsError(error));
+  // }
+  let paramstr = this.buildParams(null,identity,bi);
+  this.http.get<Job[]>(this.Base+'/stat'+'?'+paramstr,options)
+                    // .pipe(catchError(this.networkError))
+                    .subscribe(resp => this.updateJoblist(resp, identity),
+                               error => this.getJobsError(error));
 }
 
  public getconfig(app: Strudelapp, identity: Identity): Observable<any> {
@@ -154,7 +163,7 @@ public setStatusMsg(statusMsg: BehaviorSubject<any>) {
    return JSON.stringify({'app': app, 'appparams': appparams});
  }
 
- submit(app: Strudelapp, identity: Identity, batchinterface: BatchInterface, appparams?: string) {
+ submit(app: Strudelapp, identity: Identity, batchinterface: BatchInterface, appparams?: any) {
    let headers = new HttpHeaders();
    let options = { headers: headers, withCredentials: true};
    this.statusMsg.next('Submitting job');
@@ -163,6 +172,7 @@ public setStatusMsg(statusMsg: BehaviorSubject<any>) {
    // let body = this.buildBody(app,appparams)
    let keys = this.authorisationService.getKeys();
    let body = {'app': app, 'appparams': appparams, 'keys': keys}
+   console.log('tes is submitting the job with body',body);
    this.http.post<any>(this.Base+'/submit'+'?'+paramstr, body, options)
                                          // .pipe(catchError(this.handleError))
                                          .subscribe(resp => {
@@ -183,7 +193,10 @@ public setStatusMsg(statusMsg: BehaviorSubject<any>) {
    let options = { headers: headers, withCredentials: true};
    // this.statusMsg.next(null);
    let data = {};
-   let paramstr = this.buildParams(job.app,job.identity,this.batchinterface[job.identity.repr()]);
+   let bi = new BatchInterface();
+   bi.statcmd = job.identity.site.statcmd;
+   bi.cancelcmd = job.identity.site.cancelcmd;
+   let paramstr = this.buildParams(job.app,job.identity,bi);
    this.http.delete<any>(this.Base+'/cancel/'+job.jobid+'?'+paramstr, options)
                       .pipe(catchError(this.handleError))
                       .subscribe(resp => this.submitted(resp,job.identity));
@@ -207,7 +220,7 @@ public setStatusMsg(statusMsg: BehaviorSubject<any>) {
    job.connectionState = 1;
    this.http.get<string>(this.Base+'/appinstance/'+username+'/'+loginhost+'/'+batchhost+'?'+paramstr, options)
                 // .pipe(catchError(this.handleError))
-                .subscribe(resp =>  { job.appinst = resp; this.createTunnel(job) ; console.log('got app inst data'+job.appinst)} )
+                .subscribe(resp =>  { job.appinst = resp; this.createTunnel(job) } )
    // let paramstr = this.buildParams(job.app,job.identity,this.batchinterface[job.identity.repr()]);
    // let headers = new HttpHeaders();
    // let options = { headers: headers, withCredentials: true};
@@ -241,7 +254,7 @@ public setStatusMsg(statusMsg: BehaviorSubject<any>) {
    job.connectionState = 3;
    this.http.get<string>(this.Base+'/appurl?'+paramstr,options)
                 .pipe(catchError(this.handleError))
-                .subscribe(resp => { console.log(resp); job.connectionState = 0; this.openAppWindow(resp)});
+                .subscribe(resp => {  job.connectionState = 0; this.openAppWindow(resp)});
 
 
  }
@@ -295,9 +308,7 @@ public postMkDir(id: Identity, path: string, name: string ) {
   params.set('identity',JSON.stringify(id));
   params.set('path',JSON.stringify(path));
 
-  return this.http.post<any>(this.Base+'/mkdir?'+params.toString(),name, options)
-                      .pipe(catchError(this.handleError))
-
+  return this.http.post<any>(this.Base+'/mkdir?'+params.toString(),name, options);
 }
 
 public getSftpData(id: Identity, path: string, cd: string ) {
@@ -309,7 +320,7 @@ public getSftpData(id: Identity, path: string, cd: string ) {
   params.set('cd',JSON.stringify(cd));
 
   return this.http.get<any>(this.Base+'/ls?'+params.toString(),options)
-                      .pipe(catchError(this.handleError))
+                      // .pipe(catchError(this.handleError))
 
 }
 
@@ -326,7 +337,7 @@ private httperror(errorstr: string) {
     this.statusMsg.next("Some authentication tokens have expired, you may need to log in again");
     this.authorisationService.updateAgentContents();
   }
-  console.log(errorstr);
+  console.error(errorstr);
 }
 
 // private networkError(error: HttpErrorResponse) {
@@ -340,8 +351,6 @@ private httperror(errorstr: string) {
 
 private handleError(error: HttpErrorResponse) {
   if (error.error instanceof ErrorEvent) {
-    console.log('instance of ErrorEvent');
-    console.log(error);
     // A client-side or network error occurred. Handle it accordingly.
     return throwError("Hmm, that didn't work. If you're using a local connection, please make sure Strudel-TES is running.");
   } else {
diff --git a/src/app/transfer/transfer.component.html b/src/app/transfer/transfer.component.html
index 4259e24da4df609276bded56c8350c834fe28c2a..0d3dbb4025be9679b555c4900ccff5ddae6675f9 100644
--- a/src/app/transfer/transfer.component.html
+++ b/src/app/transfer/transfer.component.html
@@ -1,18 +1,6 @@
-<div  fxFlex style="flex: 1 1 0%; box-sizing: border-box">
-<div fxLayout="column" fxLayoutAlign="space-around stretch" style="height: 100%; width: 100%" >
-    <mat-toolbar color="primary">
-      <mat-toolbar-row>
-        <button mat-icon-button (click)=idSideNav.toggle()><mat-icon>menu</mat-icon></button>
+<!-- <div  fxFlex style="flex: 1 1 0%; box-sizing: border-box">
+<div fxLayout="column" fxLayoutAlign="space-around stretch" style="height: 100%; width: 100%" > -->
 
-        <span>Strudel v2.0</span>
-        <span class="fill-horizontal-space"></span>
-      </mat-toolbar-row>
-    </mat-toolbar>
-
-<mat-sidenav-container #idSideNav autosize style="height: 100%; width: 100%">
-  <mat-sidenav #idSideNav mode="side" opened>
-      <app-sv2-side-nav></app-sv2-side-nav>
-  </mat-sidenav>
   <div fxLayout="column" fxLayoutAlign="space-around stretch" style="height: 100%; width: 100%" >
 
     <div fxLayout="row" fxLayout="space-between stretch" fxLayoutGap="1%" style="height: 90%">
@@ -46,9 +34,8 @@
     </div>
   </div>
 
+<!--
 
 
-    <!-- <mat-card style="width: 100%; box-sizing: border-box">Transfer tasks</mat-card> -->
-</mat-sidenav-container>
-</div>
 </div>
+</div> -->
diff --git a/src/app/transfer/transfer.component.ts b/src/app/transfer/transfer.component.ts
index 66a33abc9e391aa62af354391480420abe3c2981..7fe4e3cb9f73ae4d3eefde8f74677a28ecc5e0df 100644
--- a/src/app/transfer/transfer.component.ts
+++ b/src/app/transfer/transfer.component.ts
@@ -29,6 +29,8 @@ export class TransferComponent implements OnInit {
   site: Computesite[];
   disableSend: Boolean;
   statusMsg: BehaviorSubject<string>;
+  redirecturi: string;
+  appevent: any;
 
 
   constructor(private computesitesService: ComputesitesService,
@@ -42,6 +44,7 @@ export class TransferComponent implements OnInit {
     this.pathSubject = [ new BehaviorSubject(""),new BehaviorSubject("")];
     this.id = [null,null];
     this.disableSend = true;
+    this.statusMsg = this.tesService.statusMsg;
   }
 
   ngOnInit() {
@@ -53,7 +56,6 @@ export class TransferComponent implements OnInit {
     // this.id = [null,null];
     // this.disableSend = true;
     setTimeout( () => this.authService.updateAgentContents() )
-
   }
 
 compareObjects(o1: any, o2: any) {
@@ -64,10 +66,16 @@ compareObjects(o1: any, o2: any) {
   }
 }
 
+processError(idx,error) {
+  this.working[idx].next(false);
+  this.statusMsg.next(error.error.message);
+
+}
+
 newDirectory(idx: number, name: string) {
   console.log('attempt to create directory',name,'on',this.id[idx]);
   this.working[idx].next(true);
-  this.tesService.postMkDir(this.id[idx],this.path[idx],name).subscribe(resp => this. getSftpls(idx,'.'));
+  this.tesService.postMkDir(this.id[idx],this.path[idx],name).subscribe(resp => this.getSftpls(idx,'.'), error => this.processError(idx,error));
 }
 
 getSftpls(idx,cd) {
@@ -75,7 +83,7 @@ getSftpls(idx,cd) {
   console.log(this.id);
   console.log(idx);
   this.working[idx].next(true);
-  this.tesService.getSftpData(this.id[idx],this.path[idx],cd).subscribe(resp => this.updateSftpls(idx,resp));
+  this.tesService.getSftpData(this.id[idx],this.path[idx],cd).subscribe(resp => this.updateSftpls(idx,resp), error => this.processError(idx,error));
 }
 
 makeFileElements(data) {
@@ -165,8 +173,8 @@ makeFileElements(data) {
           'id': this.id[dest],
           'path': this.path[dest]
         }});
-      localStorage.setItem('appparams',appparams);
-      window.close();
+      console.log('send file activated, nagivating to redirect uri');
+      window.parent.postMessage({'appData':appparams},'*');
     } else {
       console.log('Dont send file not enough servers'+element.name+' on ');
     }
diff --git a/src/assets/config/computesites.json b/src/assets/config/computesites.json
index ee5d81849edf4549a6b0b6779f5a97a43df71c51..9e1c469b5cf3373e56b33d9d2595a5940a8309df 100644
--- a/src/assets/config/computesites.json
+++ b/src/assets/config/computesites.json
@@ -1,12 +1,14 @@
 [
   {
-    "url": "http://localhost:8080/",
+    "url": "http://localhost:5200/",
     "name": "M3",
     "host": "m3-login2.massive.org.au",
     "dtn": "m3-dtn1.massive.org.au",
     "cafingerprint": "RSA SHA256:cmDxHrZQSPlBMUUcI/BWmruXho1XOzfXPDHSqVTwV2I",
     "appCatalog": [],
-    "appCatalogUri": "./assets/config/m3apps.json"
+    "appCatalogUri": "./assets/config/m3apps.json",
+    "cancelcmd": "scancel {jobid}",
+    "statcmd": "/usr/local/sv2/sv2stat.py"
   },
   {
     "url": "https://vm-118-138-240-255.erc.monash.edu.au/m3siteconfig/",
@@ -15,7 +17,9 @@
     "dtn": "ozstar.swin.edu.au",
     "cafingerprint": "RSA SHA256:uRYwTJSLksZbwSXYYmOjXh6JzSXpwVnY6o7BYFJc60g",
     "appCatalog": [],
-    "appCatalogUri": "./assets/config/m3apps.json"
+    "appCatalogUri": "./assets/config/m3apps.json",
+    "cancelcmd": "scancel {jobid}",
+    "statcmd": "/usr/local/sv2/sv2stat.py"
   },
   {
     "url": "https://vm-118-138-240-255.erc.monash.edu.au/m3siteconfig_dev/",
@@ -24,7 +28,9 @@
     "dtn": "146.118.65.246",
     "cafingerprint": "RSA SHA256:cmDxHrZQSPlBMUUcI/BWmruXho1XOzfXPDHSqVTwV2I",
     "appCatalog": [],
-    "appCatalogUri": "./assets/config/cvluwaapps.json"
+    "appCatalogUri": "./assets/config/cvluwaapps.json",
+    "cancelcmd": "scancel {jobid}",
+    "statcmd": "/usr/local/sv2/sv2stat.py"
   },
   {
     "url": null ,
diff --git a/src/assets/config/computesites.json~ b/src/assets/config/computesites.json~
deleted file mode 100644
index 11ff902c340f3d58e58c0e2901b42b6f0d58bde8..0000000000000000000000000000000000000000
--- a/src/assets/config/computesites.json~
+++ /dev/null
@@ -1,26 +0,0 @@
-[
-  {
-    "url": "http://localhost:8080/",
-    "name": "M3",
-    "host": "m3-login2.massive.org.au",
-    "cafingerprint": "RSA SHA256:cmDxHrZQSPlBMUUcI/BWmruXho1XOzfXPDHSqVTwV2I",
-    "appCatalog": [],
-    "appCatalogUri": "assets/config/m3apps.json"
-  },
-  {
-    "url": "https://vm-118-138-240-255.erc.monash.edu.au/m3staticsiteconfig/",
-    "name": "M3 Static Services",
-    "host": "m3-login2.massive.org.au",
-    "cafingerprint": "RSA SHA256:cmDxHrZQSPlBMUUcI/BWmruXho1XOzfXPDHSqVTwV2I",
-    "appCatalog": [],
-    "appCatalogUri": "assets/config/m3staticapps.json"
-  },
-  {
-    "url": "https://vm-118-138-240-255.erc.monash.edu.au/m3siteconfig/",
-    "name": "OzStar",
-    "host": "ozstar.swin.edu.au",
-    "cafingerprint": "RSA SHA256:uRYwTJSLksZbwSXYYmOjXh6JzSXpwVnY6o7BYFJc60g",
-    "appCatalog": [],
-    "appCatalogUri": "assets/config/m3apps.json"
-  }
-]
diff --git a/src/assets/config/m3apps.json b/src/assets/config/m3apps.json
index e97e7c987b3fbac2713d3d3aa2bda9a6bfe48dc8..0f36950c56ea3cc1e97dcc4cd8e5c6db423c7ca1 100644
--- a/src/assets/config/m3apps.json
+++ b/src/assets/config/m3apps.json
@@ -7,14 +7,6 @@
     "localbind": true,
     "applist": null
   },
-  { "url": null,
-    "name": "Guacamole Desktop",
-    "startscript": "#!/bin/bash\n/home/chines/desktop.sh\n ",
-    "paramscmd": "/home/chines/vdiparam.py",
-    "client": {"cmd": null, "redir": "guacamole?username={username}&password={password}" },
-    "localbind": true,
-    "applist": null
-  },
  {
    "url": null,
    "name": "Jupyter Lab",
@@ -24,36 +16,9 @@
    "localbind": true,
    "applist": null
   },
-  {
-    "url": null,
-    "name": "LiberTEM",
-    "startscript": "eval $(cat /home/chines/libertembatch)",
-    "paramscmd": "/projects/pMOSP/chines/libertem_venv/bin/python /projects/pMOSP/chines/libertem_venv/bin/server_stat.py",
-    "client": {"cmd": null, "redir": ""},
-    "localbind": true,
-    "applist": null
-  },
-  {
-    "url": null,
-    "name": "CryoSPARC",
-    "startscript": null,
-    "paramscmd": "/home/chines/cryosparc_params.py",
-    "client": {"cmd": null, "redir": ""},
-    "localbind": true,
-    "applist": null
-  },
-  {
-    "url": null,
-    "name": "R Studio Server",
-    "startscript": "#!/bin/bash\n/usr/local/sv2/rstudioserver/run.sh\n",
-    "paramscmd": "/usr/local/sv2/rstudioserver/params.py",
-    "client": {"cmd": null, "redir": ""},
-    "localbind": true,
-    "applist": null
-  },
   { "url": "transfer",
     "name": "Transfer files",
-    "startscript": "#!/bin/bash\n echo '{appparams}' > ft.json",
+    "startscript": "#!/bin/bash\n echo '{appparams}' | /usr/local/sv2/copytool.py\n",
     "paramscmd": "/home/chines/sv2/desktop_novnc/params.py",
     "client": {"cmd": null, "redir": null },
     "localbind": true,
diff --git a/src/assets/config/m3apps.json~ b/src/assets/config/m3apps.json~
new file mode 100644
index 0000000000000000000000000000000000000000..f15ba47b5ff47c0c646baed612b38dd090e34ee8
--- /dev/null
+++ b/src/assets/config/m3apps.json~
@@ -0,0 +1,62 @@
+[
+  { "url": null,
+    "name": "Desktop",
+    "startscript": "#!/bin/bash\n/home/chines/sv2/desktop_novnc/desktop.sh\n ",
+    "paramscmd": "/home/chines/sv2/desktop_novnc/params.py",
+    "client": {"cmd": null, "redir": "vnc.html?host=vm-118-138-240-255.erc.monash.edu.au&port=443&password={password}" },
+    "localbind": true,
+    "applist": null
+  },
+  { "url": null,
+    "name": "Guacamole Desktop",
+    "startscript": "#!/bin/bash\n/home/chines/desktop.sh\n ",
+    "paramscmd": "/home/chines/vdiparam.py",
+    "client": {"cmd": null, "redir": "guacamole?username={username}&password={password}" },
+    "localbind": true,
+    "applist": null
+  },
+ {
+   "url": null,
+   "name": "Jupyter Lab",
+   "startscript": "#!/bin/bash\n/home/chines/jupyter.slurm\n",
+   "paramscmd": "/home/chines/jupyter_params.py",
+   "client": {"cmd": null, "redir": "?token={token}"},
+   "localbind": true,
+   "applist": null
+  },
+  {
+    "url": null,
+    "name": "LiberTEM",
+    "startscript": "eval $(cat /home/chines/libertembatch)",
+    "paramscmd": "/projects/pMOSP/chines/libertem_venv/bin/python /projects/pMOSP/chines/libertem_venv/bin/server_stat.py",
+    "client": {"cmd": null, "redir": ""},
+    "localbind": true,
+    "applist": null
+  },
+  {
+    "url": null,
+    "name": "CryoSPARC",
+    "startscript": null,
+    "paramscmd": "/home/chines/cryosparc_params.py",
+    "client": {"cmd": null, "redir": ""},
+    "localbind": true,
+    "applist": null
+  },
+  {
+    "url": null,
+    "name": "R Studio Server",
+    "startscript": "#!/bin/bash\n/usr/local/sv2/rstudioserver/run.sh\n",
+    "paramscmd": "/usr/local/sv2/rstudioserver/params.py",
+    "client": {"cmd": null, "redir": ""},
+    "localbind": true,
+    "applist": null
+  },
+  { "url": "transfer",
+    "name": "Transfer files",
+    "startscript": "#!/bin/bash\n echo '{appparams}' | /usr/local/sv2/copytool.py\n",
+    "paramscmd": "/home/chines/sv2/desktop_novnc/params.py",
+    "client": {"cmd": null, "redir": null },
+    "localbind": true,
+    "applist": null
+  }
+]