Commit e81101e3 authored by Illya Klymov's avatar Illya Klymov Committed by Jacques Erasmus

Update client_factory to provide last_import_target

* update relevant specs
parent a9d2b71c
...@@ -5,10 +5,13 @@ import { parseIntPagination, normalizeHeaders } from '~/lib/utils/common_utils'; ...@@ -5,10 +5,13 @@ import { parseIntPagination, normalizeHeaders } from '~/lib/utils/common_utils';
import { s__ } from '~/locale'; import { s__ } from '~/locale';
import { STATUSES } from '../../constants'; import { STATUSES } from '../../constants';
import { i18n, NEW_NAME_FIELD } from '../constants'; import { i18n, NEW_NAME_FIELD } from '../constants';
import { isAvailableForImport } from '../utils';
import bulkImportSourceGroupItemFragment from './fragments/bulk_import_source_group_item.fragment.graphql'; import bulkImportSourceGroupItemFragment from './fragments/bulk_import_source_group_item.fragment.graphql';
import bulkImportSourceGroupProgressFragment from './fragments/bulk_import_source_group_progress.fragment.graphql';
import addValidationErrorMutation from './mutations/add_validation_error.mutation.graphql'; import addValidationErrorMutation from './mutations/add_validation_error.mutation.graphql';
import removeValidationErrorMutation from './mutations/remove_validation_error.mutation.graphql'; import removeValidationErrorMutation from './mutations/remove_validation_error.mutation.graphql';
import setImportProgressMutation from './mutations/set_import_progress.mutation.graphql'; import setImportProgressMutation from './mutations/set_import_progress.mutation.graphql';
import setImportTargetMutation from './mutations/set_import_target.mutation.graphql';
import updateImportStatusMutation from './mutations/update_import_status.mutation.graphql'; import updateImportStatusMutation from './mutations/update_import_status.mutation.graphql';
import availableNamespacesQuery from './queries/available_namespaces.query.graphql'; import availableNamespacesQuery from './queries/available_namespaces.query.graphql';
import bulkImportSourceGroupQuery from './queries/bulk_import_source_group.query.graphql'; import bulkImportSourceGroupQuery from './queries/bulk_import_source_group.query.graphql';
...@@ -34,6 +37,7 @@ function makeGroup(data) { ...@@ -34,6 +37,7 @@ function makeGroup(data) {
}; };
const NESTED_OBJECT_FIELDS = { const NESTED_OBJECT_FIELDS = {
import_target: clientTypenames.BulkImportTarget, import_target: clientTypenames.BulkImportTarget,
last_import_target: clientTypenames.BulkImportTarget,
progress: clientTypenames.BulkImportProgress, progress: clientTypenames.BulkImportProgress,
}; };
...@@ -55,6 +59,7 @@ async function checkImportTargetIsValid({ client, newName, targetNamespace, sour ...@@ -55,6 +59,7 @@ async function checkImportTargetIsValid({ client, newName, targetNamespace, sour
data: { existingGroup, existingProject }, data: { existingGroup, existingProject },
} = await client.query({ } = await client.query({
query: groupAndProjectQuery, query: groupAndProjectQuery,
fetchPolicy: 'no-cache',
variables: { variables: {
fullPath: `${targetNamespace}/${newName}`, fullPath: `${targetNamespace}/${newName}`,
}, },
...@@ -82,6 +87,7 @@ async function checkImportTargetIsValid({ client, newName, targetNamespace, sour ...@@ -82,6 +87,7 @@ async function checkImportTargetIsValid({ client, newName, targetNamespace, sour
} }
const localProgressId = (id) => `not-started-${id}`; const localProgressId = (id) => `not-started-${id}`;
const nextName = (name) => `${name}-1`;
export function createResolvers({ endpoints, sourceUrl, GroupsManager = SourceGroupsManager }) { export function createResolvers({ endpoints, sourceUrl, GroupsManager = SourceGroupsManager }) {
const groupsManager = new GroupsManager({ const groupsManager = new GroupsManager({
...@@ -140,17 +146,28 @@ export function createResolvers({ endpoints, sourceUrl, GroupsManager = SourceGr ...@@ -140,17 +146,28 @@ export function createResolvers({ endpoints, sourceUrl, GroupsManager = SourceGr
const { jobId, importState: cachedImportState } = const { jobId, importState: cachedImportState } =
groupsManager.getImportStateFromStorageByGroupId(group.id) ?? {}; groupsManager.getImportStateFromStorageByGroupId(group.id) ?? {};
const status = cachedImportState?.status ?? STATUSES.NONE;
const importTarget =
status === STATUSES.FINISHED && cachedImportState.importTarget
? {
target_namespace: cachedImportState.importTarget.target_namespace,
new_name: nextName(cachedImportState.importTarget.new_name),
}
: cachedImportState?.importTarget ?? {
new_name: group.full_path,
target_namespace: availableNamespaces[0]?.full_path ?? '',
};
return makeGroup({ return makeGroup({
...group, ...group,
validation_errors: [], validation_errors: [],
progress: { progress: {
id: jobId ?? localProgressId(group.id), id: jobId ?? localProgressId(group.id),
status: cachedImportState?.status ?? STATUSES.NONE, status,
},
import_target: cachedImportState?.importTarget ?? {
new_name: group.full_path,
target_namespace: availableNamespaces[0]?.full_path ?? '',
}, },
import_target: importTarget,
last_import_target: cachedImportState?.importTarget ?? null,
}); });
}), }),
pageInfo: { pageInfo: {
...@@ -161,7 +178,7 @@ export function createResolvers({ endpoints, sourceUrl, GroupsManager = SourceGr ...@@ -161,7 +178,7 @@ export function createResolvers({ endpoints, sourceUrl, GroupsManager = SourceGr
setTimeout(() => { setTimeout(() => {
response.nodes.forEach((group) => { response.nodes.forEach((group) => {
if (group.progress.status === STATUSES.NONE) { if (isAvailableForImport(group)) {
checkImportTargetIsValid({ checkImportTargetIsValid({
client, client,
newName: group.import_target.new_name, newName: group.import_target.new_name,
...@@ -193,32 +210,18 @@ export function createResolvers({ endpoints, sourceUrl, GroupsManager = SourceGr ...@@ -193,32 +210,18 @@ export function createResolvers({ endpoints, sourceUrl, GroupsManager = SourceGr
targetNamespace, targetNamespace,
newName, newName,
}); });
return makeGroup({ return makeGroup({
id: sourceGroupId, id: sourceGroupId,
import_target: { import_target: {
target_namespace: targetNamespace, target_namespace: targetNamespace,
new_name: newName, new_name: newName,
},
});
},
setTargetNamespace: (_, { targetNamespace, sourceGroupId }) =>
makeGroup({
id: sourceGroupId, id: sourceGroupId,
import_target: {
target_namespace: targetNamespace,
}, },
}), });
setNewName: (_, { newName, sourceGroupId }) =>
makeGroup({
id: sourceGroupId,
import_target: {
new_name: newName,
}, },
}),
async setImportProgress(_, { sourceGroupId, status, jobId }) { async setImportProgress(_, { sourceGroupId, status, jobId, importTarget }) {
if (jobId) { if (jobId) {
groupsManager.updateImportProgress(jobId, status); groupsManager.updateImportProgress(jobId, status);
} }
...@@ -229,12 +232,40 @@ export function createResolvers({ endpoints, sourceUrl, GroupsManager = SourceGr ...@@ -229,12 +232,40 @@ export function createResolvers({ endpoints, sourceUrl, GroupsManager = SourceGr
id: jobId ?? localProgressId(sourceGroupId), id: jobId ?? localProgressId(sourceGroupId),
status, status,
}, },
last_import_target: {
__typename: clientTypenames.BulkImportTarget,
...importTarget,
},
}); });
}, },
async updateImportStatus(_, { id, status }) { async updateImportStatus(_, { id, status }, { client, getCacheKey }) {
groupsManager.updateImportProgress(id, status); groupsManager.updateImportProgress(id, status);
const progressItem = client.readFragment({
fragment: bulkImportSourceGroupProgressFragment,
fragmentName: 'BulkImportSourceGroupProgress',
id: getCacheKey({
__typename: clientTypenames.BulkImportProgress,
id,
}),
});
if (status === STATUSES.FINISHED && progressItem && progressItem.status !== status) {
const groups = groupsManager.getImportedGroupsByJobId(id);
groups.forEach(async ({ id: groupId, importTarget }) => {
client.mutate({
mutation: setImportTargetMutation,
variables: {
sourceGroupId: groupId,
targetNamespace: importTarget.target_namespace,
newName: nextName(importTarget.new_name),
},
});
});
}
return { return {
__typename: clientTypenames.BulkImportProgress, __typename: clientTypenames.BulkImportProgress,
id, id,
...@@ -327,10 +358,10 @@ export function createResolvers({ endpoints, sourceUrl, GroupsManager = SourceGr ...@@ -327,10 +358,10 @@ export function createResolvers({ endpoints, sourceUrl, GroupsManager = SourceGr
return { status: STATUSES.NONE }; return { status: STATUSES.NONE };
}) })
.then((newStatus) => .then((newStatus) =>
sourceGroupIds.forEach((sourceGroupId) => sourceGroupIds.forEach((sourceGroupId, idx) =>
client.mutate({ client.mutate({
mutation: setImportProgressMutation, mutation: setImportProgressMutation,
variables: { sourceGroupId, ...newStatus }, variables: { sourceGroupId, ...newStatus, importTarget: groups[idx].import_target },
}), }),
), ),
) )
......
...@@ -5830,6 +5830,9 @@ msgstr "" ...@@ -5830,6 +5830,9 @@ msgstr ""
msgid "Bulk update" msgid "Bulk update"
msgstr "" msgstr ""
msgid "BulkImports|Re-import creates a new group. It does not sync with the existing group."
msgstr ""
msgid "BulkImport|Existing groups" msgid "BulkImport|Existing groups"
msgstr "" msgstr ""
...@@ -5851,6 +5854,9 @@ msgstr "" ...@@ -5851,6 +5854,9 @@ msgstr ""
msgid "BulkImport|Importing the group failed" msgid "BulkImport|Importing the group failed"
msgstr "" msgstr ""
msgid "BulkImport|Last imported to %{link}"
msgstr ""
msgid "BulkImport|Name already exists." msgid "BulkImport|Name already exists."
msgstr "" msgstr ""
...@@ -27568,6 +27574,9 @@ msgstr "" ...@@ -27568,6 +27574,9 @@ msgstr ""
msgid "Re-authentication required" msgid "Re-authentication required"
msgstr "" msgstr ""
msgid "Re-import"
msgstr ""
msgid "Re-request review" msgid "Re-request review"
msgstr "" msgstr ""
......
...@@ -259,6 +259,10 @@ describe('Bulk import resolvers', () => { ...@@ -259,6 +259,10 @@ describe('Bulk import resolvers', () => {
target_namespace: 'root', target_namespace: 'root',
new_name: 'group1', new_name: 'group1',
}, },
last_import_target: {
target_namespace: 'root',
new_name: 'group1',
},
validation_errors: [], validation_errors: [],
}, },
], ],
...@@ -414,18 +418,30 @@ describe('Bulk import resolvers', () => { ...@@ -414,18 +418,30 @@ describe('Bulk import resolvers', () => {
}); });
}); });
it('setImportProgress updates group progress', async () => { it('setImportProgress updates group progress and sets import target', async () => {
const NEW_STATUS = 'dummy'; const NEW_STATUS = 'dummy';
const FAKE_JOB_ID = 5; const FAKE_JOB_ID = 5;
const IMPORT_TARGET = {
__typename: 'ClientBulkImportTarget',
new_name: 'fake_name',
target_namespace: 'fake_target',
};
const { const {
data: { data: {
setImportProgress: { progress }, setImportProgress: { progress, last_import_target: lastImportTarget },
}, },
} = await client.mutate({ } = await client.mutate({
mutation: setImportProgressMutation, mutation: setImportProgressMutation,
variables: { sourceGroupId: GROUP_ID, status: NEW_STATUS, jobId: FAKE_JOB_ID }, variables: {
sourceGroupId: GROUP_ID,
status: NEW_STATUS,
jobId: FAKE_JOB_ID,
importTarget: IMPORT_TARGET,
},
}); });
expect(lastImportTarget).toMatchObject(IMPORT_TARGET);
expect(progress).toMatchObject({ expect(progress).toMatchObject({
id: FAKE_JOB_ID, id: FAKE_JOB_ID,
status: NEW_STATUS, status: NEW_STATUS,
......
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