diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..46a9ffa --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,2 @@ +### 1.0.6: +- Modify type and add doc to readme \ No newline at end of file diff --git a/README.md b/README.md index 8724023..e1d7c20 100644 --- a/README.md +++ b/README.md @@ -1,25 +1,142 @@ # vue-datatable-url-sync -Synchronize your datatable filter, ordering and options with the query params. In Vue2 and Vue3 +Synchronize your datatable filter, ordering and options with the query params. In Vue2 and Vue3 with the composition api ! + +# Goal and explanation + +Have you ever as an user filtered or navigated in a datable, open an item of the datable, go back to the datable and see you loose all your filter and pagination and have to rewrite them again ? +If yes was it frustrating ? +If yes then this lib is here to help your user never feel that again. Even if you reload the page or share the link with others user. + + +Now there is already some other lib even in pure Vanilla to sync the query parameters with a javascript object. But you have to rewrite all the logic avec the datatble options (page, pageSize, ordering) and even compare the difference between two state. + +By separating the filters and the datable options vue-datatable-url-sync automatise all the desired behavior for working with datatable. + +Example of usage with a vuetify datatable (It can work with any datatable): + +// coming soon + +# Installation: -## Project setup ``` -npm install +npm install vue-datatable-url-sync ``` -### Compiles and hot-reloads for development +# Usage + +[For full example see this file for vue 3](https://github.com/socotecio/vue-datatable-url-sync/blob/main/vue3-example/src/components/HelloWorld.vue) + +[For full example see this file for vue 2](https://github.com/socotecio/vue-datatable-url-sync/blob/main/vue2-example/src/components/HelloWorld.vue) +### 1 - Import the lib + +```js +import useDatatableUrlSync from 'vue-datatable-url-sync'; ``` -npm run serve + +### 2 - Define your setup function and the data you use for your datatable + +```js +setup (props, ctx) { + const form = ref({ + search: "" + }) + const options = ref({ + page: 1, + page_size: 10, + ordering: [] + }) + const items = ref([]) +} ``` -### Compiles and minifies for production +### 3 - Define the function called each time the url query change (in the setup fucntion) + +```js +const fetchDatas = (queryParams, queryAsObject) => { + console.log(queryParams, queryAsObject) +} ``` -npm run build + +### 4 - Use it + +```js +// Vue 3 +useDatatableUrlSync(useRoute(), useRouter(), form, fetchDatas, options) +// Vue 2 +useDatatableUrlSync(ctx.root.$route, ctx.root.$router, form, fetchDatas, options) ``` -### Lints and fixes files +### 5 Return your data to use it in the datatable + +```js +return { + form, + options, + items +} ``` -npm run lint + + +# useDatatableUrlSync params + +Prototype: +```js +function useDatatableUrlSync(route: any, router: any, form: GenericDictionnary, fetchDatas: Function, options: GenericDictionnary, formSchema?: VDUSFormSchema, initializeForm?: Function, configurations?: VDUSConfiguration) ``` -### Customize configuration -See [Configuration Reference](https://cli.vuejs.org/config/). \ No newline at end of file +| Params | Description | +| --------- | ----------------------------------------------------------------- | +| route | The route element from vue router. As it differe from Vue2 and Vue3 we can't import it automatically and need to have the instance in parameter | +| router | The route instance from vue router. As it differe from Vue2 and Vue3 we can't import it automatically and need to have the instance in parameter | +| form | A simple object used to filter the form. This object is synchronized with the url. When it change it reset the page attribute of the options variable | +| fetchDatas | Callback function called when options or form changed or after a reload with the correct parameter to send to the backend for backend pagination or custom actions. This function take 2 parameter: queryParams, queryAsObject that are the data transformed by VDUS to match your backend criteria in string or object format. | +| options | The options used for the datatable. It follow a strict pattern. See [VDUSDatatableOptions](https://github.com/socotecio/vue-datatable-url-sync/blob/main/src/utils/VDUSTypes.ts#L15) type for more informations. If your server use other query identifier use formSchema to change their name before fetchDatas been called | +| formSchema | Optional. The object that allow you to customize the defaut value, the type and the names send to the backend. See [VDUSFormSchema](https://github.com/socotecio/vue-datatable-url-sync/blob/main/src/utils/VDUSTypes.ts#L11) type for the structure and [the documentation section](#formschema) to understand how to use it | +| initializeForm | Optional. A callback function called at the component creation to allow developer to adapt behavior depending of the query params in the url if needed. Usefull if to value are non-compatible because user change it manually. | +| configurations | Optional. Object that allow to personnalise the behavior of VDUS in specific case. See [VDUSConfiguration](https://github.com/socotecio/vue-datatable-url-sync/blob/main/src/utils/VDUSTypes.ts#L21) type and [the documentation section](#configurations) to understand how to use it | + + +# useDatatableUrlSync returned values + +| Key name | Description | +| --------- | ----------------------------------------------------------------- | +| loading | Boolean value to be able to wait in the template that the data is correctly setted from the url and the data retrieve or filtered in fetchDatas especially if your fetchDatas is asynchronous | +| vuetifyOptions | The datatable options on the vuetify format to be able to use it directly in the template without the need to transform it | + + +# Configurations + +Configurations object allow you to personnalize the behavior of vue-datatable-url-sync. All the configurations are optionals + +| Key name | Default | Description | +| --------- | ------------ | ----------------------------------------------------------------- | +| prefix | "" | Prefix all the params by a string only in the url to allow you have multiple instance of VDUS in the same html page | +| debounceTime | 0 | Allow you to specify a debounce time before sending request to your server. This is usefull when you have only text field but can bring lag feeling when using checkbox or select. You can also use debounce directly in your component to personalize this behavior | +| serveurDefaultPageSize | 10 | The default value for you backend pagination to be sure to send it if the default value in front is different that the one in your back | +| extraQueryParams | {} | Put variable in the url and send them to your back even if not in your form | + +# FormSchema + +The parameter formSchema allow you to adapt the default behavior of vue-datatable-url-sync for each parameter (for the form AND for the options). +With it you can specify the type of the params, the default value and the query param name to send to the server. + +[See the type to understand better](https://github.com/socotecio/vue-datatable-url-sync/blob/main/src/utils/VDUSTypes.ts#L11) + +Here is the description of the type for the configuration of each params ([ParamSchema](https://github.com/socotecio/vue-datatable-url-sync/blob/main/src/utils/VDUSTypes.ts#L5)) + +| Key name | Description | +| --------- | ----------------------------------------------------------------- | +| name | The name to send to the backend server | +| default | The default value. It prevent default value to show in the url | +| type | The type of the params to cast it correctly into your form or your options | + + +# VDUS Types + +| Type name | Description | +| ----------- | ------------------------------------------------------------------- | +| [GenericDictionnary](https://github.com/socotecio/vue-datatable-url-sync/blob/main/src/utils/VDUSTypes.ts#L1) | Generic object that accept any key and any value | +| [VDUSParamSchema](https://github.com/socotecio/vue-datatable-url-sync/blob/main/src/utils/VDUSTypes.ts#L5) | Object describing how to handle query param when reading them from url or before sending them to the backend server | +| [VDUSFormSchema](https://github.com/socotecio/vue-datatable-url-sync/blob/main/src/utils/VDUSTypes.ts#L11) | Object describing how to handle the form and options object passed as parameter of useDatatableUrlSync | +| [VDUSDatatableOptions](https://github.com/socotecio/vue-datatable-url-sync/blob/main/src/utils/VDUSTypes.ts#L15) | Object describing the params accepted in the datatable options | +| [VDUSConfiguration](https://github.com/socotecio/vue-datatable-url-sync/blob/main/src/utils/VDUSTypes.ts#L21) | Configuration object for vue datatable url sync | diff --git a/src/useDatatableUrlSync.ts b/src/useDatatableUrlSync.ts index 7233f76..3e20645 100644 --- a/src/useDatatableUrlSync.ts +++ b/src/useDatatableUrlSync.ts @@ -13,13 +13,13 @@ import { import cloneDeep from "lodash.clonedeep"; import isEqual from "lodash.isequal"; -import { ref, watch, nextTick, computed } from 'vue-demi' -import {GenericDictionnary, VDUSConfiguration, VuetifyOptions} from "./utils/VDUSTypes" +import { ref, watch, nextTick, computed, Ref } from 'vue-demi' +import {GenericDictionnary, VDUSConfiguration, VuetifyOptions, VDUSFormSchema, VDUSDatatableOptions} from "./utils/VDUSTypes" /* DOC here on params and return value */ -export default function useDatatableUrlSync(route: any, router: any, form: GenericDictionnary, fetchDatas: Function, options: GenericDictionnary, formSchema?: GenericDictionnary, initializeForm?: Function, configurations?: VDUSConfiguration) { +export default function useDatatableUrlSync(route: any, router: any, form: Ref, fetchDatas: Function, options: Ref, formSchema?: VDUSFormSchema, initializeForm?: Function, configurations?: VDUSConfiguration) { // ----------------------------- DEFAULTING PARAMS ------------------------------ configurations = { @@ -33,11 +33,17 @@ export default function useDatatableUrlSync(route: any, router: any, form: Gener extraQueryParams: {}, ...configurations || {} } + options.value = { + page: 1, + page_size: configurations.serveurDefaultPageSize, + ordering: [], + ...options.value + } formSchema = { page: { type: "integer", default: 1 }, page_size: { type: "integer", default: 10 }, ordering: { type: "arrayString", default: [] }, - ...formSchema + ...formSchema || {} } // ----------------------------- DATA ------------------------------ @@ -202,7 +208,7 @@ export default function useDatatableUrlSync(route: any, router: any, form: Gener if ( key.startsWith(configurations?.prefix || "") && (typeof form.value[keyWithoutPrefix] !== "undefined" || - typeof options.value[keyWithoutPrefix] !== "undefined") + typeof (options.value as GenericDictionnary)[keyWithoutPrefix] !== "undefined") ) { newLocalQuery[keyWithoutPrefix] = convertParamIfTypeInSchema( route.query, @@ -234,7 +240,7 @@ export default function useDatatableUrlSync(route: any, router: any, form: Gener /* Doc */ - const updateOptionsIfNeeded = (newOptions: GenericDictionnary) => { + const updateOptionsIfNeeded = (newOptions: VDUSDatatableOptions) => { newOptions = { ...options.value, ...newOptions }; if (isEqual(options.value, newOptions)) { return false; @@ -292,7 +298,8 @@ export default function useDatatableUrlSync(route: any, router: any, form: Gener // If the form is updated because an other component pushed a new value that we was watching // And we was not on the first page we need to go back to the first page - if (formUpdated && options.value.page > 1) { + const currentPageNumber: number = options.value.page || 1; + if (formUpdated && currentPageNumber > 1) { options.value.page = 1; } diff --git a/src/utils/VDUSTypes.ts b/src/utils/VDUSTypes.ts index 6d363ce..71788b1 100644 --- a/src/utils/VDUSTypes.ts +++ b/src/utils/VDUSTypes.ts @@ -1,11 +1,28 @@ type GenericDictionnary = { [key: string]: any; } + +type VDUSParamSchema = { + name?: string; + default?: any; + type?: "string" | "boolean" | "integer" | "arrayInt" | "arrayString"; +} + +type VDUSFormSchema = { + [key: string]: VDUSParamSchema; +} + +type VDUSDatatableOptions = { + page?: number; + page_size?: number; + ordering?: Array; +} + type VDUSConfiguration = { - prefix: string; - debounceTime: number; - serveurDefaultPageSize: number; - extraQueryParams: GenericDictionnary; + prefix?: string; + debounceTime?: number; + serveurDefaultPageSize?: number; + extraQueryParams?: GenericDictionnary; } type VuetifySortArraysObject = { @@ -24,4 +41,4 @@ type VuetifyOptions = { mustSort: boolean; } -export {GenericDictionnary, VDUSConfiguration, VuetifySortArraysObject, VuetifyOptions} \ No newline at end of file +export {GenericDictionnary, VDUSConfiguration, VuetifySortArraysObject, VuetifyOptions, VDUSParamSchema, VDUSFormSchema, VDUSDatatableOptions} \ No newline at end of file diff --git a/src/utils/listPaginatedTools.ts b/src/utils/listPaginatedTools.ts index 3265695..60d9a45 100644 --- a/src/utils/listPaginatedTools.ts +++ b/src/utils/listPaginatedTools.ts @@ -5,9 +5,9 @@ import { extractIntegerValue } from "./helpers"; import isEqual from "lodash.isequal"; -import {GenericDictionnary} from "./VDUSTypes" +import {GenericDictionnary, VDUSDatatableOptions, VDUSFormSchema} from "./VDUSTypes" -function getDefaultValueForParam(param: string, schema?: GenericDictionnary): any { +const getDefaultValueForParam = (param: string, schema?: VDUSFormSchema): any => { if (schema && schema[param]) { // if there is a defautl value we change the condition to is non equality if (schema[param].default) { @@ -18,7 +18,7 @@ function getDefaultValueForParam(param: string, schema?: GenericDictionnary): an else if (schema[param].type === "boolean") { // Default for boolean is false return false; - } else if (["arrayInt", "arrayString"].includes(schema[param].type)) { + } else if (["arrayInt", "arrayString"].includes(schema[param].type as string)) { // Default for array is empty array or first element null or empty return []; } @@ -26,7 +26,7 @@ function getDefaultValueForParam(param: string, schema?: GenericDictionnary): an return null; } -function isValueDefault(value: any, param: string, schema?: GenericDictionnary): boolean { +const isValueDefault = (value: any, param: string, schema?: VDUSFormSchema): boolean => { // Default is string let isValueDefault: boolean = value === ""; @@ -44,7 +44,7 @@ function isValueDefault(value: any, param: string, schema?: GenericDictionnary): else if (schema[param].type === "boolean") { // Default for boolean is false isValueDefault = value === false; - } else if (["arrayInt", "arrayString"].includes(schema[param].type)) { + } else if (["arrayInt", "arrayString"].includes(schema[param].type as string)) { // Default for array is empty array or first element null or empty isValueDefault = value.length === 0 || value[0] === null || value[0] === ""; @@ -61,7 +61,7 @@ function isValueDefault(value: any, param: string, schema?: GenericDictionnary): if localName is true it will no replace the param key with the real used for backend query if localName is false the name will be replaced by the correct one sended to backend */ -function generateQueryFromObject(object: GenericDictionnary, schema?: GenericDictionnary, localName = true): GenericDictionnary { +const generateQueryFromObject = (object: GenericDictionnary, schema?: VDUSFormSchema, localName = true): GenericDictionnary => { const queryUrl: GenericDictionnary = {}; for (const [key, value] of Object.entries(object)) { // We do not want to send a default value @@ -73,7 +73,7 @@ function generateQueryFromObject(object: GenericDictionnary, schema?: GenericDic let queryKey = key; // But this can be overrided if name attribute is defined in the param schema if (!localName && schema && schema[key] && schema[key].name) { - queryKey = schema[key].name; + queryKey = (schema[key].name as string); // typescript error because .name can be undefined but if check it before } queryUrl[queryKey] = value; @@ -81,7 +81,7 @@ function generateQueryFromObject(object: GenericDictionnary, schema?: GenericDic return queryUrl; } -function convertParamIfTypeInSchema(query: GenericDictionnary, param: string, schema?: GenericDictionnary, prefix = ""): any { +const convertParamIfTypeInSchema = (query: GenericDictionnary, param: string, schema?: VDUSFormSchema, prefix = ""): any => { if (!schema || !schema[param] || !schema[param].type) { return query[prefix + param]; } @@ -104,22 +104,22 @@ function convertParamIfTypeInSchema(query: GenericDictionnary, param: string, sc /* Transform query parameter from vue router to two javascript objects representing the filtering form and the options */ -function readFormAndOptionsFromLocalQuery( +const readFormAndOptionsFromLocalQuery = ( query: GenericDictionnary, form: GenericDictionnary, - options: GenericDictionnary, - schema?: GenericDictionnary, + options: VDUSDatatableOptions, + schema?: VDUSFormSchema, removedParam: Array = [] -): {newOptions: GenericDictionnary; newForm: GenericDictionnary} { +): {newOptions: VDUSDatatableOptions; newForm: GenericDictionnary} => { - const newOptions: GenericDictionnary = {}; + const newOptions: VDUSDatatableOptions = {}; const newForm: GenericDictionnary = {}; for (const param in query) { if (typeof form[param] !== "undefined") { newForm[param] = convertParamIfTypeInSchema(query, param, schema); - } else if (typeof options[param] !== "undefined") { - newOptions[param] = convertParamIfTypeInSchema(query, param, schema); + } else if (typeof (options as GenericDictionnary)[param] !== "undefined") { + (newOptions as GenericDictionnary)[param] = convertParamIfTypeInSchema(query, param, schema); } } // This allow to reset to default deleted param by other component @@ -129,14 +129,14 @@ function readFormAndOptionsFromLocalQuery( } }); removedParam.forEach(param => { - if (typeof options[param] !== "undefined") { - newOptions[param] = getDefaultValueForParam(param, schema); + if (typeof (options as GenericDictionnary)[param] !== "undefined") { + (newOptions as GenericDictionnary)[param] = getDefaultValueForParam(param, schema); } }); return { newOptions, newForm }; } -function getRemovedKeyBetweenTwoObject(originalObject: GenericDictionnary, newObject: GenericDictionnary): Array { +const getRemovedKeyBetweenTwoObject = (originalObject: GenericDictionnary, newObject: GenericDictionnary): Array => { const originalObjectKeys: Array = Object.keys(originalObject); const newObjectKeys: Array = Object.keys(newObject); return originalObjectKeys.filter( diff --git a/vue2-example/package-lock.json b/vue2-example/package-lock.json index 8f5846a..cbc8f95 100644 --- a/vue2-example/package-lock.json +++ b/vue2-example/package-lock.json @@ -11853,9 +11853,9 @@ } }, "vue-datatable-url-sync": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/vue-datatable-url-sync/-/vue-datatable-url-sync-1.0.3.tgz", - "integrity": "sha512-A/zhRsQi+pvEvH3Jr3VVFBvx8G2sIzC3xtnkxAw92/gpZqEGN5r7gxZpwPmy6rPA/urVb3Cw0dxZC4D/kUR7Mg==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/vue-datatable-url-sync/-/vue-datatable-url-sync-1.0.5.tgz", + "integrity": "sha512-f5bPGAWDaVoJWJ4cJuythMkNmCTGOjYaZ1J1nEvzoIj4BcRAe4HiqD6+hDHoZlTBg1g1o/XqGgctLRPZd0sRhQ==", "requires": { "lodash.clonedeep": "^4.5.0", "lodash.debounce": "^4.0.8", diff --git a/vue2-example/package.json b/vue2-example/package.json index bf32a8c..d1018e5 100644 --- a/vue2-example/package.json +++ b/vue2-example/package.json @@ -11,7 +11,7 @@ "@vue/composition-api": "^1.0.0-rc.5", "core-js": "^3.6.5", "vue": "^2.6.11", - "vue-datatable-url-sync": "^1.0.3", + "vue-datatable-url-sync": "^1.0.5", "vue-router": "^3.5.1", "vuetify": "^2.4.0" }, diff --git a/vue3-example/.eslintrc.js b/vue3-example/.eslintrc.js index 3420fd9..93f97fc 100644 --- a/vue3-example/.eslintrc.js +++ b/vue3-example/.eslintrc.js @@ -13,6 +13,9 @@ module.exports = { }, rules: { 'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off', - 'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off' + 'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off', + "@typescript-eslint/camelcase": "off", + "@typescript-eslint/no-explicit-any": "off", + "@typescript-eslint/no-use-before-define": "off" } } diff --git a/vue3-example/package-lock.json b/vue3-example/package-lock.json index c7708a9..7bede57 100644 --- a/vue3-example/package-lock.json +++ b/vue3-example/package-lock.json @@ -2398,6 +2398,122 @@ "tslint": "^5.20.1", "webpack": "^4.0.0", "yorkie": "^2.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "optional": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "optional": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "optional": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "optional": true + }, + "fork-ts-checker-webpack-plugin-v5": { + "version": "npm:fork-ts-checker-webpack-plugin@5.2.1", + "resolved": "https://registry.npmjs.org/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-5.2.1.tgz", + "integrity": "sha512-SVi+ZAQOGbtAsUWrZvGzz38ga2YqjWvca1pXQFUArIVXqli0lLoDQ8uS0wg0kSpcwpZmaW5jVCZXQebkyUQSsw==", + "dev": true, + "optional": true, + "requires": { + "@babel/code-frame": "^7.8.3", + "@types/json-schema": "^7.0.5", + "chalk": "^4.1.0", + "cosmiconfig": "^6.0.0", + "deepmerge": "^4.2.2", + "fs-extra": "^9.0.0", + "memfs": "^3.1.2", + "minimatch": "^3.0.4", + "schema-utils": "2.7.0", + "semver": "^7.3.2", + "tapable": "^1.0.0" + } + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "optional": true + }, + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "optional": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "schema-utils": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.0.tgz", + "integrity": "sha512-0ilKFI6QQF5nxDZLFn2dMjvc4hjg/Wkg7rHd3jK6/A4a1Hl9VFdQWvgB1UMGoU94pad1P/8N7fMcEnLnSiju8A==", + "dev": true, + "optional": true, + "requires": { + "@types/json-schema": "^7.0.4", + "ajv": "^6.12.2", + "ajv-keywords": "^3.4.1" + } + }, + "semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "optional": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "optional": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true, + "optional": true + } } }, "@vue/cli-plugin-vuex": { @@ -2476,6 +2592,16 @@ "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", "dev": true }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "optional": true, + "requires": { + "color-convert": "^2.0.1" + } + }, "cacache": { "version": "13.0.1", "resolved": "https://registry.npmjs.org/cacache/-/cacache-13.0.1.tgz", @@ -2502,6 +2628,34 @@ "unique-filename": "^1.1.1" } }, + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "optional": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "optional": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "optional": true + }, "fs-extra": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", @@ -2513,6 +2667,13 @@ "universalify": "^0.1.0" } }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "optional": true + }, "jsonfile": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", @@ -2522,6 +2683,18 @@ "graceful-fs": "^4.1.6" } }, + "loader-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz", + "integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==", + "dev": true, + "optional": true, + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + } + }, "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -2538,6 +2711,16 @@ "minipass": "^3.1.1" } }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "optional": true, + "requires": { + "has-flag": "^4.0.0" + } + }, "terser-webpack-plugin": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-2.3.8.tgz", @@ -2560,6 +2743,18 @@ "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", "dev": true + }, + "vue-loader-v16": { + "version": "npm:vue-loader@16.1.2", + "resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-16.1.2.tgz", + "integrity": "sha512-8QTxh+Fd+HB6fiL52iEVLKqE9N1JSlMXLR92Ijm6g8PZrwIxckgpqjPDWRP5TWxdiPaHR+alUWsnu1ShQOwt+Q==", + "dev": true, + "optional": true, + "requires": { + "chalk": "^4.1.0", + "hash-sum": "^2.0.0", + "loader-utils": "^2.0.0" + } } } }, @@ -6908,122 +7103,6 @@ } } }, - "fork-ts-checker-webpack-plugin-v5": { - "version": "npm:fork-ts-checker-webpack-plugin@5.2.1", - "resolved": "https://registry.npmjs.org/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-5.2.1.tgz", - "integrity": "sha512-SVi+ZAQOGbtAsUWrZvGzz38ga2YqjWvca1pXQFUArIVXqli0lLoDQ8uS0wg0kSpcwpZmaW5jVCZXQebkyUQSsw==", - "dev": true, - "optional": true, - "requires": { - "@babel/code-frame": "^7.8.3", - "@types/json-schema": "^7.0.5", - "chalk": "^4.1.0", - "cosmiconfig": "^6.0.0", - "deepmerge": "^4.2.2", - "fs-extra": "^9.0.0", - "memfs": "^3.1.2", - "minimatch": "^3.0.4", - "schema-utils": "2.7.0", - "semver": "^7.3.2", - "tapable": "^1.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "optional": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dev": true, - "optional": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "optional": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true, - "optional": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "optional": true - }, - "lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "optional": true, - "requires": { - "yallist": "^4.0.0" - } - }, - "schema-utils": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.0.tgz", - "integrity": "sha512-0ilKFI6QQF5nxDZLFn2dMjvc4hjg/Wkg7rHd3jK6/A4a1Hl9VFdQWvgB1UMGoU94pad1P/8N7fMcEnLnSiju8A==", - "dev": true, - "optional": true, - "requires": { - "@types/json-schema": "^7.0.4", - "ajv": "^6.12.2", - "ajv-keywords": "^3.4.1" - } - }, - "semver": { - "version": "7.3.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz", - "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==", - "dev": true, - "optional": true, - "requires": { - "lru-cache": "^6.0.0" - } - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "optional": true, - "requires": { - "has-flag": "^4.0.0" - } - }, - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true, - "optional": true - } - } - }, "form-data": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", @@ -8777,11 +8856,15 @@ "integrity": "sha1-+CbJtOKoUR2E46yinbBeGk87cqk=", "dev": true }, + "lodash.clonedeep": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", + "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=" + }, "lodash.debounce": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", - "integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168=", - "dev": true + "integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168=" }, "lodash.defaultsdeep": { "version": "4.6.1", @@ -8795,6 +8878,11 @@ "integrity": "sha1-ZHYsSGGAglGKw99Mz11YhtriA0c=", "dev": true }, + "lodash.isequal": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", + "integrity": "sha1-QVxEePK8wwEgwizhDtMib30+GOA=" + }, "lodash.ismatch": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/lodash.ismatch/-/lodash.ismatch-4.4.0.tgz", @@ -17521,6 +17609,23 @@ "@vue/shared": "3.0.6" } }, + "vue-datatable-url-sync": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/vue-datatable-url-sync/-/vue-datatable-url-sync-1.0.5.tgz", + "integrity": "sha512-f5bPGAWDaVoJWJ4cJuythMkNmCTGOjYaZ1J1nEvzoIj4BcRAe4HiqD6+hDHoZlTBg1g1o/XqGgctLRPZd0sRhQ==", + "requires": { + "lodash.clonedeep": "^4.5.0", + "lodash.debounce": "^4.0.8", + "lodash.isequal": "^4.5.0", + "vue-demi": "^0.6.2", + "vue-router": "^4.0.3" + } + }, + "vue-demi": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.6.2.tgz", + "integrity": "sha512-4KfwxbqsZcDz7UryD11oHa6FLK9Gzx4MIwAEcP37IbUdXuF6DHg2w9L5Zv5t+FNqsuAjEQ2NnGVIZ3u71y435Q==" + }, "vue-eslint-parser": { "version": "7.5.0", "resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-7.5.0.tgz", @@ -17574,87 +17679,6 @@ } } }, - "vue-loader-v16": { - "version": "npm:vue-loader@16.1.2", - "resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-16.1.2.tgz", - "integrity": "sha512-8QTxh+Fd+HB6fiL52iEVLKqE9N1JSlMXLR92Ijm6g8PZrwIxckgpqjPDWRP5TWxdiPaHR+alUWsnu1ShQOwt+Q==", - "dev": true, - "optional": true, - "requires": { - "chalk": "^4.1.0", - "hash-sum": "^2.0.0", - "loader-utils": "^2.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "optional": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dev": true, - "optional": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "optional": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true, - "optional": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "optional": true - }, - "loader-utils": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz", - "integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==", - "dev": true, - "optional": true, - "requires": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^2.1.2" - } - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "optional": true, - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, "vue-router": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-4.0.4.tgz", diff --git a/vue3-example/package.json b/vue3-example/package.json index 66855f0..29f7d18 100644 --- a/vue3-example/package.json +++ b/vue3-example/package.json @@ -8,9 +8,9 @@ "lint": "vue-cli-service lint" }, "dependencies": { - "vue-datatable-url-sync": "0.1.0", "core-js": "^3.6.5", "vue": "^3.0.0", + "vue-datatable-url-sync": "^1.0.5", "vue-router": "^4.0.0-0" }, "devDependencies": { diff --git a/vue3-example/src/App.vue b/vue3-example/src/App.vue index b964355..303f9fd 100644 --- a/vue3-example/src/App.vue +++ b/vue3-example/src/App.vue @@ -1,7 +1,6 @@ diff --git a/vue3-example/src/components/HelloWorld.vue b/vue3-example/src/components/HelloWorld.vue index e8838bd..3a35711 100644 --- a/vue3-example/src/components/HelloWorld.vue +++ b/vue3-example/src/components/HelloWorld.vue @@ -21,14 +21,15 @@ \ No newline at end of file diff --git a/vue3-example/src/router/index.ts b/vue3-example/src/router/index.ts index a6021e1..ee85b85 100644 --- a/vue3-example/src/router/index.ts +++ b/vue3-example/src/router/index.ts @@ -7,14 +7,6 @@ const routes: Array = [ name: 'Home', component: Home }, - { - path: '/about', - name: 'About', - // route level code-splitting - // this generates a separate chunk (about.[hash].js) for this route - // which is lazy-loaded when the route is visited. - component: () => import(/* webpackChunkName: "about" */ '../views/About.vue') - } ] const router = createRouter({ diff --git a/vue3-example/src/shims-vue.d.ts b/vue3-example/src/shims-vue.d.ts index 3804a43..34f69c7 100644 --- a/vue3-example/src/shims-vue.d.ts +++ b/vue3-example/src/shims-vue.d.ts @@ -1,4 +1,6 @@ /* eslint-disable */ + +declare module 'vue-datatable-url-sync'; declare module '*.vue' { import type { DefineComponent } from 'vue' const component: DefineComponent<{}, {}, any> diff --git a/vue3-example/src/views/About.vue b/vue3-example/src/views/About.vue deleted file mode 100644 index 3fa2807..0000000 --- a/vue3-example/src/views/About.vue +++ /dev/null @@ -1,5 +0,0 @@ - diff --git a/vue3-example/src/views/Home.vue b/vue3-example/src/views/Home.vue index 50d8a19..bc3d8db 100644 --- a/vue3-example/src/views/Home.vue +++ b/vue3-example/src/views/Home.vue @@ -1,6 +1,5 @@ diff --git a/vue3-example/tsconfig.json b/vue3-example/tsconfig.json index e621cbc..65434ae 100644 --- a/vue3-example/tsconfig.json +++ b/vue3-example/tsconfig.json @@ -6,6 +6,7 @@ "jsx": "preserve", "importHelpers": true, "moduleResolution": "node", + "allowJs": true, "skipLibCheck": true, "esModuleInterop": true, "allowSyntheticDefaultImports": true,