move to feature module and init board
This commit is contained in:
92
src/modules/feature/FeatureStep.vue
Normal file
92
src/modules/feature/FeatureStep.vue
Normal file
@@ -0,0 +1,92 @@
|
||||
<script setup lang="ts">
|
||||
import { FeatureStep } from '@/modules/feature/feature-steps'
|
||||
import { computed } from 'vue'
|
||||
|
||||
const props = defineProps<{
|
||||
step: FeatureStep
|
||||
}>()
|
||||
const remainingBlueBuckets = computed(() =>
|
||||
Math.max(0, props.step.blueBuckets - props.step.featuresDone.length)
|
||||
)
|
||||
const hasFeaturesInProgress = computed(
|
||||
() => props.step.featuresInProgress.length > 0
|
||||
)
|
||||
const hasFeaturesDone = computed(() => props.step.featuresInProgress.length > 0)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<li class="feature-step">
|
||||
<header>{{ step.title }}</header>
|
||||
<section class="doing">
|
||||
<h5>📝⌛</h5>
|
||||
<ul v-if="hasFeaturesInProgress">
|
||||
<li
|
||||
v-for="feature in step.featuresInProgress"
|
||||
:key="feature.name"
|
||||
class="bin"
|
||||
>
|
||||
{{ feature.name }}
|
||||
</li>
|
||||
</ul>
|
||||
</section>
|
||||
<section class="done">
|
||||
<h5>📝✅</h5>
|
||||
<ul v-if="hasFeaturesDone">
|
||||
<li
|
||||
v-for="feature in step.featuresDone"
|
||||
:key="feature.name"
|
||||
class="bin"
|
||||
>
|
||||
{{ feature.name }}
|
||||
</li>
|
||||
</ul>
|
||||
<div
|
||||
v-for="blueBucket in remainingBlueBuckets"
|
||||
:key="blueBucket"
|
||||
class="bin blue-bin"
|
||||
>
|
||||
Blue bucket
|
||||
</div>
|
||||
</section>
|
||||
</li>
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.feature-step {
|
||||
header {
|
||||
padding: 0.5rem;
|
||||
border: solid 2px var(--background-color);
|
||||
margin-top: 1rem;
|
||||
}
|
||||
|
||||
section {
|
||||
margin: 1rem 0;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
h5 {
|
||||
margin-bottom: 0;
|
||||
background-color: var(--background-color);
|
||||
padding: 0.35rem;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.bin {
|
||||
margin-top: 1rem;
|
||||
border: 3px solid var(--background-color);
|
||||
height: 60px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
font-size: 12pt;
|
||||
padding: 0 0.5rem;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.blue-bin {
|
||||
background-color: var(--background-color);
|
||||
color: white;
|
||||
font-size: 18pt;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
51
src/modules/feature/FeatureSteps.vue
Normal file
51
src/modules/feature/FeatureSteps.vue
Normal file
@@ -0,0 +1,51 @@
|
||||
<script setup lang="ts">
|
||||
import FeatureStep from '@/modules/feature/FeatureStep.vue'
|
||||
import { createFeatureBoard } from '@/modules/feature/feature-board'
|
||||
import { featureSteps as initialFeatureSteps } from '@/modules/feature/feature-steps'
|
||||
import { ref } from 'vue'
|
||||
|
||||
const featureBoard = createFeatureBoard()
|
||||
|
||||
const featureSteps = ref(featureBoard.initBoard(initialFeatureSteps))
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<ul class="features-steps">
|
||||
<FeatureStep v-for="step in featureSteps" :key="step.title" :step="step" />
|
||||
</ul>
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.features-steps {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
gap: 1rem;
|
||||
flex-wrap: wrap;
|
||||
align-items: flex-start;
|
||||
margin: 0 1rem;
|
||||
border: 3px solid var(--background-color);
|
||||
|
||||
li:first-child {
|
||||
margin-left: 1rem;
|
||||
}
|
||||
|
||||
li:last-child {
|
||||
margin-right: 1rem;
|
||||
}
|
||||
|
||||
li:not(:last-child) {
|
||||
padding-right: 1rem;
|
||||
border-right: 3px solid var(--background-color);
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
li {
|
||||
flex: 1;
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
color: var(--background-color);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
29
src/modules/feature/feature-board.ts
Normal file
29
src/modules/feature/feature-board.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
import { FeatureStatus, FeatureStep } from '@/modules/feature/feature-steps'
|
||||
import { features } from '@/modules/feature/feature.fixture'
|
||||
import { pickRandomElement, popNElement, shuffleArray } from '@/utils'
|
||||
|
||||
export const createFeatureBoard = () => {
|
||||
const boardFeatures = shuffleArray(features)
|
||||
|
||||
const initBoard = (featureSteps: FeatureStep[]): FeatureStep[] => {
|
||||
const initialFeatures = popNElement(boardFeatures, 10)
|
||||
|
||||
initialFeatures.forEach((feature) => {
|
||||
const step = pickRandomElement(featureSteps)
|
||||
const doingOrDone: FeatureStatus = pickRandomElement(['doing', 'done'])
|
||||
|
||||
switch (doingOrDone) {
|
||||
case 'doing':
|
||||
step.featuresInProgress.push(feature)
|
||||
break
|
||||
case 'done':
|
||||
step.featuresDone.push(feature)
|
||||
break
|
||||
}
|
||||
})
|
||||
|
||||
return featureSteps
|
||||
}
|
||||
|
||||
return { initBoard }
|
||||
}
|
||||
53
src/modules/feature/feature-steps.ts
Normal file
53
src/modules/feature/feature-steps.ts
Normal file
@@ -0,0 +1,53 @@
|
||||
export type FeatureStatus = 'doing' | 'done'
|
||||
|
||||
export type FeatureStep = {
|
||||
title: string
|
||||
featuresInProgress: Feature[]
|
||||
featuresDone: Feature[]
|
||||
blueBuckets: number
|
||||
}
|
||||
|
||||
export const featureSteps: FeatureStep[] = [
|
||||
{
|
||||
title: 'Pitch',
|
||||
featuresInProgress: [],
|
||||
featuresDone: [],
|
||||
blueBuckets: 2
|
||||
},
|
||||
{
|
||||
title: 'Design',
|
||||
featuresInProgress: [],
|
||||
featuresDone: [],
|
||||
blueBuckets: 1
|
||||
},
|
||||
{
|
||||
title: 'Investigation',
|
||||
featuresInProgress: [],
|
||||
featuresDone: [],
|
||||
blueBuckets: 1
|
||||
},
|
||||
{
|
||||
title: 'Product design',
|
||||
featuresInProgress: [],
|
||||
featuresDone: [],
|
||||
blueBuckets: 2
|
||||
},
|
||||
{
|
||||
title: 'Development',
|
||||
featuresInProgress: [],
|
||||
featuresDone: [],
|
||||
blueBuckets: 2
|
||||
},
|
||||
{
|
||||
title: 'UAT',
|
||||
featuresInProgress: [],
|
||||
featuresDone: [],
|
||||
blueBuckets: 3
|
||||
},
|
||||
{
|
||||
title: 'Release',
|
||||
featuresInProgress: [],
|
||||
featuresDone: [],
|
||||
blueBuckets: 0
|
||||
}
|
||||
]
|
||||
10
src/modules/feature/feature.fixture.test.ts
Normal file
10
src/modules/feature/feature.fixture.test.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
import { faker } from '@faker-js/faker'
|
||||
import { describe, it } from 'vitest'
|
||||
|
||||
describe('feature fixture', () => {
|
||||
it('creates lots of animals', () => {
|
||||
for (let i = 0; i < 200; i++) {
|
||||
console.log(`"${faker.animal.dog()}", `)
|
||||
}
|
||||
})
|
||||
})
|
||||
207
src/modules/feature/feature.fixture.ts
Normal file
207
src/modules/feature/feature.fixture.ts
Normal file
@@ -0,0 +1,207 @@
|
||||
const featureNames = [
|
||||
'Dachshund',
|
||||
'Jagdterrier',
|
||||
'Chesapeake Bay Retriever',
|
||||
'Cretan Hound',
|
||||
'Bulldog',
|
||||
'Lapponian Herder',
|
||||
'Vizsla',
|
||||
'Norwegian Elkhound',
|
||||
'Rat Terrier',
|
||||
'Kangal Shepherd Dog',
|
||||
'English Foxhound',
|
||||
'Kanni',
|
||||
'Finnish Spitz',
|
||||
'Bloodhound',
|
||||
'Siberian Husky',
|
||||
'Paisley Terrier',
|
||||
'Cairn Terrier',
|
||||
'Chortai',
|
||||
'Bucovina Shepherd Dog',
|
||||
'German Longhaired Pointer',
|
||||
'Portuguese Water Dog',
|
||||
'Aidi',
|
||||
'Dunker',
|
||||
'Slovenský Kopov',
|
||||
'Kokoni',
|
||||
'Pembroke Welsh Corgi',
|
||||
'English Mastiff',
|
||||
'Papillon',
|
||||
'Blue Picardy Spaniel',
|
||||
'Cursinu',
|
||||
'Coton de Tulear',
|
||||
'Akita',
|
||||
'King Charles Spaniel',
|
||||
'Mudhol Hound',
|
||||
'Serrano Bulldog',
|
||||
'Telomian',
|
||||
'Komondor',
|
||||
'Chinese Crested Dog',
|
||||
'Banjara Hound',
|
||||
'Jagdterrier',
|
||||
'Australian Cattle Dog',
|
||||
'Afghan Hound',
|
||||
'King Shepherd',
|
||||
'Boykin Spaniel',
|
||||
'Hamiltonstövare',
|
||||
'Bull Arab',
|
||||
'Basque Shepherd Dog',
|
||||
'East Siberian Laika',
|
||||
'Australian Cattle Dog',
|
||||
'German Hound',
|
||||
'Scottish Terrier',
|
||||
'Volpino Italiano',
|
||||
'Sussex Spaniel',
|
||||
'Kanni',
|
||||
'Otterhound',
|
||||
'Kintamani',
|
||||
'Mudi',
|
||||
'Pastore della Lessinia e del Lagorai',
|
||||
'Danish-Swedish Farmdog',
|
||||
'Basset Hound',
|
||||
'McNab dog',
|
||||
'Pungsan Dog',
|
||||
'Bouvier des Flandres',
|
||||
'Westphalian Dachsbracke',
|
||||
'Slovenský Cuvac',
|
||||
'Portuguese Water Dog',
|
||||
'American English Coonhound',
|
||||
'Old Croatian Sighthound',
|
||||
'Affenpinscher',
|
||||
'Karakachan dog',
|
||||
'Hierran Wolfdog',
|
||||
'Samoyed',
|
||||
'Magyar agár',
|
||||
'Sarabi dog',
|
||||
'Cane Corso',
|
||||
"Braque d'Auvergne",
|
||||
'Volpino Italiano',
|
||||
'Newfoundland',
|
||||
'Chow Chow',
|
||||
'East Siberian Laika',
|
||||
'Shih Tzu',
|
||||
'English Springer Spaniel',
|
||||
'Ratonero Bodeguero Andaluz',
|
||||
'Australian Kelpie',
|
||||
'New Zealand Heading Dog',
|
||||
'Burgos Pointer',
|
||||
'German Wirehaired Pointer',
|
||||
'Serrano Bulldog',
|
||||
'King Shepherd',
|
||||
'Norwegian Lundehund',
|
||||
'Lagotto Romagnolo',
|
||||
'Basset Bleu de Gascogne',
|
||||
'Vikhan',
|
||||
'Clumber Spaniel',
|
||||
'Field Spaniel',
|
||||
'Greater Swiss Mountain Dog',
|
||||
'Boerboel',
|
||||
'Basenji',
|
||||
'Thai Ridgeback',
|
||||
'Rottweiler',
|
||||
'Slovakian Wirehaired Pointer',
|
||||
'Brittany',
|
||||
'Welsh Sheepdog',
|
||||
'Tosa',
|
||||
'Olde English Bulldogge',
|
||||
'Galgo Español',
|
||||
'Mudi',
|
||||
'Smooth Fox Terrier',
|
||||
'Bedlington Terrier',
|
||||
'Picardy Spaniel',
|
||||
'Chien Français Blanc et Orange',
|
||||
'Kokoni',
|
||||
'Gull Terrier',
|
||||
'Redbone Coonhound',
|
||||
'Rajapalayam',
|
||||
'Perro de Presa Canario',
|
||||
'Austrian Pinscher',
|
||||
'Saluki',
|
||||
'Kintamani',
|
||||
'Galician Shepherd Dog',
|
||||
'Standard Schnauzer',
|
||||
'Cão de Gado Transmontano',
|
||||
'American Staffordshire Terrier',
|
||||
'Wirehaired Pointing Griffon',
|
||||
'Galician Shepherd Dog',
|
||||
'Transylvanian Hound',
|
||||
'Chien Français Blanc et Noir',
|
||||
'Taigan',
|
||||
'Kombai',
|
||||
'Saint Hubert Jura Hound',
|
||||
'Swedish Vallhund',
|
||||
'Dogo Sardesco',
|
||||
'German Shorthaired Pointer',
|
||||
'Pražský Krysařík',
|
||||
'Airedale Terrier',
|
||||
'Chortai',
|
||||
'Bernese Mountain Dog',
|
||||
'Drever',
|
||||
'Estonian Hound',
|
||||
'Dutch Smoushond',
|
||||
'Wire Fox Terrier',
|
||||
'Neapolitan Mastiff',
|
||||
'Bearded Collie',
|
||||
'Telomian',
|
||||
'English Cocker Spaniel',
|
||||
'Airedale Terrier',
|
||||
'Mountain Feist',
|
||||
'Treeing Tennessee Brindle',
|
||||
'Garafian Shepherd',
|
||||
'Grand Griffon Vendéen',
|
||||
'Gull Terrier',
|
||||
'Villano de Las Encartaciones',
|
||||
'Russian Spaniel',
|
||||
'Yakutian Laika',
|
||||
'Curly-Coated Retriever',
|
||||
'Rajapalayam',
|
||||
'Sabueso Español',
|
||||
'Hovawart',
|
||||
'Peruvian Inca Orchid',
|
||||
'Pekingese',
|
||||
'Icelandic Sheepdog',
|
||||
'Cairn Terrier',
|
||||
'Glen of Imaal Terrier',
|
||||
'Australian Shepherd',
|
||||
'Dunker',
|
||||
'Briquet Griffon Vendéen',
|
||||
'Scottish Deerhound',
|
||||
'Mudhol Hound',
|
||||
'Danish-Swedish Farmdog',
|
||||
'Australian Terrier',
|
||||
'Chinese Chongqing Dog',
|
||||
'Irish Red and White Setter',
|
||||
'Podenco Valenciano',
|
||||
"Cirneco dell'Etna",
|
||||
'German Shepherd Dog',
|
||||
'Levriero Sardo',
|
||||
'Romanian Mioritic Shepherd Dog',
|
||||
'Finnish Hound',
|
||||
'Segugio Maremmano',
|
||||
'Andalusian Hound',
|
||||
'Swedish White Elkhound',
|
||||
'Tenterfield Terrier',
|
||||
'Wirehaired Pointing Griffon',
|
||||
'Cão Fila de São Miguel',
|
||||
'Italian Greyhound',
|
||||
'Jindo',
|
||||
'Pyrenean Mountain Dog',
|
||||
'Field Spaniel',
|
||||
'Alaskan Klee Kai',
|
||||
'Lupo Italiano',
|
||||
'Silken Windhound',
|
||||
'Cavalier King Charles Spaniel',
|
||||
'Spanish Mastiff',
|
||||
'Sinhala Hound',
|
||||
'Grand Griffon Vendéen',
|
||||
'Shiloh Shepherd',
|
||||
'Sarabi dog',
|
||||
'Cane Corso',
|
||||
'Japanese Spitz',
|
||||
'Dogue de Bordeaux'
|
||||
]
|
||||
|
||||
export const features: Feature[] = featureNames.map((name) => ({
|
||||
name,
|
||||
complexity: Math.floor(Math.random() * 5)
|
||||
}))
|
||||
4
src/modules/feature/feature.ts
Normal file
4
src/modules/feature/feature.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
type Feature = {
|
||||
name: string
|
||||
complexity: number
|
||||
}
|
||||
Reference in New Issue
Block a user