dossier overview refactor

This commit is contained in:
Dan Percic 2021-11-16 18:59:57 +02:00
parent 1ce531c371
commit 164481ceca
17 changed files with 238 additions and 193 deletions

View File

@ -129,7 +129,6 @@ export class DossierOverviewBulkActionsComponent {
this.dossier.dossierId,
)
.toPromise();
await this._appStateService.reloadActiveDossierFiles();
this.reload.emit();
this._loadingService.stop();
},

View File

@ -0,0 +1,43 @@
<iqser-page-header
(closeAction)="routerHistoryService.navigateToLastDossiersScreen()"
[actionConfigs]="actionConfigs"
[helpModeKey]="'filter-document-list'"
[showCloseButton]="true"
[viewModeSelection]="viewModeSelection"
>
<redaction-file-download-btn
[dossier]="dossier"
[files]="entitiesService.all$ | async"
tooltipPosition="below"
></redaction-file-download-btn>
<iqser-circle-button
(action)="exportFilesAsCSV()"
[tooltip]="'dossier-overview.header-actions.download-csv' | translate"
icon="iqser:csv"
tooltipPosition="below"
></iqser-circle-button>
<iqser-circle-button
(action)="reanalyseDossier()"
*ngIf="permissionsService.displayReanalyseBtn(dossier) && analysisForced"
[tooltipClass]="'small ' + ((listingService.areSomeSelected$ | async) ? '' : 'warn')"
[tooltip]="'dossier-overview.new-rule.toast.actions.reanalyse-all' | translate"
[type]="circleButtonTypes.warn"
icon="iqser:refresh"
tooltipPosition="below"
></iqser-circle-button>
<iqser-circle-button
(action)="actionPerformed.emit('upload')"
[tooltip]="'dossier-overview.header-actions.upload-document' | translate"
[type]="circleButtonTypes.primary"
class="ml-14"
icon="iqser:upload"
tooltipPosition="below"
></iqser-circle-button>
</iqser-page-header>
<ng-template #viewModeSelection>
<redaction-view-mode-selection></redaction-view-mode-selection>
</ng-template>

View File

