Commit b50fef91 authored by Vitaly Slobodin's avatar Vitaly Slobodin

Merge branch '324326-client-side-solution-for-text-viewer' into 'master'

Blob refactor: Create text viewer

See merge request gitlab-org/gitlab!65451
parents 44502201 996b7968
......@@ -11,7 +11,7 @@ import { __ } from '~/locale';
import blobInfoQuery from '../queries/blob_info.query.graphql';
import BlobButtonGroup from './blob_button_group.vue';
import BlobEdit from './blob_edit.vue';
import { loadViewer } from './blob_viewers';
import { loadViewer, viewerProps } from './blob_viewers';
export default {
components: {
......@@ -31,12 +31,12 @@ export default {
};
},
result() {
if (this.hasRichViewer && !this.blobViewer) {
this.loadLegacyViewer();
}
this.switchViewer(
this.hasRichViewer && !window.location.hash ? RICH_BLOB_VIEWER : SIMPLE_BLOB_VIEWER,
);
if (this.hasRichViewer && !this.blobViewer) {
this.loadLegacyViewer();
}
},
error() {
this.displayError();
......@@ -125,6 +125,10 @@ export default {
const { fileType } = this.viewer;
return loadViewer(fileType);
},
viewerProps() {
const { fileType } = this.viewer;
return viewerProps(fileType, this.blobInfo);
},
},
methods: {
loadLegacyViewer() {
......@@ -183,7 +187,7 @@ export default {
:active-viewer="viewer"
:loading="false"
/>
<component :is="blobViewer" v-else class="blob-viewer" />
<component :is="blobViewer" v-else v-bind="viewerProps" class="blob-viewer" />
</div>
</div>
</template>
......@@ -3,8 +3,7 @@ export const loadViewer = (type) => {
case 'empty':
return () => import(/* webpackChunkName: 'blob_empty_viewer' */ './empty_viewer.vue');
case 'text':
// TODO (follow-up): import the text viewer
return null; // () => import(/* webpackChunkName: 'blob_text_viewer' */ './text_viewer.vue');
return () => import(/* webpackChunkName: 'blob_text_viewer' */ './text_viewer.vue');
case 'download':
// TODO (follow-up): import the download viewer
return null; // () => import(/* webpackChunkName: 'blob_download_viewer' */ './download_viewer.vue');
......@@ -12,3 +11,13 @@ export const loadViewer = (type) => {
return null;
}
};
export const viewerProps = (type, blob) => {
return {
text: {
content: blob.rawTextBlob,
fileName: blob.name,
readOnly: true,
},
}[type];
};
<script>
export default {
components: {
SourceEditor: () =>
import(/* webpackChunkName: 'SourceEditor' */ '~/vue_shared/components/source_editor.vue'),
},
props: {
content: {
type: String,
required: true,
},
fileName: {
type: String,
required: true,
},
readOnly: {
type: Boolean,
required: true,
},
},
};
</script>
<template>
<source-editor :value="content" :file-name="fileName" :editor-options="{ readOnly }" />
</template>
......@@ -11,7 +11,8 @@ import BlobHeader from '~/blob/components/blob_header.vue';
import BlobButtonGroup from '~/repository/components/blob_button_group.vue';
import BlobContentViewer from '~/repository/components/blob_content_viewer.vue';
import BlobEdit from '~/repository/components/blob_edit.vue';
import { loadViewer } from '~/repository/components/blob_viewers';
import { loadViewer, viewerProps } from '~/repository/components/blob_viewers';
import TextViewer from '~/repository/components/blob_viewers/text_viewer.vue';
import blobInfoQuery from '~/repository/queries/blob_info.query.graphql';
jest.mock('~/repository/components/blob_viewers');
......@@ -122,6 +123,7 @@ describe('Blob content viewer component', () => {
const findBlobEdit = () => wrapper.findComponent(BlobEdit);
const findBlobContent = () => wrapper.findComponent(BlobContent);
const findBlobButtonGroup = () => wrapper.findComponent(BlobButtonGroup);
const findTextViewer = () => wrapper.findComponent(TextViewer);
afterEach(() => {
wrapper.destroy();
......@@ -231,6 +233,15 @@ describe('Blob content viewer component', () => {
expect(findBlobContent().exists()).toBe(false);
});
it('renders a TextViewer for text files', () => {
loadViewer.mockReturnValueOnce(TextViewer);
viewerProps.mockReturnValueOnce({ content: 'test', fileName: 'test.js', readOnly: true });
factory({ mockData: { blobInfo: simpleMockData } });
expect(findTextViewer().exists()).toBe(true);
});
});
describe('BlobHeader action slot', () => {
......
import { shallowMount } from '@vue/test-utils';
import waitForPromises from 'helpers/wait_for_promises';
import TextViewer from '~/repository/components/blob_viewers/text_viewer.vue';
import SourceEditor from '~/vue_shared/components/source_editor.vue';
describe('Text Viewer', () => {
let wrapper;
const propsData = {
content: 'Some content',
fileName: 'file_name.js',
readOnly: true,
};
const createComponent = () => {
wrapper = shallowMount(TextViewer, { propsData });
};
const findEditor = () => wrapper.findComponent(SourceEditor);
it('renders a Source Editor component', async () => {
createComponent();
await waitForPromises();
expect(findEditor().exists()).toBe(true);
expect(findEditor().props('value')).toBe(propsData.content);
expect(findEditor().props('fileName')).toBe(propsData.fileName);
expect(findEditor().props('editorOptions')).toEqual({ readOnly: propsData.readOnly });
});
});
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