Product: @pdftron/webviewer
Product Version:^11.7.1
Below is my code. I added new buttons to header, in dark mode those icons are not visible.
ngAfterViewInit() {
const baseHref = this.platformLocation.getBaseHrefFromDOM();
WebViewer({
path: baseHref + 'lib/webviewer',
licenseKey: this.commonService.aspyreKey,
initialDoc: '',
// enableFilePicker: true,
fullAPI: true,
css: 'assets/css/webviewer-docview.css'
}, this.viewer.nativeElement).then(instance => {
this.viewerInstance = instance;
const { UI, Core } = instance;
const { Annotations, annotationManager, documentViewer, Tools } = Core;
const { Feature } = instance.UI;
// instance.UI.disableFeatures(\[Feature.FilePicker\]);
// instance.UI.disableTools(\[Tools.ToolNames.STAMP\]);
// instance.UI.disableTools(\[Tools.ToolNames.ARROW\]);
UI.setToolbarGroup('toolbarGroup-View');
UI.disableElements(\[
'toolbarGroup-View', // entire View menu
'toolbarGroup-Edit', // entire Edit menu
'toolbarGroup-Annotate', // entire Annotate menu
'toolbarGroup-FillAndSign',
'toolbarGroup-Shapes',
'toolbarGroup-Insert',
'menuOverlay', // context menu
'downloadButton', // single button
'toolbarGroup-Edit',
'toolbarGroup-Forms',
'panToolButton',
// this.viewerInstance.UI.Feature.FilePicker
// 'textSelectButton',
\]);
if(this.docBlob){
this.viewerInstance.UI.loadDocument(this.docBlob);
this.docBlob = '';
}
this.viewerInstance.Core.documentViewer.addEventListener('documentLoaded', async () => {
UI.setToolbarGroup('toolbarGroup-View');
const readUserInfo: any = this.commonService.getItem('userInfo');
const userInfo = JSON.parse(readUserInfo);
this.viewerInstance.Core.annotationManager.setCurrentUser(userInfo\[0\]\["FullName"\]);
if (this.showCustomActions) {
let allButtonConfigs: Record<string, any> = {}
if(!this.recordSecureHold){
allButtonConfigs = {
addTask: { name: 'TaskCompletionAssignTask', title: 'Add Task', img: 'assets/images/book.svg', onClick: () => this.addDoctask() },
addRecordTask: { name: 'TaskCompletionAssignTask', title: 'Add Record Task', img: 'assets/images/list.svg', onClick: () => this.addRecordtask() },
// newDocument: { title: 'Add New Document', img: 'assets/images/file-plus.svg', onClick: () => console.log('') },
// keyEdit: { title: 'Key Edit', img: 'assets/images/key.svg', onClick: () => this.keyEdit() },
showNotes: { name: 'DocNotesView,NotesAdminView', title: 'Hide/Show Documents Notes', img: 'assets/images/file-o.svg', onClick: () => this.docAction('showNotes') },
save: { name: 'Save', title: 'Save', img: 'assets/images/save.svg', onClick: () => this.saveDocument() },
delete: { name: 'DocDelete', title: 'Delete Document', img: 'assets/images/trash.svg', onClick: () => this.docAction('delete') },
// auditTrail: { title: 'View Audit Trail', img: 'assets/images/list-check.svg', onClick: () => this.docAction('auditTrail') },
indexing: {name:'DocSendToIndexing', title: 'Send To Indexing', img: 'assets/images/receipt.svg', onClick: () => this.docAction('indexing') },
problemQueuee: {name:'DocSendToProblemQ', title: 'Send To Problem Queue', img: 'assets/images/verified.svg', onClick: () => this.docAction('problemQueuee') },
workflow: {name:'DocSendToWorkflowQ', title: 'Send To Workflow', img: 'assets/images/list-check.svg', onClick: () => this.docAction('workflow') },
anotherRecord: {name:'DocSendToAnotherRecord', title: 'Send To Another Record', img: 'assets/images/sitemap.svg', onClick: () => this.docAction('anotherRecord') },
fax: { name: 'DocFax', title: 'Fax', img: 'assets/images/send.svg', onClick: () => this.docAction('fax') },
email: { name: 'DocEmail', title: 'Email', img: 'assets/images/envelope.svg', onClick: () => this.docAction('email') },
changeDocType: { name: 'DocChangeType', title: 'Change Document Type', img: 'assets/images/directions.svg', onClick: () => this.docAction('changeDocType') },
indexingWorkflow: { name: 'Workflow', title: 'Indexing Workflow', img: 'assets/images/file-plus.svg', onClick: () => this.docAction('indexingWorkflow') },
};
}
else{
allButtonConfigs = {
fax: { name: 'DocFax', title: 'Fax', img: 'assets/images/send.svg', onClick: () => this.docAction('fax') },
email: { name: 'DocEmail', title: 'Email', img: 'assets/images/envelope.svg', onClick: () => this.docAction('email') },
};
}
let buttonsToAdd = \[...this.customButtons\];
//Check General permission
const buttonConfigs: Record<string, any> = {};
for (const \[key, config\] of Object.entries(allButtonConfigs)) {
const actionName = config.name || key;
if (this.commonService.hasGeneralPermission(actionName) || actionName == 'Save') {
buttonConfigs\[key\] = config;
}
}
if (this.recordSecureHold || this.isDocSecureHold) {
buttonsToAdd = this.customButtons.filter(
(btn: any) => btn !== 'workflow' && btn !== 'indexingWorkflow'
);
}
// Remove button if condition is false
if (!this.indexWorkflowVisible) {
buttonsToAdd = buttonsToAdd.filter((btn : any) => btn !== 'indexingWorkflow');
}
const customButtonInstances = buttonsToAdd
.filter((btn: any) => !this.notRequiredAction.includes(btn))
.filter((btn: any) => buttonConfigs\[btn\])
.map((btn: any) =>
new UI.Components.CustomButton({
dataElement: btn,
...buttonConfigs\[btn\],
})
);
// Get the modula \*/
// const header = UI.getModularHeader('default-top-header');
// // Existing items in header
// const existing = header.getItems();
// // Append your buttons
// header.setItems(\[
// ...existing, ...customButtonInstances
// \]);
const header = UI.getModularHeader('default-top-header');
// Remove previously added custom buttons
const cleanedItems = header.getItems().filter((item: any) =>
!this.customButtons.includes(item.dataElement)
);
// Add fresh buttons
header.setItems(\[
...cleanedItems,
...customButtonInstances
\]);
if (!this.recordSecureHold) {
if (this.commonService.hasGeneralPermission('DocEdit')) {
UI.enableFeatures(\[
UI.Feature.Redaction, UI.Feature.ContentEdit, UI.Feature.Annotations
\])
UI.enableElements(\[
'toolbarGroup-View', // entire View menu
'toolbarGroup-Edit', // entire Edit menu
'toolbarGroup-Annotate', // entire Annotate menu
'toolbarGroup-FillAndSign',
'toolbarGroup-Shapes',
'toolbarGroup-Insert',
'menuOverlay', // context menu
'toolbarGroup-Edit',
'toolbarGroup-Forms',
'panToolButton',
\]);
}
}
if (this.commonService.hasGeneralPermission('DocDownload')) {
UI.enableElements(\[
'downloadButton'
\])
}
if (!this.commonService.hasGeneralPermission('DocPrint')) {
UI.disableElements(\[
'printButton'
\])
}
this.getStamps();
}
});
documentViewer.addEventListener('mouseLeftDown', e => {
if(this.addNewtask){
try {
this.stamData = {};
const rect = documentViewer.getViewerCoordinatesFromMouseEvent(e)
this.startX = rect.x;
this.startY = rect.y;
const pageNumber = documentViewer.getCurrentPage();
this.stamData = {
PageNumber: pageNumber,
X: this.startX,
Y: this.startY,
Width: this.width,
Height: this.height,
TextAlign: 'center',
TextVerticalAlign: 'center',
FontSize: '32pt',
}
} catch (err) {
return;
}
}
});
// mouse up
documentViewer.addEventListener('mouseLeftUp', e => {
if(this.addNewtask){
let pageCoords;
try {
pageCoords = documentViewer.getViewerCoordinatesFromMouseEvent(e)
} catch (err) {
return;
}
if (!pageCoords) {
return;
}
this.endX = pageCoords.x;
this.endY = pageCoords.y;
// calculate rectangle bounds
this.width = Math.abs(this.startX - this.endX);
this.height = Math.abs(this.startY - this.endY);
this.stamData\['Width'\] = this.width;
this.stamData\['Height'\] = this.height;
if(this.width > 0)
this.addDoctask();
}
});
// 🔹 Detect stamp delete (use annotationChanged with action = delete)
annotationManager.addEventListener('annotationChanged', (annotations: any\[\], action: string) => {
if(this.annotationAddedProgramatically)
this.annotationAddedProgramatically = false;
if (action === 'delete') {
annotations.forEach(annot => {
if (annot instanceof Annotations.FreeTextAnnotation && !this.deletingStampForSave) {
this.deleteTask(annotations\[0\].Id);
}
});
}
if (action === 'add') {
annotations.forEach((annot: any) => {
if (annot instanceof this.viewerInstance.Core.Annotations.FreeTextAnnotation) {
// this.addUserHeader(annot);
}
});
}
});
annotationManager.addEventListener('annotationSelected', (annotations, action) => {
if(annotations\[0\] instanceof this.viewerInstance.Core.Annotations.FreeTextAnnotation && action=='selected'){
if (annotations\[0\] && annotations\[0\].Id && typeof annotations\[0\].Id == 'number' && !this.taskAdded) {
console.log(annotations\[0\].Id);
this.onTaskRowSelect(this.stamList.find((el: any) => el.TaskID == annotations\[0\].Id))
}
}
});
// documentViewer.addEventListener('rotationUpdated', (pageIndex, rotation) => {
// // this.syncViewerRotationToDocument();
// this.annotationAddedProgramatically = false;
// this.rotationMap\[pageIndex + 1\] = rotation / 90;
// });
documentViewer.addEventListener('rotationUpdated', async () => {
// We fire the process, but the main logic is deferred to a function that guarantees completion
// await this.synchronizeRotationsAndDownload(instance);
this.annotationAddedProgramatically = false;
});
instance.UI.addEventListener('toolbarGroupChanged', (e) => {
// if(e?.detail != 'toolbarGroup-View')
// setTimeout(() => {
// const { UI} = this.viewerInstance;
// UI.setToolbarGroup('toolbarGroup-View');
// }, 500);
});
})
}
