Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 0 additions & 25 deletions .circleci/config.yml

This file was deleted.

61 changes: 61 additions & 0 deletions .gitlab-ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
include:
- template: Auto-DevOps.gitlab-ci.yml

build:
stage: build
image: "registry.gitlab.com/gitlab-org/cluster-integration/auto-build-image:v0.4.0"
cache: {}
variables:
DOCKER_TLS_CERTDIR: ""
services:
- docker:19.03.12-dind
script:
- |
if [[ -z "$CI_COMMIT_TAG" ]]; then
export CI_APPLICATION_REPOSITORY=${CI_APPLICATION_REPOSITORY:-$CI_REGISTRY_IMAGE/$CI_COMMIT_REF_SLUG}
export CI_APPLICATION_TAG=${CI_APPLICATION_TAG:-$CI_COMMIT_SHA}
else
export CI_APPLICATION_REPOSITORY=${CI_APPLICATION_REPOSITORY:-$CI_REGISTRY_IMAGE}
export CI_APPLICATION_TAG=${CI_APPLICATION_TAG:-$CI_COMMIT_TAG}
fi
- ./bin/build.sh
rules:
- if: '$CI_COMMIT_TAG || $CI_COMMIT_BRANCH'

cache:
key: ${CI_COMMIT_REF_SLUG}
paths:
- .npm
- node_modules

variables:
AUTO_DEVOPS_BUILD_IMAGE_CNB_ENABLED: "true"
AUTO_DEVOPS_BUILD_IMAGE_CNB_BUILDER: "heroku/buildpacks:20"
BUILDPACK_URL: "heroku/nodejs"
npm_config_cache: "$CI_PROJECT_DIR/.npm"

test:
stage: test
image: node:12.20.0-stretch
before_script:
- npm ci --cache .npm --prefer-offline
script:
- npm install
- npm run test
rules:
- if: '$TEST_DISABLED'
when: never
- if: '$CI_COMMIT_TAG || $CI_COMMIT_BRANCH'

lint:
stage: test
image: node:12.20.0-stretch
before_script:
- npm ci --cache .npm --prefer-offline
script:
- npm install
- npm run lint:prod
rules:
- if: '$TEST_DISABLED'
when: never
- if: '$CI_COMMIT_TAG || $CI_COMMIT_BRANCH'
2 changes: 1 addition & 1 deletion .tool-versions
Original file line number Diff line number Diff line change
@@ -1 +1 @@
nodejs 11.7.0
nodejs 12.20.0
22 changes: 0 additions & 22 deletions Dockerfile

This file was deleted.

2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

> Online tutoring platform built with Vue.js and Webpack

