summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2020-02-27 00:09:19 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2020-02-27 00:09:19 +0000
commit0a0e82d1440b06650e5fc524168b1f50a8feec68 (patch)
treec2202560fb250008cf4109e99537b10604faf01b /app
parentf82d5dcab7c3d9a672abc827c92f86887b683a7d (diff)
downloadgitlab-ce-0a0e82d1440b06650e5fc524168b1f50a8feec68.tar.gz
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app')
-rw-r--r--app/assets/javascripts/boards/models/issue.js31
-rw-r--r--app/assets/javascripts/boards/stores/boards_store.js36
-rw-r--r--app/assets/javascripts/monitoring/components/dashboard.vue2
-rw-r--r--app/assets/javascripts/monitoring/components/embed.vue4
-rw-r--r--app/assets/javascripts/monitoring/stores/actions.js18
-rw-r--r--app/assets/javascripts/monitoring/stores/getters.js4
-rw-r--r--app/assets/javascripts/monitoring/stores/mutations.js37
-rw-r--r--app/assets/javascripts/monitoring/stores/state.js2
-rw-r--r--app/assets/javascripts/monitoring/stores/utils.js90
-rw-r--r--app/assets/javascripts/monitoring/utils.js2
-rw-r--r--app/controllers/groups/registry/repositories_controller.rb2
-rw-r--r--app/controllers/projects/registry/repositories_controller.rb2
-rw-r--r--app/views/projects/registry/repositories/index.html.haml2
13 files changed, 138 insertions, 94 deletions
diff --git a/app/assets/javascripts/boards/models/issue.js b/app/assets/javascripts/boards/models/issue.js
index 0e86359534b..4f5d583e61f 100644
--- a/app/assets/javascripts/boards/models/issue.js
+++ b/app/assets/javascripts/boards/models/issue.js
@@ -26,36 +26,7 @@ class ListIssue {
}
refreshData(obj, defaultAvatar) {
- this.id = obj.id;
- this.iid = obj.iid;
- this.title = obj.title;
- this.confidential = obj.confidential;
- this.dueDate = obj.due_date;
- this.sidebarInfoEndpoint = obj.issue_sidebar_endpoint;
- this.referencePath = obj.reference_path;
- this.path = obj.real_path;
- this.toggleSubscriptionEndpoint = obj.toggle_subscription_endpoint;
- this.project_id = obj.project_id;
- this.timeEstimate = obj.time_estimate;
- this.assignableLabelsEndpoint = obj.assignable_labels_endpoint;
- this.blocked = obj.blocked;
-
- if (obj.project) {
- this.project = new IssueProject(obj.project);
- }
-
- if (obj.milestone) {
- this.milestone = new ListMilestone(obj.milestone);
- this.milestone_id = obj.milestone.id;
- }
-
- if (obj.labels) {
- this.labels = obj.labels.map(label => new ListLabel(label));
- }
-
- if (obj.assignees) {
- this.assignees = obj.assignees.map(a => new ListAssignee(a, defaultAvatar));
- }
+ boardsStore.refreshIssueData(this, obj, defaultAvatar);
}
addLabel(label) {
diff --git a/app/assets/javascripts/boards/stores/boards_store.js b/app/assets/javascripts/boards/stores/boards_store.js
index f233228614f..010eda9b6c5 100644
--- a/app/assets/javascripts/boards/stores/boards_store.js
+++ b/app/assets/javascripts/boards/stores/boards_store.js
@@ -12,6 +12,10 @@ import axios from '~/lib/utils/axios_utils';
import { mergeUrlParams } from '~/lib/utils/url_utility';
import eventHub from '../eventhub';
import { ListType } from '../constants';
+import IssueProject from '../models/project';
+import ListLabel from '../models/label';
+import ListAssignee from '../models/assignee';
+import ListMilestone from '../models/milestone';
const boardsStore = {
disabled: false,
@@ -593,6 +597,38 @@ const boardsStore = {
clearMultiSelect() {
this.multiSelect.list = [];
},
+ refreshIssueData(issue, obj, defaultAvatar) {
+ issue.id = obj.id;
+ issue.iid = obj.iid;
+ issue.title = obj.title;
+ issue.confidential = obj.confidential;
+ issue.dueDate = obj.due_date;
+ issue.sidebarInfoEndpoint = obj.issue_sidebar_endpoint;
+ issue.referencePath = obj.reference_path;
+ issue.path = obj.real_path;
+ issue.toggleSubscriptionEndpoint = obj.toggle_subscription_endpoint;
+ issue.project_id = obj.project_id;
+ issue.timeEstimate = obj.time_estimate;
+ issue.assignableLabelsEndpoint = obj.assignable_labels_endpoint;
+ issue.blocked = obj.blocked;
+
+ if (obj.project) {
+ issue.project = new IssueProject(obj.project);
+ }
+
+ if (obj.milestone) {
+ issue.milestone = new ListMilestone(obj.milestone);
+ issue.milestone_id = obj.milestone.id;
+ }
+
+ if (obj.labels) {
+ issue.labels = obj.labels.map(label => new ListLabel(label));
+ }
+
+ if (obj.assignees) {
+ issue.assignees = obj.assignees.map(a => new ListAssignee(a, defaultAvatar));
+ }
+ },
};
BoardsStoreEE.initEESpecific(boardsStore);
diff --git a/app/assets/javascripts/monitoring/components/dashboard.vue b/app/assets/javascripts/monitoring/components/dashboard.vue
index 79f32b357fc..a6d10d37103 100644
--- a/app/assets/javascripts/monitoring/components/dashboard.vue
+++ b/app/assets/javascripts/monitoring/components/dashboard.vue
@@ -522,7 +522,7 @@ export default {
<div v-if="!showEmptyState">
<graph-group
- v-for="(groupData, index) in dashboard.panel_groups"
+ v-for="(groupData, index) in dashboard.panelGroups"
:key="`${groupData.group}.${groupData.priority}`"
:name="groupData.group"
:show-panels="showPanels"
diff --git a/app/assets/javascripts/monitoring/components/embed.vue b/app/assets/javascripts/monitoring/components/embed.vue
index 49188a7af8f..15366b45618 100644
--- a/app/assets/javascripts/monitoring/components/embed.vue
+++ b/app/assets/javascripts/monitoring/components/embed.vue
@@ -28,10 +28,10 @@ export default {
...mapState('monitoringDashboard', ['dashboard']),
...mapGetters('monitoringDashboard', ['metricsWithData']),
charts() {
- if (!this.dashboard || !this.dashboard.panel_groups) {
+ if (!this.dashboard || !this.dashboard.panelGroups) {
return [];
}
- const groupWithMetrics = this.dashboard.panel_groups.find(group =>
+ const groupWithMetrics = this.dashboard.panelGroups.find(group =>
group.panels.find(chart => this.chartHasData(chart)),
) || { panels: [] };
diff --git a/app/assets/javascripts/monitoring/stores/actions.js b/app/assets/javascripts/monitoring/stores/actions.js
index daa095d9b3b..aa6c35d97be 100644
--- a/app/assets/javascripts/monitoring/stores/actions.js
+++ b/app/assets/javascripts/monitoring/stores/actions.js
@@ -51,9 +51,11 @@ export const requestMetricsDashboard = ({ commit }) => {
commit(types.REQUEST_METRICS_DATA);
};
export const receiveMetricsDashboardSuccess = ({ commit, dispatch }, { response, params }) => {
- commit(types.SET_ALL_DASHBOARDS, response.all_dashboards);
- commit(types.RECEIVE_METRICS_DATA_SUCCESS, response.dashboard);
- commit(types.SET_ENDPOINTS, convertObjectPropsToCamelCase(response.metrics_data));
+ const { all_dashboards, dashboard, metrics_data } = response;
+
+ commit(types.SET_ALL_DASHBOARDS, all_dashboards);
+ commit(types.RECEIVE_METRICS_DATA_SUCCESS, dashboard);
+ commit(types.SET_ENDPOINTS, convertObjectPropsToCamelCase(metrics_data));
return dispatch('fetchPrometheusMetrics', params);
};
@@ -149,16 +151,16 @@ export const fetchPrometheusMetric = ({ commit }, { metric, params }) => {
step,
};
- commit(types.REQUEST_METRIC_RESULT, { metricId: metric.metric_id });
+ commit(types.REQUEST_METRIC_RESULT, { metricId: metric.metricId });
- return fetchPrometheusResult(metric.prometheus_endpoint_path, queryParams)
+ return fetchPrometheusResult(metric.prometheusEndpointPath, queryParams)
.then(result => {
- commit(types.RECEIVE_METRIC_RESULT_SUCCESS, { metricId: metric.metric_id, result });
+ commit(types.RECEIVE_METRIC_RESULT_SUCCESS, { metricId: metric.metricId, result });
})
.catch(error => {
Sentry.captureException(error);
- commit(types.RECEIVE_METRIC_RESULT_FAILURE, { metricId: metric.metric_id, error });
+ commit(types.RECEIVE_METRIC_RESULT_FAILURE, { metricId: metric.metricId, error });
// Continue to throw error so the dashboard can notify using createFlash
throw error;
});
@@ -168,7 +170,7 @@ export const fetchPrometheusMetrics = ({ state, commit, dispatch, getters }, par
commit(types.REQUEST_METRICS_DATA);
const promises = [];
- state.dashboard.panel_groups.forEach(group => {
+ state.dashboard.panelGroups.forEach(group => {
group.panels.forEach(panel => {
panel.metrics.forEach(metric => {
promises.push(dispatch('fetchPrometheusMetric', { metric, params }));
diff --git a/app/assets/javascripts/monitoring/stores/getters.js b/app/assets/javascripts/monitoring/stores/getters.js
index 3801149e49d..1affc6f0a76 100644
--- a/app/assets/javascripts/monitoring/stores/getters.js
+++ b/app/assets/javascripts/monitoring/stores/getters.js
@@ -11,7 +11,7 @@ const metricsIdsInPanel = panel =>
* states in all the metric in the dashboard or group.
*/
export const getMetricStates = state => groupKey => {
- let groups = state.dashboard.panel_groups;
+ let groups = state.dashboard.panelGroups;
if (groupKey) {
groups = groups.filter(group => group.key === groupKey);
}
@@ -43,7 +43,7 @@ export const getMetricStates = state => groupKey => {
* filtered by group key.
*/
export const metricsWithData = state => groupKey => {
- let groups = state.dashboard.panel_groups;
+ let groups = state.dashboard.panelGroups;
if (groupKey) {
groups = groups.filter(group => group.key === groupKey);
}
diff --git a/app/assets/javascripts/monitoring/stores/mutations.js b/app/assets/javascripts/monitoring/stores/mutations.js
index 8bd53a24b61..7aac98821c9 100644
--- a/app/assets/javascripts/monitoring/stores/mutations.js
+++ b/app/assets/javascripts/monitoring/stores/mutations.js
@@ -1,18 +1,11 @@
import Vue from 'vue';
import pick from 'lodash/pick';
-import { slugify } from '~/lib/utils/text_utility';
import * as types from './mutation_types';
-import { normalizeMetric, normalizeQueryResult } from './utils';
+import { mapToDashboardViewModel, normalizeQueryResult } from './utils';
import { BACKOFF_TIMEOUT } from '../../lib/utils/common_utils';
import { metricStates } from '../constants';
import httpStatusCodes from '~/lib/utils/http_status';
-const normalizePanelMetrics = (metrics, defaultLabel) =>
- metrics.map(metric => ({
- ...normalizeMetric(metric),
- label: metric.label || defaultLabel,
- }));
-
/**
* Locate and return a metric in the dashboard by its id
* as generated by `uniqMetricsId()`.
@@ -21,10 +14,10 @@ const normalizePanelMetrics = (metrics, defaultLabel) =>
*/
const findMetricInDashboard = (metricId, dashboard) => {
let res = null;
- dashboard.panel_groups.forEach(group => {
+ dashboard.panelGroups.forEach(group => {
group.panels.forEach(panel => {
panel.metrics.forEach(metric => {
- if (metric.metric_id === metricId) {
+ if (metric.metricId === metricId) {
res = metric;
}
});
@@ -86,27 +79,9 @@ export default {
state.showEmptyState = true;
},
[types.RECEIVE_METRICS_DATA_SUCCESS](state, dashboard) {
- state.dashboard = {
- ...dashboard,
- panel_groups: dashboard.panel_groups.map((group, i) => {
- const key = `${slugify(group.group || 'default')}-${i}`;
- let { panels = [] } = group;
-
- // each panel has metric information that needs to be normalized
- panels = panels.map(panel => ({
- ...panel,
- metrics: normalizePanelMetrics(panel.metrics, panel.y_label),
- }));
-
- return {
- ...group,
- panels,
- key,
- };
- }),
- };
+ state.dashboard = mapToDashboardViewModel(dashboard);
- if (!state.dashboard.panel_groups.length) {
+ if (!state.dashboard.panelGroups.length) {
state.emptyState = 'noData';
}
},
@@ -206,7 +181,7 @@ export default {
state.showErrorBanner = enabled;
},
[types.SET_PANEL_GROUP_METRICS](state, payload) {
- const panelGroup = state.dashboard.panel_groups.find(pg => payload.key === pg.key);
+ const panelGroup = state.dashboard.panelGroups.find(pg => payload.key === pg.key);
panelGroup.panels = payload.panels;
},
[types.SET_ENVIRONMENTS_FILTER](state, searchTerm) {
diff --git a/app/assets/javascripts/monitoring/stores/state.js b/app/assets/javascripts/monitoring/stores/state.js
index a2050f8e893..2b1907e8df7 100644
--- a/app/assets/javascripts/monitoring/stores/state.js
+++ b/app/assets/javascripts/monitoring/stores/state.js
@@ -15,7 +15,7 @@ export default () => ({
showEmptyState: true,
showErrorBanner: true,
dashboard: {
- panel_groups: [],
+ panelGroups: [],
},
allDashboards: [],
diff --git a/app/assets/javascripts/monitoring/stores/utils.js b/app/assets/javascripts/monitoring/stores/utils.js
index cd586c6af3e..82deaa7ccfd 100644
--- a/app/assets/javascripts/monitoring/stores/utils.js
+++ b/app/assets/javascripts/monitoring/stores/utils.js
@@ -1,4 +1,4 @@
-import { omit } from 'lodash';
+import { slugify } from '~/lib/utils/text_utility';
import createGqClient, { fetchPolicies } from '~/lib/graphql';
import { getIdFromGraphQLId } from '~/graphql_shared/utils';
@@ -9,6 +9,13 @@ export const gqClient = createGqClient(
},
);
+/**
+ * Metrics loaded from project-defined dashboards do not have a metric_id.
+ * This method creates a unique ID combining metric_id and id, if either is present.
+ * This is hopefully a temporary solution until BE processes metrics before passing to fE
+ * @param {Object} metric - metric
+ * @returns {Object} - normalized metric with a uniqueID
+ */
export const uniqMetricsId = metric => `${metric.metric_id}_${metric.id}`;
/**
@@ -41,22 +48,75 @@ export const parseEnvironmentsResponse = (response = [], projectPath) =>
});
/**
- * Metrics loaded from project-defined dashboards do not have a metric_id.
- * This method creates a unique ID combining metric_id and id, if either is present.
- * This is hopefully a temporary solution until BE processes metrics before passing to fE
- * @param {Object} metric - metric
- * @returns {Object} - normalized metric with a uniqueID
+ * Maps metrics to its view model
+ *
+ * This function difers from other in that is maps all
+ * non-define properties as-is to the object. This is not
+ * advisable as it could lead to unexpected side-effects.
+ *
+ * Related issue:
+ * 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) =>
+ metrics.map(({ label, id, metric_id, query_range, prometheus_endpoint_path, ...metric }) => ({
+ label: label || defaultLabel,
+ queryRange: query_range,
+ prometheusEndpointPath: prometheus_endpoint_path,
+ metricId: uniqMetricsId({ metric_id, id }),
-export const normalizeMetric = (metric = {}) =>
- omit(
- {
- ...metric,
- metric_id: uniqMetricsId(metric),
- metricId: uniqMetricsId(metric),
- },
- 'id',
- );
+ // `metric_id` is used by embed.vue, keeping this duplicated.
+ // https://gitlab.com/gitlab-org/gitlab/issues/37492
+ metric_id: uniqMetricsId({ metric_id, id }),
+ ...metric,
+ }));
+
+/**
+ * Maps a metrics panel to its view model
+ *
+ * @param {Object} panel - Metrics panel
+ * @returns {Object}
+ */
+const mapToPanelViewModel = ({ title = '', type, y_label, metrics = [] }) => {
+ return {
+ title,
+ type,
+ y_label,
+ metrics: mapToMetricsViewModel(metrics, y_label),
+ };
+};
+
+/**
+ * Maps a metrics panel group to its view model
+ *
+ * @param {Object} panelGroup - Panel Group
+ * @returns {Object}
+ */
+const mapToPanelGroupViewModel = ({ group = '', panels = [] }, i) => {
+ return {
+ key: `${slugify(group || 'default')}-${i}`,
+ group,
+ panels: panels.map(mapToPanelViewModel),
+ };
+};
+
+/**
+ * Maps a dashboard json object to its view model
+ *
+ * @param {Object} dashboard - Dashboard object
+ * @param {String} dashboard.dashboard - Dashboard name object
+ * @param {Array} dashboard.panel_groups - Panel groups array
+ * @returns {Object}
+ */
+export const mapToDashboardViewModel = ({ dashboard = '', panel_groups = [] }) => {
+ return {
+ dashboard,
+ panelGroups: panel_groups.map(mapToPanelGroupViewModel),
+ };
+};
export const normalizeQueryResult = timeSeries => {
let normalizedResult = {};
diff --git a/app/assets/javascripts/monitoring/utils.js b/app/assets/javascripts/monitoring/utils.js
index b2fa44835e6..6694ae2f157 100644
--- a/app/assets/javascripts/monitoring/utils.js
+++ b/app/assets/javascripts/monitoring/utils.js
@@ -7,7 +7,7 @@ import {
/**
* This method is used to validate if the graph data format for a chart component
- * that needs a time series as a response from a prometheus query (query_range) is
+ * that needs a time series as a response from a prometheus query (queryRange) is
* of a valid format or not.
* @param {Object} graphData the graph data response from a prometheus request
* @returns {boolean} whether the graphData format is correct
diff --git a/app/controllers/groups/registry/repositories_controller.rb b/app/controllers/groups/registry/repositories_controller.rb
index 84c25cfb180..ac4ca197d72 100644
--- a/app/controllers/groups/registry/repositories_controller.rb
+++ b/app/controllers/groups/registry/repositories_controller.rb
@@ -17,7 +17,7 @@ module Groups
serializer = ContainerRepositoriesSerializer
.new(current_user: current_user)
- if Feature.enabled?(:vue_container_registry_explorer)
+ if Feature.enabled?(:vue_container_registry_explorer, group)
render json: serializer.with_pagination(request, response)
.represent_read_only(@images)
else
diff --git a/app/controllers/projects/registry/repositories_controller.rb b/app/controllers/projects/registry/repositories_controller.rb
index e524d1c29a2..d6d993f427d 100644
--- a/app/controllers/projects/registry/repositories_controller.rb
+++ b/app/controllers/projects/registry/repositories_controller.rb
@@ -17,7 +17,7 @@ module Projects
serializer = ContainerRepositoriesSerializer
.new(project: project, current_user: current_user)
- if Feature.enabled?(:vue_container_registry_explorer)
+ if Feature.enabled?(:vue_container_registry_explorer, project.group)
render json: serializer.with_pagination(request, response).represent(@images)
else
render json: serializer.represent(@images)
diff --git a/app/views/projects/registry/repositories/index.html.haml b/app/views/projects/registry/repositories/index.html.haml
index c668c9e8494..247cf021cc7 100644
--- a/app/views/projects/registry/repositories/index.html.haml
+++ b/app/views/projects/registry/repositories/index.html.haml
@@ -4,7 +4,7 @@
%section
.row.registry-placeholder.prepend-bottom-10
.col-12
- - if Feature.enabled?(:vue_container_registry_explorer, @project)
+ - if Feature.enabled?(:vue_container_registry_explorer, @project.group)
#js-container-registry{ data: { endpoint: project_container_registry_index_path(@project),
project_path: @project.full_path,
"help_page_path" => help_page_path('user/packages/container_registry/index'),