1
0
mirror of https://github.com/haiwen/seahub.git synced 2025-09-05 08:53:14 +00:00

Optimize/all tags view toolbar (#7593)

* all tags view toolbar

* optimize

---------

Co-authored-by: zhouwenxuan <aries@Mac.local>
This commit is contained in:
Aries
2025-03-12 13:55:41 +08:00
committed by GitHub
parent d58878ec39
commit a2ee1fede2
9 changed files with 159 additions and 13 deletions

View File

@@ -160,6 +160,7 @@ SFTable.propTypes = {
loadAll: PropTypes.func,
moveRecords: PropTypes.func,
renderCustomDraggedRows: PropTypes.func,
updateSelectedRecordIds: PropTypes.func,
};
export default SFTable;

View File

@@ -411,6 +411,7 @@ class Records extends Component {
// clear selected records
this.onDeselectAllRecords();
this.props.updateSelectedRecordIds([]);
};
selectCell = (cellPosition) => {
@@ -603,6 +604,7 @@ class Records extends Component {
const { treeMetrics } = this.state;
let updatedTreeMetrics = { ...treeMetrics };
TreeMetrics.selectTreeNodesByKeys(nodesKeys, updatedTreeMetrics);
this.props.updateSelectedRecordIds(TreeMetrics.getSelectedIds(updatedTreeMetrics, this.props.treeNodeKeyRecordIdMap));
this.setState({ treeMetrics: updatedTreeMetrics });
};
@@ -614,6 +616,7 @@ class Records extends Component {
let updatedTreeMetrics = { ...treeMetrics };
TreeMetrics.selectTreeNode(nodeKey, updatedTreeMetrics);
this.props.updateSelectedRecordIds(TreeMetrics.getSelectedIds(updatedTreeMetrics, this.props.treeNodeKeyRecordIdMap));
this.setState({ treeMetrics: updatedTreeMetrics });
};
@@ -624,6 +627,7 @@ class Records extends Component {
}
let updatedTreeMetrics = { ...treeMetrics };
TreeMetrics.deselectTreeNode(nodeKey, updatedTreeMetrics);
this.props.updateSelectedRecordIds(TreeMetrics.getSelectedIds(updatedTreeMetrics, this.props.treeNodeKeyRecordIdMap));
this.setState({ treeMetrics: updatedTreeMetrics });
};
@@ -633,6 +637,7 @@ class Records extends Component {
let updatedTreeMetrics = { ...treeMetrics };
const allNodesKeys = recordsTree.map((node) => getTreeNodeKey(node)).filter(Boolean);
TreeMetrics.selectTreeNodesByKeys(allNodesKeys, updatedTreeMetrics);
this.props.updateSelectedRecordIds(TreeMetrics.getSelectedIds(updatedTreeMetrics, this.props.treeNodeKeyRecordIdMap));
this.setState({ recordMetrics: updatedTreeMetrics });
};
@@ -1063,6 +1068,7 @@ Records.propTypes = {
moveRecord: PropTypes.func,
addFolder: PropTypes.func,
moveRecords: PropTypes.func,
updateSelectedRecordIds: PropTypes.func,
};
export default Records;

View File

@@ -0,0 +1,81 @@
import React, { useCallback, useEffect, useState } from 'react';
import { gettext } from '../../utils/constants';
import ItemDropdownMenu from '../dropdown-menu/metadata-item-dropdown-menu';
import { EVENT_BUS_TYPE } from '../../metadata/constants';
import TextTranslation from '../../utils/text-translation';
import EventBus from '../common/event-bus';
const AllTagsToolbar = () => {
const [selectedTagIds, setSelectedTagIds] = useState([]);
const canDelete = window.sfTagsDataContext && window.sfTagsDataContext.checkCanDeleteTag();
const eventBus = EventBus.getInstance();
const unSelect = useCallback(() => {
eventBus && eventBus.dispatch(EVENT_BUS_TYPE.SELECT_NONE);
}, [eventBus]);
const deleteTags = useCallback(() => {
eventBus && eventBus.dispatch(EVENT_BUS_TYPE.DELETE_TAGS, selectedTagIds);
}, [selectedTagIds, eventBus]);
const getMenuList = useCallback(() => {
const { MERGE_TAGS, NEW_CHILD_TAG } = TextTranslation;
const list = [];
if (selectedTagIds.length > 1) {
list.push(MERGE_TAGS);
return list;
}
list.push(NEW_CHILD_TAG);
return list;
}, [selectedTagIds]);
const onMenuItemClick = useCallback((operation, e) => {
switch (operation) {
case TextTranslation.MERGE_TAGS.key: {
eventBus && eventBus.dispatch(EVENT_BUS_TYPE.MERGE_TAGS, selectedTagIds, { left: e.clientX, top: e.clientY });
break;
}
case TextTranslation.NEW_CHILD_TAG.key: {
eventBus && eventBus.dispatch(EVENT_BUS_TYPE.NEW_SUB_TAG, selectedTagIds[0]);
break;
}
}
}, [eventBus, selectedTagIds]);
useEffect(() => {
const unsubscribeSelectTags = eventBus && eventBus.subscribe(EVENT_BUS_TYPE.SELECT_TAGS, (ids) => {
setSelectedTagIds(ids);
});
return () => {
unsubscribeSelectTags && unsubscribeSelectTags();
};
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
const length = selectedTagIds.length;
return (
<div className="selected-dirents-toolbar">
<span className="cur-view-path-btn px-2" onClick={unSelect}>
<span className="sf3-font-x-01 sf3-font mr-2" aria-label={gettext('Unselect')} title={gettext('Unselect')}></span>
<span>{length}{' '}{gettext('selected')}</span>
</span>
{canDelete &&
<span className="cur-view-path-btn" onClick={deleteTags}>
<span className="sf3-font-delete1 sf3-font" aria-label={gettext('Delete')} title={gettext('Delete')}></span>
</span>
}
{length > 0 && (
<ItemDropdownMenu
item={{}}
toggleClass={'cur-view-path-btn sf3-font-more-vertical sf3-font'}
onMenuItemClick={onMenuItemClick}
getMenuList={getMenuList}
/>
)}
</div>
);
};
export default AllTagsToolbar;

View File

@@ -0,0 +1,28 @@
import React from 'react';
import PropTypes from 'prop-types';
import { TAGS_MODE } from '../dir-view-mode/constants';
import { ALL_TAGS_ID } from '../../tag/constants';
import AllTagsToolbar from './all-tags-toolbar';
import TagFilesToolbar from './tag-files-toolbar';
import TableFilesToolbar from './table-files-toolbar';
const MetadataPathToolbar = ({ repoID, repoInfo, mode, path }) => {
if (mode === TAGS_MODE) {
const isAllTagsView = path.split('/').pop() === ALL_TAGS_ID;
if (isAllTagsView) return <AllTagsToolbar />;
return <TagFilesToolbar currentRepoInfo={repoInfo} />;
}
return (
<TableFilesToolbar repoID={repoID} />
);
};
MetadataPathToolbar.propTypes = {
repoID: PropTypes.string.isRequired,
repoInfo: PropTypes.object.isRequired,
mode: PropTypes.string.isRequired,
path: PropTypes.string.isRequired,
};
export default MetadataPathToolbar;

View File

@@ -99,6 +99,12 @@ export const EVENT_BUS_TYPE = {
SELECT_TAG_FILES: 'select_tag_files',
UNSELECT_TAG_FILES: 'unselect_tag_files',
// tags
SELECT_TAGS: 'select_tags',
DELETE_TAGS: 'delete_tags',
MERGE_TAGS: 'merge_tags',
NEW_SUB_TAG: 'new_sub_tag',
// file
FILE_HISTORY: 'file_history',
FILE_ACCESS_LOG: 'file_access_log',

View File

@@ -30,8 +30,7 @@ import DirTool from '../../components/cur-dir-path/dir-tool';
import Detail from '../../components/dirent-detail';
import DirColumnView from '../../components/dir-view-mode/dir-column-view';
import SelectedDirentsToolbar from '../../components/toolbar/selected-dirents-toolbar';
import TagFilesToolbar from '../../components/toolbar/tag-files-toolbar';
import TableFilesToolbar from '../../components/toolbar/table-files-toolbar';
import MetadataPathToolbar from '../../components/toolbar/metadata-path-toolbar';
import '../../css/lib-content-view.css';
@@ -2193,7 +2192,7 @@ class LibContentView extends React.Component {
render() {
const { repoID } = this.props;
let { currentRepoInfo, userPerm, isCopyMoveProgressDialogShow, isDeleteFolderDialogOpen, errorMsg,
path, usedRepoTags, isDirentSelected } = this.state;
path, usedRepoTags, isDirentSelected, currentMode } = this.state;
if (this.state.libNeedDecrypt) {
return (
@@ -2278,10 +2277,8 @@ class LibContentView extends React.Component {
'animation-children': isDirentSelected
})}>
{isDirentSelected ? (
this.state.currentMode === TAGS_MODE ? (
<TagFilesToolbar currentRepoInfo={this.state.currentRepoInfo} />
) : this.state.currentMode === METADATA_MODE ? (
<TableFilesToolbar repoID={this.props.repoID} />
currentMode === TAGS_MODE || currentMode === METADATA_MODE ? (
<MetadataPathToolbar repoID={repoID} repoInfo={currentRepoInfo} mode={currentMode} path={path} />
) : (
<SelectedDirentsToolbar
repoID={this.props.repoID}

View File

@@ -13,7 +13,7 @@ import { ALL_TAGS_ID } from '../../constants';
import './index.css';
const AllTags = ({ updateCurrentPath, ...params }) => {
const AllTags = ({ updateCurrentPath, toggleShowDirentToolbar, ...params }) => {
const [displayTag, setDisplayTag] = useState('');
const [isLoadingMore, setLoadingMore] = useState(false);
@@ -99,6 +99,7 @@ const AllTags = ({ updateCurrentPath, ...params }) => {
setDisplayTag={onChangeDisplayTag}
isLoadingMoreRecords={isLoadingMore}
loadMore={loadMore}
toggleShowDirentToolbar={toggleShowDirentToolbar}
/>
</div>
);

View File

@@ -36,6 +36,7 @@ const TagsTable = ({
modifyColumnWidth: modifyColumnWidthAPI,
setDisplayTag,
loadMore,
toggleShowDirentToolbar,
}) => {
const { tagsData, updateTag, deleteTags, addTagLinks, deleteTagLinks, deleteTagsLinks, addChildTag, mergeTags } = useTags();
@@ -46,6 +47,8 @@ const TagsTable = ({
const parentTagIdRef = useRef(null);
const mergeTagsSelectorProps = useRef({});
const eventBus = EventBus.getInstance();
const table = useMemo(() => {
if (!tagsData) {
return {
@@ -108,10 +111,9 @@ const TagsTable = ({
const onDeleteTags = useCallback((tagsIds) => {
deleteTags(tagsIds);
const eventBus = EventBus.getInstance();
toggleShowDirentToolbar(false);
eventBus.dispatch(TABLE_EVENT_BUS_TYPE.SELECT_NONE);
}, [deleteTags]);
}, [eventBus, deleteTags, toggleShowDirentToolbar]);
const onNewSubTag = useCallback((parentTagId) => {
parentTagIdRef.current = parentTagId;
@@ -260,13 +262,25 @@ const TagsTable = ({
}
}, [table, addTagLinks, deleteTagsLinks]);
const updateSelectedTagIds = useCallback((ids) => {
toggleShowDirentToolbar(ids.length > 0);
setTimeout(() => {
eventBus && eventBus.dispatch(EVENT_BUS_TYPE.SELECT_TAGS, ids);
}, 0);
}, [eventBus, toggleShowDirentToolbar]);
useEffect(() => {
const eventBus = EventBus.getInstance();
const unsubscribeUpdateSearchResult = eventBus.subscribe(EVENT_BUS_TYPE.UPDATE_SEARCH_RESULT, updateSearchResult);
const unsubscribeDeleteTags = eventBus.subscribe(EVENT_BUS_TYPE.DELETE_TAGS, onDeleteTags);
const unsubscribeMergeTags = eventBus.subscribe(EVENT_BUS_TYPE.MERGE_TAGS, onMergeTags);
const unsubscribeNewSubTag = eventBus.subscribe(EVENT_BUS_TYPE.NEW_SUB_TAG, onNewSubTag);
return () => {
unsubscribeUpdateSearchResult();
unsubscribeDeleteTags();
unsubscribeMergeTags();
unsubscribeNewSubTag();
};
}, [updateSearchResult]);
}, [eventBus, updateSearchResult, onDeleteTags, onMergeTags, onNewSubTag, updateSelectedTagIds]);
return (
<>
@@ -296,6 +310,7 @@ const TagsTable = ({
loadMore={loadMore}
renderCustomDraggedRows={renderCustomDraggedRows}
moveRecords={moveTags}
updateSelectedRecordIds={updateSelectedTagIds}
/>
{isShowNewSubTagDialog && (
<EditTagDialog tags={table.rows} title={gettext('New child tag')} onToggle={closeNewSubTagDialog} onSubmit={handelAddChildTag} />
@@ -314,6 +329,7 @@ TagsTable.propTypes = {
modifyColumnWidth: PropTypes.func,
setDisplayTag: PropTypes.func,
loadMore: PropTypes.func,
toggleShowDirentToolbar: PropTypes.func,
};
export default TagsTable;

View File

@@ -256,6 +256,16 @@ const TextTranslation = {
key: 'OCR',
value: gettext('OCR'),
},
// tag view
MERGE_TAGS: {
key: 'Merge tags',
value: gettext('Merge tags'),
},
NEW_CHILD_TAG: {
key: 'New child tag',
value: gettext('New child tag'),
},
};
export default TextTranslation;