Commit 24cff0c9 authored by Nicolò Maria Mezzopera's avatar Nicolò Maria Mezzopera Committed by Ezekiel Kigbo

Update package title to react to resize

parent 446c75a1
<script>
import { GlIcon, GlSprintf, GlBadge } from '@gitlab/ui';
import { GlIcon, GlSprintf, GlBadge, GlResizeObserverDirective } from '@gitlab/ui';
import { GlBreakpointInstance } from '@gitlab/ui/dist/utils';
import { numberToHumanSize } from '~/lib/utils/number_utils';
import { __ } from '~/locale';
......@@ -21,6 +21,9 @@ export default {
GlBadge,
TimeAgoTooltip,
},
directives: {
GlResizeObserver: GlResizeObserverDirective,
},
i18n: {
packageInfo: __('v%{version} published %{timeAgo}'),
},
......@@ -60,18 +63,26 @@ export default {
},
},
mounted() {
this.isDesktop = GlBreakpointInstance.isDesktop();
this.checkBreakpoints();
},
methods: {
dynamicSlotName(index) {
return `metadata-tag${index}`;
},
checkBreakpoints() {
this.isDesktop = GlBreakpointInstance.isDesktop();
},
},
};
</script>
<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>
<gl-icon name="eye" class="gl-mr-3" />
<span data-testid="sub-header">
......
<script>
import { GlAvatar, GlSprintf, GlLink, GlSkeletonLoader } from '@gitlab/ui';
import { isEqual } from 'lodash';
export default {
name: 'TitleArea',
......@@ -36,13 +37,21 @@ export default {
metadataSlots: [],
};
},
async mounted() {
const METADATA_PREFIX = 'metadata-';
this.metadataSlots = Object.keys(this.$slots).filter((k) => k.startsWith(METADATA_PREFIX));
mounted() {
this.recalculateMetadataSlots();
},
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
await this.$nextTick();
this.metadataSlots = Object.keys(this.$slots).filter((k) => k.startsWith(METADATA_PREFIX));
if (!isEqual(metadataSlots, this.metadataSlots)) {
this.metadataSlots = metadataSlots;
}
},
},
};
</script>
......
......@@ -177,15 +177,6 @@ exports[`PackageTitle renders without tags 1`] = `
texttooltip=""
/>
</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>
......
import { GlIcon, GlSprintf } from '@gitlab/ui';
import { GlBreakpointInstance } from '@gitlab/ui/dist/utils';
import { createMockDirective, getBinding } from 'helpers/vue_mock_directive';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import PackageTags from '~/packages/shared/components/package_tags.vue';
import PackageTitle from '~/packages_and_registries/package_registry/components/details/package_title.vue';
......@@ -30,6 +31,9 @@ describe('PackageTitle', () => {
TitleArea,
GlSprintf,
},
directives: {
GlResizeObserver: createMockDirective(),
},
});
return wrapper.vm.$nextTick();
}
......@@ -51,7 +55,7 @@ describe('PackageTitle', () => {
describe('renders', () => {
it('without tags', async () => {
await createComponent();
await createComponent({ ...packageData(), packageFiles: { nodes: packageFiles() } });
expect(wrapper.element).toMatchSnapshot();
});
......@@ -64,12 +68,26 @@ describe('PackageTitle', () => {
it('with tags on mobile', async () => {
jest.spyOn(GlBreakpointInstance, 'isDesktop').mockReturnValue(false);
await createComponent();
await wrapper.vm.$nextTick();
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', () => {
......
......@@ -135,15 +135,16 @@ describe('title area', () => {
},
});
};
it('shows dynamic slots', async () => {
mountComponent();
// we manually add a new slot to simulate dynamic slots being evaluated after the initial mount
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();
expect(findDynamicSlot().exists()).toBe(false);
await wrapper.vm.$nextTick();
expect(findDynamicSlot().exists()).toBe(true);
});
......@@ -160,10 +161,8 @@ describe('title area', () => {
'metadata-foo': wrapper.vm.$slots['metadata-foo'],
};
await wrapper.vm.$nextTick();
expect(findDynamicSlot().exists()).toBe(false);
expect(findMetadataSlot('metadata-foo').exists()).toBe(true);
// updating the slots like we do on line 159 does not cause the updated lifecycle-hook to be triggered
wrapper.vm.$forceUpdate();
await wrapper.vm.$nextTick();
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