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 e9254c4b9..91b040f54 100644 --- a/assets/styles/main.scss +++ b/assets/styles/main.scss @@ -126,3 +126,23 @@ hr { background-color: $color-neutral-80; height: 1px !important; } + +#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 @@ + + @@ -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 6bf42691e..f79b00db5 100644 --- a/layouts/default.vue +++ b/layouts/default.vue @@ -26,7 +26,7 @@ @@ -121,6 +125,10 @@ export default { }, methods: { isExact(url) { + if (url.indexOf('/profile') === 0) { + // do only match own profile + this.$route.path === url + } return this.$route.path.indexOf(url) === 0 } } @@ -147,10 +155,14 @@ export default { padding-bottom: 0.5rem; nav { - margin-left: -15px; - margin-right: -15px; + margin-left: -16px; + margin-right: -10px; padding-top: 1rem; padding-bottom: 1rem; + + a { + padding-left: 12px; + } } } diff --git a/locales/de.json b/locales/de.json index 2db0b529b..d248e2e4b 100644 --- a/locales/de.json +++ b/locales/de.json @@ -13,7 +13,9 @@ "memberSince": "Mitglied seit", "follow": "Folgen", "followers": "Folgen", - "following": "Folgt" + "following": "Folgt", + "shouted": "Empfohlen", + "commented": "Kommentiert" }, "settings": { "name": "Einstellungen", @@ -111,4 +113,4 @@ "loadMore": "mehr laden", "loading": "wird geladen" } -} \ No newline at end of file +} diff --git a/locales/en.json b/locales/en.json index ba1224835..d34631b47 100644 --- a/locales/en.json +++ b/locales/en.json @@ -13,7 +13,9 @@ "memberSince": "Member since", "follow": "Follow", "followers": "Followers", - "following": "Following" + "following": "Following", + "shouted": "Shouted", + "commented": "Commented" }, "settings": { "name": "Settings", @@ -111,4 +113,4 @@ "loadMore": "load more", "loading": "loading" } -} \ No newline at end of file +} diff --git a/package.json b/package.json index 580f8cae8..0ef5f9373 100644 --- a/package.json +++ b/package.json @@ -42,7 +42,7 @@ "@nuxtjs/axios": "^5.3.6", "@nuxtjs/dotenv": "^1.3.0", "accounting": "^0.4.1", - "cookie-universal-nuxt": "^2.0.12", + "cookie-universal-nuxt": "^2.0.14", "cross-env": "^5.2.0", "date-fns": "^2.0.0-alpha.26", "express": "^4.16.3", @@ -51,6 +51,7 @@ "jsonwebtoken": "^8.3.0", "nuxt": "^2.0.0", "nuxt-env": "^0.0.4", + "nuxt-sass-resources-loader": "^2.0.5", "v-tooltip": "^2.0.0-rc.33", "vue-count-to": "^1.0.13", "vue-izitoast": "1.1.2", @@ -72,7 +73,6 @@ "jest": "^23.6.0", "node-sass": "^4.11.0", "nodemon": "^1.18.9", - "nuxt-sass-resources-loader": "^2.0.5", "prettier": "1.14.3", "sass-loader": "^7.1.0", "vue-jest": "^3.0.2", diff --git a/pages/post/_slug.vue b/pages/post/_slug.vue index b3e6e2ea8..0d147532c 100644 --- a/pages/post/_slug.vue +++ b/pages/post/_slug.vue @@ -18,33 +18,33 @@