Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'app/assets/javascripts/import_entities/import_groups')
-rw-r--r--app/assets/javascripts/import_entities/import_groups/components/import_table.vue92
-rw-r--r--app/assets/javascripts/import_entities/import_groups/components/import_table_row.vue147
-rw-r--r--app/assets/javascripts/import_entities/import_groups/graphql/client_factory.js78
-rw-r--r--app/assets/javascripts/import_entities/import_groups/graphql/queries/group.query.graphql5
-rw-r--r--app/assets/javascripts/import_entities/import_groups/graphql/services/source_groups_manager.js83
-rw-r--r--app/assets/javascripts/import_entities/import_groups/graphql/services/status_poller.js12
-rw-r--r--app/assets/javascripts/import_entities/import_groups/index.js3
7 files changed, 324 insertions, 96 deletions
diff --git a/app/assets/javascripts/import_entities/import_groups/components/import_table.vue b/app/assets/javascripts/import_entities/import_groups/components/import_table.vue
index 7c5f48dcafc..f337520b0db 100644
--- a/app/assets/javascripts/import_entities/import_groups/components/import_table.vue
+++ b/app/assets/javascripts/import_entities/import_groups/components/import_table.vue
@@ -1,13 +1,15 @@
<script>
import {
GlEmptyState,
+ GlDropdown,
+ GlDropdownItem,
GlIcon,
GlLink,
GlLoadingIcon,
GlSearchBoxByClick,
GlSprintf,
} from '@gitlab/ui';
-import { s__ } from '~/locale';
+import { s__, __ } from '~/locale';
import PaginationLinks from '~/vue_shared/components/pagination_links.vue';
import importGroupMutation from '../graphql/mutations/import_group.mutation.graphql';
import setNewNameMutation from '../graphql/mutations/set_new_name.mutation.graphql';
@@ -16,9 +18,14 @@ import availableNamespacesQuery from '../graphql/queries/available_namespaces.qu
import bulkImportSourceGroupsQuery from '../graphql/queries/bulk_import_source_groups.query.graphql';
import ImportTableRow from './import_table_row.vue';
+const PAGE_SIZES = [20, 50, 100];
+const DEFAULT_PAGE_SIZE = PAGE_SIZES[0];
+
export default {
components: {
GlEmptyState,
+ GlDropdown,
+ GlDropdownItem,
GlIcon,
GlLink,
GlLoadingIcon,
@@ -33,12 +40,17 @@ export default {
type: String,
required: true,
},
+ groupPathRegex: {
+ type: RegExp,
+ required: true,
+ },
},
data() {
return {
filter: '',
page: 1,
+ perPage: DEFAULT_PAGE_SIZE,
};
},
@@ -46,13 +58,17 @@ export default {
bulkImportSourceGroups: {
query: bulkImportSourceGroupsQuery,
variables() {
- return { page: this.page, filter: this.filter };
+ return { page: this.page, filter: this.filter, perPage: this.perPage };
},
},
availableNamespaces: availableNamespacesQuery,
},
computed: {
+ humanizedTotal() {
+ return this.paginationInfo.total >= 1000 ? __('1000+') : this.paginationInfo.total;
+ },
+
hasGroups() {
return this.bulkImportSourceGroups?.nodes?.length > 0;
},
@@ -113,14 +129,20 @@ export default {
variables: { sourceGroupId },
});
},
+
+ setPageSize(size) {
+ this.perPage = size;
+ },
},
+
+ PAGE_SIZES,
};
</script>
<template>
<div>
<div
- class="gl-py-5 gl-border-solid gl-border-gray-200 gl-border-0 gl-border-b-1 gl-display-flex gl-align-items-center"
+ class="gl-py-5 gl-border-solid gl-border-gray-200 gl-border-0 gl-border-b-1 gl-display-flex"
>
<span>
<gl-sprintf v-if="!$apollo.loading && hasGroups" :message="statusMessage">
@@ -147,12 +169,17 @@ export default {
</div>
<gl-loading-icon v-if="$apollo.loading" size="md" class="gl-mt-5" />
<template v-else>
- <gl-empty-state v-if="hasEmptyFilter" :title="__('Sorry, your filter produced no results')" />
+ <gl-empty-state
+ v-if="hasEmptyFilter"
+ :title="__('Sorry, your filter produced no results')"
+ :description="__('To widen your search, change or remove filters above.')"
+ />
<gl-empty-state
v-else-if="!hasGroups"
- :title="s__('BulkImport|No groups available for import')"
+ :title="s__('BulkImport|You have no groups to import')"
+ :description="s__('Check your source instance permissions.')"
/>
- <div v-else class="gl-display-flex gl-flex-direction-column gl-align-items-center">
+ <template v-else>
<table class="gl-w-full">
<thead class="gl-border-solid gl-border-gray-200 gl-border-0 gl-border-b-1">
<th class="gl-py-4 import-jobs-from-col">{{ s__('BulkImport|From source group') }}</th>
@@ -160,12 +187,13 @@ export default {
<th class="gl-py-4 import-jobs-status-col">{{ __('Status') }}</th>
<th class="gl-py-4 import-jobs-cta-col"></th>
</thead>
- <tbody>
+ <tbody class="gl-vertical-align-top">
<template v-for="group in bulkImportSourceGroups.nodes">
<import-table-row
:key="group.id"
:group="group"
:available-namespaces="availableNamespaces"
+ :group-path-regex="groupPathRegex"
@update-target-namespace="updateTargetNamespace(group.id, $event)"
@update-new-name="updateNewName(group.id, $event)"
@import-group="importGroup(group.id)"
@@ -173,12 +201,50 @@ export default {
</template>
</tbody>
</table>
- <pagination-links
- :change="setPage"
- :page-info="bulkImportSourceGroups.pageInfo"
- class="gl-mt-3"
- />
- </div>
+ <div v-if="hasGroups" class="gl-display-flex gl-mt-3 gl-align-items-center">
+ <pagination-links
+ :change="setPage"
+ :page-info="bulkImportSourceGroups.pageInfo"
+ class="gl-m-0"
+ />
+ <gl-dropdown category="tertiary" class="gl-ml-auto">
+ <template #button-content>
+ <span class="font-weight-bold">
+ <gl-sprintf :message="__('%{count} items per page')">
+ <template #count>
+ {{ perPage }}
+ </template>
+ </gl-sprintf>
+ </span>
+ <gl-icon class="gl-button-icon dropdown-chevron" name="chevron-down" />
+ </template>
+ <gl-dropdown-item
+ v-for="size in $options.PAGE_SIZES"
+ :key="size"
+ @click="setPageSize(size)"
+ >
+ <gl-sprintf :message="__('%{count} items per page')">
+ <template #count>
+ {{ size }}
+ </template>
+ </gl-sprintf>
+ </gl-dropdown-item>
+ </gl-dropdown>
+ <div class="gl-ml-2">
+ <gl-sprintf :message="s__('BulkImport|Showing %{start}-%{end} of %{total}')">
+ <template #start>
+ {{ paginationInfo.start }}
+ </template>
+ <template #end>
+ {{ paginationInfo.end }}
+ </template>
+ <template #total>
+ {{ humanizedTotal }}
+ </template>
+ </gl-sprintf>
+ </div>
+ </div>
+ </template>
</template>
</div>
</template>
diff --git a/app/assets/javascripts/import_entities/import_groups/components/import_table_row.vue b/app/assets/javascripts/import_entities/import_groups/components/import_table_row.vue
index 1707ab10c89..aed879e75fb 100644
--- a/app/assets/javascripts/import_entities/import_groups/components/import_table_row.vue
+++ b/app/assets/javascripts/import_entities/import_groups/components/import_table_row.vue
@@ -1,15 +1,29 @@
<script>
-import { GlButton, GlIcon, GlLink, GlFormInput } from '@gitlab/ui';
+import {
+ GlButton,
+ GlDropdown,
+ GlDropdownDivider,
+ GlDropdownItem,
+ GlDropdownSectionHeader,
+ GlIcon,
+ GlLink,
+ GlFormInput,
+} from '@gitlab/ui';
import { joinPaths } from '~/lib/utils/url_utility';
-import Select2Select from '~/vue_shared/components/select2_select.vue';
import ImportStatus from '../../components/import_status.vue';
import { STATUSES } from '../../constants';
+import groupQuery from '../graphql/queries/group.query.graphql';
+
+const DEBOUNCE_INTERVAL = 300;
export default {
components: {
- Select2Select,
ImportStatus,
GlButton,
+ GlDropdown,
+ GlDropdownDivider,
+ GlDropdownItem,
+ GlDropdownSectionHeader,
GlLink,
GlIcon,
GlFormInput,
@@ -23,9 +37,41 @@ export default {
type: Array,
required: true,
},
+ groupPathRegex: {
+ type: RegExp,
+ required: true,
+ },
+ },
+
+ apollo: {
+ existingGroup: {
+ query: groupQuery,
+ debounce: DEBOUNCE_INTERVAL,
+ variables() {
+ return {
+ fullPath: this.fullPath,
+ };
+ },
+ skip() {
+ return !this.isNameValid || this.isAlreadyImported;
+ },
+ },
},
+
computed: {
- isDisabled() {
+ importTarget() {
+ return this.group.import_target;
+ },
+
+ isInvalid() {
+ return Boolean(!this.isNameValid || this.existingGroup);
+ },
+
+ isNameValid() {
+ return this.groupPathRegex.test(this.importTarget.new_name);
+ },
+
+ isAlreadyImported() {
return this.group.status !== STATUSES.NONE;
},
@@ -33,61 +79,89 @@ export default {
return this.group.status === STATUSES.FINISHED;
},
- select2Options() {
- return {
- data: this.availableNamespaces.map((namespace) => ({
- id: namespace.full_path,
- text: namespace.full_path,
- })),
- };
- },
- },
- methods: {
- getPath(group) {
- return `${group.import_target.target_namespace}/${group.import_target.new_name}`;
+ fullPath() {
+ return `${this.importTarget.target_namespace}/${this.importTarget.new_name}`;
},
- getFullPath(group) {
- return joinPaths(gon.relative_url_root || '/', this.getPath(group));
+ absolutePath() {
+ return joinPaths(gon.relative_url_root || '/', this.fullPath);
},
},
};
</script>
<template>
- <tr class="gl-border-gray-200 gl-border-0 gl-border-b-1">
+ <tr class="gl-border-gray-200 gl-border-0 gl-border-b-1 gl-border-solid">
<td class="gl-p-4">
- <gl-link :href="group.web_url" target="_blank">
+ <gl-link
+ :href="group.web_url"
+ target="_blank"
+ class="gl-display-flex gl-align-items-center gl-h-7"
+ >
{{ group.full_path }} <gl-icon name="external-link" />
</gl-link>
</td>
<td class="gl-p-4">
- <gl-link v-if="isFinished" :href="getFullPath(group)">{{ getPath(group) }}</gl-link>
+ <gl-link
+ v-if="isFinished"
+ class="gl-display-flex gl-align-items-center gl-h-7"
+ :href="absolutePath"
+ >
+ {{ fullPath }}
+ </gl-link>
<div
v-else
class="import-entities-target-select gl-display-flex gl-align-items-stretch"
:class="{
- disabled: isDisabled,
+ disabled: isAlreadyImported,
}"
>
- <select2-select
- :disabled="isDisabled"
- :options="select2Options"
- :value="group.import_target.target_namespace"
- @input="$emit('update-target-namespace', $event)"
- />
+ <gl-dropdown
+ :text="importTarget.target_namespace"
+ :disabled="isAlreadyImported"
+ toggle-class="gl-rounded-top-right-none! gl-rounded-bottom-right-none!"
+ class="import-entities-namespace-dropdown gl-h-7 gl-flex-fill-1"
+ >
+ <gl-dropdown-item @click="$emit('update-target-namespace', '')">{{
+ s__('BulkImport|No parent')
+ }}</gl-dropdown-item>
+ <template v-if="availableNamespaces.length">
+ <gl-dropdown-divider />
+ <gl-dropdown-section-header>
+ {{ s__('BulkImport|Existing groups') }}
+ </gl-dropdown-section-header>
+ <gl-dropdown-item
+ v-for="ns in availableNamespaces"
+ :key="ns.full_path"
+ @click="$emit('update-target-namespace', ns.full_path)"
+ >
+ {{ ns.full_path }}
+ </gl-dropdown-item>
+ </template>
+ </gl-dropdown>
<div
- class="import-entities-target-select-separator gl-px-3 gl-display-flex gl-align-items-center gl-border-solid gl-border-0 gl-border-t-1 gl-border-b-1"
+ class="import-entities-target-select-separator gl-h-7 gl-px-3 gl-display-flex gl-align-items-center gl-border-solid gl-border-0 gl-border-t-1 gl-border-b-1"
>
/
</div>
- <gl-form-input
- class="gl-rounded-top-left-none gl-rounded-bottom-left-none"
- :disabled="isDisabled"
- :value="group.import_target.new_name"
- @input="$emit('update-new-name', $event)"
- />
+ <div class="gl-flex-fill-1">
+ <gl-form-input
+ class="gl-rounded-top-left-none gl-rounded-bottom-left-none"
+ :class="{ 'is-invalid': isInvalid && !isAlreadyImported }"
+ :disabled="isAlreadyImported"
+ :value="importTarget.new_name"
+ @input="$emit('update-new-name', $event)"
+ />
+ <p v-if="isInvalid" class="gl-text-red-500 gl-m-0 gl-mt-2">
+ <template v-if="!isNameValid">
+ {{ __('Please choose a group URL with no special characters.') }}
+ </template>
+ <template v-else-if="existingGroup">
+ {{ s__('BulkImport|Name already exists.') }}
+ </template>
+ </p>
+ </div>
</div>
</td>
<td class="gl-p-4 gl-white-space-nowrap">
@@ -95,7 +169,8 @@ export default {
</td>
<td class="gl-p-4">
<gl-button
- v-if="!isDisabled"
+ v-if="!isAlreadyImported"
+ :disabled="isInvalid"
variant="success"
category="secondary"
@click="$emit('import-group')"
diff --git a/app/assets/javascripts/import_entities/import_groups/graphql/client_factory.js b/app/assets/javascripts/import_entities/import_groups/graphql/client_factory.js
index 8110934efc4..d444cc77aa7 100644
--- a/app/assets/javascripts/import_entities/import_groups/graphql/client_factory.js
+++ b/app/assets/javascripts/import_entities/import_groups/graphql/client_factory.js
@@ -15,52 +15,71 @@ export const clientTypenames = {
BulkImportPageInfo: 'ClientBulkImportPageInfo',
};
-export function createResolvers({ endpoints }) {
+export function createResolvers({ endpoints, sourceUrl, GroupsManager = SourceGroupsManager }) {
let statusPoller;
+ let sourceGroupManager;
+ const getGroupsManager = (client) => {
+ if (!sourceGroupManager) {
+ sourceGroupManager = new GroupsManager({ client, sourceUrl });
+ }
+ return sourceGroupManager;
+ };
+
return {
Query: {
async bulkImportSourceGroups(_, vars, { client }) {
- const {
- data: { availableNamespaces },
- } = await client.query({ query: availableNamespacesQuery });
-
if (!statusPoller) {
statusPoller = new StatusPoller({
- client,
+ groupManager: getGroupsManager(client),
pollPath: endpoints.jobs,
});
statusPoller.startPolling();
}
- return axios
- .get(endpoints.status, {
+ const groupsManager = getGroupsManager(client);
+ return Promise.all([
+ axios.get(endpoints.status, {
params: {
page: vars.page,
per_page: vars.perPage,
filter: vars.filter,
},
- })
- .then(({ headers, data }) => {
+ }),
+ client.query({ query: availableNamespacesQuery }),
+ ]).then(
+ ([
+ { headers, data },
+ {
+ data: { availableNamespaces },
+ },
+ ]) => {
const pagination = parseIntPagination(normalizeHeaders(headers));
return {
__typename: clientTypenames.BulkImportSourceGroupConnection,
- nodes: data.importable_data.map((group) => ({
- __typename: clientTypenames.BulkImportSourceGroup,
- ...group,
- status: STATUSES.NONE,
- import_target: {
- new_name: group.full_path,
- target_namespace: availableNamespaces[0].full_path,
- },
- })),
+ nodes: data.importable_data.map((group) => {
+ const cachedImportState = groupsManager.getImportStateFromStorageByGroupId(
+ group.id,
+ );
+
+ return {
+ __typename: clientTypenames.BulkImportSourceGroup,
+ ...group,
+ status: cachedImportState?.status ?? STATUSES.NONE,
+ import_target: cachedImportState?.importTarget ?? {
+ new_name: group.full_path,
+ target_namespace: availableNamespaces[0]?.full_path ?? '',
+ },
+ };
+ }),
pageInfo: {
__typename: clientTypenames.BulkImportPageInfo,
...pagination,
},
};
- });
+ },
+ );
},
availableNamespaces: () =>
@@ -73,21 +92,21 @@ export function createResolvers({ endpoints }) {
},
Mutation: {
setTargetNamespace(_, { targetNamespace, sourceGroupId }, { client }) {
- new SourceGroupsManager({ client }).updateById(sourceGroupId, (sourceGroup) => {
+ getGroupsManager(client).updateById(sourceGroupId, (sourceGroup) => {
// eslint-disable-next-line no-param-reassign
sourceGroup.import_target.target_namespace = targetNamespace;
});
},
setNewName(_, { newName, sourceGroupId }, { client }) {
- new SourceGroupsManager({ client }).updateById(sourceGroupId, (sourceGroup) => {
+ getGroupsManager(client).updateById(sourceGroupId, (sourceGroup) => {
// eslint-disable-next-line no-param-reassign
sourceGroup.import_target.new_name = newName;
});
},
async importGroup(_, { sourceGroupId }, { client }) {
- const groupManager = new SourceGroupsManager({ client });
+ const groupManager = getGroupsManager(client);
const group = groupManager.findById(sourceGroupId);
groupManager.setImportStatus(group, STATUSES.SCHEDULING);
try {
@@ -101,13 +120,10 @@ export function createResolvers({ endpoints }) {
},
],
});
- groupManager.setImportStatus(group, STATUSES.STARTED);
- SourceGroupsManager.attachImportId(group, response.data.id);
+ groupManager.startImport({ group, importId: response.data.id });
} catch (e) {
- createFlash({
- message: s__('BulkImport|Importing the group failed'),
- });
-
+ const message = e?.response?.data?.error ?? s__('BulkImport|Importing the group failed');
+ createFlash({ message });
groupManager.setImportStatus(group, STATUSES.NONE);
throw e;
}
@@ -116,5 +132,5 @@ export function createResolvers({ endpoints }) {
};
}
-export const createApolloClient = ({ endpoints }) =>
- createDefaultClient(createResolvers({ endpoints }), { assumeImmutableResults: true });
+export const createApolloClient = ({ sourceUrl, endpoints }) =>
+ createDefaultClient(createResolvers({ sourceUrl, endpoints }), { assumeImmutableResults: true });
diff --git a/app/assets/javascripts/import_entities/import_groups/graphql/queries/group.query.graphql b/app/assets/javascripts/import_entities/import_groups/graphql/queries/group.query.graphql
new file mode 100644
index 00000000000..52df3581ac4
--- /dev/null
+++ b/app/assets/javascripts/import_entities/import_groups/graphql/queries/group.query.graphql
@@ -0,0 +1,5 @@
+query group($fullPath: ID!) {
+ existingGroup: group(fullPath: $fullPath) {
+ id
+ }
+}
diff --git a/app/assets/javascripts/import_entities/import_groups/graphql/services/source_groups_manager.js b/app/assets/javascripts/import_entities/import_groups/graphql/services/source_groups_manager.js
index 261e30edbbb..2c88d25358f 100644
--- a/app/assets/javascripts/import_entities/import_groups/graphql/services/source_groups_manager.js
+++ b/app/assets/javascripts/import_entities/import_groups/graphql/services/source_groups_manager.js
@@ -1,5 +1,7 @@
import { defaultDataIdFromObject } from 'apollo-cache-inmemory';
import produce from 'immer';
+import { debounce, merge } from 'lodash';
+import { STATUSES } from '../../../constants';
import ImportSourceGroupFragment from '../fragments/bulk_import_source_group_item.fragment.graphql';
function extractTypeConditionFromFragment(fragment) {
@@ -13,15 +15,24 @@ function generateGroupId(id) {
});
}
+export const KEY = 'gl-bulk-imports-import-state';
+export const DEBOUNCE_INTERVAL = 200;
+
export class SourceGroupsManager {
- static importMap = new Map();
+ constructor({ client, sourceUrl, storage = window.localStorage }) {
+ this.client = client;
+ this.sourceUrl = sourceUrl;
- static attachImportId(group, importId) {
- SourceGroupsManager.importMap.set(importId, group.id);
+ this.storage = storage;
+ this.importStates = this.loadImportStatesFromStorage();
}
- constructor({ client }) {
- this.client = client;
+ loadImportStatesFromStorage() {
+ try {
+ return JSON.parse(this.storage.getItem(KEY)) ?? {};
+ } catch {
+ return {};
+ }
}
findById(id) {
@@ -42,8 +53,48 @@ export class SourceGroupsManager {
this.update(group, fn);
}
- findByImportId(importId) {
- return this.findById(SourceGroupsManager.importMap.get(importId));
+ saveImportState(importId, group) {
+ this.importStates[this.getStorageKey(importId)] = {
+ id: group.id,
+ importTarget: group.import_target,
+ status: group.status,
+ };
+ this.saveImportStatesToStorage();
+ }
+
+ getImportStateFromStorage(importId) {
+ return this.importStates[this.getStorageKey(importId)];
+ }
+
+ getImportStateFromStorageByGroupId(groupId) {
+ const PREFIX = this.getStorageKey('');
+ const [, importState] =
+ Object.entries(this.importStates).find(
+ ([key, group]) => key.startsWith(PREFIX) && group.id === groupId,
+ ) ?? [];
+
+ return importState;
+ }
+
+ getStorageKey(importId) {
+ return `${this.sourceUrl}|${importId}`;
+ }
+
+ saveImportStatesToStorage = debounce(() => {
+ try {
+ // storage might be changed in other tab so fetch first
+ this.storage.setItem(
+ KEY,
+ JSON.stringify(merge({}, this.loadImportStatesFromStorage(), this.importStates)),
+ );
+ } catch {
+ // empty catch intentional: storage might be unavailable or full
+ }
+ }, DEBOUNCE_INTERVAL);
+
+ startImport({ group, importId }) {
+ this.setImportStatus(group, STATUSES.CREATED);
+ this.saveImportState(importId, group);
}
setImportStatus(group, status) {
@@ -52,4 +103,22 @@ export class SourceGroupsManager {
sourceGroup.status = status;
});
}
+
+ setImportStatusByImportId(importId, status) {
+ const importState = this.getImportStateFromStorage(importId);
+ if (!importState) {
+ return;
+ }
+
+ if (importState.status !== status) {
+ importState.status = status;
+ }
+
+ const group = this.findById(importState.id);
+ if (group?.id) {
+ this.setImportStatus(group, status);
+ }
+
+ this.saveImportStatesToStorage();
+ }
}
diff --git a/app/assets/javascripts/import_entities/import_groups/graphql/services/status_poller.js b/app/assets/javascripts/import_entities/import_groups/graphql/services/status_poller.js
index 63cd6b48fc4..b80a575afce 100644
--- a/app/assets/javascripts/import_entities/import_groups/graphql/services/status_poller.js
+++ b/app/assets/javascripts/import_entities/import_groups/graphql/services/status_poller.js
@@ -3,12 +3,9 @@ import createFlash from '~/flash';
import axios from '~/lib/utils/axios_utils';
import Poll from '~/lib/utils/poll';
import { s__ } from '~/locale';
-import { SourceGroupsManager } from './source_groups_manager';
export class StatusPoller {
- constructor({ client, pollPath }) {
- this.client = client;
-
+ constructor({ groupManager, pollPath }) {
this.eTagPoll = new Poll({
resource: {
fetchJobs: () => axios.get(pollPath),
@@ -29,7 +26,7 @@ export class StatusPoller {
}
});
- this.groupManager = new SourceGroupsManager({ client });
+ this.groupManager = groupManager;
}
startPolling() {
@@ -38,10 +35,7 @@ export class StatusPoller {
async updateImportsStatuses(importStatuses) {
importStatuses.forEach(({ id, status_name: statusName }) => {
- const group = this.groupManager.findByImportId(id);
- if (group.id) {
- this.groupManager.setImportStatus(group, statusName);
- }
+ this.groupManager.setImportStatusByImportId(id, statusName);
});
}
}
diff --git a/app/assets/javascripts/import_entities/import_groups/index.js b/app/assets/javascripts/import_entities/import_groups/index.js
index cd837a840e4..cc60c8cbdb0 100644
--- a/app/assets/javascripts/import_entities/import_groups/index.js
+++ b/app/assets/javascripts/import_entities/import_groups/index.js
@@ -16,9 +16,11 @@ export function mountImportGroupsApp(mountElement) {
createBulkImportPath,
jobsPath,
sourceUrl,
+ groupPathRegex,
} = mountElement.dataset;
const apolloProvider = new VueApollo({
defaultClient: createApolloClient({
+ sourceUrl,
endpoints: {
status: statusPath,
availableNamespaces: availableNamespacesPath,
@@ -35,6 +37,7 @@ export function mountImportGroupsApp(mountElement) {
return createElement(ImportTable, {
props: {
sourceUrl,
+ groupPathRegex: new RegExp(`^(${groupPathRegex})$`),
},
});
},