@slickgrid-universal/odata 5.11.0 → 5.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/services/grid-odata.service.js +67 -39
- package/dist/cjs/services/grid-odata.service.js.map +1 -1
- package/dist/cjs/services/odataQueryBuilder.service.js +8 -8
- package/dist/cjs/services/odataQueryBuilder.service.js.map +1 -1
- package/dist/esm/services/grid-odata.service.js +68 -40
- package/dist/esm/services/grid-odata.service.js.map +1 -1
- package/dist/esm/services/odataQueryBuilder.service.js +8 -8
- package/dist/esm/services/odataQueryBuilder.service.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/types/services/grid-odata.service.d.ts +1 -1
- package/dist/types/services/grid-odata.service.d.ts.map +1 -1
- package/package.json +4 -4
- package/src/services/grid-odata.service.ts +109 -64
- package/src/services/odataQueryBuilder.service.ts +11 -11
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"grid-odata.service.d.ts","sourceRoot":"","sources":["../../../src/services/grid-odata.service.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,cAAc,EACd,MAAM,EAEN,aAAa,EACb,UAAU,EACV,aAAa,EACb,iBAAiB,EACjB,aAAa,EACb,iBAAiB,EACjB,UAAU,EAEV,eAAe,EACf,UAAU,EACV,qBAAqB,EAErB,cAAc,EACd,UAAU,EACV,aAAa,EACb,gBAAgB,EAChB,SAAS,EACV,MAAM,6BAA6B,CAAC;AACrC,OAAO,
|
|
1
|
+
{"version":3,"file":"grid-odata.service.d.ts","sourceRoot":"","sources":["../../../src/services/grid-odata.service.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,cAAc,EACd,MAAM,EAEN,aAAa,EACb,UAAU,EACV,aAAa,EACb,iBAAiB,EACjB,aAAa,EACb,iBAAiB,EACjB,UAAU,EAEV,eAAe,EACf,UAAU,EACV,qBAAqB,EAErB,cAAc,EACd,UAAU,EACV,aAAa,EACb,gBAAgB,EAChB,SAAS,EACV,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAY,SAAS,EAA0B,YAAY,EAA+B,MAAM,6BAA6B,CAAC;AAErI,OAAO,EAAE,wBAAwB,EAAE,MAAM,gCAAgC,CAAC;AAC1E,OAAO,KAAK,EAAE,WAAW,EAAsB,MAAM,wBAAwB,CAAC;AAK9E,qBAAa,gBAAiB,YAAW,cAAc;IACrD,SAAS,CAAC,eAAe,EAAE,aAAa,EAAE,CAAM;IAChD,SAAS,CAAC,kBAAkB,EAAE,iBAAiB,GAAG,IAAI,CAAQ;IAC9D,SAAS,CAAC,eAAe,EAAE,aAAa,EAAE,CAAM;IAChD,SAAS,CAAC,kBAAkB,EAAE,MAAM,EAAE,CAAM;IAC5C,SAAS,CAAC,KAAK,EAAE,SAAS,GAAG,SAAS,CAAC;IACvC,SAAS,CAAC,aAAa,EAAE,wBAAwB,CAAC;IAClD,OAAO,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC;IAC/B,UAAU,EAAE,UAAU,GAAG,SAAS,CAAC;IACnC,cAAc,EAAE,WAAW,CAIzB;IAEF,wCAAwC;IACxC,IAAI,iBAAiB,IAAI,MAAM,EAAE,CAEhC;IAED,mCAAmC;IACnC,IAAI,YAAY,IAAI,wBAAwB,CAE3C;IAED,iEAAiE;IACjE,SAAS,KAAK,YAAY,IAAI,UAAU,CAEvC;;IAMD,IAAI,CAAC,cAAc,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,EAAE,UAAU,CAAC,EAAE,UAAU,EAAE,IAAI,CAAC,EAAE,SAAS,EAAE,aAAa,CAAC,EAAE,aAAa,GAAG,IAAI;IA+B3H,UAAU,IAAI,MAAM;IAIpB,WAAW,CAAC,aAAa,EAAE,GAAG,GAAG,IAAI;IA2DrC,YAAY,IAAI,IAAI;IAKpB,YAAY,IAAI,IAAI;IAKpB,aAAa,CAAC,cAAc,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,GAAG,IAAI;IAK1D,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAI3C,0DAA0D;IAC1D,iBAAiB,IAAI,aAAa,EAAE;IAIpC,4DAA4D;IAC5D,oBAAoB,IAAI,iBAAiB,GAAG,IAAI;IAIhD,0DAA0D;IAC1D,iBAAiB,IAAI,aAAa,EAAE;IAIpC;;;;OAIG;IACH,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM;IAgC1C,sBAAsB,IAAI,IAAI;IAM9B,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,UAAU,EAAE,GAAG,IAAI;IAO9E,sBAAsB,CAAC,MAAM,EAAE,KAAK,GAAG,SAAS,EAAE,IAAI,EAAE,iBAAiB,GAAG,MAAM;IAyBlF,0BAA0B,CAAC,MAAM,EAAE,KAAK,GAAG,SAAS,EAAE,IAAI,EAAE,qBAAqB,GAAG,MAAM;IAe1F,oBAAoB,CAAC,MAAM,EAAE,KAAK,GAAG,SAAS,EAAE,IAAI,EAAE,gBAAgB,GAAG,eAAe,GAAG,MAAM;IAqBjG;;;OAGG;IACH,aAAa,CAAC,aAAa,EAAE,aAAa,GAAG,aAAa,EAAE,EAAE,8BAA8B,CAAC,EAAE,OAAO,GAAG,IAAI;IA+O7G;;;;OAIG;IACH,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI;IAkBzD;;;OAGG;IACH,aAAa,CAAC,WAAW,CAAC,EAAE,UAAU,EAAE,EAAE,aAAa,CAAC,EAAE,aAAa,EAAE,GAAG,MAAM;IA8FlF;;;OAGG;IACH,SAAS,CAAC,yBAAyB,CAAC,aAAa,EAAE,aAAa,GAAG,aAAa,EAAE,GAAG,aAAa,EAAE;IAwBpG;;OAEG;IACH,SAAS,CAAC,uBAAuB,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,YAAY,GAAG,cAAc,EAAE,WAAW,EAAE,UAAU,EAAE,GAAG,MAAM;IAsBhI;;OAEG;IACH,SAAS,CAAC,oBAAoB,CAAC,SAAS,EAAE,CAAC,OAAO,SAAS,CAAC,CAAC,MAAM,OAAO,SAAS,CAAC,EAAE,WAAW,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,GAAG,GAAG;CA6C9H"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@slickgrid-universal/odata",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.12.0",
|
|
4
4
|
"description": "Grid OData Service to sync a grid with an OData backend server",
|
|
5
5
|
"main": "./dist/cjs/index.js",
|
|
6
6
|
"types": "./dist/types/index.d.ts",
|
|
@@ -38,12 +38,12 @@
|
|
|
38
38
|
"not dead"
|
|
39
39
|
],
|
|
40
40
|
"dependencies": {
|
|
41
|
-
"@slickgrid-universal/common": "~5.
|
|
42
|
-
"@slickgrid-universal/utils": "~5.
|
|
41
|
+
"@slickgrid-universal/common": "~5.12.0",
|
|
42
|
+
"@slickgrid-universal/utils": "~5.12.0"
|
|
43
43
|
},
|
|
44
44
|
"funding": {
|
|
45
45
|
"type": "ko_fi",
|
|
46
46
|
"url": "https://ko-fi.com/ghiscoding"
|
|
47
47
|
},
|
|
48
|
-
"gitHead": "
|
|
48
|
+
"gitHead": "d7e892ebc1727d7c83cc1e5cc80db8302eef4f63"
|
|
49
49
|
}
|
|
@@ -21,14 +21,7 @@ import type {
|
|
|
21
21
|
SingleColumnSort,
|
|
22
22
|
SlickGrid,
|
|
23
23
|
} from '@slickgrid-universal/common';
|
|
24
|
-
import {
|
|
25
|
-
CaseType,
|
|
26
|
-
FieldType,
|
|
27
|
-
mapOperatorByFieldType,
|
|
28
|
-
OperatorType,
|
|
29
|
-
parseUtcDate,
|
|
30
|
-
SortDirection,
|
|
31
|
-
} from '@slickgrid-universal/common';
|
|
24
|
+
import { CaseType, FieldType, mapOperatorByFieldType, OperatorType, parseUtcDate, SortDirection } from '@slickgrid-universal/common';
|
|
32
25
|
import { getHtmlStringOutput, stripTags, titleCase } from '@slickgrid-universal/utils';
|
|
33
26
|
import { OdataQueryBuilderService } from './odataQueryBuilder.service.js';
|
|
34
27
|
import type { OdataOption, OdataSortingOption } from '../interfaces/index.js';
|
|
@@ -48,7 +41,7 @@ export class GridOdataService implements BackendService {
|
|
|
48
41
|
defaultOptions: OdataOption = {
|
|
49
42
|
top: DEFAULT_ITEMS_PER_PAGE,
|
|
50
43
|
orderBy: '',
|
|
51
|
-
caseType: CaseType.pascalCase
|
|
44
|
+
caseType: CaseType.pascalCase,
|
|
52
45
|
};
|
|
53
46
|
|
|
54
47
|
/** Getter for the Column Definitions */
|
|
@@ -63,7 +56,7 @@ export class GridOdataService implements BackendService {
|
|
|
63
56
|
|
|
64
57
|
/** Getter for the Grid Options pulled through the Grid Object */
|
|
65
58
|
protected get _gridOptions(): GridOption {
|
|
66
|
-
return this._grid?.getOptions() ?? {} as GridOption;
|
|
59
|
+
return this._grid?.getOptions() ?? ({} as GridOption);
|
|
67
60
|
}
|
|
68
61
|
|
|
69
62
|
constructor() {
|
|
@@ -80,11 +73,12 @@ export class GridOdataService implements BackendService {
|
|
|
80
73
|
this._odataService.options = { ...mergedOptions, top: undefined };
|
|
81
74
|
this._currentPagination = null;
|
|
82
75
|
} else {
|
|
83
|
-
const topOption =
|
|
76
|
+
const topOption =
|
|
77
|
+
(mergedOptions.infiniteScroll as InfiniteScrollOption)?.fetchSize ?? pagination?.pageSize ?? this.defaultOptions.top;
|
|
84
78
|
this._odataService.options = { ...mergedOptions, top: topOption };
|
|
85
79
|
this._currentPagination = {
|
|
86
80
|
pageNumber: 1,
|
|
87
|
-
pageSize: this._odataService.options.top || this.defaultOptions.top || DEFAULT_PAGE_SIZE
|
|
81
|
+
pageSize: this._odataService.options.top || this.defaultOptions.top || DEFAULT_PAGE_SIZE,
|
|
88
82
|
};
|
|
89
83
|
}
|
|
90
84
|
|
|
@@ -108,10 +102,12 @@ export class GridOdataService implements BackendService {
|
|
|
108
102
|
const odataVersion = this._odataService.options.version ?? 2;
|
|
109
103
|
|
|
110
104
|
if (this.pagination && this._odataService.options.enableCount) {
|
|
111
|
-
const countExtractor =
|
|
112
|
-
odataVersion >= 4
|
|
113
|
-
|
|
114
|
-
|
|
105
|
+
const countExtractor =
|
|
106
|
+
(this._odataService.options.countExtractor ?? odataVersion >= 4)
|
|
107
|
+
? (r: any) => r?.['@odata.count']
|
|
108
|
+
: odataVersion === 3
|
|
109
|
+
? (r: any) => r?.['__count']
|
|
110
|
+
: (r: any) => r?.d?.['__count'];
|
|
115
111
|
const count = countExtractor(processResult);
|
|
116
112
|
if (typeof count === 'number') {
|
|
117
113
|
this.pagination.totalItems = count;
|
|
@@ -119,15 +115,17 @@ export class GridOdataService implements BackendService {
|
|
|
119
115
|
}
|
|
120
116
|
|
|
121
117
|
if (this._odataService.options.enableExpand) {
|
|
122
|
-
const datasetExtractor =
|
|
123
|
-
odataVersion >= 4
|
|
124
|
-
|
|
125
|
-
|
|
118
|
+
const datasetExtractor =
|
|
119
|
+
(this._odataService.options.datasetExtractor ?? odataVersion >= 4)
|
|
120
|
+
? (r: any) => r?.value
|
|
121
|
+
: odataVersion === 3
|
|
122
|
+
? (r: any) => r?.results
|
|
123
|
+
: (r: any) => r?.d?.results;
|
|
126
124
|
const dataset = datasetExtractor(processResult);
|
|
127
125
|
if (Array.isArray(dataset)) {
|
|
128
126
|
// Flatten navigation fields (fields containing /) in the dataset (regardless of enableExpand).
|
|
129
127
|
// E.g. given columndefinition 'product/name' and dataset [{id: 1,product:{'name':'flowers'}}], then flattens to [{id:1,'product/name':'flowers'}]
|
|
130
|
-
const navigationFields = new Set(this._columnDefinitions.flatMap(x => x.fields ?? [x.field]).filter(x => x.includes('/')));
|
|
128
|
+
const navigationFields = new Set(this._columnDefinitions.flatMap((x) => x.fields ?? [x.field]).filter((x) => x.includes('/')));
|
|
131
129
|
if (navigationFields.size > 0) {
|
|
132
130
|
const navigations = new Set<string>();
|
|
133
131
|
for (const item of dataset) {
|
|
@@ -232,7 +230,7 @@ export class GridOdataService implements BackendService {
|
|
|
232
230
|
*/
|
|
233
231
|
resetPaginationOptions(): void {
|
|
234
232
|
this._odataService.updateOptions({
|
|
235
|
-
skip: 0
|
|
233
|
+
skip: 0,
|
|
236
234
|
});
|
|
237
235
|
}
|
|
238
236
|
|
|
@@ -269,7 +267,11 @@ export class GridOdataService implements BackendService {
|
|
|
269
267
|
* PAGINATION
|
|
270
268
|
*/
|
|
271
269
|
processOnPaginationChanged(_event: Event | undefined, args: PaginationChangedArgs): string {
|
|
272
|
-
const pageSize = +(
|
|
270
|
+
const pageSize = +(
|
|
271
|
+
(this.options?.infiniteScroll as InfiniteScrollOption)?.fetchSize ||
|
|
272
|
+
args.pageSize ||
|
|
273
|
+
(this.pagination ? this.pagination.pageSize : DEFAULT_PAGE_SIZE)
|
|
274
|
+
);
|
|
273
275
|
this.updatePagination(args.newPage, pageSize);
|
|
274
276
|
|
|
275
277
|
// build the OData query which we will use in the WebAPI callback
|
|
@@ -280,7 +282,13 @@ export class GridOdataService implements BackendService {
|
|
|
280
282
|
* SORTING
|
|
281
283
|
*/
|
|
282
284
|
processOnSortChanged(_event: Event | undefined, args: SingleColumnSort | MultiColumnSort): string {
|
|
283
|
-
const sortColumns =
|
|
285
|
+
const sortColumns = args.multiColumnSort
|
|
286
|
+
? (args as MultiColumnSort).sortCols
|
|
287
|
+
: new Array({
|
|
288
|
+
columnId: (args as ColumnSort).sortCol?.id ?? '',
|
|
289
|
+
sortCol: (args as ColumnSort).sortCol,
|
|
290
|
+
sortAsc: (args as ColumnSort).sortAsc,
|
|
291
|
+
});
|
|
284
292
|
|
|
285
293
|
// loop through all columns to inspect sorters & set the query
|
|
286
294
|
this.updateSorters(sortColumns);
|
|
@@ -321,22 +329,27 @@ export class GridOdataService implements BackendService {
|
|
|
321
329
|
columnDef = columnFilter.columnDef;
|
|
322
330
|
}
|
|
323
331
|
if (!columnDef) {
|
|
324
|
-
throw new Error(
|
|
332
|
+
throw new Error(
|
|
333
|
+
'[GridOData Service]: Something went wrong in trying to get the column definition of the specified filter (or preset filters). Did you make a typo on the filter columnId?'
|
|
334
|
+
);
|
|
325
335
|
}
|
|
326
336
|
|
|
327
|
-
let fieldName =
|
|
337
|
+
let fieldName =
|
|
338
|
+
columnDef.filter?.queryField || columnDef.queryFieldFilter || columnDef.queryField || columnDef.field || columnDef.name || '';
|
|
328
339
|
if (fieldName instanceof HTMLElement) {
|
|
329
340
|
fieldName = stripTags(fieldName.innerHTML);
|
|
330
341
|
}
|
|
331
342
|
const fieldType = columnDef.type || FieldType.string;
|
|
332
343
|
let searchTerms = (columnFilter?.searchTerms ? [...columnFilter.searchTerms] : null) || [];
|
|
333
|
-
let fieldSearchValue =
|
|
344
|
+
let fieldSearchValue = Array.isArray(searchTerms) && searchTerms.length === 1 ? searchTerms[0] : '';
|
|
334
345
|
if (typeof fieldSearchValue === 'undefined') {
|
|
335
346
|
fieldSearchValue = '';
|
|
336
347
|
}
|
|
337
348
|
|
|
338
349
|
if (!fieldName) {
|
|
339
|
-
throw new Error(
|
|
350
|
+
throw new Error(
|
|
351
|
+
`GridOData filter could not find the field name to query the search, your column definition must include a valid "field" or "name" (optionally you can also use the "queryfield").`
|
|
352
|
+
);
|
|
340
353
|
}
|
|
341
354
|
|
|
342
355
|
if (this._odataService.options.useVerbatimSearchTerms || columnFilter.verbatimSearchTerms) {
|
|
@@ -344,21 +357,22 @@ export class GridOdataService implements BackendService {
|
|
|
344
357
|
continue;
|
|
345
358
|
}
|
|
346
359
|
|
|
347
|
-
fieldSearchValue =
|
|
360
|
+
fieldSearchValue = fieldSearchValue === undefined || fieldSearchValue === null ? '' : `${fieldSearchValue}`; // make sure it's a string
|
|
348
361
|
|
|
349
362
|
// run regex to find possible filter operators unless the user disabled the feature
|
|
350
363
|
const autoParseInputFilterOperator = columnDef.autoParseInputFilterOperator ?? this._gridOptions.autoParseInputFilterOperator;
|
|
351
364
|
|
|
352
365
|
// group (2): comboStartsWith, (3): comboEndsWith, (4): Operator, (1 or 5): searchValue, (6): last char is '*' (meaning starts with, ex.: abc*)
|
|
353
|
-
const matches =
|
|
354
|
-
|
|
355
|
-
|
|
366
|
+
const matches =
|
|
367
|
+
autoParseInputFilterOperator !== false
|
|
368
|
+
? fieldSearchValue.match(/^((.*[^\\*\r\n])[*]{1}(.*[^*\r\n]))|^([<>!=*]{0,2})(.*[^<>!=*])([*]?)$/) || []
|
|
369
|
+
: [fieldSearchValue, '', '', '', '', fieldSearchValue, ''];
|
|
356
370
|
|
|
357
371
|
const comboStartsWith = matches?.[2] || '';
|
|
358
372
|
const comboEndsWith = matches?.[3] || '';
|
|
359
373
|
let operator = columnFilter.operator || matches?.[4];
|
|
360
374
|
let searchValue = matches?.[1] || matches?.[5] || '';
|
|
361
|
-
const lastValueChar = matches?.[6] ||
|
|
375
|
+
const lastValueChar = matches?.[6] || operator === '*z' || operator === OperatorType.endsWith ? '*' : '';
|
|
362
376
|
const bypassOdataQuery = columnFilter.bypassBackendQuery || false;
|
|
363
377
|
|
|
364
378
|
// no need to query if search value is empty
|
|
@@ -371,7 +385,12 @@ export class GridOdataService implements BackendService {
|
|
|
371
385
|
if (comboStartsWith && comboEndsWith) {
|
|
372
386
|
searchTerms = [comboStartsWith, comboEndsWith];
|
|
373
387
|
operator = OperatorType.startsWithEndsWith;
|
|
374
|
-
} else if (
|
|
388
|
+
} else if (
|
|
389
|
+
Array.isArray(searchTerms) &&
|
|
390
|
+
searchTerms.length === 1 &&
|
|
391
|
+
typeof searchTerms[0] === 'string' &&
|
|
392
|
+
searchTerms[0].indexOf('..') >= 0
|
|
393
|
+
) {
|
|
375
394
|
// range filter
|
|
376
395
|
if (operator !== OperatorType.rangeInclusive && operator !== OperatorType.rangeExclusive) {
|
|
377
396
|
operator = this._gridOptions.defaultFilterRangeOperator ?? OperatorType.rangeInclusive;
|
|
@@ -401,7 +420,12 @@ export class GridOdataService implements BackendService {
|
|
|
401
420
|
}
|
|
402
421
|
|
|
403
422
|
// Range with 1 searchterm should lead to equals for a date field.
|
|
404
|
-
if (
|
|
423
|
+
if (
|
|
424
|
+
(operator === OperatorType.rangeInclusive || operator === OperatorType.rangeExclusive) &&
|
|
425
|
+
Array.isArray(searchTerms) &&
|
|
426
|
+
searchTerms.length === 1 &&
|
|
427
|
+
fieldType === FieldType.date
|
|
428
|
+
) {
|
|
405
429
|
operator = OperatorType.equal;
|
|
406
430
|
}
|
|
407
431
|
|
|
@@ -440,7 +464,7 @@ export class GridOdataService implements BackendService {
|
|
|
440
464
|
operator,
|
|
441
465
|
columnFilterOperator: columnFilter.operator,
|
|
442
466
|
searchValues: searchTerms,
|
|
443
|
-
grid: this._grid
|
|
467
|
+
grid: this._grid,
|
|
444
468
|
});
|
|
445
469
|
}
|
|
446
470
|
|
|
@@ -454,7 +478,10 @@ export class GridOdataService implements BackendService {
|
|
|
454
478
|
tmpSearchTerms.push(`startswith(${fieldName}, ${sw})`);
|
|
455
479
|
tmpSearchTerms.push(`endswith(${fieldName}, ${ew})`);
|
|
456
480
|
searchBy = tmpSearchTerms.join(' and ');
|
|
457
|
-
} else if (
|
|
481
|
+
} else if (
|
|
482
|
+
searchTerms?.length > 1 &&
|
|
483
|
+
(operator === 'IN' || operator === 'NIN' || operator === 'NOTIN' || operator === 'NOT IN' || operator === 'NOT_IN')
|
|
484
|
+
) {
|
|
458
485
|
// when having more than 1 search term (then check if we have a "IN" or "NOT IN" filter search)
|
|
459
486
|
const tmpSearchTerms: string[] = [];
|
|
460
487
|
if (operator === 'IN') {
|
|
@@ -473,14 +500,26 @@ export class GridOdataService implements BackendService {
|
|
|
473
500
|
if (!(typeof searchBy === 'string' && searchBy[0] === '(' && searchBy.slice(-1) === ')')) {
|
|
474
501
|
searchBy = `(${searchBy})`;
|
|
475
502
|
}
|
|
476
|
-
} else if (
|
|
503
|
+
} else if (
|
|
504
|
+
operator === '*' ||
|
|
505
|
+
operator === 'a*' ||
|
|
506
|
+
operator === '*z' ||
|
|
507
|
+
lastValueChar === '*' ||
|
|
508
|
+
operator === OperatorType.startsWith ||
|
|
509
|
+
operator === OperatorType.endsWith
|
|
510
|
+
) {
|
|
477
511
|
// first/last character is a '*' will be a startsWith or endsWith
|
|
478
|
-
searchBy =
|
|
512
|
+
searchBy =
|
|
513
|
+
operator === '*' || operator === '*z' || operator === OperatorType.endsWith
|
|
514
|
+
? `endswith(${fieldName}, ${searchValue})`
|
|
515
|
+
: `startswith(${fieldName}, ${searchValue})`;
|
|
479
516
|
} else if (operator === OperatorType.rangeExclusive || operator === OperatorType.rangeInclusive) {
|
|
480
517
|
// example:: (Name >= 'Bob' and Name <= 'Jane')
|
|
481
518
|
searchBy = this.filterBySearchTermRange(getHtmlStringOutput(fieldName), operator, searchTerms);
|
|
482
|
-
} else if (
|
|
483
|
-
(
|
|
519
|
+
} else if (
|
|
520
|
+
(operator === '' || operator === OperatorType.contains || operator === OperatorType.notContains) &&
|
|
521
|
+
(fieldType === FieldType.string || fieldType === FieldType.text || fieldType === FieldType.readonly)
|
|
522
|
+
) {
|
|
484
523
|
searchBy = odataVersion >= 4 ? `contains(${fieldName}, ${searchValue})` : `substringof(${searchValue}, ${fieldName})`;
|
|
485
524
|
if (operator === OperatorType.notContains) {
|
|
486
525
|
searchBy = `not ${searchBy}`;
|
|
@@ -501,8 +540,8 @@ export class GridOdataService implements BackendService {
|
|
|
501
540
|
|
|
502
541
|
// update the service options with filters for the buildQuery() to work later
|
|
503
542
|
this._odataService.updateOptions({
|
|
504
|
-
filter:
|
|
505
|
-
skip: undefined
|
|
543
|
+
filter: searchByArray.length > 0 ? searchByArray.join(' and ') : '',
|
|
544
|
+
skip: undefined,
|
|
506
545
|
});
|
|
507
546
|
}
|
|
508
547
|
|
|
@@ -518,10 +557,13 @@ export class GridOdataService implements BackendService {
|
|
|
518
557
|
};
|
|
519
558
|
|
|
520
559
|
// unless user specifically set "enablePagination" to False, we'll update pagination options in every other cases
|
|
521
|
-
if (
|
|
560
|
+
if (
|
|
561
|
+
this._gridOptions &&
|
|
562
|
+
(this._gridOptions.enablePagination || !this._gridOptions.hasOwnProperty('enablePagination') || this.options?.infiniteScroll)
|
|
563
|
+
) {
|
|
522
564
|
this._odataService.updateOptions({
|
|
523
565
|
top: pageSize,
|
|
524
|
-
skip: (newPage - 1) * pageSize
|
|
566
|
+
skip: (newPage - 1) * pageSize,
|
|
525
567
|
});
|
|
526
568
|
}
|
|
527
569
|
}
|
|
@@ -537,26 +579,26 @@ export class GridOdataService implements BackendService {
|
|
|
537
579
|
if (!sortColumns && presetSorters) {
|
|
538
580
|
// make the presets the current sorters, also make sure that all direction are in lowercase for OData
|
|
539
581
|
currentSorters = presetSorters;
|
|
540
|
-
currentSorters.forEach((sorter) => sorter.direction = sorter.direction.toLowerCase() as SortDirectionString);
|
|
582
|
+
currentSorters.forEach((sorter) => (sorter.direction = sorter.direction.toLowerCase() as SortDirectionString));
|
|
541
583
|
|
|
542
584
|
// display the correct sorting icons on the UI, for that it requires (columnId, sortAsc) properties
|
|
543
585
|
const tmpSorterArray = currentSorters.map((sorter) => {
|
|
544
586
|
const columnDef = this._columnDefinitions.find((column: Column) => column.id === sorter.columnId);
|
|
545
587
|
|
|
546
588
|
odataSorters.push({
|
|
547
|
-
field: columnDef ? (
|
|
548
|
-
direction: sorter.direction
|
|
589
|
+
field: columnDef ? (columnDef.queryFieldSorter || columnDef.queryField || columnDef.field) + '' : sorter.columnId + '',
|
|
590
|
+
direction: sorter.direction,
|
|
549
591
|
});
|
|
550
592
|
|
|
551
593
|
// return only the column(s) found in the Column Definitions ELSE null
|
|
552
594
|
if (columnDef) {
|
|
553
595
|
return {
|
|
554
596
|
columnId: sorter.columnId,
|
|
555
|
-
sortAsc: sorter.direction.toUpperCase() === SortDirection.ASC
|
|
597
|
+
sortAsc: sorter.direction.toUpperCase() === SortDirection.ASC,
|
|
556
598
|
};
|
|
557
599
|
}
|
|
558
600
|
return null;
|
|
559
|
-
}) as { columnId: string | number; sortAsc: boolean
|
|
601
|
+
}) as { columnId: string | number; sortAsc: boolean }[] | null;
|
|
560
602
|
|
|
561
603
|
// set the sort icons, but also make sure to filter out null values (that happens when columnDef is not found)
|
|
562
604
|
if (Array.isArray(tmpSorterArray) && this._grid) {
|
|
@@ -582,13 +624,13 @@ export class GridOdataService implements BackendService {
|
|
|
582
624
|
|
|
583
625
|
currentSorters.push({
|
|
584
626
|
columnId: columnDef.sortCol.id,
|
|
585
|
-
direction: columnDef.sortAsc ? SortDirection.asc : SortDirection.desc
|
|
627
|
+
direction: columnDef.sortAsc ? SortDirection.asc : SortDirection.desc,
|
|
586
628
|
});
|
|
587
629
|
|
|
588
630
|
if (queryField !== '') {
|
|
589
631
|
odataSorters.push({
|
|
590
632
|
field: queryField,
|
|
591
|
-
direction: columnDef.sortAsc ? SortDirection.ASC : SortDirection.DESC
|
|
633
|
+
direction: columnDef.sortAsc ? SortDirection.ASC : SortDirection.DESC,
|
|
592
634
|
});
|
|
593
635
|
}
|
|
594
636
|
}
|
|
@@ -598,18 +640,20 @@ export class GridOdataService implements BackendService {
|
|
|
598
640
|
}
|
|
599
641
|
|
|
600
642
|
// transform the sortby array into a CSV string for OData
|
|
601
|
-
currentSorters = currentSorters || [] as CurrentSorter[];
|
|
602
|
-
const csvString = odataSorters
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
643
|
+
currentSorters = currentSorters || ([] as CurrentSorter[]);
|
|
644
|
+
const csvString = odataSorters
|
|
645
|
+
.map((sorter) => {
|
|
646
|
+
let str = '';
|
|
647
|
+
if (sorter && sorter.field) {
|
|
648
|
+
const sortField = this._odataService.options.caseType === CaseType.pascalCase ? titleCase(sorter.field) : sorter.field;
|
|
649
|
+
str = `${sortField} ${(sorter && sorter.direction && sorter.direction.toLowerCase()) || ''}`;
|
|
650
|
+
}
|
|
651
|
+
return str;
|
|
652
|
+
})
|
|
653
|
+
.join(',');
|
|
610
654
|
|
|
611
655
|
this._odataService.updateOptions({
|
|
612
|
-
orderBy: csvString
|
|
656
|
+
orderBy: csvString,
|
|
613
657
|
});
|
|
614
658
|
|
|
615
659
|
// keep current Sorters and update the service options with the new sorting
|
|
@@ -628,7 +672,8 @@ export class GridOdataService implements BackendService {
|
|
|
628
672
|
*/
|
|
629
673
|
protected castFilterToColumnFilters(columnFilters: ColumnFilters | CurrentFilter[]): CurrentFilter[] {
|
|
630
674
|
// keep current filters & always save it as an array (columnFilters can be an object when it is dealt by SlickGrid Filter)
|
|
631
|
-
const filtersArray: ColumnFilter[] =
|
|
675
|
+
const filtersArray: ColumnFilter[] =
|
|
676
|
+
typeof columnFilters === 'object' ? Object.keys(columnFilters).map((key) => (columnFilters as any)[key]) : columnFilters;
|
|
632
677
|
|
|
633
678
|
if (!Array.isArray(filtersArray)) {
|
|
634
679
|
return [];
|
|
@@ -677,7 +722,7 @@ export class GridOdataService implements BackendService {
|
|
|
677
722
|
/**
|
|
678
723
|
* Normalizes the search value according to field type and oData version.
|
|
679
724
|
*/
|
|
680
|
-
protected normalizeSearchValue(fieldType: typeof FieldType[keyof typeof FieldType], searchValue: any, version: number): any {
|
|
725
|
+
protected normalizeSearchValue(fieldType: (typeof FieldType)[keyof typeof FieldType], searchValue: any, version: number): any {
|
|
681
726
|
switch (fieldType) {
|
|
682
727
|
case FieldType.date:
|
|
683
728
|
searchValue = parseUtcDate(searchValue as string);
|
|
@@ -21,16 +21,16 @@ export class OdataQueryBuilderService {
|
|
|
21
21
|
constructor() {
|
|
22
22
|
this._odataOptions = {
|
|
23
23
|
filterQueue: [],
|
|
24
|
-
orderBy: ''
|
|
24
|
+
orderBy: '',
|
|
25
25
|
};
|
|
26
26
|
this._defaultSortBy = '';
|
|
27
27
|
this._columnFilters = {};
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
/*
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
31
|
+
* Build the OData query string from all the options provided
|
|
32
|
+
* @return string OData query
|
|
33
|
+
*/
|
|
34
34
|
buildQuery(): string {
|
|
35
35
|
if (!this._odataOptions) {
|
|
36
36
|
throw new Error('Odata Service requires certain options like "top" for it to work');
|
|
@@ -40,7 +40,7 @@ export class OdataQueryBuilderService {
|
|
|
40
40
|
|
|
41
41
|
// When enableCount is set, add it to the OData query
|
|
42
42
|
if (this._odataOptions?.enableCount === true) {
|
|
43
|
-
const countQuery =
|
|
43
|
+
const countQuery = this._odataOptions.version && this._odataOptions.version >= 4 ? '$count=true' : '$inlinecount=allpages';
|
|
44
44
|
queryTmpArray.push(countQuery);
|
|
45
45
|
}
|
|
46
46
|
|
|
@@ -86,7 +86,7 @@ export class OdataQueryBuilderService {
|
|
|
86
86
|
}
|
|
87
87
|
|
|
88
88
|
if (this._odataOptions.enableSelect || this._odataOptions.enableExpand) {
|
|
89
|
-
const fields = this._columnDefinitions.flatMap(x => x.fields ?? [x.field]);
|
|
89
|
+
const fields = this._columnDefinitions.flatMap((x) => x.fields ?? [x.field]);
|
|
90
90
|
fields.unshift(this._datasetIdPropName);
|
|
91
91
|
const selectExpand = this.buildSelectExpand([...new Set(fields)]);
|
|
92
92
|
if (this._odataOptions.enableSelect) {
|
|
@@ -128,7 +128,7 @@ export class OdataQueryBuilderService {
|
|
|
128
128
|
saveColumnFilter(fieldName: string, value: any, searchTerms?: any[]): void {
|
|
129
129
|
this._columnFilters[fieldName] = {
|
|
130
130
|
search: searchTerms,
|
|
131
|
-
value
|
|
131
|
+
value,
|
|
132
132
|
};
|
|
133
133
|
}
|
|
134
134
|
|
|
@@ -177,8 +177,8 @@ export class OdataQueryBuilderService {
|
|
|
177
177
|
// private functions
|
|
178
178
|
// -------------------
|
|
179
179
|
|
|
180
|
-
private buildSelectExpand(selectFields: string[]): { selectParts: string[]; expandParts: string[]
|
|
181
|
-
const navigations: { [navigation: string]: string[]
|
|
180
|
+
private buildSelectExpand(selectFields: string[]): { selectParts: string[]; expandParts: string[] } {
|
|
181
|
+
const navigations: { [navigation: string]: string[] } = {};
|
|
182
182
|
const selectItems = new Set<string>();
|
|
183
183
|
|
|
184
184
|
for (const field of selectFields) {
|
|
@@ -203,11 +203,11 @@ export class OdataQueryBuilderService {
|
|
|
203
203
|
|
|
204
204
|
return {
|
|
205
205
|
selectParts: [...selectItems],
|
|
206
|
-
expandParts: this._odataOptions.enableExpand ? this.buildExpand(navigations) : []
|
|
206
|
+
expandParts: this._odataOptions.enableExpand ? this.buildExpand(navigations) : [],
|
|
207
207
|
};
|
|
208
208
|
}
|
|
209
209
|
|
|
210
|
-
private buildExpand(navigations: { [navigation: string]: string[]
|
|
210
|
+
private buildExpand(navigations: { [navigation: string]: string[] }): string[] {
|
|
211
211
|
const expandParts = [];
|
|
212
212
|
for (const navigation of Object.keys(navigations)) {
|
|
213
213
|
if (this._odataOptions.enableSelect && this._odataOptions.version && this._odataOptions.version >= 4) {
|