Elastic: Partial Files support

This commit is contained in:
Aleksander Machniak 2018-04-17 12:57:59 +02:00
parent 3188831475
commit 2270fd8b6a
18 changed files with 1016 additions and 203 deletions

View file

@ -2024,7 +2024,7 @@ function rcube_calendar_ui(settings)
resizable: false, // prevents from Availability tab reflow bugs on resize
closeOnEscape: true,
title: rcmail.gettext('findresources', 'calendar'),
classes: {'ui-dialog': 'resources-dialog'},
classes: {'ui-dialog': 'selection-dialog resources-dialog'},
open: function() {
rcmail.ksearch_blur();
$dialog.attr('aria-hidden', 'false');

View file

@ -8,18 +8,8 @@
<div class="header">
<a class="button icon back-content-button" href="#back" data-hidden="big"><span class="inner"><roundcube:label name="back" /></span></a>
<span id="aria-label-calendars" class="header-title"><roundcube:label name="calendar.calendars" /></span>
<div id="calendar-search" class="searchbar toolbar" role="search" aria-labelledby="aria-label-calendarsearchform">
<h2 id="aria-label-calendarsearchform" class="voice"><roundcube:label name="calendar.arialabelcalsearchform" /></h2>
<form name="foldersearchform" onsubmit="return false">
<input id="calendarlistsearch" type="text" name="q" placeholder="<roundcube:label name="searchplaceholder" />" />
<a class="button reset" href="#" onclick="return rcmail.command(\'reset-listsearch\',null,this,event)" title="<roundcube:label name="resetsearch" />" tabindex="0">
<span class="inner"><roundcube:label name="resetsearch" /></span>
</a>
</form>
<a class="button search" href="#" title="<roundcube:label name="calendar.findcalendars" />" tabindex="0">
<span class="inner"><roundcube:label name="calendar.findcalendars" /></span>
</a>
</div>
<roundcube:object name="libkolab.folder_search_form" id="calendarlistsearch" wrapper="searchbar toolbar"
ariatag="h2" label="calsearchform" label-domain="calendar" buttontitle="findcalendars" />
</div>
<div id="calendars-content" class="scroller">
<roundcube:object name="plugin.calendar_list" id="calendarslist" class="treelist listing iconized" />
@ -184,7 +174,7 @@
<div id="eventresourcesdialog" class="popupmenu">
<h3 class="voice" id="aria-label-resourceselection"><roundcube:label name="calendar.arialabelresourceselection" /></h3>
<div class="resource-selection " role="navigation" aria-labelledby="aria-label-resourceselection">
<div class="resource-selection selection-list" role="navigation" aria-labelledby="aria-label-resourceselection">
<div class="header">
<span class="header-title"><roundcube:label name="calendar.tabresources" /></span>
<roundcube:object name="plugin.resources_searchform" id="resourcesearchbox"
@ -195,7 +185,7 @@
<roundcube:object name="plugin.resources_list" id="resources-list" class="listing treelist" />
</div>
</div>
<div class="resource-content">
<div class="resource-content selection-content">
<div class="header" data-hidden="normal,big">
<a class="button icon back" href="#back" onclick="$('#eventresourcesdialog .resource-content').hide(); $('#eventresourcesdialog .resource-selection').show()">
<span class="inner"><roundcube:label name="back" /></span>

View file

@ -1,29 +1,16 @@
<div id="search-addon" class="searchbar toolbar" role="search" aria-labelledby="aria-labelfoldersearchform">
<h2 id="aria-label-labelfoldersearchform" class="voice"><roundcube:label name="kolab_addressbook.foldersearchform" /></h2>
<form name="foldersearchform" onsubmit="return false">
<input id="addressbooksearch" type="text" name="q" placeholder="<roundcube:label name="searchplaceholder" />" />
<a class="button reset" href="#" onclick="return rcmail.command(\'reset-listsearch\',null,this,event)" title="<roundcube:label name="resetsearch" />" tabindex="0">
<span class="inner"><roundcube:label name="resetsearch" /></span>
</a>
</form>
<a class="button search" href="#"title="<roundcube:label name="kolab_addressbook.findaddressbooks" />" tabindex="0" >
<span class="inner"><roundcube:label name="kolab_addressbook.findaddressbooks" /></span>
</a>
</div>
<roundcube:object name="libkolab.folder_search_form" id="addressbooksearch" wrapper="searchbar toolbar"
ariatag="h2" label="foldersearchform" label-domain="kolab_addressbook" buttontitle="findaddressbooks" />
<script>
// append search form for address books
if (rcmail.gui_objects.folderlist) {
var searchbar = $('#search-addon')
var searchbar = $('#addressbooksearch').parent().parent()
.attr('aria-controls', rcmail.gui_objects.folderlist)
.insertAfter($('#layout > .sidebar > .header > .header-title'))
.get(0);
// Initialize searchbar
UI.searchbar_init(searchbar);
// Make checkboxes pretty
rcmail.addEventListener('init', function() {
// Make checkboxes pretty
rcmail.treelist.addEventListener('add-item', function(prop) {
UI.pretty_checkbox($(prop.li).find('input').addClass('flex-checkbox'));
});

View file

@ -339,13 +339,22 @@ function kolab_directory_selector_dialog(id)
kolab_dialog_show(dialog, {
title: rcmail.gettext('kolab_files.' + label),
buttons: buttons,
button_classes: ['mainaction'],
button_classes: ['mainaction save', 'cancel'],
classes: {'ui-dialog': 'selection-dialog files-dialog'},
minWidth: 250,
minHeight: 300,
height: 400,
width: 300
}, fn);
// add link for "more options" drop-down
if (!dialog.find('foldercreatelink').length)
$('<a>')
.attr({href: '#', 'class': 'btn btn-link options add-folder'})
.text(rcmail.gettext('kolab_files.addfolder'))
.click(function(e) { rcmail.command('folder-create', '', this, e); })
.prependTo(dialog.parent().parent().find('.ui-dialog-buttonset'));
// "enable" folder creation when dialog is displayed in parent window
if (rcmail.is_framed()) {
parent.rcmail.enable_command('folder-create', true);
@ -393,7 +402,8 @@ function kolab_files_selector_dialog()
kolab_dialog_show(dialog, {
title: rcmail.gettext('kolab_files.selectfiles'),
buttons: buttons,
button_classes: ['mainaction'],
button_classes: ['mainaction save', 'cancel'],
classes: {'ui-dialog': 'selection-dialog files-dialog'},
minWidth: 500,
minHeight: 300,
width: 700,
@ -454,7 +464,7 @@ function kolab_files_folder_create_dialog()
kolab_dialog_show(dialog, {
title: rcmail.gettext('kolab_files.foldercreate'),
buttons: buttons,
button_classes: ['mainaction']
button_classes: ['mainaction save', 'cancel']
});
// Fix submitting form with Enter
@ -499,7 +509,8 @@ function kolab_files_folder_edit_dialog()
kolab_dialog_show(dialog, {
title: rcmail.gettext('kolab_files.folderedit'),
buttons: buttons,
button_classes: ['mainaction']
button_classes: ['mainaction save', 'cancel'],
height: 200
});
// Fix submitting form with Enter
@ -544,9 +555,6 @@ function kolab_files_folder_mount_dialog()
kolab_dialog_close(this);
};
// close folderoption menu
rcmail.hide_menu('folderoptions');
// initialize drivers list
if (!rcmail.drivers_list_initialized) {
rcmail.drivers_list_initialized = true;
@ -569,7 +577,7 @@ function kolab_files_folder_mount_dialog()
});
}
args.button_classes = ['mainaction'];
args.button_classes = ['mainaction save', 'cancel'];
// show dialog window
kolab_dialog_show(dialog, args, function() {
@ -664,7 +672,7 @@ function kolab_files_file_edit_dialog(file, sessions, readonly)
kolab_dialog_show(dialog, {
title: title,
buttons: buttons,
button_classes: ['mainaction'],
button_classes: ['mainaction save', 'cancel'],
minHeight: height - 100,
height: height
});
@ -701,9 +709,9 @@ function kolab_files_file_rename_dialog(file)
kolab_dialog_show(dialog, {
title: rcmail.gettext('kolab_files.renamefile'),
buttons: buttons,
button_classes: ['mainaction'],
button_classes: ['mainaction save', 'cancel'],
minHeight: 100,
height: 200
height: 100
});
};
@ -711,6 +719,7 @@ function kolab_files_file_rename_dialog(file)
function kolab_files_file_create_dialog(file)
{
var buttons = {}, action = file ? 'copy' : 'create',
button_classes = ['mainaction save'],
dialog = $('#files-file-create-dialog'),
type_select = $('select[name="type"]', dialog),
select = $('select[name="parent"]', dialog).html(''),
@ -746,6 +755,7 @@ function kolab_files_file_create_dialog(file)
};
if (action == 'create') {
button_classes.push('save');
buttons[rcmail.gettext('kolab_files.create')] = function() {
create_func(this);
};
@ -756,6 +766,7 @@ function kolab_files_file_create_dialog(file)
type_select.parent('tr').hide();
}
button_classes.push('cancel');
buttons[rcmail.gettext('kolab_files.cancel')] = function() {
kolab_dialog_close(this);
};
@ -767,7 +778,7 @@ function kolab_files_file_create_dialog(file)
kolab_dialog_show(dialog, {
title: rcmail.gettext('kolab_files.' + action + 'file'),
buttons: buttons,
button_classes: ['mainaction'],
button_classes: button_classes,
minHeight: 150,
height: 250
});
@ -810,12 +821,14 @@ function kolab_files_session_dialog(session)
else if (session.is_invited) {
// @TODO: check if not-accepted and provide "Decline invitation" button
// @TODO: Add "Accept button", add comment field to the dialog
button_classes.push('session join');
buttons[rcmail.gettext('kolab_files.join')] = function() {
kolab_dialog_close(this);
join_session(session.id);
};
}
else {
button_classes.push('session request');
buttons[rcmail.gettext('kolab_files.request')] = function() {
kolab_dialog_close(this);
// @TODO: Add comment field to the dialog
@ -823,6 +836,7 @@ function kolab_files_session_dialog(session)
};
}
button_classes.push('cancel');
buttons[rcmail.gettext('kolab_files.cancel')] = function() {
kolab_dialog_close(this);
};
@ -935,8 +949,10 @@ function kolab_files_upload_input(button)
})
.attr('onclick', '') // remove default button action
.click(function(e) {
console.log("*1")
// forward click if mouse-enter event was missed
if (rcmail.commands['files-upload'] && !this.__active) {
console.log("*2")
this.__active = true;
move_file_input(e);
file.trigger(e);
@ -1202,6 +1218,10 @@ function kolab_files_frame_load(frame)
rcmail.enable_command('files-print', (rcmail.file_editor && rcmail.file_editor.printable)
|| (info && /^image\//i.test(info.type)));
// Enable image tools
rcmail.enable_command('image-scale', 'image-rotate', info && !!/^image\//.test(info.type));
rcmail.gui_objects.messagepartframe = frame;
// detect Print button and check if it can be accessed
try {
if ($('#fileframe').contents().find('#print').length)
@ -1312,17 +1332,12 @@ function document_editor_init()
// executed on editing session termination
function document_editor_close()
{
$('<div>').addClass('popupdialog').attr('role', 'alertdialog')
.html($('<span>').text(rcmail.gettext('kolab_files.sessionterminated')))
.dialog({
resizable: false,
closeOnEscape: true,
dialogClass: 'error',
title: rcmail.gettext('kolab_files.sessionterminatedtitle'),
close: function() { window.close(); },
width: 420,
minHeight: 90
}).show();
var dialog = $('<div>').addClass('popupdialog').attr('role', 'alertdialog')
.html($('<span>').text(rcmail.gettext('kolab_files.sessionterminated')));
rcmail.alert_dialog(dialog, function() { window.close(); }, {
title: rcmail.gettext('kolab_files.sessionterminatedtitle')
});
return false; // skip Chwala's error message
};
@ -1353,10 +1368,10 @@ rcube_webmail.prototype.document_editors = function()
rcube_webmail.prototype.document_close = function()
{
// check document "unsaved changes" state and display a warning
if (this.commands['document-save'] && !confirm(this.gettext('kolab_files.unsavedchanges')))
return;
file_api.document_delete(this.env.file_data.session.id);
if (this.commands['document-save'])
this.confirm_dialog(this.gettext('kolab_files.unsavedchanges'), 'kolab_files.terminate', function() {
file_api.document_delete(rcmail.env.file_data.session.id);
});
};
// document editors management dialog
@ -1389,7 +1404,7 @@ function kolab_files_editors_dialog(session)
kolab_dialog_show(dialog, {
title: rcmail.gettext('kolab_files.manageeditors'),
buttons: buttons,
button_classes: ['mainaction']
button_classes: ['cancel']
});
if (!rcmail.env.editors_dialog) {
@ -1448,7 +1463,7 @@ function kolab_files_add_attendees(names, comment)
counter++;
}
else {
alert(rcmail.gettext('noemailwarning'));
rcmail.alert_dialog(rcmail.gettext('noemailwarning'));
}
}
@ -1524,7 +1539,7 @@ function document_editor_invitation_handler(invitation)
function kolab_files_invitation_dialog(invitation)
{
var text, records = [], content = [], buttons = {},
var text, records = [], content = [], buttons = {}, button_classes = [],
dialog = $('#document-invitation-dialog'),
data_map = {status: 'status', 'changed': 'when', filename: 'file', comment: 'comment'},
record_fn = function(type, label, value) {
@ -1548,6 +1563,7 @@ function kolab_files_invitation_dialog(invitation)
if (!invitation.is_session_owner) {
if (invitation.status == 'invited') {
text = document_editor.invitation_msg(invitation);
button_classes = ['session join', 'session accept', 'session decline delete'];
buttons[rcmail.gettext('kolab_files.join')] = function() {
join_session();
@ -1569,6 +1585,7 @@ function kolab_files_invitation_dialog(invitation)
else if (invitation.status == 'accepted-owner') {
text = document_editor.invitation_msg(invitation);
button_classes = ['mainaction session join'];
buttons[rcmail.gettext('kolab_files.join')] = function() {
join_session();
kolab_dialog_close(this);
@ -1586,6 +1603,7 @@ function kolab_files_invitation_dialog(invitation)
else if (invitation.status == 'requested') {
text = document_editor.invitation_msg(invitation);
button_classes = ['session accept', 'session decline delete'];
buttons[rcmail.gettext('kolab_files.accept')] = function() {
document_editor.invitation_accept(invitation);
kolab_dialog_close(this);
@ -1612,6 +1630,7 @@ function kolab_files_invitation_dialog(invitation)
content.push($('<table class="propform">').html(records));
}
button_classes.push('cancel');
buttons[rcmail.gettext('kolab_files.close')] = function() {
kolab_dialog_close(this);
};
@ -1621,7 +1640,8 @@ function kolab_files_invitation_dialog(invitation)
// show dialog window
kolab_dialog_show(dialog, {
title: rcmail.gettext('kolab_files.invitationtitle').replace('$file', invitation.filename),
buttons: buttons
buttons: buttons,
button_classes: button_classes
});
};
@ -1677,19 +1697,20 @@ rcube_webmail.prototype.files_search_reset = function()
file_api.file_search_reset();
};
rcube_webmail.prototype.files_folder_delete = function()
rcube_webmail.prototype.files_folder_delete = function(prop, elem, event)
{
if (confirm(this.get_label('kolab_files.folderdeleteconfirm')))
this.hide_menu('folderoptions', event);
this.confirm_dialog(this.get_label('kolab_files.folderdeleteconfirm'), 'delete', function() {
file_api.folder_delete(file_api.env.folder);
});
};
rcube_webmail.prototype.files_delete = function()
{
if (!confirm(this.get_label('kolab_files.filedeleteconfirm')))
return;
var files = this.env.file ? [this.env.file] : kolab_files_selected();
file_api.file_delete(files);
this.confirm_dialog(this.get_label('kolab_files.filedeleteconfirm'), 'delete', function() {
var files = rcmail.env.file ? [rcmail.env.file] : kolab_files_selected();
file_api.file_delete(files);
});
};
rcube_webmail.prototype.files_move = function(folder)
@ -1881,13 +1902,15 @@ rcube_webmail.prototype.folder_create = function()
kolab_files_folder_create_dialog();
};
rcube_webmail.prototype.folder_rename = function()
rcube_webmail.prototype.folder_rename = function(prop, elem, event)
{
this.hide_menu('folderoptions', event);
kolab_files_folder_edit_dialog();
};
rcube_webmail.prototype.folder_mount = function()
rcube_webmail.prototype.folder_mount = function(prop, elem, event)
{
this.hide_menu('folderoptions', event);
kolab_files_folder_mount_dialog();
};
@ -2169,23 +2192,20 @@ function kolab_files_ui()
{
var toggle, sublist, collapsed, parent, parent_name, classes = ['mailbox'],
row = $('<li>'),
id = 'rcmli' + rcmail.html_identifier_encode(i);
row.attr('id', id).append($('<a class="name">').text(folder.name));
id = 'rcmli' + rcmail.html_identifier_encode(i),
content = $('<div>').append($('<a class="name">').text(folder.name));
if (folder.virtual)
classes.push('virtual');
else {
if (folder.subscribed !== undefined)
row.append(this.folder_list_subscription_button(folder.subscribed));
content.append(this.folder_list_subscription_button(folder.subscribed));
if (folder.readonly)
classes.push('readonly');
}
row.addClass(classes.join(' '));
folder.ref = row;
folder.ref = row.attr({id: id, 'class': classes.join(' ')}).append(content);
if (folder.depth) {
// find parent folder
@ -2228,7 +2248,7 @@ function kolab_files_ui()
// subscription button handler
this.folder_list_subscription_button_click = function(elem)
{
var folder = $(elem).parent('li').prop('id').replace(/^rcmli/, ''),
var folder = $(elem).parents('li:first').prop('id').replace(/^rcmli/, ''),
selected = $(elem).hasClass('subscribed');
folder = folder.replace(/--xsR$/, ''); // this might be a search result
@ -2240,7 +2260,7 @@ function kolab_files_ui()
// sets subscription button status
this.folder_list_subscription_state = function(elem, status)
{
$(elem).children('a.subscription')
$(elem).find('a.subscription:first')
.prop('aria-checked', status)[status ? 'addClass' : 'removeClass']('subscribed');
};
@ -2366,7 +2386,7 @@ function kolab_files_ui()
id: i,
classes: classes,
text: folder.name,
html: html,
html: $('<div>').append(html),
collapsed: false,
virtual: folder.virtual
}, path.length ? path.join(separator) : null);
@ -2429,7 +2449,7 @@ function kolab_files_ui()
if (!folder.virtual)
html.push(this.folder_list_subscription_button(true));
node.html = html;
node.html = $('<div>').append(html);
delete node.children;
rcmail.folder_list.insert(node, i > 0 ? path.slice(0, i).join(separator) : null);
@ -2930,12 +2950,6 @@ function kolab_files_ui()
if (c == 'name')
col = '<td class="name filename ' + this.file_type_class(data.type) + '">'
+ '<span>' + escapeHTML(file_api.file_name(data.file)) + '</span></td>';
/*
else if (c == 'mtime')
col = '<td class="mtime">' + data.mtime + '</td>';
else if (c == 'size')
col = '<td class="size">' + this.file_size(data.size) + '</td>';
*/
else if (c == 'owner')
col = '<td class="owner">' + escapeHTML(data.owner_name || data.owner) + '</td>';
else if (c == 'options')
@ -3147,7 +3161,7 @@ function kolab_files_ui()
// or overwrite destination file(s)
this.file_move_ask_user = function(list, move)
{
var file = list[0], buttons = {},
var file = list[0], buttons = {}, button_classes = ['save file overwrite'],
text = rcmail.gettext('kolab_files.filemoveconfirm').replace('$file', file.dst),
dialog = $('<div></div>');
@ -3164,7 +3178,8 @@ function kolab_files_ui()
file_api.request(action, {file: f, overwrite: 1}, 'file_move_ask_user_response');
};
if (list.length > 1)
if (list.length > 1) {
button_classes.push('file overwrite all');
buttons[rcmail.gettext('kolab_files.fileoverwriteall')] = function() {
var f = {}, action = move ? 'file_move' : 'file_copy';
@ -3174,6 +3189,7 @@ function kolab_files_ui()
file_api.req = file_api.set_busy(true, move ? 'kolab_files.filemoving' : 'kolab_files.filecopying');
file_api.request(action, {file: f, overwrite: 1}, action + '_response');
};
}
var skip_func = function() {
list.shift();
@ -3185,9 +3201,11 @@ function kolab_files_ui()
file_api.file_list();
};
button_classes.push('cancel file skip');
buttons[rcmail.gettext('kolab_files.fileskip')] = skip_func;
if (list.length > 1)
button_classes.push('cancel file skip all');
buttons[rcmail.gettext('kolab_files.fileskipall')] = function() {
kolab_dialog_close(this, true);
if (move)
@ -3323,7 +3341,7 @@ function kolab_files_ui()
size += files[i].size || files[i].fileSize;
if (size > maxsize) {
alert(rcmail.get_label('kolab_files.uploadsizeerror').replace('$size', kolab_files_file_size(maxsize)));
rcmail.alert_dialog(rcmail.get_label('kolab_files.uploadsizeerror').replace('$size', kolab_files_file_size(maxsize)));
return false;
}
}
@ -3729,6 +3747,7 @@ function kolab_files_ui()
};
args.title = this.t('kolab_files.folderauthtitle').replace('$title', label);
args.button_classes = ['mainaction save', 'cancel'];
// show dialog window
kolab_dialog_show(dialog, args, function() {

View file

@ -236,7 +236,7 @@ class kolab_files_engine
$out = $this->rc->output->form_tag($attrib, $out);
}
$this->plugin->add_label('foldercreating', 'foldercreatenotice', 'create', 'foldercreate', 'cancel');
$this->plugin->add_label('foldercreating', 'foldercreatenotice', 'create', 'foldercreate', 'cancel', 'addfolder');
$this->rc->output->add_gui_object('folder-create-form', $attrib['id']);
return $out;
@ -256,9 +256,9 @@ class kolab_files_engine
$select_parent = new html_select(array('id' => 'folder-edit-parent', 'name' => 'parent'));
$table = new html_table(array('cols' => 2, 'class' => 'propform'));
$table->add('title', html::label('folder-name', rcube::Q($this->plugin->gettext('foldername'))));
$table->add('title', html::label('folder-edit-name', rcube::Q($this->plugin->gettext('foldername'))));
$table->add(null, $input_name->show());
$table->add('title', html::label('folder-parent', rcube::Q($this->plugin->gettext('folderinside'))));
$table->add('title', html::label('folder-edit-parent', rcube::Q($this->plugin->gettext('folderinside'))));
$table->add(null, $select_parent->show());
$out = $table->show();
@ -318,7 +318,7 @@ class kolab_files_engine
. html::img(array('src' => $source['image'], 'alt' => $key, 'title' => $source['name']))
. html::div(null, html::span('name', rcube::Q($source['name']))
. html::br()
. html::span('description', rcube::Q($source['description']))
. html::span('description hint', rcube::Q($source['description']))
. $form->show()
);
@ -348,12 +348,13 @@ class kolab_files_engine
$checkbox = new html_checkbox(array(
'name' => 'store_passwords',
'value' => '1',
'class' => 'pretty-checkbox',
'id' => 'auth-pass-checkbox' . $attrib['suffix'],
));
return html::div('auth-options', $checkbox->show(). '&nbsp;'
. html::label('auth-pass-checkbox' . $attrib['suffix'], $this->plugin->gettext('storepasswords'))
. html::span('description', $this->plugin->gettext('storepasswordsdesc'))
. html::p('description hint', $this->plugin->gettext('storepasswordsdesc'))
);
}
@ -465,7 +466,7 @@ class kolab_files_engine
$table->add(null, $input_name->show());
$table->add('title', html::label('file-create-type', rcube::Q($this->plugin->gettext('type'))));
$table->add(null, $select_type->show());
$table->add('title', html::label('folder-parent', rcube::Q($this->plugin->gettext('folderinside'))));
$table->add('title', html::label('file-create-parent', rcube::Q($this->plugin->gettext('folderinside'))));
$table->add(null, $select_parent->show());
$out = $table->show();
@ -488,32 +489,16 @@ class kolab_files_engine
*/
public function file_search_form($attrib)
{
$attrib['name'] = '_q';
if (empty($attrib['id'])) {
$attrib['id'] = 'filesearchbox';
}
if ($attrib['type'] == 'search' && !$this->rc->output->browser->khtml) {
unset($attrib['type'], $attrib['results']);
}
$input_q = new html_inputfield($attrib);
$out = $input_q->show();
// add some labels to client
$this->rc->output->add_label('searching');
$this->rc->output->add_gui_object('filesearchbox', $attrib['id']);
$attrib += array(
'name' => '_q',
'gui-object' => 'filesearchbox',
'form-name' => 'filesearchform',
'command' => 'files-search',
'reset-command' => 'files-search-reset',
);
// add form tag around text field
if (empty($attrib['form'])) {
$out = $this->rc->output->form_tag(array(
'action' => '?_task=files',
'name' => "filesearchform",
'onsubmit' => rcmail_output::JS_OBJECT_NAME . ".command('files-search'); return false",
), $out);
}
return $out;
return $this->rc->output->search_form($attrib);
}
/**
@ -1467,6 +1452,7 @@ class kolab_files_engine
$this->rc->output->set_env('extwin', true);
$this->rc->output->set_env('file', $file);
$this->rc->output->set_env('file_data', $this->file_data);
$this->rc->output->set_env('mimetype', $this->file_data['type']);
$this->rc->output->set_env('editor_type', $editor_type);
$this->rc->output->set_env('photo_placeholder', $placeholder);
$this->rc->output->set_pagetitle(rcube::Q($file));

View file

@ -20,10 +20,12 @@ $labels['fromcloud'] = 'From cloud...';
$labels['selectfiles'] = 'Select file(s) to attach...';
$labels['attachsel'] = 'Attach selected';
$labels['foldercreate'] = 'Create folder';
$labels['addfolder'] = 'Add folder';
$labels['folderedit'] = 'Edit folder';
$labels['foldermount'] = 'Add storage';
$labels['folderdelete'] = 'Delete folder';
$labels['folderoptions'] = 'Folder options';
$labels['findfolders'] = 'Find folders';
$labels['folderinside'] = 'Insert inside';
$labels['foldername'] = 'Folder name';

View file

@ -0,0 +1,38 @@
<div id="files-compose-dialog" class="popupmenu" role="dialog" aria-labelledby="aria-label-fileselect">
<h3 id="aria-label-fileselect" class="voice"><roundcube:label name="kolab_files.arialabelfileselectdialog" /></h3>
<div id="folderlistbox" class="selection-list" role="navigation" aria-labelledby="aria-label-folderlist">
<h4 id="aria-label-folderlist" class="voice"><roundcube:label name="kolab_files.arialabelfolderlist" /></h4>
<div class="header">
<span class="header-title"><roundcube:label name="folders" /></span>
<roundcube:object name="libkolab.folder_search_form" id="foldersearch" wrapper="searchbar toolbar"
ariatag="h5" label="foldersearchform" buttontitle="kolab_files.findfolders" />
</div>
<div id="files-folder-list" class="scroller"></div>
</div>
<div id="filelistcontainer" class="selection-content">
<div class="header">
<a class="button icon back-sidebar-button folders" href="#sidebar" data-hidden="big"><span class="inner"><roundcube:label name="folders" /></span></a>
<span class="header-title"></span>
<roundcube:object name="file-search-form" id="filesearchbox" wrapper="searchbar toolbar"
label="searchform" buttontitle="kolab_files.findfiles" label-domain="kolab_files"
ariatag="h3" options="filesearchmenu" />
</div>
<h4 id="aria-label-filelist" class="voice"><roundcube:label name="kolab_files.arialabelfilelist" /></h4>
<div class="scroller">
<roundcube:object name="filelist" id="filelist" class="records-table filelist sortheader fixedheader"
aria-labelledby="aria-label-filelist" />
</div>
</div>
</div>
<div id="filesearchmenu" class="popupmenu form" data-editable="true">
<h3 id="aria-label-searchmenu" class="voice"><roundcube:label name="searchmod" /></h3>
<ul class="toolbarmenu" role="menu" aria-labelledby="aria-label-searchmenu">
<li role="menuitem" class="checkbox"><label><input type="checkbox" name="all_folders" value="1" id="search_all_folders" /><roundcube:label name="kolab_files.allfolders" /></label></li>
</ul>
</div>
<div id="files-folder-auth-dialog" class="popupmenu formcontent" role="dialog" aria-labelledby="aria-label-folderauthform">
<h3 id="aria-label-folderauthform" class="voice"><roundcube:label name="kolab_files.arialabelfolderauthform" /></h3>
<roundcube:object name="folder-auth-options">
</div>

View file

@ -0,0 +1,63 @@
<roundcube:include file="includes/layout.html" />
<h1 class="voice"><roundcube:var name="env:filename" /></h1>
<div class="content selected <roundcube:var name="env:editor_type" />">
<h2 id="aria-label-toolbar" class="voice"><roundcube:label name="arialabeltoolbar" /></h2>
<div class="header" role="toolbar" aria-labelledby="aria-label-toolbar">
<span class="header-title constant"><roundcube:var name="env:filename" /></span>
<div class="toolbar">
<roundcube:button command="document-close" type="link"
class="button delete disabled" classAct="button delete"
label="kolab_files.terminate" title="kolab_files.terminatesession" innerClass="inner" />
<span class="dropbutton">
<roundcube:button command="document-export" type="link"
class="button export disabled" classAct="button export"
label="kolab_files.get" title="kolab_files.getfile" innerClass="inner" />
<a href="#export" class="button dropdown" id="exportmenulink" data-popup="export-menu" tabindex="0">
<span class="inner"><roundcubemail:label name="kolab_files.exportoptions" /><span>
</a>
</span>
<roundcube:if condition="env:editor_type == 'wopi'" />
<roundcube:button command="document-print" type="link"
class="button print disabled" classAct="button print"
label="print" title="kolab_files.printfile" innerClass="inner" />
<roundcube:endif />
<roundcube:button command="document-save" type="link"
class="button save disabled" classAct="button save"
label="kolab_files.save" title="kolab_files.savefile" innerClass="inner" />
<!--
<roundcube:if condition="env:editor_type != 'wopi'" />
<span class="spacer"></span>
<label for="document-title"><roundcube:label name="kolab_files.documenttitle" />&nbsp;<input id="document-title" type="text" value="" /></label>
<roundcube:endif />
-->
</div>
<!--
<h3 id="aria-label-collaborators" class="voice"><roundcube:label name="kolab_files.arialabelcollaborators" /></h3>
<div id="collaborators" class="toolbar" role="toolbar" aria-labelledby="aria-label-collaborators">
<roundcube:button command="document-editors" type="link" class="button add disabled" classAct="button add" classSel="button add pressed" content=" " title="kolab_files.manageeditors" />
<div id="members"></div>
</div>
-->
</div>
<h2 id="aria-label-filecontent" class="voice"><roundcube:label name="kolab_files.arialabelfilecontent" /></h2>
<div class="iframe-wrapper">
<roundcube:object name="filepreviewframe" id="fileframe" role="main"
title="kolab_files.arialabelfilecontent" aria-labelledby="aria-label-filecontent" />
</div>
</div>
<div id="export-menu" class="popupmenu">
<h3 id="aria-label-exportmenu" class="voice"><roundcube:label name="kolab_files.arialabelexportoptions" /></h3>
<ul id="exportmenu-menu" class="toolbarmenu listing" role="menu" aria-labelledby="aria-label-exportmenu"></ul>
</div>
<div id="document-editors-dialog" class="popupmenu" data-editable="true" role="dialog" aria-labelledby="aria-label-doceditorsdialog">
<h3 id="aria-label-doceditorsdialog" class="voice"><roundcube:label name="kolab_files.arialabeldoceditorsdialog" /></h3>
<roundcube:object name="document-editors-dialog" />
</div>
<script src="plugins/kolab_files/skins/elastic/ui.js" type="text/javascript"></script>
<roundcube:include file="includes/footer.html" />

View file

@ -0,0 +1,84 @@
<roundcube:include file="includes/layout.html" />
<h1 class="voice"><roundcube:var name="env:filename" /></h1>
<div class="sidebar listbox">
<div class="header">
<a class="button icon back-content-button" href="#content" data-hidden="big"><span class="inner"><roundcube:label name="back" /></span></a>
<span class="header-title" id="aria-label-contentinfo"><roundcube:label name="properties" /></span>
</div>
<roundcube:object name="fileinfobox" id="fileinfo" class="listing" />
</div>
<div class="content selected">
<h2 id="aria-label-toolbar" class="voice"><roundcube:label name="arialabeltoolbar" /></h2>
<div class="header" role="toolbar" aria-labelledby="aria-label-toolbar">
<span class="header-title constant"><roundcube:var name="env:filename" /></span>
<div id="messagetoolbar" class="toolbar">
<roundcube:button command="files-get" type="link"
class="button download disabled" classAct="button download"
label="kolab_files.get" title="kolab_files.getfile" innerClass="inner" />
<roundcube:button command="files-edit" type="link"
class="button edit disabled" classAct="button edit"
label="kolab_files.edit" title="kolab_files.editfile" innerClass="inner" />
<roundcube:button command="files-save" type="link"
class="button save disabled" classAct="button save"
label="kolab_files.save" title="kolab_files.savefile" innerClass="inner" style="display:none" />
<roundcube:button command="files-delete" type="link"
class="button delete disabled" classAct="button delete"
label="delete" title="kolab_files.deletefile" innerClass="inner" />
<roundcube:button command="files-print" type="link"
class="button print disabled" classAct="button print"
label="print" title="kolab_files.printfile" innerClass="inner" />
<roundcube:if condition="stripos(env:mimetype, 'image/') === 0" />
<roundcube:button command="image-scale" type="link" prop="+" data-hidden="small"
class="button zoomin disabled" classAct="button zoomin"
label="zoomin" title="increaseimage" innerclass="inner" />
<roundcube:button command="image-scale" type="link" prop="-" data-hidden="small"
class="button zoomout disabled" classAct="button zoomout"
label="zoomout" title="decreaseimage" innerclass="inner" />
<roundcube:button command="image-rotate" type="link"
class="button rotate disabled" classAct="button rotate" data-hidden="small"
label="rotate" title="rotateimage" innerclass="inner" />
<roundcube:endif />
</div>
</div>
<h2 id="aria-label-filecontent" class="voice"><roundcube:label name="kolab_files.arialabelfilecontent" /></h2>
<div class="iframe-wrapper">
<roundcube:object name="filepreviewframe" id="fileframe" role="main" aria-labelledby="aria-label-filecontent" />
</div>
<roundcube:if condition="stripos(env:mimetype, 'image/') === 0" />
<div id="image-tools" class="image-tools" data-hidden="big">
<h3 id="aria-label-imagetools" class="voice"><roundcube:label name="arialabelimagetools" /></h3>
<div class="toolbar" role="menu" aria-labelledby="aria-label-imagetools">
<roundcube:button command="image-scale" type="link" prop="+"
class="button zoomin disabled" classAct="button zoomin"
label="zoomin" title="increaseimage" innerclass="inner" />
<roundcube:button command="image-scale" type="link" prop="-"
class="button zoomout disabled" classAct="button zoomout"
label="zoomout" title="decreaseimage" innerclass="inner" />
<roundcube:button command="image-rotate" type="link"
class="button rotate disabled" classAct="button rotate"
label="rotate" title="rotateimage" innerclass="inner" />
</div>
<a href="#" class="button icon tools" onclick="$(this).attr('title', $(this).data('label-' + ($('#image-tools').toggleClass('open').is('.open') ? 'hide' : 'show')))"
data-label-show="<roundcube:label name="showtools" />" data-label-hide="<roundcube:label name="hidetools" />" title="<roundcube:label name="showtools" />">
<span class="inner"><roundcube:label name="showtools" /></span>
</a>
</div>
<roundcube:endif />
</div>
<div id="files-file-create-dialog" class="popupmenu" role="dialog" aria-labelledby="aria-label-filecreateform" aria-hidden="true">
<h3 id="aria-label-filecreateform" class="voice"><roundcube:label name="kolab_files.arialabelfilecreateform" /></h3>
<roundcube:object name="file-create-form" />
</div>
<div id="files-file-edit-dialog" class="popupmenu" role="dialog" aria-labelledby="aria-label-fileeditdialog" aria-hidden="true">
<h3 id="aria-label-fileeditdialog" class="voice"><roundcube:label name="kolab_files.arialabelfileeditdialog" /></h3>
<roundcube:object name="file-edit-dialog">
</div>
<script src="plugins/kolab_files/skins/elastic/ui.js" type="text/javascript"></script>
<roundcube:include file="includes/footer.html" />

View file

@ -0,0 +1,203 @@
<roundcube:include file="includes/layout.html" />
<roundcube:include file="includes/menu.html" />
<h1 class="voice"><roundcube:label name="kolab_files.files" /></h1>
<!-- folders list -->
<div class="sidebar listbox" role="navigation" aria-labelledby="arial-label-folders">
<div class="header">
<a class="button icon back-content-button" href="#back" data-hidden="big"><span class="inner"><roundcube:label name="back" /></span></a>
<span id="aria-label-folders" class="header-title"><roundcube:label name="folders" /></span>
<roundcube:object name="libkolab.folder_search_form" id="foldersearch" wrapper="searchbar toolbar"
ariatag="h2" label="foldersearchform" buttontitle="kolab_files.findfolders" />
</div>
<div id="files-folder-list" class="scroller"></div>
<div class="footer toolbar" role="toolbar">
<roundcube:button command="folder-create" type="link"
title="kolab_files.foldercreate" label="kolab_files.addfolder"
class="button create disabled" classAct="button create" innerClass="inner" />
<roundcube:button name="folderoptions" id="folderoptionslink" type="link"
title="moreactions" label="actions"
class="button actions" innerClass="inner" data-popup="folderoptions-menu" />
<roundcube:if condition="env:files_quota" />
<div id="quotadisplay" class="quota-widget">
<span class="voice"><roundcube:label name="quota"></span>
<roundcube:object name="filequotadisplay" class="count" display="text" />
</div>
<roundcube:endif />
</div>
</div>
<!-- files -->
<div class="content selected no-navbar" role="main">
<h2 id="aria-label-toolbar" class="voice"><roundcube:label name="arialabeltoolbar" /></h2>
<div class="header" role="toolbar" aria-labelledby="aria-label-toolbar">
<a class="button icon menu-button" href="#menu"><span class="inner"><roundcube:label name="menu" /></span></a>
<a class="button icon back-sidebar-button folders" href="#sidebar" data-hidden="big"><span class="inner"><roundcube:label name="folders" /></span></a>
<span class="header-title"></span>
<!-- toolbar -->
<div id="filestoolbar" class="toolbar">
<roundcube:button command="files-upload" type="link" onclick="$('#filesuploadform').click()"
class="button upload disabled" classAct="button upload"
label="kolab_files.upload" title="kolab_files.uploadfile" innerClass="inner" />
<roundcube:button command="files-get" type="link"
class="button download disabled" classAct="button download"
label="kolab_files.get" title="kolab_files.getfile" innerClass="inner" />
<roundcube:button command="files-open" type="link"
class="button open disabled" classAct="button open"
label="kolab_files.view" title="kolab_files.viewfile" innerClass="inner" />
<roundcube:button command="files-edit" type="link"
class="button edit disabled" classAct="button edit"
label="kolab_files.edit" title="kolab_files.editfile" innerClass="inner" />
<roundcube:button command="files-create" type="link"
class="button create disabled" classAct="button create"
label="kolab_files.create" title="kolab_files.createfile" innerClass="inner "/>
<roundcube:button command="files-rename" type="link"
class="button rename disabled" classAct="button rename"
label="kolab_files.rename" title="kolab_files.renamefile" innerClass="inner" />
<roundcube:button command="files-delete" type="link"
class="button delete disabled" classAct="button delete"
label="delete" title="kolab_files.deletefile" innerClass="inner" />
</div>
<roundcube:object name="file-search-form" id="searchform" wrapper="searchbar toolbar"
label="searchform" buttontitle="kolab_files.findfiles" label-domain="kolab_files"
ariatag="h3" options="filesearchmenu" />
</div>
<div id="filelistcontainer" class="content" role="main" aria-labelledby="aria-label-filelist" data-elastic-mode="true">
<h2 id="aria-label-filelist" class="voice"><roundcube:label name="kolab_files.arialabelfilelist" /></h2>
<div id="filelistbox" class="droptarget">
<roundcube:object name="filelist" id="filelist" class="records-table listing filelist sortheader fixedheader"
aria-labelledby="aria-label-filelist" />
</div>
<h2 id="aria-label-sessionslist" class="voice"><roundcube:label name="kolab_files.arialabelsessionslist" /></h2>
<div id="sessionslistbox" class="boxlistcontent" style="display:none">
<roundcube:object name="sessionslist" id="sessionslist" class="records-table listing filelist sortheader fixedheader"
optionsmenuIcon="true" aria-labelledby="aria-label-sessionslist" />
</div>
</div>
</div>
<form id="filesuploadform" class="smart-upload"></form>
<div id="files-folder-create-dialog" class="popupmenu formcontent" role="dialog" aria-labelledby="aria-label-foldercreateform">
<h3 id="aria-label-foldercreateform" class="voice"><roundcube:label name="kolab_files.arialabelfoldercreateform" /></h3>
<roundcube:object name="folder-create-form" />
</div>
<div id="files-folder-edit-dialog" class="popupmenu formcontent" role="dialog" aria-labelledby="aria-label-foldereditform">
<h3 id="aria-label-foldereditform" class="voice"><roundcube:label name="kolab_files.arialabelfoldereditform" /></h3>
<roundcube:object name="folder-edit-form" />
</div>
<div id="files-folder-mount-dialog" class="popupmenu formcontent" role="dialog" aria-labelledby="aria-label-foldermountform">
<h3 id="aria-label-foldermountform" class="voice"><roundcube:label name="kolab_files.arialabelfoldermountform" /></h3>
<roundcube:object name="folder-mount-form" />
</div>
<div id="files-file-rename-dialog" class="popupmenu formcontent" role="dialog" aria-labelledby="aria-label-filerenameform">
<h3 id="aria-label-filerenameform" class="voice"><roundcube:label name="kolab_files.arialabelfilerenameform" /></h3>
<roundcube:object name="file-rename-form" />
</div>
<div id="files-file-create-dialog" class="popupmenu formcontent" role="dialog" aria-labelledby="aria-label-filecreateform">
<h3 id="aria-label-filecreateform" class="voice"><roundcube:label name="kolab_files.arialabelfilecreateform" /></h3>
<roundcube:object name="file-create-form" />
</div>
<div id="files-folder-auth-dialog" class="popupmenu formcontent" role="dialog" aria-labelledby="aria-label-folderauthform">
<h3 id="aria-label-folderauthform" class="voice"><roundcube:label name="kolab_files.arialabelfolderauthform" /></h3>
<roundcube:object name="folder-auth-options" />
</div>
<div id="files-file-edit-dialog" class="popupmenu formcontent" role="dialog" aria-labelledby="aria-label-fileeditdialog">
<h3 id="aria-label-fileeditdialog" class="voice"><roundcube:label name="kolab_files.arialabelfileeditdialog" /></h3>
<roundcube:object name="file-edit-dialog" />
</div>
<div id="files-session-dialog" class="popupmenu formcontent" role="dialog" aria-labelledby="aria-label-filesessiondialog">
<h3 id="aria-label-filesessiondialog" class="voice"><roundcube:label name="kolab_files.arialabelfilesessiondialog" /></h3>
<roundcube:object name="file-session-dialog" />
</div>
<div id="folderoptions-menu" class="popupmenu" data-editable="true">
<h3 id="aria-label-folderoptions" class="voice"><roundcube:label name="kolab_files.folderoptions" /></h3>
<ul class="toolbarmenu listing" role="menu" aria-labelledby="aria-label-folderoptions">
<roundcube:button type="link-menuitem" command="folder-rename" label="rename" class="rename" classAct="rename active" />
<roundcube:button type="link-menuitem" command="files-folder-delete" label="delete" class="delete" classAct="delete active" />
<roundcube:if condition="!empty(env:external_sources)" />
<roundcube:button type="link-menuitem" command="folder-mount" label="kolab_files.foldermount" class="mount storage" classAct="mount storage active" />
<roundcube:endif />
<roundcube:button type="link-menuitem" command="folders" task="settings" label="managefolders" class="folders" classAct="folders active" />
</ul>
</div>
<div id="fileslistoptions-menu" class="propform popupmenu" data-editable="true" role="dialog" aria-labelledby="aria-label-fileslistoptions">
<h3 id="aria-label-fileslistoptions" class="voice"><roundcube:label name="kolab_files.arialabellistoptions" /></h3>
<roundcube:if condition="!in_array('kolab_files_sort_col', (array)config:dont_override)" />
<div class="form-group row">
<label for="listoptions-sortcol" class="col-form-label col-sm-4"><roundcube:label name="listsorting" /></label>
<div class="col-sm-8">
<select name="sort_col" class="form-control">
<option value="name"><roundcube:label name="kolab_files.name" /></option>
<option value="mtime"><roundcube:label name="kolab_files.mtime" /></option>
<option value="size"><roundcube:label name="size" /></option>
</select>
</div>
</div>
<roundcube:endif />
<roundcube:if condition="!in_array('kolab_files_sort_order', (array)config:dont_override)" />
<div class="form-group row">
<label for="listoptions-sortcol" class="col-form-label col-sm-4"><roundcube:label name="listorder" /></label>
<div class="col-sm-8">
<select class="form-control">
<option value="ASC"><roundcube:label name="asc" /></option>
<option value="DESC"><roundcube:label name="desc" /></option>
</select>
</div>
</div>
<roundcube:endif />
</div>
<!--
<div id="sessionslistoptions" class="propform popupmenu" data-editable="true" role="dialog" aria-labelledby="aria-label-sessionslistoptions">
<h3 id="aria-label-sessionslistoptions" class="voice"><roundcube:label name="kolab_files.arialabellistoptions" /></h3>
<roundcube:if condition="!in_array('kolab_files_sessions_list_cols', (array)config:dont_override)" />
<fieldset class="floating">
<legend><roundcube:label name="listcolumns" /></legend>
<ul class="proplist">
<li><label class="disabled"><input type="checkbox" name="list_col[]" value="options" checked="checked" disabled="disabled" /> <span><roundcube:label name="options" /></span></label></li>
<li><label class="disabled"><input type="checkbox" name="list_col[]" value="name" checked="checked" disabled="disabled" /> <span><roundcube:label name="kolab_files.name" /></span></label></li>
<li><label><input type="checkbox" name="list_col[]" value="owner" /> <span><roundcube:label name="kolab_files.owner" /></span></label></li>
</ul>
</fieldset>
<roundcube:endif />
<roundcube:if condition="!in_array('kolab_files_sessions_sort_col', (array)config:dont_override)" />
<fieldset class="floating">
<legend><roundcube:label name="listsorting" /></legend>
<ul class="proplist">
<li><label><input type="radio" name="sort_col" value="name" /> <span><roundcube:label name="kolab_files.name" /></span></label></li>
</ul>
</fieldset>
<roundcube:endif />
<roundcube:if condition="!in_array('kolab_files_sessions_sort_order', (array)config:dont_override)" />
<fieldset class="floating">
<legend><roundcube:label name="listorder" /></legend>
<ul class="proplist">
<li><label><input type="radio" name="sort_ord" value="ASC" /> <span><roundcube:label name="asc" /></span></label></li>
<li><label><input type="radio" name="sort_ord" value="DESC" /> <span><roundcube:label name="desc" /></span></label></li>
</ul>
</fieldset>
<roundcube:endif />
</div>
-->
<div id="dragfilemenu" class="popupmenu">
<ul class="toolbarmenu listing" role="menu">
<roundcube:button type="link-menuitem" command="files-move" onclick="return kolab_files_drag_menu_action('files-move')" label="move" classAct="active" />
<roundcube:button type="link-menuitem" command="files-copy" onclick="return kolab_files_drag_menu_action('files-copy')" label="copy" classAct="active" />
</ul>
</div>
<div id="filesearchmenu" class="popupmenu form" data-editable="true">
<h3 id="aria-label-searchmenu" class="voice"><roundcube:label name="searchmod" /></h3>
<ul class="toolbarmenu" role="menu" aria-labelledby="aria-label-searchmenu">
<li role="menuitem" class="checkbox"><label><input type="checkbox" name="all_folders" value="1" id="search_all_folders" /><roundcube:label name="kolab_files.allfolders" /></label></li>
</ul>
</div>
<script src="plugins/kolab_files/skins/elastic/ui.js" type="text/javascript"></script>
<roundcube:include file="includes/footer.html" />

View file

@ -0,0 +1,26 @@
<div id="files-dialog" class="popupmenu selection-list" data-editable="true" role="dialog" aria-labelledby="aria-label-filesavedialog">
<h3 id="aria-label-filesavedialog" class="voice"><roundcube:label name="kolab_files.arialabelfilesavedialog" /></h3>
<div class="header">
<span class="header-title"><roundcube:label name="folders" /></span>
<roundcube:object name="libkolab.folder_search_form" id="foldersearch" wrapper="searchbar toolbar"
ariatag="h2" label="foldersearchform" buttontitle="kolab_files.findfolders" />
</div>
<h3 id="aria-label-folderlist" class="voice"><roundcube:label name="kolab_files.arialabelfolderlist" /></h3>
<div id="files-folder-list" class="scroller" aria-labelledby="aria-label-folderlist" data-no-collections="true"></div>
<div id="file-save-as" class="form-addon form-group row">
<label for="file-save-as-input" class="col-form-label col-sm-4"><roundcube:label name="kolab_files.saveas" /></label>
<div class="col-sm-8">
<input id="file-save-as-input" type="text" value="" class="form-control">
</div>
</div>
</div>
<div id="files-folder-create-dialog" class="popupmenu formcontent" role="dialog" aria-labelledby="aria-label-foldercreateform">
<h3 id="aria-label-foldercreateform" class="voice"><roundcube:label name="kolab_files.arialabelfoldercreateform" /></h3>
<roundcube:object name="folder-create-form" />
</div>
<div id="files-folder-auth-dialog" class="popupmenu formcontent" role="dialog" aria-labelledby="aria-label-folderauthform">
<h3 id="aria-label-folderauthform" class="voice"><roundcube:label name="kolab_files.arialabelfolderauthform" /></h3>
<roundcube:object name="folder-auth-options">
</div>

View file

@ -0,0 +1,96 @@
function kolab_files_enable_command(p)
{
if (p.command == 'files-save') {
var toolbar = $('#filestoolbar');
$('a.button.edit', toolbar).hide();
$('a.button.save', toolbar).show();
}
};
function kolab_files_show_listoptions(p)
{
if (!p || !p.name) {
return;
}
if (p.name.match(/^(files|sessions)listmenu$/)) {
var type = RegExp.$1;
}
else {
return;
}
var $dialog = $('#' + type + 'listoptions');
// close the dialog
if ($dialog.is(':visible')) {
$dialog.dialog('close');
return;
}
// set form values
$('input[name="sort_col"][value="'+rcmail.env[type + '_sort_col']+'"]', $dialog).prop('checked', true);
$('input[name="sort_ord"][value="DESC"]', $dialog).prop('checked', rcmail.env[type + '_sort_order'] == 'DESC');
$('input[name="sort_ord"][value="ASC"]', $dialog).prop('checked', rcmail.env[type + '_sort_order'] != 'DESC');
// set checkboxes
$('input[name="list_col[]"]').each(function() {
$(this).prop('checked', $.inArray(this.value, rcmail.env[type + '_coltypes']) != -1);
});
$dialog.dialog({
modal: true,
resizable: false,
closeOnEscape: true,
close: function() { rcmail[type + 'list'].focus(); },
title: null,
minWidth: 400,
width: $dialog.width()+20
}).show();
};
function kolab_files_save_listoptions(p)
{
if (!p || !p.originalEvent) {
return;
}
if (p.originalEvent.target.id.match(/^(files|sessions)listmenusave$/)) {
var type = RegExp.$1;
}
else {
return;
}
var dialog = $('#' + type + 'listoptions').dialog('close');
var sort = $('input[name="sort_col"]:checked', dialog).val(),
ord = $('input[name="sort_ord"]:checked', dialog).val(),
cols = $('input[name="list_col[]"]:checked', dialog)
.map(function() { return this.value; }).get();
kolab_files_set_list_options(cols, sort, ord, type);
};
if (rcmail.env.action == 'open' || rcmail.env.action == 'edit') {
rcmail.addEventListener('enable-command', kolab_files_enable_command);
if ($('#exportmenu').length)
rcmail.gui_object('exportmenu', 'exportmenu');
}
$(document).ready(function() {
rcmail.addEventListener('menu-open', kolab_files_show_listoptions);
rcmail.addEventListener('menu-save', kolab_files_save_listoptions);
rcmail.addEventListener('menu-close', kolab_files_show_listoptions);
if ($('#dragfilemenu').length) {
rcmail.gui_object('file_dragmenu', 'dragfilemenu');
}
if ($('#filesearchmenu').length) {
rcmail.gui_object('file_searchmenu', 'filesearchmenu');
}
});
kolab_files_upload_input('#filesuploadform');

View file

@ -8,18 +8,8 @@
<div class="header">
<a class="button icon back-list-button" href="#back"><span class="inner"><roundcube:label name="back" /></span></a>
<span id="aria-label-notebooks" class="header-title"><roundcube:label name="kolab_notes.lists" /></span>
<div id="notebook-search" class="searchbar toolbar" role="search" aria-labelledby="aria-label-notebooksearchform">
<h2 id="aria-label-label-notebooksearchform" class="voice"><roundcube:label name="kolab_notes.arialabelfoldersearchform" /></h2>
<form name="foldersearchform" onsubmit="return false">
<input id="notebooksearch" type="text" name="q" placeholder="<roundcube:label name="searchplaceholder" />" />
<a class="button reset" href="#" onclick="return rcmail.command(\'reset-listsearch\',null,this,event)" title="<roundcube:label name="resetsearch" />" tabindex="0">
<span class="inner"><roundcube:label name="resetsearch" /></span>
</a>
</form>
<a class="button search" href="#" title="<roundcube:label name="kolab_notes.findnotebooks" />" tabindex="0">
<span class="inner"><roundcube:label name="kolab_notes.findnotebooks" /></span>
</a>
</div>
<roundcube:object name="libkolab.folder_search_form" id="notebooksearch" wrapper="searchbar toolbar"
ariatag="h2" label="foldersearchform" label-domain="kolab_notes" buttontitle="findnotebooks" />
</div>
<div id="notebooks-content" class="scroller">
<roundcube:object name="plugin.notebooks" id="notebooks" class="listing treelist iconized" />

View file

@ -58,6 +58,7 @@ class libkolab extends rcube_plugin
$this->add_texts('localization/', false);
if ($rcmail->output->type == 'html') {
$rcmail->output->add_handler('libkolab.folder_search_form', array($this, 'folder_search_form'));
$this->include_stylesheet($this->local_skin_path() . '/libkolab.css');
}
@ -342,4 +343,29 @@ class libkolab extends rcube_plugin
{
return $event['allday'] ? 'Ymd' : 'Ymd\THis';
}
/**
* Returns HTML code for folder search widget
*
* @param array $attrib Named parameters
*
* @return string HTML code for the gui object
*/
public function folder_search_form($attrib)
{
$rcmail = rcube::get_instance();
$attrib += array(
'gui-object' => false,
'wrapper' => true,
'form-name' => 'foldersearchform',
'command' => 'non-extsing-command',
'reset-command' => 'non-existing-command',
);
if ($attrib['label-domain'] && !strpos($attrib['buttontitle'], '.')) {
$attrib['buttontitle'] = $attrib['label-domain'] . '.' . $attrib['buttontitle'];
}
return $rcmail->output->search_form($attrib);
}
}

View file

@ -1713,50 +1713,13 @@ body.task-calendar {
}
.resources-dialog {
.ui-dialog-content {
display: flex !important;
overflow: hidden !important;
}
.resource-selection {
flex: 4;
display: flex;
flex-direction: column;
border: 1px solid @color-layout-border;
min-width: 300px;
justify-content: center;
.scroller {
flex: 1;
overflow-y: auto;
}
}
.header {
border-bottom: 1px solid @color-layout-border;
display: flex;
background-color: @color-layout-header-background;
font-size: @layout-header-font-size;
font-weight: bold;
line-height: @layout-header-height;
height: @layout-header-height;
min-height: @layout-header-height;
padding: 0 .25em;
position: relative; // for absolute positioning of searchbar
overflow: hidden;
white-space: nowrap;
}
.header-title {
width: 100%;
text-align: center;
margin: 0 2em;
}
.resource-content {
flex: 10;
display: flex;
flex-direction: column;
margin-left: 1em;
}
@ -1769,12 +1732,6 @@ body.task-calendar {
}
}
.tab-content {
margin-top: 1rem;
height: 100%;
overflow-y: auto;
}
.slot-nav {
display: none; // TODO
}
@ -1907,25 +1864,12 @@ body.task-calendar {
}
.resources-dialog {
.ui-dialog-content {
padding: 0 !important;
}
.resource-selection {
border: 0;
}
.resource-content,
.ui-dialog-titlebar {
.resource-content {
display: none;
margin: 0;
}
.resource-content {
.header-title {
margin-left: 0;
}
ul {
margin: 1em 1em 0 1em;
}

View file

@ -27,3 +27,276 @@ a.button.filesaveall:before {
&:extend(.font-icon-class);
content: @fa-var-folder;
}
.toolbarmenu.listing li a.mount.storage:before {
content: @fa-var-database;
}
.toolbar a.button.open:before {
content: @fa-var-eye;
}
.toolbar a.button.rename:before {
content: @fa-var-pen-square;
}
.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset a.btn-link.options.add-folder {
&:after {
display: none;
}
&:before {
display: inline !important;
content: @fa-var-plus;
margin-right: .2em;
}
}
.folderlist {
li.collection {
a.name {
padding-left: .5em;
}
&.audio a.name:before {
.font-icon-solid(@fa-var-volume-up);
}
&.video a.name:before {
.font-icon-solid(@fa-var-video);
}
&.image a.name:before {
content: @fa-var-image;
}
&.document a.name:before {
.font-icon-solid(@fa-var-book);
}
&.sessions a.name:before {
.font-icon-solid(@fa-var-users);
}
}
li.mailbox {
a.subscription {
cursor: pointer;
// reset listing's link style
padding: 0;
border-left: 0;
width: auto;
&:before {
.font-icon-regular(@fa-var-bookmark); // TODO: better icon
height: auto;
color: @color-link;
margin-right: .25rem;
}
&.subscribed:before {
&:extend(.font-icon-class);
.font-icon-solid(@fa-var-bookmark); // TODO: better icon
}
}
}
}
.filelist {
table-layout: auto !important;
td.options {
width: 2em;
}
td.name {
}
td.mtime {
width: 5em;
}
td.size {
text-align: right;
width: 3em;
}
}
.filelist tbody td.filename {
& span {
background: transparent !important;
}
& span:before {
&:extend(.font-icon-class);
.font-icon-regular(@fa-var-file);
}
&.pdf span:before,
&.application_pdf span:before {
content: @fa-var-file-pdf;
}
&.application_vnd_ms_word span:before,
&.application_msword span:before {
content: @fa-var-file-word;
}
&.application_vnd_ms_excel span:before,
&.application_vnd_oasis_opendocument_spreadsheet span:before,
&.application_vnd_oasis_opendocument_spreadsheet_template span:before {
content: @fa-var-file-excel;
}
&.application_vnd_ms_powerpoint span:before {
content: @fa-var-file-powerpoint;
}
&.application_vnd_oasis_opendocument_text span:before {
content: @fa-var-file-alt; // TODO
}
&.application_vnd_oasis_opendocument_presentation span:before,
&.application_vnd_oasis_opendocument_presentation_template span:before {
content: @fa-var-file-powerpoint; // TODO
}
&.tar span:before,
&.application_zip span:before,
&.application_x_7z_compressed span:before,
&.application_x_ace span:before,
&.application_x_arc span:before,
&.application_x_arj span:before,
&.application_x_bzip_compressed_tar span:before,
&.application_x_lha span:before,
&.application_x_rar span:before,
&.application_x_tarz span:before,
&.application_x_tzo span:before,
&.application_x_zip span:before,
&.application_x_zoo span:before {
content: @fa-var-file-archive;
}
&.image span:before,
&.image_png span:before,
&.image_svg_xml span:before,
&.image_jpeg span:before,
&.image_jpeg2000 span:before,
&.image_x_eps span:before,
&.application_vnd_stardivision_draw span:before,
&.application_vnd_sun_xml_draw span:before,
&.application_vnd_sun_xml_draw_template span:before {
content: @fa-var-file-image;
}
&.application_pgp_keys span:before,
&.application_pkcs7_mime span:before {
// TODO
}
&.audio span:before {
content: @fa-var-file-audio;
}
&.video span:before {
content: @fa-var-file-video;
}
&.ascii span:before,
&.text_plain span:before {
content: @fa-var-file-alt;
}
&.vcalendar span:before {
// TODO
}
&.vcard span:before,
&.text_x_vcard span:before {
// TODO
}
&.text_html span:before {
content: @fa-var-file-code;
}
&.style_css span:before {
// TODO
}
&.text_csv span:before {
// TODO
}
&.message_rfc822 span:before {
// TODO
}
}
#folder-mount-form {
td.source {
display: flex;
align-items: flex-start;
padding: .5rem;
&.selected {
background-color: @color-list-selected-background;
}
& > input {
height: 32px;
margin-right: .5rem;
}
& > div {
flex: 1;
}
img {
height: 32px;
margin-right: .5rem;
}
.name {
font-weight: bold;
}
.description {
font-size: 90%;
}
table {
margin-top: .5rem;
}
.form-group {
margin-bottom: 0;
}
}
.auth-options {
margin-top: .5rem;
& > label:before {
line-height: 1;
}
}
}
.files-dialog {
.selection-list {
flex: 1;
min-width: 220px;
}
.selection-content {
flex: 2;
border: 1px solid @color-layout-border;
border-left: 0;
}
a.subscription {
display: none;
}
}

View file

@ -408,6 +408,102 @@ button.btn.print:before {
}
}
.selection-dialog {
.ui-dialog-content {
display: flex !important;
overflow: hidden !important;
}
.selection-list {
display: flex;
flex-direction: column;
border: 1px solid @color-layout-border;
justify-content: center;
}
.ui-dialog-content .popupmenu {
display: flex !important; // overwrites .popupmenu style
width: 100%;
}
.scroller {
flex: 1;
overflow-y: auto;
}
.header {
border-bottom: 1px solid @color-layout-border;
display: flex;
background-color: @color-layout-header-background;
font-size: @layout-header-font-size;
font-weight: bold;
line-height: @layout-header-height;
height: @layout-header-height;
min-height: @layout-header-height;
padding: 0 .25em;
position: relative; // for absolute positioning of searchbar
overflow: hidden;
white-space: nowrap;
}
.header-title {
width: 100%;
text-align: center;
margin: 0 2em;
}
.selection-content {
display: flex;
flex-direction: column;
}
.tab-content {
margin-top: 1rem;
height: 100%;
overflow-y: auto;
}
.form-addon {
margin: 0;
padding: .5rem 0;
width: 100%;
background-color: @color-black-shade-bg;
border-top: 1px solid @color-layout-border;
}
// overwrite .popupmenu colors
.listing {
ul {
background-color: @color-layout-list-background;
}
li.selected {
color: @color-font;
}
}
@media screen and (max-width: @screen-width-small) {
.ui-dialog-content {
padding: 0 !important;
}
.selection-list {
border: 0;
}
.ui-dialog-titlebar {
display: none;
margin: 0;
}
.selection-content {
.header-title {
margin-left: 0;
}
}
}
}
@import "include/calendar";
@import "include/kolab_activesync";

View file

@ -8,18 +8,8 @@
<div class="header">
<a class="button icon back-list-button" href="#back"><span class="inner"><roundcube:label name="back" /></span></a>
<span id="aria-label-tasklists" class="header-title"><roundcube:label name="tasklist.lists" /></span>
<div id="tasklist-search" class="searchbar toolbar" role="search" aria-labelledby="aria-label-tasklistsearchform">
<h2 id="aria-label-label-tasklistsearchform" class="voice"><roundcube:label name="tasklist.arialabelfoldersearchform" /></h2>
<form name="foldersearchform" onsubmit="return false">
<input id="tasklistsearch" type="text" name="q" placeholder="<roundcube:label name="searchplaceholder" />" />
<a class="button reset" href="#" onclick="return rcmail.command(\'reset-listsearch\',null,this,event)" title="<roundcube:label name="resetsearch" />" tabindex="0">
<span class="inner"><roundcube:label name="resetsearch" /></span>
</a>
</form>
<a class="button search" href="#" title="<roundcube:label name="tasklist.findlists" />" tabindex="0">
<span class="inner"><roundcube:label name="tasklist.findlists" /></span>
</a>
</div>
<roundcube:object name="libkolab.folder_search_form" id="tasklistsearch" wrapper="searchbar toolbar"
ariatag="h2" label="foldersearchform" label-domain="tasklist" buttontitle="findlists" />
</div>
<div id="tasklists-content" class="scroller">
<roundcube:object name="plugin.tasklists" id="tasklists" class="treelist listing iconized" />