Commit beeefcf1 authored by Tomas Vik (OOO back on 2026-08-31)'s avatar Tomas Vik (OOO back on 2026-08-31) 🌴
Browse files

feat: render suggestions in MR webview

parent 31787465
Loading
Loading
Loading
Loading
+50 −0
Original line number Diff line number Diff line
import { mount } from '@vue/test-utils';
import Note from './Note';

const {
  noteOnDiffWithSuggestion,
} = require('../../../../test/integration/fixtures/graphql/discussions');

describe('Note', () => {
  let wrapper;
  const tooltipDirective = jest.fn();

  beforeEach(() => {
    tooltipDirective.mockReset();
    window.vsCodeApi = { postMessage: jest.fn() };
  });
  describe('initializes suggestions', () => {
    beforeEach(() => {
      wrapper = mount(Note, {
        propsData: {
          noteable: noteOnDiffWithSuggestion,
        },
        stubs: {
          date: true,
        },
        directives: {
          tooltip: tooltipDirective,
        },
      });
    });

    it('contains two initialized suggestions', () => {
      expect(wrapper.findAll('.suggestion').length).toBe(2);
    });

    it('suggestion header', () => {
      const suggestionHeader = wrapper.find('.suggestion .header');
      expect(suggestionHeader.text()).toMatch(/Suggested change:\s+open on the web/);
    });

    it('opens suggestion on the web', () => {
      const openOnTheWebLink = wrapper.find('.suggestion .header a');
      expect(openOnTheWebLink.attributes('href')).toBe(noteOnDiffWithSuggestion.url);
    });

    it('wraps original suggestion', () => {
      const firstSuggestedLine = wrapper.find('.suggestion .line');
      expect(firstSuggestedLine.text()).toBe('function anotherFunction1(): void{');
    });
  });
});
+52 −8
Original line number Diff line number Diff line
@@ -23,6 +23,29 @@ export default {
      return this.noteable.author;
    },
  },
  mounted() {
    this.initializeSuggestions();
  },
  methods: {
    initializeSuggestions() {
      const suggestions = this.$el.querySelectorAll('pre.language-suggestion');
      suggestions.forEach(suggestionEl => {
        const initializedSuggestionHtml = `
          <div class="suggestion">
            <div class="header">
              <strong>Suggested change:</strong>
              <emphasis><a href="${this.noteable.url}">open on the web</a></emphasis>
            </div>
            ${suggestionEl.outerHTML}
          </div>
          `;
        const initializedSuggestionEl = document.createElement('div');
        initializedSuggestionEl.innerHTML = initializedSuggestionHtml;
        suggestionEl.parentNode.insertBefore(initializedSuggestionEl, suggestionEl);
        suggestionEl.remove();
      });
    },
  },
};
</script>

@@ -54,19 +77,13 @@ export default {
  margin: 16px 0;
  box-sizing: border-box;
  display: block;
  position: relative;

  .timeline-entry-inner {
    position: relative;
  }

  .timelineIcon {
    float: left;
    position: relative;
    display: flex;
  }

  .timelineContent {
    position: relative;
    width: 100%;
  }

  .note-header {
@@ -119,5 +136,32 @@ export default {
    vertical-align: middle;
    box-sizing: border-box;
  }

  .suggestion {
    border: 1px solid;
    border-radius: 4px;
    border-color: var(--vscode-panel-border);
    margin-top: 1em;
    margin-bottom: 1em;
    .header {
      padding: 16px;
      background-color: var(--vscode-input-background);
      display: flex;
      justify-content: space-between;
    }
  }

  pre.language-suggestion {
    margin: 0;
    padding: 16px;
    code {
      display: flex;
      flex-direction: column;
      color: var(--vscode-gitDecoration-addedResourceForeground);
    }
    .line::before {
      content: '+ ';
    }
  }
}
</style>
+36 −0
Original line number Diff line number Diff line
@@ -115,6 +115,41 @@ const noteOnDiff = {
  },
};

const noteOnDiffWithSuggestion = {
  id: 'gid://gitlab/DiffNote/771043162',
  createdAt: '2021-12-13T13:13:06Z',
  system: false,
  author: {
    avatarUrl:
      'https://secure.gravatar.com/avatar/6042a9152ada74d9fb6a0cdce895337e?s=80&d=identicon',
    name: 'Tomas Vik',
    username: 'viktomas',
    webUrl: 'https://gitlab.com/viktomas',
  },
  body: '```suggestion:-0+0\nfunction anotherFunction1(): void{\n```\n\n```suggestion:-0+0\nfunction anotherFunction2(): void{\n```',
  bodyHtml:
    '<pre data-sourcepos="1:1-3:3" class="code highlight js-syntax-highlight language-suggestion" lang="suggestion" data-lang-params="-0+0" v-pre="true"><code class="js-render-suggestion"><span id="LC1" class="line" lang="suggestion">function anotherFunction1(): void{</span></code></pre>&#x000A;<pre data-sourcepos="5:1-7:3" class="code highlight js-syntax-highlight language-suggestion" lang="suggestion" data-lang-params="-0+0" v-pre="true"><code class="js-render-suggestion"><span id="LC1" class="line" lang="suggestion">function anotherFunction2(): void{</span></code></pre>',
  url: 'https://gitlab.com/viktomas/test-project/-/merge_requests/7#note_771043162',
  userPermissions: {
    resolveNote: true,
    adminNote: true,
    createNote: true,
  },
  position: {
    diffRefs: {
      baseSha: '5e6dffa282c5129aa67cd227a0429be21bfdaf80',
      headSha: 'f9ce7e16e56c162edbc9e480108041cf6b0291fe',
      startSha: '5e6dffa282c5129aa67cd227a0429be21bfdaf80',
    },
    filePath: 'test.ts',
    positionType: 'text',
    newLine: 24,
    oldLine: null,
    newPath: 'test.ts',
    oldPath: 'test.js',
  },
};

const noteOnDiffTextSnippet =
  'For labels, we can easily render the HTML ourselves, saving all the API requests';

@@ -199,6 +234,7 @@ module.exports = {
  note2TextSnippet,
  noteOnDiff,
  noteOnDiffTextSnippet,
  noteOnDiffWithSuggestion,
  singleNote,
  multipleNotes,
  discussionOnDiff,