Edit Developers
MODIFY
src/app/admin/create-developer/client-mapping.component.html
src/app/admin/create-developer/client-mapping.component.html
[cdkDropListConnectedTo]="[assignedClientList]"
class="client-list"
(cdkDropListDropped)="drop($event)">
- <div class="client-box" *ngFor="let item of availableClients" cdkDrag>{{item.organizationName}}/{{item.name}}</div>
- <div class="client-box" id="emptyClientInformation" *ngIf="availableClients.length === 0">No clients there, use API-Mgmt to create some.</div>
+ <div class="client-box" *ngFor="let item of availableClients" cdkDrag>{{item.organizationId}}/{{item.clientId}}</div>
+ <div class="client-box" id="emptyClientInformation" *ngIf="availableClients && availableClients.length === 0">No clients there, use API-Mgmt to create some.</div>
</div>
</div>
[cdkDropListConnectedTo]="[availableClientList]"
class="client-list"
(cdkDropListDropped)="drop($event)">
- <div class="client-box" *ngFor="let item of assignedClients" cdkDrag>{{item.organizationName}}/{{item.name}}</div>
- <div id="dragClientInformation" class="client-box" *ngIf="assignedClients.length === 0"><span>Drag&Drop available clients here</span></div>
+ <div class="client-box" *ngFor="let item of assignedClients" cdkDrag>{{item.organizationId}}/{{item.clientId}}</div>
+ <div id="dragClientInformation" class="client-box" *ngIf="assignedClients && assignedClients.length === 0"><span>Drag&Drop available clients here</span></div>
</div>
</div>

