changed mutation to return new array
this makes the component completly unaware of the store, instead it emits events to the parent which knows about the store
This commit is contained in:
parent
c9d676c106
commit
3270e14077
5 changed files with 80 additions and 48 deletions
|
@ -1,4 +1,5 @@
|
||||||
<script>
|
<script>
|
||||||
|
import { mapActions } from 'vuex';
|
||||||
import LoadingIcon from '../../../vue_shared/components/loading_icon.vue';
|
import LoadingIcon from '../../../vue_shared/components/loading_icon.vue';
|
||||||
import Stage from './stage.vue';
|
import Stage from './stage.vue';
|
||||||
|
|
||||||
|
@ -17,6 +18,9 @@ export default {
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
methods: {
|
||||||
|
...mapActions('pipelines', ['fetchJobs', 'toggleStageCollapsed']),
|
||||||
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@ -32,6 +36,8 @@ export default {
|
||||||
v-for="stage in stages"
|
v-for="stage in stages"
|
||||||
:key="stage.id"
|
:key="stage.id"
|
||||||
:stage="stage"
|
:stage="stage"
|
||||||
|
@fetch="fetchJobs"
|
||||||
|
@toggleCollapsed="toggleStageCollapsed"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
<script>
|
<script>
|
||||||
import { mapActions } from 'vuex';
|
|
||||||
import tooltip from '../../../vue_shared/directives/tooltip';
|
import tooltip from '../../../vue_shared/directives/tooltip';
|
||||||
import Icon from '../../../vue_shared/components/icon.vue';
|
import Icon from '../../../vue_shared/components/icon.vue';
|
||||||
import CiIcon from '../../../vue_shared/components/ci_icon.vue';
|
import CiIcon from '../../../vue_shared/components/ci_icon.vue';
|
||||||
|
@ -38,16 +37,17 @@ export default {
|
||||||
return this.stage.jobs.length;
|
return this.stage.jobs.length;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
created() {
|
|
||||||
this.fetchJobs(this.stage);
|
|
||||||
},
|
|
||||||
mounted() {
|
mounted() {
|
||||||
const { stageTitle } = this.$refs;
|
const { stageTitle } = this.$refs;
|
||||||
|
|
||||||
this.showTooltip = stageTitle.scrollWidth > stageTitle.offsetWidth;
|
this.showTooltip = stageTitle.scrollWidth > stageTitle.offsetWidth;
|
||||||
|
|
||||||
|
this.$emit('fetch', this.stage);
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
...mapActions('pipelines', ['fetchJobs', 'toggleStageCollapsed']),
|
toggleCollapsed() {
|
||||||
|
this.$emit('toggleCollapsed', this.stage.id);
|
||||||
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
@ -61,7 +61,7 @@ export default {
|
||||||
:class="{
|
:class="{
|
||||||
'border-bottom-0': stage.isCollapsed
|
'border-bottom-0': stage.isCollapsed
|
||||||
}"
|
}"
|
||||||
@click="toggleStageCollapsed(stage.id)"
|
@click="toggleCollapsed"
|
||||||
>
|
>
|
||||||
<ci-icon
|
<ci-icon
|
||||||
:status="stage.status"
|
:status="stage.status"
|
||||||
|
|
|
@ -39,20 +39,28 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[types.REQUEST_JOBS](state, id) {
|
[types.REQUEST_JOBS](state, id) {
|
||||||
const stage = state.stages.find(s => s.id === id);
|
state.stages = state.stages.map(stage => ({
|
||||||
stage.isLoading = true;
|
...stage,
|
||||||
|
isLoading: stage.id === id ? true : stage.isLoading,
|
||||||
|
}));
|
||||||
},
|
},
|
||||||
[types.RECEIVE_JOBS_ERROR](state, id) {
|
[types.RECEIVE_JOBS_ERROR](state, id) {
|
||||||
const stage = state.stages.find(s => s.id === id);
|
state.stages = state.stages.map(stage => ({
|
||||||
stage.isLoading = false;
|
...stage,
|
||||||
|
isLoading: stage.id === id ? false : stage.isLoading,
|
||||||
|
}));
|
||||||
},
|
},
|
||||||
[types.RECEIVE_JOBS_SUCCESS](state, { id, data }) {
|
[types.RECEIVE_JOBS_SUCCESS](state, { id, data }) {
|
||||||
const stage = state.stages.find(s => s.id === id);
|
state.stages = state.stages.map(stage => ({
|
||||||
stage.isLoading = false;
|
...stage,
|
||||||
stage.jobs = data.latest_statuses.map(normalizeJob);
|
isLoading: stage.id === id ? false : stage.isLoading,
|
||||||
|
jobs: data.latest_statuses.map(normalizeJob),
|
||||||
|
}));
|
||||||
},
|
},
|
||||||
[types.TOGGLE_STAGE_COLLAPSE](state, id) {
|
[types.TOGGLE_STAGE_COLLAPSE](state, id) {
|
||||||
const stage = state.stages.find(s => s.id === id);
|
state.stages = state.stages.map(stage => ({
|
||||||
stage.isCollapsed = !stage.isCollapsed;
|
...stage,
|
||||||
|
isCollapsed: stage.id === id ? !stage.isCollapsed : stage.isCollapsed,
|
||||||
|
}));
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -21,7 +21,12 @@ describe('IDE stages list', () => {
|
||||||
isCollapsed: false,
|
isCollapsed: false,
|
||||||
})),
|
})),
|
||||||
loading: false,
|
loading: false,
|
||||||
}).$mount();
|
});
|
||||||
|
|
||||||
|
spyOn(vm, 'fetchJobs');
|
||||||
|
spyOn(vm, 'toggleStageCollapsed');
|
||||||
|
|
||||||
|
vm.$mount();
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
|
@ -42,4 +47,21 @@ describe('IDE stages list', () => {
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('calls toggleStageCollapsed when clicking stage header', done => {
|
||||||
|
vm.$el.querySelector('.card-header').click();
|
||||||
|
|
||||||
|
vm.$nextTick(() => {
|
||||||
|
expect(vm.toggleStageCollapsed).toHaveBeenCalledWith(0);
|
||||||
|
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('calls fetchJobs when stage is mounted', () => {
|
||||||
|
expect(vm.fetchJobs.calls.count()).toBe(stages.length);
|
||||||
|
|
||||||
|
expect(vm.fetchJobs.calls.argsFor(0)).toEqual([vm.stages[0]]);
|
||||||
|
expect(vm.fetchJobs.calls.argsFor(1)).toEqual([vm.stages[1]]);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,51 +1,37 @@
|
||||||
import Vue from 'vue';
|
import Vue from 'vue';
|
||||||
import MockAdapter from 'axios-mock-adapter';
|
|
||||||
import axios from '~/lib/utils/axios_utils';
|
|
||||||
import { createStore } from '~/ide/stores';
|
|
||||||
import Stage from '~/ide/components/jobs/stage.vue';
|
import Stage from '~/ide/components/jobs/stage.vue';
|
||||||
import { createComponentWithStore } from '../../../helpers/vue_mount_component_helper';
|
|
||||||
import { stages, jobs } from '../../mock_data';
|
import { stages, jobs } from '../../mock_data';
|
||||||
|
|
||||||
describe('IDE pipeline stage', () => {
|
describe('IDE pipeline stage', () => {
|
||||||
const Component = Vue.extend(Stage);
|
const Component = Vue.extend(Stage);
|
||||||
let vm;
|
let vm;
|
||||||
let mock;
|
|
||||||
let stage;
|
let stage;
|
||||||
|
|
||||||
beforeEach(done => {
|
beforeEach(() => {
|
||||||
const store = createStore();
|
stage = {
|
||||||
mock = new MockAdapter(axios);
|
...stages[0],
|
||||||
|
id: 0,
|
||||||
Vue.set(
|
dropdownPath: stages[0].dropdown_path,
|
||||||
store.state.pipelines,
|
jobs: [...jobs],
|
||||||
'stages',
|
|
||||||
stages.map((mappedState, i) => ({
|
|
||||||
...mappedState,
|
|
||||||
id: i,
|
|
||||||
dropdownPath: mappedState.dropdown_path,
|
|
||||||
jobs: [],
|
|
||||||
isLoading: false,
|
isLoading: false,
|
||||||
isCollapsed: false,
|
isCollapsed: false,
|
||||||
})),
|
};
|
||||||
);
|
|
||||||
|
|
||||||
stage = store.state.pipelines.stages[0];
|
vm = new Component({
|
||||||
|
propsData: { stage },
|
||||||
mock.onGet(stage.dropdownPath).reply(200, {
|
|
||||||
latest_statuses: jobs,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
vm = createComponentWithStore(Component, store, {
|
spyOn(vm, '$emit');
|
||||||
stage,
|
|
||||||
}).$mount();
|
|
||||||
|
|
||||||
setTimeout(done, 500);
|
vm.$mount();
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
vm.$destroy();
|
vm.$destroy();
|
||||||
|
});
|
||||||
|
|
||||||
mock.restore();
|
it('emits fetch event when mounted', () => {
|
||||||
|
expect(vm.$emit).toHaveBeenCalledWith('fetch', vm.stage);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('renders stages details', () => {
|
it('renders stages details', () => {
|
||||||
|
@ -57,9 +43,19 @@ describe('IDE pipeline stage', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('collapsed', () => {
|
describe('collapsed', () => {
|
||||||
it('toggles collapse status when clicking header', done => {
|
it('emits event when clicking header', done => {
|
||||||
vm.$el.querySelector('.card-header').click();
|
vm.$el.querySelector('.card-header').click();
|
||||||
|
|
||||||
|
vm.$nextTick(() => {
|
||||||
|
expect(vm.$emit).toHaveBeenCalledWith('toggleCollapsed', vm.stage.id);
|
||||||
|
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('toggles collapse status when collapsed', done => {
|
||||||
|
vm.stage.isCollapsed = true;
|
||||||
|
|
||||||
vm.$nextTick(() => {
|
vm.$nextTick(() => {
|
||||||
expect(vm.$el.querySelector('.card-body').style.display).toBe('none');
|
expect(vm.$el.querySelector('.card-body').style.display).toBe('none');
|
||||||
|
|
||||||
|
@ -68,7 +64,7 @@ describe('IDE pipeline stage', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('sets border bottom class when collapsed', done => {
|
it('sets border bottom class when collapsed', done => {
|
||||||
vm.$el.querySelector('.card-header').click();
|
vm.stage.isCollapsed = true;
|
||||||
|
|
||||||
vm.$nextTick(() => {
|
vm.$nextTick(() => {
|
||||||
expect(vm.$el.querySelector('.card-header').classList).toContain('border-bottom-0');
|
expect(vm.$el.querySelector('.card-header').classList).toContain('border-bottom-0');
|
||||||
|
|
Loading…
Reference in a new issue