Commit 5f26b186 authored by Phil Hughes's avatar Phil Hughes

Added tabs to the code intelligence popover

https://gitlab.com/gitlab-org/gitlab/-/issues/217392
parent a04c8e24
<script> <script>
import { GlButton } from '@gitlab/ui'; import { GlButton, GlTabs, GlTab, GlLink, GlBadge } from '@gitlab/ui';
import DocLine from './doc_line.vue'; import DocLine from './doc_line.vue';
export default { export default {
components: { components: {
GlButton, GlButton,
GlTabs,
GlTab,
GlLink,
GlBadge,
DocLine, DocLine,
}, },
props: { props: {
...@@ -54,6 +58,9 @@ export default { ...@@ -54,6 +58,9 @@ export default {
isDefinitionCurrentBlob() { isDefinitionCurrentBlob() {
return this.data.definition_path.indexOf(this.blobPath) === 0; return this.data.definition_path.indexOf(this.blobPath) === 0;
}, },
references() {
return this.data.references || [];
},
}, },
watch: { watch: {
position: { position: {
...@@ -82,6 +89,8 @@ export default { ...@@ -82,6 +89,8 @@ export default {
class="popover code-navigation-popover popover-font-size-normal gl-popover bs-popover-bottom show" class="popover code-navigation-popover popover-font-size-normal gl-popover bs-popover-bottom show"
> >
<div :style="{ left: `${offsetLeft}px` }" class="arrow"></div> <div :style="{ left: `${offsetLeft}px` }" class="arrow"></div>
<gl-tabs nav-class="gl-hidden" content-class="gl-py-0">
<gl-tab :title="__('Definition')">
<div class="overflow-auto code-navigation-popover-container"> <div class="overflow-auto code-navigation-popover-container">
<div <div
v-for="(hover, index) in data.hover" v-for="(hover, index) in data.hover"
...@@ -94,7 +103,7 @@ export default { ...@@ -94,7 +103,7 @@ export default {
:class="$options.colorScheme" :class="$options.colorScheme"
class="border-0 bg-transparent m-0 code highlight text-wrap" class="border-0 bg-transparent m-0 code highlight text-wrap"
><doc-line v-for="(tokens, tokenIndex) in hover.tokens" :key="tokenIndex" :language="hover.language" :tokens="tokens"/></pre> ><doc-line v-for="(tokens, tokenIndex) in hover.tokens" :key="tokenIndex" :language="hover.language" :tokens="tokens"/></pre>
<p v-else ref="doc-output" class="p-3 m-0 gl-font-base"> <p v-else ref="doc-output" class="p-3 m-0">
{{ hover.value }} {{ hover.value }}
</p> </p>
</div> </div>
...@@ -114,5 +123,27 @@ export default { ...@@ -114,5 +123,27 @@ export default {
{{ __('Go to definition') }} {{ __('Go to definition') }}
</gl-button> </gl-button>
</div> </div>
</gl-tab>
<gl-tab data-testid="references-tab" class="py-2">
<template #title>
{{ __('References') }}
<gl-badge size="sm" class="gl-tab-counter-badge">{{ references.length }}</gl-badge>
</template>
<template v-if="references.length">
<div v-for="(reference, index) in references" :key="index" class="gl-dropdown-item">
<gl-link
:href="`${definitionPathPrefix}/${reference.path}`"
class="dropdown-item"
data-testid="reference-link"
>
{{ reference.path }}
</gl-link>
</div>
</template>
<p v-else class="gl-my-4 gl-px-4">
{{ s__('CodeNavigation|No references found') }}
</p>
</gl-tab>
</gl-tabs>
</div> </div>
</template> </template>
...@@ -5882,6 +5882,9 @@ msgstr "" ...@@ -5882,6 +5882,9 @@ msgstr ""
msgid "CodeIntelligence|This is the definition" msgid "CodeIntelligence|This is the definition"
msgstr "" msgstr ""
msgid "CodeNavigation|No references found"
msgstr ""
msgid "CodeOwner|Pattern" msgid "CodeOwner|Pattern"
msgstr "" msgstr ""
...@@ -7512,6 +7515,9 @@ msgstr "" ...@@ -7512,6 +7515,9 @@ msgstr ""
msgid "Define environments in the deploy stage(s) in <code>.gitlab-ci.yml</code> to track deployments here." msgid "Define environments in the deploy stage(s) in <code>.gitlab-ci.yml</code> to track deployments here."
msgstr "" msgstr ""
msgid "Definition"
msgstr ""
msgid "Delayed Project Deletion (%{adjourned_deletion})" msgid "Delayed Project Deletion (%{adjourned_deletion})"
msgstr "" msgstr ""
...@@ -19170,6 +19176,9 @@ msgstr "" ...@@ -19170,6 +19176,9 @@ msgstr ""
msgid "Reference:" msgid "Reference:"
msgstr "" msgstr ""
msgid "References"
msgstr ""
msgid "Refresh" msgid "Refresh"
msgstr "" msgstr ""
......
...@@ -10,6 +10,14 @@ exports[`Code navigation popover component renders popover 1`] = ` ...@@ -10,6 +10,14 @@ exports[`Code navigation popover component renders popover 1`] = `
style="left: 0px;" style="left: 0px;"
/> />
<gl-tabs-stub
contentclass="gl-py-0"
nav-class="gl-hidden"
theme="indigo"
>
<gl-tab-stub
title="Definition"
>
<div <div
class="overflow-auto code-navigation-popover-container" class="overflow-auto code-navigation-popover-container"
> >
...@@ -62,5 +70,21 @@ exports[`Code navigation popover component renders popover 1`] = ` ...@@ -62,5 +70,21 @@ exports[`Code navigation popover component renders popover 1`] = `
</gl-button-stub> </gl-button-stub>
</div> </div>
</gl-tab-stub>
<gl-tab-stub
class="py-2"
data-testid="references-tab"
>
<p
class="gl-my-4 gl-px-4"
>
No references found
</p>
</gl-tab-stub>
</gl-tabs-stub>
</div> </div>
`; `;
...@@ -40,6 +40,17 @@ const MOCK_DOCS_DATA = Object.freeze({ ...@@ -40,6 +40,17 @@ const MOCK_DOCS_DATA = Object.freeze({
definition_path: 'test.js#L20', definition_path: 'test.js#L20',
}); });
const MOCK_DATA_WITH_REFERENCES = Object.freeze({
hover: [
{
language: null,
value: 'console.log',
},
],
references: [{ path: 'index.js' }, { path: 'app.js' }],
definition_path: 'test.js#L20',
});
let wrapper; let wrapper;
function factory({ position, data, definitionPathPrefix, blobPath = 'index.js' }) { function factory({ position, data, definitionPathPrefix, blobPath = 'index.js' }) {
...@@ -64,6 +75,16 @@ describe('Code navigation popover component', () => { ...@@ -64,6 +75,16 @@ describe('Code navigation popover component', () => {
expect(wrapper.element).toMatchSnapshot(); expect(wrapper.element).toMatchSnapshot();
}); });
it('srender references tab with empty text when no references exist', () => {
factory({
position: { x: 0, y: 0, height: 0 },
data: MOCK_CODE_DATA,
definitionPathPrefix: DEFINITION_PATH_PREFIX,
});
expect(wrapper.find('[data-testid="references-tab"]').text()).toContain('No references found');
});
it('renders link with hash to current file', () => { it('renders link with hash to current file', () => {
factory({ factory({
position: { x: 0, y: 0, height: 0 }, position: { x: 0, y: 0, height: 0 },
...@@ -75,6 +96,17 @@ describe('Code navigation popover component', () => { ...@@ -75,6 +96,17 @@ describe('Code navigation popover component', () => {
expect(wrapper.find('[data-testid="go-to-definition-btn"]').attributes('href')).toBe('#L20'); expect(wrapper.find('[data-testid="go-to-definition-btn"]').attributes('href')).toBe('#L20');
}); });
it('renders list of references', () => {
factory({
position: { x: 0, y: 0, height: 0 },
data: MOCK_DATA_WITH_REFERENCES,
definitionPathPrefix: DEFINITION_PATH_PREFIX,
});
expect(wrapper.find('[data-testid="references-tab"]').exists()).toBe(true);
expect(wrapper.findAll('[data-testid="reference-link"]').length).toBe(2);
});
describe('code output', () => { describe('code output', () => {
it('renders code output', () => { it('renders code output', () => {
factory({ factory({
......
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