src/app/features/api-client/edit-api-client-scopes-dialog/edit-api-client-scopes-dialog.component.ts

Description

Change the access (client scopes) of an existing API client. Closes with the updated ApiClient, if it was changed.

Example

Metadata

Relationships

Used by

No results matching.

Depends on

Index

Properties
Methods

Methods

Async save
save()
Returns : any

Properties

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
Component
Html element with directive

results matching ""

    No results matching ""