2017-11-27 11:15:10 +00:00
/ *
*
2019-01-17 13:05:03 +00:00
* ( c ) Copyright Ascensio System SIA 2010 - 2019
2017-11-27 11:15:10 +00:00
*
* This program is a free software product . You can redistribute it and / or
* modify it under the terms of the GNU Affero General Public License ( AGPL )
* version 3 as published by the Free Software Foundation . In accordance with
* Section 7 ( a ) of the GNU AGPL its Section 15 shall be amended to the effect
* that Ascensio System SIA expressly excludes the warranty of non - infringement
* of any third - party rights .
*
* This program is distributed WITHOUT ANY WARRANTY ; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . For
* details , see the GNU AGPL at : http : //www.gnu.org/licenses/agpl-3.0.html
*
2019-01-17 13:00:34 +00:00
* You can contact Ascensio System SIA at 20 A - 12 Ernesta Birznieka - Upisha
* street , Riga , Latvia , EU , LV - 1050.
2017-11-27 11:15:10 +00:00
*
* The interactive user interfaces in modified source and object code versions
* of the Program must display Appropriate Legal Notices , as required under
* Section 5 of the GNU AGPL version 3.
*
* Pursuant to Section 7 ( b ) of the License you must retain the original Product
* logo when distributing the program . Pursuant to Section 7 ( e ) we decline to
* grant you any rights under trademark law for use of our trademarks .
*
* All the Product ' s GUI elements , including illustrations and icon sets , as
* well as technical writing content are licensed under the terms of the
* Creative Commons Attribution - ShareAlike 4.0 International . See the License
* terms at http : //creativecommons.org/licenses/by-sa/4.0/legalcode
*
* /
/ * *
* SignatureSettings . js
*
* Created by Julia Radzhabova on 5 / 24 / 17
2018-03-01 12:16:38 +00:00
* Copyright ( c ) 2018 Ascensio System SIA . All rights reserved .
2017-11-27 11:15:10 +00:00
*
* /
define ( [
'text!documenteditor/main/app/template/SignatureSettings.template' ,
'jquery' ,
'underscore' ,
'backbone' ,
2017-11-17 08:44:36 +00:00
'common/main/lib/component/Button'
2017-11-27 11:15:10 +00:00
] , function ( menuTemplate , $ , _ , Backbone ) {
'use strict' ;
DE . Views . SignatureSettings = Backbone . View . extend ( _ . extend ( {
el : '#id-signature-settings' ,
// Compile our stats template
template : _ . template ( menuTemplate ) ,
// Delegated events for creating new items, and clearing completed ones.
events : {
} ,
options : {
alias : 'SignatureSettings'
} ,
initialize : function ( ) {
this . _state = {
2017-11-10 12:44:12 +00:00
DisabledEditing : false ,
2017-11-21 08:34:38 +00:00
ready : false ,
hasValid : false ,
hasInvalid : false ,
hasRequested : false ,
tip : undefined
2017-11-27 11:15:10 +00:00
} ;
this . _locked = false ;
this . render ( ) ;
} ,
render : function ( ) {
this . $el . html ( this . template ( {
scope : this
} ) ) ;
2017-11-28 12:29:14 +00:00
var protection = DE . getController ( 'Common.Controllers.Protection' ) . getView ( ) ;
this . btnAddInvisibleSign = protection . getButton ( 'signature' ) ;
this . btnAddInvisibleSign . render ( this . $el . find ( '#signature-invisible-sign' ) ) ;
2017-11-27 11:15:10 +00:00
2017-11-16 13:06:55 +00:00
this . viewRequestedList = new Common . UI . DataView ( {
el : $ ( '#signature-requested-sign' ) ,
enableKeyEvents : false ,
itemTemplate : _ . template ( [
'<div id="<%= id %>" class="signature-item requested">' ,
2017-11-21 08:34:38 +00:00
'<div class="caret img-commonctrl nomargin"></div>' ,
2017-11-17 13:11:40 +00:00
'<div class="name"><%= Common.Utils.String.htmlEncode(name) %></div>' ,
2017-11-16 13:06:55 +00:00
'</div>'
] . join ( '' ) )
} ) ;
this . viewValidList = new Common . UI . DataView ( {
el : $ ( '#signature-valid-sign' ) ,
enableKeyEvents : false ,
itemTemplate : _ . template ( [
'<div id="<%= id %>" class="signature-item">' ,
2017-11-21 08:34:38 +00:00
'<div class="caret img-commonctrl <% if (name == "" || date == "") { %>' + 'nomargin' + '<% } %>"></div>' ,
2017-11-17 13:11:40 +00:00
'<div class="name"><%= Common.Utils.String.htmlEncode(name) %></div>' ,
'<div class="date"><%= Common.Utils.String.htmlEncode(date) %></div>' ,
2017-11-16 13:06:55 +00:00
'</div>'
] . join ( '' ) )
} ) ;
this . viewInvalidList = new Common . UI . DataView ( {
el : $ ( '#signature-invalid-sign' ) ,
enableKeyEvents : false ,
itemTemplate : _ . template ( [
'<div id="<%= id %>" class="signature-item">' ,
2017-11-21 08:34:38 +00:00
'<div class="caret img-commonctrl <% if (name == "" || date == "") { %>' + 'nomargin' + '<% } %>"></div>' ,
2017-11-17 13:11:40 +00:00
'<div class="name"><%= Common.Utils.String.htmlEncode(name) %></div>' ,
'<div class="date"><%= Common.Utils.String.htmlEncode(date) %></div>' ,
2017-11-16 13:06:55 +00:00
'</div>'
] . join ( '' ) )
} ) ;
2017-10-23 07:26:38 +00:00
2017-11-16 13:06:55 +00:00
this . viewRequestedList . on ( 'item:click' , _ . bind ( this . onSelectSignature , this ) ) ;
this . viewValidList . on ( 'item:click' , _ . bind ( this . onSelectSignature , this ) ) ;
this . viewInvalidList . on ( 'item:click' , _ . bind ( this . onSelectSignature , this ) ) ;
2018-05-08 12:02:48 +00:00
this . viewRequestedList . on ( 'item:contextmenu' , _ . bind ( this . onItemContextMenu , this ) ) ;
this . viewValidList . on ( 'item:contextmenu' , _ . bind ( this . onItemContextMenu , this ) ) ;
this . viewInvalidList . on ( 'item:contextmenu' , _ . bind ( this . onItemContextMenu , this ) ) ;
2017-11-16 13:06:55 +00:00
this . signatureMenu = new Common . UI . Menu ( {
menuAlign : 'tr-br' ,
items : [
{ caption : this . strSign , value : 0 } ,
{ caption : this . strDetails , value : 1 } ,
{ caption : this . strSetup , value : 2 } ,
{ caption : this . strDelete , value : 3 }
]
} ) ;
this . signatureMenu . on ( 'item:click' , _ . bind ( this . onMenuSignatureClick , this ) ) ;
2017-11-27 11:15:10 +00:00
} ,
setApi : function ( api ) {
this . api = api ;
if ( this . api ) {
2017-11-10 12:44:12 +00:00
this . api . asc _registerCallback ( 'asc_onUpdateSignatures' , _ . bind ( this . onApiUpdateSignatures , this ) ) ;
2017-11-27 11:15:10 +00:00
}
2017-11-28 11:20:54 +00:00
Common . NotificationCenter . on ( 'document:ready' , _ . bind ( this . onDocumentReady , this ) ) ;
2017-11-27 11:15:10 +00:00
return this ;
} ,
ChangeSettings : function ( props ) {
2017-11-21 08:34:38 +00:00
if ( ! this . _state . hasRequested && ! this . _state . hasValid && ! this . _state . hasInvalid )
2017-11-10 12:44:12 +00:00
this . updateSignatures ( this . api . asc _getSignatures ( ) , this . api . asc _getRequestSignatures ( ) ) ;
2017-11-27 11:15:10 +00:00
} ,
setLocked : function ( locked ) {
this . _locked = locked ;
} ,
setMode : function ( mode ) {
this . mode = mode ;
} ,
2017-11-10 12:44:12 +00:00
onApiUpdateSignatures : function ( valid , requested ) {
if ( ! this . _state . ready ) return ;
this . updateSignatures ( valid , requested ) ;
2017-11-21 08:34:38 +00:00
this . showSignatureTooltip ( this . _state . hasValid , this . _state . hasInvalid ) ;
2017-11-10 12:44:12 +00:00
} ,
updateSignatures : function ( valid , requested ) {
2017-11-21 08:34:38 +00:00
var me = this ,
requestedSignatures = [ ] ,
validSignatures = [ ] ,
2017-11-30 10:43:47 +00:00
invalidSignatures = [ ] ,
name _index = 1 ;
2017-11-27 11:15:10 +00:00
_ . each ( requested , function ( item , index ) {
2017-11-30 10:43:47 +00:00
var name = item . asc _getSigner1 ( ) ;
requestedSignatures . push ( { name : ( name !== "" ) ? name : ( me . strSigner + " " + name _index ++ ) , guid : item . asc _getGuid ( ) , requested : true } ) ;
2017-11-27 11:15:10 +00:00
} ) ;
_ . each ( valid , function ( item , index ) {
2017-11-21 08:34:38 +00:00
var item _date = item . asc _getDate ( ) ;
var sign = { name : item . asc _getSigner1 ( ) , certificateId : item . asc _getId ( ) , guid : item . asc _getGuid ( ) , date : ( ! _ . isEmpty ( item _date ) ) ? new Date ( item _date ) . toLocaleString ( ) : '' , invisible : ! item . asc _getVisible ( ) } ;
( item . asc _getValid ( ) == 0 ) ? validSignatures . push ( sign ) : invalidSignatures . push ( sign ) ;
2017-11-27 11:15:10 +00:00
} ) ;
2017-11-28 11:20:54 +00:00
2017-11-21 08:34:38 +00:00
// requestedSignatures = [{name: 'Hammish Mitchell', guid: '123', requested: true}, {name: 'Someone Somewhere', guid: '123', requested: true}, {name: 'Mary White', guid: '123', requested: true}, {name: 'John Black', guid: '123', requested: true}];
// validSignatures = [{name: 'Hammish Mitchell', guid: '123', date: '18/05/2017', invisible: true}, {name: 'Someone Somewhere', guid: '345', date: '18/05/2017'}];
// invalidSignatures = [{name: 'Mary White', guid: '111', date: '18/05/2017'}, {name: 'John Black', guid: '456', date: '18/05/2017'}];
me . _state . hasValid = validSignatures . length > 0 ;
me . _state . hasInvalid = invalidSignatures . length > 0 ;
me . _state . hasRequested = requestedSignatures . length > 0 ;
2017-11-28 11:20:54 +00:00
2017-11-21 08:34:38 +00:00
this . viewRequestedList . store . reset ( requestedSignatures ) ;
this . viewValidList . store . reset ( validSignatures ) ;
this . viewInvalidList . store . reset ( invalidSignatures ) ;
2017-11-27 11:15:10 +00:00
2017-11-21 08:34:38 +00:00
this . $el . find ( '.requested' ) . toggleClass ( 'hidden' , ! me . _state . hasRequested ) ;
this . $el . find ( '.valid' ) . toggleClass ( 'hidden' , ! me . _state . hasValid ) ;
this . $el . find ( '.invalid' ) . toggleClass ( 'hidden' , ! me . _state . hasInvalid ) ;
2017-11-10 12:44:12 +00:00
2017-11-21 08:34:38 +00:00
me . disableEditing ( me . _state . hasValid || me . _state . hasInvalid ) ;
2017-11-27 11:15:10 +00:00
} ,
2018-05-08 12:02:48 +00:00
onItemContextMenu : function ( picker , item , record , e ) {
var menu = this . signatureMenu ;
if ( menu . isVisible ( ) ) {
menu . hide ( ) ;
}
var offsetParent = $ ( this . el ) . offset ( ) ,
showPoint = [ e . clientX * Common . Utils . zoom ( ) - offsetParent . left + 5 , e . clientY * Common . Utils . zoom ( ) - offsetParent . top + 5 ] ;
this . showSignatureMenu ( record , showPoint ) ;
menu . menuAlign = 'tl-bl' ;
menu . menuAlignEl = null ;
menu . setOffset ( 15 , 5 ) ;
menu . show ( ) ;
_ . delay ( function ( ) {
menu . cmpEl . focus ( ) ;
} , 10 ) ;
} ,
2017-11-16 13:06:55 +00:00
onSelectSignature : function ( picker , item , record , e ) {
if ( ! record ) return ;
2017-11-27 11:15:10 +00:00
2017-11-16 13:06:55 +00:00
var btn = $ ( e . target ) ;
if ( btn && btn . hasClass ( 'caret' ) ) {
var menu = this . signatureMenu ;
if ( menu . isVisible ( ) ) {
menu . hide ( ) ;
return ;
}
2017-11-27 11:15:10 +00:00
2018-05-08 12:02:48 +00:00
var currentTarget = $ ( e . currentTarget ) ,
2017-11-16 13:06:55 +00:00
offset = currentTarget . offset ( ) ,
2018-05-08 12:02:48 +00:00
offsetParent = $ ( this . el ) . offset ( ) ,
showPoint = [ offset . left - offsetParent . left + currentTarget . width ( ) , offset . top - offsetParent . top + currentTarget . height ( ) / 2 ] ;
2017-11-20 11:06:23 +00:00
2018-05-08 12:02:48 +00:00
this . showSignatureMenu ( record , showPoint ) ;
2017-11-16 13:06:55 +00:00
2018-05-08 12:02:48 +00:00
menu . menuAlign = 'tr-br' ;
2017-11-16 13:06:55 +00:00
menu . menuAlignEl = currentTarget ;
menu . setOffset ( - 20 , - currentTarget . height ( ) / 2 + 3 ) ;
menu . show ( ) ;
_ . delay ( function ( ) {
menu . cmpEl . focus ( ) ;
} , 10 ) ;
e . stopPropagation ( ) ;
e . preventDefault ( ) ;
} else {
this . api . asc _gotoSignature ( record . get ( 'guid' ) ) ;
}
} ,
2017-11-27 11:15:10 +00:00
2018-05-08 12:02:48 +00:00
showSignatureMenu : function ( record , showPoint ) {
2021-02-19 08:43:17 +00:00
this . api . asc _gotoSignature ( record . get ( 'guid' ) ) ;
2018-05-08 12:02:48 +00:00
var menu = this . signatureMenu ,
parent = $ ( this . el ) ,
menuContainer = parent . find ( '#menu-signature-container' ) ;
if ( ! menu . rendered ) {
if ( menuContainer . length < 1 ) {
menuContainer = $ ( '<div id="menu-signature-container" style="position: absolute; z-index: 10000;"><div class="dropdown-toggle" data-toggle="dropdown"></div></div>' , menu . id ) ;
parent . append ( menuContainer ) ;
}
menu . render ( menuContainer ) ;
menu . cmpEl . attr ( { tabindex : "-1" } ) ;
menu . on ( {
'show:after' : function ( cmp ) {
if ( cmp && cmp . menuAlignEl )
cmp . menuAlignEl . toggleClass ( 'over' , true ) ;
} ,
'hide:after' : function ( cmp ) {
if ( cmp && cmp . menuAlignEl )
cmp . menuAlignEl . toggleClass ( 'over' , false ) ;
}
} ) ;
}
var requested = record . get ( 'requested' ) ,
signed = ( this . _state . hasValid || this . _state . hasInvalid ) ;
menu . items [ 0 ] . setVisible ( requested ) ;
menu . items [ 1 ] . setVisible ( ! requested ) ;
menu . items [ 2 ] . setVisible ( requested || ! record . get ( 'invisible' ) ) ;
menu . items [ 3 ] . setVisible ( ! requested ) ;
menu . items [ 0 ] . setDisabled ( this . _locked ) ;
menu . items [ 3 ] . setDisabled ( this . _locked ) ;
menu . items [ 1 ] . cmpEl . attr ( 'data-value' , record . get ( 'certificateId' ) ) ; // view certificate
menu . items [ 2 ] . cmpEl . attr ( 'data-value' , signed ? 1 : 0 ) ; // view or edit signature settings
menu . cmpEl . attr ( 'data-value' , record . get ( 'guid' ) ) ;
menuContainer . css ( { left : showPoint [ 0 ] , top : showPoint [ 1 ] } ) ;
} ,
2017-11-16 13:06:55 +00:00
onMenuSignatureClick : function ( menu , item ) {
var guid = menu . cmpEl . attr ( 'data-value' ) ;
switch ( item . value ) {
case 0 :
Common . NotificationCenter . trigger ( 'protect:sign' , guid ) ;
break ;
case 1 :
2017-11-20 11:06:23 +00:00
this . api . asc _ViewCertificate ( item . cmpEl . attr ( 'data-value' ) ) ;
2017-11-16 13:06:55 +00:00
break ;
case 2 :
Common . NotificationCenter . trigger ( 'protect:signature' , 'visible' , ! ! parseInt ( item . cmpEl . attr ( 'data-value' ) ) , guid ) ; // can edit settings for requested signature
break ;
case 3 :
2021-03-04 09:48:15 +00:00
var me = this ;
Common . UI . warning ( {
title : this . notcriticalErrorTitle ,
msg : this . txtRemoveWarning ,
buttons : [ 'ok' , 'cancel' ] ,
primary : 'ok' ,
callback : function ( btn ) {
if ( btn == 'ok' ) {
me . api . asc _RemoveSignature ( guid ) ;
}
}
} ) ;
2017-11-16 13:06:55 +00:00
break ;
}
2017-11-27 11:15:10 +00:00
} ,
2017-11-28 11:20:54 +00:00
onDocumentReady : function ( ) {
2017-11-10 12:44:12 +00:00
this . _state . ready = true ;
2017-11-28 11:20:54 +00:00
2017-11-10 12:44:12 +00:00
this . updateSignatures ( this . api . asc _getSignatures ( ) , this . api . asc _getRequestSignatures ( ) ) ;
2017-11-21 08:34:38 +00:00
this . showSignatureTooltip ( this . _state . hasValid , this . _state . hasInvalid , this . _state . hasRequested ) ;
2017-11-10 12:44:12 +00:00
} ,
2017-11-28 11:20:54 +00:00
2017-11-28 12:29:14 +00:00
showSignatureTooltip : function ( hasValid , hasInvalid , hasRequested ) {
2017-11-21 08:34:38 +00:00
var me = this ,
tip = me . _state . tip ;
2017-11-28 12:29:14 +00:00
2017-11-21 08:34:38 +00:00
if ( ! hasValid && ! hasInvalid && ! hasRequested ) {
if ( tip && tip . isVisible ( ) ) {
tip . close ( ) ;
me . _state . tip = undefined ;
}
return ;
}
var showLink = hasValid || hasInvalid ,
tipText = ( hasInvalid ) ? me . txtSignedInvalid : ( hasValid ? me . txtSigned : "" ) ;
2017-11-28 12:29:14 +00:00
if ( hasRequested )
2017-11-21 08:34:38 +00:00
tipText = me . txtRequestedSignatures + "<br><br>" + tipText ;
2017-11-28 11:20:54 +00:00
2017-11-21 08:34:38 +00:00
if ( tip && tip . isVisible ( ) && ( tipText !== tip . text || showLink !== tip . showLink ) ) {
tip . close ( ) ;
me . _state . tip = undefined ;
}
if ( ! me . _state . tip ) {
2017-11-10 12:44:12 +00:00
tip = new Common . UI . SynchronizeTip ( {
2017-11-28 11:20:54 +00:00
target : DE . getController ( 'RightMenu' ) . getView ( 'RightMenu' ) . btnSignature . btnEl ,
2017-11-28 12:29:14 +00:00
text : tipText ,
2017-11-21 08:34:38 +00:00
showLink : showLink ,
2017-11-28 11:20:54 +00:00
textLink : this . txtContinueEditing ,
2021-02-17 17:25:30 +00:00
placement : 'left-bottom'
2017-11-28 11:20:54 +00:00
} ) ;
2017-11-21 08:34:38 +00:00
tip . on ( {
'dontshowclick' : function ( ) {
Common . UI . warning ( {
title : me . notcriticalErrorTitle ,
msg : me . txtEditWarning ,
buttons : [ 'ok' , 'cancel' ] ,
primary : 'ok' ,
callback : function ( btn ) {
if ( btn == 'ok' ) {
tip . close ( ) ;
me . _state . tip = undefined ;
me . api . asc _RemoveAllSignatures ( ) ;
}
2017-11-28 12:29:14 +00:00
}
2017-11-21 08:34:38 +00:00
} ) ;
} ,
'closeclick' : function ( ) {
tip . close ( ) ;
me . _state . tip = undefined ;
}
} ) ;
me . _state . tip = tip ;
tip . show ( ) ;
}
2017-11-28 11:20:54 +00:00
} ,
disableEditing : function ( disable ) {
2017-11-10 12:44:12 +00:00
if ( this . _state . DisabledEditing != disable ) {
this . _state . DisabledEditing = disable ;
2021-06-29 13:27:44 +00:00
Common . NotificationCenter . trigger ( 'editing:disable' , disable , {
viewMode : disable ,
reviewMode : false ,
fillFormwMode : false ,
allowMerge : false ,
allowSignature : true ,
allowProtect : true ,
rightMenu : { clear : disable && ( DE . getController ( 'RightMenu' ) . rightmenu . GetActivePane ( ) !== 'id-signature-settings' ) , disable : true } ,
statusBar : true ,
leftMenu : { disable : false , previewMode : true } ,
fileMenu : false ,
navigation : { disable : false , previewMode : true } ,
comments : { disable : false , previewMode : true } ,
chat : false ,
review : true ,
viewport : false ,
documentHolder : true ,
toolbar : true ,
plugins : false
} ) ;
2017-11-10 12:44:12 +00:00
}
2017-11-28 11:20:54 +00:00
} ,
2017-11-27 11:15:10 +00:00
strSignature : 'Signature' ,
strRequested : 'Requested signatures' ,
strValid : 'Valid signatures' ,
strInvalid : 'Invalid signatures' ,
strSign : 'Sign' ,
2017-11-16 13:06:55 +00:00
strDetails : 'Signature Details' ,
strSetup : 'Signature Setup' ,
2017-11-28 12:29:14 +00:00
txtSigned : 'Valid signatures has been added to the document. The document is protected from editing.' ,
txtSignedInvalid : 'Some of the digital signatures in document are invalid or could not be verified. The document is protected from editing.' ,
txtRequestedSignatures : 'This document needs to be signed.' ,
txtContinueEditing : 'Edit anyway' ,
notcriticalErrorTitle : 'Warning' ,
2017-11-16 13:06:55 +00:00
txtEditWarning : 'Editing will remove the signatures from the document.<br>Are you sure you want to continue?' ,
2017-11-30 10:43:47 +00:00
strDelete : 'Remove Signature' ,
2021-03-04 09:48:15 +00:00
strSigner : 'Signer' ,
txtRemoveWarning : 'Are you sure you want to remove this signature?<br>This action cannot be undone.'
2017-11-27 11:15:10 +00:00
} , DE . Views . SignatureSettings || { } ) ) ;
} ) ;