# KanBan
Below is a simple example which you can use vuuri
to build a kan ban board, leveraging the group-id
and group-ids
attributes.
# Example
# Code
<template>
<div id="code-demo-app">
<div class="columns">
<div class="column">
<div>
<h2>TO DO</h2>
</div>
<div>
<vuuri
v-model="todoItems"
item-key="id"
:get-item-height="getItemHeight"
drag-enabled
:group-id="1"
>
<template #item="{ item }">
<div class="demo-item" :style="{ border: `2px ${item.color} solid` }">
<div class="grid-card-handle"></div>
</div>
</template>
</vuuri>
</div>
</div>
<div class="column">
<div>
<h2>DONE</h2>
</div>
<div>
<vuuri
v-model="doneItems"
item-key="id"
:get-item-height="getItemHeight"
drag-enabled
:group-ids="[1, 'deletable']"
>
<template #item="{ item }">
<div class="demo-item" :style="{ border: `2px ${item.color} solid` }">
<div class="grid-card-handle"></div>
</div>
</template>
</vuuri>
</div>
</div>
<div class="column">
<div>
<h2>BIN</h2>
<h6>Only items from 'Done' can be dragged here</h6>
</div>
<div>
<vuuri
v-model="binItems"
item-key="id"
:get-item-height="getItemHeight"
drag-enabled
group-id="deletable"
>
<template #item="{ item }">
<div class="demo-item" :style="{ border: `2px ${item.color} solid` }">
<div class="grid-card-handle"></div>
</div>
</template>
</vuuri>
</div>
</div>
</div>
</div>
</template>
<script>
import vuuri from "vuuri";
export default {
name: "KanBanDemo",
components: {
vuuri,
},
data() {
return {
count: 0,
todoItems: [],
doneItems: [],
binItems: []
};
},
methods: {
onDeleteClicked(item) {
const index = this.todoItems.findIndex((value) => value.id === item.id);
this.todoItems.splice(index, 1);
},
onAddClicked() {
this._buildItems();
},
onDeleteMoreClicked() {
const numberOfTimesToDelete = Math.max(
1,
Math.floor(Math.random() * this.todoItems.length)
);
console.log("numberOfTimesToDelete: ", numberOfTimesToDelete);
for (let i = 0; i < numberOfTimesToDelete; i++) {
const index = Math.floor(Math.random() * this.todoItems.length);
if (index < 0) {
return;
}
console.log("index", index, this.todoItems.length);
this.todoItems.splice(index, 1);
}
},
getItemHeight(item) {
return `${item.height}px`;
},
getSize() {
const number = Math.random();
if (number < 0.333) {
return 100;
}
if (number < 0.666) {
return 150;
}
return 200;
},
_buildItems(numberOfTimes = 4) {
const numberOfItems = Math.max(
1,
Math.floor(Math.random() * numberOfTimes)
);
for (let i = 0; i < numberOfItems; i++) {
this.todoItems.push(this._buildItem());
}
},
_addItems() {
if (this.count > 10) {
return;
}
setTimeout(() => {
this.count++;
this._buildItems(1);
this._addItems();
}, 150);
},
_buildItem() {
return {
id: Math.random(),
name: makeid(10),
color: this._getColor(),
width: this.getSize(),
height: this.getSize(),
};
},
_getColor() {
const number = Math.random();
if (number < 0.333) {
return "#aaffdc";
}
if (number < 0.666) {
return "#ff69ea";
}
return "rgb(139, 152, 255)";
},
},
mounted() {
this._addItems();
},
};
function makeid(length) {
var result = "";
var characters =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
var charactersLength = characters.length;
for (var i = 0; i < length; i++) {
result += characters.charAt(Math.floor(Math.random() * charactersLength));
}
return result;
}
</script>
<style scoped lang="scss">
#code-demo-app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin: 10px;
.demo-item {
position: relative;
height: 100%;
width: 100%;
border-radius: 15px;
cursor: move;
.grid-card-handle {
height: 100%;
}
.delete-btn {
cursor: pointer;
position: absolute;
top: 10px;
right: 10px;
border-radius: 10px;
height: 30px !important;
width: 30px !important;
padding: 0;
transition: opacity 0.3s ease, transform 0.3s ease;
opacity: 0;
transform: scale(0.5);
}
&:hover {
.delete-btn {
opacity: 1;
transform: scale(1);
}
}
}
&::v-deep {
.muuri-grid {
min-height: 100px;
border: forestgreen 1px solid;
}
.muuri-item {
margin: 5px 0;
width: 100% !important;
}
}
}
</style>