diff options
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.vue | 147 |
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')" |