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:
authorGitLab Bot <gitlab-bot@gitlab.com>2021-04-30 15:12:30 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2021-04-30 15:12:30 +0300
commit6d19e491d1257b6fbc74f4cf3a30ddb28deaeaf4 (patch)
treee14c505a5e880c85161d8c5b17b23341b6c37a21 /app/assets/javascripts/import_entities
parentea0085de54590ffde24fee2ced286961a419410d (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app/assets/javascripts/import_entities')
-rw-r--r--app/assets/javascripts/import_entities/import_groups/components/import_table_row.vue6
-rw-r--r--app/assets/javascripts/import_entities/import_groups/graphql/client_factory.js182
-rw-r--r--app/assets/javascripts/import_entities/import_groups/graphql/fragments/bulk_import_source_group_item.fragment.graphql11
-rw-r--r--app/assets/javascripts/import_entities/import_groups/graphql/fragments/bulk_import_source_group_progress.fragment.graphql4
-rw-r--r--app/assets/javascripts/import_entities/import_groups/graphql/mutations/import_group.mutation.graphql8
-rw-r--r--app/assets/javascripts/import_entities/import_groups/graphql/mutations/set_import_progress.mutation.graphql9
-rw-r--r--app/assets/javascripts/import_entities/import_groups/graphql/mutations/set_new_name.mutation.graphql7
-rw-r--r--app/assets/javascripts/import_entities/import_groups/graphql/mutations/set_target_namespace.mutation.graphql7
-rw-r--r--app/assets/javascripts/import_entities/import_groups/graphql/mutations/update_import_status.mutation.graphql6
-rw-r--r--app/assets/javascripts/import_entities/import_groups/graphql/queries/bulk_import_source_group.query.graphql7
-rw-r--r--app/assets/javascripts/import_entities/import_groups/graphql/services/source_groups_manager.js85
-rw-r--r--app/assets/javascripts/import_entities/import_groups/graphql/services/status_poller.js14
-rw-r--r--app/assets/javascripts/import_entities/import_groups/graphql/typedefs.graphql53
13 files changed, 268 insertions, 131 deletions
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 aed879e75fb..1d36b370457 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
@@ -72,11 +72,11 @@ export default {
},
isAlreadyImported() {
- return this.group.status !== STATUSES.NONE;
+ return this.group.progress.status !== STATUSES.NONE;
},
isFinished() {
- return this.group.status === STATUSES.FINISHED;
+ return this.group.progress.status === STATUSES.FINISHED;
},
fullPath() {
@@ -165,7 +165,7 @@ export default {
</div>
</td>
<td class="gl-p-4 gl-white-space-nowrap">
- <import-status :status="group.status" />
+ <import-status :status="group.progress.status" />
</td>
<td class="gl-p-4">
<gl-button
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 d444cc77aa7..facefe316eb 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
@@ -4,40 +4,82 @@ import axios from '~/lib/utils/axios_utils';
import { parseIntPagination, normalizeHeaders } from '~/lib/utils/common_utils';
import { s__ } from '~/locale';
import { STATUSES } from '../../constants';
+import bulkImportSourceGroupItemFragment from './fragments/bulk_import_source_group_item.fragment.graphql';
+import setImportProgressMutation from './mutations/set_import_progress.mutation.graphql';
+import updateImportStatusMutation from './mutations/update_import_status.mutation.graphql';
import availableNamespacesQuery from './queries/available_namespaces.query.graphql';
+import bulkImportSourceGroupQuery from './queries/bulk_import_source_group.query.graphql';
import { SourceGroupsManager } from './services/source_groups_manager';
import { StatusPoller } from './services/status_poller';
+import typeDefs from './typedefs.graphql';
export const clientTypenames = {
BulkImportSourceGroupConnection: 'ClientBulkImportSourceGroupConnection',
BulkImportSourceGroup: 'ClientBulkImportSourceGroup',
AvailableNamespace: 'ClientAvailableNamespace',
BulkImportPageInfo: 'ClientBulkImportPageInfo',
+ BulkImportTarget: 'ClientBulkImportTarget',
+ BulkImportProgress: 'ClientBulkImportProgress',
};
-export function createResolvers({ endpoints, sourceUrl, GroupsManager = SourceGroupsManager }) {
- let statusPoller;
+function makeGroup(data) {
+ const result = {
+ __typename: clientTypenames.BulkImportSourceGroup,
+ ...data,
+ };
+ const NESTED_OBJECT_FIELDS = {
+ import_target: clientTypenames.BulkImportTarget,
+ progress: clientTypenames.BulkImportProgress,
+ };
- let sourceGroupManager;
- const getGroupsManager = (client) => {
- if (!sourceGroupManager) {
- sourceGroupManager = new GroupsManager({ client, sourceUrl });
+ Object.entries(NESTED_OBJECT_FIELDS).forEach(([field, type]) => {
+ if (!data[field]) {
+ return;
}
- return sourceGroupManager;
- };
+ result[field] = {
+ __typename: type,
+ ...data[field],
+ };
+ });
+
+ return result;
+}
+
+const localProgressId = (id) => `not-started-${id}`;
+
+export function createResolvers({ endpoints, sourceUrl, GroupsManager = SourceGroupsManager }) {
+ const groupsManager = new GroupsManager({
+ sourceUrl,
+ });
+
+ let statusPoller;
return {
Query: {
+ async bulkImportSourceGroup(_, { id }, { client, getCacheKey }) {
+ return client.readFragment({
+ fragment: bulkImportSourceGroupItemFragment,
+ fragmentName: 'BulkImportSourceGroupItem',
+ id: getCacheKey({
+ __typename: clientTypenames.BulkImportSourceGroup,
+ id,
+ }),
+ });
+ },
+
async bulkImportSourceGroups(_, vars, { client }) {
if (!statusPoller) {
statusPoller = new StatusPoller({
- groupManager: getGroupsManager(client),
+ updateImportStatus: ({ id, status_name: status }) =>
+ client.mutate({
+ mutation: updateImportStatusMutation,
+ variables: { id, status },
+ }),
pollPath: endpoints.jobs,
});
statusPoller.startPolling();
}
- const groupsManager = getGroupsManager(client);
return Promise.all([
axios.get(endpoints.status, {
params: {
@@ -59,19 +101,20 @@ export function createResolvers({ endpoints, sourceUrl, GroupsManager = SourceGr
return {
__typename: clientTypenames.BulkImportSourceGroupConnection,
nodes: data.importable_data.map((group) => {
- const cachedImportState = groupsManager.getImportStateFromStorageByGroupId(
- group.id,
- );
+ const { jobId, importState: cachedImportState } =
+ groupsManager.getImportStateFromStorageByGroupId(group.id) ?? {};
- return {
- __typename: clientTypenames.BulkImportSourceGroup,
+ return makeGroup({
...group,
- status: cachedImportState?.status ?? STATUSES.NONE,
+ progress: {
+ id: jobId ?? localProgressId(group.id),
+ status: cachedImportState?.status ?? STATUSES.NONE,
+ },
import_target: cachedImportState?.importTarget ?? {
new_name: group.full_path,
target_namespace: availableNamespaces[0]?.full_path ?? '',
},
- };
+ });
}),
pageInfo: {
__typename: clientTypenames.BulkImportPageInfo,
@@ -91,26 +134,65 @@ export function createResolvers({ endpoints, sourceUrl, GroupsManager = SourceGr
),
},
Mutation: {
- setTargetNamespace(_, { targetNamespace, sourceGroupId }, { client }) {
- getGroupsManager(client).updateById(sourceGroupId, (sourceGroup) => {
- // eslint-disable-next-line no-param-reassign
- sourceGroup.import_target.target_namespace = targetNamespace;
+ setTargetNamespace: (_, { targetNamespace, sourceGroupId }) =>
+ makeGroup({
+ id: sourceGroupId,
+ import_target: {
+ target_namespace: targetNamespace,
+ },
+ }),
+
+ setNewName: (_, { newName, sourceGroupId }) =>
+ makeGroup({
+ id: sourceGroupId,
+ import_target: {
+ new_name: newName,
+ },
+ }),
+
+ async setImportProgress(_, { sourceGroupId, status, jobId }) {
+ if (jobId) {
+ groupsManager.saveImportState(jobId, { status });
+ }
+
+ return makeGroup({
+ id: sourceGroupId,
+ progress: {
+ id: jobId ?? localProgressId(sourceGroupId),
+ status,
+ },
});
},
- setNewName(_, { newName, sourceGroupId }, { client }) {
- getGroupsManager(client).updateById(sourceGroupId, (sourceGroup) => {
- // eslint-disable-next-line no-param-reassign
- sourceGroup.import_target.new_name = newName;
- });
+ async updateImportStatus(_, { id, status }) {
+ groupsManager.saveImportState(id, { status });
+
+ return {
+ __typename: clientTypenames.BulkImportProgress,
+ id,
+ status,
+ };
},
async importGroup(_, { sourceGroupId }, { client }) {
- const groupManager = getGroupsManager(client);
- const group = groupManager.findById(sourceGroupId);
- groupManager.setImportStatus(group, STATUSES.SCHEDULING);
- try {
- const response = await axios.post(endpoints.createBulkImport, {
+ const {
+ data: { bulkImportSourceGroup: group },
+ } = await client.query({
+ query: bulkImportSourceGroupQuery,
+ variables: { id: sourceGroupId },
+ });
+
+ const GROUP_BEING_SCHEDULED = makeGroup({
+ id: sourceGroupId,
+ progress: {
+ id: localProgressId(sourceGroupId),
+ status: STATUSES.SCHEDULING,
+ },
+ });
+
+ const defaultErrorMessage = s__('BulkImport|Importing the group failed');
+ axios
+ .post(endpoints.createBulkImport, {
bulk_import: [
{
source_type: 'group_entity',
@@ -119,18 +201,38 @@ export function createResolvers({ endpoints, sourceUrl, GroupsManager = SourceGr
destination_name: group.import_target.new_name,
},
],
- });
- groupManager.startImport({ group, importId: response.data.id });
- } catch (e) {
- const message = e?.response?.data?.error ?? s__('BulkImport|Importing the group failed');
- createFlash({ message });
- groupManager.setImportStatus(group, STATUSES.NONE);
- throw e;
- }
+ })
+ .then(({ data: { id: jobId } }) => {
+ groupsManager.saveImportState(jobId, {
+ id: group.id,
+ importTarget: group.import_target,
+ status: STATUSES.CREATED,
+ });
+
+ return { status: STATUSES.CREATED, jobId };
+ })
+ .catch((e) => {
+ const message = e?.response?.data?.error ?? defaultErrorMessage;
+ createFlash({ message });
+ return { status: STATUSES.NONE };
+ })
+ .then((newStatus) =>
+ client.mutate({
+ mutation: setImportProgressMutation,
+ variables: { sourceGroupId, ...newStatus },
+ }),
+ )
+ .catch(() => createFlash({ message: defaultErrorMessage }));
+
+ return GROUP_BEING_SCHEDULED;
},
},
};
}
export const createApolloClient = ({ sourceUrl, endpoints }) =>
- createDefaultClient(createResolvers({ sourceUrl, endpoints }), { assumeImmutableResults: true });
+ createDefaultClient(
+ createResolvers({ sourceUrl, endpoints }),
+ { assumeImmutableResults: true },
+ typeDefs,
+ );
diff --git a/app/assets/javascripts/import_entities/import_groups/graphql/fragments/bulk_import_source_group_item.fragment.graphql b/app/assets/javascripts/import_entities/import_groups/graphql/fragments/bulk_import_source_group_item.fragment.graphql
index 50774e36599..ee3add7966c 100644
--- a/app/assets/javascripts/import_entities/import_groups/graphql/fragments/bulk_import_source_group_item.fragment.graphql
+++ b/app/assets/javascripts/import_entities/import_groups/graphql/fragments/bulk_import_source_group_item.fragment.graphql
@@ -1,8 +1,15 @@
+#import "./bulk_import_source_group_progress.fragment.graphql"
+
fragment BulkImportSourceGroupItem on ClientBulkImportSourceGroup {
id
web_url
full_path
full_name
- status
- import_target
+ progress {
+ ...BulkImportSourceGroupProgress
+ }
+ import_target {
+ target_namespace
+ new_name
+ }
}
diff --git a/app/assets/javascripts/import_entities/import_groups/graphql/fragments/bulk_import_source_group_progress.fragment.graphql b/app/assets/javascripts/import_entities/import_groups/graphql/fragments/bulk_import_source_group_progress.fragment.graphql
new file mode 100644
index 00000000000..2d60bf82d65
--- /dev/null
+++ b/app/assets/javascripts/import_entities/import_groups/graphql/fragments/bulk_import_source_group_progress.fragment.graphql
@@ -0,0 +1,4 @@
+fragment BulkImportSourceGroupProgress on ClientBulkImportProgress {
+ id
+ status
+}
diff --git a/app/assets/javascripts/import_entities/import_groups/graphql/mutations/import_group.mutation.graphql b/app/assets/javascripts/import_entities/import_groups/graphql/mutations/import_group.mutation.graphql
index 412608d3faf..41d32a1d639 100644
--- a/app/assets/javascripts/import_entities/import_groups/graphql/mutations/import_group.mutation.graphql
+++ b/app/assets/javascripts/import_entities/import_groups/graphql/mutations/import_group.mutation.graphql
@@ -1,3 +1,9 @@
mutation importGroup($sourceGroupId: String!) {
- importGroup(sourceGroupId: $sourceGroupId) @client
+ importGroup(sourceGroupId: $sourceGroupId) @client {
+ id
+ progress {
+ id
+ status
+ }
+ }
}
diff --git a/app/assets/javascripts/import_entities/import_groups/graphql/mutations/set_import_progress.mutation.graphql b/app/assets/javascripts/import_entities/import_groups/graphql/mutations/set_import_progress.mutation.graphql
new file mode 100644
index 00000000000..2ec1269932a
--- /dev/null
+++ b/app/assets/javascripts/import_entities/import_groups/graphql/mutations/set_import_progress.mutation.graphql
@@ -0,0 +1,9 @@
+mutation setImportProgress($status: String!, $sourceGroupId: String!, $jobId: String) {
+ setImportProgress(status: $status, sourceGroupId: $sourceGroupId, jobId: $jobId) @client {
+ id
+ progress {
+ id
+ status
+ }
+ }
+}
diff --git a/app/assets/javascripts/import_entities/import_groups/graphql/mutations/set_new_name.mutation.graphql b/app/assets/javascripts/import_entities/import_groups/graphql/mutations/set_new_name.mutation.graphql
index 2bc19891401..354bf2a5815 100644
--- a/app/assets/javascripts/import_entities/import_groups/graphql/mutations/set_new_name.mutation.graphql
+++ b/app/assets/javascripts/import_entities/import_groups/graphql/mutations/set_new_name.mutation.graphql
@@ -1,3 +1,8 @@
mutation setNewName($newName: String!, $sourceGroupId: String!) {
- setNewName(newName: $newName, sourceGroupId: $sourceGroupId) @client
+ setNewName(newName: $newName, sourceGroupId: $sourceGroupId) @client {
+ id
+ import_target {
+ new_name
+ }
+ }
}
diff --git a/app/assets/javascripts/import_entities/import_groups/graphql/mutations/set_target_namespace.mutation.graphql b/app/assets/javascripts/import_entities/import_groups/graphql/mutations/set_target_namespace.mutation.graphql
index fc98a1652c1..a0ef407f135 100644
--- a/app/assets/javascripts/import_entities/import_groups/graphql/mutations/set_target_namespace.mutation.graphql
+++ b/app/assets/javascripts/import_entities/import_groups/graphql/mutations/set_target_namespace.mutation.graphql
@@ -1,3 +1,8 @@
mutation setTargetNamespace($targetNamespace: String!, $sourceGroupId: String!) {
- setTargetNamespace(targetNamespace: $targetNamespace, sourceGroupId: $sourceGroupId) @client
+ setTargetNamespace(targetNamespace: $targetNamespace, sourceGroupId: $sourceGroupId) @client {
+ id
+ import_target {
+ target_namespace
+ }
+ }
}
diff --git a/app/assets/javascripts/import_entities/import_groups/graphql/mutations/update_import_status.mutation.graphql b/app/assets/javascripts/import_entities/import_groups/graphql/mutations/update_import_status.mutation.graphql
new file mode 100644
index 00000000000..8c0233b2939
--- /dev/null
+++ b/app/assets/javascripts/import_entities/import_groups/graphql/mutations/update_import_status.mutation.graphql
@@ -0,0 +1,6 @@
+mutation updateImportStatus($status: String!, $id: String!) {
+ updateImportStatus(status: $status, id: $id) @client {
+ id
+ status
+ }
+}
diff --git a/app/assets/javascripts/import_entities/import_groups/graphql/queries/bulk_import_source_group.query.graphql b/app/assets/javascripts/import_entities/import_groups/graphql/queries/bulk_import_source_group.query.graphql
new file mode 100644
index 00000000000..0aff23af96d
--- /dev/null
+++ b/app/assets/javascripts/import_entities/import_groups/graphql/queries/bulk_import_source_group.query.graphql
@@ -0,0 +1,7 @@
+#import "../fragments/bulk_import_source_group_item.fragment.graphql"
+
+query bulkImportSourceGroup($id: ID!) {
+ bulkImportSourceGroup(id: $id) @client {
+ ...BulkImportSourceGroupItem
+ }
+}
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 2c88d25358f..536f96529d7 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,26 +1,10 @@
-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) {
- return fragment.definitions[0]?.typeCondition.name.value;
-}
-
-function generateGroupId(id) {
- return defaultDataIdFromObject({
- __typename: extractTypeConditionFromFragment(ImportSourceGroupFragment),
- id,
- });
-}
export const KEY = 'gl-bulk-imports-import-state';
export const DEBOUNCE_INTERVAL = 200;
export class SourceGroupsManager {
- constructor({ client, sourceUrl, storage = window.localStorage }) {
- this.client = client;
+ constructor({ sourceUrl, storage = window.localStorage }) {
this.sourceUrl = sourceUrl;
this.storage = storage;
@@ -35,45 +19,30 @@ export class SourceGroupsManager {
}
}
- findById(id) {
- const cacheId = generateGroupId(id);
- return this.client.readFragment({ fragment: ImportSourceGroupFragment, id: cacheId });
- }
-
- update(group, fn) {
- this.client.writeFragment({
- fragment: ImportSourceGroupFragment,
- id: generateGroupId(group.id),
- data: produce(group, fn),
- });
- }
+ saveImportState(importId, group) {
+ const key = this.getStorageKey(importId);
+ const oldState = this.importStates[key] ?? {};
- updateById(id, fn) {
- const group = this.findById(id);
- this.update(group, fn);
- }
+ if (!oldState.id && !group.id) {
+ return;
+ }
- saveImportState(importId, group) {
- this.importStates[this.getStorageKey(importId)] = {
- id: group.id,
- importTarget: group.import_target,
+ this.importStates[key] = {
+ ...oldState,
+ ...group,
status: group.status,
};
this.saveImportStatesToStorage();
}
- getImportStateFromStorage(importId) {
- return this.importStates[this.getStorageKey(importId)];
- }
-
getImportStateFromStorageByGroupId(groupId) {
const PREFIX = this.getStorageKey('');
- const [, importState] =
+ const [jobId, importState] =
Object.entries(this.importStates).find(
([key, group]) => key.startsWith(PREFIX) && group.id === groupId,
) ?? [];
- return importState;
+ return { jobId, importState };
}
getStorageKey(importId) {
@@ -91,34 +60,4 @@ export class SourceGroupsManager {
// 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) {
- this.update(group, (sourceGroup) => {
- // eslint-disable-next-line no-param-reassign
- 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 b80a575afce..0297b3d3428 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
@@ -5,13 +5,15 @@ import Poll from '~/lib/utils/poll';
import { s__ } from '~/locale';
export class StatusPoller {
- constructor({ groupManager, pollPath }) {
+ constructor({ updateImportStatus, pollPath }) {
this.eTagPoll = new Poll({
resource: {
fetchJobs: () => axios.get(pollPath),
},
method: 'fetchJobs',
- successCallback: ({ data }) => this.updateImportsStatuses(data),
+ successCallback: ({ data: statuses }) => {
+ statuses.forEach((status) => updateImportStatus(status));
+ },
errorCallback: () =>
createFlash({
message: s__('BulkImport|Update of import statuses with realtime changes failed'),
@@ -25,17 +27,9 @@ export class StatusPoller {
this.eTagPoll.stop();
}
});
-
- this.groupManager = groupManager;
}
startPolling() {
this.eTagPoll.makeRequest();
}
-
- async updateImportsStatuses(importStatuses) {
- importStatuses.forEach(({ id, status_name: statusName }) => {
- this.groupManager.setImportStatusByImportId(id, statusName);
- });
- }
}
diff --git a/app/assets/javascripts/import_entities/import_groups/graphql/typedefs.graphql b/app/assets/javascripts/import_entities/import_groups/graphql/typedefs.graphql
new file mode 100644
index 00000000000..ba042d33893
--- /dev/null
+++ b/app/assets/javascripts/import_entities/import_groups/graphql/typedefs.graphql
@@ -0,0 +1,53 @@
+type ClientBulkImportAvailableNamespace {
+ id: ID!
+ full_path: String!
+}
+
+type ClientBulkImportTarget {
+ target_namespace: String!
+ new_name: String!
+}
+
+type ClientBulkImportSourceGroupConnection {
+ nodes: [ClientBulkImportSourceGroup!]!
+ pageInfo: ClientBulkImportPageInfo!
+}
+
+type ClientBulkImportProgress {
+ id: ID
+ status: String!
+}
+
+type ClientBulkImportSourceGroup {
+ id: ID!
+ web_url: String!
+ full_path: String!
+ full_name: String!
+ progress: ClientBulkImportProgress!
+ import_target: ClientBulkImportTarget!
+}
+
+type ClientBulkImportPageInfo {
+ page: Int!
+ perPage: Int!
+ total: Int!
+ totalPages: Int!
+}
+
+extend type Query {
+ bulkImportSourceGroup(id: ID!): ClientBulkImportSourceGroup
+ bulkImportSourceGroups(
+ page: Int!
+ perPage: Int!
+ filter: String!
+ ): ClientBulkImportSourceGroupConnection!
+ availableNamespaces: [ClientBulkImportAvailableNamespace!]!
+}
+
+extend type Mutation {
+ setNewName(newName: String, sourceGroupId: ID!): ClientTargetNamespace!
+ setTargetNamespace(targetNamespace: String, sourceGroupId: ID!): ClientTargetNamespace!
+ importGroup(id: ID!): ClientBulkImportSourceGroup!
+ setImportProgress(id: ID, status: String!): ClientBulkImportSourceGroup!
+ updateImportProgress(id: ID, status: String!): ClientBulkImportProgress
+}