mirror of
https://github.com/haiwen/seahub.git
synced 2025-09-13 22:01:06 +00:00
record the status of detail to local storage (#7194)
* record the status of detail to local storage * face recognition view support show detail * feat: optimize code * fix: bug --------- Co-authored-by: zhouwenxuan <aries@Mac.local> Co-authored-by: 杨国璇 <ygx@Hello-word.local>
This commit is contained in:
@@ -10,7 +10,6 @@ import ViewModes from '../../components/view-modes';
|
|||||||
import SortMenu from '../../components/sort-menu';
|
import SortMenu from '../../components/sort-menu';
|
||||||
import MetadataViewToolBar from '../../metadata/components/view-toolbar';
|
import MetadataViewToolBar from '../../metadata/components/view-toolbar';
|
||||||
import { PRIVATE_FILE_TYPE } from '../../constants';
|
import { PRIVATE_FILE_TYPE } from '../../constants';
|
||||||
import { DIRENT_DETAIL_MODE } from '../dir-view-mode/constants';
|
|
||||||
|
|
||||||
const propTypes = {
|
const propTypes = {
|
||||||
repoID: PropTypes.string.isRequired,
|
repoID: PropTypes.string.isRequired,
|
||||||
@@ -25,7 +24,7 @@ const propTypes = {
|
|||||||
sortOrder: PropTypes.string,
|
sortOrder: PropTypes.string,
|
||||||
sortItems: PropTypes.func,
|
sortItems: PropTypes.func,
|
||||||
viewId: PropTypes.string,
|
viewId: PropTypes.string,
|
||||||
onCloseDetail: PropTypes.func,
|
onToggleDetail: PropTypes.func,
|
||||||
};
|
};
|
||||||
|
|
||||||
class DirTool extends React.Component {
|
class DirTool extends React.Component {
|
||||||
@@ -92,14 +91,10 @@ class DirTool extends React.Component {
|
|||||||
this.props.sortItems(sortBy, sortOrder);
|
this.props.sortItems(sortBy, sortOrder);
|
||||||
};
|
};
|
||||||
|
|
||||||
showDirentDetail = () => {
|
|
||||||
this.props.switchViewMode(DIRENT_DETAIL_MODE);
|
|
||||||
};
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const menuItems = this.getMenu();
|
const menuItems = this.getMenu();
|
||||||
const { isDropdownMenuOpen } = this.state;
|
const { isDropdownMenuOpen } = this.state;
|
||||||
const { repoID, currentMode, currentPath, sortBy, sortOrder, viewId, isCustomPermission } = this.props;
|
const { repoID, currentMode, currentPath, sortBy, sortOrder, viewId, isCustomPermission, onToggleDetail } = this.props;
|
||||||
const propertiesText = TextTranslation.PROPERTIES.value;
|
const propertiesText = TextTranslation.PROPERTIES.value;
|
||||||
const isFileExtended = currentPath.startsWith('/' + PRIVATE_FILE_TYPE.FILE_EXTENDED_PROPERTIES + '/');
|
const isFileExtended = currentPath.startsWith('/' + PRIVATE_FILE_TYPE.FILE_EXTENDED_PROPERTIES + '/');
|
||||||
const isTagView = currentPath.startsWith('/' + PRIVATE_FILE_TYPE.TAGS_PROPERTIES + '/');
|
const isTagView = currentPath.startsWith('/' + PRIVATE_FILE_TYPE.TAGS_PROPERTIES + '/');
|
||||||
@@ -110,8 +105,7 @@ class DirTool extends React.Component {
|
|||||||
<MetadataViewToolBar
|
<MetadataViewToolBar
|
||||||
viewId={viewId}
|
viewId={viewId}
|
||||||
isCustomPermission={isCustomPermission}
|
isCustomPermission={isCustomPermission}
|
||||||
showDetail={this.showDirentDetail}
|
onToggleDetail={onToggleDetail}
|
||||||
closeDetail={this.props.onCloseDetail}
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
@@ -130,7 +124,7 @@ class DirTool extends React.Component {
|
|||||||
<ViewModes currentViewMode={currentMode} switchViewMode={this.props.switchViewMode} />
|
<ViewModes currentViewMode={currentMode} switchViewMode={this.props.switchViewMode} />
|
||||||
<SortMenu sortBy={sortBy} sortOrder={sortOrder} onSelectSortOption={this.onSelectSortOption} />
|
<SortMenu sortBy={sortBy} sortOrder={sortOrder} onSelectSortOption={this.onSelectSortOption} />
|
||||||
{(!isCustomPermission) &&
|
{(!isCustomPermission) &&
|
||||||
<div className="cur-view-path-btn" onClick={this.showDirentDetail}>
|
<div className="cur-view-path-btn" onClick={onToggleDetail}>
|
||||||
<span className="sf3-font sf3-font-info" aria-label={propertiesText} title={propertiesText}></span>
|
<span className="sf3-font sf3-font-info" aria-label={propertiesText} title={propertiesText}></span>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
@@ -1,5 +1,4 @@
|
|||||||
export const LIST_MODE = 'list';
|
export const LIST_MODE = 'list';
|
||||||
export const GRID_MODE = 'grid';
|
export const GRID_MODE = 'grid';
|
||||||
export const DIRENT_DETAIL_MODE = 'detail';
|
|
||||||
export const METADATA_MODE = 'metadata';
|
export const METADATA_MODE = 'metadata';
|
||||||
export const TAGS_MODE = 'tags';
|
export const TAGS_MODE = 'tags';
|
||||||
|
@@ -83,7 +83,6 @@ const propTypes = {
|
|||||||
onItemsScroll: PropTypes.func.isRequired,
|
onItemsScroll: PropTypes.func.isRequired,
|
||||||
eventBus: PropTypes.object,
|
eventBus: PropTypes.object,
|
||||||
updateCurrentDirent: PropTypes.func.isRequired,
|
updateCurrentDirent: PropTypes.func.isRequired,
|
||||||
closeDirentDetail: PropTypes.func.isRequired,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class DirColumnView extends React.Component {
|
class DirColumnView extends React.Component {
|
||||||
@@ -211,7 +210,6 @@ class DirColumnView extends React.Component {
|
|||||||
copyFileCallback={this.props.copyFileCallback}
|
copyFileCallback={this.props.copyFileCallback}
|
||||||
addFolder={this.props.onAddFolder}
|
addFolder={this.props.onAddFolder}
|
||||||
updateCurrentDirent={this.props.updateCurrentDirent}
|
updateCurrentDirent={this.props.updateCurrentDirent}
|
||||||
closeDirentDetail={this.props.closeDirentDetail}
|
|
||||||
showDirentDetail={this.props.showDirentDetail}
|
showDirentDetail={this.props.showDirentDetail}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
@@ -224,7 +222,6 @@ class DirColumnView extends React.Component {
|
|||||||
deleteFilesCallback={this.props.deleteFilesCallback}
|
deleteFilesCallback={this.props.deleteFilesCallback}
|
||||||
renameFileCallback={this.props.renameFileCallback}
|
renameFileCallback={this.props.renameFileCallback}
|
||||||
updateCurrentDirent={this.props.updateCurrentDirent}
|
updateCurrentDirent={this.props.updateCurrentDirent}
|
||||||
closeDirentDetail={this.props.closeDirentDetail}
|
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{currentMode === LIST_MODE &&
|
{currentMode === LIST_MODE &&
|
||||||
|
@@ -6,9 +6,10 @@ import ViewDetails from '../../metadata/components/view-details';
|
|||||||
import ObjectUtils from '../../metadata/utils/object-utils';
|
import ObjectUtils from '../../metadata/utils/object-utils';
|
||||||
import { MetadataContext } from '../../metadata';
|
import { MetadataContext } from '../../metadata';
|
||||||
import { PRIVATE_FILE_TYPE } from '../../constants';
|
import { PRIVATE_FILE_TYPE } from '../../constants';
|
||||||
|
import { METADATA_MODE, TAGS_MODE } from '../dir-view-mode/constants';
|
||||||
|
|
||||||
const Detail = React.memo(({ repoID, path, dirent, currentRepoInfo, repoTags, fileTags, onClose, onFileTagChanged }) => {
|
const Detail = React.memo(({ repoID, path, currentMode, dirent, currentRepoInfo, repoTags, fileTags, onClose, onFileTagChanged }) => {
|
||||||
const isView = useMemo(() => path.startsWith('/' + PRIVATE_FILE_TYPE.FILE_EXTENDED_PROPERTIES), [path]);
|
const isView = useMemo(() => currentMode === METADATA_MODE || path.startsWith('/' + PRIVATE_FILE_TYPE.FILE_EXTENDED_PROPERTIES), [currentMode, path]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (isView) return;
|
if (isView) return;
|
||||||
@@ -25,6 +26,8 @@ const Detail = React.memo(({ repoID, path, dirent, currentRepoInfo, repoTags, fi
|
|||||||
};
|
};
|
||||||
}, [repoID, currentRepoInfo, isView]);
|
}, [repoID, currentRepoInfo, isView]);
|
||||||
|
|
||||||
|
if (currentMode === TAGS_MODE) return null;
|
||||||
|
|
||||||
if (isView) {
|
if (isView) {
|
||||||
const viewId = path.split('/').pop();
|
const viewId = path.split('/').pop();
|
||||||
if (!dirent) return (<ViewDetails viewId={viewId} onClose={onClose} />);
|
if (!dirent) return (<ViewDetails viewId={viewId} onClose={onClose} />);
|
||||||
@@ -60,6 +63,7 @@ const Detail = React.memo(({ repoID, path, dirent, currentRepoInfo, repoTags, fi
|
|||||||
Detail.propTypes = {
|
Detail.propTypes = {
|
||||||
repoID: PropTypes.string,
|
repoID: PropTypes.string,
|
||||||
path: PropTypes.string,
|
path: PropTypes.string,
|
||||||
|
currentMode: PropTypes.string,
|
||||||
dirent: PropTypes.object,
|
dirent: PropTypes.object,
|
||||||
currentRepoInfo: PropTypes.object,
|
currentRepoInfo: PropTypes.object,
|
||||||
repoTags: PropTypes.array,
|
repoTags: PropTypes.array,
|
||||||
|
@@ -35,7 +35,6 @@ const propTypes = {
|
|||||||
unSelectDirent: PropTypes.func.isRequired,
|
unSelectDirent: PropTypes.func.isRequired,
|
||||||
updateDirent: PropTypes.func.isRequired,
|
updateDirent: PropTypes.func.isRequired,
|
||||||
currentMode: PropTypes.string.isRequired,
|
currentMode: PropTypes.string.isRequired,
|
||||||
switchViewMode: PropTypes.func.isRequired,
|
|
||||||
direntList: PropTypes.array.isRequired,
|
direntList: PropTypes.array.isRequired,
|
||||||
onItemRename: PropTypes.func.isRequired,
|
onItemRename: PropTypes.func.isRequired,
|
||||||
showDirentDetail: PropTypes.func.isRequired,
|
showDirentDetail: PropTypes.func.isRequired,
|
||||||
|
@@ -43,3 +43,5 @@ export const SYSTEM_FOLDERS = [
|
|||||||
'/_Internal',
|
'/_Internal',
|
||||||
'/images'
|
'/images'
|
||||||
];
|
];
|
||||||
|
|
||||||
|
export const DIRENT_DETAIL_SHOW_KEY = 'sf_dirent_detail_show';
|
||||||
|
@@ -4,7 +4,7 @@ import { gettext, mediaUrl } from '../../../utils/constants';
|
|||||||
import { Detail, Header, Body } from '../../../components/dirent-detail/detail';
|
import { Detail, Header, Body } from '../../../components/dirent-detail/detail';
|
||||||
import EmptyTip from '../../../components/empty-tip';
|
import EmptyTip from '../../../components/empty-tip';
|
||||||
import { useMetadata } from '../../hooks';
|
import { useMetadata } from '../../hooks';
|
||||||
import { VIEW_TYPE } from '../../constants';
|
import { VIEW_TYPE, VIEW_TYPES_SUPPORT_SHOW_DETAIL } from '../../constants';
|
||||||
|
|
||||||
import './index.css';
|
import './index.css';
|
||||||
|
|
||||||
@@ -13,7 +13,7 @@ const ViewDetails = ({ viewId, onClose }) => {
|
|||||||
|
|
||||||
const view = useMemo(() => idViewMap[viewId], [viewId, idViewMap]);
|
const view = useMemo(() => idViewMap[viewId], [viewId, idViewMap]);
|
||||||
const icon = useMemo(() => {
|
const icon = useMemo(() => {
|
||||||
const type = view.type;
|
const type = view?.type;
|
||||||
if (type === VIEW_TYPE.GALLERY) return `${mediaUrl}favicons/gallery.png`;
|
if (type === VIEW_TYPE.GALLERY) return `${mediaUrl}favicons/gallery.png`;
|
||||||
if (type === VIEW_TYPE.TABLE) return `${mediaUrl}favicons/table.png`;
|
if (type === VIEW_TYPE.TABLE) return `${mediaUrl}favicons/table.png`;
|
||||||
if (type === VIEW_TYPE.FACE_RECOGNITION) return `${mediaUrl}favicons/face-recognition-view.png`;
|
if (type === VIEW_TYPE.FACE_RECOGNITION) return `${mediaUrl}favicons/face-recognition-view.png`;
|
||||||
@@ -21,6 +21,8 @@ const ViewDetails = ({ viewId, onClose }) => {
|
|||||||
return `${mediaUrl}img/file/256/file.png`;
|
return `${mediaUrl}img/file/256/file.png`;
|
||||||
}, [view]);
|
}, [view]);
|
||||||
|
|
||||||
|
if (!view || !VIEW_TYPES_SUPPORT_SHOW_DETAIL.includes(view.type)) return null;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Detail className="sf-metadata-view-detail">
|
<Detail className="sf-metadata-view-detail">
|
||||||
<Header title={view.name} icon={icon} iconSize={28} onClose={onClose} />
|
<Header title={view.name} icon={icon} iconSize={28} onClose={onClose} />
|
||||||
|
@@ -4,7 +4,7 @@ import { GalleryGroupBySetter, GallerySliderSetter, SortSetter } from '../../dat
|
|||||||
import { gettext } from '../../../../utils/constants';
|
import { gettext } from '../../../../utils/constants';
|
||||||
import { EVENT_BUS_TYPE, FACE_RECOGNITION_VIEW_ID, VIEW_TYPE } from '../../../constants';
|
import { EVENT_BUS_TYPE, FACE_RECOGNITION_VIEW_ID, VIEW_TYPE } from '../../../constants';
|
||||||
|
|
||||||
const FaceRecognitionViewToolbar = ({ readOnly, isCustomPermission, showDetail }) => {
|
const FaceRecognitionViewToolbar = ({ readOnly, isCustomPermission, onToggleDetail }) => {
|
||||||
const [isShow, setShow] = useState(false);
|
const [isShow, setShow] = useState(false);
|
||||||
const [view, setView] = useState({});
|
const [view, setView] = useState({});
|
||||||
|
|
||||||
@@ -35,11 +35,11 @@ const FaceRecognitionViewToolbar = ({ readOnly, isCustomPermission, showDetail }
|
|||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
if (!isShow) return null;
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="sf-metadata-tool-left-operations">
|
<div className="sf-metadata-tool-left-operations">
|
||||||
|
{isShow && (
|
||||||
|
<>
|
||||||
<GalleryGroupBySetter view={{ _id: FACE_RECOGNITION_VIEW_ID }} />
|
<GalleryGroupBySetter view={{ _id: FACE_RECOGNITION_VIEW_ID }} />
|
||||||
<GallerySliderSetter view={{ _id: FACE_RECOGNITION_VIEW_ID }} />
|
<GallerySliderSetter view={{ _id: FACE_RECOGNITION_VIEW_ID }} />
|
||||||
<SortSetter
|
<SortSetter
|
||||||
@@ -52,8 +52,10 @@ const FaceRecognitionViewToolbar = ({ readOnly, isCustomPermission, showDetail }
|
|||||||
columns={viewColumns}
|
columns={viewColumns}
|
||||||
modifySorts={modifySorts}
|
modifySorts={modifySorts}
|
||||||
/>
|
/>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
{!isCustomPermission && (
|
{!isCustomPermission && (
|
||||||
<div className="cur-view-path-btn ml-2" onClick={showDetail}>
|
<div className="cur-view-path-btn ml-2" onClick={onToggleDetail}>
|
||||||
<span className="sf3-font sf3-font-info" aria-label={gettext('Properties')} title={gettext('Properties')}></span>
|
<span className="sf3-font sf3-font-info" aria-label={gettext('Properties')} title={gettext('Properties')}></span>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
@@ -66,7 +68,7 @@ const FaceRecognitionViewToolbar = ({ readOnly, isCustomPermission, showDetail }
|
|||||||
FaceRecognitionViewToolbar.propTypes = {
|
FaceRecognitionViewToolbar.propTypes = {
|
||||||
isCustomPermission: PropTypes.bool,
|
isCustomPermission: PropTypes.bool,
|
||||||
readOnly: PropTypes.bool,
|
readOnly: PropTypes.bool,
|
||||||
showDetail: PropTypes.func,
|
onToggleDetail: PropTypes.func,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default FaceRecognitionViewToolbar;
|
export default FaceRecognitionViewToolbar;
|
||||||
|
@@ -6,7 +6,7 @@ import { gettext } from '../../../../utils/constants';
|
|||||||
|
|
||||||
const GalleryViewToolbar = ({
|
const GalleryViewToolbar = ({
|
||||||
readOnly, isCustomPermission, view, collaborators,
|
readOnly, isCustomPermission, view, collaborators,
|
||||||
modifyFilters, modifySorts, showDetail,
|
modifyFilters, modifySorts, onToggleDetail,
|
||||||
}) => {
|
}) => {
|
||||||
const viewType = useMemo(() => view.type, [view]);
|
const viewType = useMemo(() => view.type, [view]);
|
||||||
const viewColumns = useMemo(() => {
|
const viewColumns = useMemo(() => {
|
||||||
@@ -48,7 +48,7 @@ const GalleryViewToolbar = ({
|
|||||||
modifySorts={modifySorts}
|
modifySorts={modifySorts}
|
||||||
/>
|
/>
|
||||||
{!isCustomPermission && (
|
{!isCustomPermission && (
|
||||||
<div className="cur-view-path-btn ml-2" onClick={showDetail}>
|
<div className="cur-view-path-btn ml-2" onClick={onToggleDetail}>
|
||||||
<span className="sf3-font sf3-font-info" aria-label={gettext('Properties')} title={gettext('Properties')}></span>
|
<span className="sf3-font sf3-font-info" aria-label={gettext('Properties')} title={gettext('Properties')}></span>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
@@ -65,7 +65,7 @@ GalleryViewToolbar.propTypes = {
|
|||||||
collaborators: PropTypes.array,
|
collaborators: PropTypes.array,
|
||||||
modifyFilters: PropTypes.func,
|
modifyFilters: PropTypes.func,
|
||||||
modifySorts: PropTypes.func,
|
modifySorts: PropTypes.func,
|
||||||
showDetail: PropTypes.func,
|
onToggleDetail: PropTypes.func,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default GalleryViewToolbar;
|
export default GalleryViewToolbar;
|
||||||
|
@@ -9,7 +9,7 @@ import MapViewToolBar from './map-view-toolbar';
|
|||||||
|
|
||||||
import './index.css';
|
import './index.css';
|
||||||
|
|
||||||
const ViewToolBar = ({ viewId, isCustomPermission, showDetail, closeDetail }) => {
|
const ViewToolBar = ({ viewId, isCustomPermission, onToggleDetail }) => {
|
||||||
const [view, setView] = useState(null);
|
const [view, setView] = useState(null);
|
||||||
const [collaborators, setCollaborators] = useState([]);
|
const [collaborators, setCollaborators] = useState([]);
|
||||||
|
|
||||||
@@ -89,14 +89,14 @@ const ViewToolBar = ({ viewId, isCustomPermission, showDetail, closeDetail }) =>
|
|||||||
collaborators={collaborators}
|
collaborators={collaborators}
|
||||||
modifyFilters={modifyFilters}
|
modifyFilters={modifyFilters}
|
||||||
modifySorts={modifySorts}
|
modifySorts={modifySorts}
|
||||||
showDetail={showDetail}
|
onToggleDetail={onToggleDetail}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{viewType === VIEW_TYPE.FACE_RECOGNITION && (
|
{viewType === VIEW_TYPE.FACE_RECOGNITION && (
|
||||||
<FaceRecognitionViewToolbar
|
<FaceRecognitionViewToolbar
|
||||||
isCustomPermission={isCustomPermission}
|
isCustomPermission={isCustomPermission}
|
||||||
view={view}
|
view={view}
|
||||||
showDetail={showDetail}
|
onToggleDetail={onToggleDetail}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{viewType === VIEW_TYPE.KANBAN && (
|
{viewType === VIEW_TYPE.KANBAN && (
|
||||||
@@ -107,8 +107,7 @@ const ViewToolBar = ({ viewId, isCustomPermission, showDetail, closeDetail }) =>
|
|||||||
collaborators={collaborators}
|
collaborators={collaborators}
|
||||||
modifyFilters={modifyFilters}
|
modifyFilters={modifyFilters}
|
||||||
modifySorts={modifySorts}
|
modifySorts={modifySorts}
|
||||||
showDetail={showDetail}
|
onToggleDetail={onToggleDetail}
|
||||||
closeDetail={closeDetail}
|
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{viewType === VIEW_TYPE.MAP && (
|
{viewType === VIEW_TYPE.MAP && (
|
||||||
@@ -126,8 +125,7 @@ const ViewToolBar = ({ viewId, isCustomPermission, showDetail, closeDetail }) =>
|
|||||||
ViewToolBar.propTypes = {
|
ViewToolBar.propTypes = {
|
||||||
viewId: PropTypes.string,
|
viewId: PropTypes.string,
|
||||||
isCustomPermission: PropTypes.bool,
|
isCustomPermission: PropTypes.bool,
|
||||||
showDetail: PropTypes.func,
|
onToggleDetail: PropTypes.func,
|
||||||
closeDetail: PropTypes.func,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export default ViewToolBar;
|
export default ViewToolBar;
|
||||||
|
@@ -12,8 +12,7 @@ const KanbanViewToolBar = ({
|
|||||||
collaborators,
|
collaborators,
|
||||||
modifyFilters,
|
modifyFilters,
|
||||||
modifySorts,
|
modifySorts,
|
||||||
showDetail,
|
onToggleDetail,
|
||||||
closeDetail,
|
|
||||||
}) => {
|
}) => {
|
||||||
const viewType = useMemo(() => view.type, [view]);
|
const viewType = useMemo(() => view.type, [view]);
|
||||||
const viewColumns = useMemo(() => {
|
const viewColumns = useMemo(() => {
|
||||||
@@ -26,14 +25,14 @@ const KanbanViewToolBar = ({
|
|||||||
}, [viewColumns]);
|
}, [viewColumns]);
|
||||||
|
|
||||||
const onToggleKanbanSetting = () => {
|
const onToggleKanbanSetting = () => {
|
||||||
closeDetail();
|
onToggleDetail();
|
||||||
window.sfMetadataContext.eventBus.dispatch(EVENT_BUS_TYPE.TOGGLE_KANBAN_SETTINGS);
|
window.sfMetadataContext.eventBus.dispatch(EVENT_BUS_TYPE.TOGGLE_KANBAN_SETTINGS);
|
||||||
};
|
};
|
||||||
|
|
||||||
const toggleDetails = useCallback(() => {
|
const toggleDetails = useCallback(() => {
|
||||||
window.sfMetadataContext.eventBus.dispatch(EVENT_BUS_TYPE.CLOSE_KANBAN_SETTINGS);
|
window.sfMetadataContext.eventBus.dispatch(EVENT_BUS_TYPE.CLOSE_KANBAN_SETTINGS);
|
||||||
showDetail();
|
onToggleDetail();
|
||||||
}, [showDetail]);
|
}, [onToggleDetail]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@@ -88,7 +87,8 @@ KanbanViewToolBar.propTypes = {
|
|||||||
view: PropTypes.object,
|
view: PropTypes.object,
|
||||||
collaborators: PropTypes.array,
|
collaborators: PropTypes.array,
|
||||||
modifyFilters: PropTypes.func,
|
modifyFilters: PropTypes.func,
|
||||||
modifySorts: PropTypes.func
|
modifySorts: PropTypes.func,
|
||||||
|
onToggleDetail: PropTypes.func,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default KanbanViewToolBar;
|
export default KanbanViewToolBar;
|
||||||
|
@@ -123,3 +123,5 @@ export const VIEW_DEFAULT_SETTINGS = {
|
|||||||
[KANBAN_SETTINGS_KEYS.COLUMNS]: [],
|
[KANBAN_SETTINGS_KEYS.COLUMNS]: [],
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const VIEW_TYPES_SUPPORT_SHOW_DETAIL = [VIEW_TYPE.GALLERY, VIEW_TYPE.KANBAN, VIEW_TYPE.FACE_RECOGNITION];
|
||||||
|
@@ -340,7 +340,6 @@ export const MetadataViewProvider = ({
|
|||||||
store: storeRef.current,
|
store: storeRef.current,
|
||||||
isDirentDetailShow: params.isDirentDetailShow,
|
isDirentDetailShow: params.isDirentDetailShow,
|
||||||
updateCurrentDirent: params.updateCurrentDirent,
|
updateCurrentDirent: params.updateCurrentDirent,
|
||||||
closeDirentDetail: params.closeDirentDetail,
|
|
||||||
showDirentDetail: params.showDirentDetail,
|
showDirentDetail: params.showDirentDetail,
|
||||||
deleteFilesCallback: deleteFilesCallback,
|
deleteFilesCallback: deleteFilesCallback,
|
||||||
renameFileCallback: renameFileCallback,
|
renameFileCallback: renameFileCallback,
|
||||||
|
@@ -9,7 +9,7 @@ const FaceRecognition = () => {
|
|||||||
const [showPeopleFaces, setShowPeopleFaces] = useState(false);
|
const [showPeopleFaces, setShowPeopleFaces] = useState(false);
|
||||||
const peopleRef = useRef(null);
|
const peopleRef = useRef(null);
|
||||||
|
|
||||||
const { metadata, store } = useMetadataView();
|
const { metadata, store, updateCurrentDirent } = useMetadataView();
|
||||||
|
|
||||||
const peoples = useMemo(() => {
|
const peoples = useMemo(() => {
|
||||||
if (!Array.isArray(metadata.rows) || metadata.rows.length === 0) return [];
|
if (!Array.isArray(metadata.rows) || metadata.rows.length === 0) return [];
|
||||||
@@ -21,7 +21,6 @@ const FaceRecognition = () => {
|
|||||||
}, [store]);
|
}, [store]);
|
||||||
|
|
||||||
const onRemovePeoplePhotos = useCallback((peopleId, peoplePhotos, { success_callback }) => {
|
const onRemovePeoplePhotos = useCallback((peopleId, peoplePhotos, { success_callback }) => {
|
||||||
//
|
|
||||||
store.removePeoplePhotos(peopleId, peoplePhotos, { success_callback });
|
store.removePeoplePhotos(peopleId, peoplePhotos, { success_callback });
|
||||||
}, [store]);
|
}, [store]);
|
||||||
|
|
||||||
@@ -33,7 +32,8 @@ const FaceRecognition = () => {
|
|||||||
const closePeople = useCallback(() => {
|
const closePeople = useCallback(() => {
|
||||||
peopleRef.current = null;
|
peopleRef.current = null;
|
||||||
setShowPeopleFaces(false);
|
setShowPeopleFaces(false);
|
||||||
}, []);
|
updateCurrentDirent();
|
||||||
|
}, [updateCurrentDirent]);
|
||||||
|
|
||||||
const onRename = useCallback((id, newName, oldName) => {
|
const onRename = useCallback((id, newName, oldName) => {
|
||||||
store.renamePeopleName(id, newName, oldName);
|
store.renamePeopleName(id, newName, oldName);
|
||||||
|
@@ -17,7 +17,7 @@ const Peoples = ({ peoples, onOpenPeople, onRename }) => {
|
|||||||
|
|
||||||
const containerRef = useRef(null);
|
const containerRef = useRef(null);
|
||||||
|
|
||||||
const { metadata, store, closeDirentDetail } = useMetadataView();
|
const { metadata, store } = useMetadataView();
|
||||||
|
|
||||||
const loadMore = useCallback(async () => {
|
const loadMore = useCallback(async () => {
|
||||||
if (isLoadingMore) return;
|
if (isLoadingMore) return;
|
||||||
@@ -63,12 +63,6 @@ const Peoples = ({ peoples, onOpenPeople, onRename }) => {
|
|||||||
return () => {};
|
return () => {};
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
closeDirentDetail();
|
|
||||||
return () => {};
|
|
||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
if (!Array.isArray(peoples) || peoples.length === 0) return (<EmptyTip text={gettext('Identifying portraits...')} />);
|
if (!Array.isArray(peoples) || peoples.length === 0) return (<EmptyTip text={gettext('Identifying portraits...')} />);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@@ -158,7 +158,7 @@ const PeoplePhotos = ({ view, people, onClose, onDeletePeoplePhotos, onRemovePeo
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
window.sfMetadataContext.eventBus.dispatch(EVENT_BUS_TYPE.TOGGLE_VIEW_TOOLBAR, true);
|
window.sfMetadataContext.eventBus.dispatch(EVENT_BUS_TYPE.TOGGLE_VIEW_TOOLBAR, true);
|
||||||
return () => {
|
return () => {
|
||||||
window.sfMetadataContext.eventBus.dispatch(EVENT_BUS_TYPE.TOGGLE_VIEW_TOOLBAR, false);
|
window?.sfMetadataContext?.eventBus?.dispatch(EVENT_BUS_TYPE.TOGGLE_VIEW_TOOLBAR, false);
|
||||||
};
|
};
|
||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
}, []);
|
}, []);
|
||||||
|
@@ -21,17 +21,16 @@ import FileUploader from '../../components/file-uploader/file-uploader';
|
|||||||
import CopyMoveDirentProgressDialog from '../../components/dialog/copy-move-dirent-progress-dialog';
|
import CopyMoveDirentProgressDialog from '../../components/dialog/copy-move-dirent-progress-dialog';
|
||||||
import DeleteFolderDialog from '../../components/dialog/delete-folder-dialog';
|
import DeleteFolderDialog from '../../components/dialog/delete-folder-dialog';
|
||||||
import { EVENT_BUS_TYPE } from '../../components/common/event-bus-type';
|
import { EVENT_BUS_TYPE } from '../../components/common/event-bus-type';
|
||||||
import { PRIVATE_FILE_TYPE } from '../../constants';
|
import { PRIVATE_FILE_TYPE, DIRENT_DETAIL_SHOW_KEY } from '../../constants';
|
||||||
import { MetadataStatusProvider } from '../../hooks';
|
import { MetadataStatusProvider } from '../../hooks';
|
||||||
import { MetadataProvider, CollaboratorsProvider } from '../../metadata/hooks';
|
import { MetadataProvider, CollaboratorsProvider } from '../../metadata/hooks';
|
||||||
import { TagsProvider } from '../../tag/hooks';
|
import { TagsProvider } from '../../tag/hooks';
|
||||||
import { LIST_MODE, METADATA_MODE, DIRENT_DETAIL_MODE, TAGS_MODE } from '../../components/dir-view-mode/constants';
|
import { LIST_MODE, METADATA_MODE, TAGS_MODE } from '../../components/dir-view-mode/constants';
|
||||||
import CurDirPath from '../../components/cur-dir-path';
|
import CurDirPath from '../../components/cur-dir-path';
|
||||||
import DirTool from '../../components/cur-dir-path/dir-tool';
|
import DirTool from '../../components/cur-dir-path/dir-tool';
|
||||||
import Detail from '../../components/dirent-detail';
|
import Detail from '../../components/dirent-detail';
|
||||||
import DirColumnView from '../../components/dir-view-mode/dir-column-view';
|
import DirColumnView from '../../components/dir-view-mode/dir-column-view';
|
||||||
import SelectedDirentsToolbar from '../../components/toolbar/selected-dirents-toolbar';
|
import SelectedDirentsToolbar from '../../components/toolbar/selected-dirents-toolbar';
|
||||||
import { VIEW_TYPE } from '../../metadata/constants';
|
|
||||||
|
|
||||||
import '../../css/lib-content-view.css';
|
import '../../css/lib-content-view.css';
|
||||||
|
|
||||||
@@ -53,8 +52,12 @@ class LibContentView extends React.Component {
|
|||||||
let isTreePanelShown = true;
|
let isTreePanelShown = true;
|
||||||
const storedTreePanelState = localStorage.getItem('sf_dir_view_tree_panel_open');
|
const storedTreePanelState = localStorage.getItem('sf_dir_view_tree_panel_open');
|
||||||
if (storedTreePanelState != undefined) {
|
if (storedTreePanelState != undefined) {
|
||||||
isTreePanelShown = storedTreePanelState == 'true';
|
isTreePanelShown = storedTreePanelState === 'true';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const storedDirentDetailShowState = localStorage.getItem(DIRENT_DETAIL_SHOW_KEY);
|
||||||
|
const isDirentDetailShow = storedDirentDetailShowState === 'true';
|
||||||
|
|
||||||
this.state = {
|
this.state = {
|
||||||
currentMode: cookie.load('seafile_view_mode') || LIST_MODE,
|
currentMode: cookie.load('seafile_view_mode') || LIST_MODE,
|
||||||
isTreePanelShown: isTreePanelShown, // display the 'dirent tree' side panel
|
isTreePanelShown: isTreePanelShown, // display the 'dirent tree' side panel
|
||||||
@@ -88,7 +91,7 @@ class LibContentView extends React.Component {
|
|||||||
isAllDirentSelected: false,
|
isAllDirentSelected: false,
|
||||||
dirID: '', // for update dir list
|
dirID: '', // for update dir list
|
||||||
errorMsg: '',
|
errorMsg: '',
|
||||||
isDirentDetailShow: false,
|
isDirentDetailShow,
|
||||||
itemsShowLength: 100,
|
itemsShowLength: 100,
|
||||||
isSessionExpired: false,
|
isSessionExpired: false,
|
||||||
isCopyMoveProgressDialogShow: false,
|
isCopyMoveProgressDialogShow: false,
|
||||||
@@ -133,15 +136,22 @@ class LibContentView extends React.Component {
|
|||||||
};
|
};
|
||||||
|
|
||||||
showDirentDetail = () => {
|
showDirentDetail = () => {
|
||||||
this.setState({ isDirentDetailShow: true });
|
this.setState({ isDirentDetailShow: true }, () => {
|
||||||
|
localStorage.setItem(DIRENT_DETAIL_SHOW_KEY, true);
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
toggleDirentDetail = () => {
|
toggleDirentDetail = () => {
|
||||||
this.setState({ isDirentDetailShow: !this.state.isDirentDetailShow });
|
const newState = !this.state.isDirentDetailShow;
|
||||||
|
this.setState({ isDirentDetailShow: newState }, () => {
|
||||||
|
localStorage.setItem(DIRENT_DETAIL_SHOW_KEY, newState);
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
closeDirentDetail = () => {
|
closeDirentDetail = () => {
|
||||||
this.setState({ isDirentDetailShow: false });
|
this.setState({ isDirentDetailShow: false }, () => {
|
||||||
|
localStorage.setItem(DIRENT_DETAIL_SHOW_KEY, false);
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
@@ -501,14 +511,13 @@ class LibContentView extends React.Component {
|
|||||||
window.history.pushState({ url: url, path: filePath }, filePath, url);
|
window.history.pushState({ url: url, path: filePath }, filePath, url);
|
||||||
};
|
};
|
||||||
|
|
||||||
showFileMetadata = (filePath, viewId, viewType) => {
|
showFileMetadata = (filePath, viewId) => {
|
||||||
const repoID = this.props.repoID;
|
const repoID = this.props.repoID;
|
||||||
const repoInfo = this.state.currentRepoInfo;
|
const repoInfo = this.state.currentRepoInfo;
|
||||||
this.setState({
|
this.setState({
|
||||||
currentMode: METADATA_MODE,
|
currentMode: METADATA_MODE,
|
||||||
path: filePath,
|
path: filePath,
|
||||||
viewId: viewId,
|
viewId: viewId,
|
||||||
isDirentDetailShow: viewType === VIEW_TYPE.GALLERY ? this.state.isDirentDetailShow : false,
|
|
||||||
});
|
});
|
||||||
const url = `${siteRoot}library/${repoID}/${encodeURIComponent(repoInfo.repo_name)}/?view=${encodeURIComponent(viewId)}`;
|
const url = `${siteRoot}library/${repoID}/${encodeURIComponent(repoInfo.repo_name)}/?view=${encodeURIComponent(viewId)}`;
|
||||||
window.history.pushState({ url: url, path: '' }, '', url);
|
window.history.pushState({ url: url, path: '' }, '', url);
|
||||||
@@ -532,7 +541,6 @@ class LibContentView extends React.Component {
|
|||||||
currentMode: TAGS_MODE,
|
currentMode: TAGS_MODE,
|
||||||
path: filePath,
|
path: filePath,
|
||||||
tagId: tagId,
|
tagId: tagId,
|
||||||
isDirentDetailShow: false
|
|
||||||
});
|
});
|
||||||
const url = `${siteRoot}library/${repoID}/${encodeURIComponent(repoInfo.repo_name)}/?tag=${encodeURIComponent(tagId)}`;
|
const url = `${siteRoot}library/${repoID}/${encodeURIComponent(repoInfo.repo_name)}/?tag=${encodeURIComponent(tagId)}`;
|
||||||
window.history.pushState({ url: url, path: '' }, '', url);
|
window.history.pushState({ url: url, path: '' }, '', url);
|
||||||
@@ -988,10 +996,7 @@ class LibContentView extends React.Component {
|
|||||||
if (mode === this.state.currentMode) {
|
if (mode === this.state.currentMode) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (mode === DIRENT_DETAIL_MODE) {
|
|
||||||
this.toggleDirentDetail();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
cookie.save('seafile_view_mode', mode);
|
cookie.save('seafile_view_mode', mode);
|
||||||
let path = this.state.path;
|
let path = this.state.path;
|
||||||
if (this.state.isTreePanelShown && this.state.isViewFile) {
|
if (this.state.isTreePanelShown && this.state.isViewFile) {
|
||||||
@@ -1869,7 +1874,7 @@ class LibContentView extends React.Component {
|
|||||||
} else {
|
} else {
|
||||||
if (Utils.isFileMetadata(node?.object?.type)) {
|
if (Utils.isFileMetadata(node?.object?.type)) {
|
||||||
if (node.path !== this.state.path) {
|
if (node.path !== this.state.path) {
|
||||||
this.showFileMetadata(node.path, node.view_id || '0000', node.view_type || VIEW_TYPE.TABLE);
|
this.showFileMetadata(node.path, node.view_id || '0000');
|
||||||
}
|
}
|
||||||
} else if (Utils.isTags(node?.object?.type)) {
|
} else if (Utils.isTags(node?.object?.type)) {
|
||||||
if (node.path !== this.state.path) {
|
if (node.path !== this.state.path) {
|
||||||
@@ -2001,6 +2006,7 @@ class LibContentView extends React.Component {
|
|||||||
isDirentSelected: false,
|
isDirentSelected: false,
|
||||||
isAllDirentSelected: false,
|
isAllDirentSelected: false,
|
||||||
currentMode: nextModel,
|
currentMode: nextModel,
|
||||||
|
currentDirent: null,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -2248,7 +2254,6 @@ class LibContentView extends React.Component {
|
|||||||
isGroupOwnedRepo={this.state.isGroupOwnedRepo}
|
isGroupOwnedRepo={this.state.isGroupOwnedRepo}
|
||||||
showDirentDetail={this.showDirentDetail}
|
showDirentDetail={this.showDirentDetail}
|
||||||
currentMode={this.state.currentMode}
|
currentMode={this.state.currentMode}
|
||||||
switchViewMode={this.switchViewMode}
|
|
||||||
onItemConvert={this.onConvertItem}
|
onItemConvert={this.onConvertItem}
|
||||||
onAddFolder={this.onAddFolder}
|
onAddFolder={this.onAddFolder}
|
||||||
/>
|
/>
|
||||||
@@ -2304,7 +2309,7 @@ class LibContentView extends React.Component {
|
|||||||
sortItems={this.sortItems}
|
sortItems={this.sortItems}
|
||||||
viewId={this.state.viewId}
|
viewId={this.state.viewId}
|
||||||
viewType={this.props.viewType}
|
viewType={this.props.viewType}
|
||||||
onCloseDetail={this.closeDirentDetail}
|
onToggleDetail={this.toggleDirentDetail}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
@@ -2378,12 +2383,11 @@ class LibContentView extends React.Component {
|
|||||||
onItemsScroll={this.onItemsScroll}
|
onItemsScroll={this.onItemsScroll}
|
||||||
eventBus={this.props.eventBus}
|
eventBus={this.props.eventBus}
|
||||||
updateCurrentDirent={this.updateCurrentDirent}
|
updateCurrentDirent={this.updateCurrentDirent}
|
||||||
closeDirentDetail={this.closeDirentDetail}
|
|
||||||
/>
|
/>
|
||||||
:
|
:
|
||||||
<div className="message err-tip">{gettext('Folder does not exist.')}</div>
|
<div className="message err-tip">{gettext('Folder does not exist.')}</div>
|
||||||
}
|
}
|
||||||
{this.state.isDirentDetailShow && (
|
{!isCustomPermission && this.state.isDirentDetailShow && (
|
||||||
<Detail
|
<Detail
|
||||||
path={this.state.path}
|
path={this.state.path}
|
||||||
repoID={this.props.repoID}
|
repoID={this.props.repoID}
|
||||||
@@ -2393,6 +2397,7 @@ class LibContentView extends React.Component {
|
|||||||
fileTags={this.state.isViewFile ? this.state.fileTags : []}
|
fileTags={this.state.isViewFile ? this.state.fileTags : []}
|
||||||
onFileTagChanged={this.onFileTagChanged}
|
onFileTagChanged={this.onFileTagChanged}
|
||||||
onClose={this.closeDirentDetail}
|
onClose={this.closeDirentDetail}
|
||||||
|
currentMode={this.state.currentMode}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
@@ -49,7 +49,6 @@ export const TagViewProvider = ({ repoID, tagID, children, ...params }) => {
|
|||||||
deleteFilesCallback: params.deleteFilesCallback,
|
deleteFilesCallback: params.deleteFilesCallback,
|
||||||
renameFileCallback: params.renameFileCallback,
|
renameFileCallback: params.renameFileCallback,
|
||||||
updateCurrentDirent: params.updateCurrentDirent,
|
updateCurrentDirent: params.updateCurrentDirent,
|
||||||
closeDirentDetail: params.closeDirentDetail,
|
|
||||||
}}>
|
}}>
|
||||||
{children}
|
{children}
|
||||||
</TagViewContext.Provider>
|
</TagViewContext.Provider>
|
||||||
|
@@ -248,7 +248,6 @@ export const TagsProvider = ({ repoID, currentPath, selectTagsView, children, ..
|
|||||||
deleteFilesCallback: params.deleteFilesCallback,
|
deleteFilesCallback: params.deleteFilesCallback,
|
||||||
renameFileCallback: params.renameFileCallback,
|
renameFileCallback: params.renameFileCallback,
|
||||||
updateCurrentDirent: params.updateCurrentDirent,
|
updateCurrentDirent: params.updateCurrentDirent,
|
||||||
closeDirentDetail: params.closeDirentDetail,
|
|
||||||
addTag,
|
addTag,
|
||||||
addTags,
|
addTags,
|
||||||
modifyTags,
|
modifyTags,
|
||||||
|
Reference in New Issue
Block a user