@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
@@ -635,6 +635,18 @@ OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
635
635
  PERFORMANCE OF THIS SOFTWARE.
636
636
  ***************************************************************************** */
637
637
 
638
+ function __rest(s, e) {
639
+ var t = {};
640
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
641
+ t[p] = s[p];
642
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
643
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
644
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
645
+ t[p[i]] = s[p[i]];
646
+ }
647
+ return t;
648
+ }
649
+
638
650
  function __decorate(decorators, target, key, desc) {
639
651
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
640
652
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
@@ -711,98 +723,8 @@ class TekGridDeleteRowsError extends Error {
711
723
  }
712
724
  }
713
725
 
714
- class ButtonOption {
715
- constructor(config) {
716
- this.config = config;
717
- }
718
- buildComponent(grid) {
719
- const { type, label, portrait = true, iconName, } = this.config;
720
- const orientation = portrait ? 'portrait' : 'landscape';
721
- return {
722
- label,
723
- iconName,
724
- name: `${grid.name}_export_${type}_${orientation}`,
725
- component: 'ZdButton',
726
- flat: true,
727
- events: {
728
- click: () => grid.getReport(type, portrait),
729
- },
730
- };
731
- }
732
- }
733
-
734
- class MultiOption {
735
- constructor(config) {
736
- this.config = config;
737
- }
738
- formatName(id, type, grid) {
739
- return `${grid.name}_export_${type}_${id}`;
740
- }
741
- buildTooltip(option, type, grid) {
742
- const { label } = option;
743
- return {
744
- name: this.formatName(`tooltip_${label}`, type, grid),
745
- component: 'ZdTooltip',
746
- bottom: true,
747
- label,
748
- children: [],
749
- };
750
- }
751
- buildButton(option, type, grid) {
752
- const { cssClass, label, iconName, reportParams, } = option;
753
- const { portrait: optionPortrait, rowObj } = reportParams || {};
754
- return {
755
- name: this.formatName(`button_${label}`, type, grid),
756
- component: 'ZdButton',
757
- cssClass,
758
- icon: true,
759
- iconName,
760
- events: {
761
- click: () => grid.getReport(type, optionPortrait, rowObj),
762
- },
763
- };
764
- }
765
- buildDivider(option, type, grid) {
766
- const { label } = option;
767
- return {
768
- name: this.formatName(`divider_${label}`, type, grid),
769
- component: 'ZdDivider',
770
- cssClass: 'zd-my-1',
771
- vertical: true,
772
- };
773
- }
774
- buildComponent(grid) {
775
- const { type, label, multiOption, } = this.config;
776
- const optionComponents = multiOption.map((option) => ([
777
- Object.assign(Object.assign({}, this.buildTooltip(option, type, grid)), { children: [
778
- this.buildButton(option, type, grid),
779
- ] }),
780
- this.buildDivider(option, type, grid),
781
- ]))
782
- .flat();
783
- optionComponents.pop();
784
- const text = {
785
- name: this.formatName('text', type, grid),
786
- component: 'ZdText',
787
- cssClass: 'zd-display-flex zd-align-center zd-flex-grow-1 tek-grid-export-multioption-text',
788
- events: {
789
- click: ({ event }) => event === null || event === void 0 ? void 0 : event.stopPropagation(),
790
- },
791
- text: label || '',
792
- };
793
- const result = {
794
- name: this.formatName('row', type, grid),
795
- component: 'ZdRow',
796
- cssClass: 'zd-display-flex zd-ma-0 zd-py-0 zd-gap-x-1 tek-grid-export-multioption-row',
797
- children: [text, ...optionComponents],
798
- };
799
- return result;
800
- }
801
- }
802
-
803
726
  class GridBase {
804
727
  constructor(grid) {
805
- this.exportConfigButtons = [];
806
728
  this.defaultToolbar = {};
807
729
  this.atoms = {
808
730
  TITLE: '_gridTitle',
@@ -824,20 +746,8 @@ class GridBase {
824
746
  ACTIONS_DROPDOWN: '_actions_dropdown',
825
747
  };
826
748
  this.grid = grid;
827
- this.exportConfigButtons = this.getExportConfigButtons();
828
749
  this.initializeDefaultToolbarItems();
829
750
  }
830
- getOption(config) {
831
- if (config.multiOption)
832
- return new MultiOption(config);
833
- return new ButtonOption(config);
834
- }
835
- getExportConfigButtons() {
836
- return this.grid.exportConfig.map((config) => {
837
- const option = this.getOption(config);
838
- return option.buildComponent(this.grid);
839
- });
840
- }
841
751
  initializeDefaultToolbarItems() {
842
752
  this.defaultToolbar = {
843
753
  title: () => ({
@@ -945,7 +855,7 @@ class GridBase {
945
855
  name: `${this.grid.name}_columnsButton`,
946
856
  component: 'TekGridColumnsButton',
947
857
  isVisible: `{{GridController_${this.grid.componentId}.showColumnsButton}}`,
948
- iterableComponentName: this.grid.name,
858
+ gridName: this.grid.name,
949
859
  hideGroups: !(this.grid instanceof TekGrid),
950
860
  ignoreColumns: `{{GridController_${this.grid.componentId}.columnsButtonIgnore}}`,
951
861
  },
@@ -954,21 +864,15 @@ class GridBase {
954
864
  layoutOptions: () => ({
955
865
  name: `${this.grid.name}_layout_options`,
956
866
  component: 'TekGridLayoutOptions',
867
+ gridName: this.grid.name,
957
868
  isVisible: `{{GridController_${this.grid.componentId}.showLayoutOptionsButton}}`,
958
869
  }),
959
870
  exportDropdown: () => ({
960
871
  name: `${this.grid.name}_export_dropdown`,
961
- component: 'ZdDropdown',
962
- cssClass: 'tekgrid-actions-dropdown',
963
- offsetY: true,
964
- activator: {
965
- name: `${this.grid.name}_exportButton`,
966
- component: 'ZdButton',
967
- icon: true,
968
- iconName: 'fileDownload',
969
- isVisible: `{{GridController_${this.grid.componentId}.showExportButton}}`,
970
- },
971
- children: this.grid.exportActions || this.exportConfigButtons,
872
+ component: 'TekGridExportButton',
873
+ grid: this.grid,
874
+ gridName: this.grid.name,
875
+ isVisible: `{{GridController_${this.grid.componentId}.showExportButton}}`,
972
876
  }),
973
877
  actionsDivider: (index) => ({
974
878
  name: `${this.grid.name}_actions_divider${index}`,
@@ -1137,7 +1041,10 @@ class GridBase {
1137
1041
  return toolbarItems;
1138
1042
  }
1139
1043
  loadFilterButton({ component }) {
1140
- this.filterButton = component;
1044
+ this.registerFilterButton(component);
1045
+ }
1046
+ registerFilterButton(filterButton) {
1047
+ this.filterButton = filterButton;
1141
1048
  }
1142
1049
  hideButtonClick({ event }) {
1143
1050
  if (!event.defaultPrevented) {
@@ -1239,7 +1146,14 @@ class GridBase {
1239
1146
  return __awaiter(this, void 0, void 0, function* () {
1240
1147
  const { datasource } = this.grid;
1241
1148
  if (datasource instanceof TekRestDatasource || datasource instanceof TekMemoryDatasource) {
1242
- const lookupColumns = this.grid.columns.filter((column) => !!column.componentProps.datasource && !column.skipLookupSearch);
1149
+ const searchIn = datasource.searchIn || [];
1150
+ const lookupColumns = this.grid.columns.filter((column) => {
1151
+ if (!column.componentProps.datasource || column.skipLookupSearch)
1152
+ return false;
1153
+ if (searchIn.length > 0)
1154
+ return searchIn.indexOf(column.name) !== -1;
1155
+ return true;
1156
+ });
1243
1157
  const searchJoin = {};
1244
1158
  if (search) {
1245
1159
  const promises = lookupColumns.map((column) => __awaiter(this, void 0, void 0, function* () {
@@ -1577,6 +1491,95 @@ class GridController {
1577
1491
  }
1578
1492
  }
1579
1493
 
1494
+ class ButtonOption {
1495
+ constructor(config) {
1496
+ this.config = config;
1497
+ }
1498
+ buildComponent(grid) {
1499
+ const { type, label, portrait = true, iconName, } = this.config;
1500
+ const orientation = portrait ? 'portrait' : 'landscape';
1501
+ return {
1502
+ label,
1503
+ iconName,
1504
+ name: `${grid.name}_export_${type}_${orientation}`,
1505
+ component: 'ZdButton',
1506
+ flat: true,
1507
+ events: {
1508
+ click: () => grid.getReport(type, portrait),
1509
+ },
1510
+ };
1511
+ }
1512
+ }
1513
+
1514
+ class MultiOption {
1515
+ constructor(config) {
1516
+ this.config = config;
1517
+ }
1518
+ formatName(id, type, grid) {
1519
+ return `${grid.name}_export_${type}_${id}`;
1520
+ }
1521
+ buildTooltip(option, type, grid) {
1522
+ const { label } = option;
1523
+ return {
1524
+ name: this.formatName(`tooltip_${label}`, type, grid),
1525
+ component: 'ZdTooltip',
1526
+ bottom: true,
1527
+ label,
1528
+ children: [],
1529
+ };
1530
+ }
1531
+ buildButton(option, type, grid) {
1532
+ const { cssClass, label, iconName, reportParams, } = option;
1533
+ const { portrait: optionPortrait, rowObj } = reportParams || {};
1534
+ return {
1535
+ name: this.formatName(`button_${label}`, type, grid),
1536
+ component: 'ZdButton',
1537
+ cssClass,
1538
+ icon: true,
1539
+ iconName,
1540
+ events: {
1541
+ click: () => grid.getReport(type, optionPortrait, rowObj),
1542
+ },
1543
+ };
1544
+ }
1545
+ buildDivider(option, type, grid) {
1546
+ const { label } = option;
1547
+ return {
1548
+ name: this.formatName(`divider_${label}`, type, grid),
1549
+ component: 'ZdDivider',
1550
+ cssClass: 'zd-my-1',
1551
+ vertical: true,
1552
+ };
1553
+ }
1554
+ buildComponent(grid) {
1555
+ const { type, label, multiOption, } = this.config;
1556
+ const optionComponents = multiOption.map((option) => ([
1557
+ Object.assign(Object.assign({}, this.buildTooltip(option, type, grid)), { children: [
1558
+ this.buildButton(option, type, grid),
1559
+ ] }),
1560
+ this.buildDivider(option, type, grid),
1561
+ ]))
1562
+ .flat();
1563
+ optionComponents.pop();
1564
+ const text = {
1565
+ name: this.formatName('text', type, grid),
1566
+ component: 'ZdText',
1567
+ cssClass: 'zd-display-flex zd-align-center zd-flex-grow-1 tek-grid-export-multioption-text',
1568
+ events: {
1569
+ click: ({ event }) => event === null || event === void 0 ? void 0 : event.stopPropagation(),
1570
+ },
1571
+ text: label || '',
1572
+ };
1573
+ const result = {
1574
+ name: this.formatName('row', type, grid),
1575
+ component: 'ZdRow',
1576
+ cssClass: 'zd-display-flex zd-ma-0 zd-py-0 zd-gap-x-1 tek-grid-export-multioption-row',
1577
+ children: [text, ...optionComponents],
1578
+ };
1579
+ return result;
1580
+ }
1581
+ }
1582
+
1580
1583
  /**
1581
1584
  * Extracts properties from an object based on a list of properties
1582
1585
  * @param obj object whose properties will be extracted
@@ -1593,6 +1596,40 @@ const extractProperties = (obj, props) => {
1593
1596
  return result;
1594
1597
  };
1595
1598
 
1599
+ const EMPTY_VALUE = null;
1600
+ function cloneComparableValue(value) {
1601
+ return JSON.parse(JSON.stringify(value));
1602
+ }
1603
+ function normalizeComparableValue(value) {
1604
+ if (value === undefined || value === null || value === '') {
1605
+ return EMPTY_VALUE;
1606
+ }
1607
+ if (Array.isArray(value)) {
1608
+ if (!value.length)
1609
+ return EMPTY_VALUE;
1610
+ return value.map((item) => normalizeComparableValue(item));
1611
+ }
1612
+ if (value && typeof value === 'object') {
1613
+ const normalizedValue = Object.keys(value)
1614
+ .sort()
1615
+ .reduce((result, key) => {
1616
+ const normalizedItem = normalizeComparableValue(value[key]);
1617
+ if (normalizedItem !== EMPTY_VALUE) {
1618
+ result[key] = normalizedItem;
1619
+ }
1620
+ return result;
1621
+ }, {});
1622
+ if (!Object.keys(normalizedValue).length)
1623
+ return EMPTY_VALUE;
1624
+ return normalizedValue;
1625
+ }
1626
+ return value;
1627
+ }
1628
+ function areObjectsEqual(first, second) {
1629
+ return JSON.stringify(normalizeComparableValue(first))
1630
+ === JSON.stringify(normalizeComparableValue(second));
1631
+ }
1632
+
1596
1633
  const DynamicFilterOperations = {
1597
1634
  CONTAINS: true,
1598
1635
  NOT_CONTAINS: true,
@@ -2414,7 +2451,7 @@ class TekGrid extends GridEditable {
2414
2451
  */
2415
2452
  this.tasksBeforeLoad = [];
2416
2453
  this.request = debounce(() => { this.datasource.get(); }, 500);
2417
- this.updateGrouping = debounce((lazyLoad = false) => {
2454
+ this.updateGrouping = debounce((lazyLoad = this.defaultLazy) => {
2418
2455
  this.updateGroupedData(lazyLoad);
2419
2456
  }, 100);
2420
2457
  this.title = this.getInitValue('title', props.title, this.title);
@@ -2996,44 +3033,38 @@ class TekGrid extends GridEditable {
2996
3033
  super.navigateDown();
2997
3034
  return;
2998
3035
  }
2999
- if (this.cellSelection && this.viewNavigate) {
3036
+ if (this.viewNavigate) {
3000
3037
  this.viewNavigate('down');
3001
3038
  return;
3002
3039
  }
3003
- const { index } = params;
3004
- if (!this.groupedData.length || index === this.groupedData.length)
3005
- return;
3006
- const { uniqueKey, currentRow } = this.datasource;
3007
- const rowIndex = index !== undefined
3008
- ? index
3009
- : this.groupedData.findIndex((row) => {
3010
- if (currentRow.group) {
3011
- return row.group && row.groupValue === currentRow.groupValue;
3012
- }
3013
- return row[uniqueKey] && row[uniqueKey] === currentRow[uniqueKey];
3014
- });
3015
- const newRow = this.groupedData[rowIndex + 1];
3016
- if (!newRow || !this.isItemVisible(newRow) || newRow.groupFooter) {
3017
- this.navigateDown({ index: rowIndex + 1 });
3018
- return;
3019
- }
3020
- this.datasource.currentRow = newRow;
3040
+ this.navigateGroupedDatasource(false, params);
3021
3041
  }
3022
3042
  navigateUp(params) {
3023
3043
  if (!this.isGrouped()) {
3024
3044
  super.navigateUp();
3025
3045
  return;
3026
3046
  }
3027
- if (this.cellSelection && this.viewNavigate) {
3047
+ if (this.viewNavigate) {
3028
3048
  this.viewNavigate('up');
3029
3049
  return;
3030
3050
  }
3051
+ this.navigateGroupedDatasource(true, params);
3052
+ }
3053
+ navigateDatasource(up) {
3054
+ if (!this.isGrouped()) {
3055
+ super.navigateDatasource(up);
3056
+ return;
3057
+ }
3058
+ this.navigateGroupedDatasource(up);
3059
+ }
3060
+ navigateGroupedDatasource(up, params = {}) {
3031
3061
  const { index } = params;
3032
- if (!this.groupedData.length || index === -1)
3062
+ if (!this.groupedData.length
3063
+ || (!up && index === this.groupedData.length)
3064
+ || (up && index === -1))
3033
3065
  return;
3034
3066
  const { uniqueKey, currentRow } = this.datasource;
3035
- let rowIndex;
3036
- rowIndex = index !== undefined
3067
+ let rowIndex = index !== undefined
3037
3068
  ? index
3038
3069
  : this.groupedData.findIndex((row) => {
3039
3070
  if (currentRow.group) {
@@ -3041,11 +3072,12 @@ class TekGrid extends GridEditable {
3041
3072
  }
3042
3073
  return row[uniqueKey] && row[uniqueKey] === currentRow[uniqueKey];
3043
3074
  });
3044
- if (rowIndex === -1)
3075
+ if (up && rowIndex === -1)
3045
3076
  rowIndex = this.groupedData.length;
3046
- const newRow = this.groupedData[rowIndex - 1];
3077
+ const nextIndex = rowIndex + (up ? -1 : 1);
3078
+ const newRow = this.groupedData[nextIndex];
3047
3079
  if (!newRow || !this.isItemVisible(newRow) || newRow.groupFooter) {
3048
- this.navigateUp({ index: rowIndex - 1 });
3080
+ this.navigateGroupedDatasource(up, { index: nextIndex });
3049
3081
  return;
3050
3082
  }
3051
3083
  this.datasource.currentRow = newRow;
@@ -3168,6 +3200,9 @@ class TekGrid extends GridEditable {
3168
3200
  getFilterInputs(columnName) {
3169
3201
  return this.gridBase.getFilterInputs(columnName);
3170
3202
  }
3203
+ registerFilterButton(filterButton) {
3204
+ this.gridBase.registerFilterButton(filterButton);
3205
+ }
3171
3206
  isColumnSearchable(column) {
3172
3207
  return column.searchable && (!this.searchVisibleOnly || column.isVisible || column.grouped);
3173
3208
  }
@@ -3376,16 +3411,14 @@ class TekGridColumnsButtonController extends IterableColumnsButtonController {
3376
3411
  */
3377
3412
  class TekGridColumnsButton extends IterableColumnsButton {
3378
3413
  constructor(props) {
3379
- super(props);
3414
+ super(Object.assign(Object.assign({}, props), { iterableComponentName: props.gridName || props.iterableComponentName }));
3380
3415
  this.hideGroups = false;
3381
3416
  this.aggregationDataSet = [];
3382
3417
  this.hideGroups = this.getInitValue('hideGroups', props.hideGroups, this.hideGroups);
3383
3418
  this.createAccessors();
3384
3419
  }
3385
- onCreated() {
3386
- super.onCreated();
3387
- this.controller = new TekGridColumnsButtonController(this.iterableComponent);
3388
- Loader.addController(`IterableColumnsButtonController_${this.componentId}`, this.controller);
3420
+ createController() {
3421
+ return new TekGridColumnsButtonController(this.iterableComponent);
3389
3422
  }
3390
3423
  getAggregationSelectData() {
3391
3424
  if (!this.aggregationDataSet.length) {
@@ -3398,6 +3431,67 @@ class TekGridColumnsButton extends IterableColumnsButton {
3398
3431
  }
3399
3432
  }
3400
3433
 
3434
+ /**
3435
+ * Base class for TekGrid export button/dropdown component.
3436
+ */
3437
+ class TekGridExportButton extends ComponentRender {
3438
+ constructor(props) {
3439
+ super(props);
3440
+ this.gridName = this.getInitValue('gridName', props.gridName, this.gridName);
3441
+ this.grid = this.getInitValue('grid', props.grid, this.grid);
3442
+ this.exportConfig = this.getInitValue('exportConfig', props.exportConfig, this.exportConfig);
3443
+ this.exportActions = this.getInitValue('exportActions', props.exportActions, this.exportActions);
3444
+ this.children = this.getInitValue('children', props.children, []);
3445
+ this.cssClass = this.getInitValue('cssClass', props.cssClass, this.cssClass);
3446
+ this.createAccessors();
3447
+ this.loadGrid();
3448
+ }
3449
+ getOption(config) {
3450
+ if (config.multiOption)
3451
+ return new MultiOption(config);
3452
+ return new ButtonOption(config);
3453
+ }
3454
+ getExportConfigButtons() {
3455
+ if (!this.grid)
3456
+ return [];
3457
+ const exportConfig = this.exportConfig || this.grid.exportConfig;
3458
+ return exportConfig.map((config) => {
3459
+ const option = this.getOption(config);
3460
+ return option.buildComponent(this.grid);
3461
+ });
3462
+ }
3463
+ loadChildren() {
3464
+ if (!this.grid)
3465
+ return;
3466
+ if (this.exportActions) {
3467
+ this.children = this.exportActions;
3468
+ return;
3469
+ }
3470
+ if (this.exportConfig) {
3471
+ this.children = this.getExportConfigButtons();
3472
+ return;
3473
+ }
3474
+ this.children = this.grid.exportActions || this.getExportConfigButtons();
3475
+ }
3476
+ loadGrid(gridName) {
3477
+ if (gridName)
3478
+ this.gridName = gridName;
3479
+ if (!this.grid && this.gridName) {
3480
+ const grid = Metadata.getInstances(this.gridName)[0];
3481
+ if (grid)
3482
+ this.grid = grid;
3483
+ }
3484
+ if (this.grid) {
3485
+ this.gridName = this.grid.name;
3486
+ this.loadChildren();
3487
+ }
3488
+ }
3489
+ onCreated() {
3490
+ super.onCreated();
3491
+ this.loadGrid();
3492
+ }
3493
+ }
3494
+
3401
3495
  class TekFilterHelper {
3402
3496
  static getLabel(name) {
3403
3497
  return DateHelper.getLabel(name);
@@ -3425,23 +3519,35 @@ class TekGridFilterButton extends Button {
3425
3519
  this.grid = this.getInitValue('grid', props.grid, undefined);
3426
3520
  this.showCheckboxAll = this.getInitValue('showCheckboxAll', props.showCheckboxAll, this.showCheckboxAll);
3427
3521
  this.createAccessors();
3428
- if (!this.grid)
3429
- this.loadGrid();
3522
+ this.loadGrid();
3430
3523
  }
3431
3524
  loadGrid(gridName) {
3432
3525
  if (gridName)
3433
3526
  this.gridName = gridName;
3434
- if (!this.gridName)
3435
- return;
3436
- this.grid = Metadata.getInstances(this.gridName)[0];
3527
+ if (!this.grid && this.gridName) {
3528
+ const grid = Metadata.getInstances(this.gridName)[0];
3529
+ if (grid)
3530
+ this.grid = grid;
3531
+ }
3532
+ if (this.grid) {
3533
+ this.gridName = this.grid.name;
3534
+ this.grid.registerFilterButton(this);
3535
+ }
3437
3536
  }
3438
3537
  click(event) {
3439
3538
  this.callEvent('click', { component: this, event });
3539
+ this.loadGrid();
3540
+ if (!this.grid)
3541
+ return;
3440
3542
  this.grid.callEvent('filterClick', { component: this.grid, event });
3441
3543
  if (!(event === null || event === void 0 ? void 0 : event.defaultPrevented)) {
3442
3544
  this.createFilterFromColumns.call(this);
3443
3545
  }
3444
3546
  }
3547
+ onCreated() {
3548
+ super.onCreated();
3549
+ this.loadGrid();
3550
+ }
3445
3551
  loadFilterValues({ component }) {
3446
3552
  const changedCompNames = [];
3447
3553
  const { datasource } = this.grid;
@@ -3497,7 +3603,8 @@ class TekGridFilterButton extends Button {
3497
3603
  });
3498
3604
  }
3499
3605
  hideFilterModal() {
3500
- this.filterModal.hide();
3606
+ if (this.filterModal)
3607
+ this.filterModal.hide();
3501
3608
  }
3502
3609
  destroyFilterModal() {
3503
3610
  if (this.filterModal)
@@ -3543,9 +3650,14 @@ class TekGridFilterButton extends Button {
3543
3650
  },
3544
3651
  {
3545
3652
  name: `${this.grid.name}-filter-close-button`,
3546
- component: 'ZdModalCloseButton',
3653
+ component: 'ZdButton',
3654
+ icon: true,
3655
+ iconName: 'close',
3656
+ flat: true,
3547
3657
  small: true,
3548
- modalName: `${this.grid.name}-filter-modal`,
3658
+ events: {
3659
+ click: this.hideFilterModal.bind(this),
3660
+ },
3549
3661
  },
3550
3662
  ],
3551
3663
  },
@@ -3691,15 +3803,20 @@ class TekGridFilterButton extends Button {
3691
3803
  this.setFilter(filter, event, datasource.setBaseFilter.bind(datasource));
3692
3804
  }
3693
3805
  else {
3806
+ const structuredFilter = {};
3694
3807
  Object.keys(formValue).forEach((item) => {
3695
3808
  let columnName = item.split(`${this.grid.name}-filter-AND-CONTAINS-`)[1];
3696
3809
  columnName = columnName.split('-').slice(0, -1).join('-'); // remove index
3697
- if (formValue[item]) {
3698
- filter[columnName] = formValue[item];
3810
+ const itemValue = formValue[item];
3811
+ if (itemValue && !(Array.isArray(itemValue) && !itemValue.length)) {
3812
+ filter[columnName] = itemValue;
3813
+ if (!structuredFilter[columnName])
3814
+ structuredFilter[columnName] = [];
3815
+ structuredFilter[columnName].push({ relation: 'AND', operation: 'CONTAINS', value: itemValue });
3699
3816
  }
3700
3817
  });
3701
3818
  datasource.filter = filter;
3702
- this.setFilter(filter, event, datasource.setBaseFilter.bind(datasource));
3819
+ this.setFilter(structuredFilter, event, datasource.setBaseFilter.bind(datasource));
3703
3820
  }
3704
3821
  this.grid.changeLayout(event);
3705
3822
  }
@@ -3749,7 +3866,8 @@ class TekGridFilterButton extends Button {
3749
3866
  columnComponentName = `${this.grid.name}-filter-AND-CONTAINS-${column.name}-${index}`;
3750
3867
  }
3751
3868
  this.filterFormInputs[column.name].push(columnComponentName);
3752
- const newColumnComponent = Object.assign(Object.assign(Object.assign({ label: column.label }, column.componentProps), filterItem), { name: columnComponentName });
3869
+ const _b = column.componentProps || {}, componentProps = __rest(_b, ["dataValueOut"]);
3870
+ const newColumnComponent = Object.assign(Object.assign(Object.assign({ label: column.label }, componentProps), filterItem), { name: columnComponentName });
3753
3871
  if (filterItem.helperOptions) {
3754
3872
  if (!newColumnComponent.events)
3755
3873
  newColumnComponent.events = {};
@@ -3783,8 +3901,8 @@ class TekGridFilterButton extends Button {
3783
3901
  }
3784
3902
 
3785
3903
  class TekGridLayoutOptions extends ComponentRender {
3786
- constructor() {
3787
- super(...arguments);
3904
+ constructor(props) {
3905
+ super(props);
3788
3906
  this.currentLayoutName = '';
3789
3907
  this.layoutEdited = false;
3790
3908
  this.layouts = {};
@@ -3793,6 +3911,8 @@ class TekGridLayoutOptions extends ComponentRender {
3793
3911
  this.originalDatasourceOrder = [];
3794
3912
  this.originalDatasourceDynamicFilter = {};
3795
3913
  this.originalDatasourceFilter = {};
3914
+ this.gridName = this.getInitValue('gridName', props.gridName, this.gridName);
3915
+ this.createAccessors();
3796
3916
  }
3797
3917
  getParentGrid() {
3798
3918
  let { parent } = this;
@@ -3803,30 +3923,44 @@ class TekGridLayoutOptions extends ComponentRender {
3803
3923
  }
3804
3924
  return parent;
3805
3925
  }
3926
+ loadGrid(gridName) {
3927
+ if (gridName)
3928
+ this.gridName = gridName;
3929
+ if (this.gridName) {
3930
+ const grid = Metadata.getInstances(this.gridName)[0];
3931
+ if (grid)
3932
+ this.grid = grid;
3933
+ }
3934
+ else {
3935
+ this.grid = this.getParentGrid();
3936
+ }
3937
+ if (this.grid) {
3938
+ this.gridName = this.grid.name;
3939
+ }
3940
+ return this.grid;
3941
+ }
3942
+ onGridChangeLayout() {
3943
+ this.layoutEdited = this.hasLayoutChanges();
3944
+ }
3945
+ registerChangeLayoutEvent() {
3946
+ if (!this.grid || this.changeLayoutEventGrid === this.grid)
3947
+ return;
3948
+ this.grid.addEvent('changeLayout', this.onGridChangeLayout.bind(this));
3949
+ this.changeLayoutEventGrid = this.grid;
3950
+ }
3806
3951
  onMounted(element) {
3807
3952
  const _super = Object.create(null, {
3808
3953
  onMounted: { get: () => super.onMounted }
3809
3954
  });
3810
3955
  return __awaiter(this, void 0, void 0, function* () {
3811
3956
  _super.onMounted.call(this, element);
3812
- this.grid = this.getParentGrid();
3957
+ this.loadGrid();
3958
+ this.registerChangeLayoutEvent();
3813
3959
  this.originalDatasourceOrder = [...this.grid.datasource.order];
3814
3960
  this.originalDatasourceDynamicFilter = Object.assign({}, this.grid.datasource.dynamicFilter);
3815
3961
  this.originalDatasourceFilter = Object.assign({}, this.grid.datasource.filter);
3816
- this.originalColumnProps = this.grid.columns.map((column) => ({
3817
- name: column.name,
3818
- label: column.label,
3819
- align: column.align,
3820
- isVisible: column.isVisible,
3821
- minWidth: column.minWidth,
3822
- maxWidth: column.maxWidth,
3823
- width: column.width,
3824
- fixed: column.fixed,
3825
- grouped: column.grouped,
3826
- groupOpened: column.groupOpened,
3827
- aggregation: column.aggregation,
3828
- filterHelperValue: this.getHelperValue(column),
3829
- }));
3962
+ this.originalColumnProps = this.grid.columns.map((column) => this.getLayoutColumnSnapshot(column));
3963
+ this.originalLayoutSnapshot = cloneComparableValue(this.getCurrentLayoutSnapshot(''));
3830
3964
  let layoutsInfo = {};
3831
3965
  const promise = this.loadLayoutsInfo();
3832
3966
  if (this.grid instanceof TekGrid) {
@@ -3871,6 +4005,74 @@ class TekGridLayoutOptions extends ComponentRender {
3871
4005
  }
3872
4006
  return '';
3873
4007
  }
4008
+ getLayoutColumnSnapshot(column, isVisible = column.isVisible) {
4009
+ const filterHelperValue = this.getHelperValue(column);
4010
+ return {
4011
+ name: column.name,
4012
+ label: column.label,
4013
+ align: column.align,
4014
+ isVisible,
4015
+ minWidth: column.minWidth || '',
4016
+ maxWidth: column.maxWidth || '',
4017
+ width: column.width,
4018
+ fixed: !!column.fixed,
4019
+ grouped: !!column.grouped,
4020
+ groupOpened: !!column.groupOpened,
4021
+ aggregation: column.aggregation,
4022
+ filterHelperValue: Array.isArray(filterHelperValue)
4023
+ ? filterHelperValue
4024
+ : filterHelperValue || '',
4025
+ };
4026
+ }
4027
+ getCurrentLayoutSnapshot(name) {
4028
+ if (this.viewGetCurrentLayout) {
4029
+ return this.viewGetCurrentLayout(name);
4030
+ }
4031
+ return {
4032
+ name,
4033
+ gridWidth: 'auto',
4034
+ order: [...this.grid.datasource.order],
4035
+ filter: Object.assign({}, this.grid.datasource.filter),
4036
+ dynamicFilter: Object.assign({}, this.grid.datasource.dynamicFilter),
4037
+ columns: this.grid.columns.map((column) => this.getLayoutColumnSnapshot(column)),
4038
+ };
4039
+ }
4040
+ getBaselineLayoutSnapshot() {
4041
+ if (this.currentLayoutName) {
4042
+ const currentLayout = this.layouts[this.currentLayoutName];
4043
+ return currentLayout;
4044
+ }
4045
+ return this.originalLayoutSnapshot;
4046
+ }
4047
+ getOriginalLayoutSnapshot() {
4048
+ return cloneComparableValue({
4049
+ name: '',
4050
+ gridWidth: 'auto',
4051
+ order: [...this.originalDatasourceOrder],
4052
+ filter: Object.assign({}, this.originalDatasourceFilter),
4053
+ dynamicFilter: Object.assign({}, this.originalDatasourceDynamicFilter),
4054
+ columns: this.originalColumnProps,
4055
+ });
4056
+ }
4057
+ hasLayoutChanges() {
4058
+ const baselineLayout = this.getBaselineLayoutSnapshot();
4059
+ if (!baselineLayout)
4060
+ return false;
4061
+ const currentLayout = this.getCurrentLayoutSnapshot(this.currentLayoutName);
4062
+ return !areObjectsEqual(currentLayout, baselineLayout);
4063
+ }
4064
+ getCurrentLayout() {
4065
+ return this.getCurrentLayoutSnapshot(this.currentLayoutName);
4066
+ }
4067
+ getLayout(name = this.currentLayoutName) {
4068
+ if (name === '') {
4069
+ return this.getOriginalLayoutSnapshot();
4070
+ }
4071
+ const layout = this.layouts[name];
4072
+ if (!layout)
4073
+ return undefined;
4074
+ return cloneComparableValue(layout);
4075
+ }
3874
4076
  layoutHasFilter(layout) {
3875
4077
  if (layout === '')
3876
4078
  return false;
@@ -3975,16 +4177,16 @@ class TekGridLayoutOptions extends ComponentRender {
3975
4177
  this.layoutEdited = false;
3976
4178
  }
3977
4179
  applyLayout(name, save = true) {
4180
+ const layoutSelected = name === '' ? this.getLayout(name) : this.layouts[name];
3978
4181
  if (this.grid.events.beforeApplyLayout) {
3979
4182
  const canApply = this.grid.callEvent('beforeApplyLayout', {
3980
4183
  component: this.grid,
3981
- layout: this.layouts[name],
4184
+ layout: layoutSelected,
3982
4185
  });
3983
4186
  if (canApply === false)
3984
4187
  return;
3985
4188
  }
3986
4189
  this.currentLayoutName = name;
3987
- const layoutSelected = this.layouts[name];
3988
4190
  if (this.viewApplyLayout) {
3989
4191
  this.viewApplyLayout(layoutSelected);
3990
4192
  }
@@ -4019,7 +4221,12 @@ class TekGridLayoutOptions extends ComponentRender {
4019
4221
  delete this.layouts[name];
4020
4222
  this.saveLayouts();
4021
4223
  }
4022
- updateLayout(name, layout) {
4224
+ updateLayout(name = this.currentLayoutName, layout = this.getCurrentLayout()) {
4225
+ if (name === '') {
4226
+ this.updateDefaultLayout(layout);
4227
+ this.layoutEdited = false;
4228
+ return;
4229
+ }
4023
4230
  this.fixColumns(layout);
4024
4231
  this.currentLayoutName = name;
4025
4232
  layout.name = name;
@@ -4041,6 +4248,7 @@ class TekGridLayoutOptions extends ComponentRender {
4041
4248
  return Object.assign(Object.assign({}, originalColumn), column);
4042
4249
  });
4043
4250
  }
4251
+ this.originalLayoutSnapshot = this.getOriginalLayoutSnapshot();
4044
4252
  if (this.currentLayoutName === '') {
4045
4253
  this.applyLayout(this.currentLayoutName, false);
4046
4254
  }
@@ -4052,20 +4260,7 @@ class TekGridLayoutOptions extends ComponentRender {
4052
4260
  this.grid.columns.forEach((gridColumn) => {
4053
4261
  if (!hasLayoutColumns
4054
4262
  || layoutColumnNames.indexOf(gridColumn.name) === -1) {
4055
- layout.columns.push({
4056
- name: gridColumn.name,
4057
- label: gridColumn.label,
4058
- align: gridColumn.align,
4059
- isVisible: !hasLayoutColumns && gridColumn.isVisible,
4060
- width: gridColumn.width,
4061
- minWidth: gridColumn.minWidth,
4062
- maxWidth: gridColumn.maxWidth,
4063
- fixed: gridColumn.fixed,
4064
- grouped: gridColumn.grouped,
4065
- groupOpened: gridColumn.groupOpened,
4066
- aggregation: gridColumn.aggregation,
4067
- filterHelperValue: this.getHelperValue(gridColumn),
4068
- });
4263
+ layout.columns.push(this.getLayoutColumnSnapshot(gridColumn, !hasLayoutColumns && gridColumn.isVisible));
4069
4264
  }
4070
4265
  });
4071
4266
  }
@@ -4346,6 +4541,9 @@ class TekTreeGrid extends TreeGridEditable {
4346
4541
  getFilterInputs(columnName) {
4347
4542
  return this.gridBase.getFilterInputs(columnName);
4348
4543
  }
4544
+ registerFilterButton(filterButton) {
4545
+ this.gridBase.registerFilterButton(filterButton);
4546
+ }
4349
4547
  getColumn(name) {
4350
4548
  return super.getColumn(name);
4351
4549
  }
@@ -4932,4 +5130,4 @@ Messages.add({
4932
5130
  const packageContent = require('../package.json');
4933
5131
  VersionService.addPackageVersion(packageContent.name, packageContent.version);
4934
5132
 
4935
- export { BreadcrumbHeader, CardTitle, CrudAddButton, CrudButton, CrudCancelButton, CrudDeleteButton, CrudForm, CrudSaveButton, DynamicFilterOperations, DynamicFilterRelations, Image, IterableCarousel, IterableComponentRender, Loading, Notifications, ProductCard, TekDragGrid, TekFilterHelper, TekGrid, TekGridColumn, TekGridColumnsButton, TekGridColumnsButtonController, TekGridFilterButton, TekGridLayoutOptions, TekMemoryDatasource, TekRestDatasource, TekTreeGrid, TekUserInfo, TekUserInfoList, columnAggregationValues };
5133
+ export { BreadcrumbHeader, CardTitle, CrudAddButton, CrudButton, CrudCancelButton, CrudDeleteButton, CrudForm, CrudSaveButton, DynamicFilterOperations, DynamicFilterRelations, Image, IterableCarousel, IterableComponentRender, Loading, Notifications, ProductCard, TekDragGrid, TekFilterHelper, TekGrid, TekGridColumn, TekGridColumnsButton, TekGridColumnsButtonController, TekGridExportButton, TekGridFilterButton, TekGridLayoutOptions, TekMemoryDatasource, TekRestDatasource, TekTreeGrid, TekUserInfo, TekUserInfoList, columnAggregationValues };