Automatically update the sidebar trees for all users if the trees are changed somehow.

This commit is contained in:
Jan Böhmer 2022-09-25 02:08:54 +02:00
parent 2bd41eee60
commit 4c25e85a48
5 changed files with 73 additions and 0 deletions

View file

@ -6,6 +6,8 @@ export default class extends TreeController {
_storage_key; _storage_key;
_lastUpdate;
connect() { connect() {
//Check if the tree is already initialized, if so then skip initialization (useful when going back) to in history using Turbo //Check if the tree is already initialized, if so then skip initialization (useful when going back) to in history using Turbo
if(this._isInitialized()) { if(this._isInitialized()) {
@ -31,6 +33,25 @@ export default class extends TreeController {
} else { } else {
this.setMode(default_mode); this.setMode(default_mode);
} }
//Register an event listener which checks if the tree needs to be updated
document.addEventListener('turbo:render', this.doUpdateIfNeeded.bind(this));
}
doUpdateIfNeeded()
{
const info_element = document.getElementById('sidebar-last-time-updated');
const date_str = info_element.dataset.lastUpdate;
const server_last_update = new Date(date_str);
if(this._lastUpdate < server_last_update) {
console.log("Sidebar tree is outdated, reloading (last update: " + this._lastUpdate + ", server update: " + server_last_update + ")");
this._lastUpdate = new Date();
this.reinitTree();
}
} }
setMode(mode) { setMode(mode) {
@ -47,6 +68,9 @@ export default class extends TreeController {
this.sourceTextTarget.innerText = text; this.sourceTextTarget.innerText = text;
this.setURL(url); this.setURL(url);
//Update the last update time
this._lastUpdate = new Date();
} }
changeDataSource(event) changeDataSource(event)
@ -61,5 +85,7 @@ export default class extends TreeController {
//Save the mode in local storage //Save the mode in local storage
localStorage.setItem(this._storage_key, mode); localStorage.setItem(this._storage_key, mode);
this._lastUpdate = new Date();
} }
} }

View file

@ -16,6 +16,7 @@ twig:
error_page_admin_email: '%partdb.error_pages.admin_email%' error_page_admin_email: '%partdb.error_pages.admin_email%'
error_page_show_help: '%partdb.error_pages.show_help%' error_page_show_help: '%partdb.error_pages.show_help%'
sidebar_items: '%partdb.sidebar.items%' sidebar_items: '%partdb.sidebar.items%'
sidebar_tree_updater: '@App\Services\Trees\SidebarTreeUpdater'
when@test: when@test:
twig: twig:

View file

@ -75,6 +75,11 @@ class TreeCacheInvalidationListener
if ($element instanceof AbstractStructuralDBElement || $element instanceof LabelProfile) { if ($element instanceof AbstractStructuralDBElement || $element instanceof LabelProfile) {
$secure_class_name = str_replace('\\', '_', get_class($element)); $secure_class_name = str_replace('\\', '_', get_class($element));
$this->cache->invalidateTags([$secure_class_name]); $this->cache->invalidateTags([$secure_class_name]);
//Trigger a sidebar reload for all users (see SidebarTreeUpdater service)
if(!$element instanceof LabelProfile) {
$this->cache->invalidateTags(['sidebar_tree_update']);
}
} }
//If a user change, then invalidate all cached trees for him //If a user change, then invalidate all cached trees for him

View file

@ -0,0 +1,38 @@
<?php
namespace App\Services\Trees;
use Symfony\Contracts\Cache\CacheInterface;
use Symfony\Contracts\Cache\ItemInterface;
use Symfony\Contracts\Cache\TagAwareCacheInterface;
final class SidebarTreeUpdater
{
private const CACHE_KEY = 'sidebar_tree_updated';
private const TTL = 60 * 60 * 24; // 24 hours
private CacheInterface $cache;
public function __construct(TagAwareCacheInterface $treeCache)
{
$this->cache = $treeCache;
}
/**
* Returns the time when the sidebar tree was updated the last time.
* The frontend uses this information to reload the sidebar tree.
* @return \DateTimeInterface
* @throws \Psr\SimpleCache\InvalidArgumentException
*/
public function getLastTreeUpdate(): \DateTimeInterface
{
return $this->cache->get(self::CACHE_KEY, function (ItemInterface $item) {
$item->expiresAfter(self::TTL);
//This tag and therfore this whole cache gets cleared by TreeCacheInvalidationListener when a structural element is changed
$item->tag('sidebar_tree_update');
return new \DateTime();
});
}
}

View file

@ -15,6 +15,9 @@
<div {{ stimulus_controller('turbo/global_reload') }}></div> <div {{ stimulus_controller('turbo/global_reload') }}></div>
{% endif %} {% endif %}
{# Insert info about when the sidebar trees were updated last time, so the sidebar_tree_controller can decide if it needs to reload the tree #}
<span id="sidebar-last-time-updated" style="display: none;" data-last-update="{{ sidebar_tree_updater.lastTreeUpdate.format("Y-m-d\\TH:i:sP") }}"></span>
<div class="d-none" data-title="{% apply trim %}{{ current_page_title }}{% endapply %}" {{ stimulus_controller('turbo/title') }}></div> <div class="d-none" data-title="{% apply trim %}{{ current_page_title }}{% endapply %}" {{ stimulus_controller('turbo/title') }}></div>
<div class="d-none" {{ stimulus_controller('turbo/locale_menu') }}> <div class="d-none" {{ stimulus_controller('turbo/locale_menu') }}>