Commit 1286210d authored by Denys Mishunov's avatar Denys Mishunov Committed by Phil Hughes

Move clone button out of blob header

Since cloning is snippet-wide operation, the button should be
 moved out to the global scope of the snippet
parent a8c3cc80
......@@ -3,6 +3,7 @@ import BlobEmbeddable from '~/blob/components/blob_embeddable.vue';
import SnippetHeader from './snippet_header.vue';
import SnippetTitle from './snippet_title.vue';
import SnippetBlob from './snippet_blob_view.vue';
import CloneDropdownButton from '~/vue_shared/components/clone_dropdown.vue';
import { GlLoadingIcon } from '@gitlab/ui';
import { getSnippetMixin } from '../mixins/snippets';
......@@ -15,12 +16,16 @@ export default {
SnippetTitle,
GlLoadingIcon,
SnippetBlob,
CloneDropdownButton,
},
mixins: [getSnippetMixin],
computed: {
embeddable() {
return this.snippet.visibilityLevel === SNIPPET_VISIBILITY_PUBLIC;
},
canBeCloned() {
return Boolean(this.snippet.sshUrlToRepo || this.snippet.httpUrlToRepo);
},
},
};
</script>
......@@ -35,7 +40,16 @@ export default {
<template v-else>
<snippet-header :snippet="snippet" />
<snippet-title :snippet="snippet" />
<blob-embeddable v-if="embeddable" class="gl-mb-5" :url="snippet.webUrl" />
<div class="gl-display-flex gl-justify-content-end gl-mb-5">
<blob-embeddable v-if="embeddable" class="gl-flex-fill-1" :url="snippet.webUrl" />
<clone-dropdown-button
v-if="canBeCloned"
class="gl-ml-3"
:ssh-link="snippet.sshUrlToRepo"
:http-link="snippet.httpUrlToRepo"
data-qa-selector="clone_button"
/>
</div>
<div v-for="blob in blobs" :key="blob.path">
<snippet-blob :snippet="snippet" :blob="blob" />
</div>
......
<script>
import BlobHeader from '~/blob/components/blob_header.vue';
import BlobContent from '~/blob/components/blob_content.vue';
import CloneDropdownButton from '~/vue_shared/components/clone_dropdown.vue';
import GetBlobContent from '../queries/snippet.blob.content.query.graphql';
......@@ -16,7 +15,6 @@ export default {
components: {
BlobHeader,
BlobContent,
CloneDropdownButton,
},
apollo: {
blobContent: {
......@@ -66,9 +64,6 @@ export default {
const { richViewer, simpleViewer } = this.blob;
return this.activeViewerType === RICH_BLOB_VIEWER ? richViewer : simpleViewer;
},
canBeCloned() {
return this.snippet.sshUrlToRepo || this.snippet.httpUrlToRepo;
},
hasRenderError() {
return Boolean(this.viewer.renderError);
},
......@@ -93,17 +88,7 @@ export default {
:active-viewer-type="viewer.type"
:has-render-error="hasRenderError"
@viewer-changed="switchViewer"
>
<template #actions>
<clone-dropdown-button
v-if="canBeCloned"
class="gl-mr-3"
:ssh-link="snippet.sshUrlToRepo"
:http-link="snippet.httpUrlToRepo"
data-qa-selector="clone_button"
/>
</template>
</blob-header>
/>
<blob-content
:loading="isContentLoading"
:content="blobContent"
......
---
title: Move clone button out of blob header
merge_request: 37696
author:
type: changed
......@@ -38,7 +38,7 @@ module QA
element :delete_snippet_button
end
base.view 'app/assets/javascripts/snippets/components/snippet_blob_view.vue' do
base.view 'app/assets/javascripts/snippets/components/show.vue' do
element :clone_button
end
......
......@@ -3,17 +3,25 @@ import BlobEmbeddable from '~/blob/components/blob_embeddable.vue';
import SnippetHeader from '~/snippets/components/snippet_header.vue';
import SnippetTitle from '~/snippets/components/snippet_title.vue';
import SnippetBlob from '~/snippets/components/snippet_blob_view.vue';
import CloneDropdownButton from '~/vue_shared/components/clone_dropdown.vue';
import { GlLoadingIcon } from '@gitlab/ui';
import { Blob, BinaryBlob } from 'jest/blob/components/mock_data';
import { shallowMount } from '@vue/test-utils';
import { SNIPPET_VISIBILITY_PUBLIC } from '~/snippets/constants';
import {
SNIPPET_VISIBILITY_INTERNAL,
SNIPPET_VISIBILITY_PRIVATE,
SNIPPET_VISIBILITY_PUBLIC,
} from '~/snippets/constants';
describe('Snippet view app', () => {
let wrapper;
const defaultProps = {
snippetGid: 'gid://gitlab/PersonalSnippet/42',
};
const webUrl = 'http://foo.bar';
const dummyHTTPUrl = webUrl;
const dummySSHUrl = 'ssh://foo.bar';
function createComponent({ props = defaultProps, data = {}, loading = false } = {}) {
const $apollo = {
......@@ -72,4 +80,47 @@ describe('Snippet view app', () => {
expect(blobs.at(0).props('blob')).toEqual(Blob);
expect(blobs.at(1).props('blob')).toEqual(BinaryBlob);
});
describe('Embed dropdown rendering', () => {
it.each`
visibilityLevel | condition | isRendered
${SNIPPET_VISIBILITY_INTERNAL} | ${'not render'} | ${false}
${SNIPPET_VISIBILITY_PRIVATE} | ${'not render'} | ${false}
${'foo'} | ${'not render'} | ${false}
${SNIPPET_VISIBILITY_PUBLIC} | ${'render'} | ${true}
`('does $condition blob-embeddable by default', ({ visibilityLevel, isRendered }) => {
createComponent({
data: {
snippet: {
visibilityLevel,
webUrl,
},
},
});
expect(wrapper.contains(BlobEmbeddable)).toBe(isRendered);
});
});
describe('Clone button rendering', () => {
it.each`
httpUrlToRepo | sshUrlToRepo | shouldRender | isRendered
${null} | ${null} | ${'Should not'} | ${false}
${null} | ${dummySSHUrl} | ${'Should'} | ${true}
${dummyHTTPUrl} | ${null} | ${'Should'} | ${true}
${dummyHTTPUrl} | ${dummySSHUrl} | ${'Should'} | ${true}
`(
'$shouldRender render "Clone" button when `httpUrlToRepo` is $httpUrlToRepo and `sshUrlToRepo` is $sshUrlToRepo',
({ httpUrlToRepo, sshUrlToRepo, isRendered }) => {
createComponent({
data: {
snippet: {
sshUrlToRepo,
httpUrlToRepo,
},
},
});
expect(wrapper.contains(CloneDropdownButton)).toBe(isRendered);
},
);
});
});
import { mount } from '@vue/test-utils';
import SnippetBlobView from '~/snippets/components/snippet_blob_view.vue';
import BlobHeader from '~/blob/components/blob_header.vue';
import BlobEmbeddable from '~/blob/components/blob_embeddable.vue';
import BlobContent from '~/blob/components/blob_content.vue';
import {
BLOB_RENDER_EVENT_LOAD,
......@@ -9,11 +8,7 @@ import {
BLOB_RENDER_ERRORS,
} from '~/blob/components/constants';
import { RichViewer, SimpleViewer } from '~/vue_shared/components/blob_viewers';
import {
SNIPPET_VISIBILITY_PRIVATE,
SNIPPET_VISIBILITY_INTERNAL,
SNIPPET_VISIBILITY_PUBLIC,
} from '~/snippets/constants';
import { SNIPPET_VISIBILITY_PUBLIC } from '~/snippets/constants';
import { Blob as BlobMock, SimpleViewerMock, RichViewerMock } from 'jest/blob/components/mock_data';
......@@ -72,18 +67,6 @@ describe('Blob Embeddable', () => {
expect(wrapper.find(BlobContent).exists()).toBe(true);
});
it.each([SNIPPET_VISIBILITY_INTERNAL, SNIPPET_VISIBILITY_PRIVATE, 'foo'])(
'does not render blob-embeddable by default',
visibilityLevel => {
createComponent({
snippetProps: {
visibilityLevel,
},
});
expect(wrapper.find(BlobEmbeddable).exists()).toBe(false);
},
);
it('sets simple viewer correctly', () => {
createComponent();
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