diff --git a/apps/red-ui/src/app/app.module.ts b/apps/red-ui/src/app/app.module.ts
index b1a4976f2..54ed157a4 100644
--- a/apps/red-ui/src/app/app.module.ts
+++ b/apps/red-ui/src/app/app.module.ts
@@ -93,6 +93,7 @@ import { AdminBreadcrumbsComponent } from './components/admin-page-header/admin-
import { UserListingScreenComponent } from './screens/admin/users/user-listing-screen.component';
import { NotificationsComponent } from './components/notifications/notifications.component';
import { RulesScreenComponent } from './screens/admin/rules-screen/rules-screen.component';
+import { WatermarkScreenComponent } from './screens/admin/watermark-screen/watermark-screen.component';
export function HttpLoaderFactory(httpClient: HttpClient) {
return new TranslateHttpLoader(httpClient, '/assets/i18n/', '.json');
@@ -176,6 +177,14 @@ const routes = [
data: {
routeGuards: [AuthGuard, RedRoleGuard, AppStateGuard]
}
+ },
+ {
+ path: 'watermark',
+ component: WatermarkScreenComponent,
+ canActivate: [CompositeRouteGuard],
+ data: {
+ routeGuards: [AuthGuard, RedRoleGuard, AppStateGuard]
+ }
}
]
}
@@ -258,7 +267,8 @@ const matImports = [
AdminBreadcrumbsComponent,
UserListingScreenComponent,
NotificationsComponent,
- RulesScreenComponent
+ RulesScreenComponent,
+ WatermarkScreenComponent
],
imports: [
BrowserModule,
diff --git a/apps/red-ui/src/app/components/admin-page-header/admin-breadcrumbs.component.html b/apps/red-ui/src/app/components/admin-page-header/admin-breadcrumbs.component.html
index fbdb934f0..41b3ad694 100644
--- a/apps/red-ui/src/app/components/admin-page-header/admin-breadcrumbs.component.html
+++ b/apps/red-ui/src/app/components/admin-page-header/admin-breadcrumbs.component.html
@@ -26,6 +26,15 @@
*ngIf="screen === 'users' || root"
>
+
+
diff --git a/apps/red-ui/src/app/screens/admin/watermark-screen/watermark-screen.component.html b/apps/red-ui/src/app/screens/admin/watermark-screen/watermark-screen.component.html
new file mode 100644
index 000000000..5f8b64791
--- /dev/null
+++ b/apps/red-ui/src/app/screens/admin/watermark-screen/watermark-screen.component.html
@@ -0,0 +1,58 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/apps/red-ui/src/app/screens/admin/watermark-screen/watermark-screen.component.scss b/apps/red-ui/src/app/screens/admin/watermark-screen/watermark-screen.component.scss
new file mode 100644
index 000000000..7b3a81867
--- /dev/null
+++ b/apps/red-ui/src/app/screens/admin/watermark-screen/watermark-screen.component.scss
@@ -0,0 +1,25 @@
+.left-container {
+ width: calc(100vw - 353px);
+
+ .viewer {
+ height: 100%;
+ }
+}
+
+.right-container {
+ display: flex;
+ flex-direction: column;
+ width: 353px;
+ min-width: 353px;
+ padding: 25px;
+
+ .actions-container {
+ display: flex;
+ align-items: center;
+ margin-top: 24px;
+
+ button:first-child {
+ margin-right: 8px;
+ }
+ }
+}
diff --git a/apps/red-ui/src/app/screens/admin/watermark-screen/watermark-screen.component.ts b/apps/red-ui/src/app/screens/admin/watermark-screen/watermark-screen.component.ts
new file mode 100644
index 000000000..61c44355c
--- /dev/null
+++ b/apps/red-ui/src/app/screens/admin/watermark-screen/watermark-screen.component.ts
@@ -0,0 +1,126 @@
+import { ChangeDetectorRef, Component, ElementRef, OnInit, ViewChild } from '@angular/core';
+import { PermissionsService } from '../../../common/service/permissions.service';
+import WebViewer, { WebViewerInstance } from '@pdftron/webviewer';
+import { AppStateService } from '../../../state/app-state.service';
+import { FileDownloadService } from '../../file/service/file-download.service';
+import { environment } from '../../../../environments/environment';
+import { HttpClient } from '@angular/common/http';
+import { FormBuilder, FormGroup } from '@angular/forms';
+import { debounce } from '../../../utils/debounce';
+
+@Component({
+ selector: 'redaction-watermark-screen',
+ templateUrl: './watermark-screen.component.html',
+ styleUrls: ['./watermark-screen.component.scss']
+})
+export class WatermarkScreenComponent implements OnInit {
+ private _instance: WebViewerInstance;
+ private _initialConfig = {
+ text: 'Watermark',
+ color: '#000',
+ opacity: 50
+ };
+
+ @ViewChild('viewer', { static: true })
+ private _viewer: ElementRef;
+
+ public viewReady = false;
+ public configForm: FormGroup;
+
+ constructor(
+ public readonly permissionsService: PermissionsService,
+ public readonly appStateService: AppStateService,
+ private readonly _fileDownloadService: FileDownloadService,
+ private readonly _http: HttpClient,
+ private readonly _changeDetectorRef: ChangeDetectorRef,
+ private readonly _formBuilder: FormBuilder
+ ) {
+ this.configForm = this._formBuilder.group({
+ text: [this._initialConfig.text],
+ color: [this._initialConfig.color],
+ opacity: [this._initialConfig.opacity]
+ });
+ }
+
+ ngOnInit(): void {
+ this._loadViewer();
+ }
+
+ public get changed() {
+ for (const key of Object.keys(this._initialConfig)) {
+ if (this._initialConfig[key] !== this.configForm.get(key).value) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ private _loadViewer() {
+ WebViewer(
+ {
+ licenseKey: environment.licenseKey ? atob(environment.licenseKey) : null,
+ path: '/assets/wv-resources',
+ css: '/assets/pdftron/stylesheet.css'
+ },
+ this._viewer.nativeElement
+ ).then((instance) => {
+ this._instance = instance;
+
+ instance.docViewer.on('documentLoaded', () => {
+ this.viewReady = true;
+ this._changeDetectorRef.detectChanges();
+ });
+
+ this._disableElements();
+ this._drawWatermark();
+
+ this._instance.loadDocument(`${window.location.origin}/assets/pdftron/sample.pdf`);
+ });
+ }
+
+ private _disableElements() {
+ this._instance.disableElements(['header', 'toolsHeader', 'pageNavOverlay', 'textPopup']);
+ }
+
+ private _drawWatermark() {
+ this._instance.docViewer.setWatermark({
+ // Draw diagonal watermark in middle of the document
+ diagonal: {
+ fontSize: 25, // or even smaller size
+ fontFamily: 'sans-serif',
+ color: 'red',
+ opacity: 50, // from 0 to 100
+ text: 'Watermark'
+ }
+ });
+ }
+
+ @debounce()
+ public configChanged() {
+ this._instance.docViewer.setWatermark({
+ // Draw diagonal watermark in middle of the document
+ diagonal: {
+ fontSize: 30,
+ fontFamily: 'sans-serif',
+ color: this.configForm.get('color').value,
+ opacity: this.configForm.get('opacity').value, // from 0 to 100
+ text: this.configForm.get('text').value
+ }
+ });
+
+ this._instance.docViewer.refreshAll();
+ this._instance.docViewer.updateView([0], 0);
+ }
+
+ public save() {
+ this._initialConfig = {
+ ...this.configForm.getRawValue()
+ };
+ }
+
+ public revert() {
+ this.configForm.setValue(this._initialConfig);
+ this.configChanged();
+ }
+}
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 a2351e021..ddd137db2 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
@@ -21,12 +21,6 @@
.left-container {
position: relative;
- .overlay-shadow {
- @include inset-shadow;
- position: absolute;
- width: 100%;
- height: 1px;
- }
width: calc(100vw - 350px);
}
diff --git a/apps/red-ui/src/assets/i18n/en.json b/apps/red-ui/src/assets/i18n/en.json
index 6ebd3bb9d..f1fe91c61 100644
--- a/apps/red-ui/src/assets/i18n/en.json
+++ b/apps/red-ui/src/assets/i18n/en.json
@@ -566,6 +566,12 @@
"save-changes": "Save Changes",
"revert-changes": "Revert"
},
+ "watermark-screen": {
+ "action": {
+ "save": "Save",
+ "revert": "Revert"
+ }
+ },
"dictionaries": "Dictionaries",
"user-management": "User Management",
"notifications": {
@@ -575,5 +581,6 @@
"mark-read": "Mark as read",
"mark-unread": "Mark as unread"
},
- "rule-editor": "Rule Editor"
+ "rule-editor": "Rule Editor",
+ "watermark": "Watermark"
}
diff --git a/apps/red-ui/src/assets/pdftron/sample.pdf b/apps/red-ui/src/assets/pdftron/sample.pdf
new file mode 100644
index 000000000..22ace57cd
Binary files /dev/null and b/apps/red-ui/src/assets/pdftron/sample.pdf differ
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 88a71654a..d305a451a 100644
--- a/apps/red-ui/src/assets/styles/red-page-layout.scss
+++ b/apps/red-ui/src/assets/styles/red-page-layout.scss
@@ -68,6 +68,13 @@ body {
&.extended {
width: calc(100vw - 60px) !important;
}
+
+ .overlay-shadow {
+ @include inset-shadow;
+ position: absolute;
+ width: 100%;
+ height: 4px;
+ }
}
.right-container {