@zeedhi/teknisa-components-common 1.124.0 → 1.126.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.
@@ -1,4 +1,4 @@
1
- import { KeyMap, I18n, FormatterParserProvider, Messages, Metadata, DatasourceFactory, MemoryDatasource, URL, Utils, RestDatasource, Config, Accessor, Loader, DateHelper, Http, Singleton, VersionService } from '@zeedhi/core';
1
+ import { Utils, KeyMap, I18n, FormatterParserProvider, Messages, Metadata, DatasourceFactory, MemoryDatasource, URL, RestDatasource, Config, Accessor, Loader, DateHelper, Http, Singleton, VersionService } from '@zeedhi/core';
2
2
  import { Form, Button, Tooltip, GridEditable, Grid, ComponentRender, Iterable, Carousel, IterableComponentRender as IterableComponentRender$1, Loading as Loading$1, GridColumnEditable, Report, EmptyDataError, AlertService, ColumnNotFoundError, IterableColumnsButtonController, IterableColumnsButton, ModalService, SelectMultiple, TreeGridEditable, List } from '@zeedhi/common';
3
3
  import debounce from 'lodash.debounce';
4
4
  import merge from 'lodash.merge';
@@ -55,7 +55,7 @@ class CrudForm extends Form {
55
55
  const formChanged = valueKeys.some((key) => {
56
56
  const currValue = this.value[key];
57
57
  const prevValue = this.beforeEditValue ? this.beforeEditValue[key] : null;
58
- return this.nullCast(currValue) !== this.nullCast(prevValue);
58
+ return !Utils.isEqual(currValue, prevValue);
59
59
  });
60
60
  if (!formChanged) {
61
61
  this.editing = false;
@@ -64,9 +64,6 @@ class CrudForm extends Form {
64
64
  this.value[child.name] = value;
65
65
  this.editing = true;
66
66
  }
67
- nullCast(value) {
68
- return ['', null, undefined].includes(value) ? null : value;
69
- }
70
67
  onMounted(element) {
71
68
  this.cancelEdit();
72
69
  super.onMounted(element);
@@ -1338,6 +1335,9 @@ Messages.add({
1338
1335
  TEKGRID_WITH_GROUPS: '(Com grupos)',
1339
1336
  TEKGRID_GRID_MIRROR: '(Espelho do grid)',
1340
1337
  TEKGRID_NO_DATA: 'Não há dados para exportar',
1338
+ TEKGRID_LAYOUT_FILTER_CONFIRMATION: 'O layout possui informações de filtro. '
1339
+ + 'Deseja salvar o filtro com o layout?',
1340
+ TEKGRID_LAYOUT_HAS_FILTER: 'possui filtro',
1341
1341
  },
1342
1342
  },
1343
1343
  'en-US': {
@@ -1412,6 +1412,9 @@ Messages.add({
1412
1412
  TEKGRID_WITH_GROUPS: '(With groups)',
1413
1413
  TEKGRID_GRID_MIRROR: '(Grid mirror)',
1414
1414
  TEKGRID_NO_DATA: 'There is no data to export',
1415
+ TEKGRID_LAYOUT_FILTER_CONFIRMATION: 'The layout contains filter information. '
1416
+ + 'Do you want to save the filter with the layout?',
1417
+ TEKGRID_LAYOUT_HAS_FILTER: 'has filter',
1415
1418
  },
1416
1419
  },
1417
1420
  'es-CL': {
@@ -1486,6 +1489,9 @@ Messages.add({
1486
1489
  TEKGRID_WITH_GROUPS: '(Con grupos)',
1487
1490
  TEKGRID_GRID_MIRROR: '(Espejo de grid)',
1488
1491
  TEKGRID_NO_DATA: 'No hay datos para exportar',
1492
+ TEKGRID_LAYOUT_FILTER_CONFIRMATION: 'La disposición contiene información de filtro. '
1493
+ + '¿Desea guardar el filtro junto con la disposición?',
1494
+ TEKGRID_LAYOUT_HAS_FILTER: 'contiene filtro',
1489
1495
  },
1490
1496
  },
1491
1497
  });
@@ -3837,6 +3843,9 @@ class TekGridLayoutOptions extends ComponentRender {
3837
3843
  }
3838
3844
  });
3839
3845
  }
3846
+ checkLayoutsData(data) {
3847
+ return Object.assign(Object.assign({}, data), { layouts: Array.isArray(data === null || data === void 0 ? void 0 : data.layouts) ? {} : ((data === null || data === void 0 ? void 0 : data.layouts) || {}) });
3848
+ }
3840
3849
  loadLayoutsInfo() {
3841
3850
  return __awaiter(this, void 0, void 0, function* () {
3842
3851
  const eventFunction = this.events.loadLayouts || this.grid.events.loadLayouts;
@@ -3847,9 +3856,9 @@ class TekGridLayoutOptions extends ComponentRender {
3847
3856
  const route = Config.loadGridLayoutsEndPoint;
3848
3857
  const response = yield Http.get(`${route}?id=${this.grid.name}`);
3849
3858
  const responseData = response.data.data;
3850
- return responseData.length && responseData[0]
3859
+ return this.checkLayoutsData(responseData.length && responseData[0]
3851
3860
  ? responseData[0].layouts
3852
- : responseData.layouts || {};
3861
+ : responseData.layouts);
3853
3862
  }
3854
3863
  return JSON.parse(localStorage.getItem(this.grid.name) || '{}');
3855
3864
  });
@@ -3862,8 +3871,91 @@ class TekGridLayoutOptions extends ComponentRender {
3862
3871
  }
3863
3872
  return '';
3864
3873
  }
3874
+ layoutHasFilter(layout) {
3875
+ const layoutValue = typeof layout === 'string' ? this.layouts[layout] : layout;
3876
+ return Object.keys(layoutValue.filter || {}).length
3877
+ || Object.keys(layoutValue.dynamicFilter || {}).length;
3878
+ }
3865
3879
  newLayout(layout) {
3866
- this.fixColumns(layout);
3880
+ this.newLayoutValue = layout;
3881
+ if (this.layoutHasFilter(layout)) {
3882
+ if (!this.confirmFilterModal) {
3883
+ this.confirmFilterModal = ModalService.create({
3884
+ name: 'tekgrid_layout_filter_modal',
3885
+ persistent: true,
3886
+ children: [
3887
+ {
3888
+ name: 'tekgrid_layout_filter_header',
3889
+ component: 'ZdHeader',
3890
+ height: 32,
3891
+ cssClass: 'zd-mb-4',
3892
+ color: 'transparent',
3893
+ padless: true,
3894
+ elevation: 0,
3895
+ leftSlot: [
3896
+ {
3897
+ name: 'tekgrid_layout_filter_title',
3898
+ component: 'ZdText',
3899
+ text: I18n.translate('TEKGRID_LAYOUT_FILTER_CONFIRMATION'),
3900
+ cssClass: 'zd-theme-font-title',
3901
+ },
3902
+ ],
3903
+ rightSlot: [
3904
+ {
3905
+ name: 'closeModalButton',
3906
+ component: 'ZdModalCloseButton',
3907
+ small: true,
3908
+ modalName: 'tekgrid_layout_filter_modal',
3909
+ },
3910
+ ],
3911
+ },
3912
+ {
3913
+ name: 'tekgrid_layout_filter_footer',
3914
+ component: 'ZdFooter',
3915
+ color: 'transparent',
3916
+ padless: true,
3917
+ rightSlot: [
3918
+ {
3919
+ name: 'tekgrid_layout_filter_no',
3920
+ component: 'ZdButton',
3921
+ label: I18n.translate('NO'),
3922
+ outline: true,
3923
+ cssClass: 'zd-mr-2',
3924
+ events: {
3925
+ click: () => {
3926
+ this.doNewLayout(this.newLayoutValue, false);
3927
+ this.confirmFilterModal.hide();
3928
+ },
3929
+ },
3930
+ },
3931
+ {
3932
+ name: 'tekgrid_layout_filter_yes',
3933
+ component: 'ZdButton',
3934
+ label: I18n.translate('YES'),
3935
+ cssClass: 'zd-mr-2',
3936
+ events: {
3937
+ click: () => {
3938
+ this.doNewLayout(this.newLayoutValue, true);
3939
+ this.confirmFilterModal.hide();
3940
+ },
3941
+ },
3942
+ },
3943
+ ],
3944
+ },
3945
+ ],
3946
+ });
3947
+ }
3948
+ this.confirmFilterModal.show();
3949
+ }
3950
+ else {
3951
+ this.doNewLayout(layout);
3952
+ }
3953
+ }
3954
+ doNewLayout(layout, saveFilter = true) {
3955
+ if (!saveFilter) {
3956
+ layout.filter = undefined;
3957
+ layout.dynamicFilter = undefined;
3958
+ }
3867
3959
  this.currentLayoutName = layout.name;
3868
3960
  this.addLayout(layout);
3869
3961
  this.layoutEdited = false;
@@ -3881,6 +3973,14 @@ class TekGridLayoutOptions extends ComponentRender {
3881
3973
  this.layoutEdited = false;
3882
3974
  }
3883
3975
  applyLayout(name, save = true) {
3976
+ if (this.grid.events.beforeApplyLayout) {
3977
+ const canApply = this.grid.callEvent('beforeApplyLayout', {
3978
+ component: this.grid,
3979
+ layout: this.layouts[name],
3980
+ });
3981
+ if (canApply === false)
3982
+ return;
3983
+ }
3884
3984
  this.currentLayoutName = name;
3885
3985
  const layoutSelected = this.layouts[name];
3886
3986
  if (this.viewApplyLayout) {
@@ -59,7 +59,7 @@
59
59
  const formChanged = valueKeys.some((key) => {
60
60
  const currValue = this.value[key];
61
61
  const prevValue = this.beforeEditValue ? this.beforeEditValue[key] : null;
62
- return this.nullCast(currValue) !== this.nullCast(prevValue);
62
+ return !core.Utils.isEqual(currValue, prevValue);
63
63
  });
64
64
  if (!formChanged) {
65
65
  this.editing = false;
@@ -68,9 +68,6 @@
68
68
  this.value[child.name] = value;
69
69
  this.editing = true;
70
70
  }
71
- nullCast(value) {
72
- return ['', null, undefined].includes(value) ? null : value;
73
- }
74
71
  onMounted(element) {
75
72
  this.cancelEdit();
76
73
  super.onMounted(element);
@@ -1342,6 +1339,9 @@
1342
1339
  TEKGRID_WITH_GROUPS: '(Com grupos)',
1343
1340
  TEKGRID_GRID_MIRROR: '(Espelho do grid)',
1344
1341
  TEKGRID_NO_DATA: 'Não há dados para exportar',
1342
+ TEKGRID_LAYOUT_FILTER_CONFIRMATION: 'O layout possui informações de filtro. '
1343
+ + 'Deseja salvar o filtro com o layout?',
1344
+ TEKGRID_LAYOUT_HAS_FILTER: 'possui filtro',
1345
1345
  },
1346
1346
  },
1347
1347
  'en-US': {
@@ -1416,6 +1416,9 @@
1416
1416
  TEKGRID_WITH_GROUPS: '(With groups)',
1417
1417
  TEKGRID_GRID_MIRROR: '(Grid mirror)',
1418
1418
  TEKGRID_NO_DATA: 'There is no data to export',
1419
+ TEKGRID_LAYOUT_FILTER_CONFIRMATION: 'The layout contains filter information. '
1420
+ + 'Do you want to save the filter with the layout?',
1421
+ TEKGRID_LAYOUT_HAS_FILTER: 'has filter',
1419
1422
  },
1420
1423
  },
1421
1424
  'es-CL': {
@@ -1490,6 +1493,9 @@
1490
1493
  TEKGRID_WITH_GROUPS: '(Con grupos)',
1491
1494
  TEKGRID_GRID_MIRROR: '(Espejo de grid)',
1492
1495
  TEKGRID_NO_DATA: 'No hay datos para exportar',
1496
+ TEKGRID_LAYOUT_FILTER_CONFIRMATION: 'La disposición contiene información de filtro. '
1497
+ + '¿Desea guardar el filtro junto con la disposición?',
1498
+ TEKGRID_LAYOUT_HAS_FILTER: 'contiene filtro',
1493
1499
  },
1494
1500
  },
