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 {