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 691_handle-large-file-sizes-bug
This commit is contained in:
commit
e09ef35c4a
@ -1,4 +1,4 @@
|
||||
FROM node:10-alpine as base
|
||||
FROM node:12.3.1-alpine as base
|
||||
LABEL Description="Backend of the Social Network Human-Connection.org" Vendor="Human Connection gGmbH" Version="0.0.1" Maintainer="Human Connection gGmbH (developer@human-connection.org)"
|
||||
|
||||
EXPOSE 4000
|
||||
|
||||
@ -6,8 +6,8 @@
|
||||
"scripts": {
|
||||
"build": "babel src/ -d dist/ --copy-files",
|
||||
"start": "node dist/",
|
||||
"dev": "nodemon --exec babel-node src/ -e js,graphql",
|
||||
"dev:debug": "nodemon --exec babel-node --inspect=0.0.0.0:9229 src/index.js -e js,graphql",
|
||||
"dev": "nodemon --exec babel-node src/ -e js,gql",
|
||||
"dev:debug": "nodemon --exec babel-node --inspect=0.0.0.0:9229 src/index.js -e js,gql",
|
||||
"lint": "eslint src --config .eslintrc.js",
|
||||
"test": "run-s test:jest test:cucumber",
|
||||
"test:before:server": "cross-env GRAPHQL_URI=http://localhost:4123 GRAPHQL_PORT=4123 yarn run dev 2> /dev/null",
|
||||
@ -47,7 +47,7 @@
|
||||
"apollo-client": "~2.5.1",
|
||||
"apollo-link-context": "~1.0.14",
|
||||
"apollo-link-http": "~1.5.14",
|
||||
"apollo-server": "~2.5.0",
|
||||
"apollo-server": "~2.5.1",
|
||||
"bcryptjs": "~2.4.3",
|
||||
"cheerio": "~1.0.0-rc.3",
|
||||
"cors": "~2.8.5",
|
||||
@ -68,6 +68,7 @@
|
||||
"jsonwebtoken": "~8.5.1",
|
||||
"linkifyjs": "~2.1.8",
|
||||
"lodash": "~4.17.11",
|
||||
"merge-graphql-schemas": "^1.5.8",
|
||||
"ms": "~2.1.1",
|
||||
"neo4j-driver": "~1.7.4",
|
||||
"neo4j-graphql-js": "git+https://github.com/Human-Connection/neo4j-graphql-js.git#temporary_fixes",
|
||||
@ -87,15 +88,15 @@
|
||||
"@babel/plugin-proposal-throw-expressions": "^7.2.0",
|
||||
"@babel/preset-env": "~7.4.5",
|
||||
"@babel/register": "~7.4.4",
|
||||
"apollo-server-testing": "~2.5.0",
|
||||
"apollo-server-testing": "~2.5.1",
|
||||
"babel-core": "~7.0.0-0",
|
||||
"babel-eslint": "~10.0.1",
|
||||
"babel-jest": "~24.8.0",
|
||||
"chai": "~4.2.0",
|
||||
"cucumber": "~5.1.0",
|
||||
"eslint": "~5.16.0",
|
||||
"eslint-config-standard": "~12.0.0",
|
||||
"eslint-config-prettier": "~4.3.0",
|
||||
"eslint-config-standard": "~12.0.0",
|
||||
"eslint-plugin-import": "~2.17.3",
|
||||
"eslint-plugin-jest": "~22.6.4",
|
||||
"eslint-plugin-node": "~9.1.0",
|
||||
|
||||
@ -1,41 +1,2 @@
|
||||
import fs from 'fs'
|
||||
import path from 'path'
|
||||
|
||||
import userManagement from './resolvers/user_management.js'
|
||||
import statistics from './resolvers/statistics.js'
|
||||
import reports from './resolvers/reports.js'
|
||||
import posts from './resolvers/posts.js'
|
||||
import moderation from './resolvers/moderation.js'
|
||||
import follow from './resolvers/follow.js'
|
||||
import shout from './resolvers/shout.js'
|
||||
import rewards from './resolvers/rewards.js'
|
||||
import socialMedia from './resolvers/socialMedia.js'
|
||||
import notifications from './resolvers/notifications'
|
||||
import comments from './resolvers/comments'
|
||||
import users from './resolvers/users'
|
||||
|
||||
export const typeDefs = fs
|
||||
.readFileSync(process.env.GRAPHQL_SCHEMA || path.join(__dirname, 'schema.graphql'))
|
||||
.toString('utf-8')
|
||||
|
||||
export const resolvers = {
|
||||
Query: {
|
||||
...statistics.Query,
|
||||
...userManagement.Query,
|
||||
...notifications.Query,
|
||||
...comments.Query,
|
||||
},
|
||||
Mutation: {
|
||||
...userManagement.Mutation,
|
||||
...reports.Mutation,
|
||||
...posts.Mutation,
|
||||
...moderation.Mutation,
|
||||
...follow.Mutation,
|
||||
...shout.Mutation,
|
||||
...rewards.Mutation,
|
||||
...socialMedia.Mutation,
|
||||
...notifications.Mutation,
|
||||
...comments.Mutation,
|
||||
...users.Mutation,
|
||||
},
|
||||
}
|
||||
export { default as typeDefs } from './types'
|
||||
export { default as resolvers } from './resolvers'
|
||||
|
||||
@ -41,8 +41,8 @@ describe('badges', () => {
|
||||
mutation(
|
||||
$id: ID
|
||||
$key: String!
|
||||
$type: BadgeTypeEnum!
|
||||
$status: BadgeStatusEnum!
|
||||
$type: BadgeType!
|
||||
$status: BadgeStatus!
|
||||
$icon: String!
|
||||
) {
|
||||
CreateBadge(id: $id, key: $key, type: $type, status: $status, icon: $icon) {
|
||||
|
||||
5
backend/src/resolvers/index.js
Normal file
5
backend/src/resolvers/index.js
Normal file
@ -0,0 +1,5 @@
|
||||
import path from 'path'
|
||||
import { fileLoader, mergeResolvers } from 'merge-graphql-schemas'
|
||||
|
||||
const resolversArray = fileLoader(path.join(__dirname, './!(*.spec).js'))
|
||||
export default mergeResolvers(resolversArray)
|
||||
@ -14,8 +14,8 @@ export default function(params) {
|
||||
mutation(
|
||||
$id: ID
|
||||
$key: String!
|
||||
$type: BadgeTypeEnum!
|
||||
$status: BadgeStatusEnum!
|
||||
$type: BadgeType!
|
||||
$status: BadgeStatus!
|
||||
$icon: String!
|
||||
) {
|
||||
CreateBadge(id: $id, key: $key, type: $type, status: $status, icon: $icon) {
|
||||
|
||||
@ -26,7 +26,7 @@ export default function(params) {
|
||||
$title: String!
|
||||
$content: String!
|
||||
$image: String
|
||||
$visibility: VisibilityEnum
|
||||
$visibility: Visibility
|
||||
$deleted: Boolean
|
||||
) {
|
||||
CreatePost(
|
||||
|
||||
@ -23,7 +23,7 @@ export default function create(params) {
|
||||
$email: String!
|
||||
$avatar: String
|
||||
$about: String
|
||||
$role: UserGroupEnum
|
||||
$role: UserGroup
|
||||
) {
|
||||
CreateUser(
|
||||
id: $id
|
||||
|
||||
4
backend/src/types/enum/BadgeStatus.gql
Normal file
4
backend/src/types/enum/BadgeStatus.gql
Normal file
@ -0,0 +1,4 @@
|
||||
enum BadgeStatus {
|
||||
permanent
|
||||
temporary
|
||||
}
|
||||
4
backend/src/types/enum/BadgeType.gql
Normal file
4
backend/src/types/enum/BadgeType.gql
Normal file
@ -0,0 +1,4 @@
|
||||
enum BadgeType {
|
||||
role
|
||||
crowdfunding
|
||||
}
|
||||
5
backend/src/types/enum/UserGroup.gql
Normal file
5
backend/src/types/enum/UserGroup.gql
Normal file
@ -0,0 +1,5 @@
|
||||
enum UserGroup {
|
||||
admin
|
||||
moderator
|
||||
user
|
||||
}
|
||||
5
backend/src/types/enum/Visibility.gql
Normal file
5
backend/src/types/enum/Visibility.gql
Normal file
@ -0,0 +1,5 @@
|
||||
enum Visibility {
|
||||
public
|
||||
friends
|
||||
private
|
||||
}
|
||||
30
backend/src/types/index.js
Normal file
30
backend/src/types/index.js
Normal file
@ -0,0 +1,30 @@
|
||||
import fs from 'fs'
|
||||
import path from 'path'
|
||||
import { mergeTypes } from 'merge-graphql-schemas'
|
||||
|
||||
const findGqlFiles = dir => {
|
||||
var results = []
|
||||
var list = fs.readdirSync(dir)
|
||||
list.forEach(file => {
|
||||
file = path.join(dir, file).toString('utf-8')
|
||||
var stat = fs.statSync(file)
|
||||
if (stat && stat.isDirectory()) {
|
||||
// Recurse into a subdirectory
|
||||
results = results.concat(findGqlFiles(file))
|
||||
} else {
|
||||
if (path.extname(file) === '.gql') {
|
||||
// Is a gql file
|
||||
results.push(file)
|
||||
}
|
||||
}
|
||||
})
|
||||
return results
|
||||
}
|
||||
|
||||
let typeDefs = []
|
||||
|
||||
findGqlFiles(__dirname).forEach(file => {
|
||||
typeDefs.push(fs.readFileSync(file).toString('utf-8'))
|
||||
})
|
||||
|
||||
export default mergeTypes(typeDefs, { all: true })
|
||||
1
backend/src/types/scalar/Date.gql_
Normal file
1
backend/src/types/scalar/Date.gql_
Normal file
@ -0,0 +1 @@
|
||||
scalar Date
|
||||
1
backend/src/types/scalar/DateTime.gql_
Normal file
1
backend/src/types/scalar/DateTime.gql_
Normal file
@ -0,0 +1 @@
|
||||
scalar DateTime
|
||||
1
backend/src/types/scalar/Time.gql_
Normal file
1
backend/src/types/scalar/Time.gql_
Normal file
@ -0,0 +1 @@
|
||||
scalar Time
|
||||
1
backend/src/types/scalar/Upload.gql
Normal file
1
backend/src/types/scalar/Upload.gql
Normal file
@ -0,0 +1 @@
|
||||
scalar Upload
|
||||
134
backend/src/types/schema.gql
Normal file
134
backend/src/types/schema.gql
Normal file
@ -0,0 +1,134 @@
|
||||
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
|
||||
}
|
||||
|
||||
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 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")
|
||||
}
|
||||
|
||||
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 SharedInboxEndpoint {
|
||||
id: ID!
|
||||
uri: String
|
||||
}
|
||||
|
||||
type SocialMedia {
|
||||
id: ID!
|
||||
url: String
|
||||
ownedBy: [User]! @relation(name: "OWNED", direction: "IN")
|
||||
}
|
||||
|
||||
13
backend/src/types/type/Badge.gql
Normal file
13
backend/src/types/type/Badge.gql
Normal file
@ -0,0 +1,13 @@
|
||||
type Badge {
|
||||
id: ID!
|
||||
key: String!
|
||||
type: BadgeType!
|
||||
status: BadgeStatus!
|
||||
icon: String!
|
||||
#createdAt: DateTime
|
||||
#updatedAt: DateTime
|
||||
createdAt: String
|
||||
updatedAt: String
|
||||
|
||||
rewarded: [User]! @relation(name: "REWARDED", direction: "OUT")
|
||||
}
|
||||
13
backend/src/types/type/Category.gql
Normal file
13
backend/src/types/type/Category.gql
Normal file
@ -0,0 +1,13 @@
|
||||
type Category {
|
||||
id: ID!
|
||||
name: String!
|
||||
slug: String
|
||||
icon: String!
|
||||
#createdAt: DateTime
|
||||
#updatedAt: DateTime
|
||||
createdAt: String
|
||||
updatedAt: String
|
||||
|
||||
posts: [Post]! @relation(name: "CATEGORIZED", direction: "IN")
|
||||
postCount: Int! @cypher(statement: "MATCH (this)<-[:CATEGORIZED]-(r:Post) RETURN COUNT(r)")
|
||||
}
|
||||
14
backend/src/types/type/Comment.gql
Normal file
14
backend/src/types/type/Comment.gql
Normal file
@ -0,0 +1,14 @@
|
||||
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")
|
||||
}
|
||||
43
backend/src/types/type/Post.gql
Normal file
43
backend/src/types/type/Post.gql
Normal file
@ -0,0 +1,43 @@
|
||||
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: Visibility
|
||||
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
|
||||
"""
|
||||
)
|
||||
}
|
||||
10
backend/src/types/type/Tag.gql
Normal file
10
backend/src/types/type/Tag.gql
Normal file
@ -0,0 +1,10 @@
|
||||
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
|
||||
}
|
||||
80
backend/src/types/type/User.gql
Normal file
80
backend/src/types/type/User.gql
Normal file
@ -0,0 +1,80 @@
|
||||
type User {
|
||||
id: ID!
|
||||
actorId: String
|
||||
name: String
|
||||
email: String!
|
||||
slug: String
|
||||
password: String!
|
||||
avatar: String
|
||||
coverImg: String
|
||||
avatarUpload: Upload
|
||||
deleted: Boolean
|
||||
disabled: Boolean
|
||||
disabledBy: User @relation(name: "DISABLED", direction: "IN")
|
||||
role: UserGroup
|
||||
publicKey: String
|
||||
privateKey: String
|
||||
|
||||
wasInvited: Boolean
|
||||
wasSeeded: Boolean
|
||||
|
||||
location: Location @cypher(statement: "MATCH (this)-[:IS_IN]->(l:Location) RETURN l")
|
||||
locationName: String
|
||||
about: String
|
||||
socialMedia: [SocialMedia]! @relation(name: "OWNED", direction: "OUT")
|
||||
|
||||
#createdAt: DateTime
|
||||
#updatedAt: DateTime
|
||||
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)")
|
||||
}
|
||||
@ -2,6 +2,13 @@
|
||||
# yarn lockfile v1
|
||||
|
||||
|
||||
"@apollographql/apollo-tools@^0.3.6":
|
||||
version "0.3.7"
|
||||
resolved "https://registry.yarnpkg.com/@apollographql/apollo-tools/-/apollo-tools-0.3.7.tgz#3bc9c35b9fff65febd4ddc0c1fc04677693a3d40"
|
||||
integrity sha512-+ertvzAwzkYmuUtT8zH3Zi6jPdyxZwOgnYaZHY7iLnMVJDhQKWlkyjLMF8wyzlPiEdDImVUMm5lOIBZo7LkGlg==
|
||||
dependencies:
|
||||
apollo-env "0.5.1"
|
||||
|
||||
"@apollographql/apollo-tools@^0.3.6-alpha.1":
|
||||
version "0.3.6-alpha.1"
|
||||
resolved "https://registry.yarnpkg.com/@apollographql/apollo-tools/-/apollo-tools-0.3.6-alpha.1.tgz#5199b36c65c2fddc4f8bc8bb97642f74e9fb00c5"
|
||||
@ -9,10 +16,10 @@
|
||||
dependencies:
|
||||
apollo-env "0.4.1-alpha.1"
|
||||
|
||||
"@apollographql/graphql-playground-html@^1.6.6":
|
||||
version "1.6.6"
|
||||
resolved "https://registry.yarnpkg.com/@apollographql/graphql-playground-html/-/graphql-playground-html-1.6.6.tgz#022209e28a2b547dcde15b219f0c50f47aa5beb3"
|
||||
integrity sha512-lqK94b+caNtmKFs5oUVXlSpN3sm5IXZ+KfhMxOtr0LR2SqErzkoJilitjDvJ1WbjHlxLI7WtCjRmOLdOGJqtMQ==
|
||||
"@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==
|
||||
|
||||
"@babel/cli@~7.4.4":
|
||||
version "7.4.4"
|
||||
@ -1281,13 +1288,13 @@ anymatch@^2.0.0:
|
||||
micromatch "^3.1.4"
|
||||
normalize-path "^2.1.1"
|
||||
|
||||
apollo-cache-control@0.6.0:
|
||||
version "0.6.0"
|
||||
resolved "https://registry.yarnpkg.com/apollo-cache-control/-/apollo-cache-control-0.6.0.tgz#df22db28f850ea90a5722f5e92654d30c96e7f91"
|
||||
integrity sha512-66aCF6MHe0/FdD3knphwTv6CCIdb1ZxrMsiRpxP474qqyYVe2jAwBu6aJBn4emffZHZ7i6gp9dY6cPHThjnbKA==
|
||||
apollo-cache-control@0.6.1:
|
||||
version "0.6.1"
|
||||
resolved "https://registry.yarnpkg.com/apollo-cache-control/-/apollo-cache-control-0.6.1.tgz#c73ff521fe606faf18edcbd3463c421a966f3e5d"
|
||||
integrity sha512-M3cDeQDXtRxYPQ/sL4pu3IVE5Q/9jpBlENB2IjwxTDir+WFZbJV1CAnvVwyJdL1DvS6ESR35DFOurJH4Ws/OPA==
|
||||
dependencies:
|
||||
apollo-server-env "2.3.0"
|
||||
graphql-extensions "0.6.0"
|
||||
graphql-extensions "0.6.1"
|
||||
|
||||
apollo-cache-control@^0.1.0:
|
||||
version "0.1.1"
|
||||
@ -1353,17 +1360,17 @@ apollo-engine-reporting-protobuf@0.3.0:
|
||||
dependencies:
|
||||
protobufjs "^6.8.6"
|
||||
|
||||
apollo-engine-reporting@1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/apollo-engine-reporting/-/apollo-engine-reporting-1.1.0.tgz#10def3d3bf3f11ddb24765c19d9c81e30cb9d55c"
|
||||
integrity sha512-Dj0BwgcluHL0QVUaquhAoYoLX9Z4DRP/n2REcIwO8d2iy52r+1wN5QqZLx97dEFh7CjhNjTWeysJzc8XMWKa1Q==
|
||||
apollo-engine-reporting@1.1.1:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/apollo-engine-reporting/-/apollo-engine-reporting-1.1.1.tgz#f5a3240bc5c5afb210ff8c45d72995de7b0d2a13"
|
||||
integrity sha512-K7BDsj99jr8ftd9NIuHL4oF/S7CBFcgMGjL0ChhfxpkgUv80FPxJ+9Fs+9ZkKIVylV3PCi2WnihpDeEO10eZAw==
|
||||
dependencies:
|
||||
apollo-engine-reporting-protobuf "0.3.0"
|
||||
apollo-graphql "^0.2.1-alpha.1"
|
||||
apollo-server-core "2.5.0"
|
||||
apollo-server-core "2.5.1"
|
||||
apollo-server-env "2.3.0"
|
||||
async-retry "^1.2.1"
|
||||
graphql-extensions "0.6.0"
|
||||
graphql-extensions "0.6.1"
|
||||
|
||||
apollo-env@0.4.1-alpha.1:
|
||||
version "0.4.1-alpha.1"
|
||||
@ -1374,6 +1381,15 @@ apollo-env@0.4.1-alpha.1:
|
||||
node-fetch "^2.2.0"
|
||||
sha.js "^2.4.11"
|
||||
|
||||
apollo-env@0.5.1:
|
||||
version "0.5.1"
|
||||
resolved "https://registry.yarnpkg.com/apollo-env/-/apollo-env-0.5.1.tgz#b9b0195c16feadf0fe9fd5563edb0b9b7d9e97d3"
|
||||
integrity sha512-fndST2xojgSdH02k5hxk1cbqA9Ti8RX4YzzBoAB4oIe1Puhq7+YlhXGXfXB5Y4XN0al8dLg+5nAkyjNAR2qZTw==
|
||||
dependencies:
|
||||
core-js "^3.0.1"
|
||||
node-fetch "^2.2.0"
|
||||
sha.js "^2.4.11"
|
||||
|
||||
apollo-errors@^1.9.0:
|
||||
version "1.9.0"
|
||||
resolved "https://registry.yarnpkg.com/apollo-errors/-/apollo-errors-1.9.0.tgz#f1ed0ca0a6be5cd2f24e2eaa7b0860a10146ff51"
|
||||
@ -1440,24 +1456,24 @@ apollo-server-caching@0.4.0:
|
||||
dependencies:
|
||||
lru-cache "^5.0.0"
|
||||
|
||||
apollo-server-core@2.5.0:
|
||||
version "2.5.0"
|
||||
resolved "https://registry.yarnpkg.com/apollo-server-core/-/apollo-server-core-2.5.0.tgz#89fc28ba1018ebf9240bc3cc0c103fe705309023"
|
||||
integrity sha512-7hyQ/Rt0hC38bUfxMQmLNHDBIGEBykFWo9EO0W+3o/cno/SqBKd1KKichrABVv+v+SCvZAUutX6gYS5l3G+ULQ==
|
||||
apollo-server-core@2.5.1:
|
||||
version "2.5.1"
|
||||
resolved "https://registry.yarnpkg.com/apollo-server-core/-/apollo-server-core-2.5.1.tgz#0fdb6cfca56a0f5b5b3aecffb48db17b3c8e1d71"
|
||||
integrity sha512-4QNrW1AUM3M/p0+hbBX/MsjSjZTy+2rt7JpiKKkG9RmeEIzd/VG7hwwwloAZSLjYx3twz0+BnASJ9y+rGEPC8A==
|
||||
dependencies:
|
||||
"@apollographql/apollo-tools" "^0.3.6-alpha.1"
|
||||
"@apollographql/graphql-playground-html" "^1.6.6"
|
||||
"@apollographql/apollo-tools" "^0.3.6"
|
||||
"@apollographql/graphql-playground-html" "1.6.20"
|
||||
"@types/ws" "^6.0.0"
|
||||
apollo-cache-control "0.6.0"
|
||||
apollo-cache-control "0.6.1"
|
||||
apollo-datasource "0.4.0"
|
||||
apollo-engine-reporting "1.1.0"
|
||||
apollo-engine-reporting "1.1.1"
|
||||
apollo-server-caching "0.4.0"
|
||||
apollo-server-env "2.3.0"
|
||||
apollo-server-errors "2.3.0"
|
||||
apollo-server-plugin-base "0.4.0"
|
||||
apollo-tracing "0.6.0"
|
||||
apollo-server-plugin-base "0.4.1"
|
||||
apollo-tracing "0.6.1"
|
||||
fast-json-stable-stringify "^2.0.0"
|
||||
graphql-extensions "0.6.0"
|
||||
graphql-extensions "0.6.1"
|
||||
graphql-subscriptions "^1.0.0"
|
||||
graphql-tag "^2.9.2"
|
||||
graphql-tools "^4.0.0"
|
||||
@ -1488,18 +1504,18 @@ apollo-server-errors@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-express@2.5.0:
|
||||
version "2.5.0"
|
||||
resolved "https://registry.yarnpkg.com/apollo-server-express/-/apollo-server-express-2.5.0.tgz#ff6cbd3fcb8933f6316c5a5edd4db12d9a56fa65"
|
||||
integrity sha512-2gd3VWIqji2jyDYMTTqKzVU4/znjEjugtLUmPgVl5SoBvJSMTsO7VgJv+roBubZGDK8jXXUEXr2a33RtIeHe4g==
|
||||
apollo-server-express@2.5.1:
|
||||
version "2.5.1"
|
||||
resolved "https://registry.yarnpkg.com/apollo-server-express/-/apollo-server-express-2.5.1.tgz#b112d9795f2fb39076d9cbc109f5eeb7835bed6b"
|
||||
integrity sha512-528wDQnOMIenDaICkYPFWQykdXQZwpygxd+Ar0PmZiaST042NSVExV4iRWI09p1THqfsuyHygqpkK+K94bUtBA==
|
||||
dependencies:
|
||||
"@apollographql/graphql-playground-html" "^1.6.6"
|
||||
"@apollographql/graphql-playground-html" "1.6.20"
|
||||
"@types/accepts" "^1.3.5"
|
||||
"@types/body-parser" "1.17.0"
|
||||
"@types/cors" "^2.8.4"
|
||||
"@types/express" "4.16.1"
|
||||
accepts "^1.3.5"
|
||||
apollo-server-core "2.5.0"
|
||||
apollo-server-core "2.5.1"
|
||||
body-parser "^1.18.3"
|
||||
cors "^2.8.4"
|
||||
graphql-subscriptions "^1.0.0"
|
||||
@ -1527,36 +1543,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.4.0:
|
||||
version "0.4.0"
|
||||
resolved "https://registry.yarnpkg.com/apollo-server-plugin-base/-/apollo-server-plugin-base-0.4.0.tgz#38a3c37767043873dd1b07143d4e70eecbb09562"
|
||||
integrity sha512-iD7ARNtwnvHGd1EMPK0CuodM8d8hgDvFwTfIDzJY04QIQ6/KrBFaWhnCXJsy+HMb47GovwBbq67IK6eb2WJgBg==
|
||||
apollo-server-plugin-base@0.4.1:
|
||||
version "0.4.1"
|
||||
resolved "https://registry.yarnpkg.com/apollo-server-plugin-base/-/apollo-server-plugin-base-0.4.1.tgz#be380b28d71ad3b6b146d0d6a8f7ebf5675b07ff"
|
||||
integrity sha512-D2G6Ca/KBdQgEbmSfYqZqYbdVJnk/rrSv7Vj2NntwjfL7WJf0TjufxYJlrTH5jF6xCbsszDNGqfmt2Nm8x/o4g==
|
||||
|
||||
apollo-server-testing@~2.5.0:
|
||||
version "2.5.0"
|
||||
resolved "https://registry.yarnpkg.com/apollo-server-testing/-/apollo-server-testing-2.5.0.tgz#6c4c386ddbcc5e555a02afc2c625955150827969"
|
||||
integrity sha512-mjUjcdsm6np7dnx5Dy7v0k0cwNHIdTHuTZUUgLuYUPtJUS+QOmOQ4yNpglPnHwY8TXx/asFnKGKvrO5mUrUedA==
|
||||
apollo-server-testing@~2.5.1:
|
||||
version "2.5.1"
|
||||
resolved "https://registry.yarnpkg.com/apollo-server-testing/-/apollo-server-testing-2.5.1.tgz#9f210caa738a275a30269b6d8a3b29bce01b69a1"
|
||||
integrity sha512-npaj92Z33sNt4beBuoLJqlicqtawqI/41CA9/IrcswI9WwlWIxNKhfpcMYo9MpQWRT8aCIGOOAkBdG2jZlhH4Q==
|
||||
dependencies:
|
||||
apollo-server-core "2.5.0"
|
||||
apollo-server-core "2.5.1"
|
||||
|
||||
apollo-server@~2.5.0:
|
||||
version "2.5.0"
|
||||
resolved "https://registry.yarnpkg.com/apollo-server/-/apollo-server-2.5.0.tgz#a88a550dbc5ff0c6713142d1cab3b61b4a36e483"
|
||||
integrity sha512-85A3iAnXVP5QiXc0xvAJRyGsoxov06+8AzttKqehR4Q50UC1Is62xY5WZk58oW7fm+awpqh+sXB2F2E6tObSmg==
|
||||
apollo-server@~2.5.1:
|
||||
version "2.5.1"
|
||||
resolved "https://registry.yarnpkg.com/apollo-server/-/apollo-server-2.5.1.tgz#bfcfbebc123f692c0e6d85b0c56739646bd1bb7e"
|
||||
integrity sha512-eH3ubq300xhpFAxek28kb+5WZINXpWcwzyNqBQDbuasTlW8qSsqY7xrV6IIz6WUYKdX+ET0mx+Ta1DdaYQPrqw==
|
||||
dependencies:
|
||||
apollo-server-core "2.5.0"
|
||||
apollo-server-express "2.5.0"
|
||||
apollo-server-core "2.5.1"
|
||||
apollo-server-express "2.5.1"
|
||||
express "^4.0.0"
|
||||
graphql-subscriptions "^1.0.0"
|
||||
graphql-tools "^4.0.0"
|
||||
|
||||
apollo-tracing@0.6.0:
|
||||
version "0.6.0"
|
||||
resolved "https://registry.yarnpkg.com/apollo-tracing/-/apollo-tracing-0.6.0.tgz#afc2b9cbea173dc4c315a5d98053797469518083"
|
||||
integrity sha512-OpYPHVBgcQ/HT2WLXJQWwhilzR1rrl01tZeMU2N7yinsp/oyKngF5aUSMtuvX1k/T3abilQo+w10oAQlBCGdPA==
|
||||
apollo-tracing@0.6.1:
|
||||
version "0.6.1"
|
||||
resolved "https://registry.yarnpkg.com/apollo-tracing/-/apollo-tracing-0.6.1.tgz#48a6d6040f9b2f2b4365a890c2e97cb763eb2392"
|
||||
integrity sha512-rrDBgTHa9GDA3wY8O7rDsFwC6ePIVzRGxpUsThgmLvIVkkCr0KS4wJJ4C01c+v4xsOXNuQwx0IyYhxZt4twwcA==
|
||||
dependencies:
|
||||
apollo-server-env "2.3.0"
|
||||
graphql-extensions "0.6.0"
|
||||
graphql-extensions "0.6.1"
|
||||
|
||||
apollo-tracing@^0.1.0:
|
||||
version "0.1.4"
|
||||
@ -2440,6 +2456,11 @@ core-js@^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:
|
||||
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==
|
||||
|
||||
core-util-is@1.0.2, core-util-is@~1.0.0:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
|
||||
@ -2656,6 +2677,11 @@ deep-is@~0.1.3:
|
||||
resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34"
|
||||
integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=
|
||||
|
||||
deepmerge@^2.2.1:
|
||||
version "2.2.1"
|
||||
resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-2.2.1.tgz#5d3ff22a01c00f645405a2fbc17d0778a1801170"
|
||||
integrity sha512-R9hc1Xa/NOBi9WRVUWg19rl1UB7Tt4kuPd+thNJgFZoxXsTz7ncaPaeIm+40oSGuP33DfMb4sZt1QIGiJzC4EA==
|
||||
|
||||
define-properties@^1.1.2:
|
||||
version "1.1.3"
|
||||
resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1"
|
||||
@ -3723,10 +3749,10 @@ 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.6.0:
|
||||
version "0.6.0"
|
||||
resolved "https://registry.yarnpkg.com/graphql-extensions/-/graphql-extensions-0.6.0.tgz#3ee3aa57fe213f90aec5cd31275f6d04767c6a23"
|
||||
integrity sha512-SshzmbD68fHXRv2q3St29olMOxHDLQ5e9TOh+Tz2BYxinrfhjFaPNcEefiK/vF295wW827Y58bdO11Xmhf8J+Q==
|
||||
graphql-extensions@0.6.1:
|
||||
version "0.6.1"
|
||||
resolved "https://registry.yarnpkg.com/graphql-extensions/-/graphql-extensions-0.6.1.tgz#e61c4cb901e336dc5993a61093a8678a021dda59"
|
||||
integrity sha512-vB2WNQJn99pncHfvxgcdyVoazmG3cD8XzkgcaDrHTvV+xJGJEBP6056EWi0mNt1d6ukYyRS2zexdekmMCjcq0w==
|
||||
dependencies:
|
||||
"@apollographql/apollo-tools" "^0.3.6-alpha.1"
|
||||
|
||||
@ -5388,6 +5414,15 @@ merge-descriptors@1.0.1:
|
||||
resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61"
|
||||
integrity sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=
|
||||
|
||||
merge-graphql-schemas@^1.5.8:
|
||||
version "1.5.8"
|
||||
resolved "https://registry.yarnpkg.com/merge-graphql-schemas/-/merge-graphql-schemas-1.5.8.tgz#89457b60312aabead44d5b2b7625643f8ab9e369"
|
||||
integrity sha512-0TGOKebltvmWR9h9dPYS2vAqMPThXwJ6gVz7O5MtpBp2sunAg/M25iMSNI7YhU6PDJVtGtldTfqV9a+55YhB+A==
|
||||
dependencies:
|
||||
deepmerge "^2.2.1"
|
||||
glob "^7.1.3"
|
||||
is-glob "^4.0.0"
|
||||
|
||||
merge-stream@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-1.0.1.tgz#4041202d508a342ba00174008df0c251b8c135e1"
|
||||
|
||||
@ -38,7 +38,7 @@ your deployed kubernetes pods.
|
||||
## Create a namespace
|
||||
|
||||
```bash
|
||||
# in folder deployment/human-connection/
|
||||
# in folder deployment/
|
||||
$ kubectl apply -f namespace.yaml
|
||||
```
|
||||
|
||||
|
||||
@ -56,7 +56,7 @@ Deploy one-time maintenance-worker pod:
|
||||
|
||||
```bash
|
||||
# in deployment/legacy-migration/
|
||||
$ kubectl apply -f db-migration-worker.yaml
|
||||
$ kubectl apply -f maintenance-worker.yaml
|
||||
pod/nitro-maintenance-worker created
|
||||
```
|
||||
|
||||
@ -65,7 +65,7 @@ Import legacy database and uploads:
|
||||
```bash
|
||||
$ kubectl --namespace=human-connection exec -it nitro-maintenance-worker bash
|
||||
$ import_legacy_db
|
||||
$ import_uploads
|
||||
$ import_legacy_uploads
|
||||
$ exit
|
||||
```
|
||||
|
||||
|
||||
@ -8,6 +8,9 @@
|
||||
containers:
|
||||
- name: nitro-maintenance-worker
|
||||
image: humanconnection/maintenance-worker:latest
|
||||
env:
|
||||
- name: NEO4J_apoc_import_file_enabled
|
||||
value: "true"
|
||||
envFrom:
|
||||
- configMapRef:
|
||||
name: maintenance-worker
|
||||
@ -18,7 +21,7 @@
|
||||
readOnly: false
|
||||
mountPath: /root/.ssh
|
||||
- name: uploads
|
||||
mountPath: /nitro-backend/public/uploads
|
||||
mountPath: /uploads
|
||||
- name: neo4j-data
|
||||
mountPath: /data/
|
||||
volumes:
|
||||
|
||||
@ -3,9 +3,19 @@ FROM humanconnection/neo4j:latest
|
||||
ENV NODE_ENV=maintenance
|
||||
EXPOSE 7687 7474
|
||||
|
||||
ENV BUILD_DEPS="gettext" \
|
||||
RUNTIME_DEPS="libintl"
|
||||
|
||||
RUN set -x && \
|
||||
apk add --update $RUNTIME_DEPS && \
|
||||
apk add --virtual build_deps $BUILD_DEPS && \
|
||||
cp /usr/bin/envsubst /usr/local/bin/envsubst && \
|
||||
apk del build_deps
|
||||
|
||||
|
||||
RUN apk upgrade --update
|
||||
RUN apk add --no-cache mongodb-tools openssh nodejs yarn rsync
|
||||
|
||||
COPY known_hosts /root/.ssh/known_hosts
|
||||
COPY migration ./migration
|
||||
COPY migration /migration
|
||||
COPY ./binaries/* /usr/local/bin/
|
||||
|
||||
@ -5,11 +5,11 @@
|
||||
# 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='/tmp/mongo-export/splits/'
|
||||
|
||||
IMPORT_CHUNK_PATH_CQL='/tmp/mongo-export/splits/current-chunk.json'
|
||||
IMPORT_CHUNK_PATH_CQL='/tmp/mongo-export/splits/'
|
||||
# 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_CHUNK_PATH_CQL='C:/Users/dornhoeschen/AppData/Local/Temp/mongo-export/splits/'
|
||||
|
||||
IMPORT_CYPHERSHELL_BIN='cypher-shell'
|
||||
# On Windows use something like this
|
||||
|
||||
@ -0,0 +1 @@
|
||||
MATCH (n) DETACH DELETE n;
|
||||
@ -1,4 +1,46 @@
|
||||
CALL apoc.load.json("file:${IMPORT_CHUNK_PATH_CQL}") YIELD value as badge
|
||||
/*
|
||||
// Alpha Model
|
||||
// [ ] Not modeled in Nitro
|
||||
// [X] Modeled in Nitro
|
||||
// [-] Omitted in Nitro
|
||||
// [?] Unclear / has work to be done for Nitro
|
||||
{
|
||||
[?] image: {
|
||||
[?] path: { // Path is incorrect in Nitro - is icon the correct name for this field?
|
||||
[X] type: String,
|
||||
[X] required: true
|
||||
},
|
||||
[ ] alt: { // If we use an image - should we not have an alt?
|
||||
[ ] type: String,
|
||||
[ ] required: true
|
||||
}
|
||||
},
|
||||
[?] status: {
|
||||
[X] type: String,
|
||||
[X] enum: ['permanent', 'temporary'],
|
||||
[ ] default: 'permanent', // Default value is missing in Nitro
|
||||
[X] required: true
|
||||
},
|
||||
[?] type: {
|
||||
[?] type: String, // in nitro this is a defined enum - seems good for now
|
||||
[X] required: true
|
||||
},
|
||||
[X] key: {
|
||||
[X] type: String,
|
||||
[X] required: true
|
||||
},
|
||||
[?] createdAt: {
|
||||
[?] type: Date, // Type is modeled as string in Nitro which is incorrect
|
||||
[ ] default: Date.now // Default value is missing in Nitro
|
||||
},
|
||||
[?] updatedAt: {
|
||||
[?] type: Date, // Type is modeled as string in Nitro which is incorrect
|
||||
[ ] default: Date.now // Default value is missing in Nitro
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
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,
|
||||
|
||||
@ -0,0 +1 @@
|
||||
MATCH (n:Badge) DETACH DELETE n;
|
||||
@ -1,4 +1,35 @@
|
||||
CALL apoc.load.json("file:${IMPORT_CHUNK_PATH_CQL}") YIELD value as category
|
||||
/*
|
||||
// Alpha Model
|
||||
// [ ] Not modeled in Nitro
|
||||
// [X] Modeled in Nitro
|
||||
// [-] Omitted in Nitro
|
||||
// [?] Unclear / has work to be done for Nitro
|
||||
{
|
||||
[X] title: {
|
||||
[X] type: String,
|
||||
[X] required: true
|
||||
},
|
||||
[?] slug: {
|
||||
[X] type: String,
|
||||
[ ] required: true, // Not required in Nitro
|
||||
[ ] unique: true // Unique value is not enforced in Nitro?
|
||||
},
|
||||
[?] icon: { // Nitro adds required: true
|
||||
[X] type: String,
|
||||
[ ] unique: true // Unique value is not enforced in Nitro?
|
||||
},
|
||||
[?] createdAt: {
|
||||
[?] type: Date, // Type is modeled as string in Nitro which is incorrect
|
||||
[ ] default: Date.now // Default value is missing in Nitro
|
||||
},
|
||||
[?] updatedAt: {
|
||||
[?] type: Date, // Type is modeled as string in Nitro which is incorrect
|
||||
[ ] default: Date.now // Default value is missing in Nitro
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
CALL apoc.load.json("file:${IMPORT_CHUNK_PATH_CQL_FILE}") YIELD value as category
|
||||
MERGE(c:Category {id: category._id["$oid"]})
|
||||
ON CREATE SET
|
||||
c.name = category.title,
|
||||
@ -8,6 +39,7 @@ c.createdAt = category.createdAt.`$date`,
|
||||
c.updatedAt = category.updatedAt.`$date`
|
||||
;
|
||||
|
||||
// Transform icon names
|
||||
MATCH (c:Category)
|
||||
WHERE (c.icon = "categories-justforfun")
|
||||
SET c.icon = 'smile'
|
||||
|
||||
@ -0,0 +1 @@
|
||||
MATCH (n:Category) DETACH DELETE n;
|
||||
@ -1,15 +1,65 @@
|
||||
CALL apoc.load.json("file:${IMPORT_CHUNK_PATH_CQL}") YIELD value as json
|
||||
/*
|
||||
// Alpha Model
|
||||
// [ ] Not modeled in Nitro
|
||||
// [X] Modeled in Nitro
|
||||
// [-] Omitted in Nitro
|
||||
// [?] Unclear / has work to be done for Nitro
|
||||
{
|
||||
[?] userId: {
|
||||
[X] type: String,
|
||||
[ ] required: true, // Not required in Nitro
|
||||
[-] index: true
|
||||
},
|
||||
[?] contributionId: {
|
||||
[X] type: String,
|
||||
[ ] required: true, // Not required in Nitro
|
||||
[-] index: true
|
||||
},
|
||||
[X] content: {
|
||||
[X] type: String,
|
||||
[X] required: true
|
||||
},
|
||||
[?] contentExcerpt: { // Generated from content
|
||||
[X] type: String,
|
||||
[ ] required: true // Not required in Nitro
|
||||
},
|
||||
[ ] hasMore: { type: Boolean },
|
||||
[ ] upvotes: {
|
||||
[ ] type: Array,
|
||||
[ ] default: []
|
||||
},
|
||||
[ ] upvoteCount: {
|
||||
[ ] type: Number,
|
||||
[ ] default: 0
|
||||
},
|
||||
[?] deleted: {
|
||||
[X] type: Boolean,
|
||||
[ ] default: false, // Default value is missing in Nitro
|
||||
[-] index: true
|
||||
},
|
||||
[ ] createdAt: {
|
||||
[ ] type: Date,
|
||||
[ ] default: Date.now
|
||||
},
|
||||
[ ] updatedAt: {
|
||||
[ ] type: Date,
|
||||
[ ] default: Date.now
|
||||
},
|
||||
[ ] wasSeeded: { type: Boolean }
|
||||
}
|
||||
*/
|
||||
|
||||
MERGE (comment:Comment {id: json._id["$oid"]})
|
||||
CALL apoc.load.json("file:${IMPORT_CHUNK_PATH_CQL_FILE}") YIELD value as comment
|
||||
MERGE (c:Comment {id: comment._id["$oid"]})
|
||||
ON CREATE SET
|
||||
comment.content = json.content,
|
||||
comment.contentExcerpt = json.contentExcerpt,
|
||||
comment.deleted = json.deleted,
|
||||
comment.disabled = false
|
||||
WITH comment, json, json.contributionId as postId
|
||||
c.content = comment.content,
|
||||
c.contentExcerpt = comment.contentExcerpt,
|
||||
c.deleted = comment.deleted,
|
||||
c.disabled = false
|
||||
WITH c, comment, comment.contributionId as postId
|
||||
MATCH (post:Post {id: postId})
|
||||
WITH comment, post, json.userId as userId
|
||||
WITH c, post, comment.userId as userId
|
||||
MATCH (author:User {id: userId})
|
||||
MERGE (comment)-[:COMMENTS]->(post)
|
||||
MERGE (author)-[:WROTE]->(comment)
|
||||
MERGE (c)-[:COMMENTS]->(post)
|
||||
MERGE (author)-[:WROTE]->(c)
|
||||
;
|
||||
|
||||
@ -0,0 +1 @@
|
||||
MATCH (n:Comment) DETACH DELETE n;
|
||||
@ -1,4 +1,132 @@
|
||||
CALL apoc.load.json("file:${IMPORT_CHUNK_PATH_CQL}") YIELD value as post
|
||||
/*
|
||||
// Alpha Model
|
||||
// [ ] Not modeled in Nitro
|
||||
// [X] Modeled in Nitro
|
||||
// [-] Omitted in Nitro
|
||||
// [?] Unclear / has work to be done for Nitro
|
||||
[?] { //Modeled incorrect as Post
|
||||
[?] userId: {
|
||||
[X] type: String,
|
||||
[ ] required: true, // Not required in Nitro
|
||||
[-] index: true
|
||||
},
|
||||
[ ] organizationId: {
|
||||
[ ] type: String,
|
||||
[-] index: true
|
||||
},
|
||||
[X] categoryIds: {
|
||||
[X] type: Array,
|
||||
[-] index: true
|
||||
},
|
||||
[X] title: {
|
||||
[X] type: String,
|
||||
[X] required: true
|
||||
},
|
||||
[?] slug: { // Generated from title
|
||||
[X] type: String,
|
||||
[ ] required: true, // Not required in Nitro
|
||||
[?] unique: true, // Unique value is not enforced in Nitro?
|
||||
[-] index: true
|
||||
},
|
||||
[ ] type: {
|
||||
[ ] type: String,
|
||||
[ ] required: true,
|
||||
[-] index: true
|
||||
},
|
||||
[ ] cando: {
|
||||
[ ] difficulty: {
|
||||
[ ] type: String,
|
||||
[ ] enum: ['easy', 'medium', 'hard']
|
||||
},
|
||||
[ ] reasonTitle: { type: String },
|
||||
[ ] reason: { type: String }
|
||||
},
|
||||
[X] content: {
|
||||
[X] type: String,
|
||||
[X] required: true
|
||||
},
|
||||
[?] contentExcerpt: { // Generated from content
|
||||
[X] type: String,
|
||||
[?] required: true // Not required in Nitro
|
||||
},
|
||||
[ ] hasMore: { type: Boolean },
|
||||
[?] teaserImg: { type: String }, // Path is incorrect in Nitro
|
||||
[ ] language: {
|
||||
[ ] type: String,
|
||||
[ ] required: true,
|
||||
[-] index: true
|
||||
},
|
||||
[ ] shoutCount: {
|
||||
[ ] type: Number,
|
||||
[ ] default: 0,
|
||||
[-] index: true
|
||||
},
|
||||
[ ] meta: {
|
||||
[ ] hasVideo: {
|
||||
[ ] type: Boolean,
|
||||
[ ] default: false
|
||||
},
|
||||
[ ] embedds: {
|
||||
[ ] type: Object,
|
||||
[ ] default: {}
|
||||
}
|
||||
},
|
||||
[?] visibility: {
|
||||
[X] type: String,
|
||||
[X] enum: ['public', 'friends', 'private'],
|
||||
[ ] default: 'public', // Default value is missing in Nitro
|
||||
[-] index: true
|
||||
},
|
||||
[?] isEnabled: {
|
||||
[X] type: Boolean,
|
||||
[ ] default: true, // Default value is missing in Nitro
|
||||
[-] index: true
|
||||
},
|
||||
[?] tags: { type: Array }, // ensure this is working properly
|
||||
[ ] emotions: {
|
||||
[ ] type: Object,
|
||||
[-] index: true,
|
||||
[ ] default: {
|
||||
[ ] angry: {
|
||||
[ ] count: 0,
|
||||
[ ] percent: 0
|
||||
[ ] },
|
||||
[ ] cry: {
|
||||
[ ] count: 0,
|
||||
[ ] percent: 0
|
||||
[ ] },
|
||||
[ ] surprised: {
|
||||
[ ] count: 0,
|
||||
[ ] percent: 0
|
||||
},
|
||||
[ ] happy: {
|
||||
[ ] count: 0,
|
||||
[ ] percent: 0
|
||||
},
|
||||
[ ] funny: {
|
||||
[ ] count: 0,
|
||||
[ ] percent: 0
|
||||
}
|
||||
}
|
||||
},
|
||||
[?] deleted: {
|
||||
[X] type: Boolean,
|
||||
[ ] default: false, // Default value is missing in Nitro
|
||||
[-] index: true
|
||||
},
|
||||
[?] createdAt: {
|
||||
[?] type: Date, // Type is modeled as string in Nitro which is incorrect
|
||||
[ ] default: Date.now // Default value is missing in Nitro
|
||||
},
|
||||
[?] updatedAt: {
|
||||
[?] type: Date, // Type is modeled as string in Nitro which is incorrect
|
||||
[ ] default: Date.now // Default value is missing in Nitro
|
||||
},
|
||||
[ ] wasSeeded: { type: Boolean }
|
||||
}
|
||||
*/
|
||||
|
||||
CALL apoc.load.json("file:${IMPORT_CHUNK_PATH_CQL_FILE}") YIELD value as post
|
||||
MERGE (p:Post {id: post._id["$oid"]})
|
||||
ON CREATE SET
|
||||
p.title = post.title,
|
||||
|
||||
@ -0,0 +1,2 @@
|
||||
MATCH (n:Post) DETACH DELETE n;
|
||||
MATCH (n:Tag) DETACH DELETE n;
|
||||
@ -0,0 +1,35 @@
|
||||
/*
|
||||
// Alpha Model
|
||||
// [ ] Not modeled in Nitro
|
||||
// [X] Modeled in Nitro
|
||||
// [-] Omitted in Nitro
|
||||
// [?] Unclear / has work to be done for Nitro
|
||||
{
|
||||
[ ] userId: {
|
||||
[ ] type: String,
|
||||
[ ] required: true,
|
||||
[-] index: true
|
||||
},
|
||||
[ ] contributionId: {
|
||||
[ ] type: String,
|
||||
[ ] required: true,
|
||||
[-] index: true
|
||||
},
|
||||
[ ] rated: {
|
||||
[ ] type: String,
|
||||
[ ] required: true,
|
||||
[ ] enum: ['funny', 'happy', 'surprised', 'cry', 'angry']
|
||||
},
|
||||
[ ] createdAt: {
|
||||
[ ] type: Date,
|
||||
[ ] default: Date.now
|
||||
},
|
||||
[ ] updatedAt: {
|
||||
[ ] type: Date,
|
||||
[ ] default: Date.now
|
||||
},
|
||||
[ ] wasSeeded: { type: Boolean }
|
||||
}
|
||||
*/
|
||||
|
||||
CALL apoc.load.json("file:${IMPORT_CHUNK_PATH_CQL_FILE}") YIELD value as emotion;
|
||||
@ -1,4 +1,36 @@
|
||||
CALL apoc.load.json("file:${IMPORT_CHUNK_PATH_CQL}") YIELD value as follow
|
||||
/*
|
||||
// Alpha Model
|
||||
// [ ] Not modeled in Nitro
|
||||
// [X] Modeled in Nitro
|
||||
// [-] Omitted in Nitro
|
||||
// [?] Unclear / has work to be done for Nitro
|
||||
{
|
||||
[?] userId: {
|
||||
[-] type: String,
|
||||
[ ] required: true,
|
||||
[-] index: true
|
||||
},
|
||||
[?] foreignId: {
|
||||
[ ] type: String,
|
||||
[ ] required: true,
|
||||
[-] index: true
|
||||
},
|
||||
[?] foreignService: { // db.getCollection('follows').distinct('foreignService') returns 'organizations' and 'users'
|
||||
[ ] type: String,
|
||||
[ ] required: true,
|
||||
[ ] index: true
|
||||
},
|
||||
[ ] createdAt: {
|
||||
[ ] type: Date,
|
||||
[ ] default: Date.now
|
||||
},
|
||||
[ ] wasSeeded: { type: Boolean }
|
||||
}
|
||||
index:
|
||||
[?] { userId: 1, foreignId: 1, foreignService: 1 },{ unique: true } // is the unique constrain modeled?
|
||||
*/
|
||||
|
||||
CALL apoc.load.json("file:${IMPORT_CHUNK_PATH_CQL_FILE}") YIELD value as follow
|
||||
MATCH (u1:User {id: follow.userId}), (u2:User {id: follow.foreignId})
|
||||
MERGE (u1)-[:FOLLOWS]->(u2)
|
||||
;
|
||||
|
||||
@ -0,0 +1 @@
|
||||
// this is just a relation between users(?) - no need to delete
|
||||
@ -6,14 +6,44 @@ set -o allexport
|
||||
source $(dirname "$0")/.env
|
||||
set +o allexport
|
||||
|
||||
# Delete collection function defintion
|
||||
function delete_collection () {
|
||||
# Delete from Database
|
||||
echo "Delete $1"
|
||||
"${IMPORT_CYPHERSHELL_BIN}" < $(dirname "$0")/$1_delete.cql > /dev/null
|
||||
# Delete index file
|
||||
rm -f "${IMPORT_PATH}splits/$1.index"
|
||||
}
|
||||
|
||||
# Import collection function defintion
|
||||
function import_collection () {
|
||||
# index file of those chunks we have already imported
|
||||
INDEX_FILE="${IMPORT_PATH}splits/$1.index"
|
||||
# load index file
|
||||
if [ -f "$INDEX_FILE" ]; then
|
||||
readarray -t IMPORT_INDEX <$INDEX_FILE
|
||||
else
|
||||
declare -a IMPORT_INDEX
|
||||
fi
|
||||
# for each chunk import data
|
||||
for chunk in ${IMPORT_PATH}splits/$1/*
|
||||
do
|
||||
mv $chunk ${IMPORT_CHUNK_PATH}
|
||||
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}
|
||||
CHUNK_FILE_NAME=$(basename "${chunk}")
|
||||
# does the index not contain the chunk file name?
|
||||
if [[ ! " ${IMPORT_INDEX[@]} " =~ " ${CHUNK_FILE_NAME} " ]]; then
|
||||
# calculate the path of the chunk
|
||||
export IMPORT_CHUNK_PATH_CQL_FILE="${IMPORT_CHUNK_PATH_CQL}$1/${CHUNK_FILE_NAME}"
|
||||
# load the neo4j command and replace file variable with actual path
|
||||
NEO4J_COMMAND="$(envsubst '${IMPORT_CHUNK_PATH_CQL_FILE}' < $(dirname "$0")/$1.cql)"
|
||||
# run the import of the chunk
|
||||
echo "Import $1 ${CHUNK_FILE_NAME} (${chunk})"
|
||||
echo "${NEO4J_COMMAND}" | "${IMPORT_CYPHERSHELL_BIN}" > /dev/null
|
||||
# add file to array and file
|
||||
IMPORT_INDEX+=("${CHUNK_FILE_NAME}")
|
||||
echo "${CHUNK_FILE_NAME}" >> ${INDEX_FILE}
|
||||
else
|
||||
echo "Skipping $1 ${CHUNK_FILE_NAME} (${chunk})"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
@ -22,7 +52,26 @@ 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}
|
||||
delete_collection "badges"
|
||||
delete_collection "categories"
|
||||
delete_collection "users"
|
||||
delete_collection "follows"
|
||||
delete_collection "contributions"
|
||||
delete_collection "shouts"
|
||||
delete_collection "comments"
|
||||
|
||||
#delete_collection "emotions"
|
||||
#delete_collection "invites"
|
||||
#delete_collection "notifications"
|
||||
#delete_collection "organizations"
|
||||
#delete_collection "pages"
|
||||
#delete_collection "projects"
|
||||
#delete_collection "settings"
|
||||
#delete_collection "status"
|
||||
#delete_collection "systemnotifications"
|
||||
#delete_collection "userscandos"
|
||||
#delete_collection "usersettings"
|
||||
echo "DONE"
|
||||
|
||||
# Import Data
|
||||
echo "Start Importing Data"
|
||||
@ -33,16 +82,19 @@ 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"
|
||||
|
||||
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 "DONE"
|
||||
|
||||
echo "Time elapsed: $SECONDS seconds"
|
||||
|
||||
@ -0,0 +1,39 @@
|
||||
/*
|
||||
// Alpha Model
|
||||
// [ ] Not modeled in Nitro
|
||||
// [X] Modeled in Nitro
|
||||
// [-] Omitted in Nitro
|
||||
// [?] Unclear / has work to be done for Nitro
|
||||
{
|
||||
[ ] email: {
|
||||
[ ] type: String,
|
||||
[ ] required: true,
|
||||
[-] index: true,
|
||||
[ ] unique: true
|
||||
},
|
||||
[ ] code: {
|
||||
[ ] type: String,
|
||||
[-] index: true,
|
||||
[ ] required: true
|
||||
},
|
||||
[ ] role: {
|
||||
[ ] type: String,
|
||||
[ ] enum: ['admin', 'moderator', 'manager', 'editor', 'user'],
|
||||
[ ] default: 'user'
|
||||
},
|
||||
[ ] invitedByUserId: { type: String },
|
||||
[ ] language: { type: String },
|
||||
[ ] badgeIds: [],
|
||||
[ ] wasUsed: {
|
||||
[ ] type: Boolean,
|
||||
[-] index: true
|
||||
},
|
||||
[ ] createdAt: {
|
||||
[ ] type: Date,
|
||||
[ ] default: Date.now
|
||||
},
|
||||
[ ] wasSeeded: { type: Boolean }
|
||||
}
|
||||
*/
|
||||
|
||||
CALL apoc.load.json("file:${IMPORT_CHUNK_PATH_CQL_FILE}") YIELD value as invite;
|
||||
@ -0,0 +1,48 @@
|
||||
/*
|
||||
// Alpha Model
|
||||
// [ ] Not modeled in Nitro
|
||||
// [X] Modeled in Nitro
|
||||
// [-] Omitted in Nitro
|
||||
// [?] Unclear / has work to be done for Nitro
|
||||
{
|
||||
[ ] userId: { // User this notification is sent to
|
||||
[ ] type: String,
|
||||
[ ] required: true,
|
||||
[-] index: true
|
||||
},
|
||||
[ ] type: {
|
||||
[ ] type: String,
|
||||
[ ] required: true,
|
||||
[ ] enum: ['comment','comment-mention','contribution-mention','following-contribution']
|
||||
},
|
||||
[ ] relatedUserId: {
|
||||
[ ] type: String,
|
||||
[-] index: true
|
||||
},
|
||||
[ ] relatedContributionId: {
|
||||
[ ] type: String,
|
||||
[-] index: true
|
||||
},
|
||||
[ ] relatedOrganizationId: {
|
||||
[ ] type: String,
|
||||
[-] index: true
|
||||
},
|
||||
[ ] relatedCommentId: {type: String },
|
||||
[ ] unseen: {
|
||||
[ ] type: Boolean,
|
||||
[ ] default: true,
|
||||
[-] index: true
|
||||
},
|
||||
[ ] createdAt: {
|
||||
[ ] type: Date,
|
||||
[ ] default: Date.now
|
||||
},
|
||||
[ ] updatedAt: {
|
||||
[ ] type: Date,
|
||||
[ ] default: Date.now
|
||||
},
|
||||
[ ] wasSeeded: { type: Boolean }
|
||||
}
|
||||
*/
|
||||
|
||||
CALL apoc.load.json("file:${IMPORT_CHUNK_PATH_CQL_FILE}") YIELD value as notification;
|
||||
@ -0,0 +1,137 @@
|
||||
/*
|
||||
// Alpha Model
|
||||
// [ ] Not modeled in Nitro
|
||||
// [X] Modeled in Nitro
|
||||
// [-] Omitted in Nitro
|
||||
// [?] Unclear / has work to be done for Nitro
|
||||
{
|
||||
[ ] name: {
|
||||
[ ] type: String,
|
||||
[ ] required: true,
|
||||
[-] index: true
|
||||
},
|
||||
[ ] slug: {
|
||||
[ ] type: String,
|
||||
[ ] required: true,
|
||||
[ ] unique: true,
|
||||
[-] index: true
|
||||
},
|
||||
[ ] followersCounts: {
|
||||
[ ] users: {
|
||||
[ ] type: Number,
|
||||
[ ] default: 0
|
||||
},
|
||||
[ ] organizations: {
|
||||
[ ] type: Number,
|
||||
[ ] default: 0
|
||||
},
|
||||
[ ] projects: {
|
||||
[ ] type: Number,
|
||||
[ ] default: 0
|
||||
}
|
||||
},
|
||||
[ ] followingCounts: {
|
||||
[ ] users: {
|
||||
[ ] type: Number,
|
||||
[ ] default: 0
|
||||
},
|
||||
[ ] organizations: {
|
||||
[ ] type: Number,
|
||||
[ ] default: 0
|
||||
},
|
||||
[ ] projects: {
|
||||
[ ] type: Number,
|
||||
[ ] default: 0
|
||||
}
|
||||
},
|
||||
[ ] categoryIds: {
|
||||
[ ] type: Array,
|
||||
[ ] required: true,
|
||||
[-] index: true
|
||||
},
|
||||
[ ] logo: { type: String },
|
||||
[ ] coverImg: { type: String },
|
||||
[ ] userId: {
|
||||
[ ] type: String,
|
||||
[ ] required: true,
|
||||
[-] index: true
|
||||
},
|
||||
[ ] description: {
|
||||
[ ] type: String,
|
||||
[ ] required: true
|
||||
},
|
||||
[ ] descriptionExcerpt: { type: String }, // will be generated automatically
|
||||
[ ] publicEmail: { type: String },
|
||||
[ ] url: { type: String },
|
||||
[ ] type: {
|
||||
[ ] type: String,
|
||||
[-] index: true,
|
||||
[ ] enum: ['ngo', 'npo', 'goodpurpose', 'ev', 'eva']
|
||||
},
|
||||
[ ] language: {
|
||||
[ ] type: String,
|
||||
[ ] required: true,
|
||||
[ ] default: 'de',
|
||||
[-] index: true
|
||||
},
|
||||
[ ] addresses: {
|
||||
[ ] type: [{
|
||||
[ ] street: {
|
||||
[ ] type: String,
|
||||
[ ] required: true
|
||||
},
|
||||
[ ] zipCode: {
|
||||
[ ] type: String,
|
||||
[ ] required: true
|
||||
},
|
||||
[ ] city: {
|
||||
[ ] type: String,
|
||||
[ ] required: true
|
||||
},
|
||||
[ ] country: {
|
||||
[ ] type: String,
|
||||
[ ] required: true
|
||||
},
|
||||
[ ] lat: {
|
||||
[ ] type: Number,
|
||||
[ ] required: true
|
||||
},
|
||||
[ ] lng: {
|
||||
[ ] type: Number,
|
||||
[ ] required: true
|
||||
}
|
||||
}],
|
||||
[ ] default: []
|
||||
},
|
||||
[ ] createdAt: {
|
||||
[ ] type: Date,
|
||||
[ ] default: Date.now
|
||||
},
|
||||
[ ] updatedAt: {
|
||||
[ ] type: Date,
|
||||
[ ] default: Date.now
|
||||
},
|
||||
[ ] isEnabled: {
|
||||
[ ] type: Boolean,
|
||||
[ ] default: false,
|
||||
[-] index: true
|
||||
},
|
||||
[ ] reviewedBy: {
|
||||
[ ] type: String,
|
||||
[ ] default: null,
|
||||
[-] index: true
|
||||
},
|
||||
[ ] tags: {
|
||||
[ ] type: Array,
|
||||
[-] index: true
|
||||
},
|
||||
[ ] deleted: {
|
||||
[ ] type: Boolean,
|
||||
[ ] default: false,
|
||||
[-] index: true
|
||||
},
|
||||
[ ] wasSeeded: { type: Boolean }
|
||||
}
|
||||
*/
|
||||
|
||||
CALL apoc.load.json("file:${IMPORT_CHUNK_PATH_CQL_FILE}") YIELD value as organisation;
|
||||
@ -0,0 +1,55 @@
|
||||
/*
|
||||
// Alpha Model
|
||||
// [ ] Not modeled in Nitro
|
||||
// [X] Modeled in Nitro
|
||||
// [-] Omitted in Nitro
|
||||
// [?] Unclear / has work to be done for Nitro
|
||||
{
|
||||
[ ] title: {
|
||||
[ ] type: String,
|
||||
[ ] required: true
|
||||
},
|
||||
[ ] slug: {
|
||||
[ ] type: String,
|
||||
[ ] required: true,
|
||||
[-] index: true
|
||||
},
|
||||
[ ] type: {
|
||||
[ ] type: String,
|
||||
[ ] required: true,
|
||||
[ ] default: 'page'
|
||||
},
|
||||
[ ] key: {
|
||||
[ ] type: String,
|
||||
[ ] required: true,
|
||||
[-] index: true
|
||||
},
|
||||
[ ] content: {
|
||||
[ ] type: String,
|
||||
[ ] required: true
|
||||
},
|
||||
[ ] language: {
|
||||
[ ] type: String,
|
||||
[ ] required: true,
|
||||
[-] index: true
|
||||
},
|
||||
[ ] active: {
|
||||
[ ] type: Boolean,
|
||||
[ ] default: true,
|
||||
[-] index: true
|
||||
},
|
||||
[ ] createdAt: {
|
||||
[ ] type: Date,
|
||||
[ ] default: Date.now
|
||||
},
|
||||
[ ] updatedAt: {
|
||||
[ ] type: Date,
|
||||
[ ] default: Date.now
|
||||
},
|
||||
[ ] wasSeeded: { type: Boolean }
|
||||
}
|
||||
index:
|
||||
[ ] { slug: 1, language: 1 },{ unique: true }
|
||||
*/
|
||||
|
||||
CALL apoc.load.json("file:${IMPORT_CHUNK_PATH_CQL_FILE}") YIELD value as page;
|
||||
@ -0,0 +1,44 @@
|
||||
/*
|
||||
// Alpha Model
|
||||
// [ ] Not modeled in Nitro
|
||||
// [X] Modeled in Nitro
|
||||
// [-] Omitted in Nitro
|
||||
// [?] Unclear / has work to be done for Nitro
|
||||
{
|
||||
[ ] name: {
|
||||
[ ] type: String,
|
||||
[ ] required: true
|
||||
},
|
||||
[ ] slug: { type: String },
|
||||
[ ] followerIds: [],
|
||||
[ ] categoryIds: { type: Array },
|
||||
[ ] logo: { type: String },
|
||||
[ ] userId: {
|
||||
[ ] type: String,
|
||||
[ ] required: true
|
||||
},
|
||||
[ ] description: {
|
||||
[ ] type: String,
|
||||
[ ] required: true
|
||||
},
|
||||
[ ] content: {
|
||||
[ ] type: String,
|
||||
[ ] required: true
|
||||
},
|
||||
[ ] addresses: {
|
||||
[ ] type: Array,
|
||||
[ ] default: []
|
||||
},
|
||||
[ ] createdAt: {
|
||||
[ ] type: Date,
|
||||
[ ] default: Date.now
|
||||
},
|
||||
[ ] updatedAt: {
|
||||
[ ] type: Date,
|
||||
[ ] default: Date.now
|
||||
},
|
||||
[ ] wasSeeded: { type: Boolean }
|
||||
}
|
||||
*/
|
||||
|
||||
CALL apoc.load.json("file:${IMPORT_CHUNK_PATH_CQL_FILE}") YIELD value as project;
|
||||
@ -0,0 +1,36 @@
|
||||
/*
|
||||
// Alpha Model
|
||||
// [ ] Not modeled in Nitro
|
||||
// [X] Modeled in Nitro
|
||||
// [-] Omitted in Nitro
|
||||
// [?] Unclear / has work to be done for Nitro
|
||||
{
|
||||
[ ] key: {
|
||||
[ ] type: String,
|
||||
[ ] default: 'system',
|
||||
[-] index: true,
|
||||
[ ] unique: true
|
||||
},
|
||||
[ ] invites: {
|
||||
[ ] userCanInvite: {
|
||||
[ ] type: Boolean,
|
||||
[ ] required: true,
|
||||
[ ] default: false
|
||||
},
|
||||
[ ] maxInvitesByUser: {
|
||||
[ ] type: Number,
|
||||
[ ] required: true,
|
||||
[ ] default: 1
|
||||
},
|
||||
[ ] onlyUserWithBadgesCanInvite: {
|
||||
[ ] type: Array,
|
||||
[ ] default: []
|
||||
}
|
||||
},
|
||||
[ ] maintenance: false
|
||||
}, {
|
||||
[ ] timestamps: true
|
||||
}
|
||||
*/
|
||||
|
||||
CALL apoc.load.json("file:${IMPORT_CHUNK_PATH_CQL_FILE}") YIELD value as setting;
|
||||
@ -1,4 +1,36 @@
|
||||
CALL apoc.load.json("file:${IMPORT_CHUNK_PATH_CQL}") YIELD value as shout
|
||||
/*
|
||||
// Alpha Model
|
||||
// [ ] Not modeled in Nitro
|
||||
// [X] Modeled in Nitro
|
||||
// [-] Omitted in Nitro
|
||||
// [?] Unclear / has work to be done for Nitro
|
||||
{
|
||||
[?] userId: {
|
||||
[X] type: String,
|
||||
[ ] required: true, // Not required in Nitro
|
||||
[-] index: true
|
||||
},
|
||||
[?] foreignId: {
|
||||
[X] type: String,
|
||||
[ ] required: true, // Not required in Nitro
|
||||
[-] index: true
|
||||
},
|
||||
[?] foreignService: { // db.getCollection('shots').distinct('foreignService') returns 'contributions'
|
||||
[X] type: String,
|
||||
[ ] required: true, // Not required in Nitro
|
||||
[-] index: true
|
||||
},
|
||||
[ ] createdAt: {
|
||||
[ ] type: Date,
|
||||
[ ] default: Date.now
|
||||
},
|
||||
[ ] wasSeeded: { type: Boolean }
|
||||
}
|
||||
index:
|
||||
[?] { userId: 1, foreignId: 1 },{ unique: true } // is the unique constrain modeled?
|
||||
*/
|
||||
|
||||
CALL apoc.load.json("file:${IMPORT_CHUNK_PATH_CQL_FILE}") YIELD value as shout
|
||||
MATCH (u:User {id: shout.userId}), (p:Post {id: shout.foreignId})
|
||||
MERGE (u)-[:SHOUTED]->(p)
|
||||
;
|
||||
|
||||
@ -0,0 +1 @@
|
||||
// this is just a relation between users and contributions - no need to delete
|
||||
@ -0,0 +1,19 @@
|
||||
/*
|
||||
// Alpha Model
|
||||
// [ ] Not modeled in Nitro
|
||||
// [X] Modeled in Nitro
|
||||
// [-] Omitted in Nitro
|
||||
// [?] Unclear / has work to be done for Nitro
|
||||
{
|
||||
[ ] maintenance: {
|
||||
[ ] type: Boolean,
|
||||
[ ] default: false
|
||||
},
|
||||
[ ] updatedAt: {
|
||||
[ ] type: Date,
|
||||
[ ] default: Date.now
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
CALL apoc.load.json("file:${IMPORT_CHUNK_PATH_CQL_FILE}") YIELD value as status;
|
||||
@ -0,0 +1,61 @@
|
||||
/*
|
||||
// Alpha Model
|
||||
// [ ] Not modeled in Nitro
|
||||
// [X] Modeled in Nitro
|
||||
// [-] Omitted in Nitro
|
||||
// [?] Unclear / has work to be done for Nitro
|
||||
{
|
||||
[ ] type: {
|
||||
[ ] type: String,
|
||||
[ ] default: 'info',
|
||||
[ ] required: true,
|
||||
[-] index: true
|
||||
},
|
||||
[ ] title: {
|
||||
[ ] type: String,
|
||||
[ ] required: true
|
||||
},
|
||||
[ ] content: {
|
||||
[ ] type: String,
|
||||
[ ] required: true
|
||||
},
|
||||
[ ] slot: {
|
||||
[ ] type: String,
|
||||
[ ] required: true,
|
||||
[-] index: true
|
||||
},
|
||||
[ ] language: {
|
||||
[ ] type: String,
|
||||
[ ] required: true,
|
||||
[-] index: true
|
||||
},
|
||||
[ ] permanent: {
|
||||
[ ] type: Boolean,
|
||||
[ ] default: false
|
||||
},
|
||||
[ ] requireConfirmation: {
|
||||
[ ] type: Boolean,
|
||||
[ ] default: false
|
||||
},
|
||||
[ ] active: {
|
||||
[ ] type: Boolean,
|
||||
[ ] default: true,
|
||||
[-] index: true
|
||||
},
|
||||
[ ] totalCount: {
|
||||
[ ] type: Number,
|
||||
[ ] default: 0
|
||||
},
|
||||
[ ] createdAt: {
|
||||
[ ] type: Date,
|
||||
[ ] default: Date.now
|
||||
},
|
||||
[ ] updatedAt: {
|
||||
[ ] type: Date,
|
||||
[ ] default: Date.now
|
||||
},
|
||||
[ ] wasSeeded: { type: Boolean }
|
||||
}
|
||||
*/
|
||||
|
||||
CALL apoc.load.json("file:${IMPORT_CHUNK_PATH_CQL_FILE}") YIELD value as systemnotification;
|
||||
@ -1,4 +1,101 @@
|
||||
CALL apoc.load.json("file:${IMPORT_CHUNK_PATH_CQL}") YIELD value as user
|
||||
/*
|
||||
// Alpha Model
|
||||
// [ ] Not modeled in Nitro
|
||||
// [X] Modeled in Nitro
|
||||
// [-] Omitted in Nitro
|
||||
// [?] Unclear / has work to be done for Nitro
|
||||
{
|
||||
[?] email: {
|
||||
[X] type: String,
|
||||
[-] index: true,
|
||||
[X] required: true,
|
||||
[?] unique: true //unique constrain missing in Nitro
|
||||
},
|
||||
[?] password: { // Not required in Alpha -> verify if always present
|
||||
[X] type: String
|
||||
},
|
||||
[X] name: { type: String },
|
||||
[X] slug: {
|
||||
[X] type: String,
|
||||
[-] index: true
|
||||
},
|
||||
[ ] gender: { type: String },
|
||||
[ ] followersCounts: {
|
||||
[ ] users: {
|
||||
[ ] type: Number,
|
||||
[ ] default: 0
|
||||
},
|
||||
[ ] organizations: {
|
||||
[ ] type: Number,
|
||||
[ ] default: 0
|
||||
},
|
||||
[ ] projects: {
|
||||
[ ] type: Number,
|
||||
[ ] default: 0
|
||||
}
|
||||
},
|
||||
[ ] followingCounts: {
|
||||
[ ] users: {
|
||||
[ ] type: Number,
|
||||
[ ] default: 0
|
||||
},
|
||||
[ ] organizations: {
|
||||
[ ] type: Number,
|
||||
[ ] default: 0
|
||||
},
|
||||
[ ] projects: {
|
||||
[ ] type: Number,
|
||||
[ ] default: 0
|
||||
}
|
||||
},
|
||||
[ ] timezone: { type: String },
|
||||
[?] avatar: { type: String }, // Path is incorrect in Nitro
|
||||
[?] coverImg: { type: String }, // Path is incorrect in Nitro, was not modeled in latest Nitro - do we want this?
|
||||
[ ] doiToken: { type: String },
|
||||
[ ] confirmedAt: { type: Date },
|
||||
[?] badgeIds: [], // Verify this is working properly
|
||||
[?] deletedAt: { type: Date }, // The Date of deletion is not saved in Nitro
|
||||
[?] createdAt: {
|
||||
[?] type: Date, // Modeled as String in Nitro
|
||||
[ ] default: Date.now // Default value is missing in Nitro
|
||||
},
|
||||
[?] updatedAt: {
|
||||
[?] type: Date, // Modeled as String in Nitro
|
||||
[ ] default: Date.now // Default value is missing in Nitro
|
||||
},
|
||||
[ ] lastActiveAt: {
|
||||
[ ] type: Date,
|
||||
[ ] default: Date.now
|
||||
},
|
||||
[ ] isVerified: { type: Boolean },
|
||||
[?] role: {
|
||||
[X] type: String,
|
||||
[-] index: true,
|
||||
[?] enum: ['admin', 'moderator', 'manager', 'editor', 'user'], // missing roles manager & editor in Nitro
|
||||
[ ] default: 'user' // Default value is missing in Nitro
|
||||
},
|
||||
[ ] verifyToken: { type: String },
|
||||
[ ] verifyShortToken: { type: String },
|
||||
[ ] verifyExpires: { type: Date },
|
||||
[ ] verifyChanges: { type: Object },
|
||||
[ ] resetToken: { type: String },
|
||||
[ ] resetShortToken: { type: String },
|
||||
[ ] resetExpires: { type: Date },
|
||||
[X] wasSeeded: { type: Boolean },
|
||||
[X] wasInvited: { type: Boolean },
|
||||
[ ] language: {
|
||||
[ ] type: String,
|
||||
[ ] default: 'en'
|
||||
},
|
||||
[ ] termsAndConditionsAccepted: { type: Date }, // we display the terms and conditions on registration
|
||||
[ ] systemNotificationsSeen: {
|
||||
[ ] type: Array,
|
||||
[ ] default: []
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
CALL apoc.load.json("file:${IMPORT_CHUNK_PATH_CQL_FILE}") YIELD value as user
|
||||
MERGE(u:User {id: user._id["$oid"]})
|
||||
ON CREATE SET
|
||||
u.name = user.name,
|
||||
@ -8,6 +105,7 @@ u.password = user.password,
|
||||
u.avatar = user.avatar,
|
||||
u.coverImg = user.coverImg,
|
||||
u.wasInvited = user.wasInvited,
|
||||
u.wasSeeded = user.wasSeeded,
|
||||
u.role = toLower(user.role),
|
||||
u.createdAt = user.createdAt.`$date`,
|
||||
u.updatedAt = user.updatedAt.`$date`,
|
||||
|
||||
@ -0,0 +1 @@
|
||||
MATCH (n:User) DETACH DELETE n;
|
||||
@ -0,0 +1,35 @@
|
||||
/*
|
||||
// Alpha Model
|
||||
// [ ] Not modeled in Nitro
|
||||
// [X] Modeled in Nitro
|
||||
// [-] Omitted in Nitro
|
||||
// [?] Unclear / has work to be done for Nitro
|
||||
{
|
||||
[ ] userId: {
|
||||
[ ] type: String,
|
||||
[ ] required: true
|
||||
},
|
||||
[ ] contributionId: {
|
||||
[ ] type: String,
|
||||
[ ] required: true
|
||||
},
|
||||
[ ] done: {
|
||||
[ ] type: Boolean,
|
||||
[ ] default: false
|
||||
},
|
||||
[ ] doneAt: { type: Date },
|
||||
[ ] createdAt: {
|
||||
[ ] type: Date,
|
||||
[ ] default: Date.now
|
||||
},
|
||||
[ ] updatedAt: {
|
||||
[ ] type: Date,
|
||||
[ ] default: Date.now
|
||||
},
|
||||
[ ] wasSeeded: { type: Boolean }
|
||||
}
|
||||
index:
|
||||
[ ] { userId: 1, contributionId: 1 },{ unique: true }
|
||||
*/
|
||||
|
||||
CALL apoc.load.json("file:${IMPORT_CHUNK_PATH_CQL_FILE}") YIELD value as usercando;
|
||||
@ -0,0 +1,43 @@
|
||||
/*
|
||||
// Alpha Model
|
||||
// [ ] Not modeled in Nitro
|
||||
// [X] Modeled in Nitro
|
||||
// [-] Omitted in Nitro
|
||||
// [?] Unclear / has work to be done for Nitro
|
||||
{
|
||||
[ ] userId: {
|
||||
[ ] type: String,
|
||||
[ ] required: true,
|
||||
[ ] unique: true
|
||||
},
|
||||
[ ] blacklist: {
|
||||
[ ] type: Array,
|
||||
[ ] default: []
|
||||
},
|
||||
[ ] uiLanguage: {
|
||||
[ ] type: String,
|
||||
[ ] required: true
|
||||
},
|
||||
[ ] contentLanguages: {
|
||||
[ ] type: Array,
|
||||
[ ] default: []
|
||||
},
|
||||
[ ] filter: {
|
||||
[ ] categoryIds: {
|
||||
[ ] type: Array,
|
||||
[ ] index: true
|
||||
},
|
||||
[ ] emotions: {
|
||||
[ ] type: Array,
|
||||
[ ] index: true
|
||||
}
|
||||
},
|
||||
[ ] hideUsersWithoutTermsOfUseSigniture: {type: Boolean},
|
||||
[ ] updatedAt: {
|
||||
[ ] type: Date,
|
||||
[ ] default: Date.now
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
CALL apoc.load.json("file:${IMPORT_CHUNK_PATH_CQL_FILE}") YIELD value as usersetting;
|
||||
@ -9,4 +9,4 @@
|
||||
- ReadWriteOnce
|
||||
resources:
|
||||
requests:
|
||||
storage: 2Gi
|
||||
storage: 25Gi
|
||||
|
||||
@ -10,7 +10,7 @@ module.exports = {
|
||||
},
|
||||
extends: [
|
||||
'standard',
|
||||
'plugin:vue/recommended',
|
||||
'plugin:vue/essential',
|
||||
'plugin:prettier/recommended'
|
||||
],
|
||||
// required to lint *.vue files
|
||||
@ -25,7 +25,9 @@ module.exports = {
|
||||
'no-console': ['error'],
|
||||
'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off',
|
||||
'vue/component-name-in-template-casing': ['error', 'kebab-case'],
|
||||
'prettier/prettier': ['error'],
|
||||
'prettier/prettier': ['error', {
|
||||
htmlWhitespaceSensitivity: 'ignore'
|
||||
}],
|
||||
// 'newline-per-chained-call': [2]
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
FROM node:10-alpine as base
|
||||
FROM node:12.3.1-alpine as base
|
||||
LABEL Description="Web Frontend of the Social Network Human-Connection.org" Vendor="Human-Connection gGmbH" Version="0.0.1" Maintainer="Human-Connection gGmbH (developer@human-connection.org)"
|
||||
|
||||
EXPOSE 3000
|
||||
@ -18,7 +18,7 @@ COPY . .
|
||||
|
||||
FROM base as build-and-test
|
||||
RUN cp .env.template .env
|
||||
RUN yarn install --production=false --frozen-lockfile --non-interactive
|
||||
RUN yarn install --ignore-engines --production=false --frozen-lockfile --non-interactive
|
||||
RUN yarn run build
|
||||
|
||||
FROM base as production
|
||||
|
||||
@ -1,10 +1,5 @@
|
||||
<template>
|
||||
<ds-avatar
|
||||
:image="avatarUrl"
|
||||
:name="userName"
|
||||
class="avatar"
|
||||
:size="size"
|
||||
/>
|
||||
<ds-avatar :image="avatarUrl" :name="userName" class="avatar" :size="size" />
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
@ -1,20 +1,7 @@
|
||||
<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"
|
||||
>
|
||||
<hc-image
|
||||
:title="badge.key"
|
||||
:image-props="{ src: badge.icon}"
|
||||
class="hc-badge"
|
||||
/>
|
||||
<div :class="[badges.length === 2 && 'hc-badges-dual']" class="hc-badges">
|
||||
<div v-for="badge in badges" :key="badge.key" class="hc-badge-container">
|
||||
<hc-image :title="badge.key" :image-props="{ src: badge.icon }" class="hc-badge" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -1,9 +1,6 @@
|
||||
<template>
|
||||
<ds-tag>
|
||||
<ds-icon
|
||||
size="large"
|
||||
:name="icon"
|
||||
/>
|
||||
<ds-icon size="large" :name="icon" />
|
||||
{{ name }}
|
||||
</ds-tag>
|
||||
</template>
|
||||
|
||||
@ -1,17 +1,11 @@
|
||||
<template>
|
||||
<div v-if="(comment.deleted || comment.disabled) && !isModerator">
|
||||
<ds-text
|
||||
style="padding-left: 40px; font-weight: bold;"
|
||||
color="soft"
|
||||
>
|
||||
<ds-text style="padding-left: 40px; font-weight: bold;" color="soft">
|
||||
<ds-icon name="ban" />
|
||||
{{ this.$t('comment.content.unavailable-placeholder') }}
|
||||
</ds-text>
|
||||
</div>
|
||||
<div
|
||||
v-else
|
||||
:class="{'comment': true, 'disabled-content': (comment.deleted || comment.disabled)}"
|
||||
>
|
||||
<div v-else :class="{ comment: true, 'disabled-content': comment.deleted || comment.disabled }">
|
||||
<ds-space margin-bottom="x-small">
|
||||
<hc-user :user="author" />
|
||||
</ds-space>
|
||||
@ -27,10 +21,7 @@
|
||||
<!-- eslint-disable vue/no-v-html -->
|
||||
<!-- TODO: replace editor content with tiptap render view -->
|
||||
<ds-space margin-bottom="small" />
|
||||
<div
|
||||
style="padding-left: 40px;"
|
||||
v-html="comment.contentExcerpt"
|
||||
/>
|
||||
<div style="padding-left: 40px;" v-html="comment.contentExcerpt" />
|
||||
<!-- eslint-enable vue/no-v-html -->
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -1,32 +1,13 @@
|
||||
<template>
|
||||
<dropdown
|
||||
class="content-menu"
|
||||
:placement="placement"
|
||||
offset="5"
|
||||
>
|
||||
<template
|
||||
slot="default"
|
||||
slot-scope="{toggleMenu}"
|
||||
>
|
||||
<slot
|
||||
name="button"
|
||||
:toggleMenu="toggleMenu"
|
||||
>
|
||||
<ds-button
|
||||
class="content-menu-trigger"
|
||||
size="small"
|
||||
ghost
|
||||
@click.prevent="toggleMenu"
|
||||
>
|
||||
<dropdown class="content-menu" :placement="placement" offset="5">
|
||||
<template slot="default" slot-scope="{ toggleMenu }">
|
||||
<slot name="button" :toggleMenu="toggleMenu">
|
||||
<ds-button class="content-menu-trigger" size="small" ghost @click.prevent="toggleMenu">
|
||||
<ds-icon name="ellipsis-v" />
|
||||
</ds-button>
|
||||
</slot>
|
||||
</template>
|
||||
<div
|
||||
slot="popover"
|
||||
slot-scope="{toggleMenu}"
|
||||
class="content-menu-popover"
|
||||
>
|
||||
<div slot="popover" slot-scope="{ toggleMenu }" class="content-menu-popover">
|
||||
<ds-menu :routes="routes">
|
||||
<ds-menu-item
|
||||
slot="menuitem"
|
||||
|
||||
@ -1,35 +1,13 @@
|
||||
<template>
|
||||
<ds-form
|
||||
ref="contributionForm"
|
||||
v-model="form"
|
||||
:schema="formSchema"
|
||||
@submit="submit"
|
||||
>
|
||||
<ds-form ref="contributionForm" v-model="form" :schema="formSchema" @submit="submit">
|
||||
<template slot-scope="{ errors }">
|
||||
<ds-card>
|
||||
<ds-input
|
||||
model="title"
|
||||
class="post-title"
|
||||
placeholder="Title"
|
||||
name="title"
|
||||
autofocus
|
||||
/>
|
||||
<ds-input model="title" class="post-title" placeholder="Title" name="title" autofocus />
|
||||
<no-ssr>
|
||||
<hc-editor
|
||||
:users="users"
|
||||
:value="form.content"
|
||||
@input="updateEditorContent"
|
||||
/>
|
||||
<hc-editor :users="users" :value="form.content" @input="updateEditorContent" />
|
||||
</no-ssr>
|
||||
<div
|
||||
slot="footer"
|
||||
style="text-align: right"
|
||||
>
|
||||
<ds-button
|
||||
:disabled="loading || disabled"
|
||||
ghost
|
||||
@click.prevent="$router.back()"
|
||||
>
|
||||
<div slot="footer" style="text-align: right">
|
||||
<ds-button :disabled="loading || disabled" ghost @click.prevent="$router.back()">
|
||||
{{ $t('actions.cancel') }}
|
||||
</ds-button>
|
||||
<ds-button
|
||||
|
||||
@ -1,9 +1,6 @@
|
||||
<template>
|
||||
<span>
|
||||
<no-ssr
|
||||
placeholder="0"
|
||||
tag="span"
|
||||
>
|
||||
<no-ssr placeholder="0" tag="span">
|
||||
<count-to
|
||||
:start-val="lastEndVal || startVal"
|
||||
:end-val="endVal"
|
||||
|
||||
@ -7,17 +7,8 @@
|
||||
trigger="manual"
|
||||
:offset="offset"
|
||||
>
|
||||
<slot
|
||||
:toggleMenu="toggleMenu"
|
||||
:openMenu="openMenu"
|
||||
:closeMenu="closeMenu"
|
||||
:isOpen="isOpen"
|
||||
/>
|
||||
<div
|
||||
slot="popover"
|
||||
@mouseover="popoverMouseEnter"
|
||||
@mouseleave="popoveMouseLeave"
|
||||
>
|
||||
<slot :toggleMenu="toggleMenu" :openMenu="openMenu" :closeMenu="closeMenu" :isOpen="isOpen" />
|
||||
<div slot="popover" @mouseover="popoverMouseEnter" @mouseleave="popoveMouseLeave">
|
||||
<slot
|
||||
name="popover"
|
||||
:toggleMenu="toggleMenu"
|
||||
|
||||
@ -1,10 +1,6 @@
|
||||
<template>
|
||||
<div class="editor">
|
||||
<div
|
||||
v-show="showSuggestions"
|
||||
ref="suggestions"
|
||||
class="suggestion-list"
|
||||
>
|
||||
<div v-show="showSuggestions" ref="suggestions" class="suggestion-list">
|
||||
<template v-if="hasResults">
|
||||
<div
|
||||
v-for="(user, index) in filteredUsers"
|
||||
@ -16,10 +12,7 @@
|
||||
@{{ user.slug }}
|
||||
</div>
|
||||
</template>
|
||||
<div
|
||||
v-else
|
||||
class="suggestion-list__item is-empty"
|
||||
>
|
||||
<div v-else class="suggestion-list__item is-empty">
|
||||
No users found
|
||||
</div>
|
||||
</div>
|
||||
@ -154,10 +147,7 @@
|
||||
</ds-button>
|
||||
</div>
|
||||
</editor-floating-menu>
|
||||
<editor-content
|
||||
ref="editor"
|
||||
:editor="editor"
|
||||
/>
|
||||
<editor-content ref="editor" :editor="editor" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
@ -1,9 +1,5 @@
|
||||
<template>
|
||||
<ds-space
|
||||
class="hc-empty"
|
||||
centered
|
||||
:margin="margin"
|
||||
>
|
||||
<ds-space class="hc-empty" centered :margin="margin">
|
||||
<ds-text>
|
||||
<img
|
||||
:src="iconPath"
|
||||
@ -11,12 +7,9 @@
|
||||
class="hc-empty-icon"
|
||||
style="margin-bottom: 5px"
|
||||
alt="Empty"
|
||||
><br>
|
||||
<ds-text
|
||||
v-show="message"
|
||||
class="hc-empty-message"
|
||||
color="softer"
|
||||
>
|
||||
/>
|
||||
<br />
|
||||
<ds-text v-show="message" class="hc-empty-message" color="softer">
|
||||
{{ message }}
|
||||
</ds-text>
|
||||
</ds-text>
|
||||
|
||||
@ -1,8 +1,5 @@
|
||||
<template>
|
||||
<img
|
||||
v-bind="imageProps"
|
||||
:src="imageSrc"
|
||||
>
|
||||
<img v-bind="imageProps" :src="imageSrc" />
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
@ -1,14 +1,6 @@
|
||||
<template>
|
||||
<ds-space
|
||||
margin-top="large"
|
||||
style="text-align: center"
|
||||
>
|
||||
<ds-button
|
||||
:loading="loading"
|
||||
icon="arrow-down"
|
||||
ghost
|
||||
@click="$emit('click')"
|
||||
>
|
||||
<ds-space margin-top="large" style="text-align: center">
|
||||
<ds-button :loading="loading" icon="arrow-down" ghost @click="$emit('click')">
|
||||
{{ $t('actions.loadMore') }}
|
||||
</ds-button>
|
||||
</ds-space>
|
||||
|
||||
@ -1,30 +1,19 @@
|
||||
<template>
|
||||
<dropdown
|
||||
ref="menu"
|
||||
:placement="placement"
|
||||
:offset="offset"
|
||||
>
|
||||
<dropdown ref="menu" :placement="placement" :offset="offset">
|
||||
<a
|
||||
slot="default"
|
||||
slot-scope="{toggleMenu}"
|
||||
slot-scope="{ toggleMenu }"
|
||||
class="locale-menu"
|
||||
href="#"
|
||||
@click.prevent="toggleMenu()"
|
||||
>
|
||||
<ds-icon
|
||||
style="margin-right: 2px;"
|
||||
name="globe"
|
||||
/>
|
||||
<ds-icon style="margin-right: 2px;" name="globe" />
|
||||
{{ current.code.toUpperCase() }}
|
||||
<ds-icon
|
||||
style="margin-left: 2px"
|
||||
size="xx-small"
|
||||
name="angle-down"
|
||||
/>
|
||||
<ds-icon style="margin-left: 2px" size="xx-small" name="angle-down" />
|
||||
</a>
|
||||
<ds-menu
|
||||
slot="popover"
|
||||
slot-scope="{toggleMenu}"
|
||||
slot-scope="{ toggleMenu }"
|
||||
class="locale-menu-popover"
|
||||
:matcher="matcher"
|
||||
:routes="routes"
|
||||
|
||||
@ -1,15 +1,7 @@
|
||||
<template>
|
||||
<ds-modal
|
||||
:title="title"
|
||||
:is-open="isOpen"
|
||||
@cancel="cancel"
|
||||
>
|
||||
<ds-modal :title="title" :is-open="isOpen" @cancel="cancel">
|
||||
<transition name="ds-transition-fade">
|
||||
<ds-flex
|
||||
v-if="success"
|
||||
class="hc-modal-success"
|
||||
centered
|
||||
>
|
||||
<ds-flex v-if="success" class="hc-modal-success" centered>
|
||||
<sweetalert-icon icon="success" />
|
||||
</ds-flex>
|
||||
</transition>
|
||||
@ -17,24 +9,12 @@
|
||||
<!-- eslint-disable-next-line vue/no-v-html -->
|
||||
<p v-html="message" />
|
||||
|
||||
<template
|
||||
slot="footer"
|
||||
>
|
||||
<ds-button
|
||||
class="cancel"
|
||||
icon="close"
|
||||
@click="cancel"
|
||||
>
|
||||
<template slot="footer">
|
||||
<ds-button class="cancel" icon="close" @click="cancel">
|
||||
{{ $t('post.delete.cancel') }}
|
||||
</ds-button>
|
||||
|
||||
<ds-button
|
||||
danger
|
||||
class="confirm"
|
||||
icon="trash"
|
||||
:loading="loading"
|
||||
@click="confirm"
|
||||
>
|
||||
<ds-button danger class="confirm" icon="trash" :loading="loading" @click="confirm">
|
||||
{{ $t('post.delete.submit') }}
|
||||
</ds-button>
|
||||
</template>
|
||||
|
||||
@ -1,26 +1,14 @@
|
||||
<template>
|
||||
<ds-modal
|
||||
:title="title"
|
||||
:is-open="isOpen"
|
||||
@cancel="cancel"
|
||||
>
|
||||
<ds-modal :title="title" :is-open="isOpen" @cancel="cancel">
|
||||
<!-- eslint-disable-next-line vue/no-v-html -->
|
||||
<p v-html="message" />
|
||||
|
||||
<template slot="footer">
|
||||
<ds-button
|
||||
class="cancel"
|
||||
@click="cancel"
|
||||
>
|
||||
<ds-button class="cancel" @click="cancel">
|
||||
{{ $t('disable.cancel') }}
|
||||
</ds-button>
|
||||
|
||||
<ds-button
|
||||
danger
|
||||
class="confirm"
|
||||
icon="exclamation-circle"
|
||||
@click="confirm"
|
||||
>
|
||||
<ds-button danger class="confirm" icon="exclamation-circle" @click="confirm">
|
||||
{{ $t('disable.submit') }}
|
||||
</ds-button>
|
||||
</template>
|
||||
|
||||
@ -1,15 +1,7 @@
|
||||
<template>
|
||||
<ds-modal
|
||||
:title="title"
|
||||
:is-open="isOpen"
|
||||
@cancel="cancel"
|
||||
>
|
||||
<ds-modal :title="title" :is-open="isOpen" @cancel="cancel">
|
||||
<transition name="ds-transition-fade">
|
||||
<ds-flex
|
||||
v-if="success"
|
||||
class="hc-modal-success"
|
||||
centered
|
||||
>
|
||||
<ds-flex v-if="success" class="hc-modal-success" centered>
|
||||
<sweetalert-icon icon="success" />
|
||||
</ds-flex>
|
||||
</transition>
|
||||
@ -17,14 +9,8 @@
|
||||
<!-- eslint-disable-next-line vue/no-v-html -->
|
||||
<p v-html="message" />
|
||||
|
||||
<template
|
||||
slot="footer"
|
||||
>
|
||||
<ds-button
|
||||
class="cancel"
|
||||
icon="close"
|
||||
@click="cancel"
|
||||
>
|
||||
<template slot="footer">
|
||||
<ds-button class="cancel" icon="close" @click="cancel">
|
||||
{{ $t('report.cancel') }}
|
||||
</ds-button>
|
||||
|
||||
|
||||
@ -27,11 +27,7 @@
|
||||
/>
|
||||
<password-strength :password="formData.newPassword" />
|
||||
<ds-space margin-top="base">
|
||||
<ds-button
|
||||
:loading="loading"
|
||||
:disabled="disabled"
|
||||
primary
|
||||
>
|
||||
<ds-button :loading="loading" :disabled="disabled" primary>
|
||||
{{ $t('settings.security.change-password.button') }}
|
||||
</ds-button>
|
||||
</ds-space>
|
||||
|
||||
@ -1,16 +1,10 @@
|
||||
<template>
|
||||
<div class="field">
|
||||
<div class="password-strength-meter">
|
||||
<div
|
||||
class="password-strength-meter-inner"
|
||||
:class="'strength-' + strength"
|
||||
/>
|
||||
<div class="password-strength-meter-inner" :class="'strength-' + strength" />
|
||||
</div>
|
||||
<p class="help">
|
||||
<span
|
||||
v-if="pass"
|
||||
:class="{ insecure: !isSecure }"
|
||||
>
|
||||
<span v-if="pass" :class="{ insecure: !isSecure }">
|
||||
{{ $t('settings.security.change-password.passwordSecurity') }}:
|
||||
<strong>{{ $t(`settings.security.change-password.passwordStrength${strength}`) }}</strong>
|
||||
</span>
|
||||
|
||||
@ -1,8 +1,5 @@
|
||||
<template>
|
||||
<ds-card
|
||||
:image="post.image"
|
||||
:class="{'post-card': true, 'disabled-content': post.disabled}"
|
||||
>
|
||||
<ds-card :image="post.image" :class="{ 'post-card': true, 'disabled-content': post.disabled }">
|
||||
<!-- Post Link Target -->
|
||||
<nuxt-link
|
||||
class="post-link"
|
||||
@ -14,30 +11,20 @@
|
||||
<!-- Username, Image & Date of Post -->
|
||||
<div>
|
||||
<no-ssr>
|
||||
<hc-user
|
||||
:user="post.author"
|
||||
:trunc="35"
|
||||
:date-time="post.createdAt"
|
||||
/>
|
||||
<hc-user :user="post.author" :trunc="35" :date-time="post.createdAt" />
|
||||
</no-ssr>
|
||||
<hc-ribbon :text="$t('post.name')" />
|
||||
</div>
|
||||
<ds-space margin-bottom="small" />
|
||||
<!-- Post Title -->
|
||||
<ds-heading
|
||||
tag="h3"
|
||||
no-margin
|
||||
>
|
||||
<ds-heading tag="h3" no-margin>
|
||||
{{ post.title }}
|
||||
</ds-heading>
|
||||
<ds-space margin-bottom="small" />
|
||||
<!-- Post Content Excerpt -->
|
||||
<!-- eslint-disable vue/no-v-html -->
|
||||
<!-- TODO: replace editor content with tiptap render view -->
|
||||
<div
|
||||
class="hc-editor-content"
|
||||
v-html="excerpt"
|
||||
/>
|
||||
<div class="hc-editor-content" v-html="excerpt" />
|
||||
<!-- eslint-enable vue/no-v-html -->
|
||||
<!-- Footer o the Post -->
|
||||
<template slot="footer">
|
||||
@ -46,29 +33,25 @@
|
||||
<hc-category
|
||||
v-for="category in post.categories"
|
||||
:key="category.id"
|
||||
v-tooltip="{content: category.name, placement: 'bottom-start', delay: { show: 500 }}"
|
||||
v-tooltip="{ content: category.name, placement: 'bottom-start', delay: { show: 500 } }"
|
||||
:icon="category.icon"
|
||||
/>
|
||||
</div>
|
||||
<no-ssr>
|
||||
<div style="display: inline-block; float: right">
|
||||
<!-- Shouts Count -->
|
||||
<span :style="{ opacity: post.shoutedCount ? 1 : .5 }">
|
||||
<span :style="{ opacity: post.shoutedCount ? 1 : 0.5 }">
|
||||
<ds-icon name="bullhorn" />
|
||||
<small>{{ post.shoutedCount }}</small>
|
||||
</span>
|
||||
|
||||
<!-- Comments Count -->
|
||||
<span :style="{ opacity: post.commentsCount ? 1 : .5 }">
|
||||
<span :style="{ opacity: post.commentsCount ? 1 : 0.5 }">
|
||||
<ds-icon name="comments" />
|
||||
<small>{{ post.commentsCount }}</small>
|
||||
</span>
|
||||
<!-- Menu -->
|
||||
<content-menu
|
||||
resource-type="contribution"
|
||||
:resource="post"
|
||||
:is-owner="isAuthor"
|
||||
/>
|
||||
<content-menu resource-type="contribution" :resource="post" :is-owner="isAuthor" />
|
||||
</div>
|
||||
</no-ssr>
|
||||
</template>
|
||||
|
||||
@ -5,16 +5,12 @@
|
||||
role="search"
|
||||
:class="{
|
||||
'is-active': isActive,
|
||||
'is-open': isOpen
|
||||
'is-open': isOpen,
|
||||
}"
|
||||
>
|
||||
<div class="field">
|
||||
<div class="control">
|
||||
<a
|
||||
v-if="isActive"
|
||||
class="search-clear-btn"
|
||||
@click="clear"
|
||||
>
|
||||
<a v-if="isActive" class="search-clear-btn" @click="clear">
|
||||
|
||||
</a>
|
||||
<ds-select
|
||||
@ -42,42 +38,31 @@
|
||||
@input.native="handleInput"
|
||||
@click.capture.native="isOpen = true"
|
||||
>
|
||||
<template
|
||||
slot="option"
|
||||
slot-scope="{option}"
|
||||
>
|
||||
<template slot="option" slot-scope="{ option }">
|
||||
<ds-flex>
|
||||
<ds-flex-item class="search-option-label">
|
||||
<ds-text>
|
||||
{{ option.label | truncate(70) }}
|
||||
</ds-text>
|
||||
</ds-flex-item>
|
||||
<ds-flex-item
|
||||
class="search-option-meta"
|
||||
width="280px"
|
||||
>
|
||||
<ds-flex-item class="search-option-meta" width="280px">
|
||||
<ds-flex>
|
||||
<ds-flex-item>
|
||||
<ds-text
|
||||
size="small"
|
||||
color="softer"
|
||||
class="search-meta"
|
||||
>
|
||||
<ds-text size="small" color="softer" class="search-meta">
|
||||
<span style="text-align: right;">
|
||||
<b>{{ option.commentsCount }}</b> <ds-icon name="comments" />
|
||||
<b>{{ option.commentsCount }}</b>
|
||||
<ds-icon name="comments" />
|
||||
</span>
|
||||
<span style="width: 36px; display: inline-block; text-align: right;">
|
||||
<b>{{ option.shoutedCount }}</b> <ds-icon name="bullhorn" />
|
||||
<b>{{ option.shoutedCount }}</b>
|
||||
<ds-icon name="bullhorn" />
|
||||
</span>
|
||||
</ds-text>
|
||||
</ds-flex-item>
|
||||
<ds-flex-item>
|
||||
<ds-text
|
||||
size="small"
|
||||
color="softer"
|
||||
align="right"
|
||||
>
|
||||
{{ option.author.name | truncate(32) }} - {{ option.createdAt | dateTime('dd.MM.yyyy') }}
|
||||
<ds-text size="small" color="softer" align="right">
|
||||
{{ option.author.name | truncate(32) }} -
|
||||
{{ option.createdAt | dateTime('dd.MM.yyyy') }}
|
||||
</ds-text>
|
||||
</ds-flex-item>
|
||||
</ds-flex>
|
||||
|
||||
@ -1,8 +1,5 @@
|
||||
<template>
|
||||
<ds-space
|
||||
margin="large"
|
||||
style="text-align: center"
|
||||
>
|
||||
<ds-space margin="large" style="text-align: center">
|
||||
<ds-button
|
||||
:loading="loading"
|
||||
:disabled="disabled"
|
||||
@ -13,16 +10,9 @@
|
||||
@click="toggle"
|
||||
/>
|
||||
<ds-space margin-bottom="xx-small" />
|
||||
<ds-text
|
||||
color="soft"
|
||||
class="shout-button-text"
|
||||
>
|
||||
<ds-heading
|
||||
style="display: inline"
|
||||
tag="h3"
|
||||
>
|
||||
{{ shoutedCount }}x
|
||||
</ds-heading> {{ $t('shoutButton.shouted') }}
|
||||
<ds-text color="soft" class="shout-button-text">
|
||||
<ds-heading style="display: inline" tag="h3">{{ shoutedCount }}x</ds-heading>
|
||||
{{ $t('shoutButton.shouted') }}
|
||||
</ds-text>
|
||||
</ds-space>
|
||||
</template>
|
||||
|
||||
@ -36,7 +36,9 @@ export default {
|
||||
},
|
||||
computed: {
|
||||
backgroundImage() {
|
||||
const { avatar } = this.user || {}
|
||||
const avatar =
|
||||
this.user.avatar ||
|
||||
'https://human-connection.org/wp-content/uploads/2019/03/human-connection-logo.svg'
|
||||
const userAvatar = avatar.startsWith('/') ? avatar.replace('/', '/api/') : avatar
|
||||
return {
|
||||
backgroundImage: `url(${userAvatar})`,
|
||||
|
||||
@ -6,53 +6,24 @@
|
||||
<hc-avatar />
|
||||
</div>
|
||||
<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>
|
||||
</div>
|
||||
</div>
|
||||
<dropdown
|
||||
v-else
|
||||
:class="{'disabled-content': user.disabled}"
|
||||
placement="top-start"
|
||||
offset="0"
|
||||
>
|
||||
<template
|
||||
slot="default"
|
||||
slot-scope="{openMenu, closeMenu, isOpen}"
|
||||
>
|
||||
<nuxt-link
|
||||
:to="userLink"
|
||||
:class="['user', isOpen && 'active']"
|
||||
>
|
||||
<div
|
||||
@mouseover="openMenu(true)"
|
||||
@mouseleave="closeMenu(true)"
|
||||
>
|
||||
<dropdown v-else :class="{ 'disabled-content': user.disabled }" placement="top-start" offset="0">
|
||||
<template slot="default" slot-scope="{ openMenu, closeMenu, isOpen }">
|
||||
<nuxt-link :to="userLink" :class="['user', isOpen && 'active']">
|
||||
<div @mouseover="openMenu(true)" @mouseleave="closeMenu(true)">
|
||||
<div
|
||||
style="display: inline-block; float: left; margin-right: 4px; height: 100%; vertical-align: middle;"
|
||||
>
|
||||
<hc-avatar
|
||||
:user="user"
|
||||
/>
|
||||
<hc-avatar :user="user" />
|
||||
</div>
|
||||
<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>
|
||||
</div>
|
||||
<!-- Time -->
|
||||
<div
|
||||
v-if="dateTime"
|
||||
style="display: inline;"
|
||||
>
|
||||
<ds-text
|
||||
align="left"
|
||||
size="small"
|
||||
color="soft"
|
||||
>
|
||||
<div v-if="dateTime" style="display: inline;">
|
||||
<ds-text align="left" size="small" color="soft">
|
||||
<ds-icon name="clock" />
|
||||
<no-ssr>
|
||||
<hc-relative-date-time :date-time="dateTime" />
|
||||
@ -64,10 +35,7 @@
|
||||
</template>
|
||||
<template slot="popover">
|
||||
<div style="min-width: 250px">
|
||||
<hc-badges
|
||||
v-if="user.badges && user.badges.length"
|
||||
:badges="user.badges"
|
||||
/>
|
||||
<hc-badges v-if="user.badges && user.badges.length" :badges="user.badges" />
|
||||
<ds-text
|
||||
v-if="user.location"
|
||||
align="center"
|
||||
@ -82,11 +50,7 @@
|
||||
<ds-flex style="margin-top: -10px">
|
||||
<ds-flex-item class="ds-tab-nav-item">
|
||||
<ds-space margin="small">
|
||||
<ds-number
|
||||
:count="fanCount"
|
||||
:label="$t('profile.followers')"
|
||||
size="x-large"
|
||||
/>
|
||||
<ds-number :count="fanCount" :label="$t('profile.followers')" size="x-large" />
|
||||
</ds-space>
|
||||
</ds-flex-item>
|
||||
<ds-flex-item class="ds-tab-nav-item ds-tab-nav-item-active">
|
||||
@ -106,20 +70,16 @@
|
||||
</ds-space>
|
||||
</ds-flex-item>
|
||||
</ds-flex>
|
||||
<ds-flex
|
||||
v-if="!itsMe"
|
||||
gutter="x-small"
|
||||
style="margin-bottom: 0;"
|
||||
>
|
||||
<ds-flex-item :width="{base: 3}">
|
||||
<ds-flex v-if="!itsMe" gutter="x-small" style="margin-bottom: 0;">
|
||||
<ds-flex-item :width="{ base: 3 }">
|
||||
<hc-follow-button
|
||||
:follow-id="user.id"
|
||||
:is-followed="user.followedByCurrentUser"
|
||||
@optimistic="follow => user.followedByCurrentUser = follow"
|
||||
@update="follow => user.followedByCurrentUser = follow"
|
||||
@optimistic="follow => (user.followedByCurrentUser = follow)"
|
||||
@update="follow => (user.followedByCurrentUser = follow)"
|
||||
/>
|
||||
</ds-flex-item>
|
||||
<ds-flex-item :width="{base: 1}">
|
||||
<ds-flex-item :width="{ base: 1 }">
|
||||
<ds-button fullwidth>
|
||||
<ds-icon name="user-times" />
|
||||
</ds-button>
|
||||
|
||||
@ -1,36 +1,18 @@
|
||||
<template>
|
||||
<ds-form
|
||||
v-model="form"
|
||||
@submit="handleSubmit"
|
||||
>
|
||||
<ds-form v-model="form" @submit="handleSubmit">
|
||||
<template slot-scope="{ errors }">
|
||||
<ds-card>
|
||||
<hc-editor
|
||||
ref="editor"
|
||||
:users="users"
|
||||
:value="form.content"
|
||||
@input="updateEditorContent"
|
||||
/>
|
||||
<hc-editor ref="editor" :users="users" :value="form.content" @input="updateEditorContent" />
|
||||
<ds-space />
|
||||
<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: '40%', md: '20%', sm: '30%', xs: '30%' }">
|
||||
<ds-button
|
||||
:disabled="disabled"
|
||||
ghost
|
||||
class="cancelBtn"
|
||||
@click.prevent="clear"
|
||||
>
|
||||
<ds-button :disabled="disabled" ghost class="cancelBtn" @click.prevent="clear">
|
||||
{{ $t('actions.cancel') }}
|
||||
</ds-button>
|
||||
</ds-flex-item>
|
||||
<ds-flex-item :width="{ base: '40%', md: '20%', sm: '40%', xs: '40%' }">
|
||||
<ds-button
|
||||
type="submit"
|
||||
:loading="loading"
|
||||
:disabled="disabled || errors"
|
||||
primary
|
||||
>
|
||||
<ds-button type="submit" :loading="loading" :disabled="disabled || errors" primary>
|
||||
{{ $t('post.comment.submit') }}
|
||||
</ds-button>
|
||||
</ds-flex-item>
|
||||
|
||||
@ -9,26 +9,17 @@
|
||||
color="primary"
|
||||
size="small"
|
||||
round
|
||||
>{{ comments.length }}</ds-tag> Comments
|
||||
>
|
||||
{{ comments.length }}
|
||||
</ds-tag>
|
||||
Comments
|
||||
</span>
|
||||
</h3>
|
||||
<ds-space margin-bottom="large" />
|
||||
<div
|
||||
v-if="comments && comments.length"
|
||||
id="comments"
|
||||
class="comments"
|
||||
>
|
||||
<comment
|
||||
v-for="comment in comments"
|
||||
:key="comment.id"
|
||||
:comment="comment"
|
||||
/>
|
||||
<div v-if="comments && comments.length" id="comments" class="comments">
|
||||
<comment v-for="comment in comments" :key="comment.id" :comment="comment" />
|
||||
</div>
|
||||
<hc-empty
|
||||
v-else
|
||||
name="empty"
|
||||
icon="messages"
|
||||
/>
|
||||
<hc-empty v-else name="empty" icon="messages" />
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
|
||||
@ -1,18 +1,11 @@
|
||||
<template>
|
||||
<ds-space
|
||||
:class="{'notification': true, 'read': notification.read}"
|
||||
margin-bottom="x-small"
|
||||
>
|
||||
<ds-space :class="{ notification: true, read: notification.read }" margin-bottom="x-small">
|
||||
<no-ssr>
|
||||
<ds-space margin-bottom="x-small">
|
||||
<hc-user
|
||||
:user="post.author"
|
||||
:date-time="post.createdAt"
|
||||
:trunc="35"
|
||||
/>
|
||||
<hc-user :user="post.author" :date-time="post.createdAt" :trunc="35" />
|
||||
</ds-space>
|
||||
<ds-text color="soft">
|
||||
{{ $t("notifications.menu.mentioned") }}
|
||||
{{ $t('notifications.menu.mentioned') }}
|
||||
</ds-text>
|
||||
</no-ssr>
|
||||
<ds-space margin-bottom="x-small" />
|
||||
@ -22,16 +15,11 @@
|
||||
@click.native="$emit('read')"
|
||||
>
|
||||
<ds-space margin-bottom="x-small">
|
||||
<ds-card
|
||||
:header="post.title"
|
||||
:image="post.image"
|
||||
hover
|
||||
space="x-small"
|
||||
>
|
||||
<ds-card :header="post.title" :image="post.image" hover space="x-small">
|
||||
<ds-space margin-bottom="x-small" />
|
||||
<!-- eslint-disable vue/no-v-html -->
|
||||
<div v-html="excerpt" />
|
||||
<!-- eslint-enable vue/no-v-html -->
|
||||
<!-- eslint-enable vue/no-v-html -->
|
||||
</ds-card>
|
||||
</ds-space>
|
||||
</nuxt-link>
|
||||
|
||||
@ -1,36 +1,16 @@
|
||||
<template>
|
||||
<ds-button
|
||||
v-if="totalNotifications <= 0"
|
||||
class="notifications-menu"
|
||||
disabled
|
||||
icon="bell"
|
||||
>
|
||||
<ds-button v-if="totalNotifications <= 0" class="notifications-menu" disabled icon="bell">
|
||||
{{ totalNotifications }}
|
||||
</ds-button>
|
||||
<dropdown
|
||||
v-else
|
||||
class="notifications-menu"
|
||||
>
|
||||
<template
|
||||
slot="default"
|
||||
slot-scope="{toggleMenu}"
|
||||
>
|
||||
<ds-button
|
||||
primary
|
||||
icon="bell"
|
||||
@click.prevent="toggleMenu"
|
||||
>
|
||||
<dropdown v-else class="notifications-menu">
|
||||
<template slot="default" slot-scope="{ toggleMenu }">
|
||||
<ds-button primary icon="bell" @click.prevent="toggleMenu">
|
||||
{{ totalNotifications }}
|
||||
</ds-button>
|
||||
</template>
|
||||
<template
|
||||
slot="popover"
|
||||
>
|
||||
<template slot="popover">
|
||||
<div class="notifications-menu-popover">
|
||||
<notification-list
|
||||
:notifications="notifications"
|
||||
@markAsRead="markAsRead"
|
||||
/>
|
||||
<notification-list :notifications="notifications" @markAsRead="markAsRead" />
|
||||
</div>
|
||||
</template>
|
||||
</dropdown>
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user