Commit 785b6248 authored by Andrew Fontaine's avatar Andrew Fontaine

Merge branch 'fe_commit_history_csv' into 'master'

Export Merge commits CSV - Frontend changes

See merge request gitlab-org/gitlab!38513
parents c53da647 71d337e4
......@@ -5,7 +5,7 @@ import { parseBoolean } from '~/lib/utils/common_utils';
export default () => {
const el = document.getElementById('js-compliance-dashboard');
const { mergeRequests, emptyStateSvgPath, isLastPage } = el.dataset;
const { mergeRequests, emptyStateSvgPath, isLastPage, mergeCommitsCsvExportPath } = el.dataset;
return new Vue({
el,
......@@ -15,6 +15,7 @@ export default () => {
mergeRequests: JSON.parse(mergeRequests),
isLastPage: parseBoolean(isLastPage),
emptyStateSvgPath,
mergeCommitsCsvExportPath,
},
}),
});
......
......@@ -4,6 +4,7 @@ import { GlTabs, GlTab } from '@gitlab/ui';
import { __ } from '~/locale';
import MergeRequestsGrid from './merge_requests/grid.vue';
import EmptyState from './empty_state.vue';
import MergeCommitsExportButton from './merge_requests/merge_commits_export_button.vue';
import { COMPLIANCE_TAB_COOKIE_KEY } from '../constants';
export default {
......@@ -13,6 +14,7 @@ export default {
EmptyState,
GlTab,
GlTabs,
MergeCommitsExportButton,
},
props: {
emptyStateSvgPath: {
......@@ -28,11 +30,19 @@ export default {
required: false,
default: false,
},
mergeCommitsCsvExportPath: {
type: String,
required: false,
default: '',
},
},
computed: {
hasMergeRequests() {
return this.mergeRequests.length > 0;
},
hasMergeCommitsCsvExportPath() {
return this.mergeCommitsCsvExportPath !== '';
},
},
methods: {
showTabs() {
......@@ -49,8 +59,14 @@ export default {
<template>
<div v-if="hasMergeRequests" class="compliance-dashboard">
<header class="gl-my-5">
<h4>{{ $options.strings.heading }}</h4>
<header>
<div class="gl-mt-5 d-flex">
<h4 class="gl-flex-grow-1 gl-my-0">{{ $options.strings.heading }}</h4>
<merge-commits-export-button
v-if="hasMergeCommitsCsvExportPath"
:merge-commits-csv-export-path="mergeCommitsCsvExportPath"
/>
</div>
<p>{{ $options.strings.subheading }}</p>
</header>
......
<script>
import { GlButton, GlTooltip } from '@gitlab/ui';
import { __ } from '~/locale';
export default {
components: {
GlButton,
GlTooltip,
},
props: {
mergeCommitsCsvExportPath: {
required: true,
type: String,
},
},
strings: {
listMergeCommitsButtonText: __('List of all merge commits'),
exportAsCsv: __('Export as CSV'),
csvSizeLimit: __('(max size 15 MB)'),
},
data() {
return {
button: null,
};
},
mounted() {
this.button = this.$refs.button;
},
};
</script>
<template>
<div>
<gl-button
ref="button"
:href="mergeCommitsCsvExportPath"
icon="export"
class="gl-align-self-center"
>
{{ $options.strings.listMergeCommitsButtonText }}
</gl-button>
<gl-tooltip v-if="button" :target="button" boundary="viewport" placement="top">
<p class="gl-my-0">{{ $options.strings.exportAsCsv }}</p>
<p class="gl-my-0">{{ $options.strings.csvSizeLimit }}</p>
</gl-tooltip>
</div>
</template>
......@@ -3,4 +3,5 @@
#js-compliance-dashboard{ data: { merge_requests: @merge_requests.to_json,
is_last_page: @last_page.to_json,
empty_state_svg_path: image_path('illustrations/merge_requests.svg') } }
empty_state_svg_path: image_path('illustrations/merge_requests.svg'),
merge_commits_csv_export_path: group_security_merge_commit_reports_path(@group, format: :csv) } }
---
title: Add Merge Commit CSV export button in Compliance Dashboard
merge_request: 38513
author:
type: added
......@@ -4,13 +4,21 @@ exports[`ComplianceDashboard component when there are merge requests and the sho
<div
class="compliance-dashboard"
>
<header
class="gl-my-5"
<header>
<div
class="gl-mt-5 d-flex"
>
<h4
class="gl-flex-grow-1 gl-my-0"
>
<h4>
Compliance Dashboard
</h4>
<merge-commits-export-button-stub
mergecommitscsvexportpath="/csv"
/>
</div>
<p>
Here you will find recent merge request activity
</p>
......@@ -44,13 +52,21 @@ exports[`ComplianceDashboard component when there are merge requests matches the
<div
class="compliance-dashboard"
>
<header
class="gl-my-5"
<header>
<div
class="gl-mt-5 d-flex"
>
<h4
class="gl-flex-grow-1 gl-my-0"
>
<h4>
Compliance Dashboard
</h4>
<merge-commits-export-button-stub
mergecommitscsvexportpath="/csv"
/>
</div>
<p>
Here you will find recent merge request activity
</p>
......
......@@ -4,6 +4,7 @@ import { GlTabs, GlTab } from '@gitlab/ui';
import ComplianceDashboard from 'ee/compliance_dashboard/components/dashboard.vue';
import MergeRequestGrid from 'ee/compliance_dashboard/components/merge_requests/grid.vue';
import MergeCommitsExportButton from 'ee/compliance_dashboard/components/merge_requests/merge_commits_export_button.vue';
import { COMPLIANCE_TAB_COOKIE_KEY } from 'ee/compliance_dashboard/constants';
import { createMergeRequests } from '../mock_data';
......@@ -12,8 +13,10 @@ describe('ComplianceDashboard component', () => {
const isLastPage = false;
const mergeRequests = createMergeRequests({ count: 2 });
const mergeCommitsCsvExportPath = '/csv';
const findMergeRequestsGrid = () => wrapper.find(MergeRequestGrid);
const findMergeCommitsExportButton = () => wrapper.find(MergeCommitsExportButton);
const findDashboardTabs = () => wrapper.find(GlTabs);
const createComponent = (props = {}) => {
......@@ -21,6 +24,7 @@ describe('ComplianceDashboard component', () => {
propsData: {
mergeRequests,
isLastPage,
mergeCommitsCsvExportPath,
emptyStateSvgPath: 'empty.svg',
...props,
},
......@@ -57,6 +61,10 @@ describe('ComplianceDashboard component', () => {
expect(findMergeRequestsGrid().props('isLastPage')).toBe(isLastPage);
});
it('renders the merge commit export button', () => {
expect(findMergeCommitsExportButton().exists()).toBe(true);
});
describe('and the show tabs cookie is true', () => {
beforeEach(() => {
Cookies.set(COMPLIANCE_TAB_COOKIE_KEY, true);
......@@ -86,4 +94,16 @@ describe('ComplianceDashboard component', () => {
expect(findMergeRequestsGrid().exists()).toBe(false);
});
});
describe('when the merge commit export link is not present', () => {
beforeEach(() => {
wrapper = createComponent({ mergeCommitsCsvExportPath: '' });
});
it('does not render the merge commit export button', () => {
return wrapper.vm.$nextTick().then(() => {
expect(findMergeCommitsExportButton().exists()).toBe(false);
});
});
});
});
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`MergeCommitsExportButton component Merge commit CSV export button matches the snapshot 1`] = `
<div>
<gl-button-stub
category="tertiary"
class="gl-align-self-center"
href="/merge_commit_reports"
icon="export"
size="medium"
variant="default"
>
List of all merge commits
</gl-button-stub>
<gl-tooltip-stub
boundary="viewport"
placement="top"
target="[object Object]"
>
<p
class="gl-my-0"
>
Export as CSV
</p>
<p
class="gl-my-0"
>
(max size 15 MB)
</p>
</gl-tooltip-stub>
</div>
`;
import { shallowMount } from '@vue/test-utils';
import { GlButton } from '@gitlab/ui';
import MergeCommitsExportButton from 'ee/compliance_dashboard/components/merge_requests/merge_commits_export_button.vue';
const CSV_EXPORT_PATH = '/merge_commit_reports';
describe('MergeCommitsExportButton component', () => {
let wrapper;
const findCsvExportButton = () => wrapper.find(GlButton);
const createComponent = (props = {}) => {
return shallowMount(MergeCommitsExportButton, {
propsData: {
mergeCommitsCsvExportPath: CSV_EXPORT_PATH,
...props,
},
});
};
beforeEach(() => {
wrapper = createComponent();
});
afterEach(() => {
wrapper.destroy();
});
describe('Merge commit CSV export button', () => {
it('matches the snapshot', () => {
expect(wrapper.element).toMatchSnapshot();
});
it('renders the merge commits csv export button', () => {
expect(findCsvExportButton().exists()).toBe(true);
});
it('renders the export icon', () => {
expect(findCsvExportButton().props('icon')).toBe('export');
});
it('links to the csv download path', () => {
expect(findCsvExportButton().attributes('href')).toEqual(CSV_EXPORT_PATH);
});
});
});
......@@ -868,6 +868,9 @@ msgstr ""
msgid "(line: %{startLine})"
msgstr ""
msgid "(max size 15 MB)"
msgstr ""
msgid "(removed)"
msgstr ""
......@@ -14387,6 +14390,9 @@ msgstr ""
msgid "List available repositories"
msgstr ""
msgid "List of all merge commits"
msgstr ""
msgid "List settings"
msgstr ""
......
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