@deephaven/iris-grid 1.28.0 → 1.29.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.
- package/dist/ColumnStatistics.js +1 -1
- package/dist/ColumnStatistics.js.map +1 -1
- package/dist/IrisGrid.d.ts +28 -4
- package/dist/IrisGrid.d.ts.map +1 -1
- package/dist/IrisGrid.js +185 -113
- package/dist/IrisGrid.js.map +1 -1
- package/dist/IrisGridCopyHandler.d.ts +5 -4
- package/dist/IrisGridCopyHandler.d.ts.map +1 -1
- package/dist/IrisGridCopyHandler.js +36 -29
- package/dist/IrisGridCopyHandler.js.map +1 -1
- package/dist/IrisGridModel.d.ts +2 -2
- package/dist/IrisGridModel.d.ts.map +1 -1
- package/dist/IrisGridModel.js +2 -2
- package/dist/IrisGridModel.js.map +1 -1
- package/dist/IrisGridSelectionUtils.d.ts +26 -0
- package/dist/IrisGridSelectionUtils.d.ts.map +1 -0
- package/dist/IrisGridSelectionUtils.js +84 -0
- package/dist/IrisGridSelectionUtils.js.map +1 -0
- package/dist/IrisGridTableModel.d.ts +4 -4
- package/dist/IrisGridTableModel.d.ts.map +1 -1
- package/dist/IrisGridTableModel.js +8 -8
- package/dist/IrisGridTableModel.js.map +1 -1
- package/dist/IrisGridTableModelTemplate.d.ts +25 -3
- package/dist/IrisGridTableModelTemplate.d.ts.map +1 -1
- package/dist/IrisGridTableModelTemplate.js +283 -79
- package/dist/IrisGridTableModelTemplate.js.map +1 -1
- package/dist/IrisGridTreeTableModel.d.ts +2 -0
- package/dist/IrisGridTreeTableModel.d.ts.map +1 -1
- package/dist/IrisGridTreeTableModel.js +11 -0
- package/dist/IrisGridTreeTableModel.js.map +1 -1
- package/dist/KeyedGridModel.d.ts +63 -0
- package/dist/KeyedGridModel.d.ts.map +1 -0
- package/dist/KeyedGridModel.js +12 -0
- package/dist/KeyedGridModel.js.map +1 -0
- package/dist/KeyedSelection.d.ts +194 -0
- package/dist/KeyedSelection.d.ts.map +1 -0
- package/dist/KeyedSelection.js +699 -0
- package/dist/KeyedSelection.js.map +1 -0
- package/dist/LazyIrisGrid.d.ts +1 -0
- package/dist/LazyIrisGrid.d.ts.map +1 -1
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/key-handlers/CopyKeyHandler.d.ts.map +1 -1
- package/dist/key-handlers/CopyKeyHandler.js +8 -6
- package/dist/key-handlers/CopyKeyHandler.js.map +1 -1
- package/dist/mousehandlers/IrisGridContextMenuHandler.d.ts +1 -1
- package/dist/mousehandlers/IrisGridContextMenuHandler.d.ts.map +1 -1
- package/dist/mousehandlers/IrisGridContextMenuHandler.js +94 -69
- package/dist/mousehandlers/IrisGridContextMenuHandler.js.map +1 -1
- package/dist/sidebar/TableCsvExporter.d.ts +7 -4
- package/dist/sidebar/TableCsvExporter.d.ts.map +1 -1
- package/dist/sidebar/TableCsvExporter.js +86 -38
- package/dist/sidebar/TableCsvExporter.js.map +1 -1
- package/package.json +9 -9
|
@@ -20,6 +20,7 @@ import Log from '@deephaven/log';
|
|
|
20
20
|
import { EventShimCustomEvent, PromiseUtils, assertNotNull } from '@deephaven/utils';
|
|
21
21
|
import { TableUtils, Formatter, FormatterUtils, DateUtils } from '@deephaven/jsapi-utils';
|
|
22
22
|
import IrisGridModel from "./IrisGridModel.js";
|
|
23
|
+
import { serializeKeyValues } from "./KeyedSelection.js";
|
|
23
24
|
import AggregationOperation from "./sidebar/aggregations/AggregationOperation.js";
|
|
24
25
|
import IrisGridUtils from "./IrisGridUtils.js";
|
|
25
26
|
import MissingKeyError from "./MissingKeyError.js";
|
|
@@ -121,6 +122,16 @@ class IrisGridTableModelTemplate extends IrisGridModel {
|
|
|
121
122
|
_defineProperty(this, "_columnHeaderGroups", []);
|
|
122
123
|
_defineProperty(this, "_isColumnHeaderGroupsInitialized", false);
|
|
123
124
|
_defineProperty(this, "_movedColumns", null);
|
|
125
|
+
_defineProperty(this, "getMemoizedSelectionKeyColumnIndices", memoize((columns, raw) => {
|
|
126
|
+
if (raw == null || typeof raw !== 'string' || raw.trim() === '') {
|
|
127
|
+
return [];
|
|
128
|
+
}
|
|
129
|
+
return raw.split(',').map(name => {
|
|
130
|
+
var idx = columns.findIndex(c => c.name === name.trim());
|
|
131
|
+
if (idx < 0) throw new Error("Selection key column not found: ".concat(name));
|
|
132
|
+
return idx;
|
|
133
|
+
});
|
|
134
|
+
}));
|
|
124
135
|
_defineProperty(this, "getMemoizedInitialMovedColumns", memoize(layoutHints => {
|
|
125
136
|
var _layoutHints$columnGr, _layoutHints$frontCol, _layoutHints$backColu, _layoutHints$frozenCo;
|
|
126
137
|
if (!layoutHints) {
|
|
@@ -325,6 +336,21 @@ class IrisGridTableModelTemplate extends IrisGridModel {
|
|
|
325
336
|
this.pendingNewDataMap = new Map();
|
|
326
337
|
this.pendingNewRowCount = 0;
|
|
327
338
|
}
|
|
339
|
+
get selectionKeyColumnIndices() {
|
|
340
|
+
var _getAttribute, _ref2;
|
|
341
|
+
return this.getMemoizedSelectionKeyColumnIndices(this.columns, (_getAttribute = (_ref2 = this.table).getAttribute) === null || _getAttribute === void 0 ? void 0 : _getAttribute.call(_ref2, 'keyColumns'));
|
|
342
|
+
}
|
|
343
|
+
get hasUniqueSelectionKeys() {
|
|
344
|
+
var _getAttribute2, _ref3;
|
|
345
|
+
return ((_getAttribute2 = (_ref3 = this.table).getAttribute) === null || _getAttribute2 === void 0 ? void 0 : _getAttribute2.call(_ref3, 'uniqueKeys')) === 'true';
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
// Totals rows have aggregate column values (not real row keys), so exclude
|
|
349
|
+
// them from keyed selection to keep copy / download filters meaningful.
|
|
350
|
+
// Follow up to design how this should work is DH-23589
|
|
351
|
+
isKeyableRow(row) {
|
|
352
|
+
return !this.isTotalsRow(row);
|
|
353
|
+
}
|
|
328
354
|
close() {
|
|
329
355
|
this.table.close();
|
|
330
356
|
if (this.totalsTable !== null) {
|
|
@@ -467,7 +493,7 @@ class IrisGridTableModelTemplate extends IrisGridModel {
|
|
|
467
493
|
return !this.isSaveInProgress && this.inputTable != null;
|
|
468
494
|
}
|
|
469
495
|
get isDeletable() {
|
|
470
|
-
return this.
|
|
496
|
+
return this.inputKeyColumnSet.size > 0;
|
|
471
497
|
}
|
|
472
498
|
get isViewportPending() {
|
|
473
499
|
if (this.viewport == null || this.viewport.columns === undefined || this.viewportData == null) {
|
|
@@ -539,7 +565,7 @@ class IrisGridTableModelTemplate extends IrisGridModel {
|
|
|
539
565
|
textForCell(x, y) {
|
|
540
566
|
var _this$columns$x;
|
|
541
567
|
var text = this.textValueForCell(x, y);
|
|
542
|
-
if (text == null && this.
|
|
568
|
+
if (text == null && this.isInputKeyColumn(x)) {
|
|
543
569
|
var pendingRow = this.pendingRow(y);
|
|
544
570
|
if (pendingRow != null && this.pendingDataMap.has(pendingRow)) {
|
|
545
571
|
// Asterisk to show a value is required for a key column on a row that has some data entered
|
|
@@ -587,7 +613,7 @@ class IrisGridTableModelTemplate extends IrisGridModel {
|
|
|
587
613
|
var column = this.sourceColumn(x, y);
|
|
588
614
|
return IrisGridUtils.colorForValue(theme, column.type, column.name, value);
|
|
589
615
|
}
|
|
590
|
-
} else if (this.isPendingRow(y) && this.
|
|
616
|
+
} else if (this.isPendingRow(y) && this.isInputKeyColumn(x)) {
|
|
591
617
|
assertNotNull(theme.errorTextColor);
|
|
592
618
|
return theme.errorTextColor;
|
|
593
619
|
}
|
|
@@ -1140,12 +1166,190 @@ class IrisGridTableModelTemplate extends IrisGridModel {
|
|
|
1140
1166
|
return data.map(row => row.join('\t')).join('\n');
|
|
1141
1167
|
})();
|
|
1142
1168
|
}
|
|
1143
|
-
|
|
1169
|
+
|
|
1170
|
+
/**
|
|
1171
|
+
* Builds a filter condition matching any row whose key columns equal one of the provided key value sets.
|
|
1172
|
+
*
|
|
1173
|
+
* @param keyValues A map of key column names to their corresponding values
|
|
1174
|
+
* @param keyColumns The key columns to filter by
|
|
1175
|
+
* @returns A filter condition matching the provided key values, or null if no filter is needed
|
|
1176
|
+
*/
|
|
1177
|
+
buildKeyFilter(keyValues, keyColumns) {
|
|
1178
|
+
// Return null if there are no key values to filter by
|
|
1179
|
+
if (keyValues.size === 0) return null;
|
|
1180
|
+
|
|
1181
|
+
// Create an AND filter for each set of key values
|
|
1182
|
+
var keyFilters = [];
|
|
1183
|
+
keyValues.forEach(values => {
|
|
1184
|
+
var colFilters = values.map((val, i) => {
|
|
1185
|
+
var col = keyColumns[i];
|
|
1186
|
+
return this.tableUtils.makeNullableEqFilter(col, val);
|
|
1187
|
+
});
|
|
1188
|
+
keyFilters.push(colFilters.length === 1 ? colFilters[0] : colFilters[0].and(...colFilters.slice(1)));
|
|
1189
|
+
});
|
|
1190
|
+
|
|
1191
|
+
// Combine the key filters with OR logic
|
|
1192
|
+
return keyFilters.length === 1 ? keyFilters[0] : keyFilters[0].or(...keyFilters.slice(1));
|
|
1193
|
+
}
|
|
1194
|
+
createFilteredByKeysTable(keyValues, invertedSelection) {
|
|
1144
1195
|
var _this4 = this;
|
|
1196
|
+
return _asyncToGenerator(function* () {
|
|
1197
|
+
if (TableUtils.isTreeTable(_this4.table)) {
|
|
1198
|
+
throw new Error('createFilteredByKeysTable is not supported on tree tables');
|
|
1199
|
+
}
|
|
1200
|
+
var keyColumns = _this4.selectionKeyColumnIndices.map(i => _this4.columns[i]);
|
|
1201
|
+
var keyFilter = _this4.buildKeyFilter(keyValues, keyColumns);
|
|
1202
|
+
var copy = yield _this4.table.copy();
|
|
1203
|
+
try {
|
|
1204
|
+
if (keyFilter == null && !invertedSelection) {
|
|
1205
|
+
// Empty non-inverted selection means zero rows match; filter to nothing so
|
|
1206
|
+
// callers (e.g. CSV exporter) see size=0 rather than the full unfiltered table.
|
|
1207
|
+
var neverMatch = keyColumns[0].filter().isNull().and(keyColumns[0].filter().isNull().not());
|
|
1208
|
+
yield _this4.tableUtils.applyFilter(copy, [neverMatch]);
|
|
1209
|
+
} else if (keyFilter != null) {
|
|
1210
|
+
var filter = invertedSelection ? [keyFilter.not()] : [keyFilter];
|
|
1211
|
+
yield _this4.tableUtils.applyFilter(copy, filter);
|
|
1212
|
+
}
|
|
1213
|
+
// Fall-through when keyFilter == null && invertedSelection: all rows selected.
|
|
1214
|
+
// Skip applyFilter — an empty filter array on a fresh copy produces no
|
|
1215
|
+
// filterchanged event, causing applyFilter to time out.
|
|
1216
|
+
return copy;
|
|
1217
|
+
} catch (err) {
|
|
1218
|
+
// applyFilter can reject or time out; the copy hasn't been returned to any
|
|
1219
|
+
// caller yet, so close it here to avoid leaking a JS API table.
|
|
1220
|
+
copy.close();
|
|
1221
|
+
throw err;
|
|
1222
|
+
}
|
|
1223
|
+
})();
|
|
1224
|
+
}
|
|
1225
|
+
fetchKeyValuesForRowRanges(ranges) {
|
|
1226
|
+
var _this5 = this;
|
|
1227
|
+
return _asyncToGenerator(function* () {
|
|
1228
|
+
// Compute the bounding envelope covering every range so the server round
|
|
1229
|
+
// trip is one viewport subscription regardless of how many disjoint ranges
|
|
1230
|
+
// were selected. Handles reverse-ordered and out-of-order input.
|
|
1231
|
+
var minStart = null;
|
|
1232
|
+
var maxEnd = null;
|
|
1233
|
+
for (var i = 0; i < ranges.length; i += 1) {
|
|
1234
|
+
var _ranges$i = ranges[i],
|
|
1235
|
+
startRow = _ranges$i.startRow,
|
|
1236
|
+
endRow = _ranges$i.endRow;
|
|
1237
|
+
if (startRow == null) continue; // eslint-disable-line no-continue
|
|
1238
|
+
var rEnd = endRow !== null && endRow !== void 0 ? endRow : startRow;
|
|
1239
|
+
var low = Math.min(startRow, rEnd);
|
|
1240
|
+
var high = Math.max(startRow, rEnd);
|
|
1241
|
+
if (minStart === null || low < minStart) minStart = low;
|
|
1242
|
+
if (maxEnd === null || high > maxEnd) maxEnd = high;
|
|
1243
|
+
}
|
|
1244
|
+
if (minStart === null || maxEnd === null) return new Map();
|
|
1245
|
+
var keyColumns = _this5.selectionKeyColumnIndices.map(i => _this5.columns[i]);
|
|
1246
|
+
// Use a secondary viewport subscription on the live table to avoid a copy/filter round-trip.
|
|
1247
|
+
var sub = _this5.table.createViewportSubscription({
|
|
1248
|
+
rows: {
|
|
1249
|
+
first: minStart,
|
|
1250
|
+
last: maxEnd
|
|
1251
|
+
},
|
|
1252
|
+
columns: keyColumns
|
|
1253
|
+
});
|
|
1254
|
+
try {
|
|
1255
|
+
var data = yield sub.getViewportData();
|
|
1256
|
+
var result = new Map();
|
|
1257
|
+
// Filter to only rows the caller actually requested — the envelope may
|
|
1258
|
+
// include rows between disjoint ranges that must not be selected.
|
|
1259
|
+
data.rows.forEach((row, i) => {
|
|
1260
|
+
var rowIndex = data.offset + i;
|
|
1261
|
+
if (!IrisGridTableModelTemplate.rowInAnyRange(rowIndex, ranges)) return;
|
|
1262
|
+
var values = keyColumns.map(col => row.get(col));
|
|
1263
|
+
result.set(serializeKeyValues(values), values);
|
|
1264
|
+
});
|
|
1265
|
+
return result;
|
|
1266
|
+
} finally {
|
|
1267
|
+
sub.close();
|
|
1268
|
+
}
|
|
1269
|
+
})();
|
|
1270
|
+
}
|
|
1271
|
+
static rowInAnyRange(rowIndex, ranges) {
|
|
1272
|
+
for (var i = 0; i < ranges.length; i += 1) {
|
|
1273
|
+
var _ranges$i2 = ranges[i],
|
|
1274
|
+
startRow = _ranges$i2.startRow,
|
|
1275
|
+
endRow = _ranges$i2.endRow;
|
|
1276
|
+
if (startRow == null) continue; // eslint-disable-line no-continue
|
|
1277
|
+
var rEnd = endRow !== null && endRow !== void 0 ? endRow : startRow;
|
|
1278
|
+
var low = Math.min(startRow, rEnd);
|
|
1279
|
+
var high = Math.max(startRow, rEnd);
|
|
1280
|
+
if (rowIndex >= low && rowIndex <= high) return true;
|
|
1281
|
+
}
|
|
1282
|
+
return false;
|
|
1283
|
+
}
|
|
1284
|
+
|
|
1285
|
+
/**
|
|
1286
|
+
* Implementation of snapshotByKeys.
|
|
1287
|
+
* This works by filtering the table based on the key values and then taking a snapshot of the entire filtered table.
|
|
1288
|
+
*/
|
|
1289
|
+
snapshotByKeys(columns, keyValues, invertedSelection) {
|
|
1290
|
+
var _arguments3 = arguments,
|
|
1291
|
+
_this6 = this;
|
|
1292
|
+
return _asyncToGenerator(function* () {
|
|
1293
|
+
var includeHeaders = _arguments3.length > 3 && _arguments3[3] !== undefined ? _arguments3[3] : false;
|
|
1294
|
+
var formatValue = _arguments3.length > 4 && _arguments3[4] !== undefined ? _arguments3[4] : v => v;
|
|
1295
|
+
var maxRows = _arguments3.length > 5 && _arguments3[5] !== undefined ? _arguments3[5] : null;
|
|
1296
|
+
if (maxRows != null && maxRows < 1) {
|
|
1297
|
+
throw new Error("maxRows must be at least 1, got ".concat(maxRows));
|
|
1298
|
+
}
|
|
1299
|
+
if (TableUtils.isTreeTable(_this6.table)) {
|
|
1300
|
+
throw new Error('snapshotByKeys is not supported on tree tables');
|
|
1301
|
+
}
|
|
1302
|
+
var keyColumns = _this6.selectionKeyColumnIndices.map(i => _this6.columns[i]);
|
|
1303
|
+
var keyFilter = _this6.buildKeyFilter(keyValues, keyColumns);
|
|
1304
|
+
if (keyFilter == null && !invertedSelection) {
|
|
1305
|
+
// Empty normal selection — nothing to copy
|
|
1306
|
+
return includeHeaders ? [columns.map(c => c.name)] : [];
|
|
1307
|
+
}
|
|
1308
|
+
var filteredTable = yield _this6.createFilteredByKeysTable(keyValues, invertedSelection);
|
|
1309
|
+
try {
|
|
1310
|
+
var result = [];
|
|
1311
|
+
if (includeHeaders) {
|
|
1312
|
+
result.push(columns.map(c => c.name));
|
|
1313
|
+
}
|
|
1314
|
+
if (filteredTable.size > 0) {
|
|
1315
|
+
var lastRow = maxRows != null ? Math.min(filteredTable.size - 1, maxRows - 1) : filteredTable.size - 1;
|
|
1316
|
+
var sub = filteredTable.createViewportSubscription({
|
|
1317
|
+
rows: {
|
|
1318
|
+
first: 0,
|
|
1319
|
+
last: lastRow
|
|
1320
|
+
},
|
|
1321
|
+
columns: [...columns]
|
|
1322
|
+
});
|
|
1323
|
+
try {
|
|
1324
|
+
var data = yield sub.getViewportData();
|
|
1325
|
+
result.push(...data.rows.map(rowData => columns.map(col => formatValue(rowData.get(col), col))));
|
|
1326
|
+
} finally {
|
|
1327
|
+
sub.close();
|
|
1328
|
+
}
|
|
1329
|
+
}
|
|
1330
|
+
return result;
|
|
1331
|
+
} finally {
|
|
1332
|
+
filteredTable.close();
|
|
1333
|
+
}
|
|
1334
|
+
})();
|
|
1335
|
+
}
|
|
1336
|
+
textSnapshotByKeys(columns, keyValues, invertedSelection) {
|
|
1337
|
+
var _arguments4 = arguments,
|
|
1338
|
+
_this7 = this;
|
|
1339
|
+
return _asyncToGenerator(function* () {
|
|
1340
|
+
var includeHeaders = _arguments4.length > 3 && _arguments4[3] !== undefined ? _arguments4[3] : false;
|
|
1341
|
+
var formatValue = _arguments4.length > 4 && _arguments4[4] !== undefined ? _arguments4[4] : v => "".concat(v);
|
|
1342
|
+
var maxRows = _arguments4.length > 5 && _arguments4[5] !== undefined ? _arguments4[5] : null;
|
|
1343
|
+
var data = yield _this7.snapshotByKeys(columns, keyValues, invertedSelection, includeHeaders, formatValue, maxRows);
|
|
1344
|
+
return data.map(row => row.join('\t')).join('\n');
|
|
1345
|
+
})();
|
|
1346
|
+
}
|
|
1347
|
+
valuesTable(columns) {
|
|
1348
|
+
var _this8 = this;
|
|
1145
1349
|
return _asyncToGenerator(function* () {
|
|
1146
1350
|
var table = null;
|
|
1147
1351
|
try {
|
|
1148
|
-
table = yield
|
|
1352
|
+
table = yield _this8.table.copy();
|
|
1149
1353
|
table.applyFilter([]);
|
|
1150
1354
|
table.applySort([]);
|
|
1151
1355
|
return yield table.selectDistinct(Array.isArray(columns) ? columns : [columns]);
|
|
@@ -1169,17 +1373,17 @@ class IrisGridTableModelTemplate extends IrisGridModel {
|
|
|
1169
1373
|
if (this.frontColumns.includes(columnName) || this.backColumns.includes(columnName) || this.frozenColumns.includes(columnName) || !columnName) {
|
|
1170
1374
|
return false;
|
|
1171
1375
|
}
|
|
1172
|
-
return !this.
|
|
1376
|
+
return !this.isInputKeyColumn(modelIndex);
|
|
1173
1377
|
}
|
|
1174
1378
|
isColumnSortable(modelIndex) {
|
|
1175
1379
|
var _this$columns$modelIn;
|
|
1176
1380
|
return (_this$columns$modelIn = this.columns[modelIndex].isSortable) !== null && _this$columns$modelIn !== void 0 ? _this$columns$modelIn : true;
|
|
1177
1381
|
}
|
|
1178
|
-
|
|
1179
|
-
return this.
|
|
1382
|
+
isInputKeyColumn(x) {
|
|
1383
|
+
return this.inputKeyColumnSet.has(this.columns[x].name);
|
|
1180
1384
|
}
|
|
1181
|
-
|
|
1182
|
-
return this.
|
|
1385
|
+
isInputValueColumn(x) {
|
|
1386
|
+
return this.inputValueColumnSet.has(this.columns[x].name);
|
|
1183
1387
|
}
|
|
1184
1388
|
isRowMovable() {
|
|
1185
1389
|
return false;
|
|
@@ -1196,23 +1400,23 @@ class IrisGridTableModelTemplate extends IrisGridModel {
|
|
|
1196
1400
|
// If an input table does not have key columns, it is append only and existing rows cannot be editable
|
|
1197
1401
|
// Pending rows are always editable
|
|
1198
1402
|
var isPendingRange = this.isPendingRow(range.startRow) && this.isPendingRow(range.endRow);
|
|
1199
|
-
var
|
|
1403
|
+
var isInputKeyColumnInRange = false;
|
|
1200
1404
|
assertNotNull(range.startColumn);
|
|
1201
1405
|
// Check if any of the columns in grid range are key columns
|
|
1202
1406
|
var bound = (_range$endColumn = range.endColumn) !== null && _range$endColumn !== void 0 ? _range$endColumn : this.table.size;
|
|
1203
1407
|
for (var column = range.startColumn; column <= bound; column += 1) {
|
|
1204
|
-
var isKey = this.
|
|
1205
|
-
var isValue = this.
|
|
1408
|
+
var isKey = this.isInputKeyColumn(column);
|
|
1409
|
+
var isValue = this.isInputValueColumn(column);
|
|
1206
1410
|
if (!isKey && !isValue) {
|
|
1207
1411
|
// If any column is not a key or value column, range is not editable
|
|
1208
1412
|
return false;
|
|
1209
1413
|
}
|
|
1210
1414
|
if (isKey) {
|
|
1211
|
-
|
|
1415
|
+
isInputKeyColumnInRange = true;
|
|
1212
1416
|
break;
|
|
1213
1417
|
}
|
|
1214
1418
|
}
|
|
1215
|
-
if (!(isPendingRange || this.
|
|
1419
|
+
if (!(isPendingRange || this.inputKeyColumnSet.size !== 0 && !isInputKeyColumnInRange)) {
|
|
1216
1420
|
return false;
|
|
1217
1421
|
}
|
|
1218
1422
|
return true;
|
|
@@ -1249,10 +1453,10 @@ class IrisGridTableModelTemplate extends IrisGridModel {
|
|
|
1249
1453
|
* @returns A promise that resolves successfully when the operation is complete, or rejects if there's an error
|
|
1250
1454
|
*/
|
|
1251
1455
|
setValueForCell(x, y, text) {
|
|
1252
|
-
var
|
|
1456
|
+
var _this9 = this;
|
|
1253
1457
|
return _asyncToGenerator(function* () {
|
|
1254
1458
|
// Cache the value in our pending string cache so that it stays displayed until our edit has been completed
|
|
1255
|
-
return
|
|
1459
|
+
return _this9.setValueForRanges([new GridRange(x, y, x, y)], text);
|
|
1256
1460
|
})();
|
|
1257
1461
|
}
|
|
1258
1462
|
|
|
@@ -1263,9 +1467,9 @@ class IrisGridTableModelTemplate extends IrisGridModel {
|
|
|
1263
1467
|
* @returns A promise that resolves successfully when the operation is complete, or rejects if there's an error
|
|
1264
1468
|
*/
|
|
1265
1469
|
setValueForRanges(ranges, text) {
|
|
1266
|
-
var
|
|
1470
|
+
var _this0 = this;
|
|
1267
1471
|
return _asyncToGenerator(function* () {
|
|
1268
|
-
if (!
|
|
1472
|
+
if (!_this0.isEditableRanges(ranges)) {
|
|
1269
1473
|
throw new Error("Edits contain uneditable ranges");
|
|
1270
1474
|
}
|
|
1271
1475
|
try {
|
|
@@ -1276,35 +1480,35 @@ class IrisGridTableModelTemplate extends IrisGridModel {
|
|
|
1276
1480
|
// Since there could be different formatting for each column, but the value will be the same across rows
|
|
1277
1481
|
var formattedText = [];
|
|
1278
1482
|
GridRange.forEachCell(ranges, (x, y) => {
|
|
1279
|
-
var column =
|
|
1483
|
+
var column = _this0.columns[x];
|
|
1280
1484
|
columnSet.add(column);
|
|
1281
1485
|
if (formattedText[x] === undefined) {
|
|
1282
|
-
var value =
|
|
1283
|
-
formattedText[x] = value != null ?
|
|
1486
|
+
var value = _this0.tableUtils.makeValue(column.type, text, _this0.formatter.timeZone);
|
|
1487
|
+
formattedText[x] = value != null ? _this0.displayString(value, column.type, column.name) : null;
|
|
1284
1488
|
}
|
|
1285
|
-
|
|
1489
|
+
_this0.cachePendingValue(x, y, formattedText[x]);
|
|
1286
1490
|
});
|
|
1287
1491
|
|
|
1288
1492
|
// Take care of updates to the pending new area first, as they can be updated synchronously
|
|
1289
|
-
var pendingAreaRange =
|
|
1493
|
+
var pendingAreaRange = _this0.getPendingAreaRange();
|
|
1290
1494
|
var pendingRanges = ranges.map(range => GridRange.intersection(pendingAreaRange, range)).filter(range => range != null).map(range => {
|
|
1291
1495
|
assertNotNull(range);
|
|
1292
|
-
return GridRange.offset(range, 0, -(
|
|
1496
|
+
return GridRange.offset(range, 0, -(_this0.floatingTopRowCount + _this0.table.size));
|
|
1293
1497
|
});
|
|
1294
1498
|
if (pendingRanges.length > 0) {
|
|
1295
|
-
var newDataMap = new Map(
|
|
1499
|
+
var newDataMap = new Map(_this0.pendingNewDataMap);
|
|
1296
1500
|
GridRange.forEachCell(pendingRanges, (columnIndex, rowIndex) => {
|
|
1297
1501
|
if (!newDataMap.has(rowIndex)) {
|
|
1298
1502
|
newDataMap.set(rowIndex, {
|
|
1299
1503
|
data: new Map()
|
|
1300
1504
|
});
|
|
1301
1505
|
}
|
|
1302
|
-
var column =
|
|
1506
|
+
var column = _this0.columns[columnIndex];
|
|
1303
1507
|
var row = newDataMap.get(rowIndex);
|
|
1304
1508
|
assertNotNull(row);
|
|
1305
1509
|
var rowData = row.data;
|
|
1306
1510
|
var newRowData = new Map(rowData);
|
|
1307
|
-
var value =
|
|
1511
|
+
var value = _this0.tableUtils.makeValue(column.type, text, _this0.formatter.timeZone);
|
|
1308
1512
|
if (value != null) {
|
|
1309
1513
|
newRowData.set(columnIndex, {
|
|
1310
1514
|
value
|
|
@@ -1320,29 +1524,29 @@ class IrisGridTableModelTemplate extends IrisGridModel {
|
|
|
1320
1524
|
newDataMap.delete(rowIndex);
|
|
1321
1525
|
}
|
|
1322
1526
|
});
|
|
1323
|
-
|
|
1527
|
+
_this0.pendingDataMap = newDataMap;
|
|
1324
1528
|
}
|
|
1325
|
-
|
|
1326
|
-
var tableAreaRange =
|
|
1529
|
+
_this0.dispatchEvent(new EventShimCustomEvent(IrisGridModel.EVENT.UPDATED));
|
|
1530
|
+
var tableAreaRange = _this0.getTableAreaRange();
|
|
1327
1531
|
var tableRanges = ranges.map(range => GridRange.intersection(tableAreaRange, range)).filter(range => range != null);
|
|
1328
1532
|
if (tableRanges.length > 0) {
|
|
1329
|
-
var
|
|
1533
|
+
var _this0$inputTable;
|
|
1330
1534
|
// Get a snapshot of the full rows, as we need to write a full row when editing
|
|
1331
|
-
var data = yield
|
|
1535
|
+
var data = yield _this0.snapshot(tableRanges.map(range => {
|
|
1332
1536
|
var _range$startRow, _range$endRow;
|
|
1333
1537
|
return new GridRange(null, (_range$startRow = range === null || range === void 0 ? void 0 : range.startRow) !== null && _range$startRow !== void 0 ? _range$startRow : null, null, (_range$endRow = range === null || range === void 0 ? void 0 : range.endRow) !== null && _range$endRow !== void 0 ? _range$endRow : null);
|
|
1334
1538
|
}));
|
|
1335
1539
|
var newRows = data.map(row => {
|
|
1336
1540
|
var newRow = {};
|
|
1337
|
-
for (var c = 0; c <
|
|
1338
|
-
newRow[
|
|
1541
|
+
for (var c = 0; c < _this0.columns.length; c += 1) {
|
|
1542
|
+
newRow[_this0.columns[c].name] = row[c];
|
|
1339
1543
|
}
|
|
1340
1544
|
columnSet.forEach(column => {
|
|
1341
|
-
newRow[column.name] =
|
|
1545
|
+
newRow[column.name] = _this0.tableUtils.makeValue(column.type, text, _this0.formatter.timeZone);
|
|
1342
1546
|
});
|
|
1343
1547
|
return newRow;
|
|
1344
1548
|
});
|
|
1345
|
-
var result = yield (
|
|
1549
|
+
var result = yield (_this0$inputTable = _this0.inputTable) === null || _this0$inputTable === void 0 ? void 0 : _this0$inputTable.addRows(newRows);
|
|
1346
1550
|
log.debug('setValueForRanges(', ranges, ',', text, ') set tableRanges', tableRanges, 'result', result);
|
|
1347
1551
|
}
|
|
1348
1552
|
|
|
@@ -1352,7 +1556,7 @@ class IrisGridTableModelTemplate extends IrisGridModel {
|
|
|
1352
1556
|
GridRange.forEachCell(ranges, (x, y) => {
|
|
1353
1557
|
var cellText = formattedText[x];
|
|
1354
1558
|
assertNotNull(cellText);
|
|
1355
|
-
|
|
1559
|
+
_this0.cacheFormattedValue(x, y, cellText);
|
|
1356
1560
|
});
|
|
1357
1561
|
} catch (err) {
|
|
1358
1562
|
log.error('Unable to set ranges', ranges, text, err);
|
|
@@ -1364,25 +1568,25 @@ class IrisGridTableModelTemplate extends IrisGridModel {
|
|
|
1364
1568
|
});
|
|
1365
1569
|
} finally {
|
|
1366
1570
|
GridRange.forEachCell(ranges, (x, y) => {
|
|
1367
|
-
|
|
1571
|
+
_this0.clearPendingValue(x, y);
|
|
1368
1572
|
});
|
|
1369
1573
|
}
|
|
1370
1574
|
})();
|
|
1371
1575
|
}
|
|
1372
1576
|
setValues() {
|
|
1373
|
-
var
|
|
1374
|
-
|
|
1577
|
+
var _arguments5 = arguments,
|
|
1578
|
+
_this1 = this;
|
|
1375
1579
|
return _asyncToGenerator(function* () {
|
|
1376
|
-
var edits =
|
|
1580
|
+
var edits = _arguments5.length > 0 && _arguments5[0] !== undefined ? _arguments5[0] : [];
|
|
1377
1581
|
log.debug('setValues(', edits, ')');
|
|
1378
1582
|
if (!edits.every(edit => {
|
|
1379
1583
|
var _edit$column, _edit$row;
|
|
1380
|
-
return
|
|
1584
|
+
return _this1.isEditableRange(GridRange.makeCell((_edit$column = edit.column) !== null && _edit$column !== void 0 ? _edit$column : edit.x, (_edit$row = edit.row) !== null && _edit$row !== void 0 ? _edit$row : edit.y));
|
|
1381
1585
|
})) {
|
|
1382
1586
|
throw new Error("Edits contain uneditable ranges");
|
|
1383
1587
|
}
|
|
1384
1588
|
try {
|
|
1385
|
-
var newDataMap = new Map(
|
|
1589
|
+
var newDataMap = new Map(_this1.pendingNewDataMap);
|
|
1386
1590
|
|
|
1387
1591
|
// Cache the display values
|
|
1388
1592
|
edits.forEach(edit => {
|
|
@@ -1390,13 +1594,13 @@ class IrisGridTableModelTemplate extends IrisGridModel {
|
|
|
1390
1594
|
var text = edit.text;
|
|
1391
1595
|
var x = (_edit$column2 = edit.column) !== null && _edit$column2 !== void 0 ? _edit$column2 : edit.x;
|
|
1392
1596
|
var y = (_edit$row2 = edit.row) !== null && _edit$row2 !== void 0 ? _edit$row2 : edit.y;
|
|
1393
|
-
var column =
|
|
1394
|
-
var value =
|
|
1395
|
-
var formattedText = value != null ?
|
|
1396
|
-
|
|
1597
|
+
var column = _this1.columns[x];
|
|
1598
|
+
var value = _this1.tableUtils.makeValue(column.type, text, _this1.formatter.timeZone);
|
|
1599
|
+
var formattedText = value != null ? _this1.displayString(value, column.type, column.name) : null;
|
|
1600
|
+
_this1.cachePendingValue(x, y, formattedText);
|
|
1397
1601
|
|
|
1398
1602
|
// Take care of updates to the pending new area as well, as that can be updated synchronously
|
|
1399
|
-
var pendingRow =
|
|
1603
|
+
var pendingRow = _this1.pendingRow(y);
|
|
1400
1604
|
if (pendingRow != null) {
|
|
1401
1605
|
if (!newDataMap.has(pendingRow)) {
|
|
1402
1606
|
newDataMap.set(pendingRow, {
|
|
@@ -1423,10 +1627,10 @@ class IrisGridTableModelTemplate extends IrisGridModel {
|
|
|
1423
1627
|
}
|
|
1424
1628
|
}
|
|
1425
1629
|
});
|
|
1426
|
-
|
|
1630
|
+
_this1.pendingDataMap = newDataMap;
|
|
1427
1631
|
|
|
1428
1632
|
// Send an update right after setting the pending map so the values are displayed immediately
|
|
1429
|
-
|
|
1633
|
+
_this1.dispatchEvent(new EventShimCustomEvent(IrisGridModel.EVENT.UPDATED));
|
|
1430
1634
|
|
|
1431
1635
|
// Need to group by row...
|
|
1432
1636
|
var rowEditMap = edits.reduce((rowMap, edit) => {
|
|
@@ -1442,12 +1646,12 @@ class IrisGridTableModelTemplate extends IrisGridModel {
|
|
|
1442
1646
|
var _edit$column3, _edit$row4;
|
|
1443
1647
|
return GridRange.makeCell((_edit$column3 = edit.column) !== null && _edit$column3 !== void 0 ? _edit$column3 : edit.x, (_edit$row4 = edit.row) !== null && _edit$row4 !== void 0 ? _edit$row4 : edit.y);
|
|
1444
1648
|
}));
|
|
1445
|
-
var tableAreaRange =
|
|
1649
|
+
var tableAreaRange = _this1.getTableAreaRange();
|
|
1446
1650
|
var tableRanges = ranges.map(range => GridRange.intersection(tableAreaRange, range)).filter(range => range != null);
|
|
1447
1651
|
if (tableRanges.length > 0) {
|
|
1448
|
-
var
|
|
1652
|
+
var _this1$inputTable;
|
|
1449
1653
|
// Get a snapshot of the full rows, as we need to write a full row when editing
|
|
1450
|
-
var data = yield
|
|
1654
|
+
var data = yield _this1.snapshot(tableRanges.map(range => {
|
|
1451
1655
|
assertNotNull(range);
|
|
1452
1656
|
return new GridRange(null, range.startRow, null, range.endRow);
|
|
1453
1657
|
}));
|
|
@@ -1466,22 +1670,22 @@ class IrisGridTableModelTemplate extends IrisGridModel {
|
|
|
1466
1670
|
r -= rangeRowCount;
|
|
1467
1671
|
}
|
|
1468
1672
|
var newRow = {};
|
|
1469
|
-
for (var c = 0; c <
|
|
1470
|
-
newRow[
|
|
1673
|
+
for (var c = 0; c < _this1.columns.length; c += 1) {
|
|
1674
|
+
newRow[_this1.columns[c].name] = row[c];
|
|
1471
1675
|
}
|
|
1472
1676
|
assertNotNull(rowIndex);
|
|
1473
1677
|
var rowEdits = rowEditMap.get(rowIndex);
|
|
1474
1678
|
if (rowEdits != null) {
|
|
1475
1679
|
rowEdits.forEach(edit => {
|
|
1476
1680
|
var _edit$column4;
|
|
1477
|
-
var column =
|
|
1478
|
-
newRow[column.name] =
|
|
1681
|
+
var column = _this1.columns[(_edit$column4 = edit.column) !== null && _edit$column4 !== void 0 ? _edit$column4 : edit.x];
|
|
1682
|
+
newRow[column.name] = _this1.tableUtils.makeValue(column.type, edit.text, _this1.formatter.timeZone);
|
|
1479
1683
|
});
|
|
1480
1684
|
}
|
|
1481
1685
|
return newRow;
|
|
1482
1686
|
});
|
|
1483
1687
|
log.info('setValues setting tableRanges', tableRanges);
|
|
1484
|
-
var result = yield (
|
|
1688
|
+
var result = yield (_this1$inputTable = _this1.inputTable) === null || _this1$inputTable === void 0 ? void 0 : _this1$inputTable.addRows(newRows);
|
|
1485
1689
|
log.info('setValues set tableRanges', tableRanges, 'SUCCESS', result);
|
|
1486
1690
|
}
|
|
1487
1691
|
|
|
@@ -1494,45 +1698,45 @@ class IrisGridTableModelTemplate extends IrisGridModel {
|
|
|
1494
1698
|
var text = edit.text;
|
|
1495
1699
|
var x = (_edit$column5 = edit.column) !== null && _edit$column5 !== void 0 ? _edit$column5 : edit.x;
|
|
1496
1700
|
var y = (_edit$row5 = edit.row) !== null && _edit$row5 !== void 0 ? _edit$row5 : edit.y;
|
|
1497
|
-
var column =
|
|
1498
|
-
var value =
|
|
1499
|
-
var formattedText = value != null ?
|
|
1500
|
-
|
|
1701
|
+
var column = _this1.columns[x];
|
|
1702
|
+
var value = _this1.tableUtils.makeValue(column.type, text, _this1.formatter.timeZone);
|
|
1703
|
+
var formattedText = value != null ? _this1.displayString(value, column.type, column.name) : null;
|
|
1704
|
+
_this1.cacheFormattedValue(x, y, formattedText);
|
|
1501
1705
|
});
|
|
1502
1706
|
} finally {
|
|
1503
1707
|
edits.forEach(edit => {
|
|
1504
|
-
|
|
1708
|
+
_this1.clearPendingValue(edit.column, edit.row);
|
|
1505
1709
|
});
|
|
1506
1710
|
}
|
|
1507
1711
|
})();
|
|
1508
1712
|
}
|
|
1509
1713
|
commitPending() {
|
|
1510
|
-
var
|
|
1714
|
+
var _this10 = this;
|
|
1511
1715
|
return _asyncToGenerator(function* () {
|
|
1512
|
-
if (
|
|
1716
|
+
if (_this10.pendingNewDataMap.size <= 0) {
|
|
1513
1717
|
throw new Error('No pending changes to commit');
|
|
1514
1718
|
}
|
|
1515
1719
|
try {
|
|
1516
|
-
var
|
|
1517
|
-
|
|
1720
|
+
var _this10$inputTable, _this10$viewport$bott, _this10$viewport;
|
|
1721
|
+
_this10.isSaveInProgress = true;
|
|
1518
1722
|
var newRows = [];
|
|
1519
|
-
|
|
1723
|
+
_this10.pendingNewDataMap.forEach(row => {
|
|
1520
1724
|
var newRow = {};
|
|
1521
|
-
row.data.forEach((
|
|
1522
|
-
var value =
|
|
1523
|
-
var columnName = typeof columnIndex === 'string' ? columnIndex :
|
|
1725
|
+
row.data.forEach((_ref4, columnIndex) => {
|
|
1726
|
+
var value = _ref4.value;
|
|
1727
|
+
var columnName = typeof columnIndex === 'string' ? columnIndex : _this10.columns[columnIndex].name;
|
|
1524
1728
|
newRow[columnName] = value;
|
|
1525
1729
|
});
|
|
1526
1730
|
newRows.push(newRow);
|
|
1527
1731
|
});
|
|
1528
|
-
var result = yield (
|
|
1529
|
-
log.debug('commitPending()',
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1732
|
+
var result = yield (_this10$inputTable = _this10.inputTable) === null || _this10$inputTable === void 0 ? void 0 : _this10$inputTable.addRows(newRows);
|
|
1733
|
+
log.debug('commitPending()', _this10.pendingNewDataMap, 'result', result);
|
|
1734
|
+
_this10.pendingNewDataMap = new Map();
|
|
1735
|
+
_this10.pendingNewRowCount = Math.max(0, ((_this10$viewport$bott = (_this10$viewport = _this10.viewport) === null || _this10$viewport === void 0 ? void 0 : _this10$viewport.bottom) !== null && _this10$viewport$bott !== void 0 ? _this10$viewport$bott : 0) - _this10.table.size);
|
|
1736
|
+
_this10.formattedStringData = [];
|
|
1737
|
+
_this10.dispatchEvent(new EventShimCustomEvent(IrisGridModel.EVENT.PENDING_DATA_UPDATED));
|
|
1534
1738
|
} finally {
|
|
1535
|
-
|
|
1739
|
+
_this10.isSaveInProgress = false;
|
|
1536
1740
|
}
|
|
1537
1741
|
})();
|
|
1538
1742
|
}
|