Skip to content

Commit

Permalink
support multi-model pages
Browse files Browse the repository at this point in the history
  • Loading branch information
hhaensel committed Nov 9, 2024
1 parent 599628c commit 98727ab
Show file tree
Hide file tree
Showing 5 changed files with 28 additions and 16 deletions.
4 changes: 2 additions & 2 deletions assets/js/watchers.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ const watcherMixin = {
},

push: function (field) {
Genie.WebChannels.sendMessageTo(CHANNEL, 'watchers', {'payload': {
Genie.WebChannels.sendMessageTo(this.channel_, 'watchers', {'payload': {
'field': field,
'newval': this[field],
'oldval': null,
Expand Down Expand Up @@ -110,7 +110,7 @@ const eventMixin = {
if (event_data === undefined) { event_data = {} }
console.debug('event: ' + JSON.stringify(event_data) + ":" + event_handler)
if (mode=='addclient') { event_data._addclient = true}
Genie.WebChannels.sendMessageTo(window.CHANNEL, 'events', {
Genie.WebChannels.sendMessageTo(this.channel_, 'events', {
'event': {
'name': event_handler,
'event': event_data
Expand Down
11 changes: 7 additions & 4 deletions src/Elements.jl
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,10 @@ function vue_integration(::Type{M};
app.config.globalProperties[key] = value
});
window.$vue_app_name = window.GENIEMODEL = app.mount(rootSelector);
window.channelIndex = window.channelIndex || 0;
$vue_app_name.WebChannel = Genie.AllWebChannels[channelIndex];
$vue_app_name.channel_ = $vue_app_name.WebChannel.channel;
channelIndex++;
} // end of initStipple
"
Expand Down Expand Up @@ -209,8 +213,7 @@ function vue_integration(::Type{M};
}
}
function app_ready() {
$vue_app_name.channel_ = window.CHANNEL;
function app_$(vue_app_name)_ready() {
$vue_app_name.isready = true;
Genie.Revivers.addReviver(window.$(vue_app_name).revive_jsfunction);
$(transport == Genie.WebChannels &&
Expand All @@ -236,8 +239,8 @@ function vue_integration(::Type{M};
initStipple('#$vue_app_name');
initWatchers();
Genie.WebChannels.subscriptionHandlers.push(function(event) {
app_ready();
$vue_app_name.WebChannel.subscriptionHandlers.push(function(event) {
app_$(vue_app_name)_ready();
});
}
"""
Expand Down
18 changes: 12 additions & 6 deletions src/Layout.jl
Original file line number Diff line number Diff line change
Expand Up @@ -41,18 +41,19 @@ julia> layout([
"<link href=\"https://fonts.googleapis.com/css?family=Material+Icons\" rel=\"stylesheet\" /><link href=\"https://fonts.googleapis.com/css2?family=Lato:ital,wght@0,400;0,700;0,900;1,400&display=swap\" rel=\"stylesheet\" /><link href=\"/css/stipple/stipplecore.css\" rel=\"stylesheet\" /><link href=\"/css/stipple/quasar.min.css\" rel=\"stylesheet\" /><span v-text='greeting'>Hello</span><script src=\"/js/channels.js?v=1.17.1\"></script><script src=\"/js/underscore-min.js\"></script><script src=\"/js/vue.global.prod.js\"></script><script src=\"/js/quasar.umd.prod.js\"></script>\n<script src=\"/js/apexcharts.min.js\"></script><script src=\"/js/vue-apexcharts.min.js\"></script><script src=\"/js/stipplecore.js\" defer></script><script src=\"/js/vue_filters.js\" defer></script>"
```
"""
function layout(output::Union{S,Vector}, m::M;
function layout(output::Union{S,Vector}, m::Union{M, Vector{M}};
partial::Bool = false, title::String = "", class::String = "", style::String = "", head_content::Union{AbstractString, Vector{<:AbstractString}} = "",
channel::String = Stipple.channel_js_name,
core_theme::Bool = true)::ParsedHTMLString where {M<:ReactiveModel, S<:AbstractString}

isa(output, Vector) && (output = join(output, '\n'))
m isa Vector || (m = [m])

content = [
output
theme(; core_theme)
Stipple.deps(m)
]
Stipple.deps.(m)...
] |> union

partial && return content

Expand Down Expand Up @@ -84,17 +85,22 @@ julia> page(:elemid, [
"<!DOCTYPE html>\n<html><head><title></title><meta name=\"viewport\" content=\"width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no, minimal-ui\" /></head><body class style><link href=\"https://fonts.googleapis.com/css?family=Material+Icons\" rel=\"stylesheet\" /><link href=\"https://fonts.googleapis.com/css2?family=Lato:ital,wght@0,400;0,700;0,900;1,400&display=swap\" rel=\"stylesheet\" /><link href=\"/css/stipple/stipplecore.css\" rel=\"stylesheet\" /><link href=\"/css/stipple/quasar.min.css\" rel=\"stylesheet\" /><div id=elemid><span v-text='greeting'>Hello</span></div><script src=\"/js/channels.js?v=1.17.1\"></script><script src=\"/js/underscore-min.js\"></script><script src=\"/js/vue.global.prod.js\"></script><script src=\"/js/quasar.umd.prod.js\"></script>\n<script src=\"/js/apexcharts.min.js\"></script><script src=\"/js/vue-apexcharts.min.js\"></script><script src=\"/js/stipplecore.js\" defer></script><script src=\"/js/vue_filters.js\" defer></script></body></html>"
```
"""
function page(model::M, args...;
function page(model::Union{M, Vector{M}}, args...;
partial::Bool = false, title::String = "", class::String = "container", style::String = "",
channel::String = Genie.config.webchannels_default_route, head_content::Union{AbstractString, Vector{<:AbstractString}} = "",
prepend::Union{S,Vector} = "", append::Union{T,Vector} = [],
core_theme::Bool = true,
kwargs...)::ParsedHTMLString where {M<:Stipple.ReactiveModel, S<:AbstractString,T<:AbstractString}

model isa Vector || (model = [model])
uis = if !isempty(args)
args[1] isa Vector ? args[1] : [args[1]]
else
""
end
layout(
[
join(prepend)
Genie.Renderer.Html.div(id = vm(M), args...; class = class, kwargs...)
[Genie.Renderer.Html.div(id = vm(m), ui, args[2:end]...; class = class, kwargs...) for (m, ui) in zip(model, uis)]...
join(append)
], model;
partial = partial, title = title, style = style, head_content = head_content, channel = channel,
Expand Down
9 changes: 6 additions & 3 deletions src/Stipple.jl
Original file line number Diff line number Diff line change
Expand Up @@ -342,10 +342,10 @@ changed on the frontend, it is pushed over to the backend using `channel`, at a
function watch(vue_app_name::String, fieldname::Symbol, channel::String, debounce::Int, model::M; jsfunction::String = "")::String where {M<:ReactiveModel}
js_channel = isempty(channel) ?
"window.Genie.Settings.webchannels_default_route" :
(channel == Stipple.channel_js_name ? Stipple.channel_js_name : "'$channel'")
"$vue_app_name.channel_"

isempty(jsfunction) &&
(jsfunction = "Genie.WebChannels.sendMessageTo($js_channel, 'watchers', {'payload': {'field':'$fieldname', 'newval': newVal, 'oldval': oldVal, 'sesstoken': document.querySelector(\"meta[name='sesstoken']\")?.getAttribute('content')}});")
(jsfunction = "$vue_app_name.WebChannel.sendMessageTo($js_channel, 'watchers', {'payload': {'field':'$fieldname', 'newval': newVal, 'oldval': oldVal, 'sesstoken': document.querySelector(\"meta[name='sesstoken']\")?.getAttribute('content')}});")

output = IOBuffer()
if fieldname == :isready
Expand Down Expand Up @@ -847,7 +847,10 @@ end


function channelscript(channel::String) :: String
Genie.Renderer.Html.script(["window.CHANNEL = '$(channel)';"])
Genie.Renderer.Html.script(["""
window.CHANNEL = '$(channel)';
if (window.Genie) Genie.init_webchannel('$(channel)');
"""])
end


Expand Down
2 changes: 1 addition & 1 deletion src/stipple/rendering.jl
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ function Stipple.render(app::M)::Dict{Symbol,Any} where {M<:ReactiveModel}
for field in fieldnames(typeof(app))
f = getfield(app, field)

occursin(SETTINGS.private_pattern, String(field)) && continue
field != CHANNELFIELDNAME && occursin(SETTINGS.private_pattern, String(field)) && continue
f isa Reactive && f.r_mode == PRIVATE && continue

result[field] = Stipple.jsrender(f, field)
Expand Down

0 comments on commit 98727ab

Please sign in to comment.