mirror of
https://github.com/haiwen/seahub.git
synced 2025-09-08 02:10:24 +00:00
update metadata loading ui (#7080)
Co-authored-by: zhouwenxuan <aries@Mac.local>
This commit is contained in:
@@ -105,6 +105,10 @@ export const SUPPORT_BATCH_DOWNLOAD_TYPES = [];
|
|||||||
|
|
||||||
export const PER_LOAD_NUMBER = 1000;
|
export const PER_LOAD_NUMBER = 1000;
|
||||||
|
|
||||||
|
export const DEFAULT_RETRY_TIMES = 4;
|
||||||
|
|
||||||
|
export const DEFAULT_RETRY_INTERVAL = 1000;
|
||||||
|
|
||||||
// dtable-db limit loads up to 10,000 rows at a time
|
// dtable-db limit loads up to 10,000 rows at a time
|
||||||
export const MAX_LOAD_NUMBER = 10000;
|
export const MAX_LOAD_NUMBER = 10000;
|
||||||
|
|
||||||
|
@@ -7,7 +7,6 @@ import { EVENT_BUS_TYPE, PER_LOAD_NUMBER } from '../constants';
|
|||||||
import { Utils } from '../../utils/utils';
|
import { Utils } from '../../utils/utils';
|
||||||
import { useMetadata } from './metadata';
|
import { useMetadata } from './metadata';
|
||||||
import { useCollaborators } from './collaborators';
|
import { useCollaborators } from './collaborators';
|
||||||
import { gettext } from '../../utils/constants';
|
|
||||||
|
|
||||||
const MetadataViewContext = React.createContext(null);
|
const MetadataViewContext = React.createContext(null);
|
||||||
|
|
||||||
@@ -21,7 +20,7 @@ export const MetadataViewProvider = ({
|
|||||||
const [metadata, setMetadata] = useState({ rows: [], columns: [], view: {} });
|
const [metadata, setMetadata] = useState({ rows: [], columns: [], view: {} });
|
||||||
const storeRef = useRef(null);
|
const storeRef = useRef(null);
|
||||||
const { collaborators } = useCollaborators();
|
const { collaborators } = useCollaborators();
|
||||||
const { showFirstView, setShowFirstView } = useMetadata();
|
const { isEmptyRepo, showFirstView, setShowFirstView } = useMetadata();
|
||||||
|
|
||||||
const tableChanged = useCallback(() => {
|
const tableChanged = useCallback(() => {
|
||||||
setMetadata(storeRef.current.data);
|
setMetadata(storeRef.current.data);
|
||||||
@@ -84,10 +83,7 @@ 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).then(() => {
|
storeRef.current.load(PER_LOAD_NUMBER, isEmptyRepo).then(() => {
|
||||||
if (showFirstView && storeRef.current.data.rows.length === 0) {
|
|
||||||
toaster.success(gettext('The files\' metadata is being created. This may take a minute or so. Please refresh the page later.'));
|
|
||||||
}
|
|
||||||
setMetadata(storeRef.current.data);
|
setMetadata(storeRef.current.data);
|
||||||
setShowFirstView(false);
|
setShowFirstView(false);
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
@@ -134,6 +130,7 @@ export const MetadataViewProvider = ({
|
|||||||
<MetadataViewContext.Provider
|
<MetadataViewContext.Provider
|
||||||
value={{
|
value={{
|
||||||
isLoading,
|
isLoading,
|
||||||
|
showFirstView,
|
||||||
metadata,
|
metadata,
|
||||||
store: storeRef.current,
|
store: storeRef.current,
|
||||||
isDirentDetailShow: params.isDirentDetailShow,
|
isDirentDetailShow: params.isDirentDetailShow,
|
||||||
|
@@ -15,6 +15,7 @@ export const MetadataProvider = ({ repoID, currentRepoInfo, hideMetadataView, se
|
|||||||
return window.app.pageOptions.enableMetadataManagement;
|
return window.app.pageOptions.enableMetadataManagement;
|
||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
}, [window.app.pageOptions.enableMetadataManagement, currentRepoInfo]);
|
}, [window.app.pageOptions.enableMetadataManagement, currentRepoInfo]);
|
||||||
|
const isEmptyRepo = useMemo(() => currentRepoInfo.file_count === 0, [currentRepoInfo]);
|
||||||
|
|
||||||
const [enableMetadata, setEnableExtendedProperties] = useState(false);
|
const [enableMetadata, setEnableExtendedProperties] = useState(false);
|
||||||
const [enableFaceRecognition, setEnableFaceRecognition] = useState(false);
|
const [enableFaceRecognition, setEnableFaceRecognition] = useState(false);
|
||||||
@@ -215,6 +216,7 @@ export const MetadataProvider = ({ repoID, currentRepoInfo, hideMetadataView, se
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<MetadataContext.Provider value={{
|
<MetadataContext.Provider value={{
|
||||||
|
isEmptyRepo,
|
||||||
enableMetadata,
|
enableMetadata,
|
||||||
updateEnableMetadata,
|
updateEnableMetadata,
|
||||||
enableFaceRecognition,
|
enableFaceRecognition,
|
||||||
|
@@ -11,3 +11,18 @@
|
|||||||
max-height: 24px;
|
max-height: 24px;
|
||||||
height: unset;
|
height: unset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.sf-metadata-loading-wrapper {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sf-metadata-loading-tip {
|
||||||
|
margin-top: 8px;
|
||||||
|
font-size: 14px;
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
import React, { useCallback } from 'react';
|
import React, { useCallback } from 'react';
|
||||||
import { CenteredLoading } from '@seafile/sf-metadata-ui-component';
|
import { CenteredLoading, Loading } from '@seafile/sf-metadata-ui-component';
|
||||||
import Table from '../views/table';
|
import Table from '../views/table';
|
||||||
import Gallery from '../views/gallery';
|
import Gallery from '../views/gallery';
|
||||||
import FaceRecognition from '../views/face-recognition';
|
import FaceRecognition from '../views/face-recognition';
|
||||||
@@ -10,7 +10,7 @@ import { gettext } from '../../utils/constants';
|
|||||||
import { VIEW_TYPE } from '../constants';
|
import { VIEW_TYPE } from '../constants';
|
||||||
|
|
||||||
const View = () => {
|
const View = () => {
|
||||||
const { isLoading, metadata, errorMsg } = useMetadataView();
|
const { isLoading, showFirstView, metadata, errorMsg } = useMetadataView();
|
||||||
|
|
||||||
const renderView = useCallback((metadata) => {
|
const renderView = useCallback((metadata) => {
|
||||||
if (!metadata) return null;
|
if (!metadata) return null;
|
||||||
@@ -36,7 +36,14 @@ const View = () => {
|
|||||||
}
|
}
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
if (isLoading) return (<CenteredLoading />);
|
if (isLoading) {
|
||||||
|
return showFirstView ? (
|
||||||
|
<div className="sf-metadata-loading-wrapper">
|
||||||
|
<Loading />
|
||||||
|
<span className="sf-metadata-loading-tip">{gettext('Extended properties are being built.')}</span>
|
||||||
|
</div>
|
||||||
|
) : <CenteredLoading />;
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="sf-metadata-wrapper">
|
<div className="sf-metadata-wrapper">
|
||||||
|
@@ -5,7 +5,7 @@ import {
|
|||||||
Operation, LOCAL_APPLY_OPERATION_TYPE, NEED_APPLY_AFTER_SERVER_OPERATION, OPERATION_TYPE, UNDO_OPERATION_TYPE,
|
Operation, LOCAL_APPLY_OPERATION_TYPE, NEED_APPLY_AFTER_SERVER_OPERATION, OPERATION_TYPE, UNDO_OPERATION_TYPE,
|
||||||
VIEW_OPERATION, COLUMN_OPERATION
|
VIEW_OPERATION, COLUMN_OPERATION
|
||||||
} from './operations';
|
} from './operations';
|
||||||
import { EVENT_BUS_TYPE, PER_LOAD_NUMBER, PRIVATE_COLUMN_KEY } from '../constants';
|
import { EVENT_BUS_TYPE, PER_LOAD_NUMBER, PRIVATE_COLUMN_KEY, DEFAULT_RETRY_TIMES, DEFAULT_RETRY_INTERVAL } from '../constants';
|
||||||
import DataProcessor from './data-processor';
|
import DataProcessor from './data-processor';
|
||||||
import ServerOperator from './server-operator';
|
import ServerOperator from './server-operator';
|
||||||
import LocalOperator from './local-operator';
|
import LocalOperator from './local-operator';
|
||||||
@@ -46,9 +46,13 @@ class Store {
|
|||||||
this.startIndex = 0;
|
this.startIndex = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
async loadMetadata(view, limit) {
|
async loadMetadata(view, limit, retries = DEFAULT_RETRY_TIMES, delay = DEFAULT_RETRY_INTERVAL) {
|
||||||
const res = await this.context.getMetadata({ view_id: this.viewId, start: this.startIndex, limit });
|
const res = await this.context.getMetadata({ view_id: this.viewId, start: this.startIndex, limit });
|
||||||
const rows = res?.data?.results || [];
|
const rows = res?.data?.results || [];
|
||||||
|
if (rows.length === 0 && retries > 0) {
|
||||||
|
await new Promise(resolve => setTimeout(resolve, delay));
|
||||||
|
return this.loadMetadata(view, limit, retries - 1, delay);
|
||||||
|
}
|
||||||
const columns = normalizeColumns(res?.data?.metadata);
|
const columns = normalizeColumns(res?.data?.metadata);
|
||||||
let data = new Metadata({ rows, columns, view });
|
let data = new Metadata({ rows, columns, view });
|
||||||
data.view.rows = data.row_ids;
|
data.view.rows = data.row_ids;
|
||||||
@@ -59,10 +63,11 @@ class Store {
|
|||||||
DataProcessor.run(this.data, { collaborators: this.collaborators });
|
DataProcessor.run(this.data, { collaborators: this.collaborators });
|
||||||
}
|
}
|
||||||
|
|
||||||
async load(limit = PER_LOAD_NUMBER) {
|
async load(limit = PER_LOAD_NUMBER, isEmptyRepo = 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 || {};
|
||||||
await this.loadMetadata(view, limit);
|
const retries = isEmptyRepo ? 0 : DEFAULT_RETRY_TIMES;
|
||||||
|
await this.loadMetadata(view, limit, retries);
|
||||||
}
|
}
|
||||||
|
|
||||||
async reload(limit = PER_LOAD_NUMBER) {
|
async reload(limit = PER_LOAD_NUMBER) {
|
||||||
|
Reference in New Issue
Block a user