Merge pull request #523 from nextcloud/permissions
Correctly handle tasks in read-only calendars
This commit is contained in:
commit
93270e2434
5 changed files with 70 additions and 11 deletions
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Reference in a new issue