Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

use multi routes in single page #171

Open
alerem18 opened this issue Feb 5, 2023 · 11 comments
Open

use multi routes in single page #171

alerem18 opened this issue Feb 5, 2023 · 11 comments
Assignees

Comments

@alerem18
Copy link

alerem18 commented Feb 5, 2023

i wonder is it possible to have a SPA(Single Page Application) with stipple so we can render different models in one page without refreshing the page and create multiple pages
a feature like (Link to="some path" in REACT)

also i would appreciate anyone who can explain me what are channels briefly

@AbhimanyuAryan
Copy link
Member

@alerem18 for now you'll have to use something complicated and solve this problem with genie instead of declaring frontend routing with something like stippleui tabs. I am thinking of adding it

https://github.com/GenieFramework/MultiRoute

@hhaensel
Copy link
Member

hhaensel commented Feb 7, 2023

I think it is not very difficult to support multiple models on a single page.
We would need to have a window.CHANNEL = {modeltype1: channel1; modeltype2: channel2} dict indstead of the current window.CHANNEL = "my channel string".
I could imagine that we could use that to implement SPAs with different models.
Maybe we could even do loading on demand ...

@AbhimanyuAryan
Copy link
Member

yes I interpreted it wrong. Go with helmut's answer

@alerem18
Copy link
Author

alerem18 commented Feb 8, 2023

@alerem18 for now you'll have to use something complicated and solve this problem with genie instead of declaring frontend routing with something like stippleui tabs. I am thinking of adding it

https://github.com/GenieFramework/MultiRoute

i've tried that already, it's not SPA, it's just multi-page multi-route problem, the goal is to use something like react or vue do, render different models on the same page

@essenciary
Copy link
Member

My 2 cents:

  • multiple (Vue) models on the same page would be useful. However, that was pretty complicated in Vue 2 and got much simpler in Vue 3. As we need to migrate to Vue 3 anyway, I would add multi-model support after Vue 3 support.
  • SPA routing should use a proper router (like vue-router) vs rolling out a custom solution. So we could also look into officially supporting routing.
  • traditional SPAs are a dying trend, with users moving to JS frameworks with SSR and dynamic islands (Next, Nuxt, Remix, etc). We might want to consider integrating and bundling a front-end framework instead of "just" routing.

@hhaensel
Copy link
Member

hhaensel commented Nov 9, 2024

Well, it was much more difficult, as each of the models needs its own websocket. So the whole architecture in Genie's channels.js needed to be changed.
Not sure wether I now have chosen the most elegant way, we can discuss this here.

But at least I have an MWE that works on the branches hh-multimodel for Genie and Stipple

using Stipple, Stipple.ReactiveTools
using StippleUI

@app MyApp1 begin
    @in i = 0
    
    @onchange i begin
        @notify("i has changed $i")
    end
end handlers1

@app MyApp2 begin
    @in i = 0

    @onchange i begin
        @notify("i has changed $i")
    end
end handlers2

ui() = row(card([
    cardsection(h3("Alert", @if(:ws_disconnected)))
    cardsection(numberfield("i", :i))
    cardsection(textfield("i text", :i, @for(n in 1:1)))
]))

route("/") do
    global model1 = init(MyApp1, channel = Stipple.channelfactory()) |> handlers1
    global model2 = init(MyApp2, channel = Stipple.channelfactory()) |> handlers2
    page([model1, model2], [ui, ui]) |> html
end

up(open_browser = true)
image image

@hhaensel
Copy link
Member

hhaensel commented Nov 9, 2024

Still room for improvement:

  • suppress errors (e.g. eliminate deps duplicates
  • support page template
  • find a variant that doesn't reevaluate channels.js for each model but rather only executes a single function with the channel as argument, instead of relying on window.CHANNEL and execution order
  • support more than one model per model type (which currently fails due to $vue_app_name being non-unique)

@hhaensel
Copy link
Member

hhaensel commented Nov 9, 2024

But hey, it's a start
UPDATE: part of above is already solved

@hhaensel
Copy link
Member

Everything solved:

route("/") do
    global models = [init(MyApp1, channel = Stipple.channelfactory()) |> handlers1 for _ in 1:5]    
    page(models, fill(ui, length(models)), pagetemplate = (x...) -> row([x...])) |> html
end

leads to
image

@hhaensel
Copy link
Member

Each model has its own websocket!

@hhaensel
Copy link
Member

hhaensel commented Nov 11, 2024

@essenciary, @PGimenez
After having solved keepalive for all models the modifications are ready to be merged.
Moreover, keepalive is adapted to restart with modified startDelay after user input, which previously extended the keepalive delay.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants