All files / app/assets/javascripts/mr_notes init_notes.js

0% Statements 0/23
0% Branches 0/6
0% Functions 0/8
0% Lines 0/23

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115                                                                                                                                                                                                                                     
import Vue from 'vue';
import VueApollo from 'vue-apollo';
// eslint-disable-next-line no-restricted-imports
import { mapActions, mapState, mapGetters } from 'vuex';
import { apolloProvider } from '~/graphql_shared/issuable_client';
 
import { renderGFM } from '~/behaviors/markdown/render_gfm';
import { parseBoolean } from '~/lib/utils/common_utils';
import store from '~/mr_notes/stores';
import notesEventHub from '~/notes/event_hub';
import discussionNavigator from '../notes/components/discussion_navigator.vue';
import NotesApp from '../notes/components/notes_app.vue';
import { getNotesFilterData } from '../notes/utils/get_notes_filter_data';
import initWidget from '../vue_merge_request_widget';
 
export default () => {
  requestIdleCallback(
    () => {
      renderGFM(document.getElementById('diff-notes-app'));
    },
    { timeout: 500 },
  );
 
  const el = document.getElementById('js-vue-mr-discussions');
  if (!el) {
    return;
  }
 
  Vue.use(VueApollo);
 
  const notesFilterProps = getNotesFilterData(el);
  const notesDataset = el.dataset;
 
  // eslint-disable-next-line no-new
  new Vue({
    el,
    name: 'MergeRequestDiscussions',
    components: {
      NotesApp,
    },
    store,
    apolloProvider,
    provide: {
      reportAbusePath: notesDataset.reportAbusePath,
      newCommentTemplatePaths: JSON.parse(notesDataset.newCommentTemplatePaths),
      mrFilter: true,
      newCustomEmojiPath: notesDataset.newCustomEmojiPath,
    },
    data() {
      const noteableData = JSON.parse(notesDataset.noteableData);
      noteableData.noteableType = notesDataset.noteableType;
      noteableData.targetType = notesDataset.targetType;
      noteableData.discussion_locked = parseBoolean(notesDataset.isLocked);
 
      return {
        noteableData,
        endpoints: {
          metadata: notesDataset.endpointMetadata,
        },
        notesData: JSON.parse(notesDataset.notesData),
        helpPagePath: notesDataset.helpPagePath,
      };
    },
    computed: {
      ...mapGetters(['isNotesFetched']),
      ...mapState({
        activeTab: (state) => state.page.activeTab,
      }),
      isShowTabActive() {
        return this.activeTab === 'show';
      },
    },
    watch: {
      isShowTabActive: {
        handler(newVal) {
          if (newVal) {
            initWidget();
          }
        },
        immediate: true,
      },
    },
    created() {
      this.setEndpoints(this.endpoints);
 
      if (!this.isNotesFetched) {
        notesEventHub.$emit('fetchNotesData');
      }
 
      this.fetchMrMetadata();
    },
    methods: {
      ...mapActions(['setEndpoints', 'fetchMrMetadata']),
    },
    render(createElement) {
      // NOTE: Even though `discussionNavigator` is added to the `notes-app`,
      // it adds a global key listener so it works on the diffs tab as well.
      // If we create a single Vue app for all of the MR tabs, we should move this
      // up the tree, to the root.
      return createElement(discussionNavigator, [
        createElement('notes-app', {
          props: {
            noteableData: this.noteableData,
            notesData: this.notesData,
            userData: this.currentUserData,
            shouldShow: this.isShowTabActive,
            helpPagePath: this.helpPagePath,
            ...notesFilterProps,
          },
        }),
      ]);
    },
  });
};