Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Improve filters - add secondary filter - within filter search functionality #4790

Merged
merged 9 commits into from
Dec 30, 2024
2 changes: 1 addition & 1 deletion .github/workflows/build-and-deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ jobs:
include-pattern: spec/components/.*_spec.rb
- tests: unit_other
include-pattern: spec/.*_spec.rb
exclude-pattern: spec/(features|smoke|models|services|forms|components)/.*_spec.rb
exclude-pattern: spec/(system|features|smoke|models|services|forms|components)/.*_spec.rb
- tests: integration_auth
include-pattern: spec/features/auth/.*_spec.rb
- tests: integration_find
Expand Down
1 change: 1 addition & 0 deletions .rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ Naming/BlockForwarding:
RSpec/NoExpectationExample:
Exclude:
- 'spec/features/**/*'
- 'spec/system/**/*'

RSpec/MultipleMemoizedHelpers:
Max: 29
12 changes: 12 additions & 0 deletions app/assets/stylesheets/components/find/_filter-search.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
.app-filter__group {
.govuk-fieldset {
.govuk-checkboxes {
.scrollable-filter {
margin-left: -10px;
max-height: 196px;
overflow-y: auto;
padding-left: 10px;
}
}
}
}
1 change: 1 addition & 0 deletions app/assets/stylesheets/find_application.scss
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
@import "components/find/feedback";
@import "components/find/filter-layout";
@import "components/find/filter";
@import "components/find/filter-search";
@import "components/find/filters";
@import "components/find/map";

Expand Down
8 changes: 0 additions & 8 deletions app/controllers/find/v2/results_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@
module Find
module V2
class ResultsController < Find::ApplicationController
before_action :enforce_basic_auth

def index
@search_courses_form = SearchCoursesForm.new(search_courses_params)
@courses = CoursesQuery.call(params: @search_courses_form.search_params)
Expand All @@ -28,12 +26,6 @@ def search_courses_params
funding: []
)
end

def enforce_basic_auth
authenticate_or_request_with_http_basic do |username, password|
BasicAuthenticable.authenticate(username, password)
end
end
end
end
end
6 changes: 6 additions & 0 deletions app/javascript/find/application.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,12 @@ import initAutocomplete from './autocomplete'
import dfeAutocomplete from './dfe-autocomplete'
import CookieBanner from '../cookie_banner'

import { Application } from '@hotwired/stimulus'
import FilterSearchController from './controllers/filter_search_controller'

window.Stimulus = Application.start()
Stimulus.register('filter-search', FilterSearchController)

window.jQuery = jQuery
window.$ = jQuery

Expand Down
58 changes: 58 additions & 0 deletions app/javascript/find/controllers/filter_search_controller.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import { Controller } from '@hotwired/stimulus'

// Connects to data-controller="filter-search"
export default class extends Controller {
static targets = ['optionsList', 'searchInput', 'legend']

static instanceCounter = 0

connect () {
const legend = this.element.querySelector('legend')
legend.dataset.filterSearchTarget = 'legend'

// This will be unique for each filter-search instance
this.instanceId = this.constructor.instanceCounter++

const searchInput = this.createSearchInput()
this.optionsListTarget.before(searchInput)
}

createSearchInput () {
const container = document.createElement('div')
container.classList.add('filter-search__search')

const inputId = `${this.identifier}-${this.instanceId}-input`
const labelText = `${this.legendTarget.innerText}`

container.innerHTML = `
<label for="${inputId}" class="govuk-label govuk-visually-hidden">
${labelText}
</label>
<input type="search" id="${inputId}"
class="govuk-input govuk-!-margin-bottom-1"
autocomplete="off"
placeholder="Search"
data-action="input->${this.identifier}#search"
data-filter-search-target="searchInput">
`

return container
}

search () {
const optionItems = this.optionsListTarget.children
const searchValue = this.searchInputTarget.value.toLowerCase()

this.toggleItems(optionItems, searchValue)
}

toggleItems (items, searchValue) {
Array.from(items).forEach(function (item) {
if (item.textContent.toLowerCase().indexOf(searchValue) > -1) {
item.style.display = ''
} else {
item.style.display = 'none'
}
})
}
}
12 changes: 9 additions & 3 deletions app/views/find/v2/results/index.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,15 @@
<%= form.govuk_check_box :can_sponsor_visa, "true", multiple: false, label: { text: t("helpers.label.courses_query_filters.can_sponsor_visa"), size: "s" } %>
<% end %>

<%= form.govuk_check_boxes_fieldset :subjects, legend: { text: t("helpers.legend.courses_query_filters.secondary_html"), size: "s" }, hint: { text: t("helpers.hint.courses_query_filters.secondary"), class: "govuk-!-font-size-16" }, class: "app-filter__group", hidden: false, multiple: false, form_group: { class: "app-filter__group" } do %>
<%= form.govuk_collection_check_boxes :subjects, form.object.secondary_subjects, :subject_code, :subject_name, legend: nil, include_hidden: false, small: true %>
<% end %>
<%= form.govuk_check_boxes_fieldset :subjects, legend: { text: t("helpers.legend.courses_query_filters.secondary_html"), size: "s" }, hint: { text: t("helpers.hint.courses_query_filters.secondary"), class: "govuk-!-font-size-16" }, class: "govuk-checkboxes--small", hidden: false, multiple: false, form_group: { class: "app-filter__group", data: { controller: "filter-search" } } do %>
<div class="filter-search scrollable-filter" data-filter-search-target="optionsList">
<% form.object.secondary_subjects.each do |subject| %>
<%= form.govuk_check_box :subjects,
subject.subject_code,
label: { text: subject.subject_name } %>
<% end %>
</div>
<% end %>

