From 549d6a8463a1eb971f892a44c587bc28d8f669e0 Mon Sep 17 00:00:00 2001 From: smizrahi Date: Wed, 26 Oct 2022 14:30:10 +0200 Subject: [PATCH] fix(calendar): Update c_startdate field when updating event. Fixes #4376 --- SOPE/GDLContentStore/GCSFolder.m | 12 +++++++++++- SOPE/NGCards/iCalCalendar.h | 3 +++ SOPE/NGCards/iCalCalendar.m | 19 +++++++++++++++++++ UI/WebServerResources/js/Common.js | 2 +- UI/WebServerResources/js/Common.js.map | 2 +- 5 files changed, 35 insertions(+), 3 deletions(-) diff --git a/SOPE/GDLContentStore/GCSFolder.m b/SOPE/GDLContentStore/GCSFolder.m index 628aaade31..733ebf0256 100644 --- a/SOPE/GDLContentStore/GCSFolder.m +++ b/SOPE/GDLContentStore/GCSFolder.m @@ -987,7 +987,7 @@ - (NSException *) writeContent: (NSString *) _content NSDictionary *currentRow; NSNumber *storedVersion; BOOL isNewRecord, hasInsertDelegate, hasUpdateDelegate; - NSCalendarDate *nowDate; + NSCalendarDate *nowDate, *startDate; NSNumber *now; EOEntity *quickTableEntity, *storeTableEntity; NSArray *rows; @@ -1002,6 +1002,7 @@ - (NSException *) writeContent: (NSString *) _content error = nil; nowDate = [NSCalendarDate date]; now = [NSNumber numberWithUnsignedInt:[nowDate timeIntervalSince1970]]; + startDate = nil; if (doLogStore) [self logWithFormat:@"should store content: '%@'\n%@", _name, _content]; @@ -1071,6 +1072,7 @@ - (NSException *) writeContent: (NSString *) _content [contentRow setObject:_name forKey:@"c_name"]; [contentRow setObject:now forKey:@"c_lastmodified"]; + if (isNewRecord) { [contentRow setObject:now forKey:@"c_creationdate"]; @@ -1141,6 +1143,14 @@ - (NSException *) writeContent: (NSString *) _content } else { + // Update c_startdate for appointments + if ([theComponent respondsToSelector:@selector(startDate)]) { + startDate = [theComponent startDate]; + if (startDate) { + [quickRow setObject:[NSNumber numberWithUnsignedInt:[startDate timeIntervalSince1970]] forKey:@"c_startdate"]; + } + } + if (!ofFlags.sameTableForQuick) error = (hasUpdateDelegate ? [quickChannel updateRowX: quickRow diff --git a/SOPE/NGCards/iCalCalendar.h b/SOPE/NGCards/iCalCalendar.h index ec9f0b2d9e..b22d7ee7ab 100644 --- a/SOPE/NGCards/iCalCalendar.h +++ b/SOPE/NGCards/iCalCalendar.h @@ -56,6 +56,9 @@ - (void) setMethod: (NSString *) _method; - (NSString *) method; +// - (void) setStartDate: (NSCalendarDate *) newStartDate; +- (NSCalendarDate *) startDate; + - (NSArray *) events; - (NSArray *) todos; - (NSArray *) journals; diff --git a/SOPE/NGCards/iCalCalendar.m b/SOPE/NGCards/iCalCalendar.m index 0834ed555a..d44c62212c 100644 --- a/SOPE/NGCards/iCalCalendar.m +++ b/SOPE/NGCards/iCalCalendar.m @@ -133,8 +133,27 @@ - (void) setMethod: (NSString *) _value - (NSString *) method { return [[self uniqueChildWithTag: @"method"] flattenedValuesForKey: @""]; +} + +- (NSCalendarDate *) startDate +{ + // Parse all dtstart to find the earlier + NSCalendarDate *calendarDate, *tmpCalendarDate; + NSUInteger i; + + calendarDate = nil; + if ([[self allObjects] count] > 0) { + calendarDate = [[[[self allObjects] objectAtIndex: 0] uniqueChildWithTag: @"dtstart"] dateTime]; + for (i = 0U ; i < [[self allObjects] count] ; i++) { + tmpCalendarDate = [[[[self allObjects] objectAtIndex: i] uniqueChildWithTag: @"dtstart"] dateTime]; + if ([tmpCalendarDate timeIntervalSince1970] < [calendarDate timeIntervalSince1970]) calendarDate = tmpCalendarDate; + } + } + + return calendarDate; } + - (void) addToEvents: (iCalEvent *) _event { [self addChild: _event]; diff --git a/UI/WebServerResources/js/Common.js b/UI/WebServerResources/js/Common.js index 62767e5ebe..d6fe11aea7 100644 --- a/UI/WebServerResources/js/Common.js +++ b/UI/WebServerResources/js/Common.js @@ -1,2 +1,2 @@ -function l(){var n,e,t=arguments[0],o=t,r=arguments;for(labels[t]?o=labels[t]:clabels[t]&&(o=clabels[t]),n=1,e=0;n');return s.on("load",function(){var e=o.get("$state");2"+e+"");return e.find("a").attr("target","_blank"),t.trustAs("html",e.html())}}e.$inject=["$sce"],angular.module("SOGo.Common").filter("ensureTarget",e)}(),function(){"use strict";angular.module("SOGo.Common").filter("loc",function(){return l})}(),function(){"use strict";angular.module("SOGo.Common").filter("range",function(){return function(e){for(var t=[],n=0;n"):void 0}}e.$inject=["linkyFilter"],angular.module("SOGo.Common").filter("txt2html",e)}(),function(){"use strict";function e(t,n,e,o,r,i,s){var a=this;function c(e,t){if(t&&t.target.parentNode.classList.contains("md-secondary"))return!1;a.selectedUid==e.uid?a.selectedUid=null:(a.selectedUid=e.uid,(a.selectedUser=e).inactive||a.selectedUser.$rights())}a.users=r,a.folder=s,a.selectedUser=null,a.selectedUid=null,a.userToAdd="",a.searchText="",a.folderClassName=function(){return!!angular.isFunction(s.getClassName)&&s.getClassName("bg")},a.templateName=function(e){return"UIx"+(t[0].getElementById("UIxAnonymousUserRightsEditor")&&e.$isAnonymous()?"Anonymous":"")+"UserRightsEditor"},a.userFilter=function(e){return i.$filter(e,s.$acl.users,{dry:!0})},a.closeModal=function(){s.$acl.$resetUsersRights(),e.hide()},a.saveModal=function(){s.$acl.$saveUsersRights().then(function(){e.hide()},function(e,t){o.alert(l("Warning"),l("An error occured, please try again."))})},a.confirmChange=function(e){e=e.$confirmRights(a.folder);e&&(a.confirmation.showing=!0,a.confirmation.message=e)},a.removeUser=function(e){n(function(){s.$acl.$removeUser(e.uid)},500)},a.addUser=function(e){e&&s.$acl.$addUser(e).then(function(e){a.userToAdd="",a.searchText="",a.selectedUid=null,e&&c(e)})},a.toggleAllRights=function(e){s.$acl.$toggleAllRights(e)},a.selectUser=c,a.hasNoRight=function(e){return s.$acl.$hasNoRight(e)},a.showRights=function(e){return a.selectedUid==e.uid&&!e.inactive},a.confirmation={showing:!1,message:""}}e.$inject=["$document","$timeout","$mdDialog","Dialog","usersWithACL","User","folder"],angular.module("SOGo.Common").controller("AclController",e)}(),function(){"use strict";function e(e,t,n,o,r,i,s,a,c,u,d,h,m,g){var p=new m(h.baseURL(),h.activeUser());function f(e,t){var n;t.data&&t.data.message&&angular.isString(t.data.message)?n=t.data.message:t.status&&(n=t.statusText),n?a.show({template:["",'
',' error_outline'," "+l(n)+"","
","
"].join(""),hideDelay:5e3,position:d.toastPosition}):u.debug("untrap error")}this.$onInit=function(){t.isPopup=h.isPopup,t.activeUser=h.activeUser(),t.baseURL=h.baseURL(),t.leftIsClose=!c(d["gt-md"]),t.centerIsClose=!!i.centerIsClose&&!t.leftIsClose,t.currentDay=window.currentDay,n(function(){o(function(){r.get("../date").then(function(e){t.currentDay=e})},864e5)},1e3*window.currentDay.secondsBeforeTomorrow),t.$watch(function(){return c(d["gt-xs"])},function(e){t.isGtExtraSmall=e}),t.$watch(function(){return c(d["gt-md"])},function(e){(t.isGtMedium=e)&&(t.leftIsClose=!1)}),e.$on("http:Error",f),t.isPopup||(h.activeUser("path").calendar&&g.getAlarms(),h.activeUser("path").mail&&g.pollInbox())},t.toggleLeft=function(){t.isGtMedium?t.leftIsClose=!t.leftIsClose:(t.leftIsClose=!s("left").isOpen(),t.leftIsClose&&angular.element(i).triggerHandler("resize"),s("left").toggle().then(function(){u.debug("toggle left is done")}))},t.toggleRight=function(){s("right").toggle().then(function(){u.debug("toggle right is done")})},t.toggleCenter=function(e){t.centerIsClose=!t.centerIsClose,e&&e.save&&p.post(null,"saveListState",{state:t.centerIsClose?"collapse":"rise"})}}e.$inject=["$rootScope","$scope","$timeout","$interval","$http","$window","$mdSidenav","$mdToast","$mdMedia","$log","sgConstant","sgSettings","Resource","Preferences"],angular.module("SOGo.Common").controller("navController",e)}(),function(){"use strict";function s(e){this.folderId=e}s.factory=["$q","$timeout","sgSettings","Resource","User",function(e,t,n,o,r){return angular.extend(s,{$q:e,$timeout:t,$$resource:new o(n.activeUser("folderURL"),n.activeUser()),$User:r}),s}],angular.module("SOGo.Common").factory("Acl",s.factory),s.prototype.$users=function(t){var n,o=this,r=s.$q.defer();return this.users?(r.resolve(this.users),r.promise):(angular.isDefined(t)?s.$$resource.userResource(t):s.$$resource).fetch(this.folderId,"acls").then(function(e){return o.users=[],angular.forEach(e.users,function(e){(n=new s.$User(e)).canSubscribeUser=n.isSubscribed,n.wasSubscribed=n.isSubscribed,n.$rights=angular.bind(n,n.$acl,o.folderId,t),o.users.push(n)}),r.resolve(o.users),o.users},function(e){throw r.reject(l(e.statusText)),Error("No access to object")})},s.prototype.$addUser=function(e,t){var n=this,o=s.$q.defer(),r={uid:e.uid};return!e.uid||-1<_.indexOf(_.map(this.users,"uid"),e.uid)?o.resolve():(angular.isDefined(t)?s.$$resource.userResource(t):s.$$resource).fetch(this.folderId,"addUserInAcls",r).then(function(){e.wasSubscribed=!1,e.userClass=e.isGroup?"normal-group":"normal-user",e.$rights=angular.bind(e,e.$acl,n.folderId,t),n.users.push(e),o.resolve(e)},function(e,t){o.reject(l("An error occured, please try again."))}),o.promise},s.prototype.$removeUser=function(t,e){var n=this,o={uid:t},e=(angular.isDefined(e)?s.$$resource.userResource(e):s.$$resource).fetch(this.folderId,"removeUserFromAcls",o);return e.then(function(){var e=_.indexOf(_.map(n.users,"uid"),t);0<=e&&(n.users[e].$shadowRights=null,n.users.splice(e,1))})},s.prototype.$toggleAllRights=function(n){var o=!angular.isUndefined(_.find(_.values(n.rights),function(e){return 1!==e&&"Modifier"!==e}));_.forEach(n.rights,function(e,t){angular.isNumber(n.rights[t])?n.rights[t]=o?1:0:n.rights[t]=o?"Modifier":"None"})},s.prototype.$hasNoRight=function(e){e=_.find(e.rights,function(e,t){return angular.isNumber(e)?1===e:"None"!==e});return _.isUndefined(e)},s.prototype.$resetUsersRights=function(){angular.forEach(this.users,function(e){e.$resetRights()})},s.prototype.$saveUsersRights=function(e){var t=this,n=s.$q.defer(),o=s.$q.defer(),r={action:"saveUserRights"},i=[];return angular.forEach(this.users,function(e){e.$rightsAreDirty()&&i.push(e.$omit())}),i.length?(angular.isDefined(e)?s.$$resource.userResource(e):s.$$resource).save(this.folderId,i,r).then(function(){angular.forEach(t.users,function(e){e.$rightsAreDirty()&&(e.$shadowRights=angular.copy(e.rights))}),n.resolve()},n.reject):n.resolve(),i=[],angular.forEach(this.users,function(e){!e.wasSubscribed&&e.isSubscribed&&i.push(e.uid)}),i.length?(r={uids:i.join(",")},s.$$resource.fetch(this.folderId,"subscribeUsers",r).then(function(){angular.forEach(t.users,function(e){e.wasSubscribed=e.isSubscribed}),o.resolve()},o.reject)):o.resolve(),s.$q.all([n.promise,o.promise])}}(),function(){"use strict";angular.module("SOGo.Authentication",["ngCookies"]).constant("passwordPolicyConfig",{PolicyPasswordChangeUnsupported:-3,PolicyPasswordSystemUnknown:-2,PolicyPasswordUnknown:-1,PolicyPasswordExpired:0,PolicyAccountLocked:1,PolicyChangeAfterReset:2,PolicyPasswordModNotAllowed:3,PolicyMustSupplyOldPassword:4,PolicyInsufficientPasswordQuality:5,PolicyPasswordTooShort:6,PolicyPasswordTooYoung:7,PolicyPasswordInHistory:8,PolicyPasswordRecoveryFailed:9,PolicyPasswordRecoveryInvalidToken:10,PolicyNoError:65535}).provider("Authentication",function(){function m(e,t){var n,o;return t&&(e+="@"+t),t=""+window.location.href,"/"==(e=ApplicationBaseURL+encodeURIComponent(e))[0]&&(o=(n=t.split("/"))[2],e=n[0]+"//"+o+e),t.startsWith(e)&&!t.endsWith("/logoff")?t:e}function e(c,u,d,h){return{login:function(e){var t,n=c.defer(),o=e.username,r=e.password,i=e.verificationCode,s=e.domain,a=e.rememberLogin?1:0;return e.loginSuffix&&!o.endsWith(e.loginSuffix)&&(o+=loginSuffix,s=!1),e.language&&"WONoSelectionString"!=e.language&&(t=e.language),u({method:"POST",url:"/SOGo/connect",data:{userName:o,password:r,verificationCode:i,domain:s,language:t,rememberLogin:a}}).then(function(e){var t=e.data;navigator&&!navigator.cookieEnabled?n.reject({error:l("cookiesNotEnabled")}):void 0!==t.totpMissingKey&&202==e.status?n.resolve({totpmissingkey:1}):void 0!==t.totpDisabled?n.resolve({cn:t.cn,url:m(o,s),totpdisabled:1}):void 0!==t.expire&&void 0!==t.grace?t.expire<0&&0','
',' ','

