Skip to content
代码片段 群组 项目
未验证 提交 512e1564 编辑于 作者: Alexander Turinske's avatar Alexander Turinske 提交者: GitLab
浏览文件

Merge branch '442536-policies-group-projects-select-all' into 'master'

Select all and reset for group project dropdown

See merge request https://gitlab.com/gitlab-org/gitlab/-/merge_requests/145874



Merged-by: default avatarAlexander Turinske <aturinske@gitlab.com>
Approved-by: default avatarCamellia X Yang <xyang@gitlab.com>
Approved-by: default avatarAlexander Turinske <aturinske@gitlab.com>
Co-authored-by: default avatarArtur Fedorov <afedorov@gitlab.com>
No related branches found
No related tags found
无相关合并请求
...@@ -10,6 +10,8 @@ import { DEFAULT_DEBOUNCE_AND_THROTTLE_MS } from '~/lib/utils/constants'; ...@@ -10,6 +10,8 @@ import { DEFAULT_DEBOUNCE_AND_THROTTLE_MS } from '~/lib/utils/constants';
export default { export default {
i18n: { i18n: {
projectDropdownHeader: __('Select projects'), projectDropdownHeader: __('Select projects'),
selectAllLabel: __('Select all'),
clearAllLabel: __('Clear all'),
}, },
name: 'GroupProjectsDropdown', name: 'GroupProjectsDropdown',
components: { components: {
...@@ -84,11 +86,15 @@ export default { ...@@ -84,11 +86,15 @@ export default {
selected: this.formattedSelectedProjectsIds, selected: this.formattedSelectedProjectsIds,
items: this.projectItems, items: this.projectItems,
itemTypeName: __('projects'), itemTypeName: __('projects'),
useAllSelected: !this.hasNextPage,
}); });
}, },
loading() { loading() {
return this.$apollo.queries.projects.loading; return this.$apollo.queries.projects.loading;
}, },
hasNextPage() {
return this.projectsPageInfo.hasNextPage;
},
projectItems() { projectItems() {
return this.projects?.reduce((acc, { id, name }) => { return this.projects?.reduce((acc, { id, name }) => {
acc[id] = name; acc[id] = name;
...@@ -101,6 +107,15 @@ export default { ...@@ -101,6 +107,15 @@ export default {
projectsIds() { projectsIds() {
return this.projects.map(({ id }) => id); return this.projects.map(({ id }) => id);
}, },
resetButtonLabel() {
return this.multiple ? this.$options.i18n.clearAllLabel : '';
},
category() {
return this.state ? 'primary' : 'secondary';
},
variant() {
return this.state ? 'default' : 'danger';
},
}, },
created() { created() {
this.debouncedSearch = debounce(this.setSearchTerm, DEFAULT_DEBOUNCE_AND_THROTTLE_MS); this.debouncedSearch = debounce(this.setSearchTerm, DEFAULT_DEBOUNCE_AND_THROTTLE_MS);
...@@ -148,12 +163,15 @@ export default { ...@@ -148,12 +163,15 @@ export default {
is-check-centered is-check-centered
searchable searchable
fluid-width fluid-width
:toggle-class="{ 'gl-inset-border-1-red-500!': !state }" :category="category"
:variant="variant"
:multiple="multiple" :multiple="multiple"
:loading="loading" :loading="loading"
:header-text="$options.i18n.projectDropdownHeader" :header-text="$options.i18n.projectDropdownHeader"
:infinite-scroll="projectsPageInfo.hasNextPage" :infinite-scroll="hasNextPage"
:infinite-scroll-loading="loading" :infinite-scroll-loading="loading"
:reset-button-label="resetButtonLabel"
:show-select-all-button-label="$options.i18n.selectAllLabel"
:searching="loading" :searching="loading"
:selected="existingFormattedSelectedProjectsIds" :selected="existingFormattedSelectedProjectsIds"
:placement="placement" :placement="placement"
...@@ -161,6 +179,8 @@ export default { ...@@ -161,6 +179,8 @@ export default {
:toggle-text="dropdownPlaceholder" :toggle-text="dropdownPlaceholder"
@bottom-reached="fetchMoreGroupProjects" @bottom-reached="fetchMoreGroupProjects"
@search="debouncedSearch" @search="debouncedSearch"
@reset="selectProjects([])"
@select="selectProjects" @select="selectProjects"
@select-all="selectProjects(projectsIds)"
/> />
</template> </template>
...@@ -191,6 +191,26 @@ describe('GroupProjectsDropdown', () => { ...@@ -191,6 +191,26 @@ describe('GroupProjectsDropdown', () => {
expect(requestHandlers.getGroupProjects).toHaveBeenCalledTimes(2); expect(requestHandlers.getGroupProjects).toHaveBeenCalledTimes(2);
}); });
it.each`
hasNextPage | expectedText
${true} | ${'1 +1 more'}
${false} | ${'All projects'}
`(
'selects all projects only when all projects loaded',
async ({ hasNextPage, expectedText }) => {
createComponent({
propsData: {
selected: defaultNodesIds,
},
handlers: mockApolloHandlers(defaultNodes, hasNextPage),
});
await waitForPromises();
expect(findDropdown().props('toggleText')).toBe(expectedText);
},
);
describe('when the fetch query throws an error', () => { describe('when the fetch query throws an error', () => {
it('emits an error event', async () => { it('emits an error event', async () => {
createComponent({ createComponent({
...@@ -231,4 +251,44 @@ describe('GroupProjectsDropdown', () => { ...@@ -231,4 +251,44 @@ describe('GroupProjectsDropdown', () => {
expect(findDropdown().props('selected')).toEqual(defaultNodesIds); expect(findDropdown().props('selected')).toEqual(defaultNodesIds);
}); });
}); });
describe('validation', () => {
it('renders default dropdown when validation passes', () => {
createComponent({
propsData: {
state: true,
},
});
expect(findDropdown().props('variant')).toEqual('default');
expect(findDropdown().props('category')).toEqual('primary');
});
it('renders danger dropdown when validation passes', () => {
createComponent();
expect(findDropdown().props('variant')).toEqual('danger');
expect(findDropdown().props('category')).toEqual('secondary');
});
});
describe('select all', () => {
it('selects all projects', async () => {
createComponent();
await waitForPromises();
findDropdown().vm.$emit('select-all');
expect(wrapper.emitted('select')).toEqual([[defaultNodes]]);
});
it('resets all projects', async () => {
createComponent();
await waitForPromises();
findDropdown().vm.$emit('reset');
expect(wrapper.emitted('select')).toEqual([[[]]]);
});
});
}); });
0% 加载中 .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册