diff --git a/Procfile.webpack b/Procfile.webpack new file mode 100644 index 000000000..6b8c62be8 --- /dev/null +++ b/Procfile.webpack @@ -0,0 +1,3 @@ +web: bundle exec rake cf:run_migrations db:migrate && bin/rails server -p $PORT +worker: bundle exec sidekiq -L ./log/worker.log -C ./config/sidekiq.yml +webpack: bin/webpack-dev-server \ No newline at end of file diff --git a/app/assets/javascripts/admin/comments.js.coffee b/app/assets/javascripts/admin/comments.js.coffee index da4d82250..cab48ec08 100644 --- a/app/assets/javascripts/admin/comments.js.coffee +++ b/app/assets/javascripts/admin/comments.js.coffee @@ -1,5 +1,5 @@ ready = -> - $('body').on 'submit', '.new_comment', (e) -> + $(document).on 'submit', '.new_comment', (e) -> that = $(this) e.preventDefault() $.ajax @@ -30,8 +30,9 @@ ready = -> else signatureWrapper.html("") + window.fire(that[0], 'ajax:x:success', data) - $('body').on 'submit', '.destroy-comment', (e) -> + $(document).on 'submit', '.destroy-comment', (e) -> e.preventDefault() $.ajax url: $(this).attr('action') diff --git a/app/assets/javascripts/admin/financial_data.js.coffee b/app/assets/javascripts/admin/financial_data.js.coffee index c548a5db0..96df61541 100644 --- a/app/assets/javascripts/admin/financial_data.js.coffee +++ b/app/assets/javascripts/admin/financial_data.js.coffee @@ -6,14 +6,13 @@ jQuery -> overallBenchmarksTable = ($ "#overall-financial-benchmarks") financialTable = ($ "#financial-table") - ($ "input", form).on "change keyup keydown paste", -> - timer ||= setTimeout(saveFinancials, 500 ) + $("input", form).on "change keyup keydown paste", -> + timer ||= setTimeout(saveFinancials, 500) ($ "button", form).on "click", (event) -> do event.preventDefault $(this).closest(".form-group").removeClass("form-edit") - updateExportsGrowth = (exports) -> exportsGrowth = ($ 'tr.exports-growth td.value', benchmarksTable) values = exports.map (i, td) -> @@ -91,13 +90,13 @@ jQuery -> url = form.attr('action') formData = form.serialize() updateBenchmarks() - - jqXHR = $.ajax({ + $.ajax url: url data: formData type: 'POST' - dataType: 'js' - }) + dataType: 'script' + success: (_data) -> + window.fire(form[0], 'ajax:x:success', null) ($ 'td.value', financialTable).each (i, td) -> input = ($ 'input', ($ td)) diff --git a/app/assets/javascripts/admin/focusable.js.coffee b/app/assets/javascripts/admin/focusable.js.coffee new file mode 100644 index 000000000..4d5f3c536 --- /dev/null +++ b/app/assets/javascripts/admin/focusable.js.coffee @@ -0,0 +1,25 @@ +FOCUSABLE_ELEMENTS = 'input:not([disabled]), select:not([disabled]), textarea:not([disabled]), button:not([disabled]), [href], [tabindex]:not([tabindex="-1"]):not([disabled]), details:not([disabled]), summary:not(:disabled)' +FOCUSABLE_FORM_ELEMENTS = 'input:not([disabled]), select:not([disabled]), textarea:not([disabled])' + +window.FOCUSABLE_ELEMENTS = FOCUSABLE_ELEMENTS +window.FOCUSABLE_FORM_ELEMENTS = FOCUSABLE_FORM_ELEMENTS + +visible = (el) -> + !el.hidden and (!el.type or el.type != 'hidden') and (el.offsetWidth > 0 or el.offsetHeight > 0) + +focusable = (el) -> + el.tabIndex >= 0 and !el.disabled and visible(el) + +window.focusElement = (el, elements = FOCUSABLE_ELEMENTS) -> + autofocusElement = Array.from(el.querySelectorAll(elements)).filter(focusable)[0] + if autofocusElement + autofocusElement.focus() + return + +window.autofocusElement = (el) -> + autofocusElement = Array.from(el.querySelectorAll('[autofocus]')).filter(focusable)[0] + if !autofocusElement + autofocusElement = el + el.setAttribute('tabindex', '-1') + autofocusElement.focus() + return \ No newline at end of file diff --git a/app/assets/javascripts/admin/form_answers.js.coffee b/app/assets/javascripts/admin/form_answers.js.coffee index fd7492260..c9ff0ff43 100644 --- a/app/assets/javascripts/admin/form_answers.js.coffee +++ b/app/assets/javascripts/admin/form_answers.js.coffee @@ -314,9 +314,12 @@ ready = -> if $('.form_answer_attachment').length == 0 sidebarSection.find(".document-list .p-empty").removeClass("visuallyhidden") - $(document).on "click", ".form-edit-link", (e) -> + $(document).on 'click', '.form-edit-link', (e) -> e.preventDefault() - $(this).closest(".form-group").addClass("form-edit") + element = this.closest('.form-group') + if (element) + element.classList.add('form-edit') + $(".submit-assessment").on "ajax:error", (e, data, status, xhr) -> errors = data.responseJSON $(this).addClass("field-with-errors") @@ -431,8 +434,8 @@ editFormAnswerAutoUpdate = -> $(".sic-code .form-save-link").on "click", (e) -> e.preventDefault() e.stopPropagation() - that = $("#form_answer_sic_code") - form = $(".edit_form_answer") + input = $("#form_answer_sic_code") + form = $(e.target).closest('form') $.ajax action: form.attr("action") data: form.serialize() @@ -440,15 +443,19 @@ editFormAnswerAutoUpdate = -> dataType: "json" success: (result) -> - formGroup = that.parents(".form-group") + formGroup = input.parents(".form-group") formGroup.removeClass("form-edit") - formGroup.find(".form-value p").text(that.find("option:selected").text()) + console.log(formGroup, input) + formGroup.find(".form-value p").text(input.val()) sicCodes = result["form_answer"]["sic_codes"] counter = 1 for row in $(".sector-average-growth td") $(row).text(sicCodes[counter.toString()]) counter += 1 $(".avg-growth-legend").text(result["form_answer"]["legend"]) + + window.fire(form[0], 'ajax:x:success', null) + bindRags =(klass) -> $(document).on "click", "#{klass} .btn-rag .dropdown-menu a", (e) -> e.preventDefault() diff --git a/app/assets/javascripts/admin/settings.js.coffee b/app/assets/javascripts/admin/settings.js.coffee index 0c878afbf..2b927673f 100644 --- a/app/assets/javascripts/admin/settings.js.coffee +++ b/app/assets/javascripts/admin/settings.js.coffee @@ -117,20 +117,20 @@ jQuery -> settingsWrapper.on "click", ".btn-cancel", (e) -> e.preventDefault() - form_well = ($ e.currentTarget).closest('.well') + well = ($ e.currentTarget).closest('.well') - if form_well.hasClass("deadline-form") + if well.hasClass("deadline-form") wrapper = ($ e.currentTarget).closest('.deadline') ($ ".form-value", wrapper).removeClass("hidden") ($ ".deadline-form", wrapper).addClass("hidden") ($ ".edit-deadline", wrapper).removeClass("hidden") - else if form_well.hasClass("notification-edit-form") + else if well.hasClass("notification-edit-form") wrapper = ($ e.currentTarget).closest('li') ($ ".form-value", wrapper).removeClass("hidden") ($ ".notification-edit-form", wrapper).addClass("hidden") ($ ".actions", wrapper).removeClass("hidden") - else if form_well.hasClass("notification-new-form") + else if well.hasClass("notification-new-form") wrapper = ($ e.currentTarget).closest('.panel-section') ($ ".notification-form", wrapper).addClass("hidden") diff --git a/app/assets/javascripts/application-admin.js.coffee b/app/assets/javascripts/application-admin.js.coffee index 6011afb7b..673022e3f 100644 --- a/app/assets/javascripts/application-admin.js.coffee +++ b/app/assets/javascripts/application-admin.js.coffee @@ -26,7 +26,18 @@ #= require clean-paste $(document).ready(() -> - $("html").removeClass("no-js").addClass("js") - ($ ".timepicker").timePicker() - ($ ".datepicker").datepicker({dateFormat: "dd/mm/yy"}) + $('html').removeClass('no-js').addClass('js') + ($ '.timepicker').timePicker() + ($ '.datepicker').datepicker({dateFormat: 'dd/mm/yy'}) ) + +$(document).on 'ajax:success', 'form', (event, data, _status, _xhr) -> + fire(this, 'ajax:x:success', data) + +$(document).on 'ajax:error', 'form', (event, data, _status, _xhr) -> + fire(this, 'ajax:x:error', data) + +window.fire = (obj, name, data) -> + event = new CustomEvent(name, detail: data, bubbles: true, cancelable: true) + obj.dispatchEvent(event) + !event.defaultPrevented diff --git a/app/assets/javascripts/frontend/form-validation.js.coffee b/app/assets/javascripts/frontend/form-validation.js.coffee index 973b5ccb8..9695846bd 100644 --- a/app/assets/javascripts/frontend/form-validation.js.coffee +++ b/app/assets/javascripts/frontend/form-validation.js.coffee @@ -145,11 +145,49 @@ window.FormValidation = for subquestion in subquestions if not @validateSingleQuestion($(subquestion)) @logThis(question, "validateRequiredQuestion", "This field is required") - @addErrorMessage($(subquestion), "This field is required") + @addSubfieldError(question, subquestion) else if not @validateSingleQuestion(question) @logThis(question, "validateRequiredQuestion", "This field is required") - @addErrorMessage(question, "This field is required") + @addQuestionError(question) + + addSubfieldError: (question, subquestion) -> + questionRef = question.attr("data-question_ref") + input = $(subquestion).find('input,textarea,select').filter(':visible') + label = $("label[for='#{input.attr('id')}']").text() + incompleteMessage = "Question #{questionRef} is incomplete. It is required and must be filled in." + + if question.hasClass('date-DDMMYYYY') + @addErrorMessage($(subquestion), "#{incompleteMessage} Use the format DD/MM/YYYY.") + else if question.hasClass('date-MMYYYY') + @addErrorMessage($(subquestion), "#{incompleteMessage} Use the format MM/YYYY.") + else if question.hasClass('date-YYYY') + @addErrorMessage($(subquestion), "#{incompleteMessage} Use the format YYYY.") + else if input.hasClass("autocomplete__input") + @addErrorMessage($(subquestion), "Question #{questionRef} is incomplete. #{label} is required and an option must be selected from the following dropdown list.") + else + if question.find(".js-financial-year-latest").length + #avoid duplicate errors for financial year questions + return + else + @addErrorMessage($(subquestion), "Question #{questionRef} is incomplete. #{label} is required and must be filled in.") + + addQuestionError: (question) -> + questionRef = question.attr("data-question_ref") + incompleteMessage = "Question #{questionRef} is incomplete. It is required" + if @isOptionsQuestion(question) + @addErrorMessage(question, "#{incompleteMessage} and an option must be chosen from the following list.") + else if @isSelectQuestion(question) + @addErrorMessage(question, "#{incompleteMessage} and an option must be selected from the following dropdown list.") + else if @isTextishQuestion(question) && !question.hasClass("question-year") + @addErrorMessage(question, "#{incompleteMessage} and must be filled in.") + else if question.hasClass("question-year") + @addErrorMessage(question, "#{incompleteMessage} and must be filled in. Use the format YYYY.") + else if @isCheckboxQuestion(question) + if question.find("input[type='checkbox']").length > 1 + @addErrorMessage(question, "#{incompleteMessage} and at least one option must be chosen from the following list.") + else + @addErrorMessage(question, "#{incompleteMessage} and confirmation must be given by ticking the checkbox.") validateMatchQuestion: (question) -> q = question.find(".match") @@ -161,6 +199,7 @@ window.FormValidation = validateMaxDate: (question) -> val = question.find("input[type='number']").val() + questionRef = question.attr("data-question_ref") questionYear = question.find(".js-date-input-year").val() questionMonth = question.find(".js-date-input-month").val() @@ -175,7 +214,7 @@ window.FormValidation = if not @toDate(questionDate).isValid() @logThis(question, "validateMaxDate", "Not a valid date") - @addErrorMessage(question, "Not a valid date") + @addErrorMessage(question, "Question #{questionRef} is incomplete. The date entered is not valid. Use the format DD/MM/YYYY.") return if diff > 0 @@ -291,6 +330,7 @@ window.FormValidation = @addErrorMessage(question, "Not a valid number") validateEmployeeMin: (question) -> + questionRef = question.attr("data-question_ref") for subquestion in question.find("input") shownQuestion = true for conditional in $(subquestion).parents('.js-conditional-question') @@ -299,9 +339,10 @@ window.FormValidation = if shownQuestion subq = $(subquestion) + label = $("label[for='#{subq.attr('id')}']").text() if not subq.val() and question.hasClass("question-required") @logThis(question, "validateEmployeeMin", "This field is required") - @appendMessage(subq.closest(".span-financial"), "This field is required") + @appendMessage(subq.closest(".span-financial"), "Question #{questionRef} is incomplete. #{label} is required and must be filled in. Enter '0' if none.") @addErrorClass(question) continue else if not subq.val() @@ -374,6 +415,7 @@ window.FormValidation = validateCurrentAwards: (question) -> $(".govuk-error-message", question).empty() + questionRef = question.attr("data-question_ref") for subquestion in question.find(".list-add li") errors = false @@ -382,7 +424,7 @@ window.FormValidation = if !$(input).val() fieldName = $(input).data("dependable-option-siffix") fieldName = fieldName[0].toUpperCase() + fieldName.slice(1) - fieldError = "#{fieldName} can't be blank. " + fieldError = "Question #{questionRef} is incomplete. #{fieldName} is required and an option must be selected from the following list. " @logThis(question, "validateCurrentAwards", fieldError) @appendMessage($(input).closest('.govuk-form-group'), fieldError) errors = true @@ -402,6 +444,7 @@ window.FormValidation = subq = $(subquestion) qParent = subq.closest(".js-fy-entries") errContainer = subq.closest(".span-financial") + questionRef = question.attr("data-question_ref") shownQuestion = true for conditional in $(subquestion).parents('.js-conditional-question') @@ -413,7 +456,8 @@ window.FormValidation = if not subq.val() and question.hasClass("question-required") @logThis(question, "validateMoneyByYears", "This field is required") - @appendMessage(errContainer, "This field is required") + label = $("label[for='#{subq.attr('id')}']").text() + @appendMessage(errContainer, "Question #{questionRef} is incomplete. #{label} is required and must be filled in. Enter '0' if none.") @addErrorClass(question) continue else if not subq.val() @@ -448,41 +492,54 @@ window.FormValidation = if !conditional return # end of conditional validation + questionRef = question.attr("data-question_ref") for subquestionBlock in question.find(".by-years-wrapper.show-question .govuk-date-input") subq = $(subquestionBlock) qParent = subq.closest(".js-fy-entries") + label = qParent.find(".js-year-default").text() errorsContainer = qParent.find(".govuk-error-message").html() day = subq.find("input.js-fy-day").val() month = subq.find("input.js-fy-month").val() year = subq.find("input.js-fy-year").val() - if (not day or not month or not year) - if question.hasClass("question-required") && errorsContainer.length < 1 + if question.hasClass("question-required") && errorsContainer.length < 1 + if (not day and not month and not year) @logThis(question, "validateDateByYears", "This field is required") - @appendMessage(qParent, "This field is required") + @appendMessage(qParent, "Question #{questionRef} is incomplete. #{label} is required and must be filled in. Use the format DD/MM/YYYY.") @addErrorClass(question) - else - complexDateString = day + "/" + month + "/" + year - date = @toDate(complexDateString) + else if (not day) + @appendMessage(qParent, "Question #{questionRef} is incomplete. #{label} day is required and must be filled in. Use the format DD.") + else if (not month) + @appendMessage(qParent, "Question #{questionRef} is incomplete. #{label} month is required and must be filled in. Use the format MM.") + else if (not year) + @appendMessage(qParent, "Question #{questionRef} is incomplete. #{label} year is required and must be filled in. Use the format YYYY.") + else + complexDateString = day + "/" + month + "/" + year + date = @toDate(complexDateString) - if not date.isValid() - @logThis(question, "validateDateByYears", "Not a valid date") - @appendMessage(qParent, "Not a valid date") - @addErrorClass(question) + if not date.isValid() + @logThis(question, "validateDateByYears", "Not a valid date") + @appendMessage(qParent, "Not a valid date") + @addErrorClass(question) validateInnovationFinancialDate: (question) -> - val = question.find("input[type='number']").val() - + questionRef = question.attr("data-question_ref") questionDay = parseInt(question.find(".innovation-day").val()) questionMonth = parseInt(question.find(".innovation-month").val()) questionDate = "#{questionDay}/#{questionMonth}/#{moment().format('Y')}" - if not @toDate(questionDate).isValid() + if (not questionDay and not questionMonth) + @addErrorMessage(question, "Question #{questionRef} is incomplete. Year-end is required and must be filled in. Use the format DD/MM.") + else if not questionDay + @addErrorMessage(question, "Question #{questionRef} is incomplete. Day is required and must be filled in. Use the format DD/MM.") + else if not questionMonth + @addErrorMessage(question, "Question #{questionRef} is incomplete. Month is required and must be filled in. Use the format DD/MM.") + else if not @toDate(questionDate).isValid() @logThis(question, "validateMaxDate", "Not a valid date") - @addErrorMessage(question, "Not a valid date") + @addErrorMessage(question, "Question #{questionRef} is incomplete. It is required and must be filled in. Use the format DD/MM.") return validateDiffBetweenDates: (question) -> diff --git a/app/assets/javascripts/frontend/js_detector.js.coffee b/app/assets/javascripts/frontend/js_detector.js.coffee new file mode 100644 index 000000000..b7334d196 --- /dev/null +++ b/app/assets/javascripts/frontend/js_detector.js.coffee @@ -0,0 +1,3 @@ +jQuery -> + # if the user has javascript enabled, remove non js step value + $("#non_js_step_title").val("") diff --git a/app/assets/javascripts/frontend/password-strength-indicator.js b/app/assets/javascripts/frontend/password-strength-indicator.js index 71f7b0791..6448b0dfd 100644 --- a/app/assets/javascripts/frontend/password-strength-indicator.js +++ b/app/assets/javascripts/frontend/password-strength-indicator.js @@ -138,6 +138,7 @@ $(function() { if (someProblem) { $('#password-guidance').removeClass("govuk-!-display-none"); + $('#password-result-span').addClass("hide") } else { $('#password-guidance').addClass("govuk-!-display-none"); } @@ -147,8 +148,10 @@ $(function() { if ($passwordField.val().length == 0) { $passwordField.attr('aria-invalid', "true"); + $('#password-result-span').addClass("hide") } else if ($.inArray('good-password', guidance) >= 0) { $passwordField.attr('aria-invalid', "false"); + $('#password-result-span').removeClass("hide") } else { $passwordField.attr('aria-invalid', "true"); } @@ -160,13 +163,16 @@ $(function() { if ($passwordConfirmationField.val().length == 0) { $passwordConfirmationField.attr('aria-invalid', "true"); + $('#password-confirmation-result-span').addClass("hide") } else if ($.inArray('confirmation-not-matching', guidance) >= 0) { $passwordConfirmationField.attr('aria-invalid', "true"); indicator.parent().removeClass('confirmation-matching'); + $('#password-confirmation-result-span').addClass("hide") } else if ($.inArray('confirmation-matching', guidance) >= 0) { $passwordConfirmationField.attr('aria-invalid', "false"); if($.inArray('good-password', guidance) >= 0) { indicator.parent().addClass('confirmation-matching'); + $('#password-confirmation-result-span').removeClass("hide") } } } diff --git a/app/assets/stylesheets/admin/_variables.scss b/app/assets/stylesheets/admin/_variables.scss index bc468ae15..740857467 100644 --- a/app/assets/stylesheets/admin/_variables.scss +++ b/app/assets/stylesheets/admin/_variables.scss @@ -31,3 +31,4 @@ $header-hover: #444; $blue-link-colour: #3264A3; $govuk-light-blue: #5694ca; $govuk-highlight-yellow: #fd0; +$govuk-warning-red: #d4351c; diff --git a/app/assets/stylesheets/admin/base.scss b/app/assets/stylesheets/admin/base.scss index 0c1f0c9f3..4060c2682 100644 --- a/app/assets/stylesheets/admin/base.scss +++ b/app/assets/stylesheets/admin/base.scss @@ -28,9 +28,9 @@ input[type=text], input[type=tel], input[type=email], input[type=password], input[type=checkbox], select { &:focus { - outline: 3px solid #ffdd00; - outline-offset: 0; - box-shadow: inset 0 0 0 2px; + outline: 3px solid #ffdd00 !important; + outline-offset: 0 !important; + box-shadow: inset 0 0 0 2px !important; } } diff --git a/app/assets/stylesheets/admin/page-applications.scss b/app/assets/stylesheets/admin/page-applications.scss index d2a114b6e..9598f9530 100644 --- a/app/assets/stylesheets/admin/page-applications.scss +++ b/app/assets/stylesheets/admin/page-applications.scss @@ -599,6 +599,12 @@ left: 0; } + &:hover { + color: #fff; + background-color: $govuk-light-blue; + border-color: #204d74 + } + .show-bulk-assign & { .js & { display: none; diff --git a/app/assets/stylesheets/frontend/forms.scss b/app/assets/stylesheets/frontend/forms.scss index fc7729529..2b27d1d30 100644 --- a/app/assets/stylesheets/frontend/forms.scss +++ b/app/assets/stylesheets/frontend/forms.scss @@ -1110,3 +1110,8 @@ fieldset.account-contact-preferences-other-ops { .js-fy-entries { margin-bottom: 30px } + +.cke_wordcount span { + font-size: 1.1875rem !important; + color: $grey-1 !important; +} diff --git a/app/controllers/admin/admins_controller.rb b/app/controllers/admin/admins_controller.rb index e5e008e53..65753238b 100644 --- a/app/controllers/admin/admins_controller.rb +++ b/app/controllers/admin/admins_controller.rb @@ -19,6 +19,9 @@ def create authorize @resource, :create? @resource.save + + render_flash_message_for(@resource) + location = @resource.persisted? ? admin_admins_path : nil respond_with :admin, @resource, location: location end @@ -32,6 +35,8 @@ def update @resource.update_without_password(resource_params) end + render_flash_message_for(@resource) + respond_with :admin, @resource, location: admin_admins_path end @@ -39,6 +44,8 @@ def destroy authorize @resource, :destroy? @resource.soft_delete! + render_flash_message_for(@resource) + respond_with :admin, @resource, location: admin_admins_path end diff --git a/app/controllers/admin/assessors_controller.rb b/app/controllers/admin/assessors_controller.rb index 6074ee624..f41faa68b 100644 --- a/app/controllers/admin/assessors_controller.rb +++ b/app/controllers/admin/assessors_controller.rb @@ -20,6 +20,9 @@ def create @resource.save location = @resource.persisted? ? admin_assessors_path : nil + + render_flash_message_for(@resource) + respond_with :admin, @resource, location: location end @@ -32,6 +35,8 @@ def update @resource.update_without_password(resource_params) end + render_flash_message_for(@resource) + respond_with :admin, @resource, location: admin_assessors_path end @@ -39,6 +44,8 @@ def destroy authorize @resource, :destroy? @resource.soft_delete! + render_flash_message_for(@resource) + respond_with :admin, @resource, location: admin_assessors_path end diff --git a/app/controllers/admin/base_controller.rb b/app/controllers/admin/base_controller.rb index 0fa7161e9..8ea7ef5bc 100644 --- a/app/controllers/admin/base_controller.rb +++ b/app/controllers/admin/base_controller.rb @@ -20,6 +20,14 @@ def current_subject current_admin end + def render_flash_message_for(resource, message: nil) + if resource.errors.any? + flash[:error] = message || "An unknown error has occurred, please try again." + else + flash[:notice] = message || "Success!" + end + end + private def user_not_authorized diff --git a/app/controllers/admin/comments_controller.rb b/app/controllers/admin/comments_controller.rb index 1cf05c751..938f5c908 100644 --- a/app/controllers/admin/comments_controller.rb +++ b/app/controllers/admin/comments_controller.rb @@ -27,6 +27,7 @@ def create head :ok end else + render_flash_message_for(@comment) redirect_to admin_form_answer_path(form_answer) end end @@ -38,7 +39,10 @@ def update log_event if resource.update(update_params) respond_to do |format| - format.html { redirect_to([namespace_name, form_answer]) } + format.html do + render_flash_message_for(resource) + redirect_to([namespace_name, form_answer]) + end format.js { head :ok } end end @@ -49,8 +53,11 @@ def destroy log_event if resource.destroy respond_to do |format| - format.json{ render(json: :ok)} - format.html{ redirect_to admin_form_answer_path(form_answer)} + format.json { render(json: :ok)} + format.html do + render_flash_message_for(resource) + redirect_to(admin_form_answer_path(form_answer)) + end end end diff --git a/app/controllers/admin/custom_emails_controller.rb b/app/controllers/admin/custom_emails_controller.rb index bbe767e96..438461a96 100644 --- a/app/controllers/admin/custom_emails_controller.rb +++ b/app/controllers/admin/custom_emails_controller.rb @@ -15,8 +15,10 @@ def create @form = CustomEmailForm.new(custom_email_form_attributes) if @form.valid? CustomEmailWorker.perform_async(custom_email_form_attributes) + render_flash_message_for(@form) redirect_to admin_custom_email_path, notice: "Email was successfully scheduled" else + render_flash_message_for(@form) render :show end end diff --git a/app/controllers/admin/judges_controller.rb b/app/controllers/admin/judges_controller.rb index 147578b2d..5ee3060f8 100644 --- a/app/controllers/admin/judges_controller.rb +++ b/app/controllers/admin/judges_controller.rb @@ -20,6 +20,9 @@ def create @resource.save location = @resource.persisted? ? admin_judges_path : nil + + render_flash_message_for(@resource) + respond_with :admin, @resource, location: location end @@ -32,6 +35,8 @@ def update @resource.update_without_password(resource_params) end + render_flash_message_for(@resource) + respond_with :admin, @resource, location: admin_judges_path end @@ -39,6 +44,8 @@ def destroy authorize @resource, :destroy? @resource.soft_delete! + render_flash_message_for(@resource) + respond_with :admin, @resource, location: admin_judges_path end diff --git a/app/controllers/admin/users_controller.rb b/app/controllers/admin/users_controller.rb index b5c22f5af..89015ebc0 100644 --- a/app/controllers/admin/users_controller.rb +++ b/app/controllers/admin/users_controller.rb @@ -27,6 +27,9 @@ def create @resource.save location = @resource.persisted? ? admin_users_path : nil + + render_flash_message_for(@resource) + respond_with :admin, @resource, location: location end @@ -39,6 +42,8 @@ def update @resource.update_without_password(resource_params) end + render_flash_message_for(@resource) + respond_with :admin, @resource, location: admin_users_path end diff --git a/app/controllers/concerns/admin_shortlisted_docs_context.rb b/app/controllers/concerns/admin_shortlisted_docs_context.rb index dd01eafc7..bc8a520f8 100644 --- a/app/controllers/concerns/admin_shortlisted_docs_context.rb +++ b/app/controllers/concerns/admin_shortlisted_docs_context.rb @@ -18,6 +18,7 @@ def create respond_to do |format| format.html do + render_flash_message_for(attachment) redirect_to [namespace_name, form_answer] end @@ -30,7 +31,8 @@ def create else respond_to do |format| format.html do - redirect_to [namespace_name, form_answer], alert: attachment.errors.full_messages.join(", ") + render_flash_message_for(attachment) + redirect_to [namespace_name, form_answer] end format.js do @@ -55,6 +57,7 @@ def destroy if request.xhr? || request.format.js? head :ok else + render_flash_message_for(resource) redirect_to [namespace_name, form_answer] end end diff --git a/app/controllers/concerns/admin_shortlisted_docs_submission_context.rb b/app/controllers/concerns/admin_shortlisted_docs_submission_context.rb index 70e2b1da5..e3ddf4706 100644 --- a/app/controllers/concerns/admin_shortlisted_docs_submission_context.rb +++ b/app/controllers/concerns/admin_shortlisted_docs_submission_context.rb @@ -6,6 +6,8 @@ def create respond_to do |format| format.html do + render_flash_message_for(resource) + redirect_to [namespace_name, form_answer], alert: render_errors end diff --git a/app/controllers/concerns/draft_notes_mixin.rb b/app/controllers/concerns/draft_notes_mixin.rb index 3a9ac2604..ff7fcebe1 100644 --- a/app/controllers/concerns/draft_notes_mixin.rb +++ b/app/controllers/concerns/draft_notes_mixin.rb @@ -9,6 +9,7 @@ def create respond_to do |format| format.html do + render_flash_message_for(resource) redirect_to [namespace_name, form_answer] end @@ -28,6 +29,7 @@ def update respond_to do |format| format.html do + render_flash_message_for(resource) redirect_to [namespace_name, form_answer] end diff --git a/app/controllers/form_controller.rb b/app/controllers/form_controller.rb index a99fdf178..38637f991 100644 --- a/app/controllers/form_controller.rb +++ b/app/controllers/form_controller.rb @@ -110,7 +110,11 @@ def edit_form end def save - @form_answer.document = prepare_doc if params[:form].present? + if params[:form].present? + @form_answer.document = prepare_doc + @form_answer.current_non_js_step = params[:form][:current_non_js_step].presence + end + @form = @form_answer.award_form.decorate(answers: HashWithIndifferentAccess.new(@form_answer.document)) redirected = params[:next_action] == "redirect" diff --git a/app/forms/award_years/v2024/innovation/innovation_step1.rb b/app/forms/award_years/v2024/innovation/innovation_step1.rb index fb9c20f01..6e426508d 100644 --- a/app/forms/award_years/v2024/innovation/innovation_step1.rb +++ b/app/forms/award_years/v2024/innovation/innovation_step1.rb @@ -12,14 +12,15 @@ def innovation_step1 text "I confirm that I have the consent of the head of my organisation to fill in and submit this entry form." end - head_of_business :head_of_business, "Details of the head of your organisation" do + sub_fields :head_of_business, "Details of the head of your organisation" do + required sub_ref "A 1.2" classes "sub-question" sub_fields([ { title: "Title" }, { first_name: "First name" }, { last_name: "Last name" }, - { honours: "Personal Honours (optional)" }, + { honours: "Personal Honours (optional)", hint: "For example, Lieutenant (LVO), Member of the Most Excellent Order of the British Empire (MBE), Air Force Cross (AFC). Please do not include qualifications such as a master's degree or doctorate." }, { job_title: "Job title or role in the organisation" }, { email: "Email address" } ]) diff --git a/app/forms/award_years/v2024/innovation/innovation_step2.rb b/app/forms/award_years/v2024/innovation/innovation_step2.rb index 18399588d..4405f6a87 100644 --- a/app/forms/award_years/v2024/innovation/innovation_step2.rb +++ b/app/forms/award_years/v2024/innovation/innovation_step2.rb @@ -115,7 +115,7 @@ def innovation_step2 end date :started_trading, "Date started trading." do - classes "js-started-trading" + classes "js-started-trading date-DDMMYYYY" required ref "B 5" context -> do @@ -156,7 +156,8 @@ def innovation_step2 style "small" end - press_contact_details :press_contact_details, "Contact details for press enquiries." do + sub_fields :press_contact_details, "Contact details for press enquiries." do + required ref "B 7" context %(

