mirror of
https://github.com/haiwen/seahub.git
synced 2025-09-19 18:29:23 +00:00
refactor(tag): open tag files via click name (#7377)
This commit is contained in:
@@ -95,7 +95,6 @@ export const TagsProvider = ({ repoID, currentPath, selectTagsView, children, ..
|
||||
const handelSelectTag = useCallback((tag, isSelected) => {
|
||||
if (isSelected) return;
|
||||
const id = getTagId(tag);
|
||||
setReloading(id === ALL_TAGS_ID);
|
||||
const node = {
|
||||
children: [],
|
||||
path: '/' + PRIVATE_FILE_TYPE.TAGS_PROPERTIES + '/' + id,
|
||||
@@ -259,6 +258,7 @@ export const TagsProvider = ({ repoID, currentPath, selectTagsView, children, ..
|
||||
isLoading,
|
||||
isReloading,
|
||||
tagsData,
|
||||
currentPath,
|
||||
store: storeRef.current,
|
||||
context: contextRef.current,
|
||||
deleteFilesCallback: params.deleteFilesCallback,
|
||||
|
@@ -17,7 +17,7 @@ const AllTags = ({ updateCurrentPath, ...params }) => {
|
||||
const [displayTag, setDisplayTag] = useState('');
|
||||
const [isLoadingMore, setLoadingMore] = useState(false);
|
||||
|
||||
const { isLoading, isReloading, tagsData, store, context } = useTags();
|
||||
const { isLoading, isReloading, tagsData, store, context, currentPath } = useTags();
|
||||
|
||||
useEffect(() => {
|
||||
const eventBus = context.eventBus;
|
||||
@@ -26,6 +26,16 @@ const AllTags = ({ updateCurrentPath, ...params }) => {
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (!currentPath) return;
|
||||
if (!currentPath.includes('/' + PRIVATE_FILE_TYPE.TAGS_PROPERTIES + '/')) return;
|
||||
const pathList = currentPath.split('/');
|
||||
const [, , currentTagId, children] = pathList;
|
||||
if (currentTagId === ALL_TAGS_ID && !children) {
|
||||
setDisplayTag('');
|
||||
}
|
||||
}, [currentPath]);
|
||||
|
||||
const onChangeDisplayTag = useCallback((tagID = '') => {
|
||||
if (displayTag === tagID) return;
|
||||
|
||||
@@ -58,9 +68,9 @@ const AllTags = ({ updateCurrentPath, ...params }) => {
|
||||
|
||||
useEffect(() => {
|
||||
if (isLoading || isReloading) {
|
||||
onChangeDisplayTag();
|
||||
setDisplayTag('');
|
||||
}
|
||||
}, [isLoading, isReloading, onChangeDisplayTag]);
|
||||
}, [isLoading, isReloading]);
|
||||
|
||||
if (isReloading) return (<CenteredLoading />);
|
||||
|
||||
|
@@ -1,23 +0,0 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import TagNameOperationBtn from './tag-name-operation-btn';
|
||||
import { PRIVATE_COLUMN_KEY } from '../../../../constants/column/private';
|
||||
|
||||
const CellOperationBtn = ({ column, record, ...customProps }) => {
|
||||
|
||||
switch (column.key) {
|
||||
case PRIVATE_COLUMN_KEY.TAG_NAME: {
|
||||
return (<TagNameOperationBtn {...customProps} column={column} record={record} />);
|
||||
}
|
||||
default: {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
CellOperationBtn.propTypes = {
|
||||
column: PropTypes.object,
|
||||
record: PropTypes.object,
|
||||
};
|
||||
|
||||
export default CellOperationBtn;
|
@@ -1,18 +0,0 @@
|
||||
.sf-tag-cell-operation-btn {
|
||||
background: #fff;
|
||||
border-radius: 3px;
|
||||
box-shadow: rgba(15, 15, 15, 0.1) 0px 0px 0px 1px, rgba(15, 15, 15, 0.1) 0px 2px 4px;
|
||||
position: absolute;
|
||||
right: 8px;
|
||||
top: 6px;
|
||||
transition: background 0.020s ease-in;
|
||||
}
|
||||
|
||||
.sf-tag-cell-operation-btn:hover {
|
||||
background: #efefef;
|
||||
}
|
||||
|
||||
.sf-tag-cell-operation-btn .sf-metadata-icon {
|
||||
fill: #666;
|
||||
font-size: 14px;
|
||||
}
|
@@ -1,39 +0,0 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { UncontrolledTooltip } from 'reactstrap';
|
||||
import { IconBtn } from '@seafile/sf-metadata-ui-component';
|
||||
import { PRIVATE_COLUMN_KEY } from '../../../../../constants';
|
||||
import { gettext } from '../../../../../../utils/constants';
|
||||
|
||||
import './index.css';
|
||||
|
||||
const TagNameOperationBtn = ({ record, setDisplayTag }) => {
|
||||
|
||||
const handelClick = () => {
|
||||
setDisplayTag(record[PRIVATE_COLUMN_KEY.ID]);
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<IconBtn id="sf-tag-open-tag-files" className="sf-tag-cell-operation-btn" size={20} iconName="open-file" onClick={handelClick} />
|
||||
<UncontrolledTooltip
|
||||
hideArrow
|
||||
target="sf-tag-open-tag-files"
|
||||
placement="bottom"
|
||||
fade={false}
|
||||
delay={{ show: 0, hide: 0 }}
|
||||
modifiers={{ preventOverflow: { boundariesElement: document.body } }}
|
||||
>
|
||||
{gettext('Tag related files')}
|
||||
</UncontrolledTooltip>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
TagNameOperationBtn.propTypes = {
|
||||
column: PropTypes.object,
|
||||
record: PropTypes.object,
|
||||
setDisplayTag: PropTypes.func,
|
||||
};
|
||||
|
||||
export default TagNameOperationBtn;
|
@@ -1,3 +1,4 @@
|
||||
import React from 'react';
|
||||
import ParentTagsEditor from './parent-tags';
|
||||
import ChildTagsEditor from './child-tags';
|
||||
import TagNameEditor from './tag-name';
|
||||
|
@@ -1,13 +1,15 @@
|
||||
import React from 'react';
|
||||
import ParentTagsFormatter from './parent-tags';
|
||||
import TagNameFormatter from './tag-name';
|
||||
import ChildTagsFormatter from './child-tags';
|
||||
import TagFilesFormatter from './tag-files';
|
||||
import { PRIVATE_COLUMN_KEY } from '../../../../constants';
|
||||
|
||||
export const createColumnFormatter = ({ column }) => {
|
||||
export const createColumnFormatter = ({ column, otherProps }) => {
|
||||
switch (column.key) {
|
||||
case PRIVATE_COLUMN_KEY.TAG_NAME: {
|
||||
return <TagNameFormatter />;
|
||||
const { setDisplayTag } = otherProps;
|
||||
return <TagNameFormatter setDisplayTag={setDisplayTag} />;
|
||||
}
|
||||
case PRIVATE_COLUMN_KEY.PARENT_LINKS: {
|
||||
return <ParentTagsFormatter />;
|
||||
|
@@ -1,8 +1,9 @@
|
||||
import React, { useMemo } from 'react';
|
||||
import React, { useCallback, useMemo } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { PRIVATE_COLUMN_KEY } from '../../../../constants';
|
||||
import { getRecordIdFromRecord } from '../../../../../metadata/utils/cell';
|
||||
|
||||
const TagNameFormatter = ({ record }) => {
|
||||
|
||||
const TagNameFormatter = ({ record, isCellSelected, setDisplayTag }) => {
|
||||
const tagColor = useMemo(() => {
|
||||
return record[PRIVATE_COLUMN_KEY.TAG_COLOR];
|
||||
}, [record]);
|
||||
@@ -11,12 +12,24 @@ const TagNameFormatter = ({ record }) => {
|
||||
return record[PRIVATE_COLUMN_KEY.TAG_NAME];
|
||||
}, [record]);
|
||||
|
||||
const onClickName = useCallback(() => {
|
||||
if (!isCellSelected) return;
|
||||
const tagId = getRecordIdFromRecord(record);
|
||||
setDisplayTag(tagId);
|
||||
}, [isCellSelected, record, setDisplayTag]);
|
||||
|
||||
return (
|
||||
<div className="sf-table-tag-name-formatter sf-table-cell-formatter sf-metadata-ui cell-formatter-container">
|
||||
<span className="sf-table-tag-color" style={{ backgroundColor: tagColor }}></span>
|
||||
<span className="sf-table-tag-name" title={tagName}>{tagName}</span>
|
||||
<span className="sf-table-tag-name-wrapper"><span className="sf-table-tag-name" title={tagName} onClick={onClickName}>{tagName}</span></span>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
TagNameFormatter.propTypes = {
|
||||
record: PropTypes.object,
|
||||
isCellSelected: PropTypes.bool,
|
||||
setDisplayTag: PropTypes.func,
|
||||
};
|
||||
|
||||
export default TagNameFormatter;
|
||||
|
@@ -24,7 +24,12 @@
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
|
||||
.sf-table-tag-name-formatter .sf-table-tag-name {
|
||||
.sf-table-tag-name-formatter .sf-table-tag-name-wrapper {
|
||||
flex: 1;
|
||||
padding-left: 20px;
|
||||
|
||||
}
|
||||
|
||||
.sf-table-cell.cell-selected .sf-table-tag-name-formatter .sf-table-tag-name:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
@@ -2,7 +2,6 @@ import React, { useCallback, useMemo, useRef, useState } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import SFTable from '../../../../components/sf-table';
|
||||
import EditTagDialog from '../../../components/dialog/edit-tag-dialog';
|
||||
import CellOperationBtn from './cell-operation';
|
||||
import { createTableColumns } from './columns-factory';
|
||||
import { createContextMenuOptions } from './context-menu-options';
|
||||
import { gettext } from '../../../../utils/constants';
|
||||
@@ -73,12 +72,13 @@ const TagsTable = ({
|
||||
_id: TABLE_ID,
|
||||
...tagsData,
|
||||
columns: createTableColumns(tagsData.columns, {
|
||||
setDisplayTag,
|
||||
updateTag,
|
||||
addTagLinks,
|
||||
deleteTagLinks,
|
||||
}),
|
||||
};
|
||||
}, [tagsData, updateTag, addTagLinks, deleteTagLinks]);
|
||||
}, [tagsData, setDisplayTag, updateTag, addTagLinks, deleteTagLinks]);
|
||||
|
||||
const visibleColumns = useMemo(() => {
|
||||
const keyColumnMap = table.columns.reduce((currKeyColumnMap, column) => ({ ...currKeyColumnMap, [column.key]: column }), {});
|
||||
@@ -139,10 +139,6 @@ const TagsTable = ({
|
||||
modifyColumnWidthAPI(column.key, newWidth);
|
||||
}, [modifyColumnWidthAPI]);
|
||||
|
||||
const TagTableCellOperationBtn = useMemo(() => {
|
||||
return (<CellOperationBtn setDisplayTag={setDisplayTag} />);
|
||||
}, [setDisplayTag]);
|
||||
|
||||
const createTagContextMenuOptions = useCallback((tableProps) => {
|
||||
return createContextMenuOptions({
|
||||
...tableProps,
|
||||
@@ -185,7 +181,6 @@ const TagsTable = ({
|
||||
isLoadingMoreRecords={isLoadingMoreRecords}
|
||||
hasMoreRecords={table.hasMore}
|
||||
showGridFooter={false}
|
||||
CellOperationBtn={TagTableCellOperationBtn}
|
||||
createContextMenuOptions={createTagContextMenuOptions}
|
||||
storeGridScroll={storeGridScroll}
|
||||
storeFoldedGroups={storeFoldedGroups}
|
||||
|
Reference in New Issue
Block a user