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({38 rpcAddr: import.meta.env.VITE_YORKIE_API_ADDR,39 apiKey: import.meta.env.VITE_YORKIE_API_KEY,40});4142const doc = new yorkie.Document(43 `vuejs-kanban-${new Date().toISOString().substring(0, 10).replace(/-/g, '')}`,44 { enableDevtools: true },45);4647export default {48 data() {49 return {50 lists: [],51 title: '',52 opened: null,53 };54 },55 created() {56 this.fetchDoc();57 },58 beforeUnmount() {59 this.disconnect();60 },61 watch: {62 opened(index) {63 this.$nextTick(function () {64 if (index === 0) {65 // Open add list form66 this.$refs['addListForm'].querySelector('input').focus();67 } else if (index) {68 // Or open add card form69 this.$refs['addCardForm'][index - 1].querySelector('input').focus();70 }71 this.title = '';72 });73 },74 },75 methods: {76 async fetchDoc() {77 await client.activate();78 await client.attach(doc);7980 doc.update((root) => {81 if (!root.lists) {82 root.lists = defaultLists;83 }84 }, 'create default list if not exists');8586 doc.subscribe((event) => {87 this.lists = doc.getRoot().lists;88 });89 await client.sync();9091 this.lists = doc.getRoot().lists;92 },9394 async disconnect() {95 await client.deactivate({ keepalive: true });96 },9798 isOpened(index) {99 return this.opened === index;100 },101102 openForm(index) {103 this.opened = index;104 },105106 closeForm() {107 this.opened = null;108 },109110 addCard(list) {111 if (this.title === '') return;112113 doc.update((root) => {114 root.lists.getElementByID(list.getID()).cards.push({115 title: this.title,116 });117 this.title = '';118 }, `add new card by ${client.getID()}`);119 },120121 deleteCard(list, card) {122 doc.update((root) => {123 root.lists.getElementByID(list.getID()).cards.deleteByID(card.getID());124 }, `delete a card by ${client.getID()}`);125 },126127 addList() {128 if (this.title === '') return;129130 doc.update((root) => {131 root.lists.push({132 title: this.title,133 cards: [],134 });135 this.title = '';136 }, `add new list by ${client.getID()}`);137 },138139 deleteList(list) {140 doc.update((root) => {141 root.lists.deleteByID(list.getID());142 }, `delete a list by ${client.getID()}`);143 },144 },145};146</script>147148<template>149 <div v-cloak class="list" v-for="(list, index) in lists">150 <span class="delete" v-on:click="deleteList(list)">❌</span>151 <div class="title">{{ list.title }}</div>152 <div class="card" v-for="card in list.cards">153 <span class="delete" v-on:click="deleteCard(list, card)">❌</span>154 {{ card.title }}155 </div>156 <div class="add-card" ref="addCardForm">157 <div v-if="isOpened(index + 1)" class="add-form">158 <input159 type="text"160 placeholder="Enter card title"161 v-model="title"162 v-on:keyup.enter="addCard(list)"163 v-on:keyup.esc="closeForm()"164 />165 <div class="buttons">166 <input type="button" value="Add" v-on:click="addCard(list)" />167 <input168 type="button"169 value="Close"170 class="pull-right"171 v-on:click="closeForm()"172 />173 </div>174 </div>175 <div v-else class="add-card-opener" v-on:click="openForm(index + 1)">176 Add another card177 </div>178 </div>179 </div>180 <div class="add-list" ref="addListForm">181 <div v-if="isOpened(0)" class="add-form">182 <input183 type="text"184 placeholder="Enter list title"185 v-model="title"186 v-on:keyup.enter="addList()"187 v-on:keyup.esc="closeForm()"188 />189 <div class="buttons">190 <input type="button" value="Add" v-on:click="addList()" />191 <input192 type="button"193 value="Close"194 class="pull-right"195 v-on:click="closeForm()"196 />197 </div>198 </div>199 <div v-else class="add-list-opener" v-on:click="openForm(0)">200 Add another list201 </div>202 </div>203</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