Compare commits

...

63 Commits

Author SHA1 Message Date
c406c11b88 Commits After Part 1 2020-08-01 14:21:29 -07:00
The Jared Wilcurt
083b450fd3
Update App.test.js.snap 2020-07-24 12:08:57 -04:00
The Jared Wilcurt
105bfa6b66
Rename vue.png to logo.png
This prevents a bug from when you `vue add vue-router`
2020-07-24 10:56:44 -04:00
TheJaredWilcurt
c4a9410e76 Rename vue.png to logo.png
This prevents a bug from when you vue add vue-router
2020-07-24 10:53:50 -04:00
The Jared Wilcurt
0c6fad9828
Rename vue.png to logo.png 2020-07-24 10:44:55 -04:00
The Jared Wilcurt
512a079698
Update package.json 2020-07-16 14:06:11 -04:00
The Jared Wilcurt
0a75ba489a
Update dependencies
* Fix Jest Haste Map
* Update NW.js
* Swap Vue-A11y linter for Vuejs-Accessibility
* Lint
* Update deps
* Remove --runInBand
* Bump to 1.6.0
2020-07-16 13:57:21 -04:00
TheJaredWilcurt
de49954d58 Bump to 1.6.0 2020-07-16 13:37:30 -04:00
TheJaredWilcurt
c5d8775d93 Remove --runInBand 2020-07-16 13:37:17 -04:00
TheJaredWilcurt
e4f83505e0 Update deps 2020-07-16 13:37:01 -04:00
TheJaredWilcurt
2d8aa8b6c7 Lint 2020-07-16 13:36:14 -04:00
TheJaredWilcurt
f3f430ab47 Swap Vue-A11y linter for Vuejs-Accessibility 2020-07-16 13:36:02 -04:00
TheJaredWilcurt
f63522dcf1 Update NW.js 2020-07-16 13:34:54 -04:00
TheJaredWilcurt
3ae1535348 Fix Jest Haste Map 2020-07-16 13:33:30 -04:00
The Jared Wilcurt
812c3a1edd
Update dependencies 2020-02-19 12:49:31 -05:00
TheJaredWilcurt
079f0399fc bump 2020-02-19 12:09:32 -05:00
TheJaredWilcurt
f8d5c7c4f9 remove note 2020-02-19 12:02:57 -05:00
TheJaredWilcurt
e35a2b69fa Updating to Vue-CLI 4.2.2 2020-02-19 12:01:02 -05:00
TheJaredWilcurt
58d0251849 Updating non-vue deps 2020-02-19 12:00:43 -05:00
TheJaredWilcurt
e7c99dade0 Update NW.js 2020-02-19 12:00:03 -05:00
TheJaredWilcurt
ec2853f2b6 fix tests 2020-02-19 11:34:27 -05:00
TheJaredWilcurt
0cbdf6b8a1 Revert to Jest 24.9.0 to avoid bug 2020-02-19 11:19:59 -05:00
The Jared Wilcurt
0a009067ae Update dependencies 2020-01-23 19:43:40 -05:00
The Jared Wilcurt
be3c9e17bc
Jest-Vue-Serializer-TJW 2020-01-19 09:30:45 -05:00
The Jared Wilcurt
bae2d779f7
Update README.md 2020-01-19 09:26:57 -05:00
The Jared Wilcurt
f71fa9d6c7
Update README.md 2020-01-19 09:26:11 -05:00
The Jared Wilcurt
f9a05f42e5 fix build icon 2020-01-19 09:19:54 -05:00
The Jared Wilcurt
5d315f08cb Build bump 2020-01-19 09:01:38 -05:00
The Jared Wilcurt
482cffbb4e bump scripts 2020-01-19 08:43:05 -05:00
The Jared Wilcurt
25c23d161e bump 2020-01-19 08:14:54 -05:00
The Jared Wilcurt
7497fe7a41 Update nw versions 2020-01-19 08:10:06 -05:00
The Jared Wilcurt
446b730430 Add Jest-Serializer-Vue-TJW 2020-01-19 08:04:38 -05:00
The Jared Wilcurt
3db2da197c Update Dependencies 2020-01-19 08:02:52 -05:00
The Jared Wilcurt
714c585f9b
A11Y Lint & Update Dependencies 2019-12-27 00:57:14 -05:00
The Jared Wilcurt
5a8a3aa04c Version bump 2019-12-27 00:53:31 -05:00
The Jared Wilcurt
5a46f07509 fix regression test scripts 2019-12-27 00:01:30 -05:00
The Jared Wilcurt
e08191e92a Update README.md 2019-12-26 23:37:29 -05:00
The Jared Wilcurt
be639705f6 Update deps 2019-12-26 23:11:26 -05:00
The Jared Wilcurt
bb24e425c9 Set up A11y linter 2019-12-26 22:37:19 -05:00
The Jared Wilcurt
c414e832b0 Update dependencies and bump 2019-11-11 19:20:46 -05:00
The Jared Wilcurt
7707eccbf6 Change Vue-DevTools utility 2019-11-11 19:20:23 -05:00
The Jared Wilcurt
9aa0b10e0d
Markdown formatting 2019-11-07 08:42:26 -05:00
The Jared Wilcurt
ec0c68c881
Add command to update Vue-DevTools 2019-11-07 08:37:00 -05:00
The Jared Wilcurt
2250d86bc3
Update README.md 2019-11-07 08:36:21 -05:00
The Jared Wilcurt
c1debf849e
Add MainfestComments 2019-11-07 08:10:09 -05:00
The Jared Wilcurt
5dc3336c4b
Enable spell checking 2019-11-07 08:02:01 -05:00
The Jared Wilcurt
2b43f6444b
Rename CODE_OF_CONDUCT to CODE_OF_CONDUCT.md 2019-10-29 21:57:13 -04:00
The Jared Wilcurt
beb9b92cc0
Rename CODE_OF_CONDUCT.md to CODE_OF_CONDUCT 2019-10-29 21:55:59 -04:00
The Jared Wilcurt
bf9989462f
Create CODE_OF_CONDUCT.md 2019-10-29 21:51:37 -04:00
The Jared Wilcurt
968a1714e7
Update Deps and add FS example 2019-10-29 13:20:44 -04:00
The Jared Wilcurt
b192c65423 Bump npm scripts 2019-10-29 13:14:26 -04:00
The Jared Wilcurt
8d5ef466f8 Update README 2019-10-29 13:12:00 -04:00
The Jared Wilcurt
20e3c5caee Build Status 2019-10-29 13:04:16 -04:00
The Jared Wilcurt
2d4ea6038f Version bump 2019-10-29 13:02:40 -04:00
The Jared Wilcurt
410f795a0d Set up travis 2019-10-29 12:53:13 -04:00
The Jared Wilcurt
c6dc4dbdc7 Update browserslistrc 2019-10-29 12:28:55 -04:00
The Jared Wilcurt
72038ea76c Merge remote-tracking branch 'refs/remotes/origin/master' into updates 2019-10-29 12:27:24 -04:00
The Jared Wilcurt
05f0b399bf Update tests 2019-10-29 12:27:18 -04:00
The Jared Wilcurt
3955b2e342 Add File System Example 2019-10-29 12:27:04 -04:00
The Jared Wilcurt
eb31b843e2 Update Dependencies 2019-10-29 12:25:15 -04:00
The Jared Wilcurt
e64fe15a8f Simplify eslint 2019-10-29 11:55:40 -04:00
The Jared Wilcurt
2a102c742a Linux 86 to 64 2019-10-20 17:37:31 -07:00
The Jared Wilcurt
b7d16c2790 Update manifest and lock file for linux 2019-10-20 16:18:25 -07:00
29 changed files with 6445 additions and 10216 deletions

