Commit 837a6b53 authored by Martin Wortschack's avatar Martin Wortschack

Merge branch '207463-fetch-blob-with-snippet' into 'master'

Fetch Snippet's blob in the same GraphQL query as the Snippet itself

See merge request gitlab-org/gitlab!29441
parents eea793bc b6cf2349
...@@ -3,10 +3,8 @@ import BlobEmbeddable from '~/blob/components/blob_embeddable.vue'; ...@@ -3,10 +3,8 @@ import BlobEmbeddable from '~/blob/components/blob_embeddable.vue';
import { SNIPPET_VISIBILITY_PUBLIC } from '../constants'; import { SNIPPET_VISIBILITY_PUBLIC } from '../constants';
import BlobHeader from '~/blob/components/blob_header.vue'; import BlobHeader from '~/blob/components/blob_header.vue';
import BlobContent from '~/blob/components/blob_content.vue'; import BlobContent from '~/blob/components/blob_content.vue';
import { GlLoadingIcon } from '@gitlab/ui';
import CloneDropdownButton from '~/vue_shared/components/clone_dropdown.vue'; import CloneDropdownButton from '~/vue_shared/components/clone_dropdown.vue';
import GetSnippetBlobQuery from '../queries/snippet.blob.query.graphql';
import GetBlobContent from '../queries/snippet.blob.content.query.graphql'; import GetBlobContent from '../queries/snippet.blob.content.query.graphql';
import { SIMPLE_BLOB_VIEWER, RICH_BLOB_VIEWER } from '~/blob/components/constants'; import { SIMPLE_BLOB_VIEWER, RICH_BLOB_VIEWER } from '~/blob/components/constants';
...@@ -16,25 +14,9 @@ export default { ...@@ -16,25 +14,9 @@ export default {
BlobEmbeddable, BlobEmbeddable,
BlobHeader, BlobHeader,
BlobContent, BlobContent,
GlLoadingIcon,
CloneDropdownButton, CloneDropdownButton,
}, },
apollo: { apollo: {
blob: {
query: GetSnippetBlobQuery,
variables() {
return {
ids: this.snippet.id,
};
},
update: data => data.snippets.edges[0].node.blob,
result(res) {
const viewer = res.data.snippets.edges[0].node.blob.richViewer
? RICH_BLOB_VIEWER
: SIMPLE_BLOB_VIEWER;
this.switchViewer(viewer, true);
},
},
blobContent: { blobContent: {
query: GetBlobContent, query: GetBlobContent,
variables() { variables() {
...@@ -55,18 +37,18 @@ export default { ...@@ -55,18 +37,18 @@ export default {
}, },
data() { data() {
return { return {
blob: {}, blob: this.snippet.blob,
blobContent: '', blobContent: '',
activeViewerType: window.location.hash ? SIMPLE_BLOB_VIEWER : '', activeViewerType:
this.snippet.blob?.richViewer && !window.location.hash
? RICH_BLOB_VIEWER
: SIMPLE_BLOB_VIEWER,
}; };
}, },
computed: { computed: {
embeddable() { embeddable() {
return this.snippet.visibilityLevel === SNIPPET_VISIBILITY_PUBLIC; return this.snippet.visibilityLevel === SNIPPET_VISIBILITY_PUBLIC;
}, },
isBlobLoading() {
return this.$apollo.queries.blob.loading;
},
isContentLoading() { isContentLoading() {
return this.$apollo.queries.blobContent.loading; return this.$apollo.queries.blobContent.loading;
}, },
...@@ -79,8 +61,8 @@ export default { ...@@ -79,8 +61,8 @@ export default {
}, },
}, },
methods: { methods: {
switchViewer(newViewer, respectHash = false) { switchViewer(newViewer) {
this.activeViewerType = respectHash && window.location.hash ? SIMPLE_BLOB_VIEWER : newViewer; this.activeViewerType = newViewer;
}, },
}, },
}; };
...@@ -88,13 +70,7 @@ export default { ...@@ -88,13 +70,7 @@ export default {
<template> <template>
<div> <div>
<blob-embeddable v-if="embeddable" class="mb-3" :url="snippet.webUrl" /> <blob-embeddable v-if="embeddable" class="mb-3" :url="snippet.webUrl" />
<gl-loading-icon <article class="file-holder snippet-file-content">
v-if="isBlobLoading"
:label="__('Loading blob')"
size="lg"
class="prepend-top-20 append-bottom-20"
/>
<article v-else class="file-holder snippet-file-content">
<blob-header :blob="blob" :active-viewer-type="viewer.type" @viewer-changed="switchViewer"> <blob-header :blob="blob" :active-viewer-type="viewer.type" @viewer-changed="switchViewer">
<template #actions> <template #actions>
<clone-dropdown-button <clone-dropdown-button
......
#import '~/graphql_shared/fragments/blobviewer.fragment.graphql'
fragment SnippetBase on Snippet { fragment SnippetBase on Snippet {
id id
title title
...@@ -9,6 +11,19 @@ fragment SnippetBase on Snippet { ...@@ -9,6 +11,19 @@ fragment SnippetBase on Snippet {
webUrl webUrl
httpUrlToRepo httpUrlToRepo
sshUrlToRepo sshUrlToRepo
blob {
binary
name
path
rawPath
size
simpleViewer {
...BlobViewer
}
richViewer {
...BlobViewer
}
}
userPermissions { userPermissions {
adminSnippet adminSnippet
updateSnippet updateSnippet
......
#import '~/graphql_shared/fragments/blobviewer.fragment.graphql'
query SnippetBlobFull($ids: [ID!]) {
snippets(ids: $ids) {
edges {
node {
id
blob {
binary
name
path
rawPath
size
simpleViewer {
...BlobViewer
}
richViewer {
...BlobViewer
}
}
}
}
}
}
...@@ -12189,9 +12189,6 @@ msgstr "" ...@@ -12189,9 +12189,6 @@ msgstr ""
msgid "Loading" msgid "Loading"
msgstr "" msgstr ""
msgid "Loading blob"
msgstr ""
msgid "Loading contribution stats for group members" msgid "Loading contribution stats for group members"
msgstr "" msgstr ""
......
import { mount } from '@vue/test-utils'; import { mount } from '@vue/test-utils';
import { GlLoadingIcon } from '@gitlab/ui';
import SnippetBlobView from '~/snippets/components/snippet_blob_view.vue'; import SnippetBlobView from '~/snippets/components/snippet_blob_view.vue';
import BlobHeader from '~/blob/components/blob_header.vue'; import BlobHeader from '~/blob/components/blob_header.vue';
import BlobEmbeddable from '~/blob/components/blob_embeddable.vue'; import BlobEmbeddable from '~/blob/components/blob_embeddable.vue';
...@@ -19,23 +18,15 @@ describe('Blob Embeddable', () => { ...@@ -19,23 +18,15 @@ describe('Blob Embeddable', () => {
id: 'gid://foo.bar/snippet', id: 'gid://foo.bar/snippet',
webUrl: 'https://foo.bar', webUrl: 'https://foo.bar',
visibilityLevel: SNIPPET_VISIBILITY_PUBLIC, visibilityLevel: SNIPPET_VISIBILITY_PUBLIC,
blob: BlobMock,
}; };
const dataMock = { const dataMock = {
blob: BlobMock,
activeViewerType: SimpleViewerMock.type, activeViewerType: SimpleViewerMock.type,
}; };
function createComponent( function createComponent(props = {}, data = dataMock, contentLoading = false) {
props = {},
data = dataMock,
blobLoading = false,
contentLoading = false,
) {
const $apollo = { const $apollo = {
queries: { queries: {
blob: {
loading: blobLoading,
},
blobContent: { blobContent: {
loading: contentLoading, loading: contentLoading,
}, },
...@@ -87,12 +78,6 @@ describe('Blob Embeddable', () => { ...@@ -87,12 +78,6 @@ describe('Blob Embeddable', () => {
expect(wrapper.find(BlobEmbeddable).exists()).toBe(true); expect(wrapper.find(BlobEmbeddable).exists()).toBe(true);
}); });
it('shows loading icon while blob data is in flight', () => {
createComponent({}, dataMock, true);
expect(wrapper.find(GlLoadingIcon).exists()).toBe(true);
expect(wrapper.find('.snippet-file-content').exists()).toBe(false);
});
it('sets simple viewer correctly', () => { it('sets simple viewer correctly', () => {
createComponent(); createComponent();
expect(wrapper.find(SimpleViewer).exists()).toBe(true); expect(wrapper.find(SimpleViewer).exists()).toBe(true);
...@@ -133,14 +118,14 @@ describe('Blob Embeddable', () => { ...@@ -133,14 +118,14 @@ describe('Blob Embeddable', () => {
}); });
it('renders simple viewer by default if URL contains hash', () => { it('renders simple viewer by default if URL contains hash', () => {
createComponent(); createComponent({}, {});
expect(wrapper.vm.activeViewerType).toBe(SimpleViewerMock.type); expect(wrapper.vm.activeViewerType).toBe(SimpleViewerMock.type);
expect(wrapper.find(SimpleViewer).exists()).toBe(true); expect(wrapper.find(SimpleViewer).exists()).toBe(true);
}); });
describe('switchViewer()', () => { describe('switchViewer()', () => {
it('by default switches to the passed viewer', () => { it('switches to the passed viewer', () => {
createComponent(); createComponent();
wrapper.vm.switchViewer(RichViewerMock.type); wrapper.vm.switchViewer(RichViewerMock.type);
...@@ -157,22 +142,6 @@ describe('Blob Embeddable', () => { ...@@ -157,22 +142,6 @@ describe('Blob Embeddable', () => {
expect(wrapper.find(SimpleViewer).exists()).toBe(true); expect(wrapper.find(SimpleViewer).exists()).toBe(true);
}); });
}); });
it('respects hash over richViewer in the blob when corresponding parameter is passed', () => {
createComponent(
{},
{
blob: BlobMock,
},
);
expect(wrapper.vm.blob.richViewer).toEqual(expect.any(Object));
wrapper.vm.switchViewer(RichViewerMock.type, true);
return wrapper.vm.$nextTick().then(() => {
expect(wrapper.vm.activeViewerType).toBe(SimpleViewerMock.type);
expect(wrapper.find(SimpleViewer).exists()).toBe(true);
});
});
}); });
}); });
}); });
......
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