@zeedhi/teknisa-components-common 1.130.0 → 1.132.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.
Files changed (32) hide show
  1. package/coverage/clover.xml +1224 -1109
  2. package/coverage/coverage-final.json +48 -46
  3. package/coverage/lcov-report/index.html +22 -22
  4. package/coverage/lcov-report/tests/__helpers__/component-event-helper.ts.html +3 -3
  5. package/coverage/lcov-report/tests/__helpers__/flush-promises-helper.ts.html +1 -1
  6. package/coverage/lcov-report/tests/__helpers__/get-child-helper.ts.html +11 -11
  7. package/coverage/lcov-report/tests/__helpers__/index.html +1 -1
  8. package/coverage/lcov-report/tests/__helpers__/index.ts.html +4 -4
  9. package/coverage/lcov-report/tests/__helpers__/mock-created-helper.ts.html +3 -3
  10. package/coverage/lcov.info +2230 -1993
  11. package/dist/tek-components-common.esm.js +393 -195
  12. package/dist/tek-components-common.umd.js +393 -194
  13. package/package.json +2 -2
  14. package/tests/unit/components/tek-grid/grid-columns-button.spec.ts +123 -2
  15. package/tests/unit/components/tek-grid/grid-export-button.spec.ts +403 -0
  16. package/tests/unit/components/tek-grid/grid-filter-button.spec.ts +147 -4
  17. package/tests/unit/components/tek-grid/grid.spec.ts +182 -9
  18. package/tests/unit/components/tek-grid/layout_options.spec.ts +680 -25
  19. package/tests/unit/utils/object-comparison.spec.ts +89 -0
  20. package/types/components/index.d.ts +1 -0
  21. package/types/components/tek-grid/grid-columns-button.d.ts +2 -1
  22. package/types/components/tek-grid/grid-export-button.d.ts +19 -0
  23. package/types/components/tek-grid/grid-filter-button.d.ts +1 -0
  24. package/types/components/tek-grid/grid.d.ts +4 -0
  25. package/types/components/tek-grid/interfaces.d.ts +8 -0
  26. package/types/components/tek-grid/layout-options.d.ts +15 -0
  27. package/types/components/tek-tree-grid/tree-grid.d.ts +2 -0
  28. package/types/utils/grid-base/export-options/button-option.d.ts +3 -1
  29. package/types/utils/grid-base/export-options/multi-option.d.ts +3 -1
  30. package/types/utils/grid-base/grid-base.d.ts +1 -3
  31. package/types/utils/index.d.ts +1 -0
  32. package/types/utils/object-comparison.d.ts +3 -0
@@ -84,6 +84,27 @@ describe('TekGridFilterButton', () => {
84
84
 
85
85
  expect(filterButton.grid).toEqual(instance);
86
86
  });
87
+
88
+ it('should load grid by gridName after the filter button is created', () => {
89
+ const filterButton = new TekGridFilterButton({
90
+ name: 'external-filter-button',
91
+ component: 'TekGridFilterButton',
92
+ gridName: 'grid-created-after-filter-button',
93
+ });
94
+
95
+ expect(filterButton.grid).toBeUndefined();
96
+
97
+ const instance = new TekGrid({
98
+ name: 'grid-created-after-filter-button',
99
+ component: 'TekGrid',
100
+ });
101
+ instance.onCreated();
102
+
103
+ filterButton.loadGrid();
104
+
105
+ expect(filterButton.grid).toEqual(instance);
106
+ expect((instance as any).gridBase.filterButton).toBe(filterButton);
107
+ });
87
108
  });
88
109
 
