ui: Add sorting to namespaces (#8405)

* Add sorting to namespaces

* Add sorting to namespaces

* ui: Fix up default namespace no delete test (#8467)

Co-authored-by: John Cowen <johncowen@users.noreply.github.com>
This commit is contained in:
Kenia 2020-08-10 10:54:51 -04:00 committed by hashicorp-ci
parent 99d683bfe5
commit 84f594ec0b
12 changed files with 105 additions and 15 deletions

View File

@ -6,7 +6,7 @@
Deleting {{item.Name}}... Deleting {{item.Name}}...
</p> </p>
{{else}} {{else}}
<a href={{href-to 'dc.nspaces.edit' item.Name}}>{{item.Name}}</a> <a data-test-nspace={{item.Name}} href={{href-to 'dc.nspaces.edit' item.Name}}>{{item.Name}}</a>
{{/if}} {{/if}}
</BlockSlot> </BlockSlot>
<BlockSlot @name="details"> <BlockSlot @name="details">

View File

@ -1,6 +1,7 @@
export default (collection, clickable, attribute, text, actions) => () => { export default (collection, clickable, attribute, text, actions) => () => {
return collection('.consul-nspace-list li:not(:first-child)', { return collection('.consul-nspace-list [data-test-list-row]', {
nspace: clickable('a'), nspace: clickable('a'),
name: attribute('data-test-nspace', '[data-test-nspace]'),
description: text('[data-test-description]'), description: text('[data-test-description]'),
...actions(['edit', 'delete']), ...actions(['edit', 'delete']),
}); });

View File

@ -2,6 +2,7 @@ import Controller from '@ember/controller';
export default Controller.extend({ export default Controller.extend({
queryParams: { queryParams: {
sortBy: 'sort',
search: { search: {
as: 'filter', as: 'filter',
}, },

View File

@ -4,6 +4,7 @@ import intention from 'consul-ui/sort/comparators/intention';
import token from 'consul-ui/sort/comparators/token'; import token from 'consul-ui/sort/comparators/token';
import role from 'consul-ui/sort/comparators/role'; import role from 'consul-ui/sort/comparators/role';
import policy from 'consul-ui/sort/comparators/policy'; import policy from 'consul-ui/sort/comparators/policy';
import nspace from 'consul-ui/sort/comparators/nspace';
export function initialize(container) { export function initialize(container) {
// Service-less injection using private properties at a per-project level // Service-less injection using private properties at a per-project level
@ -15,6 +16,7 @@ export function initialize(container) {
token: token(), token: token(),
role: role(), role: role(),
policy: policy(), policy: policy(),
nspace: nspace(),
}; };
Sort.reopen({ Sort.reopen({
comparator: function(type) { comparator: function(type) {

View File

@ -7,6 +7,7 @@ export default Route.extend(WithNspaceActions, {
data: service('data-source/service'), data: service('data-source/service'),
repo: service('repository/nspace'), repo: service('repository/nspace'),
queryParams: { queryParams: {
sortBy: 'sort',
search: { search: {
as: 'filter', as: 'filter',
replace: true, replace: true,

View File

@ -0,0 +1,3 @@
export default () => key => {
return key;
};

View File

@ -1,4 +1,11 @@
{{title 'Namespaces'}} {{title 'Namespaces'}}
{{#let (selectable-key-values
(array "Name:asc" "A to Z")
(array "Name:desc" "Z to A")
selected=sortBy
)
as |sort|
}}
<EventSource @src={{items}} /> <EventSource @src={{items}} />
<AppView @class="nspace list" @loading={{isLoading}}> <AppView @class="nspace list" @loading={{isLoading}}>
<BlockSlot @name="notification" as |status type subject|> <BlockSlot @name="notification" as |status type subject|>
@ -12,16 +19,22 @@
<BlockSlot @name="actions"> <BlockSlot @name="actions">
<a data-test-create href="{{href-to 'dc.nspaces.create'}}" class="type-create">Create</a> <a data-test-create href="{{href-to 'dc.nspaces.create'}}" class="type-create">Create</a>
</BlockSlot> </BlockSlot>
<BlockSlot @name="content"> <BlockSlot @name="toolbar">
{{#if (gt items.length 0)}} {{#if (gt items.length 0)}}
<SearchBar <SearchBar
@placeholder="Search by name"
@value={{search}} @value={{search}}
@onsearch={{action (mut search) value="target.value"}} @onsearch={{action (mut search) value="target.value"}}
@secondary="sort"
@selected={{sort.selected}}
@options={{sort.items}}
@onchange={{action (mut sortBy) value='target.selected.key'}}
/> />
{{/if}} {{/if}}
<ChangeableSet @dispatcher={{searchable 'nspace' items}} @terms={{search}}> </BlockSlot>
<BlockSlot @name="content" as |filtered|> <BlockSlot @name="content">
{{#let (sort-by (comparator 'nspace' sort.selected.key) items) as |sorted|}}
<ChangeableSet @dispatcher={{searchable 'nspace' sorted}} @terms={{search}}>
<BlockSlot @name="set" as |filtered|>
<ConsulNspaceList <ConsulNspaceList
@items={{filtered}} @items={{filtered}}
@ondelete={{queue (action send 'delete')}} @ondelete={{queue (action send 'delete')}}
@ -57,5 +70,7 @@
</ConsulNspaceList> </ConsulNspaceList>
</BlockSlot> </BlockSlot>
</ChangeableSet> </ChangeableSet>
{{/let}}
</BlockSlot> </BlockSlot>
</AppView> </AppView>
{{/let}}

View File

@ -10,7 +10,15 @@ Feature: dc / nspaces / index: Nspaces List
Namespace: default Namespace: default
--- ---
And 1 datacenter model with the value "dc-1" And 1 datacenter model with the value "dc-1"
And 3 nspace models And 3 nspace models from yaml
---
- Name: a-namespace
Description: a namespace
- Name: default
Description: The default namespace
- Name: z-namespace
Description: z namespace
---
When I visit the nspaces page for yaml When I visit the nspaces page for yaml
--- ---
dc: dc-1 dc: dc-1
@ -29,5 +37,5 @@ Feature: dc / nspaces / index: Nspaces List
And I see 1 nspace model with the description "The default namespace" And I see 1 nspace model with the description "The default namespace"
Scenario: The default namespace can't be deleted Scenario: The default namespace can't be deleted
Then I see 3 nspace models Then I see 3 nspace models
And I click actions on the nspaces And I click nspaces.1.actions
Then I don't see delete on the nspaces Then I don't see nspaces.1.delete

View File

@ -0,0 +1,49 @@
@setupApplicationTest
@onlyNamespaceable
Feature: dc / nspaces / sorting
Scenario: Sorting Namespaces
Given settings from yaml
---
consul:token:
SecretID: secret
AccessorID: accessor
Namespace: default
---
Given 1 datacenter model with the value "dc-1"
And 6 nspace models from yaml
---
- Name: "nspace-5"
- Name: "nspace-3"
- Name: "nspace-1"
- Name: "nspace-4"
- Name: "nspace-2"
- Name: "nspace-6"
---
When I visit the nspaces page for yaml
---
dc: dc-1
---
Then the url should be /dc-1/namespaces
Then I see 6 nspace models
When I click selected on the sort
When I click options.1.button on the sort
Then I see name on the nspaces vertically like yaml
---
- "nspace-6"
- "nspace-5"
- "nspace-4"
- "nspace-3"
- "nspace-2"
- "nspace-1"
---
When I click selected on the sort
When I click options.0.button on the sort
Then I see name on the nspaces vertically like yaml
---
- "nspace-1"
- "nspace-2"
- "nspace-3"
- "nspace-4"
- "nspace-5"
- "nspace-6"
---

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

@ -181,7 +181,7 @@ export default {
intentions(visitable, creatable, clickable, consulIntentionList, popoverSelect) intentions(visitable, creatable, clickable, consulIntentionList, popoverSelect)
), ),
intention: create(intention(visitable, submitable, deletable, cancelable)), intention: create(intention(visitable, submitable, deletable, cancelable)),
nspaces: create(nspaces(visitable, creatable, consulNspaceList, freetextFilter)), nspaces: create(nspaces(visitable, creatable, consulNspaceList, popoverSelect)),
nspace: create( nspace: create(
nspace(visitable, submitable, deletable, cancelable, policySelector, roleSelector) nspace(visitable, submitable, deletable, cancelable, policySelector, roleSelector)
), ),

View File

@ -1,7 +1,7 @@
export default function(visitable, creatable, nspaces, filter) { export default function(visitable, creatable, nspaces, popoverSelect) {
return creatable({ return creatable({
visit: visitable('/:dc/namespaces'), visit: visitable('/:dc/namespaces'),
nspaces: nspaces(), nspaces: nspaces(),
filter: filter(), sort: popoverSelect(),
}); });
} }