Compare commits
39 Commits
Author | SHA1 | Date | |
---|---|---|---|
c406c11b88 | |||
|
083b450fd3 | ||
|
105bfa6b66 | ||
|
c4a9410e76 | ||
|
0c6fad9828 | ||
|
512a079698 | ||
|
0a75ba489a | ||
|
de49954d58 | ||
|
c5d8775d93 | ||
|
e4f83505e0 | ||
|
2d8aa8b6c7 | ||
|
f3f430ab47 | ||
|
f63522dcf1 | ||
|
3ae1535348 | ||
|
812c3a1edd | ||
|
079f0399fc | ||
|
f8d5c7c4f9 | ||
|
e35a2b69fa | ||
|
58d0251849 | ||
|
e7c99dade0 | ||
|
ec2853f2b6 | ||
|
0cbdf6b8a1 | ||
|
0a009067ae | ||
|
be3c9e17bc | ||
|
bae2d779f7 | ||
|
f71fa9d6c7 | ||
|
f9a05f42e5 | ||
|
5d315f08cb | ||
|
482cffbb4e | ||
|
25c23d161e | ||
|
7497fe7a41 | ||
|
446b730430 | ||
|
3db2da197c | ||
|
714c585f9b | ||
|
5a8a3aa04c | ||
|
5a46f07509 | ||
|
e08191e92a | ||
|
be639705f6 | ||
|
bb24e425c9 |
@ -1 +1 @@
|
||||
chrome 78
|
||||
chrome 84
|
||||
|
11
.eslintrc.js
11
.eslintrc.js
@ -26,6 +26,7 @@ module.exports = {
|
||||
extends: [
|
||||
'eslint:recommended',
|
||||
'plugin:jest/recommended',
|
||||
'plugin:vuejs-accessibility/recommended',
|
||||
'tjw-base',
|
||||
'tjw-vue'
|
||||
],
|
||||
@ -33,6 +34,16 @@ module.exports = {
|
||||
'no-restricted-syntax': [
|
||||
'error',
|
||||
'Property[method="true"]'
|
||||
],
|
||||
'vuejs-accessibility/label-has-for': [
|
||||
'error',
|
||||
{
|
||||
'components': ['Label'],
|
||||
'required': {
|
||||
'some': ['nesting', 'id']
|
||||
},
|
||||
'allowChildren': false
|
||||
}
|
||||
]
|
||||
}
|
||||
};
|
||||
|
20
README.md
20
README.md
@ -6,25 +6,30 @@ NW.js + Vue-CLI 4 example
|
||||
|
||||

|
||||
|
||||
* NW.js
|
||||
* Vue-CLI 4
|
||||
* Vue 2.6
|
||||
* NW.js 0.47.0
|
||||
* Chrome 84
|
||||
* Node 14.5.0
|
||||
* Vue-CLI 4.4.6
|
||||
* Vue 2.6.11
|
||||
* Vue-DevTools (latest)
|
||||
* Babel
|
||||
* ESLint
|
||||
* Vue Linting
|
||||
* A11Y Linting
|
||||
* Jest Linting
|
||||
* Jest (100% test coverage)
|
||||
* Jest Serializer Vue (TJW)
|
||||
|
||||
*Why not include Vue-Router or Vuex?*
|
||||
|
||||
Those are both very easily added from the Vue-CLI. There is also no custom styling libraries (Bulma, Bootstrap, etc), or meta-languages (Sass, TS, Pug, etc), or component libraries (Vuetify, Inkline, etc). This is repo is meant to be the "go to" option for building all desktop apps with Vue. So it avoids pushing any particular choices on to you. With the exception of testing being set up for Jest, and Linting being set up to ensure minumum quality of this boilerplate repo itself. Both of which can be easily modified, ignored, or removed.
|
||||
Those are both very easily added from the Vue-CLI. There is also no custom styling libraries (Bulma, Bootstrap, etc), or meta-languages (Sass, TS, Pug, etc), or component libraries (Vuetify, Inkline, etc). This repo is meant to be the "go to" option for building all desktop apps with Vue. So it avoids pushing any particular choices on to you. With the exception of testing being set up for Jest, and Linting being set up to ensure minumum quality of this boilerplate repo itself. Both of which can be easily modified, ignored, or removed.
|
||||
|
||||
|
||||
## Running Locally for development
|
||||
|
||||
1. `npm install`
|
||||
1. `npm start`
|
||||
1. An empty window will pop up while Webpack warm ups
|
||||
1. Once Webpack is running, refresh the window and you're golden
|
||||
1. Once Webpack finishes starting up your app will appear in a window
|
||||
|
||||
|
||||
## Building for distribution
|
||||
@ -81,7 +86,10 @@ This will download the source code for the latest version of Vue-DevTools and do
|
||||
This is not for those *using* this repo, but for those *maintaining* it.
|
||||
|
||||
1. When updating the version of NW.js devDependency, also update these:
|
||||
* `package.json` devDeps, build nwVersion
|
||||
* `tests/unit/setup.js`
|
||||
* `tests/unit/components/__snapshots__/HelloWorld.test.js.snap`
|
||||
* `.browserslistrc`
|
||||
1. Update the version numbers at the top of the README
|
||||
1. Bump the version number, and all the npm scripts that reference the version number
|
||||
1. Run `npm run regression` after updating dependencies or other major changes to verify builds still work correctly
|
||||
|
@ -1,5 +1,5 @@
|
||||
module.exports = {
|
||||
presets: [
|
||||
'@vue/app'
|
||||
'@vue/cli-plugin-babel/preset'
|
||||
]
|
||||
};
|
||||
|
@ -2,45 +2,20 @@ process.env.VUE_CLI_BABEL_TARGET_NODE = true;
|
||||
process.env.VUE_CLI_BABEL_TRANSPILE_MODULES = true;
|
||||
|
||||
module.exports = {
|
||||
collectCoverageFrom: [
|
||||
'src/**/*.{js,vue}',
|
||||
'!src/main.js',
|
||||
'!**/node_modules/**'
|
||||
],
|
||||
preset: '@vue/cli-plugin-unit-jest',
|
||||
coverageDirectory: '<rootDir>/tests/unit/coverage',
|
||||
moduleFileExtensions: [
|
||||
'js',
|
||||
'jsx',
|
||||
'json',
|
||||
'vue'
|
||||
],
|
||||
moduleNameMapper: {
|
||||
'^@/(.*)$': '<rootDir>/src/$1'
|
||||
},
|
||||
setupFilesAfterEnv: [
|
||||
'<rootDir>/tests/unit/setup.js'
|
||||
],
|
||||
snapshotSerializers: [
|
||||
'<rootDir>/tests/unit/serializer.js'
|
||||
'<rootDir>/node_modules/jest-serializer-vue-tjw'
|
||||
],
|
||||
testEnvironment: 'jest-environment-jsdom-global',
|
||||
testMatch: [
|
||||
'**/tests/unit/**/*.test.js'
|
||||
],
|
||||
testPathIgnorePatterns: [
|
||||
'<rootDir>/tests/e2e'
|
||||
],
|
||||
testURL: 'http://localhost/',
|
||||
transform: {
|
||||
'^.+\\.vue$': 'vue-jest',
|
||||
'.+\\.(css|styl|less|sass|scss|svg|png|jpg|ttf|woff|woff2)$': 'jest-transform-stub',
|
||||
'^.+\\.jsx?$': 'babel-jest'
|
||||
},
|
||||
transformIgnorePatterns: [
|
||||
'/node_modules/'
|
||||
],
|
||||
watchPlugins: [
|
||||
'jest-watch-typeahead/filename',
|
||||
'jest-watch-typeahead/testname'
|
||||
'<rootDir>/tests/e2e',
|
||||
'<rootDir>/dist',
|
||||
'<rootDir>/dist-vue'
|
||||
]
|
||||
};
|
||||
|
@ -15,6 +15,7 @@ nwBinary = './node_modules/nw/' + nwBinary;
|
||||
driver = './node_modules/nw/' + driver;
|
||||
|
||||
module.exports = (function (settings) {
|
||||
console.log(nwBinary);
|
||||
settings.webdriver.server_path = driver;
|
||||
settings.selenium.cli_args['webdriver.chrome.driver'] = driver;
|
||||
return settings;
|
||||
|
12834
package-lock.json
generated
12834
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
143
package.json
143
package.json
@ -1,87 +1,75 @@
|
||||
{
|
||||
"ManifestComments": [
|
||||
"Only add dependencies that you want shipped to the end user, for everything else, use devDependencies, including things that will be bundled by webpack.",
|
||||
"NW.js requires a name and a main, everything else is optional.",
|
||||
"The build section is used by nwjs-builder-phoenix, see it's documentation for more info",
|
||||
"To turn spell checking off, remove it from the chromium-args in this file"
|
||||
],
|
||||
"name": "nw-vue",
|
||||
"version": "1.2.0",
|
||||
"main": "http://localhost:8964",
|
||||
"node-remote": "http://localhost:8964",
|
||||
"node-main": "",
|
||||
"window": {
|
||||
"width": 960,
|
||||
"height": 600,
|
||||
"min_width": 700,
|
||||
"min_height": 500,
|
||||
"icon": "src/assets/vue.png"
|
||||
},
|
||||
"version": "1.6.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"start": "concurrently \"npm run serve\" \"wait-on http://localhost:8964 && nw .\"",
|
||||
"serve": "vue-cli-service serve --port=8964",
|
||||
"build": "npm run build:clean && npm run build:vue && npm run build:nw",
|
||||
"build:clean": "rimraf ./dist-vue ./dist",
|
||||
"build:vue": "vue-cli-service build --modern --dest ./dist-vue",
|
||||
"build:nw": "build --concurrent --tasks win-x86,linux-x86,linux-x64,mac-x64 --mirror https://dl.nwjs.io/ .",
|
||||
"build:win": "npm run build:win:clean && npm run build:vue && build --tasks win-x86 --mirror https://dl.nwjs.io/ .",
|
||||
"build:lin": "npm run build:lin:clean && npm run build:vue && build --tasks linux-x64 --mirror https://dl.nwjs.io/ .",
|
||||
"build:win:clean": "rimraf ./dist-vue ./dist/nw-vue-1.1.0-win-x86 ./dist/nw-vue-1.1.0-win-x86.zip ./dist/nw-vue-1.1.0-win-x86.7z ./dist/nw-vue-1.1.0-win-x86-Setup.exe",
|
||||
"build:lin:clean": "rimraf ./dist-vue ./dist/nw-vue-1.1.0-linux-x64 ./dist/nw-vue-1.1.0-linux-x64.zip",
|
||||
"run:win": "dist\\nw-vue-1.1.0-win-x86\\nw-vue.exe",
|
||||
"run:lin": "./dist/nw-vue-1.1.0-linux-x64/nw-vue",
|
||||
"regression": "rd /s /q node_modules & rd /s /q node_modules & rd /s /q node_modules & npm install && npm run lint && npm test && npm run build:win && npm run run:win",
|
||||
"lint": "vue-cli-service lint --no-fix",
|
||||
"fix": "vue-cli-service lint --fix",
|
||||
"test": "npm run test:unit",
|
||||
"test:unit": "jest --config jest.config.js --coverage",
|
||||
"test:e2e": "vue-cli-service test:e2e",
|
||||
"test:unit": "jest --config jest.config.js --coverage --runInBand",
|
||||
"validate": "npm run lint && npm run test:unit && npm run build:vue",
|
||||
"update:vue-devtools": "rimraf ./node_modules/nw-vue-devtools-prebuilt && npm install"
|
||||
"lint": "vue-cli-service lint --no-fix",
|
||||
"build:clean": "rimraf ./dist-vue ./dist",
|
||||
"build:lin": "npm run build:lin:clean && npm run build:vue && build --tasks linux-x64 --mirror https://dl.nwjs.io/ .",
|
||||
"build:lin:clean": "rimraf ./dist-vue ./dist/nw-vue-1.6.0-linux-x64 ./dist/nw-vue-1.6.0-linux-x64.zip",
|
||||
"build:nw": "build --concurrent --tasks win-x86,linux-x86,linux-x64,mac-x64 --mirror https://dl.nwjs.io/ .",
|
||||
"build:vue": "vue-cli-service build --modern --dest ./dist-vue",
|
||||
"build:win": "npm run build:win:clean && npm run build:vue && build --tasks win-x86 --mirror https://dl.nwjs.io/ .",
|
||||
"build:win:clean": "rimraf ./dist-vue ./dist/nw-vue-1.6.0-win-x86 ./dist/nw-vue-1.6.0-win-x86.zip ./dist/nw-vue-1.6.0-win-x86.7z ./dist/nw-vue-1.6.0-win-x86-Setup.exe",
|
||||
"fix": "vue-cli-service lint --fix",
|
||||
"regression": "rd /s /q node_modules & rd /s /q node_modules & rd /s /q node_modules & npm install && npm run lint && npm test && npm run build:win && npm run run:win",
|
||||
"run:lin": "./dist/nw-vue-1.6.0-linux-x64/nw-vue",
|
||||
"run:win": "dist\\nw-vue-1.6.0-win-x86\\nw-vue.exe",
|
||||
"start": "concurrently \"npm run serve\" \"wait-on http://localhost:8964 && nw .\"",
|
||||
"test": "npm run test:unit",
|
||||
"update:vue-devtools": "rimraf ./node_modules/nw-vue-devtools-prebuilt && npm install",
|
||||
"validate": "npm run lint && npm run test:unit && npm run build:vue"
|
||||
},
|
||||
"main": "http://localhost:8964",
|
||||
"dependencies": {
|
||||
"express": "^4.17.1"
|
||||
"bootstrap": "^4.5.0",
|
||||
"bootstrap-vue": "^2.16.0",
|
||||
"express": "^4.17.1",
|
||||
"vue-router": "^3.2.0",
|
||||
"vue-select": "^3.10.7",
|
||||
"vue2-datepicker": "^3.6.1",
|
||||
"vuex": "^3.4.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@vue/cli-plugin-babel": "^4.0.5",
|
||||
"@vue/cli-plugin-e2e-nightwatch": "^4.0.5",
|
||||
"@vue/cli-plugin-eslint": "^4.0.5",
|
||||
"@vue/cli-plugin-unit-jest": "^4.0.5",
|
||||
"@vue/cli-service": "^4.0.5",
|
||||
"@vue/test-utils": "1.0.0-beta.29",
|
||||
"babel-core": "7.0.0-bridge.0",
|
||||
"babel-eslint": "^10.0.3",
|
||||
"babel-jest": "^24.9.0",
|
||||
"babel-plugin-dynamic-import-node": "^2.3.0",
|
||||
"babel-plugin-transform-runtime": "^6.23.0",
|
||||
"babel-preset-env": "^1.7.0",
|
||||
"babel-preset-stage-2": "^6.24.1",
|
||||
"babel-preset-vue-app": "^2.0.0",
|
||||
"concurrently": "^5.0.0",
|
||||
"core-js": "^3.4.0",
|
||||
"eslint": "^6.6.0",
|
||||
"@vue/cli-plugin-babel": "^4.4.6",
|
||||
"@vue/cli-plugin-e2e-nightwatch": "^4.4.6",
|
||||
"@vue/cli-plugin-eslint": "^4.4.6",
|
||||
"@vue/cli-plugin-router": "^4.4.6",
|
||||
"@vue/cli-plugin-unit-jest": "^4.4.6",
|
||||
"@vue/cli-plugin-vuex": "^4.4.6",
|
||||
"@vue/cli-service": "^4.4.6",
|
||||
"@vue/test-utils": "^1.0.3",
|
||||
"babel-eslint": "^10.1.0",
|
||||
"concurrently": "^5.2.0",
|
||||
"core-js": "^3.6.5",
|
||||
"eslint": "^7.4.0",
|
||||
"eslint-config-tjw-base": "^1.0.0",
|
||||
"eslint-config-tjw-vue": "^1.0.0",
|
||||
"eslint-plugin-jest": "^23.0.3",
|
||||
"eslint-plugin-vue": "^6.0.0",
|
||||
"jest": "^24.9.0",
|
||||
"jest-environment-jsdom": "^24.9.0",
|
||||
"jest-environment-jsdom-global": "^1.2.0",
|
||||
"jest-transform-stub": "^2.0.0",
|
||||
"nw": "0.42.3-sdk",
|
||||
"eslint-config-tjw-vue": "^2.0.0",
|
||||
"eslint-plugin-jest": "^23.18.0",
|
||||
"eslint-plugin-vue": "^6.2.2",
|
||||
"eslint-plugin-vuejs-accessibility": "^0.3.1",
|
||||
"jest-serializer-vue-tjw": "^3.14.0",
|
||||
"nw": "0.47.0-sdk",
|
||||
"nw-vue-devtools-prebuilt": "^0.0.10",
|
||||
"nwjs-builder-phoenix": "^1.15.0",
|
||||
"nwjs-types": "^1.0.0",
|
||||
"rimraf": "^3.0.0",
|
||||
"vue": "^2.6.10",
|
||||
"vue-jest": "^3.0.5",
|
||||
"vue-template-compiler": "^2.6.10",
|
||||
"wait-on": "^3.3.0"
|
||||
"rimraf": "^3.0.2",
|
||||
"vue": "^2.6.11",
|
||||
"vue-template-compiler": "^2.6.11",
|
||||
"wait-on": "^5.1.0"
|
||||
},
|
||||
"chromium-args": "--enable-spell-checking --load-extension='./node_modules/nw-vue-devtools-prebuilt/extension'",
|
||||
"ManifestComments": [
|
||||
"Only add dependencies that you want shipped to the end user, for everything else, use devDependencies, including things that will be bundled by webpack.",
|
||||
"NW.js requires a name and a main, everything else is optional.",
|
||||
"The build section is used by nwjs-builder-phoenix, see its documentation for more info",
|
||||
"To turn spell checking off, remove it from the chromium-args in this file"
|
||||
],
|
||||
"build": {
|
||||
"nwVersion": "v0.42.3",
|
||||
"nwVersion": "v0.47.0",
|
||||
"nwFlavor": "normal",
|
||||
"targets": [
|
||||
"zip",
|
||||
@ -103,6 +91,7 @@
|
||||
".gitignore",
|
||||
".editorconfig",
|
||||
"babel.config.js",
|
||||
"CODE_OF_CONDUCT.md",
|
||||
"cypress.json",
|
||||
"jest.config.js",
|
||||
"nightwatch.conf.js",
|
||||
@ -114,6 +103,7 @@
|
||||
"vue.config.js"
|
||||
],
|
||||
"strippedProperties": [
|
||||
"ManifestComments",
|
||||
"scripts",
|
||||
"devDependencies",
|
||||
"build"
|
||||
@ -122,7 +112,14 @@
|
||||
"main": "http://localhost:8965",
|
||||
"node-remote": "http://localhost:8965",
|
||||
"node-main": "server.js",
|
||||
"chromium-args": "--enable-spell-checking"
|
||||
"chromium-args": "--enable-spell-checking",
|
||||
"window": {
|
||||
"width": 960,
|
||||
"height": 600,
|
||||
"min_width": 700,
|
||||
"min_height": 500,
|
||||
"icon": "dist-vue/icon.png"
|
||||
}
|
||||
},
|
||||
"win": {
|
||||
"icon": "public/icon-256.ico"
|
||||
@ -139,5 +136,15 @@
|
||||
"diffUpdaters": false,
|
||||
"hashCalculation": true
|
||||
}
|
||||
},
|
||||
"chromium-args": "--enable-spell-checking --load-extension='./node_modules/nw-vue-devtools-prebuilt/extension'",
|
||||
"node-main": "",
|
||||
"node-remote": "http://localhost:8964",
|
||||
"window": {
|
||||
"width": 960,
|
||||
"height": 600,
|
||||
"min_width": 700,
|
||||
"min_height": 500,
|
||||
"icon": "src/assets/vue.png"
|
||||
}
|
||||
}
|
||||
|
74
src/App.vue
74
src/App.vue
@ -1,41 +1,55 @@
|
||||
<template>
|
||||
<div id="app">
|
||||
<img
|
||||
src="@/assets/vue.png"
|
||||
alt="Vue.js logo"
|
||||
title="Vue.js"
|
||||
class="logo"
|
||||
/>
|
||||
<img
|
||||
src="@/assets/nw.png"
|
||||
alt="NW.js logo"
|
||||
title="NW.js"
|
||||
class="logo"
|
||||
/>
|
||||
<HelloWorld msg="Welcome to your Vue.js Desktop App in NW.js!" />
|
||||
<b-navbar toggleable="lg" type="dark" variant="info">
|
||||
<b-button class="mr-4" v-b-toggle.sidebar>Menu</b-button>
|
||||
<b-navbar-brand href="#">NavBar</b-navbar-brand>
|
||||
</b-navbar>
|
||||
<b-sidebar id="sidebar" title="Main Menu">
|
||||
<div class="px-3 py-2">
|
||||
<b-list-group>
|
||||
<b-list-group-item href="/#/">
|
||||
Hours Log
|
||||
</b-list-group-item>
|
||||
<b-list-group-item href="/#/projects">
|
||||
Projects
|
||||
</b-list-group-item>
|
||||
</b-list-group>
|
||||
<div class="dropdown-divider"></div>
|
||||
<b-list-group class="">
|
||||
<b-list-group-item href="/">
|
||||
Exports
|
||||
</b-list-group-item>
|
||||
<b-list-group-item href="/">
|
||||
Settings
|
||||
</b-list-group-item>
|
||||
</b-list-group>
|
||||
</div>
|
||||
</b-sidebar>
|
||||
<div id="nav">
|
||||
</div>
|
||||
<router-view />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import HelloWorld from '@/components/HelloWorld.vue';
|
||||
|
||||
export default {
|
||||
name: 'App',
|
||||
components: {
|
||||
HelloWorld
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style>
|
||||
#app {
|
||||
margin-top: 60px;
|
||||
color: #2C3E50;
|
||||
font-family: 'Avenir', sans-serif;
|
||||
font-family: Avenir, Helvetica, Arial, sans-serif;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
text-align: center;
|
||||
color: #2c3e50;
|
||||
}
|
||||
.logo {
|
||||
max-height: 140px;
|
||||
margin: 0px 10px;
|
||||
|
||||
#nav {
|
||||
padding: 30px;
|
||||
}
|
||||
|
||||
#nav a {
|
||||
font-weight: bold;
|
||||
color: #2c3e50;
|
||||
}
|
||||
|
||||
#nav a.router-link-exact-active {
|
||||
color: #42b983;
|
||||
}
|
||||
</style>
|
||||
|
Before Width: | Height: | Size: 6.7 KiB After Width: | Height: | Size: 6.7 KiB |
19
src/main.js
19
src/main.js
@ -1,10 +1,29 @@
|
||||
import Vue from 'vue';
|
||||
import { BootstrapVue, IconsPlugin } from 'bootstrap-vue'
|
||||
import vSelect from 'vue-select'
|
||||
import DatePicker from 'vue2-datepicker'
|
||||
|
||||
import 'bootstrap/dist/css/bootstrap.css'
|
||||
import 'bootstrap-vue/dist/bootstrap-vue.css'
|
||||
import 'vue-select/dist/vue-select.css'
|
||||
import 'vue2-datepicker/index.css'
|
||||
|
||||
import App from './App.vue';
|
||||
import router from './router';
|
||||
import store from './store';
|
||||
|
||||
Vue.use(BootstrapVue)
|
||||
Vue.use(IconsPlugin)
|
||||
Vue.component('v-select', vSelect)
|
||||
Vue.component('date-picker', DatePicker)
|
||||
|
||||
Vue.config.productionTip = false;
|
||||
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
const app = new Vue({
|
||||
router,
|
||||
store,
|
||||
|
||||
render: function (hyperscript) {
|
||||
return hyperscript(App);
|
||||
}
|
||||
|
31
src/router/index.js
Normal file
31
src/router/index.js
Normal file
@ -0,0 +1,31 @@
|
||||
import Vue from 'vue';
|
||||
import VueRouter from 'vue-router';
|
||||
import HoursLog from '../views/HoursLog.vue';
|
||||
import TimeEntry from '../views/TimeEntry.vue';
|
||||
import Projects from '../views/Projects.vue'
|
||||
|
||||
Vue.use(VueRouter);
|
||||
|
||||
const routes = [
|
||||
{
|
||||
path: '/',
|
||||
name: 'HoursLog',
|
||||
component: HoursLog
|
||||
},
|
||||
{
|
||||
path: '/add-time-entry',
|
||||
name: 'TimeEntry',
|
||||
component: TimeEntry
|
||||
},
|
||||
{
|
||||
path: '/projects',
|
||||
name: 'Projects',
|
||||
component: Projects
|
||||
},
|
||||
];
|
||||
|
||||
const router = new VueRouter({
|
||||
routes
|
||||
});
|
||||
|
||||
export default router;
|
15
src/store/index.js
Normal file
15
src/store/index.js
Normal file
@ -0,0 +1,15 @@
|
||||
import Vue from 'vue';
|
||||
import Vuex from 'vuex';
|
||||
|
||||
Vue.use(Vuex);
|
||||
|
||||
export default new Vuex.Store({
|
||||
state: {
|
||||
},
|
||||
mutations: {
|
||||
},
|
||||
actions: {
|
||||
},
|
||||
modules: {
|
||||
}
|
||||
});
|
46
src/views/HoursLog.vue
Normal file
46
src/views/HoursLog.vue
Normal file
@ -0,0 +1,46 @@
|
||||
<template>
|
||||
<b-container class="hours-log-page">
|
||||
<b-row>
|
||||
<b-col cm="8" offset-sm="2">
|
||||
<b-row class="mt-5 mb-4 ">
|
||||
<b-col>
|
||||
<h1>Hours Log</h1>
|
||||
</b-col>
|
||||
<b-col>
|
||||
<b-btn variant="primary" @click="$router.push({name: 'TimeEntry'})">
|
||||
+ Add Entry
|
||||
</b-btn>
|
||||
</b-col>
|
||||
</b-row>
|
||||
<b-row>
|
||||
<b-col>
|
||||
<b-table striped hover :items="items"></b-table>
|
||||
</b-col>
|
||||
</b-row>
|
||||
</b-col>
|
||||
</b-row>
|
||||
</b-container>
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// @ is an alias to /src
|
||||
|
||||
export default {
|
||||
name: 'HoursLog',
|
||||
components: {
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
items: [
|
||||
{
|
||||
project_name: 'Company #1',
|
||||
date: 'May 12, 2020',
|
||||
start_time: '7:00 am',
|
||||
end_time: '11:00',
|
||||
},
|
||||
]
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
39
src/views/Projects.vue
Normal file
39
src/views/Projects.vue
Normal file
@ -0,0 +1,39 @@
|
||||
<template>
|
||||
<b-container class="projects-page">
|
||||
<b-row>
|
||||
<b-col cm="8" offset-sm="2">
|
||||
<b-row class="mt-5 mb-4 ">
|
||||
<b-col>
|
||||
<h1>Projects</h1>
|
||||
</b-col>
|
||||
<b-col>
|
||||
<b-btn variant="primary">+ Add New Project</b-btn>
|
||||
</b-col>
|
||||
</b-row>
|
||||
|
||||
<b-row>
|
||||
<b-col>
|
||||
<v-select
|
||||
:options="[{label: 'Canada', code: 'ca'}]"
|
||||
/>
|
||||
</b-col>
|
||||
</b-row>
|
||||
</b-col>
|
||||
</b-row>
|
||||
</b-container>
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// @ is an alias to /src
|
||||
|
||||
export default {
|
||||
name: 'Projects',
|
||||
components: {
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
56
src/views/TimeEntry.vue
Normal file
56
src/views/TimeEntry.vue
Normal file
@ -0,0 +1,56 @@
|
||||
<template>
|
||||
<b-container class="time-entry-page">
|
||||
<b-row>
|
||||
<b-col sm="6" offset-sm="3">
|
||||
<b-row>
|
||||
<b-col>
|
||||
<h1>New Time Entry</h1>
|
||||
</b-col>
|
||||
</b-row>
|
||||
<b-row>
|
||||
<b-col>
|
||||
<b-form @submit="onSubmit" @reset="onReset">
|
||||
<b-form-group id="input-group-1" label="Star Date:" label-for="input-1">
|
||||
<date-picker v-model="formData.startDate" type="datetime" />
|
||||
</b-form-group>
|
||||
|
||||
<b-form-group id="input-group-2" label="End Date:" label-for="input-2">
|
||||
<date-picker v-model="formData.endDate" type="datetime" />
|
||||
</b-form-group>
|
||||
<b-button type="submit" variant="primary">Submit</b-button>
|
||||
<b-button type="reset" variant="danger">Reset</b-button>
|
||||
</b-form>
|
||||
</b-col>
|
||||
</b-row>
|
||||
</b-col>
|
||||
</b-row>
|
||||
</b-container>
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// @ is an alias to /src
|
||||
|
||||
export default {
|
||||
name: 'TimeEntry',
|
||||
components: {
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
formData: {
|
||||
startDate: {},
|
||||
endDate: {},
|
||||
notes: '',
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
onSubmit() {
|
||||
|
||||
},
|
||||
onReset() {
|
||||
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
@ -5,7 +5,7 @@ describe('App.vue', () => {
|
||||
test('Render default contents', () => {
|
||||
const wrapper = shallowMount(App);
|
||||
|
||||
expect(wrapper.html())
|
||||
expect(wrapper)
|
||||
.toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
exports[`App.vue Render default contents 1`] = `
|
||||
<div id="app">
|
||||
<img src="@/assets/vue.png" alt="Vue.js logo" title="Vue.js" class="logo">
|
||||
<img src="@/assets/logo.png" alt="Vue.js logo" title="Vue.js" class="logo">
|
||||
<img src="@/assets/nw.png" alt="NW.js logo" title="NW.js" class="logo">
|
||||
<helloworld-stub msg="Welcome to your Vue.js Desktop App in NW.js!"></helloworld-stub>
|
||||
</div>
|
||||
|
@ -5,23 +5,25 @@ describe('FsExample.vue', () => {
|
||||
test('Render default contents', () => {
|
||||
const wrapper = shallowMount(FsExample);
|
||||
|
||||
expect(wrapper.html())
|
||||
expect(wrapper)
|
||||
.toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('Click button', () => {
|
||||
test('Click button', async () => {
|
||||
const wrapper = shallowMount(FsExample);
|
||||
let domButton = wrapper.find('[data-test="fs-example-button"]');
|
||||
domButton.trigger('click');
|
||||
|
||||
await wrapper.vm.$nextTick();
|
||||
|
||||
expect(window.nw.require)
|
||||
.toHaveBeenCalledWith('fs');
|
||||
|
||||
expect(wrapper.html())
|
||||
expect(wrapper)
|
||||
.toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('Error state', () => {
|
||||
test('Error state', async () => {
|
||||
window.nw.require.mockImplementation((module) => {
|
||||
if (module === 'fs') {
|
||||
return new Error();
|
||||
@ -32,10 +34,12 @@ describe('FsExample.vue', () => {
|
||||
let domButton = wrapper.find('[data-test="fs-example-button"]');
|
||||
domButton.trigger('click');
|
||||
|
||||
await wrapper.vm.$nextTick();
|
||||
|
||||
expect(window.nw.require)
|
||||
.toHaveBeenCalledWith('fs');
|
||||
|
||||
expect(wrapper.html())
|
||||
expect(wrapper)
|
||||
.toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
|
@ -15,23 +15,23 @@ describe('HelloWorld.vue', () => {
|
||||
test('Render default contents', () => {
|
||||
const wrapper = mount(HelloWorld);
|
||||
|
||||
expect(wrapper.html())
|
||||
expect(wrapper)
|
||||
.toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('Activate dev tools', () => {
|
||||
test('Activate dev tools', async () => {
|
||||
const wrapper = shallowMount(HelloWorld);
|
||||
|
||||
const button = wrapper.find('[data-test="toggleDevTools"]');
|
||||
|
||||
button.trigger('click');
|
||||
wrapper.vm.$nextTick();
|
||||
await wrapper.vm.$nextTick();
|
||||
|
||||
expect(wrapper.find('[data-test="toggleDevTools').html())
|
||||
.toMatchSnapshot('hide');
|
||||
|
||||
button.trigger('click');
|
||||
wrapper.vm.$nextTick();
|
||||
await wrapper.vm.$nextTick();
|
||||
|
||||
expect(wrapper.find('[data-test="toggleDevTools').html())
|
||||
.toMatchSnapshot('show');
|
||||
|
@ -32,7 +32,7 @@ describe('LinkList.vue', () => {
|
||||
propsData: { links: [link] }
|
||||
});
|
||||
|
||||
expect(wrapper.html())
|
||||
expect(wrapper)
|
||||
.toMatchSnapshot();
|
||||
});
|
||||
|
||||
|
@ -23,11 +23,11 @@ exports[`HelloWorld.vue Render default contents 1`] = `
|
||||
</h1>
|
||||
<h3>
|
||||
You are using
|
||||
Vue.js (v2.6.10),
|
||||
NW.js (v0.42.3-sdk),
|
||||
Node.js (v13.1.0),
|
||||
Vue.js (v2.6.11),
|
||||
NW.js (v0.47.0-sdk),
|
||||
Node.js (v14.5.0),
|
||||
and
|
||||
Chromium (v78.0.3904.97).
|
||||
Chromium (v84.0.4147.89).
|
||||
</h3>
|
||||
<button>
|
||||
Show
|
||||
|
@ -1,42 +0,0 @@
|
||||
// Based on jest-serializer-vue
|
||||
|
||||
const beautify = require('pretty');
|
||||
|
||||
function isHtmlString (received) {
|
||||
return received && typeof(received) === 'string' && received.startsWith('<');
|
||||
}
|
||||
|
||||
function isVueWrapper (received) {
|
||||
return received && typeof(received) === 'object' && typeof(received.isVueInstance) === 'function';
|
||||
}
|
||||
|
||||
// This removes data-test="whatever" from your snapshots
|
||||
// If you also want to remove them from your production builds, see:
|
||||
// https://forum.vuejs.org/t/how-to-remove-attributes-from-tags-inside-vue-components/24138
|
||||
function removeDataTestAttributes (html) {
|
||||
// [-\w]+ will catch 1 or more instaces of a-z, A-Z, 0-9, hyphen (-), or underscore (_)
|
||||
return html.replace(/ data-test="[-\w]+"/g, '');
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
test: function (received) {
|
||||
return isHtmlString(received) || isVueWrapper(received);
|
||||
},
|
||||
print: function (received) {
|
||||
let html = received || '';
|
||||
if (isVueWrapper(received)) {
|
||||
html = received.html();
|
||||
}
|
||||
html = removeDataTestAttributes(html);
|
||||
// To see available options: https://github.com/beautify-web/js-beautify/blob/master/js/src/html/options.js
|
||||
const options = {
|
||||
indent_size: 2,
|
||||
unformatted: ['code', 'pre'],
|
||||
inline: [],
|
||||
indent_inner_html: true,
|
||||
indent_char: ' ',
|
||||
sep: '\n'
|
||||
};
|
||||
return beautify(html, options);
|
||||
}
|
||||
};
|
@ -22,14 +22,15 @@ window.getComputedStyle = function getComputedStyleStub (el) {
|
||||
|
||||
global.beforeEach(() => {
|
||||
window.process = {
|
||||
cwd: process.cwd,
|
||||
env: {
|
||||
NODE_ENV: 'development'
|
||||
},
|
||||
versions: {
|
||||
chromium: '78.0.3904.97',
|
||||
nw: '0.42.3',
|
||||
chromium: '84.0.4147.89',
|
||||
nw: '0.47.0',
|
||||
'nw-flavor': 'sdk',
|
||||
node: '13.1.0'
|
||||
node: '14.5.0'
|
||||
}
|
||||
};
|
||||
window.nw = {
|
||||
|
Loading…
Reference in New Issue
Block a user