added empty state & YAML error state

This commit is contained in:
Phil Hughes 2018-05-29 10:35:13 +01:00
parent b4ef2aad02
commit 782c31a494
No known key found for this signature in database
GPG key ID: 32245528C52E0F9F
10 changed files with 88 additions and 18 deletions

View file

@ -1,10 +1,12 @@
<script>
import { mapActions, mapGetters, mapState } from 'vuex';
import { sprintf, __ } from '../../../locale';
import LoadingIcon from '../../../vue_shared/components/loading_icon.vue';
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';
import EmptyState from '../../../pipelines/components/empty_state.vue';
import JobsList from '../jobs/list.vue';
export default {
@ -15,10 +17,23 @@ export default {
Tabs,
Tab,
JobsList,
EmptyState,
},
computed: {
...mapState(['pipelinesEmptyStateSvgPath']),
...mapGetters(['currentProject']),
...mapGetters('pipelines', ['jobsCount', 'failedJobsCount', 'failedStages', 'pipelineFailed']),
...mapState('pipelines', ['isLoadingPipeline', 'latestPipeline', 'stages', 'isLoadingJobs']),
ciLintText() {
return sprintf(
__('You can also test your .gitlab-ci.yml in the %{linkStart}Lint%{linkEnd}'),
{
linkStart: `<a href="${this.currentProject.web_url}/-/ci/lint">`,
linkEnd: '</a>',
},
false,
);
},
},
created() {
this.fetchLatestPipeline();
@ -32,12 +47,13 @@ export default {
<template>
<div class="ide-pipeline">
<loading-icon
v-if="isLoadingPipeline && !latestPipeline"
v-if="isLoadingPipeline && latestPipeline === null"
class="prepend-top-default"
size="2"
/>
<template v-else-if="latestPipeline">
<template v-else-if="latestPipeline !== null">
<header
v-if="latestPipeline"
class="ide-tree-header ide-pipeline-header"
>
<ci-icon
@ -61,7 +77,31 @@ export default {
</a>
</span>
</header>
<tabs class="ide-pipeline-list">
<empty-state
v-if="latestPipeline === false"
help-page-path="a"
:empty-state-svg-path="pipelinesEmptyStateSvgPath"
:can-set-ci="true"
/>
<div
v-else-if="latestPipeline.yamlError"
class="bs-callout bs-callout-danger"
>
<p class="append-bottom-0">
Found errors in your .gitlab-ci.yml:
</p>
<p class="append-bottom-0">
{{ latestPipeline.yamlError }}
</p>
<p
class="append-bottom-0"
v-html="ciLintText"
></p>
</div>
<tabs
v-else
class="ide-pipeline-list"
>
<tab
:active="!pipelineFailed"
>
@ -105,6 +145,7 @@ export default {
.ide-pipeline {
display: flex;
flex-direction: column;
height: 100%;
}
.ide-pipeline-list {
@ -121,4 +162,9 @@ export default {
.ide-pipeline-header .ci-status-icon {
display: flex;
}
.ide-pipeline .empty-state {
margin-top: auto;
margin-bottom: auto;
}
</style>

View file

@ -21,6 +21,7 @@ export function initIde(el) {
emptyStateSvgPath: el.dataset.emptyStateSvgPath,
noChangesStateSvgPath: el.dataset.noChangesStateSvgPath,
committedStateSvgPath: el.dataset.committedStateSvgPath,
pipelinesEmptyStateSvgPath: el.dataset.pipelinesEmptyStateSvgPath,
});
},
render(createElement) {

View file

@ -19,12 +19,14 @@ export const receiveLatestPipelineError = ({ commit, dispatch }) => {
dispatch('stopPipelinePolling');
};
export const receiveLatestPipelineSuccess = ({ rootGetters, commit }, { pipelines }) => {
let lastCommitPipeline = false;
if (pipelines && pipelines.length) {
const lastCommitHash = rootGetters.lastCommit && rootGetters.lastCommit.id;
const lastCommitPipeline = pipelines.find(pipeline => pipeline.commit.id === lastCommitHash);
commit(types.RECEIVE_LASTEST_PIPELINE_SUCCESS, lastCommitPipeline);
lastCommitPipeline = pipelines.find(pipeline => pipeline.commit.id === lastCommitHash);
}
commit(types.RECEIVE_LASTEST_PIPELINE_SUCCESS, lastCommitPipeline);
};
export const fetchLatestPipeline = ({ dispatch, rootGetters }) => {

View file

@ -19,6 +19,7 @@ export default {
details: {
status: pipeline.details.status,
},
yamlError: pipeline.yaml_errors,
};
state.stages = pipeline.details.stages.map((stage, i) => {
const foundStage = state.stages.find(s => s.id === i);
@ -32,6 +33,8 @@ export default {
jobs: foundStage ? foundStage.jobs : [],
};
});
} else {
state.latestPipeline = false;
}
},
[types.REQUEST_JOBS](state, id) {

View file

@ -1,5 +1,5 @@
export default () => ({
isLoadingPipeline: false,
isLoadingPipeline: true,
isLoadingJobs: false,
latestPipeline: null,
stages: [],

View file

@ -114,12 +114,13 @@ export default {
},
[types.SET_EMPTY_STATE_SVGS](
state,
{ emptyStateSvgPath, noChangesStateSvgPath, committedStateSvgPath },
{ emptyStateSvgPath, noChangesStateSvgPath, committedStateSvgPath, pipelinesEmptyStateSvgPath },
) {
Object.assign(state, {
emptyStateSvgPath,
noChangesStateSvgPath,
committedStateSvgPath,
pipelinesEmptyStateSvgPath,
});
},
[types.TOGGLE_FILE_FINDER](state, fileFindVisible) {

View file

@ -3,7 +3,8 @@
#ide.ide-loading{ data: {"empty-state-svg-path" => image_path('illustrations/multi_file_editor_empty.svg'),
"no-changes-state-svg-path" => image_path('illustrations/multi-editor_no_changes_empty.svg'),
"committed-state-svg-path" => image_path('illustrations/multi-editor_all_changes_committed_empty.svg') } }
"committed-state-svg-path" => image_path('illustrations/multi-editor_all_changes_committed_empty.svg'),
"pipelines-empty-state-svg-path": image_path('illustrations/pipelines_empty.svg') } }
.text-center
= icon('spinner spin 2x')
%h2.clgray= _('Loading the GitLab IDE...')

View file

@ -20,12 +20,14 @@ export const pipelines = [
ref: 'master',
sha: '123',
status: 'failed',
commit: { id: '123' },
},
{
id: 2,
ref: 'master',
sha: '213',
status: 'success',
commit: { id: '213' },
},
];

View file

@ -65,15 +65,28 @@ describe('IDE pipelines actions', () => {
});
describe('receiveLatestPipelineSuccess', () => {
it('commits pipeline', done => {
testAction(
receiveLatestPipelineSuccess,
const rootGetters = {
lastCommit: { id: '123' },
};
let commit;
beforeEach(() => {
commit = jasmine.createSpy('commit');
});
it('commits pipeline', () => {
receiveLatestPipelineSuccess({ rootGetters, commit }, { pipelines });
expect(commit.calls.argsFor(0)).toEqual([
types.RECEIVE_LASTEST_PIPELINE_SUCCESS,
pipelines[0],
mockedState,
[{ type: types.RECEIVE_LASTEST_PIPELINE_SUCCESS, payload: pipelines[0] }],
[],
done,
);
]);
});
it('commits false when there are no pipelines', () => {
receiveLatestPipelineSuccess({ rootGetters, commit }, { pipelines: [] });
expect(commit.calls.argsFor(0)).toEqual([types.RECEIVE_LASTEST_PIPELINE_SUCCESS, false]);
});
});

View file

@ -47,13 +47,14 @@ describe('IDE pipelines mutations', () => {
path: 'test',
commit: { id: '123' },
details: { status: jasmine.any(Object) },
yamlError: undefined,
});
});
it('does not set latest pipeline if pipeline is null', () => {
mutations[types.RECEIVE_LASTEST_PIPELINE_SUCCESS](mockedState, null);
expect(mockedState.latestPipeline).toEqual(null);
expect(mockedState.latestPipeline).toEqual(false);
});
it('sets stages', () => {