diff --git a/app/javascript/controllers/turbo_controller.ts b/app/javascript/controllers/turbo_controller.ts index bfd1b0027..1c55528b2 100644 --- a/app/javascript/controllers/turbo_controller.ts +++ b/app/javascript/controllers/turbo_controller.ts @@ -9,6 +9,10 @@ type StreamRenderEvent = CustomEvent<{ render(streamElement: StreamElement): void; }>; +type FrameRenderEvent = CustomEvent<{ + render(currentElement: Element, newElement: Element): void; +}>; + export class TurboController extends ApplicationController { static targets = ['spinner']; @@ -29,7 +33,7 @@ export class TurboController extends ApplicationController { connect() { this.#actions = new Actions({ - element: document.documentElement, + element: document.body, schema: { forceAttribute: 'data-turbo-force', hiddenClassName: 'hidden' }, debug: false }); @@ -46,14 +50,22 @@ export class TurboController extends ApplicationController { // prevent scroll on turbo form submits this.onGlobal('turbo:render', () => this.preventScrollIfNeeded()); - // reset state preserved for actions between pages - this.onGlobal('turbo:load', () => this.actions.reset()); - // see: https://turbo.hotwired.dev/handbook/streams#custom-actions this.onGlobal('turbo:before-stream-render', (event: StreamRenderEvent) => { event.detail.render = (streamElement: StreamElement) => this.actions.applyActions([parseTurboStream(streamElement)]); }); + + // see: https://turbo.hotwired.dev/handbook/frames#custom-rendering + this.onGlobal('turbo:before-frame-render', (event: FrameRenderEvent) => { + event.detail.render = (currentElement, newElement) => { + // There is a bug in morphdom when it comes to mutate a custom element. It will miserably + // crash. We mutate its content instead. + const fragment = document.createDocumentFragment(); + fragment.append(...newElement.childNodes); + this.actions.update({ targets: [currentElement], fragment }); + }; + }); } private startSpinner() { diff --git a/app/views/administrateurs/procedures/administrateurs.html.haml b/app/views/administrateurs/procedures/administrateurs.html.haml index c3051c65a..de7daa525 100644 --- a/app/views/administrateurs/procedures/administrateurs.html.haml +++ b/app/views/administrateurs/procedures/administrateurs.html.haml @@ -2,13 +2,13 @@ .main-filter-header.fr-my-3w = form_with(url: administrateurs_admin_procedures_path, method: :get, data: { turbo_frame: 'procedures' }, html: { role: 'search' }) do |f| - @filter.zone_ids&.each do |zone_id| - = hidden_field_tag 'zone_ids[]', zone_id + = hidden_field_tag 'zone_ids[]', zone_id, id: "zone_#{zone_id}" - @filter.statuses&.each do |status| - = hidden_field_tag 'statuses[]', status + = hidden_field_tag 'statuses[]', status, id: "status_#{status}" = hidden_field_tag 'from_publication_date', @filter.from_publication_date if @filter.from_publication_date.present? = f.label 'email', 'Recercher des administrateurs par email', class: 'fr-label' - = f.search_field 'email', size: 40, class: 'fr-input' + = f.search_field 'email', size: 40, class: 'fr-input', data: { turbo_force: true } .actions= link_to 'Voir la liste des démarches', all_admin_procedures_path(@filter.params), class: 'fr-btn fr-btn--secondary' .fr-table.fr-table--bordered %table#all-admins diff --git a/app/views/administrateurs/procedures/all.html.haml b/app/views/administrateurs/procedures/all.html.haml index b8049b05e..5552cf704 100644 --- a/app/views/administrateurs/procedures/all.html.haml +++ b/app/views/administrateurs/procedures/all.html.haml @@ -2,13 +2,13 @@ .main-filter-header.fr-my-3w = form_with(url: all_admin_procedures_path, method: :get, data: { turbo_frame: 'procedures' }, html: { role: 'search', class: 'search' }) do |f| - @filter.zone_ids&.each do |zone_id| - = hidden_field_tag 'zone_ids[]', zone_id + = hidden_field_tag 'zone_ids[]', zone_id, id: "zone_#{zone_id}" - @filter.statuses&.each do |status| - = hidden_field_tag 'statuses[]', status + = hidden_field_tag 'statuses[]', status, id: "status_#{status}" = hidden_field_tag 'from_publication_date', @filter.from_publication_date if @filter.from_publication_date.present? = f.label :libelle, 'Rechercher des démarches par libellé', class: 'fr-label' - = f.search_field 'libelle', size: 30, class: 'fr-input' + = f.search_field 'libelle', size: 30, class: 'fr-input', data: { turbo_force: true } .actions .link.fr-mx-1w= link_to 'Voir les administrateurs', administrateurs_admin_procedures_path(@filter.params), class: 'fr-btn fr-btn--secondary' .link.fr-mx-1w{ "data-turbo": "false" }= link_to 'Exporter les résultats', all_admin_procedures_path(@filter.params.merge(format: :xlsx)), class: 'fr-btn fr-btn--secondary' diff --git a/app/views/layouts/all.html.haml b/app/views/layouts/all.html.haml index 7a752fa19..1bc899b74 100644 --- a/app/views/layouts/all.html.haml +++ b/app/views/layouts/all.html.haml @@ -10,7 +10,7 @@ %p Ce tableau de bord permet de consulter les informations sur les démarches simplifiées pour toutes les zones. Filtrez par zone et statut. Consultez la liste des démarches et cliquez sur une démarche pour voir la zone et quels sont les administrateurs. .fr-container--fluid{ data: { turbo: 'true' } } - .fr-grid-row.fr-grid-row--gutters + %turbo-frame#procedures.fr-grid-row.fr-grid-row--gutters{ 'data-turbo-action': 'advance' } .fr-col-3 = form_with(url: all_admin_procedures_path, method: :get, data: { controller: 'autosubmit', turbo_frame: 'procedures' }) do |f| @@ -20,7 +20,7 @@ %span.fr-icon-filter-fill.fr-icon--sm.fr-mr-1w{ 'aria-hidden': 'true' } Filtrer .reinit - = link_to all_admin_procedures_path(zone_ids: current_administrateur.zones) do + = link_to all_admin_procedures_path(zone_ids: current_administrateur.zones), { data: { turbo: 'false' } } do %span.fr-icon-arrow-go-back-line Réinitialiser %ul %li.fr-py-2w.fr-pl-2w{ 'data-controller': "expand" } @@ -71,11 +71,11 @@ Tags .fr-ml-1w.hidden{ 'data-expand-target': 'content' } %div - = f.search_field :tag, placeholder: 'Choisissez un tag', list: 'tags_list', class: 'fr-input', data: { no_autosubmit: 'input' } + = f.search_field :tag, placeholder: 'Choisissez un tag', list: 'tags_list', class: 'fr-input', data: { no_autosubmit: 'input', turbo_force: true } %datalist#tags_list - Procedure.tags.each do |tag| %option{ value: tag } - %turbo-frame#procedures.fr-col-9{ 'data-turbo-action': 'advance' } + .fr-col-9 = yield(:results) = render template: 'layouts/application'