JSFiddle - React, Tailwind, and code Playground
by ChangJoo Park
HTML
<div id="app">
<div class="flex-container">
<department-item v-for="list in listData" :key="list.name" :list-data="list"></department-item>
</div>
</div>
<template id="department-item">
<!-- box:start -->
<div class="box">
<div class="header">
<div class="title">{{listData.name}}</div>
<div class="action">+</div>
</div>
<div class="body">
<list-item-directory
v-for="directory in directories"
:key="directory.name"
:directory="directory"
v-on:request-new-list="requestNewList"
></list-item-directory>
<list-item-user v-for="user in users" :key="user.name" :user="user"></list-item-user>
</div>
</div>
<!-- box:end -->
</template>
<template id="list-item-directory">
<div class="item directory" v-on:click="requestNewList(directory)">
<div class="avatar">
📁
</div>
<div class="profile-wrapper">
<div class="name">{{directory.name}}</div>
<div class="details">Users: {{directory.count}}</div>
</div>
</div>
</template>
<template id="list-item-user">
<div class="item user">
<img class="avatar" :src="user.profileImage">
<div class="profile-wrapper">
<div class="name">{{user.name}}</div>
<div class="details">{{user.description}}</div>
</div>
</div>
</template>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Faker/3.1.0/faker.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Faker/3.1.0/locales/ko/faker.ko.js"></script>
CSS
@import url('https://fonts.googleapis.com/css?family=Montserrat');
body {
margin: 0;
padding: 0;
background-color: rgb(242, 242, 242);
font-family: 'Montserrat', sans-serif;
}
.flex-container {
display: -webkit-box;
display: -moz-box;
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
flex-flow: row;
height: 100%;
position: absolute;
width: 100%;
}
.box {
background-color: #838c91;
border: 1px solid white;
flex: 1;
-webkit-flex: 1;
min-width: 300px;
max-width: 300px;
position: relative;
display: flex;
flex-direction: column;
max-height: 100%;
margin-right: 10px;
}
.header {
background-color: #e2e4e6;
padding: 10px;
display: flex;
position: relative;
min-height: 20px;
align-items: center;
}
.header .title {
font-weight: bold;
flex: 1;
}
.header .action {
width: 10px;
font-weight: bold;
font-size: 20px;
cursor: pointer;
}
.box .body {
margin-top: 10px;
min-height: 0;
overflow: auto;
}
.box .body .item {
margin: 5px;
border-radius: 5px;
margin-bottom: 5px;
padding: 10px;
color: DimGrey;
background-color: #fff;
display: flex;
flex-direction: row;
align-items: center;
min-height: 40px;
cursor: pointer;
user-select: none;
}
.box .body .item:hover {
background-color: #e2e4e6;
}
.user .avatar {
width: 30px;
height: 30px;
border-radius: 50%;
vertical-align: middle;
margin-right: 10px;
}
.directory .avatar {
font-size: 25px;
margin-right: 5px;
}
.profile-wrapper .name {
font-size: 14px;
}
.profile-wrapper .details {
font-size: 12px;
}
JavaScript
var res = []
var generateDepartment = function (requestName) {
var newList = {
id: faker.random.uuid(),
type: 'list',
name: requestName || faker.commerce.department(),
data: {
directories: [],
users: []
}
}
var directoryCount = faker.random.number({min:2, max:5});
for (var j = 0; j < directoryCount; j++) {
var newDirectory = {
id: faker.random.uuid(),
type: 'directory',
name: faker.commerce.department(),
count: faker.random.number(),
listId: newList.id
}
newList.data.directories.push(newDirectory)
}
var userCount = faker.random.number({min:5, max:20});
for (var k = 0; k < userCount; k++) {
var newUser = {
id: faker.random.uuid(),
type: 'user',
name: faker.name.lastName() + faker.name.firstName(),
description: faker.name.jobTitle(),
profileImage: faker.image.avatar()
}
newList.data.users.push(newUser)
}
return newList
}
var moveList = function (requestDirectory) {
return new Promise(function (resolve, rejct) {
console.log('moveList : ',requestDirectory)
var indexOfList = res.findIndex(function (list) {
return list.id === requestDirectory.listId
})
console.log(indexOfList)
res.splice(indexOfList + 1, res.length - 1)
resolve()
})
}
var listCount = 1;
for (var i = 0; i < listCount; i++) {
res.push(generateDepartment())
}
var listItemUser = {
name: 'list-item-user',
template: '#list-item-user',
props: ['user']
}
var listItemDirectory = {
name: 'list-item-directory',
template: '#list-item-directory',
props: ['directory'],
methods: {
requestNewList: function(selectedDirectory) {
this.$emit('request-new-list', selectedDirectory)
}
}
}
var departmentItem = {
name: 'department-item',
template: '#department-item',
props: ['listData'],
created: function() {
console.log(this.listData)
},
computed: {
directories: function () {
return this.listData.data.directories ||...