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">
|
||||
import FeatureDashboard from '@/modules/feature/FeatureDashboard.vue'
|
||||
import FeatureStep from '@/modules/feature/FeatureStep.vue'
|
||||
import { featureSteps } from '@/modules/feature/feature-steps'
|
||||
import { useFeatureStore } from '@/modules/feature/store'
|
||||
@@ -29,7 +30,8 @@ const pushAndProblemSolving20Percent = () => {
|
||||
<div>
|
||||
{{ featureStore.features.length }} features | mean complexity :
|
||||
{{ featureStore.meanComplexity }} | mean lead time :
|
||||
{{ featureStore.meanLeadTime }} days
|
||||
{{ featureStore.meanLeadTime }} days | Total days:
|
||||
{{ featureStore.meta.totalDays }}
|
||||
</div>
|
||||
<div>
|
||||
<button @click="featureStore.nextDay('push')">push system</button>
|
||||
@@ -43,7 +45,16 @@ const pushAndProblemSolving20Percent = () => {
|
||||
<button @click="featureStore.nextDay('problem-solving')">
|
||||
problem solving
|
||||
</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>
|
||||
<ul class="features-steps">
|
||||
@@ -54,6 +65,7 @@ const pushAndProblemSolving20Percent = () => {
|
||||
:features="featureStore.featuresGroupedByStep[step.stepIndex] ?? []"
|
||||
/>
|
||||
</ul>
|
||||
<FeatureDashboard />
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
||||
@@ -21,8 +21,9 @@ const hasQualityIssue = ({
|
||||
)
|
||||
|
||||
let multiplicator = getOverburdenMultiplicator(tasksInParallel)
|
||||
const quality = Math.random()
|
||||
|
||||
return Math.random() > qualityProbability / multiplicator
|
||||
return quality > qualityProbability / multiplicator
|
||||
}
|
||||
|
||||
export const newBoard = () => shuffleArray(features)
|
||||
|
||||
@@ -13,9 +13,10 @@ type Meta = {
|
||||
|
||||
type Analysis = {
|
||||
worstFeature: Feature
|
||||
daysToDeliver: number
|
||||
meanQualityIssue: number
|
||||
meanComplexity: number
|
||||
meanLeadTime: number
|
||||
mainStrategy: Strategy | string
|
||||
}
|
||||
|
||||
type Dashboard = Array<{
|
||||
@@ -29,7 +30,7 @@ type State = {
|
||||
features: Feature[]
|
||||
backlog: Feature[]
|
||||
meta: Meta
|
||||
dashboard: Dashboard
|
||||
dashboards: Dashboard
|
||||
}
|
||||
|
||||
const resetMeta = (): Meta => ({
|
||||
@@ -48,7 +49,7 @@ export const useFeatureStore = defineStore('feature', {
|
||||
features: [],
|
||||
backlog: [],
|
||||
meta: resetMeta(),
|
||||
dashboard: []
|
||||
dashboards: []
|
||||
}),
|
||||
actions: {
|
||||
initBoard() {
|
||||
@@ -73,6 +74,32 @@ export const useFeatureStore = defineStore('feature', {
|
||||
strategy,
|
||||
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: {
|
||||
@@ -94,6 +121,17 @@ export const useFeatureStore = defineStore('feature', {
|
||||
) / 100
|
||||
)
|
||||
},
|
||||
meanQualityIssue: (state) => {
|
||||
return (
|
||||
Math.round(
|
||||
100 *
|
||||
(sumElements(
|
||||
state.features.map((feature) => feature.qualityIssue)
|
||||
) /
|
||||
state.features.length)
|
||||
) / 100
|
||||
)
|
||||
},
|
||||
featuresGroupedByStep: (state) => {
|
||||
const groupedByStep: Record<number, Feature[]> = {}
|
||||
|
||||
@@ -106,6 +144,10 @@ export const useFeatureStore = defineStore('feature', {
|
||||
})
|
||||
|
||||
return groupedByStep
|
||||
}
|
||||
},
|
||||
isProjectFinished: (state) =>
|
||||
state.features.every(
|
||||
(feature) => feature.step === 0 && feature.status === 'done'
|
||||
)
|
||||
}
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user