+
-
+
{{ file.filename }}
@@ -13,5 +13,29 @@
-
+
+ {{ file.fileAttributes.attributeIdToValue[config.id] || '-' }}
+
+
+
+
+
diff --git a/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/components/workflow-item/workflow-item.component.scss b/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/components/workflow-item/workflow-item.component.scss
index 75bdb518a..9468a2610 100644
--- a/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/components/workflow-item/workflow-item.component.scss
+++ b/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/components/workflow-item/workflow-item.component.scss
@@ -1,34 +1,60 @@
@use 'common-mixins';
.workflow-item {
- padding: 10px;
+ padding: 10px 10px 8px 10px;
- > div {
- display: flex;
- justify-content: space-between;
-
- .details {
- max-width: calc(100% - 28px);
-
- .filename {
- font-weight: 600;
- line-height: 18px;
- @include common-mixins.line-clamp(1);
- }
- }
-
- .user {
- display: flex;
- align-items: flex-end;
- }
- }
-
- redaction-file-actions {
- margin-top: 10px;
- display: none;
+ &:hover .filename {
+ text-decoration: underline;
}
&:hover redaction-file-actions {
- display: block;
+ display: initial;
}
}
+
+.details-wrapper {
+ display: flex;
+ justify-content: space-between;
+
+ .details {
+ max-width: calc(100% - 28px);
+
+ .filename {
+ font-weight: 600;
+ line-height: 18px;
+ @include common-mixins.line-clamp(1);
+ }
+ }
+
+ .user {
+ display: flex;
+ align-items: flex-end;
+ }
+}
+
+redaction-file-workload {
+ margin-top: 10px;
+ display: block;
+ min-height: 16px;
+}
+
+.file-actions {
+ margin-top: 8px;
+ min-height: 34px;
+ overflow: hidden;
+ align-items: center;
+ display: flex;
+}
+
+.actions-wrapper {
+ overflow: hidden;
+ flex: 1;
+}
+
+redaction-file-actions:not(.keep-visible) {
+ display: none;
+}
+
+.mt-4 {
+ margin-top: 4px;
+}
diff --git a/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/components/workflow-item/workflow-item.component.ts b/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/components/workflow-item/workflow-item.component.ts
index fffcf980d..7c3916b84 100644
--- a/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/components/workflow-item/workflow-item.component.ts
+++ b/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/components/workflow-item/workflow-item.component.ts
@@ -1,5 +1,6 @@
-import { ChangeDetectionStrategy, Component, Input } from '@angular/core';
-import { File } from '@red/domain';
+import { ChangeDetectionStrategy, ChangeDetectorRef, Component, ElementRef, Input, OnInit, ViewChild } from '@angular/core';
+import { File, IFileAttributeConfig } from '@red/domain';
+import { Debounce, Required } from '@iqser/common-ui';
@Component({
selector: 'redaction-workflow-item',
@@ -7,6 +8,25 @@ import { File } from '@red/domain';
styleUrls: ['./workflow-item.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush,
})
-export class WorkflowItemComponent {
- @Input() file: File;
+export class WorkflowItemComponent implements OnInit {
+ @Input() @Required() file!: File;
+ @Input() @Required() displayedAttributes!: IFileAttributeConfig[];
+ width: number;
+
+ @ViewChild('actionsWrapper', { static: true }) private _actionsWrapper: ElementRef;
+
+ constructor(private readonly _changeRef: ChangeDetectorRef) {}
+
+ ngOnInit(): void {
+ const _observer = new ResizeObserver((entries: ResizeObserverEntry[]) => {
+ this._updateItemWidth(entries[0]);
+ });
+ _observer.observe(this._actionsWrapper.nativeElement);
+ }
+
+ @Debounce(30)
+ private _updateItemWidth(entry: ResizeObserverEntry): void {
+ this.width = entry.contentRect.width;
+ this._changeRef.detectChanges();
+ }
}
diff --git a/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/config.service.ts b/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/config.service.ts
index 135fa3130..77a6b107e 100644
--- a/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/config.service.ts
+++ b/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/config.service.ts
@@ -7,14 +7,12 @@ import {
List,
ListingMode,
ListingModes,
- LoadingService,
NestedFilter,
TableColumnConfig,
WorkflowConfig,
} from '@iqser/common-ui';
import { File, IFileAttributeConfig, StatusSorter, WorkflowFileStatus, WorkflowFileStatuses } from '@red/domain';
import { workflowFileStatusTranslations } from '../../translations/file-status-translations';
-import { FileAssignService } from '../../shared/services/file-assign.service';
import { PermissionsService } from '@services/permissions.service';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { TranslateService } from '@ngx-translate/core';
@@ -24,9 +22,9 @@ import { annotationFilterChecker, RedactionFilterSorter } from '@utils/index';
import { workloadTranslations } from '../../translations/workload-translations';
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';
+import noop from 'lodash/noop';
+import { BulkActionsService } from './services/bulk-actions.service';
@Injectable()
export class ConfigService {
@@ -34,15 +32,12 @@ export class ConfigService {
private readonly _listingMode$ = new BehaviorSubject
(ListingModes.table);
constructor(
- private readonly _fileAssignService: FileAssignService,
- private readonly _filesService: FilesService,
- private readonly _loadingService: LoadingService,
- private readonly _dossiersService: DossiersService,
private readonly _permissionsService: PermissionsService,
private readonly _translateService: TranslateService,
private readonly _userService: UserService,
private readonly _dialogService: DossiersDialogService,
private readonly _appConfigService: AppConfigService,
+ private readonly _bulkActionsService: BulkActionsService,
) {
this.listingMode$ = this._listingMode$.asObservable();
}
@@ -63,34 +58,45 @@ export class ConfigService {
{
label: workflowFileStatusTranslations[WorkflowFileStatuses.NEW],
key: WorkflowFileStatuses.NEW,
- enterFn: this._unassignFn,
- enterPredicate: (file: File) => this._permissionsService.canUnassignUser(file),
+ enterFn: noop,
+ enterPredicate: () => false,
color: '#D3D5DA',
+ entities: new BehaviorSubject([]),
},
{
label: workflowFileStatusTranslations[WorkflowFileStatuses.UNDER_REVIEW],
- enterFn: this._underReviewFn,
- enterPredicate: (file: File) =>
- this._permissionsService.canSetUnderReview(file) ||
- this._permissionsService.canAssignToSelf(file) ||
- this._permissionsService.canAssignUser(file),
+ enterFn: async (files: File[]) => {
+ if (files[0].workflowStatus === WorkflowFileStatuses.UNDER_APPROVAL) {
+ await this._bulkActionsService.backToUnderReview(files);
+ } else {
+ await this._bulkActionsService.assignToMe(files);
+ }
+ },
+ enterPredicate: (files: File[]) =>
+ this._permissionsService.canSetUnderReview(files) ||
+ this._permissionsService.canAssignToSelf(files) ||
+ this._permissionsService.canAssignUser(files),
key: WorkflowFileStatuses.UNDER_REVIEW,
color: '#FDBD00',
+ entities: new BehaviorSubject([]),
},
{
label: workflowFileStatusTranslations[WorkflowFileStatuses.UNDER_APPROVAL],
- enterFn: this._underApprovalFn,
- enterPredicate: (file: File) =>
- this._permissionsService.canSetUnderApproval(file) || this._permissionsService.canUndoApproval(file),
+ enterFn: (files: File[]) => this._bulkActionsService.setToUnderApproval(files),
+ enterPredicate: (files: File[]) =>
+ this._permissionsService.canSetUnderApproval(files) || this._permissionsService.canUndoApproval(files),
key: WorkflowFileStatuses.UNDER_APPROVAL,
color: '#374C81',
+ entities: new BehaviorSubject([]),
},
{
label: workflowFileStatusTranslations[WorkflowFileStatuses.APPROVED],
- enterFn: this._approveFn,
- enterPredicate: (file: File) => this._permissionsService.isReadyForApproval(file) && file.canBeApproved,
+ enterFn: (files: File[]) => this._bulkActionsService.approve(files),
+ enterPredicate: (files: File[]) =>
+ this._permissionsService.isReadyForApproval(files) && this._permissionsService.canBeApproved(files),
key: WorkflowFileStatuses.APPROVED,
color: '#48C9F7',
+ entities: new BehaviorSubject([]),
},
],
};
@@ -323,7 +329,7 @@ export class ConfigService {
_unassignedChecker = (file: File) => !file.assignee;
- _assignedToOthersChecker = (file: File) => !file.isNew && file.assignee !== this._userService.currentUser.id;
+ _assignedToOthersChecker = (file: File) => file.assignee && file.assignee !== this._userService.currentUser.id;
private _quickFilters(entities: File[]): NestedFilter[] {
const recentPeriod = this._appConfigService.values.RECENT_PERIOD_IN_HOURS;
@@ -361,31 +367,4 @@ export class ConfigService {
private _openEditDossierDialog($event: MouseEvent, dossierId: string) {
this._dialogService.openDialog('editDossier', $event, { dossierId });
}
-
- private _unassignFn = async (file: File) => {
- this._loadingService.start();
- await this._filesService.setUnassigned([file.fileId], file.dossierId).toPromise();
- this._loadingService.stop();
- };
-
- private _underReviewFn = async (file: File) => {
- await this._fileAssignService.assignReviewer(null, file, true);
- };
-
- private _underApprovalFn = async (file: File) => {
- const dossier = this._dossiersService.find(file.dossierId);
- if (dossier.approverIds.length > 1) {
- await this._fileAssignService.assignApprover(null, file, true);
- } else {
- this._loadingService.start();
- await this._filesService.setUnderApprovalFor([file.id], dossier.dossierId, dossier.approverIds[0]).toPromise();
- this._loadingService.stop();
- }
- };
-
- private _approveFn = async (file: File) => {
- this._loadingService.start();
- await this._filesService.setApprovedFor([file.id], file.dossierId).toPromise();
- this._loadingService.stop();
- };
}
diff --git a/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/dossier-overview.module.ts b/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/dossier-overview.module.ts
index 3d7b9fb5c..57f081d3b 100644
--- a/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/dossier-overview.module.ts
+++ b/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/dossier-overview.module.ts
@@ -11,13 +11,14 @@ import { DossierDetailsStatsComponent } from './components/dossier-details-stats
import { TableItemComponent } from './components/table-item/table-item.component';
import { ConfigService } from './config.service';
import { SharedDossiersModule } from '../../shared/shared-dossiers.module';
-import { FileWorkloadColumnComponent } from './components/table-item/file-workload-column/file-workload-column.component';
+import { FileWorkloadComponent } from './components/table-item/file-workload/file-workload.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';
import { FileNameColumnComponent } from './components/table-item/file-name-column/file-name-column.component';
import { AddedColumnComponent } from './components/table-item/added-column/added-column.component';
+import { BulkActionsService } from './services/bulk-actions.service';
const routes: Routes = [
{
@@ -36,7 +37,7 @@ const routes: Routes = [
DossierOverviewBulkActionsComponent,
DossierDetailsComponent,
DossierDetailsStatsComponent,
- FileWorkloadColumnComponent,
+ FileWorkloadComponent,
TableItemComponent,
FileStatsComponent,
WorkflowItemComponent,
@@ -45,7 +46,7 @@ const routes: Routes = [
FileNameColumnComponent,
AddedColumnComponent,
],
- providers: [ConfigService],
+ providers: [ConfigService, BulkActionsService],
imports: [RouterModule.forChild(routes), CommonModule, SharedModule, SharedDossiersModule, IqserIconsModule, TranslateModule],
})
export class DossierOverviewModule {}
diff --git a/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/screen/dossier-overview-screen.component.html b/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/screen/dossier-overview-screen.component.html
index 39fdceef3..1010b0c02 100644
--- a/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/screen/dossier-overview-screen.component.html
+++ b/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/screen/dossier-overview-screen.component.html
@@ -32,16 +32,16 @@
(noDataAction)="fileInput.click()"
*ngIf="mode === listingModes.workflow"
[addElementIcon]="'iqser:upload'"
+ [bulkActions]="bulkActions"
[config]="workflowConfig"
[itemClasses]="{ disabled: disabledFn }"
- [itemHeight]="'56px'"
[itemTemplate]="workflowItemTemplate"
[noDataButtonIcon]="'iqser:upload'"
[noDataButtonLabel]="'dossier-overview.no-data.action' | translate"
[noDataIcon]="'iqser:document'"
[noDataText]="'dossier-overview.no-data.title' | translate"
[showNoDataButton]="true"
- addElementColumn="UNASSIGNED"
+ addElementColumn="NEW"
>