Commit 9b20b0ab authored by Nicolò Maria Mezzopera's avatar Nicolò Maria Mezzopera

Merge branch 'nfriend-releases-page-add-static-data-to-state' into 'master'

Step 3/4: Update Releases page to use Vuex state instead of props

See merge request gitlab-org/gitlab!41636
parents d00aff48 fe46eb1b
...@@ -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