feat: allow quickly creating multiple tasks at once with multiline input (#796)
Co-authored-by: kolaente <k@knt.li> Reviewed-on: https://kolaente.dev/vikunja/frontend/pulls/796 Co-authored-by: konrad <k@knt.li> Co-committed-by: konrad <k@knt.li>
This commit is contained in:
parent
3dfa286a12
commit
442e6b12e0
2 changed files with 49 additions and 7 deletions
|
@ -27,7 +27,7 @@ describe('Task', () => {
|
|||
|
||||
it('Should be created new', () => {
|
||||
cy.visit('/lists/1/list')
|
||||
cy.get('input.input[placeholder="Add a new task…"')
|
||||
cy.get('.input[placeholder="Add a new task…"')
|
||||
.type('New Task')
|
||||
cy.get('.button')
|
||||
.contains('Add')
|
||||
|
@ -43,7 +43,7 @@ describe('Task', () => {
|
|||
cy.visit('/lists/1/list')
|
||||
cy.get('.list-is-empty-notice')
|
||||
.should('not.exist')
|
||||
cy.get('input.input[placeholder="Add a new task…"')
|
||||
cy.get('.input[placeholder="Add a new task…"')
|
||||
.type('New Task')
|
||||
cy.get('.button')
|
||||
.contains('Add')
|
||||
|
|
|
@ -2,16 +2,17 @@
|
|||
<div class="task-add">
|
||||
<div class="field is-grouped">
|
||||
<p class="control has-icons-left is-expanded">
|
||||
<input
|
||||
<textarea
|
||||
:disabled="taskService.loading || null"
|
||||
@keyup.enter="addTask()"
|
||||
class="input"
|
||||
:placeholder="$t('list.list.addPlaceholder')"
|
||||
type="text"
|
||||
v-focus
|
||||
v-model="newTaskTitle"
|
||||
ref="newTaskInput"
|
||||
:style="{'height': `${textAreaHeight}px`}"
|
||||
@keyup="errorMessage = ''"
|
||||
@keydown.enter="handleEnter"
|
||||
/>
|
||||
<span class="icon is-small is-left">
|
||||
<icon icon="tasks"/>
|
||||
|
@ -40,6 +41,12 @@ import TaskService from '../../services/task'
|
|||
import createTask from '@/components/tasks/mixins/createTask'
|
||||
import QuickAddMagic from '@/components/tasks/partials/quick-add-magic.vue'
|
||||
|
||||
const INITIAL_SCROLL_HEIGHT = 40
|
||||
|
||||
const cleanupTitle = title => {
|
||||
return title.replace(/^((\* |\+ |- )(\[ \] )?)/g, '')
|
||||
}
|
||||
|
||||
export default {
|
||||
name: 'add-task',
|
||||
data() {
|
||||
|
@ -47,6 +54,7 @@ export default {
|
|||
newTaskTitle: '',
|
||||
taskService: new TaskService(),
|
||||
errorMessage: '',
|
||||
textAreaHeight: INITIAL_SCROLL_HEIGHT,
|
||||
}
|
||||
},
|
||||
mixins: [
|
||||
|
@ -61,6 +69,16 @@ export default {
|
|||
required: false,
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
newTaskTitle(newVal) {
|
||||
let scrollHeight = this.$refs.newTaskInput.scrollHeight
|
||||
if (scrollHeight < INITIAL_SCROLL_HEIGHT || newVal === '') {
|
||||
scrollHeight = INITIAL_SCROLL_HEIGHT
|
||||
}
|
||||
|
||||
this.textAreaHeight = scrollHeight
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
addTask() {
|
||||
if (this.newTaskTitle === '') {
|
||||
|
@ -73,10 +91,20 @@ export default {
|
|||
return
|
||||
}
|
||||
|
||||
this.createNewTask(this.newTaskTitle, 0, this.$store.state.auth.settings.defaultListId, this.defaultPosition)
|
||||
const newTasks = []
|
||||
this.newTaskTitle.split(/[\r\n]+/).forEach(t => {
|
||||
newTasks.push(
|
||||
this.createNewTask(cleanupTitle(t), 0, this.$store.state.auth.settings.defaultListId, this.defaultPosition)
|
||||
.then(task => {
|
||||
this.newTaskTitle = ''
|
||||
this.$emit('taskAdded', task)
|
||||
return task
|
||||
}),
|
||||
)
|
||||
})
|
||||
|
||||
Promise.all(newTasks)
|
||||
.then(() => {
|
||||
this.newTaskTitle = ''
|
||||
})
|
||||
.catch(e => {
|
||||
if (e === 'NO_LIST') {
|
||||
|
@ -86,6 +114,16 @@ export default {
|
|||
this.$message.error(e)
|
||||
})
|
||||
},
|
||||
handleEnter(e) {
|
||||
// when pressing shift + enter we want to continue as we normally would. Otherwise, we want to create
|
||||
// the new task(s). The vue event modifier don't allow this, hence this method.
|
||||
if (e.shiftKey) {
|
||||
return
|
||||
}
|
||||
|
||||
e.preventDefault()
|
||||
this.addTask()
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
@ -98,4 +136,8 @@ export default {
|
|||
height: 2.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
.input, .textarea {
|
||||
transition: border-color $transition;
|
||||
}
|
||||
</style>
|
||||
|
|
Loading…
Reference in a new issue