diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 4452f2286..18ff7a379 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -300,77 +300,10 @@ jobs: repository: ${{ github.repository }} client-payload: '{"ref": "${{ github.ref }}", "sha": "${{ github.sha }}", "VERSION": "${VERSION}", "BUILD_DATE": "${BUILD_DATE}", "BUILD_COMMIT": "${BUILD_COMMIT}", "BUILD_VERSION": "${BUILD_VERSION}"}' - # ############################################################################## - # # JOB: KUBERNETES DEPLOY ACTUAL/LATEST VERSION ###################################### - # ############################################################################## - # kubernetes_deploy: - # # see example https://github.com/do-community/example-doctl-action - # # see example https://github.com/do-community/example-doctl-action/blob/main/.github/workflows/workflow.yaml - # name: Kubernetes deploy of latest version to stage.ocelot.social cluster at DigitalOcean - # runs-on: ubuntu-latest - # needs: [upload_to_dockerhub] - # steps: - # ########################################################################## - # # CHECKOUT CODE ########################################################## - # ########################################################################## - # - name: Checkout code - # uses: actions/checkout@v3 - # ########################################################################## - # # SET ENVS ############################################################### - # ########################################################################## - # - name: ENV - VERSION - # run: echo "VERSION=$(node -p -e "require('./package.json').version")" >> $GITHUB_ENV - # - name: ENV - BUILD_VERSION - # run: echo "BUILD_VERSION=${VERSION}-${GITHUB_RUN_NUMBER}" >> $GITHUB_ENV - # ########################################################################## - # # Install DigitalOceans doctl and set kubeconfig ######################### - # ########################################################################## - # - name: Install doctl - # uses: digitalocean/action-doctl@v2 - # with: - # token: ${{ secrets.DIGITALOCEAN_ACCESS_TOKEN }} - # - name: Save DigitalOcean kubeconfig with short-lived credentials - # run: doctl kubernetes cluster kubeconfig save --expiry-seconds 600 cluster-stage-ocelot-social - # ########################################################################## - # # Deploy new Docker images to DigitalOcean Kubernetes cluster ############ - # ########################################################################## - # # - name: Deploy 'latest' to DigitalOcean Kubernetes - # # run: | - # # kubectl -n default set image deployment/ocelot-webapp container-ocelot-webapp=ocelotsocialnetwork/webapp:latest - # # kubectl -n default rollout restart deployment/ocelot-webapp - # # kubectl -n default set image deployment/ocelot-backend container-ocelot-backend=ocelotsocialnetwork/backend:latest - # # kubectl -n default rollout restart deployment/ocelot-backend - # # kubectl -n default set image deployment/ocelot-maintenance container-ocelot-maintenance=ocelotsocialnetwork/maintenance:latest - # # kubectl -n default rollout restart deployment/ocelot-maintenance - # # kubectl -n default set image deployment/ocelot-neo4j container-ocelot-neo4j=ocelotsocialnetwork/neo4j-community:latest - # # kubectl -n default rollout restart deployment/ocelot-neo4j - # - name: Deploy actual version '$BUILD_VERSION' to DigitalOcean Kubernetes - # run: | - # kubectl -n default set image deployment/ocelot-webapp container-ocelot-webapp=ocelotsocialnetwork/webapp:$BUILD_VERSION - # kubectl -n default rollout restart deployment/ocelot-webapp - # kubectl -n default set image deployment/ocelot-backend container-ocelot-backend=ocelotsocialnetwork/backend:$BUILD_VERSION - # kubectl -n default rollout restart deployment/ocelot-backend - # kubectl -n default set image deployment/ocelot-maintenance container-ocelot-maintenance=ocelotsocialnetwork/maintenance:$BUILD_VERSION - # kubectl -n default rollout restart deployment/ocelot-maintenance - # kubectl -n default set image deployment/ocelot-neo4j container-ocelot-neo4j=ocelotsocialnetwork/neo4j-community:$BUILD_VERSION - # kubectl -n default rollout restart deployment/ocelot-neo4j - # # because this step 'kubectl -n default rollout status deployment/* --timeout=600s' does not work as expected - # # and we need the pods to be up again for cleaning and seeding the Neo4j database and the backend. - # # !!! this is not a perfect solution !!! - # # deployments are regularly up again after 3 minutes and 10 seconds - # - name: Sleep for 4 minutes, means 240 seconds - # run: sleep 240s - # shell: bash - # - name: Verify deployment and wait for the pods of each deployment to get ready for cleaning and seeding of the database - # run: | - # kubectl -n default rollout status deployment/ocelot-backend --timeout=600s - # kubectl -n default rollout status deployment/ocelot-neo4j --timeout=600s - # kubectl -n default rollout status deployment/ocelot-maintenance --timeout=600s - # kubectl -n default rollout status deployment/ocelot-webapp --timeout=600s - # - name: Run migrations for Neo4j database via backend for staging - # run: | - # kubectl -n default exec -it $(kubectl -n default get pods | grep ocelot-backend | awk '{ print $1 }') -- /bin/sh -c "yarn prod:migrate up" - # - name: Reset and seed Neo4j database via backend for staging - # # db cleaning and seeding is only possible in production if env 'PRODUCTION_DB_CLEAN_ALLOW=true' is set in deployment - # run: | - # kubectl -n default exec -it $(kubectl -n default get pods | grep ocelot-backend | awk '{ print $1 }') -- /bin/sh -c "node --experimental-repl-await dist/db/clean.js && node --experimental-repl-await dist/db/seed.js" \ No newline at end of file + - name: Repository Dispatch stage.ocelot.social + uses: peter-evans/repository-dispatch@v2 + with: + token: ${{ secrets.OCELOT_PUBLISH_EVENT_PAT }} # this token is required to access the other repository + event-type: trigger-build-success + repository: 'Ocelot-Social-Community/stage.ocelot.social' + client-payload: '{"ref": "${{ github.ref }}", "sha": "${{ github.sha }}", "VERSION": "${VERSION}", "BUILD_DATE": "${BUILD_DATE}", "BUILD_COMMIT": "${BUILD_COMMIT}", "BUILD_VERSION": "${BUILD_VERSION}"}' \ No newline at end of file diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 46d80241f..1740c09fe 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -329,19 +329,16 @@ jobs: - name: backend | docker-compose run: docker-compose -f docker-compose.yml -f docker-compose.test.yml up --detach --no-deps webapp neo4j backend - name: cypress | Fullstack tests + id: e2e-tests run: | yarn install yarn run cypress:run --spec $(cypress/parallel-features.sh ${{ matrix.job }} ${{ env.jobs }} ) ########################################################################## - # UPLOAD SCREENSHOTS & VIDEO ############################################# + # UPLOAD SCREENSHOTS - IF TESTS FAIL ##################################### ########################################################################## - - name: Upload Artifact + - name: Full stack tests | if any test failed, upload screenshots + if: ${{ failure() && steps.e2e-tests.conclusion == 'failure' }} uses: actions/upload-artifact@v3 with: name: cypress-screenshots path: cypress/screenshots/ - - name: Upload Artifact - uses: actions/upload-artifact@v3 - with: - name: cypress-videos - path: cypress/videos/ diff --git a/README.md b/README.md index 8ddf97fe5..06e8d4929 100644 --- a/README.md +++ b/README.md @@ -197,7 +197,8 @@ Prepare database once before you start by running the following command in a sec ```bash # in main folder while docker-compose is up -$ docker-compose exec backend yarn run db:migrate init +$ docker compose exec backend yarn run db:migrate init +$ docker compose exec backend yarn run db:migrate up ``` Then clear and seed database by running the following command as well in the second terminal: diff --git a/backend/README.md b/backend/README.md index 03724ce54..98b0e7218 100644 --- a/backend/README.md +++ b/backend/README.md @@ -81,8 +81,7 @@ More details about our GraphQL playground and how to use it with ocelot.social c ### Database Indexes and Constraints -Database indexes and constraints need to be created when the database and the -backend is running: +Database indexes and constraints need to be created and upgraded when the database and the backend are running: {% tabs %} {% tab title="Docker" %} @@ -98,6 +97,11 @@ $ docker compose exec backend yarn prod:migrate init $ docker compose exec backend /bin/sh -c "yarn prod:migrate init" ``` +```bash +# in main folder with docker compose running +$ docker exec backend yarn run db:migrate up +``` + {% endtab %} {% tab title="Without Docker" %} @@ -107,6 +111,11 @@ $ docker compose exec backend /bin/sh -c "yarn prod:migrate init" yarn run db:migrate init ``` +```bash +# in backend/ with database running (In docker or local) +yarn run db:migrate up +``` + {% endtab %} {% endtabs %} @@ -134,6 +143,8 @@ $ docker exec backend yarn run db:reset $ docker-compose down -v # if container is not running, run this command to set up your database indexes and constraints $ docker exec backend yarn run db:migrate init +# And then upgrade the indexes and const +$ docker exec backend yarn run db:migrate up ``` {% endtab %} diff --git a/backend/src/db/factories.js b/backend/src/db/factories.js index ecc792736..44af5bbea 100644 --- a/backend/src/db/factories.js +++ b/backend/src/db/factories.js @@ -23,6 +23,7 @@ export const cleanDatabase = async (options = {}) => { return transaction.run( ` MATCH (everything) + WHERE NOT 'Migration' IN labels(everything) DETACH DELETE everything `, ) diff --git a/backend/src/schema/resolvers/groups.js b/backend/src/schema/resolvers/groups.js index 4a13dcc88..5ec1700b9 100644 --- a/backend/src/schema/resolvers/groups.js +++ b/backend/src/schema/resolvers/groups.js @@ -16,6 +16,7 @@ export default { Group: async (_object, params, context, _resolveInfo) => { const { isMember, id, slug, first, offset } = params let pagination = '' + const orderBy = 'ORDER BY group.createdAt DESC' if (first !== undefined && offset !== undefined) pagination = `SKIP ${offset} LIMIT ${first}` const matchParams = { id, slug } removeUndefinedNullValuesFromObject(matchParams) @@ -29,6 +30,7 @@ export default { WITH group, membership WHERE (group.groupType IN ['public', 'closed']) OR (group.groupType = 'hidden' AND membership.role IN ['usual', 'admin', 'owner']) RETURN group {.*, myRole: membership.role} + ${orderBy} ${pagination} ` } else { @@ -39,6 +41,7 @@ export default { WITH group WHERE group.groupType IN ['public', 'closed'] RETURN group {.*, myRole: NULL} + ${orderBy} ${pagination} ` } else { @@ -48,6 +51,7 @@ export default { WITH group, membership WHERE (group.groupType IN ['public', 'closed']) OR (group.groupType = 'hidden' AND membership.role IN ['usual', 'admin', 'owner']) RETURN group {.*, myRole: membership.role} + ${orderBy} ${pagination} ` } diff --git a/cypress/cypress.json b/cypress/cypress.json index dbe8691fa..de323f736 100644 --- a/cypress/cypress.json +++ b/cypress/cypress.json @@ -4,6 +4,7 @@ "ignoreTestFiles": "*.js", "chromeWebSecurity": false, "baseUrl": "http://localhost:3000", + "video":false, "retries": { "runMode": 2, "openMode": 0 diff --git a/deployment/DOCKER_MORE_CLOSELY.md b/deployment/DOCKER_MORE_CLOSELY.md new file mode 100644 index 000000000..67488fe81 --- /dev/null +++ b/deployment/DOCKER_MORE_CLOSELY.md @@ -0,0 +1,33 @@ +# Docker + +## Apple M1 Platform + +***Attention:** For using Docker commands in Apple M1 environments!* + +```bash +# set env variable for your shell +$ export DOCKER_DEFAULT_PLATFORM=linux/amd64 +``` + +For even more informations, see [Docker More Closely](#docker-more-closely) + +### Docker Compose Override File For Apple M1 Platform + +For Docker compose `up` or `build` commands, you can use our Apple M1 override file that specifies the M1 platform: + +```bash +# in main folder + +# for production +$ docker compose -f docker-compose.yml -f docker-compose.apple-m1.override.yml up + +# for production testing Docker images from DockerHub +$ docker compose -f docker-compose.ocelotsocial-branded.yml -f docker-compose.apple-m1.override.yml up + +# only once: init admin user and create indexes and constraints in Neo4j database +$ docker compose exec backend /bin/sh -c "yarn prod:migrate init" +``` + +## Docker More Closely In Main Code + +To get more informations about the Apple M1 platform and to analyze the Docker builds etc. you find our documentation in our main code, [here](https://github.com/Ocelot-Social-Community/Ocelot-Social/blob/master/DOCKER_MORE_CLOSELY.md). diff --git a/deployment/src/kubernetes/dns.values.template.yaml b/deployment/configurations/example/kubernetes/dns.values.template.yaml similarity index 100% rename from deployment/src/kubernetes/dns.values.template.yaml rename to deployment/configurations/example/kubernetes/dns.values.template.yaml diff --git a/deployment/scripts/cluster.reseed.sh b/deployment/scripts/cluster.reseed.sh new file mode 100755 index 000000000..705e1880a --- /dev/null +++ b/deployment/scripts/cluster.reseed.sh @@ -0,0 +1,12 @@ +#!/bin/bash + +# base setup +SCRIPT_PATH=$(realpath $0) +SCRIPT_DIR=$(dirname $SCRIPT_PATH) + +# configuration +CONFIGURATION=${CONFIGURATION:-"example"} +KUBECONFIG=${KUBECONFIG:-${SCRIPT_DIR}/../configurations/${CONFIGURATION}/kubeconfig.yaml} + +# clean & seed +kubectl --kubeconfig=${KUBECONFIG} -n default exec -it $(kubectl --kubeconfig=${KUBECONFIG} -n default get pods | grep ocelot-backend | awk '{ print $1 }') -- /bin/sh -c "node --experimental-repl-await dist/db/clean.js && node --experimental-repl-await dist/db/seed.js" \ No newline at end of file diff --git a/deployment/scripts/cluster.upgrade.sh b/deployment/scripts/cluster.upgrade.sh index 2502a778a..1aec2cf18 100755 --- a/deployment/scripts/cluster.upgrade.sh +++ b/deployment/scripts/cluster.upgrade.sh @@ -7,7 +7,13 @@ SCRIPT_DIR=$(dirname $SCRIPT_PATH) # configuration CONFIGURATION=${CONFIGURATION:-"example"} KUBECONFIG=${KUBECONFIG:-${SCRIPT_DIR}/../configurations/${CONFIGURATION}/kubeconfig.yaml} -VALUES=${SCRIPT_DIR}/../configurations/${CONFIGURATION}/kubernetes/values.yaml +VALUES=${SCRIPT_DIR}/../configurations/${CONFIGURATION}/kubernetes/values. +DOCKERHUB_OCELOT_TAG=${DOCKERHUB_OCELOT_TAG:-"latest"} # upgrade with helm -helm --kubeconfig=${KUBECONFIG} upgrade ocelot --values ${VALUES} ${SCRIPT_DIR}/../src/kubernetes/ --debug --timeout 10m \ No newline at end of file +helm --kubeconfig=${KUBECONFIG} upgrade ocelot \ + --values ${VALUES} \ + --set appVersion="${DOCKERHUB_OCELOT_TAG}" + ${SCRIPT_DIR}/../src/kubernetes/ \ + --debug \ + --timeout 10m \ No newline at end of file diff --git a/deployment/scripts/secret.generate.sh b/deployment/scripts/secret.generate.sh new file mode 100755 index 000000000..dba958c34 --- /dev/null +++ b/deployment/scripts/secret.generate.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +# generate a secret and store it in the SECRET file. +# Note that this overwrites the existing file + +# base setup +SCRIPT_PATH=$(realpath $0) +SCRIPT_DIR=$(dirname $SCRIPT_PATH) + +# configuration +CONFIGURATION=${CONFIGURATION:-"example"} +SECRET_FILE=${SCRIPT_DIR}/../configurations/${CONFIGURATION}/SECRET + +openssl rand -base64 32 > ${SECRET_FILE} \ No newline at end of file diff --git a/deployment/scripts/secrets.decrypt.sh b/deployment/scripts/secrets.decrypt.sh new file mode 100755 index 000000000..283768ad0 --- /dev/null +++ b/deployment/scripts/secrets.decrypt.sh @@ -0,0 +1,44 @@ +#!/bin/bash + +# decrypt secrets in the selected configuration +# Note that existing decrypted files will be overwritten + +# base setup +SCRIPT_PATH=$(realpath $0) +SCRIPT_DIR=$(dirname $SCRIPT_PATH) + +# configuration +CONFIGURATION=${CONFIGURATION:-"example"} +SECRET=${SECRET} +SECRET_FILE=${SCRIPT_DIR}/../configurations/${CONFIGURATION}/SECRET +FILES=(\ + "${SCRIPT_DIR}/../configurations/${CONFIGURATION}/.env" \ + "${SCRIPT_DIR}/../configurations/${CONFIGURATION}/kubeconfig.yaml" \ + "${SCRIPT_DIR}/../configurations/${CONFIGURATION}/kubernetes/values.yaml" \ + "${SCRIPT_DIR}/../configurations/${CONFIGURATION}/kubernetes/dns.values.yaml" \ + ) + +# Load SECRET from file if it is not set explicitly +if [ -z ${SECRET} ] && [ -f "${SECRET_FILE}" ]; then + SECRET=$(<${SECRET_FILE}) +fi + +# exit when there is no SECRET set +if [ -z ${SECRET} ]; then + echo "No SECRET provided and no SECRET-File found." + exit 1 +fi + +# decrypt +for file in "${FILES[@]}" +do + if [ -f "${file}.enc" ]; then + #gpg --symmetric --batch --passphrase="${SECRET}" --cipher-algo AES256 --output ${file}.enc ${file} + gpg --quiet --batch --yes --decrypt --passphrase="${SECRET}" --output ${file} ${file}.enc + echo "Decrypted ${file}" + fi +done + +echo "DONE" +# gpg --quiet --batch --yes --decrypt --passphrase="${SECRET}" \ +# --output $HOME/secrets/my_secret.json my_secret.json.gpg diff --git a/deployment/scripts/secrets.encrypt.sh b/deployment/scripts/secrets.encrypt.sh new file mode 100755 index 000000000..ef6c87e85 --- /dev/null +++ b/deployment/scripts/secrets.encrypt.sh @@ -0,0 +1,41 @@ +#!/bin/bash + +# encrypt secrets in the selected configuration +# Note that existing encrypted files will be overwritten + +# base setup +SCRIPT_PATH=$(realpath $0) +SCRIPT_DIR=$(dirname $SCRIPT_PATH) + +# configuration +CONFIGURATION=${CONFIGURATION:-"example"} +SECRET=${SECRET} +SECRET_FILE=${SCRIPT_DIR}/../configurations/${CONFIGURATION}/SECRET +FILES=(\ + "${SCRIPT_DIR}/../configurations/${CONFIGURATION}/.env" \ + "${SCRIPT_DIR}/../configurations/${CONFIGURATION}/kubeconfig.yaml" \ + "${SCRIPT_DIR}/../configurations/${CONFIGURATION}/kubernetes/values.yaml" \ + "${SCRIPT_DIR}/../configurations/${CONFIGURATION}/kubernetes/dns.values.yaml" \ + ) + +# Load SECRET from file if it is not set explicitly +if [ -z ${SECRET} ] && [ -f "${SECRET_FILE}" ]; then + SECRET=$(<${SECRET_FILE}) +fi + +# exit when there is no SECRET set +if [ -z ${SECRET} ]; then + echo "No SECRET provided and no SECRET-File found." + exit 1 +fi + +# encrypt +for file in "${FILES[@]}" +do + if [ -f "${file}" ]; then + gpg --symmetric --batch --yes --passphrase="${SECRET}" --cipher-algo AES256 --output ${file}.enc ${file} + echo "Encrypted ${file}" + fi +done + +echo "DONE" diff --git a/deployment/src/kubernetes/.gitignore b/deployment/src/kubernetes/.gitignore deleted file mode 100644 index e0473b0fd..000000000 --- a/deployment/src/kubernetes/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -/dns.values.yaml -/nginx.values.yaml -/values.yaml diff --git a/deployment/src/kubernetes/nginx.values.template.yaml b/deployment/src/kubernetes/nginx.values.yaml similarity index 100% rename from deployment/src/kubernetes/nginx.values.template.yaml rename to deployment/src/kubernetes/nginx.values.yaml diff --git a/neo4j/README.md b/neo4j/README.md index df3b5fde6..1ea625d89 100644 --- a/neo4j/README.md +++ b/neo4j/README.md @@ -44,7 +44,7 @@ for development, spin up a [hosted Neo4j Sandbox instance](https://neo4j.com/download/), run Neo4j in one of the [many cloud options](https://neo4j.com/developer/guide-cloud-deployment/), [spin up Neo4j in a Docker container](https://neo4j.com/developer/docker/), -on Archlinux you can install [neo4j-community from AUR](https://aur.archlinux.org/packages/neo4j-community/) +on Arch linux you can install [neo4j-community from AUR](https://aur.archlinux.org/packages/neo4j-community/) or on Debian-based systems install [Neo4j from the Debian Repository](http://debian.neo4j.org/). Just be sure to update the Neo4j connection string and credentials accordingly in `backend/.env`. diff --git a/webapp/components/Button/JoinLeaveButton.vue b/webapp/components/Button/JoinLeaveButton.vue index 9bcb5042a..152039eb0 100644 --- a/webapp/components/Button/JoinLeaveButton.vue +++ b/webapp/components/Button/JoinLeaveButton.vue @@ -6,6 +6,7 @@ :icon="icon" :filled="isMember && !hovered" :danger="isMember && hovered" + v-tooltip="tooltip" @mouseenter.native="onHover" @mouseleave.native="hovered = false" @click.prevent="toggle" @@ -24,6 +25,7 @@ export default { group: { type: Object, required: true }, userId: { type: String, required: true }, isMember: { type: Boolean, required: true }, + isNonePendingMember: { type: Boolean, required: true }, disabled: { type: Boolean, default: false }, loading: { type: Boolean, default: false }, }, @@ -35,17 +37,33 @@ export default { }, computed: { icon() { - if (this.isMember && this.hovered) { - return 'close' - } else { - return this.isMember ? 'check' : 'plus' + if (this.isMember) { + if (this.isNonePendingMember) { + return this.hovered ? 'close' : 'check' + } else { + return this.hovered ? 'close' : 'question-circle' + } } + return 'plus' }, label() { if (this.isMember) { - return this.$t('group.joinLeaveButton.iAmMember') - } else { - return this.$t('group.joinLeaveButton.join') + if (this.isNonePendingMember) { + return this.hovered + ? this.$t('group.joinLeaveButton.leave') + : this.$t('group.joinLeaveButton.iAmMember') + } else { + return this.$t('group.joinLeaveButton.pendingMember') + } + } + return this.$t('group.joinLeaveButton.join') + }, + tooltip() { + return { + content: this.$t('group.joinLeaveButton.tooltip'), + placement: 'right', + show: this.isMember && !this.isNonePendingMember && this.hovered, + trigger: this.isMember && !this.isNonePendingMember ? 'hover' : 'manual', } }, }, diff --git a/webapp/components/Category/index.vue b/webapp/components/Category/index.vue index 8e4014086..ebbaae584 100644 --- a/webapp/components/Category/index.vue +++ b/webapp/components/Category/index.vue @@ -30,6 +30,7 @@ export default { } } .filterActive { - background-color: $color-success-active; + color: $color-primary-inverse; + background-color: $color-primary-active; } diff --git a/webapp/components/FilterMenu/HeaderButton.vue b/webapp/components/FilterMenu/HeaderButton.vue new file mode 100644 index 000000000..780e29ade --- /dev/null +++ b/webapp/components/FilterMenu/HeaderButton.vue @@ -0,0 +1,57 @@ + + + diff --git a/webapp/components/Group/GroupList.vue b/webapp/components/Group/GroupList.vue index 7618e5b57..dbde61ac6 100644 --- a/webapp/components/Group/GroupList.vue +++ b/webapp/components/Group/GroupList.vue @@ -1,9 +1,14 @@ + diff --git a/webapp/components/NotificationsTable/NotificationsTable.spec.js b/webapp/components/NotificationsTable/NotificationsTable.spec.js index e48610034..0d3560787 100644 --- a/webapp/components/NotificationsTable/NotificationsTable.spec.js +++ b/webapp/components/NotificationsTable/NotificationsTable.spec.js @@ -59,8 +59,8 @@ describe('NotificationsTable.vue', () => { wrapper = Wrapper() }) - it('renders a table', () => { - expect(wrapper.find('.ds-table').exists()).toBe(true) + it('renders a grid table', () => { + expect(wrapper.find('.notification-grid').exists()).toBe(true) }) describe('renders 4 columns', () => { @@ -84,7 +84,7 @@ describe('NotificationsTable.vue', () => { describe('Post', () => { let firstRowNotification beforeEach(() => { - firstRowNotification = wrapper.findAll('tbody tr').at(0) + firstRowNotification = wrapper.findAll('.notification-grid-row').at(0) }) it('renders the author', () => { @@ -117,7 +117,7 @@ describe('NotificationsTable.vue', () => { describe('Comment', () => { let secondRowNotification beforeEach(() => { - secondRowNotification = wrapper.findAll('tbody tr').at(1) + secondRowNotification = wrapper.findAll('.notification-grid-row').at(1) }) it('renders the author', () => { diff --git a/webapp/components/NotificationsTable/NotificationsTable.vue b/webapp/components/NotificationsTable/NotificationsTable.vue index 07db4f9a2..7065b2624 100644 --- a/webapp/components/NotificationsTable/NotificationsTable.vue +++ b/webapp/components/NotificationsTable/NotificationsTable.vue @@ -1,62 +1,108 @@