Commit f049b19c authored by Olena Horal-Koretska's avatar Olena Horal-Koretska

Merge branch 'cngo-improve-csv-import-buttons-code' into 'master'

Improve CSV import/export buttons code

See merge request gitlab-org/gitlab!71581
parents 15238108 dc523ddd
<script>
import { GlButton, GlModal, GlSprintf, GlIcon } from '@gitlab/ui';
import { __, n__ } from '~/locale';
import { ISSUABLE_TYPE } from '../constants';
export default {
name: 'CsvExportModal',
i18n: {
exportText: __(
'The CSV export will be created in the background. Once finished, it will be sent to %{email} in an attachment.',
),
},
components: {
GlButton,
GlModal,
......@@ -32,53 +37,39 @@ export default {
required: true,
},
},
data() {
return {
// eslint-disable-next-line @gitlab/require-i18n-strings
issuableName: this.issuableType === ISSUABLE_TYPE.issues ? 'issues' : 'merge requests',
};
computed: {
isIssue() {
return this.issuableType === ISSUABLE_TYPE.issues;
},
exportText() {
return this.isIssue ? __('Export issues') : __('Export merge requests');
},
issuableCountText() {
return this.isIssue
? n__('1 issue selected', '%d issues selected', this.issuableCount)
: n__('1 merge request selected', '%d merge requests selected', this.issuableCount);
},
},
issueableType: ISSUABLE_TYPE,
};
</script>
<template>
<gl-modal :modal-id="modalId" body-class="gl-p-0!" data-qa-selector="export_issuable_modal">
<template #modal-title>
<gl-sprintf :message="__('Export %{name}')">
<template #name>{{ issuableName }}</template>
</gl-sprintf>
</template>
<gl-modal
:modal-id="modalId"
body-class="gl-p-0!"
:title="exportText"
data-qa-selector="export_issuable_modal"
>
<div
v-if="issuableCount > -1"
class="gl-justify-content-start gl-align-items-center gl-p-4 gl-border-b-solid gl-border-1 gl-border-gray-50"
>
<gl-icon name="check" class="gl-color-green-400" />
<strong class="gl-m-3">
<gl-sprintf
v-if="issuableType === $options.issueableType.issues"
:message="n__('1 issue selected', '%d issues selected', issuableCount)"
>
<template #issuableCount>{{ issuableCount }}</template>
</gl-sprintf>
<gl-sprintf
v-else
:message="n__('1 merge request selected', '%d merge requests selected', issuableCount)"
>
<template #issuableCount>{{ issuableCount }}</template>
</gl-sprintf>
</strong>
<strong class="gl-m-3">{{ issuableCountText }}</strong>
</div>
<div class="modal-text gl-px-4 gl-py-5">
<gl-sprintf
:message="
__(
`The CSV export will be created in the background. Once finished, it will be sent to %{strongStart}${email}%{strongEnd} in an attachment.`,
)
"
>
<template #strong="{ content }">
<strong>{{ content }}</strong>
<gl-sprintf :message="$options.i18n.exportText">
<template #email>
<strong>{{ email }}</strong>
</template>
</gl-sprintf>
</div>
......@@ -92,9 +83,7 @@ export default {
data-track-action="click_button"
:data-track-label="`export_${issuableType}_csv`"
>
<gl-sprintf :message="__('Export %{name}')">
<template #name>{{ issuableName }}</template>
</gl-sprintf>
{{ exportText }}
</gl-button>
</template>
</gl-modal>
......
......@@ -15,6 +15,8 @@ import CsvImportModal from './csv_import_modal.vue';
export default {
i18n: {
exportAsCsvButtonText: __('Export as CSV'),
importCsvText: __('Import CSV'),
importFromJiraText: __('Import from Jira'),
importIssuesText: __('Import issues'),
},
name: 'CsvImportExportButtons',
......@@ -101,13 +103,16 @@ export default {
:text-sr-only="!showLabel"
:icon="importButtonIcon"
>
<gl-dropdown-item v-gl-modal="importModalId">{{ __('Import CSV') }}</gl-dropdown-item>
<gl-dropdown-item v-gl-modal="importModalId">
{{ $options.i18n.importCsvText }}
</gl-dropdown-item>
<gl-dropdown-item
v-if="canEdit"
:href="projectImportJiraPath"
data-qa-selector="import_from_jira_link"
>{{ __('Import from Jira') }}</gl-dropdown-item
>
{{ $options.i18n.importFromJiraText }}
</gl-dropdown-item>
</gl-dropdown>
</gl-button-group>
<csv-export-modal
......
<script>
import { GlModal, GlSprintf, GlFormGroup, GlButton } from '@gitlab/ui';
import { GlModal, GlFormGroup } from '@gitlab/ui';
import csrf from '~/lib/utils/csrf';
import { ISSUABLE_TYPE } from '../constants';
import { __, sprintf } from '~/locale';
export default {
name: 'CsvImportModal',
i18n: {
maximumFileSizeText: __('The maximum file size allowed is %{size}.'),
importIssuesText: __('Import issues'),
uploadCsvFileText: __('Upload CSV file'),
mainText: __(
"Your issues will be imported in the background. Once finished, you'll get a confirmation email.",
),
helpText: __(
'It must have a header row and at least two columns: the first column is the issue title and the second column is the issue description. The separator is automatically detected.',
),
},
actionPrimary: {
text: __('Import issues'),
},
components: {
GlModal,
GlSprintf,
GlFormGroup,
GlButton,
},
inject: {
issuableType: {
default: '',
},
exportCsvPath: {
default: '',
},
importCsvIssuesPath: {
default: '',
},
......@@ -31,11 +36,10 @@ export default {
required: true,
},
},
data() {
return {
// eslint-disable-next-line @gitlab/require-i18n-strings
issuableName: this.issuableType === ISSUABLE_TYPE.issues ? 'issues' : 'merge requests',
};
computed: {
maxFileSizeText() {
return sprintf(this.$options.i18n.maximumFileSizeText, { size: this.maxAttachmentSize });
},
},
methods: {
submitForm() {
......@@ -47,34 +51,22 @@ export default {
</script>
<template>
<gl-modal :modal-id="modalId" :title="__('Import issues')">
<gl-modal
:modal-id="modalId"
:title="$options.i18n.importIssuesText"
:action-primary="$options.actionPrimary"
@primary="submitForm"
>
<form ref="form" :action="importCsvIssuesPath" enctype="multipart/form-data" method="post">
<input :value="$options.csrf.token" type="hidden" name="authenticity_token" />
<p>
{{
__(
"Your issues will be imported in the background. Once finished, you'll get a confirmation email.",
)
}}
</p>
<gl-form-group :label="__('Upload CSV file')" label-for="file">
<p>{{ $options.i18n.mainText }}</p>
<gl-form-group :label="$options.i18n.uploadCsvFileText" label-for="file">
<input id="file" type="file" name="file" accept=".csv,text/csv" />
</gl-form-group>
<p class="text-secondary">
{{
__(
'It must have a header row and at least two columns: the first column is the issue title and the second column is the issue description. The separator is automatically detected.',
)
}}
<gl-sprintf :message="__('The maximum file size allowed is %{size}.')"
><template #size>{{ maxAttachmentSize }}</template></gl-sprintf
>
{{ $options.i18n.helpText }}
{{ maxFileSizeText }}
</p>
</form>
<template #modal-footer>
<gl-button category="primary" variant="confirm" @click="submitForm">{{
__('Import issues')
}}</gl-button>
</template>
</gl-modal>
</template>
......@@ -13851,9 +13851,6 @@ msgstr ""
msgid "Export"
msgstr ""
msgid "Export %{name}"
msgstr ""
msgid "Export %{requirementsCount} requirements?"
msgstr ""
......@@ -13866,6 +13863,12 @@ msgstr ""
msgid "Export group"
msgstr ""
msgid "Export issues"
msgstr ""
msgid "Export merge requests"
msgstr ""
msgid "Export project"
msgstr ""
......@@ -33627,6 +33630,9 @@ msgstr[1] ""
msgid "The API key used by GitLab for accessing the Spam Check service endpoint."
msgstr ""
msgid "The CSV export will be created in the background. Once finished, it will be sent to %{email} in an attachment."
msgstr ""
msgid "The GitLab subscription service (customers.gitlab.com) is currently experiencing an outage. You can monitor the status and get updates at %{linkStart}status.gitlab.com%{linkEnd}."
msgstr ""
......
......@@ -61,11 +61,6 @@ describe('CsvExportModal', () => {
expect(wrapper.text()).toContain('10 issues selected');
expect(findIcon().exists()).toBe(true);
});
it("doesn't display the info text when issuableCount is -1", () => {
wrapper = createComponent({ props: { issuableCount: -1 } });
expect(wrapper.text()).not.toContain('issues selected');
});
});
describe('email info text', () => {
......
......@@ -17,7 +17,6 @@ describe('CsvImportModal', () => {
...props,
},
provide: {
issuableType: 'issues',
...injectedProperties,
},
stubs: {
......@@ -43,9 +42,9 @@ describe('CsvImportModal', () => {
const findAuthenticityToken = () => new FormData(findForm().element).get('authenticity_token');
describe('template', () => {
it('displays modal title', () => {
it('passes correct title props to modal', () => {
wrapper = createComponent();
expect(findModal().text()).toContain('Import issues');
expect(findModal().props('title')).toContain('Import issues');
});
it('displays a note about the maximum allowed file size', () => {
......@@ -73,7 +72,7 @@ describe('CsvImportModal', () => {
});
it('submits the form when the primary action is clicked', () => {
findPrimaryButton().trigger('click');
findModal().vm.$emit('primary');
expect(formSubmitSpy).toHaveBeenCalled();
});
......
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