2018-09-05 23:46:35 +03:00
|
|
|
<template>
|
2018-09-12 23:09:34 +03:00
|
|
|
<v-container grid-list-md>
|
2018-09-22 15:53:18 +03:00
|
|
|
<!-- TODO remove when links refactored -->
|
|
|
|
<router-link to="/haskell">
|
|
|
|
<button class="test-btn">Test Article</button>
|
|
|
|
</router-link>
|
|
|
|
|
2018-09-12 23:09:34 +03:00
|
|
|
<v-layout
|
|
|
|
row
|
|
|
|
wrap
|
|
|
|
justify-space-between
|
|
|
|
>
|
2018-09-05 23:46:35 +03:00
|
|
|
<v-flex
|
2018-09-13 23:36:29 +03:00
|
|
|
class="mr-3 mt-3"
|
2018-09-12 23:09:34 +03:00
|
|
|
column
|
|
|
|
xs12
|
|
|
|
sm5
|
|
|
|
md3
|
|
|
|
lg3
|
|
|
|
xl1
|
2018-09-16 21:02:30 +03:00
|
|
|
v-for="(groupCategories, groupName, index) in groups"
|
2018-09-05 23:46:35 +03:00
|
|
|
:key="index"
|
2018-09-18 21:59:07 +03:00
|
|
|
>
|
2018-09-12 23:09:34 +03:00
|
|
|
<div class="category-group">
|
2018-11-17 14:46:51 +03:00
|
|
|
<h4 class="mb-2 display-1 font-weight-black category-group-name">
|
2018-09-16 17:51:10 +03:00
|
|
|
{{ groupName }}
|
|
|
|
</h4>
|
2018-09-16 20:51:24 +03:00
|
|
|
<!-- TODO remove duplicates of same a-links -->
|
2018-09-13 23:26:52 +03:00
|
|
|
<a-link
|
2018-09-12 23:09:34 +03:00
|
|
|
class="category-title"
|
2018-09-13 23:26:52 +03:00
|
|
|
openInNewTab
|
2018-09-16 16:32:35 +03:00
|
|
|
v-for="category in groupCategories[CategoryStatus.finished]"
|
|
|
|
:key="category.uid"
|
2018-09-16 20:51:24 +03:00
|
|
|
:url="`http://aelve.com:4801/haskell/${getCategoryUrl(category)}`"
|
2018-09-16 16:32:35 +03:00
|
|
|
>
|
|
|
|
<h6
|
|
|
|
class="ml-2 subheading font-weight-bold"
|
|
|
|
>
|
2018-09-16 21:02:30 +03:00
|
|
|
{{ category.title }}
|
2018-09-16 16:32:35 +03:00
|
|
|
</h6>
|
|
|
|
</a-link>
|
2018-09-16 17:51:10 +03:00
|
|
|
|
2018-09-16 16:32:35 +03:00
|
|
|
<h6
|
2018-09-16 18:22:38 +03:00
|
|
|
class="ml-2 mb-1 body-2 font-weight-bold"
|
2018-09-16 16:32:35 +03:00
|
|
|
v-if="groupCategories[CategoryStatus.inProgress]"
|
|
|
|
>
|
|
|
|
In progress
|
|
|
|
</h6>
|
|
|
|
<a-link
|
|
|
|
class="category-title ml-3"
|
|
|
|
openInNewTab
|
|
|
|
v-for="category in groupCategories[CategoryStatus.inProgress]"
|
|
|
|
:key="category.uid"
|
2018-09-16 20:51:24 +03:00
|
|
|
:url="`http://aelve.com:4801/haskell/${getCategoryUrl(category)}`"
|
2018-09-16 16:32:35 +03:00
|
|
|
>
|
|
|
|
<h6
|
2018-09-16 18:22:38 +03:00
|
|
|
class="ml-2 body-1 font-weight-bold"
|
2018-09-16 16:32:35 +03:00
|
|
|
>
|
2018-09-16 21:02:30 +03:00
|
|
|
{{ category.title }}
|
2018-09-16 16:32:35 +03:00
|
|
|
</h6>
|
|
|
|
</a-link>
|
2018-09-16 17:51:10 +03:00
|
|
|
|
2018-09-16 16:32:35 +03:00
|
|
|
<h6
|
2018-09-16 18:22:38 +03:00
|
|
|
class="ml-2 mb-1 body-2 font-weight-bold"
|
2018-09-16 17:50:10 +03:00
|
|
|
v-if="groupCategories[CategoryStatus.toBeWritten]"
|
2018-09-16 16:32:35 +03:00
|
|
|
>
|
|
|
|
To be written
|
|
|
|
</h6>
|
|
|
|
<a-link
|
|
|
|
class="category-title ml-3"
|
|
|
|
openInNewTab
|
|
|
|
v-for="category in groupCategories[CategoryStatus.toBeWritten]"
|
|
|
|
:key="category.uid"
|
2018-09-16 20:51:24 +03:00
|
|
|
:url="`http://aelve.com:4801/haskell/${getCategoryUrl(category)}`"
|
2018-09-12 23:09:34 +03:00
|
|
|
>
|
|
|
|
<h6
|
2018-09-16 18:22:38 +03:00
|
|
|
class="ml-2 body-1 font-weight-bold"
|
2018-09-12 23:09:34 +03:00
|
|
|
>
|
2018-09-16 21:02:30 +03:00
|
|
|
{{ category.title }}
|
2018-09-12 23:09:34 +03:00
|
|
|
</h6>
|
2018-09-13 23:26:52 +03:00
|
|
|
</a-link>
|
2018-09-16 21:02:30 +03:00
|
|
|
|
2018-10-03 23:19:19 +03:00
|
|
|
<v-btn
|
2018-11-17 14:46:51 +03:00
|
|
|
class="ml-2 pl-0 add-category-btn"
|
2018-10-03 23:19:19 +03:00
|
|
|
color="grey"
|
|
|
|
flat
|
2018-11-08 00:24:18 +03:00
|
|
|
@click="openAddCategoryDialog(groupName)"
|
2018-09-16 21:02:30 +03:00
|
|
|
>
|
2018-10-03 23:19:19 +03:00
|
|
|
<v-icon class="mr-1" left>add</v-icon>
|
|
|
|
Add new category
|
|
|
|
</v-btn>
|
2018-09-05 23:46:35 +03:00
|
|
|
</div>
|
|
|
|
</v-flex>
|
2018-10-03 23:19:19 +03:00
|
|
|
<add-category-dialog
|
|
|
|
v-model="isAddGroupDialogOpen"
|
|
|
|
:groupName="addCategoryGroupName"
|
|
|
|
/>
|
2018-09-05 23:46:35 +03:00
|
|
|
</v-layout>
|
|
|
|
</v-container>
|
|
|
|
</template>
|
|
|
|
|
|
|
|
<script lang="ts">
|
|
|
|
import _groupBy from 'lodash/groupBy'
|
2018-09-12 23:23:07 +03:00
|
|
|
import _toKebabCase from 'lodash/kebabCase'
|
2018-10-04 00:40:14 +03:00
|
|
|
import _sortBy from 'lodash/sortBy'
|
|
|
|
import _fromPairs from 'lodash/fromPairs'
|
2018-09-05 23:46:35 +03:00
|
|
|
import Vue from 'vue'
|
|
|
|
import Component from 'vue-class-component'
|
2018-11-21 13:31:31 +03:00
|
|
|
import { ICategoryInfo, CategoryStatus } from 'client/service/Category'
|
2018-09-16 21:02:30 +03:00
|
|
|
import AddCategoryDialog from 'client/components/AddCategoryDialog.vue'
|
2018-09-16 16:32:35 +03:00
|
|
|
|
2018-09-16 21:02:30 +03:00
|
|
|
@Component({
|
|
|
|
components: {
|
|
|
|
AddCategoryDialog
|
|
|
|
}
|
|
|
|
})
|
2018-09-12 23:09:34 +03:00
|
|
|
export default class Categories extends Vue {
|
2018-09-16 16:32:35 +03:00
|
|
|
CategoryStatus = CategoryStatus
|
2018-10-03 23:19:19 +03:00
|
|
|
addCategoryGroupName: string = ''
|
|
|
|
isAddGroupDialogOpen: boolean = false
|
2018-10-04 00:40:14 +03:00
|
|
|
|
2018-11-21 13:31:31 +03:00
|
|
|
async asyncData () {
|
2018-10-03 00:07:01 +03:00
|
|
|
return this.$store.dispatch('category/loadCategoryList')
|
2018-09-12 23:09:34 +03:00
|
|
|
}
|
2018-11-21 13:31:31 +03:00
|
|
|
get categories () {
|
2018-09-12 23:09:34 +03:00
|
|
|
return this.$store.state.category.categoryList
|
2018-09-05 23:46:35 +03:00
|
|
|
}
|
2018-11-21 13:31:31 +03:00
|
|
|
get groups () {
|
|
|
|
const groupedByGroupName = _groupBy(this.categories, 'group')
|
2018-10-04 00:40:14 +03:00
|
|
|
const groupedEntries = Object.entries(groupedByGroupName)
|
2018-11-21 13:31:31 +03:00
|
|
|
const groupedAlsoByStatus = groupedEntries.map(([key, value]: [string, ICategoryInfo[]]) => {
|
2018-10-04 00:40:14 +03:00
|
|
|
const grouppedCategoriesByStatus = _groupBy(value, 'status')
|
|
|
|
return [key, grouppedCategoriesByStatus]
|
2018-09-16 16:32:35 +03:00
|
|
|
})
|
2018-10-04 00:40:14 +03:00
|
|
|
// Key is groupName, so we sort by groupNames
|
|
|
|
const entriesKeyIndex = 0
|
|
|
|
const sortedAlphabetically = _sortBy(groupedAlsoByStatus, entriesKeyIndex)
|
|
|
|
return _fromPairs(sortedAlphabetically)
|
2018-09-16 16:32:35 +03:00
|
|
|
}
|
2018-11-21 13:31:31 +03:00
|
|
|
openAddCategoryDialog (groupName: string) {
|
2018-10-03 23:19:19 +03:00
|
|
|
this.addCategoryGroupName = groupName
|
|
|
|
this.isAddGroupDialogOpen = true
|
|
|
|
}
|
2018-11-21 13:31:31 +03:00
|
|
|
getCategoryUrl (category: ICategoryInfo): string {
|
2018-09-12 23:23:07 +03:00
|
|
|
return `${_toKebabCase(category.title)}-${category.uid}`
|
|
|
|
}
|
2018-09-05 23:46:35 +03:00
|
|
|
}
|
|
|
|
</script>
|
|
|
|
|
2018-09-12 23:09:34 +03:00
|
|
|
<style scoped>
|
|
|
|
.category-group {
|
2018-09-05 23:46:35 +03:00
|
|
|
text-align: left;
|
|
|
|
}
|
2018-09-12 23:09:34 +03:00
|
|
|
.category-title {
|
2018-09-12 23:51:13 +03:00
|
|
|
display: block;
|
2018-09-13 23:36:29 +03:00
|
|
|
line-height: 1.2;
|
2018-09-12 23:09:34 +03:00
|
|
|
}
|
2018-09-13 23:26:52 +03:00
|
|
|
.category-title:not(:last-child) {
|
|
|
|
margin-bottom: 5px;
|
2018-09-12 23:09:34 +03:00
|
|
|
}
|
2018-09-18 21:59:07 +03:00
|
|
|
.test-btn {
|
|
|
|
background: #000;
|
|
|
|
color: #fff;
|
|
|
|
padding: 8px 14px 7px;
|
|
|
|
border-radius: 25px;
|
|
|
|
text-transform: uppercase;
|
|
|
|
margin: 0 0 20px;
|
|
|
|
}
|
2018-09-05 23:46:35 +03:00
|
|
|
</style>
|