mirror of
https://github.com/haiwen/seahub.git
synced 2025-09-14 14:21:23 +00:00
[markdown edit] added 'add a file'; fixed UI for 'link', 'image' popup
This commit is contained in:
@@ -533,7 +533,8 @@ function userInputOPtionsForSelect2(user_search_url) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var FileTree = {
|
var FileTree = {
|
||||||
renderDirTree: function($container, $form, initial_data) {
|
// list dirs & files
|
||||||
|
renderTree: function($container, $form, initial_data, options) {
|
||||||
$container.jstree({
|
$container.jstree({
|
||||||
'core': {
|
'core': {
|
||||||
'data': function(node, callback) {
|
'data': function(node, callback) {
|
||||||
@@ -547,21 +548,38 @@ var FileTree = {
|
|||||||
} else {
|
} else {
|
||||||
repo_id = $container.jstree('get_node', node.parents[node.parents.length - 2]).data.repo_id;
|
repo_id = $container.jstree('get_node', node.parents[node.parents.length - 2]).data.repo_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var url = $container.data('site_root') + 'ajax/repo/' + repo_id + '/dirents/'
|
||||||
|
+ '?path=' + encodeURIComponent(node_path);
|
||||||
|
if (options && options.dir_only) {
|
||||||
|
url += '&dir_only=true';
|
||||||
|
}
|
||||||
$.ajax({
|
$.ajax({
|
||||||
url: $container.data('site_root') + 'ajax/repo/' + repo_id + '/dirents/'
|
url: url,
|
||||||
+ '?path=' + encodeURIComponent(node_path) + '&dir_only=true',
|
|
||||||
cache: false,
|
cache: false,
|
||||||
dataType: 'json',
|
dataType: 'json',
|
||||||
success: function(data) { // data: [{'name': ''}, ...]
|
success: function(data) { // data: [{'name': '', 'type': 'dir'|'file'}, ...]
|
||||||
|
var node_name;
|
||||||
if (data.length) {
|
if (data.length) {
|
||||||
for (var i = 0, len = data.length; i < len; i++) {
|
for (var i = 0, len = data.length; i < len; i++) {
|
||||||
|
node_name = data[i].name;
|
||||||
|
if (data[i].type == 'dir') {
|
||||||
node.children.push({
|
node.children.push({
|
||||||
'text': HTMLescape(data[i].name),
|
'text': HTMLescape(node_name),
|
||||||
'data': {
|
'data': {
|
||||||
'path': node_path + data[i].name + '/',
|
'path': node_path + node_name + '/'
|
||||||
},
|
},
|
||||||
'children': true
|
'children': true
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
node.children.push({
|
||||||
|
'text': HTMLescape(node_name),
|
||||||
|
'type': 'file',
|
||||||
|
'data': {
|
||||||
|
'path': node_path + node_name
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -571,9 +589,15 @@ var FileTree = {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
'multiple': false, // only 1 folder is allowed to be selected at one time
|
'multiple': false, // only 1 item is allowed to be selected at one time
|
||||||
'animation': 100
|
'animation': 100
|
||||||
|
}, // 'core' ends
|
||||||
|
'types': { // custom node types
|
||||||
|
'file': { // add type 'file'
|
||||||
|
'icon': 'jstree-file'
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
'plugins': ['types']
|
||||||
})
|
})
|
||||||
.on('select_node.jstree', function(e, data) {
|
.on('select_node.jstree', function(e, data) {
|
||||||
var node = data.node;
|
var node = data.node;
|
||||||
@@ -586,5 +610,10 @@ var FileTree = {
|
|||||||
$('input[name="dst_repo"]', $form).val(repo_id);
|
$('input[name="dst_repo"]', $form).val(repo_id);
|
||||||
$('input[name="dst_path"]', $form).val(node.data.path);
|
$('input[name="dst_path"]', $form).val(node.data.path);
|
||||||
});
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
// only list dirs
|
||||||
|
renderDirTree: function($container, $form, initial_data) {
|
||||||
|
this.renderTree($container, $form, initial_data, {'dir_only': true});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@@ -31,6 +31,7 @@
|
|||||||
height:auto;
|
height:auto;
|
||||||
border-radius:4px;
|
border-radius:4px;
|
||||||
margin:0;
|
margin:0;
|
||||||
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
@@ -134,6 +135,24 @@
|
|||||||
</form>
|
</form>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
|
||||||
|
{% if not err and filetype == 'Markdown' %}
|
||||||
|
<form id="add-file-form" action="" method="post" class="file-choose-form hide">{% csrf_token %}
|
||||||
|
<h3>{% trans "Choose a file" %}</h3>
|
||||||
|
<div class="dir-tree-cont">
|
||||||
|
<div id="repos-dirs">
|
||||||
|
<span class="loading-icon loading-tip"></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<input type="hidden" name="dst_repo" value="" />
|
||||||
|
<input type="hidden" name="dst_path" value="" />
|
||||||
|
<p class="error hide">{% trans "Please choose a file." %}</p>
|
||||||
|
<button type="submit" class="submit">{% trans "Submit" %}</button>
|
||||||
|
<button class="simplemodal-close">{% trans "Cancel" %}</button>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
<div id="load-draft" class="hide">
|
<div id="load-draft" class="hide">
|
||||||
<h3 id="dialogTitle">{% trans "Draft Available" %}</h3>
|
<h3 id="dialogTitle">{% trans "Draft Available" %}</h3>
|
||||||
<p>{% trans "There's a saved draft for this file, would you like to load it?" %}</p>
|
<p>{% trans "There's a saved draft for this file, would you like to load it?" %}</p>
|
||||||
@@ -293,11 +312,91 @@ var mdEditor = editormd('md-editor', {
|
|||||||
'bold', 'italic', '|',
|
'bold', 'italic', '|',
|
||||||
'h1', 'h2', 'h3', 'h4', '|',
|
'h1', 'h2', 'h3', 'h4', '|',
|
||||||
'list-ul', 'list-ol', 'hr', '|',
|
'list-ul', 'list-ol', 'hr', '|',
|
||||||
'link', 'image', 'table', '|',
|
'link', 'file', 'image', 'table', '|',
|
||||||
'undo', 'redo','|',
|
'undo', 'redo','|',
|
||||||
'watch', 'fullscreen'
|
'watch', 'fullscreen'
|
||||||
];
|
];
|
||||||
},
|
},
|
||||||
|
toolbarIconsClass: {
|
||||||
|
'file': 'fa-file'
|
||||||
|
},
|
||||||
|
toolbarHandlers: {
|
||||||
|
'file': function(cm, icon, cursor, selection) {
|
||||||
|
var $form = $('#add-file-form');
|
||||||
|
$form.modal();
|
||||||
|
$('#simplemodal-container').css({'width':'auto', 'height':'auto'});
|
||||||
|
|
||||||
|
// fetch repos and render the tree
|
||||||
|
$.ajax({
|
||||||
|
url: '{% url 'api2-repos' %}',
|
||||||
|
cache: false,
|
||||||
|
dataType: 'json',
|
||||||
|
success: function(data) {
|
||||||
|
var repos = [], repo_ids = [], repo;
|
||||||
|
for (var i = 0, len = data.length; i < len; i++) {
|
||||||
|
repo = data[i];
|
||||||
|
// remove encrypted & duplicate
|
||||||
|
if (!repo.encrypted && repo_ids.indexOf(repo.id) == -1) {
|
||||||
|
repo_ids.push(repo.id);
|
||||||
|
repos.push({
|
||||||
|
'text': HTMLescape(repo.name),
|
||||||
|
'data': {'repo_id': repo.id, 'path': '/'},
|
||||||
|
'children': true
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
repos.sort(function(a, b) {
|
||||||
|
var a_name = a.text.toLowerCase();
|
||||||
|
var b_name = b.text.toLowerCase();
|
||||||
|
return a_name < b_name ? -1 : 1;
|
||||||
|
});
|
||||||
|
FileTree.renderTree($('#repos-dirs').data('site_root', '{{SITE_ROOT}}'), $form, repos); // there is at least 1 repo
|
||||||
|
},
|
||||||
|
error: function(xhr) {
|
||||||
|
if (xhr.responseText) {
|
||||||
|
feedback($.parseJSON(xhr.responseText).error||$.parseJSON(xhr.responseText).error_msg, 'error');
|
||||||
|
} else {
|
||||||
|
feedback("{% trans "Please check the network." %}", 'error');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$form.submit(function() {
|
||||||
|
var dst_repo = $('[name="dst_repo"]', $form).val(),
|
||||||
|
dst_path = $('[name="dst_path"]', $form).val();
|
||||||
|
|
||||||
|
// no item is selected
|
||||||
|
if (!dst_repo || !dst_path) {
|
||||||
|
$('.error', $form).removeClass('hide');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// a dir is selected
|
||||||
|
if (dst_path.charAt(dst_path.length - 1) == '/') {
|
||||||
|
$('.error', $form).removeClass('hide'); // only a file can be selected
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$.modal.close();
|
||||||
|
|
||||||
|
var path_arr = dst_path.split('/'),
|
||||||
|
path_arr_ = [],
|
||||||
|
name = path_arr[path_arr.length - 1],
|
||||||
|
encodedPath;
|
||||||
|
for (var i = 0, len = path_arr.length; i < len; i++) {
|
||||||
|
path_arr_.push(encodeURIComponent(path_arr[i]));
|
||||||
|
}
|
||||||
|
encodedPath = path_arr_.join('/');
|
||||||
|
|
||||||
|
var url = '{{SITE_ROOT}}lib/' + dst_repo + '/file' + encodedPath;
|
||||||
|
// replace ... or directly insert
|
||||||
|
cm.replaceSelection('[' + name + '](' + url + ')');
|
||||||
|
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
},
|
||||||
lang: {
|
lang: {
|
||||||
// custom title of toolbar icons
|
// custom title of toolbar icons
|
||||||
toolbar: {
|
toolbar: {
|
||||||
@@ -311,6 +410,7 @@ var mdEditor = editormd('md-editor', {
|
|||||||
'list-ol': "{% trans "Ordered list" %}",
|
'list-ol': "{% trans "Ordered list" %}",
|
||||||
hr: "{% trans "Horizontal rule" %}",
|
hr: "{% trans "Horizontal rule" %}",
|
||||||
link: "{% trans "Link" %}",
|
link: "{% trans "Link" %}",
|
||||||
|
"file": "{% trans "File" %}",
|
||||||
image: "{% trans "Image" %}",
|
image: "{% trans "Image" %}",
|
||||||
table: "{% trans "Table" %}",
|
table: "{% trans "Table" %}",
|
||||||
undo: "{% trans "Undo(Ctrl+Z)" %}",
|
undo: "{% trans "Undo(Ctrl+Z)" %}",
|
||||||
|
@@ -141,15 +141,15 @@ def get_dirents(request, repo_id):
|
|||||||
for dirent in dirents:
|
for dirent in dirents:
|
||||||
if stat.S_ISDIR(dirent.mode):
|
if stat.S_ISDIR(dirent.mode):
|
||||||
subdir = {
|
subdir = {
|
||||||
'name': dirent.obj_name
|
'name': dirent.obj_name,
|
||||||
|
'type': 'dir'
|
||||||
}
|
}
|
||||||
d_list.append(subdir)
|
d_list.append(subdir)
|
||||||
else:
|
else:
|
||||||
if not dir_only:
|
if not dir_only:
|
||||||
f = {
|
f = {
|
||||||
'id': dirent.obj_id,
|
|
||||||
'name': dirent.obj_name,
|
'name': dirent.obj_name,
|
||||||
'type': 'file',
|
'type': 'file'
|
||||||
}
|
}
|
||||||
f_list.append(f)
|
f_list.append(f)
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user