@revolist/revogrid 4.9.9 → 4.9.11

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 (193) hide show
  1. package/dist/cjs/column.drag.plugin-e636b5af.js +1686 -0
  2. package/dist/cjs/column.drag.plugin-e636b5af.js.map +1 -0
  3. package/dist/cjs/{column.service-bfaba0e0.js → column.service-15c8352d.js} +443 -56
  4. package/dist/cjs/column.service-15c8352d.js.map +1 -0
  5. package/dist/cjs/{toNumber-838e6ff5.js → debounce-cb5f4e35.js} +229 -12
  6. package/dist/cjs/debounce-cb5f4e35.js.map +1 -0
  7. package/dist/cjs/{edit.utils-983f1a82.js → edit.utils-1172677c.js} +2 -2
  8. package/dist/cjs/{edit.utils-983f1a82.js.map → edit.utils-1172677c.js.map} +1 -1
  9. package/dist/cjs/{header-cell-renderer-53e4fd75.js → header-cell-renderer-375a879f.js} +42 -4
  10. package/dist/cjs/header-cell-renderer-375a879f.js.map +1 -0
  11. package/dist/cjs/{index-464d1aaf.js → index-28b6fdfb.js} +31 -31
  12. package/dist/cjs/{index-464d1aaf.js.map → index-28b6fdfb.js.map} +1 -1
  13. package/dist/cjs/index.cjs.js +39 -28
  14. package/dist/cjs/index.cjs.js.map +1 -1
  15. package/dist/cjs/{key.utils-12715159.js → key.utils-c62ab1e1.js} +2 -12
  16. package/dist/cjs/key.utils-c62ab1e1.js.map +1 -0
  17. package/dist/cjs/revo-grid.cjs.entry.js +704 -2034
  18. package/dist/cjs/revo-grid.cjs.entry.js.map +1 -1
  19. package/dist/cjs/revogr-attribution_6.cjs.entry.js +17 -18
  20. package/dist/cjs/revogr-attribution_6.cjs.entry.js.map +1 -1
  21. package/dist/cjs/revogr-clipboard_3.cjs.entry.js +6 -77
  22. package/dist/cjs/revogr-clipboard_3.cjs.entry.js.map +1 -1
  23. package/dist/cjs/revogr-data_4.cjs.entry.js +117 -123
  24. package/dist/cjs/revogr-data_4.cjs.entry.js.map +1 -1
  25. package/dist/cjs/revogr-filter-panel.cjs.entry.js +1 -2
  26. package/dist/cjs/revogr-filter-panel.cjs.entry.js.map +1 -1
  27. package/dist/cjs/{row-header-utils-e71dc7bf.js → row-header-utils-22ffee54.js} +2 -2
  28. package/dist/cjs/{row-header-utils-e71dc7bf.js.map → row-header-utils-22ffee54.js.map} +1 -1
  29. package/dist/cjs/sorting.sign-8bf92449.js +19 -0
  30. package/dist/cjs/sorting.sign-8bf92449.js.map +1 -0
  31. package/dist/cjs/text-editor-91a9f5b5.js +82 -0
  32. package/dist/cjs/text-editor-91a9f5b5.js.map +1 -0
  33. package/dist/cjs/{throttle-c893457e.js → throttle-5da5df51.js} +4 -5
  34. package/dist/cjs/throttle-5da5df51.js.map +1 -0
  35. package/dist/cjs/viewport.helpers-e59a544e.js +58 -0
  36. package/dist/cjs/viewport.helpers-e59a544e.js.map +1 -0
  37. package/dist/collection/components/editors/text-editor.js.map +1 -1
  38. package/dist/collection/components/header/revogr-header.js +1 -1
  39. package/dist/collection/components/overlay/keyboard.service.js +2 -2
  40. package/dist/collection/components/overlay/keyboard.service.js.map +1 -1
  41. package/dist/collection/components/revoGrid/revo-grid-style.css +6 -0
  42. package/dist/collection/index.js +2 -2
  43. package/dist/collection/index.js.map +1 -1
  44. package/dist/collection/plugins/index.js +16 -0
  45. package/dist/collection/plugins/index.js.map +1 -0
  46. package/dist/collection/plugins/moveColumn/column.drag.plugin.js.map +1 -1
  47. package/dist/collection/types/selection.js.map +1 -1
  48. package/dist/collection/utils/key.utils.js +0 -9
  49. package/dist/collection/utils/key.utils.js.map +1 -1
  50. package/dist/esm/column.drag.plugin-30dc4e24.js +1665 -0
  51. package/dist/esm/column.drag.plugin-30dc4e24.js.map +1 -0
  52. package/dist/esm/{column.service-6f1faf2d.js → column.service-414e9cba.js} +435 -51
  53. package/dist/esm/column.service-414e9cba.js.map +1 -0
  54. package/dist/esm/{toNumber-8de324a7.js → debounce-e8e9464a.js} +229 -13
  55. package/dist/esm/debounce-e8e9464a.js.map +1 -0
  56. package/dist/esm/{edit.utils-c3f5c9f4.js → edit.utils-0666e5bd.js} +2 -2
  57. package/dist/esm/{edit.utils-c3f5c9f4.js.map → edit.utils-0666e5bd.js.map} +1 -1
  58. package/dist/esm/{header-cell-renderer-66d01daa.js → header-cell-renderer-ca570fcf.js} +40 -4
  59. package/dist/esm/header-cell-renderer-ca570fcf.js.map +1 -0
  60. package/dist/esm/{index-c428acf6.js → index-74b9801b.js} +3 -3
  61. package/dist/esm/{index-c428acf6.js.map → index-74b9801b.js.map} +1 -1
  62. package/dist/esm/index.js +10 -7
  63. package/dist/esm/index.js.map +1 -1
  64. package/dist/esm/{key.utils-b1f93f7e.js → key.utils-d3df5db8.js} +3 -12
  65. package/dist/esm/key.utils-d3df5db8.js.map +1 -0
  66. package/dist/esm/revo-grid.entry.js +675 -2005
  67. package/dist/esm/revo-grid.entry.js.map +1 -1
  68. package/dist/esm/revogr-attribution_6.entry.js +9 -10
  69. package/dist/esm/revogr-attribution_6.entry.js.map +1 -1
  70. package/dist/esm/revogr-clipboard_3.entry.js +5 -76
  71. package/dist/esm/revogr-clipboard_3.entry.js.map +1 -1
  72. package/dist/esm/revogr-data_4.entry.js +50 -56
  73. package/dist/esm/revogr-data_4.entry.js.map +1 -1
  74. package/dist/esm/revogr-filter-panel.entry.js +1 -2
  75. package/dist/esm/revogr-filter-panel.entry.js.map +1 -1
  76. package/dist/esm/{row-header-utils-3a6f6adc.js → row-header-utils-c7e3e2d5.js} +2 -2
  77. package/dist/esm/{row-header-utils-3a6f6adc.js.map → row-header-utils-c7e3e2d5.js.map} +1 -1
  78. package/dist/esm/sorting.sign-1afddea1.js +15 -0
  79. package/dist/esm/sorting.sign-1afddea1.js.map +1 -0
  80. package/dist/esm/text-editor-96d69516.js +80 -0
  81. package/dist/esm/text-editor-96d69516.js.map +1 -0
  82. package/dist/esm/{throttle-f9cda5b0.js → throttle-262c3ed2.js} +3 -4
  83. package/dist/esm/throttle-262c3ed2.js.map +1 -0
  84. package/dist/esm/viewport.helpers-7e7f9dad.js +52 -0
  85. package/dist/esm/viewport.helpers-7e7f9dad.js.map +1 -0
  86. package/dist/revo-grid/column.drag.plugin-30dc4e24.js +5 -0
  87. package/dist/revo-grid/column.drag.plugin-30dc4e24.js.map +1 -0
  88. package/dist/revo-grid/column.service-414e9cba.js +5 -0
  89. package/dist/revo-grid/column.service-414e9cba.js.map +1 -0
  90. package/dist/revo-grid/debounce-e8e9464a.js +5 -0
  91. package/dist/revo-grid/debounce-e8e9464a.js.map +1 -0
  92. package/dist/revo-grid/{edit.utils-c3f5c9f4.js → edit.utils-0666e5bd.js} +2 -2
  93. package/dist/revo-grid/header-cell-renderer-ca570fcf.js +5 -0
  94. package/dist/revo-grid/header-cell-renderer-ca570fcf.js.map +1 -0
  95. package/dist/revo-grid/{index-c428acf6.js → index-74b9801b.js} +2 -2
  96. package/dist/revo-grid/index.esm.js +1 -1
  97. package/dist/revo-grid/key.utils-d3df5db8.js +5 -0
  98. package/dist/revo-grid/key.utils-d3df5db8.js.map +1 -0
  99. package/dist/revo-grid/revo-grid.entry.js +1 -1
  100. package/dist/revo-grid/revo-grid.entry.js.map +1 -1
  101. package/dist/revo-grid/revogr-attribution_6.entry.js +1 -1
  102. package/dist/revo-grid/revogr-attribution_6.entry.js.map +1 -1
  103. package/dist/revo-grid/revogr-clipboard_3.entry.js +1 -1
  104. package/dist/revo-grid/revogr-clipboard_3.entry.js.map +1 -1
  105. package/dist/revo-grid/revogr-data_4.entry.js +1 -1
  106. package/dist/revo-grid/revogr-data_4.entry.js.map +1 -1
  107. package/dist/revo-grid/revogr-filter-panel.entry.js +1 -1
  108. package/dist/revo-grid/revogr-filter-panel.entry.js.map +1 -1
  109. package/dist/revo-grid/{row-header-utils-3a6f6adc.js → row-header-utils-c7e3e2d5.js} +2 -2
  110. package/dist/revo-grid/sorting.sign-1afddea1.js +5 -0
  111. package/dist/revo-grid/sorting.sign-1afddea1.js.map +1 -0
  112. package/dist/revo-grid/text-editor-96d69516.js +5 -0
  113. package/dist/revo-grid/text-editor-96d69516.js.map +1 -0
  114. package/dist/revo-grid/throttle-262c3ed2.js +5 -0
  115. package/dist/revo-grid/{throttle-f9cda5b0.js.map → throttle-262c3ed2.js.map} +1 -1
  116. package/dist/revo-grid/viewport.helpers-7e7f9dad.js +5 -0
  117. package/dist/revo-grid/viewport.helpers-7e7f9dad.js.map +1 -0
  118. package/dist/types/components/editors/text-editor.d.ts +2 -2
  119. package/dist/types/index.d.ts +2 -2
  120. package/dist/types/plugins/index.d.ts +12 -0
  121. package/dist/types/plugins/moveColumn/column.drag.plugin.d.ts +1 -13
  122. package/dist/types/types/selection.d.ts +1 -1
  123. package/dist/types/utils/key.utils.d.ts +0 -1
  124. package/hydrate/index.js +2 -11
  125. package/hydrate/index.mjs +2 -11
  126. package/package.json +1 -1
  127. package/standalone/_stringToPath.js +1 -1
  128. package/standalone/column.service.js +1 -1
  129. package/standalone/data.store.js +2 -2
  130. package/standalone/debounce.js +1 -1
  131. package/standalone/dimension.helpers.js +1 -1
  132. package/standalone/index.js +7 -5
  133. package/standalone/index.js.map +1 -1
  134. package/standalone/isObjectLike.js +1 -1
  135. package/standalone/revo-grid.js +1948 -1948
  136. package/standalone/revo-grid.js.map +1 -1
  137. package/standalone/revogr-edit.js +1 -1
  138. package/standalone/revogr-edit2.js +1 -10
  139. package/standalone/revogr-edit2.js.map +1 -1
  140. package/standalone/revogr-header.js +1 -1
  141. package/standalone/revogr-header2.js +54 -52
  142. package/standalone/revogr-header2.js.map +1 -1
  143. package/standalone/revogr-overlay-selection2.js +2 -2
  144. package/standalone/revogr-overlay-selection2.js.map +1 -1
  145. package/standalone/revogr-row-headers2.js +1 -1
  146. package/standalone/throttle.js +1 -1
  147. package/standalone/toNumber.js +1 -1
  148. package/dist/cjs/column.service-bfaba0e0.js.map +0 -1
  149. package/dist/cjs/column.utils-4a450d27.js +0 -345
  150. package/dist/cjs/column.utils-4a450d27.js.map +0 -1
  151. package/dist/cjs/debounce-e2b7c6fb.js +0 -226
  152. package/dist/cjs/debounce-e2b7c6fb.js.map +0 -1
  153. package/dist/cjs/dispatcher-998aa470.js +0 -46
  154. package/dist/cjs/dispatcher-998aa470.js.map +0 -1
  155. package/dist/cjs/header-cell-renderer-53e4fd75.js.map +0 -1
  156. package/dist/cjs/key.utils-12715159.js.map +0 -1
  157. package/dist/cjs/selection.helpers-2c90d546.js +0 -450
  158. package/dist/cjs/selection.helpers-2c90d546.js.map +0 -1
  159. package/dist/cjs/throttle-c893457e.js.map +0 -1
  160. package/dist/cjs/toNumber-838e6ff5.js.map +0 -1
  161. package/dist/esm/column.service-6f1faf2d.js.map +0 -1
  162. package/dist/esm/column.utils-1a402ff9.js +0 -333
  163. package/dist/esm/column.utils-1a402ff9.js.map +0 -1
  164. package/dist/esm/debounce-7781346d.js +0 -224
  165. package/dist/esm/debounce-7781346d.js.map +0 -1
  166. package/dist/esm/dispatcher-ea08404f.js +0 -43
  167. package/dist/esm/dispatcher-ea08404f.js.map +0 -1
  168. package/dist/esm/header-cell-renderer-66d01daa.js.map +0 -1
  169. package/dist/esm/key.utils-b1f93f7e.js.map +0 -1
  170. package/dist/esm/selection.helpers-ac4368b0.js +0 -441
  171. package/dist/esm/selection.helpers-ac4368b0.js.map +0 -1
  172. package/dist/esm/throttle-f9cda5b0.js.map +0 -1
  173. package/dist/esm/toNumber-8de324a7.js.map +0 -1
  174. package/dist/revo-grid/column.service-6f1faf2d.js +0 -5
  175. package/dist/revo-grid/column.service-6f1faf2d.js.map +0 -1
  176. package/dist/revo-grid/column.utils-1a402ff9.js +0 -5
  177. package/dist/revo-grid/column.utils-1a402ff9.js.map +0 -1
  178. package/dist/revo-grid/debounce-7781346d.js +0 -5
  179. package/dist/revo-grid/debounce-7781346d.js.map +0 -1
  180. package/dist/revo-grid/dispatcher-ea08404f.js +0 -5
  181. package/dist/revo-grid/dispatcher-ea08404f.js.map +0 -1
  182. package/dist/revo-grid/header-cell-renderer-66d01daa.js +0 -5
  183. package/dist/revo-grid/header-cell-renderer-66d01daa.js.map +0 -1
  184. package/dist/revo-grid/key.utils-b1f93f7e.js +0 -5
  185. package/dist/revo-grid/key.utils-b1f93f7e.js.map +0 -1
  186. package/dist/revo-grid/selection.helpers-ac4368b0.js +0 -5
  187. package/dist/revo-grid/selection.helpers-ac4368b0.js.map +0 -1
  188. package/dist/revo-grid/throttle-f9cda5b0.js +0 -5
  189. package/dist/revo-grid/toNumber-8de324a7.js +0 -5
  190. package/dist/revo-grid/toNumber-8de324a7.js.map +0 -1
  191. /package/dist/revo-grid/{edit.utils-c3f5c9f4.js.map → edit.utils-0666e5bd.js.map} +0 -0
  192. /package/dist/revo-grid/{index-c428acf6.js.map → index-74b9801b.js.map} +0 -0
  193. /package/dist/revo-grid/{row-header-utils-3a6f6adc.js.map → row-header-utils-c7e3e2d5.js.map} +0 -0
@@ -2,23 +2,23 @@
2
2
  * Built by Revolist OU ❤️
3
3
  */
4
4
  import { h, proxyCustomElement, HTMLElement as HTMLElement$1, createEvent, Host } from '@stencil/core/internal/client';
5
- import { r as reduce_1, c as calculateDimensionData, e as each, a as getItemByIndex, g as getItemByPosition } from './dimension.helpers.js';
6
- import { i as createStore, h as setStore, j as isArray_1, _ as _baseIteratee, k as isArrayLike_1, l as keys_1, m as findIndex_1, D as DataStore, b as getSourceItem, e as getSourceItemVirtualIndexByProp, s as setSourceByVirtualIndex, a as getVisibleSourceItem, f as gatherTrimmedItems, n as _baseProperty, o as _baseKeys, r as range_1, q as toInteger_1, u as _isIterateeCall, g as getPhysical, d as setItems } from './data.store.js';
5
+ import { r as reduce_1, c as calculateDimensionData, e as each, g as getItemByPosition, a as getItemByIndex } from './dimension.helpers.js';
6
+ import { i as createStore, h as setStore, j as isArray_1, b as getSourceItem, k as toInteger_1, _ as _isIterateeCall, g as getPhysical, d as setItems, l as _baseProperty, m as _baseKeys, n as isArrayLike_1, r as range_1, o as _baseIteratee, q as keys_1, u as findIndex_1, D as DataStore, e as getSourceItemVirtualIndexByProp, s as setSourceByVirtualIndex, a as getVisibleSourceItem, f as gatherTrimmedItems } from './data.store.js';
7
7
  import { _ as _getTag } from './_stringToPath.js';
8
8
  import { _ as _baseGetTag, i as isObjectLike_1 } from './isObjectLike.js';
9
9
  import { b as isGrouping, d as getGroupingName, G as GROUP_EXPANDED, e as getParsedGroup, f as isSameGroup, h as GROUP_DEPTH, P as PSEUDO_GROUP_ITEM_VALUE, j as PSEUDO_GROUP_ITEM_ID, k as GROUPING_ROW_TYPE, l as PSEUDO_GROUP_COLUMN, m as GROUP_EXPAND_EVENT, o as gatherGrouping, p as isGroupingColumn, E as EMPTY_INDEX, q as SelectionStoreConnector } from './column.service.js';
10
10
  import { d as debounce_1 } from './debounce.js';
11
11
  import { R as RESIZE_INTERVAL } from './consts.js';
12
- import { V as ViewportStore, f as calculateRowHeaderSize, h as defineCustomElement$6 } from './revogr-row-headers2.js';
13
- import { t as timeout, g as getScrollbarSize } from './index2.js';
12
+ import { f as calculateRowHeaderSize, V as ViewportStore, h as defineCustomElement$6 } from './revogr-row-headers2.js';
13
+ import { g as getScrollbarSize, t as timeout } from './index2.js';
14
14
  import { F as FILTER_PROP, i as isFilterBtn } from './filter.button.js';
15
15
  import { v as viewportDataPartition, H as HEADER_SLOT, C as CONTENT_SLOT, F as FOOTER_SLOT, D as DATA_SLOT, d as defineCustomElement$3 } from './revogr-viewport-scroll2.js';
16
- import { d as dispatch, O as ON_COLUMN_CLICK, b as defineCustomElement$9 } from './revogr-header2.js';
16
+ import { d as dispatch, O as ON_COLUMN_CLICK, c as defineCustomElement$9 } from './revogr-header2.js';
17
17
  import { g as getPropertyFromEvent } from './selection.utils.js';
18
18
  import { d as defineCustomElement$e } from './revogr-attribution2.js';
19
19
  import { d as defineCustomElement$d } from './revogr-clipboard2.js';
20
20
  import { d as defineCustomElement$c } from './revogr-data2.js';
21
- import { m as defineCustomElement$b } from './revogr-edit2.js';
21
+ import { l as defineCustomElement$b } from './revogr-edit2.js';
22
22
  import { d as defineCustomElement$a } from './revogr-focus2.js';
23
23
  import { d as defineCustomElement$8 } from './revogr-order-editor2.js';
24
24
  import { d as defineCustomElement$7 } from './revogr-overlay-selection2.js';
@@ -414,1083 +414,1701 @@ function getColumnByProp(columns, prop) {
414
414
  return findColumn(columns, prop);
415
415
  }
416
416
 
417
- var baseIteratee = _baseIteratee,
418
- isArrayLike$1 = isArrayLike_1,
419
- keys = keys_1;
420
-
421
417
  /**
422
- * Creates a `_.find` or `_.findLast` function.
423
- *
424
- * @private
425
- * @param {Function} findIndexFunc The function to find the collection index.
426
- * @returns {Function} Returns the new find function.
418
+ * Plugin module for revo-grid grid system
419
+ * Add support for automatic column resize
427
420
  */
