Files
cbsnexora/src/app/users/dsc/revoke-dsc-dialog/revoke-dsc-dialog.component.ts
T
AdityaandClaude Opus 4.7 09fab88451 feat: DSC enrollment + MFA controls, user CRUD UX, auth error hardening
- DSC module: list/enroll/revoke dialogs and dsc.service (m_bank_user_dsc API)
- Access control: DSC + MFA toggles via disable-confirm-dialog
- Two-factor auth: expanded UX (DSC + OTP flows)
- Users: create/edit form polish, success snackbar on edit, DSC widget
  retained only inside dsc/ (removed from view-user)
- Auth: X-Requested-With added globally; error handler null-safe on
  empty 500 bodies

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-12 11:26:22 +05:30

81 lines
2.3 KiB
TypeScript

/**
* Copyright since 2025 Mifos Initiative
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
import { Component, inject } from '@angular/core';
import { FormsModule } from '@angular/forms';
import {
MAT_DIALOG_DATA,
MatDialogRef,
MatDialogTitle,
MatDialogContent,
MatDialogActions
} from '@angular/material/dialog';
import { MatButton } from '@angular/material/button';
import { MatFormField, MatLabel, MatError } from '@angular/material/form-field';
import { MatInput } from '@angular/material/input';
import { MatProgressSpinner } from '@angular/material/progress-spinner';
import { FaIconComponent } from '@fortawesome/angular-fontawesome';
import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module';
import { DscService } from '../dsc.service';
import { BankUserDsc } from '../dsc.model';
interface RevokeDialogData {
dsc: BankUserDsc;
}
@Component({
selector: 'mifosx-revoke-dsc-dialog',
templateUrl: './revoke-dsc-dialog.component.html',
styleUrls: ['./revoke-dsc-dialog.component.scss'],
imports: [
...STANDALONE_SHARED_IMPORTS,
FormsModule,
MatDialogTitle,
MatDialogContent,
MatDialogActions,
MatButton,
MatFormField,
MatLabel,
MatError,
MatInput,
MatProgressSpinner,
FaIconComponent
]
})
export class RevokeDscDialogComponent {
private service = inject(DscService);
private dialogRef = inject(MatDialogRef<RevokeDscDialogComponent>);
data = inject<RevokeDialogData>(MAT_DIALOG_DATA);
reason = '';
submitting = false;
errorMessage = '';
cancel(): void {
this.dialogRef.close({ revoked: false });
}
confirm(): void {
if (!this.reason?.trim() || !this.data?.dsc?.id) return;
this.submitting = true;
this.errorMessage = '';
this.service.revokeDsc(this.data.dsc.id, this.reason.trim()).subscribe({
next: () => {
this.submitting = false;
this.dialogRef.close({ revoked: true });
},
error: (err) => {
this.submitting = false;
this.errorMessage =
err?.error?.defaultUserMessage || err?.error?.message || err?.message || 'Could not revoke DSC.';
}
});
}
}