diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2022-01-11 18:16:38 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2022-01-11 18:16:38 +0000 |
commit | b330f7f0bfb2035b03e84e5fa751816b6ad9b841 (patch) | |
tree | 5dd72fddc7545c3fb6c5bff6b662bea3dea54d79 /app | |
parent | a8281ac43424e4b820286823bdb48f068b21d7d3 (diff) | |
download | gitlab-ce-b330f7f0bfb2035b03e84e5fa751816b6ad9b841.tar.gz |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app')
28 files changed, 192 insertions, 88 deletions
diff --git a/app/assets/javascripts/behaviors/copy_code.js b/app/assets/javascripts/behaviors/copy_code.js index e4dfdeba209..a8863a18068 100644 --- a/app/assets/javascripts/behaviors/copy_code.js +++ b/app/assets/javascripts/behaviors/copy_code.js @@ -29,7 +29,7 @@ class CopyCodeButton extends HTMLElement { } function addCodeButton() { - [...document.querySelectorAll('pre.code.js-syntax-highlight')] + [...document.querySelectorAll('pre.code.js-syntax-highlight:not(.content-editor-code-block)')] .filter((el) => el.attr('lang') !== 'mermaid') .filter((el) => !el.closest('.js-markdown-code')) .forEach((el) => { diff --git a/app/assets/javascripts/clusters_list/constants.js b/app/assets/javascripts/clusters_list/constants.js index b5729fe4d2d..380a5d0aada 100644 --- a/app/assets/javascripts/clusters_list/constants.js +++ b/app/assets/javascripts/clusters_list/constants.js @@ -106,7 +106,7 @@ export const I18N_AGENT_MODAL = { empty_state: { modalTitle: s__('ClusterAgents|Connect your cluster through the Agent'), modalBody: s__( - "ClusterAgents|To install a new agent, first add the agent's configuration file to this repository. %{linkStart}What's the agent's configuration file?%{linkEnd}", + "ClusterAgents|To install a new agent, first add the agent's configuration file to this repository. %{linkStart}Learn more about installing GitLab Agent.%{linkEnd}", ), enableKasText: s__( "ClusterAgents|Your instance doesn't have the %{linkStart}GitLab Agent Server (KAS)%{linkEnd} set up. Ask a GitLab Administrator to install it.", diff --git a/app/assets/javascripts/content_editor/components/wrappers/frontmatter.vue b/app/assets/javascripts/content_editor/components/wrappers/frontmatter.vue index 97b69afd12e..e8829d00986 100644 --- a/app/assets/javascripts/content_editor/components/wrappers/frontmatter.vue +++ b/app/assets/javascripts/content_editor/components/wrappers/frontmatter.vue @@ -20,7 +20,7 @@ export default { }; </script> <template> - <node-view-wrapper class="gl-relative code highlight" as="pre"> + <node-view-wrapper class="content-editor-code-block gl-relative code highlight" as="pre"> <span data-testid="frontmatter-label" class="gl-absolute gl-top-0 gl-right-3" diff --git a/app/assets/javascripts/content_editor/extensions/code_block_highlight.js b/app/assets/javascripts/content_editor/extensions/code_block_highlight.js index ea51bee3ba9..9dc17fcd570 100644 --- a/app/assets/javascripts/content_editor/extensions/code_block_highlight.js +++ b/app/assets/javascripts/content_editor/extensions/code_block_highlight.js @@ -19,7 +19,14 @@ export default CodeBlockLowlight.extend({ }; }, renderHTML({ HTMLAttributes }) { - return ['div', ['pre', HTMLAttributes, ['code', {}, 0]]]; + return [ + 'pre', + { + ...HTMLAttributes, + class: `content-editor-code-block ${HTMLAttributes.class}`, + }, + ['code', {}, 0], + ]; }, }).configure({ lowlight, diff --git a/app/assets/javascripts/packages_and_registries/package_registry/components/details/app.vue b/app/assets/javascripts/packages_and_registries/package_registry/components/details/app.vue index 7dd090a7b47..52fea4bebbe 100644 --- a/app/assets/javascripts/packages_and_registries/package_registry/components/details/app.vue +++ b/app/assets/javascripts/packages_and_registries/package_registry/components/details/app.vue @@ -68,15 +68,7 @@ export default { GlModal: GlModalDirective, }, mixins: [Tracking.mixin()], - inject: [ - 'packageId', - 'projectName', - 'canDelete', - 'svgPath', - 'npmPath', - 'projectListUrl', - 'groupListUrl', - ], + inject: ['packageId', 'svgPath', 'projectListUrl', 'groupListUrl'], trackingActions: { DELETE_PACKAGE_TRACKING_ACTION, REQUEST_DELETE_PACKAGE_TRACKING_ACTION, @@ -99,7 +91,7 @@ export default { return this.queryVariables; }, update(data) { - return data.package; + return data.package || {}; }, error(error) { createFlash({ @@ -111,19 +103,22 @@ export default { }, }, computed: { + projectName() { + return this.packageEntity.project?.name; + }, queryVariables() { return { id: convertToGraphQLId('Packages::Package', this.packageId), }; }, packageFiles() { - return this.packageEntity?.packageFiles?.nodes; + return this.packageEntity.packageFiles?.nodes; }, isLoading() { return this.$apollo.queries.packageEntity.loading; }, isValidPackage() { - return this.isLoading || Boolean(this.packageEntity?.name); + return this.isLoading || Boolean(this.packageEntity.name); }, tracking() { return { @@ -140,7 +135,7 @@ export default { return this.packageEntity.packageType === PACKAGE_TYPE_NUGET; }, showFiles() { - return this.packageEntity?.packageType !== PACKAGE_TYPE_COMPOSER; + return this.packageEntity.packageType !== PACKAGE_TYPE_COMPOSER; }, }, methods: { @@ -240,7 +235,7 @@ export default { <package-title :package-entity="packageEntity"> <template #delete-button> <gl-button - v-if="canDelete" + v-if="packageEntity.canDestroy" v-gl-modal="'delete-modal'" variant="danger" category="primary" @@ -264,6 +259,7 @@ export default { <package-files v-if="showFiles" + :can-delete="packageEntity.canDestroy" :package-files="packageFiles" @download-file="track($options.trackingActions.PULL_PACKAGE)" @delete-file="handleFileDelete" diff --git a/app/assets/javascripts/packages_and_registries/package_registry/components/details/composer_installation.vue b/app/assets/javascripts/packages_and_registries/package_registry/components/details/composer_installation.vue index 4ef37a3cbbe..a482c29bf50 100644 --- a/app/assets/javascripts/packages_and_registries/package_registry/components/details/composer_installation.vue +++ b/app/assets/javascripts/packages_and_registries/package_registry/components/details/composer_installation.vue @@ -18,7 +18,7 @@ export default { GlLink, GlSprintf, }, - inject: ['composerConfigRepositoryName', 'composerPath', 'groupListUrl'], + inject: ['groupListUrl'], props: { packageEntity: { type: Object, @@ -28,7 +28,7 @@ export default { computed: { composerRegistryInclude() { // eslint-disable-next-line @gitlab/require-i18n-strings - return `composer config repositories.${this.composerConfigRepositoryName} '{"type": "composer", "url": "${this.composerPath}"}'`; + return `composer config repositories.${this.packageEntity.composerConfigRepositoryUrl} '{"type": "composer", "url": "${this.packageEntity.composerUrl}"}'`; }, composerPackageInclude() { // eslint-disable-next-line @gitlab/require-i18n-strings diff --git a/app/assets/javascripts/packages_and_registries/package_registry/components/details/conan_installation.vue b/app/assets/javascripts/packages_and_registries/package_registry/components/details/conan_installation.vue index 72e6a26e15f..ba0a3fcf5a1 100644 --- a/app/assets/javascripts/packages_and_registries/package_registry/components/details/conan_installation.vue +++ b/app/assets/javascripts/packages_and_registries/package_registry/components/details/conan_installation.vue @@ -18,7 +18,6 @@ export default { GlLink, GlSprintf, }, - inject: ['conanPath'], props: { packageEntity: { type: Object, @@ -32,7 +31,7 @@ export default { }, conanSetupCommand() { // eslint-disable-next-line @gitlab/require-i18n-strings - return `conan remote add gitlab ${this.conanPath}`; + return `conan remote add gitlab ${this.packageEntity.conanUrl}`; }, }, i18n: { diff --git a/app/assets/javascripts/packages_and_registries/package_registry/components/details/maven_installation.vue b/app/assets/javascripts/packages_and_registries/package_registry/components/details/maven_installation.vue index 9757838ccfb..4510c7a7322 100644 --- a/app/assets/javascripts/packages_and_registries/package_registry/components/details/maven_installation.vue +++ b/app/assets/javascripts/packages_and_registries/package_registry/components/details/maven_installation.vue @@ -24,7 +24,6 @@ export default { GlLink, GlSprintf, }, - inject: ['mavenPath'], props: { packageEntity: { type: Object, @@ -37,6 +36,9 @@ export default { }; }, computed: { + mavenUrl() { + return this.packageEntity.mavenUrl; + }, appGroup() { return this.packageEntity.metadata.appGroup; }, @@ -62,19 +64,19 @@ export default { return `<repositories> <repository> <id>gitlab-maven</id> - <url>${this.mavenPath}</url> + <url>${this.mavenUrl}</url> </repository> </repositories> <distributionManagement> <repository> <id>gitlab-maven</id> - <url>${this.mavenPath}</url> + <url>${this.mavenUrl}</url> </repository> <snapshotRepository> <id>gitlab-maven</id> - <url>${this.mavenPath}</url> + <url>${this.mavenUrl}</url> </snapshotRepository> </distributionManagement>`; }, @@ -87,7 +89,7 @@ export default { gradleGroovyAddSourceCommand() { // eslint-disable-next-line @gitlab/require-i18n-strings return `maven { - url '${this.mavenPath}' + url '${this.mavenUrl}' }`; }, @@ -96,7 +98,7 @@ export default { }, gradleKotlinAddSourceCommand() { - return `maven("${this.mavenPath}")`; + return `maven("${this.mavenUrl}")`; }, showMaven() { return this.instructionType === 'maven'; diff --git a/app/assets/javascripts/packages_and_registries/package_registry/components/details/npm_installation.vue b/app/assets/javascripts/packages_and_registries/package_registry/components/details/npm_installation.vue index 7af9a2ade56..95b09b25678 100644 --- a/app/assets/javascripts/packages_and_registries/package_registry/components/details/npm_installation.vue +++ b/app/assets/javascripts/packages_and_registries/package_registry/components/details/npm_installation.vue @@ -26,7 +26,7 @@ export default { GlSprintf, GlFormRadioGroup, }, - inject: ['npmPath', 'npmProjectPath'], + inject: ['npmPath'], props: { packageEntity: { type: Object, @@ -66,7 +66,7 @@ export default { npmSetupCommand(type, endpointType) { const scope = this.packageEntity.name.substring(0, this.packageEntity.name.indexOf('/')); const npmPathForEndpoint = - endpointType === INSTANCE_PACKAGE_ENDPOINT_TYPE ? this.npmPath : this.npmProjectPath; + endpointType === INSTANCE_PACKAGE_ENDPOINT_TYPE ? this.npmPath : this.packageEntity.npmUrl; if (type === NPM_PACKAGE_MANAGER) { return `echo ${scope}:registry=${npmPathForEndpoint}/ >> .npmrc`; diff --git a/app/assets/javascripts/packages_and_registries/package_registry/components/details/nuget_installation.vue b/app/assets/javascripts/packages_and_registries/package_registry/components/details/nuget_installation.vue index ca48da70bb4..b2007df142c 100644 --- a/app/assets/javascripts/packages_and_registries/package_registry/components/details/nuget_installation.vue +++ b/app/assets/javascripts/packages_and_registries/package_registry/components/details/nuget_installation.vue @@ -18,7 +18,6 @@ export default { GlLink, GlSprintf, }, - inject: ['nugetPath'], props: { packageEntity: { type: Object, @@ -30,7 +29,7 @@ export default { return `nuget install ${this.packageEntity.name} -Source "GitLab"`; }, nugetSetupCommand() { - return `nuget source Add -Name "GitLab" -Source "${this.nugetPath}" -UserName <your_username> -Password <your_token>`; + return `nuget source Add -Name "GitLab" -Source "${this.packageEntity.nugetUrl}" -UserName <your_username> -Password <your_token>`; }, }, tracking: { diff --git a/app/assets/javascripts/packages_and_registries/package_registry/components/details/package_files.vue b/app/assets/javascripts/packages_and_registries/package_registry/components/details/package_files.vue index bf7fe6fb91b..3724e371e01 100644 --- a/app/assets/javascripts/packages_and_registries/package_registry/components/details/package_files.vue +++ b/app/assets/javascripts/packages_and_registries/package_registry/components/details/package_files.vue @@ -22,8 +22,12 @@ export default { FileSha, }, mixins: [Tracking.mixin()], - inject: ['canDelete'], props: { + canDelete: { + type: Boolean, + required: false, + default: false, + }, packageFiles: { type: Array, required: false, diff --git a/app/assets/javascripts/packages_and_registries/package_registry/components/details/pypi_installation.vue b/app/assets/javascripts/packages_and_registries/package_registry/components/details/pypi_installation.vue index 1c4ef21a2cf..a126d30f1ec 100644 --- a/app/assets/javascripts/packages_and_registries/package_registry/components/details/pypi_installation.vue +++ b/app/assets/javascripts/packages_and_registries/package_registry/components/details/pypi_installation.vue @@ -19,7 +19,6 @@ export default { GlLink, GlSprintf, }, - inject: ['pypiPath', 'pypiSetupPath'], props: { packageEntity: { type: Object, @@ -29,11 +28,11 @@ export default { computed: { pypiPipCommand() { // eslint-disable-next-line @gitlab/require-i18n-strings - return `pip install ${this.packageEntity.name} --extra-index-url ${this.pypiPath}`; + return `pip install ${this.packageEntity.name} --extra-index-url ${this.packageEntity.pypiUrl}`; }, pypiSetupCommand() { return `[gitlab] -repository = ${this.pypiSetupPath} +repository = ${this.packageEntity.pypiSetupUrl} username = __token__ password = <your personal access token>`; }, diff --git a/app/assets/javascripts/packages_and_registries/package_registry/graphql/queries/get_package_details.query.graphql b/app/assets/javascripts/packages_and_registries/package_registry/graphql/queries/get_package_details.query.graphql index 08ea0938a59..c45cbe56e00 100644 --- a/app/assets/javascripts/packages_and_registries/package_registry/graphql/queries/get_package_details.query.graphql +++ b/app/assets/javascripts/packages_and_registries/package_registry/graphql/queries/get_package_details.query.graphql @@ -7,9 +7,19 @@ query getPackageDetails($id: ID!) { createdAt updatedAt status + canDestroy + npmUrl + mavenUrl + conanUrl + nugetUrl + pypiUrl + pypiSetupUrl + composerUrl + composerConfigRepositoryUrl project { id path + name } tags(first: 10) { nodes { diff --git a/app/assets/javascripts/vue_merge_request_widget/components/extensions/base.vue b/app/assets/javascripts/vue_merge_request_widget/components/extensions/base.vue index 549cf64fb08..7322958e6df 100644 --- a/app/assets/javascripts/vue_merge_request_widget/components/extensions/base.vue +++ b/app/assets/javascripts/vue_merge_request_widget/components/extensions/base.vue @@ -13,6 +13,7 @@ import * as Sentry from '@sentry/browser'; import api from '~/api'; import { sprintf, s__, __ } from '~/locale'; import SmartVirtualList from '~/vue_shared/components/smart_virtual_list.vue'; +import Poll from '~/lib/utils/poll'; import { EXTENSION_ICON_CLASS, EXTENSION_ICONS } from '../../constants'; import StatusIcon from './status_icon.vue'; import Actions from './actions.vue'; @@ -132,19 +133,50 @@ export default { this.triggerRedisTracking(); }, + initExtensionPolling() { + const poll = new Poll({ + resource: { + fetchData: () => this.fetchCollapsedData(this.$props), + }, + method: 'fetchData', + successCallback: (data) => { + if (Object.keys(data).length > 0) { + poll.stop(); + this.setCollapsedData(data); + } + }, + errorCallback: (e) => { + poll.stop(); + + this.setCollapsedError(e); + }, + }); + + poll.makeRequest(); + }, loadCollapsedData() { this.loadingState = LOADING_STATES.collapsedLoading; - this.fetchCollapsedData(this.$props) - .then((data) => { - this.collapsedData = data; - this.loadingState = null; - }) - .catch((e) => { - this.loadingState = LOADING_STATES.collapsedError; + if (this.$options.enablePolling) { + this.initExtensionPolling(); + } else { + this.fetchCollapsedData(this.$props) + .then((data) => { + this.setCollapsedData(data); + }) + .catch((e) => { + this.setCollapsedError(e); + }); + } + }, + setCollapsedData(data) { + this.collapsedData = data; + this.loadingState = null; + }, + setCollapsedError(e) { + this.loadingState = LOADING_STATES.collapsedError; - Sentry.captureException(e); - }); + Sentry.captureException(e); }, loadAllData() { if (this.hasFullData) return; diff --git a/app/assets/javascripts/vue_merge_request_widget/components/extensions/index.js b/app/assets/javascripts/vue_merge_request_widget/components/extensions/index.js index ec6e6ed2620..8438f3492b2 100644 --- a/app/assets/javascripts/vue_merge_request_widget/components/extensions/index.js +++ b/app/assets/javascripts/vue_merge_request_widget/components/extensions/index.js @@ -13,6 +13,7 @@ export const registerExtension = (extension) => { props: extension.props, i18n: extension.i18n, expandEvent: extension.expandEvent, + enablePolling: extension.enablePolling, computed: { ...Object.keys(extension.computed).reduce( (acc, computedKey) => ({ diff --git a/app/assets/javascripts/vue_merge_request_widget/extensions/terraform/index.js b/app/assets/javascripts/vue_merge_request_widget/extensions/terraform/index.js index d9868101e9d..a564acada02 100644 --- a/app/assets/javascripts/vue_merge_request_widget/extensions/terraform/index.js +++ b/app/assets/javascripts/vue_merge_request_widget/extensions/terraform/index.js @@ -1,10 +1,10 @@ import { __, n__, s__, sprintf } from '~/locale'; import axios from '~/lib/utils/axios_utils'; -import Poll from '~/lib/utils/poll'; import { EXTENSION_ICONS } from '../../constants'; export default { name: 'WidgetTerraform', + enablePolling: true, i18n: { label: s__('Terraform|Terraform reports'), loading: s__('Terraform|Loading Terraform reports...'), @@ -81,34 +81,17 @@ export default { }, // Custom methods fetchPlans() { - return new Promise((resolve) => { - const poll = new Poll({ - resource: { - fetchPlans: () => axios.get(this.terraformReportsPath), - }, - data: this.terraformReportsPath, - method: 'fetchPlans', - successCallback: ({ data }) => { - if (Object.keys(data).length > 0) { - poll.stop(); - - const result = Object.keys(data).map((key) => { - return data[key]; - }); - - resolve(result); - } - }, - errorCallback: () => { - const invalidData = { tf_report_error: 'api_error' }; - poll.stop(); - const result = [invalidData]; - resolve(result); - }, + return axios + .get(this.terraformReportsPath) + .then(({ data }) => { + return Object.keys(data).map((key) => { + return data[key]; + }); + }) + .catch(() => { + const invalidData = { tf_report_error: 'api_error' }; + return [invalidData]; }); - - poll.makeRequest(); - }); }, createReportRow(report, iconName) { const addNum = Number(report.create); diff --git a/app/controllers/projects/merge_requests_controller.rb b/app/controllers/projects/merge_requests_controller.rb index 0b1516f6f45..fb9d1a85656 100644 --- a/app/controllers/projects/merge_requests_controller.rb +++ b/app/controllers/projects/merge_requests_controller.rb @@ -49,10 +49,6 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo push_frontend_feature_flag(:diff_searching_usage_data, @project, default_enabled: :yaml) end - before_action do - push_frontend_feature_flag(:show_relevant_approval_rule_approvers, @project, default_enabled: :yaml) - end - around_action :allow_gitaly_ref_name_caching, only: [:index, :show, :discussions] after_action :log_merge_request_show, only: [:show] diff --git a/app/helpers/notes_helper.rb b/app/helpers/notes_helper.rb index 2dadaa0be0a..1afdb7a0ab9 100644 --- a/app/helpers/notes_helper.rb +++ b/app/helpers/notes_helper.rb @@ -48,7 +48,7 @@ module NotesHelper data[:note_type] = LegacyDiffNote.name else data[:note_type] = DiffNote.name - data[:position] = position.to_json + data[:position] = Gitlab::Json.dump(position) end data diff --git a/app/models/project.rb b/app/models/project.rb index 5c4ffd08304..fa5e84ee83e 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -436,6 +436,7 @@ class Project < ApplicationRecord prefix: :import, to: :import_state, allow_nil: true delegate :squash_always?, :squash_never?, :squash_enabled_by_default?, :squash_readonly?, to: :project_setting delegate :squash_option, :squash_option=, to: :project_setting + delegate :mr_default_target_self, :mr_default_target_self=, to: :project_setting delegate :previous_default_branch, :previous_default_branch=, to: :project_setting delegate :no_import?, to: :import_state, allow_nil: true delegate :name, to: :owner, allow_nil: true, prefix: true diff --git a/app/models/project_setting.rb b/app/models/project_setting.rb index fc834286876..4e37174e604 100644 --- a/app/models/project_setting.rb +++ b/app/models/project_setting.rb @@ -22,6 +22,16 @@ class ProjectSetting < ApplicationRecord def squash_readonly? %w[always never].include?(squash_option) end + + validate :validates_mr_default_target_self + + private + + def validates_mr_default_target_self + if mr_default_target_self_changed? && !project.forked? + errors.add :mr_default_target_self, _('This setting is allowed for forked projects only') + end + end end ProjectSetting.prepend_mod diff --git a/app/services/auth/container_registry_authentication_service.rb b/app/services/auth/container_registry_authentication_service.rb index 1d5acff162e..a92a2c8aef5 100644 --- a/app/services/auth/container_registry_authentication_service.rb +++ b/app/services/auth/container_registry_authentication_service.rb @@ -124,7 +124,8 @@ module Auth type: type, name: path.to_s, actions: authorized_actions, - migration_eligible: self.class.migration_eligible(project: requested_project) + migration_eligible: self.class.migration_eligible(project: requested_project), + cdn_redirect: cdn_redirect }.compact end @@ -150,6 +151,13 @@ module Auth false end + # This is used to determine whether blob download requests using a given JWT token should be redirected to Google + # Cloud CDN or not. The intent is to enable a percentage of time rollout for this new feature on the Container + # Registry side. See https://gitlab.com/gitlab-org/gitlab/-/issues/349417 for more details. + def cdn_redirect + Feature.enabled?(:container_registry_cdn_redirect) || nil + end + ## # Because we do not have two way communication with registry yet, # we create a container repository image resource when push to the diff --git a/app/services/projects/destroy_service.rb b/app/services/projects/destroy_service.rb index 936c2da1e71..5c4a0e947de 100644 --- a/app/services/projects/destroy_service.rb +++ b/app/services/projects/destroy_service.rb @@ -41,6 +41,8 @@ module Projects true rescue StandardError => error + context = Gitlab::ApplicationContext.current.merge(project_id: project.id) + Gitlab::ErrorTracking.track_exception(error, **context) attempt_rollback(project, error.message) false rescue Exception => error # rubocop:disable Lint/RescueException diff --git a/app/services/projects/fork_service.rb b/app/services/projects/fork_service.rb index 74b7d18f401..3e8d6563709 100644 --- a/app/services/projects/fork_service.rb +++ b/app/services/projects/fork_service.rb @@ -69,6 +69,8 @@ module Projects new_params[:avatar] = @project.avatar end + new_params[:mr_default_target_self] = target_mr_default_target_self unless target_mr_default_target_self.nil? + new_params.merge!(@project.object_pool_params) new_params @@ -127,5 +129,9 @@ module Projects Gitlab::VisibilityLevel.closest_allowed_level(target_level) end + + def target_mr_default_target_self + @target_mr_default_target_self ||= params[:mr_default_target_self] + end end end diff --git a/app/views/notify/_note_email.html.haml b/app/views/notify/_note_email.html.haml index ae9c8554e73..ad0c873bf56 100644 --- a/app/views/notify/_note_email.html.haml +++ b/app/views/notify/_note_email.html.haml @@ -26,12 +26,10 @@ = stylesheet_link_tag 'mailers/highlighted_diff_email' %table - = render partial: "projects/diffs/line", + = render partial: "projects/diffs/email_line", collection: discussion.truncated_diff_lines(diff_limit: diff_limit), as: :line, - locals: { diff_file: discussion.diff_file, - plain: true, - email: true } + locals: { diff_file: discussion.diff_file } %div{ style: note_style } = markdown(note.note, pipeline: :email, author: note.author, current_user: @recipient, issuable_reference_expansion_enabled: true) diff --git a/app/views/notify/repository_push_email.html.haml b/app/views/notify/repository_push_email.html.haml index 5c5520f4cb8..93806e6de8e 100644 --- a/app/views/notify/repository_push_email.html.haml +++ b/app/views/notify/repository_push_email.html.haml @@ -74,7 +74,7 @@ - blob = diff_file.blob - if blob && blob.readable_text? %table.code.white - = render partial: "projects/diffs/line", collection: diff_file.highlighted_diff_lines, as: :line, locals: { diff_file: diff_file, plain: true, email: true } + = render partial: "projects/diffs/email_line", collection: diff_file.highlighted_diff_lines, as: :line, locals: { diff_file: diff_file } - else No preview for this file type %br diff --git a/app/views/projects/diffs/_email_line.html.haml b/app/views/projects/diffs/_email_line.html.haml new file mode 100644 index 00000000000..dfff143196c --- /dev/null +++ b/app/views/projects/diffs/_email_line.html.haml @@ -0,0 +1,21 @@ +-# This template is used when rendering diffs in email notifications +-# Called inside: app/views/notify/repository_push_email.html.haml +-# app/views/notify/_note_email.html.haml + +%tr.line_holder{ class: line.type } + - case line.type + - when 'match' + = diff_match_line line.old_pos, line.new_pos, text: line.text + - when 'old-nonewline', 'new-nonewline' + %td.old_line.diff-line-num + %td.new_line.diff-line-num + %td.line_content.match= line.text + - else + %td.old_line.diff-line-num{ class: line.type, data: { linenumber: line.old_pos } } + = diff_link_number(line.type, "new", line.old_pos) + + %td.new_line.diff-line-num{ class: line.type, data: { linenumber: line.new_pos } } + = diff_link_number(line.type, "old", line.new_pos) + + %td.line_content{ class: line.type }< + %pre= line.rich_text diff --git a/app/views/projects/diffs/_line.html.haml b/app/views/projects/diffs/_line.html.haml index de7f9eba158..330e2f564c9 100644 --- a/app/views/projects/diffs/_line.html.haml +++ b/app/views/projects/diffs/_line.html.haml @@ -1,3 +1,5 @@ +-# This file is deprecated in favour of inline rendering: +-# https://gitlab.com/gitlab-org/gitlab/-/merge_requests/57237 - plain = local_assigns.fetch(:plain, false) - discussions = local_assigns.fetch(:discussions, nil) - line_code = diff_file.line_code(line) diff --git a/app/views/projects/diffs/_text_file.html.haml b/app/views/projects/diffs/_text_file.html.haml index bf946b0ce73..6e7e0244721 100644 --- a/app/views/projects/diffs/_text_file.html.haml +++ b/app/views/projects/diffs/_text_file.html.haml @@ -4,10 +4,38 @@ %a.show-suppressed-diff.cursor-pointer.js-show-suppressed-diff= _("Changes suppressed. Click to show.") %table.text-file.diff-wrap-lines.code.code-commit.js-syntax-highlight.commit-diff{ data: diff_view_data, class: too_big ? 'hide' : '' } - = render partial: "projects/diffs/line", - collection: diff_file.highlighted_diff_lines, - as: :line, - locals: { diff_file: diff_file, discussions: @grouped_diff_discussions } + - if Feature.enabled?(:inline_haml_diff_line_rendering, @project, default_enabled: :yaml) + - diff_file.highlighted_diff_lines.each do |line| + - line_code = diff_file.line_code(line) + + %tr.line_holder{ class: line.type, id: line_code } + - case line.type + - when 'match' + = diff_match_line line.old_pos, line.new_pos, text: line.text + - when 'old-nonewline', 'new-nonewline' + %td.old_line.diff-line-num + %td.new_line.diff-line-num + %td.line_content.match= line.text + - else + %td.old_line.diff-line-num{ class: "#{line.type} js-avatar-container", data: { linenumber: line.old_pos } } + = add_diff_note_button(line_code, diff_file.position(line), line.type) + %a{ href: "##{line_code}", data: { linenumber: diff_link_number(line.type, "new", line.old_pos) } } + + %td.new_line.diff-line-num{ class: line.type, data: { linenumber: line.new_pos } } + %a{ href: "##{line_code}", data: { linenumber: diff_link_number(line.type, "old", line.new_pos) } } + + %td.line_content{ class: line.type }< + = diff_line_content(line.rich_text) + + - if line.discussable? && @grouped_diff_discussions.present? && @grouped_diff_discussions[line_code] + - line_discussions = @grouped_diff_discussions[line_code] + = render "discussions/diff_discussion", discussions: line_discussions, expanded: line_discussions.any?(&:expanded?) + + - else + = render partial: "projects/diffs/line", + collection: diff_file.highlighted_diff_lines, + as: :line, + locals: { diff_file: diff_file, discussions: @grouped_diff_discussions } - if !diff_file.new_file? && !diff_file.deleted_file? && diff_file.highlighted_diff_lines.any? - last_line = diff_file.highlighted_diff_lines.last |