From 65fc1019ad1921f2a2e1ad96993892eebf650da2 Mon Sep 17 00:00:00 2001 From: Mattias Reichel Date: Tue, 7 Nov 2023 15:15:44 +0100 Subject: [PATCH] Add method to cancel Inertia processing. Useful in controllers if you want to respond with a http response without the Inertia headers. --- .../plugin/inertia/InertiaInterceptor.groovy | 4 +--- .../grails/plugin/inertia/Inertia.groovy | 9 +++++++++ .../grails/plugin/inertia/InertiaTrait.groovy | 8 ++++++++ .../inertia/InertiaInterceptorSpec.groovy | 20 +++++++++++++++++++ 4 files changed, 38 insertions(+), 3 deletions(-) diff --git a/grails-app/controllers/grails/plugin/inertia/InertiaInterceptor.groovy b/grails-app/controllers/grails/plugin/inertia/InertiaInterceptor.groovy index df7792a..0b3aab1 100644 --- a/grails-app/controllers/grails/plugin/inertia/InertiaInterceptor.groovy +++ b/grails-app/controllers/grails/plugin/inertia/InertiaInterceptor.groovy @@ -23,7 +23,6 @@ import groovy.json.JsonSlurper import groovy.transform.CompileStatic import io.micronaut.http.HttpStatus -import static Inertia.INERTIA_ATTRIBUTE_CANCEL_INERTIA import static Inertia.INERTIA_ATTRIBUTE_MANIFEST import static Inertia.INERTIA_ATTRIBUTE_VERSION import static Inertia.INERTIA_HEADER @@ -64,7 +63,7 @@ class InertiaInterceptor implements GrailsConfigurationAware { boolean after() { - if (inertiaResponseCanceled) return true + if (Inertia.isCanceled) return true setContentType() setHeaders() @@ -117,7 +116,6 @@ class InertiaInterceptor implements GrailsConfigurationAware { boolean getMethodNotAllowedShouldBePrevented() { isInertiaRequest && response.status == HttpStatus.FOUND.code && request.method in ['PUT', 'PATCH', 'DELETE'] } boolean getIsInertiaHtmlView() { modelAndView?.viewName == INERTIA_VIEW_HTML } boolean getIsInertiaRequest() { request.getHeader(INERTIA_HEADER) == 'true' } - boolean isInertiaResponseCanceled() { request.getAttribute(INERTIA_ATTRIBUTE_CANCEL_INERTIA) } boolean getIsAssetsCurrent() { def currentVersion = request.getAttribute(INERTIA_ATTRIBUTE_VERSION) as String def requestedVersion = request.getHeader(INERTIA_HEADER_VERSION) as String diff --git a/src/main/groovy/grails/plugin/inertia/Inertia.groovy b/src/main/groovy/grails/plugin/inertia/Inertia.groovy index 6fb2b6d..6378ca0 100644 --- a/src/main/groovy/grails/plugin/inertia/Inertia.groovy +++ b/src/main/groovy/grails/plugin/inertia/Inertia.groovy @@ -76,6 +76,15 @@ class Inertia { response.status = SC_CONFLICT } + @SuppressWarnings('unused') + static void cancel() { + request.setAttribute INERTIA_ATTRIBUTE_CANCEL_INERTIA, true + } + + static boolean getIsCanceled() { + request.getAttribute INERTIA_ATTRIBUTE_CANCEL_INERTIA + } + private static ModelAndView renderInternal(String component, Map props, Map viewData) { isInertiaRequest ? renderJson(component, props) : diff --git a/src/main/groovy/grails/plugin/inertia/InertiaTrait.groovy b/src/main/groovy/grails/plugin/inertia/InertiaTrait.groovy index 9103814..37c5a4a 100644 --- a/src/main/groovy/grails/plugin/inertia/InertiaTrait.groovy +++ b/src/main/groovy/grails/plugin/inertia/InertiaTrait.groovy @@ -58,4 +58,12 @@ trait InertiaTrait { void setInertiaSharedData(Map sharedData) { Inertia.sharedData = sharedData } + + void cancelInertia() { + Inertia.cancel() + } + + boolean isInertiaCanceled() { + Inertia.isCanceled + } } \ No newline at end of file diff --git a/src/test/groovy/grails/plugin/inertia/InertiaInterceptorSpec.groovy b/src/test/groovy/grails/plugin/inertia/InertiaInterceptorSpec.groovy index fc9a5dd..37bbf57 100644 --- a/src/test/groovy/grails/plugin/inertia/InertiaInterceptorSpec.groovy +++ b/src/test/groovy/grails/plugin/inertia/InertiaInterceptorSpec.groovy @@ -106,6 +106,21 @@ class InertiaInterceptorSpec extends Specification implements InterceptorUnitTes ! response.containsHeader('X-Inertia') ! ('X-Inertia' in response.getHeaders('Vary')) } + + def 'canceling Inertia request with Inertia.cancel() works'() { + given: 'a controller' + def controller = (TestController) mockController(TestController) + + when: 'a request for json is processed' + request.addHeader 'X-Inertia', true + request.addHeader 'X-Inertia-Version', '0' + withInterceptors(controller: 'test', httpMethod: 'GET') { controller.cancelInertiaAction() } + interceptor.after() + + then: 'no inertia response headers are set' + ! response.containsHeader('X-Inertia') + ! ('X-Inertia' in response.getHeaders('Vary')) + } } @Controller @@ -116,6 +131,11 @@ class TestController { renderInertia 'index', [hello: 'world'] } + def cancelInertiaAction() { + Inertia.cancel() + render 'cancelInertiaAction' + } + def testing() { renderInertia 'testing' }