summaryrefslogtreecommitdiff
path: root/app/assets
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2020-04-09 15:09:29 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2020-04-09 15:09:29 +0000
commit209bd8cf1f542f6ba2a069b368a9187faa871e96 (patch)
tree6b77dc8183135b8316cc70c8dbc9c4e7c18cf05a /app/assets
parenta9ced7da447785c57477b3d8dbccc73a78cface1 (diff)
downloadgitlab-ce-209bd8cf1f542f6ba2a069b368a9187faa871e96.tar.gz
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app/assets')
-rw-r--r--app/assets/javascripts/diffs/store/mutations.js1
-rw-r--r--app/assets/javascripts/header.js19
-rw-r--r--app/assets/javascripts/helpers/monitor_helper.js80
-rw-r--r--app/assets/javascripts/monitoring/components/charts/bar.vue2
-rw-r--r--app/assets/javascripts/monitoring/components/charts/column.vue2
-rw-r--r--app/assets/javascripts/monitoring/components/charts/time_series.vue2
-rw-r--r--app/assets/javascripts/monitoring/stores/utils.js5
-rw-r--r--app/assets/javascripts/repository/router.js2
-rw-r--r--app/assets/javascripts/static_site_editor/components/publish_toolbar.vue23
-rw-r--r--app/assets/javascripts/static_site_editor/components/static_site_editor.vue19
-rw-r--r--app/assets/javascripts/static_site_editor/store/actions.js4
-rw-r--r--app/assets/javascripts/static_site_editor/store/getters.js4
-rw-r--r--app/assets/javascripts/static_site_editor/store/mutation_types.js1
-rw-r--r--app/assets/javascripts/static_site_editor/store/mutations.js4
-rw-r--r--app/assets/javascripts/static_site_editor/store/state.js2
15 files changed, 141 insertions, 29 deletions
diff --git a/app/assets/javascripts/diffs/store/mutations.js b/app/assets/javascripts/diffs/store/mutations.js
index 3c00ae98e75..cc9bfa2e174 100644
--- a/app/assets/javascripts/diffs/store/mutations.js
+++ b/app/assets/javascripts/diffs/store/mutations.js
@@ -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;
diff --git a/app/assets/javascripts/header.js b/app/assets/javascripts/header.js
index fdd27e08793..1678991b1ea 100644
--- a/app/assets/javascripts/header.js
+++ b/app/assets/javascripts/header.js
@@ -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();
});
diff --git a/app/assets/javascripts/helpers/monitor_helper.js b/app/assets/javascripts/helpers/monitor_helper.js
index 87b4b14f6bf..94a0d38f05f 100644
--- a/app/assets/javascripts/helpers/monitor_helper.js
+++ b/app/assets/javascripts/helpers/monitor_helper.js
@@ -1,4 +1,64 @@
/**
+ * @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)
* @returns {Array} The formatted values
@@ -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);
diff --git a/app/assets/javascripts/monitoring/components/charts/bar.vue b/app/assets/javascripts/monitoring/components/charts/bar.vue
index 01fd8940dad..e1018cd5952 100644
--- a/app/assets/javascripts/monitoring/components/charts/bar.vue
+++ b/app/assets/javascripts/monitoring/components/charts/bar.vue
@@ -58,7 +58,7 @@ export default {
},
methods: {
formatLegendLabel(query) {
- return `${query.label}`;
+ return query.label;
},
onResize() {
if (!this.$refs.barChart) return;
diff --git a/app/assets/javascripts/monitoring/components/charts/column.vue b/app/assets/javascripts/monitoring/components/charts/column.vue
index 0ed801e6e57..7a2e3e1b511 100644
--- a/app/assets/javascripts/monitoring/components/charts/column.vue
+++ b/app/assets/javascripts/monitoring/components/charts/column.vue
@@ -76,7 +76,7 @@ export default {
},
methods: {
formatLegendLabel(query) {
- return `${query.label}`;
+ return query.label;
},
onResize() {
if (!this.$refs.columnChart) return;
diff --git a/app/assets/javascripts/monitoring/components/charts/time_series.vue b/app/assets/javascripts/monitoring/components/charts/time_series.vue
index e43a0131528..f4cd6bbbb34 100644
--- a/app/assets/javascripts/monitoring/components/charts/time_series.vue
+++ b/app/assets/javascripts/monitoring/components/charts/time_series.vue
@@ -251,7 +251,7 @@ export default {
},
methods: {
formatLegendLabel(query) {
- return `${query.label}`;
+ return query.label;
},
isTooltipOfType(tooltipType, defaultType) {
return tooltipType === defaultType;
diff --git a/app/assets/javascripts/monitoring/stores/utils.js b/app/assets/javascripts/monitoring/stores/utils.js
index 5e620d6c2f5..d01acdd031b 100644
--- a/app/assets/javascripts/monitoring/stores/utils.js
+++ b/app/assets/javascripts/monitoring/stores/utils.js
@@ -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 }),
diff --git a/app/assets/javascripts/repository/router.js b/app/assets/javascripts/repository/router.js
index d74447dd566..b2636f910fe 100644
--- a/app/assets/javascripts/repository/router.js
+++ b/app/assets/javascripts/repository/router.js
@@ -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 => ({
diff --git a/app/assets/javascripts/static_site_editor/components/publish_toolbar.vue b/app/assets/javascripts/static_site_editor/components/publish_toolbar.vue
new file mode 100644
index 00000000000..83b50b2f8eb
--- /dev/null
+++ b/app/assets/javascripts/static_site_editor/components/publish_toolbar.vue
@@ -0,0 +1,23 @@
+<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>
diff --git a/app/assets/javascripts/static_site_editor/components/static_site_editor.vue b/app/assets/javascripts/static_site_editor/components/static_site_editor.vue
index f06d48ee4f5..80a55d5ee11 100644
--- a/app/assets/javascripts/static_site_editor/components/static_site_editor.vue
+++ b/app/assets/javascripts/static_site_editor/components/static_site_editor.vue
@@ -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>
diff --git a/app/assets/javascripts/static_site_editor/store/actions.js b/app/assets/javascripts/static_site_editor/store/actions.js
index 192345f3749..141148de1e0 100644
--- a/app/assets/javascripts/static_site_editor/store/actions.js
+++ b/app/assets/javascripts/static_site_editor/store/actions.js
@@ -15,4 +15,8 @@ export const loadContent = ({ commit, state: { sourcePath, projectId } }) => {
});
};
+export const setContent = ({ commit }, content) => {
+ commit(mutationTypes.SET_CONTENT, content);
+};
+
export default () => {};
diff --git a/app/assets/javascripts/static_site_editor/store/getters.js b/app/assets/javascripts/static_site_editor/store/getters.js
index 8baa2941594..41256201c26 100644
--- a/app/assets/javascripts/static_site_editor/store/getters.js
+++ b/app/assets/javascripts/static_site_editor/store/getters.js
@@ -1,2 +1,2 @@
-// 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;
diff --git a/app/assets/javascripts/static_site_editor/store/mutation_types.js b/app/assets/javascripts/static_site_editor/store/mutation_types.js
index cbe51180541..2bb201f5d24 100644
--- a/app/assets/javascripts/static_site_editor/store/mutation_types.js
+++ b/app/assets/javascripts/static_site_editor/store/mutation_types.js
@@ -1,3 +1,4 @@
export const LOAD_CONTENT = 'loadContent';
export const RECEIVE_CONTENT_SUCCESS = 'receiveContentSuccess';
export const RECEIVE_CONTENT_ERROR = 'receiveContentError';
+export const SET_CONTENT = 'setContent';
diff --git a/app/assets/javascripts/static_site_editor/store/mutations.js b/app/assets/javascripts/static_site_editor/store/mutations.js
index 88cb74d2b11..8b8bacf35c2 100644
--- a/app/assets/javascripts/static_site_editor/store/mutations.js
+++ b/app/assets/javascripts/static_site_editor/store/mutations.js
@@ -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;
+ },
};
diff --git a/app/assets/javascripts/static_site_editor/store/state.js b/app/assets/javascripts/static_site_editor/store/state.js
index b68e73f06f5..1ae11b3343d 100644
--- a/app/assets/javascripts/static_site_editor/store/state.js
+++ b/app/assets/javascripts/static_site_editor/store/state.js
@@ -3,7 +3,9 @@ const createState = (initialState = {}) => ({
sourcePath: null,
isLoadingContent: false,
+ isSavingChanges: false,
+ originalContent: '',
content: '',
title: '',