Skip to content
This repository was archived by the owner on Jun 1, 2025. It is now read-only.

Commit 1d70037

Browse files
committed
feat(odata): add "enableCount" flag to add to OData query, closes #287
- update Jest unit tests - update Cypress E2E tests
1 parent 695f602 commit 1d70037

File tree

9 files changed

+470
-213
lines changed

9 files changed

+470
-213
lines changed
Lines changed: 46 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,51 +1,54 @@
11
<div class="container-fluid">
2-
<h2>{{title}}</h2>
3-
<div class="subtitle" [innerHTML]="subTitle"></div>
4-
<br>
2+
<h2>{{title}}</h2>
3+
<div class="subtitle" [innerHTML]="subTitle"></div>
4+
<br>
55

6-
<div class="col-sm-6">
7-
<label>autoEdit setting: </label>
8-
<span id="radioAutoEdit">
9-
<label class="radio-inline control-label" for="radioTrue">
10-
<input type="radio" name="inlineRadioOptions" id="radioTrue" checked [value]="isAutoEdit" (change)="setAutoEdit(true)"> ON (single-click)
11-
</label>
12-
<label class="radio-inline control-label" for="radioFalse">
13-
<input type="radio" name="inlineRadioOptions" id="radioFalse" [value]="isAutoEdit" (change)="setAutoEdit(false)"> OFF (double-click)
14-
</label>
15-
</span>
16-
<div class="row col-sm-12">
17-
<span>
18-
<button class="btn btn-default btn-sm" (click)="undo()">
19-
<i class="fa fa-undo"></i>
20-
Undo last edit(s)
21-
</button>
22-
<button class="btn btn-default btn-sm" (click)="angularGrid.filterService.clearFilters()">Clear Filters</button>
23-
<button class="btn btn-default btn-sm" (click)="angularGrid.sortService.clearSorting()">Clear Sorting</button>
24-
<label class="checkbox-inline control-label" for="autoCommitEdit">
25-
<input type="checkbox" id="autoCommitEdit" [value]="gridOptions.autoCommitEdit" (click)="changeAutoCommit()">
26-
Auto Commit Edit
27-
</label>
28-
</span>
29-
</div>
6+
<div class="col-sm-6">
7+
<label>autoEdit setting: </label>
8+
<span id="radioAutoEdit">
9+
<label class="radio-inline control-label" for="radioTrue">
10+
<input type="radio" name="inlineRadioOptions" id="radioTrue" checked [value]="isAutoEdit"
11+
(change)="setAutoEdit(true)"> ON (single-click)
12+
</label>
13+
<label class="radio-inline control-label" for="radioFalse">
14+
<input type="radio" name="inlineRadioOptions" id="radioFalse" [value]="isAutoEdit"
15+
(change)="setAutoEdit(false)"> OFF (double-click)
16+
</label>
17+
</span>
18+
<div class="row col-sm-12">
19+
<span>
20+
<button class="btn btn-default btn-sm" (click)="undo()">
21+
<i class="fa fa-undo"></i>
22+
Undo last edit(s)
23+
</button>
24+
<button class="btn btn-default btn-sm" (click)="angularGrid.filterService.clearFilters()">Clear Filters</button>
25+
<button class="btn btn-default btn-sm" (click)="angularGrid.sortService.clearSorting()">Clear Sorting</button>
26+
<label class="checkbox-inline control-label" for="autoCommitEdit">
27+
<input type="checkbox" id="autoCommitEdit" [checked]="gridOptions.autoCommitEdit"
28+
(click)="changeAutoCommit()">
29+
Auto Commit Edit
30+
</label>
31+
</span>
3032
</div>
33+
</div>
3134

3235

33-
<div class="col-sm-6">
34-
<div class="alert alert-info" *ngIf="updatedObject">
35-
<strong>Updated Item:</strong> {{updatedObject | json}}
36-
</div>
37-
<div class="alert alert-warning" *ngIf="alertWarning">
38-
<strong>Updated Item:</strong> {{alertWarning}}
39-
</div>
36+
<div class="col-sm-6">
37+
<div class="alert alert-info" *ngIf="updatedObject">
38+
<strong>Updated Item:</strong> {{updatedObject | json}}
4039
</div>
41-
42-
<div class="col-sm-12">
43-
<angular-slickgrid gridId="grid22"
44-
(onAngularGridCreated)="angularGridReady($event)"
45-
(sgOnCellChange)="onCellChanged($event.detail.eventData, $event.detail.args)"
46-
(sgOnClick)="onCellClicked($event.detail.eventData, $event.detail.args)"
47-
(sgOnValidationError)="onCellValidation($event.detail.eventData, $event.detail.args)"
48-
[columnDefinitions]="columnDefinitions" [gridOptions]="gridOptions" [dataset]="dataset">
49-
</angular-slickgrid>
40+
<div class="alert alert-warning" *ngIf="alertWarning">
41+
<strong>Updated Item:</strong> {{alertWarning}}
5042
</div>
43+
</div>
44+
45+
<div class="col-sm-12">
46+
<angular-slickgrid gridId="grid22"
47+
(onAngularGridCreated)="angularGridReady($event)"
48+
(sgOnCellChange)="onCellChanged($event.detail.eventData, $event.detail.args)"
49+
(sgOnClick)="onCellClicked($event.detail.eventData, $event.detail.args)"
50+
(sgOnValidationError)="onCellValidation($event.detail.eventData, $event.detail.args)"
51+
[columnDefinitions]="columnDefinitions" [gridOptions]="gridOptions" [dataset]="dataset">
52+
</angular-slickgrid>
53+
</div>
5154
</div>
Lines changed: 54 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,59 +1,63 @@
11
<div class="container-fluid">
2-
<h2>{{title}}</h2>
3-
<div class="subtitle" [innerHTML]="subTitle"></div>
2+
<h2>{{title}}</h2>
3+
<div class="subtitle" [innerHTML]="subTitle"></div>
44

5-
<div class="col-sm-6">
6-
<label>autoEdit setting: </label>
7-
<span id="radioAutoEdit">
8-
<label class="radio-inline control-label" for="radioTrue">
9-
<input type="radio" name="inlineRadioOptions" id="radioTrue" checked [value]="isAutoEdit" (change)="setAutoEdit(true)"> ON (single-click)
10-
</label>
11-
<label class="radio-inline control-label" for="radioFalse">
12-
<input type="radio" name="inlineRadioOptions" id="radioFalse" [value]="isAutoEdit" (change)="setAutoEdit(false)"> OFF (double-click)
13-
</label>
14-
</span>
15-
<div class="row col-sm-12">
16-
<span>
17-
<button class="btn btn-default btn-sm" (click)="undo()">
18-
<i class="fa fa-undo"></i>
19-
Undo last edit(s)
20-
</button>
21-
<label class="checkbox-inline control-label" for="autoCommitEdit">
22-
<input type="checkbox" id="autoCommitEdit" [value]="gridOptions.autoCommitEdit" (click)="changeAutoCommit()">
23-
Auto Commit Edit
24-
</label>
25-
</span>
26-
</div>
27-
<div class="row" style="margin-top: 5px">
28-
<button class="btn btn-default btn-sm" (click)="angularGrid.filterService.clearFilters()">Clear Filters</button>
29-
<button class="btn btn-default btn-sm" (click)="angularGrid.sortService.clearSorting()">Clear Sorting</button>
30-
<button class="btn btn-default btn-sm btn-info" (click)="addItem()" title="Clear Filters &amp; Sorting to see it better">Add item</button>
31-
<button class="btn btn-default btn-sm btn-danger" (click)="deleteItem()">Delete item</button>
32-
<button class="btn btn-default btn-sm" (click)="dynamicallyAddTitleHeader()">
33-
<i class="fa fa-plus"></i>
34-
Dynamically Duplicate Title Column
35-
</button>
36-
</div>
5+
<div class="col-sm-6">
6+
<label>autoEdit setting: </label>
7+
<span id="radioAutoEdit">
8+
<label class="radio-inline control-label" for="radioTrue">
9+
<input type="radio" name="inlineRadioOptions" id="radioTrue" checked [value]="isAutoEdit"
10+
(change)="setAutoEdit(true)"> ON (single-click)
11+
</label>
12+
<label class="radio-inline control-label" for="radioFalse">
13+
<input type="radio" name="inlineRadioOptions" id="radioFalse" [value]="isAutoEdit"
14+
(change)="setAutoEdit(false)"> OFF (double-click)
15+
</label>
16+
</span>
17+
<div class="row col-sm-12">
18+
<span>
19+
<button class="btn btn-default btn-sm" (click)="undo()">
20+
<i class="fa fa-undo"></i>
21+
Undo last edit(s)
22+
</button>
23+
<label class="checkbox-inline control-label" for="autoCommitEdit">
24+
<input type="checkbox" id="autoCommitEdit" [checked]="gridOptions.autoCommitEdit"
25+
(click)="changeAutoCommit()">
26+
Auto Commit Edit
27+
</label>
28+
</span>
3729
</div>
30+
<div class="row" style="margin-top: 5px">
31+
<button class="btn btn-default btn-sm" (click)="angularGrid.filterService.clearFilters()">Clear Filters</button>
32+
<button class="btn btn-default btn-sm" (click)="angularGrid.sortService.clearSorting()">Clear Sorting</button>
33+
<button class="btn btn-default btn-sm btn-info" (click)="addItem()"
34+
title="Clear Filters &amp; Sorting to see it better">Add item</button>
35+
<button class="btn btn-default btn-sm btn-danger" (click)="deleteItem()">Delete item</button>
36+
<button class="btn btn-default btn-sm" (click)="dynamicallyAddTitleHeader()">
37+
<i class="fa fa-plus"></i>
38+
Dynamically Duplicate Title Column
39+
</button>
40+
</div>
41+
</div>
3842

