diff --git a/app/assets/javascripts/jobs/job_details_bundle.js b/app/assets/javascripts/jobs/job_details_bundle.js index a84324f14b2f0fd01dcb22c9bf9c654b1ad3ac53..0136ec4d19427d24bbe1bfcfe21f69d83b82b4e7 100644 --- a/app/assets/javascripts/jobs/job_details_bundle.js +++ b/app/assets/javascripts/jobs/job_details_bundle.js @@ -1,34 +1,36 @@ +import { mapState } from 'vuex'; import Vue from 'vue'; -import JobMediator from './job_details_mediator'; -import jobHeader from './components/header.vue'; -import detailsBlock from './components/sidebar_details_block.vue'; +import Job from '../job'; +import JobHeader from './components/header.vue'; +import DetailsBlock from './components/sidebar_details_block.vue'; +import createStore from './store'; export default () => { const { dataset } = document.getElementById('js-job-details-vue'); - const mediator = new JobMediator({ endpoint: dataset.endpoint }); - mediator.fetchJob(); + // eslint-disable-next-line no-new + new Job(); + + const store = createStore(); + store.dispatch('setJobEndpoint', dataset.endpoint); + store.dispatch('fetchJob'); // Header // eslint-disable-next-line no-new new Vue({ el: '#js-build-header-vue', components: { - jobHeader, - }, - data() { - return { - mediator, - }; + JobHeader, }, - mounted() { - this.mediator.initBuildClass(); + store, + computed: { + ...mapState(['job', 'isLoading']), }, render(createElement) { return createElement('job-header', { props: { - isLoading: this.mediator.state.isLoading, - job: this.mediator.store.state.job, + isLoading: this.isLoading, + job: this.job, }, }); }, @@ -41,18 +43,17 @@ export default () => { new Vue({ el: detailsBlockElement, components: { - detailsBlock, + DetailsBlock, }, - data() { - return { - mediator, - }; + store, + computed: { + ...mapState(['job', 'isLoading']), }, render(createElement) { return createElement('details-block', { props: { - isLoading: this.mediator.state.isLoading, - job: this.mediator.store.state.job, + isLoading: this.isLoading, + job: this.job, runnerHelpUrl: dataset.runnerHelpUrl, terminalPath: detailsBlockDataset.terminalPath, }, diff --git a/app/assets/javascripts/jobs/job_details_mediator.js b/app/assets/javascripts/jobs/job_details_mediator.js deleted file mode 100644 index 073e518baa001e6ee14c554d4cd443a04787be8e..0000000000000000000000000000000000000000 --- a/app/assets/javascripts/jobs/job_details_mediator.js +++ /dev/null @@ -1,65 +0,0 @@ -import Visibility from 'visibilityjs'; -import Flash from '../flash'; -import Poll from '../lib/utils/poll'; -import JobStore from './stores/job_store'; -import JobService from './services/job_service'; -import Job from '../job'; - -export default class JobMediator { - constructor(options = {}) { - this.options = options; - - this.store = new JobStore(); - this.service = new JobService(options.endpoint); - - this.state = { - isLoading: false, - }; - } - - initBuildClass() { - this.build = new Job(); - } - - fetchJob() { - this.poll = new Poll({ - resource: this.service, - method: 'getJob', - successCallback: response => this.successCallback(response), - errorCallback: () => this.errorCallback(), - }); - - if (!Visibility.hidden()) { - this.state.isLoading = true; - this.poll.makeRequest(); - } else { - this.getJob(); - } - - Visibility.change(() => { - if (!Visibility.hidden()) { - this.poll.restart(); - } else { - this.poll.stop(); - } - }); - } - - getJob() { - return this.service - .getJob() - .then(response => this.successCallback(response)) - .catch(() => this.errorCallback()); - } - - successCallback(response) { - this.state.isLoading = false; - return this.store.storeJob(response.data); - } - - errorCallback() { - this.state.isLoading = false; - - return new Flash('An error occurred while fetching the job.'); - } -} diff --git a/app/assets/javascripts/jobs/services/job_service.js b/app/assets/javascripts/jobs/services/job_service.js deleted file mode 100644 index b746489c45c32226acecf52d29c8476094d85aeb..0000000000000000000000000000000000000000 --- a/app/assets/javascripts/jobs/services/job_service.js +++ /dev/null @@ -1,11 +0,0 @@ -import axios from '../../lib/utils/axios_utils'; - -export default class JobService { - constructor(endpoint) { - this.job = endpoint; - } - - getJob() { - return axios.get(this.job); - } -} diff --git a/app/assets/javascripts/jobs/store/mutations.js b/app/assets/javascripts/jobs/store/mutations.js index cd12ef87d40bde44911be4839567a9f209dd2433..c3f2359fa4d1f745a314cd8714942c13f4145d51 100644 --- a/app/assets/javascripts/jobs/store/mutations.js +++ b/app/assets/javascripts/jobs/store/mutations.js @@ -1,6 +1,9 @@ import * as types from './mutation_types'; export default { + [types.SET_JOB_ENDPOINT](state, endpoint) { + state.jobEndpoint = endpoint; + }, [types.REQUEST_STATUS_FAVICON](state) { state.fetchingStatusFavicon = true; }, diff --git a/app/assets/javascripts/jobs/stores/job_store.js b/app/assets/javascripts/jobs/stores/job_store.js deleted file mode 100644 index 766194b8387ac8484c59951da408d569de5dbf10..0000000000000000000000000000000000000000 --- a/app/assets/javascripts/jobs/stores/job_store.js +++ /dev/null @@ -1,11 +0,0 @@ -export default class JobStore { - constructor() { - this.state = { - job: {}, - }; - } - - storeJob(job = {}) { - this.state.job = job; - } -} diff --git a/changelogs/unreleased/50904-use-vuex-store-job.yml b/changelogs/unreleased/50904-use-vuex-store-job.yml new file mode 100644 index 0000000000000000000000000000000000000000..5b1112a4f5b82d2d8047811a0c56978646872930 --- /dev/null +++ b/changelogs/unreleased/50904-use-vuex-store-job.yml @@ -0,0 +1,5 @@ +--- +title: Uses Vuex store in job details page and removes old mediator pattern +merge_request: +author: +type: other diff --git a/spec/javascripts/jobs/components/job_details_mediator_spec.js b/spec/javascripts/jobs/components/job_details_mediator_spec.js deleted file mode 100644 index 3e2fb7bfbbbfddfcf6e7d483b88c5efb4c72f22b..0000000000000000000000000000000000000000 --- a/spec/javascripts/jobs/components/job_details_mediator_spec.js +++ /dev/null @@ -1,39 +0,0 @@ -import MockAdapter from 'axios-mock-adapter'; -import axios from '~/lib/utils/axios_utils'; -import JobMediator from '~/jobs/job_details_mediator'; -import job from '../mock_data'; - -describe('JobMediator', () => { - let mediator; - let mock; - - beforeEach(() => { - mediator = new JobMediator({ endpoint: 'jobs/40291672.json' }); - mock = new MockAdapter(axios); - }); - - afterEach(() => { - mock.restore(); - }); - - it('should set defaults', () => { - expect(mediator.store).toBeDefined(); - expect(mediator.service).toBeDefined(); - expect(mediator.options).toEqual({ endpoint: 'jobs/40291672.json' }); - expect(mediator.state.isLoading).toEqual(false); - }); - - describe('request and store data', () => { - beforeEach(() => { - mock.onGet().reply(200, job, {}); - }); - - it('should store received data', (done) => { - mediator.fetchJob(); - setTimeout(() => { - expect(mediator.store.state.job).toEqual(job); - done(); - }, 0); - }); - }); -}); diff --git a/spec/javascripts/jobs/components/job_store_spec.js b/spec/javascripts/jobs/components/job_store_spec.js deleted file mode 100644 index 0dad5111b3257ff30a7800f8777fecef19cc39b8..0000000000000000000000000000000000000000 --- a/spec/javascripts/jobs/components/job_store_spec.js +++ /dev/null @@ -1,26 +0,0 @@ -import JobStore from '~/jobs/stores/job_store'; -import job from '../mock_data'; - -describe('Job Store', () => { - let store; - - beforeEach(() => { - store = new JobStore(); - }); - - it('should set defaults', () => { - expect(store.state.job).toEqual({}); - }); - - describe('storeJob', () => { - it('should store empty object if none is provided', () => { - store.storeJob(); - expect(store.state.job).toEqual({}); - }); - - it('should store provided argument', () => { - store.storeJob(job); - expect(store.state.job).toEqual(job); - }); - }); -}); diff --git a/spec/javascripts/jobs/store/mutations_spec.js b/spec/javascripts/jobs/store/mutations_spec.js index 6900b2e56022351c9703974a64193092383af03b..9ba543d32a8495e1e4a0db19f1375572c94fb962 100644 --- a/spec/javascripts/jobs/store/mutations_spec.js +++ b/spec/javascripts/jobs/store/mutations_spec.js @@ -12,6 +12,13 @@ describe('Jobs Store Mutations', () => { stateCopy = state(); }); + describe('SET_JOB_ENDPOINT', () => { + it('should set jobEndpoint', () => { + mutations[types.SET_JOB_ENDPOINT](stateCopy, 'job/21312321.json'); + expect(stateCopy.jobEndpoint).toEqual('job/21312321.json'); + }); + }); + describe('REQUEST_STATUS_FAVICON', () => { it('should set fetchingStatusFavicon to true', () => { mutations[types.REQUEST_STATUS_FAVICON](stateCopy);