Merge branch 'main' of github.com:jcalixte/tps

This commit is contained in:
Julien Calixte
2025-05-23 10:42:56 +02:00
6 changed files with 83 additions and 50 deletions

View File

@@ -30,6 +30,22 @@ li {
color: var(--primary-color); color: var(--primary-color);
} }
.no-focus.text-hide,
.no-focus.text-hide a,
.no-focus.text-hide a:visited,
.no-focus.text-hide a:focus,
.no-focus.text-hide a:focus-visible {
color: var(--primary-color-no-focus);
}
.focus.text-hide,
.focus.text-hide a,
.focus.text-hide a:visited,
.focus.text-hide a:focus,
.focus.text-hide a:focus-visible {
color: var(--color);
}
.customer-satisfaction-roof-parent { .customer-satisfaction-roof-parent {
filter: url(#round); filter: url(#round);
/* Making the triangle fit the rest of the house */ /* Making the triangle fit the rest of the house */
@@ -181,7 +197,14 @@ details.hud li {
.raibow { .raibow {
text-decoration: underline; text-decoration: underline;
background: linear-gradient(to right, #6666ff, #0099ff, #00ff00, #ff3399, #6666ff); background: linear-gradient(
to right,
#6666ff,
#0099ff,
#00ff00,
#ff3399,
#6666ff
);
-webkit-background-clip: text; -webkit-background-clip: text;
background-clip: text; background-clip: text;
color: transparent; color: transparent;
@@ -189,9 +212,7 @@ details.hud li {
background-size: 400% 100%; background-size: 400% 100%;
} }
@keyframes rainbow-animation { @keyframes rainbow-animation {
0%, 0%,
100% { 100% {
background-position: 0 0; background-position: 0 0;
@@ -200,4 +221,4 @@ details.hud li {
50% { 50% {
background-position: 100% 0; background-position: 100% 0;
} }
} }

View File

@@ -161,7 +161,7 @@
</ul> </ul>
<p> <p>
Screenshot the house: Screenshot the house:
<button class="button" id="screenshot-house">Screenshot</button> <button class="button" id="screenshot-house">copy to clipboard</button>
</p> </p>
</details> </details>
<svg class="round-svg" xmlns="http://www.w3.org/2000/svg"> <svg class="round-svg" xmlns="http://www.w3.org/2000/svg">

24
main.ts
View File

@@ -50,7 +50,9 @@ if (focusElements.length > 0) {
focusable.classList.contains(element) focusable.classList.contains(element)
) )
if (!elementToFocus) { if (elementToFocus) {
focusable.classList.add('focus')
} else {
focusable.classList.add('no-focus') focusable.classList.add('no-focus')
} }
}) })
@@ -83,12 +85,20 @@ const screenshotHouseButton = document.querySelector('#screenshot-house')
if (screenshotHouseButton) { if (screenshotHouseButton) {
screenshotHouseButton.addEventListener('click', async () => { screenshotHouseButton.addEventListener('click', async () => {
const house = document.querySelector('#thinking-people-system') const house = document.querySelector('#thinking-people-system')
if (house) { if (!house) {
const png = await domToPng(house) return
const a = document.createElement('a') }
a.href = png
a.download = 'thinking-people-system.png' const png = await domToPng(house)
a.click()
try {
const response = await fetch(png)
const blob = await response.blob()
await navigator.clipboard.write([
new ClipboardItem({ [blob.type]: blob })
])
} catch (error) {
console.warn(error)
} }
}) })
} }

View File

@@ -121,55 +121,50 @@ const createdAt = new Date('2025-01-08').toLocaleDateString(undefined, {
coding, and ensuring the product goes live. coding, and ensuring the product goes live.
</p> </p>
<p> <p>
First, what is a feature? A feature is a software component that First, let's take a moment to define the most important element: the
provides a functionality for the user. Examples include the ability to feature. A feature is a software component that provides a functionality
read articles, share content, or use the app offline. In our simulation, for the user like the ability to read articles, share content, or use
a feature is represented as follows: the app offline. In our simulation, a feature is represented as follows:
</p> </p>
<FeatureItem :feature="feature" /> <FeatureItem :feature="feature" />
<p> <p>
Each feature starts with an intention: "<code>{{ feature.name }}</code Each feature starts with an intention: "<code>{{ feature.name }}</code
>". This defines what we will add to the mobile app. >". "<span class="numeric">{{ feature.leadTime }}d</span>" indicates the
number of days teams work on the feature. The goal is to minimize this
number and deliver features as quickly as possible. "<QualityIssue
class="inline"
:quality-issue="feature.qualityIssue"
/>" shows the number of defects found in the feature during its workflow
<em
>(For simplicity, we assume teams can identify all defects, and no
defective features are delivered)</em
>. Any defect must be reworked by the team that caused it.
</p> </p>
<p>It takes one day to each team to complete their part.</p>
<!-- [complexity] <!-- [complexity]
<p> <p>
<span class="numeric">({{ feature.complexity }})</span> is the <span class="numeric">({{ feature.complexity }})</span> is the
complexity of the feature. The more complex a feature is, the more complexity of the feature. The more complex a feature is, the more
chance we introduce a defect. chance we introduce a defect.
</p> --> </p> -->
<p>
<span class="numeric">{{ feature.leadTime }}d</span> indicates the
number of days teams work on the feature. The goal is to minimize this
number and deliver features as quickly as possible.
</p>
<p>
<QualityIssue class="inline" :quality-issue="feature.qualityIssue" />
shows the number of defects found in the feature during its workflow.
For simplicity, we assume teams can identify all defects, and no
defective features are delivered. Any defect must be reworked by the
team that caused it.
</p>
<p>
Okay! We have 20 features to deliver. Each team takes one day to
complete their part for a feature.
</p>
<!-- [dps] <p>Each day, you can choose between 3 strategies:</p> --> <!-- [dps] <p>Each day, you can choose between 3 strategies:</p> -->
<p>Every day, you can choose between two strategies:</p>
<ol>
<li><PushSystemIcon /> Push system</li>
<li><PullSystemIcon /> Pull system</li>
</ol>
<p> <p>
In this article, well examine how these strategies affect efficiency Okay! We have 20 features to deliver and every day, you can choose
and quality. Lets explore each one! between two strategies:
</p> </p>
<h3>The Push System: Start as Many Features as Possible</h3> <h3>
1. <PushSystemIcon /> The Push System: Start as Many Features as
Possible
</h3>
<p> <p>
In the push system, we aim to maximize the time teams spend working on In the push system, we aim to maximize the time teams spend working on
the product. This ensures no downtime, as everyone always has tasks to the product. This ensures no downtime, as everyone always has tasks to
complete. complete.
</p> </p>
<h3>The Pull System: Produce Features When the Next Team Needs Them</h3> <h3>
2. <PullSystemIcon /> The Pull System: Produce Features When the Next
Team Needs Them
</h3>
<p> <p>
Instead of pushing features forward, the pull system waits until the Instead of pushing features forward, the pull system waits until the
next team is ready. This approach acknowledges that the ideal "push next team is ready. This approach acknowledges that the ideal "push
@@ -177,9 +172,9 @@ const createdAt = new Date('2025-01-08').toLocaleDateString(undefined, {
readiness, we avoid creating a backlog of pre-prepared features. readiness, we avoid creating a backlog of pre-prepared features.
</p> </p>
<p> <p>
To implement this, we introduce "blue bins" as safety stock. These bins We introduce "blue bins" as safety stocks: these bins ensure teams
ensure teams always have work ready to process without delays but we always have work ready to process without delays
stop whenever blue bins are full. <em><strong>but</strong></em> teams stop whenever blue bins are full.
</p> </p>
<!-- [dps] <!-- [dps]
<h3>Problem solving: no production, just reflection</h3> <h3>Problem solving: no production, just reflection</h3>
@@ -191,12 +186,15 @@ const createdAt = new Date('2025-01-08').toLocaleDateString(undefined, {
team learn and start to be extremely good at problem solving. team learn and start to be extremely good at problem solving.
</p> --> </p> -->
</div> </div>
<div class="text">
<p>All set? Let's make this app!</p>
</div>
<FlowDashboard class="above" /> <FlowDashboard class="above" />
<FeatureSteps alias="playground" /> <FeatureSteps alias="playground" />
<div class="manual-simulation text"> <div class="manual-simulation text">
<p> <p>
Well, what do you think? Not so simple... What are the insights from Well, what do you think? Not so obvious... What can we say? Here are
these strategies? Here are some observations: some observations:
</p> </p>
<ol> <ol>
<li> <li>
@@ -230,7 +228,7 @@ const createdAt = new Date('2025-01-08').toLocaleDateString(undefined, {
</p> </p>
<p> <p>
Do you mind comparing more projects? What happens when we simulate 1000 Do you mind comparing more projects? What happens when we simulate 1000
news mobile app! Are patterns the same? news mobile apps! Are patterns the same?
</p> </p>
</div> </div>
<SimulationControls type="multiple" /> <SimulationControls type="multiple" />

View File

@@ -15,7 +15,11 @@ const featuresInProgress = computed(() =>
props.features.filter((feature) => feature.status === 'doing') props.features.filter((feature) => feature.status === 'doing')
) )
const featuresDone = computed(() => const featuresDone = computed(() =>
props.features.filter((feature) => feature.status === 'done') props.step.title === 'Release'
? props.features
.filter((feature) => feature.status === 'done')
.sort((a, b) => (a.leadTime > b.leadTime ? -1 : 1))
: props.features.filter((feature) => feature.status === 'done')
) )
const hasFeaturesInProgress = computed( const hasFeaturesInProgress = computed(

View File

@@ -152,7 +152,7 @@
</ul> </ul>
<p> <p>
Screenshot the house: Screenshot the house:
<button class="button" id="screenshot-house">Screenshot</button> <button class="button" id="screenshot-house">copy to clipboard</button>
</p> </p>
</details> </details>
<svg class="round-svg" xmlns="http://www.w3.org/2000/svg"> <svg class="round-svg" xmlns="http://www.w3.org/2000/svg">