@wavemaker/app-ng-runtime 11.14.1-3.6306 → 11.14.1-32.647748
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/components/base/bundles/index.umd.js +6 -22
- package/components/base/esm2022/pipes/custom-pipes.mjs +1 -1
- package/components/base/esm2022/widgets/common/base/base.component.mjs +8 -24
- package/components/base/fesm2022/index.mjs +7 -23
- package/components/base/fesm2022/index.mjs.map +1 -1
- package/components/chart/bundles/index.umd.js +2 -2
- package/components/chart/esm2022/chart.utils.mjs +3 -3
- package/components/chart/fesm2022/index.mjs +2 -2
- package/components/chart/fesm2022/index.mjs.map +1 -1
- package/components/containers/wizard/bundles/index.umd.js +21 -2
- package/components/containers/wizard/esm2022/wizard-step/wizard-step.component.mjs +3 -1
- package/components/containers/wizard/esm2022/wizard.component.mjs +20 -3
- package/components/containers/wizard/fesm2022/index.mjs +21 -2
- package/components/containers/wizard/fesm2022/index.mjs.map +1 -1
- package/components/containers/wizard/wizard-step/wizard-step.component.d.ts +2 -0
- package/components/data/pagination/bundles/index.umd.js +6 -1
- package/components/data/pagination/esm2022/pagination.component.mjs +7 -2
- package/components/data/pagination/fesm2022/index.mjs +6 -1
- package/components/data/pagination/fesm2022/index.mjs.map +1 -1
- package/components/data/table/bundles/index.umd.js +331 -23
- package/components/data/table/esm2022/table-action/table-action.directive.mjs +8 -1
- package/components/data/table/esm2022/table-column/table-column.directive.mjs +108 -4
- package/components/data/table/esm2022/table-column-group/table-column-group.directive.mjs +9 -1
- package/components/data/table/esm2022/table-cud.directive.mjs +22 -5
- package/components/data/table/esm2022/table-filter.directive.mjs +43 -4
- package/components/data/table/esm2022/table-row/table-row.directive.mjs +8 -1
- package/components/data/table/esm2022/table-row-action/table-row-action.directive.mjs +8 -1
- package/components/data/table/esm2022/table.component.mjs +134 -15
- package/components/data/table/fesm2022/index.mjs +333 -25
- package/components/data/table/fesm2022/index.mjs.map +1 -1
- package/components/data/table/table-action/table-action.directive.d.ts +3 -2
- package/components/data/table/table-column/table-column.directive.d.ts +3 -2
- package/components/data/table/table-column-group/table-column-group.directive.d.ts +3 -2
- package/components/data/table/table-cud.directive.d.ts +3 -1
- package/components/data/table/table-filter.directive.d.ts +3 -1
- package/components/data/table/table-row/table-row.directive.d.ts +3 -2
- package/components/data/table/table-row-action/table-row-action.directive.d.ts +3 -2
- package/components/data/table/table.component.d.ts +10 -0
- package/components/page/default/bundles/index.umd.js +1 -0
- package/components/page/default/esm2022/page.directive.mjs +2 -1
- package/components/page/default/fesm2022/index.mjs +1 -0
- package/components/page/default/fesm2022/index.mjs.map +1 -1
- package/core/bundles/index.umd.js +185 -330
- package/core/esm2022/public_api.mjs +2 -2
- package/core/esm2022/utils/watcher.mjs +189 -328
- package/core/fesm2022/index.mjs +192 -330
- package/core/fesm2022/index.mjs.map +1 -1
- package/core/public_api.d.ts +1 -1
- package/core/utils/watcher.d.ts +5 -26
- package/locales/moment-timezone/moment-timezone-with-data.js +179 -27
- package/npm-shrinkwrap.json +2 -2
- package/package-lock.json +2 -2
- package/package.json +1 -1
- package/runtime/base/bundles/index.umd.js +20 -46
- package/runtime/base/components/base-prefab.component.d.ts +6 -4
- package/runtime/base/esm2022/components/app-component/app.component.mjs +2 -7
- package/runtime/base/esm2022/components/base-page.component.mjs +2 -8
- package/runtime/base/esm2022/components/base-partial.component.mjs +3 -11
- package/runtime/base/esm2022/components/base-prefab.component.mjs +21 -21
- package/runtime/base/esm2022/components/base-spa-page.component.mjs +2 -9
- package/runtime/base/fesm2022/index.mjs +21 -47
- package/runtime/base/fesm2022/index.mjs.map +1 -1
- package/runtime/dynamic/bundles/index.umd.js +4 -0
- package/runtime/dynamic/esm2022/app/app.config.mjs +6 -2
- package/runtime/dynamic/fesm2022/index.mjs +5 -1
- package/runtime/dynamic/fesm2022/index.mjs.map +1 -1
- package/scripts/datatable/datatable.js +336 -33
|
@@ -108,7 +108,7 @@
|
|
|
108
108
|
const ROW_OPS_FIELD = 'rowOperations';
|
|
109
109
|
const noop = () => { };
|
|
110
110
|
const isInputBodyWrapper = target => {
|
|
111
|
-
const classes = ['.dropdown-menu', '.uib-typeahead-match', '.modal-dialog', '.toast'];
|
|
111
|
+
const classes = ['.dropdown-menu', '.uib-typeahead-match', '.modal-dialog', '.toast', '.bs-datepicker-container'];
|
|
112
112
|
let isInput = false;
|
|
113
113
|
classes.forEach(cls => {
|
|
114
114
|
if (target.closest(cls).length) {
|
|
@@ -129,6 +129,19 @@
|
|
|
129
129
|
};
|
|
130
130
|
class TableComponent extends i4.StylableComponent {
|
|
131
131
|
static { this.initializeProps = registerProps$5(); }
|
|
132
|
+
/** wm.Variable + inline or quickedit (editmode is string from markup; normalize case). */
|
|
133
|
+
isModelVariableInlineOrQuickEdit() {
|
|
134
|
+
if (lodashEs.get(this.datasource, 'category') !== 'wm.Variable') {
|
|
135
|
+
return false;
|
|
136
|
+
}
|
|
137
|
+
const em = String(this.editmode || '').toLowerCase();
|
|
138
|
+
return em === 'quickedit' || em === 'inline';
|
|
139
|
+
}
|
|
140
|
+
/** True while an inline/quickedit row save is updating the grid (incl. delayed navigator emit). */
|
|
141
|
+
shouldSoftRefreshAfterModelVarRowSave() {
|
|
142
|
+
return this.isModelVariableInlineOrQuickEdit()
|
|
143
|
+
&& (this._isInlineEditSave || this._modelVarEditSoftRefreshActiveUntil > Date.now());
|
|
144
|
+
}
|
|
132
145
|
set gridData(newValue) {
|
|
133
146
|
this.isDataLoading = false;
|
|
134
147
|
// Fix for [WMS-24012]: hide no datafound msg when variableInflight is true and dataset is empty
|
|
@@ -196,7 +209,14 @@
|
|
|
196
209
|
console.warn('Error in beforedatarender event callback, continuing with table rendering:', error);
|
|
197
210
|
}
|
|
198
211
|
}
|
|
199
|
-
|
|
212
|
+
if (this.shouldSoftRefreshAfterModelVarRowSave()) {
|
|
213
|
+
const clonedData = i2.getClonedObject(this._gridData);
|
|
214
|
+
this.gridOptions.data = clonedData;
|
|
215
|
+
this.callDataGridMethod('softRefreshData', clonedData);
|
|
216
|
+
}
|
|
217
|
+
else {
|
|
218
|
+
this.setDataGridOption('data', i2.getClonedObject(this._gridData));
|
|
219
|
+
}
|
|
200
220
|
}
|
|
201
221
|
}
|
|
202
222
|
get gridData() {
|
|
@@ -249,6 +269,8 @@
|
|
|
249
269
|
this.formfields = {};
|
|
250
270
|
this.enablesort = true;
|
|
251
271
|
this.showviewlessbutton = false;
|
|
272
|
+
/** Covers async navigator/dataset updates after inline/quickedit save (wm.Variable). */
|
|
273
|
+
this._modelVarEditSoftRefreshActiveUntil = 0;
|
|
252
274
|
this.primaryKey = [];
|
|
253
275
|
this.selectedItems = [];
|
|
254
276
|
this.selectedItemChange = new rxjs.Subject();
|
|
@@ -587,7 +609,25 @@
|
|
|
587
609
|
this.prevData = i2.getClonedObject(row);
|
|
588
610
|
},
|
|
589
611
|
afterRowUpdate: (row, e, callBack, options) => {
|
|
590
|
-
|
|
612
|
+
const isModelVarInlineOrQuick = this.isModelVariableInlineOrQuickEdit();
|
|
613
|
+
if (isModelVarInlineOrQuick) {
|
|
614
|
+
this._isInlineEditSave = true;
|
|
615
|
+
// Inline save triggers navigatePage / dataset emit asynchronously; a
|
|
616
|
+
// microtask timeout cleared the flag before gridData ran → full rerender.
|
|
617
|
+
this._modelVarEditSoftRefreshActiveUntil = Date.now() + 550;
|
|
618
|
+
}
|
|
619
|
+
i2.muteWatchers();
|
|
620
|
+
const v = lodashEs.get(this.datasource, 'category') === 'wm.Variable' && options && options.rowindex != null;
|
|
621
|
+
this.updateRecord(lodashEs.extend({}, options, { row, prevData: v ? options.rowindex : this.prevData, event: e, callBack }));
|
|
622
|
+
setTimeout(() => {
|
|
623
|
+
i2.unMuteWatchers();
|
|
624
|
+
if (isModelVarInlineOrQuick) {
|
|
625
|
+
setTimeout(() => {
|
|
626
|
+
this._isInlineEditSave = false;
|
|
627
|
+
this._modelVarEditSoftRefreshActiveUntil = 0;
|
|
628
|
+
}, 520);
|
|
629
|
+
}
|
|
630
|
+
}, 10);
|
|
591
631
|
},
|
|
592
632
|
onBeforeRowUpdate: (row, e, options) => {
|
|
593
633
|
return this.invokeEventCallback('beforerowupdate', { $event: e, $data: row, row, options: options });
|
|
@@ -659,11 +699,67 @@
|
|
|
659
699
|
this.customExprCompiledTl = {};
|
|
660
700
|
this.customExprCompiledSummaryTl = {};
|
|
661
701
|
},
|
|
702
|
+
updateCustomExpressionContexts: (preparedData) => {
|
|
703
|
+
const viewCount = this.customExprViewRef.length;
|
|
704
|
+
for (let i = 0; i < viewCount; i++) {
|
|
705
|
+
const viewRef = this.customExprViewRef.get(i);
|
|
706
|
+
if (!viewRef || !viewRef.context || !viewRef.context.row || viewRef.context.row.$index === undefined) {
|
|
707
|
+
continue;
|
|
708
|
+
}
|
|
709
|
+
const existingRow = viewRef.context.row;
|
|
710
|
+
const rowIndex = existingRow.$index - 1;
|
|
711
|
+
const dataRow = preparedData[rowIndex];
|
|
712
|
+
if (!dataRow) {
|
|
713
|
+
continue;
|
|
714
|
+
}
|
|
715
|
+
Object.keys(dataRow).forEach(key => {
|
|
716
|
+
if (key !== '$$index' && key !== '$$pk') {
|
|
717
|
+
existingRow[key] = dataRow[key];
|
|
718
|
+
}
|
|
719
|
+
});
|
|
720
|
+
existingRow.$isFirst = existingRow.$index === 1;
|
|
721
|
+
existingRow.$isLast = this.gridData.length === existingRow.$index;
|
|
722
|
+
viewRef.markForCheck();
|
|
723
|
+
}
|
|
724
|
+
},
|
|
662
725
|
clearRowDetailExpression: () => {
|
|
663
726
|
this.rowDetailViewRef.clear();
|
|
664
727
|
this.rowDefMap = {};
|
|
665
728
|
this.rowDefInstances = {};
|
|
666
729
|
},
|
|
730
|
+
invalidateRowDetailCache: (preparedData) => {
|
|
731
|
+
this.rowDefMap = {};
|
|
732
|
+
this.rowDefInstances = {};
|
|
733
|
+
// Update existing row detail view contexts in-place so currently
|
|
734
|
+
// expanded partials pick up the new row data via change detection.
|
|
735
|
+
const viewCount = this.rowDetailViewRef.length;
|
|
736
|
+
for (let i = 0; i < viewCount; i++) {
|
|
737
|
+
const viewRef = this.rowDetailViewRef.get(i);
|
|
738
|
+
if (!viewRef || !viewRef.context || !viewRef.context.row) {
|
|
739
|
+
continue;
|
|
740
|
+
}
|
|
741
|
+
const existingRow = viewRef.context.row;
|
|
742
|
+
const rowIndex = existingRow.$index - 1;
|
|
743
|
+
const dataRow = preparedData[rowIndex];
|
|
744
|
+
if (!dataRow) {
|
|
745
|
+
continue;
|
|
746
|
+
}
|
|
747
|
+
Object.keys(dataRow).forEach(key => {
|
|
748
|
+
if (key !== '$$index' && key !== '$$pk') {
|
|
749
|
+
existingRow[key] = dataRow[key];
|
|
750
|
+
}
|
|
751
|
+
});
|
|
752
|
+
viewRef.markForCheck();
|
|
753
|
+
}
|
|
754
|
+
},
|
|
755
|
+
refreshSelectedItems: () => {
|
|
756
|
+
const selectedRows = this.callDataGridMethod('getSelectedRows');
|
|
757
|
+
if (selectedRows.length) {
|
|
758
|
+
this.items.length = 0;
|
|
759
|
+
selectedRows.forEach(row => this.items.push(row));
|
|
760
|
+
this.selectedItemChange.next(selectedRows);
|
|
761
|
+
}
|
|
762
|
+
},
|
|
667
763
|
generateCustomExpressions: (rowData, index, summaryRow) => {
|
|
668
764
|
const row = this.getClonedRowObject(rowData);
|
|
669
765
|
const compileTemplate = (tmpl) => {
|
|
@@ -1125,7 +1221,9 @@
|
|
|
1125
1221
|
this.applyProps.forEach(args => this.callDataGridMethod(...args));
|
|
1126
1222
|
if (this.editmode === i4.EDIT_MODE.QUICK_EDIT) {
|
|
1127
1223
|
this.documentClickBind = this._documentClickBind.bind(this);
|
|
1128
|
-
|
|
1224
|
+
// Use capture phase so a click on another grid (which calls stopPropagation) still reaches this
|
|
1225
|
+
// listener and lets the current grid save/close its editing row.
|
|
1226
|
+
document.addEventListener('click', this.documentClickBind, true);
|
|
1129
1227
|
}
|
|
1130
1228
|
}
|
|
1131
1229
|
getConfiguredState() {
|
|
@@ -1351,8 +1449,10 @@
|
|
|
1351
1449
|
}
|
|
1352
1450
|
}
|
|
1353
1451
|
ngOnDestroy() {
|
|
1452
|
+
this._modelVarEditSoftRefreshActiveUntil = 0;
|
|
1453
|
+
this._isInlineEditSave = false;
|
|
1354
1454
|
// MEMORY LEAK FIX: Remove document click listener
|
|
1355
|
-
document.removeEventListener('click', this.documentClickBind);
|
|
1455
|
+
document.removeEventListener('click', this.documentClickBind, true);
|
|
1356
1456
|
// MEMORY LEAK FIX: Unsubscribe from navigator watches
|
|
1357
1457
|
if (this.navigatorResultWatch) {
|
|
1358
1458
|
this.navigatorResultWatch.unsubscribe();
|
|
@@ -1411,7 +1511,6 @@
|
|
|
1411
1511
|
this.selectedItems = [];
|
|
1412
1512
|
this.fieldDefs = [];
|
|
1413
1513
|
this.fullFieldDefs = [];
|
|
1414
|
-
this.gridData = [];
|
|
1415
1514
|
this.__fullData = null;
|
|
1416
1515
|
// MEMORY LEAK FIX: Destroy jQuery datatable widget before clearing gridOptions
|
|
1417
1516
|
if (this.datagridElement && this.datagridElement.datatable) {
|
|
@@ -1524,6 +1623,7 @@
|
|
|
1524
1623
|
row.$isLast = this.gridData.length === row.$index;
|
|
1525
1624
|
delete row.$$index;
|
|
1526
1625
|
delete row.$$pk;
|
|
1626
|
+
delete row.$$wmSourceListIndex;
|
|
1527
1627
|
return row;
|
|
1528
1628
|
}
|
|
1529
1629
|
handleLoading(data) {
|
|
@@ -1765,6 +1865,14 @@
|
|
|
1765
1865
|
// Apply filter and sort, if data is refreshed through Refresh data method
|
|
1766
1866
|
if (!this.isNavigationEnabled() && this._isClientSearch) {
|
|
1767
1867
|
data = i2.getClonedObject(serviceData);
|
|
1868
|
+
if (lodashEs.isObject(data) && !lodashEs.isArray(data)) {
|
|
1869
|
+
data = [data];
|
|
1870
|
+
}
|
|
1871
|
+
if (lodashEs.get(this.datasource, 'category') === 'wm.Variable' && lodashEs.isArray(data)) {
|
|
1872
|
+
for (let i = 0; i < data.length; i++) {
|
|
1873
|
+
data[i].$$wmSourceListIndex = i;
|
|
1874
|
+
}
|
|
1875
|
+
}
|
|
1768
1876
|
data = this.getSearchResult(data, this.filterInfo);
|
|
1769
1877
|
data = this.getSortResult(data, this.sortInfo);
|
|
1770
1878
|
this.serverData = data;
|
|
@@ -1946,10 +2054,7 @@
|
|
|
1946
2054
|
this.headerselectall = false;
|
|
1947
2055
|
this.setDataGridOption("headerselectall", false);
|
|
1948
2056
|
}
|
|
1949
|
-
|
|
1950
|
-
if (this.datasource && this.dataset !== undefined) {
|
|
1951
|
-
this.watchVariableDataSet(this.dataset);
|
|
1952
|
-
}
|
|
2057
|
+
this.watchVariableDataSet(this.dataset);
|
|
1953
2058
|
this.onDataSourceChange();
|
|
1954
2059
|
break;
|
|
1955
2060
|
case 'dataset':
|
|
@@ -2094,6 +2199,10 @@
|
|
|
2094
2199
|
case 'show':
|
|
2095
2200
|
if (nv) {
|
|
2096
2201
|
this.invokeEventCallback('show');
|
|
2202
|
+
// recompute layout now that the table is visible again
|
|
2203
|
+
if (this.datagridElement) {
|
|
2204
|
+
this.redraw(false);
|
|
2205
|
+
}
|
|
2097
2206
|
}
|
|
2098
2207
|
else {
|
|
2099
2208
|
this.invokeEventCallback('hide');
|
|
@@ -2268,6 +2377,11 @@
|
|
|
2268
2377
|
if (lodashEs.isObject(data) && !lodashEs.isArray(data)) {
|
|
2269
2378
|
data = [data];
|
|
2270
2379
|
}
|
|
2380
|
+
if (lodashEs.get(this.datasource, 'category') === 'wm.Variable' && lodashEs.isArray(data)) {
|
|
2381
|
+
for (let i = 0; i < data.length; i++) {
|
|
2382
|
+
data[i].$$wmSourceListIndex = i;
|
|
2383
|
+
}
|
|
2384
|
+
}
|
|
2271
2385
|
data = this.getSearchResult(data, this.filterInfo);
|
|
2272
2386
|
data = this.getSortResult(data, this.sortInfo);
|
|
2273
2387
|
return data;
|
|
@@ -2328,11 +2442,16 @@
|
|
|
2328
2442
|
}
|
|
2329
2443
|
_documentClickBind(event) {
|
|
2330
2444
|
const $target = event.target;
|
|
2331
|
-
// If click
|
|
2445
|
+
// If the click is within this table, a dialog, or a date picker, do not save the row.
|
|
2332
2446
|
if (this.$element[0].contains($target) || event.target.doctype || isInputBodyWrapper($($target))) {
|
|
2333
2447
|
return;
|
|
2334
2448
|
}
|
|
2335
|
-
this.
|
|
2449
|
+
// If click is inside another datatable, that table's edit handler saves this row — skip to avoid a duplicate save. [WMS-31104]
|
|
2450
|
+
if ($($target).closest('.app-datagrid').length) {
|
|
2451
|
+
return;
|
|
2452
|
+
}
|
|
2453
|
+
// Click is outside all tables — save the editing row without returning focus to this table. [WMS-31104]
|
|
2454
|
+
this.callDataGridMethod('saveRow', undefined, true);
|
|
2336
2455
|
}
|
|
2337
2456
|
_redraw(forceRender) {
|
|
2338
2457
|
if (forceRender) {
|
|
@@ -2340,7 +2459,7 @@
|
|
|
2340
2459
|
}
|
|
2341
2460
|
else {
|
|
2342
2461
|
setTimeout(() => {
|
|
2343
|
-
this.callDataGridMethod('setColGroupWidths');
|
|
2462
|
+
this.callDataGridMethod(forceRender === false ? 'refreshColumnWidths' : 'setColGroupWidths');
|
|
2344
2463
|
this.callDataGridMethod('addOrRemoveScroll');
|
|
2345
2464
|
});
|
|
2346
2465
|
}
|
|
@@ -2670,11 +2789,11 @@
|
|
|
2670
2789
|
this.table.toggleMessage(true, 'success', this.table.updatemessage);
|
|
2671
2790
|
}
|
|
2672
2791
|
if (this.table.datasource.execute(i2.DataSource.Operation.SUPPORTS_CRUD)) {
|
|
2673
|
-
this.table.initiateSelectItem('current', response,
|
|
2792
|
+
this.table.initiateSelectItem('current', response, options.skipFocus, false, options.callBack);
|
|
2674
2793
|
this.updateVariable(response, options.callBack);
|
|
2675
2794
|
}
|
|
2676
2795
|
else if (!this.table.datasource.execute(i2.DataSource.Operation.IS_API_AWARE)) {
|
|
2677
|
-
this.table.initiateSelectItem('current', response,
|
|
2796
|
+
this.table.initiateSelectItem('current', response, options.skipFocus, this.table.datasource.category === 'wm.Variable', options.callBack);
|
|
2678
2797
|
}
|
|
2679
2798
|
i2.triggerFn(options.success, response);
|
|
2680
2799
|
this.table.invokeEventCallback('rowupdate', { $event: options.event, $data: response, row: response });
|
|
@@ -2695,7 +2814,11 @@
|
|
|
2695
2814
|
if (dataSource.execute(i2.DataSource.Operation.SUPPORTS_CRUD) || !dataSource.execute(i2.DataSource.Operation.IS_API_AWARE) || dataSource.category === 'wm.CrudVariable') {
|
|
2696
2815
|
if (!dataSource.execute(i2.DataSource.Operation.IS_API_AWARE)) {
|
|
2697
2816
|
const extraOptions = this.generatePath(this.table.binddataset);
|
|
2698
|
-
|
|
2817
|
+
const item = options.row;
|
|
2818
|
+
if (dataSource.category === 'wm.Variable' && item) {
|
|
2819
|
+
delete item['$$wmSourceListIndex'];
|
|
2820
|
+
}
|
|
2821
|
+
dataSource.execute(i2.DataSource.Operation.SET_ITEM, { prevItem: options.prevData, item, path: extraOptions.path, parentIndex: extraOptions.index });
|
|
2699
2822
|
this.updateSuccessHandler(options.row, options);
|
|
2700
2823
|
return;
|
|
2701
2824
|
}
|
|
@@ -2778,7 +2901,14 @@
|
|
|
2778
2901
|
if (dataSource.execute(i2.DataSource.Operation.SUPPORTS_CRUD) || !dataSource.execute(i2.DataSource.Operation.IS_API_AWARE) || this.table._isDependent || dataSource.category === 'wm.CrudVariable') {
|
|
2779
2902
|
if (!dataSource.execute(i2.DataSource.Operation.IS_API_AWARE)) {
|
|
2780
2903
|
const extraOptions = this.generatePath(this.table.binddataset);
|
|
2781
|
-
|
|
2904
|
+
let item = options.row;
|
|
2905
|
+
if (dataSource.category === 'wm.Variable' && options.rowindex != null) {
|
|
2906
|
+
item = options.rowindex;
|
|
2907
|
+
}
|
|
2908
|
+
else if (dataSource.category === 'wm.Variable' && item) {
|
|
2909
|
+
delete item['$$wmSourceListIndex'];
|
|
2910
|
+
}
|
|
2911
|
+
dataSource.execute(i2.DataSource.Operation.REMOVE_ITEM, { item, path: extraOptions.path, parentIndex: extraOptions.index });
|
|
2782
2912
|
this.deleteSuccessHandler(options.row, undefined, options.evt, options.callBack);
|
|
2783
2913
|
return;
|
|
2784
2914
|
}
|
|
@@ -2924,6 +3054,12 @@
|
|
|
2924
3054
|
this.table.callDataGridMethod('cancelEdit', $row);
|
|
2925
3055
|
}
|
|
2926
3056
|
}
|
|
3057
|
+
ngOnDestroy() {
|
|
3058
|
+
// MEMORY LEAK FIX: Clear all references
|
|
3059
|
+
this.table = null;
|
|
3060
|
+
this.dialogService = null;
|
|
3061
|
+
this.app = null;
|
|
3062
|
+
}
|
|
2927
3063
|
static { this.ɵfac = i0__namespace.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0__namespace, type: TableCUDDirective, deps: [{ token: TableComponent, self: true }, { token: i2__namespace.AbstractDialogService }, { token: i2__namespace.App }], target: i0__namespace.ɵɵFactoryTarget.Directive }); }
|
|
2928
3064
|
static { this.ɵdir = i0__namespace.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.2.13", type: TableCUDDirective, isStandalone: true, selector: "[wmTableCUD]", ngImport: i0__namespace }); }
|
|
2929
3065
|
}
|
|
@@ -3235,7 +3371,19 @@
|
|
|
3235
3371
|
}
|
|
3236
3372
|
// Function that checks if a given string is a valid date and returns the timestamp if it is, or NaN if it's not.
|
|
3237
3373
|
parseDateString(dateString) {
|
|
3374
|
+
if (typeof dateString !== 'string') {
|
|
3375
|
+
return NaN;
|
|
3376
|
+
}
|
|
3377
|
+
const trimmed = dateString.trim();
|
|
3378
|
+
if (!trimmed) {
|
|
3379
|
+
return NaN;
|
|
3380
|
+
}
|
|
3238
3381
|
const timestamp = Date.parse(dateString);
|
|
3382
|
+
// handling case when string starts with string and end with number
|
|
3383
|
+
const monthRegex = /\b(?:Jan(?:uary)?|Feb(?:ruary)?|Mar(?:ch)?|Apr(?:il)?|May|Jun(?:e)?|Jul(?:y)?|Aug(?:ust)?|Sep(?:t(?:ember)?)?|Oct(?:ober)?|Nov(?:ember)?|Dec(?:ember)?)\b/i;
|
|
3384
|
+
if (/^[A-Za-z]+/.test(trimmed) && /\d+$/.test(trimmed) && !monthRegex.test(trimmed)) {
|
|
3385
|
+
return NaN;
|
|
3386
|
+
}
|
|
3239
3387
|
if (!isNaN(timestamp)) {
|
|
3240
3388
|
return timestamp;
|
|
3241
3389
|
}
|
|
@@ -3247,20 +3395,38 @@
|
|
|
3247
3395
|
// Returns data sorted using sortObj
|
|
3248
3396
|
getSortResult(data, sortObj) {
|
|
3249
3397
|
if (sortObj && sortObj.direction) {
|
|
3250
|
-
const
|
|
3398
|
+
const sampleItem = lodashEs.find(data, (item) => {
|
|
3399
|
+
const v = lodashEs.get(item, sortObj.field);
|
|
3400
|
+
return typeof v === 'string' && !!v.trim();
|
|
3401
|
+
});
|
|
3402
|
+
const fieldValue = sampleItem ? lodashEs.get(sampleItem, sortObj.field) : undefined;
|
|
3251
3403
|
const isValidDateString = typeof fieldValue === 'string' ? this.parseDateString(fieldValue) : NaN;
|
|
3252
3404
|
if (!isNaN(isValidDateString)) { // if the field is a date string
|
|
3253
|
-
data = lodashEs.orderBy(data, [
|
|
3405
|
+
data = lodashEs.orderBy(data, [
|
|
3406
|
+
(item) => {
|
|
3407
|
+
const v = lodashEs.get(item, sortObj.field);
|
|
3408
|
+
return v === null || v === undefined || v === '' ? 1 : 0;
|
|
3409
|
+
},
|
|
3410
|
+
(item) => {
|
|
3411
|
+
const ts = this.parseDateString(lodashEs.get(item, sortObj.field));
|
|
3412
|
+
return isNaN(ts) ? 1 : 0;
|
|
3413
|
+
},
|
|
3414
|
+
(item) => this.parseDateString(lodashEs.get(item, sortObj.field))
|
|
3415
|
+
], ['asc', 'asc', sortObj.direction]);
|
|
3254
3416
|
}
|
|
3255
3417
|
else if (sortObj.sortBy ? this.table.columns[sortObj.sortBy]?.caseinsensitive : this.table.columns[sortObj.field]?.caseinsensitive) {
|
|
3256
3418
|
//Fix for [WMS-27505]: Added case-insensitive sorting so that uppercase and lowercase letters are treated the same when sorting.
|
|
3257
3419
|
data = lodashEs.orderBy(data, [
|
|
3420
|
+
(item) => {
|
|
3421
|
+
const val = lodashEs.get(item, sortObj.field);
|
|
3422
|
+
return val === null || val === undefined || val === '' ? 1 : 0;
|
|
3423
|
+
},
|
|
3258
3424
|
(item) => {
|
|
3259
3425
|
const val = lodashEs.get(item, sortObj.field);
|
|
3260
3426
|
return typeof val === 'string' ? val.toLowerCase() : val;
|
|
3261
3427
|
},
|
|
3262
3428
|
(item) => lodashEs.get(item, sortObj.field) // fallback to original value
|
|
3263
|
-
], [sortObj.direction, sortObj.direction]);
|
|
3429
|
+
], ['asc', sortObj.direction, sortObj.direction]);
|
|
3264
3430
|
}
|
|
3265
3431
|
else {
|
|
3266
3432
|
data = lodashEs.orderBy(data, sortObj.field, sortObj.direction);
|
|
@@ -3282,6 +3448,11 @@
|
|
|
3282
3448
|
if (lodashEs.isObject(data) && !lodashEs.isArray(data)) {
|
|
3283
3449
|
data = [data];
|
|
3284
3450
|
}
|
|
3451
|
+
if (lodashEs.get(this.table.datasource, 'category') === 'wm.Variable' && lodashEs.isArray(data)) {
|
|
3452
|
+
for (let i = 0; i < data.length; i++) {
|
|
3453
|
+
data[i].$$wmSourceListIndex = i;
|
|
3454
|
+
}
|
|
3455
|
+
}
|
|
3285
3456
|
/*Both the functions return same 'data' if arguments are undefined*/
|
|
3286
3457
|
data = this.getSearchResult(data, this.table.filterInfo);
|
|
3287
3458
|
data = this.getSortResult(data, this.table.sortInfo);
|
|
@@ -3612,6 +3783,10 @@
|
|
|
3612
3783
|
condition: logicalOp
|
|
3613
3784
|
});
|
|
3614
3785
|
}
|
|
3786
|
+
ngOnDestroy() {
|
|
3787
|
+
// MEMORY LEAK FIX: Clear table reference
|
|
3788
|
+
this.table = null;
|
|
3789
|
+
}
|
|
3615
3790
|
static { this.ɵfac = i0__namespace.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0__namespace, type: TableFilterSortDirective, deps: [{ token: TableComponent, self: true }], target: i0__namespace.ɵɵFactoryTarget.Directive }); }
|
|
3616
3791
|
static { this.ɵdir = i0__namespace.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.2.13", type: TableFilterSortDirective, isStandalone: true, selector: "[wmTableFilterSort]", ngImport: i0__namespace }); }
|
|
3617
3792
|
}
|
|
@@ -3698,6 +3873,13 @@
|
|
|
3698
3873
|
this.buttonDef[key] = nv;
|
|
3699
3874
|
}
|
|
3700
3875
|
}
|
|
3876
|
+
ngOnDestroy() {
|
|
3877
|
+
// MEMORY LEAK FIX: Clear table and buttonDef references
|
|
3878
|
+
this.table = null;
|
|
3879
|
+
this.buttonDef = null;
|
|
3880
|
+
// Call parent ngOnDestroy (BaseComponent has cleanup)
|
|
3881
|
+
super.ngOnDestroy();
|
|
3882
|
+
}
|
|
3701
3883
|
static { this.ɵfac = i0__namespace.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0__namespace, type: TableActionDirective, deps: [{ token: i0__namespace.Injector }, { token: TableComponent, optional: true }, { token: 'EXPLICIT_CONTEXT', optional: true }], target: i0__namespace.ɵɵFactoryTarget.Directive }); }
|
|
3702
3884
|
static { this.ɵdir = i0__namespace.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.2.13", type: TableActionDirective, isStandalone: true, selector: "[wmTableAction]", providers: [
|
|
3703
3885
|
i4.provideAsWidgetRef(TableActionDirective)
|
|
@@ -3862,6 +4044,14 @@
|
|
|
3862
4044
|
const fieldName = this.group && this.group.name;
|
|
3863
4045
|
i4.setHeaderConfigForTable(this.table.headerConfig, this.config, fieldName, fieldName ? colIndex : headerIndex);
|
|
3864
4046
|
}
|
|
4047
|
+
ngOnDestroy() {
|
|
4048
|
+
// MEMORY LEAK FIX: Clear table, group, and config references
|
|
4049
|
+
this.table = null;
|
|
4050
|
+
this.group = null;
|
|
4051
|
+
this.config = null;
|
|
4052
|
+
// Call parent ngOnDestroy (BaseComponent has cleanup)
|
|
4053
|
+
super.ngOnDestroy();
|
|
4054
|
+
}
|
|
3865
4055
|
static { this.ɵfac = i0__namespace.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0__namespace, type: TableColumnGroupDirective, deps: [{ token: i0__namespace.Injector }, { token: TableColumnGroupDirective, optional: true, skipSelf: true }, { token: TableComponent, optional: true }, { token: 'EXPLICIT_CONTEXT', optional: true }], target: i0__namespace.ɵɵFactoryTarget.Directive }); }
|
|
3866
4056
|
static { this.ɵdir = i0__namespace.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.2.13", type: TableColumnGroupDirective, isStandalone: true, selector: "[wmTableColumnGroup]", providers: [
|
|
3867
4057
|
i4.provideAsWidgetRef(TableColumnGroupDirective)
|
|
@@ -4056,6 +4246,10 @@
|
|
|
4056
4246
|
}
|
|
4057
4247
|
// Remove validators for the inline widget and set form to untouched
|
|
4058
4248
|
removeValidations() {
|
|
4249
|
+
// Guard against component destruction or table/ngform being null
|
|
4250
|
+
if (this.isDestroyed || !this.table || !this.table.ngform) {
|
|
4251
|
+
return;
|
|
4252
|
+
}
|
|
4059
4253
|
this.table.ngform.markAsUntouched();
|
|
4060
4254
|
const control = this.getFormControl();
|
|
4061
4255
|
if (!control) {
|
|
@@ -4067,6 +4261,10 @@
|
|
|
4067
4261
|
}
|
|
4068
4262
|
// Apply default|sync|async|prop validators for QuickEdit new row form control
|
|
4069
4263
|
applyNewRowValidations() {
|
|
4264
|
+
// Guard against component destruction or table/ngform being null
|
|
4265
|
+
if (this.isDestroyed || !this.table || !this.table.ngform) {
|
|
4266
|
+
return;
|
|
4267
|
+
}
|
|
4070
4268
|
if (!this._checkNewEditableRowControl()) {
|
|
4071
4269
|
return;
|
|
4072
4270
|
}
|
|
@@ -4083,22 +4281,37 @@
|
|
|
4083
4281
|
}
|
|
4084
4282
|
// Remove validators for the QuickEdit new row widget and set form to untouched
|
|
4085
4283
|
removeNewRowValidations() {
|
|
4284
|
+
// Guard against component destruction or table/ngform being null
|
|
4285
|
+
if (this.isDestroyed || !this.table || !this.table.ngform) {
|
|
4286
|
+
return;
|
|
4287
|
+
}
|
|
4086
4288
|
this.table.ngform.markAsUntouched();
|
|
4087
4289
|
if (!this._checkNewEditableRowControl()) {
|
|
4088
4290
|
return;
|
|
4089
4291
|
}
|
|
4090
4292
|
const control = this.getFormControl('_new');
|
|
4293
|
+
if (!control) {
|
|
4294
|
+
return;
|
|
4295
|
+
}
|
|
4091
4296
|
control.clearValidators();
|
|
4092
4297
|
control.clearAsyncValidators();
|
|
4093
4298
|
control.updateValueAndValidity();
|
|
4094
4299
|
}
|
|
4095
4300
|
addFormControl(suffix) {
|
|
4301
|
+
// Guard against component destruction or table/ngform being null
|
|
4302
|
+
if (this.isDestroyed || !this.table || !this.table.ngform) {
|
|
4303
|
+
return;
|
|
4304
|
+
}
|
|
4096
4305
|
const ctrlName = suffix ? (this.binding + suffix) : this.binding;
|
|
4097
4306
|
this.table.ngform.addControl(ctrlName, this.table.fb.control(''));
|
|
4098
4307
|
}
|
|
4099
4308
|
getFormControl(suffix) {
|
|
4309
|
+
// Guard against component destruction or table/ngform being null
|
|
4310
|
+
if (this.isDestroyed || !this.table || !this.table.ngform) {
|
|
4311
|
+
return null;
|
|
4312
|
+
}
|
|
4100
4313
|
const ctrlName = suffix ? (this.binding + suffix) : this.binding;
|
|
4101
|
-
return this.table.ngform.controls[ctrlName];
|
|
4314
|
+
return this.table.ngform.controls[ctrlName] || null;
|
|
4102
4315
|
}
|
|
4103
4316
|
_checkNewEditableRowControl() {
|
|
4104
4317
|
return this._isNewEditableRow && this.getFormControl('_new');
|
|
@@ -4172,12 +4385,16 @@
|
|
|
4172
4385
|
}
|
|
4173
4386
|
// On field value change, apply cascading filter and set validation message
|
|
4174
4387
|
onValueChange(val, widget) {
|
|
4388
|
+
// Guard against component destruction or table being null
|
|
4389
|
+
if (this.isDestroyed || !this.table) {
|
|
4390
|
+
return;
|
|
4391
|
+
}
|
|
4175
4392
|
if (val !== null) {
|
|
4176
4393
|
i4.applyFilterOnField(this.table.datasource, this.widget, this.table.fieldDefs, val, {
|
|
4177
4394
|
widget: 'edit-widget-type'
|
|
4178
4395
|
});
|
|
4179
4396
|
}
|
|
4180
|
-
if (this.table.ngform.touched) {
|
|
4397
|
+
if (this.table.ngform && this.table.ngform.touched) {
|
|
4181
4398
|
this.activeControlType = widget;
|
|
4182
4399
|
if (widget === 'inlineInstance') {
|
|
4183
4400
|
this.notifyChanges();
|
|
@@ -4435,7 +4652,7 @@
|
|
|
4435
4652
|
this.defaultvalue = i4.getDefaultValue(this.defaultvalue, this.type, this.editWidgetType);
|
|
4436
4653
|
break;
|
|
4437
4654
|
case 'show':
|
|
4438
|
-
this.table.redraw(
|
|
4655
|
+
this.table.redraw(false);
|
|
4439
4656
|
this.showinfilter = this.nativeElement.hasAttribute('showinfilter') ? this.nativeElement.getAttribute('showinfilter') : nv;
|
|
4440
4657
|
break;
|
|
4441
4658
|
case 'filterdataset':
|
|
@@ -4468,6 +4685,83 @@
|
|
|
4468
4685
|
this.table.redraw(true);
|
|
4469
4686
|
}
|
|
4470
4687
|
}
|
|
4688
|
+
ngOnDestroy() {
|
|
4689
|
+
// MEMORY LEAK FIX: Clear ContentChildren QueryLists
|
|
4690
|
+
if (this._filterInstances) {
|
|
4691
|
+
try {
|
|
4692
|
+
this._filterInstances.reset([]);
|
|
4693
|
+
}
|
|
4694
|
+
catch (e) {
|
|
4695
|
+
// Silently handle cleanup errors - QueryList might already be destroyed
|
|
4696
|
+
}
|
|
4697
|
+
}
|
|
4698
|
+
if (this._inlineInstances) {
|
|
4699
|
+
try {
|
|
4700
|
+
this._inlineInstances.reset([]);
|
|
4701
|
+
}
|
|
4702
|
+
catch (e) {
|
|
4703
|
+
// Silently handle cleanup errors - QueryList might already be destroyed
|
|
4704
|
+
}
|
|
4705
|
+
}
|
|
4706
|
+
if (this._inlineInstancesNew) {
|
|
4707
|
+
try {
|
|
4708
|
+
this._inlineInstancesNew.reset([]);
|
|
4709
|
+
}
|
|
4710
|
+
catch (e) {
|
|
4711
|
+
// Silently handle cleanup errors - QueryList might already be destroyed
|
|
4712
|
+
}
|
|
4713
|
+
}
|
|
4714
|
+
// MEMORY LEAK FIX: Clear all widget instance references
|
|
4715
|
+
this.filterInstance = null;
|
|
4716
|
+
this.inlineInstance = null;
|
|
4717
|
+
this.inlineInstanceNew = null;
|
|
4718
|
+
// MEMORY LEAK FIX: Clear template references
|
|
4719
|
+
this.customExprTmpl = null;
|
|
4720
|
+
this.inlineWidthTempRef = null;
|
|
4721
|
+
this.filterTemplateRef = null;
|
|
4722
|
+
// MEMORY LEAK FIX: Clear dataset references
|
|
4723
|
+
this._filterDataSet = null;
|
|
4724
|
+
this.dataset = null;
|
|
4725
|
+
this._dataoptions = null;
|
|
4726
|
+
this._datasource = null;
|
|
4727
|
+
// MEMORY LEAK FIX: Clear validation objects
|
|
4728
|
+
if (this.fieldValidations) {
|
|
4729
|
+
try {
|
|
4730
|
+
this.fieldValidations.destroy();
|
|
4731
|
+
}
|
|
4732
|
+
catch (e) {
|
|
4733
|
+
// Silently handle cleanup errors
|
|
4734
|
+
}
|
|
4735
|
+
this.fieldValidations = null;
|
|
4736
|
+
}
|
|
4737
|
+
if (this.fieldValidations_new) {
|
|
4738
|
+
try {
|
|
4739
|
+
this.fieldValidations_new.destroy();
|
|
4740
|
+
}
|
|
4741
|
+
catch (e) {
|
|
4742
|
+
// Silently handle cleanup errors
|
|
4743
|
+
}
|
|
4744
|
+
this.fieldValidations_new = null;
|
|
4745
|
+
}
|
|
4746
|
+
this.syncValidators = [];
|
|
4747
|
+
this.asyncValidators = [];
|
|
4748
|
+
// MEMORY LEAK FIX: Clear filter control reference
|
|
4749
|
+
this.filterControl = null;
|
|
4750
|
+
// MEMORY LEAK FIX: Clear notify fields array
|
|
4751
|
+
if (this.notifyForFields) {
|
|
4752
|
+
this.notifyForFields = [];
|
|
4753
|
+
}
|
|
4754
|
+
// MEMORY LEAK FIX: Clear observe fields array
|
|
4755
|
+
if (this.observeOnFields) {
|
|
4756
|
+
this.observeOnFields = [];
|
|
4757
|
+
}
|
|
4758
|
+
// MEMORY LEAK FIX: Clear table and group references
|
|
4759
|
+
// Note: These are injected dependencies, but clearing helps GC
|
|
4760
|
+
this.table = null;
|
|
4761
|
+
this.group = null;
|
|
4762
|
+
// Call parent ngOnDestroy
|
|
4763
|
+
super.ngOnDestroy();
|
|
4764
|
+
}
|
|
4471
4765
|
static { this.ɵfac = i0__namespace.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0__namespace, type: TableColumnDirective, deps: [{ token: i0__namespace.Injector }, { token: i2__namespace.AppDefaults }, { token: TableComponent, optional: true }, { token: TableColumnGroupDirective, optional: true }, { token: 'filterdataset.bind', attribute: true }, { token: 'dataset.bind', attribute: true }, { token: 'EXPLICIT_CONTEXT', optional: true }], target: i0__namespace.ɵɵFactoryTarget.Directive }); }
|
|
4472
4766
|
static { this.ɵdir = i0__namespace.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.2.13", type: TableColumnDirective, isStandalone: true, selector: "[wmTableColumn]", providers: [
|
|
4473
4767
|
i4.provideAsWidgetRef(TableColumnDirective)
|
|
@@ -4562,6 +4856,13 @@
|
|
|
4562
4856
|
this.config.content = this.content;
|
|
4563
4857
|
}
|
|
4564
4858
|
}
|
|
4859
|
+
ngOnDestroy() {
|
|
4860
|
+
// MEMORY LEAK FIX: Clear table and config references
|
|
4861
|
+
this.table = null;
|
|
4862
|
+
this.config = null;
|
|
4863
|
+
// Call parent ngOnDestroy (BaseComponent has cleanup)
|
|
4864
|
+
super.ngOnDestroy();
|
|
4865
|
+
}
|
|
4565
4866
|
static { this.ɵfac = i0__namespace.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0__namespace, type: TableRowDirective, deps: [{ token: i0__namespace.Injector }, { token: TableComponent, optional: true, skipSelf: true }, { token: 'EXPLICIT_CONTEXT', optional: true }], target: i0__namespace.ɵɵFactoryTarget.Directive }); }
|
|
4566
4867
|
static { this.ɵdir = i0__namespace.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.2.13", type: TableRowDirective, isStandalone: true, selector: "[wmTableRow]", providers: [
|
|
4567
4868
|
i4.provideAsWidgetRef(TableRowDirective)
|
|
@@ -4643,6 +4944,13 @@
|
|
|
4643
4944
|
this.populateAction();
|
|
4644
4945
|
this.table.registerRowActions(this.buttonDef);
|
|
4645
4946
|
}
|
|
4947
|
+
ngOnDestroy() {
|
|
4948
|
+
// MEMORY LEAK FIX: Clear table reference and button definition
|
|
4949
|
+
this.table = null;
|
|
4950
|
+
this.buttonDef = null;
|
|
4951
|
+
// Call parent ngOnDestroy (BaseComponent has cleanup)
|
|
4952
|
+
super.ngOnDestroy();
|
|
4953
|
+
}
|
|
4646
4954
|
static { this.ɵfac = i0__namespace.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0__namespace, type: TableRowActionDirective, deps: [{ token: i0__namespace.Injector }, { token: TableComponent, optional: true }, { token: i4.Context, self: true }, { token: 'EXPLICIT_CONTEXT', optional: true }], target: i0__namespace.ɵɵFactoryTarget.Directive }); }
|
|
4647
4955
|
static { this.ɵdir = i0__namespace.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.2.13", type: TableRowActionDirective, isStandalone: true, selector: "[wmTableRowAction]", providers: [
|
|
4648
4956
|
i4.provideAsWidgetRef(TableRowActionDirective),
|