diff --git a/GITLAB_WORKHORSE_VERSION b/GITLAB_WORKHORSE_VERSION index 680aa63c75f..a1846656fa0 100644 --- a/GITLAB_WORKHORSE_VERSION +++ b/GITLAB_WORKHORSE_VERSION @@ -1 +1 @@ -8.55.0 +8.56.0 diff --git a/Gemfile b/Gemfile index 80d617286d1..293111d1d4b 100644 --- a/Gemfile +++ b/Gemfile @@ -209,7 +209,7 @@ gem 'httparty', '~> 0.16.4' gem 'rainbow', '~> 3.0' # Progress bar -gem 'ruby-progressbar' +gem 'ruby-progressbar', '~> 1.10' # GitLab settings gem 'settingslogic', '~> 2.0.9' diff --git a/Gemfile.lock b/Gemfile.lock index b9fb5d1085e..f16173de975 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1480,7 +1480,7 @@ DEPENDENCIES rspec_profiling (~> 0.0.6) ruby-fogbugz (~> 0.2.1) ruby-prof (~> 1.3.0) - ruby-progressbar + ruby-progressbar (~> 1.10) ruby_parser (~> 3.15) rubyzip (~> 2.0.0) rugged (~> 0.28) diff --git a/app/assets/javascripts/diffs/components/diff_content.vue b/app/assets/javascripts/diffs/components/diff_content.vue index 1454728288e..f938ea368d8 100644 --- a/app/assets/javascripts/diffs/components/diff_content.vue +++ b/app/assets/javascripts/diffs/components/diff_content.vue @@ -169,12 +169,16 @@ export default { :a-mode="diffFile.a_mode" :b-mode="diffFile.b_mode" > - +
- +
diff --git a/app/assets/javascripts/importer_status.js b/app/assets/javascripts/importer_status.js deleted file mode 100644 index 078c50ee9c6..00000000000 --- a/app/assets/javascripts/importer_status.js +++ /dev/null @@ -1,149 +0,0 @@ -import $ from 'jquery'; -import { escape } from 'lodash'; -import { __, sprintf } from './locale'; -import axios from './lib/utils/axios_utils'; -import { deprecatedCreateFlash as flash } from './flash'; -import { parseBoolean, spriteIcon } from './lib/utils/common_utils'; - -class ImporterStatus { - constructor({ jobsUrl, importUrl, ciCdOnly }) { - this.jobsUrl = jobsUrl; - this.importUrl = importUrl; - this.ciCdOnly = ciCdOnly; - this.initStatusPage(); - this.setAutoUpdate(); - } - - initStatusPage() { - $('.js-add-to-import') - .off('click') - .on('click', this.addToImport.bind(this)); - - $('.js-import-all') - .off('click') - .on('click', function onClickImportAll() { - const $btn = $(this); - $btn.disable().addClass('is-loading'); - return $('.js-add-to-import').each(function triggerAddImport() { - return $(this).trigger('click'); - }); - }); - } - - addToImport(event) { - const $btn = $(event.currentTarget); - const $tr = $btn.closest('tr'); - const $targetField = $tr.find('.import-target'); - const $namespaceInput = $targetField.find('.js-select-namespace option:selected'); - const repoData = $tr.data(); - const id = repoData.id || $tr.attr('id').replace('repo_', ''); - - let targetNamespace; - let newName; - if ($namespaceInput.length > 0) { - targetNamespace = $namespaceInput[0].innerHTML; - newName = $targetField.find('#path').prop('value'); - $targetField.empty().append(`${targetNamespace}/${newName}`); - } - $btn.disable().addClass('is-loading'); - - this.id = id; - - let attributes = { - repo_id: id, - target_namespace: targetNamespace, - new_name: newName, - ci_cd_only: this.ciCdOnly, - }; - - if (repoData) { - attributes = Object.assign(repoData, attributes); - } - - return axios - .post(this.importUrl, attributes) - .then(({ data }) => { - const job = $tr; - job.attr('id', `project_${data.id}`); - - job.find('.import-target').html(`${data.full_path}`); - $('table.import-jobs tbody').prepend(job); - - job.addClass('table-active'); - const connectingVerb = this.ciCdOnly ? __('connecting') : __('importing'); - job.find('.import-actions').html( - sprintf( - escape(__('%{loadingIcon} Started')), - { - loadingIcon: ``, - }, - false, - ), - ); - }) - .catch(error => { - let details = error; - - const $statusField = $tr.find('.job-status'); - $statusField.text(__('Failed')); - - if (error.response && error.response.data && error.response.data.errors) { - details = error.response.data.errors; - } - - flash(sprintf(__('An error occurred while importing project: %{details}'), { details })); - }); - } - - autoUpdate() { - return axios.get(this.jobsUrl).then(({ data = [] }) => { - data.forEach(job => { - const jobItem = $(`#project_${job.id}`); - const statusField = jobItem.find('.job-status'); - - const spinner = ''; - - switch (job.import_status) { - case 'finished': - jobItem.removeClass('table-active').addClass('table-success'); - statusField.html(`${spriteIcon('check', 's16')} ${__('Done')}`); - break; - case 'scheduled': - statusField.html(`${spinner} ${__('Scheduled')}`); - break; - case 'started': - statusField.html(`${spinner} ${__('Started')}`); - break; - case 'failed': - statusField.html(__('Failed')); - break; - default: - statusField.html(job.import_status); - break; - } - }); - }); - } - - setAutoUpdate() { - setInterval(this.autoUpdate.bind(this), 4000); - } -} - -// eslint-disable-next-line consistent-return -function initImporterStatus() { - const importerStatus = document.querySelector('.js-importer-status'); - - if (importerStatus) { - const data = importerStatus.dataset; - return new ImporterStatus({ - jobsUrl: data.jobsImportPath, - importUrl: data.importPath, - ciCdOnly: parseBoolean(data.ciCdOnly), - }); - } -} - -export { initImporterStatus as default, ImporterStatus }; diff --git a/app/assets/javascripts/main.js b/app/assets/javascripts/main.js index b404f390a2d..abf25ab5f24 100644 --- a/app/assets/javascripts/main.js +++ b/app/assets/javascripts/main.js @@ -23,7 +23,6 @@ import { getLocationHash, visitUrl } from './lib/utils/url_utility'; // everything else import { deprecatedCreateFlash as Flash, removeFlashClickListener } from './flash'; import initTodoToggle from './header'; -import initImporterStatus from './importer_status'; import initLayoutNav from './layout_nav'; import initAlertHandler from './alert_handler'; import './feature_highlight/feature_highlight_options'; @@ -107,7 +106,6 @@ function deferredInitialisation() { const $body = $('body'); initBreadcrumbs(); - initImporterStatus(); initTodoToggle(); initLogoAnimation(); initUsagePingConsent(); diff --git a/app/assets/javascripts/notes/components/diff_with_note.vue b/app/assets/javascripts/notes/components/diff_with_note.vue index 91cf682943e..98e3ae5179c 100644 --- a/app/assets/javascripts/notes/components/diff_with_note.vue +++ b/app/assets/javascripts/notes/components/diff_with_note.vue @@ -131,14 +131,18 @@ export default { :file-hash="discussion.diff_file.file_hash" :project-path="projectPath" > - + diff --git a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_missing_branch.vue b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_missing_branch.vue index 6489569cf68..8511797286d 100644 --- a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_missing_branch.vue +++ b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_missing_branch.vue @@ -2,6 +2,9 @@ import { GlIcon, GlTooltipDirective } from '@gitlab/ui'; import { sprintf, s__ } from '~/locale'; import statusIcon from '../mr_widget_status_icon.vue'; +import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin'; +import mergeRequestQueryVariablesMixin from '../../mixins/merge_request_query_variables'; +import missingBranchQuery from '../../queries/states/missing_branch.query.graphql'; export default { name: 'MRWidgetMissingBranch', @@ -12,15 +15,38 @@ export default { GlIcon, statusIcon, }, + mixins: [glFeatureFlagMixin(), mergeRequestQueryVariablesMixin], + apollo: { + state: { + query: missingBranchQuery, + skip() { + return !this.glFeatures.mergeRequestWidgetGraphql; + }, + variables() { + return this.mergeRequestQueryVariables; + }, + update: data => data.project.mergeRequest, + }, + }, props: { mr: { type: Object, required: true, }, }, + data() { + return { state: {} }; + }, computed: { + sourceBranchRemoved() { + if (this.glFeatures.mergeRequestWidgetGraphql) { + return !this.state.sourceBranchExists; + } + + return this.mr.sourceBranchRemoved; + }, missingBranchName() { - return this.mr.sourceBranchRemoved ? 'source' : 'target'; + return this.sourceBranchRemoved ? 'source' : 'target'; }, missingBranchNameMessage() { return sprintf( @@ -49,7 +75,7 @@ export default {
- {{ missingBranchName }} + {{ missingBranchName }} {{ s__('mrWidget|branch does not exist.') }} {{ missingBranchNameMessage }} diff --git a/app/assets/javascripts/vue_merge_request_widget/queries/states/missing_branch.query.graphql b/app/assets/javascripts/vue_merge_request_widget/queries/states/missing_branch.query.graphql new file mode 100644 index 00000000000..ea95218aec6 --- /dev/null +++ b/app/assets/javascripts/vue_merge_request_widget/queries/states/missing_branch.query.graphql @@ -0,0 +1,7 @@ +query missingBranchQuery($projectPath: ID!, $iid: String!) { + project(fullPath: $projectPath) { + mergeRequest(iid: $iid) { + sourceBranchExists + } + } +} diff --git a/app/assets/javascripts/vue_shared/components/content_viewer/viewers/image_viewer.vue b/app/assets/javascripts/vue_shared/components/content_viewer/viewers/image_viewer.vue index 55526dcc381..eb7e24734ce 100644 --- a/app/assets/javascripts/vue_shared/components/content_viewer/viewers/image_viewer.vue +++ b/app/assets/javascripts/vue_shared/components/content_viewer/viewers/image_viewer.vue @@ -28,6 +28,8 @@ export default { return { width: 0, height: 0, + renderedWidth: 0, + renderedHeight: 0, }; }, computed: { @@ -63,11 +65,14 @@ export default { this.height = contentImg.naturalHeight; this.$nextTick(() => { + this.renderedWidth = contentImg.clientWidth; + this.renderedHeight = contentImg.clientHeight; + this.$emit('imgLoaded', { width: this.width, height: this.height, - renderedWidth: contentImg.clientWidth, - renderedHeight: contentImg.clientHeight, + renderedWidth: this.renderedWidth, + renderedHeight: this.renderedHeight, }); }); } @@ -79,7 +84,12 @@ export default {