code cleanup
@ -17,7 +17,14 @@
|
||||
[class.error]="!checkbox.value && showToast"
|
||||
color="primary"
|
||||
>
|
||||
{{ checkbox.label | translate: { dossiersCount: dossiersCount, userCount: users.length } }}
|
||||
{{
|
||||
checkbox.label
|
||||
| translate
|
||||
: {
|
||||
dossiersCount: dossiersCount,
|
||||
userCount: users.length
|
||||
}
|
||||
}}
|
||||
</mat-checkbox>
|
||||
</div>
|
||||
|
||||
|
||||
@ -31,8 +31,6 @@ export interface Field {
|
||||
providers: [FilterService, SearchService, ScreenStateService, SortingService]
|
||||
})
|
||||
export class FileAttributesCsvImportDialogComponent extends BaseListingComponent<Field> {
|
||||
protected readonly _primaryKey = 'id';
|
||||
|
||||
csvFile: File;
|
||||
dossierTemplateId: string;
|
||||
parseResult: { data: any[]; errors: any[]; meta: any; fields: Field[] };
|
||||
@ -45,6 +43,7 @@ export class FileAttributesCsvImportDialogComponent extends BaseListingComponent
|
||||
keepPreview = false;
|
||||
columnSample = [];
|
||||
initialParseConfig: { delimiter?: string; encoding?: string } = {};
|
||||
protected readonly _primaryKey = 'id';
|
||||
|
||||
constructor(
|
||||
private readonly _appStateService: AppStateService,
|
||||
|
||||
@ -25,8 +25,8 @@ export class DefaultColorsScreenComponent
|
||||
}>
|
||||
implements OnInit
|
||||
{
|
||||
private _colorsObj: Colors;
|
||||
protected readonly _primaryKey = 'key';
|
||||
private _colorsObj: Colors;
|
||||
|
||||
constructor(
|
||||
private readonly _appStateService: AppStateService,
|
||||
|
||||
@ -30,8 +30,8 @@
|
||||
<redaction-circle-button
|
||||
(action)="openDeleteTemplatesDialog($event)"
|
||||
*ngIf="canBulkDelete$(permissionsService.isAdmin()) | async"
|
||||
icon="red:trash"
|
||||
[tooltip]="'dossier-templates-listing.bulk.delete' | translate"
|
||||
icon="red:trash"
|
||||
type="dark-bg"
|
||||
></redaction-circle-button>
|
||||
|
||||
|
||||
@ -5,9 +5,9 @@
|
||||
|
||||
<div>
|
||||
<redaction-page-header
|
||||
[buttonConfigs]="buttonConfigs"
|
||||
[pageLabel]="'license-information' | translate"
|
||||
[showCloseButton]="permissionsService.isUser()"
|
||||
[buttonConfigs]="buttonConfigs"
|
||||
></redaction-page-header>
|
||||
|
||||
<div class="red-content-inner">
|
||||
|
||||
@ -47,10 +47,6 @@ export class RulesScreenComponent extends ComponentHasChanges implements OnInit
|
||||
_appStateService.activateDossierTemplate(_activatedRoute.snapshot.params.dossierTemplateId);
|
||||
}
|
||||
|
||||
async ngOnInit() {
|
||||
await this._initialize();
|
||||
}
|
||||
|
||||
get hasChanges(): boolean {
|
||||
return this.currentLines.toString() !== this.initialLines.toString();
|
||||
}
|
||||
@ -64,6 +60,10 @@ export class RulesScreenComponent extends ComponentHasChanges implements OnInit
|
||||
this.codeEditorTextChanged();
|
||||
}
|
||||
|
||||
async ngOnInit() {
|
||||
await this._initialize();
|
||||
}
|
||||
|
||||
onCodeEditorInit(editor: ICodeEditor) {
|
||||
this._codeEditor = editor;
|
||||
(window as any).monaco.editor.defineTheme('redaction', {
|
||||
|
||||
@ -20,8 +20,8 @@ import { DossiersService } from '../../../dossier/services/dossiers.service';
|
||||
})
|
||||
export class TrashScreenComponent extends BaseListingComponent<Dossier> implements OnInit {
|
||||
readonly itemSize = 85;
|
||||
private readonly _deleteRetentionHours = this._appConfigService.getConfig(AppConfigKey.DELETE_RETENTION_HOURS);
|
||||
protected readonly _primaryKey = 'dossierName';
|
||||
private readonly _deleteRetentionHours = this._appConfigService.getConfig(AppConfigKey.DELETE_RETENTION_HOURS);
|
||||
|
||||
constructor(
|
||||
private readonly _appStateService: AppStateService,
|
||||
|
||||
@ -22,11 +22,10 @@ import { map } from 'rxjs/operators';
|
||||
providers: [FilterService, SearchService, ScreenStateService, SortingService]
|
||||
})
|
||||
export class UserListingScreenComponent extends BaseListingComponent<User> implements OnInit {
|
||||
protected readonly _primaryKey = 'userId';
|
||||
readonly canDeleteSelected$ = this._canDeleteSelected$;
|
||||
|
||||
collapsedDetails = false;
|
||||
chartData: DoughnutChartConfig[] = [];
|
||||
protected readonly _primaryKey = 'userId';
|
||||
@ViewChildren(InitialsAvatarComponent)
|
||||
private readonly _avatars: QueryList<InitialsAvatarComponent>;
|
||||
|
||||
|
||||
@ -6,8 +6,7 @@
|
||||
[tooltip]="'annotation-actions.edit-reason.label' | translate"
|
||||
[type]="btnType"
|
||||
icon="red:edit"
|
||||
>
|
||||
</redaction-circle-button>
|
||||
></redaction-circle-button>
|
||||
|
||||
<redaction-circle-button
|
||||
(action)="annotationActionsService.convertRecommendationToAnnotation($event, annotations, annotationsChanged)"
|
||||
@ -16,8 +15,7 @@
|
||||
[tooltip]="'annotation-actions.accept-recommendation.label' | translate"
|
||||
[type]="btnType"
|
||||
icon="red:check"
|
||||
>
|
||||
</redaction-circle-button>
|
||||
></redaction-circle-button>
|
||||
|
||||
<redaction-circle-button
|
||||
(action)="annotationActionsService.acceptSuggestion($event, annotations, annotationsChanged)"
|
||||
@ -26,8 +24,7 @@
|
||||
[tooltip]="'annotation-actions.accept-suggestion.label' | translate"
|
||||
[type]="btnType"
|
||||
icon="red:check"
|
||||
>
|
||||
</redaction-circle-button>
|
||||
></redaction-circle-button>
|
||||
|
||||
<redaction-circle-button
|
||||
(action)="annotationActionsService.undoDirectAction($event, annotations, annotationsChanged)"
|
||||
@ -36,8 +33,7 @@
|
||||
[tooltip]="'annotation-actions.undo' | translate"
|
||||
[type]="btnType"
|
||||
icon="red:undo"
|
||||
>
|
||||
</redaction-circle-button>
|
||||
></redaction-circle-button>
|
||||
|
||||
<redaction-circle-button
|
||||
(action)="annotationActionsService.rejectSuggestion($event, annotations, annotationsChanged)"
|
||||
@ -46,8 +42,7 @@
|
||||
[tooltip]="'annotation-actions.reject-suggestion' | translate"
|
||||
[type]="btnType"
|
||||
icon="red:trash"
|
||||
>
|
||||
</redaction-circle-button>
|
||||
></redaction-circle-button>
|
||||
|
||||
<redaction-circle-button
|
||||
(action)="annotationActionsService.recategorizeImage($event, annotations, annotationsChanged)"
|
||||
@ -56,8 +51,7 @@
|
||||
[tooltip]="'annotation-actions.recategorize-image' | translate"
|
||||
[type]="btnType"
|
||||
icon="red:thumb-down"
|
||||
>
|
||||
</redaction-circle-button>
|
||||
></redaction-circle-button>
|
||||
|
||||
<redaction-circle-button
|
||||
(action)="annotationActionsService.markAsFalsePositive($event, annotations, annotationsChanged)"
|
||||
@ -66,8 +60,7 @@
|
||||
[tooltip]="'annotation-actions.remove-annotation.false-positive' | translate"
|
||||
[type]="btnType"
|
||||
icon="red:thumb-down"
|
||||
>
|
||||
</redaction-circle-button>
|
||||
></redaction-circle-button>
|
||||
|
||||
<redaction-circle-button
|
||||
(action)="annotationActionsService.forceRedaction($event, annotations, annotationsChanged)"
|
||||
@ -76,8 +69,7 @@
|
||||
[tooltip]="'annotation-actions.force-redaction.label' | translate"
|
||||
[type]="btnType"
|
||||
icon="red:thumb-up"
|
||||
>
|
||||
</redaction-circle-button>
|
||||
></redaction-circle-button>
|
||||
|
||||
<redaction-circle-button
|
||||
(action)="hideAnnotation($event)"
|
||||
@ -86,8 +78,7 @@
|
||||
[tooltip]="'annotation-actions.hide' | translate"
|
||||
[type]="btnType"
|
||||
icon="red:visibility-off"
|
||||
>
|
||||
</redaction-circle-button>
|
||||
></redaction-circle-button>
|
||||
|
||||
<redaction-circle-button
|
||||
(action)="showAnnotation($event)"
|
||||
@ -96,8 +87,7 @@
|
||||
[tooltip]="'annotation-actions.show' | translate"
|
||||
[type]="btnType"
|
||||
icon="red:visibility"
|
||||
>
|
||||
</redaction-circle-button>
|
||||
></redaction-circle-button>
|
||||
|
||||
<redaction-circle-button
|
||||
(action)="suggestRemoveAnnotations($event, true)"
|
||||
@ -106,8 +96,7 @@
|
||||
[tooltip]="'annotation-actions.remove-annotation.remove-from-dict' | translate"
|
||||
[type]="btnType"
|
||||
icon="red:remove-from-dict"
|
||||
>
|
||||
</redaction-circle-button>
|
||||
></redaction-circle-button>
|
||||
|
||||
<redaction-circle-button
|
||||
(action)="markAsFalsePositive($event)"
|
||||
@ -116,8 +105,7 @@
|
||||
[tooltip]="'annotation-actions.remove-annotation.false-positive' | translate"
|
||||
[type]="btnType"
|
||||
icon="red:thumb-down"
|
||||
>
|
||||
</redaction-circle-button>
|
||||
></redaction-circle-button>
|
||||
|
||||
<redaction-circle-button
|
||||
(action)="suggestRemoveAnnotations($event, false)"
|
||||
@ -126,6 +114,5 @@
|
||||
[tooltip]="'annotation-actions.remove-annotation.only-here' | translate"
|
||||
[type]="btnType"
|
||||
icon="red:trash"
|
||||
>
|
||||
</redaction-circle-button>
|
||||
></redaction-circle-button>
|
||||
</div>
|
||||
|
||||
@ -14,14 +14,10 @@ import { WebViewerInstance } from '@pdftron/webviewer';
|
||||
export class AnnotationActionsComponent implements OnInit {
|
||||
@Input() btnType: 'dark-bg' | 'primary' = 'dark-bg';
|
||||
@Input() tooltipPosition: 'before' | 'above' = 'before';
|
||||
|
||||
@Input() _annotations: AnnotationWrapper[];
|
||||
@Input() canPerformAnnotationActions: boolean;
|
||||
@Input() viewer: WebViewerInstance;
|
||||
@Input() alwaysVisible: boolean;
|
||||
|
||||
@Output() annotationsChanged = new EventEmitter<AnnotationWrapper>();
|
||||
|
||||
annotationPermissions: AnnotationPermissions;
|
||||
|
||||
constructor(
|
||||
@ -30,6 +26,8 @@ export class AnnotationActionsComponent implements OnInit {
|
||||
private _permissionsService: PermissionsService
|
||||
) {}
|
||||
|
||||
private _annotations: AnnotationWrapper[];
|
||||
|
||||
get annotations(): AnnotationWrapper[] {
|
||||
return this._annotations;
|
||||
}
|
||||
|
||||
@ -5,7 +5,6 @@ import { PageRange, ReanalysisControllerService } from '@redaction/red-ui-http';
|
||||
import { FileDataModel } from '../../../../models/file/file-data.model';
|
||||
import { Toaster } from '../../../../services/toaster.service';
|
||||
import { LoadingService } from '../../../../services/loading.service';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
|
||||
@Component({
|
||||
selector: 'redaction-page-exclusion',
|
||||
|
||||
@ -49,11 +49,13 @@
|
||||
|
||||
.page-number-input {
|
||||
-moz-appearance: textfield;
|
||||
|
||||
&::-webkit-outer-spin-button,
|
||||
&::-webkit-inner-spin-button {
|
||||
-webkit-appearance: none;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
color: $grey-7;
|
||||
text-decoration: none;
|
||||
outline: none;
|
||||
|
||||
@ -1,7 +1,5 @@
|
||||
import { ChangeDetectorRef, Component, Inject, ViewChild } from '@angular/core';
|
||||
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
|
||||
import { FormBuilder } from '@angular/forms';
|
||||
import { AppStateService } from '@state/app-state.service';
|
||||
import { MAT_DIALOG_DATA } from '@angular/material/dialog';
|
||||
import { DossierWrapper } from '@state/model/dossier.wrapper';
|
||||
import { EditDossierGeneralInfoComponent } from './general-info/edit-dossier-general-info.component';
|
||||
import { EditDossierDownloadPackageComponent } from './download-package/edit-dossier-download-package.component';
|
||||
|
||||
@ -9,8 +9,8 @@
|
||||
<div class="red-content-inner">
|
||||
<div class="content-container">
|
||||
<redaction-table-header
|
||||
[tableHeaderLabel]="'dossier-listing.table-header.title'"
|
||||
[tableColConfigs]="tableColConfigs"
|
||||
[tableHeaderLabel]="'dossier-listing.table-header.title'"
|
||||
></redaction-table-header>
|
||||
|
||||
<redaction-empty-state
|
||||
|
||||
@ -42,7 +42,6 @@ export class DossierListingScreenComponent
|
||||
implements OnInit, AfterViewInit, OnDestroy, OnAttach, OnDetach
|
||||
{
|
||||
readonly itemSize = 95;
|
||||
protected readonly _primaryKey = 'dossierName';
|
||||
buttonConfigs: ButtonConfig[] = [
|
||||
{
|
||||
label: this._translateService.instant('dossier-listing.add-new'),
|
||||
@ -70,10 +69,9 @@ export class DossierListingScreenComponent
|
||||
class: 'flex-end'
|
||||
}
|
||||
];
|
||||
|
||||
dossiersChartData: DoughnutChartConfig[] = [];
|
||||
documentsChartData: DoughnutChartConfig[] = [];
|
||||
|
||||
protected readonly _primaryKey = 'dossierName';
|
||||
private _lastScrollPosition: number;
|
||||
|
||||
@ViewChild('needsWorkTemplate', { read: TemplateRef, static: true })
|
||||
@ -95,6 +93,18 @@ export class DossierListingScreenComponent
|
||||
this._loadEntitiesFromState();
|
||||
}
|
||||
|
||||
private get _userId() {
|
||||
return this._userService.userId;
|
||||
}
|
||||
|
||||
private get _activeDossiersCount(): number {
|
||||
return this.screenStateService.allEntities.filter(p => p.dossier.status === Dossier.StatusEnum.ACTIVE).length;
|
||||
}
|
||||
|
||||
private get _inactiveDossiersCount(): number {
|
||||
return this.screenStateService.allEntities.length - this._activeDossiersCount;
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.calculateData();
|
||||
|
||||
@ -144,18 +154,6 @@ export class DossierListingScreenComponent
|
||||
});
|
||||
}
|
||||
|
||||
private get _userId() {
|
||||
return this._userService.userId;
|
||||
}
|
||||
|
||||
private get _activeDossiersCount(): number {
|
||||
return this.screenStateService.allEntities.filter(p => p.dossier.status === Dossier.StatusEnum.ACTIVE).length;
|
||||
}
|
||||
|
||||
private get _inactiveDossiersCount(): number {
|
||||
return this.screenStateService.allEntities.length - this._activeDossiersCount;
|
||||
}
|
||||
|
||||
calculateData() {
|
||||
this._computeAllFilters();
|
||||
|
||||
|
||||
@ -43,10 +43,10 @@ export class DossierOverviewScreenComponent
|
||||
implements OnInit, OnDestroy, OnDetach, OnAttach
|
||||
{
|
||||
readonly itemSize = 80;
|
||||
protected readonly _primaryKey = 'filename';
|
||||
collapsedDetails = false;
|
||||
actionConfigs: ActionConfig[];
|
||||
dossierAttributes: DossierAttributeWithValue[] = [];
|
||||
protected readonly _primaryKey = 'filename';
|
||||
@ViewChild(DossierDetailsComponent, { static: false })
|
||||
private readonly _dossierDetailsComponent: DossierDetailsComponent;
|
||||
private readonly _lastOpenedFileKey = 'Dossier-Recent-' + this.activeDossier.dossierId;
|
||||
|
||||
@ -44,6 +44,21 @@ export abstract class BaseListingComponent<T> extends AutoUnsubscribeComponent i
|
||||
this.noMatch$ = this._noMatch$;
|
||||
}
|
||||
|
||||
get allEntities(): T[] {
|
||||
return this.screenStateService.allEntities;
|
||||
}
|
||||
|
||||
private get _sortedDisplayedEntities$(): Observable<T[]> {
|
||||
return this.screenStateService.displayedEntities$.pipe(map(entities => this.sortingService.defaultSort(entities)));
|
||||
}
|
||||
|
||||
private get _noMatch$(): Observable<boolean> {
|
||||
return combineLatest([this.screenStateService.allEntitiesLength$, this.screenStateService.displayedLength$]).pipe(
|
||||
map(([hasEntities, hasDisplayedEntities]) => hasEntities && !hasDisplayedEntities),
|
||||
distinctUntilChanged()
|
||||
);
|
||||
}
|
||||
|
||||
setInitialConfig() {
|
||||
this.sortingService.setSortingOption({
|
||||
column: this._primaryKey,
|
||||
@ -56,21 +71,6 @@ export abstract class BaseListingComponent<T> extends AutoUnsubscribeComponent i
|
||||
super.ngOnDestroy();
|
||||
}
|
||||
|
||||
private get _sortedDisplayedEntities$(): Observable<T[]> {
|
||||
return this.screenStateService.displayedEntities$.pipe(map(entities => this.sortingService.defaultSort(entities)));
|
||||
}
|
||||
|
||||
get allEntities(): T[] {
|
||||
return this.screenStateService.allEntities;
|
||||
}
|
||||
|
||||
private get _noMatch$(): Observable<boolean> {
|
||||
return combineLatest([this.screenStateService.allEntitiesLength$, this.screenStateService.displayedLength$]).pipe(
|
||||
map(([hasEntities, hasDisplayedEntities]) => hasEntities && !hasDisplayedEntities),
|
||||
distinctUntilChanged()
|
||||
);
|
||||
}
|
||||
|
||||
canBulkDelete$(hasPermission = true): Observable<boolean> {
|
||||
return this.screenStateService.areSomeEntitiesSelected$.pipe(
|
||||
map(areSomeEntitiesSelected => areSomeEntitiesSelected && hasPermission),
|
||||
|
||||
@ -44,7 +44,6 @@ export class DictionaryManagerComponent implements OnChanges, OnInit {
|
||||
private _diffEditor: IDiffEditor;
|
||||
private _decorations: string[] = [];
|
||||
private _searchDecorations: string[] = [];
|
||||
private _dossier: DossierWrapper = this.selectDossier as DossierWrapper;
|
||||
|
||||
constructor(
|
||||
private readonly _dictionaryControllerService: DictionaryControllerService,
|
||||
@ -53,14 +52,7 @@ export class DictionaryManagerComponent implements OnChanges, OnInit {
|
||||
this.currentEntries = this.initialEntries;
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.editorOptions = {
|
||||
theme: 'vs',
|
||||
language: 'text/plain',
|
||||
automaticLayout: true,
|
||||
readOnly: !this.canEdit
|
||||
};
|
||||
}
|
||||
private _dossier: DossierWrapper = this.selectDossier as DossierWrapper;
|
||||
|
||||
get dossier() {
|
||||
return this._dossier;
|
||||
@ -101,6 +93,15 @@ export class DictionaryManagerComponent implements OnChanges, OnInit {
|
||||
return this.currentEntries.toString() !== this.initialEntries.toString();
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.editorOptions = {
|
||||
theme: 'vs',
|
||||
language: 'text/plain',
|
||||
automaticLayout: true,
|
||||
readOnly: !this.canEdit
|
||||
};
|
||||
}
|
||||
|
||||
onDiffEditorInit(editor: IDiffEditor): void {
|
||||
this._diffEditor = editor;
|
||||
}
|
||||
|
||||
@ -25,7 +25,7 @@
|
||||
<div (click)="resetFilters()" *ngIf="showResetFilters$ | async" class="reset-filters" translate="reset-filters"></div>
|
||||
</div>
|
||||
|
||||
<div class="actions" *ngIf="showCloseButton || actionConfigs || buttonConfigs">
|
||||
<div *ngIf="showCloseButton || actionConfigs || buttonConfigs" class="actions">
|
||||
<ng-container *ngFor="let config of buttonConfigs; trackBy: trackByLabel">
|
||||
<redaction-icon-button
|
||||
(action)="config.action($event)"
|
||||
@ -51,8 +51,8 @@
|
||||
|
||||
<redaction-circle-button
|
||||
*ngIf="showCloseButton"
|
||||
[tooltip]="'common.close' | translate"
|
||||
[class.ml-6]="actionConfigs"
|
||||
[tooltip]="'common.close' | translate"
|
||||
icon="red:close"
|
||||
redactionNavigateLastDossiersScreen
|
||||
tooltipPosition="below"
|
||||
|
||||
@ -9,13 +9,13 @@
|
||||
<div class="table-header" redactionSyncWidth="table-item">
|
||||
<redaction-table-col-name
|
||||
*ngFor="let config of tableColConfigs"
|
||||
[withSort]="config.withSort"
|
||||
[class]="config.class"
|
||||
[column]="config.column"
|
||||
[label]="config.label"
|
||||
[class]="config.class"
|
||||
[leftIcon]="config.leftIcon"
|
||||
[rightIcon]="config.rightIcon"
|
||||
[rightIconTooltip]="config.rightIconTooltip"
|
||||
[rightIcon]="config.rightIcon"
|
||||
[withSort]="config.withSort"
|
||||
></redaction-table-col-name>
|
||||
|
||||
<div class="scrollbar-placeholder"></div>
|
||||
|
||||
@ -1,24 +1,29 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { FilterModel } from '@shared/components/filters/popup-filter/model/filter.model';
|
||||
import { getFilteredEntities, processFilters } from '@shared/components/filters/popup-filter/utils/filter-utils';
|
||||
import { ScreenStateService } from '@shared/services/screen-state.service';
|
||||
import { SearchService } from '@shared/services/search.service';
|
||||
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 } from 'rxjs';
|
||||
import { distinctUntilChanged, map, switchMap } from 'rxjs/operators';
|
||||
|
||||
@Injectable()
|
||||
export class FilterService {
|
||||
readonly showResetFilters$ = this._showResetFilters$;
|
||||
private readonly _filterGroups$ = new BehaviorSubject<FilterGroup[]>([]);
|
||||
private readonly _refresh$ = new BehaviorSubject(null);
|
||||
|
||||
readonly filterGroups$ = this._refresh$.pipe(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(null);
|
||||
}
|
||||
@ -67,14 +72,6 @@ export class FilterService {
|
||||
this.refresh();
|
||||
}
|
||||
|
||||
private get _showResetFilters$(): Observable<boolean> {
|
||||
return this.filterGroups$.pipe(
|
||||
map(all => this._toFlatFilters(all)),
|
||||
map(f => !!f.find(el => el.checked)),
|
||||
distinctUntilChanged()
|
||||
);
|
||||
}
|
||||
|
||||
private _toFlatFilters(entities: FilterGroup[]): FilterModel[] {
|
||||
const flatChildren = (filters: FilterModel[]) => (filters ?? []).reduce((acc, f) => [...acc, ...(f?.filters ?? [])], []);
|
||||
|
||||
|
||||
@ -9,22 +9,19 @@ const toLengthValue = entities => entities?.length ?? 0;
|
||||
|
||||
@Injectable()
|
||||
export class ScreenStateService<T> {
|
||||
private readonly _allEntities$ = new BehaviorSubject<T[]>([]);
|
||||
readonly allEntities$ = this._allEntities$.asObservable();
|
||||
readonly allEntitiesLength$ = this._allEntitiesLength$;
|
||||
|
||||
private readonly _displayedEntities$ = new BehaviorSubject<T[]>([]);
|
||||
readonly displayedEntities$ = this._getDisplayedEntities$;
|
||||
readonly displayedLength$ = this._displayedLength$;
|
||||
|
||||
private readonly _selectedEntities$ = new BehaviorSubject<T[]>([]);
|
||||
readonly selectedEntities$ = this._selectedEntities$.asObservable();
|
||||
readonly selectedLength$ = this._selectedLength$;
|
||||
|
||||
readonly noData$ = this._noData$;
|
||||
readonly areAllEntitiesSelected$ = this._areAllEntitiesSelected$;
|
||||
readonly areSomeEntitiesSelected$ = this._areSomeEntitiesSelected$;
|
||||
readonly notAllEntitiesSelected$ = this._notAllEntitiesSelected$;
|
||||
private readonly _allEntities$ = new BehaviorSubject<T[]>([]);
|
||||
readonly allEntities$ = this._allEntities$.asObservable();
|
||||
private readonly _displayedEntities$ = new BehaviorSubject<T[]>([]);
|
||||
private readonly _selectedEntities$ = new BehaviorSubject<T[]>([]);
|
||||
readonly selectedEntities$ = this._selectedEntities$.asObservable();
|
||||
|
||||
constructor(private readonly _filterService: FilterService, private readonly _searchService: SearchService<T>) {
|
||||
// setInterval(() => {
|
||||
@ -46,36 +43,6 @@ export class ScreenStateService<T> {
|
||||
return Object.values(this._displayedEntities$.getValue());
|
||||
}
|
||||
|
||||
setEntities(newEntities: Partial<T[]>): void {
|
||||
this._allEntities$.next(newEntities);
|
||||
}
|
||||
|
||||
setSelectedEntities(newEntities: Partial<T[]>): void {
|
||||
this._selectedEntities$.next(newEntities);
|
||||
}
|
||||
|
||||
isSelected(entity: T): boolean {
|
||||
return this.selectedEntities.indexOf(entity) !== -1;
|
||||
}
|
||||
|
||||
selectEntities(entities?: T[]): void {
|
||||
if (entities !== undefined && entities !== null && entities.length > 0) {
|
||||
return entities.forEach(entity => this._selectOne(entity));
|
||||
}
|
||||
return this._selectAll();
|
||||
}
|
||||
|
||||
updateSelection(): void {
|
||||
const items = this.displayedEntities.filter(item => this.selectedEntities.includes(item));
|
||||
this.setSelectedEntities(items);
|
||||
}
|
||||
|
||||
logCurrentState(): void {
|
||||
console.log('Entities', this.allEntities);
|
||||
console.log('Displayed', this.displayedEntities);
|
||||
console.log('Selected', this.selectedEntities);
|
||||
}
|
||||
|
||||
get _getDisplayedEntities$(): Observable<T[]> {
|
||||
const filterGroups$ = this._filterService.filterGroups$;
|
||||
const searchValue$ = this._searchService.valueChanges$;
|
||||
@ -133,6 +100,40 @@ export class ScreenStateService<T> {
|
||||
);
|
||||
}
|
||||
|
||||
private get _allEntitiesSelected() {
|
||||
return this.displayedEntities.length !== 0 && this.displayedEntities.length === this.selectedEntities.length;
|
||||
}
|
||||
|
||||
setEntities(newEntities: Partial<T[]>): void {
|
||||
this._allEntities$.next(newEntities);
|
||||
}
|
||||
|
||||
setSelectedEntities(newEntities: Partial<T[]>): void {
|
||||
this._selectedEntities$.next(newEntities);
|
||||
}
|
||||
|
||||
isSelected(entity: T): boolean {
|
||||
return this.selectedEntities.indexOf(entity) !== -1;
|
||||
}
|
||||
|
||||
selectEntities(entities?: T[]): void {
|
||||
if (entities !== undefined && entities !== null && entities.length > 0) {
|
||||
return entities.forEach(entity => this._selectOne(entity));
|
||||
}
|
||||
return this._selectAll();
|
||||
}
|
||||
|
||||
updateSelection(): void {
|
||||
const items = this.displayedEntities.filter(item => this.selectedEntities.includes(item));
|
||||
this.setSelectedEntities(items);
|
||||
}
|
||||
|
||||
logCurrentState(): void {
|
||||
console.log('Entities', this.allEntities);
|
||||
console.log('Displayed', this.displayedEntities);
|
||||
console.log('Selected', this.selectedEntities);
|
||||
}
|
||||
|
||||
private _selectOne(entity: T): void {
|
||||
const currentEntityIdx = this.selectedEntities.indexOf(entity);
|
||||
if (currentEntityIdx === -1) {
|
||||
@ -145,8 +146,4 @@ export class ScreenStateService<T> {
|
||||
if (this._allEntitiesSelected) return this.setSelectedEntities([]);
|
||||
this.setSelectedEntities(this.displayedEntities);
|
||||
}
|
||||
|
||||
private get _allEntitiesSelected() {
|
||||
return this.displayedEntities.length !== 0 && this.displayedEntities.length === this.selectedEntities.length;
|
||||
}
|
||||
}
|
||||
|
||||
@ -4,16 +4,18 @@ import { startWith } from 'rxjs/operators';
|
||||
|
||||
@Injectable()
|
||||
export class SearchService<T> {
|
||||
private _searchKey: string;
|
||||
|
||||
readonly searchForm = this._formBuilder.group({
|
||||
query: ['']
|
||||
});
|
||||
|
||||
readonly valueChanges$ = this.searchForm.get('query').valueChanges.pipe(startWith(''));
|
||||
private _searchKey: string;
|
||||
|
||||
constructor(private readonly _formBuilder: FormBuilder) {}
|
||||
|
||||
get searchValue(): string {
|
||||
return this.searchForm.get('query').value;
|
||||
}
|
||||
|
||||
searchIn(entities: T[]) {
|
||||
if (!this._searchKey) return entities;
|
||||
|
||||
@ -25,10 +27,6 @@ export class SearchService<T> {
|
||||
this._searchKey = value;
|
||||
}
|
||||
|
||||
get searchValue(): string {
|
||||
return this.searchForm.get('query').value;
|
||||
}
|
||||
|
||||
reset(): void {
|
||||
this.searchForm.reset({ query: '' });
|
||||
}
|
||||
|
||||
@ -17,6 +17,18 @@ export interface SortingOption {
|
||||
export class SortingService {
|
||||
private _sortingOption: SortingOption;
|
||||
|
||||
get sortingOption(): SortingOption {
|
||||
return this._sortingOption;
|
||||
}
|
||||
|
||||
private get _currentOrder(): SortingOrder {
|
||||
return this._sortingOption.order;
|
||||
}
|
||||
|
||||
private set _currentOrder(value: SortingOrder) {
|
||||
this._sortingOption.order = value;
|
||||
}
|
||||
|
||||
setSortingOption(value: SortingOption): void {
|
||||
this._sortingOption = value;
|
||||
}
|
||||
@ -49,16 +61,4 @@ export class SortingService {
|
||||
this._sortingOption = { column, order: SortingOrders.ASC };
|
||||
}
|
||||
}
|
||||
|
||||
get sortingOption(): SortingOption {
|
||||
return this._sortingOption;
|
||||
}
|
||||
|
||||
private get _currentOrder(): SortingOrder {
|
||||
return this._sortingOption.order;
|
||||
}
|
||||
|
||||
private set _currentOrder(value: SortingOrder) {
|
||||
this._sortingOption.order = value;
|
||||
}
|
||||
}
|
||||
|
||||
@ -9,14 +9,14 @@ interface UserAttributes {
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class UserPreferenceService {
|
||||
private _userAttributes: UserAttributes = {};
|
||||
|
||||
constructor(private readonly _userPreferenceControllerService: UserPreferenceControllerService) {
|
||||
_userPreferenceControllerService.getAllUserAttributes().subscribe(attributes => {
|
||||
this._userAttributes = attributes ?? {};
|
||||
});
|
||||
}
|
||||
|
||||
private _userAttributes: UserAttributes = {};
|
||||
|
||||
get userAttributes(): UserAttributes {
|
||||
return this._userAttributes;
|
||||
}
|
||||
|
||||
@ -1,11 +1,13 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg height="14px" version="1.1" viewBox="0 0 14 14" width="14px" xmlns="http://www.w3.org/2000/svg">
|
||||
<svg height="14px" version="1.1" viewBox="0 0 14 14" width="14px"
|
||||
xmlns="http://www.w3.org/2000/svg">
|
||||
<g fill="none" fill-rule="evenodd" id="Styleguide" stroke="none" stroke-width="1">
|
||||
<g id="Styleguide-Actions" transform="translate(-62.000000, -609.000000)">
|
||||
<rect height="906" width="904" x="0" y="0"></rect>
|
||||
<g id="Group-6" transform="translate(52.000000, 599.000000)">
|
||||
<rect height="34" id="Rectangle" rx="17" width="34" x="0" y="0"></rect>
|
||||
<g fill="#868E96" fill-rule="nonzero" id="status" transform="translate(10.000000, 10.000000)">
|
||||
<g fill="#868E96" fill-rule="nonzero" id="status"
|
||||
transform="translate(10.000000, 10.000000)">
|
||||
<path
|
||||
d="M7.7,2.38 L8.75,3.29 L6.86,5.18 L7.7,5.18 C11.2,5.18 14,8.05 14,11.48 L14,11.48 L12.6,11.48 C12.6,8.75 10.43,6.58 7.7,6.58 L7.7,6.58 L6.86,6.58 L8.75,8.47 L7.77,9.45 L4.2,5.88 L7.7,2.38 Z M3.5,2.38 L4.48,3.36 L1.96,5.88 L4.48,8.47 L3.5,9.45 L0,5.88 L3.5,2.38 Z"
|
||||
id="Back-to-review"></path>
|
||||
|
||||
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||
<!-- Generator: Adobe Illustrator 18.1.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px"
|
||||
viewBox="0 0 18.08 18.08" style="enable-background:new 0 0 18.08 18.08;" xml:space="preserve">
|
||||
<svg id="Capa_1" style="enable-background:new 0 0 18.08 18.08;" version="1.1" viewBox="0 0 18.08 18.08" x="0px"
|
||||
xml:space="preserve" xmlns="http://www.w3.org/2000/svg" y="0px">
|
||||
<g fill="#868E96">
|
||||
<path d="M6.504,10.283c-0.101,0-0.197,0.039-0.269,0.111c-0.071,0.07-0.111,0.167-0.111,0.269l0.008,2.55
|
||||
H1.026V2.245H8.54v1.36c0.151-0.102,0.334-0.162,0.53-0.162h0.547V1.729c0-0.188-0.153-0.342-0.342-0.342H0.342
|
||||
|
||||
|
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 1.9 KiB |
@ -1,13 +1,13 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="14px" height="14px" viewBox="0 0 14 14" version="1.1"
|
||||
<svg height="14px" version="1.1" viewBox="0 0 14 14" width="14px"
|
||||
xmlns="http://www.w3.org/2000/svg">
|
||||
<title>711C9D82-CAA8-47BE-954A-A9DA22CE85E6</title>
|
||||
<g id="Trash" stroke="none" stroke-width="1" fill="currentColor" fill-rule="evenodd">
|
||||
<g fill="currentColor" fill-rule="evenodd" id="Trash" stroke="none" stroke-width="1">
|
||||
<g id="05.-Trash-bulk-actions" transform="translate(-133.000000, -130.000000)">
|
||||
<g id="Group-36" transform="translate(0.000000, 112.000000)">
|
||||
<g id="Group-9" transform="translate(123.000000, 0.000000)">
|
||||
<g id="Group-21" transform="translate(0.000000, 8.000000)" fill="currentColor"
|
||||
fill-rule="nonzero">
|
||||
<g fill="currentColor" fill-rule="nonzero" id="Group-21"
|
||||
transform="translate(0.000000, 8.000000)">
|
||||
<g id="Put-back" transform="translate(10.000000, 10.000000)">
|
||||
<path
|
||||
d="M5,4.42 L3.8,4.42 L6.5,1.72 L5,0.42 L0,5.42 L5.1,10.52 L6.5,9.12 L3.8,6.42 L5,6.42 C8.9,6.42 12,9.52 12,13.42 L14,13.42 C14,8.52 10,4.42 5,4.42 Z"></path>
|
||||
|
||||
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
@ -1 +1,14 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 24 24" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><g><rect fill="none" height="24" width="24"/></g><g><g><path d="M15.82,7.22l-1,0.4c-0.21-0.16-0.43-0.29-0.67-0.39L14,6.17C13.98,6.07,13.9,6,13.8,6h-1.6c-0.1,0-0.18,0.07-0.19,0.17 l-0.15,1.06c-0.24,0.1-0.47,0.23-0.67,0.39l-1-0.4c-0.09-0.03-0.2,0-0.24,0.09l-0.8,1.38c-0.05,0.09-0.03,0.2,0.05,0.26l0.85,0.66 C10.02,9.73,10,9.87,10,10c0,0.13,0.01,0.26,0.03,0.39l-0.84,0.66c-0.08,0.06-0.1,0.17-0.05,0.25l0.8,1.39 c0.05,0.09,0.15,0.12,0.25,0.09l0.99-0.4c0.21,0.16,0.43,0.29,0.68,0.39L12,13.83c0.02,0.1,0.1,0.17,0.2,0.17h1.6 c0.1,0,0.18-0.07,0.2-0.17l0.15-1.06c0.24-0.1,0.47-0.23,0.67-0.39l0.99,0.4c0.09,0.04,0.2,0,0.24-0.09l0.8-1.39 c0.05-0.09,0.03-0.19-0.05-0.25l-0.83-0.66C15.99,10.26,16,10.13,16,10c0-0.14-0.01-0.27-0.03-0.39l0.85-0.66 c0.08-0.06,0.1-0.17,0.05-0.26l-0.8-1.38C16.02,7.22,15.91,7.19,15.82,7.22z M13,11.43c-0.79,0-1.43-0.64-1.43-1.43 S12.21,8.57,13,8.57s1.43,0.64,1.43,1.43S13.79,11.43,13,11.43z"/><path d="M19.94,9.06c-0.43-3.27-3.23-5.86-6.53-6.05C13.27,3,13.14,3,13,3C9.47,3,6.57,5.61,6.08,9l-1.93,3.48 C3.74,13.14,4.22,14,5,14h1v2c0,1.1,0.9,2,2,2h1v3h7v-4.68C18.62,15.07,20.35,12.24,19.94,9.06z M14.89,14.63L14,15.05V19h-3v-3H8 v-4H6.7l1.33-2.33C8.21,7.06,10.35,5,13,5c2.76,0,5,2.24,5,5C18,12.09,16.71,13.88,14.89,14.63z"/></g></g></svg>
|
||||
<svg enable-background="new 0 0 24 24" fill="#000000" height="24px"
|
||||
viewBox="0 0 24 24" width="24px" xmlns="http://www.w3.org/2000/svg">
|
||||
<g>
|
||||
<rect fill="none" height="24" width="24" />
|
||||
</g>
|
||||
<g>
|
||||
<g>
|
||||
<path
|
||||
d="M15.82,7.22l-1,0.4c-0.21-0.16-0.43-0.29-0.67-0.39L14,6.17C13.98,6.07,13.9,6,13.8,6h-1.6c-0.1,0-0.18,0.07-0.19,0.17 l-0.15,1.06c-0.24,0.1-0.47,0.23-0.67,0.39l-1-0.4c-0.09-0.03-0.2,0-0.24,0.09l-0.8,1.38c-0.05,0.09-0.03,0.2,0.05,0.26l0.85,0.66 C10.02,9.73,10,9.87,10,10c0,0.13,0.01,0.26,0.03,0.39l-0.84,0.66c-0.08,0.06-0.1,0.17-0.05,0.25l0.8,1.39 c0.05,0.09,0.15,0.12,0.25,0.09l0.99-0.4c0.21,0.16,0.43,0.29,0.68,0.39L12,13.83c0.02,0.1,0.1,0.17,0.2,0.17h1.6 c0.1,0,0.18-0.07,0.2-0.17l0.15-1.06c0.24-0.1,0.47-0.23,0.67-0.39l0.99,0.4c0.09,0.04,0.2,0,0.24-0.09l0.8-1.39 c0.05-0.09,0.03-0.19-0.05-0.25l-0.83-0.66C15.99,10.26,16,10.13,16,10c0-0.14-0.01-0.27-0.03-0.39l0.85-0.66 c0.08-0.06,0.1-0.17,0.05-0.26l-0.8-1.38C16.02,7.22,15.91,7.19,15.82,7.22z M13,11.43c-0.79,0-1.43-0.64-1.43-1.43 S12.21,8.57,13,8.57s1.43,0.64,1.43,1.43S13.79,11.43,13,11.43z" />
|
||||
<path
|
||||
d="M19.94,9.06c-0.43-3.27-3.23-5.86-6.53-6.05C13.27,3,13.14,3,13,3C9.47,3,6.57,5.61,6.08,9l-1.93,3.48 C3.74,13.14,4.22,14,5,14h1v2c0,1.1,0.9,2,2,2h1v3h7v-4.68C18.62,15.07,20.35,12.24,19.94,9.06z M14.89,14.63L14,15.05V19h-3v-3H8 v-4H6.7l1.33-2.33C8.21,7.06,10.35,5,13,5c2.76,0,5,2.24,5,5C18,12.09,16.71,13.88,14.89,14.63z" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.5 KiB |
@ -43,6 +43,7 @@
|
||||
-khtml-user-select: none; /* Konqueror HTML */
|
||||
-moz-user-select: none; /* Old versions of Firefox */
|
||||
-ms-user-select: none; /* Internet Explorer/Edge */
|
||||
user-select: none; /* Non-prefixed version, currently
|
||||
supported by Chrome, Edge, Opera and Firefox */
|
||||
user-select: none;
|
||||
/* Non-prefixed version, currently
|
||||
supported by Chrome, Edge, Opera and Firefox */
|
||||
}
|
||||
|
||||