Fix bug in using knownUIDs where empty rows were left or too many removed when the count changed

This commit is contained in:
Nathan Gray 2014-03-19 19:19:34 +00:00
parent e3538302fc
commit 133c4a317c
3 changed files with 116 additions and 79 deletions

View File

@ -325,6 +325,100 @@ class etemplate_widget_nextmatch extends etemplate_widget
egw_json_response::get()->apply('egw_app_header', array($GLOBALS['egw_info']['flags']['app_header'])); egw_json_response::get()->apply('egw_app_header', array($GLOBALS['egw_info']['flags']['app_header']));
} }
if($no_rows) $rows = Array();
$row_id = isset($value['row_id']) ? $value['row_id'] : 'id';
$row_modified = $value['row_modified'];
foreach($rows as $n => $row)
{
$kUkey = false;
if (is_int($n) && $row)
{
if (!isset($row[$row_id])) unset($row_id); // unset default row_id of 'id', if not used
if (!isset($row[$row_modified])) unset($row_modified);
$id = $row_id ? $row[$row_id] : $n;
$result['order'][] = $id;
// check if we need to send the data
//error_log("$id Known: " . (array_search($id, $knownUids) !== false ? 'Yes' : 'No') . ' Modified: ' . egw_time::to($row[$row_modified]) . ' > ' . egw_time::to($lastModified).'? ' . ($row[$row_modified] > $lastModified ? 'Yes' : 'No'));
if (!$row_id || !$knownUids || ($kUkey = array_search($id, $knownUids)) === false ||
!$lastModified || !isset($row[$row_modified]) || $row[$row_modified] > $lastModified)
{
$result['data'][$id] = $row;
}
if ($kUkey !== false) unset($knownUids[$kUkey]);
}
else // non-row data set by get_rows method
{
$result['rows'][$n] = $row;
}
}
// check knowUids outside of range for modification - includes deleted
/*
if ($knownUids)
{
// row_id not set for nextmatch --> just skip them, we can't identify the rows
if (!$row_id)
{
foreach($knownUids as $uid)
{
// Just don't send it back for now
unset($result['data'][$uid]);
//$result['data'][$uid] = null;
}
}
else
{
error_log(__METHOD__."() knowUids left to check ".array2string($knownUids));
// check if they are up to date: we create a query similar to csv-export without any filters
$uid_query = $value;
$uid_query['csv_export'] = 'knownUids'; // do not store $value in session
$uid_query['filter'] = $uid_query['filter2'] = $uid_query['cat_id'] = $uid_query['search'] = '';
$uid_query['col_filter'] = array($row_id => $knownUids);
// if we know name of modification column and have a last-modified date
if ($row_modified && $lastModified) // --> set filter to return only modified entries
{
$uid_query['col_filter'][] = $row_modified.' > '.(int)$lastModified;
}
$uid_query['start'] = 0;
$uid_query['num_rows'] = count($knownUids);
$rows = array();
try
{
if (self::call_get_rows($uid_query, $rows))
{
foreach($rows as $n => $row)
{
if (!is_int($n)) continue; // ignore non-row data set by get_rows method
if (!$row_modified || !isset($row[$row_modified]) ||
!isset($lastModified) || $row[$row_modified] > $lastModified)
{
$result['data'][$row[$row_id]] = $row;
$kUkey = array_search($id, $knownUids);
if ($kUkey !== false) unset($knownUids[$kUkey]);
}
}
}
}
catch (Exception $e)
{
unset($value['row_modified']);
error_log("Error trying to find changed rows with {$value['get_rows']}, falling back to all rows. ");
error_log($e);
}
// Remove any remaining knownUIDs from the grid
foreach($knownUids as $uid)
{
$result['data'][$uid] = null;
}
}
}
*/
// Check for anything changed in the query // Check for anything changed in the query
// Tell the client about the changes // Tell the client about the changes
$request_value =& self::get_array(self::$request->content, $form_name,true); $request_value =& self::get_array(self::$request->content, $form_name,true);
@ -368,82 +462,8 @@ class etemplate_widget_nextmatch extends etemplate_widget
self::$request->content = array(); self::$request->content = array();
self::$request->content = $content; self::$request->content = $content;
} }
if($no_rows) $rows = Array();
$row_id = isset($value['row_id']) ? $value['row_id'] : 'id';
$row_modified = $value['row_modified'];
foreach($rows as $n => $row)
{
$kUkey = false;
if (is_int($n) && $row)
{
if (!isset($row[$row_id])) unset($row_id); // unset default row_id of 'id', if not used
if (!isset($row[$row_modified])) unset($row_modified);
$id = $row_id ? $row[$row_id] : $n;
$result['order'][] = $id;
// check if we need to send the data
//error_log("$id Known: " . (array_search($id, $knownUids) !== false ? 'Yes' : 'No') . ' Modified: ' . egw_time::to($row[$row_modified]) . ' > ' . egw_time::to($lastModified).'? ' . ($row[$row_modified] > $lastModified ? 'Yes' : 'No'));
if (!$row_id || !$knownUids || ($kUkey = array_search($id, $knownUids)) === false ||
!$lastModified || !isset($row[$row_modified]) || $row[$row_modified] > $lastModified)
{
$result['data'][$id] = $row;
}
if ($kUkey !== false) unset($knownUids[$kUkey]);
}
else // non-row data set by get_rows method
{
$result['rows'][$n] = $row;
}
}
// check knowUids outside of range for modification
if ($knownUids)
{
// commenting out trying to validate knowUids not returned in current list,
// as this generates a second db search and they might not be visible anyway
// --> for now we tell the grid to purge them
//if (!$row_id) // row_id not set by nextmatch user --> tell client to delete data, as we cant identify rows
{
foreach($knownUids as $uid)
{
// Just don't send it back for now
unset($result['data'][$uid]);
//$result['data'][$uid] = null;
}
}
/*else
{
//error_log(__METHOD__."() knowUids left to check ".array2string($knownUids));
// check if they are up to date: we create a query similar to csv-export without any filters
$value['csv_export'] = 'knownUids'; // do not store $value in session
$value['filter'] = $value['filter2'] = $value['cat_id'] = $value['search'] = '';
$value['col_filter'] = array($row_id => $knownUids);
// if we know name of modification column and have a last-modified date
if ($row_modified && $lastModified) // --> set filter to return only modified entries
{
$value['col_filter'][] = $row_modified.' > '.(int)$lastModified;
}
$value['start'] = 0;
$value['num_rows'] = count($knownUids);
$rows = array();
if (self::call_get_rows($value, $rows))
{
foreach($rows as $n => $row)
{
if (!is_int($n)) continue; // ignore non-row data set by get_rows method
if (!$row_modified || !isset($row[$row_modified]) ||
!isset($lastModified) || $row[$row_modified] > $lastModified)
{
$result['data'][$row[$row_id]] = $row;
}
}
}
}*/
}
// Send back data
//foreach($result as $name => $value) if ($name != 'readonlys') error_log(__METHOD__."() result['$name']=".array2string($name == 'data' ? array_keys($value) : $value)); //foreach($result as $name => $value) if ($name != 'readonlys') error_log(__METHOD__."() result['$name']=".array2string($name == 'data' ? array_keys($value) : $value));
egw_json_response::get()->data($result); egw_json_response::get()->data($result);

