Commit 2277b124 authored by Ezekiel Kigbo's avatar Ezekiel Kigbo Committed by Sincheol (David) Kim

Include the project name VSA stage records

For group VSA we should include the project name
for each record in the stage table

Expose project object to VSA stage records

Changelog: added
EE: true
parent dfdc2855
......@@ -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