Merge branch 'master' of https://github.com/Human-Connection/Human-Connection into 1017-send-out-notifications-on-create-omment

This commit is contained in:
Wolfgang Huß 2019-07-15 08:30:10 +02:00
commit 2c9855e584
46 changed files with 691 additions and 1010 deletions

View File

@ -48,7 +48,7 @@
"apollo-client": "~2.6.3",
"apollo-link-context": "~1.0.18",
"apollo-link-http": "~1.5.15",
"apollo-server": "~2.6.8",
"apollo-server": "~2.6.9",
"bcryptjs": "~2.4.3",
"cheerio": "~1.0.0-rc.3",
"cors": "~2.8.5",
@ -68,7 +68,7 @@
"helmet": "~3.18.0",
"jsonwebtoken": "~8.5.1",
"linkifyjs": "~2.1.8",
"lodash": "~4.17.13",
"lodash": "~4.17.14",
"merge-graphql-schemas": "^1.5.8",
"neo4j-driver": "~1.7.4",
"neo4j-graphql-js": "^2.6.3",
@ -81,7 +81,7 @@
"slug": "~1.1.0",
"trunc-html": "~1.1.2",
"uuid": "~3.3.2",
"wait-on": "~3.2.0"
"wait-on": "~3.3.0"
},
"devDependencies": {
"@babel/cli": "~7.5.0",
@ -90,7 +90,7 @@
"@babel/plugin-proposal-throw-expressions": "^7.2.0",
"@babel/preset-env": "~7.5.4",
"@babel/register": "~7.4.4",
"apollo-server-testing": "~2.6.8",
"apollo-server-testing": "~2.6.9",
"babel-core": "~7.0.0-0",
"babel-eslint": "~10.0.2",
"babel-jest": "~24.8.0",

View File

@ -146,6 +146,7 @@ const permissions = shield(
Comment: allow,
User: or(noEmailFilter, isAdmin),
isLoggedIn: allow,
Badge: allow,
},
Mutation: {
'*': deny,
@ -160,9 +161,6 @@ const permissions = shield(
UpdatePost: isAuthor,
DeletePost: isAuthor,
report: isAuthenticated,
CreateBadge: isAdmin,
UpdateBadge: isAdmin,
DeleteBadge: isAdmin,
CreateSocialMedia: isAuthenticated,
DeleteSocialMedia: isAuthenticated,
// AddBadgeRewarded: isAdmin,

View File

@ -1,6 +1,9 @@
import { UserInputError } from 'apollo-server'
import Joi from '@hapi/joi'
const COMMENT_MIN_LENGTH = 1
const NO_POST_ERR_MESSAGE = 'Comment cannot be created without a post!'
const validate = schema => {
return async (resolve, root, args, context, info) => {
const validation = schema.validate(args)
@ -15,8 +18,36 @@ const socialMediaSchema = Joi.object().keys({
.required(),
})
const validateCommentCreation = async (resolve, root, args, context, info) => {
const content = args.content.replace(/<(?:.|\n)*?>/gm, '').trim()
const { postId } = args
if (!args.content || content.length < COMMENT_MIN_LENGTH) {
throw new UserInputError(`Comment must be at least ${COMMENT_MIN_LENGTH} character long!`)
}
const session = context.driver.session()
const postQueryRes = await session.run(
`
MATCH (post:Post {id: $postId})
RETURN post`,
{
postId,
},
)
const [post] = postQueryRes.records.map(record => {
return record.get('post')
})
if (!post) {
throw new UserInputError(NO_POST_ERR_MESSAGE)
} else {
return resolve(root, args, context, info)
}
}
export default {
Mutation: {
CreateSocialMedia: validate(socialMediaSchema),
CreateComment: validateCommentCreation,
},
}

View File

@ -0,0 +1,7 @@
module.exports = {
id: { type: 'string', primary: true, lowercase: true },
status: { type: 'string', valid: ['permanent', 'temporary'] },
type: { type: 'string', valid: ['role', 'crowdfunding'] },
icon: { type: 'string', required: true },
createdAt: { type: 'string', isoDate: true, default: () => new Date().toISOString() },
}

View File

@ -43,6 +43,12 @@ module.exports = {
target: 'User',
direction: 'in',
},
rewarded: {
type: 'relationship',
relationship: 'REWARDED',
target: 'Badge',
direction: 'in',
},
invitedBy: { type: 'relationship', relationship: 'INVITED', target: 'User', direction: 'in' },
createdAt: { type: 'string', isoDate: true, default: () => new Date().toISOString() },
updatedAt: {

View File

@ -1,6 +1,7 @@
// NOTE: We cannot use `fs` here to clean up the code. Cypress breaks on any npm
// module that is not browser-compatible. Node's `fs` module is server-side only
export default {
Badge: require('./Badge.js'),
User: require('./User.js'),
InvitationCode: require('./InvitationCode.js'),
EmailAddress: require('./EmailAddress.js'),

View File

@ -12,11 +12,25 @@ export default applyScalars(
resolvers,
config: {
query: {
exclude: ['InvitationCode', 'EmailAddress', 'Notfication', 'Statistics', 'LoggedInUser'],
exclude: [
'Badge',
'InvitationCode',
'EmailAddress',
'Notfication',
'Statistics',
'LoggedInUser',
],
// add 'User' here as soon as possible
},
mutation: {
exclude: ['InvitationCode', 'EmailAddress', 'Notfication', 'Statistics', 'LoggedInUser'],
exclude: [
'Badge',
'InvitationCode',
'EmailAddress',
'Notfication',
'Statistics',
'LoggedInUser',
],
// add 'User' here as soon as possible
},
debug: CONFIG.DEBUG,

View File

@ -0,0 +1,9 @@
import { neo4jgraphql } from 'neo4j-graphql-js'
export default {
Query: {
Badge: async (object, args, context, resolveInfo) => {
return neo4jgraphql(object, args, context, resolveInfo, false)
},
},
}

View File

@ -1,200 +0,0 @@
import { GraphQLClient } from 'graphql-request'
import Factory from '../../seed/factories'
import { host, login } from '../../jest/helpers'
const factory = Factory()
let client
describe('badges', () => {
beforeEach(async () => {
await factory.create('User', {
email: 'user@example.org',
role: 'user',
password: '1234',
})
await factory.create('User', {
id: 'u2',
role: 'moderator',
email: 'moderator@example.org',
})
await factory.create('User', {
id: 'u3',
role: 'admin',
email: 'admin@example.org',
})
})
afterEach(async () => {
await factory.cleanDatabase()
})
describe('CreateBadge', () => {
const variables = {
id: 'b1',
key: 'indiegogo_en_racoon',
type: 'crowdfunding',
status: 'permanent',
icon: '/img/badges/indiegogo_en_racoon.svg',
}
const mutation = `
mutation(
$id: ID
$key: String!
$type: BadgeType!
$status: BadgeStatus!
$icon: String!
) {
CreateBadge(id: $id, key: $key, type: $type, status: $status, icon: $icon) {
id,
key,
type,
status,
icon
}
}
`
describe('unauthenticated', () => {
it('throws authorization error', async () => {
client = new GraphQLClient(host)
await expect(client.request(mutation, variables)).rejects.toThrow('Not Authorised')
})
})
describe('authenticated admin', () => {
beforeEach(async () => {
const headers = await login({ email: 'admin@example.org', password: '1234' })
client = new GraphQLClient(host, { headers })
})
it('creates a badge', async () => {
const expected = {
CreateBadge: {
icon: '/img/badges/indiegogo_en_racoon.svg',
id: 'b1',
key: 'indiegogo_en_racoon',
status: 'permanent',
type: 'crowdfunding',
},
}
await expect(client.request(mutation, variables)).resolves.toEqual(expected)
})
})
describe('authenticated moderator', () => {
beforeEach(async () => {
const headers = await login({ email: 'moderator@example.org', password: '1234' })
client = new GraphQLClient(host, { headers })
})
it('throws authorization error', async () => {
await expect(client.request(mutation, variables)).rejects.toThrow('Not Authorised')
})
})
})
describe('UpdateBadge', () => {
beforeEach(async () => {
await factory.authenticateAs({ email: 'admin@example.org', password: '1234' })
await factory.create('Badge', { id: 'b1' })
})
const variables = {
id: 'b1',
key: 'whatever',
}
const mutation = `
mutation($id: ID!, $key: String!) {
UpdateBadge(id: $id, key: $key) {
id
key
}
}
`
describe('unauthenticated', () => {
it('throws authorization error', async () => {
client = new GraphQLClient(host)
await expect(client.request(mutation, variables)).rejects.toThrow('Not Authorised')
})
})
describe('authenticated moderator', () => {
beforeEach(async () => {
const headers = await login({ email: 'moderator@example.org', password: '1234' })
client = new GraphQLClient(host, { headers })
})
it('throws authorization error', async () => {
await expect(client.request(mutation, variables)).rejects.toThrow('Not Authorised')
})
})
describe('authenticated admin', () => {
beforeEach(async () => {
const headers = await login({ email: 'admin@example.org', password: '1234' })
client = new GraphQLClient(host, { headers })
})
it('updates a badge', async () => {
const expected = {
UpdateBadge: {
id: 'b1',
key: 'whatever',
},
}
await expect(client.request(mutation, variables)).resolves.toEqual(expected)
})
})
})
describe('DeleteBadge', () => {
beforeEach(async () => {
await factory.authenticateAs({ email: 'admin@example.org', password: '1234' })
await factory.create('Badge', { id: 'b1' })
})
const variables = {
id: 'b1',
}
const mutation = `
mutation($id: ID!) {
DeleteBadge(id: $id) {
id
}
}
`
describe('unauthenticated', () => {
it('throws authorization error', async () => {
client = new GraphQLClient(host)
await expect(client.request(mutation, variables)).rejects.toThrow('Not Authorised')
})
})
describe('authenticated moderator', () => {
beforeEach(async () => {
const headers = await login({ email: 'moderator@example.org', password: '1234' })
client = new GraphQLClient(host, { headers })
})
it('throws authorization error', async () => {
await expect(client.request(mutation, variables)).rejects.toThrow('Not Authorised')
})
})
describe('authenticated admin', () => {
beforeEach(async () => {
const headers = await login({ email: 'admin@example.org', password: '1234' })
client = new GraphQLClient(host, { headers })
})
it('deletes a badge', async () => {
const expected = {
DeleteBadge: {
id: 'b1',
},
}
await expect(client.request(mutation, variables)).resolves.toEqual(expected)
})
})
})
})

View File

@ -1,40 +1,15 @@
import { neo4jgraphql } from 'neo4j-graphql-js'
import { UserInputError } from 'apollo-server'
const COMMENT_MIN_LENGTH = 1
const NO_POST_ERR_MESSAGE = 'Comment cannot be created without a post!'
export default {
Mutation: {
CreateComment: async (object, params, context, resolveInfo) => {
const content = params.content.replace(/<(?:.|\n)*?>/gm, '').trim()
const { postId } = params
// Adding relationship from comment to post by passing in the postId,
// but we do not want to create the comment with postId as an attribute
// because we use relationships for this. So, we are deleting it from params
// before comment creation.
delete params.postId
if (!params.content || content.length < COMMENT_MIN_LENGTH) {
throw new UserInputError(`Comment must be at least ${COMMENT_MIN_LENGTH} character long!`)
}
const session = context.driver.session()
const postQueryRes = await session.run(
`
MATCH (post:Post {id: $postId})
RETURN post`,
{
postId,
},
)
const [post] = postQueryRes.records.map(record => {
return record.get('post')
})
if (!post) {
throw new UserInputError(NO_POST_ERR_MESSAGE)
}
const commentWithoutRelationships = await neo4jgraphql(
object,
params,

View File

@ -1,47 +1,47 @@
import { neode } from '../../bootstrap/neo4j'
import { UserInputError } from 'apollo-server'
const instance = neode()
const getUserAndBadge = async ({ badgeKey, userId }) => {
let user = await instance.first('User', 'id', userId)
const badge = await instance.first('Badge', 'id', badgeKey)
if (!user) throw new UserInputError("Couldn't find a user with that id")
if (!badge) throw new UserInputError("Couldn't find a badge with that id")
return { user, badge }
}
export default {
Mutation: {
reward: async (_object, params, context, _resolveInfo) => {
const { fromBadgeId, toUserId } = params
const session = context.driver.session()
let transactionRes = await session.run(
`MATCH (badge:Badge {id: $badgeId}), (rewardedUser:User {id: $rewardedUserId})
MERGE (badge)-[:REWARDED]->(rewardedUser)
RETURN rewardedUser {.id}`,
{
badgeId: fromBadgeId,
rewardedUserId: toUserId,
},
)
const [rewardedUser] = transactionRes.records.map(record => {
return record.get('rewardedUser')
})
session.close()
return rewardedUser.id
const { user, badge } = await getUserAndBadge(params)
await user.relateTo(badge, 'rewarded')
return user.toJson()
},
unreward: async (_object, params, context, _resolveInfo) => {
const { fromBadgeId, toUserId } = params
const { badgeKey, userId } = params
const { user } = await getUserAndBadge(params)
const session = context.driver.session()
let transactionRes = await session.run(
`MATCH (badge:Badge {id: $badgeId})-[reward:REWARDED]->(rewardedUser:User {id: $rewardedUserId})
DELETE reward
RETURN rewardedUser {.id}`,
{
badgeId: fromBadgeId,
rewardedUserId: toUserId,
},
)
const [rewardedUser] = transactionRes.records.map(record => {
return record.get('rewardedUser')
})
session.close()
return rewardedUser.id
try {
// silly neode cannot remove relationships
await session.run(
`
MATCH (badge:Badge {id: $badgeKey})-[reward:REWARDED]->(rewardedUser:User {id: $userId})
DELETE reward
RETURN rewardedUser
`,
{
badgeKey,
userId,
},
)
} catch (err) {
throw err
} finally {
session.close()
}
return user.toJson()
},
},
}

View File

@ -1,12 +1,20 @@
import { GraphQLClient } from 'graphql-request'
import Factory from '../../seed/factories'
import { host, login } from '../../jest/helpers'
import gql from 'graphql-tag'
const factory = Factory()
let user
let badge
describe('rewards', () => {
const variables = {
from: 'indiegogo_en_rhino',
to: 'u1',
}
beforeEach(async () => {
await factory.create('User', {
user = await factory.create('User', {
id: 'u1',
role: 'user',
email: 'user@example.org',
@ -22,9 +30,8 @@ describe('rewards', () => {
role: 'admin',
email: 'admin@example.org',
})
await factory.create('Badge', {
id: 'b6',
key: 'indiegogo_en_rhino',
badge = await factory.create('Badge', {
id: 'indiegogo_en_rhino',
type: 'crowdfunding',
status: 'permanent',
icon: '/img/badges/indiegogo_en_rhino.svg',
@ -35,21 +42,19 @@ describe('rewards', () => {
await factory.cleanDatabase()
})
describe('RewardBadge', () => {
const mutation = `
mutation(
$from: ID!
$to: ID!
) {
reward(fromBadgeId: $from, toUserId: $to)
describe('reward', () => {
const mutation = gql`
mutation($from: ID!, $to: ID!) {
reward(badgeKey: $from, userId: $to) {
id
badges {
id
}
}
}
`
describe('unauthenticated', () => {
const variables = {
from: 'b6',
to: 'u1',
}
let client
it('throws authorization error', async () => {
@ -65,74 +70,94 @@ describe('rewards', () => {
client = new GraphQLClient(host, { headers })
})
describe('badge for id does not exist', () => {
it('rejects with a telling error message', async () => {
await expect(
client.request(mutation, {
...variables,
from: 'bullshit',
}),
).rejects.toThrow("Couldn't find a badge with that id")
})
})
describe('user for id does not exist', () => {
it('rejects with a telling error message', async () => {
await expect(
client.request(mutation, {
...variables,
to: 'bullshit',
}),
).rejects.toThrow("Couldn't find a user with that id")
})
})
it('rewards a badge to user', async () => {
const variables = {
from: 'b6',
to: 'u1',
}
const expected = {
reward: 'u1',
reward: {
id: 'u1',
badges: [{ id: 'indiegogo_en_rhino' }],
},
}
await expect(client.request(mutation, variables)).resolves.toEqual(expected)
})
it('rewards a second different badge to same user', async () => {
await factory.create('Badge', {
id: 'b1',
key: 'indiegogo_en_racoon',
type: 'crowdfunding',
status: 'permanent',
id: 'indiegogo_en_racoon',
icon: '/img/badges/indiegogo_en_racoon.svg',
})
const variables = {
from: 'b1',
to: 'u1',
}
const expected = {
reward: 'u1',
reward: {
id: 'u1',
badges: [{ id: 'indiegogo_en_racoon' }, { id: 'indiegogo_en_rhino' }],
},
}
await expect(client.request(mutation, variables)).resolves.toEqual(expected)
await client.request(mutation, variables)
await expect(
client.request(mutation, {
...variables,
from: 'indiegogo_en_racoon',
}),
).resolves.toEqual(expected)
})
it('rewards the same badge as well to another user', async () => {
const variables1 = {
from: 'b6',
to: 'u1',
}
await client.request(mutation, variables1)
const variables2 = {
from: 'b6',
to: 'u2',
}
const expected = {
reward: 'u2',
reward: {
id: 'u2',
badges: [{ id: 'indiegogo_en_rhino' }],
},
}
await expect(client.request(mutation, variables2)).resolves.toEqual(expected)
await expect(
client.request(mutation, {
...variables,
to: 'u2',
}),
).resolves.toEqual(expected)
})
it('returns the original reward if a reward is attempted a second time', async () => {
const variables = {
from: 'b6',
to: 'u1',
}
it('creates no duplicate reward relationships', async () => {
await client.request(mutation, variables)
await client.request(mutation, variables)
const query = `{
User( id: "u1" ) {
badgesCount
const query = gql`
{
User(id: "u1") {
badgesCount
badges {
id
}
}
}
}
`
const expected = { User: [{ badgesCount: 1 }] }
const expected = { User: [{ badgesCount: 1, badges: [{ id: 'indiegogo_en_rhino' }] }] }
await expect(client.request(query)).resolves.toEqual(expected)
})
})
describe('authenticated moderator', () => {
const variables = {
from: 'b6',
to: 'u1',
}
let client
beforeEach(async () => {
const headers = await login({ email: 'moderator@example.org', password: '1234' })
@ -147,27 +172,41 @@ describe('rewards', () => {
})
})
describe('RemoveReward', () => {
describe('unreward', () => {
beforeEach(async () => {
await factory.relate('User', 'Badges', { from: 'b6', to: 'u1' })
await user.relateTo(badge, 'rewarded')
})
const variables = {
from: 'b6',
to: 'u1',
}
const expected = {
unreward: 'u1',
}
const expected = { unreward: { id: 'u1', badges: [] } }
const mutation = `
mutation(
$from: ID!
$to: ID!
) {
unreward(fromBadgeId: $from, toUserId: $to)
const mutation = gql`
mutation($from: ID!, $to: ID!) {
unreward(badgeKey: $from, userId: $to) {
id
badges {
id
}
}
}
`
describe('check test setup', () => {
it('user has one badge', async () => {
const query = gql`
{
User(id: "u1") {
badgesCount
badges {
id
}
}
}
`
const expected = { User: [{ badgesCount: 1, badges: [{ id: 'indiegogo_en_rhino' }] }] }
const client = new GraphQLClient(host)
await expect(client.request(query)).resolves.toEqual(expected)
})
})
describe('unauthenticated', () => {
let client
@ -188,12 +227,9 @@ describe('rewards', () => {
await expect(client.request(mutation, variables)).resolves.toEqual(expected)
})
it('fails to remove a not existing badge from user', async () => {
it('does not crash when unrewarding multiple times', async () => {
await client.request(mutation, variables)
await expect(client.request(mutation, variables)).rejects.toThrow(
"Cannot read property 'id' of undefined",
)
await expect(client.request(mutation, variables)).resolves.toEqual(expected)
})
})

View File

@ -139,7 +139,7 @@ export default {
organizationsCreated: '-[:CREATED_ORGA]->(related:Organization)',
organizationsOwned: '-[:OWNING_ORGA]->(related:Organization)',
categories: '-[:CATEGORIZED]->(related:Category)',
badges: '-[:REWARDED]->(related:Badge)',
badges: '<-[:REWARDED]-(related:Badge)',
}),
},
}

View File

@ -147,7 +147,7 @@ describe('users', () => {
}
`
beforeEach(async () => {
asAuthor = await factory.create('User', {
await factory.create('User', {
email: 'test@example.org',
password: '1234',
id: 'u343',
@ -191,6 +191,7 @@ describe('users', () => {
describe('attempting to delete my own account', () => {
let expectedResponse
beforeEach(async () => {
asAuthor = Factory()
await asAuthor.authenticateAs({
email: 'test@example.org',
password: '1234',

View File

@ -1,4 +0,0 @@
enum BadgeStatus {
permanent
temporary
}

View File

@ -1,4 +0,0 @@
enum BadgeType {
role
crowdfunding
}

View File

@ -0,0 +1,7 @@
enum Emotion {
surprised
cry
happy
angry
funny
}

View File

@ -28,8 +28,6 @@ type Mutation {
report(id: ID!, description: String): Report
disable(id: ID!): ID
enable(id: ID!): ID
reward(fromBadgeId: ID!, toUserId: ID!): ID
unreward(fromBadgeId: ID!, toUserId: ID!): ID
# Shout the given Type and ID
shout(id: ID!, type: ShoutTypeEnum): Boolean!
# Unshout the given Type and ID

View File

@ -1,324 +0,0 @@
scalar Upload
type Query {
isLoggedIn: Boolean!
# Get the currently logged in User based on the given JWT Token
currentUser: User
# Get the latest Network Statistics
statistics: Statistics!
findPosts(filter: String!, limit: Int = 10): [Post]! @cypher(
statement: """
CALL db.index.fulltext.queryNodes('full_text_search', $filter)
YIELD node as post, score
MATCH (post)<-[:WROTE]-(user:User)
WHERE score >= 0.2
AND NOT user.deleted = true AND NOT user.disabled = true
AND NOT post.deleted = true AND NOT post.disabled = true
RETURN post
LIMIT $limit
"""
)
CommentByPost(postId: ID!): [Comment]!
}
type Mutation {
# Get a JWT Token for the given Email and password
login(email: String!, password: String!): String!
signup(email: String!, password: String!): Boolean!
changePassword(oldPassword:String!, newPassword: String!): String!
report(id: ID!, description: String): Report
disable(id: ID!): ID
enable(id: ID!): ID
reward(fromBadgeId: ID!, toUserId: ID!): ID
unreward(fromBadgeId: ID!, toUserId: ID!): ID
# Shout the given Type and ID
shout(id: ID!, type: ShoutTypeEnum): Boolean!
# Unshout the given Type and ID
unshout(id: ID!, type: ShoutTypeEnum): Boolean!
# Follow the given Type and ID
follow(id: ID!, type: FollowTypeEnum): Boolean!
# Unfollow the given Type and ID
unfollow(id: ID!, type: FollowTypeEnum): Boolean!
}
type Statistics {
countUsers: Int!
countPosts: Int!
countComments: Int!
countNotifications: Int!
countOrganizations: Int!
countProjects: Int!
countInvites: Int!
countFollows: Int!
countShouts: Int!
}
type Notification {
id: ID!
read: Boolean,
user: User @relation(name: "NOTIFIED", direction: "OUT")
post: Post @relation(name: "NOTIFIED", direction: "IN")
createdAt: String
}
scalar Date
scalar Time
scalar DateTime
enum VisibilityEnum {
public
friends
private
}
enum UserGroupEnum {
admin
moderator
user
}
type Location {
id: ID!
name: String!
nameEN: String
nameDE: String
nameFR: String
nameNL: String
nameIT: String
nameES: String
namePT: String
namePL: String
type: String!
lat: Float
lng: Float
parent: Location @cypher(statement: "MATCH (this)-[:IS_IN]->(l:Location) RETURN l")
}
type User {
id: ID!
actorId: String
name: String
email: String!
slug: String
password: String!
avatar: String
avatarUpload: Upload
deleted: Boolean
disabled: Boolean
disabledBy: User @relation(name: "DISABLED", direction: "IN")
role: UserGroupEnum
publicKey: String
privateKey: String
location: Location @cypher(statement: "MATCH (this)-[:IS_IN]->(l:Location) RETURN l")
locationName: String
about: String
socialMedia: [SocialMedia]! @relation(name: "OWNED", direction: "OUT")
createdAt: String
updatedAt: String
notifications(read: Boolean): [Notification]! @relation(name: "NOTIFIED", direction: "IN")
friends: [User]! @relation(name: "FRIENDS", direction: "BOTH")
friendsCount: Int! @cypher(statement: "MATCH (this)<-[:FRIENDS]->(r:User) RETURN COUNT(DISTINCT r)")
following: [User]! @relation(name: "FOLLOWS", direction: "OUT")
followingCount: Int! @cypher(statement: "MATCH (this)-[:FOLLOWS]->(r:User) RETURN COUNT(DISTINCT r)")
followedBy: [User]! @relation(name: "FOLLOWS", direction: "IN")
followedByCount: Int! @cypher(statement: "MATCH (this)<-[:FOLLOWS]-(r:User) RETURN COUNT(DISTINCT r)")
# Is the currently logged in user following that user?
followedByCurrentUser: Boolean! @cypher(
statement: """
MATCH (this)<-[:FOLLOWS]-(u:User {id: $cypherParams.currentUserId})
RETURN COUNT(u) >= 1
"""
)
#contributions: [WrittenPost]!
#contributions2(first: Int = 10, offset: Int = 0): [WrittenPost2]!
# @cypher(
# statement: "MATCH (this)-[w:WROTE]->(p:Post) RETURN p as Post, w.timestamp as timestamp"
# )
contributions: [Post]! @relation(name: "WROTE", direction: "OUT")
contributionsCount: Int! @cypher(
statement: """
MATCH (this)-[:WROTE]->(r:Post)
WHERE (NOT exists(r.deleted) OR r.deleted = false)
AND (NOT exists(r.disabled) OR r.disabled = false)
RETURN COUNT(r)
"""
)
comments: [Comment]! @relation(name: "WROTE", direction: "OUT")
commentsCount: Int! @cypher(statement: "MATCH (this)-[:WROTE]->(r:Comment) WHERE NOT r.deleted = true AND NOT r.disabled = true RETURN COUNT(r)")
shouted: [Post]! @relation(name: "SHOUTED", direction: "OUT")
shoutedCount: Int! @cypher(statement: "MATCH (this)-[:SHOUTED]->(r:Post) WHERE NOT r.deleted = true AND NOT r.disabled = true RETURN COUNT(DISTINCT r)")
organizationsCreated: [Organization] @relation(name: "CREATED_ORGA", direction: "OUT")
organizationsOwned: [Organization] @relation(name: "OWNING_ORGA", direction: "OUT")
blacklisted: [User]! @relation(name: "BLACKLISTED", direction: "OUT")
categories: [Category]! @relation(name: "CATEGORIZED", direction: "OUT")
badges: [Badge]! @relation(name: "REWARDED", direction: "IN")
badgesCount: Int! @cypher(statement: "MATCH (this)<-[:REWARDED]-(r:Badge) RETURN COUNT(r)")
}
type Post {
id: ID!
activityId: String
objectId: String
author: User @relation(name: "WROTE", direction: "IN")
title: String!
slug: String
content: String!
contentExcerpt: String
image: String
imageUpload: Upload
visibility: VisibilityEnum
deleted: Boolean
disabled: Boolean
disabledBy: User @relation(name: "DISABLED", direction: "IN")
createdAt: String
updatedAt: String
relatedContributions: [Post]! @cypher(
statement: """
MATCH (this)-[:TAGGED|CATEGORIZED]->(categoryOrTag)<-[:TAGGED|CATEGORIZED]-(post:Post)
RETURN DISTINCT post
LIMIT 10
"""
)
tags: [Tag]! @relation(name: "TAGGED", direction: "OUT")
categories: [Category]! @relation(name: "CATEGORIZED", direction: "OUT")
comments: [Comment]! @relation(name: "COMMENTS", direction: "IN")
commentsCount: Int! @cypher(statement: "MATCH (this)<-[:COMMENTS]-(r:Comment) WHERE NOT r.deleted = true AND NOT r.disabled = true RETURN COUNT(r)")
shoutedBy: [User]! @relation(name: "SHOUTED", direction: "IN")
shoutedCount: Int! @cypher(statement: "MATCH (this)<-[:SHOUTED]-(r:User) WHERE NOT r.deleted = true AND NOT r.disabled = true RETURN COUNT(DISTINCT r)")
# Has the currently logged in user shouted that post?
shoutedByCurrentUser: Boolean! @cypher(
statement: """
MATCH (this)<-[:SHOUTED]-(u:User {id: $cypherParams.currentUserId})
RETURN COUNT(u) >= 1
"""
)
}
type Comment {
id: ID!
activityId: String
postId: ID
author: User @relation(name: "WROTE", direction: "IN")
content: String!
contentExcerpt: String
post: Post @relation(name: "COMMENTS", direction: "OUT")
createdAt: String
updatedAt: String
deleted: Boolean
disabled: Boolean
disabledBy: User @relation(name: "DISABLED", direction: "IN")
}
type Report {
id: ID!
submitter: User @relation(name: "REPORTED", direction: "IN")
description: String
type: String! @cypher(statement: "MATCH (resource)<-[:REPORTED]-(this) RETURN labels(resource)[0]")
createdAt: String
comment: Comment @relation(name: "REPORTED", direction: "OUT")
post: Post @relation(name: "REPORTED", direction: "OUT")
user: User @relation(name: "REPORTED", direction: "OUT")
}
type Category {
id: ID!
name: String!
slug: String
icon: String!
posts: [Post]! @relation(name: "CATEGORIZED", direction: "IN")
postCount: Int! @cypher(statement: "MATCH (this)<-[:CATEGORIZED]-(r:Post) RETURN COUNT(r)")
}
type Badge {
id: ID!
key: String!
type: BadgeTypeEnum!
status: BadgeStatusEnum!
icon: String!
rewarded: [User]! @relation(name: "REWARDED", direction: "OUT")
}
enum BadgeTypeEnum {
role
crowdfunding
}
enum BadgeStatusEnum {
permanent
temporary
}
enum ShoutTypeEnum {
Post
Organization
Project
}
enum FollowTypeEnum {
User
Organization
Project
}
type Reward {
id: ID!
user: User @relation(name: "REWARDED", direction: "IN")
rewarderId: ID
createdAt: String
badge: Badge @relation(name: "REWARDED", direction: "OUT")
}
type Organization {
id: ID!
createdBy: User @relation(name: "CREATED_ORGA", direction: "IN")
ownedBy: [User] @relation(name: "OWNING_ORGA", direction: "IN")
name: String!
slug: String
description: String!
descriptionExcerpt: String
deleted: Boolean
disabled: Boolean
tags: [Tag]! @relation(name: "TAGGED", direction: "OUT")
categories: [Category]! @relation(name: "CATEGORIZED", direction: "OUT")
}
type Tag {
id: ID!
name: String!
taggedPosts: [Post]! @relation(name: "TAGGED", direction: "IN")
taggedOrganizations: [Organization]! @relation(name: "TAGGED", direction: "IN")
taggedCount: Int! @cypher(statement: "MATCH (this)<-[:TAGGED]-(p) RETURN COUNT(DISTINCT p)")
taggedCountUnique: Int! @cypher(statement: "MATCH (this)<-[:TAGGED]-(p)<-[:WROTE]-(u:User) RETURN COUNT(DISTINCT u)")
deleted: Boolean
disabled: Boolean
}
type SharedInboxEndpoint {
id: ID!
uri: String
}
type SocialMedia {
id: ID!
url: String
ownedBy: [User]! @relation(name: "OWNED", direction: "IN")
}

View File

@ -1,6 +1,5 @@
type Badge {
id: ID!
key: String!
type: BadgeType!
status: BadgeStatus!
icon: String!
@ -10,4 +9,23 @@ type Badge {
updatedAt: String
rewarded: [User]! @relation(name: "REWARDED", direction: "OUT")
}
}
enum BadgeStatus {
permanent
temporary
}
enum BadgeType {
role
crowdfunding
}
type Query {
Badge: [Badge]
}
type Mutation {
reward(badgeKey: ID!, userId: ID!): User
unreward(badgeKey: ID!, userId: ID!): User
}

View File

@ -0,0 +1,10 @@
type EMOTED @relation(name: "EMOTED") {
from: User
to: Post
emotion: Emotion
#createdAt: DateTime
#updatedAt: DateTime
createdAt: String
updatedAt: String
}

View File

@ -48,6 +48,8 @@ type Post {
RETURN COUNT(u) >= 1
"""
)
emotions: [EMOTED]
}
type Mutation {

View File

@ -73,6 +73,8 @@ type User {
badges: [Badge]! @relation(name: "REWARDED", direction: "IN")
badgesCount: Int! @cypher(statement: "MATCH (this)<-[:REWARDED]-(r:Badge) RETURN COUNT(r)")
emotions: [EMOTED]
}

View File

@ -1,28 +1,15 @@
import uuid from 'uuid/v4'
export default function(params) {
const {
id = uuid(),
key = '',
type = 'crowdfunding',
status = 'permanent',
icon = '/img/badges/indiegogo_en_panda.svg',
} = params
export default function create() {
return {
mutation: `
mutation(
$id: ID
$key: String!
$type: BadgeType!
$status: BadgeStatus!
$icon: String!
) {
CreateBadge(id: $id, key: $key, type: $type, status: $status, icon: $icon) {
id
}
factory: async ({ args, neodeInstance }) => {
const defaults = {
type: 'crowdfunding',
status: 'permanent',
}
`,
variables: { id, key, type, status, icon },
args = {
...defaults,
...args,
}
return neodeInstance.create('Badge', args)
},
}
}

View File

@ -73,6 +73,7 @@ export default function Factory(options = {}) {
const { factory, mutation, variables } = this.factories[node](args)
if (factory) {
this.lastResponse = await factory({ args, neodeInstance })
return this.lastResponse
} else {
this.lastResponse = await this.graphQLClient.request(mutation, variables)
}

View File

@ -3,7 +3,7 @@ import uuid from 'uuid/v4'
import encryptPassword from '../../helpers/encryptPassword'
import slugify from 'slug'
export default function create(params) {
export default function create() {
return {
factory: async ({ args, neodeInstance }) => {
const defaults = {
@ -21,8 +21,7 @@ export default function create(params) {
...args,
}
args = await encryptPassword(args)
const user = await neodeInstance.create('User', args)
return user.toJson()
return neodeInstance.create('User', args)
},
}
}

View File

@ -5,52 +5,42 @@ import Factory from './factories'
;(async function() {
try {
const f = Factory()
await Promise.all([
const [racoon, rabbit, wolf, bear, turtle, rhino] = await Promise.all([
f.create('Badge', {
id: 'b1',
key: 'indiegogo_en_racoon',
type: 'crowdfunding',
status: 'permanent',
id: 'indiegogo_en_racoon',
icon: '/img/badges/indiegogo_en_racoon.svg',
}),
f.create('Badge', {
id: 'b2',
key: 'indiegogo_en_rabbit',
type: 'crowdfunding',
status: 'permanent',
id: 'indiegogo_en_rabbit',
icon: '/img/badges/indiegogo_en_rabbit.svg',
}),
f.create('Badge', {
id: 'b3',
key: 'indiegogo_en_wolf',
type: 'crowdfunding',
status: 'permanent',
id: 'indiegogo_en_wolf',
icon: '/img/badges/indiegogo_en_wolf.svg',
}),
f.create('Badge', {
id: 'b4',
key: 'indiegogo_en_bear',
type: 'crowdfunding',
status: 'permanent',
id: 'indiegogo_en_bear',
icon: '/img/badges/indiegogo_en_bear.svg',
}),
f.create('Badge', {
id: 'b5',
key: 'indiegogo_en_turtle',
type: 'crowdfunding',
status: 'permanent',
id: 'indiegogo_en_turtle',
icon: '/img/badges/indiegogo_en_turtle.svg',
}),
f.create('Badge', {
id: 'b6',
key: 'indiegogo_en_rhino',
type: 'crowdfunding',
status: 'permanent',
id: 'indiegogo_en_rhino',
icon: '/img/badges/indiegogo_en_rhino.svg',
}),
])
await Promise.all([
const [
peterLustig,
bobDerBaumeister,
jennyRostock,
tick, // eslint-disable-line no-unused-vars
trick, // eslint-disable-line no-unused-vars
track, // eslint-disable-line no-unused-vars
dagobert,
] = await Promise.all([
f.create('User', {
id: 'u1',
name: 'Peter Lustig',
@ -123,30 +113,16 @@ import Factory from './factories'
])
await Promise.all([
f.relate('User', 'Badges', {
from: 'b6',
to: 'u1',
}),
f.relate('User', 'Badges', {
from: 'b5',
to: 'u2',
}),
f.relate('User', 'Badges', {
from: 'b4',
to: 'u3',
}),
f.relate('User', 'Badges', {
from: 'b3',
to: 'u4',
}),
f.relate('User', 'Badges', {
from: 'b2',
to: 'u5',
}),
f.relate('User', 'Badges', {
from: 'b1',
to: 'u6',
}),
peterLustig.relateTo(racoon, 'rewarded'),
peterLustig.relateTo(rhino, 'rewarded'),
peterLustig.relateTo(wolf, 'rewarded'),
bobDerBaumeister.relateTo(racoon, 'rewarded'),
bobDerBaumeister.relateTo(turtle, 'rewarded'),
jennyRostock.relateTo(bear, 'rewarded'),
dagobert.relateTo(rabbit, 'rewarded'),
])
await Promise.all([
f.relate('User', 'Friends', {
from: 'u1',
to: 'u2',

View File

@ -9,10 +9,10 @@
dependencies:
apollo-env "0.5.1"
"@apollographql/graphql-playground-html@1.6.20":
version "1.6.20"
resolved "https://registry.yarnpkg.com/@apollographql/graphql-playground-html/-/graphql-playground-html-1.6.20.tgz#bf9f2acdf319c0959fad8ec1239741dd2ead4e8d"
integrity sha512-3LWZa80HcP70Pl+H4KhLDJ7S0px+9/c8GTXdl6SpunRecUaB27g/oOQnAjNHLHdbWuGE0uyqcuGiTfbKB3ilaQ==
"@apollographql/graphql-playground-html@1.6.24":
version "1.6.24"
resolved "https://registry.yarnpkg.com/@apollographql/graphql-playground-html/-/graphql-playground-html-1.6.24.tgz#3ce939cb127fb8aaa3ffc1e90dff9b8af9f2e3dc"
integrity sha512-8GqG48m1XqyXh4mIZrtB5xOhUwSsh1WsrrsaZQOEYYql3YN9DEu9OOSg0ILzXHZo/h2Q74777YE4YzlArQzQEQ==
"@babel/cli@~7.5.0":
version "7.5.0"
@ -787,7 +787,7 @@
resolved "https://registry.yarnpkg.com/@hapi/hoek/-/hoek-8.0.1.tgz#9712fa2ad124ac64668ab06ba847b1eaf83a03fd"
integrity sha512-cctMYH5RLbElaUpZn3IJaUj9QNQD8iXDnl7xNY6KB1aFD2ciJrwpo3kvZowIT75uA+silJFDnSR2kGakALUymg==
"@hapi/joi@^15.1.0":
"@hapi/joi@^15.0.3", "@hapi/joi@^15.1.0":
version "15.1.0"
resolved "https://registry.yarnpkg.com/@hapi/joi/-/joi-15.1.0.tgz#940cb749b5c55c26ab3b34ce362e82b6162c8e7a"
integrity sha512-n6kaRQO8S+kepUTbXL9O/UOL788Odqs38/VOfoCrATDtTvyfiO3fgjlSRaNkHabpTLgM7qru9ifqXlXbXk8SeQ==
@ -1343,13 +1343,13 @@ anymatch@^2.0.0:
micromatch "^3.1.4"
normalize-path "^2.1.1"
apollo-cache-control@0.7.4:
version "0.7.4"
resolved "https://registry.yarnpkg.com/apollo-cache-control/-/apollo-cache-control-0.7.4.tgz#0cb5c7be0e0dd0c44b1257144cd7f9f2a3c374e6"
integrity sha512-TVACHwcEF4wfHo5H9FLnoNjo0SLDo2jPW+bXs9aw0Y4Z2UisskSAPnIYOqUPnU8SoeNvs7zWgbLizq11SRTJtg==
apollo-cache-control@0.7.5:
version "0.7.5"
resolved "https://registry.yarnpkg.com/apollo-cache-control/-/apollo-cache-control-0.7.5.tgz#5d8b949bd9b4f03ca32c7d7e429f509c6881eefc"
integrity sha512-zCPwHjbo/VlmXl0sclZfBq/MlVVeGUAg02Q259OIXSgHBvn9BbExyz+EkO/DJvZfGMquxqS1X1BFO3VKuLUTdw==
dependencies:
apollo-server-env "2.4.0"
graphql-extensions "0.7.4"
graphql-extensions "0.7.7"
apollo-cache-control@^0.1.0:
version "0.1.1"
@ -1406,17 +1406,17 @@ apollo-engine-reporting-protobuf@0.3.1:
dependencies:
protobufjs "^6.8.6"
apollo-engine-reporting@1.3.5:
version "1.3.5"
resolved "https://registry.yarnpkg.com/apollo-engine-reporting/-/apollo-engine-reporting-1.3.5.tgz#075424d39dfe77a20f96e8e33b7ae52d58c38e1e"
integrity sha512-pSwjPgXK/elFsR22LXALtT3jI4fpEpeTNTHgNwLVLohaolusMYgBc/9FnVyFWFfMFS9k+3RmfeQdHhZ6T7WKFQ==
apollo-engine-reporting@1.3.6:
version "1.3.6"
resolved "https://registry.yarnpkg.com/apollo-engine-reporting/-/apollo-engine-reporting-1.3.6.tgz#579ba2da85ff848bd92be1b0f1ad61f0c57e3585"
integrity sha512-oCoFAUBGveg1i1Sao/2gNsf1kirJBT6vw6Zan9BCNUkyh68ewDts+xRg32VnD9lDhaHpXVJ3tVtuaV44HmdSEw==
dependencies:
apollo-engine-reporting-protobuf "0.3.1"
apollo-graphql "^0.3.3"
apollo-server-core "2.6.7"
apollo-server-core "2.6.9"
apollo-server-env "2.4.0"
async-retry "^1.2.1"
graphql-extensions "0.7.6"
graphql-extensions "0.7.7"
apollo-env@0.5.1:
version "0.5.1"
@ -1486,50 +1486,24 @@ apollo-server-caching@0.4.0:
dependencies:
lru-cache "^5.0.0"
apollo-server-core@2.6.7:
version "2.6.7"
resolved "https://registry.yarnpkg.com/apollo-server-core/-/apollo-server-core-2.6.7.tgz#85b0310f40cfec43a702569c73af16d88776a6f0"
integrity sha512-HfOGLvEwPgDWTvd3ZKRPEkEnICKb7xadn1Mci4+auMTsL/NVkfpjPa8cdzubi/kS2/MvioIn7Bg74gmiSLghGQ==
apollo-server-core@2.6.9:
version "2.6.9"
resolved "https://registry.yarnpkg.com/apollo-server-core/-/apollo-server-core-2.6.9.tgz#75542ad206782e5c31a023b54962e9fdc6404a91"
integrity sha512-r2/Kjm1UmxoTViUt5EcExWXkWl0riXsuGyS1q5LpHKKnA+6b+t4LQKECkRU4EWNpuuzJQn7aF7MmMdvURxoEig==
dependencies:
"@apollographql/apollo-tools" "^0.3.6"
"@apollographql/graphql-playground-html" "1.6.20"
"@apollographql/graphql-playground-html" "1.6.24"
"@types/ws" "^6.0.0"
apollo-cache-control "0.7.4"
apollo-cache-control "0.7.5"
apollo-datasource "0.5.0"
apollo-engine-reporting "1.3.5"
apollo-engine-reporting "1.3.6"
apollo-server-caching "0.4.0"
apollo-server-env "2.4.0"
apollo-server-errors "2.3.0"
apollo-server-plugin-base "0.5.6"
apollo-tracing "0.7.3"
apollo-server-errors "2.3.1"
apollo-server-plugin-base "0.5.8"
apollo-tracing "0.7.4"
fast-json-stable-stringify "^2.0.0"
graphql-extensions "0.7.6"
graphql-subscriptions "^1.0.0"
graphql-tag "^2.9.2"
graphql-tools "^4.0.0"
graphql-upload "^8.0.2"
sha.js "^2.4.11"
subscriptions-transport-ws "^0.9.11"
ws "^6.0.0"
apollo-server-core@2.6.8:
version "2.6.8"
resolved "https://registry.yarnpkg.com/apollo-server-core/-/apollo-server-core-2.6.8.tgz#c8758b5f26b5f3b9fef51b911265b80a9ce5251d"
integrity sha512-Jxw+6R/2I2LiZ6kjRFTzPpdjw7HfuVLfNU+svgNlxioLducxBH/wqUs3qYTf4eVUUtWy+nSS/BUf/Ullo+Ur0Q==
dependencies:
"@apollographql/apollo-tools" "^0.3.6"
"@apollographql/graphql-playground-html" "1.6.20"
"@types/ws" "^6.0.0"
apollo-cache-control "0.7.4"
apollo-datasource "0.5.0"
apollo-engine-reporting "1.3.5"
apollo-server-caching "0.4.0"
apollo-server-env "2.4.0"
apollo-server-errors "2.3.0"
apollo-server-plugin-base "0.5.7"
apollo-tracing "0.7.3"
fast-json-stable-stringify "^2.0.0"
graphql-extensions "0.7.6"
graphql-extensions "0.7.7"
graphql-subscriptions "^1.0.0"
graphql-tag "^2.9.2"
graphql-tools "^4.0.0"
@ -1555,23 +1529,23 @@ apollo-server-env@2.4.0:
node-fetch "^2.1.2"
util.promisify "^1.0.0"
apollo-server-errors@2.3.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/apollo-server-errors/-/apollo-server-errors-2.3.0.tgz#700622b66a16dffcad3b017e4796749814edc061"
integrity sha512-rUvzwMo2ZQgzzPh2kcJyfbRSfVKRMhfIlhY7BzUfM4x6ZT0aijlgsf714Ll3Mbf5Fxii32kD0A/DmKsTecpccw==
apollo-server-errors@2.3.1:
version "2.3.1"
resolved "https://registry.yarnpkg.com/apollo-server-errors/-/apollo-server-errors-2.3.1.tgz#033cf331463ebb99a563f8354180b41ac6714eb6"
integrity sha512-errZvnh0vUQChecT7M4A/h94dnBSRL213dNxpM5ueMypaLYgnp4hiCTWIEaooo9E4yMGd1qA6WaNbLDG2+bjcg==
apollo-server-express@2.6.8:
version "2.6.8"
resolved "https://registry.yarnpkg.com/apollo-server-express/-/apollo-server-express-2.6.8.tgz#9f3e29f7087af669f05d75dfd335b4a9383ba48e"
integrity sha512-LQzVHknQDkHWffc2qK9dr/qNxQ/WecSKiye5/w10tXrOy3aruTFe67ysG/vMnFZ/puroqiZ2njHzhHZztqQ4sA==
apollo-server-express@2.6.9:
version "2.6.9"
resolved "https://registry.yarnpkg.com/apollo-server-express/-/apollo-server-express-2.6.9.tgz#176dab7f2cd5a99655c8eb382ad9b10797422a7b"
integrity sha512-iTkdIdX7m9EAlmL/ZPkKR+x/xuFk1HYZWuJIJG57hHUhcOxj50u7F1E5+5fDwl5RFIdepQ61azF31hhNZuNi4g==
dependencies:
"@apollographql/graphql-playground-html" "1.6.20"
"@apollographql/graphql-playground-html" "1.6.24"
"@types/accepts" "^1.3.5"
"@types/body-parser" "1.17.0"
"@types/cors" "^2.8.4"
"@types/express" "4.17.0"
accepts "^1.3.5"
apollo-server-core "2.6.8"
apollo-server-core "2.6.9"
body-parser "^1.18.3"
cors "^2.8.4"
graphql-subscriptions "^1.0.0"
@ -1599,41 +1573,36 @@ apollo-server-module-graphiql@^1.3.4, apollo-server-module-graphiql@^1.4.0:
resolved "https://registry.yarnpkg.com/apollo-server-module-graphiql/-/apollo-server-module-graphiql-1.4.0.tgz#c559efa285578820709f1769bb85d3b3eed3d8ec"
integrity sha512-GmkOcb5he2x5gat+TuiTvabnBf1m4jzdecal3XbXBh/Jg+kx4hcvO3TTDFQ9CuTprtzdcVyA11iqG7iOMOt7vA==
apollo-server-plugin-base@0.5.6:
version "0.5.6"
resolved "https://registry.yarnpkg.com/apollo-server-plugin-base/-/apollo-server-plugin-base-0.5.6.tgz#3a7128437a0f845e7d873fa43ef091ff7bf27975"
integrity sha512-wJvcPqfm/kiBwY5JZT85t2A4pcHv24xdQIpWMNt1zsnx77lIZqJmhsc22eSUSrlnYqUMXC4XMVgSUfAO4oI9wg==
apollo-server-plugin-base@0.5.8:
version "0.5.8"
resolved "https://registry.yarnpkg.com/apollo-server-plugin-base/-/apollo-server-plugin-base-0.5.8.tgz#77b4127aff4e3514a9d49e3cc61256aee4d9422e"
integrity sha512-ICbaXr0ycQZL5llbtZhg8zyHbxuZ4khdAJsJgiZaUXXP6+F47XfDQ5uwnl/4Sq9fvkpwS0ctvfZ1D+Ks4NvUzA==
apollo-server-plugin-base@0.5.7:
version "0.5.7"
resolved "https://registry.yarnpkg.com/apollo-server-plugin-base/-/apollo-server-plugin-base-0.5.7.tgz#267faeb5c2de7fa8d3be469cb99f82f601be7aed"
integrity sha512-HeEwEZ92c2XYRV+0CFLbstW3vUJ4idCxR9E9Q3wwvhXrq8gaGzqyDoC8EzAzRxCJUKcEn7xQOpT/AUTC/KtkRA==
apollo-server-testing@~2.6.8:
version "2.6.8"
resolved "https://registry.yarnpkg.com/apollo-server-testing/-/apollo-server-testing-2.6.8.tgz#e75364df7fdc2d6a11023f8a0f72a14309b90800"
integrity sha512-pch2I+8QhdXBMnGDctVth4BcZ5hocwY/ogtBMoQuv7H2HBnlDOz7dCM9BH4TW3+Tk6cFgvLTaDtLJ+NxMCtyVA==
apollo-server-testing@~2.6.9:
version "2.6.9"
resolved "https://registry.yarnpkg.com/apollo-server-testing/-/apollo-server-testing-2.6.9.tgz#6c1d20a89c0676bf32714405d729c302d62adfb1"
integrity sha512-MQfXAjNsI63O9sY60tQnGy102sqJSr++Yzm+IR44WrK3Z7FHUDisoh6UATly04EDGtO034xtqukzdUNQCK7+rw==
dependencies:
apollo-server-core "2.6.8"
apollo-server-core "2.6.9"
apollo-server@~2.6.8:
version "2.6.8"
resolved "https://registry.yarnpkg.com/apollo-server/-/apollo-server-2.6.8.tgz#5f3cf5cf4f2feccbded0cb03fa37dcd8260e5c6a"
integrity sha512-BxwaGxnD3GPuZAAqsexVHFvDlF/s2X8pILgYQ4x+VhUkMeQ12DHQtKPuxn2v2GYwH0U/GDXNohkgwxF/5eTDsQ==
apollo-server@~2.6.9:
version "2.6.9"
resolved "https://registry.yarnpkg.com/apollo-server/-/apollo-server-2.6.9.tgz#10e70488b35bf5171612dfd3f030e4ef94c75295"
integrity sha512-thZxUHVM1CLl3503gMCVirxN9J/33s5C1R+hHMEfLaUSoDlXSMA81Y9LCOi9+6d0C9l5DwiZCFXeZI/fKic2RA==
dependencies:
apollo-server-core "2.6.8"
apollo-server-express "2.6.8"
apollo-server-core "2.6.9"
apollo-server-express "2.6.9"
express "^4.0.0"
graphql-subscriptions "^1.0.0"
graphql-tools "^4.0.0"
apollo-tracing@0.7.3:
version "0.7.3"
resolved "https://registry.yarnpkg.com/apollo-tracing/-/apollo-tracing-0.7.3.tgz#8533e3e2dca2d5a25e8439ce498ea33ff4d159ee"
integrity sha512-H6fSC+awQGnfDyYdGIB0UQUhcUC3n5Vy+ujacJ0bY6R+vwWeZOQvu7wRHNjk/rbOSTLCo9A0OcVX7huRyu9SZg==
apollo-tracing@0.7.4:
version "0.7.4"
resolved "https://registry.yarnpkg.com/apollo-tracing/-/apollo-tracing-0.7.4.tgz#f24d1065100b6d8bf581202859ea0e85ba7bf30d"
integrity sha512-vA0FJCBkFpwdWyVF5UtCqN+enShejyiqSGqq8NxXHU1+GEYTngWa56x9OGsyhX+z4aoDIa3HPKPnP3pjzA0qpg==
dependencies:
apollo-server-env "2.4.0"
graphql-extensions "0.7.4"
graphql-extensions "0.7.7"
apollo-tracing@^0.1.0:
version "0.1.4"
@ -2508,17 +2477,12 @@ core-js-pure@3.1.2:
resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.1.2.tgz#62fc435f35b7374b9b782013cdcb2f97e9f6dffa"
integrity sha512-5ckIdBF26B3ldK9PM177y2ZcATP2oweam9RskHSoqfZCrJ2As6wVg8zJ1zTriFsZf6clj/N1ThDFRGaomMsh9w==
core-js@^2.4.0, core-js@^2.5.3, core-js@^2.5.7:
version "2.6.2"
resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.2.tgz#267988d7268323b349e20b4588211655f0e83944"
integrity sha512-NdBPF/RVwPW6jr0NCILuyN9RiqLo2b1mddWHkUL+VnvcB7dzlnBJ1bXYntjpTGOgkZiiLWj2JxmOr7eGE3qK6g==
core-js@^2.4.0, core-js@^2.5.3, core-js@^2.5.7, core-js@^2.6.5:
version "2.6.9"
resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.9.tgz#6b4b214620c834152e179323727fc19741b084f2"
integrity sha512-HOpZf6eXmnl7la+cUdMnLvUxKNqLUzJvgIziQ0DiF3JwSImNphIqdGqzj6hIKyX04MmV0poclQ7+wjWvxQyR2A==
core-js@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.0.0.tgz#a8dbfa978d29bfc263bfb66c556d0ca924c28957"
integrity sha512-WBmxlgH2122EzEJ6GH8o9L/FeoUKxxxZ6q6VUxoTlsE4EvbTWKJb447eyVxTEuq0LpXjlq/kCB2qgBvsYRkLvQ==
core-js@^3.0.1:
core-js@^3.0.0, core-js@^3.0.1:
version "3.1.3"
resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.1.3.tgz#95700bca5f248f5f78c0ec63e784eca663ec4138"
integrity sha512-PWZ+ZfuaKf178BIAg+CRsljwjIMRV8MY00CbZczkR6Zk5LfkSkjGoaab3+bqRQWVITNZxQB7TFYz+CFcyuamvA==
@ -3827,19 +3791,13 @@ graphql-deduplicator@^2.0.1:
resolved "https://registry.yarnpkg.com/graphql-deduplicator/-/graphql-deduplicator-2.0.2.tgz#d8608161cf6be97725e178df0c41f6a1f9f778f3"
integrity sha512-0CGmTmQh4UvJfsaTPppJAcHwHln8Ayat7yXXxdnuWT+Mb1dBzkbErabCWzjXyKh/RefqlGTTA7EQOZHofMaKJA==
graphql-extensions@0.7.4:
version "0.7.4"
resolved "https://registry.yarnpkg.com/graphql-extensions/-/graphql-extensions-0.7.4.tgz#78327712822281d5778b9210a55dc59c93a9c184"
integrity sha512-Ly+DiTDU+UtlfPGQkqmBX2SWMr9OT3JxMRwpB9K86rDNDBTJtG6AE2kliQKKE+hg1+945KAimO7Ep+YAvS7ywg==
dependencies:
"@apollographql/apollo-tools" "^0.3.6"
graphql-extensions@0.7.6:
version "0.7.6"
resolved "https://registry.yarnpkg.com/graphql-extensions/-/graphql-extensions-0.7.6.tgz#80cdddf08b0af12525529d1922ee2ea0d0cc8ecf"
integrity sha512-RV00O3YFD1diehvdja180BlKOGWgeigr/8/Wzr6lXwLcFtk6FecQC/7nf6oW1qhuXczHyNjt/uCr0WWbWq6mYg==
graphql-extensions@0.7.7:
version "0.7.7"
resolved "https://registry.yarnpkg.com/graphql-extensions/-/graphql-extensions-0.7.7.tgz#19f4dea35391065de72b25def98f8396887bdf43"
integrity sha512-xiTbVGPUpLbF86Bc+zxI/v/axRkwZx3s+y2/kUb2c2MxNZeNhMZEw1dSutuhY2f2JkRkYFJii0ucjIVqPAQ/Lg==
dependencies:
"@apollographql/apollo-tools" "^0.3.6"
apollo-server-env "2.4.0"
graphql-extensions@^0.0.x, graphql-extensions@~0.0.9:
version "0.0.10"
@ -5023,7 +4981,7 @@ jmespath@0.15.0:
resolved "https://registry.yarnpkg.com/jmespath/-/jmespath-0.15.0.tgz#a3f222a9aae9f966f5d27c796510e28091764217"
integrity sha1-o/Iiqarp+Wb10nx5ZRDigJF2Qhc=
joi@^13.0.0, joi@^13.7.0:
joi@^13.7.0:
version "13.7.0"
resolved "https://registry.yarnpkg.com/joi/-/joi-13.7.0.tgz#cfd85ebfe67e8a1900432400b4d03bbd93fb879f"
integrity sha512-xuY5VkHfeOYK3Hdi91ulocfuFopwgbSORmIwzcwHKESQhC7w1kD5jaVSPnqDxS2I8t3RZ9omCKAxNwXN5zG1/Q==
@ -5382,9 +5340,9 @@ lodash.isstring@^4.0.1:
integrity sha1-1SfftUVuynzJu5XV2ur4i6VKVFE=
lodash.mergewith@^4.6.1:
version "4.6.1"
resolved "https://registry.yarnpkg.com/lodash.mergewith/-/lodash.mergewith-4.6.1.tgz#639057e726c3afbdb3e7d42741caa8d6e4335927"
integrity sha512-eWw5r+PYICtEBgrBE5hhlT6aAa75f411bgDz/ZL2KZqYV03USvucsxcHUIlGTDTECs1eunpI7HOV7U+WLDvNdQ==
version "4.6.2"
resolved "https://registry.yarnpkg.com/lodash.mergewith/-/lodash.mergewith-4.6.2.tgz#617121f89ac55f59047c7aec1ccd6654c6590f55"
integrity sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==
lodash.once@^4.0.0:
version "4.1.1"
@ -5401,10 +5359,10 @@ lodash@=3.10.1:
resolved "https://registry.yarnpkg.com/lodash/-/lodash-3.10.1.tgz#5bf45e8e49ba4189e17d482789dfd15bd140b7b6"
integrity sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=
lodash@^4.13.1, lodash@^4.15.0, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.4, lodash@^4.17.5, lodash@~4.17.13:
version "4.17.13"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.13.tgz#0bdc3a6adc873d2f4e0c4bac285df91b64fc7b93"
integrity sha512-vm3/XWXfWtRua0FkUyEHBZy8kCPjErNBT9fJx8Zvs+U6zjqPbTUOpkaoum3O5uiA8sm+yNMHXfYkTUHFoMxFNA==
lodash@^4.13.1, lodash@^4.15.0, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.4, lodash@^4.17.5, lodash@~4.17.14:
version "4.17.14"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.14.tgz#9ce487ae66c96254fe20b599f21b6816028078ba"
integrity sha512-mmKYbW3GLuJeX+iGP+Y7Gp1AiGHGbXHCOh/jZmrawMmsE7MS4znI3RL2FsjbqOyMayHInjOeykW7PEajUk1/xw==
long@^4.0.0:
version "4.0.0"
@ -8037,13 +7995,13 @@ w3c-hr-time@^1.0.1:
dependencies:
browser-process-hrtime "^0.1.2"
wait-on@~3.2.0:
version "3.2.0"
resolved "https://registry.yarnpkg.com/wait-on/-/wait-on-3.2.0.tgz#c83924df0fc42a675c678324c49c769d378bcb85"
integrity sha512-QUGNKlKLDyY6W/qHdxaRlXUAgLPe+3mLL/tRByHpRNcHs/c7dZXbu+OnJWGNux6tU1WFh/Z8aEwvbuzSAu79Zg==
wait-on@~3.3.0:
version "3.3.0"
resolved "https://registry.yarnpkg.com/wait-on/-/wait-on-3.3.0.tgz#9940981d047a72a9544a97b8b5fca45b2170a082"
integrity sha512-97dEuUapx4+Y12aknWZn7D25kkjMk16PbWoYzpSdA8bYpVfS6hpl2a2pOWZ3c+Tyt3/i4/pglyZctG3J4V1hWQ==
dependencies:
core-js "^2.5.7"
joi "^13.0.0"
"@hapi/joi" "^15.0.3"
core-js "^2.6.5"
minimist "^1.2.0"
request "^2.88.0"
rx "^4.1.0"

View File

@ -23,24 +23,27 @@ Cypress.Commands.add('factory', () => {
Cypress.Commands.add(
'create',
{ prevSubject: true },
(factory, node, properties) => {
return factory.create(node, properties)
async (factory, node, properties) => {
await factory.create(node, properties)
return factory
}
)
Cypress.Commands.add(
'relate',
{ prevSubject: true },
(factory, node, relationship, properties) => {
return factory.relate(node, relationship, properties)
async (factory, node, relationship, properties) => {
await factory.relate(node, relationship, properties)
return factory
}
)
Cypress.Commands.add(
'mutate',
{ prevSubject: true },
(factory, mutation, variables) => {
return factory.mutate(mutation, variables)
async (factory, mutation, variables) => {
await factory.mutate(mutation, variables)
return factory
}
)

View File

@ -25,7 +25,7 @@
[?] type: String, // in nitro this is a defined enum - seems good for now
[X] required: true
},
[X] key: {
[X] id: {
[X] type: String,
[X] required: true
},
@ -43,7 +43,7 @@
CALL apoc.load.json("file:${IMPORT_CHUNK_PATH_CQL_FILE}") YIELD value as badge
MERGE(b:Badge {id: badge._id["$oid"]})
ON CREATE SET
b.key = badge.key,
b.id = badge.key,
b.type = badge.type,
b.icon = replace(badge.image.path, 'https://api-alpha.human-connection.org', ''),
b.status = badge.status,

View File

@ -0,0 +1 @@
MATCH (u:User)-[e:EMOTED]->(c:Post) DETACH DELETE e;

View File

@ -5,31 +5,54 @@
// [-] Omitted in Nitro
// [?] Unclear / has work to be done for Nitro
{
[ ] userId: {
[ ] type: String,
[ ] required: true,
[X] userId: {
[X] type: String,
[X] required: true,
[-] index: true
},
[ ] contributionId: {
[ ] type: String,
[ ] required: true,
[X] contributionId: {
[X] type: String,
[X] required: true,
[-] index: true
},
[ ] rated: {
[ ] type: String,
[?] rated: {
[X] type: String,
[ ] required: true,
[ ] enum: ['funny', 'happy', 'surprised', 'cry', 'angry']
[?] enum: ['funny', 'happy', 'surprised', 'cry', 'angry']
},
[ ] createdAt: {
[ ] type: Date,
[ ] default: Date.now
[X] createdAt: {
[X] type: Date,
[X] default: Date.now
},
[ ] updatedAt: {
[ ] type: Date,
[ ] default: Date.now
[X] updatedAt: {
[X] type: Date,
[X] default: Date.now
},
[ ] wasSeeded: { type: Boolean }
[-] wasSeeded: { type: Boolean }
}
*/
CALL apoc.load.json("file:${IMPORT_CHUNK_PATH_CQL_FILE}") YIELD value as emotion;
CALL apoc.load.json("file:${IMPORT_CHUNK_PATH_CQL_FILE}") YIELD value as emotion
MATCH (u:User {id: emotion.userId}),
(c:Post {id: emotion.contributionId})
MERGE (u)-[e:EMOTED {
id: emotion._id["$oid"],
emotion: emotion.rated,
createdAt: datetime(emotion.createdAt.`$date`),
updatedAt: datetime(emotion.updatedAt.`$date`)
}]->(c)
RETURN e;
/*
// Queries
// user sets an emotion emotion:
// MERGE (u)-[e:EMOTED {id: ..., emotion: "funny", createdAt: ..., updatedAt: ...}]->(c)
// user removes emotion
// MATCH (u)-[e:EMOTED]->(c) DELETE e
// contribution distributions over every `emotion` property value for one post
// MATCH (u:User)-[e:EMOTED]->(c:Post {id: "5a70bbc8508f5b000b443b1a"}) RETURN e.emotion,COUNT(e.emotion)
// contribution distributions over every `emotion` property value for one user (advanced - "whats the primary emotion used by the user?")
// MATCH (u:User{id:"5a663b1ac64291000bf302a1"})-[e:EMOTED]->(c:Post) RETURN e.emotion,COUNT(e.emotion)
// contribution distributions over every `emotion` property value for all posts created by one user (advanced - "how do others react to my contributions?")
// MATCH (u:User)-[e:EMOTED]->(c:Post)<-[w:WROTE]-(a:User{id:"5a663b1ac64291000bf302a1"}) RETURN e.emotion,COUNT(e.emotion)
// if we can filter the above an a variable timescale that would be great (should be possible on createdAt and updatedAt fields)
*/

View File

@ -1 +1 @@
// this is just a relation between users(?) - no need to delete
MATCH (u1:User)-[f:FOLLOWS]->(u2:User) DETACH DELETE f;

View File

@ -60,8 +60,8 @@ delete_collection "contributions" "contributions_post"
delete_collection "contributions" "contributions_cando"
delete_collection "shouts" "shouts"
delete_collection "comments" "comments"
delete_collection "emotions" "emotions"
#delete_collection "emotions"
#delete_collection "invites"
#delete_collection "notifications"
#delete_collection "organizations"
@ -82,12 +82,12 @@ import_collection "users" "users/users.cql"
import_collection "follows_users" "follows/follows.cql"
#import_collection "follows_organizations" "follows/follows.cql"
import_collection "contributions_post" "contributions/contributions.cql"
import_collection "contributions_cando" "contributions/contributions.cql"
#import_collection "contributions_cando" "contributions/contributions.cql"
#import_collection "contributions_DELETED" "contributions/contributions.cql"
import_collection "shouts" "shouts/shouts.cql"
import_collection "comments" "comments/comments.cql"
import_collection "emotions" "emotions/emotions.cql"
# import_collection "emotions"
# import_collection "invites"
# import_collection "notifications"
# import_collection "organizations"

View File

@ -24,7 +24,7 @@
"cross-env": "^5.2.0",
"cypress": "^3.4.0",
"cypress-cucumber-preprocessor": "^1.12.0",
"cypress-file-upload": "^3.2.0",
"cypress-file-upload": "^3.2.1",
"cypress-plugin-retries": "^1.2.2",
"dotenv": "^8.0.0",
"faker": "Marak/faker.js#master",

View File

@ -1,6 +1,6 @@
<template>
<div :class="[badges.length === 2 && 'hc-badges-dual']" class="hc-badges">
<div v-for="badge in badges" :key="badge.key" class="hc-badge-container">
<div v-for="badge in badges" :key="badge.id" class="hc-badge-container">
<img :title="badge.key" :src="badge.icon | proxyApiUrl" class="hc-badge" />
</div>
</div>

View File

@ -47,7 +47,8 @@ export default {
},
watch: {
Post(post) {
this.comments = post[0].comments || []
const [first] = post
this.comments = (first && first.comments) || []
},
},
apollo: {

View File

@ -25,7 +25,6 @@ export default app => {
}
badges {
id
key
icon
}
}

View File

@ -29,7 +29,6 @@ export default i18n => {
}
badges {
id
key
icon
}
}

View File

@ -30,7 +30,6 @@ export default i18n => {
}
badges {
id
key
icon
}
}
@ -61,7 +60,6 @@ export default i18n => {
}
badges {
id
key
icon
}
}

View File

@ -19,7 +19,6 @@ export default i18n => {
createdAt
badges {
id
key
icon
}
badgesCount
@ -39,7 +38,6 @@ export default i18n => {
commentsCount
badges {
id
key
icon
}
location {
@ -61,7 +59,6 @@ export default i18n => {
commentsCount
badges {
id
key
icon
}
location {

View File

@ -1,4 +1,7 @@
{
"filter-menu": {
"title": "Twoja bańka filtrująca"
},
"site": {
"made": "Z &#10084; zrobiony",
"imprint": "Nadruk",
@ -13,6 +16,7 @@
"responsible": "Odpowiedzialny zgodnie z § 55 Abs. 2 RStV (Niemcy)",
"bank": "rachunek bankowy",
"germany": "Niemcy"
},
"login": {
"copy": "Jeśli masz już konto Human Connection, zaloguj się tutaj.",
@ -20,9 +24,35 @@
"logout": "Wyloguj się",
"email": "Twój adres e-mail",
"password": "Twoje hasło",
"forgotPassword": "Zapomniałeś hasła?",
"moreInfo": "Co to jest Human Connection?",
"moreInfoURL": "https://human-connection.org/pl/",
"moreInfoHint": "na stronę prezentacji",
"hello": "Cześć"
},
"password-reset": {
"title": "Zresetuj hasło",
"form": {
"description": "Na podany adres e-mail zostanie wysłany email z resetem hasła.",
"submit": "Poproś o wiadomość e-mail",
"submitted": "Na adres <b>{email}</b> została wysłana wiadomość z dalszymi instrukcjami."
}
},
"verify-code": {
"form": {
"code": "Wprowadź swój kod",
"description": "Otwórz swoją skrzynkę odbiorczą i wpisz kod, który do Ciebie wysłaliśmy.",
"next": "Kontynuuj",
"change-password": {
"success": "Zmiana hasła zakończyła się sukcesem!",
"error": "Zmiana hasła nie powiodła się. Może kod bezpieczeństwa nie był poprawny?",
"help": "W przypadku problemów, zachęcamy do zwrócenia się o pomoc, wysyłając do nas wiadomość e-mail:"
}
}
},
"editor": {
"placeholder": "Zostaw swoje inspirujące myśli...."
},
"profile": {
"name": "Mój profil",
"memberSince": "Członek od",
@ -31,7 +61,27 @@
"following": "Obserwowani",
"shouted": "Krzyknij",
"commented": "Skomentuj",
"userAnonym": "Anonymous"
"userAnonym": "Anonimowy",
"socialMedia": "Gdzie indziej mogę znaleźć",
"network": {
"title": "Sieć",
"following": "jest następująca:",
"followingNobody": "nie podąża za nikim.",
"followedBy": "po którym następuje:",
"followedByNobody": "nie jest śledzona przez nikogo.",
"and": "i",
"more": "więcej"
}
},
"notifications": {
"menu": {
"mentioned": "wspomniała o tobie na posterunku."
}
},
"search": {
"placeholder": "Wyszukiwanie",
"hint": "Czego szukasz?",
"failed": "Nic nie znaleziono"
},
"settings": {
"name": "Ustawienia",
@ -40,10 +90,28 @@
"labelName": "Twoje dane",
"namePlaceholder": "Anonymous",
"labelCity": "Twoje miasto lub region",
"labelBio": "O Tobie"
"labelBio": "O Tobie",
"success": "Twoje dane zostały pomyślnie zaktualizowane!"
},
"security": {
"name": "Bezpieczeństwo"
"name": "Bezpieczeństwo",
"change-password": {
"button": "Zmień hasło",
"success": "Hasło zostało pomyślnie zmienione!",
"label-old-password": "Twoje stare hasło",
"label-new-password": "Twoje nowe hasło",
"label-new-password-confirm": "Potwierdź nowe hasło",
"message-old-password-required": "Wprowadź swoje stare hasło",
"message-new-password-required": "Wprowadź nowe hasło",
"message-new-password-confirm-required": "Potwierdź nowe hasło.",
"message-new-password-missmatch": "Wpisz ponownie to samo hasło.",
"passwordSecurity": "Zabezpieczenie hasłem",
"passwordStrength0": "Bardzo niepewne hasło",
"passwordStrength1": "Niepewne hasło",
"passwordStrength2": "Hasło pośredniczące",
"passwordStrength3": "Silne hasło",
"passwordStrength4": "Bardzo mocne hasło"
}
},
"invites": {
"name": "Zaproszenia"
@ -51,29 +119,42 @@
"download": {
"name": "Pobierz dane"
},
"delete": {
"name": "Usuń konto"
"deleteUserAccount": {
"name": "Usuwanie danych",
"contributionsCount": "Usuń moje stanowiska.",
"commentsCount": "Usuń moje komentarze {liczba}.",
"accountDescription": "Bądź świadomy, że Twój post i komentarze są ważne dla naszej społeczności. Jeśli nadal chcesz je usunąć, musisz zaznaczyć je poniżej.",
"accountWarning": "<b>Nie możesz zarządzać</b> i <b>Nie możesz REKOVER</b> swoje konto, posty lub komentarze po usunięciu konta!",
"success": "Konto zostało pomyślnie usunięte",
"pleaseConfirm": "<b class='is-danger'>Niszczycielskie działanie!</b> Typ <b>{potwierdź}</b> aby potwierdzić"
},
"organizations": {
"name": "Moje organizacje"
"name": "My Organizations"
},
"languages": {
"name": "Języki"
"name": "Languages"
},
"social-media": {
"name": "Social media",
"placeholder": "Add social media url",
"submit": "Add link",
"successAdd": "Added social media. Updated user profile!",
"successDelete": "Deleted social media. Updated user profile!"
}
},
"admin": {
"name": "Administrator",
"name": "Admin",
"dashboard": {
"name": "Tablica rozdzielcza",
"users": "Użytkownicy",
"posts": "Posty",
"posts": "Stanowiska",
"comments": "Komentarze",
"notifications": "Powiadomienia",
"organizations": "Organizacje",
"projects": "Projekty",
"invites": "Zaproszenia",
"follows": "Obserwowań",
"shouts": "Okrzyk"
"invites": "Zaprasza",
"follows": "Podąża za",
"shouts": "Zalecane"
},
"organizations": {
"name": "Organizacje"
@ -90,116 +171,193 @@
"categories": {
"name": "Kategorie",
"categoryName": "Nazwa",
"postCount": "Posty"
"postCount": "Stanowiska"
},
"tags": {
"name": "Tagi",
"name": "Znaczniki",
"tagCountUnique": "Użytkownicy",
"tagCount": "Posty"
"tagCount": "Stanowiska"
},
"settings": {
"name": "Ustawienia"
}
},
"post": {
"name": "Post",
"name": "Poczta",
"moreInfo": {
"name": "Więcej informacji"
},
"takeAction": {
"name": "Podejmij działanie"
"name": "Podejmij działania"
},
"menu": {
"edit": "Edytuj Post",
"delete": "Usuń wpis"
},
"comment": {
"submit": "Komentarz",
"submitted": "Przedłożony komentarz"
}
},
"comment": {
"content": {
"unavailable-placeholder": " ...ten komentarz nie jest już dostępny."
},
"menu": {
"edit": "Edytuj komentarz",
"delete": "Usuń komentarz"
},
"show": {
"more": "Pokaż więcej",
"less": "Pokaż mniej"
}
},
"quotes": {
"african": {
"quote": "Wielu małych ludzi w wielu małych miejscach robi wiele małych rzeczy, które mogą zmienić oblicze świata.",
"quote": "Wielu małych ludzi w wielu małych miejscowościach robi wiele małych rzeczy, które mogą zmienić oblicze świata.",
"author": "Afrykańskie przysłowie"
}
},
"common": {
"post": "Post ::: Posty",
"post": "Poczta ::: Posty",
"comment": "Komentarz ::: Komentarze",
"letsTalk": "Porozmawiajmy",
"versus": "Versus",
"versus": "werset",
"moreInfo": "Więcej informacji",
"takeAction": "Podejmij działanie",
"shout": "okrzyk okrzyki",
"takeAction": "Podejmij działania",
"shout": "przekazanie sprawy ::: Polecam tę stronę",
"user": "Użytkownik ::: Użytkownicy",
"category": "kategoria kategorie",
"organization": "Organizacja ::: Organizacje",
"category": "Kategoria ::: Kategorie",
"organization": "Organization ::: Organizations",
"project": "Projekt ::: Projekty",
"tag": "Tag ::: Tagi",
"name": "imię",
"loadMore": "załaduj więcej",
"loading": "ładowanie",
"reportContent": "Raport"
"tag": "Znacznik ::: Znaczniki",
"name": "Nazwa",
"loadMore": "Obciążenie więcej",
"loading": "załadunek",
"reportContent": "Sprawozdanie",
"validations": {
"email": "musi być ważny adres e-mail.",
"verification-code": "musi mieć długość 6 znaków."
}
},
"actions": {
"loading": "ładowanie",
"loadMore": "załaduj więcej",
"create": "Stwórz",
"save": "Zapisz",
"edit": "Edytuj",
"loading": "załadunek",
"loadMore": "Obciążenie więcej",
"create": "Tworzenie",
"save": "Oszczędzaj",
"edit": "Edycja",
"delete": "Usuń",
"cancel": "Anuluj"
"cancel": "Odwołaj"
},
"moderation": {
"name": "Moderacja",
"name": "Umiarkowanie",
"reports": {
"empty": "Gratulacje, moderacja nie jest potrzebna",
"name": "Raporty",
"reporter": "zgłoszone przez"
"empty": "Gratulacje, nic do umiarkowanego.",
"name": "Sprawozdania",
"submitter": "zgłaszane przez",
"disabledBy": "niepełnosprawni przez"
}
},
"disable": {
"submit": "Niepełnosprawność",
"cancel": "Odwołaj",
"success": "Niepełnosprawni skutecznie",
"user": {
"title": "Ukryj użytkownika",
"title": "Wyłączenie użytkownika",
"type": "Użytkownik",
"message": "Czy na pewno chcesz wyłączyć użytkownika \" <b> {name} </b> \"?"
"message": "Czy naprawdę chcesz wyłączyć użytkownika \"<b>{name}</b>\"?"
},
"contribution": {
"title": "Ukryj wpis",
"type": "Wpis / Post",
"message": "Czy na pewno chcesz ukryć wpis \" <b> tytuł} </b> \"?"
"title": "Wyłącz Wkład",
"type": "Wkład",
"message": "Naprawdę chcesz unieszkodliwić ten wkład \"<b>{name}</b>\"?"
},
"comment": {
"title": "Ukryj wpis",
"title": "Wyłącz komentarz",
"type": "Komentarz",
"message": "Czy na pewno chcesz ukryć komentarz użytkownika\"<b>(Imie/Avatar</b>\"?"
"message": "Naprawdę chcesz wyłączyć komentarz \"<b>{name}</b>\"?"
}
},
"delete": {
"submit": "Usuń",
"cancel": "Odwołaj",
"contribution": {
"title": "Usuń Post",
"type": "Wkład",
"message": "Naprawdę chcesz usunąć post \"<b>{name}</b>\"?",
"success": "Wyślij pomyślnie usunięty!"
},
"comment": {
"title": "Usuń komentarz",
"type": "Komentarz",
"message": "Czy naprawdę chcesz usunąć komentarz \"<b>{name}</b>\"?",
"success": "Komentarz został pomyślnie usunięty!"
}
},
"report": {
"submit": "Wyślij raport",
"cancel": "Anuluj",
"submit": "Sprawozdanie",
"cancel": "Odwołaj",
"success": "Dzięki za zgłoszenie!",
"user": {
"title": "Zgłoś użytkownika",
"title": "Raport Użytkownik",
"type": "Użytkownik",
"message": "Czy na pewno chcesz zgłosić użytkownika \" <b> {Imie} </b> \"?"
"message": "Naprawdę chcesz zgłosić użytkownika \"<b>{name}</b>\"?",
"error": "Zgłosiłeś już użytkownika!"
},
"contribution": {
"title": "Zgłoś wpis",
"type": "Wpis / Post",
"message": "Czy na pewno chcesz zgłosić ten wpis użytkownika \" <b> {Imie} </b> \"?"
"title": "Wkład w raport",
"type": "Wkład",
"message": "Naprawdę chcesz zgłosić wkład, jaki wniosłaś do programu \"<b>{name}</b>\"?",
"error": "Zgłosiłeś już ten wkład!"
},
"comment": {
"title": "Zgłoś komentarz",
"title": "Sprawozdanie Komentarz",
"type": "Komentarz",
"message": "Czy na pewno chcesz zgłosić komentarz użytkownika\"<b>(Imie/Avatar</b>\"?"
"message": "Naprawdę chcesz zgłosić komentarz od \"<b>{name}</b>\"?",
"error": "Zgłosiłeś już komentarz!"
}
},
"followButton": {
"follow": "naśladować",
"following": "w skutek"
},
"shoutButton": {
"shouted": "wykrzyczany"
},
"release": {
"submit": "Zwolnienie",
"cancel": "Odwołaj",
"success": "Wydany z powodzeniem!",
"user": {
"title": "Zwolnienie użytkownika",
"type": "Użytkownik",
"message": "Naprawdę chcesz uwolnić użytkownika \"<b>{name}</b>\"?"
},
"contribution": {
"title": "Zwolnienie Wkład",
"type": "Wkład",
"message": "Naprawdę chcesz uwolnić swój wkład \"<b>{name}</b>\"?"
},
"comment": {
"title": "Zwolnienie komentarz",
"type": "komentarz",
"message": "Czy naprawdę chcesz opublikować komentarz od \"<b>{name}</b>\"?"
}
},
"user": {
"avatar": {
"submitted": "Przesłanie udane"
}
},
"contribution": {
"edit": "Edytuj wpis",
"delete": "Usuń wpis"
},
"comment": {
"edit": "Edytuj komentarz",
"delete": "Usuń komentarz"
},
"followButton": {
"follow": "Obserwuj",
"following": "Obserwowani"
},
"shoutButton": {
"shouted": "krzyczeć"
"newPost": "Utwórz nowy post",
"filterFollow": "Filtrowanie wkładu użytkowników, za którymi podążam",
"filterALL": "Wyświetl wszystkie wkłady",
"success": "Zachowany!",
"languageSelectLabel": "Język",
"categories": {
"infoSelectedNoOfMaxCategories": "{chosen} z {max} wybrane kategorie"
}
}
}

View File

@ -157,7 +157,6 @@ export default {
}
badges {
id
key
icon
}
}

View File

@ -111,7 +111,6 @@ export default {
}
badges {
id
key
icon
}
}

View File

@ -6863,7 +6863,7 @@ locate-path@^3.0.0:
p-locate "^3.0.0"
path-exists "^3.0.0"
lodash._reinterpolate@~3.0.0:
lodash._reinterpolate@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz#0ccf2d89166af03b3663c796538b75ac6e114d9d"
integrity sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=
@ -6924,19 +6924,19 @@ lodash.tail@^4.1.1:
integrity sha1-0jM6NtnncXyK0vfKyv7HwytERmQ=
lodash.template@^4.2.4, lodash.template@^4.4.0:
version "4.4.0"
resolved "https://registry.yarnpkg.com/lodash.template/-/lodash.template-4.4.0.tgz#e73a0385c8355591746e020b99679c690e68fba0"
integrity sha1-5zoDhcg1VZF0bgILmWecaQ5o+6A=
version "4.5.0"
resolved "https://registry.yarnpkg.com/lodash.template/-/lodash.template-4.5.0.tgz#f976195cf3f347d0d5f52483569fe8031ccce8ab"
integrity sha512-84vYFxIkmidUiFxidA/KjjH9pAycqW+h980j7Fuz5qxRtO9pgB7MDFTdys1N7A5mcucRiDyEq4fusljItR1T/A==
dependencies:
lodash._reinterpolate "~3.0.0"
lodash._reinterpolate "^3.0.0"
lodash.templatesettings "^4.0.0"
lodash.templatesettings@^4.0.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/lodash.templatesettings/-/lodash.templatesettings-4.1.0.tgz#2b4d4e95ba440d915ff08bc899e4553666713316"
integrity sha1-K01OlbpEDZFf8IvImeRVNmZxMxY=
version "4.2.0"
resolved "https://registry.yarnpkg.com/lodash.templatesettings/-/lodash.templatesettings-4.2.0.tgz#e481310f049d3cf6d47e912ad09313b154f0fb33"
integrity sha512-stgLz+i3Aa9mZgnjr/O+v9ruKZsPsndy7qPZOchbqk2cnTU1ZaldKK+v7m54WoKIyxiuMZTKT2H81F8BeAc3ZQ==
dependencies:
lodash._reinterpolate "~3.0.0"
lodash._reinterpolate "^3.0.0"
lodash.uniq@^4.5.0:
version "4.5.0"
@ -6949,9 +6949,9 @@ lodash.uniqueid@^4.0.1:
integrity sha1-MmjyanyI5PSxdY1nknGBTjH6WyY=
lodash@4.x, lodash@^4.0.0, lodash@^4.15.0, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.3, lodash@^4.17.4, lodash@^4.17.5, lodash@~4.17.10:
version "4.17.11"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.11.tgz#b39ea6229ef607ecd89e2c8df12536891cac9b8d"
integrity sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==
version "4.17.14"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.14.tgz#9ce487ae66c96254fe20b599f21b6816028078ba"
integrity sha512-mmKYbW3GLuJeX+iGP+Y7Gp1AiGHGbXHCOh/jZmrawMmsE7MS4znI3RL2FsjbqOyMayHInjOeykW7PEajUk1/xw==
log-symbols@^2.2.0:
version "2.2.0"

View File

@ -1827,10 +1827,10 @@ cypress-cucumber-preprocessor@^1.12.0:
glob "^7.1.2"
through "^2.3.8"
cypress-file-upload@^3.2.0:
version "3.2.0"
resolved "https://registry.yarnpkg.com/cypress-file-upload/-/cypress-file-upload-3.2.0.tgz#a48282e1fea385ba6aef9ec3296a934026f5fd67"
integrity sha512-C1nFgURTgvtz9MpP7sYKjhKSdgQvDhUs3f4w6hvEH33wDDQUkmXwrozKDvxXSdccc07M7wH4O5JF61sTkvY8lA==
cypress-file-upload@^3.2.1:
version "3.2.1"
resolved "https://registry.yarnpkg.com/cypress-file-upload/-/cypress-file-upload-3.2.1.tgz#12befbd5f685883b2ce39133d675173f60caae5b"
integrity sha512-Wx9+DVon1Sc8HhiNpWaCYvjn5q8izYg9+Es0MhwlRj2APRToaihtM0EJgS/om9gA9HeKbU0ReTpv+xk/0VCUjw==
cypress-plugin-retries@^1.2.2:
version "1.2.2"