refacto: extract the toolbox component
This commit is contained in:
44
src/modules/5s/BoardGameToolbox.vue
Normal file
44
src/modules/5s/BoardGameToolbox.vue
Normal file
@@ -0,0 +1,44 @@
|
||||
<script setup lang="ts">
|
||||
import { useBoardGameStore } from '@/modules/5s/board-game-store'
|
||||
import { computed } from 'vue'
|
||||
|
||||
const boardGameStore = useBoardGameStore()
|
||||
const isSeitonActivated = computed(() =>
|
||||
boardGameStore.sUsed.includes('seiton')
|
||||
)
|
||||
|
||||
const rawTools = computed(() =>
|
||||
boardGameStore.tools.map((t) => `${t.name} (${t.alias})`).join(', ')
|
||||
)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<aside class="board-game-tools prose">
|
||||
<h2>Toolbox</h2>
|
||||
<div class="overflow-x-auto" v-if="isSeitonActivated">
|
||||
<table class="table table-zebra">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Tool</th>
|
||||
<th>Alias</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="tool in boardGameStore.tools" :key="tool.alias">
|
||||
<td>{{ tool.name }}</td>
|
||||
<td>{{ tool.alias }}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div v-else>
|
||||
{{ rawTools }}
|
||||
</div>
|
||||
</aside>
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.board-game-tools {
|
||||
flex: 1;
|
||||
}
|
||||
</style>
|
||||
@@ -1,54 +1,56 @@
|
||||
<script setup lang="ts">
|
||||
import { useBoardGameStore } from '@/modules/5s/board-game-store'
|
||||
import BoardGameToolbox from '@/modules/5s/BoardGameToolbox.vue'
|
||||
import { _5S, is5S } from '@/modules/5s/types/5s'
|
||||
import { toDuration } from '@/modules/5s/utils'
|
||||
import { ref, toValue } from 'vue'
|
||||
|
||||
const userInput = ref('')
|
||||
const mode = ref<_5S | null>(null)
|
||||
const boardGameStore = useBoardGameStore()
|
||||
const duration = ref<string | null>(null)
|
||||
|
||||
setInterval(() => {
|
||||
duration.value = boardGameStore.start
|
||||
duration.value = boardGameStore.meta.start
|
||||
? toDuration(
|
||||
new Date(boardGameStore.start),
|
||||
boardGameStore.end ? new Date(boardGameStore.end) : new Date()
|
||||
new Date(boardGameStore.meta.start),
|
||||
boardGameStore.meta.end ? new Date(boardGameStore.meta.end) : new Date()
|
||||
)
|
||||
: null
|
||||
}, 1000)
|
||||
|
||||
const submit = () => {
|
||||
const lastInput = toValue(userInput)
|
||||
|
||||
boardGameStore.craftWithTool(lastInput)
|
||||
|
||||
userInput.value = ''
|
||||
|
||||
if (!lastInput.startsWith('/')) {
|
||||
boardGameStore.craftWithTool(lastInput)
|
||||
return
|
||||
}
|
||||
|
||||
if (lastInput === '/') {
|
||||
mode.value = null
|
||||
return
|
||||
}
|
||||
|
||||
const command = lastInput.split('/').pop()
|
||||
|
||||
if (!command) {
|
||||
return
|
||||
}
|
||||
|
||||
if (is5S(command)) {
|
||||
boardGameStore.activateS(command)
|
||||
return
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="board-game-workshop prose">
|
||||
<aside>
|
||||
<h2>Tools</h2>
|
||||
<div class="overflow-x-auto">
|
||||
<table class="table table-zebra">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Tool</th>
|
||||
<th>Alias</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="tool in boardGameStore.tools" :key="tool.alias">
|
||||
<td>{{ tool.name }}</td>
|
||||
<td>{{ tool.alias }}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
<div class="main">
|
||||
<h2>Workshop</h2>
|
||||
<div class="board-game-workshop">
|
||||
<BoardGameToolbox class="aside" />
|
||||
<div class="main prose">
|
||||
<h2 class="title">Workshop</h2>
|
||||
<button
|
||||
class="btn"
|
||||
v-if="!boardGameStore.currentBoardGame"
|
||||
@@ -135,26 +137,25 @@ const submit = () => {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<aside
|
||||
class="performance"
|
||||
v-if="duration !== null || boardGameStore.perfs.length > 0"
|
||||
v-if="duration !== null || boardGameStore.meta.perfs.length > 0"
|
||||
>
|
||||
<h2>Performance</h2>
|
||||
|
||||
<p>{{ duration }}</p>
|
||||
|
||||
<template v-if="boardGameStore.perfs.length > 0">
|
||||
<template v-if="boardGameStore.meta.perfs.length > 0">
|
||||
<h3>Last performances</h3>
|
||||
|
||||
<ul>
|
||||
<li v-for="perf in boardGameStore.perfs">
|
||||
<li v-for="perf in boardGameStore.meta.perfs">
|
||||
{{ toDuration(new Date(perf[0]), new Date(perf[1])) }}
|
||||
</li>
|
||||
</ul>
|
||||
</template>
|
||||
</aside>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@@ -187,12 +188,13 @@ form {
|
||||
color: green;
|
||||
}
|
||||
|
||||
aside {
|
||||
aside,
|
||||
.aside {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.main {
|
||||
flex: 2;
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 1rem;
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { _5S } from '@/modules/5s/types/5s'
|
||||
import { boardGames } from '@/modules/5s/types/board-games'
|
||||
import { tools } from '@/modules/5s/types/tools'
|
||||
import { BoardGame, Part, Task, Tool } from '@/modules/5s/types/workshop'
|
||||
@@ -12,10 +13,20 @@ type State = {
|
||||
currentPartIndex: number | null
|
||||
currentTaskIndex: number | null
|
||||
usedTools: string[]
|
||||
sUsed: _5S[]
|
||||
meta: {
|
||||
start: string | null
|
||||
end: string | null
|
||||
perfs: Array<[string, string]>
|
||||
}
|
||||
}
|
||||
|
||||
const firstDemands = [
|
||||
boardGames[0]
|
||||
// boardGames[0],
|
||||
// boardGames[0],
|
||||
// boardGames[0]
|
||||
]
|
||||
|
||||
export const useBoardGameStore = defineStore('board-game', {
|
||||
state: (): State => ({
|
||||
@@ -25,23 +36,25 @@ export const useBoardGameStore = defineStore('board-game', {
|
||||
currentPartIndex: null,
|
||||
currentTaskIndex: null,
|
||||
usedTools: [],
|
||||
sUsed: [],
|
||||
meta: {
|
||||
start: null,
|
||||
end: null,
|
||||
perfs: []
|
||||
}
|
||||
}),
|
||||
actions: {
|
||||
initGame() {
|
||||
// this.boardGames = [boardGames[0], boardGames[1]]
|
||||
this.tools = tools.map((t) => ({
|
||||
...t,
|
||||
alias: randomAlias()
|
||||
}))
|
||||
this.boardGames = [boardGames[0]]
|
||||
this.boardGames = firstDemands
|
||||
this.currentBoardGameIndex = 0
|
||||
this.currentPartIndex = 0
|
||||
this.currentTaskIndex = 0
|
||||
this.start = new Date().toISOString()
|
||||
this.end = null
|
||||
this.meta.start = new Date().toISOString()
|
||||
this.meta.end = null
|
||||
},
|
||||
craftWithTool(alias: string) {
|
||||
if (!this.currentTask) {
|
||||
@@ -67,7 +80,7 @@ export const useBoardGameStore = defineStore('board-game', {
|
||||
},
|
||||
increment() {
|
||||
if (
|
||||
!this.start ||
|
||||
!this.meta.start ||
|
||||
!this.currentTask ||
|
||||
!this.currentPart ||
|
||||
!this.currentBoardGame ||
|
||||
@@ -99,11 +112,14 @@ export const useBoardGameStore = defineStore('board-game', {
|
||||
}
|
||||
|
||||
// All board games complete
|
||||
this.end = new Date().toISOString()
|
||||
this.perfs = [...this.perfs, [this.start, this.end]]
|
||||
this.meta.end = new Date().toISOString()
|
||||
this.meta.perfs = [...this.meta.perfs, [this.meta.start, this.meta.end]]
|
||||
this.currentBoardGameIndex = null
|
||||
this.currentPartIndex = null
|
||||
this.currentTaskIndex = null
|
||||
},
|
||||
activateS(s: _5S) {
|
||||
this.sUsed = [...this.sUsed, s]
|
||||
}
|
||||
},
|
||||
getters: {
|
||||
@@ -141,11 +157,11 @@ export const useBoardGameStore = defineStore('board-game', {
|
||||
return this.currentPart.tasks[this.currentTaskIndex]
|
||||
},
|
||||
durationToComplete(): string | null {
|
||||
if (!this.start || !this.end) {
|
||||
if (!this.meta.start || !this.meta.end) {
|
||||
return null
|
||||
}
|
||||
|
||||
return toDuration(new Date(this.start), new Date(this.end))
|
||||
return toDuration(new Date(this.meta.start), new Date(this.meta.end))
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
6
src/modules/5s/types/5s.ts
Normal file
6
src/modules/5s/types/5s.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
export type _5S = 'seiri' | 'seiton' | 'seiso' | 'seiketsu' | 'shitsuke'
|
||||
const all5S: _5S[] = ['seiri', 'seiton', 'seiso', 'seiketsu', 'shitsuke']
|
||||
|
||||
export const is5S = (s: string): s is _5S => {
|
||||
return all5S.includes(s as _5S)
|
||||
}
|
||||
@@ -11,10 +11,8 @@ export const randomFloat = (min: number, max: number) => {
|
||||
}
|
||||
|
||||
export const randomAlias = () =>
|
||||
Array.from({ length: 5 }, () =>
|
||||
Math.random() < 0.9
|
||||
? String.fromCharCode(97 + Math.floor(Math.random() * 26))
|
||||
: '-'
|
||||
Array.from({ length: 4 }, () =>
|
||||
String.fromCharCode(97 + Math.floor(Math.random() * 26))
|
||||
).join('')
|
||||
|
||||
export const getMean = (data: number[]) =>
|
||||
|
||||
Reference in New Issue
Block a user