summaryrefslogtreecommitdiff
path: root/app/assets/javascripts
diff options
context:
space:
mode:
Diffstat (limited to 'app/assets/javascripts')
-rw-r--r--app/assets/javascripts/blob/3d_viewer/index.js147
-rw-r--r--app/assets/javascripts/blob/3d_viewer/mesh_object.js49
-rw-r--r--app/assets/javascripts/blob/pdf/index.js2
-rw-r--r--app/assets/javascripts/blob/stl_viewer.js19
-rw-r--r--app/assets/javascripts/build.js1
-rw-r--r--app/assets/javascripts/dispatcher.js2
-rw-r--r--app/assets/javascripts/droplab/plugins/ajax.js8
-rw-r--r--app/assets/javascripts/droplab/plugins/ajax_filter.js2
-rw-r--r--app/assets/javascripts/environments/components/environment_actions.js25
-rw-r--r--app/assets/javascripts/environments/components/environment_item.js1
-rw-r--r--app/assets/javascripts/filtered_search/dropdown_non_user.js7
-rw-r--r--app/assets/javascripts/filtered_search/dropdown_user.js7
-rw-r--r--app/assets/javascripts/issue_show/index.js26
-rw-r--r--app/assets/javascripts/issue_show/issue_title.js78
-rw-r--r--app/assets/javascripts/issue_show/services/index.js10
-rw-r--r--app/assets/javascripts/lib/utils/common_utils.js31
-rw-r--r--app/assets/javascripts/merge_request_widget.js7
-rw-r--r--app/assets/javascripts/pipelines.js4
-rw-r--r--app/assets/javascripts/vue_pipelines_index/components/pipelines_actions.js23
-rw-r--r--app/assets/javascripts/vue_pipelines_index/stores/pipelines_store.js4
-rw-r--r--app/assets/javascripts/vue_realtime_listener/index.js38
21 files changed, 441 insertions, 50 deletions
diff --git a/app/assets/javascripts/blob/3d_viewer/index.js b/app/assets/javascripts/blob/3d_viewer/index.js
new file mode 100644
index 00000000000..68d4ddad551
--- /dev/null
+++ b/app/assets/javascripts/blob/3d_viewer/index.js
@@ -0,0 +1,147 @@
+import * as THREE from 'three/build/three.module';
+import STLLoaderClass from 'three-stl-loader';
+import OrbitControlsClass from 'three-orbit-controls';
+import MeshObject from './mesh_object';
+
+const STLLoader = STLLoaderClass(THREE);
+const OrbitControls = OrbitControlsClass(THREE);
+
+export default class Renderer {
+ constructor(container) {
+ this.renderWrapper = this.render.bind(this);
+ this.objects = [];
+
+ this.container = container;
+ this.width = this.container.offsetWidth;
+ this.height = 500;
+
+ this.loader = new STLLoader();
+
+ this.fov = 45;
+ this.camera = new THREE.PerspectiveCamera(
+ this.fov,
+ this.width / this.height,
+ 1,
+ 1000,
+ );
+
+ this.scene = new THREE.Scene();
+
+ this.scene.add(this.camera);
+
+ // Setup the viewer
+ this.setupRenderer();
+ this.setupGrid();
+ this.setupLight();
+
+ // Setup OrbitControls
+ this.controls = new OrbitControls(
+ this.camera,
+ this.renderer.domElement,
+ );
+ this.controls.minDistance = 5;
+ this.controls.maxDistance = 30;
+ this.controls.enableKeys = false;
+
+ this.loadFile();
+ }
+
+ setupRenderer() {
+ this.renderer = new THREE.WebGLRenderer({
+ antialias: true,
+ });
+
+ this.renderer.setClearColor(0xFFFFFF);
+ this.renderer.setPixelRatio(window.devicePixelRatio);
+ this.renderer.setSize(
+ this.width,
+ this.height,
+ );
+ }
+
+ setupLight() {
+ // Point light illuminates the object
+ const pointLight = new THREE.PointLight(
+ 0xFFFFFF,
+ 2,
+ 0,
+ );
+
+ pointLight.castShadow = true;
+
+ this.camera.add(pointLight);
+
+ // Ambient light illuminates the scene
+ const ambientLight = new THREE.AmbientLight(
+ 0xFFFFFF,
+ 1,
+ );
+ this.scene.add(ambientLight);
+ }
+
+ setupGrid() {
+ this.grid = new THREE.GridHelper(
+ 20,
+ 20,
+ 0x000000,
+ 0x000000,
+ );
+
+ this.scene.add(this.grid);
+ }
+
+ loadFile() {
+ this.loader.load(this.container.dataset.endpoint, (geo) => {
+ const obj = new MeshObject(geo);
+
+ this.objects.push(obj);
+ this.scene.add(obj);
+
+ this.start();
+ this.setDefaultCameraPosition();
+ });
+ }
+
+ start() {
+ // Empty the container first
+ this.container.innerHTML = '';
+
+ // Add to DOM
+ this.container.appendChild(this.renderer.domElement);
+
+ // Make controls visible
+ this.container.parentNode.classList.remove('is-stl-loading');
+
+ this.render();
+ }
+
+ render() {
+ this.renderer.render(
+ this.scene,
+ this.camera,
+ );
+
+ requestAnimationFrame(this.renderWrapper);
+ }
+
+ changeObjectMaterials(type) {
+ this.objects.forEach((obj) => {
+ obj.changeMaterial(type);
+ });
+ }
+
+ setDefaultCameraPosition() {
+ const obj = this.objects[0];
+ const radius = (obj.geometry.boundingSphere.radius / 1.5);
+ const dist = radius / (Math.sin((this.fov * (Math.PI / 180)) / 2));
+
+ this.camera.position.set(
+ 0,
+ dist + 1,
+ dist,
+ );
+
+ this.camera.lookAt(this.grid);
+ this.controls.update();
+ }
+}
diff --git a/app/assets/javascripts/blob/3d_viewer/mesh_object.js b/app/assets/javascripts/blob/3d_viewer/mesh_object.js
new file mode 100644
index 00000000000..96758884abf
--- /dev/null
+++ b/app/assets/javascripts/blob/3d_viewer/mesh_object.js
@@ -0,0 +1,49 @@
+import {
+ Matrix4,
+ MeshLambertMaterial,
+ Mesh,
+} from 'three/build/three.module';
+
+const defaultColor = 0xE24329;
+const materials = {
+ default: new MeshLambertMaterial({
+ color: defaultColor,
+ }),
+ wireframe: new MeshLambertMaterial({
+ color: defaultColor,
+ wireframe: true,
+ }),
+};
+
+export default class MeshObject extends Mesh {
+ constructor(geo) {
+ super(
+ geo,
+ materials.default,
+ );
+
+ this.geometry.computeBoundingSphere();
+
+ this.rotation.set(-Math.PI / 2, 0, 0);
+
+ if (this.geometry.boundingSphere.radius > 4) {
+ const scale = 4 / this.geometry.boundingSphere.radius;
+
+ this.geometry.applyMatrix(
+ new Matrix4().makeScale(
+ scale,
+ scale,
+ scale,
+ ),
+ );
+ this.geometry.computeBoundingSphere();
+
+ this.position.x = -this.geometry.boundingSphere.center.x;
+ this.position.z = this.geometry.boundingSphere.center.y;
+ }
+ }
+
+ changeMaterial(type) {
+ this.material = materials[type];
+ }
+}
diff --git a/app/assets/javascripts/blob/pdf/index.js b/app/assets/javascripts/blob/pdf/index.js
index 5b79717d1e1..a74c2db9a61 100644
--- a/app/assets/javascripts/blob/pdf/index.js
+++ b/app/assets/javascripts/blob/pdf/index.js
@@ -10,7 +10,7 @@ Vue.use(PDFLab, {
export default () => {
const el = document.getElementById('js-pdf-viewer');
- new Vue({
+ return new Vue({
el,
data() {
return {
diff --git a/app/assets/javascripts/blob/stl_viewer.js b/app/assets/javascripts/blob/stl_viewer.js
new file mode 100644
index 00000000000..f611c4fe640
--- /dev/null
+++ b/app/assets/javascripts/blob/stl_viewer.js
@@ -0,0 +1,19 @@
+import Renderer from './3d_viewer';
+
+document.addEventListener('DOMContentLoaded', () => {
+ const viewer = new Renderer(document.getElementById('js-stl-viewer'));
+
+ [].slice.call(document.querySelectorAll('.js-material-changer')).forEach((el) => {
+ el.addEventListener('click', (e) => {
+ const target = e.target;
+
+ e.preventDefault();
+
+ document.querySelector('.js-material-changer.active').classList.remove('active');
+ target.classList.add('active');
+ target.blur();
+
+ viewer.changeObjectMaterials(target.dataset.type);
+ });
+ });
+});
diff --git a/app/assets/javascripts/build.js b/app/assets/javascripts/build.js
index 6efd26ccc37..fe54ecffdfe 100644
--- a/app/assets/javascripts/build.js
+++ b/app/assets/javascripts/build.js
@@ -88,6 +88,7 @@ window.Build = (function() {
dataType: 'json',
success: function(buildData) {
$('.js-build-output').html(buildData.trace_html);
+ gl.utils.setCiStatusFavicon(`${this.pageUrl}/status.json`);
if (window.location.hash === DOWN_BUILD_TRACE) {
$("html,body").scrollTop(this.$buildTrace.height());
}
diff --git a/app/assets/javascripts/dispatcher.js b/app/assets/javascripts/dispatcher.js
index 80490052389..9c7acc903d1 100644
--- a/app/assets/javascripts/dispatcher.js
+++ b/app/assets/javascripts/dispatcher.js
@@ -226,9 +226,11 @@ const ShortcutsBlob = require('./shortcuts_blob');
case 'projects:pipelines:builds':
case 'projects:pipelines:show':
const { controllerAction } = document.querySelector('.js-pipeline-container').dataset;
+ const pipelineStatusUrl = `${document.querySelector('.js-pipeline-tab-link a').getAttribute('href')}/status.json`;
new gl.Pipelines({
initTabs: true,
+ pipelineStatusUrl,
tabsOptions: {
action: controllerAction,
defaultAction: 'pipelines',
diff --git a/app/assets/javascripts/droplab/plugins/ajax.js b/app/assets/javascripts/droplab/plugins/ajax.js
index f08b638fc62..12afe53ed76 100644
--- a/app/assets/javascripts/droplab/plugins/ajax.js
+++ b/app/assets/javascripts/droplab/plugins/ajax.js
@@ -1,9 +1,5 @@
/* eslint-disable */
-function droplabAjaxException(message) {
- this.message = message;
-}
-
const Ajax = {
_loadUrlData: function _loadUrlData(url) {
var self = this;
@@ -58,9 +54,7 @@ const Ajax = {
this._loadUrlData(config.endpoint)
.then(function(d) {
self._loadData(d, config, self);
- }, config.onError).catch(function(e) {
- throw new droplabAjaxException(e.message || e);
- });
+ }, config.onError).catch(config.onError);
}
},
destroy: function() {
diff --git a/app/assets/javascripts/droplab/plugins/ajax_filter.js b/app/assets/javascripts/droplab/plugins/ajax_filter.js
index 7fe221e101f..cfd7e2ca189 100644
--- a/app/assets/javascripts/droplab/plugins/ajax_filter.js
+++ b/app/assets/javascripts/droplab/plugins/ajax_filter.js
@@ -68,7 +68,7 @@ const AjaxFilter = {
this._loadUrlData(url)
.then(function(data) {
self._loadData(data, config, self);
- }, config.onError);
+ }, config.onError).catch(config.onError);
}
},
diff --git a/app/assets/javascripts/environments/components/environment_actions.js b/app/assets/javascripts/environments/components/environment_actions.js
index 385085c03e2..1418e8d86ee 100644
--- a/app/assets/javascripts/environments/components/environment_actions.js
+++ b/app/assets/javascripts/environments/components/environment_actions.js
@@ -45,11 +45,20 @@ export default {
new Flash('An error occured while making the request.');
});
},
+
+ isActionDisabled(action) {
+ if (action.playable === undefined) {
+ return false;
+ }
+
+ return !action.playable;
+ },
},
template: `
<div class="btn-group" role="group">
<button
+ type="button"
class="dropdown btn btn-default dropdown-new js-dropdown-play-icon-container has-tooltip"
data-container="body"
data-toggle="dropdown"
@@ -58,15 +67,24 @@ export default {
:disabled="isLoading">
<span>
<span v-html="playIconSvg"></span>
- <i class="fa fa-caret-down" aria-hidden="true"></i>
- <i v-if="isLoading" class="fa fa-spinner fa-spin" aria-hidden="true"></i>
+ <i
+ class="fa fa-caret-down"
+ aria-hidden="true"/>
+ <i
+ v-if="isLoading"
+ class="fa fa-spinner fa-spin"
+ aria-hidden="true"/>
</span>
+ </button>
<ul class="dropdown-menu dropdown-menu-align-right">
<li v-for="action in actions">
<button
+ type="button"
+ class="js-manual-action-link no-btn btn"
@click="onClickAction(action.play_path)"
- class="js-manual-action-link no-btn">
+ :class="{ 'disabled': isActionDisabled(action) }"
+ :disabled="isActionDisabled(action)">
${playIconSvg}
<span>
{{action.name}}
@@ -74,7 +92,6 @@ export default {
</button>
</li>
</ul>
- </button>
</div>
`,
};
diff --git a/app/assets/javascripts/environments/components/environment_item.js b/app/assets/javascripts/environments/components/environment_item.js
index e44d93a30c7..d9b49287dec 100644
--- a/app/assets/javascripts/environments/components/environment_item.js
+++ b/app/assets/javascripts/environments/components/environment_item.js
@@ -142,6 +142,7 @@ export default {
const parsedAction = {
name: gl.text.humanize(action.name),
play_path: action.play_path,
+ playable: action.playable,
};
return parsedAction;
});
diff --git a/app/assets/javascripts/filtered_search/dropdown_non_user.js b/app/assets/javascripts/filtered_search/dropdown_non_user.js
index 35c76dff79a..6296965b911 100644
--- a/app/assets/javascripts/filtered_search/dropdown_non_user.js
+++ b/app/assets/javascripts/filtered_search/dropdown_non_user.js
@@ -1,3 +1,5 @@
+/* global Flash */
+
import Ajax from '~/droplab/plugins/ajax';
import Filter from '~/droplab/plugins/filter';
@@ -13,6 +15,11 @@ require('./filtered_search_dropdown');
endpoint,
method: 'setData',
loadingTemplate: this.loadingTemplate,
+ onError() {
+ /* eslint-disable no-new */
+ new Flash('An error occured fetching the dropdown data.');
+ /* eslint-enable no-new */
+ },
},
Filter: {
filterFunction: gl.DropdownUtils.filterWithSymbol.bind(null, this.symbol, input),
diff --git a/app/assets/javascripts/filtered_search/dropdown_user.js b/app/assets/javascripts/filtered_search/dropdown_user.js
index 4f9f25c1f1b..38b5d315bcf 100644
--- a/app/assets/javascripts/filtered_search/dropdown_user.js
+++ b/app/assets/javascripts/filtered_search/dropdown_user.js
@@ -1,3 +1,5 @@
+/* global Flash */
+
import AjaxFilter from '~/droplab/plugins/ajax_filter';
require('./filtered_search_dropdown');
@@ -18,6 +20,11 @@ require('./filtered_search_dropdown');
},
searchValueFunction: this.getSearchInput.bind(this),
loadingTemplate: this.loadingTemplate,
+ onError() {
+ /* eslint-disable no-new */
+ new Flash('An error occured fetching the dropdown data.');
+ /* eslint-enable no-new */
+ },
},
};
}
diff --git a/app/assets/javascripts/issue_show/index.js b/app/assets/javascripts/issue_show/index.js
new file mode 100644
index 00000000000..b6ce8e83729
--- /dev/null
+++ b/app/assets/javascripts/issue_show/index.js
@@ -0,0 +1,26 @@
+import Vue from 'vue';
+import IssueTitle from './issue_title';
+import '../vue_shared/vue_resource_interceptor';
+
+const vueOptions = () => ({
+ el: '.issue-title-entrypoint',
+ components: {
+ IssueTitle,
+ },
+ data() {
+ const issueTitleData = document.querySelector('.issue-title-data').dataset;
+
+ return {
+ initialTitle: issueTitleData.initialTitle,
+ endpoint: issueTitleData.endpoint,
+ };
+ },
+ template: `
+ <IssueTitle
+ :initialTitle="initialTitle"
+ :endpoint="endpoint"
+ />
+ `,
+});
+
+(() => new Vue(vueOptions()))();
diff --git a/app/assets/javascripts/issue_show/issue_title.js b/app/assets/javascripts/issue_show/issue_title.js
new file mode 100644
index 00000000000..1184c8956dc
--- /dev/null
+++ b/app/assets/javascripts/issue_show/issue_title.js
@@ -0,0 +1,78 @@
+import Visibility from 'visibilityjs';
+import Poll from './../lib/utils/poll';
+import Service from './services/index';
+
+export default {
+ props: {
+ initialTitle: { required: true, type: String },
+ endpoint: { required: true, type: String },
+ },
+ data() {
+ const resource = new Service(this.$http, this.endpoint);
+
+ const poll = new Poll({
+ resource,
+ method: 'getTitle',
+ successCallback: (res) => {
+ this.renderResponse(res);
+ },
+ errorCallback: (err) => {
+ if (process.env.NODE_ENV !== 'production') {
+ // eslint-disable-next-line no-console
+ console.error('ISSUE SHOW TITLE REALTIME ERROR', err);
+ } else {
+ throw new Error(err);
+ }
+ },
+ });
+
+ return {
+ poll,
+ timeoutId: null,
+ title: this.initialTitle,
+ };
+ },
+ methods: {
+ fetch() {
+ this.poll.makeRequest();
+
+ Visibility.change(() => {
+ if (!Visibility.hidden()) {
+ this.poll.restart();
+ } else {
+ this.poll.stop();
+ }
+ });
+ },
+ renderResponse(res) {
+ const body = JSON.parse(res.body);
+ this.triggerAnimation(body);
+ },
+ triggerAnimation(body) {
+ const { title } = body;
+
+ /**
+ * since opacity is changed, even if there is no diff for Vue to update
+ * we must check the title even on a 304 to ensure no visual change
+ */
+ if (this.title === title) return;
+
+ this.$el.style.opacity = 0;
+
+ this.timeoutId = setTimeout(() => {
+ this.title = title;
+
+ this.$el.style.transition = 'opacity 0.2s ease';
+ this.$el.style.opacity = 1;
+
+ clearTimeout(this.timeoutId);
+ }, 100);
+ },
+ },
+ created() {
+ this.fetch();
+ },
+ template: `
+ <h2 class='title' v-html='title'></h2>
+ `,
+};
diff --git a/app/assets/javascripts/issue_show/services/index.js b/app/assets/javascripts/issue_show/services/index.js
new file mode 100644
index 00000000000..c4ab0b1e07a
--- /dev/null
+++ b/app/assets/javascripts/issue_show/services/index.js
@@ -0,0 +1,10 @@
+export default class Service {
+ constructor(resource, endpoint) {
+ this.resource = resource;
+ this.endpoint = endpoint;
+ }
+
+ getTitle() {
+ return this.resource.get(this.endpoint);
+ }
+}
diff --git a/app/assets/javascripts/lib/utils/common_utils.js b/app/assets/javascripts/lib/utils/common_utils.js
index 46b80c04e20..e1e6ca25446 100644
--- a/app/assets/javascripts/lib/utils/common_utils.js
+++ b/app/assets/javascripts/lib/utils/common_utils.js
@@ -2,6 +2,8 @@
(function() {
(function(w) {
var base;
+ const faviconEl = document.getElementById('favicon');
+ const originalFavicon = faviconEl ? faviconEl.getAttribute('href') : null;
w.gl || (w.gl = {});
(base = w.gl).utils || (base.utils = {});
w.gl.utils.isInGroupsPage = function() {
@@ -361,5 +363,34 @@
fn(next, stop);
});
};
+
+ w.gl.utils.setFavicon = (iconName) => {
+ if (faviconEl && iconName) {
+ faviconEl.setAttribute('href', `/assets/${iconName}.ico`);
+ }
+ };
+
+ w.gl.utils.resetFavicon = () => {
+ if (faviconEl) {
+ faviconEl.setAttribute('href', originalFavicon);
+ }
+ };
+
+ w.gl.utils.setCiStatusFavicon = (pageUrl) => {
+ $.ajax({
+ url: pageUrl,
+ dataType: 'json',
+ success: function(data) {
+ if (data && data.icon) {
+ gl.utils.setFavicon(`ci_favicons/${data.icon}`);
+ } else {
+ gl.utils.resetFavicon();
+ }
+ },
+ error: function() {
+ gl.utils.resetFavicon();
+ }
+ });
+ };
})(window);
}).call(window);
diff --git a/app/assets/javascripts/merge_request_widget.js b/app/assets/javascripts/merge_request_widget.js
index 0e2af3df071..b0254b17dd2 100644
--- a/app/assets/javascripts/merge_request_widget.js
+++ b/app/assets/javascripts/merge_request_widget.js
@@ -38,11 +38,13 @@ import MiniPipelineGraph from './mini_pipeline_graph_dropdown';
function MergeRequestWidget(opts) {
// Initialize MergeRequestWidget behavior
//
- // check_enable - Boolean, whether to check automerge status
- // merge_check_url - String, URL to use to check automerge status
+ // check_enable - Boolean, whether to check automerge status
+ // merge_check_url - String, URL to use to check automerge status
// ci_status_url - String, URL to use to check CI status
+ // pipeline_status_url - String, URL to use to get CI status for Favicon
//
this.opts = opts;
+ this.opts.pipeline_status_url = `${this.opts.pipeline_status_url}.json`;
this.$widgetBody = $('.mr-widget-body');
$('#modal_merge_info').modal({
show: false
@@ -159,6 +161,7 @@ import MiniPipelineGraph from './mini_pipeline_graph_dropdown';
_this.status = data.status;
_this.hasCi = data.has_ci;
_this.updateMergeButton(_this.status, _this.hasCi);
+ gl.utils.setCiStatusFavicon(_this.opts.pipeline_status_url);
if (data.environments && data.environments.length) _this.renderEnvironments(data.environments);
if (data.status !== _this.opts.ci_status ||
data.sha !== _this.opts.ci_sha ||
diff --git a/app/assets/javascripts/pipelines.js b/app/assets/javascripts/pipelines.js
index 9203abefbbc..4252b615887 100644
--- a/app/assets/javascripts/pipelines.js
+++ b/app/assets/javascripts/pipelines.js
@@ -9,6 +9,10 @@ require('./lib/utils/bootstrap_linked_tabs');
new global.LinkedTabs(options.tabsOptions);
}
+ if (options.pipelineStatusUrl) {
+ gl.utils.setCiStatusFavicon(options.pipelineStatusUrl);
+ }
+
this.addMarginToBuildColumns();
}
diff --git a/app/assets/javascripts/vue_pipelines_index/components/pipelines_actions.js b/app/assets/javascripts/vue_pipelines_index/components/pipelines_actions.js
index 4bb2b048884..12d80768646 100644
--- a/app/assets/javascripts/vue_pipelines_index/components/pipelines_actions.js
+++ b/app/assets/javascripts/vue_pipelines_index/components/pipelines_actions.js
@@ -38,6 +38,14 @@ export default {
new Flash('An error occured while making the request.');
});
},
+
+ isActionDisabled(action) {
+ if (action.playable === undefined) {
+ return false;
+ }
+
+ return !action.playable;
+ },
},
template: `
@@ -51,16 +59,23 @@ export default {
aria-label="Manual job"
:disabled="isLoading">
${playIconSvg}
- <i class="fa fa-caret-down" aria-hidden="true"></i>
- <i v-if="isLoading" class="fa fa-spinner fa-spin" aria-hidden="true"></i>
+ <i
+ class="fa fa-caret-down"
+ aria-hidden="true" />
+ <i
+ v-if="isLoading"
+ class="fa fa-spinner fa-spin"
+ aria-hidden="true" />
</button>
<ul class="dropdown-menu dropdown-menu-align-right">
<li v-for="action in actions">
<button
type="button"
- class="js-pipeline-action-link no-btn"
- @click="onClickAction(action.path)">
+ class="js-pipeline-action-link no-btn btn"
+ @click="onClickAction(action.path)"
+ :class="{ 'disabled': isActionDisabled(action) }"
+ :disabled="isActionDisabled(action)">
${playIconSvg}
<span>{{action.name}}</span>
</button>
diff --git a/app/assets/javascripts/vue_pipelines_index/stores/pipelines_store.js b/app/assets/javascripts/vue_pipelines_index/stores/pipelines_store.js
index 7ac10086a55..377ec8ba2cc 100644
--- a/app/assets/javascripts/vue_pipelines_index/stores/pipelines_store.js
+++ b/app/assets/javascripts/vue_pipelines_index/stores/pipelines_store.js
@@ -1,5 +1,5 @@
/* eslint-disable no-underscore-dangle*/
-import '../../vue_realtime_listener';
+import VueRealtimeListener from '../../vue_realtime_listener';
export default class PipelinesStore {
constructor() {
@@ -56,6 +56,6 @@ export default class PipelinesStore {
const removeIntervals = () => clearInterval(this.timeLoopInterval);
const startIntervals = () => startTimeLoops();
- gl.VueRealtimeListener(removeIntervals, startIntervals);
+ VueRealtimeListener(removeIntervals, startIntervals);
}
}
diff --git a/app/assets/javascripts/vue_realtime_listener/index.js b/app/assets/javascripts/vue_realtime_listener/index.js
index 30f6680a673..4ddb2f975b0 100644
--- a/app/assets/javascripts/vue_realtime_listener/index.js
+++ b/app/assets/javascripts/vue_realtime_listener/index.js
@@ -1,29 +1,9 @@
-/* eslint-disable no-param-reassign */
-
-((gl) => {
- gl.VueRealtimeListener = (removeIntervals, startIntervals) => {
- const removeAll = () => {
- removeIntervals();
- window.removeEventListener('beforeunload', removeIntervals);
- window.removeEventListener('focus', startIntervals);
- window.removeEventListener('blur', removeIntervals);
- document.removeEventListener('beforeunload', removeAll);
- };
-
- window.addEventListener('beforeunload', removeIntervals);
- window.addEventListener('focus', startIntervals);
- window.addEventListener('blur', removeIntervals);
- document.addEventListener('beforeunload', removeAll);
-
- // add removeAll methods to stack
- const stack = gl.VueRealtimeListener.reset;
- gl.VueRealtimeListener.reset = () => {
- gl.VueRealtimeListener.reset = stack;
- removeAll();
- stack();
- };
- };
-
- // remove all event listeners and intervals
- gl.VueRealtimeListener.reset = () => undefined; // noop
-})(window.gl || (window.gl = {}));
+export default (removeIntervals, startIntervals) => {
+ window.removeEventListener('focus', startIntervals);
+ window.removeEventListener('blur', removeIntervals);
+ window.removeEventListener('onbeforeload', removeIntervals);
+
+ window.addEventListener('focus', startIntervals);
+ window.addEventListener('blur', removeIntervals);
+ window.addEventListener('onbeforeload', removeIntervals);
+};