From 1231e38431d576e49b88a36222c3f357681bab6b Mon Sep 17 00:00:00 2001
From: mechtelm <nicht@mehr.fragen>
Date: Mon, 8 Apr 2019 20:10:28 +0200
Subject: [PATCH] superadmin: users working better then ever

---
 src/app/maindata.service.ts                   |  2 -
 .../about-text/about-text.component.css       |  0
 .../about-text/about-text.component.html      | 25 ------
 .../about-text/about-text.component.spec.ts   | 25 ------
 .../about-text/about-text.component.ts        | 56 --------------
 src/app/superadmin/backend.service.ts         | 76 +++++++------------
 .../dashboard/dashboard.component.css         |  0
 .../dashboard/dashboard.component.html        |  8 --
 .../dashboard/dashboard.component.spec.ts     | 25 ------
 .../dashboard/dashboard.component.ts          | 19 -----
 src/app/superadmin/datastore.service.spec.ts  | 15 ----
 src/app/superadmin/datastore.service.ts       | 20 -----
 src/app/superadmin/index.ts                   |  3 -
 .../superadmin/superadmin-routing.module.ts   |  2 -
 src/app/superadmin/superadmin.component.css   | 11 +--
 src/app/superadmin/superadmin.component.html  | 11 ++-
 src/app/superadmin/superadmin.component.ts    | 19 ++---
 src/app/superadmin/superadmin.module.ts       |  9 +--
 src/app/superadmin/users/users.component.css  |  8 ++
 src/app/superadmin/users/users.component.html | 14 +++-
 src/app/superadmin/users/users.component.ts   | 60 +++++++++------
 .../workspaces/workspaces.component.css       |  4 +
 .../workspaces/workspaces.component.ts        |  1 -
 src/app/workspace/workspace.component.css     |  5 --
 24 files changed, 106 insertions(+), 312 deletions(-)
 delete mode 100644 src/app/superadmin/about-text/about-text.component.css
 delete mode 100644 src/app/superadmin/about-text/about-text.component.html
 delete mode 100644 src/app/superadmin/about-text/about-text.component.spec.ts
 delete mode 100644 src/app/superadmin/about-text/about-text.component.ts
 delete mode 100644 src/app/superadmin/dashboard/dashboard.component.css
 delete mode 100644 src/app/superadmin/dashboard/dashboard.component.html
 delete mode 100644 src/app/superadmin/dashboard/dashboard.component.spec.ts
 delete mode 100644 src/app/superadmin/dashboard/dashboard.component.ts
 delete mode 100644 src/app/superadmin/datastore.service.spec.ts
 delete mode 100644 src/app/superadmin/datastore.service.ts

diff --git a/src/app/maindata.service.ts b/src/app/maindata.service.ts
index acce73d4..eb266aef 100644
--- a/src/app/maindata.service.ts
+++ b/src/app/maindata.service.ts
@@ -46,8 +46,6 @@ export class MainDataService {
           myLoginData.name = logindata.name;
           myLoginData.workspaces = logindata.workspaces;
           myLoginData.is_superadmin = logindata.is_superadmin;
-          console.log('fü33 ' + myLoginData.name);
-
       }
     }
     this.loginData$.next(myLoginData);
