Commit 253e749b authored by Ezekiel Kigbo's avatar Ezekiel Kigbo

Merge branch '336389-investigate-layout-change-issue-in-package-details-title' into 'master'

Update package title to react to resize

See merge request gitlab-org/gitlab!69846
parents de542257 24cff0c9
<script> <script>
import { GlIcon, GlSprintf, GlBadge } from '@gitlab/ui'; import { GlIcon, GlSprintf, GlBadge, GlResizeObserverDirective } from '@gitlab/ui';
import { GlBreakpointInstance } from '@gitlab/ui/dist/utils'; import { GlBreakpointInstance } from '@gitlab/ui/dist/utils';
import { numberToHumanSize } from '~/lib/utils/number_utils'; import { numberToHumanSize } from '~/lib/utils/number_utils';
import { __ } from '~/locale'; import { __ } from '~/locale';
...@@ -21,6 +21,9 @@ export default { ...@@ -21,6 +21,9 @@ export default {
GlBadge, GlBadge,
TimeAgoTooltip, TimeAgoTooltip,
}, },
directives: {
GlResizeObserver: GlResizeObserverDirective,
},
i18n: { i18n: {
packageInfo: __('v%{version} published %{timeAgo}'), packageInfo: __('v%{version} published %{timeAgo}'),
}, },
...@@ -60,18 +63,26 @@ export default { ...@@ -60,18 +63,26 @@ export default {
}, },
}, },
mounted() { mounted() {
this.isDesktop = GlBreakpointInstance.isDesktop(); this.checkBreakpoints();
}, },
methods: { methods: {
dynamicSlotName(index) { dynamicSlotName(index) {
return `metadata-tag${index}`; return `metadata-tag${index}`;
}, },
checkBreakpoints() {
this.isDesktop = GlBreakpointInstance.isDesktop();
},
}, },
}; };
</script> </script>
<template> <template>
<title-area :title="packageEntity.name" :avatar="packageIcon" data-qa-selector="package_title"> <title-area
v-gl-resize-observer="checkBreakpoints"
:title="packageEntity.name"
:avatar="packageIcon"
data-qa-selector="package_title"
>
<template #sub-header> <template #sub-header>
<gl-icon name="eye" class="gl-mr-3" /> <gl-icon name="eye" class="gl-mr-3" />
<span data-testid="sub-header"> <span data-testid="sub-header">
......
<script> <script>
import { GlAvatar, GlSprintf, GlLink, GlSkeletonLoader } from '@gitlab/ui'; import { GlAvatar, GlSprintf, GlLink, GlSkeletonLoader } from '@gitlab/ui';
import { isEqual } from 'lodash';
export default { export default {
name: 'TitleArea', name: 'TitleArea',
...@@ -36,13 +37,21 @@ export default { ...@@ -36,13 +37,21 @@ export default {
metadataSlots: [], metadataSlots: [],
}; };
}, },
async mounted() { mounted() {
const METADATA_PREFIX = 'metadata-'; this.recalculateMetadataSlots();
this.metadataSlots = Object.keys(this.$slots).filter((k) => k.startsWith(METADATA_PREFIX)); },
updated() {
this.recalculateMetadataSlots();
},
methods: {
recalculateMetadataSlots() {
const METADATA_PREFIX = 'metadata-';
const metadataSlots = Object.keys(this.$slots).filter((k) => k.startsWith(METADATA_PREFIX));
// we need to wait for next tick to ensure that dynamic names slots are picked up if (!isEqual(metadataSlots, this.metadataSlots)) {
await this.$nextTick(); this.metadataSlots = metadataSlots;
this.metadataSlots = Object.keys(this.$slots).filter((k) => k.startsWith(METADATA_PREFIX)); }
},
}, },
}; };
</script> </script>
......
...@@ -177,15 +177,6 @@ exports[`PackageTitle renders without tags 1`] = ` ...@@ -177,15 +177,6 @@ exports[`PackageTitle renders without tags 1`] = `
texttooltip="" texttooltip=""
/> />
</div> </div>
<div
class="gl-display-flex gl-align-items-center gl-mr-5"
>
<package-tags-stub
hidelabel="true"
tagdisplaylimit="2"
tags="[object Object],[object Object],[object Object]"
/>
</div>
</div> </div>
</div> </div>
......
import { GlIcon, GlSprintf } from '@gitlab/ui'; import { GlIcon, GlSprintf } from '@gitlab/ui';
import { GlBreakpointInstance } from '@gitlab/ui/dist/utils'; import { GlBreakpointInstance } from '@gitlab/ui/dist/utils';
import { createMockDirective, getBinding } from 'helpers/vue_mock_directive';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper'; import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import PackageTags from '~/packages/shared/components/package_tags.vue'; import PackageTags from '~/packages/shared/components/package_tags.vue';
import PackageTitle from '~/packages_and_registries/package_registry/components/details/package_title.vue'; import PackageTitle from '~/packages_and_registries/package_registry/components/details/package_title.vue';
...@@ -30,6 +31,9 @@ describe('PackageTitle', () => { ...@@ -30,6 +31,9 @@ describe('PackageTitle', () => {
TitleArea, TitleArea,
GlSprintf, GlSprintf,
}, },
directives: {
GlResizeObserver: createMockDirective(),
},
}); });
return wrapper.vm.$nextTick(); return wrapper.vm.$nextTick();
} }
...@@ -51,7 +55,7 @@ describe('PackageTitle', () => { ...@@ -51,7 +55,7 @@ describe('PackageTitle', () => {
describe('renders', () => { describe('renders', () => {
it('without tags', async () => { it('without tags', async () => {
await createComponent(); await createComponent({ ...packageData(), packageFiles: { nodes: packageFiles() } });
expect(wrapper.element).toMatchSnapshot(); expect(wrapper.element).toMatchSnapshot();
}); });
...@@ -64,12 +68,26 @@ describe('PackageTitle', () => { ...@@ -64,12 +68,26 @@ describe('PackageTitle', () => {
it('with tags on mobile', async () => { it('with tags on mobile', async () => {
jest.spyOn(GlBreakpointInstance, 'isDesktop').mockReturnValue(false); jest.spyOn(GlBreakpointInstance, 'isDesktop').mockReturnValue(false);
await createComponent(); await createComponent();
await wrapper.vm.$nextTick(); await wrapper.vm.$nextTick();
expect(findPackageBadges()).toHaveLength(packageTags().length); expect(findPackageBadges()).toHaveLength(packageTags().length);
}); });
it('when the page is resized', async () => {
await createComponent();
expect(findPackageBadges()).toHaveLength(0);
jest.spyOn(GlBreakpointInstance, 'isDesktop').mockReturnValue(false);
const { value } = getBinding(wrapper.element, 'gl-resize-observer');
value();
await wrapper.vm.$nextTick();
expect(findPackageBadges()).toHaveLength(packageTags().length);
});
}); });
describe('package title', () => { describe('package title', () => {
......
...@@ -135,15 +135,16 @@ describe('title area', () => { ...@@ -135,15 +135,16 @@ describe('title area', () => {
}, },
}); });
}; };
it('shows dynamic slots', async () => { it('shows dynamic slots', async () => {
mountComponent(); mountComponent();
// we manually add a new slot to simulate dynamic slots being evaluated after the initial mount // we manually add a new slot to simulate dynamic slots being evaluated after the initial mount
wrapper.vm.$slots[DYNAMIC_SLOT] = createDynamicSlot(); wrapper.vm.$slots[DYNAMIC_SLOT] = createDynamicSlot();
// updating the slots like we do on line 141 does not cause the updated lifecycle-hook to be triggered
wrapper.vm.$forceUpdate();
await wrapper.vm.$nextTick(); await wrapper.vm.$nextTick();
expect(findDynamicSlot().exists()).toBe(false);
await wrapper.vm.$nextTick();
expect(findDynamicSlot().exists()).toBe(true); expect(findDynamicSlot().exists()).toBe(true);
}); });
...@@ -160,10 +161,8 @@ describe('title area', () => { ...@@ -160,10 +161,8 @@ describe('title area', () => {
'metadata-foo': wrapper.vm.$slots['metadata-foo'], 'metadata-foo': wrapper.vm.$slots['metadata-foo'],
}; };
await wrapper.vm.$nextTick(); // updating the slots like we do on line 159 does not cause the updated lifecycle-hook to be triggered
expect(findDynamicSlot().exists()).toBe(false); wrapper.vm.$forceUpdate();
expect(findMetadataSlot('metadata-foo').exists()).toBe(true);
await wrapper.vm.$nextTick(); await wrapper.vm.$nextTick();
expect(findSlotOrderElements().at(0).attributes('data-testid')).toBe(DYNAMIC_SLOT); expect(findSlotOrderElements().at(0).attributes('data-testid')).toBe(DYNAMIC_SLOT);
......
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