Add ability to store view in favorites, so tiles can be put on home.

Still some bugs in resizing with this in the home portlet.
This commit is contained in:
Nathan Gray 2015-01-13 21:56:54 +00:00
parent daf62789a0
commit abb02c7b40
9 changed files with 131 additions and 37 deletions

View File

@ -100,7 +100,7 @@ var et2_dataview_tile = et2_dataview_row.extend([],
_recalculate_columns: function() {
if(this._inTree && this.tr && this.tr.parent())
{
this.columns = parseInt(this.tr.parent().innerWidth() / this.tr.outerWidth(true));
this.columns = Math.max(1,parseInt(this.tr.parent().innerWidth() / this.tr.outerWidth(true)));
}
}
});

View File

@ -113,7 +113,12 @@ var et2_nextmatch = et2_DOMWidget.extend([et2_IResizeable, et2_IInput],
"description": "Hide the second filter",
"default": et2_no_init
},
"view": {
"name": "View",
"type": "string",
"description": "Display entries as either 'row' or 'tile'. A matching template must also be set after changing this.",
"default": et2_no_init
},
"onselect": {
"name": "onselect",
"type": "js",
@ -1663,7 +1668,7 @@ var et2_nextmatch = et2_DOMWidget.extend([et2_IResizeable, et2_IInput],
* This should be followed by a call to change the template to match, which
* will cause a reload of the grid using the new settings.
*
* @param {type} view
* @param {string} view Either 'tile' or 'row'
*/
set_view: function(view)
{

View File

@ -30,12 +30,11 @@ class filemanager_favorite_portlet extends home_favorite_portlet
$ui = new filemanager_ui();
$this->context['template'] = 'filemanager.index.rows';
$this->nm_settings += array(
'get_rows' => 'filemanager.filemanager_ui.get_rows',
'csv_export' => true,
// Use a different template so it can be accessed from client side
'template' => 'filemanager.home.rows',
'template' => ($this->nm_settings['view'] == 'tile' ? 'filemanager.tile' : 'filemanager.home.rows' ),
// Filemanager needs this header, it's an important component for actions, but we reduce it to the minimum
'header_left' => 'filemanager.home.header_left',
// Use a reduced column set for home, user can change if needed
@ -80,6 +79,11 @@ class filemanager_favorite_portlet extends home_favorite_portlet
{
$ui = new filemanager_ui();
$total = $ui->get_rows($query, $rows, $readonlys);
// Change template to match selected view
if($query['view'])
{
$query['template'] = ($query['view'] == 'row' ? 'filemanager.home.rows' : 'filemanager.tile');
}
unset($GLOBALS['egw_info']['flags']['app_header']);
return $total;
}

View File

@ -482,6 +482,13 @@ class filemanager_ui
{
$tpl->setElementAttribute('nm[buttons][upload]', 'drop_target', 'popupMainDiv');
}
// Set view button to match current settings
if($content['nm']['view'] == 'tile')
{
$tpl->setElementAttribute('nm[buttons][button][change_view]','label',lang('List view'));
$tpl->setElementAttribute('nm[buttons][button][change_view]','image','list_row');
}
// if initial load is done via GET request (idots template or share.php)
// get_rows cant call app.filemanager.set_readonly, so we need to do that here
$content['initial_path_readonly'] = !egw_vfs::is_writable($content['nm']['path']);
@ -757,7 +764,7 @@ class filemanager_ui
* @param array $query
* @param array &$rows
*/
function get_rows($query, &$rows)
function get_rows(&$query, &$rows)
{
// show projectmanager sidebox for projectmanager path
if (substr($query['path'],0,20) == '/apps/projectmanager' && isset($GLOBALS['egw_info']['user']['apps']['projectmanager']))
@ -771,6 +778,11 @@ class filemanager_ui
}
if(!$query['path']) $query['path'] = static::get_home_dir();
// Change template to match selected view
if($query['view'])
{
$query['template'] = ($query['view'] == 'row' ? 'filemanager.index.rows' : 'filemanager.tile');
}
// be tolerant with (in previous versions) not correct urlencoded pathes
if (!egw_vfs::stat($query['path'],true) && egw_vfs::stat(urldecode($query['path'])))
{

View File

@ -72,6 +72,13 @@ app.classes.filemanager = AppJS.extend(
this._super.apply(this, arguments);
this.path_widget[et2.DOMContainer.id] = this.et2.getWidgetById('path') || null;
if(this.path_widget[et2.DOMContainer.id])
{
// Bind to removal to remove from list
$j(et2.DOMContainer).on('clear', function(e) {
delete app.filemanager.path_widget[e.target.id];
});
}
if(this.et2.getWidgetById('nm'))
{
@ -95,6 +102,60 @@ app.classes.filemanager = AppJS.extend(
}
},
/**
* Set the application's state to the given state.
*
* Extended from parent to also handle view
*
*
* @param {{name: string, state: object}|string} state Object (or JSON string) for a state.
* Only state is required, and its contents are application specific.
*
* @return {boolean} false - Returns false to stop event propagation
*/
setState: function(state)
{
// State should be an object, not a string, but we'll parse
if(typeof state == "string")
{
if(state.indexOf('{') != -1 || state =='null')
{
state = JSON.parse(state);
}
}
if(typeof state == "object" && state.state && state.state.view)
{
var et2 = etemplate2.getById('filemanager-index');
if(et2)
{
var nm = et2.widgetContainer.getWidgetById('nm');
nm.set_view(state.state.view);
}
}
return this._super.call(this,state);
},
/**
* Retrieve the current state of the application for future restoration
*
* Extended from parent to also set view
*
* @return {object} Application specific map representing the current state
*/
getState: function()
{
var state = this._super.apply(this);
var et2 = etemplate2.getById('filemanager-index');
if(et2)
{
var nm = et2.widgetContainer.getWidgetById('nm');
state.view = nm.view;
}
return state;
},
/**
* Regexp to convert id to a path, use this.id2path(_id)
*/
@ -609,7 +670,8 @@ app.classes.filemanager = AppJS.extend(
/**
* Toggle view between tiles and rows
*
* @param {string} [view] - Specify what to change the view to. Either 'tile' or 'row'.
* @param {string|Event} [view] - Specify what to change the view to. Either 'tile' or 'row'.
* Or, if this is used as a callback view is actually the event, and we need to find the view.
* @param {et2_widget} [button_widget] - The widget that's calling
*/
change_view: function(view, button_widget)
@ -622,6 +684,10 @@ app.classes.filemanager = AppJS.extend(
return;
}
if(!button_widget)
{
button_widget = nm.getWidgetById('button[change_view]');
}
if(button_widget && button_widget.instanceOf(et2_button))
{
// Switch view based on button icon, since controller can get re-created
@ -637,6 +703,8 @@ app.classes.filemanager = AppJS.extend(
}
nm.set_view(view);
// Put it into active filters (but don't refresh)
nm.activeFilters.view = view;
// Change template to match
this.et2.getWidgetById('nm').set_template(view == nm.controller.VIEW_ROW ? 'filemanager.index.rows' : 'filemanager.tile');
@ -765,23 +833,26 @@ app.classes.filemanager = AppJS.extend(
this.readonly = [_path, _ro];
return;
}
var path = this.get_path();
if (_path == path)
for(var id in this.path_widget)
{
var ids = ['button[linkpaste]', 'button[paste]', 'button[createdir]', 'button[symlink]', 'upload'];
for(var i=0; i < ids.length; ++i)
var path = this.get_path(id);
if (_path == path)
{
var widget = this.et2.getWidgetById(ids[i]);
if (widget)
var ids = ['button[linkpaste]', 'button[paste]', 'button[createdir]', 'button[symlink]', 'upload'];
for(var i=0; i < ids.length; ++i)
{
if (widget._type == 'button' || widget._type == 'buttononly')
var widget = etemplate2.getById(id).widgetContainer.getWidgetById(ids[i]);
if (widget)
{
widget.set_readonly(_ro);
}
else
{
widget.set_disabled(_ro);
if (widget._type == 'button' || widget._type == 'buttononly')
{
widget.set_readonly(_ro);
}
else
{
widget.set_disabled(_ro);
}
}
}
}

View File

@ -73,20 +73,15 @@ table.egwGridView_grid .tile .file_tile {
display: block;
max-width: 140px;
}
#filemanager-index_nm .tile .file_tile img.vfsMimeIcon {
.tile .file_tile img.vfsMimeIcon {
height: auto;
width: auto;
max-height: 64px;
display:block;
margin: 0 auto;
}
.egwGridView_grid tr.tile:hover .innerContainer {
overflow: visible;
}
.egwGridView_grid tr.tile:hover .file_tile > :not(.iconOverlayContainer) {
position: relative;
z-index:90;
background-color: white;
.tile .file_tile .et2_label {
word-wrap: break-word;
}
/**

View File

@ -0,0 +1,12 @@
<?xml version="1.0"?>
<!-- $Id$ -->
<!-- This template is in a seperate file so etemplate can find it for home -->
<overlay>
<template id="filemanager.home.header_left" template="" lang="" group="0" version="1.9.002">
<hbox span="all" class="filemanager_navigation">
<image label="Up" src="goup" onclick="app.filemanager.change_dir('..',widget);" id="up"/>
<image label="Go to your home directory" src="gohome" onclick="app.filemanager.change_dir('~',widget);" id="home"/>
<vfs-name label="Path" id="path" onchange="if(widget.getValue() == '') { app.filemanager.change_dir('~',widget);} return true;" size="80" class="address"/>
</hbox>
</template>
</overlay>

View File

@ -18,7 +18,7 @@
<nextmatch-header/>
</row>
<row class="tile $row_cont[class]">
<vbox class="file_tile" width="150px" height="150px">
<vbox class="file_tile" width="150px" height="110px">
<vfs-mime align="center" id="$row"/>
<vfs-name id="${row}[name]" no_lang="1" readonly="true"/>
<description id="${row}[comment]"/>

View File

@ -100,20 +100,15 @@ table.egwGridView_grid .tile .file_tile {
display: block;
max-width: 140px;
}
#filemanager-index_nm .tile .file_tile img.vfsMimeIcon {
.tile .file_tile img.vfsMimeIcon {
height: auto;
width: auto;
max-height: 64px;
display: block;
margin: 0 auto;
}
.egwGridView_grid tr.tile:hover .innerContainer {
overflow: visible;
}
.egwGridView_grid tr.tile:hover .file_tile > :not(.iconOverlayContainer) {
position: relative;
z-index: 90;
background-color: white;
.tile .file_tile .et2_label {
word-wrap: break-word;
}
/**
* Select file dialog