Document info

This commit is contained in:
Adina Țeudan 2021-03-23 23:45:43 +02:00
parent f0056fee56
commit 9659cbe289
24 changed files with 402 additions and 143 deletions

View File

@ -118,6 +118,8 @@ import { SearchInputComponent } from './components/search-input/search-input.com
import { AppRoutingModule } from './app-routing.module'; import { AppRoutingModule } from './app-routing.module';
import { AddEditFileAttributeDialogComponent } from './dialogs/add-edit-file-attribute-dialog/add-edit-file-attribute-dialog.component'; import { AddEditFileAttributeDialogComponent } from './dialogs/add-edit-file-attribute-dialog/add-edit-file-attribute-dialog.component';
import { ConfirmDeleteFileAttributeDialogComponent } from './dialogs/confirm-delete-file-attribute-dialog/confirm-delete-file-attribute-dialog.component'; import { ConfirmDeleteFileAttributeDialogComponent } from './dialogs/confirm-delete-file-attribute-dialog/confirm-delete-file-attribute-dialog.component';
import { DocumentInfoDialogComponent } from './dialogs/document-info-dialog/document-info-dialog.component';
import { DocumentInfoComponent } from './components/document-info/document-info.component';
export function HttpLoaderFactory(httpClient: HttpClient) { export function HttpLoaderFactory(httpClient: HttpClient) {
return new TranslateHttpLoader(httpClient, '/assets/i18n/', '.json'); return new TranslateHttpLoader(httpClient, '/assets/i18n/', '.json');
@ -222,7 +224,9 @@ const matImports = [
FileAttributesListingScreenComponent, FileAttributesListingScreenComponent,
SearchInputComponent, SearchInputComponent,
AddEditFileAttributeDialogComponent, AddEditFileAttributeDialogComponent,
ConfirmDeleteFileAttributeDialogComponent ConfirmDeleteFileAttributeDialogComponent,
DocumentInfoDialogComponent,
DocumentInfoComponent
], ],
imports: [ imports: [
BrowserModule, BrowserModule,

View File

@ -0,0 +1,39 @@
<div class="right-title heading" translate="file-preview.tabs.document-info.label">
<div>
<redaction-circle-button
icon="red:edit"
(action)="closeDocumentInfoView.emit()"
tooltipPosition="before"
tooltip="file-preview.tabs.document-info.edit"
></redaction-circle-button>
<redaction-circle-button
icon="red:close"
(action)="closeDocumentInfoView.emit()"
tooltipPosition="before"
tooltip="file-preview.tabs.document-info.close"
></redaction-circle-button>
</div>
</div>
<div class="section">
Attributes go here
</div>
<div class="section small-label stats-subtitle">
<div>
<mat-icon svgIcon="red:folder"></mat-icon>
<span>{{ 'file-preview.tabs.document-info.details.project' | translate: { projectName: project.name } }}</span>
</div>
<div>
<mat-icon svgIcon="red:document"></mat-icon>
<span>{{ 'file-preview.tabs.document-info.details.pages' | translate: { pages: file.numberOfPages } }}</span>
</div>
<div>
<mat-icon svgIcon="red:calendar"></mat-icon>
<span>{{ 'file-preview.tabs.document-info.details.created-on' | translate: { date: file.added | date: 'mediumDate' } }}</span>
</div>
<div *ngIf="project.project.dueDate">
<mat-icon svgIcon="red:lightning"></mat-icon>
<span>{{ 'file-preview.tabs.document-info.details.due' | translate: { date: project.project.dueDate | date: 'mediumDate' } }}</span>
</div>
</div>

View File

@ -0,0 +1,22 @@
@import '../../../assets/styles/red-variables';
.right-title > div {
display: flex;
> redaction-circle-button:not(:last-child) {
margin-right: 2px;
}
}
.section {
padding: 25px;
flex-direction: column;
> div {
justify-content: flex-start;
}
&:not(:last-child) {
border-bottom: 1px solid $separator;
}
}

View File

@ -0,0 +1,21 @@
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
import { FileStatus } from '@redaction/red-ui-http';
import { AppStateService } from '../../state/app-state.service';
@Component({
selector: 'redaction-document-info',
templateUrl: './document-info.component.html',
styleUrls: ['./document-info.component.scss']
})
export class DocumentInfoComponent implements OnInit {
@Input() file: FileStatus;
@Output() closeDocumentInfoView = new EventEmitter();
constructor(private _appStateService: AppStateService) {}
ngOnInit(): void {}
public get project() {
return this._appStateService.getProjectById(this.file.projectId);
}
}

View File

@ -49,6 +49,15 @@
> >
</redaction-file-download-btn> </redaction-file-download-btn>
<redaction-circle-button
*ngIf="screen === 'file-preview'"
(action)="toggleViewDocumentInfo()"
tooltip="file-preview.document-info"
tooltipPosition="before"
icon="red:status-info"
[attr.aria-expanded]="activeDocumentInfo"
></redaction-circle-button>
<!-- Ready for approval--> <!-- Ready for approval-->
<redaction-circle-button <redaction-circle-button
(action)="setFileUnderApproval($event, fileStatus)" (action)="setFileUnderApproval($event, fileStatus)"

View File

@ -14,6 +14,7 @@ import { DEFAULT_RUL_SET_UUID } from '../../utils/rule-set-default';
}) })
export class FileActionsComponent implements OnInit { export class FileActionsComponent implements OnInit {
@Input() fileStatus: FileStatusWrapper; @Input() fileStatus: FileStatusWrapper;
@Input() activeDocumentInfo: boolean;
@Output() actionPerformed = new EventEmitter<string>(); @Output() actionPerformed = new EventEmitter<string>();
actionMenuOpen: boolean; actionMenuOpen: boolean;
@ -40,6 +41,10 @@ export class FileActionsComponent implements OnInit {
} }
} }
public toggleViewDocumentInfo() {
this.actionPerformed.emit('view-document-info');
}
public get tooltipPosition() { public get tooltipPosition() {
return this.screen === 'file-preview' ? 'below' : 'above'; return this.screen === 'file-preview' ? 'below' : 'above';
} }

