@zeedhi/teknisa-components-common 1.106.0 → 1.107.1
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/coverage/clover.xml +641 -550
- package/coverage/coverage-final.json +12 -10
- package/coverage/lcov-report/index.html +20 -20
- package/coverage/lcov-report/tests/__helpers__/component-event-helper.ts.html +1 -1
- package/coverage/lcov-report/tests/__helpers__/flush-promises-helper.ts.html +2 -2
- package/coverage/lcov-report/tests/__helpers__/get-child-helper.ts.html +1 -1
- package/coverage/lcov-report/tests/__helpers__/index.html +1 -1
- package/coverage/lcov-report/tests/__helpers__/index.ts.html +1 -1
- package/coverage/lcov-report/tests/__helpers__/mock-created-helper.ts.html +1 -1
- package/coverage/lcov.info +1248 -1081
- package/dist/tek-components-common.esm.js +246 -29
- package/dist/tek-components-common.umd.js +245 -28
- package/package.json +2 -2
- package/tests/unit/components/tek-datasource/memory-datasource.spec.ts +10 -0
- package/tests/unit/components/tek-datasource/rest-datasource.spec.ts +5 -3
- package/tests/unit/components/tek-grid/grid-filter-button.spec.ts +4 -10
- package/tests/unit/components/tek-grid/grid.spec.ts +451 -3
- package/types/components/tek-datasource/memory-datasource.d.ts +7 -1
- package/types/components/tek-datasource/rest-datasource.d.ts +7 -1
- package/types/components/tek-grid/grid.d.ts +46 -3
- package/types/components/tek-grid/interfaces.d.ts +19 -0
- package/types/error/incomplete-groups-error.d.ts +8 -0
- package/types/utils/extract-properties.d.ts +7 -0
- package/types/utils/index.d.ts +1 -0
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
import {
|
|
4
4
|
Button, Dropdown, IModal, Modal, ModalService, Search, TextInput, Text, Report,
|
|
5
|
+
AlertService,
|
|
6
|
+
EmptyDataError,
|
|
5
7
|
} from '@zeedhi/common';
|
|
6
8
|
import {
|
|
7
9
|
KeyMap, Http, Metadata, IDictionary, IEventParam,
|
|
@@ -42,6 +44,43 @@ const createAndMount = (props: ITekGrid) => {
|
|
|
42
44
|
return instance;
|
|
43
45
|
};
|
|
44
46
|
|
|
47
|
+
const createGroupedGrid = async (props: Partial<ITekGrid> = {}) => {
|
|
48
|
+
const grid = createAndMount({
|
|
49
|
+
name: 'grid',
|
|
50
|
+
component: 'TekGrid',
|
|
51
|
+
columns: [
|
|
52
|
+
{ name: 'id' },
|
|
53
|
+
{ name: 'name' },
|
|
54
|
+
{ name: 'month' },
|
|
55
|
+
{ name: 'department', grouped: true },
|
|
56
|
+
],
|
|
57
|
+
datasource: {
|
|
58
|
+
uniqueKey: 'id',
|
|
59
|
+
data: [
|
|
60
|
+
{
|
|
61
|
+
id: '1', name: 'First', month: 11, department: 1,
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
id: '2', name: 'Second', month: 11, department: 1,
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
id: '3', name: 'Third', month: 11, department: 2,
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
id: '4', name: 'Fourth', month: 12, department: 1,
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
id: '5', name: 'Fifth', month: 12, department: 2,
|
|
74
|
+
},
|
|
75
|
+
],
|
|
76
|
+
},
|
|
77
|
+
...props,
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
await flushPromises();
|
|
81
|
+
return grid;
|
|
82
|
+
};
|
|
83
|
+
|
|
45
84
|
describe('TekGrid', () => {
|
|
46
85
|
beforeEach(() => {
|
|
47
86
|
// clear all metadata instances before testing
|
|
@@ -375,7 +414,7 @@ describe('TekGrid', () => {
|
|
|
375
414
|
|
|
376
415
|
const getReport = async () => { await instance.getReport('pdf'); };
|
|
377
416
|
|
|
378
|
-
expect(getReport).
|
|
417
|
+
expect(getReport).not.toThrow();
|
|
379
418
|
|
|
380
419
|
const getColumnSpy = jest.spyOn(instance, 'getColumn').mockImplementationOnce(() => {
|
|
381
420
|
throw Error();
|
|
@@ -414,6 +453,37 @@ describe('TekGrid', () => {
|
|
|
414
453
|
},
|
|
415
454
|
}, undefined);
|
|
416
455
|
});
|
|
456
|
+
|
|
457
|
+
it('when data is empty, should show alert', async () => {
|
|
458
|
+
reportSpy = jest.spyOn(Report.prototype, 'getReport').mockImplementation(() => { throw new EmptyDataError(); });
|
|
459
|
+
const alertSpy = jest.spyOn(AlertService, 'show').mockImplementation(() => 1);
|
|
460
|
+
|
|
461
|
+
const instance = new TekGrid({
|
|
462
|
+
name: 'grid',
|
|
463
|
+
component: 'TekGrid',
|
|
464
|
+
datasource: {
|
|
465
|
+
data: [],
|
|
466
|
+
},
|
|
467
|
+
});
|
|
468
|
+
|
|
469
|
+
expect(async () => instance.getReport('xls2')).not.toThrow();
|
|
470
|
+
|
|
471
|
+
expect(alertSpy).toHaveBeenCalledWith({ name: 'no-data-warning', text: 'TEKGRID_NO_DATA', color: 'warning' });
|
|
472
|
+
});
|
|
473
|
+
|
|
474
|
+
it('when an error happens, should throw normally', async () => {
|
|
475
|
+
reportSpy = jest.spyOn(Report.prototype, 'getReport').mockImplementation(() => { throw new Error(); });
|
|
476
|
+
|
|
477
|
+
const instance = new TekGrid({
|
|
478
|
+
name: 'grid',
|
|
479
|
+
component: 'TekGrid',
|
|
480
|
+
datasource: {
|
|
481
|
+
data: [],
|
|
482
|
+
},
|
|
483
|
+
});
|
|
484
|
+
|
|
485
|
+
expect(async () => instance.getReport('xls2')).rejects.toThrow();
|
|
486
|
+
});
|
|
417
487
|
});
|
|
418
488
|
|
|
419
489
|
describe('saveChanges()', () => {
|
|
@@ -2080,6 +2150,19 @@ describe('TekGrid', () => {
|
|
|
2080
2150
|
|
|
2081
2151
|
expect(instance.datasource.page).toBe(1);
|
|
2082
2152
|
});
|
|
2153
|
+
|
|
2154
|
+
it('deve retornar true se a coluna tiver filtro simples com dados (datasource comum)', () => {
|
|
2155
|
+
const column = { name: 'categoria' } as TekGridColumn;
|
|
2156
|
+
const grid = new TekGrid({ name: 'grid2', component: 'TekGrid' }) as any;
|
|
2157
|
+
|
|
2158
|
+
grid.datasource = {
|
|
2159
|
+
filter: {
|
|
2160
|
+
categoria: ['A'],
|
|
2161
|
+
},
|
|
2162
|
+
};
|
|
2163
|
+
|
|
2164
|
+
expect(grid.columnHasFilterData(column)).toBe(true);
|
|
2165
|
+
});
|
|
2083
2166
|
});
|
|
2084
2167
|
|
|
2085
2168
|
describe('rowClick', () => {
|
|
@@ -2264,7 +2347,6 @@ describe('TekGrid', () => {
|
|
|
2264
2347
|
row: grid.groupedData[0],
|
|
2265
2348
|
component: grid,
|
|
2266
2349
|
});
|
|
2267
|
-
expect(grid.datasource.currentRow).toEqual({});
|
|
2268
2350
|
});
|
|
2269
2351
|
|
|
2270
2352
|
it('should not call events.groupRowClick if cellClick prevents it', async () => {
|
|
@@ -2339,7 +2421,6 @@ describe('TekGrid', () => {
|
|
|
2339
2421
|
row: grid.groupedData[0],
|
|
2340
2422
|
component: grid,
|
|
2341
2423
|
});
|
|
2342
|
-
expect(grid.datasource.currentRow).toEqual({});
|
|
2343
2424
|
});
|
|
2344
2425
|
|
|
2345
2426
|
it('should not call events.groupRowDoubleClick if cellDoubleClick prevents it', async () => {
|
|
@@ -2665,4 +2746,371 @@ describe('TekGrid', () => {
|
|
|
2665
2746
|
expect(spy).toHaveBeenCalledTimes(1);
|
|
2666
2747
|
});
|
|
2667
2748
|
});
|
|
2749
|
+
|
|
2750
|
+
describe('addNewRow', () => {
|
|
2751
|
+
it('when not using groups, should add a new row to the datasource', async () => {
|
|
2752
|
+
const instance = new TekGrid({
|
|
2753
|
+
name: 'Grid',
|
|
2754
|
+
component: 'TekGrid',
|
|
2755
|
+
datasource: {
|
|
2756
|
+
page: 1,
|
|
2757
|
+
data: [
|
|
2758
|
+
{ id: 1 },
|
|
2759
|
+
],
|
|
2760
|
+
},
|
|
2761
|
+
});
|
|
2762
|
+
const newRow1 = { id: 2 };
|
|
2763
|
+
await instance.addNewRow(newRow1, 'start');
|
|
2764
|
+
expect(instance.datasource.data[0]).toEqual({ id: 2, __added_row: true });
|
|
2765
|
+
expect(instance.datasource.data[1]).toEqual({ id: 1 });
|
|
2766
|
+
});
|
|
2767
|
+
|
|
2768
|
+
it('should add a new row to the groupedData array', async () => {
|
|
2769
|
+
const grid = await createGroupedGrid();
|
|
2770
|
+
|
|
2771
|
+
expect(grid.groupedData).toMatchObject([
|
|
2772
|
+
{ groupValue: 1 },
|
|
2773
|
+
{ id: '1', groupHeaders: [{ groupValue: 1 }] },
|
|
2774
|
+
{ id: '2', groupHeaders: [{ groupValue: 1 }] },
|
|
2775
|
+
{ id: '4', groupHeaders: [{ groupValue: 1 }] },
|
|
2776
|
+
{ groupValue: 2 },
|
|
2777
|
+
{ id: '3', groupHeaders: [{ groupValue: 2 }] },
|
|
2778
|
+
{ id: '5', groupHeaders: [{ groupValue: 2 }] },
|
|
2779
|
+
]);
|
|
2780
|
+
expect(grid.groupedData[0].children).toMatchObject([
|
|
2781
|
+
{ id: '1' },
|
|
2782
|
+
{ id: '2' },
|
|
2783
|
+
{ id: '4' },
|
|
2784
|
+
]);
|
|
2785
|
+
|
|
2786
|
+
await grid.addNewRow({ id: '999', name: 'new', department: 1 });
|
|
2787
|
+
|
|
2788
|
+
expect(grid.groupedData).toMatchObject([
|
|
2789
|
+
{ groupValue: 1 },
|
|
2790
|
+
{ id: '1', groupHeaders: [{ groupValue: 1 }] },
|
|
2791
|
+
{ id: '2', groupHeaders: [{ groupValue: 1 }] },
|
|
2792
|
+
{ id: '4', groupHeaders: [{ groupValue: 1 }] },
|
|
2793
|
+
{ id: '999', groupHeaders: [{ groupValue: 1 }] },
|
|
2794
|
+
{ groupValue: 2 },
|
|
2795
|
+
{ id: '3', groupHeaders: [{ groupValue: 2 }] },
|
|
2796
|
+
{ id: '5', groupHeaders: [{ groupValue: 2 }] },
|
|
2797
|
+
]);
|
|
2798
|
+
expect(grid.groupedData[0].children).toMatchObject([
|
|
2799
|
+
{ id: '1' },
|
|
2800
|
+
{ id: '2' },
|
|
2801
|
+
{ id: '4' },
|
|
2802
|
+
{ id: '999' },
|
|
2803
|
+
]);
|
|
2804
|
+
});
|
|
2805
|
+
|
|
2806
|
+
it('should add a new row to the groupedData array using nested groups', async () => {
|
|
2807
|
+
const grid = await createGroupedGrid({
|
|
2808
|
+
columns: [
|
|
2809
|
+
{ name: 'id' },
|
|
2810
|
+
{ name: 'name' },
|
|
2811
|
+
{ name: 'month', grouped: true },
|
|
2812
|
+
{ name: 'department', grouped: true },
|
|
2813
|
+
],
|
|
2814
|
+
});
|
|
2815
|
+
|
|
2816
|
+
expect(grid.groupedData).toMatchObject([
|
|
2817
|
+
{ groupValue: 11 },
|
|
2818
|
+
{ groupValue: 1, groupHeaders: [{ groupValue: 11 }] },
|
|
2819
|
+
{ id: '1', groupHeaders: [{ groupValue: 11 }, { groupValue: 1 }] },
|
|
2820
|
+
{ id: '2', groupHeaders: [{ groupValue: 11 }, { groupValue: 1 }] },
|
|
2821
|
+
{ groupValue: 2, groupHeaders: [{ groupValue: 11 }] },
|
|
2822
|
+
{ id: '3', groupHeaders: [{ groupValue: 11 }, { groupValue: 2 }] },
|
|
2823
|
+
{ groupValue: 12 },
|
|
2824
|
+
{ groupValue: 1, groupHeaders: [{ groupValue: 12 }] },
|
|
2825
|
+
{ id: '4', groupHeaders: [{ groupValue: 12 }, { groupValue: 1 }] },
|
|
2826
|
+
{ groupValue: 2, groupHeaders: [{ groupValue: 12 }] },
|
|
2827
|
+
{ id: '5', groupHeaders: [{ groupValue: 12 }, { groupValue: 2 }] },
|
|
2828
|
+
]);
|
|
2829
|
+
|
|
2830
|
+
await grid.addNewRow({
|
|
2831
|
+
id: '999', name: 'new', month: 12, department: 1,
|
|
2832
|
+
}, 'start');
|
|
2833
|
+
|
|
2834
|
+
expect(grid.groupedData).toMatchObject([
|
|
2835
|
+
{ groupValue: 11 },
|
|
2836
|
+
{ groupValue: 1, groupHeaders: [{ groupValue: 11 }] },
|
|
2837
|
+
{ id: '1', groupHeaders: [{ groupValue: 11 }, { groupValue: 1 }] },
|
|
2838
|
+
{ id: '2', groupHeaders: [{ groupValue: 11 }, { groupValue: 1 }] },
|
|
2839
|
+
{ groupValue: 2, groupHeaders: [{ groupValue: 11 }] },
|
|
2840
|
+
{ id: '3', groupHeaders: [{ groupValue: 11 }, { groupValue: 2 }] },
|
|
2841
|
+
{ groupValue: 12 },
|
|
2842
|
+
{ groupValue: 1, groupHeaders: [{ groupValue: 12 }] },
|
|
2843
|
+
{ id: '999', groupHeaders: [{ groupValue: 12 }, { groupValue: 1 }] },
|
|
2844
|
+
{ id: '4', groupHeaders: [{ groupValue: 12 }, { groupValue: 1 }] },
|
|
2845
|
+
{ groupValue: 2, groupHeaders: [{ groupValue: 12 }] },
|
|
2846
|
+
{ id: '5', groupHeaders: [{ groupValue: 12 }, { groupValue: 2 }] },
|
|
2847
|
+
]);
|
|
2848
|
+
|
|
2849
|
+
expect(grid.groupedData[6].children).toMatchObject([
|
|
2850
|
+
{ id: '999' },
|
|
2851
|
+
{ id: '4' },
|
|
2852
|
+
{ id: '5' },
|
|
2853
|
+
]);
|
|
2854
|
+
expect(grid.groupedData[7].children).toMatchObject([
|
|
2855
|
+
{ id: '999' },
|
|
2856
|
+
{ id: '4' },
|
|
2857
|
+
]);
|
|
2858
|
+
});
|
|
2859
|
+
|
|
2860
|
+
it('should add a new row to a group that doesnt exist', async () => {
|
|
2861
|
+
const grid = await createGroupedGrid();
|
|
2862
|
+
|
|
2863
|
+
await grid.addNewRow({ id: '999', name: 'new', department: 999 }, 'end');
|
|
2864
|
+
|
|
2865
|
+
expect(grid.groupedData).toMatchObject([
|
|
2866
|
+
{ groupValue: 1 },
|
|
2867
|
+
{ id: '1', groupHeaders: [{ groupValue: 1 }] },
|
|
2868
|
+
{ id: '2', groupHeaders: [{ groupValue: 1 }] },
|
|
2869
|
+
{ id: '4', groupHeaders: [{ groupValue: 1 }] },
|
|
2870
|
+
{ groupValue: 2 },
|
|
2871
|
+
{ id: '3', groupHeaders: [{ groupValue: 2 }] },
|
|
2872
|
+
{ id: '5', groupHeaders: [{ groupValue: 2 }] },
|
|
2873
|
+
{ groupValue: 999 },
|
|
2874
|
+
{ id: '999', groupHeaders: [{ groupValue: 999 }] },
|
|
2875
|
+
]);
|
|
2876
|
+
});
|
|
2877
|
+
|
|
2878
|
+
it('should add a new row to a group that doesnt exist using nested groups', async () => {
|
|
2879
|
+
const grid = await createGroupedGrid({
|
|
2880
|
+
columns: [
|
|
2881
|
+
{ name: 'id' },
|
|
2882
|
+
{ name: 'name' },
|
|
2883
|
+
{ name: 'month', grouped: true },
|
|
2884
|
+
{ name: 'department', grouped: true },
|
|
2885
|
+
],
|
|
2886
|
+
});
|
|
2887
|
+
|
|
2888
|
+
await grid.addNewRow({
|
|
2889
|
+
id: '999', name: 'new', month: 999, department: 1,
|
|
2890
|
+
}, 'end');
|
|
2891
|
+
|
|
2892
|
+
expect(grid.groupedData).toMatchObject([
|
|
2893
|
+
{ groupValue: 11 },
|
|
2894
|
+
{ groupValue: 1, groupHeaders: [{ groupValue: 11 }] },
|
|
2895
|
+
{ id: '1', groupHeaders: [{ groupValue: 11 }, { groupValue: 1 }] },
|
|
2896
|
+
{ id: '2', groupHeaders: [{ groupValue: 11 }, { groupValue: 1 }] },
|
|
2897
|
+
{ groupValue: 2, groupHeaders: [{ groupValue: 11 }] },
|
|
2898
|
+
{ id: '3', groupHeaders: [{ groupValue: 11 }, { groupValue: 2 }] },
|
|
2899
|
+
{ groupValue: 12 },
|
|
2900
|
+
{ groupValue: 1, groupHeaders: [{ groupValue: 12 }] },
|
|
2901
|
+
{ id: '4', groupHeaders: [{ groupValue: 12 }, { groupValue: 1 }] },
|
|
2902
|
+
{ groupValue: 2, groupHeaders: [{ groupValue: 12 }] },
|
|
2903
|
+
{ id: '5', groupHeaders: [{ groupValue: 12 }, { groupValue: 2 }] },
|
|
2904
|
+
// new group
|
|
2905
|
+
{ groupValue: 999 },
|
|
2906
|
+
{ groupValue: 1, groupHeaders: [{ groupValue: 999 }] },
|
|
2907
|
+
{ id: '999', groupHeaders: [{ groupValue: 999 }, { groupValue: 1 }] },
|
|
2908
|
+
]);
|
|
2909
|
+
});
|
|
2910
|
+
|
|
2911
|
+
it('should add a new row to a group that doesnt inside a group that exists', async () => {
|
|
2912
|
+
const grid = await createGroupedGrid({
|
|
2913
|
+
columns: [
|
|
2914
|
+
{ name: 'id' },
|
|
2915
|
+
{ name: 'name' },
|
|
2916
|
+
{ name: 'month', grouped: true },
|
|
2917
|
+
{ name: 'department', grouped: true },
|
|
2918
|
+
],
|
|
2919
|
+
});
|
|
2920
|
+
|
|
2921
|
+
await grid.addNewRow({
|
|
2922
|
+
id: '999', name: 'new', month: 11, department: 999,
|
|
2923
|
+
}, 'end');
|
|
2924
|
+
|
|
2925
|
+
expect(grid.groupedData).toMatchObject([
|
|
2926
|
+
{ groupValue: 11 },
|
|
2927
|
+
{ groupValue: 999, groupHeaders: [{ groupValue: 11 }] },
|
|
2928
|
+
{ id: '999', groupHeaders: [{ groupValue: 11 }, { groupValue: 999 }] },
|
|
2929
|
+
{ groupValue: 1, groupHeaders: [{ groupValue: 11 }] },
|
|
2930
|
+
{ id: '1', groupHeaders: [{ groupValue: 11 }, { groupValue: 1 }] },
|
|
2931
|
+
{ id: '2', groupHeaders: [{ groupValue: 11 }, { groupValue: 1 }] },
|
|
2932
|
+
{ groupValue: 2, groupHeaders: [{ groupValue: 11 }] },
|
|
2933
|
+
{ id: '3', groupHeaders: [{ groupValue: 11 }, { groupValue: 2 }] },
|
|
2934
|
+
{ groupValue: 12 },
|
|
2935
|
+
{ groupValue: 1, groupHeaders: [{ groupValue: 12 }] },
|
|
2936
|
+
{ id: '4', groupHeaders: [{ groupValue: 12 }, { groupValue: 1 }] },
|
|
2937
|
+
{ groupValue: 2, groupHeaders: [{ groupValue: 12 }] },
|
|
2938
|
+
{ id: '5', groupHeaders: [{ groupValue: 12 }, { groupValue: 2 }] },
|
|
2939
|
+
]);
|
|
2940
|
+
});
|
|
2941
|
+
|
|
2942
|
+
it('should add a new row inside nested groups that doesnt exist', async () => {
|
|
2943
|
+
const grid = await createGroupedGrid({
|
|
2944
|
+
columns: [
|
|
2945
|
+
{ name: 'id' },
|
|
2946
|
+
{ name: 'name' },
|
|
2947
|
+
{ name: 'year', grouped: true },
|
|
2948
|
+
{ name: 'month', grouped: true },
|
|
2949
|
+
{ name: 'department', grouped: true },
|
|
2950
|
+
],
|
|
2951
|
+
datasource: {
|
|
2952
|
+
uniqueKey: 'id',
|
|
2953
|
+
data: [
|
|
2954
|
+
{
|
|
2955
|
+
id: '1', name: 'First', year: 2000, month: 11, department: 1,
|
|
2956
|
+
},
|
|
2957
|
+
{
|
|
2958
|
+
id: '2', name: 'Second', year: 2000, month: 11, department: 1,
|
|
2959
|
+
},
|
|
2960
|
+
{
|
|
2961
|
+
id: '3', name: 'Third', year: 2000, month: 11, department: 2,
|
|
2962
|
+
},
|
|
2963
|
+
{
|
|
2964
|
+
id: '4', name: 'Fourth', year: 2010, month: 11, department: 1,
|
|
2965
|
+
},
|
|
2966
|
+
{
|
|
2967
|
+
id: '5', name: 'Fifth', year: 2010, month: 12, department: 2,
|
|
2968
|
+
},
|
|
2969
|
+
],
|
|
2970
|
+
},
|
|
2971
|
+
});
|
|
2972
|
+
|
|
2973
|
+
await grid.addNewRow({
|
|
2974
|
+
id: '999', name: 'new', year: 2010, month: 999, department: 999,
|
|
2975
|
+
}, 'end');
|
|
2976
|
+
await grid.addNewRow({
|
|
2977
|
+
id: '998', name: 'new', year: 2010, month: 999, department: 999,
|
|
2978
|
+
}, 'end');
|
|
2979
|
+
|
|
2980
|
+
expect(grid.groupedData).toMatchObject([
|
|
2981
|
+
{ groupValue: 2000 },
|
|
2982
|
+
{ groupValue: 11, groupHeaders: [{ groupValue: 2000 }] },
|
|
2983
|
+
{ groupValue: 1, groupHeaders: [{ groupValue: 2000 }, { groupValue: 11 }] },
|
|
2984
|
+
{ id: '1', groupHeaders: [{ groupValue: 2000 }, { groupValue: 11 }, { groupValue: 1 }] },
|
|
2985
|
+
{ id: '2', groupHeaders: [{ groupValue: 2000 }, { groupValue: 11 }, { groupValue: 1 }] },
|
|
2986
|
+
{ groupValue: 2, groupHeaders: [{ groupValue: 2000 }, { groupValue: 11 }] },
|
|
2987
|
+
{ id: '3', groupHeaders: [{ groupValue: 2000 }, { groupValue: 11 }, { groupValue: 2 }] },
|
|
2988
|
+
{ groupValue: 2010 },
|
|
2989
|
+
{ groupValue: 999, groupHeaders: [{ groupValue: 2010 }] },
|
|
2990
|
+
{ groupValue: 999, groupHeaders: [{ groupValue: 2010 }, { groupValue: 999 }] },
|
|
2991
|
+
{ id: '999', groupHeaders: [{ groupValue: 2010 }, { groupValue: 999 }, { groupValue: 999 }] },
|
|
2992
|
+
{ id: '998', groupHeaders: [{ groupValue: 2010 }, { groupValue: 999 }, { groupValue: 999 }] },
|
|
2993
|
+
{ groupValue: 11, groupHeaders: [{ groupValue: 2010 }] },
|
|
2994
|
+
{ groupValue: 1, groupHeaders: [{ groupValue: 2010 }, { groupValue: 11 }] },
|
|
2995
|
+
{ id: '4', groupHeaders: [{ groupValue: 2010 }, { groupValue: 11 }, { groupValue: 1 }] },
|
|
2996
|
+
{ groupValue: 12, groupHeaders: [{ groupValue: 2010 }] },
|
|
2997
|
+
{ groupValue: 2, groupHeaders: [{ groupValue: 2010 }, { groupValue: 12 }] },
|
|
2998
|
+
{ id: '5', groupHeaders: [{ groupValue: 2010 }, { groupValue: 12 }, { groupValue: 2 }] },
|
|
2999
|
+
]);
|
|
3000
|
+
});
|
|
3001
|
+
|
|
3002
|
+
it('should throw an error when row groups are not defined or incomplete', async () => {
|
|
3003
|
+
const grid = await createGroupedGrid({
|
|
3004
|
+
columns: [
|
|
3005
|
+
{ name: 'id' },
|
|
3006
|
+
{ name: 'name' },
|
|
3007
|
+
{ name: 'month', grouped: true },
|
|
3008
|
+
{ name: 'department', grouped: true },
|
|
3009
|
+
],
|
|
3010
|
+
});
|
|
3011
|
+
|
|
3012
|
+
// month group is undefined, should throw
|
|
3013
|
+
expect(async () => grid.addNewRow({ id: '999', name: 'new', department: 1 }, 'end')).rejects.toThrow();
|
|
3014
|
+
});
|
|
3015
|
+
});
|
|
3016
|
+
|
|
3017
|
+
describe('addToSelection', () => {
|
|
3018
|
+
it('should add a row to the selected group', async () => {
|
|
3019
|
+
const grid = await createGroupedGrid();
|
|
3020
|
+
|
|
3021
|
+
[grid.datasource.currentRow] = grid.groupedData;
|
|
3022
|
+
|
|
3023
|
+
grid.addToSelection({ id: '999', name: 'new', month: 12 });
|
|
3024
|
+
|
|
3025
|
+
expect(grid.groupedData).toMatchObject([
|
|
3026
|
+
{ groupValue: 1 },
|
|
3027
|
+
{ id: '1', groupHeaders: [{ groupValue: 1 }] },
|
|
3028
|
+
{ id: '2', groupHeaders: [{ groupValue: 1 }] },
|
|
3029
|
+
{ id: '4', groupHeaders: [{ groupValue: 1 }] },
|
|
3030
|
+
{ id: '999', groupHeaders: [{ groupValue: 1 }] },
|
|
3031
|
+
{ groupValue: 2 },
|
|
3032
|
+
{ id: '3', groupHeaders: [{ groupValue: 2 }] },
|
|
3033
|
+
{ id: '5', groupHeaders: [{ groupValue: 2 }] },
|
|
3034
|
+
]);
|
|
3035
|
+
});
|
|
3036
|
+
|
|
3037
|
+
it('should add a row to the selected group when using nested groups', async () => {
|
|
3038
|
+
const grid = await createGroupedGrid();
|
|
3039
|
+
|
|
3040
|
+
[grid.datasource.currentRow] = grid.groupedData;
|
|
3041
|
+
|
|
3042
|
+
grid.addToSelection({ id: '999', name: 'new', month: 12 });
|
|
3043
|
+
|
|
3044
|
+
expect(grid.groupedData).toMatchObject([
|
|
3045
|
+
{ groupValue: 1 },
|
|
3046
|
+
{ id: '1', groupHeaders: [{ groupValue: 1 }] },
|
|
3047
|
+
{ id: '2', groupHeaders: [{ groupValue: 1 }] },
|
|
3048
|
+
{ id: '4', groupHeaders: [{ groupValue: 1 }] },
|
|
3049
|
+
{ id: '999', groupHeaders: [{ groupValue: 1 }] },
|
|
3050
|
+
{ groupValue: 2 },
|
|
3051
|
+
{ id: '3', groupHeaders: [{ groupValue: 2 }] },
|
|
3052
|
+
{ id: '5', groupHeaders: [{ groupValue: 2 }] },
|
|
3053
|
+
]);
|
|
3054
|
+
});
|
|
3055
|
+
|
|
3056
|
+
it('when selected row is not a group, should add a row to the same group as the selected row', async () => {
|
|
3057
|
+
const grid = await createGroupedGrid({
|
|
3058
|
+
columns: [
|
|
3059
|
+
{ name: 'id' },
|
|
3060
|
+
{ name: 'name' },
|
|
3061
|
+
{ name: 'month', grouped: true },
|
|
3062
|
+
{ name: 'department', grouped: true },
|
|
3063
|
+
],
|
|
3064
|
+
});
|
|
3065
|
+
|
|
3066
|
+
grid.datasource.currentRow = grid.groupedData.find((row) => row.id === '3')!;
|
|
3067
|
+
|
|
3068
|
+
grid.addToSelection({ id: '999', name: 'new', month: 12 });
|
|
3069
|
+
|
|
3070
|
+
expect(grid.groupedData).toMatchObject([
|
|
3071
|
+
{ groupValue: 11 },
|
|
3072
|
+
{ groupValue: 1, groupHeaders: [{ groupValue: 11 }] },
|
|
3073
|
+
{ id: '1', groupHeaders: [{ groupValue: 11 }, { groupValue: 1 }] },
|
|
3074
|
+
{ id: '2', groupHeaders: [{ groupValue: 11 }, { groupValue: 1 }] },
|
|
3075
|
+
{ groupValue: 2, groupHeaders: [{ groupValue: 11 }] },
|
|
3076
|
+
{ id: '3', groupHeaders: [{ groupValue: 11 }, { groupValue: 2 }] },
|
|
3077
|
+
{ id: '999', groupHeaders: [{ groupValue: 11 }, { groupValue: 2 }] },
|
|
3078
|
+
{ groupValue: 12 },
|
|
3079
|
+
{ groupValue: 1, groupHeaders: [{ groupValue: 12 }] },
|
|
3080
|
+
{ id: '4', groupHeaders: [{ groupValue: 12 }, { groupValue: 1 }] },
|
|
3081
|
+
{ groupValue: 2, groupHeaders: [{ groupValue: 12 }] },
|
|
3082
|
+
{ id: '5', groupHeaders: [{ groupValue: 12 }, { groupValue: 2 }] },
|
|
3083
|
+
]);
|
|
3084
|
+
});
|
|
3085
|
+
|
|
3086
|
+
it('when selected row is not the most internal group, should add a row to the first most internal group', async () => {
|
|
3087
|
+
const grid = await createGroupedGrid({
|
|
3088
|
+
columns: [
|
|
3089
|
+
{ name: 'id' },
|
|
3090
|
+
{ name: 'name' },
|
|
3091
|
+
{ name: 'month', grouped: true },
|
|
3092
|
+
{ name: 'department', grouped: true },
|
|
3093
|
+
],
|
|
3094
|
+
});
|
|
3095
|
+
|
|
3096
|
+
[grid.datasource.currentRow] = grid.groupedData;
|
|
3097
|
+
|
|
3098
|
+
grid.addToSelection({ id: '999', name: 'new', month: 12 });
|
|
3099
|
+
|
|
3100
|
+
expect(grid.groupedData).toMatchObject([
|
|
3101
|
+
{ groupValue: 11 },
|
|
3102
|
+
{ groupValue: 1, groupHeaders: [{ groupValue: 11 }] },
|
|
3103
|
+
{ id: '1', groupHeaders: [{ groupValue: 11 }, { groupValue: 1 }] },
|
|
3104
|
+
{ id: '2', groupHeaders: [{ groupValue: 11 }, { groupValue: 1 }] },
|
|
3105
|
+
{ id: '999', groupHeaders: [{ groupValue: 11 }, { groupValue: 1 }] },
|
|
3106
|
+
{ groupValue: 2, groupHeaders: [{ groupValue: 11 }] },
|
|
3107
|
+
{ id: '3', groupHeaders: [{ groupValue: 11 }, { groupValue: 2 }] },
|
|
3108
|
+
{ groupValue: 12 },
|
|
3109
|
+
{ groupValue: 1, groupHeaders: [{ groupValue: 12 }] },
|
|
3110
|
+
{ id: '4', groupHeaders: [{ groupValue: 12 }, { groupValue: 1 }] },
|
|
3111
|
+
{ groupValue: 2, groupHeaders: [{ groupValue: 12 }] },
|
|
3112
|
+
{ id: '5', groupHeaders: [{ groupValue: 12 }, { groupValue: 2 }] },
|
|
3113
|
+
]);
|
|
3114
|
+
});
|
|
3115
|
+
});
|
|
2668
3116
|
});
|
|
@@ -27,6 +27,12 @@ export declare class TekMemoryDatasource extends MemoryDatasource implements ITe
|
|
|
27
27
|
protected getEncodedParam(urlParam: string, datasourceParam?: IDictionary<any>): IDictionary<any>;
|
|
28
28
|
protected getQueryStringValues(): IDictionary<any>;
|
|
29
29
|
protected getUrlQueryString(): string;
|
|
30
|
+
/**
|
|
31
|
+
* Allows the comunication between the base filter and the dynamic filter
|
|
32
|
+
* @param filtroDinamico
|
|
33
|
+
* @returns
|
|
34
|
+
*/
|
|
35
|
+
setBaseFilter(filtroDinamico: any): Promise<any>;
|
|
30
36
|
/**
|
|
31
37
|
* Adds a new dynamic filter position or replace if exists
|
|
32
38
|
* @param column Dynamic Filter column name
|
|
@@ -61,7 +67,7 @@ export declare class TekMemoryDatasource extends MemoryDatasource implements ITe
|
|
|
61
67
|
* @param value Filter value
|
|
62
68
|
* @returns Is valid filter value
|
|
63
69
|
*/
|
|
64
|
-
protected isValidDynamicFilterValue(column: string, value?: IDictionary<any>[]): boolean
|
|
70
|
+
protected isValidDynamicFilterValue(column: string, value?: IDictionary<any>[]): boolean;
|
|
65
71
|
clone(): {
|
|
66
72
|
dynamicFilter: IDictionary<IDynamicFilterItem[]>;
|
|
67
73
|
searchJoin: IDictionary<(string | number)[]>;
|
|
@@ -27,6 +27,12 @@ export declare class TekRestDatasource extends RestDatasource implements ITekRes
|
|
|
27
27
|
protected getEncodedParam(urlParam: string, datasourceParam?: IDictionary<any>): IDictionary<any>;
|
|
28
28
|
protected getQueryStringValues(): IDictionary<any>;
|
|
29
29
|
protected getUrlQueryString(): string;
|
|
30
|
+
/**
|
|
31
|
+
* Allows the comunication between the base filter and the dynamic filter
|
|
32
|
+
* @param filtroDinamico
|
|
33
|
+
* @returns
|
|
34
|
+
*/
|
|
35
|
+
setBaseFilter(filtroDinamico: any): Promise<any>;
|
|
30
36
|
/**
|
|
31
37
|
* Adds a new dynamic filter position or replace if exists
|
|
32
38
|
* @param column Dynamic Filter column name
|
|
@@ -61,7 +67,7 @@ export declare class TekRestDatasource extends RestDatasource implements ITekRes
|
|
|
61
67
|
* @param value Filter value
|
|
62
68
|
* @returns Is valid filter value
|
|
63
69
|
*/
|
|
64
|
-
protected isValidDynamicFilterValue(column: string, value?: IDictionary<any>[]): boolean
|
|
70
|
+
protected isValidDynamicFilterValue(column: string, value?: IDictionary<any>[]): boolean;
|
|
65
71
|
/**
|
|
66
72
|
* Retrieves request params
|
|
67
73
|
*/
|
|
@@ -2,7 +2,7 @@ import { GridEditable, IComponentRender } from '@zeedhi/common';
|
|
|
2
2
|
import { Datasource, IDictionary, IEventParam } from '@zeedhi/core';
|
|
3
3
|
import { ITekGridAtoms } from '../../utils';
|
|
4
4
|
import { TekGridColumn } from './grid-column';
|
|
5
|
-
import { IModalFilterProps, ITekGrid, ITekGridColumn, ITekGridEvents, ITekGridExportConfig } from './interfaces';
|
|
5
|
+
import { IGroupedData, IModalFilterProps, ITekGrid, ITekGridColumn, ITekGridEvents, ITekGridExportConfig } from './interfaces';
|
|
6
6
|
import { TekGridLayoutOptions } from './layout-options';
|
|
7
7
|
export declare class TekGrid extends GridEditable implements ITekGrid {
|
|
8
8
|
title: string;
|
|
@@ -65,7 +65,7 @@ export declare class TekGrid extends GridEditable implements ITekGrid {
|
|
|
65
65
|
groupColumnNames: string[];
|
|
66
66
|
summaryColumns: TekGridColumn[];
|
|
67
67
|
groupColumns: TekGridColumn[];
|
|
68
|
-
groupedData:
|
|
68
|
+
groupedData: IGroupedData[];
|
|
69
69
|
private toolbarSlotProps;
|
|
70
70
|
viewUpdateScrollData?: () => void;
|
|
71
71
|
private gridBase;
|
|
@@ -101,7 +101,7 @@ export declare class TekGrid extends GridEditable implements ITekGrid {
|
|
|
101
101
|
columnHasFilterData(column: TekGridColumn): boolean;
|
|
102
102
|
private buildReportGroups;
|
|
103
103
|
private buildReportAggregations;
|
|
104
|
-
getReport(type: string, portrait?: boolean, rowObj?: any): Promise<
|
|
104
|
+
getReport(type: string, portrait?: boolean, rowObj?: any): Promise<void>;
|
|
105
105
|
private groups;
|
|
106
106
|
private summary;
|
|
107
107
|
private originalDatasourceLoadAll?;
|
|
@@ -175,4 +175,47 @@ export declare class TekGrid extends GridEditable implements ITekGrid {
|
|
|
175
175
|
getFilterInputs(columnName?: string): import("@zeedhi/common").Input[];
|
|
176
176
|
isColumnSearchable(column: TekGridColumn): boolean;
|
|
177
177
|
getColumn(name: string): TekGridColumn;
|
|
178
|
+
/**
|
|
179
|
+
* Adds new row to the datasource data and pushes it to the editedRows
|
|
180
|
+
* @param row Row
|
|
181
|
+
* @param position whether the new Row will be inserted at the beginning or end of the data array
|
|
182
|
+
*/
|
|
183
|
+
addNewRow(row: IDictionary, position?: 'end' | 'start'): Promise<void>;
|
|
184
|
+
/**
|
|
185
|
+
* Takes a row and adds it to the selected group (datasource.currentRow)
|
|
186
|
+
* @param row the new row to be added
|
|
187
|
+
* @param position the position, at the beginning of the group or at the end
|
|
188
|
+
*/
|
|
189
|
+
addToSelection(row: IDictionary, position?: 'end' | 'start'): Promise<void>;
|
|
190
|
+
/**
|
|
191
|
+
* Adds a new row to the groupedData array
|
|
192
|
+
* @param row the new row to be added
|
|
193
|
+
* @param position the position, at the beginning of the group or at the end
|
|
194
|
+
*/
|
|
195
|
+
private addGroupedRow;
|
|
196
|
+
private findMissingGroups;
|
|
197
|
+
/**
|
|
198
|
+
* Finds the last group (most internal group) where a row should be inserted
|
|
199
|
+
* @param row to be inserted
|
|
200
|
+
* @returns the index and the group where the row should be inserted
|
|
201
|
+
*/
|
|
202
|
+
private findLastGroupingIndex;
|
|
203
|
+
/**
|
|
204
|
+
* Creates a group hierarchy for a new row, creating intermediate groups if needed
|
|
205
|
+
* @param row to be inserted
|
|
206
|
+
* @returns the index and the group where the row should be inserted
|
|
207
|
+
*/
|
|
208
|
+
private createGroupHierarchyForRow;
|
|
209
|
+
/**
|
|
210
|
+
* Adds a row to the children of a group
|
|
211
|
+
*/
|
|
212
|
+
private addRowToGroupChildren;
|
|
213
|
+
/**
|
|
214
|
+
* Checks if a row is a group header, adding typescript type-checking
|
|
215
|
+
*/
|
|
216
|
+
private isGroupHeader;
|
|
217
|
+
/**
|
|
218
|
+
* Checks if a row is the last grouping of the grid (the most internal grouping)
|
|
219
|
+
*/
|
|
220
|
+
private isLastGrouping;
|
|
178
221
|
}
|
|
@@ -178,3 +178,22 @@ export interface IModalFilterProps extends IModal {
|
|
|
178
178
|
height?: string;
|
|
179
179
|
maxHeight?: string;
|
|
180
180
|
}
|
|
181
|
+
export interface ITekGridGroupFooter {
|
|
182
|
+
groupFooter: boolean;
|
|
183
|
+
groupIndex: number;
|
|
184
|
+
groupHeaders: ITekGridGroupHeader[];
|
|
185
|
+
groupLabel: string;
|
|
186
|
+
groupValue: any;
|
|
187
|
+
}
|
|
188
|
+
export declare type IGroupedData = (ITekGridGroupHeader & {
|
|
189
|
+
[key: string]: any;
|
|
190
|
+
}) | {
|
|
191
|
+
[key: string]: any;
|
|
192
|
+
groupFooter: boolean;
|
|
193
|
+
groupSummary: boolean;
|
|
194
|
+
} | (ITekGridGroupFooter & {
|
|
195
|
+
[key: string]: any;
|
|
196
|
+
}) | {
|
|
197
|
+
[key: string]: any;
|
|
198
|
+
groupHeaders: ITekGridGroupHeader[];
|
|
199
|
+
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { IDictionary } from '@zeedhi/core';
|
|
2
|
+
/**
|
|
3
|
+
* Thrown when a row has incomplete group information.
|
|
4
|
+
* Provides details about the missing groups and the problematic row.
|
|
5
|
+
*/
|
|
6
|
+
export declare class IncompleteGroupsError extends Error {
|
|
7
|
+
constructor(row: IDictionary, missingGroups: string[]);
|
|
8
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Extracts properties from an object based on a list of properties
|
|
3
|
+
* @param obj object whose properties will be extracted
|
|
4
|
+
* @param props array of strings with the properties to be extracted
|
|
5
|
+
* @returns object containing the extracted properties
|
|
6
|
+
*/
|
|
7
|
+
export declare const extractProperties: (obj: any, props: string[]) => any;
|
package/types/utils/index.d.ts
CHANGED