3943

4044

41-
<div class="col-sm-6">
42-
<div class="alert alert-info" *ngIf="updatedObject">
43-
<strong>Updated Item:</strong> {{updatedObject | json}}
44-
</div>
45-
<div class="alert alert-warning" *ngIf="alertWarning">
46-
<strong>Updated Item:</strong> {{alertWarning}}
47-
</div>
45+
<div class="col-sm-6">
46+
<div class="alert alert-info" *ngIf="updatedObject">
47+
<strong>Updated Item:</strong> {{updatedObject | json}}
4848
</div>
49-
50-
<div class="col-sm-12 row">
51-
<angular-slickgrid gridId="grid2"
52-
(onAngularGridCreated)="angularGridReady($event)"
53-
(sgOnCellChange)="onCellChanged($event.detail.eventData, $event.detail.args)"
54-
(sgOnClick)="onCellClicked($event.detail.eventData, $event.detail.args)"
55-
(sgOnValidationError)="onCellValidation($event.detail.eventData, $event.detail.args)"
56-
[columnDefinitions]="columnDefinitions" [gridOptions]="gridOptions" [dataset]="dataset">
57-
</angular-slickgrid>
49+
<div class="alert alert-warning" *ngIf="alertWarning">
50+
<strong>Updated Item:</strong> {{alertWarning}}
5851
</div>
52+
</div>
53+
54+
<div class="col-sm-12 row">
55+
<angular-slickgrid gridId="grid2"
56+
(onAngularGridCreated)="angularGridReady($event)"
57+
(sgOnCellChange)="onCellChanged($event.detail.eventData, $event.detail.args)"
58+
(sgOnClick)="onCellClicked($event.detail.eventData, $event.detail.args)"
59+
(sgOnValidationError)="onCellValidation($event.detail.eventData, $event.detail.args)"
60+
[columnDefinitions]="columnDefinitions" [gridOptions]="gridOptions" [dataset]="dataset">
61+
</angular-slickgrid>
62+
</div>
5963
</div>

src/app/examples/grid-odata.component.html

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,22 +19,28 @@ <h2>{{title}}</h2>
1919
<div class="alert alert-info" data-test="alert-odata-query">
2020
<strong>OData Query:</strong> <span data-test="odata-query-result">{{odataQuery}}</span>
2121
</div>
22+
2223
<label>OData Version: </label>
2324
<span data-test="radioVersion">
2425
<label class="radio-inline control-label" for="radio2">
2526
<input type="radio" name="inlineRadioOptions" data-test="version2" id="radio2" checked [value]="2"
26-
(change)="setOdataVersion(2)"> 2
27+
(change)="setOdataVersion(2)"> 2
2728
</label>
2829
<label class="radio-inline control-label" for="radio4">
2930
<input type="radio" name="inlineRadioOptions" data-test="version4" id="radio4" [value]="4"
30-
(change)="setOdataVersion(4)"> 4
31+
(change)="setOdataVersion(4)"> 4
3132
</label>
3233
</span>
34+
<label class="checkbox-inline control-label" for="enableCount" style="margin-left: 20px">
35+
<input type="checkbox" id="enableCount" data-test="enable-count" [checked]="isCountEnabled"
36+
(click)="changeCountEnableFlag()">
37+
<span style="font-weight: bold">Enable Count</span> (add to OData query)
38+
</label>
3339
</div>
3440
</div>
3541

3642
<angular-slickgrid gridId="grid5" [columnDefinitions]="columnDefinitions" [gridOptions]="gridOptions"
37-
[dataset]="dataset" (onGridStateChanged)="gridStateChanged($event)"
38-
(onAngularGridCreated)="angularGridReady($event)">
43+
[dataset]="dataset" (onGridStateChanged)="gridStateChanged($event)"
44+
(onAngularGridCreated)="angularGridReady($event)">
3945
</angular-slickgrid>
4046
</div>

src/app/examples/grid-odata.component.ts