MODIFY
src/app/admin/create-developer/client-mapping.component.ts
src/app/admin/create-developer/client-mapping.component.ts
-import {Component, OnInit, Output} from '@angular/core';
+import {Component, OnInit, Input, Output} from '@angular/core';
import {CdkDragDrop, moveItemInArray, transferArrayItem} from '@angular/cdk/drag-drop';
-import {ApiDataService, ClientBean} from '../../api-data.service';
-import {mergeAll} from 'rxjs/operators';
+import {ApiDataService, ClientBean, ClientMapping} from '../../api-data.service';
+import {map, mergeAll, mergeMap} from 'rxjs/operators';
@Component({
selector: 'app-client-mapping',
@@ -12,27 +12,32 @@ export class ClientMappingComponent implements OnInit {
constructor(private apiDataService: ApiDataService) { }
- availableClients: Array<ClientBean> = [];
+ availableClients: Array<ClientMapping> = [];
- @Output('assignedClients') assignedClients: Array<ClientBean> = [];
+ @Input('assignedClients') assignedClients: Array<ClientMapping> = [];
ngOnInit() {
this.loadClients();
}
loadClients() {
- this.availableClients = [];
- this.apiDataService.getAllClients().subscribe(client => {
- this.availableClients.push(client);
+ const loadedAvailableClients = [];
+ this.apiDataService.getAllClients().pipe(map(client => {
+ if (this.assignedClients && !this.assignedClients.find((c => c.organizationId === client.organizationId && c.clientId === client.id))) {
+ loadedAvailableClients.push({
+ clientId: client.id,
+ organizationId: client.organizationId
});
}
+ })).subscribe(ready => this.availableClients = loadedAvailableClients);
+ }
reset() {
this.loadClients();
this.assignedClients = [];
}
- drop(event: CdkDragDrop<ClientBean[]>) {
+ drop(event: CdkDragDrop<ClientMapping[]>) {
if (event.previousContainer === event.container) {
moveItemInArray(event.container.data, event.previousIndex, event.currentIndex);
} else {

MODIFY
src/app/admin/create-developer/create-developer.component.html
src/app/admin/create-developer/create-developer.component.html
<h1>Create Developer</h1>
<div class="wrapper">
- <form [formGroup]="userFormGroup">
+ <form id="userForm" [formGroup]="userFormGroup">
<mat-form-field class="input-form-field">
<input matInput placeholder="Username" formControlName="username" (input)="checkPasswordRequired($event.target.value)" required>
</mat-form-field>
+ <span [hidden]="isPasswordRequiredForInsert">(You create a Developer for an existing API-Mgmt user.)</span>
+ <span [hidden]="!isPasswordRequiredForInsert">
+ <mat-form-field class="input-form-field">
+ <!-- use attr.disabled here because of formGroup: https://angular.io/guide/template-syntax -->
+ <input id="passwordField" matInput placeholder="Password" type="password" formControlName="password" [required]="isPasswordRequiredForInsert" [attr.disabled]="!isPasswordRequiredForInsert ? 'disabled' : null">
+ </mat-form-field>
<mat-form-field class="input-form-field">
<input matInput placeholder="First name" formControlName="firstname">
</mat-form-field>
<mat-form-field class="input-form-field">
<input matInput placeholder="Email" formControlName="email">
</mat-form-field>
- <mat-form-field class="input-form-field">
- <!-- use attr.disabled here because of formGroup: https://angular.io/guide/template-syntax -->
- <input id="passwordField" matInput placeholder="Password" type="password" formControlName="password" [required]="isPasswordRequiredForInsert" [attr.disabled]="!isPasswordRequiredForInsert ? 'disabled' : null">
- </mat-form-field>
+ </span>
</form>
<br/>

MODIFY
src/app/admin/create-developer/create-developer.component.scss
src/app/admin/create-developer/create-developer.component.scss
width: 100%;
}
+#userForm {
+ min-height: 130px;
+}
+
::ng-deep .mat-form-field.mat-focused .mat-form-field-label {
color: black!important;
}

MODIFY
src/app/admin/create-developer/create-developer.component.ts
src/app/admin/create-developer/create-developer.component.ts
@@ -37,7 +37,7 @@ export class CreateDeveloperComponent {
developerToCreate.name = this.userFormGroup.get('username').value;
developerToCreate.clients = [];
this.clientMapping.assignedClients.forEach(client => {
- developerToCreate.clients.push(new ClientMappingImpl(client.id, client.organizationName));
+ developerToCreate.clients.push(new ClientMappingImpl(client.clientId, client.organizationId));
});
const keycloakUserToCreate = new KeycloakUserImpl();

MODIFY
src/app/admin/developer-list.component.html
src/app/admin/developer-list.component.html
<mat-nav-list>
- <mat-list-item *ngFor="let developer of developers"> {{ developer.name }}
+ <mat-list-item *ngFor="let developer of developers">
+ {{ developer.name }}
<span *ngIf="developer.clients.length > 0">(</span>
<div class="developer-list-client-list" *ngFor="let client of developer.clients"> {{client.organizationId}}/{{client.clientId}}</div>
<span *ngIf="developer.clients.length > 0">)</span>
+ <mat-icon [routerLink]="['/admin/edit/developer', developer.id]">edit</mat-icon>
<mat-icon class="deleteIcon" (click)="deleteDeveloper(developer)">delete</mat-icon>
</mat-list-item>
- <mat-list-item *ngIf="developers.length === 0">No developers there, click button above to create one.</mat-list-item>
+ <mat-list-item *ngIf="!developers || developers.length === 0">No developers there, click button above to create one.</mat-list-item>
</mat-nav-list>

MODIFY
src/app/admin/developer-list.component.ts
src/app/admin/developer-list.component.ts
@@ -18,8 +18,11 @@ export class DeveloperListComponent implements OnInit {
}
public load() {
- this.apiDataService.getAllDevelopers().pipe(mergeAll()).subscribe((developers) => {
- this.developers.push(developers);
+ console.log('start loading developers');
+ this.developers = [];
+ this.apiDataService.getAllDevelopers().subscribe((developers) => {
+ console.log('Developer', developers);
+ this.developers = developers;
});
}

ADD
src/app/admin/edit-developer/edit-developer.component.html
+<h1>Edit Developer {{developerId}}</h1>
+
+<div class="wrapper">
+ <app-client-mapping #clientmapping [assignedClients]="assignedClients"></app-client-mapping>
+ <button [disabled]="clientMapping && clientMapping.assignedClients && clientMapping.assignedClients.length === 0" (click)="updateDeveloper()">Save</button>
+ <button routerLink="/admin">Cancel</button>
+</div>

ADD
src/app/admin/edit-developer/edit-developer.component.scss
+.wrapper {
+ min-width: 150px;
+ max-width: 600px;
+ width: 100%;
+}

ADD
src/app/admin/edit-developer/edit-developer.component.spec.ts
+import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { EditDeveloperComponent } from './edit-developer.component';
+
+describe('EditDeveloperComponent', () => {
+ let component: EditDeveloperComponent;
+ let fixture: ComponentFixture<EditDeveloperComponent>;
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ declarations: [ EditDeveloperComponent ]
+ })
+ .compileComponents();
+ }));
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(EditDeveloperComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});

ADD
src/app/admin/edit-developer/edit-developer.component.ts
+import {Component, OnInit, ViewChild} from '@angular/core';
+import {ActivatedRoute, Router} from '@angular/router';
+import {ApiDataService, Developer} from '../../api-data.service';
+import { ClientMappingComponent } from '../create-developer/client-mapping.component';
+import {timeInterval} from 'rxjs/operators';
+
+@Component({
+ selector: 'app-edit-developer',
+ templateUrl: './edit-developer.component.html',
+ styleUrls: ['./edit-developer.component.scss']
+})
+export class EditDeveloperComponent implements OnInit {
+
+ private developerId;
+ private developer: Developer;
+ public assignedClients;
+
+ @ViewChild('clientmapping', {static: false}) clientMapping: ClientMappingComponent;
+
+ constructor(private apiDataService: ApiDataService, private route: ActivatedRoute, private router: Router) { }
+
+ ngOnInit() {
+ this.developerId = this.route.snapshot.paramMap.get('developerId');
+ this.apiDataService.getDeveloper(this.developerId).subscribe(developer => {
+ this.developer = developer;
+ this.assignedClients = developer.clients;
+ this.clientMapping.loadClients();
+ });
+ }
+
+ updateDeveloper() {
+ if (this.developer && this.clientMapping.assignedClients.length > 0) {
+ return this.apiDataService.updateDeveloper(this.developer).subscribe(() => {
+ console.log('Update Developer done');
+ setTimeout(() => this.router.navigate(['/admin']), 500);
+ });
+ }
+ }
+
+}

MODIFY
src/app/api-data.service.ts
src/app/api-data.service.ts
@@ -201,6 +201,15 @@ export class ApiDataService {
// })));
}
+ /**
+ * Get developer by developer id
+ * @param developerId The developer id
+ */
+ public getDeveloper(developerId: string) {
+ const url = this.apimanUiRestUrl + '/developers/' + developerId;
+ return this.http.get(url) as Observable<Developer>;
+ }
+
/**
* Get developer clients by developer id
* @param developerId The developer Id
@@ -342,8 +351,11 @@ export class ApiDataService {
* @param developer the developer to update
*/
public updateDeveloper(developer: Developer) {
- const url = this.apimanUiRestUrl + '/developers';
- return this.http.put(url, developer);
+ const url = this.apimanUiRestUrl + '/developers/' + developer.id;
+ return this.http.put(url, {
+ name: developer.name,
+ clients: developer.clients
+ });
}
private isUserGeneratedFromDevPortal(user: UserRepresentation) {

MODIFY
src/app/app-init.ts
src/app/app-init.ts
@@ -12,14 +12,14 @@ export function initializer(keycloak: KeycloakService): () => Promise<any> {
initOptions: {
onLoad: 'login-required',
checkLoginIframe: false,
- token: localStorage.getItem('apiman_keycloak_token'),
- refreshToken: localStorage.getItem('apiman_keycloak_refresh_token')
+ token: sessionStorage.getItem('apiman_keycloak_token'),
+ refreshToken: sessionStorage.getItem('apiman_keycloak_refresh_token')
},
enableBearerInterceptor: true,
bearerExcludedUrls: ['/assets', '/clients/public']
}).then(success => {
const keycloakInstance = keycloak.getKeycloakInstance();
- localStorage.setItem('apiman_keycloak_token', keycloakInstance.token);
- localStorage.setItem('apiman_keycloak_refresh_token', keycloakInstance.refreshToken);
+ sessionStorage.setItem('apiman_keycloak_token', keycloakInstance.token);
+ sessionStorage.setItem('apiman_keycloak_refresh_token', keycloakInstance.refreshToken);
});
}

MODIFY
src/app/app-routing.module.ts
src/app/app-routing.module.ts
@@ -3,11 +3,13 @@ import { Routes, RouterModule } from '@angular/router';
import { AdminComponent } from './admin/admin.component';
import {DeveloperComponent} from './developer/developer.component';
import {CreateDeveloperComponent} from './admin/create-developer/create-developer.component';
+import {EditDeveloperComponent} from './admin/edit-developer/edit-developer.component';
const routes: Routes = [
{ path: '', component: DeveloperComponent },
{ path: 'admin', component: AdminComponent },
- { path: 'admin/create/developer', component: CreateDeveloperComponent }
+ { path: 'admin/create/developer', component: CreateDeveloperComponent },
+ { path: 'admin/edit/developer/:developerId', component: EditDeveloperComponent}
];
@NgModule({

MODIFY
src/app/app.module.ts
src/app/app.module.ts
@@ -24,8 +24,8 @@ import { DeveloperListComponent } from './admin/developer-list.component';
import { CreateDeveloperComponent } from './admin/create-developer/create-developer.component';
import { ClientMappingComponent } from './admin/create-developer/client-mapping.component';
import { DragDropModule } from '@angular/cdk/drag-drop';
-import { MatButtonModule } from '@angular/material';
-import { MatInputModule } from '@angular/material';
+import { MatButtonModule, MatInputModule } from '@angular/material';
+import { EditDeveloperComponent } from './admin/edit-developer/edit-developer.component';
@NgModule({
@@ -37,7 +37,8 @@ import { MatInputModule } from '@angular/material';
DeveloperComponent,
DeveloperListComponent,
CreateDeveloperComponent,
- ClientMappingComponent
+ ClientMappingComponent,
+ EditDeveloperComponent
],
imports: [
BrowserModule,

MODIFY
src/app/pas-header/pas-header.component.ts
src/app/pas-header/pas-header.component.ts
@@ -16,8 +16,8 @@ export class PasHeaderComponent implements OnInit {
}
public logout() {
- localStorage.setItem('apiman_keycloak_token', '');
- localStorage.setItem('apiman_keycloak_refresh_token', '');
+ sessionStorage.setItem('apiman_keycloak_token', '');
+ sessionStorage.setItem('apiman_keycloak_refresh_token', '');
this.keycloak.getKeycloakInstance().logout();
}

GW-263: Edit Developers