Merge pull request #8416 from tchak/stimulus-autosubmit
refactor(autosubmit): split and improuve autosubmit and turbo controller
This commit is contained in:
commit
40befbccc3
16 changed files with 138 additions and 75 deletions
|
@ -1,12 +1,13 @@
|
||||||
= form_tag add_filter_instructeur_procedure_url(procedure), method: :post, class: 'dropdown-form large', id: 'filter-component', data: { controller: 'dossier-filter' } do
|
= form_tag add_filter_instructeur_procedure_path(procedure), method: :post, class: 'dropdown-form large', id: 'filter-component', data: { turbo: true, controller: 'autosubmit' } do
|
||||||
= label_tag :field, t('.column')
|
= label_tag :field, t('.column')
|
||||||
= select_tag :field, options_for_select(filterable_fields_for_select, field_id), include_blank: field_id.nil?, data: {action: "dossier-filter#onChange"}
|
= select_tag :field, options_for_select(filterable_fields_for_select, field_id), include_blank: field_id.nil?
|
||||||
|
%input.hidden{ type: 'submit', formaction: update_filter_instructeur_procedure_path(procedure), data: { autosubmit_target: 'submitter' } }
|
||||||
%br
|
%br
|
||||||
= label_tag :value, t('.value'), for: 'value'
|
= label_tag :value, t('.value'), for: 'value'
|
||||||
- if field_type == :enum
|
- if field_type == :enum
|
||||||
= select_tag :value, options_for_select(options_for_select_of_field), id: 'value', name: 'value'
|
= select_tag :value, options_for_select(options_for_select_of_field), id: 'value', name: 'value', data: { no_autosubmit: true }
|
||||||
- else
|
- else
|
||||||
%input#value{ type: field_type, name: :value, maxlength: ProcedurePresentation::FILTERS_VALUE_MAX_LENGTH, disabled: field_id.nil? ? true : false }
|
%input#value{ type: field_type, name: :value, maxlength: ProcedurePresentation::FILTERS_VALUE_MAX_LENGTH, disabled: field_id.nil? ? true : false, data: { no_autosubmit: true } }
|
||||||
|
|
||||||
= hidden_field_tag :statut, statut
|
= hidden_field_tag :statut, statut
|
||||||
= submit_tag t('.add_filter'), class: 'fr-btn fr-btn--secondary fr-mt-2w'
|
= submit_tag t('.add_filter'), class: 'fr-btn fr-btn--secondary fr-mt-2w'
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
= form_tag update_sort_instructeur_procedure_path(procedure_id: @procedure.id, table: 'notifications', column: 'notifications', order: opposite_order), method: 'GET', data: {controller: 'checkbox'} do
|
= form_tag update_sort_instructeur_procedure_path(procedure_id: @procedure.id, table: 'notifications', column: 'notifications', order: opposite_order), method: :get, data: { controller: 'autosubmit' } do
|
||||||
.fr-toggle
|
.fr-toggle
|
||||||
= check_box_tag :order, opposite_order, active?, data: {action: 'change->checkbox#onChange'}, class: 'fr-toggle__input'
|
= check_box_tag :order, opposite_order, active?, class: 'fr-toggle__input'
|
||||||
= label_tag :order, t('.show_notified_first'), class: 'fr-toggle__label fr-pl-1w'
|
= label_tag :order, t('.show_notified_first'), class: 'fr-toggle__label fr-pl-1w'
|
||||||
= submit_tag t('.show_notified_first'), data: {"checkbox-target": 'submit' }, class: 'visually-hidden'
|
= submit_tag t('.show_notified_first'), data: {"checkbox-target": 'submit' }, class: 'visually-hidden'
|
||||||
|
|
|
@ -131,19 +131,16 @@ module Instructeurs
|
||||||
end
|
end
|
||||||
|
|
||||||
def add_filter
|
def add_filter
|
||||||
respond_to do |format|
|
procedure_presentation.add_filter(statut, params[:field], params[:value])
|
||||||
format.html do
|
|
||||||
procedure_presentation.add_filter(statut, params[:field], params[:value])
|
|
||||||
|
|
||||||
redirect_back(fallback_location: instructeur_procedure_url(procedure))
|
redirect_back(fallback_location: instructeur_procedure_url(procedure))
|
||||||
end
|
end
|
||||||
format.turbo_stream do
|
|
||||||
@statut = statut
|
def update_filter
|
||||||
@procedure = procedure
|
@statut = statut
|
||||||
@procedure_presentation = procedure_presentation
|
@procedure = procedure
|
||||||
@field = params[:field]
|
@procedure_presentation = procedure_presentation
|
||||||
end
|
@field = params[:field]
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def remove_filter
|
def remove_filter
|
||||||
|
|
|
@ -4,7 +4,7 @@ import debounce from 'debounce';
|
||||||
export type Detail = Record<string, unknown>;
|
export type Detail = Record<string, unknown>;
|
||||||
|
|
||||||
export class ApplicationController extends Controller {
|
export class ApplicationController extends Controller {
|
||||||
#debounced = new Map<() => void, () => void>();
|
#debounced = new Map<() => void, ReturnType<typeof debounce>>();
|
||||||
|
|
||||||
protected debounce(fn: () => void, interval: number): void {
|
protected debounce(fn: () => void, interval: number): void {
|
||||||
this.globalDispatch('debounced:added');
|
this.globalDispatch('debounced:added');
|
||||||
|
@ -26,6 +26,10 @@ export class ApplicationController extends Controller {
|
||||||
debounced();
|
debounced();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected cancelDebounce(fn: () => void) {
|
||||||
|
this.#debounced.get(fn)?.clear();
|
||||||
|
}
|
||||||
|
|
||||||
protected globalDispatch<T = Detail>(type: string, detail?: T): void {
|
protected globalDispatch<T = Detail>(type: string, detail?: T): void {
|
||||||
this.dispatch(type, {
|
this.dispatch(type, {
|
||||||
detail: detail as object,
|
detail: detail as object,
|
||||||
|
|
|
@ -1,32 +1,79 @@
|
||||||
|
import {
|
||||||
|
isSelectElement,
|
||||||
|
isCheckboxOrRadioInputElement,
|
||||||
|
isTextInputElement,
|
||||||
|
isDateInputElement
|
||||||
|
} from '@utils';
|
||||||
import { ApplicationController } from './application_controller';
|
import { ApplicationController } from './application_controller';
|
||||||
import { show, hide } from '@utils';
|
|
||||||
const AUTOSUBMIT_DEBOUNCE_DELAY = 5000;
|
const AUTOSUBMIT_DEBOUNCE_DELAY = 500;
|
||||||
|
const AUTOSUBMIT_DATE_DEBOUNCE_DELAY = 5000;
|
||||||
|
|
||||||
export class AutosubmitController extends ApplicationController {
|
export class AutosubmitController extends ApplicationController {
|
||||||
static targets = ['form', 'spinner'];
|
static targets = ['submitter'];
|
||||||
|
|
||||||
declare readonly formTarget: HTMLFormElement;
|
declare readonly submitterTarget: HTMLButtonElement | HTMLInputElement;
|
||||||
declare readonly spinnerTarget: HTMLElement;
|
declare readonly hasSubmitterTarget: boolean;
|
||||||
declare readonly hasSpinnerTarget: boolean;
|
|
||||||
|
|
||||||
submit() {
|
#dateTimeChangedInputs = new WeakSet<HTMLInputElement>();
|
||||||
this.formTarget.requestSubmit();
|
|
||||||
}
|
|
||||||
|
|
||||||
debouncedSubmit() {
|
|
||||||
this.debounce(this.submit, AUTOSUBMIT_DEBOUNCE_DELAY);
|
|
||||||
}
|
|
||||||
|
|
||||||
connect() {
|
connect() {
|
||||||
this.onGlobal('turbo:submit-start', () => {
|
this.on('input', (event) => this.onInput(event));
|
||||||
if (this.hasSpinnerTarget) {
|
this.on('change', (event) => this.onChange(event));
|
||||||
show(this.spinnerTarget);
|
this.on('blur', (event) => this.onBlur(event));
|
||||||
|
}
|
||||||
|
|
||||||
|
private onChange(event: Event) {
|
||||||
|
const target = event.target as HTMLInputElement;
|
||||||
|
if (target.disabled || target.hasAttribute('data-no-autosubmit')) return;
|
||||||
|
|
||||||
|
if (
|
||||||
|
isSelectElement(target) ||
|
||||||
|
isCheckboxOrRadioInputElement(target) ||
|
||||||
|
isTextInputElement(target)
|
||||||
|
) {
|
||||||
|
if (isDateInputElement(target)) {
|
||||||
|
if (target.value.trim() == '' || !isNaN(Date.parse(target.value))) {
|
||||||
|
this.#dateTimeChangedInputs.add(target);
|
||||||
|
this.debounce(this.submit, AUTOSUBMIT_DATE_DEBOUNCE_DELAY);
|
||||||
|
} else {
|
||||||
|
this.#dateTimeChangedInputs.delete(target);
|
||||||
|
this.cancelDebounce(this.submit);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.cancelDebounce(this.submit);
|
||||||
|
this.submit();
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
this.onGlobal('turbo:submit-end', () => {
|
}
|
||||||
if (this.hasSpinnerTarget) {
|
|
||||||
hide(this.spinnerTarget);
|
private onInput(event: Event) {
|
||||||
}
|
const target = event.target as HTMLInputElement;
|
||||||
});
|
if (target.disabled || target.hasAttribute('data-no-autosubmit')) return;
|
||||||
|
|
||||||
|
if (!isDateInputElement(target) && isTextInputElement(target)) {
|
||||||
|
this.debounce(this.submit, AUTOSUBMIT_DEBOUNCE_DELAY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private onBlur(event: Event) {
|
||||||
|
const target = event.target as HTMLInputElement;
|
||||||
|
if (target.disabled || target.hasAttribute('data-no-autosubmit')) return;
|
||||||
|
|
||||||
|
if (isDateInputElement(target)) {
|
||||||
|
Promise.resolve().then(() => {
|
||||||
|
if (this.#dateTimeChangedInputs.has(target)) {
|
||||||
|
this.cancelDebounce(this.submit);
|
||||||
|
this.submit();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private submit() {
|
||||||
|
const submitter = this.hasSubmitterTarget ? this.submitterTarget : null;
|
||||||
|
const form =
|
||||||
|
submitter?.form ?? this.element.closest<HTMLFormElement>('form');
|
||||||
|
form?.requestSubmit(submitter);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +0,0 @@
|
||||||
import { ApplicationController } from './application_controller';
|
|
||||||
|
|
||||||
export class CheckboxController extends ApplicationController {
|
|
||||||
onChange() {
|
|
||||||
const form = this.element as HTMLFormElement;
|
|
||||||
form.requestSubmit();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,13 +0,0 @@
|
||||||
import { httpRequest } from '@utils';
|
|
||||||
import { ApplicationController } from './application_controller';
|
|
||||||
|
|
||||||
export class DossierFilterController extends ApplicationController {
|
|
||||||
onChange() {
|
|
||||||
const element = this.element as HTMLFormElement;
|
|
||||||
|
|
||||||
httpRequest(element.action, {
|
|
||||||
method: element.getAttribute('method') ?? '',
|
|
||||||
body: new FormData(element)
|
|
||||||
}).turbo();
|
|
||||||
}
|
|
||||||
}
|
|
23
app/javascript/controllers/turbo_controller.ts
Normal file
23
app/javascript/controllers/turbo_controller.ts
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
import { show, hide } from '@utils';
|
||||||
|
|
||||||
|
import { ApplicationController } from './application_controller';
|
||||||
|
|
||||||
|
export class TurboController extends ApplicationController {
|
||||||
|
static targets = ['spinner'];
|
||||||
|
|
||||||
|
declare readonly spinnerTarget: HTMLElement;
|
||||||
|
declare readonly hasSpinnerTarget: boolean;
|
||||||
|
|
||||||
|
connect() {
|
||||||
|
this.onGlobal('turbo:submit-start', () => {
|
||||||
|
if (this.hasSpinnerTarget) {
|
||||||
|
show(this.spinnerTarget);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this.onGlobal('turbo:submit-end', () => {
|
||||||
|
if (this.hasSpinnerTarget) {
|
||||||
|
hide(this.spinnerTarget);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -290,6 +290,15 @@ export function isCheckboxOrRadioInputElement(
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function isDateInputElement(
|
||||||
|
element: HTMLElement & { type?: string }
|
||||||
|
): element is HTMLInputElement {
|
||||||
|
return (
|
||||||
|
element.tagName == 'INPUT' &&
|
||||||
|
(element.type == 'date' || element.type == 'datetime-local')
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
export function isTextInputElement(
|
export function isTextInputElement(
|
||||||
element: HTMLElement & { type?: string }
|
element: HTMLElement & { type?: string }
|
||||||
): element is HTMLInputElement {
|
): element is HTMLInputElement {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
- content_for :results do
|
- content_for :results do
|
||||||
.main-filter-header.fr-my-3w
|
.main-filter-header.fr-my-3w
|
||||||
= form_with(url: administrateurs_admin_procedures_path, method: :get, html: { 'data-autosubmit-target': 'form', 'data-turbo-frame': 'procedures', role: 'search' }) do |f|
|
= 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|
|
- @filter.zone_ids&.each do |zone_id|
|
||||||
= hidden_field_tag 'zone_ids[]', zone_id
|
= hidden_field_tag 'zone_ids[]', zone_id
|
||||||
- @filter.statuses&.each do |status|
|
- @filter.statuses&.each do |status|
|
||||||
|
@ -14,7 +14,7 @@
|
||||||
%table#all-admins
|
%table#all-admins
|
||||||
%caption
|
%caption
|
||||||
= "#{@admins.total_count} administrateurs"
|
= "#{@admins.total_count} administrateurs"
|
||||||
%span.hidden.fr-icon-ball-pen-fill{ 'aria-hidden': 'true', 'data-autosubmit-target': 'spinner' }
|
%span.hidden.fr-icon-ball-pen-fill{ 'aria-hidden': 'true', 'data-turbo-target': 'spinner' }
|
||||||
- if @filter.email
|
- if @filter.email
|
||||||
.selected-email.fr-mb-2w
|
.selected-email.fr-mb-2w
|
||||||
= link_to @filter.email, administrateurs_admin_procedures_path(@filter.without(:email)), class: 'fr-tag fr-tag--dismiss fr-mb-1w'
|
= link_to @filter.email, administrateurs_admin_procedures_path(@filter.without(:email)), class: 'fr-tag fr-tag--dismiss fr-mb-1w'
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
- content_for :results do
|
- content_for :results do
|
||||||
.main-filter-header.fr-my-3w
|
.main-filter-header.fr-my-3w
|
||||||
= form_with(url: all_admin_procedures_path, method: :get, html: { 'data-autosubmit-target': 'form', 'data-turbo-frame': 'procedures', role: 'search', class: 'search' }) do |f|
|
= 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|
|
- @filter.zone_ids&.each do |zone_id|
|
||||||
= hidden_field_tag 'zone_ids[]', zone_id
|
= hidden_field_tag 'zone_ids[]', zone_id
|
||||||
- @filter.statuses&.each do |status|
|
- @filter.statuses&.each do |status|
|
||||||
|
@ -16,7 +16,7 @@
|
||||||
%table#all-demarches
|
%table#all-demarches
|
||||||
%caption
|
%caption
|
||||||
= "#{@procedures.total_count} démarches"
|
= "#{@procedures.total_count} démarches"
|
||||||
%span.hidden.fr-icon-ball-pen-fill{ 'aria-hidden': 'true', 'data-autosubmit-target': 'spinner' }
|
%span.hidden.fr-icon-ball-pen-fill{ 'aria-hidden': 'true', 'data-turbo-target': 'spinner' }
|
||||||
- if @filter.libelle
|
- if @filter.libelle
|
||||||
.selected-query.fr-mb-2w
|
.selected-query.fr-mb-2w
|
||||||
= link_to @filter.libelle, all_admin_procedures_path(@filter.without(:libelle)), class: 'fr-tag fr-tag--dismiss fr-mb-1w'
|
= link_to @filter.libelle, all_admin_procedures_path(@filter.without(:libelle)), class: 'fr-tag fr-tag--dismiss fr-mb-1w'
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
= turbo_stream.replace 'filter-component' do
|
= turbo_stream.morph 'filter-component' do
|
||||||
= render Dossiers::FilterComponent.new(procedure: @procedure, procedure_presentation: @procedure_presentation, statut: @statut, field_id: @field)
|
= render Dossiers::FilterComponent.new(procedure: @procedure, procedure_presentation: @procedure_presentation, statut: @statut, field_id: @field)
|
|
@ -9,10 +9,10 @@
|
||||||
.fr-highlight.fr-mb-4w
|
.fr-highlight.fr-mb-4w
|
||||||
%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.
|
%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', 'data-controller': 'autosubmit' }
|
.fr-container--fluid{ data: { turbo: 'true' } }
|
||||||
.fr-grid-row.fr-grid-row--gutters
|
.fr-grid-row.fr-grid-row--gutters
|
||||||
.fr-col-3
|
.fr-col-3
|
||||||
= form_with(url: all_admin_procedures_path, method: :get, html: { 'data-autosubmit-target': 'form', 'data-turbo-frame': 'procedures' }) do |f|
|
= form_with(url: all_admin_procedures_path, method: :get, data: { controller: 'autosubmit', turbo_frame: 'procedures' }) do |f|
|
||||||
|
|
||||||
%fieldset.sidebar-filter
|
%fieldset.sidebar-filter
|
||||||
%legend
|
%legend
|
||||||
|
@ -31,7 +31,7 @@
|
||||||
.fr-ml-1w{ 'data-expand-target': 'content' }
|
.fr-ml-1w{ 'data-expand-target': 'content' }
|
||||||
= f.collection_check_boxes :zone_ids, @filter.admin_zones, :id, :current_label, include_hidden: false do |b|
|
= f.collection_check_boxes :zone_ids, @filter.admin_zones, :id, :current_label, include_hidden: false do |b|
|
||||||
.fr-checkbox-group.fr-ml-2w.fr-py-1w
|
.fr-checkbox-group.fr-ml-2w.fr-py-1w
|
||||||
= b.check_box(checked: @filter.zone_filtered?(b.value), 'data-action': 'autosubmit#submit')
|
= b.check_box(checked: @filter.zone_filtered?(b.value))
|
||||||
= b.label(class: 'fr-label') { b.text }
|
= b.label(class: 'fr-label') { b.text }
|
||||||
%li.fr-py-2w.fr-pl-2w{ 'data-controller': "expand" }
|
%li.fr-py-2w.fr-pl-2w{ 'data-controller': "expand" }
|
||||||
.fr-mb-1w
|
.fr-mb-1w
|
||||||
|
@ -41,7 +41,7 @@
|
||||||
.fr-ml-1w.hidden{ 'data-expand-target': 'content' }
|
.fr-ml-1w.hidden{ 'data-expand-target': 'content' }
|
||||||
= f.collection_check_boxes :zone_ids, @filter.other_zones, :id, :current_label, include_hidden: false do |b|
|
= f.collection_check_boxes :zone_ids, @filter.other_zones, :id, :current_label, include_hidden: false do |b|
|
||||||
.fr-checkbox-group.fr-ml-2w.fr-py-1w
|
.fr-checkbox-group.fr-ml-2w.fr-py-1w
|
||||||
= b.check_box(checked: @filter.zone_filtered?(b.value), 'data-action': 'autosubmit#submit')
|
= b.check_box(checked: @filter.zone_filtered?(b.value))
|
||||||
= b.label(class: 'fr-label') { b.text }
|
= b.label(class: 'fr-label') { b.text }
|
||||||
%li.fr-py-2w{ 'data-controller': "expand" }
|
%li.fr-py-2w{ 'data-controller': "expand" }
|
||||||
.fr-mb-1w.fr-pl-2w
|
.fr-mb-1w.fr-pl-2w
|
||||||
|
@ -51,7 +51,7 @@
|
||||||
.fr-input-group.hidden{ 'data-expand-target': 'content' }
|
.fr-input-group.hidden{ 'data-expand-target': 'content' }
|
||||||
= f.label 'from_publication_date', 'Depuis', class: 'fr-label'
|
= f.label 'from_publication_date', 'Depuis', class: 'fr-label'
|
||||||
.fr-input-wrap.fr-fi-calendar-line
|
.fr-input-wrap.fr-fi-calendar-line
|
||||||
= f.date_field 'from_publication_date', value: @filter.from_publication_date, class: 'fr-input', 'data-action': 'blur->autosubmit#submit change->autosubmit#debouncedSubmit'
|
= f.date_field 'from_publication_date', value: @filter.from_publication_date, class: 'fr-input'
|
||||||
|
|
||||||
%li.fr-py-2w.fr-pl-2w{ 'data-controller': "expand" }
|
%li.fr-py-2w.fr-pl-2w{ 'data-controller': "expand" }
|
||||||
.fr-mb-1w
|
.fr-mb-1w
|
||||||
|
@ -61,7 +61,7 @@
|
||||||
.fr-ml-1w.hidden{ 'data-expand-target': 'content' }
|
.fr-ml-1w.hidden{ 'data-expand-target': 'content' }
|
||||||
= f.collection_check_boxes :statuses, ['publiee', 'close'], :to_s, :to_s, include_hidden: false do |b|
|
= f.collection_check_boxes :statuses, ['publiee', 'close'], :to_s, :to_s, include_hidden: false do |b|
|
||||||
.fr-checkbox-group.fr-ml-2w.fr-py-1w
|
.fr-checkbox-group.fr-ml-2w.fr-py-1w
|
||||||
= b.check_box(checked: @filter.status_filtered?(b.value), 'data-action': 'autosubmit#submit')
|
= b.check_box(checked: @filter.status_filtered?(b.value))
|
||||||
= b.label(class: 'fr-label') { t b.text, scope: 'activerecord.attributes.procedure.aasm_state' }
|
= b.label(class: 'fr-label') { t b.text, scope: 'activerecord.attributes.procedure.aasm_state' }
|
||||||
|
|
||||||
%turbo-frame#procedures.fr-col-9{ 'data-turbo-action': 'advance' }
|
%turbo-frame#procedures.fr-col-9{ 'data-turbo-action': 'advance' }
|
||||||
|
|
|
@ -35,7 +35,7 @@
|
||||||
|
|
||||||
= yield(:invisible_captcha_styles)
|
= yield(:invisible_captcha_styles)
|
||||||
|
|
||||||
%body{ { id: content_for(:page_id), class: browser.platform.ios? ? 'ios' : nil }.compact }
|
%body{ { id: content_for(:page_id), class: browser.platform.ios? ? 'ios' : nil, data: { controller: 'turbo' } }.compact }
|
||||||
= render partial: 'layouts/skiplinks'
|
= render partial: 'layouts/skiplinks'
|
||||||
.page-wrapper
|
.page-wrapper
|
||||||
= render partial: "layouts/outdated_browser_banner"
|
= render partial: "layouts/outdated_browser_banner"
|
||||||
|
|
|
@ -394,7 +394,8 @@ Rails.application.routes.draw do
|
||||||
patch 'update_displayed_fields'
|
patch 'update_displayed_fields'
|
||||||
get 'update_sort/:table/:column' => 'procedures#update_sort', as: 'update_sort'
|
get 'update_sort/:table/:column' => 'procedures#update_sort', as: 'update_sort'
|
||||||
post 'add_filter'
|
post 'add_filter'
|
||||||
get 'remove_filter' => 'procedures#remove_filter', as: 'remove_filter'
|
post 'update_filter'
|
||||||
|
get 'remove_filter'
|
||||||
get 'download_export'
|
get 'download_export'
|
||||||
post 'download_export'
|
post 'download_export'
|
||||||
get 'stats'
|
get 'stats'
|
||||||
|
|
|
@ -84,6 +84,7 @@ describe "procedure filters" do
|
||||||
find("input#value[type=date]", visible: true)
|
find("input#value[type=date]", visible: true)
|
||||||
fill_in "Valeur", with: "10/10/2010"
|
fill_in "Valeur", with: "10/10/2010"
|
||||||
click_button "Ajouter le filtre"
|
click_button "Ajouter le filtre"
|
||||||
|
expect(page).to have_no_css("select#field", visible: true)
|
||||||
|
|
||||||
# use enum filter
|
# use enum filter
|
||||||
click_on 'Sélectionner un filtre'
|
click_on 'Sélectionner un filtre'
|
||||||
|
@ -134,6 +135,7 @@ describe "procedure filters" do
|
||||||
select column_name, from: "Colonne"
|
select column_name, from: "Colonne"
|
||||||
fill_in "Valeur", with: filter_value
|
fill_in "Valeur", with: filter_value
|
||||||
click_button "Ajouter le filtre"
|
click_button "Ajouter le filtre"
|
||||||
|
expect(page).to have_no_css("select#field", visible: true)
|
||||||
end
|
end
|
||||||
|
|
||||||
def add_column(column_name)
|
def add_column(column_name)
|
||||||
|
|
Loading…
Reference in a new issue