Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
4714aa72e3
commit
953b58d061
|
@ -176,6 +176,14 @@ export const trackSaasTrialGetStarted = () => {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const trackTrialAcceptTerms = () => {
|
||||||
|
if (!isSupported()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
pushEvent('saasTrialAcceptTerms');
|
||||||
|
};
|
||||||
|
|
||||||
export const trackCheckout = (selectedPlan, quantity) => {
|
export const trackCheckout = (selectedPlan, quantity) => {
|
||||||
if (!isSupported()) {
|
if (!isSupported()) {
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -11,7 +11,7 @@ export default () => {
|
||||||
// eslint-disable-next-line no-new
|
// eslint-disable-next-line no-new
|
||||||
new BlobLinePermalinkUpdater(
|
new BlobLinePermalinkUpdater(
|
||||||
document.querySelector('#blob-content-holder'),
|
document.querySelector('#blob-content-holder'),
|
||||||
'.diff-line-num[data-line-number], .diff-line-num[data-line-number] *',
|
'.file-line-num[data-line-number], .file-line-num[data-line-number] *',
|
||||||
document.querySelectorAll('.js-data-file-blob-permalink-url, .js-blob-blame-link'),
|
document.querySelectorAll('.js-data-file-blob-permalink-url, .js-blob-blame-link'),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -27,6 +27,7 @@ query getBlobInfo(
|
||||||
fileType
|
fileType
|
||||||
language
|
language
|
||||||
path
|
path
|
||||||
|
blamePath
|
||||||
editBlobPath
|
editBlobPath
|
||||||
gitpodBlobUrl
|
gitpodBlobUrl
|
||||||
ideEditPath
|
ideEditPath
|
||||||
|
|
|
@ -7,6 +7,7 @@ import { isLoggedIn } from '~/lib/utils/common_utils';
|
||||||
import { __ } from '~/locale';
|
import { __ } from '~/locale';
|
||||||
import csrf from '~/lib/utils/csrf';
|
import csrf from '~/lib/utils/csrf';
|
||||||
import '~/behaviors/markdown/render_gfm';
|
import '~/behaviors/markdown/render_gfm';
|
||||||
|
import { trackTrialAcceptTerms } from '~/google_tag_manager';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'TermsApp',
|
name: 'TermsApp',
|
||||||
|
@ -73,6 +74,7 @@ export default {
|
||||||
this.setScrollableViewportHeight();
|
this.setScrollableViewportHeight();
|
||||||
event.target.removeEventListener(FLASH_CLOSED_EVENT, this.handleFlashClose);
|
event.target.removeEventListener(FLASH_CLOSED_EVENT, this.handleFlashClose);
|
||||||
},
|
},
|
||||||
|
trackTrialAcceptTerms,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
@ -99,7 +101,13 @@ export default {
|
||||||
<gl-button type="submit">{{ $options.i18n.decline }}</gl-button>
|
<gl-button type="submit">{{ $options.i18n.decline }}</gl-button>
|
||||||
<input :value="$options.csrf.token" type="hidden" name="authenticity_token" />
|
<input :value="$options.csrf.token" type="hidden" name="authenticity_token" />
|
||||||
</form>
|
</form>
|
||||||
<form v-if="permissions.canAccept" class="gl-ml-3" method="post" :action="paths.accept">
|
<form
|
||||||
|
v-if="permissions.canAccept"
|
||||||
|
class="gl-ml-3"
|
||||||
|
method="post"
|
||||||
|
:action="paths.accept"
|
||||||
|
@submit="trackTrialAcceptTerms"
|
||||||
|
>
|
||||||
<gl-button
|
<gl-button
|
||||||
type="submit"
|
type="submit"
|
||||||
variant="confirm"
|
variant="confirm"
|
||||||
|
|
|
@ -51,6 +51,10 @@ export default {
|
||||||
required: false,
|
required: false,
|
||||||
default: null,
|
default: null,
|
||||||
},
|
},
|
||||||
|
blamePath: {
|
||||||
|
type: String,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
lines() {
|
lines() {
|
||||||
|
@ -76,6 +80,7 @@ export default {
|
||||||
:number="startingFrom + index + 1"
|
:number="startingFrom + index + 1"
|
||||||
:content="line"
|
:content="line"
|
||||||
:language="language"
|
:language="language"
|
||||||
|
:blame-path="blamePath"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div v-else class="gl-display-flex">
|
<div v-else class="gl-display-flex">
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<script>
|
<script>
|
||||||
import { GlLink, GlSafeHtmlDirective } from '@gitlab/ui';
|
import { GlLink, GlSafeHtmlDirective, GlTooltipDirective } from '@gitlab/ui';
|
||||||
import { setAttributes } from '~/lib/utils/dom_utils';
|
import { setAttributes } from '~/lib/utils/dom_utils';
|
||||||
import { BIDI_CHARS, BIDI_CHARS_CLASS_LIST, BIDI_CHAR_TOOLTIP } from '../constants';
|
import { BIDI_CHARS, BIDI_CHARS_CLASS_LIST, BIDI_CHAR_TOOLTIP } from '../constants';
|
||||||
|
|
||||||
|
@ -9,6 +9,7 @@ export default {
|
||||||
},
|
},
|
||||||
directives: {
|
directives: {
|
||||||
SafeHtml: GlSafeHtmlDirective,
|
SafeHtml: GlSafeHtmlDirective,
|
||||||
|
GlTooltip: GlTooltipDirective,
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
number: {
|
number: {
|
||||||
|
@ -23,6 +24,10 @@ export default {
|
||||||
type: String,
|
type: String,
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
|
blamePath: {
|
||||||
|
type: String,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
formattedContent() {
|
formattedContent() {
|
||||||
|
@ -58,21 +63,35 @@ export default {
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<div class="gl-display-flex">
|
<div class="gl-display-flex line-links-wrapper">
|
||||||
<div class="gl-p-0! gl-absolute gl-z-index-3 gl-border-r diff-line-num line-numbers">
|
<div
|
||||||
|
class="gl-p-0! gl-absolute gl-z-index-3 diff-line-num gl-border-r gl-display-flex line-links line-numbers"
|
||||||
|
:class="firstLineClass"
|
||||||
|
>
|
||||||
|
<gl-link
|
||||||
|
v-gl-tooltip="__('View blame')"
|
||||||
|
class="gl-user-select-none gl-ml-3 gl-shadow-none! file-line-blame"
|
||||||
|
:href="`${blamePath}#L${number}`"
|
||||||
|
data-track-action="click_link"
|
||||||
|
data-track-label="file_line_action"
|
||||||
|
data-track-property="blame"
|
||||||
|
/>
|
||||||
|
|
||||||
<gl-link
|
<gl-link
|
||||||
:id="`L${number}`"
|
:id="`L${number}`"
|
||||||
class="gl-user-select-none gl-ml-5 gl-pr-3 gl-shadow-none! file-line-num diff-line-num"
|
class="gl-user-select-none gl-flex-grow-1 gl-justify-content-end gl-pr-3 gl-shadow-none! file-line-num"
|
||||||
:class="firstLineClass"
|
|
||||||
:to="`#L${number}`"
|
:to="`#L${number}`"
|
||||||
:data-line-number="number"
|
:data-line-number="number"
|
||||||
|
data-track-action="click_link"
|
||||||
|
data-track-label="file_line_action"
|
||||||
|
data-track-property="link"
|
||||||
>
|
>
|
||||||
{{ number }}
|
{{ number }}
|
||||||
</gl-link>
|
</gl-link>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<pre
|
<pre
|
||||||
class="gl-p-0! gl-w-full gl-overflow-visible! gl-ml-11! gl-border-none! code highlight gl-line-height-normal"
|
class="gl-p-0! gl-w-full gl-overflow-visible! gl-border-none! code highlight gl-line-height-normal"
|
||||||
:class="firstLineClass"
|
:class="firstLineClass"
|
||||||
><code><span :id="`LC${number}`" v-safe-html="formattedContent" :lang="language" class="line" data-testid="content"></span></code></pre>
|
><code><span :id="`LC${number}`" v-safe-html="formattedContent" :lang="language" class="line" data-testid="content"></span></code></pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -199,6 +199,7 @@ export default {
|
||||||
:starting-from="firstChunk.startingFrom"
|
:starting-from="firstChunk.startingFrom"
|
||||||
:is-highlighted="firstChunk.isHighlighted"
|
:is-highlighted="firstChunk.isHighlighted"
|
||||||
:language="firstChunk.language"
|
:language="firstChunk.language"
|
||||||
|
:blame-path="blob.blamePath"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<gl-loading-icon v-if="isLoading" size="sm" class="gl-my-5" />
|
<gl-loading-icon v-if="isLoading" size="sm" class="gl-my-5" />
|
||||||
|
@ -213,6 +214,7 @@ export default {
|
||||||
:is-highlighted="chunk.isHighlighted"
|
:is-highlighted="chunk.isHighlighted"
|
||||||
:chunk-index="index"
|
:chunk-index="index"
|
||||||
:language="chunk.language"
|
:language="chunk.language"
|
||||||
|
:blame-path="blob.blamePath"
|
||||||
@appear="highlightChunk"
|
@appear="highlightChunk"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -202,6 +202,10 @@
|
||||||
float: none;
|
float: none;
|
||||||
border-left: 1px solid $gray-100;
|
border-left: 1px solid $gray-100;
|
||||||
|
|
||||||
|
.file-line-num {
|
||||||
|
@include gl-min-w-9;
|
||||||
|
}
|
||||||
|
|
||||||
i {
|
i {
|
||||||
float: none;
|
float: none;
|
||||||
margin-right: 0;
|
margin-right: 0;
|
||||||
|
|
|
@ -48,8 +48,9 @@
|
||||||
|
|
||||||
a {
|
a {
|
||||||
font-family: $monospace-font;
|
font-family: $monospace-font;
|
||||||
display: block;
|
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
|
@include gl-display-flex;
|
||||||
|
@include gl-justify-content-end;
|
||||||
|
|
||||||
i,
|
i,
|
||||||
svg {
|
svg {
|
||||||
|
@ -90,3 +91,44 @@ td.line-numbers {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
text-decoration: underline wavy $red-500;
|
text-decoration: underline wavy $red-500;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.blob-viewer {
|
||||||
|
.line-numbers {
|
||||||
|
// for server-side-rendering
|
||||||
|
.line-links {
|
||||||
|
min-width: 6.5rem;
|
||||||
|
|
||||||
|
&:first-child {
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// for client
|
||||||
|
&.line-links {
|
||||||
|
min-width: 6.5rem;
|
||||||
|
border-bottom-left-radius: 0;
|
||||||
|
|
||||||
|
+ pre {
|
||||||
|
margin-left: 6.5rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.line-links {
|
||||||
|
&:hover .file-line-blame::before,
|
||||||
|
&:hover .file-line-num::before,
|
||||||
|
&:focus-within .file-line-blame::before,
|
||||||
|
&:focus-within .file-line-num::before {
|
||||||
|
@include gl-visibility-visible;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.file-line-num,
|
||||||
|
.file-line-blame {
|
||||||
|
@include gl-align-items-center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -98,32 +98,50 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@mixin line-number-link($color) {
|
|
||||||
min-width: $gl-spacing-scale-9;
|
|
||||||
|
|
||||||
|
@mixin line-link($color, $icon) {
|
||||||
&::before {
|
&::before {
|
||||||
@include gl-display-none;
|
@include gl-visibility-hidden;
|
||||||
@include gl-align-self-center;
|
@include gl-align-self-center;
|
||||||
@include gl-mt-2;
|
@include gl-mr-1;
|
||||||
@include gl-mr-2;
|
@include gl-w-5;
|
||||||
@include gl-w-4;
|
@include gl-h-5;
|
||||||
@include gl-h-4;
|
background-color: rgba($color, 0.3);
|
||||||
@include gl-absolute;
|
mask-image: asset_url('icons-stacked.svg##{$icon}');
|
||||||
@include gl-left-3;
|
|
||||||
background-color: $color;
|
|
||||||
mask-image: asset_url('icons-stacked.svg#link');
|
|
||||||
mask-repeat: no-repeat;
|
mask-repeat: no-repeat;
|
||||||
mask-size: cover;
|
mask-size: cover;
|
||||||
mask-position: center;
|
mask-position: center;
|
||||||
content: '';
|
content: '';
|
||||||
}
|
}
|
||||||
|
|
||||||
&:hover::before {
|
&:hover {
|
||||||
@include gl-display-inline-block;
|
&::before {
|
||||||
|
background-color: rgba($color, 0.6);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
&:focus::before {
|
@mixin line-hover-bg($color: $white-normal) {
|
||||||
@include gl-display-inline-block;
|
&:hover,
|
||||||
|
&:focus-within {
|
||||||
|
background-color: darken($color, 10);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin first-line-top-space($bg-color: $gray-light, $border-color: $white-normal) {
|
||||||
|
&:first-child {
|
||||||
|
.line-links {
|
||||||
|
&::before {
|
||||||
|
@include gl-absolute;
|
||||||
|
@include gl-h-3;
|
||||||
|
content: '';
|
||||||
|
bottom: 100%;
|
||||||
|
left: 0;
|
||||||
|
width: 6.5rem;
|
||||||
|
background-color: $bg-color;
|
||||||
|
border-right: 1px solid $border-color;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -127,7 +127,19 @@ $dark-il: #de935f;
|
||||||
.code.dark {
|
.code.dark {
|
||||||
// Line numbers
|
// Line numbers
|
||||||
.file-line-num {
|
.file-line-num {
|
||||||
@include line-number-link($dark-line-num-color);
|
@include line-link($white, 'link');
|
||||||
|
}
|
||||||
|
|
||||||
|
.file-line-blame {
|
||||||
|
@include line-link($white, 'git');
|
||||||
|
}
|
||||||
|
|
||||||
|
.line-links {
|
||||||
|
@include line-hover-bg($dark-main-bg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.line-links-wrapper {
|
||||||
|
@include first-line-top-space($dark-main-bg, $dark-code-border);
|
||||||
}
|
}
|
||||||
|
|
||||||
.line-numbers,
|
.line-numbers,
|
||||||
|
|
|
@ -119,7 +119,19 @@ $monokai-gh: #75715e;
|
||||||
|
|
||||||
// Line numbers
|
// Line numbers
|
||||||
.file-line-num {
|
.file-line-num {
|
||||||
@include line-number-link($monokai-line-num-color);
|
@include line-link($white, 'link');
|
||||||
|
}
|
||||||
|
|
||||||
|
.file-line-blame {
|
||||||
|
@include line-link($white, 'git');
|
||||||
|
}
|
||||||
|
|
||||||
|
.line-links {
|
||||||
|
@include line-hover-bg($monokai-bg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.line-links-wrapper {
|
||||||
|
@include first-line-top-space($monokai-bg, $monokai-border);
|
||||||
}
|
}
|
||||||
|
|
||||||
.line-numbers,
|
.line-numbers,
|
||||||
|
|
|
@ -25,7 +25,19 @@
|
||||||
|
|
||||||
// Line numbers
|
// Line numbers
|
||||||
.file-line-num {
|
.file-line-num {
|
||||||
@include line-number-link($black-transparent);
|
@include line-link($black, 'link');
|
||||||
|
}
|
||||||
|
|
||||||
|
.file-line-blame {
|
||||||
|
@include line-link($black, 'git');
|
||||||
|
}
|
||||||
|
|
||||||
|
.line-links {
|
||||||
|
@include line-hover-bg;
|
||||||
|
}
|
||||||
|
|
||||||
|
.line-links-wrapper {
|
||||||
|
@include first-line-top-space;
|
||||||
}
|
}
|
||||||
|
|
||||||
.line-numbers,
|
.line-numbers,
|
||||||
|
|
|
@ -122,7 +122,19 @@ $solarized-dark-il: #2aa198;
|
||||||
|
|
||||||
// Line numbers
|
// Line numbers
|
||||||
.file-line-num {
|
.file-line-num {
|
||||||
@include line-number-link($solarized-dark-line-color);
|
@include line-link($white, 'link');
|
||||||
|
}
|
||||||
|
|
||||||
|
.file-line-blame {
|
||||||
|
@include line-link($white, 'git');
|
||||||
|
}
|
||||||
|
|
||||||
|
.line-links {
|
||||||
|
@include line-hover-bg($solarized-dark-pre-bg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.line-links-wrapper {
|
||||||
|
@include first-line-top-space($solarized-dark-pre-bg, $solarized-dark-pre-border);
|
||||||
}
|
}
|
||||||
|
|
||||||
.line-numbers,
|
.line-numbers,
|
||||||
|
|
|
@ -108,7 +108,19 @@ $solarized-light-il: #2aa198;
|
||||||
.code.solarized-light {
|
.code.solarized-light {
|
||||||
// Line numbers
|
// Line numbers
|
||||||
.file-line-num {
|
.file-line-num {
|
||||||
@include line-number-link($solarized-light-line-color);
|
@include line-link($black, 'link');
|
||||||
|
}
|
||||||
|
|
||||||
|
.file-line-blame {
|
||||||
|
@include line-link($black, 'git');
|
||||||
|
}
|
||||||
|
|
||||||
|
.line-links {
|
||||||
|
@include line-hover-bg($solarized-light-pre-bg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.line-links-wrapper {
|
||||||
|
@include first-line-top-space($solarized-light-pre-bg, $solarized-light-border);
|
||||||
}
|
}
|
||||||
|
|
||||||
.line-numbers,
|
.line-numbers,
|
||||||
|
|
|
@ -95,7 +95,15 @@ $white-gc-bg: #eaf2f5;
|
||||||
|
|
||||||
// Line numbers
|
// Line numbers
|
||||||
.file-line-num {
|
.file-line-num {
|
||||||
@include line-number-link($black-transparent);
|
@include line-link($black, 'link');
|
||||||
|
}
|
||||||
|
|
||||||
|
.file-line-blame {
|
||||||
|
@include line-link($black, 'git');
|
||||||
|
}
|
||||||
|
|
||||||
|
.line-links {
|
||||||
|
@include line-hover-bg;
|
||||||
}
|
}
|
||||||
|
|
||||||
.line-numbers,
|
.line-numbers,
|
||||||
|
@ -126,6 +134,10 @@ pre.code,
|
||||||
border-color: $white-normal;
|
border-color: $white-normal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.line-links-wrapper {
|
||||||
|
@include first-line-top-space;
|
||||||
|
}
|
||||||
|
|
||||||
&,
|
&,
|
||||||
pre.code,
|
pre.code,
|
||||||
.line_holder .line_content {
|
.line_holder .line_content {
|
||||||
|
|
|
@ -14,6 +14,10 @@ module Users
|
||||||
|
|
||||||
before_action :terms
|
before_action :terms
|
||||||
|
|
||||||
|
before_action only: [:index] do
|
||||||
|
push_frontend_feature_flag(:gitlab_gtm_datalayer, type: :ops)
|
||||||
|
end
|
||||||
|
|
||||||
layout 'terms'
|
layout 'terms'
|
||||||
|
|
||||||
feature_category :user_management
|
feature_category :user_management
|
||||||
|
|
|
@ -128,13 +128,8 @@ module MergeRequests
|
||||||
if draft_event = params.delete(:wip_event)
|
if draft_event = params.delete(:wip_event)
|
||||||
# We update the title that is provided in the params or we use the mr title
|
# We update the title that is provided in the params or we use the mr title
|
||||||
title = params[:title] || merge_request.title
|
title = params[:title] || merge_request.title
|
||||||
# Supports both `wip` and `draft` permutations of draft_event
|
|
||||||
# This support can be removed >= %15.2
|
|
||||||
#
|
|
||||||
params[:title] = case draft_event
|
params[:title] = case draft_event
|
||||||
when 'wip' then MergeRequest.draft_title(title)
|
|
||||||
when 'draft' then MergeRequest.draft_title(title)
|
when 'draft' then MergeRequest.draft_title(title)
|
||||||
when 'unwip' then MergeRequest.draftless_title(title)
|
|
||||||
when 'ready' then MergeRequest.draftless_title(title)
|
when 'ready' then MergeRequest.draftless_title(title)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,13 +1,16 @@
|
||||||
#blob-content.file-content.code.js-syntax-highlight
|
#blob-content.file-content.code.js-syntax-highlight
|
||||||
- offset = defined?(first_line_number) ? first_line_number : 1
|
- offset = defined?(first_line_number) ? first_line_number : 1
|
||||||
.line-numbers
|
.line-numbers{ class: "gl-p-0\!" }
|
||||||
- if blob.data.present?
|
- if blob.data.present?
|
||||||
- link = blob_link if defined?(blob_link)
|
- link = blob_link if defined?(blob_link)
|
||||||
|
- blame_link = project_blame_path(@project, tree_join(@ref, blob.path))
|
||||||
- blob.data.each_line.each_with_index do |_, index|
|
- blob.data.each_line.each_with_index do |_, index|
|
||||||
- i = index + offset
|
- i = index + offset
|
||||||
-# We're not using `link_to` because it is too slow once we get to thousands of lines.
|
-# We're not using `link_to` because it is too slow once we get to thousands of lines.
|
||||||
%a.file-line-num.diff-line-num{ href: "#{link}#L#{i}", id: "L#{i}", 'data-line-number' => i }
|
.gl-display-flex.line-links.diff-line-num
|
||||||
= i
|
%a.file-line-blame.gl-display-flex.has-tooltip.gl-ml-3{ href: "#{blame_link}#L#{i}", title: _('View blame'), data: { track_action: "click_link", track_label: "file_line_action", track_property: "blame" } }
|
||||||
|
%a.file-line-num.gl-display-flex.gl-justify-content-end.flex-grow-1.gl-pr-3{ href: "#{link}#L#{i}", id: "L#{i}", 'data-line-number' => i, data: { track_action: "click_link", track_label: "file_line_action", track_property: "link" } }
|
||||||
|
= i
|
||||||
- highlight = defined?(highlight_line) && highlight_line ? highlight_line - offset : nil
|
- highlight = defined?(highlight_line) && highlight_line ? highlight_line - offset : nil
|
||||||
.blob-content{ data: { blob_id: blob.id, path: blob.path, highlight_line: highlight, qa_selector: 'file_content' } }
|
.blob-content{ data: { blob_id: blob.id, path: blob.path, highlight_line: highlight, qa_selector: 'file_content' } }
|
||||||
%pre.code.highlight
|
%pre.code.highlight
|
||||||
|
|
|
@ -138,9 +138,8 @@ module Gitlab
|
||||||
def self.allow_sentry(directives)
|
def self.allow_sentry(directives)
|
||||||
sentry_dsn = Gitlab.config.sentry.clientside_dsn
|
sentry_dsn = Gitlab.config.sentry.clientside_dsn
|
||||||
sentry_uri = URI(sentry_dsn)
|
sentry_uri = URI(sentry_dsn)
|
||||||
sentry_uri.user = nil
|
|
||||||
|
|
||||||
append_to_directive(directives, 'connect_src', sentry_uri.to_s)
|
append_to_directive(directives, 'connect_src', "#{sentry_uri.scheme}://#{sentry_uri.host}")
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.allow_letter_opener(directives)
|
def self.allow_letter_opener(directives)
|
||||||
|
|
|
@ -10,6 +10,7 @@ import {
|
||||||
trackSaasTrialGroup,
|
trackSaasTrialGroup,
|
||||||
trackSaasTrialProject,
|
trackSaasTrialProject,
|
||||||
trackSaasTrialGetStarted,
|
trackSaasTrialGetStarted,
|
||||||
|
trackTrialAcceptTerms,
|
||||||
trackCheckout,
|
trackCheckout,
|
||||||
trackTransaction,
|
trackTransaction,
|
||||||
trackAddToCartUsageTab,
|
trackAddToCartUsageTab,
|
||||||
|
@ -255,6 +256,16 @@ describe('~/google_tag_manager/index', () => {
|
||||||
expect(logError).not.toHaveBeenCalled();
|
expect(logError).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('when trackTrialAcceptTerms is invoked', () => {
|
||||||
|
expect(spy).not.toHaveBeenCalled();
|
||||||
|
|
||||||
|
trackTrialAcceptTerms();
|
||||||
|
|
||||||
|
expect(spy).toHaveBeenCalledTimes(1);
|
||||||
|
expect(spy).toHaveBeenCalledWith({ event: 'saasTrialAcceptTerms' });
|
||||||
|
expect(logError).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
describe('when trackCheckout is invoked', () => {
|
describe('when trackCheckout is invoked', () => {
|
||||||
it('with selectedPlan: 2c92a00d76f0d5060176f2fb0a5029ff', () => {
|
it('with selectedPlan: 2c92a00d76f0d5060176f2fb0a5029ff', () => {
|
||||||
expect(spy).not.toHaveBeenCalled();
|
expect(spy).not.toHaveBeenCalled();
|
||||||
|
|
|
@ -8,6 +8,7 @@ export const simpleViewerMock = {
|
||||||
language: 'javascript',
|
language: 'javascript',
|
||||||
path: 'some_file.js',
|
path: 'some_file.js',
|
||||||
webPath: 'some_file.js',
|
webPath: 'some_file.js',
|
||||||
|
blamePath: 'blame/file.js',
|
||||||
editBlobPath: 'some_file.js/edit',
|
editBlobPath: 'some_file.js/edit',
|
||||||
gitpodBlobUrl: 'https://gitpod.io#path/to/blob.js',
|
gitpodBlobUrl: 'https://gitpod.io#path/to/blob.js',
|
||||||
ideEditPath: 'some_file.js/ide/edit',
|
ideEditPath: 'some_file.js/ide/edit',
|
||||||
|
|
|
@ -11,6 +11,7 @@ const DEFAULT_PROPS = {
|
||||||
number: 2,
|
number: 2,
|
||||||
content: '// Line content',
|
content: '// Line content',
|
||||||
language: 'javascript',
|
language: 'javascript',
|
||||||
|
blamePath: 'blame/file.js',
|
||||||
};
|
};
|
||||||
|
|
||||||
describe('Chunk Line component', () => {
|
describe('Chunk Line component', () => {
|
||||||
|
@ -20,7 +21,7 @@ describe('Chunk Line component', () => {
|
||||||
wrapper = shallowMountExtended(ChunkLine, { propsData: { ...DEFAULT_PROPS, ...props } });
|
wrapper = shallowMountExtended(ChunkLine, { propsData: { ...DEFAULT_PROPS, ...props } });
|
||||||
};
|
};
|
||||||
|
|
||||||
const findLink = () => wrapper.findComponent(GlLink);
|
const findLinks = () => wrapper.findAllComponents(GlLink);
|
||||||
const findContent = () => wrapper.findByTestId('content');
|
const findContent = () => wrapper.findByTestId('content');
|
||||||
const findWrappedBidiChars = () => wrapper.findAllByTestId('bidi-wrapper');
|
const findWrappedBidiChars = () => wrapper.findAllByTestId('bidi-wrapper');
|
||||||
|
|
||||||
|
@ -47,14 +48,22 @@ describe('Chunk Line component', () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('renders a blame link', () => {
|
||||||
|
expect(findLinks().at(0).attributes()).toMatchObject({
|
||||||
|
href: `${DEFAULT_PROPS.blamePath}#L${DEFAULT_PROPS.number}`,
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(findLinks().at(0).text()).toBe('');
|
||||||
|
});
|
||||||
|
|
||||||
it('renders a line number', () => {
|
it('renders a line number', () => {
|
||||||
expect(findLink().attributes()).toMatchObject({
|
expect(findLinks().at(1).attributes()).toMatchObject({
|
||||||
'data-line-number': `${DEFAULT_PROPS.number}`,
|
'data-line-number': `${DEFAULT_PROPS.number}`,
|
||||||
to: `#L${DEFAULT_PROPS.number}`,
|
to: `#L${DEFAULT_PROPS.number}`,
|
||||||
id: `L${DEFAULT_PROPS.number}`,
|
id: `L${DEFAULT_PROPS.number}`,
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(findLink().text()).toBe(DEFAULT_PROPS.number.toString());
|
expect(findLinks().at(1).text()).toBe(DEFAULT_PROPS.number.toString());
|
||||||
});
|
});
|
||||||
|
|
||||||
it('renders content', () => {
|
it('renders content', () => {
|
||||||
|
|
|
@ -10,6 +10,7 @@ const DEFAULT_PROPS = {
|
||||||
startingFrom: 140,
|
startingFrom: 140,
|
||||||
totalLines: 50,
|
totalLines: 50,
|
||||||
language: 'javascript',
|
language: 'javascript',
|
||||||
|
blamePath: 'blame/file.js',
|
||||||
};
|
};
|
||||||
|
|
||||||
describe('Chunk component', () => {
|
describe('Chunk component', () => {
|
||||||
|
@ -76,6 +77,7 @@ describe('Chunk component', () => {
|
||||||
number: DEFAULT_PROPS.startingFrom + 1,
|
number: DEFAULT_PROPS.startingFrom + 1,
|
||||||
content: splitContent[0],
|
content: splitContent[0],
|
||||||
language: DEFAULT_PROPS.language,
|
language: DEFAULT_PROPS.language,
|
||||||
|
blamePath: DEFAULT_PROPS.blamePath,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -40,7 +40,8 @@ describe('Source Viewer component', () => {
|
||||||
const chunk2 = generateContent('// Some source code 2', 70);
|
const chunk2 = generateContent('// Some source code 2', 70);
|
||||||
const content = chunk1 + chunk2;
|
const content = chunk1 + chunk2;
|
||||||
const path = 'some/path.js';
|
const path = 'some/path.js';
|
||||||
const DEFAULT_BLOB_DATA = { language, rawTextBlob: content, path };
|
const blamePath = 'some/blame/path.js';
|
||||||
|
const DEFAULT_BLOB_DATA = { language, rawTextBlob: content, path, blamePath };
|
||||||
const highlightedContent = `<span data-testid='test-highlighted' id='LC1'>${content}</span><span id='LC2'></span>`;
|
const highlightedContent = `<span data-testid='test-highlighted' id='LC1'>${content}</span><span id='LC2'></span>`;
|
||||||
|
|
||||||
const createComponent = async (blob = {}) => {
|
const createComponent = async (blob = {}) => {
|
||||||
|
|
|
@ -92,11 +92,11 @@ RSpec.describe Gitlab::ContentSecurityPolicy::ConfigLoader do
|
||||||
context 'when sentry is configured' do
|
context 'when sentry is configured' do
|
||||||
before do
|
before do
|
||||||
stub_sentry_settings
|
stub_sentry_settings
|
||||||
stub_config_setting(host: 'example.com')
|
stub_config_setting(host: 'gitlab.example.com')
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'adds sentry path to CSP without user' do
|
it 'adds sentry path to CSP without user' do
|
||||||
expect(directives['connect_src']).to eq("'self' ws://example.com dummy://example.com/43")
|
expect(directives['connect_src']).to eq("'self' ws://gitlab.example.com dummy://example.com")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -126,4 +126,34 @@ RSpec.describe DeviseMailer do
|
||||||
is_expected.to have_link("Reset password", href: "#{Gitlab.config.gitlab.url}/users/password/edit?reset_password_token=faketoken")
|
is_expected.to have_link("Reset password", href: "#{Gitlab.config.gitlab.url}/users/password/edit?reset_password_token=faketoken")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe '#email_changed' do
|
||||||
|
subject { described_class.email_changed(user, {}) }
|
||||||
|
|
||||||
|
let_it_be(:user) { create(:user) }
|
||||||
|
|
||||||
|
it_behaves_like 'an email sent from GitLab'
|
||||||
|
|
||||||
|
it 'is sent to the user' do
|
||||||
|
is_expected.to deliver_to user.email
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'has the correct subject' do
|
||||||
|
is_expected.to have_subject 'Email Changed'
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'greets the user' do
|
||||||
|
is_expected.to have_body_text /Hello, #{user.name}!/
|
||||||
|
end
|
||||||
|
|
||||||
|
context "email contains updated id" do
|
||||||
|
before do
|
||||||
|
user.update!(email: "new_email@test.com")
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'includes changed email id' do
|
||||||
|
is_expected.to have_body_text /email is being changed to new_email@test.com./
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -845,6 +845,8 @@ RSpec.describe MergeRequests::UpdateService, :mailer do
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when the draft status is changed' do
|
context 'when the draft status is changed' do
|
||||||
|
let(:title) { 'New Title' }
|
||||||
|
let(:draft_title) { "Draft: #{title}" }
|
||||||
let!(:non_subscriber) { create(:user) }
|
let!(:non_subscriber) { create(:user) }
|
||||||
let!(:subscriber) do
|
let!(:subscriber) do
|
||||||
create(:user) { |u| merge_request.toggle_subscription(u, project) }
|
create(:user) { |u| merge_request.toggle_subscription(u, project) }
|
||||||
|
@ -857,7 +859,7 @@ RSpec.describe MergeRequests::UpdateService, :mailer do
|
||||||
|
|
||||||
context 'removing draft status' do
|
context 'removing draft status' do
|
||||||
before do
|
before do
|
||||||
merge_request.update_attribute(:title, 'Draft: New Title')
|
merge_request.update_attribute(:title, draft_title)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'sends notifications for subscribers', :sidekiq_might_not_need_inline do
|
it 'sends notifications for subscribers', :sidekiq_might_not_need_inline do
|
||||||
|
@ -870,9 +872,22 @@ RSpec.describe MergeRequests::UpdateService, :mailer do
|
||||||
should_email(subscriber)
|
should_email(subscriber)
|
||||||
should_not_email(non_subscriber)
|
should_not_email(non_subscriber)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context 'when removing through wip_event param' do
|
||||||
|
it 'removes Draft from the title' do
|
||||||
|
expect { update_merge_request({ wip_event: "ready" }) }
|
||||||
|
.to change { merge_request.title }
|
||||||
|
.from(draft_title)
|
||||||
|
.to(title)
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'adding draft status' do
|
context 'adding draft status' do
|
||||||
|
before do
|
||||||
|
merge_request.update_attribute(:title, title)
|
||||||
|
end
|
||||||
|
|
||||||
it 'does not send notifications', :sidekiq_might_not_need_inline do
|
it 'does not send notifications', :sidekiq_might_not_need_inline do
|
||||||
opts = { title: 'Draft: New title' }
|
opts = { title: 'Draft: New title' }
|
||||||
|
|
||||||
|
@ -883,6 +898,15 @@ RSpec.describe MergeRequests::UpdateService, :mailer do
|
||||||
should_not_email(subscriber)
|
should_not_email(subscriber)
|
||||||
should_not_email(non_subscriber)
|
should_not_email(non_subscriber)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context 'when adding through wip_event param' do
|
||||||
|
it 'adds Draft to the title' do
|
||||||
|
expect { update_merge_request({ wip_event: "draft" }) }
|
||||||
|
.to change { merge_request.title }
|
||||||
|
.from(title)
|
||||||
|
.to(draft_title)
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,7 @@ RSpec.shared_context 'ProjectPolicy context' do
|
||||||
let_it_be_with_refind(:private_project) { create(:project, :private, namespace: owner.namespace) }
|
let_it_be_with_refind(:private_project) { create(:project, :private, namespace: owner.namespace) }
|
||||||
let_it_be_with_refind(:internal_project) { create(:project, :internal, namespace: owner.namespace) }
|
let_it_be_with_refind(:internal_project) { create(:project, :internal, namespace: owner.namespace) }
|
||||||
let_it_be_with_refind(:public_project) { create(:project, :public, namespace: owner.namespace) }
|
let_it_be_with_refind(:public_project) { create(:project, :public, namespace: owner.namespace) }
|
||||||
|
let_it_be_with_refind(:public_project_in_group) { create(:project, :public, namespace: create(:group, :public)) }
|
||||||
|
|
||||||
let(:base_guest_permissions) do
|
let(:base_guest_permissions) do
|
||||||
%i[
|
%i[
|
||||||
|
@ -93,7 +94,7 @@ RSpec.shared_context 'ProjectPolicy context' do
|
||||||
let(:owner_permissions) { base_owner_permissions + additional_owner_permissions }
|
let(:owner_permissions) { base_owner_permissions + additional_owner_permissions }
|
||||||
|
|
||||||
before_all do
|
before_all do
|
||||||
[private_project, internal_project, public_project].each do |project|
|
[private_project, internal_project, public_project, public_project_in_group].each do |project|
|
||||||
project.add_guest(guest)
|
project.add_guest(guest)
|
||||||
project.add_reporter(reporter)
|
project.add_reporter(reporter)
|
||||||
project.add_developer(developer)
|
project.add_developer(developer)
|
||||||
|
|
|
@ -24,6 +24,7 @@ RSpec.describe 'projects/blob/_viewer.html.haml' do
|
||||||
before do
|
before do
|
||||||
assign(:project, project)
|
assign(:project, project)
|
||||||
assign(:blob, blob)
|
assign(:blob, blob)
|
||||||
|
assign(:ref, 'master')
|
||||||
assign(:id, File.join('master', blob.path))
|
assign(:id, File.join('master', blob.path))
|
||||||
|
|
||||||
controller.params[:controller] = 'projects/blob'
|
controller.params[:controller] = 'projects/blob'
|
||||||
|
|
Loading…
Reference in New Issue