diff --git a/app/controllers/async_renderer_controller.rb b/app/controllers/async_renderer_controller.rb new file mode 100644 index 00000000..49caa567 --- /dev/null +++ b/app/controllers/async_renderer_controller.rb @@ -0,0 +1,11 @@ +class AsyncRendererController < ApplicationController + def async_render + renderer = "Async::#{params[:view_model]}ViewModel".constantize + view_model = renderer.new(current_user, params) + html = view_model.async_render + rescue => e + html = view_model.render_error + ensure + render inline: html.html_safe + end +end diff --git a/app/javascript/controllers/async_renderer_controller.js b/app/javascript/controllers/async_renderer_controller.js new file mode 100644 index 00000000..7deedc9d --- /dev/null +++ b/app/javascript/controllers/async_renderer_controller.js @@ -0,0 +1,26 @@ +import { Controller } from "@hotwired/stimulus" + +export default class extends Controller { + static targets = ["frame"] + static values = { + viewModel: String, + params: String + } + + connect() { + this.render(); + } + + async render() { + const params = JSON.parse(this.paramsValue) + const queryString = new URLSearchParams(params).toString(); + const response = await fetch(`/async_render?view_model=${this.viewModelValue}&${queryString}`); + + if (response.ok) { + const html = await response.text(); + this.frameTarget.innerHTML = html; + } else { + this.frameTarget.innerHTML = `