WEB-401:redesign page layout and remove absolute positioning (#2947)
Added @if guards before accessing nested properties to prevent runtime errors if the API returns incomplete data
This commit is contained in:
+160
-132
@@ -1,143 +1,171 @@
|
|||||||
<!-- Version 1 -->
|
<div class="container m-b-20 layout-row align-end">
|
||||||
|
<button
|
||||||
|
mat-raised-button
|
||||||
|
color="primary"
|
||||||
|
*mifosxHasPermission="'READ_STANDINGINSTRUCTION'"
|
||||||
|
(click)="filterStandingInstructions()"
|
||||||
|
>
|
||||||
|
{{ 'labels.buttons.Filter' | translate | titlecase }}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
<mat-card class="container">
|
<mat-card class="container">
|
||||||
<div class="layout-row-wrap gap-2px responsive-column">
|
<mat-card-content>
|
||||||
@if (isFromClient) {
|
<div class="layout-row-wrap gap-20px responsive-column">
|
||||||
<div class="flex-fill">
|
@if (isFromClient) {
|
||||||
<span class="flex-40">
|
<div class="flex-100 layout-row align-items-center gap-20px">
|
||||||
<h3 class="mat-h3">{{ 'labels.heading.Client Type' | translate }}</h3>
|
<div>
|
||||||
</span>
|
<h3 class="mat-h3 no-m-b">{{ 'labels.heading.Client Type' | translate }}</h3>
|
||||||
<span class="client-Name">
|
</div>
|
||||||
<h3 class="mat-h3">{{ clientName }}</h3>
|
<div>
|
||||||
</span>
|
<h3 class="mat-h3 no-m-b">{{ clientName }}</h3>
|
||||||
</div>
|
</div>
|
||||||
}
|
</div>
|
||||||
|
}
|
||||||
|
|
||||||
@if (!isFromClient) {
|
@if (!isFromClient) {
|
||||||
<div class="flex-fill">
|
<mat-form-field class="flex-48">
|
||||||
<mat-form-field class="flex-30">
|
<mat-label>{{ 'labels.text.ClientName' | translate }}</mat-label>
|
||||||
<input matInput placeholder="{{ 'labels.text.ClientName' | translate }}" [formControl]="clientNameControl" />
|
<input matInput [formControl]="clientNameControl" />
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
<mat-form-field class="flex-30">
|
|
||||||
<input matInput placeholder="{{ 'labels.text.FromClientId' | translate }}" [formControl]="fromClientId" />
|
<mat-form-field class="flex-48">
|
||||||
|
<mat-label>{{ 'labels.text.FromClientId' | translate }}</mat-label>
|
||||||
|
<input matInput [formControl]="fromClientId" />
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
</div>
|
}
|
||||||
}
|
|
||||||
|
|
||||||
<mat-divider [inset]="true"></mat-divider>
|
<mat-form-field class="flex-48">
|
||||||
|
<mat-label>{{ 'labels.inputs.Type' | translate }}</mat-label>
|
||||||
|
<mat-select [formControl]="transferType">
|
||||||
|
@for (transferTypeData of transferTypeDatas; track transferTypeData) {
|
||||||
|
<mat-option [value]="transferTypeData.id">
|
||||||
|
{{ transferTypeData.value }}
|
||||||
|
</mat-option>
|
||||||
|
}
|
||||||
|
</mat-select>
|
||||||
|
</mat-form-field>
|
||||||
|
|
||||||
<mat-form-field class="type-field">
|
<mat-form-field class="flex-48">
|
||||||
<mat-label>{{ 'labels.inputs.Type' | translate }}</mat-label>
|
<mat-label>{{ 'labels.text.FromAccountId' | translate }}</mat-label>
|
||||||
<mat-select [formControl]="transferType">
|
<input matInput [formControl]="fromAccountId" />
|
||||||
@for (transferTypeData of transferTypeDatas; track transferTypeData) {
|
</mat-form-field>
|
||||||
<mat-option [value]="transferTypeData.id">
|
</div>
|
||||||
{{ transferTypeData.value }}
|
</mat-card-content>
|
||||||
</mat-option>
|
|
||||||
}
|
|
||||||
</mat-select>
|
|
||||||
</mat-form-field>
|
|
||||||
|
|
||||||
<mat-form-field class="account-Id-field">
|
<div class="table-container">
|
||||||
<input matInput placeholder="{{ 'labels.text.FromAccountId' | translate }}" [formControl]="fromAccountId" />
|
<table
|
||||||
</mat-form-field>
|
mat-table
|
||||||
|
#instructionsTable
|
||||||
<button
|
[dataSource]="dataSource"
|
||||||
mat-raised-button
|
class="bordered-table"
|
||||||
color="primary"
|
[attr.aria-label]="'labels.heading.List Standing Instructions' | translate"
|
||||||
*mifosxHasPermission="'READ_STANDINGINSTRUCTION'"
|
|
||||||
(click)="filterStandingInstructions()"
|
|
||||||
class="filter-button"
|
|
||||||
>
|
>
|
||||||
{{ 'labels.buttons.Filter' | translate | titlecase }}
|
<ng-container matColumnDef="client">
|
||||||
</button>
|
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Client' | translate }}</th>
|
||||||
|
<td mat-cell *matCellDef="let instruction">
|
||||||
|
@if (instruction?.fromClient) {
|
||||||
|
{{ instruction.fromClient.displayName }}-{{ instruction.fromClient.id }}
|
||||||
|
}
|
||||||
|
</td>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
|
<ng-container matColumnDef="fromAccount">
|
||||||
|
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.From Account' | translate }}</th>
|
||||||
|
<td mat-cell *matCellDef="let instruction">
|
||||||
|
@if (instruction?.fromAccount && instruction?.fromAccountType) {
|
||||||
|
{{ instruction.fromAccount.accountNo }} ({{ instruction.fromAccountType.value }})
|
||||||
|
}
|
||||||
|
</td>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
|
<ng-container matColumnDef="beneficiary">
|
||||||
|
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Beneficiary' | translate }}</th>
|
||||||
|
<td mat-cell *matCellDef="let instruction">
|
||||||
|
@if (instruction?.toClient) {
|
||||||
|
{{ instruction.toClient.displayName }}
|
||||||
|
}
|
||||||
|
</td>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
|
<ng-container matColumnDef="toAccount">
|
||||||
|
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.To Account' | translate }}</th>
|
||||||
|
<td mat-cell *matCellDef="let instruction">
|
||||||
|
@if (instruction?.toAccount && instruction?.toAccountType) {
|
||||||
|
{{ instruction.toAccount.accountNo }} ({{ instruction.toAccountType.value }})
|
||||||
|
}
|
||||||
|
</td>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
|
<ng-container matColumnDef="amount">
|
||||||
|
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Amount' | translate }}</th>
|
||||||
|
<td mat-cell *matCellDef="let instruction">
|
||||||
|
@if (instruction?.instructionType && instruction?.amount !== undefined) {
|
||||||
|
{{ instruction.instructionType.value }}/{{ instruction.amount }}
|
||||||
|
}
|
||||||
|
</td>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
|
<ng-container matColumnDef="validity">
|
||||||
|
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Validity' | translate }}</th>
|
||||||
|
<td mat-cell *matCellDef="let instruction">
|
||||||
|
@if (instruction?.validFrom && instruction?.validTill) {
|
||||||
|
{{ instruction.validFrom | dateFormat }} to {{ instruction.validTill | dateFormat }}
|
||||||
|
}
|
||||||
|
</td>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
|
<ng-container matColumnDef="actions">
|
||||||
|
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Actions' | translate }}</th>
|
||||||
|
<td mat-cell *matCellDef="let instruction">
|
||||||
|
@if (instruction?.status?.value !== 'Deleted') {
|
||||||
|
<span>
|
||||||
|
<button
|
||||||
|
class="account-action-button"
|
||||||
|
mat-raised-button
|
||||||
|
color="primary"
|
||||||
|
[attr.aria-label]="'tooltips.Edit Standing Instruction' | translate"
|
||||||
|
matTooltip="{{ 'tooltips.Edit Standing Instruction' | translate }}"
|
||||||
|
*mifosxHasPermission="'UPDATE_STANDINGINSTRUCTION'"
|
||||||
|
[routerLink]="['../', instruction.id, 'edit']"
|
||||||
|
>
|
||||||
|
<i class="fa fa-edit"></i>
|
||||||
|
</button>
|
||||||
|
</span>
|
||||||
|
}
|
||||||
|
@if (instruction?.status?.value !== 'Deleted') {
|
||||||
|
<span>
|
||||||
|
<button
|
||||||
|
class="account-action-button"
|
||||||
|
mat-raised-button
|
||||||
|
color="warn"
|
||||||
|
[attr.aria-label]="'tooltips.Delete Standing Instruction' | translate"
|
||||||
|
matTooltip="{{ 'tooltips.Delete Standing Instruction' | translate }}"
|
||||||
|
*mifosxHasPermission="'DELETE_STANDINGINSTRUCTION'"
|
||||||
|
(click)="deleteStandingInstruction(instruction.id)"
|
||||||
|
>
|
||||||
|
<i class="fa fa-times"></i>
|
||||||
|
</button>
|
||||||
|
</span>
|
||||||
|
}
|
||||||
|
<button
|
||||||
|
class="account-action-button"
|
||||||
|
mat-raised-button
|
||||||
|
color="primary"
|
||||||
|
[attr.aria-label]="'tooltips.View Standing Instruction' | translate"
|
||||||
|
matTooltip="{{ 'tooltips.View Standing Instruction' | translate }}"
|
||||||
|
*mifosxHasPermission="'READ_STANDINGINSTRUCTION'"
|
||||||
|
[routerLink]="['../', instruction.id, 'view']"
|
||||||
|
>
|
||||||
|
<i class="fa fa-eye"></i>
|
||||||
|
</button>
|
||||||
|
</td>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
|
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
|
||||||
|
<tr mat-row *matRowDef="let row; columns: displayedColumns"></tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<mat-paginator [pageSize]="10" [pageSizeOptions]="[10, 25, 50, 100]" showFirstLastButtons></mat-paginator>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<table mat-table #instructionsTable [dataSource]="dataSource">
|
|
||||||
<ng-container matColumnDef="client">
|
|
||||||
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Client' | translate }}</th>
|
|
||||||
<td mat-cell *matCellDef="let instruction">
|
|
||||||
{{ instruction.fromClient.displayName }}-{{ instruction.fromClient.id }}
|
|
||||||
</td>
|
|
||||||
</ng-container>
|
|
||||||
|
|
||||||
<ng-container matColumnDef="fromAccount">
|
|
||||||
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.From Account' | translate }}</th>
|
|
||||||
<td mat-cell *matCellDef="let instruction">
|
|
||||||
{{ instruction.fromAccount.accountNo }} ({{ instruction.fromAccountType.value }})
|
|
||||||
</td>
|
|
||||||
</ng-container>
|
|
||||||
|
|
||||||
<ng-container matColumnDef="beneficiary">
|
|
||||||
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Beneficiary' | translate }}</th>
|
|
||||||
<td mat-cell *matCellDef="let instruction">{{ instruction.toClient.displayName }}</td>
|
|
||||||
</ng-container>
|
|
||||||
|
|
||||||
<ng-container matColumnDef="toAccount">
|
|
||||||
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.To Account' | translate }}</th>
|
|
||||||
<td mat-cell *matCellDef="let instruction">
|
|
||||||
{{ instruction.toAccount.accountNo }} ({{ instruction.toAccountType.value }})
|
|
||||||
</td>
|
|
||||||
</ng-container>
|
|
||||||
|
|
||||||
<ng-container matColumnDef="amount">
|
|
||||||
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Amount' | translate }}</th>
|
|
||||||
<td mat-cell *matCellDef="let instruction">{{ instruction.instructionType.value }}/{{ instruction.amount }}</td>
|
|
||||||
</ng-container>
|
|
||||||
|
|
||||||
<ng-container matColumnDef="validity">
|
|
||||||
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Validity' | translate }}</th>
|
|
||||||
<td mat-cell *matCellDef="let instruction">
|
|
||||||
{{ instruction.validFrom | dateFormat }} to {{ instruction.validTill | dateFormat }}
|
|
||||||
</td>
|
|
||||||
</ng-container>
|
|
||||||
|
|
||||||
<ng-container matColumnDef="actions">
|
|
||||||
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Actions' | translate }}</th>
|
|
||||||
<td mat-cell *matCellDef="let instruction">
|
|
||||||
@if (instruction.status.value !== 'Deleted') {
|
|
||||||
<span>
|
|
||||||
<button
|
|
||||||
class="account-action-button"
|
|
||||||
mat-raised-button
|
|
||||||
color="primary"
|
|
||||||
matTooltip="{{ 'tooltips.Edit Standing Instruction' | translate }}"
|
|
||||||
*mifosxHasPermission="'UPDATE_STANDINGINSTRUCTION'"
|
|
||||||
[routerLink]="['../', instruction.id, 'edit']"
|
|
||||||
>
|
|
||||||
<i class="fa fa-edit"></i>
|
|
||||||
</button>
|
|
||||||
</span>
|
|
||||||
}
|
|
||||||
@if (instruction.status.value !== 'Deleted') {
|
|
||||||
<span>
|
|
||||||
<button
|
|
||||||
class="account-action-button"
|
|
||||||
mat-raised-button
|
|
||||||
color="warn"
|
|
||||||
matTooltip="{{ 'tooltips.Delete Standing Instruction' | translate }}"
|
|
||||||
*mifosxHasPermission="'DELETE_STANDINGINSTRUCTION'"
|
|
||||||
(click)="deleteStandingInstruction(instruction.id)"
|
|
||||||
>
|
|
||||||
<i class="fa fa-times"></i>
|
|
||||||
</button>
|
|
||||||
</span>
|
|
||||||
}
|
|
||||||
<button
|
|
||||||
class="account-action-button"
|
|
||||||
mat-raised-button
|
|
||||||
color="primary"
|
|
||||||
matTooltip="{{ 'tooltips.View Standing Instruction' | translate }}"
|
|
||||||
*mifosxHasPermission="'READ_STANDINGINSTRUCTION'"
|
|
||||||
[routerLink]="['../', instruction.id, 'view']"
|
|
||||||
>
|
|
||||||
<i class="fa fa-eye"></i>
|
|
||||||
</button>
|
|
||||||
</td>
|
|
||||||
</ng-container>
|
|
||||||
|
|
||||||
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
|
|
||||||
<tr mat-row *matRowDef="let row; columns: displayedColumns"></tr>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
<mat-paginator [pageSize]="10" [pageSizeOptions]="[10, 25, 50, 100]" showFirstLastButtons></mat-paginator>
|
|
||||||
</mat-card>
|
</mat-card>
|
||||||
|
|||||||
+26
-20
@@ -1,23 +1,29 @@
|
|||||||
// Version 1
|
|
||||||
|
|
||||||
.container {
|
.container {
|
||||||
.filter-button {
|
.table-container {
|
||||||
height: 2.5rem;
|
margin-top: 1rem;
|
||||||
margin-top: 2rem;
|
|
||||||
|
.bordered-table {
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
.account-action-button {
|
||||||
|
min-width: 1.625rem;
|
||||||
|
padding: 0 0.375rem;
|
||||||
|
margin: 0.25rem;
|
||||||
|
line-height: 1.5625rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
th,
|
||||||
|
td {
|
||||||
|
padding: 0.75rem 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
th {
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mat-paginator {
|
||||||
|
border-top: 1px solid #e0e0e0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
table {
|
|
||||||
width: 100%;
|
|
||||||
|
|
||||||
.account-action-button {
|
|
||||||
min-width: 26px;
|
|
||||||
padding: 0 6px;
|
|
||||||
margin: 4px;
|
|
||||||
line-height: 25px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.mat-divider {
|
|
||||||
border-top-color: #fff;
|
|
||||||
}
|
|
||||||
|
|||||||
-2
@@ -24,7 +24,6 @@ import { AccountTransfersService } from '../account-transfers.service';
|
|||||||
/** Dialog Components */
|
/** Dialog Components */
|
||||||
import { DeleteDialogComponent } from 'app/shared/delete-dialog/delete-dialog.component';
|
import { DeleteDialogComponent } from 'app/shared/delete-dialog/delete-dialog.component';
|
||||||
import { SettingsService } from 'app/settings/settings.service';
|
import { SettingsService } from 'app/settings/settings.service';
|
||||||
import { MatDivider } from '@angular/material/divider';
|
|
||||||
import { MatTooltip } from '@angular/material/tooltip';
|
import { MatTooltip } from '@angular/material/tooltip';
|
||||||
import { DateFormatPipe } from '../../pipes/date-format.pipe';
|
import { DateFormatPipe } from '../../pipes/date-format.pipe';
|
||||||
import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module';
|
import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module';
|
||||||
@@ -38,7 +37,6 @@ import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module';
|
|||||||
styleUrls: ['./list-standing-instructions.component.scss'],
|
styleUrls: ['./list-standing-instructions.component.scss'],
|
||||||
imports: [
|
imports: [
|
||||||
...STANDALONE_SHARED_IMPORTS,
|
...STANDALONE_SHARED_IMPORTS,
|
||||||
MatDivider,
|
|
||||||
MatTable,
|
MatTable,
|
||||||
MatColumnDef,
|
MatColumnDef,
|
||||||
MatHeaderCellDef,
|
MatHeaderCellDef,
|
||||||
|
|||||||
@@ -651,23 +651,3 @@ mat-card {
|
|||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Re-positions account type field on list standing instructions page
|
|
||||||
.type-field {
|
|
||||||
position: absolute;
|
|
||||||
left: 1px;
|
|
||||||
top: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Re-positions account id field on list standing instructions page
|
|
||||||
.account-Id-field {
|
|
||||||
position: absolute;
|
|
||||||
left: 490px;
|
|
||||||
top: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Re-positions client name label on list standing instructions page
|
|
||||||
.client-Name {
|
|
||||||
position: absolute;
|
|
||||||
left: 490px;
|
|
||||||
}
|
|
||||||
|
|||||||
Reference in New Issue
Block a user