1495
1501
  });
@@ -3841,6 +3847,9 @@
3841
3847
  }
3842
3848
  });
3843
3849
  }
3850
+ checkLayoutsData(data) {
3851
+ return Object.assign(Object.assign({}, data), { layouts: Array.isArray(data === null || data === void 0 ? void 0 : data.layouts) ? {} : ((data === null || data === void 0 ? void 0 : data.layouts) || {}) });
3852
+ }
3844
3853
  loadLayoutsInfo() {
3845
3854
  return __awaiter(this, void 0, void 0, function* () {
3846
3855
  const eventFunction = this.events.loadLayouts || this.grid.events.loadLayouts;
@@ -3851,9 +3860,9 @@
3851
3860
  const route = core.Config.loadGridLayoutsEndPoint;
3852
3861
  const response = yield core.Http.get(`${route}?id=${this.grid.name}`);
3853
3862
  const responseData = response.data.data;
3854
- return responseData.length && responseData[0]
3863
+ return this.checkLayoutsData(responseData.length && responseData[0]
3855
3864
  ? responseData[0].layouts
3856
- : responseData.layouts || {};
3865
+ : responseData.layouts);
3857
3866
  }
3858
3867
  return JSON.parse(localStorage.getItem(this.grid.name) || '{}');
3859
3868
  });
@@ -3866,8 +3875,91 @@
3866
3875
  }
3867
3876
  return '';
3868
3877
  }
3878
+ layoutHasFilter(layout) {
3879
+ const layoutValue = typeof layout === 'string' ? this.layouts[layout] : layout;
3880
+ return Object.keys(layoutValue.filter || {}).length
3881
+ || Object.keys(layoutValue.dynamicFilter || {}).length;
3882
+ }
3869
3883
  newLayout(layout) {
3870
- this.fixColumns(layout);
3884
+ this.newLayoutValue = layout;
3885
+ if (this.layoutHasFilter(layout)) {
3886
+ if (!this.confirmFilterModal) {
3887
+ this.confirmFilterModal = common.ModalService.create({
3888
+ name: 'tekgrid_layout_filter_modal',
3889
+ persistent: true,
3890
+ children: [
3891
+ {
3892
+ name: 'tekgrid_layout_filter_header',
3893
+ component: 'ZdHeader',
3894
+ height: 32,
3895
+ cssClass: 'zd-mb-4',
3896
+ color: 'transparent',
3897
+ padless: true,
3898
+ elevation: 0,
3899
+ leftSlot: [
3900
+ {
3901
+ name: 'tekgrid_layout_filter_title',
3902
+ component: 'ZdText',
3903
+ text: core.I18n.translate('TEKGRID_LAYOUT_FILTER_CONFIRMATION'),
3904
+ cssClass: 'zd-theme-font-title',
3905
+ },
3906
+ ],
3907
+ rightSlot: [
3908
+ {
3909
+ name: 'closeModalButton',
3910
+ component: 'ZdModalCloseButton',
3911
+ small: true,
3912
+ modalName: 'tekgrid_layout_filter_modal',
3913
+ },
3914
+ ],
3915
+ },
3916
+ {
3917
+ name: 'tekgrid_layout_filter_footer',
3918
+ component: 'ZdFooter',
3919
+ color: 'transparent',
3920
+ padless: true,
3921
+ rightSlot: [
3922
+ {
3923
+ name: 'tekgrid_layout_filter_no',
3924
+ component: 'ZdButton',
3925
+ label: core.I18n.translate('NO'),
3926
+ outline: true,
3927
+ cssClass: 'zd-mr-2',
3928
+ events: {
3929
+ click: () => {
3930
+ this.doNewLayout(this.newLayoutValue, false);
3931
+ this.confirmFilterModal.hide();
3932
+ },
3933
+ },
3934
+ },
3935
+ {
3936
+ name: 'tekgrid_layout_filter_yes',
3937
+ component: 'ZdButton',
3938
+ label: core.I18n.translate('YES'),
3939
+ cssClass: 'zd-mr-2',
3940
+ events: {
3941
+ click: () => {
3942
+ this.doNewLayout(this.newLayoutValue, true);
3943
+ this.confirmFilterModal.hide();
3944
+ },
3945
+ },
3946
+ },
3947
+ ],
3948
+ },
3949
+ ],
3950
+ });
3951
+ }
3952
+ this.confirmFilterModal.show();
3953
+ }
3954
+ else {
3955
+ this.doNewLayout(layout);
3956
+ }
3957
+ }
3958
+ doNewLayout(layout, saveFilter = true) {
3959
+ if (!saveFilter) {
3960
+ layout.filter = undefined;
3961
+ layout.dynamicFilter = undefined;
3962
+ }
3871
3963
  this.currentLayoutName = layout.name;
3872
3964
  this.addLayout(layout);
3873
3965
  this.layoutEdited = false;
@@ -3885,6 +3977,14 @@
3885
3977
  this.layoutEdited = false;
3886
3978
  }
