Commit 89e2ee15 authored by Sincheol (David) Kim's avatar Sincheol (David) Kim

Merge branch '215290-vsa-display-project-for-each-record-in-group-level-feature' into 'master'

[VSA] Display project for each record in group level feature

See merge request gitlab-org/gitlab!77841
parents d1ac31ec 2277b124
......@@ -89,6 +89,11 @@ export default {
required: false,
default: true,
},
includeProjectName: {
type: Boolean,
required: false,
default: false,
},
},
data() {
if (this.pagination) {
......@@ -144,8 +149,13 @@ export default {
isMrLink(url = '') {
return url.includes('/merge_request');
},
itemId({ url, iid }) {
return this.isMrLink(url) ? `!${iid}` : `#${iid}`;
itemId({ iid, projectPath }, separator = '#') {
const prefix = this.includeProjectName ? projectPath : '';
return `${prefix}${separator}${iid}`;
},
itemDisplayName(item) {
const separator = this.isMrLink(item.url) ? '!' : '#';
return this.itemId(item, separator);
},
itemTitle(item) {
return item.title || item.name;
......@@ -201,8 +211,11 @@ export default {
<div data-testid="vsa-stage-event">
<div v-if="item.id" data-testid="vsa-stage-content">
<p class="gl-m-0">
<gl-link class="gl-text-black-normal pipeline-id" :href="item.url"
>#{{ item.id }}</gl-link
<gl-link
data-testid="vsa-stage-event-link"
class="gl-text-black-normal pipeline-id"
:href="item.url"
>{{ itemId(item.id, '#') }}</gl-link
>
<gl-icon :size="16" name="fork" />
<gl-link
......@@ -240,7 +253,12 @@ export default {
<gl-link class="gl-text-black-normal" :href="item.url">{{ itemTitle(item) }}</gl-link>
</h5>
<p class="gl-m-0">
<gl-link class="gl-text-black-normal" :href="item.url">{{ itemId(item) }}</gl-link>
<gl-link
data-testid="vsa-stage-event-link"
class="gl-text-black-normal"
:href="item.url"
>{{ itemDisplayName(item) }}</gl-link
>
<span class="gl-font-lg">&middot;</span>
<span data-testid="vsa-stage-event-date">
{{ s__('OpenedNDaysAgo|Opened') }}
......
......@@ -9,6 +9,9 @@ class AnalyticsBuildEntity < Grape::Entity
expose :ref, as: :branch
expose :short_sha
expose :author, using: UserEntity
expose :project_path do |build|
build.project.path
end
expose :started_at, as: :date do |build|
interval_in_words(build[:started_at])
......
......@@ -6,6 +6,9 @@ class AnalyticsIssueEntity < Grape::Entity
expose :title
expose :author, using: UserEntity
expose :project_path do |object|
object[:project_path]
end
expose :iid do |object|
object[:iid].to_s
......
......@@ -213,6 +213,7 @@ export default {
:empty-state-message="selectedStageError"
:no-data-svg-path="noDataSvgPath"
:pagination="pagination"
include-project-name
@handleUpdatePagination="onHandleUpdatePagination"
/>
<url-sync v-if="selectedStageReady" :query="query" />
......
......@@ -319,6 +319,10 @@ describe('EE Value Stream Analytics component', () => {
displaysStageTable(true);
});
it('sets the `includeProjectName` prop on stage table', () => {
expect(findStageTable().props('includeProjectName')).toBe(true);
});
it('displays the path navigation', () => {
displaysPathNavigation(true);
});
......
......@@ -24,6 +24,7 @@ const findTable = () => wrapper.findComponent(GlTable);
const findTableHead = () => wrapper.find('thead');
const findTableHeadColumns = () => findTableHead().findAll('th');
const findStageEventTitle = (ev) => extendedWrapper(ev).findByTestId('vsa-stage-event-title');
const findStageEventLink = (ev) => extendedWrapper(ev).findByTestId('vsa-stage-event-link');
const findStageTime = () => wrapper.findByTestId('vsa-stage-event-time');
const findIcon = (name) => wrapper.findByTestId(`${name}-icon`);
......@@ -86,6 +87,15 @@ describe('StageTable', () => {
expect(titles[index]).toBe(ev.title);
});
});
it('will not display the project name in the record link', () => {
const evs = findStageEvents();
const links = evs.wrappers.map((ev) => findStageEventLink(ev).text());
issueEventItems.forEach((ev, index) => {
expect(links[index]).toBe(`#${ev.iid}`);
});
});
});
describe('default event', () => {
......@@ -187,6 +197,21 @@ describe('StageTable', () => {
});
});
describe('includeProjectName set', () => {
beforeEach(() => {
wrapper = createComponent({ includeProjectName: true });
});
it('will display the project name in the record link', () => {
const evs = findStageEvents();
const links = evs.wrappers.map((ev) => findStageEventLink(ev).text());
issueEventItems.forEach((ev, index) => {
expect(links[index]).toBe(`${ev.projectPath}#${ev.iid}`);
});
});
});
describe('Pagination', () => {
beforeEach(() => {
wrapper = createComponent();
......
......@@ -27,6 +27,10 @@ RSpec.describe AnalyticsBuildEntity do
expect(subject).to include(:author)
end
it 'contains the project path' do
expect(subject).to include(:project_path)
end
it 'does not contain sensitive information' do
expect(subject).not_to include(/token/)
expect(subject).not_to include(/variables/)
......
......@@ -32,6 +32,10 @@ RSpec.describe AnalyticsIssueEntity do
expect(subject).to include(:author)
end
it 'contains the project path' do
expect(subject).to include(:project_path)
end
it 'does not contain sensitive information' do
expect(subject).not_to include(/token/)
expect(subject).not_to include(/variables/)
......
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