Merge branch 'main' of github.com:jcalixte/tps into main
This commit is contained in:
@@ -9,7 +9,10 @@ withDefaults(defineProps<{ color?: string }>(), {
|
||||
<template>
|
||||
<BaseIcon :color="color">
|
||||
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
|
||||
<path d="M10 10m-7 0a7 7 0 1 0 14 0a7 7 0 1 0 -14 0" />
|
||||
<path d="M21 21l-6 -6" />
|
||||
<path d="M3 12h1m8 -9v1m8 8h1m-15.4 -6.4l.7 .7m12.1 -.7l-.7 .7" />
|
||||
<path
|
||||
d="M9 16a5 5 0 1 1 6 0a3.5 3.5 0 0 0 -1 3a2 2 0 0 1 -4 0a3.5 3.5 0 0 0 -1 -3"
|
||||
/>
|
||||
<path d="M9.7 17l4.6 0" />
|
||||
</BaseIcon>
|
||||
</template>
|
||||
|
||||
@@ -4,13 +4,21 @@
|
||||
<div class="flow-hypothesis">
|
||||
<p>Here our hypothesis:</p>
|
||||
<ol>
|
||||
<li>it takes the same amount of time for each team to complete a task</li>
|
||||
<li>
|
||||
it takes the same amount of time for each team to complete a task
|
||||
<span class="meaning">same task time</span>
|
||||
</li>
|
||||
<li>teams have no other external dependencies</li>
|
||||
<li>
|
||||
teams know exactly what they need to produce their part, they will tag
|
||||
any defects they found when verifying the feature is good.
|
||||
</li>
|
||||
<li>the team where the defect appears must rework the feature.</li>
|
||||
<li>
|
||||
0 defect policy: the team where the defect appears must rework the
|
||||
feature.
|
||||
</li>
|
||||
<li>release team never fails</li>
|
||||
<li>there is no limit on how many defects a feature can have.</li>
|
||||
</ol>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -4,13 +4,14 @@ import PullSystemIcon from '@/icons/PullSystemIcon.vue'
|
||||
import PushSystemIcon from '@/icons/PushSystemIcon.vue'
|
||||
import FeatureItem from '@/modules/feature/FeatureItem.vue'
|
||||
import FlowControls from '@/modules/feature/FlowControls.vue'
|
||||
import QualityIssue from '@/modules/feature/QualityIssue.vue'
|
||||
import { Feature } from '@/modules/feature/feature'
|
||||
|
||||
const feature: Feature = {
|
||||
name: 'As a user, in the homepage, I can login',
|
||||
complexity: 3,
|
||||
leadTime: 2,
|
||||
qualityIssue: 2,
|
||||
qualityIssue: 4,
|
||||
status: 'doing',
|
||||
step: 2
|
||||
}
|
||||
@@ -36,8 +37,8 @@ const feature: Feature = {
|
||||
number and deliver as fast as possible.
|
||||
</p>
|
||||
<p>
|
||||
<span class="numeric">{{ feature.qualityIssue }}</span> are the number of
|
||||
defects the feature had during the flow.
|
||||
<QualityIssue class="inline" :quality-issue="feature.qualityIssue" />
|
||||
are the number of defects the feature had during the flow.
|
||||
</p>
|
||||
<p>
|
||||
You have 20 features to deliver, and each day you can choose between 3
|
||||
@@ -85,15 +86,22 @@ const feature: Feature = {
|
||||
understand and limit rework. The more the team investigate, the more the
|
||||
team learn and start to be extremely good at problem solving.
|
||||
</p>
|
||||
<h3>Blue bin: the security stocks</h3>
|
||||
<h3>Blue bin: the security stock</h3>
|
||||
<p>
|
||||
Blue bins are your security stock, to make sure teams can work without any
|
||||
blockers. It's to make sure the next team will always have material to
|
||||
transform. But it comes with a cost: overburden, stagnation (increase lead
|
||||
time) and duplicated mistakes (not simulated here). The less you have, the
|
||||
time) and duplicated mistakes
|
||||
<span class="meaning">not simulated here</span>. The less you have, the
|
||||
less your team has mental charge. The more you have, the more secure you
|
||||
are to make teams work. One solution: simplify your flow and lower the
|
||||
number of operation the teams have to do to deliver a feature.
|
||||
</p>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.inline {
|
||||
display: inline;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<script setup lang="ts">
|
||||
import QualityIssue from '@/modules/feature/QualityIssue.vue'
|
||||
import { Feature } from '@/modules/feature/feature'
|
||||
import { computed } from 'vue'
|
||||
|
||||
@@ -16,9 +17,10 @@ const hasQualityIssues = computed(() => props.feature.qualityIssue > 0)
|
||||
</div>
|
||||
<div class="numeric">
|
||||
{{ feature.leadTime }}d
|
||||
<div v-if="hasQualityIssues" class="red-bin">
|
||||
{{ feature.qualityIssue }}
|
||||
</div>
|
||||
<QualityIssue
|
||||
v-if="hasQualityIssues"
|
||||
:quality-issue="feature.qualityIssue"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -39,12 +41,5 @@ const hasQualityIssues = computed(() => props.feature.qualityIssue > 0)
|
||||
visibility: hidden;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.red-bin {
|
||||
--warning-color: #ca0e0e;
|
||||
border: 2px solid var(--warning-color);
|
||||
padding: 0 0.5rem 0.1rem;
|
||||
color: var(--warning-color);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
20
src/modules/feature/QualityIssue.vue
Normal file
20
src/modules/feature/QualityIssue.vue
Normal file
@@ -0,0 +1,20 @@
|
||||
<script setup lang="ts">
|
||||
defineProps<{
|
||||
qualityIssue: number
|
||||
}>()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="quality-issue red-bin numeric">{{ qualityIssue }}</div>
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.quality-issue {
|
||||
&.red-bin {
|
||||
--warning-color: #ca0e0e;
|
||||
border: 2px solid var(--warning-color);
|
||||
padding: 0 0.5rem 0.1rem;
|
||||
color: var(--warning-color);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -7,6 +7,7 @@ import {
|
||||
getMean,
|
||||
pickRandomElement,
|
||||
popNElement,
|
||||
randomFloat,
|
||||
shuffleArray,
|
||||
sumElements
|
||||
} from '@/utils'
|
||||
@@ -28,7 +29,7 @@ const hasQualityIssue = ({
|
||||
)
|
||||
|
||||
const multiplicator = getOverburdenMultiplicator(tasksInParallel)
|
||||
const quality = Math.random()
|
||||
const quality = randomFloat(0, 1)
|
||||
|
||||
return quality > qualityProbability / multiplicator
|
||||
}
|
||||
@@ -230,7 +231,7 @@ export const nextDay = (
|
||||
state.meta.teamWorkExperience += 0.01
|
||||
|
||||
if (strategy === 'problem-solving') {
|
||||
const hasTeamLearned = Math.random() > 0.25
|
||||
const hasTeamLearned = randomFloat(0, 1) > 0.25
|
||||
if (hasTeamLearned) {
|
||||
state.meta.teamWorkExperience += 1.2
|
||||
}
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import { birds } from '@/data/bird'
|
||||
import { Feature } from '@/modules/feature/feature'
|
||||
import { randomInteger } from '@/utils'
|
||||
|
||||
export const features: Feature[] = birds.map((name) => ({
|
||||
name,
|
||||
complexity: Math.floor(Math.random() * 5) + 1,
|
||||
complexity: randomInteger(1, 5),
|
||||
leadTime: 0,
|
||||
status: 'doing',
|
||||
step: Infinity,
|
||||
|
||||
16
src/utils.ts
16
src/utils.ts
@@ -1,3 +1,15 @@
|
||||
import { Random } from 'random-js'
|
||||
|
||||
const random = new Random()
|
||||
|
||||
export const randomInteger = (min: number, max: number) => {
|
||||
return random.integer(min, max)
|
||||
}
|
||||
|
||||
export const randomFloat = (min: number, max: number) => {
|
||||
return random.real(min, max)
|
||||
}
|
||||
|
||||
export const getMean = (data: number[]) =>
|
||||
Math.round(100 * (sumElements(data) / data.length)) / 100
|
||||
|
||||
@@ -11,7 +23,7 @@ export const shuffleArray = <T>(array: T[]) => {
|
||||
randomIndex
|
||||
|
||||
while (currentIndex !== 0) {
|
||||
randomIndex = Math.floor(Math.random() * currentIndex)
|
||||
randomIndex = randomInteger(0, currentIndex - 1)
|
||||
currentIndex--
|
||||
;[array[currentIndex], array[randomIndex]] = [
|
||||
array[randomIndex],
|
||||
@@ -37,7 +49,7 @@ export const popNElement = <T>(array: T[], numberOfElements: number) => {
|
||||
}
|
||||
|
||||
export const pickRandomIndex = <T>(array: T[]) =>
|
||||
Math.floor(Math.random() * array.length)
|
||||
randomInteger(0, array.length - 1)
|
||||
|
||||
export const pickRandomElement = <T>(array: T[]) =>
|
||||
array[pickRandomIndex(array)]
|
||||
|
||||
Reference in New Issue
Block a user