diff --git a/.dockerignore b/.dockerignore
index 9f734654d..4ab35e506 100644
--- a/.dockerignore
+++ b/.dockerignore
@@ -11,3 +11,8 @@ scripts/
.env
cypress/
+
+README.md
+screenshot*.png
+lokalise.png
+.editorconfig
\ No newline at end of file
diff --git a/.travis.yml b/.travis.yml
index 0ad6b5e30..46a173ae7 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -18,8 +18,8 @@ before_install:
- sudo mv docker-compose /usr/local/bin
install:
- - docker build --build-arg BUILD_COMMIT=$TRAVIS_COMMIT -t humanconnection/nitro-web .
- - docker-compose -f docker-compose.yml up -d
+ - docker build --build-arg BUILD_COMMIT=$TRAVIS_COMMIT --target production -t humanconnection/nitro-web .
+ - docker-compose -f docker-compose.yml -f docker-compose.travis.yml up -d
- git clone https://github.com/Human-Connection/Nitro-Backend.git ../Nitro-Backend
- git -C "../Nitro-Backend" checkout $TRAVIS_BRANCH || echo "Branch \`$TRAVIS_BRANCH\` does not exist, falling back to \`master\`"
- docker-compose -f ../Nitro-Backend/docker-compose.yml -f ../Nitro-Backend/docker-compose.travis.yml up -d
@@ -27,8 +27,8 @@ install:
- yarn add cypress-cucumber-preprocessor
script:
- - docker-compose exec webapp yarn run lint
- - docker-compose exec webapp yarn run test
+ - docker-compose exec -e NODE_ENV=test webapp yarn run lint
+ - docker-compose exec -e NODE_ENV=test webapp yarn run test
- docker-compose -f ../Nitro-Backend/docker-compose.yml exec backend yarn run db:seed > /dev/null
- wait-on http://localhost:3000
- cypress run --record --key $CYPRESS_TOKEN
diff --git a/Dockerfile b/Dockerfile
index 8ebbb0393..8f7df318b 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,9 +1,9 @@
-FROM node:10-alpine
+FROM node:10-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 the app port
-EXPOSE 3000
-
+ARG BUILD_COMMIT
+ENV BUILD_COMMIT=$BUILD_COMMIT
ARG WORKDIR=/nitro-web
RUN mkdir -p $WORKDIR
WORKDIR $WORKDIR
@@ -11,18 +11,19 @@ WORKDIR $WORKDIR
# See: https://github.com/nodejs/docker-node/pull/367#issuecomment-430807898
RUN apk --no-cache add git
-# Install Web Application
-COPY package.json .
-COPY yarn.lock .
-COPY styleguide/ ./styleguide
-RUN yarn install --production=false --frozen-lockfile --non-interactive
+COPY . .
-# Install and build Styleguide
-COPY styleguide/ ./styleguide
+FROM base as build-and-test
+RUN yarn install --production=false --frozen-lockfile --non-interactive
RUN cd styleguide && yarn install --production=false --frozen-lockfile --non-interactive \
&& cd .. \
&& yarn run styleguide:build
+RUN yarn run build
-COPY . .
-RUN ["yarn", "run", "build"]
+FROM base as production
+ENV NODE_ENV=production
+COPY --from=build-and-test ./nitro-web/node_modules ./node_modules
+COPY --from=build-and-test ./nitro-web/.nuxt ./.nuxt
+
+EXPOSE 3000
CMD ["yarn", "run", "start"]
diff --git a/assets/styles/main.scss b/assets/styles/main.scss
index e56007577..1ce0c0e53 100644
--- a/assets/styles/main.scss
+++ b/assets/styles/main.scss
@@ -138,3 +138,23 @@ hr {
margin-right: -15px;
}
}
+
+ #overlay {
+ display: block;
+ opacity: 0;
+ width: 100%;
+ height: 100%;
+ top: 0;
+ left: 0;
+ position: fixed;
+ background: rgba(0, 0, 0, 0.15);
+ z-index: 99;
+ pointer-events: none;
+ transition: opacity 150ms ease-out;
+ transition-delay: 50ms;
+
+ .dropdown-open & {
+ opacity: 1;
+ transition-delay: 0;
+ }
+}
diff --git a/components/Author.vue b/components/Author.vue
index 53379afa8..377b74b7f 100644
--- a/components/Author.vue
+++ b/components/Author.vue
@@ -1,127 +1,127 @@
-
-
-
-
-
-
-
- {{ author.name | truncate(trunc, 18) }}
-
-
-
-
- {{ post.createdAt | dateTime('dd. MMMM yyyy HH:mm') }}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+ {{ author.name | truncate(trunc, 18) }}
+
+
+
+
+ {{ post.createdAt | dateTime('dd. MMMM yyyy HH:mm') }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -191,4 +166,15 @@ export default {
margin-top: -45px;
border: #fff 5px solid;
}
+.author {
+ white-space: nowrap;
+ position: relative;
+ display: flex;
+ align-items: center;
+
+ &:hover,
+ &.active {
+ z-index: 999;
+ }
+}
diff --git a/components/Dropdown.vue b/components/Dropdown.vue
index f47c1cabb..1cfe84c2b 100644
--- a/components/Dropdown.vue
+++ b/components/Dropdown.vue
@@ -3,10 +3,16 @@
:open.sync="isPopoverOpen"
:open-group="Math.random().toString()"
:placement="placement"
+ :disabled="disabled"
trigger="manual"
:offset="offset"
>
-
+
@@ -29,6 +38,7 @@ let mouseLeaveTimer = null
export default {
props: {
placement: { type: String, default: 'bottom-end' },
+ disabled: { type: Boolean, default: false },
offset: { type: [String, Number], default: '16' }
},
data() {
@@ -36,17 +46,68 @@ export default {
isPopoverOpen: false
}
},
+ computed: {
+ isOpen() {
+ return this.isPopoverOpen
+ }
+ },
+ watch: {
+ isPopoverOpen: {
+ immediate: true,
+ handler(isOpen) {
+ try {
+ if (isOpen) {
+ this.$nextTick(() => {
+ setTimeout(() => {
+ document
+ .getElementsByTagName('body')[0]
+ .classList.add('dropdown-open')
+ }, 20)
+ })
+ } else {
+ document
+ .getElementsByTagName('body')[0]
+ .classList.remove('dropdown-open')
+ }
+ } catch (err) {}
+ }
+ }
+ },
beforeDestroy() {
clearTimeout(mouseEnterTimer)
clearTimeout(mouseLeaveTimer)
},
methods: {
toggleMenu() {
- this.isPopoverOpen = !this.isPopoverOpen
+ this.isPopoverOpen ? this.closeMenu(false) : this.openMenu(false)
+ },
+ openMenu(useTimeout) {
+ if (this.disabled) {
+ return
+ }
+ this.clearTimeouts()
+ if (useTimeout === true) {
+ this.popoverMouseEnter()
+ } else {
+ this.isPopoverOpen = true
+ }
+ },
+ closeMenu(useTimeout) {
+ if (this.disabled) {
+ return
+ }
+ this.clearTimeouts()
+ if (useTimeout === true) {
+ this.popoveMouseLeave()
+ } else {
+ this.isPopoverOpen = false
+ }
},
popoverMouseEnter() {
- clearTimeout(mouseEnterTimer)
- clearTimeout(mouseLeaveTimer)
+ if (this.disabled) {
+ return
+ }
+ this.clearTimeouts()
if (!this.isPopoverOpen) {
mouseEnterTimer = setTimeout(() => {
this.isPopoverOpen = true
@@ -54,13 +115,19 @@ export default {
}
},
popoveMouseLeave() {
- clearTimeout(mouseEnterTimer)
- clearTimeout(mouseLeaveTimer)
+ if (this.disabled) {
+ return
+ }
+ this.clearTimeouts()
if (this.isPopoverOpen) {
mouseLeaveTimer = setTimeout(() => {
this.isPopoverOpen = false
}, 300)
}
+ },
+ clearTimeouts() {
+ clearTimeout(mouseEnterTimer)
+ clearTimeout(mouseLeaveTimer)
}
}
}
diff --git a/cypress/integration/common/steps.js b/cypress/integration/common/steps.js
index 55660d366..78266d96e 100644
--- a/cypress/integration/common/steps.js
+++ b/cypress/integration/common/steps.js
@@ -1,6 +1,5 @@
import { Given, When, Then } from 'cypress-cucumber-preprocessor/steps'
import find from 'lodash/find'
-import { eq } from 'semver';
/* global cy */
@@ -73,7 +72,6 @@ Given('my user account has the role {string}', role => {
// TODO: use db factories instead of seed data
})
-
When('I log out', logout)
When('I visit the {string} page', page => {
diff --git a/docker-compose.override.yml b/docker-compose.override.yml
index 4188b42ce..bb7a6c1d1 100644
--- a/docker-compose.override.yml
+++ b/docker-compose.override.yml
@@ -2,6 +2,9 @@ version: '3.7'
services:
webapp:
+ build:
+ context: .
+ target: build-and-test
volumes:
- .:/nitro-web
- node_modules:/nitro-web/node_modules
diff --git a/docker-compose.travis.yml b/docker-compose.travis.yml
new file mode 100644
index 000000000..ced9719a2
--- /dev/null
+++ b/docker-compose.travis.yml
@@ -0,0 +1,7 @@
+version: "3.7"
+
+services:
+ webapp:
+ build:
+ context: .
+ target: build-and-test
diff --git a/docker-compose.yml b/docker-compose.yml
index f7c697889..c8bba8595 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -3,7 +3,9 @@ version: '3.7'
services:
webapp:
image: humanconnection/nitro-web:latest
- build: .
+ build:
+ context: .
+ target: production
ports:
- 3000:3000
- 8080:8080
diff --git a/layouts/blank.vue b/layouts/blank.vue
index 23a783ac6..140ec9f6e 100644
--- a/layouts/blank.vue
+++ b/layouts/blank.vue
@@ -5,6 +5,7 @@
+
diff --git a/layouts/default.vue b/layouts/default.vue
index 03180b61a..01f883b1e 100644
--- a/layouts/default.vue
+++ b/layouts/default.vue
@@ -26,7 +26,7 @@