refactor filter models

This commit is contained in:
Dan Percic 2021-08-05 16:50:01 +03:00
parent 1df154926a
commit 6654bd9e8a
16 changed files with 93 additions and 120 deletions

View File

@ -20,7 +20,7 @@ import { FileDataModel } from '@models/file/file-data.model';
import { CommentsComponent } from '../comments/comments.component';
import { PermissionsService } from '@services/permissions.service';
import { WebViewerInstance } from '@pdftron/webviewer';
import { CircleButtonTypes, FilterModel, IconButtonTypes } from '@iqser/common-ui';
import { CircleButtonTypes, NestedFilter, IconButtonTypes } from '@iqser/common-ui';
const COMMAND_KEY_ARRAY = ['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown', 'Escape'];
const ALL_HOTKEY_ARRAY = ['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown'];
@ -39,8 +39,8 @@ export class FileWorkloadComponent {
@Input() activeViewerPage: number;
@Input() shouldDeselectAnnotationsOnPageChange: boolean;
@Input() dialogRef: MatDialogRef<any>;
@Input() primaryFilters: FilterModel[];
@Input() secondaryFilters: FilterModel[];
@Input() primaryFilters: NestedFilter[];
@Input() secondaryFilters: NestedFilter[];
@Input() fileData: FileDataModel;
@Input() hideSkipped: boolean;
@Input() excludePages: boolean;
@ -143,7 +143,7 @@ export class FileWorkloadComponent {
}
@debounce(0)
filtersChanged(filters: { primary: FilterModel[]; secondary?: FilterModel[] }) {
filtersChanged(filters: { primary: NestedFilter[]; secondary?: NestedFilter[] }) {
this.displayedAnnotations = this._annotationProcessingService.filterAndGroupAnnotations(
this._annotations,
filters.primary,
@ -268,8 +268,8 @@ export class FileWorkloadComponent {
this.selectPage.emit(this._nextPageWithAnnotations());
}
_(filter): FilterModel {
return filter as FilterModel;
_(filter): NestedFilter {
return filter as NestedFilter;
}
private _selectFirstAnnotationOnCurrentPageIfNecessary() {

View File

@ -1,6 +1,6 @@
import { Component, Input, OnInit } from '@angular/core';
import { AppStateService } from '@state/app-state.service';
import { FilterModel } from '@iqser/common-ui';
import { NestedFilter } from '@iqser/common-ui';
@Component({
selector: 'redaction-type-filter',
@ -8,7 +8,7 @@ import { FilterModel } from '@iqser/common-ui';
styleUrls: ['./type-filter.component.scss']
})
export class TypeFilterComponent implements OnInit {
@Input() filter: FilterModel;
@Input() filter: NestedFilter;
dictionaryColor: string;

View File

@ -16,7 +16,7 @@ import { DossiersDialogService } from '../../services/dossiers-dialog.service';
import { OnAttach, OnDetach } from '@utils/custom-route-reuse.strategy';
import { UserPreferenceService } from '@services/user-preference.service';
import { ButtonConfig } from '@shared/components/page-header/models/button-config.model';
import { FilterModel, FilterService } from '@iqser/common-ui';
import { FilterService, NestedFilter } from '@iqser/common-ui';
import { SearchService } from '@shared/services/search.service';
import { ScreenStateService } from '@shared/services/screen-state.service';
import { BaseListingComponent } from '@shared/base/base-listing.component';
@ -204,7 +204,7 @@ export class DossierListingScreenComponent
allDistinctDossierTemplates.add(entry.dossierTemplateId);
});
const statusFilters = [...allDistinctFileStatus].map<FilterModel>(status => ({
const statusFilters = [...allDistinctFileStatus].map<NestedFilter>(status => ({
key: status,
label: this._translateService.instant(fileStatusTranslations[status])
}));
@ -217,7 +217,7 @@ export class DossierListingScreenComponent
checker: dossierStatusChecker
});
const peopleFilters = [...allDistinctPeople].map<FilterModel>(userId => ({
const peopleFilters = [...allDistinctPeople].map<NestedFilter>(userId => ({
key: userId,
label: this._userService.getNameForId(userId)
}));
@ -230,7 +230,7 @@ export class DossierListingScreenComponent
checker: dossierMemberChecker
});
const needsWorkFilters = [...allDistinctNeedsWork].map<FilterModel>(type => ({
const needsWorkFilters = [...allDistinctNeedsWork].map<NestedFilter>(type => ({
key: type,
label: workloadTranslations[type]
}));
@ -246,7 +246,7 @@ export class DossierListingScreenComponent
checkerArgs: this.permissionsService
});
const dossierTemplateFilters = [...allDistinctDossierTemplates].map<FilterModel>(id => ({
const dossierTemplateFilters = [...allDistinctDossierTemplates].map<NestedFilter>(id => ({
key: id,
label: this._appStateService.getDossierTemplateById(id).name
}));
@ -270,7 +270,7 @@ export class DossierListingScreenComponent
private _createQuickFilters() {
const myDossiersLabel = this._translateService.instant('dossier-listing.quick-filters.my-dossiers');
const filters: FilterModel[] = [
const filters: NestedFilter[] = [
{
key: 'my-dossiers',
label: myDossiersLabel,

View File

@ -21,7 +21,7 @@ import { DossierWrapper } from '@state/model/dossier.wrapper';
import { OnAttach, OnDetach } from '@utils/custom-route-reuse.strategy';
import { AppConfigKey, AppConfigService } from '@app-config/app-config.service';
import { ActionConfig } from '@shared/components/page-header/models/action-config.model';
import { FilterModel, FilterService, keyChecker } from '@iqser/common-ui';
import { NestedFilter, FilterService, keyChecker } from '@iqser/common-ui';
import { SearchService } from '@shared/services/search.service';
import { ScreenStateService } from '@shared/services/screen-state.service';
import { SortingService } from '@services/sorting.service';
@ -305,7 +305,7 @@ export class DossierOverviewScreenComponent
if (file.hasNone) allDistinctNeedsWork.add('none');
});
const statusFilters = [...allDistinctFileStatusWrapper].map<FilterModel>(item => ({
const statusFilters = [...allDistinctFileStatusWrapper].map<NestedFilter>(item => ({
key: item,
label: this._translateService.instant(fileStatusTranslations[item])
}));
@ -341,7 +341,7 @@ export class DossierOverviewScreenComponent
checker: keyChecker('currentReviewer')
});
const needsWorkFilters = [...allDistinctNeedsWork].map<FilterModel>(item => ({
const needsWorkFilters = [...allDistinctNeedsWork].map<NestedFilter>(item => ({
key: item,
label: workloadTranslations[item]
}));

View File

@ -36,7 +36,7 @@ import { stampPDFPage } from '@utils/page-stamper';
import { TranslateService } from '@ngx-translate/core';
import { AutoUnsubscribeComponent, CircleButtonTypes } from '@iqser/common-ui';
import { fileStatusTranslations } from '../../translations/file-status-translations';
import { FilterModel } from '@iqser/common-ui';
import { NestedFilter } from '@iqser/common-ui';
import { processFilters } from '@iqser/common-ui';
import { handleFilterDelta } from '@shared/components/filters/popup-filter/utils/filter-utils';
@ -59,8 +59,8 @@ export class FilePreviewScreenComponent extends AutoUnsubscribeComponent impleme
fileData: FileDataModel;
annotationData: AnnotationData;
selectedAnnotations: AnnotationWrapper[];
primaryFilters: FilterModel[];
secondaryFilters: FilterModel[];
primaryFilters: NestedFilter[];
secondaryFilters: NestedFilter[];
canPerformAnnotationActions: boolean;
hideSkipped = false;
displayPDFViewer = false;

View File

@ -1,5 +1,5 @@
import { Component, Injector, OnDestroy } from '@angular/core';
import { BaseListingComponent } from '../../../shared/base/base-listing.component';
import { BaseListingComponent } from '@shared/base/base-listing.component';
import { MatchedDocument, SearchControllerService, SearchResult } from '@redaction/red-ui-http';
import { BehaviorSubject, Observable } from 'rxjs';
import { debounceTime, map, skip, switchMap, tap } from 'rxjs/operators';
@ -104,8 +104,8 @@ export class SearchScreenComponent extends BaseListingComponent<ListItem> implem
.valueChanges.pipe(debounceTime(300))
.subscribe(value => this.updateNavigation(value));
this.addSubscription = this.filterService.filterGroups$.pipe(skip(1)).subscribe(filters => {
const dossierIds = filters[0].values.filter(v => v.checked).map(v => v.key);
this.addSubscription = this.filterService.filterGroups$.pipe(skip(1)).subscribe(group => {
const dossierIds = group[0].filters.filter(v => v.checked).map(v => v.key);
this.search$.next({ query: this.searchService.searchValue, dossierIds: dossierIds });
});
}

View File

@ -4,11 +4,11 @@ import { SuperTypeSorter } from '@utils/sorters/super-type-sorter';
import { handleCheckedValue } from '@iqser/common-ui';
import { annotationTypesTranslations } from '../../../translations/annotation-types-translations';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { FilterModel } from '@iqser/common-ui';
import { NestedFilter } from '@iqser/common-ui';
@Injectable()
export class AnnotationProcessingService {
static get secondaryAnnotationFilters(): FilterModel[] {
static get secondaryAnnotationFilters(): NestedFilter[] {
return [
{
key: 'with-comments',
@ -16,7 +16,7 @@ export class AnnotationProcessingService {
label: _('filter-menu.with-comments'),
checked: false,
topLevelFilter: true,
filters: [],
children: [],
checker: (annotation: AnnotationWrapper) => annotation?.comments?.length > 0
},
{
@ -25,15 +25,15 @@ export class AnnotationProcessingService {
label: _('filter-menu.with-reason-changes'),
checked: false,
topLevelFilter: true,
filters: [],
children: [],
checker: (annotation: AnnotationWrapper) => annotation?.legalBasisChangeValue?.length > 0
}
];
}
getAnnotationFilter(annotations: AnnotationWrapper[]): FilterModel[] {
const filterMap = new Map<string, FilterModel>();
const filters: FilterModel[] = [];
getAnnotationFilter(annotations: AnnotationWrapper[]): NestedFilter[] {
const filterMap = new Map<string, NestedFilter>();
const filters: NestedFilter[] = [];
annotations?.forEach(a => {
const topLevelFilter = a.superType !== 'hint' && a.superType !== 'redaction' && a.superType !== 'recommendation';
@ -52,24 +52,25 @@ export class AnnotationProcessingService {
}
const childFilter = {
key: a.dictionary,
label: a.dictionary,
checked: false,
filters: [],
matches: 1
};
filterMap.set(key, childFilter);
parentFilter.filters.push(childFilter);
parentFilter.children.push(childFilter);
}
}
});
for (const filter of filters) {
filter.filters.sort((a, b) => a.key.localeCompare(b.key));
filter.children.sort((a, b) => a.key.localeCompare(b.key));
handleCheckedValue(filter);
if (filter.checked || filter.indeterminate) {
filter.expanded = true;
}
if (filter.filters.length > 0) {
filter.matches = filter.filters.reduce((a, b) => a + b.matches, 0);
if (filter.children.length > 0) {
filter.matches = filter.children.reduce((a, b) => a + b.matches, 0);
}
}
@ -78,8 +79,8 @@ export class AnnotationProcessingService {
filterAndGroupAnnotations(
annotations: AnnotationWrapper[],
primaryFilters: FilterModel[],
secondaryFilters?: FilterModel[]
primaryFilters: NestedFilter[],
secondaryFilters?: NestedFilter[]
): { [key: number]: { annotations: AnnotationWrapper[] } } {
const obj = {};
@ -123,31 +124,31 @@ export class AnnotationProcessingService {
return obj;
}
private _createParentFilter(key: string, filterMap: Map<string, FilterModel>, filters: FilterModel[]) {
const filter: FilterModel = {
private _createParentFilter(key: string, filterMap: Map<string, NestedFilter>, filters: NestedFilter[]) {
const filter: NestedFilter = {
key: key,
topLevelFilter: true,
matches: 1,
label: annotationTypesTranslations[key],
filters: []
children: []
};
filterMap.set(key, filter);
filters.push(filter);
return filter;
}
private _getFlatFilters(filters: FilterModel[], filterBy?: (f: FilterModel) => boolean) {
const flatFilters: FilterModel[] = [];
private _getFlatFilters(filters: NestedFilter[], filterBy?: (f: NestedFilter) => boolean) {
const flatFilters: NestedFilter[] = [];
filters.forEach(filter => {
flatFilters.push(filter);
flatFilters.push(...filter.filters);
flatFilters.push(...filter.children);
});
return filterBy ? flatFilters.filter(f => filterBy(f)) : flatFilters;
}
private _matchesOne = (filters: FilterModel[], condition: (filter: FilterModel) => boolean): boolean => {
private _matchesOne = (filters: NestedFilter[], condition: (filter: NestedFilter) => boolean): boolean => {
if (filters.length === 0) return true;
for (const filter of filters) {
@ -157,7 +158,7 @@ export class AnnotationProcessingService {
return false;
};
private _matchesAll = (filters: FilterModel[], condition: (filter: FilterModel) => boolean): boolean => {
private _matchesAll = (filters: NestedFilter[], condition: (filter: NestedFilter) => boolean): boolean => {
if (filters.length === 0) return true;
for (const filter of filters) {
@ -167,7 +168,7 @@ export class AnnotationProcessingService {
return true;
};
private _checkByFilterKey = (filter: FilterModel, annotation: AnnotationWrapper) => {
private _checkByFilterKey = (filter: NestedFilter, annotation: AnnotationWrapper) => {
const superType = annotation.superType;
const isNotTopLevelFilter = superType === 'hint' || superType === 'redaction' || superType === 'recommendation';

View File

@ -86,8 +86,8 @@
<ng-container [ngTemplateOutletContext]="{ filter: filter }" [ngTemplateOutlet]="actionsTemplate ?? null"></ng-container>
</div>
<div *ngIf="_(filter).filters?.length && _(filter).expanded">
<div (click)="$event.stopPropagation()" *ngFor="let subFilter of _(filter).filters" class="padding-left mat-menu-item">
<div *ngIf="_(filter).children?.length && _(filter).expanded">
<div (click)="$event.stopPropagation()" *ngFor="let subFilter of _(filter).children" class="padding-left mat-menu-item">
<mat-checkbox (click)="filterCheckboxClicked($event, subFilter, filter)" [checked]="subFilter.checked">
<ng-container
[ngTemplateOutletContext]="{ filter: subFilter }"

View File

@ -1,5 +1,5 @@
import { ChangeDetectorRef, Component, EventEmitter, Input, OnChanges, Output, TemplateRef } from '@angular/core';
import { FilterModel } from '@iqser/common-ui';
import { NestedFilter } from '@iqser/common-ui';
import { handleCheckedValue } from '@iqser/common-ui';
import { MAT_CHECKBOX_DEFAULT_OPTIONS } from '@angular/material/checkbox';
@ -19,13 +19,13 @@ import { MAT_CHECKBOX_DEFAULT_OPTIONS } from '@angular/material/checkbox';
})
export class PopupFilterComponent implements OnChanges {
@Output() filtersChanged = new EventEmitter<{
primary: FilterModel[];
secondary?: FilterModel[];
primary: NestedFilter[];
secondary?: NestedFilter[];
}>();
@Input() filterTemplate: TemplateRef<any>;
@Input() actionsTemplate: TemplateRef<any>;
@Input() primaryFilters: FilterModel[] = [];
@Input() secondaryFilters: FilterModel[] = [];
@Input() primaryFilters: NestedFilter[] = [];
@Input() secondaryFilters: NestedFilter[] = [];
@Input() filterLabel;
@Input() icon: string;
@ -38,7 +38,7 @@ export class PopupFilterComponent implements OnChanges {
return !!this._allFilters.find(f => f.checked || f.indeterminate);
}
private get _allFilters(): FilterModel[] {
private get _allFilters(): NestedFilter[] {
return [...(this.primaryFilters ?? []), ...(this.secondaryFilters ?? [])];
}
@ -47,7 +47,7 @@ export class PopupFilterComponent implements OnChanges {
this.atLeastOneSecondaryFilterIsExpandable = !!this.secondaryFilters?.find(f => this.isExpandable(f));
}
filterCheckboxClicked($event: any, filter: FilterModel, parent?: FilterModel) {
filterCheckboxClicked($event: any, filter: NestedFilter, parent?: NestedFilter) {
$event.stopPropagation();
filter.checked = !filter.checked;
@ -57,7 +57,7 @@ export class PopupFilterComponent implements OnChanges {
} else {
if (filter.indeterminate) filter.checked = false;
filter.indeterminate = false;
filter.filters?.forEach(f => (f.checked = filter.checked));
filter.children?.forEach(f => (f.checked = filter.checked));
}
this.applyFilters();
@ -79,17 +79,17 @@ export class PopupFilterComponent implements OnChanges {
this._changeDetectorRef.detectChanges();
}
toggleFilterExpanded($event: MouseEvent, filter: FilterModel) {
toggleFilterExpanded($event: MouseEvent, filter: NestedFilter) {
$event.stopPropagation();
filter.expanded = !filter.expanded;
}
isExpandable(filter: FilterModel) {
return filter?.filters?.length > 0;
isExpandable(filter: NestedFilter) {
return filter?.children?.length > 0;
}
_(obj): FilterModel {
return obj as FilterModel;
_(obj): NestedFilter {
return obj as NestedFilter;
}
private _setFilters(onlyPrimaryFilters = false) {
@ -97,7 +97,7 @@ export class PopupFilterComponent implements OnChanges {
filters.forEach(f => {
f.checked = onlyPrimaryFilters;
f.indeterminate = false;
f.filters?.forEach(ff => (ff.checked = onlyPrimaryFilters));
f.children?.forEach(ff => (ff.checked = onlyPrimaryFilters));
});
this.applyFilters();
}

View File

@ -2,20 +2,20 @@ import { FileStatusWrapper } from '@models/file/file-status.wrapper';
import { DossierWrapper } from '@state/model/dossier.wrapper';
import { PermissionsService } from '@services/permissions.service';
import { handleCheckedValue } from '@iqser/common-ui';
import { FilterModel } from '@iqser/common-ui';
import { NestedFilter } from '@iqser/common-ui';
export function handleFilterDelta(oldFilters: FilterModel[], newFilters: FilterModel[], allFilters: FilterModel[]) {
export function handleFilterDelta(oldFilters: NestedFilter[], newFilters: NestedFilter[], allFilters: NestedFilter[]) {
const newFiltersDelta = {};
for (const newFilter of newFilters) {
const oldFilter = oldFilters.find(f => f.key === newFilter.key);
if (!oldFilter || oldFilter.matches !== newFilter.matches) {
newFiltersDelta[newFilter.key] = {};
newFilter.filters.forEach(filter => (newFiltersDelta[newFilter.key][filter.key] = {}));
newFilter.children.forEach(filter => (newFiltersDelta[newFilter.key][filter.key] = {}));
}
if (!oldFilter) {
for (const childFilter of newFilter.filters) {
const oldFilterChild = oldFilter?.filters.find(f => f.key === childFilter.key);
for (const childFilter of newFilter.children) {
const oldFilterChild = oldFilter?.children.find(f => f.key === childFilter.key);
if (!oldFilterChild || oldFilterChild.matches !== childFilter.matches) {
if (!newFiltersDelta[newFilter.key]) {
newFiltersDelta[newFilter.key] = {};
@ -30,11 +30,11 @@ export function handleFilterDelta(oldFilters: FilterModel[], newFilters: FilterM
const foundFilter = allFilters.find(f => f.key === key);
if (foundFilter) {
// if has children
if (!foundFilter.filters?.length) {
if (!foundFilter.children?.length) {
foundFilter.checked = true;
} else {
for (const subKey of Object.keys(newFiltersDelta[key])) {
const childFilter = foundFilter.filters.find(f => f.key === subKey);
const childFilter = foundFilter.children.find(f => f.key === subKey);
if (childFilter) {
childFilter.checked = true;
}
@ -49,7 +49,7 @@ export function handleFilterDelta(oldFilters: FilterModel[], newFilters: FilterM
export const annotationFilterChecker = (
input: FileStatusWrapper | DossierWrapper,
filter: FilterModel,
filter: NestedFilter,
permissionsService: PermissionsService
) => {
switch (filter.key) {
@ -81,10 +81,13 @@ export const annotationFilterChecker = (
}
};
export const dossierStatusChecker = (dw: DossierWrapper, filter: FilterModel) => dw.hasStatus(filter.key);
export const dossierStatusChecker = (dw: DossierWrapper, filter: NestedFilter) => {
console.log(dw, filter);
return dw.hasStatus(filter.key);
};
export const dossierMemberChecker = (dw: DossierWrapper, filter: FilterModel) => dw.hasMember(filter.key);
export const dossierMemberChecker = (dw: DossierWrapper, filter: NestedFilter) => dw.hasMember(filter.key);
export const dossierTemplateChecker = (dw: DossierWrapper, filter: FilterModel) => dw.dossierTemplateId === filter.key;
export const dossierTemplateChecker = (dw: DossierWrapper, filter: NestedFilter) => dw.dossierTemplateId === filter.key;
export const dossierApproverChecker = (dw: DossierWrapper, filter: FilterModel) => dw.approverIds.includes(filter.key);
export const dossierApproverChecker = (dw: DossierWrapper, filter: NestedFilter) => dw.approverIds.includes(filter.key);

View File

@ -1,5 +1,5 @@
import { BaseHeaderConfig } from './base-config.model';
export interface ActionConfig extends BaseHeaderConfig {
readonly action: ($event) => void;
readonly action: ($event: MouseEvent) => void;
}

View File

@ -1,7 +1,6 @@
import { IconButtonType } from '@iqser/common-ui';
import { BaseHeaderConfig } from './base-config.model';
import { ActionConfig } from '@shared/components/page-header/models/action-config.model';
export interface ButtonConfig extends BaseHeaderConfig {
readonly action: ($event) => void;
export interface ButtonConfig extends ActionConfig {
readonly type?: IconButtonType;
}

View File

@ -1,9 +0,0 @@
import { FilterModel } from '@iqser/common-ui';
import { TemplateRef } from '@angular/core';
import { BaseHeaderConfig } from './base-config.model';
export interface FilterConfig extends BaseHeaderConfig {
readonly primaryFilters?: FilterModel[];
readonly primaryFiltersLabel?: string;
readonly filterTemplate?: TemplateRef<any>;
}

View File

@ -31,12 +31,8 @@ export class PageHeaderComponent {
get _showResetFilters$(): Observable<boolean> {
if (!this.filterService) return of(false);
const filtersLength$ = this.filters$.pipe(
map(f => f.length),
distinctUntilChanged()
);
return combineLatest([filtersLength$, this.filterService.showResetFilters$, this.searchService.valueChanges$]).pipe(
map(([hasFilters, showResetFilters, searchValue]) => hasFilters && (showResetFilters || !!searchValue)),
return combineLatest([this.filterService.showResetFilters$, this.searchService.valueChanges$]).pipe(
map(([showResetFilters, searchValue]) => showResetFilters || !!searchValue),
distinctUntilChanged()
);
}

View File

@ -1,25 +1,26 @@
import { Injectable } from '@angular/core';
import { BehaviorSubject, combineLatest, Observable } from 'rxjs';
import { BehaviorSubject, combineLatest, Observable, pipe } from 'rxjs';
import { distinctUntilChanged, map, tap } from 'rxjs/operators';
import { FilterService } from '@iqser/common-ui';
import { SearchService } from '@shared/services/search.service';
import { getFilteredEntities } from '@iqser/common-ui';
const toLengthValue = entities => entities?.length ?? 0;
const toLengthValue = (entities: unknown[]) => entities?.length ?? 0;
const getLength = pipe(map(toLengthValue), distinctUntilChanged());
@Injectable()
export class ScreenStateService<T> {
private readonly _allEntities$ = new BehaviorSubject<T[]>([]);
readonly allEntities$ = this._allEntities$.asObservable();
readonly allEntitiesLength$ = this._allEntitiesLength$;
readonly allEntitiesLength$ = this._allEntities$.pipe(getLength);
private readonly _displayedEntities$ = new BehaviorSubject<T[]>([]);
readonly displayedEntities$ = this._getDisplayedEntities$;
readonly displayedLength$ = this._displayedLength$;
readonly displayedLength$ = this._displayedEntities$.pipe(getLength);
private readonly _selectedEntities$ = new BehaviorSubject<T[]>([]);
readonly selectedEntities$ = this._selectedEntities$.asObservable();
readonly selectedLength$ = this._selectedLength$;
readonly selectedLength$ = this._selectedEntities$.pipe(getLength);
readonly noData$ = this._noData$;
readonly areAllEntitiesSelected$ = this._areAllEntitiesSelected$;
@ -57,18 +58,6 @@ export class ScreenStateService<T> {
);
}
private get _allEntitiesLength$(): Observable<number> {
return this.allEntities$.pipe(map(toLengthValue), distinctUntilChanged());
}
private get _displayedLength$(): Observable<number> {
return this.displayedEntities$.pipe(map(toLengthValue), distinctUntilChanged());
}
private get _selectedLength$(): Observable<number> {
return this.selectedEntities$.pipe(map(toLengthValue), distinctUntilChanged());
}
private get _areAllEntitiesSelected$(): Observable<boolean> {
return combineLatest([this.displayedLength$, this.selectedLength$]).pipe(
map(([displayedLength, selectedLength]) => displayedLength && displayedLength === selectedLength),
@ -76,9 +65,6 @@ export class ScreenStateService<T> {
);
}
/**
* Indicates that some entities are selected. If all are selected this returns true
*/
private get _areSomeEntitiesSelected$(): Observable<boolean> {
return this.selectedLength$.pipe(
map(value => !!value),
@ -86,9 +72,6 @@ export class ScreenStateService<T> {
);
}
/**
* Indicates that some entities are selected, but not all
*/
private get _notAllEntitiesSelected$(): Observable<boolean> {
return combineLatest([this.areAllEntitiesSelected$, this.areSomeEntitiesSelected$]).pipe(
map(([allEntitiesAreSelected, someEntitiesAreSelected]) => !allEntitiesAreSelected && someEntitiesAreSelected),
@ -107,11 +90,11 @@ export class ScreenStateService<T> {
return this.displayedEntities.length !== 0 && this.displayedEntities.length === this.selectedEntities.length;
}
setEntities(newEntities: Partial<T[]>): void {
setEntities(newEntities: T[]): void {
this._allEntities$.next(newEntities);
}
setSelectedEntities(newEntities: Partial<T[]>): void {
setSelectedEntities(newEntities: T[]): void {
this._selectedEntities$.next(newEntities);
}
@ -120,7 +103,7 @@ export class ScreenStateService<T> {
}
selectEntities(entities?: T[]): void {
if (entities !== undefined && entities !== null && entities.length > 0) {
if (entities?.length > 0) {
return entities.forEach(entity => this._selectOne(entity));
}
return this._selectAll();

View File

@ -94,8 +94,8 @@ export class DossierWrapper {
return this.dossier.watermarkEnabled;
}
hasStatus(status: string) {
return this._files.find(f => f.status === status);
hasStatus(status: string): boolean {
return !!this._files.find(f => f.status === status);
}
hasMember(key: string) {