dtable-utils
Version:
dtable common utils
401 lines (386 loc) • 16.5 kB
JavaScript
import _defineProperty from '@babel/runtime/helpers/defineProperty';
import _toConsumableArray from '@babel/runtime/helpers/toConsumableArray';
import { isTableRows } from '../row/core.js';
import { getRowsByIds } from '../table/row.js';
import { deleteInvalidGroupby } from './core.js';
import { DateUtils } from '../date.js';
import { isDateColumn } from '../column/date.js';
import { getCollaboratorsNames } from '../cell-value-get/collaborator.js';
import { getGeolocationByGranularity } from '../cell-value-get/geolocation.js';
import { getFormulaDisplayString } from '../cell-value-get/cell-value.js';
import { sortCheckbox } from '../sort/sort-column/checkbox.js';
import { sortCollaborator } from '../sort/sort-column/collaborator.js';
import { sortDate } from '../sort/sort-column/date.js';
import { sortNumber } from '../sort/sort-column/number.js';
import { sortText } from '../sort/sort-column/text.js';
import { CellType } from '../constants/cell-type.js';
import { SINGLE_CELL_VALUE_COLUMN_TYPE_MAP, MULTIPLE_CELL_VALUE_COLUMN_TYPE_MAP, DATE_COLUMN_OPTIONS } from '../constants/column.js';
import { FORMULA_COLUMN_TYPES_MAP, FORMULA_RESULT_TYPE } from '../constants/formula.js';
import { sortFormula } from '../sort/sort-column/formula.js';
import { sortLink } from '../sort/sort-column/link.js';
import { sortDepartment } from '../sort/sort-column/department.js';
import { sortMultipleSelect } from '../sort/sort-column/multiple-select.js';
import { sortSingleSelect } from '../sort/sort-column/single-select.js';
import { MAX_GROUP_LEVEL } from '../constants/group.js';
import { SORT_TYPE, SORT_COLUMN_OPTIONS, TEXT_SORTER_COLUMN_TYPES, NUMBER_SORTER_COLUMN_TYPES } from '../constants/sort.js';
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
var _getCellValue = function _getCellValue(row, formulaRows, groupby) {
var column_key = groupby.column_key,
column = groupby.column;
var cellValue = row[column_key];
var type = column.type;
if (FORMULA_COLUMN_TYPES_MAP[type]) {
var formulaRow = formulaRows[row._id] || {};
return formulaRow[column_key];
}
// link column value is calculate as a special formula column
if (type === CellType.LINK) {
var _formulaRow = formulaRows[row._id] || {};
return _formulaRow[column_key] || [];
}
return cellValue;
};
var _getFormattedCellValue = function _getFormattedCellValue(cellValue, groupby) {
var column = groupby.column,
countType = groupby.count_type;
var columnType = column.type,
columnData = column.data;
switch (columnType) {
case CellType.TEXT:
case CellType.URL:
case CellType.EMAIL:
case CellType.LAST_MODIFIER:
case CellType.CREATOR:
case CellType.DEPARTMENT_SINGLE_SELECT:
{
return cellValue || null;
}
case CellType.DATE:
case CellType.CTIME:
case CellType.MTIME:
{
return DateUtils.getDateByGranularity(cellValue, countType) || null;
}
case CellType.NUMBER:
case CellType.DURATION:
case CellType.RATE:
{
return cellValue || cellValue === 0 ? cellValue : null;
}
case CellType.CHECKBOX:
{
return !!cellValue;
}
case CellType.SINGLE_SELECT:
{
return cellValue || null;
}
case CellType.MULTIPLE_SELECT:
{
return Array.isArray(cellValue) ? cellValue : [];
}
case CellType.COLLABORATOR:
{
return Array.isArray(cellValue) ? cellValue : [];
}
case CellType.GEOLOCATION:
{
return getGeolocationByGranularity(cellValue, countType);
}
case CellType.FORMULA:
case CellType.LINK_FORMULA:
{
var _ref = columnData || {},
result_type = _ref.result_type;
if (result_type === FORMULA_RESULT_TYPE.NUMBER) {
return cellValue || cellValue === 0 ? cellValue : null;
}
if (result_type === FORMULA_RESULT_TYPE.DATE) {
return DateUtils.getDateByGranularity(cellValue, countType) || null;
}
if (result_type === FORMULA_RESULT_TYPE.BOOL) {
return !!cellValue;
}
if (result_type === FORMULA_RESULT_TYPE.ARRAY) {
var newCellValue = cellValue;
if (isDateColumn(column) && Array.isArray(cellValue) && cellValue.length > 0) {
return DateUtils.getDateByGranularity(cellValue[0], countType) || null;
}
// convert to string
return getFormulaDisplayString(newCellValue, columnData) || null;
}
return cellValue || null;
}
case CellType.LINK:
{
if (!Array.isArray(cellValue) || cellValue.length === 0) {
return [];
}
return cellValue.map(function (linked) {
return linked.display_value;
});
}
default:
{
return null;
}
}
};
var _getStrCellValue = function _getStrCellValue(cellValue, columnType) {
var sCellValue = null;
if (SINGLE_CELL_VALUE_COLUMN_TYPE_MAP[columnType]) {
sCellValue = typeof cellValue === 'string' ? cellValue : String(cellValue);
} else if (MULTIPLE_CELL_VALUE_COLUMN_TYPE_MAP[columnType]) {
sCellValue = _toConsumableArray(cellValue).sort().toString();
}
return sCellValue;
};
var _findGroupIndexWithMultipleGroupbys = function _findGroupIndexWithMultipleGroupbys(sCellValue, cellValue2GroupIndexMap, groupsLength) {
var target = cellValue2GroupIndexMap[sCellValue];
if (target && target.index > -1) {
return target.index;
}
// eslint-disable-next-line
cellValue2GroupIndexMap[sCellValue] = {};
// eslint-disable-next-line
cellValue2GroupIndexMap[sCellValue].subgroups = {};
// eslint-disable-next-line
cellValue2GroupIndexMap[sCellValue].index = groupsLength;
return -1;
};
var _findGroupIndex = function _findGroupIndex(sCellValue, cellValue2GroupIndexMap, groupsLength) {
var index = cellValue2GroupIndexMap[sCellValue];
if (index > -1) {
return index;
}
// eslint-disable-next-line
cellValue2GroupIndexMap[sCellValue] = groupsLength;
return -1;
};
var _getSortedGroups = function getSortedGroups(groups, groupbys, value, level) {
var _groupbys$level = groupbys[level],
column = _groupbys$level.column,
sort_type = _groupbys$level.sort_type;
var collaborators = value.collaborators;
var columnType = column.type,
columnData = column.data;
var normalizedSortType = sort_type || SORT_TYPE.UP;
var option_id_index_map = {};
if (columnType === CellType.SINGLE_SELECT || columnType === CellType.MULTIPLE_SELECT) {
var _ref2 = columnData || {},
options = _ref2.options;
if (Array.isArray(options)) {
options.forEach(function (option, index) {
option_id_index_map[option.id] = index;
});
}
}
groups.sort(function (currGroupRow, nextGroupRow) {
var currCellVal = currGroupRow.cell_value;
var nextCellVal = nextGroupRow.cell_value;
if (SORT_COLUMN_OPTIONS.includes(columnType)) {
var sortResult;
if (TEXT_SORTER_COLUMN_TYPES.includes(columnType)) {
sortResult = sortText(currCellVal, nextCellVal, normalizedSortType);
} else if (NUMBER_SORTER_COLUMN_TYPES.includes(columnType)) {
sortResult = sortNumber(currCellVal, nextCellVal, normalizedSortType);
} else if (DATE_COLUMN_OPTIONS.includes(columnType)) {
sortResult = sortDate(currCellVal, nextCellVal, normalizedSortType);
} else if (columnType === CellType.DEPARTMENT_SINGLE_SELECT) {
sortResult = sortDepartment(currCellVal, nextCellVal, normalizedSortType);
} else if (columnType === CellType.CHECKBOX) {
sortResult = sortCheckbox(currCellVal, nextCellVal, normalizedSortType);
} else if (columnType === CellType.COLLABORATOR) {
var currCollaborators = currCellVal;
var nextCollaborators = nextCellVal;
if (collaborators) {
currCollaborators = getCollaboratorsNames(currCollaborators, collaborators);
nextCollaborators = getCollaboratorsNames(nextCollaborators, collaborators);
}
sortResult = sortCollaborator(currCollaborators, nextCollaborators, normalizedSortType);
} else if (columnType === CellType.SINGLE_SELECT) {
sortResult = sortSingleSelect(currCellVal, nextCellVal, {
sort_type: normalizedSortType,
option_id_index_map: option_id_index_map
});
} else if (columnType === CellType.MULTIPLE_SELECT) {
sortResult = sortMultipleSelect(currCellVal, nextCellVal, {
sort_type: normalizedSortType,
option_id_index_map: option_id_index_map
});
} else if (FORMULA_COLUMN_TYPES_MAP[columnType]) {
var currOriginalCellVal = currGroupRow.original_cell_value;
var nextOriginalCellVal = nextGroupRow.original_cell_value;
sortResult = sortFormula(currOriginalCellVal, nextOriginalCellVal, normalizedSortType, {
columnData: columnData,
value: value
});
} else if (columnType === CellType.LINK) {
var _currOriginalCellVal = currGroupRow.original_cell_value;
var _nextOriginalCellVal = nextGroupRow.original_cell_value;
sortResult = sortLink(_currOriginalCellVal, _nextOriginalCellVal, normalizedSortType, {
columnData: columnData,
value: value
});
}
return sortResult;
}
if (currCellVal === '') return 1;
if (nextCellVal === '') return -1;
return 0;
});
// for nested group.
var isNestedGroup = Array.isArray(groups[0].subgroups) && groups[0].subgroups.length > 0;
if (isNestedGroup) {
var nextLevel = level + 1;
// eslint-disable-next-line
groups = groups.map(function (group) {
var sortedSubgroups = _getSortedGroups(group.subgroups, groupbys, value, nextLevel);
return _objectSpread(_objectSpread({}, group), {}, {
subgroups: sortedSubgroups
});
});
}
return groups;
};
var groupRowsWithMultipleGroupbys = function groupRowsWithMultipleGroupbys(groupbys, rows, formulaRows, value) {
var validGroupbys = groupbys.length > MAX_GROUP_LEVEL ? groupbys.slice(0, MAX_GROUP_LEVEL) : _toConsumableArray(groupbys);
var groups = [];
var cellValue2GroupIndexMap = {};
rows.forEach(function (row) {
var rowId = row._id;
var updatedGroup;
var updateCellValue2GroupIndexMap;
for (var level = 0; level < validGroupbys.length; level++) {
var currentGroupby = validGroupbys[level];
var column = currentGroupby.column,
column_key = currentGroupby.column_key;
var columnType = column.type;
var cellValue = _getCellValue(row, formulaRows, currentGroupby);
var formattedValue = _getFormattedCellValue(cellValue, currentGroupby);
var sCellValue = _getStrCellValue(formattedValue, columnType);
var group = {
cell_value: formattedValue,
original_cell_value: cellValue,
row_ids: null,
column_key: column_key,
subgroups: [],
summaries: {}
};
if (level === 0) {
var groupedRowIndex = _findGroupIndexWithMultipleGroupbys(sCellValue, cellValue2GroupIndexMap, groups.length);
updateCellValue2GroupIndexMap = cellValue2GroupIndexMap[sCellValue].subgroups;
if (groupedRowIndex < 0) {
groups.push(group);
updatedGroup = groups[groups.length - 1];
} else {
updatedGroup = groups[groupedRowIndex];
}
} else {
var _groupedRowIndex = _findGroupIndexWithMultipleGroupbys(sCellValue, updateCellValue2GroupIndexMap, updatedGroup.subgroups.length);
updateCellValue2GroupIndexMap = updateCellValue2GroupIndexMap[sCellValue].subgroups;
if (_groupedRowIndex < 0) {
updatedGroup.subgroups.push(group);
updatedGroup = updatedGroup.subgroups[updatedGroup.subgroups.length - 1];
} else {
updatedGroup = updatedGroup.subgroups[_groupedRowIndex];
}
// update row_ids in the deepest group.
if (level === validGroupbys.length - 1) {
if (!updatedGroup.row_ids) {
updatedGroup.row_ids = [rowId];
} else {
updatedGroup.row_ids.push(rowId);
}
}
}
}
});
groups = _getSortedGroups(groups, validGroupbys, value, 0);
return groups;
};
/**
* Group table rows
* @param {array} groupbys e.g. [{ column_key, count_type, column, ... }, ...]
* @param {array} rows e.g. [{ _id, ... }, ...]
* @param {object} formulaRows computed value of formula, link-formula, link etc.
* @param {object} value e.g. { collaborators, ... }
* @returns groups: [{
* cell_value, original_cell_value, column_key,
row_ids, subgroups, summaries, ...}, ...], array
*/
var groupTableRows = function groupTableRows(groupbys, rows, formulaRows, value) {
if (groupbys.length === 0) {
return [];
}
if (groupbys.length > 1) {
return groupRowsWithMultipleGroupbys(groupbys, rows, formulaRows, value);
}
var groupby = groupbys[0];
var column_key = groupby.column_key,
column = groupby.column;
var columnType = column.type;
var groups = [];
var cellValue2GroupIndexMap = {};
rows.forEach(function (r) {
var cellValue = _getCellValue(r, formulaRows, groupby);
var formattedValue = _getFormattedCellValue(cellValue, groupby);
var sCellValue = _getStrCellValue(formattedValue, columnType);
var groupedRowIndex = _findGroupIndex(sCellValue, cellValue2GroupIndexMap, groups.length);
if (groupedRowIndex > -1) {
groups[groupedRowIndex].row_ids.push(r._id);
} else {
groups.push({
cell_value: formattedValue,
original_cell_value: cellValue,
column_key: column_key,
row_ids: [r._id],
subgroups: null,
summaries: {}
});
}
});
// sort groups
groups = _getSortedGroups(groups, groupbys, value, 0);
return groups;
};
/**
* Group view rows
* @param {array} groupbys e.g. [{ column_key, count_type, column, ... }, ...]
* @param {object} table e.g. { id_row_map, ... }
* @param {array} rowsIds e.g. [ row._id, ...]
* @param {object} formulaRows computed value of formula, link-formula, link etc.
* @param {object} value e.g. { collaborators, ... }
* @returns groups: [{
* cell_value, original_cell_value, column_key,
row_ids, subgroups, summaries, ...}, ...], array
*/
var groupViewRows = function groupViewRows(groupbys, table, rowsIds, formulaRows, value) {
if (rowsIds.length === 0) {
return [];
}
var rowsData = getRowsByIds(table, rowsIds);
return groupTableRows(groupbys, rowsData, formulaRows, value);
};
/**
* Group rows
* The "formulaRows" must be supplied if you want group rows by formula/link-formula/link columns
* @param {array} groupbys e.g. [{ column_key, count_type, ... }, ...]
* @param {array} rows e.g. table rows: [{ _id, ... }, ...] | view rows: [ row._id, ...]
* @param {object} table e.g. { id_row_map, columns, ... }
* @param {object} value e.g. { collaborators, ... }
* @param {object} formulaRows computed value of formula, link-formula, link etc.
* @returns groups: [{
* cell_value, original_cell_value, column_key,
row_ids, subgroups, summaries, ...}, ...], array
*/
var getGroupedRowsWithoutFormulaCalculation = function getGroupedRowsWithoutFormulaCalculation(groupbys, rows, table, value) {
var _ref3 = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : {},
_ref3$formulaRows = _ref3.formulaRows,
formulaRows = _ref3$formulaRows === void 0 ? null : _ref3$formulaRows;
var columns = table.columns;
var validGroupbys = deleteInvalidGroupby(groupbys, columns, table, value);
return isTableRows(rows) ? groupTableRows(validGroupbys, rows, formulaRows, value) : groupViewRows(validGroupbys, table, rows, formulaRows, value);
};
export { getGroupedRowsWithoutFormulaCalculation, groupTableRows, groupViewRows };