Commit 346f8bfc authored by Olena Horal-Koretska's avatar Olena Horal-Koretska Committed by Kushal Pandya

Preserve active tab on page reload

parent 41cc47c4
......@@ -35,13 +35,24 @@ export default {
errorMsg: s__(
'AlertManagement|There was an error displaying the alert. Please refresh the page to try again.',
),
fullAlertDetailsTitle: s__('AlertManagement|Alert details'),
overviewTitle: s__('AlertManagement|Overview'),
metricsTitle: s__('AlertManagement|Metrics'),
reportedAt: s__('AlertManagement|Reported %{when}'),
reportedAtWithTool: s__('AlertManagement|Reported %{when} by %{tool}'),
},
severityLabels: ALERTS_SEVERITY_LABELS,
tabsConfig: [
{
id: 'overview',
title: s__('AlertManagement|Overview'),
},
{
id: 'fullDetails',
title: s__('AlertManagement|Alert details'),
},
{
id: 'metrics',
title: s__('AlertManagement|Metrics'),
},
],
components: {
GlBadge,
GlAlert,
......@@ -119,6 +130,18 @@ export default {
showErrorMsg() {
return this.errored && !this.isErrorDismissed;
},
activeTab() {
return this.$route.params.tabId || this.$options.tabsConfig[0].id;
},
currentTabIndex: {
get() {
return this.$options.tabsConfig.findIndex(tab => tab.id === this.activeTab);
},
set(tabIdx) {
const tabId = this.$options.tabsConfig[tabIdx].id;
this.$router.replace({ name: 'tab', params: { tabId } });
},
},
},
mounted() {
this.trackPageViews();
......@@ -257,8 +280,8 @@ export default {
>
<h2 data-testid="title">{{ alert.title }}</h2>
</div>
<gl-tabs v-if="alert" data-testid="alertDetailsTabs">
<gl-tab data-testid="overviewTab" :title="$options.i18n.overviewTitle">
<gl-tabs v-if="alert" v-model="currentTabIndex" data-testid="alertDetailsTabs">
<gl-tab :data-testid="$options.tabsConfig[0].id" :title="$options.tabsConfig[0].title">
<div v-if="alert.severity" class="gl-mt-3 gl-mb-5 gl-display-flex">
<div class="gl-font-weight-bold gl-w-13 gl-text-right gl-pr-3">
{{ s__('AlertManagement|Severity') }}:
......@@ -309,7 +332,7 @@ export default {
</div>
</template>
</gl-tab>
<gl-tab data-testid="fullDetailsTab" :title="$options.i18n.fullAlertDetailsTitle">
<gl-tab :data-testid="$options.tabsConfig[1].id" :title="$options.tabsConfig[1].title">
<gl-table
class="alert-management-details-table"
:items="[{ key: 'Value', ...alert }]"
......@@ -325,7 +348,7 @@ export default {
</template>
</gl-table>
</gl-tab>
<gl-tab data-testId="metricsTab" :title="$options.i18n.metricsTitle">
<gl-tab :data-testid="$options.tabsConfig[2].id" :title="$options.tabsConfig[2].title">
<alert-metrics :dashboard-url="alert.metricsDashboardUrl" />
</gl-tab>
</gl-tabs>
......
import Vue from 'vue';
import VueApollo from 'vue-apollo';
import createDefaultClient from '~/lib/graphql';
import createRouter from './router';
import { defaultDataIdFromObject } from 'apollo-cache-inmemory';
import AlertDetails from './components/alert_details.vue';
import sidebarStatusQuery from './graphql/queries/sidebar_status.query.graphql';
......@@ -10,6 +11,7 @@ Vue.use(VueApollo);
export default selector => {
const domEl = document.querySelector(selector);
const { alertId, projectPath, projectIssuesPath, projectId } = domEl.dataset;
const router = createRouter();
const resolvers = {
Mutation: {
......@@ -54,6 +56,7 @@ export default selector => {
components: {
AlertDetails,
},
router,
render(createElement) {
return createElement('alert-details', {});
},
......
import Vue from 'vue';
import VueRouter from 'vue-router';
import { joinPaths } from '~/lib/utils/url_utility';
Vue.use(VueRouter);
export default function createRouter(base) {
return new VueRouter({
mode: 'hash',
base: joinPaths(gon.relative_url_root || '', base),
routes: [{ path: '/:tabId', name: 'tab' }],
});
}
---
title: Preserve active tab on alert details page reload
merge_request: 39369
author:
type: added
......@@ -20,6 +20,7 @@ describe('AlertDetails', () => {
const projectPath = 'root/alerts';
const projectIssuesPath = 'root/alerts/-/issues';
const projectId = '1';
const $router = { replace: jest.fn() };
const findDetailsTable = () => wrapper.find(GlTable);
......@@ -44,6 +45,8 @@ describe('AlertDetails', () => {
sidebarStatus: {},
},
},
$router,
$route: { params: {} },
},
stubs,
});
......@@ -81,11 +84,11 @@ describe('AlertDetails', () => {
});
it('renders a tab with overview information', () => {
expect(wrapper.find('[data-testid="overviewTab"]').exists()).toBe(true);
expect(wrapper.find('[data-testid="overview"]').exists()).toBe(true);
});
it('renders a tab with full alert information', () => {
expect(wrapper.find('[data-testid="fullDetailsTab"]').exists()).toBe(true);
expect(wrapper.find('[data-testid="fullDetails"]').exists()).toBe(true);
});
it('renders severity', () => {
......@@ -191,7 +194,7 @@ describe('AlertDetails', () => {
mountComponent({ data: { alert: mockAlert } });
});
it('should display a table of raw alert details data', () => {
wrapper.find('[data-testid="fullDetailsTab"]').trigger('click');
wrapper.find('[data-testid="fullDetails"]').trigger('click');
expect(findDetailsTable().exists()).toBe(true);
});
});
......@@ -252,6 +255,22 @@ describe('AlertDetails', () => {
);
});
});
describe('tab navigation', () => {
beforeEach(() => {
mountComponent({ data: { alert: mockAlert } });
});
it.each`
index | tabId
${0} | ${'overview'}
${1} | ${'fullDetails'}
${2} | ${'metrics'}
`('will navigate to the correct tab via $tabId', ({ index, tabId }) => {
wrapper.setData({ currentTabIndex: index });
expect($router.replace).toHaveBeenCalledWith({ name: 'tab', params: { tabId } });
});
});
});
describe('Snowplow tracking', () => {
......
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