View File

@ -756,7 +756,6 @@ var et2_dataview_controller = Class.extend({
// index entry // index entry
for (var i = mapIdx; i < _idxMap.length; i++) for (var i = mapIdx; i < _idxMap.length; i++)
{ {
this._grid.deleteRow(i);
if(typeof _idxMap[i] != 'undefined') if(typeof _idxMap[i] != 'undefined')
{ {
_idxMap[i].uid = null; _idxMap[i].uid = null;
@ -824,9 +823,18 @@ var et2_dataview_controller = Class.extend({
var order = this.count != 0 ? _response.order.splice(0, this.count) : _response.order; var order = this.count != 0 ? _response.order.splice(0, this.count) : _response.order;
// Remove from queue, or it will not be fetched again // Remove from queue, or it will not be fetched again
for(var i = this.start; i < this.start + order.length; i++) if(_response.total < this.count)
delete this.self._queue[i]; {
// Less rows than we expected
// Clear the queue, or the remnants will never be loaded again
this.self._queue = {};
}
else
{
for(var i = this.start; i < this.start + order.length; i++)
delete this.self._queue[i];
}
// Get the current index map for the updated region // Get the current index map for the updated region
var idxMap = this.self._getIndexMapping(this.start, order.length); var idxMap = this.self._getIndexMapping(this.start, order.length);

View File

@ -340,6 +340,15 @@ var et2_nextmatch_controller = et2_dataview_controller.extend(et2_IDataProvider,
} }
} }
// If we're doing an autorefresh and the count decreases, preserve the
// selection or it will be lost when the grid rows are shuffled. Increases
// are fine though.
if(this.self && this.self.kept_selection == null &&
!this.refresh && this.self._grid.getTotalCount() > _response.total)
{
this.self.keepSelection();
}
// Call the inherited function // Call the inherited function
this._super.apply(this, arguments); this._super.apply(this, arguments);