mirror of
https://github.com/Ocelot-Social-Community/Ocelot-Social.git
synced 2025-12-13 07:46:06 +00:00
Merge branch 'master' of github.com:Human-Connection/Human-Connection into dependabot/npm_and_yarn/webapp/prettier-1.17.1-fix_incompatibility
This commit is contained in:
commit
f732ff44d0
@ -22,7 +22,7 @@ install:
|
|||||||
script:
|
script:
|
||||||
# Backend
|
# Backend
|
||||||
- docker-compose exec backend yarn run lint
|
- docker-compose exec backend yarn run lint
|
||||||
- docker-compose exec backend yarn run test:jest --ci --verbose=false
|
- docker-compose exec backend yarn run test:jest --ci --verbose=false --coverage
|
||||||
- docker-compose exec backend yarn run db:reset
|
- docker-compose exec backend yarn run db:reset
|
||||||
- docker-compose exec backend yarn run db:seed
|
- docker-compose exec backend yarn run db:seed
|
||||||
- docker-compose exec backend yarn run test:cucumber
|
- docker-compose exec backend yarn run test:cucumber
|
||||||
@ -30,7 +30,7 @@ script:
|
|||||||
- docker-compose exec backend yarn run db:seed
|
- docker-compose exec backend yarn run db:seed
|
||||||
# Frontend
|
# Frontend
|
||||||
- docker-compose exec webapp yarn run lint
|
- docker-compose exec webapp yarn run lint
|
||||||
- docker-compose exec webapp yarn run test --ci --verbose=false
|
- docker-compose exec webapp yarn run test --ci --verbose=false --coverage
|
||||||
- docker-compose exec -d backend yarn run test:before:seeder
|
- docker-compose exec -d backend yarn run test:before:seeder
|
||||||
# Fullstack
|
# Fullstack
|
||||||
- CYPRESS_RETRIES=1 yarn run cypress:run
|
- CYPRESS_RETRIES=1 yarn run cypress:run
|
||||||
|
|||||||
@ -26,7 +26,6 @@
|
|||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"jest": {
|
"jest": {
|
||||||
"verbose": true,
|
"verbose": true,
|
||||||
"collectCoverage": true,
|
|
||||||
"collectCoverageFrom": [
|
"collectCoverageFrom": [
|
||||||
"**/*.js",
|
"**/*.js",
|
||||||
"!**/node_modules/**",
|
"!**/node_modules/**",
|
||||||
@ -106,7 +105,7 @@
|
|||||||
"graphql-request": "~1.8.2",
|
"graphql-request": "~1.8.2",
|
||||||
"jest": "~24.8.0",
|
"jest": "~24.8.0",
|
||||||
"nodemon": "~1.19.1",
|
"nodemon": "~1.19.1",
|
||||||
"prettier": "~1.14.3",
|
"prettier": "~1.17.1",
|
||||||
"supertest": "~4.0.2"
|
"supertest": "~4.0.2"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,9 +1,9 @@
|
|||||||
import { rule, shield, allow, or } from 'graphql-shield'
|
import { rule, shield, allow, or } from 'graphql-shield'
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* TODO: implement
|
* TODO: implement
|
||||||
* See: https://github.com/Human-Connection/Nitro-Backend/pull/40#pullrequestreview-180898363
|
* See: https://github.com/Human-Connection/Nitro-Backend/pull/40#pullrequestreview-180898363
|
||||||
*/
|
*/
|
||||||
const isAuthenticated = rule()(async (parent, args, ctx, info) => {
|
const isAuthenticated = rule()(async (parent, args, ctx, info) => {
|
||||||
return ctx.user !== null
|
return ctx.user !== null
|
||||||
})
|
})
|
||||||
|
|||||||
@ -6233,10 +6233,10 @@ prettier-linter-helpers@^1.0.0:
|
|||||||
dependencies:
|
dependencies:
|
||||||
fast-diff "^1.1.2"
|
fast-diff "^1.1.2"
|
||||||
|
|
||||||
prettier@~1.14.3:
|
prettier@~1.17.1:
|
||||||
version "1.14.3"
|
version "1.17.1"
|
||||||
resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.14.3.tgz#90238dd4c0684b7edce5f83b0fb7328e48bd0895"
|
resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.17.1.tgz#ed64b4e93e370cb8a25b9ef7fef3e4fd1c0995db"
|
||||||
integrity sha512-qZDVnCrnpsRJJq5nSsiHCE3BYMED2OtsI+cmzIzF1QIfqm5ALf8tEJcO27zV1gKNKRPdhjO0dNWnrzssDQ1tFg==
|
integrity sha512-TzGRNvuUSmPgwivDqkZ9tM/qTGW9hqDKWOE9YHiyQdixlKbv7kvEqsmDPrcHJTKwthU774TQwZXVtaQ/mMsvjg==
|
||||||
|
|
||||||
pretty-format@^24.8.0:
|
pretty-format@^24.8.0:
|
||||||
version "24.8.0"
|
version "24.8.0"
|
||||||
|
|||||||
@ -8,5 +8,5 @@ do
|
|||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
/migration/mongo/import.sh
|
/migration/mongo/export.sh
|
||||||
/migration/neo4j/import.sh
|
/migration/neo4j/import.sh
|
||||||
|
|||||||
@ -0,0 +1,16 @@
|
|||||||
|
# SSH Access
|
||||||
|
# SSH_USERNAME='username'
|
||||||
|
# SSH_HOST='example.org'
|
||||||
|
|
||||||
|
# Mongo DB on Remote Maschine
|
||||||
|
# MONGODB_USERNAME='mongouser'
|
||||||
|
# MONGODB_PASSWORD='mongopassword'
|
||||||
|
# MONGODB_DATABASE='mongodatabase'
|
||||||
|
# MONGODB_AUTH_DB='admin'
|
||||||
|
|
||||||
|
# Export Settings
|
||||||
|
# On Windows this resolves to C:\Users\dornhoeschen\AppData\Local\Temp\mongo-export (MinGW)
|
||||||
|
EXPORT_PATH='/tmp/mongo-export/'
|
||||||
|
EXPORT_MONGOEXPORT_BIN='mongoexport'
|
||||||
|
# On Windows use something like this
|
||||||
|
# EXPORT_MONGOEXPORT_BIN='C:\Program Files\MongoDB\Server\3.6\bin\mongoexport.exe'
|
||||||
45
deployment/legacy-migration/maintenance-worker/migration/mongo/export.sh
Executable file
45
deployment/legacy-migration/maintenance-worker/migration/mongo/export.sh
Executable file
@ -0,0 +1,45 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# import .env config
|
||||||
|
set -o allexport
|
||||||
|
source $(dirname "$0")/.env
|
||||||
|
set +o allexport
|
||||||
|
|
||||||
|
# Export collection function defintion
|
||||||
|
function export_collection () {
|
||||||
|
"${EXPORT_MONGOEXPORT_BIN}" --db ${MONGODB_DATABASE} --host localhost -d ${MONGODB_DATABASE} --port 27018 --username ${MONGODB_USERNAME} --password ${MONGODB_PASSWORD} --authenticationDatabase ${MONGODB_AUTH_DB} --collection $1 --collection $1 --out "${EXPORT_PATH}$1.json"
|
||||||
|
mkdir -p ${EXPORT_PATH}splits/$1/
|
||||||
|
split -l 1000 -a 3 ${EXPORT_PATH}$1.json ${EXPORT_PATH}splits/$1/
|
||||||
|
}
|
||||||
|
|
||||||
|
# Delete old export & ensure directory
|
||||||
|
rm -rf ${EXPORT_PATH}*
|
||||||
|
mkdir -p ${EXPORT_PATH}
|
||||||
|
|
||||||
|
# Open SSH Tunnel
|
||||||
|
ssh -4 -M -S my-ctrl-socket -fnNT -L 27018:localhost:27017 -l ${SSH_USERNAME} ${SSH_HOST}
|
||||||
|
|
||||||
|
# Export all Data from the Alpha to json and split them up
|
||||||
|
export_collection "badges"
|
||||||
|
export_collection "categories"
|
||||||
|
export_collection "comments"
|
||||||
|
export_collection "contributions"
|
||||||
|
export_collection "emotions"
|
||||||
|
export_collection "follows"
|
||||||
|
export_collection "invites"
|
||||||
|
export_collection "notifications"
|
||||||
|
export_collection "organizations"
|
||||||
|
export_collection "pages"
|
||||||
|
export_collection "projects"
|
||||||
|
export_collection "settings"
|
||||||
|
export_collection "shouts"
|
||||||
|
export_collection "status"
|
||||||
|
export_collection "systemnotifications"
|
||||||
|
export_collection "users"
|
||||||
|
export_collection "userscandos"
|
||||||
|
export_collection "usersettings"
|
||||||
|
|
||||||
|
# Close SSH Tunnel
|
||||||
|
ssh -S my-ctrl-socket -O check -l ${SSH_USERNAME} ${SSH_HOST}
|
||||||
|
ssh -S my-ctrl-socket -O exit -l ${SSH_USERNAME} ${SSH_HOST}
|
||||||
@ -1,26 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
set -e
|
|
||||||
|
|
||||||
echo "SSH_USERNAME ${SSH_USERNAME}"
|
|
||||||
echo "SSH_HOST ${SSH_HOST}"
|
|
||||||
echo "MONGODB_USERNAME ${MONGODB_USERNAME}"
|
|
||||||
echo "MONGODB_PASSWORD ${MONGODB_PASSWORD}"
|
|
||||||
echo "MONGODB_DATABASE ${MONGODB_DATABASE}"
|
|
||||||
echo "MONGODB_AUTH_DB ${MONGODB_AUTH_DB}"
|
|
||||||
echo "-------------------------------------------------"
|
|
||||||
|
|
||||||
|
|
||||||
rm -rf /tmp/mongo-export/*
|
|
||||||
mkdir -p /tmp/mongo-export/
|
|
||||||
|
|
||||||
ssh -4 -M -S my-ctrl-socket -fnNT -L 27018:localhost:27017 -l ${SSH_USERNAME} ${SSH_HOST}
|
|
||||||
|
|
||||||
for collection in "categories" "badges" "users" "contributions" "comments" "follows" "shouts"
|
|
||||||
do
|
|
||||||
mongoexport --db ${MONGODB_DATABASE} --host localhost -d ${MONGODB_DATABASE} --port 27018 --username ${MONGODB_USERNAME} --password ${MONGODB_PASSWORD} --authenticationDatabase ${MONGODB_AUTH_DB} --collection $collection --collection $collection --out "/tmp/mongo-export/$collection.json"
|
|
||||||
mkdir -p /tmp/mongo-export/splits/$collection/
|
|
||||||
split -l 1000 -a 3 /tmp/mongo-export/$collection.json /tmp/mongo-export/splits/$collection/
|
|
||||||
done
|
|
||||||
|
|
||||||
ssh -S my-ctrl-socket -O check -l ${SSH_USERNAME} ${SSH_HOST}
|
|
||||||
ssh -S my-ctrl-socket -O exit -l ${SSH_USERNAME} ${SSH_HOST}
|
|
||||||
@ -0,0 +1,16 @@
|
|||||||
|
# Neo4J Settings
|
||||||
|
# NEO4J_USERNAME='neo4j'
|
||||||
|
# NEO4J_PASSWORD='letmein'
|
||||||
|
|
||||||
|
# Import Settings
|
||||||
|
# On Windows this resolves to C:\Users\dornhoeschen\AppData\Local\Temp\mongo-export (MinGW)
|
||||||
|
IMPORT_PATH='/tmp/mongo-export/'
|
||||||
|
IMPORT_CHUNK_PATH='/tmp/mongo-export/splits/current-chunk.json'
|
||||||
|
|
||||||
|
IMPORT_CHUNK_PATH_CQL='/tmp/mongo-export/splits/current-chunk.json'
|
||||||
|
# On Windows this path needs to be windows style since the cypher-shell runs native - note the forward slash
|
||||||
|
# IMPORT_CHUNK_PATH_CQL='C:/Users/dornhoeschen/AppData/Local/Temp/mongo-export/splits/current-chunk.json'
|
||||||
|
|
||||||
|
IMPORT_CYPHERSHELL_BIN='cypher-shell'
|
||||||
|
# On Windows use something like this
|
||||||
|
# IMPORT_CYPHERSHELL_BIN='C:\Program Files\neo4j-community\bin\cypher-shell.bat'
|
||||||
@ -1,4 +1,4 @@
|
|||||||
CALL apoc.load.json('file:/tmp/mongo-export/splits/current-chunk.json') YIELD value as badge
|
CALL apoc.load.json("file:${IMPORT_CHUNK_PATH_CQL}") YIELD value as badge
|
||||||
MERGE(b:Badge {id: badge._id["$oid"]})
|
MERGE(b:Badge {id: badge._id["$oid"]})
|
||||||
ON CREATE SET
|
ON CREATE SET
|
||||||
b.key = badge.key,
|
b.key = badge.key,
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
CALL apoc.load.json('file:/tmp/mongo-export/splits/current-chunk.json') YIELD value as category
|
CALL apoc.load.json("file:${IMPORT_CHUNK_PATH_CQL}") YIELD value as category
|
||||||
MERGE(c:Category {id: category._id["$oid"]})
|
MERGE(c:Category {id: category._id["$oid"]})
|
||||||
ON CREATE SET
|
ON CREATE SET
|
||||||
c.name = category.title,
|
c.name = category.title,
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
CALL apoc.load.json('file:/tmp/mongo-export/splits/current-chunk.json') YIELD value as json
|
CALL apoc.load.json("file:${IMPORT_CHUNK_PATH_CQL}") YIELD value as json
|
||||||
|
|
||||||
MERGE (comment:Comment {id: json._id["$oid"]})
|
MERGE (comment:Comment {id: json._id["$oid"]})
|
||||||
ON CREATE SET
|
ON CREATE SET
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
CALL apoc.load.json('file:/tmp/mongo-export/splits/current-chunk.json') YIELD value as post
|
CALL apoc.load.json("file:${IMPORT_CHUNK_PATH_CQL}") YIELD value as post
|
||||||
MERGE (p:Post {id: post._id["$oid"]})
|
MERGE (p:Post {id: post._id["$oid"]})
|
||||||
ON CREATE SET
|
ON CREATE SET
|
||||||
p.title = post.title,
|
p.title = post.title,
|
||||||
@ -20,6 +20,6 @@ MATCH (c:Category {id: categoryId})
|
|||||||
MERGE (p)-[:CATEGORIZED]->(c)
|
MERGE (p)-[:CATEGORIZED]->(c)
|
||||||
WITH p, post.tags AS tags
|
WITH p, post.tags AS tags
|
||||||
UNWIND tags AS tag
|
UNWIND tags AS tag
|
||||||
MERGE (t:Tag {id: apoc.create.uuid(), name: tag})
|
MERGE (t:Tag {id: tag, name: tag})
|
||||||
MERGE (p)-[:TAGGED]->(t)
|
MERGE (p)-[:TAGGED]->(t)
|
||||||
;
|
;
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
CALL apoc.load.json('file:/tmp/mongo-export/splits/current-chunk.json') YIELD value as follow
|
CALL apoc.load.json("file:${IMPORT_CHUNK_PATH_CQL}") YIELD value as follow
|
||||||
MATCH (u1:User {id: follow.userId}), (u2:User {id: follow.foreignId})
|
MATCH (u1:User {id: follow.userId}), (u2:User {id: follow.foreignId})
|
||||||
MERGE (u1)-[:FOLLOWS]->(u2)
|
MERGE (u1)-[:FOLLOWS]->(u2)
|
||||||
;
|
;
|
||||||
|
|||||||
@ -1,17 +1,48 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
SECONDS=0
|
# import .env config
|
||||||
SCRIPT_DIRECTORY="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
|
set -o allexport
|
||||||
|
source $(dirname "$0")/.env
|
||||||
|
set +o allexport
|
||||||
|
|
||||||
echo "MATCH (n) DETACH DELETE n;" | cypher-shell
|
# Import collection function defintion
|
||||||
|
function import_collection () {
|
||||||
for collection in "badges" "categories" "users" "follows" "contributions" "shouts" "comments"
|
for chunk in ${IMPORT_PATH}splits/$1/*
|
||||||
do
|
|
||||||
for chunk in /tmp/mongo-export/splits/$collection/*
|
|
||||||
do
|
do
|
||||||
mv $chunk /tmp/mongo-export/splits/current-chunk.json
|
mv $chunk ${IMPORT_CHUNK_PATH}
|
||||||
echo "Import ${chunk}" && cypher-shell < $SCRIPT_DIRECTORY/$collection.cql
|
NEO4J_COMMAND="$(envsubst '${IMPORT_CHUNK_PATH_CQL}' < $(dirname "$0")/$1.cql)"
|
||||||
|
echo "Import ${chunk}"
|
||||||
|
echo "${NEO4J_COMMAND}" | "${IMPORT_CYPHERSHELL_BIN}" -u ${NEO4J_USERNAME} -p ${NEO4J_PASSWORD}
|
||||||
done
|
done
|
||||||
done
|
}
|
||||||
|
|
||||||
|
# Time variable
|
||||||
|
SECONDS=0
|
||||||
|
|
||||||
|
# Delete all Neo4J Database content
|
||||||
|
echo "Deleting Database Contents"
|
||||||
|
echo "MATCH (n) DETACH DELETE n;" | "${IMPORT_CYPHERSHELL_BIN}" -u ${NEO4J_USERNAME} -p ${NEO4J_PASSWORD}
|
||||||
|
|
||||||
|
# Import Data
|
||||||
|
echo "Start Importing Data"
|
||||||
|
import_collection "badges"
|
||||||
|
import_collection "categories"
|
||||||
|
import_collection "users"
|
||||||
|
import_collection "follows"
|
||||||
|
import_collection "contributions"
|
||||||
|
import_collection "shouts"
|
||||||
|
import_collection "comments"
|
||||||
|
#import_collection "emotions"
|
||||||
|
#import_collection "invites"
|
||||||
|
#import_collection "notifications"
|
||||||
|
#import_collection "organizations"
|
||||||
|
#import_collection "pages"
|
||||||
|
#import_collection "projects"
|
||||||
|
#import_collection "settings"
|
||||||
|
#import_collection "status"
|
||||||
|
#import_collection "systemnotifications"
|
||||||
|
#import_collection "userscandos"
|
||||||
|
#import_collection "usersettings"
|
||||||
|
|
||||||
echo "Time elapsed: $SECONDS seconds"
|
echo "Time elapsed: $SECONDS seconds"
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
CALL apoc.load.json('file:/tmp/mongo-export/splits/current-chunk.json') YIELD value as shout
|
CALL apoc.load.json("file:${IMPORT_CHUNK_PATH_CQL}") YIELD value as shout
|
||||||
MATCH (u:User {id: shout.userId}), (p:Post {id: shout.foreignId})
|
MATCH (u:User {id: shout.userId}), (p:Post {id: shout.foreignId})
|
||||||
MERGE (u)-[:SHOUTED]->(p)
|
MERGE (u)-[:SHOUTED]->(p)
|
||||||
;
|
;
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
CALL apoc.load.json('file:/tmp/mongo-export/splits/current-chunk.json') YIELD value as user
|
CALL apoc.load.json("file:${IMPORT_CHUNK_PATH_CQL}") YIELD value as user
|
||||||
MERGE(u:User {id: user._id["$oid"]})
|
MERGE(u:User {id: user._id["$oid"]})
|
||||||
ON CREATE SET
|
ON CREATE SET
|
||||||
u.name = user.name,
|
u.name = user.name,
|
||||||
|
|||||||
69
webapp/components/Avatar/Avatar.spec.js
Normal file
69
webapp/components/Avatar/Avatar.spec.js
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
import { mount, createLocalVue } from '@vue/test-utils'
|
||||||
|
import Styleguide from '@human-connection/styleguide'
|
||||||
|
import Avatar from './Avatar.vue'
|
||||||
|
|
||||||
|
const localVue = createLocalVue()
|
||||||
|
localVue.use(Styleguide)
|
||||||
|
|
||||||
|
describe('Avatar.vue', () => {
|
||||||
|
let propsData = {}
|
||||||
|
|
||||||
|
const Wrapper = () => {
|
||||||
|
return mount(Avatar, { propsData, localVue })
|
||||||
|
}
|
||||||
|
|
||||||
|
it('renders no image', () => {
|
||||||
|
expect(
|
||||||
|
Wrapper()
|
||||||
|
.find('img')
|
||||||
|
.exists(),
|
||||||
|
).toBe(false)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('renders an icon', () => {
|
||||||
|
expect(
|
||||||
|
Wrapper()
|
||||||
|
.find('.ds-icon')
|
||||||
|
.exists(),
|
||||||
|
).toBe(true)
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('given a user', () => {
|
||||||
|
describe('with a relative avatar url', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
propsData = {
|
||||||
|
user: {
|
||||||
|
avatar: '/avatar.jpg',
|
||||||
|
},
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
it('adds a prefix to load the image from the uploads service', () => {
|
||||||
|
expect(
|
||||||
|
Wrapper()
|
||||||
|
.find('img')
|
||||||
|
.attributes('src'),
|
||||||
|
).toBe('/api/avatar.jpg')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('with an absolute avatar url', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
propsData = {
|
||||||
|
user: {
|
||||||
|
avatar: 'http://lorempixel.com/640/480/animals',
|
||||||
|
},
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
it('keeps the avatar URL as is', () => {
|
||||||
|
// e.g. our seeds have absolute image URLs
|
||||||
|
expect(
|
||||||
|
Wrapper()
|
||||||
|
.find('img')
|
||||||
|
.attributes('src'),
|
||||||
|
).toBe('http://lorempixel.com/640/480/animals')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
28
webapp/components/Avatar/Avatar.vue
Normal file
28
webapp/components/Avatar/Avatar.vue
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
<template>
|
||||||
|
<ds-avatar :image="avatarUrl" :name="userName" class="avatar" :size="size" />
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'HcAvatar',
|
||||||
|
props: {
|
||||||
|
user: { type: Object, default: null },
|
||||||
|
size: { type: String, default: 'small' },
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
avatarUrl() {
|
||||||
|
const { avatar: imageSrc } = this.user || {}
|
||||||
|
if (!imageSrc) return imageSrc
|
||||||
|
return imageSrc.startsWith('/') ? imageSrc.replace('/', '/api/') : imageSrc
|
||||||
|
},
|
||||||
|
userName() {
|
||||||
|
const { name } = this.user || {}
|
||||||
|
// The name is used to display the initials in case
|
||||||
|
// the image cannot be loaded.
|
||||||
|
return name
|
||||||
|
// If the name is undefined, then our styleguide will
|
||||||
|
// display an icon for the anonymous user.
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
@ -317,10 +317,18 @@ export default {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
mounted() {
|
||||||
|
this.$root.$on('changeLanguage', () => {
|
||||||
|
this.changePlaceHolderText()
|
||||||
|
})
|
||||||
|
},
|
||||||
beforeDestroy() {
|
beforeDestroy() {
|
||||||
this.editor.destroy()
|
this.editor.destroy()
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
changePlaceHolderText() {
|
||||||
|
this.editor.extensions.options.placeholder.emptyNodeText = this.$t('editor.placeholder')
|
||||||
|
},
|
||||||
// navigate to the previous item
|
// navigate to the previous item
|
||||||
// if it's the first item, navigate to the last one
|
// if it's the first item, navigate to the last one
|
||||||
upHandler() {
|
upHandler() {
|
||||||
|
|||||||
@ -68,6 +68,7 @@ export default {
|
|||||||
changeLanguage(locale, toggleMenu) {
|
changeLanguage(locale, toggleMenu) {
|
||||||
this.$i18n.set(locale)
|
this.$i18n.set(locale)
|
||||||
toggleMenu()
|
toggleMenu()
|
||||||
|
this.$root.$emit('changeLanguage')
|
||||||
},
|
},
|
||||||
matcher(locale) {
|
matcher(locale) {
|
||||||
return locale === this.$i18n.locale()
|
return locale === this.$i18n.locale()
|
||||||
|
|||||||
@ -48,13 +48,6 @@ export default {
|
|||||||
<div class="dz-image">
|
<div class="dz-image">
|
||||||
<div data-dz-thumbnail-bg></div>
|
<div data-dz-thumbnail-bg></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="dz-details">
|
|
||||||
<div class="dz-size"><span data-dz-size></span></div>
|
|
||||||
<div class="dz-filename"><span data-dz-name></span></div>
|
|
||||||
</div>
|
|
||||||
<div class="dz-progress"><span class="dz-upload" data-dz-uploadprogress></span></div>
|
|
||||||
<div class="dz-error-message"><span data-dz-errormessage></span></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
`
|
`
|
||||||
},
|
},
|
||||||
@ -117,15 +110,16 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#customdropzone .dz-preview {
|
#customdropzone .dz-preview {
|
||||||
|
transition: all 0.2s ease-out;
|
||||||
width: 160px;
|
width: 160px;
|
||||||
display: flex;
|
display: flex;
|
||||||
}
|
}
|
||||||
|
|
||||||
#customdropzone .dz-preview .dz-image {
|
#customdropzone .dz-preview .dz-image {
|
||||||
position: relative;
|
width: 100%;
|
||||||
width: 122px;
|
height: 100%;
|
||||||
height: 122px;
|
object-fit: contain;
|
||||||
margin: -35px;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
#customdropzone .dz-preview .dz-image > div {
|
#customdropzone .dz-preview .dz-image > div {
|
||||||
|
|||||||
@ -3,7 +3,7 @@
|
|||||||
<div
|
<div
|
||||||
style="display: inline-block; float: left; margin-right: 4px; height: 100%; vertical-align: middle;"
|
style="display: inline-block; float: left; margin-right: 4px; height: 100%; vertical-align: middle;"
|
||||||
>
|
>
|
||||||
<ds-avatar style="display: inline-block; vertical-align: middle;" size="small" />
|
<hc-avatar />
|
||||||
</div>
|
</div>
|
||||||
<div style="display: inline-block; height: 100%; vertical-align: middle;">
|
<div style="display: inline-block; height: 100%; vertical-align: middle;">
|
||||||
<b class="username" style="vertical-align: middle;">{{ $t('profile.userAnonym') }}</b>
|
<b class="username" style="vertical-align: middle;">{{ $t('profile.userAnonym') }}</b>
|
||||||
@ -16,12 +16,7 @@
|
|||||||
<div
|
<div
|
||||||
style="display: inline-block; float: left; margin-right: 4px; height: 100%; vertical-align: middle;"
|
style="display: inline-block; float: left; margin-right: 4px; height: 100%; vertical-align: middle;"
|
||||||
>
|
>
|
||||||
<ds-avatar
|
<hc-avatar :user="user" />
|
||||||
:image="user.avatar"
|
|
||||||
:name="userName"
|
|
||||||
style="display: inline-block; vertical-align: middle;"
|
|
||||||
size="small"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
<div style="display: inline-block; height: 100%; vertical-align: middle;">
|
<div style="display: inline-block; height: 100%; vertical-align: middle;">
|
||||||
<b class="username" style="vertical-align: middle;">{{ userName | truncate(18) }}</b>
|
<b class="username" style="vertical-align: middle;">{{ userName | truncate(18) }}</b>
|
||||||
@ -102,6 +97,7 @@ import { mapGetters } from 'vuex'
|
|||||||
import HcRelativeDateTime from '~/components/RelativeDateTime'
|
import HcRelativeDateTime from '~/components/RelativeDateTime'
|
||||||
import HcFollowButton from '~/components/FollowButton'
|
import HcFollowButton from '~/components/FollowButton'
|
||||||
import HcBadges from '~/components/Badges'
|
import HcBadges from '~/components/Badges'
|
||||||
|
import HcAvatar from '~/components/Avatar/Avatar.vue'
|
||||||
import Dropdown from '~/components/Dropdown'
|
import Dropdown from '~/components/Dropdown'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
@ -109,6 +105,7 @@ export default {
|
|||||||
components: {
|
components: {
|
||||||
HcRelativeDateTime,
|
HcRelativeDateTime,
|
||||||
HcFollowButton,
|
HcFollowButton,
|
||||||
|
HcAvatar,
|
||||||
HcBadges,
|
HcBadges,
|
||||||
Dropdown,
|
Dropdown,
|
||||||
},
|
},
|
||||||
@ -142,12 +139,6 @@ export default {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
.profile-avatar {
|
|
||||||
display: block;
|
|
||||||
margin: auto;
|
|
||||||
margin-top: -45px;
|
|
||||||
border: #fff 5px solid;
|
|
||||||
}
|
|
||||||
.user {
|
.user {
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|||||||
@ -2,14 +2,7 @@
|
|||||||
<ds-form v-model="form" @submit="handleSubmit">
|
<ds-form v-model="form" @submit="handleSubmit">
|
||||||
<template slot-scope="{ errors }">
|
<template slot-scope="{ errors }">
|
||||||
<ds-card>
|
<ds-card>
|
||||||
<no-ssr>
|
<hc-editor ref="editor" :users="users" :value="form.content" @input="updateEditorContent" />
|
||||||
<hc-editor
|
|
||||||
ref="editor"
|
|
||||||
:users="users"
|
|
||||||
:value="form.content"
|
|
||||||
@input="updateEditorContent"
|
|
||||||
/>
|
|
||||||
</no-ssr>
|
|
||||||
<ds-space />
|
<ds-space />
|
||||||
<ds-flex :gutter="{ base: 'small', md: 'small', sm: 'x-large', xs: 'x-large' }">
|
<ds-flex :gutter="{ base: 'small', md: 'small', sm: 'x-large', xs: 'x-large' }">
|
||||||
<ds-flex-item :width="{ base: '0%', md: '50%', sm: '0%', xs: '0%' }" />
|
<ds-flex-item :width="{ base: '0%', md: '50%', sm: '0%', xs: '0%' }" />
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { config, mount, createLocalVue, createWrapper } from '@vue/test-utils'
|
import { mount, createLocalVue, createWrapper } from '@vue/test-utils'
|
||||||
import CommentForm from './index.vue'
|
import CommentForm from './index.vue'
|
||||||
import Styleguide from '@human-connection/styleguide'
|
import Styleguide from '@human-connection/styleguide'
|
||||||
|
|
||||||
@ -6,8 +6,6 @@ const localVue = createLocalVue()
|
|||||||
|
|
||||||
localVue.use(Styleguide)
|
localVue.use(Styleguide)
|
||||||
|
|
||||||
config.stubs['no-ssr'] = '<span><slot /></span>'
|
|
||||||
|
|
||||||
describe('CommentForm.vue', () => {
|
describe('CommentForm.vue', () => {
|
||||||
let mocks
|
let mocks
|
||||||
let wrapper
|
let wrapper
|
||||||
|
|||||||
@ -33,6 +33,13 @@ describe('CommentList.vue', () => {
|
|||||||
})
|
})
|
||||||
mocks = {
|
mocks = {
|
||||||
$t: jest.fn(),
|
$t: jest.fn(),
|
||||||
|
$apollo: {
|
||||||
|
queries: {
|
||||||
|
Post: {
|
||||||
|
refetch: jest.fn(),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
data = () => {
|
data = () => {
|
||||||
return {
|
return {
|
||||||
@ -63,5 +70,10 @@ describe('CommentList.vue', () => {
|
|||||||
it('displays comments when there are comments to display', () => {
|
it('displays comments when there are comments to display', () => {
|
||||||
expect(wrapper.find('div#comments').text()).toEqual('this is a comment')
|
expect(wrapper.find('div#comments').text()).toEqual('this is a comment')
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it("refetches a post's comments from the backend", () => {
|
||||||
|
wrapper.vm.refetchPostComments()
|
||||||
|
expect(mocks.$apollo.queries.Post.refetch).toHaveBeenCalledTimes(1)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@ -45,13 +45,15 @@ export default {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.$root.$on('refetchPostComments', comment => {
|
this.$root.$on('refetchPostComments', () => {
|
||||||
this.refetchPostComments(comment)
|
this.refetchPostComments()
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
refetchPostComments(comment) {
|
refetchPostComments() {
|
||||||
this.$apollo.queries.Post.refetch()
|
if (this.$apollo.queries.Post) {
|
||||||
|
this.$apollo.queries.Post.refetch()
|
||||||
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
apollo: {
|
apollo: {
|
||||||
|
|||||||
@ -39,7 +39,7 @@
|
|||||||
"
|
"
|
||||||
@click.prevent="toggleMenu"
|
@click.prevent="toggleMenu"
|
||||||
>
|
>
|
||||||
<ds-avatar :image="user.avatar" :name="user.name" size="small" />
|
<hc-avatar :user="user" />
|
||||||
<ds-icon size="xx-small" name="angle-down" />
|
<ds-icon size="xx-small" name="angle-down" />
|
||||||
</a>
|
</a>
|
||||||
</template>
|
</template>
|
||||||
@ -97,6 +97,7 @@ import SearchInput from '~/components/SearchInput.vue'
|
|||||||
import Modal from '~/components/Modal'
|
import Modal from '~/components/Modal'
|
||||||
import NotificationMenu from '~/components/notifications/NotificationMenu'
|
import NotificationMenu from '~/components/notifications/NotificationMenu'
|
||||||
import Dropdown from '~/components/Dropdown'
|
import Dropdown from '~/components/Dropdown'
|
||||||
|
import HcAvatar from '~/components/Avatar/Avatar.vue'
|
||||||
import seo from '~/mixins/seo'
|
import seo from '~/mixins/seo'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
@ -106,6 +107,7 @@ export default {
|
|||||||
SearchInput,
|
SearchInput,
|
||||||
Modal,
|
Modal,
|
||||||
NotificationMenu,
|
NotificationMenu,
|
||||||
|
HcAvatar,
|
||||||
},
|
},
|
||||||
mixins: [seo],
|
mixins: [seo],
|
||||||
data() {
|
data() {
|
||||||
|
|||||||
@ -22,7 +22,6 @@
|
|||||||
},
|
},
|
||||||
"jest": {
|
"jest": {
|
||||||
"verbose": true,
|
"verbose": true,
|
||||||
"collectCoverage": true,
|
|
||||||
"collectCoverageFrom": [
|
"collectCoverageFrom": [
|
||||||
"**/*.{js,vue}",
|
"**/*.{js,vue}",
|
||||||
"!**/node_modules/**",
|
"!**/node_modules/**",
|
||||||
|
|||||||
@ -11,13 +11,7 @@
|
|||||||
style="position: relative; height: auto;"
|
style="position: relative; height: auto;"
|
||||||
>
|
>
|
||||||
<hc-upload v-if="myProfile" :user="user" />
|
<hc-upload v-if="myProfile" :user="user" />
|
||||||
<ds-avatar
|
<hc-avatar v-else :user="user" class="profile-avatar" size="x-large" />
|
||||||
v-else
|
|
||||||
:image="user.avatar"
|
|
||||||
:name="userName"
|
|
||||||
class="profile-avatar"
|
|
||||||
size="x-large"
|
|
||||||
/>
|
|
||||||
<no-ssr>
|
<no-ssr>
|
||||||
<content-menu
|
<content-menu
|
||||||
placement="bottom-end"
|
placement="bottom-end"
|
||||||
@ -28,9 +22,7 @@
|
|||||||
/>
|
/>
|
||||||
</no-ssr>
|
</no-ssr>
|
||||||
<ds-space margin="small">
|
<ds-space margin="small">
|
||||||
<ds-heading tag="h3" align="center" no-margin>
|
<ds-heading tag="h3" align="center" no-margin>{{ userName }}</ds-heading>
|
||||||
{{ userName }}
|
|
||||||
</ds-heading>
|
|
||||||
<ds-text v-if="user.location" align="center" color="soft" size="small">
|
<ds-text v-if="user.location" align="center" color="soft" size="small">
|
||||||
<ds-icon name="map-marker" />
|
<ds-icon name="map-marker" />
|
||||||
{{ user.location.name }}
|
{{ user.location.name }}
|
||||||
@ -70,9 +62,7 @@
|
|||||||
<template v-if="user.about">
|
<template v-if="user.about">
|
||||||
<hr />
|
<hr />
|
||||||
<ds-space margin-top="small" margin-bottom="small">
|
<ds-space margin-top="small" margin-bottom="small">
|
||||||
<ds-text color="soft" size="small">
|
<ds-text color="soft" size="small">{{ user.about }}</ds-text>
|
||||||
{{ user.about }}
|
|
||||||
</ds-text>
|
|
||||||
</ds-space>
|
</ds-space>
|
||||||
</template>
|
</template>
|
||||||
</ds-card>
|
</ds-card>
|
||||||
@ -225,6 +215,7 @@ import HcLoadMore from '~/components/LoadMore.vue'
|
|||||||
import HcEmpty from '~/components/Empty.vue'
|
import HcEmpty from '~/components/Empty.vue'
|
||||||
import ContentMenu from '~/components/ContentMenu'
|
import ContentMenu from '~/components/ContentMenu'
|
||||||
import HcUpload from '~/components/Upload'
|
import HcUpload from '~/components/Upload'
|
||||||
|
import HcAvatar from '~/components/Avatar/Avatar.vue'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
@ -235,6 +226,7 @@ export default {
|
|||||||
HcBadges,
|
HcBadges,
|
||||||
HcLoadMore,
|
HcLoadMore,
|
||||||
HcEmpty,
|
HcEmpty,
|
||||||
|
HcAvatar,
|
||||||
ContentMenu,
|
ContentMenu,
|
||||||
HcUpload,
|
HcUpload,
|
||||||
},
|
},
|
||||||
@ -348,7 +340,7 @@ export default {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
.profile-avatar {
|
.profile-avatar.ds-avatar {
|
||||||
display: block;
|
display: block;
|
||||||
margin: auto;
|
margin: auto;
|
||||||
margin-top: -60px;
|
margin-top: -60px;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user