mirror of
https://github.com/haiwen/seahub.git
synced 2025-09-22 11:57:34 +00:00
fix bug - tag disappear after rename (#6814)
* fix bug - tag disappear after rename * fix tag rename action * update column data sync * feat: optimize function * feat: optimize function * feat: optimize code --------- Co-authored-by: 杨国璇 <ygx@Hello-word.local>
This commit is contained in:
@@ -9,6 +9,7 @@ import { gettext } from '../../../../utils/constants';
|
||||
import { useMetadataView } from '../../../hooks/metadata-view';
|
||||
import { getColumnOptions, getOptionNameById, generateNewOption } from '../../../utils/column';
|
||||
import { checkIsPredefinedOption } from '../../../utils/cell';
|
||||
import { COLUMN_DATA_OPERATION_TYPE } from '../../../store/operations';
|
||||
|
||||
import './index.css';
|
||||
|
||||
@@ -35,12 +36,12 @@ const OptionsPopover = ({ target, column, onToggle, onSubmit }) => {
|
||||
});
|
||||
}, [options, searchValue]);
|
||||
|
||||
const onChange = useCallback((options) => {
|
||||
onSubmit(options.filter(item => item.name));
|
||||
const onChange = useCallback((options, optionModifyType) => {
|
||||
onSubmit(options.filter(item => item.name), optionModifyType);
|
||||
setOptions(options);
|
||||
}, [onSubmit]);
|
||||
|
||||
const onUpdate = useCallback((newOption, successCallback, failCallback) => {
|
||||
const onUpdate = useCallback((newOption, type, successCallback, failCallback) => {
|
||||
const duplicateNameOption = options.find(o => o.name === newOption.name && o.id !== newOption.id);
|
||||
if (duplicateNameOption) {
|
||||
toaster.danger(gettext('There is another option with this name'));
|
||||
@@ -53,7 +54,7 @@ const OptionsPopover = ({ target, column, onToggle, onSubmit }) => {
|
||||
const newOptions = options.slice(0);
|
||||
const optionIndex = newOptions.findIndex(item => item.id === newOption.id);
|
||||
newOptions.splice(optionIndex, 1, newOption);
|
||||
onChange(newOptions);
|
||||
onChange(newOptions, type);
|
||||
}, [options, onChange, isValidEditingOption]);
|
||||
|
||||
const onMove = useCallback((optionSource, optionTarget) => {
|
||||
@@ -66,7 +67,7 @@ const OptionsPopover = ({ target, column, onToggle, onSubmit }) => {
|
||||
insertIndex++;
|
||||
}
|
||||
newOptions.splice(insertIndex, 0, movedOption);
|
||||
onChange(newOptions);
|
||||
onChange(newOptions, COLUMN_DATA_OPERATION_TYPE.MOVE_OPTION);
|
||||
}, [options, displayOptions, onChange]);
|
||||
|
||||
const onAdd = useCallback(() => {
|
||||
@@ -74,7 +75,7 @@ const OptionsPopover = ({ target, column, onToggle, onSubmit }) => {
|
||||
const newOption = generateNewOption(options, newOptionName);
|
||||
const newOptions = options.slice(0);
|
||||
newOptions.push(newOption);
|
||||
onChange(newOptions);
|
||||
onChange(newOptions, COLUMN_DATA_OPERATION_TYPE.ADD_OPTION);
|
||||
setEditingOptionId(newOptionName ? '' : newOption.id);
|
||||
}, [searchValue, options, onChange]);
|
||||
|
||||
@@ -85,7 +86,7 @@ const OptionsPopover = ({ target, column, onToggle, onSubmit }) => {
|
||||
setViewingOptionId(displayOptions[displayOptions.length - 2]?.id || '');
|
||||
}
|
||||
setDeletingOptionId('');
|
||||
onChange(newOptions);
|
||||
onChange(newOptions, COLUMN_DATA_OPERATION_TYPE.DELETE_OPTION);
|
||||
}, [displayOptions, options, onChange]);
|
||||
|
||||
const onMouseEnter = useCallback((optionId) => {
|
||||
@@ -125,7 +126,7 @@ const OptionsPopover = ({ target, column, onToggle, onSubmit }) => {
|
||||
}, [deletingOptionId, onDelete]);
|
||||
|
||||
const onImportOptions = useCallback((options) => {
|
||||
onSubmit(options);
|
||||
onSubmit(options, COLUMN_DATA_OPERATION_TYPE.ADD_OPTION);
|
||||
setOptions(options);
|
||||
}, [onSubmit]);
|
||||
|
||||
|
@@ -3,6 +3,7 @@ import PropTypes from 'prop-types';
|
||||
import classnames from 'classnames';
|
||||
import { CustomizePopover, IconBtn } from '@seafile/sf-metadata-ui-component';
|
||||
import { SELECT_OPTION_COLORS } from '../../../../../constants';
|
||||
import { COLUMN_DATA_OPERATION_TYPE } from '../../../../../store/operations';
|
||||
|
||||
import './index.css';
|
||||
|
||||
@@ -31,7 +32,7 @@ const Color = ({ option, isViewing, isPredefined, onChange }) => {
|
||||
textColor: selected.TEXT_COLOR,
|
||||
borderColor: selected.BORDER_COLOR,
|
||||
});
|
||||
onChange(newOption);
|
||||
onChange(newOption, COLUMN_DATA_OPERATION_TYPE.MODIFY_OPTION_COLOR);
|
||||
}, [option, onChange]);
|
||||
|
||||
useEffect(() => {
|
||||
|
@@ -2,6 +2,7 @@ import React, { useCallback, useEffect, useRef, useState } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { Input } from 'reactstrap';
|
||||
import { KeyCodes } from '../../../../../../constants';
|
||||
import { COLUMN_DATA_OPERATION_TYPE } from '../../../../../store/operations';
|
||||
|
||||
import './index.css';
|
||||
|
||||
@@ -21,7 +22,7 @@ const Name = ({
|
||||
let newName = name.trim();
|
||||
if (newName === option.name || newName === '') return;
|
||||
const newOption = Object.assign({}, option, { name: newName });
|
||||
onChange(newOption, () => {
|
||||
onChange(newOption, COLUMN_DATA_OPERATION_TYPE.RENAME_OPTION, () => {
|
||||
onToggleFreeze(false);
|
||||
onClose();
|
||||
}, () => {
|
||||
|
@@ -1,12 +1,16 @@
|
||||
import { isTableRows } from '../utils/row';
|
||||
import { getColumnByKey } from '../utils/column';
|
||||
import { getColumnByKey, getColumnOriginName } from '../utils/column';
|
||||
import { getFilteredRows } from '../utils/filter';
|
||||
import { getGroupRows } from '../utils/group';
|
||||
import { sortTableRows } from '../utils/sort';
|
||||
import { getRowsByIds } from '../utils/table';
|
||||
import { isGroupView } from '../utils/view';
|
||||
import { username } from '../../utils/constants';
|
||||
import { OPERATION_TYPE } from './operations';
|
||||
import { COLUMN_DATA_OPERATION_TYPE, OPERATION_TYPE } from './operations';
|
||||
import { CellType, PRIVATE_COLUMN_KEY } from '../constants';
|
||||
import { getCellValueByColumn, getOption, isValidCellValue, checkIsPredefinedOption, getColumnOptionIdsByNames,
|
||||
getColumnOptionNamesByIds
|
||||
} from '../utils/cell';
|
||||
|
||||
// const DEFAULT_COMPUTER_PROPERTIES_CONTROLLER = {
|
||||
// isUpdateSummaries: true,
|
||||
@@ -142,6 +146,33 @@ class DataProcessor {
|
||||
this.updateSummaries();
|
||||
}
|
||||
|
||||
static updateRecordsWithModifyColumnData(table, column, operation) {
|
||||
const { old_data, new_data } = operation;
|
||||
const columnOriginalName = getColumnOriginName(column);
|
||||
const columnType = column.type;
|
||||
const oldColumn = { ...column, data: old_data };
|
||||
const newColumn = { ...column, data: new_data };
|
||||
|
||||
// modify row data
|
||||
for (const row of table.rows) {
|
||||
const cellValue = getCellValueByColumn(row, column);
|
||||
if (isValidCellValue(cellValue)) {
|
||||
if (columnType === CellType.SINGLE_SELECT && !checkIsPredefinedOption(column, cellValue)) {
|
||||
const oldOptions = old_data?.options || [];
|
||||
const newOptions = new_data?.options || [];
|
||||
const oldOption = getOption(oldOptions, cellValue);
|
||||
const newOption = getOption(newOptions, oldOption?.id);
|
||||
row[columnOriginalName] = newOption ? newOption.name : null;
|
||||
} else if (columnType === CellType.MULTIPLE_SELECT) {
|
||||
const oldOptionIds = getColumnOptionIdsByNames(oldColumn, cellValue);
|
||||
const newOptionNames = getColumnOptionNamesByIds(newColumn, oldOptionIds);
|
||||
row[columnOriginalName] = newOptionNames ? newOptionNames : null;
|
||||
}
|
||||
table.id_row_map[row[PRIVATE_COLUMN_KEY.ID]] = row;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static syncOperationOnData(table, operation, { collaborators }) {
|
||||
switch (operation.op_type) {
|
||||
case OPERATION_TYPE.MODIFY_RECORD:
|
||||
@@ -214,12 +245,22 @@ class DataProcessor {
|
||||
table.view.groups = this.getGroupedRows(table, rows, groupbys, { collaborators });
|
||||
break;
|
||||
}
|
||||
case OPERATION_TYPE.MODIFY_COLUMN_DATA: {
|
||||
const { column_key, option_modify_type } = operation;
|
||||
const column = getColumnByKey(table.columns, column_key);
|
||||
if (!column) break;
|
||||
if (column.type === CellType.SINGLE_SELECT || column.type === CellType.MULTIPLE_SELECT) {
|
||||
if (option_modify_type === COLUMN_DATA_OPERATION_TYPE.RENAME_OPTION) {
|
||||
this.updateRecordsWithModifyColumnData(table, column, operation);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default DataProcessor;
|
||||
|
@@ -413,10 +413,10 @@ class Store {
|
||||
this.applyOperation(operation);
|
||||
};
|
||||
|
||||
modifyColumnData = (columnKey, newData, oldData) => {
|
||||
modifyColumnData = (columnKey, newData, oldData, { optionModifyType } = {}) => {
|
||||
const type = OPERATION_TYPE.MODIFY_COLUMN_DATA;
|
||||
const operation = this.createOperation({
|
||||
type, repo_id: this.repoId, column_key: columnKey, new_data: newData, old_data: oldData
|
||||
type, repo_id: this.repoId, column_key: columnKey, new_data: newData, old_data: oldData, option_modify_type: optionModifyType
|
||||
});
|
||||
this.applyOperation(operation);
|
||||
};
|
||||
|
@@ -19,6 +19,14 @@ export const OPERATION_TYPE = {
|
||||
MODIFY_COLUMN_ORDER: 'modify_column_order',
|
||||
};
|
||||
|
||||
export const COLUMN_DATA_OPERATION_TYPE = {
|
||||
ADD_OPTION: 'add_options',
|
||||
DELETE_OPTION: 'delete_option',
|
||||
RENAME_OPTION: 'rename_option',
|
||||
MODIFY_OPTION_COLOR: 'modify_option_color',
|
||||
MOVE_OPTION: 'move_option',
|
||||
};
|
||||
|
||||
export const OPERATION_ATTRIBUTES = {
|
||||
[OPERATION_TYPE.MODIFY_RECORD]: ['repo_id', 'row_id', 'updates', 'old_row_data', 'original_updates', 'original_old_row_data'],
|
||||
[OPERATION_TYPE.MODIFY_RECORDS]: ['repo_id', 'row_ids', 'id_row_updates', 'id_original_row_updates', 'id_old_row_data', 'id_original_old_row_data', 'is_copy_paste', 'id_obj_id'],
|
||||
@@ -32,7 +40,7 @@ export const OPERATION_ATTRIBUTES = {
|
||||
[OPERATION_TYPE.MODIFY_RECORD_VIA_BUTTON]: ['repo_id', 'row_id', 'updates', 'old_row_data', 'original_updates', 'original_old_row_data', 'button_column_key'],
|
||||
[OPERATION_TYPE.INSERT_COLUMN]: ['repo_id', 'name', 'column_type', 'key', 'data'],
|
||||
[OPERATION_TYPE.RENAME_COLUMN]: ['repo_id', 'column_key', 'new_name', 'old_name'],
|
||||
[OPERATION_TYPE.MODIFY_COLUMN_DATA]: ['repo_id', 'column_key', 'new_data', 'old_data'],
|
||||
[OPERATION_TYPE.MODIFY_COLUMN_DATA]: ['repo_id', 'column_key', 'new_data', 'old_data', 'option_modify_type'],
|
||||
[OPERATION_TYPE.DELETE_COLUMN]: ['repo_id', 'column_key', 'column'],
|
||||
[OPERATION_TYPE.MODIFY_COLUMN_WIDTH]: ['column_key', 'new_width', 'old_width'],
|
||||
[OPERATION_TYPE.MODIFY_COLUMN_ORDER]: ['repo_id', 'view_id', 'new_columns_keys', 'old_columns_keys'],
|
||||
|
@@ -4,6 +4,7 @@ import Operation from './model';
|
||||
|
||||
export {
|
||||
OPERATION_TYPE,
|
||||
COLUMN_DATA_OPERATION_TYPE,
|
||||
OPERATION_ATTRIBUTES,
|
||||
UNDO_OPERATION_TYPE,
|
||||
LOCAL_APPLY_OPERATION_TYPE,
|
||||
|
@@ -108,8 +108,8 @@ const Table = () => {
|
||||
store.deleteColumn(columnKey, oldColumn);
|
||||
}, [store]);
|
||||
|
||||
const modifyColumnData = useCallback((columnKey, newData, oldData) => {
|
||||
store.modifyColumnData(columnKey, newData, oldData);
|
||||
const modifyColumnData = useCallback((columnKey, newData, oldData, { optionModifyType } = {}) => {
|
||||
store.modifyColumnData(columnKey, newData, oldData, { optionModifyType });
|
||||
}, [store]);
|
||||
|
||||
const modifyColumnWidth = useCallback((columnKey, newWidth) => {
|
||||
|
@@ -63,10 +63,10 @@ const HeaderDropdownMenu = ({ column, view, renameColumn, modifyColumnData, dele
|
||||
setOptionPopoverShow(false);
|
||||
}, []);
|
||||
|
||||
const onUpdateOptions = useCallback((options) => {
|
||||
const onUpdateOptions = useCallback((options, optionModifyType) => {
|
||||
const oldData = column.data || {};
|
||||
setMenuShow(false);
|
||||
modifyColumnData(column.key, { options }, { options: oldData.options || [] });
|
||||
modifyColumnData(column.key, { options }, { options: oldData.options || [] }, { optionModifyType });
|
||||
}, [column, modifyColumnData]);
|
||||
|
||||
// const toggleDefineCascade = useCallback(() => {
|
||||
|
Reference in New Issue
Block a user