Merge branch 'fix/49388' into 'master'
Fix metrics graphs environments dropdown Closes #49388 See merge request gitlab-org/gitlab-ce!24441
This commit is contained in:
commit
6429dc943d
|
@ -143,7 +143,7 @@ export default {
|
||||||
*/
|
*/
|
||||||
created() {
|
created() {
|
||||||
this.service = new EnvironmentsService(this.endpoint);
|
this.service = new EnvironmentsService(this.endpoint);
|
||||||
this.requestData = { page: this.page, scope: this.scope };
|
this.requestData = { page: this.page, scope: this.scope, nested: true };
|
||||||
|
|
||||||
this.poll = new Poll({
|
this.poll = new Poll({
|
||||||
resource: this.service,
|
resource: this.service,
|
||||||
|
|
|
@ -7,8 +7,8 @@ export default class EnvironmentsService {
|
||||||
}
|
}
|
||||||
|
|
||||||
fetchEnvironments(options = {}) {
|
fetchEnvironments(options = {}) {
|
||||||
const { scope, page } = options;
|
const { scope, page, nested } = options;
|
||||||
return axios.get(this.environmentsEndpoint, { params: { scope, page } });
|
return axios.get(this.environmentsEndpoint, { params: { scope, page, nested } });
|
||||||
}
|
}
|
||||||
|
|
||||||
// eslint-disable-next-line class-methods-use-this
|
// eslint-disable-next-line class-methods-use-this
|
||||||
|
|
|
@ -20,7 +20,8 @@ export default class EnvironmentsStore {
|
||||||
*
|
*
|
||||||
* Stores the received environments.
|
* Stores the received environments.
|
||||||
*
|
*
|
||||||
* In the main environments endpoint, each environment has the following schema
|
* In the main environments endpoint (with { nested: true } in params), each folder
|
||||||
|
* has the following schema:
|
||||||
* { name: String, size: Number, latest: Object }
|
* { name: String, size: Number, latest: Object }
|
||||||
* In the endpoint to retrieve environments from each folder, the environment does
|
* In the endpoint to retrieve environments from each folder, the environment does
|
||||||
* not have the `latest` key and the data is all in the root level.
|
* not have the `latest` key and the data is all in the root level.
|
||||||
|
|
|
@ -196,13 +196,13 @@ export default {
|
||||||
class="dropdown-menu dropdown-menu-selectable dropdown-menu-drop-up"
|
class="dropdown-menu dropdown-menu-selectable dropdown-menu-drop-up"
|
||||||
>
|
>
|
||||||
<ul>
|
<ul>
|
||||||
<li v-for="environment in store.environmentsData" :key="environment.latest.id">
|
<li v-for="environment in store.environmentsData" :key="environment.id">
|
||||||
<a
|
<a
|
||||||
:href="environment.latest.metrics_path"
|
:href="environment.metrics_path"
|
||||||
:class="{ 'is-active': environment.latest.name == currentEnvironmentName }"
|
:class="{ 'is-active': environment.name == currentEnvironmentName }"
|
||||||
class="dropdown-item"
|
class="dropdown-item"
|
||||||
>
|
>
|
||||||
{{ environment.latest.name }}
|
{{ environment.name }}
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
|
@ -66,9 +66,7 @@ export default class MonitoringStore {
|
||||||
}
|
}
|
||||||
|
|
||||||
storeEnvironmentsData(environmentsData = []) {
|
storeEnvironmentsData(environmentsData = []) {
|
||||||
this.environmentsData = environmentsData.filter(
|
this.environmentsData = environmentsData.filter(environment => !!environment.last_deployment);
|
||||||
environment => !!environment.latest.last_deployment,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getMetricsCount() {
|
getMetricsCount() {
|
||||||
|
|
|
@ -15,6 +15,7 @@ class Projects::EnvironmentsController < Projects::ApplicationController
|
||||||
push_frontend_feature_flag(:area_chart, project)
|
push_frontend_feature_flag(:area_chart, project)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Returns all environments or all folders based on the :nested param
|
||||||
def index
|
def index
|
||||||
@environments = project.environments
|
@environments = project.environments
|
||||||
.with_state(params[:scope] || :available)
|
.with_state(params[:scope] || :available)
|
||||||
|
@ -25,11 +26,7 @@ class Projects::EnvironmentsController < Projects::ApplicationController
|
||||||
Gitlab::PollingInterval.set_header(response, interval: 3_000)
|
Gitlab::PollingInterval.set_header(response, interval: 3_000)
|
||||||
|
|
||||||
render json: {
|
render json: {
|
||||||
environments: EnvironmentSerializer
|
environments: serialize_environments(request, response, params[:nested]),
|
||||||
.new(project: @project, current_user: @current_user)
|
|
||||||
.with_pagination(request, response)
|
|
||||||
.within_folders
|
|
||||||
.represent(@environments),
|
|
||||||
available_count: project.environments.available.count,
|
available_count: project.environments.available.count,
|
||||||
stopped_count: project.environments.stopped.count
|
stopped_count: project.environments.stopped.count
|
||||||
}
|
}
|
||||||
|
@ -37,6 +34,7 @@ class Projects::EnvironmentsController < Projects::ApplicationController
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Returns all environments for a given folder
|
||||||
# rubocop: disable CodeReuse/ActiveRecord
|
# rubocop: disable CodeReuse/ActiveRecord
|
||||||
def folder
|
def folder
|
||||||
folder_environments = project.environments.where(environment_type: params[:id])
|
folder_environments = project.environments.where(environment_type: params[:id])
|
||||||
|
@ -48,10 +46,7 @@ class Projects::EnvironmentsController < Projects::ApplicationController
|
||||||
format.html
|
format.html
|
||||||
format.json do
|
format.json do
|
||||||
render json: {
|
render json: {
|
||||||
environments: EnvironmentSerializer
|
environments: serialize_environments(request, response),
|
||||||
.new(project: @project, current_user: @current_user)
|
|
||||||
.with_pagination(request, response)
|
|
||||||
.represent(@environments),
|
|
||||||
available_count: folder_environments.available.count,
|
available_count: folder_environments.available.count,
|
||||||
stopped_count: folder_environments.stopped.count
|
stopped_count: folder_environments.stopped.count
|
||||||
}
|
}
|
||||||
|
@ -186,6 +181,14 @@ class Projects::EnvironmentsController < Projects::ApplicationController
|
||||||
@environment ||= project.environments.find(params[:id])
|
@environment ||= project.environments.find(params[:id])
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def serialize_environments(request, response, nested = false)
|
||||||
|
serializer = EnvironmentSerializer
|
||||||
|
.new(project: @project, current_user: @current_user)
|
||||||
|
.with_pagination(request, response)
|
||||||
|
serializer = serializer.within_folders if nested
|
||||||
|
serializer.represent(@environments)
|
||||||
|
end
|
||||||
|
|
||||||
def authorize_stop_environment!
|
def authorize_stop_environment!
|
||||||
access_denied! unless can?(current_user, :stop_environment, environment)
|
access_denied! unless can?(current_user, :stop_environment, environment)
|
||||||
end
|
end
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
title: Update metrics environment dropdown to show complete option set
|
||||||
|
merge_request: 24441
|
||||||
|
author:
|
||||||
|
type: fixed
|
|
@ -47,9 +47,43 @@ describe Projects::EnvironmentsController do
|
||||||
|
|
||||||
let(:environments) { json_response['environments'] }
|
let(:environments) { json_response['environments'] }
|
||||||
|
|
||||||
|
context 'with default parameters' do
|
||||||
|
before do
|
||||||
|
get :index, params: environment_params(format: :json)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'responds with a flat payload describing available environments' do
|
||||||
|
expect(environments.count).to eq 3
|
||||||
|
expect(environments.first['name']).to eq 'production'
|
||||||
|
expect(environments.second['name']).to eq 'staging/review-1'
|
||||||
|
expect(environments.third['name']).to eq 'staging/review-2'
|
||||||
|
expect(json_response['available_count']).to eq 3
|
||||||
|
expect(json_response['stopped_count']).to eq 1
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'sets the polling interval header' do
|
||||||
|
expect(response).to have_gitlab_http_status(:ok)
|
||||||
|
expect(response.headers['Poll-Interval']).to eq("3000")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when a folder-based nested structure is requested' do
|
||||||
|
before do
|
||||||
|
get :index, params: environment_params(format: :json, nested: true)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'responds with a payload containing the latest environment for each folder' do
|
||||||
|
expect(environments.count).to eq 2
|
||||||
|
expect(environments.first['name']).to eq 'production'
|
||||||
|
expect(environments.second['name']).to eq 'staging'
|
||||||
|
expect(environments.second['size']).to eq 2
|
||||||
|
expect(environments.second['latest']['name']).to eq 'staging/review-2'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
context 'when requesting available environments scope' do
|
context 'when requesting available environments scope' do
|
||||||
before do
|
before do
|
||||||
get :index, params: environment_params(format: :json, scope: :available)
|
get :index, params: environment_params(format: :json, nested: true, scope: :available)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'responds with a payload describing available environments' do
|
it 'responds with a payload describing available environments' do
|
||||||
|
@ -64,16 +98,11 @@ describe Projects::EnvironmentsController do
|
||||||
expect(json_response['available_count']).to eq 3
|
expect(json_response['available_count']).to eq 3
|
||||||
expect(json_response['stopped_count']).to eq 1
|
expect(json_response['stopped_count']).to eq 1
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'sets the polling interval header' do
|
|
||||||
expect(response).to have_gitlab_http_status(:ok)
|
|
||||||
expect(response.headers['Poll-Interval']).to eq("3000")
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when requesting stopped environments scope' do
|
context 'when requesting stopped environments scope' do
|
||||||
before do
|
before do
|
||||||
get :index, params: environment_params(format: :json, scope: :stopped)
|
get :index, params: environment_params(format: :json, nested: true, scope: :stopped)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'responds with a payload describing stopped environments' do
|
it 'responds with a payload describing stopped environments' do
|
||||||
|
|
|
@ -6597,58 +6597,46 @@ export function convertDatesMultipleSeries(multipleSeries) {
|
||||||
|
|
||||||
export const environmentData = [
|
export const environmentData = [
|
||||||
{
|
{
|
||||||
|
id: 34,
|
||||||
name: 'production',
|
name: 'production',
|
||||||
size: 1,
|
state: 'available',
|
||||||
latest: {
|
external_url: 'http://root-autodevops-deploy.my-fake-domain.com',
|
||||||
id: 34,
|
environment_type: null,
|
||||||
name: 'production',
|
stop_action: false,
|
||||||
state: 'available',
|
metrics_path: '/root/hello-prometheus/environments/34/metrics',
|
||||||
external_url: 'http://root-autodevops-deploy.my-fake-domain.com',
|
environment_path: '/root/hello-prometheus/environments/34',
|
||||||
environment_type: null,
|
stop_path: '/root/hello-prometheus/environments/34/stop',
|
||||||
stop_action: false,
|
terminal_path: '/root/hello-prometheus/environments/34/terminal',
|
||||||
metrics_path: '/root/hello-prometheus/environments/34/metrics',
|
folder_path: '/root/hello-prometheus/environments/folders/production',
|
||||||
environment_path: '/root/hello-prometheus/environments/34',
|
created_at: '2018-06-29T16:53:38.301Z',
|
||||||
stop_path: '/root/hello-prometheus/environments/34/stop',
|
updated_at: '2018-06-29T16:57:09.825Z',
|
||||||
terminal_path: '/root/hello-prometheus/environments/34/terminal',
|
last_deployment: {
|
||||||
folder_path: '/root/hello-prometheus/environments/folders/production',
|
id: 127,
|
||||||
created_at: '2018-06-29T16:53:38.301Z',
|
|
||||||
updated_at: '2018-06-29T16:57:09.825Z',
|
|
||||||
last_deployment: {
|
|
||||||
id: 127,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'review',
|
id: 35,
|
||||||
size: 1,
|
name: 'review/noop-branch',
|
||||||
latest: {
|
state: 'available',
|
||||||
id: 35,
|
external_url: 'http://root-autodevops-deploy-review-noop-branc-die93w.my-fake-domain.com',
|
||||||
name: 'review/noop-branch',
|
environment_type: 'review',
|
||||||
state: 'available',
|
stop_action: true,
|
||||||
external_url: 'http://root-autodevops-deploy-review-noop-branc-die93w.my-fake-domain.com',
|
metrics_path: '/root/hello-prometheus/environments/35/metrics',
|
||||||
environment_type: 'review',
|
environment_path: '/root/hello-prometheus/environments/35',
|
||||||
stop_action: true,
|
stop_path: '/root/hello-prometheus/environments/35/stop',
|
||||||
metrics_path: '/root/hello-prometheus/environments/35/metrics',
|
terminal_path: '/root/hello-prometheus/environments/35/terminal',
|
||||||
environment_path: '/root/hello-prometheus/environments/35',
|
folder_path: '/root/hello-prometheus/environments/folders/review',
|
||||||
stop_path: '/root/hello-prometheus/environments/35/stop',
|
created_at: '2018-07-03T18:39:41.702Z',
|
||||||
terminal_path: '/root/hello-prometheus/environments/35/terminal',
|
updated_at: '2018-07-03T18:44:54.010Z',
|
||||||
folder_path: '/root/hello-prometheus/environments/folders/review',
|
last_deployment: {
|
||||||
created_at: '2018-07-03T18:39:41.702Z',
|
id: 128,
|
||||||
updated_at: '2018-07-03T18:44:54.010Z',
|
|
||||||
last_deployment: {
|
|
||||||
id: 128,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'no-deployment',
|
id: 36,
|
||||||
size: 1,
|
name: 'no-deployment/noop-branch',
|
||||||
latest: {
|
state: 'available',
|
||||||
id: 36,
|
created_at: '2018-07-04T18:39:41.702Z',
|
||||||
name: 'no-deployment/noop-branch',
|
updated_at: '2018-07-04T18:44:54.010Z',
|
||||||
state: 'available',
|
|
||||||
created_at: '2018-07-04T18:39:41.702Z',
|
|
||||||
updated_at: '2018-07-04T18:44:54.010Z',
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
Loading…
Reference in New Issue