Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Prevent moving non-public tasks to calendars shared with me #902

Merged
merged 5 commits into from
Mar 7, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions css/src/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,8 @@
}

&.dnd-hover {
background-color: rgba( $color-primary, .3 );
// background-color: rgba( $color-primary, .1 ); didn't work for some reason
background-color: transparentize( $color-primary, .9 );
}

button {
Expand Down Expand Up @@ -446,7 +447,8 @@
}

&.sortable-ghost .task-body {
background-color: rgba( $color-primary, .3 );
// background-color: rgba( $color-primary, .1 ); didn't work for some reason
background-color: transparentize( $color-primary, .9 );
}

.subtasks-container {
Expand Down
9 changes: 9 additions & 0 deletions src/components/AppNavigation/ListItemCalendar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,15 @@ export default {
if (this.calendar.readOnly) {
return
}
if (this.calendar.isSharedWithMe) {
const taskUri = e.dataTransfer.getData('text/plain')
if (taskUri) {
const task = this.getTask(taskUri)
if (task.class !== 'PUBLIC') {
return
}
}
}
// Get the correct element, in case we hover a child.
if (e.target.closest) {
const target = e.target.closest('li.list')
Expand Down
8 changes: 4 additions & 4 deletions src/components/TaskBody.vue
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ License along with this library. If not, see <http://www.gnu.org/licenses/>.
<template>
<li v-show="showTask"
:task-id="task.uri"
:class="{done: task.completed, readOnly: task.calendar.readOnly, deleted: !!deleteTimeout}"
:class="{done: task.completed, readOnly: readOnly, deleted: !!deleteTimeout}"
:data-priority="[task.priority]"
class="task-item"
@dragstart="dragStart($event)">
Expand All @@ -38,10 +38,10 @@ License along with this library. If not, see <http://www.gnu.org/licenses/>.
type="checkbox"
class="checkbox no-nav"
name="toggleCompleted"
:class="{'disabled': task.calendar.readOnly}"
:class="{'disabled': readOnly}"
:checked="task.completed"
:aria-checked="task.completed"
:disabled="task.calendar.readOnly"
:disabled="readOnly"
:aria-label="$t('tasks', 'Task is completed')"
@click="toggleCompleted(task)">
<label class="reactive no-nav" :for="'toggleCompleted_' + task.uid" />
Expand Down Expand Up @@ -120,7 +120,7 @@ License along with this library. If not, see <http://www.gnu.org/licenses/>.
</ActionButton>
</Actions>
<button class="inline task-star reactive no-nav" @click="toggleStarred(task)">
<span :class="[iconStar, {'disabled': task.calendar.readOnly}]" class="icon" />
<span :class="[iconStar, {'disabled': readOnly}]" class="icon" />
</button>
</div>
</div>
Expand Down
39 changes: 39 additions & 0 deletions src/components/TaskDragContainer.vue
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ License along with this library. If not, see <http://www.gnu.org/licenses/>.
:list="['']"
:set-data="setDragData"
v-bind="{group: 'tasks', swapThreshold: 0.30, delay: 500, delayOnTouchOnly: true, touchStartThreshold: 3, disabled: disabled, filter: '.readOnly'}"
:move="onMove"
@add="onAdd">
<slot />
</draggable>
Expand Down Expand Up @@ -81,6 +82,44 @@ export default {
$event.stopPropagation()
},

/**
* Called when a task is moved.
* We check here if drop onto the target is allowed.
*
* Dropping tasks with class not PUBLIC onto calendars shared with me
* is forbidden.
*
* @param {Object} $event The event which caused the move
* @returns {Boolean} If the drop is allowed
*/
onMove($event) {
// The task to move
const taskAttribute = $event.dragged.attributes['task-id']
if (taskAttribute) {
const task = this.getTask(taskAttribute.value)
if (task.class === 'PUBLIC') {
return true
}
let calendar
const calendarAttribute = $event.to.attributes['calendar-id']
if (calendarAttribute) {
calendar = this.getCalendar(calendarAttribute.value)
}
if (!calendar) {
const parentAttribute = $event.to.attributes['task-id']
if (parentAttribute) {
const parent = this.getTask(parentAttribute.value)
// If we move to a parent task, the calendar has to be the parents calendar.
calendar = parent.calendar
}
}
if (calendar && calendar.isSharedWithMe) {
return false
}
}
return true
},

/**
* Function to move a task to a new calendar or parent
*
Expand Down
11 changes: 10 additions & 1 deletion src/components/TheDetails.vue
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ License along with this library. If not, see <http://www.gnu.org/licenses/>.
track-by="id"
:placeholder="$t('tasks', 'Select a calendar')"
label="displayName"
:options="writableCalendars"
:options="targetCalendars"
:close-on-select="true"
class="multiselect-vue"
@input="changeCalendar"
Expand Down Expand Up @@ -656,6 +656,15 @@ export default {
return 'icon-sprt-bw sprt-current'
}
},
targetCalendars() {
let calendars = this.writableCalendars
// Tasks with an access class other than PUBLIC cannot be moved
// into calendars shared with me
if (this.task.class !== 'PUBLIC') {
calendars = calendars.filter(calendar => !calendar.isSharedWithMe)
}
return calendars
},
...mapGetters({
writableCalendars: 'getSortedWritableCalendars',
task: 'getTaskByRoute',
Expand Down
4 changes: 2 additions & 2 deletions src/store/tasks.js
Original file line number Diff line number Diff line change
Expand Up @@ -1183,8 +1183,8 @@ const actions = {
if (task.calendar.readOnly) {
return task
}
// Don't move tasks in shared calendars with access class not PUBLIC
if (task.calendar.isSharedWithMe && task.class !== 'PUBLIC') {
// Don't move tasks with access class not PUBLIC from or to calendars shared with me
if ((task.calendar.isSharedWithMe || calendar.isSharedWithMe) && task.class !== 'PUBLIC') {
return
}
// Don't move if source and target calendar are the same.
Expand Down