From 156c4b5b56d36924a1eca87b581d95db1346abd2 Mon Sep 17 00:00:00 2001 From: kosiakkatrina <54268893+kosiakkatrina@users.noreply.github.com> Date: Tue, 21 Jan 2025 10:40:29 +0000 Subject: [PATCH] CLDC-3081 Update date input component (#2891) * Add moj-frontend * Use date picker component in log forms * Refactor date_picker into component, add date_picker to location startdate * Use date_picker for location deactivation periods * Use date_picker in scheme deactivations * Use date_picker for merge request date * Fix missed tests * lint * Refactor --- ...eck_answers_summary_list_card_component.rb | 6 +-- app/controllers/check_errors_controller.rb | 4 +- app/controllers/form_controller.rb | 54 +++++++++---------- app/controllers/locations_controller.rb | 12 ++--- app/controllers/merge_requests_controller.rb | 4 +- app/controllers/schemes_controller.rb | 6 +-- app/frontend/application.js | 5 ++ app/frontend/styles/application.scss | 1 + app/helpers/check_answers_helper.rb | 2 +- app/helpers/check_errors_helper.rb | 2 +- app/helpers/duplicate_logs_helper.rb | 8 +-- app/helpers/form_page_helper.rb | 6 +-- app/helpers/guidance_helper.rb | 2 +- app/helpers/tasklist_helper.rb | 4 +- app/models/form.rb | 2 +- .../form/lettings/pages/address_matcher.rb | 2 +- .../form/sales/pages/address_matcher.rb | 2 +- app/models/lettings_log.rb | 4 ++ app/models/sales_log.rb | 4 ++ .../confirm_clear_all_answers.html.erb | 2 +- .../confirm_clear_answer.html.erb | 2 +- app/views/components/_date_picker.html.erb | 25 +++++++++ .../duplicate_logs/_duplicate_log.html.erb | 2 +- app/views/form/_date_question.html.erb | 18 ++++--- app/views/form/check_errors.html.erb | 4 +- app/views/locations/availability.erb | 12 +++-- app/views/locations/toggle_active.html.erb | 15 ++++-- app/views/logs/delete_duplicates.html.erb | 4 +- app/views/merge_requests/merge_date.html.erb | 14 +++-- app/views/schemes/toggle_active.html.erb | 12 +++-- config/initializers/assets.rb | 1 + config/locales/en.yml | 2 +- package.json | 2 + spec/features/form/page_routing_spec.rb | 28 +++------- spec/features/form/validations_spec.rb | 4 +- spec/features/sales_log_spec.rb | 5 +- spec/features/schemes_helpers.rb | 8 +-- spec/features/schemes_spec.rb | 8 +-- spec/requests/form_controller_spec.rb | 32 +++-------- spec/requests/locations_controller_spec.rb | 46 ++++++++-------- .../merge_requests_controller_spec.rb | 8 +-- spec/requests/schemes_controller_spec.rb | 16 +++--- webpack.config.js | 6 ++- yarn.lock | 17 +++++- 44 files changed, 221 insertions(+), 202 deletions(-) create mode 100644 app/views/components/_date_picker.html.erb diff --git a/app/components/check_answers_summary_list_card_component.rb b/app/components/check_answers_summary_list_card_component.rb index c22b2eee0..e11f69068 100644 --- a/app/components/check_answers_summary_list_card_component.rb +++ b/app/components/check_answers_summary_list_card_component.rb @@ -31,16 +31,16 @@ class CheckAnswersSummaryListCardComponent < ViewComponent::Base def action_href(question, log) referrer = question.displayed_as_answered?(log) ? "check_answers" : "check_answers_new_answer" - send("#{log.model_name.param_key}_#{question.page.id}_path", log, referrer:) + send("#{log.log_type}_#{question.page.id}_path", log, referrer:) end def correct_validation_action_href(question, log, _related_question_ids, correcting_hard_validation) return action_href(question, log) unless correcting_hard_validation if question.displayed_as_answered?(log) - send("#{log.model_name.param_key}_confirm_clear_answer_path", log, question_id: question.id) + send("#{log.log_type}_confirm_clear_answer_path", log, question_id: question.id) else - send("#{log.model_name.param_key}_#{question.page.id}_path", log, referrer: "check_errors", related_question_ids: request.query_parameters["related_question_ids"], original_page_id: request.query_parameters["original_page_id"]) + send("#{log.log_type}_#{question.page.id}_path", log, referrer: "check_errors", related_question_ids: request.query_parameters["related_question_ids"], original_page_id: request.query_parameters["original_page_id"]) end end diff --git a/app/controllers/check_errors_controller.rb b/app/controllers/check_errors_controller.rb index f246e0b01..8d7f52e0a 100644 --- a/app/controllers/check_errors_controller.rb +++ b/app/controllers/check_errors_controller.rb @@ -7,8 +7,8 @@ class CheckErrorsController < ApplicationController def confirm_clear_answer return render_not_found unless @log - @related_question_ids = params[@log.model_name.param_key].keys.reject { |id| id == "page_id" } - @page = @log.form.get_page(params[@log.model_name.param_key]["page_id"]) + @related_question_ids = params[@log.log_type].keys.reject { |id| id == "page_id" } + @page = @log.form.get_page(params[@log.log_type]["page_id"]) if params["clear_all"] @questions_to_clear = @related_question_ids.map { |id| diff --git a/app/controllers/form_controller.rb b/app/controllers/form_controller.rb index 54988e71d..63c37918d 100644 --- a/app/controllers/form_controller.rb +++ b/app/controllers/form_controller.rb @@ -9,7 +9,7 @@ class FormController < ApplicationController def submit_form if @log - @page = form.get_page(params[@log.model_name.param_key][:page]) + @page = form.get_page(params[@log.log_type][:page]) return render_check_errors_page if params["check_errors"] shown_page_ids_with_unanswered_questions_before_update = @page.subsection.pages @@ -47,7 +47,7 @@ class FormController < ApplicationController flash[:log_data] = responses_for_page question_ids = (@log.errors.map(&:attribute) - [:base]).uniq flash[:pages_with_errors_count] = question_ids.map { |id| @log.form.get_question(id, @log)&.page&.id }.compact.uniq.count - redirect_to send("#{@log.class.name.underscore}_#{@page.id}_path", @log, { referrer: request.params["referrer"], original_page_id: request.params["original_page_id"], related_question_ids: request.params["related_question_ids"] }) + redirect_to send("#{@log.log_type}_#{@page.id}_path", @log, { referrer: request.params["referrer"], original_page_id: request.params["original_page_id"], related_question_ids: request.params["related_question_ids"] }) end else render_not_found @@ -136,11 +136,9 @@ private def responses_for_page(page) page.questions.each_with_object({}) do |question, result| - question_params = params[@log.model_name.param_key][question.id] + question_params = params[@log.log_type][question.id] if question.type == "date" - day = params[@log.model_name.param_key]["#{question.id}(3i)"] - month = params[@log.model_name.param_key]["#{question.id}(2i)"] - year = params[@log.model_name.param_key]["#{question.id}(1i)"] + day, month, year = params[@log.log_type][question.id].split("/") next unless [day, month, year].any?(&:present?) result[question.id] = if Date.valid_date?(year.to_i, month.to_i, day.to_i) && year.to_i.positive? @@ -160,7 +158,7 @@ private question.answer_keys_without_dividers.each do |option| result[option] = question_params.include?(option) ? 1 : 0 end - else + elsif question.type != "date" result[question.id] = question_params end @@ -215,11 +213,11 @@ private end def previous_interruption_screen_page_id - params[@log.model_name.param_key]["interruption_page_id"] + params[@log.log_type]["interruption_page_id"] end def previous_interruption_screen_referrer - params[@log.model_name.param_key]["interruption_page_referrer_type"].presence + params[@log.log_type]["interruption_page_referrer_type"].presence end def page_has_duplicate_check_question @@ -229,7 +227,7 @@ private def update_duplication_tracking return unless page_has_duplicate_check_question - class_name = @log.class.name.underscore + class_name = @log.log_type dynamic_duplicates = current_user.send(class_name.pluralize).duplicate_logs(@log) if dynamic_duplicates.any? @@ -245,7 +243,7 @@ private end def successful_redirect_path(pages_to_check) - class_name = @log.class.name.underscore + class_name = @log.log_type if is_referrer_type?("duplicate_logs") || is_referrer_type?("duplicate_logs_banner") original_log = current_user.send(class_name.pluralize).find_by(id: from_referrer_query("original_log_id")) @@ -262,7 +260,7 @@ private end unless @log.duplicate_set_id.nil? - return send("#{@log.class.name.underscore}_duplicate_logs_path", @log, original_log_id: @log.id) + return send("#{@log.log_type}_duplicate_logs_path", @log, original_log_id: @log.id) end if is_referrer_type?("check_answers") @@ -275,25 +273,25 @@ private elsif pages_to_check.any? return redirect_path_to_question(pages_to_check[0], pages_to_check) else - return send("#{@log.model_name.param_key}_#{form.subsection_for_page(@page).id}_check_answers_path", @log) + return send("#{@log.log_type}_#{form.subsection_for_page(@page).id}_check_answers_path", @log) end end if previous_interruption_screen_page_id.present? - return send("#{@log.class.name.underscore}_#{previous_interruption_screen_page_id}_path", @log, { referrer: previous_interruption_screen_referrer, original_log_id: original_duplicate_log_id_from_query }.compact) + return send("#{@log.log_type}_#{previous_interruption_screen_page_id}_path", @log, { referrer: previous_interruption_screen_referrer, original_log_id: original_duplicate_log_id_from_query }.compact) end - if params[@log.model_name.param_key]["check_errors"] - @page = form.get_page(params[@log.model_name.param_key]["page"]) + if params[@log.log_type]["check_errors"] + @page = form.get_page(params[@log.log_type]["page"]) flash[:notice] = "You have successfully updated #{@page.questions.map(&:check_answer_label).to_sentence}" - original_page_id = params[@log.model_name.param_key]["original_page_id"] - related_question_ids = params[@log.model_name.param_key]["related_question_ids"].split(" ") - return send("#{@log.class.name.underscore}_#{original_page_id}_path", @log, { check_errors: true, related_question_ids: }.compact) + original_page_id = params[@log.log_type]["original_page_id"] + related_question_ids = params[@log.log_type]["related_question_ids"].split(" ") + return send("#{@log.log_type}_#{original_page_id}_path", @log, { check_errors: true, related_question_ids: }.compact) end if params["referrer"] == "check_errors" - @page = form.get_page(params[@log.model_name.param_key]["page"]) + @page = form.get_page(params[@log.log_type]["page"]) flash[:notice] = "You have successfully updated #{@page.questions.map(&:check_answer_label).to_sentence}" - return send("#{@log.class.name.underscore}_#{params['original_page_id']}_path", @log, { check_errors: true, related_question_ids: params["related_question_ids"] }.compact) + return send("#{@log.log_type}_#{params['original_page_id']}_path", @log, { check_errors: true, related_question_ids: params["related_question_ids"] }.compact) end is_new_answer_from_check_answers = is_referrer_type?("check_answers_new_answer") @@ -306,7 +304,7 @@ private def redirect_path_to_question(page_to_show, unanswered_pages) remaining_pages = unanswered_pages.excluding(page_to_show) remaining_page_ids = remaining_pages.any? ? remaining_pages.map(&:id).join(",") : nil - send("#{@log.class.name.underscore}_#{page_to_show.id}_path", @log, { referrer: "check_answers", unanswered_pages: remaining_page_ids }) + send("#{@log.log_type}_#{page_to_show.id}_path", @log, { referrer: "check_answers", unanswered_pages: remaining_page_ids }) end def pages_requiring_update(previously_visible_empty_page_ids) @@ -350,8 +348,8 @@ private def question_missing_response?(responses_for_page, question) if %w[checkbox validation_override].include?(question.type) answered = question.answer_keys_without_dividers.map do |option| - session["fields"][option] = @log[option] = params[@log.model_name.param_key][question.id].include?(option) ? 1 : 0 - params[@log.model_name.param_key][question.id].exclude?(option) + session["fields"][option] = @log[option] = params[@log.log_type][question.id].include?(option) ? 1 : 0 + params[@log.log_type][question.id].exclude?(option) end answered.all? else @@ -371,7 +369,7 @@ private CONFIRMATION_PAGE_IDS = %w[uprn_confirmation uprn_selection].freeze def deduplication_success_banner - deduplicated_log_link = "Log #{@log.id}" + deduplicated_log_link = "Log #{@log.id}" changed_labels = { property_postcode: "postcode", lead_tenant_age: "lead tenant’s age", @@ -430,8 +428,8 @@ private end def render_check_errors_page - if params[@log.model_name.param_key]["clear_question_ids"].present? - question_ids = params[@log.model_name.param_key]["clear_question_ids"].split(" ") + if params[@log.log_type]["clear_question_ids"].present? + question_ids = params[@log.log_type]["clear_question_ids"].split(" ") question_ids.each do |question_id| question = @log.form.get_question(question_id, @log) next if question.subsection.id == "setup" @@ -440,7 +438,7 @@ private @log.previous_la_known = nil if question.id == "ppostcode_full" end @log.save! - @questions = params[@log.model_name.param_key].keys.reject { |id| %w[clear_question_ids page].include?(id) }.map { |id| @log.form.get_question(id, @log) } + @questions = params[@log.log_type].keys.reject { |id| %w[clear_question_ids page].include?(id) }.map { |id| @log.form.get_question(id, @log) } else responses_for_page = responses_for_page(@page) @log.assign_attributes(responses_for_page) diff --git a/app/controllers/locations_controller.rb b/app/controllers/locations_controller.rb index a90833945..b80d969a0 100644 --- a/app/controllers/locations_controller.rb +++ b/app/controllers/locations_controller.rb @@ -137,9 +137,7 @@ class LocationsController < ApplicationController def availability; end def update_availability - day = location_params["startdate(3i)"] - month = location_params["startdate(2i)"] - year = location_params["startdate(1i)"] + day, month, year = location_params["startdate"].split("/") @location.startdate = if [day, month, year].none?(&:blank?) && Date.valid_date?(year.to_i, month.to_i, day.to_i) Time.zone.local(year.to_i, month.to_i, day.to_i) end @@ -258,7 +256,7 @@ private end def location_params - required_params = params.require(:location).permit(:postcode, :location_admin_district, :location_code, :name, :units, :type_of_unit, :mobility_type, "startdate(1i)", "startdate(2i)", "startdate(3i)").merge(scheme_id: @scheme.id) + required_params = params.require(:location).permit(:postcode, :location_admin_district, :location_code, :name, :units, :type_of_unit, :mobility_type, :startdate).merge(scheme_id: @scheme.id) required_params[:postcode] = PostcodeService.clean(required_params[:postcode]) if required_params[:postcode] required_params[:location_admin_district] = nil if required_params[:location_admin_district] == "Select an option" required_params @@ -297,13 +295,9 @@ private return elsif params[:location_deactivation_period]["#{key}_type".to_sym] == "default" return FormHandler.instance.start_date_of_earliest_open_for_editing_collection_period - elsif params[:location_deactivation_period][key.to_sym].present? - return params[:location_deactivation_period][key.to_sym] end - day = params[:location_deactivation_period]["#{key}(3i)"] - month = params[:location_deactivation_period]["#{key}(2i)"] - year = params[:location_deactivation_period]["#{key}(1i)"] + day, month, year = params[:location_deactivation_period][key.to_s].split("/") return nil if [day, month, year].any?(&:blank?) Time.zone.local(year.to_i, month.to_i, day.to_i) if Date.valid_date?(year.to_i, month.to_i, day.to_i) diff --git a/app/controllers/merge_requests_controller.rb b/app/controllers/merge_requests_controller.rb index e38d1bdf0..bbb9c8ee9 100644 --- a/app/controllers/merge_requests_controller.rb +++ b/app/controllers/merge_requests_controller.rb @@ -137,9 +137,7 @@ private @merge_request.errors.add(:absorbing_organisation_id, :blank) end when "merge_date" - day = merge_request_params["merge_date(3i)"] - month = merge_request_params["merge_date(2i)"] - year = merge_request_params["merge_date(1i)"] + day, month, year = merge_request_params["merge_date"].split("/") return @merge_request.errors.add(:merge_date, :blank) if [day, month, year].all?(&:blank?) diff --git a/app/controllers/schemes_controller.rb b/app/controllers/schemes_controller.rb index a76c9db52..27504e9de 100644 --- a/app/controllers/schemes_controller.rb +++ b/app/controllers/schemes_controller.rb @@ -356,13 +356,9 @@ private return elsif params[:scheme_deactivation_period]["#{key}_type".to_sym] == "default" return FormHandler.instance.start_date_of_earliest_open_for_editing_collection_period - elsif params[:scheme_deactivation_period][key.to_sym].present? - return params[:scheme_deactivation_period][key.to_sym] end - day = params[:scheme_deactivation_period]["#{key}(3i)"] - month = params[:scheme_deactivation_period]["#{key}(2i)"] - year = params[:scheme_deactivation_period]["#{key}(1i)"] + day, month, year = params[:scheme_deactivation_period][key.to_s].split("/") return nil if [day, month, year].any?(&:blank?) Time.zone.local(year.to_i, month.to_i, day.to_i) if Date.valid_date?(year.to_i, month.to_i, day.to_i) diff --git a/app/frontend/application.js b/app/frontend/application.js index 45b6fd106..0b120c049 100644 --- a/app/frontend/application.js +++ b/app/frontend/application.js @@ -14,11 +14,16 @@ import 'regenerator-runtime/runtime' // import { initAll as GOVUKFrontend } from 'govuk-frontend' import { initAll as GOVUKPrototypeComponents } from '@x-govuk/govuk-prototype-components' +import { initAll as MOJFrontend } from '@ministryofjustice/frontend' import './controllers' import './cookie-banner' import './styles/application.scss' +import 'moj-frontend' +import $ from 'jquery' +window.$ = $ require.context('govuk-frontend/dist/govuk/assets') GOVUKFrontend() GOVUKPrototypeComponents() +MOJFrontend() diff --git a/app/frontend/styles/application.scss b/app/frontend/styles/application.scss index 9639ab57c..370592640 100644 --- a/app/frontend/styles/application.scss +++ b/app/frontend/styles/application.scss @@ -50,6 +50,7 @@ $govuk-breakpoints: ( @import "unread-notification"; @import "red-link"; @import "custom-rails-admin"; +@import "node_modules/@ministryofjustice/frontend/moj/components/date-picker/date-picker"; // App utilities .app-\!-colour-muted { diff --git a/app/helpers/check_answers_helper.rb b/app/helpers/check_answers_helper.rb index 2d15dc07d..0c304fe9f 100644 --- a/app/helpers/check_answers_helper.rb +++ b/app/helpers/check_answers_helper.rb @@ -26,7 +26,7 @@ module CheckAnswersHelper end def next_incomplete_section_path(log, redirect_path) - "#{log.class.name.underscore}_#{redirect_path.underscore.tr('/', '_')}_path" + "#{log.log_type}_#{redirect_path.underscore.tr('/', '_')}_path" end private diff --git a/app/helpers/check_errors_helper.rb b/app/helpers/check_errors_helper.rb index 6d1ff0166..3b3774566 100644 --- a/app/helpers/check_errors_helper.rb +++ b/app/helpers/check_errors_helper.rb @@ -6,6 +6,6 @@ module CheckErrorsHelper end def check_errors_answer_link(log, question, page, applicable_questions) - send("#{log.model_name.param_key}_#{question.page.id}_path", log, referrer: "check_errors", original_page_id: page.id, related_question_ids: applicable_questions.map(&:id)) + send("#{log.log_type}_#{question.page.id}_path", log, referrer: "check_errors", original_page_id: page.id, related_question_ids: applicable_questions.map(&:id)) end end diff --git a/app/helpers/duplicate_logs_helper.rb b/app/helpers/duplicate_logs_helper.rb index 9eb1b6289..077845857 100644 --- a/app/helpers/duplicate_logs_helper.rb +++ b/app/helpers/duplicate_logs_helper.rb @@ -7,7 +7,7 @@ module DuplicateLogsHelper return govuk_button_link_to "Keep this log and delete duplicates", url_for( controller: "duplicate_logs", action: "delete_duplicates", - "#{duplicate_log.class.name.underscore}_id": duplicate_log.id, + "#{duplicate_log.log_type}_id": duplicate_log.id, original_log_id: original_log.id, referrer: params[:referrer], organisation_id: params[:organisation_id], @@ -16,7 +16,7 @@ module DuplicateLogsHelper if params[:referrer] == "duplicate_logs_banner" current_user.support? ? govuk_button_link_to("Review other duplicates", organisation_duplicates_path(organisation_id: params[:organisation_id], referrer: params[:referrer])) : govuk_button_link_to("Review other duplicates", duplicate_logs_path(referrer: params[:referrer])) elsif !original_log.deleted? - govuk_button_link_to "Back to Log #{original_log.id}", send("#{original_log.class.name.underscore}_path", original_log) + govuk_button_link_to "Back to Log #{original_log.id}", send("#{original_log.log_type}_path", original_log) else type = duplicate_log.lettings? ? "lettings" : "sales" govuk_button_link_to "Back to #{type} logs", url_for(duplicate_log.class) @@ -24,12 +24,12 @@ module DuplicateLogsHelper end def duplicate_logs_action_href(log, page_id, original_log_id) - send("#{log.model_name.param_key}_#{page_id}_path", log, referrer: "interruption_screen", original_log_id:) + send("#{log.log_type}_#{page_id}_path", log, referrer: "interruption_screen", original_log_id:) end def change_duplicate_logs_action_href(log, page_id, all_duplicates, original_log_id) first_remaining_duplicate_id = all_duplicates.map(&:id).reject { |id| id == log.id }.first - send("#{log.model_name.param_key}_#{page_id}_path", log, referrer: params[:referrer] == "duplicate_logs_banner" ? "duplicate_logs_banner" : "duplicate_logs", first_remaining_duplicate_id:, original_log_id:, organisation_id: params[:organisation_id]) + send("#{log.log_type}_#{page_id}_path", log, referrer: params[:referrer] == "duplicate_logs_banner" ? "duplicate_logs_banner" : "duplicate_logs", first_remaining_duplicate_id:, original_log_id:, organisation_id: params[:organisation_id]) end def duplicates_for_user(user) diff --git a/app/helpers/form_page_helper.rb b/app/helpers/form_page_helper.rb index eeb682131..74e75e572 100644 --- a/app/helpers/form_page_helper.rb +++ b/app/helpers/form_page_helper.rb @@ -1,6 +1,6 @@ module FormPageHelper def action_href(log, page_id, referrer = "check_answers") - send("#{log.model_name.param_key}_#{page_id}_path", log, referrer:) + send("#{log.log_type}_#{page_id}_path", log, referrer:) end def returning_to_question_page?(page, referrer) @@ -12,11 +12,11 @@ module FormPageHelper end def duplicate_log_set_path(log, original_log_id) - send("#{log.class.name.underscore}_duplicate_logs_path", log, original_log_id:) + send("#{log.log_type}_duplicate_logs_path", log, original_log_id:) end def relevant_check_answers_path(log, subsection) - send("#{log.class.name.underscore}_#{subsection.id}_check_answers_path", log) + send("#{log.log_type}_#{subsection.id}_check_answers_path", log) end def submit_button_text(page, referrer) diff --git a/app/helpers/guidance_helper.rb b/app/helpers/guidance_helper.rb index 00d699cd2..236931e1f 100644 --- a/app/helpers/guidance_helper.rb +++ b/app/helpers/guidance_helper.rb @@ -6,6 +6,6 @@ module GuidanceHelper question = log.form.get_question(question_id, log) return "" unless question.page.routed_to?(log, user) - "(#{govuk_link_to "Q#{question.question_number}", send("#{log.class.name.underscore}_#{question.page.id}_path", log)})".html_safe + "(#{govuk_link_to "Q#{question.question_number}", send("#{log.log_type}_#{question.page.id}_path", log)})".html_safe end end diff --git a/app/helpers/tasklist_helper.rb b/app/helpers/tasklist_helper.rb index 3a07a00f3..ff52f4094 100644 --- a/app/helpers/tasklist_helper.rb +++ b/app/helpers/tasklist_helper.rb @@ -78,9 +78,9 @@ private def next_page_or_check_answers(subsection, log, current_user) path = if subsection.is_started?(log) - "#{log.class.name.underscore}_#{subsection.id}_check_answers_path" + "#{log.log_type}_#{subsection.id}_check_answers_path" else - "#{log.class.name.underscore}_#{next_question_page(subsection, log, current_user)}_path" + "#{log.log_type}_#{next_question_page(subsection, log, current_user)}_path" end send(path, log) diff --git a/app/models/form.rb b/app/models/form.rb index ce77378ca..a6558efab 100644 --- a/app/models/form.rb +++ b/app/models/form.rb @@ -135,7 +135,7 @@ class Form end def cancel_path(page, log) - "#{log.class.name.underscore}_#{page.subsection.id}_check_answers_path" + "#{log.log_type}_#{page.subsection.id}_check_answers_path" end def unresolved_log_path diff --git a/app/models/form/lettings/pages/address_matcher.rb b/app/models/form/lettings/pages/address_matcher.rb index b1fc885be..aab5d94cd 100644 --- a/app/models/form/lettings/pages/address_matcher.rb +++ b/app/models/form/lettings/pages/address_matcher.rb @@ -24,6 +24,6 @@ class Form::Lettings::Pages::AddressMatcher < ::Form::Page def skip_href(log = nil) return unless log - "/#{log.model_name.param_key.dasherize}s/#{log.id}/property-unit-type" + "/#{log.log_type.dasherize}s/#{log.id}/property-unit-type" end end diff --git a/app/models/form/sales/pages/address_matcher.rb b/app/models/form/sales/pages/address_matcher.rb index 23b8c5c86..fd7e95499 100644 --- a/app/models/form/sales/pages/address_matcher.rb +++ b/app/models/form/sales/pages/address_matcher.rb @@ -24,6 +24,6 @@ class Form::Sales::Pages::AddressMatcher < ::Form::Page def skip_href(log = nil) return unless log - "/#{log.model_name.param_key.dasherize}s/#{log.id}/property-number-of-bedrooms" + "/#{log.log_type.dasherize}s/#{log.id}/property-number-of-bedrooms" end end diff --git a/app/models/lettings_log.rb b/app/models/lettings_log.rb index c8505b310..945d8bded 100644 --- a/app/models/lettings_log.rb +++ b/app/models/lettings_log.rb @@ -735,6 +735,10 @@ class LettingsLog < Log scheme_locations_count > 19 end + def log_type + "lettings_log" + end + private def reset_invalid_unresolved_log_fields! diff --git a/app/models/sales_log.rb b/app/models/sales_log.rb index 49ba9f81c..e4da10593 100644 --- a/app/models/sales_log.rb +++ b/app/models/sales_log.rb @@ -538,4 +538,8 @@ class SalesLog < Log def is_firststair? firststair == 1 end + + def log_type + "sales_log" + end end diff --git a/app/views/check_errors/confirm_clear_all_answers.html.erb b/app/views/check_errors/confirm_clear_all_answers.html.erb index 85e936aef..4614e81b2 100644 --- a/app/views/check_errors/confirm_clear_all_answers.html.erb +++ b/app/views/check_errors/confirm_clear_all_answers.html.erb @@ -10,7 +10,7 @@

You've selected <%= @questions_to_clear.count %> answers to clear

<%= govuk_warning_text(text: "Dependent answers related to this question may also get cleared. You will not be able to undo this action") %> - <%= form_with model: @log, url: send("#{@log.model_name.param_key}_#{@page.id}_path", @log), method: "post", local: true do |f| %> + <%= form_with model: @log, url: send("#{@log.log_type}_#{@page.id}_path", @log), method: "post", local: true do |f| %> <% @related_question_ids.each do |id| %> <%= f.hidden_field id, value: @log[id] %> diff --git a/app/views/check_errors/confirm_clear_answer.html.erb b/app/views/check_errors/confirm_clear_answer.html.erb index 9dba77fae..aa73adac6 100644 --- a/app/views/check_errors/confirm_clear_answer.html.erb +++ b/app/views/check_errors/confirm_clear_answer.html.erb @@ -9,7 +9,7 @@ <%= govuk_warning_text(text: "Dependent answers related to this question may also get cleared. You will not be able to undo this action.") %> - <%= form_with model: @log, url: send("#{@log.model_name.param_key}_#{@page.id}_path", @log), method: "post", local: true do |f| %> + <%= form_with model: @log, url: send("#{@log.log_type}_#{@page.id}_path", @log), method: "post", local: true do |f| %> <% @related_question_ids.each do |id| %> <%= f.hidden_field id, value: @log[id] %> diff --git a/app/views/components/_date_picker.html.erb b/app/views/components/_date_picker.html.erb new file mode 100644 index 000000000..f7fd59f5a --- /dev/null +++ b/app/views/components/_date_picker.html.erb @@ -0,0 +1,25 @@ +
+ <% question_has_errors = resource.errors[question_id].any? %> +
"> + <% if legend.present? %> + +

+ + <%= legend[:caption][:text] if legend[:caption].present? %> + + <%= legend[:text] %> +

+
+ <% end %> + +
"> + <%= hint %> +
+ <% if question_has_errors %> +

"> + Error: <%= resource.errors[question_id].first %> +

+ <% end %> + <%= f.text_field question_id.to_sym, class: "govuk-input moj-js-datepicker-input#{' govuk-input--error' if question_has_errors}", id: [resource_type, question_id].join("_"), aria: { describedby: "#{[resource_type, question_id].join('_')}-hint#{"#{[resource_type, question_id].join('_')} -error" if question_has_errors}" }, autocomplete: "off", value: resource[question_id]&.strftime("%d/%m/%Y") %> +
+
diff --git a/app/views/duplicate_logs/_duplicate_log.html.erb b/app/views/duplicate_logs/_duplicate_log.html.erb index 767753947..9d321f2db 100644 --- a/app/views/duplicate_logs/_duplicate_log.html.erb +++ b/app/views/duplicate_logs/_duplicate_log.html.erb @@ -4,7 +4,7 @@

- <%= govuk_link_to "Log #{log.id}", send("#{log.class.name.underscore}_path", log) %> + <%= govuk_link_to "Log #{log.id}", send("#{log.log_type}_path", log) %>

diff --git a/app/views/form/_date_question.html.erb b/app/views/form/_date_question.html.erb index aded6f3b3..55193b01a 100644 --- a/app/views/form/_date_question.html.erb +++ b/app/views/form/_date_question.html.erb @@ -1,12 +1,14 @@ <%= render partial: "form/guidance/#{question.top_guidance_partial}" if question.top_guidance? %> +<%= render partial: "components/date_picker", locals: + { + resource: @log, + question_id: question.id, + legend: { text: legend(question, page_header, conditional)[:text], size: "l", caption: caption(caption_text, page_header, conditional) }, + resource_type: @log.log_type, + hint: (question.hint_text.blank? ? "" : (question.hint_text.html_safe + "

".html_safe)) + "For example, #{date_mid_collection_year_formatted(@log.startdate).tr(' ', '/')}", + f:, + } %> -<%= f.govuk_date_field question.id.to_sym, - caption: caption(caption_text, page_header, conditional), - legend: legend(question, page_header, conditional), - hint: { text: (question.hint_text.blank? ? "" : (question.hint_text.html_safe + "

".html_safe)) + "For example, #{date_mid_collection_year_formatted(@log.startdate)}" }, - width: 20, - **stimulus_html_attributes(question) do %> - <%= govuk_inset_text(text: question.unresolved_hint_text) if question.unresolved_hint_text.present? && @log.unresolved %> -<% end %> +<%= govuk_inset_text(text: question.unresolved_hint_text) if question.unresolved_hint_text.present? && @log.unresolved %> <%= render partial: "form/guidance/#{question.bottom_guidance_partial}" if question.bottom_guidance? %> diff --git a/app/views/form/check_errors.html.erb b/app/views/form/check_errors.html.erb index bab4858a5..df297b891 100644 --- a/app/views/form/check_errors.html.erb +++ b/app/views/form/check_errors.html.erb @@ -1,7 +1,7 @@
- <%= form_with model: @log, url: send("#{@log.model_name.param_key}_confirm_clear_answer_path", @log), method: "post", local: true do |f| %> + <%= form_with model: @log, url: send("#{@log.log_type}_confirm_clear_answer_path", @log), method: "post", local: true do |f| %> <% remove_duplicate_page_errors(@log) %> <%= f.govuk_error_summary %> <%= f.hidden_field :page_id, value: @page.id %> @@ -62,6 +62,6 @@
<% end %> - <%= govuk_button_link_to "Confirm and continue", @original_page_id ? send("#{@log.model_name.param_key}_#{@original_page_id}_path", @log) : send("#{@log.model_name.param_key}_#{@page.id}_path", @log) %> + <%= govuk_button_link_to "Confirm and continue", @original_page_id ? send("#{@log.log_type}_#{@original_page_id}_path", @log) : send("#{@log.log_type}_#{@page.id}_path", @log) %>
diff --git a/app/views/locations/availability.erb b/app/views/locations/availability.erb index 8a00ddc89..9c6aca26d 100644 --- a/app/views/locations/availability.erb +++ b/app/views/locations/availability.erb @@ -12,11 +12,13 @@ <%= f.govuk_error_summary %> <%= render partial: "organisations/headings", locals: { main: I18n.t("questions.location.startdate"), sub: "Add a location to #{@scheme.service_name}" } %> - - <%= f.govuk_date_field :startdate, - hint: { text: I18n.t("hints.location.startdate") }, - legend: nil, - width: 20 %> + <%= render partial: "components/date_picker", locals: { + resource: @location, + question_id: "startdate", + legend: nil, + resource_type: "location", + hint: I18n.t("hints.location.startdate"), + f: } %>
<% if params[:referrer] == "check_answers" %> diff --git a/app/views/locations/toggle_active.html.erb b/app/views/locations/toggle_active.html.erb index 138f04fae..d2dc637a8 100644 --- a/app/views/locations/toggle_active.html.erb +++ b/app/views/locations/toggle_active.html.erb @@ -25,11 +25,16 @@ "other", label: { text: "For tenancies starting after a certain date" }, **basic_conditional_html_attributes({ "deactivation_date" => %w[other] }, "location") do %> - <%= f.govuk_date_field date_question(action), - legend: { text: "Date", size: "m" }, - hint: { text: "For example, 27 3 2022" }, - width: 20 %> - <% end %> + <%= render partial: "components/date_picker", locals: { + resource: @location, + question_id: date_question(action), + legend: { text: "Date", size: "m" }, + resource_type: "location", + hint: "For example, 27/3/2024", + f:, +} %> + <% end %> + <% end %> <%= f.govuk_submit "Continue" %> diff --git a/app/views/logs/delete_duplicates.html.erb b/app/views/logs/delete_duplicates.html.erb index 2c9acd523..f68aef030 100644 --- a/app/views/logs/delete_duplicates.html.erb +++ b/app/views/logs/delete_duplicates.html.erb @@ -19,12 +19,12 @@
<%= govuk_button_to @duplicate_logs.count == 1 ? "Delete this log" : "Delete these logs", - send("delete_logs_#{@log.class.name.underscore}s_path"), + send("delete_logs_#{@log.log_type}s_path"), method: "delete", params: { ids: @duplicate_logs.map(&:id), original_log_id: @original_log.id, remaining_log_id: @log.id, referrer: params[:referrer], organisation_id: params[:organisation_id] } %> <%= govuk_button_link_to( "Cancel", - send("#{@log.class.name.underscore}_duplicate_logs_path", @original_log, original_log_id: @original_log.id, referrer: params[:referrer], organisation_id: params[:organisation_id]), + send("#{@log.log_type}_duplicate_logs_path", @original_log, original_log_id: @original_log.id, referrer: params[:referrer], organisation_id: params[:organisation_id]), secondary: true, ) %>
diff --git a/app/views/merge_requests/merge_date.html.erb b/app/views/merge_requests/merge_date.html.erb index 637426446..c4f893892 100644 --- a/app/views/merge_requests/merge_date.html.erb +++ b/app/views/merge_requests/merge_date.html.erb @@ -11,11 +11,15 @@

What is the merge date?

Enter the official merge date. Log and organisation page data will show the new organisation name from this date.

- For example, <%= date_mid_collection_year_formatted(Time.zone.now) %>

- <%= f.govuk_date_field :merge_date, - legend: { hidden: true }, - width: 20 do %> - <% end %> + For example, <%= date_mid_collection_year_formatted(Time.zone.now).tr(" ", "/") %>

+ <%= render partial: "components/date_picker", locals: { + resource: @merge_request, + question_id: "merge_date", + legend: nil, + resource_type: "merge_request", + hint: "", + f:, + } %> <%= f.hidden_field :page, value: "merge_date" %>
<%= f.govuk_submit submit_merge_request_button_text(request.query_parameters["referrer"]) %> diff --git a/app/views/schemes/toggle_active.html.erb b/app/views/schemes/toggle_active.html.erb index 3e2f1d4a8..2a376fbbe 100644 --- a/app/views/schemes/toggle_active.html.erb +++ b/app/views/schemes/toggle_active.html.erb @@ -25,10 +25,14 @@ "other", label: { text: "For tenancies starting after a certain date" }, **basic_conditional_html_attributes({ "deactivation_date" => %w[other] }, "scheme") do %> - <%= f.govuk_date_field date_question(action), - legend: { text: "Date", size: "m" }, - hint: { text: "For example, 27 3 2025" }, - width: 20 %> + <%= render partial: "components/date_picker", locals: { + resource: @scheme, + question_id: date_question(action), + legend: { text: "Date", size: "m" }, + resource_type: "scheme", + hint: "For example, 27/3/2025", + f:, + } %> <% end %> <% end %> <%= f.govuk_submit "Continue" %> diff --git a/config/initializers/assets.rb b/config/initializers/assets.rb index 4dd81fc6a..5b9b29091 100644 --- a/config/initializers/assets.rb +++ b/config/initializers/assets.rb @@ -5,5 +5,6 @@ Rails.application.config.assets.version = "1.0" # Add additional assets to the asset load path. Rails.application.config.assets.paths << Rails.root.join("node_modules/@fortawesome/fontawesome-free/webfonts") +Rails.application.config.assets.paths << Rails.root.join("/node_modules/@ministryofjustice/frontend/moj/assets") Rails.application.config.assets.precompile += %w[rails_admin/rails_admin.css rails_admin/rails_admin.js] diff --git a/config/locales/en.yml b/config/locales/en.yml index 97a6a4bff..155814574 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -413,7 +413,7 @@ en: name: "This is how you refer to this location within your organisation." units: "A unit is the space being let. For example, the property might be a block of flats and the unit would be the specific flat being let. A unit can also be a bedroom in a shared house or flat. Do not include spaces used for staff." toggle_active: "If the date is before %{date}, select ‘From the start of the open collection period’ because the previous period has now closed." - startdate: "For example, 27 3 2021." + startdate: "For example, 27/3/2024." scheme: toggle_active: "If the date is before %{date}, select ‘From the start of the open collection period’ because the previous period has now closed." bulk_upload: diff --git a/package.json b/package.json index 5e32d4f11..65f5b5335 100644 --- a/package.json +++ b/package.json @@ -9,6 +9,7 @@ "@babel/plugin-transform-runtime": "^7.17.0", "@babel/preset-env": "^7.16.11", "@hotwired/stimulus": "^3.0.0", + "@ministryofjustice/frontend": "^3.3.0", "@stimulus/polyfills": "^2.0.0", "@webcomponents/webcomponentsjs": "^2.6.0", "@x-govuk/govuk-prototype-components": "^3.0.9", @@ -23,6 +24,7 @@ "govuk-frontend": "5.7.1", "html5shiv": "^3.7.3", "intersection-observer": "^0.12.0", + "jquery": "^3.7.1", "mini-css-extract-plugin": "^2.6.0", "rails_admin": "3.3.0", "regenerator-runtime": "^0.13.9", diff --git a/spec/features/form/page_routing_spec.rb b/spec/features/form/page_routing_spec.rb index 118b52543..72505d688 100644 --- a/spec/features/form/page_routing_spec.rb +++ b/spec/features/form/page_routing_spec.rb @@ -95,50 +95,36 @@ RSpec.describe "Form Page Routing" do it "does not reset the displayed date if it's an invalid date" do lettings_log.update!(startdate: "2021/10/13") visit("/lettings-logs/#{id}/tenancy-start-date") - fill_in("lettings_log[startdate(1i)]", with: "202") - fill_in("lettings_log[startdate(2i)]", with: "32") - fill_in("lettings_log[startdate(3i)]", with: "0") + fill_in("lettings_log[startdate]", with: "0/32/202") click_button("Save and continue") expect(page).to have_current_path("/lettings-logs/#{id}/tenancy-start-date") - expect(find_field("lettings_log[startdate(3i)]").value).to eq("13") - expect(find_field("lettings_log[startdate(2i)]").value).to eq("10") - expect(find_field("lettings_log[startdate(1i)]").value).to eq("2021") + expect(find_field("lettings_log[startdate]").value).to eq("13/10/2021") end it "displays the entered date if it's in a valid format" do lettings_log.update!(startdate: "2021/10/13") visit("/lettings-logs/#{id}/tenancy-start-date") - fill_in("lettings_log[startdate(1i)]", with: "202") - fill_in("lettings_log[startdate(2i)]", with: "12") - fill_in("lettings_log[startdate(3i)]", with: "1") + fill_in("lettings_log[startdate]", with: "1/12/202") click_button("Save and continue") expect(page).to have_current_path("/lettings-logs/#{id}/tenancy-start-date") - expect(find_field("lettings_log[startdate(3i)]").value).to eq("1") - expect(find_field("lettings_log[startdate(2i)]").value).to eq("12") - expect(find_field("lettings_log[startdate(1i)]").value).to eq("202") + expect(find_field("lettings_log[startdate]").value).to eq("01/12/0202") end it "does not reset the displayed date if it's empty" do lettings_log.update!(startdate: nil) visit("/lettings-logs/#{id}/tenancy-start-date") - fill_in("lettings_log[startdate(1i)]", with: "202") - fill_in("lettings_log[startdate(2i)]", with: "32") - fill_in("lettings_log[startdate(3i)]", with: "0") + fill_in("lettings_log[startdate]", with: "0/32/202") click_button("Save and continue") expect(page).to have_current_path("/lettings-logs/#{id}/tenancy-start-date") - expect(find_field("lettings_log[startdate(3i)]").value).to eq(nil) - expect(find_field("lettings_log[startdate(2i)]").value).to eq(nil) - expect(find_field("lettings_log[startdate(1i)]").value).to eq(nil) + expect(find_field("lettings_log[startdate]").value).to eq(nil) end it "does not show see all related answers link if only 1 field has an error" do visit("/lettings-logs/#{id}/tenancy-start-date") - fill_in("lettings_log[startdate(1i)]", with: "202") - fill_in("lettings_log[startdate(2i)]", with: "32") - fill_in("lettings_log[startdate(3i)]", with: "0") + fill_in("lettings_log[startdate]", with: "0/32/202") click_button("Save and continue") expect(page).not_to have_link("See all related answers") diff --git a/spec/features/form/validations_spec.rb b/spec/features/form/validations_spec.rb index 62b0c6b81..96875d219 100644 --- a/spec/features/form/validations_spec.rb +++ b/spec/features/form/validations_spec.rb @@ -63,9 +63,7 @@ RSpec.describe "validations" do describe "date validation", js: true do def fill_in_date(lettings_log_id, question, day, month, year, path) visit("/lettings-logs/#{lettings_log_id}/#{path}") - fill_in("lettings_log[#{question}(1i)]", with: year) - fill_in("lettings_log[#{question}(2i)]", with: month) - fill_in("lettings_log[#{question}(3i)]", with: day) + fill_in("lettings_log[#{question}]", with: [day, month, year].join("/")) end it "does not allow out of range dates to be submitted" do diff --git a/spec/features/sales_log_spec.rb b/spec/features/sales_log_spec.rb index c226c6bd3..b94ecd464 100644 --- a/spec/features/sales_log_spec.rb +++ b/spec/features/sales_log_spec.rb @@ -34,9 +34,8 @@ RSpec.describe "Sales Log Features" do it "includes the purchaser code and sale completion date questions" do click_button "Create a new sales log" click_link "Set up this sales log" - fill_in("sales_log[saledate(1i)]", with: Time.zone.today.year) - fill_in("sales_log[saledate(2i)]", with: Time.zone.today.month) - fill_in("sales_log[saledate(3i)]", with: Time.zone.today.day) + date = Time.zone.today.strftime("%d/%m/%Y") + fill_in("sales_log[saledate]", with: date) click_button "Save and continue" fill_in "sales_log[purchid]", with: "PC123" click_button "Save and continue" diff --git a/spec/features/schemes_helpers.rb b/spec/features/schemes_helpers.rb index 685c0203e..fc80e08ee 100644 --- a/spec/features/schemes_helpers.rb +++ b/spec/features/schemes_helpers.rb @@ -74,9 +74,7 @@ module SchemesHelpers click_button "Save and continue" choose "location-mobility-type-none-field" click_button "Save and continue" - fill_in "Day", with: 2 - fill_in "Month", with: 5 - fill_in "Year", with: 2023 + fill_in "location_startdate", with: "2/5/2023" click_button "Save and continue" end @@ -95,9 +93,7 @@ module SchemesHelpers click_button "Save and continue" choose "location-mobility-type-none-field" click_button "Save and continue" - fill_in "Day", with: 2 - fill_in "Month", with: 5 - fill_in "Year", with: 2023 + fill_in "location_startdate", with: "2/5/2023" click_button "Save and continue" end diff --git a/spec/features/schemes_spec.rb b/spec/features/schemes_spec.rb index dff650eb7..91ee69738 100644 --- a/spec/features/schemes_spec.rb +++ b/spec/features/schemes_spec.rb @@ -368,9 +368,7 @@ RSpec.describe "Schemes scheme Features" do click_button "Save and continue" choose "location-mobility-type-none-field" click_button "Save and continue" - fill_in "Day", with: 2 - fill_in "Month", with: 2 - fill_in "Year", with: 2022 + fill_in "location_startdate", with: "2/2/2022" click_button "Save and continue" end @@ -989,9 +987,7 @@ RSpec.describe "Schemes scheme Features" do click_button "Save and continue" choose "location-mobility-type-none-field" click_button "Save and continue" - fill_in "Day", with: 2 - fill_in "Month", with: 2 - fill_in "Year", with: 2022 + fill_in "location_startdate", with: "2/2/2022" click_button "Save and continue" end diff --git a/spec/requests/form_controller_spec.rb b/spec/requests/form_controller_spec.rb index 3ee34c517..497f65ca0 100644 --- a/spec/requests/form_controller_spec.rb +++ b/spec/requests/form_controller_spec.rb @@ -329,9 +329,7 @@ RSpec.describe FormController, type: :request do id: sales_log.id, sales_log: { page: "completion_date", - "saledate(3i)" => 30, - "saledate(2i)" => 6, - "saledate(1i)" => 2023, + "saledate" => "30/6/2023", }, } end @@ -609,9 +607,7 @@ RSpec.describe FormController, type: :request do id: lettings_log.id, lettings_log: { page: page_id, - "startdate(3i)" => 31, - "startdate(2i)" => 6, - "startdate(1i)" => 2022, + "startdate" => "31/6/2022", }, } end @@ -635,9 +631,7 @@ RSpec.describe FormController, type: :request do id: lettings_log.id, lettings_log: { page: page_id, - "startdate(3i)" => 1, - "startdate(2i)" => 1, - "startdate(1i)" => 1, + "startdate" => "1/1/1", }, } end @@ -658,9 +652,7 @@ RSpec.describe FormController, type: :request do id: sales_log.id, sales_log: { page: page_id, - "saledate(3i)" => 1, - "saledate(2i)" => 1, - "saledate(1i)" => 1, + "saledate" => "1/1/1", }, } end @@ -687,9 +679,7 @@ RSpec.describe FormController, type: :request do id: lettings_log.id, lettings_log: { page: page_id, - "startdate(3i)" => 1, - "startdate(2i)" => 1, - "startdate(1i)" => 1, + "startdate" => "1/1/1", }, } end @@ -708,9 +698,7 @@ RSpec.describe FormController, type: :request do id: sales_log.id, sales_log: { page: page_id, - "saledate(3i)" => 1, - "saledate(2i)" => 1, - "saledate(1i)" => 1, + "saledate" => "1/1/1", }, } end @@ -1326,9 +1314,7 @@ RSpec.describe FormController, type: :request do id: sales_log.id, sales_log: { page: "completion_date", - "saledate(3i)" => 30, - "saledate(2i)" => 6, - "saledate(1i)" => 2023, + "saledate" => "30/6/2023", }, } end @@ -1364,9 +1350,7 @@ RSpec.describe FormController, type: :request do id: sales_log.id, sales_log: { page: "completion_date", - "saledate(3i)" => 30, - "saledate(2i)" => 6, - "saledate(1i)" => 2024, + "saledate" => "30/06/2024", }, } end diff --git a/spec/requests/locations_controller_spec.rb b/spec/requests/locations_controller_spec.rb index 9afdc94f2..e8024bf76 100644 --- a/spec/requests/locations_controller_spec.rb +++ b/spec/requests/locations_controller_spec.rb @@ -1151,7 +1151,7 @@ RSpec.describe LocationsController, type: :request do end context "when startdate is submitted" do - let(:params) { { location: { "startdate(1i)": "2022", "startdate(2i)": "1", "startdate(3i)": "2" } } } + let(:params) { { location: { "startdate": "2/1/2022" } } } before do patch "/schemes/#{scheme.id}/locations/#{location.id}/availability", params: @@ -1168,7 +1168,7 @@ RSpec.describe LocationsController, type: :request do end context "when startdate is submitted with leading zeroes" do - let(:params) { { location: { "startdate(1i)": "2022", "startdate(2i)": "01", "startdate(3i)": "02" } } } + let(:params) { { location: { "startdate": "02/01/2022" } } } before do patch "/schemes/#{scheme.id}/locations/#{location.id}/availability", params: @@ -1185,7 +1185,7 @@ RSpec.describe LocationsController, type: :request do end context "when startdate is missing" do - let(:params) { { location: { "startdate(1i)": "", "startdate(2i)": "", "startdate(3i)": "" } } } + let(:params) { { location: { "startdate": "" } } } before do patch "/schemes/#{scheme.id}/locations/#{location.id}/availability", params: @@ -1225,7 +1225,7 @@ RSpec.describe LocationsController, type: :request do end context "when startdate is submitted" do - let(:params) { { location: { "startdate(1i)": "2022", "startdate(2i)": "1", "startdate(3i)": "2" } } } + let(:params) { { location: { "startdate": "2/1/2022" } } } before do patch "/schemes/#{scheme.id}/locations/#{location.id}/availability", params: @@ -1242,7 +1242,7 @@ RSpec.describe LocationsController, type: :request do end context "when startdate is submitted with leading zeroes" do - let(:params) { { location: { "startdate(1i)": "2022", "startdate(2i)": "01", "startdate(3i)": "02" } } } + let(:params) { { location: { "startdate": "02/01/2022" } } } before do patch "/schemes/#{scheme.id}/locations/#{location.id}/availability", params: @@ -1259,7 +1259,7 @@ RSpec.describe LocationsController, type: :request do end context "when startdate is missing" do - let(:params) { { location: { "startdate(1i)": "", "startdate(2i)": "", "startdate(3i)": "" } } } + let(:params) { { location: { "startdate": "" } } } before do patch "/schemes/#{scheme.id}/locations/#{location.id}/availability", params: @@ -1548,7 +1548,7 @@ RSpec.describe LocationsController, type: :request do end context "with other date" do - let(:params) { { location_deactivation_period: { deactivation_date_type: "other", "deactivation_date(3i)": "10", "deactivation_date(2i)": "10", "deactivation_date(1i)": "2022" } } } + let(:params) { { location_deactivation_period: { deactivation_date_type: "other", "deactivation_date": "10/10/2022" } } } context "and affected logs" do it "redirects to the confirmation page" do @@ -1708,7 +1708,7 @@ RSpec.describe LocationsController, type: :request do end context "when invalid date is entered" do - let(:params) { { location_deactivation_period: { deactivation_date_type: "other", "deactivation_date(3i)": "10", "deactivation_date(2i)": "44", "deactivation_date(1i)": "2022" } } } + let(:params) { { location_deactivation_period: { deactivation_date_type: "other", "deactivation_date": "10/44/2022" } } } it "displays the new page with an error message" do expect(response).to have_http_status(:unprocessable_content) @@ -1717,7 +1717,7 @@ RSpec.describe LocationsController, type: :request do end context "when the date entered is before the beginning of current collection window" do - let(:params) { { location_deactivation_period: { deactivation_date_type: "other", "deactivation_date(3i)": "10", "deactivation_date(2i)": "4", "deactivation_date(1i)": "2020" } } } + let(:params) { { location_deactivation_period: { deactivation_date_type: "other", "deactivation_date": "10/4/2020" } } } it "displays the new page with an error message" do expect(response).to have_http_status(:unprocessable_content) @@ -1726,7 +1726,7 @@ RSpec.describe LocationsController, type: :request do end context "when the day is not entered" do - let(:params) { { location_deactivation_period: { deactivation_date_type: "other", "deactivation_date(3i)": "", "deactivation_date(2i)": "2", "deactivation_date(1i)": "2022" } } } + let(:params) { { location_deactivation_period: { deactivation_date_type: "other", "deactivation_date": "/2/2022" } } } it "displays page with an error message" do expect(response).to have_http_status(:unprocessable_content) @@ -1735,7 +1735,7 @@ RSpec.describe LocationsController, type: :request do end context "when the month is not entered" do - let(:params) { { location_deactivation_period: { deactivation_date_type: "other", "deactivation_date(3i)": "2", "deactivation_date(2i)": "", "deactivation_date(1i)": "2022" } } } + let(:params) { { location_deactivation_period: { deactivation_date_type: "other", "deactivation_date": "2//2022" } } } it "displays page with an error message" do expect(response).to have_http_status(:unprocessable_content) @@ -1744,7 +1744,7 @@ RSpec.describe LocationsController, type: :request do end context "when the year is not entered" do - let(:params) { { location_deactivation_period: { deactivation_date_type: "other", "deactivation_date(3i)": "2", "deactivation_date(2i)": "2", "deactivation_date(1i)": "" } } } + let(:params) { { location_deactivation_period: { deactivation_date_type: "other", "deactivation_date": "2/2/" } } } it "displays page with an error message" do expect(response).to have_http_status(:unprocessable_content) @@ -1754,7 +1754,7 @@ RSpec.describe LocationsController, type: :request do context "when deactivation date is during a deactivated period" do let(:deactivation_date) { Time.zone.local(2022, 10, 10) } - let(:params) { { location_deactivation_period: { deactivation_date_type: "other", "deactivation_date(3i)": "8", "deactivation_date(2i)": "9", "deactivation_date(1i)": "2022" } } } + let(:params) { { location_deactivation_period: { deactivation_date_type: "other", "deactivation_date": "8/9/2022" } } } let(:add_deactivations) { create(:location_deactivation_period, deactivation_date: Time.zone.local(2022, 5, 5), reactivation_date: Time.zone.local(2022, 10, 12), location:) } it "displays page with an error message" do @@ -1765,7 +1765,7 @@ RSpec.describe LocationsController, type: :request do context "when there is an earlier open deactivation" do let(:deactivation_date) { Time.zone.local(2023, 10, 10) } - let(:params) { { location_deactivation_period: { deactivation_date_type: "other", "deactivation_date(3i)": "8", "deactivation_date(2i)": "9", "deactivation_date(1i)": "2024" } } } + let(:params) { { location_deactivation_period: { deactivation_date_type: "other", "deactivation_date": "8/9/2024" } } } let(:add_deactivations) { create(:location_deactivation_period, deactivation_date: Time.zone.local(2024, 6, 5), reactivation_date: nil, location:) } it "redirects to the location page and updates the existing deactivation period" do @@ -1780,7 +1780,7 @@ RSpec.describe LocationsController, type: :request do end context "when there is a later open deactivation" do - let(:params) { { location_deactivation_period: { deactivation_date_type: "other", "deactivation_date(3i)": "8", "deactivation_date(2i)": "9", "deactivation_date(1i)": "2022" } } } + let(:params) { { location_deactivation_period: { deactivation_date_type: "other", "deactivation_date": "8/9/2022" } } } let(:add_deactivations) { create(:location_deactivation_period, deactivation_date: Time.zone.local(2024, 6, 5), reactivation_date: nil, location:) } it "redirects to the confirmation page" do @@ -2078,7 +2078,7 @@ RSpec.describe LocationsController, type: :request do end context "with other date" do - let(:params) { { location_deactivation_period: { reactivation_date_type: "other", "reactivation_date(3i)": "10", "reactivation_date(2i)": "9", "reactivation_date(1i)": "2022" } } } + let(:params) { { location_deactivation_period: { reactivation_date_type: "other", "reactivation_date": "10/9/2022" } } } it "redirects to the location page and displays a success banner" do expect(response).to redirect_to("/schemes/#{scheme.id}/locations/#{location.id}") @@ -2096,7 +2096,7 @@ RSpec.describe LocationsController, type: :request do end context "with other future date" do - let(:params) { { location_deactivation_period: { reactivation_date_type: "other", "reactivation_date(3i)": "14", "reactivation_date(2i)": "12", "reactivation_date(1i)": "2023" } } } + let(:params) { { location_deactivation_period: { reactivation_date_type: "other", "reactivation_date": "14/12/2023" } } } it "redirects to the location page and displays a success banner" do expect(response).to redirect_to("/schemes/#{scheme.id}/locations/#{location.id}") @@ -2116,7 +2116,7 @@ RSpec.describe LocationsController, type: :request do end context "when invalid date is entered" do - let(:params) { { location_deactivation_period: { reactivation_date_type: "other", "reactivation_date(3i)": "10", "reactivation_date(2i)": "44", "reactivation_date(1i)": "2022" } } } + let(:params) { { location_deactivation_period: { reactivation_date_type: "other", "reactivation_date": "10/44/2022" } } } it "displays the new page with an error message" do expect(response).to have_http_status(:unprocessable_content) @@ -2125,7 +2125,7 @@ RSpec.describe LocationsController, type: :request do end context "when the date is entered is before the beginning of current collection window" do - let(:params) { { location_deactivation_period: { reactivation_date_type: "other", "reactivation_date(3i)": "10", "reactivation_date(2i)": "4", "reactivation_date(1i)": "2020" } } } + let(:params) { { location_deactivation_period: { reactivation_date_type: "other", "reactivation_date": "10/4/2020" } } } it "displays the new page with an error message" do expect(response).to have_http_status(:unprocessable_content) @@ -2134,7 +2134,7 @@ RSpec.describe LocationsController, type: :request do end context "when the day is not entered" do - let(:params) { { location_deactivation_period: { reactivation_date_type: "other", "reactivation_date(3i)": "", "reactivation_date(2i)": "2", "reactivation_date(1i)": "2022" } } } + let(:params) { { location_deactivation_period: { reactivation_date_type: "other", "reactivation_date": "/2/2022" } } } it "displays page with an error message" do expect(response).to have_http_status(:unprocessable_content) @@ -2143,7 +2143,7 @@ RSpec.describe LocationsController, type: :request do end context "when the month is not entered" do - let(:params) { { location_deactivation_period: { reactivation_date_type: "other", "reactivation_date(3i)": "2", "reactivation_date(2i)": "", "reactivation_date(1i)": "2022" } } } + let(:params) { { location_deactivation_period: { reactivation_date_type: "other", "reactivation_date": "2//2022" } } } it "displays page with an error message" do expect(response).to have_http_status(:unprocessable_content) @@ -2152,7 +2152,7 @@ RSpec.describe LocationsController, type: :request do end context "when the year is not entered" do - let(:params) { { location_deactivation_period: { reactivation_date_type: "other", "reactivation_date(3i)": "2", "reactivation_date(2i)": "2", "reactivation_date(1i)": "" } } } + let(:params) { { location_deactivation_period: { reactivation_date_type: "other", "reactivation_date": "2/2/" } } } it "displays page with an error message" do expect(response).to have_http_status(:unprocessable_content) @@ -2162,7 +2162,7 @@ RSpec.describe LocationsController, type: :request do context "when the reactivation date is before deactivation date" do let(:deactivation_date) { Time.zone.local(2022, 10, 10) } - let(:params) { { location_deactivation_period: { reactivation_date_type: "other", "reactivation_date(3i)": "8", "reactivation_date(2i)": "9", "reactivation_date(1i)": "2022" } } } + let(:params) { { location_deactivation_period: { reactivation_date_type: "other", "reactivation_date": "8/9/2022" } } } it "displays page with an error message" do expect(response).to have_http_status(:unprocessable_content) diff --git a/spec/requests/merge_requests_controller_spec.rb b/spec/requests/merge_requests_controller_spec.rb index 4c07dbfb7..5545d6ca2 100644 --- a/spec/requests/merge_requests_controller_spec.rb +++ b/spec/requests/merge_requests_controller_spec.rb @@ -354,7 +354,7 @@ RSpec.describe MergeRequestsController, type: :request do context "when not answering the question" do let(:merge_request) { MergeRequest.create!(requesting_organisation: organisation, absorbing_organisation: other_organisation) } let(:params) do - { merge_request: { page: "merge_date" } } + { merge_request: { merge_date: "", page: "merge_date" } } end let(:request) do patch "/merge-request/#{merge_request.id}", headers:, params: @@ -375,7 +375,7 @@ RSpec.describe MergeRequestsController, type: :request do context "when merge date set to an invalid date" do let(:merge_request) { MergeRequest.create!(requesting_organisation: organisation) } let(:params) do - { merge_request: { page: "merge_date", "merge_date(3i)": "10", "merge_date(2i)": "44", "merge_date(1i)": "2022" } } + { merge_request: { page: "merge_date", "merge_date": "10/44/2022" } } end let(:request) do @@ -393,7 +393,7 @@ RSpec.describe MergeRequestsController, type: :request do context "when merge date set to a valid date" do let(:merge_request) { MergeRequest.create!(requesting_organisation: organisation) } let(:params) do - { merge_request: { page: "merge_date", "merge_date(3i)": "10", "merge_date(2i)": "4", "merge_date(1i)": "2022" } } + { merge_request: { page: "merge_date", "merge_date": "10/4/2022" } } end let(:request) do @@ -416,7 +416,7 @@ RSpec.describe MergeRequestsController, type: :request do context "when merge date set to a date more than 1 year in the future" do let(:merge_request) { MergeRequest.create!(requesting_organisation: organisation) } let(:params) do - { merge_request: { page: "merge_date", "merge_date(3i)": (Time.zone.now.day + 1).to_s, "merge_date(2i)": Time.zone.now.month.to_s, "merge_date(1i)": (Time.zone.now.year + 1).to_s } } + { merge_request: { page: "merge_date", "merge_date": [(Time.zone.now.day + 1).to_s, Time.zone.now.month.to_s, (Time.zone.now.year + 1).to_s].join("/") } } end let(:request) do diff --git a/spec/requests/schemes_controller_spec.rb b/spec/requests/schemes_controller_spec.rb index 713e54142..e5a96992f 100644 --- a/spec/requests/schemes_controller_spec.rb +++ b/spec/requests/schemes_controller_spec.rb @@ -2749,7 +2749,7 @@ RSpec.describe SchemesController, type: :request do end context "with other date" do - let(:params) { { scheme_deactivation_period: { deactivation_date_type: "other", "deactivation_date(3i)": "10", "deactivation_date(2i)": "10", "deactivation_date(1i)": "2022" } } } + let(:params) { { scheme_deactivation_period: { deactivation_date_type: "other", "deactivation_date": "10/10/2022" } } } context "and affected logs" do it "redirects to the confirmation page" do @@ -2901,7 +2901,7 @@ RSpec.describe SchemesController, type: :request do end context "when invalid date is entered" do - let(:params) { { scheme_deactivation_period: { deactivation_date_type: "other", "deactivation_date(3i)": "10", "deactivation_date(2i)": "44", "deactivation_date(1i)": "2022" } } } + let(:params) { { scheme_deactivation_period: { deactivation_date_type: "other", "deactivation_date": "10/44/2022" } } } it "displays the new page with an error message" do expect(response).to have_http_status(:unprocessable_content) @@ -2910,7 +2910,7 @@ RSpec.describe SchemesController, type: :request do end context "when the date is entered is before the beginning of current collection window" do - let(:params) { { scheme_deactivation_period: { deactivation_date_type: "other", "deactivation_date(3i)": "10", "deactivation_date(2i)": "4", "deactivation_date(1i)": "2020" } } } + let(:params) { { scheme_deactivation_period: { deactivation_date_type: "other", "deactivation_date": "10/4/2020" } } } it "displays the new page with an error message" do expect(response).to have_http_status(:unprocessable_content) @@ -2919,7 +2919,7 @@ RSpec.describe SchemesController, type: :request do end context "when the day is not entered" do - let(:params) { { scheme_deactivation_period: { deactivation_date_type: "other", "deactivation_date(3i)": "", "deactivation_date(2i)": "2", "deactivation_date(1i)": "2022" } } } + let(:params) { { scheme_deactivation_period: { deactivation_date_type: "other", "deactivation_date": "/2/2022" } } } it "displays page with an error message" do expect(response).to have_http_status(:unprocessable_content) @@ -2928,7 +2928,7 @@ RSpec.describe SchemesController, type: :request do end context "when the month is not entered" do - let(:params) { { scheme_deactivation_period: { deactivation_date_type: "other", "deactivation_date(3i)": "2", "deactivation_date(2i)": "", "deactivation_date(1i)": "2022" } } } + let(:params) { { scheme_deactivation_period: { deactivation_date_type: "other", "deactivation_date": "2//2022" } } } it "displays page with an error message" do expect(response).to have_http_status(:unprocessable_content) @@ -2937,7 +2937,7 @@ RSpec.describe SchemesController, type: :request do end context "when the year is not entered" do - let(:params) { { scheme_deactivation_period: { deactivation_date_type: "other", "deactivation_date(3i)": "2", "deactivation_date(2i)": "2", "deactivation_date(1i)": "" } } } + let(:params) { { scheme_deactivation_period: { deactivation_date_type: "other", "deactivation_date": "2/2/" } } } it "displays page with an error message" do expect(response).to have_http_status(:unprocessable_content) @@ -2947,7 +2947,7 @@ RSpec.describe SchemesController, type: :request do context "when there is an earlier open deactivation" do let(:deactivation_date) { Time.zone.local(2022, 10, 10) } - let(:params) { { scheme_deactivation_period: { deactivation_date_type: "other", "deactivation_date(3i)": "8", "deactivation_date(2i)": "9", "deactivation_date(1i)": "2023" } } } + let(:params) { { scheme_deactivation_period: { deactivation_date_type: "other", "deactivation_date": "8/9/2023" } } } let(:add_deactivations) { create(:scheme_deactivation_period, deactivation_date: Time.zone.local(2023, 6, 5), reactivation_date: nil, scheme:) } before do @@ -2968,7 +2968,7 @@ RSpec.describe SchemesController, type: :request do context "when there is a later open deactivation" do let(:deactivation_date) { Time.zone.local(2022, 10, 10) } - let(:params) { { scheme_deactivation_period: { deactivation_date_type: "other", "deactivation_date(3i)": "8", "deactivation_date(2i)": "9", "deactivation_date(1i)": "2022" } } } + let(:params) { { scheme_deactivation_period: { deactivation_date_type: "other", "deactivation_date": "8/9/2022" } } } let(:add_deactivations) { create(:scheme_deactivation_period, deactivation_date: Time.zone.local(2023, 6, 5), reactivation_date: nil, scheme:) } it "redirects to the confirmation page" do diff --git a/webpack.config.js b/webpack.config.js index 32d4030c0..3d362e010 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -41,7 +41,8 @@ module.exports = { resolve: { alias: { 'govuk-frontend-styles': path.resolve(__dirname, 'node_modules/govuk-frontend/dist/govuk/all.scss'), - 'govuk-prototype-styles': path.resolve(__dirname, 'node_modules/@x-govuk/govuk-prototype-components/x-govuk/all.scss') + 'govuk-prototype-styles': path.resolve(__dirname, 'node_modules/@x-govuk/govuk-prototype-components/x-govuk/all.scss'), + 'moj-frontend': path.resolve(__dirname, 'node_modules/@ministryofjustice/frontend/moj/all.js') }, modules: ['node_modules', 'node_modules/govuk-frontend/dist/govuk'] }, @@ -62,7 +63,8 @@ module.exports = { { from: 'node_modules/govuk-frontend/dist/govuk/assets/fonts', to: 'fonts' }, { from: 'node_modules/html5shiv/dist/html5shiv.min.js', to: 'vendor' }, { from: 'app/frontend/vendor/outerHTML.js', to: 'vendor' }, - { from: 'app/frontend/vendor/polyfill-output-value.js', to: 'vendor' } + { from: 'app/frontend/vendor/polyfill-output-value.js', to: 'vendor' }, + { from: 'node_modules/@ministryofjustice/frontend/moj/all.js', to: 'vendor' } ] }) ] diff --git a/yarn.lock b/yarn.lock index 11ea50b9a..05279f9ed 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1109,6 +1109,14 @@ "@jridgewell/resolve-uri" "^3.1.0" "@jridgewell/sourcemap-codec" "^1.4.14" +"@ministryofjustice/frontend@^3.3.0": + version "3.3.0" + resolved "https://registry.yarnpkg.com/@ministryofjustice/frontend/-/frontend-3.3.0.tgz#45bb0359fa9a466a574d44e2a78121f5544c2eeb" + integrity sha512-kK1+XTI8KPgL2kA3ylTkXfXqA2cirENh1oxTYnvogt6W8vg5VexGSYjynRZ5EhRUAQh6uHPmOGyr+mYXmNwReQ== + dependencies: + govuk-frontend "^5.0.0" + moment "^2.27.0" + "@nodelib/fs.scandir@2.1.5": version "2.1.5" resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" @@ -2734,7 +2742,7 @@ gopd@^1.0.1: dependencies: get-intrinsic "^1.1.3" -govuk-frontend@5.7.1: +govuk-frontend@5.7.1, govuk-frontend@^5.0.0: version "5.7.1" resolved "https://registry.yarnpkg.com/govuk-frontend/-/govuk-frontend-5.7.1.tgz#d4c561ebf8c0b76130f31df8c2e4d70d340cd63f" integrity sha512-jF1cq5rn57kxZmJRprUZhTQ31zaBBK4b5AyeJaPX3Yhg22lk90Mx/dQLvOk/ycV3wM7e0y+s4IPvb2fFaPlCGg== @@ -3124,7 +3132,7 @@ jest-worker@^27.4.5: dependencies: jquery ">=1.8.0 <4.0.0" -"jquery@>=1.8.0 <4.0.0", jquery@^3.6.0: +"jquery@>=1.8.0 <4.0.0", jquery@^3.6.0, jquery@^3.7.1: version "3.7.1" resolved "https://registry.yarnpkg.com/jquery/-/jquery-3.7.1.tgz#083ef98927c9a6a74d05a6af02806566d16274de" integrity sha512-m4avr8yL8kmFN8psrbFFFmB/If14iN5o9nw/NgnnM+kybDJpRsAynV2BsfpTYrTRysYUdADVD7CkUUizgkpLfg== @@ -3386,6 +3394,11 @@ minimist@^1.2.0, minimist@^1.2.6: resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== +moment@^2.27.0: + version "2.30.1" + resolved "https://registry.yarnpkg.com/moment/-/moment-2.30.1.tgz#f8c91c07b7a786e30c59926df530b4eac96974ae" + integrity sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how== + ms@2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009"