View File

@ -1 +1 @@
chrome 77
chrome 84

View File

@ -21,167 +21,29 @@ module.exports = {
},
plugins: [
'jest',
// required to lint *.vue files
'vue'
],
extends: [
'eslint:recommended',
'plugin:vue/recommended',
'plugin:jest/recommended'
'plugin:jest/recommended',
'plugin:vuejs-accessibility/recommended',
'tjw-base',
'tjw-vue'
],
rules: {
'arrow-parens': ['off'],
'brace-style': [
'no-restricted-syntax': [
'error',
'1tbs',
{
'allowSingleLine': true
}
'Property[method="true"]'
],
'comma-dangle': ['error', 'never'],
'comma-spacing': [
'vuejs-accessibility/label-has-for': [
'error',
{
'before': false,
'after': true
'components': ['Label'],
'required': {
'some': ['nesting', 'id']
},
'allowChildren': false
}
],
'comma-style': ['error', 'last'],
'curly': ['error'],
// allow async-await
'generator-star-spacing': ['off'],
// 2 space indentation to match .editorconfig
'indent': [
'error',
2,
{
'SwitchCase': 1
}
],
'keyword-spacing': [
'error',
{
'before': true,
'after': true
}
],
// allow debugger during development
'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off',
'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off',
'no-multi-spaces': ['error'],
'no-restricted-syntax': ['error', 'Property[method="true"]'],
'no-unused-vars': ['error'],
'no-undef': ['error'],
// Only allow let and const, no var
'no-var': ['error'],
'object-curly-spacing': ['error', 'always'],
'one-var': ['error', 'never'],
'quotes': ['error', 'single'],
'semi': ['error', 'always'],
'space-before-blocks': ['error', 'always'],
'space-before-function-paren': ['error', 'always'],
'space-in-parens': ['error', 'never'],
'space-infix-ops': ['error'],
'spaced-comment': ['error', 'always'],
// Vue Linter Options
'vue/attribute-hyphenation': ['error', 'never'],
'vue/attributes-order': [
'error',
{
'order': [
// 'v-for item in items'
'LIST_RENDERING',
// 'v-if', 'v-else-if', 'v-else', 'v-show', 'v-cloak'
'CONDITIONALS',
// 'v-once', 'v-pre'
'RENDER_MODIFIERS',
// 'v-model', 'v-bind', ':property="foo"'
'BINDING',
// 'v-text', 'v-html'
'CONTENT',
// 'is'
'DEFINITION',
// 'id'
'GLOBAL',
// 'customProp="foo"', 'class', 'type', 'value' etc
'OTHER_ATTR',
// '@click="functionCall"', 'v-on="event"'
'EVENTS',
// 'slot', 'key', 'ref'
'UNIQUE'
]
}
],
'vue/html-closing-bracket-newline': [
'error',
{
'singleline': 'never',
'multiline': 'always'
}
],
'vue/html-closing-bracket-spacing': [
'error',
{
'startTag': 'never',
'endTag': 'never',
'selfClosingTag': 'always'
}
],
'vue/html-indent': [
'error',
2,
{
'attribute': 1,
'closeBracket': 0
}
],
'vue/html-self-closing': [
'error',
{
'html': {
'void': 'always',
'normal': 'never',
'component': 'always'
}
}
],
'vue/max-attributes-per-line': [
'error',
{
'singleline': 3,
'multiline': {
'max': 1,
'allowFirstLine': false
}
}
],
'vue/name-property-casing': ['error', 'PascalCase'],
'vue/order-in-components': [
'error',
{
'order': [
'el',
'name',
['template', 'render'],
'parent',
'functional',
['delimiters', 'comments'],
['components', 'directives'],
'extends',
'mixins',
'inheritAttrs',
'model',
['props', 'propsData'],
'data',
'methods',
'computed',
'filters',
'watch',
'LIFECYCLE_HOOKS',
'renderError'
]
}
],
'vue/prop-name-casing': ['error', 'camelCase']
]
}
};

9
.travis.yml Normal file
View File

@ -0,0 +1,9 @@
sudo: required
dist: trusty
language: node_js
node_js:
- "10"
install:
- npm install
script:
- npm run validate

55
CODE_OF_CONDUCT.md Normal file
View File

@ -0,0 +1,55 @@
# "No Ideologies" Code of Conduct
The following are the guidelines we expect our community members and maintainers to follow.
* * *
## Terminology and Scope
**What defines a "maintainer"?**
* A maintainer is anyone that interacts with the community on behalf of this project. Amount of code written is not a qualifier. A maintainer may include those who solely help in support roles such as in resolving issues, improving documentation, administrating or moderating forums/chatrooms, or any other non-coding specific roles. Maintainers also include those that are responsible for the building and upkeep of the project.
**What defines a "community member"?**
* Anyone interacting with this project directly, including maintainers.
**What is the scope of these guidelines?**
* These guidelines apply only to this project and forms of communication directly related to it, such as issue trackers, forums, chatrooms, and in person events specific to this project. If a member is violating these guidelines outside of this project or on other platforms, that is beyond our scope and any grievances should be handled on those platforms.
**Discussing the guidelines:**
* Discussions around these guidelines, improving, updating, or altering them, is permitted so long as the discussions do not violate any existing guidelines.
* * *
## Guidelines
### Guidelines for community members
This project is technical in nature and not based around any particular non-technical ideology. As such, communication that is based primarily around ideologies unrelated to the technologies used by this repository are not permitted.
Any discussion or communication that is primarily focused around an ideology, be it about race, gender, politics, religion, or anything else non-technical, is not allowed. Everyone has their own ideological preferences, beliefs, and opinions. We do not seek to marginalize, exclude, or judge anyone for their ideologies. To prevent conflict between those with differing or opposing ideologies, all communication on these subjects are prohibited. Some discussions around these topics may be important, however this project is not the proper channel for these discussions.
### Guidelines for maintainers
* Maintainers must abide by the same rules as all other community members mentioned above. However, in addition, maintainers are held to a higher standard, explained below.
* Maintainers should answer all questions politely.
* If someone is upset or angry about something, it's probably because it's difficult to use, so thank them for bringing it to your attention and address ways to solve the problem. Maintainers should focus on the content of the message, and not on how it was delivered.
* A maintainer should seek to update members when an issue they brought up is resolved.
* * *
## Appropriate response to violations
How to respond to a community member or maintainer violating a guideline.
1. If an issue is created that violates a guideline a maintainer should close and lock the issue, explaining "This issue is in violation of our code of conduct. Please review it before posting again." with a link to this document.
1. If a member repeatedly violates the guidelines established in this document, they should be politely warned that continuing to violate the rules may result in being banned from the community. This means revoking access and support to interactions relating directly to the project (issue trackers, chatrooms, forums, in person events, etc.). However, they may continue to use the technology in accordance with its license.
1. If a maintainer is in violation of a guideline, they should be informed of such with a link to this document. If additional actions are required of the maintainer but not taken, then other maintainers should be informed of these inactions.
1. If a maintainer repeatedly violates the guidelines established in this document, they should be politely warned that continuing to violate the rules may result in being banned from the community. This means revoking access and support to interactions relating directly to the project (issue trackers, chatrooms, forums, in person events, etc.). However, they may continue to use the technology in accordance with its license. In addition, future contributions to this project may be ignored as well.
* * *
Based on version 1.0.3 from https://github.com/CodifiedConduct/coc-no-ideologies

View File

@ -1,24 +1,35 @@
# nw-vue-cli-example
NW.js + Vue-CLI 3 example
[![Build Status](https://travis-ci.org/nwutils/nw-vue-cli-example.svg?branch=master)](https://travis-ci.org/nwutils/nw-vue-cli-example)
NW.js + Vue-CLI 4 example
![A screenshot of the default app running on Windows](screenshot.png)
* NW.js
* Vue-CLI 3
* Vue 2
* Vue-DevTools
* 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 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
@ -31,7 +42,7 @@ NW.js + Vue-CLI 3 example
# **IMPORTANT NOTE ABOUT BUILDS!!!**
They take a long time. If you do `npm run build` expect it to take 10-30 minutes (depending on amount of dependencies in the dist and your CPU/internet). This can be adjusted by changing the build params in the `package.json`. The more platforms and build types, the longer it takes.
They take a long time. If you do `npm run build` expect it to take 10-30 minutes. This can be adjusted by changing the build params in the `package.json`. The more platforms and build types, the longer it takes. You can also remove the `--concurrent` from the `build:nw` script to see a status of what has been completed. This will allow individual pieces to finish faster, but the entire build will take longer.
## Automated quality enforcment
@ -51,6 +62,16 @@ Want Vue-Router? Vuex? Use the Vue-CLI to add them:
* * *
## Updating Vue-DevTools
To update your version of Vue-DevTools run `npm run update:vue-devtools`.
This will download the source code for the latest version of Vue-DevTools and do a custom build for NW.js. This ensures you always have the latest version.
* * *
## Alternatives
* [nwjs-vue](https://github.com/elegantweb/nwjs-vue) - Uses Vue-CLI 2
@ -65,7 +86,10 @@ Want Vue-Router? Vuex? Use the Vue-CLI to add them:
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:
* `tests/unit/setup.js`
* `tests/unit/components/__snapshots__/HelloWorld.test.js.snap`
* `.browserslistrc`
* `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

View File

@ -1,5 +1,5 @@
module.exports = {
presets: [
'@vue/app'
'@vue/cli-plugin-babel/preset'
]
};

View File

@ -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'
]
};

View File

@ -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;

15663
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,73 +1,75 @@
{
"name": "nw-vue",
"version": "1.0.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:win:clean": "rimraf ./dist-vue ./dist/nw-vue-1.0.0-win-x86 ./dist/nw-vue-1.0.0-win-x86.zip ./dist/nw-vue-1.0.0-win-x86.7z ./dist/nw-vue-1.0.0-win-x86-Setup.exe",
"run:win": "dist\\nw-vue-1.0.0-win-x86\\nw-vue.exe",
"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"
"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": "^3.11.0",
"@vue/cli-plugin-e2e-nightwatch": "^3.11.0",
"@vue/cli-plugin-eslint": "^3.11.0",
"@vue/cli-plugin-unit-jest": "^3.11.0",
"@vue/cli-service": "^3.11.0",
"@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": "^4.1.2",
"core-js": "^2.6.5",
"eslint": "^6.4.0",
"eslint-plugin-jest": "^22.17.0",
"eslint-plugin-vue": "^5.2.3",
"jest": "^24.9.0",
"jest-environment-jsdom-global": "^1.2.0",
"jest-transform-stub": "^2.0.0",
"nw": "0.41.1-sdk",
"nw-vue-devtools": "^1.3.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": "^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": "--load-extension='./node_modules/nw-vue-devtools/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.41.1",
"nwVersion": "v0.47.0",
"nwFlavor": "normal",
"targets": [
"zip",
@ -89,6 +91,7 @@
".gitignore",
".editorconfig",
"babel.config.js",
"CODE_OF_CONDUCT.md",
"cypress.json",
"jest.config.js",
"nightwatch.conf.js",
@ -100,7 +103,7 @@
"vue.config.js"
],
"strippedProperties": [
"chromium-args",
"ManifestComments",
"scripts",
"devDependencies",
"build"
@ -108,7 +111,15 @@
"overriddenProperties": {
"main": "http://localhost:8965",
"node-remote": "http://localhost:8965",
"node-main": "server.js"
"node-main": "server.js",
"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"
@ -125,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"
}
}

View File

@ -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>

View File

Before

Width:  |  Height:  |  Size: 6.7 KiB

After

Width:  |  Height:  |  Size: 6.7 KiB

View File

@ -0,0 +1,85 @@
<template>
<div>
<div v-if="error">
There was an error attempting to read from the file system.
</div>
<button
data-test="fs-example-button"
@click="getCurrentDirectory"
>
<template v-if="!error">
Click for File System example
</template>
<template v-else>
Try again for File System example
</template>
</button>
<template v-if="contents">
<p>
The contents of the current working directory:
</p>
<div class="contents">
<div
v-for="(file, fileIndex) in contents"
class="file"
:key="'file' + fileIndex"
>
{{ file }}
</div>
</div>
</template>
</div>
</template>
<script>
export default {
name: 'FsExample',
data: function () {
return {
contents: null,
error: false
};
},
methods: {
getCurrentDirectory: function () {
const fs = window.nw.require('fs');
try {
this.contents = fs.readdirSync('.');
this.error = false;
} catch (err) {
this.error = true;
}
}
},
computed: {}
};
</script>
<style scoped>
button {
background: linear-gradient(0deg, #2EB277, #65E6AC);
border-width: 3.4px;
border-color: #35495E;
border-radius: 8px;
margin: 22px 0px 6px 0px;
padding: 11px 17px;
color: #050709;
font-family: 'Trebuchet MS', Verdana, sans-serif;
font-size: 16px;
font-weight: bold;
}
.contents {
display: flex;
flex-flow: wrap;
}
.file {
flex-grow: 1;
min-width: 200px;
background: #DDD;
margin: 5px;
padding: 11px;
}
</style>

View File

@ -37,17 +37,23 @@
<h3>Ecosystem</h3>
<LinkList :links="ecosystemLinks" />
<hr />
<FsExample />
</div>
</template>
<script>
import Vue from 'vue';
import FsExample from '@/components/FsExample.vue';
import LinkList from '@/components/LinkList.vue';
export default {
name: 'HelloWorld',
components: {
FsExample,
LinkList
},
props: {
@ -157,7 +163,7 @@ export default {
},
computed: {
devMode: function () {
return window.process.env.NODE_ENV === 'development';
return window.process.versions['nw-flavor'] === 'sdk';
},
versions: function () {
return window.process.versions;

View File

@ -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
View 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
View 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
View 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
View 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
View 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>

View File

@ -5,7 +5,7 @@ describe('App.vue', () => {
test('Render default contents', () => {
const wrapper = shallowMount(App);
expect(wrapper.html())
expect(wrapper)
.toMatchSnapshot();
});
});

View File

@ -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>

View File

@ -0,0 +1,45 @@
import { shallowMount } from '@vue/test-utils';
import FsExample from '@/components/FsExample.vue';
describe('FsExample.vue', () => {
test('Render default contents', () => {
const wrapper = shallowMount(FsExample);
expect(wrapper)
.toMatchSnapshot();
});
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)
.toMatchSnapshot();
});
test('Error state', async () => {
window.nw.require.mockImplementation((module) => {
if (module === 'fs') {
return new Error();
}
});
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)
.toMatchSnapshot();
});
});

View File

@ -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');

View File

@ -32,7 +32,7 @@ describe('LinkList.vue', () => {
propsData: { links: [link] }
});
expect(wrapper.html())
expect(wrapper)
.toMatchSnapshot();
});

View File

@ -0,0 +1,43 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`FsExample.vue Click button 1`] = `
<div>
<!---->
<button>
Click for File System example
</button>
<p>
The contents of the current working directory:
</p>
<div class="contents">
<div class="file">
example-file-1.ext
</div>
<div class="file">
example-file-2.ext
</div>
</div>
</div>
`;
exports[`FsExample.vue Error state 1`] = `
<div>
<div>
There was an error attempting to read from the file system.
</div>
<button>
Try again for File System example
</button>
<!---->
</div>
`;
exports[`FsExample.vue Render default contents 1`] = `
<div>
<!---->
<button>
Click for File System example
</button>
<!---->
</div>
`;

View File

@ -23,11 +23,11 @@ exports[`HelloWorld.vue Render default contents 1`] = `
</h1>
<h3>
You are using
Vue.js (v2.6.10),
NW.js (v0.41.1-sdk),
Node.js (v12.9.1),
Vue.js (v2.6.11),
NW.js (v0.47.0-sdk),
Node.js (v14.5.0),
and
Chromium (v77.0.3865.75).
Chromium (v84.0.4147.89).
</h3>
<button>
Show
@ -141,5 +141,13 @@ exports[`HelloWorld.vue Render default contents 1`] = `
</a>
</li>
</ul>
<hr>
<div>
<!---->
<button>
Click for File System example
</button>
<!---->
</div>
</div>
`;

View File

@ -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);
}
};

View File

@ -22,17 +22,27 @@ window.getComputedStyle = function getComputedStyleStub (el) {
global.beforeEach(() => {
window.process = {
cwd: process.cwd,
env: {
NODE_ENV: 'development'
},
versions: {
chromium: '77.0.3865.75',
nw: '0.41.1',
chromium: '84.0.4147.89',
nw: '0.47.0',
'nw-flavor': 'sdk',
node: '12.9.1'
node: '14.5.0'
}
};
window.nw = {
require: jest.fn((module) => {
if (module === 'fs') {
return {
readdirSync: jest.fn(() => {
return ['example-file-1.ext', 'example-file-2.ext'];
})
};
}
}),
Shell: {
openExternal: jest.fn()
},