easier takt time computation
This commit is contained in:
@@ -4,22 +4,25 @@ import { featureSteps } from '@/modules/feature/feature-steps'
|
|||||||
import { useFeatureStore } from '@/modules/feature/feature-store'
|
import { useFeatureStore } from '@/modules/feature/feature-store'
|
||||||
import { onMounted } from 'vue'
|
import { onMounted } from 'vue'
|
||||||
|
|
||||||
|
const NUMBER_OF_FEATURES = 20
|
||||||
|
|
||||||
const featureStore = useFeatureStore()
|
const featureStore = useFeatureStore()
|
||||||
|
|
||||||
onMounted(() => featureStore.initBoard())
|
onMounted(() => featureStore.initBoard(NUMBER_OF_FEATURES))
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="dashboard">
|
<div class="dashboard">
|
||||||
<div>
|
<div>
|
||||||
{{ featureStore.features.length }} features | mean complexity :
|
{{ featureStore.features.length }} / {{ NUMBER_OF_FEATURES }} features in
|
||||||
{{ featureStore.meanComplexity }} | mean lead time :
|
the board | mean complexity : {{ featureStore.meanComplexity }} | mean
|
||||||
{{ featureStore.meanLeadTime }} days | Total days:
|
lead time : {{ featureStore.meanLeadTime }} days | Total days:
|
||||||
{{ featureStore.meta.totalDays }} | Team work experience:
|
{{ featureStore.meta.totalDays }} | Team work experience:
|
||||||
{{ featureStore.meta.teamWorkExperience }}
|
{{ featureStore.meta.teamWorkExperience }}
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
New feature live every {{ featureStore.taktTime }} days.
|
New feature live every {{ featureStore.taktTime }} days. Finishing in
|
||||||
|
{{ featureStore.eat }} days.
|
||||||
</div>
|
</div>
|
||||||
<div class="row">Strategy of the day:</div>
|
<div class="row">Strategy of the day:</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ import {
|
|||||||
sumElements
|
sumElements
|
||||||
} from '@/utils'
|
} from '@/utils'
|
||||||
|
|
||||||
const MAX_FEATURES = 200
|
|
||||||
const HARD_STOP = 5000
|
const HARD_STOP = 5000
|
||||||
|
|
||||||
const hasQualityIssue = ({
|
const hasQualityIssue = ({
|
||||||
@@ -34,7 +33,10 @@ const hasQualityIssue = ({
|
|||||||
return quality > qualityProbability / multiplicator
|
return quality > qualityProbability / multiplicator
|
||||||
}
|
}
|
||||||
|
|
||||||
export const newBacklog = () => shuffleArray(initialFeatures)
|
export const newBacklog = (limit?: number) =>
|
||||||
|
limit !== undefined
|
||||||
|
? popNElement(shuffleArray(initialFeatures), limit)
|
||||||
|
: shuffleArray(initialFeatures)
|
||||||
|
|
||||||
export const initBoard = (
|
export const initBoard = (
|
||||||
steps: FeatureStep[],
|
steps: FeatureStep[],
|
||||||
@@ -125,7 +127,7 @@ export const getFeaturesForNextDay = ({
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
if (features.length < MAX_FEATURES) {
|
if (backlog.length > 0) {
|
||||||
switch (strategy) {
|
switch (strategy) {
|
||||||
case 'push': {
|
case 'push': {
|
||||||
const [nextFeature] = popNElement(backlog, 1)
|
const [nextFeature] = popNElement(backlog, 1)
|
||||||
@@ -217,7 +219,7 @@ const getQualityProbability = (
|
|||||||
return probabilityOfGoodQuality
|
return probabilityOfGoodQuality
|
||||||
}
|
}
|
||||||
|
|
||||||
const isFeatureDone = (feature: Feature) =>
|
export const isFeatureDone = (feature: Feature) =>
|
||||||
feature.step === 0 && feature.status === 'done'
|
feature.step === 0 && feature.status === 'done'
|
||||||
|
|
||||||
export const nextDay = (
|
export const nextDay = (
|
||||||
@@ -276,7 +278,7 @@ export const simulate = (
|
|||||||
let i = 0
|
let i = 0
|
||||||
|
|
||||||
while (!isProjectFinished(state.features) && i++ < HARD_STOP) {
|
while (!isProjectFinished(state.features) && i++ < HARD_STOP) {
|
||||||
if (strategy === 'pull-dps' || strategy === 'push-dps') {
|
if (strategy.includes('dps')) {
|
||||||
if (state.meta.totalDays % 5 === 0) {
|
if (state.meta.totalDays % 5 === 0) {
|
||||||
state = nextDay(state, 'problem-solving')
|
state = nextDay(state, 'problem-solving')
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -4,13 +4,13 @@ import {
|
|||||||
getMeanLeadTime,
|
getMeanLeadTime,
|
||||||
getMeanQualityIssue,
|
getMeanQualityIssue,
|
||||||
initBoard,
|
initBoard,
|
||||||
|
isFeatureDone,
|
||||||
newBacklog,
|
newBacklog,
|
||||||
nextDay
|
nextDay
|
||||||
} from '@/modules/feature/feature-board'
|
} from '@/modules/feature/feature-board'
|
||||||
import { featureSteps } from '@/modules/feature/feature-steps'
|
import { featureSteps } from '@/modules/feature/feature-steps'
|
||||||
import { Strategy } from '@/modules/lean/strategy'
|
import { Strategy } from '@/modules/lean/strategy'
|
||||||
import { FeatureState, Meta } from '@/store-type'
|
import { FeatureState, Meta } from '@/store-type'
|
||||||
import { sumElements } from '@/utils'
|
|
||||||
import { defineStore } from 'pinia'
|
import { defineStore } from 'pinia'
|
||||||
|
|
||||||
const resetMeta = (): Meta => ({
|
const resetMeta = (): Meta => ({
|
||||||
@@ -33,9 +33,9 @@ export const useFeatureStore = defineStore('feature', {
|
|||||||
meta: resetMeta()
|
meta: resetMeta()
|
||||||
}),
|
}),
|
||||||
actions: {
|
actions: {
|
||||||
// set the number of feature we want
|
// todo set the number of feature we want
|
||||||
async initBoard() {
|
async initBoard(limit: number) {
|
||||||
this.backlog = newBacklog()
|
this.backlog = newBacklog(limit)
|
||||||
this.steps = featureSteps
|
this.steps = featureSteps
|
||||||
this.features = initBoard(this.steps, this.backlog)
|
this.features = initBoard(this.steps, this.backlog)
|
||||||
|
|
||||||
@@ -56,10 +56,10 @@ export const useFeatureStore = defineStore('feature', {
|
|||||||
meanComplexity: (state) => getMeanComplexity(state.features),
|
meanComplexity: (state) => getMeanComplexity(state.features),
|
||||||
meanLeadTime: (state) => getMeanLeadTime(state.features),
|
meanLeadTime: (state) => getMeanLeadTime(state.features),
|
||||||
meanQualityIssue: (state) => getMeanQualityIssue(state.features),
|
meanQualityIssue: (state) => getMeanQualityIssue(state.features),
|
||||||
taktTime: (state) =>
|
taktTime: (state): string =>
|
||||||
(
|
(
|
||||||
state.meta.totalDays / sumElements(state.meta.featuresDonePerDay)
|
state.meta.totalDays / state.features.filter(isFeatureDone).length
|
||||||
).toFixed(2) ?? 0,
|
).toFixed(2) ?? `0`,
|
||||||
featuresGroupedByStep: (state) => {
|
featuresGroupedByStep: (state) => {
|
||||||
const groupedByStep: Record<number, Feature[]> = {}
|
const groupedByStep: Record<number, Feature[]> = {}
|
||||||
|
|
||||||
@@ -72,6 +72,13 @@ export const useFeatureStore = defineStore('feature', {
|
|||||||
})
|
})
|
||||||
|
|
||||||
return groupedByStep
|
return groupedByStep
|
||||||
|
},
|
||||||
|
eat(): string {
|
||||||
|
return (
|
||||||
|
parseFloat(this.taktTime) *
|
||||||
|
(this.features.filter((feature) => !isFeatureDone(feature)).length +
|
||||||
|
this.backlog.length)
|
||||||
|
).toFixed(2)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -21,8 +21,8 @@ const strategies: Strategy[] = ['push', 'pull', 'push-dps', 'pull-dps']
|
|||||||
<th>#</th>
|
<th>#</th>
|
||||||
<th class="numeric">push</th>
|
<th class="numeric">push</th>
|
||||||
<th class="numeric">pull</th>
|
<th class="numeric">pull</th>
|
||||||
<th class="numeric">pull and DPS</th>
|
|
||||||
<th class="numeric">push and DPS</th>
|
<th class="numeric">push and DPS</th>
|
||||||
|
<th class="numeric">pull and DPS</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { featureSteps } from '@/modules/feature/feature-steps'
|
import { featureSteps } from '@/modules/feature/feature-steps'
|
||||||
import { Strategy } from '@/modules/lean/strategy'
|
import { Strategy } from '@/modules/lean/strategy'
|
||||||
import { Dashboard, Meta } from '@/store-type'
|
import { Dashboard, Meta } from '@/store-type'
|
||||||
import { getRound, sumElements } from '@/utils'
|
import { getRound } from '@/utils'
|
||||||
import { defineStore } from 'pinia'
|
import { defineStore } from 'pinia'
|
||||||
|
|
||||||
// Get features done per day to plot it
|
// Get features done per day to plot it
|
||||||
@@ -64,6 +64,7 @@ export const useSimulationStore = defineStore('dashboard', {
|
|||||||
this.dashboards.push(dashboard)
|
this.dashboards.push(dashboard)
|
||||||
},
|
},
|
||||||
async simulate(strategy: Strategy) {
|
async simulate(strategy: Strategy) {
|
||||||
|
this.requestedSimulation++
|
||||||
const steps = featureSteps
|
const steps = featureSteps
|
||||||
const backlog = await instance.newBacklog()
|
const backlog = await instance.newBacklog()
|
||||||
const features = await instance.initBoard(steps, backlog)
|
const features = await instance.initBoard(steps, backlog)
|
||||||
@@ -98,10 +99,8 @@ export const useSimulationStore = defineStore('dashboard', {
|
|||||||
|
|
||||||
this.newDashboard(dashboard)
|
this.newDashboard(dashboard)
|
||||||
this.mean[strategy].leadTimeSum += dashboard.analysis.meanLeadTime
|
this.mean[strategy].leadTimeSum += dashboard.analysis.meanLeadTime
|
||||||
// todo: set directly the number of features
|
|
||||||
this.mean[strategy].taktTimeSum +=
|
this.mean[strategy].taktTimeSum +=
|
||||||
dashboard.meta.totalDays /
|
dashboard.meta.totalDays / newState.features.length
|
||||||
sumElements(dashboard.meta.featuresDonePerDay)
|
|
||||||
this.mean[strategy].complexitySum += dashboard.analysis.meanComplexity
|
this.mean[strategy].complexitySum += dashboard.analysis.meanComplexity
|
||||||
this.mean[strategy].qualityIssueSum += dashboard.analysis.meanQualityIssue
|
this.mean[strategy].qualityIssueSum += dashboard.analysis.meanQualityIssue
|
||||||
this.mean[strategy].simulations++
|
this.mean[strategy].simulations++
|
||||||
|
|||||||
Reference in New Issue
Block a user