Vue it is
I know, the 18th front-end change; I have a feeling there won't be a 19th.
This commit is contained in:
parent
632f06ac5f
commit
338f11d1ab
@ -1,12 +1,9 @@
|
|||||||
# EditorConfig is awesome: http://EditorConfig.org
|
|
||||||
|
|
||||||
# top-most EditorConfig file
|
|
||||||
root = true
|
root = true
|
||||||
|
|
||||||
# Unix-style newlines with a newline ending every file
|
|
||||||
[*]
|
[*]
|
||||||
end_of_line = lf
|
charset = utf-8
|
||||||
insert_final_newline = true
|
|
||||||
# 2 space indentation
|
|
||||||
indent_style = space
|
indent_style = space
|
||||||
indent_size = 2
|
indent_size = 2
|
||||||
|
end_of_line = lf
|
||||||
|
insert_final_newline = true
|
||||||
|
trim_trailing_whitespace = true
|
||||||
|
2
src/app/.eslintignore
Normal file
2
src/app/.eslintignore
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
build/*.js
|
||||||
|
config/*.js
|
27
src/app/.eslintrc.js
Normal file
27
src/app/.eslintrc.js
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
// http://eslint.org/docs/user-guide/configuring
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
root: true,
|
||||||
|
parser: 'babel-eslint',
|
||||||
|
parserOptions: {
|
||||||
|
sourceType: 'module'
|
||||||
|
},
|
||||||
|
env: {
|
||||||
|
browser: true,
|
||||||
|
},
|
||||||
|
// https://github.com/feross/standard/blob/master/RULES.md#javascript-standard-style
|
||||||
|
extends: 'standard',
|
||||||
|
// required to lint *.vue files
|
||||||
|
plugins: [
|
||||||
|
'html'
|
||||||
|
],
|
||||||
|
// add your custom rules here
|
||||||
|
'rules': {
|
||||||
|
// allow paren-less arrow functions
|
||||||
|
'arrow-parens': 0,
|
||||||
|
// allow async-await
|
||||||
|
'generator-star-spacing': 0,
|
||||||
|
// allow debugger during development
|
||||||
|
'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0
|
||||||
|
}
|
||||||
|
}
|
19
src/app/.gitignore
vendored
Normal file
19
src/app/.gitignore
vendored
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
.DS_Store
|
||||||
|
node_modules/
|
||||||
|
dist/
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
test/unit/coverage
|
||||||
|
test/e2e/reports
|
||||||
|
selenium-debug.log
|
||||||
|
|
||||||
|
# Editor directories and files
|
||||||
|
.idea
|
||||||
|
*.suo
|
||||||
|
*.ntvs*
|
||||||
|
*.njsproj
|
||||||
|
*.sln
|
||||||
|
|
||||||
|
# Auth0 settings
|
||||||
|
src/auth/auth0-variables.js
|
8
src/app/.postcssrc.js
Normal file
8
src/app/.postcssrc.js
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
// https://github.com/michael-ciniawsky/postcss-load-config
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
"plugins": {
|
||||||
|
// to edit target browsers: use "browserslist" field in package.json
|
||||||
|
"autoprefixer": {}
|
||||||
|
}
|
||||||
|
}
|
21
src/app/LICENSE
Normal file
21
src/app/LICENSE
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2017 Daniel J. Summers
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
6
src/app/config/dev.env.js
Normal file
6
src/app/config/dev.env.js
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
var merge = require('webpack-merge')
|
||||||
|
var prodEnv = require('./prod.env')
|
||||||
|
|
||||||
|
module.exports = merge(prodEnv, {
|
||||||
|
NODE_ENV: '"development"'
|
||||||
|
})
|
38
src/app/config/index.js
Normal file
38
src/app/config/index.js
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
// see http://vuejs-templates.github.io/webpack for documentation.
|
||||||
|
var path = require('path')
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
build: {
|
||||||
|
env: require('./prod.env'),
|
||||||
|
index: path.resolve(__dirname, '../dist/index.html'),
|
||||||
|
assetsRoot: path.resolve(__dirname, '../dist'),
|
||||||
|
assetsSubDirectory: 'static',
|
||||||
|
assetsPublicPath: '/',
|
||||||
|
productionSourceMap: true,
|
||||||
|
// Gzip off by default as many popular static hosts such as
|
||||||
|
// Surge or Netlify already gzip all static assets for you.
|
||||||
|
// Before setting to `true`, make sure to:
|
||||||
|
// npm install --save-dev compression-webpack-plugin
|
||||||
|
productionGzip: false,
|
||||||
|
productionGzipExtensions: ['js', 'css'],
|
||||||
|
// Run the build command with an extra argument to
|
||||||
|
// View the bundle analyzer report after build finishes:
|
||||||
|
// `npm run build --report`
|
||||||
|
// Set to `true` or `false` to always turn it on or off
|
||||||
|
bundleAnalyzerReport: process.env.npm_config_report
|
||||||
|
},
|
||||||
|
dev: {
|
||||||
|
env: require('./dev.env'),
|
||||||
|
port: 8080,
|
||||||
|
autoOpenBrowser: true,
|
||||||
|
assetsSubDirectory: 'static',
|
||||||
|
assetsPublicPath: '/',
|
||||||
|
proxyTable: {},
|
||||||
|
// CSS Sourcemaps off by default because relative paths are "buggy"
|
||||||
|
// with this option, according to the CSS-Loader README
|
||||||
|
// (https://github.com/webpack/css-loader#sourcemaps)
|
||||||
|
// In our experience, they generally work as expected,
|
||||||
|
// just be aware of this issue when enabling this option.
|
||||||
|
cssSourceMap: false
|
||||||
|
}
|
||||||
|
}
|
3
src/app/config/prod.env.js
Normal file
3
src/app/config/prod.env.js
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
module.exports = {
|
||||||
|
NODE_ENV: '"production"'
|
||||||
|
}
|
6
src/app/config/test.env.js
Normal file
6
src/app/config/test.env.js
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
var merge = require('webpack-merge')
|
||||||
|
var devEnv = require('./dev.env')
|
||||||
|
|
||||||
|
module.exports = merge(devEnv, {
|
||||||
|
NODE_ENV: '"testing"'
|
||||||
|
})
|
@ -2,12 +2,13 @@
|
|||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<title>Aurelia</title>
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
<base href="/">
|
<title>myPrayerJournal</title>
|
||||||
|
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
|
||||||
|
<!-- link rel="stylesheet" href="https://ajax.aspnetcdn.com/ajax/bootstrap/3.3.6/css/bootstrap.min.css" -->
|
||||||
</head>
|
</head>
|
||||||
|
<body>
|
||||||
<body aurelia-app="main">
|
<div id="app"></div>
|
||||||
<script src="scripts/vendor-bundle.js" data-main="aurelia-bootstrapper"></script>
|
<!-- built files will be auto injected -->
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
11350
src/app/package-lock.json
generated
Normal file
11350
src/app/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,54 +1,98 @@
|
|||||||
{
|
{
|
||||||
"name": "contact-manager",
|
"name": "my-prayer-journal",
|
||||||
"description": "An Aurelia client application.",
|
"version": "0.8.0",
|
||||||
"version": "0.1.0",
|
"description": "myPrayerJournal - Front End",
|
||||||
"repository": {
|
"author": "Daniel J. Summers <daniel@djs-consulting.com>",
|
||||||
"type": "???",
|
"private": true,
|
||||||
"url": "???"
|
"scripts": {
|
||||||
|
"dev": "node build/dev-server.js",
|
||||||
|
"start": "node build/dev-server.js",
|
||||||
|
"build": "node build/build.js",
|
||||||
|
"unit": "cross-env BABEL_ENV=test karma start test/unit/karma.conf.js --single-run",
|
||||||
|
"e2e": "node test/e2e/runner.js",
|
||||||
|
"test": "npm run unit && npm run e2e",
|
||||||
|
"lint": "eslint --ext .js,.vue src test/unit/specs test/e2e/specs"
|
||||||
},
|
},
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"aurelia-animator-css": "^1.0.1",
|
"EventEmitter": "^1.0.0",
|
||||||
"aurelia-bootstrapper": "^2.1.0",
|
"auth0-js": "^8.8.0",
|
||||||
"aurelia-fetch-client": "^1.1.2",
|
"bootstrap-vue": "^0.18.0",
|
||||||
"auth0-lock": "^10.16.0",
|
"vue": "^2.3.3",
|
||||||
"bluebird": "^3.4.1",
|
"vue-router": "^2.6.0"
|
||||||
"bootstrap": "^3.3.7",
|
|
||||||
"jquery": "^2.2.4",
|
|
||||||
"nprogress": "^0.2.0",
|
|
||||||
"requirejs": "^2.3.2",
|
|
||||||
"text": "github:requirejs/text#latest"
|
|
||||||
},
|
},
|
||||||
"peerDependencies": {},
|
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"aurelia-cli": "^0.27.0",
|
"autoprefixer": "^7.1.2",
|
||||||
"aurelia-testing": "^1.0.0-beta.2.0.1",
|
"babel-core": "^6.22.1",
|
||||||
"aurelia-tools": "^1.0.0",
|
"babel-eslint": "^7.1.1",
|
||||||
"browser-sync": "^2.13.0",
|
"babel-loader": "^7.1.1",
|
||||||
"connect-history-api-fallback": "^1.2.0",
|
"babel-plugin-transform-runtime": "^6.22.0",
|
||||||
"gulp": "github:gulpjs/gulp#4.0",
|
"babel-preset-env": "^1.3.2",
|
||||||
"gulp-changed-in-place": "^2.0.3",
|
"babel-preset-stage-2": "^6.22.0",
|
||||||
"gulp-plumber": "^1.1.0",
|
"babel-register": "^6.22.0",
|
||||||
"gulp-rename": "^1.2.2",
|
"chalk": "^2.0.1",
|
||||||
"gulp-sourcemaps": "^2.0.0-alpha",
|
"connect-history-api-fallback": "^1.3.0",
|
||||||
"gulp-notify": "^2.2.0",
|
"copy-webpack-plugin": "^4.0.1",
|
||||||
"minimatch": "^3.0.2",
|
"css-loader": "^0.28.0",
|
||||||
"through2": "^2.0.1",
|
"cssnano": "^3.10.0",
|
||||||
"uglify-js": "^2.6.3",
|
"eslint": "^3.19.0",
|
||||||
"vinyl-fs": "^2.4.3",
|
"eslint-friendly-formatter": "^3.0.0",
|
||||||
"event-stream": "^3.3.3",
|
"eslint-loader": "^1.7.1",
|
||||||
"gulp-typescript": "^3.1.4",
|
"eslint-plugin-html": "^3.0.0",
|
||||||
"gulp-tslint": "^5.0.0",
|
"eslint-config-standard": "^6.2.1",
|
||||||
"tslint": "^3.11.0",
|
"eslint-plugin-promise": "^3.4.0",
|
||||||
"typescript": ">=1.9.0-dev || ^2.0.0",
|
"eslint-plugin-standard": "^2.0.1",
|
||||||
"@types/node": "^6.0.45",
|
"eventsource-polyfill": "^0.9.6",
|
||||||
"gulp-htmlmin": "^3.0.0",
|
"express": "^4.14.1",
|
||||||
"html-minifier": "^3.2.3",
|
"extract-text-webpack-plugin": "^2.0.0",
|
||||||
"jasmine-core": "^2.4.1",
|
"file-loader": "^0.11.1",
|
||||||
"karma": "^0.13.22",
|
"friendly-errors-webpack-plugin": "^1.1.3",
|
||||||
"karma-chrome-launcher": "^1.0.1",
|
"html-webpack-plugin": "^2.28.0",
|
||||||
"karma-jasmine": "^1.0.2",
|
"http-proxy-middleware": "^0.17.3",
|
||||||
"karma-typescript-preprocessor": "^0.2.1",
|
"webpack-bundle-analyzer": "^2.2.1",
|
||||||
"@types/jasmine": "^2.2.0"
|
"cross-env": "^5.0.1",
|
||||||
}
|
"karma": "^1.4.1",
|
||||||
|
"karma-coverage": "^1.1.1",
|
||||||
|
"karma-mocha": "^1.3.0",
|
||||||
|
"karma-phantomjs-launcher": "^1.0.2",
|
||||||
|
"karma-phantomjs-shim": "^1.4.0",
|
||||||
|
"karma-sinon-chai": "^1.3.1",
|
||||||
|
"karma-sourcemap-loader": "^0.3.7",
|
||||||
|
"karma-spec-reporter": "0.0.31",
|
||||||
|
"karma-webpack": "^2.0.2",
|
||||||
|
"lolex": "^1.5.2",
|
||||||
|
"mocha": "^3.2.0",
|
||||||
|
"chai": "^3.5.0",
|
||||||
|
"sinon": "^2.1.0",
|
||||||
|
"sinon-chai": "^2.8.0",
|
||||||
|
"inject-loader": "^3.0.0",
|
||||||
|
"babel-plugin-istanbul": "^4.1.1",
|
||||||
|
"phantomjs-prebuilt": "^2.1.14",
|
||||||
|
"chromedriver": "^2.27.2",
|
||||||
|
"cross-spawn": "^5.0.1",
|
||||||
|
"nightwatch": "^0.9.12",
|
||||||
|
"selenium-server": "^3.0.1",
|
||||||
|
"semver": "^5.3.0",
|
||||||
|
"shelljs": "^0.7.6",
|
||||||
|
"opn": "^5.1.0",
|
||||||
|
"optimize-css-assets-webpack-plugin": "^2.0.0",
|
||||||
|
"ora": "^1.2.0",
|
||||||
|
"rimraf": "^2.6.0",
|
||||||
|
"url-loader": "^0.5.8",
|
||||||
|
"vue-loader": "^12.1.0",
|
||||||
|
"vue-style-loader": "^3.0.1",
|
||||||
|
"vue-template-compiler": "^2.3.3",
|
||||||
|
"webpack": "^2.6.1",
|
||||||
|
"webpack-dev-middleware": "^1.10.0",
|
||||||
|
"webpack-hot-middleware": "^2.18.0",
|
||||||
|
"webpack-merge": "^4.1.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 4.0.0",
|
||||||
|
"npm": ">= 3.0.0"
|
||||||
|
},
|
||||||
|
"browserslist": [
|
||||||
|
"> 1%",
|
||||||
|
"last 2 versions",
|
||||||
|
"not ie <= 8"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
73
src/app/src/App.vue
Normal file
73
src/app/src/App.vue
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
<template>
|
||||||
|
<div id="app">
|
||||||
|
<navigation :auth="auth" />
|
||||||
|
<div id="content" class="container">
|
||||||
|
<router-view :auth="auth"></router-view>
|
||||||
|
</div>
|
||||||
|
<footer>
|
||||||
|
<p class="text-right"><i>myPrayerJournal v0.8.0</i></p>
|
||||||
|
</footer>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import AuthService from './auth/AuthService'
|
||||||
|
import Navigation from './components/Navigation.vue'
|
||||||
|
|
||||||
|
const auth = new AuthService()
|
||||||
|
const { login, logout, authenticated, authNotifier } = auth
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'app',
|
||||||
|
data: function () {
|
||||||
|
authNotifier.on('authChange', authState => {
|
||||||
|
this.authenticated = authState.authenticated
|
||||||
|
})
|
||||||
|
return {
|
||||||
|
auth,
|
||||||
|
authenticated
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
login,
|
||||||
|
logout
|
||||||
|
},
|
||||||
|
components: {
|
||||||
|
Navigation
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
@import url('../node_modules/bootstrap/dist/css/bootstrap.css');
|
||||||
|
@import url('../node_modules/bootstrap-vue/dist/bootstrap-vue.css');
|
||||||
|
|
||||||
|
body {
|
||||||
|
padding-top: 60px;
|
||||||
|
}
|
||||||
|
footer {
|
||||||
|
border-top: solid 1px lightgray;
|
||||||
|
margin-top: 1rem;
|
||||||
|
padding: 0 1rem;
|
||||||
|
|
||||||
|
}
|
||||||
|
.material-icons.md-18 {
|
||||||
|
font-size: 18px;
|
||||||
|
}
|
||||||
|
.material-icons.md-24 {
|
||||||
|
font-size: 24px;
|
||||||
|
}
|
||||||
|
.material-icons.md-36 {
|
||||||
|
font-size: 36px;
|
||||||
|
}
|
||||||
|
.material-icons.md-48 {
|
||||||
|
font-size: 48px;
|
||||||
|
}
|
||||||
|
.material-icons {
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
.mpj-page-title {
|
||||||
|
border-bottom: solid 1px lightgray;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
</style>
|
70
src/app/src/auth/AuthService.js
Normal file
70
src/app/src/auth/AuthService.js
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
import auth0 from 'auth0-js'
|
||||||
|
import { AUTH_CONFIG } from './auth0-variables'
|
||||||
|
import EventEmitter from 'EventEmitter'
|
||||||
|
import router from './../router'
|
||||||
|
|
||||||
|
export default class AuthService {
|
||||||
|
authenticated = this.isAuthenticated()
|
||||||
|
authNotifier = new EventEmitter()
|
||||||
|
|
||||||
|
constructor () {
|
||||||
|
this.login = this.login.bind(this)
|
||||||
|
this.setSession = this.setSession.bind(this)
|
||||||
|
this.logout = this.logout.bind(this)
|
||||||
|
this.isAuthenticated = this.isAuthenticated.bind(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
auth0 = new auth0.WebAuth({
|
||||||
|
domain: AUTH_CONFIG.domain,
|
||||||
|
clientID: AUTH_CONFIG.clientId,
|
||||||
|
redirectUri: AUTH_CONFIG.callbackUrl,
|
||||||
|
audience: `https://${AUTH_CONFIG.domain}/userinfo`,
|
||||||
|
responseType: 'token id_token',
|
||||||
|
scope: 'openid'
|
||||||
|
})
|
||||||
|
|
||||||
|
login () {
|
||||||
|
this.auth0.authorize()
|
||||||
|
}
|
||||||
|
|
||||||
|
handleAuthentication () {
|
||||||
|
this.auth0.parseHash((err, authResult) => {
|
||||||
|
if (authResult && authResult.accessToken && authResult.idToken) {
|
||||||
|
this.setSession(authResult)
|
||||||
|
router.replace('/dashboard')
|
||||||
|
} else if (err) {
|
||||||
|
router.replace('/')
|
||||||
|
console.log(err)
|
||||||
|
alert(`Error: ${err.error}. Check the console for further details.`)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
setSession (authResult) {
|
||||||
|
// Set the time that the access token will expire at
|
||||||
|
let expiresAt = JSON.stringify(
|
||||||
|
authResult.expiresIn * 1000 + new Date().getTime()
|
||||||
|
)
|
||||||
|
localStorage.setItem('access_token', authResult.accessToken)
|
||||||
|
localStorage.setItem('id_token', authResult.idToken)
|
||||||
|
localStorage.setItem('expires_at', expiresAt)
|
||||||
|
this.authNotifier.emit('authChange', { authenticated: true })
|
||||||
|
}
|
||||||
|
|
||||||
|
logout () {
|
||||||
|
// Clear access token and ID token from local storage
|
||||||
|
localStorage.removeItem('access_token')
|
||||||
|
localStorage.removeItem('id_token')
|
||||||
|
localStorage.removeItem('expires_at')
|
||||||
|
this.userProfile = null
|
||||||
|
this.authNotifier.emit('authChange', false)
|
||||||
|
// navigate to the home route
|
||||||
|
router.replace('/')
|
||||||
|
}
|
||||||
|
|
||||||
|
isAuthenticated () {
|
||||||
|
// Check whether the current time is past the access token's expiry time
|
||||||
|
let expiresAt = JSON.parse(localStorage.getItem('expires_at'))
|
||||||
|
return new Date().getTime() < expiresAt
|
||||||
|
}
|
||||||
|
}
|
21
src/app/src/components/Dashboard.vue
Normal file
21
src/app/src/components/Dashboard.vue
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
<template>
|
||||||
|
<article>
|
||||||
|
<page-title title="Your Dashboard" />
|
||||||
|
<p>here you are! {{ JSON.stringify(this.user) }}</p>
|
||||||
|
</article>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import PageTitle from './PageTitle'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'dashboard',
|
||||||
|
props: ['user'],
|
||||||
|
data () {
|
||||||
|
return {}
|
||||||
|
},
|
||||||
|
components: {
|
||||||
|
PageTitle
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
34
src/app/src/components/Home.vue
Normal file
34
src/app/src/components/Home.vue
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
<template>
|
||||||
|
<article>
|
||||||
|
<page-title title="Welcome!" hideOnPage="true" />
|
||||||
|
<div class="row">
|
||||||
|
<div class="col">
|
||||||
|
<p> </p>
|
||||||
|
<p>
|
||||||
|
myPrayerJournal is a place where individuals can record their prayer requests, record that they prayed for
|
||||||
|
them, update them as God moves in the situation, and record a final answer received on that request. It
|
||||||
|
will also allow individuals to review their answered prayers.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
This site is currently in very limited alpha, as it is being developed with a core group of test users.
|
||||||
|
If this is something in which you are interested, check back around mid-November 2017 for an update on the
|
||||||
|
development progress.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</article>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import PageTitle from './PageTitle.vue'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'home',
|
||||||
|
data () {
|
||||||
|
return {}
|
||||||
|
},
|
||||||
|
components: {
|
||||||
|
PageTitle
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
25
src/app/src/components/Navigation.vue
Normal file
25
src/app/src/components/Navigation.vue
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
<template>
|
||||||
|
<b-navbar toggleable type="inverse" variant="inverse" fixed="top">
|
||||||
|
<b-nav-toggle target="navCollapse"></b-nav-toggle>
|
||||||
|
<b-link class="navbar-brand" :to="{ name: 'Home' }">
|
||||||
|
<span style="font-weight:100;">my</span><span style="font-weight:600;">Prayer</span><span style="font-weight:700;">Journal</span>
|
||||||
|
</b-link>
|
||||||
|
<b-collapse is-nav id="navCollapse">
|
||||||
|
<b-nav is-nav-bar>
|
||||||
|
<b-nav-item v-if="auth.authenticated" :to="{ name: 'Dashboard' }">Dashboard</b-nav-item>
|
||||||
|
<b-nav-item v-if="auth.authenticated" @click="auth.logout()">Log Off</b-nav-item>
|
||||||
|
<b-nav-item v-if="!auth.authenticated" @click="auth.login()">Log On</b-nav-item>
|
||||||
|
</b-nav>
|
||||||
|
</b-collapse>
|
||||||
|
</b-navbar>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'navigation',
|
||||||
|
props: ['auth'],
|
||||||
|
data: function () {
|
||||||
|
return { }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
21
src/app/src/components/PageTitle.vue
Normal file
21
src/app/src/components/PageTitle.vue
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
<template>
|
||||||
|
<h2 v-if="!hideOnPage" class="mpj-page-title" v-html="title"></h2>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'page-title',
|
||||||
|
props: ['title', 'hideOnPage'],
|
||||||
|
data () {
|
||||||
|
return {}
|
||||||
|
},
|
||||||
|
created () {
|
||||||
|
document.title = `${this.title} « myPrayerJournal`
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
title () {
|
||||||
|
document.title = `${this.title} « myPrayerJournal`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
14
src/app/src/components/user/LogOn.vue
Normal file
14
src/app/src/components/user/LogOn.vue
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
<template>
|
||||||
|
<p>hang tight...</p>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'log-on',
|
||||||
|
props: ['auth'],
|
||||||
|
data () {
|
||||||
|
this.auth.handleAuthentication()
|
||||||
|
return {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
18
src/app/src/main.js
Normal file
18
src/app/src/main.js
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
// The Vue build version to load with the `import` command
|
||||||
|
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
|
||||||
|
import Vue from 'vue'
|
||||||
|
import BootstrapVue from 'bootstrap-vue'
|
||||||
|
import App from './App'
|
||||||
|
import router from './router'
|
||||||
|
|
||||||
|
Vue.config.productionTip = false
|
||||||
|
|
||||||
|
Vue.use(BootstrapVue)
|
||||||
|
|
||||||
|
/* eslint-disable no-new */
|
||||||
|
new Vue({
|
||||||
|
el: '#app',
|
||||||
|
router,
|
||||||
|
template: '<App/>',
|
||||||
|
components: { App }
|
||||||
|
})
|
17
src/app/src/router/index.js
Normal file
17
src/app/src/router/index.js
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
import Vue from 'vue'
|
||||||
|
import Router from 'vue-router'
|
||||||
|
|
||||||
|
import Dashboard from '@/components/Dashboard'
|
||||||
|
import Home from '@/components/Home'
|
||||||
|
import LogOn from '@/components/user/LogOn'
|
||||||
|
|
||||||
|
Vue.use(Router)
|
||||||
|
|
||||||
|
export default new Router({
|
||||||
|
mode: 'history',
|
||||||
|
routes: [
|
||||||
|
{ path: '/', name: 'Home', component: Home },
|
||||||
|
{ path: '/dashboard', name: 'Dashboard', component: Dashboard },
|
||||||
|
{ path: '/user/log-on', name: 'LogOn', component: LogOn }
|
||||||
|
]
|
||||||
|
})
|
0
src/app/static/.gitkeep
Normal file
0
src/app/static/.gitkeep
Normal file
26
src/app/test/e2e/custom-assertions/elementCount.js
Normal file
26
src/app/test/e2e/custom-assertions/elementCount.js
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
// A custom Nightwatch assertion.
|
||||||
|
// the name of the method is the filename.
|
||||||
|
// can be used in tests like this:
|
||||||
|
//
|
||||||
|
// browser.assert.elementCount(selector, count)
|
||||||
|
//
|
||||||
|
// for how to write custom assertions see
|
||||||
|
// http://nightwatchjs.org/guide#writing-custom-assertions
|
||||||
|
exports.assertion = function (selector, count) {
|
||||||
|
this.message = 'Testing if element <' + selector + '> has count: ' + count
|
||||||
|
this.expected = count
|
||||||
|
this.pass = function (val) {
|
||||||
|
return val === this.expected
|
||||||
|
}
|
||||||
|
this.value = function (res) {
|
||||||
|
return res.value
|
||||||
|
}
|
||||||
|
this.command = function (cb) {
|
||||||
|
var self = this
|
||||||
|
return this.api.execute(function (selector) {
|
||||||
|
return document.querySelectorAll(selector).length
|
||||||
|
}, [selector], function (res) {
|
||||||
|
cb.call(self, res)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
46
src/app/test/e2e/nightwatch.conf.js
Normal file
46
src/app/test/e2e/nightwatch.conf.js
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
require('babel-register')
|
||||||
|
var config = require('../../config')
|
||||||
|
|
||||||
|
// http://nightwatchjs.org/gettingstarted#settings-file
|
||||||
|
module.exports = {
|
||||||
|
src_folders: ['test/e2e/specs'],
|
||||||
|
output_folder: 'test/e2e/reports',
|
||||||
|
custom_assertions_path: ['test/e2e/custom-assertions'],
|
||||||
|
|
||||||
|
selenium: {
|
||||||
|
start_process: true,
|
||||||
|
server_path: require('selenium-server').path,
|
||||||
|
host: '127.0.0.1',
|
||||||
|
port: 4444,
|
||||||
|
cli_args: {
|
||||||
|
'webdriver.chrome.driver': require('chromedriver').path
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
test_settings: {
|
||||||
|
default: {
|
||||||
|
selenium_port: 4444,
|
||||||
|
selenium_host: 'localhost',
|
||||||
|
silent: true,
|
||||||
|
globals: {
|
||||||
|
devServerURL: 'http://localhost:' + (process.env.PORT || config.dev.port)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
chrome: {
|
||||||
|
desiredCapabilities: {
|
||||||
|
browserName: 'chrome',
|
||||||
|
javascriptEnabled: true,
|
||||||
|
acceptSslCerts: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
firefox: {
|
||||||
|
desiredCapabilities: {
|
||||||
|
browserName: 'firefox',
|
||||||
|
javascriptEnabled: true,
|
||||||
|
acceptSslCerts: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
33
src/app/test/e2e/runner.js
Normal file
33
src/app/test/e2e/runner.js
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
// 1. start the dev server using production config
|
||||||
|
process.env.NODE_ENV = 'testing'
|
||||||
|
var server = require('../../build/dev-server.js')
|
||||||
|
|
||||||
|
server.ready.then(() => {
|
||||||
|
// 2. run the nightwatch test suite against it
|
||||||
|
// to run in additional browsers:
|
||||||
|
// 1. add an entry in test/e2e/nightwatch.conf.json under "test_settings"
|
||||||
|
// 2. add it to the --env flag below
|
||||||
|
// or override the environment flag, for example: `npm run e2e -- --env chrome,firefox`
|
||||||
|
// For more information on Nightwatch's config file, see
|
||||||
|
// http://nightwatchjs.org/guide#settings-file
|
||||||
|
var opts = process.argv.slice(2)
|
||||||
|
if (opts.indexOf('--config') === -1) {
|
||||||
|
opts = opts.concat(['--config', 'test/e2e/nightwatch.conf.js'])
|
||||||
|
}
|
||||||
|
if (opts.indexOf('--env') === -1) {
|
||||||
|
opts = opts.concat(['--env', 'chrome'])
|
||||||
|
}
|
||||||
|
|
||||||
|
var spawn = require('cross-spawn')
|
||||||
|
var runner = spawn('./node_modules/.bin/nightwatch', opts, { stdio: 'inherit' })
|
||||||
|
|
||||||
|
runner.on('exit', function (code) {
|
||||||
|
server.close()
|
||||||
|
process.exit(code)
|
||||||
|
})
|
||||||
|
|
||||||
|
runner.on('error', function (err) {
|
||||||
|
server.close()
|
||||||
|
throw err
|
||||||
|
})
|
||||||
|
})
|
19
src/app/test/e2e/specs/test.js
Normal file
19
src/app/test/e2e/specs/test.js
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
// For authoring Nightwatch tests, see
|
||||||
|
// http://nightwatchjs.org/guide#usage
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
'default e2e tests': function (browser) {
|
||||||
|
// automatically uses dev Server port from /config.index.js
|
||||||
|
// default: http://localhost:8080
|
||||||
|
// see nightwatch.conf.js
|
||||||
|
const devServer = browser.globals.devServerURL
|
||||||
|
|
||||||
|
browser
|
||||||
|
.url(devServer)
|
||||||
|
.waitForElementVisible('#app', 5000)
|
||||||
|
.assert.elementPresent('.hello')
|
||||||
|
.assert.containsText('h1', 'Welcome to Your Vue.js App')
|
||||||
|
.assert.elementCount('img', 1)
|
||||||
|
.end()
|
||||||
|
}
|
||||||
|
}
|
9
src/app/test/unit/.eslintrc
Normal file
9
src/app/test/unit/.eslintrc
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"env": {
|
||||||
|
"mocha": true
|
||||||
|
},
|
||||||
|
"globals": {
|
||||||
|
"expect": true,
|
||||||
|
"sinon": true
|
||||||
|
}
|
||||||
|
}
|
13
src/app/test/unit/index.js
Normal file
13
src/app/test/unit/index.js
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
import Vue from 'vue'
|
||||||
|
|
||||||
|
Vue.config.productionTip = false
|
||||||
|
|
||||||
|
// require all test files (files that ends with .spec.js)
|
||||||
|
const testsContext = require.context('./specs', true, /\.spec$/)
|
||||||
|
testsContext.keys().forEach(testsContext)
|
||||||
|
|
||||||
|
// require all src files except main.js for coverage.
|
||||||
|
// you can also change this to match only the subset of files that
|
||||||
|
// you want coverage for.
|
||||||
|
const srcContext = require.context('../../src', true, /^\.\/(?!main(\.js)?$)/)
|
||||||
|
srcContext.keys().forEach(srcContext)
|
33
src/app/test/unit/karma.conf.js
Normal file
33
src/app/test/unit/karma.conf.js
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
// This is a karma config file. For more details see
|
||||||
|
// http://karma-runner.github.io/0.13/config/configuration-file.html
|
||||||
|
// we are also using it with karma-webpack
|
||||||
|
// https://github.com/webpack/karma-webpack
|
||||||
|
|
||||||
|
var webpackConfig = require('../../build/webpack.test.conf')
|
||||||
|
|
||||||
|
module.exports = function (config) {
|
||||||
|
config.set({
|
||||||
|
// to run in additional browsers:
|
||||||
|
// 1. install corresponding karma launcher
|
||||||
|
// http://karma-runner.github.io/0.13/config/browsers.html
|
||||||
|
// 2. add it to the `browsers` array below.
|
||||||
|
browsers: ['PhantomJS'],
|
||||||
|
frameworks: ['mocha', 'sinon-chai', 'phantomjs-shim'],
|
||||||
|
reporters: ['spec', 'coverage'],
|
||||||
|
files: ['./index.js'],
|
||||||
|
preprocessors: {
|
||||||
|
'./index.js': ['webpack', 'sourcemap']
|
||||||
|
},
|
||||||
|
webpack: webpackConfig,
|
||||||
|
webpackMiddleware: {
|
||||||
|
noInfo: true
|
||||||
|
},
|
||||||
|
coverageReporter: {
|
||||||
|
dir: './coverage',
|
||||||
|
reporters: [
|
||||||
|
{ type: 'lcov', subdir: '.' },
|
||||||
|
{ type: 'text-summary' }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
0
src/app/test/unit/specs/.gitkeep
Normal file
0
src/app/test/unit/specs/.gitkeep
Normal file
Loading…
Reference in New Issue
Block a user