...
 
Commits (6)
......@@ -22,7 +22,10 @@ small {
font-size: small;
}
.width-limit {
max-width: 250px;
}
.bold {
font-weight: bold;
}
......@@ -7,14 +7,14 @@
<!-- service column -->
<td>
<h4>{{ service.name }}</h4>
<h4 style="font-weight: bold;">{{ service.name }}</h4>
<br>
<small>{{ service.description }}</small>
</td>
<ng-container *ngIf="(state$ | async) as state; else noStateItem">
<!-- state column -->
<td class="width-limit" [matTooltip]="tooltip(state)">
<td class="width-limit">
<span [ngSwitch]="state.state" class="spaced">
<mat-icon *ngSwitchCase="'deployed'">call_made</mat-icon>
<mat-icon *ngSwitchCase="'questionnaire'">warning</mat-icon>
......@@ -27,29 +27,14 @@
</span>
<h4>{{ lang.printState(state.state) }}</h4>
<br>
<div class="mat-small">{{ tooltip(state) }}</div>
<div class="mat-small">{{ stateDescription }}</div>
</td>
<!-- actions column -->
<td>
<div *ngIf="state.state == 'deployed'">
<button (click)="dialog.openCredentials(state$)" mat-raised-button class="mat-elevation-z6">
Credentials
</button>
</div>
<div *ngIf="state.state == 'questionnaire'">
<button (click)="dialog.openQuestionnaire(state$)" mat-raised-button color="accent" class="mat-elevation-z6">
Questionnaire
</button>
</div>
<div *ngIf="state.state == 'failed'">
<button (click)="dialog.openMessage(state)" mat-raised-button color="accent" class="mat-elevation-z6">
Failure
</button>
</div>
<div *ngIf="state.state == 'rejected'">
<button (click)="dialog.openMessage(state)" mat-raised-button color="accent" class="mat-elevation-z6">
Rejected
<div *ngIf="button !== undefined">
<button (click)="buttonAction(state)" matTooltip="{{ button.tooltip }}" color="{{ button.color }}" mat-raised-button class="mat-elevation-z6">
{{ button.text }}
</button>
</div>
<div *ngIf="!state.is_pending && state.is_credential_pending">
......
......@@ -5,7 +5,13 @@ import { Observable } from 'rxjs';
import { UserService } from '../user.service';
import { LanguageService } from '../language.service';
import { DialogService } from '../dialogues/dialog.service';
import { Site, Service, DeploymentState } from '../types/types.module';
import { Site, Service, DeploymentState, StateID } from '../types/types.module';
interface Button {
text: string;
tooltip: string;
color: string;
}
@Component({
selector: '[deployment-state-tr]',
......@@ -16,9 +22,41 @@ export class StateComponent implements OnInit {
@Input() service: Service;
buttons: Record<StateID, Button | undefined> = {
'not_deployed' : undefined,
'deployment_pending': undefined,
'removal_pending': undefined,
'deployed': {
color: 'primary',
text: 'View Credentials',
tooltip: 'View detailed information about the deployed credentials'
},
'questionnaire': {
color: 'warn',
text: 'Submit Data',
tooltip: 'Submit missing data',
},
'failed': {
color: 'warn',
text: 'Show Error',
tooltip: 'Show more details on the error',
},
'rejected': {
color: 'warn',
text: 'Show Message',
tooltip: 'Show Message',
},
};
stateDescriptions: Record<StateID, string>;
// set in subscribe
public button: Button | undefined = undefined;
public stateDescription = '';
public state$: Observable<DeploymentState>;
public stateTooltip: string;
constructor(
public userService: UserService,
......@@ -27,33 +65,51 @@ export class StateComponent implements OnInit {
) { }
ngOnInit() {
this.stateDescriptions = {
'not_deployed': `Your credentials are not deployed for ${ this.service.name }.`,
'deployment_pending': `Waiting for the deployment of your credentials to ${ this.service.site.name }.`,
'removal_pending': `Waiting for the removal of your credentials from ${ this.service.site.name }.`,
'deployed': `
The credentials are deployed for this service ${ this.service.name }.
Click "${ this.buttons['deployed'].text }" see details on your deployed ssh keys and credentials.
`,
'questionnaire': `
More data is needed to deploy your credentials.
Please click "${ this.buttons['questionnaire'].text }" to submit the missing data.
`,
'failed': `
The deployment of your credentials failed, but will be tried again.
Please click "${ this.buttons['failed'].text }" for more details concerning this error.
`,
'rejected': `
The deployment of your credentials was rejected.
Please click "${ this.buttons['rejected'].text }" to show more details.
`,
};
this.state$ = this.userService.subscribeStateFor(this.service);
this.stateTooltip = 'foo';
this.state$.subscribe(
(state: DeploymentState) => {
this.button = this.buttons[state.state];
this.stateDescription = this.stateDescriptions[state.state];
}
);
}
public tooltip(state: DeploymentState): string {
public buttonAction(state: DeploymentState): void {
switch (state.state) {
case 'not_deployed':
return `The credentials are not deployed for the service ${ this.service.name }.`;
case 'deployed':
return `The credentials are deployed for the service ${ this.service.name }. Click to see details.`;
case 'deployment_pending':
return `Waiting for the deployment of the credentials to the site ${ this.service.site.name }`;
case 'removal_pending':
return `Waiting for the removal of the credentials from the site ${ this.service.site.name }`;
return this.dialog.openCredentials(this.state$);
case 'questionnaire':
return `Site ${ this.service.site.name } needs more data to deploy the keys. Please click to submit the data.`;
return this.dialog.openQuestionnaire(this.state$);
case 'failed':
return `Site ${ this.service.site.name } failed to deploy the credentials. The deployment will be retried. Click for details.`;
return this.dialog.openMessage(state);
case 'rejected':
return `Site ${ this.service.site.name } rejected the deployment of the credentials. Click for details.`;
default:
return 'Access to this service was never requested.';
return this.dialog.openMessage(state);
}
}
public contactSupport() {
window.location.href = 'mailto:' + this.service.contact_email + '?subject=%5BFEUDAL%5D%20Help%20request%0A';
window.location.href = `mailto:${ this.service.contact_email }?subject=%5BFEUDAL%5D%20Help%20request%0A`;
}
}
......@@ -2,6 +2,26 @@ import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
// STATE ENUMS
const states = [
'deployment_pending',
'removal_pending',
'deployed',
'not_deployed',
'questionnaire',
'failed',
'rejected',
] as const;
export type StateID = typeof states[number];
const stateTargets = [
'deployed',
'not_deployed',
] as const;
export type StateTargetID = typeof stateTargets[number];
// auth stuff
export interface IdP {
id: number;
......@@ -68,8 +88,8 @@ export interface JSONObject {
export interface CredentialState {
credential: SSHKeyRef;
is_pending: boolean;
state: string;
state_target: string;
state: StateID;
state_target: StateTargetID;
}
export interface DeploymentState {
......@@ -83,16 +103,16 @@ export interface DeploymentState {
questionnaire: JSONObject | undefined;
service: Service;
site: Site;
state: string;
state_target: string;
state: StateID;
state_target: StateTargetID;
}
export interface Deployment {
id: number;
service?: Service; // only for ServiceDeployment
services?: Service[]; // only for VODeployment
state: string;
state_target: string;
state: StateID;
state_target: StateTargetID;
states: DeploymentState[];
vo?: VO; // only for VODeployment
}
......
......@@ -26,6 +26,10 @@ table {
width: 100%;
}
thead > tr > td {
font-size: 110%;
}
tr > * {
padding-right: 15px;
padding-bottom: 15px;
......