Make adding fields to tasks more intuitive (#365)

Reviewed-on: https://kolaente.dev/vikunja/frontend/pulls/365
Reviewed-by: konrad <konrad@kola-entertainments.de>
Co-authored-by: profi248 <kostal.david8@gmail.com>
Co-committed-by: profi248 <kostal.david8@gmail.com>
This commit is contained in:
profi248 2021-01-04 21:22:56 +00:00 committed by konrad
parent 55bc849c2c
commit 2da6d7649f
3 changed files with 152 additions and 116 deletions

View file

@ -254,3 +254,16 @@
.link-share-container .task-view { .link-share-container .task-view {
background-color: transparent; background-color: transparent;
} }
.flash-background-enter, .flash-background-enter-active {
animation: flash-background $flash-background-duration ease 1;
}
@keyframes flash-background {
0% {
background: lighten($primary, 30);
}
100% {
background: transparent;
}
}

View file

@ -17,6 +17,7 @@ $navbar-dropdown-boxed-shadow: $dropdown-content-shadow;
$bulmaswatch-import-font: false !default; $bulmaswatch-import-font: false !default;
$light-background: #F1F5F8; $light-background: #F1F5F8;
$transition-duration: 100ms; $transition-duration: 100ms;
$flash-background-duration: 750ms;
$transparent-background-light: rgba($light-background, 0.9); $transparent-background-light: rgba($light-background, 0.9);
$vikunja-font: 'Quicksand', sans-serif; $vikunja-font: 'Quicksand', sans-serif;

View file

@ -28,129 +28,145 @@
v-model="task.assignees" v-model="task.assignees"
/> />
</div> </div>
<div class="column" v-if="activeFields.priority"> <transition name="flash-background" appear>
<!-- Priority --> <div class="column" v-if="activeFields.priority">
<div class="detail-title"> <!-- Priority -->
<icon :icon="['far', 'star']"/> <div class="detail-title">
Priority <icon :icon="['far', 'star']"/>
Priority
</div>
<priority-select
:disabled="!canWrite"
@change="saveTask"
ref="priority"
v-model="task.priority"/>
</div> </div>
<priority-select </transition>
:disabled="!canWrite" <transition name="flash-background" appear>
@change="saveTask" <div class="column" v-if="activeFields.dueDate">
ref="priority" <!-- Due Date -->
v-model="task.priority"/> <div class="detail-title">
</div> <icon icon="calendar"/>
<div class="column" v-if="activeFields.dueDate"> Due Date
<!-- Due Date --> </div>
<div class="detail-title"> <div class="date-input">
<icon icon="calendar"/> <datepicker
Due Date v-model="task.dueDate"
@close-on-change="() => saveTask()"
choose-date-label="Click here to set a due date"
:disabled="taskService.loading || !canWrite"
ref="dueDate"
/>
<a @click="() => {task.dueDate = null;saveTask()}" v-if="task.dueDate && canWrite" class="remove">
<span class="icon is-small">
<icon icon="times"></icon>
</span>
</a>
</div>
</div> </div>
<div class="date-input"> </transition>
<datepicker <transition name="flash-background" appear>
v-model="task.dueDate" <div class="column" v-if="activeFields.percentDone">
@close-on-change="() => saveTask()" <!-- Percent Done -->
choose-date-label="Click here to set a due date" <div class="detail-title">
:disabled="taskService.loading || !canWrite" <icon icon="percent"/>
ref="dueDate" Percent Done
</div>
<percent-done-select
:disabled="!canWrite"
@change="saveTask"
ref="percentDone"
v-model="task.percentDone"/>
</div>
</transition>
<transition name="flash-background" appear>
<div class="column" v-if="activeFields.startDate">
<!-- Start Date -->
<div class="detail-title">
<icon icon="calendar-week"/>
Start Date
</div>
<div class="date-input">
<datepicker
v-model="task.startDate"
@close-on-change="() => saveTask()"
choose-date-label="Click here to set a start date"
:disabled="taskService.loading || !canWrite"
ref="startDate"
/> />
<a @click="() => {task.dueDate = null;saveTask()}" v-if="task.dueDate && canWrite" class="remove"> <a @click="() => {task.startDate = null;saveTask()}" v-if="task.startDate && canWrite" class="remove">
<span class="icon is-small"> <span class="icon is-small">
<icon icon="times"></icon> <icon icon="times"></icon>
</span> </span>
</a> </a>
</div>
</div> </div>
</div> </transition>
<div class="column" v-if="activeFields.percentDone"> <transition name="flash-background" appear>
<!-- Percent Done --> <div class="column" v-if="activeFields.endDate">
<div class="detail-title"> <!-- End Date -->
<icon icon="percent"/> <div class="detail-title">
Percent Done <icon icon="calendar-week"/>
End Date
</div>
<div class="date-input">
<datepicker
v-model="task.endDate"
@close-on-change="() => saveTask()"
choose-date-label="Click here to set an end date"
:disabled="taskService.loading || !canWrite"
ref="endDate"
/>
<a @click="() => {task.endDate = null;saveTask()}" v-if="task.endDate && canWrite" class="remove">
<span class="icon is-small">
<icon icon="times"></icon>
</span>
</a>
</div>
</div> </div>
<percent-done-select </transition>
:disabled="!canWrite" <transition name="flash-background" appear>
@change="saveTask" <div class="column" v-if="activeFields.reminders">
ref="percentDone" <!-- Reminders -->
v-model="task.percentDone"/> <div class="detail-title">
</div> <icon icon="history"/>
<div class="column" v-if="activeFields.startDate"> Reminders
<!-- Start Date --> </div>
<div class="detail-title"> <reminders
<icon icon="calendar-week"/> :disabled="!canWrite"
Start Date @change="saveTask"
ref="reminders"
v-model="task.reminderDates"/>
</div> </div>
<div class="date-input"> </transition>
<datepicker <transition name="flash-background" appear>
v-model="task.startDate" <div class="column" v-if="activeFields.repeatAfter">
@close-on-change="() => saveTask()" <!-- Repeat after -->
choose-date-label="Click here to set a start date" <div class="detail-title">
:disabled="taskService.loading || !canWrite" <icon :icon="['far', 'clock']"/>
ref="startDate" Repeat
/> </div>
<a @click="() => {task.startDate = null;saveTask()}" v-if="task.startDate && canWrite" class="remove"> <repeat-after
<span class="icon is-small"> :disabled="!canWrite"
<icon icon="times"></icon> @change="saveTask"
</span> ref="repeatAfter"
</a> v-model="task"/>
</div> </div>
</div> </transition>
<div class="column" v-if="activeFields.endDate"> <transition name="flash-background" appear>
<!-- End Date --> <div class="column" v-if="activeFields.color">
<div class="detail-title"> <!-- Color -->
<icon icon="calendar-week"/> <div class="detail-title">
End Date <icon icon="fill-drip"/>
Color
</div>
<color-picker
@change="saveTask"
menu-position="bottom"
ref="color"
v-model="taskColor"/>
</div> </div>
<div class="date-input"> </transition>
<datepicker
v-model="task.endDate"
@close-on-change="() => saveTask()"
choose-date-label="Click here to set an end date"
:disabled="taskService.loading || !canWrite"
ref="endDate"
/>
<a @click="() => {task.endDate = null;saveTask()}" v-if="task.endDate && canWrite" class="remove">
<span class="icon is-small">
<icon icon="times"></icon>
</span>
</a>
</div>
</div>
<div class="column" v-if="activeFields.reminders">
<!-- Reminders -->
<div class="detail-title">
<icon icon="history"/>
Reminders
</div>
<reminders
:disabled="!canWrite"
@change="saveTask"
ref="reminders"
v-model="task.reminderDates"/>
</div>
<div class="column" v-if="activeFields.repeatAfter">
<!-- Repeat after -->
<div class="detail-title">
<icon :icon="['far', 'clock']"/>
Repeat
</div>
<repeat-after
:disabled="!canWrite"
@change="saveTask"
ref="repeatAfter"
v-model="task"/>
</div>
<div class="column" v-if="activeFields.color">
<!-- Color -->
<div class="detail-title">
<icon icon="fill-drip"/>
Color
</div>
<color-picker
@change="saveTask"
menu-position="bottom"
ref="color"
v-model="taskColor"/>
</div>
</div> </div>
<!-- Labels --> <!-- Labels -->
@ -546,7 +562,13 @@ export default {
this.activeFields[fieldName] = true this.activeFields[fieldName] = true
this.$nextTick(() => { this.$nextTick(() => {
if (this.$refs[fieldName]) { if (this.$refs[fieldName]) {
this.$refs[fieldName].$el.focus() this.$refs[fieldName].$el.focus();
// scroll the field to the center of the screen if not in viewport already
const boundingRect = this.$refs[fieldName].$el.getBoundingClientRect();
if (boundingRect.top > (window.scrollY + window.innerHeight) || boundingRect.top < window.scrollY)
this.$refs[fieldName].$el.scrollIntoView({behavior: "smooth", block: "center", inline: "nearest"});
} }
}) })
}, },