<template> <v-container class="px-0"> <kanban-board :stages="stages" :blocks="tasks" :config="config" :status-prop="statusProp" @update-block="updateBlock"> <div v-for="stage in stages" :slot="stage" :key="stage"> <div class="body-1 py-1" :class="stage === 'Done' ? 'font-weight-regular': 'font-weight-bold'"> <span>{{ stage }}</span> <span style="color: #F29829" class="pl-2" v-if="stage === 'Done' && !tasks.every(task => task.effort_real > 0) && tasks.some(task => task.status === 'Done')">Click <v-icon dark small color="primary">mdi-dots-vertical</v-icon> to enter hours spent</span></div> <v-card v-if="stage === 'Backlog'" flat tile class="text-center" :disabled="finished"> <v-card-text> <add-task :members="members" :labels="getBoard.labels"></add-task> </v-card-text> </v-card> </div> <v-card flat :disabled="finished" :class="{'no-drag':finished}" tile v-for="block in tasks" :slot="block.id" :key="block.id" :loading="loading ? 'accent' : false" :outlined="block.status === 'Done' && !!!block.effort_real" :style="block.status === 'Done' && !!!block.effort_real ? 'border: 2px solid #F29829' : ''" > <v-card-title class="body-2 pt-1 pb-0 pr-1"> <v-row no-gutters> <v-col cols="10"> {{ block.lens_emoji }} {{ block.lens }} | {{ block.purpose_emoji }} {{ block.purpose }} </v-col> <v-col cols="2" class="text-right"> <edit-task :task="block" :members="members"></edit-task> </v-col> </v-row> </v-card-title> <v-card-text class="black--text body-2 pr-1"> {{ block.name }} </v-card-text> <v-card-actions> <v-btn small text v-show="block.comments.length > 0" :ripple="false" plain> {{ block.comments.length }} <v-icon x-small right class="ml-0">mdi-comment-outline</v-icon> </v-btn> <v-spacer></v-spacer> <v-chip small dark :class="block.status === 'Done' || block.status === 'Rejected' ? null : hashColor(block.lens)"> <v-icon small left>mdi-account-circle</v-icon> {{ block.owner }} </v-chip> <v-chip small dark class="mx-1" :class="block.status === 'Done' || block.status === 'Rejected' ? null : hashColor(block.lens)"> <v-icon small left>mdi-account-circle-outline</v-icon> {{ block.reviewer }} </v-chip> <v-chip small dark :class="block.status === 'Done' || block.status === 'Rejected' ? null : hashColor(block.lens)"> <v-icon small left>mdi-timelapse</v-icon> {{ block.effort }} </v-chip> </v-card-actions> </v-card> </kanban-board> </v-container> </template> <script> import EditTask from "@/components/EditTask"; import {mapGetters} from "vuex"; import AddTask from "@/components/AddTask"; export default { name: "Board", components: {EditTask, AddTask}, props: ['tasks', 'team', 'finished'], data() { return { stages: ['Backlog', 'Todo', 'Work-in-Progress', 'Done', 'Rejected'], blocks: [], statusProp: 'status', loading: false, config: { // Don't allow blocks to be moved out of the approved stage // accepts(block, target, source) { // return source.dataset.status !== 'Done' // }, // eslint-disable-next-line no-unused-vars moves(block, source, handle, sibling) { // https://github.com/valor-software/ng2-dragula/issues/784#issuecomment-336483568 return !block.children[0].classList.contains('no-drag') } }, members: Object.values(this.team.members), } }, computed: { ...mapGetters('site', ['getBoard']), }, methods: { updateBlock(id, status) { this.loading = true this.$http.put('/board/task', { id: Number(id), status: status }).then(response => { this.$store.dispatch('site/updateTask', { id: Number(id), name: response.data.name, owner: response.data.owner, reviewer: response.data.reviewer, effort: response.data.effort, effort_real: response.data.effort_real, status: status, lens: response.data.lens, lens_emoji: response.data.lens_emoji, purpose: response.data.purpose, purpose_emoji: response.data.purpose_emoji, description: response.data.description, comments: response.data.comments, }) }).catch(() => { this.$snackbar.showMessage({ content: 'Something went wrong, please try again!', color: 'warning' }) }).finally(() => this.loading = false) }, hashColor(lens) { switch (lens) { case 'Viability': return 'error' case 'Feasibility': return 'info' case 'Desirability': return 'primary' default: return 'secondary' } } }, } </script> <style lang="scss"> @import '../assets/kanban.scss'; </style>