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
7632330e
Commit
7632330e
authored
Jul 18, 2018
by
Fatih Acet
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fix showing outdated discussions on Changes tab
parent
489025bb
Changes
15
Show whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
146 additions
and
20 deletions
+146
-20
app/assets/javascripts/diffs/components/diff_line_gutter_content.vue
...javascripts/diffs/components/diff_line_gutter_content.vue
+2
-1
app/assets/javascripts/diffs/components/inline_diff_comment_row.vue
.../javascripts/diffs/components/inline_diff_comment_row.vue
+5
-2
app/assets/javascripts/diffs/components/inline_diff_view.vue
app/assets/javascripts/diffs/components/inline_diff_view.vue
+1
-2
app/assets/javascripts/diffs/components/parallel_diff_comment_row.vue
...avascripts/diffs/components/parallel_diff_comment_row.vue
+1
-1
app/assets/javascripts/diffs/components/parallel_diff_view.vue
...ssets/javascripts/diffs/components/parallel_diff_view.vue
+1
-2
app/assets/javascripts/diffs/store/getters.js
app/assets/javascripts/diffs/store/getters.js
+40
-0
app/assets/javascripts/diffs/store/utils.js
app/assets/javascripts/diffs/store/utils.js
+21
-0
app/assets/javascripts/notes/stores/getters.js
app/assets/javascripts/notes/stores/getters.js
+0
-12
app/serializers/discussion_entity.rb
app/serializers/discussion_entity.rb
+1
-0
changelogs/unreleased/_acet-fix-outdated-discussions.yml
changelogs/unreleased/_acet-fix-outdated-discussions.yml
+5
-0
spec/javascripts/diffs/components/diff_line_gutter_content_spec.js
...scripts/diffs/components/diff_line_gutter_content_spec.js
+2
-0
spec/javascripts/diffs/components/inline_diff_view_spec.js
spec/javascripts/diffs/components/inline_diff_view_spec.js
+1
-0
spec/javascripts/diffs/mock_data/diff_discussions.js
spec/javascripts/diffs/mock_data/diff_discussions.js
+11
-0
spec/javascripts/diffs/store/getters_spec.js
spec/javascripts/diffs/store/getters_spec.js
+35
-0
spec/javascripts/diffs/store/utils_spec.js
spec/javascripts/diffs/store/utils_spec.js
+20
-0
No files found.
app/assets/javascripts/diffs/components/diff_line_gutter_content.vue
View file @
7632330e
...
@@ -77,7 +77,8 @@ export default {
...
@@ -77,7 +77,8 @@ export default {
diffViewType
:
state
=>
state
.
diffs
.
diffViewType
,
diffViewType
:
state
=>
state
.
diffs
.
diffViewType
,
diffFiles
:
state
=>
state
.
diffs
.
diffFiles
,
diffFiles
:
state
=>
state
.
diffs
.
diffFiles
,
}),
}),
...
mapGetters
([
'
isLoggedIn
'
,
'
discussionsByLineCode
'
]),
...
mapGetters
([
'
isLoggedIn
'
]),
...
mapGetters
(
'
diffs
'
,
[
'
discussionsByLineCode
'
]),
lineHref
()
{
lineHref
()
{
return
this
.
lineCode
?
`#
${
this
.
lineCode
}
`
:
'
#
'
;
return
this
.
lineCode
?
`#
${
this
.
lineCode
}
`
:
'
#
'
;
},
},
...
...
app/assets/javascripts/diffs/components/inline_diff_comment_row.vue
View file @
7632330e
...
@@ -26,13 +26,16 @@ export default {
...
@@ -26,13 +26,16 @@ export default {
...
mapState
({
...
mapState
({
diffLineCommentForms
:
state
=>
state
.
diffs
.
diffLineCommentForms
,
diffLineCommentForms
:
state
=>
state
.
diffs
.
diffLineCommentForms
,
}),
}),
...
mapGetters
([
'
discussionsByLineCode
'
]),
...
mapGetters
(
'
diffs
'
,
[
'
discussionsByLineCode
'
]),
discussions
()
{
discussions
()
{
return
this
.
discussionsByLineCode
[
this
.
line
.
lineCode
]
||
[];
return
this
.
discussionsByLineCode
[
this
.
line
.
lineCode
]
||
[];
},
},
className
()
{
className
()
{
return
this
.
discussions
.
length
?
''
:
'
js-temp-notes-holder
'
;
return
this
.
discussions
.
length
?
''
:
'
js-temp-notes-holder
'
;
},
},
hasCommentForm
()
{
return
this
.
diffLineCommentForms
[
this
.
line
.
lineCode
];
},
},
},
};
};
</
script
>
</
script
>
...
@@ -53,7 +56,7 @@ export default {
...
@@ -53,7 +56,7 @@ export default {
:discussions=
"discussions"
:discussions=
"discussions"
/>
/>
<diff-line-note-form
<diff-line-note-form
v-if=
"
diffLineCommentForms[line.lineCode]
"
v-if=
"
hasCommentForm
"
:diff-file-hash=
"diffFileHash"
:diff-file-hash=
"diffFileHash"
:line=
"line"
:line=
"line"
:note-target-line=
"line"
:note-target-line=
"line"
...
...
app/assets/javascripts/diffs/components/inline_diff_view.vue
View file @
7632330e
...
@@ -20,8 +20,7 @@ export default {
...
@@ -20,8 +20,7 @@ export default {
},
},
},
},
computed
:
{
computed
:
{
...
mapGetters
(
'
diffs
'
,
[
'
commitId
'
]),
...
mapGetters
(
'
diffs
'
,
[
'
commitId
'
,
'
discussionsByLineCode
'
]),
...
mapGetters
([
'
discussionsByLineCode
'
]),
...
mapState
({
...
mapState
({
diffLineCommentForms
:
state
=>
state
.
diffs
.
diffLineCommentForms
,
diffLineCommentForms
:
state
=>
state
.
diffs
.
diffLineCommentForms
,
}),
}),
...
...
app/assets/javascripts/diffs/components/parallel_diff_comment_row.vue
View file @
7632330e
...
@@ -26,7 +26,7 @@ export default {
...
@@ -26,7 +26,7 @@ export default {
...
mapState
({
...
mapState
({
diffLineCommentForms
:
state
=>
state
.
diffs
.
diffLineCommentForms
,
diffLineCommentForms
:
state
=>
state
.
diffs
.
diffLineCommentForms
,
}),
}),
...
mapGetters
([
'
discussionsByLineCode
'
]),
...
mapGetters
(
'
diffs
'
,
[
'
discussionsByLineCode
'
]),
leftLineCode
()
{
leftLineCode
()
{
return
this
.
line
.
left
.
lineCode
;
return
this
.
line
.
left
.
lineCode
;
},
},
...
...
app/assets/javascripts/diffs/components/parallel_diff_view.vue
View file @
7632330e
...
@@ -21,8 +21,7 @@ export default {
...
@@ -21,8 +21,7 @@ export default {
},
},
},
},
computed
:
{
computed
:
{
...
mapGetters
(
'
diffs
'
,
[
'
commitId
'
]),
...
mapGetters
(
'
diffs
'
,
[
'
commitId
'
,
'
discussionsByLineCode
'
]),
...
mapGetters
([
'
discussionsByLineCode
'
]),
...
mapState
({
...
mapState
({
diffLineCommentForms
:
state
=>
state
.
diffs
.
diffLineCommentForms
,
diffLineCommentForms
:
state
=>
state
.
diffs
.
diffLineCommentForms
,
}),
}),
...
...
app/assets/javascripts/diffs/store/getters.js
View file @
7632330e
import
_
from
'
underscore
'
;
import
_
from
'
underscore
'
;
import
{
convertObjectPropsToCamelCase
}
from
'
~/lib/utils/common_utils
'
;
import
{
PARALLEL_DIFF_VIEW_TYPE
,
INLINE_DIFF_VIEW_TYPE
}
from
'
../constants
'
;
import
{
PARALLEL_DIFF_VIEW_TYPE
,
INLINE_DIFF_VIEW_TYPE
}
from
'
../constants
'
;
import
{
getDiffRefsByLineCode
}
from
'
./utils
'
;
export
const
isParallelView
=
state
=>
state
.
diffViewType
===
PARALLEL_DIFF_VIEW_TYPE
;
export
const
isParallelView
=
state
=>
state
.
diffViewType
===
PARALLEL_DIFF_VIEW_TYPE
;
...
@@ -56,6 +58,44 @@ export const getDiffFileDiscussions = (state, getters, rootState, rootGetters) =
...
@@ -56,6 +58,44 @@ export const getDiffFileDiscussions = (state, getters, rootState, rootGetters) =
discussion
.
diff_discussion
&&
_
.
isEqual
(
discussion
.
diff_file
.
file_hash
,
diff
.
fileHash
),
discussion
.
diff_discussion
&&
_
.
isEqual
(
discussion
.
diff_file
.
file_hash
,
diff
.
fileHash
),
)
||
[];
)
||
[];
/**
* Returns an Object with discussions by their diff line code
* To avoid rendering outdated discussions on the Changes tab we should do a bunch of SHA
* comparisions. `note.position.formatter` have the current version diff refs but
* `note.original_position.formatter` will have the first version's diff refs.
* If line diff refs matches with one of them, we should render it as a discussion on Changes tab.
*
* @param {Object} diff
* @returns {Array}
*/
export
const
discussionsByLineCode
=
(
state
,
getters
,
rootState
,
rootGetters
)
=>
{
const
diffRefsByLineCode
=
getDiffRefsByLineCode
(
state
.
diffFiles
);
return
rootGetters
.
discussions
.
reduce
((
acc
,
note
)
=>
{
const
isDiffDiscussion
=
note
.
diff_discussion
;
const
hasLineCode
=
note
.
line_code
;
const
isResolvable
=
note
.
resolvable
;
const
diffRefs
=
diffRefsByLineCode
[
note
.
line_code
];
if
(
isDiffDiscussion
&&
hasLineCode
&&
isResolvable
&&
diffRefs
)
{
const
refs
=
convertObjectPropsToCamelCase
(
note
.
position
.
formatter
);
const
originalRefs
=
convertObjectPropsToCamelCase
(
note
.
original_position
.
formatter
);
if
(
_
.
isEqual
(
refs
,
diffRefs
)
||
_
.
isEqual
(
originalRefs
,
diffRefs
))
{
const
lineCode
=
note
.
line_code
;
if
(
acc
[
lineCode
])
{
acc
[
lineCode
].
push
(
note
);
}
else
{
acc
[
lineCode
]
=
[
note
];
}
}
}
return
acc
;
},
{});
};
// prevent babel-plugin-rewire from generating an invalid default during karma∂ tests
// prevent babel-plugin-rewire from generating an invalid default during karma∂ tests
export
const
getDiffFileByHash
=
state
=>
fileHash
=>
export
const
getDiffFileByHash
=
state
=>
fileHash
=>
state
.
diffFiles
.
find
(
file
=>
file
.
fileHash
===
fileHash
);
state
.
diffFiles
.
find
(
file
=>
file
.
fileHash
===
fileHash
);
...
...
app/assets/javascripts/diffs/store/utils.js
View file @
7632330e
...
@@ -173,3 +173,24 @@ export function trimFirstCharOfLineContent(line = {}) {
...
@@ -173,3 +173,24 @@ export function trimFirstCharOfLineContent(line = {}) {
return
parsedLine
;
return
parsedLine
;
}
}
export
function
getDiffRefsByLineCode
(
diffFiles
)
{
return
diffFiles
.
reduce
((
acc
,
diffFile
)
=>
{
const
{
baseSha
,
headSha
,
startSha
}
=
diffFile
.
diffRefs
;
const
{
newPath
,
oldPath
}
=
diffFile
;
// We can only use highlightedDiffLines to create the map of diff lines because
// highlightedDiffLines will also include every parallel diff line in it.
if
(
diffFile
.
highlightedDiffLines
)
{
diffFile
.
highlightedDiffLines
.
forEach
(
line
=>
{
const
{
lineCode
,
oldLine
,
newLine
}
=
line
;
if
(
lineCode
)
{
acc
[
lineCode
]
=
{
baseSha
,
headSha
,
startSha
,
newPath
,
oldPath
,
oldLine
,
newLine
};
}
});
}
return
acc
;
},
{});
}
app/assets/javascripts/notes/stores/getters.js
View file @
7632330e
...
@@ -28,18 +28,6 @@ export const notesById = state =>
...
@@ -28,18 +28,6 @@ export const notesById = state =>
return
acc
;
return
acc
;
},
{});
},
{});
export
const
discussionsByLineCode
=
state
=>
state
.
discussions
.
reduce
((
acc
,
note
)
=>
{
if
(
note
.
diff_discussion
&&
note
.
line_code
&&
note
.
resolvable
)
{
// For context about line notes: there might be multiple notes with the same line code
const
items
=
acc
[
note
.
line_code
]
||
[];
items
.
push
(
note
);
Object
.
assign
(
acc
,
{
[
note
.
line_code
]:
items
});
}
return
acc
;
},
{});
export
const
noteableType
=
state
=>
{
export
const
noteableType
=
state
=>
{
const
{
ISSUE_NOTEABLE_TYPE
,
MERGE_REQUEST_NOTEABLE_TYPE
,
EPIC_NOTEABLE_TYPE
}
=
constants
;
const
{
ISSUE_NOTEABLE_TYPE
,
MERGE_REQUEST_NOTEABLE_TYPE
,
EPIC_NOTEABLE_TYPE
}
=
constants
;
...
...
app/serializers/discussion_entity.rb
View file @
7632330e
...
@@ -4,6 +4,7 @@ class DiscussionEntity < Grape::Entity
...
@@ -4,6 +4,7 @@ class DiscussionEntity < Grape::Entity
expose
:id
,
:reply_id
expose
:id
,
:reply_id
expose
:position
,
if:
->
(
d
,
_
)
{
d
.
diff_discussion?
&&
!
d
.
legacy_diff_discussion?
}
expose
:position
,
if:
->
(
d
,
_
)
{
d
.
diff_discussion?
&&
!
d
.
legacy_diff_discussion?
}
expose
:original_position
,
if:
->
(
d
,
_
)
{
d
.
diff_discussion?
&&
!
d
.
legacy_diff_discussion?
}
expose
:line_code
,
if:
->
(
d
,
_
)
{
d
.
diff_discussion?
}
expose
:line_code
,
if:
->
(
d
,
_
)
{
d
.
diff_discussion?
}
expose
:expanded?
,
as: :expanded
expose
:expanded?
,
as: :expanded
expose
:active?
,
as: :active
,
if:
->
(
d
,
_
)
{
d
.
diff_discussion?
}
expose
:active?
,
as: :active
,
if:
->
(
d
,
_
)
{
d
.
diff_discussion?
}
...
...
changelogs/unreleased/_acet-fix-outdated-discussions.yml
0 → 100644
View file @
7632330e
---
title
:
Fix showing outdated discussions on Changes tab
merge_request
:
20445
author
:
type
:
fixed
spec/javascripts/diffs/components/diff_line_gutter_content_spec.js
View file @
7632330e
...
@@ -18,10 +18,12 @@ describe('DiffLineGutterContent', () => {
...
@@ -18,10 +18,12 @@ describe('DiffLineGutterContent', () => {
};
};
const
setDiscussions
=
component
=>
{
const
setDiscussions
=
component
=>
{
component
.
$store
.
dispatch
(
'
setInitialNotes
'
,
getDiscussionsMockData
());
component
.
$store
.
dispatch
(
'
setInitialNotes
'
,
getDiscussionsMockData
());
component
.
$store
.
commit
(
'
diffs/SET_DIFF_DATA
'
,
{
diffFiles
:
[
getDiffFileMock
()]
});
};
};
const
resetDiscussions
=
component
=>
{
const
resetDiscussions
=
component
=>
{
component
.
$store
.
dispatch
(
'
setInitialNotes
'
,
[]);
component
.
$store
.
dispatch
(
'
setInitialNotes
'
,
[]);
component
.
$store
.
commit
(
'
diffs/SET_DIFF_DATA
'
,
{});
};
};
describe
(
'
computed
'
,
()
=>
{
describe
(
'
computed
'
,
()
=>
{
...
...
spec/javascripts/diffs/components/inline_diff_view_spec.js
View file @
7632330e
...
@@ -33,6 +33,7 @@ describe('InlineDiffView', () => {
...
@@ -33,6 +33,7 @@ describe('InlineDiffView', () => {
it
(
'
should render discussions
'
,
done
=>
{
it
(
'
should render discussions
'
,
done
=>
{
const
el
=
component
.
$el
;
const
el
=
component
.
$el
;
component
.
$store
.
dispatch
(
'
setInitialNotes
'
,
getDiscussionsMockData
());
component
.
$store
.
dispatch
(
'
setInitialNotes
'
,
getDiscussionsMockData
());
component
.
$store
.
commit
(
'
diffs/SET_DIFF_DATA
'
,
{
diffFiles
:
[
getDiffFileMock
()]
});
Vue
.
nextTick
(()
=>
{
Vue
.
nextTick
(()
=>
{
expect
(
el
.
querySelectorAll
(
'
.notes_holder
'
).
length
).
toEqual
(
1
);
expect
(
el
.
querySelectorAll
(
'
.notes_holder
'
).
length
).
toEqual
(
1
);
...
...
spec/javascripts/diffs/mock_data/diff_discussions.js
View file @
7632330e
...
@@ -12,6 +12,17 @@ export default {
...
@@ -12,6 +12,17 @@ export default {
head_sha
:
'
c48ee0d1bf3b30453f5b32250ce03134beaa6d13
'
,
head_sha
:
'
c48ee0d1bf3b30453f5b32250ce03134beaa6d13
'
,
},
},
},
},
original_position
:
{
formatter
:
{
old_line
:
null
,
new_line
:
2
,
old_path
:
'
CHANGELOG
'
,
new_path
:
'
CHANGELOG
'
,
base_sha
:
'
e63f41fe459e62e1228fcef60d7189127aeba95a
'
,
start_sha
:
'
d9eaefe5a676b820c57ff18cf5b68316025f7962
'
,
head_sha
:
'
c48ee0d1bf3b30453f5b32250ce03134beaa6d13
'
,
},
},
line_code
:
'
1c497fbb3a46b78edf04cc2a2fa33f67e3ffbe2a_1_2
'
,
line_code
:
'
1c497fbb3a46b78edf04cc2a2fa33f67e3ffbe2a_1_2
'
,
expanded
:
true
,
expanded
:
true
,
notes
:
[
notes
:
[
...
...
spec/javascripts/diffs/store/getters_spec.js
View file @
7632330e
...
@@ -2,6 +2,7 @@ import * as getters from '~/diffs/store/getters';
...
@@ -2,6 +2,7 @@ import * as getters from '~/diffs/store/getters';
import
state
from
'
~/diffs/store/modules/diff_state
'
;
import
state
from
'
~/diffs/store/modules/diff_state
'
;
import
{
PARALLEL_DIFF_VIEW_TYPE
,
INLINE_DIFF_VIEW_TYPE
}
from
'
~/diffs/constants
'
;
import
{
PARALLEL_DIFF_VIEW_TYPE
,
INLINE_DIFF_VIEW_TYPE
}
from
'
~/diffs/constants
'
;
import
discussion
from
'
../mock_data/diff_discussions
'
;
import
discussion
from
'
../mock_data/diff_discussions
'
;
import
diffFile
from
'
../mock_data/diff_file
'
;
describe
(
'
Diffs Module Getters
'
,
()
=>
{
describe
(
'
Diffs Module Getters
'
,
()
=>
{
let
localState
;
let
localState
;
...
@@ -203,4 +204,38 @@ describe('Diffs Module Getters', () => {
...
@@ -203,4 +204,38 @@ describe('Diffs Module Getters', () => {
expect
(
getters
.
getDiffFileByHash
(
localState
)(
'
123
'
)).
toBeUndefined
();
expect
(
getters
.
getDiffFileByHash
(
localState
)(
'
123
'
)).
toBeUndefined
();
});
});
});
});
describe
(
'
discussionsByLineCode
'
,
()
=>
{
let
mockState
;
beforeEach
(()
=>
{
mockState
=
{
diffFiles
:
[
diffFile
]
};
});
it
(
'
should return a map of diff lines with their line codes
'
,
()
=>
{
const
mockGetters
=
{
discussions
:
[
discussionMock
]
};
const
map
=
getters
.
discussionsByLineCode
(
mockState
,
{},
{},
mockGetters
);
expect
(
map
[
'
1c497fbb3a46b78edf04cc2a2fa33f67e3ffbe2a_1_2
'
]).
toBeDefined
();
expect
(
Object
.
keys
(
map
).
length
).
toEqual
(
1
);
});
it
(
'
should have the diff discussion on the map if the original position matches
'
,
()
=>
{
discussionMock
.
position
.
formatter
.
base_sha
=
'
ff9200
'
;
const
mockGetters
=
{
discussions
:
[
discussionMock
]
};
const
map
=
getters
.
discussionsByLineCode
(
mockState
,
{},
{},
mockGetters
);
expect
(
map
[
'
1c497fbb3a46b78edf04cc2a2fa33f67e3ffbe2a_1_2
'
]).
toBeDefined
();
expect
(
Object
.
keys
(
map
).
length
).
toEqual
(
1
);
});
it
(
'
should not add an outdated diff discussion to the returned map
'
,
()
=>
{
discussionMock
.
position
.
formatter
.
base_sha
=
'
ff9200
'
;
discussionMock
.
original_position
.
formatter
.
base_sha
=
'
ff9200
'
;
const
mockGetters
=
{
discussions
:
[
discussionMock
]
};
const
map
=
getters
.
discussionsByLineCode
(
mockState
,
{},
{},
mockGetters
);
expect
(
Object
.
keys
(
map
).
length
).
toEqual
(
0
);
});
});
});
});
spec/javascripts/diffs/store/utils_spec.js
View file @
7632330e
...
@@ -207,4 +207,24 @@ describe('DiffsStoreUtils', () => {
...
@@ -207,4 +207,24 @@ describe('DiffsStoreUtils', () => {
expect
(
utils
.
trimFirstCharOfLineContent
()).
toEqual
({});
expect
(
utils
.
trimFirstCharOfLineContent
()).
toEqual
({});
});
});
});
});
describe
(
'
getDiffRefsByLineCode
'
,
()
=>
{
it
(
'
should return diffRefs for all highlightedDiffLines
'
,
()
=>
{
const
diffFile
=
getDiffFileMock
();
const
map
=
utils
.
getDiffRefsByLineCode
([
diffFile
]);
const
{
highlightedDiffLines
}
=
diffFile
;
const
lineCodeCount
=
highlightedDiffLines
.
reduce
(
(
acc
,
line
)
=>
(
line
.
lineCode
?
acc
+
1
:
acc
),
0
,
);
const
{
baseSha
,
headSha
,
startSha
}
=
diffFile
.
diffRefs
;
const
targetLine
=
map
[
highlightedDiffLines
[
4
].
lineCode
];
expect
(
Object
.
keys
(
map
).
length
).
toEqual
(
lineCodeCount
);
expect
(
targetLine
.
baseSha
).
toEqual
(
baseSha
);
expect
(
targetLine
.
headSha
).
toEqual
(
headSha
);
expect
(
targetLine
.
startSha
).
toEqual
(
startSha
);
});
});
});
});
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