@@ -278,6 +279,7 @@ def innovation_step2 queen_award_applications :applied_for_queen_awards_details, " List the Queen's/King's awards you have applied for in the last 10 years." do classes "sub-question question-current-awards" sub_ref "B 12.1" + required conditional :applied_for_queen_awards, :yes diff --git a/app/forms/award_years/v2024/innovation/innovation_step3.rb b/app/forms/award_years/v2024/innovation/innovation_step3.rb index 0329a8b67..e5de6a908 100644 --- a/app/forms/award_years/v2024/innovation/innovation_step3.rb +++ b/app/forms/award_years/v2024/innovation/innovation_step3.rb @@ -284,7 +284,7 @@ def innovation_step3 date :innovation_was_launched_in_the_market, "Select the date when your innovation was launched in the market." do sub_section :innovation_timeline_header - classes "sub-question" + classes "sub-question date-DDMMYYYY" sub_ref "C 2.2" required context -> do diff --git a/app/forms/award_years/v2024/innovation/innovation_step4.rb b/app/forms/award_years/v2024/innovation/innovation_step4.rb index 3245beda7..f3086bafb 100644 --- a/app/forms/award_years/v2024/innovation/innovation_step4.rb +++ b/app/forms/award_years/v2024/innovation/innovation_step4.rb @@ -481,6 +481,7 @@ def innovation_step4 end options :product_estimated_figures, "Are any of the figures used on this page estimates?" do + required ref "D 9" yes_no context %( diff --git a/app/forms/award_years/v2024/international_trade/international_trade_step1.rb b/app/forms/award_years/v2024/international_trade/international_trade_step1.rb index df378d884..1eec16e3c 100644 --- a/app/forms/award_years/v2024/international_trade/international_trade_step1.rb +++ b/app/forms/award_years/v2024/international_trade/international_trade_step1.rb @@ -14,14 +14,15 @@ def trade_step1 ) end - head_of_business :head_of_business, "Details of the head of your organisation" do + sub_fields :head_of_business, "Details of the head of your organisation" do sub_ref "A 1.2" + required classes "sub-question" sub_fields([ { title: "Title" }, { first_name: "First name" }, { last_name: "Last name" }, - { honours: "Personal Honours (optional)" }, + { honours: "Personal Honours (optional)", hint: "For example, Lieutenant (LVO), Member of the Most Excellent Order of the British Empire (MBE), Air Force Cross (AFC). Please do not include qualifications such as a master's degree or doctorate." }, { job_title: "Job title or role in the organisation" }, { email: "Email address" } ]) diff --git a/app/forms/award_years/v2024/international_trade/international_trade_step2.rb b/app/forms/award_years/v2024/international_trade/international_trade_step2.rb index 3a436b64b..c6945269f 100644 --- a/app/forms/award_years/v2024/international_trade/international_trade_step2.rb +++ b/app/forms/award_years/v2024/international_trade/international_trade_step2.rb @@ -118,7 +118,7 @@ def trade_step2 end date :started_trading, "Date started trading." do - classes "js-started-trading" + classes "js-started-trading date-DDMMYYYY" required ref "B 5" context %( @@ -156,8 +156,9 @@ def trade_step2 style "small" end - press_contact_details :press_contact_details, "Contact details for press enquiries." do + sub_fields :press_contact_details, "Contact details for press enquiries." do ref "B 7" + required context %(

If your application is successful, you may get contacted by the press. diff --git a/app/forms/award_years/v2024/social_mobility/social_mobility_step1.rb b/app/forms/award_years/v2024/social_mobility/social_mobility_step1.rb index f1d2059cd..835cb1834 100644 --- a/app/forms/award_years/v2024/social_mobility/social_mobility_step1.rb +++ b/app/forms/award_years/v2024/social_mobility/social_mobility_step1.rb @@ -12,14 +12,15 @@ def mobility_step1 text "I confirm that I have the consent of the head of my organisation to fill in and submit this entry form." end - head_of_business :head_of_business, "Details of the head of your organisation" do + sub_fields :head_of_business, "Details of the head of your organisation" do sub_ref "A 1.2" + required classes "sub-question" sub_fields([ { title: "Title" }, { first_name: "First name" }, { last_name: "Last name" }, - { honours: "Personal Honours (optional)" }, + { honours: "Personal Honours (optional)", hint: "For example, Lieutenant (LVO), Member of the Most Excellent Order of the British Empire (MBE), Air Force Cross (AFC). Please do not include qualifications such as a master's degree or doctorate." }, { job_title: "Job title or role in the organisation" }, { email: "Email address" } ]) diff --git a/app/forms/award_years/v2024/social_mobility/social_mobility_step2.rb b/app/forms/award_years/v2024/social_mobility/social_mobility_step2.rb index db722a4e0..0bd7cc83f 100644 --- a/app/forms/award_years/v2024/social_mobility/social_mobility_step2.rb +++ b/app/forms/award_years/v2024/social_mobility/social_mobility_step2.rb @@ -116,7 +116,7 @@ def mobility_step2 end date :started_trading, "Date started trading." do - classes "js-started-trading" + classes "js-started-trading date-DDMMYYYY" required ref "B 5" context %( @@ -154,8 +154,9 @@ def mobility_step2 style "small" end - press_contact_details :press_contact_details, "Contact details for press enquiries." do + sub_fields :press_contact_details, "Contact details for press enquiries." do ref "B 7" + required context %(

If your application is successful, you may get contacted by the press. diff --git a/app/forms/award_years/v2024/sustainable_development/sustainable_development_step1.rb b/app/forms/award_years/v2024/sustainable_development/sustainable_development_step1.rb index 513904668..71da8439a 100644 --- a/app/forms/award_years/v2024/sustainable_development/sustainable_development_step1.rb +++ b/app/forms/award_years/v2024/sustainable_development/sustainable_development_step1.rb @@ -13,14 +13,15 @@ def development_step1 text "I confirm that I have the consent of the head of my organisation to fill in and submit this entry form." end - head_of_business :head_of_business, "Details of the head of your organisation" do + sub_fields :head_of_business, "Details of the head of your organisation" do sub_ref "A 1.2" + required classes "sub-question" sub_fields([ { title: "Title" }, { first_name: "First name" }, { last_name: "Last name" }, - { honours: "Personal Honours (optional)" }, + { honours: "Personal Honours (optional)", hint: "For example, Lieutenant (LVO), Member of the Most Excellent Order of the British Empire (MBE), Air Force Cross (AFC). Please do not include qualifications such as a master's degree or doctorate." }, { job_title: "Job title or role in the organisation" }, { email: "Email address" } ]) diff --git a/app/forms/award_years/v2024/sustainable_development/sustainable_development_step2.rb b/app/forms/award_years/v2024/sustainable_development/sustainable_development_step2.rb index 95f31abe6..41d85e431 100644 --- a/app/forms/award_years/v2024/sustainable_development/sustainable_development_step2.rb +++ b/app/forms/award_years/v2024/sustainable_development/sustainable_development_step2.rb @@ -116,7 +116,7 @@ def development_step2 end date :started_trading, "Date started trading." do - classes "js-started-trading" + classes "js-started-trading date-DDMMYYYY" required ref "B 5" context %( @@ -154,8 +154,9 @@ def development_step2 style "small" end - press_contact_details :press_contact_details, "Contact details for press enquiries." do + sub_fields :press_contact_details, "Contact details for press enquiries." do ref "B 7" + required context %(

If your application is successful, you may get contacted by the press. diff --git a/app/forms/qae_form_builder.rb b/app/forms/qae_form_builder.rb index 3bfdb4b01..3c5474fc9 100644 --- a/app/forms/qae_form_builder.rb +++ b/app/forms/qae_form_builder.rb @@ -28,6 +28,7 @@ require "qae_form_builder/position_details_question" require "qae_form_builder/previous_name_question" require "qae_form_builder/country_question" +require "qae_form_builder/sub_fields_question" require "qae_form_builder/address_question" require "qae_form_builder/head_of_business_question" require "qae_form_builder/press_contact_details_question" diff --git a/app/forms/qae_form_builder/address_question.rb b/app/forms/qae_form_builder/address_question.rb index 71162b0b3..cab52cc48 100644 --- a/app/forms/qae_form_builder/address_question.rb +++ b/app/forms/qae_form_builder/address_question.rb @@ -1,27 +1,9 @@ class QAEFormBuilder - class AddressQuestionValidator < QuestionValidator + class AddressQuestionValidator < SubFieldsQuestionValidator NO_VALIDATION_SUB_FIELDS = [:street, :county] - def errors - result = super - - if question.required? - question.required_sub_fields.each do |sub_field| - suffix = sub_field.keys[0] - if !question.input_value(suffix: suffix).present? && NO_VALIDATION_SUB_FIELDS.exclude?(suffix) - result[question.hash_key(suffix: suffix)] ||= "" - result[question.hash_key(suffix: suffix)] << " Can't be blank." - end - end - end - - # need to add govuk-form-group--errors class - result[question.hash_key] ||= "" if result.any? - - result - end end - class AddressQuestionDecorator < QuestionDecorator + class AddressQuestionDecorator < SubFieldsQuestionDecorator include RegionHelper def required_sub_fields @@ -50,15 +32,11 @@ def rendering_sub_fields end end - class AddressQuestionBuilder < QuestionBuilder + class AddressQuestionBuilder < SubFieldsQuestionBuilder def countries(countries) @q.countries = countries end - def sub_fields(fields) - @q.sub_fields = fields - end - def region_context(region_context) @q.region_context = region_context end @@ -68,7 +46,7 @@ def county_context(county_context) end end - class AddressQuestion < Question + class AddressQuestion < SubFieldsQuestion attr_accessor :countries, :sub_fields, :region_context, :county_context end end diff --git a/app/forms/qae_form_builder/checkbox_seria_question.rb b/app/forms/qae_form_builder/checkbox_seria_question.rb index 05ce55ca1..c43a43856 100644 --- a/app/forms/qae_form_builder/checkbox_seria_question.rb +++ b/app/forms/qae_form_builder/checkbox_seria_question.rb @@ -1,7 +1,15 @@ class QAEFormBuilder class CheckboxSeriaQuestionValidator < QuestionValidator def errors - result = super + result = {} + + return {} if skip_base_validation? + + if question.required? + if !question.input_value.present? + result[question.hash_key] = "Question #{question.ref || question.sub_ref} is incomplete. It is required and at least one option must be chosen from the following list." + end + end if question.input_value && question.selection_limit if question.input_value.size > question.selection_limit diff --git a/app/forms/qae_form_builder/confirm_question.rb b/app/forms/qae_form_builder/confirm_question.rb index 7f87e11f0..1417657ca 100644 --- a/app/forms/qae_form_builder/confirm_question.rb +++ b/app/forms/qae_form_builder/confirm_question.rb @@ -1,5 +1,18 @@ class QAEFormBuilder class ConfirmQuestionValidator < QuestionValidator + def errors + result = {} + + return {} if skip_base_validation? + + if question.required? + if !question.input_value.present? + result[question.hash_key] = "Question #{question.ref || question.sub_ref} is incomplete. It is required and confirmation must be given by ticking the checkbox." + end + end + + result + end end class ConfirmQuestionBuilder < QuestionBuilder diff --git a/app/forms/qae_form_builder/date_question.rb b/app/forms/qae_form_builder/date_question.rb index f32058be0..b0a56ca7b 100644 --- a/app/forms/qae_form_builder/date_question.rb +++ b/app/forms/qae_form_builder/date_question.rb @@ -16,17 +16,17 @@ def errors if !date if question.required? result[question.hash_key] ||= "" - result[question.hash_key] << " Invalid date." + result[question.hash_key] << "Question #{question.ref || question.sub_ref} is incomplete. It requires a date in the format DD/MM/YYYY." end else if date_min && date < date_min result[question.hash_key] ||= "" - result[question.hash_key] << " Date should be greater than #{date_min.strftime('%d/%m/%Y')}." + result[question.hash_key] << "Question #{question.ref || question.sub_ref} is incomplete. Date should be after #{date_min.strftime('%d/%m/%Y')}." end if date_max && date > date_max result[question.hash_key] ||= "" - result[question.hash_key] << " Date should be less than #{date_max.strftime('%d/%m/%Y')}." + result[question.hash_key] << "Question #{question.ref || question.sub_ref} is incomplete. Date should be before #{date_max.strftime('%d/%m/%Y')}." end end diff --git a/app/forms/qae_form_builder/innovation_financial_year_date_question.rb b/app/forms/qae_form_builder/innovation_financial_year_date_question.rb index 7c8ba036c..698f370cd 100644 --- a/app/forms/qae_form_builder/innovation_financial_year_date_question.rb +++ b/app/forms/qae_form_builder/innovation_financial_year_date_question.rb @@ -14,7 +14,7 @@ def errors if !date && question.required? result[question.hash_key] ||= "" - result[question.hash_key] << " Invalid date." + result[question.hash_key] << "#{question.ref || question.sub_ref} is incomplete. Year-end is required. Use the format MM/YYYY" end result diff --git a/app/forms/qae_form_builder/multi_question_validator.rb b/app/forms/qae_form_builder/multi_question_validator.rb index f0e59d9fd..695da6125 100644 --- a/app/forms/qae_form_builder/multi_question_validator.rb +++ b/app/forms/qae_form_builder/multi_question_validator.rb @@ -7,7 +7,7 @@ def errors if !entity[attr].present? result[question.key] ||= {} result[question.key][index] ||= "" - result[question.key][index] << " #{attr.humanize.capitalize} can't be blank." + result[question.key][index] << "Question #{question.ref || question.sub_ref} is incomplete. #{attr.humanize} can't be blank." end end end diff --git a/app/forms/qae_form_builder/options_question.rb b/app/forms/qae_form_builder/options_question.rb index d3f435492..7ad8b4634 100644 --- a/app/forms/qae_form_builder/options_question.rb +++ b/app/forms/qae_form_builder/options_question.rb @@ -1,5 +1,18 @@ class QAEFormBuilder class OptionsQuestionValidator < QuestionValidator + def errors + result = {} + + return {} if skip_base_validation? + + if question.required? + if !question.input_value.present? + result[question.hash_key] = "Question #{question.ref || question.sub_ref} is incomplete. It is required and an option must be chosen from the following list." + end + end + + result + end end QuestionAnswerOption = Struct.new(:value, :text) diff --git a/app/forms/qae_form_builder/question.rb b/app/forms/qae_form_builder/question.rb index d28342944..0bff6308d 100644 --- a/app/forms/qae_form_builder/question.rb +++ b/app/forms/qae_form_builder/question.rb @@ -3,6 +3,7 @@ class QuestionValidator # multifield questions that can not be simply validated SKIP_PRESENCE_VALIDATION_QUESTIONS = [ "DateQuestion", + "SubFieldsQuestion", "AddressQuestion", "InnovationFinancialYearDateQuestion", "ByYearsQuestion", @@ -32,7 +33,7 @@ def errors if question.required? if !question.input_value.present? - result[question.hash_key] = "Can't be blank." + result[question.hash_key] = "Question #{question.ref || question.sub_ref} is incomplete. It is required and and must be filled in." end end @@ -127,6 +128,7 @@ def label_as_legend? "by_years_label_question", "matrix_question", "press_contact_details_question", + "sub_fields_question", "upload_question" ] diff --git a/app/forms/qae_form_builder/sic_code_dropdown_question.rb b/app/forms/qae_form_builder/sic_code_dropdown_question.rb index e6824aab4..e054e0e1a 100644 --- a/app/forms/qae_form_builder/sic_code_dropdown_question.rb +++ b/app/forms/qae_form_builder/sic_code_dropdown_question.rb @@ -1,5 +1,17 @@ class QAEFormBuilder class SicCodeDropdownQuestionValidator < QuestionValidator + def errors + result = super + + if question.required? + if !question.input_value.present? + result[question.hash_key] ||= "" + result[question.hash_key] = "Question #{question.ref || question.sub_ref} is incomplete. It is required and and an option must be selected from the following dropdown list." + end + end + + result + end end class SicCodeDropdownQuestionBuilder < DropdownQuestionBuilder diff --git a/app/forms/qae_form_builder/sub_fields_question.rb b/app/forms/qae_form_builder/sub_fields_question.rb new file mode 100644 index 000000000..3b1c6b7f8 --- /dev/null +++ b/app/forms/qae_form_builder/sub_fields_question.rb @@ -0,0 +1,46 @@ +class QAEFormBuilder + class SubFieldsQuestionValidator < QuestionValidator + NO_VALIDATION_SUB_FIELDS = [:honours] + def errors + result = super + + if question.required? + question.required_sub_fields.each do |sub_field| + suffix = sub_field.keys[0] + if !question.input_value(suffix: suffix).present? && NO_VALIDATION_SUB_FIELDS.exclude?(suffix) + result[question.hash_key(suffix: suffix)] ||= "" + result[question.hash_key(suffix: suffix)] << "Question #{question.ref || question.sub_ref} is incomplete. #{suffix.to_s.humanize} is required and and must be filled in." + end + end + end + + # need to add govuk-form-group--errors class + result[question.hash_key] ||= "" if result.any? + + result + end + end + + class SubFieldsQuestionDecorator < QuestionDecorator + def required_sub_fields + sub_fields + end + + def rendering_sub_fields + required_sub_fields.map do |f| + {key: f.keys.first, title: f.values.first, hint: f.try(:[], :hint)} + end + end + end + + class SubFieldsQuestionBuilder < QuestionBuilder + def sub_fields fields + @q.sub_fields = fields + end + end + + class SubFieldsQuestion < Question + attr_accessor :sub_fields + end + +end diff --git a/app/forms/qae_form_builder/year_question.rb b/app/forms/qae_form_builder/year_question.rb index b19177716..4b3ad4c10 100644 --- a/app/forms/qae_form_builder/year_question.rb +++ b/app/forms/qae_form_builder/year_question.rb @@ -3,6 +3,13 @@ class YearQuestionValidator < QuestionValidator def errors result = super + if question.required? + if !question.input_value.present? + result[question.hash_key] ||= "" + result[question.hash_key] = "Question #{question.ref || question.sub_ref} is incomplete. It is required and and must be filled in. Use the format YYYY." + end + end + year = question.input_value.to_i if year < question.min || year > question.max diff --git a/app/javascript/admin.js b/app/javascript/admin.js new file mode 100644 index 000000000..2d08e9bc9 --- /dev/null +++ b/app/javascript/admin.js @@ -0,0 +1,6 @@ +import { Application } from '@hotwired/stimulus'; +import { definitionsFromContext } from '@hotwired/stimulus-webpack-helpers'; + +const application = Application.start(); +const context = require.context('controllers', true, /_controller\.js$/); +application.load(definitionsFromContext(context)); diff --git a/app/javascript/application_controller.js b/app/javascript/application_controller.js new file mode 100644 index 000000000..a42e264de --- /dev/null +++ b/app/javascript/application_controller.js @@ -0,0 +1,35 @@ +import { Controller } from '@hotwired/stimulus'; + +export default class extends Controller { + get classList() { + return this.element.classList; + } + + get csrfToken() { + return this.metaValue('csrf-token'); + } + + dispatch(eventName, { target = this.element, detail = {}, bubbles = true, cancelable = true } = {}) { + const type = `${this.identifier}:${eventName}`; + const event = new CustomEvent(type, { detail, bubbles, cancelable }); + target.dispatchEvent(event); + return event; + } + + observeMutations(callback, target = this.element, options = { childList: true, subtree: true }) { + const observer = new MutationObserver((mutations) => { + observer.disconnect(); + Promise.resolve().then(start); // eslint-disable-line no-use-before-define + callback.call(this, mutations); + }); + function start() { + if (target.isConnected) observer.observe(target, options); + } + start(); + } + + metaValue(name) { + const element = document.head.querySelector(`meta[name="${name}"]`); + return element && element.getAttribute('content'); + } +} diff --git a/app/javascript/controllers/autofocus_first_element_controller.js b/app/javascript/controllers/autofocus_first_element_controller.js new file mode 100644 index 000000000..68d54d6b6 --- /dev/null +++ b/app/javascript/controllers/autofocus_first_element_controller.js @@ -0,0 +1,7 @@ +export default class extends ApplicationController { + static targets = ['element']; + + connect() { + this.elementTargets[0].focus(); + } +} diff --git a/app/javascript/controllers/element_focus_controller.js b/app/javascript/controllers/element_focus_controller.js new file mode 100644 index 000000000..88189b0f2 --- /dev/null +++ b/app/javascript/controllers/element_focus_controller.js @@ -0,0 +1,50 @@ +export default class extends ApplicationController { + static targets = ['reveal', 'dismiss']; + static values = { + selector: String + } + + connect() { + if (this.hasRevealTarget) { + this.revealTarget.addEventListener('click', () => setTimeout(() => this.focusFirstElement(), 1)) + } + + if (this.hasDismissTarget) { + this.dismissTarget.addEventListener('click', () => setTimeout(() => this.focusElement(), 1)) + } + } + + focusElement(_event) { + if (this.hasRevealTarget && this.focusable(this.revealTarget)) { + this.revealTarget.focus() + } + } + + focusFirstElement(_event) { + const element = this.focusableElements[0] + + if (element) { + element.focus() + } + } + + // Private + + visible(el) { + return !el.hidden && (!el.type || el.type != 'hidden') && (el.offsetWidth > 0 || el.offsetHeight > 0) + } + + focusable(el) { + return el.tabIndex >= 0 && !el.disabled && this.visible(el) + } + + get focusableElements() { + return Array.from(this.element.querySelectorAll(this.selectors)).filter((el) => this.focusable(el)) || [] + } + + get selectors() { + return this.hasSelectorValue ? + this.selectorValue : + 'input:not([disabled]), select:not([disabled]), textarea:not([disabled])' + } +} diff --git a/app/javascript/controllers/element_removal_controller.js b/app/javascript/controllers/element_removal_controller.js new file mode 100644 index 000000000..7341e71d5 --- /dev/null +++ b/app/javascript/controllers/element_removal_controller.js @@ -0,0 +1,5 @@ +export default class extends ApplicationController { + remove() { + this.element.remove(); + } +} diff --git a/app/javascript/controllers/inline_flash_controller.js b/app/javascript/controllers/inline_flash_controller.js new file mode 100644 index 000000000..481c3316e --- /dev/null +++ b/app/javascript/controllers/inline_flash_controller.js @@ -0,0 +1,70 @@ +export default class extends ApplicationController { + static targets = ['form', 'link']; + + static values = { + error: String, + success: String, + }; + + connect() { + this.formTargets.forEach((el) => { + el.addEventListener('ajax:x:success', this.onSuccess); + el.addEventListener('ajax:x:error', this.onError); + }); + } + + disconnect() { + this.formTargets.forEach((el) => { + el.removeEventListener('ajax:x:success', this.onSuccess); + el.removeEventListener('ajax:x:error', this.onError); + }); + } + + success(event) { + return this.onSuccess(event); + } + + error(event) { + return this.onError(event); + } + + onSuccess = (event) => { + const msg = this.hasSuccessValue ? this.successValue : 'Success!'; + const [alert, identifier] = this.createAlert('success', msg); + + setTimeout(() => this.showAlert(alert, identifier), 1); + }; + + onError = (event) => { + const msg = this.hasErrorValue ? this.errorValue : 'An unknown error has occurred, please try again.'; + const [alert, identifier] = this.createAlert('danger', msg); + + setTimeout(() => this.showAlert(alert, identifier), 1); + }; + + createAlert = (type, message) => { + const id = 'alert__' + String(Math.random()).slice(2, -1); + const element = ` +

+ `; + + return [element, id]; + }; + + showAlert = (alert, identifier) => { + const existing = this.element.querySelector('[id*=alert__]') + if (existing) existing.remove() + + this.element.insertAdjacentHTML('afterbegin', alert); + + setTimeout(() => { + const inserted = document.getElementById(identifier); + if (inserted) inserted.remove(); + }, 4000); + }; +} diff --git a/app/javascript/packs/application-admin.js b/app/javascript/packs/application-admin.js new file mode 100644 index 000000000..cc47ae7d7 --- /dev/null +++ b/app/javascript/packs/application-admin.js @@ -0,0 +1 @@ +require('admin') \ No newline at end of file diff --git a/app/models/form_answer.rb b/app/models/form_answer.rb index ad2b218b7..afe2a8841 100644 --- a/app/models/form_answer.rb +++ b/app/models/form_answer.rb @@ -16,7 +16,7 @@ class FormAnswer < ApplicationRecord has_paper_trail - attr_accessor :current_step, :validator_errors, :steps_with_errors + attr_accessor :current_step, :validator_errors, :steps_with_errors, :current_non_js_step pg_search_scope :basic_search, against: [ @@ -550,7 +550,8 @@ def set_user_info end def validate_answers - if submitted? && (current_step || (submitted_at_changed? && submitted_at_was.nil?)) + if current_non_js_step.present? || (submitted? && (current_step || (submitted_at_changed? && submitted_at_was.nil?))) + validator = FormAnswerValidator.new(self) unless validator.valid? diff --git a/app/validators/form_answer_validator.rb b/app/validators/form_answer_validator.rb index dac2d99e6..ae9ade64a 100644 --- a/app/validators/form_answer_validator.rb +++ b/app/validators/form_answer_validator.rb @@ -16,11 +16,14 @@ def valid? award_form.steps.each do |step| # if form was submitted before + # or it's a non-js form # we should validate current step # else if form was submitted just now # we should validate entire form - if step.title.parameterize == current_step || (form_answer.submitted_at_changed? && form_answer.submitted_at_was.nil?) + non_js_save = step.title.parameterize == form_answer.current_non_js_step && form_answer.submitted_at.nil? + + if step.title.parameterize == current_step || non_js_save || (form_answer.submitted_at_changed? && form_answer.submitted_at_was.nil?) step.questions.each do |q| if (errors = q.validate).any? @errors.merge!(errors) diff --git a/app/views/admin/admins/_form.html.slim b/app/views/admin/admins/_form.html.slim index 15ec8cd34..4e84f3c8f 100644 --- a/app/views/admin/admins/_form.html.slim +++ b/app/views/admin/admins/_form.html.slim @@ -26,6 +26,14 @@ .question-group#password-change-panel #password-control-group h3 = f.label :password, class: "form-label" + .guidance-panel.if-no-js-hide + .govuk-form-group--error#password-guidance + p.govuk-error-message.text-underline Please improve your password + p.govuk-error-message#password-too-short + ' It must be at least 10 characters. + p.govuk-error-message#parts-of-email It shouldn't include part or all of your email address. + p.govuk-error-message#password-entropy + ' It must be more complex. Consider using whole sentences (with spaces), lyrics or phrases to make it more memorable. .row .col-md-4.col-sm-6 .input-group @@ -33,23 +41,15 @@ wrapper_html: { class: 'form-group' }, input_html: { class: 'form-control', "data-min-password-length" => "10" }, label: false - span#password-result-span.input-group-addon + span#password-result-span.input-group-addon.hide i#password-result.glyphicon.glyphicon-ok .clear - .guidance-panel.if-no-js-hide - #password-guidance - br - .alert.alert-warning - p.text-underline Please improve your password - p#password-too-short - ' It must be at least 10 characters. - p#parts-of-email It shouldn't include part or all of your email address. - p#password-entropy - ' It must be more complex. Consider using whole sentences (with spaces), lyrics or phrases to make it more memorable. - #password-confirmation-control-group h3 = f.label :password_confirmation, label: "Retype password", class: "form-label" + .if-no-js-hide + .govuk-form-group--error#password-confirmation-guidance + p.govuk-error-message#password-confirmation-match The confirmation must match the password .row .col-md-4.col-sm-6 .input-group @@ -57,16 +57,10 @@ wrapper_html: { class: 'form-group' }, input_html: { class: 'form-control' }, label: false - span#password-confirmation-result-span.input-group-addon + span#password-confirmation-result-span.input-group-addon.hide i#password-confirmation-result.glyphicon.glyphicon-ok .clear - .if-no-js-hide - #password-confirmation-guidance - br - .alert.alert-warning - p#password-confirmation-match The confirmation must match the password - br .row .col-md-4.col-sm-6 diff --git a/app/views/admin/assessors/_form.html.slim b/app/views/admin/assessors/_form.html.slim index 2a1b556d3..62a9ab399 100644 --- a/app/views/admin/assessors/_form.html.slim +++ b/app/views/admin/assessors/_form.html.slim @@ -42,6 +42,14 @@ .question-group#password-change-panel #password-control-group h2 = f.label :password, class: "form-label" + .guidance-panel.if-no-js-hide + .govuk-form-group--error#password-guidance + p.govuk-error-message.text-underline Please improve your password + p.govuk-error-message#password-too-short + ' It must be at least 10 characters. + p.govuk-error-message#parts-of-email It shouldn't include part or all of your email address. + p.govuk-error-message#password-entropy + ' It must be more complex. Consider using whole sentences (with spaces), lyrics or phrases to make it more memorable. .row .col-md-4.col-sm-6 .input-group @@ -49,22 +57,15 @@ wrapper_html: { class: 'form-group' }, input_html: { class: 'form-control' }, label: false - span#password-result-span.input-group-addon + span#password-result-span.input-group-addon.hide i#password-result.glyphicon.glyphicon-ok .clear - .guidance-panel.if-no-js-hide - #password-guidance - br - .alert.alert-warning - p.text-underline Please improve your password - p#password-too-short - ' It must be at least 10 characters. - p#parts-of-email It shouldn't include part or all of your email address. - p#password-entropy - ' It must be more complex. Consider using whole sentences (with spaces), lyrics or phrases to make it more memorable. #password-confirmation-control-group h2 = f.label :password_confirmation, label: "Retype password", class: "form-label" + .if-no-js-hide + .govuk-form-group--error#password-confirmation-guidance + p.govuk-error-message#password-confirmation-match The confirmation must match the password .row .col-md-4.col-sm-6 .input-group @@ -72,16 +73,10 @@ wrapper_html: { class: 'form-group' }, input_html: { class: 'form-control' }, label: false - span#password-confirmation-result-span.input-group-addon + span#password-confirmation-result-span.input-group-addon.hide i#password-confirmation-result.glyphicon.glyphicon-ok .clear - .if-no-js-hide - #password-confirmation-guidance - br - .alert.alert-warning - p#password-confirmation-match The confirmation must match the password - br .row diff --git a/app/views/admin/audit_certificate/_form.html.slim b/app/views/admin/audit_certificate/_form.html.slim index 8bb91ff40..fb1a48c3a 100644 --- a/app/views/admin/audit_certificate/_form.html.slim +++ b/app/views/admin/audit_certificate/_form.html.slim @@ -3,7 +3,7 @@ / whether file was saved or not .span = hidden_field_tag "valid", "false", id: "form-audit_certificate-valid" -= form_for [namespace_name, form_answer, audit_certificate], html: { multipart: true } do |form| += form_for [namespace_name, form_answer, audit_certificate], html: { multipart: true, data: { inline_flash_target: "form" } } do |form| .well.js-attachment-form h3 Attach document diff --git a/app/views/admin/comments/_form.html.slim b/app/views/admin/comments/_form.html.slim index 492dacfb3..f56bb24bd 100644 --- a/app/views/admin/comments/_form.html.slim +++ b/app/views/admin/comments/_form.html.slim @@ -2,7 +2,7 @@ label ' Add a comment = f.hidden_field :section, id: "#{f.object.section}_section_hidden_field" - = f.text_area :body, id: "#{f.object.section}_comment_body", class: 'form-control', rows: 4, "data-behavior" => "autosave", "data-autosave-key" => "#{@form_answer.id}-#{f.object.section}-new-comment" + = f.text_area :body, id: "#{f.object.section}_comment_body", autofocus: true, class: 'form-control', rows: 4, "data-behavior" => "autosave", "data-autosave-key" => "#{@form_answer.id}-#{f.object.section}-new-comment" .comment-actions = f.check_box :flagged, id: "#{f.object.section}_flagged_hidden_checkbox" = link_to "#flag-comment", class: "link-flag-comment js-link-flag-comment" diff --git a/app/views/admin/email_notifications/create.js.erb b/app/views/admin/email_notifications/create.js.erb index 867231a8c..2a98249bb 100644 --- a/app/views/admin/email_notifications/create.js.erb +++ b/app/views/admin/email_notifications/create.js.erb @@ -6,6 +6,8 @@ wrapper = $("#email_notification_" + "<%= @email_notification.kind %>"); $(".new_email_notification .timepicker", wrapper).val(null); $(".new_email_notification .datepicker", wrapper).val(null); + window.fire($(".new_email_notification", wrapper)[0], 'ajax:x:success', null) <% else %> $(".notification-form input", wrapper).closest(".input").addClass("field-with-errors"); + window.fire($(".new_email_notification", wrapper)[0], 'ajax:x:error', null) <% end %> diff --git a/app/views/admin/email_notifications/update.js.erb b/app/views/admin/email_notifications/update.js.erb index 3d103a7c7..3d0c49cbf 100644 --- a/app/views/admin/email_notifications/update.js.erb +++ b/app/views/admin/email_notifications/update.js.erb @@ -7,6 +7,8 @@ wrapper = $("#notification-" + "<%= @email_notification.id %>"); $(".notification-edit-form input.datepicker", wrapper).val("<%= @email_notification.formatted_trigger_at_date %>"); $(".notification-edit-form input.timepicker", wrapper).val("<%= @email_notification.formatted_trigger_at_time %>"); $(".trigger-at", wrapper).html("<%= @email_notification.decorate.formatted_trigger_time %>"); + window.fire($(".edit_email_notification", wrapper)[0], 'ajax:x:success', null) <% else %> $(".notification-edit-form input", wrapper).closest(".input").addClass("field-with-errors"); + window.fire($(".edit_email_notification", wrapper)[0], 'ajax:x:error', null) <% end %> diff --git a/app/views/admin/feedbacks/_feedback_fields.html.slim b/app/views/admin/feedbacks/_feedback_fields.html.slim index 76fa39fb2..460397528 100644 --- a/app/views/admin/feedbacks/_feedback_fields.html.slim +++ b/app/views/admin/feedbacks/_feedback_fields.html.slim @@ -1,4 +1,4 @@ -.form-group +.form-group[data-controller="element-focus"] .form-container strong = feedback_field_value[:label] .form-group class=feedback_field @@ -25,10 +25,10 @@ .clear - if policy(feedback).update? - = link_to "#", class: "form-edit-link pull-right" do + = link_to "#", class: "form-edit-link pull-right", data: { element_focus_target: "reveal" } do span.glyphicon.glyphicon-pencil ' Edit .form-actions.text-right - = link_to "Cancel", "#", class: "btn btn-default form-cancel-link if-no-js-hide" + = link_to "Cancel", "#", class: "btn btn-default form-cancel-link if-no-js-hide", data: { element_focus_target: "dismiss" } = link_to "Save", "#", class: "btn btn-primary form-save-link pull-right" .clear diff --git a/app/views/admin/feedbacks/_overall_feedback_field.html.slim b/app/views/admin/feedbacks/_overall_feedback_field.html.slim index d6b8e3020..3a8dc769c 100644 --- a/app/views/admin/feedbacks/_overall_feedback_field.html.slim +++ b/app/views/admin/feedbacks/_overall_feedback_field.html.slim @@ -1,4 +1,4 @@ -.form-group +.form-group[data-controller="element-focus"] .form-container strong Overall Summary .form-value.no-js-update @@ -11,10 +11,10 @@ .clear - if policy(feedback).update? - = link_to "#", class: "form-edit-link pull-right" do + = link_to "#", class: "form-edit-link pull-right", data: { element_focus_target: "reveal" } do span.glyphicon.glyphicon-pencil ' Edit .form-actions.text-right - = link_to "Cancel", "#", class: "btn btn-default form-cancel-link if-no-js-hide" + = link_to "Cancel", "#", class: "btn btn-default form-cancel-link if-no-js-hide", data: { element_focus_target: "dismiss" } = link_to "Save", "#", class: "btn btn-primary form-save-link pull-right" .clear diff --git a/app/views/admin/feedbacks/_section.html.slim b/app/views/admin/feedbacks/_section.html.slim index 067a9760f..d27eab339 100644 --- a/app/views/admin/feedbacks/_section.html.slim +++ b/app/views/admin/feedbacks/_section.html.slim @@ -1,6 +1,6 @@ - feedback = form_answer.feedback.present? ? form_answer.feedback : form_answer.build_feedback - url = feedback.persisted? ? polymorphic_url([namespace_name, form_answer, feedback]) : polymorphic_url([namespace_name, form_answer, :feedbacks]) -= simple_form_for feedback, url: url, remote: true, authenticity_token: true, html: { "data-type" => "json" } do |f| += simple_form_for feedback, url: url, remote: true, authenticity_token: true, html: { data: { type: "json", inline_flash_target: "form" } } do |f| - if !form_answer.promotion? = render "admin/feedbacks/overall_feedback_field", f: f, feedback: feedback - FeedbackForm.fields_for_award_type(form_answer.object).each do |feedback_field, feedback_field_value| diff --git a/app/views/admin/figures_and_vat_returns/_form.html.slim b/app/views/admin/figures_and_vat_returns/_form.html.slim index c8fcb55b5..4381b4635 100644 --- a/app/views/admin/figures_and_vat_returns/_form.html.slim +++ b/app/views/admin/figures_and_vat_returns/_form.html.slim @@ -3,7 +3,7 @@ / whether file was saved or not .span = hidden_field_tag "valid", "false", id: "#{attachment.model_name.param_key}-valid" -= form_for [namespace_name, form_answer, attachment], html: { multipart: true } do |form| += form_for [namespace_name, form_answer, attachment], html: { multipart: true, data: { inline_flash_target: "form" } } do |form| .well.js-attachment-form h3 Attach document diff --git a/app/views/admin/form_answer_attachments/_form_answer_attachment.html.slim b/app/views/admin/form_answer_attachments/_form_answer_attachment.html.slim index a0d809744..7a2d2bfe2 100644 --- a/app/views/admin/form_answer_attachments/_form_answer_attachment.html.slim +++ b/app/views/admin/form_answer_attachments/_form_answer_attachment.html.slim @@ -4,7 +4,7 @@ - if show_remove_form_answer_attachment?(form_answer_attachment) small.pull-right = form_for([namespace_name, form_answer_attachment.form_answer, form_answer_attachment], - html: { method: :delete, style: "display:inline-block;"}) do |f| + html: { data: { inline_flash_target: "form" }, method: :delete, style: "display: inline-block;" }) do |f| = f.submit 'Remove', class: 'if-js-hide' diff --git a/app/views/admin/form_answers/_assessors_section.html.slim b/app/views/admin/form_answers/_assessors_section.html.slim index ea5aaf0a1..1308de427 100644 --- a/app/views/admin/form_answers/_assessors_section.html.slim +++ b/app/views/admin/form_answers/_assessors_section.html.slim @@ -12,7 +12,7 @@ = resource.lead_assessors .clear - li.form-group.primary-assessor-assignment + li.form-group.primary-assessor-assignment[data-controller="element-focus inline-flash"] label[for='assessor_assignment_primary_assessor_id'] ' Primary: .form-value class=("ellipsis edit-value" if policy(resource).assign_assessor?) @@ -25,7 +25,7 @@ - if policy(resource).assign_assessor? = form_for [namespace_name, resource.assessor_assignments.primary], remote: true, - html: { "data-type" => "json"}, + html: { data: { type: "json", inline_flash_target: "form" } }, authenticity_token: true do |form| .form-fields @@ -35,18 +35,18 @@ id: 'assessor_assignment_primary_assessor_id', class: 'form-control custom-select' - = link_to "#", class: "form-edit-link" + = link_to "#", class: "form-edit-link", data: { element_focus_target: "reveal" } span.glyphicon.glyphicon-pencil ' Edit .clear .form-actions.text-right span.if-no-js-hide - = link_to "Cancel", "#", class: "btn btn-default form-cancel-link" + = link_to "Cancel", "#", class: "btn btn-default form-cancel-link", data: { element_focus_target: "dismiss" } = form.submit "Save", class: "btn btn-primary form-save-button" .errors-holder .clear - li.form-group.secondary-assessor-assignment + li.form-group.secondary-assessor-assignment[data-controller="element-focus inline-flash"] label[for='assessor_assignment_secondary_assessor_id'] span.assessor-label Secondary: .form-value class=("ellipsis edit-value" if policy(resource).assign_assessor?) @@ -59,7 +59,7 @@ - if policy(resource).assign_assessor? = form_for [namespace_name, resource.assessor_assignments.secondary], remote: true, - html: { "data-type" => "json" }, + html: { data: { type: "json", inline_flash_target: "form" } }, authenticity_token: true do |form| .form-fields @@ -69,13 +69,13 @@ id: 'assessor_assignment_secondary_assessor_id', class: 'form-control custom-select' - = link_to "#", class: "form-edit-link" + = link_to "#", class: "form-edit-link", data: { element_focus_target: "reveal" } span.glyphicon.glyphicon-pencil ' Edit .clear .form-actions.text-right span.if-no-js-hide - = link_to "Cancel", "#", class: "btn btn-default form-cancel-link" + = link_to "Cancel", "#", class: "btn btn-default form-cancel-link", data: { element_focus_target: "dismiss" } = form.submit "Save", class: "btn btn-primary form-save-button" .errors-holder .clear diff --git a/app/views/admin/form_answers/_financials_review.html.slim b/app/views/admin/form_answers/_financials_review.html.slim index cfe20d894..082ed2b1a 100644 --- a/app/views/admin/form_answers/_financials_review.html.slim +++ b/app/views/admin/form_answers/_financials_review.html.slim @@ -6,11 +6,12 @@ - if policy(review_audit_certificate).create? = simple_form_for([namespace_name, review_audit_certificate], remote: true, - authenticity_token: true) do |f| + authenticity_token: true, + html: { controller: "inline-flash", inline_flash_target: "form" }) do |f| = f.input :form_answer_id, as: :hidden - .form-group + .form-group[data-controller="element-focus"] = render "admin/form_answers/financial_summary/audit_certificate" .input.form-group.form-fields .radio @@ -27,12 +28,12 @@ .input.form-group.form-fields.form-block = f.input :changes_description, as: :text, input_html: { rows: 5, class: "form-control" }, label: "Changes made" .clear - = link_to "#", class: "form-edit-link pull-right edit-review-audit" + = link_to "#", class: "form-edit-link pull-right edit-review-audit", data: { element_focus_target: "reveal" } span.glyphicon.glyphicon-pencil ' Edit .form-actions.text-left .form-fields - = link_to "Cancel", "#", class: "btn btn-default form-cancel-link if-no-js-hide" + = link_to "Cancel", "#", class: "btn btn-default form-cancel-link if-no-js-hide", data: { element_focus_target: "dismiss" } = link_to "Save", "#", class: "btn btn-primary save-review-audit pull-right", style: "display: none" .clear @@ -49,11 +50,12 @@ remote: true, url: [namespace_name, :review_commercial_figures], method: :post, - authenticity_token: true) do |f| + authenticity_token: true, + html: { controller: "inline-flash", inline_flash_target: "form" }) do |f| = f.input :form_answer_id, as: :hidden - .form-group + .form-group[data-controller="element-focus"] = render "admin/form_answers/financial_summary/shortlisted_financial_docs", docs_wrapper: resource.shortlisted_documents_wrapper .input.form-group.form-fields .radio diff --git a/app/views/admin/form_answers/_section_admin_comments.html.slim b/app/views/admin/form_answers/_section_admin_comments.html.slim index 0b9caabda..988212316 100644 --- a/app/views/admin/form_answers/_section_admin_comments.html.slim +++ b/app/views/admin/form_answers/_section_admin_comments.html.slim @@ -1,7 +1,7 @@ -.panel.panel-default +.panel.panel-default[data-controller="element-focus"] .panel-heading#admin-comments-heading h3.panel-title - a data-toggle="collapse" data-parent="#panel-application-info" href="#section-admin-comments" aria-expanded="true" aria-controls="section-admin-comments" + a data-toggle="collapse" data-parent="#panel-application-info" href="#section-admin-comments" aria-expanded="true" aria-controls="section-admin-comments" data-element-focus-target="reveal" ' Admin Comments span.comments-number - if @form_answer.comments.admin.any? @@ -17,9 +17,9 @@ #section-admin-comments.section-admin-comments.panel-collapse.collapse aria-labelledby="admin-comments-heading" .panel-body - .comments-container data-comment-form=new_admin_form_answer_comment_path(@form_answer) + .comments-container[data-comment-form=new_admin_form_answer_comment_path(@form_answer) data-controller="inline-flash"] - if !(defined? read_only) - = form_for([:admin, @form_answer, @form_answer.comments.new(section: "admin")], html: { id: "admin_comment_form" }) do |f| + = form_for([:admin, @form_answer, @form_answer.comments.new(section: "admin")], html: { id: "admin_comment_form", data: { inline_flash_target: "form" } }) do |f| = render('admin/comments/form', f: f) .comment-insert - if !(defined? read_only) diff --git a/app/views/admin/form_answers/_section_appraisal_form_moderated.html.slim b/app/views/admin/form_answers/_section_appraisal_form_moderated.html.slim index b586e4574..e89cc2c72 100644 --- a/app/views/admin/form_answers/_section_appraisal_form_moderated.html.slim +++ b/app/views/admin/form_answers/_section_appraisal_form_moderated.html.slim @@ -7,12 +7,12 @@ small = moderated_assessment.last_editor_info - #section-appraisal-form-moderated.section-appraisal-form.section-appraisal-form-moderated.panel-collapse.collapse aria-labelledby="appraisal-form-moderated-heading" - .panel-body + #section-appraisal-form-moderated.section-appraisal-form.section-appraisal-form-moderated.panel-collapse.collapse[aria-labelledby="appraisal-form-moderated-heading"] + .panel-body[data-controller="inline-flash"] = simple_form_for([namespace_name, moderated_assessment], remote: true, authenticity_token: true, - html: { "data-type" => "json"}) do |f| + html: { data: { type: "json", inline_flash_target: "form" } }) do |f| = render_section(resource, f) = hidden_field_tag :updated_section diff --git a/app/views/admin/form_answers/_section_appraisal_form_primary.html.slim b/app/views/admin/form_answers/_section_appraisal_form_primary.html.slim index 6662b3076..3dcd6f6d6 100644 --- a/app/views/admin/form_answers/_section_appraisal_form_primary.html.slim +++ b/app/views/admin/form_answers/_section_appraisal_form_primary.html.slim @@ -7,12 +7,11 @@ small = primary_assessment.last_editor_info #section-appraisal-form-primary.section-appraisal-form.section-appraisal-form-primary.panel-collapse.collapse aria-labelledby="appraisal-form-primary-heading" - .panel-body - + .panel-body[data-controller="inline-flash"] = simple_form_for([namespace_name, primary_assessment], remote: true, authenticity_token: true, - html: { "data-type" => "json", id: "primary_appraisal_form" }) do |f| + html: { data: { type: "json", inline_flash_target: "form" }, id: "primary_appraisal_form" }) do |f| = hidden_field_tag :updated_section, nil, id: "primary_updated_section_hidden_field" = render_section(resource, f) diff --git a/app/views/admin/form_answers/_section_appraisal_form_secondary.html.slim b/app/views/admin/form_answers/_section_appraisal_form_secondary.html.slim index 6581f710b..3324b5a4a 100644 --- a/app/views/admin/form_answers/_section_appraisal_form_secondary.html.slim +++ b/app/views/admin/form_answers/_section_appraisal_form_secondary.html.slim @@ -7,12 +7,11 @@ small = secondary_assessment.last_editor_info #section-appraisal-form-secondary.section-appraisal-form.section-appraisal-form-secondary.panel-collapse.collapse aria-labelledby="appraisal-form-secondary-heading" - .panel-body - + .panel-body[data-controller="inline-flash"] = simple_form_for([namespace_name, secondary_assessment], remote: true, authenticity_token: true, - html: { "data-type" => "json", id: "secondary_appraisal_form"}) do |f| + html: { data: { type: "json", inline_flash_target: "form" }, id: "secondary_appraisal_form"}) do |f| = hidden_field_tag :updated_section, nil, id: "secondary_updated_section_hidden_field" = render_section(resource, f) diff --git a/app/views/admin/form_answers/_section_case_summary.html.slim b/app/views/admin/form_answers/_section_case_summary.html.slim index 1dd043273..04fdcd52d 100644 --- a/app/views/admin/form_answers/_section_case_summary.html.slim +++ b/app/views/admin/form_answers/_section_case_summary.html.slim @@ -13,7 +13,7 @@ = "Updated by #{message_author_name(assessment.editable)} - #{format_date(assessment.updated_at)}" .panel-collapse.collapse aria-labelledby="case-summary-heading-#{assessment.position}" id="section-case-summary-#{assessment.position}" class="section-case-summary-#{assessment.position}" - .panel-body + .panel-body[data-controller="inline-flash"] /.alert.alert-glyphicon.alert-info span.glyphicon.glyphicon-info-sign p.todo-placeholder @@ -23,7 +23,7 @@ / For Primary Assessor / It becomes read-only for primary assessor after submission - = simple_form_for([namespace_name, assessment], remote: true, authenticity_token: true) do |f| + = simple_form_for([namespace_name, assessment], remote: true, authenticity_token: true, html: { data: { inline_flash_target: "form" } }) do |f| = render partial: "admin/form_answers/appraisal_form_components/application_background_section", locals: { f: f} = render_section(resource, f) diff --git a/app/views/admin/form_answers/_section_company_details.html.slim b/app/views/admin/form_answers/_section_company_details.html.slim index c27c760b5..fc8ce6b9b 100644 --- a/app/views/admin/form_answers/_section_company_details.html.slim +++ b/app/views/admin/form_answers/_section_company_details.html.slim @@ -1,25 +1,36 @@ -.panel.panel-default +.panel.panel-default[data-controller="element-focus"] .panel-heading#company-details-heading h3.panel-title - a data-toggle="collapse" data-parent="#panel-application-info" href="#section-company-details" aria-expanded="true" aria-controls="section-company-details" + a data-toggle="collapse" data-parent="#panel-application-info" href="#section-company-details" aria-expanded="true" aria-controls="section-company-details" data-element-focus-target="reveal" = @form_answer.promotion? ? "Nominee Details" : "Company Details" - if resource.company_details_updated_at && resource.company_details_editable small = "Updated by: #{resource.company_details_editable.decorate.full_name} - #{format_date(resource.company_details_updated_at)}" - #section-company-details.section-company-details.panel-collapse.collapse aria-labelledby="company-details-heading" - .panel-body.company-details-forms - = render "admin/form_answers/company_details/company_name_form" - = render "admin/form_answers/company_details/organisation_type_form" - = render "admin/form_answers/company_details/address_form" - = render "admin/form_answers/company_details/previous_wins_form" - = render "admin/form_answers/company_details/sic_form" - = render "admin/form_answers/company_details/this_entry_relates_to_form" - = render "admin/form_answers/company_details/goods_services_form" - = render "admin/form_answers/company_details/registration_number_form" - = render "admin/form_answers/company_details/date_trading_form" - = render "admin/form_answers/company_details/website_form" - = render "admin/form_answers/company_details/organisation_head_form" - = render "admin/form_answers/company_details/parent_company_form" + .panel-body.company-details-forms.space-y-3 + div[data-controller="inline-flash"] + = render "admin/form_answers/company_details/company_name_form" + div[data-controller="inline-flash"] + = render "admin/form_answers/company_details/organisation_type_form" + div[data-controller="inline-flash"] + = render "admin/form_answers/company_details/address_form" + div[data-controller="inline-flash"] + = render "admin/form_answers/company_details/previous_wins_form" + div[data-controller="inline-flash"] + = render "admin/form_answers/company_details/sic_form" + div[data-controller="inline-flash"] + = render "admin/form_answers/company_details/this_entry_relates_to_form" + div[data-controller="inline-flash"] + = render "admin/form_answers/company_details/goods_services_form" + div[data-controller="inline-flash"] + = render "admin/form_answers/company_details/registration_number_form" + div[data-controller="inline-flash"] + = render "admin/form_answers/company_details/date_trading_form" + div[data-controller="inline-flash"] + = render "admin/form_answers/company_details/website_form" + div[data-controller="inline-flash"] + = render "admin/form_answers/company_details/organisation_head_form" + div[data-controller="inline-flash"] + = render "admin/form_answers/company_details/parent_company_form" = render "admin/form_answers/company_details/user_accounts" diff --git a/app/views/admin/form_answers/_section_critical_comments.html.slim b/app/views/admin/form_answers/_section_critical_comments.html.slim index cd0188dbc..bec666a41 100644 --- a/app/views/admin/form_answers/_section_critical_comments.html.slim +++ b/app/views/admin/form_answers/_section_critical_comments.html.slim @@ -1,7 +1,7 @@ -.panel.panel-default +.panel.panel-default[data-controller="element-focus"] .panel-heading#critical-comments-heading h3.panel-title - a data-toggle="collapse" data-parent="#panel-assessment" href="#section-critical-comments" aria-expanded="true" aria-controls="section-critical-comments" + a data-toggle="collapse" data-parent="#panel-assessment" href="#section-critical-comments" aria-expanded="true" aria-controls="section-critical-comments" data-element-focus-target="reveal" ' Critical Comments span.comments-number - if @form_answer.comments.critical.any? @@ -16,9 +16,9 @@ = "Updated by #{message_author_name(last_comment.author)} - #{l(last_comment.created_at, format: :date_at_time)}" #section-critical-comments.section-critical-comments.panel-collapse.collapse aria-labelledby="critical-comments-heading" - .panel-body + .panel-body[data-controller="inline-flash"] .comments-container.comment-assessor - = form_for([namespace_name, @form_answer, @form_answer.comments.new(section: "critical")]) do |f| + = form_for([namespace_name, @form_answer, @form_answer.comments.new(section: "critical")], html: { data: { inline_flash_target: "form" } }) do |f| = render("admin/comments/form", f: f) .comment-insert = render(collection: @form_answer.comments.critical, partial: "admin/form_answers/comment") diff --git a/app/views/admin/form_answers/_section_documents.html.slim b/app/views/admin/form_answers/_section_documents.html.slim index b00e569cc..30017bb46 100644 --- a/app/views/admin/form_answers/_section_documents.html.slim +++ b/app/views/admin/form_answers/_section_documents.html.slim @@ -34,7 +34,7 @@ - if @form_answer.audit_certificate.blank? && Settings.after_shortlisting_stage? .sidebar-section.no-margin-bottom.space-y-3 - if @form_answer.requires_vocf? - #audit-certificate-form + #audit-certificate-form[data-controller="inline-flash"] - audit_certificate = @form_answer.build_audit_certificate = render "admin/audit_certificate/form", form_answer: @form_answer, audit_certificate: audit_certificate @@ -43,9 +43,9 @@ = render(partial: "admin/figures_and_vat_returns/status", locals: { form_answer: @form_answer, figures_form: figures_form }) - #vat-returns-section + #vat-returns-section[data-controller="inline-flash"] = render(partial: "admin/figures_and_vat_returns/vat_returns", locals: { form_answer: @form_answer, figures_form: figures_form }) - #commercial-figures-section + #commercial-figures-section[data-controller="inline-flash"] = render(partial: "admin/figures_and_vat_returns/actual_figures", locals: { form_answer: @form_answer, figures_form: figures_form }) / TODO Only appears for EP but for now we need to think more on it diff --git a/app/views/admin/form_answers/_section_draft_notes.html.slim b/app/views/admin/form_answers/_section_draft_notes.html.slim index 9dd1bfd83..51f72a7b1 100644 --- a/app/views/admin/form_answers/_section_draft_notes.html.slim +++ b/app/views/admin/form_answers/_section_draft_notes.html.slim @@ -1,20 +1,20 @@ - @form_answer.draft_note || @form_answer.build_draft_note -.panel.panel-default +.panel.panel-default[data-controller="element-focus"] .panel-heading#draft-notes-heading h3.panel-title - a data-toggle="collapse" data-parent="#panel-assessment" href="#section-draft-notes" aria-expanded="true" aria-controls="section-draft-notes" + a data-toggle="collapse" data-parent="#panel-assessment" href="#section-draft-notes" aria-expanded="true" aria-controls="section-draft-notes" data-element-focus-target="reveal" ' Draft Notes - if @form_answer.draft_note.decorate.try(:last_updated_by).present? small= @form_answer.draft_note.decorate.try(:last_updated_by) #section-draft-notes.section-draft-notes.panel-collapse.collapse aria-labelledby="draft-notes-heading" - .panel-body + .panel-body[data-controller="inline-flash"] = simple_form_for([namespace_name, @form_answer, @form_answer.draft_note], remote: true, authenticity_token: true, - html: { "data-type" => "json" }) do |f| + html: { data: { type: "json", inline_flash_target: "form" } }) do |f| - .form-group class="#{'form-edit' if f.object.content.blank?}" + .form-group[class="#{'form-edit' if f.object.content.blank?}" data-controller="element-focus"] .form-container .form-value p @@ -28,11 +28,11 @@ as: :text, label: false - = link_to "#", class: "form-edit-link pull-right" + = link_to "#", class: "form-edit-link pull-right", data: { element_focus_target: "reveal" } span.glyphicon.glyphicon-pencil ' Edit .form-actions.text-right - = link_to "Cancel", "#", class: "btn btn-default form-cancel-link if-no-js-hide" + = link_to "Cancel", "#", class: "btn btn-default form-cancel-link if-no-js-hide", data: { element_focus_target: "dismiss" } = f.submit "Save", class: "btn btn-primary form-save-link pull-right if-js-hide" = link_to "Save", "#", class: "btn btn-primary form-save-link pull-right if-no-js-hide" .clear diff --git a/app/views/admin/form_answers/_section_palace_attendees.html.slim b/app/views/admin/form_answers/_section_palace_attendees.html.slim index 18bfdce24..3382705e9 100644 --- a/app/views/admin/form_answers/_section_palace_attendees.html.slim +++ b/app/views/admin/form_answers/_section_palace_attendees.html.slim @@ -14,5 +14,5 @@ - palace_invite.prebuild_if_necessary.palace_attendees.each_with_index do |pa, index| = render(partial: "admin/form_answers/winners_components/palace_attendee", locals: { index: index, pa: pa, palace_invite: palace_invite }) - #palace-invite-submit-form + #palace-invite-submit-form[data-controller="inline-flash"] = render "admin/form_answers/winners_components/palace_invite_submit_form", palace_invite: palace_invite diff --git a/app/views/admin/form_answers/_section_press_summary.html.slim b/app/views/admin/form_answers/_section_press_summary.html.slim index ac2e04ca3..167d95a6f 100644 --- a/app/views/admin/form_answers/_section_press_summary.html.slim +++ b/app/views/admin/form_answers/_section_press_summary.html.slim @@ -1,7 +1,7 @@ -.panel.panel-default +.panel.panel-default[data-controller="element-focus"] .panel-heading#press-summary-heading h3.panel-title - a data-toggle="collapse" data-parent="#panel-winners" href="#section-press-summary" aria-expanded="true" aria-controls="section-press-summary" + a data-toggle="collapse" data-parent="#panel-winners" href="#section-press-summary" aria-expanded="true" aria-controls="section-press-summary" data-element-focus-target="reveal" ' Press Book Notes small.updated-by - if @form_answer.press_summary_updated_by diff --git a/app/views/admin/form_answers/_submitted_view.html.slim b/app/views/admin/form_answers/_submitted_view.html.slim index e20383b38..f2f618d21 100644 --- a/app/views/admin/form_answers/_submitted_view.html.slim +++ b/app/views/admin/form_answers/_submitted_view.html.slim @@ -44,7 +44,7 @@ small = @form_answer.feedback_updated_by #section-feedback.section-application-info.panel-collapse.collapse aria-labelledby="feedback-heading" - .panel-body + .panel-body[data-controller="inline-flash"] = render "admin/feedbacks/section", form_answer: @form_answer - if show_winners_section? diff --git a/app/views/admin/form_answers/appraisal_form_components/_application_background_section.html.slim b/app/views/admin/form_answers/appraisal_form_components/_application_background_section.html.slim index e2710987e..bda474ff6 100644 --- a/app/views/admin/form_answers/appraisal_form_components/_application_background_section.html.slim +++ b/app/views/admin/form_answers/appraisal_form_components/_application_background_section.html.slim @@ -1,6 +1,6 @@ - editable = f.object.editable_for?(current_subject) -.form-group.application-background-section class="#{'form-edit' if f.object.application_background_section_desc.blank? && editable}" +.form-group.application-background-section[class="#{'form-edit' if f.object.application_background_section_desc.blank? && editable}" data-controller="element-focus"] .form-container label.form-label Application background .form-value @@ -20,7 +20,7 @@ label: false - if editable - = link_to "#", class: "form-edit-link pull-right" + = link_to "#", class: "form-edit-link pull-right", data: { element_focus_target: "reveal" } span.glyphicon.glyphicon-pencil ' Edit = link_to "Save", "#", class: "btn btn-primary form-save-link pull-right if-no-js-hide" diff --git a/app/views/admin/form_answers/appraisal_form_components/_non_rag_section.html.slim b/app/views/admin/form_answers/appraisal_form_components/_non_rag_section.html.slim index 984c8d357..0f1d9dd39 100644 --- a/app/views/admin/form_answers/appraisal_form_components/_non_rag_section.html.slim +++ b/app/views/admin/form_answers/appraisal_form_components/_non_rag_section.html.slim @@ -2,7 +2,7 @@ - editable = f.object.editable_for?(current_subject) -.form-group.rag-section class="#{'form-edit' if f.object.public_send(section.desc).blank? && editable}" +.form-group.rag-section[class="#{'form-edit' if f.object.public_send(section.desc).blank? && editable}" data-controller="element-focus"] .form-container label.form-label = section.label @@ -22,10 +22,10 @@ label: false - if editable - = link_to "#", class: "form-edit-link pull-right" + = link_to "#", class: "form-edit-link pull-right", data: { element_focus_target: "reveal" } span.glyphicon.glyphicon-pencil ' Edit .form-actions.text-right - = link_to "Cancel", "#", class: "btn btn-default form-cancel-link if-no-js-hide" + = link_to "Cancel", "#", class: "btn btn-default form-cancel-link if-no-js-hide", data: { element_focus_target: "dismiss" } = link_to "Save", "#", class: "btn btn-primary form-save-link pull-right if-no-js-hide", "data-updated-section" => section.desc .clear diff --git a/app/views/admin/form_answers/appraisal_form_components/_rag_section.html.slim b/app/views/admin/form_answers/appraisal_form_components/_rag_section.html.slim index 7ad978116..dcd7d4908 100644 --- a/app/views/admin/form_answers/appraisal_form_components/_rag_section.html.slim +++ b/app/views/admin/form_answers/appraisal_form_components/_rag_section.html.slim @@ -2,7 +2,7 @@ - editable = f.object.editable_for?(current_subject) -.form-group.rag-section class="#{'form-edit' if f.object.public_send(section.desc).blank? && editable} form-#{section.label.parameterize}" +.form-group.rag-section[class="#{'form-edit' if f.object.public_send(section.desc).blank? && editable} form-#{section.label.parameterize}" data-controller="element-focus"] .form-container = f.input section.rate, as: :select, @@ -42,10 +42,10 @@ label: false - if editable - = link_to "#", class: "form-edit-link pull-right" + = link_to "#", class: "form-edit-link pull-right", data: { element_focus_target: "reveal" } span.glyphicon.glyphicon-pencil ' Edit .form-actions.text-right - = link_to "Cancel", "#", class: "btn btn-default form-cancel-link if-no-js-hide" + = link_to "Cancel", "#", class: "btn btn-default form-cancel-link if-no-js-hide", data: { element_focus_target: "dismiss" } = link_to "Save", "#", class: "btn btn-primary form-save-link pull-right if-no-js-hide", "data-updated-section" => section.desc .clear diff --git a/app/views/admin/form_answers/appraisal_form_components/_verdict_section.html.slim b/app/views/admin/form_answers/appraisal_form_components/_verdict_section.html.slim index cdd0c2828..38a87c333 100644 --- a/app/views/admin/form_answers/appraisal_form_components/_verdict_section.html.slim +++ b/app/views/admin/form_answers/appraisal_form_components/_verdict_section.html.slim @@ -2,7 +2,7 @@ - editable = f.object.editable_for?(current_subject) - rag_editable = f.object.moderated_rag_editable_for?(current_subject) -.form-group.verdict-section class="#{'form-edit' if f.object.public_send(section.desc).blank? && editable} form-#{section.label.parameterize}" +.form-group.verdict-section[class="#{'form-edit' if f.object.public_send(section.desc).blank? && editable} form-#{section.label.parameterize}" data-controller="element-focus"] .form-container = f.input section.rate, as: :select, @@ -40,10 +40,10 @@ label: false - if editable - = link_to "#", class: "form-edit-link pull-right" + = link_to "#", class: "form-edit-link pull-right", data: { element_focus_target: "reveal" } span.glyphicon.glyphicon-pencil ' Edit .form-actions.text-right - = link_to "Cancel", "#", class: "btn btn-default form-cancel-link if-no-js-hide" + = link_to "Cancel", "#", class: "btn btn-default form-cancel-link if-no-js-hide", data: { element_focus_target: "dismiss" } = link_to "Save", "#", class: "btn btn-primary form-save-link pull-right if-no-js-hide", "data-updated-section" => section.desc .clear diff --git a/app/views/admin/form_answers/company_details/_address_form.html.slim b/app/views/admin/form_answers/company_details/_address_form.html.slim index 6d379d420..9307c7993 100644 --- a/app/views/admin/form_answers/company_details/_address_form.html.slim +++ b/app/views/admin/form_answers/company_details/_address_form.html.slim @@ -1,6 +1,6 @@ .form-group-multiple-parent - if @form_answer.promotion? - .form-group.form-group-multiple.company-address-personal-form + .form-group.form-group-multiple.company-address-personal-form[data-controller="element-focus"] .form-container label.form-label Nominee Address @@ -30,10 +30,9 @@ - if @form_answer.nominee_region.present? = @form_answer.nominee_region - - if user_can_edit(@form_answer, :address) = simple_form_for([namespace_name, resource], remote: true, - authenticity_token: true, html: { "data-type" => "html", id: "address_form_admin_appraisal" }) do |f| + authenticity_token: true, html: { data: { type: "html", inline_flash_target: "form" }, id: "address_form_admin_appraisal" }) do |f| = hidden_field_tag :section, "address" .input.form-group.form-fields.form-block @@ -88,17 +87,17 @@ collection: regions .form-actions.text-right - = link_to "Cancel", "#", class: "btn btn-default form-cancel-link if-no-js-hide" + = link_to "Cancel", "#", class: "btn btn-default form-cancel-link if-no-js-hide", data: { element_focus_target: "dismiss" } = f.submit "Save", class: "btn btn-primary pull-right" .clear - = link_to "#", class: "form-edit-link pull-right" + = link_to "#", class: "form-edit-link pull-right", data: { element_focus_target: "reveal" } span.glyphicon.glyphicon-pencil ' Edit .clear - .form-group.form-group-multiple.company-address-form + .form-group.form-group-multiple.company-address-form[data-controller="element-focus"] .form-container label.form-label = @form_answer.promotion? ? "Organisation Address" : "Address" @@ -146,7 +145,7 @@ - if resource.submitted_and_after_the_deadline? && CompanyDetailPolicy.new(pundit_user, resource).can_manage_address? = simple_form_for([namespace_name, resource], remote: true, - authenticity_token: true, html: { "data-type" => "html" }) do |f| + authenticity_token: true, html: { data: { type: "html", inline_flash_target: "form" }, id: "address_form_admin_appraisal" }) do |f| = hidden_field_tag :section, "address", id: "section_address_hidden_field" .input.form-group.form-fields.form-block @@ -218,18 +217,18 @@ input_html: { class: "form-control" } .form-actions.text-right - = link_to "Cancel", "#", class: "btn btn-default form-cancel-link if-no-js-hide" + = link_to "Cancel", "#", class: "btn btn-default form-cancel-link if-no-js-hide", data: { element_focus_target: "dismiss" } = f.submit "Save", class: "btn btn-primary pull-right" .clear - = link_to "#", class: "form-edit-link pull-right" + = link_to "#", class: "form-edit-link pull-right", data: { element_focus_target: "reveal" } span.glyphicon.glyphicon-pencil ' Edit .clear - if @form_answer.promotion? - .form-group.form-group-multiple.company-address-nominator-form + .form-group.form-group-multiple.company-address-nominator-form[data-controller="element-focus"] .form-container label.form-label Nominator Address @@ -263,7 +262,7 @@ - if resource.submitted_and_after_the_deadline? && CompanyDetailPolicy.new(pundit_user, resource).can_manage_address? = simple_form_for([namespace_name, resource], remote: true, - authenticity_token: true, html: { "data-type" => "html" }) do |f| + authenticity_token: true, html: { data: { type: "html", inline_flash_target: "form" }, id: "address_form_admin_appraisal" }) do |f| = hidden_field_tag :section, "address" .input.form-group.form-fields.form-block = f.simple_fields_for(:data) do |f| @@ -321,12 +320,12 @@ input_html: { class: "form-control" } .form-actions.text-right - = link_to "Cancel", "#", class: "btn btn-default form-cancel-link if-no-js-hide" + = link_to "Cancel", "#", class: "btn btn-default form-cancel-link if-no-js-hide", data: { element_focus_target: "dismiss" } = f.submit "Save", class: "btn btn-primary pull-right" .clear - = link_to "#", class: "form-edit-link pull-right" + = link_to "#", class: "form-edit-link pull-right", data: { element_focus_target: "reveal" } span.glyphicon.glyphicon-pencil ' Edit .clear diff --git a/app/views/admin/form_answers/company_details/_company_name_form.html.slim b/app/views/admin/form_answers/company_details/_company_name_form.html.slim index 720f73512..60a5d7f2d 100644 --- a/app/views/admin/form_answers/company_details/_company_name_form.html.slim +++ b/app/views/admin/form_answers/company_details/_company_name_form.html.slim @@ -1,10 +1,10 @@ - account_name = @form_answer.promotion? ? "Nominee name" : "Company name" - if user_can_edit_company(@form_answer) - .form-group + .form-group[data-controller="element-focus"] = simple_form_for [namespace_name, @form_answer], remote: true, authenticity_token: true, - html: { "data-type" => "html", class: "company-name-form", id: "company_name_form_admin_appraisal"} do |f| + html: { data: { type: "html", inline_flash_target: "form" }, class: "company-name-form", id: "company_name_form_admin_appraisal"} do |f| = hidden_field_tag :section, "company_name", id: "section_company_name_hidden_field" .form-container @@ -30,10 +30,10 @@ input_html: { class: "form-control" } .form-actions.text-right - = link_to "Cancel", "#", class: "btn btn-default form-cancel-link if-no-js-hide" + = link_to "Cancel", "#", class: "btn btn-default form-cancel-link if-no-js-hide", data: { element_focus_target: "dismiss" } = f.submit "Save", class: "btn btn-primary pull-right" .clear - = link_to "#", class: "form-edit-link pull-right" + = link_to "#", class: "form-edit-link pull-right", data: { element_focus_target: "reveal" } span.glyphicon.glyphicon-pencil ' Edit .clear diff --git a/app/views/admin/form_answers/company_details/_date_trading_form.html.slim b/app/views/admin/form_answers/company_details/_date_trading_form.html.slim index 81a1baa16..1dab343c1 100644 --- a/app/views/admin/form_answers/company_details/_date_trading_form.html.slim +++ b/app/views/admin/form_answers/company_details/_date_trading_form.html.slim @@ -1,9 +1,9 @@ - unless @form_answer.promotion? - if user_can_edit(@form_answer, :date_trading) - .form-group + .form-group[data-controller="element-focus"] = simple_form_for [namespace_name, resource], remote: true, - authenticity_token: true, html: { "data-type" => "html", id: "date_trading_form_admin_appraisal" } do |f| + authenticity_token: true, html: { data: { type: "html", inline_flash_target: "form" }, id: "date_trading_form_admin_appraisal" } do |f| = hidden_field_tag :section, "date_trading", id: "section_date_trading_hidden_field" .form-container @@ -27,11 +27,11 @@ input.string.optional.form-control id="date_started_trading_1i" type='text' name="form_answer[data_attributes][started_trading_year]" value="#{@form_answer.document["started_trading_year"]}" .clear .form-actions.text-right - = link_to "Cancel", "#", class: "btn btn-default form-cancel-link if-no-js-hide" + = link_to "Cancel", "#", class: "btn btn-default form-cancel-link if-no-js-hide", data: { element_focus_target: "dismiss" } = f.submit "Save", class: "btn btn-primary pull-right" .clear - = link_to "#", class: "form-edit-link pull-right" + = link_to "#", class: "form-edit-link pull-right", data: { element_focus_target: "reveal" } span.glyphicon.glyphicon-pencil ' Edit .clear diff --git a/app/views/admin/form_answers/company_details/_goods_services_form.html.slim b/app/views/admin/form_answers/company_details/_goods_services_form.html.slim index 53b81cf88..620fce08e 100644 --- a/app/views/admin/form_answers/company_details/_goods_services_form.html.slim +++ b/app/views/admin/form_answers/company_details/_goods_services_form.html.slim @@ -1,5 +1,5 @@ - unless @form_answer.promotion? - .form-group + .form-group[data-controller="element-focus"] .form-container label.form-label Description of goods/services .form-value @@ -15,7 +15,7 @@ p = service["desc_short"] - if user_can_edit(@form_answer, :goods_services) - = simple_form_for [namespace_name, resource], remote: true, authenticity_token: true, html: { "data-type" => "html", id: "goods_services_form_admin_appraisal" } do |f| + = simple_form_for [namespace_name, resource], remote: true, authenticity_token: true, html: { data: { type: "html", inline_flash_target: "form" }, id: "goods_services_form_admin_appraisal" } do |f| = hidden_field_tag :section, "goods_services", id: "section_goods_services_hidden_field" .form-fields.form-block = f.simple_fields_for(:data) do |f| @@ -30,10 +30,10 @@ = "Goods/services #{index + 1}" input.form-control.js-chart-count type="text" name="form_answer[data_attributes][trade_goods_and_services_explanations][#{index}][desc_short]" value="#{service["desc_short"]}" rows= 3 data-word-max = 15 .form-actions.text-right - = link_to "Cancel", "#", class: "btn btn-default form-cancel-link if-no-js-hide" + = link_to "Cancel", "#", class: "btn btn-default form-cancel-link if-no-js-hide", data: { element_focus_target: "dismiss" } = f.submit "Save", class: "btn btn-primary pull-right" .clear - = link_to "#", class: "form-edit-link pull-right" + = link_to "#", class: "form-edit-link pull-right", data: { element_focus_target: "reveal" } span.glyphicon.glyphicon-pencil ' Edit .clear diff --git a/app/views/admin/form_answers/company_details/_organisation_head_form.html.slim b/app/views/admin/form_answers/company_details/_organisation_head_form.html.slim index 2944064d9..9772d1ea0 100644 --- a/app/views/admin/form_answers/company_details/_organisation_head_form.html.slim +++ b/app/views/admin/form_answers/company_details/_organisation_head_form.html.slim @@ -1,9 +1,9 @@ - unless @form_answer.promotion? - if user_can_edit(@form_answer, :organisation_head) - .form-group + .form-group[data-controller="element-focus"] = simple_form_for [namespace_name, resource], remote: true, - authenticity_token: true, html: { "data-type" => "html", id: "organisation_head_form_admin_appraisal" } do |f| + authenticity_token: true, html: { data: { type: "html", inline_flash_target: "form" }, id: "organisation_head_form_admin_appraisal" } do |f| = hidden_field_tag :section, "organisation_head", id: "section_organisation_head_hidden_field" .form-container @@ -61,11 +61,11 @@ label: "Email", input_html: { class: "form-control" } .form-actions.text-right - = link_to "Cancel", "#", class: "btn btn-default form-cancel-link if-no-js-hide" + = link_to "Cancel", "#", class: "btn btn-default form-cancel-link if-no-js-hide", data: { element_focus_target: "dismiss" } = f.submit "Save", class: "btn btn-primary pull-right" .clear - = link_to "#", class: "form-edit-link pull-right" + = link_to "#", class: "form-edit-link pull-right", data: { element_focus_target: "reveal" } span.glyphicon.glyphicon-pencil ' Edit .clear diff --git a/app/views/admin/form_answers/company_details/_organisation_type_form.html.slim b/app/views/admin/form_answers/company_details/_organisation_type_form.html.slim index fb328ae87..0b08fde0d 100644 --- a/app/views/admin/form_answers/company_details/_organisation_type_form.html.slim +++ b/app/views/admin/form_answers/company_details/_organisation_type_form.html.slim @@ -2,10 +2,10 @@ - unless @form_answer.promotion? - if user_can_edit(@form_answer, :organisation_type) - .form-group class="#{'form-edit' if @form_answer.organisation_type.blank?}" + .form-group[class="#{'form-edit' if @form_answer.organisation_type.blank?}" data-controller="element-focus"] = simple_form_for [namespace_name, resource], remote: true, - authenticity_token: true, html: { "data-type" => "html", id: "organisation_type_form_admin_appraisal" } do |f| + authenticity_token: true, html: { data: { type: "html", inline_flash_target: "form" }, id: "organisation_type_form_admin_appraisal" } do |f| = hidden_field_tag :section, "organisation_type", id: "section_organisation_type_hidden_field" .form-container @@ -27,11 +27,11 @@ input_html: { class: "form-control" }, include_blank: false .form-actions.text-right - = link_to "Cancel", "#", class: "btn btn-default form-cancel-link if-no-js-hide" + = link_to "Cancel", "#", class: "btn btn-default form-cancel-link if-no-js-hide", data: { element_focus_target: "dismiss" } = f.submit "Save", class: "btn btn-primary pull-right" .clear - = link_to "#", class: "form-edit-link pull-right" + = link_to "#", class: "form-edit-link pull-right", data: { element_focus_target: "reveal" } span.glyphicon.glyphicon-pencil ' Edit .clear diff --git a/app/views/admin/form_answers/company_details/_registration_number_form.html.slim b/app/views/admin/form_answers/company_details/_registration_number_form.html.slim index 9a8893ec7..a4a84b6bd 100644 --- a/app/views/admin/form_answers/company_details/_registration_number_form.html.slim +++ b/app/views/admin/form_answers/company_details/_registration_number_form.html.slim @@ -1,10 +1,10 @@ - unless @form_answer.promotion? - if user_can_edit(@form_answer, :registration_number) - .form-group class="#{'form-edit' if @form_answer.registration_number.blank?}" + .form-group[class="#{'form-edit' if @form_answer.registration_number.blank?}" data-controller="element-focus"] = simple_form_for [namespace_name, resource], remote: true, authenticity_token: true, - html: { "data-type" => "html", class: "registration-number-form", id: "registration_number_form_admin_appraisal" } do |f| + html: { data: { type: "html", inline_flash_target: "form" }, class: "registration-number-form", id: "registration_number_form_admin_appraisal" } do |f| = hidden_field_tag :section, "registration_number", id: "section_registration_number_hidden_field" .form-container label.form-label Company/charity registration number @@ -22,11 +22,11 @@ label: false, input_html: { class: "form-control" } .form-actions.text-right - = link_to "Cancel", "#", class: "btn btn-default form-cancel-link if-no-js-hide" + = link_to "Cancel", "#", class: "btn btn-default form-cancel-link if-no-js-hide", data: { element_focus_target: "dismiss" } = f.submit "Save", class: "btn btn-primary pull-right" .clear - = link_to "#", class: "form-edit-link pull-right" + = link_to "#", class: "form-edit-link pull-right", data: { element_focus_target: "reveal" } span.glyphicon.glyphicon-pencil ' Edit .clear diff --git a/app/views/admin/form_answers/company_details/_sic_form.html.slim b/app/views/admin/form_answers/company_details/_sic_form.html.slim index 2b4df5ec7..574b8d205 100644 --- a/app/views/admin/form_answers/company_details/_sic_form.html.slim +++ b/app/views/admin/form_answers/company_details/_sic_form.html.slim @@ -3,11 +3,11 @@ - sic = @form_answer.sic_code_name - if user_can_edit(@form_answer, :sic_code) - .form-group.sic-code class="#{'form-edit' if @form_answer.sic_code.blank?}" + .form-group.sic-code[class="#{'form-edit' if @form_answer.sic_code.blank?}" data-controller="element-focus"] = simple_form_for [namespace_name, @form_answer], remote: true, authenticity_token: true, - html: { "data-type" => "html", id: "sic_code_form_admin_appraisal" } do |f| + html: { data: { type: "html", inline_flash_target: "form" }, id: "sic_code_form_admin_appraisal" } do |f| = hidden_field_tag :section, "sic_code", id: "section_sic_code_hidden_field" @@ -29,10 +29,10 @@ include_blank: false, label: false .form-actions.text-right - = link_to "Cancel", "#", class: "btn btn-default form-cancel-link if-no-js-hide" + = link_to "Cancel", "#", class: "btn btn-default form-cancel-link if-no-js-hide", data: { element_focus_target: "dismiss" } = f.submit "Save", class: "btn btn-primary form-save-link pull-right" - = link_to "#", class: "form-edit-link pull-right" + = link_to "#", class: "form-edit-link pull-right", data: { element_focus_target: "reveal" } span.glyphicon.glyphicon-pencil ' Edit .clear diff --git a/app/views/admin/form_answers/company_details/_this_entry_relates_to_form.html.slim b/app/views/admin/form_answers/company_details/_this_entry_relates_to_form.html.slim index 0b7b5547c..d0e07bc7f 100644 --- a/app/views/admin/form_answers/company_details/_this_entry_relates_to_form.html.slim +++ b/app/views/admin/form_answers/company_details/_this_entry_relates_to_form.html.slim @@ -2,10 +2,10 @@ - if @form_answer.show_this_entry_relates_to_question? - if user_can_edit(@form_answer, :this_entry_relates_to) - .form-group class="#{'form-edit' if @form_answer.this_entry_relates_to.blank?}" + .form-group[class="#{'form-edit' if @form_answer.this_entry_relates_to.blank?}" data-controller="element-focus"] = simple_form_for [namespace_name, resource], remote: true, - authenticity_token: true, html: { "data-type" => "html", id: "this_entry_relates_to_form_admin_appraisal" } do |f| + authenticity_token: true, html: { data: { type: "html", inline_flash_target: "form" }, id: "this_entry_relates_to_form_admin_appraisal" } do |f| = hidden_field_tag :section, "this_entry_relates_to", id: "section_this_entry_relates_to_hidden_field" .form-container @@ -24,11 +24,11 @@ = render "admin/form_answers/company_details/entry_relates_to_checkboxes", awards: ["development", "mobility"] .form-actions.text-right - = link_to "Cancel", "#", class: "btn btn-default form-cancel-link if-no-js-hide" + = link_to "Cancel", "#", class: "btn btn-default form-cancel-link if-no-js-hide", data: { element_focus_target: "dismiss" } = f.submit "Save", class: "btn btn-primary pull-right" .clear - = link_to "#", class: "form-edit-link pull-right" + = link_to "#", class: "form-edit-link pull-right", data: { element_focus_target: "reveal" } span.glyphicon.glyphicon-pencil ' Edit .clear diff --git a/app/views/admin/form_answers/company_details/_website_form.html.slim b/app/views/admin/form_answers/company_details/_website_form.html.slim index 2d899c316..319abec8a 100644 --- a/app/views/admin/form_answers/company_details/_website_form.html.slim +++ b/app/views/admin/form_answers/company_details/_website_form.html.slim @@ -1,9 +1,9 @@ - unless @form_answer.promotion? - if user_can_edit(@form_answer, :website) - .form-group class="#{'form-edit' if @form_answer.website_url.blank?}" + .form-group[class="#{'form-edit' if @form_answer.website_url.blank?}" data-controller="element-focus"] = simple_form_for [namespace_name, resource], remote: true, - authenticity_token: true, html: { "data-type" => "html", id: "website_form_admin_appraisal" } do |f| + authenticity_token: true, html: { data: { type: "html", inline_flash_target: "form" }, id: "website_form_admin_appraisal" } do |f| = hidden_field_tag :section, "website", id: "section_website_hidden_field" .form-container @@ -22,11 +22,11 @@ label: false, input_html: { class: "form-control" } .form-actions.text-right - = link_to "Cancel", "#", class: "btn btn-default form-cancel-link if-no-js-hide" + = link_to "Cancel", "#", class: "btn btn-default form-cancel-link if-no-js-hide", data: { element_focus_target: "dismiss" } = f.submit "Save", class: "btn btn-primary pull-right" .clear - = link_to "#", class: "form-edit-link pull-right" + = link_to "#", class: "form-edit-link pull-right", data: { element_focus_target: "reveal" } span.glyphicon.glyphicon-pencil ' Edit .clear diff --git a/app/views/admin/form_answers/company_details/parent_company/_form.html.slim b/app/views/admin/form_answers/company_details/parent_company/_form.html.slim index 84607b3a5..395e07de9 100644 --- a/app/views/admin/form_answers/company_details/parent_company/_form.html.slim +++ b/app/views/admin/form_answers/company_details/parent_company/_form.html.slim @@ -1,7 +1,7 @@ -.form-group.form-group-multiple class="#{'form-edit' if @form_answer.parent_company.blank?}" +.form-group.form-group-multiple[class="#{'form-edit' if @form_answer.parent_company.blank?}" data-controller="element-focus"] = simple_form_for [namespace_name, resource], remote: true, - authenticity_token: true, html: { "data-type" => "html" } do |f| + authenticity_token: true, html: { data: { type: "html", inline_flash_target: "form" } } do |f| = hidden_field_tag :section, "parent_company", id: "section_parent_company_hidden_field" .form-container @@ -29,11 +29,11 @@ collection: country_collection .form-actions.text-right - = link_to "Cancel", "#", class: "btn btn-default form-cancel-link if-no-js-hide" + = link_to "Cancel", "#", class: "btn btn-default form-cancel-link if-no-js-hide", data: { element_focus_target: "dismiss" } = f.submit "Save", class: "btn btn-primary pull-right" .clear - = link_to "#", class: "form-edit-link pull-right" + = link_to "#", class: "form-edit-link pull-right", data: { element_focus_target: "reveal" } span.glyphicon.glyphicon-pencil ' Edit .clear diff --git a/app/views/admin/form_answers/company_details/previous_wins/_form.html.slim b/app/views/admin/form_answers/company_details/previous_wins/_form.html.slim index 28f8d7fb2..66807bc69 100644 --- a/app/views/admin/form_answers/company_details/previous_wins/_form.html.slim +++ b/app/views/admin/form_answers/company_details/previous_wins/_form.html.slim @@ -1,10 +1,10 @@ = simple_form_for [namespace_name, @form_answer], remote: true, authenticity_token: true, - html: { "data-type" => "html", id: "previous_wins_form" } do |f| + html: { data: { type: "html", inline_flash_target: "form" }, id: "previous_wins_form" } do |f| = hidden_field_tag :section, "previous_wins", id: "previous_wins_section_hidden_field" - .form-container + .form-container[data-controller="element-focus"] = render "admin/form_answers/company_details/previous_wins/show" .input.form-group.form-fields.form-block @@ -34,11 +34,11 @@ = link_to "+ Add another winnings", "#", class: "btn btn-default if-no-js-hide add-previous-winning" .form-actions.text-right - = link_to "Cancel", "#", class: "btn btn-default form-cancel-link if-no-js-hide" + = link_to "Cancel", "#", class: "btn btn-default form-cancel-link if-no-js-hide", data: { element_focus_target: "dismiss" } = f.submit "Save", class: "btn btn-primary pull-right" - = link_to "#", class: "form-edit-link pull-right" + = link_to "#", class: "form-edit-link pull-right", data: { element_focus_target: "reveal" } span.glyphicon.glyphicon-pencil ' Edit .clear diff --git a/app/views/admin/form_answers/financial_summary/_list.html.slim b/app/views/admin/form_answers/financial_summary/_list.html.slim index af2fa19be..31f01ddfa 100644 --- a/app/views/admin/form_answers/financial_summary/_list.html.slim +++ b/app/views/admin/form_answers/financial_summary/_list.html.slim @@ -1,7 +1,7 @@ - url = pundit_user.is_a?(Admin) ? update_financials_admin_form_answer_path(@form_answer) : update_financials_assessor_form_answer_path(@form_answer) -.form-group - = form_for @form_answer, url: url do |f| +.form-group[data-controller="element-focus"] + = form_for @form_answer, url: url, html: { data: { controller: "inline-flash", inline_flash_target: "form" }, id: "form-admin-financial-summary" } do |f| .table-overflow-container table.table.table-striped#financial-table colgroup @@ -17,11 +17,11 @@ = render "admin/form_answers/financial_summary/row", f: f, row: row - if policy(resource).update_financials? - = link_to "#", class: "form-edit-link pull-right" + = link_to "#", class: "form-edit-link pull-right", data: { element_focus_target: "reveal" } span.glyphicon.glyphicon-pencil ' Edit .form-actions.text-right - = link_to "Cancel", "#", class: "btn btn-default form-cancel-link if-no-js-hide" + = link_to "Cancel", "#", class: "btn btn-default form-cancel-link if-no-js-hide", data: { element_focus_target: "dismiss" } = button_tag "Save", class: "btn btn-primary form-save-button pull-right" .clear diff --git a/app/views/admin/form_answers/winners_components/_palace_attendee.html.slim b/app/views/admin/form_answers/winners_components/_palace_attendee.html.slim index 25e3f431e..24f07136b 100644 --- a/app/views/admin/form_answers/winners_components/_palace_attendee.html.slim +++ b/app/views/admin/form_answers/winners_components/_palace_attendee.html.slim @@ -1,4 +1,4 @@ -.form-group.palace-attendee-container class=("form-edit" if pa.errors.present? || defined?(@enable_edition)) +.form-group.palace-attendee-container[class=("form-edit" if pa.errors.present? || defined?(@enable_edition)) data-controller="element-focus"] .form-value .empty-message class="#{'visuallyhidden' if palace_invite.palace_attendees.exists?}" p.p-empty No attendees confirmed. @@ -10,7 +10,7 @@ - if palace_invite.palace_attendees.exists? ul.list-unstyled li.well - = link_to "#", class: "form-edit-link pull-right" + = link_to "#", class: "form-edit-link pull-right", data: { element_focus_target: "reveal" } span.glyphicon.glyphicon-pencil ' Edit @@ -44,7 +44,6 @@ - else ' - - .input.form-group.form-fields.form-block.attendees-forms data-attendees-limit=palace_invite.attendees_limit / ### Business Award winner / Each winning business sends two representatives. If a business is successful in more than one business category they are allowed to send two reps for each winning category. The invitation is sent to the head of the winning unit. diff --git a/app/views/admin/form_answers/winners_components/_palace_invite_submit_form.html.slim b/app/views/admin/form_answers/winners_components/_palace_invite_submit_form.html.slim index f9e1bafe4..e20c76188 100644 --- a/app/views/admin/form_answers/winners_components/_palace_invite_submit_form.html.slim +++ b/app/views/admin/form_answers/winners_components/_palace_invite_submit_form.html.slim @@ -3,7 +3,8 @@ = simple_form_for([:submit, namespace_name, palace_invite], remote: true, authenticity_token: true, - method: :post) do |f| + method: :post, + html: { data: { inline_flash_target: "form" } }) do |f| = f.submit "Submit", class: "btn btn-primary" .clear diff --git a/app/views/admin/judges/_form.html.slim b/app/views/admin/judges/_form.html.slim index 63a29d781..9f10a57bc 100644 --- a/app/views/admin/judges/_form.html.slim +++ b/app/views/admin/judges/_form.html.slim @@ -26,6 +26,15 @@ .question-group#password-change-panel #password-control-group h3 = f.label :password, class: "form-label" + .guidance-panel.if-no-js-hide + .govuk-form-group--error#password-guidance + p.govuk-error-message.text-underline Please improve your password + p.govuk-error-message#password-too-short + ' It must be at least 10 characters. + p.govuk-error-message#parts-of-email It shouldn't include part or all of your email address. + p.govuk-error-message#password-entropy + ' It must be more complex. Consider using whole sentences (with spaces), lyrics or phrases to make it more memorable. + .row .col-md-4.col-sm-6 .input-group @@ -33,19 +42,9 @@ wrapper_html: { class: 'form-group' }, input_html: { class: 'form-control' }, label: false - span#password-result-span.input-group-addon + span#password-result-span.input-group-addon.hide i#password-result.glyphicon.glyphicon-ok .clear - .guidance-panel.if-no-js-hide - #password-guidance - br - .alert.alert-warning - p.text-underline Please improve your password - p#password-too-short - ' It must be at least 10 characters. - p#parts-of-email It shouldn't include part or all of your email address. - p#password-entropy - ' It must be more complex. Consider using whole sentences (with spaces), lyrics or phrases to make it more memorable. #password-confirmation-control-group h3 = f.label :password_confirmation, label: "Retype password", class: "form-label" @@ -56,15 +55,13 @@ wrapper_html: { class: 'form-group' }, input_html: { class: 'form-control' }, label: false - span#password-confirmation-result-span.input-group-addon + span#password-confirmation-result-span.input-group-addon.hide i#password-confirmation-result.glyphicon.glyphicon-ok .clear .if-no-js-hide - #password-confirmation-guidance - br - .alert.alert-warning - p#password-confirmation-match The confirmation must match the password + .govuk-form-group--error#password-confirmation-guidance + p.govuk-error-message#password-confirmation-match The confirmation must match the password br diff --git a/app/views/admin/press_summaries/_contact_details_for_press_enquiries_before_2020.html.slim b/app/views/admin/press_summaries/_contact_details_for_press_enquiries_before_2020.html.slim index f54f55ba5..c9c7a8299 100644 --- a/app/views/admin/press_summaries/_contact_details_for_press_enquiries_before_2020.html.slim +++ b/app/views/admin/press_summaries/_contact_details_for_press_enquiries_before_2020.html.slim @@ -22,10 +22,10 @@ input_html: { class: 'form-control' } .clear - = link_to "#", class: "form-edit-link pull-right" do + = link_to "#", class: "form-edit-link pull-right", data: { element_focus_target: "reveal" } do span.glyphicon.glyphicon-pencil ' Edit .form-actions.text-right - = link_to "Cancel", "#", class: "btn btn-default form-cancel-link if-no-js-hide" + = link_to "Cancel", "#", class: "btn btn-default form-cancel-link if-no-js-hide", data: { element_focus_target: "dismiss" } = f.submit "Save", class: "btn btn-primary form-save-link pull-right" .clear \ No newline at end of file diff --git a/app/views/admin/press_summaries/_contact_details_for_press_enquiries_since_2020.html.slim b/app/views/admin/press_summaries/_contact_details_for_press_enquiries_since_2020.html.slim index 5822679dc..ad8ca55b7 100644 --- a/app/views/admin/press_summaries/_contact_details_for_press_enquiries_since_2020.html.slim +++ b/app/views/admin/press_summaries/_contact_details_for_press_enquiries_since_2020.html.slim @@ -49,10 +49,10 @@ input_html: { class: 'form-control' } .clear - = link_to "#", class: "form-edit-link pull-right" do + = link_to "#", class: "form-edit-link pull-right", data: { element_focus_target: "reveal" } do span.glyphicon.glyphicon-pencil ' Edit .form-actions.text-right - = link_to "Cancel", "#", class: "btn btn-default form-cancel-link if-no-js-hide" + = link_to "Cancel", "#", class: "btn btn-default form-cancel-link if-no-js-hide", data: { element_focus_target: "dismiss" } = f.submit "Save", class: "btn btn-primary form-save-link pull-right" .clear \ No newline at end of file diff --git a/app/views/admin/press_summaries/_section.html.slim b/app/views/admin/press_summaries/_section.html.slim index bde7f0ae6..f78f3a322 100644 --- a/app/views/admin/press_summaries/_section.html.slim +++ b/app/views/admin/press_summaries/_section.html.slim @@ -1,10 +1,10 @@ - press_summary = form_answer.press_summary || form_answer.build_press_summary - url = press_summary.persisted? ? polymorphic_url([namespace_name, form_answer, press_summary]) : polymorphic_url([namespace_name, form_answer, :press_summaries]) -= simple_form_for press_summary, url: url, remote: true, authenticity_token: true do |f| += simple_form_for press_summary, url: url, remote: true, authenticity_token: true, html: { data: { controller: "inline-flash", inline_flash_target: "form" } } do |f| = f.input :body_update, as: :hidden, input_html: {value: true} - .form-group.press-summary-body-block + .form-group.press-summary-body-block[data-controller="element-focus"] label.form-label Body .js-hint-visible-on-edit | Please type, rather than copy from a word processor. @@ -20,19 +20,19 @@ .clear - if policy(press_summary).update? - = link_to "#", class: "form-edit-link pull-right" do + = link_to "#", class: "form-edit-link pull-right", data: { element_focus_target: "reveal" } do span.glyphicon.glyphicon-pencil ' Edit .form-actions.text-right - = link_to "Cancel", "#", class: "btn btn-default form-cancel-link if-no-js-hide" + = link_to "Cancel", "#", class: "btn btn-default form-cancel-link if-no-js-hide", data: { element_focus_target: "dismiss" } = f.submit "Save", class: "btn btn-primary form-save-link pull-right" .clear - if policy(press_summary).update? - = simple_form_for press_summary, url: url, remote: true, authenticity_token: true do |f| + = simple_form_for press_summary, url: url, remote: true, authenticity_token: true, html: { data: { controller: "inline-flash", inline_flash_target: "form" } } do |f| = f.input :contact_details_update, as: :hidden, input_html: {value: true} - .form-group + .form-group[data-controller="element-focus"] label.form-label Contact details for press enquiries - if form_answer.award_year.year >= 2020 diff --git a/app/views/admin/settings/_deadline_form.html.slim b/app/views/admin/settings/_deadline_form.html.slim index 0a1925e3f..145f624ae 100644 --- a/app/views/admin/settings/_deadline_form.html.slim +++ b/app/views/admin/settings/_deadline_form.html.slim @@ -2,13 +2,13 @@ - deadline = deadline.decorate if deadline.present? - if deadline.present? - .deadline id="deadline-#{deadline.id}" + .deadline[id="deadline-#{deadline.id}" data-controller="element-focus inline-flash"] span.date-time-text => deadline.message span.trigger-at = deadline.formatted_trigger_time .deadline-form.well - = simple_form_for deadline, url: admin_settings_deadline_path(deadline, year: params[:year]), remote: true, authenticity_token: true do |f| + = simple_form_for deadline, url: admin_settings_deadline_path(deadline, year: params[:year]), remote: true, authenticity_token: true, html: { data: { inline_flash_target: "form" } } do |f| .control-date label.control-label Set date and time .clear @@ -18,11 +18,11 @@ input_html: { id: '' } .control-action - = link_to "Cancel", "#", class: "btn btn-default btn-cancel if-no-js-hide", role: "button" - input type="button" value="Save" class="btn btn-primary btn-submit" aria-label="Save #{I18n.t("deadline_buttons.#{kind}")}" + = link_to "Cancel", "#", class: "btn btn-default btn-cancel if-no-js-hide", role: "button", data: { element_focus_target: "dismiss" } + input[type="button" value="Save" class="btn btn-primary btn-submit" aria-label="Save #{I18n.t("deadline_buttons.#{kind}")}"] .clear - = link_to "Edit", "#", class: "edit-deadline if-no-js-hide", role: "button", aria: {label: "Edit #{I18n.t("deadline_buttons.#{kind}")}"} + = link_to "Edit", "#", class: "edit-deadline if-no-js-hide", role: "button", aria: {label: "Edit #{I18n.t("deadline_buttons.#{kind}")}"}, data: { element_focus_target: "reveal" } span.deadline-help - if deadline.help_message.present? diff --git a/app/views/admin/settings/_email_notification.html.slim b/app/views/admin/settings/_email_notification.html.slim index b4e8ea706..4fac1ba1b 100644 --- a/app/views/admin/settings/_email_notification.html.slim +++ b/app/views/admin/settings/_email_notification.html.slim @@ -1,7 +1,7 @@ - notifications = @email_notifications.select { |n| n.kind == kind } - notifications = EmailNotificationDecorator.decorate_collection(notifications) -.panel-section id="email_notification_#{kind}" +.panel-section[id="email_notification_#{kind}" data-controller="element-focus"] p = I18n.t("email_notification_headers.#{kind}") @@ -17,11 +17,12 @@ .email-example.well = MailRenderer.new.public_send(kind) - = link_to "+ Schedule new email", "#", class: "btn btn-default btn-add-schedule if-no-js-hide", role: "button", aria: {label: "Schedule #{I18n.t("email_buttons.#{kind}")}"} + = link_to "+ Schedule new email", "#", class: "btn btn-default btn-add-schedule if-no-js-hide", role: "button", aria: {label: "Schedule #{I18n.t("email_buttons.#{kind}")}"}, data: { element_focus_target: "reveal" } - .notification-form - = render "schedule_new", notification: @settings.email_notifications.build(kind: kind), kind: kind + div[data-controller="inline-flash"] + .notification-form + = render "schedule_new", notification: @settings.email_notifications.build(kind: kind), kind: kind - ul.notifications - - notifications.each do |notification| - = render 'notification', notification: notification.decorate + ul.notifications + - notifications.each do |notification| + = render "notification", notification: notification.decorate diff --git a/app/views/admin/settings/_notification.html.slim b/app/views/admin/settings/_notification.html.slim index f2485fae9..29e98f911 100644 --- a/app/views/admin/settings/_notification.html.slim +++ b/app/views/admin/settings/_notification.html.slim @@ -16,7 +16,7 @@ li id="notification-#{notification.id}" ' | = button_to "Delete", admin_settings_email_notification_path(notification), { onclick: "return confirm('Are you sure?')", method: :delete, remote: true } .notification-edit-form.well - = simple_form_for notification, url: admin_settings_email_notification_path(notification, year: params[:year]), remote: true, authenticity_token: true do |f| + = simple_form_for notification, url: admin_settings_email_notification_path(notification, year: params[:year]), remote: true, authenticity_token: true, html: { data: { inline_flash_target: "form" } } do |f| .control-date label.control-label Edit schedule = f.input :trigger_at, diff --git a/app/views/admin/settings/_schedule_new.html.slim b/app/views/admin/settings/_schedule_new.html.slim index d35078aad..75200c4c0 100644 --- a/app/views/admin/settings/_schedule_new.html.slim +++ b/app/views/admin/settings/_schedule_new.html.slim @@ -3,7 +3,7 @@ .well.question-group.notification-new-form h3 Schedule new email - = simple_form_for notification, url: admin_settings_email_notifications_path(year: params[:year]), remote: true, authenticity_token: true, html: { id: "new_email_notification_#{kind}" } do |f| + = simple_form_for notification, url: admin_settings_email_notifications_path(year: params[:year]), remote: true, authenticity_token: true, html: { id: "new_email_notification_#{kind}", data: { inline_flash_target: "form" } } do |f| = f.input :kind, as: :hidden, input_html: { id: "email_notification_kind_#{kind}" } .control-date .form-group @@ -13,6 +13,6 @@ input_html: { id: "" } .control-action - = link_to "Cancel", "#", class: "btn btn-default btn-cancel if-no-js-hide", role: "button" + = link_to "Cancel", "#", class: "btn btn-default btn-cancel if-no-js-hide", role: "button", data: { element_focus_target: "dismiss" } = f.submit "Save", class: "btn btn-primary btn-submit" .clear diff --git a/app/views/admin/users/_fields_password.html.slim b/app/views/admin/users/_fields_password.html.slim index 02de52d9a..e9ce0f421 100644 --- a/app/views/admin/users/_fields_password.html.slim +++ b/app/views/admin/users/_fields_password.html.slim @@ -18,6 +18,14 @@ - else = f.label :password, label: "Password" - password_hint = "" + .guidance-panel.if-no-js-hide + .govuk-form-group--error#password-guidance + p.govuk-error-message.text-underline Please improve your password + p.govuk-error-message#password-too-short + ' It must be at least 10 characters. + p.govuk-error-message#parts-of-email It shouldn't include part or all of your email address. + p.govuk-error-message#password-entropy + ' It must be more complex. Consider using whole sentences (with spaces), lyrics or phrases to make it more memorable. .row .col-md-4.col-sm-6 .input-group @@ -25,22 +33,15 @@ wrapper_html: { class: "form-group" }, input_html: { class: "form-control password-strength-meter" }, label_html: { class: "visuallyhidden" } - span#password-result-span.input-group-addon + span#password-result-span.input-group-addon.hide i#password-result.glyphicon.glyphicon-ok span.hint = password_hint - .guidance-panel.if-no-js-hide - #password-guidance - .alert.alert-warning - p.text-underline Please improve your password - p#password-too-short - ' It must be at least 10 characters. - p#parts-of-email It shouldn't include part or all of your email address. - p#password-entropy - ' It must be more complex. Consider using whole sentences (with spaces), lyrics or phrases to make it more memorable. - .question-group#password-confirmation-control-group h3 = f.label :password_confirmation, label: "Retype password" + .if-no-js-hide + .govuk-form-group--error#password-confirmation-guidance + p.govuk-error-message#password-confirmation-match The confirmation must match the password .row .col-md-4.col-sm-6 .input-group @@ -48,11 +49,5 @@ wrapper_html: { class: "form-group" }, input_html: { class: "form-control" }, label_html: { class: "visuallyhidden" } - span#password-confirmation-result-span.input-group-addon + span#password-confirmation-result-span.input-group-addon.hide i#password-confirmation-result.glyphicon.glyphicon-ok - - .if-no-js-hide - #password-confirmation-guidance - br - .alert.alert-warning - p#password-confirmation-match The confirmation must match the password diff --git a/app/views/admin/users/_fields_user_details.html.slim b/app/views/admin/users/_fields_user_details.html.slim index fe631fe3d..8503be267 100644 --- a/app/views/admin/users/_fields_user_details.html.slim +++ b/app/views/admin/users/_fields_user_details.html.slim @@ -5,7 +5,7 @@ .col-md-1.col-sm-2 = f.input :title, wrapper_html: { class: "form-group" }, - input_html: { class: "form-control" }, + input_html: { autofocus: true, class: "form-control" }, label: false .question-group diff --git a/app/views/admin/users/_form.html.slim b/app/views/admin/users/_form.html.slim index d2bde7535..265768a63 100644 --- a/app/views/admin/users/_form.html.slim +++ b/app/views/admin/users/_form.html.slim @@ -1,47 +1,47 @@ -= simple_form_for [:admin, resource], html: { class: "qae-form" } do |f| += simple_form_for [:admin, resource], html: { class: "qae-form", data: { type: "json", controller: "inline-flash", inline_flash_target: "form" } } do |f| .panel-group#user-form-panel-parent - .panel.panel-default + .panel.panel-default[data-controller="element-focus"] .panel-heading#user-details-heading h2.panel-title - a data-toggle="collapse" data-parent="#user-form-panel" href="#user-details" aria-expanded="true" aria-controls="user-details" + a data-toggle="collapse" data-parent="#user-form-panel" href="#user-details" aria-expanded="true" aria-controls="user-details" data-element-focus-target="reveal" = controller_name == "users" ? "Applicant" : controller_name.singularize.titleize ' Details #user-details.section-user-details.panel-collapse.collapse.in aria-labelledby="user-details-heading" .panel-body = render "fields_user_details", f: f - .panel.panel-default + .panel.panel-default[data-controller="element-focus"] .panel-heading id="organisation-details-header" h2.panel-title - a.collapsed data-toggle="collapse" data-parent="#user-form-panel" href="#organisation-details" aria-expanded="false" aria-controls="organisation-details" + a.collapsed data-toggle="collapse" data-parent="#user-form-panel" href="#organisation-details" aria-expanded="false" aria-controls="organisation-details" data-element-focus-target="reveal" ' Organisation Details #organisation-details.section-organisation-details.panel-collapse.collapse aria-labelledby="organisation-details-header" .panel-body = render "fields_organisation_details", f: f - .panel.panel-default + .panel.panel-default[data-controller="element-focus"] .panel-heading id="contact-preferences-header" h2.panel-title - a.collapsed data-toggle="collapse" data-parent="#user-form-panel" href="#contact-preferences" aria-expanded="false" aria-controls="contact-preferences" + a.collapsed data-toggle="collapse" data-parent="#user-form-panel" href="#contact-preferences" aria-expanded="false" aria-controls="contact-preferences" data-element-focus-target="reveal" ' Contact Preferences #contact-preferences.section-contact-preferences.panel-collapse.collapse aria-labelledby="contact-preferences-header" .panel-body = render "fields_contact_preferences", f: f - unless action_name == "new" - .panel.panel-default + .panel.panel-default[data-controller="element-focus"] .panel-heading id="section-collaborators-header" h2.panel-title - a.collapsed data-toggle="collapse" data-parent="#user-form-panel" href="#section-collaborators" aria-expanded="false" aria-controls="section-collaborators" + a.collapsed data-toggle="collapse" data-parent="#user-form-panel" href="#section-collaborators" aria-expanded="false" aria-controls="section-collaborators" data-element-focus-target="reveal" ' Collaborators #section-collaborators.section-collaborators.panel-collapse.collapse aria-labelledby="section-collaborators-header" .panel-body = render "fields_collaborators", f: f, resource: resource - .panel.panel-default + .panel.panel-default[data-controller="element-focus"] .panel-heading id="section-password-header" h2.panel-title - a.collapsed data-toggle="collapse" data-parent="#user-form-panel" href="#section-password" aria-expanded="false" aria-controls="section-password" + a.collapsed data-toggle="collapse" data-parent="#user-form-panel" href="#section-password" aria-expanded="false" aria-controls="section-password" data-element-focus-target="reveal" ' Password #section-password.section-password.panel-collapse.collapse aria-labelledby="section-password-header" .panel-body diff --git a/app/views/assessor/form_answers/_bulk_assignment.html.slim b/app/views/assessor/form_answers/_bulk_assignment.html.slim index d04f8915e..78ffd2bee 100644 --- a/app/views/assessor/form_answers/_bulk_assignment.html.slim +++ b/app/views/assessor/form_answers/_bulk_assignment.html.slim @@ -1,6 +1,6 @@ - if show_bulk_assignment? - .if-no-js-hide - .btn.bulk-assign-assessors-link Bulk Assign Assessors + .if-no-js-hide[data-controller="element-focus"] + .btn.bulk-assign-assessors-link[data-element-focus-target="reveal"] Bulk Assign Assessors .bulk-assign-assessors-form .well @@ -29,6 +29,6 @@ = f.text_field :form_answer_ids, class: "if-js-hide visuallyhidden" .pull-right - = link_to "Cancel", "#", class: "btn btn-default if-no-js-hide bulk-assign-assessors-cancel-link" + = link_to "Cancel", "#", class: "btn btn-default if-no-js-hide bulk-assign-assessors-cancel-link", data: { element_focus_target: "dismiss" } = f.submit "Assign", class: "btn btn-primary" .clear diff --git a/app/views/assessor/form_answers/_submitted_view.html.slim b/app/views/assessor/form_answers/_submitted_view.html.slim index daad1b373..aeab1be95 100644 --- a/app/views/assessor/form_answers/_submitted_view.html.slim +++ b/app/views/assessor/form_answers/_submitted_view.html.slim @@ -45,7 +45,7 @@ small = @form_answer.feedback_updated_by #section-feedback.section-application-info.panel-collapse.collapse aria-labelledby="feedback-heading" - .panel-body + .panel-body[data-controller="inline-flash"] = render "admin/feedbacks/section", form_answer: @form_answer - if show_winners_section? diff --git a/app/views/assessor/form_answers/index.html.slim b/app/views/assessor/form_answers/index.html.slim index 99b88c377..80ef5bf70 100644 --- a/app/views/assessor/form_answers/index.html.slim +++ b/app/views/assessor/form_answers/index.html.slim @@ -34,25 +34,19 @@ h1.admin-page-heading = simple_form_for @search, url: assessor_form_answers_path, method: :get, as: :search, html: { class: 'search-form', id: 'application_table_search_form' } do |f| = hidden_field_tag :award_type, category_picker.current_award_type, id: "award_type_application_table_search_form" - label for="year" class="visuallyhidden" aria-hidden="true" - ' Award year - = text_field_tag :year, @award_year.year, class: "visuallyhidden", aria: { hidden: true } + = hidden_field_tag :year, @award_year.year - # status filters need to be here because the filtering is done in the other form above, so in order not to break filtering, we need to duplicate it here = f.simple_fields_for [:filters, @search.filters] do |h| - = h.label :status, class: "visuallyhidden", for: "status_application_table_search_form", aria: { hidden: true } = h.input :status, collection: FormAnswerStatus::AssessorFilter.options, label: false, - input_html: { multiple: true, class: 'visuallyhidden', id: 'status_application_table_search_form' }, - aria: { hidden: true } + input_html: { multiple: true, id: 'status_application_table_search_form', class: 'hide' } - = h.label :sub_status, class: "visuallyhidden", for: "sub_status_application_table_search_form", aria: { hidden: true } = h.input :sub_status, collection: FormAnswerStatus::AssessorFilter.sub_options(current_assessor), label: false, - input_html: { multiple: true, class: 'visuallyhidden', id: 'sub_status_application_table_search_form'}, - aria: { hidden: true } + input_html: { multiple: true, id: 'sub_status_application_table_search_form', class: 'hide'} .row .col-xs-12 @@ -61,7 +55,6 @@ h1.admin-page-heading tr - if current_subject.categories_as_lead.include?(category_picker.current_award_type) th - span.visuallyhidden Select for bulk action span.if-no-js-hide = check_box_tag :check_all, "Check all", false, aria: { label: "Select all applications for bulk action" } th.sortable width="250" diff --git a/app/views/layouts/application-admin.html.slim b/app/views/layouts/application-admin.html.slim index 3bd3ec372..25b0cbe50 100644 --- a/app/views/layouts/application-admin.html.slim +++ b/app/views/layouts/application-admin.html.slim @@ -122,4 +122,5 @@ html.no-js - if should_enable_js? = javascript_include_tag 'application-admin' + = javascript_pack_tag 'application-admin' = javascript_tag "$(function() { AdminAssessorAutomatedPollingOfSession.init('admin'); });" diff --git a/app/views/layouts/application-assessor.html.slim b/app/views/layouts/application-assessor.html.slim index 5a67e432b..6323148a3 100644 --- a/app/views/layouts/application-assessor.html.slim +++ b/app/views/layouts/application-assessor.html.slim @@ -96,4 +96,5 @@ html.no-js - if should_enable_js? = javascript_include_tag 'application-admin' + = javascript_pack_tag 'application-admin' = javascript_tag "$(function() { AdminAssessorAutomatedPollingOfSession.init('assessor'); });" diff --git a/app/views/layouts/application-judge.html.slim b/app/views/layouts/application-judge.html.slim index 3fd42c2fc..a1d45d573 100644 --- a/app/views/layouts/application-judge.html.slim +++ b/app/views/layouts/application-judge.html.slim @@ -93,4 +93,5 @@ html.no-js - if should_enable_js? = javascript_include_tag 'application-admin' + = javascript_pack_tag 'application-admin' = javascript_tag "$(function() { AdminAssessorAutomatedPollingOfSession.init('judge'); });" diff --git a/app/views/layouts/application.html.slim b/app/views/layouts/application.html.slim index fa4520555..0c12654f2 100644 --- a/app/views/layouts/application.html.slim +++ b/app/views/layouts/application.html.slim @@ -1,4 +1,4 @@ -title = content_for?(:title) ? yield(:title) + " - King's Awards for Enterprise" : "King's Awards for Enterprise" +title = content_for?(:title) ? "#{'Appraisal view of ' if admin_in_read_only_mode?}" + yield(:title) + " - King's Awards for Enterprise" : "King's Awards for Enterprise" - content_for :head do = stylesheet_link_tag "application.css" diff --git a/app/views/qae_form/_address_question.html.slim b/app/views/qae_form/_address_question.html.slim index 3044f0867..711cdb6dc 100644 --- a/app/views/qae_form/_address_question.html.slim +++ b/app/views/qae_form/_address_question.html.slim @@ -14,7 +14,15 @@ div role="group" id="q_#{question.key}" | Error: = @form_answer.validator_errors[question.hash_key(suffix: "building")] span.govuk-error-message - input.govuk-input.govuk-input--width-10.js-trigger-autosave.required type="text" name=question.input_name(suffix: 'building') value=question.input_value(suffix: 'building') autocomplete="off" id="q_#{question.key}_line_1" *possible_read_only_ops aria-describedby=(@form_answer.validator_errors && @form_answer.validator_errors[question.hash_key] ? "error_for_building" : nil ) + input.govuk-input.govuk-input--width-10.js-trigger-autosave.required[ + type="text" + name=question.input_name(suffix: 'building') + value=question.input_value(suffix: 'building') + autocomplete="off" + id="q_#{question.key}_line_1" *possible_read_only_ops + aria-describedby=(@form_answer.validator_errors && @form_answer.validator_errors[question.hash_key] ? "error_for_building" : nil ) + ] + .govuk-form-group.question-required label.govuk-label for="q_#{question.key}_line_2" ' Street @@ -24,12 +32,20 @@ div role="group" id="q_#{question.key}" | Error: = @form_answer.validator_errors[question.hash_key(suffix: "street")] span.govuk-error-message - input.govuk-input.govuk-input--width-10.js-trigger-autosave type="text" name=question.input_name(suffix: 'street') value=question.input_value(suffix: 'street') autocomplete="off" id="q_#{question.key}_line_2" *possible_read_only_ops aria-describedby=(@form_answer.validator_errors && @form_answer.validator_errors[question.hash_key] ? "error_for_street" : nil ) + input.govuk-input.govuk-input--width-10.js-trigger-autosave[ + type="text" + name=question.input_name(suffix: 'street') + value=question.input_value(suffix: 'street') + autocomplete="off" + id="q_#{question.key}_line_2" *possible_read_only_ops + aria-describedby=(@form_answer.validator_errors && @form_answer.validator_errors[question.hash_key] ? "error_for_street" : nil ) + ] + - when :country .govuk-form-group.question-required label.govuk-label for="#{question.key}_country" ' Country - = country_select(question.step.form.form_name, "#{question.key}_country", {priority_countries: ["GB", "US"], selected: question.input_value(suffix: 'country')}, possible_read_only_ops.merge({name: question.input_name(suffix: 'country'), class: 'js-trigger-autosave required custom-select govuk-!-width-one-half', aria: {describedby:(@form_answer.validator_errors && @form_answer.validator_errors[question.hash_key] ? "error_for_country" : nil )}})) + = country_select(question.step.form.form_name, "#{question.key}_country", { priority_countries: ["GB", "US"], selected: question.input_value(suffix: 'country') }, possible_read_only_ops.merge({ name: question.input_name(suffix: 'country'), class: 'js-trigger-autosave required custom-select govuk-!-width-one-half', aria: {describedby:(@form_answer.validator_errors && @form_answer.validator_errors[question.hash_key] ? "error_for_country" : nil )}, data: {subfield: "Country"}})) - if @form_answer.validator_errors&.dig(question.hash_key(suffix: sub_field_key)) span.govuk-error-message span.govuk-visually-hidden @@ -40,7 +56,7 @@ div role="group" id="q_#{question.key}" - when :county .govuk-form-group.question-required - label.govuk-label id="#{question.key}_region_label" for="#{question.key}_county" aria-describedby="#{question.key}_county_hint" + label.govuk-label id="#{question.key}_region_label" for="form_#{question.key}_#{sub_field_key}" aria-describedby="#{question.key}_county_hint" ' County - if @form_answer.validator_errors&.dig(question.hash_key(suffix: sub_field_key)) span.govuk-error-message @@ -54,7 +70,7 @@ div role="group" id="q_#{question.key}" .question-context[id="#{question.key}_county_hint"] == question.county_context - = select_tag("#{question.key}_county", options_for_select(question.counties, question.input_value(suffix: "county")), possible_read_only_ops.merge({name: question.input_name(suffix: 'county'), class: "js-trigger-autosave required custom-select govuk-!-width-one-third", include_blank: true, aria: { label: "Select #{question.key}", describedby:(@form_answer.validator_errors && @form_answer.validator_errors[question.hash_key] ? "error_for_county" : nil )}})) + = select_tag(question.input_name(suffix: sub_field_key), options_for_select(question.counties, question.input_value(suffix: "county")), possible_read_only_ops.merge({ name: question.input_name(suffix: 'county'), class: "js-trigger-autosave required custom-select govuk-!-width-one-third", include_blank: true, aria: { label: "Select #{question.key}", describedby:(@form_answer.validator_errors && @form_answer.validator_errors[question.hash_key] ? "error_for_county" : nil )}})) - else .govuk-form-group.question-required @@ -70,4 +86,12 @@ div role="group" id="q_#{question.key}" - klass = "#{sub_field_title.parameterize == 'postcode' ? 'govuk-input--width-10' : 'govuk-input--width-20'}" - klass <<(QAEFormBuilder::AddressQuestionValidator::NO_VALIDATION_SUB_FIELDS.exclude?(sub_field_key) ? " required" : " not-required") - input.govuk-input.js-trigger-autosave class=klass type="text" id=question.input_name(suffix: sub_field_key) value=question.input_value(suffix: sub_field_key) name=question.input_name(suffix: sub_field_key) autocomplete="off" *possible_read_only_ops aria-describedby=(@form_answer.validator_errors && @form_answer.validator_errors[question.hash_key] ? "error_for_#{sub_field_key}" : nil ) + input.govuk-input.js-trigger-autosave[ + class=klass + type="text" + id=question.input_name(suffix: sub_field_key) + value=question.input_value(suffix: sub_field_key) + name=question.input_name(suffix: sub_field_key) + autocomplete="off" *possible_read_only_ops + aria-describedby=(@form_answer.validator_errors && @form_answer.validator_errors[question.hash_key] ? "error_for_#{sub_field_key}" : nil ) + ] diff --git a/app/views/qae_form/_press_contact_details_question.html.slim b/app/views/qae_form/_press_contact_details_question.html.slim index 335faf4ef..995857a63 100644 --- a/app/views/qae_form/_press_contact_details_question.html.slim +++ b/app/views/qae_form/_press_contact_details_question.html.slim @@ -1,25 +1,27 @@ -.govuk-form-group.question-block.question-required - label.govuk-label for=question.input_name(suffix:'title') - ' Title - span.govuk-error-message - input.js-trigger-autosave.govuk-input.tiny type="text" name=question.input_name(suffix: 'title') value=question.input_value(suffix: 'title') autocomplete="off" *possible_read_only_ops id=question.input_name(suffix: 'title') -.govuk-form-group.question-block.question-required - label.govuk-label for=question.input_name(suffix:'first_name') - ' First name - span.govuk-error-message - input.js-trigger-autosave.govuk-input.govuk-input--width-10 type="text" name=question.input_name(suffix: 'first_name') value=question.input_value(suffix: 'first_name') autocomplete="off" *possible_read_only_ops id=question.input_name(suffix: 'first_name') -.govuk-form-group.question-block.question-required - label.govuk-label for=question.input_name(suffix:'last_name') - ' Last name - span.govuk-error-message - input.js-trigger-autosave.govuk-input.govuk-input--width-10 type="text" name=question.input_name(suffix: 'last_name') value=question.input_value(suffix: 'last_name') autocomplete="off" *possible_read_only_ops id=question.input_name(suffix: 'last_name') -.govuk-form-group.question-block.question-required - label.govuk-label for=question.input_name(suffix:'telephone') - ' Telephone - span.govuk-error-message - input.js-trigger-autosave.govuk-input.govuk-input--width-10 type="tel" pattern="[0-9]*" name=question.input_name(suffix: 'telephone') value=question.input_value(suffix: 'telephone') autocomplete="off" *possible_read_only_ops id=question.input_name(suffix: 'telephone') -.govuk-form-group.question-block.question-required - label.govuk-label for=question.input_name(suffix:'email') - ' Email address - span.govuk-error-message - input.js-trigger-autosave.govuk-input.large type="email" name=question.input_name(suffix: 'email') value=question.input_value(suffix: 'email') autocomplete="off" *possible_read_only_ops id=question.input_name(suffix: 'email') +.govuk-form-group + div role="group" id="#{question.key}" + .question-block.question-required + label.govuk-label for=question.input_name(suffix:'title') + ' Title + span.govuk-error-message + input.js-trigger-autosave.govuk-input.tiny type="text" name=question.input_name(suffix: 'title') value=question.input_value(suffix: 'title') autocomplete="off" *possible_read_only_ops id=question.input_name(suffix: 'title') + .question-block.question-required + label.govuk-label for=question.input_name(suffix:'first_name') + ' First name + span.govuk-error-message + input.js-trigger-autosave.govuk-input.govuk-input--width-10 type="text" name=question.input_name(suffix: 'first_name') value=question.input_value(suffix: 'first_name') autocomplete="off" *possible_read_only_ops id=question.input_name(suffix: 'first_name') + .question-block.question-required + label.govuk-label for=question.input_name(suffix:'last_name') + ' Last name + span.govuk-error-message + input.js-trigger-autosave.govuk-input.govuk-input--width-10 type="text" name=question.input_name(suffix: 'last_name') value=question.input_value(suffix: 'last_name') autocomplete="off" *possible_read_only_ops id=question.input_name(suffix: 'last_name') + .question-block.question-required + label.govuk-label for=question.input_name(suffix:'telephone') + ' Telephone + span.govuk-error-message + input.js-trigger-autosave.govuk-input.govuk-input--width-10 type="tel" pattern="[0-9]*" name=question.input_name(suffix: 'telephone') value=question.input_value(suffix: 'telephone') autocomplete="off" *possible_read_only_ops id=question.input_name(suffix: 'telephone') + .question-block.question-required + label.govuk-label for=question.input_name(suffix:'email') + ' Email address + span.govuk-error-message + input.js-trigger-autosave.govuk-input.large type="email" name=question.input_name(suffix: 'email') value=question.input_value(suffix: 'email') autocomplete="off" *possible_read_only_ops id=question.input_name(suffix: 'email') diff --git a/app/views/qae_form/_queen_award_applications_question.html.slim b/app/views/qae_form/_queen_award_applications_question.html.slim index dbc8837bb..c6722ccf2 100644 --- a/app/views/qae_form/_queen_award_applications_question.html.slim +++ b/app/views/qae_form/_queen_award_applications_question.html.slim @@ -41,7 +41,7 @@ div role="group" id="q_#{question.key}" | Category span.govuk-error-message span.if-no-js-hide - select.govuk-select.js-trigger-autosave name="form[applied_for_queen_awards_details][#{index}][category]" data-dependable-values=dependable_values data-parent-option-dependable-key=question.key data-dependable-option-siffix="category" data-input-value="category" class=("js-options-with-dependent-child-select" if children_depends_on.present?) *possible_read_only_ops id="form[applied_for_queen_awards_details][#{index}][category]" + select.govuk-select.custom-select.js-trigger-autosave name="form[applied_for_queen_awards_details][#{index}][category]" data-dependable-values=dependable_values data-parent-option-dependable-key=question.key data-dependable-option-siffix="category" data-input-value="category" class=("js-options-with-dependent-child-select" if children_depends_on.present?) *possible_read_only_ops id="form[applied_for_queen_awards_details][#{index}][category]" option value="" ' Category - question.categories.each do |category| @@ -57,7 +57,7 @@ div role="group" id="q_#{question.key}" | Year span.govuk-error-message span.if-no-js-hide - select.govuk-select.js-trigger-autosave name="form[applied_for_queen_awards_details][#{index}][year]" data-dependable-option-siffix="year" data-input-value="year" data-parent-option-dependable-key=question.key class=("js-options-with-dependent-child-select" if children_depends_on.present?) *possible_read_only_ops id="form[applied_for_queen_awards_details][#{index}][year]" + select.govuk-select.custom-select.js-trigger-autosave name="form[applied_for_queen_awards_details][#{index}][year]" data-dependable-option-siffix="year" data-input-value="year" data-parent-option-dependable-key=question.key class=("js-options-with-dependent-child-select" if children_depends_on.present?) *possible_read_only_ops id="form[applied_for_queen_awards_details][#{index}][year]" option value="" ' Year - question.years.each do |year| @@ -73,7 +73,7 @@ div role="group" id="q_#{question.key}" | Outcome (Won/Did not win) span.govuk-error-message span.if-no-js-hide - select.govuk-select.js-trigger-autosave name="form[applied_for_queen_awards_details][#{index}][outcome]" data-dependable-values=dependable_values data-parent-option-dependable-key=question.key data-dependable-option-siffix="outcome" data-input-value="outcome" class=("js-options-with-dependent-child-select" if children_depends_on.present?) *possible_read_only_ops id="form[applied_for_queen_awards_details][#{index}][outcome]" + select.govuk-select.custom-select.js-trigger-autosave name="form[applied_for_queen_awards_details][#{index}][outcome]" data-dependable-values=dependable_values data-parent-option-dependable-key=question.key data-dependable-option-siffix="outcome" data-input-value="outcome" class=("js-options-with-dependent-child-select" if children_depends_on.present?) *possible_read_only_ops id="form[applied_for_queen_awards_details][#{index}][outcome]" option value="" ' Outcome (Won/Did not win) - question.outcomes.each do |outcome| @@ -96,7 +96,7 @@ div role="group" id="q_#{question.key}" label.govuk-label for="form[applied_for_queen_awards_details][0][category]" | Category span.govuk-error-message - select.govuk-select.js-trigger-autosave name="form[applied_for_queen_awards_details][0][category]" data-dependable-values=dependable_values data-parent-option-dependable-key=question.key data-dependable-option-siffix="category" class=("js-options-with-dependent-child-select" if children_depends_on.present?) *possible_read_only_ops + select.govuk-select.custom-select.js-trigger-autosave name="form[applied_for_queen_awards_details][0][category]" data-dependable-values=dependable_values data-parent-option-dependable-key=question.key data-dependable-option-siffix="category" id="form[applied_for_queen_awards_details][0][category]" class=("js-options-with-dependent-child-select" if children_depends_on.present?) *possible_read_only_ops option value="" ' Category - question.categories.each do |category| @@ -107,7 +107,7 @@ div role="group" id="q_#{question.key}" label.govuk-label for="form[applied_for_queen_awards_details][0][year]" | Year span.govuk-error-message - select.govuk-select.js-trigger-autosave name="form[applied_for_queen_awards_details][0][year]" data-dependable-option-siffix="year" data-parent-option-dependable-key=question.key class=("js-options-with-dependent-child-select" if children_depends_on.present?) *possible_read_only_ops + select.govuk-select.custom-select.js-trigger-autosave name="form[applied_for_queen_awards_details][0][year]" data-dependable-option-siffix="year" data-parent-option-dependable-key=question.key id="form[applied_for_queen_awards_details][0][year]" class=("js-options-with-dependent-child-select" if children_depends_on.present?) *possible_read_only_ops option value="" ' Year - question.years.each do |year| @@ -118,7 +118,7 @@ div role="group" id="q_#{question.key}" label.govuk-label for="form[applied_for_queen_awards_details][0][outcome]" | Outcome (Won/Did not win) span.govuk-error-message - select.govuk-select.js-trigger-autosave name="form[applied_for_queen_awards_details][0][outcome]" data-dependable-values=dependable_values data-parent-option-dependable-key=question.key data-dependable-option-siffix="outcome" class=("js-options-with-dependent-child-select" if children_depends_on.present?) *possible_read_only_ops + select.govuk-select.custom-select.js-trigger-autosave name="form[applied_for_queen_awards_details][0][outcome]" data-dependable-values=dependable_values data-parent-option-dependable-key=question.key data-dependable-option-siffix="outcome" id="form[applied_for_queen_awards_details][0][outcome]" class=("js-options-with-dependent-child-select" if children_depends_on.present?) *possible_read_only_ops option value="" ' Outcome (Won/Did not win) - question.outcomes.each do |outcome| diff --git a/app/views/qae_form/_queen_award_holder_question.html.slim b/app/views/qae_form/_queen_award_holder_question.html.slim index 608224502..99181bfc3 100644 --- a/app/views/qae_form/_queen_award_holder_question.html.slim +++ b/app/views/qae_form/_queen_award_holder_question.html.slim @@ -38,7 +38,7 @@ div role="group" id="q_#{question.key}" aria-labelledby="q_#{question.key}_label label.govuk-form-label for="form[queen_award_holder_details][#{index}][category]" | Category div.if-no-js-hide - select.inline.govuk-select.js-trigger-autosave name="form[queen_award_holder_details][#{index}][category]" data-dependable-values=dependable_values data-parent-option-dependable-key=question.key data-dependable-option-siffix="category" class=("js-options-with-dependent-child-select" if children_depends_on.present?) *possible_read_only_ops + select.inline.custom-select.govuk-select.js-trigger-autosave name="form[queen_award_holder_details][#{index}][category]" data-dependable-values=dependable_values data-parent-option-dependable-key=question.key data-dependable-option-siffix="category" class=("js-options-with-dependent-child-select" if children_depends_on.present?) *possible_read_only_ops option value="" ' Category - question.categories.each do |category| @@ -52,7 +52,7 @@ div role="group" id="q_#{question.key}" aria-labelledby="q_#{question.key}_label label.govuk-form-label name="form[queen_award_holder_details][#{index}][year]" | Year Awarded span.if-no-js-hide - select.govuk-select.inline.js-trigger-autosave name="form[queen_award_holder_details][#{index}][year]" data-dependable-option-siffix="year" data-parent-option-dependable-key=question.key class=("js-options-with-dependent-child-select" if children_depends_on.present?) *possible_read_only_ops + select.govuk-select.custom-select.inline.js-trigger-autosave name="form[queen_award_holder_details][#{index}][year]" data-dependable-option-siffix="year" data-parent-option-dependable-key=question.key class=("js-options-with-dependent-child-select" if children_depends_on.present?) *possible_read_only_ops option value="" ' Year Awarded - question.years.each do |year| @@ -72,7 +72,7 @@ div role="group" id="q_#{question.key}" aria-labelledby="q_#{question.key}_label .govuk-form-group label for="form[queen_award_holder_details][0][category]" | Category - select.govuk-select.inline.js-trigger-autosave name="form[queen_award_holder_details][0][category]" data-dependable-values=dependable_values data-parent-option-dependable-key=question.key data-dependable-option-siffix="category" class=("js-options-with-dependent-child-select" if children_depends_on.present?) *possible_read_only_ops + select.govuk-select.custom-select.inline.js-trigger-autosave name="form[queen_award_holder_details][0][category]" data-dependable-values=dependable_values data-parent-option-dependable-key=question.key data-dependable-option-siffix="category" class=("js-options-with-dependent-child-select" if children_depends_on.present?) *possible_read_only_ops option value="" ' Category - question.categories.each do |category| @@ -83,7 +83,7 @@ div role="group" id="q_#{question.key}" aria-labelledby="q_#{question.key}_label .govuk-form-group label for="form[queen_award_holder_details][0][year]" | Year Awarded - select.govuk-select.inline.js-trigger-autosave name="form[queen_award_holder_details][0][year]" data-dependable-option-siffix="year" data-parent-option-dependable-key=question.key class=("js-options-with-dependent-child-select" if children_depends_on.present?) *possible_read_only_ops + select.govuk-select.custom-select.inline.js-trigger-autosave name="form[queen_award_holder_details][0][year]" data-dependable-option-siffix="year" data-parent-option-dependable-key=question.key class=("js-options-with-dependent-child-select" if children_depends_on.present?) *possible_read_only_ops option value="" ' Year Awarded - question.years.each do |year| diff --git a/app/views/qae_form/_question.html.slim b/app/views/qae_form/_question.html.slim index 4ac4188f2..15bb9cea1 100644 --- a/app/views/qae_form/_question.html.slim +++ b/app/views/qae_form/_question.html.slim @@ -1,3 +1,5 @@ +- ref = question.ref ? question.ref : question.sub_ref + - if question.header h2.govuk-heading-l = question.header @@ -7,10 +9,9 @@ .govuk-form-group == question.context - elsif question.label_as_legend? - fieldset class=question.fieldset_classes data=question.fieldset_data_hash + fieldset class=question.fieldset_classes data=question.fieldset_data_hash data-question_ref="#{ref}" = condition_divs question do .govuk-form-group class=(" govuk-form-group--error" if @form_answer.validator_errors && @form_answer.validator_errors[question.hash_key]) - - ref = question.ref ? question.ref : question.sub_ref - if question.title != "" || question.show_ref_always.present? legend.govuk-fieldset__legend aria-describedby=("hint_for_#{question.key}" if question.context || question.form_hint) - if question.ref || question.sub_ref @@ -73,10 +74,9 @@ = render "qae_form/conditional_hints/list", question: question - else - div class=question.fieldset_classes data=question.fieldset_data_hash + div class=question.fieldset_classes data=question.fieldset_data_hash data-question_ref="#{ref}" = condition_divs question do .govuk-form-group class=(" govuk-form-group--error" if @form_answer.validator_errors && @form_answer.validator_errors[question.hash_key]) - - ref = question.ref ? question.ref : question.sub_ref - if question.title != "" || question.show_ref_always.present? label.govuk-label for="q_#{question.key}" id="q_#{question.key}_label" aria-label="#{ref.to_s.gsub(' ', '-')}: #{question.title}" aria-describedby=("hint_for_#{question.key}" if question.context || question.form_hint) - if question.ref || question.sub_ref diff --git a/app/views/qae_form/_step.html.slim b/app/views/qae_form/_step.html.slim index 48a05fc17..e9d2ed81b 100644 --- a/app/views/qae_form/_step.html.slim +++ b/app/views/qae_form/_step.html.slim @@ -7,6 +7,7 @@ = step.title - if step.context == step.context + input type="hidden" name="form[current_non_js_step]" value="#{step.title.parameterize}" id="non_js_step_title" = render partial: "qae_form/question", collection: step.questions, locals: { answers: answers, attachments: attachments } - if step.submit = render partial: "qae_form/step_submit", object: step.submit, as: 'submit' diff --git a/app/views/qae_form/_sub_fields_question.html.slim b/app/views/qae_form/_sub_fields_question.html.slim new file mode 100644 index 000000000..7e08faf02 --- /dev/null +++ b/app/views/qae_form/_sub_fields_question.html.slim @@ -0,0 +1,39 @@ +div role="group" id="#{question.key}" + - question.rendering_sub_fields.each do |sub_field_block| + - sub_field_key = sub_field_block[:key] + - sub_field_title = sub_field_block[:title] + - sub_field_hint = sub_field_block[:hint] + + .govuk-form-group.question-required + label.govuk-label for=question.input_name(suffix: sub_field_key) value=question.input_value(suffix: sub_field_key) + = sub_field_title + - if @form_answer.validator_errors&.dig(question.hash_key(suffix: sub_field_key)) + span.govuk-error-message + span.govuk-visually-hidden + | Error: + =< @form_answer.validator_errors[question.hash_key(suffix: sub_field_key)] + span.govuk-error-message + - if sub_field_hint + span.govuk-hint + = sub_field_hint + .clear + + - case sub_field_key + - when :email + - klass = 'large' + - when :title + - klass = 'tiny' + - else + - klass = 'govuk-input--width-10' + + - klass <<(QAEFormBuilder::SubFieldsQuestionValidator::NO_VALIDATION_SUB_FIELDS.exclude?(sub_field_key) ? " required" : " not-required") + + input.govuk-input.js-trigger-autosave[ + class=klass + type="text" + id=question.input_name(suffix: sub_field_key) + value=question.input_value(suffix: sub_field_key) + name=question.input_name(suffix: sub_field_key) + autocomplete="off" *possible_read_only_ops + aria-describedby=(@form_answer.validator_errors && @form_answer.validator_errors[question.hash_key] ? "error_for_#{sub_field_key}" : nil ) + ] diff --git a/app/views/qae_form/_text_question.html.slim b/app/views/qae_form/_text_question.html.slim index 6b733cf49..56bdaa66e 100644 --- a/app/views/qae_form/_text_question.html.slim +++ b/app/views/qae_form/_text_question.html.slim @@ -1 +1,11 @@ -input class="govuk-input js-trigger-autosave #{question.style.present? ? question.style : 'govuk-input--width-10'}" type="#{question.type.present? ? question.type.to_s : 'text'}" pattern="#{'[0-9]*' if question.type == 'tel' || question.type == 'number'}" name=question.input_name value=question.input_value autocomplete="off" id="q_#{question.key}" *possible_read_only_ops aria-describedby=(@form_answer.validator_errors && @form_answer.validator_errors[question.hash_key] ? "error_for_#{question.key}" : nil ) +input[ + class="govuk-input js-trigger-autosave + #{question.style.present? ? question.style : 'govuk-input--width-10'}" + type="#{question.type.present? ? question.type.to_s : 'text'}" + pattern="#{'[0-9]*' if question.type == 'tel' || question.type == 'number'}" + name=question.input_name + value=question.input_value + autocomplete="off" + id="q_#{question.key}"*possible_read_only_ops + aria-describedby=(@form_answer.validator_errors && @form_answer.validator_errors[question.hash_key] ? "error_for_#{question.key}" : nil ) +] diff --git a/config/webpack/base.js b/config/webpack/base.js index 034c04933..48d8f5e24 100644 --- a/config/webpack/base.js +++ b/config/webpack/base.js @@ -1,8 +1,15 @@ -const { webpackConfig, merge } = require('@rails/webpacker') +const webpack = require('webpack'); +const { merge, webpackConfig } = require('@rails/webpacker'); + const customConfig = { + plugins: [ + new webpack.ProvidePlugin({ + ApplicationController: ['application_controller', 'default'], + }), + ], resolve: { - extensions: ['.css', '.scss'] - } -} + extensions: ['.css', '.scss'], + }, +}; -module.exports = merge(webpackConfig, customConfig) \ No newline at end of file +module.exports = merge(webpackConfig, customConfig); diff --git a/config/webpack/development.js b/config/webpack/development.js index c84a413b5..8b54a9ce3 100644 --- a/config/webpack/development.js +++ b/config/webpack/development.js @@ -1,5 +1,5 @@ -process.env.NODE_ENV = process.env.NODE_ENV || 'development' +process.env.NODE_ENV = process.env.NODE_ENV || 'development'; -const webpackConfig = require('./base') +const webpackConfig = require('./base'); -module.exports = webpackConfig +module.exports = webpackConfig; diff --git a/config/webpack/production.js b/config/webpack/production.js index c41e04360..e5ef88d10 100644 --- a/config/webpack/production.js +++ b/config/webpack/production.js @@ -1,5 +1,5 @@ -process.env.NODE_ENV = process.env.NODE_ENV || 'production' +process.env.NODE_ENV = process.env.NODE_ENV || 'production'; -const webpackConfig = require('./base') +const webpackConfig = require('./base'); -module.exports = webpackConfig +module.exports = webpackConfig; diff --git a/config/webpack/test.js b/config/webpack/test.js index c84a413b5..8b54a9ce3 100644 --- a/config/webpack/test.js +++ b/config/webpack/test.js @@ -1,5 +1,5 @@ -process.env.NODE_ENV = process.env.NODE_ENV || 'development' +process.env.NODE_ENV = process.env.NODE_ENV || 'development'; -const webpackConfig = require('./base') +const webpackConfig = require('./base'); -module.exports = webpackConfig +module.exports = webpackConfig; diff --git a/package.json b/package.json index ff2aed57c..269d5bc4f 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,7 @@ { "dependencies": { + "@hotwired/stimulus": "^3.2.1", + "@hotwired/stimulus-webpack-helpers": "^1.0.1", "@rails/webpacker": "^6.0.0-rc.6", "css-loader": "^5.2.6", "css-minimizer-webpack-plugin": "^3.0.2", diff --git a/spec/decorators/form_answer_decorator_spec.rb b/spec/decorators/form_answer_decorator_spec.rb index 599a446b2..af9e0666d 100644 --- a/spec/decorators/form_answer_decorator_spec.rb +++ b/spec/decorators/form_answer_decorator_spec.rb @@ -92,7 +92,7 @@ describe "#dashboard_status" do it "returns fill progress when application is not submitted" do form_answer = create(:form_answer, :trade, state: "application_in_progress", document: { sic_code: SICCode.first.code }) - expect(described_class.new(form_answer).dashboard_status).to eq("Application in progress...9%") + expect(described_class.new(form_answer).dashboard_status).to eq("Application in progress...8%") end it "warns that assessors are not assigned if assessment is in progress and assessors are not assigned yet for admin section" do diff --git a/yarn.lock b/yarn.lock index cc285272e..0a16691d7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -920,6 +920,16 @@ resolved "https://registry.yarnpkg.com/@gar/promisify/-/promisify-1.1.3.tgz#555193ab2e3bb3b6adc3d551c9c030d9e860daf6" integrity sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw== +"@hotwired/stimulus-webpack-helpers@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@hotwired/stimulus-webpack-helpers/-/stimulus-webpack-helpers-1.0.1.tgz#4cd74487adeca576c9865ac2b9fe5cb20cef16dd" + integrity sha512-wa/zupVG0eWxRYJjC1IiPBdt3Lruv0RqGN+/DTMmUWUyMAEB27KXmVY6a8YpUVTM7QwVuaLNGW4EqDgrS2upXQ== + +"@hotwired/stimulus@^3.2.1": + version "3.2.1" + resolved "https://registry.yarnpkg.com/@hotwired/stimulus/-/stimulus-3.2.1.tgz#e3de23623b0c52c247aba4cd5d530d257008676b" + integrity sha512-HGlzDcf9vv/EQrMJ5ZG6VWNs8Z/xMN+1o2OhV1gKiSG6CqZt5MCBB1gRg5ILiN3U0jEAxuDTNPRfBcnZBDmupQ== + "@jridgewell/gen-mapping@^0.1.0": version "0.1.1" resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz#e5d2e450306a9491e3bd77e323e38d7aff315996"