@@ -22,6 +24,7 @@ const Header = ({ title, icon, onClose, component = {} }) => {
Header.propTypes = {
title: PropTypes.string.isRequired,
icon: PropTypes.string.isRequired,
+ iconSize: PropTypes.number,
component: PropTypes.object,
onClose: PropTypes.func.isRequired,
};
diff --git a/frontend/src/components/dirent-detail/dirent-details/index.css b/frontend/src/components/dirent-detail/dirent-details/index.css
index 9a0e83b5b6c..026a62878f0 100644
--- a/frontend/src/components/dirent-detail/dirent-details/index.css
+++ b/frontend/src/components/dirent-detail/dirent-details/index.css
@@ -42,3 +42,8 @@
.detail-body .sf-metadata-property-detail-tags.tags-empty {
padding: 6.5px 6px;;
}
+
+.detail-body .detail-content.detail-content-empty {
+ width: 100%;
+ height: 100%;
+}
diff --git a/frontend/src/metadata/components/gallery-details/index.js b/frontend/src/metadata/components/gallery-details/index.js
deleted file mode 100644
index 323155b797f..00000000000
--- a/frontend/src/metadata/components/gallery-details/index.js
+++ /dev/null
@@ -1,133 +0,0 @@
-import React, { useEffect, useMemo, useState } from 'react';
-import PropTypes from 'prop-types';
-import Repo from '../../../models/repo';
-import toaster from '../../../components/toast';
-import Loading from '../../../components/loading';
-import DetailItem from '../../../components/dirent-detail/detail-item';
-import { Formatter } from '@seafile/sf-metadata-ui-component';
-import { Utils } from '../../../utils/utils';
-import { gettext, siteRoot, thumbnailSizeForGrid } from '../../../utils/constants';
-import { Detail, Header, Body } from '../../../components/dirent-detail/detail';
-import { CellType, PRIVATE_COLUMN_KEY } from '../../constants';
-import { useMetadata, useGallery } from '../../../metadata';
-import { seafileAPI } from '../../../utils/seafile-api';
-import FileDetails from '../../../components/dirent-detail/dirent-details/file-details';
-import { Dirent } from '../../../models';
-
-const GalleryDetail = ({ currentRepoInfo, viewID, onClose }) => {
- const [isLoading, setLoading] = useState(true);
- const [repo, setRepo] = useState({});
- const [direntDetail, setDirentDetail] = useState(null);
- const { viewsMap } = useMetadata();
- const { currentImage } = useGallery();
-
- const view = useMemo(() => viewsMap[viewID], [viewID, viewsMap]);
- const icon = useMemo(() => Utils.getFolderIconUrl(), []);
- const creatorField = useMemo(() => ({ type: CellType.CREATOR, name: gettext('Creator') }), []);
- const mtimeField = useMemo(() => ({ type: CellType.MTIME, name: gettext('Last modified time') }), []);
-
- useEffect(() => {
- setLoading(true);
- seafileAPI.getRepoInfo(currentRepoInfo.repo_id).then(res => {
- const repo = new Repo(res.data);
- setRepo(repo);
- setLoading(false);
- }).catch(error => {
- let errMessage = Utils.getErrorMsg(error);
- toaster.danger(errMessage);
- });
- }, [currentRepoInfo.repo_id]);
-
- useEffect(() => {
- const fetchDirentDetail = async () => {
- if (currentImage) {
- try {
- const direntPath = Utils.joinPath(currentImage.path, currentImage.name);
- const res = await seafileAPI.getFileInfo(currentRepoInfo.repo_id, direntPath);
- setDirentDetail(res.data);
- } catch (error) {
- let errMessage = Utils.getErrorMsg(error);
- toaster.danger(errMessage);
- }
- } else {
- setDirentDetail(null);
- }
- };
-
- fetchDirentDetail();
- }, [currentImage, currentRepoInfo.repo_id]);
-
- const dirent = useMemo(() => {
- return currentImage ? new Dirent({
- id: currentImage.obj_id,
- name: currentImage.name,
- type: 'file'
- }) : null;
- }, [currentImage]);
-
- const smallIconUrl = useMemo(() => dirent ? Utils.getDirentIcon(dirent) : '', [dirent]);
- const bigIconUrl = useMemo(() => dirent ? `${siteRoot}thumbnail/${currentRepoInfo.repo_id}/${thumbnailSizeForGrid}${Utils.encodePath(`${currentImage.path === '/' ? '' : currentImage.path}/${dirent.name}`)}` : '', [dirent, currentRepoInfo.repo_id, currentImage]);
-
- const renderGalleryInfo = () => (
-
-
-
- {isLoading ? (
-
- ) : (
-
-
-
-
-
-
-
-
- )}
-
-
- );
-
- const renderImageInfo = () => (
-
-
-
-
-
-
- {dirent && direntDetail && (
-
-
-
- )}
-
-
- );
-
- return currentImage ? renderImageInfo() : renderGalleryInfo();
-};
-
-GalleryDetail.propTypes = {
- currentRepoInfo: PropTypes.object.isRequired,
- viewID: PropTypes.string.isRequired,
- onClose: PropTypes.func.isRequired,
-};
-
-export default GalleryDetail;
diff --git a/frontend/src/metadata/components/view-details/index.css b/frontend/src/metadata/components/view-details/index.css
new file mode 100644
index 00000000000..752ea2215c6
--- /dev/null
+++ b/frontend/src/metadata/components/view-details/index.css
@@ -0,0 +1,3 @@
+.sf-metadata-view-detail .detail-content-empty .empty-tip {
+ margin: 0;
+}
diff --git a/frontend/src/metadata/components/view-details/index.js b/frontend/src/metadata/components/view-details/index.js
new file mode 100644
index 00000000000..37a1356aa9a
--- /dev/null
+++ b/frontend/src/metadata/components/view-details/index.js
@@ -0,0 +1,38 @@
+import React, { useMemo } from 'react';
+import PropTypes from 'prop-types';
+import { gettext, mediaUrl } from '../../../utils/constants';
+import { Detail, Header, Body } from '../../../components/dirent-detail/detail';
+import EmptyTip from '../../../components/empty-tip';
+import { useMetadata } from '../../hooks';
+import { VIEW_TYPE } from '../../constants';
+
+import './index.css';
+
+const ViewDetails = ({ viewId, onClose }) => {
+ const { viewsMap } = useMetadata();
+
+ const view = useMemo(() => viewsMap[viewId], [viewId, viewsMap]);
+ const icon = useMemo(() => {
+ const type = view.type;
+ if (type === VIEW_TYPE.GALLERY) return `${mediaUrl}favicons/gallery.png`;
+ if (type === VIEW_TYPE.TABLE) return `${mediaUrl}favicons/table.png`;
+ }, [view]);
+
+ return (
+
+
+
+
+
+
+
+
+ );
+};
+
+ViewDetails.propTypes = {
+ viewId: PropTypes.string.isRequired,
+ onClose: PropTypes.func.isRequired,
+};
+
+export default ViewDetails;
diff --git a/frontend/src/metadata/components/view-toolbar/gallery-view-toolbar/index.js b/frontend/src/metadata/components/view-toolbar/gallery-view-toolbar/index.js
new file mode 100644
index 00000000000..79328d8634b
--- /dev/null
+++ b/frontend/src/metadata/components/view-toolbar/gallery-view-toolbar/index.js
@@ -0,0 +1,71 @@
+import React, { useMemo } from 'react';
+import PropTypes from 'prop-types';
+import { GalleryGroupBySetter, GallerySliderSetter, FilterSetter, SortSetter } from '../../data-process-setter';
+import { PRIVATE_COLUMN_KEY } from '../../../constants';
+import { gettext } from '../../../../utils/constants';
+
+const GalleryViewToolbar = ({
+ readOnly, isCustomPermission, view, collaborators,
+ modifyFilters, modifySorts, showDetail,
+}) => {
+ const viewType = useMemo(() => view.type, [view]);
+ const viewColumns = useMemo(() => {
+ if (!view) return [];
+ return view.columns;
+ }, [view]);
+
+ const filterColumns = useMemo(() => {
+ return viewColumns.filter(c => c.key !== PRIVATE_COLUMN_KEY.FILE_TYPE);
+ }, [viewColumns]);
+
+ return (
+ <>
+
+
+
+
+
+ {!isCustomPermission && (
+
+
+
+ )}
+
+
+ >
+ );
+};
+
+GalleryViewToolbar.propTypes = {
+ readOnly: PropTypes.bool,
+ isCustomPermission: PropTypes.bool,
+ view: PropTypes.object.isRequired,
+ collaborators: PropTypes.array,
+ modifyFilters: PropTypes.func,
+ modifySorts: PropTypes.func,
+ showDetail: PropTypes.func,
+};
+
+export default GalleryViewToolbar;
diff --git a/frontend/src/metadata/components/view-toolbar/index.js b/frontend/src/metadata/components/view-toolbar/index.js
index 7a9b2e7713c..1404e142918 100644
--- a/frontend/src/metadata/components/view-toolbar/index.js
+++ b/frontend/src/metadata/components/view-toolbar/index.js
@@ -1,24 +1,15 @@
-import React, { useCallback, useEffect, useMemo, useState } from 'react';
+import React, { useCallback, useEffect, useState } from 'react';
import PropTypes from 'prop-types';
-import { GalleryGroupBySetter, GallerySliderSetter, FilterSetter, GroupbySetter, SortSetter, HideColumnSetter } from '../data-process-setter';
-import { EVENT_BUS_TYPE, PRIVATE_COLUMN_KEY, VIEW_TYPE } from '../../constants';
-import { gettext } from '../../../utils/constants';
+import { EVENT_BUS_TYPE, VIEW_TYPE } from '../../constants';
+import TableViewToolbar from './table-view-toolbar';
+import GalleryViewToolbar from './gallery-view-toolbar';
import './index.css';
-const ViewToolBar = ({ viewId, isCustomPermission, switchViewMode }) => {
+const ViewToolBar = ({ viewId, isCustomPermission, showDetail }) => {
const [view, setView] = useState(null);
const [collaborators, setCollaborators] = useState([]);
- const viewColumns = useMemo(() => {
- if (!view) return [];
- return view.columns;
- }, [view]);
-
- const filterColumns = useMemo(() => {
- return viewColumns.filter(c => c.key !== PRIVATE_COLUMN_KEY.FILE_TYPE);
- }, [viewColumns]);
-
const onHeaderClick = useCallback(() => {
window.sfMetadataContext.eventBus.dispatch(EVENT_BUS_TYPE.SELECT_NONE);
}, []);
@@ -68,73 +59,36 @@ const ViewToolBar = ({ viewId, isCustomPermission, switchViewMode }) => {
if (!view) return null;
const viewType = view.type;
- const readOnly = !window.sfMetadataContext.canModifyView(view);
+ const readOnly = window.sfMetadataContext ? !window.sfMetadataContext.canModifyView(view) : true;
return (
-
- {viewType === VIEW_TYPE.GALLERY && (
- <>
-
-
- >
- )}
-
-
- {viewType === VIEW_TYPE.GALLERY && !isCustomPermission && (
-
switchViewMode('detail')}>
-
-
- )}
- {viewType !== VIEW_TYPE.GALLERY && (
-
- )}
- {viewType !== VIEW_TYPE.GALLERY && (
-
- )}
-
-
+ )}
);
};
diff --git a/frontend/src/metadata/components/view-toolbar/table-view-toolbar/index.js b/frontend/src/metadata/components/view-toolbar/table-view-toolbar/index.js
new file mode 100644
index 00000000000..8d3bc3c6c03
--- /dev/null
+++ b/frontend/src/metadata/components/view-toolbar/table-view-toolbar/index.js
@@ -0,0 +1,82 @@
+import React, { useMemo } from 'react';
+import PropTypes from 'prop-types';
+import { FilterSetter, GroupbySetter, SortSetter, HideColumnSetter } from '../../data-process-setter';
+import { PRIVATE_COLUMN_KEY } from '../../../constants';
+
+const TableViewToolbar = ({
+ readOnly, view, collaborators,
+ modifyFilters, modifySorts, modifyGroupbys, modifyHiddenColumns, modifyColumnOrder
+}) => {
+ const viewType = useMemo(() => view.type, [view]);
+ const viewColumns = useMemo(() => {
+ if (!view) return [];
+ return view.columns;
+ }, [view]);
+
+ const filterColumns = useMemo(() => {
+ return viewColumns.filter(c => c.key !== PRIVATE_COLUMN_KEY.FILE_TYPE);
+ }, [viewColumns]);
+
+ return (
+ <>
+
+
+
+
+
+
+
+ >
+ );
+};
+
+TableViewToolbar.propTypes = {
+ readOnly: PropTypes.bool,
+ view: PropTypes.object.isRequired,
+ collaborators: PropTypes.array,
+ modifyFilters: PropTypes.func,
+ modifySorts: PropTypes.func,
+ modifyGroupbys: PropTypes.func,
+ modifyHiddenColumns: PropTypes.func,
+ modifyColumnOrder: PropTypes.func,
+};
+
+export default TableViewToolbar;
diff --git a/frontend/src/metadata/hooks/gallery.js b/frontend/src/metadata/hooks/gallery.js
deleted file mode 100644
index 142f148ae0e..00000000000
--- a/frontend/src/metadata/hooks/gallery.js
+++ /dev/null
@@ -1,27 +0,0 @@
-import React, { useState, createContext, useContext, useCallback } from 'react';
-
-const GalleryContext = createContext();
-
-export const GalleryProvider = ({ children }) => {
- const [currentImage, setCurrentImage] = useState(null);
-
- const updateCurrentImage = useCallback((image) => {
- setCurrentImage(image);
- }, []);
-
- return (
-
- {children}
-
- );
-};
-
-export const useGallery = () => {
- const context = useContext(GalleryContext);
-
- if (!context) {
- throw new Error('\'GalleryContext\' is null');
- }
-
- return context;
-};
diff --git a/frontend/src/metadata/hooks/index.js b/frontend/src/metadata/hooks/index.js
index 73beeb7a5a7..74b4c9ab566 100644
--- a/frontend/src/metadata/hooks/index.js
+++ b/frontend/src/metadata/hooks/index.js
@@ -1,4 +1,3 @@
export { MetadataProvider, useMetadata } from './metadata';
export { EnableMetadataProvider, useEnableMetadata } from './enable-metadata';
export { CollaboratorsProvider, useCollaborators } from './collaborators';
-export { GalleryProvider, useGallery } from './gallery';
diff --git a/frontend/src/metadata/hooks/metadata-view.js b/frontend/src/metadata/hooks/metadata-view.js
index f5aa31e08f6..105af8eade9 100644
--- a/frontend/src/metadata/hooks/metadata-view.js
+++ b/frontend/src/metadata/hooks/metadata-view.js
@@ -124,6 +124,7 @@ export const MetadataViewProvider = ({
store: storeRef.current,
deleteFilesCallback: params.deleteFilesCallback,
renameFileCallback: params.renameFileCallback,
+ updateCurrentDirent: params.updateCurrentDirent,
}}
>
{children}
diff --git a/frontend/src/metadata/hooks/metadata.js b/frontend/src/metadata/hooks/metadata.js
index 7c3a3d61d6d..7c572b7e8b8 100644
--- a/frontend/src/metadata/hooks/metadata.js
+++ b/frontend/src/metadata/hooks/metadata.js
@@ -137,11 +137,11 @@ export const MetadataProvider = ({ repoID, hideMetadataView, selectMetadataView,
name: isFaceRecognitionView ? gettext('Photos - classfied by people') : gettext('File extended properties'),
type: isFaceRecognitionView ? PRIVATE_FILE_TYPE.FACE_RECOGNITION : PRIVATE_FILE_TYPE.FILE_EXTENDED_PROPERTIES,
isDir: () => false,
- viewType: view.type,
},
parentNode: {},
key: repoID,
view_id: view._id,
+ view_type: view.type,
};
selectMetadataView(node);
// eslint-disable-next-line react-hooks/exhaustive-deps
diff --git a/frontend/src/metadata/views/gallery/gallery-main.js b/frontend/src/metadata/views/gallery/gallery-main.js
index 82a77b59071..b4a91efaa7a 100644
--- a/frontend/src/metadata/views/gallery/gallery-main.js
+++ b/frontend/src/metadata/views/gallery/gallery-main.js
@@ -1,4 +1,4 @@
-import React, { useState, useCallback, useMemo, useRef, useEffect } from 'react';
+import React, { useState, useCallback, useMemo, useRef } from 'react';
import classnames from 'classnames';
import PropTypes from 'prop-types';
import EmptyTip from '../../../components/empty-tip';
@@ -12,7 +12,7 @@ const GalleryMain = ({
size,
gap,
mode,
- selectedImageIDs,
+ selectedImages,
onImageSelect,
onImageClick,
onImageDoubleClick,
@@ -26,6 +26,7 @@ const GalleryMain = ({
const [selectionStart, setSelectionStart] = useState(null);
const imageHeight = useMemo(() => size + gap, [size, gap]);
+ const selectedImageIds = useMemo(() => selectedImages.map(img => img.id), [selectedImages]);
const handleMouseDown = useCallback((e) => {
if (e.button !== 0) return;
@@ -80,28 +81,6 @@ const GalleryMain = ({
setIsSelecting(false);
}, []);
- const handleClickOutside = useCallback((e) => {
- const images = containerRef.current.querySelectorAll('.metadata-gallery-image-item');
- let isClickInsideImage = false;
-
- images.forEach(img => {
- if (img.contains(e.target)) {
- isClickInsideImage = true;
- }
- });
-
- if (!isClickInsideImage && containerRef.current.contains(e.target)) {
- onImageSelect([]);
- }
- }, [onImageSelect]);
-
- useEffect(() => {
- document.addEventListener('mousedown', handleClickOutside);
- return () => {
- document.removeEventListener('mousedown', handleClickOutside);
- };
- }, [handleClickOutside]);
-
const renderDisplayGroup = useCallback((group) => {
const { top: overScanTop, bottom: overScanBottom } = overScan;
const { name, children, height, top, paddingTop } = group;
@@ -138,6 +117,7 @@ const GalleryMain = ({
{name || gettext('Empty')}
)}
{children.slice(childrenStartIndex, childrenEndIndex + 1).map((row) => {
return row.children.map((img) => {
- const isSelected = selectedImageIDs.includes(img.id);
+ const isSelected = selectedImageIds.includes(img.id);
return (
);
- }, [overScan, columns, size, imageHeight, mode, selectedImageIDs, onImageClick, onImageDoubleClick, onImageRightClick]);
+ }, [overScan, columns, size, imageHeight, mode, selectedImageIds, onImageClick, onImageDoubleClick, onImageRightClick]);
if (!Array.isArray(groups) || groups.length === 0) {
return
;
@@ -213,7 +192,7 @@ GalleryMain.propTypes = {
size: PropTypes.number.isRequired,
gap: PropTypes.number.isRequired,
mode: PropTypes.string,
- selectedImageIDs: PropTypes.array.isRequired,
+ selectedImages: PropTypes.array.isRequired,
onImageSelect: PropTypes.func.isRequired,
onImageClick: PropTypes.func.isRequired,
onImageDoubleClick: PropTypes.func.isRequired,
diff --git a/frontend/src/metadata/views/gallery/index.css b/frontend/src/metadata/views/gallery/index.css
index f259d2ca56e..abefa0b1908 100644
--- a/frontend/src/metadata/views/gallery/index.css
+++ b/frontend/src/metadata/views/gallery/index.css
@@ -1,5 +1,5 @@
.sf-metadata-gallery-container {
- height: calc(100vh - 100px);
+ height: 100%;
padding: 0 16px;
position: relative;
display: flex;
diff --git a/frontend/src/metadata/views/gallery/index.js b/frontend/src/metadata/views/gallery/index.js
index eddfa5ae5e7..75f6ea6d1a1 100644
--- a/frontend/src/metadata/views/gallery/index.js
+++ b/frontend/src/metadata/views/gallery/index.js
@@ -9,13 +9,15 @@ import ImageDialog from '../../../components/dialog/image-dialog';
import ZipDownloadDialog from '../../../components/dialog/zip-download-dialog';
import ModalPortal from '../../../components/modal-portal';
import { useMetadataView } from '../../hooks/metadata-view';
+import { useCollaborators } from '../../hooks';
import { Utils } from '../../../utils/utils';
import { getDateDisplayString, getFileNameFromRecord, getParentDirFromRecord } from '../../utils/cell';
import { siteRoot, fileServerRoot, useGoFileserver, gettext, thumbnailSizeForGrid, thumbnailSizeForOriginal } from '../../../utils/constants';
import { EVENT_BUS_TYPE, PER_LOAD_NUMBER, PRIVATE_COLUMN_KEY, GALLERY_DATE_MODE, DATE_TAG_HEIGHT, GALLERY_IMAGE_GAP } from '../../constants';
-import { useGallery } from '../../hooks';
+import { getRowById } from '../../utils/table';
import './index.css';
+import { getEventClassName } from '../../utils/common';
const Gallery = () => {
const [isFirstLoading, setFirstLoading] = useState(true);
@@ -32,15 +34,14 @@ const Gallery = () => {
const containerRef = useRef(null);
const renderMoreTimer = useRef(null);
- const { updateCurrentImage } = useGallery();
- const { metadata, store } = useMetadataView();
- const repoID = store.repoId;
+ const { metadata, store, updateCurrentDirent } = useMetadataView();
+ const { getCollaborator } = useCollaborators();
+ const repoID = window.sfMetadataContext.getSetting('repoID');
- useEffect(() => updateCurrentImage(selectedImages[0]), [selectedImages, updateCurrentImage]);
-
- const selectedImageIDs = useMemo(() => {
- return selectedImages.map(image => image.id);
- }, [selectedImages]);
+ useEffect(() => {
+ updateCurrentDirent();
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ }, []);
// Number of images per row
const columns = useMemo(() => {
@@ -214,22 +215,48 @@ const Gallery = () => {
return groups.flatMap(group => group.children.flatMap(row => row.children));
}, [groups]);
+ const updateSelectedImage = useCallback((image = null) => {
+ const imageInfo = image ? getRowById(metadata, image.id) : null;
+ if (!imageInfo) {
+ updateCurrentDirent();
+ return;
+ }
+ const size = imageInfo[PRIVATE_COLUMN_KEY.SIZE];
+ const lastModifierEmail = imageInfo[PRIVATE_COLUMN_KEY.FILE_MODIFIER];
+ const lastModifier = getCollaborator(lastModifierEmail);
+ const lastModified = imageInfo[PRIVATE_COLUMN_KEY.FILE_MTIME];
+ updateCurrentDirent({
+ type: 'file',
+ name: image.name,
+ path: image.path,
+ size: (typeof size === 'number') ? Utils.bytesToSize(size) : size,
+ last_modified: lastModified || '',
+ last_modifier_name: lastModifier.name || '',
+ last_modifier_email: lastModifier.email || '',
+ last_modifier_avatar: lastModified.avatar_url || '',
+ modifier_contact_email: lastModifier || '',
+ file_tags: []
+ });
+ }, [metadata, getCollaborator, updateCurrentDirent]);
+
const handleClick = useCallback((event, image) => {
if (event.metaKey || event.ctrlKey) {
setSelectedImages(prev =>
prev.includes(image) ? prev.filter(img => img !== image) : [...prev, image]
);
+ updateSelectedImage(image);
} else if (event.shiftKey && selectedImages.length > 0) {
const lastSelected = selectedImages[selectedImages.length - 1];
const start = imageItems.indexOf(lastSelected);
const end = imageItems.indexOf(image);
const range = imageItems.slice(Math.min(start, end), Math.max(start, end) + 1);
setSelectedImages(prev => Array.from(new Set([...prev, ...range])));
+ updateSelectedImage(null);
} else {
- updateCurrentImage(image);
setSelectedImages([image]);
+ updateSelectedImage(image);
}
- }, [imageItems, selectedImages, updateCurrentImage]);
+ }, [imageItems, selectedImages, updateSelectedImage]);
const handleDoubleClick = useCallback((event, image) => {
const index = imageItems.findIndex(item => item.id === image.id);
@@ -321,8 +348,18 @@ const Gallery = () => {
setIsZipDialogOpen(false);
};
+ const handleClickOutside = useCallback((event) => {
+ const className = getEventClassName(event);
+ const isClickInsideImage = className.includes('metadata-gallery-image-item') || className.includes('metadata-gallery-grid-image');
+
+ if (!isClickInsideImage && containerRef.current.contains(event.target)) {
+ handleImageSelection([]);
+ updateSelectedImage();
+ }
+ }, [handleImageSelection, updateSelectedImage]);
+
return (
-
+
{!isFirstLoading && (
<>
@@ -333,7 +370,7 @@ const Gallery = () => {
overScan={overScan}
gap={GALLERY_IMAGE_GAP}
mode={mode}
- selectedImageIDs={selectedImageIDs}
+ selectedImages={selectedImages}
onImageSelect={handleImageSelection}
onImageClick={handleClick}
onImageDoubleClick={handleDoubleClick}
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 1a871643ce5..911ca6cd68c 100644
--- a/frontend/src/pages/lib-content-view/lib-content-view.js
+++ b/frontend/src/pages/lib-content-view/lib-content-view.js
@@ -21,13 +21,14 @@ import CopyMoveDirentProgressDialog from '../../components/dialog/copy-move-dire
import DeleteFolderDialog from '../../components/dialog/delete-folder-dialog';
import { EVENT_BUS_TYPE } from '../../components/common/event-bus-type';
import { PRIVATE_FILE_TYPE } from '../../constants';
-import { MetadataProvider, CollaboratorsProvider, GalleryProvider } from '../../metadata/hooks';
-import { LIST_MODE, METADATA_MODE, FACE_RECOGNITION_MODE, VIEW_TYPE } from '../../components/dir-view-mode/constants';
+import { MetadataProvider, CollaboratorsProvider } from '../../metadata/hooks';
+import { LIST_MODE, METADATA_MODE, FACE_RECOGNITION_MODE, DIRENT_DETAIL_MODE } from '../../components/dir-view-mode/constants';
import CurDirPath from '../../components/cur-dir-path';
import DirTool from '../../components/cur-dir-path/dir-tool';
import DetailContainer from '../../components/dirent-detail/detail-container';
import DirColumnView from '../../components/dir-view-mode/dir-column-view';
import SelectedDirentsToolbar from '../../components/toolbar/selected-dirents-toolbar';
+import { VIEW_TYPE } from '../../metadata/constants';
import '../../css/lib-content-view.css';
@@ -83,7 +84,6 @@ class LibContentView extends React.Component {
dirID: '', // for update dir list
errorMsg: '',
isDirentDetailShow: false,
- direntDetailPanelTab: '',
itemsShowLength: 100,
isSessionExpired: false,
isCopyMoveProgressDialogShow: false,
@@ -107,7 +107,11 @@ class LibContentView extends React.Component {
this.unsubscribeEventBus = null;
}
- updateCurrentDirent = (deletedDirent) => {
+ updateCurrentDirent = (dirent = null) => {
+ this.setState({ currentDirent: dirent });
+ };
+
+ updateCurrentNotExistDirent = (deletedDirent) => {
let { currentDirent } = this.state;
if (currentDirent && deletedDirent.name === currentDirent.name) {
this.setState({ currentDirent: null });
@@ -124,31 +128,16 @@ class LibContentView extends React.Component {
}
};
- showDirentDetail = (direntDetailPanelTab) => {
- if (direntDetailPanelTab) {
- this.setState({ direntDetailPanelTab: direntDetailPanelTab }, () => {
- this.setState({ isDirentDetailShow: true });
- });
- } else {
- this.setState({
- direntDetailPanelTab: '',
- isDirentDetailShow: true
- });
- }
+ showDirentDetail = () => {
+ this.setState({ isDirentDetailShow: true });
};
toggleDirentDetail = () => {
- this.setState({
- direntDetailPanelTab: '',
- isDirentDetailShow: !this.state.isDirentDetailShow
- });
+ this.setState({ isDirentDetailShow: !this.state.isDirentDetailShow });
};
closeDirentDetail = () => {
- this.setState({
- isDirentDetailShow: false,
- direntDetailPanelTab: '',
- });
+ this.setState({ isDirentDetailShow: false });
};
componentDidMount() {
@@ -1020,7 +1009,7 @@ class LibContentView extends React.Component {
if (mode === this.state.currentMode) {
return;
}
- if (mode === 'detail') {
+ if (mode === DIRENT_DETAIL_MODE) {
this.toggleDirentDetail();
return;
}
@@ -1134,7 +1123,7 @@ class LibContentView extends React.Component {
};
onMainPanelItemDelete = (dirent) => {
- this.updateCurrentDirent(dirent);
+ this.updateCurrentNotExistDirent(dirent);
let path = Utils.joinPath(this.state.path, dirent.name);
this.deleteItem(path, dirent.isDir());
};
@@ -1261,7 +1250,7 @@ class LibContentView extends React.Component {
// list operations
onMoveItem = (destRepo, dirent, moveToDirentPath, nodeParentPath) => {
- this.updateCurrentDirent(dirent);
+ this.updateCurrentNotExistDirent(dirent);
let repoID = this.props.repoID;
// just for view list state
let dirName = dirent.name;
@@ -1897,7 +1886,7 @@ class LibContentView extends React.Component {
}
} else if (Utils.isFileMetadata(node?.object?.type)) {
if (node.path !== this.state.path) {
- this.showFileMetadata(node.path, node.view_id || '0000', node.object.viewType);
+ this.showFileMetadata(node.path, node.view_id || '0000', node.view_type || VIEW_TYPE.TABLE);
}
} else if (Utils.isFaceRecognition(node?.object?.type)) {
if (node.path !== this.state.path) {
@@ -2360,94 +2349,92 @@ class LibContentView extends React.Component {
}
-
-
- {this.state.pathExist ?
-
- :
-
{gettext('Folder does not exist.')}
- }
- {this.state.isDirentDetailShow && (
-
- )}
-
-
+
+ {this.state.pathExist ?
+
+ :
+
{gettext('Folder does not exist.')}
+ }
+ {this.state.isDirentDetailShow && (
+
+ )}
+
{canUpload && this.state.pathExist && !this.state.isViewFile && this.state.currentMode !== METADATA_MODE && (