petra-tool / frontend / src / components / TaskForm.vue
TaskForm.vue
Raw
<template>
  <v-form ref="form" v-model="form.valid" lazy-validation>
    <v-row>
      <v-col cols="12" sm="6">
        <div class="text-h5 text--primary mb-3">Owner</div>
        <v-select
          label="Choose a lead for this task..."
          outlined
          :items="form.ownerOptions.filter(member => member.available)"
          v-model="form.selectedOwner"
          item-text="name"
          item-value="name"
          required
          :disabled="disabled"
          :rules="[
                    value => !!value || 'Owner is required.',
                    value => form.selectedReviewer !== value || 'Owner and Reviewer must be different.'
                  ]"
        ></v-select>
      </v-col>
      <v-col cols="12" sm="6">
        <div class="text-h5 text--primary mb-3">Reviewer</div>
        <v-select
          label="Choose a reviewer for this task..."
          outlined
          :items="form.reviewerOptions.filter(member => member.available)"
          v-model="form.selectedReviewer"
          item-text="name"
          item-value="name"
          required
          :disabled="disabled"
          :rules="[
                    value => !!value || 'Reviewer is required.',
                    value => form.selectedOwner !== value || 'Owner and Reviewer must be different.'
                  ]"
        ></v-select>
      </v-col>
    </v-row>

    <v-row no-gutters>
      <v-col cols="12">
        <div class="text-h5 text--primary mb-3">Task Name</div>
        <v-text-field
          label="Insert a title for this task..."
          v-model="form.name"
          outlined
          required
          counter maxlength="120"
          :disabled="disabled"
          :rules="[value => !!value || 'Description is required.']"
        ></v-text-field>
      </v-col>
    </v-row>

    <v-row no-gutters>
      <v-col cols="12">
        <div class="text-h5 text--primary mb-3">Task Description</div>
        <v-textarea
          label="Describe this task in more detail..."
          hint="This is optional, multiple lines possible."
          persistent-hint
          v-model="form.description"
          outlined
          :disabled="disabled"
          rows="3"
        ></v-textarea>
      </v-col>
    </v-row>

    <v-row>
      <v-col cols="12" md="6">
        <div class="text-h5 text--primary mb-3">Lens</div>
        <v-select
          label="Assign a lens to this task..."
          :items="form.lensOptions"
          v-model="form.lensSelected"
          outlined
          :disabled="disabled"
          v-on:change="updatePurpose"
          :rules="[value => !!value || 'Lens is required.']"
        ></v-select>
      </v-col>
      <v-col cols="12" md="6">
        <div class="text-h5 text--primary mb-3">Prototyping Purpose</div>
        <v-select
          label="Assign a purpose to the task..."
          :items="form.purposeOptions"
          v-model="form.purposeSelected"
          outlined
          :disabled="disabled"
          :rules="[value => !!value || 'Purpose is required.']"
        ></v-select>
      </v-col>
    </v-row>

    <v-row no-gutters>
      <v-col cols="12">
        <div class="text-h5 text--primary">Effort</div>
        <div v-if="$store.getters['site/getSettings'].includes('honeypot')"
             class="body-2" :class="honeyPotIst > honeyPot ? 'red--text' : ''">
          Honey Pot: {{honeyPotIst}} / {{honeyPot}}
        </div>
        <div class="mb-3 body-2">
          Assign an effort to this task.
          The following efforts are possible:
          (1) Equivalent to <b>one working hour</b>,
          (3) Equivalent to <b>three working hours</b>,
          and (5) Equivalent to <b>five working hours</b>.
          If a task is bigger than "5" break it down to smaller tasks (e.g., tasks has an effort of 10; break it down to two two tasks with effort 5).
        </div>
        <v-card flat>
          <v-card-text class="pb-0">
            <v-slider
              class="pt-6 mx-1"
              v-model="form.selectedEffort"
              track-color="accent lighten-4"
              color="accent"
              :tick-labels="['low', 'medium', 'high']"
              :min="1"
              :max="5"
              step="2"
              ticks="always"
              tick-size="6"
              thumb-label="always"
              :thumb-size="24"
              :readonly="disabled"
              :rules="[value => !!value || 'Effort is required.']"
            >
            </v-slider>
          </v-card-text>
        </v-card>
      </v-col>
    </v-row>
  </v-form>

</template>

<script>
import sumBy from 'lodash/sumBy'

export default {
  name: "TaskForm",
  props: ['form', 'disabled'],
  methods: {
    updatePurpose() {
      let purposeOptions = []

      // Requirement is actually a label...
      if (typeof this.form.selectedLabel === "undefined" || typeof this.form.selectedLabel.purpose === "undefined" || this.form.selectedLabel === "") {
        this.form.purposeOptions = [{
          text: '๐Ÿงญ Exploration - Generate new knowledge',
          value: 'Explore'
        },{
          text: '๐Ÿ”Ž Evaluation - Verify existing knowledge',
          value: 'Evaluate'
        },{
          text: '๐Ÿ—ฃ๏ธ Communication - Convey new/existing knowledge',
          value: 'Communicate'
        }]
      } else {
        this.form.selectedLabel.purpose.forEach(purpose => {
          if (purpose.name === 'Explore') {
            purposeOptions.push({
              text: '๐Ÿงญ Exploration - Generate new knowledge',
              value: 'Explore'
            })
          }
          if (purpose.name === 'Evaluate') {
            purposeOptions.push({
              text: '๐Ÿ”Ž Evaluation - Verify existing knowledge',
              value: 'Evaluate'
            })
          }
          if (purpose.name === 'Communicate') {
            purposeOptions.push({
              text: '๐Ÿ—ฃ๏ธ Communication - Convey new/existing knowledge',
              value: 'Communicate'
            })
          }
        })
        this.form.purposeOptions = purposeOptions
      }
    },
    updateLens() {
      let lensOptions = []

      // Requirement is actually a label...
      if (typeof this.form.selectedLabel === "undefined" || typeof this.form.selectedLabel.lens === "undefined" || this.form.selectedLabel === "") {
        this.form.lensOptions = [{
          text: '๐Ÿ’ก Desirability - Do people want this product?',
          value: 'Desirability'
        },{
          text: 'โš™๏ธ Feasibility - Can we build this product?',
          value: 'Feasibility'
        },{
          text: '๐Ÿš€ Viability - Should we build this product?',
          value: 'Viability'
        }]
      } else {
        this.form.selectedLabel.lens.forEach(lens => {
          if (lens.name === 'Desirability') {
            lensOptions.push({
              text: '๐Ÿ’ก Desirability - Do people want this product?',
              value: 'Desirability'
            })
          }
          if (lens.name === 'Evaluate') {
            lensOptions.push({
              text: 'โš™๏ธ Feasibility - Can we build this product?',
              value: 'Feasibility'
            })
          }
          if (lens.name === 'Communicate') {
            lensOptions.push({
              text: '๐Ÿš€ Viability - Should we build this product?',
              value: 'Viability'
            })
          }
        })
        this.form.lensOptions = lensOptions
      }
    },
  },
  computed: {
    honeyPot() {
      let members = this.$store.getters['site/getMembers'].filter(member => member.available)
      let hours = sumBy(members, 'hours')
      let sprint = this.$store.getters['site/getTeam'].sprint
      return hours * sprint // members.length * hours / members.length
    },
    honeyPotIst() {
      return sumBy(this.$store.getters['site/getTasks'], 'effort') + this.form.selectedEffort
    }
  },
  mounted() {
    this.updatePurpose()
    this.updateLens()
  }
}
</script>

<style scoped>

</style>