Merge branch 'master' of github.com:Ocelot-Social-Community/Ocelot-Social into 5059-epic-groups

# Conflicts:
#	backend/src/constants/categories.js
#	backend/src/db/seed.js
This commit is contained in:
Wolfgang Huß 2022-08-31 09:02:26 +02:00
commit a8f59a4c42
17 changed files with 243 additions and 133 deletions

View File

@ -1,3 +1,102 @@
// this file is duplicated in `backend/src/constants/metadata.js` and `webapp/constants/metadata.js`
export const CATEGORIES_MIN = 1
export const CATEGORIES_MAX = 3
export const categories = [
{
icon: 'users',
name: 'networking',
description: 'Kooperation, Aktionsbündnisse, Solidarität, Hilfe',
},
{
icon: 'home',
name: 'home',
description: 'Bauen, Lebensgemeinschaften, Tiny Houses, Gemüsegarten',
},
{
icon: 'lightbulb',
name: 'energy',
description: 'Öl, Gas, Kohle, Wind, Wasserkraft, Biogas, Atomenergie, ...',
},
{
icon: 'smile',
name: 'psyche',
description: 'Seele, Gefühle, Glück',
},
{
icon: 'movement',
name: 'body-and-excercise',
description: 'Sport, Yoga, Massage, Tanzen, Entspannung',
},
{
icon: 'balance-scale',
name: 'law',
description: 'Menschenrechte, Gesetze, Verordnungen',
},
{
icon: 'money',
name: 'finance',
description: 'Geld, Finanzsystem, Alternativwährungen, ...',
},
{
icon: 'child',
name: 'children',
description: 'Familie, Pädagogik, Schule, Prägung',
},
{
icon: 'suitcase',
name: 'mobility',
description: 'Reise, Verkehr, Elektromobilität',
},
{
icon: 'shopping-cart',
name: 'economy',
description: 'Handel, Konsum, Marketing, Lebensmittel, Lieferketten, ...',
},
{
icon: 'angellist',
name: 'peace',
description: 'Krieg, Militär, soziale Verteidigung, Waffen, Cyberattacken',
},
{
icon: 'university',
name: 'politics',
description: 'Demokratie, Mitbestimmung, Wahlen, Korruption, Parteien',
},
{
icon: 'tree',
name: 'nature',
description: 'Tiere, Pflanzen, Landwirtschaft, Ökologie, Artenvielfalt',
},
{
icon: 'graduation-cap',
name: 'science',
description: 'Bildung, Hochschule, Publikationen, ...',
},
{
icon: 'medkit',
name: 'health',
description: 'Medizin, Ernährung, WHO, Impfungen, Schadstoffe, ...',
},
{
icon: 'desktop',
name: 'it-and-media',
description:
'Nachrichten, Manipulation, Datenschutz, Überwachung, Datenkraken, AI, Software, Apps',
},
{
icon: 'heart-o',
name: 'spirituality',
description: 'Religion, Werte, Ethik',
},
{
icon: 'music',
name: 'culture',
description: 'Kunst, Theater, Musik, Fotografie, Film',
},
{
icon: 'ellipsis-h',
name: 'miscellaneous',
description: '',
},
]

View File

@ -1,6 +1,8 @@
import { getDriver, getNeode } from '../../db/neo4j'
import { hashSync } from 'bcryptjs'
import { v4 as uuid } from 'uuid'
import { categories } from '../../constants/categories'
import CONFIG from '../../config'
const defaultAdmin = {
email: 'admin@example.org',
@ -10,6 +12,29 @@ const defaultAdmin = {
slug: 'admin',
}
const createCategories = async (session) => {
const createCategoriesTxResultPromise = session.writeTransaction(async (txc) => {
categories.forEach(({ icon, name }, index) => {
const id = `cat${index + 1}`
txc.run(
`MERGE (c:Category {
icon: "${icon}",
slug: "${name}",
name: "${name}",
id: "${id}",
createdAt: toString(datetime())
})`,
)
})
})
try {
await createCategoriesTxResultPromise
console.log('Successfully created categories!') // eslint-disable-line no-console
} catch (error) {
console.log(`Error creating categories: ${error}`) // eslint-disable-line no-console
}
}
const createDefaultAdminUser = async (session) => {
const readTxResultPromise = session.readTransaction(async (txc) => {
const result = await txc.run('MATCH (user:User) RETURN count(user) AS userCount')
@ -45,7 +70,7 @@ const createDefaultAdminUser = async (session) => {
})
try {
await createAdminTxResultPromise
console.log('Successfully created default admin user') // eslint-disable-line no-console
console.log('Successfully created default admin user!') // eslint-disable-line no-console
} catch (error) {
console.log(error) // eslint-disable-line no-console
}
@ -58,6 +83,7 @@ class Store {
const { driver } = neode
const session = driver.session()
await createDefaultAdminUser(session)
if (CONFIG.CATEGORIES_ACTIVE) await createCategories(session)
const writeTxResultPromise = session.writeTransaction(async (txc) => {
await txc.run('CALL apoc.schema.assert({},{},true)') // drop all indices and contraints
return Promise.all(

View File

@ -5,6 +5,7 @@ import createServer from '../server'
import faker from '@faker-js/faker'
import Factory from '../db/factories'
import { getNeode, getDriver } from '../db/neo4j'
import { gql } from '../helpers/jest'
import {
createGroupMutation,
joinGroupMutation,
@ -12,6 +13,7 @@ import {
} from './graphql/groups'
import { createPostMutation } from './graphql/posts'
import { createCommentMutation } from './graphql/comments'
import { categories } from '../constants/categories'
if (CONFIG.PRODUCTION && !CONFIG.PRODUCTION_DB_CLEAN_ALLOW) {
throw new Error(`You cannot seed the database in a non-staging and real production environment!`)
@ -273,104 +275,16 @@ const languages = ['de', 'en', 'es', 'fr', 'it', 'pt', 'pl']
dagobert.relateTo(louie, 'blocked'),
])
await Promise.all([
Factory.build('category', {
id: 'cat1',
name: 'Just For Fun',
slug: 'just-for-fun',
icon: 'smile',
await Promise.all(
categories.map(({ icon, name }, index) => {
Factory.build('category', {
id: `cat${index + 1}`,
slug: name,
name,
icon,
})
}),
Factory.build('category', {
id: 'cat2',
name: 'Happiness & Values',
slug: 'happiness-values',
icon: 'heart-o',
}),
Factory.build('category', {
id: 'cat3',
name: 'Health & Wellbeing',
slug: 'health-wellbeing',
icon: 'medkit',
}),
Factory.build('category', {
id: 'cat4',
name: 'Environment & Nature',
slug: 'environment-nature',
icon: 'tree',
}),
Factory.build('category', {
id: 'cat5',
name: 'Animal Protection',
slug: 'animal-protection',
icon: 'paw',
}),
Factory.build('category', {
id: 'cat6',
name: 'Human Rights & Justice',
slug: 'human-rights-justice',
icon: 'balance-scale',
}),
Factory.build('category', {
id: 'cat7',
name: 'Education & Sciences',
slug: 'education-sciences',
icon: 'graduation-cap',
}),
Factory.build('category', {
id: 'cat8',
name: 'Cooperation & Development',
slug: 'cooperation-development',
icon: 'users',
}),
Factory.build('category', {
id: 'cat9',
name: 'Democracy & Politics',
slug: 'democracy-politics',
icon: 'university',
}),
Factory.build('category', {
id: 'cat10',
name: 'Economy & Finances',
slug: 'economy-finances',
icon: 'money',
}),
Factory.build('category', {
id: 'cat11',
name: 'Energy & Technology',
slug: 'energy-technology',
icon: 'flash',
}),
Factory.build('category', {
id: 'cat12',
name: 'IT, Internet & Data Privacy',
slug: 'it-internet-data-privacy',
icon: 'mouse-pointer',
}),
Factory.build('category', {
id: 'cat13',
name: 'Art, Culture & Sport',
slug: 'art-culture-sport',
icon: 'paint-brush',
}),
Factory.build('category', {
id: 'cat14',
name: 'Freedom of Speech',
slug: 'freedom-of-speech',
icon: 'bullhorn',
}),
Factory.build('category', {
id: 'cat15',
name: 'Consumption & Sustainability',
slug: 'consumption-sustainability',
icon: 'shopping-cart',
}),
Factory.build('category', {
id: 'cat16',
name: 'Global Peace & Nonviolence',
slug: 'global-peace-nonviolence',
icon: 'angellist',
}),
])
)
const [environment, nature, democracy, freedom] = await Promise.all([
Factory.build('tag', {

View File

@ -9,8 +9,7 @@ export default {
updatedAt: {
type: 'string',
isoDate: true,
required: true,
default: () => new Date().toISOString(),
required: false,
},
post: {
type: 'relationship',

View File

@ -358,7 +358,7 @@ export default {
undefinedToNull: ['activityId', 'objectId', 'language', 'pinnedAt', 'pinned'],
hasMany: {
tags: '-[:TAGGED]->(related:Tag)',
// categories: '-[:CATEGORIZED]->(related:Category)',
categories: '-[:CATEGORIZED]->(related:Category)',
comments: '<-[:COMMENTS]-(related:Comment)',
shoutedBy: '<-[:SHOUTED]-(related:User)',
emotions: '<-[related:EMOTED]',

View File

@ -0,0 +1,5 @@
<!-- Generated by IcoMoon.io -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
<title>child</title>
<path d="M12 3c2.202 0 3.791 1.007 4.531 2.313 0.026-0.041 0.034-0.084 0.063-0.125 0.453-0.641 1.315-1.188 2.406-1.188v2c-0.453 0-0.588 0.111-0.719 0.281 3.845 0.921 6.812 4.105 7.563 8.063 1.193 0.397 2.156 1.337 2.156 2.656 0 1.365-1.024 2.33-2.281 2.688-0.816 4.701-4.82 8.313-9.719 8.313s-8.903-3.611-9.719-8.313c-1.257-0.357-2.281-1.323-2.281-2.688s1.024-2.33 2.281-2.688c0.741-4.271 4.122-7.637 8.406-8.219-0.39-0.574-1.192-1.094-2.688-1.094v-2zM16 8c-4.093 0-7.461 3.121-7.906 7.125l-0.094 0.875h-1c-0.555 0-1 0.445-1 1s0.445 1 1 1h1l0.094 0.875c0.445 4.004 3.813 7.125 7.906 7.125s7.461-3.121 7.906-7.125l0.094-0.875h1c0.555 0 1-0.445 1-1s-0.445-1-1-1h-0.875l-0.125-0.875c-0.536-4.019-3.907-7.125-8-7.125zM12.5 16c0.828 0 1.5 0.672 1.5 1.5s-0.672 1.5-1.5 1.5-1.5-0.672-1.5-1.5 0.672-1.5 1.5-1.5zM19.5 16c0.828 0 1.5 0.672 1.5 1.5s-0.672 1.5-1.5 1.5-1.5-0.672-1.5-1.5 0.672-1.5 1.5-1.5z"></path>
</svg>

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

@ -0,0 +1,5 @@
<!-- Generated by IcoMoon.io -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
<title>desktop</title>
<path d="M2 6h28v18h-13v2h5v2h-12v-2h5v-2h-13v-18zM4 8v14h24v-14h-24z"></path>
</svg>

After

Width:  |  Height:  |  Size: 240 B

View File

@ -0,0 +1,5 @@
<!-- Generated by IcoMoon.io -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
<title>ellipsis-h</title>
<path d="M6 14c1.105 0 2 0.895 2 2s-0.895 2-2 2-2-0.895-2-2 0.895-2 2-2zM16 14c1.105 0 2 0.895 2 2s-0.895 2-2 2-2-0.895-2-2 0.895-2 2-2zM26 14c1.105 0 2 0.895 2 2s-0.895 2-2 2-2-0.895-2-2 0.895-2 2-2z"></path>
</svg>

After

Width:  |  Height:  |  Size: 374 B

View File

@ -0,0 +1,5 @@
<!-- Generated by IcoMoon.io -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
<title>home</title>
<path d="M16 2.594l0.719 0.688 13 13-1.438 1.438-1.281-1.281v11.563h-9v-10h-4v10h-9v-11.563l-1.281 1.281-1.438-1.438 13-13zM16 5.438l-9 9v11.563h5v-10h8v10h5v-11.563z"></path>
</svg>

After

Width:  |  Height:  |  Size: 334 B

View File

@ -0,0 +1,5 @@
<!-- Generated by IcoMoon.io -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
<title>lightbulb-o</title>
<path d="M6.813 2.406l2.094 2.094-1.406 1.406-2.094-2.094zM25.188 2.406l1.406 1.406-2.094 2.094-1.406-1.406zM16 3.031c4.934-0.047 9 4.027 9 8.969 0 2.706-1.249 5.062-2.906 6.719-1.238 1.15-2 2.627-2 4.094v1.188h-0.094v4h-2.281c-0.347 0.597-0.982 1-1.719 1s-1.372-0.403-1.719-1h-2.281v-6c-0.203-1.117-0.794-2.212-1.75-3.031-2.233-1.898-3.573-4.845-3.125-8.094 0.561-4.039 3.789-7.316 7.844-7.781 0.011-0.001 0.020 0.001 0.031 0 0.336-0.041 0.671-0.059 1-0.063zM16 5.031c-0.258 0.004-0.518 0.030-0.781 0.063-3.131 0.348-5.687 2.881-6.125 6.031-0.352 2.552 0.702 4.811 2.469 6.313 1.388 1.19 2.124 2.848 2.344 4.563h4.375c0.236-1.792 1.094-3.434 2.438-4.688l-0.031-0.031c1.343-1.343 2.313-3.187 2.313-5.281 0-3.861-3.135-7.024-7-6.969zM2 12h3v2h-3v-2zM27 12h3v2h-3v-2zM7.5 20.094l1.406 1.406-2.094 2.094-1.406-1.406zM24.5 20.094l2.094 2.094-1.406 1.406-2.094-2.094zM14 24v2h4v-2h-4z"></path>
</svg>

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 26.4.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="24px" height="24.3px" viewBox="0 0 24 24.3" style="enable-background:new 0 0 24 24.3;" xml:space="preserve">
<style type="text/css">
.st0{fill:#333333;}
</style>
<g>
<circle class="st0" cx="17.1" cy="2.9" r="2.9"/>
<path class="st0" d="M23.5,5.6L23.5,5.6c-0.6-0.5-1.4-0.5-2,0.1l-2.7,3l-2.2-1.4c0.1,0.3,0.1,0.6,0.1,0.9c0,0.6-0.2,1.1-0.5,1.6
L16,10.2l1.5,1c0.4,0.3,0.9,0.4,1.4,0.4c0.1,0,0.2,0,0.4,0c0.6-0.1,1.2-0.4,1.6-0.9l2.7-3.1C24.2,7,24.1,6.1,23.5,5.6z"/>
<path class="st0" d="M6.5,17c-0.3-0.2-0.5-0.5-0.7-0.8c0,0,0,0,0,0L4.6,19l-4,2.7C0,22.1-0.2,23,0.2,23.6l0,0
c0.4,0.6,1.3,0.8,1.9,0.4l4.7-3.2l1.4-3.3l-0.7-0.1C7.2,17.4,6.8,17.2,6.5,17z"/>
<path class="st0" d="M16.3,15.1l-4.4-0.5l3.5-4.7l0.3-0.4C16,9,16.2,8.6,16.2,8.2c0-0.7-0.4-1.4-1-1.7c-0.1,0-0.1-0.1-0.2-0.1
l-1.8-0.7L9.4,4.4C9.1,4.3,8.8,4.3,8.5,4.3c-0.3,0-0.5,0-0.8,0.1c-0.5,0.2-1,0.5-1.3,0.9L3.7,8.5C3.2,9.1,3.3,10,3.9,10.5l0,0
c0.3,0.2,0.6,0.3,0.9,0.3c0.4,0,0.8-0.2,1.1-0.5L8.6,7L11.4,8l-4.8,6.5l0,0c-0.1,0.1-0.1,0.3-0.2,0.4c-0.2,0.8,0.4,1.7,1.3,1.8
l0.9,0.1l6.9,0.9l-1.7,2.7c-0.4,0.7-0.2,1.5,0.5,1.9h0c0.2,0.1,0.5,0.2,0.7,0.2c0.5,0,0.9-0.2,1.2-0.7l2-3.2
c0.4-0.7,0.5-1.6,0.1-2.3C17.8,15.7,17.1,15.2,16.3,15.1z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@ -0,0 +1,5 @@
<!-- Generated by IcoMoon.io -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
<title>music</title>
<path d="M27 3.781v17.219c0 2.197-1.803 4-4 4s-4-1.803-4-4 1.803-4 4-4c0.732 0 1.407 0.214 2 0.563v-7.375l-14 2.625v11.188c0 2.197-1.803 4-4 4s-4-1.803-4-4 1.803-4 4-4c0.732 0 1.407 0.214 2 0.563v-13.406l0.813-0.125 16-3zM25 6.188l-14 2.625v2l14-2.625v-2zM23 19c-1.116 0-2 0.884-2 2s0.884 2 2 2 2-0.884 2-2-0.884-2-2-2zM7 22c-1.116 0-2 0.884-2 2s0.884 2 2 2 2-0.884 2-2-0.884-2-2-2z"></path>
</svg>

After

Width:  |  Height:  |  Size: 551 B

View File

@ -0,0 +1,5 @@
<!-- Generated by IcoMoon.io -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
<title>suitcase</title>
<path d="M14 3h4c1.093 0 2 0.907 2 2v1h3v-1h2v1h2c1.093 0 2 0.907 2 2v16c0 1.093-0.907 2-2 2h-22c-1.093 0-2-0.907-2-2v-16c0-1.093 0.907-2 2-2h2v-1h2v1h3v-1c0-1.093 0.907-2 2-2zM14 5v1h4v-1h-4zM5 8v16h2v-15h2v15h14v-15h2v15h2v-16h-22z"></path>
</svg>

After

Width:  |  Height:  |  Size: 405 B

View File

@ -8,6 +8,9 @@ let wrapper
describe('FilterMenu.vue', () => {
const mocks = {
$t: jest.fn((string) => string),
$env: {
CATEGORIES_ACTIVE: true,
},
}
const getters = {

View File

@ -14,6 +14,7 @@
<div class="filter-menu-options">
<h2 class="title">{{ $t('filter-menu.filter-by') }}</h2>
<following-filter />
<categories-filter v-if="categoriesActive" />
</div>
<div class="filter-menu-options">
<h2 class="title">{{ $t('filter-menu.order-by') }}</h2>
@ -28,17 +29,24 @@ import Dropdown from '~/components/Dropdown'
import { mapGetters } from 'vuex'
import FollowingFilter from './FollowingFilter'
import OrderByFilter from './OrderByFilter'
import CategoriesFilter from './CategoriesFilter'
export default {
components: {
Dropdown,
FollowingFilter,
CategoriesFilter,
OrderByFilter,
},
props: {
placement: { type: String },
offset: { type: [String, Number] },
},
data() {
return {
categoriesActive: this.$env.CATEGORIES_ACTIVE,
}
},
computed: {
...mapGetters({
filterActive: 'posts/isActive',

View File

@ -218,22 +218,25 @@
},
"category": {
"name": {
"animal-protection": "Schutz der Tiere",
"art-culture-sport": "Kunst, Kultur & Sport",
"consumption-sustainability": "Verbrauch & Nachhaltigkeit",
"cooperation-development": "Zusammenarbeit & Entwicklung",
"democracy-politics": "Demokratie & Politik",
"economy-finances": "Wirtschaft & Finanzen",
"education-sciences": "Bildung & Wissenschaft",
"energy-technology": "Energie & Technologie",
"environment-nature": "Umwelt & Natur",
"freedom-of-speech": "Redefreiheit",
"global-peace-nonviolence": "Globaler Frieden & Gewaltlosigkeit",
"happiness-values": "Glück & Werte",
"health-wellbeing": "Gesundheit & Wohlbefinden",
"human-rights-justice": "Menschenrechte & Gerechtigkeit",
"it-internet-data-privacy": "IT, Internet & Datenschutz",
"just-for-fun": "Nur zum Spaß"
"body-and-excercise": "Körper & Bewegung",
"children": "Kinder",
"culture": "Kultur",
"economy": "Wirtschaft",
"energy": "Energie",
"finance": "Finanzen",
"health": "Gesundheit",
"home": "Wohnen",
"it-and-media": "IT & Medien",
"law": "Recht",
"miscellaneous": "Sonstiges",
"mobility": "Mobilität",
"nature": "Natur",
"networking": "Vernetzung",
"peace": "Frieden",
"politics": "Politik",
"psyche": "Psyche",
"science": "Wissenschaft",
"spirituality": "Spiritualität"
}
},
"emotions-label": {

View File

@ -218,22 +218,25 @@
},
"category": {
"name": {
"animal-protection": "Animal Protection",
"art-culture-sport": "Art, Culture, & Sport",
"consumption-sustainability": "Consumption & Sustainability",
"cooperation-development": "Cooperation & Development",
"democracy-politics": "Democracy & Politics",
"economy-finances": "Economy & Finances",
"education-sciences": "Education & Sciences",
"energy-technology": "Energy & Technology",
"environment-nature": "Environment & Nature",
"freedom-of-speech": "Freedom of Speech",
"global-peace-nonviolence": "Global Peace & Nonviolence",
"happiness-values": "Happiness & Values",
"health-wellbeing": "Health & Wellbeing",
"human-rights-justice": "Human Rights & Justice",
"it-internet-data-privacy": "IT, Internet & Data Privacy",
"just-for-fun": "Just for Fun"
"body-and-excercise": "Body & Excercise",
"children": "Children",
"culture": "Culture",
"economy": "Economy",
"energy": "Energy",
"finance": "Finance",
"health": "Health",
"home": "Home",
"it-and-media": "IT & Media",
"law": "Law",
"miscellaneous": "Miscellaneous",
"mobility": "Mobility",
"nature": "Nature",
"networking": "Networking",
"peace": "Peace",
"politics": "Politics",
"psyche": "Psyche",
"science": "Science",
"spirituality": "Spirituality"
}
},
"emotions-label": {