[![CircleCI](https://circleci.com/gh/UPchieve/web.svg?style=svg)](https://circleci.com/gh/UPchieve/web) [![Contributor Covenant](https://img.shields.io/badge/Contributor%20Covenant-v2.0%20adopted-ff69b4.svg)](code_of_conduct.md)
[![Contributor Covenant](https://img.shields.io/badge/Contributor%20Covenant-v2.0%20adopted-ff69b4.svg)](code_of_conduct.md)

## GITLAB

Expand Down
50 changes: 50 additions & 0 deletions bin/build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
#!/bin/bash -e

# build stage script for Auto-DevOps

if ! docker info &>/dev/null; then
if [ -z "$DOCKER_HOST" ] && [ "$KUBERNETES_PORT" ]; then
export DOCKER_HOST='tcp://localhost:2375'
fi
fi

if [[ -n "$CI_REGISTRY" && -n "$CI_REGISTRY_USER" ]]; then
echo "Logging to GitLab Container Registry with CI credentials..."
echo "$CI_REGISTRY_PASSWORD" | docker login -u "$CI_REGISTRY_USER" --password-stdin "$CI_REGISTRY"
fi

image_previous="$CI_APPLICATION_REPOSITORY:$CI_COMMIT_BEFORE_SHA"
image_tagged="$CI_APPLICATION_REPOSITORY:$CI_APPLICATION_TAG"
image_latest="$CI_APPLICATION_REPOSITORY:latest"

builder=${AUTO_DEVOPS_BUILD_IMAGE_CNB_BUILDER:-"heroku/buildpacks:18"}
echo "Building Cloud Native Buildpack-based application with builder ${builder}..."
buildpack_args=()
if [[ -n "$BUILDPACK_URL" ]]; then
buildpack_args=('--buildpack' "$BUILDPACK_URL")
fi
env_args=()
if [[ -n "$AUTO_DEVOPS_BUILD_IMAGE_FORWARDED_CI_VARIABLES" ]]; then
mapfile -t env_arg_names < <(echo "$AUTO_DEVOPS_BUILD_IMAGE_FORWARDED_CI_VARIABLES" | tr ',' "\n")
for env_arg_name in "${env_arg_names[@]}"; do
env_args+=('--env' "$env_arg_name")
done
fi
pack build "$image_tagged" \
--builder "$builder" \
"${env_args[@]}" \
"${buildpack_args[@]}" \
--env HTTP_PROXY \
--env http_proxy \
--env HTTPS_PROXY \
--env https_proxy \
--env FTP_PROXY \
--env ftp_proxy \
--env NO_PROXY \
--env no_proxy \
--env "NODE_ENV=production"

docker tag "$image_tagged" "$image_latest"

docker push "$image_tagged"
docker push "$image_latest"
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,8 @@
"vuex": "^3.0.1"
},
"engines": {
"node": ">= 11.7.0",
"npm": ">= 6.0.0"
"node": "^12.20.0",
"npm": "^6.14.8"
},
"devDependencies": {
"cypress-file-upload": "^4.0.7",
Expand Down
54 changes: 52 additions & 2 deletions src/components/App/AppModal/ModalTemplate.vue
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
<template>
<div
class="ModalTemplate"
ref="modalTemplateContainer"
:class="{ 'ModalTemplate--important': important }"
@click="closeModal"
@keydown="checkKeyEvent"
>
<div v-if="mobileMode" class="ModalTemplate-header">
<div
Expand Down Expand Up @@ -44,6 +46,9 @@ import { mapGetters } from "vuex";
import LargeButton from "@/components/LargeButton";
import ArrowIcon from "@/assets/arrow.svg";

const FOCUSABLE_ELEMENT_SELECTOR =
'button:not([disabled]), [href], input:not([tabindex="-1"]), select, textarea, [tabindex]:not([tabindex="-1"])';

export default {
components: { LargeButton, ArrowIcon },
props: {
Expand All @@ -59,6 +64,11 @@ export default {
mounted() {
const body = document.querySelector("body");
body.classList.add("disable-scroll");

// focus on first focusable child element, to put the focus in the trap
this.$refs.modalTemplateContainer
.querySelectorAll(FOCUSABLE_ELEMENT_SELECTOR)[0]
.focus();
},
beforeDestroy() {
const body = document.querySelector("body");
Expand All @@ -78,8 +88,48 @@ export default {
closeModal(event) {
// users must interact with the modal button to close session related modals
if (this.isSessionFulfilledModal) return;
const { target } = event;
if (target.classList.contains("ModalTemplate")) this.handleCancel();
const { key, target } = event;
if (key === "Escape" || target.classList.contains("ModalTemplate")) {
this.handleCancel();
}
},
checkKeyEvent(event) {
// based on tab key trap at:
// https://gist.github.com/JimSchofield/ec06d1f209799f5cd279f5683b178da4
const { key } = event;

if (key === "Escape") {
// treat as a close event and exit early
this.closeModal(event);
return;
}

const focusableList = this.$refs.modalTemplateContainer.querySelectorAll(
FOCUSABLE_ELEMENT_SELECTOR
);

// escape early if only 1 or no elements to focus
if (focusableList.length < 2 && event.key === "Tab") {
event.preventDefault();
return;
}

const last = focusableList.length - 1;
if (
event.key === "Tab" &&
event.shiftKey === false &&
event.target === focusableList[last]
) {
event.preventDefault();
focusableList[0].focus();
} else if (
event.key === "Tab" &&
event.shiftKey === true &&
event.target === focusableList[0]
) {
event.preventDefault();
focusableList[last].focus();
}
}
}
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,20 @@
<input
v-model="responses[question.key].answer"
type="radio"
tabindex="-1"
:id="`${question.key}_${option.value}`"
:value="option.value"
/>
<label :for="`${question.key}_${option.value}`">
<label
:for="`${question.key}_${option.value}`"
tabindex="0"
@keydown.space="responses[question.key].answer = option.value"
>
<span>{{ option.displayName }}</span>
<input
v-if="option.value === 'other'"
type="text"
tabindex="-1"
v-model="responses[question.key].other"
:disabled="responses[question.key].answer !== 'other'"
/>
Expand Down