<%= form.govuk_check_boxes_fieldset :study_types, legend: { text: t("helpers.legend.courses_query_filters.study_type_html"), size: "s" }, class: "app-filter__group govuk-checkboxes--small", multiple: false, form_group: { class: "app-filter__group" } do %>
<%= form.govuk_check_box :study_types, "full_time", label: { text: t("helpers.label.courses_query_filters.study_type_options.full_time"), size: "s" }, include_hidden: false %>
Expand Down
2 changes: 1 addition & 1 deletion config/routes/find.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
get '/course/:provider_code/:course_code/git/:git_path', to: 'courses#git_redirect', as: :get_into_teaching_redirect
get '/course/:provider_code/:course_code/provider/website', to: 'courses#provider_website', as: :provider_website

get '/v2/results', to: 'v2/results#index', as: 'v2_results'
get '/v2/results', to: 'v2/results#index', as: 'v2_results', constraints: ->(_request) { Settings.features.v2_results.present? }
get '/results', to: 'results#index', as: 'results'
get '/location-suggestions', to: 'location_suggestions#index'
get '/cycle-has-ended', to: 'pages#cycle_has_ended', as: 'cycle_has_ended'
Expand Down
1 change: 1 addition & 0 deletions config/settings/qa.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ basic_auth:
features:
send_request_data_to_bigquery: true
api_summary_content_change: true
v2_results: true

find_valid_referers:
- https://qa.find-teacher-training-courses.service.gov.uk
Expand Down
1 change: 1 addition & 0 deletions config/settings/review.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,4 @@ authentication:

features:
api_summary_content_change: true
v2_results: true
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,15 @@
],
"globals": [
"$",
"google"
"google",
"Stimulus"
],
"ignore": [
"app/javascript/jestGlobalMocks.js"
]
},
"dependencies": {
"@hotwired/stimulus": "^3.2.2",
"@ministryofjustice/frontend": "2.0.0",
"accessible-autocomplete": "^2.0.4",
"core-js": "^3.9.1",
Expand Down
29 changes: 25 additions & 4 deletions spec/support/system_test_config.rb
Original file line number Diff line number Diff line change
@@ -1,14 +1,30 @@
# frozen_string_literal: true

# Use different Capybara ports when running tests in parallel
if ENV['TEST_ENV_NUMBER']
Capybara.server_port = 9887 + ENV['TEST_ENV_NUMBER'].to_i
end
Capybara.server_port = 9887 + ENV['TEST_ENV_NUMBER'].to_i if ENV['TEST_ENV_NUMBER']

# Cannot use puma, we may need to upgrade rackup > 3
Capybara.server = :webrick

Capybara.register_driver :selenium_chrome_headless do |app|
options = Selenium::WebDriver::Chrome::Options.new.tap do |opts|
opts.add_argument('--headless=new')
opts.add_argument('--no-sandbox')
opts.add_argument('--disable-dev-shm-usage')
opts.add_argument('--disable-gpu')
opts.add_argument('--window-size=1400,1400')
end

Capybara::Selenium::Driver.new(app, browser: :chrome, options:)
end

Capybara.javascript_driver = :selenium_chrome_headless

# Allow Capybara to click a <label> even if its corresponding <input> isn't visible on screen.
# This needs to be enabled when using custom-styled checkboxes and radios, such as those
# in the GOV.UK Design System.
Capybara.automatic_label_click = true

RSpec.configure do |config|
screen_size = [1400, 1400]

Expand All @@ -20,7 +36,12 @@
end

config.before(:each, :js, type: :system) do
driven_by :selenium, using: :headless_chrome, screen_size:
driven_by :selenium_chrome_headless, using: :headless_chrome, screen_size:

if Capybara.current_driver == :selenium_chrome_headless
logs = page.driver.browser.manage.logs.get(:browser)
logs.each { |log| puts log.message }
end
end

config.before(:each, :js_browser, type: :system) do
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,21 @@

require 'rails_helper'

feature 'V2 results - disabled' do
RSpec.describe 'V2 results - disabled', service: :find do
before do
allow(Settings.features).to receive_messages(v2_results: false)
end

scenario 'when I visit the results page' do
when_i_visit_the_find_results_page
then_i_see_not_authorised
then_i_see_not_found
end

def when_i_visit_the_find_results_page
visit find_v2_results_path
end

def then_i_see_not_authorised
expect(page.status_code).to eq(401)
def then_i_see_not_found
expect(page.status_code).to eq(404)
end
end
Loading
Loading