Convert datetime field to datetime_local (#8572)
* Convert datetime field to datetime_local * Fix tests * Add value formatting view datetime component * Add helper datetime component value
This commit is contained in:
parent
9c26d76f28
commit
4b0e6ea382
10 changed files with 55 additions and 66 deletions
|
@ -173,6 +173,7 @@
|
|||
input[type=email],
|
||||
input[type=password],
|
||||
input[type=date],
|
||||
input[type=datetime-local],
|
||||
input[type=number],
|
||||
input[type=tel],
|
||||
textarea,
|
||||
|
@ -207,6 +208,7 @@
|
|||
input[type=date],
|
||||
input[type=number],
|
||||
input[type=tel],
|
||||
input[type=datetime-local],
|
||||
textarea,
|
||||
select {
|
||||
border-radius: 4px;
|
||||
|
@ -248,6 +250,7 @@
|
|||
input[type=password],
|
||||
input[type=date],
|
||||
input[type=number],
|
||||
input[type=datetime-local],
|
||||
input[type=tel],
|
||||
textarea {
|
||||
@media (max-width: $two-columns-breakpoint) {
|
||||
|
@ -284,7 +287,8 @@
|
|||
&:not([size]) {
|
||||
&[type='date'],
|
||||
&[type='tel'],
|
||||
&[type='number'] {
|
||||
&[type='number'],
|
||||
&[type='datetime-local'] {
|
||||
width: 33.33%;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
class EditableChamp::DatetimeComponent < EditableChamp::EditableChampBaseComponent
|
||||
def datetime_start_year(date)
|
||||
if date == nil || date.year == 0 || date.year >= Date.today.year - 1
|
||||
Date.today.year - 1
|
||||
def formatted_value_for_datetime_locale
|
||||
if @champ.valid? && @champ.value.present?
|
||||
# convert to a format that the datetime-local input can understand
|
||||
DateTime.iso8601(@champ.value).strftime('%Y-%m-%dT%H:%M')
|
||||
else
|
||||
date.year
|
||||
@champ.value
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,4 +1,2 @@
|
|||
- parsed_value = @champ.value.present? ? Time.zone.parse(@champ.value) : nil
|
||||
|
||||
.datetime
|
||||
= @form.datetime_select(:value, id: @champ.input_id, aria: { describedby: @champ.describedby_id }, selected: parsed_value, start_year: datetime_start_year(parsed_value), end_year: Date.today.year + 50, minute_step: 5, include_blank: true)
|
||||
= @form.datetime_field(:value, value: formatted_value_for_datetime_locale, id: @champ.input_id, aria: { describedby: @champ.describedby_id })
|
||||
|
|
|
@ -36,10 +36,6 @@ class Champs::DatetimeChamp < Champ
|
|||
value.present? ? I18n.l(Time.zone.parse(value)) : ""
|
||||
end
|
||||
|
||||
def html_label?
|
||||
false
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def convert_to_iso8601
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
describe EditableChamp::DatetimeComponent, type: :component do
|
||||
let(:component) {
|
||||
described_class.new(form: instance_double(ActionView::Helpers::FormBuilder, object_name: "dossier[champs_public_attributes]"), champ:)
|
||||
}
|
||||
|
||||
describe '#formatted_value_for_datetime_locale' do
|
||||
subject { component.formatted_value_for_datetime_locale }
|
||||
|
||||
context 'when the value is nil' do
|
||||
let(:champ) { create(:champ_datetime, dossier: create(:dossier), value: nil) }
|
||||
|
||||
it { is_expected.to be_nil }
|
||||
end
|
||||
|
||||
context 'when the value is not a valid datetime' do
|
||||
let(:champ) { create(:champ_datetime, dossier: create(:dossier), value: 'invalid') }
|
||||
|
||||
it { is_expected.to be_nil }
|
||||
end
|
||||
|
||||
context 'when the value is a valid datetime' do
|
||||
let(:champ) { create(:champ_datetime, dossier: create(:dossier), value: '2020-01-01T00:00:00+01:00') }
|
||||
|
||||
it { is_expected.to eq('2020-01-01T00:00') }
|
||||
end
|
||||
end
|
||||
end
|
|
@ -796,11 +796,7 @@ describe Instructeurs::DossiersController, type: :controller do
|
|||
},
|
||||
'1': {
|
||||
id: champ_datetime.id,
|
||||
'value(1i)': 2019,
|
||||
'value(2i)': 12,
|
||||
'value(3i)': 21,
|
||||
'value(4i)': 13,
|
||||
'value(5i)': 17
|
||||
value: '2019-12-21T13:17'
|
||||
},
|
||||
'2': {
|
||||
id: champ_linked_drop_down_list.id,
|
||||
|
|
|
@ -18,5 +18,6 @@ shared_examples "the user has got a prefilled dossier, owned by themselves" do
|
|||
expect(page).to have_field(type_de_champ_text.libelle, with: text_value)
|
||||
expect(page).to have_field(type_de_champ_phone.libelle, with: phone_value)
|
||||
expect(page).to have_css('label', text: type_de_champ_phone.libelle)
|
||||
expect(page).to have_field(type_de_champ_datetime.libelle, with: datetime_value)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -21,8 +21,9 @@ describe 'The user' do
|
|||
# fill data
|
||||
fill_in('text *', with: 'super texte')
|
||||
fill_in('textarea', with: 'super textarea')
|
||||
fill_in('date', with: '12-12-2012')
|
||||
select_date_and_time(Time.zone.parse('06/01/2030 7h05'), form_id_for_datetime('datetime'))
|
||||
fill_in('date *', with: '12-12-2012')
|
||||
fill_in('datetime', with: Time.zone.parse('2023-01-06T07:05'))
|
||||
find("input[type=datetime-local]").send_keys(:arrow_up).send_keys(:arrow_down) # triggers onChange
|
||||
fill_in('number', with: '42')
|
||||
fill_in('decimal_number', with: '17')
|
||||
fill_in('integer_number', with: '12')
|
||||
|
@ -57,7 +58,7 @@ describe 'The user' do
|
|||
expect(champ_value_for('text')).to eq('super texte')
|
||||
expect(champ_value_for('textarea')).to eq('super textarea')
|
||||
expect(champ_value_for('date')).to eq('2012-12-12')
|
||||
expect(champ_value_for('datetime')).to eq('2030-01-06T07:05:00+01:00')
|
||||
expect(champ_value_for('datetime')).to eq('2023-01-06T07:05:00+01:00')
|
||||
expect(champ_value_for('number')).to eq('42')
|
||||
expect(champ_value_for('decimal_number')).to eq('17')
|
||||
expect(champ_value_for('integer_number')).to eq('12')
|
||||
|
@ -82,7 +83,7 @@ describe 'The user' do
|
|||
expect(page).to have_field('text', with: 'super texte')
|
||||
expect(page).to have_field('textarea', with: 'super textarea')
|
||||
expect(page).to have_field('date', with: '2012-12-12')
|
||||
check_date_and_time(Time.zone.parse('06/01/2030 7:05'), form_id_for_datetime('datetime'))
|
||||
expect(page).to have_field('datetime', with: '2023-01-06T07:05')
|
||||
expect(page).to have_field('number', with: '42')
|
||||
expect(page).to have_checked_field('checkbox')
|
||||
expect(page).to have_checked_field('Madame')
|
||||
|
@ -527,32 +528,6 @@ describe 'The user' do
|
|||
expect(page).to have_current_path(identite_dossier_path(user_dossier))
|
||||
end
|
||||
|
||||
def form_id_for_datetime(libelle)
|
||||
# The HTML for datetime is a bit specific since it has 5 selects, below here is a sample HTML
|
||||
# So, we want to find the partial id of a datetime (partial because there are 5 ids:
|
||||
# dossier_champs_attributes_3_value_1i, 2i, ... 5i) ; we are interested in the 'dossier_champs_attributes_3_value' part
|
||||
# which is then completed in select_date_and_time and check_date_and_time
|
||||
#
|
||||
# We find the H2, find the first select in the next .datetime div, then strip the last 3 characters
|
||||
#
|
||||
# <h4 class="form-label">
|
||||
# libelle
|
||||
# </h4>
|
||||
# <div class="datetime">
|
||||
# <span class="hidden">
|
||||
# <label for="dossier_champs_attributes_3_value_3i">Jour</label></span>
|
||||
# <select id="dossier_champs_attributes_3_value_3i" name="dossier[champs_attributes][3][value(3i)]">
|
||||
# <option value=""></option>
|
||||
# <option value="1">1</option>
|
||||
# <option value="2">2</option>
|
||||
# <!-- … -->
|
||||
# </select>
|
||||
# <!-- … 4 other selects for month, year, minute and seconds -->
|
||||
# </div>
|
||||
e = find(:xpath, ".//div[contains(text()[normalize-space()], '#{libelle}')]")
|
||||
e.sibling('.datetime').first('select')[:id][0..-4]
|
||||
end
|
||||
|
||||
def champ_value_for(libelle)
|
||||
champs = user_dossier.reload.champs_public
|
||||
champs.find { |c| c.libelle == libelle }.value
|
||||
|
@ -565,20 +540,4 @@ describe 'The user' do
|
|||
click_on 'Continuer'
|
||||
expect(page).to have_current_path(brouillon_dossier_path(user_dossier))
|
||||
end
|
||||
|
||||
def select_date_and_time(date, field)
|
||||
select date.strftime('%Y'), from: "#{field}_1i" # year
|
||||
select I18n.l(date, format: '%B'), from: "#{field}_2i" # month
|
||||
select date.strftime('%-d'), from: "#{field}_3i" # day
|
||||
select date.strftime('%H'), from: "#{field}_4i" # hour
|
||||
select date.strftime('%M'), from: "#{field}_5i" # minute
|
||||
end
|
||||
|
||||
def check_date_and_time(date, field)
|
||||
expect(page).to have_selected_value("#{field}_1i", selected: date.strftime('%Y'))
|
||||
expect(page).to have_selected_value("#{field}_2i", selected: I18n.l(date, format: '%B'))
|
||||
expect(page).to have_selected_value("#{field}_3i", selected: date.strftime('%-d'))
|
||||
expect(page).to have_selected_value("#{field}_4i", selected: date.strftime('%H'))
|
||||
expect(page).to have_selected_value("#{field}_5i", selected: date.strftime('%M'))
|
||||
end
|
||||
end
|
||||
|
|
|
@ -6,8 +6,10 @@ describe 'Prefilling a dossier (with a GET request):' do
|
|||
|
||||
let(:type_de_champ_text) { create(:type_de_champ_text, procedure: procedure) }
|
||||
let(:type_de_champ_phone) { create(:type_de_champ_phone, procedure: procedure) }
|
||||
let(:type_de_champ_datetime) { create(:type_de_champ_datetime, procedure: procedure) }
|
||||
let(:text_value) { "My Neighbor Totoro is the best movie ever" }
|
||||
let(:phone_value) { "invalid phone value" }
|
||||
let(:datetime_value) { "2023-02-01T10:32" }
|
||||
|
||||
context 'when authenticated' do
|
||||
it_behaves_like "the user has got a prefilled dossier, owned by themselves" do
|
||||
|
@ -20,7 +22,8 @@ describe 'Prefilling a dossier (with a GET request):' do
|
|||
visit commencer_path(
|
||||
path: procedure.path,
|
||||
"champ_#{type_de_champ_text.to_typed_id}" => text_value,
|
||||
"champ_#{type_de_champ_phone.to_typed_id}" => phone_value
|
||||
"champ_#{type_de_champ_phone.to_typed_id}" => phone_value,
|
||||
"champ_#{type_de_champ_datetime.to_typed_id}" => datetime_value
|
||||
)
|
||||
|
||||
click_on "Poursuivre mon dossier prérempli"
|
||||
|
@ -33,7 +36,8 @@ describe 'Prefilling a dossier (with a GET request):' do
|
|||
visit commencer_path(
|
||||
path: procedure.path,
|
||||
"champ_#{type_de_champ_text.to_typed_id}" => text_value,
|
||||
"champ_#{type_de_champ_phone.to_typed_id}" => phone_value
|
||||
"champ_#{type_de_champ_phone.to_typed_id}" => phone_value,
|
||||
"champ_#{type_de_champ_datetime.to_typed_id}" => datetime_value
|
||||
)
|
||||
end
|
||||
|
||||
|
|
|
@ -6,8 +6,10 @@ describe 'Prefilling a dossier (with a POST request):' do
|
|||
|
||||
let(:type_de_champ_text) { create(:type_de_champ_text, procedure: procedure) }
|
||||
let(:type_de_champ_phone) { create(:type_de_champ_phone, procedure: procedure) }
|
||||
let(:type_de_champ_datetime) { create(:type_de_champ_datetime, procedure: procedure) }
|
||||
let(:text_value) { "My Neighbor Totoro is the best movie ever" }
|
||||
let(:phone_value) { "invalid phone value" }
|
||||
let(:datetime_value) { "2023-02-01T10:32" }
|
||||
|
||||
scenario "the user get the URL of a prefilled orphan brouillon dossier" do
|
||||
dossier_url = create_and_prefill_dossier_with_post_request
|
||||
|
@ -95,7 +97,8 @@ describe 'Prefilling a dossier (with a POST request):' do
|
|||
headers: { "Content-Type" => "application/json" },
|
||||
params: {
|
||||
"champ_#{type_de_champ_text.to_typed_id}" => text_value,
|
||||
"champ_#{type_de_champ_phone.to_typed_id}" => phone_value
|
||||
"champ_#{type_de_champ_phone.to_typed_id}" => phone_value,
|
||||
"champ_#{type_de_champ_datetime.to_typed_id}" => datetime_value
|
||||
}.to_json
|
||||
JSON.parse(session.response.body)["dossier_url"].gsub("http://www.example.com", "")
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue