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
18d0b537
Commit
18d0b537
authored
Jan 07, 2021
by
David O'Regan
Committed by
Mark Florian
Jan 07, 2021
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
fix(feedback): apply merge feedback
fix(feedback): apply merge feedback
parent
6dc17497
Changes
11
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
146 additions
and
87 deletions
+146
-87
ee/app/assets/javascripts/oncall_schedules/components/add_edit_schedule_form.vue
...ts/oncall_schedules/components/add_edit_schedule_form.vue
+15
-12
ee/app/assets/javascripts/oncall_schedules/components/add_edit_schedule_modal.vue
...s/oncall_schedules/components/add_edit_schedule_modal.vue
+19
-13
ee/app/assets/javascripts/oncall_schedules/components/oncall_schedule.vue
...vascripts/oncall_schedules/components/oncall_schedule.vue
+0
-1
ee/app/assets/javascripts/oncall_schedules/components/rotations/components/add_edit_rotation_form.vue
...omponents/rotations/components/add_edit_rotation_form.vue
+21
-17
ee/app/assets/javascripts/oncall_schedules/components/rotations/components/add_edit_rotation_modal.vue
...mponents/rotations/components/add_edit_rotation_modal.vue
+26
-25
ee/app/assets/javascripts/oncall_schedules/components/rotations/components/rotation_assignee.vue
...les/components/rotations/components/rotation_assignee.vue
+1
-1
ee/app/assets/javascripts/oncall_schedules/utils/common_utils.js
...assets/javascripts/oncall_schedules/utils/common_utils.js
+11
-0
ee/spec/frontend/oncall_schedule/__snapshots__/add_edit_schedule_form_spec.js.snap
...chedule/__snapshots__/add_edit_schedule_form_spec.js.snap
+3
-1
ee/spec/frontend/oncall_schedule/add_edit_schedule_form_spec.js
...c/frontend/oncall_schedule/add_edit_schedule_form_spec.js
+26
-12
ee/spec/frontend/oncall_schedule/rotations/components/__snapshots__/add_edit_rotation_modal_spec.js.snap
...onents/__snapshots__/add_edit_rotation_modal_spec.js.snap
+1
-0
ee/spec/frontend/oncall_schedule/rotations/components/add_edit_rotation_form_spec.js
...edule/rotations/components/add_edit_rotation_form_spec.js
+23
-5
No files found.
ee/app/assets/javascripts/oncall_schedules/components/add_edit_schedule_form.vue
View file @
18d0b537
...
@@ -52,12 +52,8 @@ export default {
...
@@ -52,12 +52,8 @@ export default {
type
:
Object
,
type
:
Object
,
required
:
true
,
required
:
true
,
},
},
isNameInvalid
:
{
validationState
:
{
type
:
Boolean
,
type
:
Object
,
required
:
true
,
},
isTimezoneInvalid
:
{
type
:
Boolean
,
required
:
true
,
required
:
true
,
},
},
schedule
:
{
schedule
:
{
...
@@ -69,6 +65,7 @@ export default {
...
@@ -69,6 +65,7 @@ export default {
data
()
{
data
()
{
return
{
return
{
tzSearchTerm
:
''
,
tzSearchTerm
:
''
,
selectedDropdownTimezone
:
null
,
};
};
},
},
computed
:
{
computed
:
{
...
@@ -94,6 +91,9 @@ export default {
...
@@ -94,6 +91,9 @@ export default {
isTimezoneSelected
(
tz
)
{
isTimezoneSelected
(
tz
)
{
return
isEqual
(
tz
,
this
.
form
.
timezone
);
return
isEqual
(
tz
,
this
.
form
.
timezone
);
},
},
setTimezone
(
timezone
)
{
this
.
selectedDropdownTimezone
=
timezone
;
},
},
},
};
};
</
script
>
</
script
>
...
@@ -105,12 +105,13 @@ export default {
...
@@ -105,12 +105,13 @@ export default {
:invalid-feedback=
"$options.i18n.fields.name.validation.empty"
:invalid-feedback=
"$options.i18n.fields.name.validation.empty"
label-size=
"sm"
label-size=
"sm"
label-for=
"schedule-name"
label-for=
"schedule-name"
:state=
"validationState.name"
requried
>
>
<gl-form-input
<gl-form-input
id=
"schedule-name"
id=
"schedule-name"
:value=
"form.name"
:value=
"form.name"
:state=
"!isNameInvalid"
@
blur=
"$emit('update-schedule-form',
{ type: 'name', value: $event.target.value })"
@
input=
"$emit('update-schedule-form',
{ type: 'name', value: $event })"
/>
/>
</gl-form-group>
</gl-form-group>
...
@@ -122,7 +123,7 @@ export default {
...
@@ -122,7 +123,7 @@ export default {
<gl-form-input
<gl-form-input
id=
"schedule-description"
id=
"schedule-description"
:value=
"form.description"
:value=
"form.description"
@
input=
"$emit('update-schedule-form',
{ type: 'description', value: $event
})"
@
blur=
"$emit('update-schedule-form',
{ type: 'description', value: $event.target.value
})"
/>
/>
</gl-form-group>
</gl-form-group>
...
@@ -131,15 +132,17 @@ export default {
...
@@ -131,15 +132,17 @@ export default {
label-size=
"sm"
label-size=
"sm"
label-for=
"schedule-timezone"
label-for=
"schedule-timezone"
:description=
"$options.i18n.fields.timezone.description"
:description=
"$options.i18n.fields.timezone.description"
:state=
"
!isTimezoneInvalid
"
:state=
"
validationState.timezone
"
:invalid-feedback=
"$options.i18n.fields.timezone.validation.empty"
:invalid-feedback=
"$options.i18n.fields.timezone.validation.empty"
requried
>
>
<gl-dropdown
<gl-dropdown
id=
"schedule-timezone"
id=
"schedule-timezone"
:text=
"selectedTimezone"
:text=
"selectedTimezone"
class=
"timezone-dropdown gl-w-full"
class=
"timezone-dropdown gl-w-full"
:header-text=
"$options.i18n.selectTimezone"
:header-text=
"$options.i18n.selectTimezone"
:class=
"
{ 'invalid-dropdown': isTimezoneInvalid }"
:class=
"
{ 'invalid-dropdown': !validationState.timezone }"
@hide="$emit('update-schedule-form', { type: 'timezone', value: selectedDropdownTimezone })"
>
>
<gl-search-box-by-type
v-model.trim=
"tzSearchTerm"
/>
<gl-search-box-by-type
v-model.trim=
"tzSearchTerm"
/>
<gl-dropdown-item
<gl-dropdown-item
...
@@ -147,7 +150,7 @@ export default {
...
@@ -147,7 +150,7 @@ export default {
:key=
"getFormattedTimezone(tz)"
:key=
"getFormattedTimezone(tz)"
:is-checked=
"isTimezoneSelected(tz)"
:is-checked=
"isTimezoneSelected(tz)"
is-check-item
is-check-item
@
click=
"
$emit('update-schedule-form',
{ type: 'timezone', value: tz }
)"
@
click=
"
setTimezone(tz
)"
>
>
<span
class=
"gl-white-space-nowrap"
>
{{
getFormattedTimezone
(
tz
)
}}
</span>
<span
class=
"gl-white-space-nowrap"
>
{{
getFormattedTimezone
(
tz
)
}}
</span>
</gl-dropdown-item>
</gl-dropdown-item>
...
...
ee/app/assets/javascripts/oncall_schedules/components/add_edit_schedule_modal.vue
View file @
18d0b537
...
@@ -7,6 +7,7 @@ import createOncallScheduleMutation from '../graphql/mutations/create_oncall_sch
...
@@ -7,6 +7,7 @@ import createOncallScheduleMutation from '../graphql/mutations/create_oncall_sch
import
updateOncallScheduleMutation
from
'
../graphql/mutations/update_oncall_schedule.mutation.graphql
'
;
import
updateOncallScheduleMutation
from
'
../graphql/mutations/update_oncall_schedule.mutation.graphql
'
;
import
AddEditScheduleForm
from
'
./add_edit_schedule_form.vue
'
;
import
AddEditScheduleForm
from
'
./add_edit_schedule_form.vue
'
;
import
{
updateStoreOnScheduleCreate
,
updateStoreAfterScheduleEdit
}
from
'
../utils/cache_updates
'
;
import
{
updateStoreOnScheduleCreate
,
updateStoreAfterScheduleEdit
}
from
'
../utils/cache_updates
'
;
import
{
isNameFieldValid
}
from
'
../utils/common_utils
'
;
export
const
i18n
=
{
export
const
i18n
=
{
cancel
:
__
(
'
Cancel
'
),
cancel
:
__
(
'
Cancel
'
),
...
@@ -48,7 +49,11 @@ export default {
...
@@ -48,7 +49,11 @@ export default {
description
:
this
.
schedule
?.
description
,
description
:
this
.
schedule
?.
description
,
timezone
:
this
.
timezones
.
find
(({
identifier
})
=>
this
.
schedule
?.
timezone
===
identifier
),
timezone
:
this
.
timezones
.
find
(({
identifier
})
=>
this
.
schedule
?.
timezone
===
identifier
),
},
},
error
:
null
,
error
:
''
,
validationState
:
{
name
:
true
,
timezone
:
true
,
},
};
};
},
},
computed
:
{
computed
:
{
...
@@ -59,7 +64,7 @@ export default {
...
@@ -59,7 +64,7 @@ export default {
attributes
:
[
attributes
:
[
{
variant
:
'
info
'
},
{
variant
:
'
info
'
},
{
loading
:
this
.
loading
},
{
loading
:
this
.
loading
},
{
disabled
:
this
.
isFormInv
alid
},
{
disabled
:
!
this
.
isFormV
alid
},
],
],
},
},
cancel
:
{
cancel
:
{
...
@@ -67,14 +72,8 @@ export default {
...
@@ -67,14 +72,8 @@ export default {
},
},
};
};
},
},
isNameInvalid
()
{
isFormValid
()
{
return
!
this
.
form
.
name
?.
length
;
return
Object
.
values
(
this
.
validationState
).
every
(
Boolean
);
},
isTimezoneInvalid
()
{
return
isEmpty
(
this
.
form
.
timezone
);
},
isFormInvalid
()
{
return
this
.
isNameInvalid
||
this
.
isTimezoneInvalid
;
},
},
editScheduleVariables
()
{
editScheduleVariables
()
{
return
{
return
{
...
@@ -169,10 +168,18 @@ export default {
...
@@ -169,10 +168,18 @@ export default {
});
});
},
},
hideErrorAlert
()
{
hideErrorAlert
()
{
this
.
error
=
null
;
this
.
error
=
''
;
},
},
updateScheduleForm
({
type
,
value
})
{
updateScheduleForm
({
type
,
value
})
{
this
.
form
[
type
]
=
value
;
this
.
form
[
type
]
=
value
;
this
.
validateForm
(
type
);
},
validateForm
(
key
)
{
if
(
key
===
'
name
'
)
{
this
.
validationState
.
name
=
isNameFieldValid
(
this
.
form
.
name
);
}
else
if
(
key
===
'
timezone
'
)
{
this
.
validationState
.
timezone
=
!
isEmpty
(
this
.
form
.
timezone
);
}
},
},
},
},
};
};
...
@@ -192,8 +199,7 @@ export default {
...
@@ -192,8 +199,7 @@ export default {
{{
errorMsg
}}
{{
errorMsg
}}
</gl-alert>
</gl-alert>
<add-edit-schedule-form
<add-edit-schedule-form
:is-name-invalid=
"isNameInvalid"
:validation-state=
"validationState"
:is-timezone-invalid=
"isTimezoneInvalid"
:form=
"form"
:form=
"form"
:schedule=
"schedule"
:schedule=
"schedule"
@
update-schedule-form=
"updateScheduleForm"
@
update-schedule-form=
"updateScheduleForm"
...
...
ee/app/assets/javascripts/oncall_schedules/components/oncall_schedule.vue
View file @
18d0b537
...
@@ -143,7 +143,6 @@ export default {
...
@@ -143,7 +143,6 @@ export default {
</gl-card>
</gl-card>
</gl-card>
</gl-card>
<delete-schedule-modal
:schedule=
"schedule"
:modal-id=
"$options.deleteScheduleModalId"
/>
<delete-schedule-modal
:schedule=
"schedule"
:modal-id=
"$options.deleteScheduleModalId"
/>
<edit-schedule-modal
:schedule=
"schedule"
:modal-id=
"$options.editScheduleModalId"
/>
<edit-schedule-modal
<edit-schedule-modal
:schedule=
"schedule"
:schedule=
"schedule"
:modal-id=
"$options.editScheduleModalId"
:modal-id=
"$options.editScheduleModalId"
...
...
ee/app/assets/javascripts/oncall_schedules/components/rotations/components/add_edit_rotation_form.vue
View file @
18d0b537
...
@@ -10,13 +10,13 @@ import {
...
@@ -10,13 +10,13 @@ import {
GlAvatar
,
GlAvatar
,
GlAvatarLabeled
,
GlAvatarLabeled
,
}
from
'
@gitlab/ui
'
;
}
from
'
@gitlab/ui
'
;
import
{
s__
,
__
}
from
'
~/locale
'
;
import
{
import
{
LENGTH_ENUM
,
LENGTH_ENUM
,
HOURS_IN_DAY
,
HOURS_IN_DAY
,
CHEVRON_SKIPPING_SHADE_ENUM
,
CHEVRON_SKIPPING_SHADE_ENUM
,
CHEVRON_SKIPPING_PALETTE_ENUM
,
CHEVRON_SKIPPING_PALETTE_ENUM
,
}
from
'
../../../constants
'
;
}
from
'
ee/oncall_schedules/constants
'
;
import
{
s__
,
__
}
from
'
~/locale
'
;
import
{
format24HourTimeStringFromInt
}
from
'
~/lib/utils/datetime_utility
'
;
import
{
format24HourTimeStringFromInt
}
from
'
~/lib/utils/datetime_utility
'
;
export
const
i18n
=
{
export
const
i18n
=
{
...
@@ -65,16 +65,8 @@ export default {
...
@@ -65,16 +65,8 @@ export default {
type
:
Boolean
,
type
:
Boolean
,
required
:
true
,
required
:
true
,
},
},
rotationNameIsValid
:
{
validationState
:
{
type
:
Boolean
,
type
:
Object
,
required
:
true
,
},
rotationParticipantsAreValid
:
{
type
:
Boolean
,
required
:
true
,
},
rotationStartsAtIsValid
:
{
type
:
Boolean
,
required
:
true
,
required
:
true
,
},
},
participants
:
{
participants
:
{
...
@@ -105,11 +97,11 @@ export default {
...
@@ -105,11 +97,11 @@ export default {
label-size=
"sm"
label-size=
"sm"
label-for=
"rotation-name"
label-for=
"rotation-name"
:invalid-feedback=
"$options.i18n.fields.name.error"
:invalid-feedback=
"$options.i18n.fields.name.error"
:state=
"
rotationNameIsValid
"
:state=
"
validationState.name
"
>
>
<gl-form-input
<gl-form-input
id=
"rotation-name"
id=
"rotation-name"
@
input=
"$emit('update-rotation-form',
{ type: 'name', value: $event
})"
@
blur=
"$emit('update-rotation-form',
{ type: 'name', value: $event.target.value
})"
/>
/>
</gl-form-group>
</gl-form-group>
...
@@ -118,7 +110,7 @@ export default {
...
@@ -118,7 +110,7 @@ export default {
label-size=
"sm"
label-size=
"sm"
label-for=
"rotation-participants"
label-for=
"rotation-participants"
:invalid-feedback=
"$options.i18n.fields.participants.error"
:invalid-feedback=
"$options.i18n.fields.participants.error"
:state=
"
rotationParticipantsAreValid
"
:state=
"
validationState.participants
"
>
>
<gl-token-selector
<gl-token-selector
v-model=
"participantsArr"
v-model=
"participantsArr"
...
@@ -126,6 +118,7 @@ export default {
...
@@ -126,6 +118,7 @@ export default {
:loading=
"isLoading"
:loading=
"isLoading"
container-class=
"gl-h-13! gl-overflow-y-auto"
container-class=
"gl-h-13! gl-overflow-y-auto"
@
text-input=
"$emit('filter-participants', $event)"
@
text-input=
"$emit('filter-participants', $event)"
@
blur=
"$emit('update-rotation-form',
{ type: 'participants', value: participantsArr })"
@input="$emit('update-rotation-form', { type: 'participants', value: participantsArr })"
@input="$emit('update-rotation-form', { type: 'participants', value: participantsArr })"
>
>
<template
#token-content
="
{ token }">
<template
#token-content
="
{ token }">
...
@@ -176,13 +169,24 @@ export default {
...
@@ -176,13 +169,24 @@ export default {
label-size=
"sm"
label-size=
"sm"
label-for=
"rotation-time"
label-for=
"rotation-time"
:invalid-feedback=
"$options.i18n.fields.startsAt.error"
:invalid-feedback=
"$options.i18n.fields.startsAt.error"
:state=
"
rotationStartsAtIsValid
"
:state=
"
validationState.startsAt
"
>
>
<div
class=
"gl-display-flex gl-align-items-center"
>
<div
class=
"gl-display-flex gl-align-items-center"
>
<gl-datepicker
<gl-datepicker
class=
"gl-mr-3"
class=
"gl-mr-3"
@
input=
"$emit('update-rotation-form', { type: 'startsAt.date', value: $event })"
@
input=
"$emit('update-rotation-form', { type: 'startsAt.date', value: $event })"
/>
>
<
template
#default=
"{ formattedDate }"
>
<gl-form-input
class=
"gl-w-full"
:value=
"formattedDate"
:placeholder=
"__(`YYYY-MM-DD`)"
@
blur=
"
$emit('update-rotation-form',
{ type: 'startsAt.date', value: $event.target.value })
"
/>
</
template
>
</gl-datepicker>
<span>
{{ __('at') }}
</span>
<span>
{{ __('at') }}
</span>
<gl-dropdown
<gl-dropdown
id=
"rotation-time"
id=
"rotation-time"
...
...
ee/app/assets/javascripts/oncall_schedules/components/rotations/components/add_edit_rotation_modal.vue
View file @
18d0b537
<
script
>
<
script
>
import
{
GlModal
,
GlAlert
}
from
'
@gitlab/ui
'
;
import
{
GlModal
,
GlAlert
}
from
'
@gitlab/ui
'
;
import
{
set
}
from
'
lodash
'
;
import
{
set
}
from
'
lodash
'
;
import
getOncallSchedulesQuery
from
'
ee/oncall_schedules/graphql/queries/get_oncall_schedules.query.graphql
'
;
import
createOncallScheduleRotationMutation
from
'
ee/oncall_schedules/graphql/mutations/create_oncall_schedule_rotation.mutation.graphql
'
;
import
updateOncallScheduleRotationMutation
from
'
ee/oncall_schedules/graphql/mutations/update_oncall_schedule_rotation.mutation.graphql
'
;
import
{
LENGTH_ENUM
}
from
'
ee/oncall_schedules/constants
'
;
import
{
updateStoreAfterRotationAdd
,
updateStoreAfterRotationEdit
,
}
from
'
ee/oncall_schedules/utils/cache_updates
'
;
import
{
isNameFieldValid
}
from
'
ee/oncall_schedules/utils/common_utils
'
;
import
{
s__
,
__
}
from
'
~/locale
'
;
import
{
s__
,
__
}
from
'
~/locale
'
;
import
createFlash
,
{
FLASH_TYPES
}
from
'
~/flash
'
;
import
createFlash
,
{
FLASH_TYPES
}
from
'
~/flash
'
;
import
usersSearchQuery
from
'
~/graphql_shared/queries/users_search.query.graphql
'
;
import
usersSearchQuery
from
'
~/graphql_shared/queries/users_search.query.graphql
'
;
import
getOncallSchedulesQuery
from
'
../../../graphql/queries/get_oncall_schedules.query.graphql
'
;
import
createOncallScheduleRotationMutation
from
'
../../../graphql/mutations/create_oncall_schedule_rotation.mutation.graphql
'
;
import
updateOncallScheduleRotationMutation
from
'
../../../graphql/mutations/update_oncall_schedule_rotation.mutation.graphql
'
;
import
{
LENGTH_ENUM
}
from
'
../../../constants
'
;
import
AddEditRotationForm
from
'
./add_edit_rotation_form.vue
'
;
import
AddEditRotationForm
from
'
./add_edit_rotation_form.vue
'
;
import
{
updateStoreAfterRotationAdd
,
updateStoreAfterRotationEdit
,
}
from
'
../../../utils/cache_updates
'
;
import
{
format24HourTimeStringFromInt
}
from
'
~/lib/utils/datetime_utility
'
;
import
{
format24HourTimeStringFromInt
}
from
'
~/lib/utils/datetime_utility
'
;
export
const
i18n
=
{
export
const
i18n
=
{
...
@@ -81,6 +82,11 @@ export default {
...
@@ -81,6 +82,11 @@ export default {
},
},
},
},
error
:
''
,
error
:
''
,
validationState
:
{
name
:
true
,
participants
:
true
,
startsAt
:
true
,
},
};
};
},
},
computed
:
{
computed
:
{
...
@@ -99,15 +105,6 @@ export default {
...
@@ -99,15 +105,6 @@ export default {
},
},
};
};
},
},
rotationNameIsValid
()
{
return
this
.
form
.
name
!==
''
;
},
rotationParticipantsAreValid
()
{
return
this
.
form
.
participants
.
length
>
0
;
},
rotationStartsAtIsValid
()
{
return
Boolean
(
this
.
form
.
startsAt
.
date
);
},
rotationVariables
()
{
rotationVariables
()
{
return
{
return
{
projectPath
:
this
.
projectPath
,
projectPath
:
this
.
projectPath
,
...
@@ -130,11 +127,7 @@ export default {
...
@@ -130,11 +127,7 @@ export default {
};
};
},
},
isFormValid
()
{
isFormValid
()
{
return
(
return
Object
.
values
(
this
.
validationState
).
every
(
Boolean
);
this
.
rotationNameIsValid
&&
this
.
rotationParticipantsAreValid
&&
this
.
rotationStartsAtIsValid
);
},
},
isLoading
()
{
isLoading
()
{
return
this
.
loading
||
this
.
$apollo
.
queries
.
participants
.
loading
;
return
this
.
loading
||
this
.
$apollo
.
queries
.
participants
.
loading
;
...
@@ -226,10 +219,20 @@ export default {
...
@@ -226,10 +219,20 @@ export default {
},
},
updateRotationForm
({
type
,
value
})
{
updateRotationForm
({
type
,
value
})
{
set
(
this
.
form
,
type
,
value
);
set
(
this
.
form
,
type
,
value
);
this
.
validateForm
(
type
);
},
},
filterParticipants
(
query
)
{
filterParticipants
(
query
)
{
this
.
ptSearchTerm
=
query
;
this
.
ptSearchTerm
=
query
;
},
},
validateForm
(
key
)
{
if
(
key
===
'
name
'
)
{
this
.
validationState
.
name
=
isNameFieldValid
(
this
.
form
.
name
);
}
else
if
(
key
===
'
participants
'
)
{
this
.
validationState
.
participants
=
this
.
form
.
participants
.
length
>
0
;
}
else
if
(
key
===
'
startsAt.date
'
)
{
this
.
validationState
.
startsAt
=
Boolean
(
this
.
form
.
startsAt
.
date
);
}
},
},
},
};
};
</
script
>
</
script
>
...
@@ -248,9 +251,7 @@ export default {
...
@@ -248,9 +251,7 @@ export default {
{{
error
||
$options
.
i18n
.
errorMsg
}}
{{
error
||
$options
.
i18n
.
errorMsg
}}
</gl-alert>
</gl-alert>
<add-edit-rotation-form
<add-edit-rotation-form
:rotation-name-is-valid=
"rotationNameIsValid"
:validation-state=
"validationState"
:rotation-participants-are-valid=
"rotationParticipantsAreValid"
:rotation-starts-at-is-valid=
"rotationStartsAtIsValid"
:form=
"form"
:form=
"form"
:schedule=
"schedule"
:schedule=
"schedule"
:participants=
"participants"
:participants=
"participants"
...
...
ee/app/assets/javascripts/oncall_schedules/components/rotations/components/rotation_assignee.vue
View file @
18d0b537
<
script
>
<
script
>
import
{
GlToken
,
GlAvatarLabeled
,
GlPopover
}
from
'
@gitlab/ui
'
;
import
{
GlToken
,
GlAvatarLabeled
,
GlPopover
}
from
'
@gitlab/ui
'
;
import
{
assigneeScheduleDateStart
}
from
'
ee/oncall_schedules/utils/common_utils
'
;
import
{
__
,
sprintf
}
from
'
~/locale
'
;
import
{
__
,
sprintf
}
from
'
~/locale
'
;
import
{
assigneeScheduleDateStart
}
from
'
../../../utils/common_utils
'
;
export
default
{
export
default
{
components
:
{
components
:
{
...
...
ee/app/assets/javascripts/oncall_schedules/utils/common_utils.js
View file @
18d0b537
...
@@ -30,3 +30,14 @@ export const getFormattedTimezone = (tz) => {
...
@@ -30,3 +30,14 @@ export const getFormattedTimezone = (tz) => {
export
const
assigneeScheduleDateStart
=
(
startDate
,
daysToAdd
)
=>
{
export
const
assigneeScheduleDateStart
=
(
startDate
,
daysToAdd
)
=>
{
return
getDateInFuture
(
startDate
,
daysToAdd
);
return
getDateInFuture
(
startDate
,
daysToAdd
);
};
};
/**
* Returns `true` for non-empty string, otherwise returns `false`
*
* @param {String} startDate
*
* @returns {Boolean}
*/
export
const
isNameFieldValid
=
(
nameField
)
=>
{
return
Boolean
(
nameField
?.
length
);
};
ee/spec/frontend/oncall_schedule/__snapshots__/add_edit_schedule_form_spec.js.snap
View file @
18d0b537
...
@@ -9,10 +9,11 @@ exports[`AddEditScheduleForm renders modal layout 1`] = `
...
@@ -9,10 +9,11 @@ exports[`AddEditScheduleForm renders modal layout 1`] = `
label="Name"
label="Name"
label-for="schedule-name"
label-for="schedule-name"
label-size="sm"
label-size="sm"
requried=""
state="true"
>
>
<gl-form-input-stub
<gl-form-input-stub
id="schedule-name"
id="schedule-name"
state="true"
value="Test schedule"
value="Test schedule"
/>
/>
</gl-form-group-stub>
</gl-form-group-stub>
...
@@ -34,6 +35,7 @@ exports[`AddEditScheduleForm renders modal layout 1`] = `
...
@@ -34,6 +35,7 @@ exports[`AddEditScheduleForm renders modal layout 1`] = `
label="Timezone"
label="Timezone"
label-for="schedule-timezone"
label-for="schedule-timezone"
label-size="sm"
label-size="sm"
requried=""
state="true"
state="true"
>
>
<gl-dropdown-stub
<gl-dropdown-stub
...
...
ee/spec/frontend/oncall_schedule/add_edit_schedule_form_spec.js
View file @
18d0b537
import
{
shallowMount
}
from
'
@vue/test-utils
'
;
import
{
shallowMount
}
from
'
@vue/test-utils
'
;
import
{
GlSearchBoxByType
,
GlDropdown
,
GlDropdownItem
}
from
'
@gitlab/ui
'
;
import
{
GlSearchBoxByType
,
GlDropdown
,
GlDropdownItem
,
GlFormGroup
}
from
'
@gitlab/ui
'
;
import
AddEditScheduleForm
,
{
import
AddEditScheduleForm
,
{
i18n
,
i18n
,
}
from
'
ee/oncall_schedules/components/add_edit_schedule_form.vue
'
;
}
from
'
ee/oncall_schedules/components/add_edit_schedule_form.vue
'
;
...
@@ -22,8 +22,10 @@ describe('AddEditScheduleForm', () => {
...
@@ -22,8 +22,10 @@ describe('AddEditScheduleForm', () => {
description
:
mockSchedule
.
description
,
description
:
mockSchedule
.
description
,
timezone
:
mockTimezones
[
0
],
timezone
:
mockTimezones
[
0
],
},
},
isNameInvalid
:
false
,
validationState
:
{
isTimezoneInvalid
:
false
,
name
:
true
,
timezone
:
true
,
},
schedule
:
mockSchedule
,
schedule
:
mockSchedule
,
...
props
,
...
props
,
},
},
...
@@ -36,9 +38,6 @@ describe('AddEditScheduleForm', () => {
...
@@ -36,9 +38,6 @@ describe('AddEditScheduleForm', () => {
mutate
,
mutate
,
},
},
},
},
stubs
:
{
GlFormGroup
:
false
,
},
});
});
};
};
...
@@ -52,13 +51,25 @@ describe('AddEditScheduleForm', () => {
...
@@ -52,13 +51,25 @@ describe('AddEditScheduleForm', () => {
});
});
const
findTimezoneDropdown
=
()
=>
wrapper
.
find
(
GlDropdown
);
const
findTimezoneDropdown
=
()
=>
wrapper
.
find
(
GlDropdown
);
const
findDropdownOptions
=
()
=>
wrapper
.
findAll
(
GlDropdownItem
);
const
findDropdownOptions
=
()
=>
wrapper
.
findAll
Components
(
GlDropdownItem
);
const
findTimezoneSearchBox
=
()
=>
wrapper
.
find
(
GlSearchBoxByType
);
const
findTimezoneSearchBox
=
()
=>
wrapper
.
find
(
GlSearchBoxByType
);
const
findScheduleName
=
()
=>
wrapper
.
find
(
GlFormGroup
);
it
(
'
renders modal layout
'
,
()
=>
{
it
(
'
renders modal layout
'
,
()
=>
{
expect
(
wrapper
.
element
).
toMatchSnapshot
();
expect
(
wrapper
.
element
).
toMatchSnapshot
();
});
});
describe
(
'
Schedule form validation
'
,
()
=>
{
it
(
'
should show feedback for an invalid name input validation state
'
,
async
()
=>
{
createComponent
({
props
:
{
validationState
:
{
name
:
false
},
},
});
expect
(
findScheduleName
().
attributes
(
'
state
'
)).
toBeFalsy
();
});
});
describe
(
'
Timezone select
'
,
()
=>
{
describe
(
'
Timezone select
'
,
()
=>
{
it
(
'
has options based on provided BE data
'
,
()
=>
{
it
(
'
has options based on provided BE data
'
,
()
=>
{
expect
(
findDropdownOptions
()).
toHaveLength
(
mockTimezones
.
length
);
expect
(
findDropdownOptions
()).
toHaveLength
(
mockTimezones
.
length
);
...
@@ -102,20 +113,23 @@ describe('AddEditScheduleForm', () => {
...
@@ -102,20 +113,23 @@ describe('AddEditScheduleForm', () => {
describe
(
'
Form validation
'
,
()
=>
{
describe
(
'
Form validation
'
,
()
=>
{
describe
(
'
Timezone select
'
,
()
=>
{
describe
(
'
Timezone select
'
,
()
=>
{
it
(
'
has
red border when nothing selecte
d
'
,
()
=>
{
it
(
'
has
a validation red border when timezone field is invali
d
'
,
()
=>
{
createComponent
({
createComponent
({
props
:
{
props
:
{
schedule
:
null
,
schedule
:
null
,
form
:
{
name
:
''
,
description
:
''
,
timezone
:
''
},
form
:
{
name
:
''
,
description
:
''
,
timezone
:
''
},
isTimezoneInvalid
:
true
,
validationState
:
{
timezone
:
false
}
,
},
},
});
});
expect
(
findTimezoneDropdown
().
classes
()).
toContain
(
'
invalid-dropdown
'
);
expect
(
findTimezoneDropdown
().
classes
()).
toContain
(
'
invalid-dropdown
'
);
});
});
it
(
"
doesn't have a red border when there is selected option
"
,
async
()
=>
{
it
(
'
does not have a validation red border when timezone field is valid
'
,
async
()
=>
{
findDropdownOptions
().
at
(
1
).
vm
.
$emit
(
'
click
'
);
createComponent
({
await
wrapper
.
vm
.
$nextTick
();
props
:
{
validationState
:
{
timezone
:
true
},
},
});
expect
(
findTimezoneDropdown
().
classes
()).
not
.
toContain
(
'
invalid-dropdown
'
);
expect
(
findTimezoneDropdown
().
classes
()).
not
.
toContain
(
'
invalid-dropdown
'
);
});
});
});
});
...
...
ee/spec/frontend/oncall_schedule/rotations/components/__snapshots__/add_edit_rotation_modal_spec.js.snap
View file @
18d0b537
...
@@ -16,6 +16,7 @@ exports[`AddEditRotationModal renders rotation modal layout 1`] = `
...
@@ -16,6 +16,7 @@ exports[`AddEditRotationModal renders rotation modal layout 1`] = `
form="[object Object]"
form="[object Object]"
participants=""
participants=""
schedule="[object Object]"
schedule="[object Object]"
validationstate="[object Object]"
/>
/>
</gl-modal-stub>
</gl-modal-stub>
`;
`;
ee/spec/frontend/oncall_schedule/rotations/components/add_edit_rotation_form_spec.js
View file @
18d0b537
import
{
shallowMount
}
from
'
@vue/test-utils
'
;
import
{
shallowMount
}
from
'
@vue/test-utils
'
;
import
waitForPromises
from
'
helpers/wait_for_promises
'
;
import
waitForPromises
from
'
helpers/wait_for_promises
'
;
import
{
GlDropdownItem
,
GlTokenSelector
}
from
'
@gitlab/ui
'
;
import
{
GlDropdownItem
,
GlTokenSelector
,
GlFormGroup
}
from
'
@gitlab/ui
'
;
import
AddEditRotationForm
from
'
ee/oncall_schedules/components/rotations/components/add_edit_rotation_form.vue
'
;
import
AddEditRotationForm
from
'
ee/oncall_schedules/components/rotations/components/add_edit_rotation_form.vue
'
;
import
{
LENGTH_ENUM
}
from
'
ee/oncall_schedules/constants
'
;
import
{
LENGTH_ENUM
}
from
'
ee/oncall_schedules/constants
'
;
import
{
participants
,
getOncallSchedulesQueryResponse
}
from
'
../../mocks/apollo_mock
'
;
import
{
participants
,
getOncallSchedulesQueryResponse
}
from
'
../../mocks/apollo_mock
'
;
...
@@ -23,9 +23,11 @@ describe('AddEditRotationForm', () => {
...
@@ -23,9 +23,11 @@ describe('AddEditRotationForm', () => {
...
props
,
...
props
,
schedule
,
schedule
,
isLoading
:
false
,
isLoading
:
false
,
rotationNameIsValid
:
true
,
validationState
:
{
rotationParticipantsAreValid
:
true
,
name
:
true
,
rotationStartsAtIsValid
:
true
,
participants
:
false
,
startsAt
:
false
,
},
participants
,
participants
,
form
:
{
form
:
{
name
:
''
,
name
:
''
,
...
@@ -57,7 +59,23 @@ describe('AddEditRotationForm', () => {
...
@@ -57,7 +59,23 @@ describe('AddEditRotationForm', () => {
const
findRotationLength
=
()
=>
wrapper
.
find
(
'
[id = "rotation-length"]
'
);
const
findRotationLength
=
()
=>
wrapper
.
find
(
'
[id = "rotation-length"]
'
);
const
findRotationStartsOn
=
()
=>
wrapper
.
find
(
'
[id = "rotation-time"]
'
);
const
findRotationStartsOn
=
()
=>
wrapper
.
find
(
'
[id = "rotation-time"]
'
);
const
findUserSelector
=
()
=>
wrapper
.
find
(
GlTokenSelector
);
const
findUserSelector
=
()
=>
wrapper
.
find
(
GlTokenSelector
);
const
findDropdownOptions
=
()
=>
wrapper
.
findAll
(
GlDropdownItem
);
const
findDropdownOptions
=
()
=>
wrapper
.
findAllComponents
(
GlDropdownItem
);
const
findRotationFormGroups
=
()
=>
wrapper
.
findAllComponents
(
GlFormGroup
);
describe
(
'
Rotation form validation
'
,
()
=>
{
it
.
each
`
index | type | validationState | value
${
0
}
|
${
'
name
'
}
|
${
true
}
|
${
'
true
'
}
${
1
}
|
${
'
participants
'
}
|
${
false
}
|
${
undefined
}
${
3
}
|
${
'
startsAt
'
}
|
${
false
}
|
${
undefined
}
`
(
'
form validation for $type returns $value when passed validate state of $validationState
'
,
({
index
,
value
})
=>
{
const
formGroup
=
findRotationFormGroups
();
expect
(
formGroup
.
at
(
index
).
attributes
(
'
state
'
)).
toBe
(
value
);
},
);
});
describe
(
'
Rotation length and start time
'
,
()
=>
{
describe
(
'
Rotation length and start time
'
,
()
=>
{
it
(
'
renders the rotation length value
'
,
async
()
=>
{
it
(
'
renders the rotation length value
'
,
async
()
=>
{
...
...
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