ui: [BUGFIX] De-duplicate Tag rendering (#10186)

* Add some tests for duplicated and non-duplicated tags

* Ensure tags get de-duped and add docs

* Update docs to include info on the recursive-ness
This commit is contained in:
John Cowen 2021-05-07 12:07:11 +01:00 committed by GitHub
parent 24fc07be09
commit 5400c81e29
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 168 additions and 23 deletions

3
.changelog/10186.txt Normal file
View File

@ -0,0 +1,3 @@
```release-note:bug
ui: De-duplicate tags in rendered tag listings
```

View File

@ -0,0 +1,75 @@
# TagList
Template only component for rendering a list of tags. You can pass either/or/and `@tags=tags` and/or `@item=item` (`item` must have a `Tags` property) for ease. If you pass both they are merged and de-duped.
Tags are de-duplicated when rendered.
```hbs preview-template
<TagList
@item={{hash
Tags=(array 'tag' 'tag' 'another-tag')
}}
/>
<hr />
<TagList
@tags={{array 'another-tag' 'tag' 'tag'}}
/>
```
`TagList` is also a recursive component, which can currently be used for when you need to wrap the `TagList` component in more DOM, but you only want that DOM to appear if your array of tags is non-empty.
```hbs preview-template
<figure>
<figcaption>
This list has tags therefore the red border div will also be rendered.
</figcaption>
<TagList
@item={{hash
Tags=(array 'tag' 'tag' 'another-tag')
}}
as |Tags|>
<div style="border: 1px solid red;">
<Tags />
</div>
</TagList>
</figure>
<hr />
<figure>
<figcaption>
This list has no tags therefore the tags _and_ red border div will **not** be rendered.
</figcaption>
<TagList
@item={{hash
Tags=(array)
}}
as |Tags|>
<div style="border: 1px solid red;">
<Tags />
</div>
</TagList>
</figure>
```
## Arguments
| Argument | Type | Default | Description |
| --- | --- | --- | --- |
| `item` | `Object` | | Object with a `Tags` property equalling an array of string tags |
| `tags` | `Array` | | An array of string tags |
## Yields
When used as a block level component the `TagList` yields itself, see above example for usage.
| Property | Type | Description |
| --- | --- | --- |
| `Tags` | `Array` | The resulting collection of data after searching/sorting/filtering |

View File

@ -1,20 +1,29 @@
{{#if (gt item.Tags.length 0)}} {{#let (union (or @item.Tags (array)) (or @tags (array))) as |tags|}}
{{#if (has-block)}} {{#if (gt tags.length 0)}}
{{yield {{#if (has-block)}}
(component 'tag-list' item=item) {{yield
(component 'tag-list' item=@item)
}}
{{else}}
<dl
class="tag-list"
...attributes
>
<dt
{{tooltip}}
>
{{t "components.tag-list.title"
default=(array
"common.consul.tags"
)
}} }}
{{else}} </dt>
<dl class="tag-list"> <dd data-test-tags>
<dt> {{#each tags as |item|}}
<Tooltip> <span>{{item}}</span>
Tags {{/each}}
</Tooltip> </dd>
</dt> </dl>
<dd data-test-tags> {{/if}}
{{#each item.Tags as |item|}}
<span>{{item}}</span>
{{/each}}
</dd>
</dl>
{{/if}} {{/if}}
{{/if}} {{/let}}

View File

@ -1,5 +0,0 @@
import Component from '@ember/component';
export default Component.extend({
tagName: '',
});

View File

@ -0,0 +1,48 @@
@setupApplicationTest
Feature: dc / services / show / tags
Background:
Given 1 datacenter model with the value "dc1"
And 1 node models
Scenario: A service with multiple tags
Given 1 service model from yaml
---
- Service:
Name: service
Kind: ~
Tags:
- tag
- tag1
- tag2
---
When I visit the service page for yaml
---
dc: dc1
service: service
---
And I see tags on the tabs
When I click tags on the tabs
And I see tagsIsSelected on the tabs
And I see 3 tag models on the tabs.tagsTab component
Scenario: A service with multiple duplicated tags
Given 1 service model from yaml
---
- Service:
Name: service
Kind: ~
Tags:
- tag1
- tag2
- tag
- tag
- tag1
- tag2
---
When I visit the service page for yaml
---
dc: dc1
service: service
---
And I see tags on the tabs
When I click tags on the tabs
And I see tagsIsSelected on the tabs
And I see 3 tag models on the tabs.tagsTab component

View File

@ -0,0 +1,10 @@
import steps from '../../../steps';
// step definitions that are shared between features should be moved to the
// tests/acceptance/steps/steps.js file
export default function(assert) {
return steps(assert).then('I should find a file', function() {
assert.ok(true, this.step);
});
}

View File

@ -36,5 +36,10 @@ export default function(visitable, clickable, attribute, collection, text, inten
name: text('[data-test-service-name]'), name: text('[data-test-service-name]'),
}), }),
}; };
page.tabs.tagsTab = {
tags: collection('.tag-list dd > span', {
name: text(),
}),
};
return page; return page;
} }