Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ETQ instructeur, sur la liste des démarches, je peux accéder directement à une démarche via une dropdown #11193

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# frozen_string_literal: true

class Instructeurs::SelectProcedureDropDownListComponent < Dsfr::InputComponent
def initialize(procedures:)
@procedures = procedures
end

def react_props
{
items:,
placeholder: t('.placeholder'),
name: "procedure_id",
id: 'select-procedure-drop-down-list',
'aria-describedby': 'select-procedure-drop-down-list-label',
form: 'select-procedure-drop-down-list-component',
data: { no_autosubmit: 'input blur', no_autosubmit_on_empty: 'true', autosubmit_target: 'input' }
}
end

def items
@procedures.map { ["n°#{_1.id} - #{_1.libelle}", _1.id] }
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
en:
label: Direct access
placeholder: Select a procedure
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
fr:
label: Accès direct
placeholder: Sélectionner une démarche
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
= form_with url: url_for([:select_procedure, :instructeur, :procedures]),
class: 'ml-auto',
id: 'select-procedure-drop-down-list-component',
data: { turbo: false, controller: 'autosubmit' } do

.flex.align-center
= label_tag :procedure_id, t('.label'), class: 'fr-label font-weight-bold fr-mr-2w', id: 'select-procedure-drop-down-list-label', for: 'select-procedure-drop-down-list'
%react-fragment
= render ReactComponent.new "ComboBox/SingleComboBox", **react_props

%input.hidden{
type: 'submit',
formmethod: 'get',
formaction: url_for([:select_procedure, :instructeur, :procedures]),
formnovalidate: 'true',
data: { autosubmit_target: 'submitter' }
}
8 changes: 7 additions & 1 deletion app/controllers/instructeurs/procedures_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

module Instructeurs
class ProceduresController < InstructeurController
before_action :ensure_ownership!, except: [:index, :order_positions, :update_order_positions]
before_action :ensure_ownership!, except: [:index, :order_positions, :update_order_positions, :select_procedure]
before_action :ensure_not_super_admin!, only: [:download_export, :exports]

ITEMS_PER_PAGE = 100
Expand Down Expand Up @@ -74,6 +74,12 @@ def update_order_positions
redirect_to instructeur_procedures_path, notice: "L'ordre des démarches a été mis à jour."
end

def select_procedure
return redirect_to instructeur_procedure_path(procedure_id: params[:procedure_id]) if params[:procedure_id].present?

redirect_to instructeur_procedures_path
end

def show
@procedure = procedure
# Technically, procedure_presentation already sets the attribute.
Expand Down
20 changes: 17 additions & 3 deletions app/javascript/components/ComboBox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,12 @@ export function ComboBox({
description,
className,
inputRef,
placeholder,
...props
}: ComboBoxProps & { inputRef?: RefObject<HTMLInputElement> }) {
}: ComboBoxProps & {
inputRef?: RefObject<HTMLInputElement>;
placeholder?: string;
}) {
return (
<AriaComboBox
{...props}
Expand All @@ -60,7 +64,11 @@ export function ComboBox({
</Label>
) : null}
<div className="fr-ds-combobox__input" style={{ position: 'relative' }}>
<Input className="fr-select fr-autocomplete" ref={inputRef} />
<Input
className="fr-select fr-autocomplete"
ref={inputRef}
placeholder={placeholder || undefined}
/>
<Button
aria-haspopup="false"
aria-label=""
Expand Down Expand Up @@ -97,6 +105,7 @@ export function SingleComboBox({
const {
items: defaultItems,
selectedKey: defaultSelectedKey,
placeholder,
emptyFilterKey,
name,
formValue,
Expand All @@ -116,7 +125,12 @@ export function SingleComboBox({

return (
<>
<ComboBox menuTrigger="focus" {...comboBoxProps} {...props}>
<ComboBox
menuTrigger="focus"
placeholder={placeholder}
{...comboBoxProps}
{...props}
>
{(item) => <ComboBoxItem id={item.value}>{item.label}</ComboBoxItem>}
</ComboBox>
{children || name ? (
Expand Down
3 changes: 2 additions & 1 deletion app/javascript/components/react-aria/props.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ export const SingleComboBoxProps = s.assign(
s.partial(
s.object({
selectedKey: s.nullable(s.string()),
emptyFilterKey: s.nullable(s.string())
emptyFilterKey: s.nullable(s.string()),
placeholder: s.string()
})
)
);
Expand Down
1 change: 1 addition & 0 deletions app/views/instructeurs/procedures/index.html.haml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
.flex.fr-mb-2v
%h1.fr-h3.fr-mb-0 Démarches
= render Instructeurs::TabsExplanationsComponent.new
= render Instructeurs::SelectProcedureDropDownListComponent.new(procedures: @procedures)
= render partial: 'instructeurs/procedures/synthese', locals: { procedures: @procedures, all_dossiers_counts: @all_dossiers_counts }

%nav.fr-tabs{ role: 'navigation', 'aria-label': t('views.users.dossiers.secondary_menu') }
Expand Down
1 change: 1 addition & 0 deletions config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -461,6 +461,7 @@
collection do
get 'order_positions'
patch 'update_order_positions'
get 'select_procedure'
end
end

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# frozen_string_literal: true

require "rails_helper"

RSpec.describe Instructeurs::SelectProcedureDropDownListComponent, type: :component do
subject do
render_inline(described_class.new(procedures:))
end

let(:procedures) {
[
create(:procedure, libelle: "Procedure importante", id: 1001),
create(:procedure, libelle: "Procedure facile", id: 1002),
create(:procedure, libelle: "Procedure terminée", id: 1003)
]
}

it "renders the label" do
expect(subject).to have_text("Accès direct")
end

let(:react_component) { page.find('react-component') }
let(:react_props_items) { JSON.parse(react_component['props']) }

it "renders the procedures" do
subject
expect(react_props_items["items"]).to eq([
["n°1001 - Procedure importante", 1001],
["n°1002 - Procedure facile", 1002],
["n°1003 - Procedure terminée", 1003]
])
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# frozen_string_literal: true

class Instructeurs::SelectProcedureDropDownListComponentPreview < ViewComponent::Preview
def default
@procedures = Procedure.limit(10)
render(Instructeurs::SelectProcedureDropDownListComponent.new(procedures: @procedures))
end
end
43 changes: 43 additions & 0 deletions spec/controllers/instructeurs/procedures_controller_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -995,4 +995,47 @@
expect(response.body).not_to include("Déposer")
end
end

describe '#select_procedure' do
let(:instructeur) { create(:instructeur) }

before do
sign_in(instructeur.user)
end

context 'when procedure_id is present' do
let(:procedure) { create(:procedure) }

it 'redirects to the procedure path' do
puts "procedure.id: #{procedure.id}"
get :select_procedure, params: { procedure_id: procedure.id }

expect(response).to redirect_to(instructeur_procedure_path(procedure_id: procedure.id))
end
end

context 'when procedure_id is not present' do
it 'redirects to procedures index' do
get :select_procedure

expect(response).to redirect_to(instructeur_procedures_path)
end
end

context 'when procedure_id is empty string' do
it 'redirects to procedures index' do
get :select_procedure, params: { procedure_id: '' }

expect(response).to redirect_to(instructeur_procedures_path)
end
end

context 'when procedure_id is nil' do
it 'redirects to procedures index' do
get :select_procedure, params: { procedure_id: nil }

expect(response).to redirect_to(instructeur_procedures_path)
end
end
end
end
Loading