diff --git a/app/views/search/index.html.erb b/app/views/search/index.html.erb
index 427ddd78bd4..af144b0491b 100644
--- a/app/views/search/index.html.erb
+++ b/app/views/search/index.html.erb
@@ -56,17 +56,19 @@ See COPYRIGHT and LICENSE files for more details.
].compact
)
- header.with_tab_nav(label: nil) do |tab_nav|
+ header.with_tab_nav(label: nil, test_selector: "search-tabs") do |tab_nav|
search_types.each do |name|
tab_nav.with_tab(
+ test_selector: "search-tab-#{name}",
selected: search_params[:filter] == name,
- href: search_path(filter: name, q: @question, scope: search_params[:scope])
+ href: search_path(project_id: @project, filter: name, q: @question, scope: search_params[:scope])
) { |t| t.with_text { OpenProject::GlobalSearch.tab_name(name) } }
end
tab_nav.with_tab(
+ test_selector: "search-tab-all",
selected: search_params[:filter].blank?,
- href: search_path(q: @question, scope: search_params[:scope])
+ href: search_path(project_id: @project, q: @question, scope: search_params[:scope])
) { |t| t.with_text { OpenProject::GlobalSearch.tab_name("all") } }
end
end
diff --git a/frontend/src/app/core/global_search/global-search-work-packages.component.ts b/frontend/src/app/core/global_search/global-search-work-packages.component.ts
index 6a6d03b0c9b..e827154c1cd 100644
--- a/frontend/src/app/core/global_search/global-search-work-packages.component.ts
+++ b/frontend/src/app/core/global_search/global-search-work-packages.component.ts
@@ -57,6 +57,7 @@ import {
} from 'core-app/features/work-packages/directives/query-space/wp-isolated-query-space.directive';
import { QueryRequestParams } from 'core-app/features/work-packages/components/wp-query/url-params-helper';
import { populateInputsFromDataset } from 'core-app/shared/components/dataset-inputs';
+import { CurrentProjectService } from 'core-app/core/current-project/current-project.service';
@Component({
selector: 'opce-global-search-work-packages',
@@ -93,6 +94,7 @@ export class GlobalSearchWorkPackagesComponent extends UntilDestroyedMixin imple
readonly halResourceService:HalResourceService,
readonly wpTableFilters:WorkPackageViewFiltersService,
readonly querySpace:IsolatedQuerySpace,
+ readonly currentProject:CurrentProjectService,
readonly cdRef:ChangeDetectorRef,
) {
super();
@@ -134,7 +136,7 @@ export class GlobalSearchWorkPackagesComponent extends UntilDestroyedMixin imple
columns = ['id', 'subject', 'type', 'status', 'updatedAt'];
}
- if (this.scope === '') {
+ if (this.scope === '' && this.currentProject.id) {
filters.push({
subprojectId: {
operator: '*',
diff --git a/frontend/src/app/core/global_search/services/global-search.service.ts b/frontend/src/app/core/global_search/services/global-search.service.ts
index de9eb6250d4..38f17e17697 100644
--- a/frontend/src/app/core/global_search/services/global-search.service.ts
+++ b/frontend/src/app/core/global_search/services/global-search.service.ts
@@ -61,6 +61,11 @@ export class GlobalSearchService {
params.set('q', query);
params.set('scope', scope);
+ // Filter work packages by default
+ if (!params.get('filter')) {
+ params.set('filter', 'work_packages');
+ }
+
return params.toString();
}
}
diff --git a/modules/meeting/spec/features/meetings_search_spec.rb b/modules/meeting/spec/features/meetings_search_spec.rb
index 23d32e4f4eb..ed400c8df15 100644
--- a/modules/meeting/spec/features/meetings_search_spec.rb
+++ b/modules/meeting/spec/features/meetings_search_spec.rb
@@ -38,6 +38,7 @@ RSpec.describe "Meeting search", :js do
let!(:meeting) { create(:meeting, project:) }
let!(:agenda_item) { create(:meeting_agenda_item, meeting:) }
+ let(:global_search) { Components::GlobalSearch.new }
before do
login_as user
@@ -52,7 +53,7 @@ RSpec.describe "Meeting search", :js do
select_text: "In this project ↵",
wait_dropdown_open: true)
- page.find('[data-qa-tab-id="meetings"]').click
+ global_search.open_tab :meetings
expect(page.find_by_id("search-results")).to have_text(meeting.title)
end
@@ -62,7 +63,7 @@ RSpec.describe "Meeting search", :js do
select_text: "In this project ↵",
wait_dropdown_open: true)
- page.find('[data-qa-tab-id="meetings"]').click
+ global_search.open_tab :meetings
expect(page.find_by_id("search-results")).to have_text(meeting.title)
end
@@ -72,7 +73,7 @@ RSpec.describe "Meeting search", :js do
select_text: "In this project ↵",
wait_dropdown_open: true)
- page.find('[data-qa-tab-id="meetings"]').click
+ global_search.open_tab :meetings
expect(page.find_by_id("search-results")).to have_text(meeting.title)
end
end
diff --git a/spec/features/search/search_spec.rb b/spec/features/search/search_spec.rb
index 97d78037d07..26a6f3104bd 100644
--- a/spec/features/search/search_spec.rb
+++ b/spec/features/search/search_spec.rb
@@ -167,9 +167,11 @@ RSpec.describe "Search", :js, :selenium, with_settings: { per_page_options: "5"
# Selection project scope 'In all projects' redirects away from current project.
global_search.submit_in_global_scope
- expect(page)
- .to have_current_path (/\/search/)
- expect(current_url).to match(/\/search\?q=#{"%23#{search_target.id}"}&work_packages=1&scope=all$/)
+ expect(page).to have_current_path (/\/search/)
+
+ expect(current_url).to include("q=#{"%23#{search_target.id}"}")
+ expect(current_url).to include("filter=work_packages")
+ expect(current_url).to include("scope=all")
end
end
@@ -296,19 +298,12 @@ RSpec.describe "Search", :js, :selenium, with_settings: { per_page_options: "5"
global_search.submit_in_current_project
# Expect that the "All" tab is selected.
- expect(page).to have_css('[data-qa-tab-id="all"][data-qa-tab-selected]')
+ global_search.expect_active_tab :work_packages
- # Expect that the project scope is set to current_project and no module (this is the "all" tab) is requested.
- expect(current_url).to match(/\/#{project.identifier}\/search\?q=#{query}&scope=current_project$/)
-
- # Select "Work packages" tab
- page.find('[data-qa-tab-id="work_packages"]').click
-
- # Expect that the project scope is set to current_project and the module "work_packages" is requested.
- expect(current_url).to match(/\/search\?q=#{query}&work_packages=1&scope=current_project$/)
-
- # Expect that the "Work packages" tab is selected.
- expect(page).to have_css('[data-qa-tab-id="work_packages"][data-qa-tab-selected]')
+ expect(current_url).to include("/#{project.identifier}/search")
+ expect(current_url).to include("q=#{query}")
+ expect(current_url).to include("filter=work_packages")
+ expect(current_url).to include("scope=current_project")
table = Pages::EmbeddedWorkPackagesTable.new(find(".work-packages-embedded-view--container"))
table.expect_work_package_count(5) # because we set the page size to this
@@ -363,8 +358,9 @@ RSpec.describe "Search", :js, :selenium, with_settings: { per_page_options: "5"
# and expect that subproject's work packages will not be found
table.ensure_work_package_not_listed! other_work_package
- expect(current_url)
- .to match(/\/#{project.identifier}\/search\?q=Other%20work%20package&work_packages=1&scope=current_project$/)
+ expect(current_url).to include("q=Other+work+package")
+ expect(current_url).to include("filter=work_packages")
+ expect(current_url).to include("scope=current_project")
# Expect to find custom field values
# ...for type: text
@@ -381,12 +377,16 @@ RSpec.describe "Search", :js, :selenium, with_settings: { per_page_options: "5"
global_search.submit_in_project_and_subproject_scope
# Expect that the "Work packages" tab is selected.
- expect(page).to have_css('[data-qa-tab-id="work_packages"][data-qa-tab-selected]')
+ global_search.expect_active_tab :work_packages
expect(page).to have_text "Search for \"#{other_work_package.subject}\" in #{project.name} and all subprojects"
# Expect that the project scope is not set and work_packages module continues to stay selected.
- expect(current_url).to match(/\/#{project.identifier}\/search\?q=Other%20work%20package&work_packages=1$/)
+ expect(current_url).to match(/\/#{project.identifier}\/search/)
+ expect(current_url).to include("q=Other+work+package")
+ expect(current_url).to include("filter=work_packages")
+ expect(current_url).to include("scope=&")
+
table = Pages::EmbeddedWorkPackagesTable.new(find(".work-packages-embedded-view--container"))
table.expect_work_package_count(1)
@@ -430,18 +430,21 @@ RSpec.describe "Search", :js, :selenium, with_settings: { per_page_options: "5"
global_search.search query
global_search.submit_in_project_and_subproject_scope
+ global_search.open_tab :work_packages
+
+ table = Pages::EmbeddedWorkPackagesTable.new(find(".work-packages-embedded-view--container"))
+ table.ensure_work_package_not_listed!(work_packages[0])
+ table.ensure_work_package_not_listed!(work_packages[1])
+ table.expect_work_package_listed(work_packages[9])
+
+ global_search.open_tab "All"
+
expect(page)
.to have_content attachment_text
expect(page)
.to have_css(".search-highlight", text: query)
- page.find('[data-qa-tab-id="work_packages"]').click
-
- table = Pages::EmbeddedWorkPackagesTable.new(find(".work-packages-embedded-view--container"))
- table.ensure_work_package_not_listed!(work_packages[0])
- table.ensure_work_package_not_listed!(work_packages[1])
- table.expect_work_package_listed(work_packages[9])
end
end
end
@@ -464,6 +467,7 @@ RSpec.describe "Search", :js, :selenium, with_settings: { per_page_options: "5"
it "highlights last note" do
global_search.search "note"
global_search.submit_in_global_scope
+ global_search.open_tab "All"
within("dt.work_package-note + dd") do
expect(page).to have_css(".description", text: note_two.notes)
@@ -486,7 +490,7 @@ RSpec.describe "Search", :js, :selenium, with_settings: { per_page_options: "5"
select_text: "In all projects ↵",
wait_dropdown_open: false)
- within ".global-search--tabs" do
+ within_test_selector("search-tabs") do
click_on "Projects"
end
end
diff --git a/spec/support/components/global_search.rb b/spec/support/components/global_search.rb
index 379fb27953a..c0cbcbed941 100644
--- a/spec/support/components/global_search.rb
+++ b/spec/support/components/global_search.rb
@@ -43,6 +43,17 @@ module Components
SeleniumHubWaiter.wait
end
+ def open_tab(tab_id)
+ page.within_test_selector("search-tabs") do
+ name = tab_id.is_a?(Symbol) ? OpenProject::GlobalSearch.tab_name(tab_id.to_s) : tab_id
+ click_on(name)
+ end
+ end
+
+ def expect_active_tab(id)
+ expect(page).to have_css("#{page.test_selector("search-tab-#{id}")}[aria-current]")
+ end
+
def expect_open
expect(page).to have_selector(selector)
end