Commit 1b15b3b8 authored by Enrique Alcantara's avatar Enrique Alcantara

Load source page content Vuex workflow

Implements required actions, mutations, and getters
to load source page into the static site editor
parent ee0541cc
<script>
import { mapState, mapActions } from 'vuex';
import { mapState, mapGetters, mapActions } from 'vuex';
import { GlSkeletonLoader } from '@gitlab/ui';
import EditArea from './edit_area.vue';
......@@ -10,7 +10,8 @@ export default {
GlSkeletonLoader,
},
computed: {
...mapState(['content', 'isContentLoaded', 'isLoadingContent']),
...mapState(['content', 'isLoadingContent']),
...mapGetters(['isContentLoaded']),
},
mounted() {
this.loadContent();
......
......@@ -3,7 +3,11 @@ import StaticSiteEditor from './components/static_site_editor.vue';
import createStore from './store';
const initStaticSiteEditor = el => {
const store = createStore();
const { projectId, path: sourcePath } = el.dataset;
const store = createStore({
initialState: { projectId, sourcePath },
});
return new Vue({
el,
......
import createFlash from '~/flash';
import { __ } from '~/locale';
import * as mutationTypes from './mutation_types';
import loadSourceContent from '~/static_site_editor/services/load_source_content';
export const loadContent = ({ commit, state: { sourcePath, projectId } }) => {
commit(mutationTypes.LOAD_CONTENT);
return loadSourceContent({ sourcePath, projectId })
.then(data => commit(mutationTypes.RECEIVE_CONTENT_SUCCESS, data))
.catch(() => {
commit(mutationTypes.RECEIVE_CONTENT_ERROR);
createFlash(__('An error ocurred while loading your content. Please try again.'));
});
};
export default () => {};
// eslint-disable-next-line import/prefer-default-export
export const isContentLoaded = ({ content }) => Boolean(content);
import Vuex from 'vuex';
import Vue from 'vue';
import createState from './state';
import * as getters from './getters';
import * as actions from './actions';
import mutations from './mutations';
Vue.use(Vuex);
const createStore = ({ initialState } = {}) => {
return new Vuex.Store({
state: createState(initialState),
getters,
actions,
mutations,
});
};
......
export const LOAD_CONTENT = 'loadContent';
export const RECEIVE_CONTENT_SUCCESS = 'receiveContentSuccess';
export const RECEIVE_CONTENT_ERROR = 'receiveContentError';
import * as types from './mutation_types';
export default {
[types.LOAD_CONTENT](state) {
state.isLoadingContent = true;
},
[types.RECEIVE_CONTENT_SUCCESS](state, { title, content }) {
state.isLoadingContent = false;
state.title = title;
state.content = content;
},
[types.RECEIVE_CONTENT_ERROR](state) {
state.isLoadingContent = false;
},
};
const createState = (initialState = {}) => ({
projectId: null,
sourcePath: null,
isLoadingContent: false,
isContentLoaded: false,
content: '',
title: '',
...initialState,
});
......
......@@ -2063,6 +2063,9 @@ msgstr ""
msgid "An error occurred. Please try again."
msgstr ""
msgid "An error ocurred while loading your content. Please try again."
msgstr ""
msgid "An instance-level serverless domain already exists."
msgstr ""
......
......@@ -17,11 +17,15 @@ describe('StaticSiteEditor', () => {
let store;
let loadContentActionMock;
const buildStore = (initialState = {}) => {
const buildStore = ({ initialState, getters } = {}) => {
loadContentActionMock = jest.fn();
store = new Vuex.Store({
state: createState(initialState),
getters: {
isContentLoaded: () => false,
...getters,
},
actions: {
loadContent: loadContentActionMock,
},
......@@ -56,7 +60,7 @@ describe('StaticSiteEditor', () => {
const content = 'edit area content';
beforeEach(() => {
buildStore({ content, isContentLoaded: true });
buildStore({ initialState: { content }, getters: { isContentLoaded: () => true } });
buildWrapper();
});
......@@ -70,7 +74,7 @@ describe('StaticSiteEditor', () => {
});
it('displays skeleton loader while loading content', () => {
buildStore({ isLoadingContent: true });
buildStore({ initialState: { isLoadingContent: true } });
buildWrapper();
expect(wrapper.find(GlSkeletonLoader).exists()).toBe(true);
......
import testAction from 'helpers/vuex_action_helper';
import createState from '~/static_site_editor/store/state';
import * as actions from '~/static_site_editor/store/actions';
import * as mutationTypes from '~/static_site_editor/store/mutation_types';
import loadSourceContent from '~/static_site_editor/services/load_source_content';
import createFlash from '~/flash';
import {
projectId,
sourcePath,
sourceContentTitle as title,
sourceContent as content,
} from '../mock_data';
jest.mock('~/flash');
jest.mock('~/static_site_editor/services/load_source_content', () => jest.fn());
describe('Static Site Editor Store actions', () => {
let state;
beforeEach(() => {
state = createState({
projectId,
sourcePath,
});
});
describe('loadContent', () => {
describe('on success', () => {
const payload = { title, content };
beforeEach(() => {
loadSourceContent.mockResolvedValueOnce(payload);
});
it('commits receiveContentSuccess', () => {
testAction(
actions.loadContent,
null,
state,
[
{ type: mutationTypes.LOAD_CONTENT },
{ type: mutationTypes.RECEIVE_CONTENT_SUCCESS, payload },
],
[],
);
expect(loadSourceContent).toHaveBeenCalledWith({ projectId, sourcePath });
});
});
describe('on error', () => {
const expectedMutations = [
{ type: mutationTypes.LOAD_CONTENT },
{ type: mutationTypes.RECEIVE_CONTENT_ERROR },
];
beforeEach(() => {
loadSourceContent.mockRejectedValueOnce();
});
it('commits receiveContentError', () => {
testAction(actions.loadContent, null, state, expectedMutations);
});
it('displays flash communicating error', () => {
return testAction(actions.loadContent, null, state, expectedMutations).then(() => {
expect(createFlash).toHaveBeenCalledWith(
'An error ocurred while loading your content. Please try again.',
);
});
});
});
});
});
import createState from '~/static_site_editor/store/state';
import { isContentLoaded } from '~/static_site_editor/store/getters';
import { sourceContent as content } from '../mock_data';
describe('Static Site Editor Store getters', () => {
describe('isContentLoaded', () => {
it('returns true when content is not empty', () => {
expect(isContentLoaded(createState({ content }))).toBe(true);
});
it('returns false when content is empty', () => {
expect(isContentLoaded(createState({ content: '' }))).toBe(false);
});
});
});
import createState from '~/static_site_editor/store/state';
import mutations from '~/static_site_editor/store/mutations';
import * as types from '~/static_site_editor/store/mutation_types';
import { sourceContentTitle as title, sourceContent as content } from '../mock_data';
describe('Static Site Editor Store mutations', () => {
let state;
beforeEach(() => {
state = createState();
});
describe('loadContent', () => {
beforeEach(() => {
mutations[types.LOAD_CONTENT](state);
});
it('sets isLoadingContent to true', () => {
expect(state.isLoadingContent).toBe(true);
});
});
describe('receiveContentSuccess', () => {
const payload = { title, content };
beforeEach(() => {
mutations[types.RECEIVE_CONTENT_SUCCESS](state, payload);
});
it('sets current state to LOADING', () => {
expect(state.isLoadingContent).toBe(false);
});
it('sets title', () => {
expect(state.title).toBe(payload.title);
});
it('sets content', () => {
expect(state.content).toBe(payload.content);
});
});
describe('receiveContentError', () => {
beforeEach(() => {
mutations[types.RECEIVE_CONTENT_ERROR](state);
});
it('sets current state to LOADING_ERROR', () => {
expect(state.isLoadingContent).toBe(false);
});
});
});
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