View File

@ -1,13 +1,13 @@
<section class="dialog"> <section class="dialog">
<div class="dialog-header heading-l"> <div class="dialog-header heading-l">
{{ (fileAttribute ? 'add-edit-file-attribute.title.edit' : 'add-edit-file-attribute.title.new') | translate: { name: fileAttribute?.name } }} {{ (fileAttribute ? 'add-edit-file-attribute.title.edit' : 'add-edit-file-attribute.title.new') | translate: { name: fileAttribute?.label } }}
</div> </div>
<form (submit)="saveFileAttribute()" [formGroup]="fileAttributeForm"> <form (submit)="saveFileAttribute()" [formGroup]="fileAttributeForm">
<div class="dialog-content"> <div class="dialog-content">
<div class="red-input-group required w-300"> <div class="red-input-group required w-300">
<label translate="add-edit-file-attribute.form.name"></label> <label translate="add-edit-file-attribute.form.name"></label>
<input formControlName="name" name="name" type="text" placeholder="{{ 'add-edit-file-attribute.form.name-placeholder' | translate }}" /> <input formControlName="label" name="label" type="text" placeholder="{{ 'add-edit-file-attribute.form.name-placeholder' | translate }}" />
</div> </div>
<div class="red-input-group ignore-label-styles"> <div class="red-input-group ignore-label-styles">

View File

