Merge branch 'master' of https://github.com/Ocelot-Social-Community/Ocelot-Social into feature/mark-all-notification-as-read-test

This commit is contained in:
Wolfgang Huß 2020-11-12 15:37:38 +01:00
commit a94d7188be
49 changed files with 523 additions and 138 deletions

View File

@ -45,10 +45,12 @@ script:
- docker-compose down - docker-compose down
- docker-compose -f docker-compose.yml up -d - docker-compose -f docker-compose.yml up -d
- wait-on http://localhost:7474 - wait-on http://localhost:7474
- yarn run cypress:run --record # disable for last deploy, because of flakiness!
- yarn run cucumber # - yarn run cypress:run --record
# - yarn run cucumber
# Coverage # Coverage
- yarn run codecov # disable this uneffective thing for last deploy, because of easyness!
# - yarn run codecov
after_success: after_success:
- wget https://raw.githubusercontent.com/DiscordHooks/travis-ci-discord-webhook/master/send.sh - wget https://raw.githubusercontent.com/DiscordHooks/travis-ci-discord-webhook/master/send.sh
@ -67,14 +69,16 @@ after_failure:
before_deploy: before_deploy:
- go get -u github.com/tcnksm/ghr - go get -u github.com/tcnksm/ghr
- ./scripts/setup_kubernetes.sh # stop deployment to kubernetes until we have set it up
# - ./scripts/setup_kubernetes.sh
deploy: deploy:
- provider: script - provider: script
script: bash scripts/docker_push.sh script: bash scripts/docker_push.sh
on: on:
branch: master branch: master
- provider: script # stop deployment to kubernetes until we have set it up
script: bash scripts/deploy.sh # - provider: script
on: # script: bash scripts/deploy.sh
branch: master # on:
# branch: master

View File

