Skip to content

Commit

Permalink
refactor(tag): parent tag files count includes children (#7420)
Browse files Browse the repository at this point in the history
  • Loading branch information
renjie-run authored Jan 23, 2025
1 parent 076d147 commit b7d9f78
Show file tree
Hide file tree
Showing 17 changed files with 294 additions and 84 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,7 @@ class ActionsCell extends Component {
};

getRecordNo = () => {
if (this.props.showRecordAsTree) {
return this.props.treeNodeDisplayIndex;
}
return this.props.index + 1;
return (this.props.showRecordAsTree ? this.props.treeNodeIndex : this.props.index) + 1;
};

render() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,12 @@ const Cell = React.memo(({
frozen,
height,
showRecordAsTree,
nodeDepth,
treeNodeIndex,
treeNodeDepth,
hasChildNodes,
isFoldedNode,
isFoldedTreeNode,
checkCanModifyRecord,
toggleExpandNode,
toggleExpandTreeNode,
}) => {
const cellEditable = useMemo(() => {
return checkIsColumnEditable(column) && checkCanModifyRecord && checkCanModifyRecord(record);
Expand Down Expand Up @@ -168,19 +169,19 @@ const Cell = React.memo(({
};

const renderCellContent = useCallback(() => {
const columnFormatter = isValidElement(column.formatter) && cloneElement(column.formatter, { isCellSelected, value: cellValue, column, record, onChange: modifyRecord });
const columnFormatter = isValidElement(column.formatter) && cloneElement(column.formatter, { isCellSelected, value: cellValue, column, record, treeNodeIndex, onChange: modifyRecord });
if (showRecordAsTree && isNameColumn) {
return (
<div className="sf-table-cell-tree-node">
{hasChildNodes && <span className="sf-table-record-tree-expand-icon" style={{ left: nodeDepth * NODE_ICON_LEFT_INDENT }} onClick={toggleExpandNode}><i className={classnames('sf3-font sf3-font-down', { 'rotate-270': isFoldedNode })}></i></span>}
<div className="sf-table-cell-tree-node-content" style={{ paddingLeft: NODE_CONTENT_LEFT_INDENT + nodeDepth * NODE_ICON_LEFT_INDENT }}>
{hasChildNodes && <span className="sf-table-record-tree-expand-icon" style={{ left: treeNodeDepth * NODE_ICON_LEFT_INDENT }} onClick={toggleExpandTreeNode}><i className={classnames('sf3-font sf3-font-down', { 'rotate-270': isFoldedTreeNode })}></i></span>}
<div className="sf-table-cell-tree-node-content" style={{ paddingLeft: NODE_CONTENT_LEFT_INDENT + treeNodeDepth * NODE_ICON_LEFT_INDENT }}>
{columnFormatter}
</div>
</div>
);
}
return columnFormatter;
}, [isNameColumn, column, isCellSelected, cellValue, record, showRecordAsTree, nodeDepth, hasChildNodes, isFoldedNode, modifyRecord, toggleExpandNode]);
}, [isNameColumn, column, isCellSelected, cellValue, record, showRecordAsTree, treeNodeIndex, treeNodeDepth, hasChildNodes, isFoldedTreeNode, modifyRecord, toggleExpandTreeNode]);

return (
<div key={`${record._id}-${column.key}`} {...containerProps}>
Expand Down Expand Up @@ -208,14 +209,15 @@ Cell.propTypes = {
column: PropTypes.object.isRequired,
height: PropTypes.number,
needBindEvents: PropTypes.bool,
modifyRecord: PropTypes.func,
highlightClassName: PropTypes.string,
bgColor: PropTypes.string,
showRecordAsTree: PropTypes.bool,
nodeDepth: PropTypes.number,
treeNodeIndex: PropTypes.number,
treeNodeDepth: PropTypes.number,
hasChildNodes: PropTypes.bool,
isFoldedNode: PropTypes.bool,
toggleExpandNode: PropTypes.func,
isFoldedTreeNode: PropTypes.bool,
modifyRecord: PropTypes.func,
toggleExpandTreeNode: PropTypes.func,
};

export default Cell;
34 changes: 18 additions & 16 deletions frontend/src/components/sf-table/table-main/records/record/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,11 @@ class Record extends React.Component {
nextProps.searchResult !== this.props.searchResult ||
nextProps.columnColor !== this.props.columnColor ||
nextProps.showRecordAsTree !== this.props.showRecordAsTree ||
nextProps.nodeKey !== this.props.nodeKey ||
nextProps.nodeDepth !== this.props.nodeDepth ||
nextProps.treeNodeIndex !== this.props.treeNodeIndex ||
nextProps.treeNodeKey !== this.props.treeNodeKey ||
nextProps.treeNodeDepth !== this.props.treeNodeDepth ||
nextProps.hasChildNodes !== this.props.hasChildNodes ||
nextProps.treeNodeDisplayIndex !== this.props.treeNodeDisplayIndex ||
nextProps.isFoldedNode !== this.props.isFoldedNode
nextProps.isFoldedTreeNode !== this.props.isFoldedTreeNode
);
}

Expand Down Expand Up @@ -116,10 +116,11 @@ class Record extends React.Component {
highlightClassName={highlightClassName}
bgColor={bgColor}
showRecordAsTree={this.props.showRecordAsTree}
nodeDepth={this.props.nodeDepth}
treeNodeIndex={this.props.treeNodeIndex}
treeNodeDepth={this.props.treeNodeDepth}
hasChildNodes={this.props.hasChildNodes}
isFoldedNode={this.props.isFoldedNode}
toggleExpandNode={this.props.toggleExpandNode}
isFoldedTreeNode={this.props.isFoldedTreeNode}
toggleExpandTreeNode={this.props.toggleExpandTreeNode}
/>
);
});
Expand Down Expand Up @@ -183,10 +184,11 @@ class Record extends React.Component {
highlightClassName={highlightClassName}
bgColor={bgColor}
showRecordAsTree={this.props.showRecordAsTree}
nodeDepth={this.props.nodeDepth}
treeNodeIndex={this.props.treeNodeIndex}
treeNodeDepth={this.props.treeNodeDepth}
hasChildNodes={this.props.hasChildNodes}
isFoldedNode={this.props.isFoldedNode}
toggleExpandNode={this.props.toggleExpandNode}
isFoldedTreeNode={this.props.isFoldedTreeNode}
toggleExpandTreeNode={this.props.toggleExpandTreeNode}
/>
);
});
Expand Down Expand Up @@ -273,7 +275,7 @@ class Record extends React.Component {
recordId={record._id}
index={index}
showRecordAsTree={this.props.showRecordAsTree}
treeNodeDisplayIndex={this.props.treeNodeDisplayIndex}
treeNodeIndex={this.props.treeNodeIndex}
onSelectRecord={this.onSelectRecord}
isLastFrozenCell={!lastFrozenColumnKey}
height={cellHeight}
Expand Down Expand Up @@ -316,12 +318,12 @@ Record.propTypes = {
searchResult: PropTypes.object,
columnColor: PropTypes.object,
showRecordAsTree: PropTypes.bool,
nodeKey: PropTypes.string,
nodeDepth: PropTypes.number,
treeNodeIndex: PropTypes.number,
treeNodeKey: PropTypes.string,
treeNodeDepth: PropTypes.number,
hasChildNodes: PropTypes.bool,
treeNodeDisplayIndex: PropTypes.number,
isFoldedNode: PropTypes.bool,
toggleExpandNode: PropTypes.func,
isFoldedTreeNode: PropTypes.bool,
toggleExpandTreeNode: PropTypes.func,
};

export default Record;
14 changes: 7 additions & 7 deletions frontend/src/components/sf-table/table-main/records/tree-body.js
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ class TreeBody extends Component {
if (row && checkIsTreeNodeShown(nodeKey, keyNodeFoldedMap)) {
shownNodes.push({
...node,
node_display_index: index + 1,
node_index: index,
});
}
});
Expand Down Expand Up @@ -535,7 +535,7 @@ class TreeBody extends Component {
const rowHeight = this.getRowHeight();
const cellMetaData = this.getCellMetaData();
let shownNodes = visibleNodes.map((node, index) => {
const { _id: recordId, node_key, node_depth, node_display_index } = node;
const { _id: recordId, node_key, node_depth, node_index } = node;
const hasChildNodes = checkTreeNodeHasChildNodes(node);
const record = this.props.recordGetterById(recordId);
const isSelected = TreeMetrics.checkIsTreeNodeSelected(node_key, treeMetrics);
Expand All @@ -553,7 +553,6 @@ class TreeBody extends Component {
}}
isSelected={isSelected}
index={recordIndex}
treeNodeDisplayIndex={node_display_index}
isLastRecord={isLastRecord}
showSequenceColumn={this.props.showSequenceColumn}
record={record}
Expand All @@ -567,17 +566,18 @@ class TreeBody extends Component {
cellMetaData={cellMetaData}
columnColor={columnColor}
searchResult={this.props.searchResult}
nodeKey={node_key}
nodeDepth={node_depth}
treeNodeIndex={node_index}
treeNodeKey={node_key}
treeNodeDepth={node_depth}
hasChildNodes={hasChildNodes}
isFoldedNode={isFoldedNode}
isFoldedTreeNode={isFoldedNode}
checkCanModifyRecord={this.props.checkCanModifyRecord}
checkCellValueChanged={this.props.checkCellValueChanged}
hasSelectedCell={hasSelectedCell}
selectedPosition={selectedPosition}
selectNoneCells={this.selectNoneCells}
onSelectRecord={this.props.onSelectRecord}
toggleExpandNode={() => this.toggleExpandNode(node_key)}
toggleExpandTreeNode={() => this.toggleExpandNode(node_key)}
/>
);
});
Expand Down
7 changes: 4 additions & 3 deletions frontend/src/components/sf-table/utils/cell-comparer.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export const checkCellValueChanged = (oldVal, newVal) => {
export const cellCompare = (props, nextProps) => {
const {
record: oldRecord, column, isCellSelected, isLastCell, highlightClassName, height, bgColor,
showRecordAsTree, nodeDepth, hasChildNodes, isFoldedNode,
showRecordAsTree, treeNodeIndex, treeNodeDepth, hasChildNodes, isFoldedTreeNode,
} = props;
const {
record: newRecord, highlightClassName: newHighlightClassName, height: newHeight, column: newColumn, bgColor: newBgColor,
Expand All @@ -49,9 +49,10 @@ export const cellCompare = (props, nextProps) => {
!ObjectUtils.isSameObject(column.data, newColumn.data) ||
bgColor !== newBgColor ||
showRecordAsTree !== nextProps.showRecordAsTree ||
nodeDepth !== nextProps.nodeDepth ||
treeNodeIndex !== nextProps.treeNodeIndex ||
treeNodeDepth !== nextProps.treeNodeDepth ||
hasChildNodes !== nextProps.hasChildNodes ||
isFoldedNode !== nextProps.isFoldedNode ||
isFoldedTreeNode !== nextProps.isFoldedTreeNode ||
props.groupRecordIndex !== nextProps.groupRecordIndex ||
props.recordIndex !== nextProps.recordIndex
);
Expand Down
35 changes: 33 additions & 2 deletions frontend/src/components/sf-table/utils/tree.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ export const generateKeyTreeNodeRowIdMap = (tree) => {
return tree_node_key_row_id_map;
};


export const getValidKeyTreeNodeFoldedMap = (keyTreeNodeFoldedMap, treeNodeKeyRecordIdMap) => {
if (!keyTreeNodeFoldedMap) return {};

Expand Down Expand Up @@ -71,6 +70,21 @@ export const checkIsTreeNodeShown = (nodeKey, keyFoldedNodeMap) => {
return !foldedNodeKeys.some((foldedNodeKey) => nodeKey !== foldedNodeKey && nodeKey.includes(foldedNodeKey));
};

export const updatedKeyTreeNodeMap = (nodeKey, node, keyTreeNodeMap) => {
if (!nodeKey || !node || !keyTreeNodeMap) return;
keyTreeNodeMap[nodeKey] = node;
};

export const getTreeNodeByKey = (nodeKey, keyTreeNodeMap) => {
if (!nodeKey || !keyTreeNodeMap) return null;
return keyTreeNodeMap[nodeKey];
};

export const getTreeNodeById = (nodeId, tree) => {
if (!nodeId || !Array.isArray(tree) || tree.length === 0) return null;
return tree.find((node) => getTreeNodeId(node) === nodeId);
};

export const getTreeNodeId = (node) => {
return node ? node[TREE_NODE_KEY.ID] : '';
};
Expand All @@ -95,7 +109,7 @@ export const resetTreeHasChildNodesStatus = (tree) => {
const nextNode = tree[index + 1];
const nextNodeKey = getTreeNodeKey(nextNode);
const currentNodeKey = getTreeNodeKey(node);
if (nextNode && checkTreeNodeHasChildNodes(node) && !nextNodeKey.includes(currentNodeKey)) {
if (checkTreeNodeHasChildNodes(node) && (!nextNode || !nextNodeKey.includes(currentNodeKey))) {
tree[index][TREE_NODE_KEY.HAS_CHILD_NODES] = false;
}
});
Expand Down Expand Up @@ -131,3 +145,20 @@ export const addTreeChildNode = (newChildNode, parentNode, tree) => {
}
tree.splice(lastChildNodeIndex + 1, 0, newChildNode);
};

export const getAllSubTreeNodes = (nodeIndex, tree) => {
const treeLen = Array.isArray(tree) ? tree.length : 0;
const parentNode = tree[nodeIndex];
const parentNodeKey = getTreeNodeKey(parentNode);
if (!parentNodeKey || nodeIndex === treeLen - 1) return [];

let subNodes = [];
for (let i = nodeIndex + 1, len = treeLen; i < len; i++) {
const currNodeKey = getTreeNodeKey(tree[i]);
if (!currNodeKey || !currNodeKey.includes(parentNodeKey)) {
break;
}
subNodes.push(tree[i]);
}
return subNodes;
};
6 changes: 6 additions & 0 deletions frontend/src/tag/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,12 @@ class TagsManagerAPI {
return this.req.get(url);
};

getTagsFiles = (repoID, tags_ids) => {
const url = this.server + '/api/v2.1/repos/' + repoID + '/metadata/tags-files/';
const params = { tags_ids };
return this.req.post(url, params);
};

// file tags
updateFileTags = (repoID, data) => {
const url = this.server + '/api/v2.1/repos/' + repoID + '/metadata/file-tags/';
Expand Down
36 changes: 19 additions & 17 deletions frontend/src/tag/hooks/tag-view.js
Original file line number Diff line number Diff line change
@@ -1,42 +1,44 @@
import React, { useContext, useEffect, useState } from 'react';
import React, { useCallback, useContext, useEffect, useState } from 'react';
import { Utils } from '../../utils/utils';
import tagsAPI from '../api';
import { useTags } from './tags';
import { PRIVATE_COLUMN_KEY } from '../constants';
import { getRecordIdFromRecord } from '../../metadata/utils/cell';
import { getTreeNodeByKey } from '../../components/sf-table/utils/tree';
import { getAllChildTagsIdsFromNode } from '../utils/tree';

// This hook provides content related to seahub interaction, such as whether to enable extended attributes, views data, etc.
const TagViewContext = React.createContext(null);

export const TagViewProvider = ({ repoID, tagID, children, ...params }) => {
export const TagViewProvider = ({ repoID, tagID, nodeKey, children, ...params }) => {
const [isLoading, setLoading] = useState(true);
const [tagFiles, setTagFiles] = useState(null);
const [errorMessage, setErrorMessage] = useState(null);

const { updateLocalTag } = useTags();
const { tagsData } = useTags();

const getChildTagsIds = useCallback((nodeKey) => {
if (!nodeKey) return [];
const displayNode = getTreeNodeByKey(nodeKey, tagsData.key_tree_node_map);
return getAllChildTagsIdsFromNode(displayNode);
}, [tagsData]);

useEffect(() => {
setLoading(true);
tagsAPI.getTagFiles(repoID, tagID).then(res => {
const childTagsIds = getChildTagsIds(nodeKey);
let tagsIds = [tagID];
if (Array.isArray(childTagsIds) && childTagsIds.length > 0) {
tagsIds.push(...childTagsIds);
}
tagsAPI.getTagsFiles(repoID, tagsIds).then(res => {
const rows = res.data?.results || [];
setTagFiles({ columns: res.data?.metadata || [], rows: res.data?.results || [] });
updateLocalTag(tagID, {
[PRIVATE_COLUMN_KEY.TAG_FILE_LINKS]: rows.map(r => {
const recordId = getRecordIdFromRecord(r);
return {
row_id: recordId,
display_value: recordId
};
})
});
setTagFiles({ columns: res.data?.metadata || [], rows });
setLoading(false);
}).catch(error => {
const errorMessage = Utils.getErrorMsg(error);
setErrorMessage(errorMessage);
setLoading(false);
});
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [repoID, tagID]);
}, [repoID, tagID, nodeKey]);

return (
<TagViewContext.Provider value={{
Expand Down
Loading

0 comments on commit b7d9f78

Please sign in to comment.