Merge pull request #523 from nextcloud/permissions

Correctly handle tasks in read-only calendars
This commit is contained in:
Raimund Schlüßler 2019-07-25 21:34:58 +02:00 committed by GitHub
commit 93270e2434
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 70 additions and 11 deletions

View file

@ -990,6 +990,15 @@
margin: 1px -1px;
vertical-align: middle;
&.multiselect--disabled {
background-color: var(--color-main-background) !important;
cursor: default;
.multiselect__single, input:not([type='range']):disabled {
background-color: var(--color-main-background) !important;
cursor: default;
}
}
&.multiselect--active .multiselect__tags {
border: 1px solid var(--color-border-dark);
}
@ -1105,6 +1114,18 @@
}
.disabled .body .section {
> div {
.calendar-indicator {
cursor: default;
}
}
&.detail-all-day {
div,
span {
cursor: default;
}
}
&.date:hover .icon.icon-trash {
display: none;
@ -1153,6 +1174,10 @@
}
}
&.disabled {
cursor: not-allowed;
}
&.active {
opacity: .7;
}

View file

@ -47,11 +47,11 @@ License along with this library. If not, see <http://www.gnu.org/licenses/>.
role="checkbox"
@click="toggleCompleted(task)"
>
<span :class="{'icon-checkmark': task.completed}" class="icon icon-bw task-checkbox reactive no-nav" />
<span :class="{'icon-checkmark': task.completed, 'disabled': task.calendar.readOnly}" class="icon icon-bw task-checkbox reactive no-nav" />
</span>
<span class="icon task-separator" />
<span class="task-star" @click="toggleStarred(task)">
<span :class="[iconStar]" class="icon right large reactive no-nav" />
<span :class="[iconStar, {'disabled': task.calendar.readOnly}]" class="icon right large reactive no-nav" />
</span>
<span v-if="!task.calendar.readOnly"
class="task-addsubtask add-subtask"

View file

@ -65,7 +65,7 @@ License along with this library. If not, see <http://www.gnu.org/licenses/>.
/>
</task-drag-container>
<LoadCompletedButton :calendar="calendar" />
<DeleteCompletedModal v-if="calendar.loadedCompleted" :calendar="calendar" />
<DeleteCompletedModal v-if="calendar.loadedCompleted && !calendar.readOnly" :calendar="calendar" />
</div>
</div>
</div>

View file

