add file dialogs
This commit is contained in:
parent
06500c7e29
commit
2b599e3ef4
3 changed files with 610 additions and 0 deletions
40
static/js/pandora/deleteFileDialog.js
Normal file
40
static/js/pandora/deleteFileDialog.js
Normal file
|
@ -0,0 +1,40 @@
|
|||
// vim: et:ts=4:sw=4:sts=4:ft=javascript
|
||||
'use strict';
|
||||
|
||||
pandora.ui.deleteFileDialog = function(file, callback) {
|
||||
|
||||
var that = pandora.ui.iconDialog({
|
||||
buttons: [
|
||||
Ox.Button({
|
||||
id: 'keep',
|
||||
title: 'Keep File'
|
||||
}).bindEvent({
|
||||
click: function() {
|
||||
that.close();
|
||||
}
|
||||
}),
|
||||
Ox.Button({
|
||||
id: 'delete',
|
||||
title: 'Delete File'
|
||||
}).bindEvent({
|
||||
click: function() {
|
||||
that.close();
|
||||
pandora.api.removeFile({
|
||||
id: file.id
|
||||
}, function(result) {
|
||||
Ox.Request.clearCache('findFiles');
|
||||
callback();
|
||||
});
|
||||
}
|
||||
})
|
||||
],
|
||||
keys: {enter: 'delete', escape: 'keep'},
|
||||
text: 'Are you sure you want to delete the file'
|
||||
+ ' "'+ item.filename + '"?',
|
||||
title: 'Delete File'
|
||||
});
|
||||
|
||||
return that;
|
||||
|
||||
};
|
||||
|
445
static/js/pandora/filesDialog.js
Normal file
445
static/js/pandora/filesDialog.js
Normal file
|
@ -0,0 +1,445 @@
|
|||
// vim: et:ts=4:sw=4:sts=4:ft=javascript
|
||||
|
||||
'use strict';
|
||||
|
||||
pandora.ui.filesDialog = function() {
|
||||
|
||||
var dialogHeight = Math.round((window.innerHeight - 48) * 0.9),
|
||||
dialogWidth = Math.round(window.innerWidth * 0.9),
|
||||
formWidth = 272 + Ox.UI.SCROLLBAR_SIZE,
|
||||
|
||||
$findSelect = Ox.Select({
|
||||
items: [
|
||||
{id: 'all', title: 'Find: All'},
|
||||
{id: 'username', title: 'Find: Username'},
|
||||
{id: 'filename', title: 'Find: Filename'}
|
||||
],
|
||||
overlap: 'right',
|
||||
type: 'image'
|
||||
})
|
||||
.bindEvent({
|
||||
change: function(data) {
|
||||
$findInput.value() && updateList();
|
||||
$findInput.options({placeholder: data.title});
|
||||
}
|
||||
}),
|
||||
|
||||
$findInput = Ox.Input({
|
||||
changeOnKeypress: true,
|
||||
clear: true,
|
||||
placeholder: 'Find: All',
|
||||
width: 192
|
||||
})
|
||||
.bindEvent({
|
||||
change: updateList
|
||||
}),
|
||||
|
||||
$findElement = Ox.FormElementGroup({
|
||||
elements: [
|
||||
$findSelect,
|
||||
$findInput
|
||||
]
|
||||
})
|
||||
.css({float: 'right', margin: '4px'}),
|
||||
|
||||
$list = Ox.TableList({
|
||||
columns: [
|
||||
{
|
||||
id: 'username',
|
||||
operator: '+',
|
||||
title: 'Username',
|
||||
visible: true,
|
||||
width: 128
|
||||
},
|
||||
{
|
||||
align: 'right',
|
||||
format: function(value) {
|
||||
return value.split('.').slice(0, -1).join('.')
|
||||
},
|
||||
id: 'filename',
|
||||
operator: '+',
|
||||
title: 'Filename',
|
||||
visible: true,
|
||||
width: 192
|
||||
},
|
||||
{
|
||||
format: function(value) {
|
||||
return value.split('.').pop();
|
||||
},
|
||||
id: 'extension',
|
||||
operator: '+',
|
||||
title: 'Extension',
|
||||
visible: true,
|
||||
width: 64
|
||||
},
|
||||
{
|
||||
format: function(value) {
|
||||
return Ox.formatValue(value, 'B');
|
||||
},
|
||||
id: 'size',
|
||||
operator: '-',
|
||||
title: 'Size',
|
||||
visible: true,
|
||||
width: 64
|
||||
},
|
||||
{
|
||||
id: 'description',
|
||||
operator: '+',
|
||||
title: 'Description',
|
||||
visible: true,
|
||||
width: 192
|
||||
},
|
||||
{
|
||||
align: 'right',
|
||||
format: function(value) {
|
||||
return Ox.formatDate(value, '%F %T');
|
||||
},
|
||||
id: 'created',
|
||||
operator: '-',
|
||||
title: 'Created',
|
||||
visible: true,
|
||||
width: 144
|
||||
},
|
||||
{
|
||||
align: 'right',
|
||||
format: function(value) {
|
||||
return Ox.formatDate(value, '%F %T');
|
||||
},
|
||||
id: 'modified',
|
||||
operator: '-',
|
||||
title: 'Modified',
|
||||
visible: true,
|
||||
width: 144
|
||||
},
|
||||
{
|
||||
align: 'right',
|
||||
id: 'matches',
|
||||
operator: '-',
|
||||
title: 'Matches',
|
||||
visible: true,
|
||||
width: 64
|
||||
}
|
||||
],
|
||||
columnsVisible: true,
|
||||
items: pandora.api.findFiles,
|
||||
query: {
|
||||
conditions: pandora.user.ui.showAllFiles ? [] : [
|
||||
{key: 'username', value: pandora.user.username, operator: '=='}
|
||||
],
|
||||
operator: '&'
|
||||
},
|
||||
scrollbarVisible: true,
|
||||
sort: [{key: 'username', operator: '+'}],
|
||||
unique: 'id'
|
||||
})
|
||||
.bindEvent({
|
||||
init: function(data) {
|
||||
$status.html(
|
||||
Ox.formatNumber(data.items)
|
||||
+ ' file' + (data.items == 1 ? '' : 's')
|
||||
);
|
||||
},
|
||||
select: selectFile
|
||||
}),
|
||||
|
||||
$formLabel = Ox.Label({
|
||||
textAlign: 'center',
|
||||
title: 'No file selected',
|
||||
width: 212
|
||||
})
|
||||
.css({float: 'left', margin: '4px 2px 4px 4px'}),
|
||||
|
||||
$formElement = Ox.Element().css({overflowY: 'scroll'}),
|
||||
|
||||
$form,
|
||||
|
||||
$formToolbar = Ox.Bar({size: 24}),
|
||||
|
||||
$deleteButton = Ox.Button({
|
||||
title: 'Delete File...'
|
||||
})
|
||||
.css({margin: '4px'})
|
||||
.hide()
|
||||
.bindEvent({
|
||||
click: deleteFile
|
||||
})
|
||||
.appendTo($formToolbar),
|
||||
|
||||
$uploadButton = Ox.FileButton({
|
||||
maxFiles: 1,
|
||||
title: 'Upload File...'
|
||||
})
|
||||
.css({align: 'right', margin: '4px'})
|
||||
.bindEvent({
|
||||
click: uploadFile
|
||||
})
|
||||
.appendTo($formToolbar)
|
||||
|
||||
$content = Ox.SplitPanel({
|
||||
elements: [
|
||||
{
|
||||
element: Ox.SplitPanel({
|
||||
elements: [
|
||||
{
|
||||
element: Ox.Bar({size: 24})
|
||||
.append($findElement),
|
||||
size: 24
|
||||
},
|
||||
{
|
||||
element: $list
|
||||
}
|
||||
],
|
||||
orientation: 'vertical'
|
||||
})
|
||||
},
|
||||
{
|
||||
element: Ox.SplitPanel({
|
||||
elements: [
|
||||
{
|
||||
element: Ox.Bar({size: 24})
|
||||
.append($formLabel),
|
||||
size: 24
|
||||
},
|
||||
{
|
||||
element: $form
|
||||
},
|
||||
{
|
||||
element: $toolbar,
|
||||
size: 24
|
||||
}
|
||||
],
|
||||
orientation: 'vertical'
|
||||
})
|
||||
.bindEvent({
|
||||
resize: setWidth
|
||||
}),
|
||||
resizable: true,
|
||||
resize: [256, 384, 512],
|
||||
size: 256
|
||||
}
|
||||
],
|
||||
orientation: 'horizontal'
|
||||
}),
|
||||
|
||||
that = Ox.Dialog({
|
||||
buttons: [
|
||||
Ox.Button({
|
||||
id: 'done',
|
||||
title: 'Done',
|
||||
width: 48
|
||||
}).bindEvent({
|
||||
click: function() {
|
||||
that.close();
|
||||
}
|
||||
})
|
||||
],
|
||||
closeButton: true,
|
||||
content: $content,
|
||||
height: dialogHeight,
|
||||
maximizeButton: true,
|
||||
minHeight: 256,
|
||||
minWidth: 512,
|
||||
padding: 0,
|
||||
removeOnClose: true,
|
||||
title: 'Manage Users',
|
||||
width: dialogWidth
|
||||
})
|
||||
.bindEvent({
|
||||
resize: setHeight
|
||||
}),
|
||||
|
||||
$status = $('<div>')
|
||||
.css({
|
||||
position: 'absolute',
|
||||
top: '4px',
|
||||
left: '128px',
|
||||
right: '384px',
|
||||
bottom: '4px',
|
||||
paddingTop: '2px',
|
||||
fontSize: '9px',
|
||||
textAlign: 'center'
|
||||
})
|
||||
.appendTo(that.find('.OxButtonsbar'));
|
||||
|
||||
that.superClose = that.close;
|
||||
that.close = function() {
|
||||
Ox.Request.clearCache('findFiles');
|
||||
that.superClose();
|
||||
};
|
||||
|
||||
function deleteFile() {
|
||||
pandora.ui.deleteFileDialog(function() {
|
||||
// ...
|
||||
}).open();
|
||||
}
|
||||
|
||||
function getFormItemById(id) {
|
||||
var ret;
|
||||
Ox.forEach((
|
||||
$formButton.value() == 'edit' ? $editForm : $mailForm
|
||||
).options('items'), function($item) {
|
||||
if ($item.options('id') == id) {
|
||||
ret = $item;
|
||||
return false;
|
||||
}
|
||||
});
|
||||
return ret;
|
||||
};
|
||||
|
||||
function renderForm(id) {
|
||||
var file = $list.value(id),
|
||||
editable = file.username == pandora.user.username
|
||||
|| pandora.site.capabilities.canEditFiles[pandora.user.level];
|
||||
return Ox.Form({
|
||||
items: [
|
||||
Ox.Input({
|
||||
disabled: true,
|
||||
id: 'username',
|
||||
label: 'Username',
|
||||
labelWidth: 80,
|
||||
value: file.username,
|
||||
width: formWidth - 16
|
||||
}),
|
||||
Ox.Input({
|
||||
disabled: !editable,
|
||||
id: 'filename',
|
||||
label: 'Filename',
|
||||
labelWidth: 80,
|
||||
value: file.filename,
|
||||
width: formWidth - 16
|
||||
}),
|
||||
Ox.Input({
|
||||
disabled: true,
|
||||
id: 'extension',
|
||||
label: 'Extension',
|
||||
labelWidth: 80,
|
||||
value: file.extension,
|
||||
width: formWidth - 16
|
||||
}),
|
||||
Ox.Input({
|
||||
disabled: true,
|
||||
id: 'size',
|
||||
label: 'Size',
|
||||
labelWidth: 80,
|
||||
value: Ox.formatValue(file.size, 'B'),
|
||||
width: formWidth - 16
|
||||
}),
|
||||
Ox.Input({
|
||||
disabled: !editable,
|
||||
height: dialogHeight - 184,
|
||||
id: 'description',
|
||||
placeholder: 'Description',
|
||||
type: 'textarea',
|
||||
value: file.description,
|
||||
width: formWidth - 16
|
||||
})
|
||||
],
|
||||
width: 240
|
||||
})
|
||||
.css({margin: '8px'})
|
||||
.bindEvent({
|
||||
change: function(event) {
|
||||
var data = Ox.extend({id: file.id}, event.id, event.data.value);
|
||||
pandora.api.editFile(data, function(result) {
|
||||
$list.value(result.data.id, event.id, result.data[event.id]);
|
||||
if (event.id == 'filename') {
|
||||
$list.value(file.id, 'id', result.data.id);
|
||||
}
|
||||
Ox.Request.clearCache('findFiles');
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function renderPreview(id) {
|
||||
var isImage = Ox.contains(['jpg', 'png'], id.split('.').pop());
|
||||
return $('<img>')
|
||||
.attr({
|
||||
src: '/files/' + id + (isImage ? '' : '.jpg')
|
||||
})
|
||||
.css({
|
||||
maxWidth: formWidth - 16 + 'px',
|
||||
maxHeight: formWidth - 16 + 'px',
|
||||
});
|
||||
}
|
||||
|
||||
function selectFile(id) {
|
||||
var editable = file.username == pandora.user.username
|
||||
|| pandora.site.capabilities.canEditFiles[pandora.user.level];
|
||||
setLabel(id);
|
||||
if (id) {
|
||||
$preview = renderPreview(id).appendTo($formElement);
|
||||
$form = renderForm(id).appendTo($formElement);
|
||||
$deleteButton.options({disabled: !editable}).show();
|
||||
} else {
|
||||
$formElement.empty();
|
||||
$deleteButton.hide();
|
||||
}
|
||||
}
|
||||
|
||||
function setHeight(data) {
|
||||
var $item = getFormItemById('description');
|
||||
$item && $item.options({height: data.height - 160)});
|
||||
}
|
||||
|
||||
function setLabel(id) {
|
||||
$formLabel.options({
|
||||
title: id
|
||||
? id.split(':').slice(1).join(':')
|
||||
: 'No file selected'
|
||||
});
|
||||
}
|
||||
|
||||
function setWidth() {
|
||||
formWidth = $content.size(1);
|
||||
$formLabel.options({width: formWidth - 44});
|
||||
$form && $form.options('items').forEach(function($item) {
|
||||
$item.options({width: formWidth - 16});
|
||||
});
|
||||
$status.css({right: formWidth + 128 + 'px'});
|
||||
}
|
||||
|
||||
function updateList() {
|
||||
var key = $findSelect.value(),
|
||||
value = $findInput.value(),
|
||||
query = {
|
||||
conditions: value
|
||||
? [].concat(
|
||||
key != 'filename' ? [{key: 'username', value: value, operator: '='}] : [],
|
||||
key != 'username' ? [{key: 'filename', value: value, operator: '='}] : []
|
||||
)
|
||||
: [],
|
||||
operator: '|'
|
||||
};
|
||||
$list.options({query: query});
|
||||
}
|
||||
|
||||
function uploadFile(data) {
|
||||
pandora.ui.uploadFileDialog(data.files[0], function(file) {
|
||||
Ox.Request.clearCache('findFiles');
|
||||
pandora.api.findFiles({
|
||||
ids: [file.id],
|
||||
query: $list.options.query,
|
||||
sort: $list.options.sort,
|
||||
}, function(data) {
|
||||
$list.bindEventOnce({
|
||||
load: function() {
|
||||
list.options({selected: [file.id]});
|
||||
// selectFile(file.id);
|
||||
}
|
||||
});
|
||||
if (data.positions[file.id] > -1) {
|
||||
$list.reloadList();
|
||||
} else {
|
||||
$list.options({
|
||||
query: {conditions: [], operator: '&'}
|
||||
});
|
||||
}
|
||||
});
|
||||
}).open();
|
||||
}
|
||||
|
||||
return that;
|
||||
|
||||
};
|
||||
|
125
static/js/pandora/uploadFileDialog.js
Normal file
125
static/js/pandora/uploadFileDialog.js
Normal file
|
@ -0,0 +1,125 @@
|
|||
// vim: et:ts=4:sw=4:sts=4:ft=javascript
|
||||
'use strict';
|
||||
|
||||
pandora.ui.uploadFileDialog = function(file, callback) {
|
||||
|
||||
var extension = file.name.split('.').pop().toLowerCase(),
|
||||
|
||||
extensions = ['jpg', 'jpeg', 'pdf', 'png'],
|
||||
|
||||
jpg = false,
|
||||
|
||||
upload,
|
||||
|
||||
$content = Ox.Element(),
|
||||
|
||||
$text = $('<div>')
|
||||
.html('Uploading ' + file.name)
|
||||
.appendTo($content),
|
||||
|
||||
$progress = Ox.Progressbar({
|
||||
width: 256,
|
||||
showPercent: true,
|
||||
showTime: true
|
||||
})
|
||||
.appendTo($content),
|
||||
|
||||
$extensionDialog = pandora.iconDialog({
|
||||
buttons: [
|
||||
Ox.Button({
|
||||
id: 'close',
|
||||
title: 'Close'
|
||||
})
|
||||
.bindEvent({
|
||||
click: function() {
|
||||
$extensionDialog.close();
|
||||
}
|
||||
})
|
||||
],
|
||||
title: 'Upload File',
|
||||
text: 'Supported file types are JPG, PNG and PDF.'
|
||||
}),
|
||||
|
||||
$imageDialog = pandora.iconDialog({
|
||||
buttons: [
|
||||
Ox.Button({
|
||||
id: 'png',
|
||||
title: 'Keep as PNG',
|
||||
})
|
||||
.bindEvent({
|
||||
click: function() {
|
||||
$imageDialog.close();
|
||||
$uploadDialog.open();
|
||||
}
|
||||
}),
|
||||
Ox.Button({
|
||||
id: 'jpg'
|
||||
title: 'Encode as JPG'
|
||||
})
|
||||
.bindEvent({
|
||||
click: function() {
|
||||
jpg = true;
|
||||
$imageDialog.close();
|
||||
$uploadDialog.open();
|
||||
}
|
||||
})
|
||||
],
|
||||
text: 'Do you want to encode the image as JPG?<br><br>'
|
||||
+ '(JPGs are significantly smaller, but do not support transparency.)',
|
||||
title: 'Upload File'
|
||||
}),
|
||||
|
||||
$uploadDialog = Ox.Dialog({
|
||||
buttons: [
|
||||
Ox.Button({
|
||||
id: 'close',
|
||||
title: 'Cancel Upload'
|
||||
}).bindEvent({
|
||||
click: function() {
|
||||
if (that.title == 'Cancel Upload') {
|
||||
upload.abort();
|
||||
}
|
||||
$uploadDialog.close();
|
||||
}
|
||||
})
|
||||
],
|
||||
content: $content,
|
||||
height: 128,
|
||||
keys: {escape: 'close'},
|
||||
width: 288,
|
||||
title: 'Upload File'
|
||||
})
|
||||
.bindEvent({
|
||||
open: function() {
|
||||
upload = pandora.chunkupload({
|
||||
data: {
|
||||
filename: jpg || extension == 'jpeg'
|
||||
? file.name.split('.').slice(0, -1).join('.') + '.jpg'
|
||||
: file.name
|
||||
},
|
||||
file: file,
|
||||
url: '/api/upload/file/',
|
||||
})
|
||||
.bindEvent({
|
||||
done: function(data) {
|
||||
if (data.progress == 1) {
|
||||
that.options('buttons')[0].options({title: 'Done'})
|
||||
Ox.print('SUCCEEDED');
|
||||
} else {
|
||||
that.options('buttons')[0].options({title: 'Retry Upload'})
|
||||
Ox.print('FAILED');
|
||||
}
|
||||
},
|
||||
progress: function(data) {
|
||||
$progress.options({progress: data.progress || 0});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
return !Ox.contains(extensions, extension) ? $extensionDialog
|
||||
: extension == 'png' ? $imageDialog
|
||||
: $uploadDialog;
|
||||
|
||||
};
|
||||
|
Loading…
Reference in a new issue