mirror of
https://github.com/haiwen/seahub.git
synced 2025-08-29 20:14:19 +00:00
fix: metadata drag fill (#6914)
* fix: metadata drag fill * feat: optimize code * feat: optimize code --------- Co-authored-by: 杨国璇 <ygx@Hello-word.local>
This commit is contained in:
parent
b9ec3684b5
commit
db75243359
@ -6,6 +6,7 @@ import { getColumnByKey } from '../utils/column';
|
|||||||
import { getRowById } from '../utils/table';
|
import { getRowById } from '../utils/table';
|
||||||
import { checkIsDir } from '../utils/row';
|
import { checkIsDir } from '../utils/row';
|
||||||
import { getFileNameFromRecord } from '../utils/cell';
|
import { getFileNameFromRecord } from '../utils/cell';
|
||||||
|
import ObjectUtils from '../utils/object-utils';
|
||||||
|
|
||||||
const MAX_LOAD_RECORDS = 100;
|
const MAX_LOAD_RECORDS = 100;
|
||||||
|
|
||||||
@ -35,12 +36,16 @@ class ServerOperator {
|
|||||||
}
|
}
|
||||||
const recordsData = row_ids.map(rowId => {
|
const recordsData = row_ids.map(rowId => {
|
||||||
return { record_id: rowId, record: id_row_updates[rowId], obj_id: id_obj_id[rowId] };
|
return { record_id: rowId, record: id_row_updates[rowId], obj_id: id_obj_id[rowId] };
|
||||||
});
|
}).filter(recordData => recordData.record && !ObjectUtils.isEmpty(recordData.record));
|
||||||
window.sfMetadataContext.modifyRecords(repo_id, recordsData, is_copy_paste).then(res => {
|
if (recordsData.length === 0) {
|
||||||
callback({ operation });
|
callback({ operation });
|
||||||
}).catch(error => {
|
} else {
|
||||||
callback({ error: gettext('Failed to modify records') });
|
window.sfMetadataContext.modifyRecords(repo_id, recordsData, is_copy_paste).then(res => {
|
||||||
});
|
callback({ operation });
|
||||||
|
}).catch(error => {
|
||||||
|
callback({ error: gettext('Failed to modify records') });
|
||||||
|
});
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case OPERATION_TYPE.DELETE_RECORDS: {
|
case OPERATION_TYPE.DELETE_RECORDS: {
|
||||||
|
@ -38,6 +38,10 @@ class ObjectUtils {
|
|||||||
if (!source || !comparison) return false;
|
if (!source || !comparison) return false;
|
||||||
return !this.isObjectChanged(source, comparison);
|
return !this.isObjectChanged(source, comparison);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static isEmpty = (target) => {
|
||||||
|
return target && target.constructor === Object && Object.keys(target).length === 0;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export const hasOwnProperty = (obj, propertyKey) => {
|
export const hasOwnProperty = (obj, propertyKey) => {
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
import { getCellValueByColumn, getFileNameFromRecord } from '../../../utils/cell';
|
import { getCellValueByColumn, getFileNameFromRecord, isCellValueChanged } from '../../../utils/cell';
|
||||||
import { getColumnByIndex, getColumnOriginName } from '../../../utils/column';
|
import { getColumnByIndex, getColumnOriginName } from '../../../utils/column';
|
||||||
import { CellType, NOT_SUPPORT_DRAG_COPY_COLUMN_TYPES, PRIVATE_COLUMN_KEY, TRANSFER_TYPES } from '../../../constants';
|
import { CellType, NOT_SUPPORT_DRAG_COPY_COLUMN_TYPES, PRIVATE_COLUMN_KEY, TRANSFER_TYPES,
|
||||||
|
REG_NUMBER_DIGIT, REG_STRING_NUMBER_PARTS, COLUMN_RATE_MAX_NUMBER,
|
||||||
|
} from '../../../constants';
|
||||||
import { getGroupRecordByIndex } from './group-metrics';
|
import { getGroupRecordByIndex } from './group-metrics';
|
||||||
import { convertCellValue } from './convert-utils';
|
import { convertCellValue } from './convert-utils';
|
||||||
import { Utils } from '../../../../utils/utils';
|
import { Utils } from '../../../../utils/utils';
|
||||||
@ -209,14 +211,15 @@ class GridUtils {
|
|||||||
const value = draggedRangeMatrix[j - startColumnIdx][idx];
|
const value = draggedRangeMatrix[j - startColumnIdx][idx];
|
||||||
const rule = rules[cellKey];
|
const rule = rules[cellKey];
|
||||||
const fillingValue = rule({ n: fillingIndex - 1, value });
|
const fillingValue = rule({ n: fillingIndex - 1, value });
|
||||||
|
if (isCellValueChanged(fillingValue, dragRow[columnName], type)) {
|
||||||
|
updatedOriginalRows[dragRowId] = Object.assign({}, updatedOriginalRows[dragRowId], { [columnName]: fillingValue });
|
||||||
|
oldOriginalRows[dragRowId] = Object.assign({}, oldOriginalRows[dragRowId], { [columnName]: dragRow[columnName] });
|
||||||
|
const update = updatedOriginalRows[dragRowId];
|
||||||
|
const oldUpdate = oldOriginalRows[dragRowId];
|
||||||
|
|
||||||
updatedOriginalRows[dragRowId] = Object.assign({}, updatedOriginalRows[dragRowId], { [columnName]: fillingValue });
|
updatedRows[dragRowId] = Object.assign({}, updatedRows[dragRowId], update);
|
||||||
oldOriginalRows[dragRowId] = Object.assign({}, oldOriginalRows[dragRowId], { [columnName]: dragRow[columnName] });
|
oldRows[dragRowId] = Object.assign({}, oldRows[dragRowId], oldUpdate);
|
||||||
const update = updatedOriginalRows[dragRowId];
|
}
|
||||||
const oldUpdate = oldOriginalRows[dragRowId];
|
|
||||||
|
|
||||||
updatedRows[dragRowId] = Object.assign({}, updatedRows[dragRowId], update);
|
|
||||||
oldRows[dragRowId] = Object.assign({}, oldRows[dragRowId], oldUpdate);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
currentGroupRowIndex++;
|
currentGroupRowIndex++;
|
||||||
@ -260,21 +263,21 @@ class GridUtils {
|
|||||||
case CellType.DATE: {
|
case CellType.DATE: {
|
||||||
let format = data && data.format && data.format.indexOf('HH:mm') > -1 ? 'YYYY-MM-DD HH:mm' : 'YYYY-MM-DD';
|
let format = data && data.format && data.format.indexOf('HH:mm') > -1 ? 'YYYY-MM-DD HH:mm' : 'YYYY-MM-DD';
|
||||||
let value0 = valueList[0];
|
let value0 = valueList[0];
|
||||||
let yearTolerance = this.getYearTolerance(valueList);
|
let yearTolerance = this._getYearTolerance(valueList);
|
||||||
if (yearTolerance) {
|
if (yearTolerance) {
|
||||||
ruleMatrixItem = ({ n }) => {
|
ruleMatrixItem = ({ n }) => {
|
||||||
return dayjs(value0).add(n * yearTolerance, 'years').format(format);
|
return dayjs(value0).add(n * yearTolerance, 'years').format(format);
|
||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
let monthTolerance = this.getMonthTolerance(valueList);
|
let monthTolerance = this._getMonthTolerance(valueList);
|
||||||
if (monthTolerance) {
|
if (monthTolerance) {
|
||||||
ruleMatrixItem = ({ n }) => {
|
ruleMatrixItem = ({ n }) => {
|
||||||
return dayjs(value0).add(n * monthTolerance, 'months').format(format);
|
return dayjs(value0).add(n * monthTolerance, 'months').format(format);
|
||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
let dayTolerance = this.getDayTolerance(valueList);
|
let dayTolerance = this._getDayTolerance(valueList);
|
||||||
if (dayTolerance) {
|
if (dayTolerance) {
|
||||||
ruleMatrixItem = ({ n }) => {
|
ruleMatrixItem = ({ n }) => {
|
||||||
let time = n * dayTolerance + this.getDateStringValue(value0);
|
let time = n * dayTolerance + this.getDateStringValue(value0);
|
||||||
@ -285,7 +288,7 @@ class GridUtils {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CellType.NUMBER: {
|
case CellType.NUMBER: {
|
||||||
ruleMatrixItem = this.getLeastSquares(valueList);
|
ruleMatrixItem = this._getLeastSquares(valueList);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CellType.TEXT: {
|
case CellType.TEXT: {
|
||||||
@ -293,7 +296,7 @@ class GridUtils {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CellType.RATE: {
|
case CellType.RATE: {
|
||||||
ruleMatrixItem = this.getRatingLeastSquares(valueList, data);
|
ruleMatrixItem = this._getRatingLeastSquares(valueList, data);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
@ -312,7 +315,7 @@ class GridUtils {
|
|||||||
return dateObject.isValid() ? dateObject.valueOf() : 0;
|
return dateObject.isValid() ? dateObject.valueOf() : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
getYearTolerance(dateList) {
|
_getYearTolerance(dateList) {
|
||||||
let date0 = dayjs(dateList[0]);
|
let date0 = dayjs(dateList[0]);
|
||||||
let date1 = dayjs(dateList[1]);
|
let date1 = dayjs(dateList[1]);
|
||||||
if (!date0.isValid() || !date1.isValid()) {
|
if (!date0.isValid() || !date1.isValid()) {
|
||||||
@ -334,7 +337,7 @@ class GridUtils {
|
|||||||
return isYearArithmeticSequence ? tolerance : 0;
|
return isYearArithmeticSequence ? tolerance : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
getMonthTolerance(dateList) {
|
_getMonthTolerance(dateList) {
|
||||||
let date0 = dayjs(dateList[0]);
|
let date0 = dayjs(dateList[0]);
|
||||||
let date1 = dayjs(dateList[1]);
|
let date1 = dayjs(dateList[1]);
|
||||||
if (!date0.isValid() || !date1.isValid()) {
|
if (!date0.isValid() || !date1.isValid()) {
|
||||||
@ -355,7 +358,7 @@ class GridUtils {
|
|||||||
return isMonthArithmeticSequence ? tolerance : 0;
|
return isMonthArithmeticSequence ? tolerance : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
getDayTolerance(dateList) {
|
_getDayTolerance(dateList) {
|
||||||
let date0 = this.getDateStringValue(dateList[0]);
|
let date0 = this.getDateStringValue(dateList[0]);
|
||||||
let tolerance = this.getDateStringValue(dateList[1]) - date0;
|
let tolerance = this.getDateStringValue(dateList[1]) - date0;
|
||||||
let isDayArithmeticSequence = dateList.every((date, i) => {
|
let isDayArithmeticSequence = dateList.every((date, i) => {
|
||||||
@ -367,7 +370,7 @@ class GridUtils {
|
|||||||
return isDayArithmeticSequence ? tolerance : 0;
|
return isDayArithmeticSequence ? tolerance : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
getLeastSquares(numberList) {
|
_getLeastSquares(numberList) {
|
||||||
let slope;
|
let slope;
|
||||||
let intercept;
|
let intercept;
|
||||||
let xAverage;
|
let xAverage;
|
||||||
@ -405,6 +408,136 @@ class GridUtils {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_isArithmeticSequence(numberList) {
|
||||||
|
let number0 = numberList[0];
|
||||||
|
let tolerance = numberList[1] - number0;
|
||||||
|
let func = (v, n) => {
|
||||||
|
return v === n * (tolerance) + number0;
|
||||||
|
};
|
||||||
|
return numberList.every(func);
|
||||||
|
}
|
||||||
|
|
||||||
|
_getTextItemStructureInfo(textItem) {
|
||||||
|
let validTextItem = textItem || '';
|
||||||
|
let lastNumberPosition = -1;
|
||||||
|
let lastNumber = validTextItem;
|
||||||
|
let valueList = validTextItem.match(REG_STRING_NUMBER_PARTS) || [];
|
||||||
|
for (let i = valueList.length - 1; i > -1; i--) {
|
||||||
|
let valueItem = valueList[i];
|
||||||
|
if (REG_NUMBER_DIGIT.test(valueItem)) {
|
||||||
|
lastNumberPosition = i;
|
||||||
|
lastNumber = valueItem;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (lastNumberPosition !== -1) {
|
||||||
|
valueList[lastNumberPosition] = '-|*|-sf-metadata-|*|-';
|
||||||
|
}
|
||||||
|
|
||||||
|
return { lastNumberPosition, lastNumber, structure: valueList.join('') };
|
||||||
|
}
|
||||||
|
|
||||||
|
_getTextFillNumberRule(valueList, lastNumber, lastNumberPosition, fillFunc) {
|
||||||
|
let isStartWith0 = lastNumber.startsWith('0');
|
||||||
|
return ({ n }) => {
|
||||||
|
let fillValue = fillFunc ? fillFunc({ lastNumber, n }) : '';
|
||||||
|
if (isStartWith0 && fillValue.length < lastNumber.length) {
|
||||||
|
fillValue = '0'.repeat(lastNumber.length - fillValue.length) + fillValue;
|
||||||
|
}
|
||||||
|
valueList[lastNumberPosition] = fillValue;
|
||||||
|
return valueList.join('');
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
_getTextRule(textList) {
|
||||||
|
let isAllNotIncludeNumber = textList.every(item => !REG_NUMBER_DIGIT.test(item || ''));
|
||||||
|
if (isAllNotIncludeNumber) {
|
||||||
|
return NORMAL_RULE;
|
||||||
|
}
|
||||||
|
if (textList.length === 1) {
|
||||||
|
let valueList = textList[0].match(REG_STRING_NUMBER_PARTS);
|
||||||
|
let { lastNumberPosition, lastNumber } = this._getTextItemStructureInfo(textList[0]);
|
||||||
|
return this._getTextFillNumberRule(valueList, lastNumber, lastNumberPosition, ({ lastNumber, n }) => {
|
||||||
|
let lastNumberValue = parseInt(lastNumber, 10);
|
||||||
|
return (lastNumberValue + n) + '';
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// isStructureConsistent: the last number part is not equal, other is equal
|
||||||
|
let structureList = textList.map((text) => this._getTextItemStructureInfo(text));
|
||||||
|
let firstStructure = structureList[0];
|
||||||
|
let isStructureConsistent = structureList.every(structure => structure['lastNumberPosition'] === firstStructure['lastNumberPosition'] && structure['structure'] === firstStructure['structure']);
|
||||||
|
if (isStructureConsistent) {
|
||||||
|
let numberList = structureList.map(structure => parseInt(structure.lastNumber, 10));
|
||||||
|
if (this._isArithmeticSequence(numberList)) {
|
||||||
|
let valueList = textList[0].match(REG_STRING_NUMBER_PARTS);
|
||||||
|
let secondStructure = structureList[1];
|
||||||
|
let secondStructureLastNumberValue = parseInt(secondStructure['lastNumber'], 10);
|
||||||
|
return this._getTextFillNumberRule(valueList, firstStructure['lastNumber'], firstStructure['lastNumberPosition'], ({ lastNumber, n }) => {
|
||||||
|
let lastNumberValue = parseInt(lastNumber, 10);
|
||||||
|
return (n * (secondStructureLastNumberValue - lastNumberValue) + lastNumberValue) + '';
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return NORMAL_RULE;
|
||||||
|
}
|
||||||
|
return ({ value, n }) => {
|
||||||
|
if (REG_NUMBER_DIGIT.test(value || '')) {
|
||||||
|
let valueList = value.match(REG_STRING_NUMBER_PARTS);
|
||||||
|
let { lastNumberPosition, lastNumber } = this._getTextItemStructureInfo(value);
|
||||||
|
let isStartWith0 = lastNumber.startsWith('0');
|
||||||
|
let lastNumberValue = parseInt(lastNumber, 10);
|
||||||
|
let fillValue = (lastNumberValue + Math.floor(n / textList.length)) + '';
|
||||||
|
if (isStartWith0 && fillValue.length < lastNumber.length) {
|
||||||
|
fillValue = '0'.repeat(lastNumber.length - fillValue.length) + fillValue;
|
||||||
|
}
|
||||||
|
valueList[lastNumberPosition] = fillValue;
|
||||||
|
return valueList.join('');
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
_getRatingLeastSquares(numberList, data) {
|
||||||
|
const { rate_max_number = COLUMN_RATE_MAX_NUMBER[4].name } = data || {};
|
||||||
|
let slope;
|
||||||
|
let intercept;
|
||||||
|
let xAverage;
|
||||||
|
let yAverage;
|
||||||
|
let xSum = 0;
|
||||||
|
let ySum = 0;
|
||||||
|
let xSquareSum = 0;
|
||||||
|
let xySum = 0;
|
||||||
|
let validCellsLen = 0;
|
||||||
|
let emptyCellPositions = [];
|
||||||
|
numberList.forEach((v, i) => {
|
||||||
|
if (v !== undefined && v !== null && v !== '') {
|
||||||
|
validCellsLen++;
|
||||||
|
xSum += i;
|
||||||
|
ySum += v;
|
||||||
|
xySum += (v * i);
|
||||||
|
xSquareSum += Math.pow(i, 2);
|
||||||
|
} else {
|
||||||
|
emptyCellPositions.push(i);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (validCellsLen < 2) {
|
||||||
|
return NORMAL_RULE;
|
||||||
|
}
|
||||||
|
xAverage = xSum / validCellsLen;
|
||||||
|
yAverage = ySum / validCellsLen;
|
||||||
|
slope = (xySum - validCellsLen * xAverage * yAverage) / (xSquareSum - validCellsLen * Math.pow(xAverage, 2));
|
||||||
|
intercept = yAverage - slope * xAverage;
|
||||||
|
return ({ n }) => {
|
||||||
|
if (emptyCellPositions.length && emptyCellPositions.includes(n % numberList.length)) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
let y = n * slope + intercept;
|
||||||
|
const value = Number(parseFloat(y).toFixed(0));
|
||||||
|
if (value > rate_max_number) return rate_max_number;
|
||||||
|
if (value < 0) return 0;
|
||||||
|
return value;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default GridUtils;
|
export default GridUtils;
|
||||||
|
Loading…
Reference in New Issue
Block a user