mirror of
https://github.com/haiwen/seahub.git
synced 2025-09-04 16:31:13 +00:00
dtable file view page
This commit is contained in:
@@ -9,7 +9,7 @@ import GridHeaderContextMenu from './grid-header-contextmenu';
|
|||||||
import GridContentContextMenu from './grid-content-contextmenu';
|
import GridContentContextMenu from './grid-content-contextmenu';
|
||||||
import DTableStore from './store/dtable-store';
|
import DTableStore from './store/dtable-store';
|
||||||
|
|
||||||
const { repoID, filePath } = window.app.pageOptions;
|
const { workspaceID, fileName } = window.app.pageOptions;
|
||||||
|
|
||||||
const DEFAULT_DATA = {
|
const DEFAULT_DATA = {
|
||||||
columns: [
|
columns: [
|
||||||
@@ -38,7 +38,7 @@ class AppMain extends React.Component {
|
|||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
|
|
||||||
seafileAPI.getFileDownloadLink(repoID, filePath).then(res => {
|
seafileAPI.getTableDownloadLink(workspaceID, fileName).then(res => {
|
||||||
let url = res.data;
|
let url = res.data;
|
||||||
seafileAPI.getFileContent(url).then(res => {
|
seafileAPI.getFileContent(url).then(res => {
|
||||||
let data = res.data ? res.data : JSON.stringify(DEFAULT_DATA);
|
let data = res.data ? res.data : JSON.stringify(DEFAULT_DATA);
|
||||||
|
@@ -3,7 +3,6 @@ import PropTypes from 'prop-types';
|
|||||||
import { Button, Dropdown, DropdownToggle, DropdownMenu, DropdownItem } from 'reactstrap';
|
import { Button, Dropdown, DropdownToggle, DropdownMenu, DropdownItem } from 'reactstrap';
|
||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
import { seafileAPI } from '../../utils/seafile-api';
|
import { seafileAPI } from '../../utils/seafile-api';
|
||||||
import { Utils } from '../../utils/utils';
|
|
||||||
import { gettext, siteRoot } from '../../utils/constants';
|
import { gettext, siteRoot } from '../../utils/constants';
|
||||||
import Loading from '../../components/loading';
|
import Loading from '../../components/loading';
|
||||||
import CreateWorkspaceDialog from '../../components/dialog/create-workspace-dialog';
|
import CreateWorkspaceDialog from '../../components/dialog/create-workspace-dialog';
|
||||||
@@ -17,7 +16,7 @@ moment.locale(window.app.config.lang);
|
|||||||
|
|
||||||
const tablePropTypes = {
|
const tablePropTypes = {
|
||||||
table: PropTypes.object.isRequired,
|
table: PropTypes.object.isRequired,
|
||||||
repoID: PropTypes.string.isRequired,
|
workspaceID: PropTypes.string.isRequired,
|
||||||
renameTable: PropTypes.func.isRequired,
|
renameTable: PropTypes.func.isRequired,
|
||||||
deleteTable: PropTypes.func.isRequired,
|
deleteTable: PropTypes.func.isRequired,
|
||||||
};
|
};
|
||||||
@@ -74,7 +73,7 @@ class Table extends Component {
|
|||||||
render() {
|
render() {
|
||||||
|
|
||||||
let table = this.props.table;
|
let table = this.props.table;
|
||||||
let tableHref = siteRoot + 'lib/' + this.props.repoID + '/file' + Utils.encodePath(Utils.joinPath('/', table.name));
|
let tableHref = siteRoot + 'workspace/' + this.props.workspaceID + '/dtable/' + table.name + '/';
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<tr onMouseEnter={this.onMouseEnter} onMouseLeave={this.onMouseLeave}>
|
<tr onMouseEnter={this.onMouseEnter} onMouseLeave={this.onMouseLeave}>
|
||||||
@@ -269,7 +268,7 @@ class Workspace extends Component {
|
|||||||
<Table
|
<Table
|
||||||
key={index}
|
key={index}
|
||||||
table={table}
|
table={table}
|
||||||
repoID={workspace.repo_id}
|
workspaceID={workspace.id}
|
||||||
renameTable={this.renameTable}
|
renameTable={this.renameTable}
|
||||||
deleteTable={this.deleteTable}
|
deleteTable={this.deleteTable}
|
||||||
/>
|
/>
|
||||||
|
@@ -54,6 +54,9 @@ export const canLockUnlockFile = window.app.pageOptions.canLockUnlockFile;
|
|||||||
export const curNoteMsg = window.app.pageOptions.curNoteMsg;
|
export const curNoteMsg = window.app.pageOptions.curNoteMsg;
|
||||||
export const curNoteID = window.app.pageOptions.curNoteID;
|
export const curNoteID = window.app.pageOptions.curNoteID;
|
||||||
|
|
||||||
|
// ctable
|
||||||
|
export const workspaceID = window.app.pageOptions.workspaceID;
|
||||||
|
|
||||||
// wiki
|
// wiki
|
||||||
export const slug = window.wiki ? window.wiki.config.slug : '';
|
export const slug = window.wiki ? window.wiki.config.slug : '';
|
||||||
export const repoID = window.wiki ? window.wiki.config.repoId : '';
|
export const repoID = window.wiki ? window.wiki.config.repoId : '';
|
||||||
|
@@ -7,17 +7,26 @@ from rest_framework.authentication import SessionAuthentication
|
|||||||
from rest_framework.permissions import IsAuthenticated
|
from rest_framework.permissions import IsAuthenticated
|
||||||
from rest_framework import status
|
from rest_framework import status
|
||||||
from rest_framework.response import Response
|
from rest_framework.response import Response
|
||||||
|
from django.http import HttpResponse, Http404
|
||||||
|
from django.shortcuts import render
|
||||||
|
from django.utils.translation import ugettext as _
|
||||||
|
|
||||||
from pysearpc import SearpcError
|
from pysearpc import SearpcError
|
||||||
from seaserv import seafile_api, edit_repo
|
from seaserv import seafile_api, edit_repo, is_repo_owner
|
||||||
|
|
||||||
from seahub.api2.authentication import TokenAuthentication
|
from seahub.api2.authentication import TokenAuthentication
|
||||||
from seahub.api2.throttling import UserRateThrottle
|
from seahub.api2.throttling import UserRateThrottle
|
||||||
from seahub.api2.utils import api_error
|
from seahub.api2.utils import api_error
|
||||||
|
from seahub.api2.views import get_repo_file
|
||||||
from seahub.dtable.models import WorkSpaces
|
from seahub.dtable.models import WorkSpaces
|
||||||
from seahub.base.templatetags.seahub_tags import email2nickname
|
from seahub.base.templatetags.seahub_tags import email2nickname
|
||||||
from seahub.utils.timeutils import timestamp_to_isoformat_timestr
|
from seahub.utils.timeutils import timestamp_to_isoformat_timestr
|
||||||
from seahub.utils import is_valid_dirent_name, is_org_context, normalize_file_path, check_filename_with_rename
|
from seahub.utils import is_valid_dirent_name, is_org_context, normalize_file_path, \
|
||||||
from seahub.settings import MAX_UPLOAD_FILE_NAME_LEN
|
check_filename_with_rename, render_error, render_permission_error, CTABLE
|
||||||
|
from seahub.views.file import send_file_access_msg
|
||||||
|
from seahub.auth.decorators import login_required
|
||||||
|
from seahub.settings import MAX_UPLOAD_FILE_NAME_LEN, SHARE_LINK_EXPIRE_DAYS_MIN, \
|
||||||
|
SHARE_LINK_EXPIRE_DAYS_MAX, SHARE_LINK_EXPIRE_DAYS_DEFAULT
|
||||||
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
@@ -233,6 +242,52 @@ class DTableView(APIView):
|
|||||||
permission_classes = (IsAuthenticated, )
|
permission_classes = (IsAuthenticated, )
|
||||||
throttle_classes = (UserRateThrottle, )
|
throttle_classes = (UserRateThrottle, )
|
||||||
|
|
||||||
|
def get(self, request, workspace_id):
|
||||||
|
"""view table file, get table download link
|
||||||
|
"""
|
||||||
|
# argument check
|
||||||
|
table_name = request.GET.get('name', None)
|
||||||
|
if not table_name:
|
||||||
|
error_msg = 'name invalid.'
|
||||||
|
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
|
||||||
|
|
||||||
|
reuse = request.GET.get('reuse', '0')
|
||||||
|
if reuse not in ('1', '0'):
|
||||||
|
error_msg = 'reuse invalid.'
|
||||||
|
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
|
||||||
|
|
||||||
|
# resource check
|
||||||
|
workspace = WorkSpaces.objects.get_workspace_by_id(workspace_id)
|
||||||
|
if not workspace:
|
||||||
|
error_msg = 'WorkSpace %s not found.' % workspace_id
|
||||||
|
return api_error(status.HTTP_404_NOT_FOUND, error_msg)
|
||||||
|
|
||||||
|
repo_id = workspace.repo_id
|
||||||
|
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)
|
||||||
|
|
||||||
|
table_path = normalize_file_path(table_name)
|
||||||
|
table_file_id = seafile_api.get_file_id_by_path(repo_id, table_path)
|
||||||
|
if not table_file_id:
|
||||||
|
error_msg = 'Library %s not found.' % repo_id
|
||||||
|
return api_error(status.HTTP_404_NOT_FOUND, error_msg)
|
||||||
|
|
||||||
|
# permission check
|
||||||
|
username = request.user.username
|
||||||
|
owner = workspace.owner
|
||||||
|
if username != owner:
|
||||||
|
error_msg = 'Permission denied.'
|
||||||
|
return api_error(status.HTTP_403_FORBIDDEN, error_msg)
|
||||||
|
|
||||||
|
# send stats message
|
||||||
|
send_file_access_msg(request, repo, table_path, 'api')
|
||||||
|
|
||||||
|
op = request.GET.get('op', 'download')
|
||||||
|
use_onetime = False if reuse == '1' else True
|
||||||
|
return get_repo_file(request, repo_id, table_file_id, table_name, op, use_onetime)
|
||||||
|
|
||||||
def post(self, request, workspace_id):
|
def post(self, request, workspace_id):
|
||||||
"""create a table file
|
"""create a table file
|
||||||
"""
|
"""
|
||||||
@@ -409,3 +464,41 @@ class DTableView(APIView):
|
|||||||
return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)
|
return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)
|
||||||
|
|
||||||
return Response({'success': True}, status=status.HTTP_200_OK)
|
return Response({'success': True}, status=status.HTTP_200_OK)
|
||||||
|
|
||||||
|
|
||||||
|
@login_required
|
||||||
|
def dtable_file_view(request, workspace_id, name):
|
||||||
|
|
||||||
|
# resource check
|
||||||
|
workspace = WorkSpaces.objects.get_workspace_by_id(workspace_id)
|
||||||
|
if not workspace:
|
||||||
|
raise Http404
|
||||||
|
|
||||||
|
repo_id = workspace.repo_id
|
||||||
|
repo = seafile_api.get_repo(repo_id)
|
||||||
|
if not repo:
|
||||||
|
raise Http404
|
||||||
|
|
||||||
|
table_path = normalize_file_path(name)
|
||||||
|
table_file_id = seafile_api.get_file_id_by_path(repo_id, table_path)
|
||||||
|
if not table_file_id:
|
||||||
|
return render_error(request, _(u'Table does not exist'))
|
||||||
|
|
||||||
|
# permission check
|
||||||
|
username = request.user.username
|
||||||
|
owner = workspace.owner
|
||||||
|
if username != owner:
|
||||||
|
return render_permission_error(request, _(u'Unable to view file'))
|
||||||
|
|
||||||
|
return_dict = {
|
||||||
|
'repo': repo,
|
||||||
|
'workspace_id': workspace_id,
|
||||||
|
'path': table_path,
|
||||||
|
'filename': name,
|
||||||
|
'filetype': CTABLE,
|
||||||
|
'share_link_expire_days_default': SHARE_LINK_EXPIRE_DAYS_DEFAULT,
|
||||||
|
'share_link_expire_days_min': SHARE_LINK_EXPIRE_DAYS_MIN,
|
||||||
|
'share_link_expire_days_max': SHARE_LINK_EXPIRE_DAYS_MAX,
|
||||||
|
}
|
||||||
|
|
||||||
|
return render(request, 'ctable_file_view_react.html', return_dict)
|
||||||
|
@@ -41,6 +41,10 @@ window.app.pageOptions = {
|
|||||||
enableWatermark: {% if enable_watermark %}true{% else %}false{% endif %},
|
enableWatermark: {% if enable_watermark %}true{% else %}false{% endif %},
|
||||||
|
|
||||||
// for {{filetype}} file
|
// for {{filetype}} file
|
||||||
|
{% if filetype == 'ctable' %}
|
||||||
|
workspaceID: '{{ workspace_id }}',
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
{% block extra_data %}
|
{% block extra_data %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
};
|
};
|
||||||
|
@@ -84,7 +84,7 @@ from seahub.api2.endpoints.related_files import RelatedFilesView, RelatedFileVie
|
|||||||
from seahub.api2.endpoints.webdav_secret import WebdavSecretView
|
from seahub.api2.endpoints.webdav_secret import WebdavSecretView
|
||||||
from seahub.api2.endpoints.starred_items import StarredItems
|
from seahub.api2.endpoints.starred_items import StarredItems
|
||||||
from seahub.api2.endpoints.markdown_lint import MarkdownLintView
|
from seahub.api2.endpoints.markdown_lint import MarkdownLintView
|
||||||
from seahub.api2.endpoints.dtable import WorkSpacesView, WorkSpaceView, DTableView
|
from seahub.api2.endpoints.dtable import WorkSpacesView, WorkSpaceView, DTableView, dtable_file_view
|
||||||
|
|
||||||
# Admin
|
# Admin
|
||||||
from seahub.api2.endpoints.admin.revision_tag import AdminTaggedItemsView
|
from seahub.api2.endpoints.admin.revision_tag import AdminTaggedItemsView
|
||||||
@@ -348,6 +348,7 @@ urlpatterns = [
|
|||||||
url(r'^api/v2.1/workspaces/$', WorkSpacesView.as_view(), name='api-v2.1-workspaces'),
|
url(r'^api/v2.1/workspaces/$', WorkSpacesView.as_view(), name='api-v2.1-workspaces'),
|
||||||
url(r'^api/v2.1/workspace/(?P<workspace_id>\d+)/$', WorkSpaceView.as_view(), name='api-v2.1-workspace'),
|
url(r'^api/v2.1/workspace/(?P<workspace_id>\d+)/$', WorkSpaceView.as_view(), name='api-v2.1-workspace'),
|
||||||
url(r'^api/v2.1/workspace/(?P<workspace_id>\d+)/dtable/$', DTableView.as_view(), name='api-v2.1-workspace-table'),
|
url(r'^api/v2.1/workspace/(?P<workspace_id>\d+)/dtable/$', DTableView.as_view(), name='api-v2.1-workspace-table'),
|
||||||
|
url(r'^workspace/(?P<workspace_id>\d+)/dtable/(?P<name>.*)/$', dtable_file_view, name='dtable-file-view'),
|
||||||
|
|
||||||
# Deprecated
|
# Deprecated
|
||||||
url(r'^api/v2.1/repos/(?P<repo_id>[-0-9a-f]{36})/tags/$', FileTagsView.as_view(), name="api-v2.1-filetags-view"),
|
url(r'^api/v2.1/repos/(?P<repo_id>[-0-9a-f]{36})/tags/$', FileTagsView.as_view(), name="api-v2.1-filetags-view"),
|
||||||
|
@@ -734,8 +734,6 @@ def view_lib_file(request, repo_id, path):
|
|||||||
|
|
||||||
return render(request, template, return_dict)
|
return render(request, template, return_dict)
|
||||||
|
|
||||||
elif filetype == CTABLE:
|
|
||||||
return render(request, template, return_dict)
|
|
||||||
elif filetype == CDOC:
|
elif filetype == CDOC:
|
||||||
return render(request, template, return_dict)
|
return render(request, template, return_dict)
|
||||||
elif filetype == IMAGE:
|
elif filetype == IMAGE:
|
||||||
|
Reference in New Issue
Block a user