Skip to content

Commit ad7177e

Browse files
authored
Merge pull request #1 from socotecio/feature/integrateVuetifyOptions
fix(vuetify): need publish to test
2 parents 2507664 + a5cee17 commit ad7177e

File tree

13 files changed

+955
-83
lines changed

13 files changed

+955
-83
lines changed

src/useDatatableUrlSync.ts

Lines changed: 53 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,23 @@ import {
44
generateQueryFromObject,
55
convertParamIfTypeInSchema,
66
getRemovedKeyBetweenTwoObject,
7-
//getDefaultValueForParam
7+
getDefaultValueForParam
88
} from "./utils/listPaginatedTools";
9+
import {
10+
getSortsArrayFromOrdering,
11+
getOrderingFromSortArray
12+
} from "./utils/helpers";
913
import cloneDeep from "lodash.clonedeep";
1014
import isEqual from "lodash.isequal";
1115

12-
import { ref, watch, nextTick } from 'vue-demi'
16+
import { ref, watch, nextTick, computed } from 'vue-demi'
1317
import { useRoute, useRouter } from 'vue-router'
14-
import {GenericDictionnary, VDUSConfiguration} from "./utils/VDUSTypes"
18+
import {GenericDictionnary, VDUSConfiguration, VuetifyOptions} from "./utils/VDUSTypes"
1519

