Description
Change the access (client scopes) of an existing API client.
Closes with the updated ApiClient, if it was changed.
Example
|
Readonly
apiClient
|
Type : unknown
|
Default value : inject<ApiClient>(MAT_DIALOG_DATA)
|
|
|
|
Readonly
error
|
Type : unknown
|
Default value : signal<string | undefined>(undefined)
|
|
|
|
Readonly
saving
|
Type : unknown
|
Default value : signal(false)
|
|
|
|
Readonly
scopes
|
Type : unknown
|
Default value : new FormControl<string[]>([...this.apiClient.scopes], {
nonNullable: true,
validators: [Validators.required],
})
|
|
|
import { Component, inject, signal } from "@angular/core";
import { FormControl, Validators } from "@angular/forms";
import {
MAT_DIALOG_DATA,
MatDialogModule,
MatDialogRef,
} from "@angular/material/dialog";
import { MatButtonModule } from "@angular/material/button";
import { DialogCloseComponent } from "#src/app/core/common-components/dialog-close/dialog-close.component";
import {
ApiClient,
ApiClientService,
errorMessageOf,
logRequestError,
} from "../api-client.service";
import { ApiClientScopeSelectionComponent } from "../api-client-scope-selection/api-client-scope-selection.component";
/**
* Change the access (client scopes) of an existing API client.
* Closes with the updated {@link ApiClient}, if it was changed.
*/
@Component({
selector: "app-edit-api-client-scopes-dialog",
imports: [
MatDialogModule,
MatButtonModule,
DialogCloseComponent,
ApiClientScopeSelectionComponent,
],
templateUrl: "./edit-api-client-scopes-dialog.component.html",
})
export class EditApiClientScopesDialogComponent {
private readonly apiClientService = inject(ApiClientService);
private readonly dialogRef =
inject<MatDialogRef<EditApiClientScopesDialogComponent, ApiClient>>(
MatDialogRef,
);
readonly apiClient = inject<ApiClient>(MAT_DIALOG_DATA);
readonly scopes = new FormControl<string[]>([...this.apiClient.scopes], {
nonNullable: true,
validators: [Validators.required],
});
readonly saving = signal(false);
readonly error = signal<string | undefined>(undefined);
async save() {
if (this.scopes.invalid || this.saving()) {
return;
}
this.saving.set(true);
this.error.set(undefined);
try {
const updated = await this.apiClientService.updateScopes(
this.apiClient.clientId,
this.scopes.value,
);
this.dialogRef.close(updated);
} catch (err) {
logRequestError("Could not change the scopes of an API client", err);
this.error.set(errorMessageOf(err));
} finally {
this.saving.set(false);
}
}
}
<h2 mat-dialog-title i18n>Access of "{{ apiClient.name }}"</h2>
<app-dialog-close mat-dialog-close></app-dialog-close>
<mat-dialog-content>
<p i18n>
Choose what the external system can access through the API. It keeps its
current credentials. Access tokens it already got keep their previous access
until they expire.
</p>
<app-api-client-scope-selection
[control]="scopes"
></app-api-client-scope-selection>
@if (error(); as error) {
<p class="color-error" role="alert">{{ error }}</p>
}
</mat-dialog-content>
<mat-dialog-actions>
<button
mat-raised-button
color="accent"
type="button"
(click)="save()"
[disabled]="scopes.invalid || scopes.pristine || saving()"
i18n="Button label"
>
Save
</button>
<button mat-button mat-dialog-close i18n="Button label">Cancel</button>
</mat-dialog-actions>
Legend
Html element with directive