2021-06-21 21:43:55 +00:00
/ *
*
* ( c ) Copyright Ascensio System SIA 2010 - 2021
*
* 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
*
* You can contact Ascensio System SIA at 20 A - 12 Ernesta Birznieka - Upisha
* street , Riga , Latvia , EU , LV - 1050.
*
* 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
*
* /
/ * *
* ProtectDialog . js
*
* Created by Julia Radzhabova on 21.06 . 2021
* Copyright ( c ) 2021 Ascensio System SIA . All rights reserved .
*
* /
define ( [
'common/main/lib/component/Window'
] , function ( ) {
'use strict' ;
SSE . Views . ProtectDialog = Common . UI . Window . extend ( _ . extend ( {
initialize : function ( options ) {
var t = this ,
_options = { } ;
_ . extend ( _options , {
2021-06-22 22:44:35 +00:00
title : options . title ? options . title : ( options . type == 'sheet' ? this . txtSheetTitle : this . txtWBTitle ) ,
2021-06-21 21:43:55 +00:00
cls : 'modal-dlg' ,
2021-06-22 11:56:07 +00:00
width : 350 ,
2021-11-24 14:13:04 +00:00
height : 'auto' ,
2021-06-22 22:44:35 +00:00
buttons : options . buttons ? options . buttons : [ {
2021-06-21 21:43:55 +00:00
value : 'ok' ,
caption : this . txtProtect
} , 'cancel' ]
} , options ) ;
this . handler = options . handler ;
this . txtDescription = options . txtDescription || '' ;
2021-06-22 11:56:07 +00:00
this . type = options . type || 'workbook' ;
this . props = options . props ;
2021-08-20 12:53:45 +00:00
this . names = options . names ;
this . isEdit = options . isEdit ;
2021-06-22 22:44:35 +00:00
this . api = options . api ;
2021-06-21 21:43:55 +00:00
this . template = options . template || [
'<div class="box">' ,
2021-06-22 22:44:35 +00:00
'<% if (type=="range") { %>' ,
'<div class="input-row">' ,
'<label>' + t . txtRangeName + '</label>' ,
'</div>' ,
'<div id="id-range-name-txt" class="input-row" style="margin-bottom: 5px;"></div>' ,
'<div class="input-row">' ,
'<label>' + t . txtRange + '</label>' ,
'</div>' ,
'<div id="id-range-txt" class="input-row" style="margin-bottom: 10px;"></div>' ,
'<% } else { %>' ,
'<div class="" style="margin-bottom: 10px;">' ,
'<label>' + ( t . type == 'sheet' ? t . txtSheetDescription : t . txtWBDescription ) + '</label>' ,
'</div>' ,
'<% } %>' ,
2021-06-21 21:43:55 +00:00
'<div class="input-row">' ,
'<label>' + t . txtPassword + ' (' + t . txtOptional + ')' + '</label>' ,
'</div>' ,
'<div id="id-password-txt" class="input-row" style="margin-bottom: 5px;"></div>' ,
'<div class="input-row">' ,
2021-06-22 11:56:07 +00:00
'<label>' + t . txtRepeat + '</label>' ,
2021-06-21 21:43:55 +00:00
'</div>' ,
'<div id="id-repeat-txt" class="input-row" style="margin-bottom: 10px;"></div>' ,
2021-06-22 11:56:07 +00:00
'<% if (type=="sheet") { %>' ,
'<div class="input-row">' ,
'<label>' + t . txtAllow + '</label>' ,
'</div>' ,
'<div id="protect-dlg-options" class="" style="width: 100%; height: 139px; overflow: hidden;margin-bottom: 10px;"></div>' ,
'<% } %>' ,
2021-06-21 21:43:55 +00:00
'<label>' + t . txtWarning + '</label>' ,
'</div>'
] . join ( '' ) ;
_options . tpl = _ . template ( this . template ) ( _options ) ;
Common . UI . Window . prototype . initialize . call ( this , _options ) ;
} ,
render : function ( ) {
Common . UI . Window . prototype . render . call ( this ) ;
2021-06-22 11:56:07 +00:00
var me = this ;
this . $window . find ( '.dlg-btn' ) . on ( 'click' , _ . bind ( this . onBtnClick , this ) ) ;
2021-10-07 23:53:44 +00:00
2021-06-22 11:56:07 +00:00
this . repeatPwd = new Common . UI . InputField ( {
el : $ ( '#id-repeat-txt' ) ,
type : 'password' ,
allowBlank : true ,
style : 'width: 100%;' ,
maxLength : 255 ,
validateOnBlur : false ,
validation : function ( value ) {
return me . txtIncorrectPwd ;
}
} ) ;
2021-10-08 12:24:41 +00:00
2021-10-10 08:11:20 +00:00
this . inputPwd = new Common . UI . InputFieldBtnPassword ( {
2021-10-07 23:53:44 +00:00
el : $ ( '#id-password-txt' ) ,
type : 'password' ,
allowBlank : true ,
style : 'width: 100%;' ,
maxLength : 255 ,
validateOnBlur : false ,
2021-10-11 13:04:00 +00:00
repeatInput : this . repeatPwd ,
showPwdOnClick : true
2021-10-07 23:53:44 +00:00
} ) ;
2021-06-22 11:56:07 +00:00
if ( this . type == 'sheet' ) {
this . optionsList = new Common . UI . ListView ( {
el : $ ( '#protect-dlg-options' , this . $window ) ,
store : new Common . UI . DataViewStore ( ) ,
simpleAddMode : true ,
scrollAlwaysVisible : true ,
template : _ . template ( [ '<div class="listview inner" style=""></div>' ] . join ( '' ) ) ,
itemTemplate : _ . template ( [
'<div>' ,
'<label class="checkbox-indeterminate" style="position:absolute;">' ,
'<input id="pdcheckbox-<%= id %>" type="checkbox" class="button__checkbox">' ,
'<label for="pdcheckbox-<%= id %>" class="checkbox__shape" ></label>' ,
'</label>' ,
'<div id="<%= id %>" class="list-item" style="pointer-events:none; margin-left: 20px;display: flex;">' ,
'<div style="flex-grow: 1;"><%= Common.Utils.String.htmlEncode(value) %></div>' ,
'</div>' ,
'</div>'
] . join ( '' ) )
2021-06-21 21:43:55 +00:00
} ) ;
2021-06-22 11:56:07 +00:00
this . optionsList . on ( {
'item:change' : this . onItemChanged . bind ( this ) ,
'item:add' : this . onItemChanged . bind ( this ) ,
'item:select' : this . onCellCheck . bind ( this )
2021-06-21 21:43:55 +00:00
} ) ;
2021-06-22 11:56:07 +00:00
this . optionsList . onKeyDown = _ . bind ( this . onListKeyDown , this ) ;
this . optionsList . on ( 'entervalue' , _ . bind ( this . onPrimary , this ) ) ;
2021-06-21 21:43:55 +00:00
}
2021-06-22 11:56:07 +00:00
2021-06-22 22:44:35 +00:00
if ( this . type == 'range' ) {
this . inputRangeName = new Common . UI . InputField ( {
el : $ ( '#id-range-name-txt' ) ,
allowBlank : false ,
blankError : this . txtEmpty ,
style : 'width: 100%;' ,
maxLength : 255 ,
2021-08-20 12:53:45 +00:00
validateOnBlur : false ,
validateOnChange : false ,
validation : function ( value ) {
if ( value == '' ) return true ;
var res = me . api . asc _checkProtectedRangeName ( value ) ;
switch ( res ) {
case Asc . c _oAscDefinedNameReason . WrongName :
return me . textInvalidName ;
break ;
case Asc . c _oAscDefinedNameReason . Existed :
return ( me . isEdit && me . props . asc _getName ( ) . toLowerCase ( ) == value . toLowerCase ( ) ) ? true : me . textExistName ;
case Asc . c _oAscDefinedNameReason . OK :
var index = me . names . indexOf ( value . toLowerCase ( ) ) ;
return ( index < 0 || me . isEdit && me . props . asc _getName ( ) . toLowerCase ( ) == value . toLowerCase ( ) ) ? true : me . textExistName ;
default :
return me . textInvalidName ;
}
}
2021-06-22 22:44:35 +00:00
} ) ;
this . txtDataRange = new Common . UI . InputFieldBtn ( {
el : $ ( '#id-range-txt' ) ,
name : 'range' ,
style : 'width: 100%;' ,
2021-06-23 09:20:24 +00:00
allowBlank : false ,
2021-06-22 22:44:35 +00:00
btnHint : this . textSelectData ,
blankError : this . txtEmpty ,
validateOnChange : true ,
2021-06-23 15:07:56 +00:00
validateOnBlur : false ,
2021-06-22 22:44:35 +00:00
validation : function ( value ) {
2021-06-23 15:07:56 +00:00
var isvalid = me . api . asc _checkDataRange ( Asc . c _oAscSelectionDialogType . ConditionalFormattingRule , value , true ) ;
2021-06-23 09:20:24 +00:00
return ( isvalid !== Asc . c _oAscError . ID . DataRangeError ) ? true : me . textInvalidRange ;
2021-06-22 22:44:35 +00:00
}
} ) ;
this . txtDataRange . on ( 'button:click' , _ . bind ( this . onSelectData , this ) ) ;
}
2021-06-22 11:56:07 +00:00
this . afterRender ( ) ;
2021-06-21 21:43:55 +00:00
} ,
getFocusedComponents : function ( ) {
2021-06-22 22:44:35 +00:00
var arr = [ ] ;
( this . type == 'range' ) && ( arr = arr . concat ( [ this . inputRangeName , this . txtDataRange ] ) ) ;
arr = arr . concat ( [ this . inputPwd , this . repeatPwd ] ) ;
( this . type == 'sheet' ) && ( arr = arr . concat ( [ this . optionsList ] ) ) ;
return arr ;
2021-06-21 21:43:55 +00:00
} ,
getDefaultFocusableComponent : function ( ) {
2021-06-22 22:44:35 +00:00
return ( this . type == 'range' ) ? this . inputRangeName : this . inputPwd ;
2021-06-21 21:43:55 +00:00
} ,
2021-06-22 11:56:07 +00:00
afterRender : function ( ) {
this . _setDefaults ( this . props ) ;
} ,
2021-06-21 21:43:55 +00:00
onPrimary : function ( event ) {
this . _handleInput ( 'ok' ) ;
return false ;
} ,
onBtnClick : function ( event ) {
this . _handleInput ( event . currentTarget . attributes [ 'result' ] . value ) ;
} ,
_handleInput : function ( state ) {
if ( this . handler ) {
if ( state == 'ok' ) {
2021-06-22 22:44:35 +00:00
if ( this . inputRangeName && this . inputRangeName . checkValidate ( ) !== true ) {
this . inputRangeName . focus ( ) ;
return ;
}
2021-06-23 09:20:24 +00:00
if ( this . txtDataRange && this . txtDataRange . checkValidate ( ) !== true ) {
this . txtDataRange . focus ( ) ;
return ;
}
2021-06-21 21:43:55 +00:00
if ( this . inputPwd . checkValidate ( ) !== true ) {
this . inputPwd . focus ( ) ;
return ;
}
if ( this . inputPwd . getValue ( ) !== this . repeatPwd . getValue ( ) ) {
this . repeatPwd . checkValidate ( ) ;
this . repeatPwd . focus ( ) ;
return ;
}
}
2021-06-23 09:20:24 +00:00
this . handler . call ( this , state , this . inputPwd . getValue ( ) , ( state == 'ok' ) ? this . getSettings ( ) : undefined ) ;
2021-06-21 21:43:55 +00:00
}
this . close ( ) ;
} ,
2021-06-22 11:56:07 +00:00
_setDefaults : function ( props ) {
this . optionsList && this . updateOptionsList ( props ) ;
2021-06-23 09:20:24 +00:00
( this . type == 'range' ) && this . updateRangeSettings ( props ) ;
2021-06-22 11:56:07 +00:00
} ,
onItemChanged : function ( view , record ) {
var state = record . model . get ( 'check' ) ;
if ( state == 'indeterminate' )
$ ( 'input[type=checkbox]' , record . $el ) . prop ( 'indeterminate' , true ) ;
else $ ( 'input[type=checkbox]' , record . $el ) . prop ( { checked : state , indeterminate : false } ) ;
} ,
onCellCheck : function ( listView , itemView , record ) {
if ( this . checkCellTrigerBlock )
return ;
var target = '' , isLabel = false , bound = null ;
var event = window . event ? window . event : window . _event ;
if ( event ) {
target = $ ( event . currentTarget ) . find ( '.list-item' ) ;
if ( target . length ) {
bound = target . get ( 0 ) . getBoundingClientRect ( ) ;
var _clientX = event . clientX * Common . Utils . zoom ( ) ,
_clientY = event . clientY * Common . Utils . zoom ( ) ;
if ( bound . left < _clientX && _clientX < bound . right &&
bound . top < _clientY && _clientY < bound . bottom ) {
isLabel = true ;
}
}
2021-09-29 08:38:25 +00:00
if ( isLabel || event . target . className . match ( 'checkbox' ) && event . target . localName !== 'input' ) {
2021-06-22 11:56:07 +00:00
this . updateCellCheck ( listView , record ) ;
_ . delay ( function ( ) {
listView . focus ( ) ;
} , 100 , this ) ;
}
}
} ,
onListKeyDown : function ( e , data ) {
var record = null , listView = this . optionsList ;
if ( listView . disabled ) return ;
if ( _ . isUndefined ( undefined ) ) data = e ;
if ( data . keyCode == Common . UI . Keys . SPACE ) {
data . preventDefault ( ) ;
data . stopPropagation ( ) ;
this . updateCellCheck ( listView , listView . getSelectedRec ( ) ) ;
} else {
Common . UI . DataView . prototype . onKeyDown . call ( this . optionsList , e , data ) ;
}
} ,
updateCellCheck : function ( listView , record ) {
if ( record && listView ) {
record . set ( 'check' , ! record . get ( 'check' ) ) ;
2021-07-16 12:47:24 +00:00
if ( record . get ( 'optionName' ) == 'SelectLockedCells' && record . get ( 'check' ) )
this . optionsList . store . findWhere ( { optionName : 'SelectUnlockedCells' } ) . set ( 'check' , true ) ;
2021-08-05 11:17:50 +00:00
if ( record . get ( 'optionName' ) == 'SelectUnlockedCells' && ! record . get ( 'check' ) )
this . optionsList . store . findWhere ( { optionName : 'SelectLockedCells' } ) . set ( 'check' , false ) ;
2021-06-22 11:56:07 +00:00
// listView.scroller.update({minScrollbarLength : 40, alwaysVisibleY: true, suppressScrollX: true});
}
} ,
2021-06-23 09:20:24 +00:00
updateRangeSettings : function ( props ) {
if ( props ) {
this . inputRangeName . setValue ( props . asc _getName ( ) ) ;
this . txtDataRange . setValue ( props . asc _getSqref ( ) ) ;
}
} ,
2021-06-22 11:56:07 +00:00
updateOptionsList : function ( props ) {
var optionsArr = [
{ value : this . txtSelLocked , optionName : 'SelectLockedCells' } ,
{ value : this . txtSelUnLocked , optionName : 'SelectUnlockedCells' } ,
{ value : this . txtFormatCells , optionName : 'FormatCells' } ,
{ value : this . txtFormatCols , optionName : 'FormatColumns' } ,
{ value : this . txtFormatRows , optionName : 'FormatRows' } ,
{ value : this . txtInsCols , optionName : 'InsertColumns' } ,
{ value : this . txtInsRows , optionName : 'InsertRows' } ,
{ value : this . txtInsHyper , optionName : 'InsertHyperlinks' } ,
{ value : this . txtDelCols , optionName : 'DeleteColumns' } ,
{ value : this . txtDelRows , optionName : 'DeleteRows' } ,
{ value : this . txtSort , optionName : 'Sort' } ,
{ value : this . txtAutofilter , optionName : 'AutoFilter' } ,
{ value : this . txtPivot , optionName : 'PivotTables' } ,
{ value : this . txtObjs , optionName : 'Objects' } ,
{ value : this . txtScen , optionName : 'Scenarios' }
] ;
var arr = [ ] ;
optionsArr . forEach ( function ( item , index ) {
arr . push ( new Common . UI . DataViewModel ( {
selected : false ,
allowSelected : true ,
value : item . value ,
optionName : item . optionName ,
2021-06-22 12:45:04 +00:00
check : props && props [ 'asc_get' + item . optionName ] ? ! props [ 'asc_get' + item . optionName ] ( ) : false
2021-06-22 11:56:07 +00:00
} ) ) ;
} ) ;
this . optionsList . store . reset ( arr ) ;
this . optionsList . scroller . update ( { minScrollbarLength : 40 , alwaysVisibleY : true , suppressScrollX : true } ) ;
} ,
2021-06-22 22:44:35 +00:00
getSettings : function ( ) {
if ( this . type == 'sheet' ) return this . getSheetSettings ( ) ;
if ( this . type == 'range' ) return this . getRangeSettings ( ) ;
} ,
2021-06-22 11:56:07 +00:00
2021-06-22 22:44:35 +00:00
getSheetSettings : function ( ) {
2021-06-22 13:07:10 +00:00
var props = this . props ? this . props : new Asc . CSheetProtection ( ) ;
2021-06-22 11:56:07 +00:00
this . optionsList . store . each ( function ( item , index ) {
2021-06-22 12:45:04 +00:00
props && props [ 'asc_set' + item . get ( 'optionName' ) ] && props [ 'asc_set' + item . get ( 'optionName' ) ] ( ! item . get ( 'check' ) ) ;
2021-06-22 11:56:07 +00:00
} ) ;
return props ;
} ,
2021-06-22 22:44:35 +00:00
getRangeSettings : function ( ) {
var props = this . props ? this . props : new Asc . CProtectedRange ( ) ;
props . asc _setName ( this . inputRangeName . getValue ( ) ) ;
props . asc _setSqref ( this . txtDataRange . getValue ( ) ) ;
return props ;
} ,
onSelectData : function ( ) {
var me = this ;
if ( me . api ) {
var handlerDlg = function ( dlg , result ) {
if ( result == 'ok' ) {
me . dataRangeValid = dlg . getSettings ( ) ;
me . txtDataRange . setValue ( me . dataRangeValid ) ;
me . txtDataRange . checkValidate ( ) ;
}
} ;
var win = new SSE . Views . CellRangeDialog ( {
handler : handlerDlg
} ) . on ( 'close' , function ( ) {
me . show ( ) ;
_ . delay ( function ( ) {
me . txtDataRange . focus ( ) ;
} , 1 ) ;
} ) ;
var xy = me . $window . offset ( ) ;
me . hide ( ) ;
win . show ( xy . left + 65 , xy . top + 77 ) ;
win . setSettings ( {
api : me . api ,
range : ( ! _ . isEmpty ( me . txtDataRange . getValue ( ) ) && ( me . txtDataRange . checkValidate ( ) == true ) ) ? me . txtDataRange . getValue ( ) : me . dataRangeValid ,
2021-06-23 09:20:24 +00:00
type : Asc . c _oAscSelectionDialogType . ConditionalFormattingRule ,
validation : function ( ) { return true ; }
2021-06-22 22:44:35 +00:00
} ) ;
}
} ,
2021-06-22 11:56:07 +00:00
txtPassword : "Password" ,
2021-06-21 21:43:55 +00:00
txtRepeat : 'Repeat password' ,
txtIncorrectPwd : 'Confirmation password is not identical' ,
txtWarning : 'Warning: If you lose or forget the password, it cannot be recovered. Please keep it in a safe place.' ,
txtOptional : 'optional' ,
2021-06-22 11:56:07 +00:00
txtProtect : 'Protect' ,
txtSelLocked : 'Select locked cells' ,
txtSelUnLocked : 'Select unlocked cells' ,
txtFormatCells : 'Format cells' ,
txtFormatCols : 'Format columns' ,
txtFormatRows : 'Format rows' ,
txtInsCols : 'Insert columns' ,
txtInsRows : 'Insert rows' ,
txtInsHyper : 'Insert hyperlink' ,
txtDelCols : 'Delete columns' ,
txtDelRows : 'Delete rows' ,
txtSort : 'Sort' ,
txtAutofilter : 'Use AutoFilter' ,
txtPivot : 'Use PivotTable and PivotChart' ,
txtObjs : 'Edit objects' ,
txtScen : 'Edit scenarios' ,
txtWBDescription : 'To prevent other users from viewing hidden worksheets, adding, moving, deleting, or hiding worksheets and renaming worksheets, you can protect the structure of your workbook with a password.' ,
txtWBTitle : 'Protect Workbook structure' ,
txtSheetDescription : 'Prevent unwanted changes from others by limiting their ability to edit.' ,
txtSheetTitle : 'Protect Sheet' ,
2021-06-22 22:44:35 +00:00
txtAllow : 'Allow all users of this sheet to' ,
txtRangeName : 'Title' ,
txtRange : 'Range' ,
txtEmpty : 'This field is required' ,
2021-06-23 15:07:56 +00:00
textSelectData : 'Select Data' ,
2021-08-20 12:53:45 +00:00
textInvalidRange : 'ERROR! Invalid cells range' ,
textInvalidName : 'The range title must begin with a letter and may only contain letters, numbers, and spaces.' ,
textExistName : 'ERROR! Range with such a title already exists'
2021-06-21 21:43:55 +00:00
} , SSE . Views . ProtectDialog || { } ) ) ;
} ) ;