diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2021-12-14 15:13:33 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2021-12-14 15:13:33 +0300 |
commit | 79a7da2537e94c34aba92ad4b9a5dc1da431b2c4 (patch) | |
tree | 83b6a53a15a9266ca2e2aca061dd3f33d5282b1f /app/assets/javascripts/import_entities | |
parent | a58667ab4b4fc4b0d1e47e95d91c27ccadd0acd3 (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app/assets/javascripts/import_entities')
7 files changed, 91 insertions, 66 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 298771a4d12..f2837a7bb44 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 @@ -314,9 +314,8 @@ export default { variables: { importRequests }, }); } catch (error) { - const message = error?.networkError?.response?.data?.error ?? i18n.ERROR_IMPORT; createFlash({ - message, + message: i18n.ERROR_IMPORT, captureError: true, error, }); diff --git a/app/assets/javascripts/import_entities/import_groups/components/import_target_cell.vue b/app/assets/javascripts/import_entities/import_groups/components/import_target_cell.vue index ca9ae9447d0..344a6e45370 100644 --- a/app/assets/javascripts/import_entities/import_groups/components/import_target_cell.vue +++ b/app/assets/javascripts/import_entities/import_groups/components/import_target_cell.vue @@ -32,72 +32,84 @@ export default { fullPath() { return this.group.importTarget.targetNamespace.fullPath || s__('BulkImport|No parent'); }, - invalidNameValidationMessage() { - return getInvalidNameValidationMessage(this.group.importTarget); + validationMessage() { + return ( + this.group.progress?.message || getInvalidNameValidationMessage(this.group.importTarget) + ); + }, + validNameState() { + // bootstrap-vue requires null for "indifferent" state, if we return true + // this will highlight field in green like "passed validation" + return this.group.flags.isInvalid && this.group.flags.isAvailableForImport ? false : null; }, }, }; </script> <template> - <div class="gl-display-flex gl-align-items-stretch"> - <import-group-dropdown - #default="{ namespaces }" - :text="fullPath" - :disabled="!group.flags.isAvailableForImport" - :namespaces="availableNamespaces" - toggle-class="gl-rounded-top-right-none! gl-rounded-bottom-right-none!" - class="gl-h-7 gl-flex-grow-1" - data-qa-selector="target_namespace_selector_dropdown" - > - <gl-dropdown-item @click="$emit('update-target-namespace', { fullPath: '', id: null })">{{ - s__('BulkImport|No parent') - }}</gl-dropdown-item> - <template v-if="namespaces.length"> - <gl-dropdown-divider /> - <gl-dropdown-section-header> - {{ s__('BulkImport|Existing groups') }} - </gl-dropdown-section-header> - <gl-dropdown-item - v-for="ns in namespaces" - :key="ns.fullPath" - data-qa-selector="target_group_dropdown_item" - :data-qa-group-name="ns.fullPath" - @click="$emit('update-target-namespace', ns)" - > - {{ ns.fullPath }} - </gl-dropdown-item> - </template> - </import-group-dropdown> - <div - class="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 gl-bg-gray-10" - :class="{ - 'gl-text-gray-400 gl-border-gray-100': !group.flags.isAvailableForImport, - 'gl-border-gray-200': group.flags.isAvailableForImport, - }" - > - / - </div> - <div class="gl-flex-grow-1"> - <gl-form-input - class="gl-rounded-top-left-none gl-rounded-bottom-left-none" + <div> + <div class="gl-display-flex gl-align-items-stretch"> + <import-group-dropdown + #default="{ namespaces }" + :text="fullPath" + :disabled="!group.flags.isAvailableForImport" + :namespaces="availableNamespaces" + toggle-class="gl-rounded-top-right-none! gl-rounded-bottom-right-none!" + class="gl-h-7 gl-flex-grow-1" + data-qa-selector="target_namespace_selector_dropdown" + > + <gl-dropdown-item @click="$emit('update-target-namespace', { fullPath: '', id: null })">{{ + s__('BulkImport|No parent') + }}</gl-dropdown-item> + <template v-if="namespaces.length"> + <gl-dropdown-divider /> + <gl-dropdown-section-header> + {{ s__('BulkImport|Existing groups') }} + </gl-dropdown-section-header> + <gl-dropdown-item + v-for="ns in namespaces" + :key="ns.fullPath" + data-qa-selector="target_group_dropdown_item" + :data-qa-group-name="ns.fullPath" + @click="$emit('update-target-namespace', ns)" + > + {{ ns.fullPath }} + </gl-dropdown-item> + </template> + </import-group-dropdown> + <div + class="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 gl-bg-gray-10" :class="{ - 'gl-inset-border-1-gray-200!': group.flags.isAvailableForImport, - 'gl-inset-border-1-gray-100!': !group.flags.isAvailableForImport, - 'is-invalid': group.flags.isInvalid && group.flags.isAvailableForImport, + 'gl-text-gray-400 gl-border-gray-100': !group.flags.isAvailableForImport, + 'gl-border-gray-200': group.flags.isAvailableForImport, }" - debounce="500" - :disabled="!group.flags.isAvailableForImport" - :value="group.importTarget.newName" - :aria-label="__('New name')" - @input="$emit('update-new-name', $event)" - /> - <p - v-if="group.flags.isAvailableForImport && group.flags.isInvalid" - class="gl-text-red-500 gl-m-0 gl-mt-2" > - {{ invalidNameValidationMessage }} - </p> + / + </div> + <div class="gl-flex-grow-1"> + <gl-form-input + class="gl-rounded-top-left-none gl-rounded-bottom-left-none" + :class="{ + 'gl-inset-border-1-gray-200!': + group.flags.isAvailableForImport && !group.flags.isInvalid, + 'gl-inset-border-1-gray-100!': + !group.flags.isAvailableForImport && !group.flags.isInvalid, + }" + debounce="500" + :disabled="!group.flags.isAvailableForImport" + :value="group.importTarget.newName" + :aria-label="__('New name')" + :state="validNameState" + @input="$emit('update-new-name', $event)" + /> + </div> + </div> + <div + v-if="group.flags.isAvailableForImport && (group.flags.isInvalid || validationMessage)" + class="gl-text-red-500 gl-m-0 gl-mt-2" + role="alert" + > + {{ validationMessage }} </div> </div> </template> 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 bce6e7bcb1f..31352bbc8bb 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 @@ -142,9 +142,7 @@ export function createResolvers({ endpoints }) { }; }); - const { - data: { id: jobId }, - } = await axios.post(endpoints.createBulkImport, { + const { data: originalResponse } = await axios.post(endpoints.createBulkImport, { bulk_import: importOperations.map((op) => ({ source_type: 'group_entity', source_full_path: op.group.fullPath, @@ -153,15 +151,21 @@ export function createResolvers({ endpoints }) { })), }); - return importOperations.map((op) => { + 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: jobId, - status: STATUSES.CREATED, + 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 }); 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 index 2d60bf82d65..33c564f36a8 100644 --- 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 @@ -1,4 +1,5 @@ fragment BulkImportSourceGroupProgress on ClientBulkImportProgress { id status + message } diff --git a/app/assets/javascripts/import_entities/import_groups/graphql/mutations/import_groups.mutation.graphql b/app/assets/javascripts/import_entities/import_groups/graphql/mutations/import_groups.mutation.graphql index 75215471d0f..39289887b75 100644 --- a/app/assets/javascripts/import_entities/import_groups/graphql/mutations/import_groups.mutation.graphql +++ b/app/assets/javascripts/import_entities/import_groups/graphql/mutations/import_groups.mutation.graphql @@ -9,6 +9,7 @@ mutation importGroups($importRequests: [ImportGroupInput!]!) { progress { id status + message } } } diff --git a/app/assets/javascripts/import_entities/import_groups/graphql/services/local_storage_cache.js b/app/assets/javascripts/import_entities/import_groups/graphql/services/local_storage_cache.js index 09bc7b33692..1aad22f0f3f 100644 --- a/app/assets/javascripts/import_entities/import_groups/graphql/services/local_storage_cache.js +++ b/app/assets/javascripts/import_entities/import_groups/graphql/services/local_storage_cache.js @@ -22,7 +22,14 @@ export class LocalStorageCache { loadCacheFromStorage() { try { - return JSON.parse(this.storage.getItem(KEY)) ?? {}; + const storage = JSON.parse(this.storage.getItem(KEY)) ?? {}; + Object.values(storage).forEach((entry) => { + if (entry.progress && !('message' in entry.progress)) { + // eslint-disable-next-line no-param-reassign + entry.progress.message = ''; + } + }); + return storage; } catch { return {}; } diff --git a/app/assets/javascripts/import_entities/import_groups/graphql/typedefs.graphql b/app/assets/javascripts/import_entities/import_groups/graphql/typedefs.graphql index b8dd79a5000..1639ce16758 100644 --- a/app/assets/javascripts/import_entities/import_groups/graphql/typedefs.graphql +++ b/app/assets/javascripts/import_entities/import_groups/graphql/typedefs.graphql @@ -16,6 +16,7 @@ type ClientBulkImportSourceGroupConnection { type ClientBulkImportProgress { id: ID! status: String! + message: String } type ClientBulkImportValidationError { |