Commit 01dae627 authored by Nathan Friend's avatar Nathan Friend

Reorganize releases/** code in preparation for "show" page

This commit updates the releases/** code to allow more Vuex pages to be
added in the future. In particular, this work is in preparation for the
new dedicated Release page (a "show" page) being added in the
near future.
parent d887cda0
import ZenMode from '~/zen_mode'; import ZenMode from '~/zen_mode';
import initEditRelease from '~/releases/detail'; import initEditRelease from '~/releases/mount_edit';
document.addEventListener('DOMContentLoaded', () => { document.addEventListener('DOMContentLoaded', () => {
new ZenMode(); // eslint-disable-line no-new new ZenMode(); // eslint-disable-line no-new
......
import initReleases from '~/releases/list'; import initReleases from '~/releases/mount_index';
document.addEventListener('DOMContentLoaded', initReleases); document.addEventListener('DOMContentLoaded', initReleases);
...@@ -7,7 +7,7 @@ import MarkdownField from '~/vue_shared/components/markdown/field.vue'; ...@@ -7,7 +7,7 @@ import MarkdownField from '~/vue_shared/components/markdown/field.vue';
import autofocusonshow from '~/vue_shared/directives/autofocusonshow'; import autofocusonshow from '~/vue_shared/directives/autofocusonshow';
export default { export default {
name: 'ReleaseDetailApp', name: 'ReleaseEditApp',
components: { components: {
GlFormInput, GlFormInput,
GlFormGroup, GlFormGroup,
...@@ -18,7 +18,7 @@ export default { ...@@ -18,7 +18,7 @@ export default {
autofocusonshow, autofocusonshow,
}, },
computed: { computed: {
...mapState([ ...mapState('detail', [
'isFetchingRelease', 'isFetchingRelease',
'fetchError', 'fetchError',
'markdownDocsPath', 'markdownDocsPath',
...@@ -42,7 +42,7 @@ export default { ...@@ -42,7 +42,7 @@ export default {
); );
}, },
tagName() { tagName() {
return this.$store.state.release.tagName; return this.$store.state.detail.release.tagName;
}, },
tagNameHintText() { tagNameHintText() {
return sprintf( return sprintf(
...@@ -60,7 +60,7 @@ export default { ...@@ -60,7 +60,7 @@ export default {
}, },
releaseTitle: { releaseTitle: {
get() { get() {
return this.$store.state.release.name; return this.$store.state.detail.release.name;
}, },
set(title) { set(title) {
this.updateReleaseTitle(title); this.updateReleaseTitle(title);
...@@ -68,7 +68,7 @@ export default { ...@@ -68,7 +68,7 @@ export default {
}, },
releaseNotes: { releaseNotes: {
get() { get() {
return this.$store.state.release.description; return this.$store.state.detail.release.description;
}, },
set(notes) { set(notes) {
this.updateReleaseNotes(notes); this.updateReleaseNotes(notes);
...@@ -79,7 +79,7 @@ export default { ...@@ -79,7 +79,7 @@ export default {
this.fetchRelease(); this.fetchRelease();
}, },
methods: { methods: {
...mapActions([ ...mapActions('detail', [
'fetchRelease', 'fetchRelease',
'updateRelease', 'updateRelease',
'updateReleaseTitle', 'updateReleaseTitle',
......
...@@ -32,7 +32,7 @@ export default { ...@@ -32,7 +32,7 @@ export default {
}, },
}, },
computed: { computed: {
...mapState(['isLoading', 'releases', 'hasError', 'pageInfo']), ...mapState('list', ['isLoading', 'releases', 'hasError', 'pageInfo']),
shouldRenderEmptyState() { shouldRenderEmptyState() {
return !this.releases.length && !this.hasError && !this.isLoading; return !this.releases.length && !this.hasError && !this.isLoading;
}, },
...@@ -47,7 +47,7 @@ export default { ...@@ -47,7 +47,7 @@ export default {
}); });
}, },
methods: { methods: {
...mapActions(['fetchReleases']), ...mapActions('list', ['fetchReleases']),
onChangePage(page) { onChangePage(page) {
historyPushState(buildUrlWithCurrentLocation(`?page=${page}`)); historyPushState(buildUrlWithCurrentLocation(`?page=${page}`));
this.fetchReleases({ page, projectId: this.projectId }); this.fetchReleases({ page, projectId: this.projectId });
......
import Vue from 'vue';
import App from './components/app.vue';
import createStore from './store';
export default () => {
const element = document.getElementById('js-releases-page');
return new Vue({
el: element,
store: createStore(),
components: {
App,
},
render(createElement) {
return createElement('app', {
props: {
projectId: element.dataset.projectId,
documentationLink: element.dataset.documentationPath,
illustrationPath: element.dataset.illustrationPath,
},
});
},
});
};
import Vue from 'vue'; import Vue from 'vue';
import ReleaseDetailApp from './components/app.vue'; import ReleaseEditApp from './components/app_edit.vue';
import createStore from './store'; import createStore from './stores';
import detailModule from './stores/modules/detail';
export default () => { export default () => {
const el = document.getElementById('js-edit-release-page'); const el = document.getElementById('js-edit-release-page');
const store = createStore(); const store = createStore({ detail: detailModule });
store.dispatch('setInitialState', el.dataset); store.dispatch('setInitialState', el.dataset);
return new Vue({ return new Vue({
el, el,
store, store,
components: { ReleaseDetailApp }, render: h => h(ReleaseEditApp),
render(createElement) {
return createElement('release-detail-app');
},
}); });
}; };
import Vue from 'vue';
import ReleaseListApp from './components/app_index.vue';
import createStore from './stores';
import listModule from './stores/modules/list';
export default () => {
const el = document.getElementById('js-releases-page');
return new Vue({
el,
store: createStore({ list: listModule }),
render: h =>
h(ReleaseListApp, {
props: {
projectId: el.dataset.projectId,
documentationLink: el.dataset.documentationPath,
illustrationPath: el.dataset.illustrationPath,
},
}),
});
};
import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex);
export default modules => new Vuex.Store({ modules });
import Vue from 'vue';
import Vuex from 'vuex';
import * as actions from './actions'; import * as actions from './actions';
import mutations from './mutations'; import mutations from './mutations';
import state from './state'; import state from './state';
Vue.use(Vuex); export default {
namespaced: true,
export default () => actions,
new Vuex.Store({ mutations,
actions, state,
mutations, };
state,
});
import Vue from 'vue';
import Vuex from 'vuex';
import state from './state'; import state from './state';
import * as actions from './actions'; import * as actions from './actions';
import mutations from './mutations'; import mutations from './mutations';
Vue.use(Vuex); export default {
namespaced: true,
export default () => actions,
new Vuex.Store({ mutations,
actions, state,
mutations, };
state: state(),
});
import Vuex from 'vuex'; import Vuex from 'vuex';
import { mount } from '@vue/test-utils'; import { mount } from '@vue/test-utils';
import ReleaseDetailApp from '~/releases/detail/components/app.vue'; import ReleaseEditApp from '~/releases/components/app_edit.vue';
import { release } from '../../mock_data'; import { release } from '../mock_data';
import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils'; import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils';
describe('Release detail component', () => { describe('Release edit component', () => {
let wrapper; let wrapper;
let releaseClone; let releaseClone;
let actions; let actions;
...@@ -27,9 +27,17 @@ describe('Release detail component', () => { ...@@ -27,9 +27,17 @@ describe('Release detail component', () => {
navigateToReleasesPage: jest.fn(), navigateToReleasesPage: jest.fn(),
}; };
const store = new Vuex.Store({ actions, state }); const store = new Vuex.Store({
modules: {
detail: {
namespaced: true,
actions,
state,
},
},
});
wrapper = mount(ReleaseDetailApp, { wrapper = mount(ReleaseEditApp, {
store, store,
}); });
......
...@@ -2,8 +2,8 @@ import { mount } from '@vue/test-utils'; ...@@ -2,8 +2,8 @@ import { mount } from '@vue/test-utils';
import { GlLink } from '@gitlab/ui'; import { GlLink } from '@gitlab/ui';
import { truncateSha } from '~/lib/utils/text_utility'; import { truncateSha } from '~/lib/utils/text_utility';
import Icon from '~/vue_shared/components/icon.vue'; import Icon from '~/vue_shared/components/icon.vue';
import { release } from '../../mock_data'; import { release } from '../mock_data';
import EvidenceBlock from '~/releases/list/components/evidence_block.vue'; import EvidenceBlock from '~/releases/components/evidence_block.vue';
import ClipboardButton from '~/vue_shared/components/clipboard_button.vue'; import ClipboardButton from '~/vue_shared/components/clipboard_button.vue';
describe('Evidence Block', () => { describe('Evidence Block', () => {
......
import { mount } from '@vue/test-utils'; import { mount } from '@vue/test-utils';
import { GlLink } from '@gitlab/ui'; import { GlLink } from '@gitlab/ui';
import { trimText } from 'helpers/text_helper'; import { trimText } from 'helpers/text_helper';
import ReleaseBlockFooter from '~/releases/list/components/release_block_footer.vue'; import ReleaseBlockFooter from '~/releases/components/release_block_footer.vue';
import Icon from '~/vue_shared/components/icon.vue'; import Icon from '~/vue_shared/components/icon.vue';
import { release } from '../../mock_data'; import { release } from '../mock_data';
import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils'; import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils';
jest.mock('~/vue_shared/mixins/timeago', () => ({ jest.mock('~/vue_shared/mixins/timeago', () => ({
......
import { shallowMount } from '@vue/test-utils'; import { shallowMount } from '@vue/test-utils';
import { cloneDeep, merge } from 'lodash'; import { cloneDeep, merge } from 'lodash';
import { GlLink } from '@gitlab/ui'; import { GlLink } from '@gitlab/ui';
import ReleaseBlockHeader from '~/releases/list/components/release_block_header.vue'; import ReleaseBlockHeader from '~/releases/components/release_block_header.vue';
import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils'; import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils';
import { release as originalRelease } from '../../mock_data'; import { release as originalRelease } from '../mock_data';
describe('Release block header', () => { describe('Release block header', () => {
let wrapper; let wrapper;
......
import { mount } from '@vue/test-utils'; import { mount } from '@vue/test-utils';
import { GlProgressBar, GlLink, GlBadge, GlButton } from '@gitlab/ui'; import { GlProgressBar, GlLink, GlBadge, GlButton } from '@gitlab/ui';
import { trimText } from 'helpers/text_helper'; import { trimText } from 'helpers/text_helper';
import ReleaseBlockMilestoneInfo from '~/releases/list/components/release_block_milestone_info.vue'; import ReleaseBlockMilestoneInfo from '~/releases/components/release_block_milestone_info.vue';
import { milestones } from '../../mock_data'; import { milestones } from '../mock_data';
import { MAX_MILESTONES_TO_DISPLAY } from '~/releases/list/constants'; import { MAX_MILESTONES_TO_DISPLAY } from '~/releases/constants';
describe('Release block milestone info', () => { describe('Release block milestone info', () => {
let wrapper; let wrapper;
......
import $ from 'jquery'; import $ from 'jquery';
import { mount } from '@vue/test-utils'; import { mount } from '@vue/test-utils';
import { first } from 'underscore'; import { first } from 'underscore';
import EvidenceBlock from '~/releases/list/components/evidence_block.vue'; import EvidenceBlock from '~/releases/components/evidence_block.vue';
import ReleaseBlock from '~/releases/list/components/release_block.vue'; import ReleaseBlock from '~/releases/components/release_block.vue';
import ReleaseBlockFooter from '~/releases/list/components/release_block_footer.vue'; import ReleaseBlockFooter from '~/releases/components/release_block_footer.vue';
import timeagoMixin from '~/vue_shared/mixins/timeago'; import timeagoMixin from '~/vue_shared/mixins/timeago';
import { release } from '../../mock_data'; import { release } from '../mock_data';
import Icon from '~/vue_shared/components/icon.vue'; import Icon from '~/vue_shared/components/icon.vue';
import { scrollToElement } from '~/lib/utils/common_utils'; import { scrollToElement } from '~/lib/utils/common_utils';
......
import axios from 'axios'; import axios from 'axios';
import MockAdapter from 'axios-mock-adapter'; import MockAdapter from 'axios-mock-adapter';
import testAction from 'helpers/vuex_action_helper'; import testAction from 'helpers/vuex_action_helper';
import * as actions from '~/releases/detail/store/actions'; import * as actions from '~/releases/stores/modules/detail/actions';
import * as types from '~/releases/detail/store/mutation_types'; import * as types from '~/releases/stores/modules/detail/mutation_types';
import { release } from '../../mock_data'; import { release } from '../../../mock_data';
import state from '~/releases/detail/store/state'; import state from '~/releases/stores/modules/detail/state';
import createFlash from '~/flash'; import createFlash from '~/flash';
import { redirectTo } from '~/lib/utils/url_utility'; import { redirectTo } from '~/lib/utils/url_utility';
import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils'; import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils';
......
...@@ -5,10 +5,10 @@ ...@@ -5,10 +5,10 @@
* is resolved * is resolved
*/ */
import state from '~/releases/detail/store/state'; import state from '~/releases/stores/modules/detail/state';
import mutations from '~/releases/detail/store/mutations'; import mutations from '~/releases/stores/modules/detail/mutations';
import * as types from '~/releases/detail/store/mutation_types'; import * as types from '~/releases/stores/modules/detail/mutation_types';
import { release } from '../../mock_data'; import { release } from '../../../mock_data';
describe('Release detail mutations', () => { describe('Release detail mutations', () => {
let stateClone; let stateClone;
......
import _ from 'underscore'; import _ from 'underscore';
import Vue from 'vue'; import Vue from 'vue';
import { mountComponentWithStore } from 'spec/helpers/vue_mount_component_helper'; import { mountComponentWithStore } from 'spec/helpers/vue_mount_component_helper';
import app from '~/releases/list/components/app.vue'; import app from '~/releases/components/app_index.vue';
import createStore from '~/releases/list/store'; import createStore from '~/releases/stores';
import listModule from '~/releases/stores/modules/list';
import api from '~/api'; import api from '~/api';
import { resetStore } from '../store/helpers'; import { resetStore } from '../stores/modules/list/helpers';
import { import {
pageInfoHeadersWithoutPagination, pageInfoHeadersWithoutPagination,
pageInfoHeadersWithPagination, pageInfoHeadersWithPagination,
release, release,
releases, releases,
} from '../../mock_data'; } from '../mock_data';
describe('Releases App ', () => { describe('Releases App ', () => {
const Component = Vue.extend(app); const Component = Vue.extend(app);
...@@ -25,7 +26,7 @@ describe('Releases App ', () => { ...@@ -25,7 +26,7 @@ describe('Releases App ', () => {
}; };
beforeEach(() => { beforeEach(() => {
store = createStore(); store = createStore({ list: listModule });
releasesPagination = _.range(21).map(index => ({ ...release, tag_name: `${index}.00` })); releasesPagination = _.range(21).map(index => ({ ...release, tag_name: `${index}.00` }));
}); });
......
...@@ -4,12 +4,12 @@ import { ...@@ -4,12 +4,12 @@ import {
fetchReleases, fetchReleases,
receiveReleasesSuccess, receiveReleasesSuccess,
receiveReleasesError, receiveReleasesError,
} from '~/releases/list/store/actions'; } from '~/releases/stores/modules/list/actions';
import state from '~/releases/list/store/state'; import state from '~/releases/stores/modules/list/state';
import * as types from '~/releases/list/store/mutation_types'; import * as types from '~/releases/stores/modules/list/mutation_types';
import api from '~/api'; import api from '~/api';
import { parseIntPagination } from '~/lib/utils/common_utils'; import { parseIntPagination } from '~/lib/utils/common_utils';
import { pageInfoHeadersWithoutPagination, releases } from '../../mock_data'; import { pageInfoHeadersWithoutPagination, releases } from '../../../mock_data';
describe('Releases State actions', () => { describe('Releases State actions', () => {
let mockedState; let mockedState;
......
import state from '~/releases/list/store/state'; import state from '~/releases/stores/modules/list/state';
// eslint-disable-next-line import/prefer-default-export // eslint-disable-next-line import/prefer-default-export
export const resetStore = store => { export const resetStore = store => {
......
import state from '~/releases/list/store/state'; import state from '~/releases/stores/modules/list/state';
import mutations from '~/releases/list/store/mutations'; import mutations from '~/releases/stores/modules/list/mutations';
import * as types from '~/releases/list/store/mutation_types'; import * as types from '~/releases/stores/modules/list/mutation_types';
import { parseIntPagination } from '~/lib/utils/common_utils'; import { parseIntPagination } from '~/lib/utils/common_utils';
import { pageInfoHeadersWithoutPagination, releases } from '../../mock_data'; import { pageInfoHeadersWithoutPagination, releases } from '../../../mock_data';
describe('Releases Store Mutations', () => { describe('Releases Store Mutations', () => {
let stateCopy; let stateCopy;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment