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

Merge branch '505619-policies-add-infinite-scroll-block-modification' into 'master'

No related branches found
No related tags found
无相关合并请求
......@@ -3,7 +3,7 @@ import { GlSprintf } from '@gitlab/ui';
import { s__, sprintf } from '~/locale';
import { convertToGraphQLId, getIdFromGraphQLId } from '~/graphql_shared/utils';
import { TYPENAME_GROUP } from '~/graphql_shared/constants';
import getGroupsByIds from 'ee/security_orchestration/graphql/queries/get_groups_by_ids.qyery.graphql';
import getGroupsByIds from 'ee/security_orchestration/graphql/queries/get_groups_by_ids.query.graphql';
export default {
name: 'BlockGroupBranchModificationSetting',
......
......@@ -7,13 +7,14 @@ import {
GlSprintf,
GlTooltipDirective,
} from '@gitlab/ui';
import produce from 'immer';
import { createAlert } from '~/alert';
import { helpPagePath } from '~/helpers/help_page_helper';
import { DEFAULT_DEBOUNCE_AND_THROTTLE_MS } from '~/lib/utils/constants';
import { getSelectedOptionsText } from '~/lib/utils/listbox_helpers';
import { TYPENAME_GROUP } from '~/graphql_shared/constants';
import { convertToGraphQLId } from '~/graphql_shared/utils';
import getGroupsByIds from 'ee/security_orchestration/graphql/queries/get_groups_by_ids.qyery.graphql';
import getGroupsByIds from 'ee/security_orchestration/graphql/queries/get_groups_by_ids.query.graphql';
import { searchInItemsProperties } from '~/lib/utils/search_utils';
import { __, s__ } from '~/locale';
import {
......@@ -41,6 +42,7 @@ export default {
},
update(data) {
const groups = data.groups?.nodes?.map(createGroupObject) || [];
this.pageInfo = data.groups?.pageInfo || {};
return this.joinUniqueGroups(groups);
},
async result() {
......@@ -82,6 +84,7 @@ export default {
selectedExceptionType: this.exceptions.length ? EXCEPT_GROUPS : WITHOUT_EXCEPTIONS,
searchValue: '',
searching: false,
pageInfo: {},
};
},
computed: {
......@@ -124,6 +127,9 @@ export default {
maxOptionsShown: 2,
});
},
hasNextPage() {
return this.pageInfo.hasNextPage;
},
},
watch: {
enabled(value) {
......@@ -181,6 +187,27 @@ export default {
emitChangeEvent(value) {
this.$emit('change', value);
},
async loadMoreGroups() {
if (!this.hasNextPage) return [];
try {
return await this.$apollo.queries.groups.fetchMore({
variables: {
search: this.searchValue,
after: this.pageInfo.endCursor,
},
updateQuery(previousResult, { fetchMoreResult }) {
return produce(fetchMoreResult, (draftData) => {
draftData.groups.nodes = [
...previousResult.groups.nodes,
...fetchMoreResult.groups.nodes,
];
});
},
});
} catch {
return [];
}
},
},
GROUP_PROTECTED_BRANCHES_DOCS: helpPagePath('user/project/repository/branches/protected', {
......@@ -216,9 +243,11 @@ export default {
multiple
searchable
:items="filteredGroups"
:infinite-scroll="hasNextPage"
:loading="loading"
:selected="exceptionIds"
:toggle-text="toggleText"
@bottom-reached="loadMoreGroups"
@search="handleSearch"
@select="updateGroupExceptionValue"
>
......
#import "~/graphql_shared/fragments/page_info.fragment.graphql"
query getGroupsByIds($ids: [ID!], $search: String, $topLevelOnly: Boolean) {
groups(ids: $ids, search: $search, topLevelOnly: $topLevelOnly) {
query getGroupsByIds($ids: [ID!], $search: String, $topLevelOnly: Boolean, $after: String = "") {
groups(ids: $ids, search: $search, topLevelOnly: $topLevelOnly, after: $after) {
nodes {
id
name
......
......@@ -8,7 +8,7 @@ import { createMockGroups } from 'ee_jest/security_orchestration/mocks/mock_data
import { convertToGraphQLId } from '~/graphql_shared/utils';
import { TYPENAME_GROUP } from '~/graphql_shared/constants';
import createMockApollo from 'helpers/mock_apollo_helper';
import getGroupsByIds from 'ee/security_orchestration/graphql/queries/get_groups_by_ids.qyery.graphql';
import getGroupsByIds from 'ee/security_orchestration/graphql/queries/get_groups_by_ids.query.graphql';
describe('BlockGroupBranchModificationSetting', () => {
let wrapper;
......@@ -52,6 +52,7 @@ describe('BlockGroupBranchModificationSetting', () => {
expect(requestHandler).toHaveBeenCalledWith({
ids: exceptions.map(({ id }) => convertToGraphQLId(TYPENAME_GROUP, id)),
after: '',
});
expect(findExceptions()).toHaveLength(2);
expect(findExceptions().at(0).text()).toBe(groups[0].fullName);
......
......@@ -10,7 +10,7 @@ import {
} from 'ee/security_orchestration/components/policy_editor/scan_result/lib/settings';
import BlockGroupBranchModification from 'ee/security_orchestration/components/policy_editor/scan_result/settings/block_group_branch_modification.vue';
import { createMockGroups } from 'ee_jest/security_orchestration/mocks/mock_data';
import getGroupsByIds from 'ee/security_orchestration/graphql/queries/get_groups_by_ids.qyery.graphql';
import getGroupsByIds from 'ee/security_orchestration/graphql/queries/get_groups_by_ids.query.graphql';
import { convertToGraphQLId } from '~/graphql_shared/utils';
import { TYPENAME_GROUP } from '~/graphql_shared/constants';
import createMockApollo from 'helpers/mock_apollo_helper';
......@@ -21,12 +21,20 @@ describe('BlockGroupBranchModification', () => {
let wrapper;
let requestHandler;
const defaultHandler = (nodes = createMockGroups()) =>
const defaultPageInfo = {
__typename: 'PageInfo',
hasNextPage: false,
hasPreviousPage: false,
startCursor: null,
endCursor: null,
};
const defaultHandler = (nodes = createMockGroups(), pageInfo = defaultPageInfo) =>
jest.fn().mockResolvedValue({
data: {
groups: {
nodes,
pageInfo: {},
pageInfo,
},
},
});
......@@ -67,7 +75,7 @@ describe('BlockGroupBranchModification', () => {
});
it('renders when enabled', () => {
createComponent({ enabled: true });
createComponent({ propsData: { enabled: true } });
expect(findLink().attributes('href')).toBe(
'/help/user/project/repository/branches/protected#for-all-projects-in-a-group',
);
......@@ -93,7 +101,7 @@ describe('BlockGroupBranchModification', () => {
});
it('retrieves top-level groups', () => {
expect(requestHandler).toHaveBeenCalledWith({ topLevelOnly: true, search: '' });
expect(requestHandler).toHaveBeenCalledWith({ topLevelOnly: true, search: '', after: '' });
});
it('renders the except selection dropdown', () => {
......@@ -160,7 +168,7 @@ describe('BlockGroupBranchModification', () => {
it('searches for groups', async () => {
createComponent({ propsData: { enabled: true, exceptions: [{ id: 1 }, { id: 2 }] } });
await findExceptionsDropdown().vm.$emit('search', 'git');
expect(requestHandler).toHaveBeenCalledWith({ search: 'git', topLevelOnly: true });
expect(requestHandler).toHaveBeenCalledWith({ search: 'git', topLevelOnly: true, after: '' });
});
});
......@@ -187,11 +195,42 @@ describe('BlockGroupBranchModification', () => {
await waitForPromises();
expect(requestHandler).toHaveBeenCalledTimes(2);
expect(requestHandler).toHaveBeenNthCalledWith(1, { topLevelOnly: true, search: '' });
expect(requestHandler).toHaveBeenNthCalledWith(1, {
topLevelOnly: true,
search: '',
after: '',
});
expect(requestHandler).toHaveBeenNthCalledWith(2, {
after: '',
topLevelOnly: true,
ids: [7, 8].map((id) => convertToGraphQLId(TYPENAME_GROUP, id)),
});
});
});
describe('infinite scroll', () => {
it('does not make a query to fetch more groups when there is no next page', async () => {
createComponent({ propsData: { enabled: true, exceptions: [{ id: 1 }, { id: 2 }] } });
await waitForPromises();
findExceptionsDropdown().vm.$emit('bottom-reached');
expect(requestHandler).toHaveBeenCalledTimes(1);
});
it('makes a query to fetch more groups when there is a next page', async () => {
createComponent({
propsData: { enabled: true, exceptions: [{ id: 1 }, { id: 2 }] },
handler: defaultHandler(createMockGroups(), { ...defaultPageInfo, hasNextPage: true }),
});
await waitForPromises();
findExceptionsDropdown().vm.$emit('bottom-reached');
expect(requestHandler).toHaveBeenCalledTimes(2);
expect(requestHandler).toHaveBeenNthCalledWith(2, {
after: null,
topLevelOnly: true,
search: '',
});
});
});
});
0% 加载中 .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册