Skip to content
Snippets Groups Projects
Unverified Commit 5e79276b authored by Phil Hughes's avatar Phil Hughes
Browse files

improve API calls by calling internal API to get data

render job items (needs improvements to components)
parent cfe4d2f2
No related branches found
No related tags found
No related merge requests found
Loading
Loading
@@ -24,7 +24,7 @@ const Api = {
branchSinglePath: '/api/:version/projects/:id/repository/branches/:branch',
createBranchPath: '/api/:version/projects/:id/repository/branches',
pipelinesPath: '/api/:version/projects/:id/pipelines',
pipelineJobsPath: '/api/:version/projects/:id/pipelines/:pipeline_id/jobs',
pipelineJobsPath: '/:project_path/pipelines/:id/builds.json',
 
group(groupId, callback) {
const url = Api.buildUrl(Api.groupPath).replace(':id', groupId);
Loading
Loading
@@ -232,8 +232,8 @@ const Api = {
 
pipelineJobs(projectPath, pipelineId, params = {}) {
const url = Api.buildUrl(this.pipelineJobsPath)
.replace(':id', encodeURIComponent(projectPath))
.replace(':pipeline_id', pipelineId);
.replace(':project_path', projectPath)
.replace(':id', pipelineId);
 
return axios.get(url, { params });
},
Loading
Loading
<script>
import { mapActions, mapGetters } from 'vuex';
import { mapActions, mapGetters, mapState } from 'vuex';
import Icon from '../../../vue_shared/components/icon.vue';
import CiIcon from '../../../vue_shared/components/ci_icon.vue';
import Tabs from '../../../vue_shared/components/tabs/tabs';
import Tab from '../../../vue_shared/components/tabs/tab.vue';
 
Loading
Loading
@@ -7,15 +9,18 @@ export default {
components: {
Tabs,
Tab,
Icon,
CiIcon,
},
computed: {
...mapGetters('pipelines', ['jobsCount', 'failedJobs']),
...mapGetters('pipelines', ['jobsCount', 'failedJobsCount']),
...mapState('pipelines', ['stages']),
},
mounted() {
this.fetchJobs();
this.fetchStages();
},
methods: {
...mapActions('pipelines', ['fetchJobs']),
...mapActions('pipelines', ['fetchStages']),
},
};
</script>
Loading
Loading
@@ -27,11 +32,44 @@ export default {
<template slot="title">
Jobs <span class="badge">{{ jobsCount }}</span>
</template>
List all jobs here
<div style="overflow: auto;">
<div
v-for="stage in stages"
:key="stage.id"
class="panel panel-default"
>
<div
class="panel-heading"
@click="() => stage.isCollapsed = !stage.isCollapsed"
>
<ci-icon :status="stage.status" />
{{ stage.title }}
<span class="badge">
{{ stage.jobs.length }}
</span>
<icon
:name="stage.isCollapsed ? 'angle-left' : 'angle-down'"
css-classes="pull-right"
/>
</div>
<div
class="panel-body"
v-show="!stage.isCollapsed"
>
<div
v-for="job in stage.jobs"
:key="job.id"
>
<ci-icon :status="job.status" />
{{ job.name }} #{{ job.id }}
</div>
</div>
</div>
</div>
</tab>
<tab>
<template slot="title">
Failed Jobs <span class="badge">{{ failedJobs.length }}</span>
Failed Jobs <span class="badge">{{ failedJobsCount }}</span>
</template>
List all failed jobs here
</tab>
Loading
Loading
import axios from 'axios';
import { __ } from '../../../../locale';
import Api from '../../../../api';
import flash from '../../../../flash';
Loading
Loading
@@ -21,29 +22,40 @@ export const fetchLatestPipeline = ({ dispatch, rootState }, sha) => {
.catch(() => dispatch('receiveLatestPipelineError'));
};
 
export const requestJobs = ({ commit }) => commit(types.REQUEST_JOBS);
export const receiveJobsError = ({ commit }) => {
flash(__('There was an error loading jobs'));
commit(types.RECEIVE_JOBS_ERROR);
export const requestStages = ({ commit }) => commit(types.REQUEST_STAGES);
export const receiveStagesError = ({ commit }) => {
flash(__('There was an error loading job stages'));
commit(types.RECEIVE_STAGES_ERROR);
};
export const receiveJobsSuccess = ({ commit }, data) => commit(types.RECEIVE_JOBS_SUCCESS, data);
export const receiveStagesSuccess = ({ commit }, data) =>
commit(types.RECEIVE_STAGES_SUCCESS, data);
export const fetchStages = ({ dispatch, state, rootState }) => {
dispatch('requestStages');
 
export const fetchJobs = ({ dispatch, state, rootState }, page = '1') => {
dispatch('requestJobs');
Api.pipelineJobs(rootState.currentProjectId, state.latestPipeline.id)
.then(({ data }) => dispatch('receiveStagesSuccess', data))
.then(() => state.stages.forEach(stage => dispatch('fetchJobs', stage)))
.catch(() => dispatch('receiveStagesError'));
};
 
Api.pipelineJobs(rootState.currentProjectId, state.latestPipeline.id, {
page,
})
.then(({ data, headers }) => {
const nextPage = headers && headers['x-next-page'];
export const requestJobs = ({ commit }, id) => commit(types.REQUEST_JOBS, id);
export const receiveJobsError = ({ commit }, id) => {
flash(__('There was an error loading jobs'));
commit(types.RECEIVE_JOBS_ERROR, id);
};
export const receiveJobsSuccess = ({ commit }, { id, data }) =>
commit(types.RECEIVE_JOBS_SUCCESS, { id, data });
 
dispatch('receiveJobsSuccess', data);
export const fetchJobs = ({ dispatch }, stage) => {
dispatch('requestJobs', stage.id);
 
if (nextPage) {
dispatch('fetchJobs', nextPage);
}
axios
.get(stage.dropdown_path)
.then(({ data }) => {
dispatch('receiveJobsSuccess', { id: stage.id, data });
})
.catch(() => dispatch('receiveJobsError'));
.catch(() => dispatch('receiveJobsError', stage.id));
};
 
export default () => {};
export const hasLatestPipeline = state => !state.isLoadingPipeline && !!state.latestPipeline;
 
export const failedJobs = state =>
export const failedJobsCount = state =>
state.stages.reduce(
(acc, stage) => acc.concat(stage.jobs.filter(job => job.status === 'failed')),
[],
(acc, stage) => acc + stage.jobs.filter(j => j.status.label === 'failed').length,
0,
);
 
export const jobsCount = state => state.stages.reduce((acc, stage) => acc + stage.jobs.length, 0);
Loading
Loading
@@ -2,6 +2,10 @@ export const REQUEST_LATEST_PIPELINE = 'REQUEST_LATEST_PIPELINE';
export const RECEIVE_LASTEST_PIPELINE_ERROR = 'RECEIVE_LASTEST_PIPELINE_ERROR';
export const RECEIVE_LASTEST_PIPELINE_SUCCESS = 'RECEIVE_LASTEST_PIPELINE_SUCCESS';
 
export const REQUEST_STAGES = 'REQUEST_STAGES';
export const RECEIVE_STAGES_ERROR = 'RECEIVE_STAGES_ERROR';
export const RECEIVE_STAGES_SUCCESS = 'RECEIVE_STAGES_SUCCESS';
export const REQUEST_JOBS = 'REQUEST_JOBS';
export const RECEIVE_JOBS_ERROR = 'RECEIVE_JOBS_ERROR';
export const RECEIVE_JOBS_SUCCESS = 'RECEIVE_JOBS_SUCCESS';
Loading
Loading
@@ -18,37 +18,52 @@ export default {
};
}
},
[types.REQUEST_JOBS](state) {
[types.REQUEST_STAGES](state) {
state.isLoadingJobs = true;
},
[types.RECEIVE_JOBS_ERROR](state) {
[types.RECEIVE_STAGES_ERROR](state) {
state.isLoadingJobs = false;
},
[types.RECEIVE_JOBS_SUCCESS](state, jobs) {
[types.RECEIVE_STAGES_SUCCESS](state, stages) {
state.isLoadingJobs = false;
 
state.stages = jobs.reduce((acc, job) => {
let stage = acc.find(s => s.title === job.stage);
if (!stage) {
stage = {
title: job.stage,
isCollapsed: false,
jobs: [],
};
acc.push(stage);
}
stage.jobs = stage.jobs.concat({
id: job.id,
name: job.name,
status: job.status,
stage: job.stage,
duration: job.duration,
});
return acc;
}, state.stages);
state.stages = stages.map((stage, i) => ({
...stage,
id: i,
isCollapsed: false,
isLoading: false,
jobs: [],
}));
},
[types.REQUEST_JOBS](state, id) {
state.stages = state.stages.reduce(
(acc, stage) =>
acc.concat({
...stage,
isLoading: id === stage.id ? true : stage.isLoading,
}),
[],
);
},
[types.RECEIVE_JOBS_ERROR](state, id) {
state.stages = state.stages.reduce(
(acc, stage) =>
acc.concat({
...stage,
isLoading: id === stage.id ? false : stage.isLoading,
}),
[],
);
},
[types.RECEIVE_JOBS_SUCCESS](state, { id, data }) {
state.stages = state.stages.reduce(
(acc, stage) =>
acc.concat({
...stage,
isLoading: id === stage.id ? false : stage.isLoading,
jobs: id === stage.id ? data.latest_statuses : stage.jobs,
}),
[],
);
},
};
Loading
Loading
@@ -26,6 +26,9 @@ export default {
created() {
this.isTab = true;
},
updated() {
this.$parent.$forceUpdate();
},
};
</script>
 
Loading
Loading
Loading
Loading
@@ -76,7 +76,16 @@ class Projects::PipelinesController < Projects::ApplicationController
end
 
def builds
render_show
respond_to do |format|
format.html do
render_show
end
format.json do
render json: PipelineSerializer
.new(project: @project, current_user: @current_user)
.represent_stages(@pipeline)
end
end
end
 
def failures
Loading
Loading
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment