Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
1
Merge Requests
1
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
gitlab-ce
Commits
e3616635
Commit
e3616635
authored
Sep 18, 2020
by
Nicolò Maria Mezzopera
Committed by
Paul Slaughter
Sep 18, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add info_line to registry/title_area component
https://gitlab.com/gitlab-org/gitlab/-/merge_requests/42443
parent
fa2ee656
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
250 additions
and
242 deletions
+250
-242
app/assets/javascripts/registry/explorer/components/list_page/registry_header.vue
...egistry/explorer/components/list_page/registry_header.vue
+31
-48
app/assets/javascripts/vue_shared/components/registry/title_area.vue
...javascripts/vue_shared/components/registry/title_area.vue
+52
-24
spec/frontend/packages/details/components/__snapshots__/package_title_spec.js.snap
...tails/components/__snapshots__/package_title_spec.js.snap
+113
-101
spec/frontend/registry/explorer/components/list_page/registry_header_spec.js
...try/explorer/components/list_page/registry_header_spec.js
+22
-68
spec/frontend/vue_shared/components/registry/title_area_spec.js
...rontend/vue_shared/components/registry/title_area_spec.js
+32
-1
No files found.
app/assets/javascripts/registry/explorer/components/list_page/registry_header.vue
View file @
e3616635
<
script
>
import
{
GlSprintf
,
GlLink
}
from
'
@gitlab/ui
'
;
import
TitleArea
from
'
~/vue_shared/components/registry/title_area.vue
'
;
import
MetadataItem
from
'
~/vue_shared/components/registry/metadata_item.vue
'
;
import
{
n__
,
sprintf
}
from
'
~/locale
'
;
...
...
@@ -15,8 +14,6 @@ import {
export
default
{
components
:
{
GlSprintf
,
GlLink
,
TitleArea
,
MetadataItem
,
},
...
...
@@ -54,8 +51,6 @@ export default {
},
i18n
:
{
CONTAINER_REGISTRY_TITLE
,
LIST_INTRO_TEXT
,
EXPIRATION_POLICY_DISABLED_MESSAGE
,
},
computed
:
{
imagesCountText
()
{
...
...
@@ -83,52 +78,40 @@ export default {
!
this
.
expirationPolicyEnabled
&&
this
.
imagesCount
>
0
&&
!
this
.
hideExpirationPolicyData
);
},
infoMessages
()
{
const
base
=
[{
text
:
LIST_INTRO_TEXT
,
link
:
this
.
helpPagePath
}];
return
this
.
showExpirationPolicyTip
?
[
...
base
,
{
text
:
EXPIRATION_POLICY_DISABLED_MESSAGE
,
link
:
this
.
expirationPolicyHelpPagePath
},
]
:
base
;
},
},
};
</
script
>
<
template
>
<div>
<title-area
:title=
"$options.i18n.CONTAINER_REGISTRY_TITLE"
>
<template
#right-actions
>
<slot
name=
"commands"
></slot>
</
template
>
<
template
#metadata_count
>
<metadata-item
v-if=
"imagesCount"
data-testid=
"images-count"
icon=
"container-image"
:text=
"imagesCountText"
/>
</
template
>
<
template
#metadata_exp_policies
>
<metadata-item
v-if=
"!hideExpirationPolicyData"
data-testid=
"expiration-policy"
icon=
"expire"
:text=
"expirationPolicyText"
size=
"xl"
/>
</
template
>
</title-area>
<div
data-testid=
"info-area"
>
<p>
<span
data-testid=
"default-intro"
>
<gl-sprintf
:message=
"$options.i18n.LIST_INTRO_TEXT"
>
<
template
#docLink=
"{content}"
>
<gl-link
:href=
"helpPagePath"
target=
"_blank"
>
{{
content
}}
</gl-link>
</
template
>
</gl-sprintf>
</span>
<span
v-if=
"showExpirationPolicyTip"
data-testid=
"expiration-disabled-message"
>
<gl-sprintf
:message=
"$options.i18n.EXPIRATION_POLICY_DISABLED_MESSAGE"
>
<
template
#docLink=
"{content}"
>
<gl-link
:href=
"expirationPolicyHelpPagePath"
target=
"_blank"
>
{{
content
}}
</gl-link>
</
template
>
</gl-sprintf>
</span>
</p>
</div>
</div>
<title-area
:title=
"$options.i18n.CONTAINER_REGISTRY_TITLE"
:info-messages=
"infoMessages"
>
<template
#right-actions
>
<slot
name=
"commands"
></slot>
</
template
>
<
template
#metadata_count
>
<metadata-item
v-if=
"imagesCount"
data-testid=
"images-count"
icon=
"container-image"
:text=
"imagesCountText"
/>
</
template
>
<
template
#metadata_exp_policies
>
<metadata-item
v-if=
"!hideExpirationPolicyData"
data-testid=
"expiration-policy"
icon=
"expire"
:text=
"expirationPolicyText"
size=
"xl"
/>
</
template
>
</title-area>
</template>
app/assets/javascripts/vue_shared/components/registry/title_area.vue
View file @
e3616635
<
script
>
import
{
GlAvatar
}
from
'
@gitlab/ui
'
;
import
{
GlAvatar
,
GlSprintf
,
GlLink
}
from
'
@gitlab/ui
'
;
export
default
{
name
:
'
TitleArea
'
,
components
:
{
GlAvatar
,
GlSprintf
,
GlLink
,
},
props
:
{
avatar
:
{
...
...
@@ -17,6 +19,11 @@ export default {
default
:
null
,
required
:
false
,
},
infoMessages
:
{
type
:
Array
,
default
:
()
=>
[],
required
:
false
,
},
},
data
()
{
return
{
...
...
@@ -30,37 +37,58 @@ export default {
</
script
>
<
template
>
<div
class=
"gl-display-flex gl-justify-content-space-between gl-py-3"
>
<div
class=
"gl-flex-direction-column"
>
<div
class=
"gl-display-flex"
>
<gl-avatar
v-if=
"avatar"
:src=
"avatar"
shape=
"rect"
class=
"gl-align-self-center gl-mr-4"
/>
<div
class=
"gl-display-flex gl-flex-direction-column"
>
<div
class=
"gl-display-flex gl-justify-content-space-between gl-py-3"
>
<div
class=
"gl-flex-direction-column"
>
<div
class=
"gl-display-flex"
>
<gl-avatar
v-if=
"avatar"
:src=
"avatar"
shape=
"rect"
class=
"gl-align-self-center gl-mr-4"
/>
<div
class=
"gl-display-flex gl-flex-direction-column"
>
<h1
class=
"gl-font-size-h1 gl-mt-3 gl-mb-2"
data-testid=
"title"
>
<slot
name=
"title"
>
{{
title
}}
</slot>
</h1>
<div
class=
"gl-display-flex gl-flex-direction-column"
>
<h1
class=
"gl-font-size-h1 gl-mt-3 gl-mb-2"
data-testid=
"title"
>
<slot
name=
"title"
>
{{
title
}}
</slot>
</h1>
<div
v-if=
"$slots['sub-header']"
class=
"gl-display-flex gl-align-items-center gl-text-gray-500 gl-mt-1"
>
<slot
name=
"sub-header"
></slot>
</div>
</div>
</div>
<div
class=
"gl-display-flex gl-flex-wrap gl-align-items-center gl-mt-3"
>
<div
v-if=
"$slots['sub-header']"
class=
"gl-display-flex gl-align-items-center gl-text-gray-500 gl-mt-1"
v-for=
"(row, metadataIndex) in metadataSlots"
:key=
"metadataIndex"
class=
"gl-display-flex gl-align-items-center gl-mr-5"
>
<slot
name=
"sub-header
"
></slot>
<slot
:name=
"row
"
></slot>
</div>
</div>
</div>
<div
class=
"gl-display-flex gl-flex-wrap gl-align-items-center gl-mt-3"
>
<div
v-for=
"(row, metadataIndex) in metadataSlots"
:key=
"metadataIndex"
class=
"gl-display-flex gl-align-items-center gl-mr-5"
>
<slot
:name=
"row"
></slot>
</div>
<div
v-if=
"$slots['right-actions']"
class=
"gl-mt-3"
>
<slot
name=
"right-actions"
></slot>
</div>
</div>
<div
v-if=
"$slots['right-actions']"
class=
"gl-mt-3"
>
<slot
name=
"right-actions"
></slot>
</div>
<p>
<span
v-for=
"(message, index) in infoMessages"
:key=
"index"
class=
"gl-mr-2"
data-testid=
"info-message"
>
<gl-sprintf
:message=
"message.text"
>
<template
#docLink
="
{content}">
<gl-link
:href=
"message.link"
target=
"_blank"
>
{{
content
}}
</gl-link>
</
template
>
</gl-sprintf>
</span>
</p>
</div>
</template>
spec/frontend/packages/details/components/__snapshots__/package_title_spec.js.snap
View file @
e3616635
...
...
@@ -2,151 +2,163 @@
exports[`PackageTitle renders with tags 1`] = `
<div
class="gl-display-flex gl-
justify-content-space-between gl-py-3
"
class="gl-display-flex gl-
flex-direction-column
"
data-qa-selector="package_title"
>
<div
class="gl-
flex-direction-column
"
class="gl-
display-flex gl-justify-content-space-between gl-py-3
"
>
<div
class="gl-
display-flex
"
class="gl-
flex-direction-column
"
>
<!---->
<div
class="gl-display-flex
gl-flex-direction-column
"
class="gl-display-flex"
>
<h1
class="gl-font-size-h1 gl-mt-3 gl-mb-2"
data-testid="title"
>
Test package
</h1>
<!---->
<div
class="gl-display-flex gl-
align-items-center gl-text-gray-500 gl-mt-1
"
class="gl-display-flex gl-
flex-direction-column
"
>
<gl-icon-stub
class="gl-mr-3"
name="eye"
size="16"
/>
<h1
class="gl-font-size-h1 gl-mt-3 gl-mb-2"
data-testid="title"
>
Test package
</h1>
<gl-sprintf-stub
message="v%{version} published %{timeAgo}"
/>
<div
class="gl-display-flex gl-align-items-center gl-text-gray-500 gl-mt-1"
>
<gl-icon-stub
class="gl-mr-3"
name="eye"
size="16"
/>
<gl-sprintf-stub
message="v%{version} published %{timeAgo}"
/>
</div>
</div>
</div>
</div>
<div
class="gl-display-flex gl-flex-wrap gl-align-items-center gl-mt-3"
>
<div
class="gl-display-flex gl-align-items-center gl-mr-5"
>
<metadata-item-stub
data-testid="package-type"
icon="package"
link=""
size="s"
text="maven"
/>
</div>
<div
class="gl-display-flex gl-align-items-center gl-mr-5"
>
<metadata-item-stub
data-testid="package-size"
icon="disk"
link=""
size="s"
text="300 bytes"
/>
</div>
<div
class="gl-display-flex gl-
align-items-center gl-mr-5
"
class="gl-display-flex gl-
flex-wrap gl-align-items-center gl-mt-3
"
>
<package-tags-stub
hidelabel="true"
tagdisplaylimit="2"
tags="[object Object],[object Object],[object Object],[object Object]"
/>
<div
class="gl-display-flex gl-align-items-center gl-mr-5"
>
<metadata-item-stub
data-testid="package-type"
icon="package"
link=""
size="s"
text="maven"
/>
</div>
<div
class="gl-display-flex gl-align-items-center gl-mr-5"
>
<metadata-item-stub
data-testid="package-size"
icon="disk"
link=""
size="s"
text="300 bytes"
/>
</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],[object Object]"
/>
</div>
</div>
</div>
<!---->
</div>
<
!----
>
<
p /
>
</div>
`;
exports[`PackageTitle renders without tags 1`] = `
<div
class="gl-display-flex gl-
justify-content-space-between gl-py-3
"
class="gl-display-flex gl-
flex-direction-column
"
data-qa-selector="package_title"
>
<div
class="gl-
flex-direction-column
"
class="gl-
display-flex gl-justify-content-space-between gl-py-3
"
>
<div
class="gl-
display-flex
"
class="gl-
flex-direction-column
"
>
<!---->
<div
class="gl-display-flex
gl-flex-direction-column
"
class="gl-display-flex"
>
<h1
class="gl-font-size-h1 gl-mt-3 gl-mb-2"
data-testid="title"
>
Test package
</h1>
<!---->
<div
class="gl-display-flex gl-
align-items-center gl-text-gray-500 gl-mt-1
"
class="gl-display-flex gl-
flex-direction-column
"
>
<gl-icon-stub
class="gl-mr-3"
name="eye"
size="16"
/>
<h1
class="gl-font-size-h1 gl-mt-3 gl-mb-2"
data-testid="title"
>
Test package
</h1>
<gl-sprintf-stub
message="v%{version} published %{timeAgo}"
/>
<div
class="gl-display-flex gl-align-items-center gl-text-gray-500 gl-mt-1"
>
<gl-icon-stub
class="gl-mr-3"
name="eye"
size="16"
/>
<gl-sprintf-stub
message="v%{version} published %{timeAgo}"
/>
</div>
</div>
</div>
</div>
<div
class="gl-display-flex gl-flex-wrap gl-align-items-center gl-mt-3"
>
<div
class="gl-display-flex gl-align-items-center gl-mr-5"
>
<metadata-item-stub
data-testid="package-type"
icon="package"
link=""
size="s"
text="maven"
/>
</div>
<div
class="gl-display-flex gl-
align-items-center gl-mr-5
"
class="gl-display-flex gl-
flex-wrap gl-align-items-center gl-mt-3
"
>
<metadata-item-stub
data-testid="package-size"
icon="disk"
link=""
size="s"
text="300 bytes"
/>
<div
class="gl-display-flex gl-align-items-center gl-mr-5"
>
<metadata-item-stub
data-testid="package-type"
icon="package"
link=""
size="s"
text="maven"
/>
</div>
<div
class="gl-display-flex gl-align-items-center gl-mr-5"
>
<metadata-item-stub
data-testid="package-size"
icon="disk"
link=""
size="s"
text="300 bytes"
/>
</div>
</div>
</div>
<!---->
</div>
<
!----
>
<
p /
>
</div>
`;
spec/frontend/registry/explorer/components/list_page/registry_header_spec.js
View file @
e3616635
import
{
shallowMount
}
from
'
@vue/test-utils
'
;
import
{
GlSprintf
,
GlLink
}
from
'
@gitlab/ui
'
;
import
{
GlSprintf
}
from
'
@gitlab/ui
'
;
import
Component
from
'
~/registry/explorer/components/list_page/registry_header.vue
'
;
import
TitleArea
from
'
~/vue_shared/components/registry/title_area.vue
'
;
import
{
...
...
@@ -19,12 +19,8 @@ describe('registry_header', () => {
const
findTitleArea
=
()
=>
wrapper
.
find
(
TitleArea
);
const
findCommandsSlot
=
()
=>
wrapper
.
find
(
'
[data-testid="commands-slot"]
'
);
const
findInfoArea
=
()
=>
wrapper
.
find
(
'
[data-testid="info-area"]
'
);
const
findIntroText
=
()
=>
wrapper
.
find
(
'
[data-testid="default-intro"]
'
);
const
findImagesCountSubHeader
=
()
=>
wrapper
.
find
(
'
[data-testid="images-count"]
'
);
const
findExpirationPolicySubHeader
=
()
=>
wrapper
.
find
(
'
[data-testid="expiration-policy"]
'
);
const
findDisabledExpirationPolicyMessage
=
()
=>
wrapper
.
find
(
'
[data-testid="expiration-disabled-message"]
'
);
const
mountComponent
=
(
propsData
,
slots
)
=>
{
wrapper
=
shallowMount
(
Component
,
{
...
...
@@ -123,44 +119,18 @@ describe('registry_header', () => {
});
});
describe
(
'
info area
'
,
()
=>
{
it
(
'
exists
'
,
()
=>
{
mountComponent
();
expect
(
findInfoArea
().
exists
()).
toBe
(
true
);
});
describe
(
'
info messages
'
,
()
=>
{
describe
(
'
default message
'
,
()
=>
{
beforeEach
(()
=>
{
return
mountComponent
({
helpPagePath
:
'
bar
'
});
});
it
(
'
exists
'
,
()
=>
{
expect
(
findIntroText
().
exists
()).
toBe
(
true
);
});
it
(
'
has the correct copy
'
,
()
=>
{
expect
(
findIntroText
().
text
()).
toMatchInterpolatedText
(
LIST_INTRO_TEXT
);
});
it
(
'
is correctly bound to title_area props
'
,
()
=>
{
mountComponent
({
helpPagePath
:
'
foo
'
});
it
(
'
has the correct link
'
,
()
=>
{
expect
(
findIntroText
()
.
find
(
GlLink
)
.
attributes
(
'
href
'
),
).
toBe
(
'
bar
'
);
expect
(
findTitleArea
().
props
(
'
infoMessages
'
)).
toEqual
([
{
text
:
LIST_INTRO_TEXT
,
link
:
'
foo
'
},
]);
});
});
describe
(
'
expiration policy info message
'
,
()
=>
{
describe
(
'
when there are no images
'
,
()
=>
{
it
(
'
is hidden
'
,
()
=>
{
mountComponent
();
expect
(
findDisabledExpirationPolicyMessage
().
exists
()).
toBe
(
false
);
});
});
describe
(
'
when there are images
'
,
()
=>
{
describe
(
'
when expiration policy is disabled
'
,
()
=>
{
beforeEach
(()
=>
{
...
...
@@ -170,43 +140,27 @@ describe('registry_header', () => {
imagesCount
:
1
,
});
});
it
(
'
message exist
'
,
()
=>
{
expect
(
findDisabledExpirationPolicyMessage
().
exists
()).
toBe
(
true
);
});
it
(
'
has the correct copy
'
,
()
=>
{
expect
(
findDisabledExpirationPolicyMessage
().
text
()).
toMatchInterpolatedText
(
EXPIRATION_POLICY_DISABLED_MESSAGE
,
);
});
it
(
'
has the correct link
'
,
()
=>
{
expect
(
findDisabledExpirationPolicyMessage
()
.
find
(
GlLink
)
.
attributes
(
'
href
'
),
).
toBe
(
'
foo
'
);
it
(
'
the prop is correctly bound
'
,
()
=>
{
expect
(
findTitleArea
().
props
(
'
infoMessages
'
)).
toEqual
([
{
text
:
LIST_INTRO_TEXT
,
link
:
''
},
{
text
:
EXPIRATION_POLICY_DISABLED_MESSAGE
,
link
:
'
foo
'
},
]);
});
});
describe
(
'
when expiration policy is enabled
'
,
()
=>
{
describe
.
each
`
desc | props
${
'
when there are no images
'
}
|
${{
expirationPolicy
:
{
enabled
:
false
}
, imagesCount: 0 }}
${
'
when expiration policy is enabled
'
}
|
${{
expirationPolicy
:
{
enabled
:
true
}
, imagesCount: 1 }}
${
'
when the expiration policy is completely disabled
'
}
|
${{
expirationPolicy
:
{
enabled
:
false
}
, imagesCount: 1, hideExpirationPolicyData: true }}
`
(
'
$desc
'
,
({
props
})
=>
{
it
(
'
message does not exist
'
,
()
=>
{
mountComponent
({
expirationPolicy
:
{
enabled
:
true
},
imagesCount
:
1
,
});
expect
(
findDisabledExpirationPolicyMessage
().
exists
()).
toBe
(
false
);
});
});
describe
(
'
when the expiration policy is completely disabled
'
,
()
=>
{
it
(
'
message does not exist
'
,
()
=>
{
mountComponent
({
expirationPolicy
:
{
enabled
:
true
},
imagesCount
:
1
,
hideExpirationPolicyData
:
true
,
});
mountComponent
(
props
);
expect
(
findDisabledExpirationPolicyMessage
().
exists
()).
toBe
(
false
);
expect
(
findTitleArea
().
props
(
'
infoMessages
'
)).
toEqual
([
{
text
:
LIST_INTRO_TEXT
,
link
:
''
},
]);
});
});
});
...
...
spec/frontend/vue_shared/components/registry/title_area_spec.js
View file @
e3616635
import
{
GlAvatar
}
from
'
@gitlab/ui
'
;
import
{
GlAvatar
,
GlSprintf
,
GlLink
}
from
'
@gitlab/ui
'
;
import
{
shallowMount
}
from
'
@vue/test-utils
'
;
import
component
from
'
~/vue_shared/components/registry/title_area.vue
'
;
...
...
@@ -10,10 +10,12 @@ describe('title area', () => {
const
findMetadataSlot
=
name
=>
wrapper
.
find
(
`[data-testid="
${
name
}
"]`
);
const
findTitle
=
()
=>
wrapper
.
find
(
'
[data-testid="title"]
'
);
const
findAvatar
=
()
=>
wrapper
.
find
(
GlAvatar
);
const
findInfoMessages
=
()
=>
wrapper
.
findAll
(
'
[data-testid="info-message"]
'
);
const
mountComponent
=
({
propsData
=
{
title
:
'
foo
'
},
slots
}
=
{})
=>
{
wrapper
=
shallowMount
(
component
,
{
propsData
,
stubs
:
{
GlSprintf
},
slots
:
{
'
sub-header
'
:
'
<div data-testid="sub-header" />
'
,
'
right-actions
'
:
'
<div data-testid="right-actions" />
'
,
...
...
@@ -95,4 +97,33 @@ describe('title area', () => {
});
});
});
describe
(
'
info-messages
'
,
()
=>
{
it
(
'
shows a message when the props contains one
'
,
()
=>
{
mountComponent
({
propsData
:
{
infoMessages
:
[{
text
:
'
foo foo bar bar
'
}]
}
});
const
messages
=
findInfoMessages
();
expect
(
messages
).
toHaveLength
(
1
);
expect
(
messages
.
at
(
0
).
text
()).
toBe
(
'
foo foo bar bar
'
);
});
it
(
'
shows a link when the props contains one
'
,
()
=>
{
mountComponent
({
propsData
:
{
infoMessages
:
[{
text
:
'
foo %{docLinkStart}link%{docLinkEnd}
'
,
link
:
'
bar
'
}],
},
});
const
message
=
findInfoMessages
().
at
(
0
);
expect
(
message
.
find
(
GlLink
).
attributes
(
'
href
'
)).
toBe
(
'
bar
'
);
expect
(
message
.
text
()).
toBe
(
'
foo link
'
);
});
it
(
'
multiple messages generates multiple spans
'
,
()
=>
{
mountComponent
({
propsData
:
{
infoMessages
:
[{
text
:
'
foo
'
},
{
text
:
'
bar
'
}]
}
});
expect
(
findInfoMessages
()).
toHaveLength
(
2
);
});
});
});
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment