Commit 85c18432 authored by Nicolò Maria Mezzopera's avatar Nicolò Maria Mezzopera Committed by Paul Slaughter

Add skeleton loader to title_area

- source
- tests

https://gitlab.com/gitlab-org/gitlab/-/merge_requests/50181
parent d9465f87
...@@ -43,6 +43,11 @@ export default { ...@@ -43,6 +43,11 @@ export default {
required: false, required: false,
default: false, default: false,
}, },
metadataLoading: {
type: Boolean,
required: false,
default: false,
},
}, },
loader: { loader: {
repeat: 10, repeat: 10,
...@@ -92,7 +97,11 @@ export default { ...@@ -92,7 +97,11 @@ export default {
</script> </script>
<template> <template>
<title-area :title="$options.i18n.CONTAINER_REGISTRY_TITLE" :info-messages="infoMessages"> <title-area
:title="$options.i18n.CONTAINER_REGISTRY_TITLE"
:info-messages="infoMessages"
:metadata-loading="metadataLoading"
>
<template #right-actions> <template #right-actions>
<slot name="commands"></slot> <slot name="commands"></slot>
</template> </template>
......
...@@ -242,6 +242,7 @@ export default { ...@@ -242,6 +242,7 @@ export default {
<template v-else> <template v-else>
<registry-header <registry-header
:metadata-loading="isLoading"
:images-count="containerRepositoriesCount" :images-count="containerRepositoriesCount"
:expiration-policy="config.expirationPolicy" :expiration-policy="config.expirationPolicy"
:help-page-path="config.helpPagePath" :help-page-path="config.helpPagePath"
......
<script> <script>
import { GlAvatar, GlSprintf, GlLink } from '@gitlab/ui'; import { GlAvatar, GlSprintf, GlLink, GlSkeletonLoader } from '@gitlab/ui';
export default { export default {
name: 'TitleArea', name: 'TitleArea',
...@@ -7,6 +7,7 @@ export default { ...@@ -7,6 +7,7 @@ export default {
GlAvatar, GlAvatar,
GlSprintf, GlSprintf,
GlLink, GlLink,
GlSkeletonLoader,
}, },
props: { props: {
avatar: { avatar: {
...@@ -24,6 +25,11 @@ export default { ...@@ -24,6 +25,11 @@ export default {
default: () => [], default: () => [],
required: false, required: false,
}, },
metadataLoading: {
type: Boolean,
required: false,
default: false,
},
}, },
data() { data() {
return { return {
...@@ -68,13 +74,23 @@ export default { ...@@ -68,13 +74,23 @@ export default {
</div> </div>
<div class="gl-display-flex gl-flex-wrap gl-align-items-center gl-mt-3"> <div class="gl-display-flex gl-flex-wrap gl-align-items-center gl-mt-3">
<div <template v-if="!metadataLoading">
v-for="(row, metadataIndex) in metadataSlots" <div
:key="metadataIndex" v-for="(row, metadataIndex) in metadataSlots"
class="gl-display-flex gl-align-items-center gl-mr-5" :key="metadataIndex"
> class="gl-display-flex gl-align-items-center gl-mr-5"
<slot :name="row"></slot> >
</div> <slot :name="row"></slot>
</div>
</template>
<template v-else>
<div class="gl-w-full">
<gl-skeleton-loader :width="200" :height="16" preserve-aspect-ratio="xMinYMax meet">
<circle cx="6" cy="8" r="6" />
<rect x="16" y="4" width="200" height="8" rx="4" />
</gl-skeleton-loader>
</div>
</template>
</div> </div>
</div> </div>
<div v-if="$slots['right-actions']" class="gl-mt-3"> <div v-if="$slots['right-actions']" class="gl-mt-3">
......
---
title: Adjust container registry metadata during loading
merge_request: 50181
author:
type: changed
...@@ -41,9 +41,12 @@ describe('registry_header', () => { ...@@ -41,9 +41,12 @@ describe('registry_header', () => {
describe('header', () => { describe('header', () => {
it('has a title', () => { it('has a title', () => {
mountComponent(); mountComponent({ metadataLoading: true });
expect(findTitleArea().props('title')).toBe(CONTAINER_REGISTRY_TITLE); expect(findTitleArea().props()).toMatchObject({
title: CONTAINER_REGISTRY_TITLE,
metadataLoading: true,
});
}); });
it('has a commands slot', () => { it('has a commands slot', () => {
......
...@@ -116,6 +116,7 @@ describe('List Page', () => { ...@@ -116,6 +116,7 @@ describe('List Page', () => {
expect(findRegistryHeader().exists()).toBe(true); expect(findRegistryHeader().exists()).toBe(true);
expect(findRegistryHeader().props()).toMatchObject({ expect(findRegistryHeader().props()).toMatchObject({
imagesCount: 2, imagesCount: 2,
metadataLoading: false,
}); });
}); });
...@@ -170,6 +171,12 @@ describe('List Page', () => { ...@@ -170,6 +171,12 @@ describe('List Page', () => {
expect(findCliCommands().exists()).toBe(false); expect(findCliCommands().exists()).toBe(false);
}); });
it('title has the metadataLoading props set to true', () => {
mountComponent();
expect(findRegistryHeader().props('metadataLoading')).toBe(true);
});
}); });
describe('list is empty', () => { describe('list is empty', () => {
......
import { GlAvatar, GlSprintf, GlLink } from '@gitlab/ui'; import { GlAvatar, GlSprintf, GlLink, GlSkeletonLoader } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils'; import { shallowMount } from '@vue/test-utils';
import component from '~/vue_shared/components/registry/title_area.vue'; import component from '~/vue_shared/components/registry/title_area.vue';
...@@ -15,6 +15,7 @@ describe('title area', () => { ...@@ -15,6 +15,7 @@ describe('title area', () => {
const findInfoMessages = () => wrapper.findAll('[data-testid="info-message"]'); const findInfoMessages = () => wrapper.findAll('[data-testid="info-message"]');
const findDynamicSlot = () => wrapper.find(`[data-testid="${DYNAMIC_SLOT}`); const findDynamicSlot = () => wrapper.find(`[data-testid="${DYNAMIC_SLOT}`);
const findSlotOrderElements = () => wrapper.findAll('[slot-test]'); const findSlotOrderElements = () => wrapper.findAll('[slot-test]');
const findSkeletonLoader = () => wrapper.find(GlSkeletonLoader);
const mountComponent = ({ propsData = { title: 'foo' }, slots } = {}) => { const mountComponent = ({ propsData = { title: 'foo' }, slots } = {}) => {
wrapper = shallowMount(component, { wrapper = shallowMount(component, {
...@@ -100,6 +101,29 @@ describe('title area', () => { ...@@ -100,6 +101,29 @@ describe('title area', () => {
expect(findMetadataSlot(name).exists()).toBe(true); expect(findMetadataSlot(name).exists()).toBe(true);
}); });
}); });
it('is/are hidden when metadata-loading is true', async () => {
mountComponent({ slots: slotMocks, propsData: { title: 'foo', metadataLoading: true } });
await wrapper.vm.$nextTick();
slotNames.forEach(name => {
expect(findMetadataSlot(name).exists()).toBe(false);
});
});
});
describe('metadata skeleton loader', () => {
it('is hidden when metadata loading is false', () => {
mountComponent();
expect(findSkeletonLoader().exists()).toBe(false);
});
it('is shown when metadata loading is true', () => {
mountComponent({ propsData: { metadataLoading: true } });
expect(findSkeletonLoader().exists()).toBe(true);
});
}); });
describe('dynamic slots', () => { describe('dynamic slots', () => {
......
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