mirror of
https://github.com/aelve/guide.git
synced 2024-12-23 12:52:31 +03:00
Merge branch 'develop' of https://github.com/aelve/guide into develop
This commit is contained in:
commit
0bf980156e
@ -2,7 +2,7 @@
|
||||
<v-container>
|
||||
<div class="category-wrapper">
|
||||
<template v-if="category">
|
||||
<category-info
|
||||
<CategoryHeader
|
||||
:category="category"
|
||||
:categoryId="categoryId"
|
||||
:categoryTitle="category.title"
|
||||
@ -59,14 +59,14 @@ import { Prop } from 'vue-property-decorator'
|
||||
import CategoryItem from 'client/components/CategoryItem.vue'
|
||||
import CategoryDescription from 'client/components/CategoryDescription.vue'
|
||||
import category from 'client/store/modules/category'
|
||||
import CategoryInfo from 'client/components/CategoryInfo.vue'
|
||||
import CategoryHeader from 'client/components/CategoryHeader.vue'
|
||||
import AddItemDialog from 'client/components/AddItemDialog.vue'
|
||||
|
||||
@Component({
|
||||
components: {
|
||||
CategoryItem,
|
||||
CategoryDescription,
|
||||
CategoryInfo,
|
||||
CategoryHeader,
|
||||
AddItemDialog
|
||||
}
|
||||
})
|
||||
|
236
front/client/components/CategoryHeader.vue
Normal file
236
front/client/components/CategoryHeader.vue
Normal file
@ -0,0 +1,236 @@
|
||||
<template>
|
||||
<div class="category-top">
|
||||
<div class="category-top-titles">
|
||||
<v-tooltip bottom>
|
||||
<template v-slot:activator="{ on }">
|
||||
<a-link
|
||||
openInNewTab
|
||||
aria-label="RSS feed for all new items in this category"
|
||||
:url="`https://guide.aelve.com/haskell/feed/category/${categoryId}`"
|
||||
class="category-rss-button"
|
||||
v-on="on"
|
||||
>
|
||||
<v-icon
|
||||
left
|
||||
size="20"
|
||||
class="mr-3 rss-link-icon"
|
||||
>$vuetify.icons.rss</v-icon>
|
||||
</a-link>
|
||||
</template>
|
||||
<span>RSS feed for all new items in this category</span>
|
||||
</v-tooltip>
|
||||
|
||||
<router-link
|
||||
class="category-top-link mr-3"
|
||||
:to="categoryUrl"
|
||||
>
|
||||
{{categoryTitle}}
|
||||
</router-link>
|
||||
<h2 class="category-top-group"> {{categoryGroup}} </h2>
|
||||
</div>
|
||||
|
||||
<v-menu
|
||||
bottom
|
||||
left
|
||||
>
|
||||
<template v-slot:activator="{ on }">
|
||||
<v-btn
|
||||
flat
|
||||
icon
|
||||
class="category-actions-menu-btn"
|
||||
v-on="on"
|
||||
>
|
||||
<v-icon
|
||||
color="grey"
|
||||
size="16"
|
||||
>$vuetify.icons.bars</v-icon>
|
||||
</v-btn>
|
||||
</template>
|
||||
|
||||
<v-list>
|
||||
<v-list-tile class="category-actions-menu-item">
|
||||
<CategoryHeaderBtn
|
||||
text="New item"
|
||||
icon="plus"
|
||||
class="mr-1"
|
||||
@click="openAddItemDialog"
|
||||
/>
|
||||
</v-list-tile>
|
||||
<v-list-tile class="category-actions-menu-item">
|
||||
<CategoryHeaderBtn
|
||||
text="Category settings"
|
||||
icon="cog"
|
||||
class="mr-1"
|
||||
@click="openCategorySettingsEditDialog"
|
||||
/>
|
||||
</v-list-tile>
|
||||
<v-list-tile class="category-actions-menu-item">
|
||||
<CategoryHeaderBtn
|
||||
text="Delete category"
|
||||
icon="trash-alt"
|
||||
@click="deleteCategory"
|
||||
/>
|
||||
</v-list-tile>
|
||||
</v-list>
|
||||
</v-menu>
|
||||
|
||||
<div class="category-actions">
|
||||
<CategoryHeaderBtn
|
||||
text="New item"
|
||||
icon="plus"
|
||||
class="mr-1"
|
||||
@click="openAddItemDialog"
|
||||
/>
|
||||
<CategoryHeaderBtn
|
||||
text="Category settings"
|
||||
icon="cog "
|
||||
class="mr-1"
|
||||
@click="openCategorySettingsEditDialog"
|
||||
/>
|
||||
<CategoryHeaderBtn
|
||||
text="Delete category"
|
||||
icon="trash-alt"
|
||||
@click="deleteCategory"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<category-info-edit
|
||||
v-model="isCategoryInfoEdit"
|
||||
:categoryId="categoryId"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import Vue from 'vue'
|
||||
import Component from 'vue-class-component'
|
||||
import { Prop } from 'vue-property-decorator'
|
||||
import CategoryInfoEdit from 'client/components/CategoryInfoEdit.vue'
|
||||
import ALink from 'client/components/ALink.vue'
|
||||
import Confirm from 'client/helpers/ConfirmDecorator'
|
||||
import CategoryHeaderBtn from 'client/components/CategoryHeaderBtn.vue'
|
||||
|
||||
@Component({
|
||||
components: {
|
||||
CategoryInfoEdit,
|
||||
ALink,
|
||||
CategoryHeaderBtn
|
||||
}
|
||||
})
|
||||
export default class CategoryHeader extends Vue {
|
||||
@Prop(Object) category!: object
|
||||
@Prop(String) categoryId!: string
|
||||
@Prop(String) categoryTitle!: string
|
||||
@Prop(String) categoryGroup!: string
|
||||
@Prop(String) categoryUrl!: string
|
||||
|
||||
isCategoryInfoEdit: boolean = false
|
||||
isAddItemDialogOpen: boolean = false
|
||||
|
||||
openCategorySettingsEditDialog () {
|
||||
this.isCategoryInfoEdit = true
|
||||
}
|
||||
|
||||
openAddItemDialog () {
|
||||
this.$emit('openAddItemDialog')
|
||||
}
|
||||
|
||||
@Confirm({ text: 'delete this category' })
|
||||
async deleteCategory () {
|
||||
if (!this.category) {
|
||||
return
|
||||
}
|
||||
await this.$store.dispatch('category/deleteCategory', this.categoryId)
|
||||
this.$router.back()
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="postcss" scoped>
|
||||
.category-top {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
justify-content: space-between;
|
||||
margin: 0 0 10px;
|
||||
}
|
||||
|
||||
.rss-link-icon:hover {
|
||||
color: #000;
|
||||
}
|
||||
|
||||
.category-top-titles {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
align-items: baseline;
|
||||
}
|
||||
|
||||
.category-rss-button {
|
||||
/* For vertical aligning on one line with category title */
|
||||
font-size: 1px;
|
||||
}
|
||||
|
||||
.category-top-link {
|
||||
font-size: 22px;
|
||||
font-weight: 600;
|
||||
text-decoration: none;
|
||||
color: #979797;
|
||||
cursor: pointer;
|
||||
transition: all ease-in-out 0.25s;
|
||||
}
|
||||
|
||||
.category-top-link:hover {
|
||||
color: #000;
|
||||
}
|
||||
|
||||
.category-top-group {
|
||||
font-size: 16px;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.category-actions-menu-btn {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.category-actions {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
justify-content: center;
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
.category-actions-menu-item {
|
||||
height: 36px;
|
||||
|
||||
>>> .v-list__tile {
|
||||
height: 36px;
|
||||
}
|
||||
|
||||
>>> button {
|
||||
width: 100%;
|
||||
padding: 5px;
|
||||
|
||||
.v-btn__content {
|
||||
justify-content: flex-start;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.category-actions-menu-btn {
|
||||
display: block;
|
||||
}
|
||||
.category-actions {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 425px) {
|
||||
.category-top-link {
|
||||
font-size: 18px;
|
||||
}
|
||||
.category-top-group {
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
35
front/client/components/CategoryHeaderBtn.vue
Normal file
35
front/client/components/CategoryHeaderBtn.vue
Normal file
@ -0,0 +1,35 @@
|
||||
<template>
|
||||
<v-btn
|
||||
flat
|
||||
class="category-header-btn"
|
||||
:title="text"
|
||||
color="grey"
|
||||
v-bind="$attrs"
|
||||
v-on="$listeners"
|
||||
>
|
||||
<v-icon size="14" class="mr-1" left>{{`$vuetify.icons.${icon}`}}</v-icon>
|
||||
{{ text }}
|
||||
</v-btn>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import Vue from 'vue'
|
||||
import Component from 'vue-class-component'
|
||||
import { Prop } from 'vue-property-decorator'
|
||||
|
||||
@Component
|
||||
export default class CategoryHeaderBtn extends Vue {
|
||||
@Prop(String) icon: string
|
||||
@Prop(String) text: string
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.category-header-btn {
|
||||
margin: 0;
|
||||
padding: 0 4px;
|
||||
height: 28px;
|
||||
font-size: 12px;
|
||||
font-weight: bold;
|
||||
}
|
||||
</style>
|
@ -1,151 +0,0 @@
|
||||
<template>
|
||||
<div class="category-top">
|
||||
<div class="category-top-data">
|
||||
<v-tooltip bottom>
|
||||
<template v-slot:activator="{ on }">
|
||||
<a-link
|
||||
openInNewTab
|
||||
aria-label="RSS feed for all new items in this category"
|
||||
:url="`https://guide.aelve.com/haskell/feed/category/${categoryId}`"
|
||||
v-on="on"
|
||||
>
|
||||
<v-icon
|
||||
left
|
||||
size="18"
|
||||
class="mr-3"
|
||||
>$vuetify.icons.rss</v-icon>
|
||||
</a-link>
|
||||
</template>
|
||||
<span>RSS feed for all new items in this category</span>
|
||||
</v-tooltip>
|
||||
|
||||
<p class="category-top-group mr-3"> {{categoryGroup}} </p>
|
||||
<v-icon size="8" class="mr-3" left>$vuetify.icons.circle</v-icon>
|
||||
<router-link
|
||||
class="category-top-link mr-3"
|
||||
:to="categoryUrl"
|
||||
>
|
||||
{{categoryTitle}}
|
||||
</router-link>
|
||||
<category-item-btn
|
||||
title="Edit item info"
|
||||
icon="cog"
|
||||
iconSize="18"
|
||||
@click="openCategoryInfoDialog"
|
||||
/>
|
||||
</div>
|
||||
<v-btn
|
||||
class="ma-0 px-1"
|
||||
flat
|
||||
title="Add new item"
|
||||
color="grey"
|
||||
@click="openDialog"
|
||||
>
|
||||
<v-icon size="14" class="mr-1" left>$vuetify.icons.plus</v-icon>
|
||||
Add new item
|
||||
</v-btn>
|
||||
<v-btn
|
||||
icon
|
||||
flat
|
||||
class="ma-0 pa-0"
|
||||
color="grey"
|
||||
title="Delete category"
|
||||
@click="deleteCategory"
|
||||
>
|
||||
<v-icon size="14">$vuetify.icons.trash-alt</v-icon>
|
||||
</v-btn>
|
||||
<category-info-edit
|
||||
v-model="isCategoryInfoEdit"
|
||||
:categoryId="categoryId"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import Vue from 'vue'
|
||||
import Component from 'vue-class-component'
|
||||
import { Prop } from 'vue-property-decorator'
|
||||
import CategoryInfoEdit from 'client/components/CategoryInfoEdit.vue'
|
||||
import ALink from 'client/components/ALink.vue'
|
||||
import Confirm from 'client/helpers/ConfirmDecorator'
|
||||
import CategoryItemBtn from 'client/components/CategoryItemBtn.vue'
|
||||
|
||||
@Component({
|
||||
components: {
|
||||
CategoryInfoEdit,
|
||||
ALink,
|
||||
CategoryItemBtn,
|
||||
}
|
||||
})
|
||||
export default class CategoryInfo extends Vue {
|
||||
@Prop(Object) category!: object
|
||||
@Prop(String) categoryId!: string
|
||||
@Prop(String) categoryTitle!: string
|
||||
@Prop(String) categoryGroup!: string
|
||||
@Prop(String) categoryUrl!: string
|
||||
|
||||
isCategoryInfoEdit: boolean = false
|
||||
isAddItemDialogOpen: boolean = false
|
||||
|
||||
openCategoryInfoDialog () {
|
||||
this.isCategoryInfoEdit = true
|
||||
}
|
||||
|
||||
openDialog () {
|
||||
this.$emit('openAddItemDialog');
|
||||
}
|
||||
|
||||
@Confirm({ text: 'delete this category' })
|
||||
async deleteCategory () {
|
||||
if (!this.category) {
|
||||
return
|
||||
}
|
||||
await this.$store.dispatch('category/deleteCategory', this.categoryId)
|
||||
this.$router.back()
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.category-top {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin: 0 0 5px;
|
||||
}
|
||||
|
||||
.category-top-data {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.category-top >>> i {
|
||||
margin-right: 15px;
|
||||
font-size: 18px;
|
||||
color: #979797;
|
||||
cursor: pointer;
|
||||
transition: all ease-in-out 0.25s;
|
||||
}
|
||||
|
||||
.category-top >>> i:hover {
|
||||
color: #000;
|
||||
}
|
||||
|
||||
.category-top-link {
|
||||
font-size: 24px;
|
||||
font-weight: 600;
|
||||
text-decoration: none;
|
||||
color: #979797;
|
||||
cursor: pointer;
|
||||
transition: all ease-in-out 0.25s;
|
||||
}
|
||||
|
||||
.category-top-link:hover {
|
||||
color: #000;
|
||||
}
|
||||
|
||||
.category-top-group {
|
||||
font-size: 24px;
|
||||
}
|
||||
</style>
|
||||
|
Loading…
Reference in New Issue
Block a user