diff --git a/app/controllers/organisations_controller.rb b/app/controllers/organisations_controller.rb index dfe50fa22..9d3e63b33 100644 --- a/app/controllers/organisations_controller.rb +++ b/app/controllers/organisations_controller.rb @@ -4,8 +4,8 @@ class OrganisationsController < ApplicationController include DuplicateLogsHelper before_action :authenticate_user! - before_action :find_resource, except: %i[index new create] - before_action :authenticate_scope!, except: [:index] + before_action :find_resource, except: %i[index new create search] + before_action :authenticate_scope!, except: %i[index search] before_action :session_filters, if: -> { current_user.support? || current_user.organisation.has_managing_agents? }, only: %i[lettings_logs sales_logs email_lettings_csv download_lettings_csv email_sales_csv download_sales_csv] before_action :session_filters, only: %i[users schemes email_schemes_csv download_schemes_csv] before_action -> { filter_manager.serialize_filters_to_session }, if: -> { current_user.support? || current_user.organisation.has_managing_agents? }, only: %i[lettings_logs sales_logs email_lettings_csv download_lettings_csv email_sales_csv download_sales_csv] @@ -280,6 +280,17 @@ class OrganisationsController < ApplicationController render "schemes/changes" end + def search + org_options = current_user.support? ? Organisation.all : Organisation.affiliated_organisations(current_user.organisation) + organisations = org_options.search_by(params["query"]).limit(20) + + org_data = organisations.each_with_object({}) do |org, hash| + hash[org.id] = { value: org.name } + end + + render json: org_data.to_json + end + private def filter_type diff --git a/app/frontend/controllers/search_controller.js b/app/frontend/controllers/search_controller.js index 6d447f7f8..ada55d820 100644 --- a/app/frontend/controllers/search_controller.js +++ b/app/frontend/controllers/search_controller.js @@ -11,8 +11,8 @@ const populateOptions = (results, selectEl) => { const option = document.createElement('option') option.value = key option.innerHTML = searchableName(results[key]) - option.setAttribute('data-hint', results[key].hint) - option.textContent = searchableName(results[key]) + if (results[key].hint) { option.setAttribute('data-hint', results[key].hint) } + option.setAttribute('text', searchableName(results[key])) selectEl.appendChild(option) options.push(option) }) @@ -23,14 +23,14 @@ export default class extends Controller { const selectEl = this.element const matches = /^(\w+)\[(\w+)\]$/.exec(selectEl.name) const rawFieldName = matches ? `${matches[1]}[${matches[2]}_raw]` : '' - const relativeUrlRoute = JSON.parse(this.element.dataset.info).relative_url_route + const searchUrl = JSON.parse(this.element.dataset.info).search_url accessibleAutocomplete.enhanceSelectElement({ defaultValue: '', selectElement: selectEl, minLength: 1, source: (query, populateResults) => { - fetchAndPopulateSearchResults(query, populateResults, relativeUrlRoute, populateOptions, selectEl) + fetchAndPopulateSearchResults(query, populateResults, searchUrl, populateOptions, selectEl) }, autoselect: true, placeholder: 'Start typing to search', diff --git a/app/frontend/modules/search.js b/app/frontend/modules/search.js index b232c2a08..c2679b80c 100644 --- a/app/frontend/modules/search.js +++ b/app/frontend/modules/search.js @@ -119,8 +119,9 @@ export const suggestion = (value, options) => { export const searchSuggestion = (value, options) => { try { - const result = enhanceOption(options.find((o) => o.innerHTML === value)) - if (result) { + const option = options.find((o) => o.innerHTML === value) + if (option) { + const result = enhanceOption(option) const html = result.append ? `${result.text} ${result.append}` : `${result.text}` return result.hint ? `${html}
${result.hint}
` : html } else { @@ -151,14 +152,9 @@ export const fetchAndPopulateSearchResults = async (query, populateResults, rela } } -export const fetchUserOptions = async (query, relativeUrlRoute) => { +export const fetchUserOptions = async (query, searchUrl) => { try { - let response - if (relativeUrlRoute) { - response = await fetch(`${relativeUrlRoute}/users/search?query=${encodeURIComponent(query)}`) - } else { - response = await fetch(`/users/search?query=${encodeURIComponent(query)}`) - } + const response = await fetch(`${searchUrl}?query=${encodeURIComponent(query)}`) const results = await response.json() return results } catch (error) { @@ -172,7 +168,7 @@ export const getSearchableName = (option) => { } export const searchableName = (option) => { - return option.value + ' ' + option.hint + return option.hint ? option.value + ' ' + option.hint : option.value } export const confirmSelectedOption = (selectEl, val) => { diff --git a/app/helpers/filters_helper.rb b/app/helpers/filters_helper.rb index 12845fce4..81a986ebf 100644 --- a/app/helpers/filters_helper.rb +++ b/app/helpers/filters_helper.rb @@ -84,13 +84,31 @@ module FiltersHelper JSON.parse(session[session_name_for(filter_type)])[filter] || "" end - def owning_organisation_filter_options(user) - organisation_options = user.support? ? Organisation.all : ([user.organisation] + user.organisation.stock_owners + user.organisation.absorbed_organisations).uniq - [OpenStruct.new(id: "", name: "Select an option")] + organisation_options.map { |org| OpenStruct.new(id: org.id, name: org.name) } + def owning_organisation_filter_options(_user, filter_type) + if applied_filters(filter_type)["owning_organisation"].present? + org = Organisation.find(applied_filters(filter_type)["owning_organisation"]) # make sure this doesn't expose anything weird + [OpenStruct.new(id: org.id, name: org.name)] + else + [OpenStruct.new(id: "", name: "Select an option")] + end end - def assigned_to_filter_options - [OpenStruct.new(id: "", name: "Select an option", hint: "")] + def assigned_to_filter_options(filter_type) + if applied_filters(filter_type)["assigned_to"] == "specific_user" + user = User.find(applied_filters(filter_type)["user"]) # make sure this doesn't expose anything weird + [OpenStruct.new(id: user.id, name: user.name, hint: user.email)] + else + [OpenStruct.new(id: "", name: "Select an option", hint: "")] + end + end + + def filter_search_url(category) + case category + when :user + ENV["RAILS_RELATIVE_URL_ROOT"].present? ? "#{ENV['RAILS_RELATIVE_URL_ROOT']}/users/search" : "/users/search" + when :owning_organisation, :managing_organisation + ENV["RAILS_RELATIVE_URL_ROOT"].present? ? "#{ENV['RAILS_RELATIVE_URL_ROOT']}/organisations/search" : "/organisations/search" + end end def collection_year_options @@ -124,9 +142,13 @@ module FiltersHelper end end - def managing_organisation_filter_options(user) - organisation_options = user.support? ? Organisation.all : ([user.organisation] + user.organisation.managing_agents + user.organisation.absorbed_organisations).uniq - [OpenStruct.new(id: "", name: "Select an option")] + organisation_options.map { |org| OpenStruct.new(id: org.id, name: org.name) } + def managing_organisation_filter_options(_user, filter_type) + if applied_filters(filter_type)["managing_organisation"].present? + org = Organisation.find(applied_filters(filter_type)["managing_organisation"]) # make sure this doesn't expose anything weird + [OpenStruct.new(id: org.id, name: org.name)] + else + [OpenStruct.new(id: "", name: "Select an option")] + end end def show_scheme_managing_org_filter?(user) diff --git a/app/models/organisation.rb b/app/models/organisation.rb index 8f77df166..f0e8ca243 100644 --- a/app/models/organisation.rb +++ b/app/models/organisation.rb @@ -18,6 +18,7 @@ class Organisation < ApplicationRecord belongs_to :absorbing_organisation, class_name: "Organisation", optional: true has_many :absorbed_organisations, class_name: "Organisation", foreign_key: "absorbing_organisation_id" scope :visible, -> { where(discarded_at: nil) } + scope :affiliated_organisations, ->(organisation) { where(id: (organisation.child_organisations + [organisation] + organisation.parent_organisations).map(&:id)) } def affiliated_stock_owners ids = [] diff --git a/app/views/filters/_select_filter.html.erb b/app/views/filters/_select_filter.html.erb index 70d7e007d..9e564bfb2 100644 --- a/app/views/filters/_select_filter.html.erb +++ b/app/views/filters/_select_filter.html.erb @@ -1,7 +1,7 @@ <%= f.govuk_select(category.to_sym, label: { text: label, hidden: secondary }, "data-controller": "search conditional-filter", - "data-info": {relative_url_route: ENV["RAILS_RELATIVE_URL_ROOT"]}.to_json) do %> + "data-info": { search_url: filter_search_url(category.to_sym) }.to_json) do %> <% collection.each do |answer| %>