1620
/*
1721
DOC here on params and return value
1822
*/
19-
export default function useDatatableUrlSync(form: GenericDictionnary, fetchDatas: Function, options: GenericDictionnary, formSchema?: GenericDictionnary, initializeForm?: Function, configurations?:VDUSConfiguration) {
23+
export default function useDatatableUrlSync(form: GenericDictionnary, fetchDatas: Function, options: GenericDictionnary, formSchema?: GenericDictionnary, initializeForm?: Function, configurations?: VDUSConfiguration) {
2024

2125
// ----------------------------- DEFAULTING PARAMS ------------------------------
2226
configurations = {
@@ -41,15 +45,54 @@ export default function useDatatableUrlSync(form: GenericDictionnary, fetchDatas
4145
const route = useRoute();
4246
const router = useRouter()
4347

44-
let ignoredQueryParams:GenericDictionnary = {};
45-
let localQuery:GenericDictionnary = {};
46-
const loading = ref<Boolean>(false);
48+
let ignoredQueryParams: GenericDictionnary = {};
49+
let localQuery: GenericDictionnary = {};
50+
const loading = ref<boolean>(false);
4751
let disableRouterWatch = false;
4852

4953
const debounceSearch = debounce(isFilter => {
5054
localQuery = triggerSearchIfNeeded(isFilter, getDatas);
5155
}, configurations?.debounceTime || 0);
5256

57+
// ----------------------------- COMPUTED ---------------------------
58+
59+
const vuetifyOptions = computed({
60+
get: ():VuetifyOptions => {
61+
let vuetifyOptions:VuetifyOptions = {
62+
page: 1,
63+
itemsPerPage: 10,
64+
sortBy: [],
65+
sortDesc: [],
66+
groupBy: [],
67+
groupDesc: [],
68+
multiSort: false,
69+
mustSort: false
70+
};
71+
72+
vuetifyOptions.page = options.page ?? getDefaultValueForParam("page", formSchema);
73+
vuetifyOptions.itemsPerPage = options.page_size ?? getDefaultValueForParam("page_size", formSchema);
74+
75+
let ordering:Array<string> =
76+
Array.isArray(options.ordering) &&
77+
options.ordering.length > 0
78+
? options.ordering
79+
: getDefaultValueForParam("ordering", formSchema);
80+
81+
let { sortBy, sortDesc } = getSortsArrayFromOrdering(ordering);
82+
83+
vuetifyOptions.sortBy = sortBy;
84+
vuetifyOptions.sortDesc = sortDesc;
85+
86+
return vuetifyOptions;
87+
},
88+
set: (newOptions:VuetifyOptions) => {
89+
// As we do not define options by default, to avoid reload from other component we doesn't want, we need to set data because they are not reactive
90+
options.page = newOptions.page;
91+
options.page_size = newOptions.itemsPerPage;
92+
options.ordering = getOrderingFromSortArray(newOptions.sortBy, newOptions.sortDesc)
93+
}
94+
})
95+
5396
// ----------------------------- WATCH ------------------------------
5497
watch(form, () => {
5598
debounceSearch(true);
@@ -78,7 +121,7 @@ export default function useDatatableUrlSync(form: GenericDictionnary, fetchDatas
78121
isFilter is true if it's a filter attribute taht changed. This allow us to reset the page number to 1
79122
This allow to fetch data in back end and apply the filter in the url query
80123
*/
81-
const triggerSearchIfNeeded = (isFilter:Boolean, triggerFunction:Function) => {
124+
const triggerSearchIfNeeded = (isFilter:boolean, triggerFunction:Function) => {
82125
let newLocalQuery: GenericDictionnary = {
83126
...generateQueryFromObject(form.value, formSchema, true),
84127
...generateQueryFromObject(options.value, formSchema, true)
@@ -208,7 +251,7 @@ export default function useDatatableUrlSync(form: GenericDictionnary, fetchDatas
208251
/*
209252
DOC
210253
*/
211-
const initializeFromRouter = (created: Boolean) => {
254+
const initializeFromRouter = (created: boolean) => {
212255
// Need to select only elements that are in this.form to avoid multiple instance reload between them
213256
ignoredQueryParams = {};
214257

@@ -271,6 +314,7 @@ export default function useDatatableUrlSync(form: GenericDictionnary, fetchDatas
271314
initializeFromRouter(true)
272315

273316
return {
317+
vuetifyOptions,
274318
loading
275319
}
276320
}

src/utils/VDUSTypes.ts

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,20 @@ type VDUSConfiguration = {
88
extraQueryParams: GenericDictionnary
99
}
1010

11-
export {GenericDictionnary, VDUSConfiguration}
11+
type VuetifySortArraysObject = {
12+
sortBy: Array<string>,
13+
sortDesc: Array<boolean>
14+
}
15+
16+
type VuetifyOptions = {
17+
page: number,
18+
itemsPerPage: number,
19+
sortBy: Array<string>,
20+
sortDesc: Array<boolean>,
21+
groupBy: Array<string>,
22+
groupDesc: Array<boolean>,
23+
multiSort: boolean,
24+
mustSort: boolean
25+
}
26+
27+
export {GenericDictionnary, VDUSConfiguration, VuetifySortArraysObject, VuetifyOptions}

src/utils/helpers.ts

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,52 @@
1+
import {VuetifySortArraysObject} from "./VDUSTypes";
2+
13
export const elementToArrayOfInt = (element: any):Array<number> => {
24
return ["number", "string"].includes(typeof element)
35
? [parseInt(element)]
46
: element.map((item:any) => parseInt(item));
57
};
68

7-
export const elementToArrayOfString = (element: any) => {
9+
export const elementToArrayOfString = (element: any): Array<string> => {
810
return element ? (typeof element === "string" ? [element] : element) : [];
911
};
1012

11-
export const extractBooleanValue = (value: any, defaultValue:Boolean = true) => {
13+
export const extractBooleanValue = (value: any, defaultValue:boolean = true):boolean => {
1214
return value ? value.toString() === "true" : defaultValue;
1315
};
1416

15-
export const extractIntegerValue = (value:any, defaultValue:number = 0) => {
17+
export const extractIntegerValue = (value:any, defaultValue:number = 0):number => {
1618
const parsed = parseInt(value);
1719
return isNaN(parsed) ? defaultValue : parsed;
1820
};
21+
22+
export const getSortsArrayFromOrdering = (ordering:Array<string>):VuetifySortArraysObject => {
23+
if (!ordering) {
24+
return { sortBy: [], sortDesc: [] };
25+
}
26+
let sortBy:Array<string> = [];
27+
let sortDesc:Array<boolean> = [];
28+
29+
ordering.forEach(orderItem => {
30+
let isDesc:boolean = false;
31+
if (orderItem.startsWith("-")) {
32+
orderItem = orderItem.replace("-", "");
33+
isDesc = true;
34+
}
35+
sortBy.push(orderItem);
36+
sortDesc.push(isDesc);
37+
});
38+
39+
return { sortBy, sortDesc };
40+
}
41+
42+
export const getOrderingFromSortArray = (sortBy:Array<string>, sortDesc:Array<boolean>):Array<string> => {
43+
let ordering:Array<string> = [];
44+
sortBy.forEach((orderItem, index) => {
45+
let isDesc:boolean = true;
46+
if (sortDesc.length > index) {
47+
isDesc = sortDesc[index];
48+
}
49+
ordering.push(`${isDesc ? "-" : ""}${orderItem}`);
50+
});
51+
return ordering;
52+
}

src/utils/listPaginatedTools.ts

Lines changed: 50 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -7,32 +7,6 @@ import {
77
import isEqual from "lodash.isequal";
88
import {GenericDictionnary} from "./VDUSTypes"
99

10-
/*
11-
This function take a object in parameter that is often a form of filtering field
12-
all this field are filtered before being used to be transformed as a query url
13-
if localName is true it will no replace the param key with the real used for backend query
14-
if localName is false the name will be replaced by the correct one sended to backend
15-
*/
16-
function generateQueryFromObject(object: GenericDictionnary, schema?: GenericDictionnary, localName: Boolean = true): GenericDictionnary {
17-
let queryUrl: GenericDictionnary = {};
18-
for (let [key, value] of Object.entries(object)) {
19-
// We do not want to send a default value
20-
if (isValueDefault(value, key, schema)) {
21-
continue;
22-
}
23-
24-
// by default the quey key is the same that the form key
25-
let queryKey = key;
26-
// But this can be overrided if name attribute is defined in the param schema
27-
if (!localName && schema && schema[key] && schema[key].name) {
28-
queryKey = schema[key].name;
29-
}
30-
31-
queryUrl[queryKey] = value;
32-
}
33-
return queryUrl;
34-
}
35-
3610
function getDefaultValueForParam(param: string, schema?: GenericDictionnary): any {
3711
if (schema && schema[param]) {
3812
// if there is a defautl value we change the condition to is non equality
@@ -81,6 +55,52 @@ function isValueDefault(value: any, param: string, schema?: GenericDictionnary):
8155
return value === null || isValueDefault;
8256
}
8357

58+
/*
59+
This function take a object in parameter that is often a form of filtering field
60+
all this field are filtered before being used to be transformed as a query url
61+
if localName is true it will no replace the param key with the real used for backend query
62+
if localName is false the name will be replaced by the correct one sended to backend
63+
*/
64+
function generateQueryFromObject(object: GenericDictionnary, schema?: GenericDictionnary, localName = true): GenericDictionnary {
65+
const queryUrl: GenericDictionnary = {};
66+
for (const [key, value] of Object.entries(object)) {
67+
// We do not want to send a default value
68+
if (isValueDefault(value, key, schema)) {
69+
continue;
70+
}
71+
72+
// by default the quey key is the same that the form key
73+
let queryKey = key;
74+
// But this can be overrided if name attribute is defined in the param schema
75+
if (!localName && schema && schema[key] && schema[key].name) {
76+
queryKey = schema[key].name;
77+
}
78+
79+
queryUrl[queryKey] = value;
80+
}
81+
return queryUrl;
82+
}
83+
84+
function convertParamIfTypeInSchema(query: GenericDictionnary, param: string, schema?: GenericDictionnary, prefix = ""): any {
85+
if (!schema || !schema[param] || !schema[param].type) {
86+
return query[prefix + param];
87+
}
88+
if (schema[param].type === "boolean") {
89+
return extractBooleanValue(query[prefix + param]);
90+
}
91+
if (schema[param].type === "integer") {
92+
return extractIntegerValue(query[prefix + param]);
93+
}
94+
if (schema[param].type === "arrayInt") {
95+
return elementToArrayOfInt(query[prefix + param]);
96+
}
97+
if (schema[param].type === "arrayString") {
98+
return elementToArrayOfString(query[prefix + param]);
99+
}
100+
101+
return query[prefix + param];
102+
}
103+
84104
/*
85105
Transform query parameter from vue router to two javascript objects representing the filtering form and the options
86106
*/
@@ -90,12 +110,12 @@ function readFormAndOptionsFromLocalQuery(
90110
options: GenericDictionnary,
91111
schema?: GenericDictionnary,
92112
removedParam: Array<string> = []
93-
): {newOptions: GenericDictionnary, newForm: GenericDictionnary} {
113+
): {newOptions: GenericDictionnary; newForm: GenericDictionnary} {
94114

95-
let newOptions: GenericDictionnary = {};
96-
let newForm: GenericDictionnary = {};
115+
const newOptions: GenericDictionnary = {};
116+
const newForm: GenericDictionnary = {};
97117

98-
for (let param in query) {
118+
for (const param in query) {
99119
if (typeof form[param] !== "undefined") {
100120
newForm[param] = convertParamIfTypeInSchema(query, param, schema);
101121
} else if (typeof options[param] !== "undefined") {
@@ -116,26 +136,6 @@ function readFormAndOptionsFromLocalQuery(
116136
return { newOptions, newForm };
117137
}
118138

119-
function convertParamIfTypeInSchema(query: GenericDictionnary, param: string, schema?: GenericDictionnary, prefix: string = ""): any {
120-
if (!schema || !schema[param] || !schema[param].type) {
121-
return query[prefix + param];
122-
}
123-
if (schema[param].type === "boolean") {
124-
return extractBooleanValue(query[prefix + param]);
125-
}
126-
if (schema[param].type === "integer") {
127-
return extractIntegerValue(query[prefix + param]);
128-
}
129-
if (schema[param].type === "arrayInt") {
130-
return elementToArrayOfInt(query[prefix + param]);
131-
}
132-
if (schema[param].type === "arrayString") {
133-
return elementToArrayOfString(query[prefix + param]);
134-
}
135-
136-
return query[prefix + param];
137-
}
138-
139139
function getRemovedKeyBetweenTwoObject(originalObject: GenericDictionnary, newObject: GenericDictionnary): Array<string> {
140140
const originalObjectKeys: Array<string> = Object.keys(originalObject);
141141
const newObjectKeys: Array<string> = Object.keys(newObject);

vue2-example/.eslintrc.js

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,17 @@ module.exports = {
55
},
66
'extends': [
77
'plugin:vue/essential',
8-
'eslint:recommended'
8+
'eslint:recommended',
9+
'@vue/typescript/recommended'
910
],
1011
parserOptions: {
11-
parser: 'babel-eslint'
12+
parser: '@typescript-eslint/parser'
1213
},
1314
rules: {
1415
'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
15-
'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off'
16+
'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
17+
"@typescript-eslint/camelcase": "off",
18+
"@typescript-eslint/no-explicit-any": "off",
19+
"@typescript-eslint/no-use-before-define": "off"
1620
}
1721
}

0 commit comments

Comments
 (0)