2018-11-20 20:47:30 +05:30
|
|
|
import Visibility from 'visibilityjs';
|
2021-03-11 19:13:27 +05:30
|
|
|
import { deprecatedCreateFlash as flash } from '~/flash';
|
2018-12-13 13:39:08 +05:30
|
|
|
import axios from '~/lib/utils/axios_utils';
|
2021-03-08 18:12:59 +05:30
|
|
|
import { setFaviconOverlay, resetFavicon } from '~/lib/utils/favicon';
|
2021-03-11 19:13:27 +05:30
|
|
|
import httpStatusCodes from '~/lib/utils/http_status';
|
|
|
|
import Poll from '~/lib/utils/poll';
|
2018-12-13 13:39:08 +05:30
|
|
|
import {
|
|
|
|
canScroll,
|
|
|
|
isScrolledToBottom,
|
|
|
|
isScrolledToTop,
|
|
|
|
isScrolledToMiddle,
|
|
|
|
scrollDown,
|
|
|
|
scrollUp,
|
|
|
|
} from '~/lib/utils/scroll_utils';
|
2021-03-11 19:13:27 +05:30
|
|
|
import { __ } from '~/locale';
|
|
|
|
import * as types from './mutation_types';
|
2018-11-20 20:47:30 +05:30
|
|
|
|
2020-03-13 15:44:24 +05:30
|
|
|
export const init = ({ dispatch }, { endpoint, logState, pagePath }) => {
|
|
|
|
dispatch('setJobEndpoint', endpoint);
|
|
|
|
dispatch('setTraceOptions', {
|
|
|
|
logState,
|
|
|
|
pagePath,
|
|
|
|
});
|
|
|
|
|
|
|
|
return Promise.all([dispatch('fetchJob'), dispatch('fetchTrace')]);
|
|
|
|
};
|
|
|
|
|
2018-11-20 20:47:30 +05:30
|
|
|
export const setJobEndpoint = ({ commit }, endpoint) => commit(types.SET_JOB_ENDPOINT, endpoint);
|
2018-12-13 13:39:08 +05:30
|
|
|
export const setTraceOptions = ({ commit }, options) => commit(types.SET_TRACE_OPTIONS, options);
|
|
|
|
|
|
|
|
export const hideSidebar = ({ commit }) => commit(types.HIDE_SIDEBAR);
|
|
|
|
export const showSidebar = ({ commit }) => commit(types.SHOW_SIDEBAR);
|
|
|
|
|
|
|
|
export const toggleSidebar = ({ dispatch, state }) => {
|
|
|
|
if (state.isSidebarOpen) {
|
|
|
|
dispatch('hideSidebar');
|
|
|
|
} else {
|
|
|
|
dispatch('showSidebar');
|
|
|
|
}
|
|
|
|
};
|
2018-11-20 20:47:30 +05:30
|
|
|
|
|
|
|
let eTagPoll;
|
|
|
|
|
|
|
|
export const clearEtagPoll = () => {
|
|
|
|
eTagPoll = null;
|
|
|
|
};
|
|
|
|
|
|
|
|
export const stopPolling = () => {
|
|
|
|
if (eTagPoll) eTagPoll.stop();
|
|
|
|
};
|
|
|
|
|
|
|
|
export const restartPolling = () => {
|
|
|
|
if (eTagPoll) eTagPoll.restart();
|
|
|
|
};
|
|
|
|
|
|
|
|
export const requestJob = ({ commit }) => commit(types.REQUEST_JOB);
|
|
|
|
|
|
|
|
export const fetchJob = ({ state, dispatch }) => {
|
|
|
|
dispatch('requestJob');
|
|
|
|
|
|
|
|
eTagPoll = new Poll({
|
|
|
|
resource: {
|
|
|
|
getJob(endpoint) {
|
|
|
|
return axios.get(endpoint);
|
|
|
|
},
|
|
|
|
},
|
|
|
|
data: state.jobEndpoint,
|
|
|
|
method: 'getJob',
|
|
|
|
successCallback: ({ data }) => dispatch('receiveJobSuccess', data),
|
|
|
|
errorCallback: () => dispatch('receiveJobError'),
|
|
|
|
});
|
|
|
|
|
|
|
|
if (!Visibility.hidden()) {
|
|
|
|
eTagPoll.makeRequest();
|
|
|
|
} else {
|
|
|
|
axios
|
|
|
|
.get(state.jobEndpoint)
|
|
|
|
.then(({ data }) => dispatch('receiveJobSuccess', data))
|
|
|
|
.catch(() => dispatch('receiveJobError'));
|
|
|
|
}
|
|
|
|
|
|
|
|
Visibility.change(() => {
|
|
|
|
if (!Visibility.hidden()) {
|
|
|
|
dispatch('restartPolling');
|
|
|
|
} else {
|
|
|
|
dispatch('stopPolling');
|
|
|
|
}
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
2018-12-13 13:39:08 +05:30
|
|
|
export const receiveJobSuccess = ({ commit }, data = {}) => {
|
2018-12-05 23:21:45 +05:30
|
|
|
commit(types.RECEIVE_JOB_SUCCESS, data);
|
2018-12-13 13:39:08 +05:30
|
|
|
|
|
|
|
if (data.status && data.status.favicon) {
|
|
|
|
setFaviconOverlay(data.status.favicon);
|
|
|
|
} else {
|
|
|
|
resetFavicon();
|
|
|
|
}
|
2018-12-05 23:21:45 +05:30
|
|
|
};
|
2018-11-20 20:47:30 +05:30
|
|
|
export const receiveJobError = ({ commit }) => {
|
|
|
|
commit(types.RECEIVE_JOB_ERROR);
|
|
|
|
flash(__('An error occurred while fetching the job.'));
|
2018-12-13 13:39:08 +05:30
|
|
|
resetFavicon();
|
2018-11-20 20:47:30 +05:30
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Job's Trace
|
|
|
|
*/
|
2018-12-13 13:39:08 +05:30
|
|
|
export const scrollTop = ({ dispatch }) => {
|
|
|
|
scrollUp();
|
|
|
|
dispatch('toggleScrollButtons');
|
2018-11-20 20:47:30 +05:30
|
|
|
};
|
|
|
|
|
2018-12-13 13:39:08 +05:30
|
|
|
export const scrollBottom = ({ dispatch }) => {
|
|
|
|
scrollDown();
|
|
|
|
dispatch('toggleScrollButtons');
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Responsible for toggling the disabled state of the scroll buttons
|
|
|
|
*/
|
|
|
|
export const toggleScrollButtons = ({ dispatch }) => {
|
|
|
|
if (canScroll()) {
|
|
|
|
if (isScrolledToMiddle()) {
|
|
|
|
dispatch('enableScrollTop');
|
|
|
|
dispatch('enableScrollBottom');
|
|
|
|
} else if (isScrolledToTop()) {
|
|
|
|
dispatch('disableScrollTop');
|
|
|
|
dispatch('enableScrollBottom');
|
|
|
|
} else if (isScrolledToBottom()) {
|
|
|
|
dispatch('disableScrollBottom');
|
|
|
|
dispatch('enableScrollTop');
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
dispatch('disableScrollBottom');
|
|
|
|
dispatch('disableScrollTop');
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
export const disableScrollBottom = ({ commit }) => commit(types.DISABLE_SCROLL_BOTTOM);
|
|
|
|
export const disableScrollTop = ({ commit }) => commit(types.DISABLE_SCROLL_TOP);
|
|
|
|
export const enableScrollBottom = ({ commit }) => commit(types.ENABLE_SCROLL_BOTTOM);
|
|
|
|
export const enableScrollTop = ({ commit }) => commit(types.ENABLE_SCROLL_TOP);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* While the automatic scroll down is active,
|
|
|
|
* we show the scroll down button with an animation
|
|
|
|
*/
|
|
|
|
export const toggleScrollAnimation = ({ commit }, toggle) =>
|
|
|
|
commit(types.TOGGLE_SCROLL_ANIMATION, toggle);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Responsible to handle automatic scroll
|
|
|
|
*/
|
|
|
|
export const toggleScrollisInBottom = ({ commit }, toggle) => {
|
|
|
|
commit(types.TOGGLE_IS_SCROLL_IN_BOTTOM_BEFORE_UPDATING_TRACE, toggle);
|
2018-11-20 20:47:30 +05:30
|
|
|
};
|
|
|
|
|
|
|
|
export const requestTrace = ({ commit }) => commit(types.REQUEST_TRACE);
|
|
|
|
|
2018-12-13 13:39:08 +05:30
|
|
|
export const fetchTrace = ({ dispatch, state }) =>
|
2018-11-20 20:47:30 +05:30
|
|
|
axios
|
|
|
|
.get(`${state.traceEndpoint}/trace.json`, {
|
|
|
|
params: { state: state.traceState },
|
|
|
|
})
|
|
|
|
.then(({ data }) => {
|
2018-12-13 13:39:08 +05:30
|
|
|
dispatch('toggleScrollisInBottom', isScrolledToBottom());
|
2018-11-20 20:47:30 +05:30
|
|
|
dispatch('receiveTraceSuccess', data);
|
|
|
|
|
2020-03-13 15:44:24 +05:30
|
|
|
if (data.complete) {
|
2018-11-20 20:47:30 +05:30
|
|
|
dispatch('stopPollingTrace');
|
2020-03-13 15:44:24 +05:30
|
|
|
} else if (!state.traceTimeout) {
|
|
|
|
dispatch('startPollingTrace');
|
2018-11-20 20:47:30 +05:30
|
|
|
}
|
|
|
|
})
|
2021-03-08 18:12:59 +05:30
|
|
|
.catch((e) =>
|
2021-02-22 17:27:13 +05:30
|
|
|
e.response.status === httpStatusCodes.FORBIDDEN
|
|
|
|
? dispatch('receiveTraceUnauthorizedError')
|
|
|
|
: dispatch('receiveTraceError'),
|
|
|
|
);
|
2018-12-13 13:39:08 +05:30
|
|
|
|
2020-03-13 15:44:24 +05:30
|
|
|
export const startPollingTrace = ({ dispatch, commit }) => {
|
|
|
|
const traceTimeout = setTimeout(() => {
|
|
|
|
commit(types.SET_TRACE_TIMEOUT, 0);
|
|
|
|
dispatch('fetchTrace');
|
|
|
|
}, 4000);
|
|
|
|
|
|
|
|
commit(types.SET_TRACE_TIMEOUT, traceTimeout);
|
|
|
|
};
|
|
|
|
|
|
|
|
export const stopPollingTrace = ({ state, commit }) => {
|
|
|
|
clearTimeout(state.traceTimeout);
|
|
|
|
commit(types.SET_TRACE_TIMEOUT, 0);
|
2018-11-20 20:47:30 +05:30
|
|
|
commit(types.STOP_POLLING_TRACE);
|
|
|
|
};
|
2020-03-13 15:44:24 +05:30
|
|
|
|
2018-11-20 20:47:30 +05:30
|
|
|
export const receiveTraceSuccess = ({ commit }, log) => commit(types.RECEIVE_TRACE_SUCCESS, log);
|
2020-03-13 15:44:24 +05:30
|
|
|
export const receiveTraceError = ({ dispatch }) => {
|
|
|
|
dispatch('stopPollingTrace');
|
2018-11-20 20:47:30 +05:30
|
|
|
flash(__('An error occurred while fetching the job log.'));
|
|
|
|
};
|
2021-02-22 17:27:13 +05:30
|
|
|
export const receiveTraceUnauthorizedError = ({ dispatch }) => {
|
|
|
|
dispatch('stopPollingTrace');
|
|
|
|
flash(__('The current user is not authorized to access the job log.'));
|
|
|
|
};
|
2019-12-04 20:38:33 +05:30
|
|
|
/**
|
2020-07-28 23:09:34 +05:30
|
|
|
* When the user clicks a collapsible line in the job
|
2019-12-04 20:38:33 +05:30
|
|
|
* log, we commit a mutation to update the state
|
|
|
|
*
|
|
|
|
* @param {Object} section
|
|
|
|
*/
|
|
|
|
export const toggleCollapsibleLine = ({ commit }, section) =>
|
|
|
|
commit(types.TOGGLE_COLLAPSIBLE_LINE, section);
|
2018-11-20 20:47:30 +05:30
|
|
|
|
|
|
|
/**
|
|
|
|
* Jobs list on sidebar - depend on stages dropdown
|
|
|
|
*/
|
2018-12-05 23:21:45 +05:30
|
|
|
export const requestJobsForStage = ({ commit }, stage) =>
|
|
|
|
commit(types.REQUEST_JOBS_FOR_STAGE, stage);
|
2018-11-20 20:47:30 +05:30
|
|
|
|
|
|
|
// On stage click, set selected stage + fetch job
|
2019-09-04 21:01:54 +05:30
|
|
|
export const fetchJobsForStage = ({ dispatch }, stage = {}) => {
|
2018-12-05 23:21:45 +05:30
|
|
|
dispatch('requestJobsForStage', stage);
|
2018-11-20 20:47:30 +05:30
|
|
|
|
|
|
|
axios
|
2018-12-05 23:21:45 +05:30
|
|
|
.get(stage.dropdown_path, {
|
|
|
|
params: {
|
|
|
|
retried: 1,
|
|
|
|
},
|
|
|
|
})
|
|
|
|
.then(({ data }) => {
|
2021-03-08 18:12:59 +05:30
|
|
|
const retriedJobs = data.retried.map((job) => ({ ...job, retried: true }));
|
2018-12-05 23:21:45 +05:30
|
|
|
const jobs = data.latest_statuses.concat(retriedJobs);
|
|
|
|
|
|
|
|
dispatch('receiveJobsForStageSuccess', jobs);
|
|
|
|
})
|
2018-11-20 20:47:30 +05:30
|
|
|
.catch(() => dispatch('receiveJobsForStageError'));
|
|
|
|
};
|
|
|
|
export const receiveJobsForStageSuccess = ({ commit }, data) =>
|
|
|
|
commit(types.RECEIVE_JOBS_FOR_STAGE_SUCCESS, data);
|
|
|
|
export const receiveJobsForStageError = ({ commit }) => {
|
|
|
|
commit(types.RECEIVE_JOBS_FOR_STAGE_ERROR);
|
|
|
|
flash(__('An error occurred while fetching the jobs.'));
|
|
|
|
};
|
|
|
|
|
2019-10-12 21:52:04 +05:30
|
|
|
export const triggerManualJob = ({ state }, variables) => {
|
2021-03-08 18:12:59 +05:30
|
|
|
const parsedVariables = variables.map((variable) => {
|
2020-05-24 23:13:21 +05:30
|
|
|
const copyVar = { ...variable };
|
2019-10-12 21:52:04 +05:30
|
|
|
delete copyVar.id;
|
|
|
|
return copyVar;
|
|
|
|
});
|
|
|
|
|
|
|
|
axios
|
|
|
|
.post(state.job.status.action.path, {
|
|
|
|
job_variables_attributes: parsedVariables,
|
|
|
|
})
|
|
|
|
.catch(() => flash(__('An error occurred while triggering the job.')));
|
|
|
|
};
|