feat: remove edit-task from list view (#2721)
continuous-integration/drone/push Build is passing Details

Co-authored-by: Dominik Pschenitschni <mail@celement.de>
Reviewed-on: #2721
Reviewed-by: konrad <k@knt.li>
Co-authored-by: Dominik Pschenitschni <dpschen@noreply.kolaente.de>
Co-committed-by: Dominik Pschenitschni <dpschen@noreply.kolaente.de>
This commit is contained in:
Dominik Pschenitschni 2022-11-17 15:35:18 +00:00 committed by konrad
parent 8ef309243d
commit 45ec1623d5
3 changed files with 57 additions and 317 deletions

View File

@ -78,7 +78,7 @@ describe('List View List', () => {
cy.get('.menu-list li .list-menu-link .color-bubble')
.should('have.css', 'background-color', 'rgb(0, 219, 96)')
cy.get('.tasks-container .tasks .color-bubble')
cy.get('.tasks .color-bubble')
.should('not.exist')
})
@ -90,9 +90,9 @@ describe('List View List', () => {
})
cy.visit('/lists/1/list')
cy.get('.tasks-container .tasks')
cy.get('.tasks')
.should('contain', tasks[1].title)
cy.get('.tasks-container .tasks')
cy.get('.tasks')
.should('not.contain', tasks[99].title)
cy.get('.card-content .pagination .pagination-link')
@ -101,9 +101,9 @@ describe('List View List', () => {
cy.url()
.should('contain', '?page=2')
cy.get('.tasks-container .tasks')
cy.get('.tasks')
.should('contain', tasks[99].title)
cy.get('.tasks-container .tasks')
cy.get('.tasks')
.should('not.contain', tasks[1].title)
})
})

View File

@ -1,187 +0,0 @@
<template>
<card
class="taskedit"
:title="$t('list.list.editTask')"
@close="$emit('close')"
:has-close="true"
>
<form @submit.prevent="editTaskSubmit()">
<div class="field">
<label class="label" for="tasktext">{{ $t('task.attributes.title') }}</label>
<div class="control">
<input
:class="{ disabled: taskService.loading }"
:disabled="taskService.loading || undefined"
@change="editTaskSubmit()"
class="input"
id="tasktext"
type="text"
v-focus
v-model="taskEditTask.title"
/>
</div>
</div>
<div class="field">
<label class="label" for="taskdescription">{{ $t('task.attributes.description') }}</label>
<div class="control">
<editor
:preview-is-default="false"
id="taskdescription"
:placeholder="$t('task.description.placeholder')"
v-if="editorActive"
v-model="taskEditTask.description"
/>
</div>
</div>
<strong>{{ $t('task.attributes.reminders') }}</strong>
<reminders
v-model="taskEditTask.reminderDates"
@update:model-value="editTaskSubmit()"
/>
<div class="field">
<label class="label">{{ $t('task.attributes.labels') }}</label>
<div class="control">
<edit-labels
:task-id="taskEditTask.id"
v-model="taskEditTask.labels"
/>
</div>
</div>
<div class="field">
<label class="label">{{ $t('task.attributes.color') }}</label>
<div class="control">
<color-picker v-model="taskEditTask.hexColor" />
</div>
</div>
<x-button
:loading="taskService.loading"
class="is-fullwidth"
@click="editTaskSubmit()"
>
{{ $t('misc.save') }}
</x-button>
<router-link
class="mt-2 has-text-centered is-block"
:to="taskDetailRoute"
>
{{ $t('task.openDetail') }}
</router-link>
</form>
</card>
</template>
<script setup lang="ts">
import {ref, reactive, computed, shallowReactive, watch, nextTick, type PropType} from 'vue'
import {useRouter} from 'vue-router'
import {useI18n} from 'vue-i18n'
import Editor from '@/components/input/AsyncEditor'
import TaskService from '@/services/task'
import TaskModel from '@/models/task'
import type {ITask} from '@/modelTypes/ITask'
import EditLabels from './partials/editLabels.vue'
import Reminders from './partials/reminders.vue'
import ColorPicker from '../input/colorPicker.vue'
import {success} from '@/message'
const {t} = useI18n({useScope: 'global'})
const router = useRouter()
const props = defineProps({
task: {
type: Object as PropType<ITask | null>,
},
})
const taskService = shallowReactive(new TaskService())
const editorActive = ref(false)
let taskEditTask: ITask | undefined
// FIXME: this initialization should not be necessary here
function initTaskFields() {
taskEditTask.dueDate =
+new Date(props.task.dueDate) === 0 ? null : props.task.dueDate
taskEditTask.startDate =
+new Date(props.task.startDate) === 0
? null
: props.task.startDate
taskEditTask.endDate =
+new Date(props.task.endDate) === 0 ? null : props.task.endDate
// This makes the editor trigger its mounted function again which makes it forget every input
// it currently has in its textarea. This is a counter-hack to a hack inside of vue-easymde
// which made it impossible to detect change from the outside. Therefore the component would
// not update if new content from the outside was made available.
// See https://github.com/NikulinIlya/vue-easymde/issues/3
editorActive.value = false
nextTick(() => (editorActive.value = true))
}
watch(
() => props.task,
() => {
if (!taskEditTask) {
taskEditTask = reactive(props.task)
} else {
Object.assign(taskEditTask, new TaskModel(props.task))
}
initTaskFields()
},
{immediate: true },
)
const taskDetailRoute = computed(() => {
return {
name: 'task.detail',
params: { id: taskEditTask.id },
state: { backdropView: router.currentRoute.value.fullPath },
}
})
async function editTaskSubmit() {
const newTask = await taskService.update(taskEditTask)
Object.assign(taskEditTask, newTask)
initTaskFields()
success({message: t('task.detail.updateSuccess')})
}
</script>
<style lang="scss" scoped>
.priority-select {
.select,
select {
width: 100%;
}
}
ul.assingees {
list-style: none;
margin: 0;
li {
padding: 0.5rem 0.5rem 0;
a {
float: right;
color: var(--danger);
transition: all $transition;
}
}
}
.tag {
margin-right: 0.5rem;
margin-bottom: 0.5rem;
&:last-child {
margin-right: 0;
}
}
</style>

View File

@ -53,15 +53,13 @@
class="loader-container is-max-width-desktop list-view"
>
<card :padding="false" :has-content="false" class="has-overflow">
<template
<add-task
v-if="!list.isArchived && canWrite"
>
<add-task
@taskAdded="updateTaskList"
ref="addTaskRef"
:default-position="firstNewPosition"
/>
</template>
class="list-view__add-task"
ref="addTaskRef"
:default-position="firstNewPosition"
@taskAdded="updateTaskList"
/>
<nothing v-if="ctaVisible && tasks.length === 0 && !loading">
{{ $t('list.list.empty') }}
@ -70,59 +68,42 @@
</ButtonLink>
</nothing>
<div class="tasks-container" :class="{ 'has-task-edit-open': isTaskEdit }">
<div
class="tasks mt-0"
v-if="tasks && tasks.length > 0"
>
<draggable
v-bind="DRAG_OPTIONS"
v-model="tasks"
group="tasks"
@start="() => drag = true"
@end="saveTaskPosition"
handle=".handle"
<draggable
v-if="tasks && tasks.length > 0"
v-bind="DRAG_OPTIONS"
v-model="tasks"
group="tasks"
@start="() => drag = true"
@end="saveTaskPosition"
handle=".handle"
:disabled="!canWrite"
item-key="id"
tag="ul"
:component-data="{
class: {
tasks: true,
'dragging-disabled': !canWrite || isAlphabeticalSorting
},
type: 'transition-group'
}"
>
<template #item="{element: t}">
<single-task-in-list
:show-list-color="false"
:disabled="!canWrite"
item-key="id"
tag="ul"
:component-data="{
class: { 'dragging-disabled': !canWrite || isAlphabeticalSorting },
type: 'transition-group'
}"
:can-mark-as-done="canWrite || isSavedFilter(list)"
:the-task="t"
@taskUpdated="updateTasks"
>
<template #item="{element: t}">
<single-task-in-list
:show-list-color="false"
:disabled="!canWrite"
:can-mark-as-done="canWrite || isSavedFilter(list)"
:the-task="t"
@taskUpdated="updateTasks"
>
<template v-if="canWrite">
<span class="icon handle">
<icon icon="grip-lines"/>
</span>
<BaseButton
@click="editTask(t.id)"
class="icon settings"
v-if="!list.isArchived"
>
<icon icon="pencil-alt"/>
</BaseButton>
</template>
</single-task-in-list>
<template v-if="canWrite">
<span class="icon handle">
<icon icon="grip-lines"/>
</span>
</template>
</draggable>
</div>
<EditTask
v-if="isTaskEdit"
class="taskedit mt-0"
:title="$t('list.list.editTask')"
@close="closeTaskEditPane()"
:shadow="false"
:task="taskEditTask"
/>
</div>
</single-task-in-list>
</template>
</draggable>
<Pagination
:total-pages="totalPages"
@ -139,14 +120,12 @@ export default { name: 'List' }
</script>
<script setup lang="ts">
import {ref, computed, toRef, nextTick, onMounted, type PropType, watch} from 'vue'
import {ref, computed, toRef, nextTick, onMounted, type PropType} from 'vue'
import draggable from 'zhyswan-vuedraggable'
import {useRoute, useRouter} from 'vue-router'
import ListWrapper from '@/components/list/ListWrapper.vue'
import BaseButton from '@/components/base/BaseButton.vue'
import ButtonLink from '@/components/misc/ButtonLink.vue'
import EditTask from '@/components/tasks/edit-task.vue'
import AddTask from '@/components/tasks/add-task.vue'
import SingleTaskInList from '@/components/tasks/partials/singleTaskInList.vue'
import FilterPopup from '@/components/list/partials/filter-popup.vue'
@ -196,23 +175,9 @@ const showTaskSearch = ref(false)
const drag = ref(false)
const DRAG_OPTIONS = {
animation: 100,
ghostClass: 'ghost',
ghostClass: 'task-ghost',
} as const
const taskEditTask = ref<ITask | null>(null)
const isTaskEdit = ref(false)
function closeTaskEditPane() {
isTaskEdit.value = false
taskEditTask.value = null
}
watch(
() => props.listId,
closeTaskEditPane,
)
const {
tasks,
loading,
@ -296,11 +261,6 @@ function updateTaskList(task: ITask) {
baseStore.setHasTasks(true)
}
function editTask(id: ITask['id']) {
taskEditTask.value = {...tasks.value.find(t => t.id === Number(id))}
isTaskEdit.value = true
}
function updateTasks(updatedTask: ITask) {
for (const t in tasks.value) {
if (tasks.value[t].id === updatedTask.id) {
@ -339,54 +299,21 @@ function prepareFiltersAndLoadTasks() {
</script>
<style lang="scss" scoped>
.tasks-container {
display: flex;
.tasks {
padding: .5rem;
}
&.has-task-edit-open {
flex-direction: column;
@media screen and (min-width: $tablet) {
flex-direction: row;
.tasks {
width: 66%;
}
}
}
.tasks {
width: 100%;
padding: .5rem;
.ghost {
border-radius: $radius;
background: var(--grey-100);
border: 2px dashed var(--grey-300);
* {
opacity: 0;
}
}
}
.taskedit {
width: 33%;
margin-right: 1rem;
margin-left: .5rem;
min-height: calc(100% - 1rem);
@media screen and (max-width: $tablet) {
width: 100%;
border-radius: 0;
margin: 0;
border-left: 0;
border-right: 0;
border-bottom: 0;
}
.task-ghost {
border-radius: $radius;
background: var(--grey-100);
border: 2px dashed var(--grey-300);
* {
opacity: 0;
}
}
.list-view .task-add {
.list-view__add-task {
padding: 1rem 1rem 0;
}