mirror of
https://github.com/haiwen/seahub.git
synced 2025-09-06 17:33:18 +00:00
Md copy view (#6598)
* duplicate md view * optimize code * optimize code * Update metadata_manage.py * Update metadata_manage.py --------- Co-authored-by: 孙永强 <11704063+s-yongqiang@user.noreply.gitee.com> Co-authored-by: r350178982 <32759763+r350178982@users.noreply.github.com>
This commit is contained in:
@@ -118,6 +118,12 @@ class MetadataManagerAPI {
|
||||
return this._sendPostRequest(url, params, { headers: { 'Content-type': 'application/json' } });
|
||||
};
|
||||
|
||||
duplicateView = (repoID, viewId) => {
|
||||
const url = this.server + '/api/v2.1/repos/' + repoID + '/metadata/duplicate-view/';
|
||||
const params = { view_id: viewId };
|
||||
return this._sendPostRequest(url, params, { headers: { 'Content-type': 'application/json' } });
|
||||
};
|
||||
|
||||
modifyView = (repoID, viewId, viewData) => {
|
||||
const url = this.server + '/api/v2.1/repos/' + repoID + '/metadata/views/';
|
||||
const params = {
|
||||
|
@@ -120,6 +120,20 @@ export const MetadataProvider = ({ repoID, hideMetadataView, selectMetadataView,
|
||||
});
|
||||
}, [navigation, repoID, viewsMap, selectView]);
|
||||
|
||||
const duplicateView = useCallback((viewId) => {
|
||||
metadataAPI.duplicateView(repoID, viewId).then(res => {
|
||||
const view = res.data.view;
|
||||
let newNavigation = navigation.slice(0);
|
||||
newNavigation.push({ _id: view._id, type: 'view' });
|
||||
viewsMap.current[view._id] = view;
|
||||
setNavigation(newNavigation);
|
||||
selectView(view);
|
||||
}).catch(error => {
|
||||
const errorMsg = Utils.getErrorMsg(error);
|
||||
toaster.danger(errorMsg);
|
||||
});
|
||||
}, [navigation, repoID, viewsMap, selectView]);
|
||||
|
||||
const deleteView = useCallback((viewId, isSelected) => {
|
||||
metadataAPI.deleteView(repoID, viewId).then(res => {
|
||||
const newNavigation = navigation.filter(item => item._id !== viewId);
|
||||
@@ -170,6 +184,7 @@ export const MetadataProvider = ({ repoID, hideMetadataView, selectMetadataView,
|
||||
viewsMap: viewsMap.current,
|
||||
selectView,
|
||||
addView,
|
||||
duplicateView,
|
||||
deleteView,
|
||||
updateView,
|
||||
moveView,
|
||||
|
@@ -23,6 +23,7 @@ const MetadataTreeView = ({ userPerm, currentPath }) => {
|
||||
viewsMap,
|
||||
selectView,
|
||||
addView,
|
||||
duplicateView,
|
||||
deleteView,
|
||||
updateView,
|
||||
moveView
|
||||
@@ -122,6 +123,7 @@ const MetadataTreeView = ({ userPerm, currentPath }) => {
|
||||
view={view}
|
||||
onClick={(view) => selectView(view, isSelected)}
|
||||
onDelete={() => deleteView(view._id, isSelected)}
|
||||
onCopy={() => duplicateView(view._id)}
|
||||
onUpdate={(update, successCallback, failCallback) => onUpdateView(view._id, update, successCallback, failCallback)}
|
||||
onMove={moveView}
|
||||
/>);
|
||||
|
@@ -16,6 +16,7 @@ const ViewItem = ({
|
||||
view,
|
||||
onClick,
|
||||
onDelete,
|
||||
onCopy,
|
||||
onUpdate,
|
||||
onMove,
|
||||
}) => {
|
||||
@@ -38,6 +39,7 @@ const ViewItem = ({
|
||||
if (!canUpdate) return [];
|
||||
let value = [
|
||||
{ key: 'rename', value: gettext('Rename') },
|
||||
{ key: 'duplicate', value: gettext('Duplicate') }
|
||||
];
|
||||
if (canDelete) {
|
||||
value.push({ key: 'delete', value: gettext('Delete') });
|
||||
@@ -75,11 +77,16 @@ const ViewItem = ({
|
||||
return;
|
||||
}
|
||||
|
||||
if (operationKey === 'duplicate') {
|
||||
onCopy();
|
||||
return;
|
||||
}
|
||||
|
||||
if (operationKey === 'delete') {
|
||||
onDelete();
|
||||
return;
|
||||
}
|
||||
}, [onDelete]);
|
||||
}, [onDelete, onCopy]);
|
||||
|
||||
const closeRenamePopover = useCallback((event) => {
|
||||
event.stopPropagation();
|
||||
|
@@ -697,6 +697,52 @@ class MetadataViews(APIView):
|
||||
return Response({'success': True})
|
||||
|
||||
|
||||
class MetadataViewsDuplicateView(APIView):
|
||||
authentication_classes = (TokenAuthentication, SessionAuthentication)
|
||||
permission_classes = (IsAuthenticated,)
|
||||
throttle_classes = (UserRateThrottle,)
|
||||
|
||||
def post(self, request, repo_id):
|
||||
view_id = request.data.get('view_id')
|
||||
if not view_id:
|
||||
error_msg = 'view_id invalid'
|
||||
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
|
||||
|
||||
record = RepoMetadata.objects.filter(repo_id=repo_id).first()
|
||||
if not record or not record.enabled:
|
||||
error_msg = f'The metadata module is disabled for repo {repo_id}.'
|
||||
return api_error(status.HTTP_404_NOT_FOUND, error_msg)
|
||||
|
||||
views = RepoMetadataViews.objects.filter(
|
||||
repo_id=repo_id
|
||||
).first()
|
||||
if not views:
|
||||
error_msg = 'The metadata views does not exists.'
|
||||
return api_error(status.HTTP_404_NOT_FOUND, error_msg)
|
||||
|
||||
if view_id not in views.view_ids:
|
||||
error_msg = 'view_id %s does not exists.' % view_id
|
||||
return api_error(status.HTTP_404_NOT_FOUND, error_msg)
|
||||
|
||||
repo = seafile_api.get_repo(repo_id)
|
||||
if not repo:
|
||||
error_msg = 'Library %s not found.' % repo_id
|
||||
return api_error(status.HTTP_404_NOT_FOUND, error_msg)
|
||||
|
||||
permission = check_folder_permission(request, repo_id, '/')
|
||||
if permission != 'rw':
|
||||
error_msg = 'Permission denied.'
|
||||
return api_error(status.HTTP_403_FORBIDDEN, error_msg)
|
||||
try:
|
||||
result = RepoMetadataViews.objects.duplicate_view(repo_id, view_id)
|
||||
except Exception as e:
|
||||
logger.exception(e)
|
||||
error_msg = 'Internal Server Error'
|
||||
return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)
|
||||
|
||||
return Response({'view': result})
|
||||
|
||||
|
||||
class MetadataViewsDetailView(APIView):
|
||||
authentication_classes = (TokenAuthentication, SessionAuthentication)
|
||||
permission_classes = (IsAuthenticated,)
|
||||
|
@@ -2,6 +2,7 @@ import logging
|
||||
import json
|
||||
import random
|
||||
import string
|
||||
import copy
|
||||
from django.db import models
|
||||
|
||||
from seahub.utils import get_no_duplicate_obj_name
|
||||
@@ -140,7 +141,23 @@ class RepoMetadataViewsManager(models.Manager):
|
||||
metadata_views.details = json.dumps(view_details)
|
||||
metadata_views.save()
|
||||
return json.loads(metadata_views.details)
|
||||
|
||||
|
||||
def duplicate_view(self, repo_id, view_id):
|
||||
metadata_views = self.filter(repo_id=repo_id).first()
|
||||
view_details = json.loads(metadata_views.details)
|
||||
exist_view_ids = metadata_views.view_ids
|
||||
new_view_id = generate_view_id(4, exist_view_ids)
|
||||
duplicate_view = next((copy.deepcopy(view) for view in view_details['views'] if view.get('_id') == view_id), None)
|
||||
duplicate_view['_id'] = new_view_id
|
||||
view_name = get_no_duplicate_obj_name(duplicate_view['name'], metadata_views.view_names)
|
||||
duplicate_view['name'] = view_name
|
||||
view_details['views'].append(duplicate_view)
|
||||
view_details['navigation'].append({'_id': new_view_id, 'type': 'view'})
|
||||
metadata_views.details = json.dumps(view_details)
|
||||
metadata_views.save()
|
||||
|
||||
return duplicate_view
|
||||
|
||||
def delete_view(self, repo_id, view_id):
|
||||
metadata_views = self.filter(repo_id=repo_id).first()
|
||||
view_details = json.loads(metadata_views.details)
|
||||
|
@@ -208,7 +208,7 @@ from seahub.api2.endpoints.wiki2 import Wikis2View, Wiki2View, Wiki2ConfigView,
|
||||
Wiki2DuplicatePageView, WikiPageTrashView
|
||||
from seahub.api2.endpoints.subscription import SubscriptionView, SubscriptionPlansView, SubscriptionLogsView
|
||||
from seahub.api2.endpoints.metadata_manage import MetadataRecords, MetadataManage, MetadataColumns, MetadataRecordInfo, \
|
||||
MetadataViews, MetadataViewsMoveView, MetadataViewsDetailView, MetadataSummarizeDocs
|
||||
MetadataViews, MetadataViewsMoveView, MetadataViewsDetailView, MetadataSummarizeDocs, MetadataViewsDuplicateView
|
||||
from seahub.api2.endpoints.user_list import UserListView
|
||||
|
||||
|
||||
@@ -1038,5 +1038,5 @@ if settings.ENABLE_METADATA_MANAGEMENT:
|
||||
re_path(r'^api/v2.1/repos/(?P<repo_id>[-0-9a-f]{36})/metadata/views/(?P<view_id>[-0-9a-zA-Z]{4})/$', MetadataViewsDetailView.as_view(), name='api-v2.1-metadata-views-detail'),
|
||||
re_path(r'^api/v2.1/repos/(?P<repo_id>[-0-9a-f]{36})/metadata/move-views/$', MetadataViewsMoveView.as_view(), name='api-v2.1-metadata-views-move'),
|
||||
re_path(r'^api/v2.1/repos/(?P<repo_id>[-0-9a-f]{36})/metadata/ai/summarize-documents/$', MetadataSummarizeDocs.as_view(), name='api-v2.1-metadata-summarize-documents'),
|
||||
|
||||
re_path(r'^api/v2.1/repos/(?P<repo_id>[-0-9a-f]{36})/metadata/duplicate-view/$', MetadataViewsDuplicateView.as_view(), name='api-v2.1-metadata-view-duplicate'),
|
||||
]
|
||||
|
Reference in New Issue
Block a user