@ -0,0 +1,82 @@
import { ChangeDetectionStrategy, Component, EventEmitter, Input, OnInit, Output, TemplateRef } from '@angular/core';
import { RouterHistoryService } from '@services/router-history.service';
import { ActionConfig, CircleButtonTypes, EntitiesService, List, ListingService, SortingService, Toaster } from '@iqser/common-ui';
import { Dossier, File } from '@red/domain';
import { PermissionsService } from '@services/permissions.service';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { ReanalysisService } from '@services/reanalysis.service';
import { map, take } from 'rxjs/operators';
import { saveAsCSV } from '@utils/csv-utils';
import { UserService } from '@services/user.service';
import { ConfigService } from '../../config.service';
@Component({
selector: 'redaction-screen-header',
templateUrl: './screen-header.component.html',
styleUrls: ['./screen-header.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class ScreenHeaderComponent implements OnInit {
@Input() viewModeSelection: TemplateRef<any>;
@Input() dossier: Dossier;
@Input() analysisForced: boolean;
@Output() readonly actionPerformed = new EventEmitter<string>();
readonly circleButtonTypes = CircleButtonTypes;
actionConfigs: List<ActionConfig>;
constructor(
private readonly _toaster: Toaster,
readonly configService: ConfigService,
private readonly _userService: UserService,
readonly listingService: ListingService<File>,
readonly sortingService: SortingService<File>,
readonly permissionsService: PermissionsService,
readonly entitiesService: EntitiesService<File>,
readonly routerHistoryService: RouterHistoryService,
private readonly _reanalysisService: ReanalysisService,
) {}
ngOnInit() {
this.actionConfigs = this.configService.actionConfig(this.dossier.dossierId);
}
async reanalyseDossier() {
try {
await this._reanalysisService.reanalyzeDossier(this.dossier.dossierId, true).toPromise();
this.actionPerformed.emit('reload');
this._toaster.success(_('dossier-overview.reanalyse-dossier.success'));
} catch (e) {
this._toaster.error(_('dossier-overview.reanalyse-dossier.error'));
}
}
exportFilesAsCSV() {
const sortedEntities$ = this.listingService.displayed$.pipe(map(entities => this.sortingService.defaultSort(entities)));
sortedEntities$.pipe(take(1)).subscribe(entities => {
const fileName = this.dossier.dossierName + '.export.csv';
saveAsCSV(
fileName,
entities,
[
'dossierId',
'fileId',
'filename',
'primaryAttribute',
'numberOfPages',
'assignee',
'workflowStatus',
'processingStatus',
'lastUpdated',
'lastUploaded',
'lastProcessed',
'hasHints',
'hasImages',
'hasRedactions',
'hasUpdates',
'excluded',
],
fsv => ({ ...fsv, assignee: this._userService.getNameForId(fsv.currentReviewer) }),
);
});
}
}

View File

@ -66,6 +66,7 @@
]"
></iqser-status-bar>
</div>
<redaction-file-actions
(actionPerformed)="calculateData.emit($event)"
*ngIf="!file.isProcessing"

View File

@ -0,0 +1,19 @@
<div *ngIf="configService.listingMode$ | async as mode" class="view-mode-selection">
<div class="all-caps-label" translate="view-mode.view-as"></div>
<iqser-circle-button
(action)="configService.listingMode = listingModes.table"
[attr.aria-expanded]="mode === listingModes.table"
[tooltip]="'view-mode.list' | translate"
[type]="circleButtonTypes.dossierView"
icon="iqser:list"
></iqser-circle-button>
<iqser-circle-button
(action)="configService.listingMode = listingModes.workflow"
[attr.aria-expanded]="mode === listingModes.workflow"
[tooltip]="'view-mode.workflow' | translate"
[type]="circleButtonTypes.dossierView"
icon="iqser:lanes"
></iqser-circle-button>
</div>

View File

@ -0,0 +1,17 @@
@use 'apps/red-ui/src/assets/styles/variables';
.view-mode-selection {
border-right: 1px solid variables.$separator;
padding-right: 16px;
margin-right: 16px !important;
display: flex;
align-items: center;
> iqser-circle-button:not(:last-child) {
margin-right: 2px;
}
> div {
margin-right: 8px;
}
}

View File

@ -0,0 +1,16 @@
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { ConfigService } from '../../config.service';
import { CircleButtonTypes, ListingModes } from '@iqser/common-ui';
@Component({
selector: 'redaction-view-mode-selection',
templateUrl: './view-mode-selection.component.html',
styleUrls: ['./view-mode-selection.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class ViewModeSelectionComponent {
readonly listingModes = ListingModes;
readonly circleButtonTypes = CircleButtonTypes;
constructor(readonly configService: ConfigService) {}
}

View File

@ -27,9 +27,13 @@ import * as moment from 'moment';
import { ConfigService as AppConfigService } from '@services/config.service';
import { DossiersService } from '@services/entity-services/dossiers.service';
import { FilesService } from '@services/entity-services/files.service';
import { BehaviorSubject, Observable } from 'rxjs';
@Injectable()
export class ConfigService {
readonly listingMode$: Observable<ListingMode>;
private readonly _listingMode$ = new BehaviorSubject<ListingMode>(ListingModes.table);
constructor(
private readonly _fileActionService: FileActionService,
private readonly _filesService: FilesService,
@ -41,7 +45,17 @@ export class ConfigService {
private readonly _userService: UserService,
private readonly _dialogService: DossiersDialogService,
private readonly _appConfigService: AppConfigService,
) {}
) {
this.listingMode$ = this._listingMode$.asObservable();
}
get listingMode(): ListingMode {
return this._listingMode$.value;
}
set listingMode(listingMode: ListingMode) {
this._listingMode$.next(listingMode);
}
actionConfig(dossierId: string): List<ActionConfig> {
return [
@ -135,7 +149,6 @@ export class ConfigService {
filterGroups(
entities: File[],
listingMode: ListingMode,
fileAttributeConfigs: IFileAttributeConfig[],
needsWorkFilterTemplate: TemplateRef<unknown>,
checkedRequiredFilters: () => NestedFilter[],
@ -195,7 +208,7 @@ export class ConfigService {
});
});
if (listingMode === ListingModes.table) {
if (this.listingMode === ListingModes.table) {
const statusFilters = [...allDistinctWorkflowFileStatuses].map(
status =>
new NestedFilter({

View File

@ -14,6 +14,8 @@ import { SharedDossiersModule } from '../../shared/shared-dossiers.module';
import { FileWorkloadColumnComponent } from './components/file-workload-column/file-workload-column.component';
import { FileStatsComponent } from './components/file-stats/file-stats.component';
import { WorkflowItemComponent } from './components/workflow-item/workflow-item.component';
import { ScreenHeaderComponent } from './components/screen-header/screen-header.component';
import { ViewModeSelectionComponent } from './components/view-mode-selection/view-mode-selection.component';
const routes = [
{
@ -33,6 +35,8 @@ const routes = [
TableItemComponent,
FileStatsComponent,
WorkflowItemComponent,
ScreenHeaderComponent,
ViewModeSelectionComponent,
],
providers: [ConfigService],
imports: [RouterModule.forChild(routes), CommonModule, SharedModule, SharedDossiersModule, IqserIconsModule, TranslateModule],

View File

@ -1,49 +1,15 @@
<ng-container *ngIf="dossier$ | async as dossier">
<section (longPress)="forceReanalysisAction($event)" redactionLongPress>
<iqser-page-header
(closeAction)="routerHistoryService.navigateToLastDossiersScreen()"
[actionConfigs]="actionConfigs"
[showCloseButton]="true"
[viewModeSelection]="viewModeSelection"
[helpModeKey]="'filter-document-list'"
>
<redaction-file-download-btn
[dossier]="dossier"
[files]="entitiesService.all$ | async"
tooltipPosition="below"
></redaction-file-download-btn>
<iqser-circle-button
(action)="exportFilesAsCSV()"
[tooltip]="'dossier-overview.header-actions.download-csv' | translate"
icon="iqser:csv"
tooltipPosition="below"
></iqser-circle-button>
<iqser-circle-button
(action)="reanalyseDossier()"
*ngIf="permissionsService.displayReanalyseBtn(dossier) && analysisForced"
[tooltipClass]="'small ' + ((listingService.areSomeSelected$ | async) ? '' : 'warn')"
[tooltip]="'dossier-overview.new-rule.toast.actions.reanalyse-all' | translate"
[type]="circleButtonTypes.warn"
icon="iqser:refresh"
tooltipPosition="below"
></iqser-circle-button>
<iqser-circle-button
(action)="fileInput.click()"
[tooltip]="'dossier-overview.header-actions.upload-document' | translate"
[type]="circleButtonTypes.primary"
class="ml-14"
icon="iqser:upload"
tooltipPosition="below"
></iqser-circle-button>
</iqser-page-header>
<redaction-screen-header
(actionPerformed)="actionPerformed($event)"
[analysisForced]="analysisForced"
[dossier]="dossier"
></redaction-screen-header>
<div class="overlay-shadow"></div>
<div class="content-inner">
<div *ngIf="listingMode$ | async as mode" [class.extended]="collapsedDetails" class="content-container">
<div *ngIf="configService.listingMode$ | async as mode" [class.extended]="collapsedDetails" class="content-container">
<iqser-table
(noDataAction)="fileInput.click()"
*ngIf="mode === listingModes.table"
@ -82,7 +48,7 @@
<redaction-dossier-details
(openAssignDossierMembersDialog)="openAssignDossierMembersDialog()"
(openDossierDictionaryDialog)="openDossierDictionaryDialog()"
(toggleCollapse)="toggleCollapsedDetails()"
(toggleCollapse)="collapsedDetails = !collapsedDetails"
[dossierAttributes]="dossierAttributes"
></redaction-dossier-details>
</div>
@ -100,27 +66,6 @@
<input #fileInput (change)="uploadFiles($event.target['files'])" class="file-upload-input" multiple="true" type="file" />
<ng-template #viewModeSelection>
<div *ngIf="listingMode$ | async as mode" class="view-mode-selection">
<div class="all-caps-label" translate="view-mode.view-as"></div>
<iqser-circle-button
(action)="listingMode = listingModes.table"
[attr.aria-expanded]="mode === listingModes.table"
[tooltip]="'view-mode.list' | translate"
[type]="circleButtonTypes.dossierView"
icon="iqser:list"
></iqser-circle-button>
<iqser-circle-button
(action)="listingMode = listingModes.workflow"
[attr.aria-expanded]="mode === listingModes.workflow"
[tooltip]="'view-mode.workflow' | translate"
[type]="circleButtonTypes.dossierView"
icon="iqser:lanes"
></iqser-circle-button>
</div>
</ng-template>
<ng-template #tableItemTemplate let-file="entity">
<redaction-table-item
(calculateData)="actionPerformed($event)"

View File

@ -43,19 +43,3 @@
background-color: inherit;
}
}
.view-mode-selection {
border-right: 1px solid variables.$separator;
padding-right: 16px;
margin-right: 16px !important;
display: flex;
align-items: center;
> iqser-circle-button:not(:last-child) {
margin-right: 2px;
}
> div {
margin-right: 8px;
}
}

View File

@ -17,13 +17,11 @@ import { FileUploadModel } from '@upload-download/model/file-upload.model';
import { FileUploadService } from '@upload-download/services/file-upload.service';
import { StatusOverlayService } from '@upload-download/services/status-overlay.service';
import * as moment from 'moment';
import { UserService } from '@services/user.service';
import { Observable, timer } from 'rxjs';
import { switchMap, take, tap, withLatestFrom } from 'rxjs/operators';
import { switchMap, tap } from 'rxjs/operators';
import { convertFiles, Files, handleFileDrop } from '@utils/index';
import { DossiersDialogService } from '../../../services/dossiers-dialog.service';
import {
ActionConfig,
CircleButtonTypes,
DefaultListingServices,
ListingComponent,
@ -34,13 +32,11 @@ import {
OnDetach,
TableColumnConfig,
TableComponent,
Toaster,
WorkflowConfig,
} from '@iqser/common-ui';
import { DossierAttributesService } from '@shared/services/controller-wrappers/dossier-attributes.service';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { PermissionsService } from '@services/permissions.service';
import { RouterHistoryService } from '@services/router-history.service';
import { ActivatedRoute, Router } from '@angular/router';
import { FileAttributesService } from '@services/entity-services/file-attributes.service';
import { ConfigService as AppConfigService } from '@services/config.service';
@ -49,9 +45,7 @@ import { DossiersService } from '@services/entity-services/dossiers.service';
import { DossierTemplatesService } from '@services/entity-services/dossier-templates.service';
import { LongPressEvent } from '@shared/directives/long-press.directive';
import { UserPreferenceService } from '@services/user-preference.service';
import { saveAsCSV } from '@utils/csv-utils';
import { FilesMapService } from '@services/entity-services/files-map.service';
import { ReanalysisService } from '@services/reanalysis.service';
import { DossierStatsService } from '@services/entity-services/dossier-stats.service';
@Component({
@ -63,7 +57,6 @@ import { DossierStatsService } from '@services/entity-services/dossier-stats.ser
export class DossierOverviewScreenComponent extends ListingComponent<File> implements OnInit, OnDestroy, OnDetach, OnAttach {
readonly listingModes = ListingModes;
readonly circleButtonTypes = CircleButtonTypes;
readonly currentUser = this._userService.currentUser;
readonly tableHeaderLabel = _('dossier-overview.table-header.title');
collapsedDetails = false;
@ -72,29 +65,24 @@ export class DossierOverviewScreenComponent extends ListingComponent<File> imple
analysisForced: boolean;
displayedInFileListAttributes: IFileAttributeConfig[] = [];
displayedAttributes: IFileAttributeConfig[] = [];
readonly workflowConfig: WorkflowConfig<File, WorkflowFileStatus> = this._configService.workflowConfig(() => this.reloadFiles());
readonly actionConfigs: readonly ActionConfig[];
readonly workflowConfig: WorkflowConfig<File, WorkflowFileStatus> = this.configService.workflowConfig(() => this.reloadFiles());
readonly dossier$: Observable<Dossier>;
readonly dossierId: string;
currentDossier: Dossier;
private _lastScrolledIndex: number;
@ViewChild('needsWorkFilterTemplate', { read: TemplateRef, static: true })
private readonly _needsWorkFilterTemplate: TemplateRef<unknown>;
@ViewChild('fileInput') private readonly _fileInput: ElementRef;
@ViewChild('fileInput', { static: true }) private readonly _fileInput: ElementRef;
@ViewChild(TableComponent) private readonly _tableComponent: TableComponent<Dossier>;
constructor(
private readonly _toaster: Toaster,
protected readonly _injector: Injector,
private readonly _router: Router,
private readonly _userService: UserService,
readonly permissionsService: PermissionsService,
private readonly _loadingService: LoadingService,
private readonly _appStateService: AppStateService,
private readonly _reanalysisService: ReanalysisService,
private readonly _dossiersService: DossiersService,
private readonly _dossierTemplatesService: DossierTemplatesService,
readonly routerHistoryService: RouterHistoryService,
private readonly _appConfigService: AppConfigService,
private readonly _dialogService: DossiersDialogService,
private readonly _fileUploadService: FileUploadService,
@ -102,23 +90,21 @@ export class DossierOverviewScreenComponent extends ListingComponent<File> imple
private readonly _fileDropOverlayService: FileDropOverlayService,
private readonly _dossierAttributesService: DossierAttributesService,
private readonly _fileAttributesService: FileAttributesService,
private readonly _configService: ConfigService,
readonly configService: ConfigService,
private readonly _userPreferenceService: UserPreferenceService,
private readonly _fileMapService: FilesMapService,
private readonly _dossierStatsService: DossierStatsService,
activatedRoute: ActivatedRoute,
) {
super(_injector);
this._appStateService.reset();
this.dossierId = activatedRoute.snapshot.paramMap.get('dossierId');
this.actionConfigs = this._configService.actionConfig(this.dossierId);
this.dossier$ = this._dossiersService.getEntityChanged$(this.dossierId);
this.currentDossier = this._dossiersService.find(this.dossierId);
this.fileAttributeConfigs = this._fileAttributesService.getFileAttributeConfig(
this.currentDossier.dossierTemplateId,
)?.fileAttributeConfigs;
this.tableColumnConfigs = this._configService.tableConfig(this.displayedAttributes);
this.tableColumnConfigs = this.configService.tableConfig(this.displayedAttributes);
}
private _fileAttributeConfigs: IFileAttributeConfig[];
@ -138,10 +124,14 @@ export class DossierOverviewScreenComponent extends ListingComponent<File> imple
}
async actionPerformed(action?: string, file?: File) {
if (action === 'assign-reviewer') {
if (['assign-reviewer', 'reload'].includes(action)) {
return this.reloadFiles();
}
if (action === 'upload') {
return this._fileInput.nativeElement.click();
}
await this.calculateData();
if (action === 'navigate') {
@ -169,7 +159,7 @@ export class DossierOverviewScreenComponent extends ListingComponent<File> imple
.pipe(switchMap(() => this.reloadFiles()))
.subscribe();
this.addSubscription = this.listingMode$.subscribe(() => {
this.addSubscription = this.configService.listingMode$.subscribe(() => {
this._computeAllFilters();
});
@ -179,10 +169,6 @@ export class DossierOverviewScreenComponent extends ListingComponent<File> imple
)?.fileAttributeConfigs;
});
this.addSubscription = this._tableComponent.scrollViewport.scrolledIndexChange
.pipe(tap(index => (this._lastScrolledIndex = index)))
.subscribe();
try {
this.dossierAttributes = await this._dossierAttributesService.getWithValues(this.currentDossier);
} catch (e) {
@ -199,7 +185,7 @@ export class DossierOverviewScreenComponent extends ListingComponent<File> imple
async ngOnAttach() {
await this.ngOnInit();
this._tableComponent.scrollViewport.scrollToIndex(this._lastScrolledIndex, 'smooth');
this._tableComponent.tableContent.scrollToLastIndex();
}
ngOnDetach() {
@ -210,20 +196,9 @@ export class DossierOverviewScreenComponent extends ListingComponent<File> imple
this.analysisForced = !$event.touchEnd && this._userPreferenceService.areDevFeaturesEnabled;
}
async reanalyseDossier() {
try {
await this._reanalysisService.reanalyzeDossier(this.dossierId, true).toPromise();
await this.reloadFiles();
this._toaster.success(_('dossier-overview.reanalyse-dossier.success'));
} catch (e) {
this._toaster.error(_('dossier-overview.reanalyse-dossier.error'));
}
}
async reloadFiles() {
const files = await this._appStateService.getFiles(this.currentDossier);
await this._appStateService.getFiles(this.currentDossier);
await this._dossierStatsService.getFor([this.dossierId]).toPromise();
this.entitiesService.setEntities(files);
this._computeAllFilters();
}
@ -244,38 +219,9 @@ export class DossierOverviewScreenComponent extends ListingComponent<File> imple
event.preventDefault();
}
exportFilesAsCSV() {
this.sortedDisplayedEntities$.pipe(take(1), withLatestFrom(this.dossier$)).subscribe(([entities, dossier]) => {
const fileName = dossier.dossierName + '.export.csv';
saveAsCSV(
fileName,
entities,
[
'dossierId',
'fileId',
'filename',
'primaryAttribute',
'numberOfPages',
'assignee',
'workflowStatus',
'processingStatus',
'lastUpdated',
'lastUploaded',
'lastProcessed',
'hasHints',
'hasImages',
'hasRedactions',
'hasUpdates',
'excluded',
],
fsv => ({ ...fsv, assignee: this._userService.getNameForId(fsv.currentReviewer) }),
);
});
}
async uploadFiles(files: Files): Promise<void> {
await this._uploadFiles(convertFiles(files, this.currentDossier));
this._fileInput.nativeElement.value = null;
(this._fileInput as any).nativeElement.value = null;
}
openAssignDossierMembersDialog(): void {
@ -292,10 +238,6 @@ export class DossierOverviewScreenComponent extends ListingComponent<File> imple
});
}
toggleCollapsedDetails() {
this.collapsedDetails = !this.collapsedDetails;
}
recentlyModifiedChecker = (file: File) =>
moment(file.lastUpdated).add(this._appConfigService.values.RECENT_PERIOD_IN_HOURS, 'hours').isAfter(moment());
@ -315,9 +257,8 @@ export class DossierOverviewScreenComponent extends ListingComponent<File> imple
}
private _computeAllFilters() {
const filterGroups = this._configService.filterGroups(
const filterGroups = this.configService.filterGroups(
this.entitiesService.all,
this.listingMode,
this._fileAttributeConfigs,
this._needsWorkFilterTemplate,
() => this.checkedRequiredFilters,

View File

@ -1,21 +1,10 @@
import {
AfterViewInit,
ChangeDetectionStrategy,
Component,
forwardRef,
Injector,
OnDestroy,
OnInit,
TemplateRef,
ViewChild,
} from '@angular/core';
import { ChangeDetectionStrategy, Component, forwardRef, Injector, OnDestroy, OnInit, TemplateRef, ViewChild } from '@angular/core';
import { AppStateService } from '@state/app-state.service';
import { Dossier } from '@red/domain';
import { UserService } from '@services/user.service';
import { PermissionsService } from '@services/permissions.service';
import { TranslateChartService } from '@services/translate-chart.service';
import { timer } from 'rxjs';
import { tap } from 'rxjs/operators';
import { Router } from '@angular/router';
import { DossiersDialogService } from '../../../services/dossiers-dialog.service';
import { DefaultListingServicesTmp, EntitiesService, ListingComponent, OnAttach, OnDetach, TableComponent } from '@iqser/common-ui';
@ -34,15 +23,11 @@ import { FilesService } from '@services/entity-services/files.service';
],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class DossiersListingScreenComponent
extends ListingComponent<Dossier>
implements OnInit, AfterViewInit, OnDestroy, OnAttach, OnDetach
{
export class DossiersListingScreenComponent extends ListingComponent<Dossier> implements OnInit, OnDestroy, OnAttach, OnDetach {
readonly currentUser = this._userService.currentUser;
readonly tableColumnConfigs = this._configService.tableConfig;
readonly tableHeaderLabel = _('dossier-listing.table-header.title');
readonly buttonConfigs = this._configService.buttonsConfig(() => this.openAddDossierDialog());
private _lastScrolledIndex: number;
@ViewChild('needsWorkFilterTemplate', {
read: TemplateRef,
static: true,
@ -74,16 +59,9 @@ export class DossiersListingScreenComponent
});
}
ngAfterViewInit(): void {
this.addSubscription = this._tableComponent.scrollViewport.scrolledIndexChange
.pipe(tap(index => (this._lastScrolledIndex = index)))
.subscribe();
}
ngOnAttach(): void {
this.ngOnInit();
this.ngAfterViewInit();
this._tableComponent.scrollViewport.scrollToIndex(this._lastScrolledIndex, 'smooth');
this._tableComponent.tableContent.scrollToLastIndex();
}
ngOnDetach(): void {

View File

@ -1,10 +1,14 @@
<div *ngIf="isDossierOverviewList" class="action-buttons">
<ng-container *ngTemplateOutlet="actions"></ng-container>
<div *ngIf="showStatusBar && file.isProcessing" [matTooltip]="'file-status.processing' | translate" class="spinning"
matTooltipPosition="above">
<div
*ngIf="showStatusBar && file.isProcessing"
[matTooltip]="'file-status.processing' | translate"
class="spinning"
matTooltipPosition="above"
>
<mat-icon svgIcon="red:reanalyse"></mat-icon>
</div>
<iqser-status-bar *ngIf="showStatusBar" [configs]="statusBarConfig"></iqser-status-bar>
<iqser-status-bar *ngIf="showStatusBar" [configs]="[{ color: file.workflowStatus, length: 1 }]"></iqser-status-bar>
</div>
<ng-container *ngIf="isFilePreview || isDossierOverviewWorkflow">
@ -147,6 +151,7 @@
[type]="circleButtonTypes.dark"
icon="iqser:refresh"
></iqser-circle-button>
<!-- exclude from redaction -->
<div class="iqser-input-group">
<mat-slide-toggle

View File

@ -1,6 +1,6 @@
import { ChangeDetectionStrategy, Component, EventEmitter, Input, OnDestroy, OnInit, Output } from '@angular/core';
import { PermissionsService } from '@services/permissions.service';
import { Dossier, File, WorkflowFileStatus } from '@red/domain';
import { Dossier, File } from '@red/domain';
import { AppStateService } from '@state/app-state.service';
import { DossiersDialogService } from '../../../services/dossiers-dialog.service';
import {
@ -8,11 +8,9 @@ import {
CircleButtonType,
CircleButtonTypes,
ConfirmationDialogInput,
List,
LoadingService,
OnChange,
Required,
StatusBarConfig,
Toaster,
} from '@iqser/common-ui';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
@ -45,8 +43,6 @@ export class FileActionsComponent extends AutoUnsubscribe implements OnInit, OnD
@Output() readonly actionPerformed = new EventEmitter<string>();
dossier$: Observable<Dossier>;
statusBarConfig?: List<StatusBarConfig<WorkflowFileStatus>>;
tooltipPosition?: 'below' | 'above';
toggleTooltip?: string;
assignTooltip?: string;
buttonType?: CircleButtonType;
@ -95,6 +91,10 @@ export class FileActionsComponent extends AutoUnsubscribe implements OnInit, OnD
return this.type === 'file-preview';
}
get tooltipPosition() {
return this.isFilePreview ? 'below' : 'above';
}
get isDossierOverview(): boolean {
return this.type.startsWith('dossier-overview-list');
}
@ -234,8 +234,6 @@ export class FileActionsComponent extends AutoUnsubscribe implements OnInit, OnD
}
setup() {
this.statusBarConfig = [{ color: this.file.workflowStatus, length: 1 }];
this.tooltipPosition = this.isFilePreview ? 'below' : 'above';
this.assignTooltip = this.file.isUnderApproval ? _('dossier-overview.assign-approver') : _('dossier-overview.assign-reviewer');
this.buttonType = this.isFilePreview ? CircleButtonTypes.default : CircleButtonTypes.dark;
this.toggleTooltip = this._toggleTooltip;

@ -1 +1 @@
Subproject commit aa7926da8d93542ff0d0d93de5da4547db1e3cb1
Subproject commit 710d014455779412dc28b1b5bc34d96b3f0b27b3