allow uploading/deleting multiple documents, fixes #1960. replace select option with item aware add button, fixes #1961
This commit is contained in:
parent
3899ce00f2
commit
19b8bcfc83
5 changed files with 135 additions and 109 deletions
|
@ -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']):
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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() {
|
||||||
|
|
|
@ -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});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue