diff --git a/ee/app/assets/javascripts/dependencies/components/dependencies_actions.vue b/ee/app/assets/javascripts/dependencies/components/dependencies_actions.vue index ccd8ffbcee4bd2cf7f964cb8a7bb535301f4b223..9c3b34c21688daeb8204ca774e9198b9ec0119ce 100644 --- a/ee/app/assets/javascripts/dependencies/components/dependencies_actions.vue +++ b/ee/app/assets/javascripts/dependencies/components/dependencies_actions.vue @@ -22,6 +22,8 @@ export default { components: { GlSorting, GlSortingItem, + GroupDependenciesFilteredSearch: () => + import('ee/dependencies/components/filtered_search/group_dependencies_filtered_search.vue'), }, mixins: [glFeatureFlagsMixin()], inject: ['namespaceType', 'enableProjectSearch'], @@ -80,6 +82,10 @@ export default { <div class="gl-display-flex gl-p-5 gl-bg-gray-10 gl-border-t-1 gl-border-t-solid gl-border-gray-100" > + <group-dependencies-filtered-search + v-if="glFeatures.groupLevelDependenciesFiltering && !isProjectNamespace" + class="gl-mr-3" + /> <gl-sorting :text="sortFieldName" :is-ascending="isSortAscending" diff --git a/ee/app/assets/javascripts/dependencies/components/filtered_search/group_dependencies_filtered_search.vue b/ee/app/assets/javascripts/dependencies/components/filtered_search/group_dependencies_filtered_search.vue new file mode 100644 index 0000000000000000000000000000000000000000..4fbf53cb31cb3a133982c3e08382ed7ffd6b3388 --- /dev/null +++ b/ee/app/assets/javascripts/dependencies/components/filtered_search/group_dependencies_filtered_search.vue @@ -0,0 +1,37 @@ +<script> +import { GlFilteredSearch } from '@gitlab/ui'; + +export default { + components: { + GlFilteredSearch, + }, + data() { + return { + value: [], + }; + }, + computed: { + tokens() { + // adding filter tokens will be addressed in separate issues/MRs: + // * https://gitlab.com/gitlab-org/gitlab/-/issues/422356 + // * https://gitlab.com/gitlab-org/gitlab/-/issues/422355 + return []; + }, + }, + methods: { + filterDependencies() { + // connecting the filter with the parent component, which is responsible for + // API calls, will be addressed in a separate MR + }, + }, +}; +</script> + +<template> + <gl-filtered-search + v-model="value" + :placeholder="__('Search or filter dependencies...')" + :available-tokens="tokens" + @submit="filterDependencies" + /> +</template> diff --git a/ee/app/controllers/groups/dependencies_controller.rb b/ee/app/controllers/groups/dependencies_controller.rb index a91e8cfa0ca992da0b27273e07d48488202169db..f86763c6c0f72d88df8688296234e9dd47aadaa0 100644 --- a/ee/app/controllers/groups/dependencies_controller.rb +++ b/ee/app/controllers/groups/dependencies_controller.rb @@ -15,6 +15,7 @@ class DependenciesController < Groups::ApplicationController before_action only: :index do push_frontend_feature_flag(:group_level_licenses, group) + push_frontend_feature_flag(:group_level_dependencies_filtering, group) end def index diff --git a/ee/config/feature_flags/development/group_level_dependencies_filtering.yml b/ee/config/feature_flags/development/group_level_dependencies_filtering.yml new file mode 100644 index 0000000000000000000000000000000000000000..c2d3ffd0dea3b9683b527da899112cdb110499e0 --- /dev/null +++ b/ee/config/feature_flags/development/group_level_dependencies_filtering.yml @@ -0,0 +1,8 @@ +--- +name: group_level_dependencies_filtering +introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/131339 +rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/424727 +milestone: '16.4' +type: development +group: group::threat insights +default_enabled: false diff --git a/ee/spec/frontend/dependencies/components/dependencies_actions_spec.js b/ee/spec/frontend/dependencies/components/dependencies_actions_spec.js index ce79cee2322a9cba0be6b0b2516e8111db4b8e87..12b6d2042d0c33d158e51f675a3ca94bb822151b 100644 --- a/ee/spec/frontend/dependencies/components/dependencies_actions_spec.js +++ b/ee/spec/frontend/dependencies/components/dependencies_actions_spec.js @@ -1,6 +1,7 @@ import { GlSorting, GlSortingItem } from '@gitlab/ui'; import { nextTick } from 'vue'; import DependenciesActions from 'ee/dependencies/components/dependencies_actions.vue'; +import GroupDependenciesFilteredSearch from 'ee/dependencies/components/filtered_search/group_dependencies_filtered_search.vue'; import createStore from 'ee/dependencies/store'; import { DEPENDENCY_LIST_TYPES } from 'ee/dependencies/store/constants'; import { @@ -30,7 +31,11 @@ describe('DependenciesActions component', () => { stubs: { GlSortingItem, }, - provide: { ...objectBasicProp, glFeatures: { groupLevelLicenses: true }, ...provide }, + provide: { + ...objectBasicProp, + glFeatures: { groupLevelLicenses: true, groupLevelDependenciesFiltering: true }, + ...provide, + }, }); }; @@ -133,6 +138,23 @@ describe('DependenciesActions component', () => { ); }); }); + + describe('with the "groupLevelDependenciesFiltering" feature flag disabled', () => { + beforeEach(async () => { + factory({ + propsData: { namespace }, + provide: { + namespaceType: 'group', + glFeatures: { groupLevelDependenciesFiltering: false }, + }, + }); + await nextTick(); + }); + + it('does not render a filtered-search input', () => { + expect(wrapper.findComponent(GroupDependenciesFilteredSearch).exists()).toBe(false); + }); + }); }); it('dispatches the toggleSortOrder action on clicking the sort order button', () => { diff --git a/ee/spec/frontend/dependencies/components/filtered_search/group_dependencies_filtered_search_spec.js b/ee/spec/frontend/dependencies/components/filtered_search/group_dependencies_filtered_search_spec.js new file mode 100644 index 0000000000000000000000000000000000000000..4422b180ee595036f966c1ab1e28b064f139a6d5 --- /dev/null +++ b/ee/spec/frontend/dependencies/components/filtered_search/group_dependencies_filtered_search_spec.js @@ -0,0 +1,20 @@ +import { shallowMount } from '@vue/test-utils'; +import { GlFilteredSearch } from '@gitlab/ui'; +import GroupDependenciesFilteredSearch from 'ee/dependencies/components/filtered_search/group_dependencies_filtered_search.vue'; + +describe('GroupDependenciesFilteredSearch', () => { + let wrapper; + + const createComponent = () => { + wrapper = shallowMount(GroupDependenciesFilteredSearch); + }; + + beforeEach(createComponent); + + it('contains a filtered-search input', () => { + expect(wrapper.findComponent(GlFilteredSearch).props()).toMatchObject({ + availableTokens: [], + placeholder: 'Search or filter dependencies...', + }); + }); +}); diff --git a/locale/gitlab.pot b/locale/gitlab.pot index a4c9567a2c4607f2da1073ccd747d4b294da6ab4..522c54b089155d06cd67d5a071127bf634a6f5be 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -41775,6 +41775,9 @@ msgstr "" msgid "Search or filter commits" msgstr "" +msgid "Search or filter dependencies..." +msgstr "" + msgid "Search or filter results…" msgstr ""