Commit fe46eb1b authored by Nathan Friend's avatar Nathan Friend Committed by Nicolò Maria Mezzopera

Update releases page to use state instead of props

This commit updates the releases page to store static data as Vuex state
instead of passing thee data to the Vue app as props.
parent c5915a7f
...@@ -25,31 +25,16 @@ export default { ...@@ -25,31 +25,16 @@ export default {
GlLink, GlLink,
GlButton, GlButton,
}, },
props: {
projectId: {
type: String,
required: true,
},
projectPath: {
type: String,
required: true,
},
documentationPath: {
type: String,
required: true,
},
illustrationPath: {
type: String,
required: true,
},
newReleasePath: {
type: String,
required: false,
default: '',
},
},
computed: { computed: {
...mapState('list', ['isLoading', 'releases', 'hasError', 'pageInfo']), ...mapState('list', [
'documentationPath',
'illustrationPath',
'newReleasePath',
'isLoading',
'releases',
'hasError',
'pageInfo',
]),
shouldRenderEmptyState() { shouldRenderEmptyState() {
return !this.releases.length && !this.hasError && !this.isLoading; return !this.releases.length && !this.hasError && !this.isLoading;
}, },
...@@ -65,15 +50,13 @@ export default { ...@@ -65,15 +50,13 @@ export default {
created() { created() {
this.fetchReleases({ this.fetchReleases({
page: getParameterByName('page'), page: getParameterByName('page'),
projectId: this.projectId,
projectPath: this.projectPath,
}); });
}, },
methods: { methods: {
...mapActions('list', ['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 });
}, },
}, },
}; };
......
...@@ -7,7 +7,7 @@ export default { ...@@ -7,7 +7,7 @@ export default {
name: 'ReleasesPaginationGraphql', name: 'ReleasesPaginationGraphql',
components: { GlKeysetPagination }, components: { GlKeysetPagination },
computed: { computed: {
...mapState('list', ['projectPath', 'graphQlPageInfo']), ...mapState('list', ['graphQlPageInfo']),
showPagination() { showPagination() {
return this.graphQlPageInfo.hasPreviousPage || this.graphQlPageInfo.hasNextPage; return this.graphQlPageInfo.hasPreviousPage || this.graphQlPageInfo.hasNextPage;
}, },
...@@ -16,11 +16,11 @@ export default { ...@@ -16,11 +16,11 @@ export default {
...mapActions('list', ['fetchReleasesGraphQl']), ...mapActions('list', ['fetchReleasesGraphQl']),
onPrev(before) { onPrev(before) {
historyPushState(buildUrlWithCurrentLocation(`?before=${before}`)); historyPushState(buildUrlWithCurrentLocation(`?before=${before}`));
this.fetchReleasesGraphQl({ projectPath: this.projectPath, before }); this.fetchReleasesGraphQl({ before });
}, },
onNext(after) { onNext(after) {
historyPushState(buildUrlWithCurrentLocation(`?after=${after}`)); historyPushState(buildUrlWithCurrentLocation(`?after=${after}`));
this.fetchReleasesGraphQl({ projectPath: this.projectPath, after }); this.fetchReleasesGraphQl({ after });
}, },
}, },
}; };
......
...@@ -7,13 +7,13 @@ export default { ...@@ -7,13 +7,13 @@ export default {
name: 'ReleasesPaginationRest', name: 'ReleasesPaginationRest',
components: { TablePagination }, components: { TablePagination },
computed: { computed: {
...mapState('list', ['projectId', 'pageInfo']), ...mapState('list', ['pageInfo']),
}, },
methods: { methods: {
...mapActions('list', ['fetchReleasesRest']), ...mapActions('list', ['fetchReleasesRest']),
onChangePage(page) { onChangePage(page) {
historyPushState(buildUrlWithCurrentLocation(`?page=${page}`)); historyPushState(buildUrlWithCurrentLocation(`?page=${page}`));
this.fetchReleasesRest({ page, projectId: this.projectId }); this.fetchReleasesRest({ page });
}, },
}, },
}; };
......
...@@ -21,9 +21,6 @@ export default () => { ...@@ -21,9 +21,6 @@ export default () => {
graphqlMilestoneStats: Boolean(gon.features?.graphqlMilestoneStats), graphqlMilestoneStats: Boolean(gon.features?.graphqlMilestoneStats),
}, },
}), }),
render: h => render: h => h(ReleaseListApp),
h(ReleaseListApp, {
props: el.dataset,
}),
}); });
}; };
...@@ -23,7 +23,7 @@ export const requestReleases = ({ commit }) => commit(types.REQUEST_RELEASES); ...@@ -23,7 +23,7 @@ export const requestReleases = ({ commit }) => commit(types.REQUEST_RELEASES);
* *
* @param {String} projectId * @param {String} projectId
*/ */
export const fetchReleases = ({ dispatch, rootState }, { page = '1', projectId, projectPath }) => { export const fetchReleases = ({ dispatch, rootState, state }, { page = '1' }) => {
dispatch('requestReleases'); dispatch('requestReleases');
if ( if (
...@@ -35,7 +35,7 @@ export const fetchReleases = ({ dispatch, rootState }, { page = '1', projectId, ...@@ -35,7 +35,7 @@ export const fetchReleases = ({ dispatch, rootState }, { page = '1', projectId,
.query({ .query({
query: allReleasesQuery, query: allReleasesQuery,
variables: { variables: {
fullPath: projectPath, fullPath: state.projectPath,
}, },
}) })
.then(response => { .then(response => {
...@@ -44,7 +44,7 @@ export const fetchReleases = ({ dispatch, rootState }, { page = '1', projectId, ...@@ -44,7 +44,7 @@ export const fetchReleases = ({ dispatch, rootState }, { page = '1', projectId,
.catch(() => dispatch('receiveReleasesError')); .catch(() => dispatch('receiveReleasesError'));
} else { } else {
api api
.releases(projectId, { page }) .releases(state.projectId, { page })
.then(response => dispatch('receiveReleasesSuccess', response)) .then(response => dispatch('receiveReleasesSuccess', response))
.catch(() => dispatch('receiveReleasesError')); .catch(() => dispatch('receiveReleasesError'));
} }
......
...@@ -27,15 +27,18 @@ describe('Releases App ', () => { ...@@ -27,15 +27,18 @@ describe('Releases App ', () => {
tagName: `${index}.00`, tagName: `${index}.00`,
})); }));
const defaultProps = { const defaultInitialState = {
projectId: 'gitlab-ce', projectId: 'gitlab-ce',
projectPath: 'gitlab-org/gitlab-ce', projectPath: 'gitlab-org/gitlab-ce',
documentationPath: 'help/releases', documentationPath: 'help/releases',
illustrationPath: 'illustration/path', illustrationPath: 'illustration/path',
}; };
const createComponent = (propsData = defaultProps) => { const createComponent = (stateUpdates = {}) => {
const listModule = createListModule({}); const listModule = createListModule({
...defaultInitialState,
...stateUpdates,
});
fetchReleaseSpy = jest.spyOn(listModule.actions, 'fetchReleases'); fetchReleaseSpy = jest.spyOn(listModule.actions, 'fetchReleases');
...@@ -51,7 +54,6 @@ describe('Releases App ', () => { ...@@ -51,7 +54,6 @@ describe('Releases App ', () => {
wrapper = shallowMount(ReleasesApp, { wrapper = shallowMount(ReleasesApp, {
store, store,
localVue, localVue,
propsData,
}); });
}; };
...@@ -68,13 +70,9 @@ describe('Releases App ', () => { ...@@ -68,13 +70,9 @@ describe('Releases App ', () => {
createComponent(); createComponent();
}); });
it('calls fetchRelease with the page, project ID, and project path', () => { it('calls fetchRelease with the page parameter', () => {
expect(fetchReleaseSpy).toHaveBeenCalledTimes(1); expect(fetchReleaseSpy).toHaveBeenCalledTimes(1);
expect(fetchReleaseSpy).toHaveBeenCalledWith(expect.anything(), { expect(fetchReleaseSpy).toHaveBeenCalledWith(expect.anything(), { page: null });
page: null,
projectId: defaultProps.projectId,
projectPath: defaultProps.projectPath,
});
}); });
}); });
...@@ -156,7 +154,7 @@ describe('Releases App ', () => { ...@@ -156,7 +154,7 @@ describe('Releases App ', () => {
const newReleasePath = 'path/to/new/release'; const newReleasePath = 'path/to/new/release';
beforeEach(() => { beforeEach(() => {
createComponent({ ...defaultProps, newReleasePath }); createComponent({ ...defaultInitialState, newReleasePath });
}); });
it('renders the "New release" button', () => { it('renders the "New release" button', () => {
......
...@@ -143,7 +143,7 @@ describe('~/releases/components/releases_pagination_graphql.vue', () => { ...@@ -143,7 +143,7 @@ describe('~/releases/components/releases_pagination_graphql.vue', () => {
it('calls fetchReleasesGraphQl with the correct after cursor', () => { it('calls fetchReleasesGraphQl with the correct after cursor', () => {
expect(listModule.actions.fetchReleasesGraphQl.mock.calls).toEqual([ expect(listModule.actions.fetchReleasesGraphQl.mock.calls).toEqual([
[expect.anything(), { projectPath, after: cursors.endCursor }], [expect.anything(), { after: cursors.endCursor }],
]); ]);
}); });
...@@ -161,7 +161,7 @@ describe('~/releases/components/releases_pagination_graphql.vue', () => { ...@@ -161,7 +161,7 @@ describe('~/releases/components/releases_pagination_graphql.vue', () => {
it('calls fetchReleasesGraphQl with the correct before cursor', () => { it('calls fetchReleasesGraphQl with the correct before cursor', () => {
expect(listModule.actions.fetchReleasesGraphQl.mock.calls).toEqual([ expect(listModule.actions.fetchReleasesGraphQl.mock.calls).toEqual([
[expect.anything(), { projectPath, before: cursors.startCursor }], [expect.anything(), { before: cursors.startCursor }],
]); ]);
}); });
......
...@@ -59,7 +59,7 @@ describe('~/releases/components/releases_pagination_rest.vue', () => { ...@@ -59,7 +59,7 @@ describe('~/releases/components/releases_pagination_rest.vue', () => {
it('calls fetchReleasesRest with the correct page', () => { it('calls fetchReleasesRest with the correct page', () => {
expect(listModule.actions.fetchReleasesRest.mock.calls).toEqual([ expect(listModule.actions.fetchReleasesRest.mock.calls).toEqual([
[expect.anything(), { projectId, page: newPage }], [expect.anything(), { page: newPage }],
]); ]);
}); });
......
...@@ -23,11 +23,16 @@ describe('Releases State actions', () => { ...@@ -23,11 +23,16 @@ describe('Releases State actions', () => {
let pageInfo; let pageInfo;
let releases; let releases;
let graphqlReleasesResponse; let graphqlReleasesResponse;
let projectPath;
const projectPath = 'root/test-project';
const projectId = 19;
beforeEach(() => { beforeEach(() => {
mockedState = { mockedState = {
...createState({}), ...createState({
projectId,
projectPath,
}),
featureFlags: { featureFlags: {
graphqlReleaseData: true, graphqlReleaseData: true,
graphqlReleasesPage: true, graphqlReleasesPage: true,
...@@ -38,7 +43,6 @@ describe('Releases State actions', () => { ...@@ -38,7 +43,6 @@ describe('Releases State actions', () => {
pageInfo = parseIntPagination(pageInfoHeadersWithoutPagination); pageInfo = parseIntPagination(pageInfoHeadersWithoutPagination);
releases = convertObjectPropsToCamelCase(originalReleases, { deep: true }); releases = convertObjectPropsToCamelCase(originalReleases, { deep: true });
graphqlReleasesResponse = cloneDeep(originalGraphqlReleasesResponse); graphqlReleasesResponse = cloneDeep(originalGraphqlReleasesResponse);
projectPath = 'root/test-project';
}); });
describe('requestReleases', () => { describe('requestReleases', () => {
...@@ -51,7 +55,7 @@ describe('Releases State actions', () => { ...@@ -51,7 +55,7 @@ describe('Releases State actions', () => {
describe('success', () => { describe('success', () => {
it('dispatches requestReleases and receiveReleasesSuccess', done => { it('dispatches requestReleases and receiveReleasesSuccess', done => {
jest.spyOn(gqClient, 'query').mockImplementation(({ query, variables }) => { jest.spyOn(gqClient, 'query').mockImplementation(({ query, variables }) => {
expect(query).toEqual(allReleasesQuery); expect(query).toBe(allReleasesQuery);
expect(variables).toEqual({ expect(variables).toEqual({
fullPath: projectPath, fullPath: projectPath,
}); });
...@@ -60,7 +64,7 @@ describe('Releases State actions', () => { ...@@ -60,7 +64,7 @@ describe('Releases State actions', () => {
testAction( testAction(
fetchReleases, fetchReleases,
{ projectPath }, {},
mockedState, mockedState,
[], [],
[ [
...@@ -83,7 +87,7 @@ describe('Releases State actions', () => { ...@@ -83,7 +87,7 @@ describe('Releases State actions', () => {
testAction( testAction(
fetchReleases, fetchReleases,
{ projectPath }, {},
mockedState, mockedState,
[], [],
[ [
...@@ -107,14 +111,14 @@ describe('Releases State actions', () => { ...@@ -107,14 +111,14 @@ describe('Releases State actions', () => {
describe('success', () => { describe('success', () => {
it('dispatches requestReleases and receiveReleasesSuccess', done => { it('dispatches requestReleases and receiveReleasesSuccess', done => {
jest.spyOn(api, 'releases').mockImplementation((id, options) => { jest.spyOn(api, 'releases').mockImplementation((id, options) => {
expect(id).toEqual(1); expect(id).toBe(projectId);
expect(options.page).toEqual('1'); expect(options.page).toBe('1');
return Promise.resolve({ data: releases, headers: pageInfoHeadersWithoutPagination }); return Promise.resolve({ data: releases, headers: pageInfoHeadersWithoutPagination });
}); });
testAction( testAction(
fetchReleases, fetchReleases,
{ projectId: 1 }, {},
mockedState, mockedState,
[], [],
[ [
...@@ -132,13 +136,13 @@ describe('Releases State actions', () => { ...@@ -132,13 +136,13 @@ describe('Releases State actions', () => {
it('dispatches requestReleases and receiveReleasesSuccess on page two', done => { it('dispatches requestReleases and receiveReleasesSuccess on page two', done => {
jest.spyOn(api, 'releases').mockImplementation((_, options) => { jest.spyOn(api, 'releases').mockImplementation((_, options) => {
expect(options.page).toEqual('2'); expect(options.page).toBe('2');
return Promise.resolve({ data: releases, headers: pageInfoHeadersWithoutPagination }); return Promise.resolve({ data: releases, headers: pageInfoHeadersWithoutPagination });
}); });
testAction( testAction(
fetchReleases, fetchReleases,
{ page: '2', projectId: 1 }, { page: '2' },
mockedState, mockedState,
[], [],
[ [
...@@ -161,7 +165,7 @@ describe('Releases State actions', () => { ...@@ -161,7 +165,7 @@ describe('Releases State actions', () => {
testAction( testAction(
fetchReleases, fetchReleases,
{ projectId: null }, {},
mockedState, mockedState,
[], [],
[ [
......
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