ui/lib/pipeline/addon/components/log-view/component.js

163 lines
4.0 KiB
JavaScript

import Component from '@ember/component';
import { next } from '@ember/runloop';
import { set, get, observer } from '@ember/object';
import ThrottledResize from 'shared/mixins/throttled-resize';
import C from 'shared/utils/pipeline-constants';
import { inject as service } from '@ember/service';
import $ from 'jquery';
export default Component.extend(ThrottledResize, {
scope: service(),
intl: service(),
logIndex: null,
classNames: 'pipeline-log',
status: 'connecting',
fullscreen: false,
socket: null,
logHeight: 300,
content: null,
clean: null,
init() {
this._super(...arguments);
next(() => {
this.selectedDidChange();
});
},
willDestroyElement() {
this.disconnect();
this._super();
},
actions: {
scrollToBottom() {
$('.anchor-bottom')[0].scrollIntoView(false);
},
scrollToTop() {
$('.anchor-top')[0].scrollIntoView(true);
},
toggleLogMode() {
if (this.toggleLogMode) {
this.toggleLogMode();
}
set(this, 'fullscreen', !get(this, 'fullscreen'));
}
},
selectedDidChange: observer('logIndex.{stageIndex,stepIndex}', function() {
this.disconnect();
this.connect();
}),
getDefaultLog() {
const intl = get(this, 'intl');
const stageIndex = get(this, 'logIndex.stageIndex');
let defaultMessage = intl.t('buildDetailPage.log.waiting');
const condition = get(this, 'activity.conditions.firstObject');
if ( condition && condition.message ) {
defaultMessage = condition.message;
}
if ( stageIndex === -1 ) {
return defaultMessage;
}
const stepIndex = get(this, 'logIndex.stepIndex');
const stages = get(this, 'activity.stages');
const step = stages[stageIndex].steps[stepIndex];
if ( step && step.state !== C.STATES.WAITING ) {
return intl.t('buildDetailPage.log.loading');
} else {
return intl.t('buildDetailPage.log.waiting');
}
},
connect() {
var body = $('.log-body')[0];
var $body = $(body); // eslint-disable-line
$body.empty();
body.insertAdjacentHTML('beforeend', this.getDefaultLog());
set(this, 'clean', false);
const stageIndex = get(this, 'logIndex.stageIndex');
const stepIndex = get(this, 'logIndex.stepIndex');
const activity = get(this, 'activity');
if ( !activity || stageIndex === -1 || stepIndex === -1 ) {
return;
}
const scheme = window.location.protocol === 'https:' ? 'wss://' : 'ws://';
let url = `${ scheme }${ window.location.host }/v3/projects/${ get(this, 'scope.currentProject.id') }/pipelineExecutions/${ activity.id }/log?stage=${ stageIndex }&step=${ stepIndex }`;
var socket = new WebSocket(url);
set(this, 'socket', socket);
set(this, 'status', 'initializing');
socket.onopen = () => {
set(this, 'status', 'connected');
};
socket.onmessage = (message) => {
if ( !get(this, 'clean') ) {
set(this, 'clean', true);
$body.empty();
}
const isFollow = (window.innerHeight + window.scrollY) >= ( document.body.offsetHeight - 200);
set(this, 'status', 'connected');
body.insertAdjacentHTML('beforeend', message.data);
if (isFollow) {
next(() => {
this.send('scrollToBottom');
});
}
};
socket.onclose = () => {
if (this.isDestroyed || this.isDestroying) {
return;
}
set(this, 'status', 'disconnected');
};
},
disconnect() {
set(this, 'status', 'closed');
var socket = get(this, 'socket');
if (socket) {
socket.close();
set(this, 'socket', null);
}
},
onResize() {
const amount = get(this, 'activity.amount')
$('.log-body').css('min-height', Math.max(($(window).height() - get(this, 'logHeight'))) + 'px'); // eslint-disable-line
if (amount) {
$('.log-body').css('min-height', `${ (amount.countStep + amount.countStage) * 82 }px`);
}
},
toggleLogMode() {
throw new Error('toggleLogMode action is required!');
}
});