From feee156c0a171d1cc22db6263aa4e3028c0deb2e Mon Sep 17 00:00:00 2001 From: Ludovic Marcotte Date: Fri, 24 Apr 2015 16:07:48 -0400 Subject: [PATCH] Added calendar sharing capability --- UI/Scheduler/UIxCalUserRightsEditor.m | 30 +++-- UI/Scheduler/product.plist | 2 + .../UIxContactsUserRightsEditor.wox | 16 ++- UI/Templates/SchedulerUI/UIxCalMainView.wox | 11 +- .../SchedulerUI/UIxCalUserRightsEditor.wox | 103 +++++++++++------- UI/WebServerResources/angular-material | 2 +- UI/WebServerResources/js/Common/user-model.js | 6 +- UI/WebServerResources/js/SchedulerUI.js | 74 ++++++++++++- .../components/bottomSheet/bottomSheet.scss | 10 +- .../scss/components/sidenav/sidenav.scss | 4 +- .../scss/components/toolbar/toolbar.scss | 4 +- 11 files changed, 197 insertions(+), 65 deletions(-) diff --git a/UI/Scheduler/UIxCalUserRightsEditor.m b/UI/Scheduler/UIxCalUserRightsEditor.m index 00534bff8..33fa93b4a 100644 --- a/UI/Scheduler/UIxCalUserRightsEditor.m +++ b/UI/Scheduler/UIxCalUserRightsEditor.m @@ -23,6 +23,7 @@ #import #import #import +#import #import #import @@ -94,22 +95,35 @@ return rightsForType; } -- (void) updateRights +- (NSDictionary *) userRightsForObject +{ + NSMutableDictionary *d; + + [self prepareRightsForm]; + + d = [NSMutableDictionary dictionaryWithObjectsAndKeys: + [NSNumber numberWithBool:[self userCanCreateObjects]], @"canCreateObjects", + [NSNumber numberWithBool:[self userCanEraseObjects]], @"canEraseObjects", + nil]; + + [d addEntriesFromDictionary: rights]; + + return d; +} + +- (void) updateRights: (NSDictionary *) newRights { NSEnumerator *types; NSString *currentType, *currentValue; NSArray *rightsForType; - WORequest *request; - request = [context request]; types = [[self rightTypes] objectEnumerator]; currentType = [types nextObject]; while (currentType) { rightsForType = [self _rightsForType: currentType]; - currentValue - = [request formValueForKey: - [NSString stringWithFormat: @"%@Right", currentType]]; + currentValue = [newRights objectForKey: currentType]; + if ([currentValue isEqualToString: @"None"]) [self removeAllRightsFromList: rightsForType]; else @@ -119,12 +133,12 @@ currentType = [types nextObject]; } - if ([[request formValueForKey: @"ObjectCreator"] length] > 0) + if ([[newRights objectForKey: @"canCreateObjects"] boolValue]) [self appendRight: SOGoRole_ObjectCreator]; else [self removeRight: SOGoRole_ObjectCreator]; - if ([[request formValueForKey: @"ObjectEraser"] length] > 0) + if ([[newRights objectForKey: @"canEraseObjects"] boolValue]) [self appendRight: SOGoRole_ObjectEraser]; else [self removeRight: SOGoRole_ObjectEraser]; diff --git a/UI/Scheduler/product.plist b/UI/Scheduler/product.plist index d684b659d..a224fbc4d 100644 --- a/UI/Scheduler/product.plist +++ b/UI/Scheduler/product.plist @@ -123,6 +123,7 @@ userRights = { protectedBy = "ReadAcls"; pageName = "UIxCalUserRightsEditor"; + actionName = "userRights"; }; saveUserRights = { protectedBy = "Change Permissions"; @@ -168,6 +169,7 @@ userRights = { protectedBy = "ReadAcls"; pageName = "UIxCalUserRightsEditor"; + actionName = "userRights"; }; saveUserRights = { protectedBy = "Change Permissions"; diff --git a/UI/Templates/ContactsUI/UIxContactsUserRightsEditor.wox b/UI/Templates/ContactsUI/UIxContactsUserRightsEditor.wox index e29a11b07..e79d0c8e3 100644 --- a/UI/Templates/ContactsUI/UIxContactsUserRightsEditor.wox +++ b/UI/Templates/ContactsUI/UIxContactsUserRightsEditor.wox @@ -10,28 +10,36 @@ + ng-change="confirmChange(selectedUser)" + ng-true-value="1" + ng-false-value="0"> + ng-hide="selectedUser.$isAnonymous()" + ng-true-value="1" + ng-false-value="0"> + ng-hide="selectedUser.$isAnonymous()" + ng-true-value="1" + ng-false-value="0"> + ng-hide="selectedUser.$isAnonymous()" + ng-true-value="1" + ng-false-value="0"> diff --git a/UI/Templates/SchedulerUI/UIxCalMainView.wox b/UI/Templates/SchedulerUI/UIxCalMainView.wox index 92d53dc31..ba659dc00 100644 --- a/UI/Templates/SchedulerUI/UIxCalMainView.wox +++ b/UI/Templates/SchedulerUI/UIxCalMainView.wox @@ -175,7 +175,12 @@ label:aria-label="Enable">

{{calendar.name}}

+ ng-class="calendar.getClassName()"> + + + @@ -294,4 +299,8 @@ + + diff --git a/UI/Templates/SchedulerUI/UIxCalUserRightsEditor.wox b/UI/Templates/SchedulerUI/UIxCalUserRightsEditor.wox index 2843c63db..345b1e5a5 100644 --- a/UI/Templates/SchedulerUI/UIxCalUserRightsEditor.wox +++ b/UI/Templates/SchedulerUI/UIxCalUserRightsEditor.wox @@ -10,45 +10,72 @@ title="title" const:toolbar="none" const:popup="YES"> -
- -
- - + +
+ + + +
+ + + + + + + +
-
- -
-
-
+ +
+ + + + + + + +
-
- -
- -
-
- - - - + +
+ + + + + + + +
- + + + + + + + + + +
+ + diff --git a/UI/WebServerResources/angular-material b/UI/WebServerResources/angular-material index 965594586..6fe6a8fb2 160000 --- a/UI/WebServerResources/angular-material +++ b/UI/WebServerResources/angular-material @@ -1 +1 @@ -Subproject commit 96559458633f90dafd543d3a88f9a2165fd76ac3 +Subproject commit 6fe6a8fb20e00c337b60385aef4da9c7f639a92b diff --git a/UI/WebServerResources/js/Common/user-model.js b/UI/WebServerResources/js/Common/user-model.js index 8cff4daa5..d7ad6ecdc 100644 --- a/UI/WebServerResources/js/Common/user-model.js +++ b/UI/WebServerResources/js/Common/user-model.js @@ -90,9 +90,9 @@ User.$$resource.fetch(folderId, 'userRights', param).then(function(data) { _this.rights = data; // Convert numbers (0|1) to boolean values - angular.forEach(_.keys(_this.rights), function(key) { - _this.rights[key] = _this.rights[key] ? true : false; - }); + //angular.forEach(_.keys(_this.rights), function(key) { + // _this.rights[key] = _this.rights[key] ? true : false; + //}); // console.debug('rights ' + _this.uid + ' => ' + JSON.stringify(data, undefined, 2)); // Keep a copy of the server's version _this.$shadowRights = angular.copy(data); diff --git a/UI/WebServerResources/js/SchedulerUI.js b/UI/WebServerResources/js/SchedulerUI.js index 0a88bb816..d05a42c9a 100644 --- a/UI/WebServerResources/js/SchedulerUI.js +++ b/UI/WebServerResources/js/SchedulerUI.js @@ -84,7 +84,8 @@ }) }) - .controller('CalendarsController', ['$scope', '$rootScope', '$stateParams', '$state', '$timeout', '$log', 'sgFocus', 'encodeUriFilter', 'sgDialog', 'sgSettings', 'sgCalendar', 'stateCalendars', function($scope, $rootScope, $stateParams, $state, $timeout, $log, focus, encodeUriFilter, Dialog, Settings, Calendar, stateCalendars) { + + .controller('CalendarsController', ['$scope', '$rootScope', '$stateParams', '$state', '$timeout', '$q', '$mdDialog', '$log', 'sgFocus', 'encodeUriFilter', 'sgDialog', 'sgSettings', 'sgCalendar', 'sgUser', 'stateCalendars', function($scope, $rootScope, $stateParams, $state, $timeout, $q, $mdDialog, $log, focus, encodeUriFilter, Dialog, Settings, Calendar, User, stateCalendars) { var vm = this; vm.activeUser = Settings.activeUser; @@ -115,6 +116,77 @@ true // compare for object equality ); + $scope.share = function(calendar) { + $mdDialog.show({ + templateUrl: calendar.id + '/UIxAclEditor', // UI/Templates/UIxAclEditor.wox + controller: CalendarACLController, + clickOutsideToClose: true, + escapeToClose: true, + locals: { + usersWithACL: calendar.$acl.$users(), + User: User, + stateCalendar: calendar, + q: $q + } + }); + function CalendarACLController($scope, $mdDialog, usersWithACL, User, stateCalendar, q) { + $scope.users = usersWithACL; // ACL users + $scope.stateCalendar = stateCalendar; + $scope.userToAdd = ''; + $scope.searchText = ''; + $scope.userFilter = function($query) { + var deferred = q.defer(); + User.$filter($query).then(function(results) { + deferred.resolve(results) + }); + return deferred.promise; + }; + $scope.closeModal = function() { + stateCalendar.$acl.$resetUsersRights(); // cancel changes + $mdDialog.hide(); + }; + $scope.saveModal = function() { + stateCalendar.$acl.$saveUsersRights().then(function() { + $mdDialog.hide(); + }, function(data, status) { + Dialog.alert(l('Warning'), l('An error occured please try again.')); + }); + }; + $scope.confirmChange = function(user) { + var confirmation = user.$confirmRights(); + if (confirmation) { + Dialog.confirm(l('Warning'), confirmation).then(function(res) { + if (!res) + user.$resetRights(true); + }); + } + }; + $scope.removeUser = function(user) { + stateCalendar.$acl.$removeUser(user.uid).then(function() { + if (user.uid == $scope.selectedUser.uid) { + $scope.selectedUser = null; + } + }, function(data, status) { + Dialog.alert(l('Warning'), l('An error occured please try again.')) + }); + }; + $scope.addUser = function(data) { + stateCalendar.$acl.$addUser(data).then(function() { + $scope.userToAdd = ''; + $scope.searchText = ''; + }, function(error) { + Dialog.alert(l('Warning'), error); + }); + }; + $scope.selectUser = function(user) { + // Check if it is a different user + if ($scope.selectedUser != user) { + $scope.selectedUser = user; + $scope.selectedUser.$rights(); + } + }; + }; + } /** * subscribeToFolder - Callback of sgSubscribe directive */ diff --git a/UI/WebServerResources/scss/components/bottomSheet/bottomSheet.scss b/UI/WebServerResources/scss/components/bottomSheet/bottomSheet.scss index f641edf5d..b4a7270c4 100644 --- a/UI/WebServerResources/scss/components/bottomSheet/bottomSheet.scss +++ b/UI/WebServerResources/scss/components/bottomSheet/bottomSheet.scss @@ -3,19 +3,19 @@ md-bottom-sheet.md-default-theme { border: none; background-color: inherit; - background-image: url("../img/cardboard-transp.png"); - background-blend-mode: multiply; + //background-image: url("../img/cardboard-transp.png"); + //background-blend-mode: multiply; } md-bottom-sheet.md-default-theme .md-button.md-default-theme { &:hover:not([disabled]) { background-color: inherit; - background-image: url("../img/cardboard-transp.png"); - background-blend-mode: multiply; + //background-image: url("../img/cardboard-transp.png"); + //background-blend-mode: multiply; color: sg-color($sogoBlue, 800); } &[disabled] { padding: 6px; // The server remove the 'a' tag when disabling text-transform: uppercase; } -} \ No newline at end of file +} diff --git a/UI/WebServerResources/scss/components/sidenav/sidenav.scss b/UI/WebServerResources/scss/components/sidenav/sidenav.scss index c3ad2afd2..5707aec70 100644 --- a/UI/WebServerResources/scss/components/sidenav/sidenav.scss +++ b/UI/WebServerResources/scss/components/sidenav/sidenav.scss @@ -32,8 +32,8 @@ md-sidenav { & md-content, & md-toolbar { background-color: inherit; - background-image: url("../img/cardboard-transp.png"); - background-blend-mode: multiply; + //background-image: url("../img/cardboard-transp.png"); + //background-blend-mode: multiply; } } diff --git a/UI/WebServerResources/scss/components/toolbar/toolbar.scss b/UI/WebServerResources/scss/components/toolbar/toolbar.scss index ae1854237..cf349b56d 100644 --- a/UI/WebServerResources/scss/components/toolbar/toolbar.scss +++ b/UI/WebServerResources/scss/components/toolbar/toolbar.scss @@ -17,8 +17,8 @@ md-toolbar { z-index: $z-index-toolbar; // dirty fix to override angular-material botchy typography font-size: 1em !important; - background-image: url("../img/felt-transp.png"); - background-blend-mode: luminosity; + //background-image: url("../img/felt-transp.png"); + //background-blend-mode: luminosity; box-shadow: $whiteframe-shadow-z1; }