Text watermark config

This commit is contained in:
Adina Țeudan 2020-12-10 17:12:54 +02:00
parent 213d51c23b
commit da2803f446
9 changed files with 244 additions and 8 deletions

View File

@ -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,

View File

@ -26,6 +26,15 @@
*ngIf="screen === 'users' || root"
></a>
<a
class="ml-32 breadcrumb"
[routerLink]="'/ui/admin/watermark'"
[routerLinkActiveOptions]="{ exact: true }"
routerLinkActive="active"
translate="watermark"
*ngIf="screen === 'watermark' || root"
></a>
<ng-container *ngIf="dictionary">
<mat-icon svgIcon="red:arrow-right"></mat-icon>
<a class="breadcrumb" [routerLink]="'/ui/admin/dictionaries/' + dictionary.type" routerLinkActive="active">

View File

@ -0,0 +1,58 @@
<section>
<div class="page-header">
<redaction-admin-breadcrumbs class="flex-1"></redaction-admin-breadcrumbs>
<div class="actions">
<redaction-circle-button
class="ml-6"
*ngIf="permissionsService.isUser()"
[routerLink]="['/ui/projects/']"
tooltip="common.close"
tooltipPosition="before"
icon="red:close"
></redaction-circle-button>
</div>
</div>
<div class="red-content-inner">
<div class="left-container">
<div class="overlay-shadow"></div>
<div #viewer class="viewer"></div>
</div>
<div class="right-container">
<form [formGroup]="configForm" (keyup)="configChanged()">
<div class="red-input-group">
<label translate="Text"></label>
<input formControlName="text" name="text" type="text" />
</div>
<div class="red-input-group">
<label translate="Color"></label>
<input formControlName="color" name="color" type="text" placeholder="{{ 'add-edit-dictionary.form.color-placeholder' | translate }}" />
<div
class="input-icon"
[colorPicker]="configForm.get('color').value"
[cpOutputFormat]="'hex'"
(colorPickerChange)="configForm.get('color').setValue($event); configChanged()"
>
<mat-icon svgIcon="red:color-picker"></mat-icon>
</div>
</div>
<div class="red-input-group">
<label translate="Opacity"></label>
<input formControlName="opacity" name="opacity" type="number" (change)="configChanged()" />
</div>
</form>
<div class="actions-container">
<button color="primary" mat-flat-button (click)="save()" [disabled]="!changed" class="red-button">
{{ 'watermark-screen.action.save' | translate }}
</button>
<div class="all-caps-label pointer" (click)="revert()" [translate]="'watermark-screen.action.revert'"></div>
</div>
</div>
</div>
</section>
<redaction-full-page-loading-indicator [displayed]="!viewReady"></redaction-full-page-loading-indicator>

View File

@ -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;
}
}
}

View File

@ -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();
}
}

View File

@ -21,12 +21,6 @@
.left-container {
position: relative;
.overlay-shadow {
@include inset-shadow;
position: absolute;
width: 100%;
height: 1px;
}
width: calc(100vw - 350px);
}

View File

@ -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"
}

Binary file not shown.

View File

@ -68,6 +68,13 @@ body {
&.extended {
width: calc(100vw - 60px) !important;
}
.overlay-shadow {
@include inset-shadow;
position: absolute;
width: 100%;
height: 4px;
}
}
.right-container {