♻️ (feature) reverse parent child link with feature step index in feature
This commit is contained in:
@@ -1,17 +1,26 @@
|
||||
<script setup lang="ts">
|
||||
import { Feature } from '@/modules/feature/feature'
|
||||
import { FeatureStep } from '@/modules/feature/feature-steps'
|
||||
import { computed } from 'vue'
|
||||
|
||||
const props = defineProps<{
|
||||
step: FeatureStep
|
||||
features: Feature[]
|
||||
}>()
|
||||
const featuresInProgress = computed(() =>
|
||||
props.features.filter((feature) => feature.status === 'doing')
|
||||
)
|
||||
const featuresDone = computed(() =>
|
||||
props.features.filter((feature) => feature.status === 'done')
|
||||
)
|
||||
|
||||
const remainingBlueBuckets = computed(() =>
|
||||
Math.max(0, props.step.blueBuckets - props.step.featuresDone.length)
|
||||
Math.max(0, props.step.blueBuckets - featuresDone.value.length)
|
||||
)
|
||||
const hasFeaturesInProgress = computed(
|
||||
() => props.step.featuresInProgress.length > 0
|
||||
() => featuresInProgress.value.length > 0
|
||||
)
|
||||
const hasFeaturesDone = computed(() => props.step.featuresInProgress.length > 0)
|
||||
const hasFeaturesDone = computed(() => featuresInProgress.value.length > 0)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -21,7 +30,7 @@ const hasFeaturesDone = computed(() => props.step.featuresInProgress.length > 0)
|
||||
<h5>📝⌛</h5>
|
||||
<ul v-if="hasFeaturesInProgress">
|
||||
<li
|
||||
v-for="feature in step.featuresInProgress"
|
||||
v-for="feature in featuresInProgress"
|
||||
:key="feature.name"
|
||||
class="bin"
|
||||
>
|
||||
@@ -35,11 +44,7 @@ const hasFeaturesDone = computed(() => props.step.featuresInProgress.length > 0)
|
||||
<section class="done">
|
||||
<h5>📝✅</h5>
|
||||
<ul v-if="hasFeaturesDone">
|
||||
<li
|
||||
v-for="feature in step.featuresDone"
|
||||
:key="feature.name"
|
||||
class="bin"
|
||||
>
|
||||
<li v-for="feature in featuresDone" :key="feature.name" class="bin">
|
||||
<div>
|
||||
{{ feature.name }}
|
||||
</div>
|
||||
|
||||
@@ -1,38 +1,29 @@
|
||||
<script setup lang="ts">
|
||||
import FeatureStep from '@/modules/feature/FeatureStep.vue'
|
||||
import { Feature } from '@/modules/feature/feature'
|
||||
import { createFeatureBoard } from '@/modules/feature/feature-board'
|
||||
import {
|
||||
FeatureStep as FeatureStepType,
|
||||
featureSteps as initialFeatureSteps
|
||||
} from '@/modules/feature/feature-steps'
|
||||
import { featureSteps } from '@/modules/feature/feature-steps'
|
||||
import { sumElements } from '@/utils'
|
||||
import { computed, onMounted, ref } from 'vue'
|
||||
|
||||
const featureBoard = createFeatureBoard()
|
||||
|
||||
const featureSteps = ref<FeatureStepType[]>([])
|
||||
|
||||
const allFeatures = computed(() =>
|
||||
featureSteps.value.flatMap((step) => [
|
||||
...step.featuresInProgress,
|
||||
...step.featuresDone
|
||||
])
|
||||
)
|
||||
const features = ref<Feature[]>([])
|
||||
|
||||
const meanComplexity = computed(() =>
|
||||
sumElements(allFeatures.value.map((feature) => feature.complexity))
|
||||
sumElements(features.value.map((feature) => feature.complexity))
|
||||
)
|
||||
|
||||
const meanLeadTime = computed(() =>
|
||||
sumElements(allFeatures.value.map((feature) => feature.leadTime))
|
||||
sumElements(features.value.map((feature) => feature.leadTime))
|
||||
)
|
||||
|
||||
onMounted(
|
||||
() => (featureSteps.value = featureBoard.initBoard(initialFeatureSteps))
|
||||
)
|
||||
onMounted(() => (features.value = featureBoard.initBoard(featureSteps)))
|
||||
|
||||
const nextDay = () =>
|
||||
(featureSteps.value = featureBoard.nextDay(featureSteps.value))
|
||||
const nextDay = () => (features.value = featureBoard.nextDay(features.value))
|
||||
|
||||
const getStepFeatures = (stepIndex: number) =>
|
||||
features.value.filter((feature) => feature.step === stepIndex)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -46,7 +37,12 @@ const nextDay = () =>
|
||||
</div>
|
||||
</div>
|
||||
<ul class="features-steps">
|
||||
<FeatureStep v-for="step in featureSteps" :key="step.title" :step="step" />
|
||||
<FeatureStep
|
||||
v-for="step in featureSteps"
|
||||
:key="step.title"
|
||||
:step="step"
|
||||
:features="getStepFeatures(step.stepIndex)"
|
||||
/>
|
||||
</ul>
|
||||
</template>
|
||||
|
||||
|
||||
@@ -1,40 +1,34 @@
|
||||
import { FeatureStatus, FeatureStep } from '@/modules/feature/feature-steps'
|
||||
import { Feature } from '@/modules/feature/feature'
|
||||
import { FeatureStep } from '@/modules/feature/feature-steps'
|
||||
import { features } from '@/modules/feature/feature.fixture'
|
||||
import { pickRandomElement, popNElement, shuffleArray } from '@/utils'
|
||||
|
||||
export const createFeatureBoard = () => {
|
||||
const boardFeatures = shuffleArray(features)
|
||||
|
||||
const initBoard = (featureSteps: FeatureStep[]): FeatureStep[] => {
|
||||
const initBoard = (steps: FeatureStep[]): Feature[] => {
|
||||
const initialFeatures = popNElement(boardFeatures, 10)
|
||||
|
||||
initialFeatures.forEach((feature) => {
|
||||
const step = pickRandomElement(featureSteps)
|
||||
const doingOrDone: FeatureStatus = pickRandomElement(['doing', 'done'])
|
||||
|
||||
switch (doingOrDone) {
|
||||
case 'doing':
|
||||
step.featuresInProgress.push(feature)
|
||||
break
|
||||
case 'done':
|
||||
step.featuresDone.push(feature)
|
||||
break
|
||||
}
|
||||
const step = pickRandomElement(steps)
|
||||
feature.status = pickRandomElement(['doing', 'done'])
|
||||
feature.step = step.stepIndex
|
||||
})
|
||||
|
||||
return featureSteps
|
||||
return initialFeatures
|
||||
}
|
||||
|
||||
const nextDay = (featureSteps: FeatureStep[]): FeatureStep[] => {
|
||||
featureSteps.forEach((step) => {
|
||||
step.featuresInProgress.forEach((feature) => feature.leadTime++)
|
||||
|
||||
if (step.title.toLowerCase() !== 'release') {
|
||||
step.featuresDone.forEach((feature) => feature.leadTime++)
|
||||
const nextDay = (features: Feature[]): Feature[] => {
|
||||
features.forEach((feature) => {
|
||||
const isFeatureLive = feature.step === 0 && feature.status === 'done'
|
||||
if (isFeatureLive) {
|
||||
return
|
||||
}
|
||||
|
||||
feature.leadTime++
|
||||
})
|
||||
|
||||
return featureSteps
|
||||
return features
|
||||
}
|
||||
|
||||
return { initBoard, nextDay }
|
||||
|
||||
@@ -1,53 +1,43 @@
|
||||
export type FeatureStatus = 'doing' | 'done'
|
||||
|
||||
export type FeatureStep = {
|
||||
title: string
|
||||
featuresInProgress: Feature[]
|
||||
featuresDone: Feature[]
|
||||
blueBuckets: number
|
||||
stepIndex: number
|
||||
}
|
||||
|
||||
export const featureSteps: FeatureStep[] = [
|
||||
{
|
||||
title: 'Pitch',
|
||||
featuresInProgress: [],
|
||||
featuresDone: [],
|
||||
stepIndex: 6,
|
||||
blueBuckets: 2
|
||||
},
|
||||
{
|
||||
title: 'Design',
|
||||
featuresInProgress: [],
|
||||
featuresDone: [],
|
||||
stepIndex: 5,
|
||||
blueBuckets: 1
|
||||
},
|
||||
{
|
||||
title: 'Investigation',
|
||||
featuresInProgress: [],
|
||||
featuresDone: [],
|
||||
stepIndex: 4,
|
||||
blueBuckets: 1
|
||||
},
|
||||
{
|
||||
title: 'Product design',
|
||||
featuresInProgress: [],
|
||||
featuresDone: [],
|
||||
stepIndex: 3,
|
||||
blueBuckets: 2
|
||||
},
|
||||
{
|
||||
title: 'Development',
|
||||
featuresInProgress: [],
|
||||
featuresDone: [],
|
||||
stepIndex: 2,
|
||||
blueBuckets: 2
|
||||
},
|
||||
{
|
||||
title: 'UAT',
|
||||
featuresInProgress: [],
|
||||
featuresDone: [],
|
||||
stepIndex: 1,
|
||||
blueBuckets: 3
|
||||
},
|
||||
{
|
||||
title: 'Release',
|
||||
featuresInProgress: [],
|
||||
featuresDone: [],
|
||||
stepIndex: 0,
|
||||
blueBuckets: 0
|
||||
}
|
||||
]
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { Feature } from '@/modules/feature/feature'
|
||||
|
||||
const featureNames = [
|
||||
'Dachshund',
|
||||
'Jagdterrier',
|
||||
@@ -204,5 +206,7 @@ const featureNames = [
|
||||
export const features: Feature[] = featureNames.map((name) => ({
|
||||
name,
|
||||
complexity: Math.floor(Math.random() * 5),
|
||||
leadTime: 0
|
||||
leadTime: 0,
|
||||
status: 'doing',
|
||||
step: Infinity
|
||||
}))
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
type Feature = {
|
||||
export type FeatureStatus = 'doing' | 'done'
|
||||
|
||||
export type Feature = {
|
||||
name: string
|
||||
complexity: number
|
||||
leadTime: number
|
||||
status: FeatureStatus
|
||||
step: number
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user