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
|
import Vue from 'vue';
import VueApollo from 'vue-apollo';
import createDefaultClient from '~/lib/graphql';
import IssuePopover from './components/issue_popover.vue';
import MRPopover from './components/mr_popover.vue';
const componentsByReferenceType = {
issue: IssuePopover,
merge_request: MRPopover,
};
let renderFn;
const handleIssuablePopoverMouseOut = ({ target }) => {
target.removeEventListener('mouseleave', handleIssuablePopoverMouseOut);
if (renderFn) {
clearTimeout(renderFn);
}
};
const popoverMountedAttr = 'data-popover-mounted';
/**
* 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 handleIssuablePopoverMount = ({
apolloProvider,
projectPath,
title,
iid,
referenceType,
target,
}) => {
// Add listener to actually remove it again
target.addEventListener('mouseleave', handleIssuablePopoverMouseOut);
renderFn = setTimeout(() => {
const PopoverComponent = Vue.extend(componentsByReferenceType[referenceType]);
new PopoverComponent({
propsData: {
target,
projectPath,
iid,
cachedTitle: title,
},
apolloProvider,
}).$mount();
target.setAttribute(popoverMountedAttr, true);
}, 200); // 200ms delay so not every mouseover triggers Popover + API Call
};
export default (elements) => {
if (elements.length > 0) {
Vue.use(VueApollo);
const apolloProvider = new VueApollo({
defaultClient: createDefaultClient(),
});
const listenerAddedAttr = 'data-popover-listener-added';
elements.forEach((el) => {
const { projectPath, iid, referenceType } = el.dataset;
const title = el.dataset.mrTitle || el.title;
if (!el.getAttribute(listenerAddedAttr) && projectPath && title && iid && referenceType) {
el.addEventListener('mouseenter', ({ target }) => {
if (!el.getAttribute(popoverMountedAttr)) {
handleIssuablePopoverMount({
apolloProvider,
projectPath,
title,
iid,
referenceType,
target,
});
}
});
el.setAttribute(listenerAddedAttr, true);
}
});
}
};
|