Home: Better initial load of new favorites

Less server requests, shows data without reload, favorite select populated immediately
This commit is contained in:
nathan 2023-03-15 10:15:25 -06:00
parent 1a665046c9
commit 17018a7a24
5 changed files with 120 additions and 36 deletions

View File

@ -418,7 +418,7 @@ export class Et2Portlet extends Et2Widget(SlCard)
let content = this.portletProperties; let content = this.portletProperties;
// Add values, but skip any duplicate properties // Add values, but skip any duplicate properties
Object.keys(this.settings).forEach(k => Object.keys(this.settings || {}).forEach(k =>
{ {
if(typeof k == "string" && isNaN(parseInt(k)) || content.filter(v => v.name == this.settings[k].name).length == 0) if(typeof k == "string" && isNaN(parseInt(k)) || content.filter(v => v.name == this.settings[k].name).length == 0)
{ {
@ -488,17 +488,17 @@ export class Et2Portlet extends Et2Widget(SlCard)
public update_settings(settings) public update_settings(settings)
{ {
// Skip any updates during loading // Skip any updates during loading
if(!this.getInstanceManager().isReady) if(this.getInstanceManager() && !this.getInstanceManager().isReady)
{ {
return; return Promise.resolve();
} }
// Save settings - server might reply with new content if the portlet needs an update, // Save settings - server might reply with new content if the portlet needs an update,
// but ideally it doesn't // but ideally it doesn't
this.classList.add("loading"); this.classList.add("loading");
return this.egw().jsonq("home.home_ui.ajax_set_properties", [this.id, [], settings, this.settings ? this.settings.group : false], return this.egw().request("home.home_ui.ajax_set_properties", [this.id, [], settings, this.settings ? this.settings.group : false])
function(data) .then((data) =>
{ {
// This section not for us // This section not for us
if(!data || typeof data.attributes == 'undefined') if(!data || typeof data.attributes == 'undefined')
@ -536,9 +536,7 @@ export class Et2Portlet extends Et2Widget(SlCard)
this.egw().debug('warn', e, this); this.egw().debug('warn', e, this);
} }
} }
}, });
this);
} }
render() render()

View File

@ -85,20 +85,18 @@ class home_favorite_portlet extends home_portlet
} }
// Load and copy favorite // Load and copy favorite
if($context['favorite'] && !is_array($context['favorite'])) if($context['favorite'])
{ {
$favorites = Framework\Favorites::get_favorites($context['appname']); $favorites = Framework\Favorites::get_favorites($context['appname']);
$context['favorite'] = $favorites[$context['favorite']];
$need_reload = true;
} }
$this->favorite = (array)$context['favorite']; $this->favorite = (array)$favorites[$context['favorite'] ?: 'blank'];
$this->title = lang($context['appname']) . ': ' . $this->favorite['name']; $this->title = lang($context['appname']) . ': ' . $this->favorite['name'];
$this->context = $context; $this->context = $context;
if($this->favorite) if($this->favorite)
{ {
$this->nm_settings['favorite'] = $this->context['favorite']; $this->nm_settings['favorite'] = $this->context['favorite'];
if(is_array($this->favorite['state'])) if(is_array($favorites[$context['favorite']]['state']))
{ {
$this->nm_settings += $this->favorite['state']; $this->nm_settings += $this->favorite['state'];
} }

View File

@ -427,6 +427,7 @@ class home_ui
'id' => $portlet, 'id' => $portlet,
'caption' => $desc['displayName'], 'caption' => $desc['displayName'],
'hint' => $desc['description'], 'hint' => $desc['description'],
'appname' => $appname,
'onExecute' => 'javaScript:app.home.add', 'onExecute' => 'javaScript:app.home.add',
'acceptedTypes' => $instance->accept_drop(), 'acceptedTypes' => $instance->accept_drop(),
'allowOnMultiple' => $instance->accept_multiple() 'allowOnMultiple' => $instance->accept_multiple()

View File

@ -4,6 +4,7 @@ import shoelace from "../../api/js/etemplate/Styles/shoelace";
import {etemplate2} from "../../api/js/etemplate/etemplate2"; import {etemplate2} from "../../api/js/etemplate/etemplate2";
import type {SelectOption} from "../../api/js/etemplate/Et2Select/FindSelectOptions"; import type {SelectOption} from "../../api/js/etemplate/Et2Select/FindSelectOptions";
import {Et2Favorites} from "../../api/js/etemplate/Et2Favorites/Et2Favorites"; import {Et2Favorites} from "../../api/js/etemplate/Et2Favorites/Et2Favorites";
import {Et2Dialog} from "../../api/js/etemplate/Et2Dialog/Et2Dialog";
export class Et2PortletFavorite extends Et2Portlet export class Et2PortletFavorite extends Et2Portlet
{ {
@ -41,26 +42,99 @@ export class Et2PortletFavorite extends Et2Portlet
* @returns {[{name : string, type : string, select_options? : [SelectOption]}]} * @returns {[{name : string, type : string, select_options? : [SelectOption]}]}
*/ */
get portletProperties() : { name : string, type : string, label : string, select_options? : SelectOption[] }[] get portletProperties() : { name : string, type : string, label : string, select_options? : SelectOption[] }[]
{
return [
...super.portletProperties,
{name: "favorite", type: "et2-select", label: "Favorite", select_options: this.favorites}
]
}
public get favorites()
{ {
// Default blank filter // Default blank filter
let favorites = [ let favorites = [
{value: 'blank', label: this.egw().lang("No filters")} {value: 'blank', label: this.egw().lang("No filters"), favorite: {}}
]; ];
// Load favorites // Load favorites
let preferences : any = this.egw().preference("*", this.settings.appname); if(this.settings?.appname)
for(let pref_name in preferences)
{ {
if(pref_name.indexOf(Et2Favorites.PREFIX) == 0 && typeof preferences[pref_name] == 'object') let preferences : any = this.egw().preference("*", this.settings.appname);
for(let pref_name in preferences)
{ {
let name = pref_name.substr(Et2Favorites.PREFIX.length); if(pref_name.indexOf(Et2Favorites.PREFIX) == 0 && typeof preferences[pref_name] == 'object')
favorites.push({value: name, label: preferences[pref_name]['name']}); {
let name = pref_name.substr(Et2Favorites.PREFIX.length);
favorites.push({
value: name,
label: preferences[pref_name]['name'],
favorite: preferences[pref_name]
});
}
} }
} }
return [ return favorites;
...super.portletProperties, }
{name: "favorite", type: "et2-select", label: "Favorite", select_options: favorites}
] /**
* Overridden so we can just apply the favorite to the nm
*
* @param button_id
* @param value
*/
_process_edit(button_id, value)
{
if(button_id == Et2Dialog.OK_BUTTON && value.favorite != this.settings.favorite)
{
const state = this.favorites.find(f => f.value == value.favorite)?.favorite || {};
if(this.nm && typeof state == "object")
{
// Firefox has trouble with spaces in search
if(state.state && state.state.search)
{
state.state.search = unescape(state.state.search);
}
// Apply
if(state.state && state.state.sort && state.state.sort.id)
{
this.nm.sortBy(state.state.sort.id, state.state.sort.asc, false);
}
else
{
// Not using resetSort() to avoid the extra applyFilters() call
this.nm.sortBy(undefined, undefined, false);
}
if(state.state && state.state.selectcols)
{
// Make sure it's a real array, not an object, then set cols
this.nm.set_columns(jQuery.extend([], state.state.selectcols));
}
this.nm.applyFilters(state.state || state.filter || {});
}
}
super._process_edit(button_id, value);
}
/**
* Override parent to force resize on initial load
* @param settings
* @returns {Promise<void> | Promise<boolean>}
*/
update_settings(settings) : Promise<void> | Promise<boolean>
{
return super.update_settings(settings)
.then(result =>
{
// Response did not ask for settings, and was not understandable for us
if(result == false && !this.nm)
{
// If child was added recently (not loaded in normal reload), resize them all
etemplate2.getByTemplate("home.favorite").forEach(et => (<etemplate2>et).resize(undefined))
}
return result;
});
} }
headerTemplate() headerTemplate()
@ -78,11 +152,16 @@ export class Et2PortletFavorite extends Et2Portlet
`; `;
} }
protected get nm()
{
return this.getWidgetById('nm') || etemplate2.getById(this.id) && etemplate2.getById(this.id).widgetContainer.getWidgetById('nm') || false;
}
public toggleHeader() public toggleHeader()
{ {
//widget.set_class(widget.class == 'opened' ? 'closed' : 'opened'); //widget.set_class(widget.class == 'opened' ? 'closed' : 'opened');
// We operate on the DOM here, nm should be unaware of our fiddling // We operate on the DOM here, nm should be unaware of our fiddling
let nm = this.getWidgetById('nm') || etemplate2.getById(this.id) && etemplate2.getById(this.id).widgetContainer.getWidgetById('nm') || false; let nm = this.nm
if(!nm) if(!nm)
{ {
return; return;

View File

@ -178,9 +178,6 @@ export class HomeApp extends EgwApp
et2.DOMContainer.id = et2.uniqueId; et2.DOMContainer.id = et2.uniqueId;
} }
// Instanciate custom code for this portlet
this._get_portlet_code(portlet);
// Ordering of portlets // Ordering of portlets
// Only needs to be done once, but its hard to tell when everything is loaded // Only needs to be done once, but its hard to tell when everything is loaded
this._do_ordering(); this._do_ordering();
@ -241,9 +238,18 @@ export class HomeApp extends EgwApp
{ {
// Basic portlet attributes // Basic portlet attributes
let attrs = { let attrs = {
id: this._create_id(), id: this._create_id(),
class: action.data.class class: action.data.class,
settings: {}
}; };
// Add extra data from action
Object.keys(action.data).forEach(k =>
{
if(["id", "type", "acceptedTypes", "class"].indexOf(k) == -1)
{
attrs["settings"][k] = action.data[k];
}
})
// Try to put it about where the menu was opened // Try to put it about where the menu was opened
if(action.menu_context) if(action.menu_context)
@ -258,10 +264,15 @@ export class HomeApp extends EgwApp
portlet.loadingFinished(); portlet.loadingFinished();
// Get actual attributes & settings, since they're not available client side yet // Get actual attributes & settings, since they're not available client side yet
portlet.update_settings(attrs); portlet.update_settings(attrs).then((result) =>
{
// Instanciate custom code for this portlet // Initial add needs to wait for the update to come back, then ask about settings
this._get_portlet_code(portlet); // Etemplate can conflict with portlet asking for settings
if(result === false)
{
portlet.edit_settings();
}
});
} }
/** /**
@ -311,9 +322,6 @@ export class HomeApp extends EgwApp
// Get actual attributes & settings, since they're not available client side yet // Get actual attributes & settings, since they're not available client side yet
portlet.update_settings(attrs); portlet.update_settings(attrs);
// Instanciate custom code for this portlet
this._get_portlet_code(portlet);
} }
/** /**