diff --git a/src/app/superadmin/about-text/about-text.component.css b/src/app/superadmin/about-text/about-text.component.css
deleted file mode 100644
index e69de29b..00000000
diff --git a/src/app/superadmin/about-text/about-text.component.html b/src/app/superadmin/about-text/about-text.component.html
deleted file mode 100644
index 7c335e74..00000000
--- a/src/app/superadmin/about-text/about-text.component.html
+++ /dev/null
@@ -1,25 +0,0 @@
-<!-- <form [formGroup]="aboutTextForm" (ngSubmit)="setAboutText()">
-  <div fxLayout="row">
-    <button mat-raised-button type="submit">
-        <mat-icon>save</mat-icon>
-    </button>
-  </div>
-  <br>
-  <textarea matInput formControlName="myTextArea" cols="90" rows="20" placeholder="Enter text here..."></textarea>
-</form> -->
-
-<form [formGroup]="aboutTextForm" (ngSubmit)="setAboutText()">
-  <div fxLayout="row">
-    <button mat-raised-button>
-        <mat-icon>save</mat-icon>
-    </button>
-  </div>
-  <br>
-
-</form>
-
-<link href="https://cdn.quilljs.com/1.3.6/quill.snow.css" rel="stylesheet">
-<div id="editor-container"></div>
-
-
-<script src="https://cdn.quilljs.com/1.3.6/quill.js"></script>
diff --git a/src/app/superadmin/about-text/about-text.component.spec.ts b/src/app/superadmin/about-text/about-text.component.spec.ts
deleted file mode 100644
index be632b84..00000000
--- a/src/app/superadmin/about-text/about-text.component.spec.ts
+++ /dev/null
@@ -1,25 +0,0 @@
-import { async, ComponentFixture, TestBed } from '@angular/core/testing';
-
-import { AboutTextComponent } from './about-text.component';
-
-describe('AboutTextComponent', () => {
-  let component: AboutTextComponent;
-  let fixture: ComponentFixture<AboutTextComponent>;
-
-  beforeEach(async(() => {
-    TestBed.configureTestingModule({
-      declarations: [ AboutTextComponent ]
-    })
-    .compileComponents();
-  }));
-
-  beforeEach(() => {
-    fixture = TestBed.createComponent(AboutTextComponent);
-    component = fixture.componentInstance;
-    fixture.detectChanges();
-  });
-
-  it('should create', () => {
-    expect(component).toBeTruthy();
-  });
-});
diff --git a/src/app/superadmin/about-text/about-text.component.ts b/src/app/superadmin/about-text/about-text.component.ts
deleted file mode 100644
index cece233a..00000000
--- a/src/app/superadmin/about-text/about-text.component.ts
+++ /dev/null
@@ -1,56 +0,0 @@
-import { Component, OnInit } from '@angular/core';
-import { MatTableDataSource } from '@angular/material/table';
-import { ViewChild } from '@angular/core';
-import { DatastoreService } from '../datastore.service';
-import { MatSort, MatDialog, MatSnackBar } from '@angular/material';
-import { FormGroup, FormsModule, FormBuilder } from '@angular/forms';
-import { SelectionModel } from '@angular/cdk/collections';
-import { ConfirmDialogComponent, ConfirmDialogData, MessageDialogComponent,
-  MessageDialogData, MessageType } from '../../iqb-common';
-// import { AboutComponent } from './../../about';
-import { BackendService as BackendServiceReadOnly } from './../../backend.service';
-import { BackendService as BackendServiceSuperAdmin } from './../backend.service';
-// import * as Quill from 'quill';
-
-
-
-@Component({
-  selector: 'itc-about-text',
-  templateUrl: './about-text.component.html',
-  styleUrls: ['./about-text.component.css']
-})
-export class AboutTextComponent implements OnInit {
-  aboutTextForm: FormGroup;
-  public dataLoading = false;
-  aboutText: string;
-
-  constructor(
-    private bsRO: BackendServiceReadOnly,
-    private bsSA: BackendServiceSuperAdmin,
-    private fb: FormBuilder,
-    private snackBar: MatSnackBar
-  ) { }
-
-  ngOnInit() {
-    this.aboutTextForm = this.fb.group({
-      myTextArea: this.fb.control('')
-    });
-    // this.mds.pageTitle$.next('');
-    // this.bsRO.getAboutText().subscribe(t => this.aboutTextForm.get('myTextArea').setValue(t as string));
-  }
-
-  setAboutText() {
-
-    this.bsSA.setAboutText(this.aboutTextForm.get('myTextArea').value).subscribe(respOk => {
-      if (respOk) {
-        this.snackBar.open('Geänderter Text', '', {duration: 1500});
-      } else {
-        this.snackBar.open('Text konnte nicht geändert werden', 'Fehler', {duration: 1500});
-      }
-      this.dataLoading = false;
-    });
-  }
-
-
-
-}
diff --git a/src/app/superadmin/backend.service.ts b/src/app/superadmin/backend.service.ts
index 92aa7a93..f84b20ef 100644
--- a/src/app/superadmin/backend.service.ts
+++ b/src/app/superadmin/backend.service.ts
@@ -1,6 +1,6 @@
 import { Injectable, Inject } from '@angular/core';
 import { HttpClient, HttpHeaders, HttpEvent, HttpErrorResponse } from '@angular/common/http';
