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>
import { GlButton } from '@gitlab/ui';
import { GlButton, GlTabs, GlTab, GlLink, GlBadge } from '@gitlab/ui';
import DocLine from './doc_line.vue';
export default {
components: {
GlButton,
GlTabs,
GlTab,
GlLink,
GlBadge,
DocLine,
},
props: {
......@@ -54,6 +58,9 @@ export default {
isDefinitionCurrentBlob() {
return this.data.definition_path.indexOf(this.blobPath) === 0;
},
references() {
return this.data.references || [];
},
},
watch: {
position: {
......@@ -82,37 +89,61 @@ export default {
class="popover code-navigation-popover popover-font-size-normal gl-popover bs-popover-bottom show"
>
<div :style="{ left: `${offsetLeft}px` }" class="arrow"></div>
<div class="overflow-auto code-navigation-popover-container">
<div
v-for="(hover, index) in data.hover"
:key="index"
:class="{ 'border-bottom': index !== data.hover.length - 1 }"
>
<pre
v-if="hover.language"
ref="code-output"
:class="$options.colorScheme"
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>
<p v-else ref="doc-output" class="p-3 m-0 gl-font-base">
{{ hover.value }}
<gl-tabs nav-class="gl-hidden" content-class="gl-py-0">
<gl-tab :title="__('Definition')">
<div class="overflow-auto code-navigation-popover-container">
<div
v-for="(hover, index) in data.hover"
:key="index"
:class="{ 'border-bottom': index !== data.hover.length - 1 }"
>
<pre
v-if="hover.language"
ref="code-output"
:class="$options.colorScheme"
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>
<p v-else ref="doc-output" class="p-3 m-0">
{{ hover.value }}
</p>
</div>
</div>
<div v-if="definitionPath || isCurrentDefinition" class="popover-body border-top">
<span v-if="isCurrentDefinition" class="gl-font-weight-bold gl-font-base">
{{ s__('CodeIntelligence|This is the definition') }}
</span>
<gl-button
v-else
:href="definitionPath"
:target="isDefinitionCurrentBlob ? null : '_blank'"
class="w-100"
variant="default"
data-testid="go-to-definition-btn"
>
{{ __('Go to definition') }}
</gl-button>
</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>
</div>
</div>
<div v-if="definitionPath || isCurrentDefinition" class="popover-body border-top">
<span v-if="isCurrentDefinition" class="gl-font-weight-bold gl-font-base">
{{ s__('CodeIntelligence|This is the definition') }}
</span>
<gl-button
v-else
:href="definitionPath"
:target="isDefinitionCurrentBlob ? null : '_blank'"
class="w-100"
variant="default"
data-testid="go-to-definition-btn"
>
{{ __('Go to definition') }}
</gl-button>
</div>
</gl-tab>
</gl-tabs>
</div>
</template>
......@@ -5882,6 +5882,9 @@ msgstr ""
msgid "CodeIntelligence|This is the definition"
msgstr ""
msgid "CodeNavigation|No references found"
msgstr ""
msgid "CodeOwner|Pattern"
msgstr ""
......@@ -7512,6 +7515,9 @@ msgstr ""
msgid "Define environments in the deploy stage(s) in <code>.gitlab-ci.yml</code> to track deployments here."
msgstr ""
msgid "Definition"
msgstr ""
msgid "Delayed Project Deletion (%{adjourned_deletion})"
msgstr ""
......@@ -19170,6 +19176,9 @@ msgstr ""
msgid "Reference:"
msgstr ""
msgid "References"
msgstr ""
msgid "Refresh"
msgstr ""
......
......@@ -10,57 +10,81 @@ exports[`Code navigation popover component renders popover 1`] = `
style="left: 0px;"
/>
<div
class="overflow-auto code-navigation-popover-container"
<gl-tabs-stub
contentclass="gl-py-0"
nav-class="gl-hidden"
theme="indigo"
>
<div
class=""
<gl-tab-stub
title="Definition"
>
<pre
class="border-0 bg-transparent m-0 code highlight text-wrap"
<div
class="overflow-auto code-navigation-popover-container"
>
<span
class="line"
lang="javascript"
<div
class=""
>
<span
class="k"
<pre
class="border-0 bg-transparent m-0 code highlight text-wrap"
>
function
</span>
<span>
main() {
</span>
</span>
<span
class="line"
lang="javascript"
<span
class="line"
lang="javascript"
>
<span
class="k"
>
function
</span>
<span>
main() {
</span>
</span>
<span
class="line"
lang="javascript"
>
<span>
}
</span>
</span>
</pre>
</div>
</div>
<div
class="popover-body border-top"
>
<gl-button-stub
category="tertiary"
class="w-100"
data-testid="go-to-definition-btn"
href="http://gitlab.com/test.js"
icon=""
size="medium"
target="_blank"
variant="default"
>
<span>
}
</span>
</span>
</pre>
</div>
</div>
<div
class="popover-body border-top"
>
<gl-button-stub
category="tertiary"
class="w-100"
data-testid="go-to-definition-btn"
href="http://gitlab.com/test.js"
icon=""
size="medium"
target="_blank"
variant="default"
Go to definition
</gl-button-stub>
</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
Go to definition
</gl-button-stub>
</div>
</p>
</gl-tab-stub>
</gl-tabs-stub>
</div>
`;
......@@ -40,6 +40,17 @@ const MOCK_DOCS_DATA = Object.freeze({
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;
function factory({ position, data, definitionPathPrefix, blobPath = 'index.js' }) {
......@@ -64,6 +75,16 @@ describe('Code navigation popover component', () => {
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', () => {
factory({
position: { x: 0, y: 0, height: 0 },
......@@ -75,6 +96,17 @@ describe('Code navigation popover component', () => {
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', () => {
it('renders code output', () => {
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