Commit 7838193e authored by Nick Kipling's avatar Nick Kipling

Moved shared components

Moved components into shared
Updated dependencies
Updated stores and props
Updated tests
parent fa84e87e
...@@ -5,8 +5,8 @@ import Tracking from '~/tracking'; ...@@ -5,8 +5,8 @@ import Tracking from '~/tracking';
import { s__, sprintf } from '~/locale'; import { s__, sprintf } from '~/locale';
import { TrackingActions } from '../../shared/constants'; import { TrackingActions } from '../../shared/constants';
import { packageTypeToTrackCategory } from '../../shared/utils'; import { packageTypeToTrackCategory } from '../../shared/utils';
import PackagesListLoader from './packages_list_loader.vue'; import PackagesListLoader from '../../shared/components/packages_list_loader.vue';
import PackagesListRow from './packages_list_row.vue'; import PackagesListRow from '../../shared/components/package_list_row.vue';
export default { export default {
components: { components: {
...@@ -98,6 +98,8 @@ export default { ...@@ -98,6 +98,8 @@ export default {
v-for="packageEntity in list" v-for="packageEntity in list"
:key="packageEntity.id" :key="packageEntity.id"
:package-entity="packageEntity" :package-entity="packageEntity"
:package-link="packageEntity._links.web_path"
:is-group="isGroupPage"
@packageToDelete="setItemToBeDeleted" @packageToDelete="setItemToBeDeleted"
/> />
</div> </div>
......
import { LIST_KEY_PROJECT } from '../constants'; import { LIST_KEY_PROJECT } from '../constants';
import { beautifyPath } from '../../shared/utils'; import { beautifyPath } from '../../shared/utils';
export const getList = state => export default state =>
state.packages.map(p => ({ ...p, projectPathName: beautifyPath(p[LIST_KEY_PROJECT]) })); state.packages.map(p => ({ ...p, projectPathName: beautifyPath(p[LIST_KEY_PROJECT]) }));
export const getCommitLink = ({ config }) => ({ project_path: projectPath, pipeline = {} }) => {
if (config.isGroupPage) {
return `/${projectPath}/commit/${pipeline.sha}`;
}
return `../commit/${pipeline.sha}`;
};
import Vue from 'vue'; import Vue from 'vue';
import Vuex from 'vuex'; import Vuex from 'vuex';
import * as actions from './actions'; import * as actions from './actions';
import * as getters from './getters'; import getList from './getters';
import mutations from './mutations'; import mutations from './mutations';
import state from './state'; import state from './state';
...@@ -10,7 +10,9 @@ Vue.use(Vuex); ...@@ -10,7 +10,9 @@ Vue.use(Vuex);
export const createStore = () => export const createStore = () =>
new Vuex.Store({ new Vuex.Store({
state, state,
getters, getters: {
getList,
},
actions, actions,
mutations, mutations,
}); });
......
...@@ -4,10 +4,9 @@ import PublishMethod from './publish_method.vue'; ...@@ -4,10 +4,9 @@ import PublishMethod from './publish_method.vue';
import { GlButton, GlIcon, GlLink, GlSprintf, GlTooltipDirective } from '@gitlab/ui'; import { GlButton, GlIcon, GlLink, GlSprintf, GlTooltipDirective } from '@gitlab/ui';
import { getPackageTypeLabel } from '../../shared/utils'; import { getPackageTypeLabel } from '../../shared/utils';
import timeagoMixin from '~/vue_shared/mixins/timeago'; import timeagoMixin from '~/vue_shared/mixins/timeago';
import { mapState } from 'vuex';
export default { export default {
name: 'PackagesListRow', name: 'PackageListRow',
components: { components: {
GlButton, GlButton,
GlIcon, GlIcon,
...@@ -25,11 +24,27 @@ export default { ...@@ -25,11 +24,27 @@ export default {
type: Object, type: Object,
required: true, required: true,
}, },
packageLink: {
type: String,
required: true,
},
disableDelete: {
type: Boolean,
default: false,
required: false,
},
isGroup: {
type: Boolean,
default: false,
required: false,
},
showPackageType: {
type: Boolean,
default: true,
required: false,
},
}, },
computed: { computed: {
...mapState({
isGroupPage: state => state.config.isGroupPage,
}),
packageType() { packageType() {
return getPackageTypeLabel(this.packageEntity.package_type); return getPackageTypeLabel(this.packageEntity.package_type);
}, },
...@@ -40,7 +55,7 @@ export default { ...@@ -40,7 +55,7 @@ export default {
return Boolean(this.packageEntity.project_path); return Boolean(this.packageEntity.project_path);
}, },
deleteAvailable() { deleteAvailable() {
return !this.isGroupPage; return !this.disableDelete && !this.isGroup;
}, },
}, },
}; };
...@@ -51,7 +66,7 @@ export default { ...@@ -51,7 +66,7 @@ export default {
<div class="table-section section-50 d-flex flex-md-column justify-content-between flex-wrap"> <div class="table-section section-50 d-flex flex-md-column justify-content-between flex-wrap">
<div class="d-flex align-items-center mr-2"> <div class="d-flex align-items-center mr-2">
<gl-link <gl-link
:href="packageEntity._links.web_path" :href="packageLink"
data-qa-selector="package_link" data-qa-selector="package_link"
class="text-dark font-weight-bold mb-md-1" class="text-dark font-weight-bold mb-md-1"
> >
...@@ -80,25 +95,25 @@ export default { ...@@ -80,25 +95,25 @@ export default {
<gl-icon name="review-list" class="text-secondary ml-2 mr-1" /> <gl-icon name="review-list" class="text-secondary ml-2 mr-1" />
<gl-link <gl-link
ref="packages-row-project" data-testid="packages-row-project"
:href="`/${packageEntity.project_path}`" :href="`/${packageEntity.project_path}`"
class="text-secondary" class="text-secondary"
>{{ packageEntity.projectPathName }}</gl-link >{{ packageEntity.projectPathName }}</gl-link
> >
</div> </div>
<div class="d-flex align-items-center"> <div v-if="showPackageType" class="d-flex align-items-center" data-testid="package-type">
<gl-icon name="package" class="text-secondary ml-2 mr-1" /> <gl-icon name="package" class="text-secondary ml-2 mr-1" />
<span ref="package-type">{{ packageType }}</span> <span>{{ packageType }}</span>
</div> </div>
</div> </div>
</div> </div>
<div <div
class="table-section d-flex flex-md-column justify-content-between align-items-md-end" class="table-section d-flex flex-md-column justify-content-between align-items-md-end"
:class="isGroupPage ? 'section-50' : 'section-40'" :class="!deleteAvailable ? 'section-50' : 'section-40'"
> >
<publish-method :package-entity="packageEntity" /> <publish-method :package-entity="packageEntity" :is-group="isGroup" />
<div class="text-secondary order-0 order-md-1 mt-md-2"> <div class="text-secondary order-0 order-md-1 mt-md-2">
<gl-sprintf :message="__('Created %{timestamp}')"> <gl-sprintf :message="__('Created %{timestamp}')">
...@@ -113,7 +128,7 @@ export default { ...@@ -113,7 +128,7 @@ export default {
<div v-if="deleteAvailable" class="table-section section-10 d-flex justify-content-end"> <div v-if="deleteAvailable" class="table-section section-10 d-flex justify-content-end">
<gl-button <gl-button
ref="action-delete" data-testid="action-delete"
icon="remove" icon="remove"
category="primary" category="primary"
variant="danger" variant="danger"
......
<script> <script>
import ClipboardButton from '~/vue_shared/components/clipboard_button.vue'; import ClipboardButton from '~/vue_shared/components/clipboard_button.vue';
import { GlIcon, GlLink } from '@gitlab/ui'; import { GlIcon, GlLink } from '@gitlab/ui';
import { mapGetters } from 'vuex'; import { getCommitLink } from '../utils';
export default { export default {
name: 'PublishMethod', name: 'PublishMethod',
...@@ -15,9 +15,13 @@ export default { ...@@ -15,9 +15,13 @@ export default {
type: Object, type: Object,
required: true, required: true,
}, },
isGroup: {
type: Boolean,
required: false,
default: false,
},
}, },
computed: { computed: {
...mapGetters(['getCommitLink']),
hasPipeline() { hasPipeline() {
return Boolean(this.packageEntity.pipeline); return Boolean(this.packageEntity.pipeline);
}, },
...@@ -25,7 +29,7 @@ export default { ...@@ -25,7 +29,7 @@ export default {
return this.packageEntity.pipeline?.sha.substring(0, 8); return this.packageEntity.pipeline?.sha.substring(0, 8);
}, },
linkToCommit() { linkToCommit() {
return this.getCommitLink(this.packageEntity); return getCommitLink(this.packageEntity, this.isGroup);
}, },
}, },
}; };
......
...@@ -24,3 +24,11 @@ export const getPackageTypeLabel = packageType => { ...@@ -24,3 +24,11 @@ export const getPackageTypeLabel = packageType => {
return null; return null;
} }
}; };
export const getCommitLink = ({ project_path: projectPath, pipeline = {} }, isGroup = false) => {
if (isGroup) {
return `/${projectPath}/commit/${pipeline.sha}`;
}
return `../commit/${pipeline.sha}`;
};
...@@ -4,8 +4,8 @@ import { GlTable, GlPagination, GlModal } from '@gitlab/ui'; ...@@ -4,8 +4,8 @@ import { GlTable, GlPagination, GlModal } from '@gitlab/ui';
import Tracking from '~/tracking'; import Tracking from '~/tracking';
import { mount, createLocalVue } from '@vue/test-utils'; import { mount, createLocalVue } from '@vue/test-utils';
import PackagesList from 'ee/packages/list/components/packages_list.vue'; import PackagesList from 'ee/packages/list/components/packages_list.vue';
import PackagesListLoader from 'ee/packages/list/components/packages_list_loader.vue'; import PackagesListLoader from 'ee/packages/shared/components/packages_list_loader.vue';
import PackagesListRow from 'ee/packages/list/components/packages_list_row.vue'; import PackagesListRow from 'ee/packages/shared/components/package_list_row.vue';
import * as SharedUtils from 'ee/packages/shared/utils'; import * as SharedUtils from 'ee/packages/shared/utils';
import { TrackingActions } from 'ee/packages/shared/constants'; import { TrackingActions } from 'ee/packages/shared/constants';
import stubChildren from 'helpers/stub_children'; import stubChildren from 'helpers/stub_children';
......
import * as getters from 'ee/packages/list/stores/getters'; import getList from 'ee/packages/list/stores/getters';
import { packageList } from '../../mock_data'; import { packageList } from '../../mock_data';
describe('Getters registry list store', () => { describe('Getters registry list store', () => {
...@@ -21,35 +21,16 @@ describe('Getters registry list store', () => { ...@@ -21,35 +21,16 @@ describe('Getters registry list store', () => {
describe('getList', () => { describe('getList', () => {
it('returns a list of packages', () => { it('returns a list of packages', () => {
const result = getters.getList(state); const result = getList(state);
expect(result).toHaveLength(packageList.length); expect(result).toHaveLength(packageList.length);
expect(result[0].name).toBe('Test package'); expect(result[0].name).toBe('Test package');
}); });
it('adds projectPathName', () => { it('adds projectPathName', () => {
const result = getters.getList(state); const result = getList(state);
expect(result[0].projectPathName).toMatchInlineSnapshot(`"foo / bar / baz"`); expect(result[0].projectPathName).toMatchInlineSnapshot(`"foo / bar / baz"`);
}); });
}); });
describe('getCommitLink', () => {
it('returns a relative link when isGroupPage is false', () => {
const link = getters.getCommitLink(state)(packageList[0]);
expect(link).toContain('../commit');
});
describe('when isGroupPage is true', () => {
beforeEach(() => setState({ isGroupPage: true }));
it('returns an absolute link matching project path', () => {
const mavenPackage = packageList[0];
const link = getters.getCommitLink(state)(mavenPackage);
expect(link).toContain(`/${mavenPackage.project_path}/commit`);
});
});
});
}); });
...@@ -44,6 +44,7 @@ exports[`packages_list_row renders 1`] = ` ...@@ -44,6 +44,7 @@ exports[`packages_list_row renders 1`] = `
<gl-link-stub <gl-link-stub
class="text-secondary" class="text-secondary"
data-testid="packages-row-project"
href="/foo/bar/baz" href="/foo/bar/baz"
> >
...@@ -52,6 +53,7 @@ exports[`packages_list_row renders 1`] = ` ...@@ -52,6 +53,7 @@ exports[`packages_list_row renders 1`] = `
<div <div
class="d-flex align-items-center" class="d-flex align-items-center"
data-testid="package-type"
> >
<gl-icon-stub <gl-icon-stub
class="text-secondary ml-2 mr-1" class="text-secondary ml-2 mr-1"
...@@ -88,6 +90,7 @@ exports[`packages_list_row renders 1`] = ` ...@@ -88,6 +90,7 @@ exports[`packages_list_row renders 1`] = `
<gl-button-stub <gl-button-stub
aria-label="Remove package" aria-label="Remove package"
category="primary" category="primary"
data-testid="action-delete"
icon="remove" icon="remove"
size="medium" size="medium"
title="Remove package" title="Remove package"
......
...@@ -24,7 +24,7 @@ exports[`publish_method renders 1`] = ` ...@@ -24,7 +24,7 @@ exports[`publish_method renders 1`] = `
<gl-link-stub <gl-link-stub
class="mr-1" class="mr-1"
href="commit-link" href="../commit/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
> >
xxxxxxxx xxxxxxxx
</gl-link-stub> </gl-link-stub>
......
import Vuex from 'vuex'; import { mount, shallowMount } from '@vue/test-utils';
import { mount, shallowMount, createLocalVue } from '@vue/test-utils'; import PackagesListRow from 'ee/packages/shared/components/package_list_row.vue';
import PackagesListRow from 'ee/packages/list/components/packages_list_row.vue';
import PackageTags from 'ee/packages/shared/components/package_tags.vue'; import PackageTags from 'ee/packages/shared/components/package_tags.vue';
import { packageList } from '../../mock_data'; import { packageList } from '../../mock_data';
const localVue = createLocalVue();
localVue.use(Vuex);
describe('packages_list_row', () => { describe('packages_list_row', () => {
let wrapper; let wrapper;
let store; let store;
...@@ -14,36 +10,27 @@ describe('packages_list_row', () => { ...@@ -14,36 +10,27 @@ describe('packages_list_row', () => {
const [packageWithoutTags, packageWithTags] = packageList; const [packageWithoutTags, packageWithTags] = packageList;
const findPackageTags = () => wrapper.find(PackageTags); const findPackageTags = () => wrapper.find(PackageTags);
const findProjectLink = () => wrapper.find({ ref: 'packages-row-project' }); const findProjectLink = () => wrapper.find('[data-testid="packages-row-project"]');
const findDeleteButton = () => wrapper.find({ ref: 'action-delete' }); const findDeleteButton = () => wrapper.find('[data-testid="action-delete"]');
const findPackageType = () => wrapper.find('[data-testid="package-type"]');
const mountComponent = ( const mountComponent = ({
isGroupPage = false, isGroup = false,
packageEntity = packageWithoutTags, packageEntity = packageWithoutTags,
shallow = true, shallow = true,
) => { showPackageType = true,
disableDelete = false,
} = {}) => {
const mountFunc = shallow ? shallowMount : mount; const mountFunc = shallow ? shallowMount : mount;
const state = {
config: {
isGroupPage,
},
};
store = new Vuex.Store({
state,
getters: {
getCommitLink: () => () => {
return 'commit-link';
},
},
});
wrapper = mountFunc(PackagesListRow, { wrapper = mountFunc(PackagesListRow, {
localVue,
store, store,
propsData: { propsData: {
packageLink: 'foo',
packageEntity, packageEntity,
isGroup,
showPackageType,
disableDelete,
}, },
}); });
}; };
...@@ -60,7 +47,7 @@ describe('packages_list_row', () => { ...@@ -60,7 +47,7 @@ describe('packages_list_row', () => {
describe('tags', () => { describe('tags', () => {
it('renders package tags when a package has tags', () => { it('renders package tags when a package has tags', () => {
mountComponent(false, packageWithTags); mountComponent({ isGroup: false, packageEntity: packageWithTags });
expect(findPackageTags().exists()).toBe(true); expect(findPackageTags().exists()).toBe(true);
}); });
...@@ -72,9 +59,9 @@ describe('packages_list_row', () => { ...@@ -72,9 +59,9 @@ describe('packages_list_row', () => {
}); });
}); });
describe('when is isGroupPage', () => { describe('when is is group', () => {
beforeEach(() => { beforeEach(() => {
mountComponent(true); mountComponent({ isGroup: true });
}); });
it('has project field', () => { it('has project field', () => {
...@@ -86,8 +73,32 @@ describe('packages_list_row', () => { ...@@ -86,8 +73,32 @@ describe('packages_list_row', () => {
}); });
}); });
describe('showPackageType', () => {
it('shows the type when set', () => {
mountComponent();
expect(findPackageType().exists()).toBe(true);
});
it('does not show the type when not set', () => {
mountComponent({ showPackageType: false });
expect(findPackageType().exists()).toBe(false);
});
});
describe('deleteAvailable', () => {
it('does not show when not set', () => {
mountComponent({ disableDelete: true });
expect(findDeleteButton().exists()).toBe(false);
});
});
describe('delete event', () => { describe('delete event', () => {
beforeEach(() => mountComponent(false, packageWithoutTags, false)); beforeEach(() =>
mountComponent({ isGroup: false, packageEntity: packageWithoutTags, shallow: false }),
);
it('emits the packageToDelete event when the delete button is clicked', () => { it('emits the packageToDelete event when the delete button is clicked', () => {
findDeleteButton().trigger('click'); findDeleteButton().trigger('click');
......
import { mount } from '@vue/test-utils'; import { mount } from '@vue/test-utils';
import PackagesListLoader from 'ee/packages/list/components/packages_list_loader.vue'; import PackagesListLoader from 'ee/packages/shared/components/packages_list_loader.vue';
describe('PackagesListLoader', () => { describe('PackagesListLoader', () => {
let wrapper; let wrapper;
......
import Vuex from 'vuex'; import { shallowMount } from '@vue/test-utils';
import { shallowMount, createLocalVue } from '@vue/test-utils'; import PublishMethod from 'ee/packages/shared/components/publish_method.vue';
import PublishMethod from 'ee/packages/list/components/publish_method.vue';
import { packageList } from '../../mock_data'; import { packageList } from '../../mock_data';
const localVue = createLocalVue();
localVue.use(Vuex);
describe('publish_method', () => { describe('publish_method', () => {
let wrapper; let wrapper;
let store;
const [packageWithoutPipeline, packageWithPipeline] = packageList; const [packageWithoutPipeline, packageWithPipeline] = packageList;
...@@ -16,20 +11,11 @@ describe('publish_method', () => { ...@@ -16,20 +11,11 @@ describe('publish_method', () => {
const findPipelineSha = () => wrapper.find({ ref: 'pipeline-sha' }); const findPipelineSha = () => wrapper.find({ ref: 'pipeline-sha' });
const findManualPublish = () => wrapper.find({ ref: 'manual-ref' }); const findManualPublish = () => wrapper.find({ ref: 'manual-ref' });
const mountComponent = packageEntity => { const mountComponent = (packageEntity = {}, isGroup = false) => {
store = new Vuex.Store({
getters: {
getCommitLink: () => () => {
return 'commit-link';
},
},
});
wrapper = shallowMount(PublishMethod, { wrapper = shallowMount(PublishMethod, {
localVue,
store,
propsData: { propsData: {
packageEntity, packageEntity,
isGroup,
}, },
}); });
}; };
......
...@@ -2,8 +2,10 @@ import { ...@@ -2,8 +2,10 @@ import {
packageTypeToTrackCategory, packageTypeToTrackCategory,
beautifyPath, beautifyPath,
getPackageTypeLabel, getPackageTypeLabel,
getCommitLink,
} from 'ee/packages/shared/utils'; } from 'ee/packages/shared/utils';
import { PackageType, TrackingCategories } from 'ee/packages/shared/constants'; import { PackageType, TrackingCategories } from 'ee/packages/shared/constants';
import { packageList } from '../mock_data';
describe('Packages shared utils', () => { describe('Packages shared utils', () => {
describe('packageTypeToTrackCategory', () => { describe('packageTypeToTrackCategory', () => {
...@@ -43,4 +45,21 @@ describe('Packages shared utils', () => { ...@@ -43,4 +45,21 @@ describe('Packages shared utils', () => {
}); });
}); });
}); });
describe('getCommitLink', () => {
it('returns a relative link when isGroup is false', () => {
const link = getCommitLink(packageList[0], false);
expect(link).toContain('../commit');
});
describe('when isGroup is true', () => {
it('returns an absolute link matching project path', () => {
const mavenPackage = packageList[0];
const link = getCommitLink(mavenPackage, true);
expect(link).toContain(`/${mavenPackage.project_path}/commit`);
});
});
});
}); });
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