Skip to content
Snippets Groups Projects
Commit 24cff0c9 authored by Nicolò Maria Mezzopera's avatar Nicolò Maria Mezzopera Committed by Ezekiel Kigbo
Browse files

Update package title to react to resize

parent 446c75a1
No related branches found
No related tags found
1 merge request!69846Update package title to react to resize
<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);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment