From 734150639205dc2cb9bab219b2592f0e36668082 Mon Sep 17 00:00:00 2001 From: cedricabuso Date: Fri, 3 Mar 2023 11:29:37 +0800 Subject: [PATCH] Dev-3730 Platforms > Upgrade Quasar to latest versions (#54) --- .eslintignore | 84 ++++- README.md | 43 ++- package.json | 90 +++-- public/blank-avatar.png | Bin 0 -> 1544 bytes .../statics => public}/icons/icon-128x128.png | Bin .../statics => public}/icons/icon-192x192.png | Bin .../statics => public}/icons/icon-256x256.png | Bin .../statics => public}/icons/icon-384x384.png | Bin .../statics => public}/icons/icon-512x512.png | Bin quasar.conf.js | 198 ----------- quasar.config.js | 308 ++++++++++++++++++ src/boot/api.js | 120 +++++++ src/boot/axios.js | 13 +- src/boot/google-api.js | 19 +- src/boot/jwt.js | 19 +- src/boot/notify.js | 77 +++-- src/boot/vue-analytics.js | 26 ++ src/boot/vue-i18next.js | 33 +- src/router/index.js | 4 +- src/statics/app-logo.png | Bin 7197 -> 0 bytes src/statics/icons/apple-icon-152x152.png | Bin 13156 -> 0 bytes src/statics/icons/favicon-16x16.png | Bin 1355 -> 0 bytes src/statics/icons/favicon-32x32.png | Bin 2604 -> 0 bytes src/statics/icons/ms-icon-144x144.png | Bin 12292 -> 0 bytes 24 files changed, 675 insertions(+), 359 deletions(-) create mode 100644 public/blank-avatar.png rename {src/statics => public}/icons/icon-128x128.png (100%) rename {src/statics => public}/icons/icon-192x192.png (100%) rename {src/statics => public}/icons/icon-256x256.png (100%) rename {src/statics => public}/icons/icon-384x384.png (100%) rename {src/statics => public}/icons/icon-512x512.png (100%) delete mode 100644 quasar.conf.js create mode 100644 quasar.config.js create mode 100644 src/boot/api.js create mode 100644 src/boot/vue-analytics.js delete mode 100644 src/statics/app-logo.png delete mode 100644 src/statics/icons/apple-icon-152x152.png delete mode 100644 src/statics/icons/favicon-16x16.png delete mode 100644 src/statics/icons/favicon-32x32.png delete mode 100644 src/statics/icons/ms-icon-144x144.png diff --git a/.eslintignore b/.eslintignore index 0157478..8fb6a9c 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1,3 +1,81 @@ -/dist -quasar.conf.js -config/ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage + +# nyc test coverage +.nyc_output + +# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# Bower dependency directory (https://bower.io/) +bower_components + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (http://nodejs.org/api/addons.html) +build/Release + +# Dependency directories +node_modules/ +jspm_packages/ + +# Typescript v1 declaration files +typings/ + +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +# Optional REPL history +.node_repl_history + +# Output of 'npm pack' +*.tgz + +# Yarn Integrity file +.yarn-integrity + +# dotenv environment variables file +.env + +# Editor workspace settings +.idea/ +.vscode/ + +# dependencies lock file +package-lock.json +yarn.lock + +# Quasar Framework ignored files +.quasar +.DS_Store +.thumbs.db +dist/ +/src-cordova/platforms +/src-cordova/plugins +/src-cordova/www + +# esdoc +docs/ + +/src-pwa/pwa-flag.d.ts +/src/store/store-flag.d.ts diff --git a/README.md b/README.md index 6b3915d..bd9adfe 100644 --- a/README.md +++ b/README.md @@ -2,32 +2,45 @@ > Frontend boilerplate using Quasar Framework -## Build Setup +## Env pre-requisites +```bash +"node": ">= 12.22.1", +"npm": ">= 6.13.4", +"yarn": ">= 1.21.1" -``` bash +``` + +## Install the dependencies +```bash # install cross-env $ npm i -g cross-env -# install dependencies -$ npm install +yarn +# or +npm install +``` -# serve with hot reload at localhost:8081 -$ npm run dev +### Start the app in development mode (hot-code reloading, error reporting, etc.) +```bash +npm run dev +``` -# build for production with minification -$ npm run build +### Build the app for production +```bash +npm run build +``` +### Other commands +```bash # lint code $ npm run lint # fix lint errors -$ npm run lint -- --fix - -# run unit tests -$ npm test - -# TDD -$ npm run tdd +$ npm run lint-fix ``` +### Customize the configuration +See [Configuring quasar.config.js](https://v2.quasar.dev/quasar-cli-webpack/quasar-config-js). + +### Boilerplate usage For more information regarding usage, see [WIKI](https://github.com/anyTV/quasar-boilerplate/wiki). diff --git a/package.json b/package.json index a74239c..ca7ac45 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "anytv-quasar-boilerplate", - "version": "1.6.0", + "version": "2.0.0", "description": "AnyTV Quasar Boilerplate", "repository": "https://github.com/anyTV/quasar-boilerplate", "productName": "Freedom! App", @@ -13,58 +13,52 @@ "scripts": { "lint": "eslint --ext .js,.vue src", "lint-fix": "eslint --fix --ext .js,.vue src", - "dev": "cross-env node node_modules/@quasar/cli/bin/quasar dev", - "docs": "esdoc", + "dev": "cross-env npx quasar dev -m pwa", + "build": "cross-env NODE_ENV=production npx quasar build -m pwa", "postinstall": "quasar-app-extension-freedom-components" }, "dependencies": { - "@panter/vue-i18next": "^0.15.1", - "@quasar/app": "^1.9.6", - "@quasar/extras": "^1.10.10", - "axios": "^0.21.1", - "i18next": "^10.2.2", - "i18next-browser-languagedetector": "^2.1.0", - "i18next-http-backend": "^1.2.4", - "jsonwebtoken": "^8.2.1", - "lodash-es": "^4.17.10", - "moment": "^2.20.1", - "qs": "^6.5.2", - "quasar": "^1.15.23", - "quasar-app-extension-freedom-components": "git+https://freedom-components-readonly:9jawmhdE8Pxuzy6a5yQQ@gitlab.com/anyTV/incubator/freedom-components.git#v1.8.0", - "vue": "2.6.11", - "vue-gtm": "3.1.0-vue2", - "vue-router": "^3.0.1", - "vue-template-compiler": "2.6.11", - "vuelidate": "^0.7.6", - "vuex": "^3.0.1" - }, - "dependenciesComments": { - "vue-gtm": "Default packages are built for vue3, use `-vue2` for all packages that would be installed. @see https://github.com/mib200/vue-gtm/issues/98" + "@quasar/extras": "^1.0.0", + "@vuelidate/core": "^2.0.0", + "@vuelidate/validators": "^2.0.0", + "axios": "^1.3.4", + "core-js": "^3.6.5", + "eslint-webpack-plugin": "^4.0.0", + "i18next": "^22.4.10", + "i18next-browser-languagedetector": "^7.0.1", + "i18next-http-backend": "^2.1.1", + "jsonwebtoken": "^9.0.0", + "moment": "^2.29.4", + "node-polyfill-webpack-plugin": "^2.0.1", + "pinia": "^2.0.32", + "qs": "^6.11.0", + "quasar": "^2.6.0", + "quasar-app-extension-freedom-components": "git+https://freedom-components-readonly:9jawmhdE8Pxuzy6a5yQQ@gitlab.com/anyTV/incubator/freedom-components.git#v1.11.11", + "vue": "^3.2.33", + "vue-analytics": "^5.22.1", + "vue-i18n": "^9.2.2", + "vue-router": "^4.0.0", + "workbox-webpack-plugin": "^6.5.4" }, "devDependencies": { - "@quasar/cli": "^1.2.1", - "babel-eslint": "^8.2.1", - "cross-env": "^7.0.3", - "esdoc": "^1.1.0", - "esdoc-standard-plugin": "^1.0.0", - "eslint": "^7.32.0", - "eslint-friendly-formatter": "^4.0.1", - "eslint-plugin-import": "^2.9.0", - "eslint-plugin-node": "^6.0.1", - "eslint-plugin-promise": "^3.7.0", - "eslint-plugin-vue": "^7.0.0", - "eslint-webpack-plugin": "^3.1.1", - "lodash": "^4.17.10", - "strip-ansi": "^3.0.1", - "webpack": "^4.39.1" - }, - "engines": { - "node": ">= 8.9.0", - "npm": ">= 5.6.0" + "@quasar/app-webpack": "^3.0.0", + "stylus": "^0.59.0", + "stylus-loader": "^7.1.0" }, "browserslist": [ - "> 1%", - "last 2 versions", - "not ie <= 10" - ] + "last 10 Chrome versions", + "last 10 Firefox versions", + "last 4 Edge versions", + "last 7 Safari versions", + "last 8 Android versions", + "last 8 ChromeAndroid versions", + "last 8 FirefoxAndroid versions", + "last 10 iOS versions", + "last 5 Opera versions" + ], + "engines": { + "node": ">= 12.22.1", + "npm": ">= 6.13.4", + "yarn": ">= 1.21.1" + } } diff --git a/public/blank-avatar.png b/public/blank-avatar.png new file mode 100644 index 0000000000000000000000000000000000000000..ae4c4a65fdd8e8adb7ffe336bf30ca6f99f73fd7 GIT binary patch literal 1544 zcmV+j2KV`iP)P)t-soL&C%1{;Nix~%-Y@FxxT^4&Cj#A zyVu#<(bU$vz{BR~>D1TQzr@DicU9~F00nqSL_t(|+U=W*lG`8*MZtm+{C>v%|1T|E zpmf^$)rH+o$9FxklT6I9BoIbk_UO^0M~@yodi3bgqfb#$n9aQSo!LH7zEw0D_ns%W zA^;i{LYUXEXDmNNBnVgke&Y>xfXL4P0<03qWLKhy(yAr?wwS zInmg+tDz8J$O{1i(@s;VxT$mfh02CRD- z0N*a;X$-_Rpg#@RnPPs6lvWU|R`A31V2}g+ zmvCHaC9H5ALA^v$1SU3h4}q(tw84#5rQJX-eO)f}Y;#G9_GE zR+8VCFQ8At4+$snt-5Z8a4V6LAb5i4`g9@b+!5WfTqGvw7rSH+KV-P8<`)UL8Zz8R zVD@f1>b%ryM7i!w+ypu!D_;KNDz9va$p$ z5ajX2qR8igUjXb*_1+6v8Om0B2#W1{0RC$75-?v7S$n1Ew_*S()z1P1*$Oitz*hcN z6CsjR4W%K>T%H003J%Tusz@3sBlAk*Ha7+!bF~ufBP4`iOmua-RMj|+RkgJBWIqyF ztCavi`w)thZzh_qYnl?rKfcI8f#z|60vBqVE1PMZ=h|srr>-&X@g@QVFw)xJ0-*J# zn}>Gmt5ItrWktmGSoK?rn(3Q)3dC;80x`~7PW7uFxpE3419=oh+JwbyFcKD!0T8U( ztSHb*b&x61IhJAa6bYgNzsL26sjaw*g8?~lZ2lO6Mf5Us!GRxQfC=D%1_k0^_Ji^m zQ7GMxFI2JpaQy)Q40qj7VK9vK$%A=Yq|i&<;0iuK;5tDwRPyKg?1_G^-BMqdaEIOg z&Id>bmG{8aI~gohhs;IG>aEF&zl?%uAqDG31KcPGg#68X-SWN@Skr1rKTS_=GI)rp z7RBAD1hNop>LrER<88$sD#Ant=e{)r5(a^4OecTRazUwo9^wrppQlOEv)AxXCN95 z@B0yp@sSxQIfJX=o<6VwBV-V{D#hU{ROk)45Kwbo57y!=TUg4;X9l?)62J(Q$q2Dd zvHzqE;F@0Yd<-x{yT2wGS2u}g6NOsIz8`#w&LxUVv%5uyUS>7|C*?e`Ll7R@$tOH^ zwKFtW1YZiwsaQDMue|W=qH%&J_Lkb^XK3%?GmzEWE5EjVD}35NIqc0D0P#tJ6}}!} uFG*xqZ0O4!!5%&OHzmGUMZvy(xxNFr4oI6@B#%!30000Pd# literal 0 HcmV?d00001 diff --git a/src/statics/icons/icon-128x128.png b/public/icons/icon-128x128.png similarity index 100% rename from src/statics/icons/icon-128x128.png rename to public/icons/icon-128x128.png diff --git a/src/statics/icons/icon-192x192.png b/public/icons/icon-192x192.png similarity index 100% rename from src/statics/icons/icon-192x192.png rename to public/icons/icon-192x192.png diff --git a/src/statics/icons/icon-256x256.png b/public/icons/icon-256x256.png similarity index 100% rename from src/statics/icons/icon-256x256.png rename to public/icons/icon-256x256.png diff --git a/src/statics/icons/icon-384x384.png b/public/icons/icon-384x384.png similarity index 100% rename from src/statics/icons/icon-384x384.png rename to public/icons/icon-384x384.png diff --git a/src/statics/icons/icon-512x512.png b/public/icons/icon-512x512.png similarity index 100% rename from src/statics/icons/icon-512x512.png rename to public/icons/icon-512x512.png diff --git a/quasar.conf.js b/quasar.conf.js deleted file mode 100644 index b59c5e6..0000000 --- a/quasar.conf.js +++ /dev/null @@ -1,198 +0,0 @@ -const path = require('path'); -const webpack = require('webpack'); -const config = require('./config'); -const pkg = require('./package'); -const ESLintPlugin = require('eslint-webpack-plugin'); - -// Configuration for your app -module.exports = function (ctx) { - return { - // app boot (/src/boot) - boot: [ - /** - * Enable only the plugins that your app is going to use. - */ - 'axios', - 'jwt', - 'notify', - 'admin-api', - // 'google-api', - 'vuelidate', - 'vue-gtm', - - /** - * if vue-i18next is enabled, we can use directive v-waitForT so translations can be loaded first - * before rendering the component - */ - 'vue-i18next', - ], - css: [ - 'app.styl' - ], - extras: [ - 'material-icons', - // 'mdi-v3', - // 'fontawesome-v5', - // 'ionicons-v4' - ], - supportIE: true, - build: { - // gzip: true, // use if deployment server does not have gzip by default - scopeHoisting: true, - vueRouterMode: 'history', - publicPath: '/', - analyze: process.env.ANALYZE, - devtool: 'source-map', - env: config.env, - extendWebpack(cfg) { - cfg.plugins.push(new ESLintPlugin({ - extensions: ['js', 'vue'], - exclude: ['node_modules', 'quasar'], - })); - - cfg.resolve.alias = { - ...cfg.resolve.alias, - // add custom aliases below - '@': path.resolve(__dirname, './src/components'), - 'lodash': 'lodash-es', - }; - - // ignore moment locales - cfg.plugins.push(new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/)); - } - }, - devServer: { - https: true, - port: 8080, - open: true, // opens browser window automatically - // proxy: { - // '/api': { - // target: '', - // changeOrigin: true, - // pathRewrite: { - // '^/api': '' - // } - // } - // } - }, - // framework: 'all' --- includes everything; for dev only! - framework: { - components: [ - 'QAvatar', - 'QBadge', - 'QBar', - 'QBreadcrumbs', - 'QBreadcrumbsEl', - 'QBtn', - 'QBtnToggle', - 'QCard', - 'QCardActions', - 'QCardSection', - 'QChip', - 'QDate', - 'QFooter', - 'QHeader', - 'QIcon', - 'QInput', - 'QItem', - 'QItemLabel', - 'QItemSection', - 'QLayout', - 'QList', - 'QMenu', - 'QOptionGroup', - 'QPagination', - 'QPopupProxy', - 'QRadio', - 'QSelect', - 'QSeparator', - 'QSpace', - 'QTab', - 'QTabPanel', - 'QTabPanels', - 'QTable', - 'QTabs', - 'QToggle', - 'QToolbar', - 'QToolbarTitle', - ], - directives: [], - // Quasar plugins - plugins: [ - 'Notify', - 'Loading', - 'LocalStorage', - ] - }, - // animations: 'all' --- includes all animations - animations: [], - pwa: { - // workboxPluginMode: 'InjectManifest', - workboxOptions: { - skipWaiting: true - }, - manifest: { - name: pkg.productName, - short_name: pkg.name, - description: pkg.description, - display: 'standalone', - orientation: 'portrait', - background_color: '#ffffff', - theme_color: '#027be3', - icons: [ - { - 'src': 'statics/icons/icon-128x128.png', - 'sizes': '128x128', - 'type': 'image/png' - }, - { - 'src': 'statics/icons/icon-192x192.png', - 'sizes': '192x192', - 'type': 'image/png' - }, - { - 'src': 'statics/icons/icon-256x256.png', - 'sizes': '256x256', - 'type': 'image/png' - }, - { - 'src': 'statics/icons/icon-384x384.png', - 'sizes': '384x384', - 'type': 'image/png' - }, - { - 'src': 'statics/icons/icon-512x512.png', - 'sizes': '512x512', - 'type': 'image/png' - } - ] - } - }, - cordova: { - // id: 'org.cordova.quasar.app' - }, - electron: { - // bundler: 'builder', // or 'packager' - extendWebpack(cfg) { - // do something with Electron process Webpack cfg - }, - packager: { - // https://github.com/electron-userland/electron-packager/blob/master/docs/api.md#options - - // OS X / Mac App Store - // appBundleId: '', - // appCategoryType: '', - // osxSign: '', - // protocol: 'myapp://path', - - // Window only - // win32metadata: { ... } - }, - builder: { - // https://www.electron.build/configuration/configuration - - // appId: 'quasar-app' - } - } - }; -}; diff --git a/quasar.config.js b/quasar.config.js new file mode 100644 index 0000000..d36c652 --- /dev/null +++ b/quasar.config.js @@ -0,0 +1,308 @@ +/* eslint-env node */ + +/* + * This file runs in a Node context (it's NOT transpiled by Babel), so use only + * the ES6 features that are supported by your Node version. https://node.green/ + */ + +// Configuration for your app +// https://v2.quasar.dev/quasar-cli-webpack/quasar-config-js + + +const { configure } = require('quasar/wrappers'); +const nodePolyfillWebpackPlugin = require('node-polyfill-webpack-plugin'); + +const config = require('./config'); +const pkg = require('./package'); + +module.exports = configure(function (ctx) { + return { + // https://v2.quasar.dev/quasar-cli-webpack/supporting-ts + supportTS: false, + + // https://v2.quasar.dev/quasar-cli-webpack/prefetch-feature + // preFetch: true, + + // app boot file (/src/boot) + // --> boot files are part of "main.js" + // https://v2.quasar.dev/quasar-cli-webpack/boot-files + boot: [ + /** + * if vue-i18next is enabled, we can use directive v-waitForT so translations can be loaded first + * before rendering the component + */ + 'vue-i18next', + + /** + * Enable only the plugins that your app is going to use. + */ + 'axios', + 'jwt', + 'notify', + 'api', + // 'google-api', + ], + + // https://v2.quasar.dev/quasar-cli-webpack/quasar-config-js#Property%3A-css + css: [ + 'app.scss' + ], + + // https://github.com/quasarframework/quasar/tree/dev/extras + extras: [ + // 'ionicons-v4', + // 'mdi-v5', + // 'fontawesome-v6', + // 'eva-icons', + // 'themify', + // 'line-awesome', + // 'roboto-font-latin-ext', // this or either 'roboto-font', NEVER both! + + 'roboto-font', // 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 + build: { + scopeHoisting: true, + vueRouterMode: 'history', // available values: 'hash', 'history' + publicPath: '/', + analyze: process.env.ANALYZE, + env: config.env, + devtool: 'source-map', + // transpile: false, + + // Add dependencies for transpiling with Babel (Array of string/regex) + // (from node_modules, which are by default not transpiled). + // Applies only if "transpile" is set to true. + // transpileDependencies: [], + + // rtl: true, // https://quasar.dev/options/rtl-support + // preloadChunks: true, + // showProgress: false, + // gzip: true, + + // Options below are automatically set depending on the env, set them if you want to override + // extractCSS: false, + + // https://v2.quasar.dev/quasar-cli-webpack/handling-webpack + // "chain" is a webpack-chain object https://github.com/neutrinojs/webpack-chain + chainWebpack (chain) { + chain + .plugin('node-polyfill') + .use(nodePolyfillWebpackPlugin); + } + + }, + + // Full list of options: https://v2.quasar.dev/quasar-cli-webpack/quasar-config-js#Property%3A-devServer + devServer: { + server: { + type: 'https' + }, + port: 8000, + open: true, // opens browser window automatically + + proxy: { + '/api': { + target: 'http://localhost:5000', + secure: false, + changeOrigin: true, + pathRewrite: { + '^/api': '/api' + } + } + } + }, + + // https://v2.quasar.dev/quasar-cli-webpack/quasar-config-js#Property%3A-framework + framework: { + config: {}, + + iconSet: 'material-icons', // Quasar icon set + // lang: 'en-US', // Quasar language pack + + // For special cases outside of where the auto-import strategy can have an impact + // (like functional components as one of the examples), + // you can manually specify Quasar components/directives to be available everywhere: + // + components: [ + 'QAvatar', + 'QBadge', + 'QBar', + 'QBreadcrumbs', + 'QBreadcrumbsEl', + 'QBtn', + 'QBtnToggle', + 'QCard', + 'QCardActions', + 'QCardSection', + 'QCarousel', + 'QCarouselSlide', + 'QChip', + 'QDate', + 'QExpansionItem', + 'QFooter', + 'QHeader', + 'QIcon', + 'QImg', + 'QInput', + 'QItem', + 'QItemLabel', + 'QItemSection', + 'QLayout', + 'QList', + 'QMenu', + 'QOptionGroup', + 'QPage', + 'QPageContainer', + 'QPageSticky', + 'QPagination', + 'QPopupProxy', + 'QRadio', + 'QSelect', + 'QSeparator', + 'QSpace', + 'QTab', + 'QTabPanel', + 'QTabPanels', + 'QTable', + 'QTabs', + 'QToggle', + 'QToolbar', + 'QToolbarTitle', + ], + // directives: [], + + // Quasar plugins + plugins: [ + 'Notify', + 'Dialog', + 'Loading', + 'LocalStorage', + 'SessionStorage', + ] + }, + + // animations: 'all', // --- includes all animations + // https://quasar.dev/options/animations + animations: [], + + // https://v2.quasar.dev/quasar-cli-webpack/developing-ssr/configuring-ssr + ssr: { + pwa: true, + + // manualStoreHydration: true, + // manualPostHydrationTrigger: true, + + prodPort: 3000, // The default port that the production server should use + // (gets superseded if process.env.PORT is specified at runtime) + + maxAge: 1000 * 60 * 60 * 24 * 30, + // Tell browser when a file from the server should expire from cache (in ms) + + + chainWebpackWebserver (/* chain */) {}, + + + middlewares: [ + ctx.prod ? 'compression' : '', + 'render' // keep this as last one + ] + }, + + // https://v2.quasar.dev/quasar-cli-webpack/developing-pwa/configuring-pwa + pwa: { + workboxPluginMode: 'GenerateSW', // 'GenerateSW' or 'InjectManifest' + workboxOptions: { + skipWaiting: true + }, + + // for the custom service worker ONLY (/src-pwa/custom-service-worker.[js|ts]) + // if using workbox in InjectManifest mode + + chainWebpackCustomSW (/* chain */) {}, + + + manifest: { + name: pkg.productName, + short_name: pkg.name, + description: pkg.description, + 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' + } + ] + } + }, + + // Full list of options: https://v2.quasar.dev/quasar-cli-webpack/developing-cordova-apps/configuring-cordova + cordova: { + // 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 + capacitor: { + hideSplashscreen: true + }, + + // Full list of options: https://v2.quasar.dev/quasar-cli-webpack/developing-electron-apps/configuring-electron + electron: { + bundler: 'packager', // 'packager' or 'builder' + + packager: { + // https://github.com/electron-userland/electron-packager/blob/master/docs/api.md#options + + // OS X / Mac App Store + // appBundleId: '', + // appCategoryType: '', + // osxSign: '', + // protocol: 'myapp://path', + + // Windows only + // win32metadata: { ... } + }, + + builder: { + // https://www.electron.build/configuration/configuration + + appId: pkg.name + }, + + // "chain" is a webpack-chain object https://github.com/neutrinojs/webpack-chain + + chainWebpackMain (/* chain */) {}, + + + + chainWebpackPreload (/* chain */) {}, + + } + } +}); diff --git a/src/boot/api.js b/src/boot/api.js new file mode 100644 index 0000000..5246d77 --- /dev/null +++ b/src/boot/api.js @@ -0,0 +1,120 @@ +import _ from 'lodash'; +import axios from 'axios'; +import { boot } from 'quasar/wrappers'; +import { stringify } from 'qs'; + +import config from 'src/config'; +import index from 'src/router'; +import { jwt } from 'src/boot/jwt'; + +const apiConfig = { + baseURL: config.API.BASE_URL, + paramsSerializer: { + serialize: (params) => stringify(params, { arrayFormat: 'brackets' }) + } +}; + +const $submit = async (method, endpoint, payload = null) => { + + try { + const api = axios.create({ + headers: { 'Access-Token': jwt.getToken() }, + ...apiConfig + }); + + let response = await api[_.toLower(method)](endpoint, payload); + + return { + httpStatus: { + code: response.status, + text: response.statusText + }, + metadata: _.omit(response.data, ['data']), + data: _.cloneDeep(response.data.data) + }; + } + catch (error) { + // general handler for when error is not from axios (i.e. no response prop) + if (!error.response || error.response.status >= 500) { + throw { + error: 'server_error_notice', + message: 'server_error_notice' + }; + } + + if (error.response.data.code === 'UNAUTH') { + index.push({ + name: 'home', + params: { + errorCode: error.response.data.code + } + }); + + throw { + message: 'session-expired-relogin-prompt' + }; + } + + throw { + httpStatus: { + code: error.response.status, + text: error.response.statusText + }, + code: error.response.data.code, + message: error.response.data.message, + error: error.response.data.error, + }; + } +}; + +const api = { + $get: (endpoint, payload = null) => { + return $submit('get', endpoint, payload); + }, + $post: (endpoint, payload = null) => { + return $submit('post', endpoint, payload); + }, + $put: (endpoint, payload = null) => { + return $submit('put', endpoint, payload); + }, + $patch: (endpoint, payload = null) => { + return $submit('patch', endpoint, payload); + }, + $delete: (endpoint, payload = null) => { + return $submit('delete', endpoint, payload); + }, + + async get_albums() { + return $submit('get', config.API.ALBUMS.GET); + }, + + async post_album(params) { + return $submit('post', config.API.ALBUMS.POST, params); + }, + + async get_images(params) { + return $submit('get', config.API.IMAGE.GET, { params }); + }, + + async add_image(params) { + return $submit('post', config.API.IMAGE.POST, params); + }, + + async get_directory_and_access(params) { + return $submit('get', config.API.ALBUMS.GET_DIRECTORY_ACCESS, { + params, + }); + }, +}; + +/** + * Plugin for injecting axios globally as $api resource + * @example + * // In a component you can use it like: + * this.$api.post(...); + */ +export default boot(({ app }) => { + app.config.globalProperties.$api = api; +}); + +export { api }; diff --git a/src/boot/axios.js b/src/boot/axios.js index 365b425..f44caea 100644 --- a/src/boot/axios.js +++ b/src/boot/axios.js @@ -1,11 +1,6 @@ +import { boot } from 'quasar/wrappers'; import axiosHelper from 'src/helpers/axios'; -export default ({ Vue }) => { - Object.defineProperties(Vue.prototype, { - $axios: { - get() { - return axiosHelper; - } - } - }); -}; +export default boot(({ app }) => { + app.config.globalProperties.$axios = axiosHelper; +}); diff --git a/src/boot/google-api.js b/src/boot/google-api.js index eb891ea..7928f22 100644 --- a/src/boot/google-api.js +++ b/src/boot/google-api.js @@ -1,16 +1,9 @@ +import { boot } from 'quasar/wrappers'; import GoogleAPIClient from 'src/helpers/google-api-client'; -import googleAPIConfig from 'src/config/google-api'; +import google_api_config from 'src/config/google-api'; -export default async ({ Vue }) => { - const client = await GoogleAPIClient(googleAPIConfig); +export default boot(async ({ app }) => { + const client = await GoogleAPIClient(google_api_config); - Vue.googleAPI = client; - - Object.defineProperties(Vue.prototype, { - $googleAPI: { - get() { - return client; - }, - }, - }); -}; + app.config.globalProperties.$google_api = client; +}); diff --git a/src/boot/jwt.js b/src/boot/jwt.js index a33664f..2c9d14c 100644 --- a/src/boot/jwt.js +++ b/src/boot/jwt.js @@ -1,16 +1,11 @@ +import { boot } from 'quasar/wrappers' import JWT from 'src/helpers/jwt'; import config from 'src/config'; +import axiosHelper from "src/helpers/axios"; +const jwt = new JWT(config.JWT_STORAGE_KEY); -export default ({ Vue }) => { - const jwt = new JWT(config.JWT_STORAGE_KEY); +export default boot(({ app }) => { + app.config.globalProperties.$jwt = jwt; +}); - Vue.jwt = jwt; - - Object.defineProperties(Vue.prototype, { - $jwt: { - get() { - return jwt; - } - } - }); -}; +export { jwt }; diff --git a/src/boot/notify.js b/src/boot/notify.js index acb1610..41ae481 100644 --- a/src/boot/notify.js +++ b/src/boot/notify.js @@ -1,10 +1,43 @@ 'use strict'; +import { i18n } from 'src/boot/vue-i18next'; +import { boot } from 'quasar/wrappers'; import { Notify } from 'quasar'; import config from 'src/config'; +const trans = i18n.global.t; + const closeBtn = '✖'; +Notify.setDefaults({ + position: config.NOTIFY_POSITION, + timeout: 5000, + textColor: 'white', +}); + +const notify = { + success: (message) => Notify.create({ + color: 'positive', + message: trans(message), + closeBtn + }), + error: (message) => Notify.create({ + color: 'negative', + message: trans(message), + closeBtn + }), + warning: (message) => Notify.create({ + color: 'warning', + message: trans(message), + closeBtn + }), + info: (message) => Notify.create({ + color: 'info', + message: trans(message), + closeBtn + }), +}; + /** * Usage for notify plugin * @@ -15,42 +48,8 @@ const closeBtn = '✖'; * this.$notify.success('successfully-created'); */ -export default ({ app, Vue }) => { - - Notify.setDefaults({ - position: config.NOTIFY_POSITION, - timeout: 5000, - textColor: 'white', - }); - - const notifyHandlers = { - success: (message) => Notify.create({ - color: 'positive', - message: app.i18n.i18next.t(message), - closeBtn - }), - error: (message) => Notify.create({ - color: 'negative', - message: app.i18n.i18next.t(message), - closeBtn - }), - warning: (message) => Notify.create({ - color: 'warning', - message: app.i18n.i18next.t(message), - closeBtn - }), - info: (message) => Notify.create({ - color: 'info', - message: app.i18n.i18next.t(message), - closeBtn - }), - }; - - Object.defineProperties(Vue.prototype, { - $notify: { - get() { - return notifyHandlers; - } - } - }); -}; +export default boot(({ app }) => { + app.config.globalProperties.$notify = notify; +}); + +export { notify }; diff --git a/src/boot/vue-analytics.js b/src/boot/vue-analytics.js new file mode 100644 index 0000000..e31e7b3 --- /dev/null +++ b/src/boot/vue-analytics.js @@ -0,0 +1,26 @@ +import { boot } from 'quasar/wrappers'; +import VueAnalytics from 'vue-analytics'; +import router from 'src/router'; + +const PROD = process.env.PROD; +/** + * Set Google Analytics ID in src/config/env//index.js > GOOGLE_ANALYTICS_ID. + */ +const GOOGLE_ANALYTICS_ID = process.env.GOOGLE_ANALYTICS_ID; + +export default boot(({ app }) => { + app.use(VueAnalytics, { + id: GOOGLE_ANALYTICS_ID, + router, + autoTracking: { + transformQueryString: false, + skipSamePath: true, + exception: true, + exceptionLogs: false, + }, + debug: { + sendHitTask: PROD, + enabled: !PROD, + }, + }); +}); diff --git a/src/boot/vue-i18next.js b/src/boot/vue-i18next.js index f880029..edd9498 100644 --- a/src/boot/vue-i18next.js +++ b/src/boot/vue-i18next.js @@ -1,9 +1,9 @@ -import i18next from 'i18next'; -import i18nextHttpBackend from 'i18next-http-backend'; -import i18nextLangDetector from 'i18next-browser-languagedetector'; -import VueI18next from '@panter/vue-i18next'; -import i18nextConfig from 'src/config/i18next'; import _ from 'lodash'; +import { boot } from 'quasar/wrappers'; + +import { createI18n } from 'vue-i18n'; +import i18nextConfig from 'src/config/i18next'; +const i18n = createI18n(i18nextConfig); /** * Plugin for injecting i18n directive and filter @@ -27,20 +27,11 @@ import _ from 'lodash'; * this.$trans([obj1, obj2], ['key1', 'key2']); // also supports array of objects using multiple keys using array */ -export default async ({ app, Vue }) => { - Vue.use(VueI18next); - - i18next.use(i18nextLangDetector); - - if (i18nextConfig.backend) { - i18next.use(i18nextHttpBackend); - } - - await i18next.init(i18nextConfig); - - app.i18n = new VueI18next(i18next); - - Vue.mixin({ +export default boot(async ({ app }) => { + app.i18n = i18n; + app.config.globalProperties.i18n = i18n; + app.use(i18n); + app.mixin({ methods: { $trans(obj, props, trim = false) { /** @@ -95,4 +86,6 @@ export default async ({ app, Vue }) => { } } }); -}; +}); + +export { i18n }; diff --git a/src/router/index.js b/src/router/index.js index 3918843..0af6f44 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -8,14 +8,14 @@ Vue.use(VueRouter); const Router = new VueRouter({ /* - * NOTE! Change Vue Router mode from quasar.conf.js -> build -> vueRouterMode + * NOTE! Change Vue Router mode from quasar.config.js -> build -> vueRouterMode * * When going with "history" mode, please also make sure "build.publicPath" * is set to something other than an empty string. * Example: '/' instead of '' */ - // Leave as is and change from quasar.conf.js instead! + // Leave as is and change from quasar.config.js instead! mode: process.env.VUE_ROUTER_MODE, base: process.env.VUE_ROUTER_BASE, scrollBehavior: () => ({ y: 0 }), diff --git a/src/statics/app-logo.png b/src/statics/app-logo.png deleted file mode 100644 index 590e8ce5b7ab465c0c3a23d01354b488c900af0b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7197 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 diff --git a/src/statics/icons/apple-icon-152x152.png b/src/statics/icons/apple-icon-152x152.png deleted file mode 100644 index c918acd9c69da93f1193cb84ceb0acd6c8ca11e9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 13156 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 P3V{7dXF|1=-{rpnqXA-u diff --git a/src/statics/icons/ms-icon-144x144.png b/src/statics/icons/ms-icon-144x144.png deleted file mode 100644 index b0880e8daf02e4685010a381d4fbbd56859543de..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12292 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 P1OP-