mirror of
https://github.com/Ocelot-Social-Community/Ocelot-Social.git
synced 2025-12-13 07:46:06 +00:00
feat(webapp): group categories on posts
This commit is contained in:
parent
e2667a1a98
commit
3244f3f86d
@ -10,9 +10,9 @@
|
|||||||
:icon="category.icon"
|
:icon="category.icon"
|
||||||
size="small"
|
size="small"
|
||||||
v-tooltip="{
|
v-tooltip="{
|
||||||
content: $t(`contribution.category.description.${category.slug}`),
|
content: $t(`contribution.category.description.${category.slug}`),
|
||||||
placement: 'bottom-start',
|
placement: 'bottom-start',
|
||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
{{ $t(`contribution.category.name.${category.slug}`) }}
|
{{ $t(`contribution.category.name.${category.slug}`) }}
|
||||||
</base-button>
|
</base-button>
|
||||||
@ -20,75 +20,82 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import CategoryQuery from '~/graphql/CategoryQuery'
|
import CategoryQuery from '~/graphql/CategoryQuery'
|
||||||
import { CATEGORIES_MAX } from '~/constants/categories.js'
|
import { CATEGORIES_MAX } from '~/constants/categories.js'
|
||||||
import xor from 'lodash/xor'
|
import xor from 'lodash/xor'
|
||||||
import SortCategories from '~/mixins/sortCategoriesMixin.js'
|
import SortCategories from '~/mixins/sortCategoriesMixin.js'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
inject: {
|
inject: {
|
||||||
$parentForm: {
|
$parentForm: {
|
||||||
default: null,
|
default: null,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
mixins: [SortCategories],
|
mixins: [SortCategories],
|
||||||
props: {
|
props: {
|
||||||
existingCategoryIds: { type: Array, default: () => [] },
|
existingCategoryIds: { type: Array, default: () => [] },
|
||||||
model: { type: String, required: true },
|
model: { type: String, required: true },
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
categories: null,
|
categories: null,
|
||||||
selectedMax: CATEGORIES_MAX,
|
selectedMax: CATEGORIES_MAX,
|
||||||
selectedCategoryIds: this.existingCategoryIds,
|
selectedCategoryIds: this.existingCategoryIds,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
watch: {
|
||||||
selectedCount() {
|
existingCategoryIds() {
|
||||||
return this.selectedCategoryIds.length
|
console.log('existingCategoryIds', this.selectedCategoryIds)
|
||||||
},
|
if (!this.selectedCategoryIds.length)
|
||||||
reachedMaximum() {
|
this.selectedCategoryIds = this.existingCategoryIds
|
||||||
return this.selectedCount >= this.selectedMax
|
},
|
||||||
},
|
},
|
||||||
},
|
computed: {
|
||||||
methods: {
|
selectedCount() {
|
||||||
toggleCategory(id) {
|
return this.selectedCategoryIds.length
|
||||||
this.selectedCategoryIds = xor(this.selectedCategoryIds, [id])
|
},
|
||||||
if (this.$parentForm) {
|
reachedMaximum() {
|
||||||
this.$parentForm.update(this.model, this.selectedCategoryIds)
|
return this.selectedCount >= this.selectedMax
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
isActive(id) {
|
methods: {
|
||||||
return this.selectedCategoryIds.includes(id)
|
toggleCategory(id) {
|
||||||
},
|
this.selectedCategoryIds = xor(this.selectedCategoryIds, [id])
|
||||||
isDisabled(id) {
|
if (this.$parentForm) {
|
||||||
return !!(this.reachedMaximum && !this.isActive(id))
|
this.$parentForm.update(this.model, this.selectedCategoryIds)
|
||||||
},
|
}
|
||||||
categoryButtonsId(categoryId) {
|
},
|
||||||
return `category-buttons-${categoryId}`
|
isActive(id) {
|
||||||
},
|
return this.selectedCategoryIds.includes(id)
|
||||||
},
|
},
|
||||||
apollo: {
|
isDisabled(id) {
|
||||||
Category: {
|
return !!(this.reachedMaximum && !this.isActive(id))
|
||||||
query() {
|
},
|
||||||
return CategoryQuery()
|
categoryButtonsId(categoryId) {
|
||||||
},
|
return `category-buttons-${categoryId}`
|
||||||
result({ data: { Category } }) {
|
},
|
||||||
this.categories = this.sortCategories(Category)
|
},
|
||||||
},
|
apollo: {
|
||||||
},
|
Category: {
|
||||||
},
|
query() {
|
||||||
}
|
return CategoryQuery()
|
||||||
|
},
|
||||||
|
result({ data: { Category } }) {
|
||||||
|
this.categories = this.sortCategories(Category)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
.categories-select {
|
.categories-select {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
|
|
||||||
> .base-button {
|
> .base-button {
|
||||||
margin-right: $space-xx-small;
|
margin-right: $space-xx-small;
|
||||||
margin-bottom: $space-xx-small;
|
margin-bottom: $space-xx-small;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@ -94,188 +94,197 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import gql from 'graphql-tag'
|
import gql from 'graphql-tag'
|
||||||
import { mapGetters } from 'vuex'
|
import { mapGetters } from 'vuex'
|
||||||
import Editor from '~/components/Editor/Editor'
|
import Editor from '~/components/Editor/Editor'
|
||||||
import PostMutations from '~/graphql/PostMutations.js'
|
import PostMutations from '~/graphql/PostMutations.js'
|
||||||
import CategoriesSelect from '~/components/CategoriesSelect/CategoriesSelect'
|
import CategoriesSelect from '~/components/CategoriesSelect/CategoriesSelect'
|
||||||
import ImageUploader from '~/components/Uploader/ImageUploader'
|
import ImageUploader from '~/components/Uploader/ImageUploader'
|
||||||
import links from '~/constants/links.js'
|
import links from '~/constants/links.js'
|
||||||
import PageParamsLink from '~/components/_new/features/PageParamsLink/PageParamsLink.vue'
|
import PageParamsLink from '~/components/_new/features/PageParamsLink/PageParamsLink.vue'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
Editor,
|
Editor,
|
||||||
ImageUploader,
|
ImageUploader,
|
||||||
PageParamsLink,
|
PageParamsLink,
|
||||||
CategoriesSelect,
|
CategoriesSelect,
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
contribution: {
|
contribution: {
|
||||||
type: Object,
|
type: Object,
|
||||||
default: () => ({}),
|
default: () => ({}),
|
||||||
},
|
},
|
||||||
group: {
|
group: {
|
||||||
type: Object,
|
type: Object,
|
||||||
default: () => null,
|
default: () => null,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
const { title, content, image, categories } = this.contribution
|
const { title, content, image, categories } = this.contribution
|
||||||
const {
|
const {
|
||||||
sensitive: imageBlurred = false,
|
sensitive: imageBlurred = false,
|
||||||
aspectRatio: imageAspectRatio = null,
|
aspectRatio: imageAspectRatio = null,
|
||||||
type: imageType = null,
|
type: imageType = null,
|
||||||
} = image || {}
|
} = image || {}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
categoriesActive: this.$env.CATEGORIES_ACTIVE,
|
categoriesActive: this.$env.CATEGORIES_ACTIVE,
|
||||||
links,
|
links,
|
||||||
formData: {
|
formData: {
|
||||||
title: title || '',
|
title: title || '',
|
||||||
content: content || '',
|
content: content || '',
|
||||||
image: image || null,
|
image: image || null,
|
||||||
imageAspectRatio,
|
imageAspectRatio,
|
||||||
imageType,
|
imageType,
|
||||||
imageBlurred,
|
imageBlurred,
|
||||||
categoryIds: categories ? categories.map((category) => category.id) : [],
|
categoryIds: categories ? categories.map((category) => category.id) : []
|
||||||
},
|
},
|
||||||
formSchema: {
|
formSchema: {
|
||||||
title: { required: true, min: 3, max: 100 },
|
title: { required: true, min: 3, max: 100 },
|
||||||
content: { required: true },
|
content: { required: true },
|
||||||
imageBlurred: { required: false },
|
imageBlurred: { required: false },
|
||||||
categoryIds: {
|
categoryIds: {
|
||||||
type: 'array',
|
type: 'array',
|
||||||
required: this.categoriesActive,
|
required: this.categoriesActive,
|
||||||
validator: (_, value = []) => {
|
validator: (_, value = []) => {
|
||||||
if (this.categoriesActive && (value.length === 0 || value.length > 3)) {
|
if (this.categoriesActive && (value.length === 0 || value.length > 3)) {
|
||||||
return [new Error(this.$t('common.validations.categories'))]
|
return [new Error(this.$t('common.validations.categories'))]
|
||||||
}
|
}
|
||||||
return []
|
return []
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
loading: false,
|
loading: false,
|
||||||
users: [],
|
users: [],
|
||||||
hashtags: [],
|
hashtags: [],
|
||||||
imageUpload: null,
|
imageUpload: null,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapGetters({
|
...mapGetters({
|
||||||
currentUser: 'auth/user',
|
currentUser: 'auth/user',
|
||||||
}),
|
}),
|
||||||
contentLength() {
|
contentLength() {
|
||||||
return this.$filters.removeHtml(this.formData.content).length
|
return this.$filters.removeHtml(this.formData.content).length
|
||||||
},
|
},
|
||||||
groupId() {
|
groupId() {
|
||||||
return this.group && this.group.id
|
return this.group && this.group.id
|
||||||
},
|
},
|
||||||
showGroupHint() {
|
showGroupHint() {
|
||||||
return this.groupId && ['closed', 'hidden'].includes(this.group.groupType)
|
return this.groupId && ['closed', 'hidden'].includes(this.group.groupType)
|
||||||
},
|
},
|
||||||
groupName() {
|
groupName() {
|
||||||
return this.group && this.group.name
|
return this.group && this.group.name
|
||||||
},
|
},
|
||||||
},
|
groupCategories() {
|
||||||
methods: {
|
return this.group && this.group.categories
|
||||||
submit() {
|
},
|
||||||
let image = null
|
},
|
||||||
const { title, content, categoryIds } = this.formData
|
watch: {
|
||||||
if (this.formData.image) {
|
groupCategories() {
|
||||||
image = {
|
console.log('groupCategories', this.groupCategories)
|
||||||
sensitive: this.formData.imageBlurred,
|
if (!this.formData.categoryIds && this.groupCategories) this.formData.categoryIds = this.groupCategories
|
||||||
}
|
},
|
||||||
if (this.imageUpload) {
|
},
|
||||||
image.upload = this.imageUpload
|
methods: {
|
||||||
image.aspectRatio = this.formData.imageAspectRatio
|
submit() {
|
||||||
image.type = this.formData.imageType
|
let image = null
|
||||||
}
|
const { title, content, categoryIds } = this.formData
|
||||||
}
|
if (this.formData.image) {
|
||||||
this.loading = true
|
image = {
|
||||||
this.$apollo
|
sensitive: this.formData.imageBlurred,
|
||||||
.mutate({
|
}
|
||||||
mutation: this.contribution.id ? PostMutations().UpdatePost : PostMutations().CreatePost,
|
if (this.imageUpload) {
|
||||||
variables: {
|
image.upload = this.imageUpload
|
||||||
title,
|
image.aspectRatio = this.formData.imageAspectRatio
|
||||||
content,
|
image.type = this.formData.imageType
|
||||||
categoryIds,
|
}
|
||||||
id: this.contribution.id || null,
|
}
|
||||||
image,
|
this.loading = true
|
||||||
groupId: this.groupId,
|
this.$apollo
|
||||||
},
|
.mutate({
|
||||||
})
|
mutation: this.contribution.id ? PostMutations().UpdatePost : PostMutations().CreatePost,
|
||||||
.then(({ data }) => {
|
variables: {
|
||||||
this.loading = false
|
title,
|
||||||
this.$toast.success(this.$t('contribution.success'))
|
content,
|
||||||
const result = data[this.contribution.id ? 'UpdatePost' : 'CreatePost']
|
categoryIds,
|
||||||
|
id: this.contribution.id || null,
|
||||||
|
image,
|
||||||
|
groupId: this.groupId,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.then(({ data }) => {
|
||||||
|
this.loading = false
|
||||||
|
this.$toast.success(this.$t('contribution.success'))
|
||||||
|
const result = data[this.contribution.id ? 'UpdatePost' : 'CreatePost']
|
||||||
|
|
||||||
this.$router.push({
|
this.$router.push({
|
||||||
name: 'post-id-slug',
|
name: 'post-id-slug',
|
||||||
params: { id: result.id, slug: result.slug },
|
params: { id: result.id, slug: result.slug },
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
this.$toast.error(err.message)
|
this.$toast.error(err.message)
|
||||||
this.loading = false
|
this.loading = false
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
updateEditorContent(value) {
|
updateEditorContent(value) {
|
||||||
this.$refs.contributionForm.update('content', value)
|
this.$refs.contributionForm.update('content', value)
|
||||||
},
|
},
|
||||||
addHeroImage(file) {
|
addHeroImage(file) {
|
||||||
this.formData.image = null
|
this.formData.image = null
|
||||||
if (file) {
|
if (file) {
|
||||||
const reader = new FileReader()
|
const reader = new FileReader()
|
||||||
reader.onload = ({ target }) => {
|
reader.onload = ({ target }) => {
|
||||||
this.formData.image = {
|
this.formData.image = {
|
||||||
...this.formData.image,
|
...this.formData.image,
|
||||||
url: target.result,
|
url: target.result,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
reader.readAsDataURL(file)
|
reader.readAsDataURL(file)
|
||||||
this.imageUpload = file
|
this.imageUpload = file
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
addImageAspectRatio(aspectRatio) {
|
addImageAspectRatio(aspectRatio) {
|
||||||
this.formData.imageAspectRatio = aspectRatio
|
this.formData.imageAspectRatio = aspectRatio
|
||||||
},
|
},
|
||||||
addImageType(imageType) {
|
addImageType(imageType) {
|
||||||
this.formData.imageType = imageType
|
this.formData.imageType = imageType
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
apollo: {
|
apollo: {
|
||||||
User: {
|
User: {
|
||||||
query() {
|
query() {
|
||||||
return gql`
|
return gql`
|
||||||
query {
|
query {
|
||||||
User(orderBy: slug_asc) {
|
User(orderBy: slug_asc) {
|
||||||
id
|
id
|
||||||
slug
|
slug
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
},
|
},
|
||||||
result({ data: { User } }) {
|
result({ data: { User } }) {
|
||||||
this.users = User
|
this.users = User
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Tag: {
|
Tag: {
|
||||||
query() {
|
query() {
|
||||||
return gql`
|
return gql`
|
||||||
query {
|
query {
|
||||||
Tag(orderBy: id_asc) {
|
Tag(orderBy: id_asc) {
|
||||||
id
|
id
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
},
|
},
|
||||||
result({ data: { Tag } }) {
|
result({ data: { Tag } }) {
|
||||||
this.hashtags = Tag
|
this.hashtags = Tag
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user