@revolist/revogrid 4.10.33 → 4.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/dist/cjs/{column.drag.plugin-e7ee8105.js → column.drag.plugin-5978b75e.js} +100 -63
  2. package/dist/cjs/column.drag.plugin-5978b75e.js.map +1 -0
  3. package/dist/cjs/index.cjs.js +1 -1
  4. package/dist/cjs/revo-grid.cjs.entry.js +1 -1
  5. package/dist/cjs/revo-grid.cjs.entry.js.map +1 -1
  6. package/dist/cjs/revogr-filter-panel.cjs.entry.js +6 -2
  7. package/dist/cjs/revogr-filter-panel.cjs.entry.js.map +1 -1
  8. package/dist/collection/components/revoGrid/revo-grid.js +26 -12
  9. package/dist/collection/components/revoGrid/revo-grid.js.map +1 -1
  10. package/dist/collection/plugins/filter/filter.indexed.js +1 -0
  11. package/dist/collection/plugins/filter/filter.indexed.js.map +1 -1
  12. package/dist/collection/plugins/filter/filter.panel.js +7 -2
  13. package/dist/collection/plugins/filter/filter.panel.js.map +1 -1
  14. package/dist/collection/plugins/filter/filter.plugin.js +98 -62
  15. package/dist/collection/plugins/filter/filter.plugin.js.map +1 -1
  16. package/dist/collection/plugins/filter/filter.types.js.map +1 -1
  17. package/dist/esm/{column.drag.plugin-6ed6cd8d.js → column.drag.plugin-7756231e.js} +100 -63
  18. package/dist/esm/column.drag.plugin-7756231e.js.map +1 -0
  19. package/dist/esm/index.js +2 -2
  20. package/dist/esm/revo-grid.entry.js +1 -1
  21. package/dist/esm/revo-grid.entry.js.map +1 -1
  22. package/dist/esm/revogr-filter-panel.entry.js +6 -2
  23. package/dist/esm/revogr-filter-panel.entry.js.map +1 -1
  24. package/dist/revo-grid/column.drag.plugin-7756231e.js +5 -0
  25. package/dist/revo-grid/column.drag.plugin-7756231e.js.map +1 -0
  26. package/dist/revo-grid/index.esm.js +1 -1
  27. package/dist/revo-grid/revo-grid.entry.js +1 -1
  28. package/dist/revo-grid/revo-grid.entry.js.map +1 -1
  29. package/dist/revo-grid/revogr-filter-panel.entry.js +1 -1
  30. package/dist/revo-grid/revogr-filter-panel.entry.js.map +1 -1
  31. package/dist/types/components/revoGrid/revo-grid.d.ts +3 -3
  32. package/dist/types/components.d.ts +6 -6
  33. package/dist/types/plugins/filter/filter.plugin.d.ts +13 -6
  34. package/dist/types/plugins/filter/filter.types.d.ts +14 -7
  35. package/hydrate/index.js +105 -64
  36. package/hydrate/index.mjs +105 -64
  37. package/package.json +13 -13
  38. package/readme.md +3 -3
  39. package/standalone/revo-grid.js +99 -62
  40. package/standalone/revo-grid.js.map +1 -1
  41. package/standalone/revogr-filter-panel.js +6 -2
  42. package/standalone/revogr-filter-panel.js.map +1 -1
  43. package/dist/cjs/column.drag.plugin-e7ee8105.js.map +0 -1
  44. package/dist/esm/column.drag.plugin-6ed6cd8d.js.map +0 -1
  45. package/dist/revo-grid/column.drag.plugin-6ed6cd8d.js +0 -5
  46. package/dist/revo-grid/column.drag.plugin-6ed6cd8d.js.map +0 -1
@@ -1123,6 +1123,7 @@ const notContains = (value, extra) => {
1123
1123
  notContains.extra = 'input';
1124
1124
  contains.extra = 'input';
1125
1125
 
1126
+ // filter.indexed.ts
1126
1127
  const filterCoreFunctionsIndexedByType = {
1127
1128
  none: () => true,
1128
1129
  empty: notSet,
@@ -1160,19 +1161,25 @@ const filterNames = {
1160
1161
  lte: '<=',
1161
1162
  };
1162
1163
 
1164
+ // filter.plugin.tsx
1163
1165
  const FILTER_TRIMMED_TYPE = 'filter';
1164
1166
  const FILTER_CONFIG_CHANGED_EVENT = 'filterconfigchanged';
1165
1167
  const FILTE_PANEL = 'revogr-filter-panel';
1166
1168
  /**
1167
1169
  * @typedef ColumnFilterConfig
1168
1170
  * @type {object}
1169
- * @property {FilterCollection|undefined} collection - preserved filter data
1171
+ *
1172
+ * @property {MultiFilterItem|undefined} multiFilterItems - data for multi filtering with relation
1173
+ *
1174
+ * @property {Record<ColumnProp, FilterCollectionItem>|undefined} collection - preserved filter data, relation for filters will be applied as 'and'
1175
+ *
1170
1176
  * @property {string[]|undefined} include - filters to be included, if defined everything else out of scope will be ignored
1177
+ *
1171
1178
  * @property {Record<string, CustomFilter>|undefined} customFilters - hash map of {FilterType:CustomFilter}.
1179
+ *
1172
1180
  * @property {FilterLocalization|undefined} localization - translation for filter popup captions.
1173
- * @property {MultiFilterItem|undefined} multiFilterItems - data for multi filtering.
1181
+ *
1174
1182
  * @property {boolean|undefined} disableDynamicFiltering - disables dynamic filtering. A way to apply filters on Save only.
1175
- * A way to define your own filter types per column
1176
1183
  */
1177
1184
  /**
1178
1185
  * @internal
@@ -1204,7 +1211,7 @@ class FilterPlugin extends BasePlugin {
1204
1211
  this.revogrid.registerVNode = [
1205
1212
  ...existingNodes,
1206
1213
  index.h("revogr-filter-panel", { filterNames: this.filterNameIndexByType, filterEntities: this.filterFunctionsIndexedByType, filterCaptions: (_a = config === null || config === void 0 ? void 0 : config.localization) === null || _a === void 0 ? void 0 : _a.captions, onFilterChange: e => this.onFilterChange(e.detail), onResetChange: e => this.onFilterReset(e.detail), disableDynamicFiltering: config === null || config === void 0 ? void 0 : config.disableDynamicFiltering, ref: e => (this.pop = e) },
1207
- " ",
1214
+ ' ',
1208
1215
  this.extraContent()),
1209
1216
  ];
1210
1217
  const aftersourceset = async () => {
@@ -1229,9 +1236,12 @@ class FilterPlugin extends BasePlugin {
1229
1236
  }
1230
1237
  await this.runFiltering(this.multiFilterItems);
1231
1238
  };
1232
- this.addEventListener('headerclick', (e) => this.headerclick(e));
1239
+ this.addEventListener('headerclick', e => this.headerclick(e));
1233
1240
  this.addEventListener(FILTER_CONFIG_CHANGED_EVENT, ({ detail }) => {
1234
- if (!detail || typeof detail === 'object' && (!detail.multiFilterItems || !Object.keys(detail.multiFilterItems).length)) {
1241
+ if (!detail ||
1242
+ (typeof detail === 'object' &&
1243
+ (!detail.multiFilterItems ||
1244
+ !Object.keys(detail.multiFilterItems).length))) {
1235
1245
  this.clearFiltering();
1236
1246
  return;
1237
1247
  }
@@ -1243,6 +1253,9 @@ class FilterPlugin extends BasePlugin {
1243
1253
  this.addEventListener('aftersourceset', aftersourceset);
1244
1254
  this.addEventListener('filter', ({ detail }) => this.onFilterChange(detail));
1245
1255
  }
1256
+ beforeshow(_) {
1257
+ // used as hook for filter panel
1258
+ }
1246
1259
  extraContent() {
1247
1260
  return null;
1248
1261
  }
@@ -1260,8 +1273,11 @@ class FilterPlugin extends BasePlugin {
1260
1273
  if (!this.filterByType[cFilter.columnFilterType]) {
1261
1274
  this.filterByType[cFilter.columnFilterType] = [];
1262
1275
  }
1276
+ // add custom filter type
1263
1277
  this.filterByType[cFilter.columnFilterType].push(customFilterType);
1278
+ // add custom filter function
1264
1279
  this.filterFunctionsIndexedByType[customFilterType] = cFilter.func;
1280
+ // add custom filter name
1265
1281
  this.filterNameIndexByType[customFilterType] = cFilter.name;
1266
1282
  }
1267
1283
  }
@@ -1289,7 +1305,8 @@ class FilterPlugin extends BasePlugin {
1289
1305
  }
1290
1306
  }
1291
1307
  if (config.collection) {
1292
- this.filterCollection = Object.fromEntries(Object.entries(config.collection).filter(([, item]) => this.filterFunctionsIndexedByType[item.type]));
1308
+ const filtersWithFilterFunctionPresent = Object.entries(config.collection).filter(([, item]) => this.filterFunctionsIndexedByType[item.type]);
1309
+ this.filterCollection = Object.fromEntries(filtersWithFilterFunctionPresent);
1293
1310
  }
1294
1311
  else {
1295
1312
  this.filterCollection = {};
@@ -1305,7 +1322,7 @@ class FilterPlugin extends BasePlugin {
1305
1322
  }
1306
1323
  }
1307
1324
  async headerclick(e) {
1308
- var _a;
1325
+ var _a, _b;
1309
1326
  const el = (_a = e.detail.originalEvent) === null || _a === void 0 ? void 0 : _a.target;
1310
1327
  if (!filter_button.isFilterBtn(el)) {
1311
1328
  return;
@@ -1318,8 +1335,9 @@ class FilterPlugin extends BasePlugin {
1318
1335
  const gridPos = this.revogrid.getBoundingClientRect();
1319
1336
  const buttonPos = el.getBoundingClientRect();
1320
1337
  const prop = e.detail.prop;
1321
- const data = Object.assign(Object.assign(Object.assign({}, e.detail), this.filterCollection[prop]), { x: buttonPos.x - gridPos.x, y: buttonPos.y - gridPos.y + buttonPos.height, autoCorrect: true, filterTypes: this.getColumnFilter(e.detail.filter), filterItems: this.multiFilterItems });
1322
- this.pop.show(Object.assign(Object.assign({}, data), { extraContent: this.extraHyperContent }));
1338
+ const data = Object.assign(Object.assign(Object.assign({}, e.detail), this.filterCollection[prop]), { x: buttonPos.x - gridPos.x, y: buttonPos.y - gridPos.y + buttonPos.height, autoCorrect: true, filterTypes: this.getColumnFilter(e.detail.filter), filterItems: this.multiFilterItems, extraContent: this.extraHyperContent });
1339
+ (_b = this.beforeshow) === null || _b === void 0 ? void 0 : _b.call(this, data);
1340
+ this.pop.show(data);
1323
1341
  }
1324
1342
  getColumnFilter(type) {
1325
1343
  let filterType = 'string';
@@ -1403,7 +1421,11 @@ class FilterPlugin extends BasePlugin {
1403
1421
  }
1404
1422
  // applies the hasFilter to the columns to show filter icon
1405
1423
  this.providers.column.updateColumns(columnsToUpdate);
1406
- this.emit('afterfilterapply');
1424
+ this.emit('afterfilterapply', {
1425
+ multiFilterItems: filterItems,
1426
+ source,
1427
+ collection,
1428
+ });
1407
1429
  }
1408
1430
  async clearFiltering() {
1409
1431
  this.multiFilterItems = {};
@@ -1418,7 +1440,6 @@ class FilterPlugin extends BasePlugin {
1418
1440
  if (multiFilterItems[prop].length > 0) {
1419
1441
  const firstFilterItem = multiFilterItems[prop][0];
1420
1442
  collection[prop] = {
1421
- filter: this.filterFunctionsIndexedByType[firstFilterItem.type],
1422
1443
  type: firstFilterItem.type,
1423
1444
  value: firstFilterItem.value,
1424
1445
  };
@@ -1445,67 +1466,83 @@ class FilterPlugin extends BasePlugin {
1445
1466
  getRowFilter(rows, filterItems, columnByProp) {
1446
1467
  const propKeys = Object.keys(filterItems);
1447
1468
  const trimmed = {};
1448
- let propFilterSatisfiedCount = 0;
1449
- let lastFilterResults = [];
1450
1469
  // each rows
1451
- rows.forEach((model, rowIndex) => {
1470
+ for (let rowIndex = 0; rowIndex < rows.length; rowIndex++) {
1452
1471
  // check filter by column properties
1453
1472
  for (const prop of propKeys) {
1454
- const propFilters = filterItems[prop];
1455
- // reset the count of satisfied filters
1456
- propFilterSatisfiedCount = 0;
1473
+ // add to the list of removed/trimmed rows of filter condition is satisfied
1474
+ if (this.shouldTrimRow(filterItems[prop], prop, columnByProp[prop], rows[rowIndex])) {
1475
+ trimmed[rowIndex] = true;
1476
+ }
1477
+ } // end of for-of propKeys
1478
+ }
1479
+ return trimmed;
1480
+ }
1481
+ shouldTrimRow(propFilters, prop, column, model = {}) {
1482
+ // reset the count of satisfied filters
1483
+ let propFilterSatisfiedCount = 0;
1484
+ // reset the array of last filter results
1485
+ let lastFilterResults = [];
1486
+ // testing each filter for a prop
1487
+ for (const [filterIndex, filterData] of propFilters.entries()) {
1488
+ // the filter LogicFunction based on the type
1489
+ const filterFunc = this.filterFunctionsIndexedByType[filterData.type];
1490
+ // THE MAGIC OF FILTERING IS HERE
1491
+ // If there is no column but user wants to filter by a property
1492
+ const value = column ? column_service.getCellDataParsed(model, column) : model[prop];
1493
+ // OR relation
1494
+ if (filterData.relation === 'or') {
1457
1495
  // reset the array of last filter results
1458
1496
  lastFilterResults = [];
1459
- // testing each filter for a prop
1460
- for (const [filterIndex, filterData] of propFilters.entries()) {
1461
- // the filter LogicFunction based on the type
1462
- const filterFunc = this.filterFunctionsIndexedByType[filterData.type];
1463
- // THE MAGIC OF FILTERING IS HERE
1464
- const column = columnByProp[prop];
1465
- // If there is no column but user wants to filter by a property
1466
- const value = column ? column_service.getCellDataParsed(model, columnByProp[prop]) : model[prop];
1467
- // OR relation
1468
- if (filterData.relation === 'or') {
1497
+ // if the filter is satisfied, continue to the next filter
1498
+ if (filterFunc(value, filterData.value)) {
1499
+ continue;
1500
+ }
1501
+ // if the filter is not satisfied, count it
1502
+ propFilterSatisfiedCount++;
1503
+ // AND relation
1504
+ }
1505
+ else {
1506
+ // 'and' relation will need to know the next filter
1507
+ // so we save this current filter to include it in the next filter
1508
+ lastFilterResults.push(!filterFunc(value, filterData.value));
1509
+ if (isFinalAndFilter(filterIndex, propFilters)) {
1510
+ // let's just continue since for sure propFilterSatisfiedCount cannot be satisfied
1511
+ if (allAndConditionsSatisfied(lastFilterResults)) {
1469
1512
  // reset the array of last filter results
1470
1513
  lastFilterResults = [];
1471
- // if the filter is satisfied, continue to the next filter
1472
- if (filterFunc(value, filterData.value)) {
1473
- continue;
1474
- }
1475
- // if the filter is not satisfied, count it
1476
- propFilterSatisfiedCount++;
1477
- // AND relation
1478
- }
1479
- else {
1480
- // 'and' relation will need to know the next filter
1481
- // so we save this current filter to include it in the next filter
1482
- lastFilterResults.push(!filterFunc(value, filterData.value));
1483
- // check first if we have a filter on the next index to pair it with this current filter
1484
- const nextFilterData = propFilters[filterIndex + 1];
1485
- // stop the sequence if there is no next filter or if the next filter is not an 'and' relation
1486
- if (!nextFilterData || nextFilterData.relation !== 'and') {
1487
- // let's just continue since for sure propFilterSatisfiedCount cannot be satisfied
1488
- if (lastFilterResults.indexOf(true) === -1) {
1489
- // reset the array of last filter results
1490
- lastFilterResults = [];
1491
- continue;
1492
- }
1493
- // we need to add all of the lastFilterResults since we need to satisfy all
1494
- propFilterSatisfiedCount += lastFilterResults.length;
1495
- // reset the array of last filter results
1496
- lastFilterResults = [];
1497
- }
1514
+ continue;
1498
1515
  }
1499
- } // end of propFilters forEach
1500
- // add to the list of removed/trimmed rows of filter condition is satisfied
1501
- if (propFilterSatisfiedCount === propFilters.length) {
1502
- trimmed[rowIndex] = true;
1516
+ // we need to add all of the lastFilterResults since we need to satisfy all
1517
+ propFilterSatisfiedCount += lastFilterResults.length;
1518
+ // reset the array of last filter results
1519
+ lastFilterResults = [];
1503
1520
  }
1504
- } // end of for-of propKeys
1505
- });
1506
- return trimmed;
1521
+ }
1522
+ } // end of propFilters forEach
1523
+ return propFilterSatisfiedCount === propFilters.length;
1507
1524
  }
1508
1525
  }
1526
+ /**
1527
+ * Checks if the current filter is the final one in an AND sequence.
1528
+ * @param index - Current filter index in the list.
1529
+ * @param filters - Array of filters for the property.
1530
+ * @returns True if this is the last AND condition; false otherwise.
1531
+ */
1532
+ function isFinalAndFilter(index, filters) {
1533
+ const nextFilter = filters[index + 1]; // Get the next filter in the list.
1534
+ // Return true if there's no next filter or if the next filter defined and is not part of the AND sequence.
1535
+ return !nextFilter || (!!nextFilter.relation && nextFilter.relation !== 'and');
1536
+ }
1537
+ /**
1538
+ * Determines if all conditions in an AND sequence are satisfied.
1539
+ * @param pendingResults - An array of results from the AND conditions.
1540
+ * @returns True if all conditions are satisfied; false otherwise.
1541
+ */
1542
+ function allAndConditionsSatisfied(pendingResults) {
1543
+ // Check if there are any failed conditions in the pending results.
1544
+ return !pendingResults.includes(true);
1545
+ }
1509
1546
 
1510
1547
  // provide collapse data
1511
1548
  function doCollapse(pIndex, source) {
@@ -2523,4 +2560,4 @@ exports.isRowType = isRowType;
2523
2560
  exports.isStretchPlugin = isStretchPlugin;
2524
2561
  exports.rowTypes = rowTypes;
2525
2562
 
2526
- //# sourceMappingURL=column.drag.plugin-e7ee8105.js.map
2563
+ //# sourceMappingURL=column.drag.plugin-5978b75e.js.map