allow uploading/deleting multiple documents, fixes #1960. replace select option with item aware add button, fixes #1961

This commit is contained in:
j 2014-01-02 10:11:27 +00:00
parent 3899ce00f2
commit 19b8bcfc83
5 changed files with 135 additions and 109 deletions

View file

@ -250,6 +250,7 @@ def upload(request):
chunk_id = form.cleaned_data['chunkId'] chunk_id = form.cleaned_data['chunkId']
response = { response = {
'result': 1, 'result': 1,
'id': file.get_id(),
'resultUrl': request.build_absolute_uri(file.get_absolute_url()) 'resultUrl': request.build_absolute_uri(file.get_absolute_url())
} }
if not file.save_chunk(c, chunk_id, form.cleaned_data['done']): if not file.save_chunk(c, chunk_id, form.cleaned_data['done']):

View file

@ -1,13 +1,13 @@
// vim: et:ts=4:sw=4:sts=4:ft=javascript // vim: et:ts=4:sw=4:sts=4:ft=javascript
'use strict'; 'use strict';
pandora.ui.deleteDocumentDialog = function(file, callback) { pandora.ui.deleteDocumentDialog = function(files, callback) {
var that = pandora.ui.iconDialog({ var that = pandora.ui.iconDialog({
buttons: [ buttons: [
Ox.Button({ Ox.Button({
id: 'keep', id: 'keep',
title: Ox._('Keep Document') title: files.length == 1 ? Ox._('Keep Document') : Ox._('Keep Documents')
}).bindEvent({ }).bindEvent({
click: function() { click: function() {
that.close(); that.close();
@ -15,19 +15,21 @@ pandora.ui.deleteDocumentDialog = function(file, callback) {
}), }),
Ox.Button({ Ox.Button({
id: 'delete', id: 'delete',
title: Ox._('Delete Document') title: files.length == 1 ? Ox._('Delete Document') : Ox._('Delete Documents')
}).bindEvent({ }).bindEvent({
click: function() { click: function() {
that.close(); that.close();
pandora.api.removeDocument({ pandora.api.removeDocument({
id: file ids: files
}, callback); }, callback);
} }
}) })
], ],
content: Ox._('Are you sure you want to delete the document "{0}"?', [file]), content: files.length == 1
? Ox._('Are you sure you want to delete the document "{0}"?', [files[0]])
: Ox._('Are you sure you want to delete {0} documents?', [files.length]),
keys: {enter: 'delete', escape: 'keep'}, keys: {enter: 'delete', escape: 'keep'},
title: Ox._('Delete Document') title: files.length == 1 ? Ox._('Delete Document') : Ox._('Delete {0} Documents', [files.length])
}); });
return that; return that;

View file

@ -2,9 +2,7 @@
'use strict'; 'use strict';
pandora.ui.documentsDialog = function(options) { pandora.ui.documentsDialog = function() {
options = options || {};
var dialogHeight = Math.round((window.innerHeight - 48) * 0.9), var dialogHeight = Math.round((window.innerHeight - 48) * 0.9),
dialogWidth = Math.round(window.innerWidth * 0.9), dialogWidth = Math.round(window.innerWidth * 0.9),
itemWidth = 272 + Ox.UI.SCROLLBAR_SIZE, itemWidth = 272 + Ox.UI.SCROLLBAR_SIZE,
@ -155,6 +153,7 @@ pandora.ui.documentsDialog = function(options) {
unique: 'id' unique: 'id'
}) })
.bindEvent({ .bindEvent({
'delete': deleteDocuments,
init: function(data) { init: function(data) {
$status.html( $status.html(
Ox.toTitleCase(Ox.formatCount(data.items, 'file')) Ox.toTitleCase(Ox.formatCount(data.items, 'file'))
@ -165,10 +164,8 @@ pandora.ui.documentsDialog = function(options) {
}, },
select: function(data) { select: function(data) {
selected = data.ids[0]; selected = data.ids[0];
$addButton.options({disabled: data.ids.length == 0});
selectFile(); selectFile();
options.callback && $doneButton.options({
disabled: !data.ids.length
});
} }
}), }),
@ -219,30 +216,36 @@ pandora.ui.documentsDialog = function(options) {
.css({float: 'left', margin: '4px'}) .css({float: 'left', margin: '4px'})
.hide() .hide()
.bindEvent({ .bindEvent({
click: deleteFile click: deleteDocuments
}) })
.appendTo($itemToolbar), .appendTo($itemToolbar),
$addButton = Ox.Button({
disabled: true,
id: 'add',
title: Ox._('Add'),
width: 48
}).bindEvent({
click: addDocuments
}),
$doneButton = Ox.Button({ $doneButton = Ox.Button({
disabled: !!options.callback,
id: 'done', id: 'done',
title: options.callback ? Ox._('Select') : Ox._('Done'), title: Ox._('Done'),
width: 48 width: 48
}).bindEvent({ }).bindEvent({
click: function() { click: function() {
options.callback && options.callback($list.options('selected'));
that.close(); that.close();
} }
}), }),
$uploadButton = Ox.FileButton({ $uploadButton = Ox.FileButton({
maxFiles: 1, title: Ox._('Upload Documents...'),
title: Ox._('Upload Document...'),
width: 128 width: 128
}) })
.css({float: 'right', margin: '4px'}) .css({float: 'right', margin: '4px'})
.bindEvent({ .bindEvent({
click: uploadFile click: uploadDocuments
}) })
.appendTo($itemToolbar), .appendTo($itemToolbar),
@ -309,7 +312,7 @@ pandora.ui.documentsDialog = function(options) {
}), }),
that = Ox.Dialog({ that = Ox.Dialog({
buttons: [$doneButton], buttons: pandora.user.ui.item ? [$addButton, $doneButton] : [$doneButton],
closeButton: true, closeButton: true,
content: $content, content: $content,
height: dialogHeight, height: dialogHeight,
@ -341,9 +344,24 @@ pandora.ui.documentsDialog = function(options) {
that.superClose(); that.superClose();
}; };
function deleteFile() { function addDocuments() {
pandora.ui.deleteDocumentDialog($list.options('selected')[0], function() { pandora.api.addDocument({
Ox.Request.clearCache('findDocuments'); item: pandora.user.ui.item,
ids: $list.options('selected')
}, function() {
Ox.Request.clearCache();
if (pandora.user.ui.itemView == 'documents') {
//fixme just upload list here
//self.$documentsList.reloadList();
pandora.$ui.contentPanel.replaceElement(1,
pandora.$ui.item = pandora.ui.item());
}
});
}
function deleteDocuments() {
pandora.ui.deleteDocumentDialog($list.options('selected'), function() {
Ox.Request.clearCache(pandora.user.ui.item ? void 0 : 'findDocuments');
$list.reloadList(); $list.reloadList();
}).open(); }).open();
} }
@ -528,28 +546,18 @@ pandora.ui.documentsDialog = function(options) {
} : query}); } : query});
} }
function uploadFile(data) { function uploadDocuments(data) {
pandora.ui.uploadDocumentDialog(data.files[0], function(file) { pandora.ui.uploadDocumentDialog(data.files, function(files) {
Ox.Request.clearCache('findDocuments'); if (files) {
pandora.api.findDocuments({ Ox.Request.clearCache('findDocuments');
positions: [file.id],
query: $list.options('query'),
sort: $list.options('sort'),
}, function(data) {
$list.bindEventOnce({ $list.bindEventOnce({
load: function() { load: function() {
$list.options({selected: [file.id]}); $list.options({selected: [files.ids]});
// selectFile(file.id); // selectFile(file.id);
} }
}); });
if (data.data.positions[file.id] > -1) { $list.reloadList();
$list.reloadList(); }
} else {
$list.options({
query: {conditions: [], operator: '&'}
});
}
});
}).open(); }).open();
} }

View file

@ -148,22 +148,7 @@ pandora.ui.documentsView = function(options, self) {
}); });
function addDocuments() { function addDocuments() {
pandora.$ui.documentsDialog = pandora.ui.documentsDialog({ pandora.$ui.documentsDialog = pandora.ui.documentsDialog().open();
callback: function(ids) {
if (ids) {
pandora.api.addDocument({
item: pandora.user.ui.item,
ids: ids
}, function() {
Ox.Request.clearCache();
//fixme just upload list here
//self.$documentsList.reloadList();
pandora.$ui.contentPanel.replaceElement(1,
pandora.$ui.item = pandora.ui.item());
});
}
}
}).open();
} }
function renderPreview() { function renderPreview() {

View file

@ -1,16 +1,17 @@
// vim: et:ts=4:sw=4:sts=4:ft=javascript // vim: et:ts=4:sw=4:sts=4:ft=javascript
'use strict'; 'use strict';
pandora.ui.uploadDocumentDialog = function(file, callback) { pandora.ui.uploadDocumentDialog = function(files, callback) {
var extension = file.name.split('.').pop().toLowerCase(), var extensions = files.map(function(file) {
return file.name.split('.').pop().toLowerCase()
}),
extensions = ['gif', 'jpg', 'jpeg', 'pdf', 'png'], supportedExtensions = ['gif', 'jpg', 'jpeg', 'pdf', 'png'],
filename = file.name.split('.').slice(0, -1).join('.') + '.' filename,
+ (extension == 'jpeg' ? 'jpg' : extension),
id = pandora.user.username + ':' + filename, ids = [],
upload, upload,
@ -19,7 +20,7 @@ pandora.ui.uploadDocumentDialog = function(file, callback) {
$content = Ox.Element().css({margin: '16px'}), $content = Ox.Element().css({margin: '16px'}),
$text = $('<div>') $text = $('<div>')
.html(Ox._('Uploading {0}', [file.name])) .html(Ox._('Uploading {0}', [files[0].name]))
.appendTo($content), .appendTo($content),
$progress = Ox.Progressbar({ $progress = Ox.Progressbar({
@ -43,10 +44,10 @@ pandora.ui.uploadDocumentDialog = function(file, callback) {
var title = this.options('title'); var title = this.options('title');
$uploadDialog.close(); $uploadDialog.close();
if (title == Ox._('Cancel Upload')) { if (title == Ox._('Cancel Upload')) {
upload.abort(); upload && upload.abort();
} else if (title == Ox._('Done')) { } else if (title == Ox._('Done')) {
callback({ callback({
id: id ids: ids
}); });
} }
} }
@ -56,57 +57,49 @@ pandora.ui.uploadDocumentDialog = function(file, callback) {
height: 112, height: 112,
keys: {escape: 'close'}, keys: {escape: 'close'},
width: 288, width: 288,
title: Ox._('Upload File') title: files.length == 1
? Ox._('Upload Document')
: Ox._('Upload {0} Documents', [files.length])
}) })
.bindEvent({ .bindEvent({
open: function() { open: function() {
upload = pandora.chunkupload({ uploadFile(0);
data: {
filename: filename
},
file: file,
url: '/api/upload/document/',
})
.bindEvent({
done: function(data) {
if (data.progress == 1) {
$uploadDialog.options('buttons')[0].options({title: Ox._('Done')});
Ox.print('SUCCEEDED');
} else {
$message.html(Ox._('Upload failed.'))
$uploadDialog.options('buttons')[0].options({title: Ox._('Close')});
Ox.print('FAILED');
}
},
progress: function(data) {
$progress.options({progress: data.progress || 0});
}
});
} }
}); });
if (!Ox.contains(extensions, extension)) { if (!Ox.every(extensions, function(extension) {
return Ox.contains(supportedExtensions, extension)
})) {
return errorDialog(Ox._('Supported file types are GIF, JPG, PNG and PDF.')); return errorDialog(Ox._('Supported file types are GIF, JPG, PNG and PDF.'));
} else { } else {
Ox.oshash(file, function(oshash) { var valid = true;
pandora.api.findDocuments({ Ox.parallelForEach(files, function(file, index, array, callback) {
keys: ['id'], var extension = file.name.split('.').pop().toLowerCase(),
query: { filename = file.name.split('.').slice(0, -1).join('.') + '.'
conditions: [{key: 'oshash', value: oshash, operator: '=='}], + (extension == 'jpeg' ? 'jpg' : extension);
operator: '&' valid && Ox.oshash(file, function(oshash) {
}, pandora.api.findDocuments({
range: [0, 1], keys: ['id', 'user', 'name', 'extension'],
sort: [{key: 'name', operator: '+'}] query: {
}, function(result) { conditions: [{key: 'oshash', value: oshash, operator: '=='}],
if (result.data.items.length) { operator: '&'
errorDialog(filename == result.data.items[0].id },
? Ox._('The file {0} already exists', [filename]) range: [0, 1],
: Ox._('The file {0} already exists as {1}', [filename, result.data.items[0].id]) sort: [{key: 'name', operator: '+'}]
).open(); }, function(result) {
} else { if (result.data.items.length) {
$uploadDialog.open(); var id = result.data.items[0].name + '.' + result.data.items[0].extension;
} valid && errorDialog(filename == id
}) ? Ox._('The file {0} already exists', [filename])
: Ox._('The file {0} already exists as {1}', [filename, id])
).open();
valid = false;
}
callback();
})
});
} ,function() {
valid && $uploadDialog.open();
}); });
return {open: Ox.noop}; return {open: Ox.noop};
} }
@ -125,9 +118,46 @@ pandora.ui.uploadDocumentDialog = function(file, callback) {
}) })
], ],
content: text, content: text,
title: Ox._('Upload File') title: Ox._('Upload Document')
}); });
} }
function uploadFile(part) {
var file = files[part],
extension = file.name.split('.').pop().toLowerCase(),
filename = file.name.split('.').slice(0, -1).join('.') + '.'
+ (extension == 'jpeg' ? 'jpg' : extension);
$text.html(Ox._('Uploading {0}', [file.name]));
upload = pandora.chunkupload({
data: {
filename: filename
},
file: file,
url: '/api/upload/document/',
})
.bindEvent({
done: function(data) {
if (data.progress == 1) {
part++;
if (part == files.length) {
$progress.options({progress: data.progress});
$uploadDialog.options('buttons')[0].options({title: Ox._('Done')});
ids.push(data.id);
} else {
uploadFile(part);
}
} else {
$message.html(Ox._('Upload failed.'))
$uploadDialog.options('buttons')[0].options({title: Ox._('Close')});
}
},
progress: function(data) {
var progress = data.progress || 0;
progress = part/files.length + 1/files.length * progress;
$progress.options({progress: progress});
}
});
}
}; };