feat(tasks,shares): fix Share Account Edit Details routing/auto-select, popup compare dialog, redesign Approval Center filters
build-run / Run Lint, Build and Deploy (push) Canceled after 0s
Publish Image in Docker Hub / build (push) Canceled after 0s
Playwright E2E Tests / Run Playwright Tests (push) Canceled after 0s
Tests / testRigor (push) Canceled after 0s

- Register the missing edit-details route so the Share Account "Edit Details"
  maker-checker screen (already built) is actually reachable, and remove the
  stale hardcoded disable on its menu entry.
- Fix Terms step race: Default Savings Account, Total Shares and Application
  Date now display correctly in edit mode instead of racing an async
  product-template fetch or reusing pending-application-only fields.
- Show a client's linked share account number on the Savings Account General
  tab.
- Replace the inline diff panel on Pending Share Account Edits with a popup
  compare dialog (mirrors the savings equivalent), showing only fields that
  actually changed.
- Redesign Pending Share/Savings Account Edits, Share Withdrawal Requests,
  Dividend Requests and Share Addition Requests with a consistent header,
  search box and (where the data supports it) date-range filters, matching
  the existing Withdrawal Requests screen.
This commit is contained in:
2026-09-01 07:43:07 +05:30
parent 7a2cb25538
commit 9739ff0758
27 changed files with 2932 additions and 507 deletions
@@ -78,9 +78,15 @@ export class SharesAccountTermsStepComponent implements OnChanges, OnInit {
currencyCode: this.sharesAccountProductTemplate.currency.code,
decimal: this.sharesAccountProductTemplate.currency.decimalPlaces,
currencyMultiple: this.sharesAccountProductTemplate.currency.inMultiplesOf,
unitPrice: this.sharesAccountProductTemplate.currentMarketPrice,
savingsAccountId: ''
unitPrice: this.sharesAccountProductTemplate.currentMarketPrice
});
// A product change clears any previously-selected savings account, since it may no longer be
// valid for the new product's currency - but only once, and never after the account's own
// already-linked savings account has been restored (below, and in ngOnInit for approvalEditMode) -
// otherwise this reset races the async product-template fetch and wipes that restored value.
if (!this.isSavingsPatched) {
this.sharesAccountTermsForm.get('savingsAccountId').patchValue('');
}
this.setOptions();
if (this.sharesAccountTemplate) {
if (!this.isSavingsPatched && this.sharesAccountTemplate.savingsAccountId) {
@@ -94,20 +100,34 @@ export class SharesAccountTermsStepComponent implements OnChanges, OnInit {
ngOnInit() {
this.maxDate = this.settingsService.businessDate;
if (this.sharesAccountTemplate) {
// In approvalEditMode the account is already active: there is nothing "pending approval" and
// purchasedShares[0] is a transaction row, not the application date - use the account's real
// approved share count and its original submitted date instead (both fields are disabled below
// and never sent in the edit payload, so this is display-only).
this.sharesAccountTermsForm.patchValue({
requestedShares: this.sharesAccountTemplate.summary.totalPendingForApprovalShares,
requestedShares: this.approvalEditMode
? this.sharesAccountTemplate.summary.totalApprovedShares
: this.sharesAccountTemplate.summary.totalPendingForApprovalShares,
minimumActivePeriod: this.sharesAccountTemplate.minimumActivePeriod,
minimumActivePeriodFrequencyType:
this.sharesAccountTemplate.minimumActivePeriod && this.sharesAccountTemplate.minimumActivePeriodTypeEnum.id,
lockinPeriodFrequency: this.sharesAccountTemplate.lockinPeriod,
lockinPeriodFrequencyType:
this.sharesAccountTemplate.lockinPeriod && this.sharesAccountTemplate.lockPeriodTypeEnum.id,
applicationDate:
this.sharesAccountTemplate.purchasedShares[0].purchasedDate &&
new Date(this.sharesAccountTemplate.purchasedShares[0].purchasedDate),
applicationDate: this.approvalEditMode
? this.sharesAccountTemplate.timeline.submittedOnDate &&
new Date(this.sharesAccountTemplate.timeline.submittedOnDate)
: this.sharesAccountTemplate.purchasedShares[0].purchasedDate &&
new Date(this.sharesAccountTemplate.purchasedShares[0].purchasedDate),
allowDividendCalculationForInactiveClients:
this.sharesAccountTemplate.allowDividendCalculationForInactiveClients
});
// Seeded directly here rather than left to the async product-template fetch in ngOnChanges:
// that fetch can resolve out of order and its own reset-to-'' would otherwise win the race.
if (!this.isSavingsPatched && this.sharesAccountTemplate.savingsAccountId) {
this.sharesAccountTermsForm.get('savingsAccountId').patchValue(this.sharesAccountTemplate.savingsAccountId);
this.isSavingsPatched = true;
}
}
if (this.approvalEditMode) {
this.sharesAccountTermsForm.get('requestedShares').disable();
@@ -105,15 +105,7 @@
<mat-menu #More="matMenu">
@for (option of buttonConfig.options; track option) {
<span>
<button
mat-menu-item
*mifosxHasPermission="option.taskPermissionName"
[disabled]="option.name === 'Edit Details'"
[matTooltip]="
option.name === 'Edit Details' ? ('tooltips.Editing details is disabled' | translate) : ''
"
(click)="doAction(option.name)"
>
<button mat-menu-item *mifosxHasPermission="option.taskPermissionName" (click)="doAction(option.name)">
{{ 'labels.menus.' + option.name | translate }}
</button>
</span>
+9
View File
@@ -17,6 +17,7 @@ import { ChargesTabComponent } from './shares-account-view/charges-tab/charges-t
import { DividendsTabComponent } from './shares-account-view/dividends-tab/dividends-tab.component';
import { CreateSharesAccountComponent } from './create-shares-account/create-shares-account.component';
import { EditSharesAccountComponent } from './edit-shares-account/edit-shares-account.component';
import { EditShareAccountDetailsComponent } from './edit-share-account-details/edit-share-account-details.component';
import { SharesAccountActionsComponent } from './shares-account-actions/shares-account-actions.component';
import { ShareHoldersComponent } from './share-holders/share-holders.component';
@@ -108,6 +109,14 @@ const routes: Routes = [
sharesAccountAndTemplate: SharesAccountAndTemplateResolver
}
},
{
path: 'edit-details',
data: { title: 'Edit Share Account Details', breadcrumb: 'Edit Details', routeParamBreadcrumb: false },
component: EditShareAccountDetailsComponent,
resolve: {
sharesAccountAndTemplate: SharesAccountAndTemplateResolver
}
},
{
path: 'actions/:name',
data: { title: 'Shares Account Actions', breadcrumb: 'Actions', routeParamBreadcrumb: 'name' },