* Smarter favorite highlighting

Now highlights if the current application state matches a favorite, either by click or manually setting the filters.
This commit is contained in:
Nathan Gray 2015-06-29 19:16:56 +00:00
parent f9142139d5
commit dcc69abf9b
3 changed files with 150 additions and 7 deletions

View File

@ -1419,6 +1419,12 @@ app.classes.calendar = AppJS.extend(
state = state ? JSON.parse(state) : {}; state = state ? JSON.parse(state) : {};
} }
// Make sure date is consitantly a string, in case it needs to be passed to server
if(state.date.toJSON)
{
state.state = state.date.toJSON();
}
// Don't store current user in state to allow admins to create favourites for all // Don't store current user in state to allow admins to create favourites for all
// Should make no difference for normal users. // Should make no difference for normal users.
if(state.owner == egw.user('account_id')) if(state.owner == egw.user('account_id'))
@ -1427,6 +1433,10 @@ app.classes.calendar = AppJS.extend(
// it will work for other users too. // it will work for other users too.
state.owner = 0; state.owner = 0;
} }
// Don't store first and last
delete state.first;
delete state.last;
return state; return state;
}, },
@ -1468,7 +1478,10 @@ app.classes.calendar = AppJS.extend(
} }
} }
} }
$j(this.sidebox_et2.getInstanceManager().DOMContainer).hide(); if(this.sidebox_et2)
{
$j(this.sidebox_et2.getInstanceManager().DOMContainer).hide();
}
// Check for a supported client-side view // Check for a supported client-side view
if(this.views[state.state.view] && if(this.views[state.state.view] &&
@ -1675,6 +1688,9 @@ app.classes.calendar = AppJS.extend(
} }
},this,et2_valueWidget); },this,et2_valueWidget);
// If current state matches a favorite, hightlight it
this.highlight_favorite();
// Sidebox is updated, we can clear the flag // Sidebox is updated, we can clear the flag
this.state_update_in_progress = false; this.state_update_in_progress = false;

View File

