Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2021-03-16 21:18:33 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2021-03-16 21:18:33 +0300
commitf64a639bcfa1fc2bc89ca7db268f594306edfd7c (patch)
treea2c3c2ebcc3b45e596949db485d6ed18ffaacfa1 /app/assets/javascripts/issuable
parentbfbc3e0d6583ea1a91f627528bedc3d65ba4b10f (diff)
Add latest changes from gitlab-org/gitlab@13-10-stable-eev13.10.0-rc40
Diffstat (limited to 'app/assets/javascripts/issuable')
-rw-r--r--app/assets/javascripts/issuable/components/csv_export_modal.vue100
-rw-r--r--app/assets/javascripts/issuable/components/csv_import_export_buttons.vue107
-rw-r--r--app/assets/javascripts/issuable/components/csv_import_modal.vue86
-rw-r--r--app/assets/javascripts/issuable/constants.js6
-rw-r--r--app/assets/javascripts/issuable/init_csv_import_export_buttons.js45
5 files changed, 344 insertions, 0 deletions
diff --git a/app/assets/javascripts/issuable/components/csv_export_modal.vue b/app/assets/javascripts/issuable/components/csv_export_modal.vue
new file mode 100644
index 00000000000..78987a5c629
--- /dev/null
+++ b/app/assets/javascripts/issuable/components/csv_export_modal.vue
@@ -0,0 +1,100 @@
+<script>
+import { GlButton, GlModal, GlSprintf, GlIcon } from '@gitlab/ui';
+import { ISSUABLE_TYPE } from '../constants';
+
+export default {
+ name: 'CsvExportModal',
+ components: {
+ GlButton,
+ GlModal,
+ GlSprintf,
+ GlIcon,
+ },
+ inject: {
+ issuableType: {
+ default: '',
+ },
+ issuableCount: {
+ default: 0,
+ },
+ email: {
+ default: '',
+ },
+ exportCsvPath: {
+ default: '',
+ },
+ },
+ props: {
+ modalId: {
+ type: String,
+ required: true,
+ },
+ },
+ data() {
+ return {
+ // eslint-disable-next-line @gitlab/require-i18n-strings
+ issuableName: this.issuableType === ISSUABLE_TYPE.issues ? 'issues' : 'merge requests',
+ };
+ },
+ 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>
+ <div
+ v-if="issuableCount > -1"
+ data-testid="issuable-count-note"
+ 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 request selected', issuableCount)"
+ >
+ <template #issuableCount>{{ issuableCount }}</template>
+ </gl-sprintf>
+ </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>
+ </template>
+ </gl-sprintf>
+ </div>
+ <template #modal-footer>
+ <gl-button
+ category="primary"
+ variant="confirm"
+ :href="exportCsvPath"
+ data-method="post"
+ :data-qa-selector="`export_${issuableType}_button`"
+ data-track-event="click_button"
+ :data-track-label="`export_${issuableType}_csv`"
+ >
+ <gl-sprintf :message="__('Export %{name}')">
+ <template #name>{{ issuableName }}</template>
+ </gl-sprintf>
+ </gl-button>
+ </template>
+ </gl-modal>
+</template>
diff --git a/app/assets/javascripts/issuable/components/csv_import_export_buttons.vue b/app/assets/javascripts/issuable/components/csv_import_export_buttons.vue
new file mode 100644
index 00000000000..bbf4160ce35
--- /dev/null
+++ b/app/assets/javascripts/issuable/components/csv_import_export_buttons.vue
@@ -0,0 +1,107 @@
+<script>
+import {
+ GlButtonGroup,
+ GlButton,
+ GlDropdown,
+ GlDropdownItem,
+ GlTooltipDirective,
+ GlModalDirective,
+} from '@gitlab/ui';
+import { __ } from '~/locale';
+import { ISSUABLE_TYPE } from '../constants';
+import CsvExportModal from './csv_export_modal.vue';
+import CsvImportModal from './csv_import_modal.vue';
+
+export default {
+ name: 'CsvImportExportButtons',
+ components: {
+ GlButtonGroup,
+ GlButton,
+ GlDropdown,
+ GlDropdownItem,
+ CsvExportModal,
+ CsvImportModal,
+ },
+ directives: {
+ GlTooltip: GlTooltipDirective,
+ GlModal: GlModalDirective,
+ },
+ inject: {
+ issuableType: {
+ default: ISSUABLE_TYPE.issues,
+ },
+ showExportButton: {
+ default: false,
+ },
+ showImportButton: {
+ default: false,
+ },
+ containerClass: {
+ default: '',
+ },
+ canEdit: {
+ default: false,
+ },
+ projectImportJiraPath: {
+ default: null,
+ },
+ showLabel: {
+ default: false,
+ },
+ },
+ computed: {
+ exportModalId() {
+ return `${this.issuableType}-export-modal`;
+ },
+ importModalId() {
+ return `${this.issuableType}-import-modal`;
+ },
+ importButtonText() {
+ return this.showLabel ? this.$options.importIssuesText : null;
+ },
+ importButtonTooltipText() {
+ return this.showLabel ? null : this.$options.importIssuesText;
+ },
+ importButtonIcon() {
+ return this.showLabel ? null : 'import';
+ },
+ },
+ importIssuesText: __('Import issues'),
+};
+</script>
+
+<template>
+ <div :class="containerClass">
+ <gl-button-group>
+ <gl-button
+ v-if="showExportButton"
+ v-gl-tooltip.hover="__('Export as CSV')"
+ v-gl-modal="exportModalId"
+ icon="export"
+ data-qa-selector="export_as_csv_button"
+ data-testid="export-csv-button"
+ />
+ <gl-dropdown
+ v-if="showImportButton"
+ v-gl-tooltip.hover="importButtonTooltipText"
+ data-qa-selector="import_issues_dropdown"
+ data-testid="import-csv-dropdown"
+ :text="importButtonText"
+ :icon="importButtonIcon"
+ >
+ <gl-dropdown-item v-gl-modal="importModalId" data-testid="import-csv-link">{{
+ __('Import CSV')
+ }}</gl-dropdown-item>
+ <gl-dropdown-item
+ v-if="canEdit"
+ :href="projectImportJiraPath"
+ data-qa-selector="import_from_jira_link"
+ data-testid="import-from-jira-link"
+ >{{ __('Import from Jira') }}</gl-dropdown-item
+ >
+ </gl-dropdown>
+ </gl-button-group>
+ <csv-export-modal v-if="showExportButton" :modal-id="exportModalId" />
+ <csv-import-modal v-if="showImportButton" :modal-id="importModalId" />
+ </div>
+</template>
diff --git a/app/assets/javascripts/issuable/components/csv_import_modal.vue b/app/assets/javascripts/issuable/components/csv_import_modal.vue
new file mode 100644
index 00000000000..77fc2f31583
--- /dev/null
+++ b/app/assets/javascripts/issuable/components/csv_import_modal.vue
@@ -0,0 +1,86 @@
+<script>
+import { GlModal, GlSprintf, GlFormGroup, GlButton } from '@gitlab/ui';
+import csrf from '~/lib/utils/csrf';
+import { ISSUABLE_TYPE } from '../constants';
+
+export default {
+ name: 'CsvImportModal',
+ components: {
+ GlModal,
+ GlSprintf,
+ GlFormGroup,
+ GlButton,
+ },
+ inject: {
+ issuableType: {
+ default: '',
+ },
+ exportCsvPath: {
+ default: '',
+ },
+ importCsvIssuesPath: {
+ default: '',
+ },
+ maxAttachmentSize: {
+ default: 0,
+ },
+ },
+ props: {
+ modalId: {
+ type: String,
+ required: true,
+ },
+ },
+ data() {
+ return {
+ // eslint-disable-next-line @gitlab/require-i18n-strings
+ issuableName: this.issuableType === ISSUABLE_TYPE.issues ? 'issues' : 'merge requests',
+ };
+ },
+ methods: {
+ submitForm() {
+ this.$refs.form.submit();
+ },
+ },
+ csrf,
+};
+</script>
+
+<template>
+ <gl-modal :modal-id="modalId" :title="__('Import issues')">
+ <form
+ ref="form"
+ :action="importCsvIssuesPath"
+ enctype="multipart/form-data"
+ method="post"
+ data-testid="import-csv-form"
+ >
+ <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">
+ <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
+ >
+ </p>
+ </form>
+ <template #modal-footer>
+ <gl-button category="primary" variant="confirm" @click="submitForm">{{
+ __('Import issues')
+ }}</gl-button>
+ </template>
+ </gl-modal>
+</template>
diff --git a/app/assets/javascripts/issuable/constants.js b/app/assets/javascripts/issuable/constants.js
new file mode 100644
index 00000000000..9344f4a7c9a
--- /dev/null
+++ b/app/assets/javascripts/issuable/constants.js
@@ -0,0 +1,6 @@
+export const EVENT_ISSUABLE_VUE_APP_CHANGE = 'issuable_vue_app:change';
+
+export const ISSUABLE_TYPE = {
+ issues: 'issues',
+ mergeRequests: 'merge-requests',
+};
diff --git a/app/assets/javascripts/issuable/init_csv_import_export_buttons.js b/app/assets/javascripts/issuable/init_csv_import_export_buttons.js
new file mode 100644
index 00000000000..5a720b89d33
--- /dev/null
+++ b/app/assets/javascripts/issuable/init_csv_import_export_buttons.js
@@ -0,0 +1,45 @@
+import Vue from 'vue';
+import { parseBoolean } from '~/lib/utils/common_utils';
+import ImportExportButtons from './components/csv_import_export_buttons.vue';
+
+export default () => {
+ const el = document.querySelector('.js-csv-import-export-buttons');
+
+ if (!el) return null;
+
+ const {
+ showExportButton,
+ showImportButton,
+ issuableType,
+ issuableCount,
+ email,
+ exportCsvPath,
+ importCsvIssuesPath,
+ containerClass,
+ canEdit,
+ projectImportJiraPath,
+ maxAttachmentSize,
+ showLabel,
+ } = el.dataset;
+
+ return new Vue({
+ el,
+ provide: {
+ showExportButton: parseBoolean(showExportButton),
+ showImportButton: parseBoolean(showImportButton),
+ issuableType,
+ issuableCount,
+ email,
+ exportCsvPath,
+ importCsvIssuesPath,
+ containerClass,
+ canEdit: parseBoolean(canEdit),
+ projectImportJiraPath,
+ maxAttachmentSize,
+ showLabel,
+ },
+ render(h) {
+ return h(ImportExportButtons);
+ },
+ });
+};