Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
feudal
feudalWebpage
Commits
2ce5f255
Commit
2ce5f255
authored
May 16, 2018
by
Lukas Burgey
Browse files
Change display of live updates
parent
b717a992
Changes
10
Hide whitespace changes
Inline
Side-by-side
src/app/account/account.component.html
View file @
2ce5f255
<p>
You can delete your account. All deployments will be withdrawn if you choose to do so.
<p
class=
"mat-body-1"
>
You can delete your account. All deployments will be withdrawn if you choose to do so.
</p>
<p
class=
"mat-body-2"
>
<mat-checkbox
[(ngModel)]=
"sure"
style=
"margin-right: 8px"
[checked]=
"sure"
>
</mat-checkbox>
I'm sure I want to delete all my data on the server.
<p>
<mat-checkbox
[(ngModel)]=
"sure"
style=
"margin-right: 8px"
[checked]=
"sure"
>
I'm sure I want to delete all my data on the server.
</mat-checkbox>
<button
mat-raised-button
mat-dialog-close
color=
"primary"
(click)=
"delete()"
[disabled]=
"!sure"
>
Delete
</button>
<button
mat-raised-button
mat-dialog-close
color=
"primary"
(click)=
"delete()"
[disabled]=
"!sure"
>
Delete
</button>
</p>
src/app/app.component.html
View file @
2ce5f255
<mat-toolbar
color=
"primary"
>
<span>
Federated User Credential Deployment Portal
</span>
<span
class=
"toolbar-spacer"
></span>
<app-login></app-login>
<mat-toolbar
color=
"primary"
class=
"mat-typography"
>
<mat-toolbar-row>
<h1>
Federated User Credential Deployment Portal
</h1>
</mat-toolbar-row>
<mat-toolbar-row>
<app-login></app-login>
</mat-toolbar-row>
</mat-toolbar>
<div
class=
"outer"
>
<div
class=
"inner"
>
...
...
src/app/app.module.ts
View file @
2ce5f255
...
...
@@ -2,7 +2,6 @@ import {BrowserModule} from '@angular/platform-browser';
import
{
BrowserAnimationsModule
}
from
'
@angular/platform-browser/animations
'
;
import
{
NgModule
}
from
'
@angular/core
'
;
import
{
FormsModule
}
from
'
@angular/forms
'
;
import
{
RouterModule
}
from
'
@angular/router
'
;
import
{
JsonPipe
}
from
'
@angular/common
'
;
import
{
HttpModule
}
from
'
@angular/http
'
;
import
{
HttpClientModule
,
HttpClientXsrfModule
}
from
'
@angular/common/http
'
;
...
...
@@ -19,6 +18,8 @@ import {MatSelectModule} from '@angular/material/select';
import
{
MatInputModule
}
from
'
@angular/material/input
'
;
import
{
MatCheckboxModule
}
from
'
@angular/material/checkbox
'
;
import
{
MatTooltipModule
}
from
'
@angular/material/tooltip
'
;
import
{
MatProgressBarModule
}
from
'
@angular/material/progress-bar
'
;
import
{
MatProgressSpinnerModule
}
from
'
@angular/material/progress-spinner
'
;
// Other libs
import
{
StompRService
}
from
'
@stomp/ng2-stompjs
'
;
...
...
@@ -58,11 +59,6 @@ import {AccountComponent} from './account/account.component';
cookieName
:
'
csrftoken
'
,
headerName
:
'
HTTP_X_CSRFTOKEN
'
,
}),
/*
RouterModule.forRoot(
routes,
),
*/
MatButtonModule
,
MatToolbarModule
,
MatTableModule
,
...
...
@@ -75,6 +71,8 @@ import {AccountComponent} from './account/account.component';
MatInputModule
,
MatCheckboxModule
,
MatTooltipModule
,
MatProgressBarModule
,
MatProgressSpinnerModule
,
],
providers
:
[
CookieService
,
...
...
src/app/login/login.component.html
View file @
2ce5f255
<span
*ngIf=
"userService.loggedIn ? false : true"
>
<form
*ngIf=
"idps"
<span
class=
".row-fill-remaining-space"
></span>
<span>
<span
*ngIf=
"userService.loggedIn ? false : true"
>
<form
*ngIf=
"idps"
(ngSubmit)=
"userService.login(selectedIdP)"
#loginForm
="
ngForm
"
>
<mat-form-field>
<mat-select
name=
"idp"
required
[(ngModel)]=
"selectedIdP"
>
<mat-option
*ngFor=
"let idp of idps"
[value]=
"idp"
>
{{ idp.name }}
</mat-option>
</mat-select>
</mat-form-field>
<button
mat-raised-button
[disabled]=
"!loginForm.form.valid"
color=
"accent"
type=
"submit"
>
Login
</button>
</form>
</span>
<span
*ngIf=
"userService.loggedIn"
>
<button
mat-button
mat-icon-button
(click)=
"dialog.openAccount()"
>
<mat-icon>
settings
</mat-icon>
</button>
<button
mat-button
mat-icon-button
(click)=
"dialog.openSshKeys()"
>
<mat-icon>
vpn_key
</mat-icon>
</button>
<button
mat-button
(click)=
"dialog.openProfile()"
>
{{ userService.user?.email }}
</button>
<button
mat-raised-button
color=
"accent"
(click)=
"userService.logout()"
>
Logout
</button>
<mat-form-field>
<mat-select
name=
"idp"
required
[(ngModel)]=
"selectedIdP"
>
<mat-option
*ngFor=
"let idp of idps"
[value]=
"idp"
>
{{ idp.name }}
</mat-option>
</mat-select>
</mat-form-field>
<button
mat-raised-button
[disabled]=
"!loginForm.form.valid"
color=
"accent"
type=
"submit"
>
Login
</button>
</form>
</span>
<span
*ngIf=
"userService.loggedIn"
>
<button
mat-button
mat-icon-button
(click)=
"dialog.openAccount()"
>
<mat-icon>
settings
</mat-icon>
</button>
<button
mat-button
mat-icon-button
(click)=
"dialog.openSshKeys()"
>
<mat-icon>
vpn_key
</mat-icon>
</button>
<button
mat-button
(click)=
"dialog.openProfile()"
>
{{ userService.user?.email }}
</button>
<button
mat-raised-button
color=
"accent"
(click)=
"userService.logout()"
>
Logout
</button>
</span>
</span>
src/app/mgmt/mgmt.component.html
View file @
2ce5f255
<div
*ngIf=
"userService.loggedIn"
>
<div>
<h
4
>
Services
</h
4
>
<div
class=
"mat-typography"
>
<h
2
>
Services
</h
2
>
<div
*ngIf=
"userService.services.length > 0"
>
<mat-accordion>
<app-service
*ngFor=
"let service of userService.services"
...
...
@@ -16,7 +16,15 @@
<h4>
Uncompleted tasks
</h4>
<div>
<p
*ngFor=
"let task of userService.user.deployment_tasks"
>
{{ task.action }}: {{ task.key }}
{{ task | json }}
</p>
</div>
</div>
<div
*ngIf=
"userService.messages.length > 0"
>
<h4>
Messages
</h4>
<div>
<p
*ngFor=
"let message of userService.messages"
>
{{ message }}
</p>
</div>
</div>
...
...
src/app/service/service.component.html
View file @
2ce5f255
<mat-expansion-panel>
<mat-expansion-panel
*ngIf=
"serviceData"
>
<mat-expansion-panel-header>
<mat-panel-title>
{{ serviceData.name }}
</mat-panel-title>
<mat-panel-title>
{{ serviceData.name }}
</mat-panel-title>
<mat-panel-description>
{{ serviceData.description }}
</mat-panel-description>
</mat-expansion-panel-header>
<div
style=
"padding-bottom: 10px;"
>
<span
style=
"padding-right: 35px;"
*ngFor=
"let site of serviceData.site"
matTooltip=
"Provided at site {{ site.name }}"
>
<mat-icon
style=
"vertical-align: middle; padding-right: 5px;"
>
storage
</mat-icon>
{{ site.name }}
</span>
</div>
<div>
<span
style=
"padding-right: 35px;"
*ngFor=
"let group of serviceData.groups"
matTooltip=
"Can be used with membership of group {{ group.name }}"
>
<mat-icon
style=
"vertical-align: middle; padding-right: 5px;"
>
lock outline
</mat-icon>
{{ group.name }}
</span>
</div>
<table
width=
"60%"
>
<tr
style=
"margin-bottom: 15px;"
>
<td
*ngFor=
"let site of serviceData.site"
>
<span
matTooltip=
"Provided at site {{ site.name }}"
>
<mat-icon
style=
"vertical-align: middle; padding-right: 5px;"
>
storage
</mat-icon>
{{ site.name }}
</span>
<span
*ngIf=
"userService.taskInProgress(site, serviceData); then progress else done"
></span>
<ng-template
#progress
matTooltip=
"A task is in progress"
>
<span
style=
"display: inline-block; vertical-align: middle"
>
<mat-progress-spinner
diameter=
"24"
mode=
"indeterminate"
></mat-progress-spinner>
</span>
</ng-template>
<ng-template
#done
>
<span
matTooltip=
"All tasks are done"
>
<mat-icon
style=
"vertical-align: middle"
>
done
</mat-icon>
</span>
</ng-template>
</td>
</tr>
<tr>
<td
style=
"padding-right: 35px;"
*ngFor=
"let group of serviceData.groups"
matTooltip=
"Can be used with membership of group {{ group.name }}"
>
<mat-icon
style=
"vertical-align: middle; padding-right: 5px;"
>
lock outline
</mat-icon>
{{ group.name }}
</td>
</tr>
</table>
<mat-action-row>
<div
*ngIf=
"userService.user.ssh_keys.length > 0"
>
<div
*ngIf=
"userService.user.ssh_keys.length > 0; then boxes else upload"
></div>
<ng-template
#boxes
>
<span
style=
"margin-right: 15px;"
>
Deployed k
eys:
</span>
<br/>
SSH K
eys:
</span>
<mat-checkbox
*ngFor=
"let key of userService.user.ssh_keys"
style=
"margin-right: 8px"
[checked]=
"isDeployed(key)"
(change)=
"deploymentChange(key)"
>
{{ key.name }}
</mat-checkbox>
</div>
<div
*ngIf=
"userService.user.ssh_keys.length === 0"
>
</ng-template>
<ng-template
#upload
>
<span
style=
"margin-right: 15px;"
>
Please upload an SSH Key to use this service:
</span>
<button
mat-icon-button
(click)=
"dialog.openSshKeys()"
><mat-icon>
vpn_key
</mat-icon></button>
</
div
>
</
ng-template
>
</mat-action-row>
</mat-expansion-panel>
src/app/snackbar.service.ts
View file @
2ce5f255
...
...
@@ -13,6 +13,7 @@ export class SnackBarService {
}
public
open
(
message
:
string
)
{
console
.
log
(
message
);
return
this
.
snackBar
.
open
(
message
,
''
,
this
.
config
);
}
...
...
src/app/ssh-keys/ssh-keys.component.html
View file @
2ce5f255
<div
style=
"margin-bottom: 25px;"
>
<mat-table
*ngIf=
"userService.user.ssh_keys"
[dataSource]=
"userService.sshKeyData"
>
<div
*ngIf=
"userService.user.ssh_keys.length > 0; then key_list else upload_note"
></div>
</div>
<div
*ngIf=
"upload; then uploading else not_uploading"
></div>
<ng-template
#key_list
>
<mat-table
[dataSource]=
"userService.sshKeyData"
>
<ng-container
matColumnDef=
"name"
>
<mat-header-cell
*matHeaderCellDef
>
Name
</mat-header-cell>
<mat-cell
*matCellDef=
"let element"
>
{{ element.name}}
</mat-cell>
...
...
@@ -11,20 +15,24 @@
<ng-container
matColumnDef=
"action"
>
<mat-header-cell
*matHeaderCellDef
>
Action
</mat-header-cell>
<mat-cell
*matCellDef=
"let element"
>
<button
mat-icon-button
(click)=
"deleteKey(element)"
><mat-icon>
delete_forever
</mat-icon></button>
<button
mat-icon-button
(click)=
"deleteKey(element)"
>
<mat-icon>
delete_forever
</mat-icon>
</button>
</mat-cell>
</ng-container>
<mat-header-row
*matHeaderRowDef=
"columns"
></mat-header-row>
<mat-row
*matRowDef=
"let row; columns: columns;"
></mat-row>
</mat-table>
<p
*ngIf=
"!userService.user.ssh_keys"
>
</ng-template>
<ng-template
#upload_note
>
<p>
You have no uploaded keys.
</p>
</
div
>
<
div
*ngIf=
"!
upload
"
>
</
ng-template
>
<
ng-template
#
upload
ing
>
<button
mat-icon-button
(click)=
"upload = true"
><mat-icon>
add
</mat-icon></button>
</
div
>
<
div
*ngIf=
"upload"
class=
"form-container"
>
</
ng-template
>
<
ng-template
#not_uploading
>
<form
(ngSubmit)=
"uploadKey()"
#sshKeyForm
="
ngForm
"
>
<mat-form-field>
<input
matInput
placeholder=
"Name"
required
[(ngModel)]=
"newKeyName"
name=
"name"
>
...
...
@@ -34,4 +42,4 @@
</mat-form-field>
<button
mat-raised-button
color=
"primary"
type=
"submit"
[disabled]=
"!sshKeyForm.form.valid"
>
Submit
</button>
</form>
</
div
>
</
ng-template
>
src/app/types/types.module.ts
View file @
2ce5f255
...
...
@@ -47,6 +47,8 @@ export interface User {
userinfo
:
any
;
ssh_keys
:
SSHKey
[];
deployments
:
Deployment
[];
deployment_tasks
:
any
[];
deployment_task_items
:
any
[];
id
:
number
;
}
...
...
src/app/user.service.ts
View file @
2ce5f255
import
{
Injectable
}
from
'
@angular/core
'
;
import
{
HttpClient
,
HttpErrorResponse
}
from
'
@angular/common/http
'
;
import
{
Observable
}
from
'
rxjs/Observable
'
;
import
'
rxjs/add/operator/map
'
;
import
'
rxjs/add/operator/catch
'
;
import
'
rxjs/add/observable/of
'
;
import
{
CookieService
}
from
'
ngx-cookie-service
'
;
import
{
MatTableDataSource
}
from
'
@angular/material
'
;
import
{
of
as
observableOf
,
Observable
}
from
'
rxjs
'
;
import
{
SnackBarService
}
from
'
./snackbar.service
'
;
import
{
catchError
,
map
}
from
'
rxjs/operators
'
;
import
{
Injectable
}
from
'
@angular/core
'
;
import
{
HttpClient
,
HttpErrorResponse
}
from
'
@angular/common/http
'
;
import
{
CookieService
}
from
'
ngx-cookie-service
'
;
import
{
MatTableDataSource
}
from
'
@angular/material
'
;
import
{
SnackBarService
}
from
'
./snackbar.service
'
;
import
{
StompConfig
,
StompRService
}
from
'
@stomp/ng2-stompjs
'
;
import
{
Message
}
from
'
@stomp/stompjs
'
;
import
{
environment
}
from
'
../environments/environment
'
;
import
{
IdP
,
User
,
Service
,
AuthInfo
,
AllAuthInfo
,
UserState
,
SSHKey
,
NewSSHKey
}
from
'
./types/types.module
'
;
import
{
environment
}
from
'
../environments/environment
'
;
import
{
IdP
,
User
,
Service
,
AuthInfo
,
AllAuthInfo
,
UserState
,
SSHKey
,
NewSSHKey
}
from
'
./types/types.module
'
;
@
Injectable
()
...
...
@@ -23,6 +26,7 @@ export class UserService {
public
sshKeyData
:
MatTableDataSource
<
any
>
;
public
userInfoData
:
MatTableDataSource
<
any
>
;
public
services
:
Service
[];
public
messages
:
string
[];
constructor
(
...
...
@@ -32,6 +36,7 @@ export class UserService {
private
_stompService
:
StompRService
,
)
{
this
.
update
();
this
.
messages
=
[];
}
public
setIdPPreference
(
idp
:
IdP
)
{
...
...
@@ -47,7 +52,7 @@ export class UserService {
public
getIdPPreference
():
Observable
<
AllAuthInfo
>
{
let
idpID
=
Number
(
this
.
cookieService
.
get
(
environment
.
idpCookieName
));
return
this
.
http
.
get
(
'
/backend/auth/v1/info/
'
).
map
(
return
this
.
http
.
get
(
'
/backend/auth/v1/info/
'
).
pipe
(
map
(
(
authInfo
:
AuthInfo
)
=>
{
let
selected
=
authInfo
.
idps
[
1
];
...
...
@@ -64,15 +69,12 @@ export class UserService {
selected
:
selected
,
};
}
)
.
catch
(
)
,
catch
Error
(
(
error
:
any
)
=>
{
this
.
errorHandler
(
error
);
return
O
bservable
.
o
f
(
null
);
return
o
bservable
O
f
(
null
);
}
);
}
private
_handleValueChange
(
newData
:
any
)
{
),);
}
private
_updateUserValues
(
newUser
:
any
)
{
...
...
@@ -150,6 +152,58 @@ export class UserService {
this
.
updateState
();
}
private
initStomp
()
{
// handle with care
let
login
=
this
.
user
.
id
let
passcode
=
this
.
cookieService
.
get
(
'
sessionid
'
);
const
stompConfig
:
StompConfig
=
{
// Which server?
url
:
'
wss://hdf-portal.data.kit.edu/ws
'
,
// Headers
// Typical keys: login, passcode, host
headers
:
{
login
:
'
webpage-client:
'
+
login
,
passcode
:
passcode
,
},
// How often to heartbeat?
// Interval in milliseconds, set to 0 to disable
heartbeat_in
:
0
,
// Typical value 0 - disabled
heartbeat_out
:
20000
,
// Typical value 20000 - every 20 seconds
// Wait in milliseconds before attempting auto reconnect
// Set to 0 to disable
// Typical value 5000 (5 seconds)
reconnect_delay
:
5000
,
// Will log diagnostics on console
debug
:
false
,
};
this
.
_stompService
.
config
=
stompConfig
;
this
.
_stompService
.
initAndConnect
();
}
private
connectLiveUpdates
()
{
this
.
initStomp
();
let
subscription
=
this
.
_stompService
.
subscribe
(
'
/exchange/update/
'
+
this
.
user
.
id
.
toString
()
);
subscription
.
pipe
(
map
((
message
:
Message
)
=>
{
return
message
.
body
;
})).
subscribe
((
body
:
any
)
=>
{
let
json
=
JSON
.
parse
(
body
);
if
(
json
.
message
&&
json
.
message
!=
''
)
{
this
.
snackBar
.
open
(
json
.
message
);
this
.
messages
.
push
(
json
.
message
);
}
if
(
json
.
user_state
)
{
this
.
_updateUserValues
(
json
.
user_state
);
}
});
}
public
login
(
idp
:
IdP
)
{
this
.
setIdPPreference
(
idp
);
window
.
location
.
href
=
'
https://hdf-portal.data.kit.edu/backend/auth/v1/request/
'
;
...
...
@@ -250,54 +304,15 @@ export class UserService {
);
}
public
initStomp
()
{
// handle with care
let
login
=
this
.
user
.
id
let
passcode
=
this
.
cookieService
.
get
(
'
sessionid
'
);
const
stompConfig
:
StompConfig
=
{
// Which server?
url
:
'
wss://hdf-portal.data.kit.edu:15671/ws
'
,
// Headers
// Typical keys: login, passcode, host
headers
:
{
login
:
'
webpage-client:
'
+
login
,
passcode
:
passcode
,
},
// How often to heartbeat?
// Interval in milliseconds, set to 0 to disable
heartbeat_in
:
0
,
// Typical value 0 - disabled
heartbeat_out
:
20000
,
// Typical value 20000 - every 20 seconds
// Wait in milliseconds before attempting auto reconnect
// Set to 0 to disable
// Typical value 5000 (5 seconds)
reconnect_delay
:
5000
,
// Will log diagnostics on console
debug
:
false
,
};
this
.
_stompService
.
config
=
stompConfig
;
this
.
_stompService
.
initAndConnect
();
}
public
connectLiveUpdates
()
{
this
.
initStomp
();
let
subscription
=
this
.
_stompService
.
subscribe
(
'
/exchange/update/
'
+
this
.
user
.
id
.
toString
()
);
public
taskInProgress
(
site
,
service
):
boolean
{
if
(
site
&&
service
)
{
subscription
.
map
((
message
:
Message
)
=>
{
return
message
.
body
;
}).
subscribe
((
body
:
any
)
=>
{
let
json
=
JSON
.
parse
(
body
);
if
(
json
.
message
&&
json
.
message
!=
''
)
{
this
.
snackBar
.
open
(
json
.
message
);
}
if
(
json
.
user_state
)
{
this
.
_updateUserValues
(
json
.
user_state
);
for
(
const
item
of
this
.
user
.
deployment_task_items
){
if
(
item
.
site
.
id
==
site
.
id
&&
item
.
service
.
id
==
service
.
id
)
{
return
true
;
}
}
});
}
return
false
;
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment