mirror of https://github.com/hashicorp/consul
Browse Source
Adds a 'status' for the filtering/searching in the UI, without this its not super clear that you are filtering a recordset due to the menu selections being hidden once closed. You can also use the pills in this status view to delete individual filters.pull/9638/head
John Cowen
4 years ago
committed by
GitHub
82 changed files with 3117 additions and 1946 deletions
@ -0,0 +1,4 @@
|
||||
```release-note:feature |
||||
ui: Add additional search/filter status pills for viewing and removing current |
||||
filters in listing views |
||||
``` |
@ -1,59 +1,127 @@
|
||||
<form |
||||
class="consul-acl-search-bar filter-bar" |
||||
<SearchBar |
||||
class="consul-acl-search-bar" |
||||
...attributes |
||||
@filter={{@filter}} |
||||
> |
||||
<div class="search"> |
||||
<FreetextFilter |
||||
@onsearch={{action @onsearch}} |
||||
@value={{@search}} |
||||
@placeholder="Search" |
||||
/> |
||||
</div> |
||||
<div class="filters"> |
||||
<PopoverSelect |
||||
@position="left" |
||||
@onchange={{action @onfilter.kind}} |
||||
@multiple={{true}} |
||||
as |components|> |
||||
<BlockSlot @name="selected"> |
||||
<span> |
||||
Type |
||||
</span> |
||||
</BlockSlot> |
||||
<BlockSlot @name="options"> |
||||
{{#let components.Optgroup components.Option as |Optgroup Option|}} |
||||
<Option @value="management" @selected={{contains 'management' @filter.kinds}}>Management</Option> |
||||
<Option @value="client" @selected={{contains 'service' @filter.kinds}}>Client</Option> |
||||
<:status as |search|> |
||||
|
||||
{{#let |
||||
|
||||
(t (concat "components.consul.acl.search-bar." search.status.key) |
||||
default=(array |
||||
(concat "common.search." search.status.key) |
||||
(concat "common.consul." search.status.key) |
||||
) |
||||
) |
||||
|
||||
(t (concat "components.consul.acl.search-bar." search.status.value) |
||||
default=(array |
||||
(concat "common.search." search.status.value) |
||||
(concat "common.consul." search.status.value) |
||||
(concat "common.brand." search.status.value) |
||||
) |
||||
) |
||||
|
||||
as |key value|}} |
||||
<search.RemoveFilter |
||||
aria-label={{t "common.ui.remove" item=(concat key " " value)}} |
||||
> |
||||
<dl> |
||||
<dt>{{key}}</dt> |
||||
<dd>{{value}}</dd> |
||||
</dl> |
||||
</search.RemoveFilter> |
||||
{{/let}} |
||||
</BlockSlot> |
||||
</PopoverSelect> |
||||
</div> |
||||
<div class="sort"> |
||||
<PopoverSelect |
||||
class="type-sort" |
||||
data-test-sort-control |
||||
@position="right" |
||||
@onchange={{action @onsort}} |
||||
@multiple={{false}} |
||||
as |components|> |
||||
<BlockSlot @name="selected"> |
||||
<span> |
||||
{{#let (from-entries (array |
||||
(array "Name:asc" "A to Z") |
||||
(array "Name:desc" "Z to A") |
||||
)) |
||||
as |selectable| |
||||
}} |
||||
{{get selectable @sort}} |
||||
{{/let}} |
||||
</span> |
||||
</BlockSlot> |
||||
<BlockSlot @name="options"> |
||||
{{#let components.Optgroup components.Option as |Optgroup Option|}} |
||||
<Option @value="Name:asc" @selected={{eq "Name:asc" @sort}}>A to Z</Option> |
||||
<Option @value="Name:desc" @selected={{eq "Name:desc" @sort}}>Z to A</Option> |
||||
{{/let}} |
||||
</BlockSlot> |
||||
</PopoverSelect> |
||||
</div> |
||||
</form> |
||||
|
||||
</:status> |
||||
<:search as |search|> |
||||
<search.Search |
||||
@onsearch={{action @onsearch}} |
||||
@value={{@search}} |
||||
@placeholder={{t "common.search.search"}} |
||||
> |
||||
{{#if @filter.searchproperty}} |
||||
<search.Select |
||||
class="type-search-properties" |
||||
@position="right" |
||||
@onchange={{action @filter.searchproperty.change}} |
||||
@multiple={{true}} |
||||
@required={{true}} |
||||
as |components|> |
||||
<BlockSlot @name="selected"> |
||||
<span> |
||||
{{t "common.search.searchproperty"}} |
||||
</span> |
||||
</BlockSlot> |
||||
<BlockSlot @name="options"> |
||||
{{#let components.Optgroup components.Option as |Optgroup Option|}} |
||||
{{#each @filter.searchproperty.default as |prop|}} |
||||
<Option @value={{prop}} @selected={{contains prop @filter.searchproperty.value}}> |
||||
{{t (concat "common.consul." (lowercase prop))}} |
||||
</Option> |
||||
{{/each}} |
||||
{{/let}} |
||||
</BlockSlot> |
||||
</search.Select> |
||||
{{/if}} |
||||
</search.Search> |
||||
</:search> |
||||
<:filter as |search|> |
||||
<search.Select |
||||
class="type-status" |
||||
@position="left" |
||||
@onchange={{action @filter.kind.change}} |
||||
@multiple={{true}} |
||||
as |components|> |
||||
<BlockSlot @name="selected"> |
||||
<span> |
||||
{{t "components.consul.acl.search-bar.kind.name"}} |
||||
</span> |
||||
</BlockSlot> |
||||
<BlockSlot @name="options"> |
||||
{{#let components.Optgroup components.Option as |Optgroup Option|}} |
||||
{{#each (array "management" "client") as |state|}} |
||||
<Option class="value-{{state}}" @value={{state}} @selected={{contains state @filter.status.value}}> |
||||
{{t (concat "components.acl.search-bar.kind.options." state) |
||||
default=(array |
||||
(concat "common.search." state) |
||||
) |
||||
}} |
||||
</Option> |
||||
{{/each}} |
||||
{{/let}} |
||||
</BlockSlot> |
||||
</search.Select> |
||||
</:filter> |
||||
<:sort as |search|> |
||||
<search.Select |
||||
class="type-sort" |
||||
data-test-sort-control |
||||
@position="right" |
||||
@onchange={{action @sort.change}} |
||||
@multiple={{false}} |
||||
@required={{true}} |
||||
as |components|> |
||||
<BlockSlot @name="selected"> |
||||
<span> |
||||
{{#let (from-entries (array |
||||
(array "Name:asc" (t "common.sort.alpha.asc")) |
||||
(array "Name:desc" (t "common.sort.alpha.desc")) |
||||
)) |
||||
as |selectable| |
||||
}} |
||||
{{get selectable @sort.value}} |
||||
{{/let}} |
||||
</span> |
||||
</BlockSlot> |
||||
<BlockSlot @name="options"> |
||||
{{#let components.Optgroup components.Option as |Optgroup Option|}} |
||||
<Optgroup @label={{t "common.consul.name"}}> |
||||
<Option @value="Name:asc" @selected={{eq "Name:asc" @sort.value}}>{{t "common.sort.alpha.asc"}}</Option> |
||||
<Option @value="Name:desc" @selected={{eq "Name:desc" @sort.value}}>{{t "common.sort.alpha.desc"}}</Option> |
||||
</Optgroup> |
||||
{{/let}} |
||||
</BlockSlot> |
||||
</search.Select> |
||||
</:sort> |
||||
</SearchBar> |
||||
|
@ -1,140 +1,190 @@
|
||||
<form |
||||
class="consul-health-check-search-bar filter-bar" |
||||
<SearchBar |
||||
class="consul-healthcheck-search-bar" |
||||
...attributes |
||||
@filter={{@filter}} |
||||
> |
||||
<div class="search"> |
||||
<FreetextFilter |
||||
@onsearch={{action @onsearch}} |
||||
@value={{@search}} |
||||
@placeholder="Search" |
||||
> |
||||
<PopoverSelect |
||||
class="type-search-properties" |
||||
@position="right" |
||||
@onchange={{action @onfilter.searchproperty}} |
||||
<:status as |search|> |
||||
|
||||
{{#let |
||||
|
||||
(t (concat "components.consul.health-check.search-bar." search.status.key ".name") |
||||
default=(array |
||||
(concat "common.search." search.status.key) |
||||
(concat "common.consul." search.status.key) |
||||
) |
||||
) |
||||
|
||||
(t (concat "components.consul.health-check.search-bar." search.status.key ".options." search.status.value) |
||||
default=(array |
||||
(concat "common.search." search.status.value) |
||||
(concat "common.consul." search.status.value) |
||||
) |
||||
) |
||||
|
||||
as |key value|}} |
||||
<search.RemoveFilter |
||||
aria-label={{t "common.ui.remove" item=(concat key " " value)}} |
||||
> |
||||
<dl> |
||||
<dt>{{key}}</dt> |
||||
<dd>{{value}}</dd> |
||||
</dl> |
||||
</search.RemoveFilter> |
||||
{{/let}} |
||||
|
||||
</:status> |
||||
<:search as |search|> |
||||
<search.Search |
||||
@onsearch={{action @onsearch}} |
||||
@value={{@search}} |
||||
@placeholder={{t "common.search.search"}} |
||||
> |
||||
{{#if @filter.searchproperty}} |
||||
<search.Select |
||||
class="type-search-properties" |
||||
@position="right" |
||||
@onchange={{action @filter.searchproperty.change}} |
||||
@multiple={{true}} |
||||
@required={{true}} |
||||
as |components|> |
||||
<BlockSlot @name="selected"> |
||||
<span> |
||||
{{t "common.search.searchproperty"}} |
||||
</span> |
||||
</BlockSlot> |
||||
<BlockSlot @name="options"> |
||||
{{#let components.Optgroup components.Option as |Optgroup Option|}} |
||||
{{#each @filter.searchproperty.default as |prop|}} |
||||
<Option @value={{prop}} @selected={{contains prop @filter.searchproperty.value}}> |
||||
{{t (concat "common.consul." (lowercase prop))}} |
||||
</Option> |
||||
{{/each}} |
||||
{{/let}} |
||||
</BlockSlot> |
||||
</search.Select> |
||||
{{/if}} |
||||
</search.Search> |
||||
</:search> |
||||
<:filter as |search|> |
||||
<search.Select |
||||
class="type-status" |
||||
@position="left" |
||||
@onchange={{action @filter.status.change}} |
||||
@multiple={{true}} |
||||
as |components|> |
||||
<BlockSlot @name="selected"> |
||||
<span> |
||||
Search across |
||||
{{t "common.consul.status"}} |
||||
</span> |
||||
</BlockSlot> |
||||
<BlockSlot @name="options"> |
||||
{{#let components.Optgroup components.Option as |Optgroup Option|}} |
||||
{{#each @searchproperties as |prop|}} |
||||
<Option @value={{prop}} @selected={{contains prop @filter.searchproperties}}>{{prop}}</Option> |
||||
{{#each (array "passing" "warning" "critical" "empty") as |state|}} |
||||
<Option class="value-{{state}}" @value={{state}} @selected={{contains state @filter.status.value}}> |
||||
{{t (concat "common.consul." state) |
||||
default=(array |
||||
(concat "common.search." state) |
||||
) |
||||
}} |
||||
</Option> |
||||
{{/each}} |
||||
{{/let}} |
||||
</BlockSlot> |
||||
</PopoverSelect> |
||||
</FreetextFilter> |
||||
</div> |
||||
<div class="filters"> |
||||
<PopoverSelect |
||||
class="type-status" |
||||
@position="left" |
||||
@onchange={{action @onfilter.status}} |
||||
@multiple={{true}} |
||||
as |components|> |
||||
<BlockSlot @name="selected"> |
||||
<span> |
||||
Health Status |
||||
</span> |
||||
</BlockSlot> |
||||
<BlockSlot @name="options"> |
||||
{{#let components.Optgroup components.Option as |Optgroup Option|}} |
||||
<Option class="value-passing" @value="passing" @selected={{contains 'passing' @filter.statuses}}>Passing</Option> |
||||
<Option class="value-warning" @value="warning" @selected={{contains 'warning' @filter.statuses}}>Warning</Option> |
||||
<Option class="value-critical" @value="critical" @selected={{contains 'critical' @filter.statuses}}>Failing</Option> |
||||
<Option class="value-empty" @value="empty" @selected={{contains 'empty' @filter.statuses}}>No checks</Option> |
||||
{{/let}} |
||||
</BlockSlot> |
||||
</PopoverSelect> |
||||
|
||||
<PopoverSelect |
||||
class="type-kind" |
||||
@position="left" |
||||
@onchange={{action @onfilter.kind}} |
||||
@multiple={{true}} |
||||
as |components|> |
||||
<BlockSlot @name="selected"> |
||||
<span> |
||||
Kind |
||||
</span> |
||||
</BlockSlot> |
||||
<BlockSlot @name="options"> |
||||
{{#let components.Optgroup components.Option as |Optgroup Option|}} |
||||
<Option @value="service" @selected={{contains 'service' @filter.kinds}}>Service Check</Option> |
||||
<Option @value="node" @selected={{contains 'node' @filter.kinds}}>Node Check</Option> |
||||
{{/let}} |
||||
</BlockSlot> |
||||
</PopoverSelect> |
||||
|
||||
<PopoverSelect |
||||
class="type-check" |
||||
@position="left" |
||||
@onchange={{action @onfilter.check}} |
||||
@multiple={{true}} |
||||
as |components|> |
||||
<BlockSlot @name="selected"> |
||||
<span> |
||||
Type |
||||
</span> |
||||
</BlockSlot> |
||||
<BlockSlot @name="options"> |
||||
{{#let components.Optgroup components.Option as |Optgroup Option|}} |
||||
<Option @value="alias" @selected={{contains 'alias' @filter.checks}}>alias</Option> |
||||
<Option @value="docker" @selected={{contains 'docker' @filter.checks}}>Docker</Option> |
||||
<Option @value="grpc" @selected={{contains 'grpc' @filter.checks}}>gRPC</Option> |
||||
<Option @value="http" @selected={{contains 'http' @filter.checks}}>HTTP</Option> |
||||
<Option @value="serf" @selected={{contains 'serf' @filter.checks}}>Serf</Option> |
||||
<Option @value="tcp" @selected={{contains 'tcp' @filter.checks}}>TCP</Option> |
||||
<Option @value="ttl" @selected={{contains 'ttl' @filter.checks}}>TTL</Option> |
||||
{{/let}} |
||||
</BlockSlot> |
||||
</PopoverSelect> |
||||
|
||||
</div> |
||||
<div class="sort"> |
||||
<PopoverSelect |
||||
class="type-sort" |
||||
data-test-sort-control |
||||
@position="right" |
||||
@onchange={{action @onsort}} |
||||
@multiple={{false}} |
||||
as |components|> |
||||
<BlockSlot @name="selected"> |
||||
<span> |
||||
{{#let (from-entries (array |
||||
(array "Name:asc" "A to Z") |
||||
(array "Name:desc" "Z to A") |
||||
(array "Status:asc" "Unhealthy to Healthy") |
||||
(array "Status:desc" "Healthy to Unhealthy") |
||||
(array "Kind:asc" "Service to Node") |
||||
(array "Kind:desc" "Node to Service") |
||||
)) |
||||
as |selectable| |
||||
}} |
||||
{{get selectable @sort}} |
||||
{{/let}} |
||||
</span> |
||||
</BlockSlot> |
||||
<BlockSlot @name="options"> |
||||
</search.Select> |
||||
{{#if @filter.kind}} |
||||
<search.Select |
||||
class="type-kind" |
||||
@position="left" |
||||
@onchange={{action @filter.kind.change}} |
||||
@multiple={{true}} |
||||
as |components|> |
||||
<BlockSlot @name="selected"> |
||||
<span> |
||||
{{t "components.consul.health-check.search-bar.kind.name"}} |
||||
</span> |
||||
</BlockSlot> |
||||
<BlockSlot @name="options"> |
||||
{{#let components.Optgroup components.Option as |Optgroup Option|}} |
||||
{{#each (array "service" "node") as |item|}} |
||||
<Option @value={{item}} @selected={{contains item @filter.kind.value}}> |
||||
{{t (concat "components.consul.health-check.search-bar.kind.options." item) |
||||
default=(array |
||||
(concat "common.search." item) |
||||
) |
||||
}} |
||||
</Option> |
||||
{{/each}} |
||||
{{/let}} |
||||
</BlockSlot> |
||||
</search.Select> |
||||
{{/if}} |
||||
<search.Select |
||||
class="type-check" |
||||
@position="left" |
||||
@onchange={{action @filter.check.change}} |
||||
@multiple={{true}} |
||||
as |components|> |
||||
<BlockSlot @name="selected"> |
||||
<span> |
||||
{{t "components.consul.health-check.search-bar.check.name"}} |
||||
</span> |
||||
</BlockSlot> |
||||
<BlockSlot @name="options"> |
||||
{{#let components.Optgroup components.Option as |Optgroup Option|}} |
||||
{{#each (array "alias" "docker" "grpc" "http" "script" "serf" "tcp" "ttl") as |item|}} |
||||
<Option @value={{item}} @selected={{contains item @filter.check.value}}> |
||||
{{t (concat "components.consul.health-check.search-bar.check.options." item) |
||||
default=(array |
||||
(concat "common.search." item) |
||||
) |
||||
}} |
||||
</Option> |
||||
{{/each}} |
||||
{{/let}} |
||||
</BlockSlot> |
||||
</search.Select> |
||||
</:filter> |
||||
<:sort as |search|> |
||||
<search.Select |
||||
class="type-sort" |
||||
data-test-sort-control |
||||
@position="right" |
||||
@onchange={{action @sort.change}} |
||||
@multiple={{false}} |
||||
@required={{true}} |
||||
as |components|> |
||||
<BlockSlot @name="selected"> |
||||
<span> |
||||
{{#let (from-entries (array |
||||
(array "Name:asc" (t "common.sort.alpha.asc")) |
||||
(array "Name:desc" (t "common.sort.alpha.desc")) |
||||
(array "Status:asc" (t "common.sort.status.asc")) |
||||
(array "Status:desc" (t "common.sort.status.desc")) |
||||
(array "Kind:asc" (t "components.consul.health-check.search-bar.sort.kind.asc")) |
||||
(array "Kind:desc" (t "components.consul.health-check.search-bar.sort.kind.desc")) |
||||
)) |
||||
as |selectable| |
||||
}} |
||||
{{get selectable @sort.value}} |
||||
{{/let}} |
||||
</span> |
||||
</BlockSlot> |
||||
<BlockSlot @name="options"> |
||||
{{#let components.Optgroup components.Option as |Optgroup Option|}} |
||||
<Optgroup @label="Health Status"> |
||||
<Option @value="Status:asc" @selected={{eq "Status:asc" @sort}}>Unhealthy to Healthy</Option> |
||||
<Option @value="Status:desc" @selected={{eq "Status:desc" @sort}}>Healthy to Unhealthy</Option> |
||||
<Optgroup @label={{t "common.consul.status"}}> |
||||
<Option @value="Status:asc" @selected={{eq "Status:asc" @sort.value}}>{{t "common.sort.status.asc"}}</Option> |
||||
<Option @value="Status:desc" @selected={{eq "Status:desc" @sort.value}}>{{t "common.sort.status.desc"}}</Option> |
||||
</Optgroup> |
||||
<Optgroup @label="Check Name"> |
||||
<Option @value="Name:asc" @selected={{eq "Name:asc" @sort}}>A to Z</Option> |
||||
<Option @value="Name:desc" @selected={{eq "Name:desc" @sort}}>Z to A</Option> |
||||
<Optgroup @label={{t "components.consul.health-check.search-bar.sort.name.name"}}> |
||||
<Option @value="Name:asc" @selected={{eq "Name:asc" @sort.value}}>{{t "common.sort.alpha.asc"}}</Option> |
||||
<Option @value="Name:desc" @selected={{eq "Name:desc" @sort.value}}>{{t "common.sort.alpha.desc"}}</Option> |
||||
</Optgroup> |
||||
<Optgroup @label="Check Type"> |
||||
<Optgroup @label={{t "components.consul.health-check.search-bar.sort.kind.name"}}> |
||||
<Option @value="Kind:asc" @selected={{eq "Kind:asc" @sort}}>Service to Node</Option> |
||||
<Option @value="Kind:desc" @selected={{eq "Kind:desc" @sort}}>Node to Service</Option> |
||||
</Optgroup> |
||||
{{/let}} |
||||
</BlockSlot> |
||||
</PopoverSelect> |
||||
</div> |
||||
</form> |
||||
</BlockSlot> |
||||
</search.Select> |
||||
</:sort> |
||||
</SearchBar> |
@ -1,102 +1,140 @@
|
||||
<form |
||||
class="consul-intention-search-bar filter-bar" |
||||
<SearchBar |
||||
class="consul-intention-search-bar" |
||||
...attributes |
||||
@filter={{@filter}} |
||||
> |
||||
<div class="search"> |
||||
<FreetextFilter |
||||
@onsearch={{action @onsearch}} |
||||
@value={{@search}} |
||||
@placeholder="Search" |
||||
> |
||||
<PopoverSelect |
||||
class="type-search-properties" |
||||
@position="right" |
||||
@onchange={{action @onfilter.searchproperty}} |
||||
<:status as |search|> |
||||
|
||||
{{#let |
||||
|
||||
(t (concat "components.consul.intention.search-bar." search.status.key) |
||||
default=(array |
||||
(concat "common.search." search.status.key) |
||||
(concat "common.consul." search.status.key) |
||||
) |
||||
) |
||||
|
||||
(t (concat "components.consul.intention.search-bar." search.status.value) |
||||
default=(array |
||||
(concat "common.search." search.status.value) |
||||
(concat "common.consul." search.status.value) |
||||
) |
||||
) |
||||
|
||||
as |key value|}} |
||||
<search.RemoveFilter |
||||
aria-label={{t "common.ui.remove" item=(concat key " " value)}} |
||||
> |
||||
<dl> |
||||
<dt>{{key}}</dt> |
||||
<dd>{{value}}</dd> |
||||
</dl> |
||||
</search.RemoveFilter> |
||||
{{/let}} |
||||
|
||||
</:status> |
||||
<:search as |search|> |
||||
<search.Search |
||||
@onsearch={{action @onsearch}} |
||||
@value={{@search}} |
||||
@placeholder={{t "common.search.search"}} |
||||
> |
||||
{{#if @filter.searchproperty}} |
||||
<search.Select |
||||
class="type-search-properties" |
||||
@position="right" |
||||
@onchange={{action @filter.searchproperty.change}} |
||||
@multiple={{true}} |
||||
@required={{true}} |
||||
as |components|> |
||||
<BlockSlot @name="selected"> |
||||
<span> |
||||
{{t "common.search.searchproperty"}} |
||||
</span> |
||||
</BlockSlot> |
||||
<BlockSlot @name="options"> |
||||
{{#let components.Optgroup components.Option as |Optgroup Option|}} |
||||
{{#each @filter.searchproperty.default as |prop|}} |
||||
<Option @value={{prop}} @selected={{contains prop @filter.searchproperty.value}}> |
||||
{{t (concat "common.consul." (lowercase prop))}} |
||||
</Option> |
||||
{{/each}} |
||||
{{/let}} |
||||
</BlockSlot> |
||||
</search.Select> |
||||
{{/if}} |
||||
</search.Search> |
||||
</:search> |
||||
<:filter as |search|> |
||||
<search.Select |
||||
class="type-access" |
||||
@position="left" |
||||
@onchange={{action @filter.access.change}} |
||||
@multiple={{true}} |
||||
as |components|> |
||||
<BlockSlot @name="selected"> |
||||
<span> |
||||
Search across |
||||
{{t "components.consul.intention.search-bar.access.name"}} |
||||
</span> |
||||
</BlockSlot> |
||||
<BlockSlot @name="options"> |
||||
{{#let components.Optgroup components.Option as |Optgroup Option|}} |
||||
<Option @value="SourceName" @selected={{contains 'SourceName' @filter.searchproperties}}>Source Name</Option> |
||||
<Option @value="DestinationName" @selected={{contains 'DestinationName' @filter.searchproperties}}>Destination Name</Option> |
||||
{{#each (array "allow" "deny" "") as |item|}} |
||||
<Option class={{concat 'value-' item}} @value={{or item 'app-aware'}} @selected={{contains (or item 'app-aware') @filter.access.value}}> |
||||
<span>{{t (concat "components.consul.intention.search-bar.access.options." (or item 'app-aware'))}}</span> |
||||
</Option> |
||||
{{/each}} |
||||
{{/let}} |
||||
</BlockSlot> |
||||
</PopoverSelect> |
||||
</FreetextFilter> |
||||
</div> |
||||
<div class="filters"> |
||||
<PopoverSelect |
||||
@position="left" |
||||
@onchange={{action @onfilter.access}} |
||||
@multiple={{true}} |
||||
as |components|> |
||||
<BlockSlot @name="selected"> |
||||
<span> |
||||
Permission |
||||
</span> |
||||
</BlockSlot> |
||||
<BlockSlot @name="options"> |
||||
{{#let components.Optgroup components.Option as |Optgroup Option|}} |
||||
<Option class="value-allow" @value="allow" @selected={{contains 'allow' |
||||
@filter.accesses}}><span>Allow</span></Option> |
||||
<Option class="value-deny" @value="deny" @selected={{contains 'deny' |
||||
@filter.accesses}}><span>Deny</span></Option> |
||||
<Option class="value-" @value="app-aware" @selected={{contains |
||||
'app-aware' @filter.accesses}}><span>App aware</span></Option> |
||||
{{/let}} |
||||
</BlockSlot> |
||||
</PopoverSelect> |
||||
</div> |
||||
<div class="sort"> |
||||
<PopoverSelect |
||||
class="type-sort" |
||||
data-test-sort-control |
||||
@position="right" |
||||
@onchange={{action @onsort}} |
||||
@multiple={{false}} |
||||
as |components|> |
||||
<BlockSlot @name="selected"> |
||||
<span> |
||||
{{#let (from-entries (array |
||||
(array "Action:asc" "Allow to Deny") |
||||
(array "Action:desc" "Deny to Allow") |
||||
(array "SourceName:asc" "Source: A to Z") |
||||
(array "SourceName:desc" "Source: Z to A") |
||||
(array "DestinationName:asc" "Destination: A to Z") |
||||
(array "DestinationName:desc" "Destination: Z to A") |
||||
(array "Precedence:asc" "Precedence: Ascending") |
||||
(array "Precedence:desc" "Precedence: Descending") |
||||
)) |
||||
as |selectable| |
||||
}} |
||||
{{get selectable @sort}} |
||||
{{/let}} |
||||
</span> |
||||
</BlockSlot> |
||||
<BlockSlot @name="options"> |
||||
{{#let components.Optgroup components.Option as |Optgroup Option|}} |
||||
<Optgroup @label="Permission"> |
||||
<Option @value="Action:asc" @selected={{eq "Action:asc" @sort}}>Allow to Deny</Option> |
||||
<Option @value="Action:desc" @selected={{eq "Action:desc" @sort}}>Deny to Allow</Option> |
||||
</search.Select> |
||||
</:filter> |
||||
<:sort as |search|> |
||||
<search.Select |
||||
class="type-sort" |
||||
data-test-sort-control |
||||
@position="right" |
||||
@onchange={{action @sort.change}} |
||||
@multiple={{false}} |
||||
@required={{true}} |
||||
as |components|> |
||||
<BlockSlot @name="selected"> |
||||
<span> |
||||
{{#let (from-entries (array |
||||
(array "Action:asc" (t "components.consul.intention.search-bar.sort.access.asc")) |
||||
(array "Action:desc" (t "components.consul.intention.search-bar.sort.access.desc")) |
||||
(array "SourceName:asc" (t "components.consul.intention.search-bar.sort.source-name.asc")) |
||||
(array "SourceName:desc" (t "components.consul.intention.search-bar.sort.source-name.desc")) |
||||
(array "DestinationName:asc" (t "components.consul.intention.search-bar.sort.destination-name.asc")) |
||||
(array "DestinationName:desc" (t "components.consul.intention.search-bar.sort.destination-name.desc")) |
||||
(array "Precedence:asc" (t "common.sort.numeric.asc")) |
||||
(array "Precedence:desc" (t "common.sort.numeric.desc")) |
||||
)) |
||||
as |selectable| |
||||
}} |
||||
{{get selectable @sort.value}} |
||||
{{/let}} |
||||
</span> |
||||
</BlockSlot> |
||||
<BlockSlot @name="options"> |
||||
{{#let components.Optgroup components.Option as |Optgroup Option|}} |
||||
<Optgroup @label={{t "components.consul.intention.search-bar.sort.access.name"}}> |
||||
<Option @value="Action:asc" @selected={{eq "Action:asc" @sort.value}}>{{t "components.consul.intention.search-bar.sort.access.asc"}}</Option> |
||||
<Option @value="Action:desc" @selected={{eq "Action:desc" @sort.value}}>{{t "components.consul.intention.search-bar.sort.access.desc"}}</Option> |
||||
</Optgroup> |
||||
<Optgroup @label="Source"> |
||||
<Option @value="SourceName:asc" @selected={{eq "SourceName:asc" @sort}}>A to Z</Option> |
||||
<Option @value="SourceName:desc" @selected={{eq "SourceName:desc" @sort}}>Z to A</Option> |
||||
<Optgroup @label={{t "components.consul.intention.search-bar.sort.source-name.name"}}> |
||||
<Option @value="SourceName:asc" @selected={{eq "SourceName:asc" @sort.value}}>{{t "common.sort.alpha.asc"}}</Option> |
||||
<Option @value="SourceName:desc" @selected={{eq "SourceName:desc" @sort.value}}>{{t "common.sort.alpha.desc"}}</Option> |
||||
</Optgroup> |
||||
<Optgroup @label="Destination"> |
||||
<Option @value="DestinationName:asc" @selected={{eq "DestinationName:asc" @sort}}>A to Z</Option> |
||||
<Option @value="DestinationName:desc" @selected={{eq "DestinationName:desc" @sort}}>Z to A</Option> |
||||
<Optgroup @label={{t "components.consul.intention.search-bar.sort.destination-name.name"}}> |
||||
<Option @value="DestinationName:asc" @selected={{eq "DestinationName:asc" @sort.value}}>{{t "common.sort.alpha.asc"}}</Option> |
||||
<Option @value="DestinationName:desc" @selected={{eq "DestinationName:desc" @sort.value}}>{{t "common.sort.alpha.desc"}}</Option> |
||||
</Optgroup> |
||||
<Optgroup @label="Precedence"> |
||||
<Option @value="Precedence:asc" @selected={{eq "Precedence:asc" @sort}}>Ascending</Option> |
||||
<Option @value="Precedence:desc" @selected={{eq "Precedence:desc" @sort}}>Descending</Option> |
||||
<Optgroup @label={{t "components.consul.intention.search-bar.sort.precedence.name"}}> |
||||
<Option @value="Precedence:asc" @selected={{eq "Precedence:asc" @sort.value}}>{{t "common.sort.numeric.asc"}}</Option> |
||||
<Option @value="Precedence:desc" @selected={{eq "Precedence:desc" @sort.value}}>{{t "common.sort.numeric.desc"}}</Option> |
||||
</Optgroup> |
||||
{{/let}} |
||||
</BlockSlot> |
||||
</PopoverSelect> |
||||
</div> |
||||
</form> |
||||
{{/let}} |
||||
</BlockSlot> |
||||
</search.Select> |
||||
</:sort> |
||||
</SearchBar> |
@ -1,68 +1,128 @@
|
||||
<form |
||||
class="consul-kv-search-bar filter-bar" |
||||
<SearchBar |
||||
class="consul-kv-search-bar" |
||||
...attributes |
||||
@filter={{@filter}} |
||||
> |
||||
<div class="search"> |
||||
<FreetextFilter |
||||
@onsearch={{action @onsearch}} |
||||
@value={{@search}} |
||||
@placeholder="Search" |
||||
/> |
||||
</div> |
||||
<div class="filters"> |
||||
<PopoverSelect |
||||
class="type-kind" |
||||
@position="left" |
||||
@onchange={{action @onfilter.kind}} |
||||
@multiple={{true}} |
||||
as |components|> |
||||
<BlockSlot @name="selected"> |
||||
<span> |
||||
Type |
||||
</span> |
||||
</BlockSlot> |
||||
<BlockSlot @name="options"> |
||||
{{#let components.Optgroup components.Option as |Optgroup Option|}} |
||||
<Option @value="folder" @selected={{contains 'folder' @filter.kinds}}>Folder</Option> |
||||
<Option @value="key" @selected={{contains 'key' @filter.kinds}}>Key</Option> |
||||
<:status as |search|> |
||||
|
||||
{{#let |
||||
|
||||
(t (concat "components.consul.kv.search-bar." search.status.key) |
||||
default=(array |
||||
(concat "common.search." search.status.key) |
||||
(concat "common.consul." search.status.key) |
||||
) |
||||
) |
||||
|
||||
(t (concat "components.consul.kv.search-bar." search.status.value) |
||||
default=(array |
||||
(concat "common.search." search.status.value) |
||||
(concat "common.consul." search.status.value) |
||||
) |
||||
) |
||||
|
||||
as |key value|}} |
||||
<search.RemoveFilter |
||||
aria-label={{t "common.ui.remove" item=(concat key " " value)}} |
||||
> |
||||
<dl> |
||||
<dt>{{key}}</dt> |
||||
<dd>{{value}}</dd> |
||||
</dl> |
||||
</search.RemoveFilter> |
||||
{{/let}} |
||||
</BlockSlot> |
||||
</PopoverSelect> |
||||
</div> |
||||
<div class="sort"> |
||||
<PopoverSelect |
||||
class="type-sort" |
||||
data-test-sort-control |
||||
@position="right" |
||||
@onchange={{action @onsort}} |
||||
@multiple={{false}} |
||||
as |components|> |
||||
<BlockSlot @name="selected"> |
||||
<span> |
||||
{{#let (from-entries (array |
||||
(array "Key:asc" "A to Z") |
||||
(array "Key:desc" "Z to A") |
||||
(array "Kind:asc" "Folders to Keys") |
||||
(array "Kind:desc" "Keys to Folders") |
||||
)) |
||||
as |selectable| |
||||
}} |
||||
{{get selectable @sort}} |
||||
{{/let}} |
||||
</span> |
||||
</BlockSlot> |
||||
<BlockSlot @name="options"> |
||||
{{#let components.Optgroup components.Option as |Optgroup Option|}} |
||||
<Optgroup @label="Name"> |
||||
<Option @value="Key:asc" @selected={{eq "Key:asc" @sort}}>A to Z</Option> |
||||
<Option @value="Key:desc" @selected={{eq "Key:desc" @sort}}>Z to A</Option> |
||||
</Optgroup> |
||||
<Optgroup @label="Type"> |
||||
<Option @value="Kind:asc" @selected={{eq "Kind:asc" @sort}}>Folders to Keys</Option> |
||||
<Option @value="Kind:desc" @selected={{eq "Kind:desc" @sort}}>Keys to Folders</Option> |
||||
</Optgroup> |
||||
{{/let}} |
||||
</BlockSlot> |
||||
</PopoverSelect> |
||||
</div> |
||||
</form> |
||||
|
||||
</:status> |
||||
<:search as |search|> |
||||
<search.Search |
||||
@onsearch={{action @onsearch}} |
||||
@value={{@search}} |
||||
@placeholder={{t "common.search.search"}} |
||||
> |
||||
{{#if @filter.searchproperty}} |
||||
<search.Select |
||||
class="type-search-properties" |
||||
@position="right" |
||||
@onchange={{action @filter.searchproperty.change}} |
||||
@multiple={{true}} |
||||
@required={{true}} |
||||
as |components|> |
||||
<BlockSlot @name="selected"> |
||||
<span> |
||||
{{t "common.search.searchproperty"}} |
||||
</span> |
||||
</BlockSlot> |
||||
<BlockSlot @name="options"> |
||||
{{#let components.Optgroup components.Option as |Optgroup Option|}} |
||||
{{#each @filter.searchproperty.default as |prop|}} |
||||
<Option @value={{prop}} @selected={{contains prop @filter.searchproperty.value}}> |
||||
{{t (concat "common.consul." (lowercase prop))}} |
||||
</Option> |
||||
{{/each}} |
||||
{{/let}} |
||||
</BlockSlot> |
||||
</search.Select> |
||||
{{/if}} |
||||
</search.Search> |
||||
</:search> |
||||
<:filter as |search|> |
||||
<search.Select |
||||
class="type-kind" |
||||
@position="left" |
||||
@onchange={{action @filter.kind.change}} |
||||
@multiple={{true}} |
||||
as |components|> |
||||
<BlockSlot @name="selected"> |
||||
<span> |
||||
{{t "components.consul.kv.search-bar.kind.name"}} |
||||
</span> |
||||
</BlockSlot> |
||||
<BlockSlot @name="options"> |
||||
{{#let components.Optgroup components.Option as |Optgroup Option|}} |
||||
{{#each (array "folder" "key") as |item|}} |
||||
<Option class="value-{item}}" @value={{item}} @selected={{contains item @filter.kind.value}}> |
||||
{{t (concat "components.consul.kv.search-bar.kind.options." item)}} |
||||
</Option> |
||||
{{/each}} |
||||
{{/let}} |
||||
</BlockSlot> |
||||
</search.Select> |
||||
</:filter> |
||||
<:sort as |search|> |
||||
<search.Select |
||||
class="type-sort" |
||||
data-test-sort-control |
||||
@position="right" |
||||
@onchange={{action @sort.change}} |
||||
@multiple={{false}} |
||||
@required={{true}} |
||||
as |components|> |
||||
<BlockSlot @name="selected"> |
||||
<span> |
||||
{{#let (from-entries (array |
||||
(array "Key:asc" (t "common.sort.alpha.asc")) |
||||
(array "Key:desc" (t "common.sort.alpha.desc")) |
||||
(array "Kind:asc" (t "components.consul.kv.search-bar.sort.kind.asc")) |
||||
(array "Kind:desc" (t "components.consul.kv.search-bar.sort.kind.desc")) |
||||
)) |
||||
as |selectable| |
||||
}} |
||||
{{get selectable @sort.value}} |
||||
{{/let}} |
||||
</span> |
||||
</BlockSlot> |
||||
<BlockSlot @name="options"> |
||||
{{#let components.Optgroup components.Option as |Optgroup Option|}} |
||||
<Optgroup @label={{t "common.consul.name"}}> |
||||
<Option @value="Key:asc" @selected={{eq "Key:asc" @sort.value}}>{{t "common.sort.alpha.asc"}}</Option> |
||||
<Option @value="Key:desc" @selected={{eq "Key:desc" @sort.value}}>{{t "common.sort.alpha.desc"}}</Option> |
||||
</Optgroup> |
||||
<Optgroup @label={{t "components.consul.kv.search-bar.kind.name"}}> |
||||
<Option @value="Kind:asc" @selected={{eq "Kind:asc" @sort.value}}>{{t "components.consul.kv.search-bar.sort.kind.asc"}}</Option> |
||||
<Option @value="Kind:desc" @selected={{eq "Kind:desc" @sort.value}}>{{t "components.consul.kv.search-bar.sort.kind.desc"}}</Option> |
||||
</Optgroup> |
||||
{{/let}} |
||||
</BlockSlot> |
||||
</search.Select> |
||||
</:sort> |
||||
</SearchBar> |
||||
|
@ -1,90 +1,131 @@
|
||||
<form |
||||
class="consul-node-search-bar filter-bar" |
||||
<SearchBar |
||||
class="consul-node-search-bar" |
||||
...attributes |
||||
@filter={{@filter}} |
||||
> |
||||
<div class="search"> |
||||
<FreetextFilter |
||||
@onsearch={{action @onsearch}} |
||||
@value={{@search}} |
||||
@placeholder="Search" |
||||
> |
||||
<PopoverSelect |
||||
class="type-search-properties" |
||||
@position="right" |
||||
@onchange={{action @onfilter.searchproperty}} |
||||
<:status as |search|> |
||||
|
||||
{{#let |
||||
|
||||
(t (concat "components.consul.node.search-bar." search.status.key) |
||||
default=(array |
||||
(concat "common.search." search.status.key) |
||||
(concat "common.consul." search.status.key) |
||||
) |
||||
) |
||||
|
||||
(t (concat "components.consul.node.search-bar." search.status.value) |
||||
default=(array |
||||
(concat "common.search." search.status.value) |
||||
(concat "common.consul." search.status.value) |
||||
(concat "common.brand." search.status.value) |
||||
) |
||||
) |
||||
|
||||
as |key value|}} |
||||
<search.RemoveFilter |
||||
aria-label={{t "common.ui.remove" item=(concat key " " value)}} |
||||
> |
||||
<dl> |
||||
<dt>{{key}}</dt> |
||||
<dd>{{value}}</dd> |
||||
</dl> |
||||
</search.RemoveFilter> |
||||
{{/let}} |
||||
|
||||
</:status> |
||||
<:search as |search|> |
||||
<search.Search |
||||
@onsearch={{action @onsearch}} |
||||
@value={{@search}} |
||||
@placeholder={{t "common.search.search"}} |
||||
> |
||||
<search.Select |
||||
class="type-search-properties" |
||||
@position="right" |
||||
@onchange={{action @filter.searchproperty.change}} |
||||
@multiple={{true}} |
||||
@required={{true}} |
||||
as |components|> |
||||
<BlockSlot @name="selected"> |
||||
<span> |
||||
{{t "common.search.searchproperty"}} |
||||
</span> |
||||
</BlockSlot> |
||||
<BlockSlot @name="options"> |
||||
{{#let components.Optgroup components.Option as |Optgroup Option|}} |
||||
{{#each @filter.searchproperty.default as |prop|}} |
||||
<Option @value={{prop}} @selected={{contains prop @filter.searchproperty.value}}> |
||||
{{t (concat "common.consul." (lowercase prop))}} |
||||
</Option> |
||||
{{/each}} |
||||
{{/let}} |
||||
</BlockSlot> |
||||
</search.Select> |
||||
</search.Search> |
||||
</:search> |
||||
<:filter as |search|> |
||||
<search.Select |
||||
class="type-status" |
||||
@position="left" |
||||
@onchange={{action @filter.status.change}} |
||||
@multiple={{true}} |
||||
as |components|> |
||||
<BlockSlot @name="selected"> |
||||
<span> |
||||
Search across |
||||
{{t "common.consul.status"}} |
||||
</span> |
||||
</BlockSlot> |
||||
<BlockSlot @name="options"> |
||||
{{#let components.Optgroup components.Option as |Optgroup Option|}} |
||||
<Option @value="Node" @selected={{contains 'Node' @filter.searchproperties}}>Node Name</Option> |
||||
<Option @value="Address" @selected={{contains 'Address' @filter.searchproperties}}>Address</Option> |
||||
<Option @value="Meta" @selected={{contains 'Meta' @filter.searchproperties}}>Node Meta</Option> |
||||
{{#each (array "passing" "warning" "critical") as |state|}} |
||||
<Option class="value-{{state}}" @value={{state}} @selected={{contains state @filter.status.value}}> |
||||
{{t (concat "common.consul." state) |
||||
default=(array |
||||
(concat "common.search." state) |
||||
) |
||||
}} |
||||
</Option> |
||||
{{/each}} |
||||
{{/let}} |
||||
</BlockSlot> |
||||
</PopoverSelect> |
||||
</FreetextFilter> |
||||
</div> |
||||
<div class="filters"> |
||||
<PopoverSelect |
||||
class="type-status" |
||||
@position="left" |
||||
@onchange={{action @onfilter.status}} |
||||
@multiple={{true}} |
||||
as |components|> |
||||
<BlockSlot @name="selected"> |
||||
<span> |
||||
Health Status |
||||
</span> |
||||
</BlockSlot> |
||||
<BlockSlot @name="options"> |
||||
{{#let components.Optgroup components.Option as |Optgroup Option|}} |
||||
<Option class="value-passing" @value="passing" @selected={{contains 'passing' @filter.statuses}}>Passing</Option> |
||||
<Option class="value-warning" @value="warning" @selected={{contains 'warning' @filter.statuses}}>Warning</Option> |
||||
<Option class="value-critical" @value="critical" @selected={{contains 'critical' @filter.statuses}}>Failing</Option> |
||||
<Option class="value-empty" @value="empty" @selected={{contains 'empty' @filter.statuses}}>No checks</Option> |
||||
{{/let}} |
||||
</BlockSlot> |
||||
</PopoverSelect> |
||||
</div> |
||||
<div class="sort"> |
||||
<PopoverSelect |
||||
class="type-sort" |
||||
data-test-sort-control |
||||
@position="right" |
||||
@onchange={{action @onsort}} |
||||
@multiple={{false}} |
||||
as |components|> |
||||
<BlockSlot @name="selected"> |
||||
<span> |
||||
{{#let (from-entries (array |
||||
(array "Node:asc" "A to Z") |
||||
(array "Node:desc" "Z to A") |
||||
(array "Status:asc" "Unhealthy to Healthy") |
||||
(array "Status:desc" "Healthy to Unhealthy") |
||||
)) |
||||
as |selectable| |
||||
}} |
||||
{{get selectable @sort}} |
||||
{{/let}} |
||||
</span> |
||||
</BlockSlot> |
||||
<BlockSlot @name="options"> |
||||
{{#let components.Optgroup components.Option as |Optgroup Option|}} |
||||
<Optgroup @label="Health Status"> |
||||
<Option @value="Status:asc" @selected={{eq "Status:asc" @sort}}>Unhealthy to Healthy</Option> |
||||
<Option @value="Status:desc" @selected={{eq "Status:desc" @sort}}>Healthy to Unhealthy</Option> |
||||
</Optgroup> |
||||
<Optgroup @label="Service Name"> |
||||
<Option @value="Node:asc" @selected={{eq "Node:asc" @sort}}>A to Z</Option> |
||||
<Option @value="Node:desc" @selected={{eq "Node:desc" @sort}}>Z to A</Option> |
||||
</Optgroup> |
||||
{{/let}} |
||||
</BlockSlot> |
||||
</PopoverSelect> |
||||
</div> |
||||
</form> |
||||
</search.Select> |
||||
</:filter> |
||||
<:sort as |search|> |
||||
<search.Select |
||||
class="type-sort" |
||||
data-test-sort-control |
||||
@position="right" |
||||
@onchange={{action @sort.change}} |
||||
@multiple={{false}} |
||||
@required={{true}} |
||||
as |components|> |
||||
<BlockSlot @name="selected"> |
||||
<span> |
||||
{{#let (from-entries (array |
||||
(array "Node:asc" (t "common.sort.alpha.asc")) |
||||
(array "Node:desc" (t "common.sort.alpha.desc")) |
||||
(array "Status:asc" (t "common.sort.status.asc")) |
||||
(array "Status:desc" (t "common.sort.status.desc")) |
||||
)) |
||||
as |selectable| |
||||
}} |
||||
{{get selectable @sort.value}} |
||||
{{/let}} |
||||
</span> |
||||
</BlockSlot> |
||||
<BlockSlot @name="options"> |
||||
{{#let components.Optgroup components.Option as |Optgroup Option|}} |
||||
<Optgroup @label={{t "common.consul.status"}}> |
||||
<Option @value="Status:asc" @selected={{eq "Status:asc" @sort.value}}>{{t "common.sort.status.asc"}}</Option> |
||||
<Option @value="Status:desc" @selected={{eq "Status:desc" @sort.value}}>{{t "common.sort.status.desc"}}</Option> |
||||
</Optgroup> |
||||
<Optgroup @label={{t "common.consul.node-name"}}> |
||||
<Option @value="Node:asc" @selected={{eq "Node:asc" @sort.value}}>{{t "common.sort.alpha.asc"}}</Option> |
||||
<Option @value="Node:desc" @selected={{eq "Node:desc" @sort.value}}>{{t "common.sort.alpha.desc"}}</Option> |
||||
</Optgroup> |
||||
{{/let}} |
||||
</BlockSlot> |
||||
</search.Select> |
||||
</:sort> |
||||
</SearchBar> |
@ -1,63 +1,98 @@
|
||||
<form |
||||
class="consul-nspace-search-bar filter-bar" |
||||
<SearchBar |
||||
class="consul-nspace-search-bar" |
||||
...attributes |
||||
@filter={{@filter}} |
||||
> |
||||
<div class="search"> |
||||
<FreetextFilter |
||||
@onsearch={{action @onsearch}} |
||||
@value={{@search}} |
||||
@placeholder="Search" |
||||
> |
||||
<PopoverSelect |
||||
class="type-search-properties" |
||||
<:status as |search|> |
||||
|
||||
{{#let |
||||
|
||||
(t (concat "components.consul.nspace.search-bar." search.status.key) |
||||
default=(array |
||||
(concat "common.search." search.status.key) |
||||
(concat "common.consul." search.status.key) |
||||
) |
||||
) |
||||
|
||||
(t (concat "components.consul.nspace.search-bar." search.status.value) |
||||
default=(array |
||||
(concat "common.search." search.status.value) |
||||
(concat "common.consul." search.status.value) |
||||
(concat "common.brand." search.status.value) |
||||
) |
||||
) |
||||
|
||||
as |key value|}} |
||||
<search.RemoveFilter |
||||
aria-label={{t "common.ui.remove" item=(concat key " " value)}} |
||||
> |
||||
<dl> |
||||
<dt>{{key}}</dt> |
||||
<dd>{{value}}</dd> |
||||
</dl> |
||||
</search.RemoveFilter> |
||||
{{/let}} |
||||
|
||||
</:status> |
||||
<:search as |search|> |
||||
<search.Search |
||||
@onsearch={{action @onsearch}} |
||||
@value={{@search}} |
||||
@placeholder={{t "common.search.search"}} |
||||
> |
||||
<search.Select |
||||
class="type-search-properties" |
||||
@position="right" |
||||
@onchange={{action @filter.searchproperty.change}} |
||||
@multiple={{true}} |
||||
@required={{true}} |
||||
as |components|> |
||||
<BlockSlot @name="selected"> |
||||
<span> |
||||
{{t "common.search.searchproperty"}} |
||||
</span> |
||||
</BlockSlot> |
||||
<BlockSlot @name="options"> |
||||
{{#let components.Optgroup components.Option as |Optgroup Option|}} |
||||
{{#each @filter.searchproperty.default as |prop|}} |
||||
<Option @value={{prop}} @selected={{contains prop @filter.searchproperty.value}}> |
||||
{{t (concat "common.consul." (lowercase prop))}} |
||||
</Option> |
||||
{{/each}} |
||||
{{/let}} |
||||
</BlockSlot> |
||||
</search.Select> |
||||
</search.Search> |
||||
</:search> |
||||
<:sort as |search|> |
||||
<search.Select |
||||
class="type-sort" |
||||
data-test-sort-control |
||||
@position="right" |
||||
@onchange={{action @onfilter.searchproperty}} |
||||
@multiple={{true}} |
||||
@onchange={{action @sort.change}} |
||||
@multiple={{false}} |
||||
@required={{true}} |
||||
as |components|> |
||||
<BlockSlot @name="selected"> |
||||
<span> |
||||
Search across |
||||
{{#let (from-entries (array |
||||
(array "Name:asc" (t "common.sort.alpha.asc")) |
||||
(array "Name:desc" (t "common.sort.alpha.desc")) |
||||
)) |
||||
as |selectable| |
||||
}} |
||||
{{get selectable @sort.value}} |
||||
{{/let}} |
||||
</span> |
||||
</BlockSlot> |
||||
<BlockSlot @name="options"> |
||||
{{#let components.Optgroup components.Option as |Optgroup Option|}} |
||||
<Option @value="Name" @selected={{contains 'Name' @filter.searchproperties}}>Name</Option> |
||||
<Option @value="Description" @selected={{contains 'Description' @filter.searchproperties}}>Description</Option> |
||||
<Option @value="Policy" @selected={{contains 'Policy' @filter.searchproperties}}>Policy</Option> |
||||
<Option @value="Role" @selected={{contains 'Role' @filter.searchproperties}}>Role</Option> |
||||
<Optgroup @label={{t "common.consul.name"}}> |
||||
<Option @value="Name:asc" @selected={{eq "Name:asc" @sort.value}}>{{t "common.sort.alpha.asc"}}</Option> |
||||
<Option @value="Name:desc" @selected={{eq "Name:desc" @sort.value}}>{{t "common.sort.alpha.desc"}}</Option> |
||||
</Optgroup> |
||||
{{/let}} |
||||
</BlockSlot> |
||||
</PopoverSelect> |
||||
</FreetextFilter> |
||||
</div> |
||||
<div class="sort"> |
||||
<PopoverSelect |
||||
class="type-sort" |
||||
data-test-sort-control |
||||
@position="right" |
||||
@onchange={{action @onsort}} |
||||
@multiple={{false}} |
||||
as |components|> |
||||
<BlockSlot @name="selected"> |
||||
<span> |
||||
{{#let (from-entries (array |
||||
(array "Name:asc" "A to Z") |
||||
(array "Name:desc" "Z to A") |
||||
)) |
||||
as |selectable| |
||||
}} |
||||
{{get selectable @sort}} |
||||
{{/let}} |
||||
</span> |
||||
</BlockSlot> |
||||
<BlockSlot @name="options"> |
||||
{{#let components.Optgroup components.Option as |Optgroup Option|}} |
||||
<Optgroup @label="Name"> |
||||
<Option @value="Name:asc" @selected={{eq "Name:asc" @sort}}>A to Z</Option> |
||||
<Option @value="Name:desc" @selected={{eq "Name:desc" @sort}}>Z to A</Option> |
||||
</Optgroup> |
||||
{{/let}} |
||||
</BlockSlot> |
||||
</PopoverSelect> |
||||
</div> |
||||
</form> |
||||
</search.Select> |
||||
</:sort> |
||||
</SearchBar> |
@ -1,101 +1,145 @@
|
||||
<form |
||||
class="consul-policy-search-bar filter-bar" |
||||
<SearchBar |
||||
class="consul-policy-search-bar" |
||||
...attributes |
||||
@filter={{@filter}} |
||||
> |
||||
<div class="search"> |
||||
<FreetextFilter |
||||
@onsearch={{action @onsearch}} |
||||
@value={{@search}} |
||||
@placeholder="Search" |
||||
> |
||||
<PopoverSelect |
||||
class="type-search-properties" |
||||
@position="right" |
||||
@onchange={{action @onfilter.searchproperty}} |
||||
<:status as |search|> |
||||
|
||||
{{#let |
||||
|
||||
(t (concat "components.consul.policy.search-bar." search.status.key ".name") |
||||
default=(array |
||||
(concat "common.search." search.status.key) |
||||
(concat "common.consul." search.status.key) |
||||
) |
||||
) |
||||
|
||||
(t (concat "components.consul.policy.search-bar." search.status.key ".options." search.status.value) |
||||
default=(array |
||||
(concat "common.search." search.status.value) |
||||
(concat "common.consul." search.status.value) |
||||
(concat "common.brand." search.status.value) |
||||
) |
||||
) |
||||
|
||||
as |key value|}} |
||||
<search.RemoveFilter |
||||
aria-label={{t "common.ui.remove" item=(concat key " " value)}} |
||||
> |
||||
<dl> |
||||
<dt>{{key}}</dt> |
||||
<dd>{{if (eq search.status.key 'datacenter') search.status.value value}}</dd> |
||||
</dl> |
||||
</search.RemoveFilter> |
||||
{{/let}} |
||||
|
||||
</:status> |
||||
<:search as |search|> |
||||
<search.Search |
||||
@onsearch={{action @onsearch}} |
||||
@value={{@search}} |
||||
@placeholder={{t "common.search.search"}} |
||||
> |
||||
<search.Select |
||||
class="type-search-properties" |
||||
@position="right" |
||||
@onchange={{action @filter.searchproperty.change}} |
||||
@multiple={{true}} |
||||
@required={{true}} |
||||
as |components|> |
||||
<BlockSlot @name="selected"> |
||||
<span> |
||||
{{t "common.search.searchproperty"}} |
||||
</span> |
||||
</BlockSlot> |
||||
<BlockSlot @name="options"> |
||||
{{#let components.Optgroup components.Option as |Optgroup Option|}} |
||||
{{#each @filter.searchproperty.default as |prop|}} |
||||
<Option @value={{prop}} @selected={{contains prop @filter.searchproperty.value}}> |
||||
{{t (concat "common.consul." (lowercase prop))}} |
||||
</Option> |
||||
{{/each}} |
||||
{{/let}} |
||||
</BlockSlot> |
||||
</search.Select> |
||||
</search.Search> |
||||
</:search> |
||||
<:filter as |search|> |
||||
<search.Select |
||||
class="type-datacenter" |
||||
@position="left" |
||||
@onchange={{action @filter.datacenter.change}} |
||||
@multiple={{true}} |
||||
as |components|> |
||||
<BlockSlot @name="selected"> |
||||
<span> |
||||
{{t "common.consul.datacenter"}} |
||||
</span> |
||||
</BlockSlot> |
||||
<BlockSlot @name="options"> |
||||
{{#let components.Optgroup components.Option as |Optgroup Option|}} |
||||
{{#each dcs as |dc|}} |
||||
<Option @value={{dc.Name}} @selected={{contains dc.Name @filter.datacenter.value}}>{{dc.Name}}</Option> |
||||
{{/each}} |
||||
<DataSource @src="/*/*/datacenters" @loading="lazy" @onchange={{action (mut this.dcs) value="data"}} /> |
||||
{{/let}} |
||||
</BlockSlot> |
||||
</search.Select> |
||||
<search.Select |
||||
class="type-kind" |
||||
@position="left" |
||||
@onchange={{action @filter.kind.change}} |
||||
@multiple={{true}} |
||||
as |components|> |
||||
<BlockSlot @name="selected"> |
||||
<span> |
||||
Search across |
||||
{{t "components.consul.policy.search-bar.kind.name"}} |
||||
</span> |
||||
</BlockSlot> |
||||
<BlockSlot @name="options"> |
||||
{{#let components.Optgroup components.Option as |Optgroup Option|}} |
||||
<Option @value="Name" @selected={{contains 'Name' @filter.searchproperties}}>Name</Option> |
||||
<Option @value="Description" @selected={{contains 'Description' @filter.searchproperties}}>Description</Option> |
||||
{{#each (array "global-management" "standard") as |state|}} |
||||
<Option class="value-{{state}}" @value={{state}} @selected={{contains state @filter.kind.value}}> |
||||
{{t (concat "components.consul.policy.search-bar.kind.options." state) |
||||
default=(array |
||||
(concat "common.search." state) |
||||
) |
||||
}} |
||||
</Option> |
||||
{{/each}} |
||||
{{/let}} |
||||
</BlockSlot> |
||||
</PopoverSelect> |
||||
</FreetextFilter> |
||||
</div> |
||||
<div class="filters"> |
||||
<PopoverSelect |
||||
class="select-dcs" |
||||
@position="left" |
||||
@onchange={{action @onfilter.dc}} |
||||
@multiple={{true}} |
||||
as |components|> |
||||
<BlockSlot @name="selected"> |
||||
<span> |
||||
Datacenters |
||||
</span> |
||||
</BlockSlot> |
||||
<BlockSlot @name="options"> |
||||
{{#let components.Optgroup components.Option as |Optgroup Option|}} |
||||
{{#each dcs as |dc|}} |
||||
<Option @value={{@dc.Name}} @selected={{contains dc.Name @filter.dcs}}>{{dc.Name}}</Option> |
||||
{{/each}} |
||||
{{/let}} |
||||
<DataSource @src="/*/*/datacenters" @loading="lazy" @onchange={{action (mut this.dcs) value="data"}} /> |
||||
</BlockSlot> |
||||
</PopoverSelect> |
||||
<PopoverSelect |
||||
class="select-type" |
||||
@position="left" |
||||
@onchange={{action @onfilter.kind}} |
||||
@multiple={{true}} |
||||
as |components|> |
||||
<BlockSlot @name="selected"> |
||||
<span> |
||||
Type |
||||
</span> |
||||
</BlockSlot> |
||||
<BlockSlot @name="options"> |
||||
{{#let components.Optgroup components.Option as |Optgroup Option|}} |
||||
<Option @value="global-management" @selected={{contains 'global-management' @filter.kinds}}>Global Management</Option> |
||||
<Option @value="standard" @selected={{contains 'standard' @filter.kinds}}>Standard</Option> |
||||
{{/let}} |
||||
</BlockSlot> |
||||
</PopoverSelect> |
||||
</div> |
||||
<div class="sort"> |
||||
<PopoverSelect |
||||
class="type-sort" |
||||
data-test-sort-control |
||||
@position="right" |
||||
@onchange={{action @onsort}} |
||||
@multiple={{false}} |
||||
as |components|> |
||||
<BlockSlot @name="selected"> |
||||
<span> |
||||
{{#let (from-entries (array |
||||
(array "Name:asc" "A to Z") |
||||
(array "Name:desc" "Z to A") |
||||
)) |
||||
as |selectable| |
||||
}} |
||||
{{get selectable @sort}} |
||||
{{/let}} |
||||
</span> |
||||
</BlockSlot> |
||||
<BlockSlot @name="options"> |
||||
{{#let components.Optgroup components.Option as |Optgroup Option|}} |
||||
<Optgroup @label="Name"> |
||||
<Option @value="Name:asc" @selected={{eq "Name:asc" @sort}}>A to Z</Option> |
||||
<Option @value="Name:desc" @selected={{eq "Name:desc" @sort}}>Z to A</Option> |
||||
</Optgroup> |
||||
{{/let}} |
||||
</BlockSlot> |
||||
</PopoverSelect> |
||||
</div> |
||||
</form> |
||||
</search.Select> |
||||
</:filter> |
||||
<:sort as |search|> |
||||
<search.Select |
||||
class="type-sort" |
||||
data-test-sort-control |
||||
@position="right" |
||||
@onchange={{action @sort.change}} |
||||
@multiple={{false}} |
||||
@required={{true}} |
||||
as |components|> |
||||
<BlockSlot @name="selected"> |
||||
<span> |
||||
{{#let (from-entries (array |
||||
(array "Name:asc" (t "common.sort.alpha.asc")) |
||||
(array "Name:desc" (t "common.sort.alpha.desc")) |
||||
)) |
||||
as |selectable| |
||||
}} |
||||
{{get selectable @sort.value}} |
||||
{{/let}} |
||||
</span> |
||||
</BlockSlot> |
||||
<BlockSlot @name="options"> |
||||
{{#let components.Optgroup components.Option as |Optgroup Option|}} |
||||
<Optgroup @label={{t "common.ui.name"}}> |
||||
<Option @value="Name:asc" @selected={{eq "Name:asc" @sort.value}}>{{t "common.sort.alpha.asc"}}</Option> |
||||
<Option @value="Name:desc" @selected={{eq "Name:desc" @sort.value}}>{{t "common.sort.alpha.desc"}}</Option> |
||||
</Optgroup> |
||||
{{/let}} |
||||
</BlockSlot> |
||||
</search.Select> |
||||
</:sort> |
||||
</SearchBar> |
||||
|
@ -1,68 +1,104 @@
|
||||
<form |
||||
class="consul-role-search-bar filter-bar" |
||||
<SearchBar |
||||
class="consul-role-search-bar" |
||||
...attributes |
||||
@filter={{@filter}} |
||||
> |
||||
<div class="search"> |
||||
<FreetextFilter |
||||
@onsearch={{action @onsearch}} |
||||
@value={{@search}} |
||||
@placeholder="Search" |
||||
> |
||||
<PopoverSelect |
||||
class="type-search-properties" |
||||
<:status as |search|> |
||||
|
||||
{{#let |
||||
|
||||
(t (concat "components.consul.role.search-bar." search.status.key ".name") |
||||
default=(array |
||||
(concat "common.search." search.status.key) |
||||
(concat "common.consul." search.status.key) |
||||
) |
||||
) |
||||
|
||||
(t (concat "components.consul.role.search-bar." search.status.key ".options." search.status.value) |
||||
default=(array |
||||
(concat "common.search." search.status.value) |
||||
(concat "common.consul." search.status.value) |
||||
(concat "common.brand." search.status.value) |
||||
) |
||||
) |
||||
|
||||
as |key value|}} |
||||
<search.RemoveFilter |
||||
aria-label={{t "common.ui.remove" item=(concat key " " value)}} |
||||
> |
||||
<dl> |
||||
<dt>{{key}}</dt> |
||||
<dd>{{value}}</dd> |
||||
</dl> |
||||
</search.RemoveFilter> |
||||
{{/let}} |
||||
|
||||
</:status> |
||||
<:search as |search|> |
||||
<search.Search |
||||
@onsearch={{action @onsearch}} |
||||
@value={{@search}} |
||||
@placeholder={{t "common.search.search"}} |
||||
> |
||||
<search.Select |
||||
class="type-search-properties" |
||||
@position="right" |
||||
@onchange={{action @filter.searchproperty.change}} |
||||
@multiple={{true}} |
||||
@required={{true}} |
||||
as |components|> |
||||
<BlockSlot @name="selected"> |
||||
<span> |
||||
{{t "common.search.searchproperty"}} |
||||
</span> |
||||
</BlockSlot> |
||||
<BlockSlot @name="options"> |
||||
{{#let components.Optgroup components.Option as |Optgroup Option|}} |
||||
{{#each @filter.searchproperty.default as |prop|}} |
||||
<Option @value={{prop}} @selected={{contains prop @filter.searchproperty.value}}> |
||||
{{t (concat "common.consul." (lowercase prop))}} |
||||
</Option> |
||||
{{/each}} |
||||
{{/let}} |
||||
</BlockSlot> |
||||
</search.Select> |
||||
</search.Search> |
||||
</:search> |
||||
<:sort as |search|> |
||||
<search.Select |
||||
class="type-sort" |
||||
data-test-sort-control |
||||
@position="right" |
||||
@onchange={{action @onfilter.searchproperty}} |
||||
@multiple={{true}} |
||||
@onchange={{action @sort.change}} |
||||
@multiple={{false}} |
||||
@required={{true}} |
||||
as |components|> |
||||
<BlockSlot @name="selected"> |
||||
<span> |
||||
Search across |
||||
{{#let (from-entries (array |
||||
(array "Name:asc" (t "common.sort.alpha.asc")) |
||||
(array "Name:desc" (t "common.sort.alpha.desc")) |
||||
(array "CreateIndex:desc" (t "common.sort.age.desc")) |
||||
(array "CreateIndex:asc" (t "common.sort.age.asc")) |
||||
)) |
||||
as |selectable| |
||||
}} |
||||
{{get selectable @sort.value}} |
||||
{{/let}} |
||||
</span> |
||||
</BlockSlot> |
||||
<BlockSlot @name="options"> |
||||
{{#let components.Optgroup components.Option as |Optgroup Option|}} |
||||
<Option @value="Name" @selected={{contains 'Name' @filter.searchproperties}}>Name</Option> |
||||
<Option @value="Description" @selected={{contains 'Description' @filter.searchproperties}}>Description</Option> |
||||
<Option @value="Policy" @selected={{contains 'Policy' @filter.searchproperties}}>Policy</Option> |
||||
{{/let}} |
||||
</BlockSlot> |
||||
</PopoverSelect> |
||||
</FreetextFilter> |
||||
</div> |
||||
<div class="sort"> |
||||
<PopoverSelect |
||||
class="type-sort" |
||||
data-test-sort-control |
||||
@position="right" |
||||
@onchange={{action @onsort}} |
||||
@multiple={{false}} |
||||
as |components|> |
||||
<BlockSlot @name="selected"> |
||||
<span> |
||||
{{#let (from-entries (array |
||||
(array "Name:asc" "A to Z") |
||||
(array "Name:desc" "Z to A") |
||||
(array "CreateIndex:desc" "Newest to oldest") |
||||
(array "CreateIndex:asc" "Oldest to newest") |
||||
)) |
||||
as |selectable| |
||||
}} |
||||
{{get selectable @sort}} |
||||
{{/let}} |
||||
</span> |
||||
</BlockSlot> |
||||
<BlockSlot @name="options"> |
||||
{{#let components.Optgroup components.Option as |Optgroup Option|}} |
||||
<Optgroup @label="Name"> |
||||
<Option @value="Name:asc" @selected={{eq "Name:asc" @sort}}>A to Z</Option> |
||||
<Option @value="Name:desc" @selected={{eq "Name:desc" @sort}}>Z to A</Option> |
||||
<Optgroup @label={{t "common.ui.name"}}> |
||||
<Option @value="Name:asc" @selected={{eq "Name:asc" @sort.value}}>{{t "common.sort.alpha.asc"}}</Option> |
||||
<Option @value="Name:desc" @selected={{eq "Name:desc" @sort.value}}>{{t "common.sort.alpha.desc"}}</Option> |
||||
</Optgroup> |
||||
<Optgroup @label="Creation"> |
||||
<Option @value="CreateIndex:desc" @selected={{eq "CreateIndex:desc" @sort}}>Newest to oldest</Option> |
||||
<Option @value="CreateIndex:asc" @selected={{eq "CreateIndex:asc" @sort}}>Oldest to newest</Option> |
||||
<Optgroup @label={{t "common.ui.creation"}}> |
||||
<Option @value="CreateIndex:desc" @selected={{eq "CreateIndex:desc" @sort.value}}>{{t "common.sort.age.desc"}}</Option> |
||||
<Option @value="CreateIndex:asc" @selected={{eq "CreateIndex:asc" @sort.value}}>{{t "common.sort.age.asc"}}</Option> |
||||
</Optgroup> |
||||
{{/let}} |
||||
</BlockSlot> |
||||
</PopoverSelect> |
||||
</div> |
||||
</form> |
||||
{{/let}} |
||||
</BlockSlot> |
||||
</search.Select> |
||||
</:sort> |
||||
</SearchBar> |
||||
|
@ -1,111 +1,156 @@
|
||||
<form |
||||
class="consul-service-instance-search-bar filter-bar" |
||||
<SearchBar |
||||
class="consul-service-instance-search-bar" |
||||
...attributes |
||||
@filter={{@filter}} |
||||
> |
||||
<div class="search"> |
||||
<FreetextFilter |
||||
@onsearch={{action @onsearch}} |
||||
@value={{@search}} |
||||
@placeholder="Search" |
||||
> |
||||
<PopoverSelect |
||||
class="type-search-properties" |
||||
@position="right" |
||||
@onchange={{action @onfilter.searchproperty}} |
||||
<:status as |search|> |
||||
|
||||
{{#let |
||||
|
||||
(t (concat "components.consul.service-instance.search-bar." search.status.key ".name") |
||||
default=(array |
||||
(concat "common.search." search.status.key) |
||||
(concat "common.consul." search.status.key) |
||||
) |
||||
) |
||||
|
||||
(t (concat "components.consul.service-instance.search-bar." search.status.key ".options." search.status.value) |
||||
default=(array |
||||
(concat "common.search." search.status.value) |
||||
(concat "common.consul." search.status.value) |
||||
(concat "common.brand." search.status.value) |
||||
) |
||||
) |
||||
|
||||
as |key value|}} |
||||
<search.RemoveFilter |
||||
aria-label={{t "common.ui.remove" item=(concat key " " value)}} |
||||
> |
||||
<dl> |
||||
<dt>{{key}}</dt> |
||||
<dd>{{value}}</dd> |
||||
</dl> |
||||
</search.RemoveFilter> |
||||
{{/let}} |
||||
|
||||
</:status> |
||||
<:search as |search|> |
||||
<search.Search |
||||
@onsearch={{action @onsearch}} |
||||
@value={{@search}} |
||||
@placeholder={{t "common.search.search"}} |
||||
> |
||||
{{#if @filter.searchproperty}} |
||||
<search.Select |
||||
class="type-search-properties" |
||||
@position="right" |
||||
@onchange={{action @filter.searchproperty.change}} |
||||
@multiple={{true}} |
||||
@required={{true}} |
||||
as |components|> |
||||
<BlockSlot @name="selected"> |
||||
<span> |
||||
{{t "common.search.searchproperty"}} |
||||
</span> |
||||
</BlockSlot> |
||||
<BlockSlot @name="options"> |
||||
{{#let components.Optgroup components.Option as |Optgroup Option|}} |
||||
{{#each @filter.searchproperty.default as |prop|}} |
||||
<Option @value={{prop}} @selected={{contains prop @filter.searchproperty.value}}> |
||||
{{t (concat "common.consul." (lowercase prop))}} |
||||
</Option> |
||||
{{/each}} |
||||
{{/let}} |
||||
</BlockSlot> |
||||
</search.Select> |
||||
{{/if}} |
||||
</search.Search> |
||||
</:search> |
||||
<:filter as |search|> |
||||
<search.Select |
||||
class="type-status" |
||||
@position="left" |
||||
@onchange={{action @filter.status.change}} |
||||
@multiple={{true}} |
||||
as |components|> |
||||
<BlockSlot @name="selected"> |
||||
<span> |
||||
Search across |
||||
{{t "common.consul.status"}} |
||||
</span> |
||||
</BlockSlot> |
||||
<BlockSlot @name="options"> |
||||
{{#let components.Optgroup components.Option as |Optgroup Option|}} |
||||
{{#each @searchproperties as |prop|}} |
||||
<Option @value={{prop}} @selected={{contains prop @filter.searchproperties}}>{{string-replace-all prop '\.' ' '}}</Option> |
||||
{{#each (array "passing" "warning" "critical" "empty") as |state|}} |
||||
<Option class="value-{{state}}" @value={{state}} @selected={{contains state @filter.status.value}}> |
||||
{{t (concat "common.consul." state) |
||||
default=(array |
||||
(concat "common.search." state) |
||||
) |
||||
}} |
||||
</Option> |
||||
{{/each}} |
||||
{{/let}} |
||||
</BlockSlot> |
||||
</PopoverSelect> |
||||
</FreetextFilter> |
||||
</div> |
||||
<div class="filters"> |
||||
<PopoverSelect |
||||
class="type-status" |
||||
@position="left" |
||||
@onchange={{action @onfilter.status}} |
||||
@multiple={{true}} |
||||
as |components|> |
||||
<BlockSlot @name="selected"> |
||||
<span> |
||||
Health Status |
||||
</span> |
||||
</BlockSlot> |
||||
<BlockSlot @name="options"> |
||||
{{#let components.Optgroup components.Option as |Optgroup Option|}} |
||||
<Option class="value-passing" @value="passing" @selected={{contains 'passing' @filter.statuses}}>Passing</Option> |
||||
<Option class="value-warning" @value="warning" @selected={{contains 'warning' @filter.statuses}}>Warning</Option> |
||||
<Option class="value-critical" @value="critical" @selected={{contains 'critical' @filter.statuses}}>Failing</Option> |
||||
<Option class="value-empty" @value="empty" @selected={{contains 'empty' @filter.statuses}}>No checks</Option> |
||||
{{/let}} |
||||
</BlockSlot> |
||||
</PopoverSelect> |
||||
{{#if (gt @sources.length 0)}} |
||||
<PopoverSelect |
||||
class="type-source" |
||||
@position="left" |
||||
@onchange={{action @onfilter.source}} |
||||
@multiple={{true}} |
||||
as |components|> |
||||
<BlockSlot @name="selected"> |
||||
<span> |
||||
Source |
||||
</span> |
||||
</BlockSlot> |
||||
<BlockSlot @name="options"> |
||||
{{#let components.Optgroup components.Option as |Optgroup Option|}} |
||||
{{#each @sources as |source|}} |
||||
<Option class={{source}} @value={{source}} @selected={{contains source @filter.sources}}>{{source}}</Option> |
||||
{{/each}} |
||||
{{/let}} |
||||
</BlockSlot> |
||||
</PopoverSelect> |
||||
{{/if}} |
||||
</div> |
||||
<div class="sort"> |
||||
<PopoverSelect |
||||
class="type-sort" |
||||
data-test-sort-control |
||||
@position="right" |
||||
@onchange={{action @onsort}} |
||||
@multiple={{false}} |
||||
as |components|> |
||||
<BlockSlot @name="selected"> |
||||
<span> |
||||
{{#let (from-entries (array |
||||
(array "Name:asc" "A to Z") |
||||
(array "Name:desc" "Z to A") |
||||
(array "Status:asc" "Unhealthy to Healthy") |
||||
(array "Status:desc" "Healthy to Unhealthy") |
||||
)) |
||||
as |selectable| |
||||
}} |
||||
{{get selectable @sort}} |
||||
{{/let}} |
||||
</span> |
||||
</BlockSlot> |
||||
<BlockSlot @name="options"> |
||||
</search.Select> |
||||
{{#if (gt @sources.length 0)}} |
||||
<search.Select |
||||
class="type-source" |
||||
@position="left" |
||||
@onchange={{action @filter.source.change}} |
||||
@multiple={{true}} |
||||
as |components|> |
||||
<BlockSlot @name="selected"> |
||||
<span> |
||||
{{t "common.search.source"}} |
||||
</span> |
||||
</BlockSlot> |
||||
<BlockSlot @name="options"> |
||||
{{#let components.Optgroup components.Option as |Optgroup Option|}} |
||||
{{#each @sources as |source|}} |
||||
<Option class={{source}} @value={{source}} @selected={{contains source @filter.source.value}}> |
||||
{{t (concat "common.brand." source)}} |
||||
</Option> |
||||
{{/each}} |
||||
{{/let}} |
||||
</BlockSlot> |
||||
</search.Select> |
||||
{{/if}} |
||||
</:filter> |
||||
<:sort as |search|> |
||||
<search.Select |
||||
class="type-sort" |
||||
data-test-sort-control |
||||
@position="right" |
||||
@onchange={{action @sort.change}} |
||||
@multiple={{false}} |
||||
@required={{true}} |
||||
as |components|> |
||||
<BlockSlot @name="selected"> |
||||
<span> |
||||
{{#let (from-entries (array |
||||
(array "Name:asc" (t "common.sort.alpha.asc")) |
||||
(array "Name:desc" (t "common.sort.alpha.desc")) |
||||
(array "Status:asc" (t "common.sort.status.asc")) |
||||
(array "Status:desc" (t "common.sort.status.desc")) |
||||
)) |
||||
as |selectable| |
||||
}} |
||||
{{get selectable @sort.value}} |
||||
{{/let}} |
||||
</span> |
||||
</BlockSlot> |
||||
<BlockSlot @name="options"> |
||||
{{#let components.Optgroup components.Option as |Optgroup Option|}} |
||||
<Optgroup @label="Health Status"> |
||||
<Option @value="Status:asc" @selected={{eq "Status:asc" @sort}}>Unhealthy to Healthy</Option> |
||||
<Option @value="Status:desc" @selected={{eq "Status:desc" @sort}}>Healthy to Unhealthy</Option> |
||||
<Optgroup @label={{t "common.consul.status"}}> |
||||
<Option @value="Status:asc" @selected={{eq "Status:asc" @sort.value}}>{{t "common.sort.status.asc"}}</Option> |
||||
<Option @value="Status:desc" @selected={{eq "Status:desc" @sort.value}}>{{t "common.sort.status.desc"}}</Option> |
||||
</Optgroup> |
||||
<Optgroup @label="Service Name"> |
||||
<Option @value="Name:asc" @selected={{eq "Name:asc" @sort}}>A to Z</Option> |
||||
<Option @value="Name:desc" @selected={{eq "Name:desc" @sort}}>Z to A</Option> |
||||
<Optgroup @label={{t "components.consul.service-instance.search-bar.sort.name.name"}}> |
||||
<Option @value="Name:asc" @selected={{eq "Name:asc" @sort.value}}>{{t "common.sort.alpha.asc"}}</Option> |
||||
<Option @value="Name:desc" @selected={{eq "Name:desc" @sort.value}}>{{t "common.sort.alpha.desc"}}</Option> |
||||
</Optgroup> |
||||
{{/let}} |
||||
</BlockSlot> |
||||
</PopoverSelect> |
||||
</div> |
||||
</form> |
||||
</BlockSlot> |
||||
</search.Select> |
||||
</:sort> |
||||
</SearchBar> |
||||
|
@ -1,135 +1,190 @@
|
||||
<form |
||||
class="consul-service-search-bar filter-bar" |
||||
<SearchBar |
||||
class="consul-service-search-bar" |
||||
...attributes |
||||
@filter={{@filter}} |
||||
> |
||||
<div class="search"> |
||||
<FreetextFilter |
||||
@onsearch={{action @onsearch}} |
||||
@value={{@search}} |
||||
@placeholder="Search" |
||||
> |
||||
<PopoverSelect |
||||
class="type-search-properties" |
||||
@position="right" |
||||
@onchange={{action @onfilter.searchproperty}} |
||||
<:status as |search|> |
||||
|
||||
{{#let |
||||
|
||||
(t (concat "components.consul.service.search-bar." search.status.key) |
||||
default=(array |
||||
(concat "common.search." search.status.key) |
||||
(concat "common.consul." search.status.key) |
||||
) |
||||
) |
||||
|
||||
(t (concat "components.consul.service.search-bar." search.status.value) |
||||
default=(array |
||||
(concat "common.search." search.status.value) |
||||
(concat "common.consul." search.status.value) |
||||
(concat "common.brand." search.status.value) |
||||
) |
||||
) |
||||
|
||||
as |key value|}} |
||||
<search.RemoveFilter |
||||
aria-label={{t "common.ui.remove" item=(concat key " " value)}} |
||||
> |
||||
<dl> |
||||
<dt>{{key}}</dt> |
||||
<dd>{{value}}</dd> |
||||
</dl> |
||||
</search.RemoveFilter> |
||||
{{/let}} |
||||
|
||||
</:status> |
||||
<:search as |search|> |
||||
<search.Search |
||||
@onsearch={{action @onsearch}} |
||||
@value={{@search}} |
||||
@placeholder={{t "common.search.search"}} |
||||
> |
||||
<search.Select |
||||
class="type-search-properties" |
||||
@position="right" |
||||
@onchange={{action @filter.searchproperty.change}} |
||||
@multiple={{true}} |
||||
@required={{true}} |
||||
as |components|> |
||||
<BlockSlot @name="selected"> |
||||
<span> |
||||
{{t "common.search.searchproperty"}} |
||||
</span> |
||||
</BlockSlot> |
||||
<BlockSlot @name="options"> |
||||
{{#let components.Optgroup components.Option as |Optgroup Option|}} |
||||
{{#each @filter.searchproperty.default as |prop|}} |
||||
<Option @value={{prop}} @selected={{contains prop @filter.searchproperty.value}}> |
||||
{{t (concat "common.consul." (lowercase prop))}} |
||||
</Option> |
||||
{{/each}} |
||||
{{/let}} |
||||
</BlockSlot> |
||||
</search.Select> |
||||
</search.Search> |
||||
</:search> |
||||
<:filter as |search|> |
||||
<search.Select |
||||
class="type-status" |
||||
@position="left" |
||||
@onchange={{action @filter.status.change}} |
||||
@multiple={{true}} |
||||
as |components|> |
||||
<BlockSlot @name="selected"> |
||||
<span> |
||||
Search across |
||||
{{t "common.consul.status"}} |
||||
</span> |
||||
</BlockSlot> |
||||
<BlockSlot @name="options"> |
||||
{{#let components.Optgroup components.Option as |Optgroup Option|}} |
||||
<Option @value="Name" @selected={{contains 'Name' @filter.searchproperties}}>Name</Option> |
||||
<Option @value="Tags" @selected={{contains 'Tags' @filter.searchproperties}}>Tags</Option> |
||||
{{#each (array "passing" "warning" "critical" "empty") as |state|}} |
||||
<Option class="value-{{state}}" @value={{state}} @selected={{contains state @filter.status.value}}> |
||||
{{t (concat "common.consul." state) |
||||
default=(array |
||||
(concat "common.search." state) |
||||
) |
||||
}} |
||||
</Option> |
||||
{{/each}} |
||||
{{/let}} |
||||
</BlockSlot> |
||||
</PopoverSelect> |
||||
</FreetextFilter> |
||||
</div> |
||||
<div class="filters"> |
||||
<PopoverSelect |
||||
class="type-status" |
||||
@position="left" |
||||
@onchange={{action @onfilter.status}} |
||||
@multiple={{true}} |
||||
as |components|> |
||||
<BlockSlot @name="selected"> |
||||
<span> |
||||
Health Status |
||||
</span> |
||||
</BlockSlot> |
||||
<BlockSlot @name="options"> |
||||
{{#let components.Optgroup components.Option as |Optgroup Option|}} |
||||
<Option class="value-passing" @value="passing" @selected={{contains 'passing' @filter.statuses}}>Passing</Option> |
||||
<Option class="value-warning" @value="warning" @selected={{contains 'warning' @filter.statuses}}>Warning</Option> |
||||
<Option class="value-critical" @value="critical" @selected={{contains 'critical' @filter.statuses}}>Failing</Option> |
||||
<Option class="value-empty" @value="empty" @selected={{contains 'empty' @filter.statuses}}>No checks</Option> |
||||
{{/let}} |
||||
</BlockSlot> |
||||
</PopoverSelect> |
||||
<PopoverSelect |
||||
@position="left" |
||||
@onchange={{action @onfilter.kind}} |
||||
@multiple={{true}} |
||||
as |components|> |
||||
<BlockSlot @name="selected"> |
||||
<span> |
||||
Service Type |
||||
</span> |
||||
</BlockSlot> |
||||
<BlockSlot @name="options"> |
||||
{{#let components.Optgroup components.Option as |Optgroup Option|}} |
||||
<Option @value="service" @selected={{contains 'service' @filter.kinds}}>Service</Option> |
||||
<Optgroup @label="Gateway"> |
||||
<Option @value="ingress-gateway" @selected={{contains 'ingress-gateway' @filter.kinds}}>Ingress Gateway</Option> |
||||
<Option @value="terminating-gateway" @selected={{contains 'terminating-gateway' @filter.kinds}}>Terminating Gateway</Option> |
||||
<Option @value="mesh-gateway" @selected={{contains 'mesh-gateway' @filter.kinds}}>Mesh Gateway</Option> |
||||
</Optgroup> |
||||
<Optgroup @label="Mesh"> |
||||
<Option @value="in-mesh" @selected={{contains 'in-mesh' @filter.kinds}}>In service mesh</Option> |
||||
<Option @value="not-in-mesh" @selected={{contains 'not-in-mesh' @filter.kinds}}>Not in service mesh</Option> |
||||
</Optgroup> |
||||
{{/let}} |
||||
</BlockSlot> |
||||
</PopoverSelect> |
||||
{{#if (gt @sources.length 0)}} |
||||
<PopoverSelect |
||||
class="type-source" |
||||
@position="left" |
||||
@onchange={{action @onfilter.source}} |
||||
@multiple={{true}} |
||||
as |components|> |
||||
<BlockSlot @name="selected"> |
||||
<span> |
||||
Source |
||||
</span> |
||||
</BlockSlot> |
||||
<BlockSlot @name="options"> |
||||
{{#let components.Optgroup components.Option as |Optgroup Option|}} |
||||
{{#each @sources as |source|}} |
||||
<Option class={{source}} @value={{source}} @selected={{contains source @filter.sources}}>{{source}}</Option> |
||||
{{/each}} |
||||
{{/let}} |
||||
</BlockSlot> |
||||
</PopoverSelect> |
||||
{{/if}} |
||||
</div> |
||||
<div class="sort"> |
||||
<PopoverSelect |
||||
class="type-sort" |
||||
data-test-sort-control |
||||
@position="right" |
||||
@onchange={{action @onsort}} |
||||
@multiple={{false}} |
||||
as |components|> |
||||
<BlockSlot @name="selected"> |
||||
<span> |
||||
{{#let (from-entries (array |
||||
(array "Name:asc" "A to Z") |
||||
(array "Name:desc" "Z to A") |
||||
(array "Status:asc" "Unhealthy to Healthy") |
||||
(array "Status:desc" "Healthy to Unhealthy") |
||||
)) |
||||
as |selectable| |
||||
}} |
||||
{{get selectable @sort}} |
||||
{{/let}} |
||||
</span> |
||||
</BlockSlot> |
||||
<BlockSlot @name="options"> |
||||
{{#let components.Optgroup components.Option as |Optgroup Option|}} |
||||
<Optgroup @label="Health Status"> |
||||
<Option @value="Status:asc" @selected={{eq "Status:asc" @sort}}>Unhealthy to Healthy</Option> |
||||
<Option @value="Status:desc" @selected={{eq "Status:desc" @sort}}>Healthy to Unhealthy</Option> |
||||
</Optgroup> |
||||
<Optgroup @label="Service Name"> |
||||
<Option @value="Name:asc" @selected={{eq "Name:asc" @sort}}>A to Z</Option> |
||||
<Option @value="Name:desc" @selected={{eq "Name:desc" @sort}}>Z to A</Option> |
||||
</Optgroup> |
||||
{{/let}} |
||||
</BlockSlot> |
||||
</PopoverSelect> |
||||
</div> |
||||
</form> |
||||
</search.Select> |
||||
<search.Select |
||||
@position="left" |
||||
@onchange={{action @filter.kind.change}} |
||||
@multiple={{true}} |
||||
as |components|> |
||||
<BlockSlot @name="selected"> |
||||
<span> |
||||
{{t "components.consul.service.search-bar.kind"}} |
||||
</span> |
||||
</BlockSlot> |
||||
<BlockSlot @name="options"> |
||||
{{#let components.Optgroup components.Option as |Optgroup Option|}} |
||||
<Option @value="service" @selected={{contains 'service' @filter.kind.value}}> |
||||
{{t "common.consul.service"}} |
||||
</Option> |
||||
<Optgroup |
||||
@label={{t "common.consul.gateway"}} |
||||
> |
||||
{{#each (array "ingress-gateway" "terminating-gateway" "mesh-gateway") as |kind|}} |
||||
<Option @value={{kind}} @selected={{contains kind @filter.kind.value}}> |
||||
{{t (concat "common.consul." kind)}} |
||||
</Option> |
||||
{{/each}} |
||||
</Optgroup> |
||||
<Optgroup |
||||
@label={{t "common.consul.mesh"}} |
||||
> |
||||
{{#each (array "in-mesh" "not-in-mesh") as |state|}} |
||||
<Option @value={{state}} @selected={{contains state @filter.kind.value}}> |
||||
{{t (concat "common.search." state)}} |
||||
</Option> |
||||
{{/each}} |
||||
</Optgroup> |
||||
{{/let}} |
||||
</BlockSlot> |
||||
</search.Select> |
||||
{{#if (gt @sources.length 0)}} |
||||
<search.Select |
||||
class="type-source" |
||||
@position="left" |
||||
@onchange={{action @filter.source.change}} |
||||
@multiple={{true}} |
||||
as |components|> |
||||
<BlockSlot @name="selected"> |
||||
<span> |
||||
{{t "common.search.source"}} |
||||
</span> |
||||
</BlockSlot> |
||||
<BlockSlot @name="options"> |
||||
{{#let components.Optgroup components.Option as |Optgroup Option|}} |
||||
{{#each @sources as |source|}} |
||||
<Option class={{source}} @value={{source}} @selected={{contains source @filter.source.value}}> |
||||
{{t (concat "common.brand." source)}} |
||||
</Option> |
||||
{{/each}} |
||||
{{/let}} |
||||
</BlockSlot> |
||||
</search.Select> |
||||
{{/if}} |
||||
</:filter> |
||||
<:sort as |search|> |
||||
<search.Select |
||||
class="type-sort" |
||||
data-test-sort-control |
||||
@position="right" |
||||
@onchange={{action @sort.change}} |
||||
@multiple={{false}} |
||||
@required={{true}} |
||||
as |components|> |
||||
<BlockSlot @name="selected"> |
||||
<span> |
||||
{{#let (from-entries (array |
||||
(array "Name:asc" (t "common.sort.alpha.asc")) |
||||
(array "Name:desc" (t "common.sort.alpha.desc")) |
||||
(array "Status:asc" (t "common.sort.status.asc")) |
||||
(array "Status:desc" (t "common.sort.status.desc")) |
||||
)) |
||||
as |selectable| |
||||
}} |
||||
{{get selectable @sort.value}} |
||||
{{/let}} |
||||
</span> |
||||
</BlockSlot> |
||||
<BlockSlot @name="options"> |
||||
{{#let components.Optgroup components.Option as |Optgroup Option|}} |
||||
<Optgroup @label={{t "common.consul.status"}}> |
||||
<Option @value="Status:asc" @selected={{eq "Status:asc" @sort.value}}>{{t "common.sort.status.asc"}}</Option> |
||||
<Option @value="Status:desc" @selected={{eq "Status:desc" @sort.value}}>{{t "common.sort.status.desc"}}</Option> |
||||
</Optgroup> |
||||
<Optgroup @label={{t "common.consul.service-name"}}> |
||||
<Option @value="Name:asc" @selected={{eq "Name:asc" @sort.value}}>{{t "common.sort.alpha.asc"}}</Option> |
||||
<Option @value="Name:desc" @selected={{eq "Name:desc" @sort.value}}>{{t "common.sort.alpha.desc"}}</Option> |
||||
</Optgroup> |
||||
{{/let}} |
||||
</BlockSlot> |
||||
</search.Select> |
||||
</:sort> |
||||
</SearchBar> |
||||
|
@ -1,83 +1,125 @@
|
||||
<form |
||||
class="consul-token-search-bar filter-bar" |
||||
<SearchBar |
||||
class="consul-token-search-bar" |
||||
...attributes |
||||
@filter={{@filter}} |
||||
> |
||||
<div class="search"> |
||||
<FreetextFilter |
||||
@onsearch={{action @onsearch}} |
||||
@value={{@search}} |
||||
@placeholder="Search" |
||||
> |
||||
<PopoverSelect |
||||
class="type-search-properties" |
||||
@position="right" |
||||
@onchange={{action @onfilter.searchproperty}} |
||||
<:status as |search|> |
||||
|
||||
{{#let |
||||
|
||||
(t (concat "components.consul.token.search-bar." search.status.key ".name") |
||||
default=(array |
||||
(concat "common.search." search.status.key) |
||||
(concat "common.consul." search.status.key) |
||||
) |
||||
) |
||||
|
||||
(t (concat "components.consul.token.search-bar." search.status.key ".options." search.status.value) |
||||
default=(array |
||||
(concat "common.search." search.status.value) |
||||
(concat "common.consul." search.status.value) |
||||
(concat "common.brand." search.status.value) |
||||
) |
||||
) |
||||
|
||||
as |key value|}} |
||||
<search.RemoveFilter |
||||
aria-label={{t "common.ui.remove" item=(concat key " " value)}} |
||||
> |
||||
<dl> |
||||
<dt>{{key}}</dt> |
||||
<dd>{{value}}</dd> |
||||
</dl> |
||||
</search.RemoveFilter> |
||||
{{/let}} |
||||
|
||||
</:status> |
||||
<:search as |search|> |
||||
<search.Search |
||||
@onsearch={{action @onsearch}} |
||||
@value={{@search}} |
||||
@placeholder={{t "common.search.search"}} |
||||
> |
||||
<search.Select |
||||
class="type-search-properties" |
||||
@position="right" |
||||
@onchange={{action @filter.searchproperty.change}} |
||||
@multiple={{true}} |
||||
@required={{true}} |
||||
as |components|> |
||||
<BlockSlot @name="selected"> |
||||
<span> |
||||
{{t "common.search.searchproperty"}} |
||||
</span> |
||||
</BlockSlot> |
||||
<BlockSlot @name="options"> |
||||
{{#let components.Optgroup components.Option as |Optgroup Option|}} |
||||
{{#each @filter.searchproperty.default as |prop|}} |
||||
<Option @value={{prop}} @selected={{contains prop @filter.searchproperty.value}}> |
||||
{{t (concat "common.consul." (lowercase prop))}} |
||||
</Option> |
||||
{{/each}} |
||||
{{/let}} |
||||
</BlockSlot> |
||||
</search.Select> |
||||
</search.Search> |
||||
</:search> |
||||
<:filter as |search|> |
||||
<search.Select |
||||
class="type-status" |
||||
@position="left" |
||||
@onchange={{action @filter.kind.change}} |
||||
@multiple={{true}} |
||||
as |components|> |
||||
<BlockSlot @name="selected"> |
||||
<span> |
||||
Search across |
||||
{{t "components.consul.token.search-bar.kind.name"}} |
||||
</span> |
||||
</BlockSlot> |
||||
<BlockSlot @name="options"> |
||||
{{#let components.Optgroup components.Option as |Optgroup Option|}} |
||||
<Option @value="AccessorID" @selected={{contains 'AccessorID' @filter.searchproperties}}>AccessorID</Option> |
||||
<Option @value="Description" @selected={{contains 'Description' @filter.searchproperties}}>Description</Option> |
||||
<Option @value="Policy" @selected={{contains 'Policy' @filter.searchproperties}}>Policy</Option> |
||||
<Option @value="Role" @selected={{contains 'Role' @filter.searchproperties}}>Role</Option> |
||||
{{#each (array "global-management" "global" "local") as |state|}} |
||||
<Option class="value-{{state}}" @value={{state}} @selected={{contains state @filter.kind.value}}> |
||||
{{t (concat "components.consul.token.search-bar.kind.options." state) |
||||
default=(array |
||||
(concat "common.search." state) |
||||
) |
||||
}} |
||||
</Option> |
||||
{{/each}} |
||||
{{/let}} |
||||
</BlockSlot> |
||||
</PopoverSelect> |
||||
</FreetextFilter> |
||||
</div> |
||||
<div class="filters"> |
||||
<PopoverSelect |
||||
@position="left" |
||||
@onchange={{action @onfilter.kind}} |
||||
@multiple={{true}} |
||||
as |components|> |
||||
<BlockSlot @name="selected"> |
||||
<span> |
||||
Type |
||||
</span> |
||||
</BlockSlot> |
||||
<BlockSlot @name="options"> |
||||
{{#let components.Optgroup components.Option as |Optgroup Option|}} |
||||
<Option @value="global-management" @selected={{contains 'global-management' @filter.kinds}}>Global Management</Option> |
||||
<Option @value="global" @selected={{contains 'global' @filter.kinds}}>Global Scope</Option> |
||||
<Option @value="local" @selected={{contains 'local' @filter.kinds}}>Local Scope</Option> |
||||
{{/let}} |
||||
</BlockSlot> |
||||
</PopoverSelect> |
||||
</div> |
||||
<div class="sort"> |
||||
<PopoverSelect |
||||
class="type-sort" |
||||
data-test-sort-control |
||||
@position="right" |
||||
@onchange={{action @onsort}} |
||||
@multiple={{false}} |
||||
as |components|> |
||||
<BlockSlot @name="selected"> |
||||
<span> |
||||
{{#let (from-entries (array |
||||
(array "CreateTime:desc" "Newest to oldest") |
||||
(array "CreateTime:asc" "Oldest to newest") |
||||
)) |
||||
as |selectable| |
||||
}} |
||||
{{get selectable @sort}} |
||||
{{/let}} |
||||
</span> |
||||
</BlockSlot> |
||||
<BlockSlot @name="options"> |
||||
{{#let components.Optgroup components.Option as |Optgroup Option|}} |
||||
<Optgroup @label="Creation"> |
||||
<Option @value="CreateTime:desc" @selected={{eq "CreateTime:desc" @sort}}>Newest to oldest</Option> |
||||
<Option @value="CreateTime:asc" @selected={{eq "CreateTime:asc" @sort}}>Oldest to newest</Option> |
||||
</search.Select> |
||||
</:filter> |
||||
<:sort as |search|> |
||||
<search.Select |
||||
class="type-sort" |
||||
data-test-sort-control |
||||
@position="right" |
||||
@onchange={{action @sort.change}} |
||||
@multiple={{false}} |
||||
@required={{true}} |
||||
as |components|> |
||||
<BlockSlot @name="selected"> |
||||
<span> |
||||
{{#let (from-entries (array |
||||
(array "CreateTime:desc" (t "common.sort.age.desc")) |
||||
(array "CreateTime:asc" (t "common.sort.age.asc")) |
||||
)) |
||||
as |selectable| |
||||
}} |
||||
{{get selectable @sort.value}} |
||||
{{/let}} |
||||
</span> |
||||
</BlockSlot> |
||||
<BlockSlot @name="options"> |
||||
{{#let components.Optgroup components.Option as |Optgroup Option|}} |
||||
<Optgroup @label={{t "common.ui.creation"}}> |
||||
<Option @value="CreateTime:desc" @selected={{eq "CreateTime:desc" @sort.value}}>{{t "common.sort.age.desc"}}</Option> |
||||
<Option @value="CreateTime:asc" @selected={{eq "CreateTime:asc" @sort.value}}>{{t "common.sort.age.asc"}}</Option> |
||||
</Optgroup> |
||||
{{/let}} |
||||
</BlockSlot> |
||||
</PopoverSelect> |
||||
</div> |
||||
</form> |
||||
{{/let}} |
||||
</BlockSlot> |
||||
</search.Select> |
||||
</:sort> |
||||
</SearchBar> |
||||
|
@ -1,63 +1,96 @@
|
||||
<form |
||||
class="consul-upstream-instance-search-bar filter-bar" |
||||
<SearchBar |
||||
class="consul-upstream-instance-search-bar" |
||||
...attributes |
||||
@filter={{@filter}} |
||||
> |
||||
<div class="search"> |
||||
<FreetextFilter |
||||
@onsearch={{action @onsearch}} |
||||
@value={{@search}} |
||||
@placeholder="Search" |
||||
> |
||||
<PopoverSelect |
||||
class="type-search-properties" |
||||
<:status as |search|> |
||||
|
||||
{{#let |
||||
|
||||
(t (concat "components.consul.upstream-instance.search-bar." search.status.key ".name") |
||||
default=(array |
||||
(concat "common.search." search.status.key) |
||||
(concat "common.consul." search.status.key) |
||||
) |
||||
) |
||||
|
||||
(t (concat "components.consul.upstream-instance.search-bar." search.status.value ".name") |
||||
default=(array |
||||
(concat "common.search." search.status.value) |
||||
(concat "common.consul." search.status.value) |
||||
(concat "common.brand." search.status.value) |
||||
) |
||||
) |
||||
|
||||
as |key value|}} |
||||
<search.RemoveFilter |
||||
aria-label={{t "common.ui.remove" item=(concat key " " value)}} |
||||
> |
||||
<dl> |
||||
<dt>{{key}}</dt> |
||||
<dd>{{value}}</dd> |
||||
</dl> |
||||
</search.RemoveFilter> |
||||
{{/let}} |
||||
|
||||
</:status> |
||||
<:search as |search|> |
||||
<search.Search |
||||
@onsearch={{action @onsearch}} |
||||
@value={{@search}} |
||||
@placeholder={{t "common.search.search"}} |
||||
> |
||||
<search.Select |
||||
class="type-search-properties" |
||||
@position="right" |
||||
@onchange={{action @filter.searchproperty.change}} |
||||
@multiple={{true}} |
||||
@required={{true}} |
||||
as |components|> |
||||
<BlockSlot @name="selected"> |
||||
<span> |
||||
{{t "common.search.searchproperty"}} |
||||
</span> |
||||
</BlockSlot> |
||||
<BlockSlot @name="options"> |
||||
{{#let components.Optgroup components.Option as |Optgroup Option|}} |
||||
{{#each @filter.searchproperty.default as |prop|}} |
||||
<Option @value={{prop}} @selected={{contains prop @filter.searchproperty.value}}> |
||||
{{t (concat "common.consul." (lowercase prop))}} |
||||
</Option> |
||||
{{/each}} |
||||
{{/let}} |
||||
</BlockSlot> |
||||
</search.Select> |
||||
</search.Search> |
||||
</:search> |
||||
<:sort as |search|> |
||||
<search.Select |
||||
class="type-sort" |
||||
data-test-sort-control |
||||
@position="right" |
||||
@onchange={{action @onfilter.searchproperty}} |
||||
@multiple={{true}} |
||||
@onchange={{action @sort.change}} |
||||
@multiple={{false}} |
||||
@required={{true}} |
||||
as |components|> |
||||
<BlockSlot @name="selected"> |
||||
<span> |
||||
Search across |
||||
{{#let (from-entries (array |
||||
(array "DestinationName:asc" (t "common.sort.alpha.asc")) |
||||
(array "DestinationName:desc" (t "common.sort.alpha.desc")) |
||||
)) |
||||
as |selectable| |
||||
}} |
||||
{{get selectable @sort.value}} |
||||
{{/let}} |
||||
</span> |
||||
</BlockSlot> |
||||
<BlockSlot @name="options"> |
||||
{{#let components.Optgroup components.Option as |Optgroup Option|}} |
||||
{{#each @searchproperties as |prop|}} |
||||
<Option @value={{prop}} @selected={{contains prop @filter.searchproperties}}>{{prop}}</Option> |
||||
{{/each}} |
||||
<Option @value="DestinationName:asc" @selected={{eq "DestinationName:asc" @sort.value}}>{{t "common.sort.alpha.asc"}}</Option> |
||||
<Option @value="DestinationName:desc" @selected={{eq "DestinationName:desc" @sort.value}}>{{t "common.sort.alpha.desc"}}</Option> |
||||
{{/let}} |
||||
</BlockSlot> |
||||
</PopoverSelect> |
||||
</FreetextFilter> |
||||
</div> |
||||
<div class="sort"> |
||||
{{#let (or @sort 'DestinationName:asc') as |sort|}} |
||||
<PopoverSelect |
||||
class="type-sort" |
||||
data-test-sort-control |
||||
@position="right" |
||||
@onchange={{action @onsort}} |
||||
@multiple={{false}} |
||||
as |components|> |
||||
<BlockSlot @name="selected"> |
||||
<span> |
||||
{{#let (from-entries (array |
||||
(array "DestinationName:asc" "A to Z") |
||||
(array "DestinationName:desc" "Z to A") |
||||
)) |
||||
as |selectable|}} |
||||
{{get selectable sort}} |
||||
{{/let}} |
||||
</span> |
||||
</BlockSlot> |
||||
<BlockSlot @name="options"> |
||||
{{#let components.Optgroup components.Option as |Optgroup Option|}} |
||||
<Optgroup @label="Service Name"> |
||||
<Option @value="DestinationName:asc" @selected={{eq "DestinationName:asc" sort}}>A to Z</Option> |
||||
<Option @value="DestinationName:desc" @selected={{eq "DestinationName:desc" sort}}>Z to A</Option> |
||||
</Optgroup> |
||||
{{/let}} |
||||
</BlockSlot> |
||||
</PopoverSelect> |
||||
{{/let}} |
||||
</div> |
||||
</form> |
||||
</search.Select> |
||||
</:sort> |
||||
</SearchBar> |
||||
|
@ -1,86 +1,126 @@
|
||||
<form |
||||
class="consul-upstream-search-bar filter-bar" |
||||
<SearchBar |
||||
class="consul-upstream-search-bar" |
||||
...attributes |
||||
@filter={{@filter}} |
||||
> |
||||
<div class="search"> |
||||
<FreetextFilter |
||||
@onsearch={{action @onsearch}} |
||||
@value={{@search}} |
||||
@placeholder="Search" |
||||
> |
||||
<PopoverSelect |
||||
class="type-search-properties" |
||||
@position="right" |
||||
@onchange={{action @onfilter.searchproperty}} |
||||
<:status as |search|> |
||||
|
||||
{{#let |
||||
|
||||
(t (concat "components.consul.upstream.search-bar." search.status.key ".name") |
||||
default=(array |
||||
(concat "common.search." search.status.key) |
||||
(concat "common.consul." search.status.key) |
||||
) |
||||
) |
||||
|
||||
(t (concat "components.consul.upstream.search-bar." search.status.value ".name") |
||||
default=(array |
||||
(concat "common.search." search.status.value) |
||||
(concat "common.consul." search.status.value) |
||||
(concat "common.brand." search.status.value) |
||||
) |
||||
) |
||||
|
||||
as |key value|}} |
||||
<search.RemoveFilter |
||||
aria-label={{t "common.ui.remove" item=(concat key " " value)}} |
||||
> |
||||
<dl> |
||||
<dt>{{key}}</dt> |
||||
<dd>{{value}}</dd> |
||||
</dl> |
||||
</search.RemoveFilter> |
||||
{{/let}} |
||||
|
||||
</:status> |
||||
<:search as |search|> |
||||
<search.Search |
||||
@onsearch={{action @onsearch}} |
||||
@value={{@search}} |
||||
@placeholder={{t "common.search.search"}} |
||||
> |
||||
<search.Select |
||||
class="type-search-properties" |
||||
@position="right" |
||||
@onchange={{action @filter.searchproperty.change}} |
||||
@multiple={{true}} |
||||
@required={{true}} |
||||
as |components|> |
||||
<BlockSlot @name="selected"> |
||||
<span> |
||||
{{t "common.search.searchproperty"}} |
||||
</span> |
||||
</BlockSlot> |
||||
<BlockSlot @name="options"> |
||||
{{#let components.Optgroup components.Option as |Optgroup Option|}} |
||||
{{#each @filter.searchproperty.default as |prop|}} |
||||
<Option @value={{prop}} @selected={{contains prop @filter.searchproperty.value}}> |
||||
{{t (concat "common.consul." (lowercase prop))}} |
||||
</Option> |
||||
{{/each}} |
||||
{{/let}} |
||||
</BlockSlot> |
||||
</search.Select> |
||||
</search.Search> |
||||
</:search> |
||||
<:filter as |search|> |
||||
<search.Select |
||||
@position="left" |
||||
@onchange={{action @filter.instance.change}} |
||||
@multiple={{true}} |
||||
as |components|> |
||||
<BlockSlot @name="selected"> |
||||
<span> |
||||
Search across |
||||
{{t "components.consul.upstream.search-bar.instance.name"}} |
||||
</span> |
||||
</BlockSlot> |
||||
<BlockSlot @name="options"> |
||||
{{#let components.Optgroup components.Option as |Optgroup Option|}} |
||||
<Option @value="Name" @selected={{contains 'Name' @filter.searchproperties}}>Name</Option> |
||||
<Option @value="Tags" @selected={{contains 'Tags' @filter.searchproperties}}>Tags</Option> |
||||
{{#each (array "registered" "not-registered") as |item|}} |
||||
<Option @value={{item}} @selected={{contains item @filter.instance.value}}> |
||||
{{t (concat "common.consul." item)}} |
||||
</Option> |
||||
{{/each}} |
||||
{{/let}} |
||||
</BlockSlot> |
||||
</PopoverSelect> |
||||
</FreetextFilter> |
||||
</div> |
||||
<div class="filters"> |
||||
<PopoverSelect |
||||
@position="left" |
||||
@onchange={{action @onfilter.instance}} |
||||
@multiple={{true}} |
||||
as |components|> |
||||
<BlockSlot @name="selected"> |
||||
<span> |
||||
Type |
||||
</span> |
||||
</BlockSlot> |
||||
<BlockSlot @name="options"> |
||||
{{#let components.Optgroup components.Option as |Optgroup Option|}} |
||||
<Option @value="registered" @selected={{contains 'registered' @filter.instances}}>Registered</Option> |
||||
<Option @value="not-registered" @selected={{contains 'not-registered' @filter.instances}}>Not Registered</Option> |
||||
{{/let}} |
||||
</BlockSlot> |
||||
</PopoverSelect> |
||||
</div> |
||||
<div class="sort"> |
||||
<PopoverSelect |
||||
class="type-sort" |
||||
data-test-sort-control |
||||
@position="right" |
||||
@onchange={{action @onsort}} |
||||
@multiple={{false}} |
||||
as |components|> |
||||
<BlockSlot @name="selected"> |
||||
<span> |
||||
{{#let (from-entries (array |
||||
(array "Name:asc" "A to Z") |
||||
(array "Name:desc" "Z to A") |
||||
(array "Status:asc" "Unhealthy to Healthy") |
||||
(array "Status:desc" "Healthy to Unhealthy") |
||||
)) |
||||
as |selectable| |
||||
}} |
||||
{{get selectable @sort}} |
||||
{{/let}} |
||||
</span> |
||||
</BlockSlot> |
||||
<BlockSlot @name="options"> |
||||
{{#let components.Optgroup components.Option as |Optgroup Option|}} |
||||
<Optgroup @label="Health Status"> |
||||
<Option @value="Status:asc" @selected={{eq "Status:asc" @sort}}>Unhealthy to Healthy</Option> |
||||
<Option @value="Status:desc" @selected={{eq "Status:desc" @sort}}>Healthy to Unhealthy</Option> |
||||
</Optgroup> |
||||
<Optgroup @label="Service Name"> |
||||
<Option @value="Name:asc" @selected={{eq "Name:asc" @sort}}>A to Z</Option> |
||||
<Option @value="Name:desc" @selected={{eq "Name:desc" @sort}}>Z to A</Option> |
||||
</Optgroup> |
||||
{{/let}} |
||||
</BlockSlot> |
||||
</PopoverSelect> |
||||
</div> |
||||
</form> |
||||
</search.Select> |
||||
</:filter> |
||||
<:sort as |search|> |
||||
<search.Select |
||||
class="type-sort" |
||||
data-test-sort-control |
||||
@position="right" |
||||
@onchange={{action @sort.change}} |
||||
@multiple={{false}} |
||||
@required={{true}} |
||||
as |components|> |
||||
<BlockSlot @name="selected"> |
||||
<span> |
||||
{{#let (from-entries (array |
||||
(array "Name:asc" (t "common.sort.alpha.asc")) |
||||
(array "Name:desc" (t "common.sort.alpha.desc")) |
||||
(array "Status:asc" (t "common.sort.status.asc")) |
||||
(array "Status:desc" (t "common.sort.status.desc")) |
||||
)) |
||||
as |selectable| |
||||
}} |
||||
{{get selectable @sort.value}} |
||||
{{/let}} |
||||
</span> |
||||
</BlockSlot> |
||||
<BlockSlot @name="options"> |
||||
{{#let components.Optgroup components.Option as |Optgroup Option|}} |
||||
<Optgroup @label={{t "common.consul.status"}}> |
||||
<Option @value="Status:asc" @selected={{eq "Status:asc" @sort.value}}>{{t "common.sort.status.asc"}}</Option> |
||||
<Option @value="Status:desc" @selected={{eq "Status:desc" @sort.value}}>{{t "common.sort.status.desc"}}</Option> |
||||
</Optgroup> |
||||
<Optgroup @label={{t "common.consul.service-name"}}> |
||||
<Option @value="Name:asc" @selected={{eq "Name:asc" @sort.value}}>{{t "common.sort.alpha.asc"}}</Option> |
||||
<Option @value="Name:desc" @selected={{eq "Name:desc" @sort.value}}>{{t "common.sort.alpha.desc"}}</Option> |
||||
</Optgroup> |
||||
{{/let}} |
||||
</BlockSlot> |
||||
</search.Select> |
||||
</:sort> |
||||
</SearchBar> |
||||
|
@ -1,7 +1,7 @@
|
||||
{{#let components.MenuSeparator as |MenuSeparator|}} |
||||
{{#let @components.MenuSeparator as |MenuSeparator|}} |
||||
<MenuSeparator> |
||||
<BlockSlot @name="label"> |
||||
{{label}} |
||||
{{@label}} |
||||
</BlockSlot> |
||||
</MenuSeparator> |
||||
{{yield}} |
||||
|
@ -1,5 +0,0 @@
|
||||
import Component from '@ember/component'; |
||||
|
||||
export default Component.extend({ |
||||
tagName: '', |
||||
}); |
@ -1,20 +1,16 @@
|
||||
import Component from '@ember/component'; |
||||
import { inject as service } from '@ember/service'; |
||||
import Component from '@glimmer/component'; |
||||
import { tracked } from '@glimmer/tracking'; |
||||
import { action } from '@ember/object'; |
||||
|
||||
export default Component.extend({ |
||||
tagName: '', |
||||
dom: service('dom'), |
||||
didInsertElement: function() { |
||||
this._super(...arguments); |
||||
this.select.addOption(this); |
||||
}, |
||||
willDestroyElement: function() { |
||||
this._super(...arguments); |
||||
this.select.removeOption(this); |
||||
}, |
||||
actions: { |
||||
click: function(e) { |
||||
this.onclick(e, this.value); |
||||
}, |
||||
}, |
||||
}); |
||||
export default class Option extends Component { |
||||
@tracked selected; |
||||
|
||||
@action |
||||
connect() { |
||||
this.args.select.addOption(this); |
||||
} |
||||
@action |
||||
disconnect() { |
||||
this.args.select.removeOption(this); |
||||
} |
||||
} |
||||
|
@ -1,61 +0,0 @@
|
||||
## SearchBar |
||||
|
||||
```handlebars |
||||
<SearchBar |
||||
@value={{"search term"}} |
||||
@onsearch={{action "search"}} |
||||
/> |
||||
``` |
||||
|
||||
### Arguments |
||||
|
||||
| Argument | Type | Default | Description | |
||||
| --- | --- | --- | --- | |
||||
| `value` | `String` | | The string `value` of the freetext search bar | |
||||
| `onsearch` | `Function` | | The action to fire when the freetext search bar changes. Emits a native event with a `target.value` property containing the text typed into the search bar | |
||||
| `options` | `Array` | | An array of Key/Values pairs to use for options for either a filter interface or a sort interface | |
||||
| `selected` | `Object` | | An object containing a Key/Value pair of the currently selected option | |
||||
| `onchange` | `Function` | | The action to fire when the filter/sort changes. Emits an Event-like object, when filtering this has a `target.value` property containg the key of the selected filter, when sorting this has a `target.selected` property containing the selected Key/Value pair | |
||||
| `secondary` | `string` | | String identifier to signify what type of secondary filter to show. Currently only value here is 'sort' | |
||||
|
||||
`SearchBar` is used for a variety of searching behaviours, freetext searching, filtering and sorting. It is also slot based to enable you to completely overwrite the secondary search if need be. |
||||
|
||||
### Examples |
||||
|
||||
```handlebars |
||||
{{! Freetext only search bar}} |
||||
<SearchBar |
||||
@value={{"search term"}} |
||||
@onsearch={{action "search"}} |
||||
/> |
||||
``` |
||||
|
||||
```handlebars |
||||
{{! Freetext and filter search bar}} |
||||
<SearchBar |
||||
@value={{search}} |
||||
@onsearch={{action (mut search) value='target.value'}} |
||||
@selected={{filter.selected}} |
||||
@options={{filter.items}} |
||||
@onchange={{action (mut filterBy) value='target.value'}} |
||||
/> |
||||
``` |
||||
|
||||
```handlebars |
||||
{{! Freetext and sort search bar}} |
||||
<SearchBar |
||||
@value={{search}} |
||||
@onsearch={{action (mut search) value='target.value'}} |
||||
@secondary="sort" |
||||
@selected={{sort.selected}} |
||||
@options={{sort.items}} |
||||
@onchange={{action (mut sortBy) value='target.selected.key'}} |
||||
/> |
||||
``` |
||||
|
||||
### See |
||||
|
||||
- [Component Source Code](./index.js) |
||||
- [Template Source Code](./index.hbs) |
||||
|
||||
--- |
@ -1,31 +1,68 @@
|
||||
{{yield}} |
||||
<form class={{concat 'filter-bar' (if (eq secondary 'sort') ' with-sort')}} ...attributes> |
||||
{{#yield-slot name="primary"}} |
||||
<fieldset> |
||||
{{yield}} |
||||
</fieldset> |
||||
{{else}} |
||||
<FreetextFilter |
||||
@onsearch={{action onsearch}} |
||||
@value={{value}} |
||||
@placeholder={{or placeholder 'Search'}} |
||||
/> |
||||
{{/yield-slot}} |
||||
{{#yield-slot name="secondary"}} |
||||
<fieldset> |
||||
{{yield}} |
||||
</fieldset> |
||||
{{else}} |
||||
{{#if options}} |
||||
{{#if (eq secondary 'sort')}} |
||||
{{else}} |
||||
<RadioGroup |
||||
@keyboardAccess={{true}} |
||||
@value={{selected.key}} |
||||
@items={{options}} |
||||
@onchange={{action onchange}} |
||||
/> |
||||
{{/if}} |
||||
{{/if}} |
||||
{{/yield-slot}} |
||||
</form> |
||||
<div |
||||
class="search-bar" |
||||
...attributes |
||||
> |
||||
<form |
||||
class="filter-bar" |
||||
> |
||||
<div class="search"> |
||||
{{yield (hash |
||||
Search=(component "freetext-filter") |
||||
Select=(component "popover-select") |
||||
) to="search"}} |
||||
</div> |
||||
<div class="filters"> |
||||
{{yield (hash |
||||
Search=(component "freetext-filter") |
||||
Select=(component "popover-select") |
||||
) to="filter"}} |
||||
</div> |
||||
<div class="sort"> |
||||
{{yield (hash |
||||
Search=(component "freetext-filter") |
||||
Select=(component "popover-select") |
||||
) to="sort"}} |
||||
</div> |
||||
</form> |
||||
{{#if this.isFiltered}} |
||||
<div class="search-bar-status"> |
||||
<dl> |
||||
<dt>{{string-trim |
||||
(t "component.search-bar.header" |
||||
default="common.ui.filtered-by" |
||||
item="" |
||||
) |
||||
}}</dt> |
||||
<dd> |
||||
<ul> |
||||
{{#each this.filters as |filter|}} |
||||
{{yield (hash |
||||
RemoveFilter=(component "search-bar/remove-filter" onclick=(action |
||||
(get (get @filter filter.key) "change") |
||||
(hash |
||||
target=(hash |
||||
selectedItems=(join filter.selected ',') |
||||
) |
||||
)) |
||||
) |
||||
status=(hash |
||||
key=filter.key |
||||
value=(lowercase filter.value) |
||||
) |
||||
) |
||||
to="status" |
||||
}} |
||||
{{/each}} |
||||
<li class="remove-all"> |
||||
<Action |
||||
{{on "click" this.removeAllFilters}} |
||||
> |
||||
Remove filters |
||||
</Action> |
||||
</li> |
||||
</ul> |
||||
</dd> |
||||
</dl> |
||||
</div> |
||||
{{/if}} |
||||
</div> |
||||
|
@ -1,6 +1,34 @@
|
||||
import Component from '@ember/component'; |
||||
import Slotted from 'block-slots'; |
||||
import Component from '@glimmer/component'; |
||||
import { action } from '@ember/object'; |
||||
import { diff, filters } from './utils'; |
||||
|
||||
export default Component.extend(Slotted, { |
||||
tagName: '', |
||||
}); |
||||
export default class SearchBar extends Component { |
||||
// only show the filter status bar if we have searchproperty filters or
|
||||
// normal types of filters, and we are currently filtering by either of those
|
||||
get isFiltered() { |
||||
const searchproperty = this.args.filter.searchproperty || { default: [], value: [] }; |
||||
return ( |
||||
diff(searchproperty.default, searchproperty.value).length > 0 || |
||||
Object.entries(this.args.filter).some(([key, value]) => { |
||||
return key !== 'searchproperty' && typeof value.value !== 'undefined'; |
||||
}) |
||||
); |
||||
} |
||||
|
||||
// convert the object based filters to an array of iterable filters ready for
|
||||
// rendering
|
||||
get filters() { |
||||
return filters(this.args.filter); |
||||
} |
||||
|
||||
@action |
||||
removeAllFilters() { |
||||
Object.values(this.args.filter).forEach((value, i) => { |
||||
// put in a little queue to ensure query params are unset properly
|
||||
// ideally this would be done outside of the component
|
||||
// TODO: Look to see if this can be moved to serializeQueryParam
|
||||
// so we we aren't polluting components with queryParam related things
|
||||
setTimeout(() => value.change(value.default || []), 1 * i); |
||||
}); |
||||
} |
||||
} |
||||
|
@ -0,0 +1,60 @@
|
||||
.search-bar { |
||||
&-status { |
||||
& { |
||||
border-bottom: $decor-border-100; |
||||
border-bottom-color: $gray-200; |
||||
} |
||||
.remove-all button { |
||||
@extend %anchor; |
||||
} |
||||
li:not(.remove-all) { |
||||
& { |
||||
@extend %pill-200; |
||||
border: $decor-border-100; |
||||
border-color: $gray-200; |
||||
color: $gray-600; |
||||
} |
||||
button { |
||||
cursor: pointer; |
||||
} |
||||
button::before { |
||||
@extend %with-cancel-plain-mask, %as-pseudo; |
||||
color: $gray-600; |
||||
margin-top: 1px; |
||||
margin-right: 0.2rem; |
||||
} |
||||
} |
||||
& { |
||||
padding: .5rem 0; |
||||
padding-left: .5rem; |
||||
} |
||||
dt::after { |
||||
content: ':'; |
||||
padding-right: 0.3rem; |
||||
} |
||||
& > dl > dt { |
||||
float: left; |
||||
} |
||||
dt { |
||||
white-space: nowrap; |
||||
} |
||||
li { |
||||
display: inline-flex; |
||||
} |
||||
li:not(:last-child) { |
||||
margin-right: 0.3rem; |
||||
margin-bottom: 0.3rem; |
||||
} |
||||
li:not(.remove-all) { |
||||
& { |
||||
padding: 0 0.2rem; |
||||
} |
||||
dl { |
||||
display: flex; |
||||
} |
||||
button { |
||||
padding: 0; |
||||
} |
||||
} |
||||
} |
||||
} |
@ -1,7 +0,0 @@
|
||||
export default (search, secondary = () => {}) => scope => { |
||||
return { |
||||
scope: scope, |
||||
...search(), |
||||
...secondary(), |
||||
}; |
||||
}; |
@ -0,0 +1,7 @@
|
||||
<li> |
||||
<Action |
||||
...attributes |
||||
{{on 'click' @onclick}} |
||||
/> |
||||
{{yield}} |
||||
</li> |
@ -0,0 +1,38 @@
|
||||
export const diff = (a, b) => { |
||||
return a.filter(item => !b.includes(item)); |
||||
}; |
||||
/** |
||||
* filters accepts the args.filter @attribute which is shaped like |
||||
* {filterName: {default: ['Node', 'Address'], value: ['Address']}, ...} |
||||
* It will turn this into an array of 'filters' shaped like |
||||
* [{key: 'filterName', value: 'Address', selected: ["Node"]}] |
||||
* importantly 'selected' isn't what is currently 'selected' it is what selected |
||||
* will be once you remove this filter |
||||
* There is more explanation in the unit tests for this function so thats worthwhile |
||||
* checking if you are in amongst this |
||||
*/ |
||||
export const filters = filters => { |
||||
return Object.entries(filters) |
||||
.filter(([key, value]) => { |
||||
if (key === 'searchproperty') { |
||||
return diff(value.default, value.value).length > 0; |
||||
} |
||||
return (value.value || []).length > 0; |
||||
}) |
||||
.reduce((prev, [key, value]) => { |
||||
return prev.concat( |
||||
value.value.map(item => { |
||||
const obj = { |
||||
key: key, |
||||
value: item, |
||||
}; |
||||
if (key !== 'searchproperty') { |
||||
obj.selected = diff(value.value, [item]); |
||||
} else { |
||||
obj.selected = value.value.length === 1 ? value.default : diff(value.value, [item]); |
||||
} |
||||
return obj; |
||||
}) |
||||
); |
||||
}, []); |
||||
}; |
@ -1,12 +1,13 @@
|
||||
import setHelpers from 'mnemonist/set'; |
||||
|
||||
export default { |
||||
statuses: { |
||||
status: { |
||||
passing: (item, value) => item.Status === value, |
||||
warning: (item, value) => item.Status === value, |
||||
critical: (item, value) => item.Status === value, |
||||
empty: (item, value) => item.MeshChecks.length === 0, |
||||
}, |
||||
sources: (item, values) => { |
||||
source: (item, values) => { |
||||
return setHelpers.intersectionSize(values, new Set(item.ExternalSources || [])) !== 0; |
||||
}, |
||||
}; |
||||
|
@ -1,83 +1,93 @@
|
||||
{{page-title 'ACLs'}} |
||||
{{#let (hash |
||||
kinds=(if kind (split kind ',') undefined) |
||||
) as |filters|}} |
||||
{{#let (or sortBy "Name:asc") as |sort|}} |
||||
<AppView> |
||||
<BlockSlot @name="notification" as |status type item error|> |
||||
<Consul::Acl::Notifications |
||||
@status={{status}} |
||||
@type={{type}} |
||||
@error={{error}} |
||||
/> |
||||
</BlockSlot> |
||||
<BlockSlot @name="header"> |
||||
<h1> |
||||
ACL Tokens <em>{{format-number items.length}} total</em> |
||||
</h1> |
||||
<label for="toolbar-toggle"></label> |
||||
</BlockSlot> |
||||
<BlockSlot @name="actions"> |
||||
<a data-test-create href="{{href-to 'dc.acls.create'}}" class="type-create">Create</a> |
||||
</BlockSlot> |
||||
<BlockSlot @name="toolbar"> |
||||
{{#if (gt items.length 0) }} |
||||
<Consul::Acl::SearchBar |
||||
@search={{search}} |
||||
@onsearch={{action (mut search) value="target.value"}} |
||||
{{#let |
||||
|
||||
(hash |
||||
value=(or sortBy "Name:asc") |
||||
change=(action (mut sortBy) value="target.selected") |
||||
) |
||||
|
||||
(hash |
||||
kind=(hash |
||||
value=(if kind (split kind ',') undefined) |
||||
change=(action (mut kind) value="target.selectedItems") |
||||
) |
||||
) |
||||
|
||||
items |
||||
|
||||
@sort={{sort}} |
||||
@onsort={{action (mut sortBy) value="target.selected"}} |
||||
as |sort filters items|}} |
||||
|
||||
@filter={{filters}} |
||||
@onfilter={{hash |
||||
kind=(action (mut kind) value="target.selectedItems") |
||||
}} |
||||
<AppView> |
||||
<BlockSlot @name="notification" as |status type item error|> |
||||
<Consul::Acl::Notifications |
||||
@status={{status}} |
||||
@type={{type}} |
||||
@error={{error}} |
||||
/> |
||||
{{/if}} |
||||
</BlockSlot> |
||||
<BlockSlot @name="content"> |
||||
<DataCollection |
||||
@type="acl" |
||||
@sort={{sort}} |
||||
@filters={{filters}} |
||||
@search={{search}} |
||||
@items={{items}} |
||||
as |collection|> |
||||
<collection.Collection> |
||||
<Consul::Acl::List |
||||
@items={{collection.items}} |
||||
</BlockSlot> |
||||
<BlockSlot @name="header"> |
||||
<h1> |
||||
ACL Tokens <em>{{format-number items.length}} total</em> |
||||
</h1> |
||||
<label for="toolbar-toggle"></label> |
||||
</BlockSlot> |
||||
<BlockSlot @name="actions"> |
||||
<a data-test-create href="{{href-to 'dc.acls.create'}}" class="type-create">Create</a> |
||||
</BlockSlot> |
||||
<BlockSlot @name="toolbar"> |
||||
{{#if (gt items.length 0) }} |
||||
<Consul::Acl::SearchBar |
||||
@search={{search}} |
||||
@onsearch={{action (mut search) value="target.value"}} |
||||
|
||||
@sort={{sort}} |
||||
|
||||
@filter={{filters}} |
||||
/> |
||||
{{/if}} |
||||
</BlockSlot> |
||||
<BlockSlot @name="content"> |
||||
<DataCollection |
||||
@type="acl" |
||||
@sort={{sort.value}} |
||||
@filters={{filters}} |
||||
@search={{search}} |
||||
@items={{items}} |
||||
as |collection|> |
||||
<collection.Collection> |
||||
<Consul::Acl::List |
||||
@items={{collection.items}} |
||||
|
||||
@ondelete={{route-action 'delete'}} |
||||
@onuse={{route-action 'use'}} |
||||
@onclone={{route-action 'clone'}} |
||||
> |
||||
</Consul::Acl::List> |
||||
</collection.Collection> |
||||
<collection.Empty> |
||||
<EmptyState @allowLogin={{true}}> |
||||
<BlockSlot @name="header"> |
||||
<h2> |
||||
{{#if (gt items.length 0)}} |
||||
No ACLs found |
||||
{{else}} |
||||
Welcome to ACLs |
||||
{{/if}} |
||||
</h2> |
||||
</BlockSlot> |
||||
<BlockSlot @name="body"> |
||||
<p> |
||||
{{#if (gt items.length 0)}} |
||||
No ACLs where found matching that search, or you may not have access to view the ACLs you are searching for. |
||||
{{else}} |
||||
There don't seem to be any ACLs yet, or you may not have access to view ACLs yet. |
||||
{{/if}} |
||||
</p> |
||||
</BlockSlot> |
||||
</EmptyState> |
||||
</collection.Empty> |
||||
</DataCollection> |
||||
</BlockSlot> |
||||
</AppView> |
||||
|
||||
@ondelete={{route-action 'delete'}} |
||||
@onuse={{route-action 'use'}} |
||||
@onclone={{route-action 'clone'}} |
||||
> |
||||
</Consul::Acl::List> |
||||
</collection.Collection> |
||||
<collection.Empty> |
||||
<EmptyState @allowLogin={{true}}> |
||||
<BlockSlot @name="header"> |
||||
<h2> |
||||
{{#if (gt items.length 0)}} |
||||
No ACLs found |
||||
{{else}} |
||||
Welcome to ACLs |
||||
{{/if}} |
||||
</h2> |
||||
</BlockSlot> |
||||
<BlockSlot @name="body"> |
||||
<p> |
||||
{{#if (gt items.length 0)}} |
||||
No ACLs where found matching that search, or you may not have access to view the ACLs you are searching for. |
||||
{{else}} |
||||
There don't seem to be any ACLs yet, or you may not have access to view ACLs yet. |
||||
{{/if}} |
||||
</p> |
||||
</BlockSlot> |
||||
</EmptyState> |
||||
</collection.Empty> |
||||
</DataCollection> |
||||
</BlockSlot> |
||||
</AppView> |
||||
{{/let}} |
||||
{{/let}} |
||||
|
@ -0,0 +1,9 @@
|
||||
// if we can't find the message, take the last part of the identifier and
|
||||
// ucfirst it so it looks human
|
||||
export default function missingMessage(key, locales) { |
||||
const last = key |
||||
.split('.') |
||||
.pop() |
||||
.replaceAll('-', ' '); |
||||
return `${last.substr(0, 1).toUpperCase()}${last.substr(1)}`; |
||||
} |
@ -1,24 +0,0 @@
|
||||
import { module, test } from 'qunit'; |
||||
import { setupRenderingTest } from 'ember-qunit'; |
||||
import { render } from '@ember/test-helpers'; |
||||
import { hbs } from 'ember-cli-htmlbars'; |
||||
|
||||
module('Integration | Component | search-bar', function(hooks) { |
||||
setupRenderingTest(hooks); |
||||
|
||||
test('it renders', async function(assert) { |
||||
// Set any properties with this.set('myProperty', 'value');
|
||||
this.set('search', function(e) {}); |
||||
|
||||
await render(hbs`<SearchBar @onsearch={{action search}}/>`); |
||||
|
||||
assert.equal(this.element.textContent.trim(), 'Search'); |
||||
|
||||
// Template block usage:
|
||||
await render(hbs` |
||||
<SearchBar @onsearch={{action search}}></SearchBar> |
||||
`);
|
||||
|
||||
assert.equal(this.element.textContent.trim(), 'Search'); |
||||
}); |
||||
}); |
@ -0,0 +1,154 @@
|
||||
import { filters } from 'consul-ui/components/search-bar/utils'; |
||||
import { module, test } from 'qunit'; |
||||
|
||||
module('Unit | Component | search-bar/filters', function() { |
||||
test('it correctly reshapes the filter data', function(assert) { |
||||
[ |
||||
// basic filter, returns a single filter button when clicked
|
||||
// resets selected/queryparam to empty
|
||||
{ |
||||
filters: { |
||||
status: { |
||||
value: ['passing'], |
||||
}, |
||||
}, |
||||
expected: [ |
||||
{ |
||||
key: 'status', |
||||
value: 'passing', |
||||
selected: [], |
||||
}, |
||||
], |
||||
}, |
||||
// basic filters, returns multiple filter button when clicked
|
||||
// sets selected/queryparam to the left over single filter
|
||||
{ |
||||
filters: { |
||||
status: { |
||||
value: ['passing', 'warning'], |
||||
}, |
||||
}, |
||||
expected: [ |
||||
{ |
||||
key: 'status', |
||||
value: 'passing', |
||||
selected: ['warning'], |
||||
}, |
||||
{ |
||||
key: 'status', |
||||
value: 'warning', |
||||
selected: ['passing'], |
||||
}, |
||||
], |
||||
}, |
||||
// basic filters, returns multiple filter button when clicked
|
||||
// sets selected/queryparam to the left over multiple filters
|
||||
{ |
||||
filters: { |
||||
status: { |
||||
value: ['passing', 'warning', 'critical'], |
||||
}, |
||||
}, |
||||
expected: [ |
||||
{ |
||||
key: 'status', |
||||
value: 'passing', |
||||
selected: ['warning', 'critical'], |
||||
}, |
||||
{ |
||||
key: 'status', |
||||
value: 'warning', |
||||
selected: ['passing', 'critical'], |
||||
}, |
||||
{ |
||||
key: 'status', |
||||
value: 'critical', |
||||
selected: ['passing', 'warning'], |
||||
}, |
||||
], |
||||
}, |
||||
// basic filters, returns multiple filter button when clicked
|
||||
// sets selected/queryparam to the left over multiple filters
|
||||
// also search property multiple filter, sets the selected/queryparam to
|
||||
// the left of single searchproperty filter
|
||||
{ |
||||
filters: { |
||||
status: { |
||||
value: ['passing', 'warning', 'critical'], |
||||
}, |
||||
searchproperties: { |
||||
default: ['Node', 'Address', 'Meta'], |
||||
value: ['Node', 'Address'], |
||||
}, |
||||
}, |
||||
expected: [ |
||||
{ |
||||
key: 'status', |
||||
value: 'passing', |
||||
selected: ['warning', 'critical'], |
||||
}, |
||||
{ |
||||
key: 'status', |
||||
value: 'warning', |
||||
selected: ['passing', 'critical'], |
||||
}, |
||||
{ |
||||
key: 'status', |
||||
value: 'critical', |
||||
selected: ['passing', 'warning'], |
||||
}, |
||||
{ |
||||
key: 'searchproperties', |
||||
value: 'Node', |
||||
selected: ['Address'], |
||||
}, |
||||
{ |
||||
key: 'searchproperties', |
||||
value: 'Address', |
||||
selected: ['Node'], |
||||
}, |
||||
], |
||||
}, |
||||
// basic filters, returns multiple filter button when clicked
|
||||
// sets selected/queryparam to the left over multiple filters
|
||||
// also search property single filter, resets the selected/queryparam to
|
||||
// empty
|
||||
{ |
||||
filters: { |
||||
status: { |
||||
value: ['passing', 'warning', 'critical'], |
||||
}, |
||||
searchproperties: { |
||||
default: ['Node', 'Address', 'Meta'], |
||||
value: ['Node'], |
||||
}, |
||||
}, |
||||
expected: [ |
||||
{ |
||||
key: 'status', |
||||
value: 'passing', |
||||
selected: ['warning', 'critical'], |
||||
}, |
||||
{ |
||||
key: 'status', |
||||
value: 'warning', |
||||
selected: ['passing', 'critical'], |
||||
}, |
||||
{ |
||||
key: 'status', |
||||
value: 'critical', |
||||
selected: ['passing', 'warning'], |
||||
}, |
||||
{ |
||||
key: 'searchproperties', |
||||
value: 'Node', |
||||
selected: [], |
||||
}, |
||||
], |
||||
}, |
||||
].forEach(item => { |
||||
const actual = filters(item.filters); |
||||
assert.deepEqual(actual, item.expected); |
||||
}); |
||||
}); |
||||
}); |
@ -1 +1,158 @@
|
||||
common: |
||||
brand: |
||||
consul: Consul |
||||
terraform: Terraform |
||||
nomad: Nomad |
||||
vault: Vault |
||||
aws: AWS |
||||
kubernetes: Kubernetes |
||||
ui: |
||||
remove: Remove {item} |
||||
filtered-by: Filtered by {item} |
||||
name: Name |
||||
creation: Creation |
||||
consul: |
||||
name: Name |
||||
passing: Passing |
||||
warning: Warning |
||||
critical: Critical |
||||
registered: Registered |
||||
not-registered: Not Registered |
||||
empty: No checks |
||||
tags: Tags |
||||
service: Service |
||||
gateway: Gateway |
||||
mesh: Mesh |
||||
ingress-gateway: Ingress Gateway |
||||
terminating-gateway: Terminating Gateway |
||||
mesh-gateway: Mesh Gateway |
||||
status: Health Status |
||||
service-name: Service Name |
||||
node-name: Node Name |
||||
accessorid: AccessorID |
||||
datacenter: Datacenter |
||||
localbindaddress: Local Bind Address |
||||
localbindport: Local Bind Port |
||||
destinationname: Destination Name |
||||
sourcename: Source Name |
||||
search: |
||||
search: Search |
||||
searchproperty: Search Across |
||||
source: Source |
||||
critical: Failing |
||||
in-mesh: In service mesh |
||||
not-in-mesh: Not in service mesh |
||||
sort: |
||||
alpha: |
||||
asc: A to Z |
||||
desc: Z to A |
||||
numeric: |
||||
asc: Ascending |
||||
desc: Descending |
||||
age: |
||||
asc: Oldest to Newest |
||||
desc: Newest to Oldest |
||||
status: |
||||
asc: Unhealthy to Healthy |
||||
desc: Healthy to Unhealthy |
||||
|
||||
components: |
||||
consul: |
||||
service: |
||||
search-bar: |
||||
kind: Service Type |
||||
in-mesh: In service mesh |
||||
not-in-mesh: Not in service mesh |
||||
upstream: |
||||
search-bar: |
||||
instance: |
||||
name: Type |
||||
service-instance: |
||||
search-bar: |
||||
sort: |
||||
name: |
||||
name: Service Name |
||||
health-check: |
||||
search-bar: |
||||
kind: |
||||
name: Kind |
||||
options: |
||||
service: Service Check |
||||
node: Node Check |
||||
check: |
||||
name: Type |
||||
options: |
||||
alias: alias |
||||
docker: docker |
||||
grpc: grpc |
||||
http: http |
||||
script: script |
||||
serf: serf |
||||
tcp: tcp |
||||
ttl: ttl |
||||
sort: |
||||
name: |
||||
name: Check Name |
||||
kind: |
||||
name: Check Type |
||||
asc: Service to Node |
||||
desc: Node to Service |
||||
acl: |
||||
search-bar: |
||||
kind: |
||||
name: Type |
||||
options: |
||||
management: Management |
||||
client: Client |
||||
token: |
||||
search-bar: |
||||
kind: |
||||
name: Type |
||||
options: |
||||
global-management: Global Management |
||||
global: Global Scope |
||||
local: Local Scope |
||||
policy: |
||||
search-bar: |
||||
kind: |
||||
name: Type |
||||
options: |
||||
global-management: Global Management |
||||
standard: Standard |
||||
kv: |
||||
search-bar: |
||||
kind: |
||||
name: Type |
||||
options: |
||||
folder: Folder |
||||
key: Key |
||||
sort: |
||||
kind: |
||||
asc: Folders to Keys |
||||
desc: Keys to Folders |
||||
intention: |
||||
search-bar: |
||||
access: |
||||
name: Permission |
||||
options: |
||||
allow: Allow |
||||
deny: Deny |
||||
app-aware: App aware |
||||
sort: |
||||
access: |
||||
name: Permission |
||||
asc: Allow to Deny |
||||
desc: Deny to Allow |
||||
source-name: |
||||
name: Source |
||||
asc: "Source: A to Z" |
||||
desc: "Source: Z to A" |
||||
destination-name: |
||||
name: Destination |
||||
asc: "Destination: A to Z" |
||||
desc: "Destination: Z to A" |
||||
precedence: |
||||
name: Precedence |
||||
asc: Ascending |
||||
desc: Descending |
||||
|
||||
|
Loading…
Reference in new issue