89
110
  describe('filterClick()', () => {
@@ -117,6 +138,85 @@ describe('TekGridFilterButton', () => {
117
138
  spyMetadata.mockReset();
118
139
  });
119
140
 
141
+ it('should open the filter modal from an external button when grid filterButton is false', () => {
142
+ const instance = new TekGrid({
143
+ name: 'grid_external_filter_button',
144
+ component: 'TekGrid',
145
+ filterButton: false,
146
+ columns: [
147
+ { name: 'id' },
148
+ { name: 'name', filterable: true, filterProps: [{ name: 'name_edit', label: 'name' }] },
149
+ ],
150
+ });
151
+
152
+ let formElements: any = [];
153
+ const spy = jest.spyOn(ModalService, 'create').mockImplementation((modal: IModal) => {
154
+ const form = getChild<IForm>(modal.children || [], `${instance.name}-filter-form`);
155
+ formElements = form.children;
156
+
157
+ return new Modal(modal);
158
+ });
159
+ instance.onCreated();
160
+
161
+ const button = new TekGridFilterButton({
162
+ name: 'external-filter-button',
163
+ component: 'TekGridFilterButton',
164
+ gridName: instance.name,
165
+ });
166
+ setClick(button);
167
+
168
+ expect(button.grid).toEqual(instance);
169
+ expect((instance as any).gridBase.filterButton).toBe(button);
170
+ expect(formElements[0].name).toBe(`${instance.name}-filter-AND-CONTAINS-name-0`);
171
+
172
+ spy.mockReset();
173
+ });
174
+
175
+ it('should not open the filter modal when click cannot resolve a grid', () => {
176
+ const spy = jest.spyOn(ModalService, 'create');
177
+ const button = new TekGridFilterButton({
178
+ name: 'external-filter-button-without-grid',
179
+ component: 'TekGridFilterButton',
180
+ gridName: 'missing-grid',
181
+ });
182
+
183
+ setClick(button);
184
+
185
+ expect(button.grid).toBeUndefined();
186
+ expect(spy).not.toBeCalled();
187
+
188
+ spy.mockReset();
189
+ });
190
+
191
+ it('should close the owning filter modal from the header close button', () => {
192
+ const instance = new TekGrid({
193
+ name: 'grid_filter_close_button',
194
+ component: 'TekGrid',
195
+ });
196
+
197
+ let closeButton: IButton = { name: 'close', component: 'ZdButton' };
198
+ const spy = jest.spyOn(ModalService, 'create').mockImplementation((modal: IModal) => {
199
+ const header = getChild(modal.children || [], `${instance.name}-filter-header-container`);
200
+ closeButton = getChild(header.children || [], `${instance.name}-filter-close-button`);
201
+
202
+ return new Modal(modal);
203
+ });
204
+ instance.onCreated();
205
+
206
+ const buttonProps = getChild<ITekGridFilterButton>(instance.toolbarSlot, `${instance.name}_filterButton`);
207
+ const button = new TekGridFilterButton(buttonProps);
208
+ setClick(button);
209
+
210
+ const hideSpy = jest.spyOn((button as any).filterModal, 'hide');
211
+ const closeButtonObject = new Button(closeButton);
212
+ setClick(closeButtonObject);
213
+
214
+ expect(closeButton.component).toBe('ZdButton');
215
+ expect(hideSpy).toBeCalled();
216
+
217
+ spy.mockReset();
218
+ });
219
+
120
220
  it('should call events', () => {
121
221
  let filterClickCalled = false;
122
222
  const instance = new TekGrid({
@@ -207,6 +307,49 @@ describe('TekGridFilterButton', () => {
207
307
  spy.mockReset();
208
308
  });
209
309
 
310
+ it('should create filter form elements without dataValueOut from componentProps', () => {
311
+ const instance = new TekGrid({
312
+ name: 'grid_filterClick_dataValueOut',
313
+ component: 'TekGrid',
314
+ columns: [
315
+ {
316
+ name: 'name',
317
+ filterable: true,
318
+ componentProps: {
319
+ name: 'name_edit',
320
+ component: 'ZdSelect',
321
+ dataText: 'description',
322
+ dataValueOut: 'id',
323
+ },
324
+ filterProps: [{ name: 'name_filter', label: 'name' }],
325
+ },
326
+ {
327
+ name: 'description',
328
+ filterable: true,
329
+ filterProps: [{ name: 'description_filter', label: 'description' }],
330
+ },
331
+ ],
332
+ });
333
+
334
+ let formElements: any = [];
335
+ const spy = jest.spyOn(ModalService, 'create').mockImplementation((modal: IModal) => {
336
+ const form = getChild<IForm>(modal.children || [], `${instance.name}-filter-form`);
337
+ formElements = form.children;
338
+
339
+ return new Modal(modal);
340
+ });
341
+ instance.onCreated();
342
+ (instance.columns[1] as any).componentProps = undefined;
343
+ clickOnFilterButton(instance);
344
+
345
+ expect(formElements[0].component).toBe('ZdSelect');
346
+ expect(formElements[0].dataText).toBe('description');
347
+ expect(formElements[0].dataValueOut).toBeUndefined();
348
+ expect(formElements[1].name).toBe(`${instance.name}-filter-AND-CONTAINS-description-0`);
349
+
350
+ spy.mockReset();
351
+ });
352
+
210
353
  it('when creating a SelectMultiple filter, default should not add showCheckboxAll prop', () => {
211
354
  const instance = new TekGrid({
212
355
  name: 'grid_filterClick5',
@@ -318,7 +461,7 @@ describe('TekGridFilterButton', () => {
318
461
  formObject.value['grid_filterClick5-filter-AND-CONTAINS-id-0'] = ['example'];
319
462
  setClick(applyButtonObject);
320
463
 
321
- expect(instance.datasource.filter).toEqual({});
464
+ expect(instance.datasource.filter).toEqual({ id: ['example'] });
322
465
 
323
466
  selectObject.checkboxAll = true;
324
467
  setClick(applyButtonObject);
@@ -327,7 +470,7 @@ describe('TekGridFilterButton', () => {
327
470
 
328
471
  (Config as any).set({ selectAllCompatibilityMode: true });
329
472
  setClick(applyButtonObject);
330
- expect(instance.datasource.filter).toEqual({});
473
+ expect(instance.datasource.filter).toEqual({ id: 'T' });
331
474
 
332
475
  spy.mockReset();
333
476
  });
@@ -952,10 +1095,10 @@ describe('TekGridFilterButton', () => {
952
1095
  };
953
1096
  const applyButtonObject = new Button(applyButton);
954
1097
  setClick(applyButtonObject);
955
- expect(instance.datasource.filter).toEqual({});
1098
+ expect(instance.datasource.filter).toEqual({ id: '1;2;3', name: 'teste', salary: '1000' });
956
1099
  expect(beforeApplyFilterCalled).toBeTruthy();
957
1100
  expect(changeLayoutCalled).toBeTruthy();
958
- expect(instance.columnHasFilterData({ name: 'name' } as TekGridColumn)).toBe(undefined);
1101
+ expect(instance.columnHasFilterData({ name: 'name' } as TekGridColumn)).toBe(true);
959
1102
 
960
1103
  setClick(applyButtonObject, { defaultPrevented: true });
961
1104
  expect(spyDatasourceGet).toBeCalledTimes(1);
@@ -15,7 +15,7 @@ import {
15
15
  ITekGrid,
16
16
  ITekGridFilterButton,
17
17
  ITekGridGroupFooter,
18
- TekGrid, TekGridColumn, TekGridFilterButton, TekRestDatasource,
18
+ TekGrid, TekGridColumn, TekGridExportButton, TekGridFilterButton, TekRestDatasource,
19
19
  } from '../../../../src';
20
20
  import { ReportFilter } from '../../../../src/utils';
21
21
  import { setClick, getChild } from '../../../__helpers__';
@@ -232,12 +232,19 @@ describe('TekGrid', () => {
232
232
  ],
233
233
  });
234
234
 
235
- expect((instance as any).gridBase.exportConfigButtons[0].label).toBeUndefined();
236
- expect((instance as any).gridBase.exportConfigButtons[0].iconName).toBe('icon');
237
- expect((instance as any).gridBase.exportConfigButtons[0].name).toBe('grid_export_pdf_landscape');
238
- expect((instance as any).gridBase.exportConfigButtons[0].component).toBe('ZdButton');
239
- expect((instance as any).gridBase.exportConfigButtons[0].flat).toBeTruthy();
240
- expect((instance as any).gridBase.exportConfigButtons[0].events).toBeDefined();
235
+ const exportButton = new TekGridExportButton({
236
+ name: 'grid_export_dropdown',
237
+ component: 'TekGridExportButton',
238
+ grid: instance,
239
+ });
240
+ const exportConfigButton = exportButton.children![0];
241
+
242
+ expect(exportConfigButton.label).toBeUndefined();
243
+ expect(exportConfigButton.iconName).toBe('icon');
244
+ expect(exportConfigButton.name).toBe('grid_export_pdf_landscape');
245
+ expect(exportConfigButton.component).toBe('ZdButton');
246
+ expect(exportConfigButton.flat).toBeTruthy();
247
+ expect(exportConfigButton.events).toBeDefined();
241
248
  });
242
249
 
243
250
  it('should create new TekGrid with accessor datasource', () => {
@@ -1032,6 +1039,10 @@ describe('TekGrid', () => {
1032
1039
 
1033
1040
  await flushPromises();
1034
1041
 
1042
+ instance.navigateDatasource(false);
1043
+ expect(instance.datasource.currentRow).toEqual(instance.groupedData[0]);
1044
+ instance.datasource.currentRow = {};
1045
+
1035
1046
  dispatchEvent('arrowdown', {}); // arrow down
1036
1047
  expect(instance.datasource.currentRow).toEqual(instance.groupedData[0]);
1037
1048
 
@@ -1198,11 +1209,10 @@ describe('TekGrid', () => {
1198
1209
  spyMetadata.mockReset();
1199
1210
  });
1200
1211
 
1201
- it('when using cellSelection, should use viewNavigate', async () => {
1212
+ it('when grouped, should use viewNavigate', async () => {
1202
1213
  const instance = new TekGrid({
1203
1214
  name: 'grid_navigation_1',
1204
1215
  component: 'TekGrid',
1205
- cellSelection: true,
1206
1216
  columns: [
1207
1217
  {
1208
1218
  name: 'name',
@@ -1854,6 +1864,46 @@ describe('TekGrid', () => {
1854
1864
  httpSpy.mockReset();
1855
1865
  });
1856
1866
 
1867
+ it('should not call loadAfterTasks when initialized with lazyLoad datasource', async () => {
1868
+ const instance = createAndMount({
1869
+ name: 'grid_grouping_lazy_load',
1870
+ component: 'TekGrid',
1871
+ columns: [
1872
+ {
1873
+ name: 'id',
1874
+ label: 'id',
1875
+ },
1876
+ {
1877
+ name: 'name',
1878
+ label: 'name',
1879
+ },
1880
+ {
1881
+ name: 'department',
1882
+ label: 'department',
1883
+ grouped: true,
1884
+ },
1885
+ ],
1886
+ datasource: {
1887
+ uniqueKey: 'id',
1888
+ route: '/zeedhi',
1889
+ type: 'tek-rest',
1890
+ limit: 10,
1891
+ watchUrl: false,
1892
+ lazyLoad: true,
1893
+ },
1894
+ });
1895
+
1896
+ const updateGroupedDataSpy = jest.spyOn(instance, 'updateGroupedData');
1897
+ const loadAfterTasksSpy = jest.spyOn(instance, 'loadAfterTasks');
1898
+
1899
+ jest.runAllTimers();
1900
+
1901
+ expect(updateGroupedDataSpy).toHaveBeenCalled();
1902
+ expect(loadAfterTasksSpy).not.toHaveBeenCalled();
1903
+
1904
+ loadAfterTasksSpy.mockRestore();
1905
+ });
1906
+
1857
1907
  it('editedRows should return cleaned rows', async () => {
1858
1908
  const instance = new TekGrid({
1859
1909
  name: 'grid_grouping_4',
@@ -2286,6 +2336,126 @@ describe('TekGrid', () => {
2286
2336
 
2287
2337
  expect(grid.columnHasFilterData(column)).toBe(true);
2288
2338
  });
2339
+
2340
+ it('should search only in columns listed in searchIn when searchIn is non-empty', async () => {
2341
+ const instance = new TekGrid({
2342
+ name: 'grid_search',
2343
+ component: 'TekGrid',
2344
+ columns: [
2345
+ { name: 'id' },
2346
+ {
2347
+ name: 'employee_id',
2348
+ componentProps: {
2349
+ name: 'ZdSelect',
2350
+ dataText: ['name'],
2351
+ datasource: {
2352
+ type: 'tek-rest',
2353
+ uniqueKey: 'id',
2354
+ route: '/zeedhi',
2355
+ lazyLoad: false,
2356
+ },
2357
+ },
2358
+ },
2359
+ {
2360
+ name: 'department_id',
2361
+ componentProps: {
2362
+ name: 'ZdSelect',
2363
+ dataText: ['name'],
2364
+ datasource: {
2365
+ type: 'tek-rest',
2366
+ uniqueKey: 'id',
2367
+ route: '/departments',
2368
+ lazyLoad: false,
2369
+ },
2370
+ },
2371
+ },
2372
+ ],
2373
+ datasource: {
2374
+ type: 'tek-rest',
2375
+ lazyLoad: true,
2376
+ route: '/grid',
2377
+ searchIn: ['employee_id'],
2378
+ } as any,
2379
+ });
2380
+
2381
+ await instance.setSearch('1');
2382
+
2383
+ expect(instance.datasource).toBeInstanceOf(TekRestDatasource);
2384
+ expect((instance.datasource as TekRestDatasource).searchJoin).toEqual({ employee_id: [1, 15] });
2385
+ expect(httpSpy).toHaveBeenCalledTimes(2);
2386
+ });
2387
+
2388
+ it('should search all lookup columns when searchIn is empty', async () => {
2389
+ const instance = new TekGrid({
2390
+ name: 'grid_search_empty_searchin',
2391
+ component: 'TekGrid',
2392
+ columns: [
2393
+ { name: 'id' },
2394
+ {
2395
+ name: 'employee_id',
2396
+ componentProps: {
2397
+ name: 'ZdSelect',
2398
+ dataText: ['name'],
2399
+ datasource: {
2400
+ type: 'tek-rest',
2401
+ uniqueKey: 'id',
2402
+ route: '/zeedhi',
2403
+ lazyLoad: false,
2404
+ },
2405
+ },
2406
+ },
2407
+ ],
2408
+ datasource: {
2409
+ type: 'tek-rest',
2410
+ lazyLoad: true,
2411
+ route: '/grid',
2412
+ searchIn: [],
2413
+ } as any,
2414
+ });
2415
+
2416
+ await instance.setSearch('1');
2417
+
2418
+ expect(instance.datasource).toBeInstanceOf(TekRestDatasource);
2419
+ expect((instance.datasource as TekRestDatasource).searchJoin).toEqual({ employee_id: [1, 15] });
2420
+ expect(httpSpy).toHaveBeenCalledTimes(2);
2421
+ });
2422
+
2423
+ it('should fall back to empty array when datasource.searchIn is null', async () => {
2424
+ const instance = new TekGrid({
2425
+ name: 'grid_search_null_searchin',
2426
+ component: 'TekGrid',
2427
+ columns: [
2428
+ { name: 'id' },
2429
+ {
2430
+ name: 'employee_id',
2431
+ componentProps: {
2432
+ name: 'ZdSelect',
2433
+ dataText: ['name'],
2434
+ datasource: {
2435
+ type: 'tek-rest',
2436
+ uniqueKey: 'id',
2437
+ route: '/zeedhi',
2438
+ lazyLoad: false,
2439
+ },
2440
+ },
2441
+ },
2442
+ ],
2443
+ datasource: {
2444
+ type: 'tek-rest',
2445
+ lazyLoad: true,
2446
+ route: '/grid',
2447
+ searchIn: [],
2448
+ } as any,
2449
+ });
2450
+
2451
+ (instance.datasource as any).searchIn = null;
2452
+
2453
+ await instance.setSearch('1');
2454
+
2455
+ expect(instance.datasource).toBeInstanceOf(TekRestDatasource);
2456
+ expect((instance.datasource as TekRestDatasource).searchJoin).toEqual({ employee_id: [1, 15] });
2457
+ expect(httpSpy).toHaveBeenCalledTimes(2);
2458
+ });
2289
2459
  });
2290
2460
 
2291
2461
  describe('rowClick', () => {
@@ -3372,6 +3542,9 @@ describe('TekGrid', () => {
3372
3542
  expect(toolbarSlot.find((c: IComponentRender) => c.name?.includes('_title'))).toBeUndefined();
3373
3543
  expect(toolbarSlot.find((c: IComponentRender) => c.name?.includes('_hideTooltip'))).toBeUndefined();
3374
3544
  expect(toolbarSlot[0].name).toBe('grid_toolbarDiv');
3545
+ expect(getChild<any>(toolbarSlot, 'grid_columnsButton').gridName).toBe('grid');
3546
+ expect(getChild<any>(toolbarSlot, 'grid_columnsButton').iterableComponentName).toBeUndefined();
3547
+ expect(getChild<IComponentRender>(toolbarSlot, 'grid_layout_options').gridName).toBe('grid');
3375
3548
  });
3376
3549
  });
3377
3550
  });