diff --git a/apps/red-ui/src/app/icons/icons.module.ts b/apps/red-ui/src/app/icons/icons.module.ts
index 0c8622230..7a0945248 100644
--- a/apps/red-ui/src/app/icons/icons.module.ts
+++ b/apps/red-ui/src/app/icons/icons.module.ts
@@ -44,6 +44,8 @@ export class IconsModule {
'lightning',
'logout',
'menu',
+ 'nav-first',
+ 'nav-last',
'needs-work',
'new-tab',
'notification',
diff --git a/apps/red-ui/src/app/screens/file/file-preview-screen/file-preview-screen.component.html b/apps/red-ui/src/app/screens/file/file-preview-screen/file-preview-screen.component.html
index 70834b8bc..94f66155c 100644
--- a/apps/red-ui/src/app/screens/file/file-preview-screen/file-preview-screen.component.html
+++ b/apps/red-ui/src/app/screens/file/file-preview-screen/file-preview-screen.component.html
@@ -217,17 +217,37 @@
(keydown)="preventKeyDefault($event)"
(keyup)="preventKeyDefault($event)"
[class.active-panel]="pagesPanelActive"
- class="pages"
+ class="quick-navigation"
tabindex="0"
>
-
-
+
+
+
+
+
+
+
+
+
diff --git a/apps/red-ui/src/app/screens/file/file-preview-screen/file-preview-screen.component.scss b/apps/red-ui/src/app/screens/file/file-preview-screen/file-preview-screen.component.scss
index 55c647921..965a39992 100644
--- a/apps/red-ui/src/app/screens/file/file-preview-screen/file-preview-screen.component.scss
+++ b/apps/red-ui/src/app/screens/file/file-preview-screen/file-preview-screen.component.scss
@@ -58,7 +58,7 @@
box-sizing: border-box;
display: flex;
- .pages,
+ .quick-navigation,
.annotations {
overflow-y: scroll;
outline: none;
@@ -68,10 +68,44 @@
}
}
- .pages {
+ .quick-navigation {
border-right: 1px solid $separator;
min-width: 61px;
- @include no-scroll-bar();
+ overflow: hidden;
+ display: flex;
+ flex-direction: column;
+
+ .jump {
+ min-height: 32px;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ cursor: pointer;
+ transition: background-color 0.25s;
+
+ &:not(.disabled):hover {
+ background-color: $grey-6;
+ }
+
+ mat-icon {
+ width: 16px;
+ height: 16px;
+ }
+
+ &.disabled {
+ cursor: default;
+
+ mat-icon {
+ opacity: 0.3;
+ }
+ }
+ }
+
+ .pages {
+ @include no-scroll-bar();
+ overflow: auto;
+ flex: 1;
+ }
}
.page-separator {
diff --git a/apps/red-ui/src/app/screens/file/file-preview-screen/file-preview-screen.component.ts b/apps/red-ui/src/app/screens/file/file-preview-screen/file-preview-screen.component.ts
index 11c7055f5..54111d07d 100644
--- a/apps/red-ui/src/app/screens/file/file-preview-screen/file-preview-screen.component.ts
+++ b/apps/red-ui/src/app/screens/file/file-preview-screen/file-preview-screen.component.ts
@@ -29,7 +29,6 @@ import { FormBuilder, FormGroup } from '@angular/forms';
import { FileManagementControllerService, StatusControllerService } from '@redaction/red-ui-http';
import { PdfViewerDataService } from '../service/pdf-viewer-data.service';
import { download } from '../../../utils/file-download-utils';
-import { MatButtonToggleChange } from '@angular/material/button-toggle';
import { ViewMode } from '../model/view-mode';
const COMMAND_KEY_ARRAY = ['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown', 'Escape'];
@@ -81,10 +80,6 @@ export class FilePreviewScreenComponent implements OnInit, OnDestroy {
return this._instance;
}
- get displayedPages(): number[] {
- return Object.keys(this.displayedAnnotations).map((key) => Number(key));
- }
-
get activeViewerPage() {
return this._instance?.docViewer?.getCurrentPage();
}
@@ -119,6 +114,11 @@ export class FilePreviewScreenComponent implements OnInit, OnDestroy {
public analysisProgress: number;
public analysisInterval: number;
+ public quickScrollFirstEnabled = false;
+ public quickScrollLastEnabled = false;
+
+ public displayedPages: number[] = [];
+
get indeterminateMode() {
return (
this.analysisProgress > 100 || this.appStateService.activeFile.analysisDuration < 3 * 1000 // it takes longer than usual - switch to indeterminate
@@ -342,11 +342,31 @@ export class FilePreviewScreenComponent implements OnInit, OnDestroy {
this._scrollToFirstElement(elements);
}
- private _scrollQuickNavigation() {
- const elements: any[] = this._quickNavigationElement.nativeElement.querySelectorAll(`#quick-nav-page-${this.activeViewerPage}`);
+ private _scrollQuickNavigationToPage(page: number) {
+ const elements: any[] = this._quickNavigationElement.nativeElement.querySelectorAll(`#quick-nav-page-${page}`);
this._scrollToFirstElement(elements);
}
+ private _scrollQuickNavigation() {
+ let quickNavPageIndex = this.displayedPages.findIndex((p) => p >= this.activeViewerPage);
+ if (quickNavPageIndex === -1 || this.displayedPages[quickNavPageIndex] !== this.activeViewerPage) {
+ quickNavPageIndex = Math.max(0, quickNavPageIndex - 1);
+ }
+ this._scrollQuickNavigationToPage(this.displayedPages[quickNavPageIndex]);
+ }
+
+ public scrollQuickNavFirst() {
+ if (this.displayedPages.length > 0) {
+ this._scrollQuickNavigationToPage(this.displayedPages[0]);
+ }
+ }
+
+ public scrollQuickNavLast() {
+ if (this.displayedPages.length > 0) {
+ this._scrollQuickNavigationToPage(this.displayedPages[this.displayedPages.length - 1]);
+ }
+ }
+
private _scrollAnnotations() {
if (this.firstSelectedAnnotation?.pageNumber === this.activeViewerPage) {
return;
@@ -570,6 +590,8 @@ export class FilePreviewScreenComponent implements OnInit, OnDestroy {
filtersChanged(filters: FilterModel[]) {
this.displayedAnnotations = this._annotationProcessingService.filterAndGroupAnnotations(this.annotations, filters);
+ this.displayedPages = Object.keys(this.displayedAnnotations).map((key) => Number(key));
+ this.computeQuickNavButtonsState();
this._changeDetectorRef.markForCheck();
}
@@ -579,6 +601,13 @@ export class FilePreviewScreenComponent implements OnInit, OnDestroy {
}
}
+ public computeQuickNavButtonsState() {
+ const element: HTMLElement = this._quickNavigationElement.nativeElement.querySelector(`#pages`);
+ const { scrollTop, scrollHeight, clientHeight } = element;
+ this.quickScrollFirstEnabled = scrollTop !== 0;
+ this.quickScrollLastEnabled = scrollHeight !== scrollTop + clientHeight;
+ }
+
private _cleanupAndRedrawManualAnnotations() {
this._fileDownloadService.loadActiveFileManualAnnotations().subscribe((manualRedactions) => {
this.fileData.manualRedactions = manualRedactions;
diff --git a/apps/red-ui/src/app/screens/project-overview-screen/project-overview-screen.component.html b/apps/red-ui/src/app/screens/project-overview-screen/project-overview-screen.component.html
index 871bb552a..876718855 100644
--- a/apps/red-ui/src/app/screens/project-overview-screen/project-overview-screen.component.html
+++ b/apps/red-ui/src/app/screens/project-overview-screen/project-overview-screen.component.html
@@ -213,7 +213,7 @@
-
+
{{ fileStatus.numberOfPages }}
diff --git a/apps/red-ui/src/app/screens/project-overview-screen/project-overview-screen.component.scss b/apps/red-ui/src/app/screens/project-overview-screen/project-overview-screen.component.scss
index ec491ef19..34b886b01 100644
--- a/apps/red-ui/src/app/screens/project-overview-screen/project-overview-screen.component.scss
+++ b/apps/red-ui/src/app/screens/project-overview-screen/project-overview-screen.component.scss
@@ -41,7 +41,7 @@ cdk-virtual-scroll-viewport {
max-width: 25vw;
}
- .pages {
+ .quick-navigation {
display: flex;
flex-direction: row;
align-items: center;
diff --git a/apps/red-ui/src/assets/i18n/en.json b/apps/red-ui/src/assets/i18n/en.json
index a777c282e..1f94de8db 100644
--- a/apps/red-ui/src/assets/i18n/en.json
+++ b/apps/red-ui/src/assets/i18n/en.json
@@ -306,7 +306,11 @@
"new-tab-ssr": "Open Document in Server Side Rendering Mode",
"html-debug": "Open Document HTML Debug",
"download-original-file": "Download Original File",
- "exit-fullscreen": "Exit Full Screen (F)"
+ "exit-fullscreen": "Exit Full Screen (F)",
+ "quick-nav": {
+ "jump-first": "Jump to first annotation",
+ "jump-last": "Jump to last annotation"
+ }
},
"annotation-actions": {
"message": {
diff --git a/apps/red-ui/src/assets/icons/general/nav-first.svg b/apps/red-ui/src/assets/icons/general/nav-first.svg
new file mode 100644
index 000000000..685ffebac
--- /dev/null
+++ b/apps/red-ui/src/assets/icons/general/nav-first.svg
@@ -0,0 +1,15 @@
+
+
diff --git a/apps/red-ui/src/assets/icons/general/nav-last.svg b/apps/red-ui/src/assets/icons/general/nav-last.svg
new file mode 100644
index 000000000..1c0697770
--- /dev/null
+++ b/apps/red-ui/src/assets/icons/general/nav-last.svg
@@ -0,0 +1,15 @@
+
+