0
0
Fork 0

Formatted project

This commit is contained in:
Joan Sanchez 2022-03-24 14:57:11 +01:00
parent ecdb785abb
commit c29a51fc48
50 changed files with 35473 additions and 35606 deletions

View File

@ -3,7 +3,7 @@ root = true
[*] [*]
charset = utf-8 charset = utf-8
indent_style = space indent_style = space
indent_size = 2 indent_size = 4
end_of_line = lf end_of_line = lf
insert_final_newline = true insert_final_newline = true
trim_trailing_whitespace = true trim_trailing_whitespace = true

View File

@ -1,80 +1,78 @@
module.exports = { module.exports = {
// https://eslint.org/docs/user-guide/configuring#configuration-cascading-and-hierarchy // https://eslint.org/docs/user-guide/configuring#configuration-cascading-and-hierarchy
// This option interrupts the configuration hierarchy at this file // This option interrupts the configuration hierarchy at this file
// Remove this if you have an higher level ESLint config file (it usually happens into a monorepos) // Remove this if you have an higher level ESLint config file (it usually happens into a monorepos)
root: true, root: true,
parserOptions: { parserOptions: {
parser: '@babel/eslint-parser', parser: '@babel/eslint-parser',
ecmaVersion: 2018, // Allows for the parsing of modern ECMAScript features ecmaVersion: 2020, // Allows for the parsing of modern ECMAScript features
sourceType: 'module' // Allows for the use of imports sourceType: 'module', // Allows for the use of imports
},
env: {
browser: true
},
// Rules order is important, please avoid shuffling them
extends: [
// Base ESLint recommended rules
// 'eslint:recommended',
// Uncomment any of the lines below to choose desired strictness,
// but leave only one uncommented!
// See https://eslint.vuejs.org/rules/#available-rules
'plugin:vue/vue3-essential', // Priority A: Essential (Error Prevention)
// 'plugin:vue/vue3-strongly-recommended', // Priority B: Strongly Recommended (Improving Readability)
// 'plugin:vue/vue3-recommended', // Priority C: Recommended (Minimizing Arbitrary Choices and Cognitive Overhead)
// https://github.com/prettier/eslint-config-prettier#installation
// usage with Prettier, provided by 'eslint-config-prettier'.
'prettier'
],
plugins: [
// https://eslint.vuejs.org/user-guide/#why-doesn-t-it-work-on-vue-files
// required to lint *.vue files
'vue',
// https://github.com/typescript-eslint/typescript-eslint/issues/389#issuecomment-509292674
// Prettier has not been included as plugin to avoid performance impact
// add it as an extension for your IDE
],
globals: {
ga: 'readonly', // Google Analytics
cordova: 'readonly',
__statics: 'readonly',
__QUASAR_SSR__: 'readonly',
__QUASAR_SSR_SERVER__: 'readonly',
__QUASAR_SSR_CLIENT__: 'readonly',
__QUASAR_SSR_PWA__: 'readonly',
process: 'readonly',
Capacitor: 'readonly',
chrome: 'readonly',
defineProps: 'readonly', // Vue SFC setup compiler macro
defineEmits: 'readonly', // Vue SFC setup compiler macro
defineExpose: 'readonly' // Vue SFC setup compiler macro
},
// add your custom rules here
rules: {
'prefer-promise-reject-errors': 'off',
// allow debugger during development only
'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off'
},
overrides: [
{
files: ['**/*.spec.{js,ts}'],
extends: [
// Add Cypress-specific lint rules, globals and Cypress plugin
// See https://github.com/cypress-io/eslint-plugin-cypress#rules
'plugin:cypress/recommended',
],
}, },
],
} env: {
browser: true,
},
// Rules order is important, please avoid shuffling them
extends: [
// Base ESLint recommended rules
'eslint:recommended',
// Uncomment any of the lines below to choose desired strictness,
// but leave only one uncommented!
// See https://eslint.vuejs.org/rules/#available-rules
//'plugin:vue/vue3-essential', // Priority A: Essential (Error Prevention)
'plugin:vue/vue3-strongly-recommended', // Priority B: Strongly Recommended (Improving Readability)
// 'plugin:vue/vue3-recommended', // Priority C: Recommended (Minimizing Arbitrary Choices and Cognitive Overhead)
// https://github.com/prettier/eslint-config-prettier#installation
// usage with Prettier, provided by 'eslint-config-prettier'.
'prettier',
],
plugins: [
// https://eslint.vuejs.org/user-guide/#why-doesn-t-it-work-on-vue-files
// required to lint *.vue files
'vue',
// https://github.com/typescript-eslint/typescript-eslint/issues/389#issuecomment-509292674
// Prettier has not been included as plugin to avoid performance impact
// add it as an extension for your IDE
],
globals: {
ga: 'readonly', // Google Analytics
cordova: 'readonly',
__statics: 'readonly',
__QUASAR_SSR__: 'readonly',
__QUASAR_SSR_SERVER__: 'readonly',
__QUASAR_SSR_CLIENT__: 'readonly',
__QUASAR_SSR_PWA__: 'readonly',
process: 'readonly',
Capacitor: 'readonly',
chrome: 'readonly',
defineProps: 'readonly', // Vue SFC setup compiler macro
defineEmits: 'readonly', // Vue SFC setup compiler macro
defineExpose: 'readonly', // Vue SFC setup compiler macro
},
// add your custom rules here
rules: {
'prefer-promise-reject-errors': 'off',
// allow debugger during development only
'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off',
},
overrides: [
{
files: ['**/*.spec.{js,ts}'],
extends: [
// Add Cypress-specific lint rules, globals and Cypress plugin
// See https://github.com/cypress-io/eslint-plugin-cypress#rules
'plugin:cypress/recommended',
],
},
],
};

View File

@ -2,8 +2,8 @@
// https://github.com/michael-ciniawsky/postcss-load-config // https://github.com/michael-ciniawsky/postcss-load-config
module.exports = { module.exports = {
plugins: [ plugins: [
// to edit target browsers: use "browserslist" field in package.json // to edit target browsers: use "browserslist" field in package.json
require('autoprefixer') require('autoprefixer'),
] ],
} };

7
.prettierrc.js Normal file
View File

@ -0,0 +1,7 @@
module.exports = {
singleQuote: true,
printWidth: 120,
tabWidth: 4,
semi: true,
endOfLine: 'auto',
};

View File

@ -1,15 +1,15 @@
{ {
"recommendations": [ "recommendations": [
"dbaeumer.vscode-eslint", "dbaeumer.vscode-eslint",
"esbenp.prettier-vscode", "esbenp.prettier-vscode",
"editorconfig.editorconfig", "editorconfig.editorconfig",
"johnsoncodehk.volar", "johnsoncodehk.volar",
"wayou.vscode-todo-highlight" "wayou.vscode-todo-highlight"
], ],
"unwantedRecommendations": [ "unwantedRecommendations": [
"octref.vetur", "octref.vetur",
"hookyqr.beautify", "hookyqr.beautify",
"dbaeumer.jshint", "dbaeumer.jshint",
"ms-vscode.vscode-typescript-tslint-plugin" "ms-vscode.vscode-typescript-tslint-plugin"
] ]
} }

35
.vscode/settings.json vendored
View File

@ -1,24 +1,15 @@
{ {
"editor.bracketPairColorization.enabled": true, "editor.bracketPairColorization.enabled": true,
"editor.guides.bracketPairs": true, "editor.guides.bracketPairs": true,
"editor.formatOnSave": true, "editor.formatOnSave": true,
"editor.defaultFormatter": "esbenp.prettier-vscode", "editor.defaultFormatter": "johnsoncodehk.volar",
"editor.codeActionsOnSave": [ "editor.codeActionsOnSave": ["source.fixAll.eslint"],
"source.fixAll.eslint" "eslint.validate": ["javascript", "javascriptreact", "typescript", "vue"],
], "jest.jestCommandLine": "jest",
"eslint.validate": [ "json.schemas": [
"javascript", {
"javascriptreact", "fileMatch": ["cypress.json"],
"typescript", "url": "https://on.cypress.io/cypress.schema.json"
"vue" }
], ]
"jest.jestCommandLine": "jest",
"json.schemas": [
{
"fileMatch": [
"cypress.json"
],
"url": "https://on.cypress.io/cypress.schema.json"
}
]
} }

View File

@ -3,6 +3,7 @@
Salix front-end Salix front-end
## Install the dependencies ## Install the dependencies
```bash ```bash
yarn yarn
# or # or
@ -10,32 +11,33 @@ npm install
``` ```
### Start the app in development mode (hot-code reloading, error reporting, etc.) ### Start the app in development mode (hot-code reloading, error reporting, etc.)
```bash ```bash
quasar dev quasar dev
``` ```
### Lint the files ### Lint the files
```bash ```bash
yarn lint yarn lint
# or # or
npm run lint npm run lint
``` ```
### Format the files ### Format the files
```bash ```bash
yarn format yarn format
# or # or
npm run format npm run format
``` ```
### Build the app for production ### Build the app for production
```bash ```bash
quasar build quasar build
``` ```
### Customize the configuration ### Customize the configuration
See [Configuring quasar.config.js](https://v2.quasar.dev/quasar-cli-webpack/quasar-config-js). See [Configuring quasar.config.js](https://v2.quasar.dev/quasar-cli-webpack/quasar-config-js).

View File

@ -9,10 +9,10 @@ let extend = undefined;
*/ */
if (fs.existsSync('./.babelrc')) { if (fs.existsSync('./.babelrc')) {
extend = './.babelrc'; extend = './.babelrc';
} }
module.exports = { module.exports = {
presets: ['@quasar/babel-preset-app'], presets: ['@quasar/babel-preset-app'],
extends: extend, extends: extend,
}; };

View File

@ -1,15 +1,15 @@
{ {
"baseUrl": "http://localhost:8080/", "baseUrl": "http://localhost:8080/",
"fixturesFolder": "test/cypress/fixtures", "fixturesFolder": "test/cypress/fixtures",
"integrationFolder": "test/cypress/integration", "integrationFolder": "test/cypress/integration",
"pluginsFile": "test/cypress/plugins/index.js", "pluginsFile": "test/cypress/plugins/index.js",
"screenshotsFolder": "test/cypress/screenshots", "screenshotsFolder": "test/cypress/screenshots",
"supportFile": "test/cypress/support/index.js", "supportFile": "test/cypress/support/index.js",
"videosFolder": "test/cypress/videos", "videosFolder": "test/cypress/videos",
"video": true, "video": true,
"component": { "component": {
"componentFolder": "src", "componentFolder": "src",
"testFiles": "**/*.spec.js", "testFiles": "**/*.spec.js",
"supportFile": "test/cypress/support/unit.js" "supportFile": "test/cypress/support/unit.js"
} }
} }

View File

@ -1,64 +1,56 @@
const esModules = ['quasar', 'quasar/lang', 'lodash-es'].join('|'); const esModules = ['quasar', 'quasar/lang', 'lodash-es'].join('|');
module.exports = { module.exports = {
globals: { globals: {
__DEV__: true, __DEV__: true,
// TODO: Remove if resolved natively // TODO: Remove if resolved natively
// See https://github.com/vuejs/vue-jest/issues/175 // See https://github.com/vuejs/vue-jest/issues/175
'vue-jest': { 'vue-jest': {
pug: { doctype: 'html' }, pug: { doctype: 'html' },
},
}, },
}, // Jest assumes we are testing in node environment, specify jsdom environment instead
// Jest assumes we are testing in node environment, specify jsdom environment instead testEnvironment: 'jsdom',
testEnvironment: 'jsdom', // noStackTrace: true,
// noStackTrace: true, // bail: true,
// bail: true, // cache: false,
// cache: false, // verbose: true,
// verbose: true, // watch: true,
// watch: true, collectCoverage: false,
collectCoverage: false, coverageDirectory: '<rootDir>/test/jest/coverage',
coverageDirectory: '<rootDir>/test/jest/coverage', collectCoverageFrom: ['<rootDir>/src/**/*.vue', '<rootDir>/src/**/*.js', '<rootDir>/src/**/*.jsx'],
collectCoverageFrom: [ // Needed in JS codebases too because of feature flags
'<rootDir>/src/**/*.vue', coveragePathIgnorePatterns: ['/node_modules/', '.d.ts$'],
'<rootDir>/src/**/*.js', coverageThreshold: {
'<rootDir>/src/**/*.jsx', global: {
], // branches: 50,
// Needed in JS codebases too because of feature flags // functions: 50,
coveragePathIgnorePatterns: ['/node_modules/', '.d.ts$'], // lines: 50,
coverageThreshold: { // statements: 50
global: { },
// branches: 50,
// functions: 50,
// lines: 50,
// statements: 50
}, },
}, testMatch: ['<rootDir>/test/jest/__tests__/**/*.(spec|test).js', '<rootDir>/src/**/*.jest.(spec|test).js'],
testMatch: [ moduleFileExtensions: ['vue', 'js', 'jsx', 'json'],
'<rootDir>/test/jest/__tests__/**/*.(spec|test).js', moduleNameMapper: {
'<rootDir>/src/**/*.jest.(spec|test).js', '^quasar$': 'quasar/dist/quasar.esm.prod.js',
], '^~/(.*)$': '<rootDir>/$1',
moduleFileExtensions: ['vue', 'js', 'jsx', 'json'], '^src/(.*)$': '<rootDir>/src/$1',
moduleNameMapper: { '^app/(.*)$': '<rootDir>/$1',
'^quasar$': 'quasar/dist/quasar.esm.prod.js', '^components/(.*)$': '<rootDir>/src/components/$1',
'^~/(.*)$': '<rootDir>/$1', '^layouts/(.*)$': '<rootDir>/src/layouts/$1',
'^src/(.*)$': '<rootDir>/src/$1', '^pages/(.*)$': '<rootDir>/src/pages/$1',
'^app/(.*)$': '<rootDir>/$1', '^assets/(.*)$': '<rootDir>/src/assets/$1',
'^components/(.*)$': '<rootDir>/src/components/$1', '^boot/(.*)$': '<rootDir>/src/boot/$1',
'^layouts/(.*)$': '<rootDir>/src/layouts/$1', '.*css$': '@quasar/quasar-app-extension-testing-unit-jest/stub.css',
'^pages/(.*)$': '<rootDir>/src/pages/$1', },
'^assets/(.*)$': '<rootDir>/src/assets/$1', transform: {
'^boot/(.*)$': '<rootDir>/src/boot/$1', '.*\\.vue$': 'vue-jest',
'.*css$': '@quasar/quasar-app-extension-testing-unit-jest/stub.css', '.*\\.js$': 'babel-jest',
}, '.+\\.(css|styl|less|sass|scss|svg|png|jpg|ttf|woff|woff2)$': 'jest-transform-stub',
transform: { // use these if NPM is being flaky, care as hosting could interfere with these
'.*\\.vue$': 'vue-jest', // '.*\\.vue$': '@quasar/quasar-app-extension-testing-unit-jest/node_modules/vue-jest',
'.*\\.js$': 'babel-jest', // '.*\\.js$': '@quasar/quasar-app-extension-testing-unit-jest/node_modules/babel-jest'
'.+\\.(css|styl|less|sass|scss|svg|png|jpg|ttf|woff|woff2)$': },
'jest-transform-stub', transformIgnorePatterns: [`node_modules/(?!(${esModules}))`],
// use these if NPM is being flaky, care as hosting could interfere with these snapshotSerializers: ['jest-serializer-vue'],
// '.*\\.vue$': '@quasar/quasar-app-extension-testing-unit-jest/node_modules/vue-jest',
// '.*\\.js$': '@quasar/quasar-app-extension-testing-unit-jest/node_modules/babel-jest'
},
transformIgnorePatterns: [`node_modules/(?!(${esModules}))`],
snapshotSerializers: ['jest-serializer-vue'],
}; };

View File

@ -1,39 +1,17 @@
{ {
"compilerOptions": { "compilerOptions": {
"baseUrl": ".", "baseUrl": ".",
"paths": { "paths": {
"src/*": [ "src/*": ["src/*"],
"src/*" "app/*": ["*"],
], "components/*": ["src/components/*"],
"app/*": [ "layouts/*": ["src/layouts/*"],
"*" "pages/*": ["src/pages/*"],
], "assets/*": ["src/assets/*"],
"components/*": [ "boot/*": ["src/boot/*"],
"src/components/*" "stores/*": ["src/stores/*"],
], "vue$": ["node_modules/vue/dist/vue.runtime.esm-bundler.js"]
"layouts/*": [ }
"src/layouts/*" },
], "exclude": ["dist", ".quasar", "node_modules"]
"pages/*": [
"src/pages/*"
],
"assets/*": [
"src/assets/*"
],
"boot/*": [
"src/boot/*"
],
"stores/*": [
"src/stores/*"
],
"vue$": [
"node_modules/vue/dist/vue.runtime.esm-bundler.js"
]
}
},
"exclude": [
"dist",
".quasar",
"node_modules"
]
} }

69044
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,58 +1,58 @@
{ {
"name": "salix-front", "name": "salix-front",
"version": "0.0.1", "version": "0.0.1",
"description": "Salix front-end", "description": "Salix front-end",
"productName": "Salix", "productName": "Salix",
"author": "Verdnatura", "author": "Verdnatura",
"private": true, "private": true,
"scripts": { "scripts": {
"lint": "eslint --ext .js,.vue ./", "lint": "eslint --ext .js,.vue ./",
"format": "prettier --write \"**/*.{js,vue,scss,html,md,json}\" --ignore-path .gitignore", "format": "prettier --write \"**/*.{js,vue,scss,html,md,json}\" --ignore-path .gitignore",
"test": "echo \"See package.json => scripts for available tests.\" && exit 0", "test": "echo \"See package.json => scripts for available tests.\" && exit 0",
"test:unit": "jest --watchAll", "test:unit": "jest --watchAll",
"test:unit:ci": "jest --ci", "test:unit:ci": "jest --ci",
"test:unit:coverage": "jest --coverage", "test:unit:coverage": "jest --coverage",
"serve:test:coverage": "quasar serve test/jest/coverage/lcov-report/ --port 8788", "serve:test:coverage": "quasar serve test/jest/coverage/lcov-report/ --port 8788",
"concurrently:dev:jest": "concurrently \"quasar dev\" \"jest --watch\"", "concurrently:dev:jest": "concurrently \"quasar dev\" \"jest --watch\"",
"test:e2e": "cross-env E2E_TEST=true start-test \"quasar dev\" http-get://localhost:8080 \"cypress open\"", "test:e2e": "cross-env E2E_TEST=true start-test \"quasar dev\" http-get://localhost:8080 \"cypress open\"",
"test:e2e:ci": "cross-env E2E_TEST=true start-test \"quasar dev\" http-get://localhost:8080 \"cypress run\"" "test:e2e:ci": "cross-env E2E_TEST=true start-test \"quasar dev\" http-get://localhost:8080 \"cypress run\""
}, },
"dependencies": { "dependencies": {
"@quasar/extras": "^1.0.0", "@quasar/extras": "^1.0.0",
"axios": "^0.21.1", "axios": "^0.21.1",
"core-js": "^3.6.5", "core-js": "^3.6.5",
"quasar": "^2.6.0", "quasar": "^2.6.0",
"vue": "^3.0.0", "vue": "^3.0.0",
"vue-i18n": "^9.0.0", "vue-i18n": "^9.0.0",
"vue-router": "^4.0.0" "vue-router": "^4.0.0"
}, },
"devDependencies": { "devDependencies": {
"@babel/eslint-parser": "^7.13.14", "@babel/eslint-parser": "^7.13.14",
"@quasar/app-webpack": "^3.0.0", "@quasar/app-webpack": "^3.0.0",
"@quasar/quasar-app-extension-testing-e2e-cypress": "^4.0.1", "@quasar/quasar-app-extension-testing-e2e-cypress": "^4.0.1",
"@quasar/quasar-app-extension-testing-unit-jest": "^3.0.0-alpha.9", "@quasar/quasar-app-extension-testing-unit-jest": "^3.0.0-alpha.9",
"eslint": "^8.10.0", "eslint": "^8.10.0",
"eslint-config-prettier": "^8.1.0", "eslint-config-prettier": "^8.1.0",
"eslint-plugin-jest": "^25.2.2", "eslint-plugin-jest": "^25.2.2",
"eslint-plugin-vue": "^8.5.0", "eslint-plugin-vue": "^8.5.0",
"eslint-webpack-plugin": "^3.1.1", "eslint-webpack-plugin": "^3.1.1",
"prettier": "^2.5.1", "prettier": "^2.5.1",
"eslint-plugin-cypress": "^2.11.3" "eslint-plugin-cypress": "^2.11.3"
}, },
"browserslist": [ "browserslist": [
"last 10 Chrome versions", "last 10 Chrome versions",
"last 10 Firefox versions", "last 10 Firefox versions",
"last 4 Edge versions", "last 4 Edge versions",
"last 7 Safari versions", "last 7 Safari versions",
"last 8 Android versions", "last 8 Android versions",
"last 8 ChromeAndroid versions", "last 8 ChromeAndroid versions",
"last 8 FirefoxAndroid versions", "last 8 FirefoxAndroid versions",
"last 10 iOS versions", "last 10 iOS versions",
"last 5 Opera versions" "last 5 Opera versions"
], ],
"engines": { "engines": {
"node": ">= 12.22.1", "node": ">= 12.22.1",
"npm": ">= 6.13.4", "npm": ">= 6.13.4",
"yarn": ">= 1.21.1" "yarn": ">= 1.21.1"
} }
} }

View File

@ -8,234 +8,213 @@
// Configuration for your app // Configuration for your app
// https://v2.quasar.dev/quasar-cli-webpack/quasar-config-js // https://v2.quasar.dev/quasar-cli-webpack/quasar-config-js
const ESLintPlugin = require('eslint-webpack-plugin');
const ESLintPlugin = require('eslint-webpack-plugin')
const { configure } = require('quasar/wrappers'); const { configure } = require('quasar/wrappers');
module.exports = configure(function (ctx) { module.exports = configure(function (ctx) {
return { return {
// https://v2.quasar.dev/quasar-cli-webpack/supporting-ts // https://v2.quasar.dev/quasar-cli-webpack/supporting-ts
supportTS: false, supportTS: false,
// https://v2.quasar.dev/quasar-cli-webpack/prefetch-feature // https://v2.quasar.dev/quasar-cli-webpack/prefetch-feature
// preFetch: true, // preFetch: true,
// app boot file (/src/boot) // app boot file (/src/boot)
// --> boot files are part of "main.js" // --> boot files are part of "main.js"
// https://v2.quasar.dev/quasar-cli-webpack/boot-files // https://v2.quasar.dev/quasar-cli-webpack/boot-files
boot: [ boot: ['i18n', 'axios'],
'i18n',
'axios',
],
// https://v2.quasar.dev/quasar-cli-webpack/quasar-config-js#Property%3A-css // https://v2.quasar.dev/quasar-cli-webpack/quasar-config-js#Property%3A-css
css: [ css: ['app.scss'],
'app.scss'
],
// https://github.com/quasarframework/quasar/tree/dev/extras // https://github.com/quasarframework/quasar/tree/dev/extras
extras: [ extras: [
// 'ionicons-v4', // 'ionicons-v4',
// 'mdi-v5', // 'mdi-v5',
// 'fontawesome-v6', // 'fontawesome-v6',
// 'eva-icons', // 'eva-icons',
// 'themify', // 'themify',
// 'line-awesome', // 'line-awesome',
// 'roboto-font-latin-ext', // this or either 'roboto-font', NEVER both! // 'roboto-font-latin-ext', // this or either 'roboto-font', NEVER both!
'roboto-font', // optional, you are not bound to it 'roboto-font', // optional, you are not bound to it
'material-icons', // optional, you are not bound to it 'material-icons', // optional, you are not bound to it
], ],
// Full list of options: https://v2.quasar.dev/quasar-cli-webpack/quasar-config-js#Property%3A-build // Full list of options: https://v2.quasar.dev/quasar-cli-webpack/quasar-config-js#Property%3A-build
build: { build: {
vueRouterMode: 'hash', // available values: 'hash', 'history' vueRouterMode: 'hash', // available values: 'hash', 'history'
// transpile: false, // transpile: false,
// publicPath: '/', // publicPath: '/',
// Add dependencies for transpiling with Babel (Array of string/regex) // Add dependencies for transpiling with Babel (Array of string/regex)
// (from node_modules, which are by default not transpiled). // (from node_modules, which are by default not transpiled).
// Applies only if "transpile" is set to true. // Applies only if "transpile" is set to true.
// transpileDependencies: [], // transpileDependencies: [],
// rtl: true, // https://quasar.dev/options/rtl-support // rtl: true, // https://quasar.dev/options/rtl-support
// preloadChunks: true, // preloadChunks: true,
// showProgress: false, // showProgress: false,
// gzip: true, // gzip: true,
// analyze: true, // analyze: true,
// Options below are automatically set depending on the env, set them if you want to override // Options below are automatically set depending on the env, set them if you want to override
// extractCSS: false, // extractCSS: false,
// https://v2.quasar.dev/quasar-cli-webpack/handling-webpack // https://v2.quasar.dev/quasar-cli-webpack/handling-webpack
// "chain" is a webpack-chain object https://github.com/neutrinojs/webpack-chain // "chain" is a webpack-chain object https://github.com/neutrinojs/webpack-chain
chainWebpack (chain) { chainWebpack(chain) {
chain.plugin('eslint-webpack-plugin') chain.plugin('eslint-webpack-plugin').use(ESLintPlugin, [{ extensions: ['js', 'vue'] }]);
.use(ESLintPlugin, [{ extensions: [ 'js', 'vue' ] }]) },
} },
}, // Full list of options: https://v2.quasar.dev/quasar-cli-webpack/quasar-config-js#Property%3A-devServer
devServer: {
server: {
type: 'http',
},
port: 8080,
open: true, // opens browser window automatically
},
// Full list of options: https://v2.quasar.dev/quasar-cli-webpack/quasar-config-js#Property%3A-devServer // https://v2.quasar.dev/quasar-cli-webpack/quasar-config-js#Property%3A-framework
devServer: { framework: {
server: { config: {},
type: 'http'
},
port: 8080,
open: true // opens browser window automatically
},
// https://v2.quasar.dev/quasar-cli-webpack/quasar-config-js#Property%3A-framework // iconSet: 'material-icons', // Quasar icon set
framework: { // lang: 'en-US', // Quasar language pack
config: {},
// iconSet: 'material-icons', // Quasar icon set // For special cases outside of where the auto-import strategy can have an impact
// lang: 'en-US', // Quasar language pack // (like functional components as one of the examples),
// you can manually specify Quasar components/directives to be available everywhere:
//
// components: [],
// directives: [],
// For special cases outside of where the auto-import strategy can have an impact // Quasar plugins
// (like functional components as one of the examples), plugins: [],
// you can manually specify Quasar components/directives to be available everywhere: },
//
// components: [],
// directives: [],
// Quasar plugins // animations: 'all', // --- includes all animations
plugins: [] // https://quasar.dev/options/animations
}, animations: [],
// animations: 'all', // --- includes all animations // https://v2.quasar.dev/quasar-cli-webpack/developing-ssr/configuring-ssr
// https://quasar.dev/options/animations ssr: {
animations: [], pwa: false,
// https://v2.quasar.dev/quasar-cli-webpack/developing-ssr/configuring-ssr // manualStoreHydration: true,
ssr: { // manualPostHydrationTrigger: true,
pwa: false,
// manualStoreHydration: true, prodPort: 3000, // The default port that the production server should use
// manualPostHydrationTrigger: true, // (gets superseded if process.env.PORT is specified at runtime)
prodPort: 3000, // The default port that the production server should use maxAge: 1000 * 60 * 60 * 24 * 30,
// (gets superseded if process.env.PORT is specified at runtime) // Tell browser when a file from the server should expire from cache (in ms)
maxAge: 1000 * 60 * 60 * 24 * 30, chainWebpackWebserver(chain) {
// Tell browser when a file from the server should expire from cache (in ms) chain.plugin('eslint-webpack-plugin').use(ESLintPlugin, [{ extensions: ['js'] }]);
},
middlewares: [
ctx.prod ? 'compression' : '',
'render', // keep this as last one
],
},
chainWebpackWebserver (chain) { // https://v2.quasar.dev/quasar-cli-webpack/developing-pwa/configuring-pwa
chain.plugin('eslint-webpack-plugin') pwa: {
.use(ESLintPlugin, [{ extensions: [ 'js' ] }]) workboxPluginMode: 'GenerateSW', // 'GenerateSW' or 'InjectManifest'
}, workboxOptions: {}, // only for GenerateSW
// for the custom service worker ONLY (/src-pwa/custom-service-worker.[js|ts])
// if using workbox in InjectManifest mode
middlewares: [ chainWebpackCustomSW(chain) {
ctx.prod ? 'compression' : '', chain.plugin('eslint-webpack-plugin').use(ESLintPlugin, [{ extensions: ['js'] }]);
'render' // keep this as last one },
]
},
// https://v2.quasar.dev/quasar-cli-webpack/developing-pwa/configuring-pwa manifest: {
pwa: { name: `Salix`,
workboxPluginMode: 'GenerateSW', // 'GenerateSW' or 'InjectManifest' short_name: `Salix`,
workboxOptions: {}, // only for GenerateSW description: `Salix front-end`,
display: 'standalone',
orientation: 'portrait',
background_color: '#ffffff',
theme_color: '#027be3',
icons: [
{
src: 'icons/icon-128x128.png',
sizes: '128x128',
type: 'image/png',
},
{
src: 'icons/icon-192x192.png',
sizes: '192x192',
type: 'image/png',
},
{
src: 'icons/icon-256x256.png',
sizes: '256x256',
type: 'image/png',
},
{
src: 'icons/icon-384x384.png',
sizes: '384x384',
type: 'image/png',
},
{
src: 'icons/icon-512x512.png',
sizes: '512x512',
type: 'image/png',
},
],
},
},
// for the custom service worker ONLY (/src-pwa/custom-service-worker.[js|ts]) // Full list of options: https://v2.quasar.dev/quasar-cli-webpack/developing-cordova-apps/configuring-cordova
// if using workbox in InjectManifest mode cordova: {
// noIosLegacyBuildFlag: true, // uncomment only if you know what you are doing
},
chainWebpackCustomSW (chain) { // Full list of options: https://v2.quasar.dev/quasar-cli-webpack/developing-capacitor-apps/configuring-capacitor
chain.plugin('eslint-webpack-plugin') capacitor: {
.use(ESLintPlugin, [{ extensions: [ 'js' ] }]) hideSplashscreen: true,
}, },
// Full list of options: https://v2.quasar.dev/quasar-cli-webpack/developing-electron-apps/configuring-electron
electron: {
bundler: 'packager', // 'packager' or 'builder'
manifest: { packager: {
name: `Salix`, // https://github.com/electron-userland/electron-packager/blob/master/docs/api.md#options
short_name: `Salix`, // OS X / Mac App Store
description: `Salix front-end`, // appBundleId: '',
display: 'standalone', // appCategoryType: '',
orientation: 'portrait', // osxSign: '',
background_color: '#ffffff', // protocol: 'myapp://path',
theme_color: '#027be3', // Windows only
icons: [ // win32metadata: { ... }
{ },
src: 'icons/icon-128x128.png',
sizes: '128x128',
type: 'image/png'
},
{
src: 'icons/icon-192x192.png',
sizes: '192x192',
type: 'image/png'
},
{
src: 'icons/icon-256x256.png',
sizes: '256x256',
type: 'image/png'
},
{
src: 'icons/icon-384x384.png',
sizes: '384x384',
type: 'image/png'
},
{
src: 'icons/icon-512x512.png',
sizes: '512x512',
type: 'image/png'
}
]
}
},
// Full list of options: https://v2.quasar.dev/quasar-cli-webpack/developing-cordova-apps/configuring-cordova builder: {
cordova: { // https://www.electron.build/configuration/configuration
// noIosLegacyBuildFlag: true, // uncomment only if you know what you are doing
},
// Full list of options: https://v2.quasar.dev/quasar-cli-webpack/developing-capacitor-apps/configuring-capacitor appId: 'salix-front',
capacitor: { },
hideSplashscreen: true
},
// Full list of options: https://v2.quasar.dev/quasar-cli-webpack/developing-electron-apps/configuring-electron // "chain" is a webpack-chain object https://github.com/neutrinojs/webpack-chain
electron: {
bundler: 'packager', // 'packager' or 'builder'
packager: { chainWebpackMain(chain) {
// https://github.com/electron-userland/electron-packager/blob/master/docs/api.md#options chain.plugin('eslint-webpack-plugin').use(ESLintPlugin, [{ extensions: ['js'] }]);
},
// OS X / Mac App Store chainWebpackPreload(chain) {
// appBundleId: '', chain.plugin('eslint-webpack-plugin').use(ESLintPlugin, [{ extensions: ['js'] }]);
// appCategoryType: '', },
// osxSign: '', },
// protocol: 'myapp://path', };
// Windows only
// win32metadata: { ... }
},
builder: {
// https://www.electron.build/configuration/configuration
appId: 'salix-front'
},
// "chain" is a webpack-chain object https://github.com/neutrinojs/webpack-chain
chainWebpackMain (chain) {
chain.plugin('eslint-webpack-plugin')
.use(ESLintPlugin, [{ extensions: [ 'js' ] }])
},
chainWebpackPreload (chain) {
chain.plugin('eslint-webpack-plugin')
.use(ESLintPlugin, [{ extensions: [ 'js' ] }])
},
}
}
}); });

View File

@ -1,13 +1,9 @@
{ {
"@quasar/testing-unit-jest": { "@quasar/testing-unit-jest": {
"babel": "babelrc", "babel": "babelrc",
"options": [ "options": ["scripts"]
"scripts" },
] "@quasar/testing-e2e-cypress": {
}, "options": ["scripts"]
"@quasar/testing-e2e-cypress": { }
"options": [
"scripts"
]
}
} }

View File

@ -1,11 +1,11 @@
{ {
"unit-jest": { "unit-jest": {
"runnerCommand": "jest --ci" "runnerCommand": "jest --ci"
}, },
"e2e-cypress": { "e2e-cypress": {
"runnerCommand": "cross-env E2E_TEST=true start-test \"quasar dev\" http-get://localhost:8080 \"cypress run\"" "runnerCommand": "cross-env E2E_TEST=true start-test \"quasar dev\" http-get://localhost:8080 \"cypress run\""
}, },
"unit-cypress": { "unit-cypress": {
"runnerCommand": "cypress run-ct" "runnerCommand": "cypress run-ct"
} }
} }

View File

@ -1,11 +1,8 @@
<template> <template>
<router-view /> <router-view />
</template> </template>
<script> <script setup>
import { defineComponent } from 'vue' const derp = ['asd'];
console.log(derp);
export default defineComponent({
name: 'App'
})
</script> </script>

View File

@ -1,5 +1,5 @@
import { boot } from 'quasar/wrappers' import { boot } from 'quasar/wrappers';
import axios from 'axios' import axios from 'axios';
// Be careful when using SSR for cross-request state pollution // Be careful when using SSR for cross-request state pollution
// due to creating a Singleton instance here; // due to creating a Singleton instance here;
@ -7,18 +7,18 @@ import axios from 'axios'
// good idea to move this instance creation inside of the // good idea to move this instance creation inside of the
// "export default () => {}" function below (which runs individually // "export default () => {}" function below (which runs individually
// for each client) // for each client)
const api = axios.create({ baseURL: 'https://api.example.com' }) const api = axios.create({ baseURL: 'https://api.example.com' });
export default boot(({ app }) => { export default boot(({ app }) => {
// for use inside Vue files (Options API) through this.$axios and this.$api // for use inside Vue files (Options API) through this.$axios and this.$api
app.config.globalProperties.$axios = axios app.config.globalProperties.$axios = axios;
// ^ ^ ^ this will allow you to use this.$axios (for Vue Options API form) // ^ ^ ^ this will allow you to use this.$axios (for Vue Options API form)
// so you won't necessarily have to import axios in each vue file // so you won't necessarily have to import axios in each vue file
app.config.globalProperties.$api = api app.config.globalProperties.$api = api;
// ^ ^ ^ this will allow you to use this.$api (for Vue Options API form) // ^ ^ ^ this will allow you to use this.$api (for Vue Options API form)
// so you can easily perform requests against your app's API // so you can easily perform requests against your app's API
}) });
export { api } export { api };

View File

@ -1,13 +1,13 @@
import { boot } from 'quasar/wrappers' import { boot } from 'quasar/wrappers';
import { createI18n } from 'vue-i18n' import { createI18n } from 'vue-i18n';
import messages from 'src/i18n' import messages from 'src/i18n';
export default boot(({ app }) => { export default boot(({ app }) => {
const i18n = createI18n({ const i18n = createI18n({
locale: 'en-US', locale: 'en-US',
messages messages,
}) });
// Set i18n instance on app // Set i18n instance on app
app.use(i18n) app.use(i18n);
}) });

View File

@ -1,49 +1,41 @@
<template> <template>
<q-item <q-item clickable tag="a" target="_blank" :href="link">
clickable <q-item-section v-if="icon" avatar>
tag="a" <q-icon :name="icon" />
target="_blank" </q-item-section>
:href="link"
>
<q-item-section
v-if="icon"
avatar
>
<q-icon :name="icon" />
</q-item-section>
<q-item-section> <q-item-section>
<q-item-label>{{ title }}</q-item-label> <q-item-label>{{ title }}</q-item-label>
<q-item-label caption>{{ caption }}</q-item-label> <q-item-label caption>{{ caption }}</q-item-label>
</q-item-section> </q-item-section>
</q-item> </q-item>
</template> </template>
<script> <script>
import { defineComponent } from 'vue' import { defineComponent } from 'vue';
export default defineComponent({ export default defineComponent({
name: 'EssentialLink', name: 'EssentialLink',
props: { props: {
title: { title: {
type: String, type: String,
required: true required: true,
}, },
caption: { caption: {
type: String, type: String,
default: '' default: '',
}, },
link: { link: {
type: String, type: String,
default: '#' default: '#',
}, },
icon: { icon: {
type: String, type: String,
default: '' default: '',
} },
} },
}) });
</script> </script>

View File

@ -1,19 +1,12 @@
<template> <template>
<q-btn <q-btn data-cy="button" label="test emit" color="positive" rounded icon="edit" @click="$emit('test')" />
data-cy="button"
label="test emit"
color="positive"
rounded
icon="edit"
@click="$emit('test')"
/>
</template> </template>
<script> <script>
import { defineComponent } from 'vue'; import { defineComponent } from 'vue';
export default defineComponent({ export default defineComponent({
name: 'QuasarButton', name: 'QuasarButton',
emits: ['test'], emits: ['test'],
}); });
</script> </script>

View File

@ -1,21 +1,16 @@
<template> <template>
<!-- notice dialogRef here --> <!-- notice dialogRef here -->
<q-dialog ref="dialogRef" @hide="onDialogHide" data-cy="dialog"> <q-dialog ref="dialogRef" @hide="onDialogHide" data-cy="dialog">
<q-card class="q-dialog-plugin"> <q-card class="q-dialog-plugin">
<q-card-section>{{ message }}</q-card-section> <q-card-section>{{ message }}</q-card-section>
<!-- buttons example --> <!-- buttons example -->
<q-card-actions align="right"> <q-card-actions align="right">
<q-btn <q-btn data-cy="ok-button" color="primary" label="OK" @click="onOKClick" />
data-cy="ok-button" <q-btn color="primary" label="Cancel" @click="onCancelClick" />
color="primary" </q-card-actions>
label="OK" </q-card>
@click="onOKClick" </q-dialog>
/>
<q-btn color="primary" label="Cancel" @click="onCancelClick" />
</q-card-actions>
</q-card>
</q-dialog>
</template> </template>
<script> <script>
@ -23,49 +18,48 @@ import { useDialogPluginComponent } from 'quasar';
import { defineComponent } from 'vue'; import { defineComponent } from 'vue';
export default defineComponent({ export default defineComponent({
name: 'QuasarDialog', name: 'QuasarDialog',
props: { props: {
message: { message: {
type: String, type: String,
required: true, required: true,
},
}, },
},
// REQUIRED; need to specify some events that your // REQUIRED; need to specify some events that your
// component will emit through useDialogPluginComponent() // component will emit through useDialogPluginComponent()
emits: useDialogPluginComponent.emits, emits: useDialogPluginComponent.emits,
setup() { setup() {
// REQUIRED; must be called inside of setup() // REQUIRED; must be called inside of setup()
const { dialogRef, onDialogHide, onDialogOK, onDialogCancel } = const { dialogRef, onDialogHide, onDialogOK, onDialogCancel } = useDialogPluginComponent();
useDialogPluginComponent(); // dialogRef - Vue ref to be applied to QDialog
// dialogRef - Vue ref to be applied to QDialog // onDialogHide - Function to be used as handler for @hide on QDialog
// onDialogHide - Function to be used as handler for @hide on QDialog // onDialogOK - Function to call to settle dialog with "ok" outcome
// onDialogOK - Function to call to settle dialog with "ok" outcome // example: onDialogOK() - no payload
// example: onDialogOK() - no payload // example: onDialogOK({ /*.../* }) - with payload
// example: onDialogOK({ /*.../* }) - with payload // onDialogCancel - Function to call to settle dialog with "cancel" outcome
// onDialogCancel - Function to call to settle dialog with "cancel" outcome
return { return {
// This is REQUIRED; // This is REQUIRED;
// Need to inject these (from useDialogPluginComponent() call) // Need to inject these (from useDialogPluginComponent() call)
// into the vue scope for the vue html template // into the vue scope for the vue html template
dialogRef, dialogRef,
onDialogHide, onDialogHide,
// other methods that we used in our vue html template; // other methods that we used in our vue html template;
// these are part of our example (so not required) // these are part of our example (so not required)
onOKClick() { onOKClick() {
// on OK, it is REQUIRED to // on OK, it is REQUIRED to
// call onDialogOK (with optional payload) // call onDialogOK (with optional payload)
onDialogOK(); onDialogOK();
// or with payload: onDialogOK({ ... }) // or with payload: onDialogOK({ ... })
// ...and it will also hide the dialog automatically // ...and it will also hide the dialog automatically
}, },
// we can passthrough onDialogCancel directly // we can passthrough onDialogCancel directly
onCancelClick: onDialogCancel, onCancelClick: onDialogCancel,
}; };
}, },
}); });
</script> </script>

View File

@ -1,33 +1,33 @@
<template> <template>
<q-drawer <q-drawer
v-model="showDrawer" v-model="showDrawer"
show-if-above show-if-above
:width="200" :width="200"
:breakpoint="700" :breakpoint="700"
elevated elevated
data-cy="drawer" data-cy="drawer"
class="bg-primary text-white" class="bg-primary text-white"
> >
<q-scroll-area class="fit"> <q-scroll-area class="fit">
<div class="q-pa-sm"> <div class="q-pa-sm">
<div v-for="n in 50" :key="n">Drawer {{ n }} / 50</div> <div v-for="n in 50" :key="n">Drawer {{ n }} / 50</div>
</div> </div>
<q-btn data-cy="button">Am I on screen?</q-btn> <q-btn data-cy="button">Am I on screen?</q-btn>
</q-scroll-area> </q-scroll-area>
</q-drawer> </q-drawer>
</template> </template>
<script> <script>
import { ref, defineComponent } from 'vue'; import { ref, defineComponent } from 'vue';
export default defineComponent({ export default defineComponent({
name: 'QuasarDrawer', name: 'QuasarDrawer',
setup() { setup() {
const showDrawer = ref(true); const showDrawer = ref(true);
return { return {
showDrawer, showDrawer,
}; };
}, },
}); });
</script> </script>

View File

@ -1,21 +1,21 @@
<template> <template>
<q-page-sticky position="bottom-right" :offset="[18, 18]"> <q-page-sticky position="bottom-right" :offset="[18, 18]">
<q-btn data-cy="button" rounded color="accent" icon="arrow_forward"> <q-btn data-cy="button" rounded color="accent" icon="arrow_forward">
{{ title }} {{ title }}
</q-btn> </q-btn>
</q-page-sticky> </q-page-sticky>
</template> </template>
<script> <script>
import { defineComponent } from 'vue'; import { defineComponent } from 'vue';
export default defineComponent({ export default defineComponent({
name: 'QuasarPageSticky', name: 'QuasarPageSticky',
props: { props: {
title: { title: {
type: String, type: String,
required: true, required: true,
},
}, },
},
}); });
</script> </script>

View File

@ -1,28 +1,21 @@
<template> <template>
<q-btn color="primary" data-cy="button"> <q-btn color="primary" data-cy="button">
Button Button
<q-tooltip <q-tooltip v-model="showTooltip" data-cy="tooltip" class="bg-red" :offset="[10, 10]"> Here I am! </q-tooltip>
v-model="showTooltip" </q-btn>
data-cy="tooltip"
class="bg-red"
:offset="[10, 10]"
>
Here I am!
</q-tooltip>
</q-btn>
</template> </template>
<script> <script>
import { ref, defineComponent } from 'vue'; import { ref, defineComponent } from 'vue';
export default defineComponent({ export default defineComponent({
name: 'QuasarTooltip', name: 'QuasarTooltip',
setup() { setup() {
const showTooltip = ref(true); const showTooltip = ref(true);
return { return {
showTooltip, showTooltip,
}; };
}, },
}); });
</script> </script>

View File

@ -2,43 +2,41 @@ import { mount } from '@cypress/vue';
import QuasarButton from '../QuasarButton.vue'; import QuasarButton from '../QuasarButton.vue';
describe('QuasarButton', () => { describe('QuasarButton', () => {
it('renders a message', () => { it('renders a message', () => {
const label = 'Hello there'; const label = 'Hello there';
mount(QuasarButton, { mount(QuasarButton, {
props: { props: {
label, label,
}, },
});
cy.dataCy('button').should('contain', label);
}); });
cy.dataCy('button').should('contain', label); it('renders another message', () => {
}); const label = 'Will this work?';
mount(QuasarButton, {
props: {
label,
},
});
it('renders another message', () => { cy.dataCy('button').should('contain', label);
const label = 'Will this work?';
mount(QuasarButton, {
props: {
label,
},
}); });
cy.dataCy('button').should('contain', label); it('should have a `positive` color', () => {
}); mount(QuasarButton);
it('should have a `positive` color', () => { cy.dataCy('button').should('have.backgroundColor', 'var(--q-positive)').should('have.color', 'white');
mount(QuasarButton); });
cy.dataCy('button') it('should emit `test` upon click', () => {
.should('have.backgroundColor', 'var(--q-positive)') mount(QuasarButton);
.should('have.color', 'white');
});
it('should emit `test` upon click', () => { cy.dataCy('button')
mount(QuasarButton); .click()
.should(() => {
cy.dataCy('button') expect(Cypress.vueWrapper.emitted('test')).to.have.length(1);
.click() });
.should(() => { });
expect(Cypress.vueWrapper.emitted('test')).to.have.length(1);
});
});
}); });

View File

@ -3,22 +3,22 @@ import DialogWrapper from 'app/test/cypress/wrappers/DialogWrapper.vue';
import QuasarDialog from '../QuasarDialog.vue'; import QuasarDialog from '../QuasarDialog.vue';
describe('QuasarDialog', () => { describe('QuasarDialog', () => {
it('should show a dialog with a message', () => { it('should show a dialog with a message', () => {
const message = 'Hello, I am a dialog'; const message = 'Hello, I am a dialog';
mount(DialogWrapper, { mount(DialogWrapper, {
props: { props: {
component: QuasarDialog, component: QuasarDialog,
componentProps: { componentProps: {
message, message,
}, },
}, },
});
cy.dataCy('dialog').should('exist').should('contain', message);
}); });
cy.dataCy('dialog').should('exist').should('contain', message);
});
it('should close a dialog when clikcing ok', () => { it('should close a dialog when clikcing ok', () => {
// The dialog is still visible from the previous test // The dialog is still visible from the previous test
cy.dataCy('dialog').should('exist').dataCy('ok-button').click(); cy.dataCy('dialog').should('exist').dataCy('ok-button').click();
cy.dataCy('dialog').should('not.exist'); cy.dataCy('dialog').should('not.exist');
}); });
}); });

View File

@ -3,19 +3,13 @@ import LayoutContainer from 'app/test/cypress/wrappers/LayoutContainer.vue';
import QuasarDrawer from '../QuasarDrawer.vue'; import QuasarDrawer from '../QuasarDrawer.vue';
describe('QuasarDrawer', () => { describe('QuasarDrawer', () => {
it('should show a drawer', () => { it('should show a drawer', () => {
mount(LayoutContainer, { mount(LayoutContainer, {
props: { props: {
component: QuasarDrawer, component: QuasarDrawer,
}, },
});
cy.dataCy('drawer').should('exist').dataCy('button').should('not.be.visible');
cy.get('.q-scrollarea .scroll').scrollTo('bottom', { duration: 500 }).dataCy('button').should('be.visible');
}); });
cy.dataCy('drawer')
.should('exist')
.dataCy('button')
.should('not.be.visible');
cy.get('.q-scrollarea .scroll')
.scrollTo('bottom', { duration: 500 })
.dataCy('button')
.should('be.visible');
});
}); });

View File

@ -3,20 +3,20 @@ import LayoutContainer from 'app/test/cypress/wrappers/LayoutContainer.vue';
import QuasarPageSticky from '../QuasarPageSticky.vue'; import QuasarPageSticky from '../QuasarPageSticky.vue';
describe('QuasarPageSticky', () => { describe('QuasarPageSticky', () => {
it('should show a sticky at the bottom-right of the page', () => { it('should show a sticky at the bottom-right of the page', () => {
mount(LayoutContainer, { mount(LayoutContainer, {
props: { props: {
component: QuasarPageSticky, component: QuasarPageSticky,
title: 'Test', title: 'Test',
}, },
}); });
cy.dataCy('button') cy.dataCy('button')
.should('be.visible') .should('be.visible')
.should(($el) => { .should(($el) => {
const rect = $el[0].getBoundingClientRect(); const rect = $el[0].getBoundingClientRect();
expect(rect.bottom).to.equal(window.innerHeight - 18); expect(rect.bottom).to.equal(window.innerHeight - 18);
expect(rect.right).to.equal(window.innerWidth - 18); expect(rect.right).to.equal(window.innerWidth - 18);
}); });
}); });
}); });

View File

@ -2,10 +2,10 @@ import { mount } from '@cypress/vue';
import QuasarTooltip from '../QuasarTooltip.vue'; import QuasarTooltip from '../QuasarTooltip.vue';
describe('QuasarTooltip', () => { describe('QuasarTooltip', () => {
it('should show a tooltip', () => { it('should show a tooltip', () => {
mount(QuasarTooltip); mount(QuasarTooltip);
cy.dataCy('button').trigger('mouseover'); cy.dataCy('button').trigger('mouseover');
cy.dataCy('tooltip').contains('Here I am!'); cy.dataCy('tooltip').contains('Here I am!');
}); });
}); });

View File

@ -12,13 +12,13 @@
// to match your app's branding. // to match your app's branding.
// Tip: Use the "Theme Builder" on Quasar's documentation website. // Tip: Use the "Theme Builder" on Quasar's documentation website.
$primary : #1976D2; $primary: #1976d2;
$secondary : #26A69A; $secondary: #26a69a;
$accent : #9C27B0; $accent: #9c27b0;
$dark : #1D1D1D; $dark: #1d1d1d;
$positive : #21BA45; $positive: #21ba45;
$negative : #C10015; $negative: #c10015;
$info : #31CCEC; $info: #31ccec;
$warning : #F2C037; $warning: #f2c037;

View File

@ -2,6 +2,6 @@
// so you can safely delete all default props below // so you can safely delete all default props below
export default { export default {
failed: 'Action failed', failed: 'Action failed',
success: 'Action was successful' success: 'Action was successful',
} };

View File

@ -1,5 +1,5 @@
import enUS from './en-US' import enUS from './en-US';
export default { export default {
'en-US': enUS 'en-US': enUS,
} };

View File

@ -1,22 +1,25 @@
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<head> <head>
<title><%= productName %></title> <title><%= productName %></title>
<meta charset="utf-8"> <meta charset="utf-8" />
<meta name="description" content="<%= productDescription %>"> <meta name="description" content="<%= productDescription %>" />
<meta name="format-detection" content="telephone=no"> <meta name="format-detection" content="telephone=no" />
<meta name="msapplication-tap-highlight" content="no"> <meta name="msapplication-tap-highlight" content="no" />
<meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width<% if (ctx.mode.cordova || ctx.mode.capacitor) { %>, viewport-fit=cover<% } %>"> <meta
name="viewport"
content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width<% if (ctx.mode.cordova || ctx.mode.capacitor) { %>, viewport-fit=cover<% } %>"
/>
<link rel="icon" type="image/png" sizes="128x128" href="icons/favicon-128x128.png"> <link rel="icon" type="image/png" sizes="128x128" href="icons/favicon-128x128.png" />
<link rel="icon" type="image/png" sizes="96x96" href="icons/favicon-96x96.png"> <link rel="icon" type="image/png" sizes="96x96" href="icons/favicon-96x96.png" />
<link rel="icon" type="image/png" sizes="32x32" href="icons/favicon-32x32.png"> <link rel="icon" type="image/png" sizes="32x32" href="icons/favicon-32x32.png" />
<link rel="icon" type="image/png" sizes="16x16" href="icons/favicon-16x16.png"> <link rel="icon" type="image/png" sizes="16x16" href="icons/favicon-16x16.png" />
<link rel="icon" type="image/ico" href="favicon.ico"> <link rel="icon" type="image/ico" href="favicon.ico" />
</head> </head>
<body> <body>
<!-- DO NOT touch the following DIV --> <!-- DO NOT touch the following DIV -->
<div id="q-app"></div> <div id="q-app"></div>
</body> </body>
</html> </html>

View File

@ -1,116 +1,95 @@
<template> <template>
<q-layout view="lHh Lpr lFf"> <q-layout view="lHh Lpr lFf">
<q-header elevated> <q-header elevated>
<q-toolbar> <q-toolbar>
<q-btn <q-btn flat dense round icon="menu" aria-label="Menu" @click="toggleLeftDrawer" />
flat
dense
round
icon="menu"
aria-label="Menu"
@click="toggleLeftDrawer"
/>
<q-toolbar-title> <q-toolbar-title> Quasar App </q-toolbar-title>
Quasar App
</q-toolbar-title>
<div>Quasar v{{ $q.version }}</div> <div>Quasar v{{ $q.version }}</div>
</q-toolbar> </q-toolbar>
</q-header> </q-header>
<q-drawer <q-drawer v-model="leftDrawerOpen" show-if-above bordered>
v-model="leftDrawerOpen" <q-list>
show-if-above <q-item-label header> Essential Links </q-item-label>
bordered
>
<q-list>
<q-item-label
header
>
Essential Links
</q-item-label>
<EssentialLink <EssentialLink v-for="link in essentialLinks" :key="link.title" v-bind="link" />
v-for="link in essentialLinks" </q-list>
:key="link.title" </q-drawer>
v-bind="link"
/>
</q-list>
</q-drawer>
<q-page-container> <q-page-container>
<router-view /> <router-view />
</q-page-container> </q-page-container>
</q-layout> </q-layout>
</template> </template>
<script> <script>
import { defineComponent, ref } from 'vue' import { defineComponent, ref } from 'vue';
import EssentialLink from 'components/EssentialLink.vue' import EssentialLink from 'components/EssentialLink.vue';
const linksList = [ const linksList = [
{ {
title: 'Docs', title: 'Docs',
caption: 'quasar.dev', caption: 'quasar.dev',
icon: 'school', icon: 'school',
link: 'https://quasar.dev' link: 'https://quasar.dev',
}, },
{ {
title: 'Github', title: 'Github',
caption: 'github.com/quasarframework', caption: 'github.com/quasarframework',
icon: 'code', icon: 'code',
link: 'https://github.com/quasarframework' link: 'https://github.com/quasarframework',
}, },
{ {
title: 'Discord Chat Channel', title: 'Discord Chat Channel',
caption: 'chat.quasar.dev', caption: 'chat.quasar.dev',
icon: 'chat', icon: 'chat',
link: 'https://chat.quasar.dev' link: 'https://chat.quasar.dev',
}, },
{ {
title: 'Forum', title: 'Forum',
caption: 'forum.quasar.dev', caption: 'forum.quasar.dev',
icon: 'record_voice_over', icon: 'record_voice_over',
link: 'https://forum.quasar.dev' link: 'https://forum.quasar.dev',
}, },
{ {
title: 'Twitter', title: 'Twitter',
caption: '@quasarframework', caption: '@quasarframework',
icon: 'rss_feed', icon: 'rss_feed',
link: 'https://twitter.quasar.dev' link: 'https://twitter.quasar.dev',
}, },
{ {
title: 'Facebook', title: 'Facebook',
caption: '@QuasarFramework', caption: '@QuasarFramework',
icon: 'public', icon: 'public',
link: 'https://facebook.quasar.dev' link: 'https://facebook.quasar.dev',
}, },
{ {
title: 'Quasar Awesome', title: 'Quasar Awesome',
caption: 'Community Quasar projects', caption: 'Community Quasar projects',
icon: 'favorite', icon: 'favorite',
link: 'https://awesome.quasar.dev' link: 'https://awesome.quasar.dev',
} },
] ];
export default defineComponent({ export default defineComponent({
name: 'MainLayout', name: 'MainLayout',
components: { components: {
EssentialLink EssentialLink,
}, },
setup () { setup() {
const leftDrawerOpen = ref(false) const leftDrawerOpen = ref(false);
return { return {
essentialLinks: linksList, essentialLinks: linksList,
leftDrawerOpen, leftDrawerOpen,
toggleLeftDrawer () { toggleLeftDrawer() {
leftDrawerOpen.value = !leftDrawerOpen.value leftDrawerOpen.value = !leftDrawerOpen.value;
} },
} };
} },
}) });
</script> </script>

View File

@ -1,31 +1,19 @@
<template> <template>
<div class="fullscreen bg-blue text-white text-center q-pa-md flex flex-center"> <div class="fullscreen bg-blue text-white text-center q-pa-md flex flex-center">
<div> <div>
<div style="font-size: 30vh"> <div style="font-size: 30vh">404</div>
404
</div>
<div class="text-h2" style="opacity:.4"> <div class="text-h2" style="opacity: 0.4">Oops. Nothing here...</div>
Oops. Nothing here...
</div>
<q-btn <q-btn class="q-mt-xl" color="white" text-color="blue" unelevated to="/" label="Go Home" no-caps />
class="q-mt-xl" </div>
color="white"
text-color="blue"
unelevated
to="/"
label="Go Home"
no-caps
/>
</div> </div>
</div>
</template> </template>
<script> <script>
import { defineComponent } from 'vue' import { defineComponent } from 'vue';
export default defineComponent({ export default defineComponent({
name: 'ErrorNotFound' name: 'ErrorNotFound',
}) });
</script> </script>

View File

@ -1,17 +1,13 @@
<template> <template>
<q-page class="flex flex-center"> <q-page class="flex flex-center">
<img <img alt="Quasar logo" src="~assets/quasar-logo-vertical.svg" style="width: 200px; height: 200px" />
alt="Quasar logo" </q-page>
src="~assets/quasar-logo-vertical.svg"
style="width: 200px; height: 200px"
>
</q-page>
</template> </template>
<script> <script>
import { defineComponent } from 'vue' import { defineComponent } from 'vue';
export default defineComponent({ export default defineComponent({
name: 'IndexPage' name: 'IndexPage',
}) });
</script> </script>

View File

@ -1,6 +1,6 @@
import { route } from 'quasar/wrappers' import { route } from 'quasar/wrappers';
import { createRouter, createMemoryHistory, createWebHistory, createWebHashHistory } from 'vue-router' import { createRouter, createMemoryHistory, createWebHistory, createWebHashHistory } from 'vue-router';
import routes from './routes' import routes from './routes';
/* /*
* If not building with SSR mode, you can * If not building with SSR mode, you can
@ -12,19 +12,21 @@ import routes from './routes'
*/ */
export default route(function (/* { store, ssrContext } */) { export default route(function (/* { store, ssrContext } */) {
const createHistory = process.env.SERVER const createHistory = process.env.SERVER
? createMemoryHistory ? createMemoryHistory
: (process.env.VUE_ROUTER_MODE === 'history' ? createWebHistory : createWebHashHistory) : process.env.VUE_ROUTER_MODE === 'history'
? createWebHistory
: createWebHashHistory;
const Router = createRouter({ const Router = createRouter({
scrollBehavior: () => ({ left: 0, top: 0 }), scrollBehavior: () => ({ left: 0, top: 0 }),
routes, routes,
// Leave this as is and make changes in quasar.conf.js instead! // Leave this as is and make changes in quasar.conf.js instead!
// quasar.conf.js -> build -> vueRouterMode // quasar.conf.js -> build -> vueRouterMode
// quasar.conf.js -> build -> publicPath // quasar.conf.js -> build -> publicPath
history: createHistory(process.env.MODE === 'ssr' ? void 0 : process.env.VUE_ROUTER_BASE) history: createHistory(process.env.MODE === 'ssr' ? void 0 : process.env.VUE_ROUTER_BASE),
}) });
return Router return Router;
}) });

View File

@ -1,19 +1,16 @@
const routes = [ const routes = [
{ {
path: '/', path: '/',
component: () => import('layouts/MainLayout.vue'), component: () => import('layouts/MainLayout.vue'),
children: [ children: [{ path: '', component: () => import('pages/IndexPage.vue') }],
{ path: '', component: () => import('pages/IndexPage.vue') } },
]
},
// Always leave this as last one, // Always leave this as last one,
// but you can also remove it // but you can also remove it
{ {
path: '/:catchAll(.*)*', path: '/:catchAll(.*)*',
component: () => import('pages/ErrorNotFound.vue') component: () => import('pages/ErrorNotFound.vue'),
} },
] ];
export default routes export default routes;

View File

@ -1,5 +1,5 @@
{ {
"name": "Using fixtures to represent data", "name": "Using fixtures to represent data",
"email": "hello@cypress.io", "email": "hello@cypress.io",
"body": "Fixtures are a great way to mock data for responses to routes" "body": "Fixtures are a great way to mock data for responses to routes"
} }

View File

@ -6,12 +6,12 @@
// This test will pass when run against a clean Quasar project // This test will pass when run against a clean Quasar project
describe('Landing', () => { describe('Landing', () => {
beforeEach(() => { beforeEach(() => {
cy.visit('/'); cy.visit('/');
}); });
it('.should() - assert that <title> is correct', () => { it('.should() - assert that <title> is correct', () => {
cy.title().should('include', 'Quasar'); cy.title().should('include', 'Quasar');
}); });
}); });
// ** The following code is an example to show you how to write some tests for your home page ** // ** The following code is an example to show you how to write some tests for your home page **

View File

@ -21,11 +21,11 @@
// * @type {Cypress.PluginConfig} // * @type {Cypress.PluginConfig}
// */ // */
module.exports = async (on, config) => { module.exports = async (on, config) => {
// // Enable component testing, you can safely remove this // // Enable component testing, you can safely remove this
// // if you don't plan to use Cypress for unit tests // // if you don't plan to use Cypress for unit tests
// if (config.testingType === 'component') { // if (config.testingType === 'component') {
// await injectDevServer(on, config); // await injectDevServer(on, config);
// } // }
return config; return config;
}; };

View File

@ -36,7 +36,7 @@ import { Dialog } from 'quasar';
// For example use the actual i18n instance or mock it // For example use the actual i18n instance or mock it
// config.global.plugins.push(i18n); // config.global.plugins.push(i18n);
config.global.mocks = { config.global.mocks = {
$t: () => '', $t: () => '',
}; };
// Overwrite the transition and transition-group stubs which are stubbed by test-utils by default. // Overwrite the transition and transition-group stubs which are stubbed by test-utils by default.

View File

@ -3,24 +3,24 @@ import { defineComponent } from 'vue';
import { Dialog } from 'quasar'; import { Dialog } from 'quasar';
export default defineComponent({ export default defineComponent({
name: 'DialogWrapper', name: 'DialogWrapper',
props: { props: {
component: { component: {
type: Object, type: Object,
required: true, required: true,
},
componentProps: {
type: Object,
default: () => ({}),
},
}, },
componentProps: { setup(props) {
type: Object, Dialog.create({
default: () => ({}), component: props.component,
},
},
setup(props) {
Dialog.create({
component: props.component,
// props forwarded to your custom component // props forwarded to your custom component
componentProps: props.componentProps, componentProps: props.componentProps,
}); });
}, },
}); });
</script> </script>

View File

@ -1,20 +1,20 @@
<template> <template>
<q-layout> <q-layout>
<component :is="component" v-bind="$attrs" /> <component :is="component" v-bind="$attrs" />
</q-layout> </q-layout>
</template> </template>
<script> <script>
import { defineComponent } from 'vue'; import { defineComponent } from 'vue';
export default defineComponent({ export default defineComponent({
name: 'LayoutContainer', name: 'LayoutContainer',
inheritAttrs: false, inheritAttrs: false,
props: { props: {
component: { component: {
type: Object, type: Object,
required: true, required: true,
},
}, },
},
}); });
</script> </script>

View File

@ -1,10 +1,10 @@
module.exports = { module.exports = {
extends: [ extends: [
// Removes 'no-undef' lint errors for Jest global functions (`describe`, `it`, etc), // Removes 'no-undef' lint errors for Jest global functions (`describe`, `it`, etc),
// add Jest-specific lint rules and Jest plugin // add Jest-specific lint rules and Jest plugin
// See https://github.com/jest-community/eslint-plugin-jest#recommended // See https://github.com/jest-community/eslint-plugin-jest#recommended
'plugin:jest/recommended', 'plugin:jest/recommended',
// Uncomment following line to apply style rules // Uncomment following line to apply style rules
// 'plugin:jest/style', // 'plugin:jest/style',
], ],
}; };

View File

@ -8,35 +8,35 @@ import MyButton from './demo/MyButton';
installQuasarPlugin(); installQuasarPlugin();
describe('MyButton', () => { describe('MyButton', () => {
it('has increment method', () => { it('has increment method', () => {
const wrapper = mount(MyButton); const wrapper = mount(MyButton);
const { vm } = wrapper; const { vm } = wrapper;
expect(typeof vm.increment).toBe('function'); expect(typeof vm.increment).toBe('function');
}); });
it('can check the inner text content', () => { it('can check the inner text content', () => {
const wrapper = mount(MyButton); const wrapper = mount(MyButton);
const { vm } = wrapper; const { vm } = wrapper;
expect(vm.$el.textContent).toContain('rocket muffin'); expect(vm.$el.textContent).toContain('rocket muffin');
expect(wrapper.find('.content').text()).toContain('rocket muffin'); expect(wrapper.find('.content').text()).toContain('rocket muffin');
}); });
it('sets the correct default data', () => { it('sets the correct default data', () => {
const wrapper = mount(MyButton); const wrapper = mount(MyButton);
const { vm } = wrapper; const { vm } = wrapper;
expect(typeof vm.counter).toBe('number'); expect(typeof vm.counter).toBe('number');
expect(vm.counter).toBe(0); expect(vm.counter).toBe(0);
}); });
it('correctly updates counter when button is pressed', async () => { it('correctly updates counter when button is pressed', async () => {
const wrapper = shallowMount(MyButton); const wrapper = shallowMount(MyButton);
const { vm } = wrapper; const { vm } = wrapper;
const button = wrapper.findComponent(QBtn); const button = wrapper.findComponent(QBtn);
await button.trigger('click'); await button.trigger('click');
expect(vm.counter).toBe(1); expect(vm.counter).toBe(1);
}); });
}); });

View File

@ -6,25 +6,23 @@ import MyDialog from './demo/MyDialog';
installQuasarPlugin(); installQuasarPlugin();
describe('MyDialog', () => { describe('MyDialog', () => {
beforeEach(() => { beforeEach(() => {
mount(MyDialog, { mount(MyDialog, {
data: () => ({ data: () => ({
isDialogOpen: true, isDialogOpen: true,
}), }),
});
}); });
});
it('should mount the document body and expose for testing', () => { it('should mount the document body and expose for testing', () => {
const wrapper = new DOMWrapper(document.body); const wrapper = new DOMWrapper(document.body);
expect(wrapper.find('.q-dialog').exists()).toBeTruthy(); expect(wrapper.find('.q-dialog').exists()).toBeTruthy();
}); });
it('can check the inner text of the dialog', () => { it('can check the inner text of the dialog', () => {
const wrapper = new DOMWrapper(document.body); const wrapper = new DOMWrapper(document.body);
expect(wrapper.find('.q-dialog').html()).toContain( expect(wrapper.find('.q-dialog').html()).toContain('Custom dialog which should be tested');
'Custom dialog which should be tested', });
);
});
}); });

View File

@ -2,29 +2,29 @@
import { defineComponent, ref } from 'vue'; import { defineComponent, ref } from 'vue';
export default defineComponent({ export default defineComponent({
name: 'MyButton', name: 'MyButton',
props: { props: {
incrementStep: { incrementStep: {
type: Number, type: Number,
default: 1, default: 1,
},
}, },
}, setup(props) {
setup(props) { const counter = ref(0);
const counter = ref(0); const input = ref('rocket muffin');
const input = ref('rocket muffin'); function increment() {
function increment() { counter.value += props.incrementStep;
counter.value += props.incrementStep; }
}
return { counter, input, increment }; return { counter, input, increment };
}, },
}); });
</script> </script>
<template> <template>
<div> <div>
<p class="content">{{ input }}</p> <p class="content">{{ input }}</p>
<span>{{ counter }}</span> <span>{{ counter }}</span>
<q-btn class="button" @click="increment()"></q-btn> <q-btn class="button" @click="increment()"></q-btn>
</div> </div>
</template> </template>

View File

@ -1,20 +1,20 @@
<template> <template>
<q-dialog v-model="isDialogOpen"> <q-dialog v-model="isDialogOpen">
<q-card> <q-card>
<q-card-section>Custom dialog which should be tested</q-card-section> <q-card-section>Custom dialog which should be tested</q-card-section>
</q-card> </q-card>
</q-dialog> </q-dialog>
</template> </template>
<script> <script>
import { defineComponent } from 'vue'; import { defineComponent } from 'vue';
export default defineComponent({ export default defineComponent({
name: 'MyDialog', name: 'MyDialog',
data() { data() {
return { return {
isDialogOpen: false, isDialogOpen: false,
}; };
}, },
}); });
</script> </script>