diff options
author | Phil Hughes <me@iamphill.com> | 2018-05-31 17:28:12 +0100 |
---|---|---|
committer | Phil Hughes <me@iamphill.com> | 2018-06-06 08:33:02 +0100 |
commit | e59d9a0c09d4ab3543015a9ca8a8012dc7faad03 (patch) | |
tree | 799fa880318c2267f18a785a4a13a095be3543f0 /app/assets | |
parent | 90216b206659b78c802ef287726552275d87daf1 (diff) | |
download | gitlab-ce-e59d9a0c09d4ab3543015a9ca8a8012dc7faad03.tar.gz |
removed need for job.js
it was a super hacky implementation that just wasn't working as intended
current sitatuon is still super hacky, but getting better!
Diffstat (limited to 'app/assets')
-rw-r--r-- | app/assets/javascripts/ide/components/jobs/detail.vue | 232 | ||||
-rw-r--r-- | app/assets/javascripts/ide/stores/modules/pipelines/utils.js | 1 | ||||
-rw-r--r-- | app/assets/javascripts/job.js | 52 |
3 files changed, 193 insertions, 92 deletions
diff --git a/app/assets/javascripts/ide/components/jobs/detail.vue b/app/assets/javascripts/ide/components/jobs/detail.vue index 28d858cf793..330d2a08eec 100644 --- a/app/assets/javascripts/ide/components/jobs/detail.vue +++ b/app/assets/javascripts/ide/components/jobs/detail.vue @@ -1,33 +1,91 @@ <script> import { mapState } from 'vuex'; +import _ from 'underscore'; +import axios from '../../../lib/utils/axios_utils'; +import CiIcon from '../../../vue_shared/components/ci_icon.vue'; import tooltip from '../../../vue_shared/directives/tooltip'; import Icon from '../../../vue_shared/components/icon.vue'; -import Job from '../../../job'; + +const scrollPositions = { + top: 'top', + bottom: 'bottom', +}; export default { directives: { tooltip, }, components: { + CiIcon, Icon, }, + data() { + return { + scrollPos: scrollPositions.top, + loading: true, + }; + }, computed: { ...mapState('pipelines', ['detailJob']), rawUrl() { return `${this.detailJob.path}/raw`; }, + isScrolledToBottom() { + return this.scrollPos === scrollPositions.bottom; + }, + isScrolledToTop() { + return this.scrollPos === scrollPositions.top; + }, + jobId() { + return `#${this.detailJob.id}`; + }, }, mounted() { - this.job = new Job({ - buildStage: 'a', - buildState: this.detailJob.status.text, - pagePath: this.detailJob.path, - redirectToJob: false, - }); + this.getTrace(); }, beforeDestroy() { - this.job.destroy(); + clearTimeout(this.timeout); + }, + methods: { + scrollDown() { + this.$refs.buildTrace.scrollTo(0, this.$refs.buildTrace.scrollHeight); + }, + scrollUp() { + this.$refs.buildTrace.scrollTo(0, 0); + }, + scrollBuildLog: _.throttle(function scrollDebounce() { + const scrollTop = this.$refs.buildTrace.scrollTop; + const offsetHeight = this.$refs.buildTrace.offsetHeight; + const scrollHeight = this.$refs.buildTrace.scrollHeight; + + if (scrollTop + offsetHeight === scrollHeight) { + this.scrollPos = scrollPositions.bottom; + } else if (scrollTop === 0) { + this.scrollPos = scrollPositions.top; + } else { + this.scrollPos = ''; + } + }), + getTrace(state = null) { + return axios + .get(`${this.detailJob.path}/trace`, { + params: { + state, + }, + }) + .then(({ data }) => { + this.loading = !data.complete; + this.detailJob.output = data.append ? `${this.detailJob.output}${data.html}` : data.html; + + if (!data.complete) { + this.timeout = setTimeout(() => this.getTrace(data.state), 4000); + } + }) + .then(() => this.$nextTick()) + .then(() => this.scrollDown()); + }, }, + scrollPositions, }; </script> @@ -46,69 +104,97 @@ export default { {{ __('View jobs') }} </button> </header> - <div class="build-trace-container prepend-top-default"> - <div - v-once - class="top-bar js-top-bar" - > - <div class="controllers float-right"> - <a - v-tooltip - :title="__('Show complete raw')" - data-placement="top" - data-container="body" - class="js-raw-link-controller controllers-buttons" - :href="rawUrl" - > - <i - aria-hidden="true" - class="fa fa-file-text-o" - ></i> - </a> - <div - v-tooltip - class="controllers-buttons" - data-container="body" - data-placement="top" - :title="__('Scroll to top')" + <div + class="top-bar" + > + <div class="ide-job-details float-left"> + <ci-icon + class="append-right-4" + :status="detailJob.status" + :borderless="true" + :size="24" + /> + {{ detailJob.name }} + <a + :href="detailJob.path" + target="_blank" + class="ide-external-link prepend-left-4" + > + {{ jobId }} + <icon + name="external-link" + :size="12" + /> + </a> + </div> + <div class="controllers float-right"> + <a + v-tooltip + :title="__('Show complete raw')" + data-placement="top" + data-container="body" + class="controllers-buttons" + :href="rawUrl" + target="_blank" + > + <i + aria-hidden="true" + class="fa fa-file-text-o" + ></i> + </a> + <div + v-tooltip + class="controllers-buttons" + data-container="body" + data-placement="top" + :title="__('Scroll to top')" + > + <button + class="btn-scroll btn-transparent btn-blank" + type="button" + :disabled="isScrolledToTop" + @click="scrollUp" > - <button - class="js-scroll-up btn-scroll btn-transparent btn-blank" - disabled - type="button" - > - <icon - name="scroll_up" - /> - </button> - </div> - <div - v-tooltip - class="controllers-buttons" - data-container="body" - data-placement="top" - :title="__('Scroll to top')" + <icon + name="scroll_up" + /> + </button> + </div> + <div + v-tooltip + class="controllers-buttons" + data-container="body" + data-placement="top" + :title="__('Scroll to bottom')" + > + <button + class="btn-scroll btn-transparent btn-blank" + type="button" + :disabled="isScrolledToBottom" + @click="scrollDown" > - <button - class="js-scroll-up btn-scroll btn-transparent btn-blank" - disabled - type="button" - > - <icon - name="scroll_down" - /> - </button> - </div> + <icon + name="scroll_down" + /> + </button> </div> </div> - <pre - class="build-trace" - id="build-trace" - > - <code class="bash js-build-output"> - </code> - </pre> </div> + <pre + class="build-trace" + ref="buildTrace" + @scroll="scrollBuildLog" + > + <code + class="bash" + v-html="detailJob.output" + ></code> + <div + v-show="loading" + class="build-loader-animation" + > + </div> + </pre> </div> </template> @@ -122,4 +208,16 @@ export default { .ide-tree-header .btn { display: flex; } -</style>
\ No newline at end of file + +.ide-job-details { + display: flex; +} + +.ide-job-details .ci-status-icon { + height: 0; +} + +.build-trace { + margin-bottom: 0; +} +</style> diff --git a/app/assets/javascripts/ide/stores/modules/pipelines/utils.js b/app/assets/javascripts/ide/stores/modules/pipelines/utils.js index 4f40e8766e0..4ee030731e3 100644 --- a/app/assets/javascripts/ide/stores/modules/pipelines/utils.js +++ b/app/assets/javascripts/ide/stores/modules/pipelines/utils.js @@ -5,4 +5,5 @@ export const normalizeJob = job => ({ status: job.status, path: job.build_path, started: job.started, + output: '', }); diff --git a/app/assets/javascripts/job.js b/app/assets/javascripts/job.js index 095d2ff9942..611e8200b4d 100644 --- a/app/assets/javascripts/job.js +++ b/app/assets/javascripts/job.js @@ -22,8 +22,6 @@ export default class Job { this.$window = $(window); this.logBytes = 0; this.updateDropdown = this.updateDropdown.bind(this); - this.redirectToJob = - this.options.redirectToJob !== undefined ? this.options.redirectToJob : true; this.$buildTrace = $('#build-trace'); this.$buildRefreshAnimation = $('.js-build-refresh'); @@ -46,23 +44,31 @@ export default class Job { .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); + 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.$scrollTopBtn + .off('click') + .on('click', this.scrollToTop.bind(this)); - this.$scrollBottomBtn.off('click').on('click', this.scrollToBottom.bind(this)); + this.$scrollBottomBtn + .off('click') + .on('click', this.scrollToBottom.bind(this)); this.scrollThrottled = _.throttle(this.toggleScroll.bind(this), 100); - this.$window.off('scroll').on('scroll', () => { - if (!this.isScrolledToBottom()) { - this.toggleScrollAnimation(false); - } else if (this.isScrolledToBottom() && !this.isLogComplete) { - this.toggleScrollAnimation(true); - } - this.scrollThrottled(); - }); + this.$window + .off('scroll') + .on('scroll', () => { + if (!this.isScrolledToBottom()) { + this.toggleScrollAnimation(false); + } else if (this.isScrolledToBottom() && !this.isLogComplete) { + this.toggleScrollAnimation(true); + } + this.scrollThrottled(); + }); this.$window .off('resize.build') @@ -73,10 +79,6 @@ export default class Job { this.getBuildTrace(); } - destroy() { - clearTimeout(this.timeout); - } - initAffixTopArea() { /** If the browser does not support position sticky, it returns the position as static. @@ -100,8 +102,9 @@ export default class Job { const windowHeight = $(window).height(); if (this.canScroll()) { - if (currentPosition > 0 && scrollHeight - currentPosition !== windowHeight) { - // User is in the middle of the log + if (currentPosition > 0 && + (scrollHeight - currentPosition !== windowHeight)) { + // User is in the middle of the log this.toggleDisableButton(this.$scrollTopBtn, false); this.toggleDisableButton(this.$scrollBottomBtn, false); @@ -166,11 +169,10 @@ export default class Job { } getBuildTrace() { - return axios - .get(`${this.pagePath}/trace.json`, { - params: { state: this.state }, - }) - .then(res => { + return axios.get(`${this.pagePath}/trace.json`, { + params: { state: this.state }, + }) + .then((res) => { const log = res.data; if (!this.fetchingStatusFavicon) { @@ -220,7 +222,7 @@ export default class Job { this.toggleScrollAnimation(false); } - if (log.status !== this.buildStatus && this.redirectToJob) { + if (log.status !== this.buildStatus) { visitUrl(this.pagePath); } }) |