summaryrefslogtreecommitdiff
path: root/app/assets
diff options
context:
space:
mode:
authorPhil Hughes <me@iamphill.com>2018-05-31 17:28:12 +0100
committerPhil Hughes <me@iamphill.com>2018-06-06 08:33:02 +0100
commite59d9a0c09d4ab3543015a9ca8a8012dc7faad03 (patch)
tree799fa880318c2267f18a785a4a13a095be3543f0 /app/assets
parent90216b206659b78c802ef287726552275d87daf1 (diff)
downloadgitlab-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.vue232
-rw-r--r--app/assets/javascripts/ide/stores/modules/pipelines/utils.js1
-rw-r--r--app/assets/javascripts/job.js52
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);
}
})