Commit c5802dcf authored by Natalia Tepluhina's avatar Natalia Tepluhina

Merge branch '212559-sse-header' into 'master'

Add EditHeader component and spec

See merge request gitlab-org/gitlab!29191
parents fff367ce 71636d36
<script>
import { DEFAULT_HEADING } from '../constants';
export default {
props: {
title: {
type: String,
required: false,
default: '',
},
},
computed: {
heading() {
return this.title || DEFAULT_HEADING;
},
},
};
</script>
<template>
<div>
<h3 ref="sseHeading">{{ heading }}</h3>
</div>
</template>
......@@ -7,6 +7,11 @@ export default {
GlLoadingIcon,
},
props: {
returnUrl: {
type: String,
required: false,
default: '',
},
saveable: {
type: Boolean,
required: false,
......@@ -23,6 +28,10 @@ export default {
<template>
<div class="d-flex bg-light border-top justify-content-between align-items-center py-3 px-4">
<gl-loading-icon :class="{ invisible: !savingChanges }" size="md" />
<div>
<gl-new-button v-if="returnUrl" ref="returnUrlLink" :href="returnUrl">{{
s__('StaticSiteEditor|Return to site')
}}</gl-new-button>
<gl-new-button
variant="success"
:disabled="!saveable || savingChanges"
......@@ -31,4 +40,5 @@ export default {
{{ __('Submit Changes') }}
</gl-new-button>
</div>
</div>
</template>
......@@ -3,16 +3,25 @@ import { mapState, mapGetters, mapActions } from 'vuex';
import { GlSkeletonLoader } from '@gitlab/ui';
import EditArea from './edit_area.vue';
import EditHeader from './edit_header.vue';
import Toolbar from './publish_toolbar.vue';
export default {
components: {
EditArea,
EditHeader,
GlSkeletonLoader,
Toolbar,
},
computed: {
...mapState(['content', 'isLoadingContent', 'isSavingChanges', 'isContentLoaded']),
...mapState([
'content',
'isLoadingContent',
'isSavingChanges',
'isContentLoaded',
'returnUrl',
'title',
]),
...mapGetters(['contentChanged']),
},
mounted() {
......@@ -36,12 +45,14 @@ export default {
</gl-skeleton-loader>
</div>
<div v-if="isContentLoaded" class="d-flex flex-grow-1 flex-column">
<edit-header class="w-75 align-self-center py-2" :title="title" />
<edit-area
class="w-75 h-100 shadow-none align-self-center"
:value="content"
@input="setContent"
/>
<toolbar
:return-url="returnUrl"
:saveable="contentChanged"
:saving-changes="isSavingChanges"
@submit="submitChanges"
......
......@@ -10,3 +10,5 @@ export const SUBMIT_CHANGES_COMMIT_ERROR = s__(
export const SUBMIT_CHANGES_MERGE_REQUEST_ERROR = s__(
'StaticSiteEditor|Could not create merge request.',
);
export const DEFAULT_HEADING = s__('StaticSiteEditor|Static site editor');
......@@ -3,10 +3,10 @@ import StaticSiteEditor from './components/static_site_editor.vue';
import createStore from './store';
const initStaticSiteEditor = el => {
const { projectId, path: sourcePath } = el.dataset;
const { projectId, returnUrl, path: sourcePath } = el.dataset;
const store = createStore({
initialState: { projectId, sourcePath, username: window.gon.current_username },
initialState: { projectId, returnUrl, sourcePath, username: window.gon.current_username },
});
return new Vue({
......
const createState = (initialState = {}) => ({
username: null,
projectId: null,
returnUrl: null,
sourcePath: null,
isLoadingContent: false,
......
......@@ -19458,6 +19458,9 @@ msgstr ""
msgid "StaticSiteEditor|Return to site"
msgstr ""
msgid "StaticSiteEditor|Static site editor"
msgstr ""
msgid "StaticSiteEditor|Success!"
msgstr ""
......
import { shallowMount } from '@vue/test-utils';
import EditHeader from '~/static_site_editor/components/edit_header.vue';
import { DEFAULT_HEADING } from '~/static_site_editor/constants';
import { sourceContentTitle } from '../mock_data';
describe('~/static_site_editor/components/edit_header.vue', () => {
let wrapper;
const buildWrapper = (propsData = {}) => {
wrapper = shallowMount(EditHeader, {
propsData: {
...propsData,
},
});
};
const findHeading = () => wrapper.find({ ref: 'sseHeading' });
beforeEach(() => {
buildWrapper();
});
afterEach(() => {
wrapper.destroy();
});
it('renders the default heading if there is no title prop', () => {
expect(findHeading().text()).toBe(DEFAULT_HEADING);
});
it('renders the title prop value in the heading', () => {
buildWrapper({ title: sourceContentTitle });
expect(findHeading().text()).toBe(sourceContentTitle);
});
});
......@@ -3,6 +3,8 @@ import { GlNewButton, GlLoadingIcon } from '@gitlab/ui';
import PublishToolbar from '~/static_site_editor/components/publish_toolbar.vue';
import { returnUrl } from '../mock_data';
describe('Static Site Editor Toolbar', () => {
let wrapper;
......@@ -15,6 +17,7 @@ describe('Static Site Editor Toolbar', () => {
});
};
const findReturnUrlLink = () => wrapper.find({ ref: 'returnUrlLink' });
const findSaveChangesButton = () => wrapper.find(GlNewButton);
const findLoadingIndicator = () => wrapper.find(GlLoadingIcon);
......@@ -38,6 +41,17 @@ describe('Static Site Editor Toolbar', () => {
expect(findLoadingIndicator().classes()).toContain('invisible');
});
it('does not render returnUrl link', () => {
expect(findReturnUrlLink().exists()).toBe(false);
});
it('renders returnUrl link when returnUrl prop exists', () => {
buildWrapper({ returnUrl });
expect(findReturnUrlLink().exists()).toBe(true);
expect(findReturnUrlLink().attributes('href')).toBe(returnUrl);
});
describe('when saveable', () => {
it('enables Submit Changes button', () => {
buildWrapper({ saveable: true });
......
......@@ -7,9 +7,10 @@ import createState from '~/static_site_editor/store/state';
import StaticSiteEditor from '~/static_site_editor/components/static_site_editor.vue';
import EditArea from '~/static_site_editor/components/edit_area.vue';
import EditHeader from '~/static_site_editor/components/edit_header.vue';
import PublishToolbar from '~/static_site_editor/components/publish_toolbar.vue';
import { sourceContent } from '../mock_data';
import { sourceContent, sourceContentTitle } from '../mock_data';
const localVue = createLocalVue();
......@@ -60,6 +61,7 @@ describe('StaticSiteEditor', () => {
};
const findEditArea = () => wrapper.find(EditArea);
const findEditHeader = () => wrapper.find(EditHeader);
const findPublishToolbar = () => wrapper.find(PublishToolbar);
const findSkeletonLoader = () => wrapper.find(GlSkeletonLoader);
......@@ -77,16 +79,21 @@ describe('StaticSiteEditor', () => {
expect(findEditArea().exists()).toBe(false);
});
it('does not render edit header', () => {
expect(findEditHeader().exists()).toBe(false);
});
it('does not render toolbar', () => {
expect(findPublishToolbar().exists()).toBe(false);
});
});
describe('when content is loaded', () => {
const content = 'edit area content';
const content = sourceContent;
const title = sourceContentTitle;
beforeEach(() => {
buildContentLoadedStore({ initialState: { content } });
buildContentLoadedStore({ initialState: { content, title } });
buildWrapper();
});
......@@ -94,6 +101,10 @@ describe('StaticSiteEditor', () => {
expect(findEditArea().exists()).toBe(true);
});
it('renders the edit header', () => {
expect(findEditHeader().exists()).toBe(true);
});
it('does not render skeleton loader', () => {
expect(findSkeletonLoader().exists()).toBe(false);
});
......@@ -102,6 +113,10 @@ describe('StaticSiteEditor', () => {
expect(findEditArea().props('value')).toBe(content);
});
it('passes page title to edit header', () => {
expect(findEditHeader().props('title')).toBe(title);
});
it('renders toolbar', () => {
expect(findPublishToolbar().exists()).toBe(true);
});
......
......@@ -11,11 +11,11 @@ twitter_image: '/images/tweets/handbook-gitlab.png'
- TOC
{:toc .hidden-md .hidden-lg}
`;
export const sourceContentTitle = 'Handbook';
export const username = 'gitlabuser';
export const projectId = '123456';
export const returnUrl = 'https://www.gitlab.com';
export const sourcePath = 'foobar.md.html';
export const savedContentMeta = {
......
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