remote_store.js 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538
  1. /**
  2. * DevExtreme (ui/pivot_grid/remote_store.js)
  3. * Version: 19.1.16
  4. * Build date: Tue Oct 18 2022
  5. *
  6. * Copyright (c) 2012 - 2022 Developer Express Inc. ALL RIGHTS RESERVED
  7. * Read about DevExtreme licensing here: https://js.devexpress.com/Licensing/
  8. */
  9. "use strict";
  10. var _type = require("../../core/utils/type");
  11. var _class = require("../../core/class");
  12. var _class2 = _interopRequireDefault(_class);
  13. var _extend = require("../../core/utils/extend");
  14. var _iterator = require("../../core/utils/iterator");
  15. var _data_source = require("../../data/data_source/data_source");
  16. var _deferred = require("../../core/utils/deferred");
  17. var _uiPivot_grid = require("./ui.pivot_grid.utils");
  18. var _date_serialization = require("../../core/utils/date_serialization");
  19. function _interopRequireDefault(obj) {
  20. return obj && obj.__esModule ? obj : {
  21. "default": obj
  22. }
  23. }
  24. function _toConsumableArray(arr) {
  25. return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread()
  26. }
  27. function _nonIterableSpread() {
  28. throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")
  29. }
  30. function _unsupportedIterableToArray(o, minLen) {
  31. if (!o) {
  32. return
  33. }
  34. if ("string" === typeof o) {
  35. return _arrayLikeToArray(o, minLen)
  36. }
  37. var n = Object.prototype.toString.call(o).slice(8, -1);
  38. if ("Object" === n && o.constructor) {
  39. n = o.constructor.name
  40. }
  41. if ("Map" === n || "Set" === n) {
  42. return Array.from(o)
  43. }
  44. if ("Arguments" === n || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) {
  45. return _arrayLikeToArray(o, minLen)
  46. }
  47. }
  48. function _iterableToArray(iter) {
  49. if ("undefined" !== typeof Symbol && null != iter[Symbol.iterator] || null != iter["@@iterator"]) {
  50. return Array.from(iter)
  51. }
  52. }
  53. function _arrayWithoutHoles(arr) {
  54. if (Array.isArray(arr)) {
  55. return _arrayLikeToArray(arr)
  56. }
  57. }
  58. function _arrayLikeToArray(arr, len) {
  59. if (null == len || len > arr.length) {
  60. len = arr.length
  61. }
  62. for (var i = 0, arr2 = new Array(len); i < len; i++) {
  63. arr2[i] = arr[i]
  64. }
  65. return arr2
  66. }
  67. function createGroupingOptions(dimensionOptions, useSortOrder) {
  68. var groupingOptions = [];
  69. (0, _iterator.each)(dimensionOptions, function(index, dimensionOption) {
  70. groupingOptions.push({
  71. selector: dimensionOption.dataField,
  72. groupInterval: dimensionOption.groupInterval,
  73. desc: useSortOrder && "desc" === dimensionOption.sortOrder,
  74. isExpanded: index < dimensionOptions.length - 1
  75. })
  76. });
  77. return groupingOptions
  78. }
  79. function getFieldFilterSelector(field) {
  80. var selector = field.dataField;
  81. var groupInterval = field.groupInterval;
  82. if ("date" === field.dataType && "string" === typeof groupInterval) {
  83. if ("quarter" === groupInterval.toLowerCase()) {
  84. groupInterval = "Month"
  85. }
  86. selector = selector + "." + (0, _uiPivot_grid.capitalizeFirstLetter)(groupInterval)
  87. }
  88. return selector
  89. }
  90. function getIntervalFilterExpression(selector, numericInterval, numericValue, isExcludedFilterType) {
  91. var startFilterValue = [selector, isExcludedFilterType ? "<" : ">=", numericValue];
  92. var endFilterValue = [selector, isExcludedFilterType ? ">=" : "<", numericValue + numericInterval];
  93. return [startFilterValue, isExcludedFilterType ? "or" : "and", endFilterValue]
  94. }
  95. function getFilterExpressionForFilterValue(field, filterValue) {
  96. var selector = getFieldFilterSelector(field);
  97. var isExcludedFilterType = "exclude" === field.filterType;
  98. var expression = [selector, isExcludedFilterType ? "<>" : "=", filterValue];
  99. if ((0, _type.isDefined)(field.groupInterval)) {
  100. if ("string" === typeof field.groupInterval && "quarter" === field.groupInterval.toLowerCase()) {
  101. expression = getIntervalFilterExpression(selector, 3, 3 * (filterValue - 1) + 1, isExcludedFilterType)
  102. } else {
  103. if ("number" === typeof field.groupInterval && "date" !== field.dataType) {
  104. expression = getIntervalFilterExpression(selector, field.groupInterval, filterValue, isExcludedFilterType)
  105. }
  106. }
  107. }
  108. return expression
  109. }
  110. function createFieldFilterExpressions(field, operation) {
  111. var fieldFilterExpressions = [];
  112. if (field.searchValue) {
  113. return [field.dataField, "contains", field.searchValue]
  114. }
  115. if ("exclude" === field.filterType) {
  116. operation = operation || "and"
  117. } else {
  118. operation = operation || "or"
  119. }(0, _iterator.each)(field.filterValues, function(index, filterValue) {
  120. var currentExpression = [];
  121. if (Array.isArray(filterValue)) {
  122. var parseLevelsRecursive = field.levels && field.levels.length;
  123. if (parseLevelsRecursive) {
  124. currentExpression = createFieldFilterExpressions({
  125. filterValues: filterValue,
  126. filterType: field.filterType,
  127. levels: field.levels
  128. }, "and")
  129. }
  130. } else {
  131. var currentField = field.levels ? field.levels[index] : field;
  132. currentExpression = getFilterExpressionForFilterValue(currentField, filterValue)
  133. }
  134. if (!currentExpression.length) {
  135. return
  136. }
  137. if (fieldFilterExpressions.length) {
  138. fieldFilterExpressions.push(operation)
  139. }
  140. fieldFilterExpressions.push(currentExpression)
  141. });
  142. return fieldFilterExpressions
  143. }
  144. function createFilterExpressions(fields) {
  145. var filterExpressions = [];
  146. (0, _iterator.each)(fields, function(_, field) {
  147. var fieldExpressions = createFieldFilterExpressions(field);
  148. if (!fieldExpressions.length) {
  149. return []
  150. }
  151. if (filterExpressions.length) {
  152. filterExpressions.push("and")
  153. }
  154. filterExpressions.push(fieldExpressions)
  155. });
  156. if (1 === filterExpressions.length) {
  157. filterExpressions = filterExpressions[0]
  158. }
  159. return filterExpressions
  160. }
  161. function mergeFilters(filter1, filter2) {
  162. var mergedFilter;
  163. var notEmpty = function(filter) {
  164. return filter && filter.length
  165. };
  166. if (notEmpty(filter1) && notEmpty(filter2)) {
  167. mergedFilter = [filter1, "and", filter2]
  168. } else {
  169. mergedFilter = notEmpty(filter1) ? filter1 : filter2
  170. }
  171. return mergedFilter
  172. }
  173. function createLoadOptions(options, externalFilterExpr, hasRows) {
  174. var filterExpressions = createFilterExpressions(options.filters);
  175. var groupingOptions = createGroupingOptions(options.rows, options.rowTake).concat(createGroupingOptions(options.columns, options.columnTake));
  176. var loadOptions = {
  177. groupSummary: [],
  178. totalSummary: [],
  179. group: groupingOptions.length ? groupingOptions : void 0,
  180. take: groupingOptions.length ? void 0 : 1
  181. };
  182. if (options.rows.length && options.rowTake) {
  183. loadOptions.skip = options.rowSkip;
  184. loadOptions.take = options.rowTake;
  185. loadOptions.requireGroupCount = true
  186. } else {
  187. if (options.columns.length && options.columnTake && !hasRows) {
  188. loadOptions.skip = options.columnSkip;
  189. loadOptions.take = options.columnTake;
  190. loadOptions.requireGroupCount = true
  191. }
  192. }
  193. if (externalFilterExpr) {
  194. filterExpressions = mergeFilters(filterExpressions, externalFilterExpr)
  195. }
  196. if (filterExpressions.length) {
  197. loadOptions.filter = filterExpressions
  198. }(0, _iterator.each)(options.values, function(_, value) {
  199. var summaryOption = {
  200. selector: value.dataField,
  201. summaryType: value.summaryType || "count"
  202. };
  203. loadOptions.groupSummary.push(summaryOption);
  204. options.includeTotalSummary && loadOptions.totalSummary.push(summaryOption)
  205. });
  206. return loadOptions
  207. }
  208. function forEachGroup(data, callback, level) {
  209. data = data || [];
  210. level = level || 0;
  211. for (var i = 0; i < data.length; i++) {
  212. var group = data[i];
  213. callback(group, level);
  214. if (group && group.items && group.items.length) {
  215. forEachGroup(group.items, callback, level + 1)
  216. }
  217. }
  218. }
  219. function setValue(valuesArray, value, rowIndex, columnIndex, dataIndex) {
  220. valuesArray[rowIndex] = valuesArray[rowIndex] || [];
  221. valuesArray[rowIndex][columnIndex] = valuesArray[rowIndex][columnIndex] || [];
  222. if (!(0, _type.isDefined)(valuesArray[rowIndex][columnIndex][dataIndex])) {
  223. valuesArray[rowIndex][columnIndex][dataIndex] = value
  224. }
  225. }
  226. function parseValue(value, field) {
  227. if (field && "number" === field.dataType && (0, _type.isString)(value)) {
  228. return Number(value)
  229. }
  230. if (field && "date" === field.dataType && !field.groupInterval && !(value instanceof Date)) {
  231. return (0, _date_serialization.deserializeDate)(value)
  232. }
  233. return value
  234. }
  235. function parseResult(data, total, descriptions, result) {
  236. var rowPath = [];
  237. var columnPath = [];
  238. var rowHash = result.rowHash;
  239. var columnHash = result.columnHash;
  240. if (total && total.summary) {
  241. (0, _iterator.each)(total.summary, function(index, summary) {
  242. setValue(result.values, summary, result.grandTotalRowIndex, result.grandTotalColumnIndex, index)
  243. })
  244. }
  245. if (total && total.groupCount >= 0) {
  246. var skip = descriptions.rows.length ? descriptions.rowSkip : descriptions.columnSkip;
  247. data = _toConsumableArray(Array(skip)).concat(data);
  248. data.length = total.groupCount
  249. }
  250. function getItem(dataItem, dimensionName, path, level, field) {
  251. var dimensionHash = result[dimensionName + "Hash"];
  252. var parentItemChildren;
  253. var item;
  254. var pathValue = path.slice(0, level + 1).join("/");
  255. if (void 0 !== dimensionHash[pathValue]) {
  256. item = dimensionHash[pathValue]
  257. } else {
  258. item = {
  259. value: parseValue(dataItem.key, field),
  260. index: result[dimensionName + "Index"]++
  261. };
  262. var parentPathValue = path.slice(0, level).join("/");
  263. if (level > 0 && void 0 !== dimensionHash[parentPathValue]) {
  264. var parentItem = dimensionHash[parentPathValue];
  265. parentItemChildren = parentItem.children = parentItem.children || []
  266. } else {
  267. parentItemChildren = result[dimensionName + "s"]
  268. }
  269. parentItemChildren.push(item);
  270. dimensionHash[pathValue] = item
  271. }
  272. return item
  273. }
  274. forEachGroup(data, function(item, level) {
  275. var rowLevel = level >= descriptions.rows.length ? descriptions.rows.length : level;
  276. var columnLevel = level >= descriptions.rows.length ? level - descriptions.rows.length : 0;
  277. var columnItem;
  278. var rowItem;
  279. if (level >= descriptions.rows.length && columnLevel >= descriptions.columns.length) {
  280. return
  281. }
  282. if (level < descriptions.rows.length) {
  283. columnPath = []
  284. }
  285. if (level >= descriptions.rows.length) {
  286. if (item) {
  287. columnPath[columnLevel] = item.key + "";
  288. columnItem = getItem(item, "column", columnPath, columnLevel, descriptions.columns[columnPath.length - 1]);
  289. rowItem = rowHash[rowPath.slice(0, rowLevel + 1).join("/")]
  290. } else {
  291. result.columns.push({})
  292. }
  293. } else {
  294. if (item) {
  295. rowPath[rowLevel] = item.key + "";
  296. rowItem = getItem(item, "row", rowPath, rowLevel);
  297. columnItem = columnHash[columnPath.slice(0, columnLevel + 1).join("/")]
  298. } else {
  299. result.rows.push({})
  300. }
  301. }
  302. var currentRowIndex = rowItem && rowItem.index || result.grandTotalRowIndex;
  303. var currentColumnIndex = columnItem && columnItem.index || result.grandTotalColumnIndex;
  304. (0, _iterator.each)(item && item.summary || [], function(i, summary) {
  305. setValue(result.values, summary, currentRowIndex, currentColumnIndex, i)
  306. })
  307. });
  308. return result
  309. }
  310. function getFiltersForDimension(fields) {
  311. return (fields || []).filter(function(f) {
  312. return f.filterValues && f.filterValues.length || f.searchValue
  313. })
  314. }
  315. function getExpandedIndex(options, axis) {
  316. if (options.headerName) {
  317. if (axis === options.headerName) {
  318. return options.path.length
  319. } else {
  320. if (options.oppositePath) {
  321. return options.oppositePath.length
  322. }
  323. }
  324. }
  325. return 0
  326. }
  327. function getFiltersForExpandedDimension(options) {
  328. return (0, _uiPivot_grid.getFiltersByPath)(options[options.headerName], options.path).concat((0, _uiPivot_grid.getFiltersByPath)(options["rows" === options.headerName ? "columns" : "rows"], options.oppositePath || []))
  329. }
  330. function getExpandedPathSliceFilter(options, dimensionName, level, firstCollapsedFieldIndex) {
  331. var result = [];
  332. var startSliceIndex = level > firstCollapsedFieldIndex ? 0 : firstCollapsedFieldIndex;
  333. var fields = options.headerName !== dimensionName ? options[dimensionName].slice(startSliceIndex, level) : [];
  334. var paths = "rows" === dimensionName ? options.rowExpandedPaths : options.columnExpandedPaths;
  335. (0, _iterator.each)(fields, function(index, field) {
  336. var filterValues = [];
  337. (0, _iterator.each)(paths, function(_, path) {
  338. path = path.slice(startSliceIndex, level);
  339. if (index < path.length) {
  340. filterValues.push(path[index])
  341. }
  342. });
  343. if (filterValues.length) {
  344. result.push((0, _extend.extend)({}, field, {
  345. filterType: "include",
  346. filterValues: filterValues
  347. }))
  348. }
  349. });
  350. return result
  351. }
  352. function getGrandTotalRequest(options, dimensionName, expandedIndex, expandedLevel, commonFilters, firstCollapsedFieldIndex) {
  353. var expandedPaths = ("columns" === dimensionName ? options.columnExpandedPaths : options.rowExpandedPaths) || [];
  354. var oppositeDimensionName = "columns" === dimensionName ? "rows" : "columns";
  355. var fields = options[dimensionName];
  356. var result = [];
  357. var newOptions;
  358. if (expandedPaths.length) {
  359. for (var i = expandedIndex; i < expandedLevel + 1; i++) {
  360. newOptions = {
  361. filters: commonFilters.concat(getExpandedPathSliceFilter(options, dimensionName, i, firstCollapsedFieldIndex))
  362. };
  363. newOptions[dimensionName] = fields.slice(expandedIndex, i + 1);
  364. newOptions[oppositeDimensionName] = [];
  365. result.push((0, _extend.extend)({}, options, newOptions))
  366. }
  367. } else {
  368. newOptions = {
  369. filters: commonFilters
  370. };
  371. newOptions[dimensionName] = fields.slice(expandedIndex, expandedLevel + 1);
  372. newOptions[oppositeDimensionName] = [];
  373. result.push((0, _extend.extend)({}, options, newOptions))
  374. }
  375. result[0].includeTotalSummary = true;
  376. return result
  377. }
  378. function getFirstCollapsedIndex(fields) {
  379. var firstCollapsedIndex = 0;
  380. (0, _iterator.each)(fields, function(index, field) {
  381. if (!field.expanded) {
  382. firstCollapsedIndex = index;
  383. return false
  384. }
  385. });
  386. return firstCollapsedIndex
  387. }
  388. function getRequestsData(options) {
  389. var rowExpandedLevel = (0, _uiPivot_grid.getExpandedLevel)(options, "rows");
  390. var columnExpandedLevel = (0, _uiPivot_grid.getExpandedLevel)(options, "columns");
  391. var filters = options.filters || [];
  392. var columnExpandedIndex = getExpandedIndex(options, "columns");
  393. var firstCollapsedColumnIndex = getFirstCollapsedIndex(options.columns);
  394. var firstCollapsedRowIndex = getFirstCollapsedIndex(options.rows);
  395. var rowExpandedIndex = getExpandedIndex(options, "rows");
  396. var data = [];
  397. filters = filters.concat(getFiltersForDimension(options.rows)).concat(getFiltersForDimension(options.columns)).concat(getFiltersForExpandedDimension(options));
  398. var columnTotalsOptions = getGrandTotalRequest(options, "columns", columnExpandedIndex, columnExpandedLevel, filters, firstCollapsedColumnIndex);
  399. if (options.rows.length && options.columns.length) {
  400. if ("rows" !== options.headerName) {
  401. data = data.concat(columnTotalsOptions)
  402. }
  403. for (var i = rowExpandedIndex; i < rowExpandedLevel + 1; i++) {
  404. var rows = options.rows.slice(rowExpandedIndex, i + 1);
  405. var rowFilterByExpandedPaths = getExpandedPathSliceFilter(options, "rows", i, firstCollapsedRowIndex);
  406. for (var j = columnExpandedIndex; j < columnExpandedLevel + 1; j++) {
  407. var preparedOptions = (0, _extend.extend)({}, options, {
  408. columns: options.columns.slice(columnExpandedIndex, j + 1),
  409. rows: rows,
  410. filters: filters.concat(getExpandedPathSliceFilter(options, "columns", j, firstCollapsedColumnIndex)).concat(rowFilterByExpandedPaths)
  411. });
  412. data.push(preparedOptions)
  413. }
  414. }
  415. } else {
  416. data = options.columns.length ? columnTotalsOptions : getGrandTotalRequest(options, "rows", rowExpandedIndex, rowExpandedLevel, filters, firstCollapsedRowIndex)
  417. }
  418. return data
  419. }
  420. function prepareFields(fields) {
  421. (0, _iterator.each)(fields || [], function(_, field) {
  422. var levels = field.levels;
  423. if (levels) {
  424. prepareFields(levels)
  425. }(0, _uiPivot_grid.setDefaultFieldValueFormatting)(field)
  426. })
  427. }
  428. module.exports = _class2.default.inherit(function() {
  429. return {
  430. ctor: function(options) {
  431. this._dataSource = new _data_source.DataSource(options);
  432. this._store = this._dataSource.store()
  433. },
  434. getFields: function(fields) {
  435. var d = new _deferred.Deferred;
  436. this._store.load({
  437. skip: 0,
  438. take: 20
  439. }).done(function(data) {
  440. d.resolve((0, _uiPivot_grid.discoverObjectFields)(data, fields))
  441. }).fail(d.reject);
  442. return d
  443. },
  444. key: function() {
  445. return this._store.key()
  446. },
  447. load: function(options) {
  448. var that = this;
  449. var d = new _deferred.Deferred;
  450. var result = {
  451. rows: [],
  452. columns: [],
  453. values: [
  454. [
  455. []
  456. ]
  457. ],
  458. grandTotalRowIndex: 0,
  459. grandTotalColumnIndex: 0,
  460. rowHash: {},
  461. columnHash: {},
  462. rowIndex: 1,
  463. columnIndex: 1
  464. };
  465. var requestsData = getRequestsData(options);
  466. var deferreds = [];
  467. prepareFields(options.rows);
  468. prepareFields(options.columns);
  469. prepareFields(options.filters);
  470. (0, _iterator.each)(requestsData, function(_, dataItem) {
  471. deferreds.push(that._store.load(createLoadOptions(dataItem, that.filter(), options.rows.length)))
  472. });
  473. _deferred.when.apply(null, deferreds).done(function() {
  474. var args = deferreds.length > 1 ? arguments : [arguments];
  475. (0, _iterator.each)(args, function(index, argument) {
  476. parseResult(argument[0], argument[1], requestsData[index], result)
  477. });
  478. d.resolve({
  479. rows: result.rows,
  480. columns: result.columns,
  481. values: result.values,
  482. grandTotalRowIndex: result.grandTotalRowIndex,
  483. grandTotalColumnIndex: result.grandTotalColumnIndex
  484. })
  485. }).fail(d.reject);
  486. return d
  487. },
  488. filter: function() {
  489. return this._dataSource.filter.apply(this._dataSource, arguments)
  490. },
  491. supportPaging: function() {
  492. return false
  493. },
  494. createDrillDownDataSource: function(loadOptions, params) {
  495. loadOptions = loadOptions || {};
  496. params = params || {};
  497. var store = this._store;
  498. var filters = (0, _uiPivot_grid.getFiltersByPath)(loadOptions.rows, params.rowPath).concat((0, _uiPivot_grid.getFiltersByPath)(loadOptions.columns, params.columnPath)).concat(getFiltersForDimension(loadOptions.rows)).concat(loadOptions.filters || []).concat(getFiltersForDimension(loadOptions.columns));
  499. var filterExp = createFilterExpressions(filters);
  500. return new _data_source.DataSource({
  501. load: function(loadOptions) {
  502. return store.load((0, _extend.extend)({}, loadOptions, {
  503. filter: mergeFilters(filterExp, loadOptions.filter),
  504. select: params.customColumns
  505. }))
  506. }
  507. })
  508. }
  509. }
  510. }());