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
|
||||
|
||||
# Unix-style newlines with a newline ending every file
|
||||
[*]
|
||||
end_of_line = lf
|
||||
insert_final_newline = true
|
||||
# 2 space indentation
|
||||
charset = utf-8
|
||||
indent_style = space
|
||||
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>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Aurelia</title>
|
||||
<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>
|
||||
|
||||
<body aurelia-app="main">
|
||||
<script src="scripts/vendor-bundle.js" data-main="aurelia-bootstrapper"></script>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
<!-- built files will be auto injected -->
|
||||
</body>
|
||||
</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",
|
||||
"description": "An Aurelia client application.",
|
||||
"version": "0.1.0",
|
||||
"repository": {
|
||||
"type": "???",
|
||||
"url": "???"
|
||||
"name": "my-prayer-journal",
|
||||
"version": "0.8.0",
|
||||
"description": "myPrayerJournal - Front End",
|
||||
"author": "Daniel J. Summers <daniel@djs-consulting.com>",
|
||||
"private": true,
|
||||
"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": {
|
||||
"aurelia-animator-css": "^1.0.1",
|
||||
"aurelia-bootstrapper": "^2.1.0",
|
||||
"aurelia-fetch-client": "^1.1.2",
|
||||
"auth0-lock": "^10.16.0",
|
||||
"bluebird": "^3.4.1",
|
||||
"bootstrap": "^3.3.7",
|
||||
"jquery": "^2.2.4",
|
||||
"nprogress": "^0.2.0",
|
||||
"requirejs": "^2.3.2",
|
||||
"text": "github:requirejs/text#latest"
|
||||
"EventEmitter": "^1.0.0",
|
||||
"auth0-js": "^8.8.0",
|
||||
"bootstrap-vue": "^0.18.0",
|
||||
"vue": "^2.3.3",
|
||||
"vue-router": "^2.6.0"
|
||||
},
|
||||
"peerDependencies": {},
|
||||
"devDependencies": {
|
||||
"aurelia-cli": "^0.27.0",
|
||||
"aurelia-testing": "^1.0.0-beta.2.0.1",
|
||||
"aurelia-tools": "^1.0.0",
|
||||
"browser-sync": "^2.13.0",
|
||||
"connect-history-api-fallback": "^1.2.0",
|
||||
"gulp": "github:gulpjs/gulp#4.0",
|
||||
"gulp-changed-in-place": "^2.0.3",
|
||||
"gulp-plumber": "^1.1.0",
|
||||
"gulp-rename": "^1.2.2",
|
||||
"gulp-sourcemaps": "^2.0.0-alpha",
|
||||
"gulp-notify": "^2.2.0",
|
||||
"minimatch": "^3.0.2",
|
||||
"through2": "^2.0.1",
|
||||
"uglify-js": "^2.6.3",
|
||||
"vinyl-fs": "^2.4.3",
|
||||
"event-stream": "^3.3.3",
|
||||
"gulp-typescript": "^3.1.4",
|
||||
"gulp-tslint": "^5.0.0",
|
||||
"tslint": "^3.11.0",
|
||||
"typescript": ">=1.9.0-dev || ^2.0.0",
|
||||
"@types/node": "^6.0.45",
|
||||
"gulp-htmlmin": "^3.0.0",
|
||||
"html-minifier": "^3.2.3",
|
||||
"jasmine-core": "^2.4.1",
|
||||
"karma": "^0.13.22",
|
||||
"karma-chrome-launcher": "^1.0.1",
|
||||
"karma-jasmine": "^1.0.2",
|
||||
"karma-typescript-preprocessor": "^0.2.1",
|
||||
"@types/jasmine": "^2.2.0"
|
||||
}
|
||||
"autoprefixer": "^7.1.2",
|
||||
"babel-core": "^6.22.1",
|
||||
"babel-eslint": "^7.1.1",
|
||||
"babel-loader": "^7.1.1",
|
||||
"babel-plugin-transform-runtime": "^6.22.0",
|
||||
"babel-preset-env": "^1.3.2",
|
||||
"babel-preset-stage-2": "^6.22.0",
|
||||
"babel-register": "^6.22.0",
|
||||
"chalk": "^2.0.1",
|
||||
"connect-history-api-fallback": "^1.3.0",
|
||||
"copy-webpack-plugin": "^4.0.1",
|
||||
"css-loader": "^0.28.0",
|
||||
"cssnano": "^3.10.0",
|
||||
"eslint": "^3.19.0",
|
||||
"eslint-friendly-formatter": "^3.0.0",
|
||||
"eslint-loader": "^1.7.1",
|
||||
"eslint-plugin-html": "^3.0.0",
|
||||
"eslint-config-standard": "^6.2.1",
|
||||
"eslint-plugin-promise": "^3.4.0",
|
||||
"eslint-plugin-standard": "^2.0.1",
|
||||
"eventsource-polyfill": "^0.9.6",
|
||||
"express": "^4.14.1",
|
||||
"extract-text-webpack-plugin": "^2.0.0",
|
||||
"file-loader": "^0.11.1",
|
||||
"friendly-errors-webpack-plugin": "^1.1.3",
|
||||
"html-webpack-plugin": "^2.28.0",
|
||||
"http-proxy-middleware": "^0.17.3",
|
||||
"webpack-bundle-analyzer": "^2.2.1",
|
||||
"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