Use of filter in the GL Account dropdown menus
This commit is contained in:
committed by
Adam Saghy
parent
6edb262028
commit
53d8436875
@@ -0,0 +1,13 @@
|
||||
<span *ngIf="accountTitle">
|
||||
<div fxFlex="{{withTitle}}" class="header">
|
||||
{{'labels.inputs.' + accountTitle | translate}}
|
||||
</div>
|
||||
|
||||
<div fxFlex="{{withAccount}}">
|
||||
{{glAccountValue()}}
|
||||
</div>
|
||||
</span>
|
||||
|
||||
<div fxFlex="100%" *ngIf="!accountTitle">
|
||||
{{glAccountValue()}}
|
||||
</div>
|
||||
@@ -0,0 +1,8 @@
|
||||
div {
|
||||
margin: 0.3rem 0;
|
||||
word-wrap: break-word;
|
||||
|
||||
&.header {
|
||||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { GlAccountDisplayComponent } from './gl-account-display.component';
|
||||
|
||||
describe('GlAccountDisplayComponent', () => {
|
||||
let component: GlAccountDisplayComponent;
|
||||
let fixture: ComponentFixture<GlAccountDisplayComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [ GlAccountDisplayComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
|
||||
fixture = TestBed.createComponent(GlAccountDisplayComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,28 @@
|
||||
import { Component, Input, OnInit } from '@angular/core';
|
||||
import { GLAccount } from 'app/shared/models/general.model';
|
||||
|
||||
@Component({
|
||||
selector: 'mifosx-gl-account-display',
|
||||
templateUrl: './gl-account-display.component.html',
|
||||
styleUrls: ['./gl-account-display.component.scss']
|
||||
})
|
||||
export class GlAccountDisplayComponent implements OnInit {
|
||||
|
||||
@Input() glAccount: GLAccount | null = null;
|
||||
@Input() accountTitle: string | null = null;
|
||||
@Input() withTitle = '50%';
|
||||
@Input() withAccount = '50%';
|
||||
|
||||
constructor() { }
|
||||
|
||||
ngOnInit(): void {
|
||||
}
|
||||
|
||||
glAccountValue(): string {
|
||||
if (this.glAccount) {
|
||||
return '(' + this.glAccount.glCode + ') ' + (this.glAccount.nameDecorated ? this.glAccount.nameDecorated : this.glAccount.name);
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
<mat-form-field fxFlex="100%" *ngIf="required">
|
||||
<mat-label>{{'labels.inputs.' + inputLabel | translate}}</mat-label>
|
||||
|
||||
<mat-select required [formControl]="inputFormControl">
|
||||
<mat-option>
|
||||
<ngx-mat-select-search [formControl]="filterFormCtrl"></ngx-mat-select-search>
|
||||
</mat-option>
|
||||
<mat-option *ngFor="let glAccount of glAccountData | async" [value]="glAccount.id">
|
||||
{{ '(' + glAccount.glCode + ') ' + glAccount.name }}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
<mat-error *ngIf="inputFormControl.hasError('required')">
|
||||
{{"labels.inputs.Account"| translate}} {{"labels.commons.is" | translate}} <strong>{{"labels.commons.required" | translate}}</strong>
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field fxFlex="100%" *ngIf="!required">
|
||||
<mat-label>{{'labels.inputs.' + inputLabel | translate}}</mat-label>
|
||||
|
||||
<mat-select [formControl]="inputFormControl">
|
||||
<mat-option>
|
||||
<ngx-mat-select-search [formControl]="filterFormCtrl"
|
||||
placeholderLabel="{{placeHolderLabel}}"
|
||||
noEntriesFoundLabel="{{noEntriesFoundLabel}}">
|
||||
</ngx-mat-select-search>
|
||||
</mat-option>
|
||||
<mat-option *ngFor="let glAccount of glAccountData | async" [value]="glAccount.id">
|
||||
{{ '(' + glAccount.glCode + ') ' + glAccount.name }}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
@@ -0,0 +1,23 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { GlAccountSelectorComponent } from './gl-account-selector.component';
|
||||
|
||||
describe('GlAccountSelectorComponent', () => {
|
||||
let component: GlAccountSelectorComponent;
|
||||
let fixture: ComponentFixture<GlAccountSelectorComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [ GlAccountSelectorComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
|
||||
fixture = TestBed.createComponent(GlAccountSelectorComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,71 @@
|
||||
import { Component, Input, OnChanges, OnDestroy, OnInit, SimpleChanges } from '@angular/core';
|
||||
import { UntypedFormControl } from '@angular/forms';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { GLAccount } from 'app/shared/models/general.model';
|
||||
import { ReplaySubject, Subject } from 'rxjs';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
|
||||
@Component({
|
||||
selector: 'mifosx-gl-account-selector',
|
||||
templateUrl: './gl-account-selector.component.html',
|
||||
styleUrls: ['./gl-account-selector.component.scss']
|
||||
})
|
||||
export class GlAccountSelectorComponent implements OnInit, OnChanges, OnDestroy {
|
||||
|
||||
@Input() inputFormControl: UntypedFormControl;
|
||||
@Input() glAccountList: GLAccount[] = [];
|
||||
@Input() required = false;
|
||||
@Input() inputLabel = '';
|
||||
|
||||
/** GL Account data. */
|
||||
protected glAccountData: ReplaySubject<GLAccount[]> = new ReplaySubject<GLAccount[]>(1);
|
||||
|
||||
/** control for the filter select */
|
||||
protected filterFormCtrl: UntypedFormControl = new UntypedFormControl('');
|
||||
|
||||
/** Subject that emits when the component has been destroyed. */
|
||||
protected _onDestroy = new Subject<void>();
|
||||
|
||||
placeHolderLabel = '';
|
||||
noEntriesFoundLabel = '';
|
||||
|
||||
constructor(private translateService: TranslateService) { }
|
||||
|
||||
ngOnInit(): void {
|
||||
// listen for search field value changes
|
||||
this.filterFormCtrl.valueChanges
|
||||
.pipe(takeUntil(this._onDestroy))
|
||||
.subscribe(() => {
|
||||
this.searchGLAccount();
|
||||
});
|
||||
|
||||
this.placeHolderLabel = this.translateService.instant('labels.inputs.Filter');
|
||||
this.noEntriesFoundLabel = this.translateService.instant('labels.text.No data found');
|
||||
}
|
||||
|
||||
ngOnChanges(changes: SimpleChanges): void {
|
||||
if (this.glAccountList) {
|
||||
this.glAccountData.next(this.glAccountList.slice());
|
||||
}
|
||||
}
|
||||
|
||||
ngOnDestroy(): void {
|
||||
this._onDestroy.next();
|
||||
this._onDestroy.complete();
|
||||
}
|
||||
|
||||
searchGLAccount(): void {
|
||||
if (this.glAccountList) {
|
||||
const search: string = this.filterFormCtrl.value.toLowerCase();
|
||||
|
||||
if (!search) {
|
||||
this.glAccountData.next(this.glAccountList.slice());
|
||||
} else {
|
||||
this.glAccountData.next(this.glAccountList.filter((option: GLAccount) => {
|
||||
return option.name.toLowerCase().indexOf(search) >= 0 || option.glCode.toLowerCase().indexOf(search) >= 0;
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -32,6 +32,7 @@ import {
|
||||
faDollarSign,
|
||||
faEdit,
|
||||
faEnvelope,
|
||||
faExchange,
|
||||
faExclamationCircle,
|
||||
faExclamationTriangle,
|
||||
faEye,
|
||||
@@ -154,6 +155,7 @@ export class IconsModule {
|
||||
faDollarSign,
|
||||
faEdit,
|
||||
faEnvelope,
|
||||
faExchange,
|
||||
faExclamationCircle,
|
||||
faExclamationTriangle,
|
||||
faEye,
|
||||
|
||||
@@ -38,6 +38,7 @@ import { MatTabsModule } from '@angular/material/tabs';
|
||||
import { MatToolbarModule } from '@angular/material/toolbar';
|
||||
import { MatTooltipModule } from '@angular/material/tooltip';
|
||||
import { MatTreeModule } from '@angular/material/tree';
|
||||
import { NgxMatSelectSearchModule } from 'ngx-mat-select-search';
|
||||
|
||||
/**
|
||||
* Material Module
|
||||
@@ -71,6 +72,7 @@ import { MatTreeModule } from '@angular/material/tree';
|
||||
MatProgressSpinnerModule,
|
||||
MatRadioModule,
|
||||
MatSelectModule,
|
||||
NgxMatSelectSearchModule,
|
||||
MatSidenavModule,
|
||||
MatSliderModule,
|
||||
MatSlideToggleModule,
|
||||
|
||||
@@ -15,6 +15,7 @@ export interface GLAccount {
|
||||
name: string;
|
||||
glCode: string;
|
||||
description: string;
|
||||
nameDecorated?: string;
|
||||
disabled: boolean;
|
||||
manualEntriesAllowed: boolean;
|
||||
type: OptionData;
|
||||
|
||||
@@ -43,6 +43,8 @@ import { AccountNumberComponent } from './account-number/account-number.componen
|
||||
import { EntityNameComponent } from './entity-name/entity-name.component';
|
||||
import { TransactionPaymentDetailComponent } from './transaction-payment-detail/transaction-payment-detail.component';
|
||||
import { StepperButtonsComponent } from './steppers/stepper-buttons/stepper-buttons.component';
|
||||
import { GlAccountSelectorComponent } from './accounting/gl-account-selector/gl-account-selector.component';
|
||||
import { GlAccountDisplayComponent } from './accounting/gl-account-display/gl-account-display.component';
|
||||
|
||||
/**
|
||||
* Shared Module
|
||||
@@ -92,7 +94,9 @@ import { StepperButtonsComponent } from './steppers/stepper-buttons/stepper-butt
|
||||
AccountNumberComponent,
|
||||
EntityNameComponent,
|
||||
TransactionPaymentDetailComponent,
|
||||
StepperButtonsComponent
|
||||
StepperButtonsComponent,
|
||||
GlAccountSelectorComponent,
|
||||
GlAccountDisplayComponent
|
||||
],
|
||||
exports: [
|
||||
FileUploadComponent,
|
||||
@@ -120,7 +124,9 @@ import { StepperButtonsComponent } from './steppers/stepper-buttons/stepper-butt
|
||||
SvgIconComponent,
|
||||
EntityNameComponent,
|
||||
TransactionPaymentDetailComponent,
|
||||
StepperButtonsComponent
|
||||
StepperButtonsComponent,
|
||||
GlAccountSelectorComponent,
|
||||
GlAccountDisplayComponent
|
||||
]
|
||||
})
|
||||
export class SharedModule { }
|
||||
|
||||
Reference in New Issue
Block a user