-
+
+
{{ fileStatus.filename }}
-
+
{{ fileStatus.primaryAttribute }}
-
-
-
- {{ fileStatus.numberOfPages }}
-
-
-
- {{ fileStatus.excludedPagesCount }}
-
-
-
- {{ fileStatus.lastOCRTime | date: 'mediumDate' }}
-
-
+
@@ -167,10 +162,71 @@
>
+
+
+
+
+
+
+
+
+
+
+
+ {{ fileStatus.filename }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ fileStatus.numberOfPages }}
+
+
+
+ {{ fileStatus.excludedPagesCount }}
+
+
+
+ {{ fileStatus.lastOCRTime | date: 'mediumDate' }}
+
+
+
diff --git a/apps/red-ui/src/app/modules/dossier/screens/dossier-overview-screen/dossier-overview-screen.component.scss b/apps/red-ui/src/app/modules/dossier/screens/dossier-overview-screen/dossier-overview-screen.component.scss
index 5a0559734..6d9657552 100644
--- a/apps/red-ui/src/app/modules/dossier/screens/dossier-overview-screen/dossier-overview-screen.component.scss
+++ b/apps/red-ui/src/app/modules/dossier/screens/dossier-overview-screen/dossier-overview-screen.component.scss
@@ -1,4 +1,5 @@
@import '../../../../../assets/styles/variables';
+@import 'libs/common-ui/src/assets/styles/mixins';
.file-upload-input {
display: none;
@@ -27,6 +28,7 @@
.primary-attribute {
padding-top: 6px;
+ @include line-clamp(1);
}
&.extend-cols {
@@ -63,3 +65,55 @@
background-color: inherit;
}
}
+
+.view-mode-selection {
+ border-right: 1px solid $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;
+ }
+}
+
+.workflow-item {
+ padding: 10px;
+
+ > div {
+ display: flex;
+ justify-content: space-between;
+
+ .details {
+ max-width: calc(100% - 28px);
+
+ .filename {
+ font-weight: 600;
+ @include line-clamp(1);
+ }
+ }
+
+ .user {
+ display: flex;
+ align-items: flex-end;
+ }
+ }
+
+ redaction-file-actions {
+ margin-top: 10px;
+ display: none;
+ }
+
+ &:hover redaction-file-actions {
+ display: block;
+ }
+}
+
+.stats-subtitle {
+ margin-top: 4px;
+}
diff --git a/apps/red-ui/src/app/modules/dossier/screens/dossier-overview-screen/dossier-overview-screen.component.ts b/apps/red-ui/src/app/modules/dossier/screens/dossier-overview-screen/dossier-overview-screen.component.ts
index b42a66abc..e1e7b22e9 100644
--- a/apps/red-ui/src/app/modules/dossier/screens/dossier-overview-screen/dossier-overview-screen.component.ts
+++ b/apps/red-ui/src/app/modules/dossier/screens/dossier-overview-screen/dossier-overview-screen.component.ts
@@ -10,6 +10,7 @@ import {
TemplateRef,
ViewChild
} from '@angular/core';
+import { FileAttributeConfig, FileStatus } from '@redaction/red-ui-http';
import { AppStateService } from '@state/app-state.service';
import { FileDropOverlayService } from '@upload-download/services/file-drop-overlay.service';
import { FileUploadModel } from '@upload-download/model/file-upload.model';
@@ -34,11 +35,13 @@ import {
DefaultListingServices,
keyChecker,
ListingComponent,
+ ListingModes,
LoadingService,
NestedFilter,
TableColumnConfig,
TableComponent,
- Toaster
+ Toaster,
+ WorkflowConfig
} from '@iqser/common-ui';
import { DossierAttributesService } from '@shared/services/controller-wrappers/dossier-attributes.service';
import { DossierAttributeWithValue } from '@models/dossier-attributes.model';
@@ -49,8 +52,10 @@ import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { annotationFilterChecker } from '@utils/filter-utils';
import { PermissionsService } from '@services/permissions.service';
import { RouterHistoryService } from '@services/router-history.service';
-import { FileAttributeConfig } from '@redaction/red-ui-http';
import { DossierWrapper } from '../../../../state/model/dossier.wrapper';
+import { Router } from '@angular/router';
+import { FileActionService } from '../../services/file-action.service';
+import StatusEnum = FileStatus.StatusEnum;
@Component({
templateUrl: './dossier-overview-screen.component.html',
@@ -58,6 +63,7 @@ import { DossierWrapper } from '../../../../state/model/dossier.wrapper';
providers: [...DefaultListingServices, { provide: ListingComponent, useExisting: forwardRef(() => DossierOverviewScreenComponent) }]
})
export class DossierOverviewScreenComponent extends ListingComponent
implements OnInit, OnDestroy, OnDetach, OnAttach {
+ readonly listingModes = ListingModes;
readonly circleButtonTypes = CircleButtonTypes;
readonly currentUser = this._userService.currentUser;
currentDossier = this._appStateService.activeDossier;
@@ -81,6 +87,7 @@ export class DossierOverviewScreenComponent extends ListingComponent;
@ViewChild('pagesTemplate', { static: true }) pagesTemplate: TemplateRef;
@ViewChild('statusTemplate', { static: true }) statusTemplate: TemplateRef;
+ readonly workflowConfig: WorkflowConfig;
protected readonly _primaryKey = 'filename';
@ViewChild(DossierDetailsComponent, { static: false })
private readonly _dossierDetailsComponent: DossierDetailsComponent;
@@ -93,6 +100,7 @@ export class DossierOverviewScreenComponent extends ListingComponent !!entity,
+ color: '#D3D5DA'
+ },
+ {
+ label: fileStatusTranslations[StatusEnum.UNDERREVIEW],
+ enterFn: this.underReviewFn,
+ enterPredicate: (file: FileStatusWrapper) => this.permissionsService.canAssignUser(file),
+ key: StatusEnum.UNDERREVIEW,
+ color: '#FDBD00'
+ },
+ {
+ label: fileStatusTranslations[StatusEnum.UNDERAPPROVAL],
+ enterFn: this.underApprovalFn,
+ enterPredicate: (file: FileStatusWrapper) =>
+ this.permissionsService.canSetUnderApproval(file) || this.permissionsService.canUndoApproval(file),
+ key: StatusEnum.UNDERAPPROVAL,
+ color: '#374C81'
+ },
+ {
+ label: fileStatusTranslations[StatusEnum.APPROVED],
+ enterFn: this.approveFn,
+ enterPredicate: (file: FileStatusWrapper) => this.permissionsService.isReadyForApproval(file),
+ key: StatusEnum.APPROVED,
+ color: '#48C9F7'
+ }
+ ]
+ };
}
get checkedRequiredFilters() {
@@ -127,10 +171,46 @@ export class DossierOverviewScreenComponent extends ListingComponent config.displayedInFileList);
}
+ unassignFn = async (file: FileStatusWrapper) => {
+ // TODO
+ console.log('unassign', file);
+ };
+
+ underReviewFn = (file: FileStatusWrapper) => {
+ this._fileActionService.assignFile('reviewer', null, file, () => this._loadingService.loadWhile(this.reloadDossiers()), true);
+ };
+
+ underApprovalFn = async (file: FileStatusWrapper) => {
+ if (this._appStateService.activeDossier.approverIds.length > 1) {
+ this._fileActionService.assignFile('approver', null, file, () => this._loadingService.loadWhile(this.reloadDossiers()), true);
+ } else {
+ this._loadingService.start();
+ await this._fileActionService.setFileUnderApproval(file).toPromise();
+ await this.reloadDossiers();
+ this._loadingService.stop();
+ }
+ };
+
+ approveFn = async (file: FileStatusWrapper) => {
+ this._loadingService.start();
+ await this._fileActionService.setFileApproved(file).toPromise();
+ await this.reloadDossiers();
+ this._loadingService.stop();
+ };
+
+ actionPerformed(action?: string, fileStatus?: FileStatusWrapper) {
+ this._calculateData();
+
+ if (action === 'navigate') {
+ this._router.navigate(this.routerLinkFn(fileStatus));
+ }
+ }
+
routerLinkFn = (fileStatus: FileStatusWrapper) =>
fileStatus.canBeOpened ? [`/main/dossiers/${this.currentDossier.dossierId}/file/${fileStatus.fileId}`] : [];
disabledFn = (fileStatus: FileStatusWrapper) => fileStatus.excluded;
+
lastOpenedFn = (fileStatus: FileStatusWrapper) => fileStatus.lastOpened;
async ngOnInit(): Promise {
@@ -139,7 +219,7 @@ export class DossierOverviewScreenComponent extends ListingComponent {
await this._appStateService.reloadActiveDossierFilesIfNecessary();
@@ -147,7 +227,7 @@ export class DossierOverviewScreenComponent extends ListingComponent {
- this.calculateData();
+ this._calculateData();
});
this.addSubscription = this._appStateService.dossierTemplateChanged$.subscribe(() => {
@@ -197,10 +277,10 @@ export class DossierOverviewScreenComponent extends ListingComponent
diff --git a/apps/red-ui/src/app/modules/dossier/services/file-action.service.ts b/apps/red-ui/src/app/modules/dossier/services/file-action.service.ts
index 0189094e3..4069a04c7 100644
--- a/apps/red-ui/src/app/modules/dossier/services/file-action.service.ts
+++ b/apps/red-ui/src/app/modules/dossier/services/file-action.service.ts
@@ -8,6 +8,7 @@ import { isArray } from 'rxjs/internal-compatibility';
import { DossiersDialogService } from './dossiers-dialog.service';
import { ConfirmationDialogInput } from '../../shared/dialogs/confirmation-dialog/confirmation-dialog.component';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
+import { Observable } from 'rxjs';
@Injectable()
export class FileActionService {
@@ -83,7 +84,7 @@ export class FileActionService {
);
}
- setFileApproved(fileStatus: FileStatusWrapper | FileStatusWrapper[]) {
+ setFileApproved(fileStatus: FileStatusWrapper | FileStatusWrapper[]): Observable {
if (!isArray(fileStatus)) {
fileStatus = [fileStatus];
}
@@ -116,11 +117,7 @@ export class FileActionService {
assignFile(mode: 'reviewer' | 'approver', $event: MouseEvent, file?: FileStatusWrapper, callback?: Function, ignoreChanged = false) {
const files = file ? [file] : [this._appStateService.activeFile];
const data = { mode, files, ignoreChanged };
- this._dialogService.openDialog('assignFile', $event, data, async () => {
- if (callback) {
- callback();
- }
- });
+ this._dialogService.openDialog('assignFile', $event, data, callback);
}
private async _assignReviewerToCurrentUser(fileStatus: FileStatusWrapper | FileStatusWrapper[], callback?: Function) {
diff --git a/apps/red-ui/src/app/modules/shared/components/page-header/page-header.component.html b/apps/red-ui/src/app/modules/shared/components/page-header/page-header.component.html
index cb2a0faa6..829a4b248 100644
--- a/apps/red-ui/src/app/modules/shared/components/page-header/page-header.component.html
+++ b/apps/red-ui/src/app/modules/shared/components/page-header/page-header.component.html
@@ -15,7 +15,9 @@
+
+
+
diff --git a/apps/red-ui/src/app/modules/shared/components/page-header/page-header.component.scss b/apps/red-ui/src/app/modules/shared/components/page-header/page-header.component.scss
index acbdfdf11..ffe60a1b5 100644
--- a/apps/red-ui/src/app/modules/shared/components/page-header/page-header.component.scss
+++ b/apps/red-ui/src/app/modules/shared/components/page-header/page-header.component.scss
@@ -1,3 +1,5 @@
+@import '../../../../../assets/styles/variables';
+
.ml-6 {
margin-left: 6px;
}
diff --git a/apps/red-ui/src/app/modules/shared/components/page-header/page-header.component.ts b/apps/red-ui/src/app/modules/shared/components/page-header/page-header.component.ts
index fb1bc8eda..e572822c4 100644
--- a/apps/red-ui/src/app/modules/shared/components/page-header/page-header.component.ts
+++ b/apps/red-ui/src/app/modules/shared/components/page-header/page-header.component.ts
@@ -1,7 +1,7 @@
-import { Component, EventEmitter, Input, Optional, Output } from '@angular/core';
+import { Component, EventEmitter, Input, Optional, Output, TemplateRef } 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, SearchService } from '@iqser/common-ui';
+import { FilterService, IconButtonTypes, Listable, SearchService } from '@iqser/common-ui';
import { distinctUntilChanged, map } from 'rxjs/operators';
import { combineLatest, Observable, of } from 'rxjs';
import { SearchPosition, SearchPositions } from '@shared/components/page-header/models/search-positions.type';
@@ -12,13 +12,15 @@ import { FileAttributeConfig } from '@redaction/red-ui-http';
templateUrl: './page-header.component.html',
styleUrls: ['./page-header.component.scss']
})
-export class PageHeaderComponent {
+export class PageHeaderComponent {
readonly searchPositions = SearchPositions;
+ readonly iconButtonTypes = IconButtonTypes;
@Input() pageLabel: string;
@Input() showCloseButton: boolean;
@Input() actionConfigs: readonly ActionConfig[];
@Input() buttonConfigs: readonly ButtonConfig[];
+ @Input() viewModeSelection: TemplateRef;
@Input() fileAttributeConfigs: readonly FileAttributeConfig[];
@Input() searchPlaceholder: string;
@Input() searchWidth: number | 'full';
diff --git a/apps/red-ui/src/assets/i18n/en.json b/apps/red-ui/src/assets/i18n/en.json
index bd220b610..a82cbef34 100644
--- a/apps/red-ui/src/assets/i18n/en.json
+++ b/apps/red-ui/src/assets/i18n/en.json
@@ -680,6 +680,7 @@
},
"ocr-file": "OCR Document",
"ocr-performed": "OCR was performed for this file.",
+ "open-document": "Open Document",
"quick-filters": {
"assigned-to-me": "Assigned to me",
"assigned-to-others": "Assigned to others",
@@ -1491,6 +1492,11 @@
"expand": "Show Details",
"title": "Users"
},
+ "view-mode": {
+ "list": "List",
+ "view-as": "View as:",
+ "workflow": "Workflow"
+ },
"watermark": "Watermark",
"watermark-screen": {
"action": {
diff --git a/apps/red-ui/src/assets/styles/red-components.scss b/apps/red-ui/src/assets/styles/red-components.scss
index 9a29adaa0..e35976702 100644
--- a/apps/red-ui/src/assets/styles/red-components.scss
+++ b/apps/red-ui/src/assets/styles/red-components.scss
@@ -81,6 +81,8 @@
mat-icon {
width: 10px;
+ height: 10px;
+ line-height: 13px;
margin-right: 6px;
}
diff --git a/apps/red-ui/src/assets/styles/red-page-layout.scss b/apps/red-ui/src/assets/styles/red-page-layout.scss
index 7e0a58eb2..8028ab0a3 100644
--- a/apps/red-ui/src/assets/styles/red-page-layout.scss
+++ b/apps/red-ui/src/assets/styles/red-page-layout.scss
@@ -241,10 +241,18 @@ section.settings {
margin-top: 32px;
}
+.mb-6 {
+ margin-bottom: 6px;
+}
+
.mb-8 {
margin-bottom: 8px !important;
}
+.mb-12 {
+ margin-bottom: 12px !important;
+}
+
.ml-8 {
margin-left: 8px;
}
diff --git a/libs/common-ui b/libs/common-ui
index 6c0f123bd..cb8393c49 160000
--- a/libs/common-ui
+++ b/libs/common-ui
@@ -1 +1 @@
-Subproject commit 6c0f123bd97148f8696038f63c9951c241b71990
+Subproject commit cb8393c492ec1e2795d644009266cc71eeca11a7