Commit 523cb9df authored by Natalia Tepluhina's avatar Natalia Tepluhina

Merge branch '330847-convert-package-details-page-to-use-graphql-2' into 'master'

Refactor and restore versions tab

See merge request gitlab-org/gitlab!67831
parents 5607675e b6d5e7f1
......@@ -20,7 +20,6 @@ import { numberToHumanSize } from '~/lib/utils/number_utils';
import { objectToQuery } from '~/lib/utils/url_utility';
import { s__, __ } from '~/locale';
// import DependencyRow from '~/packages/details/components/dependency_row.vue';
// import PackageListRow from '~/packages/shared/components/package_list_row.vue';
import PackagesListLoader from '~/packages/shared/components/packages_list_loader.vue';
import { packageTypeToTrackCategory } from '~/packages/shared/utils';
import AdditionalMetadata from '~/packages_and_registries/package_registry/components/details/additional_metadata.vue';
......@@ -28,6 +27,7 @@ import InstallationCommands from '~/packages_and_registries/package_registry/com
import PackageFiles from '~/packages_and_registries/package_registry/components/details/package_files.vue';
import PackageHistory from '~/packages_and_registries/package_registry/components/details/package_history.vue';
import PackageTitle from '~/packages_and_registries/package_registry/components/details/package_title.vue';
import VersionRow from '~/packages_and_registries/package_registry/components/details/version_row.vue';
import {
PACKAGE_TYPE_NUGET,
PACKAGE_TYPE_COMPOSER,
......@@ -62,7 +62,7 @@ export default {
GlSprintf,
PackageTitle,
PackagesListLoader,
// PackageListRow,
VersionRow,
// DependencyRow,
PackageHistory,
AdditionalMetadata,
......@@ -138,7 +138,7 @@ export default {
};
},
hasVersions() {
return this.packageEntity.versions?.length > 0;
return this.packageEntity.versions?.nodes?.length > 0;
},
packageDependencies() {
return this.packageEntity.dependency_links || [];
......@@ -154,11 +154,6 @@ export default {
formatSize(size) {
return numberToHumanSize(size);
},
getPackageVersions() {
if (!this.packageEntity.versions) {
// this.fetchPackageVersions();
}
},
async deletePackage() {
const { data } = await this.$apollo.mutate({
mutation: destroyPackageMutation,
......@@ -329,24 +324,13 @@ export default {
</p>
</gl-tab>
<gl-tab
:title="__('Other versions')"
title-item-class="js-versions-tab"
@click="getPackageVersions"
>
<gl-tab :title="__('Other versions')" title-item-class="js-versions-tab">
<template v-if="isLoading && !hasVersions">
<packages-list-loader />
</template>
<template v-else-if="hasVersions">
<!-- <package-list-row
v-for="v in packageEntity.versions"
:key="v.id"
:package-entity="{ name: packageEntity.name, ...v }"
:package-link="v.id.toString()"
:disable-delete="true"
:show-package-type="false"
/> -->
<version-row v-for="v in packageEntity.versions.nodes" :key="v.id" :package-entity="v" />
</template>
<p v-else class="gl-mt-3" data-testid="no-versions-message">
......
<script>
import { GlLink, GlSprintf, GlTruncate } from '@gitlab/ui';
import { getIdFromGraphQLId } from '~/graphql_shared/utils';
import PackageTags from '~/packages/shared/components/package_tags.vue';
import PublishMethod from '~/packages/shared/components/publish_method.vue';
import ListItem from '~/vue_shared/components/registry/list_item.vue';
import TimeAgoTooltip from '~/vue_shared/components/time_ago_tooltip.vue';
import { PACKAGE_DEFAULT_STATUS } from '../../constants';
export default {
name: 'PackageListRow',
components: {
GlLink,
GlSprintf,
GlTruncate,
PackageTags,
PublishMethod,
ListItem,
TimeAgoTooltip,
},
props: {
packageEntity: {
type: Object,
required: true,
},
},
computed: {
packageLink() {
return `${getIdFromGraphQLId(this.packageEntity.id)}`;
},
disabledRow() {
return this.packageEntity.status && this.packageEntity.status !== PACKAGE_DEFAULT_STATUS;
},
},
};
</script>
<template>
<list-item :disabled="disabledRow">
<template #left-primary>
<div class="gl-display-flex gl-align-items-center gl-mr-3 gl-min-w-0">
<gl-link :href="packageLink" class="gl-text-body gl-min-w-0" :disabled="disabledRow">
<gl-truncate :text="packageEntity.name" />
</gl-link>
<package-tags
v-if="packageEntity.tags.nodes && packageEntity.tags.nodes.length"
class="gl-ml-3"
:tags="packageEntity.tags.nodes"
hide-label
:tag-display-limit="1"
/>
</div>
</template>
<template #left-secondary>
{{ packageEntity.version }}
</template>
<template #right-primary>
<publish-method :package-entity="packageEntity" />
</template>
<template #right-secondary>
<gl-sprintf :message="__('Created %{timestamp}')">
<template #timestamp>
<time-ago-tooltip :time="packageEntity.createdAt" />
</template>
</gl-sprintf>
</template>
</list-item>
</template>
......@@ -79,10 +79,10 @@ export const FETCH_PACKAGE_DETAILS_ERROR_MESSAGE = s__(
'PackageRegistry|Failed to load the package data',
);
export const PACKAGE_ERROR_STATUS = 'error';
export const PACKAGE_DEFAULT_STATUS = 'default';
export const PACKAGE_HIDDEN_STATUS = 'hidden';
export const PACKAGE_PROCESSING_STATUS = 'processing';
export const PACKAGE_ERROR_STATUS = 'ERROR';
export const PACKAGE_DEFAULT_STATUS = 'DEFAULT';
export const PACKAGE_HIDDEN_STATUS = 'HIDDEN';
export const PACKAGE_PROCESSING_STATUS = 'PROCESSING';
export const NPM_PACKAGE_MANAGER = 'npm';
export const YARN_PACKAGE_MANAGER = 'yarn';
......@@ -7,7 +7,10 @@ query getPackageDetails($id: ID!) {
createdAt
updatedAt
status
tags {
project {
path
}
tags(first: 10) {
nodes {
id
name
......@@ -42,6 +45,21 @@ query getPackageDetails($id: ID!) {
downloadPath
}
}
versions(first: 100) {
nodes {
id
name
createdAt
version
status
tags(first: 1) {
nodes {
id
name
}
}
}
}
metadata {
... on ComposerMetadata {
targetSha
......
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`VersionRow renders 1`] = `
<div
class="gl-display-flex gl-flex-direction-column gl-border-b-solid gl-border-t-solid gl-border-t-1 gl-border-b-1 gl-border-t-transparent gl-border-b-gray-100"
>
<div
class="gl-display-flex gl-align-items-center gl-py-3 gl-px-5"
>
<!---->
<div
class="gl-display-flex gl-xs-flex-direction-column gl-justify-content-space-between gl-align-items-stretch gl-flex-grow-1"
>
<div
class="gl-display-flex gl-flex-direction-column gl-xs-mb-3 gl-min-w-0 gl-flex-grow-1"
>
<div
class="gl-display-flex gl-align-items-center gl-text-body gl-font-weight-bold gl-min-h-6 gl-min-w-0"
>
<div
class="gl-display-flex gl-align-items-center gl-mr-3 gl-min-w-0"
>
<gl-link-stub
class="gl-text-body gl-min-w-0"
href="243"
>
<span
class="gl-truncate"
title="@gitlab-org/package-15"
>
<span
class="gl-truncate-end"
>
@gitlab-org/package-15
</span>
</span>
</gl-link-stub>
<package-tags-stub
class="gl-ml-3"
hidelabel="true"
tagdisplaylimit="1"
tags="[object Object],[object Object],[object Object]"
/>
</div>
<!---->
</div>
<div
class="gl-display-flex gl-align-items-center gl-text-gray-500 gl-min-h-6 gl-min-w-0 gl-flex-grow-1"
>
1.0.1
</div>
</div>
<div
class="gl-display-flex gl-flex-direction-column gl-sm-align-items-flex-end gl-justify-content-space-between gl-text-gray-500 gl-flex-shrink-0"
>
<div
class="gl-display-flex gl-align-items-center gl-sm-text-body gl-sm-font-weight-bold gl-min-h-6"
>
<publish-method-stub
packageentity="[object Object]"
/>
</div>
<div
class="gl-display-flex gl-align-items-center gl-min-h-6"
>
Created
<time-ago-tooltip-stub
cssclass=""
time="2021-08-10T09:33:54Z"
tooltipplacement="top"
/>
</div>
</div>
</div>
<!---->
</div>
<div
class="gl-display-flex"
>
<div
class="gl-w-7"
/>
<!---->
<div
class="gl-w-9"
/>
</div>
</div>
`;
......@@ -14,6 +14,7 @@ import InstallationCommands from '~/packages_and_registries/package_registry/com
import PackageFiles from '~/packages_and_registries/package_registry/components/details/package_files.vue';
import PackageHistory from '~/packages_and_registries/package_registry/components/details/package_history.vue';
import PackageTitle from '~/packages_and_registries/package_registry/components/details/package_title.vue';
import VersionRow from '~/packages_and_registries/package_registry/components/details/version_row.vue';
import {
FETCH_PACKAGE_DETAILS_ERROR_MESSAGE,
DELETE_PACKAGE_ERROR_MESSAGE,
......@@ -28,6 +29,7 @@ import getPackageDetails from '~/packages_and_registries/package_registry/graphq
import {
packageDetailsQuery,
packageData,
packageVersions,
emptyPackageDetailsQuery,
packageDestroyMutation,
packageDestroyMutationError,
......@@ -96,6 +98,8 @@ describe('PackagesApp', () => {
const findDeleteButton = () => wrapper.findByTestId('delete-package');
const findPackageFiles = () => wrapper.findComponent(PackageFiles);
const findDeleteFileModal = () => wrapper.findByTestId('delete-file-modal');
const findVersionRows = () => wrapper.findAllComponents(VersionRow);
const noVersionsMessage = () => wrapper.findByTestId('no-versions-message');
afterEach(() => {
wrapper.destroy();
......@@ -362,4 +366,39 @@ describe('PackagesApp', () => {
});
});
});
describe('versions', () => {
it('displays the correct version count when the package has versions', async () => {
createComponent();
await waitForPromises();
expect(findVersionRows()).toHaveLength(packageVersions().length);
});
it('binds the correct props', async () => {
const [versionPackage] = packageVersions();
// eslint-disable-next-line no-underscore-dangle
delete versionPackage.__typename;
delete versionPackage.tags;
createComponent();
await waitForPromises();
expect(findVersionRows().at(0).props()).toMatchObject({
packageEntity: expect.objectContaining(versionPackage),
});
});
it('displays the no versions message when there are none', async () => {
createComponent({
resolver: jest.fn().mockResolvedValue(packageDetailsQuery({ versions: { nodes: [] } })),
});
await waitForPromises();
expect(noVersionsMessage().exists()).toBe(true);
});
});
});
import { GlLink, GlSprintf, GlTruncate } from '@gitlab/ui';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import { getIdFromGraphQLId } from '~/graphql_shared/utils';
import PackageTags from '~/packages/shared/components/package_tags.vue';
import PublishMethod from '~/packages/shared/components/publish_method.vue';
import VersionRow from '~/packages_and_registries/package_registry/components/details/version_row.vue';
import ListItem from '~/vue_shared/components/registry/list_item.vue';
import TimeAgoTooltip from '~/vue_shared/components/time_ago_tooltip.vue';
import { packageVersions } from '../../mock_data';
const packageVersion = packageVersions()[0];
describe('VersionRow', () => {
let wrapper;
const findListItem = () => wrapper.findComponent(ListItem);
const findLink = () => wrapper.findComponent(GlLink);
const findPackageTags = () => wrapper.findComponent(PackageTags);
const findPublishMethod = () => wrapper.findComponent(PublishMethod);
const findTimeAgoTooltip = () => wrapper.findComponent(TimeAgoTooltip);
function createComponent(packageEntity = packageVersion) {
wrapper = shallowMountExtended(VersionRow, {
propsData: {
packageEntity,
},
stubs: {
ListItem,
GlSprintf,
GlTruncate,
},
});
}
afterEach(() => {
wrapper.destroy();
});
it('renders', () => {
createComponent();
expect(wrapper.element).toMatchSnapshot();
});
it('has a link to the version detail', () => {
createComponent();
expect(findLink().attributes('href')).toBe(`${getIdFromGraphQLId(packageVersion.id)}`);
expect(findLink().text()).toBe(packageVersion.name);
});
it('has the version of the package', () => {
createComponent();
expect(wrapper.text()).toContain(packageVersion.version);
});
it('has a package tags component', () => {
createComponent();
expect(findPackageTags().props('tags')).toBe(packageVersion.tags.nodes);
});
it('has a publish method component', () => {
createComponent();
expect(findPublishMethod().props('packageEntity')).toBe(packageVersion);
});
it('has a time-ago tooltip', () => {
createComponent();
expect(findTimeAgoTooltip().props('time')).toBe(packageVersion.createdAt);
});
describe('disabled status', () => {
it('disables the list item', () => {
createComponent({ ...packageVersion, status: 'something' });
expect(findListItem().props('disabled')).toBe(true);
});
it('disables the link', () => {
createComponent({ ...packageVersion, status: 'something' });
expect(findLink().attributes('disabled')).toBe('true');
});
});
});
......@@ -51,6 +51,27 @@ export const packageFiles = () => [
},
];
export const packageVersions = () => [
{
createdAt: '2021-08-10T09:33:54Z',
id: 'gid://gitlab/Packages::Package/243',
name: '@gitlab-org/package-15',
status: 'DEFAULT',
tags: { nodes: packageTags() },
version: '1.0.1',
__typename: 'Package',
},
{
createdAt: '2021-08-10T09:33:54Z',
id: 'gid://gitlab/Packages::Package/244',
name: '@gitlab-org/package-15',
status: 'DEFAULT',
tags: { nodes: packageTags() },
version: '1.0.2',
__typename: 'Package',
},
];
export const packageData = (extend) => ({
id: 'gid://gitlab/Packages::Package/111',
name: '@gitlab-org/package-15',
......@@ -105,6 +126,9 @@ export const packageDetailsQuery = (extendPackage) => ({
...mavenMetadata(),
...nugetMetadata(),
},
project: {
path: 'projectPath',
},
tags: {
nodes: packageTags(),
__typename: 'PackageTagConnection',
......@@ -117,6 +141,10 @@ export const packageDetailsQuery = (extendPackage) => ({
nodes: packageFiles(),
__typename: 'PackageFileConnection',
},
versions: {
nodes: packageVersions(),
__typename: 'PackageConnection',
},
__typename: 'PackageDetailsType',
...extendPackage,
},
......
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