[Seaside] Multiple tabs with their own root components

Esteban Maringolo emaringolo at gmail.com
Tue Aug 11 16:00:19 UTC 2020


Hi Bob,

On Tue, Aug 11, 2020 at 12:09 PM Bob Nemec <bobn at rogers.com> wrote:
>
> On the point...
>
>     These days it is very common that you can open a link in a new tab to
>     view something, then close it, duplicate it or even the browser might
>     restart on that page.

> ...we have that issue with our in-house ERP system (about 650 users).
> Having users open an internal application link in a new tab is just wrong in Seaside.

That will depend on how you architecture the application and the state
involved, of course you cannot start a workflow in one page, open a
link to another tab (or even duplicate the same tab) and have
different "timelines" on each tab.

Maybe in the past that was possible with the #isolate: decorator, but
that can't be done now.
For another app where I have similar restrictions as yours, I drive
most, if not all, of the interactions via AJAX, so there are no
"internal links", but that doesn't stop the user from duplicating the
tab or clicking the Back/Forward button with [Ctrl] pressed to
duplicate that.


> To prevent that we check the history.length on the render for logged-in sessions.
> We also have options to open the application for saved links that open a domain object.
> That also had to to be checked for. To distinguish between browser tabs I use sessionStorage.
>
> aSession validNewSession ifTrue: [
>     html script: 'sessionStorage.setItem("validSession",1)'
>     ...]
>
> ...if the session is not a special case, and for the next render, I use...

What would be a "special case"?

> html script: ((JSStream on: '(history.length > 1) || (sessionStorage.getItem("validSession") == 1) ')

Have you tried using the "duplicate tab" feature? Because that nasty
thing clones the sessionStorage.

> Users are able to open new tabs with logged in sessions.
> We provide that with a 'new session' anchor...

That might be a little overkill, unless the session is lightweight.
So far I've been building Seaside apps where there is a 1:1 relation
between the Seaside session
and some "app session" where all info about the user, the database
connection, etc. is managed.

In Gemstone I guess you save the DB connection part (which can take a
huge toll if you have that many hundreds of concurrent users).

> html popupAnchor
> url: (self session requestContext request url printString, '&newSession');
> with: [...]
>
> ...our WAApplication subclass handleFiltered: checks for newSession and sets up a new logged in session.
>
> handleNewSession: aRequestContext
>
> | newSession oldSession companyOop |
>
> oldSession := self sessionForRequest: aRequestContext.
> oldSession isNil ifTrue: [
> ^super handleFiltered: aRequestContext].
>         ...copy stuff from old session to new session...
>         ^self handle: aRequestContext registering: newSession.

This could certainly become some generic WARequestFilter, but what's
missing to make it of general use is being able to detect it without
using a &newSession parameter.

Regards!


Esteban A. Maringolo


More information about the seaside mailing list