simulate and show dashboard
This commit is contained in:
26
src/modules/feature/FeatureDashboard.vue
Normal file
26
src/modules/feature/FeatureDashboard.vue
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import { useFeatureStore } from '@/modules/feature/store'
|
||||||
|
|
||||||
|
const featureStore = useFeatureStore()
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="feature-dashboard">
|
||||||
|
Dashboard
|
||||||
|
<ul>
|
||||||
|
<li v-for="dashboard in featureStore.dashboards" :key="dashboard.uuid">
|
||||||
|
{{ dashboard.analysis.mainStrategy }}: mean lead time
|
||||||
|
{{ dashboard.analysis.meanLeadTime }} | worst feature for quality
|
||||||
|
{{ dashboard.analysis.worstFeature.qualityIssue }} [{{
|
||||||
|
dashboard.analysis.worstFeature.complexity
|
||||||
|
}}]
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.feature-dashboard {
|
||||||
|
color: var(--background-color);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
import FeatureDashboard from '@/modules/feature/FeatureDashboard.vue'
|
||||||
import FeatureStep from '@/modules/feature/FeatureStep.vue'
|
import FeatureStep from '@/modules/feature/FeatureStep.vue'
|
||||||
import { featureSteps } from '@/modules/feature/feature-steps'
|
import { featureSteps } from '@/modules/feature/feature-steps'
|
||||||
import { useFeatureStore } from '@/modules/feature/store'
|
import { useFeatureStore } from '@/modules/feature/store'
|
||||||
@@ -29,7 +30,8 @@ const pushAndProblemSolving20Percent = () => {
|
|||||||
<div>
|
<div>
|
||||||
{{ featureStore.features.length }} features | mean complexity :
|
{{ featureStore.features.length }} features | mean complexity :
|
||||||
{{ featureStore.meanComplexity }} | mean lead time :
|
{{ featureStore.meanComplexity }} | mean lead time :
|
||||||
{{ featureStore.meanLeadTime }} days
|
{{ featureStore.meanLeadTime }} days | Total days:
|
||||||
|
{{ featureStore.meta.totalDays }}
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<button @click="featureStore.nextDay('push')">push system</button>
|
<button @click="featureStore.nextDay('push')">push system</button>
|
||||||
@@ -43,7 +45,16 @@ const pushAndProblemSolving20Percent = () => {
|
|||||||
<button @click="featureStore.nextDay('problem-solving')">
|
<button @click="featureStore.nextDay('problem-solving')">
|
||||||
problem solving
|
problem solving
|
||||||
</button>
|
</button>
|
||||||
Total days: {{ featureStore.meta.totalDays }}
|
<button @click="featureStore.simulate('push')">
|
||||||
|
simulate push system
|
||||||
|
</button>
|
||||||
|
<button @click="featureStore.simulate('pull')">
|
||||||
|
simulate pull system
|
||||||
|
</button>
|
||||||
|
<button @click="featureStore.simulate('pull')">
|
||||||
|
simulate pull and problem solving
|
||||||
|
</button>
|
||||||
|
<button @click="featureStore.clearDashboard()">clear dashboard</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<ul class="features-steps">
|
<ul class="features-steps">
|
||||||
@@ -54,6 +65,7 @@ const pushAndProblemSolving20Percent = () => {
|
|||||||
:features="featureStore.featuresGroupedByStep[step.stepIndex] ?? []"
|
:features="featureStore.featuresGroupedByStep[step.stepIndex] ?? []"
|
||||||
/>
|
/>
|
||||||
</ul>
|
</ul>
|
||||||
|
<FeatureDashboard />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
|
|||||||
@@ -21,8 +21,9 @@ const hasQualityIssue = ({
|
|||||||
)
|
)
|
||||||
|
|
||||||
let multiplicator = getOverburdenMultiplicator(tasksInParallel)
|
let multiplicator = getOverburdenMultiplicator(tasksInParallel)
|
||||||
|
const quality = Math.random()
|
||||||
|
|
||||||
return Math.random() > qualityProbability / multiplicator
|
return quality > qualityProbability / multiplicator
|
||||||
}
|
}
|
||||||
|
|
||||||
export const newBoard = () => shuffleArray(features)
|
export const newBoard = () => shuffleArray(features)
|
||||||
|
|||||||
@@ -13,9 +13,10 @@ type Meta = {
|
|||||||
|
|
||||||
type Analysis = {
|
type Analysis = {
|
||||||
worstFeature: Feature
|
worstFeature: Feature
|
||||||
daysToDeliver: number
|
meanQualityIssue: number
|
||||||
meanComplexity: number
|
meanComplexity: number
|
||||||
meanLeadTime: number
|
meanLeadTime: number
|
||||||
|
mainStrategy: Strategy | string
|
||||||
}
|
}
|
||||||
|
|
||||||
type Dashboard = Array<{
|
type Dashboard = Array<{
|
||||||
@@ -29,7 +30,7 @@ type State = {
|
|||||||
features: Feature[]
|
features: Feature[]
|
||||||
backlog: Feature[]
|
backlog: Feature[]
|
||||||
meta: Meta
|
meta: Meta
|
||||||
dashboard: Dashboard
|
dashboards: Dashboard
|
||||||
}
|
}
|
||||||
|
|
||||||
const resetMeta = (): Meta => ({
|
const resetMeta = (): Meta => ({
|
||||||
@@ -48,7 +49,7 @@ export const useFeatureStore = defineStore('feature', {
|
|||||||
features: [],
|
features: [],
|
||||||
backlog: [],
|
backlog: [],
|
||||||
meta: resetMeta(),
|
meta: resetMeta(),
|
||||||
dashboard: []
|
dashboards: []
|
||||||
}),
|
}),
|
||||||
actions: {
|
actions: {
|
||||||
initBoard() {
|
initBoard() {
|
||||||
@@ -73,6 +74,32 @@ export const useFeatureStore = defineStore('feature', {
|
|||||||
strategy,
|
strategy,
|
||||||
daysWithProblemSolving: this.meta.daysWithProblemSolving
|
daysWithProblemSolving: this.meta.daysWithProblemSolving
|
||||||
})
|
})
|
||||||
|
},
|
||||||
|
simulate(strategy: Strategy) {
|
||||||
|
this.initBoard()
|
||||||
|
while (!this.isProjectFinished) {
|
||||||
|
this.nextDay(strategy)
|
||||||
|
}
|
||||||
|
const [worstFeature] = this.features.sort((a, b) =>
|
||||||
|
a.qualityIssue > b.qualityIssue ? -1 : 1
|
||||||
|
)
|
||||||
|
|
||||||
|
this.dashboards.push({
|
||||||
|
uuid: new Date().getTime().toString(),
|
||||||
|
meta: this.meta,
|
||||||
|
analysis: {
|
||||||
|
meanComplexity: this.meanComplexity,
|
||||||
|
meanLeadTime: this.meanLeadTime,
|
||||||
|
meanQualityIssue: this.meanQualityIssue,
|
||||||
|
worstFeature,
|
||||||
|
mainStrategy: Object.entries(this.meta.strategy).sort((a, b) =>
|
||||||
|
a[1] > b[1] ? -1 : 1
|
||||||
|
)[0][0]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
clearDashboard() {
|
||||||
|
this.dashboards = []
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
getters: {
|
getters: {
|
||||||
@@ -94,6 +121,17 @@ export const useFeatureStore = defineStore('feature', {
|
|||||||
) / 100
|
) / 100
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
|
meanQualityIssue: (state) => {
|
||||||
|
return (
|
||||||
|
Math.round(
|
||||||
|
100 *
|
||||||
|
(sumElements(
|
||||||
|
state.features.map((feature) => feature.qualityIssue)
|
||||||
|
) /
|
||||||
|
state.features.length)
|
||||||
|
) / 100
|
||||||
|
)
|
||||||
|
},
|
||||||
featuresGroupedByStep: (state) => {
|
featuresGroupedByStep: (state) => {
|
||||||
const groupedByStep: Record<number, Feature[]> = {}
|
const groupedByStep: Record<number, Feature[]> = {}
|
||||||
|
|
||||||
@@ -106,6 +144,10 @@ export const useFeatureStore = defineStore('feature', {
|
|||||||
})
|
})
|
||||||
|
|
||||||
return groupedByStep
|
return groupedByStep
|
||||||
}
|
},
|
||||||
|
isProjectFinished: (state) =>
|
||||||
|
state.features.every(
|
||||||
|
(feature) => feature.step === 0 && feature.status === 'done'
|
||||||
|
)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user