feat: paste text and automatically create a new task
This commit is contained in:
@@ -1,10 +1,15 @@
|
||||
<script setup lang="ts">
|
||||
import { createUuid } from '@/shared/create-uuid'
|
||||
import type { Stepable } from '../interfaces/stepable'
|
||||
import TaskForm from './TaskForm.vue'
|
||||
|
||||
const props = defineProps<{
|
||||
initialSteps?: Stepable[]
|
||||
}>()
|
||||
|
||||
const id = createUuid()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<task-form :id="id" :action="'new'" />
|
||||
<task-form :id="id" :initial-steps="props.initialSteps" />
|
||||
</template>
|
||||
|
||||
@@ -14,12 +14,15 @@ const router = useRouter()
|
||||
const props = defineProps<{
|
||||
id: string
|
||||
initialTask?: Taskable
|
||||
initialSteps?: Stepable[]
|
||||
}>()
|
||||
const id = computed(() => props.id)
|
||||
const hasTasks = computed(() => store.tasks.length > 0)
|
||||
|
||||
const steps = ref<Stepable[]>(
|
||||
props.initialTask
|
||||
props.initialSteps?.length
|
||||
? props.initialSteps
|
||||
: props.initialTask
|
||||
? Task.fromTaskable(props.initialTask).steps
|
||||
: hasTasks.value
|
||||
? []
|
||||
|
||||
@@ -93,4 +93,40 @@ describe('adapt steps to textarea value', () => {
|
||||
`"9b237c28d5254f2b819fa66c853a9a60-2"`
|
||||
)
|
||||
})
|
||||
|
||||
it('parses steps with unchecked checkbox format', () => {
|
||||
const stepInTextarea = '- [ ] step with checkbox | 20'
|
||||
|
||||
const expectedStep = fixtureStep({
|
||||
id: expect.any(String),
|
||||
title: 'step with checkbox',
|
||||
estimation: 20
|
||||
})
|
||||
|
||||
expect(adaptTextareaToSteps(stepInTextarea)).toEqual([expectedStep])
|
||||
})
|
||||
|
||||
it('parses steps with checked checkbox format', () => {
|
||||
const stepInTextarea = '- [x] completed step | 15'
|
||||
|
||||
const expectedStep = fixtureStep({
|
||||
id: expect.any(String),
|
||||
title: 'completed step',
|
||||
estimation: 15
|
||||
})
|
||||
|
||||
expect(adaptTextareaToSteps(stepInTextarea)).toEqual([expectedStep])
|
||||
})
|
||||
|
||||
it('parses checkbox steps without estimation', () => {
|
||||
const stepInTextarea = '- [ ] step without estimation'
|
||||
|
||||
const expectedStep = fixtureStep({
|
||||
id: expect.any(String),
|
||||
title: 'step without estimation',
|
||||
estimation: 0
|
||||
})
|
||||
|
||||
expect(adaptTextareaToSteps(stepInTextarea)).toEqual([expectedStep])
|
||||
})
|
||||
})
|
||||
|
||||
@@ -9,7 +9,7 @@ const extractTitleAndEstimationFromStep = (
|
||||
): [string, number] => {
|
||||
const [rawTitle, rawEstimation] = rawStep
|
||||
.trim()
|
||||
.replace(/^-\s*/, '')
|
||||
.replace(/^-\s*(\[[ x]\]\s*)?/, '')
|
||||
.split('|')
|
||||
const title = rawTitle.trim()
|
||||
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
<script setup lang="ts">
|
||||
import TaskList from '@/modules/task/components/TaskList.vue'
|
||||
import { adaptTextareaToSteps } from '@/modules/task/infra/adaptStepsToTextarea'
|
||||
import { useTaskStore } from '@/modules/task/stores/useTask.store'
|
||||
import { computed } from 'vue'
|
||||
import { computed, onMounted, onUnmounted } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
|
||||
const taskStore = useTaskStore()
|
||||
const router = useRouter()
|
||||
|
||||
const hasTask = computed(() => taskStore.tasks.length > 0)
|
||||
|
||||
@@ -12,6 +15,28 @@ const resetTasks = () => {
|
||||
taskStore.reset()
|
||||
}
|
||||
}
|
||||
|
||||
const handlePaste = (event: ClipboardEvent) => {
|
||||
const clipboardText = event.clipboardData?.getData('text')
|
||||
if (!clipboardText) {
|
||||
return
|
||||
}
|
||||
|
||||
const steps = adaptTextareaToSteps(clipboardText)
|
||||
if (steps.length === 0) {
|
||||
return
|
||||
}
|
||||
|
||||
router.push({ name: 'new-task', state: { initialSteps: JSON.stringify(steps) } })
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
document.addEventListener('paste', handlePaste)
|
||||
})
|
||||
|
||||
onUnmounted(() => {
|
||||
document.removeEventListener('paste', handlePaste)
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
||||
@@ -1,9 +1,15 @@
|
||||
<script setup lang="ts">
|
||||
import NewTaskForm from '@/modules/task/components/NewTaskForm.vue'
|
||||
import type { Stepable } from '@/modules/task/interfaces/stepable'
|
||||
|
||||
const rawInitialSteps = history.state?.initialSteps as string | undefined
|
||||
const initialSteps = rawInitialSteps
|
||||
? (JSON.parse(rawInitialSteps) as Stepable[])
|
||||
: undefined
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="new-task">
|
||||
<NewTaskForm />
|
||||
<NewTaskForm :initial-steps="initialSteps" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
Reference in New Issue
Block a user