@ -412,6 +412,7 @@ var et2_nextmatch = et2_DOMWidget.extend([et2_IResizeable, et2_IInput, et2_IPrin
*/ */
applyFilters: function(_set) { applyFilters: function(_set) {
var changed = false; var changed = false;
var keep_selection = false;
// Avoid loops cause by change events // Avoid loops cause by change events
if(this.update_in_progress) return; if(this.update_in_progress) return;
@ -464,6 +465,17 @@ var et2_nextmatch = et2_DOMWidget.extend([et2_IResizeable, et2_IInput, et2_IPrin
} }
} }
} }
else if (s === 'selected')
{
changed = true;
keep_selection = true;
this.controller._selectionMgr.resetSelection();
for(var i in _set.selected)
{
this.controller._selectionMgr.setSelected(_set.selected[i].indexOf('::') > 0 ? _set.selected[i] : this.controller.dataStorePrefix + '::'+_set.selected[i],true);
}
delete _set.selected;
}
else if (this.activeFilters[s] !== _set[s]) else if (this.activeFilters[s] !== _set[s])
{ {
this.activeFilters[s] = _set[s]; this.activeFilters[s] = _set[s];
@ -475,7 +487,7 @@ var et2_nextmatch = et2_DOMWidget.extend([et2_IResizeable, et2_IInput, et2_IPrin
this.egw().debug("info", "Changing nextmatch filters to ", this.activeFilters); this.egw().debug("info", "Changing nextmatch filters to ", this.activeFilters);
// Keep the selection after applying filters, but only if unchanged // Keep the selection after applying filters, but only if unchanged
if(!changed) if(!changed || keep_selection)
{ {
this.controller.keepSelection(); this.controller.keepSelection();
} }
@ -509,6 +521,19 @@ var et2_nextmatch = et2_DOMWidget.extend([et2_IResizeable, et2_IInput, et2_IPrin
// Trigger an update // Trigger an update
this.controller.update(true); this.controller.update(true);
if(changed)
{
// Highlight matching favorite in sidebox
if(this.getInstanceManager().app)
{
var app = this.getInstanceManager().app;
if(window.app[app] && window.app[app].highlight_favorite)
{
window.app[app].highlight_favorite();
}
}
}
this.update_in_progress = false; this.update_in_progress = false;
}, },

View File

@ -142,6 +142,9 @@ var AppJS = Class.extend(
this.et2 = et2.widgetContainer; this.et2 = et2.widgetContainer;
this._fix_iFrameScrolling(); this._fix_iFrameScrolling();
if (this.egw && this.egw.is_popup()) this._set_Window_title(); if (this.egw && this.egw.is_popup()) this._set_Window_title();
// Highlights the favorite based on initial list state
this.highlight_favorite();
}, },
/** /**
@ -370,10 +373,14 @@ var AppJS = Class.extend(
li.siblings().removeClass('ui-state-highlight'); li.siblings().removeClass('ui-state-highlight');
// Wait an arbitrary 50ms to avoid having the class removed again // Wait an arbitrary 50ms to avoid having the class removed again
// by the change handler. // by the change handler.
window.setTimeout(function() { if(li.attr('data-id') !== 'blank')
li.addClass('ui-state-highlight'); {
},50); window.setTimeout(function() {
li.addClass('ui-state-highlight');
},50);
}
var href = jQuery('a[href^="javascript:"]', this).prop('href'); var href = jQuery('a[href^="javascript:"]', this).prop('href');
var matches = href ? href.match(/^javascript:([^\(]+)\((.*)?\);?$/) : null; var matches = href ? href.match(/^javascript:([^\(]+)\((.*)?\);?$/) : null;
if (matches && matches.length > 1 && matches[2] !== undefined) if (matches && matches.length > 1 && matches[2] !== undefined)
@ -418,7 +425,7 @@ var AppJS = Class.extend(
$j(egw_fw.applications[this.appname].browser.baseDiv) $j(egw_fw.applications[this.appname].browser.baseDiv)
.off('.sidebox') .off('.sidebox')
.on('change.sidebox', function() { .on('change.sidebox', function() {
$j('li',self.sidebox).removeClass('ui-state-highlight'); self.highlight_favorite();
}); });
} }
return true; return true;
@ -741,6 +748,101 @@ var AppJS = Class.extend(
return false; return false;
}, },
/**
* Mark the favorite closest matching the current state
*
* Closest matching takes into account not set values, so we pick the favorite
* with the most matching values without a value that differs.
*/
highlight_favorite: function() {
if(!this.sidebox) return;
var state = this.getState();
var best_match = false;
var best_count = 0;
$j('li[data-id]',this.sidebox).removeClass('ui-state-highlight');
$j('li[data-id] a[href^="javascript:"]',this.sidebox).each(function(i,href) {
var matches = href.href ? href.href.match(/^javascript:([^\(]+)\((.*)?\);?$/) : null;
var favorite = {}
if (matches && matches.length > 1 && matches[2] !== undefined)
{
favorite = JSON.parse(decodeURI(matches[2]));
}
if(!favorite || jQuery.isEmptyObject(favorite)) return;
var match_count = 0;
for(var state_key in state)
{
if(state[state_key] == favorite.state[state_key] || !state[state_key] && !favorite.state[state_key])
{
match_count++;
}
else if (state[state_key] && typeof state[state_key] === 'object' && favorite.state[state_key] && typeof favorite.state[state_key] === 'object')
{
if((typeof state[state_key].length !== 'undefined' || typeof state[state_key].length !== 'undefined')
&& (state[state_key].length || Object.keys(state[state_key]).length) != (favorite.state[state_key].length || Object.keys(favorite.state[state_key]).length ))
{
// State or favorite has a length, but the other does not
if((state[state_key].length === 0 || Object.keys(state[state_key]).length === 0) &&
(favorite.state[state_key].length == 0 || Object.keys(favorite.state[state_key]).length === 0))
{
// Just missing, or one is an array and the other is an object
continue;
}
// One has a value and the other doesn't, no match
debugger;
return;
}
// Consider sub-objects (column filters) individually
for(var sub_key in state[state_key])
{
if(state[state_key][sub_key] == favorite.state[state_key][sub_key] || !state[state_key][sub_key] && !favorite.state[state_key][sub_key])
{
match_count++;
}
else if (typeof state[state_key][sub_key] === 'object' && typeof state[state_key][sub_key] === 'object')
{
// Too deep to keep going, just string compare for perfect match
if(state[state_key][sub_key].toJSON() === state[state_key][sub_key])
{
match_count++;
}
}
else if(state[state_key][sub_key] && state[state_key][sub_key] != favorite.state[state_key][sub_key])
{
// Different values, do not match
debugger;
return;
}
}
}
else if (state_key == 'selectcols')
{
// Skip, might be set, might not
}
else if (typeof state[state_key] !== 'undefined' && state[state_key] != favorite.state[state_key])
{
// Different values, do not match
debugger;
return;
}
}
if(match_count > best_count)
{
best_match = href.parentNode.dataset.id;
best_count = match_count;
}
});
if(best_match)
{
$j('li[data-id="'+best_match+'"]',this.sidebox).addClass('ui-state-highlight');
}
},
/** /**
* Fix scrolling iframe browsed by iPhone/iPod/iPad touch devices * Fix scrolling iframe browsed by iPhone/iPod/iPad touch devices
*/ */