1
0
mirror of https://github.com/haiwen/seahub.git synced 2025-08-31 14:42:10 +00:00

add url for view, keep in the same view after refresh (#6510)

* parent e2bb71e8c9
author Aries <urchinzhou@gmail.com> 1723011852 +0800
committer Aries <urchinzhou@gmail.com> 1723110297 +0800

add url for view, keep in the same view after refresh

* delete useless viewName
This commit is contained in:
Aries
2024-08-09 10:32:28 +08:00
committed by GitHub
parent fdd5e6dbf9
commit 9478d4637d
3 changed files with 112 additions and 68 deletions

View File

@@ -128,7 +128,7 @@ class DirPath extends React.Component {
return ( return (
<Fragment key={index}> <Fragment key={index}>
<span className="path-split">/</span> <span className="path-split">/</span>
<span className="path-item">{gettext('File extended properties')}</span> <span className="path-item">{gettext('Views')}</span>
</Fragment> </Fragment>
); );
} }

View File

@@ -24,9 +24,11 @@ const MetadataTreeView = ({ userPerm, repoID, currentPath, onNodeClick }) => {
useEffect(() => { useEffect(() => {
metadataAPI.listViews(repoID).then(res => { metadataAPI.listViews(repoID).then(res => {
const { navigation, views } = res.data; const { navigation, views } = res.data;
Array.isArray(views) && views.forEach(view => { if (Array.isArray(views)) {
viewsMap.current[view._id] = view; views.forEach(view => {
}); viewsMap.current[view._id] = view;
});
}
setViews(navigation); setViews(navigation);
}).catch(error => { }).catch(error => {
const errorMsg = Utils.getErrorMsg(error); const errorMsg = Utils.getErrorMsg(error);
@@ -53,6 +55,7 @@ const MetadataTreeView = ({ userPerm, repoID, currentPath, onNodeClick }) => {
parentNode: {}, parentNode: {},
key: repoID, key: repoID,
view_id: view._id, view_id: view._id,
view_name: view.name,
}; };
onNodeClick(node); onNodeClick(node);
}, [repoID, onNodeClick]); }, [repoID, onNodeClick]);

View File

@@ -21,6 +21,7 @@ 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';
const propTypes = { const propTypes = {
eventBus: PropTypes.object, eventBus: PropTypes.object,
@@ -144,33 +145,20 @@ class LibContentView extends React.Component {
calculatePara = async (props) => { calculatePara = async (props) => {
const { repoID, eventBus } = props; const { repoID, eventBus } = props;
this.unsubscribeEvent = eventBus.subscribe(EVENT_BUS_TYPE.SEARCH_LIBRARY_CONTENT, this.onSearchedClick); this.unsubscribeEvent = eventBus.subscribe(EVENT_BUS_TYPE.SEARCH_LIBRARY_CONTENT, this.onSearchedClick);
// eg: http://127.0.0.1:8000/library/repo_id/repo_name/**/**/\
let location = window.location.href.split('?')[0]; // '?': to remove the effect of '?notifications=all', which is added to the URL when the 'view all notifications' dialog is open. const urlParams = new URLSearchParams(window.location.search);
location = decodeURIComponent(location); const viewID = urlParams.get('view');
let path = location.slice(location.indexOf(repoID) + repoID.length + 1); // get the string after repoID const viewName = JSON.parse(localStorage.getItem('last_visited_view'))?.viewName;
path = path.slice(path.indexOf('/')); // get current path const path = viewID
// If the path isn't a root path and ends with '/', delete the ending '/' ? `/${PRIVATE_FILE_TYPE.FILE_EXTENDED_PROPERTIES}/${viewName}`
if (path.length > 1 && path[path.length - 1] === '/') { : this.getPathFromLocation(repoID);
path = path.slice(0, path.length - 1);
}
try { try {
const repoRes = await seafileAPI.getRepoInfo(repoID); const repoInfo = await this.fetchRepoInfo(repoID);
const repoInfo = new RepoInfo(repoRes.data); const isGroupOwnedRepo = repoInfo.owner_email.includes('@seafile_group');
const isGroupOwnedRepo = repoInfo.owner_email.indexOf('@seafile_group') > -1;
this.setState({ this.setState({
currentRepoInfo: repoInfo, currentRepoInfo: repoInfo,
});
if (repoInfo.permission.startsWith('custom-')) {
const permissionID = repoInfo.permission.split('-')[1];
const permissionRes = await seafileAPI.getCustomPermission(repoID, permissionID);
window.custom_permission = permissionRes.data.permission;
}
this.isNeedUpdateHistoryState = false;
this.setState({
repoName: repoInfo.repo_name, repoName: repoInfo.repo_name,
libNeedDecrypt: repoInfo.lib_need_decrypt, libNeedDecrypt: repoInfo.lib_need_decrypt,
repoEncrypted: repoInfo.encrypted, repoEncrypted: repoInfo.encrypted,
@@ -178,37 +166,61 @@ class LibContentView extends React.Component {
path: path path: path
}); });
if (repoInfo.permission.startsWith('custom-')) {
await this.setCustomPermission(repoID, repoInfo.permission);
}
this.isNeedUpdateHistoryState = false;
if (!repoInfo.lib_need_decrypt) { if (!repoInfo.lib_need_decrypt) {
this.loadDirData(path); this.loadDirData(path);
} }
} catch (error) { } catch (error) {
if (error.response) { this.handleError(error);
if (error.response.status == 403) { }
this.setState({ };
isDirentListLoading: false,
errorMsg: gettext('Permission denied')
});
let errorMsg = gettext('Permission denied'); getPathFromLocation = (repoID) => {
toaster.danger(errorMsg); let location = window.location.href.split('?')[0];
} else if (error.response.status == 404) { location = decodeURIComponent(location);
this.setState({ let path = location.slice(location.indexOf(repoID) + repoID.length + 1);
isDirentListLoading: false, path = path.slice(path.indexOf('/'));
errorMsg: gettext('Library share permission not found.') if (path.length > 1 && path.endsWith('/')) {
}); path = path.slice(0, -1);
} else { }
this.setState({ return path;
isDirentListLoading: false, };
errorMsg: gettext('Error')
}); fetchRepoInfo = async (repoID) => {
} const repoRes = await seafileAPI.getRepoInfo(repoID);
} else { return new RepoInfo(repoRes.data);
this.setState({ };
isDirentListLoading: false,
errorMsg: gettext('Please check the network.') setCustomPermission = async (repoID, permission) => {
}); const permissionID = permission.split('-')[1];
const permissionRes = await seafileAPI.getCustomPermission(repoID, permissionID);
window.custom_permission = permissionRes.data.permission;
};
handleError = (error) => {
let errorMsg = gettext('Please check the network.');
if (error.response) {
switch (error.response.status) {
case 403:
errorMsg = gettext('Permission denied');
break;
case 404:
errorMsg = gettext('Library share permission not found.');
break;
default:
errorMsg = gettext('Error');
} }
} }
this.setState({
isDirentListLoading: false,
errorMsg: errorMsg
});
toaster.danger(errorMsg);
}; };
componentWillUnmount() { componentWillUnmount() {
@@ -365,7 +377,15 @@ class LibContentView extends React.Component {
this.updateUsedRepoTags(); this.updateUsedRepoTags();
if (Utils.isMarkdownFile(path)) { if (Utils.isMarkdownFile(path)) {
seafileAPI.getFileInfo(this.props.repoID, path).then(() => { this.handleMarkdownFile(path);
} else {
this.handleNonMarkdownFile(path);
}
};
handleMarkdownFile = (path) => {
seafileAPI.getFileInfo(this.props.repoID, path)
.then(() => {
/* /*
if (this.state.currentMode !== 'column') { if (this.state.currentMode !== 'column') {
cookie.save('seafile_view_mode', 'column'); cookie.save('seafile_view_mode', 'column');
@@ -374,27 +394,36 @@ class LibContentView extends React.Component {
*/ */
this.loadSidePanel(path); this.loadSidePanel(path);
this.showFile(path); this.showFile(path);
}).catch(() => { })
if (this.state.isTreePanelShown) { // After an error occurs, follow dir .catch(() => {
if (this.state.isTreePanelShown) {
this.loadSidePanel(path); this.loadSidePanel(path);
this.showDir(path);
} else {
this.showDir(path);
} }
this.showDir(path);
}); });
} else { };
if (this.state.isTreePanelShown) {
this.loadSidePanel(path); handleNonMarkdownFile = (path) => {
this.showDir(path); if (this.state.isTreePanelShown) {
} else { this.loadSidePanel(path);
this.showDir(path);
}
} }
if (path.includes(PRIVATE_FILE_TYPE.FILE_EXTENDED_PROPERTIES)) {
this.handleFileExtendedProperties(path);
} else {
this.showDir(path);
}
};
handleFileExtendedProperties = (path) => {
const lastVisitedView = localStorage.getItem('last_visited_view');
const { viewID, viewName } = lastVisitedView ? JSON.parse(lastVisitedView) : {};
this.showFileMetadata(path, viewID, viewName);
}; };
loadSidePanel = (path) => { loadSidePanel = (path) => {
let repoID = this.props.repoID; let repoID = this.props.repoID;
if (path === '/') { if (path === '/' || path.includes(PRIVATE_FILE_TYPE.FILE_EXTENDED_PROPERTIES)) {
seafileAPI.listDir(repoID, '/').then(res => { seafileAPI.listDir(repoID, '/').then(res => {
const { dirent_list, user_perm } = res.data; const { dirent_list, user_perm } = res.data;
let tree = this.state.treeData; let tree = this.state.treeData;
@@ -492,11 +521,23 @@ 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) => { showFileMetadata = (filePath, viewId, viewName) => {
const repoID = this.props.repoID; const repoID = this.props.repoID;
this.setState({ path: filePath, isViewFile: true, isFileLoading: false, isFileLoadedErr: false, content: '__sf-metadata', metadataViewId: viewId, isDirentDetailShow: false });
const repoInfo = this.state.currentRepoInfo; const repoInfo = this.state.currentRepoInfo;
const url = siteRoot + 'library/' + repoID + '/' + encodeURIComponent(repoInfo.repo_name);
this.setState({
path: filePath,
isViewFile: true,
isFileLoading: false,
isFileLoadedErr: false,
content: '__sf-metadata',
metadataViewId: viewId,
isDirentDetailShow: false
});
const url = `${siteRoot}library/${repoID}/${encodeURIComponent(repoInfo.repo_name)}?view=${encodeURIComponent(viewId)}`;
localStorage.setItem('last_visited_view', JSON.stringify({ viewID: viewId, viewName: viewName }));
window.history.pushState({ url: url, path: '' }, '', url); window.history.pushState({ url: url, path: '' }, '', url);
}; };
@@ -1784,7 +1825,7 @@ class LibContentView extends React.Component {
} }
} else if (Utils.isFileMetadata(node?.object?.type)) { } else 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'); this.showFileMetadata(node.path, node.view_id || '0000', node.view_name);
} }
} else { } else {
let url = siteRoot + 'lib/' + repoID + '/file' + Utils.encodePath(node.path); let url = siteRoot + 'lib/' + repoID + '/file' + Utils.encodePath(node.path);