@sankhyalabs/ezui 5.10.8 → 5.11.0-dev.2

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 (137) hide show
  1. package/README.md +0 -1
  2. package/dist/cjs/{CSSVarsUtils-af809e73.js → CSSVarsUtils-b136a156.js} +5 -0
  3. package/dist/cjs/RecordValidationProcessor-edd23705.js +102 -0
  4. package/dist/cjs/ez-actions-button.cjs.entry.js +1 -1
  5. package/dist/cjs/ez-calendar.cjs.entry.js +34 -5
  6. package/dist/cjs/ez-combo-box.cjs.entry.js +89 -14
  7. package/dist/cjs/ez-date-input.cjs.entry.js +53 -22
  8. package/dist/cjs/ez-date-time-input.cjs.entry.js +53 -19
  9. package/dist/cjs/ez-filter-input_2.cjs.entry.js +1 -1
  10. package/dist/cjs/ez-form.cjs.entry.js +9 -83
  11. package/dist/cjs/ez-grid.cjs.entry.js +488 -6
  12. package/dist/cjs/ez-number-input.cjs.entry.js +39 -15
  13. package/dist/cjs/ez-search.cjs.entry.js +11 -2
  14. package/dist/cjs/ez-text-area.cjs.entry.js +6 -2
  15. package/dist/cjs/ez-text-input.cjs.entry.js +7 -4
  16. package/dist/cjs/ez-time-input.cjs.entry.js +11 -7
  17. package/dist/cjs/ezui.cjs.js +1 -1
  18. package/dist/cjs/loader.cjs.js +1 -1
  19. package/dist/collection/collection-manifest.json +2 -2
  20. package/dist/collection/components/ez-calendar/ez-calendar.js +63 -6
  21. package/dist/collection/components/ez-combo-box/ez-combo-box.css +6 -0
  22. package/dist/collection/components/ez-combo-box/ez-combo-box.js +122 -12
  23. package/dist/collection/components/ez-date-input/ez-date-input.js +71 -21
  24. package/dist/collection/components/ez-date-time-input/ez-date-time-input.js +71 -18
  25. package/dist/collection/components/ez-grid/controller/ag-grid/AgGridController.js +40 -7
  26. package/dist/collection/components/ez-grid/controller/ag-grid/DataSource.js +1 -0
  27. package/dist/collection/components/ez-grid/controller/ag-grid/GridEditionManager.js +230 -0
  28. package/dist/collection/components/ez-grid/controller/ag-grid/editor/EzCellEditor.js +49 -0
  29. package/dist/collection/components/ez-grid/controller/ag-grid/editor/GridEditorUtils.js +10 -0
  30. package/dist/collection/components/ez-grid/controller/ag-grid/editor/IEditorMetadata.js +4 -0
  31. package/dist/collection/components/ez-grid/controller/ag-grid/editor/templates/ComboBox.tpl.js +38 -0
  32. package/dist/collection/components/ez-grid/controller/ag-grid/editor/templates/DateInput.tpl.js +40 -0
  33. package/dist/collection/components/ez-grid/controller/ag-grid/editor/templates/NumberInput.tpl.js +20 -0
  34. package/dist/collection/components/ez-grid/controller/ag-grid/editor/templates/Search.tpl.js +15 -0
  35. package/dist/collection/components/ez-grid/controller/ag-grid/editor/templates/TextInput.tpl.js +41 -0
  36. package/dist/collection/components/ez-grid/ez-grid.js +67 -0
  37. package/dist/collection/components/ez-number-input/ez-number-input.css +4 -0
  38. package/dist/collection/components/ez-number-input/ez-number-input.js +62 -15
  39. package/dist/collection/components/ez-search/ez-search.css +1 -1
  40. package/dist/collection/components/ez-search/ez-search.js +46 -1
  41. package/dist/collection/components/ez-text-area/ez-text-area.css +4 -0
  42. package/dist/collection/components/ez-text-area/ez-text-area.js +23 -1
  43. package/dist/collection/components/ez-text-input/ez-text-input.css +8 -1
  44. package/dist/collection/components/ez-text-input/ez-text-input.js +14 -5
  45. package/dist/collection/components/ez-time-input/ez-time-input.css +4 -0
  46. package/dist/collection/components/ez-time-input/ez-time-input.js +18 -7
  47. package/dist/collection/utils/CSSVarsUtils.js +5 -0
  48. package/dist/collection/utils/form/DataBinder.js +7 -62
  49. package/dist/collection/utils/form/FormMetadata.js +3 -22
  50. package/dist/collection/utils/interfaces/AbstractFieldMetadata.js +21 -0
  51. package/dist/collection/utils/validators/recordvalidator/IValidationResult.js +1 -0
  52. package/dist/collection/utils/validators/recordvalidator/IValidationSource.js +1 -0
  53. package/dist/collection/utils/validators/recordvalidator/RecordValidationProcessor.js +74 -0
  54. package/dist/custom-elements/index.js +922 -203
  55. package/dist/esm/{CSSVarsUtils-00f67f32.js → CSSVarsUtils-a97cfa29.js} +5 -0
  56. package/dist/esm/RecordValidationProcessor-abc814af.js +99 -0
  57. package/dist/esm/ez-actions-button.entry.js +1 -1
  58. package/dist/esm/ez-calendar.entry.js +35 -6
  59. package/dist/esm/ez-combo-box.entry.js +89 -14
  60. package/dist/esm/ez-date-input.entry.js +53 -22
  61. package/dist/esm/ez-date-time-input.entry.js +53 -19
  62. package/dist/esm/ez-filter-input_2.entry.js +1 -1
  63. package/dist/esm/ez-form.entry.js +10 -84
  64. package/dist/esm/ez-grid.entry.js +489 -7
  65. package/dist/esm/ez-number-input.entry.js +39 -15
  66. package/dist/esm/ez-search.entry.js +11 -2
  67. package/dist/esm/ez-text-area.entry.js +6 -2
  68. package/dist/esm/ez-text-input.entry.js +7 -4
  69. package/dist/esm/ez-time-input.entry.js +11 -7
  70. package/dist/esm/ezui.js +1 -1
  71. package/dist/esm/loader.js +1 -1
  72. package/dist/ezui/ezui.esm.js +1 -1
  73. package/dist/ezui/p-028f264f.entry.js +1 -0
  74. package/dist/ezui/p-391de0e4.entry.js +1 -0
  75. package/dist/ezui/p-4535da17.entry.js +1 -0
  76. package/dist/ezui/p-5cef0264.entry.js +1 -0
  77. package/dist/ezui/p-7eb3e1a5.js +1 -0
  78. package/dist/ezui/p-86a2036d.js +1 -0
  79. package/dist/ezui/{p-12303d2e.entry.js → p-87e85160.entry.js} +1 -1
  80. package/dist/ezui/p-90fa4cb3.entry.js +1 -0
  81. package/dist/ezui/p-9f41b414.entry.js +1 -0
  82. package/dist/ezui/p-ce035beb.entry.js +1 -0
  83. package/dist/ezui/p-d43b22f3.entry.js +1 -0
  84. package/dist/ezui/p-e2dfd935.entry.js +1 -0
  85. package/dist/ezui/p-e67d0bd5.entry.js +1 -0
  86. package/dist/ezui/{p-c7a23be9.entry.js → p-fd54b5b4.entry.js} +2 -2
  87. package/dist/ezui/{p-f1a537e3.entry.js → p-ff82b176.entry.js} +1 -1
  88. package/dist/types/components/ez-calendar/ez-calendar.d.ts +9 -1
  89. package/dist/types/components/ez-combo-box/ez-combo-box.d.ts +14 -0
  90. package/dist/types/components/ez-date-input/ez-date-input.d.ts +4 -0
  91. package/dist/types/components/ez-date-time-input/ez-date-time-input.d.ts +4 -0
  92. package/dist/types/components/ez-form-view/interfaces/IFormViewField.d.ts +2 -14
  93. package/dist/types/components/ez-grid/controller/EzGridController.d.ts +18 -0
  94. package/dist/types/components/ez-grid/controller/ag-grid/AgGridController.d.ts +4 -0
  95. package/dist/types/components/ez-grid/controller/ag-grid/GridEditionManager.d.ts +38 -0
  96. package/dist/types/components/ez-grid/controller/ag-grid/editor/EzCellEditor.d.ts +10 -0
  97. package/dist/types/components/ez-grid/controller/ag-grid/editor/GridEditorUtils.d.ts +1 -0
  98. package/dist/types/components/ez-grid/controller/ag-grid/editor/IEditorMetadata.d.ts +9 -0
  99. package/dist/types/components/ez-grid/controller/ag-grid/editor/IUICellEditor.d.ts +10 -0
  100. package/dist/types/components/ez-grid/controller/ag-grid/editor/templates/ComboBox.tpl.d.ts +4 -0
  101. package/dist/types/components/ez-grid/controller/ag-grid/editor/templates/DateInput.tpl.d.ts +5 -0
  102. package/dist/types/components/ez-grid/controller/ag-grid/editor/templates/NumberInput.tpl.d.ts +4 -0
  103. package/dist/types/components/ez-grid/controller/ag-grid/editor/templates/Search.tpl.d.ts +3 -0
  104. package/dist/types/components/ez-grid/controller/ag-grid/editor/templates/TextInput.tpl.d.ts +4 -0
  105. package/dist/types/components/ez-grid/ez-grid.d.ts +13 -0
  106. package/dist/types/components/ez-number-input/ez-number-input.d.ts +5 -1
  107. package/dist/types/components/ez-search/ez-search.d.ts +6 -1
  108. package/dist/types/components/ez-text-area/ez-text-area.d.ts +4 -0
  109. package/dist/types/components/ez-text-input/ez-text-input.d.ts +4 -1
  110. package/dist/types/components/ez-time-input/ez-time-input.d.ts +2 -1
  111. package/dist/types/components.d.ts +65 -6
  112. package/dist/types/utils/form/DataBinder.d.ts +1 -3
  113. package/dist/types/utils/form/interfaces/IFormConfig.d.ts +1 -1
  114. package/dist/types/utils/form/interfaces/index.d.ts +4 -4
  115. package/dist/types/utils/interfaces/AbstractFieldMetadata.d.ts +17 -0
  116. package/dist/types/utils/{form/interfaces → interfaces}/IFieldConfig.d.ts +2 -2
  117. package/dist/types/utils/validators/recordvalidator/IValidationSource.d.ts +6 -0
  118. package/dist/types/utils/validators/recordvalidator/RecordValidationProcessor.d.ts +13 -0
  119. package/package.json +2 -2
  120. package/dist/ezui/p-00c7c25d.entry.js +0 -1
  121. package/dist/ezui/p-0b160fec.entry.js +0 -1
  122. package/dist/ezui/p-0bd54a6f.entry.js +0 -1
  123. package/dist/ezui/p-39153935.entry.js +0 -1
  124. package/dist/ezui/p-4a5e37a7.js +0 -1
  125. package/dist/ezui/p-5782443e.entry.js +0 -1
  126. package/dist/ezui/p-5d45e384.entry.js +0 -1
  127. package/dist/ezui/p-70ea4beb.entry.js +0 -1
  128. package/dist/ezui/p-78a6e049.entry.js +0 -1
  129. package/dist/ezui/p-8bcb197f.entry.js +0 -1
  130. package/dist/ezui/p-a4c9f3c4.entry.js +0 -1
  131. /package/dist/collection/{utils/form/interfaces/IFieldConfig.js → components/ez-grid/controller/ag-grid/editor/IUICellEditor.js} +0 -0
  132. /package/dist/collection/utils/{form/interfaces/IInvalidField.js → interfaces/IFieldConfig.js} +0 -0
  133. /package/dist/collection/utils/{form/interfaces/IRecordValidator.js → validators/recordvalidator/IInvalidField.js} +0 -0
  134. /package/dist/collection/utils/{form/interfaces/IValidationResult.js → validators/recordvalidator/IRecordValidator.js} +0 -0
  135. /package/dist/types/utils/{form/interfaces → validators/recordvalidator}/IInvalidField.d.ts +0 -0
  136. /package/dist/types/utils/{form/interfaces → validators/recordvalidator}/IRecordValidator.d.ts +0 -0
  137. /package/dist/types/utils/{form/interfaces → validators/recordvalidator}/IValidationResult.d.ts +0 -0
@@ -1,4 +1,4 @@
1
- import { ApplicationContext, DataType, NumberUtils, SortMode, StringUtils, UserInterface } from '@sankhyalabs/core';
1
+ import { ApplicationContext, DataType, MaskFormatter, NumberUtils, SortMode, StringUtils, UserInterface } from '@sankhyalabs/core';
2
2
  import { Grid, } from 'ag-grid-community';
3
3
  import { Grid as EnterpriseGrid, LicenseManager } from 'ag-grid-enterprise';
4
4
  import DataSource from './DataSource';
@@ -8,6 +8,7 @@ import SelectionHeader from './components/selectionHeader';
8
8
  import gridTerms from './i18n/pt-BR.js';
9
9
  import { DISTINCT_FILTER_NAME_PREFIX } from '../../../../utils/constants';
10
10
  import { calcFilterColumnLeftPosition } from './AgGridUtils';
11
+ import GridEditionManager from './GridEditionManager';
11
12
  export default class AgGridController {
12
13
  configFilterColumn(filterColumn) {
13
14
  this._filterColumn = filterColumn;
@@ -43,6 +44,9 @@ export default class AgGridController {
43
44
  getGridConfig() {
44
45
  return this._gridConfig;
45
46
  }
47
+ getGridApi() {
48
+ return this._gridOptions.api;
49
+ }
46
50
  getSort() {
47
51
  const sortedColumns = [];
48
52
  this._gridOptions.columnApi
@@ -103,6 +107,7 @@ export default class AgGridController {
103
107
  this._doubleClickCallBack = options.onDoubleClick;
104
108
  this._multipleSelection = options.allowMultipleSelection;
105
109
  this._dataUnit = options.dataUnit;
110
+ this._editionManager = new GridEditionManager(this._dataUnit, options.useEnterLikeTab, options.recordsValidator, options.editionIsDisabled);
106
111
  this._statusResolver = options.statusResolver;
107
112
  if (this._dataUnit) {
108
113
  this._dataUnit.sortingProvider = this;
@@ -122,12 +127,14 @@ export default class AgGridController {
122
127
  defaultColDef: {
123
128
  headerClass: 'ez-grid__cell-header',
124
129
  cellClass: 'ez-grid__cell-body',
130
+ cellStyle: {
131
+ height: '100%'
132
+ }
125
133
  },
126
- components: {
127
- ezGridHeaderComponent: SelectionHeader,
128
- ezGridCustomHeader: EzGridCustomHeader,
129
- },
134
+ components: Object.assign({ ezGridHeaderComponent: SelectionHeader, ezGridCustomHeader: EzGridCustomHeader }, this._editionManager.getComponents()),
130
135
  context: {
136
+ editionManager: this._editionManager,
137
+ dataUnit: this._dataUnit,
131
138
  headerCheckStatusGetter: () => this.getSelectionHeaderStatus(),
132
139
  headerCheckStatusSetter: (selectAll) => this.updateSelectionForAll(selectAll),
133
140
  },
@@ -135,6 +142,7 @@ export default class AgGridController {
135
142
  this.defineRowModelType(this._gridOptions, options);
136
143
  this.setOptionsEvents(this._gridOptions);
137
144
  this.setOptionsSupress(this._gridOptions);
145
+ this._gridOptions = this._editionManager.configureGrid(this._gridOptions);
138
146
  if (this._enterprise) {
139
147
  this._grid = new EnterpriseGrid(container, this._gridOptions);
140
148
  }
@@ -281,6 +289,7 @@ export default class AgGridController {
281
289
  opt.onSelectionChanged = e => this.onSelectionChange(e);
282
290
  opt.onRowDoubleClicked = evt => this.onRowDoubleClick(evt);
283
291
  opt.onDragStopped = evt => this.onCallStateChange('columnMovedEnd', evt);
292
+ opt.onCellClicked = evt => this.onCellClicked(evt);
284
293
  }
285
294
  setOptionsSupress(opt) {
286
295
  opt.suppressDragLeaveHidesColumns = true;
@@ -584,7 +593,7 @@ export default class AgGridController {
584
593
  else if (propSortable === false) {
585
594
  tooltip = 'Coluna não pode ser ordenada';
586
595
  }
587
- return {
596
+ return this._editionManager.configureColumn({
588
597
  headerName: source.label,
589
598
  field: source.name,
590
599
  sortable: propSortable,
@@ -597,10 +606,19 @@ export default class AgGridController {
597
606
  showColumnFilter: (leftPosition) => this.showFilterColumn({ columnName: source.name, columnLabel: source.label, leftPosition, filteredOptions: this._filteredColumns.get(source.name) }),
598
607
  },
599
608
  valueFormatter: params => {
609
+ if (params.value == undefined) {
610
+ return "";
611
+ }
612
+ if (params.value instanceof Promise) {
613
+ return "Carregando...";
614
+ }
615
+ if (this._dataUnit) {
616
+ return this._dataUnit.getFormattedValue(source.name, params.value);
617
+ }
600
618
  return this.getFormatterByColumn(params, source);
601
619
  },
602
620
  cellStyle: this.getStyleByColumn(source),
603
- };
621
+ });
604
622
  }
605
623
  getInitCellStyle() {
606
624
  return {
@@ -673,6 +691,13 @@ export default class AgGridController {
673
691
  return params.value.toLocaleDateString();
674
692
  }
675
693
  }
694
+ if ((source === null || source === void 0 ? void 0 : source.userInterface) === UserInterface.ELAPSEDTIME || (source === null || source === void 0 ? void 0 : source.userInterface) === UserInterface.TIME) {
695
+ if (!!params.value) {
696
+ const maskFormatter = new MaskFormatter("##:##");
697
+ const formattedValue = String(params.value).padStart(4, '0');
698
+ return maskFormatter.format(formattedValue);
699
+ }
700
+ }
676
701
  }
677
702
  onCallStateChange(type, e) {
678
703
  const finished = !('finished' in e) || e['finished'];
@@ -687,6 +712,13 @@ export default class AgGridController {
687
712
  this._columnStateChangeCallback(type, this.getColumnsState(), info);
688
713
  }
689
714
  }
715
+ onCellClicked(event) {
716
+ this._editionManager.verifyClickToEdition(event.api, {
717
+ rowIndex: event.rowIndex,
718
+ column: event.column,
719
+ rowPinned: undefined
720
+ });
721
+ }
690
722
  isElementResize(e) {
691
723
  return e['target'] && e['target'].getAttribute('ref') === 'eResize';
692
724
  }
@@ -704,6 +736,7 @@ export default class AgGridController {
704
736
  if (this._selectionChangeCallback) {
705
737
  clearTimeout(this._selectionChangeDeboucing);
706
738
  this._selectionChangeDeboucing = window.setTimeout(() => {
739
+ this._editionManager.proceedAutoSave();
707
740
  if (this._dataUnit) {
708
741
  if (event.context.selectionChangeQuietly) {
709
742
  const selectionInfo = this._dataUnit;
@@ -23,6 +23,7 @@ export default class DataSource {
23
23
  case Action.DATA_SAVED:
24
24
  case Action.EDITION_CANCELED:
25
25
  case Action.DATA_CHANGED:
26
+ case Action.DATA_RESOLVED:
26
27
  this._controller.refresh();
27
28
  break;
28
29
  case Action.SELECTION_CHANGED:
@@ -0,0 +1,230 @@
1
+ import { UserInterface } from "@sankhyalabs/core";
2
+ import { KeyCode } from "ag-grid-community";
3
+ import { RecordValidationProcessor } from "../../../../utils/validators/recordvalidator/RecordValidationProcessor";
4
+ import EzCellEditor from "./editor/EzCellEditor";
5
+ export default class GridEditionManager {
6
+ constructor(dataUnit, useEnterLikeTab, recordsValidator, editionIsDisabled) {
7
+ this._dataUnit = dataUnit;
8
+ this._recordValidationProcessor = new RecordValidationProcessor(this._dataUnit, {
9
+ getRequiredFields: () => this.getRequiredFields(),
10
+ markAsInvalid: () => { },
11
+ getMessageForField: () => null
12
+ }, recordsValidator);
13
+ this._useEnterLikeTab = useEnterLikeTab;
14
+ this._editionIsDisabled = editionIsDisabled;
15
+ }
16
+ configureGrid(options) {
17
+ this._gridOptions = options;
18
+ options.readOnlyEdit = true;
19
+ options.onCellEditRequest = evt => this.onCellEditRequest(evt);
20
+ options.onCellKeyDown = evt => {
21
+ if (evt.event && evt["column"]) {
22
+ this.onCellKeyDown(evt);
23
+ }
24
+ };
25
+ return options;
26
+ }
27
+ proceedAutoSave() {
28
+ if (!this._dataUnit.isDirty()) {
29
+ this.saveSuccess();
30
+ return;
31
+ }
32
+ if (!this._isGridEdition) {
33
+ return;
34
+ }
35
+ const currentRercord = this._dataUnit.getSelectedRecord();
36
+ if (currentRercord == undefined) {
37
+ return;
38
+ }
39
+ this._recordValidationProcessor
40
+ .validate()
41
+ .then(() => {
42
+ this._dataUnit.saveData()
43
+ .then(() => this.saveSuccess())
44
+ .catch(reason => this.saveFail(reason));
45
+ })
46
+ .catch(reason => this.saveFail(reason));
47
+ }
48
+ navigateByEnterKey(keyboardEvent) {
49
+ const backwards = keyboardEvent.shiftKey;
50
+ if (this._useEnterLikeTab) {
51
+ if (backwards) {
52
+ this._gridOptions.api.tabToPreviousCell(keyboardEvent);
53
+ }
54
+ else {
55
+ this._gridOptions.api.tabToNextCell(keyboardEvent);
56
+ }
57
+ }
58
+ else {
59
+ const editionCell = this._gridOptions.api.getEditingCells()[0];
60
+ if (editionCell) {
61
+ let { rowIndex } = editionCell;
62
+ this.nextEditionRow(rowIndex, editionCell.column, backwards);
63
+ }
64
+ }
65
+ }
66
+ getComponents() {
67
+ return { ezCellEditor: EzCellEditor };
68
+ }
69
+ verifyClickToEdition(api, cellClicked) {
70
+ if (this.isSecondClick(cellClicked)) {
71
+ api.startEditingCell({ rowIndex: cellClicked.rowIndex, colKey: cellClicked.column.getColId() });
72
+ }
73
+ this._lastCellClicked = cellClicked;
74
+ }
75
+ configureColumn(col) {
76
+ col.cellEditor = 'ezCellEditor';
77
+ col.editable = params => this.canEdit(params);
78
+ col.suppressKeyboardEvent = (params) => {
79
+ return params.event.key === KeyCode.ENTER;
80
+ };
81
+ return col;
82
+ }
83
+ getRequiredFields() {
84
+ return this._gridOptions.columnApi.getAllDisplayedColumns().filter(c => {
85
+ const fieldDefinition = this._dataUnit.getField(c.getColId());
86
+ return fieldDefinition && fieldDefinition.required;
87
+ }).map(c => c.getColId());
88
+ }
89
+ saveSuccess() {
90
+ this.focusOnCell(this._targetEditionCell);
91
+ this._lastCellEdited = undefined;
92
+ this._targetEditionCell = undefined;
93
+ this._isGridEdition = false;
94
+ }
95
+ saveFail(reason) {
96
+ this.focusOnCell(this._lastCellEdited);
97
+ this._isGridEdition = false;
98
+ if (reason) {
99
+ Promise.reject(reason);
100
+ }
101
+ }
102
+ focusOnCell(cell) {
103
+ if (cell == undefined) {
104
+ return;
105
+ }
106
+ const { rowIndex, column } = cell;
107
+ this._gridOptions.api.getDisplayedRowAtIndex(rowIndex).setSelected(true, true);
108
+ this._gridOptions.api.clearRangeSelection();
109
+ this._gridOptions.api.addCellRange({ rowStartIndex: rowIndex, rowEndIndex: rowIndex, columns: [column] });
110
+ this._gridOptions.api.startEditingCell({ colKey: column.getColId(), rowIndex });
111
+ this._gridOptions.api.setFocusedCell(rowIndex, column.getColId());
112
+ const cellEditor = this._gridOptions.api.getCellEditorInstances()[0];
113
+ if (cellEditor) {
114
+ cellEditor.focusIn();
115
+ }
116
+ }
117
+ onCellKeyDown(event) {
118
+ const keyboardEvent = event.event;
119
+ switch (keyboardEvent.key) {
120
+ case KeyCode.ENTER:
121
+ this.processEnterKey(keyboardEvent, event);
122
+ break;
123
+ case KeyCode.UP:
124
+ this.editPreviousRow(event.api);
125
+ break;
126
+ case KeyCode.DOWN:
127
+ this.editNextRow(event.api);
128
+ break;
129
+ }
130
+ }
131
+ processEnterKey(keyboardEvent, event) {
132
+ const editionCell = event.api.getEditingCells()[0];
133
+ if (!editionCell) {
134
+ event.api.startEditingCell({ colKey: event.column.getColId(), rowIndex: event.rowIndex });
135
+ return;
136
+ }
137
+ this.navigateByEnterKey(keyboardEvent);
138
+ }
139
+ nextEditionRow(rowIndex, column, backwards) {
140
+ if (backwards) {
141
+ rowIndex = rowIndex - 1;
142
+ if (rowIndex < 0) {
143
+ rowIndex = this._dataUnit.records.length - 1;
144
+ }
145
+ }
146
+ else {
147
+ rowIndex = rowIndex + 1;
148
+ if (rowIndex >= this._dataUnit.records.length) {
149
+ rowIndex = 0;
150
+ }
151
+ }
152
+ this._targetEditionCell = new TargetEdition(rowIndex, column, true);
153
+ this.finishEdition();
154
+ }
155
+ editPreviousRow(api) {
156
+ this.moveEditionVertically(api, -1);
157
+ }
158
+ editNextRow(api) {
159
+ this.moveEditionVertically(api, 1);
160
+ }
161
+ moveEditionVertically(api, offset) {
162
+ const editionCell = api.getEditingCells()[0];
163
+ if (!editionCell) {
164
+ return;
165
+ }
166
+ const rowIndex = editionCell.rowIndex + offset;
167
+ if (api.getDisplayedRowAtIndex(rowIndex)) {
168
+ this._targetEditionCell = new TargetEdition(rowIndex, editionCell.column, offset < 0);
169
+ this.finishEdition();
170
+ }
171
+ }
172
+ finishEdition() {
173
+ this._gridOptions.api.stopEditing();
174
+ setTimeout(() => {
175
+ //O Timeout foi inserido para permitir que o ciclo de finalização prossiga
176
+ //pois precisamos aguardar o fim da edição para executar o autosave.
177
+ this.proceedAutoSave();
178
+ }, 0);
179
+ }
180
+ canEdit(params) {
181
+ if (this._editionIsDisabled()) {
182
+ return false;
183
+ }
184
+ return this.isColEditable(params.colDef.field);
185
+ }
186
+ isColEditable(fieldName) {
187
+ const fieldDefinition = this._dataUnit.getField(fieldName);
188
+ if (fieldDefinition) {
189
+ return !fieldDefinition.readOnly;
190
+ }
191
+ return false;
192
+ }
193
+ isSecondClick(cellClicked) {
194
+ if (!this._lastCellClicked) {
195
+ return false;
196
+ }
197
+ if (this._lastCellClicked.column != cellClicked.column) {
198
+ return false;
199
+ }
200
+ if (this._lastCellClicked.rowIndex != cellClicked.rowIndex) {
201
+ return false;
202
+ }
203
+ return true;
204
+ }
205
+ onCellEditRequest(event) {
206
+ const fieldName = event.colDef.field;
207
+ const value = event.newValue;
208
+ if (event.oldValue != value) {
209
+ if (value instanceof Promise) {
210
+ const fieldDescriptor = this._dataUnit.getField(event.colDef.colId);
211
+ event.node.setData(Object.assign(Object.assign({}, event.data), { [fieldName]: (fieldDescriptor === null || fieldDescriptor === void 0 ? void 0 : fieldDescriptor.userInterface) === UserInterface.SEARCH ? value : event.oldValue }));
212
+ value.then(resolved => event.node.setData(Object.assign(Object.assign({}, event.data), { [fieldName]: resolved })));
213
+ }
214
+ else {
215
+ event.node.setData(Object.assign(Object.assign({}, event.data), { [fieldName]: value }));
216
+ }
217
+ this._isGridEdition = true;
218
+ this._dataUnit.setFieldValue(fieldName, value, [event.data.__record__id__]);
219
+ this._lastCellEdited = { rowIndex: event.rowIndex, column: event.column, rowPinned: undefined };
220
+ }
221
+ }
222
+ }
223
+ class TargetEdition {
224
+ constructor(rowIndex, column, backwards) {
225
+ this.rowPinned = null;
226
+ this.rowIndex = rowIndex;
227
+ this.column = column;
228
+ this.backwards = backwards;
229
+ }
230
+ }
@@ -0,0 +1,49 @@
1
+ import { UserInterface } from "@sankhyalabs/core";
2
+ import { buildEditorMetadata } from "./IEditorMetadata";
3
+ import { buildTextAreaInput, buildTextInput } from "./templates/TextInput.tpl";
4
+ import { buildDate, buildDateTime, buildTime } from "./templates/DateInput.tpl";
5
+ import { buildDecimal, buildInteger } from "./templates/NumberInput.tpl";
6
+ import { buildComboBox, buildSwitch } from "./templates/ComboBox.tpl";
7
+ import { buildSearch } from "./templates/Search.tpl";
8
+ const uiBuilders = new Map();
9
+ uiBuilders.set(UserInterface.DATE, buildDate);
10
+ uiBuilders.set(UserInterface.TIME, buildTime);
11
+ uiBuilders.set(UserInterface.DATETIME, buildDateTime);
12
+ uiBuilders.set(UserInterface.DECIMALNUMBER, buildDecimal);
13
+ uiBuilders.set(UserInterface.INTEGERNUMBER, buildInteger);
14
+ uiBuilders.set(UserInterface.SWITCH, buildSwitch);
15
+ uiBuilders.set(UserInterface.CHECKBOX, buildSwitch);
16
+ uiBuilders.set(UserInterface.OPTIONSELECTOR, buildComboBox);
17
+ uiBuilders.set(UserInterface.LONGTEXT, buildTextAreaInput);
18
+ uiBuilders.set(UserInterface.SEARCH, buildSearch);
19
+ export default class EzCellEditor {
20
+ init(params) {
21
+ const fieldName = params.column.getColId();
22
+ const dataUnit = params.context.dataUnit;
23
+ const fieldMetadata = buildEditorMetadata(dataUnit.getField(fieldName), params.eGridCell, dataUnit, params.context.editionManager);
24
+ const builder = uiBuilders.get(fieldMetadata.userInterface) || buildTextInput;
25
+ this._gui = builder(fieldMetadata);
26
+ if (this._gui.valueSetter != undefined) {
27
+ this._gui.valueSetter(params.value);
28
+ }
29
+ else {
30
+ this._gui.value = params.value;
31
+ }
32
+ }
33
+ getGui() {
34
+ return this._gui;
35
+ }
36
+ afterGuiAttached() {
37
+ this.focusIn();
38
+ }
39
+ focusIn() {
40
+ this._gui.focus();
41
+ this._gui.setFocus({ selectText: true });
42
+ }
43
+ getValue() {
44
+ return this._gui.valueGetter != undefined ? this._gui.valueGetter() : this._gui.value;
45
+ }
46
+ isPopup() {
47
+ return this._gui.isPopUp;
48
+ }
49
+ }
@@ -0,0 +1,10 @@
1
+ export function getViewPortHeight(cell) {
2
+ let currentElem = cell;
3
+ while (currentElem) {
4
+ const viewPort = currentElem.querySelector("[ref=eBodyViewport]");
5
+ if (viewPort) {
6
+ return viewPort.getBoundingClientRect().bottom;
7
+ }
8
+ currentElem = currentElem.parentElement;
9
+ }
10
+ }
@@ -0,0 +1,4 @@
1
+ import { buildFieldMetadata } from '../../../../../utils/interfaces/AbstractFieldMetadata';
2
+ export const buildEditorMetadata = (descriptor, eGridCell, dataUnit, editionManager) => {
3
+ return Object.assign(Object.assign({}, buildFieldMetadata(descriptor)), { eGridCell, dataUnit, editionManager });
4
+ };
@@ -0,0 +1,38 @@
1
+ import { HTMLBuilder } from "@sankhyalabs/core";
2
+ import { getViewPortHeight } from '../GridEditorUtils';
3
+ const BOOLEAN_OPTIONS = new Map([[true, { value: "S", label: "Sim" }], [false, { value: "N", label: "Não" }]]);
4
+ export const buildComboBox = ({ required, props, eGridCell }) => {
5
+ const prop = props === null || props === void 0 ? void 0 : props.options;
6
+ let options;
7
+ if (typeof prop === "string") {
8
+ const parsed = JSON.parse(prop);
9
+ options = Object.keys(parsed).map(key => { return { value: key, label: parsed[key] }; });
10
+ }
11
+ else {
12
+ options = prop;
13
+ }
14
+ const combo = HTMLBuilder.parseElement(`<ez-combo-box
15
+ class="grid_editor"
16
+ suppress-empty-option=${required}
17
+ mode="slim"
18
+ />`);
19
+ combo.options = options;
20
+ combo.listOptionsPosition = { verticalPosition: 29, bottomLimit: getViewPortHeight(eGridCell), hardPosition: true };
21
+ return combo;
22
+ };
23
+ export const buildSwitch = (fieldMetadata) => {
24
+ const combo = buildComboBox(Object.assign(Object.assign({}, fieldMetadata), { props: Object.assign(Object.assign({}, fieldMetadata.props), { options: Array.from(BOOLEAN_OPTIONS.values()) }) }));
25
+ combo.valueGetter = () => {
26
+ const value = combo.value;
27
+ if (value == undefined) {
28
+ return;
29
+ }
30
+ return value.value == "S";
31
+ };
32
+ combo.valueSetter = (value) => {
33
+ if (value != undefined) {
34
+ combo.value = BOOLEAN_OPTIONS.get(value);
35
+ }
36
+ };
37
+ return combo;
38
+ };
@@ -0,0 +1,40 @@
1
+ import { HTMLBuilder } from "@sankhyalabs/core";
2
+ const LIMIT_TIME_VALUE = 2359;
3
+ export const buildDate = () => {
4
+ const dateInput = HTMLBuilder.parseElement(`<ez-date-input
5
+ class="ez-grid grid_editor"
6
+ mode="slim"
7
+ data-is-fixed="true"
8
+ />`);
9
+ dateInput.valueGetter = () => dateInput.getValueAsync();
10
+ return dateInput;
11
+ };
12
+ export const buildTime = ({ readOnly }) => {
13
+ const timeInputElement = HTMLBuilder.parseElement(`<ez-time-input
14
+ class="ez-grid grid_editor"
15
+ enabled=${!readOnly}
16
+ mode="slim"
17
+ />`);
18
+ timeInputElement.valueGetter = () => {
19
+ const value = timeInputElement.value;
20
+ const isAllowedTime = parseInt(value) <= LIMIT_TIME_VALUE;
21
+ return isAllowedTime ? value : null;
22
+ };
23
+ timeInputElement.valueSetter = (value) => {
24
+ const isAllowedTime = parseInt(value) <= LIMIT_TIME_VALUE;
25
+ if (!isAllowedTime)
26
+ return timeInputElement.value = null;
27
+ return timeInputElement.value = value;
28
+ };
29
+ return timeInputElement;
30
+ };
31
+ export const buildDateTime = ({ readOnly }) => {
32
+ const dateTimeInput = HTMLBuilder.parseElement(`<ez-date-time-input
33
+ class="ez-grid grid_editor"
34
+ mode="slim"
35
+ enabled=${!readOnly}
36
+ data-is-fixed="true"
37
+ />`);
38
+ dateTimeInput.valueGetter = () => dateTimeInput.getValueAsync();
39
+ return dateTimeInput;
40
+ };
@@ -0,0 +1,20 @@
1
+ import { HTMLBuilder } from "@sankhyalabs/core";
2
+ export const buildDecimal = ({ readOnly, props }) => {
3
+ const precision = Number((props === null || props === void 0 ? void 0 : props.precision) || 2);
4
+ const prettyPrecision = Number((props === null || props === void 0 ? void 0 : props.prettyPrecision) || precision);
5
+ return buildNumeric(readOnly, precision, prettyPrecision);
6
+ };
7
+ export const buildInteger = ({ readOnly }) => {
8
+ return buildNumeric(readOnly, 0, 0);
9
+ };
10
+ function buildNumeric(readOnly, precision, prettyPrecision) {
11
+ const input = HTMLBuilder.parseElement(`<ez-number-input
12
+ class="ez-grid grid_editor"
13
+ enabled=${!readOnly}
14
+ precision=${precision}
15
+ pretty-precision=${prettyPrecision}
16
+ mode="slim"
17
+ />`);
18
+ input.valueGetter = () => input.getValueAsync();
19
+ return input;
20
+ }
@@ -0,0 +1,15 @@
1
+ import { ApplicationContext, HTMLBuilder } from '@sankhyalabs/core';
2
+ import { getViewPortHeight } from '../GridEditorUtils';
3
+ export const buildSearch = ({ name, required, readOnly, eGridCell, dataUnit }) => {
4
+ const ezSearch = HTMLBuilder.parseElement(`<ez-search
5
+ class="ez-grid grid_editor"
6
+ mode="slim"
7
+ suppress-empty-option=${required}
8
+ enabled=${!readOnly}
9
+ />`);
10
+ const loader = ApplicationContext.getContextValue("__EZUI__SEARCH__OPTION__LOADER__");
11
+ ezSearch.optionLoader = (argument) => loader(argument, name, dataUnit);
12
+ ezSearch.listOptionsPosition = { verticalPosition: 29, bottomLimit: getViewPortHeight(eGridCell), hardPosition: true };
13
+ ezSearch.valueGetter = () => ezSearch.getValueAsync();
14
+ return ezSearch;
15
+ };
@@ -0,0 +1,41 @@
1
+ import { HTMLBuilder } from "@sankhyalabs/core";
2
+ const MINIMIUM_WIDTH_TEXTAREA = 210;
3
+ const PADDING_VALUE_TEXTAREA = 12;
4
+ export const buildTextInput = ({ name, contextName }) => {
5
+ return HTMLBuilder.parseElement(`<ez-text-input
6
+ class="ez-grid grid_editor"
7
+ data-field-name=${name}
8
+ data-context-name=${contextName}
9
+ mode="slim"
10
+ />`);
11
+ };
12
+ export const buildTextAreaInput = ({ eGridCell, editionManager }) => {
13
+ const element = HTMLBuilder.parseElement(`<ez-text-area
14
+ can-show-error="false"
15
+ enable-resize="true"
16
+ />`);
17
+ element.addEventListener('keydown', event => handlePressEnterEvent(event, element, editionManager));
18
+ setElementInitialWidth(eGridCell, element);
19
+ element.isPopUp = true;
20
+ return element;
21
+ };
22
+ function setElementInitialWidth(eGridCell, element) {
23
+ const { width } = eGridCell.getBoundingClientRect();
24
+ const newValue = width > MINIMIUM_WIDTH_TEXTAREA ? width : MINIMIUM_WIDTH_TEXTAREA;
25
+ element.style.minWidth = `${newValue - PADDING_VALUE_TEXTAREA}px`;
26
+ element.style.resize = "both";
27
+ }
28
+ function handlePressEnterEvent(event, element, editionManager) {
29
+ if (isEnter(event)) {
30
+ const shouldBreakLine = event.ctrlKey;
31
+ if (shouldBreakLine) {
32
+ element.appendTextToSelection('\n');
33
+ event.preventDefault();
34
+ return;
35
+ }
36
+ editionManager.navigateByEnterKey(event);
37
+ }
38
+ }
39
+ function isEnter(event) {
40
+ return [event.key, event.code].includes('Enter');
41
+ }
@@ -28,6 +28,9 @@ export class EzGrid {
28
28
  this.dataUnit = undefined;
29
29
  this.statusResolver = undefined;
30
30
  this.columnfilterDataSource = undefined;
31
+ this.useEnterLikeTab = false;
32
+ this.recordsValidator = undefined;
33
+ this.canEdit = true;
31
34
  }
32
35
  /**
33
36
  * Aplica a definição de colunas.
@@ -261,6 +264,9 @@ export class EzGrid {
261
264
  serverURL: this.serverUrl,
262
265
  dataUnit: this.dataUnit,
263
266
  statusResolver: this.statusResolver,
267
+ useEnterLikeTab: this.useEnterLikeTab,
268
+ recordsValidator: this.recordsValidator,
269
+ editionIsDisabled: () => !this.canEdit
264
270
  });
265
271
  if (this.config) {
266
272
  this.observeConfig(this.config);
@@ -269,6 +275,11 @@ export class EzGrid {
269
275
  this.setEvents();
270
276
  this.componentReady.emit();
271
277
  this._gridController.configFilterColumn(this._filterColumn);
278
+ this._container.addEventListener('focusout', (event) => {
279
+ const api = this._gridController.getGridApi();
280
+ if (api && !this._container.contains(event.relatedTarget))
281
+ api.clearFocusedCell();
282
+ });
272
283
  }
273
284
  componentWillRender() {
274
285
  this.configSelectionCounter();
@@ -472,6 +483,62 @@ export class EzGrid {
472
483
  "tags": [],
473
484
  "text": "Define um `IMultiSelectionListDataSource` respons\u00E1vel por alimentar o filtro de colunas."
474
485
  }
486
+ },
487
+ "useEnterLikeTab": {
488
+ "type": "boolean",
489
+ "mutable": false,
490
+ "complexType": {
491
+ "original": "boolean",
492
+ "resolved": "boolean",
493
+ "references": {}
494
+ },
495
+ "required": false,
496
+ "optional": false,
497
+ "docs": {
498
+ "tags": [],
499
+ "text": "Quando verdadeiro, o ENTER far\u00E1 a navega\u00E7\u00E3o como se fosse a tecla TAB na grade."
500
+ },
501
+ "attribute": "use-enter-like-tab",
502
+ "reflect": false,
503
+ "defaultValue": "false"
504
+ },
505
+ "recordsValidator": {
506
+ "type": "unknown",
507
+ "mutable": false,
508
+ "complexType": {
509
+ "original": "IRecordValidator",
510
+ "resolved": "IRecordValidator",
511
+ "references": {
512
+ "IRecordValidator": {
513
+ "location": "import",
514
+ "path": "../../utils/form/interfaces"
515
+ }
516
+ }
517
+ },
518
+ "required": false,
519
+ "optional": false,
520
+ "docs": {
521
+ "tags": [],
522
+ "text": "Define um validador respons\u00E1vel pela integridade dos registros."
523
+ }
524
+ },
525
+ "canEdit": {
526
+ "type": "boolean",
527
+ "mutable": false,
528
+ "complexType": {
529
+ "original": "boolean",
530
+ "resolved": "boolean",
531
+ "references": {}
532
+ },
533
+ "required": false,
534
+ "optional": false,
535
+ "docs": {
536
+ "tags": [],
537
+ "text": "Define se a edi\u00E7\u00E3o est\u00E1 habilitada na grid."
538
+ },
539
+ "attribute": "can-edit",
540
+ "reflect": false,
541
+ "defaultValue": "true"
475
542
  }
476
543
  };
477
544
  }