summaryrefslogtreecommitdiff
path: root/app/assets/javascripts/import_entities/import_groups/components/import_table_row.vue
diff options
context:
space:
mode:
Diffstat (limited to 'app/assets/javascripts/import_entities/import_groups/components/import_table_row.vue')
-rw-r--r--app/assets/javascripts/import_entities/import_groups/components/import_table_row.vue147
1 files changed, 111 insertions, 36 deletions
diff --git a/app/assets/javascripts/import_entities/import_groups/components/import_table_row.vue b/app/assets/javascripts/import_entities/import_groups/components/import_table_row.vue
index 1707ab10c89..aed879e75fb 100644
--- a/app/assets/javascripts/import_entities/import_groups/components/import_table_row.vue
+++ b/app/assets/javascripts/import_entities/import_groups/components/import_table_row.vue
@@ -1,15 +1,29 @@
<script>
-import { GlButton, GlIcon, GlLink, GlFormInput } from '@gitlab/ui';
+import {
+ GlButton,
+ GlDropdown,
+ GlDropdownDivider,
+ GlDropdownItem,
+ GlDropdownSectionHeader,
+ GlIcon,
+ GlLink,
+ GlFormInput,
+} from '@gitlab/ui';
import { joinPaths } from '~/lib/utils/url_utility';
-import Select2Select from '~/vue_shared/components/select2_select.vue';
import ImportStatus from '../../components/import_status.vue';
import { STATUSES } from '../../constants';
+import groupQuery from '../graphql/queries/group.query.graphql';
+
+const DEBOUNCE_INTERVAL = 300;
export default {
components: {
- Select2Select,
ImportStatus,
GlButton,
+ GlDropdown,
+ GlDropdownDivider,
+ GlDropdownItem,
+ GlDropdownSectionHeader,
GlLink,
GlIcon,
GlFormInput,
@@ -23,9 +37,41 @@ export default {
type: Array,
required: true,
},
+ groupPathRegex: {
+ type: RegExp,
+ required: true,
+ },
+ },
+
+ apollo: {
+ existingGroup: {
+ query: groupQuery,
+ debounce: DEBOUNCE_INTERVAL,
+ variables() {
+ return {
+ fullPath: this.fullPath,
+ };
+ },
+ skip() {
+ return !this.isNameValid || this.isAlreadyImported;
+ },
+ },
},
+
computed: {
- isDisabled() {
+ importTarget() {
+ return this.group.import_target;
+ },
+
+ isInvalid() {
+ return Boolean(!this.isNameValid || this.existingGroup);
+ },
+
+ isNameValid() {
+ return this.groupPathRegex.test(this.importTarget.new_name);
+ },
+
+ isAlreadyImported() {
return this.group.status !== STATUSES.NONE;
},
@@ -33,61 +79,89 @@ export default {
return this.group.status === STATUSES.FINISHED;
},
- select2Options() {
- return {
- data: this.availableNamespaces.map((namespace) => ({
- id: namespace.full_path,
- text: namespace.full_path,
- })),
- };
- },
- },
- methods: {
- getPath(group) {
- return `${group.import_target.target_namespace}/${group.import_target.new_name}`;
+ fullPath() {
+ return `${this.importTarget.target_namespace}/${this.importTarget.new_name}`;
},
- getFullPath(group) {
- return joinPaths(gon.relative_url_root || '/', this.getPath(group));
+ absolutePath() {
+ return joinPaths(gon.relative_url_root || '/', this.fullPath);
},
},
};
</script>
<template>
- <tr class="gl-border-gray-200 gl-border-0 gl-border-b-1">
+ <tr class="gl-border-gray-200 gl-border-0 gl-border-b-1 gl-border-solid">
<td class="gl-p-4">
- <gl-link :href="group.web_url" target="_blank">
+ <gl-link
+ :href="group.web_url"
+ target="_blank"
+ class="gl-display-flex gl-align-items-center gl-h-7"
+ >
{{ group.full_path }} <gl-icon name="external-link" />
</gl-link>
</td>
<td class="gl-p-4">
- <gl-link v-if="isFinished" :href="getFullPath(group)">{{ getPath(group) }}</gl-link>
+ <gl-link
+ v-if="isFinished"
+ class="gl-display-flex gl-align-items-center gl-h-7"
+ :href="absolutePath"
+ >
+ {{ fullPath }}
+ </gl-link>
<div
v-else
class="import-entities-target-select gl-display-flex gl-align-items-stretch"
:class="{
- disabled: isDisabled,
+ disabled: isAlreadyImported,
}"
>
- <select2-select
- :disabled="isDisabled"
- :options="select2Options"
- :value="group.import_target.target_namespace"
- @input="$emit('update-target-namespace', $event)"
- />
+ <gl-dropdown
+ :text="importTarget.target_namespace"
+ :disabled="isAlreadyImported"
+ toggle-class="gl-rounded-top-right-none! gl-rounded-bottom-right-none!"
+ class="import-entities-namespace-dropdown gl-h-7 gl-flex-fill-1"
+ >
+ <gl-dropdown-item @click="$emit('update-target-namespace', '')">{{
+ s__('BulkImport|No parent')
+ }}</gl-dropdown-item>
+ <template v-if="availableNamespaces.length">
+ <gl-dropdown-divider />
+ <gl-dropdown-section-header>
+ {{ s__('BulkImport|Existing groups') }}
+ </gl-dropdown-section-header>
+ <gl-dropdown-item
+ v-for="ns in availableNamespaces"
+ :key="ns.full_path"
+ @click="$emit('update-target-namespace', ns.full_path)"
+ >
+ {{ ns.full_path }}
+ </gl-dropdown-item>
+ </template>
+ </gl-dropdown>
<div
- class="import-entities-target-select-separator gl-px-3 gl-display-flex gl-align-items-center gl-border-solid gl-border-0 gl-border-t-1 gl-border-b-1"
+ class="import-entities-target-select-separator gl-h-7 gl-px-3 gl-display-flex gl-align-items-center gl-border-solid gl-border-0 gl-border-t-1 gl-border-b-1"
>
/
</div>
- <gl-form-input
- class="gl-rounded-top-left-none gl-rounded-bottom-left-none"
- :disabled="isDisabled"
- :value="group.import_target.new_name"
- @input="$emit('update-new-name', $event)"
- />
+ <div class="gl-flex-fill-1">
+ <gl-form-input
+ class="gl-rounded-top-left-none gl-rounded-bottom-left-none"
+ :class="{ 'is-invalid': isInvalid && !isAlreadyImported }"
+ :disabled="isAlreadyImported"
+ :value="importTarget.new_name"
+ @input="$emit('update-new-name', $event)"
+ />
+ <p v-if="isInvalid" class="gl-text-red-500 gl-m-0 gl-mt-2">
+ <template v-if="!isNameValid">
+ {{ __('Please choose a group URL with no special characters.') }}
+ </template>
+ <template v-else-if="existingGroup">
+ {{ s__('BulkImport|Name already exists.') }}
+ </template>
+ </p>
+ </div>
</div>
</td>
<td class="gl-p-4 gl-white-space-nowrap">
@@ -95,7 +169,8 @@ export default {
</td>
<td class="gl-p-4">
<gl-button
- v-if="!isDisabled"
+ v-if="!isAlreadyImported"
+ :disabled="isInvalid"
variant="success"
category="secondary"
@click="$emit('import-group')"