mirror of
https://github.com/haiwen/seahub.git
synced 2025-09-07 01:41:39 +00:00
fix: metadata load tip (#7103)
Co-authored-by: 杨国璇 <ygx@Hello-word.local>
This commit is contained in:
@@ -16,6 +16,7 @@ export const MetadataStatusProvider = ({ repoID, currentRepoInfo, hideMetadataVi
|
|||||||
const [isLoading, setLoading] = useState(true);
|
const [isLoading, setLoading] = useState(true);
|
||||||
const [enableMetadata, setEnableMetadata] = useState(false);
|
const [enableMetadata, setEnableMetadata] = useState(false);
|
||||||
const [enableTags, setEnableTags] = useState(false);
|
const [enableTags, setEnableTags] = useState(false);
|
||||||
|
const [isBeingBuilt, setIsBeingBuilt] = useState(false);
|
||||||
|
|
||||||
const cancelMetadataURL = useCallback(() => {
|
const cancelMetadataURL = useCallback(() => {
|
||||||
// If attribute extension is turned off, unmark the URL
|
// If attribute extension is turned off, unmark the URL
|
||||||
@@ -57,6 +58,7 @@ export const MetadataStatusProvider = ({ repoID, currentRepoInfo, hideMetadataVi
|
|||||||
cancelMetadataURL();
|
cancelMetadataURL();
|
||||||
setEnableTags(false);
|
setEnableTags(false);
|
||||||
}
|
}
|
||||||
|
setIsBeingBuilt(newValue);
|
||||||
setEnableMetadata(newValue);
|
setEnableMetadata(newValue);
|
||||||
}, [enableMetadata, cancelMetadataURL]);
|
}, [enableMetadata, cancelMetadataURL]);
|
||||||
|
|
||||||
@@ -74,7 +76,9 @@ export const MetadataStatusProvider = ({ repoID, currentRepoInfo, hideMetadataVi
|
|||||||
value={{
|
value={{
|
||||||
enableMetadataManagement,
|
enableMetadataManagement,
|
||||||
enableMetadata,
|
enableMetadata,
|
||||||
|
isBeingBuilt,
|
||||||
updateEnableMetadata,
|
updateEnableMetadata,
|
||||||
|
setIsBeingBuilt,
|
||||||
enableTags,
|
enableTags,
|
||||||
updateEnableTags,
|
updateEnableTags,
|
||||||
}}
|
}}
|
||||||
|
@@ -21,7 +21,7 @@ export const MetadataViewProvider = ({
|
|||||||
const [errorMessage, setErrorMessage] = useState(null);
|
const [errorMessage, setErrorMessage] = useState(null);
|
||||||
const storeRef = useRef(null);
|
const storeRef = useRef(null);
|
||||||
const { collaborators } = useCollaborators();
|
const { collaborators } = useCollaborators();
|
||||||
const { isEmptyRepo, showFirstView, setShowFirstView } = useMetadata();
|
const { isBeingBuilt, setIsBeingBuilt } = useMetadata();
|
||||||
|
|
||||||
const tableChanged = useCallback(() => {
|
const tableChanged = useCallback(() => {
|
||||||
setMetadata(storeRef.current.data);
|
setMetadata(storeRef.current.data);
|
||||||
@@ -85,9 +85,9 @@ export const MetadataViewProvider = ({
|
|||||||
storeRef.current = new Store({ context: window.sfMetadataContext, repoId: repoID, viewId: viewID, collaborators });
|
storeRef.current = new Store({ context: window.sfMetadataContext, repoId: repoID, viewId: viewID, collaborators });
|
||||||
window.sfMetadataStore = storeRef.current;
|
window.sfMetadataStore = storeRef.current;
|
||||||
storeRef.current.initStartIndex();
|
storeRef.current.initStartIndex();
|
||||||
storeRef.current.load(PER_LOAD_NUMBER, isEmptyRepo).then(() => {
|
storeRef.current.load(PER_LOAD_NUMBER, isBeingBuilt).then(() => {
|
||||||
setMetadata(storeRef.current.data);
|
setMetadata(storeRef.current.data);
|
||||||
setShowFirstView(false);
|
setIsBeingBuilt(false);
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
const errorMsg = Utils.getErrorMsg(error);
|
const errorMsg = Utils.getErrorMsg(error);
|
||||||
@@ -132,7 +132,7 @@ export const MetadataViewProvider = ({
|
|||||||
<MetadataViewContext.Provider
|
<MetadataViewContext.Provider
|
||||||
value={{
|
value={{
|
||||||
isLoading,
|
isLoading,
|
||||||
showFirstView,
|
isBeingBuilt,
|
||||||
errorMessage,
|
errorMessage,
|
||||||
metadata,
|
metadata,
|
||||||
store: storeRef.current,
|
store: storeRef.current,
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
import React, { useCallback, useContext, useEffect, useRef, useState, useMemo } from 'react';
|
import React, { useCallback, useContext, useEffect, useRef, useState } from 'react';
|
||||||
import metadataAPI from '../api';
|
import metadataAPI from '../api';
|
||||||
import { Utils } from '../../utils/utils';
|
import { Utils } from '../../utils/utils';
|
||||||
import toaster from '../../components/toast';
|
import toaster from '../../components/toast';
|
||||||
@@ -14,7 +14,6 @@ const MetadataContext = React.createContext(null);
|
|||||||
export const MetadataProvider = ({ repoID, currentPath, repoInfo, hideMetadataView, selectMetadataView, children }) => {
|
export const MetadataProvider = ({ repoID, currentPath, repoInfo, hideMetadataView, selectMetadataView, children }) => {
|
||||||
const [isLoading, setLoading] = useState(true);
|
const [isLoading, setLoading] = useState(true);
|
||||||
const [enableFaceRecognition, setEnableFaceRecognition] = useState(false);
|
const [enableFaceRecognition, setEnableFaceRecognition] = useState(false);
|
||||||
const [showFirstView, setShowFirstView] = useState(false);
|
|
||||||
const [navigation, setNavigation] = useState([]);
|
const [navigation, setNavigation] = useState([]);
|
||||||
const [staticView, setStaticView] = useState([]);
|
const [staticView, setStaticView] = useState([]);
|
||||||
const [, setCount] = useState(0);
|
const [, setCount] = useState(0);
|
||||||
@@ -22,9 +21,7 @@ export const MetadataProvider = ({ repoID, currentPath, repoInfo, hideMetadataVi
|
|||||||
const viewsMap = useRef({});
|
const viewsMap = useRef({});
|
||||||
const originalTitleRef = useRef(document.title);
|
const originalTitleRef = useRef(document.title);
|
||||||
|
|
||||||
const isEmptyRepo = useMemo(() => repoInfo.file_count === 0, [repoInfo]);
|
const { enableMetadata, isBeingBuilt, setIsBeingBuilt } = useMetadataStatus();
|
||||||
|
|
||||||
const { enableMetadata } = useMetadataStatus();
|
|
||||||
|
|
||||||
const updateEnableFaceRecognition = useCallback((newValue) => {
|
const updateEnableFaceRecognition = useCallback((newValue) => {
|
||||||
if (newValue === enableFaceRecognition) return;
|
if (newValue === enableFaceRecognition) return;
|
||||||
@@ -181,6 +178,14 @@ export const MetadataProvider = ({ repoID, currentPath, repoInfo, hideMetadataVi
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (isLoading) return;
|
if (isLoading) return;
|
||||||
|
if (isBeingBuilt) {
|
||||||
|
const firstViewObject = navigation.find(item => item.type === 'view');
|
||||||
|
const firstView = firstViewObject ? viewsMap.current[firstViewObject._id] : '';
|
||||||
|
if (firstView) {
|
||||||
|
selectView(firstView);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
const { origin, pathname, search } = window.location;
|
const { origin, pathname, search } = window.location;
|
||||||
const urlParams = new URLSearchParams(search);
|
const urlParams = new URLSearchParams(search);
|
||||||
if (!urlParams.has('view')) return;
|
if (!urlParams.has('view')) return;
|
||||||
@@ -201,7 +206,7 @@ export const MetadataProvider = ({ repoID, currentPath, repoInfo, hideMetadataVi
|
|||||||
selectView(firstView);
|
selectView(firstView);
|
||||||
}
|
}
|
||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
}, [isLoading]);
|
}, [isLoading, isBeingBuilt]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!currentPath.includes('/' + PRIVATE_FILE_TYPE.FILE_EXTENDED_PROPERTIES + '/')) return;
|
if (!currentPath.includes('/' + PRIVATE_FILE_TYPE.FILE_EXTENDED_PROPERTIES + '/')) return;
|
||||||
@@ -218,11 +223,10 @@ export const MetadataProvider = ({ repoID, currentPath, repoInfo, hideMetadataVi
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<MetadataContext.Provider value={{
|
<MetadataContext.Provider value={{
|
||||||
isEmptyRepo,
|
|
||||||
enableFaceRecognition,
|
enableFaceRecognition,
|
||||||
updateEnableFaceRecognition,
|
updateEnableFaceRecognition,
|
||||||
showFirstView,
|
isBeingBuilt,
|
||||||
setShowFirstView,
|
setIsBeingBuilt,
|
||||||
navigation,
|
navigation,
|
||||||
staticView,
|
staticView,
|
||||||
viewsMap: viewsMap.current,
|
viewsMap: viewsMap.current,
|
||||||
|
@@ -63,16 +63,16 @@ class Store {
|
|||||||
DataProcessor.run(this.data, { collaborators: this.collaborators });
|
DataProcessor.run(this.data, { collaborators: this.collaborators });
|
||||||
}
|
}
|
||||||
|
|
||||||
async load(limit = PER_LOAD_NUMBER, isEmptyRepo = false) {
|
async load(limit = PER_LOAD_NUMBER, isBeingBuilt = false) {
|
||||||
const viewRes = await this.context.getView(this.viewId);
|
const viewRes = await this.context.getView(this.viewId);
|
||||||
const view = viewRes?.data?.view || {};
|
const view = viewRes?.data?.view || {};
|
||||||
const retries = isEmptyRepo ? 0 : DEFAULT_RETRY_TIMES;
|
const retries = isBeingBuilt ? DEFAULT_RETRY_TIMES : 0;
|
||||||
await this.loadMetadata(view, limit, retries);
|
await this.loadMetadata(view, limit, retries);
|
||||||
}
|
}
|
||||||
|
|
||||||
async reload(limit = PER_LOAD_NUMBER) {
|
async reload(limit = PER_LOAD_NUMBER) {
|
||||||
this.startIndex = 0;
|
this.startIndex = 0;
|
||||||
await this.loadMetadata(this.data.view, limit);
|
await this.loadMetadata(this.data.view, limit, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
async loadMore(limit) {
|
async loadMore(limit) {
|
||||||
|
@@ -10,7 +10,7 @@ import { VIEW_TYPE } from '../constants';
|
|||||||
import { gettext } from '../../utils/constants';
|
import { gettext } from '../../utils/constants';
|
||||||
|
|
||||||
const View = () => {
|
const View = () => {
|
||||||
const { isLoading, showFirstView, metadata, errorMessage } = useMetadataView();
|
const { isLoading, isBeingBuilt, metadata, errorMessage } = useMetadataView();
|
||||||
|
|
||||||
const renderView = useCallback((metadata) => {
|
const renderView = useCallback((metadata) => {
|
||||||
if (!metadata) return null;
|
if (!metadata) return null;
|
||||||
@@ -37,12 +37,15 @@ const View = () => {
|
|||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
if (isLoading) {
|
if (isLoading) {
|
||||||
return showFirstView ? (
|
if (isBeingBuilt) {
|
||||||
<div className="sf-metadata-loading-wrapper">
|
return (
|
||||||
<Loading />
|
<div className="sf-metadata-loading-wrapper">
|
||||||
<span className="sf-metadata-loading-tip">{gettext('Extended properties are being built.')}</span>
|
<Loading />
|
||||||
</div>
|
<span className="sf-metadata-loading-tip">{gettext('Extended properties are being built.')}</span>
|
||||||
) : <CenteredLoading />;
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return (<CenteredLoading />);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@@ -51,6 +51,10 @@ const TagFiles = () => {
|
|||||||
}
|
}
|
||||||
}, [selectedFiles]);
|
}, [selectedFiles]);
|
||||||
|
|
||||||
|
const reSelectFiles = useCallback((fileId) => {
|
||||||
|
setSelectedFiles([fileId]);
|
||||||
|
}, []);
|
||||||
|
|
||||||
const openImagePreview = useCallback((record) => {
|
const openImagePreview = useCallback((record) => {
|
||||||
currentImageRef.current = record;
|
currentImageRef.current = record;
|
||||||
setImagePreviewerVisible(true);
|
setImagePreviewerVisible(true);
|
||||||
@@ -116,6 +120,7 @@ const TagFiles = () => {
|
|||||||
isSelected={selectedFiles && selectedFiles.includes(fileId)}
|
isSelected={selectedFiles && selectedFiles.includes(fileId)}
|
||||||
file={file}
|
file={file}
|
||||||
onSelectFile={onSelectFile}
|
onSelectFile={onSelectFile}
|
||||||
|
reSelectFiles={reSelectFiles}
|
||||||
openImagePreview={openImagePreview}
|
openImagePreview={openImagePreview}
|
||||||
/>);
|
/>);
|
||||||
})}
|
})}
|
||||||
|
@@ -15,7 +15,7 @@ import './index.css';
|
|||||||
|
|
||||||
dayjs.extend(relativeTime);
|
dayjs.extend(relativeTime);
|
||||||
|
|
||||||
const TagFile = ({ isSelected, repoID, file, onSelectFile, openImagePreview }) => {
|
const TagFile = ({ isSelected, repoID, file, onSelectFile, reSelectFiles, openImagePreview }) => {
|
||||||
const [highlight, setHighlight] = useState(false);
|
const [highlight, setHighlight] = useState(false);
|
||||||
const [isIconLoadError, setIconLoadError] = useState(false);
|
const [isIconLoadError, setIconLoadError] = useState(false);
|
||||||
|
|
||||||
@@ -76,12 +76,19 @@ const TagFile = ({ isSelected, repoID, file, onSelectFile, openImagePreview }) =
|
|||||||
});
|
});
|
||||||
}, [repoID, file, openImagePreview]);
|
}, [repoID, file, openImagePreview]);
|
||||||
|
|
||||||
|
const handelClick = useCallback((event) => {
|
||||||
|
if (event.target.tagName == 'TD') {
|
||||||
|
reSelectFiles(fileId);
|
||||||
|
}
|
||||||
|
}, [fileId, reSelectFiles]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<tr
|
<tr
|
||||||
className={classnames({
|
className={classnames({
|
||||||
'tr-highlight': highlight,
|
'tr-highlight': highlight,
|
||||||
'tr-active': isSelected
|
'tr-active': isSelected
|
||||||
})}
|
})}
|
||||||
|
onClick={handelClick}
|
||||||
onMouseEnter={onMouseEnter}
|
onMouseEnter={onMouseEnter}
|
||||||
onMouseLeave={onMouseLeave}
|
onMouseLeave={onMouseLeave}
|
||||||
>
|
>
|
||||||
@@ -101,8 +108,8 @@ const TagFile = ({ isSelected, repoID, file, onSelectFile, openImagePreview }) =
|
|||||||
<img src={displayIcon} onError={onIconLoadError} className="thumbnail cursor-pointer" alt="" />
|
<img src={displayIcon} onError={onIconLoadError} className="thumbnail cursor-pointer" alt="" />
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td className="name" onClick={handelClickFileName}>
|
<td className="name">
|
||||||
<a href={path}>{name}</a>
|
<a href={path} onClick={handelClickFileName}>{name}</a>
|
||||||
</td>
|
</td>
|
||||||
<td className="tag-list-title">
|
<td className="tag-list-title">
|
||||||
<FileTagsFormatter value={tags} />
|
<FileTagsFormatter value={tags} />
|
||||||
@@ -121,6 +128,7 @@ TagFile.propTypes = {
|
|||||||
file: PropTypes.object,
|
file: PropTypes.object,
|
||||||
onSelectFile: PropTypes.func,
|
onSelectFile: PropTypes.func,
|
||||||
openImagePreview: PropTypes.func,
|
openImagePreview: PropTypes.func,
|
||||||
|
reSelectFiles: PropTypes.func,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default TagFile;
|
export default TagFile;
|
||||||
|
Reference in New Issue
Block a user