feat: add new standalone components for system and organization management modules

This commit is contained in:
2026-09-28 12:55:42 +05:30
parent f451672ce7
commit 4ca08f6ee9
32 changed files with 347 additions and 32 deletions
@@ -42,6 +42,7 @@ import { AsyncPipe } from '@angular/common';
import { FaIconComponent } from '@fortawesome/angular-fontawesome';
import { MatGridList, MatGridTile } from '@angular/material/grid-list';
import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module';
import { AlertService } from 'app/core/alert/alert.service';
/**
* Manage Currencies component.
@@ -68,6 +69,7 @@ export class ManageCurrenciesComponent implements OnInit, AfterViewInit, OnDestr
private translateService = inject(TranslateService);
private configurationWizardService = inject(ConfigurationWizardService);
private popoverService = inject(PopoverService);
private alertService = inject(AlertService);
//** Defining PlaceHolders for the search bar */
placeHolderLabel = '';
@@ -164,8 +166,17 @@ export class ManageCurrenciesComponent implements OnInit, AfterViewInit, OnDestr
if (!selectedCurrencyCodes.includes(newCurrency.code)) {
selectedCurrencyCodes.push(newCurrency.code);
this.organizationservice.updateCurrencies(selectedCurrencyCodes).subscribe((response: any) => {
this.selectedCurrencies.push(newCurrency);
this.formRef.resetForm();
if (response?.rollbackTransaction) {
// Parked for checker approval - the currency has not actually been added yet, so the
// local list must not be mutated as if it had.
this.alertService.alert({
type: 'Success',
message: 'Currency configuration update has been submitted for approval.'
});
return;
}
this.selectedCurrencies.push(newCurrency);
if (this.configurationWizardService.showCurrencyForm) {
this.configurationWizardService.showCurrencyForm = false;
this.openDialog();
@@ -187,9 +198,18 @@ export class ManageCurrenciesComponent implements OnInit, AfterViewInit, OnDestr
});
deleteCurrencyDialogRef.afterClosed().subscribe((response: any) => {
if (response.delete) {
this.organizationservice.updateCurrencies(selectedCurrencyCodes).subscribe(() => {
this.selectedCurrencies.splice(index, 1);
this.organizationservice.updateCurrencies(selectedCurrencyCodes).subscribe((updateResponse: any) => {
this.formRef.resetForm();
if (updateResponse?.rollbackTransaction) {
// Parked for checker approval - the currency has not actually been removed yet, so the
// local list must not be mutated as if it had.
this.alertService.alert({
type: 'Success',
message: 'Currency configuration update has been submitted for approval.'
});
return;
}
this.selectedCurrencies.splice(index, 1);
});
}
});
@@ -11,6 +11,7 @@ import { UntypedFormBuilder, UntypedFormGroup, Validators, ReactiveFormsModule }
import { ActivatedRoute, Router, RouterLink } from '@angular/router';
import { OrganizationService } from 'app/organization/organization.service';
import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module';
import { AlertService } from 'app/core/alert/alert.service';
@Component({
selector: 'mifosx-create-fund',
@@ -25,6 +26,7 @@ export class CreateFundComponent implements OnInit {
private formBuilder = inject(UntypedFormBuilder);
private router = inject(Router);
private route = inject(ActivatedRoute);
private alertService = inject(AlertService);
/** Charge form. */
fundForm: UntypedFormGroup;
@@ -49,6 +51,12 @@ export class CreateFundComponent implements OnInit {
submit() {
const payload = this.fundForm.getRawValue();
this.organizationService.createFund(payload).subscribe((response: any) => {
if (response?.rollbackTransaction) {
this.alertService.alert({
type: 'Success',
message: 'Fund creation has been submitted for approval.'
});
}
this.router.navigate(['../'], { relativeTo: this.route });
});
}
@@ -7,7 +7,12 @@
-->
<div class="container m-b-20 layout-row align-end gap-20px">
<button mat-raised-button color="primary" [routerLink]="['create']" *mifosxHasPermission="'ADD_PREFERENCES'">
<button
mat-raised-button
color="primary"
[routerLink]="['create']"
*mifosxHasPermission="'CREATE_ACCOUNTNUMBERFORMAT'"
>
<fa-icon icon="plus" class="m-r-10"></fa-icon>
{{ 'labels.buttons.Create Preference' | translate }}
</button>
@@ -14,6 +14,7 @@ import { Router, ActivatedRoute, RouterLink } from '@angular/router';
/** Custom Services */
import { SystemService } from '../../system.service';
import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module';
import { AlertService } from 'app/core/alert/alert.service';
/**
* Create Account Number Preference Component.
@@ -31,6 +32,7 @@ export class CreateAccountNumberPreferenceComponent implements OnInit {
private systemService = inject(SystemService);
private route = inject(ActivatedRoute);
private router = inject(Router);
private alertService = inject(AlertService);
/** Account Number Preferences Form */
accountNumberPreferenceForm: UntypedFormGroup;
@@ -96,6 +98,14 @@ export class CreateAccountNumberPreferenceComponent implements OnInit {
accountNumberPreference.prefixType = undefined;
}
this.systemService.createAccountNumberPreference(accountNumberPreference).subscribe((response: any) => {
if (response?.rollbackTransaction) {
this.alertService.alert({
type: 'Success',
message: 'Account number preference creation has been submitted for approval.'
});
this.router.navigate(['../'], { relativeTo: this.route });
return;
}
this.router.navigate(
[
'../',
@@ -14,6 +14,7 @@ import { ActivatedRoute, Router, RouterLink } from '@angular/router';
/** Custom Services */
import { SystemService } from 'app/system/system.service';
import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module';
import { AlertService } from 'app/core/alert/alert.service';
/**
* Edit Account Number Preference Component.
@@ -31,6 +32,7 @@ export class EditAccountNumberPreferenceComponent implements OnInit {
private formBuilder = inject(UntypedFormBuilder);
private systemService = inject(SystemService);
private router = inject(Router);
private alertService = inject(AlertService);
/** Account Number Preference Form */
accountNumberPreferenceForm: UntypedFormGroup;
@@ -90,6 +92,12 @@ export class EditAccountNumberPreferenceComponent implements OnInit {
this.systemService
.updateAccountNumberPreference(this.accountNumberPreferenceData.id, accountNumberPreferenceValue)
.subscribe((response: any) => {
if (response?.rollbackTransaction) {
this.alertService.alert({
type: 'Success',
message: 'Account number preference update has been submitted for approval.'
});
}
this.router.navigate(['../'], { relativeTo: this.route });
});
}
@@ -19,6 +19,7 @@ import { TranslateService } from '@ngx-translate/core';
import { DeleteDialogComponent } from 'app/shared/delete-dialog/delete-dialog.component';
import { FaIconComponent } from '@fortawesome/angular-fontawesome';
import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module';
import { AlertService } from 'app/core/alert/alert.service';
/**
* View Account Number Preference Component.
@@ -38,6 +39,7 @@ export class ViewAccountNumberPreferenceComponent {
private router = inject(Router);
private dialog = inject(MatDialog);
private translateService = inject(TranslateService);
private alertService = inject(AlertService);
/** Account Number Preference Data */
accountNumberPreferenceData: any;
@@ -70,9 +72,17 @@ export class ViewAccountNumberPreferenceComponent {
});
deleteAccountNumberPreferenceDialogRef.afterClosed().subscribe((response: any) => {
if (response.delete) {
this.systemService.deleteAccountNumberPreference(this.accountNumberPreferenceData.id).subscribe(() => {
this.router.navigate(['/system/account-number-preferences']);
});
this.systemService
.deleteAccountNumberPreference(this.accountNumberPreferenceData.id)
.subscribe((deleteResponse: any) => {
if (deleteResponse?.rollbackTransaction) {
this.alertService.alert({
type: 'Success',
message: 'Account number preference deletion has been submitted for approval.'
});
}
this.router.navigate(['/system/account-number-preferences']);
});
}
});
}
@@ -17,6 +17,7 @@ import { PopoverService } from '../../../configuration-wizard/popover/popover.se
import { PopoverRef } from '../../../configuration-wizard/popover/popover-ref';
import { ConfigurationWizardService } from '../../../configuration-wizard/configuration-wizard.service';
import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module';
import { AlertService } from 'app/core/alert/alert.service';
@Component({
selector: 'mifosx-create-code',
@@ -33,6 +34,7 @@ export class CreateCodeComponent implements OnInit, AfterViewInit {
private router = inject(Router);
private configurationWizardService = inject(ConfigurationWizardService);
private popoverService = inject(PopoverService);
private alertService = inject(AlertService);
/** Code form. */
codeForm: UntypedFormGroup;
@@ -67,6 +69,14 @@ export class CreateCodeComponent implements OnInit, AfterViewInit {
*/
submit() {
this.systemService.createCode(this.codeForm.value).subscribe((response: any) => {
if (response?.rollbackTransaction) {
this.alertService.alert({
type: 'Success',
message: 'Code creation has been submitted for approval.'
});
this.router.navigate(['../'], { relativeTo: this.route });
return;
}
if (this.configurationWizardService.showSystemCodesForm) {
this.configurationWizardService.showSystemCodesForm = false;
this.configurationWizardService.showRolesandPermission = true;
@@ -14,6 +14,7 @@ import { ActivatedRoute, Router, RouterLink } from '@angular/router';
/** Custom Services */
import { SystemService } from '../../system.service';
import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module';
import { AlertService } from 'app/core/alert/alert.service';
/**
* Edit Code Component.
@@ -31,6 +32,7 @@ export class EditCodeComponent implements OnInit {
private systemService = inject(SystemService);
private route = inject(ActivatedRoute);
private router = inject(Router);
private alertService = inject(AlertService);
/** Code Form */
codeForm: UntypedFormGroup;
@@ -75,6 +77,20 @@ export class EditCodeComponent implements OnInit {
*/
submit() {
this.systemService.updateCode(this.codeForm.value, this.codeData.id).subscribe((response: any) => {
if (response?.rollbackTransaction) {
this.alertService.alert({
type: 'Success',
message: 'Code update has been submitted for approval.'
});
this.router.navigate(
[
'../../',
this.codeData.id
],
{ relativeTo: this.route }
);
return;
}
this.router.navigate(
[
'../../',
@@ -33,7 +33,7 @@
mat-stroked-button
color="warn"
(click)="delete()"
*mifosxHasPermission="'DELETE_CODEVALUE'"
*mifosxHasPermission="'DELETE_CODE'"
class="vc-header__btn-delete"
>
<fa-icon icon="trash" class="m-r-10"></fa-icon>
@@ -30,6 +30,7 @@ import { MatCard, MatCardContent } from '@angular/material/card';
import { MatCheckbox } from '@angular/material/checkbox';
import { MatTooltip } from '@angular/material/tooltip';
import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module';
import { AlertService } from 'app/core/alert/alert.service';
/**
* View Code Component.
@@ -53,6 +54,7 @@ export class ViewCodeComponent implements OnInit {
private formBuilder = inject(UntypedFormBuilder);
private dialog = inject(MatDialog);
private translateService = inject(TranslateService);
private alertService = inject(AlertService);
/** Code Data */
codeData: any;
@@ -152,6 +154,13 @@ export class ViewCodeComponent implements OnInit {
deleteCodeValue(index: number) {
const codeValueId = this.codeValuesData[index].id;
this.systemService.deleteCodeValue(this.codeData.id, codeValueId).subscribe((response: any) => {
if (response?.rollbackTransaction) {
this.alertService.alert({
type: 'Success',
message: 'Code value deletion has been submitted for approval.'
});
return;
}
this.codeValuesData.splice(index, 1);
this.codeValues.removeAt(index);
this.codeValueRowStatus.splice(index, 1);
@@ -177,6 +186,13 @@ export class ViewCodeComponent implements OnInit {
this.systemService
.updateCodeValue(this.codeData.id, this.codeValuesData[index].id, updatedCodeValue)
.subscribe((response: any) => {
if (response?.rollbackTransaction) {
this.alertService.alert({
type: 'Success',
message: 'Code value update has been submitted for approval.'
});
return;
}
this.codeValues.at(index).disable();
this.codeValueRowStatus[index] = 'disabled';
this.codeValues.at(index).markAsPristine();
@@ -192,7 +208,13 @@ export class ViewCodeComponent implements OnInit {
});
deleteCodeDialogRef.afterClosed().subscribe((response: any) => {
if (response.delete) {
this.systemService.deleteCode(this.codeData.id).subscribe(() => {
this.systemService.deleteCode(this.codeData.id).subscribe((deleteResponse: any) => {
if (deleteResponse?.rollbackTransaction) {
this.alertService.alert({
type: 'Success',
message: 'Code deletion has been submitted for approval.'
});
}
this.router.navigate(['/system/codes']);
});
}
@@ -221,6 +243,13 @@ export class ViewCodeComponent implements OnInit {
const newCodeValue: { name: string; description: string; position: string; isActive: boolean } =
this.codeValues.at(index).value;
this.systemService.createCodeValue(this.codeData.id, newCodeValue).subscribe((response: any) => {
if (response?.rollbackTransaction) {
this.alertService.alert({
type: 'Success',
message: 'Code value creation has been submitted for approval.'
});
return;
}
this.codeValues.at(index).disable();
this.codeValueRowStatus[index] = 'disabled';
this.codeValuesData.push({
@@ -12,6 +12,7 @@ import { UntypedFormBuilder, UntypedFormGroup, Validators, ReactiveFormsModule }
import { ActivatedRoute, Router, RouterLink } from '@angular/router';
import { SettingsService } from 'app/settings/settings.service';
import { Dates } from 'app/core/utils/dates';
import { AlertService } from 'app/core/alert/alert.service';
/** Custom Services */
import { SystemService } from '../../../system.service';
@@ -37,6 +38,7 @@ export class EditConfigurationComponent implements OnInit {
private route = inject(ActivatedRoute);
private router = inject(Router);
private dateUtils = inject(Dates);
private alertService = inject(AlertService);
/** Minimum transaction date allowed. */
minDate = new Date(2000, 0, 1);
@@ -122,7 +124,15 @@ export class EditConfigurationComponent implements OnInit {
delete payload.dateValue;
}
this.systemService.updateConfiguration(this.configuration.id, payload).subscribe(() => {
this.systemService.updateConfiguration(this.configuration.id, payload).subscribe((response: any) => {
if (response?.rollbackTransaction) {
this.alertService.alert({
type: 'Success',
message: 'Configuration update has been submitted for approval.'
});
this.router.navigate(['../../'], { relativeTo: this.route });
return;
}
this.router.navigate(['../../'], { relativeTo: this.route });
});
}
@@ -145,15 +145,25 @@ export class GlobalConfigurationsTabComponent implements OnInit, AfterViewInit {
* Enables/Disables respective configuration
*/
toggleStatus(configuration: any) {
this.systemService
.updateConfiguration(configuration.id, { enabled: configuration.enabled })
.subscribe((response: any) => {
configuration.enabled = response.changes.enabled;
if (configuration.name === SettingsService.businessDateConfigName) {
const msg = configuration.enabled ? 'enabled' : 'disabled';
this.alertService.alert({ type: SettingsService.businessDateType + ' Set Config', message: msg });
}
});
const desiredEnabled = configuration.enabled;
this.systemService.updateConfiguration(configuration.id, { enabled: desiredEnabled }).subscribe((response: any) => {
if (response?.rollbackTransaction) {
// Parked for checker approval - the configuration has not actually changed yet, so the
// toggle (already flipped optimistically by ngModel on click) must be reverted, and
// response.changes must not be read since a parked response never contains it.
configuration.enabled = !desiredEnabled;
this.alertService.alert({
type: 'Success',
message: 'Configuration update has been submitted for approval.'
});
return;
}
configuration.enabled = response.changes.enabled;
if (configuration.name === SettingsService.businessDateConfigName) {
const msg = configuration.enabled ? 'enabled' : 'disabled';
this.alertService.alert({ type: SettingsService.businessDateType + ' Set Config', message: msg });
}
});
}
/**
@@ -45,6 +45,7 @@ import { MatTooltip } from '@angular/material/tooltip';
import { FaIconComponent } from '@fortawesome/angular-fontawesome';
import { DateFormatPipe } from '../../pipes/date-format.pipe';
import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module';
import { AlertService } from 'app/core/alert/alert.service';
/**
* Entity to Entity Mapping Component
@@ -81,6 +82,7 @@ export class EntityToEntityMappingComponent implements OnInit {
private dialog = inject(MatDialog);
private settingsService = inject(SettingsService);
private translateService = inject(TranslateService);
private alertService = inject(AlertService);
/** Stores entity to entity mapping data */
entityMappings: string[] = [];
@@ -392,6 +394,12 @@ export class EntityToEntityMappingComponent implements OnInit {
newMappingData.dateFormat = dateFormat;
newMappingData.locale = this.settingsService.language.code;
this.systemService.createMapping(this.relId, newMappingData).subscribe((response: any) => {
if (response?.rollbackTransaction) {
this.alertService.alert({
type: 'Success',
message: 'Entity to entity mapping creation has been submitted for approval.'
});
}
this.showFilteredData();
});
}
@@ -413,6 +421,12 @@ export class EntityToEntityMappingComponent implements OnInit {
newMappingData.dateFormat = dateFormat;
newMappingData.locale = this.settingsService.language.code;
this.systemService.editMapping(this.mapIdToEdit, newMappingData).subscribe((response: any) => {
if (response?.rollbackTransaction) {
this.alertService.alert({
type: 'Success',
message: 'Entity to entity mapping update has been submitted for approval.'
});
}
this.showFilteredData();
});
}
@@ -427,7 +441,13 @@ export class EntityToEntityMappingComponent implements OnInit {
});
deleteNoteDialogRef.afterClosed().subscribe((response: any) => {
if (response.delete) {
this.systemService.deleteMapping(id).subscribe(() => {
this.systemService.deleteMapping(id).subscribe((deleteResponse: any) => {
if (deleteResponse?.rollbackTransaction) {
this.alertService.alert({
type: 'Success',
message: 'Entity to entity mapping deletion has been submitted for approval.'
});
}
this.showFilteredData();
});
}
@@ -16,6 +16,7 @@ import { SystemService } from 'app/system/system.service';
import { MatButton, MatIconButton } from '@angular/material/button';
import { FaIconComponent } from '@fortawesome/angular-fontawesome';
import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module';
import { AlertService } from 'app/core/alert/alert.service';
/**
* Edit Amazon S3 Component.
@@ -35,6 +36,7 @@ export class EditAmazonS3Component implements OnInit {
private systemService = inject(SystemService);
private route = inject(ActivatedRoute);
private router = inject(Router);
private alertService = inject(AlertService);
/** Amazon S3 Configuration data */
amazonS3ConfigurationData: any;
@@ -95,6 +97,12 @@ export class EditAmazonS3Component implements OnInit {
this.systemService
.updateExternalConfiguration('S3', this.amazonS3ConfigurationForm.value)
.subscribe((response: any) => {
if (response?.rollbackTransaction) {
this.alertService.alert({
type: 'Success',
message: 'Amazon S3 configuration update has been submitted for approval.'
});
}
this.router.navigate(['../'], { relativeTo: this.route });
});
}
@@ -17,6 +17,7 @@ import { MatButton, MatIconButton } from '@angular/material/button';
import { FaIconComponent } from '@fortawesome/angular-fontawesome';
import { MatCheckbox } from '@angular/material/checkbox';
import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module';
import { AlertService } from 'app/core/alert/alert.service';
/**
* Edit Email Configuration Component.
@@ -37,6 +38,7 @@ export class EditEmailComponent implements OnInit {
private systemService = inject(SystemService);
private route = inject(ActivatedRoute);
private router = inject(Router);
private alertService = inject(AlertService);
/** Password input field type. */
passwordInputType: string;
@@ -110,6 +112,12 @@ export class EditEmailComponent implements OnInit {
this.systemService
.updateExternalConfiguration('SMTP', this.emailConfigurationForm.value)
.subscribe((response: any) => {
if (response?.rollbackTransaction) {
this.alertService.alert({
type: 'Success',
message: 'Email configuration update has been submitted for approval.'
});
}
this.router.navigate(['../'], { relativeTo: this.route });
});
}
@@ -14,6 +14,7 @@ import { UntypedFormGroup, UntypedFormBuilder, Validators, ReactiveFormsModule }
/** Custom Services */
import { SystemService } from 'app/system/system.service';
import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module';
import { AlertService } from 'app/core/alert/alert.service';
/**
* Edit Notification Configuration Component.
@@ -31,6 +32,7 @@ export class EditNotificationComponent implements OnInit {
private systemService = inject(SystemService);
private route = inject(ActivatedRoute);
private router = inject(Router);
private alertService = inject(AlertService);
/** Notification Configuration data */
notificationConfigurationData: any;
@@ -85,6 +87,12 @@ export class EditNotificationComponent implements OnInit {
this.systemService
.updateExternalConfiguration('NOTIFICATION', this.notificationConfigurationForm.value)
.subscribe((response: any) => {
if (response?.rollbackTransaction) {
this.alertService.alert({
type: 'Success',
message: 'Notification configuration update has been submitted for approval.'
});
}
this.router.navigate(['../'], { relativeTo: this.route });
});
}
@@ -14,6 +14,7 @@ import { UntypedFormGroup, UntypedFormBuilder, Validators, ReactiveFormsModule }
/** Custom Services */
import { SystemService } from 'app/system/system.service';
import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module';
import { AlertService } from 'app/core/alert/alert.service';
/**
* Edit SMS Configuration Component.
@@ -31,6 +32,7 @@ export class EditSMSComponent implements OnInit {
private systemService = inject(SystemService);
private route = inject(ActivatedRoute);
private router = inject(Router);
private alertService = inject(AlertService);
/** SMS Configuration data */
smsConfigurationData: any;
@@ -89,6 +91,12 @@ export class EditSMSComponent implements OnInit {
this.systemService
.updateExternalConfiguration('SMS', this.smsConfigurationForm.value)
.subscribe((response: any) => {
if (response?.rollbackTransaction) {
this.alertService.alert({
type: 'Success',
message: 'SMS configuration update has been submitted for approval.'
});
}
this.router.navigate(['../'], { relativeTo: this.route });
});
}
@@ -48,6 +48,7 @@ import { MatButton, MatIconButton } from '@angular/material/button';
import { FaIconComponent } from '@fortawesome/angular-fontawesome';
import { MatTooltip } from '@angular/material/tooltip';
import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module';
import { AlertService } from 'app/core/alert/alert.service';
/**
* Create Data Table Component.
@@ -86,6 +87,7 @@ export class CreateDataTableComponent implements OnInit, AfterViewInit {
private configurationWizardService = inject(ConfigurationWizardService);
private popoverService = inject(PopoverService);
private translateService = inject(TranslateService);
private alertService = inject(AlertService);
/** Data Table Form */
dataTableForm: UntypedFormGroup;
@@ -296,6 +298,14 @@ export class CreateDataTableComponent implements OnInit, AfterViewInit {
delete payload.entitySubType;
}
this.systemService.createDataTable(payload).subscribe((response: any) => {
if (response?.rollbackTransaction) {
this.alertService.alert({
type: 'Success',
message: 'Data table creation has been submitted for approval.'
});
this.router.navigate(['../'], { relativeTo: this.route });
return;
}
if (this.configurationWizardService.showDatatablesForm) {
this.configurationWizardService.showDatatablesForm = false;
this.openDialog();
@@ -42,6 +42,7 @@ import { MatButton, MatIconButton } from '@angular/material/button';
import { FaIconComponent } from '@fortawesome/angular-fontawesome';
import { MatTooltip } from '@angular/material/tooltip';
import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module';
import { AlertService } from 'app/core/alert/alert.service';
/**
* Edit Data Table Component.
@@ -77,6 +78,7 @@ export class EditDataTableComponent implements OnInit {
private router = inject(Router);
private dialog = inject(MatDialog);
private translateService = inject(TranslateService);
private alertService = inject(AlertService);
/** Data Table Form. */
dataTableForm: UntypedFormGroup;
@@ -471,6 +473,12 @@ export class EditDataTableComponent implements OnInit {
this.systemService
.updateDataTable(this.dataTableChangesData, this.dataTableData.registeredTableName)
.subscribe((response: any) => {
if (response?.rollbackTransaction) {
this.alertService.alert({
type: 'Success',
message: 'Data table update has been submitted for approval.'
});
}
this.router.navigate(['../'], { relativeTo: this.route });
});
}
@@ -36,6 +36,7 @@ import { DeleteDialogComponent } from 'app/shared/delete-dialog/delete-dialog.co
import { FaIconComponent } from '@fortawesome/angular-fontawesome';
import { MatTooltip } from '@angular/material/tooltip';
import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module';
import { AlertService } from 'app/core/alert/alert.service';
/**
* View Data Table Component
@@ -69,6 +70,7 @@ export class ViewDataTableComponent implements OnInit {
private router = inject(Router);
private dialog = inject(MatDialog);
private translateService = inject(TranslateService);
private alertService = inject(AlertService);
public datatables = inject(Datatables);
/** Data Table Data */
@@ -145,7 +147,13 @@ export class ViewDataTableComponent implements OnInit {
});
deleteDataTableDialogRef.afterClosed().subscribe((response: any) => {
if (response.delete) {
this.systemService.deleteDataTable(this.dataTableData.registeredTableName).subscribe(() => {
this.systemService.deleteDataTable(this.dataTableData.registeredTableName).subscribe((deleteResponse: any) => {
if (deleteResponse?.rollbackTransaction) {
this.alertService.alert({
type: 'Success',
message: 'Data table deletion has been submitted for approval.'
});
}
this.router.navigate(['/system/data-tables'], { relativeTo: this.route });
});
}
@@ -38,6 +38,7 @@ import { MatCheckbox } from '@angular/material/checkbox';
import { MatButton, MatIconButton } from '@angular/material/button';
import { FaIconComponent } from '@fortawesome/angular-fontawesome';
import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module';
import { AlertService } from 'app/core/alert/alert.service';
/**
* Create Hook Component.
@@ -73,6 +74,7 @@ export class CreateHookComponent implements OnInit {
private formBuilder = inject(UntypedFormBuilder);
private dialog = inject(MatDialog);
private translateService = inject(TranslateService);
private alertService = inject(AlertService);
/** Hooks Template Data. */
hooksTemplateData: any;
@@ -253,6 +255,14 @@ export class CreateHookComponent implements OnInit {
}
};
this.systemService.createHook(hook).subscribe((response: any) => {
if (response?.rollbackTransaction) {
this.alertService.alert({
type: 'Success',
message: 'Hook creation has been submitted for approval.'
});
this.router.navigate(['../'], { relativeTo: this.route });
return;
}
this.router.navigate(
[
'../',
@@ -44,6 +44,7 @@ import { MatDivider } from '@angular/material/divider';
import { MatButton, MatIconButton } from '@angular/material/button';
import { FaIconComponent } from '@fortawesome/angular-fontawesome';
import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module';
import { AlertService } from 'app/core/alert/alert.service';
/**
* Edit Hook Component.
@@ -83,6 +84,7 @@ export class EditHookComponent implements OnInit {
private translateService = inject(TranslateService);
private snackBar = inject(MatSnackBar);
private cdr = inject(ChangeDetectorRef);
private alertService = inject(AlertService);
@NgModule({
imports: [
@@ -286,6 +288,12 @@ export class EditHookComponent implements OnInit {
}
};
this.systemService.updateHook(this.hookData.id, hook).subscribe((response: any) => {
if (response?.rollbackTransaction) {
this.alertService.alert({
type: 'Success',
message: 'Hook update has been submitted for approval.'
});
}
this.router.navigate(['../'], { relativeTo: this.route });
});
}
@@ -20,6 +20,7 @@ import { SystemService } from '../../system.service';
import { FaIconComponent } from '@fortawesome/angular-fontawesome';
import { DateFormatPipe } from '../../../pipes/date-format.pipe';
import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module';
import { AlertService } from 'app/core/alert/alert.service';
/**
* View Hook Component.
@@ -40,6 +41,7 @@ export class ViewHookComponent {
private systemService = inject(SystemService);
private router = inject(Router);
private translateService = inject(TranslateService);
private alertService = inject(AlertService);
/** Hook Data. */
hookData: any;
@@ -67,7 +69,13 @@ export class ViewHookComponent {
});
deleteHookDialogRef.afterClosed().subscribe((response: any) => {
if (response.delete) {
this.systemService.deleteHook(this.hookData.id).subscribe(() => {
this.systemService.deleteHook(this.hookData.id).subscribe((deleteResponse: any) => {
if (deleteResponse?.rollbackTransaction) {
this.alertService.alert({
type: 'Success',
message: 'Hook deletion has been submitted for approval.'
});
}
this.router.navigate(['/system/hooks']);
});
}
@@ -33,6 +33,7 @@ import { FaIconComponent } from '@fortawesome/angular-fontawesome';
import { MatTooltip } from '@angular/material/tooltip';
import { WorkflowDiagramComponent } from './workflow-diagram/workflow-diagram.component';
import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module';
import { AlertService } from 'app/core/alert/alert.service';
export interface JobStep {
stepName: string;
@@ -68,6 +69,7 @@ export class WorkflowJobsComponent implements OnInit {
private systemService = inject(SystemService);
dialog = inject(MatDialog);
private translateService = inject(TranslateService);
private alertService = inject(AlertService);
stepOrderHasChanged = false;
@@ -209,8 +211,14 @@ export class WorkflowJobsComponent implements OnInit {
this.systemService
.putWorkflowJobSteps(this.jobStepName, payload)
.toPromise()
.then((data) => {
.then((data: any) => {
this.stepOrderHasChanged = false;
if (data?.rollbackTransaction) {
this.alertService.alert({
type: 'Success',
message: 'Workflow step order update has been submitted for approval.'
});
}
});
}
}
@@ -39,6 +39,7 @@ import { CdkTextareaAutosize } from '@angular/cdk/text-field';
import { MatButton, MatIconButton } from '@angular/material/button';
import { FaIconComponent } from '@fortawesome/angular-fontawesome';
import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module';
import { AlertService } from 'app/core/alert/alert.service';
/**
* Create Report Component.
@@ -75,6 +76,7 @@ export class CreateReportComponent implements OnInit {
private router = inject(Router);
private dialog = inject(MatDialog);
private translateServices = inject(TranslateService);
private alertService = inject(AlertService);
/** Report Form. */
reportForm: UntypedFormGroup;
@@ -267,7 +269,14 @@ export class CreateReportComponent implements OnInit {
return reportParameter;
});
this.systemService.createReport(this.reportForm.value).subscribe((response: any) => {
// TODO: Implement Maker Checker Component.
if (response?.rollbackTransaction) {
this.alertService.alert({
type: 'Success',
message: 'Report creation has been submitted for approval.'
});
this.router.navigate(['../'], { relativeTo: this.route });
return;
}
this.router.navigate(
[
'../',
@@ -38,6 +38,7 @@ import { CdkTextareaAutosize } from '@angular/cdk/text-field';
import { MatButton, MatIconButton } from '@angular/material/button';
import { FaIconComponent } from '@fortawesome/angular-fontawesome';
import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module';
import { AlertService } from 'app/core/alert/alert.service';
/**
* Edit Report Component.
@@ -73,6 +74,7 @@ export class EditReportComponent implements OnInit {
private router = inject(Router);
private systemService = inject(SystemService);
private dialog = inject(MatDialog);
private alertService = inject(AlertService);
/** Report Data. */
reportData: any;
@@ -292,7 +294,13 @@ export class EditReportComponent implements OnInit {
return reportParameter;
});
}
this.systemService.updateReport(this.reportData.id, this.reportForm.value).subscribe(() => {
this.systemService.updateReport(this.reportData.id, this.reportForm.value).subscribe((response: any) => {
if (response?.rollbackTransaction) {
this.alertService.alert({
type: 'Success',
message: 'Report update has been submitted for approval.'
});
}
this.router.navigate(['../'], { relativeTo: this.route });
});
}
@@ -20,6 +20,7 @@ import { FaIconComponent } from '@fortawesome/angular-fontawesome';
import { MatCard, MatCardTitle, MatCardContent } from '@angular/material/card';
import { YesnoPipe } from '../../../pipes/yesno.pipe';
import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module';
import { AlertService } from 'app/core/alert/alert.service';
/**
* View Report Component.
@@ -40,6 +41,7 @@ export class ViewReportComponent {
private systemService = inject(SystemService);
private dialog = inject(MatDialog);
private router = inject(Router);
private alertService = inject(AlertService);
/** Report Data. */
reportData: any;
@@ -66,7 +68,13 @@ export class ViewReportComponent {
});
deleteReportDialogRef.afterClosed().subscribe((response: any) => {
if (response.delete) {
this.systemService.deleteReport(this.reportData.id).subscribe(() => {
this.systemService.deleteReport(this.reportData.id).subscribe((deleteResponse: any) => {
if (deleteResponse?.rollbackTransaction) {
this.alertService.alert({
type: 'Success',
message: 'Report deletion has been submitted for approval.'
});
}
this.router.navigate(['/system/reports']);
});
}
@@ -30,6 +30,7 @@ import { FaIconComponent } from '@fortawesome/angular-fontawesome';
import { MatDivider } from '@angular/material/divider';
import { MatTooltip } from '@angular/material/tooltip';
import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module';
import { AlertService } from 'app/core/alert/alert.service';
/**
* Create survey component.
@@ -55,6 +56,7 @@ export class CreateSurveyComponent implements OnInit {
private route = inject(ActivatedRoute);
private router = inject(Router);
dialog = inject(MatDialog);
private alertService = inject(AlertService);
/** Survey form. */
surveyForm: UntypedFormGroup;
@@ -244,6 +246,12 @@ export class CreateSurveyComponent implements OnInit {
countryCode: this.surveyForm.value.countryCode.toUpperCase()
});
this.systemService.createSurvey(this.surveyForm.value).subscribe((response: any) => {
if (response?.rollbackTransaction) {
this.alertService.alert({
type: 'Success',
message: 'Survey creation has been submitted for approval.'
});
}
this.router.navigate(['../'], { relativeTo: this.route });
});
}
@@ -34,6 +34,7 @@ import { FaIconComponent } from '@fortawesome/angular-fontawesome';
import { MatDivider } from '@angular/material/divider';
import { MatTooltip } from '@angular/material/tooltip';
import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module';
import { AlertService } from 'app/core/alert/alert.service';
/**
* Edit survey component.
@@ -59,6 +60,7 @@ export class EditSurveyComponent {
private route = inject(ActivatedRoute);
private router = inject(Router);
dialog = inject(MatDialog);
private alertService = inject(AlertService);
/** Survey form. */
surveyForm: UntypedFormGroup;
@@ -299,6 +301,12 @@ export class EditSurveyComponent {
this.systemService
.editSurvey(this.route.snapshot.paramMap.get('id'), this.surveyForm.value)
.subscribe((response: any) => {
if (response?.rollbackTransaction) {
this.alertService.alert({
type: 'Success',
message: 'Survey update has been submitted for approval.'
});
}
this.router.navigate(['../'], { relativeTo: this.route });
});
}
@@ -30,6 +30,7 @@ import { SystemService } from '../system.service';
import { FaIconComponent } from '@fortawesome/angular-fontawesome';
import { MatTooltip } from '@angular/material/tooltip';
import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module';
import { AlertService } from 'app/core/alert/alert.service';
/**
* Manage Surveys component.
@@ -60,6 +61,7 @@ import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module';
export class ManageSurveysComponent implements OnInit {
private route = inject(ActivatedRoute);
private systemService = inject(SystemService);
private alertService = inject(AlertService);
/* Surveys data */
surveysData: any;
@@ -139,7 +141,14 @@ export class ManageSurveysComponent implements OnInit {
* @param {any} survey Survey to activate.
*/
activate(survey: any) {
this.systemService.activateSurvey(survey.id).subscribe(() => {
this.systemService.activateSurvey(survey.id).subscribe((response: any) => {
if (response?.rollbackTransaction) {
this.alertService.alert({
type: 'Success',
message: 'Survey activation has been submitted for approval.'
});
return;
}
const today = new Date().toISOString().split('T')[0];
// This mimics the server-side logic
survey.validFrom = today;
@@ -152,7 +161,14 @@ export class ManageSurveysComponent implements OnInit {
* @param {any} survey Survey to deactivate.
*/
deactivate(survey: any) {
this.systemService.deactivateSurvey(survey.id).subscribe(() => {
this.systemService.deactivateSurvey(survey.id).subscribe((response: any) => {
if (response?.rollbackTransaction) {
this.alertService.alert({
type: 'Success',
message: 'Survey deactivation has been submitted for approval.'
});
return;
}
const date = new Date();
date.setDate(date.getDate() - 1); // Set to yesterday
const yesterday = date.toISOString().split('T')[0];
@@ -15,6 +15,7 @@ import { forkJoin } from 'rxjs';
import { UserAgreementService, UserAgreement } from './user-agreement.service';
import { ConfirmationDialogComponent } from 'app/shared/confirmation-dialog/confirmation-dialog.component';
import { HasPermissionDirective } from 'app/directives/has-permission/has-permission.directive';
import { AlertService } from 'app/core/alert/alert.service';
@Component({
selector: 'mifosx-manage-user-agreement',
@@ -34,6 +35,7 @@ export class ManageUserAgreementComponent implements OnInit {
private service = inject(UserAgreementService);
private dialog = inject(MatDialog);
private snackBar = inject(MatSnackBar);
private alertService = inject(AlertService);
agreements: UserAgreement[] = [];
activeId: number | null = null;
@@ -118,10 +120,18 @@ export class ManageUserAgreementComponent implements OnInit {
body: this.model.body
})
.subscribe({
next: () => {
this.snackBar.open('Agreement published', 'Close', { duration: 3000 });
next: (response: any) => {
this.saving = false;
this.drawerOpen = false;
if (response?.rollbackTransaction) {
this.alertService.alert({
type: 'Success',
message: 'Agreement publication has been submitted for approval.'
});
this.load();
return;
}
this.snackBar.open('Agreement published', 'Close', { duration: 3000 });
this.load();
},
error: (err: any) => {
@@ -35,7 +35,7 @@ export class UserAgreementService {
}
/** Publish a new version. The backend deactivates the previous active row automatically. */
create(data: { title: string; body: string }): Observable<{ resourceId: number }> {
return this.http.post<{ resourceId: number }>('/useragreements', data);
create(data: { title: string; body: string }): Observable<{ resourceId: number; rollbackTransaction?: boolean }> {
return this.http.post<{ resourceId: number; rollbackTransaction?: boolean }>('/useragreements', data);
}
}