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
665741cb
Commit
665741cb
authored
Jul 03, 2020
by
Nicolò Maria Mezzopera
Committed by
Jose Ivan Vargas
Jul 03, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Update list_item component with details slots
- update source - adjust tests
parent
2507dfd2
Changes
8
Show whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
180 additions
and
56 deletions
+180
-56
app/assets/javascripts/registry/explorer/components/details_page/tags_list.vue
...s/registry/explorer/components/details_page/tags_list.vue
+2
-1
app/assets/javascripts/registry/explorer/components/details_page/tags_list_row.vue
...gistry/explorer/components/details_page/tags_list_row.vue
+3
-7
app/assets/javascripts/registry/explorer/components/list_item.vue
...ts/javascripts/registry/explorer/components/list_item.vue
+83
-23
app/assets/javascripts/registry/explorer/components/list_page/image_list.vue
...pts/registry/explorer/components/list_page/image_list.vue
+2
-1
app/assets/javascripts/registry/explorer/components/list_page/image_list_row.vue
...registry/explorer/components/list_page/image_list_row.vue
+1
-6
app/assets/stylesheets/utilities.scss
app/assets/stylesheets/utilities.scss
+9
-0
spec/frontend/registry/explorer/components/details_page/tags_list_spec.js
...gistry/explorer/components/details_page/tags_list_spec.js
+10
-6
spec/frontend/registry/explorer/components/list_item_spec.js
spec/frontend/registry/explorer/components/list_item_spec.js
+70
-12
No files found.
app/assets/javascripts/registry/explorer/components/details_page/tags_list.vue
View file @
665741cb
...
@@ -63,7 +63,8 @@ export default {
...
@@ -63,7 +63,8 @@ export default {
v-for=
"(tag, index) in tags"
v-for=
"(tag, index) in tags"
:key=
"tag.path"
:key=
"tag.path"
:tag=
"tag"
:tag=
"tag"
:index=
"index"
:first=
"index === 0"
:last=
"index === tags.length - 1"
:selected=
"selectedItems[tag.name]"
:selected=
"selectedItems[tag.name]"
:is-desktop=
"isDesktop"
:is-desktop=
"isDesktop"
@
select=
"updateSelectedItems(tag.name)"
@
select=
"updateSelectedItems(tag.name)"
...
...
app/assets/javascripts/registry/explorer/components/details_page/tags_list_row.vue
View file @
665741cb
...
@@ -30,16 +30,12 @@ export default {
...
@@ -30,16 +30,12 @@ export default {
type
:
Object
,
type
:
Object
,
required
:
true
,
required
:
true
,
},
},
index
:
{
isDesktop
:
{
type
:
Number
,
required
:
true
,
},
selected
:
{
type
:
Boolean
,
type
:
Boolean
,
default
:
false
,
default
:
false
,
required
:
false
,
required
:
false
,
},
},
isDesktop
:
{
selected
:
{
type
:
Boolean
,
type
:
Boolean
,
default
:
false
,
default
:
false
,
required
:
false
,
required
:
false
,
...
@@ -66,7 +62,7 @@ export default {
...
@@ -66,7 +62,7 @@ export default {
</
script
>
</
script
>
<
template
>
<
template
>
<list-item
:index=
"index
"
:selected=
"selected"
>
<list-item
v-bind=
"$attrs
"
:selected=
"selected"
>
<template
#left-action
>
<template
#left-action
>
<gl-form-checkbox
class=
"gl-m-0"
:checked=
"selected"
@
change=
"$emit('select')"
/>
<gl-form-checkbox
class=
"gl-m-0"
:checked=
"selected"
@
change=
"$emit('select')"
/>
</
template
>
</
template
>
...
...
app/assets/javascripts/registry/explorer/components/list_item.vue
View file @
665741cb
<
script
>
<
script
>
import
{
GlButton
}
from
'
@gitlab/ui
'
;
export
default
{
export
default
{
name
:
'
ListItem
'
,
name
:
'
ListItem
'
,
components
:
{
GlButton
},
props
:
{
props
:
{
index
:
{
first
:
{
type
:
Number
,
type
:
Boolean
,
default
:
0
,
default
:
false
,
required
:
false
,
},
last
:
{
type
:
Boolean
,
default
:
false
,
required
:
false
,
required
:
false
,
},
},
disabled
:
{
disabled
:
{
...
@@ -18,33 +26,62 @@ export default {
...
@@ -18,33 +26,62 @@ export default {
required
:
false
,
required
:
false
,
},
},
},
},
data
()
{
return
{
isDetailsShown
:
false
,
detailsSlots
:
[],
};
},
computed
:
{
computed
:
{
optionalClasses
()
{
optionalClasses
()
{
return
{
return
{
'
gl-border-t-solid gl-border-t-1
'
:
this
.
index
===
0
,
'
gl-border-t-1
'
:
!
this
.
first
,
'
gl-border-t-2
'
:
this
.
first
,
'
gl-border-b-1
'
:
!
this
.
last
,
'
gl-border-b-2
'
:
this
.
last
,
'
disabled-content
'
:
this
.
disabled
,
'
disabled-content
'
:
this
.
disabled
,
'
gl-border-gray-200
'
:
!
this
.
selected
,
'
gl-border-gray-200
'
:
!
this
.
selected
,
'
gl-bg-blue-50 gl-border-blue-200
'
:
this
.
selected
,
'
gl-bg-blue-50 gl-border-blue-200
'
:
this
.
selected
,
};
};
},
},
},
},
mounted
()
{
this
.
detailsSlots
=
Object
.
keys
(
this
.
$slots
).
filter
(
k
=>
k
.
startsWith
(
'
details_
'
));
},
methods
:
{
toggleDetails
()
{
this
.
isDetailsShown
=
!
this
.
isDetailsShown
;
},
},
};
};
</
script
>
</
script
>
<
template
>
<
template
>
<div
<div
class=
"gl-display-flex gl-
align-items-center gl-border-b-solid gl-border-b-1 gl-py-4 gl-px-2
"
class=
"gl-display-flex gl-
flex-direction-column gl-border-b-solid gl-border-t-solid
"
:class=
"optionalClasses"
:class=
"optionalClasses"
>
>
<div
v-if=
"$slots['left-action']"
class=
"gl-mr-5 gl-display-none gl-display-sm-block"
>
<div
class=
"gl-display-flex gl-align-items-center gl-py-4 gl-px-2"
>
<div
v-if=
"$slots['left-action']"
class=
"gl-w-7 gl-display-none gl-display-sm-flex gl-justify-content-start gl-pl-2"
>
<slot
name=
"left-action"
></slot>
<slot
name=
"left-action"
></slot>
</div>
</div>
<div
class=
"gl-display-flex gl-flex-direction-column gl-flex-fill-1"
>
<div
class=
"gl-display-flex gl-flex-direction-column gl-flex-fill-1"
>
<div
<div
class=
"gl-display-flex gl-align-items-center gl-justify-content-space-between gl-text-black-normal gl-font-weight-bold"
class=
"gl-display-flex gl-align-items-center gl-justify-content-space-between gl-text-black-normal gl-font-weight-bold"
>
>
<div
>
<div
class=
"gl-display-flex gl-align-items-center"
>
<slot
name=
"left-primary"
></slot>
<slot
name=
"left-primary"
></slot>
<gl-button
v-if=
"detailsSlots.length > 0"
:selected=
"isDetailsShown"
icon=
"ellipsis_h"
size=
"small"
class=
"gl-ml-2"
@
click=
"toggleDetails"
/>
</div>
</div>
<div>
<div>
<slot
name=
"right-primary"
></slot>
<slot
name=
"right-primary"
></slot>
...
@@ -61,8 +98,31 @@ export default {
...
@@ -61,8 +98,31 @@ export default {
</div>
</div>
</div>
</div>
</div>
</div>
<div
v-if=
"$slots['right-action']"
class=
"gl-ml-5 gl-display-none gl-display-sm-block"
>
<div
v-if=
"$slots['right-action']"
class=
"gl-w-9 gl-display-none gl-display-sm-flex gl-justify-content-end gl-pr-2"
>
<slot
name=
"right-action"
></slot>
<slot
name=
"right-action"
></slot>
</div>
</div>
</div>
</div>
<div
class=
"gl-display-flex"
>
<div
class=
"gl-w-7"
></div>
<div
v-if=
"isDetailsShown"
class=
"gl-display-flex gl-flex-direction-column gl-flex-fill-1 gl-bg-gray-10 gl-rounded-base gl-inset-border-1-gray-200 gl-mb-3"
>
<div
v-for=
"(row, detailIndex) in detailsSlots"
:key=
"detailIndex"
class=
"gl-px-5 gl-py-2"
:class=
"
{
'gl-border-gray-200 gl-border-t-solid gl-border-t-1': detailIndex !== 0,
}"
>
<slot
:name=
"row"
></slot>
</div>
</div>
<div
class=
"gl-w-9"
></div>
</div>
</div>
</
template
>
</
template
>
app/assets/javascripts/registry/explorer/components/list_page/image_list.vue
View file @
665741cb
...
@@ -37,7 +37,8 @@ export default {
...
@@ -37,7 +37,8 @@ export default {
v-for=
"(listItem, index) in images"
v-for=
"(listItem, index) in images"
:key=
"index"
:key=
"index"
:item=
"listItem"
:item=
"listItem"
:index=
"index"
:first=
"index === 0"
:last=
"index === images.length - 1"
@
delete=
"$emit('delete', $event)"
@
delete=
"$emit('delete', $event)"
/>
/>
...
...
app/assets/javascripts/registry/explorer/components/list_page/image_list_row.vue
View file @
665741cb
...
@@ -29,11 +29,6 @@ export default {
...
@@ -29,11 +29,6 @@ export default {
type
:
Object
,
type
:
Object
,
required
:
true
,
required
:
true
,
},
},
index
:
{
type
:
Number
,
default
:
0
,
required
:
false
,
},
},
},
i18n
:
{
i18n
:
{
LIST_DELETE_BUTTON_DISABLED
,
LIST_DELETE_BUTTON_DISABLED
,
...
@@ -71,7 +66,7 @@ export default {
...
@@ -71,7 +66,7 @@ export default {
disabled: !item.deleting,
disabled: !item.deleting,
title: $options.i18n.ROW_SCHEDULED_FOR_DELETION,
title: $options.i18n.ROW_SCHEDULED_FOR_DELETION,
}"
}"
:index="index
"
v-bind="$attrs
"
:disabled="item.deleting"
:disabled="item.deleting"
>
>
<template
#left-primary
>
<template
#left-primary
>
...
...
app/assets/stylesheets/utilities.scss
View file @
665741cb
...
@@ -108,3 +108,12 @@
...
@@ -108,3 +108,12 @@
.gl-transition-property-stroke
{
.gl-transition-property-stroke
{
transition-property
:
stroke
;
transition-property
:
stroke
;
}
}
// temporary class till giltab-ui one is merged
.gl-border-t-2
{
border-top-width
:
$gl-border-size-2
;
}
.gl-border-b-2
{
border-bottom-width
:
$gl-border-size-2
;
}
spec/frontend/registry/explorer/components/details_page/tags_list_spec.js
View file @
665741cb
...
@@ -102,12 +102,16 @@ describe('Tags List', () => {
...
@@ -102,12 +102,16 @@ describe('Tags List', () => {
it
(
'
the correct props are bound to it
'
,
()
=>
{
it
(
'
the correct props are bound to it
'
,
()
=>
{
mountComponent
();
mountComponent
();
expect
(
const
rows
=
findTagsListRow
();
findTagsListRow
()
.
at
(
0
)
expect
(
rows
.
at
(
0
).
attributes
()).
toMatchObject
({
.
attributes
(),
first
:
'
true
'
,
).
toMatchObject
({
isdesktop
:
'
true
'
,
index
:
'
0
'
,
});
// The list has only two tags and for some reasons .at(-1) does not work
expect
(
rows
.
at
(
1
).
attributes
()).
toMatchObject
({
last
:
'
true
'
,
isdesktop
:
'
true
'
,
isdesktop
:
'
true
'
,
});
});
});
});
...
...
spec/frontend/registry/explorer/components/list_item_spec.js
View file @
665741cb
import
{
GlButton
}
from
'
@gitlab/ui
'
;
import
{
shallowMount
}
from
'
@vue/test-utils
'
;
import
{
shallowMount
}
from
'
@vue/test-utils
'
;
import
component
from
'
~/registry/explorer/components/list_item.vue
'
;
import
component
from
'
~/registry/explorer/components/list_item.vue
'
;
...
@@ -10,8 +11,10 @@ describe('list item', () => {
...
@@ -10,8 +11,10 @@ describe('list item', () => {
const
findRightPrimarySlot
=
()
=>
wrapper
.
find
(
'
[data-testid="right-primary"]
'
);
const
findRightPrimarySlot
=
()
=>
wrapper
.
find
(
'
[data-testid="right-primary"]
'
);
const
findRightSecondarySlot
=
()
=>
wrapper
.
find
(
'
[data-testid="right-secondary"]
'
);
const
findRightSecondarySlot
=
()
=>
wrapper
.
find
(
'
[data-testid="right-secondary"]
'
);
const
findRightActionSlot
=
()
=>
wrapper
.
find
(
'
[data-testid="right-action"]
'
);
const
findRightActionSlot
=
()
=>
wrapper
.
find
(
'
[data-testid="right-action"]
'
);
const
findDetailsSlot
=
name
=>
wrapper
.
find
(
`[data-testid="
${
name
}
"]`
);
const
findToggleDetailsButton
=
()
=>
wrapper
.
find
(
GlButton
);
const
mountComponent
=
propsData
=>
{
const
mountComponent
=
(
propsData
,
slots
)
=>
{
wrapper
=
shallowMount
(
component
,
{
wrapper
=
shallowMount
(
component
,
{
propsData
,
propsData
,
slots
:
{
slots
:
{
...
@@ -21,6 +24,7 @@ describe('list item', () => {
...
@@ -21,6 +24,7 @@ describe('list item', () => {
'
right-primary
'
:
'
<div data-testid="right-primary" />
'
,
'
right-primary
'
:
'
<div data-testid="right-primary" />
'
,
'
right-secondary
'
:
'
<div data-testid="right-secondary" />
'
,
'
right-secondary
'
:
'
<div data-testid="right-secondary" />
'
,
'
right-action
'
:
'
<div data-testid="right-action" />
'
,
'
right-action
'
:
'
<div data-testid="right-action" />
'
,
...
slots
,
},
},
});
});
};
};
...
@@ -44,6 +48,50 @@ describe('list item', () => {
...
@@ -44,6 +48,50 @@ describe('list item', () => {
expect
(
finderFunction
().
exists
()).
toBe
(
true
);
expect
(
finderFunction
().
exists
()).
toBe
(
true
);
});
});
describe
.
each
`
slotNames
${[
'
details_foo
'
]}
${[
'
details_foo
'
,
'
details_bar
'
]}
${[
'
details_foo
'
,
'
details_bar
'
,
'
details_baz
'
]}
`
(
'
$slotNames details slots
'
,
({
slotNames
})
=>
{
const
slotMocks
=
slotNames
.
reduce
((
acc
,
current
)
=>
{
acc
[
current
]
=
`<div data-testid="
${
current
}
" />`
;
return
acc
;
},
{});
it
(
'
are visible when details is shown
'
,
async
()
=>
{
mountComponent
({},
slotMocks
);
await
wrapper
.
vm
.
$nextTick
();
findToggleDetailsButton
().
vm
.
$emit
(
'
click
'
);
await
wrapper
.
vm
.
$nextTick
();
slotNames
.
forEach
(
name
=>
{
expect
(
findDetailsSlot
(
name
).
exists
()).
toBe
(
true
);
});
});
it
(
'
are not visible when details are not shown
'
,
()
=>
{
mountComponent
({},
slotMocks
);
slotNames
.
forEach
(
name
=>
{
expect
(
findDetailsSlot
(
name
).
exists
()).
toBe
(
false
);
});
});
});
describe
(
'
details toggle button
'
,
()
=>
{
it
(
'
is visible when at least one details slot exists
'
,
async
()
=>
{
mountComponent
({},
{
details_foo
:
'
<span></span>
'
});
await
wrapper
.
vm
.
$nextTick
();
expect
(
findToggleDetailsButton
().
exists
()).
toBe
(
true
);
});
it
(
'
is hidden without details slot
'
,
()
=>
{
mountComponent
();
expect
(
findToggleDetailsButton
().
exists
()).
toBe
(
false
);
});
});
describe
(
'
disabled prop
'
,
()
=>
{
describe
(
'
disabled prop
'
,
()
=>
{
it
(
'
when true applies disabled-content class
'
,
()
=>
{
it
(
'
when true applies disabled-content class
'
,
()
=>
{
mountComponent
({
disabled
:
true
});
mountComponent
({
disabled
:
true
});
...
@@ -58,21 +106,31 @@ describe('list item', () => {
...
@@ -58,21 +106,31 @@ describe('list item', () => {
});
});
});
});
describe
(
'
index
prop
'
,
()
=>
{
describe
(
'
first
prop
'
,
()
=>
{
it
(
'
when i
ndex is 0 displays a
top border
'
,
()
=>
{
it
(
'
when i
s true displays a double
top border
'
,
()
=>
{
mountComponent
({
index
:
0
});
mountComponent
({
first
:
true
});
expect
(
wrapper
.
classes
()).
toEqual
(
expect
(
wrapper
.
classes
(
'
gl-border-t-2
'
)).
toBe
(
true
);
expect
.
arrayContaining
([
'
gl-border-t-solid
'
,
'
gl-border-t-1
'
]),
);
});
});
it
(
'
when i
ndex is not 0 hides
top border
'
,
()
=>
{
it
(
'
when i
s false display a single
top border
'
,
()
=>
{
mountComponent
({
index
:
1
});
mountComponent
({
first
:
false
});
expect
(
wrapper
.
classes
()).
toEqual
(
expect
(
wrapper
.
classes
(
'
gl-border-t-1
'
)).
toBe
(
true
);
expect
.
not
.
arrayContaining
([
'
gl-border-t-solid
'
,
'
gl-border-t-1
'
]),
});
);
});
describe
(
'
last prop
'
,
()
=>
{
it
(
'
when is true displays a double bottom border
'
,
()
=>
{
mountComponent
({
last
:
true
});
expect
(
wrapper
.
classes
(
'
gl-border-b-2
'
)).
toBe
(
true
);
});
it
(
'
when is false display a single bottom border
'
,
()
=>
{
mountComponent
({
last
:
false
});
expect
(
wrapper
.
classes
(
'
gl-border-b-1
'
)).
toBe
(
true
);
});
});
});
});
...
...
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