mirror of
https://github.com/inverse-inc/sogo.git
synced 2026-02-17 07:33:57 +00:00
fix(calendar(js)): conditional display of edit and delete buttons
This commit is contained in:
@@ -672,7 +672,8 @@
|
||||
* @apiSuccess (Success 200) {String} endDate End date (ISO8601)
|
||||
* @apiSuccess (Success 200) {String} localizedEndDate Formatted end date
|
||||
* @apiSuccess (Success 200) {String} [localizedEndTime] Formatted end time
|
||||
* @apiSuccess (Success 200) {Number} isReadOnly 1 if event is read-only
|
||||
* @apiSuccess (Success 200) {Number} isEditable 1 if event can be edited by the active user
|
||||
* @apiSuccess (Success 200) {Number} isErasable 1 if event can be deleted by the active user
|
||||
* @apiSuccess (Success 200) {Number} userHasRSVP 1 if owner is invited
|
||||
* @apiSuccess (Success 200) {Number} [reply] 0 if needs-action, 1 if accepted, 2 if declined, 3 if tentative, 4 if delegated
|
||||
* @apiSuccess (Success 200) {Object[]} [attachUrls] Attached URLs
|
||||
@@ -826,7 +827,8 @@
|
||||
[componentCalendar nameInContainer], @"pid",
|
||||
[componentCalendar displayName], @"calendar",
|
||||
[NSNumber numberWithBool: isAllDay], @"isAllDay",
|
||||
[NSNumber numberWithBool: [self isReadOnly]], @"isReadOnly",
|
||||
[NSNumber numberWithBool: [self isEditable]], @"isEditable",
|
||||
[NSNumber numberWithBool: [self isErasable]], @"isErasable",
|
||||
[NSNumber numberWithBool: [self userHasRSVP]], @"userHasRSVP",
|
||||
[eventStartDate iso8601DateString], @"startDate",
|
||||
[eventEndDate iso8601DateString], @"endDate",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* UIxComponentEditor.h - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2006-2015 Inverse inc.
|
||||
* Copyright (C) 2006-2022 Inverse inc.
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -33,7 +33,8 @@
|
||||
SOGoAppointmentFolder *componentCalendar;
|
||||
}
|
||||
|
||||
- (BOOL) isReadOnly;
|
||||
- (BOOL) isEditable;
|
||||
- (BOOL) isErasable;
|
||||
- (BOOL) userHasRSVP;
|
||||
- (NSNumber *) reply;
|
||||
- (BOOL) isChildOccurrence;
|
||||
|
||||
@@ -837,10 +837,21 @@ static NSArray *reminderValues = nil;
|
||||
return rc;
|
||||
}
|
||||
|
||||
- (BOOL) isReadOnly
|
||||
- (BOOL) isEditable
|
||||
{
|
||||
return [self getEventRWType] != componentReadableWritable;
|
||||
return [self getEventRWType] == componentReadableWritable;
|
||||
}
|
||||
|
||||
- (BOOL) isErasable
|
||||
{
|
||||
NSString *owner, *userLogin;
|
||||
|
||||
userLogin = [[context activeUser] login];
|
||||
owner = [componentCalendar ownerInContext: context];
|
||||
|
||||
return ([owner isEqualToString: userLogin] || [[componentCalendar aclsForUser: userLogin] containsObject: SOGoRole_ObjectEraser]);
|
||||
}
|
||||
|
||||
//
|
||||
//- (NSString *) emailAlarmsEnabled
|
||||
//{
|
||||
|
||||
@@ -431,7 +431,8 @@
|
||||
* @apiSuccess (Success 200) {String} localizedDueTime Formatted due time
|
||||
* @apiSuccess (Success 200) {String} localizedCompletedDate Formatted completed date
|
||||
* @apiSuccess (Success 200) {String} localizedCompletedTime Formatted completed time
|
||||
* @apiSuccess (Success 200) {Number} isReadOnly 1 if task is read-only
|
||||
* @apiSuccess (Success 200) {Number} isEditable 1 if task can be edited by the active user
|
||||
* @apiSuccess (Success 200) {Number} isErasable 1 if task can be deleted by the active user
|
||||
* @apiSuccess (Success 200) {Object[]} [attachUrls] Attached URLs
|
||||
* @apiSuccess (Success 200) {String} attachUrls.value URL
|
||||
*
|
||||
@@ -561,7 +562,8 @@
|
||||
data = [NSMutableDictionary dictionaryWithObjectsAndKeys:
|
||||
[componentCalendar nameInContainer], @"pid",
|
||||
[componentCalendar displayName], @"calendar",
|
||||
[NSNumber numberWithBool: [self isReadOnly]], @"isReadOnly",
|
||||
[NSNumber numberWithBool: [self isEditable]], @"isEditable",
|
||||
[NSNumber numberWithBool: [self isErasable]], @"isErasable",
|
||||
[self alarm], @"alarm",
|
||||
nil];
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
<label><var:string label:value="Calendar"/></label>
|
||||
<md-select ng-model="editor.component.destinationCalendar"
|
||||
ng-change="editor.changeCalendar()">
|
||||
<md-option ng-repeat="calendar in editor.service.$findAll(null, true)"
|
||||
<md-option ng-repeat="calendar in editor.destinationCalendars()"
|
||||
ng-value="calendar.id">
|
||||
<div layout="row" layout-align="start center">
|
||||
<div class="sg-color-chip"
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
</md-menu-content>
|
||||
</md-menu>
|
||||
</md-menu-item>
|
||||
<md-menu-item ng-show="editor.component.isMovable()">
|
||||
<md-menu-item ng-show="editor.component.isErasable">
|
||||
<md-menu>
|
||||
<md-button label:aria-label="Move To" ng-click="$mdMenu.open($event)">
|
||||
<var:string label:value="Move To"/>
|
||||
@@ -272,20 +272,23 @@
|
||||
<!-- actions -->
|
||||
|
||||
<!-- editable but not recurrent -->
|
||||
<md-dialog-actions ng-show="::editor.component.isEditable()">
|
||||
<md-dialog-actions ng-show="::editor.component.isActionable()">
|
||||
<md-button class="md-warn"
|
||||
label:aria-label="Delete Event"
|
||||
ng-show="::editor.component.isErasable"
|
||||
ng-click="editor.deleteAllOccurrences()">
|
||||
<var:string label:value="Delete"/>
|
||||
</md-button>
|
||||
<div class="md-flex"><!-- spacer --></div>
|
||||
<md-button type="button" ng-click="editor.edit()">
|
||||
<md-button type="button"
|
||||
ng-show="::editor.component.isEditable"
|
||||
ng-click="editor.edit()">
|
||||
<var:string label:value="Edit"/>
|
||||
</md-button>
|
||||
</md-dialog-actions>
|
||||
<!-- editable and recurrent -->
|
||||
<md-dialog-actions ng-show="::editor.component.isEditableOccurrence()">
|
||||
<md-menu>
|
||||
<md-dialog-actions ng-show="::editor.component.isActionableOccurrence()">
|
||||
<md-menu ng-show="::editor.component.isErasable">
|
||||
<md-button class="md-warn"
|
||||
label:aria-label="Delete Event"
|
||||
ng-click="$mdMenu.open()"
|
||||
@@ -310,7 +313,7 @@
|
||||
</md-menu-content>
|
||||
</md-menu>
|
||||
<div class="md-flex"><!-- spacer --></div>
|
||||
<md-menu>
|
||||
<md-menu ng-show="::editor.component.isEditable">
|
||||
<md-button label:aria-label="Edit"
|
||||
ng-click="$mdMenu.open()"
|
||||
md-menu-origin="md-menu-origin">
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
<md-input-container flex="50" flex-xs="100">
|
||||
<label><var:string label:value="Calendar"/></label>
|
||||
<md-select ng-model="editor.component.destinationCalendar">
|
||||
<md-option ng-repeat="calendar in editor.service.$findAll(null, true)"
|
||||
<md-option ng-repeat="calendar in editor.destinationCalendars()"
|
||||
ng-value="calendar.id">
|
||||
<div layout="row" layout-align="start center">
|
||||
<div class="sg-color-chip"
|
||||
|
||||
@@ -125,19 +125,22 @@
|
||||
<!-- actions -->
|
||||
|
||||
<!-- editable but not recurrent -->
|
||||
<md-dialog-actions ng-show="::editor.component.isEditable()">
|
||||
<md-dialog-actions ng-show="::editor.component.isActionable()">
|
||||
<md-button class="md-warn" label:aria-label="Delete Task"
|
||||
ng-show="::editor.component.isErasable"
|
||||
ng-click="editor.deleteAllOccurrences()">
|
||||
<var:string label:value="Delete"/>
|
||||
</md-button>
|
||||
<div class="md-flex"><!-- spacer --></div>
|
||||
<md-button ng-click="editor.edit()">
|
||||
<md-button type="button"
|
||||
ng-show="::editor.component.isEditable"
|
||||
ng-click="editor.edit()">
|
||||
<var:string label:value="Edit"/>
|
||||
</md-button>
|
||||
</md-dialog-actions>
|
||||
<!-- editable and recurrent -->
|
||||
<md-dialog-actions ng-show="::editor.component.isEditableOccurrence()">
|
||||
<md-menu>
|
||||
<md-dialog-actions ng-show="::editor.component.isActionableOccurrence()">
|
||||
<md-menu ng-show="::editor.component.isErasable">
|
||||
<md-button class="md-warn"
|
||||
label:aria-label="Delete Task"
|
||||
ng-click="$mdMenu.open()"
|
||||
@@ -162,7 +165,7 @@
|
||||
</md-menu-content>
|
||||
</md-menu>
|
||||
<div class="md-flex"><!-- spacer --></div>
|
||||
<md-menu>
|
||||
<md-menu ng-show="::editor.component.isEditable">
|
||||
<md-button label:aria-label="Edit"
|
||||
ng-click="$mdMenu.open()"
|
||||
md-menu-origin="md-menu-origin">
|
||||
|
||||
@@ -116,7 +116,7 @@
|
||||
* @param {bool} [writable] - if true, returns only the list of writable calendars
|
||||
* @returns the list of calendars
|
||||
*/
|
||||
Calendar.$findAll = function(data, writable) {
|
||||
Calendar.$findAll = function(data, writable, contextId) {
|
||||
var _this = this;
|
||||
if (data) {
|
||||
this.$calendars = [];
|
||||
@@ -144,7 +144,7 @@
|
||||
|
||||
if (writable) {
|
||||
return _.union(this.$calendars, _.filter(this.$subscriptions, function(calendar) {
|
||||
return calendar.isOwned || calendar.acls.objectCreator;
|
||||
return calendar.isOwned || calendar.acls.objectCreator || calendar.id == contextId;
|
||||
}));
|
||||
}
|
||||
|
||||
|
||||
@@ -672,8 +672,8 @@
|
||||
* @desc Check if the component is editable and not an occurrence of a recurrent component
|
||||
* @returns true or false
|
||||
*/
|
||||
Component.prototype.isEditable = function() {
|
||||
return (!this.occurrenceId && !this.isReadOnly);
|
||||
Component.prototype.isActionable = function() {
|
||||
return (!this.occurrenceId && !this.userHasRSVP && (this.isEditable || this.isErasable));
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -682,8 +682,8 @@
|
||||
* @desc Check if the component is editable and an occurrence of a recurrent component
|
||||
* @returns true or false
|
||||
*/
|
||||
Component.prototype.isEditableOccurrence = function() {
|
||||
return (this.occurrenceId && !this.isReadOnly);
|
||||
Component.prototype.isActionableOccurrence = function() {
|
||||
return (this.occurrenceId && !this.userHasRSVP && (this.isEditable || this.isErasable));
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -706,18 +706,6 @@
|
||||
return (this.occurrenceId && this.userHasRSVP);
|
||||
};
|
||||
|
||||
/**
|
||||
* @function isMovable
|
||||
* @memberof Component.prototype
|
||||
* @desc Return true if the component can be moved to a different calendar which occurs in two cases:
|
||||
* - the component is editable, ie is owned by the current user;
|
||||
* - the component is an invitation and the current user is an attendee.
|
||||
* @returns true or false
|
||||
*/
|
||||
Component.prototype.isMovable = function() {
|
||||
return (!this.isReadOnly || this.userHasRSVP);
|
||||
};
|
||||
|
||||
/**
|
||||
* @function showPercentComplete
|
||||
* @memberof Component.prototype
|
||||
@@ -810,7 +798,7 @@
|
||||
*/
|
||||
Component.prototype.canRemindAttendeesByEmail = function() {
|
||||
return this.alarm.action == 'email' &&
|
||||
!this.isReadOnly &&
|
||||
this.isEditable &&
|
||||
this.attendees && this.attendees.length > 0;
|
||||
};
|
||||
|
||||
|
||||
@@ -278,6 +278,13 @@
|
||||
this.showRecurrenceEditor = true;
|
||||
};
|
||||
|
||||
this.destinationCalendars = function () {
|
||||
if (this.component.isErasable)
|
||||
return Calendar.$findAll(null, true, this.component.pid);
|
||||
else
|
||||
return [Calendar.$get(this.component.pid)];
|
||||
};
|
||||
|
||||
this.changeCalendar = function () {
|
||||
var updateRequired = (this.component.attendees && this.component.attendees.length > 0);
|
||||
if (updateRequired)
|
||||
|
||||
Reference in New Issue
Block a user