@ -61,7 +61,7 @@ License along with this library. If not, see <http://www.gnu.org/licenses/>.
</div>
<div class="body">
<ul class="sections">
<li :class="{'date': valid(task.start), 'editing': edit=='start', 'high': overdue(task.start)}"
<li v-show="!task.calendar.readOnly || task.start" :class="{'date': valid(task.start), 'editing': edit=='start', 'high': overdue(task.start)}"
class="section detail-start"
>
<div v-click-outside="() => finishEditing('start')"
@ -95,7 +95,7 @@ License along with this library. If not, see <http://www.gnu.org/licenses/>.
</a>
</div>
</li>
<li :class="{'date': valid(task.due), 'editing': edit=='due', 'high': overdue(task.due)}"
<li v-show="!task.calendar.readOnly || task.due" :class="{'date': valid(task.due), 'editing': edit=='due', 'high': overdue(task.due)}"
class="section detail-date"
>
<div v-click-outside="() => finishEditing('due')"
@ -152,6 +152,7 @@ License along with this library. If not, see <http://www.gnu.org/licenses/>.
:value="task.calendar"
:multiple="false"
:allow-empty="false"
:disabled="task.calendar.readOnly"
track-by="id"
:placeholder="t('tasks', 'Select a calendar')"
label="displayName"
@ -174,6 +175,7 @@ License along with this library. If not, see <http://www.gnu.org/licenses/>.
:value="classSelect.find( _ => _.type === task.class )"
:multiple="false"
:allow-empty="false"
:disabled="task.calendar.readOnly"
track-by="type"
:placeholder="t('tasks', 'Select a classification')"
label="displayName"
@ -186,7 +188,7 @@ License along with this library. If not, see <http://www.gnu.org/licenses/>.
</div>
</div>
</li>
<li :class="[{'editing': edit=='priority', 'date': task.priority>0}, priorityString]"
<li v-show="!task.calendar.readOnly || task.priority" :class="[{'editing': edit=='priority', 'date': task.priority>0}, priorityString]"
class="section detail-priority"
>
<div v-click-outside="() => finishEditing('priority')"
@ -224,7 +226,7 @@ License along with this library. If not, see <http://www.gnu.org/licenses/>.
</a>
</div>
</li>
<li :class="{'editing': edit=='complete', 'date': task.complete>0}"
<li v-show="!task.calendar.readOnly || task.complete" :class="{'editing': edit=='complete', 'date': task.complete>0}"
class="section detail-complete"
>
<div v-click-outside="() => finishEditing('complete')"
@ -260,7 +262,7 @@ License along with this library. If not, see <http://www.gnu.org/licenses/>.
</a>
</div>
</li>
<li :class="{'active': task.categories.length>0}" class="section detail-categories">
<li v-show="!task.calendar.readOnly || task.categories.length>0" :class="{'active': task.categories.length>0}" class="section detail-categories">
<div>
<span :class="[iconCategories]" class="icon detail-categories" />
<div class="detail-categories-container">
@ -268,6 +270,7 @@ License along with this library. If not, see <http://www.gnu.org/licenses/>.
v-model="task.categories"
:multiple="true"
:searchable="true"
:disabled="task.calendar.readOnly"
:options="task.categories"
:placeholder="t('tasks', 'Select categories')"
:taggable="true"
@ -280,7 +283,7 @@ License along with this library. If not, see <http://www.gnu.org/licenses/>.
</div>
</div>
</li>
<li class="section detail-note">
<li v-show="!task.calendar.readOnly || task.note" class="section detail-note">
<div class="note">
<div v-click-outside="() => finishEditing('note')"
class="note-body selectable"
@ -304,7 +307,7 @@ License along with this library. If not, see <http://www.gnu.org/licenses/>.
</ul>
</div>
<div class="footer">
<a v-show="!task.calendar.readOnly"
<a :style="{visibility: task.calendar.readOnly ? 'hidden' : 'visible'}"
class="close-all reactive"
@click="removeTask"
>
@ -520,7 +523,7 @@ export default {
+ (this.task.completed ? ('<br />' + t('tasks', 'Completed %s').replace('%s', moment(this.task.completedDate, 'YYYY-MM-DDTHH:mm:ss').calendar())) : '')
},
isAllDayPossible: function() {
return !this.task.calendar.readOnly && (this.task.due || this.task.start)
return !this.task.calendar.readOnly || (this.task.due || this.task.start)
},
priorityString: function() {
if (+this.task.priority > 5) {

View file

@ -566,6 +566,11 @@ const actions = {
taskData.calendar = context.getters.getDefaultCalendar
}
// Don't try to create tasks in read-only calendars
if (taskData.calendar.readOnly) {
return
}
let task = new Task('BEGIN:VCALENDAR\nVERSION:2.0\nPRODID:-//Nextcloud Tasks v' + appVersion + '\nEND:VCALENDAR', taskData.calendar)
task.created = ICAL.Time.now()
@ -632,6 +637,11 @@ const actions = {
* @param {Boolean} [data.dav = true] Trigger a dav deletion
*/
async deleteTask(context, { task, dav = true }) {
// Don't try to delete tasks in read-only calendars
if (task.calendar.readOnly) {
return
}
function deleteTaskFromStore() {
context.commit('deleteTask', task)
let parent = context.getters.getTaskByUid(task.related)
@ -680,6 +690,11 @@ const actions = {
* @returns {Promise}
*/
async updateTask(context, task) {
// Don't try to update tasks in read-only calendars
if (task.calendar.readOnly) {
return
}
let vCalendar = ICAL.stringify(task.jCal)
if (!task.conflict) {
@ -712,6 +727,10 @@ const actions = {
* @param {Task} task The task to update
*/
async toggleCompleted(context, task) {
// Don't try to edit tasks in read-only calendars
if (task.calendar.readOnly) {
return
}
if (task.completed) {
await context.dispatch('setPercentComplete', { task: task, complete: 0 })
} else {
@ -773,6 +792,10 @@ const actions = {
* @param {Task} task The task to update
*/
async toggleStarred(context, task) {
// Don't try to edit tasks in read-only calendars
if (task.calendar.readOnly) {
return
}
context.commit('toggleStarred', task)
context.dispatch('scheduleTaskUpdate', task)
},
@ -876,6 +899,10 @@ const actions = {
* @param {Task} task The task to update
*/
async toggleAllDay(context, task) {
// Don't try to toggle tasks from read-only calendars
if (task.calendar.readOnly) {
return task
}
context.commit('toggleAllDay', task)
context.dispatch('scheduleTaskUpdate', task)
},
@ -943,6 +970,10 @@ const actions = {
* @returns {Task} The moved task
*/
async moveTask(context, { task, calendar, parent = null }) {
// Don't try to move tasks from read-only calendars
if (task.calendar.readOnly) {
return task
}
// Don't move if source and target calendar are the same.
if (task.dav && task.calendar !== calendar) {