diff options
Diffstat (limited to 'app/assets/javascripts/build.js')
-rw-r--r-- | app/assets/javascripts/build.js | 516 |
1 files changed, 257 insertions, 259 deletions
diff --git a/app/assets/javascripts/build.js b/app/assets/javascripts/build.js index 1dfa064acfd..85a967180e1 100644 --- a/app/assets/javascripts/build.js +++ b/app/assets/javascripts/build.js @@ -5,287 +5,285 @@ consistent-return, prefer-rest-params */ import _ from 'underscore'; import { bytesToKiB } from './lib/utils/number_utils'; -window.Build = (function () { - Build.timeout = null; - Build.state = null; - - function Build(options) { - this.options = options || $('.js-build-options').data(); - - this.pageUrl = this.options.pageUrl; - this.buildStatus = this.options.buildStatus; - this.state = this.options.logState; - this.buildStage = this.options.buildStage; - this.$document = $(document); - this.logBytes = 0; - this.hasBeenScrolled = false; - - this.updateDropdown = this.updateDropdown.bind(this); - this.getBuildTrace = this.getBuildTrace.bind(this); - - this.$buildTrace = $('#build-trace'); - this.$buildRefreshAnimation = $('.js-build-refresh'); - this.$truncatedInfo = $('.js-truncated-info'); - this.$buildTraceOutput = $('.js-build-output'); - this.$topBar = $('.js-top-bar'); - - // Scroll controllers - this.$scrollTopBtn = $('.js-scroll-up'); - this.$scrollBottomBtn = $('.js-scroll-down'); - - clearTimeout(Build.timeout); - // Init breakpoint checker - this.bp = Breakpoints.get(); - - this.initSidebar(); - this.populateJobs(this.buildStage); - this.updateStageDropdownText(this.buildStage); - this.sidebarOnResize(); - - this.$document - .off('click', '.js-sidebar-build-toggle') - .on('click', '.js-sidebar-build-toggle', this.sidebarOnClick.bind(this)); - - this.$document - .off('click', '.stage-item') - .on('click', '.stage-item', this.updateDropdown); - - // add event listeners to the scroll buttons - this.$scrollTopBtn - .off('click') - .on('click', this.scrollToTop.bind(this)); - - this.$scrollBottomBtn - .off('click') - .on('click', this.scrollToBottom.bind(this)); - - this.scrollThrottled = _.throttle(this.toggleScroll.bind(this), 100); - - $(window) - .off('scroll') - .on('scroll', () => { - const contentHeight = this.$buildTraceOutput.prop('scrollHeight'); - if (contentHeight > this.windowSize) { - // means the user did not scroll, the content was updated. - this.windowSize = contentHeight; - } else { - // User scrolled - this.hasBeenScrolled = true; - this.toggleScrollAnimation(false); - } +function Build(options) { + this.options = options || $('.js-build-options').data(); + + this.pageUrl = this.options.pageUrl; + this.buildStatus = this.options.buildStatus; + this.state = this.options.logState; + this.buildStage = this.options.buildStage; + this.$document = $(document); + this.logBytes = 0; + this.hasBeenScrolled = false; + + this.updateDropdown = this.updateDropdown.bind(this); + this.getBuildTrace = this.getBuildTrace.bind(this); + + this.$buildTrace = $('#build-trace'); + this.$buildRefreshAnimation = $('.js-build-refresh'); + this.$truncatedInfo = $('.js-truncated-info'); + this.$buildTraceOutput = $('.js-build-output'); + this.$topBar = $('.js-top-bar'); + + // Scroll controllers + this.$scrollTopBtn = $('.js-scroll-up'); + this.$scrollBottomBtn = $('.js-scroll-down'); + + clearTimeout(Build.timeout); + // Init breakpoint checker + this.bp = Breakpoints.get(); + + this.initSidebar(); + this.populateJobs(this.buildStage); + this.updateStageDropdownText(this.buildStage); + this.sidebarOnResize(); + + this.$document + .off('click', '.js-sidebar-build-toggle') + .on('click', '.js-sidebar-build-toggle', this.sidebarOnClick.bind(this)); + + this.$document + .off('click', '.stage-item') + .on('click', '.stage-item', this.updateDropdown); + + // add event listeners to the scroll buttons + this.$scrollTopBtn + .off('click') + .on('click', this.scrollToTop.bind(this)); + + this.$scrollBottomBtn + .off('click') + .on('click', this.scrollToBottom.bind(this)); + + this.scrollThrottled = _.throttle(this.toggleScroll.bind(this), 100); + + $(window) + .off('scroll') + .on('scroll', () => { + const contentHeight = this.$buildTraceOutput.prop('scrollHeight'); + if (contentHeight > this.windowSize) { + // means the user did not scroll, the content was updated. + this.windowSize = contentHeight; + } else { + // User scrolled + this.hasBeenScrolled = true; + this.toggleScrollAnimation(false); + } - this.scrollThrottled(); - }); + this.scrollThrottled(); + }); - $(window) - .off('resize.build') - .on('resize.build', _.throttle(this.sidebarOnResize.bind(this), 100)); + $(window) + .off('resize.build') + .on('resize.build', _.throttle(this.sidebarOnResize.bind(this), 100)); - this.updateArtifactRemoveDate(); - this.initAffixTopArea(); + this.updateArtifactRemoveDate(); + this.initAffixTopArea(); - this.getBuildTrace(); - } + this.getBuildTrace(); +} - Build.prototype.initAffixTopArea = function () { - /** - If the browser does not support position sticky, it returns the position as static. - If the browser does support sticky, then we allow the browser to handle it, if not - then we default back to Bootstraps affix - **/ - if (this.$topBar.css('position') !== 'static') return; +Build.timeout = null; +Build.state = null; - const offsetTop = this.$buildTrace.offset().top; +Build.prototype.initAffixTopArea = function () { + /** + If the browser does not support position sticky, it returns the position as static. + If the browser does support sticky, then we allow the browser to handle it, if not + then we default back to Bootstraps affix + **/ + if (this.$topBar.css('position') !== 'static') return; - this.$topBar.affix({ - offset: { - top: offsetTop, - }, - }); - }; + const offsetTop = this.$buildTrace.offset().top; - Build.prototype.canScroll = function () { - return document.body.scrollHeight > window.innerHeight; - }; + this.$topBar.affix({ + offset: { + top: offsetTop, + }, + }); +}; - Build.prototype.toggleScroll = function () { - const currentPosition = document.body.scrollTop; - const windowHeight = window.innerHeight; +Build.prototype.canScroll = function () { + return document.body.scrollHeight > window.innerHeight; +}; - if (this.canScroll()) { - if (currentPosition > 0 && - (document.body.scrollHeight - currentPosition !== windowHeight)) { - // User is in the middle of the log +Build.prototype.toggleScroll = function () { + const currentPosition = document.body.scrollTop; + const windowHeight = window.innerHeight; - this.toggleDisableButton(this.$scrollTopBtn, false); - this.toggleDisableButton(this.$scrollBottomBtn, false); - } else if (currentPosition === 0) { - // User is at Top of Build Log + if (this.canScroll()) { + if (currentPosition > 0 && + (document.body.scrollHeight - currentPosition !== windowHeight)) { + // User is in the middle of the log - this.toggleDisableButton(this.$scrollTopBtn, true); - this.toggleDisableButton(this.$scrollBottomBtn, false); - } else if (document.body.scrollHeight - currentPosition === windowHeight) { - // User is at the bottom of the build log. + this.toggleDisableButton(this.$scrollTopBtn, false); + this.toggleDisableButton(this.$scrollBottomBtn, false); + } else if (currentPosition === 0) { + // User is at Top of Build Log - this.toggleDisableButton(this.$scrollTopBtn, false); - this.toggleDisableButton(this.$scrollBottomBtn, true); - } - } else { this.toggleDisableButton(this.$scrollTopBtn, true); + this.toggleDisableButton(this.$scrollBottomBtn, false); + } else if (document.body.scrollHeight - currentPosition === windowHeight) { + // User is at the bottom of the build log. + + this.toggleDisableButton(this.$scrollTopBtn, false); this.toggleDisableButton(this.$scrollBottomBtn, true); } - }; - - Build.prototype.scrollDown = function () { - document.body.scrollTop = document.body.scrollHeight; - }; - - Build.prototype.scrollToBottom = function () { - this.scrollDown(); - this.hasBeenScrolled = true; - this.toggleScroll(); - }; - - Build.prototype.scrollToTop = function () { - document.body.scrollTop = 0; - this.hasBeenScrolled = true; - this.toggleScroll(); - }; - - Build.prototype.toggleDisableButton = function ($button, disable) { - if (disable && $button.prop('disabled')) return; - $button.prop('disabled', disable); - }; - - Build.prototype.toggleScrollAnimation = function (toggle) { - this.$scrollBottomBtn.toggleClass('animate', toggle); - }; - - Build.prototype.initSidebar = function () { - this.$sidebar = $('.js-build-sidebar'); - this.$sidebar.niceScroll(); - }; - - Build.prototype.getBuildTrace = function () { - return $.ajax({ - url: `${this.pageUrl}/trace.json`, - data: this.state, - }) - .done((log) => { - gl.utils.setCiStatusFavicon(`${this.pageUrl}/status.json`); - - if (log.state) { - this.state = log.state; - } - - this.windowSize = this.$buildTraceOutput.prop('scrollHeight'); + } else { + this.toggleDisableButton(this.$scrollTopBtn, true); + this.toggleDisableButton(this.$scrollBottomBtn, true); + } +}; + +Build.prototype.scrollDown = function () { + document.body.scrollTop = document.body.scrollHeight; +}; + +Build.prototype.scrollToBottom = function () { + this.scrollDown(); + this.hasBeenScrolled = true; + this.toggleScroll(); +}; + +Build.prototype.scrollToTop = function () { + document.body.scrollTop = 0; + this.hasBeenScrolled = true; + this.toggleScroll(); +}; + +Build.prototype.toggleDisableButton = function ($button, disable) { + if (disable && $button.prop('disabled')) return; + $button.prop('disabled', disable); +}; + +Build.prototype.toggleScrollAnimation = function (toggle) { + this.$scrollBottomBtn.toggleClass('animate', toggle); +}; + +Build.prototype.initSidebar = function () { + this.$sidebar = $('.js-build-sidebar'); + this.$sidebar.niceScroll(); +}; + +Build.prototype.getBuildTrace = function () { + return $.ajax({ + url: `${this.pageUrl}/trace.json`, + data: this.state, + }) + .done((log) => { + gl.utils.setCiStatusFavicon(`${this.pageUrl}/status.json`); + + if (log.state) { + this.state = log.state; + } - if (log.append) { - this.$buildTraceOutput.append(log.html); - this.logBytes += log.size; - } else { - this.$buildTraceOutput.html(log.html); - this.logBytes = log.size; - } + this.windowSize = this.$buildTraceOutput.prop('scrollHeight'); - // if the incremental sum of logBytes we received is less than the total - // we need to show a message warning the user about that. - if (this.logBytes < log.total) { - // size is in bytes, we need to calculate KiB - const size = bytesToKiB(this.logBytes); - $('.js-truncated-info-size').html(`${size}`); - this.$truncatedInfo.removeClass('hidden'); - } else { - this.$truncatedInfo.addClass('hidden'); - } + if (log.append) { + this.$buildTraceOutput.append(log.html); + this.logBytes += log.size; + } else { + this.$buildTraceOutput.html(log.html); + this.logBytes = log.size; + } - if (!log.complete) { - if (!this.hasBeenScrolled) { - this.toggleScrollAnimation(true); - } else { - this.toggleScrollAnimation(false); - } + // if the incremental sum of logBytes we received is less than the total + // we need to show a message warning the user about that. + if (this.logBytes < log.total) { + // size is in bytes, we need to calculate KiB + const size = bytesToKiB(this.logBytes); + $('.js-truncated-info-size').html(`${size}`); + this.$truncatedInfo.removeClass('hidden'); + } else { + this.$truncatedInfo.addClass('hidden'); + } - Build.timeout = setTimeout(() => { - this.getBuildTrace(); - }, 4000); + if (!log.complete) { + if (!this.hasBeenScrolled) { + this.toggleScrollAnimation(true); } else { - this.$buildRefreshAnimation.remove(); this.toggleScrollAnimation(false); } - if (log.status !== this.buildStatus) { - gl.utils.visitUrl(this.pageUrl); - } - }) - .fail(() => { + Build.timeout = setTimeout(() => { + this.getBuildTrace(); + }, 4000); + } else { this.$buildRefreshAnimation.remove(); - }) - .then(() => { - if (!this.hasBeenScrolled) { - this.scrollDown(); - } - }) - .then(() => this.toggleScroll()); - }; - - Build.prototype.shouldHideSidebarForViewport = function () { - const bootstrapBreakpoint = this.bp.getBreakpointSize(); - return bootstrapBreakpoint === 'xs' || bootstrapBreakpoint === 'sm'; - }; - - Build.prototype.toggleSidebar = function (shouldHide) { - const shouldShow = typeof shouldHide === 'boolean' ? !shouldHide : undefined; - const $toggleButton = $('.js-sidebar-build-toggle-header'); - - this.$sidebar - .toggleClass('right-sidebar-expanded', shouldShow) - .toggleClass('right-sidebar-collapsed', shouldHide); - - this.$topBar - .toggleClass('sidebar-expanded', shouldShow) - .toggleClass('sidebar-collapsed', shouldHide); - - if (this.$sidebar.hasClass('right-sidebar-expanded')) { - $toggleButton.addClass('hidden'); - } else { - $toggleButton.removeClass('hidden'); - } - }; - - Build.prototype.sidebarOnResize = function () { - this.toggleSidebar(this.shouldHideSidebarForViewport()); - }; - - Build.prototype.sidebarOnClick = function () { - if (this.shouldHideSidebarForViewport()) this.toggleSidebar(); - }; - - Build.prototype.updateArtifactRemoveDate = function () { - const $date = $('.js-artifacts-remove'); - if ($date.length) { - const date = $date.text(); - return $date.text( - gl.utils.timeFor(new Date(date.replace(/([0-9]+)-([0-9]+)-([0-9]+)/g, '$1/$2/$3')), ' '), - ); - } - }; - - Build.prototype.populateJobs = function (stage) { - $('.build-job').hide(); - $(`.build-job[data-stage="${stage}"]`).show(); - }; - - Build.prototype.updateStageDropdownText = function (stage) { - $('.stage-selection').text(stage); - }; - - Build.prototype.updateDropdown = function (e) { - e.preventDefault(); - const stage = e.currentTarget.text; - this.updateStageDropdownText(stage); - this.populateJobs(stage); - }; - - return Build; -})(); + this.toggleScrollAnimation(false); + } + + if (log.status !== this.buildStatus) { + gl.utils.visitUrl(this.pageUrl); + } + }) + .fail(() => { + this.$buildRefreshAnimation.remove(); + }) + .then(() => { + if (!this.hasBeenScrolled) { + this.scrollDown(); + } + }) + .then(() => this.toggleScroll()); +}; + +Build.prototype.shouldHideSidebarForViewport = function () { + const bootstrapBreakpoint = this.bp.getBreakpointSize(); + return bootstrapBreakpoint === 'xs' || bootstrapBreakpoint === 'sm'; +}; + +Build.prototype.toggleSidebar = function (shouldHide) { + const shouldShow = typeof shouldHide === 'boolean' ? !shouldHide : undefined; + const $toggleButton = $('.js-sidebar-build-toggle-header'); + + this.$sidebar + .toggleClass('right-sidebar-expanded', shouldShow) + .toggleClass('right-sidebar-collapsed', shouldHide); + + this.$topBar + .toggleClass('sidebar-expanded', shouldShow) + .toggleClass('sidebar-collapsed', shouldHide); + + if (this.$sidebar.hasClass('right-sidebar-expanded')) { + $toggleButton.addClass('hidden'); + } else { + $toggleButton.removeClass('hidden'); + } +}; + +Build.prototype.sidebarOnResize = function () { + this.toggleSidebar(this.shouldHideSidebarForViewport()); +}; + +Build.prototype.sidebarOnClick = function () { + if (this.shouldHideSidebarForViewport()) this.toggleSidebar(); +}; + +Build.prototype.updateArtifactRemoveDate = function () { + const $date = $('.js-artifacts-remove'); + if ($date.length) { + const date = $date.text(); + return $date.text( + gl.utils.timeFor(new Date(date.replace(/([0-9]+)-([0-9]+)-([0-9]+)/g, '$1/$2/$3')), ' '), + ); + } +}; + +Build.prototype.populateJobs = function (stage) { + $('.build-job').hide(); + $(`.build-job[data-stage="${stage}"]`).show(); +}; + +Build.prototype.updateStageDropdownText = function (stage) { + $('.stage-selection').text(stage); +}; + +Build.prototype.updateDropdown = function (e) { + e.preventDefault(); + const stage = e.currentTarget.text; + this.updateStageDropdownText(stage); + this.populateJobs(stage); +}; + +window.Build = Build; |