@ -1,8 +1,9 @@
import { Component, Inject } from '@angular/core'; import { Component, Inject } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms'; import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { AppStateService } from '../../state/app-state.service'; import { AppStateService } from '../../state/app-state.service';
import { FileAttribute, FileAttributesControllerService } from '@redaction/red-ui-http'; import { FileAttributeConfig, FileAttributesControllerService } from '@redaction/red-ui-http';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import { computerize } from '../../utils/functions';
@Component({ @Component({
selector: 'redaction-add-edit-file-attribute-dialog', selector: 'redaction-add-edit-file-attribute-dialog',
@ -11,7 +12,7 @@ import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
}) })
export class AddEditFileAttributeDialogComponent { export class AddEditFileAttributeDialogComponent {
public fileAttributeForm: FormGroup; public fileAttributeForm: FormGroup;
public fileAttribute: FileAttribute; public fileAttribute: FileAttributeConfig;
public ruleSetId: string; public ruleSetId: string;
constructor( constructor(
@ -19,13 +20,13 @@ export class AddEditFileAttributeDialogComponent {
private readonly _formBuilder: FormBuilder, private readonly _formBuilder: FormBuilder,
private readonly _fileAttributesService: FileAttributesControllerService, private readonly _fileAttributesService: FileAttributesControllerService,
public dialogRef: MatDialogRef<AddEditFileAttributeDialogComponent>, public dialogRef: MatDialogRef<AddEditFileAttributeDialogComponent>,
@Inject(MAT_DIALOG_DATA) public data: { fileAttribute: FileAttribute; ruleSetId: string } @Inject(MAT_DIALOG_DATA) public data: { fileAttribute: FileAttributeConfig; ruleSetId: string }
) { ) {
this.fileAttribute = data.fileAttribute; this.fileAttribute = data.fileAttribute;
this.ruleSetId = data.ruleSetId; this.ruleSetId = data.ruleSetId;
this.fileAttributeForm = this._formBuilder.group({ this.fileAttributeForm = this._formBuilder.group({
name: [this.fileAttribute?.name, Validators.required], label: [this.fileAttribute?.label, Validators.required],
readonly: [this.fileAttribute ? !this.fileAttribute.editable : false], readonly: [this.fileAttribute ? !this.fileAttribute.editable : false],
visible: [this.fileAttribute?.visible] visible: [this.fileAttribute?.visible]
}); });
@ -48,12 +49,13 @@ export class AddEditFileAttributeDialogComponent {
} }
async saveFileAttribute() { async saveFileAttribute() {
const fileAttribute = { const fileAttribute: FileAttributeConfig = {
id: this.fileAttribute?.id, id: this.fileAttribute?.id,
editable: !this.fileAttributeForm.get('readonly').value, editable: !this.fileAttributeForm.get('readonly').value,
csvColumnHeader: this.fileAttribute?.csvColumnHeader || computerize(this.fileAttributeForm.get('label').value),
...this.fileAttributeForm.getRawValue() ...this.fileAttributeForm.getRawValue()
}; };
await this._fileAttributesService.setFileAttributesConfiguration({ fileAttributes: [fileAttribute] }, this.ruleSetId).toPromise(); await this._fileAttributesService.setFileAttributesConfiguration(fileAttribute, this.ruleSetId).toPromise();
this.dialogRef.close(fileAttribute); this.dialogRef.close(fileAttribute);
} }
} }

View File

@ -1,6 +1,6 @@
<section class="dialog"> <section class="dialog">
<div class="dialog-header heading-l"> <div class="dialog-header heading-l">
{{ 'confirm-delete-file-attribute.title' | translate: { name: fileAttribute.name } }} {{ 'confirm-delete-file-attribute.title' | translate: { name: fileAttribute.label } }}
</div> </div>
<div class="dialog-content"> <div class="dialog-content">

View File

@ -1,6 +1,6 @@
import { Component, Inject } from '@angular/core'; import { Component, Inject } from '@angular/core';
import { AppStateService } from '../../state/app-state.service'; import { AppStateService } from '../../state/app-state.service';
import { FileAttribute, FileAttributesControllerService } from '@redaction/red-ui-http'; import { FileAttributeConfig, FileAttributesControllerService } from '@redaction/red-ui-http';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
@Component({ @Component({
@ -9,7 +9,7 @@ import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
styleUrls: ['./confirm-delete-file-attribute-dialog.component.scss'] styleUrls: ['./confirm-delete-file-attribute-dialog.component.scss']
}) })
export class ConfirmDeleteFileAttributeDialogComponent { export class ConfirmDeleteFileAttributeDialogComponent {
public fileAttribute: FileAttribute; public fileAttribute: FileAttributeConfig;
public ruleSetId: string; public ruleSetId: string;
public checkboxes = [{ value: false }, { value: false }]; public checkboxes = [{ value: false }, { value: false }];
@ -17,7 +17,7 @@ export class ConfirmDeleteFileAttributeDialogComponent {
private readonly _appStateService: AppStateService, private readonly _appStateService: AppStateService,
private readonly _fileAttributesService: FileAttributesControllerService, private readonly _fileAttributesService: FileAttributesControllerService,
public dialogRef: MatDialogRef<ConfirmDeleteFileAttributeDialogComponent>, public dialogRef: MatDialogRef<ConfirmDeleteFileAttributeDialogComponent>,
@Inject(MAT_DIALOG_DATA) public data: { fileAttribute: FileAttribute; ruleSetId: string } @Inject(MAT_DIALOG_DATA) public data: { fileAttribute: FileAttributeConfig; ruleSetId: string }
) { ) {
this.fileAttribute = data.fileAttribute; this.fileAttribute = data.fileAttribute;
this.ruleSetId = data.ruleSetId; this.ruleSetId = data.ruleSetId;

View File

@ -3,7 +3,7 @@ import { MatDialog, MatDialogRef } from '@angular/material/dialog';
import { import {
Colors, Colors,
DictionaryControllerService, DictionaryControllerService,
FileAttribute, FileAttributeConfig,
FileManagementControllerService, FileManagementControllerService,
FileStatus, FileStatus,
ManualRedactionControllerService, ManualRedactionControllerService,
@ -30,6 +30,7 @@ import { RemoveAnnotationsDialogComponent } from './remove-annotations-dialog/re
import { ForceRedactionDialogComponent } from './force-redaction-dialog/force-redaction-dialog.component'; import { ForceRedactionDialogComponent } from './force-redaction-dialog/force-redaction-dialog.component';
import { AddEditFileAttributeDialogComponent } from './add-edit-file-attribute-dialog/add-edit-file-attribute-dialog.component'; import { AddEditFileAttributeDialogComponent } from './add-edit-file-attribute-dialog/add-edit-file-attribute-dialog.component';
import { ConfirmDeleteFileAttributeDialogComponent } from './confirm-delete-file-attribute-dialog/confirm-delete-file-attribute-dialog.component'; import { ConfirmDeleteFileAttributeDialogComponent } from './confirm-delete-file-attribute-dialog/confirm-delete-file-attribute-dialog.component';
import { DocumentInfoDialogComponent } from './document-info-dialog/document-info-dialog.component';
const dialogConfig = { const dialogConfig = {
width: '662px', width: '662px',
@ -339,7 +340,11 @@ export class DialogService {
return ref; return ref;
} }
public openAddEditFileAttributeDialog(fileAttribute: FileAttribute, ruleSetId: string, cb?: Function): MatDialogRef<AddEditFileAttributeDialogComponent> { public openAddEditFileAttributeDialog(
fileAttribute: FileAttributeConfig,
ruleSetId: string,
cb?: Function
): MatDialogRef<AddEditFileAttributeDialogComponent> {
const ref = this._dialog.open(AddEditFileAttributeDialogComponent, { const ref = this._dialog.open(AddEditFileAttributeDialogComponent, {
...dialogConfig, ...dialogConfig,
data: { fileAttribute, ruleSetId }, data: { fileAttribute, ruleSetId },
@ -356,7 +361,7 @@ export class DialogService {
} }
public openConfirmDeleteFileAttributeDialog( public openConfirmDeleteFileAttributeDialog(
fileAttribute: FileAttribute, fileAttribute: FileAttributeConfig,
ruleSetId: string, ruleSetId: string,
cb?: Function cb?: Function
): MatDialogRef<ConfirmDeleteFileAttributeDialogComponent> { ): MatDialogRef<ConfirmDeleteFileAttributeDialogComponent> {
@ -375,6 +380,22 @@ export class DialogService {
return ref; return ref;
} }
public openDocumentInfoDialog(file: FileStatus, cb?: Function): MatDialogRef<DocumentInfoDialogComponent> {
const ref = this._dialog.open(DocumentInfoDialogComponent, {
...dialogConfig,
data: file,
autoFocus: true
});
ref.afterClosed().subscribe((result) => {
if (result && cb) {
cb(result);
}
});
return ref;
}
openRemoveAnnotationModal($event: MouseEvent, annotation: AnnotationWrapper, callback: () => void) { openRemoveAnnotationModal($event: MouseEvent, annotation: AnnotationWrapper, callback: () => void) {
$event?.stopPropagation(); $event?.stopPropagation();

View File

@ -0,0 +1,24 @@
<section class="dialog">
<div class="dialog-header heading-l" translate="document-info.title"></div>
<form (submit)="saveDocumentInfo()" [formGroup]="documentInfoForm">
<div class="dialog-content">
{{ file.filename }}
<!-- <div class="red-input-group required w-300">-->
<!-- <label translate="add-edit-file-attribute.form.name"></label>-->
<!-- <input formControlName="name" name="name" type="text" placeholder="{{ 'add-edit-file-attribute.form.name-placeholder' | translate }}" />-->
<!-- </div>-->
<!-- <div class="red-input-group ignore-label-styles">-->
<!-- <mat-slide-toggle formControlName="readonly" color="primary">{{ 'add-edit-file-attribute.form.read-only' | translate }}</mat-slide-toggle>-->
<!-- </div>-->
</div>
<div class="dialog-actions">
<button [disabled]="documentInfoForm.invalid" color="primary" mat-flat-button type="submit">
{{ 'document-info.save' | translate }}
</button>
</div>
</form>
<redaction-circle-button icon="red:close" mat-dialog-close class="dialog-close"></redaction-circle-button>
</section>

View File

@ -0,0 +1,36 @@
import { Component, Inject, OnInit } from '@angular/core';
import { FormBuilder, FormGroup } from '@angular/forms';
import { FileAttributesControllerService, FileStatus } from '@redaction/red-ui-http';
import { AppStateService } from '../../state/app-state.service';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
@Component({
selector: 'redaction-document-info-dialog',
templateUrl: './document-info-dialog.component.html',
styleUrls: ['./document-info-dialog.component.scss']
})
export class DocumentInfoDialogComponent implements OnInit {
public documentInfoForm: FormGroup;
public file: FileStatus;
constructor(
private readonly _appStateService: AppStateService,
private readonly _formBuilder: FormBuilder,
private readonly _fileAttributesService: FileAttributesControllerService,
public dialogRef: MatDialogRef<DocumentInfoDialogComponent>,
@Inject(MAT_DIALOG_DATA) public data: FileStatus
) {
this.file = this.data;
console.log(this.data);
this.documentInfoForm = this._formBuilder.group({
// name: [this.fileAttribute?.name, Validators.required],
// readonly: [this.fileAttribute ? !this.fileAttribute.editable : false],
// visible: [this.fileAttribute?.visible]
});
}
ngOnInit(): void {}
public saveDocumentInfo() {}
}

View File

@ -64,8 +64,9 @@ export class IconsModule {
'sort-asc', 'sort-asc',
'sort-desc', 'sort-desc',
'status', 'status',
'status-expand',
'status-collapse', 'status-collapse',
'status-expand',
'status-info',
'template', 'template',
'thumb-down', 'thumb-down',
'thumb-up', 'thumb-up',

View File

@ -50,7 +50,7 @@
</div> </div>
</div> </div>
<div class="table-header" redactionSyncWidth="table-item"> <div [class.no-data]="noData" class="table-header" redactionSyncWidth="table-item">
<div class="select-oval-placeholder"></div> <div class="select-oval-placeholder"></div>
<redaction-table-col-name <redaction-table-col-name
@ -81,7 +81,7 @@
</div> </div>
<div> <div>
{{ attribute.name }} {{ attribute.label }}
</div> </div>
<!-- TODO--> <!-- TODO-->
<!-- <div class="center">--> <!-- <div class="center">-->

View File

@ -1,7 +1,7 @@
import { Component, OnInit } from '@angular/core'; import { Component, OnInit } from '@angular/core';
import { PermissionsService } from '../../../utils/permissions.service'; import { PermissionsService } from '../../../utils/permissions.service';
import { FormBuilder, FormGroup } from '@angular/forms'; import { FormBuilder, FormGroup } from '@angular/forms';
import { FileAttribute, FileAttributesControllerService } from '@redaction/red-ui-http'; import { FileAttributeConfig, FileAttributesControllerService } from '@redaction/red-ui-http';
import { AppStateService } from '../../../state/app-state.service'; import { AppStateService } from '../../../state/app-state.service';
import { ActivatedRoute } from '@angular/router'; import { ActivatedRoute } from '@angular/router';
import { debounce } from '../../../utils/debounce'; import { debounce } from '../../../utils/debounce';
@ -15,8 +15,8 @@ import { DialogService } from '../../../dialogs/dialog.service';
}) })
export class FileAttributesListingScreenComponent implements OnInit { export class FileAttributesListingScreenComponent implements OnInit {
public searchForm: FormGroup; public searchForm: FormGroup;
public attributes: FileAttribute[] = []; public attributes: FileAttributeConfig[] = [];
public displayedAttributes: FileAttribute[] = []; public displayedAttributes: FileAttributeConfig[] = [];
public selectedFileAttributeIds: string[] = []; public selectedFileAttributeIds: string[] = [];
public viewReady = false; public viewReady = false;
@ -47,6 +47,7 @@ export class FileAttributesListingScreenComponent implements OnInit {
try { try {
const response = await this._fileAttributesService.getFileAttributesConfiguration(this._appStateService.activeRuleSetId).toPromise(); const response = await this._fileAttributesService.getFileAttributesConfiguration(this._appStateService.activeRuleSetId).toPromise();
this.attributes = response?.fileAttributes || []; this.attributes = response?.fileAttributes || [];
} catch (e) {
} finally { } finally {
this.displayedAttributes = [...this.attributes]; this.displayedAttributes = [...this.attributes];
this._executeSearch(); this._executeSearch();
@ -71,24 +72,24 @@ export class FileAttributesListingScreenComponent implements OnInit {
if (!value) { if (!value) {
value = { query: this.searchForm.get('query').value }; value = { query: this.searchForm.get('query').value };
} }
this.displayedAttributes = this.attributes.filter((attribute) => attribute.name.toLowerCase().includes(value.query.toLowerCase())); this.displayedAttributes = this.attributes.filter((attribute) => attribute.label.toLowerCase().includes(value.query.toLowerCase()));
} }
public openAddEditAttributeDialog($event: MouseEvent, fileAttribute?: FileAttribute) { public openAddEditAttributeDialog($event: MouseEvent, fileAttribute?: FileAttributeConfig) {
$event.stopPropagation(); $event.stopPropagation();
this._dialogService.openAddEditFileAttributeDialog(fileAttribute, this._appStateService.activeRuleSetId, async () => { this._dialogService.openAddEditFileAttributeDialog(fileAttribute, this._appStateService.activeRuleSetId, async () => {
await this._loadData(); await this._loadData();
}); });
} }
public openConfirmDeleteAttributeDialog($event: MouseEvent, fileAttribute?: FileAttribute) { public openConfirmDeleteAttributeDialog($event: MouseEvent, fileAttribute?: FileAttributeConfig) {
$event.stopPropagation(); $event.stopPropagation();
this._dialogService.openConfirmDeleteFileAttributeDialog(fileAttribute, this._appStateService.activeRuleSetId, async () => { this._dialogService.openConfirmDeleteFileAttributeDialog(fileAttribute, this._appStateService.activeRuleSetId, async () => {
await this._loadData(); await this._loadData();
}); });
} }
public toggleAttributeSelected($event: MouseEvent, attribute: FileAttribute) { public toggleAttributeSelected($event: MouseEvent, attribute: FileAttributeConfig) {
$event.stopPropagation(); $event.stopPropagation();
const idx = this.selectedFileAttributeIds.indexOf(attribute.id); const idx = this.selectedFileAttributeIds.indexOf(attribute.id);
if (idx === -1) { if (idx === -1) {
@ -114,7 +115,7 @@ export class FileAttributesListingScreenComponent implements OnInit {
return this.selectedFileAttributeIds.length > 0; return this.selectedFileAttributeIds.length > 0;
} }
public isAttributeSelected(attribute: FileAttribute) { public isAttributeSelected(attribute: FileAttributeConfig) {
return this.selectedFileAttributeIds.indexOf(attribute.id) !== -1; return this.selectedFileAttributeIds.indexOf(attribute.id) !== -1;
} }
} }

View File

@ -6,7 +6,7 @@ import { PermissionsService } from '../../../utils/permissions.service';
import { FormBuilder, FormGroup } from '@angular/forms'; import { FormBuilder, FormGroup } from '@angular/forms';
import { debounce } from '../../../utils/debounce'; import { debounce } from '../../../utils/debounce';
import { RuleSetModel } from '@redaction/red-ui-http'; import { RuleSetModel } from '@redaction/red-ui-http';
import { UserPreferenceService } from '../../../common/service/user-preference.service'; import { UserPreferenceService } from '../../../utils/user-preference.service';
@Component({ @Component({
selector: 'redaction-rule-sets-listing-screen', selector: 'redaction-rule-sets-listing-screen',

View File

@ -129,7 +129,11 @@
</ng-container> </ng-container>
<div class="vertical-line"></div> <div class="vertical-line"></div>
<redaction-file-actions (actionPerformed)="fileActionPerformed($event)" *ngIf="viewReady"></redaction-file-actions> <redaction-file-actions
(actionPerformed)="fileActionPerformed($event)"
[activeDocumentInfo]="viewDocumentInfo"
*ngIf="viewReady"
></redaction-file-actions>
<redaction-circle-button <redaction-circle-button
(action)="toggleFullScreen()" (action)="toggleFullScreen()"
@ -199,7 +203,11 @@
></redaction-pdf-viewer> ></redaction-pdf-viewer>
</div> </div>
<div class="right-container"> <div class="right-container" redactionHasScrollbar>
<redaction-document-info *ngIf="viewDocumentInfo" [file]="fileData.fileStatus" (closeDocumentInfoView)="viewDocumentInfo = false">
</redaction-document-info>
<ng-container *ngIf="!viewDocumentInfo">
<div class="right-title heading" translate="file-preview.tabs.annotations.label"> <div class="right-title heading" translate="file-preview.tabs.annotations.label">
<div> <div>
<redaction-filter <redaction-filter
@ -312,6 +320,7 @@
</div> </div>
</div> </div>
</div> </div>
</ng-container>
</div> </div>
</div> </div>
</section> </section>

View File

@ -30,27 +30,20 @@
width: 350px; width: 350px;
min-width: 350px; min-width: 350px;
.right-title { &.has-scrollbar:hover {
::ng-deep redaction-document-info .right-title,
::ng-deep redaction-document-info .section {
padding-right: 13px;
}
}
::ng-deep.right-title {
height: 70px; height: 70px;
display: flex; display: flex;
border-bottom: 1px solid $separator; border-bottom: 1px solid $separator;
align-items: center; align-items: center;
justify-content: space-between; justify-content: space-between;
padding: 0 24px; padding: 0 24px;
.close-icon {
height: 14px;
width: 14px;
cursor: pointer;
}
> div {
display: flex;
redaction-circle-button {
margin-left: 2px;
}
}
} }
.right-content { .right-content {

View File

@ -146,6 +146,22 @@ export class FilePreviewScreenComponent implements OnInit, OnDestroy {
hideSkipped = false; hideSkipped = false;
private _viewDocumentInfo = false;
public get viewDocumentInfo(): boolean {
return this._viewDocumentInfo;
}
public set viewDocumentInfo(value: boolean) {
this._viewDocumentInfo = value;
if (!value) {
setTimeout(() => {
this._scrollQuickNavigation();
this.scrollToSelectedAnnotation();
}, 0);
}
}
updateViewMode() { updateViewMode() {
const allAnnotations = this._instance.annotManager.getAnnotationsList(); const allAnnotations = this._instance.annotManager.getAnnotationsList();
@ -329,13 +345,16 @@ export class FilePreviewScreenComponent implements OnInit, OnDestroy {
@debounce() @debounce()
private _scrollViews() { private _scrollViews() {
if (this.viewDocumentInfo) {
return;
}
this._scrollQuickNavigation(); this._scrollQuickNavigation();
this._scrollAnnotations(); this._scrollAnnotations();
} }
@debounce() @debounce()
private scrollToSelectedAnnotation() { private scrollToSelectedAnnotation() {
if (!this.selectedAnnotations || this.selectedAnnotations.length === 0) { if (this.viewDocumentInfo || !this.selectedAnnotations || this.selectedAnnotations.length === 0) {
return; return;
} }
const elements: any[] = this._annotationsElement.nativeElement.querySelectorAll(`div[annotation-id="${this.firstSelectedAnnotation.id}"].active`); const elements: any[] = this._annotationsElement.nativeElement.querySelectorAll(`div[annotation-id="${this.firstSelectedAnnotation.id}"].active`);
@ -602,6 +621,9 @@ export class FilePreviewScreenComponent implements OnInit, OnDestroy {
} }
public computeQuickNavButtonsState() { public computeQuickNavButtonsState() {
if (this.viewDocumentInfo) {
return;
}
const element: HTMLElement = this._quickNavigationElement.nativeElement.querySelector(`#pages`); const element: HTMLElement = this._quickNavigationElement.nativeElement.querySelector(`#pages`);
const { scrollTop, scrollHeight, clientHeight } = element; const { scrollTop, scrollHeight, clientHeight } = element;
this.quickScrollFirstEnabled = scrollTop !== 0; this.quickScrollFirstEnabled = scrollTop !== 0;
@ -670,6 +692,11 @@ export class FilePreviewScreenComponent implements OnInit, OnDestroy {
this._updateCanPerformActions(); this._updateCanPerformActions();
await this.appStateService.reloadActiveProjectFiles(); await this.appStateService.reloadActiveProjectFiles();
return; return;
case 'view-document-info':
this.viewDocumentInfo = !this.viewDocumentInfo;
return;
default: default:
this._updateCanPerformActions(); this._updateCanPerformActions();
} }

View File

@ -291,6 +291,18 @@
"view-toggle": "Redacted View", "view-toggle": "Redacted View",
"tabs": { "tabs": {
"quick-navigation": "Quick Navigation", "quick-navigation": "Quick Navigation",
"document-info": {
"label": "Document Info",
"close": "Close Document Info",
"edit": "Edit Document Info",
"details": {
"project": "in {{projectName}}",
"pages": "{{pages}} pages",
"revised-pages": "{{pages}} revised pages",
"created-on": "Created on: {{date}}",
"due": "Due: {{date}}"
}
},
"annotations": { "annotations": {
"label": "Workload" "label": "Workload"
} }
@ -303,6 +315,7 @@
"assign-me": "Assign to me", "assign-me": "Assign to me",
"last-reviewer": "Last Reviewed by:", "last-reviewer": "Last Reviewed by:",
"fullscreen": "Full Screen (F)", "fullscreen": "Full Screen (F)",
"document-info": "Your Document Info lives here. This includes metadata required on each document.",
"new-tab-ssr": "Open Document in Server Side Rendering Mode", "new-tab-ssr": "Open Document in Server Side Rendering Mode",
"html-debug": "Open Document HTML Debug", "html-debug": "Open Document HTML Debug",
"download-original-file": "Download Original File", "download-original-file": "Download Original File",
@ -732,6 +745,11 @@
"checkbox-1": "All documents it is used on will be impacted", "checkbox-1": "All documents it is used on will be impacted",
"checkbox-2": "All inputted details on the documents will be lost" "checkbox-2": "All inputted details on the documents will be lost"
}, },
"document-info": {
"title": "Introduce Document Info",
"save": "Save Document Info",
"save-approval": "Save and Send for Approval"
},
"user-listing": { "user-listing": {
"table-header": { "table-header": {
"title": "{{length}} users" "title": "{{length}} users"

View File

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="14px" height="14px" viewBox="0 0 14 14" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>F8E3057D-BE44-469F-9E28-9A04A0B36DF0</title>
<defs>
<rect id="path-1" x="0" y="61" width="1440" height="50"></rect>
<filter x="-0.5%" y="-10.0%" width="101.0%" height="128.0%" filterUnits="objectBoundingBox" id="filter-2">
<feOffset dx="0" dy="2" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
<feGaussianBlur stdDeviation="2" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur>
<feColorMatrix values="0 0 0 0 0.88627451 0 0 0 0 0.894117647 0 0 0 0 0.91372549 0 0 0 1 0" type="matrix" in="shadowBlurOuter1"></feColorMatrix>
</filter>
</defs>
<g id="File-attributes" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="Reviewer---Doc-Info-sidebar" transform="translate(-1256.000000, -79.000000)">
<rect x="0" y="0" width="1440" height="750"></rect>
<g id="Header-Document">
<g id="Group-6" transform="translate(1246.000000, 69.000000)">
<rect id="Rectangle" opacity="0.1" x="0" y="0" width="34" height="34" rx="17"></rect>
<g id="status" transform="translate(10.000000, 10.000000)" fill="currentColor">
<path d="M2.8,0 L0,0 L0,14 L14,14 L14,0 M12.6,1.4 L12.6,12.6 L1.4,12.6 L1.4,1.4 L2.8,1.4" id="pages" fill-rule="nonzero"></path>
<rect id="Rectangle" x="6.3" y="5.46" width="1.4" height="5.46"></rect>
<rect id="Rectangle" x="6.3" y="3.08" width="1.4" height="1.4"></rect>
</g>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

@ -74,7 +74,7 @@
mat-icon { mat-icon {
width: 10px; width: 10px;
margin-right: 4px; margin-right: 6px;
} }
&:not(:last-child) { &:not(:last-child) {