1
0
mirror of https://github.com/haiwen/seahub.git synced 2025-04-28 03:10:45 +00:00
This commit is contained in:
zhouwenxuan 2025-04-10 17:46:07 +08:00
parent befb6de6aa
commit dfab8a0fe4
7 changed files with 135 additions and 15 deletions

View File

@ -0,0 +1,57 @@
.search-tags-container {
width: 100%;
height: fit-content;
display: flex;
flex-direction: column;
justify-content: flex-start;
font-size: 0.8125rem;
}
.search-tags-container .tags-title {
width: 100%;
height: 20px;
display: flex;
flex-direction: row;
justify-content: flex-start;
padding: 0 16px;
margin: 10px 0 4px;
font-size: 0.875rem;
color: #999;
}
.search-tags-container .tags-content {
width: 100%;
height: fit-content;
max-height: 180px;
overflow: auto;
scrollbar-color: #C1C1C1 rgba(0, 0, 0, 0);
padding: 0 16px;
margin-bottom: 10px;
}
.search-tags-container .tags-content .tag-item {
width: 100%;
height: 40px;
display: flex;
justify-content: flex-start;
align-items: center;
padding: 0 16px;
}
.search-tags-container .tags-content .tag-item:hover {
background-color: #f0f0f0;
cursor: pointer;
}
.search-tags-container .tags-content .tag-item .tag-color {
width: 12px;
height: 12px;
border-radius: 50%;
margin-right: 8px;
}
.search-tags-container .search-tags-divider {
height: 0;
border-top: 1px solid #eee;
margin: 0 16px;
}

View File

@ -0,0 +1,70 @@
import React, { useCallback, useEffect, useState } from 'react';
import PropTypes from 'prop-types';
import { gettext } from '../../../utils/constants';
import { getTagColor, getTagId, getTagName } from '../../../tag/utils/cell';
import { PRIVATE_FILE_TYPE } from '../../../constants';
import { EVENT_BUS_TYPE } from '../../../metadata/constants';
import './index.css';
const SearchTags = ({ repoID, data, keyword, onSelectTag }) => {
const [displayTags, setDisplayTags] = useState([]);
const handleClick = useCallback((e, tagId) => {
e.preventDefault();
e.stopPropagation();
const node = {
children: [],
path: '/' + PRIVATE_FILE_TYPE.TAGS_PROPERTIES + '/' + tagId,
isExpanded: false,
isLoaded: true,
isPreload: true,
object: {
file_tags: [],
id: tagId,
type: PRIVATE_FILE_TYPE.TAGS_PROPERTIES,
isDir: () => false,
},
parentNode: {},
key: repoID,
tag_id: tagId,
};
onSelectTag(node);
window.sfTagsDataContext?.eventBus?.dispatch(EVENT_BUS_TYPE.UPDATE_SELECTED_TAG, tagId);
}, [repoID, onSelectTag]);
useEffect(() => {
if (!data || !keyword) return;
const tags = data?.filter((tag) => getTagName(tag).toLowerCase().includes(keyword.toLowerCase()));
setDisplayTags(tags);
}, [data, keyword]);
if (!data || !keyword || displayTags.length === 0) return null;
return (
<div className="search-tags-container">
<div className="tags-title">{gettext('Tags')}</div>
<div className="tags-content">
{displayTags.map((tag) => {
const tagId = getTagId(tag);
const tagName = getTagName(tag);
const tagColor = getTagColor(tag);
return (
<div className="tag-item" key={tagId} onClick={(e) => handleClick(e, tagId)}>
<div className="tag-color" style={{ backgroundColor: tagColor }} />
<div className="tag-name">{tagName}</div>
</div>
);
})}
</div>
<div className="search-tags-divider" />
</div>
);
};
SearchTags.propTypes = {
data: PropTypes.object.isRequired,
};
export default SearchTags;

View File

@ -14,7 +14,7 @@ import Loading from '../loading';
import { SEARCH_MASK, SEARCH_CONTAINER } from '../../constants/zIndexes';
import { PRIVATE_FILE_TYPE } from '../../constants';
import SearchFilters from './search-filters';
import Tags from './tags';
import SearchTags from './search-tags';
const propTypes = {
repoID: PropTypes.string,
@ -807,7 +807,7 @@ class Search extends Component {
<SearchFilters onChange={this.handleFiltersChange} />
}
{isTagsShow &&
<Tags repoID={repoID} data={tagsData} keyword={this.state.value} onSelectTag={this.handleSelectTag} />
<SearchTags repoID={repoID} data={tagsData} keyword={this.state.value} onSelectTag={this.handleSelectTag} />
}
<div
className="search-result-container dropdown-search-result-container"

View File

@ -42,7 +42,7 @@ class CommonToolbar extends React.Component {
if (this.props.eventBus) {
this.unsubscribeLibChange = this.props.eventBus.subscribe(EVENT_BUS_TYPE.CURRENT_LIBRARY_CHANGED, this.onRepoChange);
this.unsubscribeTagStatus = this.props.eventBus.subscribe(EVENT_BUS_TYPE.TAG_STATUS, (status) => this.onTagStatus(status));
this.unsubscribeTagsChanged = this.props.eventBus.subscribe(EVENT_BUS_TYPE.TAGS_CHANGED, this.onTagsChanged);
this.unsubscribeTagsChanged = this.props.eventBus.subscribe(EVENT_BUS_TYPE.TAGS_CHANGED, (tags) => this.setState({ tagsData: tags }));
}
}
@ -62,13 +62,6 @@ class CommonToolbar extends React.Component {
}
};
onTagsChanged = () => {
tagsAPI.getTags(this.state.repoID).then((res) => {
const tags = res?.data?.results || null;
this.setState({ tagsData: tags });
});
};
onSelectTag = (tag) => {
this.props.eventBus.dispatch(EVENT_BUS_TYPE.SELECT_TAG, tag);
};

View File

@ -2273,8 +2273,8 @@ class LibContentView extends React.Component {
this.clearRepoTags();
};
tagsChangedCallback = () => {
this.props.eventBus.dispatch(EVENT_BUS_TYPE.TAGS_CHANGED);
tagsChangedCallback = (tags) => {
this.props.eventBus.dispatch(EVENT_BUS_TYPE.TAGS_CHANGED, tags);
};
render() {

View File

@ -31,7 +31,7 @@ export const TagsProvider = ({ repoID, currentPath, selectTagsView, tagsChangedC
const tagsChanged = useCallback(() => {
setTagsData(storeRef.current.data);
tagsChangedCallback && tagsChangedCallback();
tagsChangedCallback && tagsChangedCallback(storeRef.current.data.rows);
}, [tagsChangedCallback]);
const handleTableError = useCallback((error) => {

View File

@ -105,7 +105,7 @@ const TagsTreeView = ({ currentPath }) => {
}, [getKeyTreeNodeExpandedMap]);
useEffect(() => {
window.sfTagsDataContext?.eventBus?.subscribe(EVENT_BUS_TYPE.UPDATE_SELECTED_TAG, (tagId) => {
const unsubscribeUpdateSelectedTag = window.sfTagsDataContext?.eventBus?.subscribe(EVENT_BUS_TYPE.UPDATE_SELECTED_TAG, (tagId) => {
if (tagId) {
const node = recordsTree.find((node) => getTreeNodeId(node) === tagId);
const nodeKey = getTreeNodeKey(node);
@ -115,7 +115,7 @@ const TagsTreeView = ({ currentPath }) => {
});
return () => {
window.sfTagsDataContext?.eventBus?.unsubscribe(EVENT_BUS_TYPE.UPDATE_SELECTED_TAG);
unsubscribeUpdateSelectedTag && unsubscribeUpdateSelectedTag();
};
}, [recordsTree]);