'," "," ",' '," ","
"," ",' '," "+l("Cancel")," ",' '," "+l("OK")," "," ","
",""].join(""),controller:i}),i.$inject=["scope","$mdDialog"],r.promise},e.$inject=["$q","$mdDialog"],angular.module("SOGo.Common").factory("Dialog",e)}(),function(){"use strict";angular.module("SOGo.Common").factory("Gravatar",function(){return function(e,t,n,o){var r,i=t,s=n;return e?(t||(i=48),"https://www.gravatar.com/avatar/"+(e=0<=(t=e.indexOf("<"))&&t<(r=e.indexOf(">",t))?e.substring(t+1,r):e).md5()+"?s="+i+"&d="+(n=s&&"none"!=s?n:o&&o.no_404?"mm":"404")):""}})}(),function(){"use strict";function a(e,t,n,o,r,i,s){angular.extend(this,{_http:e,_q:t,_window:n,_cookies:o,_path:r,_activeUser:i}),angular.extend(this,s),this._path=this._path.replace(/\/$/,"")}a.$factory=["$http","$q","$window","$cookies",function(o,r,i,s){return function(e,t,n){return new a(o,r,i,s,e,t,n)}}],angular.module("SOGo.Common").factory("Resource",a.$factory),a.prototype.encodeURL=function(e){var t=this,n=e;return angular.isArray(n)||(n=e.split("/")),_.map(n,function(e){return t._window.encodeURIComponent(e.toString())})},a.prototype.userResource=function(e){var t=_.compact(this._activeUser.folderURL.split("/"));return e&&t.splice(t.length-1,1,escape(e)),new a(this._http,this._q,this._window,this._cookies,"/"+t.join("/"),this._activeUser)},a.prototype.path=function(){var e=[this._path];return 0",' ','
',"
","
","
"," "," ",' '," {{keys[0].description}}",'
'," {{keys[0].lkey || hotkey}}","
","
","
","
",""].join(""),controller:t,locals:{hotkeys:e._hotkeys}}).finally(function(){e._cheatSheet=null}),t.$inject=["$scope","hotkeys"]},n}(this.$get=e).$inject=["$rootScope","$window"]})}(),function(){"use strict";function e(t,n){return function(e){n(function(){t.$broadcast("sgRippleDo",e)})}}e.$inject=["$rootScope","$timeout"],angular.module("SOGo.Common").factory("sgRippleClick",e)}(),function(){"use strict";function c(e){e&&this.init(e)}c.factory=["$q","$log","sgSettings","Resource",function(e,t,n,o){return angular.extend(c,{$q:e,$log:t,$$resource:new o(n.activeUser("folderURL"),n.activeUser()),$query:"",$users:[]}),c}],angular.module("SOGo.Common").factory("User",c.factory),c.$filter=function(e,s,a){var t=c.$$resource,n={search:e};if(a&&a.dry)a&&a.uid&&(t=c.$$resource.userResource(a.uid));else{if(!e)return c.$users.splice(0,c.$users.length),c.$q.when(c.$users);if(c.$query==e)return c.$q.when(c.$users);c.$query=e}return t.fetch(null,"usersSearch",n).then(function(e){function n(e){return this.uid==e.uid}var t,o,r,i;for(a?a.dry?i=[]:a.results&&(i=a.results):i=c.$users,t=s?_.filter(e.users,function(e){return!_.find(s,_.bind(n,e))}):e.users,o=i.length-1;0<=o;o--)r=i[o],_.find(t,_.bind(n,r))||i.splice(o,1);return _.forEach(t,function(e,t){_.isUndefined(_.find(i,_.bind(n,e)))&&(e=new c(e),i.splice(t,0,e))}),c.$log.debug(i),i})},c.prototype.init=function(e){angular.extend(this,e),this.$$shortFormat||(this.$$shortFormat=this.$shortFormat()),this.$$image||(this.$$image=this.image),this.$avatarIcon=this.$isGroup()||this.$isSpecial()?"group":"person",this.empty=" "},c.prototype.$fullname=function(){var e=this.cn||this.uid;return this.c_info&&(e+=" ("+this.c_info.split("\n").join("; ")+")"),e},c.prototype.$shortFormat=function(e){var t=this.$fullname(),n=this.c_email;return!(e&&!1===e.email)&&n&&t!=n&&(t+=" <"+n+">"),t},c.prototype.$acl=function(e,t){var n=this,o=c.$q.defer(),r={uid:this.uid};return this.$shadowRights?o.resolve(this.rights):(angular.isDefined(t)?c.$$resource.userResource(t):c.$$resource).fetch(e,"userRights",r).then(function(e){return n.rights=e,n.$shadowRights=angular.copy(e),o.resolve(e),e}),o.promise},c.prototype.$isGroup=function(){return this.isGroup||this.userClass&&"normal-group"==this.userClass},c.prototype.$isAnonymous=function(){return"anonymous"==this.uid},c.prototype.$isSpecial=function(){return this.userClass&&"public-user"==this.userClass},c.prototype.$confirmRights=function(e){var t=!1;return!this.$confirmation&&(_.some(_.values(this.rights))&&("anonymous"==this.uid?"AddressBook"==e.constructor.name?t=l('Potentially anyone on the Internet will be able to access your address book "%{0}", even if they do not have an account on this system. Is this information suitable for the public Internet?',e.name):"Calendar"==e.constructor.name&&(t=l('Potentially anyone on the Internet will be able to access your calendar "%{0}", even if they do not have an account on this system. Is this information suitable for the public Internet?',e.name)):"anyone"!=this.uid&&""!=this.uid||("AddressBook"==e.constructor.name?t=l('Any user with an account on this system will be able to access your address book "%{0}". Are you certain you trust them all?',e.name):"Calendar"==e.constructor.name?t=l('Any user with an account on this system will be able to access your calendar "%{0}". Are you certain you trust them all?',e.name):"Mailbox"==e.constructor.name&&(t=l('Any user with an account on this system will be able to access your mailbox "%{0}". Are you certain you trust them all?',e.name)))),this.$confirmation=t)},c.prototype.$rightsAreDirty=function(){return this.rights&&!_.isEqual(this.rights,this.$shadowRights)},c.prototype.$resetRights=function(e){var t=this;e?_.map(_.keys(this.rights),function(e){angular.isString(t.rights[e])?t.rights[e]="None":t.rights[e]=0}):this.$shadowRights&&(this.rights=angular.copy(this.$shadowRights))},c.prototype.$folders=function(e){var t=this,n=c.$q.defer(),e={type:e};return this.$$folders?n.resolve(this.$$folders):c.$$resource.userResource(this.uid).fetch(null,"foldersSearch",e).then(function(e){t.$$folders=e.folders,n.resolve(e.folders)}),n.promise},c.prototype.$omit=function(){var n={};return angular.forEach(this,function(e,t){"constructor"!=t&&"$"!=t[0]&&(n[t]=e)}),n},c.prototype.toString=function(){return"[User "+this.c_email+"]"}}(),function(){"use strict";function e(c,e,u){return{restrict:"A",scope:{autogrow:"=sgAutogrow"},link:function(e,t,n){var o,r,i,s,a;function l(){s=(s=o.value.encodeEntities()).replace(/\n/g,"
"),i.innerHTML=s+'
',i.style.visibility="hidden",i.style.display="block",o.style.height=Math.max(r,i.offsetHeight)+"px",i.style.visibility="visible",i.style.display="none"}e.autogrow&&(o=t[0],r=o.clientHeight,i=c[0].createElement("div"),s=null,i.classList.add("md-input"),i.classList.add("plain-text"),i.style.display="none",i.style.whiteSpace="pre-wrap",i.style.wordWrap="break-word",o.parentNode.appendChild(i),o.style.resize="none",o.style.overflow="hidden",t.on("keyup",u.debounce(l,200)),t.on("paste",u.debounce(l,0)),a=e.$watch(function(){return t[0].value},function(e){e&&(l(),a())}))}}}e.$inject=["$document","$timeout","$mdUtil"],angular.module("SOGo.Common").directive("sgAutogrow",e)}(),function(){"use strict";function e(e,t,r,n,i,s){var a,o;function l(){a.url=null,a.urlEmail=null,a.img.addClass("ng-hide"),a.genericImg.removeClass("ng-hide")}function c(){a.genericImg.addClass("ng-hide"),a.img.removeClass("ng-hide")}a=this,e.$on("$destroy",function(){o&&t.off("click",o)}),e.$watch(function(){return a.email},function(e,t){var n,o;e&&a.urlEmail!=e?(l(),i.defaults.SOGoGravatarEnabled&&(o=s(n=e,a.size,i.defaults.SOGoAlternateAvatar),r({method:"GET",url:o,cache:!0,headers:{Accept:"image/*"}}).then(function(){a.url||(a.url=o,a.urlEmail=n,c())},function(){l()}))):e||l()}),"sg-src"in t[0].attributes&&e.$watch(function(){return a.src},function(e){e&&(a.url=e,a.urlEmail=""+a.email,t.addClass("sg-avatar-image--zoomable"),o=function(){t.toggleClass("sg-avatar-image--zoom")},t.on("click",o),c())})}e.$inject=["$scope","$element","$http","$q","Preferences","Gravatar"],angular.module("SOGo.Common").directive("sgAvatarImage",function(){return{restrict:"AE",scope:{},bindToController:{size:"@",email:"=sgEmail",src:"=sgSrc"},transclude:!0,template:['
'," ",' ',' ',"
"].join(""),link:function(e,t,n,o){var r,i=t.find("img"),t=t.find("md-icon"),s=angular.element(t[0]),a=angular.element(t[1]);n.size&&(i.attr("width",n.size),i.attr("height",n.size),s.css("font-size",n.size+"px"),a.css("font-size",parseInt(.4*n.size)+"px"));angular.isDefined(n.ngDisabled)&&(r=e.$watch(n.ngDisabled,function(e){n.disabled&&a.css({display:"block"}),r()}));o.img=i,o.genericImg=s},controller:"sgAvatarImageController",controllerAs:"vm"}}).controller("sgAvatarImageController",e)}(),function(){"use strict";function e(e,l,c){return{link:function(e,t){var n=t[0].querySelector(".sg-button-toggle"),o=n.querySelector(".sg-icon-toggle"),r="md-rotate-180-ccw",i=t[0].querySelector(".sg-block-toggle"),s=!1;function a(){i.setAttribute("aria-hidden",!s),i.setAttribute("aria-expanded",s),s||(i.style.visibility="hidden")}n.classList.add("md-clickable"),angular.element(n).on("click",function(){(s=!s)?o.classList.add(r):o.classList.remove(r),s&&(i.style.visibility="visible"),c(function(){var e=s?i.scrollHeight:0;l(angular.element(i),{easing:"cubic-bezier(0.35, 0, 0.25, 1)",to:{height:e+"px"},duration:.75}).start().then(function(){a()})})}),a()}}}e.$inject=["$mdUtil","$animateCss","$$rAF"],angular.module("SOGo.Common").directive("sgBlockToggle",e)}(),function(){"use strict";function e(a,l,c,u){var d="sg-checked";return{restrict:"E",replace:!0,transclude:!0,require:"?ngModel",template:['