Read about our upcoming Code of Conduct on this issue

Commit 12b496db authored by GitLab Bot's avatar GitLab Bot
Browse files

Add latest changes from gitlab-org/gitlab@master

parent ba340728d0f2
......@@ -326,6 +326,7 @@ export default {
},
[types.SET_SHOW_WHITESPACE](state, showWhitespace) {
state.showWhitespace = showWhitespace;
state.diffFiles = [];
},
[types.TOGGLE_FILE_FINDER_VISIBLE](state, visible) {
state.fileFinderVisible = visible;
......
......@@ -5,6 +5,7 @@ import { highCountTrim } from '~/lib/utils/text_utility';
import SetStatusModalTrigger from './set_status_modal/set_status_modal_trigger.vue';
import SetStatusModalWrapper from './set_status_modal/set_status_modal_wrapper.vue';
import { parseBoolean } from '~/lib/utils/common_utils';
import Tracking from '~/tracking';
/**
* Updates todo counter when todos are toggled.
......@@ -73,6 +74,24 @@ function initStatusTriggers() {
}
}
export function initNavUserDropdownTracking() {
const el = document.querySelector('.js-nav-user-dropdown');
const buyEl = document.querySelector('.js-buy-ci-minutes-link');
if (el && buyEl) {
const { trackLabel, trackProperty } = buyEl.dataset;
const trackEvent = 'show_buy_ci_minutes';
$(el).on('shown.bs.dropdown', () => {
Tracking.event(undefined, trackEvent, {
label: trackLabel,
property: trackProperty,
});
});
}
}
document.addEventListener('DOMContentLoaded', () => {
requestIdleCallback(initStatusTriggers);
initNavUserDropdownTracking();
});
/**
* @param {String} queryLabel - Default query label for chart
* @param {Object} metricAttributes - Default metric attribute values (e.g. method, instance)
* @returns {String} The formatted query label
* @example
* singleAttributeLabel('app', {__name__: "up", app: "prometheus"}) -> "app: prometheus"
*/
const singleAttributeLabel = (queryLabel, metricAttributes) => {
if (!queryLabel) return '';
const relevantAttribute = queryLabel.toLowerCase().replace(' ', '_');
const value = metricAttributes[relevantAttribute];
if (!value) return '';
return `${queryLabel}: ${value}`;
};
/**
* @param {String} queryLabel - Default query label for chart
* @param {Object} metricAttributes - Default metric attribute values (e.g. method, instance)
* @returns {String} The formatted query label
* @example
* templatedLabel('__name__', {__name__: "up", app: "prometheus"}) -> "__name__"
*/
const templatedLabel = (queryLabel, metricAttributes) => {
if (!queryLabel) return '';
// eslint-disable-next-line array-callback-return
Object.entries(metricAttributes).map(([templateVar, label]) => {
const regex = new RegExp(`{{\\s*${templateVar}\\s*}}`, 'g');
// eslint-disable-next-line no-param-reassign
queryLabel = queryLabel.replace(regex, label);
});
return queryLabel;
};
/**
* @param {Object} metricAttributes - Default metric attribute values (e.g. method, instance)
* @returns {String} The formatted query label
* @example
* multiMetricLabel('', {__name__: "up", app: "prometheus"}) -> "__name__: up, app: prometheus"
*/
const multiMetricLabel = metricAttributes => {
return Object.entries(metricAttributes)
.map(([templateVar, label]) => `${templateVar}: ${label}`)
.join(', ');
};
/**
* @param {String} queryLabel - Default query label for chart
* @param {Object} metricAttributes - Default metric attribute values (e.g. method, instance)
* @returns {String} The formatted query label
*/
const getSeriesLabel = (queryLabel, metricAttributes) => {
return (
singleAttributeLabel(queryLabel, metricAttributes) ||
templatedLabel(queryLabel, metricAttributes) ||
multiMetricLabel(metricAttributes) ||
queryLabel
);
};
/**
* @param {Array} queryResults - Array of Result objects
* @param {Object} defaultConfig - Default chart config values (e.g. lineStyle, name)
......@@ -12,21 +72,11 @@ export const makeDataSeries = (queryResults, defaultConfig) =>
if (!data.length) {
return null;
}
const relevantMetric = defaultConfig.name.toLowerCase().replace(' ', '_');
const name = result.metric[relevantMetric];
const series = { data };
if (name) {
series.name = `${defaultConfig.name}: ${name}`;
} else {
series.name = defaultConfig.name;
Object.keys(result.metric).forEach(templateVar => {
const value = result.metric[templateVar];
const regex = new RegExp(`{{\\s*${templateVar}\\s*}}`, 'g');
series.name = series.name.replace(regex, value);
});
}
return { ...defaultConfig, ...series };
return {
...defaultConfig,
...series,
name: getSeriesLabel(defaultConfig.name, result.metric),
};
})
.filter(series => series !== null);
......@@ -58,7 +58,7 @@ export default {
},
methods: {
formatLegendLabel(query) {
return `${query.label}`;
return query.label;
},
onResize() {
if (!this.$refs.barChart) return;
......
......@@ -76,7 +76,7 @@ export default {
},
methods: {
formatLegendLabel(query) {
return `${query.label}`;
return query.label;
},
onResize() {
if (!this.$refs.columnChart) return;
......
......@@ -251,7 +251,7 @@ export default {
},
methods: {
formatLegendLabel(query) {
return `${query.label}`;
return query.label;
},
isTooltipOfType(tooltipType, defaultType) {
return tooltipType === defaultType;
......
......@@ -68,12 +68,11 @@ export const parseEnvironmentsResponse = (response = [], projectPath) =>
* https://gitlab.com/gitlab-org/gitlab/issues/207198
*
* @param {Array} metrics - Array of prometheus metrics
* @param {String} defaultLabel - Default label for metrics
* @returns {Object}
*/
const mapToMetricsViewModel = (metrics, defaultLabel) =>
const mapToMetricsViewModel = metrics =>
metrics.map(({ label, id, metric_id, query_range, prometheus_endpoint_path, ...metric }) => ({
label: label || defaultLabel,
label,
queryRange: query_range,
prometheusEndpointPath: prometheus_endpoint_path,
metricId: uniqMetricsId({ metric_id, id }),
......
......@@ -12,7 +12,7 @@ export default function createRouter(base, baseRef) {
base: joinPaths(gon.relative_url_root || '', base),
routes: [
{
path: `(/-)?/tree/(${encodeURIComponent(baseRef)}|${baseRef})/:path*`,
path: `(/-)?/tree/(${encodeURIComponent(baseRef).replace(/%2F/g, '/')}|${baseRef})/:path*`,
name: 'treePath',
component: TreePage,
props: route => ({
......
<script>
import { GlNewButton } from '@gitlab/ui';
export default {
components: {
GlNewButton,
},
props: {
saveable: {
type: Boolean,
required: false,
default: false,
},
},
};
</script>
<template>
<div class="d-flex bg-light border-top justify-content-between align-items-center py-3 px-4">
<gl-new-button variant="success" :disabled="!saveable">
{{ __('Submit Changes') }}
</gl-new-button>
</div>
</template>
......@@ -3,27 +3,29 @@ import { mapState, mapGetters, mapActions } from 'vuex';
import { GlSkeletonLoader } from '@gitlab/ui';
import EditArea from './edit_area.vue';
import Toolbar from './publish_toolbar.vue';
export default {
components: {
EditArea,
GlSkeletonLoader,
Toolbar,
},
computed: {
...mapState(['content', 'isLoadingContent']),
...mapGetters(['isContentLoaded']),
...mapGetters(['isContentLoaded', 'contentChanged']),
},
mounted() {
this.loadContent();
},
methods: {
...mapActions(['loadContent']),
...mapActions(['loadContent', 'setContent']),
},
};
</script>
<template>
<div class="d-flex justify-content-center h-100">
<div v-if="isLoadingContent" class="w-50 h-50 mt-2">
<div class="d-flex justify-content-center h-100 pt-2">
<div v-if="isLoadingContent" class="w-50 h-50">
<gl-skeleton-loader :width="500" :height="102">
<rect width="500" height="16" rx="4" />
<rect y="20" width="375" height="16" rx="4" />
......@@ -33,6 +35,13 @@ export default {
<rect x="410" y="40" width="90" height="16" rx="4" />
</gl-skeleton-loader>
</div>
<edit-area v-if="isContentLoaded" class="w-75 h-100 shadow-none" :value="content" />
<div v-if="isContentLoaded" class="d-flex flex-grow-1 flex-column">
<edit-area
class="w-75 h-100 shadow-none align-self-center"
:value="content"
@input="setContent"
/>
<toolbar :saveable="contentChanged" />
</div>
</div>
</template>
......@@ -15,4 +15,8 @@ export const loadContent = ({ commit, state: { sourcePath, projectId } }) => {
});
};
export const setContent = ({ commit }, content) => {
commit(mutationTypes.SET_CONTENT, content);
};
export default () => {};
// eslint-disable-next-line import/prefer-default-export
export const isContentLoaded = ({ content }) => Boolean(content);
export const isContentLoaded = ({ originalContent }) => Boolean(originalContent);
export const contentChanged = ({ originalContent, content }) => originalContent !== content;
export const LOAD_CONTENT = 'loadContent';
export const RECEIVE_CONTENT_SUCCESS = 'receiveContentSuccess';
export const RECEIVE_CONTENT_ERROR = 'receiveContentError';
export const SET_CONTENT = 'setContent';
......@@ -8,8 +8,12 @@ export default {
state.isLoadingContent = false;
state.title = title;
state.content = content;
state.originalContent = content;
},
[types.RECEIVE_CONTENT_ERROR](state) {
state.isLoadingContent = false;
},
[types.SET_CONTENT](state, content) {
state.content = content;
},
};
......@@ -3,7 +3,9 @@ const createState = (initialState = {}) => ({
sourcePath: null,
isLoadingContent: false,
isSavingChanges: false,
originalContent: '',
content: '',
title: '',
......
......@@ -67,7 +67,6 @@ def from_previous_stages(scope)
end
def from_needs(scope)
return scope unless Feature.enabled?(:ci_dag_support, project, default_enabled: true)
return scope unless processable.scheduling_type_dag?
needs_names = processable.needs.artifacts.select(:name)
......
......@@ -25,8 +25,6 @@ class Processable < ::CommitStatus
end
def self.select_with_aggregated_needs(project)
return all unless Feature.enabled?(:ci_dag_support, project, default_enabled: true)
aggregated_needs_names = Ci::BuildNeed
.scoped_build
.select("ARRAY_AGG(name)")
......
......@@ -555,22 +555,28 @@ def discussions_diffs
end
end
def diff_stats
return unless diff_refs
strong_memoize(:diff_stats) do
project.repository.diff_stats(diff_refs.base_sha, diff_refs.head_sha)
end
end
def diff_size
# Calling `merge_request_diff.diffs.real_size` will also perform
# highlighting, which we don't need here.
merge_request_diff&.real_size || diffs.real_size
merge_request_diff&.real_size || diff_stats&.real_size || diffs.real_size
end
def modified_paths(past_merge_request_diff: nil)
diffs = if past_merge_request_diff
past_merge_request_diff
elsif compare
compare
else
self.merge_request_diff
end
diffs.modified_paths
if past_merge_request_diff
past_merge_request_diff.modified_paths
elsif compare
diff_stats&.paths || compare.modified_paths
else
merge_request_diff.modified_paths
end
end
def new_paths
......
......@@ -267,7 +267,7 @@ def repository
def repository_size_checker
strong_memoize(:repository_size_checker) do
::Gitlab::RepositorySizeChecker.new(
current_size_proc: -> { repository._uncached_size.megabytes },
current_size_proc: -> { repository.size.megabytes },
limit: Gitlab::CurrentSettings.snippet_size_limit
)
end
......
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