move filter service and some filter-utils

This commit is contained in:
Dan Percic 2021-08-04 00:50:49 +03:00
parent 2dd2825c59
commit 1df154926a
36 changed files with 90 additions and 292 deletions

View File

@ -3,7 +3,7 @@ import { FileDownloadService } from '@upload-download/services/file-download.ser
import { DownloadStatusWrapper } from '@upload-download/model/download-status.wrapper';
import { DownloadControllerService } from '@redaction/red-ui-http';
import { BaseListingComponent } from '@shared/base/base-listing.component';
import { FilterService } from '@shared/services/filter.service';
import { FilterService } 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';

View File

@ -1,7 +1,7 @@
import { Component, EventEmitter, Injector, Input, OnChanges, Output, SimpleChanges } from '@angular/core';
import { Field } from '../file-attributes-csv-import-dialog.component';
import { FileAttributeConfig } from '@redaction/red-ui-http';
import { FilterService } from '@shared/services/filter.service';
import { FilterService } 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';

View File

@ -8,7 +8,7 @@ import { Observable } from 'rxjs';
import { map, startWith } from 'rxjs/operators';
import { Toaster } from '@services/toaster.service';
import { TranslateService } from '@ngx-translate/core';
import { FilterService } from '@shared/services/filter.service';
import { FilterService } 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';

View File

@ -5,7 +5,7 @@ import { ActivatedRoute } from '@angular/router';
import { PermissionsService } from '@services/permissions.service';
import { AdminDialogService } from '../../services/admin-dialog.service';
import { LoadingService } from '@services/loading.service';
import { FilterService } from '@shared/services/filter.service';
import { FilterService } 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';

View File

@ -9,7 +9,7 @@ import { ActivatedRoute } from '@angular/router';
import { TypeValueWrapper } from '@models/file/type-value.wrapper';
import { TranslateService } from '@ngx-translate/core';
import { LoadingService } from '@services/loading.service';
import { FilterService } from '@shared/services/filter.service';
import { FilterService } 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';

View File

@ -6,7 +6,7 @@ import { ActivatedRoute } from '@angular/router';
import { AdminDialogService } from '../../services/admin-dialog.service';
import { LoadingService } from '@services/loading.service';
import { SortingService } from '@services/sorting.service';
import { FilterService } from '@shared/services/filter.service';
import { FilterService } from '@iqser/common-ui';
import { SearchService } from '@shared/services/search.service';
import { ScreenStateService } from '@shared/services/screen-state.service';
import { PermissionsService } from '@services/permissions.service';

View File

@ -6,7 +6,7 @@ import { AdminDialogService } from '../../services/admin-dialog.service';
import { DossierTemplateModelWrapper } from '@models/file/dossier-template-model.wrapper';
import { LoadingService } from '@services/loading.service';
import { DossierTemplateControllerService } from '@redaction/red-ui-http';
import { FilterService } from '@shared/services/filter.service';
import { FilterService } 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';

View File

@ -5,7 +5,7 @@ import { AppStateService } from '@state/app-state.service';
import { ActivatedRoute } from '@angular/router';
import { AdminDialogService } from '../../services/admin-dialog.service';
import { LoadingService } from '@services/loading.service';
import { FilterService } from '@shared/services/filter.service';
import { FilterService } 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';

View File

@ -4,7 +4,7 @@ import { Dossier } from '@redaction/red-ui-http';
import { LoadingService } from '@services/loading.service';
import { AppConfigKey, AppConfigService } from '@app-config/app-config.service';
import * as moment from 'moment';
import { FilterService } from '@shared/services/filter.service';
import { FilterService } 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';

View File

@ -8,7 +8,7 @@ import { DoughnutChartConfig } from '@shared/components/simple-doughnut-chart/si
import { TranslateChartService } from '@services/translate-chart.service';
import { LoadingService } from '@services/loading.service';
import { InitialsAvatarComponent } from '@shared/components/initials-avatar/initials-avatar.component';
import { FilterService } from '@shared/services/filter.service';
import { FilterService } 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';

View File

@ -8,7 +8,7 @@ import { StatusSorter } from '@utils/sorters/status-sorter';
import { UserService } from '@services/user.service';
import { User } from '@redaction/red-ui-http';
import { Toaster } from '@services/toaster.service';
import { FilterService } from '@shared/services/filter.service';
import { FilterService } from '@iqser/common-ui';
import { DossierAttributeWithValue } from '@models/dossier-attributes.model';
import { fileStatusTranslations } from '../../translations/file-status-translations';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';

View File

@ -1,7 +1,7 @@
import { ChangeDetectionStrategy, Component, Input } from '@angular/core';
import { DoughnutChartConfig } from '@shared/components/simple-doughnut-chart/simple-doughnut-chart.component';
import { AppStateService } from '@state/app-state.service';
import { FilterService } from '@shared/services/filter.service';
import { FilterService } from '@iqser/common-ui';
@Component({
selector: 'redaction-dossier-listing-details',

View File

@ -17,11 +17,10 @@ import { MatDialogRef, MatDialogState } from '@angular/material/dialog';
import scrollIntoView from 'scroll-into-view-if-needed';
import { debounce } from '@utils/debounce';
import { FileDataModel } from '@models/file/file-data.model';
import { FilterModel } from '@shared/components/filters/popup-filter/model/filter.model';
import { CommentsComponent } from '../comments/comments.component';
import { PermissionsService } from '@services/permissions.service';
import { WebViewerInstance } from '@pdftron/webviewer';
import { CircleButtonTypes, IconButtonTypes } from '@iqser/common-ui';
import { CircleButtonTypes, FilterModel, IconButtonTypes } from '@iqser/common-ui';
const COMMAND_KEY_ARRAY = ['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown', 'Escape'];
const ALL_HOTKEY_ARRAY = ['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown'];

View File

@ -1,6 +1,6 @@
import { Component, Input, OnInit } from '@angular/core';
import { AppStateService } from '@state/app-state.service';
import { FilterModel } from '@shared/components/filters/popup-filter/model/filter.model';
import { FilterModel } from '@iqser/common-ui';
@Component({
selector: 'redaction-type-filter',

View File

@ -14,16 +14,9 @@ import { StatusSorter } from '@utils/sorters/status-sorter';
import { NavigationStart, Router } from '@angular/router';
import { DossiersDialogService } from '../../services/dossiers-dialog.service';
import { OnAttach, OnDetach } from '@utils/custom-route-reuse.strategy';
import { FilterModel } from '@shared/components/filters/popup-filter/model/filter.model';
import {
annotationFilterChecker,
dossierMemberChecker,
dossierStatusChecker,
dossierTemplateChecker
} from '@shared/components/filters/popup-filter/utils/filter-utils';
import { UserPreferenceService } from '@services/user-preference.service';
import { ButtonConfig } from '@shared/components/page-header/models/button-config.model';
import { FilterService } from '@shared/services/filter.service';
import { FilterModel, FilterService } 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';
@ -32,6 +25,12 @@ import { TableColConfig } from '@shared/components/table-col-name/table-col-name
import { workloadTranslations } from '../../translations/workload-translations';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { fileStatusTranslations } from '../../translations/file-status-translations';
import {
annotationFilterChecker,
dossierMemberChecker,
dossierStatusChecker,
dossierTemplateChecker
} from '@shared/components/filters/popup-filter/utils/filter-utils';
const isLeavingScreen = event => event instanceof NavigationStart && event.url !== '/main/dossiers';
@ -214,7 +213,7 @@ export class DossierListingScreenComponent
slug: 'statusFilters',
label: this._translateService.instant('filters.status'),
icon: 'red:status',
values: statusFilters.sort(StatusSorter.byStatus),
filters: statusFilters.sort(StatusSorter.byStatus),
checker: dossierStatusChecker
});
@ -227,7 +226,7 @@ export class DossierListingScreenComponent
slug: 'peopleFilters',
label: this._translateService.instant('filters.people'),
icon: 'red:user',
values: peopleFilters,
filters: peopleFilters,
checker: dossierMemberChecker
});
@ -241,7 +240,7 @@ export class DossierListingScreenComponent
label: this._translateService.instant('filters.needs-work'),
icon: 'red:needs-work',
filterTemplate: this._needsWorkTemplate,
values: needsWorkFilters.sort(RedactionFilterSorter.byKey),
filters: needsWorkFilters.sort(RedactionFilterSorter.byKey),
checker: annotationFilterChecker,
matchAll: true,
checkerArgs: this.permissionsService
@ -256,15 +255,15 @@ export class DossierListingScreenComponent
slug: 'dossierTemplateFilters',
label: this._translateService.instant('filters.dossier-templates'),
icon: 'red:template',
hide: this.filterService.getFilterGroup('dossierTemplateFilters')?.values?.length <= 1,
values: dossierTemplateFilters,
hide: this.filterService.getFilterGroup('dossierTemplateFilters')?.filters?.length <= 1,
filters: dossierTemplateFilters,
checker: dossierTemplateChecker
});
const quickFilters = this._createQuickFilters();
this.filterService.addFilterGroup({
slug: 'quickFilters',
values: quickFilters,
filters: quickFilters,
checker: (dw: DossierWrapper) => quickFilters.reduce((acc, f) => acc || (f.checked && f.checker(dw)), false)
});
}

View File

@ -19,11 +19,9 @@ import { convertFiles, handleFileDrop } from '@utils/file-drop-utils';
import { DossiersDialogService } from '../../services/dossiers-dialog.service';
import { DossierWrapper } from '@state/model/dossier.wrapper';
import { OnAttach, OnDetach } from '@utils/custom-route-reuse.strategy';
import { annotationFilterChecker, keyChecker } from '@shared/components/filters/popup-filter/utils/filter-utils';
import { FilterModel } from '@shared/components/filters/popup-filter/model/filter.model';
import { AppConfigKey, AppConfigService } from '@app-config/app-config.service';
import { ActionConfig } from '@shared/components/page-header/models/action-config.model';
import { FilterService } from '@shared/services/filter.service';
import { FilterModel, 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';
@ -37,6 +35,7 @@ import { fileStatusTranslations } from '../../translations/file-status-translati
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { CircleButtonTypes } from '@iqser/common-ui';
import { TableColConfig } from '@shared/components/table-col-name/table-col-name.component';
import { annotationFilterChecker } from '@shared/components/filters/popup-filter/utils/filter-utils';
@Component({
templateUrl: './dossier-overview-screen.component.html',
@ -54,7 +53,14 @@ export class DossierOverviewScreenComponent
readonly itemSize = 80;
collapsedDetails = false;
actionConfigs: ActionConfig[];
readonly actionConfigs: ActionConfig[] = [
{
label: this._translateService.instant('dossier-overview.header-actions.edit'),
action: $event => this.openEditDossierDialog($event),
icon: 'red:edit',
hide: !this.permissionsService.isManager()
}
];
dossierAttributes: DossierAttributeWithValue[] = [];
tableColConfigs: TableColConfig[] = [
{
@ -125,11 +131,11 @@ export class DossierOverviewScreenComponent
}
get checkedRequiredFilters() {
return this.filterService.getFilterGroup('quickFilters')?.values.filter(f => f.required && f.checked);
return this.filterService.getFilterGroup('quickFilters')?.filters.filter(f => f.required && f.checked);
}
get checkedNotRequiredFilters() {
return this.filterService.getFilterGroup('quickFilters')?.values.filter(f => !f.required && f.checked);
return this.filterService.getFilterGroup('quickFilters')?.filters.filter(f => !f.required && f.checked);
}
isLastOpenedFile({ fileId }: FileStatusWrapper): boolean {
@ -308,7 +314,7 @@ export class DossierOverviewScreenComponent
slug: 'statusFilters',
label: this._translateService.instant('filters.status'),
icon: 'red:status',
values: statusFilters.sort(StatusSorter.byStatus),
filters: statusFilters.sort(StatusSorter.byStatus),
checker: keyChecker('status')
});
@ -331,7 +337,7 @@ export class DossierOverviewScreenComponent
slug: 'peopleFilters',
label: this._translateService.instant('filters.assigned-people'),
icon: 'red:user',
values: peopleFilters,
filters: peopleFilters,
checker: keyChecker('currentReviewer')
});
@ -345,7 +351,7 @@ export class DossierOverviewScreenComponent
label: this._translateService.instant('filters.needs-work'),
icon: 'red:needs-work',
filterTemplate: this._needsWorkTemplate,
values: needsWorkFilters.sort(RedactionFilterSorter.byKey),
filters: needsWorkFilters.sort(RedactionFilterSorter.byKey),
checker: annotationFilterChecker,
matchAll: true,
checkerArgs: this.permissionsService
@ -353,14 +359,12 @@ export class DossierOverviewScreenComponent
this.filterService.addFilterGroup({
slug: 'quickFilters',
values: this._createQuickFilters(),
filters: this._createQuickFilters(),
checker: (file: FileStatusWrapper) =>
this.checkedRequiredFilters.reduce((acc, f) => acc && f.checker(file), true) &&
(this.checkedNotRequiredFilters.length === 0 ||
this.checkedNotRequiredFilters.reduce((acc, f) => acc || f.checker(file), false))
});
this._createActionConfigs();
}
private _createQuickFilters() {
@ -398,15 +402,4 @@ export class DossierOverviewScreenComponent
}
];
}
private _createActionConfigs() {
this.actionConfigs = [
{
label: this._translateService.instant('dossier-overview.header-actions.edit'),
action: $event => this.openEditDossierDialog($event),
icon: 'red:edit',
hide: !this.permissionsService.isManager()
}
];
}
}

View File

@ -31,13 +31,14 @@ import { ViewMode } from '@models/file/view-mode';
import { FileWorkloadComponent } from '../../components/file-workload/file-workload.component';
import { DossiersDialogService } from '../../services/dossiers-dialog.service';
import { OnAttach, OnDetach } from '@utils/custom-route-reuse.strategy';
import { FilterModel } from '@shared/components/filters/popup-filter/model/filter.model';
import { handleFilterDelta, processFilters } from '@shared/components/filters/popup-filter/utils/filter-utils';
import { LoadingService } from '@services/loading.service';
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 { processFilters } from '@iqser/common-ui';
import { handleFilterDelta } from '@shared/components/filters/popup-filter/utils/filter-utils';
const ALL_HOTKEY_ARRAY = ['Escape', 'F', 'f'];

View File

@ -4,19 +4,19 @@ import { MatchedDocument, SearchControllerService, SearchResult } from '@redacti
import { BehaviorSubject, Observable } from 'rxjs';
import { debounceTime, map, skip, switchMap, tap } from 'rxjs/operators';
import { ActivatedRoute, Router } from '@angular/router';
import { TableColConfig } from '../../../shared/components/table-col-name/table-col-name.component';
import { FilterService } from '../../../shared/services/filter.service';
import { SearchService } from '../../../shared/services/search.service';
import { ScreenStateService } from '../../../shared/services/screen-state.service';
import { SortingService } from '../../../../services/sorting.service';
import { AppStateService } from '../../../../state/app-state.service';
import { FileStatusWrapper } from '../../../../models/file/file-status.wrapper';
import { LoadingService } from '../../../../services/loading.service';
import { TableColConfig } from '@shared/components/table-col-name/table-col-name.component';
import { FilterService } 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';
import { AppStateService } from '@state/app-state.service';
import { FileStatusWrapper } from '@models/file/file-status.wrapper';
import { LoadingService } from '@services/loading.service';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { fileStatusTranslations } from '../../translations/file-status-translations';
import { searchPositions } from '../../../shared/components/page-header/models/search-positions.type';
import { keyChecker } from '../../../shared/components/filters/popup-filter/utils/filter-utils';
import { DossierWrapper } from '../../../../state/model/dossier.wrapper';
import { SearchPositions } from '@shared/components/page-header/models/search-positions.type';
import { keyChecker } from '@iqser/common-ui';
import { DossierWrapper } from '@state/model/dossier.wrapper';
import { TranslateService } from '@ngx-translate/core';
interface ListItem {
@ -42,7 +42,7 @@ interface SearchInput {
})
export class SearchScreenComponent extends BaseListingComponent<ListItem> implements OnDestroy {
readonly fileStatusTranslations = fileStatusTranslations;
readonly searchPositions = searchPositions;
readonly searchPositions = SearchPositions;
readonly itemSize = 85;
readonly search$ = new BehaviorSubject<SearchInput>(null);
@ -85,7 +85,7 @@ export class SearchScreenComponent extends BaseListingComponent<ListItem> implem
slug: 'dossiers',
label: this._translateService.instant('search-screen.filters.by-dossier'),
icon: 'red:folder',
values: this._appStateService.allDossiers.map(dossier => ({
filters: this._appStateService.allDossiers.map(dossier => ({
key: dossier.dossierId,
label: dossier.dossierName
})),

View File

@ -1,10 +1,10 @@
import { Injectable } from '@angular/core';
import { AnnotationWrapper } from '@models/file/annotation.wrapper';
import { SuperTypeSorter } from '@utils/sorters/super-type-sorter';
import { FilterModel } from '@shared/components/filters/popup-filter/model/filter.model';
import { handleCheckedValue } from '@shared/components/filters/popup-filter/utils/filter-utils';
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';
@Injectable()
export class AnnotationProcessingService {

View File

@ -7,7 +7,7 @@ import { combineLatest, Observable } from 'rxjs';
import { AutoUnsubscribeComponent } from '@iqser/common-ui';
import { distinctUntilChanged, map, switchMap } from 'rxjs/operators';
import { PermissionsService } from '@services/permissions.service';
import { FilterService } from '../services/filter.service';
import { FilterService } from '@iqser/common-ui';
@Component({ template: '' })
export abstract class BaseListingComponent<T> extends AutoUnsubscribeComponent implements OnDestroy {

View File

@ -1,14 +0,0 @@
import { FilterModel } from './filter.model';
import { TemplateRef } from '@angular/core';
export interface FilterGroup {
slug: string;
label?: string;
icon?: string;
filterTemplate?: TemplateRef<any>;
hide?: boolean;
values: FilterModel[];
checker: Function;
matchAll?: boolean;
checkerArgs?: any;
}

View File

@ -1,13 +0,0 @@
export interface FilterModel {
key: string;
label?: string;
icon?: string;
checked?: boolean;
indeterminate?: boolean;
expanded?: boolean;
topLevelFilter?: boolean;
matches?: number;
filters?: FilterModel[];
checker?: (obj?) => boolean;
required?: boolean;
}

View File

@ -1,6 +1,6 @@
import { ChangeDetectorRef, Component, EventEmitter, Input, OnChanges, Output, TemplateRef } from '@angular/core';
import { FilterModel } from './model/filter.model';
import { handleCheckedValue } from './utils/filter-utils';
import { FilterModel } from '@iqser/common-ui';
import { handleCheckedValue } from '@iqser/common-ui';
import { MAT_CHECKBOX_DEFAULT_OPTIONS } from '@angular/material/checkbox';
@Component({

View File

@ -1,18 +1,8 @@
import { FilterModel } from '../model/filter.model';
import { FileStatusWrapper } from '@models/file/file-status.wrapper';
import { DossierWrapper } from '@state/model/dossier.wrapper';
import { PermissionsService } from '@services/permissions.service';
import { FilterGroup } from '@shared/components/filters/popup-filter/model/filter-wrapper.model';
export function processFilters(oldFilters: FilterModel[], newFilters: FilterModel[]) {
copySettings(oldFilters, newFilters);
if (newFilters) {
newFilters.forEach(filter => {
handleCheckedValue(filter);
});
}
return newFilters;
}
import { handleCheckedValue } from '@iqser/common-ui';
import { FilterModel } from '@iqser/common-ui';
export function handleFilterDelta(oldFilters: FilterModel[], newFilters: FilterModel[], allFilters: FilterModel[]) {
const newFiltersDelta = {};
@ -57,62 +47,6 @@ export function handleFilterDelta(oldFilters: FilterModel[], newFilters: FilterM
});
}
function copySettings(oldFilters: FilterModel[], newFilters: FilterModel[]) {
if (oldFilters && newFilters) {
for (const oldFilter of oldFilters) {
const newFilter = newFilters.find(f => f.key === oldFilter.key);
if (newFilter) {
newFilter.checked = oldFilter.checked;
newFilter.indeterminate = oldFilter.indeterminate;
copySettings(oldFilter.filters, newFilter.filters);
}
}
}
}
export function handleCheckedValue(filter: FilterModel) {
if (filter.filters && filter.filters.length) {
filter.checked = filter.filters.reduce((acc, next) => acc && next.checked, true);
if (filter.checked) {
filter.indeterminate = false;
} else {
filter.indeterminate = filter.filters.reduce((acc, next) => acc || next.checked, false);
}
} else {
filter.indeterminate = false;
}
}
export function checkFilter(entity: any, filters: FilterModel[], validate: Function, validateArgs: any = [], matchAll: boolean = false) {
const hasChecked = filters.find(f => f.checked);
if (validateArgs) {
if (!Array.isArray(validateArgs)) {
validateArgs = [validateArgs];
}
} else {
validateArgs = [];
}
if (!hasChecked) {
return true;
}
let filterMatched = matchAll;
for (const filter of filters) {
if (filter.checked) {
if (matchAll) {
filterMatched = filterMatched && validate(entity, filter, ...validateArgs);
} else {
filterMatched = filterMatched || validate(entity, filter, ...validateArgs);
}
}
}
return filterMatched;
}
export const keyChecker = (key: string) => (entity: any, filter: FilterModel) => entity[key] === filter.key;
export const annotationFilterChecker = (
input: FileStatusWrapper | DossierWrapper,
filter: FilterModel,
@ -153,22 +87,4 @@ export const dossierMemberChecker = (dw: DossierWrapper, filter: FilterModel) =>
export const dossierTemplateChecker = (dw: DossierWrapper, filter: FilterModel) => dw.dossierTemplateId === filter.key;
export const dueDateChecker = (dw: DossierWrapper, filter: FilterModel) => dw.dueDateMatches(filter.key);
export const addedDateChecker = (dw: DossierWrapper, filter: FilterModel) => dw.addedDateMatches(filter.key);
export const dossierApproverChecker = (dw: DossierWrapper, filter: FilterModel) => dw.approverIds.includes(filter.key);
export function getFilteredEntities<T>(entities: T[], filters: FilterGroup[]) {
const filteredEntities: T[] = [];
for (const entity of entities) {
let add = true;
for (const filter of filters) {
add = add && checkFilter(entity, filter.values, filter.checker, filter.checkerArgs, filter.matchAll);
}
if (add) {
filteredEntities.push(entity);
}
}
return filteredEntities;
}

View File

@ -1,5 +1,5 @@
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { FilterService } from '@shared/services/filter.service';
import { FilterService } from '@iqser/common-ui';
@Component({
selector: 'redaction-quick-filters',

View File

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

View File

@ -1,5 +1,5 @@
export interface BaseHeaderConfig {
label: string;
icon?: string;
hide?: boolean;
readonly label: string;
readonly icon?: string;
readonly hide?: boolean;
}

View File

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

View File

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

View File

@ -1,6 +1,6 @@
export const searchPositions = {
export const SearchPositions = {
beforeFilters: 'beforeFilters',
afterFilters: 'afterFilters'
} as const;
export type SearchPosition = keyof typeof searchPositions;
export type SearchPosition = keyof typeof SearchPositions;

View File

@ -13,7 +13,7 @@
[filterLabel]="config.label"
[filterTemplate]="config.filterTemplate"
[icon]="config.icon"
[primaryFilters]="config.values"
[primaryFilters]="config.filters"
></redaction-popup-filter>
</ng-container>

View File

@ -1,11 +1,11 @@
import { Component, Input, Optional } from '@angular/core';
import { ActionConfig } from '@shared/components/page-header/models/action-config.model';
import { ButtonConfig } from '@shared/components/page-header/models/button-config.model';
import { FilterService } from '@shared/services/filter.service';
import { FilterService } from '@iqser/common-ui';
import { SearchService } from '@shared/services/search.service';
import { distinctUntilChanged, map } from 'rxjs/operators';
import { combineLatest, Observable, of } from 'rxjs';
import { SearchPosition, searchPositions } from '@shared/components/page-header/models/search-positions.type';
import { SearchPosition, SearchPositions } from '@shared/components/page-header/models/search-positions.type';
@Component({
selector: 'redaction-page-header',
@ -13,7 +13,7 @@ import { SearchPosition, searchPositions } from '@shared/components/page-header/
styleUrls: ['./page-header.component.scss']
})
export class PageHeaderComponent {
readonly searchPositions = searchPositions;
readonly searchPositions = SearchPositions;
@Input() pageLabel: string;
@Input() showCloseButton: boolean;

View File

@ -1,6 +1,6 @@
import { Component, Input, OnChanges } from '@angular/core';
import { Color } from '@utils/types';
import { FilterService } from '@shared/services/filter.service';
import { FilterService } from '@iqser/common-ui';
import { Observable, of } from 'rxjs';
import { map } from 'rxjs/operators';

View File

@ -1,83 +0,0 @@
import { Injectable } from '@angular/core';
import { FilterModel } from '@shared/components/filters/popup-filter/model/filter.model';
import { processFilters } from '@shared/components/filters/popup-filter/utils/filter-utils';
import { FilterGroup } from '@shared/components/filters/popup-filter/model/filter-wrapper.model';
import { BehaviorSubject, Observable, Subject } from 'rxjs';
import { distinctUntilChanged, map, startWith, switchMap } from 'rxjs/operators';
@Injectable()
export class FilterService {
private readonly _filterGroups$ = new BehaviorSubject<FilterGroup[]>([]);
private readonly _refresh$ = new Subject();
readonly filterGroups$ = this._refresh$.pipe(
startWith(''),
switchMap(() => this._filterGroups$.asObservable())
);
readonly showResetFilters$ = this._showResetFilters$;
get filterGroups(): FilterGroup[] {
return Object.values(this._filterGroups$.getValue());
}
private get _showResetFilters$(): Observable<boolean> {
return this.filterGroups$.pipe(
map(all => this._toFlatFilters(all)),
map(f => !!f.find(el => el.checked)),
distinctUntilChanged()
);
}
refresh(): void {
this._refresh$.next();
}
toggleFilter(slug: string, key: string) {
const filters = this.filterGroups.find(f => f.slug === slug).values;
let found = filters.find(f => f.key === key);
if (!found) found = filters.map(f => f.filters?.find(ff => ff.key === key))[0];
found.checked = !found.checked;
this.refresh();
}
addFilterGroup(value: FilterGroup): void {
const oldFilters = this.getFilterGroup(value.slug)?.values;
if (!oldFilters) return this._filterGroups$.next([...this.filterGroups, value]);
value.values = processFilters(oldFilters, value.values);
this._filterGroups$.next([...this.filterGroups.filter(f => f.slug !== value.slug), value]);
}
getFilterGroup(slug: string): FilterGroup {
return this.filterGroups.find(f => f.slug === slug);
}
getFilterModels$(filterGroupSlug: string): Observable<FilterModel[]> {
return this.getFilterGroup$(filterGroupSlug).pipe(map(f => f?.values));
}
getFilterGroup$(slug: string): Observable<FilterGroup> {
return this.filterGroups$.pipe(map(all => all.find(f => f.slug === slug)));
}
reset(): void {
this.filterGroups.forEach(item => {
item.values.forEach(child => {
child.checked = false;
child.indeterminate = false;
child.filters?.forEach(f => {
f.checked = false;
f.indeterminate = false;
});
});
});
this.refresh();
}
private _toFlatFilters(entities: FilterGroup[]): FilterModel[] {
const flatChildren = (filters: FilterModel[]) => (filters ?? []).reduce((acc, f) => [...acc, ...(f?.filters ?? [])], []);
return entities.reduce((acc, f) => [...acc, ...f.values, ...flatChildren(f.values)], []);
}
}

View File

@ -1,9 +1,9 @@
import { Injectable } from '@angular/core';
import { BehaviorSubject, combineLatest, Observable } from 'rxjs';
import { distinctUntilChanged, map, tap } from 'rxjs/operators';
import { FilterService } from '@shared/services/filter.service';
import { FilterService } from '@iqser/common-ui';
import { SearchService } from '@shared/services/search.service';
import { getFilteredEntities } from '@shared/components/filters/popup-filter/utils/filter-utils';
import { getFilteredEntities } from '@iqser/common-ui';
const toLengthValue = entities => entities?.length ?? 0;

View File

@ -14,19 +14,19 @@ const enum NotificationType {
}
export interface ToasterOptions extends IndividualConfig {
title?: string;
readonly title?: string;
/**
* These params are used as interpolateParams for translate service
*/
params?: object;
actions?: { title?: string; action: () => void }[];
readonly params?: object;
readonly actions?: { readonly title?: string; readonly action: () => void }[];
}
export interface ErrorToasterOptions extends ToasterOptions {
/**
* Pass an http error that will be processed by error message service and shown in toast
*/
error?: HttpErrorResponse;
readonly error?: HttpErrorResponse;
}
@Injectable({