Changes we've to do in the fronend
The following files have to be changed or created:
fileupload.component.css
.button {
overflow: hidden;
position: relative;
background-color: #212121;
color: whitesmoke;
padding: 0.5em;
}
.button [type=file] {
cursor: inherit;
display: inline-block;
font-size: 999px;
filter: alpha(opacity=0);
min-height: 100%;
min-width: 100%;
opacity: 0;
position: absolute;
right: 0;
text-align: right;
top: 0;
}
fileupload.component.html
<label class="button">
Upload...
<input
type="file"
(change)="upload($event)"
[multiple]="multiple"/>
</label>
fileupload.component.ts
import {Component, Input, Output, EventEmitter} from "@angular/core";
import {Headers, Http, RequestOptions} from "@angular/http";
import {UserService} from "../users/users.service";
import {User} from "../users/user";
@Component({
selector: 'file-upload',
templateUrl: './fileupload.component.html',
styleUrls: ['./fileupload.component.css']
})
export class FileUploadComponent {
@Input()
multiple: boolean = false;
@Input()
url: string = "";
@Output()
notify: EventEmitter<string> = new EventEmitter<string>();
constructor(private http: Http, private service: UserService) {
}
public upload = (event: EventTarget) => {
let _self = this;
window['_keycloak']
.loadUserInfo()
.success(function (userInfo) {
_self.uploadWithUserId(userInfo.sub, _self.url, event);
});
};
public uploadWithUserId = (userId: string, url: string, event: EventTarget) => {
let eventObj: MSInputMethodContext = <MSInputMethodContext> event;
let target: HTMLInputElement = <HTMLInputElement> eventObj.target;
let files: FileList = target.files;
let fileCount: number = files.length;
let formData = new FormData();
if (fileCount > 0) {
for (let i = 0; i < fileCount; i++) {
let fileUrl = '/battleapp/users/' + userId + '/profilepicture';
formData.append(fileUrl, files.item(i));
}
let token = window['_keycloak'].token;
let headers = new Headers();
headers.append('Authorization', 'Bearer ' + token);
let options = new RequestOptions({headers: headers});
this.http
.post(url, formData, options)
.map(res => res.json())
.subscribe((data: any) => {
for (var arrayKey in data) {
for (var key in data[arrayKey]) {
var value = data[arrayKey][key];
let user: User = new User(userId, undefined, undefined, undefined, value);
this.service
.update(userId, user)
.subscribe((updatedUser: User) => {
this.notify.emit(updatedUser.profilePicture);
},
error => console.log('ERROR: ' + error)
);
}
}
},
error => console.log('ERROR: ' + error)
);
}
}
}
profile.component.css
md-card img {
max-width: 90%;
max-height: 300px;
height: auto;
width: auto;
margin: 1em auto;
display: block;
}
md-card {
max-width: 600px;
}
profile.component.html
<md-card>
<md-card-header>
<md-card-title>{{ user.nickname }}</md-card-title>
<md-card-subtitle>{{ user.firstName + ' ' + user.lastName }}</md-card-subtitle>
</md-card-header>
<img md-card-image src="{{ user.profilePicture }}">
<md-card-content>
<p>Upload a profile picture!</p>
<file-upload
(notify)="onUploadFinished($event)"
[multiple]="true"
[url]="getProfilePicture()"></file-upload>
</md-card-content>
</md-card>
profile.component.ts
import {UserService} from "../users/users.service";
import {Component} from "@angular/core";
import {User} from "../users/user";
import {Observable} from "rxjs";
import {Http} from "@angular/http";
@Component({
selector: 'profile',
templateUrl: './profile.component.html',
styleUrls: ['./profile.component.css'],
providers: [UserService]
})
export class ProfileComponent {
private user: User = new User(undefined, undefined, undefined, undefined, undefined);
private environment: Observable<any>;
public url: string = "";
constructor(private http: Http, private service: UserService) {
this.environment = this.http
.get('/environment/environment.json')
.map(res => res.json());
this.http
.get('/environment/environment.json')
.map(res => res.json())
.subscribe((env: any) => {
this.url = this.getFileuploaderUrl(env);
});
}
ngOnInit() {
this.getUser();
}
public getProfilePicture = () => {
return this.url;
};
public getFileuploaderUrl = (env: any): string => {
return 'http://' + env.host + ':' + env.fileuploader_port + '/battleapp/fileupload';
};
private getUser = () => {
let _self = this;
window['_keycloak']
.loadUserInfo()
.success(function (userInfo) {
_self.service
.find(userInfo.sub)
.subscribe((responseUser: User) => {
_self.loadUser(responseUser);
},
error => console.log(error)
);
});
};
public loadUser = (responseUser: User): void => {
this.user = new User(
responseUser.id,
responseUser.nickname,
responseUser.firstName,
responseUser.lastName,
undefined);
this.service
.getFullProfilePictureUrl(responseUser.profilePicture)
.subscribe((fullUrlArray: string) => {
this.user.profilePicture = fullUrlArray;
},
error => console.log(error)
);
};
public onUploadFinished = (profilePicture: string): void => {
this.service
.getFullProfilePictureUrl(profilePicture)
.subscribe((fullUrlArray: string) => {
this.user.profilePicture = fullUrlArray;
},
error => console.log(error)
);
};
}
app.module.ts
...
import {FileUploadComponent} from "./fileupload/fileupload.component";
import {ProfileComponent} from "./profile/profile.component";
...
declarations: [
AppComponent,
UserComponent,
ProfileComponent,
NoContentComponent,
FileUploadComponent
],
...
environment.json
{
"host": "localhost",
"command_port": 8083,
"query_port": 8082,
"fileuploader_port": 8084,
"filedownloader_port": 8085
}
user.ts
export class User {
public id: string;
public nickname: string;
public firstName: string;
public lastName: string;
public profilePicture: string;
constructor(id: string,
nickname: string,
firstName: string,
lastName: string,
profilePicture: string) {
this.id = id;
this.nickname = nickname;
this.firstName = firstName;
this.lastName = lastName;
this.profilePicture = profilePicture;
}
public toString = (): string => {
return 'id: ' + this.id
+ ', nickname: ' + this.nickname
+ ', firstName: ' + this.firstName
+ ', lastName: ' + this.lastName
+ ', profilePicture: ' + this.profilePicture;
}
}
app.component.html
...
<p>
<a [routerLink]=" ['./profile'] " (click)="sidenav.toggle()">
Profile
</a>
</p>
...
app.routes.ts
...
import {ProfileComponent} from "./profile/profile.component";
...
export const ROUTES: Routes = [
{path: '', component: ProfileComponent},
{path: 'profile', component: ProfileComponent},
{path: 'users', component: UserComponent},
{path: '**', component: NoContentComponent},
];
...
We've to add the two new ports to the Kubernetes configmap of the environment.json
:
{
"host": "disruptor.ninja",
"command_port": 30080,
"query_port": 30081,
"fileuploader_port": 30082,
"filedownloader_port": 30031
}
And the same for the test configmap:
{
"host": "disruptor.ninja",
"command_port": 31080,
"query_port": 31081,
"fileuploader_port": 31082,
"filedownloader_port": 31031
}