278 lines
13 KiB
HTML
278 lines
13 KiB
HTML
<section *ngIf="appStateService.activeFile">
|
|
<div class="page-header">
|
|
<div class="flex-1">
|
|
<div
|
|
[matTooltip]="(canNotSwitchToRedactedView ? 'file-preview.cannot-show-redacted-view' : 'file-preview.show-redacted-view') | translate"
|
|
class="fit-content"
|
|
>
|
|
<mat-slide-toggle [(ngModel)]="redactedView" [disabled]="canNotSwitchToRedactedView" color="primary" labelPosition="after">
|
|
{{ 'file-preview.view-toggle' | translate }}
|
|
</mat-slide-toggle>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="page-title">
|
|
<span *ngIf="!permissionsService.canPerformAnnotationActions()" class="pill" translate="readonly-pill"></span>
|
|
</div>
|
|
|
|
<div *ngIf="viewReady" class="flex-1 actions-container">
|
|
<redaction-status-bar
|
|
[config]="[
|
|
{
|
|
length: 1,
|
|
color: appStateService.activeFile.status
|
|
}
|
|
]"
|
|
[small]="true"
|
|
>
|
|
</redaction-status-bar>
|
|
<div class="all-caps-label mr-16 ml-8">
|
|
{{ appStateService.activeFile.status | translate }}
|
|
<span *ngIf="appStateService.activeFile.status === 'UNDER_REVIEW' || appStateService.activeFile.status === 'UNDER_APPROVAL'"
|
|
>{{ 'by' | translate }}:</span
|
|
>
|
|
</div>
|
|
|
|
<ng-container *ngIf="!editingReviewer">
|
|
<redaction-initials-avatar
|
|
*ngIf="!editingReviewer"
|
|
[userId]="appStateService.activeFile.currentReviewer"
|
|
[withName]="!!appStateService.activeFile.currentReviewer"
|
|
></redaction-initials-avatar>
|
|
<div
|
|
(click)="editingReviewer = true"
|
|
*ngIf="!editingReviewer && !appStateService.activeFile.currentReviewer && permissionsService.canAssignReviewer(appStateService.activeFile)"
|
|
class="assign-reviewer pointer"
|
|
translate="file-preview.assign-reviewer"
|
|
></div>
|
|
</ng-container>
|
|
|
|
<ng-container *ngIf="editingReviewer">
|
|
<form [formGroup]="reviewerForm">
|
|
<div class="red-input-group w-250">
|
|
<mat-select formControlName="reviewer">
|
|
<mat-select-trigger>
|
|
<redaction-initials-avatar
|
|
size="small"
|
|
[userId]="reviewerForm.get('reviewer').value"
|
|
[withName]="true"
|
|
></redaction-initials-avatar>
|
|
</mat-select-trigger>
|
|
<mat-option *ngFor="let reviewerId of this.appStateService.activeProject.memberIds" [value]="reviewerId">
|
|
<redaction-initials-avatar size="small" [userId]="reviewerId" [withName]="true"></redaction-initials-avatar>
|
|
</mat-option>
|
|
</mat-select>
|
|
</div>
|
|
</form>
|
|
</ng-container>
|
|
|
|
<div *ngIf="permissionsService.canAssignReviewer(appStateService.activeFile)" class="assign-actions-wrapper">
|
|
<redaction-circle-button
|
|
(action)="editingReviewer = true"
|
|
*ngIf="!editingReviewer && permissionsService.canAssignReviewer(appStateService.activeFile) && appStateService.activeFile.currentReviewer"
|
|
icon="red:edit"
|
|
tooltip="file-preview.assign-reviewer"
|
|
tooltipPosition="below"
|
|
>
|
|
</redaction-circle-button>
|
|
|
|
<redaction-circle-button
|
|
(action)="assignReviewer()"
|
|
*ngIf="editingReviewer"
|
|
icon="red:check-alt"
|
|
tooltip="file-preview.save-assign-reviewer"
|
|
tooltipPosition="below"
|
|
>
|
|
</redaction-circle-button>
|
|
|
|
<redaction-circle-button
|
|
(action)="editingReviewer = false; resetReviewerForm()"
|
|
*ngIf="editingReviewer"
|
|
icon="red:close"
|
|
tooltip="file-preview.cancel-assign-reviewer"
|
|
tooltipPosition="below"
|
|
>
|
|
</redaction-circle-button>
|
|
|
|
<redaction-circle-button
|
|
(action)="assignToMe()"
|
|
*ngIf="!editingReviewer && permissionsService.canAssignReviewer(appStateService.activeFile) && !permissionsService.isFileReviewer()"
|
|
icon="red:assign-me"
|
|
tooltip="file-preview.assign-me"
|
|
tooltipPosition="below"
|
|
>
|
|
</redaction-circle-button>
|
|
</div>
|
|
|
|
<ng-container *ngIf="permissionsService.isManagerAndOwner() && !!appStateService.activeFile.fileStatus.lastReviewer">
|
|
<div class="vertical-line"></div>
|
|
<div class="all-caps-label mr-16 ml-8" translate="file-preview.last-reviewer"></div>
|
|
<redaction-initials-avatar [userId]="appStateService.activeFile.fileStatus.lastReviewer" [withName]="true"></redaction-initials-avatar>
|
|
</ng-container>
|
|
<div class="vertical-line"></div>
|
|
|
|
<redaction-file-actions (actionPerformed)="fileActionPerformed($event)" *ngIf="viewReady"></redaction-file-actions>
|
|
<redaction-circle-button
|
|
(action)="toggleFullScreen()"
|
|
icon="red:fullscreen"
|
|
tooltip="file-preview.fullscreen"
|
|
tooltipPosition="before"
|
|
></redaction-circle-button>
|
|
|
|
<!-- Dev Mode Features-->
|
|
<redaction-circle-button
|
|
*ngIf="userPreferenceService.areDevFeaturesEnabled"
|
|
(action)="openSSRFilePreview()"
|
|
icon="red:new-tab"
|
|
type="primary"
|
|
class="ml-8"
|
|
tooltip="file-preview.new-tab-ssr"
|
|
tooltipPosition="before"
|
|
></redaction-circle-button>
|
|
<redaction-circle-button
|
|
*ngIf="userPreferenceService.areDevFeaturesEnabled"
|
|
(action)="openHTMLDebug()"
|
|
icon="red:html-file"
|
|
type="primary"
|
|
class="ml-8"
|
|
tooltip="file-preview.html-debug"
|
|
tooltipPosition="before"
|
|
></redaction-circle-button>
|
|
<!-- End Dev Mode Features-->
|
|
|
|
<redaction-circle-button
|
|
[routerLink]="['/ui/projects/' + appStateService.activeProjectId]"
|
|
class="ml-8"
|
|
icon="red:close"
|
|
tooltip="common.close"
|
|
tooltipPosition="before"
|
|
></redaction-circle-button>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="red-content-inner" [class.fullscreen]="fullScreen">
|
|
<div class="left-container">
|
|
<div class="overlay-shadow"></div>
|
|
<redaction-pdf-viewer
|
|
(keyUp)="handleKeyEvent($event)"
|
|
(annotationSelected)="handleAnnotationSelected($event)"
|
|
(manualAnnotationRequested)="openManualAnnotationDialog($event)"
|
|
(annotationsChanged)="annotationsChangedByReviewAction($event)"
|
|
(pageChanged)="viewerPageChanged($event)"
|
|
(viewerReady)="viewerReady($event)"
|
|
[canPerformActions]="canPerformAnnotationActions"
|
|
[fileData]="displayData"
|
|
[fileStatus]="appStateService.activeFile"
|
|
[shouldDeselectAnnotationsOnPageChange]="shouldDeselectAnnotationsOnPageChange"
|
|
[annotations]="annotations"
|
|
></redaction-pdf-viewer>
|
|
</div>
|
|
|
|
<div class="right-container">
|
|
<div class="right-title heading" translate="file-preview.tabs.annotations.label">
|
|
<div>
|
|
<redaction-filter
|
|
(filtersChanged)="filtersChanged($event)"
|
|
[chevron]="true"
|
|
[filterTemplate]="annotationFilterTemplate"
|
|
[filters]="annotationFilters"
|
|
></redaction-filter>
|
|
|
|
<redaction-circle-button
|
|
*ngIf="fullScreen"
|
|
(action)="toggleFullScreen()"
|
|
icon="red:exit-fullscreen"
|
|
tooltip="file-preview.exit-fullscreen"
|
|
tooltipPosition="before"
|
|
></redaction-circle-button>
|
|
</div>
|
|
</div>
|
|
<div class="right-content">
|
|
<div
|
|
#quickNavigation
|
|
(keydown)="preventKeyDefault($event)"
|
|
(keyup)="preventKeyDefault($event)"
|
|
[class.active-panel]="pagesPanelActive"
|
|
class="pages"
|
|
tabindex="0"
|
|
>
|
|
<redaction-page-indicator
|
|
(pageSelected)="pageSelectedByClick($event)"
|
|
*ngFor="let pageNumber of displayedPages"
|
|
[active]="pageNumber === activeViewerPage"
|
|
[number]="pageNumber"
|
|
[viewedPages]="fileData.viewedPages"
|
|
>
|
|
</redaction-page-indicator>
|
|
</div>
|
|
|
|
<div style="overflow: hidden; width: 100%;">
|
|
<div attr.anotation-page-header="{{ activeViewerPage }}" class="page-separator">
|
|
<span *ngIf="!!activeViewerPage" class="all-caps-label"
|
|
><span translate="page"></span> {{ activeViewerPage }} - {{ displayedAnnotations[activeViewerPage]?.annotations?.length || 0 }}
|
|
<span [translate]="displayedAnnotations[activeViewerPage]?.annotations?.length === 1 ? 'annotation' : 'annotations'"></span
|
|
></span>
|
|
</div>
|
|
|
|
<div
|
|
#annotationsElement
|
|
(keydown)="preventKeyDefault($event)"
|
|
(keyup)="preventKeyDefault($event)"
|
|
[class.active-panel]="!pagesPanelActive"
|
|
redactionHasScrollbar
|
|
class="annotations"
|
|
tabindex="1"
|
|
>
|
|
<div *ngIf="!displayedAnnotations[activeViewerPage]" class="heading-l no-annotations">
|
|
{{ 'file-preview.no-annotations-for-page' | translate }}
|
|
</div>
|
|
|
|
<div
|
|
(click)="annotationClicked(annotation)"
|
|
*ngFor="let annotation of displayedAnnotations[activeViewerPage]?.annotations"
|
|
[ngClass]="{ active: selectedAnnotation?.id === annotation.id }"
|
|
attr.annotation-id="{{ annotation.id }}"
|
|
attr.annotation-page="{{ activeViewerPage }}"
|
|
class="annotation"
|
|
>
|
|
<div class="details">
|
|
<redaction-type-annotation-icon [annotation]="annotation"></redaction-type-annotation-icon>
|
|
<div class="flex-1">
|
|
<div>
|
|
<strong>{{ annotation.typeLabel | translate }}</strong>
|
|
</div>
|
|
<div *ngIf="annotation.dictionary && annotation.dictionary !== 'manual'">
|
|
<strong
|
|
><span>{{ annotation.descriptor | translate }}</span
|
|
>: </strong
|
|
>{{ annotation.dictionary | humanize: false }}
|
|
</div>
|
|
<div *ngIf="annotation.content">
|
|
<strong><span translate="content"></span>: </strong>{{ annotation.content }}
|
|
</div>
|
|
</div>
|
|
<redaction-annotation-actions
|
|
(annotationsChanged)="annotationsChangedByReviewAction($event)"
|
|
[annotation]="annotation"
|
|
[canPerformAnnotationActions]="canPerformAnnotationActions"
|
|
></redaction-annotation-actions>
|
|
</div>
|
|
<redaction-comments [annotation]="annotation"></redaction-comments>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<redaction-full-page-loading-indicator [displayed]="!viewReady" [message]="loadingMessage"></redaction-full-page-loading-indicator>
|
|
|
|
<ng-template #annotationFilterTemplate let-filter="filter">
|
|
<redaction-type-filter *ngIf="filter.topLevelFilter" [filter]="filter"></redaction-type-filter>
|
|
<ng-container *ngIf="!filter.topLevelFilter">
|
|
<redaction-dictionary-annotation-icon [dictionaryKey]="filter.key"></redaction-dictionary-annotation-icon>
|
|
{{ filter.key | humanize: false }}
|
|
</ng-container>
|
|
</ng-template>
|