@ngutil/data 0.0.38 → 0.0.40
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/esm2022/query/filter.mjs +73 -21
- package/esm2022/query/index.mjs +2 -2
- package/esm2022/source/proxy.directive.mjs +5 -3
- package/esm2022/source/source.mjs +6 -5
- package/fesm2022/ngutil-data.mjs +81 -26
- package/fesm2022/ngutil-data.mjs.map +1 -1
- package/package.json +3 -3
- package/query/filter.d.ts +1 -0
- package/query/index.d.ts +1 -1
- package/source/proxy.directive.d.ts +3 -1
- package/source/source.d.ts +2 -1
package/fesm2022/ngutil-data.mjs
CHANGED
|
@@ -3,7 +3,7 @@ import { Directive, Input, inject, input, NgModule } from '@angular/core';
|
|
|
3
3
|
import { DataSource as DataSource$1 } from '@angular/cdk/collections';
|
|
4
4
|
import { takeUntilDestroyed, toObservable } from '@angular/core/rxjs-interop';
|
|
5
5
|
import { BehaviorSubject, Observable, combineLatest, map, shareReplay, take, of, ReplaySubject, switchMap, distinctUntilChanged, tap, debounceTime, finalize, Subject, takeUntil, throwError } from 'rxjs';
|
|
6
|
-
import { deepClone, deepFreeze, isPlainObject, toSorted, Busy } from '@ngutil/common';
|
|
6
|
+
import { deepClone, deepFreeze, isPlainObject, isTruthy, isFalsy, toSorted, Busy } from '@ngutil/common';
|
|
7
7
|
import { flattenDepth, isEqual, intersection, flattenDeep } from 'lodash';
|
|
8
8
|
|
|
9
9
|
function pathGetterCompile(path) {
|
|
@@ -165,6 +165,14 @@ function filterNormalize(filters) {
|
|
|
165
165
|
return _normalizeFilter(filters);
|
|
166
166
|
}
|
|
167
167
|
function _normalizeFilter(filters, parent) {
|
|
168
|
+
if ("op" in filters && "value" in filters) {
|
|
169
|
+
if (filters["op"] === "|" /* FilterOp.Or */ || filters["op"] === "&" /* FilterOp.And */) {
|
|
170
|
+
return { op: filters["op"], value: filters["value"].map((v) => _normalizeFilter(v, parent)) };
|
|
171
|
+
}
|
|
172
|
+
if ("path" in filters) {
|
|
173
|
+
return filters;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
168
176
|
const norm = flattenDeep(Object.entries(filters).map(([path, value]) => {
|
|
169
177
|
switch (path) {
|
|
170
178
|
case "&" /* FilterOp.And */:
|
|
@@ -328,25 +336,10 @@ function or_(fns) {
|
|
|
328
336
|
};
|
|
329
337
|
}
|
|
330
338
|
function filterMerge(...filters) {
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
}
|
|
336
|
-
if (result == null) {
|
|
337
|
-
result = deepClone(filter);
|
|
338
|
-
}
|
|
339
|
-
else {
|
|
340
|
-
for (const [k, v] of Object.entries(filter)) {
|
|
341
|
-
if (v === undefined) {
|
|
342
|
-
delete result[k];
|
|
343
|
-
continue;
|
|
344
|
-
}
|
|
345
|
-
result[k] = deepClone(v);
|
|
346
|
-
}
|
|
347
|
-
}
|
|
348
|
-
}
|
|
349
|
-
return result;
|
|
339
|
+
const value = filters
|
|
340
|
+
.filter(v => v && ((Array.isArray(v) && v.length > 0) || (isPlainObject(v) && Object.keys(v).length > 0)))
|
|
341
|
+
.map(filter => deepClone(filter));
|
|
342
|
+
return compact({ op: "&" /* FilterOp.And */, value });
|
|
350
343
|
}
|
|
351
344
|
class FilterProperty extends QueryProperty {
|
|
352
345
|
merge(a, b) {
|
|
@@ -364,6 +357,65 @@ class FilterPropertySet extends QueryPropertySet {
|
|
|
364
357
|
return filterMerge(...args);
|
|
365
358
|
}
|
|
366
359
|
}
|
|
360
|
+
function filterSimplify(filters) {
|
|
361
|
+
if (isTruthy(filters)) {
|
|
362
|
+
filters = compact(filterNormalize(filters));
|
|
363
|
+
const result = {};
|
|
364
|
+
if (filters["op"] === "&" /* FilterOp.And */) {
|
|
365
|
+
filters = filters["value"];
|
|
366
|
+
if (filters == null) {
|
|
367
|
+
return result;
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
if (!Array.isArray(filters)) {
|
|
371
|
+
filters = [filters];
|
|
372
|
+
}
|
|
373
|
+
for (const f of filters) {
|
|
374
|
+
if (f["value"] != null &&
|
|
375
|
+
(f["op"] === "==" /* FilterOp.Eq */ || f["op"] === "===" /* FilterOp.EqStrict */ || f["op"] === "==*" /* FilterOp.EqInsesitive */)) {
|
|
376
|
+
result[f["path"]] = f["value"];
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
return result;
|
|
380
|
+
}
|
|
381
|
+
else {
|
|
382
|
+
return null;
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
function compact(filters) {
|
|
386
|
+
if (filters.op === "&" /* FilterOp.And */ || filters.op === "|" /* FilterOp.Or */) {
|
|
387
|
+
if (isFalsy(filters.value)) {
|
|
388
|
+
return null;
|
|
389
|
+
}
|
|
390
|
+
let value = filters.value.map(compact).filter(isTruthy);
|
|
391
|
+
if (value.length === 0) {
|
|
392
|
+
return null;
|
|
393
|
+
}
|
|
394
|
+
// remove subfilters with the same operator
|
|
395
|
+
value = value.reduce((acc, value) => {
|
|
396
|
+
if (value.op === filters.op) {
|
|
397
|
+
return acc.concat(value.value);
|
|
398
|
+
}
|
|
399
|
+
else {
|
|
400
|
+
acc.push(value);
|
|
401
|
+
return acc;
|
|
402
|
+
}
|
|
403
|
+
}, []);
|
|
404
|
+
// deduplicate, and latest filter is the most priority
|
|
405
|
+
value = value
|
|
406
|
+
.reverse()
|
|
407
|
+
.filter((v, i, a) => a.findIndex(v2 => v.path === v2.path && v.op === v2.op) === i)
|
|
408
|
+
.reverse();
|
|
409
|
+
if (value.length === 1) {
|
|
410
|
+
return value[0];
|
|
411
|
+
}
|
|
412
|
+
return { op: filters.op, value };
|
|
413
|
+
}
|
|
414
|
+
else if (filters.value == null) {
|
|
415
|
+
return null;
|
|
416
|
+
}
|
|
417
|
+
return filters;
|
|
418
|
+
}
|
|
367
419
|
|
|
368
420
|
function groupBy(grouper) {
|
|
369
421
|
return grouperCompile(grouper);
|
|
@@ -920,7 +972,7 @@ class DataSource extends DataSource$1 {
|
|
|
920
972
|
this.provider = provider;
|
|
921
973
|
this.store = store;
|
|
922
974
|
this.query$ = query$;
|
|
923
|
-
this.
|
|
975
|
+
this.isBusy$ = new BehaviorSubject(false);
|
|
924
976
|
this.total$ = new BehaviorSubject(undefined);
|
|
925
977
|
this.#slice = new ReplaySubject(1);
|
|
926
978
|
this.slice$ = this.#slice.pipe(switchMap(slice => this.provider.clampSlice(slice)), distinctUntilChanged(isEqual), map(slice => deepFreeze(deepClone(slice))), shareReplay(1));
|
|
@@ -949,6 +1001,7 @@ class DataSource extends DataSource$1 {
|
|
|
949
1001
|
}), take(1));
|
|
950
1002
|
}
|
|
951
1003
|
}))), finalize(() => this.#setBusy(false)), shareReplay(1));
|
|
1004
|
+
this.isEmpty$ = combineLatest({ busy: this.isBusy$, items: this.items$ }).pipe(map(({ busy, items }) => !busy && items?.some(isTruthy)), shareReplay(1));
|
|
952
1005
|
this.#cvSubs = new Map();
|
|
953
1006
|
}
|
|
954
1007
|
setSlice(slice) {
|
|
@@ -984,8 +1037,8 @@ class DataSource extends DataSource$1 {
|
|
|
984
1037
|
}
|
|
985
1038
|
#setBusy(busy) {
|
|
986
1039
|
if (this.provider.isAsync) {
|
|
987
|
-
if (this.
|
|
988
|
-
this.
|
|
1040
|
+
if (this.isBusy$.value !== busy) {
|
|
1041
|
+
this.isBusy$.next(busy);
|
|
989
1042
|
}
|
|
990
1043
|
}
|
|
991
1044
|
}
|
|
@@ -1064,6 +1117,8 @@ class DataSourceProxy extends DataSource$1 {
|
|
|
1064
1117
|
this.value$ = this.#value.pipe(takeUntilDestroyed());
|
|
1065
1118
|
this.query$ = this.value$.pipe(map(value => value.query$), shareReplay(1));
|
|
1066
1119
|
this.items$ = this.value$.pipe(switchMap(value => value.items$), shareReplay(1));
|
|
1120
|
+
this.isBusy$ = this.value$.pipe(switchMap(value => value.isBusy$), shareReplay(1));
|
|
1121
|
+
this.isEmpty$ = this.value$.pipe(switchMap(value => value.isEmpty$), shareReplay(1));
|
|
1067
1122
|
this.#cvSubs = new Map();
|
|
1068
1123
|
}
|
|
1069
1124
|
set value(value) {
|
|
@@ -1187,8 +1242,8 @@ class DataSourceProxyBusy {
|
|
|
1187
1242
|
constructor() {
|
|
1188
1243
|
this.#proxy = inject(DataSourceProxy);
|
|
1189
1244
|
this.#busy = inject(Busy);
|
|
1190
|
-
this.
|
|
1191
|
-
this.#busy.connect(this.
|
|
1245
|
+
this.isBusy$ = this.#proxy.value$.pipe(switchMap(value => value.isBusy$), shareReplay(1));
|
|
1246
|
+
this.#busy.connect(this.isBusy$).pipe(takeUntilDestroyed()).subscribe();
|
|
1192
1247
|
}
|
|
1193
1248
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.6", ngImport: i0, type: DataSourceProxyBusy, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
1194
1249
|
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.3.6", type: DataSourceProxyBusy, isStandalone: true, selector: "[nuDataSource][nuBusy]", ngImport: i0 }); }
|
|
@@ -1418,5 +1473,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.6", ngImpor
|
|
|
1418
1473
|
* Generated bundle index. Do not edit.
|
|
1419
1474
|
*/
|
|
1420
1475
|
|
|
1421
|
-
export { ArrayProvider, CollectionStore, DataProvider, DataSource, DataSourceModule, DataSourceProxy, DataSourceProxyBusy, DataSourceProxyFilter, DataSourceProxyGrouper, DataSourceProxySlimer, DataSourceProxySorter, LocalProvider, MemoryStore, ModelMeta, ModelRefByIndex, ModelRefByKey, ModelRefNorm, ObservableProvider, UnknownMeta, filterBy, filterMerge, filterNormalize, groupBy, grouperMerge, pathGetterCompile, queryExecutor, querySubject, sliceApply, sliceClamp, sliceEq, sliceInsert, sliceMerge, sliceToPages, slimBy, slimerMerge, sortBy, sorterMerge, sorterNormalize };
|
|
1476
|
+
export { ArrayProvider, CollectionStore, DataProvider, DataSource, DataSourceModule, DataSourceProxy, DataSourceProxyBusy, DataSourceProxyFilter, DataSourceProxyGrouper, DataSourceProxySlimer, DataSourceProxySorter, LocalProvider, MemoryStore, ModelMeta, ModelRefByIndex, ModelRefByKey, ModelRefNorm, ObservableProvider, UnknownMeta, filterBy, filterMerge, filterNormalize, filterSimplify, groupBy, grouperMerge, pathGetterCompile, queryExecutor, querySubject, sliceApply, sliceClamp, sliceEq, sliceInsert, sliceMerge, sliceToPages, slimBy, slimerMerge, sortBy, sorterMerge, sorterNormalize };
|
|
1422
1477
|
//# sourceMappingURL=ngutil-data.mjs.map
|