debian-mirror-gitlab/app/assets/javascripts/import_entities/import_groups/components/import_table_row.vue

228 lines
6.4 KiB
Vue
Raw Normal View History

2021-02-22 17:27:13 +05:30
<script>
2021-04-17 20:07:23 +05:30
import {
GlButton,
GlDropdownDivider,
GlDropdownItem,
GlDropdownSectionHeader,
GlIcon,
GlLink,
GlFormInput,
} from '@gitlab/ui';
2021-02-22 17:27:13 +05:30
import { joinPaths } from '~/lib/utils/url_utility';
2021-06-08 01:23:25 +05:30
import { s__ } from '~/locale';
2021-09-30 23:02:18 +05:30
import ImportGroupDropdown from '../../components/group_dropdown.vue';
2021-02-22 17:27:13 +05:30
import ImportStatus from '../../components/import_status.vue';
import { STATUSES } from '../../constants';
2021-06-08 01:23:25 +05:30
import addValidationErrorMutation from '../graphql/mutations/add_validation_error.mutation.graphql';
import removeValidationErrorMutation from '../graphql/mutations/remove_validation_error.mutation.graphql';
2021-09-04 01:27:46 +05:30
import groupAndProjectQuery from '../graphql/queries/groupAndProject.query.graphql';
2021-04-17 20:07:23 +05:30
const DEBOUNCE_INTERVAL = 300;
2021-02-22 17:27:13 +05:30
export default {
components: {
ImportStatus,
2021-09-30 23:02:18 +05:30
ImportGroupDropdown,
2021-02-22 17:27:13 +05:30
GlButton,
2021-04-17 20:07:23 +05:30
GlDropdownDivider,
GlDropdownItem,
GlDropdownSectionHeader,
2021-02-22 17:27:13 +05:30
GlLink,
GlIcon,
GlFormInput,
},
props: {
group: {
type: Object,
required: true,
},
availableNamespaces: {
type: Array,
required: true,
},
2021-04-17 20:07:23 +05:30
groupPathRegex: {
type: RegExp,
required: true,
},
},
apollo: {
2021-09-04 01:27:46 +05:30
existingGroupAndProject: {
query: groupAndProjectQuery,
2021-04-17 20:07:23 +05:30
debounce: DEBOUNCE_INTERVAL,
variables() {
return {
fullPath: this.fullPath,
};
},
2021-09-04 01:27:46 +05:30
update({ existingGroup, existingProject }) {
2021-06-08 01:23:25 +05:30
const variables = {
field: 'new_name',
sourceGroupId: this.group.id,
};
2021-09-04 01:27:46 +05:30
if (!existingGroup && !existingProject) {
2021-06-08 01:23:25 +05:30
this.$apollo.mutate({
mutation: removeValidationErrorMutation,
variables,
});
} else {
this.$apollo.mutate({
mutation: addValidationErrorMutation,
variables: {
...variables,
2021-09-04 01:27:46 +05:30
message: this.$options.i18n.NAME_ALREADY_EXISTS,
2021-06-08 01:23:25 +05:30
},
});
}
},
2021-04-17 20:07:23 +05:30
skip() {
return !this.isNameValid || this.isAlreadyImported;
},
},
2021-02-22 17:27:13 +05:30
},
2021-04-17 20:07:23 +05:30
2021-02-22 17:27:13 +05:30
computed: {
2021-09-30 23:02:18 +05:30
availableNamespaceNames() {
return this.availableNamespaces.map((ns) => ns.full_path);
},
2021-04-17 20:07:23 +05:30
importTarget() {
return this.group.import_target;
},
2021-06-08 01:23:25 +05:30
invalidNameValidationMessage() {
return this.group.validation_errors.find(({ field }) => field === 'new_name')?.message;
},
2021-04-17 20:07:23 +05:30
isInvalid() {
2021-06-08 01:23:25 +05:30
return Boolean(!this.isNameValid || this.invalidNameValidationMessage);
2021-04-17 20:07:23 +05:30
},
isNameValid() {
return this.groupPathRegex.test(this.importTarget.new_name);
},
isAlreadyImported() {
2021-06-08 01:23:25 +05:30
return this.group.progress.status !== STATUSES.NONE;
2021-02-22 17:27:13 +05:30
},
isFinished() {
2021-06-08 01:23:25 +05:30
return this.group.progress.status === STATUSES.FINISHED;
2021-02-22 17:27:13 +05:30
},
2021-04-17 20:07:23 +05:30
fullPath() {
return `${this.importTarget.target_namespace}/${this.importTarget.new_name}`;
2021-02-22 17:27:13 +05:30
},
2021-04-17 20:07:23 +05:30
absolutePath() {
return joinPaths(gon.relative_url_root || '/', this.fullPath);
2021-02-22 17:27:13 +05:30
},
},
2021-09-04 01:27:46 +05:30
i18n: {
NAME_ALREADY_EXISTS: s__('BulkImport|Name already exists.'),
},
2021-02-22 17:27:13 +05:30
};
</script>
<template>
2021-06-08 01:23:25 +05:30
<tr
class="gl-border-gray-200 gl-border-0 gl-border-b-1 gl-border-solid"
data-qa-selector="import_item"
:data-qa-source-group="group.full_path"
>
2021-02-22 17:27:13 +05:30
<td class="gl-p-4">
2021-04-17 20:07:23 +05:30
<gl-link
:href="group.web_url"
target="_blank"
class="gl-display-flex gl-align-items-center gl-h-7"
>
2021-02-22 17:27:13 +05:30
{{ group.full_path }} <gl-icon name="external-link" />
</gl-link>
</td>
<td class="gl-p-4">
2021-04-17 20:07:23 +05:30
<gl-link
v-if="isFinished"
class="gl-display-flex gl-align-items-center gl-h-7"
:href="absolutePath"
>
{{ fullPath }}
</gl-link>
2021-02-22 17:27:13 +05:30
<div
v-else
class="import-entities-target-select gl-display-flex gl-align-items-stretch"
:class="{
2021-04-17 20:07:23 +05:30
disabled: isAlreadyImported,
2021-02-22 17:27:13 +05:30
}"
>
2021-09-30 23:02:18 +05:30
<import-group-dropdown
#default="{ namespaces }"
2021-04-17 20:07:23 +05:30
:text="importTarget.target_namespace"
:disabled="isAlreadyImported"
2021-09-30 23:02:18 +05:30
:namespaces="availableNamespaceNames"
2021-04-17 20:07:23 +05:30
toggle-class="gl-rounded-top-right-none! gl-rounded-bottom-right-none!"
2021-09-04 01:27:46 +05:30
class="import-entities-namespace-dropdown gl-h-7 gl-flex-grow-1"
2021-06-08 01:23:25 +05:30
data-qa-selector="target_namespace_selector_dropdown"
2021-04-17 20:07:23 +05:30
>
<gl-dropdown-item @click="$emit('update-target-namespace', '')">{{
s__('BulkImport|No parent')
}}</gl-dropdown-item>
2021-09-30 23:02:18 +05:30
<template v-if="namespaces.length">
2021-04-17 20:07:23 +05:30
<gl-dropdown-divider />
<gl-dropdown-section-header>
{{ s__('BulkImport|Existing groups') }}
</gl-dropdown-section-header>
<gl-dropdown-item
2021-09-30 23:02:18 +05:30
v-for="ns in namespaces"
:key="ns"
2021-06-08 01:23:25 +05:30
data-qa-selector="target_group_dropdown_item"
2021-09-30 23:02:18 +05:30
:data-qa-group-name="ns"
@click="$emit('update-target-namespace', ns)"
2021-04-17 20:07:23 +05:30
>
2021-09-30 23:02:18 +05:30
{{ ns }}
2021-04-17 20:07:23 +05:30
</gl-dropdown-item>
</template>
2021-09-30 23:02:18 +05:30
</import-group-dropdown>
2021-02-22 17:27:13 +05:30
<div
2021-04-17 20:07:23 +05:30
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"
2021-02-22 17:27:13 +05:30
>
/
</div>
2021-09-04 01:27:46 +05:30
<div class="gl-flex-grow-1">
2021-04-17 20:07:23 +05:30
<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>
2021-06-08 01:23:25 +05:30
<template v-else-if="invalidNameValidationMessage">
{{ invalidNameValidationMessage }}
2021-04-17 20:07:23 +05:30
</template>
</p>
</div>
2021-02-22 17:27:13 +05:30
</div>
</td>
2021-06-08 01:23:25 +05:30
<td class="gl-p-4 gl-white-space-nowrap" data-qa-selector="import_status_indicator">
<import-status :status="group.progress.status" class="gl-mt-2" />
2021-02-22 17:27:13 +05:30
</td>
<td class="gl-p-4">
<gl-button
2021-04-17 20:07:23 +05:30
v-if="!isAlreadyImported"
:disabled="isInvalid"
2021-06-08 01:23:25 +05:30
variant="confirm"
2021-02-22 17:27:13 +05:30
category="secondary"
2021-06-08 01:23:25 +05:30
data-qa-selector="import_group_button"
2021-02-22 17:27:13 +05:30
@click="$emit('import-group')"
>{{ __('Import') }}</gl-button
>
</td>
</tr>
</template>