Skip to content

Commit

Permalink
Add basic structure for example view (yorkie-team#31)
Browse files Browse the repository at this point in the history
  • Loading branch information
hunkim98 authored and hackerwins committed Dec 17, 2022
1 parent 45dedfe commit c41ea7b
Show file tree
Hide file tree
Showing 35 changed files with 1,125 additions and 10,179 deletions.
2 changes: 1 addition & 1 deletion .env
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,4 @@ NEXT_PUBLIC_JS_SDK_URL='https://cdnjs.cloudflare.com/ajax/libs/yorkie-js-sdk/0.2
NEXT_PUBLIC_SITE_URL='http://localhost:3000'
NEXT_PUBLIC_API_ADDR='http://localhost:8080'
NEXT_PUBLIC_API_HOST='localhost'
NEXT_PUBLIC_API_PORT='8080'
NEXT_PUBLIC_API_PORT='8080'
3 changes: 2 additions & 1 deletion .env.production
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@
NEXT_PUBLIC_SITE_URL='https://yorkie.dev'
NEXT_PUBLIC_API_ADDR='https://api.yorkie.dev'
NEXT_PUBLIC_API_HOST='api.yorkie.dev'
NEXT_PUBLIC_API_PORT='443'
NEXT_PUBLIC_API_PORT='443'
NEXT_PUBLIC_EXAMPLES_API_KEY='cedaovjuioqlk4pjqn6g'
24 changes: 24 additions & 0 deletions components/BasicExampleProjects/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { Language } from 'prism-react-renderer';

export * from './kanban';

interface ProjectComponent {
isFile: boolean;
name: string;
children?: Array<ProjectFolder | ProjectFile>;
}
export interface ProjectFile extends ProjectComponent {
isFile: true;
isOpen: boolean;
language: Language;
content: string;
}
export interface ProjectFolder extends ProjectComponent {
isFile: false;
children?: Array<ProjectFolder | ProjectFile>;
}

export interface ProjectCode {
name: string;
children: Array<ProjectFolder | ProjectFile>;
}
13 changes: 13 additions & 0 deletions components/BasicExampleProjects/kanban/documentStructure.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
export const KanbanDocumentStructure = `export type KanbanDoc = {
lists: Array<List>;
};
export type List = {
title: string;
cards: Array<Card>;
};
export type Card = {
title: string;
};
`;
167 changes: 167 additions & 0 deletions components/BasicExampleProjects/kanban/files/App.vue.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
export const language = 'javascript';
export const content = `<script>
import yorkie from 'yorkie-js-sdk';
const defaultLists = [
{
title: 'Todo',
cards: [
{
title: 'Pruning document',
},
{
title: 'Clean up codes'
}
]
},
{
title: 'Doing',
cards: [
{
title: 'Array operations',
}
]
},
{
title: 'Done',
cards: [
{
title: 'Create a sample page',
},
{
title: 'Launch demo site'
}
]
},
];
const client = new yorkie.Client(${process.env.NEXT_PUBLIC_API_ADDR}, {
apiKey: ${process.env.NEXT_PUBLIC_EXAMPLES_API_KEY},
});
const doc = new yorkie.Document('vuejs-kanban');
export default {
data() {
return {
lists: [],
title: '',
opened: null,
};
},
created() {
this.fetchDoc();
},
watch: {
opened(index) {
this.$nextTick(function () {
if (index === 0) {
// Open add list form
this.$refs['addListForm'].querySelector('input').focus();
} else {
// Or open add card form
this.$refs['addCardForm'][index - 1].querySelector('input').focus();
}
});
},
},
methods: {
async fetchDoc() {
await client.activate();
await client.attach(doc);
doc.update((root) => {
if (!root.lists) {
root.lists = defaultLists;
}
}, 'create default list if not exists');
doc.subscribe((event) => {
this.lists = doc.getRoot().lists;
});
await client.sync();
this.lists = doc.getRoot().lists;
},
isOpened(index) {
return this.opened === index;
},
openForm(index) {
this.opened = index;
},
closeForm() {
this.opened = null;
},
addCard(list) {
if (this.title === '') return;
doc.update((root) => {
root.lists.getElementByID(list.getID()).cards.push({
title: this.title,
});
this.title = '';
}, \`add new card by \${client.getID()}\`);
},
deleteCard(list, card) {
doc.update((root) => {
root.lists.getElementByID(list.getID()).cards.deleteByID(card.getID());
}, \`delete a card by \${client.getID()}\`);
},
addList() {
if (this.title === '') return;
doc.update((root) => {
root.lists.push({
title: this.title,
cards: [],
});
this.title = '';
}, \`add new list by \${client.getID()}\`);
},
deleteList(list) {
doc.update((root) => {
root.lists.deleteByID(list.getID());
}, \`delete a list by \${client.getID()}\`);
},
},
}
</script>
<template>
<div v-cloak class="list" v-for="(list, index) in lists">
<span class="delete" v-on:click="deleteList(list)">❌</span>
<div class="title">{{ list.title }}</div>
<div class="card" v-for="card in list.cards">
<span class="delete" v-on:click="deleteCard(list, card)">❌</span>
{{ card.title }}
</div>
<div class="add-card" ref="addCardForm">
<div v-if="isOpened(index + 1)" class="add-form">
<input type="text" placeholder="Enter card title" v-model="title" v-on:keyup.enter="addCard(list)"
v-on:keyup.esc="closeForm()">
<div class="buttons">
<input type="button" value="Add" v-on:click="addCard(list)">
<input type="button" value="Close" class="pull-right" v-on:click="closeForm()">
</div>
</div>
<div v-else class="add-card-opener" v-on:click="openForm(index + 1)">Add another card</div>
</div>
</div>
<div class="add-list" ref="addListForm">
<div v-if="isOpened(0)" class="add-form">
<input type="text" placeholder="Enter list title" v-model="title" v-on:keyup.enter="addList()"
v-on:keyup.esc="closeForm()">
<div class="buttons">
<input type="button" value="Add" v-on:click="addList()">
<input type="button" value="Close" class="pull-right" v-on:click="closeForm()">
</div>
</div>
<div v-else class="add-list-opener" v-on:click="openForm(0)">Add another list</div>
</div>
</template>`;
15 changes: 15 additions & 0 deletions components/BasicExampleProjects/kanban/files/index.html.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
export const language = 'markup';
export const content = `<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>vuejs-kanban-yorkie</title>
</head>
<body>
<div id="app" class="kanban"></div>
<script type="module" src="/src/main.js"></script>
</body>
</html>`;
17 changes: 17 additions & 0 deletions components/BasicExampleProjects/kanban/files/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import * as mainCss from './main.css';
import * as AppVue from './App.vue';
import * as mainJs from './main.js';
import * as packageJson from './package.json';
import * as indexHtml from './index.html';
import * as viteConfigJs from './vite.config.js';

import { Language } from 'prism-react-renderer';

export const files: { [key: string]: { language: Language; content: string } } = {
'main.css': { language: mainCss.language, content: mainCss.content },
'App.vue': { language: AppVue.language, content: AppVue.content },
'main.js': { language: mainJs.language, content: mainJs.content },
'package.json': { language: packageJson.language, content: packageJson.content },
'index.html': { language: indexHtml.language, content: indexHtml.content },
'vite.config.js': { language: viteConfigJs.language, content: viteConfigJs.content },
};
133 changes: 133 additions & 0 deletions components/BasicExampleProjects/kanban/files/main.css.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
export const language = 'css';
export const content = `html,
body {
margin: 0;
padding: 0;
}
.kanban {
display: flex;
flex-direction: row;
flex-wrap: nowrap;
/* margin-bottom: 10px; */
background: #807b77;
/* border: 1px solid #ccc; */
height: 450px;
align-items: flex-start;
overflow: auto;
min-height: 100vh;
user-select: none;
}
.kanban .add-list {
padding: 10px;
color: #fff;
cursor: pointer;
background: #ffffff3d;
margin: 10px 0 10px 10px;
width: 260px;
border-radius: 3px;
flex-shrink: 0;
}
.kanban .add-list:hover {
background: #ffffff52;
}
.kaban .add-list-opener::before {
content: "+ ";
}
.delete {
position: absolute;
cursor: pointer;
top: 2px;
right: 2px;
display: none;
}
.add-form {
display: flex;
flex-direction: column;
}
.add-form input[type="text"] {
border: none;
overflow: auto;
outline: none;
font-size: 1em;
margin: 5px 0;
padding: 5px;
background: #fff;
border-radius: 3px;
box-shadow: 0 1px 0 rgba(9, 30, 66, 0.25);
position: relative;
word-break: break-word;
}
.add-form input[type="button"] {
font-size: 1em;
padding: 5px;
}
.add-form input[type="button"].pull-right {
float: right;
}
.list {
background: #ebecf0;
margin: 10px 0 10px 10px;
border-radius: 3px;
padding: 10px;
width: 260px;
display: flex;
flex-direction: column;
flex-shrink: 0;
position: relative;
}
.list:hover > .delete {
display: inherit;
}
.list .title {
font-weight: bold;
padding: 3px;
}
.list .card {
font-size: 1em;
margin: 5px 0;
padding: 5px;
background: #fff;
border-radius: 3px;
box-shadow: 0 1px 0 rgba(9, 30, 66, 0.25);
position: relative;
word-break: break-word;
}
.list .card:hover {
background: #091e4214;
}
.list .card:hover .delete {
display: inherit;
}
.add-card-opener {
margin: 5px 0;
padding: 5px;
color: #444;
font-size: 0.9em;
cursor: pointer;
}
.add-card-opener:hover {
background: #091e4214;
}
.add-card-opener::before {
content: "+ ";
}`;
7 changes: 7 additions & 0 deletions components/BasicExampleProjects/kanban/files/main.js.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export const language = 'javascript';
export const content = `import { createApp } from 'vue'
import App from './App.vue'
import './assets/main.css'
createApp(App).mount('#app')`;
Loading

0 comments on commit c41ea7b

Please sign in to comment.