@onehat/data 1.4.5 → 1.4.9
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/cypress/integration/Repository/Repository.spec.js +80 -23
- package/package.json +1 -1
- package/src/Integration/ReactNative/Repository/AsyncStorage.js +29 -3
- package/src/Integration/ReactNative/Repository/SecureStore.js +97 -92
- package/src/Repository/Ajax.js +4 -4
- package/src/Repository/Offline.js +9 -7
- package/src/Repository/Repository.js +46 -5
|
@@ -372,6 +372,19 @@ describe('Repository Base', function() {
|
|
|
372
372
|
expect(didFireChangeFilters).to.be.true;
|
|
373
373
|
});
|
|
374
374
|
|
|
375
|
+
it('changing filters resets pagination', function() {
|
|
376
|
+
this.repository.isPaginated = true;
|
|
377
|
+
this.repository.setPageSize(1);
|
|
378
|
+
this.repository.setPage(3);
|
|
379
|
+
|
|
380
|
+
this.repository.setFilters({
|
|
381
|
+
b: '1',
|
|
382
|
+
c: '2',
|
|
383
|
+
});
|
|
384
|
+
|
|
385
|
+
expect(this.repository.page).to.be.eq(1);
|
|
386
|
+
});
|
|
387
|
+
|
|
375
388
|
});
|
|
376
389
|
|
|
377
390
|
describe('pagination', function() {
|
|
@@ -414,29 +427,73 @@ describe('Repository Base', function() {
|
|
|
414
427
|
});
|
|
415
428
|
|
|
416
429
|
it('_calculatePaginationVars', function() {
|
|
417
|
-
let results
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
results
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
expect(
|
|
430
|
+
let results;
|
|
431
|
+
|
|
432
|
+
results = this.Repository._calculatePaginationVars(0, 1, 10);
|
|
433
|
+
expect(results.page).to.be.eq(1);
|
|
434
|
+
expect(results.pageSize).to.be.eq(10);
|
|
435
|
+
expect(results.total).to.be.eq(0);
|
|
436
|
+
expect(results.totalPages).to.be.eq(1);
|
|
437
|
+
expect(results.pageStart).to.be.eq(0);
|
|
438
|
+
expect(results.pageEnd).to.be.eq(0);
|
|
439
|
+
expect(results.pageTotal).to.be.eq(0);
|
|
440
|
+
|
|
441
|
+
results = this.Repository._calculatePaginationVars(15, 1, 10);
|
|
442
|
+
expect(results.page).to.be.eq(1);
|
|
443
|
+
expect(results.pageSize).to.be.eq(10);
|
|
444
|
+
expect(results.total).to.be.eq(15);
|
|
445
|
+
expect(results.totalPages).to.be.eq(2);
|
|
446
|
+
expect(results.pageStart).to.be.eq(1);
|
|
447
|
+
expect(results.pageEnd).to.be.eq(10);
|
|
448
|
+
expect(results.pageTotal).to.be.eq(10);
|
|
449
|
+
|
|
450
|
+
results = this.Repository._calculatePaginationVars(15, 2, 10);
|
|
451
|
+
expect(results.page).to.be.eq(2);
|
|
452
|
+
expect(results.pageSize).to.be.eq(10);
|
|
453
|
+
expect(results.total).to.be.eq(15);
|
|
454
|
+
expect(results.totalPages).to.be.eq(2);
|
|
455
|
+
expect(results.pageStart).to.be.eq(11);
|
|
456
|
+
expect(results.pageEnd).to.be.eq(15);
|
|
457
|
+
expect(results.pageTotal).to.be.eq(5);
|
|
458
|
+
|
|
459
|
+
results = this.Repository._calculatePaginationVars(15, 2, 5);
|
|
460
|
+
expect(results.page).to.be.eq(2);
|
|
461
|
+
expect(results.pageSize).to.be.eq(5);
|
|
462
|
+
expect(results.total).to.be.eq(15);
|
|
463
|
+
expect(results.totalPages).to.be.eq(3);
|
|
464
|
+
expect(results.pageStart).to.be.eq(6);
|
|
465
|
+
expect(results.pageEnd).to.be.eq(10);
|
|
466
|
+
expect(results.pageTotal).to.be.eq(5);
|
|
467
|
+
|
|
468
|
+
results = this.Repository._calculatePaginationVars(7, 2, 5);
|
|
469
|
+
expect(results.page).to.be.eq(2);
|
|
470
|
+
expect(results.pageSize).to.be.eq(5);
|
|
471
|
+
expect(results.total).to.be.eq(7);
|
|
472
|
+
expect(results.totalPages).to.be.eq(2);
|
|
473
|
+
expect(results.pageStart).to.be.eq(6);
|
|
474
|
+
expect(results.pageEnd).to.be.eq(7);
|
|
475
|
+
expect(results.pageTotal).to.be.eq(2);
|
|
476
|
+
|
|
477
|
+
results = this.Repository._calculatePaginationVars(15, 15, 1);
|
|
478
|
+
expect(results.page).to.be.eq(15);
|
|
479
|
+
expect(results.pageSize).to.be.eq(1);
|
|
480
|
+
expect(results.total).to.be.eq(15);
|
|
481
|
+
expect(results.totalPages).to.be.eq(15);
|
|
482
|
+
expect(results.pageStart).to.be.eq(15);
|
|
483
|
+
expect(results.pageEnd).to.be.eq(15);
|
|
484
|
+
expect(results.pageTotal).to.be.eq(1);
|
|
485
|
+
});
|
|
486
|
+
|
|
487
|
+
it('reset pagination', function() {
|
|
488
|
+
expect(this.repository.page).to.be.eq(1);
|
|
489
|
+
|
|
490
|
+
this.repository.isPaginated = true;
|
|
491
|
+
this.repository.setPageSize(1);
|
|
492
|
+
this.repository.setPage(3);
|
|
493
|
+
expect(this.repository.page).to.be.eq(3);
|
|
494
|
+
|
|
495
|
+
this.repository.resetPagination();
|
|
496
|
+
expect(this.repository.page).to.be.eq(1);
|
|
440
497
|
});
|
|
441
498
|
|
|
442
499
|
});
|
package/package.json
CHANGED
|
@@ -1,7 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This file is categorized as "Proprietary Framework Code"
|
|
3
|
+
* and is subject to the terms and conditions defined in
|
|
4
|
+
* file 'LICENSE.txt', which is part of this source code package.
|
|
5
|
+
*/
|
|
1
6
|
/** @module Repository */
|
|
2
7
|
|
|
3
8
|
import OfflineRepository from '@onehat/data/src/Repository/Offline.js';
|
|
4
|
-
import AsyncStorage from '@react-native-
|
|
9
|
+
import AsyncStorage from '@react-native-async-storage/async-storage';
|
|
5
10
|
import _ from 'lodash';
|
|
6
11
|
|
|
7
12
|
/**
|
|
@@ -37,10 +42,12 @@ class AsyncStorageRepository extends OfflineRepository {
|
|
|
37
42
|
value = result; // Invalid JSON, just return raw result
|
|
38
43
|
}
|
|
39
44
|
}
|
|
45
|
+
|
|
40
46
|
return value;
|
|
41
47
|
} catch (error) {
|
|
42
48
|
if (this.debugMode) {
|
|
43
49
|
const msg = error && error.message;
|
|
50
|
+
console.log('_storageGetValue error', msg);
|
|
44
51
|
debugger;
|
|
45
52
|
}
|
|
46
53
|
}
|
|
@@ -60,7 +67,7 @@ class AsyncStorageRepository extends OfflineRepository {
|
|
|
60
67
|
const results = await AsyncStorage.multiGet(this._namespace(keys));
|
|
61
68
|
|
|
62
69
|
if (this.debugMode) {
|
|
63
|
-
console.log(this.name, 'AsyncStorage.multiGet results',
|
|
70
|
+
console.log(this.name, 'AsyncStorage.multiGet results', results);
|
|
64
71
|
}
|
|
65
72
|
|
|
66
73
|
let values = [];
|
|
@@ -72,7 +79,17 @@ class AsyncStorageRepository extends OfflineRepository {
|
|
|
72
79
|
} catch (e) {
|
|
73
80
|
parsed = value; // Invalid JSON, just return raw result
|
|
74
81
|
}
|
|
75
|
-
|
|
82
|
+
if (parsed === null) {
|
|
83
|
+
// Values should be stored as JSON, so it should be either {} or []. If it's null, that means the AsyncStorage can't find the record
|
|
84
|
+
// Delete the index to this record
|
|
85
|
+
const re = new RegExp('^' + this.name + '\-' + '(.*)'),
|
|
86
|
+
matches = key.match(re);
|
|
87
|
+
debugger;
|
|
88
|
+
const id = parseInt(matches, 10);
|
|
89
|
+
this._deleteFromIndex(id);
|
|
90
|
+
} else {
|
|
91
|
+
values.push(parsed);
|
|
92
|
+
}
|
|
76
93
|
})
|
|
77
94
|
}
|
|
78
95
|
|
|
@@ -84,6 +101,7 @@ class AsyncStorageRepository extends OfflineRepository {
|
|
|
84
101
|
} catch (error) {
|
|
85
102
|
if (this.debugMode) {
|
|
86
103
|
const msg = error && error.message;
|
|
104
|
+
console.log('_storageGetMultiple error', msg);
|
|
87
105
|
debugger;
|
|
88
106
|
}
|
|
89
107
|
}
|
|
@@ -103,6 +121,7 @@ class AsyncStorageRepository extends OfflineRepository {
|
|
|
103
121
|
} catch (error) {
|
|
104
122
|
if (this.debugMode) {
|
|
105
123
|
const msg = error && error.message;
|
|
124
|
+
console.log('_storageSetValue error', msg);
|
|
106
125
|
debugger;
|
|
107
126
|
}
|
|
108
127
|
}
|
|
@@ -126,11 +145,16 @@ class AsyncStorageRepository extends OfflineRepository {
|
|
|
126
145
|
console.log(this.name, 'AsyncStorage.multiSet', keys);
|
|
127
146
|
}
|
|
128
147
|
|
|
148
|
+
if (_.isEmpty(converted)) {
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
|
|
129
152
|
return await AsyncStorage.multiSet(converted);
|
|
130
153
|
|
|
131
154
|
} catch (error) {
|
|
132
155
|
if (this.debugMode) {
|
|
133
156
|
const msg = error && error.message;
|
|
157
|
+
console.log('_storageSetMultiple error', msg);
|
|
134
158
|
debugger;
|
|
135
159
|
}
|
|
136
160
|
}
|
|
@@ -151,6 +175,7 @@ class AsyncStorageRepository extends OfflineRepository {
|
|
|
151
175
|
} catch (error) {
|
|
152
176
|
if (this.debugMode) {
|
|
153
177
|
const msg = error && error.message;
|
|
178
|
+
console.log('_storageDeleteValue error', msg);
|
|
154
179
|
debugger;
|
|
155
180
|
}
|
|
156
181
|
}
|
|
@@ -171,6 +196,7 @@ class AsyncStorageRepository extends OfflineRepository {
|
|
|
171
196
|
} catch (error) {
|
|
172
197
|
if (this.debugMode) {
|
|
173
198
|
const msg = error && error.message;
|
|
199
|
+
console.log('_storageDeleteMultiple error', msg);
|
|
174
200
|
debugger;
|
|
175
201
|
}
|
|
176
202
|
}
|
|
@@ -1,94 +1,99 @@
|
|
|
1
|
-
import OfflineRepository from '@onehat/data/src/Repository/Offline';
|
|
2
|
-
import * as SecureStore from 'expo-secure-store'; // see: https://docs.expo.io/versions/latest/sdk/securestore/
|
|
3
|
-
import _ from 'lodash';
|
|
4
|
-
|
|
5
1
|
/**
|
|
6
|
-
*
|
|
7
|
-
*
|
|
2
|
+
* This file is categorized as "Proprietary Framework Code"
|
|
3
|
+
* and is subject to the terms and conditions defined in
|
|
4
|
+
* file 'LICENSE.txt', which is part of this source code package.
|
|
8
5
|
*/
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
6
|
+
import OfflineRepository from '@onehat/data/src/Repository/Offline.js';
|
|
7
|
+
import * as SecureStore from 'expo-secure-store'; // see: https://docs.expo.io/versions/latest/sdk/securestore/
|
|
8
|
+
import _ from 'lodash';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Repository representing Expo's SecureStore
|
|
12
|
+
* Uses expo-secure-store package
|
|
13
|
+
*/
|
|
14
|
+
class SecureStoreRepository extends OfflineRepository {
|
|
15
|
+
|
|
16
|
+
constructor(config = {}) {
|
|
17
|
+
super(...arguments);
|
|
18
|
+
_.merge(this, config);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
_storageGetValue = async (name) => {
|
|
22
|
+
try {
|
|
23
|
+
|
|
24
|
+
if (this.debugMode) {
|
|
25
|
+
console.log(this.name, 'SecureStore.get', name);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const result = await SecureStore.getItemAsync(this._namespace(name));
|
|
29
|
+
|
|
30
|
+
if (this.debugMode) {
|
|
31
|
+
console.log(this.name, 'SecureStore.get results', name, result);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
let value;
|
|
35
|
+
if (!_.isNil(result)) {
|
|
36
|
+
try {
|
|
37
|
+
value = JSON.parse(result);
|
|
38
|
+
} catch (e) {
|
|
39
|
+
value = result; // Invalid JSON, just return raw result
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
return value;
|
|
43
|
+
} catch (error) {
|
|
44
|
+
if (this.debugMode) {
|
|
45
|
+
const msg = error && error.message;
|
|
46
|
+
debugger;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
_storageSetValue = async (name, value) => {
|
|
52
|
+
try {
|
|
53
|
+
if (!_.isString(value)) {
|
|
54
|
+
value = JSON.stringify(value);
|
|
55
|
+
}
|
|
56
|
+
if (this.debugMode) {
|
|
57
|
+
console.log(this.name, 'SecureStore.set', name, value);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const result = await SecureStore.setItemAsync(this._namespace(name), value);
|
|
61
|
+
|
|
62
|
+
// if (this.debugMode) {
|
|
63
|
+
// console.log(this.name, 'SecureStore.set results', name, result);
|
|
64
|
+
// }
|
|
65
|
+
return result;
|
|
66
|
+
} catch (error) {
|
|
67
|
+
if (this.debugMode) {
|
|
68
|
+
const msg = error && error.message;
|
|
69
|
+
debugger;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
_storageDeleteValue = async (name) => {
|
|
75
|
+
try {
|
|
76
|
+
if (this.debugMode) {
|
|
77
|
+
console.log(this.name, 'SecureStore.delete', name);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
const result = await SecureStore.deleteItemAsync(this._namespace(name));
|
|
81
|
+
|
|
82
|
+
// if (this.debugMode) {
|
|
83
|
+
// console.log(this.name, 'SecureStore.delete results', name, result);
|
|
84
|
+
// }
|
|
85
|
+
return result;
|
|
86
|
+
} catch (error) {
|
|
87
|
+
if (this.debugMode) {
|
|
88
|
+
const msg = error && error.message;
|
|
89
|
+
debugger;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
SecureStoreRepository.className = 'SecureStore';
|
|
97
|
+
SecureStoreRepository.type = 'secure';
|
|
98
|
+
|
|
99
|
+
export default SecureStoreRepository;
|
package/src/Repository/Ajax.js
CHANGED
|
@@ -292,8 +292,8 @@ class AjaxRepository extends Repository {
|
|
|
292
292
|
*/
|
|
293
293
|
_onChangeSorters = () => {
|
|
294
294
|
const sorter = this.sorters[0];
|
|
295
|
-
this.setParam(this.paramSort, sorter.name);
|
|
296
|
-
this.setParam(this.paramDirection, sorter.direction);
|
|
295
|
+
this.setParam(this.paramSort, sorter.name, true); // true to set baseParam
|
|
296
|
+
this.setParam(this.paramDirection, sorter.direction, true);
|
|
297
297
|
|
|
298
298
|
if (this.isLoaded) {
|
|
299
299
|
return this.reload();
|
|
@@ -319,8 +319,8 @@ class AjaxRepository extends Repository {
|
|
|
319
319
|
* Refreshes entities.
|
|
320
320
|
*/
|
|
321
321
|
_onChangePagination = () => {
|
|
322
|
-
this.setParam(this.paramPageNum, this.page);
|
|
323
|
-
this.setParam(this.paramPageSize, this.pageSize);
|
|
322
|
+
this.setParam(this.paramPageNum, this.page, true); // true to set baseParam
|
|
323
|
+
this.setParam(this.paramPageSize, this.pageSize, true);
|
|
324
324
|
|
|
325
325
|
if (this.isLoaded) {
|
|
326
326
|
return this.reload();
|
|
@@ -23,13 +23,8 @@ class OfflineRepository extends MemoryRepository {
|
|
|
23
23
|
|
|
24
24
|
async initialize() {
|
|
25
25
|
this.pauseEvents(); // Queue 'initialize' event from super
|
|
26
|
-
await super.initialize();
|
|
27
26
|
|
|
28
|
-
|
|
29
|
-
if (!this._index) {
|
|
30
|
-
await this._setIndex([]);
|
|
31
|
-
this._index = [];
|
|
32
|
-
}
|
|
27
|
+
await super.initialize(); // Initializes index in _loadFromStorage()
|
|
33
28
|
|
|
34
29
|
this.resumeEvents(true); // Now fire it!
|
|
35
30
|
}
|
|
@@ -80,7 +75,14 @@ class OfflineRepository extends MemoryRepository {
|
|
|
80
75
|
*/
|
|
81
76
|
_loadFromStorage = async () => {
|
|
82
77
|
try {
|
|
83
|
-
|
|
78
|
+
|
|
79
|
+
this._index = await this._getIndex();
|
|
80
|
+
if (!this._index) {
|
|
81
|
+
await this._setIndex([]);
|
|
82
|
+
this._index = [];
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
const ids = this._index,
|
|
84
86
|
total = ids && ids.length ? ids.length : 0,
|
|
85
87
|
results = [];
|
|
86
88
|
|
|
@@ -648,6 +648,7 @@ export default class Repository extends EventEmitter {
|
|
|
648
648
|
if (!_.isEqual(this.filters, filters)) {
|
|
649
649
|
isChanged = true;
|
|
650
650
|
this.filters = filters;
|
|
651
|
+
this.resetPagination();
|
|
651
652
|
this.emit('changeFilters');
|
|
652
653
|
if (this._onChangeFilters) {
|
|
653
654
|
return this._onChangeFilters();
|
|
@@ -666,6 +667,17 @@ export default class Repository extends EventEmitter {
|
|
|
666
667
|
// /_/ \__,_/\__, /_/_/ /_/\__,_/\__/\___/
|
|
667
668
|
// /____/
|
|
668
669
|
|
|
670
|
+
/**
|
|
671
|
+
* Resets the pagination to page one
|
|
672
|
+
* @fires changePageSize
|
|
673
|
+
*/
|
|
674
|
+
resetPagination = (pageSize) => {
|
|
675
|
+
if (this.isDestroyed) {
|
|
676
|
+
throw Error('this.resetPagination is no longer valid. Repository has been destroyed.');
|
|
677
|
+
}
|
|
678
|
+
this.setPage(1);
|
|
679
|
+
}
|
|
680
|
+
|
|
669
681
|
/**
|
|
670
682
|
* Sets the pageSize
|
|
671
683
|
* @fires changePageSize
|
|
@@ -779,12 +791,38 @@ export default class Repository extends EventEmitter {
|
|
|
779
791
|
* @static
|
|
780
792
|
*/
|
|
781
793
|
static _calculatePaginationVars = (total, page, pageSize) => {
|
|
794
|
+
|
|
795
|
+
// Special case: empty pages
|
|
796
|
+
if (total < 1) {
|
|
797
|
+
return {
|
|
798
|
+
page,
|
|
799
|
+
pageSize,
|
|
800
|
+
total,
|
|
801
|
+
totalPages: 1,
|
|
802
|
+
pageStart: 0,
|
|
803
|
+
pageEnd: 0,
|
|
804
|
+
pageTotal: 0,
|
|
805
|
+
};
|
|
806
|
+
}
|
|
807
|
+
|
|
782
808
|
const totalPages = Math.ceil(total / pageSize),
|
|
783
|
-
pageStart =
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
809
|
+
pageStart = ((page -1) * pageSize) + 1;
|
|
810
|
+
|
|
811
|
+
let remainder,
|
|
812
|
+
pageEnd,
|
|
813
|
+
pageTotal;
|
|
814
|
+
|
|
815
|
+
if (page === 1 && totalPages === 1) {
|
|
816
|
+
pageTotal = total;
|
|
817
|
+
} else if (page < totalPages) {
|
|
818
|
+
pageTotal = pageSize;
|
|
819
|
+
} else {
|
|
820
|
+
// last page
|
|
821
|
+
remainder = total % pageSize;
|
|
822
|
+
pageTotal = remainder || pageSize;
|
|
823
|
+
}
|
|
824
|
+
|
|
825
|
+
pageEnd = pageStart + pageTotal -1;
|
|
788
826
|
|
|
789
827
|
return {
|
|
790
828
|
page,
|
|
@@ -1302,6 +1340,9 @@ export default class Repository extends EventEmitter {
|
|
|
1302
1340
|
if (!_.isArray(entities)) {
|
|
1303
1341
|
entities = [entities];
|
|
1304
1342
|
}
|
|
1343
|
+
if (!entities.length) {
|
|
1344
|
+
return;
|
|
1345
|
+
}
|
|
1305
1346
|
_.each(entities, (entity) => {
|
|
1306
1347
|
entity.markDeleted(); // Entity is still there, it's just marked for deletion
|
|
1307
1348
|
});
|