Commit c97d822c authored by Felipe Artur's avatar Felipe Artur

Merge branch '11-1-stable-prepare-rc13' into 11-1-stable

parents 5238eb5e 07f4b095
...@@ -327,7 +327,7 @@ cloud-native-image: ...@@ -327,7 +327,7 @@ cloud-native-image:
cache: {} cache: {}
script: script:
- gem install gitlab --no-ri --no-rdoc - gem install gitlab --no-ri --no-rdoc
- ./scripts/trigger-build cng - BUILD_TRIGGER_TOKEN=$CI_JOB_TOKEN scripts/trigger-build cng
only: only:
- tags@gitlab-org/gitlab-ce - tags@gitlab-org/gitlab-ce
- tags@gitlab-org/gitlab-ee - tags@gitlab-org/gitlab-ee
......
...@@ -85,6 +85,9 @@ export default { ...@@ -85,6 +85,9 @@ export default {
} }
return __('Show latest version'); return __('Show latest version');
}, },
canCurrentUserFork() {
return this.currentUser.canFork === true && this.currentUser.canCreateMergeRequest;
},
}, },
watch: { watch: {
diffViewType() { diffViewType() {
...@@ -192,7 +195,7 @@ export default { ...@@ -192,7 +195,7 @@ export default {
v-for="file in diffFiles" v-for="file in diffFiles"
:key="file.newPath" :key="file.newPath"
:file="file" :file="file"
:current-user="currentUser" :can-current-user-fork="canCurrentUserFork"
/> />
</div> </div>
<no-changes v-else /> <no-changes v-else />
......
...@@ -18,8 +18,8 @@ export default { ...@@ -18,8 +18,8 @@ export default {
type: Object, type: Object,
required: true, required: true,
}, },
currentUser: { canCurrentUserFork: {
type: Object, type: Boolean,
required: true, required: true,
}, },
}, },
...@@ -87,7 +87,7 @@ export default { ...@@ -87,7 +87,7 @@ export default {
class="diff-file file-holder" class="diff-file file-holder"
> >
<diff-file-header <diff-file-header
:current-user="currentUser" :can-current-user-fork="canCurrentUserFork"
:diff-file="file" :diff-file="file"
:collapsible="true" :collapsible="true"
:expanded="!isCollapsed" :expanded="!isCollapsed"
......
...@@ -39,8 +39,8 @@ export default { ...@@ -39,8 +39,8 @@ export default {
required: false, required: false,
default: true, default: true,
}, },
currentUser: { canCurrentUserFork: {
type: Object, type: Boolean,
required: true, required: true,
}, },
}, },
...@@ -228,7 +228,7 @@ export default { ...@@ -228,7 +228,7 @@ export default {
<edit-button <edit-button
v-if="!diffFile.deletedFile" v-if="!diffFile.deletedFile"
:current-user="currentUser" :can-current-user-fork="canCurrentUserFork"
:edit-path="diffFile.editPath" :edit-path="diffFile.editPath"
:can-modify-blob="diffFile.canModifyBlob" :can-modify-blob="diffFile.canModifyBlob"
@showForkMessage="showForkMessage" @showForkMessage="showForkMessage"
......
...@@ -13,12 +13,8 @@ export default { ...@@ -13,12 +13,8 @@ export default {
noteForm, noteForm,
}, },
props: { props: {
diffFile: { diffFileHash: {
type: Object, type: String,
required: true,
},
diffLines: {
type: Array,
required: true, required: true,
}, },
line: { line: {
...@@ -40,6 +36,7 @@ export default { ...@@ -40,6 +36,7 @@ export default {
noteableData: state => state.notes.noteableData, noteableData: state => state.notes.noteableData,
diffViewType: state => state.diffs.diffViewType, diffViewType: state => state.diffs.diffViewType,
}), }),
...mapGetters('diffs', ['getDiffFileByHash']),
...mapGetters(['isLoggedIn', 'noteableType', 'getNoteableData', 'getNotesDataByProp']), ...mapGetters(['isLoggedIn', 'noteableType', 'getNoteableData', 'getNotesDataByProp']),
}, },
mounted() { mounted() {
...@@ -68,13 +65,14 @@ export default { ...@@ -68,13 +65,14 @@ export default {
}); });
}, },
handleSaveNote(note) { handleSaveNote(note) {
const selectedDiffFile = this.getDiffFileByHash(this.diffFileHash);
const postData = getNoteFormData({ const postData = getNoteFormData({
note, note,
noteableData: this.noteableData, noteableData: this.noteableData,
noteableType: this.noteableType, noteableType: this.noteableType,
noteTargetLine: this.noteTargetLine, noteTargetLine: this.noteTargetLine,
diffViewType: this.diffViewType, diffViewType: this.diffViewType,
diffFile: this.diffFile, diffFile: selectedDiffFile,
linePosition: this.position, linePosition: this.position,
}); });
......
...@@ -24,8 +24,12 @@ export default { ...@@ -24,8 +24,12 @@ export default {
type: Object, type: Object,
required: true, required: true,
}, },
diffFile: { fileHash: {
type: Object, type: String,
required: true,
},
contextLinesPath: {
type: String,
required: true, required: true,
}, },
diffViewType: { diffViewType: {
...@@ -120,14 +124,14 @@ export default { ...@@ -120,14 +124,14 @@ export default {
:class="classNameMap" :class="classNameMap"
> >
<diff-line-gutter-content <diff-line-gutter-content
:file-hash="diffFile.fileHash" :file-hash="fileHash"
:context-lines-path="contextLinesPath"
:line-type="normalizedLine.type" :line-type="normalizedLine.type"
:line-code="normalizedLine.lineCode" :line-code="normalizedLine.lineCode"
:line-position="linePosition" :line-position="linePosition"
:line-number="lineNumber" :line-number="lineNumber"
:meta-data="normalizedLine.metaData" :meta-data="normalizedLine.metaData"
:show-comment-button="showCommentButton" :show-comment-button="showCommentButton"
:context-lines-path="diffFile.contextLinesPath"
:is-bottom="isBottom" :is-bottom="isBottom"
:is-match-line="isMatchLine" :is-match-line="isMatchLine"
:is-context-line="isContentLine" :is-context-line="isContentLine"
......
...@@ -5,8 +5,8 @@ export default { ...@@ -5,8 +5,8 @@ export default {
type: String, type: String,
required: true, required: true,
}, },
currentUser: { canCurrentUserFork: {
type: Object, type: Boolean,
required: true, required: true,
}, },
canModifyBlob: { canModifyBlob: {
...@@ -17,12 +17,12 @@ export default { ...@@ -17,12 +17,12 @@ export default {
}, },
methods: { methods: {
handleEditClick(evt) { handleEditClick(evt) {
if (!this.currentUser || this.canModifyBlob) { if (!this.canCurrentUserFork || this.canModifyBlob) {
// if we can Edit, do default Edit button behavior // if we can Edit, do default Edit button behavior
return; return;
} }
if (this.currentUser.canFork && this.currentUser.canCreateMergeRequest) { if (this.canCurrentUserFork) {
evt.preventDefault(); evt.preventDefault();
this.$emit('showForkMessage'); this.$emit('showForkMessage');
} }
......
...@@ -13,12 +13,8 @@ export default { ...@@ -13,12 +13,8 @@ export default {
type: Object, type: Object,
required: true, required: true,
}, },
diffFile: { diffFileHash: {
type: Object, type: String,
required: true,
},
diffLines: {
type: Array,
required: true, required: true,
}, },
lineIndex: { lineIndex: {
...@@ -58,10 +54,9 @@ export default { ...@@ -58,10 +54,9 @@ export default {
/> />
<diff-line-note-form <diff-line-note-form
v-if="diffLineCommentForms[line.lineCode]" v-if="diffLineCommentForms[line.lineCode]"
:diff-file="diffFile" :diff-file-hash="diffFileHash"
:diff-lines="diffLines"
:line="line" :line="line"
:note-target-line="diffLines[lineIndex]" :note-target-line="line"
/> />
</div> </div>
</td> </td>
......
...@@ -16,8 +16,12 @@ export default { ...@@ -16,8 +16,12 @@ export default {
DiffTableCell, DiffTableCell,
}, },
props: { props: {
diffFile: { fileHash: {
type: Object, type: String,
required: true,
},
contextLinesPath: {
type: String,
required: true, required: true,
}, },
line: { line: {
...@@ -50,7 +54,7 @@ export default { ...@@ -50,7 +54,7 @@ export default {
inlineRowId() { inlineRowId() {
const { lineCode, oldLine, newLine } = this.line; const { lineCode, oldLine, newLine } = this.line;
return lineCode || `${this.diffFile.fileHash}_${oldLine}_${newLine}`; return lineCode || `${this.fileHash}_${oldLine}_${newLine}`;
}, },
}, },
created() { created() {
...@@ -78,7 +82,8 @@ export default { ...@@ -78,7 +82,8 @@ export default {
@mouseout="handleMouseMove" @mouseout="handleMouseMove"
> >
<diff-table-cell <diff-table-cell
:diff-file="diffFile" :file-hash="fileHash"
:context-lines-path="contextLinesPath"
:line="line" :line="line"
:line-type="oldLineType" :line-type="oldLineType"
:is-bottom="isBottom" :is-bottom="isBottom"
...@@ -87,7 +92,8 @@ export default { ...@@ -87,7 +92,8 @@ export default {
class="diff-line-num old_line" class="diff-line-num old_line"
/> />
<diff-table-cell <diff-table-cell
:diff-file="diffFile" :file-hash="fileHash"
:context-lines-path="contextLinesPath"
:line="line" :line="line"
:line-type="newLineType" :line-type="newLineType"
:is-bottom="isBottom" :is-bottom="isBottom"
......
...@@ -60,15 +60,15 @@ export default { ...@@ -60,15 +60,15 @@ export default {
v-for="(line, index) in normalizedDiffLines" v-for="(line, index) in normalizedDiffLines"
> >
<inline-diff-table-row <inline-diff-table-row
:diff-file="diffFile" :file-hash="diffFile.fileHash"
:context-lines-path="diffFile.contextLinesPath"
:line="line" :line="line"
:is-bottom="index + 1 === diffLinesLength" :is-bottom="index + 1 === diffLinesLength"
:key="line.lineCode" :key="line.lineCode"
/> />
<inline-diff-comment-row <inline-diff-comment-row
v-if="shouldRenderCommentRow(line)" v-if="shouldRenderCommentRow(line)"
:diff-file="diffFile" :diff-file-hash="diffFile.fileHash"
:diff-lines="normalizedDiffLines"
:line="line" :line="line"
:line-index="index" :line-index="index"
:key="index" :key="index"
......
...@@ -13,12 +13,8 @@ export default { ...@@ -13,12 +13,8 @@ export default {
type: Object, type: Object,
required: true, required: true,
}, },
diffFile: { diffFileHash: {
type: Object, type: String,
required: true,
},
diffLines: {
type: Array,
required: true, required: true,
}, },
lineIndex: { lineIndex: {
...@@ -91,10 +87,9 @@ export default { ...@@ -91,10 +87,9 @@ export default {
<diff-line-note-form <diff-line-note-form
v-if="diffLineCommentForms[leftLineCode] && v-if="diffLineCommentForms[leftLineCode] &&
diffLineCommentForms[leftLineCode]" diffLineCommentForms[leftLineCode]"
:diff-file="diffFile" :diff-file-hash="diffFileHash"
:diff-lines="diffLines"
:line="line.left" :line="line.left"
:note-target-line="diffLines[lineIndex].left" :note-target-line="line.left"
position="left" position="left"
/> />
</td> </td>
...@@ -112,10 +107,9 @@ export default { ...@@ -112,10 +107,9 @@ export default {
<diff-line-note-form <diff-line-note-form
v-if="diffLineCommentForms[rightLineCode] && v-if="diffLineCommentForms[rightLineCode] &&
diffLineCommentForms[rightLineCode] && line.right.type" diffLineCommentForms[rightLineCode] && line.right.type"
:diff-file="diffFile" :diff-file-hash="diffFileHash"
:diff-lines="diffLines"
:line="line.right" :line="line.right"
:note-target-line="diffLines[lineIndex].right" :note-target-line="line.right"
position="right" position="right"
/> />
</td> </td>
......
...@@ -19,8 +19,12 @@ export default { ...@@ -19,8 +19,12 @@ export default {
DiffTableCell, DiffTableCell,
}, },
props: { props: {
diffFile: { fileHash: {
type: Object, type: String,
required: true,
},
contextLinesPath: {
type: String,
required: true, required: true,
}, },
line: { line: {
...@@ -103,7 +107,8 @@ export default { ...@@ -103,7 +107,8 @@ export default {
@mouseout="handleMouseMove" @mouseout="handleMouseMove"
> >
<diff-table-cell <diff-table-cell
:diff-file="diffFile" :file-hash="fileHash"
:context-lines-path="contextLinesPath"
:line="line" :line="line"
:line-type="oldLineType" :line-type="oldLineType"
:line-position="linePositionLeft" :line-position="linePositionLeft"
...@@ -123,7 +128,8 @@ export default { ...@@ -123,7 +128,8 @@ export default {
> >
</td> </td>
<diff-table-cell <diff-table-cell
:diff-file="diffFile" :file-hash="fileHash"
:context-lines-path="contextLinesPath"
:line="line" :line="line"
:line-type="newLineType" :line-type="newLineType"
:line-position="linePositionRight" :line-position="linePositionRight"
......
...@@ -93,17 +93,17 @@ export default { ...@@ -93,17 +93,17 @@ export default {
v-for="(line, index) in parallelDiffLines" v-for="(line, index) in parallelDiffLines"
> >
<parallel-diff-table-row <parallel-diff-table-row
:diff-file="diffFile" :file-hash="diffFile.fileHash"
:context-lines-path="diffFile.contextLinesPath"
:line="line" :line="line"
:is-bottom="index + 1 === diffLinesLength" :is-bottom="index + 1 === diffLinesLength"
:key="index" :key="index"
/> />
<parallel-diff-comment-row <parallel-diff-comment-row
v-if="shouldRenderCommentRow(line)" v-if="shouldRenderCommentRow(line)"
:key="line.left.lineCode || line.right.lineCode" :key="`dcr-${index}`"
:line="line" :line="line"
:diff-file="diffFile" :diff-file-hash="diffFile.fileHash"
:diff-lines="parallelDiffLines"
:line-index="index" :line-index="index"
/> />
</template> </template>
......
...@@ -57,4 +57,8 @@ export const getDiffFileDiscussions = (state, getters, rootState, rootGetters) = ...@@ -57,4 +57,8 @@ export const getDiffFileDiscussions = (state, getters, rootState, rootGetters) =
) || []; ) || [];
// prevent babel-plugin-rewire from generating an invalid default during karma∂ tests // prevent babel-plugin-rewire from generating an invalid default during karma∂ tests
export const getDiffFileByHash = state => fileHash =>
state.diffFiles.find(file => file.fileHash === fileHash);
// prevent babel-plugin-rewire from generating an invalid default during karma tests
export default () => {}; export default () => {};
import _ from 'underscore'; import _ from 'underscore';
function sortMetrics(metrics) { function sortMetrics(metrics) {
return _.chain(metrics).sortBy('title').sortBy('weight').value(); return _.chain(metrics)
.sortBy('title')
.sortBy('weight')
.value();
} }
function normalizeMetrics(metrics) { function normalizeMetrics(metrics) {
...@@ -39,7 +42,9 @@ export default class MonitoringStore { ...@@ -39,7 +42,9 @@ export default class MonitoringStore {
} }
storeEnvironmentsData(environmentsData = []) { storeEnvironmentsData(environmentsData = []) {
this.environmentsData = environmentsData; this.environmentsData = environmentsData.filter(
environment => !!environment.latest.last_deployment,
);
} }
getMetricsCount() { getMetricsCount() {
......
<script> <script>
import { mapState, mapActions } from 'vuex'; import { mapState, mapActions } from 'vuex';
import imageDiffHelper from '~/image_diff/helpers/index'; import imageDiffHelper from '~/image_diff/helpers/index';
import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils'; import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils';
import DiffFileHeader from '~/diffs/components/diff_file_header.vue'; import DiffFileHeader from '~/diffs/components/diff_file_header.vue';
import SkeletonLoadingContainer from '~/vue_shared/components/skeleton_loading_container.vue'; import SkeletonLoadingContainer from '~/vue_shared/components/skeleton_loading_container.vue';
import { trimFirstCharOfLineContent } from '~/diffs/store/utils'; import { trimFirstCharOfLineContent } from '~/diffs/store/utils';
export default { export default {
components: { components: {
DiffFileHeader, DiffFileHeader,
SkeletonLoadingContainer, SkeletonLoadingContainer,
},
props: {
discussion: {
type: Object,
required: true,
}, },
props: { },
discussion: { data() {
type: Object, return {
required: true, error: false,
}, };
},
computed: {
...mapState({
noteableData: state => state.notes.noteableData,
}),
hasTruncatedDiffLines() {
return this.discussion.truncatedDiffLines && this.discussion.truncatedDiffLines.length !== 0;
}, },
data() { isDiscussionsExpanded() {
return { return true; // TODO: @fatihacet - Fix this.
error: false,
};
}, },
computed: { isCollapsed() {
...mapState({ return this.diffFile.collapsed || false;
noteableData: state => state.notes.noteableData, },
}), isImageDiff() {
hasTruncatedDiffLines() { return !this.diffFile.text;
return this.discussion.truncatedDiffLines && },
this.discussion.truncatedDiffLines.length !== 0; diffFileClass() {
}, const { text } = this.diffFile;
isDiscussionsExpanded() { return text ? 'text-file' : 'js-image-file';
return true; // TODO: @fatihacet - Fix this. },
}, diffFile() {
isCollapsed() { return convertObjectPropsToCamelCase(this.discussion.diffFile, { deep: true });
return this.diffFile.collapsed || false;
},
isImageDiff() {
return !this.diffFile.text;
},
diffFileClass() {
const { text } = this.diffFile;
return text ? 'text-file' : 'js-image-file';
},
diffFile() {
return convertObjectPropsToCamelCase(this.discussion.diffFile, { deep: true });
},
imageDiffHtml() {
return this.discussion.imageDiffHtml;
},
currentUser() {
return this.noteableData.current_user;
},
userColorScheme() {
return window.gon.user_color_scheme;
},
normalizedDiffLines() {
if (this.discussion.truncatedDiffLines) {
return this.discussion.truncatedDiffLines.map(line =>
trimFirstCharOfLineContent(convertObjectPropsToCamelCase(line)),
);
}
return [];
},
}, },
mounted() { imageDiffHtml() {
if (this.isImageDiff) { return this.discussion.imageDiffHtml;
const canCreateNote = false; },
const renderCommentBadge = true; userColorScheme() {
imageDiffHelper.initImageDiff(this.$refs.fileHolder, canCreateNote, renderCommentBadge); return window.gon.user_color_scheme;
} else if (!this.hasTruncatedDiffLines) { },
this.fetchDiff(); normalizedDiffLines() {
if (this.discussion.truncatedDiffLines) {
return this.discussion.truncatedDiffLines.map(line =>
trimFirstCharOfLineContent(convertObjectPropsToCamelCase(line)),
);
} }
return [];
},
},
mounted() {
if (this.isImageDiff) {
const canCreateNote = false;
const renderCommentBadge = true;
imageDiffHelper.initImageDiff(this.$refs.fileHolder, canCreateNote, renderCommentBadge);
} else if (!this.hasTruncatedDiffLines) {
this.fetchDiff();
}
},
methods: {
...mapActions(['fetchDiscussionDiffLines']),
rowTag(html) {
return html.outerHTML ? 'tr' : 'template';
}, },
methods: { fetchDiff() {
...mapActions(['fetchDiscussionDiffLines']), this.error = false;
rowTag(html) { this.fetchDiscussionDiffLines(this.discussion)
return html.outerHTML ? 'tr' : 'template'; .then(this.highlight)
}, .catch(() => {
fetchDiff() { this.error = true;
this.error = false; });
this.fetchDiscussionDiffLines(this.discussion)
.then(this.highlight)
.catch(() => {
this.error = true;
});
},
}, },
}; },
};
</script> </script>
<template> <template>
...@@ -99,7 +95,7 @@ ...@@ -99,7 +95,7 @@
> >
<diff-file-header <diff-file-header
:diff-file="diffFile" :diff-file="diffFile"
:current-user="currentUser" :can-current-user-fork="false"
:discussions-expanded="isDiscussionsExpanded" :discussions-expanded="isDiscussionsExpanded"
:expanded="!isCollapsed" :expanded="!isCollapsed"
/> />
......
...@@ -175,6 +175,7 @@ export default { ...@@ -175,6 +175,7 @@ export default {
<span <span
:aria-label="stage.title" :aria-label="stage.title"
aria-hidden="true" aria-hidden="true"
class="no-pointer-events"
> >
<icon :name="borderlessIcon" /> <icon :name="borderlessIcon" />
</span> </span>
......
...@@ -128,7 +128,8 @@ table { ...@@ -128,7 +128,8 @@ table {
border-spacing: 0; border-spacing: 0;
} }
.tooltip { .tooltip,
.no-pointer-events {
// Fix bootstrap4 bug whereby tooltips flicker when they are hovered over their borders // Fix bootstrap4 bug whereby tooltips flicker when they are hovered over their borders
pointer-events: none; pointer-events: none;
} }
......
...@@ -251,6 +251,7 @@ module ApplicationSettingsHelper ...@@ -251,6 +251,7 @@ module ApplicationSettingsHelper
:user_oauth_applications, :user_oauth_applications,
:version_check_enabled, :version_check_enabled,
:allow_local_requests_from_hooks_and_services, :allow_local_requests_from_hooks_and_services,
:hide_third_party_offers,
:enforce_terms, :enforce_terms,
:terms, :terms,
:mirror_available :mirror_available
......
...@@ -4,6 +4,7 @@ module ClustersHelper ...@@ -4,6 +4,7 @@ module ClustersHelper
end end
def render_gcp_signup_offer def render_gcp_signup_offer
return if Gitlab::CurrentSettings.current_application_settings.hide_third_party_offers?
return unless show_gcp_signup_offer? return unless show_gcp_signup_offer?
content_tag :section, class: 'no-animate expanded' do content_tag :section, class: 'no-animate expanded' do
......
...@@ -8,7 +8,7 @@ module SubmoduleHelper ...@@ -8,7 +8,7 @@ module SubmoduleHelper
url = repository.submodule_url_for(ref, submodule_item.path) url = repository.submodule_url_for(ref, submodule_item.path)
if url == '.' || url == './' if url == '.' || url == './'
url = File.join(Gitlab.config.gitlab.url, @project.full_path) url = File.join(Gitlab.config.gitlab.url, repository.project.full_path)
end end
if url =~ %r{([^/:]+)/([^/]+(?:\.git)?)\Z} if url =~ %r{([^/:]+)/([^/]+(?:\.git)?)\Z}
...@@ -31,7 +31,7 @@ module SubmoduleHelper ...@@ -31,7 +31,7 @@ module SubmoduleHelper
[namespace_project_path(namespace, project), [namespace_project_path(namespace, project),
namespace_project_tree_path(namespace, project, submodule_item.id)] namespace_project_tree_path(namespace, project, submodule_item.id)]
elsif relative_self_url?(url) elsif relative_self_url?(url)
relative_self_links(url, submodule_item.id) relative_self_links(url, submodule_item.id, repository.project)
elsif github_dot_com_url?(url) elsif github_dot_com_url?(url)
standard_links('github.com', namespace, project, submodule_item.id) standard_links('github.com', namespace, project, submodule_item.id)
elsif gitlab_dot_com_url?(url) elsif gitlab_dot_com_url?(url)
...@@ -73,7 +73,7 @@ module SubmoduleHelper ...@@ -73,7 +73,7 @@ module SubmoduleHelper
[base, [base, '/tree/', commit].join('')] [base, [base, '/tree/', commit].join('')]
end end
def relative_self_links(url, commit) def relative_self_links(url, commit, project)
url.rstrip! url.rstrip!
# Map relative links to a namespace and project # Map relative links to a namespace and project
# For example: # For example:
...@@ -85,7 +85,7 @@ module SubmoduleHelper ...@@ -85,7 +85,7 @@ module SubmoduleHelper
namespace = components.pop.gsub(/^\.\.$/, '') namespace = components.pop.gsub(/^\.\.$/, '')
if namespace.empty? if namespace.empty?
namespace = @project.namespace.full_path namespace = project.namespace.full_path
end end
begin begin
......
...@@ -294,6 +294,7 @@ class ApplicationSetting < ActiveRecord::Base ...@@ -294,6 +294,7 @@ class ApplicationSetting < ActiveRecord::Base
gitaly_timeout_medium: 30, gitaly_timeout_medium: 30,
gitaly_timeout_default: 55, gitaly_timeout_default: 55,
allow_local_requests_from_hooks_and_services: false, allow_local_requests_from_hooks_and_services: false,
hide_third_party_offers: false,
mirror_available: true mirror_available: true
} }
end end
......
- application_setting = local_assigns.fetch(:application_setting)
= form_for application_setting, url: admin_application_settings_path, html: { class: 'fieldset-form' } do |f|
= form_errors(application_setting)
%fieldset
.form-group
.form-check
= f.check_box :hide_third_party_offers, class: 'form-check-input'
= f.label :hide_third_party_offers, class: 'form-check-label' do
Do not display offers from third parties within GitLab
= f.submit 'Save changes', class: "btn btn-success"
...@@ -325,5 +325,16 @@ ...@@ -325,5 +325,16 @@
.settings-content .settings-content
= render partial: 'repository_mirrors_form' = render partial: 'repository_mirrors_form'
%section.settings.as-third-party-offers.no-animate#js-third-party-offers-settings{ class: ('expanded' if expanded) }
.settings-header
%h4
= _('Third party offers')
%button.btn.btn-default.js-settings-toggle{ type: 'button' }
= expanded ? _('Collapse') : _('Expand')
%p
= _('Control the display of third party offers.')
.settings-content
= render 'third_party_offers', application_setting: @application_setting
= render_if_exists 'admin/application_settings/pseudonymizer_settings', expanded: expanded = render_if_exists 'admin/application_settings/pseudonymizer_settings', expanded: expanded
---
title: Add option to hide third party offers in admin application settings
merge_request: 20379
author:
type: added
class AddHideThirdPartyOffersToApplicationSettings < ActiveRecord::Migration
include Gitlab::Database::MigrationHelpers
DOWNTIME = false
disable_ddl_transaction!
def up
add_column_with_default(:application_settings, :hide_third_party_offers,
:boolean,
default: false,
allow_null: false)
end
def down
remove_column(:application_settings, :hide_third_party_offers)
end
end
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
# #
# It's strongly recommended that you check this file into your version control system. # It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 20180702120647) do ActiveRecord::Schema.define(version: 20180704204006) do
# These are extensions that must be enabled in order to support this database # These are extensions that must be enabled in order to support this database
enable_extension "plpgsql" enable_extension "plpgsql"
...@@ -167,6 +167,7 @@ ActiveRecord::Schema.define(version: 20180702120647) do ...@@ -167,6 +167,7 @@ ActiveRecord::Schema.define(version: 20180702120647) do
t.boolean "allow_local_requests_from_hooks_and_services", default: false, null: false t.boolean "allow_local_requests_from_hooks_and_services", default: false, null: false
t.boolean "enforce_terms", default: false t.boolean "enforce_terms", default: false
t.boolean "mirror_available", default: true, null: false t.boolean "mirror_available", default: true, null: false
t.boolean "hide_third_party_offers", default: false, null: false
end end
create_table "audit_events", force: :cascade do |t| create_table "audit_events", force: :cascade do |t|
......
...@@ -45,6 +45,7 @@ Learn how to install, configure, update, and maintain your GitLab instance. ...@@ -45,6 +45,7 @@ Learn how to install, configure, update, and maintain your GitLab instance.
- [Environment variables](environment_variables.md): Supported environment variables that can be used to override their defaults values in order to configure GitLab. - [Environment variables](environment_variables.md): Supported environment variables that can be used to override their defaults values in order to configure GitLab.
- [Plugins](plugins.md): With custom plugins, GitLab administrators can introduce custom integrations without modifying GitLab's source code. - [Plugins](plugins.md): With custom plugins, GitLab administrators can introduce custom integrations without modifying GitLab's source code.
- [Enforcing Terms of Service](../user/admin_area/settings/terms.md) - [Enforcing Terms of Service](../user/admin_area/settings/terms.md)
- [Third party offers](../user/admin_area/settings/third_party_offers.md)
#### Customizing GitLab's appearance #### Customizing GitLab's appearance
......
# Third party offers
> [Introduced](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/20379)
> in [GitLab Core](https://about.gitlab.com/pricing/) 11.1
The display of third party offers can be controlled in the Admin Area -> Settings page.
This diff is collapsed.
...@@ -272,6 +272,16 @@ describe 'Admin updates settings' do ...@@ -272,6 +272,16 @@ describe 'Admin updates settings' do
expect(Gitlab::CurrentSettings.allow_local_requests_from_hooks_and_services).to be true expect(Gitlab::CurrentSettings.allow_local_requests_from_hooks_and_services).to be true
end end
it 'Enable hiding third party offers' do
page.within('.as-third-party-offers') do
check 'Do not display offers from third parties within GitLab'
click_button 'Save changes'
end
expect(page).to have_content "Application settings saved successfully"
expect(Gitlab::CurrentSettings.hide_third_party_offers).to be true
end
it 'Change Slack Notifications Service template settings' do it 'Change Slack Notifications Service template settings' do
first(:link, 'Service Templates').click first(:link, 'Service Templates').click
click_link 'Slack notifications' click_link 'Slack notifications'
......
...@@ -92,11 +92,10 @@ describe SubmoduleHelper do ...@@ -92,11 +92,10 @@ describe SubmoduleHelper do
context 'in-repository submodule' do context 'in-repository submodule' do
let(:group) { create(:group, name: "Master Project", path: "master-project") } let(:group) { create(:group, name: "Master Project", path: "master-project") }
let(:project) { create(:project, group: group) } let(:project) { create(:project, group: group) }
before do
self.instance_variable_set(:@project, project)
end
it 'in-repository' do it 'in-repository' do
allow(repo).to receive(:project).and_return(project)
stub_url('./') stub_url('./')
expect(submodule_links(submodule_item)).to eq(["/master-project/#{project.path}", "/master-project/#{project.path}/tree/hash"]) expect(submodule_links(submodule_item)).to eq(["/master-project/#{project.path}", "/master-project/#{project.path}/tree/hash"])
end end
...@@ -167,32 +166,28 @@ describe SubmoduleHelper do ...@@ -167,32 +166,28 @@ describe SubmoduleHelper do
let(:project) { create(:project, group: group) } let(:project) { create(:project, group: group) }
let(:commit_id) { sample_commit[:id] } let(:commit_id) { sample_commit[:id] }
before do
self.instance_variable_set(:@project, project)
end
it 'one level down' do it 'one level down' do
result = relative_self_links('../test.git', commit_id) result = relative_self_links('../test.git', commit_id, project)
expect(result).to eq(["/#{group.path}/test", "/#{group.path}/test/tree/#{commit_id}"]) expect(result).to eq(["/#{group.path}/test", "/#{group.path}/test/tree/#{commit_id}"])
end end
it 'with trailing whitespace' do it 'with trailing whitespace' do
result = relative_self_links('../test.git ', commit_id) result = relative_self_links('../test.git ', commit_id, project)
expect(result).to eq(["/#{group.path}/test", "/#{group.path}/test/tree/#{commit_id}"]) expect(result).to eq(["/#{group.path}/test", "/#{group.path}/test/tree/#{commit_id}"])
end end
it 'two levels down' do it 'two levels down' do
result = relative_self_links('../../test.git', commit_id) result = relative_self_links('../../test.git', commit_id, project)
expect(result).to eq(["/#{group.path}/test", "/#{group.path}/test/tree/#{commit_id}"]) expect(result).to eq(["/#{group.path}/test", "/#{group.path}/test/tree/#{commit_id}"])
end end
it 'one level down with namespace and repo' do it 'one level down with namespace and repo' do
result = relative_self_links('../foobar/test.git', commit_id) result = relative_self_links('../foobar/test.git', commit_id, project)
expect(result).to eq(["/foobar/test", "/foobar/test/tree/#{commit_id}"]) expect(result).to eq(["/foobar/test", "/foobar/test/tree/#{commit_id}"])
end end
it 'two levels down with namespace and repo' do it 'two levels down with namespace and repo' do
result = relative_self_links('../foobar/baz/test.git', commit_id) result = relative_self_links('../foobar/baz/test.git', commit_id, project)
expect(result).to eq(["/baz/test", "/baz/test/tree/#{commit_id}"]) expect(result).to eq(["/baz/test", "/baz/test/tree/#{commit_id}"])
end end
...@@ -201,7 +196,7 @@ describe SubmoduleHelper do ...@@ -201,7 +196,7 @@ describe SubmoduleHelper do
let(:project) { create(:project, namespace: user.namespace) } let(:project) { create(:project, namespace: user.namespace) }
it 'one level down with personal project' do it 'one level down with personal project' do
result = relative_self_links('../test.git', commit_id) result = relative_self_links('../test.git', commit_id, project)
expect(result).to eq(["/#{user.username}/test", "/#{user.username}/test/tree/#{commit_id}"]) expect(result).to eq(["/#{user.username}/test", "/#{user.username}/test/tree/#{commit_id}"])
end end
end end
......
...@@ -24,7 +24,7 @@ describe('diff_file_header', () => { ...@@ -24,7 +24,7 @@ describe('diff_file_header', () => {
const diffFile = convertObjectPropsToCamelCase(diffDiscussionMock.diff_file, { deep: true }); const diffFile = convertObjectPropsToCamelCase(diffDiscussionMock.diff_file, { deep: true });
props = { props = {
diffFile, diffFile,
currentUser: {}, canCurrentUserFork: false,
}; };
}); });
......
...@@ -11,7 +11,7 @@ describe('DiffFile', () => { ...@@ -11,7 +11,7 @@ describe('DiffFile', () => {
beforeEach(() => { beforeEach(() => {
vm = createComponentWithStore(Vue.extend(DiffFileComponent), store, { vm = createComponentWithStore(Vue.extend(DiffFileComponent), store, {
file: getDiffFileMock(), file: getDiffFileMock(),
currentUser: {}, canCurrentUserFork: false,
}).$mount(); }).$mount();
}); });
......
...@@ -15,7 +15,7 @@ describe('DiffLineNoteForm', () => { ...@@ -15,7 +15,7 @@ describe('DiffLineNoteForm', () => {
diffLines = diffFile.highlightedDiffLines; diffLines = diffFile.highlightedDiffLines;
component = createComponentWithStore(Vue.extend(DiffLineNoteForm), store, { component = createComponentWithStore(Vue.extend(DiffLineNoteForm), store, {
diffFile, diffFileHash: diffFile.fileHash,
diffLines, diffLines,
line: diffLines[0], line: diffLines[0],
noteTargetLine: diffLines[0], noteTargetLine: diffLines[0],
......
...@@ -184,4 +184,23 @@ describe('Diffs Module Getters', () => { ...@@ -184,4 +184,23 @@ describe('Diffs Module Getters', () => {
).toEqual(0); ).toEqual(0);
}); });
}); });
describe('getDiffFileByHash', () => {
it('returns file by hash', () => {
const fileA = {
fileHash: '123',
};
const fileB = {
fileHash: '456',
};
localState.diffFiles = [fileA, fileB];
expect(getters.getDiffFileByHash(localState)('456')).toEqual(fileB);
});
it('returns null if no matching file is found', () => {
localState.diffFiles = [];
expect(getters.getDiffFileByHash(localState)('123')).toBeUndefined();
});
});
}); });
...@@ -6561,6 +6561,9 @@ export const environmentData = [ ...@@ -6561,6 +6561,9 @@ export const environmentData = [
folder_path: '/root/hello-prometheus/environments/folders/production', folder_path: '/root/hello-prometheus/environments/folders/production',
created_at: '2018-06-29T16:53:38.301Z', created_at: '2018-06-29T16:53:38.301Z',
updated_at: '2018-06-29T16:57:09.825Z', updated_at: '2018-06-29T16:57:09.825Z',
last_deployment: {
id: 127,
},
}, },
}, },
{ {
...@@ -6580,6 +6583,20 @@ export const environmentData = [ ...@@ -6580,6 +6583,20 @@ export const environmentData = [
folder_path: '/root/hello-prometheus/environments/folders/review', folder_path: '/root/hello-prometheus/environments/folders/review',
created_at: '2018-07-03T18:39:41.702Z', created_at: '2018-07-03T18:39:41.702Z',
updated_at: '2018-07-03T18:44:54.010Z', updated_at: '2018-07-03T18:44:54.010Z',
last_deployment: {
id: 128,
},
},
},
{
name: 'no-deployment',
size: 1,
latest: {
id: 36,
name: 'no-deployment/noop-branch',
state: 'available',
created_at: '2018-07-04T18:39:41.702Z',
updated_at: '2018-07-04T18:44:54.010Z',
}, },
}, },
]; ];
import MonitoringStore from '~/monitoring/stores/monitoring_store'; import MonitoringStore from '~/monitoring/stores/monitoring_store';
import MonitoringMock, { deploymentData } from './mock_data'; import MonitoringMock, { deploymentData, environmentData } from './mock_data';
describe('MonitoringStore', function () { describe('MonitoringStore', function () {
this.store = new MonitoringStore(); this.store = new MonitoringStore();
...@@ -21,4 +21,9 @@ describe('MonitoringStore', function () { ...@@ -21,4 +21,9 @@ describe('MonitoringStore', function () {
expect(this.store.deploymentData.length).toEqual(3); expect(this.store.deploymentData.length).toEqual(3);
expect(typeof this.store.deploymentData[0]).toEqual('object'); expect(typeof this.store.deploymentData[0]).toEqual('object');
}); });
it('only stores environment data that contains deployments', () => {
this.store.storeEnvironmentsData(environmentData);
expect(this.store.environmentsData.length).toEqual(2);
});
}); });
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment