Commit 460d7a24 authored by Martin Wortschack's avatar Martin Wortschack

Merge branch '271248-fe-devops-report-filter-segments-in-the-segment-modal' into 'master'

DevOps Report: Filter segments in the segment modal

See merge request gitlab-org/gitlab!49549
parents 903d91af 3fc41db3
......@@ -6,6 +6,7 @@ import {
GlModal,
GlSprintf,
GlAlert,
GlIcon,
} from '@gitlab/ui';
import { getIdFromGraphQLId, convertToGraphQLIds, TYPE_GROUP } from '~/graphql_shared/utils';
import * as Sentry from '~/sentry/wrapper';
......@@ -23,6 +24,7 @@ export default {
GlFormCheckboxTree,
GlSprintf,
GlAlert,
GlIcon,
},
props: {
segment: {
......@@ -40,6 +42,7 @@ export default {
return {
name: this.segment?.name || '',
checkboxValues: this.segment ? this.checkboxValuesFromSegment() : [],
filter: '',
loading: false,
errors: [],
};
......@@ -78,6 +81,13 @@ export default {
modalTitle() {
return this.segment ? this.$options.i18n.editingTitle : this.$options.i18n.addingTitle;
},
filteredOptions() {
return this.filter
? this.checkboxOptions.filter(option =>
option.label.toLowerCase().includes(this.filter.toLowerCase()),
)
: this.checkboxOptions;
},
},
methods: {
async createSegment() {
......@@ -180,15 +190,30 @@ export default {
:disabled="loading"
/>
</gl-form-group>
<gl-form-group class="gl-mb-3" data-testid="filter">
<gl-icon name="search" :size="18" class="gl-text-gray-300 gl-absolute gl-mt-3 gl-ml-3" />
<gl-form-input
v-model="filter"
class="gl-pl-7!"
type="text"
:placeholder="$options.i18n.filterPlaceholder"
:disabled="loading"
/>
</gl-form-group>
<gl-form-group class="gl-mb-0">
<gl-form-checkbox-tree
v-if="filteredOptions.length"
:key="filteredOptions.length"
v-model="checkboxValues"
data-testid="groups"
:options="checkboxOptions"
:options="filteredOptions"
:hide-toggle-all="true"
:disabled="loading"
class="gl-p-3 gl-pb-0 gl-mb-2 gl-border-1 gl-border-solid gl-border-gray-100 gl-rounded-base"
/>
<gl-alert v-else variant="info" :dismissible="false" data-testid="filter-warning">
{{ $options.i18n.noResults }}
</gl-alert>
<div class="gl-text-gray-400" data-testid="groupsHelperText">
<gl-sprintf
:message="
......
......@@ -42,10 +42,12 @@ export const DEVOPS_ADOPTION_STRINGS = {
editingButton: s__('DevopsAdoption|Save changes'),
cancel: __('Cancel'),
namePlaceholder: s__('DevopsAdoption|My segment'),
filterPlaceholder: s__('DevopsAdoption|Filter by name'),
nameLabel: s__('DevopsAdoption|Name'),
selectedGroupsTextSingular: s__('DevopsAdoption|%{selectedCount} group selected (20 max)'),
selectedGroupsTextPlural: s__('DevopsAdoption|%{selectedCount} groups selected (20 max)'),
error: s__('DevopsAdoption|An error occured while saving the segment. Please try again.'),
noResults: s__('DevopsAdoption|No filter results.'),
},
table: {
editButton: s__('DevopsAdoption|Edit segment'),
......
import { ApolloMutation } from 'vue-apollo';
import { shallowMount } from '@vue/test-utils';
import { GlModal, GlFormInput, GlSprintf, GlAlert } from '@gitlab/ui';
import { GlModal, GlFormInput, GlSprintf, GlAlert, GlIcon } from '@gitlab/ui';
import { getByText } from '@testing-library/dom';
import { nextTick } from 'vue';
import waitForPromises from 'helpers/wait_for_promises';
......@@ -15,6 +15,7 @@ import {
genericErrorMessage,
dataErrorMessage,
devopsAdoptionSegmentsData,
groupNodeLabelValues,
} from '../mock_data';
const mockEvent = { preventDefault: jest.fn() };
......@@ -133,6 +134,64 @@ describe('DevopsAdoptionSegmentModal', () => {
});
});
describe('filtering', () => {
describe('filter input field', () => {
it('contains the filter input', () => {
const filter = findByTestId('filter');
expect(filter.exists()).toBe(true);
expect(filter.find(GlFormInput).exists()).toBe(true);
});
it('contains the filter icon', () => {
const icon = findByTestId('filter').find(GlIcon);
expect(icon.exists()).toBe(true);
expect(icon.props('name')).toBe('search');
});
});
it.each`
filter | results
${''} | ${groupNodeLabelValues}
${'fo'} | ${[groupNodeLabelValues[0]]}
${'ar'} | ${[groupNodeLabelValues[1]]}
`(
'displays the correct results when filtering for value "$filter"',
async ({ filter, results }) => {
wrapper.setData({ filter });
await nextTick();
const checkboxes = findByTestId('groups');
expect(checkboxes.props('options')).toStrictEqual(results);
},
);
describe('when there are no filter results', () => {
beforeEach(async () => {
wrapper.setData({ filter: 'lalalala' });
await nextTick();
});
it('displays a warning message when there are no results', async () => {
const warning = findByTestId('filter-warning');
expect(warning.exists()).toBe(true);
expect(warning.text()).toBe('No filter results.');
expect(warning.props('variant')).toBe('info');
});
it('hides the checkboxes', () => {
const checkboxes = findByTestId('groups');
expect(checkboxes.exists()).toBe(false);
});
});
});
it('does not display an error', () => {
expect(findAlert().exists()).toBe(false);
});
......
......@@ -17,6 +17,8 @@ export const groupNodes = [
},
];
export const groupNodeLabelValues = [{ label: 'Foo', value: '1' }, { label: 'Bar', value: '2' }];
export const groupIds = ['1', '2'];
export const groupGids = ['gid://gitlab/Group/1', 'gid://gitlab/Group/2'];
......
......@@ -9643,6 +9643,9 @@ msgstr ""
msgid "DevopsAdoption|Feature adoption is based on usage in the last calendar month. Last updated: %{timestamp}."
msgstr ""
msgid "DevopsAdoption|Filter by name"
msgstr ""
msgid "DevopsAdoption|Issues"
msgstr ""
......@@ -9658,6 +9661,9 @@ msgstr ""
msgid "DevopsAdoption|New segment"
msgstr ""
msgid "DevopsAdoption|No filter results."
msgstr ""
msgid "DevopsAdoption|Pipelines"
msgstr ""
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment