Added calendar sharing capability
parent
0d62ec0bea
commit
feee156c0a
|
@ -23,6 +23,7 @@
|
||||||
#import <Foundation/NSArray.h>
|
#import <Foundation/NSArray.h>
|
||||||
#import <Foundation/NSDictionary.h>
|
#import <Foundation/NSDictionary.h>
|
||||||
#import <Foundation/NSEnumerator.h>
|
#import <Foundation/NSEnumerator.h>
|
||||||
|
#import <Foundation/NSValue.h>
|
||||||
#import <NGObjWeb/WORequest.h>
|
#import <NGObjWeb/WORequest.h>
|
||||||
#import <SoObjects/SOGo/SOGoPermissions.h>
|
#import <SoObjects/SOGo/SOGoPermissions.h>
|
||||||
|
|
||||||
|
@ -94,22 +95,35 @@
|
||||||
return rightsForType;
|
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;
|
NSEnumerator *types;
|
||||||
NSString *currentType, *currentValue;
|
NSString *currentType, *currentValue;
|
||||||
NSArray *rightsForType;
|
NSArray *rightsForType;
|
||||||
WORequest *request;
|
|
||||||
|
|
||||||
request = [context request];
|
|
||||||
types = [[self rightTypes] objectEnumerator];
|
types = [[self rightTypes] objectEnumerator];
|
||||||
currentType = [types nextObject];
|
currentType = [types nextObject];
|
||||||
while (currentType)
|
while (currentType)
|
||||||
{
|
{
|
||||||
rightsForType = [self _rightsForType: currentType];
|
rightsForType = [self _rightsForType: currentType];
|
||||||
currentValue
|
currentValue = [newRights objectForKey: currentType];
|
||||||
= [request formValueForKey:
|
|
||||||
[NSString stringWithFormat: @"%@Right", currentType]];
|
|
||||||
if ([currentValue isEqualToString: @"None"])
|
if ([currentValue isEqualToString: @"None"])
|
||||||
[self removeAllRightsFromList: rightsForType];
|
[self removeAllRightsFromList: rightsForType];
|
||||||
else
|
else
|
||||||
|
@ -119,12 +133,12 @@
|
||||||
currentType = [types nextObject];
|
currentType = [types nextObject];
|
||||||
}
|
}
|
||||||
|
|
||||||
if ([[request formValueForKey: @"ObjectCreator"] length] > 0)
|
if ([[newRights objectForKey: @"canCreateObjects"] boolValue])
|
||||||
[self appendRight: SOGoRole_ObjectCreator];
|
[self appendRight: SOGoRole_ObjectCreator];
|
||||||
else
|
else
|
||||||
[self removeRight: SOGoRole_ObjectCreator];
|
[self removeRight: SOGoRole_ObjectCreator];
|
||||||
|
|
||||||
if ([[request formValueForKey: @"ObjectEraser"] length] > 0)
|
if ([[newRights objectForKey: @"canEraseObjects"] boolValue])
|
||||||
[self appendRight: SOGoRole_ObjectEraser];
|
[self appendRight: SOGoRole_ObjectEraser];
|
||||||
else
|
else
|
||||||
[self removeRight: SOGoRole_ObjectEraser];
|
[self removeRight: SOGoRole_ObjectEraser];
|
||||||
|
|
|
@ -123,6 +123,7 @@
|
||||||
userRights = {
|
userRights = {
|
||||||
protectedBy = "ReadAcls";
|
protectedBy = "ReadAcls";
|
||||||
pageName = "UIxCalUserRightsEditor";
|
pageName = "UIxCalUserRightsEditor";
|
||||||
|
actionName = "userRights";
|
||||||
};
|
};
|
||||||
saveUserRights = {
|
saveUserRights = {
|
||||||
protectedBy = "Change Permissions";
|
protectedBy = "Change Permissions";
|
||||||
|
@ -168,6 +169,7 @@
|
||||||
userRights = {
|
userRights = {
|
||||||
protectedBy = "ReadAcls";
|
protectedBy = "ReadAcls";
|
||||||
pageName = "UIxCalUserRightsEditor";
|
pageName = "UIxCalUserRightsEditor";
|
||||||
|
actionName = "userRights";
|
||||||
};
|
};
|
||||||
saveUserRights = {
|
saveUserRights = {
|
||||||
protectedBy = "Change Permissions";
|
protectedBy = "Change Permissions";
|
||||||
|
|
|
@ -10,28 +10,36 @@
|
||||||
|
|
||||||
<md-checkbox name="canViewObjects"
|
<md-checkbox name="canViewObjects"
|
||||||
ng-model="selectedUser.rights.canViewObjects"
|
ng-model="selectedUser.rights.canViewObjects"
|
||||||
ng-change="confirmChange(selectedUser)" >
|
ng-change="confirmChange(selectedUser)"
|
||||||
|
ng-true-value="1"
|
||||||
|
ng-false-value="0">
|
||||||
<var:string label:value="This person can read the cards of this addressbook." />
|
<var:string label:value="This person can read the cards of this addressbook." />
|
||||||
</md-checkbox>
|
</md-checkbox>
|
||||||
|
|
||||||
<md-checkbox name="canCreateObjects"
|
<md-checkbox name="canCreateObjects"
|
||||||
ng-model="selectedUser.rights.canCreateObjects"
|
ng-model="selectedUser.rights.canCreateObjects"
|
||||||
ng-change="confirmChange(selectedUser)"
|
ng-change="confirmChange(selectedUser)"
|
||||||
ng-hide="selectedUser.$isAnonymous()">
|
ng-hide="selectedUser.$isAnonymous()"
|
||||||
|
ng-true-value="1"
|
||||||
|
ng-false-value="0">
|
||||||
<var:string label:value="This person can add cards to this addressbook." />
|
<var:string label:value="This person can add cards to this addressbook." />
|
||||||
</md-checkbox>
|
</md-checkbox>
|
||||||
|
|
||||||
<md-checkbox name="canEditObjects"
|
<md-checkbox name="canEditObjects"
|
||||||
ng-model="selectedUser.rights.canEditObjects"
|
ng-model="selectedUser.rights.canEditObjects"
|
||||||
ng-change="confirmChange(selectedUser)"
|
ng-change="confirmChange(selectedUser)"
|
||||||
ng-hide="selectedUser.$isAnonymous()">
|
ng-hide="selectedUser.$isAnonymous()"
|
||||||
|
ng-true-value="1"
|
||||||
|
ng-false-value="0">
|
||||||
<var:string label:value="This person can edit the cards of this addressbook." />
|
<var:string label:value="This person can edit the cards of this addressbook." />
|
||||||
</md-checkbox>
|
</md-checkbox>
|
||||||
|
|
||||||
<md-checkbox name="canEraseObjects"
|
<md-checkbox name="canEraseObjects"
|
||||||
ng-model="selectedUser.rights.canEraseObjects"
|
ng-model="selectedUser.rights.canEraseObjects"
|
||||||
ng-change="confirmChange(selectedUser)"
|
ng-change="confirmChange(selectedUser)"
|
||||||
ng-hide="selectedUser.$isAnonymous()">
|
ng-hide="selectedUser.$isAnonymous()"
|
||||||
|
ng-true-value="1"
|
||||||
|
ng-false-value="0">
|
||||||
<var:string label:value="This person can erase cards from this addressbook." />
|
<var:string label:value="This person can erase cards from this addressbook." />
|
||||||
</md-checkbox>
|
</md-checkbox>
|
||||||
|
|
||||||
|
|
|
@ -175,7 +175,12 @@
|
||||||
label:aria-label="Enable"><!-- enable --></md-checkbox>
|
label:aria-label="Enable"><!-- enable --></md-checkbox>
|
||||||
<p class="sg-item-name">{{calendar.name}}</p>
|
<p class="sg-item-name">{{calendar.name}}</p>
|
||||||
<i class="md-icon-turned-in md-display-8"
|
<i class="md-icon-turned-in md-display-8"
|
||||||
ng-class="calendar.getClassName()"><!-- calendar color --></i>
|
ng-class="calendar.getClassName()"><!-- calendar
|
||||||
|
color --></i>
|
||||||
|
<md-button class="iconButton" label:aria-label="Options"
|
||||||
|
ng-click="share(calendar)">
|
||||||
|
<i class="md-icon-more-vert"><!-- options --></i>
|
||||||
|
</md-button>
|
||||||
</md-list-item>
|
</md-list-item>
|
||||||
</md-list>
|
</md-list>
|
||||||
</section>
|
</section>
|
||||||
|
@ -294,4 +299,8 @@
|
||||||
</section>
|
</section>
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<script type="text/ng-template" id="UIxUserRightsEditor">
|
||||||
|
<var:component className="UIxCalUserRightsEditor" />
|
||||||
|
</script>
|
||||||
|
|
||||||
</var:component>
|
</var:component>
|
||||||
|
|
|
@ -10,45 +10,72 @@
|
||||||
title="title"
|
title="title"
|
||||||
const:toolbar="none"
|
const:toolbar="none"
|
||||||
const:popup="YES">
|
const:popup="YES">
|
||||||
<form id="userRightsForm" const:href="saveUserRights">
|
|
||||||
<input id="uid" type="hidden" name="uid" var:value="uid"/>
|
<div class="calendarUserRights" layout="column">
|
||||||
<div class="title">
|
|
||||||
<label><span><var:string label:value="Access rights to"/></span>
|
|
||||||
<span id="folderName" class="value"><var:string value="folderName"/></span></label>
|
<!-- <var:foreach list="rightTypes" item="currentRightType">
|
||||||
<label><span><var:string label:value="For user"/></span>
|
<div><span><var:string value="currentRightTypeLabel"/></span>
|
||||||
<span class="value"><var:string value="userDisplayName"/></span></label>
|
<var:popup list="objectRights" item="currentRight"
|
||||||
|
var:name="currentRightTypeName"
|
||||||
|
var:value="currentRight"
|
||||||
|
string="currentRightLabel"
|
||||||
|
selection="currentRightSelection"
|
||||||
|
/></div>
|
||||||
|
</var:foreach>
|
||||||
|
-->
|
||||||
|
<div layout="row" layout-align="space-around center">
|
||||||
|
<var:string label:value="Public"/>
|
||||||
|
<md-select ng-model="selectedUser.rights.Public">
|
||||||
|
<var:foreach list="objectRights" item="currentRight">
|
||||||
|
<md-option var:value="currentRight">
|
||||||
|
<var:string value="currentRightLabel"/>
|
||||||
|
</md-option>
|
||||||
|
</var:foreach>
|
||||||
|
</md-select>
|
||||||
</div>
|
</div>
|
||||||
<div class="calendarUserRights">
|
|
||||||
<var:foreach list="rightTypes" item="currentRightType">
|
<div layout="row" layout-align="space-around center">
|
||||||
<div><span><var:string value="currentRightTypeLabel"/></span>
|
<var:string label:value="Confidential"/>
|
||||||
<var:popup list="objectRights" item="currentRight"
|
<md-select ng-model="selectedUser.rights.Confidential">
|
||||||
var:name="currentRightTypeName"
|
<var:foreach list="objectRights" item="currentRight">
|
||||||
var:value="currentRight"
|
<md-option var:value="currentRight">
|
||||||
string="currentRightLabel"
|
<var:string value="currentRightLabel"/>
|
||||||
selection="currentRightSelection"
|
</md-option>
|
||||||
/></div>
|
</var:foreach>
|
||||||
</var:foreach>
|
</md-select>
|
||||||
</div>
|
</div>
|
||||||
<var:if condition="userIsAnonymousUser" const:negate="YES"
|
|
||||||
><div class="basicUserRights">
|
<div layout="row" layout-align="space-around center">
|
||||||
<label><input type="checkbox" class="checkBox"
|
<var:string label:value="Private"/>
|
||||||
const:name="ObjectCreator"
|
<md-select ng-model="selectedUser.rights.Private">
|
||||||
var:checked="userCanCreateObjects"/><var:string
|
<var:foreach list="objectRights" item="currentRight">
|
||||||
label:value="This person can create objects in my calendar."
|
<md-option var:value="currentRight">
|
||||||
/></label>
|
<var:string value="currentRightLabel"/>
|
||||||
<br/>
|
</md-option>
|
||||||
<label><input type="checkbox" class="checkBox"
|
</var:foreach>
|
||||||
const:name="ObjectEraser"
|
</md-select>
|
||||||
var:checked="userCanEraseObjects"/><var:string
|
|
||||||
label:value="This person can erase objects from my calendar."
|
|
||||||
/></label>
|
|
||||||
</div></var:if>
|
|
||||||
<div class="buttons">
|
|
||||||
<a href="#" const:name="updateButton" id="updateButton"
|
|
||||||
class="button actionButton">
|
|
||||||
<span><var:string label:value="Update" /></span></a>
|
|
||||||
<a href="#" const:name="cancelButton" id="cancelButton" class="button">
|
|
||||||
<span><var:string label:value="Cancel" /></span></a>
|
|
||||||
</div>
|
</div>
|
||||||
</form>
|
|
||||||
|
<md-checkbox name="canCreateObjects"
|
||||||
|
ng-model="selectedUser.rights.canCreateObjects"
|
||||||
|
ng-change="confirmChange(selectedUser)"
|
||||||
|
ng-hide="selectedUser.$isAnonymous()"
|
||||||
|
ng-true-value="1"
|
||||||
|
ng-false-value="0">
|
||||||
|
<var:string label:value="This person can create objects in my calendar." />
|
||||||
|
</md-checkbox>
|
||||||
|
|
||||||
|
<md-checkbox name="canEraseObjects"
|
||||||
|
ng-model="selectedUser.rights.canEraseObjects"
|
||||||
|
ng-change="confirmChange(selectedUser)"
|
||||||
|
ng-hide="selectedUser.$isAnonymous()"
|
||||||
|
ng-true-value="1"
|
||||||
|
ng-false-value="0">
|
||||||
|
<var:string label:value="This person can erase objects from my calendar." />
|
||||||
|
</md-checkbox>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
</var:component>
|
</var:component>
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit 96559458633f90dafd543d3a88f9a2165fd76ac3
|
Subproject commit 6fe6a8fb20e00c337b60385aef4da9c7f639a92b
|
|
@ -90,9 +90,9 @@
|
||||||
User.$$resource.fetch(folderId, 'userRights', param).then(function(data) {
|
User.$$resource.fetch(folderId, 'userRights', param).then(function(data) {
|
||||||
_this.rights = data;
|
_this.rights = data;
|
||||||
// Convert numbers (0|1) to boolean values
|
// Convert numbers (0|1) to boolean values
|
||||||
angular.forEach(_.keys(_this.rights), function(key) {
|
//angular.forEach(_.keys(_this.rights), function(key) {
|
||||||
_this.rights[key] = _this.rights[key] ? true : false;
|
// _this.rights[key] = _this.rights[key] ? true : false;
|
||||||
});
|
//});
|
||||||
// console.debug('rights ' + _this.uid + ' => ' + JSON.stringify(data, undefined, 2));
|
// console.debug('rights ' + _this.uid + ' => ' + JSON.stringify(data, undefined, 2));
|
||||||
// Keep a copy of the server's version
|
// Keep a copy of the server's version
|
||||||
_this.$shadowRights = angular.copy(data);
|
_this.$shadowRights = angular.copy(data);
|
||||||
|
|
|
@ -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;
|
var vm = this;
|
||||||
|
|
||||||
vm.activeUser = Settings.activeUser;
|
vm.activeUser = Settings.activeUser;
|
||||||
|
@ -115,6 +116,77 @@
|
||||||
true // compare for object equality
|
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
|
* subscribeToFolder - Callback of sgSubscribe directive
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -3,19 +3,19 @@
|
||||||
md-bottom-sheet.md-default-theme {
|
md-bottom-sheet.md-default-theme {
|
||||||
border: none;
|
border: none;
|
||||||
background-color: inherit;
|
background-color: inherit;
|
||||||
background-image: url("../img/cardboard-transp.png");
|
//background-image: url("../img/cardboard-transp.png");
|
||||||
background-blend-mode: multiply;
|
//background-blend-mode: multiply;
|
||||||
}
|
}
|
||||||
|
|
||||||
md-bottom-sheet.md-default-theme .md-button.md-default-theme {
|
md-bottom-sheet.md-default-theme .md-button.md-default-theme {
|
||||||
&:hover:not([disabled]) {
|
&:hover:not([disabled]) {
|
||||||
background-color: inherit;
|
background-color: inherit;
|
||||||
background-image: url("../img/cardboard-transp.png");
|
//background-image: url("../img/cardboard-transp.png");
|
||||||
background-blend-mode: multiply;
|
//background-blend-mode: multiply;
|
||||||
color: sg-color($sogoBlue, 800);
|
color: sg-color($sogoBlue, 800);
|
||||||
}
|
}
|
||||||
&[disabled] {
|
&[disabled] {
|
||||||
padding: 6px; // The server remove the 'a' tag when disabling
|
padding: 6px; // The server remove the 'a' tag when disabling
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,8 +32,8 @@ md-sidenav {
|
||||||
& md-content,
|
& md-content,
|
||||||
& md-toolbar {
|
& md-toolbar {
|
||||||
background-color: inherit;
|
background-color: inherit;
|
||||||
background-image: url("../img/cardboard-transp.png");
|
//background-image: url("../img/cardboard-transp.png");
|
||||||
background-blend-mode: multiply;
|
//background-blend-mode: multiply;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,8 +17,8 @@ md-toolbar {
|
||||||
z-index: $z-index-toolbar;
|
z-index: $z-index-toolbar;
|
||||||
// dirty fix to override angular-material botchy typography
|
// dirty fix to override angular-material botchy typography
|
||||||
font-size: 1em !important;
|
font-size: 1em !important;
|
||||||
background-image: url("../img/felt-transp.png");
|
//background-image: url("../img/felt-transp.png");
|
||||||
background-blend-mode: luminosity;
|
//background-blend-mode: luminosity;
|
||||||
box-shadow: $whiteframe-shadow-z1;
|
box-shadow: $whiteframe-shadow-z1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue