Commit fa38acc5 authored by David O'Regan's avatar David O'Regan Committed by Miguel Rincon

Support multi schedule alert

parent d7281e68
...@@ -4,12 +4,15 @@ import { ...@@ -4,12 +4,15 @@ import {
GlButton, GlButton,
GlEmptyState, GlEmptyState,
GlLoadingIcon, GlLoadingIcon,
GlLink,
GlModalDirective, GlModalDirective,
GlTooltipDirective, GlTooltipDirective,
GlSprintf,
} from '@gitlab/ui'; } from '@gitlab/ui';
import * as Sentry from '@sentry/browser'; import * as Sentry from '@sentry/browser';
import { s__ } from '~/locale'; import { s__ } from '~/locale';
import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin'; import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import { escalationPolicyUrl } from '../constants';
import getOncallSchedulesWithRotationsQuery from '../graphql/queries/get_oncall_schedules.query.graphql'; import getOncallSchedulesWithRotationsQuery from '../graphql/queries/get_oncall_schedules.query.graphql';
import AddScheduleModal from './add_edit_schedule_modal.vue'; import AddScheduleModal from './add_edit_schedule_modal.vue';
import OncallSchedule from './oncall_schedule.vue'; import OncallSchedule from './oncall_schedule.vue';
...@@ -29,7 +32,13 @@ export const i18n = { ...@@ -29,7 +32,13 @@ export const i18n = {
successNotification: { successNotification: {
title: s__('OnCallSchedules|Try adding a rotation'), title: s__('OnCallSchedules|Try adding a rotation'),
description: s__( description: s__(
'OnCallSchedules|Your schedule has been successfully created and all alerts from this project will now be routed to this schedule. Currently, only one schedule can be created per project. More coming soon! To add individual users to this schedule, use the add a rotation button.', 'OnCallSchedules|Your schedule has been successfully created. To add individual users to this schedule, use the add a rotation button.',
),
descriptionSingle: s__(
'OnCallSchedules|To create an escalation policy using this schedule, visit the %{linkStart}escalation policy%{linkEnd} page.',
),
descriptionMulti: s__(
'OnCallSchedules|To create an escalation policy that defines which schedule is used when, visit the %{linkStart}escalation policy%{linkEnd} page.',
), ),
}, },
}; };
...@@ -37,11 +46,14 @@ export const i18n = { ...@@ -37,11 +46,14 @@ export const i18n = {
export default { export default {
i18n, i18n,
addScheduleModalId, addScheduleModalId,
escalationPolicyUrl,
components: { components: {
GlAlert, GlAlert,
GlButton, GlButton,
GlEmptyState, GlEmptyState,
GlLoadingIcon, GlLoadingIcon,
GlLink,
GlSprintf,
AddScheduleModal, AddScheduleModal,
OncallSchedule, OncallSchedule,
}, },
...@@ -78,6 +90,18 @@ export default { ...@@ -78,6 +90,18 @@ export default {
}, },
}, },
computed: { computed: {
alertMessage() {
const {
$options: {
i18n: {
successNotification: { description, descriptionMulti, descriptionSingle },
},
},
} = this;
return this.glFeatures.multipleOncallSchedules
? `${description} ${descriptionMulti}`
: `${description} ${descriptionSingle}`;
},
isLoading() { isLoading() {
return this.$apollo.queries.schedules.loading; return this.$apollo.queries.schedules.loading;
}, },
...@@ -116,7 +140,13 @@ export default { ...@@ -116,7 +140,13 @@ export default {
class="gl-my-3" class="gl-my-3"
@dismiss="showSuccessNotification = false" @dismiss="showSuccessNotification = false"
> >
{{ $options.i18n.successNotification.description }} <gl-sprintf :message="alertMessage">
<template #link="{ content }">
<gl-link :href="$options.escalationPolicyUrl" target="_blank">
{{ content }}
</gl-link>
</template>
</gl-sprintf>
</gl-alert> </gl-alert>
<oncall-schedule <oncall-schedule
v-for="(schedule, scheduleIndex) in schedules" v-for="(schedule, scheduleIndex) in schedules"
......
...@@ -48,12 +48,12 @@ export const addRotationModalId = 'addRotationModal'; ...@@ -48,12 +48,12 @@ export const addRotationModalId = 'addRotationModal';
export const editRotationModalId = 'editRotationModal'; export const editRotationModalId = 'editRotationModal';
export const deleteRotationModalId = 'deleteRotationModal'; export const deleteRotationModalId = 'deleteRotationModal';
export const ASSIGNEE_SPACER = 2;
export const ASSIGNEE_SPACER_SMALL = 1;
export const TIMELINE_CELL_WIDTH = 180; export const TIMELINE_CELL_WIDTH = 180;
export const SHIFT_WIDTH_CALCULATION_DELAY = 250; export const SHIFT_WIDTH_CALCULATION_DELAY = 250;
export const CURRENT_DAY_INDICATOR_OFFSET = 2.25;
export const oneHourOffsetDayView = 100 / HOURS_IN_DAY; export const oneHourOffsetDayView = 100 / HOURS_IN_DAY;
export const oneDayOffsetWeekView = 100 / DAYS_IN_WEEK; export const oneDayOffsetWeekView = 100 / DAYS_IN_WEEK;
export const oneHourOffsetWeekView = oneDayOffsetWeekView / HOURS_IN_DAY; export const oneHourOffsetWeekView = oneDayOffsetWeekView / HOURS_IN_DAY;
// TODO: Replace with href to documentation once https://gitlab.com/groups/gitlab-org/-/epics/4638 is completed
export const escalationPolicyUrl = 'https://gitlab.com/groups/gitlab-org/-/epics/4638';
import { GlEmptyState, GlLoadingIcon, GlAlert } from '@gitlab/ui'; import { GlEmptyState, GlLoadingIcon, GlAlert, GlSprintf, GlLink } from '@gitlab/ui';
import { createLocalVue, shallowMount } from '@vue/test-utils'; import { createLocalVue, shallowMount } from '@vue/test-utils';
import VueApollo from 'vue-apollo'; import VueApollo from 'vue-apollo';
import AddScheduleModal from 'ee/oncall_schedules/components/add_edit_schedule_modal.vue'; import AddScheduleModal from 'ee/oncall_schedules/components/add_edit_schedule_modal.vue';
...@@ -6,6 +6,7 @@ import OnCallSchedule from 'ee/oncall_schedules/components/oncall_schedule.vue'; ...@@ -6,6 +6,7 @@ import OnCallSchedule from 'ee/oncall_schedules/components/oncall_schedule.vue';
import OnCallScheduleWrapper, { import OnCallScheduleWrapper, {
i18n, i18n,
} from 'ee/oncall_schedules/components/oncall_schedules_wrapper.vue'; } from 'ee/oncall_schedules/components/oncall_schedules_wrapper.vue';
import { escalationPolicyUrl } from 'ee/oncall_schedules/constants';
import getOncallSchedulesWithRotationsQuery from 'ee/oncall_schedules/graphql/queries/get_oncall_schedules.query.graphql'; import getOncallSchedulesWithRotationsQuery from 'ee/oncall_schedules/graphql/queries/get_oncall_schedules.query.graphql';
import createMockApollo from 'helpers/mock_apollo_helper'; import createMockApollo from 'helpers/mock_apollo_helper';
import { createMockDirective, getBinding } from 'helpers/vue_mock_directive'; import { createMockDirective, getBinding } from 'helpers/vue_mock_directive';
...@@ -44,6 +45,9 @@ describe('On-call schedule wrapper', () => { ...@@ -44,6 +45,9 @@ describe('On-call schedule wrapper', () => {
GlTooltip: createMockDirective(), GlTooltip: createMockDirective(),
}, },
mocks: { $apollo }, mocks: { $apollo },
stubs: {
GlSprintf,
},
}), }),
); );
} }
...@@ -81,6 +85,8 @@ describe('On-call schedule wrapper', () => { ...@@ -81,6 +85,8 @@ describe('On-call schedule wrapper', () => {
const findEmptyState = () => wrapper.findComponent(GlEmptyState); const findEmptyState = () => wrapper.findComponent(GlEmptyState);
const findSchedules = () => wrapper.findAllComponents(OnCallSchedule); const findSchedules = () => wrapper.findAllComponents(OnCallSchedule);
const findAlert = () => wrapper.findComponent(GlAlert); const findAlert = () => wrapper.findComponent(GlAlert);
const findAlertDescription = () => wrapper.findComponent(GlSprintf);
const findAlertLink = () => wrapper.findComponent(GlLink);
const findModal = () => wrapper.findComponent(AddScheduleModal); const findModal = () => wrapper.findComponent(AddScheduleModal);
const findAddAdditionalButton = () => wrapper.findByTestId('add-additional-schedules-button'); const findAddAdditionalButton = () => wrapper.findByTestId('add-additional-schedules-button');
...@@ -113,12 +119,15 @@ describe('On-call schedule wrapper', () => { ...@@ -113,12 +119,15 @@ describe('On-call schedule wrapper', () => {
expect(schedule.exists()).toBe(true); expect(schedule.exists()).toBe(true);
}); });
it('shows success alert', async () => { it('shows success alert with distinct description for single schedule', async () => {
await findModal().vm.$emit('scheduleCreated'); await findModal().vm.$emit('scheduleCreated');
const alert = findAlert(); const alert = findAlert();
expect(alert.exists()).toBe(true); expect(alert.exists()).toBe(true);
expect(alert.props('title')).toBe(i18n.successNotification.title); expect(alert.props('title')).toBe(i18n.successNotification.title);
expect(alert.text()).toBe(i18n.successNotification.description); expect(findAlertLink().attributes('href')).toBe(escalationPolicyUrl);
expect(findAlertDescription().text()).toContain(
'To create an escalation policy using this schedule',
);
}); });
it('renders a newly created schedule', async () => { it('renders a newly created schedule', async () => {
...@@ -171,5 +180,12 @@ describe('On-call schedule wrapper', () => { ...@@ -171,5 +180,12 @@ describe('On-call schedule wrapper', () => {
const tooltip = getBinding(button.element, 'gl-tooltip'); const tooltip = getBinding(button.element, 'gl-tooltip');
expect(tooltip).toBeDefined(); expect(tooltip).toBeDefined();
}); });
it('shows success alert with distinct description for multiple schedules', async () => {
await findModal().vm.$emit('scheduleCreated');
expect(findAlertDescription().text()).toContain(
'To create an escalation policy that defines which schedule is used when',
);
});
}); });
}); });
...@@ -22571,6 +22571,12 @@ msgstr "" ...@@ -22571,6 +22571,12 @@ msgstr ""
msgid "OnCallSchedules|The schedule could not be updated. Please try again." msgid "OnCallSchedules|The schedule could not be updated. Please try again."
msgstr "" msgstr ""
msgid "OnCallSchedules|To create an escalation policy that defines which schedule is used when, visit the %{linkStart}escalation policy%{linkEnd} page."
msgstr ""
msgid "OnCallSchedules|To create an escalation policy using this schedule, visit the %{linkStart}escalation policy%{linkEnd} page."
msgstr ""
msgid "OnCallSchedules|Try adding a rotation" msgid "OnCallSchedules|Try adding a rotation"
msgstr "" msgstr ""
...@@ -22586,7 +22592,7 @@ msgstr "" ...@@ -22586,7 +22592,7 @@ msgstr ""
msgid "OnCallSchedules|You are currently a part of:" msgid "OnCallSchedules|You are currently a part of:"
msgstr "" msgstr ""
msgid "OnCallSchedules|Your schedule has been successfully created and all alerts from this project will now be routed to this schedule. Currently, only one schedule can be created per project. More coming soon! To add individual users to this schedule, use the add a rotation button." msgid "OnCallSchedules|Your schedule has been successfully created. To add individual users to this schedule, use the add a rotation button."
msgstr "" msgstr ""
msgid "OnDemandScans|Could not fetch scanner profiles. Please refresh the page, or try again later." msgid "OnDemandScans|Could not fetch scanner profiles. Please refresh the page, or try again later."
......
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