Skip to content

[NAE-2047] Fulltext search and advanced search usability with multichoice caseRef #272

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: release/6.5.0
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export abstract class AbstractCaseRefBaseFieldComponent<T extends DataField<unkn
}
let providers = [
{
provide: NAE_DEFAULT_HEADERS, useValue: this.dataField.component?.properties?.headers.split(',')
provide: NAE_DEFAULT_HEADERS, useValue: this.dataField.component?.properties?.headers?.split(',')
},
{
provide: NAE_CASE_REF_CREATE_CASE, useValue: this.dataField.component?.properties?.createCase === 'true'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import {HttpClientTestingModule} from '@angular/common/http/testing';
import {MatIconModule} from '@angular/material/icon';
import {BrowserDynamicTestingModule} from '@angular/platform-browser-dynamic/testing';
import {MockAuthenticationMethodService} from '../utility/tests/mocks/mock-authentication-method-service';
import {Component, Injector, Optional} from '@angular/core';
import {Component, Inject, Injector, Optional} from '@angular/core';
import {AbstractHeaderComponent} from './abstract-header.component';
import {TranslateLibModule} from '../translate/translate-lib.module';
import {RouterTestingModule} from '@angular/router/testing';
Expand All @@ -29,6 +29,13 @@ import {OverflowService} from './services/overflow.service';
import {AllowedNetsService} from '../allowed-nets/services/allowed-nets.service';
import {TestNoAllowedNetsFactory} from '../utility/tests/test-factory-methods';
import {AllowedNetsServiceFactory} from '../allowed-nets/services/factory/allowed-nets-service-factory';
import {CaseViewService} from "../view/case-view/service/case-view-service";
import {
DATA_FIELD_PORTAL_DATA,
DataFieldPortalData
} from "../data-fields/models/data-field-portal-data-injection-token";
import {MultichoiceField} from "../data-fields/multichoice-field/models/multichoice-field";
import {EnumerationField} from "../data-fields/enumeration-field/models/enumeration-field";

describe('AbstractHeaderComponent', () => {
let component: TestHeaderComponent;
Expand Down Expand Up @@ -89,7 +96,9 @@ describe('AbstractHeaderComponent', () => {
class TestHeaderComponent extends AbstractHeaderComponent {
constructor(protected _injector: Injector,
protected _translate: TranslateService,
@Optional() protected _overflowService: OverflowService) {
super(_injector, _translate, _overflowService);
@Optional() protected _overflowService: OverflowService,
@Optional() protected _caseViewService: CaseViewService,
@Optional() @Inject(DATA_FIELD_PORTAL_DATA) protected _dataFieldPortalData: DataFieldPortalData<MultichoiceField | EnumerationField>) {
super(_injector, _translate, _overflowService, _caseViewService, _dataFieldPortalData);
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {Component, Injector, Input, OnDestroy, OnInit, Optional} from '@angular/core';
import {Component, Inject, Injector, Input, OnDestroy, OnInit, Optional} from '@angular/core';
import {AbstractHeaderService} from './abstract-header-service';
import {CaseHeaderService} from './case-header/case-header.service';
import {TaskHeaderService} from './task-header/task-header.service';
Expand All @@ -12,6 +12,13 @@ import {OverflowService} from './services/overflow.service';
import {stopPropagation} from '../utility/stop-propagation';
import {Subscription} from 'rxjs';
import {debounceTime} from "rxjs/operators";
import {CaseViewService} from "../view/case-view/service/case-view-service";
import {
DATA_FIELD_PORTAL_DATA,
DataFieldPortalData
} from "../data-fields/models/data-field-portal-data-injection-token";
import {MultichoiceField} from "../data-fields/multichoice-field/models/multichoice-field";
import {EnumerationField} from "../data-fields/enumeration-field/models/enumeration-field";

@Component({
selector: 'ncc-abstract-header',
Expand Down Expand Up @@ -45,11 +52,16 @@ export abstract class AbstractHeaderComponent implements OnInit, OnDestroy {
protected _initHeaderCount: number = undefined;
protected _initResponsiveHeaders: boolean = undefined;
protected _approvalFormControl: FormControl;
protected _changeValue: boolean;
protected _subCases: Subscription;

constructor(protected _injector: Injector,
protected _translate: TranslateService,
@Optional() protected _overflowService: OverflowService) {
@Optional() protected _overflowService: OverflowService,
@Optional() protected _caseViewService: CaseViewService,
@Optional() @Inject(DATA_FIELD_PORTAL_DATA) protected _dataFieldPortalData: DataFieldPortalData<MultichoiceField | EnumerationField>) {
this.initializeFormControls(this._overflowService !== null);
this._changeValue = true;
}

@Input()
Expand Down Expand Up @@ -93,6 +105,7 @@ export abstract class AbstractHeaderComponent implements OnInit, OnDestroy {
this.headerService.responsiveHeaders = this._initResponsiveHeaders;
}
this.headerService.preferenceColumnCount$.subscribe(value => this.columnCountControl.setValue(value));
this.resolveApprovalDatafields();
}

ngOnDestroy(): void {
Expand All @@ -101,6 +114,9 @@ export abstract class AbstractHeaderComponent implements OnInit, OnDestroy {
this.subColumnCountControl.unsubscribe();
this.subOverflowControl.unsubscribe();
}
if (this._subCases) {
this._subCases.unsubscribe();
}
}

/**
Expand Down Expand Up @@ -199,4 +215,54 @@ export abstract class AbstractHeaderComponent implements OnInit, OnDestroy {
}
});
}

public indeterminate() {
if (this._caseViewService) {
return this._dataFieldPortalData?.dataField?.value?.length > 0 &&
this._caseViewService.cases.some(value => this._dataFieldPortalData?.dataField.value.includes(value.stringId)) &&
!this.resolveApprovalValue();
}
return this._dataFieldPortalData?.dataField?.value?.length > 0 &&
this._dataFieldPortalData?.dataField?.value?.length < this._dataFieldPortalData?.dataField?.choices?.length;
}

public typeApproval() {
return this._dataFieldPortalData?.dataField instanceof MultichoiceField ? 'multichoice' : 'enumeration';
}

protected resolveApprovalDatafields() {
if (this._dataFieldPortalData !== null && this._dataFieldPortalData.dataField instanceof MultichoiceField && this._caseViewService) {
this.approvalFormControl.setValue(this.resolveApprovalValue());
this.approvalFormControl.valueChanges.subscribe(value => {
if (this._changeValue) {
if (value) {
this._dataFieldPortalData.dataField.value = this._caseViewService.cases.map(caze => caze.stringId);
} else {
this._dataFieldPortalData.dataField.value = [];
}
}
this._changeValue = true;
})
this._dataFieldPortalData.dataField.valueChanges().subscribe(() => {
this._changeValue = false;
this.approvalFormControl.setValue(this.resolveApprovalValue());
})
this._subCases = this._caseViewService.cases$.subscribe(() => {
this._changeValue = false;
this.approvalFormControl.setValue(this.resolveApprovalValue());
})
}
if (this._dataFieldPortalData !== null && this._dataFieldPortalData.dataField instanceof EnumerationField) {
this.approvalFormControl.valueChanges.subscribe(value => {
this._dataFieldPortalData.dataField.value = null;
})
}
}

protected resolveApprovalValue() {
if (this._caseViewService.cases.length === 0) {
return false;
}
return this._caseViewService.cases.every(value => this._dataFieldPortalData?.dataField.value.includes(value.stringId));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export abstract class AbstractTaskListPaginationComponent extends AbstractDefaul
public length: number;
public pageSize = 20;
public pageIndex = 0;
public pageSizeOptions: Array<number> = [10, 20, 50];
public pageSizeOptions: Array<number> = [10, 20, 50, 100];

@Input() public disabled: boolean;
@Input()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export abstract class AbstractCaseListPaginatorComponent extends AbstractDefault
public length: number;
public pageSize = 20;
public pageIndex = 0;
public pageSizeOptions: number[] = [10, 20, 50];
public pageSizeOptions: number[] = [10, 20, 50, 100];
@Input() public approval: boolean;
@Input() public disabled: boolean;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ export class CaseViewService extends AbstractSortableViewComponent implements On

protected _loading$: LoadingWithFilterEmitter;
protected _cases$: Observable<Array<Case>>;
protected _cases: Array<Case>;
protected _nextPage$: BehaviorSubject<PageLoadRequestContext>;
protected _endOfData: boolean;
protected _pagination: Pagination;
Expand All @@ -67,6 +68,7 @@ export class CaseViewService extends AbstractSortableViewComponent implements On
@Optional() @Inject(NAE_NEW_CASE_CONFIGURATION) newCaseConfig: NewCaseConfiguration,
protected _permissionService: PermissionService) {
super(resolver);
this._cases = [];
this._newCaseConfiguration = {...this.DEFAULT_NEW_CASE_CONFIGURATION};
if (newCaseConfig !== null) {
Object.assign(this._newCaseConfiguration, newCaseConfig);
Expand Down Expand Up @@ -112,7 +114,8 @@ export class CaseViewService extends AbstractSortableViewComponent implements On
}, {})
);
this._cases$ = casesMap.pipe(
map(v => Object.values(v))
map(v => Object.values(v) as Array<Case>),
tap(cases => this._cases = cases as Array<Case>),
);
}

Expand All @@ -134,6 +137,10 @@ export class CaseViewService extends AbstractSortableViewComponent implements On
return this._cases$;
}

public get cases(): Array<Case> {
return this._cases;
}

public get pagination(): Pagination {
return this._pagination;
}
Expand Down
46 changes: 5 additions & 41 deletions projects/netgrif-components/src/lib/header/header.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
HeaderSearchService,
TaskHeaderService,
WorkflowHeaderService,
OverflowService, MultichoiceField, DATA_FIELD_PORTAL_DATA, DataFieldPortalData, EnumerationField
OverflowService, MultichoiceField, DATA_FIELD_PORTAL_DATA, DataFieldPortalData, EnumerationField, CaseViewService
} from '@netgrif/components-core';
import {TranslateService} from '@ngx-translate/core';

Expand All @@ -22,49 +22,13 @@ import {TranslateService} from '@ngx-translate/core';
CategoryFactory
]
})
export class HeaderComponent extends AbstractHeaderComponent implements OnInit {
protected _changeValue: boolean;
export class HeaderComponent extends AbstractHeaderComponent {

constructor(injector: Injector,
translate: TranslateService,
@Optional() overflowService: OverflowService,
@Optional() @Inject(DATA_FIELD_PORTAL_DATA) protected _dataFieldPortalData: DataFieldPortalData<MultichoiceField>) {
super(injector, translate, overflowService);
this._changeValue = true;
}

public indeterminate() {
return this._dataFieldPortalData?.dataField?.value?.length > 0 &&
this._dataFieldPortalData?.dataField?.value?.length < this._dataFieldPortalData?.dataField?.choices?.length;
}

public typeApproval() {
return this._dataFieldPortalData?.dataField instanceof MultichoiceField ? 'multichoice' : 'enumeration';
}

ngOnInit() {
super.ngOnInit();
if (this._dataFieldPortalData !== null && this._dataFieldPortalData.dataField instanceof MultichoiceField) {
this.approvalFormControl.setValue(this._dataFieldPortalData?.dataField.value.length === this._dataFieldPortalData?.dataField.choices.length);
this.approvalFormControl.valueChanges.subscribe(value => {
if (this._changeValue) {
if (value) {
this._dataFieldPortalData.dataField.value = this._dataFieldPortalData?.dataField.choices.map(val => val.key);
} else {
this._dataFieldPortalData.dataField.value = [];
}
}
this._changeValue = true;
})
this._dataFieldPortalData.dataField.valueChanges().subscribe(() => {
this._changeValue = false;
this.approvalFormControl.setValue(this._dataFieldPortalData?.dataField.value.length === this._dataFieldPortalData?.dataField.choices.length);
})
}
if (this._dataFieldPortalData !== null && this._dataFieldPortalData.dataField instanceof EnumerationField) {
this.approvalFormControl.valueChanges.subscribe(value => {
this._dataFieldPortalData.dataField.value = null;
})
}
@Optional() protected _caseViewService: CaseViewService,
@Optional() @Inject(DATA_FIELD_PORTAL_DATA) protected _dataFieldPortalData: DataFieldPortalData<MultichoiceField | EnumerationField>) {
super(injector, translate, overflowService, _caseViewService, _dataFieldPortalData);
}
}
Loading