diff --git a/.eslintignore b/.eslintignore index 8fb6a9c..5bebaba 100644 --- a/.eslintignore +++ b/.eslintignore @@ -78,4 +78,4 @@ dist/ docs/ /src-pwa/pwa-flag.d.ts -/src/store/store-flag.d.ts +/src/stores/store-flag.d.ts diff --git a/.gitignore b/.gitignore index 7521838..9dc7cea 100644 --- a/.gitignore +++ b/.gitignore @@ -77,4 +77,4 @@ dist/ docs/ /src-pwa/pwa-flag.d.ts -/src/store/store-flag.d.ts +/src/stores/store-flag.d.ts diff --git a/babel.config.js b/babel.config.js index 8c2a51c..ab06c47 100644 --- a/babel.config.js +++ b/babel.config.js @@ -10,7 +10,8 @@ module.exports = { { 'modules': false, 'loose': false, - 'useBuiltIns': 'usage' + 'useBuiltIns': 'usage', + 'corejs': '^3.6.5' } ], ], diff --git a/package.json b/package.json index ca7ac45..b31f9d3 100644 --- a/package.json +++ b/package.json @@ -18,6 +18,7 @@ "postinstall": "quasar-app-extension-freedom-components" }, "dependencies": { + "@gtm-support/vue-gtm": "^2.1.0", "@quasar/extras": "^1.0.0", "@vuelidate/core": "^2.0.0", "@vuelidate/validators": "^2.0.0", @@ -31,9 +32,10 @@ "moment": "^2.29.4", "node-polyfill-webpack-plugin": "^2.0.1", "pinia": "^2.0.32", + "pinia-plugin-persistedstate": "^3.2.0", "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", + "quasar-app-extension-freedom-components": "git+https://gitlab.com/anyTV/incubator/freedom-components.git#cc6ba22d", "vue": "^3.2.33", "vue-analytics": "^5.22.1", "vue-i18n": "^9.2.2", diff --git a/quasar.config.js b/quasar.config.js index d36c652..4dd286b 100644 --- a/quasar.config.js +++ b/quasar.config.js @@ -18,7 +18,7 @@ const pkg = require('./package'); module.exports = configure(function (ctx) { return { // https://v2.quasar.dev/quasar-cli-webpack/supporting-ts - supportTS: false, + supportTS: true, // https://v2.quasar.dev/quasar-cli-webpack/prefetch-feature // preFetch: true, diff --git a/src/boot/admin-api.js b/src/boot/admin-api.js index cb50cbd..07199b0 100644 --- a/src/boot/admin-api.js +++ b/src/boot/admin-api.js @@ -10,7 +10,7 @@ import qs from 'qs'; * // In a component you can use it like: * this.$adminAPI.post(...); */ -export default ({ Vue }) => { +export default ({ app }) => { const apiConfig = { baseURL: config.API.BASE_URL, @@ -23,7 +23,7 @@ export default ({ Vue }) => { try { const api = axios.create(_.defaults({ - headers: { 'Access-Token': Vue.jwt.getToken() } + headers: { 'Access-Token': app.jwt.getToken() } }, apiConfig)); let response = await api[_.toLower(method)](endpoint, payload); @@ -89,11 +89,5 @@ export default ({ Vue }) => { } }; - Object.defineProperties(Vue.prototype, { - $adminAPI: { - get() { - return adminAPI; - } - }, - }); + app.config.globalProperties.$adminAPI = adminAPI; }; diff --git a/src/boot/vue-gtm.js b/src/boot/vue-gtm.js index ba80d64..7cfbfa7 100644 --- a/src/boot/vue-gtm.js +++ b/src/boot/vue-gtm.js @@ -1,5 +1,5 @@ -import VueGtm from 'vue-gtm'; +import { createGtm } from '@gtm-support/vue-gtm'; import config from 'src/config'; -export default ({ Vue }) => Vue.use(VueGtm, config.GTM_CONFIG); +export default ({ app }) => app.use(createGtm(config.GTM_CONFIG)); diff --git a/src/boot/vuelidate.js b/src/boot/vuelidate.js index 3f08d22..ed18fcb 100644 --- a/src/boot/vuelidate.js +++ b/src/boot/vuelidate.js @@ -1,5 +1,6 @@ -import Vuelidate from 'vuelidate'; +import { useVuelidate } from '@vuelidate/core'; -export default ({ Vue }) => { - Vue.use(Vuelidate); +export default ({ app }) => { + + app.use(useVuelidate); }; diff --git a/src/css/app.scss b/src/css/app.scss new file mode 100644 index 0000000..e69de29 diff --git a/src/index.template.html b/src/index.template.html index 7b5fcd6..bdddc31 100644 --- a/src/index.template.html +++ b/src/index.template.html @@ -6,7 +6,7 @@ + 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<% } %>"> <%= htmlWebpackPlugin.options.productName %> diff --git a/src/pages/FFilterDemo.vue b/src/pages/FFilterDemo.vue index 31785f6..6b65c1e 100644 --- a/src/pages/FFilterDemo.vue +++ b/src/pages/FFilterDemo.vue @@ -110,7 +110,7 @@ import tableData from 'src/sample/tableData/tableWithFFilter'; import tableColumns from 'src/sample/tableColumns/tableWithFFilter'; import UtilMixin from 'src/mixins/utils'; - import { integer } from 'vuelidate/lib/validators'; + import { integer } from '@vuelidate/validators'; import { isValidStrictDateFormat, } from 'src/helpers/custom-validators'; @@ -145,7 +145,7 @@ name: {}, user_id: { key: 'id', - rule: integer, + rule: integer.$validator, caption: 'with_integer_rule', }, user_type: { diff --git a/src/pages/TableWithTabs.vue b/src/pages/TableWithTabs.vue index dbd3982..3c924bf 100644 --- a/src/pages/TableWithTabs.vue +++ b/src/pages/TableWithTabs.vue @@ -82,7 +82,7 @@ :hide-bottom="hideBottom" :loading="loading" :pagination.sync="tablePagination" - class="f-table" + class="stick-header-table" binary-state-sort row-key="id" @request="getTableData" @@ -225,3 +225,8 @@ } }; + + diff --git a/src/pages/TableWithTabs2.vue b/src/pages/TableWithTabs2.vue index ebba599..d31cef9 100644 --- a/src/pages/TableWithTabs2.vue +++ b/src/pages/TableWithTabs2.vue @@ -53,7 +53,7 @@ :pagination.sync="tablePagination" binary-state-sort row-key="id" - class="f-table" + class="stick-header-table" @request="getTableData" /> @@ -187,4 +187,9 @@ }, } }; - \ No newline at end of file + + + diff --git a/src/pages/TableWithoutTab.vue b/src/pages/TableWithoutTab.vue index 2563dd1..5a769ed 100644 --- a/src/pages/TableWithoutTab.vue +++ b/src/pages/TableWithoutTab.vue @@ -74,7 +74,7 @@ :pagination.sync="tablePagination" binary-state-sort row-key="id" - class="f-table" + class="stick-header-table" @request="getTableData" /> @@ -205,3 +205,8 @@ } }; + + diff --git a/src/router/index.js b/src/router/index.js index 0af6f44..2247801 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -1,36 +1,48 @@ -import Vue from 'vue'; -import VueRouter from 'vue-router'; +import { route } from 'quasar/wrappers'; +import { createApp } from 'vue'; +import { createGtm } from '@gtm-support/vue-gtm'; +import { createRouter, createMemoryHistory, createWebHistory, createWebHashHistory } from 'vue-router'; +import routes from 'src/router/routes'; +import ga from 'src/router/analytics'; -import routes from './routes'; -import ga from './analytics'; +import config from 'src/config/index'; -Vue.use(VueRouter); +const app = createApp({}); -const Router = new VueRouter({ - /* - * 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 '' - */ +export default route(function() { + const createHistory = process.env.SERVER + ? createMemoryHistory + : (process.env.VUE_ROUTER_MODE === 'history' ? createWebHistory : createWebHashHistory); - // 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 }), - routes -}); + const Router = createRouter({ + scrollBehavior: () => ({ y: 0 }), + routes, + // Leave this as is and make changes in quasar.conf.js instead! + // quasar.conf.js -> build -> vueRouterMode + // quasar.conf.js -> build -> publicPath + history: createHistory(process.env.VUE_ROUTER_BASE) + }); -Router.afterEach(to => { - Vue.gtm.trackView( - to.path, - to.name, - { - cid: ga.createSessionId(), - path: to.path - } - ); -}); + if (config.GTM_CONFIG) { + app.use( + createGtm({ + ...config.GTM_CONFIG, + loadScript: true, + vueRouter: Router, + }) + ); + } -export default Router; + Router.afterEach(to => { + app.config.globalProperties.$gtm.trackView( + to.path, + to.name, + { + cid: ga.createSessionId(), + path: to.path + } + ); + }); + + return Router; +}); diff --git a/src/store/index.js b/src/store/index.js deleted file mode 100644 index f9585c2..0000000 --- a/src/store/index.js +++ /dev/null @@ -1,12 +0,0 @@ -import Vue from 'vue'; -import Vuex from 'vuex'; - - -Vue.use(Vuex); - -const store = new Vuex.Store({ - modules: {}, - strict: !process.env.PROD -}); - -export default store; diff --git a/src/stores/index.ts b/src/stores/index.ts new file mode 100644 index 0000000..59eb219 --- /dev/null +++ b/src/stores/index.ts @@ -0,0 +1,39 @@ +import { store } from 'quasar/wrappers'; +import { createPinia } from 'pinia'; +import { Router } from 'vue-router'; +import { useQuasar, QVueGlobals } from 'quasar'; +import piniaPluginPersistedState from 'pinia-plugin-persistedstate'; + +/* + * When adding new properties to stores, you should also + * extend the `PiniaCustomProperties` interface. + * @see https://pinia.vuejs.org/core-concepts/plugins.html#typing-new-store-properties + */ +declare module 'pinia' { + export interface PiniaCustomProperties { + readonly router: Router; + $q: QVueGlobals; + } +} + +/* + * If not building with SSR mode, you can + * directly export the Store instantiation; + * + * The function below can be async too; either use + * async/await or return a Promise which resolves + * with the Store instance. + */ + +export default store((/* { ssrContext } */) => { + const pinia = createPinia(); + + // You can add Pinia plugins here + pinia.use(({ store }) => { + store.$q = useQuasar(); + }); + + pinia.use(piniaPluginPersistedState); + + return pinia; +}); diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..dd61b4a --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,6 @@ +{ + "extends": "@quasar/app-webpack/tsconfig-preset", + "compilerOptions": { + "baseUrl": "." + } +}