diff --git a/frontend/src/components/dirent-detail/dirent-details/dir-details.js b/frontend/src/components/dirent-detail/dirent-details/dir-details.js index 5afe937d3f1..a749ef303f2 100644 --- a/frontend/src/components/dirent-detail/dirent-details/dir-details.js +++ b/frontend/src/components/dirent-detail/dirent-details/dir-details.js @@ -6,7 +6,7 @@ import { CellType } from '../../../metadata/metadata-view/_basic'; import { gettext } from '../../../utils/constants'; import { MetadataDetails } from '../../../metadata'; -const DirDetails = ({ repoID, repoInfo, dirent, direntType, path, direntDetail }) => { +const DirDetails = ({ repoID, repoInfo, dirent, path, direntDetail }) => { const parent = useMemo(() => getFileParent(repoInfo, dirent, path), [repoInfo, dirent, path]); const direntPath = useMemo(() => getDirentPath(dirent, path), [dirent, path]); @@ -22,7 +22,7 @@ const DirDetails = ({ repoID, repoInfo, dirent, direntType, path, direntDetail } }]} /> {window.app.pageOptions.enableMetadataManagement && ( - + )} ); @@ -32,7 +32,6 @@ DirDetails.propTypes = { repoID: PropTypes.string, repoInfo: PropTypes.object, dirent: PropTypes.object, - direntType: PropTypes.string, path: PropTypes.string, direntDetail: PropTypes.object, }; diff --git a/frontend/src/components/dirent-detail/dirent-details/file-details.js b/frontend/src/components/dirent-detail/dirent-details/file-details.js index 24a83c1cdf6..645bd9422a4 100644 --- a/frontend/src/components/dirent-detail/dirent-details/file-details.js +++ b/frontend/src/components/dirent-detail/dirent-details/file-details.js @@ -9,8 +9,9 @@ import EditFileTagPopover from '../../popover/edit-filetag-popover'; import FileTagList from '../../file-tag-list'; import { Utils } from '../../../utils/utils'; import { MetadataDetails } from '../../../metadata'; +import ObjectUtils from '../../../metadata/metadata-view/utils/object-utils'; -const FileDetails = ({ repoID, repoInfo, dirent, path, direntDetail, direntType, onFileTagChanged, repoTags, fileTagList }) => { +const FileDetails = React.memo(({ repoID, repoInfo, dirent, path, direntDetail, onFileTagChanged, repoTags, fileTagList }) => { const [isEditFileTagShow, setEditFileTagShow] = useState(false); const parent = useMemo(() => getFileParent(repoInfo, dirent, path), [repoInfo, dirent, path]); @@ -46,7 +47,7 @@ const FileDetails = ({ repoID, repoInfo, dirent, path, direntDetail, direntType, )} {window.app.pageOptions.enableMetadataManagement && ( - + )} {isEditFileTagShow && ); -}; +}, (props, nextProps) => { + const { repoID, repoInfo, dirent, path, direntDetail } = props; + const isChanged = ( + repoID !== nextProps.repoID || + path !== nextProps.path || + !ObjectUtils.isSameObject(repoInfo, nextProps.repoInfo) || + !ObjectUtils.isSameObject(dirent, nextProps.dirent) || + !ObjectUtils.isSameObject(direntDetail, nextProps.direntDetail) + ); + return !isChanged; +}); FileDetails.propTypes = { repoID: PropTypes.string, repoInfo: PropTypes.object, dirent: PropTypes.object, - direntType: PropTypes.string, path: PropTypes.string, direntDetail: PropTypes.object, onFileTagChanged: PropTypes.func, diff --git a/frontend/src/components/dirent-detail/dirent-details/index.js b/frontend/src/components/dirent-detail/dirent-details/index.js index be12c07061e..588eb8afec7 100644 --- a/frontend/src/components/dirent-detail/dirent-details/index.js +++ b/frontend/src/components/dirent-detail/dirent-details/index.js @@ -8,18 +8,17 @@ import Dirent from '../../../models/dirent'; import Header from '../header'; import DirDetails from './dir-details'; import FileDetails from './file-details'; +import ObjectUtils from '../../../metadata/metadata-view/utils/object-utils'; import './index.css'; -const DirentDetails = React.memo(({ dirent: propsDirent, path, repoID, currentRepoInfo, repoTags, fileTags, onItemDetailsClose, onFileTagChanged }) => { - const [direntType, setDirentType] = useState(''); +const DirentDetails = React.memo(({ dirent: propsDirent, path, repoID, currentRepoInfo, repoTags, fileTags, onClose, onFileTagChanged }) => { const [direntDetail, setDirentDetail] = useState(''); const [dirent, setDirent] = useState(null); const updateDetailView = useCallback((repoID, dirent, direntPath) => { const apiName = dirent.type === 'file' ? 'getFileInfo' : 'getDirInfo'; seafileAPI[apiName](repoID, direntPath).then(res => { - setDirentType(dirent.type === 'file' ? 'file' : 'dir'); setDirentDetail(res.data); setDirent(dirent); }).catch(error => { @@ -29,7 +28,6 @@ const DirentDetails = React.memo(({ dirent: propsDirent, path, repoID, currentRe }, []); useEffect(() => { - console.log('index 组件更新'); setDirent(null); if (propsDirent) { const direntPath = Utils.joinPath(path, propsDirent.name); @@ -39,13 +37,9 @@ const DirentDetails = React.memo(({ dirent: propsDirent, path, repoID, currentRe const dirPath = Utils.getDirName(path); seafileAPI.listDir(repoID, dirPath).then(res => { const direntList = res.data.dirent_list; - let folderDirent = null; - for (let i = 0; i < direntList.length; i++) { - let dirent = direntList[i]; - if (dirent.parent_dir + dirent.name === path) { - folderDirent = new Dirent(dirent); - break; - } + let folderDirent = direntList.find(item => item.parent_dir + item.name === path) || null; + if (folderDirent) { + folderDirent = new Dirent(folderDirent); } updateDetailView(repoID, folderDirent, path); }).catch(error => { @@ -53,22 +47,22 @@ const DirentDetails = React.memo(({ dirent: propsDirent, path, repoID, currentRe toaster.danger(errMessage); }); // eslint-disable-next-line react-hooks/exhaustive-deps - }, [propsDirent, path]); + }, [propsDirent, path, repoID]); if (!dirent) return null; const direntName = dirent.name; const smallIconUrl = Utils.getDirentIcon(dirent); - // let bigIconUrl = dirent ? Utils.getDirentIcon(dirent, true) : Utils.getDirentIcon(folderDirent, true); + // let bigIconUrl = Utils.getDirentIcon(dirent, true); let bigIconUrl = ''; const isImg = Utils.imageCheck(dirent.name); - // const isVideo = dirent ? Utils.videoCheck(dirent.name) : Utils.videoCheck(folderDirent.name); + // const isVideo = Utils.videoCheck(dirent.name); if (isImg) { bigIconUrl = `${siteRoot}thumbnail/${repoID}/1024` + Utils.encodePath(`${path === '/' ? '' : path}/${dirent.name}`); } return (
-
+
{isImg && (
@@ -77,12 +71,11 @@ const DirentDetails = React.memo(({ dirent: propsDirent, path, repoID, currentRe )} {direntDetail && (
- {direntType === 'dir' ? ( + {dirent.type !== 'file' ? ( @@ -91,7 +84,6 @@ const DirentDetails = React.memo(({ dirent: propsDirent, path, repoID, currentRe repoID={repoID} repoInfo={currentRepoInfo} dirent={dirent} - direntType={direntType} path={path} direntDetail={direntDetail} repoTags={repoTags} @@ -104,6 +96,17 @@ const DirentDetails = React.memo(({ dirent: propsDirent, path, repoID, currentRe
); +}, (props, nextProps) => { + const { dirent, path, repoID, currentRepoInfo, repoTags, fileTags } = props; + const isChanged = ( + !ObjectUtils.isSameObject(currentRepoInfo, nextProps.currentRepoInfo) || + !ObjectUtils.isSameObject(dirent, nextProps.dirent) || + JSON.stringify(repoTags || []) !== JSON.stringify(nextProps.repoTags || []) || + JSON.stringify(fileTags || []) !== JSON.stringify(nextProps.fileTags || []) || + path !== nextProps.path || + repoID !== nextProps.repoID + ); + return !isChanged; }); DirentDetails.propTypes = { @@ -111,9 +114,8 @@ DirentDetails.propTypes = { dirent: PropTypes.object, path: PropTypes.string.isRequired, currentRepoInfo: PropTypes.object.isRequired, - onItemDetailsClose: PropTypes.func.isRequired, + onClose: PropTypes.func.isRequired, onFileTagChanged: PropTypes.func.isRequired, - direntDetailPanelTab: PropTypes.string, repoTags: PropTypes.array, fileTags: PropTypes.array, }; diff --git a/frontend/src/components/dirent-detail/index.js b/frontend/src/components/dirent-detail/index.js index 63dd0640264..896394456b5 100644 --- a/frontend/src/components/dirent-detail/index.js +++ b/frontend/src/components/dirent-detail/index.js @@ -1,9 +1,49 @@ +import React from 'react'; +import PropTypes from 'prop-types'; import LibDetail from './lib-details'; import DirentDetail from './dirent-details'; import './index.css'; +import ObjectUtils from '../../metadata/metadata-view/utils/object-utils'; -export { - LibDetail, - DirentDetail, +const Index = React.memo(({ repoID, path, dirent, currentRepoInfo, repoTags, fileTags, onClose, onFileTagChanged }) => { + + if (path === '/' && !dirent) { + return ( + + ); + } + return ( + + ); +}, (props, nextProps) => { + const isChanged = props.repoID !== nextProps.repoID || + props.path !== nextProps.path || + !ObjectUtils.isSameObject(props.dirent, nextProps.dirent) || + !ObjectUtils.isSameObject(props.currentRepoInfo, nextProps.currentRepoInfo) || + JSON.stringify(props.repoTags || []) !== JSON.stringify(nextProps.repoTags || []) || + JSON.stringify(props.fileTags || []) !== JSON.stringify(nextProps.fileTags || []); + return !isChanged; +}); + +Index.propTypes = { + repoID: PropTypes.string, + path: PropTypes.string, + dirent: PropTypes.object, + currentRepoInfo: PropTypes.object, + repoTags: PropTypes.array, + fileTags: PropTypes.array, + onClose: PropTypes.func, + onFileTagChanged: PropTypes.func, }; + +export default Index; diff --git a/frontend/src/components/dirent-detail/lib-details/index.js b/frontend/src/components/dirent-detail/lib-details/index.js index 5236507c24e..47c09d92a98 100644 --- a/frontend/src/components/dirent-detail/lib-details/index.js +++ b/frontend/src/components/dirent-detail/lib-details/index.js @@ -10,14 +10,14 @@ import Loading from '../../loading'; import DetailItem from '../detail-item'; import { CellType } from '../../../metadata/metadata-view/_basic'; -const LibDetail = React.memo(({ currentRepo, closeDetails }) => { +const LibDetail = React.memo(({ currentRepoInfo, onClose }) => { const [isLoading, setLoading] = useState(true); const [repo, setRepo] = useState({}); - const smallIconUrl = useMemo(() => Utils.getLibIconUrl(currentRepo), [currentRepo]); + const smallIconUrl = useMemo(() => Utils.getLibIconUrl(currentRepoInfo), [currentRepoInfo]); useEffect(() => { setLoading(true); - seafileAPI.getRepoInfo(currentRepo.repo_id).then(res => { + seafileAPI.getRepoInfo(currentRepoInfo.repo_id).then(res => { const repo = new Repo(res.data); setRepo(repo); setLoading(false); @@ -25,11 +25,11 @@ const LibDetail = React.memo(({ currentRepo, closeDetails }) => { let errMessage = Utils.getErrorMsg(error); toaster.danger(errMessage); }); - }, [currentRepo.repo_id]); + }, [currentRepoInfo.repo_id]); return (
-
+
{isLoading ? (
@@ -55,8 +55,8 @@ const LibDetail = React.memo(({ currentRepo, closeDetails }) => { }); LibDetail.propTypes = { - currentRepo: PropTypes.object.isRequired, - closeDetails: PropTypes.func.isRequired, + currentRepoInfo: PropTypes.object.isRequired, + onClose: PropTypes.func.isRequired, }; export default LibDetail; diff --git a/frontend/src/metadata/metadata-details/index.js b/frontend/src/metadata/metadata-details/index.js index 881cfa8369a..2edceefd81b 100644 --- a/frontend/src/metadata/metadata-details/index.js +++ b/frontend/src/metadata/metadata-details/index.js @@ -4,10 +4,9 @@ import { Utils } from '../../utils/utils'; import metadataAPI from '../api'; import Column from '../metadata-view/model/metadata/column'; import { normalizeFields, getCellValueByColumn } from './utils'; -import toaster from '../../components/toast'; import DetailItem from '../../components/dirent-detail/detail-item'; -const MetadataDetails = React.memo(({ repoID, filePath, direntType, emptyTip }) => { +const MetadataDetails = ({ repoID, filePath, direntType, emptyTip }) => { const [isLoading, setLoading] = useState(true); const [metadata, setMetadata] = useState({ record: {}, fields: [] }); @@ -26,8 +25,6 @@ const MetadataDetails = React.memo(({ repoID, filePath, direntType, emptyTip }) setMetadata({ record, fields }); setLoading(false); }).catch(error => { - const errorMsg = Utils.getErrorMsg(error); - toaster.danger(errorMsg); setLoading(false); }); }, [repoID, filePath, direntType]); @@ -39,7 +36,7 @@ const MetadataDetails = React.memo(({ repoID, filePath, direntType, emptyTip }) const value = getCellValueByColumn(record, field); return (); }); -}); +}; MetadataDetails.propTypes = { repoID: PropTypes.string, diff --git a/frontend/src/metadata/metadata-view/components/table/index.css b/frontend/src/metadata/metadata-view/components/table/index.css index c4404f3049f..903d1d3b7c1 100644 --- a/frontend/src/metadata/metadata-view/components/table/index.css +++ b/frontend/src/metadata/metadata-view/components/table/index.css @@ -129,7 +129,6 @@ } .sf-metadata-result-table-content .sf-metadata-result-table-row.sf-metadata-last-table-row { - height: 32px !important; border-bottom: none; } diff --git a/frontend/src/metadata/metadata-view/components/table/table-main/records/group-body/index.js b/frontend/src/metadata/metadata-view/components/table/table-main/records/group-body/index.js index e4232c1ce3e..5448053cf18 100644 --- a/frontend/src/metadata/metadata-view/components/table/table-main/records/group-body/index.js +++ b/frontend/src/metadata/metadata-view/components/table/table-main/records/group-body/index.js @@ -15,7 +15,7 @@ import { getColumnScrollPosition, getColVisibleEndIdx, getColVisibleStartIdx } f import { GROUP_HEADER_HEIGHT, GROUP_ROW_TYPE, GROUP_VIEW_OFFSET, SEQUENCE_COLUMN_WIDTH, EVENT_BUS_TYPE } from '../../../../../constants'; import { addClassName, removeClassName } from '../../../../../utils'; -const ROW_HEIGHT = 32; +const ROW_HEIGHT = 33; const GROUP_OVER_SCAN_ROWS = 10; const MAX_ANIMATION_ROWS = 50; const LOCAL_FOLDED_GROUP_KEY = 'path_folded_group'; diff --git a/frontend/src/metadata/metadata-view/components/table/table-main/records/record/index.js b/frontend/src/metadata/metadata-view/components/table/table-main/records/record/index.js index 334e47a3023..636f0c58d73 100644 --- a/frontend/src/metadata/metadata-view/components/table/table-main/records/record/index.js +++ b/frontend/src/metadata/metadata-view/components/table/table-main/records/record/index.js @@ -175,14 +175,15 @@ class Record extends React.Component { }; getRecordStyle = () => { - const { isGroupView, height } = this.props; - let style = { - height: height + 'px', - }; + const { isGroupView, height, isLastRecord } = this.props; + let style = { height: isLastRecord ? height - 1 : height }; if (isGroupView) { const { top, left } = this.props; - style.top = top + 'px'; - style.left = left + 'px'; + style.top = top; + style.left = left; + if (isLastRecord) { + style.height = height + 1; + } } return style; }; diff --git a/frontend/src/metadata/metadata-view/utils/group-metrics.js b/frontend/src/metadata/metadata-view/utils/group-metrics.js index ad47b1cee26..e4d8e6d6cc8 100644 --- a/frontend/src/metadata/metadata-view/utils/group-metrics.js +++ b/frontend/src/metadata/metadata-view/utils/group-metrics.js @@ -81,7 +81,7 @@ export const getGroupsRows = ( const lastRowIndex = rowsLength - 1; const isRowVisible = isParentGroupVisible && isExpanded; const isBtnInsertRowVisible = isRowVisible && includeInsertRow; - const rowsHeight = isRowVisible ? rowsLength * rowHeight : 0; + const rowsHeight = isRowVisible ? rowsLength * rowHeight + 1 : 0; const btnInsertRowHeight = isBtnInsertRowVisible ? INSERT_ROW_HEIGHT : 0; let rows = row_ids.map((rowId, index) => { return { @@ -90,7 +90,7 @@ export const getGroupsRows = ( rowIdx: index, isLastRow: index === lastRowIndex, visible: isRowVisible, - height: rowHeight, + height: index === lastRowIndex ? rowHeight + 1 : rowHeight, level: currentLevel, rowsLength, left, diff --git a/frontend/src/metadata/metadata-view/utils/object-utils.js b/frontend/src/metadata/metadata-view/utils/object-utils.js index e25cd397f33..859c1a5d0f1 100644 --- a/frontend/src/metadata/metadata-view/utils/object-utils.js +++ b/frontend/src/metadata/metadata-view/utils/object-utils.js @@ -34,6 +34,7 @@ class ObjectUtils { } static isSameObject(source, comparison) { + if (!source && !comparison) return true; if (!source || !comparison) return false; return !this.isObjectChanged(source, comparison); } diff --git a/frontend/src/pages/lib-content-view/lib-content-container.js b/frontend/src/pages/lib-content-view/lib-content-container.js index 112447b782c..76b0ba03402 100644 --- a/frontend/src/pages/lib-content-view/lib-content-container.js +++ b/frontend/src/pages/lib-content-view/lib-content-container.js @@ -2,7 +2,7 @@ import React, { Fragment } from 'react'; import PropTypes from 'prop-types'; import { gettext } from '../../utils/constants'; import CurDirPath from '../../components/cur-dir-path'; -import { LibDetail, DirentDetail } from '../../components/dirent-detail'; +import Detail from '../../components/dirent-detail'; import DirColumnView from '../../components/dir-view-mode/dir-column-view'; import ToolbarForSelectedDirents from '../../components/toolbar/selected-dirents-toolbar'; @@ -319,23 +319,16 @@ class LibContentContainer extends React.Component { )} {this.props.isDirentDetailShow && (
- {(this.props.path === '/' && !this.state.currentDirent) ? - : - - } +
)}
diff --git a/frontend/src/pages/lib-content-view/lib-content-view.js b/frontend/src/pages/lib-content-view/lib-content-view.js index b4ae747f71a..fd07b79761f 100644 --- a/frontend/src/pages/lib-content-view/lib-content-view.js +++ b/frontend/src/pages/lib-content-view/lib-content-view.js @@ -416,7 +416,7 @@ class LibContentView extends React.Component { let repoID = this.props.repoID; if (!this.state.isSessionExpired) { - // update stste + // update state this.setState({ isDirentListLoading: true, isViewFile: false, @@ -494,7 +494,7 @@ class LibContentView extends React.Component { showFileMetadata = (filePath, viewId) => { const repoID = this.props.repoID; - this.setState({ path: filePath, isViewFile: true, isFileLoading: false, isFileLoadedErr: false, content: '__sf-metadata', metadataViewId: viewId }); + this.setState({ path: filePath, isViewFile: true, isFileLoading: false, isFileLoadedErr: false, content: '__sf-metadata', metadataViewId: viewId, isDirentDetailShow: false }); const repoInfo = this.state.currentRepoInfo; const url = siteRoot + 'library/' + repoID + '/' + encodeURIComponent(repoInfo.repo_name); window.history.pushState({ url: url, path: '' }, '', url);