# frozen_string_literal: true module Shimmer module RemoteNavigation extend ActiveSupport::Concern included do def ui @ui ||= RemoteNavigator.new(self) end def default_render return render_modal if shimmer_request? return super unless ui.updates? render turbo_stream: ui.queued_updates.join("\n") end helper_method :modal_path def modal_path(url, id: nil, size: nil, close: true) "javascript:ui.modal.open(#{{url: url, id: id, size: size, close: close}.to_json})" end helper_method :close_modal_path def close_modal_path(id: nil) "javascript:ui.modal.close(#{{id: id}.to_json})" end helper_method :popover_path def popover_path(url, id: nil, selector: nil, placement: nil) "javascript:ui.popover.open(#{{url: url, id: id, selector: selector, placement: placement}.compact.to_json})" end def shimmer_request? request.headers["X-Shimmer"].present? end def render_modal enforce_modal render layout: false end def enforce_modal raise "trying to render a modal from a regular request" unless shimmer_request? end end end class RemoteNavigator delegate :polymorphic_path, to: :@controller def initialize(controller) @controller = controller end def queued_updates @queued_updates ||= [] end def updates? queued_updates.any? end def run_javascript(script) queued_updates.push turbo_stream.append "shimmer", "