migration: migrated dropzone to filepond; couple fixes for select2; fixes luxon seconds display;
This commit is contained in:
parent
89479931d7
commit
cf5ea2eac5
16 changed files with 542 additions and 399 deletions
|
|
@ -24,6 +24,10 @@
|
|||
"src": "<%= dirs.css.src %>/style-polymer.css",
|
||||
"dest": "<%= dirs.js.dest %>/src/components/style-polymer.css"
|
||||
},
|
||||
{
|
||||
"src": "<%= dirs.js.node_modules %>/filepond/dist/filepond.css",
|
||||
"dest": "<%= dirs.css.dest %>/filepond.css"
|
||||
},
|
||||
{
|
||||
"src": "<%= dirs.js.src %>/select2/select2.css",
|
||||
"dest": "<%= dirs.css.dest %>/select2.css"
|
||||
|
|
@ -39,12 +43,12 @@
|
|||
"<%= dirs.js.node_modules %>/luxon/build/global/luxon.min.js",
|
||||
"<%= dirs.js.node_modules %>/clipboard/dist/clipboard.min.js",
|
||||
"<%= dirs.js.node_modules %>/favico.js/favico-0.3.10.min.js",
|
||||
"<%= dirs.js.node_modules %>/dropzone/dist/min/dropzone.min.js",
|
||||
"<%= dirs.js.node_modules %>/sweetalert2/dist/sweetalert2.min.js",
|
||||
"<%= dirs.js.node_modules %>/sticky-sidebar/dist/sticky-sidebar.min.js",
|
||||
"<%= dirs.js.node_modules %>/sticky-sidebar/dist/jquery.sticky-sidebar.min.js",
|
||||
"<%= dirs.js.node_modules %>/waypoints/lib/noframework.waypoints.min.js",
|
||||
"<%= dirs.js.node_modules %>/waypoints/lib/jquery.waypoints.min.js",
|
||||
"<%= dirs.js.node_modules %>/filepond/dist/filepond.min.js",
|
||||
"<%= dirs.js.src %>/logging.js",
|
||||
"<%= dirs.js.src %>/bootstrap.js",
|
||||
"<%= dirs.js.src %>/i18n_utils.js",
|
||||
|
|
|
|||
43
package-lock.json
generated
43
package-lock.json
generated
|
|
@ -26,9 +26,9 @@
|
|||
"clipboard": "^2.0.1",
|
||||
"copy-webpack-plugin": "^4.4.2",
|
||||
"css-loader": "^0.28.11",
|
||||
"dropzone": "^5.5.0",
|
||||
"exports-loader": "^0.6.4",
|
||||
"favico.js": "^0.3.10",
|
||||
"filepond": "^4.32.10",
|
||||
"grunt": "^0.4.5",
|
||||
"grunt-cli": "^1.4.3",
|
||||
"grunt-contrib-concat": "^0.5.1",
|
||||
|
|
@ -51,7 +51,7 @@
|
|||
"raw-loader": "1.0.0-beta.0",
|
||||
"sticky-sidebar": "3.3.1",
|
||||
"style-loader": "^0.21.0",
|
||||
"sweetalert2": "^9.10.12",
|
||||
"sweetalert2": "^11.26.3",
|
||||
"ts-loader": "^1.3.3",
|
||||
"waypoints": "4.0.1",
|
||||
"webpack": "4.23.1",
|
||||
|
|
@ -3284,12 +3284,6 @@
|
|||
"domelementtype": "1"
|
||||
}
|
||||
},
|
||||
"node_modules/dropzone": {
|
||||
"version": "5.9.3",
|
||||
"resolved": "https://registry.npmjs.org/dropzone/-/dropzone-5.9.3.tgz",
|
||||
"integrity": "sha512-Azk8kD/2/nJIuVPK+zQ9sjKMRIpRvNyqn9XwbBHNq+iNuSccbJS6hwm1Woy0pMST0erSo0u4j+KJaodndDk4vA==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/duplexer": {
|
||||
"version": "0.1.2",
|
||||
"resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz",
|
||||
|
|
@ -3916,6 +3910,12 @@
|
|||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"node_modules/filepond": {
|
||||
"version": "4.32.10",
|
||||
"resolved": "https://registry.npmjs.org/filepond/-/filepond-4.32.10.tgz",
|
||||
"integrity": "sha512-uflpIL+rfAgsYk7HgXugh7ELlHNHLTPtIHfvuq0gv3x2qNfVxdGA6T7RPxMh9Vji8ysXstXkDHVXQ4hY38MPTQ==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/fill-range": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz",
|
||||
|
|
@ -10334,12 +10334,13 @@
|
|||
}
|
||||
},
|
||||
"node_modules/sweetalert2": {
|
||||
"version": "9.17.4",
|
||||
"resolved": "https://registry.npmjs.org/sweetalert2/-/sweetalert2-9.17.4.tgz",
|
||||
"integrity": "sha512-T6Js/kjtGmpekE1tPT+drdgsedEnaet03mMadKUMvtBlFzVLcYy8kvIuchaQJ09rhG5bdmRRMQ2sEK0ZnHi1vg==",
|
||||
"version": "11.26.3",
|
||||
"resolved": "https://registry.npmjs.org/sweetalert2/-/sweetalert2-11.26.3.tgz",
|
||||
"integrity": "sha512-VU0hGw/WfI9h7Mh+SCsDlWgtxDwWZ6ccqS7QcO8zEeWnwplN1GptcLstq76OluUBSLUza6ldvKd3558OhjpJ9A==",
|
||||
"dev": true,
|
||||
"funding": {
|
||||
"url": "https://sweetalert2.github.io/#donations"
|
||||
"type": "individual",
|
||||
"url": "https://github.com/sponsors/limonte"
|
||||
}
|
||||
},
|
||||
"node_modules/tapable": {
|
||||
|
|
@ -14789,12 +14790,6 @@
|
|||
"domelementtype": "1"
|
||||
}
|
||||
},
|
||||
"dropzone": {
|
||||
"version": "5.9.3",
|
||||
"resolved": "https://registry.npmjs.org/dropzone/-/dropzone-5.9.3.tgz",
|
||||
"integrity": "sha512-Azk8kD/2/nJIuVPK+zQ9sjKMRIpRvNyqn9XwbBHNq+iNuSccbJS6hwm1Woy0pMST0erSo0u4j+KJaodndDk4vA==",
|
||||
"dev": true
|
||||
},
|
||||
"duplexer": {
|
||||
"version": "0.1.2",
|
||||
"resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz",
|
||||
|
|
@ -15324,6 +15319,12 @@
|
|||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"filepond": {
|
||||
"version": "4.32.10",
|
||||
"resolved": "https://registry.npmjs.org/filepond/-/filepond-4.32.10.tgz",
|
||||
"integrity": "sha512-uflpIL+rfAgsYk7HgXugh7ELlHNHLTPtIHfvuq0gv3x2qNfVxdGA6T7RPxMh9Vji8ysXstXkDHVXQ4hY38MPTQ==",
|
||||
"dev": true
|
||||
},
|
||||
"fill-range": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz",
|
||||
|
|
@ -20525,9 +20526,9 @@
|
|||
}
|
||||
},
|
||||
"sweetalert2": {
|
||||
"version": "9.17.4",
|
||||
"resolved": "https://registry.npmjs.org/sweetalert2/-/sweetalert2-9.17.4.tgz",
|
||||
"integrity": "sha512-T6Js/kjtGmpekE1tPT+drdgsedEnaet03mMadKUMvtBlFzVLcYy8kvIuchaQJ09rhG5bdmRRMQ2sEK0ZnHi1vg==",
|
||||
"version": "11.26.3",
|
||||
"resolved": "https://registry.npmjs.org/sweetalert2/-/sweetalert2-11.26.3.tgz",
|
||||
"integrity": "sha512-VU0hGw/WfI9h7Mh+SCsDlWgtxDwWZ6ccqS7QcO8zEeWnwplN1GptcLstq76OluUBSLUza6ldvKd3558OhjpJ9A==",
|
||||
"dev": true
|
||||
},
|
||||
"tapable": {
|
||||
|
|
|
|||
|
|
@ -26,9 +26,9 @@
|
|||
"clipboard": "^2.0.1",
|
||||
"copy-webpack-plugin": "^4.4.2",
|
||||
"css-loader": "^0.28.11",
|
||||
"dropzone": "^5.5.0",
|
||||
"exports-loader": "^0.6.4",
|
||||
"favico.js": "^0.3.10",
|
||||
"filepond": "^4.32.10",
|
||||
"grunt": "^0.4.5",
|
||||
"grunt-cli": "^1.4.3",
|
||||
"grunt-contrib-concat": "^0.5.1",
|
||||
|
|
@ -51,7 +51,7 @@
|
|||
"raw-loader": "1.0.0-beta.0",
|
||||
"sticky-sidebar": "3.3.1",
|
||||
"style-loader": "^0.21.0",
|
||||
"sweetalert2": "^9.10.12",
|
||||
"sweetalert2": "^11.26.3",
|
||||
"ts-loader": "^1.3.3",
|
||||
"waypoints": "4.0.1",
|
||||
"webpack": "4.23.1",
|
||||
|
|
|
|||
|
|
@ -203,7 +203,6 @@ def includeme(config):
|
|||
route_name="repo_commit_comment_attachment_upload",
|
||||
request_method="POST",
|
||||
renderer="json_ext",
|
||||
xhr=True,
|
||||
)
|
||||
|
||||
config.add_route(
|
||||
|
|
|
|||
|
|
@ -588,7 +588,7 @@ class RepoCommitsView(RepoAppView):
|
|||
".xlsx",
|
||||
".zip",
|
||||
]
|
||||
max_file_size = 10 * 1024 * 1024 # 10MB, also validated via dropzone.js
|
||||
max_file_size = 10 * 1024 * 1024 # 10MB
|
||||
|
||||
try:
|
||||
f_store = store_utils.get_filestore_backend(self.request.registry.settings)
|
||||
|
|
|
|||
|
|
@ -1453,6 +1453,10 @@ class RepoFilesView(RepoAppView):
|
|||
nodes = {}
|
||||
|
||||
for file_obj in r_post.getall("files_upload") or []:
|
||||
if file_obj == "{}":
|
||||
# filepond sends the field with the same name as the file field with metadata which in our case is empty
|
||||
continue
|
||||
|
||||
content = file_obj.file
|
||||
filename = file_obj.filename
|
||||
|
||||
|
|
|
|||
23
rhodecode/public/css/filepond.less
Normal file
23
rhodecode/public/css/filepond.less
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
.filepond--root .filepond--file-info,
|
||||
.filepond--root .filepond--file-info-main,
|
||||
.filepond--root .filepond--file-info-sub {
|
||||
pointer-events: auto !important;
|
||||
}
|
||||
|
||||
/* Make the “sub” line look like the main line (brighter) */
|
||||
.filepond--root .filepond--file-info .filepond--file-info-sub {
|
||||
opacity: 1 !important; /* remove faded look */
|
||||
color: #ffffff; /* or whatever contrasts your green */
|
||||
font-size: 0.75em; /* same as main, if you like */
|
||||
}
|
||||
|
||||
/* Style the link itself */
|
||||
.filepond--root .filepond--file-info .filepond--file-info-sub a {
|
||||
color: #ffffff;
|
||||
text-decoration: underline;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.filepond--root .filepond--drop-label .filepond--label-action {
|
||||
font-family: @text-regular; /* or a different font */
|
||||
}
|
||||
|
|
@ -28,6 +28,7 @@
|
|||
@import 'deform';
|
||||
@import 'tooltips';
|
||||
@import 'sweetalert2';
|
||||
@import 'filepond';
|
||||
|
||||
|
||||
//--- BASE ------------------//
|
||||
|
|
@ -2957,27 +2958,11 @@ form.markup-form {
|
|||
}
|
||||
|
||||
|
||||
.dropzone-wrapper {
|
||||
.filepond-wrapper {
|
||||
border: 1px solid @grey5;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.dropzone,
|
||||
.dropzone-pure {
|
||||
border: 2px dashed @grey5;
|
||||
border-radius: 5px;
|
||||
background: white;
|
||||
min-height: 200px;
|
||||
padding: 54px;
|
||||
|
||||
.dz-message {
|
||||
font-weight: 700;
|
||||
text-align: center;
|
||||
margin: 2em 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.dz-preview {
|
||||
margin: 10px 0 !important;
|
||||
position: relative;
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ var AgeModule = (function () {
|
|||
day: days,
|
||||
hour: hours,
|
||||
minute: minutes,
|
||||
second: seconds,
|
||||
second: Math.round(seconds),
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -928,7 +928,6 @@ var CommentsController = function() {
|
|||
}, 100);
|
||||
}
|
||||
|
||||
// add dropzone support
|
||||
var insertAttachmentText = function (cm, attachmentName, attachmentStoreUrl, isRendered) {
|
||||
var renderer = templateContext.visual.default_renderer;
|
||||
if (renderer == 'rst') {
|
||||
|
|
@ -949,74 +948,115 @@ var CommentsController = function() {
|
|||
return false;
|
||||
};
|
||||
|
||||
//see: https://www.dropzonejs.com/#configuration
|
||||
var storeUrl = pyroutes.url('repo_commit_comment_attachment_upload',
|
||||
let storeUrl = pyroutes.url('repo_commit_comment_attachment_upload',
|
||||
{'repo_name': templateContext.repo_name,
|
||||
'commit_id': templateContext.commit_data.commit_id})
|
||||
|
||||
var previewTmpl = $(formElement).find('.comment-attachment-uploader-template').get(0);
|
||||
let previewTmpl = $(formElement).find('.comment-attachment-uploader-template').get(0);
|
||||
if (previewTmpl !== undefined){
|
||||
var selectLink = $(formElement).find('.pick-attachment').get(0);
|
||||
$(formElement).find('.comment-attachment-uploader').dropzone({
|
||||
url: storeUrl,
|
||||
headers: {"X-CSRF-Token": CSRF_TOKEN},
|
||||
paramName: function () {
|
||||
return "attachment"
|
||||
}, // The name that will be used to transfer the file
|
||||
clickable: selectLink,
|
||||
parallelUploads: 1,
|
||||
maxFiles: 10,
|
||||
maxFilesize: templateContext.attachment_store.max_file_size_mb,
|
||||
uploadMultiple: false,
|
||||
autoProcessQueue: true, // if false queue will not be processed automatically.
|
||||
createImageThumbnails: false,
|
||||
previewTemplate: previewTmpl.innerHTML,
|
||||
let $uploader = $(formElement).find('.comment-attachment-uploader');
|
||||
let inputElement = $uploader.find('.comment-attachment-input')[0];
|
||||
let selectLink = $(formElement).find('.pick-attachment').get(0);
|
||||
|
||||
accept: function (file, done) {
|
||||
done();
|
||||
let pond = FilePond.create(inputElement, {
|
||||
name: 'attachment',
|
||||
credits: false,
|
||||
allowMultiple: true,
|
||||
allowRevert: false,
|
||||
maxFiles: 10,
|
||||
maxParallelUploads: 1,
|
||||
maxFileSize: templateContext.attachment_store.max_file_size_mb + 'MB',
|
||||
|
||||
// custom upload so we can send CSRF header etc
|
||||
server: {
|
||||
process: function (fieldName, file, metadata, load, error, progress, abort) {
|
||||
let xhr = new XMLHttpRequest();
|
||||
xhr.open('POST', storeUrl);
|
||||
|
||||
xhr.setRequestHeader('X-CSRF-Token', CSRF_TOKEN);
|
||||
|
||||
let formData = new FormData();
|
||||
formData.append('attachment', file, file.name);
|
||||
|
||||
xhr.upload.onprogress = function (e) {
|
||||
if (e.lengthComputable) {
|
||||
progress(e.loaded, e.loaded, e.total);
|
||||
}
|
||||
};
|
||||
|
||||
xhr.onreadystatechange = function () {
|
||||
if (xhr.readyState !== XMLHttpRequest.DONE) {
|
||||
return;
|
||||
}
|
||||
|
||||
pond.removeFile(file.id); //removes status
|
||||
|
||||
if (xhr.status >= 200 && xhr.status < 300) {
|
||||
load(xhr.responseText);
|
||||
} else {
|
||||
const parsed_resp = JSON.parse(xhr.responseText || '{}');
|
||||
if (parsed_resp.error === '') return;
|
||||
|
||||
const message = (parsed_resp.error || parsed_resp.main || parsed_resp.message || "Unknown error");
|
||||
|
||||
$.Topic('/notifications').publish({
|
||||
message: {
|
||||
message: message,
|
||||
level: "error",
|
||||
force: true
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
xhr.send(formData);
|
||||
|
||||
return {
|
||||
abort: function () {
|
||||
xhr.abort();
|
||||
abort();
|
||||
}
|
||||
};
|
||||
},
|
||||
init: function () {
|
||||
},
|
||||
|
||||
this.on("sending", function (file, xhr, formData) {
|
||||
$(formElement).find('.comment-attachment-uploader').find('.dropzone-text').hide();
|
||||
$(formElement).find('.comment-attachment-uploader').find('.dropzone-upload').show();
|
||||
});
|
||||
// get rid of "tap to undo" etc
|
||||
labelTapToUndo: '',
|
||||
labelTapToRetry: '',
|
||||
labelTapToCancel: ''
|
||||
});
|
||||
|
||||
this.on("success", function (file, response) {
|
||||
$(formElement).find('.comment-attachment-uploader').find('.dropzone-text').show();
|
||||
$(formElement).find('.comment-attachment-uploader').find('.dropzone-upload').hide();
|
||||
|
||||
var isRendered = false;
|
||||
var ext = file.name.split('.').pop();
|
||||
var imageExts = templateContext.attachment_store.image_ext;
|
||||
if (imageExts.indexOf(ext) !== -1){
|
||||
isRendered = true;
|
||||
}
|
||||
|
||||
insertAttachmentText(cm, file.name, response.repo_fqn_access_path, isRendered)
|
||||
});
|
||||
|
||||
this.on("error", function (file, errorMessage, xhr) {
|
||||
$(formElement).find('.comment-attachment-uploader').find('.dropzone-upload').hide();
|
||||
|
||||
var error = null;
|
||||
|
||||
if (xhr !== undefined){
|
||||
var httpStatus = xhr.status + " " + xhr.statusText;
|
||||
if (xhr !== undefined && xhr.status >= 500) {
|
||||
error = httpStatus;
|
||||
}
|
||||
}
|
||||
|
||||
if (error === null) {
|
||||
error = errorMessage.error || errorMessage || httpStatus;
|
||||
}
|
||||
$(file.previewElement).find('.dz-error-message').html('ERROR: {0}'.format(error));
|
||||
|
||||
});
|
||||
}
|
||||
if (selectLink) {
|
||||
$(selectLink).off('click').on('click', function (e) {
|
||||
e.preventDefault();
|
||||
pond.browse();
|
||||
});
|
||||
}
|
||||
|
||||
pond.on('processfile', function (errorObj, file) {
|
||||
if (errorObj) return;
|
||||
|
||||
// success: parse server response
|
||||
let response;
|
||||
try {
|
||||
response = JSON.parse(file.serverId || '{}');
|
||||
} catch (e) {
|
||||
response = null;
|
||||
}
|
||||
if (!response) {
|
||||
return;
|
||||
}
|
||||
|
||||
let filename = file.filename || (file.file && file.file.name) || file.name || '';
|
||||
let ext = filename.split('.').pop();
|
||||
let imageExts = templateContext.attachment_store.image_ext || [];
|
||||
let isRendered = imageExts.indexOf(ext) !== -1;
|
||||
|
||||
pond.removeFile(file.id);
|
||||
|
||||
insertAttachmentText(cm, filename, response.repo_fqn_access_path, isRendered);
|
||||
});
|
||||
}
|
||||
return commentForm;
|
||||
};
|
||||
|
||||
|
|
@ -1318,6 +1358,7 @@ var CommentsController = function() {
|
|||
};
|
||||
|
||||
this.createComment = function(node, f_path, line_no, resolutionComment) {
|
||||
|
||||
self.edit = false;
|
||||
var $node = $(node);
|
||||
var $td = $node.closest('td');
|
||||
|
|
|
|||
|
|
@ -63,8 +63,9 @@ c.template_context['attachment_store'] = {
|
|||
|
||||
## CSS definitions
|
||||
<%def name="css()">
|
||||
<link rel="stylesheet" type="text/css" href="${h.asset('css/style.css', ver=c.rhodecode_version_hash)}" media="screen"/>
|
||||
<link rel="stylesheet" type="text/css" href="${h.asset('css/select2.css', ver=c.rhodecode_version_hash)}" media="screen"/>
|
||||
<link rel="stylesheet" type="text/css" href="${h.asset('css/filepond.css', ver=c.rhodecode_version_hash)}" media="screen"/>
|
||||
<link rel="stylesheet" type="text/css" href="${h.asset('css/style.css', ver='321')}" media="screen"/>
|
||||
## EXTRA FOR CSS
|
||||
${self.css_extra()}
|
||||
</%def>
|
||||
|
|
|
|||
|
|
@ -468,21 +468,14 @@
|
|||
<div class="comment-area-footer comment-attachment-uploader">
|
||||
<div class="toolbar">
|
||||
|
||||
<div class="comment-attachment-text">
|
||||
<div class="dropzone-text">
|
||||
${_("Drag'n Drop files here or")} <span class="link pick-attachment">${_('Choose your files')}</span>.<br>
|
||||
</div>
|
||||
<div class="dropzone-upload" style="display:none">
|
||||
<i class="icon-spin animate-spin"></i> ${_('uploading...')}
|
||||
</div>
|
||||
</div>
|
||||
<div style="display: none" class="comment-attachment-uploader-template"></div>
|
||||
|
||||
## comments dropzone template, empty on purpose
|
||||
<div style="display: none" class="comment-attachment-uploader-template">
|
||||
<div class="dz-file-preview" style="margin: 0">
|
||||
<div class="dz-error-message"></div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- NEW: hidden input that FilePond will enhance -->
|
||||
<input type="file"
|
||||
class="comment-attachment-input"
|
||||
name="attachment"
|
||||
multiple
|
||||
style="display:none" />
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1279,7 +1279,7 @@ def get_comments_for(diff_type, comments, filename, line_version, line_number):
|
|||
};
|
||||
|
||||
var animateText = function (fPath, anchorId) {
|
||||
fPath = Select2.util.escapeMarkup(fPath);
|
||||
fPath = jQuery.fn.select2.defaults.defaults.escapeMarkup(fPath);
|
||||
$('.fpath-placeholder-text').html(contextPrefix + '<a href="#a_' + anchorId + '">' + fPath + '</a>')
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -282,57 +282,104 @@
|
|||
window.location = pyroutes.url('repo_commits', filter);
|
||||
});
|
||||
|
||||
$("#branch_filter").select2({
|
||||
'dropdownAutoWidth': true,
|
||||
'width': 'resolve',
|
||||
'placeholder': "${c.selected_name or _('Branch filter')}",
|
||||
containerCssClass: "drop-menu",
|
||||
dropdownCssClass: "drop-menu-dropdown",
|
||||
query: function(query){
|
||||
var key = 'cache';
|
||||
var cached = cache[key] ;
|
||||
if(cached) {
|
||||
var data = {results: []};
|
||||
//filter results
|
||||
$.each(cached.results, function(){
|
||||
var section = this.text;
|
||||
var children = [];
|
||||
$.each(this.children, function(){
|
||||
if(query.term.length == 0 || this.text.toUpperCase().indexOf(query.term.toUpperCase()) >= 0 ){
|
||||
children.push({'id': this.id, 'text': this.text, 'type': this.type})
|
||||
}
|
||||
});
|
||||
data.results.push({'text': section, 'children': children});
|
||||
query.callback({results: data.results});
|
||||
// make sure we have a cache object
|
||||
window.cache = window.cache || {};
|
||||
var branchCacheKey = 'cache';
|
||||
|
||||
function buildBranchFilterData(term, cached) {
|
||||
var data = { results: [] };
|
||||
term = term || '';
|
||||
|
||||
$.each(cached.results, function () {
|
||||
var section = this.text;
|
||||
var children = [];
|
||||
|
||||
$.each(this.children, function () {
|
||||
if (!term.length || this.text.toUpperCase().indexOf(term.toUpperCase()) >= 0) {
|
||||
children.push({
|
||||
id: this.id,
|
||||
text: this.text,
|
||||
type: this.type
|
||||
});
|
||||
}
|
||||
});
|
||||
}else{
|
||||
$.ajax({
|
||||
|
||||
data.results.push({
|
||||
text: section,
|
||||
children: children
|
||||
});
|
||||
});
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
function ensureBranchFilterData(term, callback) {
|
||||
var cached = cache[branchCacheKey];
|
||||
|
||||
if (cached) {
|
||||
callback(buildBranchFilterData(term, cached));
|
||||
} else {
|
||||
$.ajax({
|
||||
url: pyroutes.url('repo_refs_changelog_data', {'repo_name': '${c.repo_name}'}),
|
||||
data: {},
|
||||
dataType: 'json',
|
||||
type: 'GET',
|
||||
success: function(data) {
|
||||
cache[key] = data;
|
||||
query.callback({results: data.results});
|
||||
success: function (data) {
|
||||
cache[branchCacheKey] = data;
|
||||
callback(buildBranchFilterData(term, data));
|
||||
}
|
||||
})
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
$('#branch_filter').on('change', function(e){
|
||||
var data = $('#branch_filter').select2('data');
|
||||
//type: branch_closed
|
||||
var selected = data.text;
|
||||
var filter = {'repo_name': '${c.repo_name}'};
|
||||
if(data.type == 'branch' || data.type == 'branch_closed'){
|
||||
filter["branch"] = selected;
|
||||
if (data.type == 'branch_closed') {
|
||||
filter["evolve"] = '1';
|
||||
}
|
||||
|
||||
var $branchFilter = $("#branch_filter");
|
||||
|
||||
var preselectedId = $branchFilter.val();
|
||||
var preselectedText = "${c.selected_name or ''}";
|
||||
|
||||
if (preselectedId && preselectedText) {
|
||||
var option = new Option(preselectedText, preselectedId, true, true);
|
||||
$branchFilter.append(option).trigger('change');
|
||||
}
|
||||
|
||||
$branchFilter.select2({
|
||||
dropdownAutoWidth: true,
|
||||
width: "100%",
|
||||
placeholder: "${c.selected_name or _('Branch filter')}",
|
||||
containerCssClass: "drop-menu",
|
||||
dropdownCssClass: "drop-menu-dropdown",
|
||||
|
||||
ajax: {
|
||||
transport: function (params, success, failure) {
|
||||
var term = (params.data && params.data.term) ? params.data.term : '';
|
||||
ensureBranchFilterData(term, function (data) {
|
||||
success(data); // already {results: [...]}
|
||||
});
|
||||
},
|
||||
processResults: function (data/*, params*/) {
|
||||
return data; // passthrough
|
||||
}
|
||||
}
|
||||
else if (data.type == 'book'){
|
||||
});
|
||||
|
||||
$branchFilter.on('select2:select', function (e) {
|
||||
var data = e.params && e.params.data;
|
||||
if (!data) {
|
||||
return;
|
||||
}
|
||||
|
||||
var selected = data.text;
|
||||
var filter = {'repo_name': '${c.repo_name}'};
|
||||
|
||||
if (data.type === 'branch' || data.type === 'branch_closed') {
|
||||
filter["branch"] = selected;
|
||||
if (data.type === 'branch_closed') {
|
||||
filter["evolve"] = '1';
|
||||
}
|
||||
} else if (data.type === 'book') {
|
||||
filter["bookmark"] = selected;
|
||||
}
|
||||
|
||||
window.location = pyroutes.url('repo_commits', filter);
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -44,6 +44,24 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.select2-container--default .select2-selection--single {
|
||||
border-radius: 0 !important;
|
||||
}
|
||||
|
||||
.select2-container--default .select2-selection--single {
|
||||
margin: 0 5px; /* left/right margin */
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
border-radius: 0 !important;
|
||||
}
|
||||
|
||||
.select2-container--default .select2-selection--single .select2-selection__arrow {
|
||||
height: 32px;
|
||||
right: 6px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script type="text/javascript">
|
||||
|
||||
var initFileJS = function () {
|
||||
|
|
@ -207,145 +225,193 @@
|
|||
};
|
||||
|
||||
var initTreeJS = function () {
|
||||
var state = getFileState();
|
||||
getFilesMetadata();
|
||||
var state = getFileState();
|
||||
getFilesMetadata();
|
||||
|
||||
// fuzzy file filter
|
||||
fileBrowserListeners(state.node_list_url, state.url_base);
|
||||
// fuzzy file filter
|
||||
fileBrowserListeners(state.node_list_url, state.url_base);
|
||||
|
||||
// switch to widget
|
||||
var initialCommitData = {
|
||||
at_ref: atRef,
|
||||
id: null,
|
||||
text: '${c.commit.raw_id}',
|
||||
type: 'sha',
|
||||
raw_id: '${c.commit.raw_id}',
|
||||
idx: ${c.commit.idx},
|
||||
files_url: null,
|
||||
};
|
||||
// switch to widget
|
||||
var initialCommitData = {
|
||||
at_ref: atRef,
|
||||
id: null,
|
||||
text: '${c.commit.raw_id}',
|
||||
type: 'sha',
|
||||
raw_id: '${c.commit.raw_id}',
|
||||
idx: ${c.commit.idx},
|
||||
files_url: null
|
||||
};
|
||||
|
||||
// check if we have ref info.
|
||||
var selectedRef = fileTreeRefs[atRef];
|
||||
if (selectedRef !== undefined) {
|
||||
$.extend(initialCommitData, selectedRef)
|
||||
}
|
||||
// check if we have ref info.
|
||||
var selectedRef = fileTreeRefs[atRef];
|
||||
if (selectedRef !== undefined) {
|
||||
$.extend(initialCommitData, selectedRef);
|
||||
}
|
||||
|
||||
var loadUrl = pyroutes.url('repo_refs_data', {'repo_name': templateContext.repo_name});
|
||||
var cacheKey = '__ALL_FILE_REFS__';
|
||||
var cachedDataSource = {};
|
||||
var loadUrl = pyroutes.url('repo_refs_data', {repo_name: templateContext.repo_name});
|
||||
var cacheKey = '__ALL_FILE_REFS__';
|
||||
var cachedDataSource = {};
|
||||
|
||||
var loadRefsData = function (query) {
|
||||
$.ajax({
|
||||
url: loadUrl,
|
||||
data: {},
|
||||
dataType: 'json',
|
||||
type: 'GET',
|
||||
success: function (data) {
|
||||
cachedDataSource[cacheKey] = data;
|
||||
query.callback({results: data.results});
|
||||
}
|
||||
});
|
||||
};
|
||||
/**
|
||||
* Build filtered data (similar to old feedRefsData) based on term and cached data.
|
||||
*/
|
||||
var buildFilteredRefsData = function (term, cachedData) {
|
||||
var data = {results: []};
|
||||
term = term || '';
|
||||
|
||||
var feedRefsData = function (query, cachedData) {
|
||||
var data = {results: []};
|
||||
//filter results
|
||||
$.each(cachedData.results, function () {
|
||||
var section = this.text;
|
||||
var children = [];
|
||||
$.each(this.children, function () {
|
||||
if (query.term.length === 0 || this.text.toUpperCase().indexOf(query.term.toUpperCase()) >= 0) {
|
||||
children.push(this)
|
||||
}
|
||||
});
|
||||
data.results.push({
|
||||
'text': section,
|
||||
'children': children
|
||||
})
|
||||
});
|
||||
// filter results
|
||||
$.each(cachedData.results, function () {
|
||||
var section = this.text;
|
||||
var children = [];
|
||||
|
||||
//push the typed in commit idx
|
||||
if (!isNaN(query.term)) {
|
||||
var files_url = pyroutes.url('repo_files',
|
||||
{'repo_name': templateContext.repo_name,
|
||||
'commit_id': query.term, 'f_path': state.f_path});
|
||||
|
||||
data.results.push({
|
||||
'text': _gettext('go to numeric commit'),
|
||||
'children': [{
|
||||
at_ref: null,
|
||||
id: null,
|
||||
text: 'r{0}'.format(query.term),
|
||||
type: 'sha',
|
||||
raw_id: query.term,
|
||||
idx: query.term,
|
||||
files_url: files_url,
|
||||
}]
|
||||
});
|
||||
$.each(this.children, function () {
|
||||
if (!term.length || this.text.toUpperCase().indexOf(term.toUpperCase()) >= 0) {
|
||||
children.push(this);
|
||||
}
|
||||
query.callback(data);
|
||||
};
|
||||
|
||||
var select2RefFileSwitcher = function (targetElement, loadUrl, initialData) {
|
||||
var formatResult = function (result, container, query) {
|
||||
return formatSelect2SelectionRefs(result);
|
||||
};
|
||||
|
||||
var formatSelection = function (data, container) {
|
||||
var commit_ref = data;
|
||||
|
||||
var tmpl = '';
|
||||
if (commit_ref.type === 'sha') {
|
||||
tmpl = (commit_ref.raw_id || "").substr(0,8);
|
||||
} else if (commit_ref.type === 'branch') {
|
||||
tmpl = tmpl.concat('<i class="icon-branch"></i> ');
|
||||
tmpl = tmpl.concat(escapeHtml(commit_ref.text));
|
||||
} else if (commit_ref.type === 'tag') {
|
||||
tmpl = tmpl.concat('<i class="icon-tag"></i> ');
|
||||
tmpl = tmpl.concat(escapeHtml(commit_ref.text));
|
||||
} else if (commit_ref.type === 'book') {
|
||||
tmpl = tmpl.concat('<i class="icon-bookmark"></i> ');
|
||||
tmpl = tmpl.concat(escapeHtml(commit_ref.text));
|
||||
}
|
||||
|
||||
var idx = commit_ref.idx || 0;
|
||||
if (idx !== 0) {
|
||||
tmpl = tmpl.concat('<span class="select-index-number">r{0}</span>'.format(idx));
|
||||
}
|
||||
return tmpl
|
||||
};
|
||||
|
||||
$(targetElement).select2({
|
||||
dropdownAutoWidth: true,
|
||||
width: "resolve",
|
||||
containerCssClass: "drop-menu",
|
||||
dropdownCssClass: "drop-menu-dropdown",
|
||||
query: function(query) {
|
||||
|
||||
var cachedData = cachedDataSource[cacheKey];
|
||||
if (cachedData) {
|
||||
feedRefsData(query, cachedData)
|
||||
} else {
|
||||
loadRefsData(query)
|
||||
}
|
||||
},
|
||||
initSelection: function(element, callback) {
|
||||
callback(initialData);
|
||||
},
|
||||
formatResult: formatResult,
|
||||
formatSelection: formatSelection
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
select2RefFileSwitcher('#refs_filter', loadUrl, initialCommitData);
|
||||
|
||||
// switcher for file tree
|
||||
$('#refs_filter').on('change', function(e) {
|
||||
var data = $('#refs_filter').select2('data');
|
||||
window.location = data.files_url
|
||||
data.results.push({
|
||||
text: section,
|
||||
children: children
|
||||
});
|
||||
});
|
||||
|
||||
// push the typed-in commit idx (numeric commit)
|
||||
if (term && !isNaN(term)) {
|
||||
var files_url = pyroutes.url('repo_files', {
|
||||
repo_name: templateContext.repo_name,
|
||||
commit_id: term,
|
||||
f_path: state.f_path
|
||||
});
|
||||
|
||||
data.results.push({
|
||||
text: _gettext('go to numeric commit'),
|
||||
children: [{
|
||||
at_ref: null,
|
||||
id: null,
|
||||
text: 'r{0}'.format(term),
|
||||
type: 'sha',
|
||||
raw_id: term,
|
||||
idx: term,
|
||||
files_url: files_url
|
||||
}]
|
||||
});
|
||||
}
|
||||
|
||||
return data;
|
||||
};
|
||||
|
||||
/**
|
||||
* Ensure refs data is loaded and filtered, then call callback(data).
|
||||
* Replaces old loadRefsData + feedRefsData + query().
|
||||
*/
|
||||
var ensureRefsData = function (term, callback) {
|
||||
var cachedData = cachedDataSource[cacheKey];
|
||||
|
||||
if (cachedData) {
|
||||
var filtered = buildFilteredRefsData(term, cachedData);
|
||||
callback(filtered);
|
||||
} else {
|
||||
$.ajax({
|
||||
url: loadUrl,
|
||||
data: {},
|
||||
dataType: 'json',
|
||||
type: 'GET',
|
||||
success: function (data) {
|
||||
cachedDataSource[cacheKey] = data;
|
||||
var filtered = buildFilteredRefsData(term, data);
|
||||
callback(filtered);
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
var select2RefFileSwitcher = function (targetElement, loadUrl, initialData) {
|
||||
var formatResult = function (result) {
|
||||
return formatSelect2SelectionRefs(result);
|
||||
};
|
||||
|
||||
var formatSelection = function (data) {
|
||||
var commit_ref = data || {};
|
||||
var tmpl = '';
|
||||
|
||||
if (commit_ref.type === 'sha') {
|
||||
tmpl = (commit_ref.raw_id || commit_ref.text || "").substr(0, 8);
|
||||
} else if (commit_ref.type === 'branch') {
|
||||
tmpl = tmpl.concat('<i class="icon-branch"></i> ');
|
||||
tmpl = tmpl.concat(escapeHtml(commit_ref.text || ''));
|
||||
} else if (commit_ref.type === 'tag') {
|
||||
tmpl = tmpl.concat('<i class="icon-tag"></i> ');
|
||||
tmpl = tmpl.concat(escapeHtml(commit_ref.text || ''));
|
||||
} else if (commit_ref.type === 'book') {
|
||||
tmpl = tmpl.concat('<i class="icon-bookmark"></i> ');
|
||||
tmpl = tmpl.concat(escapeHtml(commit_ref.text || ''));
|
||||
} else {
|
||||
// fallback
|
||||
tmpl = escapeHtml(commit_ref.text || '');
|
||||
}
|
||||
|
||||
var idx = commit_ref.idx || 0;
|
||||
if (idx !== 0) {
|
||||
tmpl = tmpl.concat('<span class="select-index-number">r{0}</span>'.format(idx));
|
||||
}
|
||||
return tmpl;
|
||||
};
|
||||
|
||||
var $element = $(targetElement);
|
||||
|
||||
// --- initSelection replacement: pre-populate selected option ---
|
||||
if (initialData) {
|
||||
// Ensure there is an id; Select2 v4 needs an id field
|
||||
if (!initialData.id) {
|
||||
initialData.id = initialData.raw_id || initialData.text;
|
||||
}
|
||||
|
||||
var option = new Option(initialData.text, initialData.id, true, true);
|
||||
// Attach full data object so templateSelection has access to type/raw_id/idx
|
||||
$(option).data('data', initialData);
|
||||
$element.append(option).trigger('change');
|
||||
}
|
||||
|
||||
$element.select2({
|
||||
dropdownAutoWidth: true,
|
||||
width: "100%",
|
||||
containerCssClass: "drop-menu",
|
||||
dropdownCssClass: "drop-menu-dropdown",
|
||||
|
||||
// --- Select2 v4 ajax API instead of "query" ---
|
||||
ajax: {
|
||||
transport: function (params, success, failure) {
|
||||
var term = (params.data && params.data.term) ? params.data.term : '';
|
||||
ensureRefsData(term, function (data) {
|
||||
success(data); // data already in {results: [...] } format
|
||||
});
|
||||
},
|
||||
processResults: function (data /*, params */) {
|
||||
// data is already in the expected {results: [...]} format
|
||||
return data;
|
||||
}
|
||||
},
|
||||
|
||||
// --- v4 template callbacks (replacing formatResult/formatSelection) ---
|
||||
templateResult: formatResult,
|
||||
templateSelection: formatSelection,
|
||||
|
||||
// allow HTML from our templates
|
||||
escapeMarkup: function (markup) { return markup; }
|
||||
});
|
||||
};
|
||||
|
||||
select2RefFileSwitcher('#refs_filter', loadUrl, initialCommitData);
|
||||
|
||||
// switcher for file tree
|
||||
// In v4, prefer the "select2:select" event and e.params.data
|
||||
$('#refs_filter').on('select2:select', function (e) {
|
||||
var data = e.params && e.params.data;
|
||||
if (data && data.files_url) {
|
||||
window.location = data.files_url;
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
$(document).ready(function() {
|
||||
|
|
|
|||
|
|
@ -21,33 +21,6 @@
|
|||
|
||||
<div class="box">
|
||||
## Template for uploads
|
||||
<div style="display: none" id="tpl-dropzone">
|
||||
<div class="dz-preview dz-file-preview">
|
||||
<div class="dz-details">
|
||||
|
||||
<div class="dz-filename">
|
||||
<span data-dz-name></span>
|
||||
</div>
|
||||
<div class="dz-filename-size">
|
||||
<span class="dz-size" data-dz-size></span>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="dz-sending" style="display: none">${_('Uploading...')}</div>
|
||||
<div class="dz-response" style="display: none">
|
||||
${_('Uploaded')} 100%
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="dz-progress">
|
||||
<span class="dz-upload" data-dz-uploadprogress></span>
|
||||
</div>
|
||||
|
||||
<div class="dz-error-message">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="edit-file-title">
|
||||
% if c.replace_binary:
|
||||
<span class="title-heading">${_('Replace content of')} <b>${c.f_path}</b> @ <code>${h.show_id(c.commit)}</code></span>
|
||||
|
|
@ -85,22 +58,14 @@
|
|||
|
||||
<div class="upload-form table">
|
||||
<div>
|
||||
|
||||
<div class="dropzone-wrapper" id="file-uploader" style="border: none; padding: 40px 0">
|
||||
<div class="dropzone-pure">
|
||||
<div class="dz-message">
|
||||
<i class="icon-upload" style="font-size:36px"></i></br>
|
||||
% if not c.replace_binary:
|
||||
${_("Drag'n Drop files here or")} <span class="link">${_('Choose your files')}</span>.<br>
|
||||
% else:
|
||||
${_("Drag'n Drop file here or")} <span class="link">${_('Choose your file')}</span>.<br>
|
||||
% endif
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="filepond-wrapper" style="border: none; padding: 40px 0">
|
||||
<input type="file"
|
||||
id="file-uploader"
|
||||
name="files_upload"
|
||||
multiple
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="upload-form edit-file-fieldset">
|
||||
|
|
@ -113,110 +78,124 @@
|
|||
${h.submit('commit_btn',_('Commit changes'), class_="btn btn-small btn-success")}
|
||||
</div>
|
||||
</div>
|
||||
##${h.end_form()}
|
||||
|
||||
<div class="file-upload-transaction-wrapper" style="display: none">
|
||||
<div class="file-upload-transaction">
|
||||
<h3>${_('Committing...')}</h3>
|
||||
<p>${_('Please wait while the files are being uploaded')}</p>
|
||||
<p class="error" style="display: none">
|
||||
|
||||
</p>
|
||||
<i class="icon-spin animate-spin"></i>
|
||||
<p></p>
|
||||
</div>
|
||||
<div class="file-upload-transaction">
|
||||
<h3>${_('Committing...')}</h3>
|
||||
<p>${_('Please wait while the files are being uploaded')}</p>
|
||||
<p class="error" style="display: none"></p>
|
||||
<i class="icon-spin animate-spin"></i>
|
||||
<p></p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
|
||||
$(document).ready(function () {
|
||||
|
||||
//see: https://www.dropzonejs.com/#configuration
|
||||
myDropzone = new Dropzone("div#file-uploader", {
|
||||
url: "${form_url}",
|
||||
headers: {"X-CSRF-Token": CSRF_TOKEN},
|
||||
paramName: function () {
|
||||
return "files_upload"
|
||||
}, // The name that will be used to transfer the file
|
||||
parallelUploads: 20,
|
||||
// Create FilePond instance
|
||||
const inputElement = document.querySelector('#file-uploader');
|
||||
|
||||
const labelIdleHtml = `
|
||||
<i class="icon-upload" style="font-size:36px"></i><br/>
|
||||
% if not c.replace_binary:
|
||||
${_("Drag'n Drop files here or")} <span class="link">${_('Choose your files')}</span>.<br>
|
||||
% else:
|
||||
${_("Drag'n Drop file here or")} <span class="link">${_('Choose your file')}</span>.<br>
|
||||
% endif
|
||||
`;
|
||||
|
||||
const pond = FilePond.create(inputElement, {
|
||||
allowMultiple: true,
|
||||
maxFiles: 20,
|
||||
uploadMultiple: true,
|
||||
//chunking: true, // use chunking transfer, not supported at the moment
|
||||
//maxFilesize: 2, // in MBs
|
||||
autoProcessQueue: false, // if false queue will not be processed automatically.
|
||||
createImageThumbnails: false,
|
||||
previewTemplate: document.querySelector('#tpl-dropzone').innerHTML,
|
||||
accept: function (file, done) {
|
||||
done();
|
||||
},
|
||||
init: function () {
|
||||
this.on("addedfile", function (file) {
|
||||
instantUpload: false,
|
||||
credits: false,
|
||||
allowFileMetadata: false,
|
||||
labelIdle: labelIdleHtml,
|
||||
|
||||
});
|
||||
|
||||
this.on("sending", function (file, xhr, formData) {
|
||||
formData.append("message", $('#commit').val());
|
||||
$(file.previewElement).find('.dz-sending').show();
|
||||
});
|
||||
|
||||
this.on("success", function (file, response) {
|
||||
$(file.previewElement).find('.dz-sending').hide();
|
||||
$(file.previewElement).find('.dz-response').show();
|
||||
|
||||
if (response.error !== null) {
|
||||
$('.file-upload-transaction-wrapper .error').html('ERROR: {0}'.format(response.error));
|
||||
$('.file-upload-transaction-wrapper .error').show();
|
||||
$('.file-upload-transaction-wrapper i').hide()
|
||||
}
|
||||
|
||||
var redirect_url = response.redirect_url || '/';
|
||||
window.location = redirect_url
|
||||
|
||||
});
|
||||
|
||||
this.on("error", function (file, errorMessage, xhr) {
|
||||
var error = null;
|
||||
|
||||
if (xhr !== undefined){
|
||||
var httpStatus = xhr.status + " " + xhr.statusText;
|
||||
if (xhr !== undefined && xhr.status >= 500) {
|
||||
error = httpStatus;
|
||||
server: {
|
||||
process: {
|
||||
url: "${form_url}",
|
||||
method: "POST",
|
||||
withCredentials: false,
|
||||
headers: {
|
||||
"X-CSRF-Token": CSRF_TOKEN
|
||||
},
|
||||
ondata: function (formData) {
|
||||
formData.append("message", $('#commit').val());
|
||||
return formData;
|
||||
},
|
||||
onload: function (responseText) {
|
||||
let response = null;
|
||||
try {
|
||||
response = JSON.parse(responseText);
|
||||
} catch (e) {
|
||||
console.error("Invalid JSON response from upload", e, responseText);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
if (error === null) {
|
||||
error = errorMessage.error || errorMessage || httpStatus;
|
||||
}
|
||||
if (response.error !== null && response.error !== undefined) {
|
||||
$('.file-upload-transaction-wrapper .error').html(
|
||||
'ERROR: {0}'.format(response.error)
|
||||
);
|
||||
$('.file-upload-transaction-wrapper .error').show();
|
||||
$('.file-upload-transaction-wrapper i').hide();
|
||||
}
|
||||
|
||||
$(file.previewElement).find('.dz-error-message').html('ERROR: {0}'.format(error));
|
||||
});
|
||||
let redirect_url = response.redirect_url || '/';
|
||||
window.location = redirect_url;
|
||||
|
||||
return response.file_id || null;
|
||||
},
|
||||
onerror: function (responseText) {
|
||||
let error = 'Upload error';
|
||||
try {
|
||||
let data = JSON.parse(responseText);
|
||||
if (data && data.error) {
|
||||
error = data.error;
|
||||
}
|
||||
} catch (e) {
|
||||
// response not JSON, ignore
|
||||
}
|
||||
|
||||
$('.file-upload-transaction-wrapper .error').html(
|
||||
'ERROR: {0}'.format(error)
|
||||
);
|
||||
$('.file-upload-transaction-wrapper .error').show();
|
||||
$('.file-upload-transaction-wrapper i').hide();
|
||||
|
||||
return error;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
$('#commit_btn').on('click', function(e) {
|
||||
$('#commit_btn').on('click', function (e) {
|
||||
e.preventDefault();
|
||||
var button = $(this);
|
||||
|
||||
let button = $(this);
|
||||
if (button.hasClass('clicked')) {
|
||||
button.attr('disabled', true);
|
||||
} else {
|
||||
button.addClass('clicked');
|
||||
}
|
||||
|
||||
var files = myDropzone.getQueuedFiles();
|
||||
let files = pond.getFiles();
|
||||
if (files.length === 0) {
|
||||
alert("Missing files");
|
||||
e.preventDefault();
|
||||
// reset button state to allow retry
|
||||
button.removeClass('clicked').attr('disabled', false);
|
||||
return;
|
||||
}
|
||||
|
||||
$('.upload-form').hide();
|
||||
$('.file-upload-transaction-wrapper').show();
|
||||
myDropzone.processQueue();
|
||||
|
||||
// start uploading all files in the pond
|
||||
pond.processFiles();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
</script>
|
||||
</%def>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue