Kanban Board
Kanban Board is a tool for managing tasks and workflow. It is a visual way to manage tasks and workflow.
App.vue
1<script>2import yorkie from 'yorkie-js-sdk';34const defaultLists = [5 {6 title: 'Todo',7 cards: [8 {9 title: 'Pruning document',10 },11 {12 title: 'Clean up codes'13 }14 ]15 },16 {17 title: 'Doing',18 cards: [19 {20 title: 'Array operations',21 }22 ]23 },24 {25 title: 'Done',26 cards: [27 {28 title: 'Create a sample page',29 },30 {31 title: 'Launch demo site'32 }33 ]34 },35];3637const client = new yorkie.Client(import.meta.env.VITE_YORKIE_API_ADDR, {38 apiKey: import.meta.env.VITE_YORKIE_API_KEY,39});40const doc = new yorkie.Document(41 `vuejs-kanban-${(new Date()).toISOString().substring(0, 10).replace(/-/g, '')}`42);4344export default {45 data() {46 return {47 lists: [],48 title: '',49 opened: null,50 };51 },52 created() {53 this.fetchDoc();54 },55 watch: {56 opened(index) {57 this.$nextTick(function () {58 if (index === 0) {59 // Open add list form60 this.$refs['addListForm'].querySelector('input').focus();61 } else {62 // Or open add card form63 this.$refs['addCardForm'][index - 1].querySelector('input').focus();64 }65 });66 },67 },68 methods: {69 async fetchDoc() {70 await client.activate();71 await client.attach(doc);727374 doc.update((root) => {75 if (!root.lists) {76 root.lists = defaultLists;77 }78 }, 'create default list if not exists');7980 doc.subscribe((event) => {81 this.lists = doc.getRoot().lists;82 });83 await client.sync();8485 this.lists = doc.getRoot().lists;86 },8788 isOpened(index) {89 return this.opened === index;90 },9192 openForm(index) {93 this.opened = index;94 },9596 closeForm() {97 this.opened = null;98 },99100 addCard(list) {101 if (this.title === '') return;102103 doc.update((root) => {104 root.lists.getElementByID(list.getID()).cards.push({105 title: this.title,106 });107 this.title = '';108 }, `add new card by ${client.getID()}`);109 },110111 deleteCard(list, card) {112 doc.update((root) => {113 root.lists.getElementByID(list.getID()).cards.deleteByID(card.getID());114 }, `delete a card by ${client.getID()}`);115 },116117 addList() {118 if (this.title === '') return;119120 doc.update((root) => {121 root.lists.push({122 title: this.title,123 cards: [],124 });125 this.title = '';126 }, `add new list by ${client.getID()}`);127 },128129 deleteList(list) {130 doc.update((root) => {131 root.lists.deleteByID(list.getID());132 }, `delete a list by ${client.getID()}`);133 },134 },135}136</script>137138<template>139 <div v-cloak class="list" v-for="(list, index) in lists">140 <span class="delete" v-on:click="deleteList(list)">❌</span>141 <div class="title">{{ list.title }}</div>142 <div class="card" v-for="card in list.cards">143 <span class="delete" v-on:click="deleteCard(list, card)">❌</span>144 {{ card.title }}145 </div>146 <div class="add-card" ref="addCardForm">147 <div v-if="isOpened(index + 1)" class="add-form">148 <input type="text" placeholder="Enter card title" v-model="title" v-on:keyup.enter="addCard(list)"149 v-on:keyup.esc="closeForm()">150 <div class="buttons">151 <input type="button" value="Add" v-on:click="addCard(list)">152 <input type="button" value="Close" class="pull-right" v-on:click="closeForm()">153 </div>154 </div>155 <div v-else class="add-card-opener" v-on:click="openForm(index + 1)">Add another card</div>156 </div>157 </div>158 <div class="add-list" ref="addListForm">159 <div v-if="isOpened(0)" class="add-form">160 <input type="text" placeholder="Enter list title" v-model="title" v-on:keyup.enter="addList()"161 v-on:keyup.esc="closeForm()">162 <div class="buttons">163 <input type="button" value="Add" v-on:click="addList()">164 <input type="button" value="Close" class="pull-right" v-on:click="closeForm()">165 </div>166 </div>167 <div v-else class="add-list-opener" v-on:click="openForm(0)">Add another list</div>168 </div>169</template>
export type KanbanDoc = {lists: Array<List>;};export type List = {title: string;cards: Array<Card>;};export type Card = {title: string;};
- User 1
- User 2
- User 1
- User 2
Event Log