diff --git a/library/Icingadb/Web/Controller.php b/library/Icingadb/Web/Controller.php index 5e5eafaa..ede186c0 100644 --- a/library/Icingadb/Web/Controller.php +++ b/library/Icingadb/Web/Controller.php @@ -11,11 +11,8 @@ use GuzzleHttp\Psr7\ServerRequest; use Icinga\Application\Config; use Icinga\Application\Icinga; use Icinga\Application\Logger; -use Icinga\Application\Version; use Icinga\Application\Web; use Icinga\Data\ConfigObject; -use Icinga\Date\DateFormatter; -use Icinga\Exception\ConfigurationError; use Icinga\Exception\Http\HttpBadRequestException; use Icinga\Exception\Json\JsonDecodeException; use Icinga\Module\Icingadb\Common\Auth; @@ -27,10 +24,9 @@ use Icinga\Module\Icingadb\Data\JsonResultSet; use Icinga\Module\Icingadb\Data\QueryColumnsProvider; use Icinga\Module\Icingadb\Web\Control\ColumnChooser; use Icinga\Module\Icingadb\Web\Control\GridViewModeSwitcher; +use Icinga\Module\Icingadb\Web\Control\TimestampToggle; use Icinga\Module\Icingadb\Web\Control\ViewModeSwitcher; use Icinga\Module\Icingadb\Widget\ItemTable\StateItemTable; -use Icinga\Module\Pdfexport\PrintableHtmlDocument; -use Icinga\Module\Pdfexport\ProvidedHook\Pdfexport; use Icinga\Security\SecurityException; use Icinga\User\Preferences; use Icinga\User\Preferences\PreferencesStore; @@ -190,10 +186,9 @@ class Controller extends CompatController $preferencesStore = PreferencesStore::create(new ConfigObject([ 'resource' => Config::app()->get('global', 'config_resource') ]), $user); - $preferencesStore->load(); - $preferencesStore->save( - new Preferences(['icingadb' => ['view_modes' => Json::encode($preferredModes)]]) - ); + $preferences = $preferencesStore->load(); + $preferences['icingadb']['view_modes'] = Json::encode($preferredModes); + $preferencesStore->save(new Preferences($preferences)); } catch (Exception $e) { Logger::error('Failed to save preferred view mode for user "%s": %s', $user->getUsername(), $e); } @@ -266,6 +261,58 @@ class Controller extends CompatController return $viewModeSwitcher; } + /** + * Create a control to switch between relative and absolute timestamps + * + * @return TimestampToggle + */ + public function createTimestampControl(): TimestampToggle + { + $path = $this->getRequest()->getUrl()->getPath(); + $timestampMode = $this->params->shift(TimestampToggle::DEFAULT_TIMESTAMP_MODE_PARAM); + $user = $this->Auth()->getUser(); + if ($timestampMode === null) { + $preferences = $user->getAdditional('icingadb.timestamps'); + if ($preferences === null) { + $preferences = Json::decode( + $user->getPreferences()->getValue('icingadb', 'timestamps', '[]'), + true + ); + $user->setAdditional('icingadb.timestamps', $preferences); + } + + $timestampMode = $preferences[$path] ?? 'absolute'; + } + + return (new TimestampToggle($timestampMode === 'relative')) + ->on( + TimestampToggle::ON_SUBMIT, + function (TimestampToggle $toggle) use ($path, $user) { + // The js changes the representation in the frontend, this request only saves the preference, + // so we can skip all unnecessary work and signal the frontend not to replace the DOM + $this->_helper->viewRenderer->setNoRender(true); + $this->_helper->layout->disableLayout(); + $this->ignoreXhrBody(); + + try { + $preferencesStore = PreferencesStore::create(new ConfigObject([ + 'resource' => Config::app()->get('global', 'config_resource') + ]), $user); + $storedPreferences = $preferencesStore->load(); + $preferences = $user->getAdditional('icingadb.timestamps') + ?? Json::decode($storedPreferences['icingadb']['timestamps'] ?? '[]', true); + + $preferences[$path] = $toggle->getToggleValue(); + $user->setAdditional('icingadb.timestamps', $preferences); + $storedPreferences['icingadb']['timestamps'] = Json::encode($preferences); + $preferencesStore->save(new Preferences($storedPreferences)); + } catch (Exception $e) { + Logger::error('Failed to save timestamp mode for user "%s": %s', $user->getUsername(), $e); + } + } + )->handleRequest($this->getServerRequest()); + } + /** * Process a search request *