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
e2d16634
Commit
e2d16634
authored
Dec 22, 2021
by
Ezekiel Kigbo
Committed by
Simon Knox
Dec 22, 2021
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Minor VSA i18n and create value stream form components refactor
parent
7e079330
Changes
13
Hide whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
480 additions
and
122 deletions
+480
-122
ee/app/assets/javascripts/analytics/cycle_analytics/components/create_value_stream_form/constants.js
...nalytics/components/create_value_stream_form/constants.js
+2
-2
ee/app/assets/javascripts/analytics/cycle_analytics/components/create_value_stream_form/custom_stage_event_field.vue
...nts/create_value_stream_form/custom_stage_event_field.vue
+81
-0
ee/app/assets/javascripts/analytics/cycle_analytics/components/create_value_stream_form/custom_stage_event_label_field.vue
...eate_value_stream_form/custom_stage_event_label_field.vue
+75
-0
ee/app/assets/javascripts/analytics/cycle_analytics/components/create_value_stream_form/custom_stage_fields.vue
...mponents/create_value_stream_form/custom_stage_fields.vue
+54
-88
ee/app/assets/javascripts/analytics/cycle_analytics/components/create_value_stream_form/default_stage_fields.vue
...ponents/create_value_stream_form/default_stage_fields.vue
+6
-0
ee/app/assets/javascripts/analytics/cycle_analytics/components/value_stream_form.vue
...nalytics/cycle_analytics/components/value_stream_form.vue
+2
-4
ee/spec/frontend/analytics/cycle_analytics/components/create_value_stream_form/custom_stage_event_field_spec.js
...create_value_stream_form/custom_stage_event_field_spec.js
+104
-0
ee/spec/frontend/analytics/cycle_analytics/components/create_value_stream_form/custom_stage_event_label_field_spec.js
..._value_stream_form/custom_stage_event_label_field_spec.js
+115
-0
ee/spec/frontend/analytics/cycle_analytics/components/create_value_stream_form/custom_stage_fields_spec.js
...ents/create_value_stream_form/custom_stage_fields_spec.js
+15
-15
ee/spec/frontend/analytics/cycle_analytics/components/create_value_stream_form/default_stage_fields_spec.js
...nts/create_value_stream_form/default_stage_fields_spec.js
+1
-0
ee/spec/frontend/analytics/cycle_analytics/components/value_stream_form_spec.js
...tics/cycle_analytics/components/value_stream_form_spec.js
+20
-8
locale/gitlab.pot
locale/gitlab.pot
+4
-4
spec/support/helpers/cycle_analytics_helpers.rb
spec/support/helpers/cycle_analytics_helpers.rb
+1
-1
No files found.
ee/app/assets/javascripts/analytics/cycle_analytics/components/create_value_stream_form/constants.js
View file @
e2d16634
...
...
@@ -3,8 +3,8 @@ import { __, s__, sprintf } from '~/locale';
export
const
NAME_MAX_LENGTH
=
100
;
export
const
i18n
=
{
FORM_TITLE
:
s__
(
'
CreateValueStreamForm|Create
Value S
tream
'
),
EDIT_FORM_TITLE
:
s__
(
'
CreateValueStreamForm|Edit
Value S
tream
'
),
FORM_TITLE
:
s__
(
'
CreateValueStreamForm|Create
value s
tream
'
),
EDIT_FORM_TITLE
:
s__
(
'
CreateValueStreamForm|Edit
value s
tream
'
),
EDIT_FORM_ACTION
:
s__
(
'
CreateValueStreamForm|Save value stream
'
),
FORM_CREATED
:
s__
(
"
CreateValueStreamForm|'%{name}' Value Stream created
"
),
FORM_EDITED
:
s__
(
"
CreateValueStreamForm|'%{name}' Value Stream saved
"
),
...
...
ee/app/assets/javascripts/analytics/cycle_analytics/components/create_value_stream_form/custom_stage_event_field.vue
0 → 100644
View file @
e2d16634
<
script
>
import
{
GlFormGroup
,
GlDropdown
,
GlDropdownItem
}
from
'
@gitlab/ui
'
;
export
default
{
name
:
'
CustomStageEventField
'
,
components
:
{
GlFormGroup
,
GlDropdown
,
GlDropdownItem
,
},
props
:
{
index
:
{
type
:
Number
,
required
:
true
,
},
eventType
:
{
type
:
String
,
required
:
true
,
},
eventsList
:
{
type
:
Array
,
required
:
true
,
},
fieldLabel
:
{
type
:
String
,
required
:
true
,
},
selectedEventName
:
{
type
:
String
,
required
:
true
,
},
disabled
:
{
type
:
Boolean
,
required
:
false
,
default
:
false
,
},
hasIdentifierError
:
{
type
:
Boolean
,
required
:
false
,
default
:
false
,
},
identifierError
:
{
type
:
String
,
required
:
false
,
default
:
''
,
},
},
computed
:
{
fieldName
()
{
const
{
eventType
,
index
}
=
this
;
return
`custom-stage-
${
eventType
}
-
${
index
}
`
;
},
},
};
</
script
>
<
template
>
<gl-form-group
class=
"gl-w-half gl-mr-2"
:data-testid=
"fieldName"
:label=
"fieldLabel"
:state=
"hasIdentifierError"
:invalid-feedback=
"identifierError"
>
<gl-dropdown
toggle-class=
"gl-mb-0"
:text=
"selectedEventName"
:name=
"fieldName"
:disabled=
"disabled"
menu-class=
"gl-overflow-hidden!"
block
>
<gl-dropdown-item
v-for=
"
{ text, value } in eventsList"
:key="`${eventType}-${value}`"
:value="value"
@click="$emit('update-identifier', value)"
>
{{
text
}}
</gl-dropdown-item
>
</gl-dropdown>
</gl-form-group>
</
template
>
ee/app/assets/javascripts/analytics/cycle_analytics/components/create_value_stream_form/custom_stage_event_label_field.vue
0 → 100644
View file @
e2d16634
<
script
>
import
{
GlFormGroup
}
from
'
@gitlab/ui
'
;
import
LabelsSelector
from
'
../labels_selector.vue
'
;
export
default
{
name
:
'
CustomStageEventLabelField
'
,
components
:
{
GlFormGroup
,
LabelsSelector
,
},
props
:
{
index
:
{
type
:
Number
,
required
:
true
,
},
eventType
:
{
type
:
String
,
required
:
true
,
},
fieldLabel
:
{
type
:
String
,
required
:
true
,
},
requiresLabel
:
{
type
:
Boolean
,
required
:
true
,
},
initialGroupLabels
:
{
type
:
Array
,
required
:
true
,
},
hasLabelError
:
{
type
:
Boolean
,
required
:
false
,
default
:
false
,
},
labelError
:
{
type
:
String
,
required
:
false
,
default
:
''
,
},
selectedLabelIds
:
{
type
:
Array
,
required
:
false
,
default
:
()
=>
[],
},
},
computed
:
{
fieldName
()
{
const
{
eventType
,
index
}
=
this
;
return
`custom-stage-
${
eventType
}
-label-
${
index
}
`
;
},
},
};
</
script
>
<
template
>
<div
class=
"gl-w-half gl-ml-2"
>
<transition
name=
"fade"
>
<gl-form-group
v-if=
"requiresLabel"
:data-testid=
"fieldName"
:label=
"fieldLabel"
:state=
"hasLabelError"
:invalid-feedback=
"labelError"
>
<labels-selector
:initial-data=
"initialGroupLabels"
:selected-label-ids=
"selectedLabelIds"
:name=
"fieldName"
@
select-label=
"$emit('update-label', $event)"
/>
</gl-form-group>
</transition>
</div>
</
template
>
ee/app/assets/javascripts/analytics/cycle_analytics/components/create_value_stream_form/custom_stage_fields.vue
View file @
e2d16634
<
script
>
import
{
GlFormGroup
,
GlFormInput
,
GlDropdown
,
GlDropdownItem
}
from
'
@gitlab/ui
'
;
import
{
GlFormGroup
,
GlFormInput
}
from
'
@gitlab/ui
'
;
import
{
isLabelEvent
,
getLabelEventsIdentifiers
,
uniqById
}
from
'
../../utils
'
;
import
LabelsSelector
from
'
../labels_selector.vue
'
;
import
{
i18n
}
from
'
./constants
'
;
import
CustomStageEventField
from
'
./custom_stage_event_field.vue
'
;
import
CustomStageEventLabelField
from
'
./custom_stage_event_label_field.vue
'
;
import
StageFieldActions
from
'
./stage_field_actions.vue
'
;
import
{
startEventOptions
,
endEventOptions
}
from
'
./utils
'
;
...
...
@@ -11,9 +12,8 @@ export default {
components
:
{
GlFormGroup
,
GlFormInput
,
GlDropdown
,
GlDropdownItem
,
LabelsSelector
,
CustomStageEventField
,
CustomStageEventLabelField
,
StageFieldActions
,
},
props
:
{
...
...
@@ -21,6 +21,10 @@ export default {
type
:
Number
,
required
:
true
,
},
stageLabel
:
{
type
:
String
,
required
:
true
,
},
totalStages
:
{
type
:
Number
,
required
:
true
,
...
...
@@ -107,6 +111,7 @@ export default {
<div
class=
"gl-display-flex"
>
<gl-form-group
class=
"gl-flex-grow-1"
:label=
"stageLabel"
:state=
"hasFieldErrors('name')"
:invalid-feedback=
"fieldErrorMessage('name')"
:data-testid=
"`custom-stage-name-$
{index}`"
...
...
@@ -123,6 +128,7 @@ export default {
</gl-form-group>
<stage-field-actions
v-if=
"hasMultipleStages"
class=
"gl-mt-6"
:index=
"index"
:stage-count=
"totalStages"
:can-remove=
"true"
...
...
@@ -131,91 +137,51 @@ export default {
/>
</div>
<div
class=
"gl-display-flex gl-justify-content-between"
>
<gl-form-group
:data-testid=
"`custom-stage-start-event-$
{index}`"
class="gl-w-half gl-mr-2"
:label="$options.i18n.FORM_FIELD_START_EVENT"
:state="hasFieldErrors('startEventIdentifier')"
:invalid-feedback="fieldErrorMessage('startEventIdentifier')"
>
<gl-dropdown
toggle-class=
"gl-mb-0"
:text=
"selectedStartEventName"
:name=
"`custom-stage-start-id-$
{index}`"
menu-class="gl-overflow-hidden!"
block
>
<gl-dropdown-item
v-for=
"
{ text, value } in startEvents"
:key="`start-event-${value}`"
:value="value"
@click="$emit('input', { field: 'startEventIdentifier', value })"
>
{{
text
}}
</gl-dropdown-item
>
</gl-dropdown>
</gl-form-group>
<div
class=
"gl-w-half gl-ml-2"
>
<transition
name=
"fade"
>
<gl-form-group
v-if=
"startEventRequiresLabel"
:data-testid=
"`custom-stage-start-event-label-$
{index}`"
:label="$options.i18n.FORM_FIELD_START_EVENT_LABEL"
:state="hasFieldErrors('startEventLabelId')"
:invalid-feedback="fieldErrorMessage('startEventLabelId')"
>
<labels-selector
:initial-data=
"initialGroupLabels"
:selected-label-ids=
"[stage.startEventLabelId]"
:name=
"`custom-stage-start-label-$
{index}`"
@select-label="$emit('input', { field: 'startEventLabelId', value: $event })"
/>
</gl-form-group>
</transition>
</div>
<custom-stage-event-field
event-type=
"start-event"
:index=
"index"
:field-label=
"$options.i18n.FORM_FIELD_START_EVENT"
:selected-event-name=
"selectedStartEventName"
:events-list=
"startEvents"
:identifier-error=
"fieldErrorMessage('startEventIdentifier')"
:has-identifier-error=
"hasFieldErrors('startEventIdentifier')"
@
update-identifier=
"$emit('input',
{ field: 'startEventIdentifier', value: $event })"
/>
<custom-stage-event-label-field
event-type=
"start-event"
:index=
"index"
:field-label=
"$options.i18n.FORM_FIELD_START_EVENT_LABEL"
:initial-group-labels=
"initialGroupLabels"
:requires-label=
"startEventRequiresLabel"
:label-error=
"fieldErrorMessage('startEventLabelId')"
:has-label-error=
"hasFieldErrors('startEventLabelId')"
:selected-label-ids=
"[stage.startEventLabelId]"
@
update-label=
"$emit('input',
{ field: 'startEventLabelId', value: $event })"
/>
</div>
<div
class=
"gl-display-flex gl-justify-content-between"
>
<gl-form-group
:data-testid=
"`custom-stage-end-event-$
{index}`"
class="gl-w-half gl-mr-2"
:label="$options.i18n.FORM_FIELD_END_EVENT"
:state="hasFieldErrors('endEventIdentifier')"
:invalid-feedback="fieldErrorMessage('endEventIdentifier')"
>
<gl-dropdown
toggle-class=
"gl-mb-0"
:text=
"selectedEndEventName"
:name=
"`custom-stage-end-id-$
{index}`"
:disabled="!hasStartEvent"
menu-class="gl-overflow-hidden!"
block
>
<gl-dropdown-item
v-for=
"
{ text, value } in endEvents"
:key="`end-event-${value}`"
:value="value"
@click="$emit('input', { field: 'endEventIdentifier', value })"
>
{{
text
}}
</gl-dropdown-item
>
</gl-dropdown>
</gl-form-group>
<div
class=
"gl-w-half gl-ml-2"
>
<transition
name=
"fade"
>
<gl-form-group
v-if=
"endEventRequiresLabel"
:data-testid=
"`custom-stage-end-event-label-$
{index}`"
:label="$options.i18n.FORM_FIELD_END_EVENT_LABEL"
:state="hasFieldErrors('endEventLabelId')"
:invalid-feedback="fieldErrorMessage('endEventLabelId')"
>
<labels-selector
:initial-data=
"initialGroupLabels"
:selected-label-ids=
"[stage.endEventLabelId]"
:name=
"`custom-stage-end-label-$
{index}`"
@select-label="$emit('input', { field: 'endEventLabelId', value: $event })"
/>
</gl-form-group>
</transition>
</div>
<custom-stage-event-field
event-type=
"end-event"
:index=
"index"
:disabled=
"!hasStartEvent"
:field-label=
"$options.i18n.FORM_FIELD_END_EVENT"
:selected-event-name=
"selectedEndEventName"
:events-list=
"endEvents"
:identifier-error=
"fieldErrorMessage('endEventIdentifier')"
:has-identifier-error=
"hasFieldErrors('endEventIdentifier')"
@
update-identifier=
"$emit('input',
{ field: 'endEventIdentifier', value: $event })"
/>
<custom-stage-event-label-field
event-type=
"end-event"
:index=
"index"
:field-label=
"$options.i18n.FORM_FIELD_END_EVENT_LABEL"
:initial-group-labels=
"initialGroupLabels"
:requires-label=
"endEventRequiresLabel"
:label-error=
"fieldErrorMessage('endEventLabelId')"
:has-label-error=
"hasFieldErrors('endEventLabelId')"
:selected-label-ids=
"[stage.endEventLabelId]"
@
update-label=
"$emit('input',
{ field: 'endEventLabelId', value: $event })"
/>
</div>
</div>
</
template
>
ee/app/assets/javascripts/analytics/cycle_analytics/components/create_value_stream_form/default_stage_fields.vue
View file @
e2d16634
...
...
@@ -26,6 +26,10 @@ export default {
type
:
Number
,
required
:
true
,
},
stageLabel
:
{
type
:
String
,
required
:
true
,
},
totalStages
:
{
type
:
Number
,
required
:
true
,
...
...
@@ -63,6 +67,7 @@ export default {
<div
class=
"gl-display-flex"
>
<gl-form-group
class=
"gl-flex-grow-1 gl-mb-0"
:label=
"stageLabel"
:state=
"isValid('name')"
:invalid-feedback=
"renderError('name')"
:data-testid=
"`default-stage-name-$
{index}`"
...
...
@@ -79,6 +84,7 @@ export default {
<!-- eslint-enable vue/no-mutating-props -->
</gl-form-group>
<stage-field-actions
class=
"gl-mt-6"
:index=
"index"
:stage-count=
"totalStages"
@
move=
"$emit('move', $event)"
...
...
ee/app/assets/javascripts/analytics/cycle_analytics/components/value_stream_form.vue
View file @
e2d16634
...
...
@@ -388,12 +388,9 @@ export default {
:key=
"stage.id || stage.transitionKey"
>
<hr
class=
"gl-my-3"
/>
<span
class=
"gl-display-flex gl-m-0 gl-vertical-align-middle gl-mr-2 gl-font-weight-bold gl-display-flex gl-pb-3"
>
{{
stageGroupLabel
(
activeStageIndex
)
}}
</span
>
<custom-stage-fields
v-if=
"stage.custom"
:stage-label=
"stageGroupLabel(activeStageIndex)"
:stage=
"stage"
:stage-events=
"formEvents"
:index=
"activeStageIndex"
...
...
@@ -406,6 +403,7 @@ export default {
/>
<default-stage-fields
v-else
:stage-label=
"stageGroupLabel(activeStageIndex)"
:stage=
"stage"
:stage-events=
"formEvents"
:index=
"activeStageIndex"
...
...
ee/spec/frontend/analytics/cycle_analytics/components/create_value_stream_form/custom_stage_event_field_spec.js
0 → 100644
View file @
e2d16634
import
{
GlDropdown
,
GlDropdownItem
}
from
'
@gitlab/ui
'
;
import
{
shallowMountExtended
}
from
'
helpers/vue_test_utils_helper
'
;
import
{
i18n
,
ERRORS
,
}
from
'
ee/analytics/cycle_analytics/components/create_value_stream_form/constants
'
;
import
CustomStageEventField
from
'
ee/analytics/cycle_analytics/components/create_value_stream_form/custom_stage_event_field.vue
'
;
import
{
customStageEvents
as
stageEvents
}
from
'
../../mock_data
'
;
const
formatStartEventOpts
=
(
_events
)
=>
[
{
text
:
'
Select start event
'
,
value
:
null
},
...
_events
.
filter
((
ev
)
=>
ev
.
canBeStartEvent
)
.
map
(({
name
:
text
,
identifier
:
value
})
=>
({
text
,
value
})),
];
const
index
=
0
;
const
eventType
=
'
stage-start-event
'
;
const
fieldLabel
=
i18n
.
FORM_FIELD_START_EVENT
;
const
selectedEventName
=
i18n
.
SELECT_START_EVENT
;
const
eventsList
=
formatStartEventOpts
(
stageEvents
);
const
selectedEventIndex
=
1
;
// index `0` is the default select text
const
firstEvent
=
eventsList
[
selectedEventIndex
];
const
identifierError
=
ERRORS
.
START_EVENT_REQUIRED
;
const
defaultProps
=
{
index
,
eventType
,
eventsList
,
fieldLabel
,
selectedEventName
,
};
describe
(
'
CustomStageEventField
'
,
()
=>
{
function
createComponent
(
props
=
{})
{
return
shallowMountExtended
(
CustomStageEventField
,
{
propsData
:
{
...
defaultProps
,
...
props
,
},
});
}
let
wrapper
=
null
;
const
findEventField
=
()
=>
wrapper
.
findByTestId
(
`custom-stage-
${
eventType
}
-
${
index
}
`
);
const
findEventDropdown
=
()
=>
findEventField
().
findComponent
(
GlDropdown
);
const
findEventDropdownItems
=
()
=>
findEventField
().
findAllComponents
(
GlDropdownItem
);
const
findEventDropdownItem
=
(
itemIndex
=
0
)
=>
findEventDropdownItems
().
at
(
itemIndex
);
beforeEach
(()
=>
{
wrapper
=
createComponent
();
});
afterEach
(()
=>
{
wrapper
.
destroy
();
});
describe
(
'
Event dropdown
'
,
()
=>
{
it
(
'
renders the event dropdown
'
,
()
=>
{
expect
(
findEventField
().
exists
()).
toBe
(
true
);
expect
(
findEventField
().
attributes
(
'
label
'
)).
toBe
(
fieldLabel
);
expect
(
findEventDropdown
().
attributes
(
'
disabled
'
)).
toBeUndefined
();
expect
(
findEventDropdown
().
attributes
(
'
text
'
)).
toBe
(
selectedEventName
);
});
it
(
'
renders each item in the event list
'
,
()
=>
{
const
ev
=
findEventDropdownItems
().
wrappers
.
map
((
d
)
=>
d
.
text
());
const
eventsListText
=
eventsList
.
map
(({
text
})
=>
text
);
expect
(
eventsListText
).
toEqual
(
ev
);
});
it
(
'
emits the `update-identifier` event when an event is selected
'
,
()
=>
{
expect
(
wrapper
.
emitted
(
'
update-identifier
'
)).
toBeUndefined
();
findEventDropdownItem
(
selectedEventIndex
).
vm
.
$emit
(
'
click
'
);
expect
(
wrapper
.
emitted
(
'
update-identifier
'
)[
0
]).
toEqual
([
firstEvent
.
value
]);
});
it
(
'
sets disables the dropdown when the disabled prop is set
'
,
async
()
=>
{
expect
(
findEventDropdown
().
attributes
(
'
disabled
'
)).
toBeUndefined
();
wrapper
=
await
createComponent
({
disabled
:
true
});
expect
(
findEventDropdown
().
attributes
(
'
disabled
'
)).
toBe
(
'
true
'
);
});
});
describe
(
'
with an event field error
'
,
()
=>
{
beforeEach
(()
=>
{
wrapper
=
createComponent
({
hasIdentifierError
:
true
,
identifierError
,
});
});
it
(
'
sets the form group error state
'
,
()
=>
{
expect
(
findEventField
().
attributes
(
'
state
'
)).
toBe
(
'
true
'
);
expect
(
findEventField
().
attributes
(
'
invalid-feedback
'
)).
toBe
(
identifierError
);
});
});
});
ee/spec/frontend/analytics/cycle_analytics/components/create_value_stream_form/custom_stage_event_label_field_spec.js
0 → 100644
View file @
e2d16634
import
{
shallowMountExtended
}
from
'
helpers/vue_test_utils_helper
'
;
import
{
i18n
,
ERRORS
,
}
from
'
ee/analytics/cycle_analytics/components/create_value_stream_form/constants
'
;
import
CustomStageEventLabelField
from
'
ee/analytics/cycle_analytics/components/create_value_stream_form/custom_stage_event_label_field.vue
'
;
import
LabelsSelector
from
'
ee/analytics/cycle_analytics/components/labels_selector.vue
'
;
import
{
groupLabels
as
initialGroupLabels
}
from
'
../../mock_data
'
;
const
index
=
0
;
const
eventType
=
'
start-event
'
;
const
fieldLabel
=
i18n
.
FORM_FIELD_START_EVENT_LABEL
;
const
labelError
=
ERRORS
.
INVALID_EVENT_PAIRS
;
const
[
selectedLabel
,
secondLabel
]
=
initialGroupLabels
;
const
selectedLabelIds
=
[
selectedLabel
.
id
,
secondLabel
.
id
];
const
defaultProps
=
{
index
,
eventType
,
fieldLabel
,
requiresLabel
:
true
,
initialGroupLabels
,
labelError
,
selectedLabelIds
:
[],
};
describe
(
'
CustomStageEventLabelField
'
,
()
=>
{
function
createComponent
(
props
=
{})
{
return
shallowMountExtended
(
CustomStageEventLabelField
,
{
propsData
:
{
...
defaultProps
,
...
props
,
},
});
}
let
wrapper
=
null
;
const
findEventLabelField
=
()
=>
wrapper
.
findByTestId
(
`custom-stage-
${
eventType
}
-label-
${
index
}
`
);
const
findEventLabelDropdown
=
()
=>
findEventLabelField
().
findComponent
(
LabelsSelector
);
const
findEventLabelDropdownProp
=
(
prop
)
=>
findEventLabelDropdown
().
props
(
prop
);
beforeEach
(()
=>
{
wrapper
=
createComponent
();
});
afterEach
(()
=>
{
wrapper
.
destroy
();
});
describe
(
'
Label dropdown
'
,
()
=>
{
it
(
'
renders the event dropdown
'
,
()
=>
{
expect
(
findEventLabelField
().
exists
()).
toBe
(
true
);
expect
(
findEventLabelField
().
attributes
(
'
label
'
)).
toBe
(
fieldLabel
);
});
it
(
'
renders each item in the labels list
'
,
()
=>
{
const
lt
=
findEventLabelDropdownProp
(
'
initialData
'
).
map
((
d
)
=>
d
.
name
);
const
labelsText
=
initialGroupLabels
.
map
(({
name
})
=>
name
);
expect
(
labelsText
).
toEqual
(
lt
);
});
it
(
'
has no selected labels
'
,
()
=>
{
const
selected
=
findEventLabelDropdownProp
(
'
selectedLabelIds
'
);
expect
(
selected
).
toEqual
([]);
});
it
(
'
emits the `update-label` event when a label is selected
'
,
()
=>
{
expect
(
wrapper
.
emitted
(
'
update-label
'
)).
toBeUndefined
();
findEventLabelDropdown
().
vm
.
$emit
(
'
select-label
'
,
selectedLabel
.
id
);
expect
(
wrapper
.
emitted
(
'
update-label
'
)[
0
]).
toEqual
([
selectedLabel
.
id
]);
});
});
describe
(
'
with selected labels
'
,
()
=>
{
beforeEach
(()
=>
{
wrapper
=
createComponent
({
selectedLabelIds
});
});
it
(
'
sets the selected labels
'
,
()
=>
{
const
selected
=
findEventLabelDropdownProp
(
'
selectedLabelIds
'
);
expect
(
selected
).
toEqual
(
selectedLabelIds
);
});
});
describe
(
'
with `requiresLabel=false`
'
,
()
=>
{
beforeEach
(()
=>
{
wrapper
=
createComponent
({
requiresLabel
:
false
});
});
it
(
'
sets the form group error state
'
,
()
=>
{
expect
(
findEventLabelField
().
exists
()).
toBe
(
false
);
});
});
describe
(
'
with an event field error
'
,
()
=>
{
beforeEach
(()
=>
{
wrapper
=
createComponent
({
hasLabelError
:
true
,
labelError
,
});
});
it
(
'
sets the form group error state
'
,
()
=>
{
expect
(
findEventLabelField
().
attributes
(
'
state
'
)).
toBe
(
'
true
'
);
expect
(
findEventLabelField
().
attributes
(
'
invalid-feedback
'
)).
toBe
(
labelError
);
});
});
});
ee/spec/frontend/analytics/cycle_analytics/components/create_value_stream_form/custom_stage_fields_spec.js
View file @
e2d16634
import
{
Gl
Dropdown
,
Gl
FormInput
}
from
'
@gitlab/ui
'
;
import
{
GlFormInput
}
from
'
@gitlab/ui
'
;
import
{
shallowMount
}
from
'
@vue/test-utils
'
;
import
CustomStageFields
from
'
ee/analytics/cycle_analytics/components/create_value_stream_form/custom_stage_fields.vue
'
;
import
CustomStageEventField
from
'
ee/analytics/cycle_analytics/components/create_value_stream_form/custom_stage_event_field.vue
'
;
import
CustomStageEventLabelField
from
'
ee/analytics/cycle_analytics/components/create_value_stream_form/custom_stage_event_label_field.vue
'
;
import
StageFieldActions
from
'
ee/analytics/cycle_analytics/components/create_value_stream_form/stage_field_actions.vue
'
;
import
LabelsSelector
from
'
ee/analytics/cycle_analytics/components/labels_selector.vue
'
;
import
{
extendedWrapper
}
from
'
helpers/vue_test_utils_helper
'
;
import
{
customStageEvents
as
stageEvents
,
labelStartEvent
,
labelEndEvent
,
customStageEndEvents
as
endEvents
,
groupLabels
as
defaultGroupLabels
,
}
from
'
../../mock_data
'
;
import
{
emptyState
,
emptyErrorsState
,
firstLabel
}
from
'
./mock_data
'
;
...
...
@@ -39,11 +41,13 @@ describe('CustomStageFields', () => {
return
extendedWrapper
(
shallowMount
(
CustomStageFields
,
{
propsData
:
{
defaultGroupLabels
,
stage
,
errors
,
stageEvents
,
index
:
0
,
totalStages
:
3
,
stageLabel
:
'
Stage 1
'
,
...
props
,
},
stubs
:
{
...
...
@@ -56,21 +60,17 @@ describe('CustomStageFields', () => {
let
wrapper
=
null
;
const
getDropdown
=
(
dropdownEl
)
=>
dropdownEl
.
findComponent
(
GlDropdown
);
const
getLabelSelect
=
(
dropdownEl
)
=>
dropdownEl
.
findComponent
(
LabelsSelector
);
const
findName
=
(
index
=
0
)
=>
wrapper
.
findByTestId
(
`custom-stage-name-
${
index
}
`
);
const
findStartEvent
=
(
index
=
0
)
=>
wrapper
.
findByTestId
(
`custom-stage-start-event-
${
index
}
`
);
const
findEndEvent
=
(
index
=
0
)
=>
wrapper
.
findByTestId
(
`custom-stage-end-event-
${
index
}
`
);
const
findStartEventLabel
=
(
index
=
0
)
=>
wrapper
.
findByTestId
(
`custom-stage-start-event-label-
${
index
}
`
);
const
findEndEventLabel
=
(
index
=
0
)
=>
wrapper
.
findByTestId
(
`custom-stage-end-event-label-
${
index
}
`
);
const
findNameField
=
()
=>
findName
().
findComponent
(
GlFormInput
);
const
findStartEventField
=
()
=>
getDropdown
(
findStartEvent
());
const
findEndEventField
=
()
=>
getDropdown
(
findEndEvent
());
const
findStartEventLabelField
=
()
=>
getLabelSelect
(
findStartEventLabel
());
const
findEndEventLabelField
=
()
=>
getLabelSelect
(
findEndEventLabel
());
const
findStartEventField
=
()
=>
wrapper
.
findAllComponents
(
CustomStageEventField
).
at
(
0
);
const
findEndEventField
=
()
=>
wrapper
.
findAllComponents
(
CustomStageEventField
).
at
(
1
);
const
findStartEventLabelField
=
()
=>
wrapper
.
findAllComponents
(
CustomStageEventLabelField
).
at
(
0
);
const
findEndEventLabelField
=
()
=>
wrapper
.
findAllComponents
(
CustomStageEventLabelField
).
at
(
1
);
const
findStageFieldActions
=
()
=>
wrapper
.
findComponent
(
StageFieldActions
);
beforeEach
(()
=>
{
...
...
@@ -135,13 +135,13 @@ describe('CustomStageFields', () => {
});
it
(
'
will display the start event label field if a label event is selected
'
,
()
=>
{
expect
(
findStartEventLabel
().
exists
()).
toEqual
(
true
);
expect
(
findStartEventLabel
Field
().
exists
()).
toEqual
(
true
);
});
it
(
'
will emit the `input` event when the start event label field when selected
'
,
async
()
=>
{
expect
(
wrapper
.
emitted
(
'
input
'
)).
toBeUndefined
();
findStartEventLabelField
().
vm
.
$emit
(
'
select
-label
'
,
firstLabel
.
id
);
findStartEventLabelField
().
vm
.
$emit
(
'
update
-label
'
,
firstLabel
.
id
);
expect
(
wrapper
.
emitted
(
'
input
'
)[
0
]).
toEqual
([
{
field
:
'
startEventLabelId
'
,
value
:
firstLabel
.
id
},
...
...
@@ -180,13 +180,13 @@ describe('CustomStageFields', () => {
});
it
(
'
will display the end event label field if a label event is selected
'
,
()
=>
{
expect
(
findEndEventLabel
().
exists
()).
toEqual
(
true
);
expect
(
findEndEventLabel
Field
().
exists
()).
toEqual
(
true
);
});
it
(
'
will emit the `input` event when the start event label field when selected
'
,
async
()
=>
{
expect
(
wrapper
.
emitted
(
'
input
'
)).
toBeUndefined
();
findEndEventLabelField
().
vm
.
$emit
(
'
select
-label
'
,
firstLabel
.
id
);
findEndEventLabelField
().
vm
.
$emit
(
'
update
-label
'
,
firstLabel
.
id
);
expect
(
wrapper
.
emitted
(
'
input
'
)[
0
]).
toEqual
([
{
field
:
'
endEventLabelId
'
,
value
:
firstLabel
.
id
},
...
...
ee/spec/frontend/analytics/cycle_analytics/components/create_value_stream_form/default_stage_fields_spec.js
View file @
e2d16634
...
...
@@ -28,6 +28,7 @@ describe('DefaultStageFields', () => {
stage
,
errors
,
stageEvents
,
stageLabel
:
'
Stage 1
'
,
},
stubs
:
{
'
labels-selector
'
:
false
,
...
...
ee/spec/frontend/analytics/cycle_analytics/components/value_stream_form_spec.js
View file @
e2d16634
...
...
@@ -3,10 +3,12 @@ import { shallowMount } from '@vue/test-utils';
import
Vue
from
'
vue
'
;
import
Vuex
from
'
vuex
'
;
import
{
i18n
,
PRESET_OPTIONS_BLANK
,
PRESET_OPTIONS_DEFAULT
,
}
from
'
ee/analytics/cycle_analytics/components/create_value_stream_form/constants
'
;
import
CustomStageFields
from
'
ee/analytics/cycle_analytics/components/create_value_stream_form/custom_stage_fields.vue
'
;
import
CustomStageEventField
from
'
ee/analytics/cycle_analytics/components/create_value_stream_form/custom_stage_event_field.vue
'
;
import
DefaultStageFields
from
'
ee/analytics/cycle_analytics/components/create_value_stream_form/default_stage_fields.vue
'
;
import
ValueStreamForm
from
'
ee/analytics/cycle_analytics/components/value_stream_form.vue
'
;
import
{
mockTracking
,
unmockTracking
}
from
'
helpers/tracking_helper
'
;
...
...
@@ -15,7 +17,12 @@ import {
convertObjectPropsToCamelCase
,
convertObjectPropsToSnakeCase
,
}
from
'
~/lib/utils/common_utils
'
;
import
{
customStageEvents
as
formEvents
,
defaultStageConfig
,
rawCustomStage
}
from
'
../mock_data
'
;
import
{
customStageEvents
as
formEvents
,
defaultStageConfig
,
rawCustomStage
,
groupLabels
as
defaultGroupLabels
,
}
from
'
../mock_data
'
;
const
scrollIntoViewMock
=
jest
.
fn
();
HTMLElement
.
prototype
.
scrollIntoView
=
scrollIntoViewMock
;
...
...
@@ -55,7 +62,7 @@ describe('ValueStreamForm', () => {
state
:
{
isCreatingValueStream
:
false
,
formEvents
,
defaultGroupLabels
:
null
,
defaultGroupLabels
,
...
state
,
},
actions
:
{
...
...
@@ -96,12 +103,16 @@ describe('ValueStreamForm', () => {
const
findRestoreStageButton
=
(
index
)
=>
wrapper
.
findByTestId
(
`stage-action-restore-
${
index
}
`
);
const
findHiddenStages
=
()
=>
wrapper
.
findAllByTestId
(
'
vsa-hidden-stage
'
).
wrappers
;
const
findBtn
=
(
btn
)
=>
findModal
().
props
(
btn
);
const
findCustomStageEventField
=
(
index
=
0
)
=>
wrapper
.
findAllComponents
(
CustomStageEventField
).
at
(
index
);
const
clickSubmit
=
()
=>
findModal
().
vm
.
$emit
(
'
primary
'
,
mockEvent
);
const
clickAddStage
=
()
=>
findModal
().
vm
.
$emit
(
'
secondary
'
,
mockEvent
);
const
clickRestoreStageAtIndex
=
(
index
)
=>
findRestoreStageButton
(
index
).
vm
.
$emit
(
'
click
'
);
const
expectFieldError
=
(
testId
,
error
=
''
)
=>
expect
(
wrapper
.
findByTestId
(
testId
).
attributes
(
'
invalid-feedback
'
)).
toBe
(
error
);
const
expectCustomFieldError
=
(
index
,
attr
,
error
=
''
)
=>
expect
(
findCustomStageEventField
(
index
).
attributes
(
attr
)).
toBe
(
error
);
const
expectStageTransitionKeys
=
(
stages
)
=>
stages
.
forEach
((
stage
)
=>
expect
(
stage
.
transitionKey
).
toContain
(
'
stage-
'
));
...
...
@@ -112,7 +123,7 @@ describe('ValueStreamForm', () => {
describe
(
'
default state
'
,
()
=>
{
beforeEach
(()
=>
{
wrapper
=
createComponent
();
wrapper
=
createComponent
(
{
state
:
{
defaultGroupLabels
:
null
}
}
);
});
it
(
'
has the extended fields
'
,
()
=>
{
...
...
@@ -120,7 +131,7 @@ describe('ValueStreamForm', () => {
});
it
(
'
sets the submit action text to "Create Value Stream"
'
,
()
=>
{
expect
(
findBtn
(
'
actionPrimary
'
).
text
).
toBe
(
'
Create Value Stream
'
);
expect
(
findBtn
(
'
actionPrimary
'
).
text
).
toBe
(
i18n
.
FORM_TITLE
);
});
describe
(
'
Preset selector
'
,
()
=>
{
...
...
@@ -223,8 +234,9 @@ describe('ValueStreamForm', () => {
});
expectFieldError
(
'
custom-stage-name-0
'
,
initialFormStageErrors
.
stages
[
0
].
name
[
0
]);
expectFieldError
(
'
custom-stage-end-event-0
'
,
expectCustomFieldError
(
1
,
'
identifiererror
'
,
initialFormStageErrors
.
stages
[
0
].
endEventIdentifier
[
0
],
);
});
...
...
@@ -247,7 +259,7 @@ describe('ValueStreamForm', () => {
});
it
(
'
sets the submit action text to "Save value stream"
'
,
()
=>
{
expect
(
findBtn
(
'
actionPrimary
'
).
text
).
toBe
(
'
Save value stream
'
);
expect
(
findBtn
(
'
actionPrimary
'
).
text
).
toBe
(
i18n
.
EDIT_FORM_ACTION
);
});
it
(
'
does not display any hidden stages
'
,
()
=>
{
...
...
@@ -324,7 +336,7 @@ describe('ValueStreamForm', () => {
});
it
(
'
has the add stage button
'
,
()
=>
{
expect
(
findBtn
(
'
actionSecondary
'
)).
toMatchObject
({
text
:
'
Add another stage
'
});
expect
(
findBtn
(
'
actionSecondary
'
)).
toMatchObject
({
text
:
i18n
.
BTN_ADD_ANOTHER_STAGE
});
});
it
(
'
adds a blank custom stage when clicked
'
,
async
()
=>
{
...
...
locale/gitlab.pot
View file @
e2d16634
...
...
@@ -10126,9 +10126,6 @@ msgstr ""
msgid "CreateValueStreamForm|Code stage start"
msgstr ""
msgid "CreateValueStreamForm|Create Value Stream"
msgstr ""
msgid "CreateValueStreamForm|Create from default template"
msgstr ""
...
...
@@ -10138,13 +10135,16 @@ msgstr ""
msgid "CreateValueStreamForm|Create new Value Stream"
msgstr ""
msgid "CreateValueStreamForm|Create value stream"
msgstr ""
msgid "CreateValueStreamForm|Default stages"
msgstr ""
msgid "CreateValueStreamForm|Default stages can only be hidden or re-ordered"
msgstr ""
msgid "CreateValueStreamForm|Edit
Value S
tream"
msgid "CreateValueStreamForm|Edit
value s
tream"
msgstr ""
msgid "CreateValueStreamForm|Editing stage"
...
...
spec/support/helpers/cycle_analytics_helpers.rb
View file @
e2d16634
...
...
@@ -59,7 +59,7 @@ module CycleAnalyticsHelpers
def
save_value_stream
(
custom_value_stream_name
)
fill_in
'create-value-stream-name'
,
with:
custom_value_stream_name
page
.
find_button
(
s_
(
'CreateValueStreamForm|Create
Value S
tream'
)).
click
page
.
find_button
(
s_
(
'CreateValueStreamForm|Create
value s
tream'
)).
click
wait_for_requests
end
...
...
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