debian-mirror-gitlab/app/assets/javascripts/import_entities/import_groups/graphql/client_factory.js
2022-01-26 12:08:38 +05:30

196 lines
6.3 KiB
JavaScript

import createDefaultClient from '~/lib/graphql';
import axios from '~/lib/utils/axios_utils';
import { parseIntPagination, normalizeHeaders } from '~/lib/utils/common_utils';
import { STATUSES } from '../../constants';
import bulkImportSourceGroupItemFragment from './fragments/bulk_import_source_group_item.fragment.graphql';
import bulkImportSourceGroupProgressFragment from './fragments/bulk_import_source_group_progress.fragment.graphql';
import { LocalStorageCache } from './services/local_storage_cache';
import typeDefs from './typedefs.graphql';
export const clientTypenames = {
BulkImportSourceGroupConnection: 'ClientBulkImportSourceGroupConnection',
BulkImportSourceGroup: 'ClientBulkImportSourceGroup',
AvailableNamespace: 'ClientAvailableNamespace',
BulkImportPageInfo: 'ClientBulkImportPageInfo',
BulkImportTarget: 'ClientBulkImportTarget',
BulkImportProgress: 'ClientBulkImportProgress',
BulkImportVersionValidation: 'ClientBulkImportVersionValidation',
BulkImportVersionValidationFeature: 'ClientBulkImportVersionValidationFeature',
BulkImportVersionValidationFeatures: 'ClientBulkImportVersionValidationFeatures',
};
function makeLastImportTarget(data) {
return {
__typename: clientTypenames.BulkImportTarget,
...data,
};
}
function makeProgress(data) {
return {
__typename: clientTypenames.BulkImportProgress,
...data,
};
}
function makeGroup(data) {
return {
__typename: clientTypenames.BulkImportSourceGroup,
...data,
progress: data.progress
? makeProgress({
id: `LOCAL-PROGRESS-${data.id}`,
...data.progress,
})
: null,
lastImportTarget: data.lastImportTarget
? makeLastImportTarget({
id: data.id,
...data.lastImportTarget,
})
: null,
};
}
function getGroupFromCache({ client, id, getCacheKey }) {
return client.readFragment({
fragment: bulkImportSourceGroupItemFragment,
fragmentName: 'BulkImportSourceGroupItem',
id: getCacheKey({
__typename: clientTypenames.BulkImportSourceGroup,
id,
}),
});
}
export function createResolvers({ endpoints }) {
const localStorageCache = new LocalStorageCache();
return {
Query: {
async bulkImportSourceGroups(_, vars) {
const { headers, data } = await axios.get(endpoints.status, {
params: {
page: vars.page,
per_page: vars.perPage,
filter: vars.filter,
},
});
const pagination = parseIntPagination(normalizeHeaders(headers));
const response = {
__typename: clientTypenames.BulkImportSourceGroupConnection,
nodes: data.importable_data.map((group) => {
return makeGroup({
id: group.id,
webUrl: group.web_url,
fullPath: group.full_path,
fullName: group.full_name,
...group,
...localStorageCache.get(group.web_url),
});
}),
pageInfo: {
__typename: clientTypenames.BulkImportPageInfo,
...pagination,
},
versionValidation: {
__typename: clientTypenames.BulkImportVersionValidation,
features: {
__typename: clientTypenames.BulkImportVersionValidationFeatures,
sourceInstanceVersion: data.version_validation.features.source_instance_version,
projectMigration: {
__typename: clientTypenames.BulkImportVersionValidationFeature,
available: data.version_validation.features.project_migration.available,
minVersion: data.version_validation.features.project_migration.min_version,
},
},
},
};
return response;
},
availableNamespaces: () =>
axios.get(endpoints.availableNamespaces).then(({ data }) =>
data.map((namespace) => ({
__typename: clientTypenames.AvailableNamespace,
id: namespace.id,
fullPath: namespace.full_path,
})),
),
},
Mutation: {
async updateImportStatus(_, { id, status: newStatus }, { client, getCacheKey }) {
const progressItem = client.readFragment({
fragment: bulkImportSourceGroupProgressFragment,
fragmentName: 'BulkImportSourceGroupProgress',
id: getCacheKey({
__typename: clientTypenames.BulkImportProgress,
id,
}),
});
if (!progressItem) return null;
localStorageCache.updateStatusByJobId(id, newStatus);
return {
__typename: clientTypenames.BulkImportProgress,
...progressItem,
id,
status: newStatus,
};
},
async importGroups(_, { importRequests }, { client, getCacheKey }) {
const importOperations = importRequests.map((importRequest) => {
const group = getGroupFromCache({
client,
getCacheKey,
id: importRequest.sourceGroupId,
});
return {
group,
...importRequest,
};
});
const { data: originalResponse } = await axios.post(endpoints.createBulkImport, {
bulk_import: importOperations.map((op) => ({
source_type: 'group_entity',
source_full_path: op.group.fullPath,
destination_namespace: op.targetNamespace,
destination_name: op.newName,
})),
});
const responses = Array.isArray(originalResponse)
? originalResponse
: [{ success: true, id: originalResponse.id }];
return importOperations.map((op, idx) => {
const response = responses[idx];
const lastImportTarget = {
targetNamespace: op.targetNamespace,
newName: op.newName,
};
const progress = {
id: response.id || `local-${Date.now()}-${idx}`,
status: response.success ? STATUSES.CREATED : STATUSES.FAILED,
message: response.message || null,
};
localStorageCache.set(op.group.webUrl, { progress, lastImportTarget });
return makeGroup({ ...op.group, progress, lastImportTarget });
});
},
},
};
}
export const createApolloClient = ({ sourceUrl, endpoints }) =>
createDefaultClient(createResolvers({ sourceUrl, endpoints }), { typeDefs });