Commit 542e8c90 authored by Olena Horal-Koretska's avatar Olena Horal-Koretska

Merge branch 'tr-fix-escalation-policy-parsing' into 'master'

Convert minutes to seconds for escalation policies

See merge request gitlab-org/gitlab!64977
parents b8c70280 744fb186
......@@ -76,13 +76,13 @@ export default {
this.rules = this.form.rules.map((rule) => {
const {
status,
elapsedTimeSeconds,
elapsedTimeMinutes,
oncallSchedule: { iid: oncallScheduleIid },
} = rule;
return {
status,
elapsedTimeSeconds,
elapsedTimeMinutes,
action: DEFAULT_ACTION,
oncallScheduleIid,
key: uniqueId(),
......
......@@ -9,7 +9,7 @@ import {
import createEscalationPolicyMutation from '../graphql/mutations/create_escalation_policy.mutation.graphql';
import updateEscalationPolicyMutation from '../graphql/mutations/update_escalation_policy.mutation.graphql';
import getEscalationPoliciesQuery from '../graphql/queries/get_escalation_policies.query.graphql';
import { isNameFieldValid, getRulesValidationState } from '../utils';
import { isNameFieldValid, getRulesValidationState, serializeRule } from '../utils';
import AddEditEscalationPolicyForm from './add_edit_escalation_policy_form.vue';
export const i18n = {
......@@ -91,7 +91,7 @@ export default {
},
requestParams() {
const id = this.isEditMode ? { id: this.escalationPolicy.id } : {};
return { ...this.form, ...id, rules: this.getRules(this.form.rules) };
return { ...this.form, ...id, rules: this.getRules(this.form.rules).map(serializeRule) };
},
},
methods: {
......@@ -186,9 +186,9 @@ export default {
},
getRules(rules) {
return rules.map(
({ status, elapsedTimeSeconds, oncallScheduleIid, oncallSchedule: { iid } = {} }) => ({
({ status, elapsedTimeMinutes, oncallScheduleIid, oncallSchedule: { iid } = {} }) => ({
status,
elapsedTimeSeconds,
elapsedTimeMinutes,
oncallScheduleIid: oncallScheduleIid || iid,
}),
);
......
......@@ -4,6 +4,7 @@ import * as Sentry from '@sentry/browser';
import { s__ } from '~/locale';
import { addEscalationPolicyModalId } from '../constants';
import getEscalationPoliciesQuery from '../graphql/queries/get_escalation_policies.query.graphql';
import { parsePolicy } from '../utils';
import AddEscalationPolicyModal from './add_edit_escalation_policy_modal.vue';
import EscalationPolicy from './escalation_policy.vue';
......@@ -47,7 +48,7 @@ export default {
};
},
update({ project }) {
return project?.incidentManagementEscalationPolicies?.nodes ?? [];
return project?.incidentManagementEscalationPolicies?.nodes.map(parsePolicy) ?? [];
},
error(error) {
Sentry.captureException(error);
......
......@@ -29,9 +29,9 @@ export const i18n = {
minutes: s__('EscalationPolicies|mins'),
};
const isRuleValid = ({ status, elapsedTimeSeconds, oncallSchedule: { name } }) =>
const isRuleValid = ({ status, elapsedTimeMinutes, oncallSchedule: { name } }) =>
Object.keys(ALERT_STATUSES).includes(status) &&
typeof elapsedTimeSeconds === 'number' &&
typeof elapsedTimeMinutes === 'number' &&
typeof name === 'string';
export default {
......@@ -145,7 +145,7 @@ export default {
</template>
<template #minutes>
<span class="gl-font-weight-bold">
{{ rule.elapsedTimeSeconds }} {{ $options.i18n.minutes }}
{{ rule.elapsedTimeMinutes }} {{ $options.i18n.minutes }}
</span>
</template>
<template #then>
......
......@@ -76,10 +76,10 @@ export default {
},
},
data() {
const { status, elapsedTimeSeconds, action, oncallScheduleIid } = this.rule;
const { status, elapsedTimeMinutes, action, oncallScheduleIid } = this.rule;
return {
status,
elapsedTimeSeconds,
elapsedTimeMinutes,
action,
oncallScheduleIid,
};
......@@ -119,7 +119,7 @@ export default {
oncallScheduleIid: parseInt(this.oncallScheduleIid, 10),
action: this.action,
status: this.status,
elapsedTimeSeconds: parseInt(this.elapsedTimeSeconds, 10),
elapsedTimeMinutes: this.elapsedTimeMinutes,
},
});
},
......@@ -169,9 +169,9 @@ export default {
</template>
<template #minutes>
<gl-form-input
v-model="elapsedTimeSeconds"
v-model="elapsedTimeMinutes"
class="gl-mx-3 gl-inset-border-1-gray-200! gl-w-12"
type="number"
number
min="0"
@input="emitUpdate"
/>
......
......@@ -13,7 +13,7 @@ export const ACTIONS = {
export const DEFAULT_ESCALATION_RULE = {
status: 'ACKNOWLEDGED',
elapsedTimeSeconds: 0,
elapsedTimeMinutes: 0,
action: 'EMAIL_ONCALL_SCHEDULE_USER',
oncallScheduleIid: null,
};
......
......@@ -17,8 +17,33 @@ export const isNameFieldValid = (name) => {
export const getRulesValidationState = (rules) => {
return rules.map((rule) => {
return {
isTimeValid: parseInt(rule.elapsedTimeSeconds, 10) >= 0,
isTimeValid: parseInt(rule.elapsedTimeMinutes, 10) >= 0,
isScheduleValid: Boolean(rule.oncallScheduleIid),
};
});
};
/**
* Serializes a rule by converting elapsed minutes to seconds
* @param {Object} rule
*
* @returns {Object} rule
*/
export const serializeRule = ({ elapsedTimeMinutes, ...ruleParams }) => ({
...ruleParams,
elapsedTimeSeconds: elapsedTimeMinutes * 60,
});
/**
* Parses a policy by converting elapsed seconds to minutes
* @param {Object} policy
*
* @returns {Object} policy
*/
export const parsePolicy = (policy) => ({
...policy,
rules: policy.rules.map(({ elapsedTimeSeconds, ...ruleParams }) => ({
...ruleParams,
elapsedTimeMinutes: elapsedTimeSeconds / 60,
})),
});
......@@ -38,7 +38,7 @@ exports[`EscalationPolicy renders policy with rules 1`] = `
class="gl-font-weight-bold"
>
10 mins
1 mins
</span>
......@@ -81,7 +81,7 @@ exports[`EscalationPolicy renders policy with rules 1`] = `
class="gl-font-weight-bold"
>
20 mins
2 mins
</span>
......
......@@ -82,7 +82,7 @@ describe('AddEscalationPolicyForm', () => {
it('on rule update emitted should update rules array and emit updates up', () => {
const updatedRule = {
status: 'TRIGGERED',
elapsedTimeSeconds: 30,
elapsedTimeMinutes: 3,
oncallScheduleIid: 2,
};
findRules().at(0).vm.$emit('update-escalation-rule', { index: 0, rule: updatedRule });
......
......@@ -23,7 +23,8 @@ describe('AddEditsEscalationPolicyModal', () => {
const mockEscalationPolicy = cloneDeep(mockPolicies[0]);
const updatedName = 'Policy name';
const updatedDescription = 'Policy description';
const updatedRules = [{ status: 'RESOLVED', elapsedTimeSeconds: 10, oncallScheduleIid: 1 }];
const updatedRules = [{ status: 'RESOLVED', elapsedTimeMinutes: 1, oncallScheduleIid: 1 }];
const serializedRules = [{ status: 'RESOLVED', elapsedTimeSeconds: 60, oncallScheduleIid: 1 }];
const createComponent = ({ escalationPolicy, isEditMode = false, modalId, data } = {}) => {
wrapper = shallowMount(AddEscalationPolicyModal, {
......@@ -99,7 +100,7 @@ describe('AddEditsEscalationPolicyModal', () => {
projectPath,
name: updatedName,
description: updatedDescription,
rules: updatedRules,
rules: serializedRules,
},
},
update: expect.any(Function),
......@@ -168,7 +169,7 @@ describe('AddEditsEscalationPolicyModal', () => {
input: {
name: updatedName,
description: updatedDescription,
rules: updatedRules,
rules: serializedRules,
id: mockEscalationPolicy.id,
},
},
......@@ -264,7 +265,7 @@ describe('AddEditsEscalationPolicyModal', () => {
});
form.vm.$emit('update-escalation-policy-form', {
field: 'rules',
value: [{ status: 'RESOLVED', elapsedTimeSeconds: 10, oncallScheduleIid: 1 }],
value: [{ status: 'RESOLVED', elapsedTimeMinutes: 1, oncallScheduleIid: 1 }],
});
await wrapper.vm.$nextTick();
expect(findModal().props('actionPrimary').attributes).toContainEqual({ disabled: false });
......
......@@ -9,11 +9,12 @@ import {
deleteEscalationPolicyModalId,
editEscalationPolicyModalId,
} from 'ee/escalation_policies/constants';
import { parsePolicy } from 'ee/escalation_policies/utils';
import mockPolicies from './mocks/mockPolicies.json';
describe('EscalationPolicy', () => {
let wrapper;
const escalationPolicy = cloneDeep(mockPolicies[0]);
const escalationPolicy = parsePolicy(cloneDeep(mockPolicies[0]));
const createComponent = () => {
wrapper = shallowMount(EscalationPolicy, {
......
import { GlEmptyState, GlLoadingIcon } from '@gitlab/ui';
import EscalationPoliciesWrapper from 'ee/escalation_policies/components/escalation_policies_wrapper.vue';
import EscalationPolicy from 'ee/escalation_policies/components/escalation_policy.vue';
import { parsePolicy } from 'ee/escalation_policies/utils';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import mockEscalationPolicies from './mocks/mockPolicies.json';
......@@ -55,7 +56,7 @@ describe('Escalation Policies Wrapper', () => {
beforeEach(() => {
mountComponent({
loading,
escalationPolicies,
escalationPolicies: escalationPolicies.map(parsePolicy),
});
});
......
......@@ -7,7 +7,7 @@
{
"id": "gid://gitlab/IncidentManagement::EscalationRule/22",
"status": "ACKNOWLEDGED",
"elapsedTimeSeconds": 10,
"elapsedTimeSeconds": 60,
"oncallSchedule": {
"iid": "3",
"name": "Schedule to fill in"
......@@ -16,7 +16,7 @@
{
"id": "gid://gitlab/IncidentManagement::EscalationRule/23",
"status": "RESOLVED",
"elapsedTimeSeconds": 20,
"elapsedTimeSeconds": 120,
"oncallSchedule": {
"iid": "4",
"name": "Monitor schedule"
......@@ -32,7 +32,7 @@
{
"id": "gid://gitlab/IncidentManagement::EscalationRule/48",
"status": "ACKNOWLEDGED",
"elapsedTimeSeconds": 30,
"elapsedTimeSeconds": 180,
"oncallSchedule": {
"iid": "3",
"name": "Schedule to fill in"
......
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