@revolist/revogrid
Version:
Virtual reactive data grid spreadsheet component - RevoGrid.
1,012 lines (985 loc) • 34.3 kB
JavaScript
/*!
* Built by Revolist OU ❤️
*/
'use strict';
var dimension_helpers = require('./dimension.helpers-B9HgANnM.js');
/**
* Converts `value` to an integer.
*
* **Note:** This method is loosely based on
* [`ToInteger`](http://www.ecma-international.org/ecma-262/7.0/#sec-tointeger).
*
* @static
* @memberOf _
* @since 4.0.0
* @category Lang
* @param {*} value The value to convert.
* @returns {number} Returns the converted integer.
* @example
*
* _.toInteger(3.2);
* // => 3
*
* _.toInteger(Number.MIN_VALUE);
* // => 0
*
* _.toInteger(Infinity);
* // => 1.7976931348623157e+308
*
* _.toInteger('3.2');
* // => 3
*/
function toInteger(value) {
var result = dimension_helpers.toFinite(value),
remainder = result % 1;
return result === result ? (remainder ? result - remainder : result) : 0;
}
/**
* A specialized version of `_.reduce` for arrays without support for
* iteratee shorthands.
*
* @private
* @param {Array} [array] The array to iterate over.
* @param {Function} iteratee The function invoked per iteration.
* @param {*} [accumulator] The initial value.
* @param {boolean} [initAccum] Specify using the first element of `array` as
* the initial value.
* @returns {*} Returns the accumulated value.
*/
function arrayReduce(array, iteratee, accumulator, initAccum) {
var index = -1,
length = array == null ? 0 : array.length;
if (initAccum && length) {
accumulator = array[++index];
}
while (++index < length) {
accumulator = iteratee(accumulator, array[index], index, array);
}
return accumulator;
}
/**
* Creates a base function for methods like `_.forIn` and `_.forOwn`.
*
* @private
* @param {boolean} [fromRight] Specify iterating from right to left.
* @returns {Function} Returns the new base function.
*/
function createBaseFor(fromRight) {
return function(object, iteratee, keysFunc) {
var index = -1,
iterable = Object(object),
props = keysFunc(object),
length = props.length;
while (length--) {
var key = props[++index];
if (iteratee(iterable[key], key, iterable) === false) {
break;
}
}
return object;
};
}
/**
* The base implementation of `baseForOwn` which iterates over `object`
* properties returned by `keysFunc` and invokes `iteratee` for each property.
* Iteratee functions may exit iteration early by explicitly returning `false`.
*
* @private
* @param {Object} object The object to iterate over.
* @param {Function} iteratee The function invoked per iteration.
* @param {Function} keysFunc The function to get the keys of `object`.
* @returns {Object} Returns `object`.
*/
var baseFor = createBaseFor();
/**
* The base implementation of `_.forOwn` without support for iteratee shorthands.
*
* @private
* @param {Object} object The object to iterate over.
* @param {Function} iteratee The function invoked per iteration.
* @returns {Object} Returns `object`.
*/
function baseForOwn(object, iteratee) {
return object && baseFor(object, iteratee, dimension_helpers.keys);
}
/**
* Creates a `baseEach` or `baseEachRight` function.
*
* @private
* @param {Function} eachFunc The function to iterate over a collection.
* @param {boolean} [fromRight] Specify iterating from right to left.
* @returns {Function} Returns the new base function.
*/
function createBaseEach(eachFunc, fromRight) {
return function(collection, iteratee) {
if (collection == null) {
return collection;
}
if (!dimension_helpers.isArrayLike(collection)) {
return eachFunc(collection, iteratee);
}
var length = collection.length,
index = -1,
iterable = Object(collection);
while ((++index < length)) {
if (iteratee(iterable[index], index, iterable) === false) {
break;
}
}
return collection;
};
}
/**
* The base implementation of `_.forEach` without support for iteratee shorthands.
*
* @private
* @param {Array|Object} collection The collection to iterate over.
* @param {Function} iteratee The function invoked per iteration.
* @returns {Array|Object} Returns `collection`.
*/
var baseEach = createBaseEach(baseForOwn);
/**
* The base implementation of `_.reduce` and `_.reduceRight`, without support
* for iteratee shorthands, which iterates over `collection` using `eachFunc`.
*
* @private
* @param {Array|Object} collection The collection to iterate over.
* @param {Function} iteratee The function invoked per iteration.
* @param {*} accumulator The initial value.
* @param {boolean} initAccum Specify using the first or last element of
* `collection` as the initial value.
* @param {Function} eachFunc The function to iterate over `collection`.
* @returns {*} Returns the accumulated value.
*/
function baseReduce(collection, iteratee, accumulator, initAccum, eachFunc) {
eachFunc(collection, function(value, index, collection) {
accumulator = initAccum
? (initAccum = false, value)
: iteratee(accumulator, value, index, collection);
});
return accumulator;
}
/**
* Reduces `collection` to a value which is the accumulated result of running
* each element in `collection` thru `iteratee`, where each successive
* invocation is supplied the return value of the previous. If `accumulator`
* is not given, the first element of `collection` is used as the initial
* value. The iteratee is invoked with four arguments:
* (accumulator, value, index|key, collection).
*
* Many lodash methods are guarded to work as iteratees for methods like
* `_.reduce`, `_.reduceRight`, and `_.transform`.
*
* The guarded methods are:
* `assign`, `defaults`, `defaultsDeep`, `includes`, `merge`, `orderBy`,
* and `sortBy`
*
* @static
* @memberOf _
* @since 0.1.0
* @category Collection
* @param {Array|Object} collection The collection to iterate over.
* @param {Function} [iteratee=_.identity] The function invoked per iteration.
* @param {*} [accumulator] The initial value.
* @returns {*} Returns the accumulated value.
* @see _.reduceRight
* @example
*
* _.reduce([1, 2], function(sum, n) {
* return sum + n;
* }, 0);
* // => 3
*
* _.reduce({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) {
* (result[value] || (result[value] = [])).push(key);
* return result;
* }, {});
* // => { '1': ['a', 'c'], '2': ['b'] } (iteration order is not guaranteed)
*/
function reduce(collection, iteratee, accumulator) {
var func = dimension_helpers.isArray(collection) ? arrayReduce : baseReduce,
initAccum = arguments.length < 3;
return func(collection, dimension_helpers.baseIteratee(iteratee), accumulator, initAccum, baseEach);
}
function getCellData(val) {
if (typeof val === 'undefined' || val === null) {
return '';
}
return val;
}
function getCellRaw(model = {}, column) {
if (!column) {
return;
}
if (column.cellParser) {
return column.cellParser(model, column);
}
return model[column.prop];
}
function getCellDataParsed(model, column) {
return getCellData(getCellRaw(model, column));
}
/**
* Get column type from column data
*/
function getColumnType(rgCol) {
if (rgCol.pin) {
return rgCol.pin;
}
return 'rgCol';
}
function getColumnSizes(cols) {
const res = {};
for (const [i, c] of cols.entries()) {
if (c.size) {
res[i] = c.size;
}
}
return res;
}
/**
* Check if column is grouping column
*/
function isColGrouping(colData) {
return !!colData.children;
}
/**
* This function is used to create a collection of columns.
*/
function getColumns(columns, level = 0, types, resFromRoot) {
const collection = {
// columns as they are in stores per type
columns: {
rgCol: [],
colPinStart: [],
colPinEnd: [],
},
// columns indexed by prop for quick access
columnByProp: {},
// column grouping
columnGrouping: {
rgCol: [],
colPinStart: [],
colPinEnd: [],
},
// sorting
sort: {},
// max depth level for column grouping
maxLevel: level,
};
return reduce(columns, (res, colData) => {
var _a;
// Grouped column
if (isColGrouping(colData)) {
res = gatherGroup(res, colData, getColumns(colData.children, level + 1, types, res), resFromRoot === null || resFromRoot === void 0 ? void 0 : resFromRoot.columns, level);
return res;
}
// Column type
const columnDefinitionFromType = colData.columnType && (types === null || types === void 0 ? void 0 : types[colData.columnType]);
// Regular column
const regularColumn = Object.assign(Object.assign({}, columnDefinitionFromType), colData);
// Regular column, no Pin
if (!regularColumn.pin) {
res.columns.rgCol.push(regularColumn);
// Pin
}
else {
res.columns[regularColumn.pin].push(regularColumn);
}
if (regularColumn.order) {
res.sort[regularColumn.prop] = regularColumn;
}
// it's possible that some columns have same prop, but better to avoid it
if (!res.columnByProp[regularColumn.prop]) {
res.columnByProp[regularColumn.prop] = [];
}
res.columnByProp[regularColumn.prop].push(regularColumn);
// trigger setup hook if present
(_a = regularColumn.beforeSetup) === null || _a === void 0 ? void 0 : _a.call(regularColumn, regularColumn);
return res;
}, collection);
}
function gatherGroup(res, colData, collection, existingColumnsByType, level = 0) {
// group template
const group = Object.assign(Object.assign({}, colData), { level, indexes: [] });
// check columns for update
columnTypes.forEach(type => {
const resultItem = res.columns[type];
const collectionItem = collection.columns[type];
// if column data
if (dimension_helpers.isArray(resultItem) && dimension_helpers.isArray(collectionItem)) {
// fill grouping
const itemLength = collectionItem.length;
if (itemLength) {
const columnLength = [...((existingColumnsByType === null || existingColumnsByType === void 0 ? void 0 : existingColumnsByType[type]) || []), ...resultItem].length;
// fill columns
resultItem.push(...collectionItem);
// fill indexes per each viewport
res.columnGrouping[type].push(Object.assign(Object.assign({}, group), { indexes: Array(itemLength).fill(columnLength).map((v, i) => v + i) }));
}
}
});
// merge column groupings
for (let k in collection.columnGrouping) {
const key = k;
const collectionItem = collection.columnGrouping[key];
const delta = ((existingColumnsByType === null || existingColumnsByType === void 0 ? void 0 : existingColumnsByType[key]) || []).length;
const rebasedItem = delta > 0
? collectionItem.map(group => (Object.assign(Object.assign({}, group), { indexes: group.indexes.map(i => i + delta) })))
: collectionItem;
res.columnGrouping[key].push(...rebasedItem);
}
res.maxLevel = Math.max(res.maxLevel, collection.maxLevel);
res.sort = Object.assign(Object.assign({}, res.sort), collection.sort);
res.columnByProp = Object.assign(Object.assign({}, res.columnByProp), collection.columnByProp);
return res;
}
function findColumn(columns, prop) {
for (const c of columns) {
if (isColGrouping(c)) {
const found = findColumn(c.children, prop);
if (found) {
return found;
}
}
else if (c.prop === prop) {
return c;
}
}
return undefined;
}
function getColumnByProp(columns, prop) {
return findColumn(columns, prop);
}
function nextCell(cell, lastCell) {
const nextItem = {};
let types = ['x', 'y'];
// previous item check
for (let t of types) {
if (cell[t] < 0) {
nextItem[t] = cell[t];
return nextItem;
}
}
// next item check
for (let t of types) {
if (cell[t] >= lastCell[t]) {
nextItem[t] = cell[t] - lastCell[t];
return nextItem;
}
}
return null;
}
function cropCellToMax(cell, lastCell) {
const croppedCell = Object.assign({}, cell);
const cellCoordinates = ['x', 'y'];
for (const coordinate of cellCoordinates) {
if (cell[coordinate] < 0) {
croppedCell[coordinate] = 0;
}
else if (cell[coordinate] >= lastCell[coordinate]) {
croppedCell[coordinate] = lastCell[coordinate] - 1;
}
}
return croppedCell;
}
function getRange(start, end) {
return start && end
? {
x: Math.min(start.x, end.x),
y: Math.min(start.y, end.y),
x1: Math.max(start.x, end.x),
y1: Math.max(start.y, end.y),
}
: null;
}
function isRangeSingleCell(a) {
return a.x === a.x1 && a.y === a.y1;
}
const rowTypes = ['rowPinStart', 'rgRow', 'rowPinEnd'];
const columnTypes = [
'colPinStart',
'rgCol',
'colPinEnd',
];
function isRowType(type) {
return rowTypes.indexOf(type) > -1;
}
const GROUP_DEPTH = `${dimension_helpers.GRID_INTERNALS}-depth`;
const PSEUDO_GROUP_ITEM = `${dimension_helpers.GRID_INTERNALS}-name`;
const PSEUDO_GROUP_ITEM_ID = `${dimension_helpers.GRID_INTERNALS}-id`;
const PSEUDO_GROUP_ITEM_VALUE = `${dimension_helpers.GRID_INTERNALS}-value`;
const PSEUDO_GROUP_COLUMN = `${dimension_helpers.GRID_INTERNALS}-column`;
const GROUP_EXPANDED = `${dimension_helpers.GRID_INTERNALS}-expanded`;
const GROUP_COLUMN_PROP = `${dimension_helpers.GRID_INTERNALS}-prop`;
const GROUP_ORIGINAL_INDEX = `${dimension_helpers.GRID_INTERNALS}-original-index`;
const GROUP_EXPAND_BTN = `group-expand`;
const GROUP_EXPAND_EVENT = `groupexpandclick`;
const GROUPING_ROW_TYPE = 'rgRow';
function getGroupValueDefault(item, prop) {
return item[prop] || null;
}
function isDataRow(item) {
return item != null;
}
// get source based on proxy item collection to preserve rgRow order
function getSource(source, items, withoutGrouping = false) {
let index = 0;
const result = {
source: [],
prevExpanded: {},
oldNewIndexes: {},
};
// order important here, expected parent is first, then others
items.forEach(i => {
const model = source[i];
if (!withoutGrouping) {
result.source.push(model);
return;
}
// grouping filter
if (isGrouping(model)) {
if (getExpanded(model)) {
result.prevExpanded[model[PSEUDO_GROUP_ITEM_VALUE]] = true;
}
}
else if (!isDataRow(model)) {
return;
}
else {
result.source.push(model);
result.oldNewIndexes[i] = index;
index++;
}
});
return result;
}
function getExpanded(model = {}) {
return model[GROUP_EXPANDED];
}
function flattenGroupMaps({ groupedValues, parentIds, isExpanded, itemIndex, expandedAll, prevExpanded, columnProps, }) {
const depth = parentIds.length;
const sourceWithGroups = [];
// collapse all groups in the beginning
let trimmed = {};
// index mapping
let oldNewIndexMap = {};
groupedValues.forEach((innerGroupedValues, groupId) => {
const levelIds = [...parentIds, groupId];
const mergedIds = levelIds.join(',');
const isGroupExpanded = isExpanded && (!!expandedAll || !!prevExpanded[mergedIds]);
sourceWithGroups.push({
[PSEUDO_GROUP_ITEM]: groupId,
[GROUP_DEPTH]: depth,
[PSEUDO_GROUP_ITEM_ID]: JSON.stringify(levelIds),
[PSEUDO_GROUP_ITEM_VALUE]: mergedIds,
[GROUP_EXPANDED]: isGroupExpanded,
[GROUP_COLUMN_PROP]: columnProps[depth],
[columnProps[depth]]: groupId,
});
itemIndex += 1;
// If parent group is collapsed, mark all items as hidden
if (!isExpanded && depth) {
trimmed[itemIndex] = true;
}
if (Array.isArray(innerGroupedValues)) {
// This branch handles leaf nodes (actual data items)
innerGroupedValues.forEach(value => {
itemIndex += 1;
if (!isGroupExpanded) {
trimmed[itemIndex] = true; // Mark items as hidden if group is collapsed
}
oldNewIndexMap[value[GROUP_ORIGINAL_INDEX]] = itemIndex; // Keep track of new positions
});
sourceWithGroups.push(...innerGroupedValues);
}
else {
// This branch handles nested groups (further subgroups)
const children = flattenGroupMaps({
groupedValues: innerGroupedValues,
parentIds: levelIds,
isExpanded: isGroupExpanded,
itemIndex,
expandedAll,
prevExpanded,
columnProps,
}); // Recursively process subgroups
sourceWithGroups.push(...children.source);
trimmed = Object.assign(Object.assign({}, children.trimmed), trimmed);
oldNewIndexMap = Object.assign(Object.assign({}, children.oldNewIndexMap), oldNewIndexMap);
itemIndex = children.itemIndex;
}
});
return {
source: sourceWithGroups,
oldNewIndexMap,
trimmed,
itemIndex,
};
}
/**
* Gather data for grouping
* @param array - flat data array
* @param columnProps - ids of groups
* @param expanded - potentially expanded items if present
*/
function gatherGrouping(array, columnProps, { prevExpanded = {}, expandedAll = false, getGroupValue = getGroupValueDefault, }) {
const groupedItems = new Map();
array.forEach((item, originalIndex) => {
if (!isDataRow(item)) {
return;
}
const groupLevelValues = columnProps.map(groupId => getGroupValue(item, groupId));
const lastLevelValue = groupLevelValues.pop();
let currentGroupLevel = groupedItems;
groupLevelValues.forEach(value => {
if (!currentGroupLevel.has(value)) {
currentGroupLevel.set(value, new Map());
}
currentGroupLevel = currentGroupLevel.get(value);
});
if (!currentGroupLevel.has(lastLevelValue)) {
const groupItems = [];
currentGroupLevel.set(lastLevelValue, groupItems);
}
const lastLevelItems = currentGroupLevel.get(lastLevelValue);
lastLevelItems.push(Object.assign(Object.assign({}, item), { [GROUP_ORIGINAL_INDEX]: originalIndex }));
});
const groupingDepth = columnProps.length;
const { source: sourceWithGroups, trimmed, oldNewIndexMap } = flattenGroupMaps({
groupedValues: groupedItems,
parentIds: [],
isExpanded: true,
itemIndex: -1,
expandedAll,
prevExpanded,
columnProps
});
return {
sourceWithGroups, // updates source mirror
depth: groupingDepth, // largest depth for grouping
trimmed, // used for expand/collapse grouping values
oldNewIndexMap, // used for mapping old values to new
};
}
function getGroupingName(rgRow) {
return rgRow === null || rgRow === void 0 ? void 0 : rgRow[PSEUDO_GROUP_ITEM];
}
function isGrouping(rgRow) {
return typeof (rgRow === null || rgRow === void 0 ? void 0 : rgRow[PSEUDO_GROUP_ITEM]) !== 'undefined';
}
function isGroupingColumn(column) {
return typeof (column === null || column === void 0 ? void 0 : column[PSEUDO_GROUP_COLUMN]) !== 'undefined';
}
function measureEqualDepth(groupA, groupB) {
const ln = groupA.length;
let i = 0;
for (; i < ln; i++) {
if (groupA[i] !== groupB[i]) {
return i;
}
}
return i;
}
function getParsedGroup(id) {
const parseGroup = JSON.parse(id);
// extra precaution and type safeguard
if (!Array.isArray(parseGroup)) {
return null;
}
return parseGroup;
}
// check if items is child of current clicked group
function isSameGroup(currentGroup, currentModel, nextModel) {
const nextGroup = getParsedGroup(nextModel[PSEUDO_GROUP_ITEM_ID]);
if (!nextGroup) {
return false;
}
const depth = measureEqualDepth(currentGroup, nextGroup);
return currentModel[GROUP_DEPTH] < depth;
}
/**
* The base implementation of `_.slice` without an iteratee call guard.
*
* @private
* @param {Array} array The array to slice.
* @param {number} [start=0] The start position.
* @param {number} [end=array.length] The end position.
* @returns {Array} Returns the slice of `array`.
*/
function baseSlice(array, start, end) {
var index = -1,
length = array.length;
if (start < 0) {
start = -start > length ? 0 : (length + start);
}
end = end > length ? length : end;
if (end < 0) {
end += length;
}
length = start > end ? 0 : ((end - start) >>> 0);
start >>>= 0;
var result = Array(length);
while (++index < length) {
result[index] = array[index + start];
}
return result;
}
/**
* Creates a slice of `array` from `start` up to, but not including, `end`.
*
* **Note:** This method is used instead of
* [`Array#slice`](https://mdn.io/Array/slice) to ensure dense arrays are
* returned.
*
* @static
* @memberOf _
* @since 3.0.0
* @category Array
* @param {Array} array The array to slice.
* @param {number} [start=0] The start position.
* @param {number} [end=array.length] The end position.
* @returns {Array} Returns the slice of `array`.
*/
function slice(array, start, end) {
var length = array == null ? 0 : array.length;
if (!length) {
return [];
}
if (end && typeof end != 'number' && dimension_helpers.isIterateeCall(array, start, end)) {
start = 0;
end = length;
}
else {
start = start == null ? 0 : toInteger(start);
end = end === undefined ? length : toInteger(end);
}
return baseSlice(array, start, end);
}
function getCellEditor(column, editors = {}) {
const editor = column === null || column === void 0 ? void 0 : column.editor;
if (!editor) {
return undefined;
}
// reference
if (typeof editor === 'string') {
return editors[editor];
}
return editor;
}
class ColumnService {
get columns() {
return dimension_helpers.getVisibleSourceItem(this.source);
}
constructor(dataStore, source) {
this.dataStore = dataStore;
this.source = source;
this.unsubscribe = [];
this.hasGrouping = false;
this.unsubscribe.push(source.onChange('source', s => this.checkGrouping(s)));
this.checkGrouping(source.get('source'));
this.type = source.get('type');
}
checkGrouping(cols) {
for (let rgCol of cols) {
if (isGroupingColumn(rgCol)) {
this.hasGrouping = true;
return;
}
this.hasGrouping = false;
}
}
isReadOnly(r, c) {
var _a;
const readOnly = (_a = this.columns[c]) === null || _a === void 0 ? void 0 : _a.readonly;
if (typeof readOnly === 'function') {
const data = this.rowDataModel(r, c);
return readOnly(data);
}
return !!readOnly;
}
mergeProperties(r, c, defaultProps, schemaModel) {
var _a, _b;
const props = Object.assign({}, defaultProps);
props.class = Object.assign(Object.assign({}, (typeof props.class === 'string'
? { [props.class]: true }
: props.class)), { [dimension_helpers.CELL_CLASS]: true, [dimension_helpers.DISABLED_CLASS]: this.isReadOnly(r, c) });
const extra = (_b = (_a = schemaModel.column) === null || _a === void 0 ? void 0 : _a.cellProperties) === null || _b === void 0 ? void 0 : _b.call(_a, schemaModel);
if (!extra) {
return props;
}
return doPropMerge(props, extra);
}
getRowClass(r, prop) {
const model = dimension_helpers.getSourceItem(this.dataStore, r) || {};
return model[prop] || '';
}
getSaveData(rowIndex, colIndex, val) {
const data = this.rowDataModel(rowIndex, colIndex);
if (typeof val === 'undefined') {
val = getCellData(data.value);
}
return Object.assign(Object.assign({}, data), { val });
}
/**
* Get cell data model for given rowIndex and colIndex
* Used to pass data to editor/renderer
*/
rowDataModel(rowIndex, colIndex) {
const column = this.columns[colIndex];
const prop = column === null || column === void 0 ? void 0 : column.prop;
const model = dimension_helpers.getSourceItem(this.dataStore, rowIndex) || {};
const type = this.dataStore.get('type');
return {
prop,
model,
data: this.dataStore.get('source'),
column,
rowIndex,
colIndex,
colType: this.type,
type,
value: getCellRaw(model, column),
};
}
getRangeData(d, columns) {
var _a;
const changed = {};
// get original length sizes
const copyColLength = d.oldRange.x1 - d.oldRange.x + 1;
const copyRowLength = d.oldRange.y1 - d.oldRange.y + 1;
const mapping = {};
// rows
for (let rowIndex = d.newRange.y, i = 0; rowIndex < d.newRange.y1 + 1; rowIndex++, i++) {
// copy original data link
const oldRowIndex = d.oldRange.y + (i % copyRowLength);
const copyRow = dimension_helpers.getSourceItem(this.dataStore, oldRowIndex) || {};
// columns
for (let colIndex = d.newRange.x, j = 0; colIndex < d.newRange.x1 + 1; colIndex++, j++) {
// check if old range area
if (rowIndex >= d.oldRange.y &&
rowIndex <= d.oldRange.y1 &&
colIndex >= d.oldRange.x &&
colIndex <= d.oldRange.x1) {
continue;
}
// requested column beyond range
if (!this.columns[colIndex]) {
continue;
}
const prop = (_a = this.columns[colIndex]) === null || _a === void 0 ? void 0 : _a.prop;
const copyColIndex = d.oldRange.x + (j % copyColLength);
const copyColumnProp = columns[copyColIndex].prop;
/** if can write */
if (!this.isReadOnly(rowIndex, colIndex)) {
/** to show before save */
if (!changed[rowIndex]) {
changed[rowIndex] = {};
}
changed[rowIndex][prop] = copyRow[copyColumnProp];
/** Generate mapping object */
if (!mapping[rowIndex]) {
mapping[rowIndex] = {};
}
mapping[rowIndex][prop] = {
colIndex: copyColIndex,
colProp: copyColumnProp,
rowIndex: oldRowIndex,
};
}
}
}
return {
changed,
mapping,
};
}
getTransformedDataToApply(start, data) {
const changed = {};
const copyRowLength = data.length;
const colLength = this.columns.length;
const rowLength = this.dataStore.get('items').length;
// rows
let rowIndex = start.y;
let maxCol = 0;
for (let i = 0; rowIndex < rowLength && i < copyRowLength; rowIndex++, i++) {
// copy original data link
const copyRow = data[i % copyRowLength];
const copyColLength = (copyRow === null || copyRow === void 0 ? void 0 : copyRow.length) || 0;
// columns
let colIndex = start.x;
for (let j = 0; colIndex < colLength && j < copyColLength; colIndex++, j++) {
const p = this.columns[colIndex].prop;
const currentCol = j % colLength;
/** if can write */
if (!this.isReadOnly(rowIndex, colIndex)) {
/** to show before save */
if (!changed[rowIndex]) {
changed[rowIndex] = {};
}
changed[rowIndex][p] = copyRow[currentCol];
}
}
maxCol = Math.max(maxCol, colIndex - 1);
}
const range = getRange(start, {
y: rowIndex - 1,
x: maxCol,
});
return {
changed,
range,
};
}
getRangeStaticData(d, value) {
const changed = {};
// rows
for (let rowIndex = d.y, i = 0; rowIndex < d.y1 + 1; rowIndex++, i++) {
// columns
for (let colIndex = d.x, j = 0; colIndex < d.x1 + 1; colIndex++, j++) {
// requested column beyond range
if (!this.columns[colIndex]) {
continue;
}
const p = this.columns[colIndex].prop;
/** if can write */
if (!this.isReadOnly(rowIndex, colIndex)) {
/** to show before save */
if (!changed[rowIndex]) {
changed[rowIndex] = {};
}
changed[rowIndex][p] = value;
}
}
}
return changed;
}
getRangeTransformedToProps(d, store) {
var _a;
const area = [];
const type = this.dataStore.get('type');
// rows
for (let rowIndex = d.y, i = 0; rowIndex < d.y1 + 1; rowIndex++, i++) {
// columns
for (let colIndex = d.x, j = 0; colIndex < d.x1 + 1; colIndex++, j++) {
const prop = (_a = this.columns[colIndex]) === null || _a === void 0 ? void 0 : _a.prop;
area.push({
prop,
rowIndex,
colIndex,
model: dimension_helpers.getSourceItem(store, rowIndex),
type,
colType: this.type,
});
}
}
return area;
}
copyRangeArray(range, store) {
const cols = [...this.columns];
const props = slice(cols, range.x, range.x1 + 1).map(v => v.prop);
const toCopy = [];
const mapping = {};
// rows indexes
for (let i = range.y; i <= range.y1; i++) {
const rgRow = [];
mapping[i] = {};
// columns indexes
for (let prop of props) {
const item = dimension_helpers.getSourceItem(store, i);
// if no item - skip
if (!item) {
continue;
}
const val = item[prop];
rgRow.push(val);
mapping[i][prop] = val;
}
toCopy.push(rgRow);
}
return {
data: toCopy,
mapping,
};
}
destroy() {
this.unsubscribe.forEach(f => f());
}
}
/**
* Checks if the given rowDrag is a service for dragging rows.
*/
function isRowDragService(rowDrag, model) {
if (typeof rowDrag === 'function') {
return rowDrag(model);
}
return !!rowDrag;
}
function mergeClasses(class1 = {}, class2 = {}) {
if (typeof class1 === 'string') {
class1 = { [class1]: true };
}
if (typeof class2 === 'string') {
class2 = { [class2]: true };
}
return Object.assign(Object.assign({}, class1), class2);
}
function doPropMerge(existing, extra) {
// if className is provided - remove it from props it messing with stencil
if (extra.className) {
extra.class = mergeClasses(extra.class, extra.className);
delete extra.className;
}
let props = Object.assign(Object.assign({}, extra), existing);
// extend existing props
if (extra.class) {
props.class = mergeClasses(props.class, extra.class);
}
if (extra.style) {
props.style = Object.assign(Object.assign({}, extra.style), props.style);
}
return props;
}
exports.ColumnService = ColumnService;
exports.GROUPING_ROW_TYPE = GROUPING_ROW_TYPE;
exports.GROUP_COLUMN_PROP = GROUP_COLUMN_PROP;
exports.GROUP_DEPTH = GROUP_DEPTH;
exports.GROUP_EXPANDED = GROUP_EXPANDED;
exports.GROUP_EXPAND_BTN = GROUP_EXPAND_BTN;
exports.GROUP_EXPAND_EVENT = GROUP_EXPAND_EVENT;
exports.GROUP_ORIGINAL_INDEX = GROUP_ORIGINAL_INDEX;
exports.PSEUDO_GROUP_COLUMN = PSEUDO_GROUP_COLUMN;
exports.PSEUDO_GROUP_ITEM = PSEUDO_GROUP_ITEM;
exports.PSEUDO_GROUP_ITEM_ID = PSEUDO_GROUP_ITEM_ID;
exports.PSEUDO_GROUP_ITEM_VALUE = PSEUDO_GROUP_ITEM_VALUE;
exports.baseEach = baseEach;
exports.columnTypes = columnTypes;
exports.cropCellToMax = cropCellToMax;
exports.doPropMerge = doPropMerge;
exports.gatherGroup = gatherGroup;
exports.gatherGrouping = gatherGrouping;
exports.getCellData = getCellData;
exports.getCellDataParsed = getCellDataParsed;
exports.getCellEditor = getCellEditor;
exports.getCellRaw = getCellRaw;
exports.getColumnByProp = getColumnByProp;
exports.getColumnSizes = getColumnSizes;
exports.getColumnType = getColumnType;
exports.getColumns = getColumns;
exports.getExpanded = getExpanded;
exports.getGroupingName = getGroupingName;
exports.getParsedGroup = getParsedGroup;
exports.getRange = getRange;
exports.getSource = getSource;
exports.isColGrouping = isColGrouping;
exports.isGrouping = isGrouping;
exports.isGroupingColumn = isGroupingColumn;
exports.isRangeSingleCell = isRangeSingleCell;
exports.isRowDragService = isRowDragService;
exports.isRowType = isRowType;
exports.isSameGroup = isSameGroup;
exports.measureEqualDepth = measureEqualDepth;
exports.nextCell = nextCell;
exports.reduce = reduce;
exports.rowTypes = rowTypes;
exports.toInteger = toInteger;