Store limited list widget configuration in user preferences (#4360)

Provides a new method of storing the list page count and visible column configs that survives a user logging out then logging back in to October. In addition, the users are provided with a "Reset to Default" button in the config modal allowing them to use the default list config if preferred.
This commit is contained in:
Ben Thomson 2019-06-08 11:28:08 +08:00 committed by GitHub
parent 66776e0614
commit 6d283829c0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 165 additions and 6 deletions

View File

@ -0,0 +1,139 @@
<?php namespace Backend\Traits;
use Str;
use Backend\Models\UserPreference;
/**
* Preference Maker Trait
*
* Adds methods for modifying user preferences in a controller class, or a class
* that contains a `$controller` property referencing a controller.
*/
trait PreferenceMaker
{
/**
* Cache for retrieved user preferences.
*
* @var array
*/
protected static $preferenceCache = [];
/**
* Saves a widget related key/value pair in to the users preferences
* @param string $key Unique key for the data store.
* @param mixed $value The value to store.
* @return void
*/
public function putUserPreference(string $key, $value): void
{
$preferences = $this->getUserPreferences();
$preferences[$key] = $value;
$this->getPreferenceStorage()->set($this->getPreferenceKey(), $preferences);
// Re-cache user preferences
self::$preferenceCache[$this->getPreferenceKey()] = $preferences;
}
/**
* Retrieves a widget related key/value pair from the user preferences
*
* @param string $key Unique key for the data store.
* @param mixed $default A default value to use when value is not found.
* @return mixed
*/
public function getUserPreference(string $key = null, $default = null)
{
$preferences = $this->getUserPreferences();
return (isset($preferences[$key])) ? $preferences[$key] : $default;
}
/**
* Retrieves and caches all user preferences for this particular controller/widget.
*
* @return array
*/
public function getUserPreferences(): array
{
if (isset(self::$preferenceCache[$this->getPreferenceKey()])) {
return self::$preferenceCache[$this->getPreferenceKey()];
}
$preferences = $this->getPreferenceStorage()->get($this->getPreferenceKey(), []);
// Cache user preferences
self::$preferenceCache[$this->getPreferenceKey()] = $preferences;
return $preferences;
}
/**
* Clears a single preference key from the user preferences for this controller/widget.
*
* @param string $key Unique key for the data store.
* @return void
*/
public function clearUserPreference(string $key): void
{
$preferences = $this->getUserPreferences();
if (!isset($preferences[$key])) {
return;
}
unset($preferences[$key]);
if (count($preferences)) {
$this->getPreferenceStorage()->set($this->getPreferenceKey(), $preferences);
// Re-cache user preferences
self::$preferenceCache[$this->getPreferenceKey()] = $preferences;
} else {
// Remove record from user preferences
$this->clearUserPreferences();
}
}
/**
* Clears all user preferences for this controller/widget.
*
* @return void
*/
public function clearUserPreferences(): void
{
$this->getPreferenceStorage()->reset($this->getPreferenceKey());
self::$preferenceCache[$this->getPreferenceKey()] = [];
}
/**
* Returns a unique identifier for this widget and controller action for preference storage.
*
* @return string
*/
protected function getPreferenceKey(): string
{
$controller = (property_exists($this, 'controller') && $this->controller)
? $this->controller
: $this;
$uniqueId = (method_exists($this, 'getId')) ? $this->getId() : $controller->getId();
// Removes Class name and "Controllers" directory
$rootNamespace = Str::getClassId(Str::getClassNamespace(Str::getClassNamespace($controller)));
// The controller action is intentionally omitted, preferences should be shared for all actions
return $rootNamespace . '::' . strtolower(class_basename($controller)) . '.' . strtolower($uniqueId);
}
/**
* Specifies the model used for storing the user preferences.
*
* @return October\Rain\Database\Model
*/
protected function getPreferenceStorage()
{
return UserPreference::forUser();
}
}

View File

@ -24,6 +24,8 @@ use ApplicationException;
*/
class Lists extends WidgetBase
{
use Backend\Traits\PreferenceMaker;
//
// Configurable properties
//
@ -207,7 +209,7 @@ class Lists extends WidgetBase
/*
* Configure the list widget
*/
$this->recordsPerPage = $this->getSession('per_page', $this->recordsPerPage);
$this->recordsPerPage = $this->getUserPreference('per_page', $this->recordsPerPage);
if ($this->showPagination == 'auto') {
$this->showPagination = $this->recordsPerPage && $this->recordsPerPage > 0;
@ -502,7 +504,7 @@ class Lists extends WidgetBase
$joinSql = $countQuery->select($joinSql)->toSql();
$selects[] = Db::raw("(".$joinSql.") as ".$alias);
/*
* If this is a polymorphic relation there will be bindings that need to be added to the query
*/
@ -546,7 +548,7 @@ class Lists extends WidgetBase
* Add custom selects
*/
$query->addSelect($selects);
/*
* Add bindings for polymorphic relations
*/
@ -725,7 +727,7 @@ class Lists extends WidgetBase
* Supplied column list
*/
if ($this->columnOverride === null) {
$this->columnOverride = $this->getSession('visible', null);
$this->columnOverride = $this->getUserPreference('visible', null);
}
if ($this->columnOverride && is_array($this->columnOverride)) {
@ -1597,12 +1599,22 @@ class Lists extends WidgetBase
{
if (($visibleColumns = post('visible_columns')) && is_array($visibleColumns)) {
$this->columnOverride = $visibleColumns;
$this->putSession('visible', $this->columnOverride);
$this->putUserPreference('visible', $this->columnOverride);
}
$this->recordsPerPage = post('records_per_page', $this->recordsPerPage);
$this->putSession('order', post('column_order'));
$this->putSession('per_page', $this->recordsPerPage);
$this->putUserPreference('per_page', $this->recordsPerPage);
return $this->onRefresh();
}
/**
* Event handler to apply the list set up.
*/
public function onResetSetup()
{
$this->clearUserPreference('visible');
$this->clearUserPreference('per_page');
return $this->onRefresh();
}

View File

@ -48,6 +48,14 @@
</div>
<div class="modal-footer">
<button
type="button"
class="btn btn-link pull-left"
data-request="<?= $this->getEventHandler('onResetSetup') ?>"
data-dismiss="popup"
data-stripe-load-indicator>
<?= e(trans('backend::lang.form.reset_default')) ?>
</button>
<button
type="button"
class="btn btn-primary"