icingaweb2-module-businessprocess
icingaweb2-module-businessprocess copied to clipboard
Remember collapsed tree branches through multiple browser/page sessions
Is your feature request related to a problem? Please describe.
I wanted to save my current view but there is no possibility to save it in this state.
Describe the solution you'd like
It would be nice to have some possibilities to save the current state of this view. As an example:
Changing to tree view would open all subprocesses and I have to hide all of them by hand.
(current state after refresh)
(enhanced view)
Describe alternatives you've considered
There are no real alternatives
Additional context
Would be nice to hear what do you think about these features.
Best Pascal
Hi, just to ensure I understand this correctly: You want the collapsed branches being kept collapsed after leaving and revisiting the page? Just like it's the case for the plugin output in a host's or service's detail view?
This, of course, is a good idea! I already wanted to implement this (since plugin-output behaves the same way) but forgot about it. Thanks for the reminder. ;)
Regarding your additional context, please open a new issue for this.
Hi, you got it correctly. This would be a nice feature.
Thanks
Just for the records, I think that this is already possible. The state is persisted as long as the session is alive and if you just refresh the views using Web's own refresh buttons instead of using a hard reload via the browser for example.
It makes sense to support browser reloads though. But I'm note quite sure whether it is a good idea to persist the state across sessions. Note that we introduce a remember me feature with Web 2.9.0 which may have an impact here.
It should work the same way as for the plugin output/custom variables in the monitoring module. Rememberme is not necessary for this, localStorage is.
@lippserd, @nilmerg: I did a quick research, as this definitively used to work. It was an essential requirement stated by the original sponsor of this module. Supporting browser reloads was mandatory. This didn't break in this module but with Icinga Web 2.6.
The problem is, that since 8212c51 our windowId no longer survives reloads. We used window.name as our window identification, because that's... well, it's purpose. This information isn't available on the initial HTTP request, that's why it's detection had to be deferred to the first XHR request. It was the client's responsibility to negotiate a new windowId in case it didn't have such.
Now, the problem is that you'll never get this information without JS, but that's part of the game. Issue #3609 tried to address this and did so by generating the ID on the server side. As there will never be a window.name shipped by the first request (read: window reload), this will always be the case. So right now our windowId is no longer a Window ID, as we ship a new one on every non-XHR-request.
I do not like a dependency on localStorage and I do not see how this would fix the problem 8212c51 tried to tackle. @lippserd: we talked about this before, as it broke other things too. @nilmerg: if you need help with fixing this in a compatible way I'd love to assist you. To me this is an essential funtionality. Being able to build code trusting a windowId is important for existing and upcoming features.
@lippserd, @nilmerg: I did a quick research, as this definitively used to work. It was an essential requirement stated by the original sponsor of this module. Supporting browser reloads was mandatory. This didn't break in this module but with Icinga Web 2.6.
The problem is, that since 8212c51 our
windowIdno longer survives reloads. We usedwindow.nameas our window identification, because that's... well, it's purpose. This information isn't available on the initial HTTP request, that's why it's detection had to be deferred to the first XHR request. It was the client's responsibility to negotiate a newwindowIdin case it didn't have such.Now, the problem is that you'll never get this information without JS, but that's part of the game. Issue #3609 tried to address this and did so by generating the ID on the server side. As there will never be a
window.nameshipped by the first request (read: window reload), this will always be the case. So right now ourwindowIdis no longer a Window ID, as we ship a new one on every non-XHR-request.I do not like a dependency on
localStorageand I do not see how this would fix the problem 8212c51 tried to tackle. @lippserd: we talked about this before, as it broke other things too. @nilmerg: if you need help with fixing this in a compatible way I'd love to assist you. To me this is an essential funtionality. Being able to build code trusting awindowIdis important for existing and upcoming features.
You're right with the window.name part and I thought we already fixed that but I have to disappoint you with the tree state persistence. It is just a simple variable cache since version 2.0.0 and gets deleted of course after a hard reload.
I'll create a new issue for window.name in Web. Though, @Thomas-Gelf you have to talk to me about the existing [1] and upcoming features relying on caching variables for window.name. I don't think that it is a good idea to do that without some utility functions that automatically clear variables for closed windows/tabs.
[1] I'm only aware of the Director session namespaces for the db connection(s).
[..] but I have to disappoint you with the tree state persistence. It is just a simple variable cache since version 2.0.0 and gets deleted of course after a hard reload.
So you're saying that this only worked with "inline reloads" in Icinga Web 2? That's possible, the initial version has been running as an iFrame in Icinga Web 1.x - and therefore didn't have that luxury :laughing: Anyway, we should then implement this here too. I'd love to see this working as follows:
- state per window (not container) and process stored to your session (in a related namespace)
- rendering respects state and applies collapsed-state classes accordingly
- JS persists local state and ships it on refresh (via XHR) to the server
Because the user might continue to click around while rendering takes place, after rendering the new content to the container JavaScript should apply it's state to the received HTML. Why two steps?
- when you don't click while server is rendering, you do not want to see it flickering on refresh
- when you do, and the server rendered with an outdated state, you of course want to have those modifications that took place in the meantime being applied
It would be nice to add container-IDs to the mix, but only once we made sure that container IDs become persistent/related to their window. Using something like windowId + '_' + $container.attr('id') might help. As long as we don't, sessions would grow way too fast. Use-case for container-based state: same business processes with different collapsed nodes in different dashlets on a dashboard. Probably a rare use-case.
I'll create a new issue for
window.namein Web.
Great, thank you!
Though, @Thomas-Gelf you have to talk to me about the existing [1] and upcoming features relying on caching variables for
window.name. I don't think that it is a good idea to do that without some utility functions that automatically clear variables for closed windows/tabs.[1] I'm only aware of the Director session namespaces for the db connection(s).
Businessprocess is another one. While collapsed state doesn't seem to be related to the windowId, simulations are so. This is something we need every time we modify state in a browser window without persisting it yet. Rarely happens right now, but would be a useful feature. If there was no use for this we shouldn't have created Window->getSessionNamespace() at all ;-)
Personally I don't really worry about clearing variables. At least as long as we keep IDs persistent in relation to their window. Of course, when you accumulate a lot of state with lots of tabs and never log out this might become an issue. Session will grow at server side unless your next logout. Shouldn't happen with normal use. In case you're worried: throw Zend_Cache into the mix. Accessing a Window-related session namespace should then prune outdated ones.
Problem with this approach: we must first make sure that background tabs refresh their containers at least from time to time. As far as I know currently they're completely disabled.
I'd love to see this working as follows[...]
I don't know why we should send client state back-and-forth and persist it on the server when we have localStorage. I'm sure sure we go that way for such a feature as we already did.
Personally I don't really worry about clearing variables. At least as long as we keep IDs persistent in relation to their window. Of course, when you accumulate a lot of state with lots of tabs and never log out this might become an issue. Session will grow at server side unless your next logout. Shouldn't happen with normal use. In case you're worried: throw Zend_Cache into the mix. Accessing a Window-related session namespace should then prune outdated ones.
We'll implement a new session storage and a remember me feature. With remember me, it makes sense to keep session values until remember me is expired (or until the user logs out of course). Then, your process states might not get cleaned at all. We must implement framework functionality that does that automatically.
But that is not the point here and we're wasting time on a discussion about a feature that is going to be implemented at some future time.
I don't know why we should send client state back-and-forth and persist it on the server when we have
localStorage. I'm sure sure we go that way for such a feature as we already did.
Speed. This has originally been built for processes with 1000+ nodes each. JavaScript is slow when it has to adjust collapsed states at each refresh, you would note flickering.
We'll implement a new session storage and a remember me feature. With remember me, it makes sense to keep session values until remember me is expired (or until the user logs out of course). Then, your process states might not get cleaned at all. We must implement framework functionality that does that automatically.
Remember-me should IMHO be strictly separated from session storage, they are related but different things. And when it goes to WindowId-related information, they shouldn't be there at all: technically it's a new login, and if logout wasn't forceful in most cases we're dealing with a new window anyway.
But that is not the point here and we're wasting time on a discussion about a feature that is going to be implemented at some future time.
I do not see this being wasted time, sorry for bothering you
Speed. This has originally been built for processes with 1000+ nodes each. JavaScript is slow when it has to adjust collapsed states at each refresh, you would note flickering.
Seems we did a great job here with the 1000+ nodes in mind. It is is pure JS since years.
Remember-me should IMHO be strictly separated from session storage, they are related but different things. And when it goes to WindowId-related information, they shouldn't be there at all: technically it's a new login, and if logout wasn't forceful in most cases we're dealing with a new window anyway.
Sure, Window related information must not be persisted across remember me session renewals but there may be other stuff. So, as I said, our framework must handle that. But, again, that is not the point here.
I do not see this being wasted time, sorry for bothering you
We'll go with localStorage. If it is too slow, we think about something else.
Uses collapsible.js now. A config with 64 root processes each with 63 sub nodes which are then in total 4k+ nodes, requires here 16s to load. All root nodes are collapsed by JS. Server execution time is the most of it. (If I use an even larger config I run into memory exhaustion or a runtime timeout.) So, JS is not the bottleneck here.

Seeing all break down with a ~130k nodes config was fun though. :joy: