Add Boolean filter field

- Add boolean filter component
-- Use same implementation as in enums
- Fix karma/jasmine tests
This commit is contained in:
Clemente Raposo 2020-12-31 15:13:50 +00:00 committed by Dillon-Brown
parent af186a7013
commit 8eff4e16b7
7 changed files with 244 additions and 107 deletions

View file

@ -0,0 +1,20 @@
<tag-input #tag
(onAdd)="onAdd($event)"
(onRemove)="onRemove()"
[(ngModel)]="selectedValues"
[class]="getInvalidClass()"
[clearOnBlur]="true"
[displayBy]="'label'"
[identifyBy]="'value'"
[inputClass]="getInvalidClass()"
[onlyFromAutocomplete]="true"
[placeholder]="getPlaceholderLabel()"
[secondaryPlaceholder]="getPlaceholderLabel()"
maxItems="1">
<tag-input-dropdown [autocompleteItems]="this.options"
[displayBy]="'label'"
[identifyBy]="'value'"
[keepOpen]="false"
[showDropdownIfEmpty]="true">
</tag-input-dropdown>
</tag-input>

View file

@ -0,0 +1,126 @@
import {async, ComponentFixture, TestBed} from '@angular/core/testing';
import {Component} from '@angular/core';
import {BooleanFilterFieldComponent} from './boolean.component';
import {FormControl, FormsModule} from '@angular/forms';
import {Field} from '@app-common/record/field.model';
import {UserPreferenceStore} from '@store/user-preference/user-preference.store';
import {userPreferenceStoreMock} from '@store/user-preference/user-preference.store.spec.mock';
import {NumberFormatter} from '@services/formatters/number/number-formatter.service';
import {numberFormatterMock} from '@services/formatters/number/number-formatter.spec.mock';
import {DatetimeFormatter} from '@services/formatters/datetime/datetime-formatter.service';
import {datetimeFormatterMock} from '@services/formatters/datetime/datetime-formatter.service.spec.mock';
import {DateFormatter} from '@services/formatters/datetime/date-formatter.service';
import {dateFormatterMock} from '@services/formatters/datetime/date-formatter.service.spec.mock';
import {CurrencyFormatter} from '@services/formatters/currency/currency-formatter.service';
import {TagInputModule} from 'ngx-chips';
import {BrowserDynamicTestingModule} from '@angular/platform-browser-dynamic/testing';
import {BrowserAnimationsModule} from '@angular/platform-browser/animations';
import {LanguageStore} from '@store/language/language.store';
import {languageStoreMock} from '@store/language/language.store.spec.mock';
@Component({
selector: 'boolean-filter-field-test-host-component',
template: '<scrm-boolean-filter [field]="field"></scrm-boolean-filter>'
})
class BooleanFilterFieldTestHostComponent {
field: Field = {
type: 'boolean',
value: '1',
metadata: null,
definition: {
options: 'dom_int_bool'
},
criteria: {
values: ['1'],
operator: '='
},
formControl: new FormControl('1')
};
}
describe('BooleanFilterFieldComponent', () => {
let testHostComponent: BooleanFilterFieldTestHostComponent;
let testHostFixture: ComponentFixture<BooleanFilterFieldTestHostComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [
BooleanFilterFieldTestHostComponent,
BooleanFilterFieldComponent,
],
imports: [
TagInputModule,
FormsModule,
BrowserDynamicTestingModule,
BrowserAnimationsModule
],
providers: [
{provide: LanguageStore, useValue: languageStoreMock},
{provide: UserPreferenceStore, useValue: userPreferenceStoreMock},
{provide: NumberFormatter, useValue: numberFormatterMock},
{provide: DatetimeFormatter, useValue: datetimeFormatterMock},
{provide: DateFormatter, useValue: dateFormatterMock},
{
provide: CurrencyFormatter,
useValue: new CurrencyFormatter(userPreferenceStoreMock, numberFormatterMock, 'en_us')
},
],
}).compileComponents();
testHostFixture = TestBed.createComponent(BooleanFilterFieldTestHostComponent);
testHostComponent = testHostFixture.componentInstance;
testHostFixture.detectChanges();
}));
it('should create', () => {
expect(testHostComponent).toBeTruthy();
});
it('should have value', () => {
expect(testHostComponent).toBeTruthy();
testHostComponent.field = {
type: 'boolean',
value: '1',
metadata: null,
definition: {
options: 'dom_int_bool'
},
criteria: {
values: ['1'],
operator: '='
},
formControl: new FormControl('1')
};
testHostFixture.detectChanges();
testHostFixture.whenStable().then(() => {
const field = testHostFixture.nativeElement.getElementsByTagName('scrm-boolean-filter')[0];
expect(field).toBeTruthy();
const tagInput = field.getElementsByTagName('tag-input').item(0);
expect(tagInput).toBeTruthy();
const tag = tagInput.getElementsByTagName('tag').item(0);
expect(tag).toBeTruthy();
const tagText = tag.getElementsByClassName('tag__text').item(0);
expect(tagText.textContent).toContain('Yes');
expect(tagText.textContent).not.toContain('1');
const deleteIcon = tagInput.getElementsByTagName('delete-icon').item(0);
expect(deleteIcon).toBeTruthy();
});
});
});

View file

@ -0,0 +1,63 @@
import {Component, OnDestroy, OnInit, ViewChild} from '@angular/core';
import {DataTypeFormatter} from '@services/formatters/data-type.formatter.service';
import {TagInputComponent} from 'ngx-chips';
import {LanguageStore} from '@store/language/language.store';
import {BaseEnumComponent} from '@fields/base/base-enum.component';
@Component({
selector: 'scrm-boolean-filter',
templateUrl: './boolean.component.html',
styleUrls: []
})
export class BooleanFilterFieldComponent extends BaseEnumComponent implements OnInit, OnDestroy {
@ViewChild('tag') tag: TagInputComponent;
constructor(protected languages: LanguageStore, protected typeFormatter: DataTypeFormatter) {
super(languages, typeFormatter);
}
ngOnInit(): void {
this.field.value = '';
if (this.field.criteria.values && this.field.criteria.values.length > 0) {
this.field.value = this.field.criteria.values[0];
}
super.ngOnInit();
}
public onAdd(item): void {
if (item && item.value) {
this.field.value = item.value;
this.field.formControl.setValue(item.value);
this.field.criteria.operator = '=';
this.field.criteria.values = [item.value];
return;
}
this.field.value = '';
this.field.formControl.setValue('');
this.selectedValues = [];
this.field.criteria.operator = '';
this.field.criteria.values = [];
return;
}
public onRemove(): void {
this.field.value = '';
this.field.formControl.setValue('');
this.field.criteria.operator = '';
this.field.criteria.values = [];
setTimeout(() => {
this.tag.focus(true, true);
this.tag.dropdown.show();
}, 200);
}
public getPlaceholderLabel(): string {
return this.languages.getAppString('LBL_SELECT_ITEM') || '';
}
}

View file

@ -0,0 +1,21 @@
import {NgModule} from '@angular/core';
import {CommonModule} from '@angular/common';
import {AppManagerModule} from '@base/app-manager/app-manager.module';
import {BooleanFilterFieldComponent} from './boolean.component';
import {FormsModule, ReactiveFormsModule} from '@angular/forms';
import {TagInputModule} from 'ngx-chips';
@NgModule({
declarations: [BooleanFilterFieldComponent],
exports: [BooleanFilterFieldComponent],
imports: [
CommonModule,
AppManagerModule.forChild(BooleanFilterFieldComponent),
FormsModule,
ReactiveFormsModule,
TagInputModule
]
})
export class BooleanFilterFieldModule {
}

View file

@ -111,108 +111,4 @@ describe('DynamicEnumEditFieldComponent', () => {
});
});
it('should allow removing value', () => {
expect(testHostComponent).toBeTruthy();
const element = testHostFixture.nativeElement;
testHostComponent.field = {
type: 'dynamicenum',
value: '_customer',
metadata: null,
definition: {
options: 'account_type_dom'
}
};
testHostFixture.detectChanges();
testHostFixture.whenStable().then(() => {
const deleteIcon = element.getElementsByTagName('delete-icon').item(0);
expect(deleteIcon).toBeTruthy();
deleteIcon.click();
testHostFixture.detectChanges();
testHostFixture.whenRenderingDone().then(() => {
const tag = element.getElementsByClassName('tag__text');
expect(tag).toBeTruthy();
expect(tag.length).toEqual(0);
});
});
});
it('should allow adding value', () => {
expect(testHostComponent).toBeTruthy();
const element = testHostFixture.nativeElement;
testHostComponent.field = {
type: 'dynamicenum',
value: '_customer',
metadata: null,
definition: {
options: 'account_type_dom'
}
};
testHostFixture.detectChanges();
testHostFixture.whenStable().then(() => {
const deleteIcon = element.getElementsByTagName('delete-icon').item(0);
expect(deleteIcon).toBeTruthy();
deleteIcon.click();
testHostFixture.detectChanges();
testHostFixture.whenRenderingDone().then(() => {
const input = element.getElementsByTagName('tag-input-form').item(0);
input.click();
testHostFixture.detectChanges();
testHostFixture.whenRenderingDone().then(() => {
const menu = window.document.getElementsByClassName('ng2-dropdown-menu').item(0);
const item = menu.getElementsByClassName('ng2-menu-item').item(0);
expect(menu).toBeTruthy();
expect(item).toBeTruthy();
item.parentElement.click();
testHostFixture.detectChanges();
testHostFixture.whenRenderingDone().then(() => {
const tag = element.getElementsByTagName('tag').item(0);
expect(tag).toBeTruthy();
const tagText = tag.getElementsByClassName('tag__text').item(0);
expect(tagText.textContent).toContain('Customer');
expect(tagText.textContent).not.toContain('_customer');
const newDeleteIcon = element.getElementsByTagName('delete-icon').item(0);
expect(newDeleteIcon).toBeTruthy();
});
});
});
});
});
});

View file

@ -46,6 +46,8 @@ import {DynamicEnumDetailFieldModule} from '@fields/dynamicenum/templates/detail
import {DynamicEnumEditFieldModule} from '@fields/dynamicenum/templates/edit/dynamicenum.module';
import {DynamicEnumDetailFieldComponent} from '@fields/dynamicenum/templates/detail/dynamicenum.component';
import {DynamicEnumEditFieldComponent} from '@fields/dynamicenum/templates/edit/dynamicenum.component';
import {BooleanFilterFieldModule} from '@fields/boolean/templates/filter/boolean.module';
import {BooleanFilterFieldComponent} from '@fields/boolean/templates/filter/boolean.component';
export const fieldModules = [
VarcharDetailFieldModule,
@ -71,7 +73,8 @@ export const fieldModules = [
DynamicEnumDetailFieldModule,
DynamicEnumEditFieldModule,
BooleanDetailFieldModule,
BooleanEditFieldModule
BooleanEditFieldModule,
BooleanFilterFieldModule
];
export const fieldComponents = [
VarcharDetailFieldComponent,
@ -97,7 +100,8 @@ export const fieldComponents = [
DynamicEnumDetailFieldComponent,
DynamicEnumEditFieldComponent,
BooleanDetailFieldComponent,
BooleanEditFieldComponent
BooleanEditFieldComponent,
BooleanFilterFieldComponent
];
export const viewFieldsMap = {
@ -144,7 +148,9 @@ export const viewFieldsMap = {
'boolean.list': BooleanDetailFieldComponent,
'boolean.detail': BooleanDetailFieldComponent,
'boolean.edit': BooleanEditFieldComponent,
'boolean.filter': BooleanFilterFieldComponent,
'bool.list': BooleanDetailFieldComponent,
'bool.detail': BooleanDetailFieldComponent,
'bool.edit': BooleanEditFieldComponent
'bool.edit': BooleanEditFieldComponent,
'bool.filter': BooleanFilterFieldComponent
};

View file

@ -67,6 +67,11 @@ export const languageMockData = {
_reseller: 'Reseller',
_other: 'Other'
},
// eslint-disable-next-line camelcase,@typescript-eslint/camelcase
dom_int_bool: {
1: 'Yes',
0: 'No',
},
},
modStrings: {
home: {