-import { Observable, throwError } from 'rxjs';
+import { Observable, throwError, of } from 'rxjs';
 import { catchError } from 'rxjs/operators';
 
 
@@ -12,7 +12,7 @@ export class BackendService {
   constructor(
     @Inject('SERVER_URL') private serverUrl: string,
     private http: HttpClient) {
-      this.serverUrl = this.serverUrl + 'admin/php_superadmin/';
+      this.serverUrl = this.serverUrl + 'php/sys.php/';
     }
 
   private errorHandler(error: Error | any): Observable<any> {
@@ -20,84 +20,54 @@ export class BackendService {
   }
 
   // *******************************************************************
-  getUsers(): Observable<GetUserDataResponse[] | ServerError> {
-    const httpOptions = {
-      headers: new HttpHeaders({
-        'Content-Type':  'application/json'
-      })
-    };
+  getUsers(): Observable<GetUserDataResponse[]> {
     return this.http
-      .post<GetUserDataResponse[]>(this.serverUrl + 'getUsers.php', {}, httpOptions)
+      .get<GetUserDataResponse[]>(this.serverUrl + 'users')
         .pipe(
-          catchError(this.handleError)
+          catchError(err => [])
         );
   }
 
 
-  addUser(name: string, password: string): Observable<Boolean | ServerError> {
-    const httpOptions = {
-      headers: new HttpHeaders({
-        'Content-Type':  'application/json'
-      })
-    };
+  addUser(name: string, password: string): Observable<Boolean> {
     return this.http
-      .post<Boolean>(this.serverUrl + 'addUser.php', {n: name, p: password}, httpOptions)
+      .post<Boolean>(this.serverUrl + 'user/add', {n: name, p: password})
         .pipe(
-          catchError(this.handleError)
+          catchError(err => of(false))
         );
   }
 
-  changePassword(name: string, password: string): Observable<Boolean | ServerError> {
-    const httpOptions = {
-      headers: new HttpHeaders({
-        'Content-Type':  'application/json'
-      })
-    };
+  changePassword(name: string, password: string): Observable<Boolean> {
     return this.http
-      .post<Boolean>(this.serverUrl + 'setPassword.php', {n: name, p: password}, httpOptions)
+      .post<Boolean>(this.serverUrl + 'user/pw', {n: name, p: password})
         .pipe(
-          catchError(this.handleError)
+          catchError(err => of(false))
         );
   }
 
-  deleteUsers(users: string[]): Observable<Boolean | ServerError> {
-    const httpOptions = {
-      headers: new HttpHeaders({
-        'Content-Type':  'application/json'
-      })
-    };
+  deleteUsers(users: string[]): Observable<Boolean> {
     return this.http
-      .post<Boolean>(this.serverUrl + 'deleteUsers.php', {u: users}, httpOptions)
+      .post<Boolean>(this.serverUrl + 'users/delete', {u: users})
         .pipe(
-          catchError(this.handleError)
+          catchError(err => of(false))
         );
   }
 
   // *******************************************************************
-  getWorkspacesByUser(username: string): Observable<IdLabelSelectedData[] | ServerError> {
-    const httpOptions = {
-      headers: new HttpHeaders({
-        'Content-Type':  'application/json'
-      })
-    };
+  getWorkspacesByUser(username: string): Observable<IdRoleData[]> {
     return this.http
-      .post<IdLabelSelectedData[]>(this.serverUrl + 'getUserWorkspaces.php', {u: username}, httpOptions)
+      .get<IdLabelSelectedData[]>(this.serverUrl + 'workspaces/' + username)
         .pipe(
-          catchError(this.handleError)
+          catchError(err => [])
         );
   }
 
   // *******************************************************************
-  setWorkspacesByUser(user: string, accessTo: IdLabelSelectedData[]): Observable<Boolean | ServerError> {
-    const httpOptions = {
-      headers: new HttpHeaders({
-        'Content-Type':  'application/json'
-      })
-    };
+  setWorkspacesByUser(user: string, accessTo: IdRoleData[]): Observable<Boolean> {
     return this.http
-      .post<Boolean>(this.serverUrl + 'setUserWorkspaces.php', {u: user, w: accessTo}, httpOptions)
+      .post<Boolean>(this.serverUrl + 'user/workspaces', {u: user, ws: accessTo})
         .pipe(
-          catchError(this.handleError)
+          catchError(err => of(false))
         );
   }
 
@@ -232,3 +202,9 @@ export interface IdLabelSelectedData {
   label: string;
   selected: boolean;
 }
+
+export interface IdRoleData {
+  id: number;
+  label: string;
+  role: string;
+}
diff --git a/src/app/superadmin/dashboard/dashboard.component.css b/src/app/superadmin/dashboard/dashboard.component.css
deleted file mode 100644
index e69de29b..00000000
diff --git a/src/app/superadmin/dashboard/dashboard.component.html b/src/app/superadmin/dashboard/dashboard.component.html
deleted file mode 100644
index 093939e3..00000000
--- a/src/app/superadmin/dashboard/dashboard.component.html
+++ /dev/null
@@ -1,8 +0,0 @@
-<p *ngIf="isSuperadmin">
-  <button color="accent" [routerLink]="['/superadmin/users']">
-    <i class="material-icons">settings</i> Users
-  </button><br/>
-  <button color="accent" [routerLink]="['/superadmin/workspaces']">
-    <i class="material-icons">settings</i> Arbeitsbereiche
-  </button>
-</p>
diff --git a/src/app/superadmin/dashboard/dashboard.component.spec.ts b/src/app/superadmin/dashboard/dashboard.component.spec.ts
deleted file mode 100644
index 9c996c37..00000000
--- a/src/app/superadmin/dashboard/dashboard.component.spec.ts
+++ /dev/null
@@ -1,25 +0,0 @@
-import { async, ComponentFixture, TestBed } from '@angular/core/testing';
-
-import { DashboardComponent } from './dashboard.component';
-
-describe('DashboardComponent', () => {
-  let component: DashboardComponent;
-  let fixture: ComponentFixture<DashboardComponent>;
-
-  beforeEach(async(() => {
-    TestBed.configureTestingModule({
-      declarations: [ DashboardComponent ]
-    })
-    .compileComponents();
-  }));
-
-  beforeEach(() => {
-    fixture = TestBed.createComponent(DashboardComponent);
-    component = fixture.componentInstance;
-    fixture.detectChanges();
-  });
-
-  it('should create', () => {
-    expect(component).toBeTruthy();
-  });
-});
diff --git a/src/app/superadmin/dashboard/dashboard.component.ts b/src/app/superadmin/dashboard/dashboard.component.ts
deleted file mode 100644
index 3f95657b..00000000
--- a/src/app/superadmin/dashboard/dashboard.component.ts
+++ /dev/null
@@ -1,19 +0,0 @@
-import { Component, OnInit } from '@angular/core';
-
-
-@Component({
-  selector: 'superadmin-dashboard',
-  templateUrl: './dashboard.component.html',
-  styleUrls: ['./dashboard.component.css']
-})
-export class DashboardComponent implements OnInit {
-  public isSuperadmin = false;
-
-  constructor() {
-  }
-
-  ngOnInit() {
-
-  }
-
-}
diff --git a/src/app/superadmin/datastore.service.spec.ts b/src/app/superadmin/datastore.service.spec.ts
deleted file mode 100644
index 9f1a16e3..00000000
--- a/src/app/superadmin/datastore.service.spec.ts
+++ /dev/null
@@ -1,15 +0,0 @@
-import { TestBed, inject } from '@angular/core/testing';
-
-import { DatastoreService } from './datastore.service';
-
-describe('DatastoreService', () => {
-  beforeEach(() => {
-    TestBed.configureTestingModule({
-      providers: [DatastoreService]
-    });
-  });
-
-  it('should be created', inject([DatastoreService], (service: DatastoreService) => {
-    expect(service).toBeTruthy();
-  }));
-});
diff --git a/src/app/superadmin/datastore.service.ts b/src/app/superadmin/datastore.service.ts
deleted file mode 100644
index 8b40a316..00000000
--- a/src/app/superadmin/datastore.service.ts
+++ /dev/null
@@ -1,20 +0,0 @@
-import { BehaviorSubject } from 'rxjs';
-import { Injectable } from '@angular/core';
-
-@Injectable({
-  providedIn: 'root'
-})
-export class DatastoreService {
-  public pageTitle$ = new BehaviorSubject('Verwaltung');
-  public isSuperadmin$ = new BehaviorSubject(false);
-
-  constructor() { }
-
-  updatePageTitle(newTitle: string) {
-    this.pageTitle$.next(newTitle);
-  }
-
-  updateIsSuperadmin(newStatus: boolean) {
-    this.isSuperadmin$.next(newStatus);
-  }
-}
diff --git a/src/app/superadmin/index.ts b/src/app/superadmin/index.ts
index 94a83da2..57d8e210 100644
--- a/src/app/superadmin/index.ts
+++ b/src/app/superadmin/index.ts
@@ -1,5 +1,2 @@
-export { DashboardComponent } from './dashboard/dashboard.component';
 export { SuperadminComponent } from './superadmin.component';
 export { SuperadminModule } from './superadmin.module';
-export { DatastoreService } from './datastore.service';
-
diff --git a/src/app/superadmin/superadmin-routing.module.ts b/src/app/superadmin/superadmin-routing.module.ts
index f50b7666..8a09ecc7 100644
--- a/src/app/superadmin/superadmin-routing.module.ts
+++ b/src/app/superadmin/superadmin-routing.module.ts
@@ -4,7 +4,6 @@ import { Routes, RouterModule } from '@angular/router';
 import { WorkspacesComponent } from './workspaces/workspaces.component';
 import { UsersComponent } from './users/users.component';
 import { SuperadminComponent } from './superadmin.component';
-import { AboutTextComponent } from './about-text/about-text.component';
 
 
 const routes: Routes = [
@@ -15,7 +14,6 @@ const routes: Routes = [
       {path: '', redirectTo: 'users', pathMatch: 'full'},
       {path: 'users', component: UsersComponent},
       {path: 'workspaces', component: WorkspacesComponent},
-      {path: 'aboutText', component: AboutTextComponent},
       {path: '**', component: UsersComponent}
     ]
   }
diff --git a/src/app/superadmin/superadmin.component.css b/src/app/superadmin/superadmin.component.css
index bc515572..90fca559 100644
--- a/src/app/superadmin/superadmin.component.css
+++ b/src/app/superadmin/superadmin.component.css
@@ -7,11 +7,12 @@
   padding: 25px;
 }
 
-.communication-error-message {
-  color: red;
-  padding: 10px 50px;
+#buttonsContainer {
+  color: rgb(253, 249, 196);
+  padding: 0 10px 0 0;
+  font-weight: bold;
 }
 
-.columnhost {
-  width: 100%;
+#buttonsContainer img {
+  width: 100px;
 }
diff --git a/src/app/superadmin/superadmin.component.html b/src/app/superadmin/superadmin.component.html
index 4752f1ce..4f4fc325 100644
--- a/src/app/superadmin/superadmin.component.html
+++ b/src/app/superadmin/superadmin.component.html
@@ -1,8 +1,15 @@
+<div id="buttonsContainer" fxLayout="row" fxLayoutAlign="start center">
+  <a [routerLink]="['/']">
+    <img src="assets/IQB-LogoA.png" matTooltip="Startseite"/>
+  </a>
+  <div fxLayout="row wrap" fxLayoutAlign="space-between center" fxFlex>
+    <div class="error-msg">{{ (mds.globalErrorMsg$ | async)?.labelNice }}</div>
+    <div>IQB-Testcenter Systemverwaltung</div>
+  </div>
+</div>
 <div class="page-body">
   <div class="adminbackground">
 
-    <!--<p class="communication-error-message" *ngIf="!isAdmin">{{ notLoggedInMessage }}</p>-->
-
     <nav mat-tab-nav-bar>
       <a mat-tab-link
           *ngFor="let link of navLinks"
diff --git a/src/app/superadmin/superadmin.component.ts b/src/app/superadmin/superadmin.component.ts
index 4a5af8bc..b33d0946 100644
--- a/src/app/superadmin/superadmin.component.ts
+++ b/src/app/superadmin/superadmin.component.ts
@@ -1,4 +1,5 @@
 import { Component, OnInit } from '@angular/core';
+import { MainDataService } from '../maindata.service';
 
 
 
@@ -6,21 +7,13 @@ import { Component, OnInit } from '@angular/core';
   templateUrl: './superadmin.component.html',
   styleUrls: ['./superadmin.component.css']
 })
-export class SuperadminComponent implements OnInit {
-
+export class SuperadminComponent {
+  constructor(
+    private mds: MainDataService
+  ) { }
 
   public navLinks = [
     {path: 'users', label: 'Users'},
-    {path: 'workspaces', label: 'Arbeitsbereiche'},
-    {path: 'aboutText', label: 'AboutText'}
+    {path: 'workspaces', label: 'Arbeitsbereiche'}
   ];
-
-
-  constructor(
-  ) { }
-
-  ngOnInit() {
-    // this.mds.updatePageTitle('IQB-Testcenter Verwaltung: Nutzer und Arbeitsbereiche');
-  }
-
 }
diff --git a/src/app/superadmin/superadmin.module.ts b/src/app/superadmin/superadmin.module.ts
index 6a00bb57..b12af6b7 100644
--- a/src/app/superadmin/superadmin.module.ts
+++ b/src/app/superadmin/superadmin.module.ts
@@ -11,16 +11,13 @@ import { SuperadminRoutingModule } from './superadmin-routing.module';
 import { WorkspacesComponent } from './workspaces/workspaces.component';
 import { UsersComponent } from './users/users.component';
 import { SuperadminComponent } from './superadmin.component';
-import { DatastoreService } from './datastore.service';
 import { BackendService } from './backend.service';
 import { IqbFilesModule } from '../iqb-files/iqb-files.module';
 import { IqbCommonModule } from '../iqb-common/iqb-common.module';
-import { DashboardComponent } from './dashboard/dashboard.component';
 import { NewuserComponent } from './users/newuser/newuser.component';
 import { NewpasswordComponent } from './users/newpassword/newpassword.component';
 import { NewworkspaceComponent } from './workspaces/newworkspace/newworkspace.component';
 import { EditworkspaceComponent } from './workspaces/editworkspace/editworkspace.component';
-import { AboutTextComponent } from './about-text/about-text.component';
 
 
 @NgModule({
@@ -49,22 +46,18 @@ import { AboutTextComponent } from './about-text/about-text.component';
   ],
   exports: [
     SuperadminComponent,
-    DashboardComponent
   ],
   declarations: [
     WorkspacesComponent,
     UsersComponent,
     SuperadminComponent,
-    DashboardComponent,
     NewuserComponent,
     NewpasswordComponent,
     NewworkspaceComponent,
-    EditworkspaceComponent,
-    AboutTextComponent
+    EditworkspaceComponent
   ],
   providers: [
     BackendService,
-    DatastoreService
   ],
   entryComponents: [
     NewuserComponent,
diff --git a/src/app/superadmin/users/users.component.css b/src/app/superadmin/users/users.component.css
index e69de29b..4c24b03c 100644
--- a/src/app/superadmin/users/users.component.css
+++ b/src/app/superadmin/users/users.component.css
@@ -0,0 +1,8 @@
+.mat-raised-button {
+    min-width: 100px;
+    margin: 2px;
+}
+
+.mat-checkbox {
+    margin: 0 3px;
+}
\ No newline at end of file
diff --git a/src/app/superadmin/users/users.component.html b/src/app/superadmin/users/users.component.html
index a27c74ac..e20f2803 100644
--- a/src/app/superadmin/users/users.component.html
+++ b/src/app/superadmin/users/users.component.html
@@ -60,19 +60,25 @@
         </button>
     </div>
 
-    <mat-table [dataSource]="WorkspacelistDatasource">
+    <mat-table [dataSource]="WorkspacelistDatasource" matSort>
       <ng-container matColumnDef="selectCheckbox">
-        <mat-cell *matCellDef="let row" fxFlex="70px">
-          <mat-checkbox (change)="selectWorkspace(row)"
-                        [checked]="row.selected">
+        <mat-header-cell *matHeaderCellDef mat-sort-header>RO | RW | MO</mat-header-cell>
+        <mat-cell *matCellDef="let row" fxFlex="100px">
+          <mat-checkbox (change)="selectWorkspace(row, 'RO')" [checked]="row.role === 'RO'" matTooltip="RO">
+          </mat-checkbox>
+          <mat-checkbox (change)="selectWorkspace(row, 'RW')" [checked]="row.role === 'RW'" matTooltip="RW">
+          </mat-checkbox>
+          <mat-checkbox (change)="selectWorkspace(row, 'MO')" [checked]="row.role === 'MO'" matTooltip="MO">
           </mat-checkbox>
         </mat-cell>
       </ng-container>
 
       <ng-container matColumnDef="label">
+        <mat-header-cell *matHeaderCellDef mat-sort-header> Arbeitsbereich </mat-header-cell>
         <mat-cell *matCellDef="let row"> {{row.name}} </mat-cell>
       </ng-container>
 
+      <mat-header-row *matHeaderRowDef="displayedWorkspaceColumns"></mat-header-row>
       <mat-row *matRowDef="let row; columns: displayedWorkspaceColumns;"></mat-row>
     </mat-table>
   </div>
diff --git a/src/app/superadmin/users/users.component.ts b/src/app/superadmin/users/users.component.ts
index 2694d5bb..23116f79 100644
--- a/src/app/superadmin/users/users.component.ts
+++ b/src/app/superadmin/users/users.component.ts
@@ -1,8 +1,8 @@
 import { NewpasswordComponent } from './newpassword/newpassword.component';
 import { NewuserComponent } from './newuser/newuser.component';
-import { BackendService, GetUserDataResponse, IdLabelSelectedData, ServerError } from '../backend.service';
+import { BackendService, GetUserDataResponse, IdLabelSelectedData, ServerError, IdRoleData } from '../backend.service';
 import { MatTableDataSource } from '@angular/material/table';
-import { ViewChild } from '@angular/core';
+import { ViewChild, OnDestroy } from '@angular/core';
 
 import { Component, OnInit } from '@angular/core';
 import { MatSort, MatDialog, MatSnackBar } from '@angular/material';
@@ -10,13 +10,15 @@ import { FormGroup } from '@angular/forms';
 import { SelectionModel } from '@angular/cdk/collections';
 import { ConfirmDialogComponent, ConfirmDialogData, MessageDialogComponent,
   MessageDialogData, MessageType } from '../../iqb-common';
+import { Subscription } from 'rxjs';
+import { MainDataService } from 'src/app/maindata.service';
 
 
 @Component({
   templateUrl: './users.component.html',
   styleUrls: ['./users.component.css']
 })
-export class UsersComponent implements OnInit {
+export class UsersComponent implements OnInit, OnDestroy {
   private isSuperadmin = false;
   public dataLoading = false;
   public objectsDatasource: MatTableDataSource<GetUserDataResponse>;
@@ -26,13 +28,15 @@ export class UsersComponent implements OnInit {
   private selectedUser = '';
 
   private pendingWorkspaceChanges = false;
-  public WorkspacelistDatasource: MatTableDataSource<IdLabelSelectedData>;
+  public WorkspacelistDatasource: MatTableDataSource<IdRoleData>;
   public displayedWorkspaceColumns = ['selectCheckbox', 'label'];
+  private logindataSubscription: Subscription = null;
 
   @ViewChild(MatSort) sort: MatSort;
 
   constructor(
     private bs: BackendService,
+    private mds: MainDataService,
     private newuserDialog: MatDialog,
     private newpasswordDialog: MatDialog,
     private deleteConfirmDialog: MatDialog,
@@ -41,13 +45,20 @@ export class UsersComponent implements OnInit {
   ) {
     this.tableselectionRow.changed.subscribe(
       r => {
-        this.selectedUser = r.added[0].name;
+        if (r.added[0]) {
+          this.selectedUser = r.added[0].name;
+        } else {
+          this.selectedUser = '';  
+        }
         this.updateWorkspaceList();
       });
   }
 
   ngOnInit() {
-    this.updateObjectList();
+    this.logindataSubscription = this.mds.loginData$.subscribe(ld => {
+      this.isSuperadmin = ld.is_superadmin;
+      this.updateObjectList();
+    });
   }
 
   // ***********************************************************************************
@@ -162,7 +173,7 @@ export class UsersComponent implements OnInit {
                 this.updateObjectList();
                 this.dataLoading = false;
               } else {
-                this.snackBar.open('Konnte Nutzer nicht löschen', 'Fehler', {duration: 1000});
+                this.snackBar.open('Konnte Nutzer nicht löschen', 'Fehler', {duration: 2000});
                 this.dataLoading = false;
               }
           });
@@ -176,21 +187,21 @@ export class UsersComponent implements OnInit {
     this.pendingWorkspaceChanges = false;
     if (this.selectedUser.length > 0) {
       this.dataLoading = true;
-      this.bs.getWorkspacesByUser(this.selectedUser).subscribe(
-        (dataresponse: IdLabelSelectedData[]) => {
+      this.bs.getWorkspacesByUser(this.selectedUser).subscribe(dataresponse => {
           this.WorkspacelistDatasource = new MatTableDataSource(dataresponse);
           this.dataLoading = false;
-        }, (err: ServerError) => {
-          // this.ass.updateAdminStatus('', '', [], err.label);
-          this.dataLoading = false;
         });
     } else {
       this.WorkspacelistDatasource = null;
     }
   }
 
-  selectWorkspace(ws?: IdLabelSelectedData) {
-    ws.selected = !ws.selected;
+  selectWorkspace(ws: IdRoleData, role: string) {
+    if (ws.role === role) {
+      ws.role = '';
+    } else {
+      ws.role = role;
+    }
     this.pendingWorkspaceChanges = true;
   }
 
@@ -203,7 +214,7 @@ export class UsersComponent implements OnInit {
           if (respOk) {
             this.snackBar.open('Zugriffsrechte geändert', '', {duration: 1000});
           } else {
-            this.snackBar.open('Konnte Zugriffsrechte nicht ändern', 'Fehler', {duration: 1000});
+            this.snackBar.open('Konnte Zugriffsrechte nicht ändern', 'Fehler', {duration: 2000});
           }
           this.dataLoading = false;
         });
@@ -216,17 +227,11 @@ export class UsersComponent implements OnInit {
   updateObjectList() {
     if (this.isSuperadmin) {
       this.dataLoading = true;
-      this.bs.getUsers().subscribe(
-        (dataresponse: GetUserDataResponse[]) => {
+      this.tableselectionCheckbox.clear();
+      this.tableselectionRow.clear();
+      this.bs.getUsers().subscribe(dataresponse => {
           this.objectsDatasource = new MatTableDataSource(dataresponse);
           this.objectsDatasource.sort = this.sort;
-          this.tableselectionCheckbox.clear();
-          this.tableselectionRow.clear();
-          this.dataLoading = false;
-        }, (err: ServerError) => {
-          // this.ass.updateAdminStatus('', '', [], err.label);
-          this.tableselectionCheckbox.clear();
-          this.tableselectionRow.clear();
           this.dataLoading = false;
         }
       );
@@ -248,4 +253,11 @@ export class UsersComponent implements OnInit {
   selectRow(row) {
     this.tableselectionRow.select(row);
   }
+
+  // % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % %
+  ngOnDestroy() {
+    if (this.logindataSubscription !== null) {
+      this.logindataSubscription.unsubscribe();
+    }
+  }
 }
diff --git a/src/app/superadmin/workspaces/workspaces.component.css b/src/app/superadmin/workspaces/workspaces.component.css
index e69de29b..fcdebc3d 100644
--- a/src/app/superadmin/workspaces/workspaces.component.css
+++ b/src/app/superadmin/workspaces/workspaces.component.css
@@ -0,0 +1,4 @@
+.mat-raised-button {
+    min-width: 100px;
+    margin: 2px;
+}
\ No newline at end of file
diff --git a/src/app/superadmin/workspaces/workspaces.component.ts b/src/app/superadmin/workspaces/workspaces.component.ts
index f8f45976..dde219e9 100644
--- a/src/app/superadmin/workspaces/workspaces.component.ts
+++ b/src/app/superadmin/workspaces/workspaces.component.ts
@@ -4,7 +4,6 @@ import { BackendService, GetUserDataResponse, IdLabelSelectedData, ServerError }
 import { MatTableDataSource } from '@angular/material/table';
 import { ViewChild } from '@angular/core';
 
-import { DatastoreService } from '../datastore.service';
 import { Component, OnInit } from '@angular/core';
 import { MatSort, MatDialog, MatSnackBar } from '@angular/material';
 import { FormGroup } from '@angular/forms';
diff --git a/src/app/workspace/workspace.component.css b/src/app/workspace/workspace.component.css
index c695d220..b6162710 100644
--- a/src/app/workspace/workspace.component.css
+++ b/src/app/workspace/workspace.component.css
@@ -33,8 +33,3 @@ mat-toolbar {
   margin: 15px;
   padding: 25px;
 }
-
-.communication-error-message {
-  color: red;
-  padding: 10px 50px;
-}
-- 
GitLab