From e3e4666dd6f45e979ebb95a0947b1048718dfc3a Mon Sep 17 00:00:00 2001 From: Jeff Hwang Date: Mon, 9 Jun 2025 17:36:22 -0400 Subject: [PATCH 1/2] add turbo frame to events and partition --- .../cash/backfila/ui/components/AutoReload.kt | 15 ++--- .../backfila/ui/pages/BackfillShowAction.kt | 58 ++++++++++--------- .../backfila/ui/pages/ServiceShowAction.kt | 2 +- .../web/static/js/auto_reload_controller.js | 44 +++++--------- 4 files changed, 54 insertions(+), 65 deletions(-) diff --git a/service/src/main/kotlin/app/cash/backfila/ui/components/AutoReload.kt b/service/src/main/kotlin/app/cash/backfila/ui/components/AutoReload.kt index af6dbc3e7..048e5825f 100644 --- a/service/src/main/kotlin/app/cash/backfila/ui/components/AutoReload.kt +++ b/service/src/main/kotlin/app/cash/backfila/ui/components/AutoReload.kt @@ -2,16 +2,17 @@ package app.cash.backfila.ui.components import kotlinx.html.TagConsumer import kotlinx.html.div +import misk.turbo.turbo_frame -// TODO -// Currently this reloads the whole page every 10s -// We want to ideally only update within a turbo frame so the rest of the UI is stable -// (ie. update form for backfill show page) -fun TagConsumer<*>.AutoReload(block: TagConsumer<*>.() -> Unit) { +fun TagConsumer<*>.AutoReload(frameId: String = "auto-reload-frame", block: TagConsumer<*>.() -> Unit) { div { attributes["data-controller"] = "auto-reload" - attributes["data-auto-reload-target"] = "frame" - block() + turbo_frame(frameId) { + attributes["data-auto-reload-target"] = "frame" + attributes["data-turbo-action"] = "replace" + + block() + } } } diff --git a/service/src/main/kotlin/app/cash/backfila/ui/pages/BackfillShowAction.kt b/service/src/main/kotlin/app/cash/backfila/ui/pages/BackfillShowAction.kt index 4a156f016..f3b06e0b3 100644 --- a/service/src/main/kotlin/app/cash/backfila/ui/pages/BackfillShowAction.kt +++ b/service/src/main/kotlin/app/cash/backfila/ui/pages/BackfillShowAction.kt @@ -86,45 +86,47 @@ class BackfillShowAction @Inject constructor( Link("Backfill #$id", path(id)), ) .buildHtmlResponseBody { - AutoReload { - PageTitle("${backfill.service_name} Backfill Run", "#$id", backfill.name) { - a { - href = BackfillCreateAction.path( - service = backfill.service_name, - variantOrBackfillNameOrId = if (backfill.variant != "default") backfill.variant else id.toString(), - backfillNameOrIdOrBlank = if (backfill.variant != "default") id.toString() else "", - ) - - button(classes = "rounded-full bg-indigo-600 px-3 py-1.5 text-sm font-semibold text-white shadow-sm hover:bg-indigo-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600") { - type = ButtonType.button - +"""Clone""" - } + // Configuration section - outside AutoReload + PageTitle("${backfill.service_name} Backfill Run", "#$id", backfill.name) { + a { + href = BackfillCreateAction.path( + service = backfill.service_name, + variantOrBackfillNameOrId = if (backfill.variant != "default") backfill.variant else id.toString(), + backfillNameOrIdOrBlank = if (backfill.variant != "default") id.toString() else "", + ) + + button(classes = "rounded-full bg-indigo-600 px-3 py-1.5 text-sm font-semibold text-white shadow-sm hover:bg-indigo-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600") { + type = ButtonType.button + +"""Clone""" } } + } - Card { - div("mx-auto grid max-w-2xl grid-cols-1 grid-rows-1 items-start gap-x-24 gap-y-8 lg:mx-0 lg:max-w-none lg:grid-cols-2") { - // """ - div("") { - h2("text-base font-semibold leading-6 text-gray-900") { +"""Configuration""" } - dl("divide-y divide-gray-100") { - leftColumnConfigurationRows.map { - ConfigurationRows(id, it) - } + Card { + div("mx-auto grid max-w-2xl grid-cols-1 grid-rows-1 items-start gap-x-24 gap-y-8 lg:mx-0 lg:max-w-none lg:grid-cols-2") { + // """ + div("") { + h2("text-base font-semibold leading-6 text-gray-900") { +"""Configuration""" } + dl("divide-y divide-gray-100") { + leftColumnConfigurationRows.map { + ConfigurationRows(id, it) } } + } - // """ - div("divide-x divide-gray-100") { - dl("divide-y divide-gray-100") { - rightColumnConfigurationRows.map { - ConfigurationRows(id, it) - } + // """ + div("divide-x divide-gray-100") { + dl("divide-y divide-gray-100") { + rightColumnConfigurationRows.map { + ConfigurationRows(id, it) } } } } + } + // Auto-reload section for Partitions and Events + AutoReload(frameId = "backfill-$id-status") { Card { // Partitions h2("text-base font-semibold leading-6 text-gray-900") { +"""Partitions""" } diff --git a/service/src/main/kotlin/app/cash/backfila/ui/pages/ServiceShowAction.kt b/service/src/main/kotlin/app/cash/backfila/ui/pages/ServiceShowAction.kt index cc0f74a9a..fd4c3edf9 100644 --- a/service/src/main/kotlin/app/cash/backfila/ui/pages/ServiceShowAction.kt +++ b/service/src/main/kotlin/app/cash/backfila/ui/pages/ServiceShowAction.kt @@ -72,7 +72,7 @@ class ServiceShowAction @Inject constructor( Link(label, path), ) .buildHtmlResponseBody { - AutoReload { + AutoReload(frameId = "backfill-$service-status") { PageTitle("Service", label) { a { href = BackfillCreateServiceIndexAction.path(service, variantOrBlank) diff --git a/service/src/main/resources/web/static/js/auto_reload_controller.js b/service/src/main/resources/web/static/js/auto_reload_controller.js index d252e05ae..36bd6f59d 100644 --- a/service/src/main/resources/web/static/js/auto_reload_controller.js +++ b/service/src/main/resources/web/static/js/auto_reload_controller.js @@ -1,41 +1,27 @@ import { Application, Controller } from "../cache/stimulus/3.1.0/stimulus.min.js"; window.Stimulus = Application.start(); -// Hard reload Stimulus.register("auto-reload", class extends Controller { + static targets = ["frame"] + connect() { console.log("Auto-reload connected..."); - this.reloadInterval = setInterval(() => { - console.log("Reloading page..."); - window.location.reload(); - }, 10000); // 10000 milliseconds = 10 seconds + this.startReloading() } disconnect() { console.log("Clearing auto-reload interval..."); - clearInterval(this.reloadInterval); + if (this.interval) clearInterval(this.interval) } -}); - -// TODO fix soft-reload -//Stimulus.register("auto-reload", class extends Controller { -// static targets = ["frame"]; -// -// connect() { -// console.log("Auto-reload connected..."); -// this.reloadInterval = setInterval(() => { -// console.log("Reloading Turbo Frame..."); -// this.reloadFrame(); -// }, 5000); // 5000 milliseconds = 5 seconds -// } -// -// disconnect() { -// console.log("Clearing auto-reload interval..."); -// clearInterval(this.reloadInterval); -// } -// -// reloadFrame() { -// this.frameTarget.src = this.frameTarget.src; -// } -//}); \ No newline at end of file + startReloading() { + this.interval = setInterval(() => { + console.log("auto-reload triggered..."); + const pathname = window.location.pathname + const url = new URL(pathname, window.location.origin) + url.searchParams.set('frame', 'true') + + Turbo.visit(url.toString(), { frame: this.frameTarget.id }) + }, 10000) + } +}); \ No newline at end of file From 227e8f6a0fbf1449b4d2c11795659db4237c3721 Mon Sep 17 00:00:00 2001 From: Jeff Hwang Date: Tue, 10 Jun 2025 12:53:55 -0400 Subject: [PATCH 2/2] remove logging --- .../src/main/resources/web/static/js/auto_reload_controller.js | 1 - 1 file changed, 1 deletion(-) diff --git a/service/src/main/resources/web/static/js/auto_reload_controller.js b/service/src/main/resources/web/static/js/auto_reload_controller.js index 36bd6f59d..9743ee933 100644 --- a/service/src/main/resources/web/static/js/auto_reload_controller.js +++ b/service/src/main/resources/web/static/js/auto_reload_controller.js @@ -16,7 +16,6 @@ Stimulus.register("auto-reload", class extends Controller { startReloading() { this.interval = setInterval(() => { - console.log("auto-reload triggered..."); const pathname = window.location.pathname const url = new URL(pathname, window.location.origin) url.searchParams.set('frame', 'true')