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
efac77f3
Commit
efac77f3
authored
Nov 17, 2021
by
Simon Knox
Committed by
Vitaly Slobodin
Nov 17, 2021
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Prefill iteration date with sensible value
parent
fff3d03e
Changes
5
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
199 additions
and
45 deletions
+199
-45
ee/app/assets/javascripts/iterations/components/iteration_form.vue
...sets/javascripts/iterations/components/iteration_form.vue
+51
-2
ee/spec/frontend/iterations/components/iteration_cadence_form_spec.js
...tend/iterations/components/iteration_cadence_form_spec.js
+3
-12
ee/spec/frontend/iterations/components/iteration_form_spec.js
...pec/frontend/iterations/components/iteration_form_spec.js
+67
-31
ee/spec/frontend/iterations/mock_data.js
ee/spec/frontend/iterations/mock_data.js
+75
-0
locale/gitlab.pot
locale/gitlab.pot
+3
-0
No files found.
ee/app/assets/javascripts/iterations/components/iteration_form.vue
View file @
efac77f3
...
...
@@ -2,12 +2,16 @@
import
{
GlAlert
,
GlButton
,
GlForm
,
GlFormInput
}
from
'
@gitlab/ui
'
;
import
initDatePicker
from
'
~/behaviors/date_picker
'
;
import
createFlash
from
'
~/flash
'
;
import
{
dayAfter
,
formatDate
}
from
'
~/lib/utils/datetime_utility
'
;
import
{
TYPE_ITERATIONS_CADENCE
}
from
'
~/graphql_shared/constants
'
;
import
{
convertToGraphQLId
,
getIdFromGraphQLId
}
from
'
~/graphql_shared/utils
'
;
import
{
__
,
s__
}
from
'
~/locale
'
;
import
MarkdownField
from
'
~/vue_shared/components/markdown/field.vue
'
;
import
readIteration
from
'
../queries/iteration.query.graphql
'
;
import
createIteration
from
'
../queries/iteration_create.mutation.graphql
'
;
import
readCadence
from
'
../queries/iteration_cadence.query.graphql
'
;
import
updateIteration
from
'
../queries/update_iteration.mutation.graphql
'
;
import
iterationsInCadence
from
'
../queries/group_iterations_in_cadence.query.graphql
'
;
export
default
{
cadencesList
:
{
...
...
@@ -40,13 +44,15 @@ export default {
if
(
!
iteration
)
{
this
.
error
=
s__
(
'
Iterations|Unable to find iteration.
'
);
return
;
return
null
;
}
this
.
title
=
iteration
.
title
;
this
.
description
=
iteration
.
description
;
this
.
startDate
=
iteration
.
startDate
;
this
.
dueDate
=
iteration
.
dueDate
;
return
iteration
;
},
error
(
err
)
{
this
.
error
=
err
.
message
;
...
...
@@ -59,6 +65,7 @@ export default {
loading
:
false
,
error
:
''
,
group
:
{
iteration
:
{}
},
cadence
:
{},
title
:
''
,
description
:
''
,
startDate
:
''
,
...
...
@@ -85,9 +92,51 @@ export default {
};
},
},
mounted
()
{
async
mounted
()
{
// TODO: utilize GlDatepicker instead of relying on this jQuery behavior
initDatePicker
();
// prefill start date for the New cadence form
// if there's iterations in the cadence, use last end_date + 1
// else use cadence startDate
if
(
!
this
.
isEditing
&&
this
.
cadenceId
)
{
const
{
data
}
=
await
this
.
$apollo
.
query
({
query
:
iterationsInCadence
,
variables
:
{
fullPath
:
this
.
fullPath
,
iterationCadenceId
:
convertToGraphQLId
(
TYPE_ITERATIONS_CADENCE
,
this
.
cadenceId
),
lastPageSize
:
1
,
state
:
'
all
'
,
},
});
const
iteration
=
data
.
workspace
.
iterations
?.
nodes
[
0
];
if
(
iteration
)
{
this
.
startDate
=
formatDate
(
dayAfter
(
new
Date
(
iteration
.
dueDate
),
{
utc
:
true
}),
'
yyyy-mm-dd
'
,
);
}
else
{
const
{
data
:
cadenceData
}
=
await
this
.
$apollo
.
query
({
query
:
readCadence
,
variables
:
{
fullPath
:
this
.
fullPath
,
id
:
this
.
cadenceId
,
},
});
if
(
cadenceData
.
group
)
{
const
cadence
=
cadenceData
.
group
?.
iterationCadences
?.
nodes
[
0
];
if
(
!
cadence
)
{
this
.
error
=
s__
(
'
Iterations|Unable to find iteration cadence.
'
);
return
;
}
this
.
startDate
=
cadence
.
startDate
;
}
}
}
},
methods
:
{
save
()
{
...
...
ee/spec/frontend/iterations/components/iteration_cadence_form_spec.js
View file @
efac77f3
...
...
@@ -9,6 +9,7 @@ import createMockApollo from 'helpers/mock_apollo_helper';
import
{
TEST_HOST
}
from
'
helpers/test_constants
'
;
import
{
extendedWrapper
}
from
'
helpers/vue_test_utils_helper
'
;
import
waitForPromises
from
'
helpers/wait_for_promises
'
;
import
{
manualIterationCadence
}
from
'
../mock_data
'
;
const
push
=
jest
.
fn
();
const
$router
=
{
...
...
@@ -28,17 +29,7 @@ describe('Iteration cadence form', () => {
let
wrapper
;
const
groupPath
=
'
gitlab-org
'
;
const
id
=
72
;
const
iterationCadence
=
{
id
:
`gid://gitlab/Iterations::Cadence/
${
id
}
`
,
title
:
'
An iteration
'
,
automatic
:
true
,
rollOver
:
false
,
durationInWeeks
:
'
3
'
,
description
:
'
The words
'
,
duration
:
'
3
'
,
startDate
:
'
2020-06-28
'
,
iterationsInAdvance
:
'
2
'
,
};
const
iterationCadence
=
manualIterationCadence
;
const
createMutationSuccess
=
{
data
:
{
result
:
{
iterationCadence
,
errors
:
[]
}
},
...
...
@@ -53,7 +44,7 @@ describe('Iteration cadence form', () => {
group
:
{
id
:
'
gid://gitlab/Group/114
'
,
iterationCadences
:
{
nodes
:
[
i
terationCadence
],
nodes
:
[
manualI
terationCadence
],
},
},
},
...
...
ee/spec/frontend/iterations/components/iteration_form_spec.js
View file @
efac77f3
...
...
@@ -5,13 +5,29 @@ import IterationForm from 'ee/iterations/components/iteration_form.vue';
import
readIteration
from
'
ee/iterations/queries/iteration.query.graphql
'
;
import
createIteration
from
'
ee/iterations/queries/iteration_create.mutation.graphql
'
;
import
updateIteration
from
'
ee/iterations/queries/update_iteration.mutation.graphql
'
;
import
groupIterationsInCadenceQuery
from
'
ee/iterations/queries/group_iterations_in_cadence.query.graphql
'
;
import
readCadence
from
'
ee/iterations/queries/iteration_cadence.query.graphql
'
;
import
createRouter
from
'
ee/iterations/router
'
;
import
createMockApollo
from
'
helpers/mock_apollo_helper
'
;
import
{
extendedWrapper
}
from
'
helpers/vue_test_utils_helper
'
;
import
waitForPromises
from
'
helpers/wait_for_promises
'
;
import
{
convertToGraphQLId
}
from
'
~/graphql_shared/utils
'
;
import
{
convertToGraphQLId
,
getIdFromGraphQLId
}
from
'
~/graphql_shared/utils
'
;
import
{
dayAfter
,
formatDate
}
from
'
~/lib/utils/datetime_utility
'
;
import
{
manualIterationCadence
as
cadence
,
mockGroupIterations
,
mockIterationNode
as
iteration
,
createMutationSuccess
,
createMutationFailure
,
updateMutationSuccess
,
emptyGroupIterationsSuccess
,
nonEmptyGroupIterationsSuccess
,
readCadenceSuccess
,
}
from
'
../mock_data
'
;
const
baseUrl
=
'
/cadences/
'
;
const
iterationId
=
getIdFromGraphQLId
(
iteration
.
id
);
const
cadenceId
=
getIdFromGraphQLId
(
cadence
.
id
);
function
createMockApolloProvider
(
requestHandlers
)
{
Vue
.
use
(
VueApollo
);
...
...
@@ -23,41 +39,20 @@ describe('Iteration Form', () => {
let
wrapper
;
let
router
;
const
groupPath
=
'
gitlab-org
'
;
const
iterationId
=
72
;
const
cadenceId
=
2
;
const
iteration
=
{
id
:
`gid://gitlab/Iteration/
${
iterationId
}
`
,
iid
:
70
,
title
:
'
An iteration
'
,
state
:
'
opened
'
,
webPath
:
'
/test
'
,
description
:
'
The words
'
,
descriptionHtml
:
'
<p>The words</p>
'
,
startDate
:
'
2020-06-28
'
,
dueDate
:
'
2020-07-05
'
,
};
const
readMutationSuccess
=
{
data
:
{
group
:
{
id
:
'
gid://gitlab/Group/114
'
,
iterations
:
{
nodes
:
[
iteration
]
},
errors
:
[]
},
},
};
const
createMutationSuccess
=
{
data
:
{
iterationCreate
:
{
iteration
,
errors
:
[]
}
}
};
const
createMutationFailure
=
{
data
:
{
iterationCreate
:
{
iteration
,
errors
:
[
'
alas, your data is unchanged
'
]
}
},
};
const
updateMutationSuccess
=
{
data
:
{
updateIteration
:
{
iteration
,
errors
:
[]
}
}
};
function
createComponent
({
mutationQuery
=
createIteration
,
mutationResult
=
createMutationSuccess
,
query
=
readIteration
,
result
=
readMutationSucces
s
,
result
=
mockGroupIteration
s
,
resolverMock
=
jest
.
fn
().
mockResolvedValue
(
mutationResult
),
groupIterationsSuccess
=
emptyGroupIterationsSuccess
,
}
=
{})
{
const
apolloProvider
=
createMockApolloProvider
([
[
query
,
jest
.
fn
().
mockResolvedValue
(
result
)],
[
mutationQuery
,
resolverMock
],
[
groupIterationsInCadenceQuery
,
jest
.
fn
().
mockResolvedValue
(
groupIterationsSuccess
)],
[
readCadence
,
jest
.
fn
().
mockResolvedValue
(
readCadenceSuccess
)],
]);
wrapper
=
extendedWrapper
(
mount
(
IterationForm
,
{
...
...
@@ -95,7 +90,10 @@ describe('Iteration Form', () => {
const
resolverMock
=
jest
.
fn
().
mockResolvedValue
(
createMutationSuccess
);
beforeEach
(()
=>
{
router
.
replace
({
name
:
'
newIteration
'
,
params
:
{
cadenceId
,
iterationId
:
undefined
}
});
router
.
replace
({
name
:
'
newIteration
'
,
params
:
{
cadenceId
,
iterationId
:
undefined
},
});
createComponent
({
resolverMock
});
});
...
...
@@ -126,7 +124,7 @@ describe('Iteration Form', () => {
groupPath
,
title
,
description
,
iterationsCadenceId
:
convertToGraphQLId
(
'
Iterations::Cadence
'
,
cadence
I
d
),
iterationsCadenceId
:
convertToGraphQLId
(
'
Iterations::Cadence
'
,
cadence
.
i
d
),
startDate
,
dueDate
,
},
...
...
@@ -159,11 +157,49 @@ describe('Iteration Form', () => {
});
});
});
describe
(
'
prefill start date field
'
,
()
=>
{
describe
(
'
cadence with iterations
'
,
()
=>
{
it
(
'
starts next day after the last iteration
'
,
async
()
=>
{
await
createComponent
({
groupIterationsSuccess
:
nonEmptyGroupIterationsSuccess
,
});
await
waitForPromises
();
const
expectedDate
=
formatDate
(
dayAfter
(
new
Date
(
iteration
.
dueDate
),
{
utc
:
true
}),
'
yyyy-mm-dd
'
,
);
expect
(
findStartDate
().
element
.
value
).
toBe
(
expectedDate
);
});
});
describe
(
'
manual cadence without iterations
'
,
()
=>
{
beforeEach
(
async
()
=>
{
await
createComponent
({
groupIterationsSuccess
:
emptyGroupIterationsSuccess
,
});
await
nextTick
();
});
it
(
'
uses cadence start date
'
,
()
=>
{
const
expectedDate
=
cadence
.
startDate
;
expect
(
findStartDate
().
element
.
value
).
toBe
(
expectedDate
);
});
});
});
});
describe
(
'
Edit iteration
'
,
()
=>
{
beforeEach
(()
=>
{
router
.
replace
({
name
:
'
editIteration
'
,
params
:
{
cadenceId
,
iterationId
}
});
router
.
replace
({
name
:
'
editIteration
'
,
params
:
{
cadenceId
:
cadence
.
id
,
iterationId
:
iteration
.
id
},
});
});
afterEach
(()
=>
{
...
...
@@ -212,7 +248,7 @@ describe('Iteration Form', () => {
expect
(
resolverMock
).
toHaveBeenCalledWith
({
input
:
{
groupPath
,
id
:
iteration
I
d
,
id
:
iteration
.
i
d
,
title
,
description
,
startDate
,
...
...
@@ -236,7 +272,7 @@ describe('Iteration Form', () => {
expect
(
resolverMock
).
toHaveBeenCalledWith
({
input
:
{
groupPath
,
id
:
iteration
I
d
,
id
:
iteration
.
i
d
,
startDate
:
''
,
dueDate
:
''
,
title
:
''
,
...
...
ee/spec/frontend/iterations/mock_data.js
View file @
efac77f3
...
...
@@ -36,3 +36,78 @@ export const mockProjectIterations = {
},
},
};
export
const
manualIterationCadence
=
{
id
:
`gid://gitlab/Iterations::Cadence/72`
,
title
:
'
A manual iteration cadence
'
,
automatic
:
true
,
rollOver
:
false
,
durationInWeeks
:
'
3
'
,
description
:
'
The words
'
,
duration
:
'
3
'
,
startDate
:
'
2020-06-28
'
,
iterationsInAdvance
:
'
2
'
,
};
export
const
createMutationSuccess
=
{
data
:
{
iterationCreate
:
{
iteration
:
mockIterationNode
,
errors
:
[]
}
},
};
export
const
createMutationFailure
=
{
data
:
{
iterationCreate
:
{
iteration
:
mockIterationNode
,
errors
:
[
'
alas, your data is unchanged
'
]
},
},
};
export
const
updateMutationSuccess
=
{
data
:
{
updateIteration
:
{
iteration
:
mockIterationNode
,
errors
:
[]
}
},
};
export
const
emptyGroupIterationsSuccess
=
{
data
:
{
workspace
:
{
id
:
'
gid://gitlab/Group/114
'
,
iterations
:
{
nodes
:
[],
pageInfo
:
{
hasNextPage
:
false
,
hasPreviousPage
:
false
,
startCursor
:
''
,
endCursor
:
''
,
},
},
},
},
};
export
const
nonEmptyGroupIterationsSuccess
=
{
data
:
{
workspace
:
{
id
:
1
,
iterations
:
{
nodes
:
[
{
...
mockIterationNode
,
scopedPath
:
'
/
'
,
},
],
pageInfo
:
{
hasNextPage
:
false
,
hasPreviousPage
:
false
,
startCursor
:
''
,
endCursor
:
''
,
},
},
},
},
};
export
const
readCadenceSuccess
=
{
data
:
{
group
:
{
id
:
'
gid://gitlab/Group/114
'
,
iterationCadences
:
{
nodes
:
[
manualIterationCadence
],
},
},
},
};
locale/gitlab.pot
View file @
efac77f3
...
...
@@ -19597,6 +19597,9 @@ msgstr ""
msgid "Iterations|Title"
msgstr ""
msgid "Iterations|Unable to find iteration cadence."
msgstr ""
msgid "Iterations|Unable to find iteration."
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