Lines changed: 35 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ import {
99
GridOption,
1010
GridStateChange,
1111
Statistic,
12-
OperatorType
12+
OdataOption,
13+
OperatorType,
1314
} from './../modules/angular-slickgrid';
1415

1516
const defaultPageSize = 20;
@@ -42,6 +43,7 @@ export class GridOdataComponent implements OnInit {
4243
dataset = [];
4344
statistics: Statistic;
4445

46+
isCountEnabled = true;
4547
odataVersion = 2;
4648
odataQuery = '';
4749
processing = true;
@@ -105,7 +107,10 @@ export class GridOdataComponent implements OnInit {
105107
},
106108
backendServiceApi: {
107109
service: new GridOdataService(),
108-
options: { version: this.odataVersion }, // defaults to 2, the query string is slightly different between OData 2 and 4
110+
options: {
111+
enableCount: this.isCountEnabled, // add the count in the OData query, which will return a property named "odata.count" (v2) or "@odata.count" (v4)
112+
version: this.odataVersion // defaults to 2, the query string is slightly different between OData 2 and 4
113+
} as OdataOption,
109114
preProcess: () => this.displaySpinner(true),
110115
process: (query) => this.getCustomerApiCall(query),
111116
postProcess: (response) => {
@@ -127,9 +132,13 @@ export class GridOdataComponent implements OnInit {
127132
getCustomerCallback(data) {
128133
// totalItems property needs to be filled for pagination to work correctly
129134
// however we need to force Angular to do a dirty check, doing a clone object will do just that
130-
this.gridOptions.pagination.totalItems = data['totalRecordCount'];
135+
let countPropName = 'totalRecordCount'; // you can use "totalRecordCount" or any name or "odata.count" when "enableCount" is set
136+
if (this.isCountEnabled) {
137+
countPropName = (this.odataVersion === 4) ? '@odata.count' : 'odata.count';
138+
}
139+
this.gridOptions.pagination.totalItems = data[countPropName];
131140
if (this.statistics) {
132-
this.statistics.totalItemCount = data['totalRecordCount'];
141+
this.statistics.totalItemCount = data[countPropName];
133142
}
134143
this.gridOptions = Object.assign({}, this.gridOptions);
135144

@@ -252,7 +261,13 @@ export class GridOdataComponent implements OnInit {
252261
const updatedData = filteredData.slice(firstRow, firstRow + top);
253262

254263
setTimeout(() => {
255-
resolve({ items: updatedData, totalRecordCount: countTotalItems, query });
264+
let countPropName = 'totalRecordCount';
265+
if (this.isCountEnabled) {
266+
countPropName = (this.odataVersion === 4) ? '@odata.count' : 'odata.count';
267+
}
268+
const backendResult = { items: updatedData, [countPropName]: countTotalItems, query };
269+
console.log('Backend Result', backendResult);
270+
resolve(backendResult);
256271
}, 250);
257272
});
258273
});
@@ -263,12 +278,25 @@ export class GridOdataComponent implements OnInit {
263278
console.log('Client sample, Grid State changed:: ', gridStateChanges);
264279
}
265280

266-
// THIS IS ONLY FOR DEMO PURPOSES DO NOT USE THIS CODE
281+
// THE FOLLOWING METHODS ARE ONLY FOR DEMO PURPOSES DO NOT USE THIS CODE
282+
// ---
283+
284+
changeCountEnableFlag() {
285+
this.isCountEnabled = !this.isCountEnabled;
286+
const odataService = this.gridOptions.backendServiceApi.service;
287+
288+
// @ts-ignore
289+
odataService.updateOptions({ enableCount: this.isCountEnabled } as OdataOption);
290+
odataService.clearFilters();
291+
this.angularGrid.filterService.clearFilters();
292+
return true;
293+
}
294+
267295
setOdataVersion(version: number) {
268296
this.odataVersion = version;
269297
const odataService = this.gridOptions.backendServiceApi.service;
270298
// @ts-ignore
271-
odataService.updateOptions({ version: this.odataVersion });
299+
odataService.updateOptions({ version: this.odataVersion } as OdataOption);
272300
odataService.clearFilters();
273301
this.angularGrid.filterService.clearFilters();
274302
return true;

src/app/modules/angular-slickgrid/models/odataOption.interface.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@ export interface OdataOption extends BackendServiceOption {
55
/** What is the casing type to use? Typically that would be 1 of the following 2: camelCase or PascalCase */
66
caseType?: CaseType;
77

8+
/** Add the total count $inlinecount (OData v2) or $count (OData v4) to the OData query */
9+
enableCount?: boolean;
10+
811
/** How many rows to pull? */
912
top?: number;
1013

0 commit comments

Comments
 (0)