Commit 8cce3941 authored by Rajendra Kadam's avatar Rajendra Kadam Committed by Enrique Alcántara

Add timeline tab for incident view

Add feature flag for timeline events tab

Add specs for tab component

Fix typo in frontend specs

Apply suggestions
parent 5b0dbc98
......@@ -5,6 +5,7 @@ import { trackIncidentDetailsViewsOptions } from '~/incidents/constants';
import { s__ } from '~/locale';
import Tracking from '~/tracking';
import AlertDetailsTable from '~/vue_shared/components/alert_details_table.vue';
import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import DescriptionComponent from '../description.vue';
import getAlert from './graphql/queries/get_alert.graphql';
import HighlightBar from './highlight_bar.vue';
......@@ -17,7 +18,10 @@ export default {
GlTabs,
HighlightBar,
MetricsTab: () => import('ee_component/issues/show/components/incidents/metrics_tab.vue'),
TimelineTab: () =>
import('ee_component/issues/show/components/incidents/timeline_events_tab.vue'),
},
mixins: [glFeatureFlagsMixin()],
inject: ['fullPath', 'iid', 'uploadMetricsFeatureAvailable'],
apollo: {
alert: {
......@@ -47,6 +51,9 @@ export default {
loading() {
return this.$apollo.queries.alert.loading;
},
incidentTabEnabled() {
return this.glFeatures.incidentTimelineEvents && this.glFeatures.incidentTimelineEventTab;
},
},
mounted() {
this.trackPageViews();
......@@ -76,6 +83,7 @@ export default {
>
<alert-details-table :alert="alert" :loading="loading" />
</gl-tab>
<timeline-tab v-if="incidentTabEnabled" data-testid="timeline-events-tab" />
</gl-tabs>
</div>
</template>
......@@ -8,6 +8,8 @@ class Projects::IncidentsController < Projects::ApplicationController
before_action :load_incident, only: [:show]
before_action do
push_frontend_feature_flag(:incident_escalations, @project)
push_frontend_feature_flag(:incident_timeline_event_tab, @project, default_enabled: :yaml)
push_licensed_feature(:incident_timeline_events) if @project.licensed_feature_available?(:incident_timeline_events)
end
feature_category :incident_management
......
---
name: incident_timeline_event_tab
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/80802
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/353426
milestone: '14.9'
type: development
group: group::respond
default_enabled: false
<script>
import { GlTab, GlButton } from '@gitlab/ui';
export default {
components: {
GlTab,
GlButton,
},
};
</script>
<template>
<gl-tab :title="s__('Incident|Timeline')">
<div class="gl-my-4">
<p>{{ s__('Incident|No timeline items have been added yet.') }}</p>
</div>
<gl-button class="gl-my-3">
{{ s__('Incident|Add new timeline event') }}
</gl-button>
</gl-tab>
</template>
import { shallowMount } from '@vue/test-utils';
import { GlButton } from '@gitlab/ui';
import TimelineEventsTab from 'ee/issues/show/components/incidents/timeline_events_tab.vue';
describe('TimlineEventsTab', () => {
let wrapper;
const mountComponent = () => {
wrapper = shallowMount(TimelineEventsTab);
};
beforeEach(() => {
mountComponent();
});
afterEach(() => {
if (wrapper) {
wrapper.destroy();
}
});
const findNoEventsLine = () => wrapper.find('p');
const findAddEventButton = () => wrapper.findComponent(GlButton);
describe('empty state', () => {
beforeEach(() => {
mountComponent();
});
it('renders the text', () => {
expect(findNoEventsLine().exists()).toBe(true);
expect(findNoEventsLine().text()).toBe('No timeline items have been added yet.');
});
it('renders the button', () => {
expect(findAddEventButton().exists()).toBe(true);
expect(findAddEventButton().text()).toBe('Add new timeline event');
});
});
});
......@@ -19418,6 +19418,9 @@ msgstr ""
msgid "Incidents|There was an issue uploading your image."
msgstr ""
msgid "Incident|Add new timeline event"
msgstr ""
msgid "Incident|Alert details"
msgstr ""
......@@ -19439,6 +19442,9 @@ msgstr ""
msgid "Incident|Metrics"
msgstr ""
msgid "Incident|No timeline items have been added yet."
msgstr ""
msgid "Incident|Summary"
msgstr ""
......@@ -19448,6 +19454,9 @@ msgstr ""
msgid "Incident|There was an issue loading incident data. Please try again."
msgstr ""
msgid "Incident|Timeline"
msgstr ""
msgid "Include author name in notification email body"
msgstr ""
......
import { GlTab } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import merge from 'lodash/merge';
import waitForPromises from 'helpers/wait_for_promises';
import { trackIncidentDetailsViewsOptions } from '~/incidents/constants';
import DescriptionComponent from '~/issues/show/components/description.vue';
import HighlightBar from '~/issues/show/components/incidents/highlight_bar.vue';
......@@ -36,6 +35,7 @@ describe('Incident Tabs component', () => {
fullPath: '',
iid: '',
uploadMetricsFeatureAvailable: true,
glFeatures: { incidentTimelineEventTab: true, incidentTimelineEvents: true },
},
data() {
return { alert: mockAlert, ...data };
......@@ -58,6 +58,7 @@ describe('Incident Tabs component', () => {
const findTabs = () => wrapper.findAll(GlTab);
const findSummaryTab = () => findTabs().at(0);
const findMetricsTab = () => wrapper.find('[data-testid="metrics-tab"]');
const findTimelineTab = () => wrapper.find('[data-testid="timeline-events-tab"]');
const findAlertDetailsTab = () => wrapper.find('[data-testid="alert-details-tab"]');
const findAlertDetailsComponent = () => wrapper.find(AlertDetailsTable);
const findDescriptionComponent = () => wrapper.find(DescriptionComponent);
......@@ -73,6 +74,29 @@ describe('Incident Tabs component', () => {
});
});
describe('incident timeline tab', () => {
beforeEach(() => {
mountComponent();
});
it('renders the timeline tab when feature flag is enabled', () => {
expect(findTimelineTab().exists()).toBe(true);
expect(findTimelineTab().attributes('title')).toBe('Timeline');
});
it('does not render timeline tab when feature flag is disabled', () => {
mountComponent({}, { provide: { glFeatures: { incidentTimelineEventTab: false } } });
expect(findTimelineTab().exists()).toBe(false);
});
it('does not render timeline tab when not available in license', () => {
mountComponent({}, { provide: { glFeatures: { incidentTimelineEvents: false } } });
expect(findTimelineTab().exists()).toBe(false);
});
});
describe('with an alert present', () => {
beforeEach(() => {
mountComponent();
......@@ -112,19 +136,15 @@ describe('Incident Tabs component', () => {
});
describe('upload metrics feature available', () => {
it('shows the metric tab when metrics are available', async () => {
it('shows the metric tab when metrics are available', () => {
mountComponent({}, { provide: { uploadMetricsFeatureAvailable: true } });
await waitForPromises();
expect(findMetricsTab().exists()).toBe(true);
});
it('hides the tab when metrics are not available', async () => {
it('hides the tab when metrics are not available', () => {
mountComponent({}, { provide: { uploadMetricsFeatureAvailable: false } });
await waitForPromises();
expect(findMetricsTab().exists()).toBe(false);
});
});
......
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