Commit ee2a4a63 authored by Enrique Alcántara's avatar Enrique Alcántara

Merge branch 'add-timeline-tab-timeline-event' into 'master'

Add timeline tab for incident view

See merge request gitlab-org/gitlab!80802
parents 3205338f 8cce3941
......@@ -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