3887
3979
  applyLayout(name, save = true) {
3980
+ if (this.grid.events.beforeApplyLayout) {
3981
+ const canApply = this.grid.callEvent('beforeApplyLayout', {
3982
+ component: this.grid,
3983
+ layout: this.layouts[name],
3984
+ });
3985
+ if (canApply === false)
3986
+ return;
3987
+ }
3888
3988
  this.currentLayoutName = name;
3889
3989
  const layoutSelected = this.layouts[name];
3890
3990
  if (this.viewApplyLayout) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zeedhi/teknisa-components-common",
3
- "version": "1.124.0",
3
+ "version": "1.126.0",
4
4
  "description": "Teknisa Components Common",
5
5
  "author": "Zeedhi <zeedhi@teknisa.com>",
6
6
  "license": "ISC",
@@ -18,7 +18,7 @@
18
18
  "watch": "npm run build -- -w"
19
19
  },
20
20
  "dependencies": {
21
- "@zeedhi/zd-drag-grid-common": "<=1.0.6",
21
+ "@zeedhi/zd-drag-grid-common": "^1.0.6",
22
22
  "@zeedhi/zd-user-info-common": "^1.3.2",
23
23
  "lodash.debounce": "4.0.*",
24
24
  "lodash.get": "4.4.*",
@@ -32,5 +32,5 @@
32
32
  "peerDependencies": {
33
33
  "@zeedhi/core": "^1.97.0"
34
34
  },
35
- "gitHead": "c977a14e03d34f5a1171cfe15cc4aff1a84a8a83"
35
+ "gitHead": "8783f8a1fc5b3ee71dc7bc21662065f9e5e7c653"
36
36
  }
@@ -1,11 +1,15 @@
1
- import { Grid, Tag } from '@zeedhi/common';
1
+ import {
2
+ Grid, Tag, Button, ModalService, IModal, Modal,
3
+ } from '@zeedhi/common';
2
4
  import { Config, Http } from '@zeedhi/core';
3
5
  import {
4
6
  ITekConfig,
7
+ ITekGridApplyLayoutEventParams,
5
8
  ITekGridLayoutInfo,
6
9
  TekGrid,
7
10
  TekGridLayoutOptions,
8
11
  } from '../../../../src';
12
+ import { setClick } from '../../../__helpers__';
9
13
 
10
14
  let savedLayouts: string = '';
11
15
  const testLayouts: ITekGridLayoutInfo = {
@@ -379,6 +383,65 @@ describe('LayoutOptions', () => {
379
383
  layouts: { 'Name first': newLayout },
380
384
  }));
381
385
  });
