Commit 4cbf8e4e authored by Ash McKenzie's avatar Ash McKenzie

Merge branch 'tr-alert-mgmt-detail-graphql-request' into 'master'

Alert Management detail page graphql initial setup

See merge request gitlab-org/gitlab!30703
parents 80bd2ca8 fb12120e
<script>
import { GlNewDropdown, GlNewDropdownItem, GlTabs, GlTab } from '@gitlab/ui';
import { s__ } from '~/locale';
import query from '../graphql/queries/details.query.graphql';
import { fetchPolicies } from '~/lib/graphql';
export default {
statuses: {
......@@ -18,11 +20,40 @@ export default {
GlTab,
GlTabs,
},
props: {
alertId: {
type: String,
required: true,
},
projectPath: {
type: String,
required: true,
},
},
apollo: {
alert: {
fetchPolicy: fetchPolicies.CACHE_AND_NETWORK,
query,
variables() {
return {
fullPath: this.projectPath,
alertId: this.alertId,
};
},
update(data) {
return data?.project?.alertManagementAlerts?.nodes?.[0] ?? null;
},
},
},
data() {
return { alert: null };
},
};
</script>
<template>
<div>
<div class="d-flex justify-content-between border-bottom pb-2 pt-1">
<div v-if="alert" class="d-flex justify-content-between border-bottom pb-2 pt-1">
<div></div>
<gl-new-dropdown class="align-self-center" right>
<gl-new-dropdown-item
v-for="(label, field) in $options.statuses"
......@@ -33,23 +64,21 @@ export default {
</gl-new-dropdown-item>
</gl-new-dropdown>
</div>
<div class="d-flex">
<gl-tabs>
<gl-tab data-testid="overviewTab" :title="$options.i18n.overviewTitle">
<ul class="pl-3">
<li data-testid="startTimeItem" class="font-weight-bold mb-3 mt-2">
{{ s__('AlertManagement|Start time:') }}
</li>
<li class="font-weight-bold my-3">
{{ s__('AlertManagement|End time:') }}
</li>
<li class="font-weight-bold my-3">
{{ s__('AlertManagement|Events:') }}
</li>
</ul>
</gl-tab>
<gl-tab data-testid="fullDetailsTab" :title="$options.i18n.fullAlertDetailsTitle" />
</gl-tabs>
</div>
<gl-tabs v-if="alert" data-testid="alertDetailsTabs">
<gl-tab data-testid="overviewTab" :title="$options.i18n.overviewTitle">
<ul class="pl-3">
<li data-testid="startTimeItem" class="font-weight-bold mb-3 mt-2">
{{ s__('AlertManagement|Start time:') }}
</li>
<li class="font-weight-bold my-3">
{{ s__('AlertManagement|End time:') }}
</li>
<li class="font-weight-bold my-3">
{{ s__('AlertManagement|Events:') }}
</li>
</ul>
</gl-tab>
<gl-tab data-testid="fullDetailsTab" :title="$options.i18n.fullAlertDetailsTitle" />
</gl-tabs>
</div>
</template>
import Vue from 'vue';
import VueApollo from 'vue-apollo';
import createDefaultClient from '~/lib/graphql';
import AlertDetails from './components/alert_details.vue';
Vue.use(VueApollo);
export default selector => {
const domEl = document.querySelector(selector);
const { alertId, projectPath } = domEl.dataset;
const apolloProvider = new VueApollo({
defaultClient: createDefaultClient(),
});
// eslint-disable-next-line no-new
new Vue({
el: selector,
apolloProvider,
components: {
AlertDetails,
},
render(createElement) {
return createElement('alert-details', {});
return createElement('alert-details', {
props: {
alertId,
projectPath,
},
});
},
});
};
query alertDetails($fullPath: ID!, $alertId: String) {
project(fullPath: $fullPath) {
alertManagementAlerts(iid: $alertId) {
nodes {
iid
endedAt
eventCount
monitoringTool
service
severity
startedAt
status
title
}
}
}
}
......@@ -8,6 +8,7 @@ class Projects::AlertManagementController < Projects::ApplicationController
end
def details
@alert_id = params[:id]
end
private
......
......@@ -10,4 +10,11 @@ module Projects::AlertManagementHelper
'alert-management-enabled' => Feature.enabled?(:alert_management_minimal, project).to_s
}
end
def alert_management_detail_data(project_path, alert_id)
{
'alert-id' => alert_id,
'project-path' => project_path
}
end
end
- add_to_breadcrumbs s_('AlertManagement|Alerts'), project_alert_management_index_path(@project)
- page_title s_('AlertManagement|Alert detail')
#js-alert_details
#js-alert_details{ data: alert_management_detail_data(@project.full_path, @alert_id) }
......@@ -64,4 +64,12 @@ describe Projects::AlertManagementController do
end
end
end
describe 'set_alert_id' do
it 'sets alert id from the route' do
get :details, params: { namespace_id: project.namespace, project_id: project, id: id }
expect(assigns(:alert_id)).to eq(id.to_s)
end
end
end
......@@ -4,14 +4,18 @@ import AlertDetails from '~/alert_management/components/alert_details.vue';
describe('AlertDetails', () => {
let wrapper;
function mountComponent() {
wrapper = shallowMount(AlertDetails);
function mountComponent(alert = {}) {
wrapper = shallowMount(AlertDetails, {
propsData: {
alertId: 'alertId',
projectPath: 'projectPath',
},
data() {
return { alert };
},
});
}
beforeEach(() => {
mountComponent();
});
afterEach(() => {
if (wrapper) {
wrapper.destroy();
......@@ -19,20 +23,42 @@ describe('AlertDetails', () => {
});
describe('Alert details', () => {
it('renders a tab with overview information', () => {
expect(wrapper.find('[data-testid="overviewTab"]').exists()).toBe(true);
});
describe('when alert is null', () => {
beforeEach(() => {
mountComponent(null);
});
it('renders a tab with full alert information', () => {
expect(wrapper.find('[data-testid="fullDetailsTab"]').exists()).toBe(true);
describe('when alert is null', () => {
beforeEach(() => {
mountComponent(null);
});
it('shows an empty state', () => {
expect(wrapper.find('[data-testid="alertDetailsTabs"]').exists()).toBe(false);
});
});
});
it('renders alert details', () => {
expect(wrapper.find('[data-testid="startTimeItem"]').exists()).toBe(true);
describe('when alert is present', () => {
beforeEach(() => {
mountComponent();
});
it('renders a tab with overview information', () => {
expect(wrapper.find('[data-testid="overviewTab"]').exists()).toBe(true);
});
it('renders a tab with full alert information', () => {
expect(wrapper.find('[data-testid="fullDetailsTab"]').exists()).toBe(true);
});
it('renders alert details', () => {
expect(wrapper.find('[data-testid="startTimeItem"]').exists()).toBe(true);
});
});
it('renders a status dropdown', () => {
expect(wrapper.find('[data-testid="statusDropdownItem"]').exists()).toBe(true);
it('renders a status dropdown containing three items', () => {
expect(wrapper.findAll('[data-testid="statusDropdownItem"]').length).toBe(3);
});
});
});
......@@ -7,11 +7,11 @@ describe Projects::AlertManagementHelper do
let_it_be(:project, reload: true) { create(:project) }
let_it_be(:current_user) { create(:user) }
let_it_be(:project_path) { project.full_path }
describe '#alert_management_data' do
let(:user_can_enable_alert_management) { false }
let(:setting_path) { project_settings_operations_path(project) }
let(:project_path) { project.full_path }
before do
allow(helper)
......@@ -21,7 +21,7 @@ describe Projects::AlertManagementHelper do
end
context 'without alert_managements_setting' do
it 'returns frontend configuration' do
it 'returns index page configuration' do
expect(alert_management_data(current_user, project)).to eq(
'project-path' => project_path,
'enable-alert-management-path' => setting_path,
......@@ -32,4 +32,15 @@ describe Projects::AlertManagementHelper do
end
end
end
describe '#alert_management_detail_data' do
let(:alert_id) { 1 }
it 'returns detail page configuration' do
expect(alert_management_detail_data(project_path, alert_id)).to eq(
'alert-id' => alert_id,
'project-path' => project_path
)
end
end
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