@ -4,6 +4,36 @@ All notable changes to this project will be documented in this file. Dates are d
Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog). Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
#### [v0.6.3](https://github.com/Human-Connection/Human-Connection/compare/v0.6.0...v0.6.3)
> 16 October 2020
- feat: Export User Data Update [`#3954`](https://github.com/Human-Connection/Human-Connection/pull/3954)
- chore: Upgrade to v0.6.2 [`#3947`](https://github.com/Human-Connection/Human-Connection/pull/3947)
#### [v0.6.2](https://github.com/Human-Connection/Human-Connection/compare/v0.6.1...v0.6.2)
> 15 October 2020
- build: 🍰 Disable Codecov for last deploy [`#3946`](https://github.com/Human-Connection/Human-Connection/pull/3946)
- feat: Export User Data [`#3899`](https://github.com/Human-Connection/Human-Connection/pull/3899)
- build: 💥 Disable full stack tests, Fix deployment to develop, tryout [`#3937`](https://github.com/Human-Connection/Human-Connection/pull/3937)
- build: 💥 Disable full stack tests [`#3935`](https://github.com/Human-Connection/Human-Connection/pull/3935)
- fix: 🍰 Sign Up Page On Safari [`#3882`](https://github.com/Human-Connection/Human-Connection/pull/3882)
- build: Add semantic PR config [`#3884`](https://github.com/Human-Connection/Human-Connection/pull/3884)
- feat: 🍰 Admin - Remove User Profile [`#3140`](https://github.com/Human-Connection/Human-Connection/pull/3140)
- fix: 🍰 Comment Counters Are Now Equal [`#3769`](https://github.com/Human-Connection/Human-Connection/pull/3769)
- feat: 🍰 Redesign Data Privacy Warning Box [`#3780`](https://github.com/Human-Connection/Human-Connection/pull/3780)
- fix: 🍰 Checkboxes Not Missing Anymore On Delete User Account Page [`#3506`](https://github.com/Human-Connection/Human-Connection/pull/3506)
- feat: 🍰 Increase Margin Of Header And Ruler For Better Legibility [`#3774`](https://github.com/Human-Connection/Human-Connection/pull/3774)
- chore: 💬 Rename stale.yml to stale-disabled.yml [`#3662`](https://github.com/Human-Connection/Human-Connection/pull/3662)
- build(deps): [security] bump apollo-server-core from 2.12.0 to 2.15.0 in /backend [`#3650`](https://github.com/Human-Connection/Human-Connection/pull/3650)
- fix: Corrected Code-of-Conduct Mail Link [`#3609`](https://github.com/Human-Connection/Human-Connection/pull/3609)
- feat: 🍰 Hero image height on post page is now set without having to wait for… [`#3583`](https://github.com/Human-Connection/Human-Connection/pull/3583)
- feat: 🍰 Alphabetically sorting tags using compute functions on index and more… [`#3589`](https://github.com/Human-Connection/Human-Connection/pull/3589)
- fix: Fixed webapp unit test command. [`#3584`](https://github.com/Human-Connection/Human-Connection/pull/3584)
- chore: Upgrade to v0.6.1 [`#3525`](https://github.com/Human-Connection/Human-Connection/pull/3525)
#### [v0.6.1](https://github.com/Human-Connection/Human-Connection/compare/v0.6.0...v0.6.1) #### [v0.6.1](https://github.com/Human-Connection/Human-Connection/compare/v0.6.0...v0.6.1)
> 4 May 2020 > 4 May 2020

View File

@ -1,11 +1,11 @@
FROM node:lts-alpine as base FROM node:12.19.0-alpine3.10 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)" 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 EXPOSE 4000
CMD ["yarn", "run", "start"] CMD ["yarn", "run", "start"]
ARG BUILD_COMMIT ARG BUILD_COMMIT
ENV BUILD_COMMIT=$BUILD_COMMIT ENV BUILD_COMMIT=$BUILD_COMMIT
ARG WORKDIR=/nitro-backend ARG WORKDIR=/develop-backend
RUN mkdir -p $WORKDIR RUN mkdir -p $WORKDIR
WORKDIR $WORKDIR WORKDIR $WORKDIR
@ -22,7 +22,7 @@ RUN NODE_ENV=production yarn run build
# reduce image size with a multistage build # reduce image size with a multistage build
FROM base as production FROM base as production
ENV NODE_ENV=production ENV NODE_ENV=production
COPY --from=build-and-test /nitro-backend/dist ./dist COPY --from=build-and-test /develop-backend/dist ./dist
COPY ./public/img/ ./public/img/ COPY ./public/img/ ./public/img/
COPY ./public/providers.json ./public/providers.json COPY ./public/providers.json ./public/providers.json
RUN yarn install --production=true --frozen-lockfile --non-interactive --no-cache RUN yarn install --production=true --frozen-lockfile --non-interactive --no-cache

View File

@ -1,6 +1,6 @@
{ {
"name": "human-connection-backend", "name": "human-connection-backend",
"version": "0.6.1", "version": "0.6.3",
"description": "GraphQL Backend for Human Connection", "description": "GraphQL Backend for Human Connection",
"main": "src/index.js", "main": "src/index.js",
"scripts": { "scripts": {

View File

@ -105,6 +105,7 @@ export default shield(
blockedUsers: isAuthenticated, blockedUsers: isAuthenticated,
notifications: isAuthenticated, notifications: isAuthenticated,
Donations: isAuthenticated, Donations: isAuthenticated,
userData: isAuthenticated,
}, },
Mutation: { Mutation: {
'*': deny, '*': deny,

View File

@ -0,0 +1,61 @@
export default {
Query: {
userData: async (object, args, context, resolveInfo) => {
const id = context.user.id
const cypher = `
MATCH (user:User { id: $id })
WITH user
OPTIONAL MATCH (posts:Post)
WHERE (user)-[:WROTE]->(posts)
AND posts.deleted = FALSE
AND posts.disabled = FALSE
RETURN { user: properties(user),
posts: collect(
posts {
.*,
author: [
(posts)<-[:WROTE]-(author:User) |
author {
.*
}
][0],
comments: [
(posts)<-[:COMMENTS]-(comment:Comment)
WHERE comment.disabled = FALSE
AND comment.deleted = FALSE |
comment {
.*,
author: [ (comment)<-[:WROTE]-(commentator:User) |
commentator { .name, .slug, .id } ][0]
}
],
categories: [ (posts)-[:CATEGORIZED]->(category:Category) |
category { .name, .id } ]
})
} AS result`
const session = context.driver.session()
const resultPromise = session.readTransaction(async (transaction) => {
const transactionResponse = transaction.run(cypher, {
id,
})
return transactionResponse
})
try {
const result = await resultPromise
const userData = result.records[0].get('result')
userData.posts.sort(byCreationDate)
userData.posts.forEach((post) => post.comments.sort(byCreationDate))
return userData
} finally {
session.close()
}
},
},
}
const byCreationDate = (a, b) => {
if (a.createdAt < b.createdAt) return -1
if (a.createdAt > b.createdAt) return 1
return 0
}

View File

@ -0,0 +1,143 @@
import Factory, { cleanDatabase } from '../../db/factories'
import { gql } from '../../helpers/jest'
import { getNeode, getDriver } from '../../db/neo4j'
import createServer from '../../server'
import { createTestClient } from 'apollo-server-testing'
let query, authenticatedUser
const driver = getDriver()
const neode = getNeode()
beforeAll(async () => {
await cleanDatabase()
const user = await Factory.build('user', {
id: 'a-user',
name: 'John Doe',
slug: 'john-doe',
})
await Factory.build('user', {
id: 'o-user',
name: 'Unauthenticated User',
slug: 'unauthenticated-user',
})
authenticatedUser = await user.toJson()
const { server } = createServer({
context: () => {
return {
driver,
neode,
user: authenticatedUser,
}
},
})
query = createTestClient(server).query
})
afterAll(async () => {
await cleanDatabase()
})
const userDataQuery = gql`
query($id: ID!) {
userData(id: $id) {
user {
id
name
slug
}
posts {
id
title
content
comments {
content
author {
slug
}
}
}
}
}
`
describe('resolvers/userData', () => {
let variables = { id: 'a-user' }
describe('given one authenticated user who did not write anything so far', () => {
it("returns the user's data and no posts", async () => {
await expect(query({ query: userDataQuery, variables })).resolves.toMatchObject({
data: {
userData: {
user: {
id: 'a-user',
name: 'John Doe',
slug: 'john-doe',
},
posts: [],
},
},
})
})
describe('the user writes a post', () => {
beforeAll(async () => {
await Factory.build(
'post',
{
id: 'a-post',
title: 'A post',
content: 'A post',
},
{ authorId: 'a-user' },
)
})
it("returns the user's data and the post", async () => {
await expect(query({ query: userDataQuery, variables })).resolves.toMatchObject({
data: {
userData: {
user: {
id: 'a-user',
name: 'John Doe',
slug: 'john-doe',
},
posts: [
{
id: 'a-post',
title: 'A post',
content: 'A post',
},
],
},
},
})
})
})
})
describe('try to request data of another user', () => {
variables = { id: 'o-user' }
it('returns the data of the authenticated user', async () => {
await expect(query({ query: userDataQuery, variables })).resolves.toMatchObject({
data: {
userData: {
user: {
id: 'a-user',
name: 'John Doe',
slug: 'john-doe',
},
posts: expect.arrayContaining([
{
id: 'a-post',
title: 'A post',
content: 'A post',
comments: [],
},
]),
},
},
})
})
})
})

View File

@ -0,0 +1,10 @@
type UserData {
user: User!
posts: [Post]
}
type Query {
userData(
id: ID
): UserData
}

View File

@ -44,7 +44,7 @@ spec:
terminationMessagePath: /dev/termination-log terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File terminationMessagePolicy: File
volumeMounts: volumeMounts:
- mountPath: /nitro-backend/public/uploads - mountPath: /develop-backend/public/uploads
name: uploads name: uploads
dnsPolicy: ClusterFirst dnsPolicy: ClusterFirst
restartPolicy: Always restartPolicy: Always

View File

@ -7,13 +7,13 @@ dbInitializion: "yarn prod:migrate init"
# dbMigrations runs the database migrations in a post-upgrade hook. # dbMigrations runs the database migrations in a post-upgrade hook.
dbMigrations: "yarn prod:migrate up" dbMigrations: "yarn prod:migrate up"
# bakendImage is the docker image for the backend deployment # bakendImage is the docker image for the backend deployment
backendImage: humanconnection/nitro-backend backendImage: ocelotsocialnetwork/develop-backend
# maintenanceImage is the docker image for the maintenance deployment # maintenanceImage is the docker image for the maintenance deployment
maintenanceImage: humanconnection/maintenance maintenanceImage: ocelotsocialnetwork/develop-maintenance
# neo4jImage is the docker image for the neo4j deployment # neo4jImage is the docker image for the neo4j deployment
neo4jImage: humanconnection/neo4j neo4jImage: ocelotsocialnetwork/develop-neo4j
# webappImage is the docker image for the webapp deployment # webappImage is the docker image for the webapp deployment
webappImage: humanconnection/nitro-web webappImage: ocelotsocialnetwork/develop-webapp
# image configures pullPolicy related to the docker images # image configures pullPolicy related to the docker images
image: image:
# pullPolicy indicates when, if ever, pods pull a new image from docker hub. # pullPolicy indicates when, if ever, pods pull a new image from docker hub.

View File

@ -36,7 +36,7 @@ spec:
name: configmap name: configmap
- secretRef: - secretRef:
name: human-connection name: human-connection
image: humanconnection/nitro-backend:latest image: ocelotsocialnetwork/develop-backend:latest
imagePullPolicy: Always imagePullPolicy: Always
name: backend name: backend
ports: ports:
@ -46,7 +46,7 @@ spec:
terminationMessagePath: /dev/termination-log terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File terminationMessagePolicy: File
volumeMounts: volumeMounts:
- mountPath: /nitro-backend/public/uploads - mountPath: /develop-backend/public/uploads
name: uploads name: uploads
dnsPolicy: ClusterFirst dnsPolicy: ClusterFirst
restartPolicy: Always restartPolicy: Always

View File

@ -31,7 +31,7 @@ spec:
- envFrom: - envFrom:
- configMapRef: - configMapRef:
name: configmap name: configmap
image: humanconnection/neo4j:latest image: ocelotsocialnetwork/develop-neo4j:latest
imagePullPolicy: Always imagePullPolicy: Always
name: neo4j name: neo4j
ports: ports:

View File

@ -37,7 +37,7 @@ spec:
name: configmap name: configmap
- secretRef: - secretRef:
name: human-connection name: human-connection
image: humanconnection/nitro-web:latest image: ocelotsocialnetwork/develop-webapp:latest
imagePullPolicy: Always imagePullPolicy: Always
name: web name: web
ports: ports:

View File

@ -10,9 +10,10 @@ bring the database into maintenance mode for manual database migrations.
## Deploy the service ## Deploy the service
We prepared sample configuration, so you can simply run: We prepared sample configuration, so you can simply run:
```sh ```sh
# in folder deployment/ # in folder deployment/
kubectl apply -f human-connection/maintenance $ kubectl apply -f ocelotsocialnetwork/develop-maintenance
``` ```
This will fire up a maintenance service. This will fire up a maintenance service.
@ -23,6 +24,7 @@ Now if you want to have a controlled downtime and you want to bring your
application into maintenance mode, you can edit your global ingress server. application into maintenance mode, you can edit your global ingress server.
E.g. in file `deployment/digital-ocean/https/ingress.yaml` change the following: E.g. in file `deployment/digital-ocean/https/ingress.yaml` change the following:
```yaml ```yaml
... ...
@ -31,13 +33,13 @@ E.g. in file `deployment/digital-ocean/https/ingress.yaml` change the following:
paths: paths:
- path: / - path: /
backend: backend:
# serviceName: nitro-web # serviceName: develop-webapp
serviceName: maintenance serviceName: develop-maintenance
# servicePort: 3000 # servicePort: 3000
servicePort: 80 servicePort: 80
``` ```
Then run ` kubectl apply -f deployment/digital-ocean/https/ingress.yaml`. If you Then run `$ kubectl apply -f deployment/digital-ocean/https/ingress.yaml`. If you
want to deactivate the maintenance server, just undo the edit and apply the want to deactivate the maintenance server, just undo the edit and apply the
configuration again. configuration again.

View File

@ -19,7 +19,7 @@ spec:
env: env:
- name: HOST - name: HOST
value: 0.0.0.0 value: 0.0.0.0
image: humanconnection/maintenance:latest image: ocelotsocialnetwork/develop-maintenance:latest
ports: ports:
- containerPort: 80 - containerPort: 80
imagePullPolicy: Always imagePullPolicy: Always

View File

@ -4,10 +4,10 @@
data: data:
SMTP_HOST: "mailserver.human-connection" SMTP_HOST: "mailserver.human-connection"
SMTP_PORT: "25" SMTP_PORT: "25"
GRAPHQL_URI: "http://nitro-backend.human-connection:4000" GRAPHQL_URI: "http://backend.human-connection:4000"
NEO4J_URI: "bolt://nitro-neo4j.human-connection:7687" NEO4J_URI: "bolt://neo4j.human-connection:7687"
NEO4J_AUTH: "none" NEO4J_AUTH: "none"
CLIENT_URI: "https://nitro-staging.human-connection.org" CLIENT_URI: "https://staging.human-connection.org"
NEO4J_apoc_import_file_enabled: "true" NEO4J_apoc_import_file_enabled: "true"
NEO4J_dbms_memory_pagecache_size: "490M" NEO4J_dbms_memory_pagecache_size: "490M"
NEO4J_dbms_memory_heap_max__size: "500M" NEO4J_dbms_memory_heap_max__size: "500M"

View File

@ -43,27 +43,27 @@ Then temporarily delete backend and database deployments
```bash ```bash
$ kubectl --namespace=human-connection get deployments $ kubectl --namespace=human-connection get deployments
NAME READY UP-TO-DATE AVAILABLE AGE NAME READY UP-TO-DATE AVAILABLE AGE
nitro-backend 1/1 1 1 3d11h develop-backend 1/1 1 1 3d11h
nitro-neo4j 1/1 1 1 3d11h develop-neo4j 1/1 1 1 3d11h
nitro-web 2/2 2 2 73d develop-webapp 2/2 2 2 73d
$ kubectl --namespace=human-connection delete deployment nitro-neo4j $ kubectl --namespace=human-connection delete deployment develop-neo4j
deployment.extensions "nitro-neo4j" deleted deployment.extensions "develop-neo4j" deleted
$ kubectl --namespace=human-connection delete deployment nitro-backend $ kubectl --namespace=human-connection delete deployment develop-backend
deployment.extensions "nitro-backend" deleted deployment.extensions "develop-backend" deleted
``` ```
Deploy one-time maintenance-worker pod: Deploy one-time develop-maintenance-worker pod:
```bash ```bash
# in deployment/legacy-migration/ # in deployment/legacy-migration/
$ kubectl apply -f maintenance-worker.yaml $ kubectl apply -f maintenance-worker.yaml
pod/nitro-maintenance-worker created pod/develop-maintenance-worker created
``` ```
Import legacy database and uploads: Import legacy database and uploads:
```bash ```bash
$ kubectl --namespace=human-connection exec -it nitro-maintenance-worker bash $ kubectl --namespace=human-connection exec -it develop-maintenance-worker bash
$ import_legacy_db $ import_legacy_db
$ import_legacy_uploads $ import_legacy_uploads
$ exit $ exit
@ -72,7 +72,7 @@ $ exit
Delete the pod when you're done: Delete the pod when you're done:
```bash ```bash
$ kubectl --namespace=human-connection delete pod nitro-maintenance-worker $ kubectl --namespace=human-connection delete pod develop-maintenance-worker
``` ```
Oh, and of course you have to get those deleted deployments back. One way of Oh, and of course you have to get those deleted deployments back. One way of

View File

@ -2,12 +2,12 @@
kind: Pod kind: Pod
apiVersion: v1 apiVersion: v1
metadata: metadata:
name: nitro-maintenance-worker name: develop-maintenance-worker
namespace: human-connection namespace: human-connection
spec: spec:
containers: containers:
- name: nitro-maintenance-worker - name: develop-maintenance-worker
image: humanconnection/maintenance-worker:latest image: ocelotsocialnetwork/develop-maintenance-worker:latest
imagePullPolicy: Always imagePullPolicy: Always
resources: resources:
requests: requests:

View File

@ -1,4 +1,4 @@
FROM humanconnection/neo4j:latest FROM ocelotsocialnetwork/develop-neo4j:latest
ENV NODE_ENV=maintenance ENV NODE_ENV=maintenance
EXPOSE 7687 7474 EXPOSE 7687 7474

View File

@ -18,8 +18,8 @@ minikube dashboard, expose the services you want on your host system.
For example: For example:
```text ```text
$ minikube service nitro-web --namespace=human-connection $ minikube service develop-webapp --namespace=human-connection
# optionally # optionally
$ minikube service nitro-backend --namespace=human-connection $ minikube service develop-backend --namespace=human-connection
``` ```

View File

@ -3,7 +3,7 @@
At the moment, the application needs two persistent volumes: At the moment, the application needs two persistent volumes:
* The `/data/` folder where `neo4j` stores its database and * The `/data/` folder where `neo4j` stores its database and
* the folder `/nitro-backend/public/uploads` where the backend stores uploads. * the folder `/develop-backend/public/uploads` where the backend stores uploads.
As a matter of precaution, the persistent volume claims that setup these volumes As a matter of precaution, the persistent volume claims that setup these volumes
live in a separate folder. You don't want to accidently loose all your data in live in a separate folder. You don't want to accidently loose all your data in

View File

@ -29,13 +29,15 @@ database connections left and nobody can access the application.
Run the following: Run the following:
```sh ```sh
kubectl --namespace=human-connection edit deployment nitro-neo4j $ kubectl --namespace=human-connection edit deployment develop-neo4j
``` ```
Add the following to `spec.template.spec.containers`: Add the following to `spec.template.spec.containers`:
```
```sh
["tail", "-f", "/dev/null"] ["tail", "-f", "/dev/null"]
``` ```
and write the file which will update the deployment. and write the file which will update the deployment.
The command `tail -f /dev/null` is the equivalent of *sleep forever*. It is a The command `tail -f /dev/null` is the equivalent of *sleep forever*. It is a
@ -51,32 +53,36 @@ file and trigger an update of the deployment.
## Create a Backup in Kubernetes ## Create a Backup in Kubernetes
First stop your Neo4J database, see above. Then: First stop your Neo4J database, see above. Then:
```sh ```sh
kubectl --namespace=human-connection get pods $ kubectl --namespace=human-connection get pods
# Copy the ID of the pod running Neo4J. # Copy the ID of the pod running Neo4J.
kubectl --namespace=human-connection exec -it <POD-ID> bash $ kubectl --namespace=human-connection exec -it <POD-ID> bash
# Once you're in the pod, dump the db to a file e.g. `/root/neo4j-backup`. # Once you're in the pod, dump the db to a file e.g. `/root/neo4j-backup`.
neo4j-admin dump --to=/root/neo4j-backup > neo4j-admin dump --to=/root/neo4j-backup
exit > exit
# Download the file from the pod to your computer. # Download the file from the pod to your computer.
kubectl cp human-connection/<POD-ID>:/root/neo4j-backup ./neo4j-backup $ kubectl cp human-connection/<POD-ID>:/root/neo4j-backup ./neo4j-backup
``` ```
Revert your changes to deployment `nitro-neo4j` which will restart the database.
Revert your changes to deployment `develop-neo4j` which will restart the database.
## Restore a Backup in Kubernetes ## Restore a Backup in Kubernetes
First stop your Neo4J database. Then: First stop your Neo4J database. Then:
```sh ```sh
kubectl --namespace=human-connection get pods $ kubectl --namespace=human-connection get pods
# Copy the ID of the pod running Neo4J. # Copy the ID of the pod running Neo4J.
# Then upload your local backup to the pod. Note that once the pod gets deleted # Then upload your local backup to the pod. Note that once the pod gets deleted
# e.g. if you change the deployment, the backup file is gone with it. # e.g. if you change the deployment, the backup file is gone with it.
kubectl cp ./neo4j-backup human-connection/<POD-ID>:/root/ $ kubectl cp ./neo4j-backup human-connection/<POD-ID>:/root/
kubectl --namespace=human-connection exec -it <POD-ID> bash $ kubectl --namespace=human-connection exec -it <POD-ID> bash
# Once you're in the pod restore the backup and overwrite the default database # Once you're in the pod restore the backup and overwrite the default database
# called `graph.db` with `--force`. # called `graph.db` with `--force`.
# This will delete all existing data in database `graph.db`! # This will delete all existing data in database `graph.db`!
neo4j-admin load --from=/root/neo4j-backup --force > neo4j-admin load --from=/root/neo4j-backup --force
exit > exit
``` ```
Revert your changes to deployment `nitro-neo4j` which will restart the database.
Revert your changes to deployment `develop-neo4j` which will restart the database.

View File

@ -7,32 +7,33 @@ database in a kubernetes cluster.
One of the benefits of doing an online backup is that the Neo4j database does not need to be stopped, so there is no downtime. Read [the docs](https://neo4j.com/docs/operations-manual/current/backup/performing/) One of the benefits of doing an online backup is that the Neo4j database does not need to be stopped, so there is no downtime. Read [the docs](https://neo4j.com/docs/operations-manual/current/backup/performing/)
To use Neo4j Enterprise you must add this line to your configmap, if using, or your deployment `nitro-neo4j` env. To use Neo4j Enterprise you must add this line to your configmap, if using, or your deployment `develop-neo4j` env.
``` ```sh
NEO4J_ACCEPT_LICENSE_AGREEMENT: "yes" NEO4J_ACCEPT_LICENSE_AGREEMENT: "yes"
``` ```
## Create a Backup in Kubernetes ## Create a Backup in Kubernetes
```sh ```sh
# Backup the database with one command, this will get the nitro-neo4j pod, ssh into it, and run the backup command # Backup the database with one command, this will get the develop-neo4j pod, ssh into it, and run the backup command
kubectl -n=human-connection exec -it $(kubectl -n=human-connection get pods | grep nitro-neo4j | awk '{ print $1 }') -- neo4j-admin backup --backup-dir=/var/lib/neo4j --name=neo4j-backup $ kubectl -n=human-connection exec -it $(kubectl -n=human-connection get pods | grep develop-neo4j | awk '{ print $1 }') -- neo4j-admin backup --backup-dir=/var/lib/neo4j --name=neo4j-backup
# Download the file from the pod to your computer. # Download the file from the pod to your computer.
kubectl cp human-connection/$(kubectl -n=human-connection get pods | grep nitro-neo4j | awk '{ print $1 }'):/var/lib/neo4j/neo4j-backup ./neo4j-backup/ $ kubectl cp human-connection/$(kubectl -n=human-connection get pods | grep develop-neo4j | awk '{ print $1 }'):/var/lib/neo4j/neo4j-backup ./neo4j-backup/
``` ```
You should now have a backup of the database locally. If you want, you can simulate disaster recovery by sshing into the nitro-neo4j pod, deleting all data and restoring from backup You should now have a backup of the database locally. If you want, you can simulate disaster recovery by sshing into the develop-neo4j pod, deleting all data and restoring from backup
## Disaster where database data is gone somehow ## Disaster where database data is gone somehow
```sh ```sh
kubectl -n=human-connection exec -it $(kubectl -n=human-connection get pods | grep nitro-neo4j |awk '{ print $1 }') bash $ kubectl -n=human-connection exec -it $(kubectl -n=human-connection get pods | grep develop-neo4j |awk '{ print $1 }') bash
# Enter cypher-shell # Enter cypher-shell
cypher-shell $ cypher-shell
# Delete all data # Delete all data
> MATCH (n) DETACH DELETE (n); > MATCH (n) DETACH DELETE (n);
exit > exit
``` ```
## Restore a backup in Kubernetes ## Restore a backup in Kubernetes
@ -42,16 +43,17 @@ Restoration must be done while the database is not running, see [our docs](https
After, you have stopped the database, and have the pod running, you can restore the database by running these commands: After, you have stopped the database, and have the pod running, you can restore the database by running these commands:
```sh ```sh
kubectl --namespace=human-connection get pods $ kubectl --namespace=human-connection get pods
# Copy the ID of the pod running Neo4J. # Copy the ID of the pod running Neo4J.
# Then upload your local backup to the pod. Note that once the pod gets deleted # Then upload your local backup to the pod. Note that once the pod gets deleted
# e.g. if you change the deployment, the backup file is gone with it. # e.g. if you change the deployment, the backup file is gone with it.
kubectl cp ./neo4j-backup/ human-connection/<POD-ID>:/root/ $ kubectl cp ./neo4j-backup/ human-connection/<POD-ID>:/root/
kubectl --namespace=human-connection exec -it <POD-ID> bash $ kubectl --namespace=human-connection exec -it <POD-ID> bash
# Once you're in the pod restore the backup and overwrite the default database # Once you're in the pod restore the backup and overwrite the default database
# called `graph.db` with `--force`. # called `graph.db` with `--force`.
# This will delete all existing data in database `graph.db`! # This will delete all existing data in database `graph.db`!
neo4j-admin restore --from=/root/neo4j-backup --force > neo4j-admin restore --from=/root/neo4j-backup --force
exit > exit
``` ```
Revert your changes to deployment `nitro-neo4j` which will restart the database.
Revert your changes to deployment `develop-neo4j` which will restart the database.

View File

@ -54,19 +54,19 @@ $ velero backup create hc-backup --include-namespaces=human-connection
That should backup your persistent volumes, too. When you enter: That should backup your persistent volumes, too. When you enter:
``` ```sh
$ velero backup describe hc-backup --details $ velero backup describe hc-backup --details
``` ```
You should see the persistent volumes at the end of the log: You should see the persistent volumes at the end of the log:
``` ```sh
.... ....
Restic Backups: Restic Backups:
Completed: Completed:
human-connection/nitro-backend-5b6dd96d6b-q77n6: uploads human-connection/develop-backend-5b6dd96d6b-q77n6: uploads
human-connection/nitro-neo4j-686d768598-z2vhh: neo4j-data human-connection/develop-neo4j-686d768598-z2vhh: neo4j-data
``` ```
## Simulate a Disaster ## Simulate a Disaster

View File

@ -4,14 +4,14 @@ services:
webapp: webapp:
environment: environment:
- "CI=${CI}" - "CI=${CI}"
image: humanconnection/nitro-web:build-and-test image: ocelotsocialnetwork/develop-webapp:build-and-test
build: build:
context: webapp context: webapp
target: build-and-test target: build-and-test
backend: backend:
environment: environment:
- "CI=${CI}" - "CI=${CI}"
image: humanconnection/nitro-backend:build-and-test image: ocelotsocialnetwork/develop-backend:build-and-test
build: build:
context: backend context: backend
target: build-and-test target: build-and-test

View File

@ -2,7 +2,7 @@ version: "3.4"
services: services:
maintenance-worker: maintenance-worker:
image: humanconnection/maintenance-worker:latest image: ocelotsocialnetwork/develop-maintenance-worker:latest
build: build:
context: deployment/legacy-migration/maintenance-worker context: deployment/legacy-migration/maintenance-worker
volumes: volumes:

View File

@ -12,7 +12,7 @@ services:
context: webapp context: webapp
target: build-and-test target: build-and-test
volumes: volumes:
- ./webapp:/nitro-web - ./webapp:/develop-webapp
environment: environment:
- NUXT_BUILD=/tmp/nuxt # avoid file permission issues when `rm -rf .nuxt/` - NUXT_BUILD=/tmp/nuxt # avoid file permission issues when `rm -rf .nuxt/`
- PUBLIC_REGISTRATION=false - PUBLIC_REGISTRATION=false
@ -22,7 +22,7 @@ services:
context: backend context: backend
target: build-and-test target: build-and-test
volumes: volumes:
- ./backend:/nitro-backend - ./backend:/develop-backend
command: yarn run dev command: yarn run dev
environment: environment:
- SMTP_HOST=mailserver - SMTP_HOST=mailserver
@ -31,7 +31,7 @@ services:
- "DEBUG=${DEBUG}" - "DEBUG=${DEBUG}"
- PUBLIC_REGISTRATION=false - PUBLIC_REGISTRATION=false
maintenance: maintenance:
image: humanconnection/maintenance:latest image: ocelotsocialnetwork/develop-maintenance:latest
build: build:
context: webapp context: webapp
dockerfile: Dockerfile.maintenance dockerfile: Dockerfile.maintenance

View File

@ -2,7 +2,7 @@ version: "3.4"
services: services:
webapp: webapp:
image: humanconnection/nitro-web:latest image: ocelotsocialnetwork/develop-webapp:latest
build: build:
context: webapp context: webapp
target: production target: production
@ -16,13 +16,13 @@ services:
depends_on: depends_on:
- backend - backend
volumes: volumes:
- webapp_node_modules:/nitro-web/node_modules - webapp_node_modules:/develop-webapp/node_modules
environment: environment:
- HOST=0.0.0.0 - HOST=0.0.0.0
- GRAPHQL_URI=http://backend:4000 - GRAPHQL_URI=http://backend:4000
- MAPBOX_TOKEN="pk.eyJ1IjoiaHVtYW4tY29ubmVjdGlvbiIsImEiOiJjajl0cnBubGoweTVlM3VwZ2lzNTNud3ZtIn0.bZ8KK9l70omjXbEkkbHGsQ" - MAPBOX_TOKEN="pk.eyJ1IjoiaHVtYW4tY29ubmVjdGlvbiIsImEiOiJjajl0cnBubGoweTVlM3VwZ2lzNTNud3ZtIn0.bZ8KK9l70omjXbEkkbHGsQ"
backend: backend:
image: humanconnection/nitro-backend:latest image: ocelotsocialnetwork/develop-backend:latest
build: build:
context: backend context: backend
target: production target: production
@ -35,8 +35,8 @@ services:
ports: ports:
- 4000:4000 - 4000:4000
volumes: volumes:
- backend_node_modules:/nitro-backend/node_modules - backend_node_modules:/develop-backend/node_modules
- uploads:/nitro-backend/public/uploads - uploads:/develop-backend/public/uploads
environment: environment:
- NEO4J_URI=bolt://neo4j:7687 - NEO4J_URI=bolt://neo4j:7687
- GRAPHQL_URI=http://backend:4000 - GRAPHQL_URI=http://backend:4000
@ -46,7 +46,7 @@ services:
- PRIVATE_KEY_PASSPHRASE=a7dsf78sadg87ad87sfagsadg78 - PRIVATE_KEY_PASSPHRASE=a7dsf78sadg87ad87sfagsadg78
- "DEBUG=${DEBUG}" - "DEBUG=${DEBUG}"
neo4j: neo4j:
image: humanconnection/neo4j:latest image: ocelotsocialnetwork/develop-neo4j:latest
build: build:
context: neo4j context: neo4j
args: args:

View File

@ -1,4 +1,6 @@
FROM neo4j:3.5.14-enterprise FROM neo4j:3.5.14
# community edition 👆🏼, because we have no enterprise licence 👇🏼 at the moment
# FROM neo4j:3.5.14-enterprise
LABEL Description="Neo4J database of the Social Network Human-Connection.org with preinstalled database constraints and indices" Vendor="Human Connection gGmbH" Version="0.0.1" Maintainer="Human Connection gGmbH (developer@human-connection.org)" LABEL Description="Neo4J database of the Social Network Human-Connection.org with preinstalled database constraints and indices" Vendor="Human Connection gGmbH" Version="0.0.1" Maintainer="Human Connection gGmbH (developer@human-connection.org)"
ARG BUILD_COMMIT ARG BUILD_COMMIT

View File

@ -1,6 +1,6 @@
{ {
"name": "human-connection", "name": "human-connection",
"version": "0.6.1", "version": "0.6.3",
"description": "Fullstack and API tests with cypress and cucumber for Human Connection", "description": "Fullstack and API tests with cypress and cucumber for Human Connection",
"author": "Human Connection gGmbh", "author": "Human Connection gGmbh",
"license": "MIT", "license": "MIT",

View File

@ -4,26 +4,26 @@ ROOT_DIR=$(dirname "$0")/..
VERSION=$(jq -r '.version' $ROOT_DIR/package.json) VERSION=$(jq -r '.version' $ROOT_DIR/package.json)
IFS='.' read -r major minor patch <<< $VERSION IFS='.' read -r major minor patch <<< $VERSION
apps=(nitro-web nitro-backend neo4j maintenance) apps=(develop-webapp develop-backend develop-neo4j develop-maintenance)
tags=($major $major.$minor $major.$minor.$patch) tags=($major $major.$minor $major.$minor.$patch)
# These three docker images have already been built by now: # These three docker images have already been built by now:
# docker build --build-arg BUILD_COMMIT=$BUILD_COMMIT --target production -t humanconnection/nitro-backend:latest $ROOT_DIR/backend # docker build --build-arg BUILD_COMMIT=$BUILD_COMMIT --target production -t ocelotsocialnetwork/develop-backend:latest $ROOT_DIR/backend
# docker build --build-arg BUILD_COMMIT=$BUILD_COMMIT --target production -t humanconnection/nitro-web:latest $ROOT_DIR/webapp # docker build --build-arg BUILD_COMMIT=$BUILD_COMMIT --target production -t ocelotsocialnetwork/develop-webapp:latest $ROOT_DIR/webapp
# docker build --build-arg BUILD_COMMIT=$BUILD_COMMIT -t humanconnection/neo4j:latest $ROOT_DIR/neo4j # docker build --build-arg BUILD_COMMIT=$BUILD_COMMIT -t ocelotsocialnetwork/develop-neo4j:latest $ROOT_DIR/neo4j
docker build -t humanconnection/maintenance:latest $ROOT_DIR/webapp/ -f $ROOT_DIR/webapp/Dockerfile.maintenance docker build -t ocelotsocialnetwork/develop-maintenance:latest $ROOT_DIR/webapp/ -f $ROOT_DIR/webapp/Dockerfile.maintenance
echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_USERNAME" --password-stdin echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_USERNAME" --password-stdin
for app in "${apps[@]}" for app in "${apps[@]}"
do do
SOURCE="humanconnection/${app}:latest" SOURCE="ocelotsocialnetwork/${app}:latest"
echo "docker push $SOURCE" echo "docker push $SOURCE"
docker push $SOURCE docker push $SOURCE
for tag in "${tags[@]}" for tag in "${tags[@]}"
do do
TARGET="humanconnection/${app}:${tag}" TARGET="ocelotsocialnetwork/${app}:${tag}"
if DOCKER_CLI_EXPERIMENTAL=enabled docker manifest inspect $TARGET >/dev/null; then if DOCKER_CLI_EXPERIMENTAL=enabled docker manifest inspect $TARGET >/dev/null; then
echo "docker image ${TARGET} already present, skipping ..." echo "docker image ${TARGET} already present, skipping ..."
else else

View File

@ -1,4 +1,4 @@
FROM node:lts-alpine as base FROM node:12.19.0-alpine3.10 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)" 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 EXPOSE 3000
@ -7,7 +7,7 @@ CMD ["yarn", "run", "start"]
# Expose the app port # Expose the app port
ARG BUILD_COMMIT ARG BUILD_COMMIT
ENV BUILD_COMMIT=$BUILD_COMMIT ENV BUILD_COMMIT=$BUILD_COMMIT
ARG WORKDIR=/nitro-web ARG WORKDIR=/develop-webapp
RUN mkdir -p $WORKDIR RUN mkdir -p $WORKDIR
WORKDIR $WORKDIR WORKDIR $WORKDIR
@ -25,7 +25,7 @@ RUN NODE_ENV=production yarn run build
FROM base as production FROM base as production
RUN yarn install --production=true --frozen-lockfile --non-interactive --no-cache RUN yarn install --production=true --frozen-lockfile --non-interactive --no-cache
COPY --from=build-and-test ./nitro-web/.nuxt ./.nuxt COPY --from=build-and-test ./develop-webapp/.nuxt ./.nuxt
COPY --from=build-and-test ./nitro-web/static ./static COPY --from=build-and-test ./develop-webapp/static ./static
COPY nuxt.config.js . COPY nuxt.config.js .
COPY locales locales COPY locales locales

View File

@ -1,4 +1,4 @@
FROM node:lts-alpine as build FROM node:12.19.0-alpine3.10 as build
LABEL Description="Maintenance page of the Social Network Human-Connection.org" Vendor="Human-Connection gGmbH" Version="0.0.1" Maintainer="Human-Connection gGmbH (developer@human-connection.org)" LABEL Description="Maintenance page 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 EXPOSE 3000
@ -7,7 +7,7 @@ CMD ["yarn", "run", "start"]
# Expose the app port # Expose the app port
ARG BUILD_COMMIT ARG BUILD_COMMIT
ENV BUILD_COMMIT=$BUILD_COMMIT ENV BUILD_COMMIT=$BUILD_COMMIT
ARG WORKDIR=/nitro-web ARG WORKDIR=/develop-webapp
RUN mkdir -p $WORKDIR RUN mkdir -p $WORKDIR
WORKDIR $WORKDIR WORKDIR $WORKDIR
@ -35,6 +35,6 @@ RUN yarn run generate
FROM nginx:alpine FROM nginx:alpine
COPY --from=build ./nitro-web/dist/ /usr/share/nginx/html/ COPY --from=build ./develop-webapp/dist/ /usr/share/nginx/html/
RUN rm /etc/nginx/conf.d/default.conf RUN rm /etc/nginx/conf.d/default.conf
COPY maintenance/nginx/custom.conf /etc/nginx/conf.d/ COPY maintenance/nginx/custom.conf /etc/nginx/conf.d/

View File

@ -0,0 +1,5 @@
<!-- Generated by IcoMoon.io -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
<title>download</title>
<path d="M15 4h2v16.563l5.281-5.281 1.438 1.438-7 7-0.719 0.688-0.719-0.688-7-7 1.438-1.438 5.281 5.281v-16.563zM7 26h18v2h-18v-2z"></path>
</svg>

After

Width:  |  Height:  |  Size: 302 B

View File

@ -279,7 +279,7 @@ $size-avatar-large: 114px;
$size-image-max-height: 2000px; $size-image-max-height: 2000px;
$size-image-cropper-max-height: 600px; $size-image-cropper-max-height: 600px;
$size-image-cropper-min-height: 400px; $size-image-cropper-min-height: 400px;
$size-image-uploader-min-height: 200px; $size-image-uploader-min-height: 250px;
/** /**
* @tokens Size Icons * @tokens Size Icons

View File

@ -20,6 +20,9 @@
:title="$t('actions.delete')" :title="$t('actions.delete')"
@click.stop="deleteImage" @click.stop="deleteImage"
/> />
<div v-if="!hasImage" class="supported-formats">
{{ $t('contribution.teaserImage.supportedFormats') }}
</div>
</vue-dropzone> </vue-dropzone>
<div v-show="showCropper" class="crop-overlay"> <div v-show="showCropper" class="crop-overlay">
<img id="cropping-image" /> <img id="cropping-image" />
@ -195,6 +198,11 @@ export default {
right: $space-small; right: $space-small;
z-index: $z-index-surface; z-index: $z-index-surface;
} }
> .supported-formats {
margin-top: 150px;
font-weight: bold;
}
} }
} }
</style> </style>

View File

@ -328,3 +328,32 @@ export const currentUserCountQuery = () => gql`
} }
} }
` `
export const userDataQuery = (i18n) => {
return gql`
${userFragment}
${postFragment}
${commentFragment}
query($id: ID!) {
userData(id: $id) {
user {
...user
}
posts {
...post
categories {
id
name
}
comments {
author {
id
slug
}
...comment
}
}
}
}
`
}

View File

@ -258,7 +258,8 @@
"newPost": "Erstelle einen neuen Beitrag", "newPost": "Erstelle einen neuen Beitrag",
"success": "Gespeichert!", "success": "Gespeichert!",
"teaserImage": { "teaserImage": {
"cropperConfirm": "Bestätigen" "cropperConfirm": "Bestätigen",
"supportedFormats": "Füge ein Bild im Dateiformat JPG, PNG oder GIF ein"
}, },
"title": "Titel" "title": "Titel"
}, },
@ -649,6 +650,8 @@
"success": "Konto erfolgreich gelöscht!" "success": "Konto erfolgreich gelöscht!"
}, },
"download": { "download": {
"description": "Klicke auf den Knopf oben, um den Inhalt deiner Beiträge und Kommentare herunterzuladen. Um die Bilder der Beiträge herunterzuladen, musst du auf den jeweiligen Link unten klicken.",
"json": "als JSON",
"name": "Daten herunterladen" "name": "Daten herunterladen"
}, },
"email": { "email": {

View File

@ -258,7 +258,8 @@
"newPost": "Create a new Post", "newPost": "Create a new Post",
"success": "Saved!", "success": "Saved!",
"teaserImage": { "teaserImage": {
"cropperConfirm": "Confirm" "cropperConfirm": "Confirm",
"supportedFormats": "Insert a picture of file format JPG , PNG or GIF"
}, },
"title": "Title" "title": "Title"
}, },
@ -649,6 +650,8 @@
"success": "Account successfully deleted!" "success": "Account successfully deleted!"
}, },
"download": { "download": {
"description": "Click on the button above to download the content of your posts and comments. To download the images of your posts, you have to click on the corresponding link below.",
"json": "as JSON",
"name": "Download Data" "name": "Download Data"
}, },
"email": { "email": {

View File

@ -256,7 +256,8 @@
"newPost": "Crear una nueva contribución", "newPost": "Crear una nueva contribución",
"success": "¡Guardado!", "success": "¡Guardado!",
"teaserImage": { "teaserImage": {
"cropperConfirm": "Confirmar" "cropperConfirm": "Confirmar",
"supportedFormats": "Insertar una imagen de formato de archivo JPG, PNG o GIF"
}, },
"title": "Título" "title": "Título"
}, },

View File

@ -256,7 +256,8 @@
"newPost": "Créer un nouveau Post", "newPost": "Créer un nouveau Post",
"success": "Enregistré!", "success": "Enregistré!",
"teaserImage": { "teaserImage": {
"cropperConfirm": "Confirmer" "cropperConfirm": "Confirmer",
"supportedFormats": "Insérer une image au format de fichier JPG, PNG ou GIF"
}, },
"title": "Titre" "title": "Titre"
}, },

View File

@ -261,7 +261,8 @@
"newPost": "", "newPost": "",
"success": "", "success": "",
"teaserImage": { "teaserImage": {
"cropperConfirm": "Confermare" "cropperConfirm": "Confermare",
"supportedFormats": "Inserisci un'immagine in formato file JPG, PNG o GIF"
}, },
"title": "" "title": ""
}, },

View File

@ -68,7 +68,8 @@
"delete": "Bijdrage verwijderen", "delete": "Bijdrage verwijderen",
"edit": "Bijdrage bewerken", "edit": "Bijdrage bewerken",
"teaserImage": { "teaserImage": {
"cropperConfirm": "Bevestigen" "cropperConfirm": "Bevestigen",
"supportedFormats": "Voeg een afbeelding in met het bestandsformaat JPG, PNG of GIF"
} }
}, },
"disable": { "disable": {

View File

@ -119,7 +119,8 @@
"newPost": "Utwórz nowy wpis", "newPost": "Utwórz nowy wpis",
"success": "Zapisano!", "success": "Zapisano!",
"teaserImage": { "teaserImage": {
"cropperConfirm": "Potwierdzać" "cropperConfirm": "Potwierdzać",
"supportedFormats": "Wstaw zdjęcie w formacie pliku JPG, PNG lub GIF"
} }
}, },
"delete": { "delete": {

View File

@ -252,7 +252,8 @@
"newPost": "Criar uma nova publicação", "newPost": "Criar uma nova publicação",
"success": "Salvo!", "success": "Salvo!",
"teaserImage": { "teaserImage": {
"cropperConfirm": "Confirmar" "cropperConfirm": "Confirmar",
"supportedFormats": "Insira uma imagem do formato JPG, PNG ou GIF"
}, },
"title": "Título" "title": "Título"
}, },

View File

@ -256,7 +256,8 @@
"newPost": "Создать пост", "newPost": "Создать пост",
"success": "Сохранено!", "success": "Сохранено!",
"teaserImage": { "teaserImage": {
"cropperConfirm": "Подтвердить" "cropperConfirm": "Подтвердить",
"supportedFormats": "Вставьте изображение файла формата JPG, PNG или GIF"
}, },
"title": "Заголовок" "title": "Заголовок"
}, },

View File

@ -1,6 +1,6 @@
{ {
"name": "human-connection-webapp", "name": "human-connection-webapp",
"version": "0.6.1", "version": "0.6.3",
"description": "Human Connection Frontend", "description": "Human Connection Frontend",
"authors": [ "authors": [
"Grzegorz Leoniec (appinteractive)", "Grzegorz Leoniec (appinteractive)",

View File

@ -51,32 +51,30 @@ export default {
name: this.$t('settings.embeds.name'), name: this.$t('settings.embeds.name'),
path: `/settings/embeds`, path: `/settings/embeds`,
}, },
{
name: this.$t('settings.download.name'),
path: `/settings/data-download`,
},
{ {
name: this.$t('settings.deleteUserAccount.name'), name: this.$t('settings.deleteUserAccount.name'),
path: `/settings/delete-account`, path: `/settings/delete-account`,
}, },
// TODO implement // TODO implement
/* { /* {
name: this.$t('settings.invites.name'), name: this.$t('settings.invites.name'),
path: `/settings/invites` path: `/settings/invites`
}, */ }, */
// TODO implement // TODO implement
/* { /* {
name: this.$t('settings.download.name'), name: this.$t('settings.organizations.name'),
path: `/settings/data-download` path: `/settings/my-organizations`
}, */ }, */
// TODO implement
// TODO implement // TODO implement
/* { /* {
name: this.$t('settings.organizations.name'), name: this.$t('settings.languages.name'),
path: `/settings/my-organizations` path: `/settings/languages`
}, */ },
// TODO implement } */
/* {
name: this.$t('settings.languages.name'),
path: `/settings/languages`
},
} */
] ]
}, },
}, },

View File

@ -1,16 +1,87 @@
<template> <template>
<base-card> <base-card>
<h2 class="title">{{ $t('settings.download.name') }}</h2> <h2 class="title">{{ $t('settings.download.name') }}</h2>
<hc-empty icon="tasks" message="Coming Soon…" /> <base-button
@click="onClick(jsonData)"
icon="download"
secondary
filled
:disabled="loading"
:loading="loading"
>
{{ $t('settings.download.json') }}
</base-button>
<ds-space margin="large" />
<ds-text>{{ $t('settings.download.description') }}</ds-text>
<ds-space margin="large" />
<base-card v-for="image in imageList" :key="image.key">
<a :href="image.url" target="_blank" rel="noopener noreferrer">{{ image.title }}</a>
<ds-space margin="xxx-small" />
</base-card>
</base-card> </base-card>
</template> </template>
<script> <script>
import HcEmpty from '~/components/Empty/Empty' import { mapGetters } from 'vuex'
import { userDataQuery } from '~/graphql/User'
import BaseButton from '~/components/_new/generic/BaseButton/BaseButton.vue'
import isEmpty from 'lodash/isEmpty'
export default { export default {
components: { components: {
HcEmpty, BaseButton,
},
data() {
return {
userData: {},
loading: true,
imageList: [],
}
},
computed: {
...mapGetters({
user: 'auth/user',
}),
jsonData() {
return { data: JSON.stringify(this.userData, null, 2), type: 'json' }
},
},
methods: {
onClick(method) {
var fileURL = window.URL.createObjectURL(new Blob([method.data]))
var fileLink = document.createElement('a')
fileLink.href = fileURL
fileLink.setAttribute('download', 'userData.' + method.type)
document.body.appendChild(fileLink)
fileLink.click()
},
},
apollo: {
queryUserData: {
query() {
return userDataQuery()
},
variables() {
return { id: this.user.id }
},
update({ userData }) {
this.userData = userData
this.loading = false
if (isEmpty(this.userData)) return null
const userId = this.userData.user.id
if (isEmpty(userId)) return null
this.imageList = this.userData.posts
.filter((post) => post.author.id === userId && post.image)
.map((post) => {
const obj = {}
obj.key = post.id
obj.url = post.image.url
obj.title = post.title
return obj
})
},
fetchPolicy: 'cache-and-network',
},
}, },
} }
</script> </script>