Created
July 17, 2019 21:42
-
-
Save leoli-dev/e5c9fdd741fc6c261c8d1faa54e00d3f to your computer and use it in GitHub Desktop.
Standup Meeting Speech Organisation System (beta)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<div class="container"> | |
<div class="row"> | |
<div class="col align-self-center"> | |
<h1 class="text-center">Standup Meeting Speech Organisation System</h1> | |
</div> | |
</div> | |
<div class="row"> | |
<div class="col align-self-center"> | |
<div id="app"> | |
<step-by-step /> | |
</div> | |
</div> | |
</div> | |
</div> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const members = [ | |
'Abby', | |
'Belle', | |
'Emmy', | |
'Frederic', | |
'Kate', | |
'Lily', | |
'Martine', | |
'Maggie', | |
'John', | |
'Tom', | |
'Rob', | |
'Will', | |
'Max', | |
'Leo', | |
] | |
const helper = { | |
addElementToArray: (arr, element) => { | |
if (arr.includes(element)) { | |
return | |
} | |
arr.push(element) | |
}, | |
removeElementFromArray: (arr, element) => { | |
if (!arr.includes(element)) { | |
return | |
} | |
const index = arr.indexOf(element) | |
if (index === -1) { | |
return | |
} | |
arr.splice(index, 1) | |
}, | |
shuffleArray: arr => arr.sort(() => Math.random() - 0.5), | |
} | |
Vue.component('report-order', { | |
data() { | |
return { | |
reportedMembers: [], | |
currentIndex: 0, | |
} | |
}, | |
props: { | |
members: { | |
type: Array, | |
default: () => [] | |
}, | |
}, | |
methods: { | |
next() { | |
this.currentIndex ++ | |
if (this.currentIndex === this.members.length) { | |
alert('Everyone have reported, well done!') | |
} | |
} | |
}, | |
template: ` | |
<div class="report-order row"> | |
<h3 class="text-center">Step 3: It's time to report!</h3> | |
<div class="col-12 text-center"> | |
<ul> | |
<li v-for="(member, index) in members" :key="index"> | |
<button type="button" class="btn" | |
:class="{ 'btn-light': index < currentIndex, 'btn-success': index === currentIndex, 'btn-secondary': index > currentIndex }" | |
> | |
{{ member }} | |
</button> | |
</li> | |
</ul> | |
</div> | |
<div class="col-12 text-center"> | |
<button type="button" class="btn btn-primary" | |
@click="next" v-if="currentIndex <= members.length - 1" | |
> | |
Next One >> | |
</button> | |
</div> | |
</div> | |
`, | |
}) | |
Vue.component('arrival-order-ol-member', { | |
props: { | |
member: { | |
type: String, | |
default: false, | |
}, | |
}, | |
methods: { | |
removeFromOrderedList() { | |
this.$emit('remove-from-ordered-list', this.member) | |
} | |
}, | |
template: ` | |
<button type="button" class="btn btn-success" @click="removeFromOrderedList"> | |
{{ member }} | |
</button> | |
`, | |
}) | |
Vue.component('arrival-order-ul-member', { | |
props: { | |
member: { | |
type: String, | |
default: false, | |
}, | |
}, | |
methods: { | |
addToOrderedList() { | |
this.$emit('add-to-ordered-list', this.member) | |
} | |
}, | |
template: ` | |
<button type="button" class="btn btn-secondary" @click="addToOrderedList"> | |
{{ member }} | |
</button> | |
`, | |
}) | |
Vue.component('arrival-order', { | |
data() { | |
return { | |
orderedMembers: [], | |
} | |
}, | |
props: { | |
members: { | |
type: Array, | |
default: () => [] | |
}, | |
}, | |
methods: { | |
addMemberToOrderedList(member) { | |
helper.addElementToArray(this.orderedMembers, member) | |
helper.removeElementFromArray(this.members, member) | |
}, | |
removeMemberFromOrderedList(member) { | |
helper.addElementToArray(this.members, member) | |
helper.removeElementFromArray(this.orderedMembers, member) | |
}, | |
goToNextStep() { | |
if (this.members.length) { | |
alert('You should mark order of arrival for every member in SU!') | |
return | |
} | |
const members = this.orderedMembers.slice(0) | |
this.$emit('step-two-done', members.reverse()) | |
}, | |
randomOrder() { | |
if (this.members.length) { | |
for (const member of this.members) { | |
helper.addElementToArray(this.orderedMembers, member) | |
} | |
this.members = [] | |
} | |
this.orderedMembers = helper.shuffleArray(this.orderedMembers) | |
} | |
}, | |
template: ` | |
<div class="arrival-order row"> | |
<div class="col-12"> | |
<h3 class="text-center">Step 2: Mark Member Arrival Order</h3> | |
</div> | |
<div class="col-5"> | |
<ul> | |
<li v-for="(member, index) in members" :key="index"> | |
<arrival-order-ul-member | |
:member="member" | |
@add-to-ordered-list="addMemberToOrderedList" | |
/> | |
</li> | |
</ul> | |
</div> | |
<div class="col-5"> | |
<ol> | |
<li v-for="(member, index) in orderedMembers" :key="index"> | |
<arrival-order-ol-member | |
:member="member" | |
@remove-from-ordered-list="removeMemberFromOrderedList" | |
/> | |
</li> | |
</ol> | |
</div> | |
<div class="col-12 text-center"> | |
<button type="button" class="btn btn-info" @click="randomOrder"> | |
Give me a random order! | |
</button> | |
</div> | |
<div class="col-12 text-center"> | |
<button type="button" class="btn btn-primary" @click="goToNextStep"> | |
Next Step >> | |
</button> | |
</div> | |
</div> | |
`, | |
}) | |
Vue.component('waiting-list-member', { | |
props: { | |
member: { | |
type: String, | |
default: false, | |
}, | |
checked: { | |
type: Boolean, | |
default: false, | |
}, | |
}, | |
methods: { | |
toggle() { | |
if (!this.checked) { | |
this.$emit('member-selected', this.member) | |
} else { | |
this.$emit('member-deselected', this.member) | |
} | |
} | |
}, | |
template: ` | |
<div class="btn-group-toggle" data-toggle="buttons"> | |
<label class="btn" :class="{ 'btn-secondary': !checked, 'btn-success': checked }"> | |
<input type="checkbox" autocomplete="off" @click="toggle"> {{ member }} | |
</label> | |
</div> | |
`, | |
}) | |
Vue.component('waiting-list', { | |
data() { | |
return { | |
waitingList: [], | |
} | |
}, | |
props: { | |
members: { | |
type: Array, | |
default: () => [], | |
}, | |
}, | |
methods: { | |
memberSelected(member) { | |
helper.addElementToArray(this.waitingList, member) | |
}, | |
memberDeselected(member) { | |
helper.removeElementFromArray(this.waitingList, member) | |
}, | |
goToNextStep() { | |
if (!this.waitingList.length) { | |
alert('You must choose at least one member!') | |
return | |
} | |
this.$emit('step-one-done', this.waitingList) | |
}, | |
selectAllMembers() { | |
this.waitingList = this.members.slice(0) | |
}, | |
}, | |
template: ` | |
<div class="waiting-list"> | |
<h3 class="text-center">Step 1: Choose the members for SU</h3> | |
<ul> | |
<li v-for="(member, index) in members" :key="index"> | |
<waiting-list-member | |
:member="member" | |
:checked="waitingList.includes(member)" | |
@member-selected="memberSelected" | |
@member-deselected="memberDeselected" | |
/> | |
</li> | |
</ul> | |
<div class="text-center"> | |
<button type="button" class="btn btn-info" @click="selectAllMembers"> | |
All Members in! | |
</button> | |
</div> | |
<div class="text-center"> | |
<button type="button" class="btn btn-primary" @click="goToNextStep"> | |
Next Step >> | |
</button> | |
</div> | |
</div> | |
`, | |
}) | |
Vue.component('step-by-step', { | |
data() { | |
return { | |
step: 1, | |
members, | |
waitingList: [], | |
orderedMembers: [], | |
} | |
}, | |
methods: { | |
stepOneDone(waitingList) { | |
this.waitingList = waitingList | |
this.step = 2 | |
}, | |
stepTwoDone(orderedMembers) { | |
console.log({orderedMembers}) | |
this.orderedMembers = orderedMembers | |
this.step = 3 | |
} | |
}, | |
template: ` | |
<waiting-list | |
v-if="step === 1" | |
:members="members" | |
@step-one-done="stepOneDone" | |
/> | |
<arrival-order | |
v-else-if="step === 2" | |
:members="waitingList" | |
@step-two-done="stepTwoDone" | |
/> | |
<report-order | |
v-else-if="step === 3" | |
:members="orderedMembers" | |
/> | |
`, | |
}) | |
const app = new Vue({ el: '#app' }) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.10/vue.min.js"></script> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
button[type="button"] { | |
margin-right: 20px; | |
margin-bottom: 5px; | |
} | |
.waiting-list > ul, | |
.report-order ul { | |
list-style: none; | |
} | |
.waiting-list li { | |
display: inline-block; | |
margin: 20px 20px; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.1.3/css/bootstrap.min.css" rel="stylesheet" /> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment