Skip to content

Commit

Permalink
🚑 Reloading page templates works, overall
Browse files Browse the repository at this point in the history
  • Loading branch information
wesen committed Feb 26, 2025
1 parent 8194063 commit 0cdf77f
Show file tree
Hide file tree
Showing 8 changed files with 401 additions and 314 deletions.
57 changes: 40 additions & 17 deletions cmd/ui-server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ func (s *Server) loadPage(path string) error {
s.mu.Unlock()

// Publish page reload event
event := events.NewPageReloadEvent(relPath)
event := events.NewPageReloadEvent(relPath, def)
if err := s.events.Publish(relPath, event); err != nil {
log.Error().Err(err).Str("path", relPath).Msg("Failed to publish page reload event")
}
Expand Down Expand Up @@ -262,12 +262,6 @@ func (s *Server) handleFileRemove(path string) error {
delete(s.routes, urlPath)
s.mu.Unlock()

// Publish page reload event
event := events.NewPageReloadEvent(relPath)
if err := s.events.Publish(relPath, event); err != nil {
log.Error().Err(err).Str("path", relPath).Msg("Failed to publish page reload event")
}

log.Info().Str("path", relPath).Str("url", urlPath).Msg("Removed page")
return nil
}
Expand Down Expand Up @@ -377,23 +371,52 @@ func (s *Server) registerComponentRenderers() {
})

// Register page-template renderer
s.sseHandler.RegisterRenderer("page-template", func(pageID string, _ interface{}) (string, error) {
log.Debug().Str("pageID", pageID).Msg("Rendering full page template")
s.sseHandler.RegisterRenderer("page-content-template", func(pageID string, data interface{}) (string, error) {
log.Debug().Str("pageID", pageID).Msg("Rendering page content template")

// Get the page definition
s.mu.RLock()
def, ok := s.pages[pageID]
s.mu.RUnlock()
var def UIDefinition

// First check if we have data from the event
if data != nil {
// Try to use the data from the event
if eventData, ok := data.(map[string]interface{}); ok {
if pageData, ok := eventData["data"]; ok {
// Try to convert the data to UIDefinition
if pageDefMap, ok := pageData.(map[string]interface{}); ok {
if components, ok := pageDefMap["components"].([]interface{}); ok {
// Convert components to the expected format
compList := make([]map[string]interface{}, 0, len(components))
for _, comp := range components {
if compMap, ok := comp.(map[string]interface{}); ok {
compList = append(compList, compMap)
}
}
def = UIDefinition{Components: compList}
}
}
}
}
}

if !ok {
return "", fmt.Errorf("page not found: %s", pageID)
// If we couldn't get the definition from the event data, use the stored one
if len(def.Components) == 0 {
s.mu.RLock()
storedDef, ok := s.pages[pageID]
s.mu.RUnlock()

if !ok {
return "", fmt.Errorf("page not found: %s", pageID)
}

def = storedDef
}

// Render the page template
// Render just the page content template, not the full page with base
var buf bytes.Buffer
err := pageTemplate(pageID, def).Render(context.Background(), &buf)
err := pageContentTemplate(pageID, def).Render(context.Background(), &buf)
if err != nil {
return "", fmt.Errorf("failed to render page template: %w", err)
return "", fmt.Errorf("failed to render page content template: %w", err)
}

return buf.String(), nil
Expand Down
56 changes: 30 additions & 26 deletions cmd/ui-server/templates.templ
Original file line number Diff line number Diff line change
Expand Up @@ -179,38 +179,42 @@ templ indexTemplate(pages map[string]UIDefinition) {

templ pageTemplate(name string, def UIDefinition) {
@base("UI Server - " + name) {
<div
class="row"
hx-ext="sse"
sse-connect={ "/sse?page=" + name }
sse-swap="component-update"
>
<div class="col-md-6">
<div class="card mb-4">
<div class="card-header">
<h5 class="card-title mb-0">Rendered UI</h5>
</div>
<div class="card-body" sse-swap="component-update">
for _, component := range def.Components {
for typ, props := range component {
@renderComponent(typ, props.(map[string]interface{}))
}
@pageContentTemplate(name, def)
}
}

templ pageContentTemplate(name string, def UIDefinition) {
<div
class="row"
hx-ext="sse"
sse-connect={ "/sse?page=" + name }
sse-swap="component-update"
>
<div class="col-md-6">
<div class="card mb-4">
<div class="card-header">
<h5 class="card-title mb-0">Rendered UI</h5>
</div>
<div class="card-body" sse-swap="component-update">
for _, component := range def.Components {
for typ, props := range component {
@renderComponent(typ, props.(map[string]interface{}))
}
</div>
}
</div>
</div>
<div class="col-md-6">
<div class="card">
<div class="card-header">
<h5 class="card-title mb-0">YAML Source</h5>
</div>
<div class="card-body source-yaml" sse-swap="yaml-update">
<pre><code class="language-yaml">{ yamlString(def) }</code></pre>
</div>
</div>
<div class="col-md-6">
<div class="card">
<div class="card-header">
<h5 class="card-title mb-0">YAML Source</h5>
</div>
<div class="card-body source-yaml" sse-swap="yaml-update">
<pre><code class="language-yaml">{ yamlString(def) }</code></pre>
</div>
</div>
</div>
}
</div>
}

templ renderComponent(typ string, props map[string]interface{}) {
Expand Down
Loading

0 comments on commit 0cdf77f

Please sign in to comment.