diff --git a/app/assets/javascripts/rapid_diffs/adapters/discussions.js b/app/assets/javascripts/rapid_diffs/adapters/discussions.js
index fdb28d8dbf6efc96f01618a74ee86c28c3221f4d..eda1ec7f414c9e6330491e43f43195db3a620e04 100644
--- a/app/assets/javascripts/rapid_diffs/adapters/discussions.js
+++ b/app/assets/javascripts/rapid_diffs/adapters/discussions.js
@@ -33,6 +33,8 @@ function mountVueApp(el, id, appData) {
render(h) {
if (!this.discussion) return null;
+ if (this.discussion.hidden) return null;
+
if (this.discussion.isForm) {
return h(NewLineDiscussionForm, { props: { discussion: this.discussion } });
}
@@ -175,6 +177,8 @@ export const parallelDiscussionsAdapter = {
newDiscussion(event, button) {
const [oldLine, newLine] = getParallelPosition(button);
const { oldPath, newPath } = this.data;
+ // Show all discussions for this file when adding a new discussion
+ useDiffDiscussions(pinia).toggleFileDiscussions(oldPath, newPath, false);
const existingDiscussionId = useDiffDiscussions(pinia).addNewLineDiscussionForm({
oldPath,
newPath,
@@ -199,6 +203,8 @@ export const inlineDiscussionsAdapter = {
newDiscussion(event, button) {
const [oldLine, newLine] = getInlinePosition(button);
const { oldPath, newPath } = this.data;
+ // Show all discussions for this file when adding a new discussion
+ useDiffDiscussions(pinia).toggleFileDiscussions(oldPath, newPath, false);
const existingDiscussionId = useDiffDiscussions(pinia).addNewLineDiscussionForm({
oldPath,
newPath,
diff --git a/app/assets/javascripts/rapid_diffs/adapters/options_menu.js b/app/assets/javascripts/rapid_diffs/adapters/options_menu.js
index f8f336f94f80258dfd869cfb17ab551bbf94f989..8aa2c7f3870a0f18621078e807c591a7c2d720e2 100644
--- a/app/assets/javascripts/rapid_diffs/adapters/options_menu.js
+++ b/app/assets/javascripts/rapid_diffs/adapters/options_menu.js
@@ -1,24 +1,33 @@
import Vue from 'vue';
+import { pinia } from '~/pinia/instance';
import DiffFileOptionsDropdown from '~/rapid_diffs/app/options_menu/diff_file_options_dropdown.vue';
+import CommitDiffsFileOptionsDropdown from '~/rapid_diffs/app/options_menu/commit_diffs_file_options_dropdown.vue';
function getMenuItems(container) {
return JSON.parse(container.querySelector('script').textContent);
}
-export const optionsMenuAdapter = {
- clicks: {
- toggleOptionsMenu(event, button) {
- const menuContainer = this.diffElement.querySelector('[data-options-menu]');
- if (!menuContainer) return;
- const items = getMenuItems(menuContainer);
- // eslint-disable-next-line no-new
- new Vue({
- el: Vue.version.startsWith('2') ? button : menuContainer,
- name: 'GlDisclosureDropdown',
- render(h) {
- return h(DiffFileOptionsDropdown, { props: { items } });
- },
- });
+const createOptionsMenuAdaptor = (dropdownComponent) => {
+ return {
+ clicks: {
+ toggleOptionsMenu(event, button) {
+ const menuContainer = this.diffElement.querySelector('[data-options-menu]');
+ if (!menuContainer) return;
+ const items = getMenuItems(menuContainer);
+ const { oldPath, newPath } = this.data;
+ // eslint-disable-next-line no-new
+ new Vue({
+ el: Vue.version.startsWith('2') ? button : menuContainer,
+ name: 'GlDisclosureDropdown',
+ pinia,
+ render(h) {
+ return h(dropdownComponent, { props: { items, oldPath, newPath } });
+ },
+ });
+ },
},
- },
+ };
};
+
+export const optionsMenuAdapter = createOptionsMenuAdaptor(DiffFileOptionsDropdown);
+export const commitOptionsMenuAdaptor = createOptionsMenuAdaptor(CommitDiffsFileOptionsDropdown);
diff --git a/app/assets/javascripts/rapid_diffs/app/adapter_configs/commit.js b/app/assets/javascripts/rapid_diffs/app/adapter_configs/commit.js
index 594a3a68598cddabd59788f1cfb7267913f0b7c2..0b5e33934e5aa4ea4e5100c688296ee64bfb4f47 100644
--- a/app/assets/javascripts/rapid_diffs/app/adapter_configs/commit.js
+++ b/app/assets/javascripts/rapid_diffs/app/adapter_configs/commit.js
@@ -3,9 +3,17 @@ import {
inlineDiscussionsAdapter,
parallelDiscussionsAdapter,
} from '~/rapid_diffs/adapters/discussions';
+import { optionsMenuAdapter, commitOptionsMenuAdaptor } from '~/rapid_diffs/adapters/options_menu';
export const adapters = {
- ...VIEWER_ADAPTERS,
- text_inline: [...VIEWER_ADAPTERS.text_inline, inlineDiscussionsAdapter],
- text_parallel: [...VIEWER_ADAPTERS.text_parallel, parallelDiscussionsAdapter],
+ text_inline: [
+ ...VIEWER_ADAPTERS.text_inline.filter((a) => a !== optionsMenuAdapter),
+ commitOptionsMenuAdaptor,
+ inlineDiscussionsAdapter,
+ ],
+ text_parallel: [
+ ...VIEWER_ADAPTERS.text_parallel.filter((a) => a !== optionsMenuAdapter),
+ commitOptionsMenuAdaptor,
+ parallelDiscussionsAdapter,
+ ],
};
diff --git a/app/assets/javascripts/rapid_diffs/app/options_menu/commit_diffs_file_options_dropdown.vue b/app/assets/javascripts/rapid_diffs/app/options_menu/commit_diffs_file_options_dropdown.vue
new file mode 100644
index 0000000000000000000000000000000000000000..d479529f5c1f5338008b9cafe1b6028630d4d7d9
--- /dev/null
+++ b/app/assets/javascripts/rapid_diffs/app/options_menu/commit_diffs_file_options_dropdown.vue
@@ -0,0 +1,81 @@
+
+
+
+
+
diff --git a/app/assets/javascripts/rapid_diffs/app/options_menu/diff_file_options_dropdown.vue b/app/assets/javascripts/rapid_diffs/app/options_menu/diff_file_options_dropdown.vue
index 69a6b32dc470f41b52f0e838c66ff0df272d2b5f..376b07e3603b192d2ea7b11ed1848da13c399f11 100644
--- a/app/assets/javascripts/rapid_diffs/app/options_menu/diff_file_options_dropdown.vue
+++ b/app/assets/javascripts/rapid_diffs/app/options_menu/diff_file_options_dropdown.vue
@@ -1,16 +1,31 @@
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/assets/javascripts/rapid_diffs/stores/diff_discussions.js b/app/assets/javascripts/rapid_diffs/stores/diff_discussions.js
index 6d2fe158607ee9f31a1b174b8e505ae5366eb5e6..58502ac995dd8bc7dea9aee2d5fe1a4341ca6319 100644
--- a/app/assets/javascripts/rapid_diffs/stores/diff_discussions.js
+++ b/app/assets/javascripts/rapid_diffs/stores/diff_discussions.js
@@ -9,6 +9,7 @@ function addReactiveDiscussionProps(discussion) {
notes: discussion.notes.map((note) => {
return Object.assign(note, { isEditing: false, editedNote: null });
}),
+ hidden: false,
});
}
@@ -128,6 +129,19 @@ export const useDiffDiscussions = defineStore('diffDiscussions', {
});
}
},
+ toggleFileDiscussions(oldPath, newPath, newState) {
+ const matchingDiscussions = this.discussions.filter((discussion) => {
+ return (
+ discussion.diff_discussion &&
+ discussion.position?.old_path === oldPath &&
+ discussion.position?.new_path === newPath
+ );
+ });
+
+ matchingDiscussions.forEach((discussion) => {
+ discussion.hidden = newState;
+ });
+ },
/* eslint-enable no-param-reassign */
},
getters: {
@@ -154,5 +168,17 @@ export const useDiffDiscussions = defineStore('diffDiscussions', {
});
};
},
+ findDiscussionsForFile() {
+ return ({ oldPath, newPath }) => {
+ return this.discussions.filter((discussion) => {
+ return (
+ !discussion.isForm &&
+ discussion.diff_discussion &&
+ discussion.position?.old_path === oldPath &&
+ discussion.position?.new_path === newPath
+ );
+ });
+ };
+ },
},
});
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index c410cd6e75a73e21d51f6381c258f261caa488e3..55ca1db954f582a1c665eb3b1a349196a287dc9f 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -54707,6 +54707,9 @@ msgstr ""
msgid "RapidDiffs|File moved from %{old} to %{new}"
msgstr ""
+msgid "RapidDiffs|Hide comments on this file"
+msgstr ""
+
msgid "RapidDiffs|Line %d"
msgstr ""
@@ -54727,6 +54730,9 @@ msgstr[1] ""
msgid "RapidDiffs|Removed line %d"
msgstr ""
+msgid "RapidDiffs|Show comments on this file"
+msgstr ""
+
msgid "RapidDiffs|Show hidden lines"
msgstr ""
diff --git a/spec/frontend/rapid_diffs/adapters/discussions_spec.js b/spec/frontend/rapid_diffs/adapters/discussions_spec.js
index 77b41e416a501110e600186263790c68bd715df6..02bda914e6c5ad14e91eec8392ecc656a1620341 100644
--- a/spec/frontend/rapid_diffs/adapters/discussions_spec.js
+++ b/spec/frontend/rapid_diffs/adapters/discussions_spec.js
@@ -157,6 +157,20 @@ describe('discussions adapters', () => {
).toStrictEqual('Commit');
});
+ it('does not render hidden discussions', async () => {
+ const discussionId = 'hidden-discussion';
+ useDiffDiscussions().discussions = [
+ {
+ id: discussionId,
+ diff_discussion: true,
+ position: { old_path: oldPath, new_path: newPath, old_line: 1, new_line: null },
+ hidden: true,
+ },
+ ];
+ await nextTick();
+ expect(getDiffFile().querySelector('[data-discussion-id]')).toBeNull();
+ });
+
it('does not render discussions for different paths', async () => {
useDiffDiscussions().discussions = [
{
@@ -201,6 +215,31 @@ describe('discussions adapters', () => {
await nextTick();
expect(document.querySelector('[data-new-discussion-form]')).not.toBeNull();
});
+
+ it('shows all discussions for the file when creating a new discussion', async () => {
+ const store = useDiffDiscussions();
+ store.discussions = [
+ {
+ id: 'hidden-discussion',
+ diff_discussion: true,
+ position: { old_path: oldPath, new_path: newPath, old_line: 1, new_line: null },
+ hidden: true,
+ },
+ ];
+ await nextTick();
+
+ jest.spyOn(store, 'toggleFileDiscussions');
+
+ let event;
+ const button = getDiffFile().querySelector('[data-click="newDiscussion"]');
+ button.addEventListener('click', (e) => {
+ event = e;
+ });
+ button.click();
+ getDiffFile().onClick(event);
+
+ expect(store.toggleFileDiscussions).toHaveBeenCalledWith(oldPath, newPath, false);
+ });
});
describe('parallelDiscussionsAdapter', () => {
@@ -333,6 +372,20 @@ describe('discussions adapters', () => {
);
});
+ it('does not render hidden discussions', async () => {
+ const discussionId = 'hidden-discussion';
+ useDiffDiscussions().discussions = [
+ {
+ id: discussionId,
+ diff_discussion: true,
+ position: { old_path: oldPath, new_path: newPath, old_line: 1, new_line: null },
+ hidden: true,
+ },
+ ];
+ await nextTick();
+ expect(getDiffFile().querySelector('[data-discussion-id]')).toBeNull();
+ });
+
it('does not render discussions for different paths', async () => {
useDiffDiscussions().discussions = [
{
@@ -377,5 +430,30 @@ describe('discussions adapters', () => {
await nextTick();
expect(document.querySelector('[data-new-discussion-form]')).not.toBeNull();
});
+
+ it('shows all discussions for the file when creating a new discussion', async () => {
+ const store = useDiffDiscussions();
+ store.discussions = [
+ {
+ id: 'hidden-discussion',
+ diff_discussion: true,
+ position: { old_path: oldPath, new_path: newPath, old_line: null, new_line: 2 },
+ hidden: true,
+ },
+ ];
+ await nextTick();
+
+ jest.spyOn(store, 'toggleFileDiscussions');
+
+ let event;
+ const button = getDiffFile().querySelector('[data-click="newDiscussion"]');
+ button.addEventListener('click', (e) => {
+ event = e;
+ });
+ button.click();
+ getDiffFile().onClick(event);
+
+ expect(store.toggleFileDiscussions).toHaveBeenCalledWith(oldPath, newPath, false);
+ });
});
});
diff --git a/spec/frontend/rapid_diffs/adapters/options_menu_spec.js b/spec/frontend/rapid_diffs/adapters/options_menu_spec.js
index 1540e71f47e48db92a0677d29451bb3765180eae..6204248fdeae58a31c29d71fb9f9f2c6943368ca 100644
--- a/spec/frontend/rapid_diffs/adapters/options_menu_spec.js
+++ b/spec/frontend/rapid_diffs/adapters/options_menu_spec.js
@@ -1,8 +1,12 @@
+import { setActivePinia } from 'pinia';
import { DiffFile } from '~/rapid_diffs/web_components/diff_file';
-import { optionsMenuAdapter } from '~/rapid_diffs/adapters/options_menu';
+import { optionsMenuAdapter, commitOptionsMenuAdaptor } from '~/rapid_diffs/adapters/options_menu';
+import { pinia } from '~/pinia/instance';
describe('Diff File Options Menu', () => {
- const item1 = { text: 'item 1', path: 'item/1/path' };
+ const item1 = { text: 'item 1', href: 'item/1/path' };
+ const oldPath = 'old/file.js';
+ const newPath = 'new/file.js';
function get(element) {
const elements = {
@@ -30,16 +34,16 @@ describe('Diff File Options Menu', () => {
get('file').onClick(event);
};
- const mount = () => {
+ const mount = (adapter = optionsMenuAdapter) => {
const viewer = 'any';
document.body.innerHTML = `
-
+