Commit b3cc00ac authored by Thomas Randolph's avatar Thomas Randolph

Toggle file tree bolding based on file "Viewed" status

Before, when scrolling to a file in the MR Review OR when
clicking the file title in the file tree view, the file would
be marked as "viewed" (and thus unbolded).

Now, the only action that can signify that a file is viewed
(and unbold the entry in the tree) is clicking the "Viewed"
checkbox on the file header in the Diffs view.

Changelog: changed
parent fc4b64a2
...@@ -85,6 +85,12 @@ export const setBaseConfig = ({ commit }, options) => { ...@@ -85,6 +85,12 @@ export const setBaseConfig = ({ commit }, options) => {
viewDiffsFileByFile, viewDiffsFileByFile,
mrReviews, mrReviews,
}); });
Array.from(new Set(Object.values(mrReviews).flat())).forEach((id) => {
const viewedId = id.replace(/^hash:/, '');
commit(types.SET_DIFF_FILE_VIEWED, { id: viewedId, seen: true });
});
}; };
export const fetchDiffFilesBatch = ({ commit, state, dispatch }) => { export const fetchDiffFilesBatch = ({ commit, state, dispatch }) => {
...@@ -850,6 +856,8 @@ export function reviewFile({ commit, state }, { file, reviewed = true }) { ...@@ -850,6 +856,8 @@ export function reviewFile({ commit, state }, { file, reviewed = true }) {
const reviews = markFileReview(state.mrReviews, file, reviewed); const reviews = markFileReview(state.mrReviews, file, reviewed);
setReviewsForMergeRequest(mrPath, reviews); setReviewsForMergeRequest(mrPath, reviews);
commit(types.SET_DIFF_FILE_VIEWED, { id: file.file_hash, seen: reviewed });
commit(types.SET_MR_FILE_REVIEWS, reviews); commit(types.SET_MR_FILE_REVIEWS, reviews);
} }
......
...@@ -256,7 +256,6 @@ export default { ...@@ -256,7 +256,6 @@ export default {
}, },
[types.VIEW_DIFF_FILE](state, fileId) { [types.VIEW_DIFF_FILE](state, fileId) {
state.currentDiffFileId = fileId; state.currentDiffFileId = fileId;
Vue.set(state.viewedDiffFileIds, fileId, true);
}, },
[types.SET_DIFF_FILE_VIEWED](state, { id, seen }) { [types.SET_DIFF_FILE_VIEWED](state, { id, seen }) {
Vue.set(state.viewedDiffFileIds, id, seen); Vue.set(state.viewedDiffFileIds, id, seen);
......
...@@ -52,8 +52,10 @@ export function markFileReview(reviews, file, reviewed = true) { ...@@ -52,8 +52,10 @@ export function markFileReview(reviews, file, reviewed = true) {
if (reviewed) { if (reviewed) {
fileReviews.add(file.id); fileReviews.add(file.id);
fileReviews.add(`hash:${file.file_hash}`);
} else { } else {
fileReviews.delete(file.id); fileReviews.delete(file.id);
fileReviews.delete(`hash:${file.file_hash}`);
} }
updatedReviews[file.file_identifier_hash] = Array.from(fileReviews); updatedReviews[file.file_identifier_hash] = Array.from(fileReviews);
......
...@@ -7,7 +7,7 @@ import { mockTracking, triggerEvent } from 'helpers/tracking_helper'; ...@@ -7,7 +7,7 @@ import { mockTracking, triggerEvent } from 'helpers/tracking_helper';
import DiffFileHeader from '~/diffs/components/diff_file_header.vue'; import DiffFileHeader from '~/diffs/components/diff_file_header.vue';
import { DIFF_FILE_AUTOMATIC_COLLAPSE, DIFF_FILE_MANUAL_COLLAPSE } from '~/diffs/constants'; import { DIFF_FILE_AUTOMATIC_COLLAPSE, DIFF_FILE_MANUAL_COLLAPSE } from '~/diffs/constants';
import { reviewFile } from '~/diffs/store/actions'; import { reviewFile } from '~/diffs/store/actions';
import { SET_MR_FILE_REVIEWS } from '~/diffs/store/mutation_types'; import { SET_DIFF_FILE_VIEWED, SET_MR_FILE_REVIEWS } from '~/diffs/store/mutation_types';
import { diffViewerModes } from '~/ide/constants'; import { diffViewerModes } from '~/ide/constants';
import { scrollToElement } from '~/lib/utils/common_utils'; import { scrollToElement } from '~/lib/utils/common_utils';
import { truncateSha } from '~/lib/utils/text_utility'; import { truncateSha } from '~/lib/utils/text_utility';
...@@ -23,6 +23,7 @@ jest.mock('~/lib/utils/common_utils'); ...@@ -23,6 +23,7 @@ jest.mock('~/lib/utils/common_utils');
const diffFile = Object.freeze( const diffFile = Object.freeze(
Object.assign(diffDiscussionsMockData.diff_file, { Object.assign(diffDiscussionsMockData.diff_file, {
id: '123', id: '123',
file_hash: 'xyz',
file_identifier_hash: 'abc', file_identifier_hash: 'abc',
edit_path: 'link:/to/edit/path', edit_path: 'link:/to/edit/path',
blob: { blob: {
...@@ -553,7 +554,13 @@ describe('DiffFileHeader component', () => { ...@@ -553,7 +554,13 @@ describe('DiffFileHeader component', () => {
reviewFile, reviewFile,
{ file, reviewed: true }, { file, reviewed: true },
{}, {},
[{ type: SET_MR_FILE_REVIEWS, payload: { [file.file_identifier_hash]: [file.id] } }], [
{ type: SET_DIFF_FILE_VIEWED, payload: { id: file.file_hash, seen: true } },
{
type: SET_MR_FILE_REVIEWS,
payload: { [file.file_identifier_hash]: [file.id, `hash:${file.file_hash}`] },
},
],
[], [],
); );
}); });
......
...@@ -99,6 +99,10 @@ describe('DiffsStoreActions', () => { ...@@ -99,6 +99,10 @@ describe('DiffsStoreActions', () => {
const projectPath = '/root/project'; const projectPath = '/root/project';
const dismissEndpoint = '/-/user_callouts'; const dismissEndpoint = '/-/user_callouts';
const showSuggestPopover = false; const showSuggestPopover = false;
const mrReviews = {
a: ['z', 'hash:a'],
b: ['y', 'hash:a'],
};
testAction( testAction(
setBaseConfig, setBaseConfig,
...@@ -110,6 +114,7 @@ describe('DiffsStoreActions', () => { ...@@ -110,6 +114,7 @@ describe('DiffsStoreActions', () => {
projectPath, projectPath,
dismissEndpoint, dismissEndpoint,
showSuggestPopover, showSuggestPopover,
mrReviews,
}, },
{ {
endpoint: '', endpoint: '',
...@@ -131,8 +136,21 @@ describe('DiffsStoreActions', () => { ...@@ -131,8 +136,21 @@ describe('DiffsStoreActions', () => {
projectPath, projectPath,
dismissEndpoint, dismissEndpoint,
showSuggestPopover, showSuggestPopover,
mrReviews,
}, },
}, },
{
type: types.SET_DIFF_FILE_VIEWED,
payload: { id: 'z', seen: true },
},
{
type: types.SET_DIFF_FILE_VIEWED,
payload: { id: 'a', seen: true },
},
{
type: types.SET_DIFF_FILE_VIEWED,
payload: { id: 'y', seen: true },
},
], ],
[], [],
done, done,
...@@ -1523,13 +1541,14 @@ describe('DiffsStoreActions', () => { ...@@ -1523,13 +1541,14 @@ describe('DiffsStoreActions', () => {
describe('reviewFile', () => { describe('reviewFile', () => {
const file = { const file = {
id: '123', id: '123',
file_hash: 'xyz',
file_identifier_hash: 'abc', file_identifier_hash: 'abc',
load_collapsed_diff_url: 'gitlab-org/gitlab-test/-/merge_requests/1/diffs', load_collapsed_diff_url: 'gitlab-org/gitlab-test/-/merge_requests/1/diffs',
}; };
it.each` it.each`
reviews | diffFile | reviewed reviews | diffFile | reviewed
${{ abc: ['123'] }} | ${file} | ${true} ${{ abc: ['123', 'hash:xyz'] }} | ${file} | ${true}
${{}} | ${file} | ${false} ${{}} | ${file} | ${false}
`( `(
'sets reviews ($reviews) to localStorage and state for file $file if it is marked reviewed=$reviewed', 'sets reviews ($reviews) to localStorage and state for file $file if it is marked reviewed=$reviewed',
({ reviews, diffFile, reviewed }) => { ({ reviews, diffFile, reviewed }) => {
......
...@@ -11,14 +11,14 @@ import { ...@@ -11,14 +11,14 @@ import {
function getDefaultReviews() { function getDefaultReviews() {
return { return {
abc: ['123', '098'], abc: ['123', 'hash:xyz', '098', 'hash:uvw'],
}; };
} }
describe('File Review(s) utilities', () => { describe('File Review(s) utilities', () => {
const mrPath = 'my/fake/mr/42'; const mrPath = 'my/fake/mr/42';
const storageKey = `${mrPath}-file-reviews`; const storageKey = `${mrPath}-file-reviews`;
const file = { id: '123', file_identifier_hash: 'abc' }; const file = { id: '123', file_hash: 'xyz', file_identifier_hash: 'abc' };
const storedValue = JSON.stringify(getDefaultReviews()); const storedValue = JSON.stringify(getDefaultReviews());
let reviews; let reviews;
...@@ -44,14 +44,14 @@ describe('File Review(s) utilities', () => { ...@@ -44,14 +44,14 @@ describe('File Review(s) utilities', () => {
}); });
describe('reviewStatuses', () => { describe('reviewStatuses', () => {
const file1 = { id: '123', file_identifier_hash: 'abc' }; const file1 = { id: '123', hash: 'xyz', file_identifier_hash: 'abc' };
const file2 = { id: '098', file_identifier_hash: 'abc' }; const file2 = { id: '098', hash: 'uvw', file_identifier_hash: 'abc' };
it.each` it.each`
mrReviews | files | fileReviews mrReviews | files | fileReviews
${{}} | ${[file1, file2]} | ${{ 123: false, '098': false }} ${{}} | ${[file1, file2]} | ${{ 123: false, '098': false }}
${{ abc: ['123'] }} | ${[file1, file2]} | ${{ 123: true, '098': false }} ${{ abc: ['123', 'hash:xyz'] }} | ${[file1, file2]} | ${{ 123: true, '098': false }}
${{ abc: ['098'] }} | ${[file1, file2]} | ${{ 123: false, '098': true }} ${{ abc: ['098', 'hash:uvw'] }} | ${[file1, file2]} | ${{ 123: false, '098': true }}
${{ def: ['123'] }} | ${[file1, file2]} | ${{ 123: false, '098': false }} ${{ def: ['123'] }} | ${[file1, file2]} | ${{ 123: false, '098': false }}
${{ abc: ['123'], def: ['098'] }} | ${[]} | ${{}} ${{ abc: ['123'], def: ['098'] }} | ${[]} | ${{}}
`( `(
...@@ -128,7 +128,7 @@ describe('File Review(s) utilities', () => { ...@@ -128,7 +128,7 @@ describe('File Review(s) utilities', () => {
describe('markFileReview', () => { describe('markFileReview', () => {
it("adds a review when there's nothing that already exists", () => { it("adds a review when there's nothing that already exists", () => {
expect(markFileReview(null, file)).toStrictEqual({ abc: ['123'] }); expect(markFileReview(null, file)).toStrictEqual({ abc: ['123', 'hash:xyz'] });
}); });
it("overwrites an existing review if it's for the same file (identifier hash)", () => { it("overwrites an existing review if it's for the same file (identifier hash)", () => {
...@@ -136,15 +136,15 @@ describe('File Review(s) utilities', () => { ...@@ -136,15 +136,15 @@ describe('File Review(s) utilities', () => {
}); });
it('removes a review from the list when `reviewed` is `false`', () => { it('removes a review from the list when `reviewed` is `false`', () => {
expect(markFileReview(reviews, file, false)).toStrictEqual({ abc: ['098'] }); expect(markFileReview(reviews, file, false)).toStrictEqual({ abc: ['098', 'hash:uvw'] });
}); });
it('adds a new review if the file ID is new', () => { it('adds a new review if the file ID is new', () => {
const updatedFile = { ...file, id: '098' }; const updatedFile = { ...file, id: '098', file_hash: 'uvw' };
const allReviews = markFileReview({ abc: ['123'] }, updatedFile); const allReviews = markFileReview({ abc: ['123', 'hash:xyz'] }, updatedFile);
expect(allReviews).toStrictEqual(getDefaultReviews()); expect(allReviews).toStrictEqual(getDefaultReviews());
expect(allReviews.abc).toStrictEqual(['123', '098']); expect(allReviews.abc).toStrictEqual(['123', 'hash:xyz', '098', 'hash:uvw']);
}); });
it.each` it.each`
...@@ -158,7 +158,7 @@ describe('File Review(s) utilities', () => { ...@@ -158,7 +158,7 @@ describe('File Review(s) utilities', () => {
it('removes the file key if there are no more reviews for it', () => { it('removes the file key if there are no more reviews for it', () => {
let updated = markFileReview(reviews, file, false); let updated = markFileReview(reviews, file, false);
updated = markFileReview(updated, { ...file, id: '098' }, false); updated = markFileReview(updated, { ...file, id: '098', file_hash: 'uvw' }, false);
expect(updated).toStrictEqual({}); expect(updated).toStrictEqual({});
}); });
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment