Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
1
Merge Requests
1
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
gitlab-ce
Commits
7afd4ad1
Commit
7afd4ad1
authored
Dec 18, 2020
by
Olena Horal-Koretska
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Enable end date/time for rotations
parent
ed41b143
Changes
6
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
167 additions
and
18 deletions
+167
-18
app/assets/stylesheets/page_bundles/oncall_schedules.scss
app/assets/stylesheets/page_bundles/oncall_schedules.scss
+12
-0
ee/app/assets/javascripts/oncall_schedules/components/rotations/components/add_edit_rotation_form.vue
...omponents/rotations/components/add_edit_rotation_form.vue
+52
-3
ee/app/assets/javascripts/oncall_schedules/components/rotations/components/add_edit_rotation_modal.vue
...mponents/rotations/components/add_edit_rotation_modal.vue
+5
-1
ee/spec/frontend/oncall_schedule/rotations/components/__snapshots__/add_edit_rotation_modal_spec.js.snap
...onents/__snapshots__/add_edit_rotation_modal_spec.js.snap
+2
-2
ee/spec/frontend/oncall_schedule/rotations/components/add_edit_rotation_form_spec.js
...edule/rotations/components/add_edit_rotation_form_spec.js
+90
-12
locale/gitlab.pot
locale/gitlab.pot
+6
-0
No files found.
app/assets/stylesheets/page_bundles/oncall_schedules.scss
View file @
7afd4ad1
...
...
@@ -29,6 +29,18 @@
}
}
.rotations-modal
{
.gl-card
{
min-width
:
75%
;
width
:
fit-content
;
@include
gl-bg-gray-10
;
}
&
.gl-modal
.modal-md
{
max-width
:
640px
;
}
}
//// Copied from roadmaps.scss - adapted for on-call schedules
$header-item-height
:
72px
;
$item-height
:
40px
;
...
...
ee/app/assets/javascripts/oncall_schedules/components/rotations/components/add_edit_rotation_form.vue
View file @
7afd4ad1
...
...
@@ -9,6 +9,8 @@ import {
GlTokenSelector
,
GlAvatar
,
GlAvatarLabeled
,
GlToggle
,
GlCard
,
}
from
'
@gitlab/ui
'
;
import
{
LENGTH_ENUM
,
...
...
@@ -33,6 +35,10 @@ export const i18n = {
title
:
__
(
'
Starts on
'
),
error
:
s__
(
'
OnCallSchedules|Rotation start date cannot be empty
'
),
},
endsOn
:
{
enableToggle
:
s__
(
'
OnCallSchedules|Enable end date
'
),
title
:
__
(
'
Ends on
'
),
},
},
};
...
...
@@ -55,6 +61,8 @@ export default {
GlTokenSelector
,
GlAvatar
,
GlAvatarLabeled
,
GlToggle
,
GlCard
,
},
props
:
{
form
:
{
...
...
@@ -82,6 +90,7 @@ export default {
data
()
{
return
{
participantsArr
:
[],
endDateEnabled
:
false
,
};
},
methods
:
{
...
...
@@ -150,7 +159,7 @@ export default {
:value=
"1"
@
input=
"$emit('update-rotation-form', { type: 'rotationLength.length', value: $event })"
/>
<gl-dropdown
id=
"rotation-length"
:text=
"form.rotationLength.unit.toLowerCase()"
>
<gl-dropdown
:text=
"form.rotationLength.unit.toLowerCase()"
>
<gl-dropdown-item
v-for=
"unit in $options.LENGTH_ENUM"
:key=
"unit"
...
...
@@ -167,7 +176,7 @@ export default {
<gl-form-group
:label=
"$options.i18n.fields.startsAt.title"
label-size=
"sm"
label-for=
"rotation-time"
label-for=
"rotation-
start-
time"
:invalid-feedback=
"$options.i18n.fields.startsAt.error"
:state=
"validationState.startsAt"
>
...
...
@@ -189,7 +198,7 @@ export default {
</gl-datepicker>
<span>
{{ __('at') }}
</span>
<gl-dropdown
id=
"rotation-time"
id=
"rotation-
start-
time"
:text=
"format24HourTimeStringFromInt(form.startsAt.time)"
class=
"gl-w-12 gl-pl-3"
>
...
...
@@ -206,5 +215,45 @@ export default {
<span
class=
"gl-pl-5"
>
{{ schedule.timezone }}
</span>
</div>
</gl-form-group>
<gl-toggle
v-model=
"endDateEnabled"
:label=
"$options.i18n.fields.endsOn.enableToggle"
label-position=
"left"
class=
"gl-mb-5"
/>
<gl-card
v-if=
"endDateEnabled"
class=
"gl-min-w-fit-content"
data-testid=
"rotation-ends-on"
>
<gl-form-group
:label=
"$options.i18n.fields.endsOn.title"
label-size=
"sm"
label-for=
"rotation-end-time"
:invalid-feedback=
"$options.i18n.fields.endsOn.error"
>
<div
class=
"gl-display-flex gl-align-items-center"
>
<gl-datepicker
class=
"gl-mr-3"
@
input=
"$emit('update-rotation-form', { type: 'endsOn.date', value: $event })"
/>
<span>
{{ __('at') }}
</span>
<gl-dropdown
id=
"rotation-end-time"
:text=
"format24HourTimeStringFromInt(form.endsOn.time)"
class=
"gl-w-12 gl-pl-3"
>
<gl-dropdown-item
v-for=
"time in $options.HOURS_IN_DAY"
:key=
"time"
:is-checked=
"form.endsOn.time === time"
is-check-item
@
click=
"$emit('update-rotation-form', { type: 'endsOn.time', value: time })"
>
<span
class=
"gl-white-space-nowrap"
>
{{ format24HourTimeStringFromInt(time) }}
</span>
</gl-dropdown-item>
</gl-dropdown>
<div
class=
"gl-mx-5"
>
{{ schedule.timezone }}
</div>
</div>
</gl-form-group>
</gl-card>
</gl-form>
</template>
ee/app/assets/javascripts/oncall_schedules/components/rotations/components/add_edit_rotation_modal.vue
View file @
7afd4ad1
...
...
@@ -80,6 +80,10 @@ export default {
date
:
null
,
time
:
0
,
},
endsOn
:
{
date
:
null
,
time
:
0
,
},
},
error
:
''
,
validationState
:
{
...
...
@@ -241,10 +245,10 @@ export default {
<gl-modal
ref=
"addEditScheduleRotationModal"
:modal-id=
"modalId"
size=
"sm"
:title=
"title"
:action-primary=
"actionsProps.primary"
:action-cancel=
"actionsProps.cancel"
modal-class=
"rotations-modal"
@
primary.prevent=
"isEditMode ? editRotation() : createRotation()"
>
<gl-alert
v-if=
"error"
variant=
"danger"
@
dismiss=
"error = ''"
>
...
...
ee/spec/frontend/oncall_schedule/rotations/components/__snapshots__/add_edit_rotation_modal_spec.js.snap
View file @
7afd4ad1
...
...
@@ -5,9 +5,9 @@ exports[`AddEditRotationModal renders rotation modal layout 1`] = `
actioncancel="[object Object]"
actionprimary="[object Object]"
dismisslabel="Close"
modalclass=""
modalclass="
rotations-modal
"
modalid="addRotationModal"
size="
sm
"
size="
md
"
title="Add rotation"
titletag="h4"
>
...
...
ee/spec/frontend/oncall_schedule/rotations/components/add_edit_rotation_form_spec.js
View file @
7afd4ad1
import
{
shallowMount
}
from
'
@vue/test-utils
'
;
import
waitForPromises
from
'
helpers/wait_for_promises
'
;
import
{
GlDropdownItem
,
GlTokenSelector
,
GlFormGroup
}
from
'
@gitlab/ui
'
;
import
{
GlDropdownItem
,
GlTokenSelector
,
GlFormGroup
,
GlToggle
}
from
'
@gitlab/ui
'
;
import
AddEditRotationForm
from
'
ee/oncall_schedules/components/rotations/components/add_edit_rotation_form.vue
'
;
import
{
LENGTH_ENUM
}
from
'
ee/oncall_schedules/constants
'
;
import
{
participants
,
getOncallSchedulesQueryResponse
}
from
'
../../mocks/apollo_mock
'
;
...
...
@@ -40,6 +40,10 @@ describe('AddEditRotationForm', () => {
date
:
null
,
time
:
0
,
},
endsOn
:
{
date
:
null
,
time
:
0
,
},
},
},
provide
:
{
...
...
@@ -53,14 +57,20 @@ describe('AddEditRotationForm', () => {
});
afterEach
(()
=>
{
if
(
wrapper
)
{
wrapper
.
destroy
();
}
});
const
findRotationLength
=
()
=>
wrapper
.
find
(
'
[id = "rotation-length"]
'
);
const
findRotationStartsOn
=
()
=>
wrapper
.
find
(
'
[id = "rotation-time"]
'
);
const
findRotationLength
=
()
=>
wrapper
.
find
(
'
[id="rotation-length"]
'
);
const
findRotationStartTime
=
()
=>
wrapper
.
find
(
'
[id="rotation-start-time"]
'
);
const
findRotationEndsContainer
=
()
=>
wrapper
.
find
(
'
[data-testid="rotation-ends-on"]
'
);
const
findEndDateToggle
=
()
=>
wrapper
.
find
(
GlToggle
);
const
findRotationEndTime
=
()
=>
wrapper
.
find
(
'
[id="rotation-end-time"]
'
);
const
findUserSelector
=
()
=>
wrapper
.
find
(
GlTokenSelector
);
const
findDropdownOptions
=
()
=>
wrapper
.
findAllComponents
(
GlDropdownItem
);
const
findRotationFormGroups
=
()
=>
wrapper
.
findAllComponents
(
GlFormGroup
);
const
findStartsOnTimeOptions
=
()
=>
findRotationStartTime
().
findAllComponents
(
GlDropdownItem
);
const
findEndsOnTimeOptions
=
()
=>
findRotationEndTime
().
findAllComponents
(
GlDropdownItem
);
describe
(
'
Rotation form validation
'
,
()
=>
{
it
.
each
`
...
...
@@ -85,19 +95,87 @@ describe('AddEditRotationForm', () => {
});
it
(
'
renders the rotation starts on datepicker
'
,
async
()
=>
{
const
startsOn
=
findRotationStart
sOn
();
const
startsOn
=
findRotationStart
Time
();
expect
(
startsOn
.
exists
()).
toBe
(
true
);
expect
(
startsOn
.
attributes
(
'
text
'
)).
toBe
(
'
00:00
'
);
expect
(
startsOn
.
attributes
(
'
headertext
'
)).
toBe
(
''
);
});
it
(
'
should add a check for a rotation length type selected
'
,
async
()
=>
{
const
selectedLengthType1
=
findDropdownOptions
().
at
(
0
);
const
selectedLengthType2
=
findDropdownOptions
().
at
(
1
);
selectedLengthType1
.
vm
.
$emit
(
'
click
'
);
it
(
'
should emit an event with selected value on time selection
'
,
async
()
=>
{
findStartsOnTimeOptions
().
at
(
3
).
vm
.
$emit
(
'
click
'
);
await
wrapper
.
vm
.
$nextTick
();
const
emittedEvent
=
wrapper
.
emitted
(
'
update-rotation-form
'
);
expect
(
emittedEvent
).
toHaveLength
(
1
);
expect
(
emittedEvent
[
0
][
0
]).
toEqual
({
type
:
'
startsAt.time
'
,
value
:
4
});
});
it
(
'
should add a checkmark to a selected start time
'
,
async
()
=>
{
const
time
=
7
;
wrapper
.
setProps
({
form
:
{
startsAt
:
{
time
,
},
rotationLength
:
{
length
:
1
,
unit
:
LENGTH_ENUM
.
hours
,
},
},
});
await
wrapper
.
vm
.
$nextTick
();
expect
(
findStartsOnTimeOptions
()
.
at
(
time
-
1
)
.
props
(
'
isChecked
'
),
).
toBe
(
true
);
});
});
describe
(
'
Rotation end time
'
,
()
=>
{
it
(
'
toggles end time visibility
'
,
async
()
=>
{
const
toggle
=
findEndDateToggle
().
vm
;
toggle
.
$emit
(
'
change
'
,
false
);
await
wrapper
.
vm
.
$nextTick
();
expect
(
findRotationEndsContainer
().
exists
()).
toBe
(
false
);
toggle
.
$emit
(
'
change
'
,
true
);
await
wrapper
.
vm
.
$nextTick
();
expect
(
findRotationEndsContainer
().
exists
()).
toBe
(
true
);
});
it
(
'
should emit an event with selected value on time selection
'
,
async
()
=>
{
findEndDateToggle
().
vm
.
$emit
(
'
change
'
,
true
);
await
wrapper
.
vm
.
$nextTick
();
const
option
=
3
;
findEndsOnTimeOptions
().
at
(
option
).
vm
.
$emit
(
'
click
'
);
await
wrapper
.
vm
.
$nextTick
();
const
emittedEvent
=
wrapper
.
emitted
(
'
update-rotation-form
'
);
expect
(
emittedEvent
).
toHaveLength
(
1
);
expect
(
emittedEvent
[
0
][
0
]).
toEqual
({
type
:
'
endsOn.time
'
,
value
:
option
+
1
});
});
it
(
'
should add a checkmark to a selected end time
'
,
async
()
=>
{
findEndDateToggle
().
vm
.
$emit
(
'
change
'
,
true
);
const
time
=
5
;
wrapper
.
setProps
({
form
:
{
endsOn
:
{
time
,
},
startsAt
:
{
time
:
0
,
},
rotationLength
:
{
length
:
1
,
unit
:
LENGTH_ENUM
.
hours
,
},
},
});
await
wrapper
.
vm
.
$nextTick
();
expect
(
selectedLengthType1
.
props
(
'
isChecked
'
)).
toBe
(
true
);
expect
(
selectedLengthType2
.
props
(
'
isChecked
'
)).
toBe
(
false
);
expect
(
findEndsOnTimeOptions
()
.
at
(
time
-
1
)
.
props
(
'
isChecked
'
),
).
toBe
(
true
);
});
});
...
...
locale/gitlab.pot
View file @
7afd4ad1
...
...
@@ -10758,6 +10758,9 @@ msgstr ""
msgid "Ends at (UTC)"
msgstr ""
msgid "Ends on"
msgstr ""
msgid "Enforce DNS rebinding attack protection"
msgstr ""
...
...
@@ -19591,6 +19594,9 @@ msgstr ""
msgid "OnCallSchedules|Edit schedule"
msgstr ""
msgid "OnCallSchedules|Enable end date"
msgstr ""
msgid "OnCallSchedules|Failed to add rotation"
msgstr ""
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment