textarea <=> steps
This commit is contained in:
@@ -1,18 +1,36 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
import { computed, ref } from 'vue'
|
||||||
|
import {
|
||||||
|
adaptStepsToTextarea,
|
||||||
|
adaptTextareaToSteps
|
||||||
|
} from '../infra/adaptStepsToTextarea'
|
||||||
import type { Step } from '../models/step'
|
import type { Step } from '../models/step'
|
||||||
|
|
||||||
defineProps<{
|
const props = defineProps<{
|
||||||
modelValue: Step[]
|
modelValue: Step[]
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
(event: 'update:modelValue', payload: Step[]): void
|
(event: 'update:modelValue', payload: Step[]): void
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
|
const rawSteps = ref(adaptStepsToTextarea(props.modelValue))
|
||||||
|
|
||||||
|
const stepsTextarea = computed({
|
||||||
|
get() {
|
||||||
|
return rawSteps.value
|
||||||
|
},
|
||||||
|
set(value) {
|
||||||
|
rawSteps.value = value
|
||||||
|
|
||||||
|
emit('update:modelValue', adaptTextareaToSteps(value))
|
||||||
|
}
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="step-input">
|
<div class="step-input">
|
||||||
<div>textarea</div>
|
<textarea v-model="stepsTextarea"></textarea>
|
||||||
<div>beautiful data</div>
|
<div>beautiful data</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
79
src/use-cases/task/infra/adaptStepsToTextarea.test.ts
Normal file
79
src/use-cases/task/infra/adaptStepsToTextarea.test.ts
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
import { describe, expect, it } from 'vitest'
|
||||||
|
import { createStepFixture } from '../models/step.fixture'
|
||||||
|
import {
|
||||||
|
adaptStepsToTextarea,
|
||||||
|
adaptTextareaToSteps
|
||||||
|
} from './adaptStepsToTextarea'
|
||||||
|
|
||||||
|
describe('adapt steps to textarea value', () => {
|
||||||
|
it('returns a string with the listed steps', () => {
|
||||||
|
const steps = [
|
||||||
|
createStepFixture(),
|
||||||
|
createStepFixture(),
|
||||||
|
createStepFixture(),
|
||||||
|
createStepFixture()
|
||||||
|
]
|
||||||
|
|
||||||
|
const stepsInTextarea = steps
|
||||||
|
.map((step) => `- ${step.title} | ${step.estimation}`)
|
||||||
|
.join('\n')
|
||||||
|
|
||||||
|
expect(adaptStepsToTextarea(steps)).toEqual(stepsInTextarea)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('returns a list of steps from a textarea value', () => {
|
||||||
|
const stepsInTextarea = `- step 1 | 3
|
||||||
|
- step 2 | 4
|
||||||
|
- step 3 | 5`
|
||||||
|
|
||||||
|
const expectedSteps = [
|
||||||
|
createStepFixture({
|
||||||
|
id: expect.any(String),
|
||||||
|
title: 'step 1',
|
||||||
|
estimation: 3
|
||||||
|
}),
|
||||||
|
createStepFixture({
|
||||||
|
id: expect.any(String),
|
||||||
|
title: 'step 2',
|
||||||
|
estimation: 4
|
||||||
|
}),
|
||||||
|
createStepFixture({
|
||||||
|
id: expect.any(String),
|
||||||
|
title: 'step 3',
|
||||||
|
estimation: 5
|
||||||
|
})
|
||||||
|
]
|
||||||
|
|
||||||
|
expect(adaptTextareaToSteps(stepsInTextarea)).toEqual(expectedSteps)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('fallbacks to 0 for the estimation if there is no estimation', () => {
|
||||||
|
const stepInTextarea = '- step 1'
|
||||||
|
|
||||||
|
const expectedStep = createStepFixture({
|
||||||
|
id: expect.any(String),
|
||||||
|
title: 'step 1',
|
||||||
|
estimation: 0
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(adaptTextareaToSteps(stepInTextarea)).toEqual([expectedStep])
|
||||||
|
})
|
||||||
|
|
||||||
|
it('fallbacks to 0 for the estimation if it can not read the number', () => {
|
||||||
|
const stepInTextarea = '- step 1 | not an estimation'
|
||||||
|
|
||||||
|
const expectedStep = createStepFixture({
|
||||||
|
id: expect.any(String),
|
||||||
|
title: 'step 1',
|
||||||
|
estimation: 0
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(adaptTextareaToSteps(stepInTextarea)).toEqual([expectedStep])
|
||||||
|
})
|
||||||
|
|
||||||
|
it('does not create a step with an empty title', () => {
|
||||||
|
const stepInTextArea = '\n-'
|
||||||
|
|
||||||
|
expect(adaptTextareaToSteps(stepInTextArea)).toEqual([])
|
||||||
|
})
|
||||||
|
})
|
||||||
38
src/use-cases/task/infra/adaptStepsToTextarea.ts
Normal file
38
src/use-cases/task/infra/adaptStepsToTextarea.ts
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
import { createUuid } from '@/shared/create-uuid'
|
||||||
|
import { Step } from '../models/step'
|
||||||
|
|
||||||
|
export const adaptStepsToTextarea = (steps: Step[]) =>
|
||||||
|
steps.map((step) => `- ${step.title} | ${step.estimation}`).join('\n')
|
||||||
|
|
||||||
|
const extractTitleAndEstimationFromStep = (
|
||||||
|
rawStep: string
|
||||||
|
): [string, number] => {
|
||||||
|
const [rawTitle, rawEstimation] = rawStep
|
||||||
|
.trim()
|
||||||
|
.replace(/^-\s*/, '')
|
||||||
|
.split('|')
|
||||||
|
const title = rawTitle.trim()
|
||||||
|
|
||||||
|
const estimationString = (rawEstimation || '').trim()
|
||||||
|
const estimation = Number(estimationString)
|
||||||
|
|
||||||
|
if (isNaN(estimation)) {
|
||||||
|
return [title, 0]
|
||||||
|
}
|
||||||
|
|
||||||
|
return [title, estimation]
|
||||||
|
}
|
||||||
|
|
||||||
|
export const adaptTextareaToSteps = (textareaValue: string): Step[] =>
|
||||||
|
textareaValue
|
||||||
|
.split('\n')
|
||||||
|
.map((rawStep) => {
|
||||||
|
const [title, estimation] = extractTitleAndEstimationFromStep(rawStep)
|
||||||
|
|
||||||
|
if (!title) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Step(createUuid(), title, estimation)
|
||||||
|
})
|
||||||
|
.filter((step) => step !== null) as Step[]
|
||||||
Reference in New Issue
Block a user