Ever wondered how a Kanban dashboard is created? Let’s explore it a little. This guides expects basic knowledge of the following

Pre requisites

  • VueJS
  • Tailwind CSS

Setting up the environment

Run the following commands to pull the package with yarn / npm

Zsh
yarn add vuedraggable@next

npm i -S vuedraggable@next

For simplicity purposes let’s pull Tailwind through CDN instead of yarn or npm. Paste the following CDN link in your index.html

HTML
<script src="https://cdn.tailwindcss.com"></script>

We are all set to go!

Covering the basics

Let’s get started by looking at a basic example of this package and figuring it out from there. This is an example provided in the docs

Vue
<template>
    <div class="p-4 flex space-x-3">
        <draggable class="space-y-2" v-model="array1" item-key="element" group="tasks">
            <template #item="{ element }">
                <div class="border rounded p-2 w-[250px]">
                    {{ element.text }}
                </div>
            </template>
        </draggable>

        <draggable class="space-y-2" v-model="array2" item-key="element" group="tasks">
            <template #item="{ element }">
                <div class="border rounded p-2 w-[250px]">
                    {{ element.text }}
                </div>
            </template>
        </draggable>
    </div>
</template>

<script>
import draggable from 'vuedraggable'

export default {
    components: {
        draggable,
    },
    data() {
        return {
            array1: [
                {
                    id: 1,
                    text: 'Basic example',
                },
                {
                    id: 2,
                    text: 'Two column example'
                },
                {
                    id: 3,
                    text: 'Kanban board'
                }
            ],
            array2: [
                {
                    id: 4,
                    text: 'Prepare code',
                },
                {
                    id: 5,
                    text: 'Demonstrate prepared code'
                },
            ],
        }
    }
}
</script>

this allows us to move elements in the same row. We can modify our example to allow moving elements from one column to another as well as moving the items in the same row

Vue
<template>
    <div class="p-4 flex space-x-3">
        <draggable class="space-y-2" v-model="array1" item-key="element" group="tasks">
            <template #item="{ element }">
                <div class="border rounded p-2 w-[250px]">
                    {{ element.text }}
                </div>
            </template>
        </draggable>

        <draggable class="space-y-2" v-model="array2" item-key="element" group="tasks">
            <template #item="{ element }">
                <div class="border rounded p-2 w-[250px]">
                    {{ element.text }}
                </div>
            </template>
        </draggable>
    </div>
</template>

Notice the group attribute, it lets us move an item from one array that has same group name to another array with the same group name

Creating Kanban Board

This already has been the crux of this guide. However, let us finally create our beloved Kanban board😉

Create a Pipelines component which will track the individual pipeline

Vue
<script setup>
import draggable from 'vuedraggable'
import Pipeline from './Pipeline.vue';

import { ref } from 'vue'

const cards = ref([
    {
        text: 'Development',
        cards: [
            {
                id: 1,
                text: 'Complete code for blog post'
            },
            {
                id: 2,
                text: 'Complete blog',
            },
            {
                id: 3,
                text: 'Fix not able to drag parent pipeline',
            }
        ],
    },
    {
        text: 'SQA',
        cards: [
            {
                id: 4,
                text: 'Test code'
            },
            {
                id: 5,
                text: 'Prepare bug sheet',
            }
        ],
    }
])
</script>

<template>
    <div class="p-4">
        <div class="flex space-x-4">
            <div class="rounded-md min-h-[600px] w-[250px] max-w-[250px] bg-gray-50" v-for="card in cards"
                :key="card.id">
                <h3 class="p-2 font-semibold">
                    {{ card.text }}
                </h3>
                <!-- adding this in next step -->
                <Pipeline :cards="card.cards" />
            </div>
        </div>
    </div>
</template>

Instead of creating separate arrays like in our previous example, we will create a single array of objects since that is closer to a real world scenario. We will loop through the cards array and pass each pipeline’s cards to a Pipeline component (coming up) which is responsible for dragging and dropping of cards. We also use flexbox for some CSS magic and display pipelines. At this point our board is starting to take some shape 🙂

Next, we will create a Pipeline component

Vue
<script setup>
import draggable from 'vuedraggable'
import { ref, defineProps, onMounted } from 'vue';
const props = defineProps(['cards'])

const cards = ref([])
onMounted(() => cards.value = props.cards)
</script>

<template>
    <draggable class="space-y-2 text-sm h-full" v-model="cards" group="cards" item-key="text">
        <template #item="{ element }">
            <div class="rounded-md shadow-sm mx-2 p-4 bg-white text-gray-500">
                {{ element.text }}
            </div>
        </template>
    </draggable>
</template>

Here the magic happens. Each pipelines takes its own cards and adds them to draggable component. Notice the group attribute. Since each pipeline has the same group name, it means we are able to move cards from one pipeline to another. That’s awesome! 😎