gitlab-org--gitlab-foss/app/assets/javascripts/mr_popover/index.js

67 lines
2 KiB
JavaScript

import Vue from 'vue';
import VueApollo from 'vue-apollo';
import MRPopover from './components/mr_popover.vue';
import createDefaultClient from '~/lib/graphql';
let renderedPopover;
let renderFn;
const handleUserPopoverMouseOut = ({ target }) => {
target.removeEventListener('mouseleave', handleUserPopoverMouseOut);
if (renderFn) {
clearTimeout(renderFn);
}
if (renderedPopover) {
renderedPopover.$destroy();
renderedPopover = null;
}
};
/**
* Adds a MergeRequestPopover component to the body, hands over as much data as the target element has in data attributes.
* loads based on data-project-path and data-iid more data about an MR from the API and sets it on the popover
*/
const handleMRPopoverMount = ({ apolloProvider, projectPath, mrTitle, iid }) => ({ target }) => {
// Add listener to actually remove it again
target.addEventListener('mouseleave', handleUserPopoverMouseOut);
renderFn = setTimeout(() => {
const MRPopoverComponent = Vue.extend(MRPopover);
renderedPopover = new MRPopoverComponent({
propsData: {
target,
projectPath,
mergeRequestIID: iid,
mergeRequestTitle: mrTitle,
},
apolloProvider,
});
renderedPopover.$mount();
}, 200); // 200ms delay so not every mouseover triggers Popover + API Call
};
export default elements => {
const mrLinks = elements || [...document.querySelectorAll('.gfm-merge_request')];
if (mrLinks.length > 0) {
Vue.use(VueApollo);
const apolloProvider = new VueApollo({
defaultClient: createDefaultClient(),
});
const listenerAddedAttr = 'data-mr-listener-added';
mrLinks.forEach(el => {
const { projectPath, mrTitle, iid } = el.dataset;
if (!el.getAttribute(listenerAddedAttr) && projectPath && mrTitle && iid) {
el.addEventListener(
'mouseenter',
handleMRPopoverMount({ apolloProvider, projectPath, mrTitle, iid }),
);
el.setAttribute(listenerAddedAttr, true);
}
});
}
};