386
+
387
+ it('should add new layout with filter', () => {
388
+ const newLayout1 = {
389
+ name: 'teste1',
390
+ filter: { name: '1' },
391
+ };
392
+ const newLayout2 = {
393
+ name: 'teste2',
394
+ filter: { name: '1' },
395
+ };
396
+ const tag = new Tag({
397
+ name: 'toolbar',
398
+ component: 'ZdTag',
399
+ tag: 'span',
400
+ });
401
+ const grid = new TekGrid({
402
+ name: 'grid',
403
+ component: 'TekGrid',
404
+ columns: [
405
+ { name: 'id' },
406
+ { name: 'name' },
407
+ { name: 'salary' },
408
+ ],
409
+ });
410
+ const instance = new TekGridLayoutOptions({ name: 'layout', component: 'TekGridLayoutOptions' });
411
+ instance.parent = tag;
412
+ tag.parent = grid;
413
+
414
+ instance.onMounted({} as HTMLElement);
415
+
416
+ let yesButton!: Button;
417
+ let noButton!: Button;
418
+
419
+ const modalServiceCreateSpy = jest.spyOn(ModalService, 'create').mockImplementation((modal: IModal) => {
420
+ const newModal = new Modal(modal);
421
+ noButton = new Button(newModal.children[1].rightSlot[0]);
422
+ yesButton = new Button(newModal.children[1].rightSlot[1]);
423
+ return newModal;
424
+ });
425
+
426
+ instance.newLayout(newLayout1);
427
+ setClick(yesButton!);
428
+
429
+ expect(instance.currentLayoutName).toBe('teste1');
430
+ expect(instance.layoutNames).toEqual(['teste1']);
431
+ expect(instance.layouts.teste1).toEqual(newLayout1);
432
+ expect(instance.layoutHasFilter('teste1')).toBeTruthy();
433
+
434
+ instance.newLayout(newLayout2);
435
+ setClick(noButton!);
436
+
437
+ expect(instance.currentLayoutName).toBe('teste2');
438
+ expect(instance.layoutNames).toEqual(['teste1', 'teste2']);
439
+ expect(instance.layouts.teste2.filter).toBeUndefined();
440
+ expect(instance.layouts.teste2.dynamicFilter).toBeUndefined();
441
+ expect(instance.layoutHasFilter('teste2')).toBeFalsy();
442
+
443
+ modalServiceCreateSpy.mockReset();
444
+ });
382
445
  });
383
446
 
384
447
  describe('addLayout()', () => {
@@ -499,6 +562,45 @@ describe('LayoutOptions', () => {
499
562
  expect(instance.currentLayoutName).toBe('Name first');
500
563
  expect(eventSavedLayouts.currentLayoutName).toBe('Name first');
501
564
  });
565
+
566
+ it('should call beforeApplyLayout', async () => {
567
+ const tag = new Tag({
568
+ name: 'toolbar',
569
+ component: 'ZdTag',
570
+ tag: 'span',
571
+ });
572
+ const grid = new TekGrid({
573
+ name: 'grid',
574
+ component: 'TekGrid',
575
+ columns: [
576
+ { name: 'id' },
577
+ { name: 'name' },
578
+ { name: 'salary' },
579
+ ],
580
+ events: {
581
+ beforeApplyLayout: ({ layout }: ITekGridApplyLayoutEventParams) => {
582
+ if (layout) layout.gridWidth = '740px';
583
+ return layout?.name === 'Name first';
584
+ },
585
+ },
586
+ });
587
+ const instance = new TekGridLayoutOptions({ name: 'layout', component: 'TekGridLayoutOptions' });
588
+ instance.parent = tag;
589
+ tag.parent = grid;
590
+
591
+ await instance.onMounted({} as HTMLElement);
592
+ instance.addLayout({
593
+ name: 'Name last',
594
+ });
595
+
596
+ expect(instance.currentLayoutName).toBe('');
597
+ instance.applyLayout('Name first');
598
+ expect(instance.currentLayoutName).toBe('Name first');
599
+ expect(instance.layouts['Name first'].gridWidth).toBe('740px');
600
+ instance.applyLayout('Name last');
601
+ expect(instance.currentLayoutName).toBe('Name first');
602
+ expect(instance.layouts['Name last'].gridWidth).toBe('740px');
603
+ });
502
604
  });
503
605
 
504
606
  describe('deleteLayout()', () => {
@@ -826,7 +928,7 @@ describe('LayoutOptions', () => {
826
928
  },
827
929
  };
828
930
 
829
- const spy = jest.spyOn(Http, 'get').mockImplementation(() => Promise.resolve({ data: { data: { layouts } } }));
931
+ let spy = jest.spyOn(Http, 'get').mockImplementation(() => Promise.resolve({ data: { data: { layouts } } }));
830
932
 
831
933
  await instance.onMounted({} as HTMLElement);
832
934
  await grid.onMounted({} as HTMLElement);
@@ -846,6 +948,20 @@ describe('LayoutOptions', () => {
846
948
  },
847
949
  });
848
950
  spy.mockReset();
951
+
952
+ // tratamento do erro no backend que esta retornando layouts como array vazio
953
+ instance.layouts = {};
954
+ spy = jest.spyOn(Http, 'get').mockImplementation(() => Promise.resolve({
955
+ data: { data: { layouts: { currentLayoutName: '', layouts: [] } } },
956
+ }));
957
+ await instance.onMounted({} as HTMLElement);
958
+ await grid.onMounted({} as HTMLElement);
959
+
960
+ await flushPromises();
961
+ expect(spy).toBeCalled();
962
+ expect(instance.layouts).toEqual({});
963
+ spy.mockReset();
964
+
849
965
  (Config as ITekConfig).loadGridLayoutsEndPoint = '';
850
966
  });
851
967
 
@@ -37,7 +37,6 @@ export declare class CrudForm extends Form implements ICrudForm {
37
37
  * @param value input value
38
38
  */
39
39
  updateChild(child: Component, value: any): void;
40
- private nullCast;
41
40
  onMounted(element: HTMLElement): void;
42
41
  /**
43
42
  * Form is focused
@@ -4,18 +4,22 @@ import { IDynamicFilterItem, TekGrid, TekGridLayoutOptions, TekTreeGrid } from '
4
4
  export interface ITekGridLayoutEventParams extends IEventParam<ITekGrid> {
5
5
  layouts: ITekGridLayoutInfo;
6
6
  }
7
+ export interface ITekGridApplyLayoutEventParams extends IEventParam<ITekGrid> {
8
+ layout?: ITekGridLayout;
9
+ }
7
10
  export interface ITekGridCalcSummaryEventParams extends IEventParam<ITekGrid> {
8
11
  summary: ITekGridSummary;
9
12
  columnName: string;
10
13
  rowValue: IDictionary<any>;
11
14
  }
12
15
  export declare type ITekGridEvent<T> = (event: T) => Promise<any>;
13
- export interface ITekGridEvents<T = IEventParam<any> | ITekGridLayoutEventParams | ITekGridCalcSummaryEventParams> extends IComponentEvents<T> {
16
+ export interface ITekGridEvents<T = IEventParam<any> | ITekGridLayoutEventParams | ITekGridApplyLayoutEventParams | ITekGridCalcSummaryEventParams> extends IComponentEvents<T> {
14
17
  addClick?: EventDef<T>;
15
18
  afterCancel?: EventDef<T>;
16
19
  afterDelete?: EventDef<T>;
17
20
  afterSave?: EventDef<T>;
18
21
  beforeApplyFilter?: EventDef<T>;
22
+ beforeApplyLayout?: EventDef<T>;
19
23
  beforeCancel?: EventDef<T>;
20
24
  beforeDelete?: EventDef<T>;
21
25
  beforeSave?: EventDef<T>;
@@ -17,9 +17,14 @@ export declare class TekGridLayoutOptions extends ComponentRender implements ITe
17
17
  grid: Grid;
18
18
  private getParentGrid;
19
19
  onMounted(element: HTMLElement): Promise<void>;
20
+ private checkLayoutsData;
20
21
  protected loadLayoutsInfo(): Promise<any>;
21
22
  getHelperValue(column: any): string | (string | undefined)[] | undefined;
23
+ layoutHasFilter(layout: string | ITekGridLayout): number;
24
+ private confirmFilterModal?;
25
+ private newLayoutValue?;
22
26
  newLayout(layout: ITekGridLayout): void;
27
+ private doNewLayout;
23
28
  addLayout(layout: ITekGridLayout): void;
24
29
  discardChanges(): void;
25
30
  applyLayout(name: string, save?: boolean): void;