Commit 717ff458 authored by Illya Klymov's avatar Illya Klymov Committed by Jacques Erasmus

Introduce import_source_cell component

* split logic of "from source group" cell to separate component
parent 1ec2e8bb
<script>
import { GlButton, GlIcon, GlTooltipDirective as GlTooltip } from '@gitlab/ui';
import { joinPaths } from '~/lib/utils/url_utility';
import { isFinished, isInvalid, isAvailableForImport } from '../utils';
export default {
components: {
GlIcon,
GlButton,
},
directives: {
GlTooltip,
},
props: {
group: {
type: Object,
required: true,
},
groupPathRegex: {
type: RegExp,
required: true,
},
},
computed: {
fullLastImportPath() {
return this.group.last_import_target
? `${this.group.last_import_target.target_namespace}/${this.group.last_import_target.new_name}`
: null;
},
absoluteLastImportPath() {
return joinPaths(gon.relative_url_root || '/', this.fullLastImportPath);
},
isAvailableForImport() {
return isAvailableForImport(this.group);
},
isFinished() {
return isFinished(this.group);
},
isInvalid() {
return isInvalid(this.group, this.groupPathRegex);
},
},
};
</script>
<template>
<span class="gl-white-space-nowrap gl-inline-flex gl-align-items-center">
<gl-icon
v-if="isFinished"
v-gl-tooltip
:size="16"
name="information-o"
:title="
s__('BulkImports|Re-import creates a new group. It does not sync with the existing group.')
"
class="gl-mr-3"
/>
<gl-button
v-if="isAvailableForImport"
:disabled="isInvalid"
variant="confirm"
category="secondary"
data-qa-selector="import_group_button"
@click="$emit('import-group')"
>
{{ isFinished ? __('Re-import') : __('Import') }}
</gl-button>
</span>
</template>
<script>
import { GlLink, GlSprintf, GlIcon } from '@gitlab/ui';
import { joinPaths } from '~/lib/utils/url_utility';
import { isFinished } from '../utils';
export default {
components: {
GlLink,
GlSprintf,
GlIcon,
},
props: {
group: {
type: Object,
required: true,
},
},
computed: {
fullLastImportPath() {
return this.group.last_import_target
? `${this.group.last_import_target.target_namespace}/${this.group.last_import_target.new_name}`
: null;
},
absoluteLastImportPath() {
return joinPaths(gon.relative_url_root || '/', this.fullLastImportPath);
},
isFinished() {
return isFinished(this.group);
},
},
};
</script>
<template>
<div>
<gl-link
:href="group.web_url"
target="_blank"
class="gl-display-inline-flex gl-align-items-center gl-h-7"
>
{{ group.full_path }} <gl-icon name="external-link" />
</gl-link>
<div v-if="isFinished && fullLastImportPath" class="gl-font-sm">
<gl-sprintf :message="s__('BulkImport|Last imported to %{link}')">
<template #link>
<gl-link :href="absoluteLastImportPath" class="gl-font-sm" target="_blank">{{
fullLastImportPath
}}</gl-link>
</template>
</gl-sprintf>
</div>
</div>
</template>
import { GlButton } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import { STATUSES } from '~/import_entities/constants';
import ImportActionsCell from '~/import_entities/import_groups/components/import_actions_cell.vue';
import { generateFakeEntry } from '../graphql/fixtures';
describe('import actions cell', () => {
let wrapper;
const createComponent = (props) => {
wrapper = shallowMount(ImportActionsCell, {
propsData: {
groupPathRegex: /^[a-zA-Z]+$/,
...props,
},
});
};
afterEach(() => {
wrapper.destroy();
});
it('renders import button when group status is NONE', () => {
const group = generateFakeEntry({ id: 1, status: STATUSES.NONE });
createComponent({ group });
const button = wrapper.findComponent(GlButton);
console.log(wrapper.html());
expect(button.exists()).toBe(true);
expect(button.text()).toBe('Import');
});
it('renders re-import button when group status is FINISHED', () => {
const group = generateFakeEntry({ id: 1, status: STATUSES.FINISHED });
createComponent({ group });
const button = wrapper.findComponent(GlButton);
expect(button.exists()).toBe(true);
expect(button.text()).toBe('Re-import');
});
it('does not render import button when group import is in progress', () => {
const group = generateFakeEntry({ id: 1, status: STATUSES.STARTED });
createComponent({ group });
const button = wrapper.findComponent(GlButton);
expect(button.exists()).toBe(false);
});
it('emits import-group event when import button is clicked', () => {
const group = generateFakeEntry({ id: 1, status: STATUSES.NONE });
createComponent({ group });
const button = wrapper.findComponent(GlButton);
button.vm.$emit('click');
expect(wrapper.emitted('import-group')).toHaveLength(1);
});
});
import { GlLink, GlSprintf } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import { STATUSES } from '~/import_entities/constants';
import ImportSourceCell from '~/import_entities/import_groups/components/import_source_cell.vue';
import { generateFakeEntry } from '../graphql/fixtures';
describe('import source cell', () => {
let wrapper;
let group;
const createComponent = (props) => {
wrapper = shallowMount(ImportSourceCell, {
propsData: {
...props,
},
stubs: { GlSprintf },
});
};
afterEach(() => {
wrapper.destroy();
});
describe('when group status is NONE', () => {
beforeEach(() => {
group = generateFakeEntry({ id: 1, status: STATUSES.NONE });
createComponent({ group });
});
it('renders link to a group', () => {
const link = wrapper.findComponent(GlLink);
expect(link.attributes().href).toBe(group.web_url);
expect(link.text()).toContain(group.full_path);
});
it('does not render last imported line', () => {
expect(wrapper.text()).not.toContain('Last imported to');
});
});
describe('when group status is FINISHED', () => {
beforeEach(() => {
group = generateFakeEntry({ id: 1, status: STATUSES.FINISHED });
createComponent({ group });
});
it('renders link to a group', () => {
const link = wrapper.findComponent(GlLink);
expect(link.attributes().href).toBe(group.web_url);
expect(link.text()).toContain(group.full_path);
});
it('renders last imported line', () => {
expect(wrapper.text()).toMatchInterpolatedText(
'fake_group_1 Last imported to root/last-group1',
);
});
});
});
...@@ -9,6 +9,10 @@ export const generateFakeEntry = ({ id, status, ...rest }) => ({ ...@@ -9,6 +9,10 @@ export const generateFakeEntry = ({ id, status, ...rest }) => ({
target_namespace: 'root', target_namespace: 'root',
new_name: `group${id}`, new_name: `group${id}`,
}, },
last_import_target: {
target_namespace: 'root',
new_name: `last-group${id}`,
},
id, id,
progress: { progress: {
id: `test-${id}`, id: `test-${id}`,
......
...@@ -20,7 +20,7 @@ describe('SourceGroupsManager', () => { ...@@ -20,7 +20,7 @@ describe('SourceGroupsManager', () => {
describe('storage management', () => { describe('storage management', () => {
const IMPORT_ID = 1; const IMPORT_ID = 1;
const IMPORT_TARGET = { destination_name: 'demo', destination_namespace: 'foo' }; const IMPORT_TARGET = { new_name: 'demo', target_namespace: 'foo' };
const STATUS = 'FAKE_STATUS'; const STATUS = 'FAKE_STATUS';
const FAKE_GROUP = { id: 1, import_target: IMPORT_TARGET, status: STATUS }; const FAKE_GROUP = { id: 1, import_target: IMPORT_TARGET, status: STATUS };
......
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