Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"typescript.tsdk": "node_modules\\typescript\\lib"
}
15 changes: 15 additions & 0 deletions src/app/admin/admin-routing.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ import { UserDetailComponent } from './users/user-detail/user-detail.component';
import { UserEditComponent } from './users/user-edit/user-edit.component';
import { UserListComponent } from './users/user-list/user-list.component';
import { UsersComponent } from './users/users.component';
import { ApiKeyComponent } from './api-key/api-key.component';
import { ApiKeyListComponent } from './api-key/api-key-list/api-key-list.component';
import { ApiKeyEditComponent } from './api-key/api-key-edit/api-key-edit.component';


const adminRoutes: Routes = [
Expand Down Expand Up @@ -44,6 +47,18 @@ const adminRoutes: Routes = [
},
],
},
{
path: 'api-key',
component: ApiKeyComponent,
children: [
{ path: '', component: ApiKeyListComponent },
{ path: 'new-api-key', component: ApiKeyEditComponent },
{
path: ':api-key-id/edit-api-key',
component: ApiKeyEditComponent,
},
],
},


];
Expand Down
12 changes: 12 additions & 0 deletions src/app/admin/admin.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ import { UsersComponent } from './users/users.component';
import { MatSelectModule } from '@angular/material/select';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatSelectSearchModule } from '@shared/components/mat-select-search/mat-select-search.module';
import { ApiKeyComponent } from './api-key/api-key.component';
import { ApiKeyListComponent } from './api-key/api-key-list/api-key-list.component';
import { ApiKeyTableComponent } from './api-key/api-key-list/api-key-table/api-key-table.component';
import { ApiKeyEditComponent } from './api-key/api-key-edit/api-key-edit.component';

@NgModule({
declarations: [
Expand All @@ -46,6 +50,10 @@ import { MatSelectSearchModule } from '@shared/components/mat-select-search/mat-
OrganisationDetailComponent,
OrganisationEditComponent,
OrganisationListComponent,
ApiKeyComponent,
ApiKeyListComponent,
ApiKeyTableComponent,
ApiKeyEditComponent,
],
imports: [
AdminRoutingModule,
Expand Down Expand Up @@ -79,6 +87,10 @@ import { MatSelectSearchModule } from '@shared/components/mat-select-search/mat-
OrganisationDetailComponent,
OrganisationEditComponent,
OrganisationListComponent,
ApiKeyComponent,
ApiKeyListComponent,
ApiKeyTableComponent,
ApiKeyEditComponent,
],
})
export class AdminModule {}
66 changes: 66 additions & 0 deletions src/app/admin/api-key/api-key-edit/api-key-edit.component.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
<app-form-header [backButton]="backButton" [title]="title"></app-form-header>

<form (ngSubmit)="onSubmit()" class="os2-form p-3 mt-4">
<div *ngIf="errorMessages" class="error-messages p-3">
<ul class="mb-0">
<li *ngFor="let error of errorMessages">
{{ error | translate }}
</li>
</ul>
</div>

<div class="row mb-5">
<div class="form-group mt-3 col-12">
<label class="form-label" for="name">{{
'API-KEY.EDIT.NAME' | translate
}}</label
>*
<input
type="text"
class="form-control"
id="name"
name="name"
[placeholder]="'API-KEY.EDIT.NAME-PLACEHOLDER' | translate"
maxlength="50"
required
[(ngModel)]="apiKeyRequest.name"
[ngClass]="{
'is-invalid': formFailedSubmit && errorFields.includes('name'),
'is-valid': formFailedSubmit && !errorFields.includes('name')
}"
/>
</div>
</div>

<div class="row mb-5">
<div class="form-group mt-3 col-12">
<label class="form-label" for="permissions">{{
'QUESTION.PERMISSION.SELECT-PERMISSION' | translate
}}</label
>*
<mat-select
class="form-control"
name="permissions"
[compareWith]="compare"
[(ngModel)]="apiKeyRequest.permissions"
[multiple]="true"
>
<mat-option
*ngFor="let permission of permissions"
[value]="permission.id"
>
{{ permission.name }}
</mat-option>
</mat-select>
</div>
</div>

<div class="form-group mt-5">
<button (click)="routeBack()" class="btn btn-secondary" type="button">
{{ 'GEN.CANCEL' | translate }}
</button>
<button class="btn btn-primary ml-2" type="submit">
{{ 'GEN.SAVE' | translate }}
</button>
</div>
</form>
Empty file.
106 changes: 106 additions & 0 deletions src/app/admin/api-key/api-key-edit/api-key-edit.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
import { Location } from '@angular/common';
import { HttpErrorResponse } from '@angular/common/http';
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { PermissionResponse } from '@app/admin/permission/permission.model';
import { PermissionService } from '@app/admin/permission/permission.service';
import { TranslateService } from '@ngx-translate/core';
import { ErrorMessageService } from '@shared/error-message.service';
import { BackButton } from '@shared/models/back-button.model';
import { SharedVariableService } from '@shared/shared-variable/shared-variable.service';
import { ApiKeyRequest } from '../api-key.model';
import { ApiKeyService } from '../api-key.service';

@Component({
selector: 'app-api-key-edit',
templateUrl: './api-key-edit.component.html',
styleUrls: ['./api-key-edit.component.scss'],
})
export class ApiKeyEditComponent implements OnInit {
apiKeyRequest = new ApiKeyRequest();
public backButton: BackButton = {
label: '',
routerLink: ['admin', 'api-key'],
};
public title = '';
public submitButton = '';
public errorMessage: string;
public errorMessages: string[];
public errorFields: string[];
public formFailedSubmit = false;
public permissions: PermissionResponse[] = [];
private organizationId: number;

constructor(
private translate: TranslateService,
private route: ActivatedRoute,
private location: Location,
private apiKeyService: ApiKeyService,
private permissionService: PermissionService,
private errorMessageService: ErrorMessageService,
private sharedVariableService: SharedVariableService
) {
translate.use('da');
}

ngOnInit(): void {
this.getPermissions();
this.translate.use('da');
this.translate
.get(['NAV.API-KEY', 'FORM.EDIT-API-KEY', 'API-KEY.EDIT.SAVE'])
.subscribe((translations) => {
this.backButton.label = translations['NAV.API-KEY'];
this.title = translations['FORM.EDIT-API-KEY'];
this.submitButton = translations['API-KEY.EDIT.SAVE'];
});

this.organizationId = this.sharedVariableService.getSelectedOrganisationId();
}

private getPermissions() {
this.permissionService
.getPermissions(
undefined,
undefined,
undefined,
undefined,
undefined,
this.organizationId
)
.subscribe(
(permissions) => {
this.permissions = permissions.data.filter(
(x) => x.organization?.id === this.organizationId
);
},
(error: HttpErrorResponse) => {
this.showError(error);
}
);
}

onSubmit(): void {
this.create();
}

private create(): void {
this.apiKeyService.create(this.apiKeyRequest).subscribe(
() => this.routeBack(),
(err) => this.showError(err)
);
}

public compare(o1: any, o2: any): boolean {
return o1 === o2;
}

private showError(err: HttpErrorResponse) {
const result = this.errorMessageService.handleErrorMessageWithFields(err);
this.errorFields = result.errorFields;
this.errorMessages = result.errorMessages;
}

routeBack(): void {
this.location.back();
}
}
17 changes: 17 additions & 0 deletions src/app/admin/api-key/api-key-list/api-key-list.component.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<app-top-bar
[title]="'NAV.API-KEY' | translate"
[ctaLabel]="'API-KEY.CREATE-NEW-API-KEY' | translate"
[ctaRouterLink]="'new-api-key'"
>
</app-top-bar>
<div class="container-fluid">
<div class="row">
<div class="col-12">
<div class="jumbotron--table">
<app-api-key-table
[organisationId]="organisationId"
></app-api-key-table>
</div>
</div>
</div>
</div>
Empty file.
28 changes: 28 additions & 0 deletions src/app/admin/api-key/api-key-list/api-key-list.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { Component, Input, OnInit } from '@angular/core';
import { Title } from '@angular/platform-browser';
import { TranslateService } from '@ngx-translate/core';
import { SharedVariableService } from '@shared/shared-variable/shared-variable.service';

@Component({
selector: 'app-api-key-list',
templateUrl: './api-key-list.component.html',
styleUrls: ['./api-key-list.component.scss'],
})
export class ApiKeyListComponent implements OnInit {
@Input() organisationId: number;

constructor(
public translate: TranslateService,
private titleService: Title,
private globalService: SharedVariableService
) {
translate.use('da');
}

ngOnInit(): void {
this.translate.get(['TITLE.API-KEY']).subscribe((translations) => {
this.titleService.setTitle(translations['TITLE.API-KEY']);
});
this.organisationId = this.globalService.getSelectedOrganisationId();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
<div class="mat-elevation-z8">
<div class="loading-shade" *ngIf="isLoadingResults">
<mat-spinner *ngIf="isLoadingResults"></mat-spinner>
</div>
<table
mat-table
[dataSource]="data"
matSort
matSortActive="name"
matSortDirection="asc"
matSortDisableClear
>
<!-- Name Column -->
<ng-container matColumnDef="name">
<th mat-header-cell *matHeaderCellDef mat-sort-header>
{{ 'API-KEY.NAME' | translate }}
</th>
<td mat-cell *matCellDef="let element">
{{ element.name }}
</td>
</ng-container>

<!-- User Groups Column -->
<ng-container matColumnDef="permissions">
<th mat-header-cell *matHeaderCellDef>
{{ 'API-KEY.PERMISSIONS' | translate }}
</th>
<td mat-cell *matCellDef="let element">
<ng-container *ngIf="element.permissions; else noUsers">
<ng-container *ngFor="let pm of element.permissions">
<span>{{ pm.name }}</span>
<br />
</ng-container>
</ng-container>
<ng-template #noUsers>{{ 'NoUsersAdded' | translate }}</ng-template>
</td>
</ng-container>

<!-- Key Column -->
<ng-container matColumnDef="key">
<th mat-header-cell *matHeaderCellDef>
{{ 'API-KEY.KEY' | translate }}
</th>
<td mat-cell *matCellDef="let element">
{{ element.key }}
</td>
</ng-container>

<!-- Menu Column -->
<ng-container matColumnDef="menu">
<th mat-header-cell *matHeaderCellDef></th>
<td mat-cell *matCellDef="let element">
<a
*ngIf="canAccess(element)"
(click)="deleteApiKey(element.id)"
[routerLink]=""
>{{ 'API-KEY.TABLE-ROW.DELETE' | translate }}
</a>
</td>
</ng-container>

<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns"></tr>
</table>
<mat-paginator
[pageSizeOptions]="[5, 10, 20]"
[pageSize]="pageSize"
[length]="resultsLength"
showFirstLastButtons
>
</mat-paginator>
</div>
Loading