428
- function createFind$1(findIndexFunc) {
429
- return function(collection, predicate, fromIndex) {
430
- var iterable = Object(collection);
431
- if (!isArrayLike$1(collection)) {
432
- var iteratee = baseIteratee(predicate);
433
- collection = keys(collection);
434
- predicate = function(key) { return iteratee(iterable[key], key, iterable); };
421
+ const LETTER_BLOCK_SIZE = 7;
422
+ var ColumnAutoSizeMode;
423
+ (function (ColumnAutoSizeMode) {
424
+ // increases column width on header click according the largest text value
425
+ ColumnAutoSizeMode["headerClickAutosize"] = "headerClickAutoSize";
426
+ // increases column width on data set and text edit, decreases performance
427
+ ColumnAutoSizeMode["autoSizeOnTextOverlap"] = "autoSizeOnTextOverlap";
428
+ // increases and decreases column width based on all items sizes, worst for performance
429
+ ColumnAutoSizeMode["autoSizeAll"] = "autoSizeAll";
430
+ })(ColumnAutoSizeMode || (ColumnAutoSizeMode = {}));
431
+ class AutoSizeColumnPlugin extends BasePlugin {
432
+ constructor(revogrid, providers, config) {
433
+ super(revogrid, providers);
434
+ this.providers = providers;
435
+ this.config = config;
436
+ this.autoSizeColumns = null;
437
+ /** for edge case when no columns defined before data */
438
+ this.dataResolve = null;
439
+ this.dataReject = null;
440
+ this.letterBlockSize = (config === null || config === void 0 ? void 0 : config.letterBlockSize) || LETTER_BLOCK_SIZE;
441
+ // create test container to check text width
442
+ if (config === null || config === void 0 ? void 0 : config.preciseSize) {
443
+ this.precsizeCalculationArea = this.initiatePresizeElement();
444
+ revogrid.appendChild(this.precsizeCalculationArea);
445
+ }
446
+ const aftersourceset = ({ detail: { source }, }) => {
447
+ this.setSource(source);
448
+ };
449
+ const afteredit = ({ detail }) => {
450
+ this.afteredit(detail);
451
+ };
452
+ const afterEditAll = ({ detail }) => {
453
+ this.afterEditAll(detail);
454
+ };
455
+ const beforecolumnsset = ({ detail: { columns }, }) => {
456
+ this.columnSet(columns);
457
+ };
458
+ const headerDblClick = ({ detail }) => {
459
+ const type = getColumnType(detail.column);
460
+ const size = this.getColumnSize(detail.index, type);
461
+ if (size) {
462
+ this.providers.dimension.setCustomSizes(type, {
463
+ [detail.index]: size,
464
+ }, true);
465
+ }
466
+ };
467
+ this.addEventListener('beforecolumnsset', beforecolumnsset);
468
+ switch (config === null || config === void 0 ? void 0 : config.mode) {
469
+ case ColumnAutoSizeMode.autoSizeOnTextOverlap:
470
+ this.addEventListener('aftersourceset', aftersourceset);
471
+ this.addEventListener('afteredit', afteredit);
472
+ break;
473
+ case ColumnAutoSizeMode.autoSizeAll:
474
+ this.addEventListener('aftersourceset', aftersourceset);
475
+ this.addEventListener('afteredit', afterEditAll);
476
+ break;
477
+ default:
478
+ this.addEventListener('headerdblclick', headerDblClick);
479
+ break;
480
+ }
435
481
  }
436
- var index = findIndexFunc(collection, predicate, fromIndex);
437
- return index > -1 ? iterable[iteratee ? collection[index] : index] : undefined;
438
- };
439
- }
440
-
441
- var _createFind = createFind$1;
442
-
443
- var createFind = _createFind,
444
- findIndex = findIndex_1;
445
-
446
- /**
447
- * Iterates over elements of `collection`, returning the first element
448
- * `predicate` returns truthy for. The predicate is invoked with three
449
- * arguments: (value, index|key, collection).
450
- *
451
- * @static
452
- * @memberOf _
453
- * @since 0.1.0
454
- * @category Collection
455
- * @param {Array|Object} collection The collection to inspect.
456
- * @param {Function} [predicate=_.identity] The function invoked per iteration.
457
- * @param {number} [fromIndex=0] The index to search from.
458
- * @returns {*} Returns the matched element, else `undefined`.
459
- * @example
460
- *
461
- * var users = [
462
- * { 'user': 'barney', 'age': 36, 'active': true },
463
- * { 'user': 'fred', 'age': 40, 'active': false },
464
- * { 'user': 'pebbles', 'age': 1, 'active': true }
465
- * ];
466
- *
467
- * _.find(users, function(o) { return o.age < 40; });
468
- * // => object for 'barney'
469
- *
470
- * // The `_.matches` iteratee shorthand.
471
- * _.find(users, { 'age': 1, 'active': true });
472
- * // => object for 'pebbles'
473
- *
474
- * // The `_.matchesProperty` iteratee shorthand.
475
- * _.find(users, ['active', false]);
476
- * // => object for 'fred'
477
- *
478
- * // The `_.property` iteratee shorthand.
479
- * _.find(users, 'active');
480
- * // => object for 'barney'
481
- */
482
- var find = createFind(findIndex);
483
-
484
- var find_1 = find;
485
-
486
- class ColumnDataProvider {
487
- get order() {
488
- const order = {};
489
- const sorting = this.sorting;
490
- if (sorting) {
491
- Object.keys(sorting).forEach((prop) => {
492
- order[prop] = sorting[prop].order;
482
+ async setSource(source) {
483
+ let autoSize = this.autoSizeColumns;
484
+ if (this.dataReject) {
485
+ this.dataReject();
486
+ this.clearPromise();
487
+ }
488
+ /** If data set first and no column provided await until get one */
489
+ if (!autoSize) {
490
+ const request = new Promise((resolve, reject) => {
491
+ this.dataResolve = resolve;
492
+ this.dataReject = reject;
493
493
  });
494
+ try {
495
+ autoSize = await request;
496
+ }
497
+ catch (e) {
498
+ return;
499
+ }
494
500
  }
495
- return order;
496
- }
497
- get stores() {
498
- return this.dataSources;
499
- }
500
- constructor() {
501
- this.sorting = null;
502
- this.dataSources = columnTypes.reduce((sources, k) => {
503
- sources[k] = new DataStore(k);
504
- return sources;
505
- }, {});
506
- }
507
- column(c, pin) {
508
- return this.getColumn(c, pin || 'rgCol');
509
- }
510
- getColumn(virtualIndex, type) {
511
- return getSourceItem(this.dataSources[type].store, virtualIndex);
512
- }
513
- getRawColumns() {
514
- return reduce_1(this.dataSources, (result, item, type) => {
515
- result[type] = item.store.get('source');
516
- return result;
517
- }, {
518
- rgCol: [],
519
- colPinStart: [],
520
- colPinEnd: [],
501
+ // calculate sizes
502
+ each(autoSize, (_v, type) => {
503
+ const sizes = {};
504
+ each(autoSize[type], rgCol => {
505
+ // calculate size
506
+ rgCol.size = sizes[rgCol.index] = source.reduce((prev, rgRow) => Math.max(prev, this.getLength(rgRow[rgCol.prop])), this.getLength(rgCol.name || ''));
507
+ });
508
+ this.providers.dimension.setCustomSizes(type, sizes, true);
521
509
  });
522
510
  }
523
- getColumns(type = 'all') {
524
- if (type !== 'all') {
525
- return this.dataSources[type].store.get('source');
511
+ getLength(len) {
512
+ var _a;
513
+ const padding = 15;
514
+ if (!len) {
515
+ return 0;
516
+ }
517
+ try {
518
+ const str = len.toString();
519
+ /**if exact calculation required proxy with html element, slow operation */
520
+ if ((_a = this.config) === null || _a === void 0 ? void 0 : _a.preciseSize) {
521
+ this.precsizeCalculationArea.innerText = str;
522
+ return this.precsizeCalculationArea.scrollWidth + padding * 2;
523
+ }
524
+ return str.length * this.letterBlockSize + padding * 2;
525
+ }
526
+ catch (e) {
527
+ return 0;
526
528
  }
527
- return columnTypes.reduce((r, t) => {
528
- r.push(...this.dataSources[t].store.get('source'));
529
- return r;
530
- }, []);
531
- }
532
- getColumnIndexByProp(prop, type) {
533
- return getSourceItemVirtualIndexByProp(this.dataSources[type].store, prop);
534
- }
535
- getColumnByProp(prop, type) {
536
- const items = this.dataSources[type].store.get('source');
537
- return find_1(items, { prop });
538
- }
539
- refreshByType(type) {
540
- this.dataSources[type].refresh();
541
529
  }
542
- setColumns(data) {
543
- columnTypes.forEach(k => {
544
- // set columns data
545
- this.dataSources[k].updateData(data.columns[k], {
546
- // max depth level
547
- depth: data.maxLevel,
548
- // groups
549
- groups: data.columnGrouping[k].reduce((res, g) => {
550
- if (!res[g.level]) {
551
- res[g.level] = [];
530
+ afteredit(e) {
531
+ let data;
532
+ if (this.isRangeEdit(e)) {
533
+ data = e.data;
534
+ }
535
+ else {
536
+ data = { 0: { [e.prop]: e.val } };
537
+ }
538
+ each(this.autoSizeColumns, (columns, type) => {
539
+ const sizes = {};
540
+ each(columns, rgCol => {
541
+ var _a;
542
+ // calculate size
543
+ const size = reduce_1(data, (prev, rgRow) => {
544
+ if (typeof rgRow[rgCol.prop] === 'undefined') {
545
+ return prev;
552
546
  }
553
- res[g.level].push(g);
554
- return res;
555
- }, {}),
547
+ return Math.max(prev || 0, this.getLength(rgRow[rgCol.prop]));
548
+ }, undefined);
549
+ if (size && ((_a = rgCol.size) !== null && _a !== void 0 ? _a : 0) < size) {
550
+ rgCol.size = sizes[rgCol.index] = size;
551
+ }
556
552
  });
553
+ this.providers.dimension.setCustomSizes(type, sizes, true);
557
554
  });
558
- this.sorting = data.sort;
559
- return data;
560
555
  }
561
- updateColumns(cols) {
562
- // collect column by type and propert
563
- const columnByKey = cols.reduce((res, c) => {
564
- const type = getColumnType(c);
565
- if (!res[type]) {
566
- res[type] = {};
567
- }
568
- res[type][c.prop] = c;
569
- return res;
570
- }, {});
571
- // find indexes in source
572
- const colByIndex = {};
573
- for (const t in columnByKey) {
574
- if (!columnByKey.hasOwnProperty(t)) {
575
- continue;
576
- }
556
+ afterEditAll(e) {
557
+ const props = {};
558
+ if (this.isRangeEdit(e)) {
559
+ each(e.data, r => each(r, (_v, p) => (props[p] = true)));
560
+ }
561
+ else {
562
+ props[e.prop] = true;
563
+ }
564
+ each(this.autoSizeColumns, (columns, type) => {
565
+ const sizes = {};
566
+ each(columns, rgCol => {
567
+ if (props[rgCol.prop]) {
568
+ const size = this.getColumnSize(rgCol.index, type);
569
+ if (size) {
570
+ sizes[rgCol.index] = size;
571
+ }
572
+ }
573
+ });
574
+ this.providers.dimension.setCustomSizes(type, sizes, true);
575
+ });
576
+ }
577
+ getColumnSize(index, type) {
578
+ var _a, _b;
579
+ const rgCol = (_b = (_a = this.autoSizeColumns) === null || _a === void 0 ? void 0 : _a[type]) === null || _b === void 0 ? void 0 : _b[index];
580
+ if (!rgCol) {
581
+ return 0;
582
+ }
583
+ return reduce_1(this.providers.data.stores, (r, s) => {
584
+ const perStore = reduce_1(s.store.get('items'), (prev, _row, i) => {
585
+ const item = getSourceItem(s.store, i);
586
+ return Math.max(prev || 0, this.getLength(item === null || item === void 0 ? void 0 : item[rgCol.prop]));
587
+ }, 0);
588
+ return Math.max(r, perStore);
589
+ }, rgCol.size || 0);
590
+ }
591
+ columnSet(columns) {
592
+ var _a;
593
+ for (let t of columnTypes) {
577
594
  const type = t;
578
- const colsToUpdate = columnByKey[type];
579
- const items = this.dataSources[type].store.get('source');
580
- colByIndex[type] = {};
581
- for (let i = 0; i < items.length; i++) {
582
- const rgCol = items[i];
583
- const colToUpdateIfExists = colsToUpdate === null || colsToUpdate === void 0 ? void 0 : colsToUpdate[rgCol.prop];
584
- if (colToUpdateIfExists) {
585
- colByIndex[type][i] = colToUpdateIfExists;
595
+ const cols = columns[type];
596
+ for (let i in cols) {
597
+ if (cols[i].autoSize || ((_a = this.config) === null || _a === void 0 ? void 0 : _a.allColumns)) {
598
+ if (!this.autoSizeColumns) {
599
+ this.autoSizeColumns = {};
600
+ }
601
+ if (!this.autoSizeColumns[type]) {
602
+ this.autoSizeColumns[type] = {};
603
+ }
604
+ this.autoSizeColumns[type][i] = Object.assign(Object.assign({}, cols[i]), { index: parseInt(i, 10) });
586
605
  }
587
606
  }
588
607
  }
589
- for (const t in colByIndex) {
590
- if (!colByIndex.hasOwnProperty(t)) {
591
- continue;
592
- }
593
- const type = t;
594
- setSourceByVirtualIndex(this.dataSources[type].store, colByIndex[type] || {});
608
+ if (this.dataResolve) {
609
+ this.dataResolve(this.autoSizeColumns || {});
610
+ this.clearPromise();
595
611
  }
596
612
  }
597
- updateColumn(column, index) {
598
- const type = getColumnType(column);
599
- setSourceByVirtualIndex(this.dataSources[type].store, { [index]: column });
613
+ clearPromise() {
614
+ this.dataResolve = null;
615
+ this.dataReject = null;
600
616
  }
601
- updateColumnSorting(column, index, sorting, additive) {
602
- if (!additive) {
603
- this.clearSorting();
604
- }
605
- column.order = sorting;
606
- if (!this.sorting) {
607
- this.sorting = {};
617
+ isRangeEdit(e) {
618
+ return !!e.data;
619
+ }
620
+ initiatePresizeElement() {
621
+ var _a;
622
+ const styleForFontTest = {
623
+ position: 'absolute',
624
+ fontSize: '14px',
625
+ height: '0',
626
+ width: '0',
627
+ whiteSpace: 'nowrap',
628
+ top: '0',
629
+ overflowX: 'scroll',
630
+ };
631
+ const el = document.createElement('div');
632
+ for (let s in styleForFontTest) {
633
+ el.style[s] = (_a = styleForFontTest[s]) !== null && _a !== void 0 ? _a : '';
608
634
  }
609
- this.sorting[column.prop] = column;
610
- this.updateColumn(column, index);
611
- return column;
635
+ el.classList.add('revo-test-container');
636
+ return el;
612
637
  }
613
- clearSorting() {
614
- const types = reduce_1(this.sorting, (r, c) => {
615
- const k = getColumnType(c);
616
- r[k] = true;
617
- return r;
618
- }, {});
619
- each(types, (_, type) => {
620
- const cols = this.dataSources[type].store.get('source');
621
- each(cols, (c) => (c.order = undefined));
622
- this.dataSources[type].setData({ source: [...cols] });
623
- });
624
- this.sorting = {};
638
+ destroy() {
639
+ var _a;
640
+ super.destroy();
641
+ (_a = this.precsizeCalculationArea) === null || _a === void 0 ? void 0 : _a.remove();
625
642
  }
626
643
  }
627
644
 
628
- /**
629
- * Data source provider
630
- */
631
- class DataProvider {
632
- constructor(dimensionProvider) {
633
- this.dimensionProvider = dimensionProvider;
634
- this.stores = reduce_1(rowTypes, (sources, k) => {
635
- sources[k] = new DataStore(k);
636
- return sources;
637
- }, {});
638
- }
639
- setData(data, type = 'rgRow', disableVirtualRows = false, grouping, silent = false) {
640
- // set rgRow data
641
- this.stores[type].updateData([...data], grouping, silent);
642
- // for pinned row no need virtual data
643
- const noVirtual = type !== 'rgRow' || disableVirtualRows;
644
- this.dimensionProvider.setData(data.length, type, noVirtual);
645
- return data;
646
- }
647
- getModel(virtualIndex, type = 'rgRow') {
648
- const store = this.stores[type].store;
649
- return getSourceItem(store, virtualIndex);
650
- }
651
- setCellData({ type, rowIndex, prop, val }, mutate = true) {
652
- const model = this.getModel(rowIndex, type);
653
- model[prop] = val;
654
- // apply data to source
655
- setSourceByVirtualIndex(this.stores[type].store, { [rowIndex]: model }, mutate);
645
+ class StretchColumn extends BasePlugin {
646
+ constructor(revogrid, providers) {
647
+ super(revogrid, providers);
648
+ this.providers = providers;
649
+ this.stretchedColumn = null;
650
+ // calculate scroll bar size for current user session
651
+ this.scrollSize = getScrollbarSize(document);
652
+ // subscribe to column changes
653
+ const beforecolumnapplied = ({ detail: { columns }, }) => this.applyStretch(columns);
654
+ this.addEventListener('beforecolumnapplied', beforecolumnapplied);
656
655
  }
657
- setRangeData(data, type) {
658
- const items = {};
659
- for (let rowIndex in data) {
660
- const oldModel = (items[rowIndex] = getSourceItem(this.stores[type].store, parseInt(rowIndex, 10)));
661
- if (!oldModel) {
662
- continue;
663
- }
664
- for (let prop in data[rowIndex]) {
665
- oldModel[prop] = data[rowIndex][prop];
656
+ setScroll({ type, hasScroll }) {
657
+ var _a;
658
+ if (type === 'rgRow' &&
659
+ this.stretchedColumn &&
660
+ ((_a = this.stretchedColumn) === null || _a === void 0 ? void 0 : _a.initialSize) === this.stretchedColumn.size) {
661
+ if (hasScroll) {
662
+ this.stretchedColumn.size -= this.scrollSize;
663
+ this.apply();
664
+ this.dropChanges();
666
665
  }
667
666
  }
668
- // apply data to source
669
- setSourceByVirtualIndex(this.stores[type].store, items);
670
- }
671
- refresh(type = 'all') {
672
- if (isRowType(type)) {
673
- this.refreshItems(type);
674
- }
675
- rowTypes.forEach((t) => this.refreshItems(t));
676
667
  }
677
- refreshItems(type = 'rgRow') {
678
- const items = this.stores[type].store.get('items');
679
- this.stores[type].setData({ items: [...items] });
668
+ activateChanges() {
669
+ const setScroll = ({ detail }) => this.setScroll(detail);
670
+ this.addEventListener('scrollchange', setScroll);
680
671
  }
681
- setGrouping({ depth }, type = 'rgRow') {
682
- this.stores[type].setData({ groupingDepth: depth });
672
+ dropChanges() {
673
+ this.stretchedColumn = null;
674
+ this.removeEventListener('scrollchange');
683
675
  }
684
- setTrimmed(trimmed, type = 'rgRow') {
685
- const store = this.stores[type];
686
- store.addTrimmed(trimmed);
687
- this.dimensionProvider.setTrimmed(trimmed, type);
688
- if (type === 'rgRow') {
689
- this.dimensionProvider.setData(getVisibleSourceItem(store.store).length, type);
676
+ apply() {
677
+ if (!this.stretchedColumn) {
678
+ return;
690
679
  }
691
- }
692
- }
693
-
694
- /**
695
- * Dimension provider
696
- * Stores dimension information and custom sizes
697
- */
698
- class DimensionProvider {
699
- constructor(viewports, config) {
700
- this.viewports = viewports;
701
- const sizeChanged = debounce_1((k) => config.realSizeChanged(k), RESIZE_INTERVAL);
702
- this.stores = reduce_1([...rowTypes, ...columnTypes], (sources, k) => {
703
- sources[k] = new DimensionStore();
704
- sources[k].store.onChange('realSize', () => sizeChanged(k));
705
- return sources;
706
- }, {});
707
- }
708
- /**
709
- * Clear old sizes from dimension and viewports
710
- * @param type - dimension type
711
- * @param count - count of items
712
- */
713
- clearSize(t, count) {
714
- this.stores[t].drop();
715
- // after we done with drop trigger viewport recalculaction
716
- this.viewports.stores[t].setOriginalSizes(this.stores[t].store.get('originItemSize'));
717
- this.setItemCount(count, t);
680
+ const type = 'rgCol';
681
+ const sizes = this.providers.dimension.stores[type].store.get('sizes');
682
+ this.providers.dimension.setCustomSizes(type, Object.assign(Object.assign({}, sizes), { [this.stretchedColumn.index]: this.stretchedColumn.size }), true);
718
683
  }
719
684
  /**
720
- * Apply new custom sizes to dimension and view port
721
- * @param type - dimension type
722
- * @param sizes - new custom sizes
723
- * @param keepOld - keep old sizes merge new with old
685
+ * Apply stretch changes
724
686
  */
725
- setCustomSizes(type, sizes, keepOld = false) {
726
- let newSizes = sizes;
727
- if (keepOld) {
728
- const oldSizes = this.stores[type].store.get('sizes');
729
- newSizes = Object.assign(Object.assign({}, oldSizes), sizes);
687
+ applyStretch(columns) {
688
+ // unsubscribe from all events
689
+ this.dropChanges();
690
+ // calculate grid size
691
+ let sizeDifference = this.revogrid.clientWidth - 1;
692
+ each(columns, (_, type) => {
693
+ const realSize = this.providers.dimension.stores[type].store.get('realSize');
694
+ sizeDifference -= realSize;
695
+ });
696
+ if (this.revogrid.rowHeaders) {
697
+ const itemsLength = this.providers.data.stores.rgRow.store.get('source').length;
698
+ const header = this.revogrid.rowHeaders;
699
+ const rowHeaderSize = calculateRowHeaderSize(itemsLength, typeof header === 'object' ? header : undefined);
700
+ if (rowHeaderSize) {
701
+ sizeDifference -= rowHeaderSize;
702
+ }
730
703
  }
731
- this.stores[type].setDimensionSize(newSizes);
732
- this.updateViewport(type, true);
704
+ if (sizeDifference > 0) {
705
+ // currently plugin accepts last column only
706
+ const index = columns.rgCol.length - 1;
707
+ const last = columns.rgCol[index];
708
+ /**
709
+ * has column
710
+ * no auto size applied
711
+ * size for column shouldn't be defined
712
+ */
713
+ const colSize = (last === null || last === void 0 ? void 0 : last.size) || this.revogrid.colSize || 0;
714
+ const size = sizeDifference + colSize - 1;
715
+ if (last && !last.autoSize && colSize < size) {
716
+ this.stretchedColumn = {
717
+ initialSize: size,
718
+ index,
719
+ size,
720
+ };
721
+ this.apply();
722
+ this.activateChanges();
723
+ }
724
+ }
725
+ }
726
+ }
727
+ /**
728
+ * Check plugin type is Stretch
729
+ */
730
+ function isStretchPlugin(plugin) {
731
+ return !!plugin.applyStretch;
732
+ }
733
+
734
+ /**
735
+ * The base implementation of `_.clamp` which doesn't coerce arguments.
736
+ *
737
+ * @private
738
+ * @param {number} number The number to clamp.
739
+ * @param {number} [lower] The lower bound.
740
+ * @param {number} upper The upper bound.
741
+ * @returns {number} Returns the clamped number.
742
+ */
743
+
744
+ function baseClamp$1(number, lower, upper) {
745
+ if (number === number) {
746
+ if (upper !== undefined) {
747
+ number = number <= upper ? number : upper;
748
+ }
749
+ if (lower !== undefined) {
750
+ number = number >= lower ? number : lower;
751
+ }
752
+ }
753
+ return number;
754
+ }
755
+
756
+ var _baseClamp = baseClamp$1;
757
+
758
+ var baseClamp = _baseClamp,
759
+ toInteger$1 = toInteger_1;
760
+
761
+ /** Used as references for the maximum length and index of an array. */
762
+ var MAX_ARRAY_LENGTH = 4294967295;
763
+
764
+ /**
765
+ * Converts `value` to an integer suitable for use as the length of an
766
+ * array-like object.
767
+ *
768
+ * **Note:** This method is based on
769
+ * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).
770
+ *
771
+ * @static
772
+ * @memberOf _
773
+ * @since 4.0.0
774
+ * @category Lang
775
+ * @param {*} value The value to convert.
776
+ * @returns {number} Returns the converted integer.
777
+ * @example
778
+ *
779
+ * _.toLength(3.2);
780
+ * // => 3
781
+ *
782
+ * _.toLength(Number.MIN_VALUE);
783
+ * // => 0
784
+ *
785
+ * _.toLength(Infinity);
786
+ * // => 4294967295
787
+ *
788
+ * _.toLength('3.2');
789
+ * // => 3
790
+ */
791
+ function toLength$1(value) {
792
+ return value ? baseClamp(toInteger$1(value), 0, MAX_ARRAY_LENGTH) : 0;
793
+ }
794
+
795
+ var toLength_1 = toLength$1;
796
+
797
+ var toInteger = toInteger_1,
798
+ toLength = toLength_1;
799
+
800
+ /**
801
+ * The base implementation of `_.fill` without an iteratee call guard.
802
+ *
803
+ * @private
804
+ * @param {Array} array The array to fill.
805
+ * @param {*} value The value to fill `array` with.
806
+ * @param {number} [start=0] The start position.
807
+ * @param {number} [end=array.length] The end position.
808
+ * @returns {Array} Returns `array`.
809
+ */
810
+ function baseFill$1(array, value, start, end) {
811
+ var length = array.length;
812
+
813
+ start = toInteger(start);
814
+ if (start < 0) {
815
+ start = -start > length ? 0 : (length + start);
816
+ }
817
+ end = (end === undefined || end > length) ? length : toInteger(end);
818
+ if (end < 0) {
819
+ end += length;
820
+ }
821
+ end = start > end ? 0 : toLength(end);
822
+ while (start < end) {
823
+ array[start++] = value;
824
+ }
825
+ return array;
826
+ }
827
+
828
+ var _baseFill = baseFill$1;
829
+
830
+ var baseFill = _baseFill,
831
+ isIterateeCall = _isIterateeCall;
832
+
833
+ /**
834
+ * Fills elements of `array` with `value` from `start` up to, but not
835
+ * including, `end`.
836
+ *
837
+ * **Note:** This method mutates `array`.
838
+ *
839
+ * @static
840
+ * @memberOf _
841
+ * @since 3.2.0
842
+ * @category Array
843
+ * @param {Array} array The array to fill.
844
+ * @param {*} value The value to fill `array` with.
845
+ * @param {number} [start=0] The start position.
846
+ * @param {number} [end=array.length] The end position.
847
+ * @returns {Array} Returns `array`.
848
+ * @example
849
+ *
850
+ * var array = [1, 2, 3];
851
+ *
852
+ * _.fill(array, 'a');
853
+ * console.log(array);
854
+ * // => ['a', 'a', 'a']
855
+ *
856
+ * _.fill(Array(3), 2);
857
+ * // => [2, 2, 2]
858
+ *
859
+ * _.fill([4, 6, 8, 10], '*', 1, 3);
860
+ * // => [4, '*', '*', 10]
861
+ */
862
+ function fill(array, value, start, end) {
863
+ var length = array == null ? 0 : array.length;
864
+ if (!length) {
865
+ return [];
866
+ }
867
+ if (start && typeof start != 'number' && isIterateeCall(array, value, start)) {
868
+ start = 0;
869
+ end = length;
870
+ }
871
+ return baseFill(array, value, start, end);
872
+ }
873
+
874
+ var fill_1 = fill;
875
+
876
+ const INITIAL = {
877
+ mime: 'text/csv',
878
+ fileKind: 'csv',
879
+ // BOM signature
880
+ bom: true,
881
+ columnDelimiter: ',',
882
+ rowDelimiter: '\r\n',
883
+ encoding: '',
884
+ };
885
+ // The ASCII character code 13 is called a Carriage Return or CR.
886
+ const CARRIAGE_RETURN = String.fromCharCode(13);
887
+ // Chr(13) followed by a Chr(10) that compose a proper CRLF.
888
+ const LINE_FEED = String.fromCharCode(10);
889
+ const DOUBLE_QT = String.fromCharCode(34);
890
+ const NO_BREAK_SPACE = String.fromCharCode(0xfeff);
891
+ const escapeRegex = new RegExp('"', 'g');
892
+ class ExportCsv {
893
+ constructor(options = {}) {
894
+ this.options = Object.assign(Object.assign({}, INITIAL), options);
895
+ }
896
+ doExport({ data, headers, props }) {
897
+ let result = this.options.bom ? NO_BREAK_SPACE : '';
898
+ // any header
899
+ if ((headers === null || headers === void 0 ? void 0 : headers.length) > 0) {
900
+ headers.forEach(header => {
901
+ // ignore empty
902
+ if (!header.length) {
903
+ return;
904
+ }
905
+ result += this.prepareHeader(header, this.options.columnDelimiter);
906
+ result += this.options.rowDelimiter;
907
+ });
908
+ }
909
+ data.forEach((rgRow, index) => {
910
+ if (index > 0) {
911
+ result += this.options.rowDelimiter;
912
+ }
913
+ // support grouping
914
+ if (isGrouping(rgRow)) {
915
+ result += this.parseCell(getGroupingName(rgRow), this.options.columnDelimiter);
916
+ return;
917
+ }
918
+ result += props.map(p => this.parseCell(rgRow[p], this.options.columnDelimiter)).join(this.options.columnDelimiter);
919
+ });
920
+ return result;
921
+ }
922
+ prepareHeader(columnHeaders, columnDelimiter) {
923
+ let result = '';
924
+ const newColumnHeaders = columnHeaders.map(v => this.parseCell(v, columnDelimiter, true));
925
+ result += newColumnHeaders.join(columnDelimiter);
926
+ return result;
927
+ }
928
+ parseCell(value, columnDelimiter, force = false) {
929
+ let escape = value;
930
+ if (typeof value !== 'string') {
931
+ escape = JSON.stringify(value);
932
+ }
933
+ const toEscape = [CARRIAGE_RETURN, DOUBLE_QT, LINE_FEED, columnDelimiter];
934
+ if (typeof escape === 'undefined') {
935
+ return '';
936
+ }
937
+ if (escape !== '' && (force || toEscape.some(i => escape.indexOf(i) >= 0))) {
938
+ return `"${escape.replace(escapeRegex, '""')}"`;
939
+ }
940
+ return escape;
941
+ }
942
+ }
943
+
944
+ var ExportTypes;
945
+ (function (ExportTypes) {
946
+ ExportTypes["csv"] = "csv";
947
+ })(ExportTypes || (ExportTypes = {}));
948
+ class ExportFilePlugin extends BasePlugin {
949
+ /** Exports string */
950
+ async exportString(options = {}, t = ExportTypes.csv) {
951
+ const data = await this.beforeexport();
952
+ if (!data) {
953
+ return null;
954
+ }
955
+ return this.formatter(t, options).doExport(data);
956
+ }
957
+ /** Exports Blob */
958
+ async exportBlob(options = {}, t = ExportTypes.csv) {
959
+ return await this.getBlob(this.formatter(t, options));
960
+ }
961
+ /** Export file */
962
+ async exportFile(options = {}, t = ExportTypes.csv) {
963
+ const formatter = this.formatter(t, options);
964
+ // url
965
+ const URL = window.URL || window.webkitURL;
966
+ const a = document.createElement('a');
967
+ const { filename, fileKind } = formatter.options;
968
+ const name = `${filename}.${fileKind}`;
969
+ const blob = await this.getBlob(formatter);
970
+ const url = blob ? URL.createObjectURL(blob) : '';
971
+ a.style.display = 'none';
972
+ a.setAttribute('href', url);
973
+ a.setAttribute('download', name);
974
+ this.revogrid.appendChild(a);
975
+ a.dispatchEvent(new MouseEvent('click'));
976
+ this.revogrid.removeChild(a);
977
+ // delay for revoke, correct for some browsers
978
+ await timeout(120);
979
+ URL.revokeObjectURL(url);
733
980
  }
734
- setItemCount(realCount, type) {
735
- this.viewports.stores[type].setViewport({ realCount });
736
- this.stores[type].setStore({ count: realCount });
981
+ /** Blob object */
982
+ async getBlob(formatter) {
983
+ const type = `${formatter.options.mime};charset=${formatter.options.encoding}`;
984
+ if (typeof Blob !== 'undefined') {
985
+ const data = await this.beforeexport();
986
+ if (!data) {
987
+ return null;
988
+ }
989
+ return new Blob([formatter.doExport(data)], { type });
990
+ }
991
+ return null;
737
992
  }
738
- /**
739
- * Apply trimmed items
740
- * @param trimmed - trimmed items
741
- * @param type
742
- */
743
- setTrimmed(trimmed, type) {
744
- const allTrimmed = gatherTrimmedItems(trimmed);
745
- const dimStoreType = this.stores[type];
746
- dimStoreType.setStore({ trimmed: allTrimmed });
747
- this.updateViewport(type, true);
993
+ // before event
994
+ async beforeexport() {
995
+ let data = await this.getData();
996
+ const event = this.emit('beforeexport', { data });
997
+ if (event.defaultPrevented) {
998
+ return null;
999
+ }
1000
+ return event.detail.data;
748
1001
  }
749
- /**
750
- * Sets dimension data and view port coordinate
751
- * @param itemCount
752
- * @param type - dimension type
753
- * @param noVirtual - disable virtual data
754
- */
755
- setData(itemCount, type, noVirtual = false) {
756
- this.setItemCount(itemCount, type);
757
- // Virtualization will get disabled
758
- if (noVirtual) {
759
- const dimension = this.stores[type].getCurrentState();
760
- this.viewports.stores[type].setViewport({
761
- virtualSize: dimension.realSize,
1002
+ async getData() {
1003
+ const data = await this.getSource();
1004
+ const colSource = [];
1005
+ const colPromises = [];
1006
+ columnTypes.forEach((t, i) => {
1007
+ colPromises.push(this.getColPerSource(t).then(s => (colSource[i] = s)));
1008
+ });
1009
+ await Promise.all(colPromises);
1010
+ const columns = {
1011
+ headers: [],
1012
+ props: [],
1013
+ };
1014
+ for (let source of colSource) {
1015
+ source.headers.forEach((h, i) => {
1016
+ if (!columns.headers[i]) {
1017
+ columns.headers[i] = [];
1018
+ }
1019
+ columns.headers[i].push(...h);
762
1020
  });
1021
+ columns.props.push(...source.props);
763
1022
  }
764
- this.updateViewport(type);
1023
+ return Object.assign({ data }, columns);
765
1024
  }
766
- applyNewColumns(columns, disableVirtualX) {
767
- for (let type of columnTypes) {
768
- // clear existing data
769
- this.stores[type].drop();
770
- const items = columns[type];
771
- // for pinned col no need virtual data
772
- const noVirtual = type !== 'rgCol' || disableVirtualX;
773
- // setItemCount
774
- this.stores[type].setStore({ count: items.length });
775
- // setCustomSizes
776
- const newSizes = getColumnSizes(items);
777
- this.stores[type].setDimensionSize(newSizes);
778
- const vpUpdate = {
779
- // this triggers drop on realCount change
780
- realCount: items.length,
781
- };
782
- // Virtualization will get disabled
783
- if (noVirtual) {
784
- vpUpdate.virtualSize = this.stores[type].getCurrentState().realSize;
1025
+ async getColPerSource(t) {
1026
+ const store = await this.revogrid.getColumnStore(t);
1027
+ const source = store.get('source');
1028
+ const virtualIndexes = store.get('items');
1029
+ const depth = store.get('groupingDepth');
1030
+ const groups = store.get('groups');
1031
+ const colNames = [];
1032
+ const colProps = [];
1033
+ const visibleItems = virtualIndexes.reduce((r, v, virtualIndex) => {
1034
+ const prop = source[v].prop;
1035
+ colNames.push(source[v].name || '');
1036
+ colProps.push(prop);
1037
+ r[prop] = virtualIndex;
1038
+ return r;
1039
+ }, {});
1040
+ const rows = this.getGroupHeaders(depth, groups, virtualIndexes, visibleItems);
1041
+ rows.push(colNames);
1042
+ return {
1043
+ headers: rows,
1044
+ props: colProps,
1045
+ };
1046
+ }
1047
+ getGroupHeaders(depth, groups, items, visibleItems) {
1048
+ const rows = [];
1049
+ const template = fill_1(new Array(items.length), '');
1050
+ for (let d = 0; d < depth; d++) {
1051
+ const rgRow = [...template];
1052
+ rows.push(rgRow);
1053
+ if (!groups[d]) {
1054
+ continue;
785
1055
  }
786
- this.viewports.stores[type].setViewport(vpUpdate);
787
- this.setViewPortCoordinate({
788
- coordinate: this.viewports.stores[type].lastCoordinate,
789
- type,
1056
+ const levelGroups = groups[d];
1057
+ // add names of groups
1058
+ levelGroups.forEach((group) => {
1059
+ const minIndex = this.findGroupStartIndex(group.ids, visibleItems);
1060
+ if (typeof minIndex === 'number') {
1061
+ rgRow[minIndex] = group.name;
1062
+ }
790
1063
  });
791
1064
  }
1065
+ return rows;
792
1066
  }
793
- getFullSize() {
794
- var _a, _b;
795
- let x = 0;
796
- let y = 0;
797
- for (let type of columnTypes) {
798
- x += ((_a = this.stores[type]) === null || _a === void 0 ? void 0 : _a.store.get('realSize')) || 0;
799
- }
800
- for (let type of rowTypes) {
801
- y += ((_b = this.stores[type]) === null || _b === void 0 ? void 0 : _b.store.get('realSize')) || 0;
802
- }
803
- return { y, x };
1067
+ findGroupStartIndex(ids, visibleItems) {
1068
+ let min;
1069
+ ids.forEach(id => {
1070
+ const current = visibleItems[id];
1071
+ if (typeof current === 'number') {
1072
+ if (typeof min !== 'number' || min > current) {
1073
+ min = current;
1074
+ }
1075
+ }
1076
+ });
1077
+ return min;
804
1078
  }
805
- updateViewport(type, force = false) {
806
- this.setViewPortCoordinate({
807
- coordinate: this.viewports.stores[type].lastCoordinate,
808
- type,
809
- force,
1079
+ async getSource() {
1080
+ const data = [];
1081
+ const promisesData = [];
1082
+ rowTypes.forEach(t => {
1083
+ const dataPart = [];
1084
+ data.push(dataPart);
1085
+ const promise = this.revogrid.getVisibleSource(t).then((d) => dataPart.push(...d));
1086
+ promisesData.push(promise);
810
1087
  });
1088
+ await Promise.all(promisesData);
1089
+ return data.reduce((r, v) => {
1090
+ r.push(...v);
1091
+ return r;
1092
+ }, []);
811
1093
  }
812
- setViewPortCoordinate({ coordinate, type, force = false, }) {
813
- const dimension = this.stores[type].getCurrentState();
814
- this.viewports.stores[type].setViewPortCoordinate(coordinate, dimension, force);
1094
+ // get correct class for future multiple types support
1095
+ formatter(type, options = {}) {
1096
+ switch (type) {
1097
+ case ExportTypes.csv:
1098
+ return new ExportCsv(options);
1099
+ default:
1100
+ throw new Error('Unknown format');
1101
+ }
815
1102
  }
816
- getViewPortPos(e) {
817
- const dimension = this.stores[e.dimension].getCurrentState();
818
- const item = getItemByIndex(dimension, e.coordinate);
819
- return item.start;
1103
+ }
1104
+
1105
+ const eq = (value, extra) => {
1106
+ if (typeof value === 'undefined' || (value === null && !extra)) {
1107
+ return true;
820
1108
  }
821
- setSettings(data, dimensionType) {
822
- let stores = [];
823
- switch (dimensionType) {
824
- case 'rgCol':
825
- stores = columnTypes;
826
- break;
827
- case 'rgRow':
828
- stores = rowTypes;
829
- break;
830
- }
831
- for (let s of stores) {
832
- this.stores[s].setStore(data);
833
- }
1109
+ if (typeof value !== 'string') {
1110
+ value = JSON.stringify(value);
1111
+ }
1112
+ const filterVal = extra === null || extra === void 0 ? void 0 : extra.toString().toLocaleLowerCase();
1113
+ if ((filterVal === null || filterVal === void 0 ? void 0 : filterVal.length) === 0) {
1114
+ return true;
1115
+ }
1116
+ return value.toLocaleLowerCase() === filterVal;
1117
+ };
1118
+ const notEq = (value, extra) => !eq(value, extra);
1119
+ notEq.extra = 'input';
1120
+ eq.extra = 'input';
1121
+
1122
+ const gtThan = function (value, extra) {
1123
+ let conditionValue;
1124
+ if (typeof value === 'number' && typeof extra !== 'undefined' && extra !== null) {
1125
+ conditionValue = parseFloat(extra === null || extra === void 0 ? void 0 : extra.toString());
1126
+ return value > conditionValue;
1127
+ }
1128
+ return false;
1129
+ };
1130
+ gtThan.extra = 'input';
1131
+
1132
+ const gtThanEq = function (value, extra) {
1133
+ return eq(value, extra) || gtThan(value, extra);
1134
+ };
1135
+ gtThanEq.extra = 'input';
1136
+
1137
+ const lt = function (value, extra) {
1138
+ let conditionValue;
1139
+ if (typeof value === 'number' && typeof extra !== 'undefined' && extra !== null) {
1140
+ conditionValue = parseFloat(extra.toString());
1141
+ return value < conditionValue;
1142
+ }
1143
+ else {
1144
+ return false;
1145
+ }
1146
+ };
1147
+ lt.extra = 'input';
1148
+
1149
+ const lsEq = function (value, extra) {
1150
+ return eq(value, extra) || lt(value, extra);
1151
+ };
1152
+ lsEq.extra = 'input';
1153
+
1154
+ const set = (value) => !(value === '' || value === null || value === void 0);
1155
+ const notSet = (value) => !set(value);
1156
+
1157
+ const beginsWith = (value, extra) => {
1158
+ if (!value) {
1159
+ return false;
1160
+ }
1161
+ if (!extra) {
1162
+ return true;
834
1163
  }
835
- }
1164
+ if (typeof value !== 'string') {
1165
+ value = JSON.stringify(value);
1166
+ }
1167
+ if (typeof extra !== 'string') {
1168
+ extra = JSON.stringify(extra);
1169
+ }
1170
+ return value.toLocaleLowerCase().indexOf(extra.toLocaleLowerCase()) === 0;
1171
+ };
1172
+ beginsWith.extra = 'input';
836
1173
 
837
- class ViewportProvider {
838
- constructor() {
839
- this.stores = reduce_1([...rowTypes, ...columnTypes], (sources, k) => {
840
- sources[k] = new ViewportStore(k);
841
- return sources;
842
- }, {});
1174
+ const contains = (value, extra) => {
1175
+ if (!extra) {
1176
+ return true;
843
1177
  }
844
- setViewport(type, data) {
845
- this.stores[type].setViewport(data);
1178
+ if (!value) {
1179
+ return false;
846
1180
  }
847
- }
1181
+ if (extra) {
1182
+ if (typeof value !== 'string') {
1183
+ value = JSON.stringify(value);
1184
+ }
1185
+ return value.toLocaleLowerCase().indexOf(extra.toString().toLowerCase()) > -1;
1186
+ }
1187
+ return true;
1188
+ };
1189
+ const notContains = (value, extra) => {
1190
+ return !contains(value, extra);
1191
+ };
1192
+ notContains.extra = 'input';
1193
+ contains.extra = 'input';
848
1194
 
849
- /**
850
- * Plugin module for revo-grid grid system
851
- * Add support for automatic column resize
852
- */
853
- const LETTER_BLOCK_SIZE = 7;
854
- var ColumnAutoSizeMode;
855
- (function (ColumnAutoSizeMode) {
856
- // increases column width on header click according the largest text value
857
- ColumnAutoSizeMode["headerClickAutosize"] = "headerClickAutoSize";
858
- // increases column width on data set and text edit, decreases performance
859
- ColumnAutoSizeMode["autoSizeOnTextOverlap"] = "autoSizeOnTextOverlap";
860
- // increases and decreases column width based on all items sizes, worst for performance
861
- ColumnAutoSizeMode["autoSizeAll"] = "autoSizeAll";
862
- })(ColumnAutoSizeMode || (ColumnAutoSizeMode = {}));
863
- class AutoSizeColumnPlugin extends BasePlugin {
1195
+ const filterNames = {
1196
+ none: 'None',
1197
+ empty: 'Not set',
1198
+ notEmpty: 'Set',
1199
+ eq: 'Equal',
1200
+ notEq: 'Not equal',
1201
+ begins: 'Begins with',
1202
+ contains: 'Contains',
1203
+ notContains: 'Does not contain',
1204
+ eqN: '=',
1205
+ neqN: '!=',
1206
+ gt: '>',
1207
+ gte: '>=',
1208
+ lt: '<',
1209
+ lte: '<=',
1210
+ };
1211
+ const filterEntities = {
1212
+ none: () => true,
1213
+ empty: notSet,
1214
+ notEmpty: set,
1215
+ eq: eq,
1216
+ notEq: notEq,
1217
+ begins: beginsWith,
1218
+ contains: contains,
1219
+ notContains: notContains,
1220
+ eqN: eq,
1221
+ neqN: notEq,
1222
+ gt: gtThan,
1223
+ gte: gtThanEq,
1224
+ lt: lt,
1225
+ lte: lsEq,
1226
+ };
1227
+ const filterTypes = {
1228
+ string: ['notEmpty', 'empty', 'eq', 'notEq', 'begins', 'contains', 'notContains'],
1229
+ number: ['notEmpty', 'empty', 'eqN', 'neqN', 'gt', 'gte', 'lt', 'lte'],
1230
+ };
1231
+
1232
+ const FILTER_TRIMMED_TYPE = 'filter';
1233
+ const FILTER_CONFIG_CHANGED_EVENT = 'filterconfigchanged';
1234
+ class FilterPlugin extends BasePlugin {
864
1235
  constructor(revogrid, providers, config) {
1236
+ var _a;
865
1237
  super(revogrid, providers);
866
- this.providers = providers;
867
- this.config = config;
868
- this.autoSizeColumns = null;
869
- /** for edge case when no columns defined before data */
870
- this.dataResolve = null;
871
- this.dataReject = null;
872
- this.letterBlockSize = (config === null || config === void 0 ? void 0 : config.letterBlockSize) || LETTER_BLOCK_SIZE;
873
- // create test container to check text width
874
- if (config === null || config === void 0 ? void 0 : config.preciseSize) {
875
- this.precsizeCalculationArea = this.initiatePresizeElement();
876
- revogrid.appendChild(this.precsizeCalculationArea);
1238
+ this.revogrid = revogrid;
1239
+ this.filterCollection = {};
1240
+ this.multiFilterItems = {};
1241
+ this.possibleFilters = Object.assign({}, filterTypes);
1242
+ this.possibleFilterNames = Object.assign({}, filterNames);
1243
+ this.possibleFilterEntities = Object.assign({}, filterEntities);
1244
+ this.filterProp = FILTER_PROP;
1245
+ if (config) {
1246
+ this.initConfig(config);
877
1247
  }
878
- const aftersourceset = ({ detail: { source }, }) => {
879
- this.setSource(source);
880
- };
881
- const afteredit = ({ detail }) => {
882
- this.afteredit(detail);
883
- };
884
- const afterEditAll = ({ detail }) => {
885
- this.afterEditAll(detail);
886
- };
887
- const beforecolumnsset = ({ detail: { columns }, }) => {
888
- this.columnSet(columns);
889
- };
890
- const headerDblClick = ({ detail }) => {
891
- const type = getColumnType(detail.column);
892
- const size = this.getColumnSize(detail.index, type);
893
- if (size) {
894
- this.providers.dimension.setCustomSizes(type, {
895
- [detail.index]: size,
896
- }, true);
1248
+ const headerclick = (e) => this.headerclick(e);
1249
+ const aftersourceset = async () => {
1250
+ const filterCollectionProps = Object.keys(this.filterCollection);
1251
+ if (filterCollectionProps.length > 0) {
1252
+ // handle old way of filtering by reworking FilterCollection to new MultiFilterItem
1253
+ filterCollectionProps.forEach((prop, index) => {
1254
+ if (!this.multiFilterItems[prop]) {
1255
+ this.multiFilterItems[prop] = [
1256
+ {
1257
+ id: index,
1258
+ type: this.filterCollection[prop].type,
1259
+ value: this.filterCollection[prop].value,
1260
+ relation: 'and',
1261
+ },
1262
+ ];
1263
+ }
1264
+ });
897
1265
  }
1266
+ await this.runFiltering();
898
1267
  };
899
- this.addEventListener('beforecolumnsset', beforecolumnsset);
900
- switch (config === null || config === void 0 ? void 0 : config.mode) {
901
- case ColumnAutoSizeMode.autoSizeOnTextOverlap:
902
- this.addEventListener('aftersourceset', aftersourceset);
903
- this.addEventListener('afteredit', afteredit);
904
- break;
905
- case ColumnAutoSizeMode.autoSizeAll:
906
- this.addEventListener('aftersourceset', aftersourceset);
907
- this.addEventListener('afteredit', afterEditAll);
908
- break;
909
- default:
910
- this.addEventListener('headerdblclick', headerDblClick);
911
- break;
912
- }
1268
+ this.addEventListener('headerclick', headerclick);
1269
+ this.addEventListener(FILTER_CONFIG_CHANGED_EVENT, ({ detail }) => {
1270
+ if (!detail) {
1271
+ this.clearFiltering();
1272
+ return;
1273
+ }
1274
+ if (typeof detail === 'object') {
1275
+ this.initConfig(detail);
1276
+ }
1277
+ aftersourceset();
1278
+ });
1279
+ this.addEventListener('aftersourceset', aftersourceset);
1280
+ this.addEventListener('filter', ({ detail }) => this.onFilterChange(detail));
1281
+ const existingNodes = this.revogrid.registerVNode.filter((n) => n.$tag$ !== 'revogr-filter-panel');
1282
+ this.revogrid.registerVNode = [
1283
+ ...existingNodes,
1284
+ h("revogr-filter-panel", { filterItems: this.multiFilterItems, filterNames: this.possibleFilterNames, filterEntities: this.possibleFilterEntities, 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), disableDynamicFiltering: config === null || config === void 0 ? void 0 : config.disableDynamicFiltering, ref: e => (this.pop = e) }),
1285
+ ];
913
1286
  }
914
- async setSource(source) {
915
- let autoSize = this.autoSizeColumns;
916
- if (this.dataReject) {
917
- this.dataReject();
918
- this.clearPromise();
1287
+ initConfig(config) {
1288
+ if (config.multiFilterItems) {
1289
+ this.multiFilterItems = Object.assign({}, config.multiFilterItems);
919
1290
  }
920
- /** If data set first and no column provided await until get one */
921
- if (!autoSize) {
922
- const request = new Promise((resolve, reject) => {
923
- this.dataResolve = resolve;
924
- this.dataReject = reject;
925
- });
926
- try {
927
- autoSize = await request;
1291
+ if (config.customFilters) {
1292
+ for (let cType in config.customFilters) {
1293
+ const cFilter = config.customFilters[cType];
1294
+ if (!this.possibleFilters[cFilter.columnFilterType]) {
1295
+ this.possibleFilters[cFilter.columnFilterType] = [];
1296
+ }
1297
+ this.possibleFilters[cFilter.columnFilterType].push(cType);
1298
+ this.possibleFilterEntities[cType] = cFilter.func;
1299
+ this.possibleFilterNames[cType] = cFilter.name;
928
1300
  }
929
- catch (e) {
930
- return;
1301
+ }
1302
+ if (config.filterProp) {
1303
+ this.filterProp = config.filterProp;
1304
+ }
1305
+ /**
1306
+ * which filters has to be included/excluded
1307
+ * convinient way to exclude system filters
1308
+ */
1309
+ const cfgInlcude = config.include;
1310
+ if (cfgInlcude) {
1311
+ const filters = {};
1312
+ for (let t in this.possibleFilters) {
1313
+ // validate filters, if appropriate function present
1314
+ const newTypes = this.possibleFilters[t].filter(f => cfgInlcude.indexOf(f) > -1);
1315
+ if (newTypes.length) {
1316
+ filters[t] = newTypes;
1317
+ }
1318
+ }
1319
+ // if any valid filters provided show them
1320
+ if (Object.keys(filters).length > 0) {
1321
+ this.possibleFilters = filters;
1322
+ }
1323
+ }
1324
+ if (config.collection) {
1325
+ this.filterCollection = reduce_1(config.collection, (result, item, prop) => {
1326
+ if (this.possibleFilterEntities[item.type]) {
1327
+ result[prop] = item;
1328
+ }
1329
+ else {
1330
+ console.warn(`${item.type} type is not found.`);
1331
+ }
1332
+ return result;
1333
+ }, {});
1334
+ }
1335
+ if (config.localization) {
1336
+ if (config.localization.filterNames) {
1337
+ Object.entries(config.localization.filterNames).forEach(([k, v]) => {
1338
+ if (this.possibleFilterNames[k] != void 0) {
1339
+ this.possibleFilterNames[k] = v;
1340
+ }
1341
+ });
931
1342
  }
932
1343
  }
933
- // calculate sizes
934
- each(autoSize, (_v, type) => {
935
- const sizes = {};
936
- each(autoSize[type], rgCol => {
937
- // calculate size
938
- rgCol.size = sizes[rgCol.index] = source.reduce((prev, rgRow) => Math.max(prev, this.getLength(rgRow[rgCol.prop])), this.getLength(rgCol.name || ''));
939
- });
940
- this.providers.dimension.setCustomSizes(type, sizes, true);
941
- });
942
1344
  }
943
- getLength(len) {
944
- var _a;
945
- const padding = 15;
946
- if (!len) {
947
- return 0;
1345
+ async headerclick(e) {
1346
+ var _a, _b, _c;
1347
+ const el = (_a = e.detail.originalEvent) === null || _a === void 0 ? void 0 : _a.target;
1348
+ if (!isFilterBtn(el)) {
1349
+ return;
948
1350
  }
949
- try {
950
- const str = len.toString();
951
- /**if exact calculation required proxy with html element, slow operation */
952
- if ((_a = this.config) === null || _a === void 0 ? void 0 : _a.preciseSize) {
953
- this.precsizeCalculationArea.innerText = str;
954
- return this.precsizeCalculationArea.scrollWidth + padding * 2;
955
- }
956
- return str.length * this.letterBlockSize + padding * 2;
1351
+ e.preventDefault();
1352
+ // close if same
1353
+ const changes = await ((_b = this.pop) === null || _b === void 0 ? void 0 : _b.getChanges());
1354
+ if (changes && (changes === null || changes === void 0 ? void 0 : changes.prop) === e.detail.prop) {
1355
+ (_c = this.pop) === null || _c === void 0 ? void 0 : _c.show();
1356
+ return;
957
1357
  }
958
- catch (e) {
959
- return 0;
1358
+ if (!this.pop) {
1359
+ return;
960
1360
  }
1361
+ // filter button clicked, open filter dialog
1362
+ const gridPos = this.revogrid.getBoundingClientRect();
1363
+ const buttonPos = el.getBoundingClientRect();
1364
+ const prop = e.detail.prop;
1365
+ this.pop.filterTypes = this.getColumnFilter(e.detail.filter);
1366
+ this.pop.show(Object.assign(Object.assign({}, this.filterCollection[prop]), { x: buttonPos.x - gridPos.x, y: buttonPos.y - gridPos.y + buttonPos.height, autoCorrect: true, prop }));
961
1367
  }
962
- afteredit(e) {
963
- let data;
964
- if (this.isRangeEdit(e)) {
965
- data = e.data;
1368
+ getColumnFilter(type) {
1369
+ let filterType = 'string';
1370
+ if (!type) {
1371
+ return { [filterType]: this.possibleFilters[filterType] };
966
1372
  }
967
- else {
968
- data = { 0: { [e.prop]: e.val } };
1373
+ // if custom column filter
1374
+ if (this.isValidType(type)) {
1375
+ filterType = type;
1376
+ // if multiple filters applied
969
1377
  }
970
- each(this.autoSizeColumns, (columns, type) => {
971
- const sizes = {};
972
- each(columns, rgCol => {
973
- var _a;
974
- // calculate size
975
- const size = reduce_1(data, (prev, rgRow) => {
976
- if (typeof rgRow[rgCol.prop] === 'undefined') {
977
- return prev;
978
- }
979
- return Math.max(prev || 0, this.getLength(rgRow[rgCol.prop]));
980
- }, undefined);
981
- if (size && ((_a = rgCol.size) !== null && _a !== void 0 ? _a : 0) < size) {
982
- rgCol.size = sizes[rgCol.index] = size;
1378
+ else if (typeof type === 'object' && type.length) {
1379
+ return type.reduce((r, multiType) => {
1380
+ if (this.isValidType(multiType)) {
1381
+ r[multiType] = this.possibleFilters[multiType];
983
1382
  }
984
- });
985
- this.providers.dimension.setCustomSizes(type, sizes, true);
986
- });
1383
+ return r;
1384
+ }, {});
1385
+ }
1386
+ return { [filterType]: this.possibleFilters[filterType] };
987
1387
  }
988
- afterEditAll(e) {
989
- const props = {};
990
- if (this.isRangeEdit(e)) {
991
- each(e.data, r => each(r, (_v, p) => (props[p] = true)));
1388
+ isValidType(type) {
1389
+ return !!(typeof type === 'string' && this.possibleFilters[type]);
1390
+ }
1391
+ // called on internal component change
1392
+ async onFilterChange(filterItems) {
1393
+ this.multiFilterItems = filterItems;
1394
+ this.runFiltering();
1395
+ }
1396
+ /**
1397
+ * Triggers grid filtering
1398
+ */
1399
+ async doFiltering(collection, items, columns, filterItems) {
1400
+ const columnsToUpdate = [];
1401
+ columns.forEach(rgCol => {
1402
+ const column = Object.assign({}, rgCol);
1403
+ const hasFilter = filterItems[column.prop];
1404
+ if (column[this.filterProp] && !hasFilter) {
1405
+ delete column[this.filterProp];
1406
+ columnsToUpdate.push(column);
1407
+ }
1408
+ if (!column[this.filterProp] && hasFilter) {
1409
+ columnsToUpdate.push(column);
1410
+ column[this.filterProp] = true;
1411
+ }
1412
+ });
1413
+ const itemsToFilter = this.getRowFilter(items, filterItems);
1414
+ // check is filter event prevented
1415
+ const { defaultPrevented, detail } = this.emit('beforefiltertrimmed', {
1416
+ collection,
1417
+ itemsToFilter,
1418
+ source: items,
1419
+ filterItems,
1420
+ });
1421
+ if (defaultPrevented) {
1422
+ return;
992
1423
  }
993
- else {
994
- props[e.prop] = true;
1424
+ // check is trimmed event prevented
1425
+ const isAddedEvent = await this.revogrid.addTrimmed(detail.itemsToFilter, FILTER_TRIMMED_TYPE);
1426
+ if (isAddedEvent.defaultPrevented) {
1427
+ return;
995
1428
  }
996
- each(this.autoSizeColumns, (columns, type) => {
997
- const sizes = {};
998
- each(columns, rgCol => {
999
- if (props[rgCol.prop]) {
1000
- const size = this.getColumnSize(rgCol.index, type);
1001
- if (size) {
1002
- sizes[rgCol.index] = size;
1003
- }
1004
- }
1005
- });
1006
- this.providers.dimension.setCustomSizes(type, sizes, true);
1007
- });
1429
+ // applies the hasFilter to the columns to show filter icon
1430
+ await this.revogrid.updateColumns(columnsToUpdate);
1431
+ this.emit('afterfilterapply');
1008
1432
  }
1009
- getColumnSize(index, type) {
1010
- var _a, _b;
1011
- const rgCol = (_b = (_a = this.autoSizeColumns) === null || _a === void 0 ? void 0 : _a[type]) === null || _b === void 0 ? void 0 : _b[index];
1012
- if (!rgCol) {
1013
- return 0;
1433
+ async clearFiltering() {
1434
+ this.multiFilterItems = {};
1435
+ await this.runFiltering();
1436
+ }
1437
+ async runFiltering() {
1438
+ const collection = {};
1439
+ // handle old filterCollection to return the first filter only (if any) from multiFilterItems
1440
+ const filterProps = Object.keys(this.multiFilterItems);
1441
+ for (const prop of filterProps) {
1442
+ // check if we have any filter for a column
1443
+ if (this.multiFilterItems[prop].length > 0) {
1444
+ const firstFilterItem = this.multiFilterItems[prop][0];
1445
+ collection[prop] = {
1446
+ filter: filterEntities[firstFilterItem.type],
1447
+ type: firstFilterItem.type,
1448
+ value: firstFilterItem.value,
1449
+ };
1450
+ }
1014
1451
  }
1015
- return reduce_1(this.providers.data.stores, (r, s) => {
1016
- const perStore = reduce_1(s.store.get('items'), (prev, _row, i) => {
1017
- const item = getSourceItem(s.store, i);
1018
- return Math.max(prev || 0, this.getLength(item === null || item === void 0 ? void 0 : item[rgCol.prop]));
1019
- }, 0);
1020
- return Math.max(r, perStore);
1021
- }, rgCol.size || 0);
1452
+ this.filterCollection = collection;
1453
+ const { source, columns } = await this.getData();
1454
+ const { defaultPrevented, detail } = this.emit('beforefilterapply', {
1455
+ collection: this.filterCollection,
1456
+ source,
1457
+ columns,
1458
+ filterItems: this.multiFilterItems,
1459
+ });
1460
+ if (defaultPrevented) {
1461
+ return;
1462
+ }
1463
+ this.doFiltering(detail.collection, detail.source, detail.columns, detail.filterItems);
1022
1464
  }
1023
- columnSet(columns) {
1024
- var _a;
1025
- for (let t of columnTypes) {
1026
- const type = t;
1027
- const cols = columns[type];
1028
- for (let i in cols) {
1029
- if (cols[i].autoSize || ((_a = this.config) === null || _a === void 0 ? void 0 : _a.allColumns)) {
1030
- if (!this.autoSizeColumns) {
1031
- this.autoSizeColumns = {};
1465
+ async getData() {
1466
+ return {
1467
+ source: await this.revogrid.getSource(),
1468
+ columns: await this.revogrid.getColumns(),
1469
+ };
1470
+ }
1471
+ getRowFilter(rows, filterItems) {
1472
+ const propKeys = Object.keys(filterItems);
1473
+ const trimmed = {};
1474
+ let propFilterSatisfiedCount = 0;
1475
+ let lastFilterResults = [];
1476
+ // each rows
1477
+ rows.forEach((model, rowIndex) => {
1478
+ // working on all props
1479
+ for (const prop of propKeys) {
1480
+ const propFilters = filterItems[prop];
1481
+ propFilterSatisfiedCount = 0;
1482
+ lastFilterResults = [];
1483
+ // testing each filter for a prop
1484
+ for (const [filterIndex, filterData] of propFilters.entries()) {
1485
+ // the filter LogicFunction based on the type
1486
+ const filter = this.possibleFilterEntities[filterData.type];
1487
+ // THE MAGIC OF FILTERING IS HERE
1488
+ if (filterData.relation === 'or') {
1489
+ lastFilterResults = [];
1490
+ if (filter(model[prop], filterData.value)) {
1491
+ continue;
1492
+ }
1493
+ propFilterSatisfiedCount++;
1032
1494
  }
1033
- if (!this.autoSizeColumns[type]) {
1034
- this.autoSizeColumns[type] = {};
1495
+ else {
1496
+ // 'and' relation will need to know the next filter
1497
+ // so we save this current filter to include it in the next filter
1498
+ lastFilterResults.push(!filter(model[prop], filterData.value));
1499
+ // check first if we have a filter on the next index to pair it with this current filter
1500
+ const nextFilterData = propFilters[filterIndex + 1];
1501
+ // stop the sequence if there is no next filter or if the next filter is not an 'and' relation
1502
+ if (!nextFilterData || nextFilterData.relation !== 'and') {
1503
+ // let's just continue since for sure propFilterSatisfiedCount cannot be satisfied
1504
+ if (lastFilterResults.indexOf(true) === -1) {
1505
+ lastFilterResults = [];
1506
+ continue;
1507
+ }
1508
+ // we need to add all of the lastFilterResults since we need to satisfy all
1509
+ propFilterSatisfiedCount += lastFilterResults.length;
1510
+ lastFilterResults = [];
1511
+ }
1035
1512
  }
1036
- this.autoSizeColumns[type][i] = Object.assign(Object.assign({}, cols[i]), { index: parseInt(i, 10) });
1037
- }
1513
+ } // end of propFilters forEach
1514
+ // add to the list of removed/trimmed rows of filter condition is satisfied
1515
+ if (propFilterSatisfiedCount === propFilters.length)
1516
+ trimmed[rowIndex] = true;
1517
+ } // end of for-of propKeys
1518
+ });
1519
+ return trimmed;
1520
+ }
1521
+ }
1522
+
1523
+ // provide collapse data
1524
+ function doCollapse(pIndex, source) {
1525
+ const model = source[pIndex];
1526
+ const collapseValue = model[PSEUDO_GROUP_ITEM_VALUE];
1527
+ const trimmed = {};
1528
+ let i = pIndex + 1;
1529
+ const total = source.length;
1530
+ while (i < total) {
1531
+ const currentModel = source[i];
1532
+ if (isGrouping(currentModel)) {
1533
+ const currentValue = currentModel[PSEUDO_GROUP_ITEM_VALUE];
1534
+ if (!currentValue.length || !currentValue.startsWith(collapseValue + ',')) {
1535
+ break;
1038
1536
  }
1537
+ currentModel[GROUP_EXPANDED] = false;
1039
1538
  }
1040
- if (this.dataResolve) {
1041
- this.dataResolve(this.autoSizeColumns || {});
1042
- this.clearPromise();
1043
- }
1044
- }
1045
- clearPromise() {
1046
- this.dataResolve = null;
1047
- this.dataReject = null;
1539
+ trimmed[i++] = true;
1048
1540
  }
1049
- isRangeEdit(e) {
1050
- return !!e.data;
1541
+ model[GROUP_EXPANDED] = false;
1542
+ return { trimmed };
1543
+ }
1544
+ /**
1545
+ *
1546
+ * @param pIndex - physical index
1547
+ * @param vIndex - virtual index, need to update item collection
1548
+ * @param source - data source
1549
+ * @param rowItemsIndexes - rgRow indexes
1550
+ */
1551
+ function doExpand(vIndex, source, rowItemsIndexes) {
1552
+ const physicalIndex = rowItemsIndexes[vIndex];
1553
+ const model = source[physicalIndex];
1554
+ const currentGroup = getParsedGroup(model[PSEUDO_GROUP_ITEM_ID]);
1555
+ const trimmed = {};
1556
+ // no group found
1557
+ if (!currentGroup) {
1558
+ return { trimmed };
1051
1559
  }
1052
- initiatePresizeElement() {
1053
- var _a;
1054
- const styleForFontTest = {
1055
- position: 'absolute',
1056
- fontSize: '14px',
1057
- height: '0',
1058
- width: '0',
1059
- whiteSpace: 'nowrap',
1060
- top: '0',
1061
- overflowX: 'scroll',
1062
- };
1063
- const el = document.createElement('div');
1064
- for (let s in styleForFontTest) {
1065
- el.style[s] = (_a = styleForFontTest[s]) !== null && _a !== void 0 ? _a : '';
1560
+ const groupItems = [];
1561
+ model[GROUP_EXPANDED] = true;
1562
+ let i = physicalIndex + 1;
1563
+ const total = source.length;
1564
+ let groupLevelOnly = 0;
1565
+ // go through all rows
1566
+ while (i < total) {
1567
+ const currentModel = source[i];
1568
+ const isGroup = isGrouping(currentModel);
1569
+ // group found
1570
+ if (isGroup) {
1571
+ if (!isSameGroup(currentGroup, model, currentModel)) {
1572
+ break;
1573
+ }
1574
+ else if (!groupLevelOnly) {
1575
+ // if get group first it's group only level
1576
+ groupLevelOnly = currentModel[GROUP_DEPTH];
1577
+ }
1066
1578
  }
1067
- el.classList.add('revo-test-container');
1068
- return el;
1579
+ // level 0 or same depth
1580
+ if (!groupLevelOnly || (isGroup && groupLevelOnly === currentModel[GROUP_DEPTH])) {
1581
+ trimmed[i] = false;
1582
+ groupItems.push(i);
1583
+ }
1584
+ i++;
1069
1585
  }
1070
- destroy() {
1071
- var _a;
1072
- super.destroy();
1073
- (_a = this.precsizeCalculationArea) === null || _a === void 0 ? void 0 : _a.remove();
1586
+ const result = {
1587
+ trimmed,
1588
+ };
1589
+ if (groupItems.length) {
1590
+ const items = [...rowItemsIndexes];
1591
+ items.splice(vIndex + 1, 0, ...groupItems);
1592
+ result.items = items;
1074
1593
  }
1594
+ return result;
1075
1595
  }
1076
1596
 
1077
- const eq = (value, extra) => {
1078
- if (typeof value === 'undefined' || (value === null && !extra)) {
1079
- return true;
1080
- }
1081
- if (typeof value !== 'string') {
1082
- value = JSON.stringify(value);
1083
- }
1084
- const filterVal = extra === null || extra === void 0 ? void 0 : extra.toString().toLocaleLowerCase();
1085
- if ((filterVal === null || filterVal === void 0 ? void 0 : filterVal.length) === 0) {
1086
- return true;
1087
- }
1088
- return value.toLocaleLowerCase() === filterVal;
1089
- };
1090
- const notEq = (value, extra) => !eq(value, extra);
1091
- notEq.extra = 'input';
1092
- eq.extra = 'input';
1093
-
1094
- const gtThan = function (value, extra) {
1095
- let conditionValue;
1096
- if (typeof value === 'number' && typeof extra !== 'undefined' && extra !== null) {
1097
- conditionValue = parseFloat(extra === null || extra === void 0 ? void 0 : extra.toString());
1098
- return value > conditionValue;
1099
- }
1100
- return false;
1101
- };
1102
- gtThan.extra = 'input';
1103
-
1104
- const gtThanEq = function (value, extra) {
1105
- return eq(value, extra) || gtThan(value, extra);
1106
- };
1107
- gtThanEq.extra = 'input';
1108
-
1109
- const lt = function (value, extra) {
1110
- let conditionValue;
1111
- if (typeof value === 'number' && typeof extra !== 'undefined' && extra !== null) {
1112
- conditionValue = parseFloat(extra.toString());
1113
- return value < conditionValue;
1114
- }
1115
- else {
1116
- return false;
1117
- }
1118
- };
1119
- lt.extra = 'input';
1120
-
1121
- const lsEq = function (value, extra) {
1122
- return eq(value, extra) || lt(value, extra);
1123
- };
1124
- lsEq.extra = 'input';
1125
-
1126
- const set = (value) => !(value === '' || value === null || value === void 0);
1127
- const notSet = (value) => !set(value);
1128
-
1129
- const beginsWith = (value, extra) => {
1130
- if (!value) {
1131
- return false;
1132
- }
1133
- if (!extra) {
1134
- return true;
1135
- }
1136
- if (typeof value !== 'string') {
1137
- value = JSON.stringify(value);
1138
- }
1139
- if (typeof extra !== 'string') {
1140
- extra = JSON.stringify(extra);
1141
- }
1142
- return value.toLocaleLowerCase().indexOf(extra.toLocaleLowerCase()) === 0;
1143
- };
1144
- beginsWith.extra = 'input';
1145
-
1146
- const contains = (value, extra) => {
1147
- if (!extra) {
1148
- return true;
1149
- }
1150
- if (!value) {
1151
- return false;
1152
- }
1153
- if (extra) {
1154
- if (typeof value !== 'string') {
1155
- value = JSON.stringify(value);
1597
+ const TRIMMED_GROUPING = 'grouping';
1598
+ /**
1599
+ * Prepare trimming updated indexes for grouping
1600
+ * @param initiallyTrimed
1601
+ * @param firstLevelMap
1602
+ * @param secondLevelMap
1603
+ */
1604
+ function processDoubleConversionTrimmed(initiallyTrimed, firstLevelMap, secondLevelMap) {
1605
+ const trimemedOptionsToUpgrade = {};
1606
+ /**
1607
+ * go through all groups except grouping
1608
+ */
1609
+ for (let type in initiallyTrimed) {
1610
+ if (type === TRIMMED_GROUPING) {
1611
+ continue;
1612
+ }
1613
+ const items = initiallyTrimed[type];
1614
+ const newItems = {};
1615
+ for (let initialIndex in items) {
1616
+ /**
1617
+ * if item exists we find it in collection
1618
+ * we support 2 level of conversions
1619
+ */
1620
+ let newConversionIndex = firstLevelMap[initialIndex];
1621
+ if (secondLevelMap) {
1622
+ newConversionIndex = secondLevelMap[newConversionIndex];
1623
+ }
1624
+ /**
1625
+ * if item was trimmed previously
1626
+ * trimming makes sense to apply
1627
+ */
1628
+ if (items[initialIndex]) {
1629
+ newItems[newConversionIndex] = true;
1630
+ /**
1631
+ * If changes present apply changes to new source
1632
+ */
1633
+ if (newConversionIndex !== parseInt(initialIndex, 10)) {
1634
+ trimemedOptionsToUpgrade[type] = newItems;
1635
+ }
1636
+ }
1156
1637
  }
1157
- return value.toLocaleLowerCase().indexOf(extra.toString().toLowerCase()) > -1;
1158
1638
  }
1159
- return true;
1160
- };
1161
- const notContains = (value, extra) => {
1162
- return !contains(value, extra);
1163
- };
1164
- notContains.extra = 'input';
1165
- contains.extra = 'input';
1166
-
1167
- const filterNames = {
1168
- none: 'None',
1169
- empty: 'Not set',
1170
- notEmpty: 'Set',
1171
- eq: 'Equal',
1172
- notEq: 'Not equal',
1173
- begins: 'Begins with',
1174
- contains: 'Contains',
1175
- notContains: 'Does not contain',
1176
- eqN: '=',
1177
- neqN: '!=',
1178
- gt: '>',
1179
- gte: '>=',
1180
- lt: '<',
1181
- lte: '<=',
1182
- };
1183
- const filterEntities = {
1184
- none: () => true,
1185
- empty: notSet,
1186
- notEmpty: set,
1187
- eq: eq,
1188
- notEq: notEq,
1189
- begins: beginsWith,
1190
- contains: contains,
1191
- notContains: notContains,
1192
- eqN: eq,
1193
- neqN: notEq,
1194
- gt: gtThan,
1195
- gte: gtThanEq,
1196
- lt: lt,
1197
- lte: lsEq,
1198
- };
1199
- const filterTypes = {
1200
- string: ['notEmpty', 'empty', 'eq', 'notEq', 'begins', 'contains', 'notContains'],
1201
- number: ['notEmpty', 'empty', 'eqN', 'neqN', 'gt', 'gte', 'lt', 'lte'],
1202
- };
1639
+ return trimemedOptionsToUpgrade;
1640
+ }
1203
1641
 
1204
- const FILTER_TRIMMED_TYPE = 'filter';
1205
- const FILTER_CONFIG_CHANGED_EVENT = 'filterconfigchanged';
1206
- class FilterPlugin extends BasePlugin {
1207
- constructor(revogrid, providers, config) {
1208
- var _a;
1642
+ class GroupingRowPlugin extends BasePlugin {
1643
+ get hasProps() {
1644
+ var _a, _b, _c;
1645
+ return ((_a = this.options) === null || _a === void 0 ? void 0 : _a.props) && ((_c = (_b = this.options) === null || _b === void 0 ? void 0 : _b.props) === null || _c === void 0 ? void 0 : _c.length);
1646
+ }
1647
+ get store() {
1648
+ return this.providers.data.stores[GROUPING_ROW_TYPE].store;
1649
+ }
1650
+ // proxy for items get
1651
+ get rowItems() {
1652
+ return this.store.get('items');
1653
+ }
1654
+ get trimmed() {
1655
+ return this.store.get('trimmed');
1656
+ }
1657
+ constructor(revogrid, providers) {
1209
1658
  super(revogrid, providers);
1210
1659
  this.revogrid = revogrid;
1211
- this.filterCollection = {};
1212
- this.multiFilterItems = {};
1213
- this.possibleFilters = Object.assign({}, filterTypes);
1214
- this.possibleFilterNames = Object.assign({}, filterNames);
1215
- this.possibleFilterEntities = Object.assign({}, filterEntities);
1216
- this.filterProp = FILTER_PROP;
1217
- if (config) {
1218
- this.initConfig(config);
1660
+ this.providers = providers;
1661
+ }
1662
+ // befoce cell focus
1663
+ onFocus(e) {
1664
+ if (isGrouping(e.detail.model)) {
1665
+ e.preventDefault();
1219
1666
  }
1220
- const headerclick = (e) => this.headerclick(e);
1221
- const aftersourceset = async () => {
1222
- const filterCollectionProps = Object.keys(this.filterCollection);
1223
- if (filterCollectionProps.length > 0) {
1224
- // handle old way of filtering by reworking FilterCollection to new MultiFilterItem
1225
- filterCollectionProps.forEach((prop, index) => {
1226
- if (!this.multiFilterItems[prop]) {
1227
- this.multiFilterItems[prop] = [
1228
- {
1229
- id: index,
1230
- type: this.filterCollection[prop].type,
1231
- value: this.filterCollection[prop].value,
1232
- relation: 'and',
1233
- },
1234
- ];
1235
- }
1236
- });
1667
+ }
1668
+ // expand event triggered
1669
+ onExpand({ virtualIndex }) {
1670
+ const { source } = this.getSource();
1671
+ let newTrimmed = this.trimmed[TRIMMED_GROUPING];
1672
+ let i = getPhysical(this.store, virtualIndex);
1673
+ const model = source[i];
1674
+ const prevExpanded = model[GROUP_EXPANDED];
1675
+ if (!prevExpanded) {
1676
+ const { trimmed, items } = doExpand(virtualIndex, source, this.rowItems);
1677
+ newTrimmed = Object.assign(Object.assign({}, newTrimmed), trimmed);
1678
+ if (items) {
1679
+ setItems(this.store, items);
1237
1680
  }
1238
- await this.runFiltering();
1239
- };
1240
- this.addEventListener('headerclick', headerclick);
1241
- this.addEventListener(FILTER_CONFIG_CHANGED_EVENT, ({ detail }) => {
1242
- if (!detail) {
1243
- this.clearFiltering();
1244
- return;
1681
+ }
1682
+ else {
1683
+ const { trimmed } = doCollapse(i, source);
1684
+ newTrimmed = Object.assign(Object.assign({}, newTrimmed), trimmed);
1685
+ this.revogrid.clearFocus();
1686
+ }
1687
+ this.store.set('source', source);
1688
+ this.revogrid.addTrimmed(newTrimmed, TRIMMED_GROUPING);
1689
+ }
1690
+ // get source based on proxy item collection to preserve rgRow order
1691
+ getSource(withoutGrouping = false) {
1692
+ const source = this.store.get('source');
1693
+ const items = this.store.get('proxyItems');
1694
+ let index = 0;
1695
+ // order important here, expected parent is first, then others
1696
+ return items.reduce((result, i) => {
1697
+ const model = source[i];
1698
+ if (!withoutGrouping) {
1699
+ result.source.push(model);
1700
+ return result;
1245
1701
  }
1246
- if (typeof detail === 'object') {
1247
- this.initConfig(detail);
1702
+ // grouping filter
1703
+ if (isGrouping(model)) {
1704
+ if (model[GROUP_EXPANDED]) {
1705
+ result.prevExpanded[model[PSEUDO_GROUP_ITEM_VALUE]] = true;
1706
+ }
1248
1707
  }
1249
- aftersourceset();
1708
+ else {
1709
+ result.source.push(model);
1710
+ result.oldNewIndexes[i] = index;
1711
+ index++;
1712
+ }
1713
+ return result;
1714
+ }, {
1715
+ source: [],
1716
+ prevExpanded: {},
1717
+ oldNewIndexes: {},
1250
1718
  });
1251
- this.addEventListener('aftersourceset', aftersourceset);
1252
- this.addEventListener('filter', ({ detail }) => this.onFilterChange(detail));
1253
- const existingNodes = this.revogrid.registerVNode.filter((n) => n.$tag$ !== 'revogr-filter-panel');
1254
- this.revogrid.registerVNode = [
1255
- ...existingNodes,
1256
- h("revogr-filter-panel", { filterItems: this.multiFilterItems, filterNames: this.possibleFilterNames, filterEntities: this.possibleFilterEntities, 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), disableDynamicFiltering: config === null || config === void 0 ? void 0 : config.disableDynamicFiltering, ref: e => (this.pop = e) }),
1257
- ];
1258
1719
  }
1259
- initConfig(config) {
1260
- if (config.multiFilterItems) {
1261
- this.multiFilterItems = Object.assign({}, config.multiFilterItems);
1720
+ setColumnGrouping(cols) {
1721
+ // if 0 column as holder
1722
+ if (cols === null || cols === void 0 ? void 0 : cols.length) {
1723
+ cols[0][PSEUDO_GROUP_COLUMN] = true;
1724
+ return true;
1262
1725
  }
1263
- if (config.customFilters) {
1264
- for (let cType in config.customFilters) {
1265
- const cFilter = config.customFilters[cType];
1266
- if (!this.possibleFilters[cFilter.columnFilterType]) {
1267
- this.possibleFilters[cFilter.columnFilterType] = [];
1726
+ return false;
1727
+ }
1728
+ setColumns({ columns }) {
1729
+ for (let type of columnTypes) {
1730
+ if (this.setColumnGrouping(columns[type])) {
1731
+ break;
1732
+ }
1733
+ }
1734
+ }
1735
+ // evaluate drag between groups
1736
+ onDrag(e) {
1737
+ const { from, to } = e.detail;
1738
+ const isDown = to - from >= 0;
1739
+ const { source } = this.getSource();
1740
+ const items = this.rowItems;
1741
+ let i = isDown ? from : to;
1742
+ const end = isDown ? to : from;
1743
+ for (; i < end; i++) {
1744
+ const model = source[items[i]];
1745
+ const isGroup = isGrouping(model);
1746
+ if (isGroup) {
1747
+ e.preventDefault();
1748
+ return;
1749
+ }
1750
+ }
1751
+ }
1752
+ beforeTrimmedApply(trimmed, type) {
1753
+ /** Before filter apply remove grouping filtering */
1754
+ if (type === FILTER_TRIMMED_TYPE) {
1755
+ const source = this.store.get('source');
1756
+ for (let index in trimmed) {
1757
+ if (trimmed[index] && isGrouping(source[index])) {
1758
+ trimmed[index] = false;
1268
1759
  }
1269
- this.possibleFilters[cFilter.columnFilterType].push(cType);
1270
- this.possibleFilterEntities[cType] = cFilter.func;
1271
- this.possibleFilterNames[cType] = cFilter.name;
1272
1760
  }
1273
1761
  }
1274
- if (config.filterProp) {
1275
- this.filterProp = config.filterProp;
1762
+ }
1763
+ // subscribe to grid events to process them accordingly
1764
+ subscribe() {
1765
+ /** if grouping present and new data source arrived */
1766
+ this.addEventListener('beforesourceset', ({ detail }) => this.onDataSet(detail));
1767
+ this.addEventListener('beforecolumnsset', ({ detail }) => this.setColumns(detail));
1768
+ /**
1769
+ * filter applied need to clear grouping and apply again
1770
+ * based on new results can be new grouping
1771
+ */
1772
+ this.addEventListener('beforetrimmed', ({ detail: { trimmed, trimmedType } }) => this.beforeTrimmedApply(trimmed, trimmedType));
1773
+ /**
1774
+ * sorting applied need to clear grouping and apply again
1775
+ * based on new results whole grouping order will changed
1776
+ */
1777
+ this.addEventListener('aftersortingapply', () => this.doSourceUpdate(Object.assign({}, this.options)));
1778
+ /**
1779
+ * Apply logic for focus inside of grouping
1780
+ * We can't focus on grouping rows, navigation only inside of groups for now
1781
+ */
1782
+ this.addEventListener('beforecellfocus', e => this.onFocus(e));
1783
+ /**
1784
+ * Prevent rgRow drag outside the group
1785
+ */
1786
+ this.addEventListener('roworderchanged', e => this.onDrag(e));
1787
+ /**
1788
+ * When grouping expand icon was clicked
1789
+ */
1790
+ this.addEventListener(GROUP_EXPAND_EVENT, ({ detail }) => this.onExpand(detail));
1791
+ }
1792
+ /**
1793
+ * Starts global source update with group clearing and applying new one
1794
+ * Initiated when need to reapply grouping
1795
+ */
1796
+ doSourceUpdate(options) {
1797
+ var _a;
1798
+ if (!this.hasProps) {
1799
+ return;
1276
1800
  }
1277
1801
  /**
1278
- * which filters has to be included/excluded
1279
- * convinient way to exclude system filters
1802
+ * Get source without grouping
1803
+ * @param newOldIndexMap - provides us mapping with new indexes vs old indexes, we would use it for trimmed mapping
1280
1804
  */
1281
- const cfgInlcude = config.include;
1282
- if (cfgInlcude) {
1283
- const filters = {};
1284
- for (let t in this.possibleFilters) {
1285
- // validate filters, if appropriate function present
1286
- const newTypes = this.possibleFilters[t].filter(f => cfgInlcude.indexOf(f) > -1);
1287
- if (newTypes.length) {
1288
- filters[t] = newTypes;
1289
- }
1290
- }
1291
- // if any valid filters provided show them
1292
- if (Object.keys(filters).length > 0) {
1293
- this.possibleFilters = filters;
1805
+ const { source, prevExpanded, oldNewIndexes } = this.getSource(true);
1806
+ /**
1807
+ * Group again
1808
+ * @param oldNewIndexMap - provides us mapping with new indexes vs old indexes
1809
+ */
1810
+ const { sourceWithGroups, depth, trimmed, oldNewIndexMap, childrenByGroup, } = gatherGrouping(source, ((_a = this.options) === null || _a === void 0 ? void 0 : _a.props) || [], Object.assign({ prevExpanded }, options));
1811
+ // setup source
1812
+ this.providers.data.setData(sourceWithGroups, GROUPING_ROW_TYPE, this.revogrid.disableVirtualY, { depth, customRenderer: options === null || options === void 0 ? void 0 : options.groupLabelTemplate }, true);
1813
+ this.updateTrimmed(trimmed, childrenByGroup, oldNewIndexes !== null && oldNewIndexes !== void 0 ? oldNewIndexes : {}, oldNewIndexMap);
1814
+ }
1815
+ /**
1816
+ * Apply grouping on data set
1817
+ * Clear grouping from source
1818
+ * If source came from other plugin
1819
+ */
1820
+ onDataSet(data) {
1821
+ var _a;
1822
+ if (!this.hasProps || !(data === null || data === void 0 ? void 0 : data.source) || !data.source.length) {
1823
+ return;
1824
+ }
1825
+ const source = data.source.filter(s => !isGrouping(s));
1826
+ const expanded = this.revogrid.grouping || {};
1827
+ const { sourceWithGroups, depth, trimmed, oldNewIndexMap, childrenByGroup, } = gatherGrouping(source, ((_a = this.options) === null || _a === void 0 ? void 0 : _a.props) || [], Object.assign({}, (expanded || {})));
1828
+ data.source = sourceWithGroups;
1829
+ this.providers.data.setGrouping({ depth });
1830
+ this.updateTrimmed(trimmed, childrenByGroup, oldNewIndexMap);
1831
+ }
1832
+ // apply grouping
1833
+ setGrouping(options) {
1834
+ // unsubscribe from all events when group applied
1835
+ this.clearSubscriptions();
1836
+ this.options = options;
1837
+ // clear props, no grouping exists
1838
+ if (!options.props || !Object.keys(options.props).length) {
1839
+ this.clearGrouping();
1840
+ return;
1841
+ }
1842
+ // props exist and source inited
1843
+ const { source } = this.getSource();
1844
+ if (source.length) {
1845
+ this.doSourceUpdate(Object.assign({}, options));
1846
+ }
1847
+ // props exist and columns inited
1848
+ for (let t of columnTypes) {
1849
+ if (this.setColumnGrouping(this.providers.column.getColumns(t))) {
1850
+ this.providers.column.refreshByType(t);
1851
+ break;
1294
1852
  }
1295
1853
  }
1296
- if (config.collection) {
1297
- this.filterCollection = reduce_1(config.collection, (result, item, prop) => {
1298
- if (this.possibleFilterEntities[item.type]) {
1299
- result[prop] = item;
1300
- }
1301
- else {
1302
- console.warn(`${item.type} type is not found.`);
1854
+ // if has any grouping subscribe to events again
1855
+ this.subscribe();
1856
+ }
1857
+ // clear grouping
1858
+ clearGrouping() {
1859
+ // clear columns
1860
+ columnTypes.forEach(t => {
1861
+ const cols = this.providers.column.getColumns(t);
1862
+ let deleted = false;
1863
+ cols.forEach(c => {
1864
+ if (isGroupingColumn(c)) {
1865
+ delete c[PSEUDO_GROUP_COLUMN];
1866
+ deleted = true;
1303
1867
  }
1304
- return result;
1305
- }, {});
1306
- }
1307
- if (config.localization) {
1308
- if (config.localization.filterNames) {
1309
- Object.entries(config.localization.filterNames).forEach(([k, v]) => {
1310
- if (this.possibleFilterNames[k] != void 0) {
1311
- this.possibleFilterNames[k] = v;
1312
- }
1313
- });
1868
+ });
1869
+ // if column store had grouping clear and refresh
1870
+ if (deleted) {
1871
+ this.providers.column.refreshByType(t);
1314
1872
  }
1873
+ });
1874
+ // clear rows
1875
+ const { source, oldNewIndexes } = this.getSource(true);
1876
+ this.providers.data.setData(source, GROUPING_ROW_TYPE, this.revogrid.disableVirtualY, undefined, true);
1877
+ this.updateTrimmed(undefined, undefined, oldNewIndexes);
1878
+ }
1879
+ updateTrimmed(trimmedGroup = {}, _childrenByGroup = {}, firstLevelMap = {}, secondLevelMap) {
1880
+ // map previously trimmed data
1881
+ const trimemedOptionsToUpgrade = processDoubleConversionTrimmed(this.trimmed, firstLevelMap, secondLevelMap);
1882
+ for (let type in trimemedOptionsToUpgrade) {
1883
+ this.revogrid.addTrimmed(trimemedOptionsToUpgrade[type], type);
1315
1884
  }
1885
+ // const emptyGroups = this.filterOutEmptyGroups(trimemedOptionsToUpgrade, childrenByGroup);
1886
+ // setup trimmed data for grouping
1887
+ this.revogrid.addTrimmed(Object.assign({}, trimmedGroup), TRIMMED_GROUPING);
1316
1888
  }
1317
- async headerclick(e) {
1318
- var _a, _b, _c;
1319
- const el = (_a = e.detail.originalEvent) === null || _a === void 0 ? void 0 : _a.target;
1320
- if (!isFilterBtn(el)) {
1889
+ }
1890
+
1891
+ const COLUMN_DRAG_CLASS = 'column-drag-start';
1892
+ class ColumnOrderHandler {
1893
+ constructor() {
1894
+ this.offset = 0;
1895
+ }
1896
+ renderAutoscroll(_, parent) {
1897
+ if (!parent) {
1321
1898
  return;
1322
1899
  }
1323
- e.preventDefault();
1324
- // close if same
1325
- const changes = await ((_b = this.pop) === null || _b === void 0 ? void 0 : _b.getChanges());
1326
- if (changes && (changes === null || changes === void 0 ? void 0 : changes.prop) === e.detail.prop) {
1327
- (_c = this.pop) === null || _c === void 0 ? void 0 : _c.show();
1900
+ this.autoscrollEl = document.createElement('div');
1901
+ this.autoscrollEl.classList.add('drag-auto-scroll-y');
1902
+ parent.appendChild(this.autoscrollEl);
1903
+ }
1904
+ autoscroll(pos, dataContainerSize, direction = 'translateX') {
1905
+ if (!this.autoscrollEl) {
1328
1906
  return;
1329
1907
  }
1330
- if (!this.pop) {
1331
- return;
1908
+ const helperOffset = 10;
1909
+ // calculate current y position inside of the grid active holder
1910
+ // 3 - size of element + border
1911
+ const maxScroll = Math.min(pos + helperOffset, dataContainerSize - 3);
1912
+ this.autoscrollEl.style.transform = `${direction}(${maxScroll}px)`;
1913
+ this.autoscrollEl.scrollIntoView({
1914
+ block: 'nearest',
1915
+ inline: 'nearest',
1916
+ });
1917
+ }
1918
+ start(e, { dataEl, gridRect, scrollEl, gridEl }, dir = 'left') {
1919
+ gridEl.classList.add(COLUMN_DRAG_CLASS);
1920
+ const scrollContainerRect = scrollEl.getBoundingClientRect();
1921
+ if (scrollContainerRect) {
1922
+ this.offset = scrollContainerRect[dir] - gridRect[dir];
1332
1923
  }
1333
- // filter button clicked, open filter dialog
1334
- const gridPos = this.revogrid.getBoundingClientRect();
1335
- const buttonPos = el.getBoundingClientRect();
1336
- const prop = e.detail.prop;
1337
- this.pop.filterTypes = this.getColumnFilter(e.detail.filter);
1338
- this.pop.show(Object.assign(Object.assign({}, this.filterCollection[prop]), { x: buttonPos.x - gridPos.x, y: buttonPos.y - gridPos.y + buttonPos.height, autoCorrect: true, prop }));
1924
+ this.renderAutoscroll(e, dataEl);
1339
1925
  }
1340
- getColumnFilter(type) {
1341
- let filterType = 'string';
1342
- if (!type) {
1343
- return { [filterType]: this.possibleFilters[filterType] };
1926
+ stop(gridEl) {
1927
+ var _a;
1928
+ gridEl.classList.remove(COLUMN_DRAG_CLASS);
1929
+ if (this.element) {
1930
+ this.element.hidden = true;
1344
1931
  }
1345
- // if custom column filter
1346
- if (this.isValidType(type)) {
1347
- filterType = type;
1348
- // if multiple filters applied
1932
+ this.offset = 0;
1933
+ (_a = this.autoscrollEl) === null || _a === void 0 ? void 0 : _a.remove();
1934
+ this.autoscrollEl = undefined;
1935
+ }
1936
+ showHandler(pos, size, direction = 'translateX') {
1937
+ if (!this.element) {
1938
+ return;
1349
1939
  }
1350
- else if (typeof type === 'object' && type.length) {
1351
- return type.reduce((r, multiType) => {
1352
- if (this.isValidType(multiType)) {
1353
- r[multiType] = this.possibleFilters[multiType];
1354
- }
1355
- return r;
1356
- }, {});
1940
+ // do not allow overcross top of the scrollable area, header excluded
1941
+ if (this.offset) {
1942
+ pos = Math.max(pos, this.offset);
1357
1943
  }
1358
- return { [filterType]: this.possibleFilters[filterType] };
1944
+ // can not be bigger then grid end
1945
+ pos = Math.min(pos, size);
1946
+ this.element.style.transform = `${direction}(${pos}px)`;
1947
+ this.element.hidden = false;
1359
1948
  }
1360
- isValidType(type) {
1361
- return !!(typeof type === 'string' && this.possibleFilters[type]);
1949
+ render() {
1950
+ const el = this.element = document.createElement('div');
1951
+ el.classList.add('drag-position-y');
1952
+ el.hidden = true;
1953
+ return el;
1362
1954
  }
1363
- // called on internal component change
1364
- async onFilterChange(filterItems) {
1365
- this.multiFilterItems = filterItems;
1366
- this.runFiltering();
1955
+ }
1956
+
1957
+ /**
1958
+ * Plugin for column manual move
1959
+ */
1960
+ const COLUMN_CLICK = ON_COLUMN_CLICK;
1961
+ const MOVE = 'columndragmousemove';
1962
+ const DRAG_END = 'columndragend';
1963
+ const BEFORE_DRAG_END = 'beforecolumndragend';
1964
+ // use this event subscription to drop D&D for particular columns
1965
+ const DRAG_START = 'columndragstart';
1966
+ class ColumnPlugin extends BasePlugin {
1967
+ constructor(revogrid, providers) {
1968
+ super(revogrid, providers);
1969
+ this.revogrid = revogrid;
1970
+ this.providers = providers;
1971
+ this.moveFunc = debounce_1((e) => this.doMove(e), 5);
1972
+ this.staticDragData = null;
1973
+ this.dragData = null;
1974
+ this.localSubscriptions = {};
1975
+ this.orderUi = new ColumnOrderHandler();
1976
+ revogrid.appendChild(this.orderUi.render());
1977
+ revogrid.classList.add('column-draggable');
1978
+ // Register events
1979
+ this.localSubscriptions['mouseleave'] = {
1980
+ target: document,
1981
+ callback: (e) => this.onMouseOut(e),
1982
+ };
1983
+ this.localSubscriptions['mouseup'] = {
1984
+ target: document,
1985
+ callback: (e) => this.onMouseUp(e),
1986
+ };
1987
+ this.localSubscriptions['mousemove'] = {
1988
+ target: document,
1989
+ callback: (e) => this.move(e),
1990
+ };
1991
+ this.addEventListener(COLUMN_CLICK, ({ detail }) => this.dragStart(detail));
1367
1992
  }
1368
- /**
1369
- * Triggers grid filtering
1370
- */
1371
- async doFiltering(collection, items, columns, filterItems) {
1372
- const columnsToUpdate = [];
1373
- columns.forEach(rgCol => {
1374
- const column = Object.assign({}, rgCol);
1375
- const hasFilter = filterItems[column.prop];
1376
- if (column[this.filterProp] && !hasFilter) {
1377
- delete column[this.filterProp];
1378
- columnsToUpdate.push(column);
1379
- }
1380
- if (!column[this.filterProp] && hasFilter) {
1381
- columnsToUpdate.push(column);
1382
- column[this.filterProp] = true;
1383
- }
1384
- });
1385
- const itemsToFilter = this.getRowFilter(items, filterItems);
1386
- // check is filter event prevented
1387
- const { defaultPrevented, detail } = this.emit('beforefiltertrimmed', {
1388
- collection,
1389
- itemsToFilter,
1390
- source: items,
1391
- filterItems,
1392
- });
1993
+ dragStart({ event, data }) {
1994
+ if (event.defaultPrevented) {
1995
+ return;
1996
+ }
1997
+ const { defaultPrevented } = dispatch(this.revogrid, DRAG_START, data);
1998
+ // check if allowed to drag particulat column
1393
1999
  if (defaultPrevented) {
1394
2000
  return;
1395
2001
  }
1396
- // check is trimmed event prevented
1397
- const isAddedEvent = await this.revogrid.addTrimmed(detail.itemsToFilter, FILTER_TRIMMED_TYPE);
1398
- if (isAddedEvent.defaultPrevented) {
2002
+ this.clearOrder();
2003
+ const { mouseleave, mouseup, mousemove } = this.localSubscriptions;
2004
+ mouseleave.target.addEventListener('mouseleave', mouseleave.callback);
2005
+ mouseup.target.addEventListener('mouseup', mouseup.callback);
2006
+ const dataEl = event.target.closest('revogr-header');
2007
+ const scrollEl = event.target.closest('revogr-viewport-scroll');
2008
+ if (!dataEl || !scrollEl) {
2009
+ return;
2010
+ }
2011
+ // no grouping drag and no row header column drag
2012
+ if (isColGrouping(data) || data.providers.type === 'rowHeaders') {
2013
+ return;
2014
+ }
2015
+ const cols = this.getDimension(data.pin || 'rgCol');
2016
+ const gridRect = this.revogrid.getBoundingClientRect();
2017
+ const elRect = dataEl.getBoundingClientRect();
2018
+ const startItem = getItemByPosition(cols, getLeftRelative(event.x, gridRect.left, elRect.left - gridRect.left));
2019
+ this.staticDragData = {
2020
+ startPos: event.x,
2021
+ startItem,
2022
+ data,
2023
+ dataEl,
2024
+ scrollEl,
2025
+ gridEl: this.revogrid,
2026
+ cols,
2027
+ };
2028
+ this.dragData = this.getData(this.staticDragData);
2029
+ mousemove.target.addEventListener('mousemove', mousemove.callback);
2030
+ this.orderUi.start(event, Object.assign(Object.assign({}, this.dragData), this.staticDragData));
2031
+ }
2032
+ doMove(e) {
2033
+ if (!this.staticDragData) {
2034
+ return;
2035
+ }
2036
+ const dragData = (this.dragData = this.getData(this.staticDragData));
2037
+ if (!dragData) {
1399
2038
  return;
1400
2039
  }
1401
- // applies the hasFilter to the columns to show filter icon
1402
- await this.revogrid.updateColumns(columnsToUpdate);
1403
- this.emit('afterfilterapply');
2040
+ const start = this.staticDragData.startPos;
2041
+ if (Math.abs(start - e.x) > 10) {
2042
+ const x = getLeftRelative(e.x, this.dragData.gridRect.left, this.dragData.scrollOffset);
2043
+ const rgCol = getItemByPosition(this.staticDragData.cols, x);
2044
+ this.orderUi.autoscroll(x, dragData.elRect.width);
2045
+ this.orderUi.showHandler(rgCol.end + dragData.scrollOffset, dragData.gridRect.width);
2046
+ }
1404
2047
  }
1405
- async clearFiltering() {
1406
- this.multiFilterItems = {};
1407
- await this.runFiltering();
2048
+ move(e) {
2049
+ dispatch(this.revogrid, MOVE, e);
2050
+ // then do move
2051
+ this.moveFunc(e);
1408
2052
  }
1409
- async runFiltering() {
1410
- const collection = {};
1411
- // handle old filterCollection to return the first filter only (if any) from multiFilterItems
1412
- const filterProps = Object.keys(this.multiFilterItems);
1413
- for (const prop of filterProps) {
1414
- // check if we have any filter for a column
1415
- if (this.multiFilterItems[prop].length > 0) {
1416
- const firstFilterItem = this.multiFilterItems[prop][0];
1417
- collection[prop] = {
1418
- filter: filterEntities[firstFilterItem.type],
1419
- type: firstFilterItem.type,
1420
- value: firstFilterItem.value,
1421
- };
2053
+ onMouseOut(_) {
2054
+ this.clearOrder();
2055
+ }
2056
+ onMouseUp(e) {
2057
+ // apply new positions
2058
+ if (this.dragData && this.staticDragData) {
2059
+ let relativePos = getLeftRelative(e.x, this.dragData.gridRect.left, this.dragData.scrollOffset);
2060
+ if (relativePos < 0) {
2061
+ relativePos = 0;
1422
2062
  }
2063
+ const newPosition = getItemByPosition(this.staticDragData.cols, relativePos);
2064
+ const store = this.providers.column.stores[this.dragData.type].store;
2065
+ const items = [...store.get('items')];
2066
+ // prevent position change if needed
2067
+ const { defaultPrevented: stopDrag } = dispatch(this.revogrid, BEFORE_DRAG_END, Object.assign(Object.assign({}, this.staticDragData), { startPosition: this.staticDragData.startItem, newPosition, newItem: store.get('source')[items[this.staticDragData.startItem.itemIndex]] }));
2068
+ if (!stopDrag) {
2069
+ // todo: if move item out of group remove item from group
2070
+ const toMove = items.splice(this.staticDragData.startItem.itemIndex, 1);
2071
+ items.splice(newPosition.itemIndex, 0, ...toMove);
2072
+ store.set('items', items);
2073
+ }
2074
+ dispatch(this.revogrid, DRAG_END, this.dragData);
1423
2075
  }
1424
- this.filterCollection = collection;
1425
- const { source, columns } = await this.getData();
1426
- const { defaultPrevented, detail } = this.emit('beforefilterapply', {
1427
- collection: this.filterCollection,
1428
- source,
1429
- columns,
1430
- filterItems: this.multiFilterItems,
1431
- });
1432
- if (defaultPrevented) {
1433
- return;
1434
- }
1435
- this.doFiltering(detail.collection, detail.source, detail.columns, detail.filterItems);
2076
+ this.clearOrder();
1436
2077
  }
1437
- async getData() {
2078
+ clearLocalSubscriptions() {
2079
+ each(this.localSubscriptions, ({ target, callback }, key) => target.removeEventListener(key, callback));
2080
+ }
2081
+ clearOrder() {
2082
+ this.staticDragData = null;
2083
+ this.dragData = null;
2084
+ this.clearLocalSubscriptions();
2085
+ this.orderUi.stop(this.revogrid);
2086
+ }
2087
+ /**
2088
+ * Clearing subscription
2089
+ */
2090
+ clearSubscriptions() {
2091
+ super.clearSubscriptions();
2092
+ this.clearLocalSubscriptions();
2093
+ }
2094
+ getData({ gridEl, dataEl, data, }) {
2095
+ const gridRect = gridEl.getBoundingClientRect();
2096
+ const elRect = dataEl.getBoundingClientRect();
2097
+ const scrollOffset = elRect.left - gridRect.left;
1438
2098
  return {
1439
- source: await this.revogrid.getSource(),
1440
- columns: await this.revogrid.getColumns(),
2099
+ elRect,
2100
+ gridRect,
2101
+ type: data.pin || 'rgCol',
2102
+ scrollOffset,
1441
2103
  };
1442
2104
  }
1443
- getRowFilter(rows, filterItems) {
1444
- const propKeys = Object.keys(filterItems);
1445
- const trimmed = {};
1446
- let propFilterSatisfiedCount = 0;
1447
- let lastFilterResults = [];
1448
- // each rows
1449
- rows.forEach((model, rowIndex) => {
1450
- // working on all props
1451
- for (const prop of propKeys) {
1452
- const propFilters = filterItems[prop];
1453
- propFilterSatisfiedCount = 0;
1454
- lastFilterResults = [];
1455
- // testing each filter for a prop
1456
- for (const [filterIndex, filterData] of propFilters.entries()) {
1457
- // the filter LogicFunction based on the type
1458
- const filter = this.possibleFilterEntities[filterData.type];
1459
- // THE MAGIC OF FILTERING IS HERE
1460
- if (filterData.relation === 'or') {
1461
- lastFilterResults = [];
1462
- if (filter(model[prop], filterData.value)) {
1463
- continue;
1464
- }
1465
- propFilterSatisfiedCount++;
1466
- }
1467
- else {
1468
- // 'and' relation will need to know the next filter
1469
- // so we save this current filter to include it in the next filter
1470
- lastFilterResults.push(!filter(model[prop], filterData.value));
1471
- // check first if we have a filter on the next index to pair it with this current filter
1472
- const nextFilterData = propFilters[filterIndex + 1];
1473
- // stop the sequence if there is no next filter or if the next filter is not an 'and' relation
1474
- if (!nextFilterData || nextFilterData.relation !== 'and') {
1475
- // let's just continue since for sure propFilterSatisfiedCount cannot be satisfied
1476
- if (lastFilterResults.indexOf(true) === -1) {
1477
- lastFilterResults = [];
1478
- continue;
1479
- }
1480
- // we need to add all of the lastFilterResults since we need to satisfy all
1481
- propFilterSatisfiedCount += lastFilterResults.length;
1482
- lastFilterResults = [];
1483
- }
1484
- }
1485
- } // end of propFilters forEach
1486
- // add to the list of removed/trimmed rows of filter condition is satisfied
1487
- if (propFilterSatisfiedCount === propFilters.length)
1488
- trimmed[rowIndex] = true;
1489
- } // end of for-of propKeys
1490
- });
1491
- return trimmed;
2105
+ getDimension(type) {
2106
+ return this.providers.dimension.stores[type].getCurrentState();
1492
2107
  }
1493
2108
  }
2109
+ function getLeftRelative(absoluteX, gridPos, offset) {
2110
+ return absoluteX - gridPos - offset;
2111
+ }
1494
2112
 
1495
2113
  var baseGetTag = _baseGetTag,
1496
2114
  isArray = isArray_1,
@@ -1631,7 +2249,7 @@ var _stringSize = stringSize$1;
1631
2249
 
1632
2250
  var baseKeys = _baseKeys,
1633
2251
  getTag = _getTag,
1634
- isArrayLike = isArrayLike_1,
2252
+ isArrayLike$1 = isArrayLike_1,
1635
2253
  isString = isString_1,
1636
2254
  stringSize = _stringSize;
1637
2255
 
@@ -1664,7 +2282,7 @@ function size(collection) {
1664
2282
  if (collection == null) {
1665
2283
  return 0;
1666
2284
  }
1667
- if (isArrayLike(collection)) {
2285
+ if (isArrayLike$1(collection)) {
1668
2286
  return isString(collection) ? stringSize(collection) : collection.length;
1669
2287
  }
1670
2288
  var tag = getTag(collection);
@@ -1897,742 +2515,435 @@ class SortingPlugin extends BasePlugin {
1897
2515
  }
1898
2516
  }
1899
2517
 
1900
- /**
1901
- * The base implementation of `_.clamp` which doesn't coerce arguments.
1902
- *
1903
- * @private
1904
- * @param {number} number The number to clamp.
1905
- * @param {number} [lower] The lower bound.
1906
- * @param {number} upper The upper bound.
1907
- * @returns {number} Returns the clamped number.
1908
- */
1909
-
1910
- function baseClamp$1(number, lower, upper) {
1911
- if (number === number) {
1912
- if (upper !== undefined) {
1913
- number = number <= upper ? number : upper;
1914
- }
1915
- if (lower !== undefined) {
1916
- number = number >= lower ? number : lower;
1917
- }
1918
- }
1919
- return number;
1920
- }
1921
-
1922
- var _baseClamp = baseClamp$1;
1923
-
1924
- var baseClamp = _baseClamp,
1925
- toInteger$1 = toInteger_1;
1926
-
1927
- /** Used as references for the maximum length and index of an array. */
1928
- var MAX_ARRAY_LENGTH = 4294967295;
1929
-
1930
- /**
1931
- * Converts `value` to an integer suitable for use as the length of an
1932
- * array-like object.
1933
- *
1934
- * **Note:** This method is based on
1935
- * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).
1936
- *
1937
- * @static
1938
- * @memberOf _
1939
- * @since 4.0.0
1940
- * @category Lang
1941
- * @param {*} value The value to convert.
1942
- * @returns {number} Returns the converted integer.
1943
- * @example
1944
- *
1945
- * _.toLength(3.2);
1946
- * // => 3
1947
- *
1948
- * _.toLength(Number.MIN_VALUE);
1949
- * // => 0
1950
- *
1951
- * _.toLength(Infinity);
1952
- * // => 4294967295
1953
- *
1954
- * _.toLength('3.2');
1955
- * // => 3
1956
- */
1957
- function toLength$1(value) {
1958
- return value ? baseClamp(toInteger$1(value), 0, MAX_ARRAY_LENGTH) : 0;
1959
- }
1960
-
1961
- var toLength_1 = toLength$1;
1962
-
1963
- var toInteger = toInteger_1,
1964
- toLength = toLength_1;
2518
+ var baseIteratee = _baseIteratee,
2519
+ isArrayLike = isArrayLike_1,
2520
+ keys = keys_1;
1965
2521
 
1966
2522
  /**
1967
- * The base implementation of `_.fill` without an iteratee call guard.
2523
+ * Creates a `_.find` or `_.findLast` function.
1968
2524
  *
1969
2525
  * @private
1970
- * @param {Array} array The array to fill.
1971
- * @param {*} value The value to fill `array` with.
1972
- * @param {number} [start=0] The start position.
1973
- * @param {number} [end=array.length] The end position.
1974
- * @returns {Array} Returns `array`.
2526
+ * @param {Function} findIndexFunc The function to find the collection index.
2527
+ * @returns {Function} Returns the new find function.
1975
2528
  */
1976
- function baseFill$1(array, value, start, end) {
1977
- var length = array.length;
1978
-
1979
- start = toInteger(start);
1980
- if (start < 0) {
1981
- start = -start > length ? 0 : (length + start);
1982
- }
1983
- end = (end === undefined || end > length) ? length : toInteger(end);
1984
- if (end < 0) {
1985
- end += length;
1986
- }
1987
- end = start > end ? 0 : toLength(end);
1988
- while (start < end) {
1989
- array[start++] = value;
1990
- }
1991
- return array;
2529
+ function createFind$1(findIndexFunc) {
2530
+ return function(collection, predicate, fromIndex) {
2531
+ var iterable = Object(collection);
2532
+ if (!isArrayLike(collection)) {
2533
+ var iteratee = baseIteratee(predicate);
2534
+ collection = keys(collection);
2535
+ predicate = function(key) { return iteratee(iterable[key], key, iterable); };
2536
+ }
2537
+ var index = findIndexFunc(collection, predicate, fromIndex);
2538
+ return index > -1 ? iterable[iteratee ? collection[index] : index] : undefined;
2539
+ };
1992
2540
  }
1993
2541
 
1994
- var _baseFill = baseFill$1;
2542
+ var _createFind = createFind$1;
1995
2543
 
1996
- var baseFill = _baseFill,
1997
- isIterateeCall = _isIterateeCall;
2544
+ var createFind = _createFind,
2545
+ findIndex = findIndex_1;
1998
2546
 
1999
2547
  /**
2000
- * Fills elements of `array` with `value` from `start` up to, but not
2001
- * including, `end`.
2002
- *
2003
- * **Note:** This method mutates `array`.
2548
+ * Iterates over elements of `collection`, returning the first element
2549
+ * `predicate` returns truthy for. The predicate is invoked with three
2550
+ * arguments: (value, index|key, collection).
2004
2551
  *
2005
2552
  * @static
2006
2553
  * @memberOf _
2007
- * @since 3.2.0
2008
- * @category Array
2009
- * @param {Array} array The array to fill.
2010
- * @param {*} value The value to fill `array` with.
2011
- * @param {number} [start=0] The start position.
2012
- * @param {number} [end=array.length] The end position.
2013
- * @returns {Array} Returns `array`.
2554
+ * @since 0.1.0
2555
+ * @category Collection
2556
+ * @param {Array|Object} collection The collection to inspect.
2557
+ * @param {Function} [predicate=_.identity] The function invoked per iteration.
2558
+ * @param {number} [fromIndex=0] The index to search from.
2559
+ * @returns {*} Returns the matched element, else `undefined`.
2014
2560
  * @example
2015
2561
  *
2016
- * var array = [1, 2, 3];
2562
+ * var users = [
2563
+ * { 'user': 'barney', 'age': 36, 'active': true },
2564
+ * { 'user': 'fred', 'age': 40, 'active': false },
2565
+ * { 'user': 'pebbles', 'age': 1, 'active': true }
2566
+ * ];
2017
2567
  *
2018
- * _.fill(array, 'a');
2019
- * console.log(array);
2020
- * // => ['a', 'a', 'a']
2568
+ * _.find(users, function(o) { return o.age < 40; });
2569
+ * // => object for 'barney'
2021
2570
  *
2022
- * _.fill(Array(3), 2);
2023
- * // => [2, 2, 2]
2571
+ * // The `_.matches` iteratee shorthand.
2572
+ * _.find(users, { 'age': 1, 'active': true });
2573
+ * // => object for 'pebbles'
2024
2574
  *
2025
- * _.fill([4, 6, 8, 10], '*', 1, 3);
2026
- * // => [4, '*', '*', 10]
2575
+ * // The `_.matchesProperty` iteratee shorthand.
2576
+ * _.find(users, ['active', false]);
2577
+ * // => object for 'fred'
2578
+ *
2579
+ * // The `_.property` iteratee shorthand.
2580
+ * _.find(users, 'active');
2581
+ * // => object for 'barney'
2027
2582
  */
2028
- function fill(array, value, start, end) {
2029
- var length = array == null ? 0 : array.length;
2030
- if (!length) {
2031
- return [];
2032
- }
2033
- if (start && typeof start != 'number' && isIterateeCall(array, value, start)) {
2034
- start = 0;
2035
- end = length;
2036
- }
2037
- return baseFill(array, value, start, end);
2038
- }
2039
-
2040
- var fill_1 = fill;
2583
+ var find = createFind(findIndex);
2041
2584
 
2042
- const INITIAL = {
2043
- mime: 'text/csv',
2044
- fileKind: 'csv',
2045
- // BOM signature
2046
- bom: true,
2047
- columnDelimiter: ',',
2048
- rowDelimiter: '\r\n',
2049
- encoding: '',
2050
- };
2051
- // The ASCII character code 13 is called a Carriage Return or CR.
2052
- const CARRIAGE_RETURN = String.fromCharCode(13);
2053
- // Chr(13) followed by a Chr(10) that compose a proper CRLF.
2054
- const LINE_FEED = String.fromCharCode(10);
2055
- const DOUBLE_QT = String.fromCharCode(34);
2056
- const NO_BREAK_SPACE = String.fromCharCode(0xfeff);
2057
- const escapeRegex = new RegExp('"', 'g');
2058
- class ExportCsv {
2059
- constructor(options = {}) {
2060
- this.options = Object.assign(Object.assign({}, INITIAL), options);
2061
- }
2062
- doExport({ data, headers, props }) {
2063
- let result = this.options.bom ? NO_BREAK_SPACE : '';
2064
- // any header
2065
- if ((headers === null || headers === void 0 ? void 0 : headers.length) > 0) {
2066
- headers.forEach(header => {
2067
- // ignore empty
2068
- if (!header.length) {
2069
- return;
2070
- }
2071
- result += this.prepareHeader(header, this.options.columnDelimiter);
2072
- result += this.options.rowDelimiter;
2073
- });
2074
- }
2075
- data.forEach((rgRow, index) => {
2076
- if (index > 0) {
2077
- result += this.options.rowDelimiter;
2078
- }
2079
- // support grouping
2080
- if (isGrouping(rgRow)) {
2081
- result += this.parseCell(getGroupingName(rgRow), this.options.columnDelimiter);
2082
- return;
2083
- }
2084
- result += props.map(p => this.parseCell(rgRow[p], this.options.columnDelimiter)).join(this.options.columnDelimiter);
2085
- });
2086
- return result;
2087
- }
2088
- prepareHeader(columnHeaders, columnDelimiter) {
2089
- let result = '';
2090
- const newColumnHeaders = columnHeaders.map(v => this.parseCell(v, columnDelimiter, true));
2091
- result += newColumnHeaders.join(columnDelimiter);
2092
- return result;
2093
- }
2094
- parseCell(value, columnDelimiter, force = false) {
2095
- let escape = value;
2096
- if (typeof value !== 'string') {
2097
- escape = JSON.stringify(value);
2098
- }
2099
- const toEscape = [CARRIAGE_RETURN, DOUBLE_QT, LINE_FEED, columnDelimiter];
2100
- if (typeof escape === 'undefined') {
2101
- return '';
2102
- }
2103
- if (escape !== '' && (force || toEscape.some(i => escape.indexOf(i) >= 0))) {
2104
- return `"${escape.replace(escapeRegex, '""')}"`;
2105
- }
2106
- return escape;
2107
- }
2108
- }
2585
+ var find_1 = find;
2109
2586
 
2110
- var ExportTypes;
2111
- (function (ExportTypes) {
2112
- ExportTypes["csv"] = "csv";
2113
- })(ExportTypes || (ExportTypes = {}));
2114
- class ExportFilePlugin extends BasePlugin {
2115
- /** Exports string */
2116
- async exportString(options = {}, t = ExportTypes.csv) {
2117
- const data = await this.beforeexport();
2118
- if (!data) {
2119
- return null;
2120
- }
2121
- return this.formatter(t, options).doExport(data);
2122
- }
2123
- /** Exports Blob */
2124
- async exportBlob(options = {}, t = ExportTypes.csv) {
2125
- return await this.getBlob(this.formatter(t, options));
2126
- }
2127
- /** Export file */
2128
- async exportFile(options = {}, t = ExportTypes.csv) {
2129
- const formatter = this.formatter(t, options);
2130
- // url
2131
- const URL = window.URL || window.webkitURL;
2132
- const a = document.createElement('a');
2133
- const { filename, fileKind } = formatter.options;
2134
- const name = `${filename}.${fileKind}`;
2135
- const blob = await this.getBlob(formatter);
2136
- const url = blob ? URL.createObjectURL(blob) : '';
2137
- a.style.display = 'none';
2138
- a.setAttribute('href', url);
2139
- a.setAttribute('download', name);
2140
- this.revogrid.appendChild(a);
2141
- a.dispatchEvent(new MouseEvent('click'));
2142
- this.revogrid.removeChild(a);
2143
- // delay for revoke, correct for some browsers
2144
- await timeout(120);
2145
- URL.revokeObjectURL(url);
2146
- }
2147
- /** Blob object */
2148
- async getBlob(formatter) {
2149
- const type = `${formatter.options.mime};charset=${formatter.options.encoding}`;
2150
- if (typeof Blob !== 'undefined') {
2151
- const data = await this.beforeexport();
2152
- if (!data) {
2153
- return null;
2154
- }
2155
- return new Blob([formatter.doExport(data)], { type });
2156
- }
2157
- return null;
2158
- }
2159
- // before event
2160
- async beforeexport() {
2161
- let data = await this.getData();
2162
- const event = this.emit('beforeexport', { data });
2163
- if (event.defaultPrevented) {
2164
- return null;
2165
- }
2166
- return event.detail.data;
2167
- }
2168
- async getData() {
2169
- const data = await this.getSource();
2170
- const colSource = [];
2171
- const colPromises = [];
2172
- columnTypes.forEach((t, i) => {
2173
- colPromises.push(this.getColPerSource(t).then(s => (colSource[i] = s)));
2174
- });
2175
- await Promise.all(colPromises);
2176
- const columns = {
2177
- headers: [],
2178
- props: [],
2179
- };
2180
- for (let source of colSource) {
2181
- source.headers.forEach((h, i) => {
2182
- if (!columns.headers[i]) {
2183
- columns.headers[i] = [];
2184
- }
2185
- columns.headers[i].push(...h);
2186
- });
2187
- columns.props.push(...source.props);
2188
- }
2189
- return Object.assign({ data }, columns);
2190
- }
2191
- async getColPerSource(t) {
2192
- const store = await this.revogrid.getColumnStore(t);
2193
- const source = store.get('source');
2194
- const virtualIndexes = store.get('items');
2195
- const depth = store.get('groupingDepth');
2196
- const groups = store.get('groups');
2197
- const colNames = [];
2198
- const colProps = [];
2199
- const visibleItems = virtualIndexes.reduce((r, v, virtualIndex) => {
2200
- const prop = source[v].prop;
2201
- colNames.push(source[v].name || '');
2202
- colProps.push(prop);
2203
- r[prop] = virtualIndex;
2204
- return r;
2205
- }, {});
2206
- const rows = this.getGroupHeaders(depth, groups, virtualIndexes, visibleItems);
2207
- rows.push(colNames);
2208
- return {
2209
- headers: rows,
2210
- props: colProps,
2211
- };
2212
- }
2213
- getGroupHeaders(depth, groups, items, visibleItems) {
2214
- const rows = [];
2215
- const template = fill_1(new Array(items.length), '');
2216
- for (let d = 0; d < depth; d++) {
2217
- const rgRow = [...template];
2218
- rows.push(rgRow);
2219
- if (!groups[d]) {
2220
- continue;
2221
- }
2222
- const levelGroups = groups[d];
2223
- // add names of groups
2224
- levelGroups.forEach((group) => {
2225
- const minIndex = this.findGroupStartIndex(group.ids, visibleItems);
2226
- if (typeof minIndex === 'number') {
2227
- rgRow[minIndex] = group.name;
2228
- }
2587
+ class ColumnDataProvider {
2588
+ get order() {
2589
+ const order = {};
2590
+ const sorting = this.sorting;
2591
+ if (sorting) {
2592
+ Object.keys(sorting).forEach((prop) => {
2593
+ order[prop] = sorting[prop].order;
2229
2594
  });
2230
2595
  }
2231
- return rows;
2596
+ return order;
2232
2597
  }
2233
- findGroupStartIndex(ids, visibleItems) {
2234
- let min;
2235
- ids.forEach(id => {
2236
- const current = visibleItems[id];
2237
- if (typeof current === 'number') {
2238
- if (typeof min !== 'number' || min > current) {
2239
- min = current;
2240
- }
2241
- }
2242
- });
2243
- return min;
2598
+ get stores() {
2599
+ return this.dataSources;
2244
2600
  }
2245
- async getSource() {
2246
- const data = [];
2247
- const promisesData = [];
2248
- rowTypes.forEach(t => {
2249
- const dataPart = [];
2250
- data.push(dataPart);
2251
- const promise = this.revogrid.getVisibleSource(t).then((d) => dataPart.push(...d));
2252
- promisesData.push(promise);
2601
+ constructor() {
2602
+ this.sorting = null;
2603
+ this.dataSources = columnTypes.reduce((sources, k) => {
2604
+ sources[k] = new DataStore(k);
2605
+ return sources;
2606
+ }, {});
2607
+ }
2608
+ column(c, pin) {
2609
+ return this.getColumn(c, pin || 'rgCol');
2610
+ }
2611
+ getColumn(virtualIndex, type) {
2612
+ return getSourceItem(this.dataSources[type].store, virtualIndex);
2613
+ }
2614
+ getRawColumns() {
2615
+ return reduce_1(this.dataSources, (result, item, type) => {
2616
+ result[type] = item.store.get('source');
2617
+ return result;
2618
+ }, {
2619
+ rgCol: [],
2620
+ colPinStart: [],
2621
+ colPinEnd: [],
2253
2622
  });
2254
- await Promise.all(promisesData);
2255
- return data.reduce((r, v) => {
2256
- r.push(...v);
2623
+ }
2624
+ getColumns(type = 'all') {
2625
+ if (type !== 'all') {
2626
+ return this.dataSources[type].store.get('source');
2627
+ }
2628
+ return columnTypes.reduce((r, t) => {
2629
+ r.push(...this.dataSources[t].store.get('source'));
2257
2630
  return r;
2258
2631
  }, []);
2259
2632
  }
2260
- // get correct class for future multiple types support
2261
- formatter(type, options = {}) {
2262
- switch (type) {
2263
- case ExportTypes.csv:
2264
- return new ExportCsv(options);
2265
- default:
2266
- throw new Error('Unknown format');
2267
- }
2633
+ getColumnIndexByProp(prop, type) {
2634
+ return getSourceItemVirtualIndexByProp(this.dataSources[type].store, prop);
2268
2635
  }
2269
- }
2270
-
2271
- // provide collapse data
2272
- function doCollapse(pIndex, source) {
2273
- const model = source[pIndex];
2274
- const collapseValue = model[PSEUDO_GROUP_ITEM_VALUE];
2275
- const trimmed = {};
2276
- let i = pIndex + 1;
2277
- const total = source.length;
2278
- while (i < total) {
2279
- const currentModel = source[i];
2280
- if (isGrouping(currentModel)) {
2281
- const currentValue = currentModel[PSEUDO_GROUP_ITEM_VALUE];
2282
- if (!currentValue.length || !currentValue.startsWith(collapseValue + ',')) {
2283
- break;
2284
- }
2285
- currentModel[GROUP_EXPANDED] = false;
2286
- }
2287
- trimmed[i++] = true;
2636
+ getColumnByProp(prop, type) {
2637
+ const items = this.dataSources[type].store.get('source');
2638
+ return find_1(items, { prop });
2288
2639
  }
2289
- model[GROUP_EXPANDED] = false;
2290
- return { trimmed };
2291
- }
2292
- /**
2293
- *
2294
- * @param pIndex - physical index
2295
- * @param vIndex - virtual index, need to update item collection
2296
- * @param source - data source
2297
- * @param rowItemsIndexes - rgRow indexes
2298
- */
2299
- function doExpand(vIndex, source, rowItemsIndexes) {
2300
- const physicalIndex = rowItemsIndexes[vIndex];
2301
- const model = source[physicalIndex];
2302
- const currentGroup = getParsedGroup(model[PSEUDO_GROUP_ITEM_ID]);
2303
- const trimmed = {};
2304
- // no group found
2305
- if (!currentGroup) {
2306
- return { trimmed };
2640
+ refreshByType(type) {
2641
+ this.dataSources[type].refresh();
2307
2642
  }
2308
- const groupItems = [];
2309
- model[GROUP_EXPANDED] = true;
2310
- let i = physicalIndex + 1;
2311
- const total = source.length;
2312
- let groupLevelOnly = 0;
2313
- // go through all rows
2314
- while (i < total) {
2315
- const currentModel = source[i];
2316
- const isGroup = isGrouping(currentModel);
2317
- // group found
2318
- if (isGroup) {
2319
- if (!isSameGroup(currentGroup, model, currentModel)) {
2320
- break;
2643
+ setColumns(data) {
2644
+ columnTypes.forEach(k => {
2645
+ // set columns data
2646
+ this.dataSources[k].updateData(data.columns[k], {
2647
+ // max depth level
2648
+ depth: data.maxLevel,
2649
+ // groups
2650
+ groups: data.columnGrouping[k].reduce((res, g) => {
2651
+ if (!res[g.level]) {
2652
+ res[g.level] = [];
2653
+ }
2654
+ res[g.level].push(g);
2655
+ return res;
2656
+ }, {}),
2657
+ });
2658
+ });
2659
+ this.sorting = data.sort;
2660
+ return data;
2661
+ }
2662
+ updateColumns(cols) {
2663
+ // collect column by type and propert
2664
+ const columnByKey = cols.reduce((res, c) => {
2665
+ const type = getColumnType(c);
2666
+ if (!res[type]) {
2667
+ res[type] = {};
2321
2668
  }
2322
- else if (!groupLevelOnly) {
2323
- // if get group first it's group only level
2324
- groupLevelOnly = currentModel[GROUP_DEPTH];
2669
+ res[type][c.prop] = c;
2670
+ return res;
2671
+ }, {});
2672
+ // find indexes in source
2673
+ const colByIndex = {};
2674
+ for (const t in columnByKey) {
2675
+ if (!columnByKey.hasOwnProperty(t)) {
2676
+ continue;
2677
+ }
2678
+ const type = t;
2679
+ const colsToUpdate = columnByKey[type];
2680
+ const items = this.dataSources[type].store.get('source');
2681
+ colByIndex[type] = {};
2682
+ for (let i = 0; i < items.length; i++) {
2683
+ const rgCol = items[i];
2684
+ const colToUpdateIfExists = colsToUpdate === null || colsToUpdate === void 0 ? void 0 : colsToUpdate[rgCol.prop];
2685
+ if (colToUpdateIfExists) {
2686
+ colByIndex[type][i] = colToUpdateIfExists;
2687
+ }
2325
2688
  }
2326
2689
  }
2327
- // level 0 or same depth
2328
- if (!groupLevelOnly || (isGroup && groupLevelOnly === currentModel[GROUP_DEPTH])) {
2329
- trimmed[i] = false;
2330
- groupItems.push(i);
2690
+ for (const t in colByIndex) {
2691
+ if (!colByIndex.hasOwnProperty(t)) {
2692
+ continue;
2693
+ }
2694
+ const type = t;
2695
+ setSourceByVirtualIndex(this.dataSources[type].store, colByIndex[type] || {});
2331
2696
  }
2332
- i++;
2333
2697
  }
2334
- const result = {
2335
- trimmed,
2336
- };
2337
- if (groupItems.length) {
2338
- const items = [...rowItemsIndexes];
2339
- items.splice(vIndex + 1, 0, ...groupItems);
2340
- result.items = items;
2698
+ updateColumn(column, index) {
2699
+ const type = getColumnType(column);
2700
+ setSourceByVirtualIndex(this.dataSources[type].store, { [index]: column });
2341
2701
  }
2342
- return result;
2343
- }
2344
-
2345
- const TRIMMED_GROUPING = 'grouping';
2346
- /**
2347
- * Prepare trimming updated indexes for grouping
2348
- * @param initiallyTrimed
2349
- * @param firstLevelMap
2350
- * @param secondLevelMap
2351
- */
2352
- function processDoubleConversionTrimmed(initiallyTrimed, firstLevelMap, secondLevelMap) {
2353
- const trimemedOptionsToUpgrade = {};
2354
- /**
2355
- * go through all groups except grouping
2356
- */
2357
- for (let type in initiallyTrimed) {
2358
- if (type === TRIMMED_GROUPING) {
2359
- continue;
2702
+ updateColumnSorting(column, index, sorting, additive) {
2703
+ if (!additive) {
2704
+ this.clearSorting();
2360
2705
  }
2361
- const items = initiallyTrimed[type];
2362
- const newItems = {};
2363
- for (let initialIndex in items) {
2364
- /**
2365
- * if item exists we find it in collection
2366
- * we support 2 level of conversions
2367
- */
2368
- let newConversionIndex = firstLevelMap[initialIndex];
2369
- if (secondLevelMap) {
2370
- newConversionIndex = secondLevelMap[newConversionIndex];
2371
- }
2372
- /**
2373
- * if item was trimmed previously
2374
- * trimming makes sense to apply
2375
- */
2376
- if (items[initialIndex]) {
2377
- newItems[newConversionIndex] = true;
2378
- /**
2379
- * If changes present apply changes to new source
2380
- */
2381
- if (newConversionIndex !== parseInt(initialIndex, 10)) {
2382
- trimemedOptionsToUpgrade[type] = newItems;
2383
- }
2384
- }
2706
+ column.order = sorting;
2707
+ if (!this.sorting) {
2708
+ this.sorting = {};
2385
2709
  }
2710
+ this.sorting[column.prop] = column;
2711
+ this.updateColumn(column, index);
2712
+ return column;
2386
2713
  }
2387
- return trimemedOptionsToUpgrade;
2388
- }
2389
-
2390
- class GroupingRowPlugin extends BasePlugin {
2391
- get hasProps() {
2392
- var _a, _b, _c;
2393
- return ((_a = this.options) === null || _a === void 0 ? void 0 : _a.props) && ((_c = (_b = this.options) === null || _b === void 0 ? void 0 : _b.props) === null || _c === void 0 ? void 0 : _c.length);
2394
- }
2395
- get store() {
2396
- return this.providers.data.stores[GROUPING_ROW_TYPE].store;
2714
+ clearSorting() {
2715
+ const types = reduce_1(this.sorting, (r, c) => {
2716
+ const k = getColumnType(c);
2717
+ r[k] = true;
2718
+ return r;
2719
+ }, {});
2720
+ each(types, (_, type) => {
2721
+ const cols = this.dataSources[type].store.get('source');
2722
+ each(cols, (c) => (c.order = undefined));
2723
+ this.dataSources[type].setData({ source: [...cols] });
2724
+ });
2725
+ this.sorting = {};
2397
2726
  }
2398
- // proxy for items get
2399
- get rowItems() {
2400
- return this.store.get('items');
2727
+ }
2728
+
2729
+ /**
2730
+ * Data source provider
2731
+ */
2732
+ class DataProvider {
2733
+ constructor(dimensionProvider) {
2734
+ this.dimensionProvider = dimensionProvider;
2735
+ this.stores = reduce_1(rowTypes, (sources, k) => {
2736
+ sources[k] = new DataStore(k);
2737
+ return sources;
2738
+ }, {});
2401
2739
  }
2402
- get trimmed() {
2403
- return this.store.get('trimmed');
2740
+ setData(data, type = 'rgRow', disableVirtualRows = false, grouping, silent = false) {
2741
+ // set rgRow data
2742
+ this.stores[type].updateData([...data], grouping, silent);
2743
+ // for pinned row no need virtual data
2744
+ const noVirtual = type !== 'rgRow' || disableVirtualRows;
2745
+ this.dimensionProvider.setData(data.length, type, noVirtual);
2746
+ return data;
2404
2747
  }
2405
- constructor(revogrid, providers) {
2406
- super(revogrid, providers);
2407
- this.revogrid = revogrid;
2408
- this.providers = providers;
2748
+ getModel(virtualIndex, type = 'rgRow') {
2749
+ const store = this.stores[type].store;
2750
+ return getSourceItem(store, virtualIndex);
2409
2751
  }
2410
- // befoce cell focus
2411
- onFocus(e) {
2412
- if (isGrouping(e.detail.model)) {
2413
- e.preventDefault();
2414
- }
2752
+ setCellData({ type, rowIndex, prop, val }, mutate = true) {
2753
+ const model = this.getModel(rowIndex, type);
2754
+ model[prop] = val;
2755
+ // apply data to source
2756
+ setSourceByVirtualIndex(this.stores[type].store, { [rowIndex]: model }, mutate);
2415
2757
  }
2416
- // expand event triggered
2417
- onExpand({ virtualIndex }) {
2418
- const { source } = this.getSource();
2419
- let newTrimmed = this.trimmed[TRIMMED_GROUPING];
2420
- let i = getPhysical(this.store, virtualIndex);
2421
- const model = source[i];
2422
- const prevExpanded = model[GROUP_EXPANDED];
2423
- if (!prevExpanded) {
2424
- const { trimmed, items } = doExpand(virtualIndex, source, this.rowItems);
2425
- newTrimmed = Object.assign(Object.assign({}, newTrimmed), trimmed);
2426
- if (items) {
2427
- setItems(this.store, items);
2758
+ setRangeData(data, type) {
2759
+ const items = {};
2760
+ for (let rowIndex in data) {
2761
+ const oldModel = (items[rowIndex] = getSourceItem(this.stores[type].store, parseInt(rowIndex, 10)));
2762
+ if (!oldModel) {
2763
+ continue;
2764
+ }
2765
+ for (let prop in data[rowIndex]) {
2766
+ oldModel[prop] = data[rowIndex][prop];
2428
2767
  }
2429
2768
  }
2430
- else {
2431
- const { trimmed } = doCollapse(i, source);
2432
- newTrimmed = Object.assign(Object.assign({}, newTrimmed), trimmed);
2433
- this.revogrid.clearFocus();
2769
+ // apply data to source
2770
+ setSourceByVirtualIndex(this.stores[type].store, items);
2771
+ }
2772
+ refresh(type = 'all') {
2773
+ if (isRowType(type)) {
2774
+ this.refreshItems(type);
2434
2775
  }
2435
- this.store.set('source', source);
2436
- this.revogrid.addTrimmed(newTrimmed, TRIMMED_GROUPING);
2776
+ rowTypes.forEach((t) => this.refreshItems(t));
2437
2777
  }
2438
- // get source based on proxy item collection to preserve rgRow order
2439
- getSource(withoutGrouping = false) {
2440
- const source = this.store.get('source');
2441
- const items = this.store.get('proxyItems');
2442
- let index = 0;
2443
- // order important here, expected parent is first, then others
2444
- return items.reduce((result, i) => {
2445
- const model = source[i];
2446
- if (!withoutGrouping) {
2447
- result.source.push(model);
2448
- return result;
2449
- }
2450
- // grouping filter
2451
- if (isGrouping(model)) {
2452
- if (model[GROUP_EXPANDED]) {
2453
- result.prevExpanded[model[PSEUDO_GROUP_ITEM_VALUE]] = true;
2454
- }
2455
- }
2456
- else {
2457
- result.source.push(model);
2458
- result.oldNewIndexes[i] = index;
2459
- index++;
2460
- }
2461
- return result;
2462
- }, {
2463
- source: [],
2464
- prevExpanded: {},
2465
- oldNewIndexes: {},
2466
- });
2778
+ refreshItems(type = 'rgRow') {
2779
+ const items = this.stores[type].store.get('items');
2780
+ this.stores[type].setData({ items: [...items] });
2467
2781
  }
2468
- setColumnGrouping(cols) {
2469
- // if 0 column as holder
2470
- if (cols === null || cols === void 0 ? void 0 : cols.length) {
2471
- cols[0][PSEUDO_GROUP_COLUMN] = true;
2472
- return true;
2473
- }
2474
- return false;
2782
+ setGrouping({ depth }, type = 'rgRow') {
2783
+ this.stores[type].setData({ groupingDepth: depth });
2475
2784
  }
2476
- setColumns({ columns }) {
2477
- for (let type of columnTypes) {
2478
- if (this.setColumnGrouping(columns[type])) {
2479
- break;
2480
- }
2785
+ setTrimmed(trimmed, type = 'rgRow') {
2786
+ const store = this.stores[type];
2787
+ store.addTrimmed(trimmed);
2788
+ this.dimensionProvider.setTrimmed(trimmed, type);
2789
+ if (type === 'rgRow') {
2790
+ this.dimensionProvider.setData(getVisibleSourceItem(store.store).length, type);
2481
2791
  }
2482
2792
  }
2483
- // evaluate drag between groups
2484
- onDrag(e) {
2485
- const { from, to } = e.detail;
2486
- const isDown = to - from >= 0;
2487
- const { source } = this.getSource();
2488
- const items = this.rowItems;
2489
- let i = isDown ? from : to;
2490
- const end = isDown ? to : from;
2491
- for (; i < end; i++) {
2492
- const model = source[items[i]];
2493
- const isGroup = isGrouping(model);
2494
- if (isGroup) {
2495
- e.preventDefault();
2496
- return;
2497
- }
2498
- }
2793
+ }
2794
+
2795
+ /**
2796
+ * Dimension provider
2797
+ * Stores dimension information and custom sizes
2798
+ */
2799
+ class DimensionProvider {
2800
+ constructor(viewports, config) {
2801
+ this.viewports = viewports;
2802
+ const sizeChanged = debounce_1((k) => config.realSizeChanged(k), RESIZE_INTERVAL);
2803
+ this.stores = reduce_1([...rowTypes, ...columnTypes], (sources, k) => {
2804
+ sources[k] = new DimensionStore();
2805
+ sources[k].store.onChange('realSize', () => sizeChanged(k));
2806
+ return sources;
2807
+ }, {});
2499
2808
  }
2500
- beforeTrimmedApply(trimmed, type) {
2501
- /** Before filter apply remove grouping filtering */
2502
- if (type === FILTER_TRIMMED_TYPE) {
2503
- const source = this.store.get('source');
2504
- for (let index in trimmed) {
2505
- if (trimmed[index] && isGrouping(source[index])) {
2506
- trimmed[index] = false;
2507
- }
2508
- }
2809
+ /**
2810
+ * Clear old sizes from dimension and viewports
2811
+ * @param type - dimension type
2812
+ * @param count - count of items
2813
+ */
2814
+ clearSize(t, count) {
2815
+ this.stores[t].drop();
2816
+ // after we done with drop trigger viewport recalculaction
2817
+ this.viewports.stores[t].setOriginalSizes(this.stores[t].store.get('originItemSize'));
2818
+ this.setItemCount(count, t);
2819
+ }
2820
+ /**
2821
+ * Apply new custom sizes to dimension and view port
2822
+ * @param type - dimension type
2823
+ * @param sizes - new custom sizes
2824
+ * @param keepOld - keep old sizes merge new with old
2825
+ */
2826
+ setCustomSizes(type, sizes, keepOld = false) {
2827
+ let newSizes = sizes;
2828
+ if (keepOld) {
2829
+ const oldSizes = this.stores[type].store.get('sizes');
2830
+ newSizes = Object.assign(Object.assign({}, oldSizes), sizes);
2509
2831
  }
2832
+ this.stores[type].setDimensionSize(newSizes);
2833
+ this.updateViewport(type, true);
2510
2834
  }
2511
- // subscribe to grid events to process them accordingly
2512
- subscribe() {
2513
- /** if grouping present and new data source arrived */
2514
- this.addEventListener('beforesourceset', ({ detail }) => this.onDataSet(detail));
2515
- this.addEventListener('beforecolumnsset', ({ detail }) => this.setColumns(detail));
2516
- /**
2517
- * filter applied need to clear grouping and apply again
2518
- * based on new results can be new grouping
2519
- */
2520
- this.addEventListener('beforetrimmed', ({ detail: { trimmed, trimmedType } }) => this.beforeTrimmedApply(trimmed, trimmedType));
2521
- /**
2522
- * sorting applied need to clear grouping and apply again
2523
- * based on new results whole grouping order will changed
2524
- */
2525
- this.addEventListener('aftersortingapply', () => this.doSourceUpdate(Object.assign({}, this.options)));
2526
- /**
2527
- * Apply logic for focus inside of grouping
2528
- * We can't focus on grouping rows, navigation only inside of groups for now
2529
- */
2530
- this.addEventListener('beforecellfocus', e => this.onFocus(e));
2531
- /**
2532
- * Prevent rgRow drag outside the group
2533
- */
2534
- this.addEventListener('roworderchanged', e => this.onDrag(e));
2535
- /**
2536
- * When grouping expand icon was clicked
2537
- */
2538
- this.addEventListener(GROUP_EXPAND_EVENT, ({ detail }) => this.onExpand(detail));
2835
+ setItemCount(realCount, type) {
2836
+ this.viewports.stores[type].setViewport({ realCount });
2837
+ this.stores[type].setStore({ count: realCount });
2539
2838
  }
2540
2839
  /**
2541
- * Starts global source update with group clearing and applying new one
2542
- * Initiated when need to reapply grouping
2840
+ * Apply trimmed items
2841
+ * @param trimmed - trimmed items
2842
+ * @param type
2543
2843
  */
2544
- doSourceUpdate(options) {
2545
- var _a;
2546
- if (!this.hasProps) {
2547
- return;
2548
- }
2549
- /**
2550
- * Get source without grouping
2551
- * @param newOldIndexMap - provides us mapping with new indexes vs old indexes, we would use it for trimmed mapping
2552
- */
2553
- const { source, prevExpanded, oldNewIndexes } = this.getSource(true);
2554
- /**
2555
- * Group again
2556
- * @param oldNewIndexMap - provides us mapping with new indexes vs old indexes
2557
- */
2558
- const { sourceWithGroups, depth, trimmed, oldNewIndexMap, childrenByGroup, } = gatherGrouping(source, ((_a = this.options) === null || _a === void 0 ? void 0 : _a.props) || [], Object.assign({ prevExpanded }, options));
2559
- // setup source
2560
- this.providers.data.setData(sourceWithGroups, GROUPING_ROW_TYPE, this.revogrid.disableVirtualY, { depth, customRenderer: options === null || options === void 0 ? void 0 : options.groupLabelTemplate }, true);
2561
- this.updateTrimmed(trimmed, childrenByGroup, oldNewIndexes !== null && oldNewIndexes !== void 0 ? oldNewIndexes : {}, oldNewIndexMap);
2844
+ setTrimmed(trimmed, type) {
2845
+ const allTrimmed = gatherTrimmedItems(trimmed);
2846
+ const dimStoreType = this.stores[type];
2847
+ dimStoreType.setStore({ trimmed: allTrimmed });
2848
+ this.updateViewport(type, true);
2562
2849
  }
2563
2850
  /**
2564
- * Apply grouping on data set
2565
- * Clear grouping from source
2566
- * If source came from other plugin
2851
+ * Sets dimension data and view port coordinate
2852
+ * @param itemCount
2853
+ * @param type - dimension type
2854
+ * @param noVirtual - disable virtual data
2567
2855
  */
2568
- onDataSet(data) {
2569
- var _a;
2570
- if (!this.hasProps || !(data === null || data === void 0 ? void 0 : data.source) || !data.source.length) {
2571
- return;
2856
+ setData(itemCount, type, noVirtual = false) {
2857
+ this.setItemCount(itemCount, type);
2858
+ // Virtualization will get disabled
2859
+ if (noVirtual) {
2860
+ const dimension = this.stores[type].getCurrentState();
2861
+ this.viewports.stores[type].setViewport({
2862
+ virtualSize: dimension.realSize,
2863
+ });
2572
2864
  }
2573
- const source = data.source.filter(s => !isGrouping(s));
2574
- const expanded = this.revogrid.grouping || {};
2575
- const { sourceWithGroups, depth, trimmed, oldNewIndexMap, childrenByGroup, } = gatherGrouping(source, ((_a = this.options) === null || _a === void 0 ? void 0 : _a.props) || [], Object.assign({}, (expanded || {})));
2576
- data.source = sourceWithGroups;
2577
- this.providers.data.setGrouping({ depth });
2578
- this.updateTrimmed(trimmed, childrenByGroup, oldNewIndexMap);
2865
+ this.updateViewport(type);
2579
2866
  }
2580
- // apply grouping
2581
- setGrouping(options) {
2582
- // unsubscribe from all events when group applied
2583
- this.clearSubscriptions();
2584
- this.options = options;
2585
- // clear props, no grouping exists
2586
- if (!options.props || !Object.keys(options.props).length) {
2587
- this.clearGrouping();
2588
- return;
2867
+ applyNewColumns(columns, disableVirtualX) {
2868
+ for (let type of columnTypes) {
2869
+ // clear existing data
2870
+ this.stores[type].drop();
2871
+ const items = columns[type];
2872
+ // for pinned col no need virtual data
2873
+ const noVirtual = type !== 'rgCol' || disableVirtualX;
2874
+ // setItemCount
2875
+ this.stores[type].setStore({ count: items.length });
2876
+ // setCustomSizes
2877
+ const newSizes = getColumnSizes(items);
2878
+ this.stores[type].setDimensionSize(newSizes);
2879
+ const vpUpdate = {
2880
+ // this triggers drop on realCount change
2881
+ realCount: items.length,
2882
+ };
2883
+ // Virtualization will get disabled
2884
+ if (noVirtual) {
2885
+ vpUpdate.virtualSize = this.stores[type].getCurrentState().realSize;
2886
+ }
2887
+ this.viewports.stores[type].setViewport(vpUpdate);
2888
+ this.setViewPortCoordinate({
2889
+ coordinate: this.viewports.stores[type].lastCoordinate,
2890
+ type,
2891
+ });
2589
2892
  }
2590
- // props exist and source inited
2591
- const { source } = this.getSource();
2592
- if (source.length) {
2593
- this.doSourceUpdate(Object.assign({}, options));
2893
+ }
2894
+ getFullSize() {
2895
+ var _a, _b;
2896
+ let x = 0;
2897
+ let y = 0;
2898
+ for (let type of columnTypes) {
2899
+ x += ((_a = this.stores[type]) === null || _a === void 0 ? void 0 : _a.store.get('realSize')) || 0;
2594
2900
  }
2595
- // props exist and columns inited
2596
- for (let t of columnTypes) {
2597
- if (this.setColumnGrouping(this.providers.column.getColumns(t))) {
2598
- this.providers.column.refreshByType(t);
2599
- break;
2600
- }
2901
+ for (let type of rowTypes) {
2902
+ y += ((_b = this.stores[type]) === null || _b === void 0 ? void 0 : _b.store.get('realSize')) || 0;
2601
2903
  }
2602
- // if has any grouping subscribe to events again
2603
- this.subscribe();
2904
+ return { y, x };
2604
2905
  }
2605
- // clear grouping
2606
- clearGrouping() {
2607
- // clear columns
2608
- columnTypes.forEach(t => {
2609
- const cols = this.providers.column.getColumns(t);
2610
- let deleted = false;
2611
- cols.forEach(c => {
2612
- if (isGroupingColumn(c)) {
2613
- delete c[PSEUDO_GROUP_COLUMN];
2614
- deleted = true;
2615
- }
2616
- });
2617
- // if column store had grouping clear and refresh
2618
- if (deleted) {
2619
- this.providers.column.refreshByType(t);
2620
- }
2906
+ updateViewport(type, force = false) {
2907
+ this.setViewPortCoordinate({
2908
+ coordinate: this.viewports.stores[type].lastCoordinate,
2909
+ type,
2910
+ force,
2621
2911
  });
2622
- // clear rows
2623
- const { source, oldNewIndexes } = this.getSource(true);
2624
- this.providers.data.setData(source, GROUPING_ROW_TYPE, this.revogrid.disableVirtualY, undefined, true);
2625
- this.updateTrimmed(undefined, undefined, oldNewIndexes);
2626
2912
  }
2627
- updateTrimmed(trimmedGroup = {}, _childrenByGroup = {}, firstLevelMap = {}, secondLevelMap) {
2628
- // map previously trimmed data
2629
- const trimemedOptionsToUpgrade = processDoubleConversionTrimmed(this.trimmed, firstLevelMap, secondLevelMap);
2630
- for (let type in trimemedOptionsToUpgrade) {
2631
- this.revogrid.addTrimmed(trimemedOptionsToUpgrade[type], type);
2913
+ setViewPortCoordinate({ coordinate, type, force = false, }) {
2914
+ const dimension = this.stores[type].getCurrentState();
2915
+ this.viewports.stores[type].setViewPortCoordinate(coordinate, dimension, force);
2916
+ }
2917
+ getViewPortPos(e) {
2918
+ const dimension = this.stores[e.dimension].getCurrentState();
2919
+ const item = getItemByIndex(dimension, e.coordinate);
2920
+ return item.start;
2921
+ }
2922
+ setSettings(data, dimensionType) {
2923
+ let stores = [];
2924
+ switch (dimensionType) {
2925
+ case 'rgCol':
2926
+ stores = columnTypes;
2927
+ break;
2928
+ case 'rgRow':
2929
+ stores = rowTypes;
2930
+ break;
2632
2931
  }
2633
- // const emptyGroups = this.filterOutEmptyGroups(trimemedOptionsToUpgrade, childrenByGroup);
2634
- // setup trimmed data for grouping
2635
- this.revogrid.addTrimmed(Object.assign({}, trimmedGroup), TRIMMED_GROUPING);
2932
+ for (let s of stores) {
2933
+ this.stores[s].setStore(data);
2934
+ }
2935
+ }
2936
+ }
2937
+
2938
+ class ViewportProvider {
2939
+ constructor() {
2940
+ this.stores = reduce_1([...rowTypes, ...columnTypes], (sources, k) => {
2941
+ sources[k] = new ViewportStore(k);
2942
+ return sources;
2943
+ }, {});
2944
+ }
2945
+ setViewport(type, data) {
2946
+ this.stores[type].setViewport(data);
2636
2947
  }
2637
2948
  }
2638
2949
 
@@ -2955,126 +3266,37 @@ class OrdererService {
2955
3266
  this.move(pos);
2956
3267
  this.moveTip({ x: event.x, y: event.y });
2957
3268
  (_a = this.el) === null || _a === void 0 ? void 0 : _a.classList.remove('hidden');
2958
- }
2959
- end() {
2960
- var _a;
2961
- (_a = this.el) === null || _a === void 0 ? void 0 : _a.classList.add('hidden');
2962
- }
2963
- move(pos) {
2964
- this.moveElement(pos.end - this.parentY);
2965
- }
2966
- moveTip({ x, y }) {
2967
- if (!this.draggable) {
2968
- return;
2969
- }
2970
- this.draggable.style.left = `${x}px`;
2971
- this.draggable.style.top = `${y}px`;
2972
- }
2973
- moveElement(y) {
2974
- if (!this.rgRow) {
2975
- return;
2976
- }
2977
- this.rgRow.style.transform = `translateY(${y}px)`;
2978
- }
2979
- }
2980
- const OrderRenderer = ({ ref }) => {
2981
- const service = new OrdererService();
2982
- ref(service);
2983
- return (h("div", { class: "draggable-wrapper hidden", ref: e => (service.el = e) },
2984
- h("div", { class: "draggable", ref: el => (service.draggable = el) },
2985
- h("span", { class: "revo-alt-icon" }),
2986
- h("span", { ref: e => (service.text = e) })),
2987
- h("div", { class: "drag-position", ref: e => (service.rgRow = e) })));
2988
- };
2989
-
2990
- class StretchColumn extends BasePlugin {
2991
- constructor(revogrid, providers) {
2992
- super(revogrid, providers);
2993
- this.providers = providers;
2994
- this.stretchedColumn = null;
2995
- // calculate scroll bar size for current user session
2996
- this.scrollSize = getScrollbarSize(document);
2997
- // subscribe to column changes
2998
- const beforecolumnapplied = ({ detail: { columns }, }) => this.applyStretch(columns);
2999
- this.addEventListener('beforecolumnapplied', beforecolumnapplied);
3000
- }
3001
- setScroll({ type, hasScroll }) {
3002
- var _a;
3003
- if (type === 'rgRow' &&
3004
- this.stretchedColumn &&
3005
- ((_a = this.stretchedColumn) === null || _a === void 0 ? void 0 : _a.initialSize) === this.stretchedColumn.size) {
3006
- if (hasScroll) {
3007
- this.stretchedColumn.size -= this.scrollSize;
3008
- this.apply();
3009
- this.dropChanges();
3010
- }
3011
- }
3012
- }
3013
- activateChanges() {
3014
- const setScroll = ({ detail }) => this.setScroll(detail);
3015
- this.addEventListener('scrollchange', setScroll);
3016
- }
3017
- dropChanges() {
3018
- this.stretchedColumn = null;
3019
- this.removeEventListener('scrollchange');
3020
- }
3021
- apply() {
3022
- if (!this.stretchedColumn) {
3023
- return;
3024
- }
3025
- const type = 'rgCol';
3026
- const sizes = this.providers.dimension.stores[type].store.get('sizes');
3027
- this.providers.dimension.setCustomSizes(type, Object.assign(Object.assign({}, sizes), { [this.stretchedColumn.index]: this.stretchedColumn.size }), true);
3028
- }
3029
- /**
3030
- * Apply stretch changes
3031
- */
3032
- applyStretch(columns) {
3033
- // unsubscribe from all events
3034
- this.dropChanges();
3035
- // calculate grid size
3036
- let sizeDifference = this.revogrid.clientWidth - 1;
3037
- each(columns, (_, type) => {
3038
- const realSize = this.providers.dimension.stores[type].store.get('realSize');
3039
- sizeDifference -= realSize;
3040
- });
3041
- if (this.revogrid.rowHeaders) {
3042
- const itemsLength = this.providers.data.stores.rgRow.store.get('source').length;
3043
- const header = this.revogrid.rowHeaders;
3044
- const rowHeaderSize = calculateRowHeaderSize(itemsLength, typeof header === 'object' ? header : undefined);
3045
- if (rowHeaderSize) {
3046
- sizeDifference -= rowHeaderSize;
3047
- }
3048
- }
3049
- if (sizeDifference > 0) {
3050
- // currently plugin accepts last column only
3051
- const index = columns.rgCol.length - 1;
3052
- const last = columns.rgCol[index];
3053
- /**
3054
- * has column
3055
- * no auto size applied
3056
- * size for column shouldn't be defined
3057
- */
3058
- const colSize = (last === null || last === void 0 ? void 0 : last.size) || this.revogrid.colSize || 0;
3059
- const size = sizeDifference + colSize - 1;
3060
- if (last && !last.autoSize && colSize < size) {
3061
- this.stretchedColumn = {
3062
- initialSize: size,
3063
- index,
3064
- size,
3065
- };
3066
- this.apply();
3067
- this.activateChanges();
3068
- }
3269
+ }
3270
+ end() {
3271
+ var _a;
3272
+ (_a = this.el) === null || _a === void 0 ? void 0 : _a.classList.add('hidden');
3273
+ }
3274
+ move(pos) {
3275
+ this.moveElement(pos.end - this.parentY);
3276
+ }
3277
+ moveTip({ x, y }) {
3278
+ if (!this.draggable) {
3279
+ return;
3069
3280
  }
3281
+ this.draggable.style.left = `${x}px`;
3282
+ this.draggable.style.top = `${y}px`;
3283
+ }
3284
+ moveElement(y) {
3285
+ if (!this.rgRow) {
3286
+ return;
3287
+ }
3288
+ this.rgRow.style.transform = `translateY(${y}px)`;
3070
3289
  }
3071
3290
  }
3072
- /**
3073
- * Check plugin type is Stretch
3074
- */
3075
- function isStretchPlugin(plugin) {
3076
- return !!plugin.applyStretch;
3077
- }
3291
+ const OrderRenderer = ({ ref }) => {
3292
+ const service = new OrdererService();
3293
+ ref(service);
3294
+ return (h("div", { class: "draggable-wrapper hidden", ref: e => (service.el = e) },
3295
+ h("div", { class: "draggable", ref: el => (service.draggable = el) },
3296
+ h("span", { class: "revo-alt-icon" }),
3297
+ h("span", { ref: e => (service.text = e) })),
3298
+ h("div", { class: "drag-position", ref: e => (service.rgRow = e) })));
3299
+ };
3078
3300
 
3079
3301
  const rowDefinitionByType = (newVal = []) => {
3080
3302
  const result = {};
@@ -3106,228 +3328,6 @@ const rowDefinitionRemoveByType = (oldVal = []) => {
3106
3328
  return result;
3107
3329
  };
3108
3330
 
3109
- const COLUMN_DRAG_CLASS = 'column-drag-start';
3110
- class ColumnOrderHandler {
3111
- constructor() {
3112
- this.offset = 0;
3113
- }
3114
- renderAutoscroll(_, parent) {
3115
- if (!parent) {
3116
- return;
3117
- }
3118
- this.autoscrollEl = document.createElement('div');
3119
- this.autoscrollEl.classList.add('drag-auto-scroll-y');
3120
- parent.appendChild(this.autoscrollEl);
3121
- }
3122
- autoscroll(pos, dataContainerSize, direction = 'translateX') {
3123
- if (!this.autoscrollEl) {
3124
- return;
3125
- }
3126
- const helperOffset = 10;
3127
- // calculate current y position inside of the grid active holder
3128
- // 3 - size of element + border
3129
- const maxScroll = Math.min(pos + helperOffset, dataContainerSize - 3);
3130
- this.autoscrollEl.style.transform = `${direction}(${maxScroll}px)`;
3131
- this.autoscrollEl.scrollIntoView({
3132
- block: 'nearest',
3133
- inline: 'nearest',
3134
- });
3135
- }
3136
- start(e, { dataEl, gridRect, scrollEl, gridEl }, dir = 'left') {
3137
- gridEl.classList.add(COLUMN_DRAG_CLASS);
3138
- const scrollContainerRect = scrollEl.getBoundingClientRect();
3139
- if (scrollContainerRect) {
3140
- this.offset = scrollContainerRect[dir] - gridRect[dir];
3141
- }
3142
- this.renderAutoscroll(e, dataEl);
3143
- }
3144
- stop(gridEl) {
3145
- var _a;
3146
- gridEl.classList.remove(COLUMN_DRAG_CLASS);
3147
- if (this.element) {
3148
- this.element.hidden = true;
3149
- }
3150
- this.offset = 0;
3151
- (_a = this.autoscrollEl) === null || _a === void 0 ? void 0 : _a.remove();
3152
- this.autoscrollEl = undefined;
3153
- }
3154
- showHandler(pos, size, direction = 'translateX') {
3155
- if (!this.element) {
3156
- return;
3157
- }
3158
- // do not allow overcross top of the scrollable area, header excluded
3159
- if (this.offset) {
3160
- pos = Math.max(pos, this.offset);
3161
- }
3162
- // can not be bigger then grid end
3163
- pos = Math.min(pos, size);
3164
- this.element.style.transform = `${direction}(${pos}px)`;
3165
- this.element.hidden = false;
3166
- }
3167
- render() {
3168
- const el = this.element = document.createElement('div');
3169
- el.classList.add('drag-position-y');
3170
- el.hidden = true;
3171
- return el;
3172
- }
3173
- }
3174
-
3175
- /**
3176
- * Plugin for column manual move
3177
- */
3178
- const COLUMN_CLICK = ON_COLUMN_CLICK;
3179
- const MOVE = 'columndragmousemove';
3180
- const DRAG_END = 'columndragend';
3181
- const BEFORE_DRAG_END = 'beforecolumndragend';
3182
- // use this event subscription to drop D&D for particular columns
3183
- const DRAG_START = 'columndragstart';
3184
- class ColumnPlugin extends BasePlugin {
3185
- constructor(revogrid, providers) {
3186
- super(revogrid, providers);
3187
- this.revogrid = revogrid;
3188
- this.providers = providers;
3189
- this.moveFunc = debounce_1((e) => this.doMove(e), 5);
3190
- this.staticDragData = null;
3191
- this.dragData = null;
3192
- this.localSubscriptions = {};
3193
- this.orderUi = new ColumnOrderHandler();
3194
- revogrid.appendChild(this.orderUi.render());
3195
- revogrid.classList.add('column-draggable');
3196
- // Register events
3197
- this.localSubscriptions['mouseleave'] = {
3198
- target: document,
3199
- callback: (e) => this.onMouseOut(e),
3200
- };
3201
- this.localSubscriptions['mouseup'] = {
3202
- target: document,
3203
- callback: (e) => this.onMouseUp(e),
3204
- };
3205
- this.localSubscriptions['mousemove'] = {
3206
- target: document,
3207
- callback: (e) => this.move(e),
3208
- };
3209
- this.addEventListener(COLUMN_CLICK, ({ detail }) => this.dragStart(detail));
3210
- }
3211
- dragStart({ event, data }) {
3212
- if (event.defaultPrevented) {
3213
- return;
3214
- }
3215
- const { defaultPrevented } = dispatch(this.revogrid, DRAG_START, data);
3216
- // check if allowed to drag particulat column
3217
- if (defaultPrevented) {
3218
- return;
3219
- }
3220
- this.clearOrder();
3221
- const { mouseleave, mouseup, mousemove } = this.localSubscriptions;
3222
- mouseleave.target.addEventListener('mouseleave', mouseleave.callback);
3223
- mouseup.target.addEventListener('mouseup', mouseup.callback);
3224
- const dataEl = event.target.closest('revogr-header');
3225
- const scrollEl = event.target.closest('revogr-viewport-scroll');
3226
- if (!dataEl || !scrollEl) {
3227
- return;
3228
- }
3229
- // no grouping drag and no row header column drag
3230
- if (isColGrouping(data) || data.providers.type === 'rowHeaders') {
3231
- return;
3232
- }
3233
- const cols = this.getDimension(data.pin || 'rgCol');
3234
- const gridRect = this.revogrid.getBoundingClientRect();
3235
- const elRect = dataEl.getBoundingClientRect();
3236
- const startItem = getItemByPosition(cols, getLeftRelative(event.x, gridRect.left, elRect.left - gridRect.left));
3237
- this.staticDragData = {
3238
- startPos: event.x,
3239
- startItem,
3240
- data,
3241
- dataEl,
3242
- scrollEl,
3243
- gridEl: this.revogrid,
3244
- cols,
3245
- };
3246
- this.dragData = this.getData(this.staticDragData);
3247
- mousemove.target.addEventListener('mousemove', mousemove.callback);
3248
- this.orderUi.start(event, Object.assign(Object.assign({}, this.dragData), this.staticDragData));
3249
- }
3250
- doMove(e) {
3251
- if (!this.staticDragData) {
3252
- return;
3253
- }
3254
- const dragData = (this.dragData = this.getData(this.staticDragData));
3255
- if (!dragData) {
3256
- return;
3257
- }
3258
- const start = this.staticDragData.startPos;
3259
- if (Math.abs(start - e.x) > 10) {
3260
- const x = getLeftRelative(e.x, this.dragData.gridRect.left, this.dragData.scrollOffset);
3261
- const rgCol = getItemByPosition(this.staticDragData.cols, x);
3262
- this.orderUi.autoscroll(x, dragData.elRect.width);
3263
- this.orderUi.showHandler(rgCol.end + dragData.scrollOffset, dragData.gridRect.width);
3264
- }
3265
- }
3266
- move(e) {
3267
- dispatch(this.revogrid, MOVE, e);
3268
- // then do move
3269
- this.moveFunc(e);
3270
- }
3271
- onMouseOut(_) {
3272
- this.clearOrder();
3273
- }
3274
- onMouseUp(e) {
3275
- // apply new positions
3276
- if (this.dragData && this.staticDragData) {
3277
- let relativePos = getLeftRelative(e.x, this.dragData.gridRect.left, this.dragData.scrollOffset);
3278
- if (relativePos < 0) {
3279
- relativePos = 0;
3280
- }
3281
- const newPosition = getItemByPosition(this.staticDragData.cols, relativePos);
3282
- const store = this.providers.column.stores[this.dragData.type].store;
3283
- const items = [...store.get('items')];
3284
- // prevent position change if needed
3285
- const { defaultPrevented: stopDrag } = dispatch(this.revogrid, BEFORE_DRAG_END, Object.assign(Object.assign({}, this.staticDragData), { startPosition: this.staticDragData.startItem, newPosition, newItem: store.get('source')[items[this.staticDragData.startItem.itemIndex]] }));
3286
- if (!stopDrag) {
3287
- // todo: if move item out of group remove item from group
3288
- const toMove = items.splice(this.staticDragData.startItem.itemIndex, 1);
3289
- items.splice(newPosition.itemIndex, 0, ...toMove);
3290
- store.set('items', items);
3291
- }
3292
- dispatch(this.revogrid, DRAG_END, this.dragData);
3293
- }
3294
- this.clearOrder();
3295
- }
3296
- clearLocalSubscriptions() {
3297
- each(this.localSubscriptions, ({ target, callback }, key) => target.removeEventListener(key, callback));
3298
- }
3299
- clearOrder() {
3300
- this.staticDragData = null;
3301
- this.dragData = null;
3302
- this.clearLocalSubscriptions();
3303
- this.orderUi.stop(this.revogrid);
3304
- }
3305
- /**
3306
- * Clearing subscription
3307
- */
3308
- clearSubscriptions() {
3309
- super.clearSubscriptions();
3310
- this.clearLocalSubscriptions();
3311
- }
3312
- getData({ gridEl, dataEl, data, }) {
3313
- const gridRect = gridEl.getBoundingClientRect();
3314
- const elRect = dataEl.getBoundingClientRect();
3315
- const scrollOffset = elRect.left - gridRect.left;
3316
- return {
3317
- elRect,
3318
- gridRect,
3319
- type: data.pin || 'rgCol',
3320
- scrollOffset,
3321
- };
3322
- }
3323
- getDimension(type) {
3324
- return this.providers.dimension.stores[type].getCurrentState();
3325
- }
3326
- }
3327
- function getLeftRelative(absoluteX, gridPos, offset) {
3328
- return absoluteX - gridPos - offset;
3329
- }
3330
-
3331
3331
  function isMobileDevice() {
3332
3332
  return /Mobi/i.test(navigator.userAgent) || /Android/i.test(navigator.userAgent) || navigator.maxTouchPoints > 0;
3333
3333
  }
@@ -3407,7 +3407,7 @@ class WCAGPlugin extends BasePlugin {
3407
3407
  }
3408
3408
  }
3409
3409
 
3410
- const revoGridStyleCss = ".revo-drag-icon{width:11px;opacity:0.8}.revo-drag-icon::before{content:\"::\"}.revo-alt-icon{-webkit-mask-image:url(\"data:image/svg+xml,%3C%3Fxml version='1.0' encoding='UTF-8'%3F%3E%3Csvg viewBox='0 0 384 383' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'%3E%3Cg%3E%3Cpath d='M192.4375,383 C197.424479,383 201.663411,381.254557 205.154297,377.763672 L205.154297,377.763672 L264.25,318.667969 C270.234375,312.683594 271.605794,306.075846 268.364258,298.844727 C265.122721,291.613607 259.51237,287.998047 251.533203,287.998047 L251.533203,287.998047 L213.382812,287.998047 L213.382812,212.445312 L288.935547,212.445312 L288.935547,250.595703 C288.935547,258.57487 292.551107,264.185221 299.782227,267.426758 C307.013346,270.668294 313.621094,269.296875 319.605469,263.3125 L319.605469,263.3125 L378.701172,204.216797 C382.192057,200.725911 383.9375,196.486979 383.9375,191.5 C383.9375,186.513021 382.192057,182.274089 378.701172,178.783203 L378.701172,178.783203 L319.605469,119.6875 C313.621094,114.201823 307.013346,112.955078 299.782227,115.947266 C292.551107,118.939453 288.935547,124.42513 288.935547,132.404297 L288.935547,132.404297 L288.935547,170.554688 L213.382812,170.554688 L213.382812,95.0019531 L251.533203,95.0019531 C259.51237,95.0019531 264.998047,91.3863932 267.990234,84.1552734 C270.982422,76.9241536 269.735677,70.3164062 264.25,64.3320312 L264.25,64.3320312 L205.154297,5.23632812 C201.663411,1.74544271 197.424479,0 192.4375,0 C187.450521,0 183.211589,1.74544271 179.720703,5.23632812 L179.720703,5.23632812 L120.625,64.3320312 C114.640625,70.3164062 113.269206,76.9241536 116.510742,84.1552734 C119.752279,91.3863932 125.36263,95.0019531 133.341797,95.0019531 L133.341797,95.0019531 L171.492188,95.0019531 L171.492188,170.554688 L95.9394531,170.554688 L95.9394531,132.404297 C95.9394531,124.42513 92.3238932,118.814779 85.0927734,115.573242 C77.8616536,112.331706 71.2539062,113.703125 65.2695312,119.6875 L65.2695312,119.6875 L6.17382812,178.783203 C2.68294271,182.274089 0.9375,186.513021 0.9375,191.5 C0.9375,196.486979 2.68294271,200.725911 6.17382812,204.216797 L6.17382812,204.216797 L65.2695312,263.3125 C71.2539062,268.798177 77.8616536,270.044922 85.0927734,267.052734 C92.3238932,264.060547 95.9394531,258.57487 95.9394531,250.595703 L95.9394531,250.595703 L95.9394531,212.445312 L171.492188,212.445312 L171.492188,287.998047 L133.341797,287.998047 C125.36263,287.998047 119.876953,291.613607 116.884766,298.844727 C113.892578,306.075846 115.139323,312.683594 120.625,318.667969 L120.625,318.667969 L179.720703,377.763672 C183.211589,381.254557 187.450521,383 192.4375,383 Z'%3E%3C/path%3E%3C/g%3E%3C/svg%3E\");mask-image:url(\"data:image/svg+xml,%3C%3Fxml version='1.0' encoding='UTF-8'%3F%3E%3Csvg viewBox='0 0 384 383' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'%3E%3Cg%3E%3Cpath d='M192.4375,383 C197.424479,383 201.663411,381.254557 205.154297,377.763672 L205.154297,377.763672 L264.25,318.667969 C270.234375,312.683594 271.605794,306.075846 268.364258,298.844727 C265.122721,291.613607 259.51237,287.998047 251.533203,287.998047 L251.533203,287.998047 L213.382812,287.998047 L213.382812,212.445312 L288.935547,212.445312 L288.935547,250.595703 C288.935547,258.57487 292.551107,264.185221 299.782227,267.426758 C307.013346,270.668294 313.621094,269.296875 319.605469,263.3125 L319.605469,263.3125 L378.701172,204.216797 C382.192057,200.725911 383.9375,196.486979 383.9375,191.5 C383.9375,186.513021 382.192057,182.274089 378.701172,178.783203 L378.701172,178.783203 L319.605469,119.6875 C313.621094,114.201823 307.013346,112.955078 299.782227,115.947266 C292.551107,118.939453 288.935547,124.42513 288.935547,132.404297 L288.935547,132.404297 L288.935547,170.554688 L213.382812,170.554688 L213.382812,95.0019531 L251.533203,95.0019531 C259.51237,95.0019531 264.998047,91.3863932 267.990234,84.1552734 C270.982422,76.9241536 269.735677,70.3164062 264.25,64.3320312 L264.25,64.3320312 L205.154297,5.23632812 C201.663411,1.74544271 197.424479,0 192.4375,0 C187.450521,0 183.211589,1.74544271 179.720703,5.23632812 L179.720703,5.23632812 L120.625,64.3320312 C114.640625,70.3164062 113.269206,76.9241536 116.510742,84.1552734 C119.752279,91.3863932 125.36263,95.0019531 133.341797,95.0019531 L133.341797,95.0019531 L171.492188,95.0019531 L171.492188,170.554688 L95.9394531,170.554688 L95.9394531,132.404297 C95.9394531,124.42513 92.3238932,118.814779 85.0927734,115.573242 C77.8616536,112.331706 71.2539062,113.703125 65.2695312,119.6875 L65.2695312,119.6875 L6.17382812,178.783203 C2.68294271,182.274089 0.9375,186.513021 0.9375,191.5 C0.9375,196.486979 2.68294271,200.725911 6.17382812,204.216797 L6.17382812,204.216797 L65.2695312,263.3125 C71.2539062,268.798177 77.8616536,270.044922 85.0927734,267.052734 C92.3238932,264.060547 95.9394531,258.57487 95.9394531,250.595703 L95.9394531,250.595703 L95.9394531,212.445312 L171.492188,212.445312 L171.492188,287.998047 L133.341797,287.998047 C125.36263,287.998047 119.876953,291.613607 116.884766,298.844727 C113.892578,306.075846 115.139323,312.683594 120.625,318.667969 L120.625,318.667969 L179.720703,377.763672 C183.211589,381.254557 187.450521,383 192.4375,383 Z'%3E%3C/path%3E%3C/g%3E%3C/svg%3E\");width:11px;height:11px;background-size:cover;background-repeat:no-repeat}.arrow-down{position:absolute;right:5px;top:0}.arrow-down svg{width:8px;margin-top:5px;margin-left:5px;opacity:0.4}.cell-value-wrapper{margin-right:10px;overflow:hidden;text-overflow:ellipsis}.revo-button{position:relative;overflow:hidden;color:#fff;background-color:#6200ee;height:34px;line-height:34px;padding:0 15px;outline:0;border:0;border-radius:7px;box-sizing:border-box;cursor:pointer}.revo-button.green{background-color:#009037;border:1px solid #00772d}.revo-button.red{background-color:#E0662E;border:1px solid #d55920}.revo-button:disabled,.revo-button[disabled]{cursor:not-allowed !important;filter:opacity(0.35) !important}.revo-button.light{border:1px solid #cedefa;line-height:32px;background:none;color:#000;box-shadow:none}revo-grid[theme=default],revo-grid:not([theme]){border:1px solid #cecece;font-size:12px}revo-grid[theme=default] revogr-header,revo-grid:not([theme]) revogr-header{text-align:center;line-height:30px;background-color:#f8f9fa}revo-grid[theme=default] revogr-header .group-rgRow,revo-grid:not([theme]) revogr-header .group-rgRow{box-shadow:none}revo-grid[theme=default] revogr-header .header-rgRow,revo-grid[theme=default] revogr-header .group-rgRow,revo-grid:not([theme]) revogr-header .header-rgRow,revo-grid:not([theme]) revogr-header .group-rgRow{text-transform:uppercase;font-size:12px;color:#000}revo-grid[theme=default] revogr-header .header-rgRow,revo-grid:not([theme]) revogr-header .header-rgRow{height:30px;box-shadow:0 -1px 0 0 #cecece inset}revo-grid[theme=default] revogr-header .rgHeaderCell,revo-grid:not([theme]) revogr-header .rgHeaderCell{box-shadow:-1px 0 0 0 #cecece inset, 0 -1px 0 0 #cecece, 0 -1px 0 0 #cecece inset}revo-grid[theme=default] revogr-header .rgHeaderCell.focused-cell,revo-grid:not([theme]) revogr-header .rgHeaderCell.focused-cell{background:rgba(233, 234, 237, 0.5)}revo-grid[theme=default] .rowHeaders,revo-grid:not([theme]) .rowHeaders{background-color:#f8f9fa}revo-grid[theme=default] .rowHeaders revogr-data .rgCell,revo-grid:not([theme]) .rowHeaders revogr-data .rgCell{color:#000}revo-grid[theme=default] .rowHeaders revogr-data .rgCell:first-child,revo-grid:not([theme]) .rowHeaders revogr-data .rgCell:first-child{box-shadow:0 -1px 0 0 #cecece inset}revo-grid[theme=default] .rowHeaders revogr-data .rgCell:not(:first-child),revo-grid:not([theme]) .rowHeaders revogr-data .rgCell:not(:first-child){box-shadow:0 -1px 0 0 #cecece inset, 1px 0 0 0 #cecece inset}revo-grid[theme=default] .rowHeaders revogr-data .rgCell:last-child,revo-grid:not([theme]) .rowHeaders revogr-data .rgCell:last-child{border-right:1px solid #cecece}revo-grid[theme=default] .rowHeaders revogr-data revogr-header,revo-grid:not([theme]) .rowHeaders revogr-data revogr-header{box-shadow:0 -1px 0 0 #cecece inset}revo-grid[theme=default] revogr-viewport-scroll.colPinStart revogr-data .rgRow .rgCell:last-child,revo-grid:not([theme]) revogr-viewport-scroll.colPinStart revogr-data .rgRow .rgCell:last-child{box-shadow:0 -1px 0 0 #e2e3e3 inset, -1px 0 0 0 #cecece inset}revo-grid[theme=default] revogr-viewport-scroll.colPinStart .footer-wrapper revogr-data .rgRow:first-child .rgCell,revo-grid:not([theme]) revogr-viewport-scroll.colPinStart .footer-wrapper revogr-data .rgRow:first-child .rgCell{box-shadow:0 1px 0 0 #cecece inset, -1px 0 0 0 #cecece inset}revo-grid[theme=default] revogr-viewport-scroll.colPinEnd,revo-grid[theme=default] revogr-viewport-scroll.colPinEnd revogr-header,revo-grid:not([theme]) revogr-viewport-scroll.colPinEnd,revo-grid:not([theme]) revogr-viewport-scroll.colPinEnd revogr-header{box-shadow:1px 0 0 #cecece inset}revo-grid[theme=default] .footer-wrapper revogr-data .rgRow:first-child .rgCell,revo-grid:not([theme]) .footer-wrapper revogr-data .rgRow:first-child .rgCell{box-shadow:0 1px 0 0 #e2e3e3 inset, -1px 0 0 0 #e2e3e3 inset, 0 -1px 0 0 #e2e3e3 inset}revo-grid[theme=default] revogr-data,revo-grid:not([theme]) revogr-data{text-align:center}revo-grid[theme=default] revogr-data .revo-draggable,revo-grid:not([theme]) revogr-data .revo-draggable{float:left}revo-grid[theme=default] revogr-data .rgRow,revo-grid:not([theme]) revogr-data .rgRow{line-height:27px}revo-grid[theme=default] revogr-data .rgRow.focused-rgRow,revo-grid:not([theme]) revogr-data .rgRow.focused-rgRow{background-color:rgba(233, 234, 237, 0.5)}revo-grid[theme=default] revogr-data .rgCell,revo-grid:not([theme]) revogr-data .rgCell{box-shadow:0 -1px 0 0 #e2e3e3 inset, -1px 0 0 0 #e2e3e3 inset}revo-grid[theme=default] revogr-data .rgCell.disabled,revo-grid:not([theme]) revogr-data .rgCell.disabled{background-color:0 -1px 0 0 #e2e3e3 inset, -1px 0 0 0 #e2e3e3 inset}revo-grid[theme=material]{font-family:Nunito, -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\"}revo-grid[theme=material] revogr-header{line-height:50px;font-weight:600;text-align:left}revo-grid[theme=material] revogr-header .rgHeaderCell{padding:0 15px;text-overflow:ellipsis}revo-grid[theme=material] revogr-header .header-rgRow{height:50px}revo-grid[theme=material] revogr-data{text-align:left}revo-grid[theme=material] revogr-data .rgRow{line-height:42px}revo-grid[theme=material] revogr-data .rgCell{padding:0 15px}revo-grid[theme=material] .rowHeaders{background-color:#f7faff}revo-grid[theme=material] .rowHeaders revogr-data .rgCell{color:#757a82}revo-grid[theme=material] revogr-header .header-rgRow.group{box-shadow:0 -1px 0 0 #f1f1f1 inset}revo-grid[theme=material] revogr-header .header-rgRow:not(.group){box-shadow:0 -1px 0 0 #f1f1f1, 0 -1px 0 0 #f1f1f1 inset}revo-grid[theme=material] revogr-header .rgHeaderCell.sortable:hover{background-color:#f1f1f1}revo-grid[theme=material] revogr-header .rgHeaderCell.focused-cell{background:rgba(233, 234, 237, 0.5)}revo-grid[theme=material] .footer-wrapper revogr-data{box-shadow:0 -1px 0 #f1f1f1}revo-grid[theme=material] revogr-viewport-scroll.colPinStart{box-shadow:-1px 0 0 #f1f1f1 inset}revo-grid[theme=material] revogr-viewport-scroll.colPinEnd{box-shadow:-1px 0 0 #f1f1f1}revo-grid[theme=material] revogr-data .rgRow{box-shadow:0 -1px 0 0 #f1f1f1 inset}revo-grid[theme=material] revogr-data .rgRow.focused-rgRow{background-color:rgba(233, 234, 237, 0.5)}revo-grid[theme=material] revogr-data .rgCell{color:rgba(0, 0, 0, 0.87)}revo-grid[theme=material] revogr-data .rgCell.disabled{background-color:#f7f7f7}revo-grid[theme=darkMaterial]{font-family:Nunito, -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\";color:#d8d8d8}revo-grid[theme=darkMaterial] revogr-header{line-height:50px;font-weight:600;text-align:left}revo-grid[theme=darkMaterial] revogr-header .rgHeaderCell{padding:0 15px;text-overflow:ellipsis}revo-grid[theme=darkMaterial] revogr-header .header-rgRow{height:50px}revo-grid[theme=darkMaterial] revogr-data{text-align:left}revo-grid[theme=darkMaterial] revogr-data .rgRow{line-height:42px}revo-grid[theme=darkMaterial] revogr-data .rgCell{padding:0 15px}revo-grid[theme=darkMaterial] .rowHeaders{background-color:rgba(40, 39, 43, 0.8)}revo-grid[theme=darkMaterial] .rowHeaders revogr-data .rgCell{color:rgba(216, 216, 216, 0.8)}revo-grid[theme=darkMaterial] revogr-header .header-rgRow.group{box-shadow:0 -1px 0 0 #404040 inset}revo-grid[theme=darkMaterial] revogr-header .header-rgRow:not(.group){box-shadow:0 -1px 0 0 #404040, 0 -1px 0 0 #404040 inset}revo-grid[theme=darkMaterial] revogr-header .rgHeaderCell.sortable:hover{background-color:rgba(64, 64, 64, 0.5)}revo-grid[theme=darkMaterial] revogr-header .rgHeaderCell.focused-cell{background:rgba(115, 148, 160, 0.15)}revo-grid[theme=darkMaterial] .footer-wrapper revogr-data{box-shadow:0 -1px 0 #404040}revo-grid[theme=darkMaterial] revogr-data .rgCell{color:rgba(216, 216, 216, 0.9)}revo-grid[theme=darkMaterial] revogr-data .rgRow{box-shadow:0 -1px 0 0 #404040 inset}revo-grid[theme=darkMaterial] revogr-data .rgRow.focused-rgRow{background-color:rgba(115, 148, 160, 0.15)}revo-grid[theme=darkMaterial] revogr-viewport-scroll.colPinStart{box-shadow:-1px 0 0 #404040 inset}revo-grid[theme=darkMaterial] revogr-viewport-scroll.colPinEnd{box-shadow:-1px 0 0 #404040}revo-grid[theme=darkCompact]{font-family:Nunito, -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\";color:#d8d8d8}revo-grid[theme=darkCompact] revogr-header{line-height:45px;font-weight:600;text-align:left}revo-grid[theme=darkCompact] revogr-header .rgHeaderCell{padding:0 15px;text-overflow:ellipsis}revo-grid[theme=darkCompact] revogr-header .header-rgRow{height:45px}revo-grid[theme=darkCompact] revogr-data{text-align:left}revo-grid[theme=darkCompact] revogr-data .rgRow{line-height:32px}revo-grid[theme=darkCompact] revogr-data .rgCell{padding:0 15px}revo-grid[theme=darkCompact] .rowHeaders{background-color:rgba(40, 39, 43, 0.8)}revo-grid[theme=darkCompact] .rowHeaders revogr-data .rgCell{color:rgba(216, 216, 216, 0.8)}revo-grid[theme=darkCompact] revogr-header .header-rgRow.group{box-shadow:0 -1px 0 0 #404040 inset}revo-grid[theme=darkCompact] revogr-header .header-rgRow:not(.group){box-shadow:0 -1px 0 0 #404040, 0 -1px 0 0 #404040 inset}revo-grid[theme=darkCompact] revogr-header .rgHeaderCell.sortable:hover{background-color:rgba(64, 64, 64, 0.5)}revo-grid[theme=darkCompact] revogr-header .rgHeaderCell.focused-cell{background:rgba(115, 148, 160, 0.15)}revo-grid[theme=darkCompact] .footer-wrapper revogr-data{box-shadow:0 -1px 0 #404040}revo-grid[theme=darkCompact] revogr-data .rgCell{color:rgba(216, 216, 216, 0.9)}revo-grid[theme=darkCompact] revogr-data .rgRow{box-shadow:0 -1px 0 0 #404040 inset}revo-grid[theme=darkCompact] revogr-data .rgRow.focused-rgRow{background-color:rgba(115, 148, 160, 0.15)}revo-grid[theme=darkCompact] revogr-viewport-scroll.colPinStart{box-shadow:-1px 0 0 #404040 inset}revo-grid[theme=darkCompact] revogr-viewport-scroll.colPinEnd{box-shadow:-1px 0 0 #404040}revo-grid[theme=compact]{font-family:Nunito, -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\"}revo-grid[theme=compact] revogr-header{line-height:45px;font-weight:600;text-align:left}revo-grid[theme=compact] revogr-header .rgHeaderCell{padding:0 15px;text-overflow:ellipsis}revo-grid[theme=compact] revogr-header .header-rgRow{height:45px}revo-grid[theme=compact] revogr-data{text-align:left}revo-grid[theme=compact] revogr-data .rgRow{line-height:32px}revo-grid[theme=compact] revogr-data .rgCell{padding:0 15px}revo-grid[theme=compact] .rowHeaders{background-color:#f7faff}revo-grid[theme=compact] .rowHeaders revogr-data .rgCell{color:#757a82}revo-grid[theme=compact] revogr-header .header-rgRow.group{box-shadow:0 -1px 0 0 #f1f1f1 inset}revo-grid[theme=compact] revogr-header .header-rgRow:not(.group){box-shadow:0 -1px 0 0 #f1f1f1, 0 -1px 0 0 #f1f1f1 inset}revo-grid[theme=compact] revogr-header .rgHeaderCell.sortable:hover{background-color:#f1f1f1}revo-grid[theme=compact] revogr-header .rgHeaderCell.focused-cell{background:rgba(233, 234, 237, 0.5)}revo-grid[theme=compact] .footer-wrapper revogr-data{box-shadow:0 -1px 0 #f1f1f1}revo-grid[theme=compact] revogr-viewport-scroll.colPinStart{box-shadow:-1px 0 0 #f1f1f1 inset}revo-grid[theme=compact] revogr-viewport-scroll.colPinEnd{box-shadow:-1px 0 0 #f1f1f1}revo-grid[theme=compact] revogr-data .rgRow{box-shadow:0 -1px 0 0 #f1f1f1 inset}revo-grid[theme=compact] revogr-data .rgRow.focused-rgRow{background-color:rgba(233, 234, 237, 0.5)}revo-grid[theme=compact] revogr-data .rgCell{color:rgba(0, 0, 0, 0.87)}revo-grid[theme=compact] revogr-data .rgCell.disabled{background-color:#f7f7f7}revo-grid[theme=compact] revo-dropdown .rv-dr-root{padding:0px 9px}revo-grid{display:block;height:100%;min-height:300px;font-family:Helvetica, Arial, Sans-Serif, serif;font-size:14px;position:relative;-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;display:flex;flex-direction:column;width:100%;height:100%}revo-grid .attribution{position:absolute;top:0;left:0;right:0;z-index:100;width:0;height:0;border-left:4px solid rgba(38, 106, 232, 0.6);border-top:4px solid rgba(38, 106, 232, 0.6);border-bottom:4px solid transparent;border-right:4px solid transparent;cursor:pointer}revo-grid .attribution .value{position:absolute;top:0;left:0;background-color:rgba(255, 255, 255, 0.9);padding:4px;border-radius:4px;box-shadow:0 1px 10px rgba(0, 0, 0, 0.2);white-space:nowrap;text-decoration:none;color:black;letter-spacing:0.3px;font-size:11px;opacity:0;width:4px;overflow:hidden;transition:opacity 0.5s ease-in-out, width 0.3s ease-in-out}revo-grid .attribution:hover .value{width:63px;opacity:1}revo-grid.column-draggable.column-drag-start:hover,revo-grid.column-draggable.column-drag-start *:hover{cursor:grabbing}revo-grid .footer-wrapper,revo-grid .header-wrapper{width:100%}revo-grid .footer-wrapper revogr-data,revo-grid .header-wrapper revogr-data{z-index:3}revo-grid revo-dropdown{width:100%}revo-grid revo-dropdown .rv-dr-root{max-height:100%}revo-grid revo-dropdown.shrink label{opacity:0}revo-grid .viewports{max-width:100%;display:flex;flex-direction:row;align-items:flex-start;flex-grow:1}revo-grid .main-viewport{flex-grow:1;height:0;display:flex;justify-content:space-between;flex-direction:row}revo-grid .draggable{position:fixed;height:30px;line-height:30px;background:#fff;border-radius:3px;display:block;z-index:100;margin-top:5px;margin-right:-20px;box-shadow:0 4px 20px 0 rgba(0, 0, 0, 0.15);padding-left:20px;padding-right:5px}revo-grid .draggable.hidden{display:none}revo-grid .draggable .revo-alt-icon{background-color:black;position:absolute;left:5px;top:10px}revo-grid .draggable-wrapper.hidden{display:none}revo-grid .drag-position{position:absolute;left:0;right:0;height:1px;z-index:2;background:gray;pointer-events:none}revo-grid .drag-position-y{position:absolute;top:0;left:0;bottom:0;width:1px;z-index:2;background:gray;pointer-events:none}revo-grid .drag-auto-scroll-y{pointer-events:none;position:absolute;left:0;top:0;height:50px;width:1px}revo-grid .clipboard{position:absolute;left:0;top:0}revo-grid revogr-scroll-virtual{position:relative}revo-grid revogr-scroll-virtual.vertical,revo-grid revogr-scroll-virtual.horizontal{z-index:3}";
3410
+ const revoGridStyleCss = ".revo-drag-icon{width:11px;opacity:0.8}.revo-drag-icon::before{content:\"::\"}.revo-alt-icon{-webkit-mask-image:url(\"data:image/svg+xml,%3C%3Fxml version='1.0' encoding='UTF-8'%3F%3E%3Csvg viewBox='0 0 384 383' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'%3E%3Cg%3E%3Cpath d='M192.4375,383 C197.424479,383 201.663411,381.254557 205.154297,377.763672 L205.154297,377.763672 L264.25,318.667969 C270.234375,312.683594 271.605794,306.075846 268.364258,298.844727 C265.122721,291.613607 259.51237,287.998047 251.533203,287.998047 L251.533203,287.998047 L213.382812,287.998047 L213.382812,212.445312 L288.935547,212.445312 L288.935547,250.595703 C288.935547,258.57487 292.551107,264.185221 299.782227,267.426758 C307.013346,270.668294 313.621094,269.296875 319.605469,263.3125 L319.605469,263.3125 L378.701172,204.216797 C382.192057,200.725911 383.9375,196.486979 383.9375,191.5 C383.9375,186.513021 382.192057,182.274089 378.701172,178.783203 L378.701172,178.783203 L319.605469,119.6875 C313.621094,114.201823 307.013346,112.955078 299.782227,115.947266 C292.551107,118.939453 288.935547,124.42513 288.935547,132.404297 L288.935547,132.404297 L288.935547,170.554688 L213.382812,170.554688 L213.382812,95.0019531 L251.533203,95.0019531 C259.51237,95.0019531 264.998047,91.3863932 267.990234,84.1552734 C270.982422,76.9241536 269.735677,70.3164062 264.25,64.3320312 L264.25,64.3320312 L205.154297,5.23632812 C201.663411,1.74544271 197.424479,0 192.4375,0 C187.450521,0 183.211589,1.74544271 179.720703,5.23632812 L179.720703,5.23632812 L120.625,64.3320312 C114.640625,70.3164062 113.269206,76.9241536 116.510742,84.1552734 C119.752279,91.3863932 125.36263,95.0019531 133.341797,95.0019531 L133.341797,95.0019531 L171.492188,95.0019531 L171.492188,170.554688 L95.9394531,170.554688 L95.9394531,132.404297 C95.9394531,124.42513 92.3238932,118.814779 85.0927734,115.573242 C77.8616536,112.331706 71.2539062,113.703125 65.2695312,119.6875 L65.2695312,119.6875 L6.17382812,178.783203 C2.68294271,182.274089 0.9375,186.513021 0.9375,191.5 C0.9375,196.486979 2.68294271,200.725911 6.17382812,204.216797 L6.17382812,204.216797 L65.2695312,263.3125 C71.2539062,268.798177 77.8616536,270.044922 85.0927734,267.052734 C92.3238932,264.060547 95.9394531,258.57487 95.9394531,250.595703 L95.9394531,250.595703 L95.9394531,212.445312 L171.492188,212.445312 L171.492188,287.998047 L133.341797,287.998047 C125.36263,287.998047 119.876953,291.613607 116.884766,298.844727 C113.892578,306.075846 115.139323,312.683594 120.625,318.667969 L120.625,318.667969 L179.720703,377.763672 C183.211589,381.254557 187.450521,383 192.4375,383 Z'%3E%3C/path%3E%3C/g%3E%3C/svg%3E\");mask-image:url(\"data:image/svg+xml,%3C%3Fxml version='1.0' encoding='UTF-8'%3F%3E%3Csvg viewBox='0 0 384 383' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'%3E%3Cg%3E%3Cpath d='M192.4375,383 C197.424479,383 201.663411,381.254557 205.154297,377.763672 L205.154297,377.763672 L264.25,318.667969 C270.234375,312.683594 271.605794,306.075846 268.364258,298.844727 C265.122721,291.613607 259.51237,287.998047 251.533203,287.998047 L251.533203,287.998047 L213.382812,287.998047 L213.382812,212.445312 L288.935547,212.445312 L288.935547,250.595703 C288.935547,258.57487 292.551107,264.185221 299.782227,267.426758 C307.013346,270.668294 313.621094,269.296875 319.605469,263.3125 L319.605469,263.3125 L378.701172,204.216797 C382.192057,200.725911 383.9375,196.486979 383.9375,191.5 C383.9375,186.513021 382.192057,182.274089 378.701172,178.783203 L378.701172,178.783203 L319.605469,119.6875 C313.621094,114.201823 307.013346,112.955078 299.782227,115.947266 C292.551107,118.939453 288.935547,124.42513 288.935547,132.404297 L288.935547,132.404297 L288.935547,170.554688 L213.382812,170.554688 L213.382812,95.0019531 L251.533203,95.0019531 C259.51237,95.0019531 264.998047,91.3863932 267.990234,84.1552734 C270.982422,76.9241536 269.735677,70.3164062 264.25,64.3320312 L264.25,64.3320312 L205.154297,5.23632812 C201.663411,1.74544271 197.424479,0 192.4375,0 C187.450521,0 183.211589,1.74544271 179.720703,5.23632812 L179.720703,5.23632812 L120.625,64.3320312 C114.640625,70.3164062 113.269206,76.9241536 116.510742,84.1552734 C119.752279,91.3863932 125.36263,95.0019531 133.341797,95.0019531 L133.341797,95.0019531 L171.492188,95.0019531 L171.492188,170.554688 L95.9394531,170.554688 L95.9394531,132.404297 C95.9394531,124.42513 92.3238932,118.814779 85.0927734,115.573242 C77.8616536,112.331706 71.2539062,113.703125 65.2695312,119.6875 L65.2695312,119.6875 L6.17382812,178.783203 C2.68294271,182.274089 0.9375,186.513021 0.9375,191.5 C0.9375,196.486979 2.68294271,200.725911 6.17382812,204.216797 L6.17382812,204.216797 L65.2695312,263.3125 C71.2539062,268.798177 77.8616536,270.044922 85.0927734,267.052734 C92.3238932,264.060547 95.9394531,258.57487 95.9394531,250.595703 L95.9394531,250.595703 L95.9394531,212.445312 L171.492188,212.445312 L171.492188,287.998047 L133.341797,287.998047 C125.36263,287.998047 119.876953,291.613607 116.884766,298.844727 C113.892578,306.075846 115.139323,312.683594 120.625,318.667969 L120.625,318.667969 L179.720703,377.763672 C183.211589,381.254557 187.450521,383 192.4375,383 Z'%3E%3C/path%3E%3C/g%3E%3C/svg%3E\");width:11px;height:11px;background-size:cover;background-repeat:no-repeat}.arrow-down{position:absolute;right:5px;top:0}.arrow-down svg{width:8px;margin-top:5px;margin-left:5px;opacity:0.4}.cell-value-wrapper{margin-right:10px;overflow:hidden;text-overflow:ellipsis}.revo-button{position:relative;overflow:hidden;color:#fff;background-color:#6200ee;height:34px;line-height:34px;padding:0 15px;outline:0;border:0;border-radius:7px;box-sizing:border-box;cursor:pointer}.revo-button.green{background-color:#009037;border:1px solid #00772d}.revo-button.red{background-color:#E0662E;border:1px solid #d55920}.revo-button:disabled,.revo-button[disabled]{cursor:not-allowed !important;filter:opacity(0.35) !important}.revo-button.light{border:1px solid #cedefa;line-height:32px;background:none;color:#000;box-shadow:none}revo-grid[theme=default],revo-grid:not([theme]){border:1px solid #cecece;font-size:12px}revo-grid[theme=default] revogr-header,revo-grid:not([theme]) revogr-header{text-align:center;line-height:30px;background-color:#f8f9fa}revo-grid[theme=default] revogr-header .group-rgRow,revo-grid:not([theme]) revogr-header .group-rgRow{box-shadow:none}revo-grid[theme=default] revogr-header .header-rgRow,revo-grid[theme=default] revogr-header .group-rgRow,revo-grid:not([theme]) revogr-header .header-rgRow,revo-grid:not([theme]) revogr-header .group-rgRow{text-transform:uppercase;font-size:12px;color:#000}revo-grid[theme=default] revogr-header .header-rgRow,revo-grid:not([theme]) revogr-header .header-rgRow{height:30px;box-shadow:0 -1px 0 0 #cecece inset}revo-grid[theme=default] revogr-header .rgHeaderCell,revo-grid:not([theme]) revogr-header .rgHeaderCell{box-shadow:-1px 0 0 0 #cecece inset, 0 -1px 0 0 #cecece, 0 -1px 0 0 #cecece inset}revo-grid[theme=default] revogr-header .rgHeaderCell.focused-cell,revo-grid:not([theme]) revogr-header .rgHeaderCell.focused-cell{background:rgba(233, 234, 237, 0.5)}revo-grid[theme=default] .rowHeaders,revo-grid:not([theme]) .rowHeaders{background-color:#f8f9fa}revo-grid[theme=default] .rowHeaders revogr-data .rgCell,revo-grid:not([theme]) .rowHeaders revogr-data .rgCell{color:#000}revo-grid[theme=default] .rowHeaders revogr-data .rgCell:first-child,revo-grid:not([theme]) .rowHeaders revogr-data .rgCell:first-child{box-shadow:0 -1px 0 0 #cecece inset}revo-grid[theme=default] .rowHeaders revogr-data .rgCell:not(:first-child),revo-grid:not([theme]) .rowHeaders revogr-data .rgCell:not(:first-child){box-shadow:0 -1px 0 0 #cecece inset, 1px 0 0 0 #cecece inset}revo-grid[theme=default] .rowHeaders revogr-data .rgCell:last-child,revo-grid:not([theme]) .rowHeaders revogr-data .rgCell:last-child{border-right:1px solid #cecece}revo-grid[theme=default] .rowHeaders revogr-data revogr-header,revo-grid:not([theme]) .rowHeaders revogr-data revogr-header{box-shadow:0 -1px 0 0 #cecece inset}revo-grid[theme=default] revogr-viewport-scroll.colPinStart revogr-data .rgRow .rgCell:last-child,revo-grid:not([theme]) revogr-viewport-scroll.colPinStart revogr-data .rgRow .rgCell:last-child{box-shadow:0 -1px 0 0 #e2e3e3 inset, -1px 0 0 0 #cecece inset}revo-grid[theme=default] revogr-viewport-scroll.colPinStart .footer-wrapper revogr-data .rgRow:first-child .rgCell,revo-grid:not([theme]) revogr-viewport-scroll.colPinStart .footer-wrapper revogr-data .rgRow:first-child .rgCell{box-shadow:0 1px 0 0 #cecece inset, -1px 0 0 0 #cecece inset}revo-grid[theme=default] revogr-viewport-scroll.colPinEnd,revo-grid[theme=default] revogr-viewport-scroll.colPinEnd revogr-header,revo-grid:not([theme]) revogr-viewport-scroll.colPinEnd,revo-grid:not([theme]) revogr-viewport-scroll.colPinEnd revogr-header{box-shadow:1px 0 0 #cecece inset}revo-grid[theme=default] .footer-wrapper revogr-data .rgRow:first-child .rgCell,revo-grid:not([theme]) .footer-wrapper revogr-data .rgRow:first-child .rgCell{box-shadow:0 1px 0 0 #e2e3e3 inset, -1px 0 0 0 #e2e3e3 inset, 0 -1px 0 0 #e2e3e3 inset}revo-grid[theme=default] revogr-data,revo-grid:not([theme]) revogr-data{text-align:center}revo-grid[theme=default] revogr-data .revo-draggable,revo-grid:not([theme]) revogr-data .revo-draggable{float:left}revo-grid[theme=default] revogr-data .rgRow,revo-grid:not([theme]) revogr-data .rgRow{line-height:27px}revo-grid[theme=default] revogr-data .rgRow.focused-rgRow,revo-grid:not([theme]) revogr-data .rgRow.focused-rgRow{background-color:rgba(233, 234, 237, 0.5)}revo-grid[theme=default] revogr-data .rgCell,revo-grid:not([theme]) revogr-data .rgCell{box-shadow:0 -1px 0 0 #e2e3e3 inset, -1px 0 0 0 #e2e3e3 inset}revo-grid[theme=default] revogr-data .rgCell.disabled,revo-grid:not([theme]) revogr-data .rgCell.disabled{background-color:0 -1px 0 0 #e2e3e3 inset, -1px 0 0 0 #e2e3e3 inset}revo-grid[theme=material]{font-family:Nunito, -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\"}revo-grid[theme=material] revogr-header{line-height:50px;font-weight:600;text-align:left}revo-grid[theme=material] revogr-header .rgHeaderCell{padding:0 15px;text-overflow:ellipsis}revo-grid[theme=material] revogr-header .header-rgRow{height:50px}revo-grid[theme=material] revogr-data{text-align:left}revo-grid[theme=material] revogr-data .rgRow{line-height:42px}revo-grid[theme=material] revogr-data .rgCell{padding:0 15px}revo-grid[theme=material] .rowHeaders{background-color:#f7faff}revo-grid[theme=material] .rowHeaders revogr-data .rgCell{color:#757a82}revo-grid[theme=material] revogr-header .header-rgRow.group{box-shadow:0 -1px 0 0 #f1f1f1 inset}revo-grid[theme=material] revogr-header .header-rgRow:not(.group){box-shadow:0 -1px 0 0 #f1f1f1, 0 -1px 0 0 #f1f1f1 inset}revo-grid[theme=material] revogr-header .rgHeaderCell.sortable:hover{background-color:#f1f1f1}revo-grid[theme=material] revogr-header .rgHeaderCell.focused-cell{background:rgba(233, 234, 237, 0.5)}revo-grid[theme=material] .footer-wrapper revogr-data{box-shadow:0 -1px 0 #f1f1f1}revo-grid[theme=material] revogr-viewport-scroll.colPinStart{box-shadow:-1px 0 0 #f1f1f1 inset}revo-grid[theme=material] revogr-viewport-scroll.colPinEnd{box-shadow:-1px 0 0 #f1f1f1}revo-grid[theme=material] revogr-data .rgRow{box-shadow:0 -1px 0 0 #f1f1f1 inset}revo-grid[theme=material] revogr-data .rgRow.focused-rgRow{background-color:rgba(233, 234, 237, 0.5)}revo-grid[theme=material] revogr-data .rgCell{color:rgba(0, 0, 0, 0.87)}revo-grid[theme=material] revogr-data .rgCell.disabled{background-color:#f7f7f7}revo-grid[theme=darkMaterial]{font-family:Nunito, -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\";color:#d8d8d8}revo-grid[theme=darkMaterial] revogr-header{line-height:50px;font-weight:600;text-align:left}revo-grid[theme=darkMaterial] revogr-header .rgHeaderCell{padding:0 15px;text-overflow:ellipsis}revo-grid[theme=darkMaterial] revogr-header .header-rgRow{height:50px}revo-grid[theme=darkMaterial] revogr-data{text-align:left}revo-grid[theme=darkMaterial] revogr-data .rgRow{line-height:42px}revo-grid[theme=darkMaterial] revogr-data .rgCell{padding:0 15px}revo-grid[theme=darkMaterial] .rowHeaders{background-color:rgba(40, 39, 43, 0.8)}revo-grid[theme=darkMaterial] .rowHeaders revogr-data .rgCell{color:rgba(216, 216, 216, 0.8)}revo-grid[theme=darkMaterial] revogr-edit{background-color:#28272b}revo-grid[theme=darkMaterial] revogr-header .header-rgRow.group{box-shadow:0 -1px 0 0 #404040 inset}revo-grid[theme=darkMaterial] revogr-header .header-rgRow:not(.group){box-shadow:0 -1px 0 0 #404040, 0 -1px 0 0 #404040 inset}revo-grid[theme=darkMaterial] revogr-header .rgHeaderCell.sortable:hover{background-color:rgba(64, 64, 64, 0.5)}revo-grid[theme=darkMaterial] revogr-header .rgHeaderCell.focused-cell{background:rgba(115, 148, 160, 0.15)}revo-grid[theme=darkMaterial] .footer-wrapper revogr-data{box-shadow:0 -1px 0 #404040}revo-grid[theme=darkMaterial] revogr-data .rgCell{color:rgba(216, 216, 216, 0.9)}revo-grid[theme=darkMaterial] revogr-data .rgRow{box-shadow:0 -1px 0 0 #404040 inset}revo-grid[theme=darkMaterial] revogr-data .rgRow.focused-rgRow{background-color:rgba(115, 148, 160, 0.15)}revo-grid[theme=darkMaterial] revogr-viewport-scroll.colPinStart{box-shadow:-1px 0 0 #404040 inset}revo-grid[theme=darkMaterial] revogr-viewport-scroll.colPinEnd{box-shadow:-1px 0 0 #404040}revo-grid[theme=darkCompact]{font-family:Nunito, -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\";color:#d8d8d8}revo-grid[theme=darkCompact] revogr-header{line-height:45px;font-weight:600;text-align:left}revo-grid[theme=darkCompact] revogr-header .rgHeaderCell{padding:0 15px;text-overflow:ellipsis}revo-grid[theme=darkCompact] revogr-header .header-rgRow{height:45px}revo-grid[theme=darkCompact] revogr-data{text-align:left}revo-grid[theme=darkCompact] revogr-data .rgRow{line-height:32px}revo-grid[theme=darkCompact] revogr-data .rgCell{padding:0 15px}revo-grid[theme=darkCompact] .rowHeaders{background-color:rgba(40, 39, 43, 0.8)}revo-grid[theme=darkCompact] .rowHeaders revogr-data .rgCell{color:rgba(216, 216, 216, 0.8)}revo-grid[theme=darkCompact] revogr-edit{background-color:#28272b}revo-grid[theme=darkCompact] revogr-header .header-rgRow.group{box-shadow:0 -1px 0 0 #404040 inset}revo-grid[theme=darkCompact] revogr-header .header-rgRow:not(.group){box-shadow:0 -1px 0 0 #404040, 0 -1px 0 0 #404040 inset}revo-grid[theme=darkCompact] revogr-header .rgHeaderCell.sortable:hover{background-color:rgba(64, 64, 64, 0.5)}revo-grid[theme=darkCompact] revogr-header .rgHeaderCell.focused-cell{background:rgba(115, 148, 160, 0.15)}revo-grid[theme=darkCompact] .footer-wrapper revogr-data{box-shadow:0 -1px 0 #404040}revo-grid[theme=darkCompact] revogr-data .rgCell{color:rgba(216, 216, 216, 0.9)}revo-grid[theme=darkCompact] revogr-data .rgRow{box-shadow:0 -1px 0 0 #404040 inset}revo-grid[theme=darkCompact] revogr-data .rgRow.focused-rgRow{background-color:rgba(115, 148, 160, 0.15)}revo-grid[theme=darkCompact] revogr-viewport-scroll.colPinStart{box-shadow:-1px 0 0 #404040 inset}revo-grid[theme=darkCompact] revogr-viewport-scroll.colPinEnd{box-shadow:-1px 0 0 #404040}revo-grid[theme=compact]{font-family:Nunito, -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\"}revo-grid[theme=compact] revogr-header{line-height:45px;font-weight:600;text-align:left}revo-grid[theme=compact] revogr-header .rgHeaderCell{padding:0 15px;text-overflow:ellipsis}revo-grid[theme=compact] revogr-header .header-rgRow{height:45px}revo-grid[theme=compact] revogr-data{text-align:left}revo-grid[theme=compact] revogr-data .rgRow{line-height:32px}revo-grid[theme=compact] revogr-data .rgCell{padding:0 15px}revo-grid[theme=compact] .rowHeaders{background-color:#f7faff}revo-grid[theme=compact] .rowHeaders revogr-data .rgCell{color:#757a82}revo-grid[theme=compact] revogr-header .header-rgRow.group{box-shadow:0 -1px 0 0 #f1f1f1 inset}revo-grid[theme=compact] revogr-header .header-rgRow:not(.group){box-shadow:0 -1px 0 0 #f1f1f1, 0 -1px 0 0 #f1f1f1 inset}revo-grid[theme=compact] revogr-header .rgHeaderCell.sortable:hover{background-color:#f1f1f1}revo-grid[theme=compact] revogr-header .rgHeaderCell.focused-cell{background:rgba(233, 234, 237, 0.5)}revo-grid[theme=compact] .footer-wrapper revogr-data{box-shadow:0 -1px 0 #f1f1f1}revo-grid[theme=compact] revogr-viewport-scroll.colPinStart{box-shadow:-1px 0 0 #f1f1f1 inset}revo-grid[theme=compact] revogr-viewport-scroll.colPinEnd{box-shadow:-1px 0 0 #f1f1f1}revo-grid[theme=compact] revogr-data .rgRow{box-shadow:0 -1px 0 0 #f1f1f1 inset}revo-grid[theme=compact] revogr-data .rgRow.focused-rgRow{background-color:rgba(233, 234, 237, 0.5)}revo-grid[theme=compact] revogr-data .rgCell{color:rgba(0, 0, 0, 0.87)}revo-grid[theme=compact] revogr-data .rgCell.disabled{background-color:#f7f7f7}revo-grid[theme=compact] revo-dropdown .rv-dr-root{padding:0px 9px}revo-grid{display:block;height:100%;min-height:300px;font-family:Helvetica, Arial, Sans-Serif, serif;font-size:14px;position:relative;-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;display:flex;flex-direction:column;width:100%;height:100%}revo-grid .attribution{position:absolute;top:0;left:0;right:0;z-index:100;width:0;height:0;border-left:4px solid rgba(38, 106, 232, 0.6);border-top:4px solid rgba(38, 106, 232, 0.6);border-bottom:4px solid transparent;border-right:4px solid transparent;cursor:pointer}revo-grid .attribution .value{position:absolute;top:0;left:0;background-color:rgba(255, 255, 255, 0.9);padding:4px;border-radius:4px;box-shadow:0 1px 10px rgba(0, 0, 0, 0.2);white-space:nowrap;text-decoration:none;color:black;letter-spacing:0.3px;font-size:11px;opacity:0;width:4px;overflow:hidden;transition:opacity 0.5s ease-in-out, width 0.3s ease-in-out}revo-grid .attribution:hover .value{width:63px;opacity:1}revo-grid.column-draggable.column-drag-start:hover,revo-grid.column-draggable.column-drag-start *:hover{cursor:grabbing}revo-grid .footer-wrapper,revo-grid .header-wrapper{width:100%}revo-grid .footer-wrapper revogr-data,revo-grid .header-wrapper revogr-data{z-index:3}revo-grid revo-dropdown{width:100%}revo-grid revo-dropdown .rv-dr-root{max-height:100%}revo-grid revo-dropdown.shrink label{opacity:0}revo-grid .viewports{max-width:100%;display:flex;flex-direction:row;align-items:flex-start;flex-grow:1}revo-grid .main-viewport{flex-grow:1;height:0;display:flex;justify-content:space-between;flex-direction:row}revo-grid .draggable{position:fixed;height:30px;line-height:30px;background:#fff;border-radius:3px;display:block;z-index:100;margin-top:5px;margin-right:-20px;box-shadow:0 4px 20px 0 rgba(0, 0, 0, 0.15);padding-left:20px;padding-right:5px}revo-grid .draggable.hidden{display:none}revo-grid .draggable .revo-alt-icon{background-color:black;position:absolute;left:5px;top:10px}revo-grid .draggable-wrapper.hidden{display:none}revo-grid .drag-position{position:absolute;left:0;right:0;height:1px;z-index:2;background:gray;pointer-events:none}revo-grid .drag-position-y{position:absolute;top:0;left:0;bottom:0;width:1px;z-index:2;background:gray;pointer-events:none}revo-grid .drag-auto-scroll-y{pointer-events:none;position:absolute;left:0;top:0;height:50px;width:1px}revo-grid .clipboard{position:absolute;left:0;top:0}revo-grid revogr-scroll-virtual{position:relative}revo-grid revogr-scroll-virtual.vertical,revo-grid revogr-scroll-virtual.horizontal{z-index:3}";
3411
3411
  const RevoGridStyle0 = revoGridStyleCss;
3412
3412
 
3413
3413
  const RevoGridComponent = /*@__PURE__*/ proxyCustomElement(class RevoGridComponent extends HTMLElement$1 {
@@ -4326,6 +4326,6 @@ function defineCustomElement$1() {
4326
4326
  const RevoGrid = RevoGridComponent;
4327
4327
  const defineCustomElement = defineCustomElement$1;
4328
4328
 
4329
- export { BasePlugin as B, DimensionStore as D, RevoGrid, ThemeService as T, getColumnSizes as a, isColGrouping as b, columnTypes as c, getColumns as d, defineCustomElement, gatherGroup as e, getColumnByProp as f, getColumnType as g, isRowType as i, rowTypes as r };
4329
+ export { BasePlugin as B, DimensionStore as D, FILTER_TRIMMED_TYPE as F, RevoGrid, ThemeService as T, isStretchPlugin as a, FILTER_CONFIG_CHANGED_EVENT as b, columnTypes as c, FilterPlugin as d, defineCustomElement, getColumnType as e, getColumnSizes as f, getLeftRelative as g, isColGrouping as h, isRowType as i, getColumns as j, gatherGroup as k, getColumnByProp as l, rowTypes as r };
4330
4330
 
4331
4331
  //# sourceMappingURL=revo-grid.js.map