discord testers bug report formatter
<main id='app'>
<textarea v-model='description' placeholder='Describe your bug...'></textarea>
<textarea v-model='expected' id='expected' placeholder='Expected results...'></textarea>
<textarea v-model='actual' id='actual' placeholder='Actual results...'></textarea>
<textarea v-model='settings' id='settings' placeholder='Additional system settings...'></textarea>
<div class='steps'>
<div class='step' v-for='(step, index) of steps'>
<input type='text' placeholder='Step...' v-model='steps[index]' :value='step'>
<button @click='removeStep(index)' type='button' class='remove'>
<i class='fa fa-trash-o'></i>
</button>
</div>
<button @click='addStep' type='button'>Add step</button>
</div>
<picker @pick='onVersionChange' :choices='discordVersions'></picker>
<picker @pick='onPlatformChange' :choices='appPlatforms'></picker>
<picker @pick='onBitnessChange' :choices='bitnesses'></picker>
<pre class='result'>!submit {{ description }} | Steps to Reproduce: {{ stepsText }}Expected Result: {{ expected }} Actual Result: {{ actual }} System Settings: {{ platform }} ({{ bitness }}), {{ version }} {{ settings }}</pre>
</main>
const systems = [
{ name: 'Windows 10' },
{ name: 'Linux' },
{ name: 'MacOS' },
]
Vue.component('picker', {
template: `<div class='chooser'>
<div class='choice' @click='pick(index)' v-for='(choice, index) of choices' :class='{ active: index == chosen }'>
{{ choice }}
</div>
</div>`,
props: ['choices'],
methods: {
pick (index) {
this.chosen = index
this.$emit('pick', index)
}
},
data () {
return {
chosen: null,
}
}
})
new Vue({
data: {
description: '',
expected: '',
actual: '',
settings: '',
steps: ['', ''],
// picker values
version: '...',
platform: '...',
bitness: '...',
// picker choices
discordVersions: ['Discord Canary', 'Discord PTB', 'Discord Stable'],
appPlatforms: ['Windows', 'macOS', 'Linux', 'Other'],
bitnesses: ['64 bit', '32 bit']
},
methods: {
addStep () {
this.steps.push('')
},
removeStep (index) {
this.steps.splice(index, 1)
},
onVersionChange (index) {
this.version = this.discordVersions[index]
},
onPlatformChange (index) {
this.platform = this.appPlatforms[index]
},
onBitnessChange (index) {
this.bitness = this.bitnesses[index]
},
},
computed: {
stepsText () {
let buffer = ''
for (let step of this.steps) {
buffer += `- ${step} `
}
return buffer
}
},
el: '#app',
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.2.4/vue.min.js"></script>
$dark: #2C2F33
$blurple: #7289DA
body, html
padding: 1.5rem
background: $dark
color: #fff
width: 100%
height: 100%
#actual
margin: 0 0 0.5rem 0
*
box-sizing: border-box
pre
background: rgba(0, 0, 0, 0.1)
padding: 5px
color: #fff
border-radius: 0.15rem
width: 100%
overflow: auto
button
&:focus, &:active
outline: 0
&:hover
background: rgba(0, 0, 0, 0.25)
&:active
background: rgba(0, 0, 0, 0.5)
cursor: pointer
padding: 5px 10px
font-size: 0.9em
background: rgba(0, 0, 0, 0.1)
border: 0
color: #fff
border-radius: 0.15rem
.steps
margin: 0.5rem 0
.step
display: flex
margin-bottom: 0.5rem
.remove
font-size: 1.25em
width: 3rem
margin-left: 0.5rem
background: #ff2e2e
&:hover
background: darken(#ff2e2e, 5%)
&:active
background: darken(#ff2e2e, 10%)
#expected
margin: 0.5rem 0 0.5rem
.chooser
display: flex
.choice
border-radius: 0.15rem
padding: 0.5rem 1rem
margin: 0.5rem
background: rgba(0, 0, 0, 0.2)
cursor: pointer
transition: box-shadow 250ms
&:hover
box-shadow: 0 0 0 0.2rem darken($blurple, 10%)
&.active
box-shadow: 0 0 0 0.2rem $blurple
input[type=text], textarea
display: block
transition: border-color 250ms
&:focus, &:active
border-color: $blurple !important
outline: none
&:hover
border-color: #000
color: #fff
padding: 10px
border-radius: 0.15rem
border: solid 1px rgba(0, 0, 0, 0.298039)
background: rgba(0, 0, 0, .1)
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet" />