ui: Search/filtering 'Filtered by:' search status (#9442)
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.
This commit is contained in:
parent
e3f5a77ade
commit
148b18b28c
|
@ -0,0 +1,4 @@
|
|||
```release-note:feature
|
||||
ui: Add additional search/filter status pills for viewing and removing current
|
||||
filters in listing views
|
||||
```
|
|
@ -31,6 +31,8 @@ module.exports = {
|
|||
|
||||
'no-unnecessary-component-helper': false,
|
||||
'link-href-attributes': false,
|
||||
// we need to be able to say tabindex={{@tabindex}}
|
||||
'no-positive-tabindex': false,
|
||||
|
||||
'no-bare-strings': false,
|
||||
},
|
||||
|
|
|
@ -19,9 +19,9 @@
|
|||
{{~/if~}}
|
||||
{{~else~}}
|
||||
<button
|
||||
tabindex="-1"
|
||||
type="button"
|
||||
{{on 'click' (optional @onclick)}}
|
||||
tabindex={{@tabindex}}
|
||||
...attributes
|
||||
>{{yield}}</button>
|
||||
{{~/if}}
|
|
@ -14,6 +14,7 @@
|
|||
<YieldSlot @name="confirm" @params={{
|
||||
block-params (component 'action'
|
||||
onclick=(action @onclick)
|
||||
tabindex="-1"
|
||||
)
|
||||
}}
|
||||
>
|
||||
|
|
|
@ -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
|
||||
<: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}}
|
||||
|
||||
</:status>
|
||||
<:search as |search|>
|
||||
<search.Search
|
||||
@onsearch={{action @onsearch}}
|
||||
@value={{@search}}
|
||||
@placeholder="Search"
|
||||
/>
|
||||
</div>
|
||||
<div class="filters">
|
||||
<PopoverSelect
|
||||
@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 @onfilter.kind}}
|
||||
@onchange={{action @filter.kind.change}}
|
||||
@multiple={{true}}
|
||||
as |components|>
|
||||
<BlockSlot @name="selected">
|
||||
<span>
|
||||
Type
|
||||
{{t "components.consul.acl.search-bar.kind.name"}}
|
||||
</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>
|
||||
{{/let}}
|
||||
{{#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>
|
||||
</PopoverSelect>
|
||||
</div>
|
||||
<div class="sort">
|
||||
<PopoverSelect
|
||||
</search.Select>
|
||||
</:filter>
|
||||
<:sort as |search|>
|
||||
<search.Select
|
||||
class="type-sort"
|
||||
data-test-sort-control
|
||||
@position="right"
|
||||
@onchange={{action @onsort}}
|
||||
@onchange={{action @sort.change}}
|
||||
@multiple={{false}}
|
||||
@required={{true}}
|
||||
as |components|>
|
||||
<BlockSlot @name="selected">
|
||||
<span>
|
||||
{{#let (from-entries (array
|
||||
(array "Name:asc" "A to Z")
|
||||
(array "Name:desc" "Z to A")
|
||||
(array "Name:asc" (t "common.sort.alpha.asc"))
|
||||
(array "Name:desc" (t "common.sort.alpha.desc"))
|
||||
))
|
||||
as |selectable|
|
||||
}}
|
||||
{{get selectable @sort}}
|
||||
{{get selectable @sort.value}}
|
||||
{{/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}}
|
||||
{{#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>
|
||||
</PopoverSelect>
|
||||
</div>
|
||||
</form>
|
||||
</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
|
||||
<: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="Search"
|
||||
@placeholder={{t "common.search.search"}}
|
||||
>
|
||||
<PopoverSelect
|
||||
{{#if @filter.searchproperty}}
|
||||
<search.Select
|
||||
class="type-search-properties"
|
||||
@position="right"
|
||||
@onchange={{action @onfilter.searchproperty}}
|
||||
@onchange={{action @filter.searchproperty.change}}
|
||||
@multiple={{true}}
|
||||
@required={{true}}
|
||||
as |components|>
|
||||
<BlockSlot @name="selected">
|
||||
<span>
|
||||
Search across
|
||||
{{t "common.search.searchproperty"}}
|
||||
</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 @filter.searchproperty.default as |prop|}}
|
||||
<Option @value={{prop}} @selected={{contains prop @filter.searchproperty.value}}>
|
||||
{{t (concat "common.consul." (lowercase prop))}}
|
||||
</Option>
|
||||
{{/each}}
|
||||
{{/let}}
|
||||
</BlockSlot>
|
||||
</PopoverSelect>
|
||||
</FreetextFilter>
|
||||
</div>
|
||||
<div class="filters">
|
||||
<PopoverSelect
|
||||
</search.Select>
|
||||
{{/if}}
|
||||
</search.Search>
|
||||
</:search>
|
||||
<:filter as |search|>
|
||||
<search.Select
|
||||
class="type-status"
|
||||
@position="left"
|
||||
@onchange={{action @onfilter.status}}
|
||||
@onchange={{action @filter.status.change}}
|
||||
@multiple={{true}}
|
||||
as |components|>
|
||||
<BlockSlot @name="selected">
|
||||
<span>
|
||||
Health Status
|
||||
{{t "common.consul.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}}
|
||||
{{#let components.Optgroup components.Option as |Optgroup 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>
|
||||
|
||||
<PopoverSelect
|
||||
</search.Select>
|
||||
{{#if @filter.kind}}
|
||||
<search.Select
|
||||
class="type-kind"
|
||||
@position="left"
|
||||
@onchange={{action @onfilter.kind}}
|
||||
@onchange={{action @filter.kind.change}}
|
||||
@multiple={{true}}
|
||||
as |components|>
|
||||
<BlockSlot @name="selected">
|
||||
<span>
|
||||
Kind
|
||||
{{t "components.consul.health-check.search-bar.kind.name"}}
|
||||
</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}}
|
||||
{{#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>
|
||||
</PopoverSelect>
|
||||
|
||||
<PopoverSelect
|
||||
</search.Select>
|
||||
{{/if}}
|
||||
<search.Select
|
||||
class="type-check"
|
||||
@position="left"
|
||||
@onchange={{action @onfilter.check}}
|
||||
@onchange={{action @filter.check.change}}
|
||||
@multiple={{true}}
|
||||
as |components|>
|
||||
<BlockSlot @name="selected">
|
||||
<span>
|
||||
Type
|
||||
{{t "components.consul.health-check.search-bar.check.name"}}
|
||||
</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}}
|
||||
{{#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>
|
||||
</PopoverSelect>
|
||||
|
||||
</div>
|
||||
<div class="sort">
|
||||
<PopoverSelect
|
||||
</search.Select>
|
||||
</:filter>
|
||||
<:sort as |search|>
|
||||
<search.Select
|
||||
class="type-sort"
|
||||
data-test-sort-control
|
||||
@position="right"
|
||||
@onchange={{action @onsort}}
|
||||
@onchange={{action @sort.change}}
|
||||
@multiple={{false}}
|
||||
@required={{true}}
|
||||
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")
|
||||
(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}}
|
||||
{{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>
|
||||
</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
|
||||
<: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="Search"
|
||||
@placeholder={{t "common.search.search"}}
|
||||
>
|
||||
<PopoverSelect
|
||||
{{#if @filter.searchproperty}}
|
||||
<search.Select
|
||||
class="type-search-properties"
|
||||
@position="right"
|
||||
@onchange={{action @onfilter.searchproperty}}
|
||||
@onchange={{action @filter.searchproperty.change}}
|
||||
@multiple={{true}}
|
||||
@required={{true}}
|
||||
as |components|>
|
||||
<BlockSlot @name="selected">
|
||||
<span>
|
||||
Search across
|
||||
{{t "common.search.searchproperty"}}
|
||||
</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 @filter.searchproperty.default as |prop|}}
|
||||
<Option @value={{prop}} @selected={{contains prop @filter.searchproperty.value}}>
|
||||
{{t (concat "common.consul." (lowercase prop))}}
|
||||
</Option>
|
||||
{{/each}}
|
||||
{{/let}}
|
||||
</BlockSlot>
|
||||
</PopoverSelect>
|
||||
</FreetextFilter>
|
||||
</div>
|
||||
<div class="filters">
|
||||
<PopoverSelect
|
||||
</search.Select>
|
||||
{{/if}}
|
||||
</search.Search>
|
||||
</:search>
|
||||
<:filter as |search|>
|
||||
<search.Select
|
||||
class="type-access"
|
||||
@position="left"
|
||||
@onchange={{action @onfilter.access}}
|
||||
@onchange={{action @filter.access.change}}
|
||||
@multiple={{true}}
|
||||
as |components|>
|
||||
<BlockSlot @name="selected">
|
||||
<span>
|
||||
Permission
|
||||
{{t "components.consul.intention.search-bar.access.name"}}
|
||||
</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}}
|
||||
{{#let components.Optgroup components.Option as |Optgroup 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>
|
||||
</div>
|
||||
<div class="sort">
|
||||
<PopoverSelect
|
||||
</search.Select>
|
||||
</:filter>
|
||||
<:sort as |search|>
|
||||
<search.Select
|
||||
class="type-sort"
|
||||
data-test-sort-control
|
||||
@position="right"
|
||||
@onchange={{action @onsort}}
|
||||
@onchange={{action @sort.change}}
|
||||
@multiple={{false}}
|
||||
@required={{true}}
|
||||
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")
|
||||
(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}}
|
||||
{{get selectable @sort.value}}
|
||||
{{/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>
|
||||
{{#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}}
|
||||
{{/let}}
|
||||
</BlockSlot>
|
||||
</PopoverSelect>
|
||||
</div>
|
||||
</form>
|
||||
</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
|
||||
<: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}}
|
||||
|
||||
</:status>
|
||||
<:search as |search|>
|
||||
<search.Search
|
||||
@onsearch={{action @onsearch}}
|
||||
@value={{@search}}
|
||||
@placeholder="Search"
|
||||
/>
|
||||
</div>
|
||||
<div class="filters">
|
||||
<PopoverSelect
|
||||
@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 @onfilter.kind}}
|
||||
@onchange={{action @filter.kind.change}}
|
||||
@multiple={{true}}
|
||||
as |components|>
|
||||
<BlockSlot @name="selected">
|
||||
<span>
|
||||
Type
|
||||
{{t "components.consul.kv.search-bar.kind.name"}}
|
||||
</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>
|
||||
{{/let}}
|
||||
{{#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>
|
||||
</PopoverSelect>
|
||||
</div>
|
||||
<div class="sort">
|
||||
<PopoverSelect
|
||||
</search.Select>
|
||||
</:filter>
|
||||
<:sort as |search|>
|
||||
<search.Select
|
||||
class="type-sort"
|
||||
data-test-sort-control
|
||||
@position="right"
|
||||
@onchange={{action @onsort}}
|
||||
@onchange={{action @sort.change}}
|
||||
@multiple={{false}}
|
||||
@required={{true}}
|
||||
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")
|
||||
(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}}
|
||||
{{get selectable @sort.value}}
|
||||
{{/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>
|
||||
{{#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="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 @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}}
|
||||
{{/let}}
|
||||
</BlockSlot>
|
||||
</PopoverSelect>
|
||||
</div>
|
||||
</form>
|
||||
</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
|
||||
<: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="Search"
|
||||
@placeholder={{t "common.search.search"}}
|
||||
>
|
||||
<PopoverSelect
|
||||
<search.Select
|
||||
class="type-search-properties"
|
||||
@position="right"
|
||||
@onchange={{action @onfilter.searchproperty}}
|
||||
@onchange={{action @filter.searchproperty.change}}
|
||||
@multiple={{true}}
|
||||
@required={{true}}
|
||||
as |components|>
|
||||
<BlockSlot @name="selected">
|
||||
<span>
|
||||
Search across
|
||||
{{t "common.search.searchproperty"}}
|
||||
</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 @filter.searchproperty.default as |prop|}}
|
||||
<Option @value={{prop}} @selected={{contains prop @filter.searchproperty.value}}>
|
||||
{{t (concat "common.consul." (lowercase prop))}}
|
||||
</Option>
|
||||
{{/each}}
|
||||
{{/let}}
|
||||
</BlockSlot>
|
||||
</PopoverSelect>
|
||||
</FreetextFilter>
|
||||
</div>
|
||||
<div class="filters">
|
||||
<PopoverSelect
|
||||
</search.Select>
|
||||
</search.Search>
|
||||
</:search>
|
||||
<:filter as |search|>
|
||||
<search.Select
|
||||
class="type-status"
|
||||
@position="left"
|
||||
@onchange={{action @onfilter.status}}
|
||||
@onchange={{action @filter.status.change}}
|
||||
@multiple={{true}}
|
||||
as |components|>
|
||||
<BlockSlot @name="selected">
|
||||
<span>
|
||||
Health Status
|
||||
{{t "common.consul.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}}
|
||||
{{#let components.Optgroup components.Option as |Optgroup 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>
|
||||
</div>
|
||||
<div class="sort">
|
||||
<PopoverSelect
|
||||
</search.Select>
|
||||
</:filter>
|
||||
<:sort as |search|>
|
||||
<search.Select
|
||||
class="type-sort"
|
||||
data-test-sort-control
|
||||
@position="right"
|
||||
@onchange={{action @onsort}}
|
||||
@onchange={{action @sort.change}}
|
||||
@multiple={{false}}
|
||||
@required={{true}}
|
||||
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")
|
||||
(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}}
|
||||
{{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>
|
||||
{{#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="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 @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}}
|
||||
{{/let}}
|
||||
</BlockSlot>
|
||||
</PopoverSelect>
|
||||
</div>
|
||||
</form>
|
||||
</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
|
||||
<: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="Search"
|
||||
@placeholder={{t "common.search.search"}}
|
||||
>
|
||||
<PopoverSelect
|
||||
<search.Select
|
||||
class="type-search-properties"
|
||||
@position="right"
|
||||
@onchange={{action @onfilter.searchproperty}}
|
||||
@onchange={{action @filter.searchproperty.change}}
|
||||
@multiple={{true}}
|
||||
@required={{true}}
|
||||
as |components|>
|
||||
<BlockSlot @name="selected">
|
||||
<span>
|
||||
Search across
|
||||
{{t "common.search.searchproperty"}}
|
||||
</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>
|
||||
{{#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>
|
||||
</PopoverSelect>
|
||||
</FreetextFilter>
|
||||
</div>
|
||||
<div class="sort">
|
||||
<PopoverSelect
|
||||
</search.Select>
|
||||
</search.Search>
|
||||
</:search>
|
||||
<:sort as |search|>
|
||||
<search.Select
|
||||
class="type-sort"
|
||||
data-test-sort-control
|
||||
@position="right"
|
||||
@onchange={{action @onsort}}
|
||||
@onchange={{action @sort.change}}
|
||||
@multiple={{false}}
|
||||
@required={{true}}
|
||||
as |components|>
|
||||
<BlockSlot @name="selected">
|
||||
<span>
|
||||
{{#let (from-entries (array
|
||||
(array "Name:asc" "A to Z")
|
||||
(array "Name:desc" "Z to A")
|
||||
(array "Name:asc" (t "common.sort.alpha.asc"))
|
||||
(array "Name:desc" (t "common.sort.alpha.desc"))
|
||||
))
|
||||
as |selectable|
|
||||
}}
|
||||
{{get selectable @sort}}
|
||||
{{get selectable @sort.value}}
|
||||
{{/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>
|
||||
{{#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}}
|
||||
{{/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
|
||||
<: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="Search"
|
||||
@placeholder={{t "common.search.search"}}
|
||||
>
|
||||
<PopoverSelect
|
||||
<search.Select
|
||||
class="type-search-properties"
|
||||
@position="right"
|
||||
@onchange={{action @onfilter.searchproperty}}
|
||||
@onchange={{action @filter.searchproperty.change}}
|
||||
@multiple={{true}}
|
||||
@required={{true}}
|
||||
as |components|>
|
||||
<BlockSlot @name="selected">
|
||||
<span>
|
||||
Search across
|
||||
{{t "common.search.searchproperty"}}
|
||||
</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 @filter.searchproperty.default as |prop|}}
|
||||
<Option @value={{prop}} @selected={{contains prop @filter.searchproperty.value}}>
|
||||
{{t (concat "common.consul." (lowercase prop))}}
|
||||
</Option>
|
||||
{{/each}}
|
||||
{{/let}}
|
||||
</BlockSlot>
|
||||
</PopoverSelect>
|
||||
</FreetextFilter>
|
||||
</div>
|
||||
<div class="filters">
|
||||
<PopoverSelect
|
||||
class="select-dcs"
|
||||
</search.Select>
|
||||
</search.Search>
|
||||
</:search>
|
||||
<:filter as |search|>
|
||||
<search.Select
|
||||
class="type-datacenter"
|
||||
@position="left"
|
||||
@onchange={{action @onfilter.dc}}
|
||||
@onchange={{action @filter.datacenter.change}}
|
||||
@multiple={{true}}
|
||||
as |components|>
|
||||
<BlockSlot @name="selected">
|
||||
<span>
|
||||
Datacenters
|
||||
{{t "common.consul.datacenter"}}
|
||||
</span>
|
||||
</BlockSlot>
|
||||
<BlockSlot @name="options">
|
||||
{{#let components.Optgroup components.Option as |Optgroup Option|}}
|
||||
{{#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>
|
||||
<Option @value={{dc.Name}} @selected={{contains dc.Name @filter.datacenter.value}}>{{dc.Name}}</Option>
|
||||
{{/each}}
|
||||
{{/let}}
|
||||
<DataSource @src="/*/*/datacenters" @loading="lazy" @onchange={{action (mut this.dcs) value="data"}} />
|
||||
{{/let}}
|
||||
</BlockSlot>
|
||||
</PopoverSelect>
|
||||
<PopoverSelect
|
||||
class="select-type"
|
||||
</search.Select>
|
||||
<search.Select
|
||||
class="type-kind"
|
||||
@position="left"
|
||||
@onchange={{action @onfilter.kind}}
|
||||
@onchange={{action @filter.kind.change}}
|
||||
@multiple={{true}}
|
||||
as |components|>
|
||||
<BlockSlot @name="selected">
|
||||
<span>
|
||||
Type
|
||||
{{t "components.consul.policy.search-bar.kind.name"}}
|
||||
</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}}
|
||||
{{#let components.Optgroup components.Option as |Optgroup 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>
|
||||
</div>
|
||||
<div class="sort">
|
||||
<PopoverSelect
|
||||
</search.Select>
|
||||
</:filter>
|
||||
<:sort as |search|>
|
||||
<search.Select
|
||||
class="type-sort"
|
||||
data-test-sort-control
|
||||
@position="right"
|
||||
@onchange={{action @onsort}}
|
||||
@onchange={{action @sort.change}}
|
||||
@multiple={{false}}
|
||||
@required={{true}}
|
||||
as |components|>
|
||||
<BlockSlot @name="selected">
|
||||
<span>
|
||||
{{#let (from-entries (array
|
||||
(array "Name:asc" "A to Z")
|
||||
(array "Name:desc" "Z to A")
|
||||
(array "Name:asc" (t "common.sort.alpha.asc"))
|
||||
(array "Name:desc" (t "common.sort.alpha.desc"))
|
||||
))
|
||||
as |selectable|
|
||||
}}
|
||||
{{get selectable @sort}}
|
||||
{{get selectable @sort.value}}
|
||||
{{/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>
|
||||
{{#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}}
|
||||
{{/let}}
|
||||
</BlockSlot>
|
||||
</PopoverSelect>
|
||||
</div>
|
||||
</form>
|
||||
</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
|
||||
<: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="Search"
|
||||
@placeholder={{t "common.search.search"}}
|
||||
>
|
||||
<PopoverSelect
|
||||
<search.Select
|
||||
class="type-search-properties"
|
||||
@position="right"
|
||||
@onchange={{action @onfilter.searchproperty}}
|
||||
@onchange={{action @filter.searchproperty.change}}
|
||||
@multiple={{true}}
|
||||
@required={{true}}
|
||||
as |components|>
|
||||
<BlockSlot @name="selected">
|
||||
<span>
|
||||
Search across
|
||||
{{t "common.search.searchproperty"}}
|
||||
</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>
|
||||
{{#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>
|
||||
</PopoverSelect>
|
||||
</FreetextFilter>
|
||||
</div>
|
||||
<div class="sort">
|
||||
<PopoverSelect
|
||||
</search.Select>
|
||||
</search.Search>
|
||||
</:search>
|
||||
<:sort as |search|>
|
||||
<search.Select
|
||||
class="type-sort"
|
||||
data-test-sort-control
|
||||
@position="right"
|
||||
@onchange={{action @onsort}}
|
||||
@onchange={{action @sort.change}}
|
||||
@multiple={{false}}
|
||||
@required={{true}}
|
||||
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")
|
||||
(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}}
|
||||
{{get selectable @sort.value}}
|
||||
{{/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>
|
||||
{{#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>
|
||||
<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}}
|
||||
{{/let}}
|
||||
</BlockSlot>
|
||||
</PopoverSelect>
|
||||
</div>
|
||||
</form>
|
||||
</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
|
||||
<: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="Search"
|
||||
@placeholder={{t "common.search.search"}}
|
||||
>
|
||||
<PopoverSelect
|
||||
{{#if @filter.searchproperty}}
|
||||
<search.Select
|
||||
class="type-search-properties"
|
||||
@position="right"
|
||||
@onchange={{action @onfilter.searchproperty}}
|
||||
@onchange={{action @filter.searchproperty.change}}
|
||||
@multiple={{true}}
|
||||
@required={{true}}
|
||||
as |components|>
|
||||
<BlockSlot @name="selected">
|
||||
<span>
|
||||
Search across
|
||||
{{t "common.search.searchproperty"}}
|
||||
</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 @filter.searchproperty.default as |prop|}}
|
||||
<Option @value={{prop}} @selected={{contains prop @filter.searchproperty.value}}>
|
||||
{{t (concat "common.consul." (lowercase prop))}}
|
||||
</Option>
|
||||
{{/each}}
|
||||
{{/let}}
|
||||
</BlockSlot>
|
||||
</PopoverSelect>
|
||||
</FreetextFilter>
|
||||
</div>
|
||||
<div class="filters">
|
||||
<PopoverSelect
|
||||
</search.Select>
|
||||
{{/if}}
|
||||
</search.Search>
|
||||
</:search>
|
||||
<:filter as |search|>
|
||||
<search.Select
|
||||
class="type-status"
|
||||
@position="left"
|
||||
@onchange={{action @onfilter.status}}
|
||||
@onchange={{action @filter.status.change}}
|
||||
@multiple={{true}}
|
||||
as |components|>
|
||||
<BlockSlot @name="selected">
|
||||
<span>
|
||||
Health Status
|
||||
{{t "common.consul.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}}
|
||||
{{#let components.Optgroup components.Option as |Optgroup 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>
|
||||
{{#if (gt @sources.length 0)}}
|
||||
<PopoverSelect
|
||||
</search.Select>
|
||||
{{#if (gt @sources.length 0)}}
|
||||
<search.Select
|
||||
class="type-source"
|
||||
@position="left"
|
||||
@onchange={{action @onfilter.source}}
|
||||
@onchange={{action @filter.source.change}}
|
||||
@multiple={{true}}
|
||||
as |components|>
|
||||
<BlockSlot @name="selected">
|
||||
<span>
|
||||
Source
|
||||
{{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.sources}}>{{source}}</Option>
|
||||
{{/each}}
|
||||
{{/let}}
|
||||
{{#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>
|
||||
</PopoverSelect>
|
||||
{{/if}}
|
||||
</div>
|
||||
<div class="sort">
|
||||
<PopoverSelect
|
||||
</search.Select>
|
||||
{{/if}}
|
||||
</:filter>
|
||||
<:sort as |search|>
|
||||
<search.Select
|
||||
class="type-sort"
|
||||
data-test-sort-control
|
||||
@position="right"
|
||||
@onchange={{action @onsort}}
|
||||
@onchange={{action @sort.change}}
|
||||
@multiple={{false}}
|
||||
@required={{true}}
|
||||
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 "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}}
|
||||
{{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>
|
||||
</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
|
||||
<: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="Search"
|
||||
@placeholder={{t "common.search.search"}}
|
||||
>
|
||||
<PopoverSelect
|
||||
<search.Select
|
||||
class="type-search-properties"
|
||||
@position="right"
|
||||
@onchange={{action @onfilter.searchproperty}}
|
||||
@onchange={{action @filter.searchproperty.change}}
|
||||
@multiple={{true}}
|
||||
@required={{true}}
|
||||
as |components|>
|
||||
<BlockSlot @name="selected">
|
||||
<span>
|
||||
Search across
|
||||
{{t "common.search.searchproperty"}}
|
||||
</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 @filter.searchproperty.default as |prop|}}
|
||||
<Option @value={{prop}} @selected={{contains prop @filter.searchproperty.value}}>
|
||||
{{t (concat "common.consul." (lowercase prop))}}
|
||||
</Option>
|
||||
{{/each}}
|
||||
{{/let}}
|
||||
</BlockSlot>
|
||||
</PopoverSelect>
|
||||
</FreetextFilter>
|
||||
</div>
|
||||
<div class="filters">
|
||||
<PopoverSelect
|
||||
</search.Select>
|
||||
</search.Search>
|
||||
</:search>
|
||||
<:filter as |search|>
|
||||
<search.Select
|
||||
class="type-status"
|
||||
@position="left"
|
||||
@onchange={{action @onfilter.status}}
|
||||
@onchange={{action @filter.status.change}}
|
||||
@multiple={{true}}
|
||||
as |components|>
|
||||
<BlockSlot @name="selected">
|
||||
<span>
|
||||
Health Status
|
||||
{{t "common.consul.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}}
|
||||
{{#let components.Optgroup components.Option as |Optgroup 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>
|
||||
<PopoverSelect
|
||||
</search.Select>
|
||||
<search.Select
|
||||
@position="left"
|
||||
@onchange={{action @onfilter.kind}}
|
||||
@onchange={{action @filter.kind.change}}
|
||||
@multiple={{true}}
|
||||
as |components|>
|
||||
<BlockSlot @name="selected">
|
||||
<span>
|
||||
Service Type
|
||||
{{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.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>
|
||||
{{#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="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
|
||||
@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}}
|
||||
{{/let}}
|
||||
</BlockSlot>
|
||||
</PopoverSelect>
|
||||
{{#if (gt @sources.length 0)}}
|
||||
<PopoverSelect
|
||||
</search.Select>
|
||||
{{#if (gt @sources.length 0)}}
|
||||
<search.Select
|
||||
class="type-source"
|
||||
@position="left"
|
||||
@onchange={{action @onfilter.source}}
|
||||
@onchange={{action @filter.source.change}}
|
||||
@multiple={{true}}
|
||||
as |components|>
|
||||
<BlockSlot @name="selected">
|
||||
<span>
|
||||
Source
|
||||
{{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.sources}}>{{source}}</Option>
|
||||
{{/each}}
|
||||
{{/let}}
|
||||
{{#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>
|
||||
</PopoverSelect>
|
||||
{{/if}}
|
||||
</div>
|
||||
<div class="sort">
|
||||
<PopoverSelect
|
||||
</search.Select>
|
||||
{{/if}}
|
||||
</:filter>
|
||||
<:sort as |search|>
|
||||
<search.Select
|
||||
class="type-sort"
|
||||
data-test-sort-control
|
||||
@position="right"
|
||||
@onchange={{action @onsort}}
|
||||
@onchange={{action @sort.change}}
|
||||
@multiple={{false}}
|
||||
@required={{true}}
|
||||
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 "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}}
|
||||
{{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>
|
||||
{{#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="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 "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}}
|
||||
{{/let}}
|
||||
</BlockSlot>
|
||||
</PopoverSelect>
|
||||
</div>
|
||||
</form>
|
||||
</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
|
||||
<: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="Search"
|
||||
@placeholder={{t "common.search.search"}}
|
||||
>
|
||||
<PopoverSelect
|
||||
<search.Select
|
||||
class="type-search-properties"
|
||||
@position="right"
|
||||
@onchange={{action @onfilter.searchproperty}}
|
||||
@onchange={{action @filter.searchproperty.change}}
|
||||
@multiple={{true}}
|
||||
@required={{true}}
|
||||
as |components|>
|
||||
<BlockSlot @name="selected">
|
||||
<span>
|
||||
Search across
|
||||
{{t "common.search.searchproperty"}}
|
||||
</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 @filter.searchproperty.default as |prop|}}
|
||||
<Option @value={{prop}} @selected={{contains prop @filter.searchproperty.value}}>
|
||||
{{t (concat "common.consul." (lowercase prop))}}
|
||||
</Option>
|
||||
{{/each}}
|
||||
{{/let}}
|
||||
</BlockSlot>
|
||||
</PopoverSelect>
|
||||
</FreetextFilter>
|
||||
</div>
|
||||
<div class="filters">
|
||||
<PopoverSelect
|
||||
</search.Select>
|
||||
</search.Search>
|
||||
</:search>
|
||||
<:filter as |search|>
|
||||
<search.Select
|
||||
class="type-status"
|
||||
@position="left"
|
||||
@onchange={{action @onfilter.kind}}
|
||||
@onchange={{action @filter.kind.change}}
|
||||
@multiple={{true}}
|
||||
as |components|>
|
||||
<BlockSlot @name="selected">
|
||||
<span>
|
||||
Type
|
||||
{{t "components.consul.token.search-bar.kind.name"}}
|
||||
</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}}
|
||||
{{#let components.Optgroup components.Option as |Optgroup 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>
|
||||
</div>
|
||||
<div class="sort">
|
||||
<PopoverSelect
|
||||
</search.Select>
|
||||
</:filter>
|
||||
<:sort as |search|>
|
||||
<search.Select
|
||||
class="type-sort"
|
||||
data-test-sort-control
|
||||
@position="right"
|
||||
@onchange={{action @onsort}}
|
||||
@onchange={{action @sort.change}}
|
||||
@multiple={{false}}
|
||||
@required={{true}}
|
||||
as |components|>
|
||||
<BlockSlot @name="selected">
|
||||
<span>
|
||||
{{#let (from-entries (array
|
||||
(array "CreateTime:desc" "Newest to oldest")
|
||||
(array "CreateTime:asc" "Oldest to newest")
|
||||
(array "CreateTime:desc" (t "common.sort.age.desc"))
|
||||
(array "CreateTime:asc" (t "common.sort.age.asc"))
|
||||
))
|
||||
as |selectable|
|
||||
}}
|
||||
{{get selectable @sort}}
|
||||
{{get selectable @sort.value}}
|
||||
{{/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>
|
||||
{{#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}}
|
||||
{{/let}}
|
||||
</BlockSlot>
|
||||
</PopoverSelect>
|
||||
</div>
|
||||
</form>
|
||||
</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
|
||||
<: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="Search"
|
||||
@placeholder={{t "common.search.search"}}
|
||||
>
|
||||
<PopoverSelect
|
||||
<search.Select
|
||||
class="type-search-properties"
|
||||
@position="right"
|
||||
@onchange={{action @onfilter.searchproperty}}
|
||||
@onchange={{action @filter.searchproperty.change}}
|
||||
@multiple={{true}}
|
||||
@required={{true}}
|
||||
as |components|>
|
||||
<BlockSlot @name="selected">
|
||||
<span>
|
||||
Search across
|
||||
{{t "common.search.searchproperty"}}
|
||||
</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 @filter.searchproperty.default as |prop|}}
|
||||
<Option @value={{prop}} @selected={{contains prop @filter.searchproperty.value}}>
|
||||
{{t (concat "common.consul." (lowercase prop))}}
|
||||
</Option>
|
||||
{{/each}}
|
||||
{{/let}}
|
||||
</BlockSlot>
|
||||
</PopoverSelect>
|
||||
</FreetextFilter>
|
||||
</div>
|
||||
<div class="sort">
|
||||
{{#let (or @sort 'DestinationName:asc') as |sort|}}
|
||||
<PopoverSelect
|
||||
</search.Select>
|
||||
</search.Search>
|
||||
</:search>
|
||||
<:sort as |search|>
|
||||
<search.Select
|
||||
class="type-sort"
|
||||
data-test-sort-control
|
||||
@position="right"
|
||||
@onchange={{action @onsort}}
|
||||
@onchange={{action @sort.change}}
|
||||
@multiple={{false}}
|
||||
@required={{true}}
|
||||
as |components|>
|
||||
<BlockSlot @name="selected">
|
||||
<span>
|
||||
{{#let (from-entries (array
|
||||
(array "DestinationName:asc" "A to Z")
|
||||
(array "DestinationName:desc" "Z to A")
|
||||
(array "DestinationName:asc" (t "common.sort.alpha.asc"))
|
||||
(array "DestinationName:desc" (t "common.sort.alpha.desc"))
|
||||
))
|
||||
as |selectable|}}
|
||||
{{get selectable sort}}
|
||||
as |selectable|
|
||||
}}
|
||||
{{get selectable @sort.value}}
|
||||
{{/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}}
|
||||
{{#let components.Optgroup components.Option as |Optgroup Option|}}
|
||||
<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>
|
||||
{{/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
|
||||
<: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="Search"
|
||||
@placeholder={{t "common.search.search"}}
|
||||
>
|
||||
<PopoverSelect
|
||||
<search.Select
|
||||
class="type-search-properties"
|
||||
@position="right"
|
||||
@onchange={{action @onfilter.searchproperty}}
|
||||
@onchange={{action @filter.searchproperty.change}}
|
||||
@multiple={{true}}
|
||||
@required={{true}}
|
||||
as |components|>
|
||||
<BlockSlot @name="selected">
|
||||
<span>
|
||||
Search across
|
||||
{{t "common.search.searchproperty"}}
|
||||
</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 @filter.searchproperty.default as |prop|}}
|
||||
<Option @value={{prop}} @selected={{contains prop @filter.searchproperty.value}}>
|
||||
{{t (concat "common.consul." (lowercase prop))}}
|
||||
</Option>
|
||||
{{/each}}
|
||||
{{/let}}
|
||||
</BlockSlot>
|
||||
</PopoverSelect>
|
||||
</FreetextFilter>
|
||||
</div>
|
||||
<div class="filters">
|
||||
<PopoverSelect
|
||||
</search.Select>
|
||||
</search.Search>
|
||||
</:search>
|
||||
<:filter as |search|>
|
||||
<search.Select
|
||||
@position="left"
|
||||
@onchange={{action @onfilter.instance}}
|
||||
@onchange={{action @filter.instance.change}}
|
||||
@multiple={{true}}
|
||||
as |components|>
|
||||
<BlockSlot @name="selected">
|
||||
<span>
|
||||
Type
|
||||
{{t "components.consul.upstream.search-bar.instance.name"}}
|
||||
</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}}
|
||||
{{#let components.Optgroup components.Option as |Optgroup 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>
|
||||
</div>
|
||||
<div class="sort">
|
||||
<PopoverSelect
|
||||
</search.Select>
|
||||
</:filter>
|
||||
<:sort as |search|>
|
||||
<search.Select
|
||||
class="type-sort"
|
||||
data-test-sort-control
|
||||
@position="right"
|
||||
@onchange={{action @onsort}}
|
||||
@onchange={{action @sort.change}}
|
||||
@multiple={{false}}
|
||||
@required={{true}}
|
||||
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 "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}}
|
||||
{{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>
|
||||
{{#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="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 "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}}
|
||||
{{/let}}
|
||||
</BlockSlot>
|
||||
</PopoverSelect>
|
||||
</div>
|
||||
</form>
|
||||
</search.Select>
|
||||
</:sort>
|
||||
</SearchBar>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import Component from '@glimmer/component';
|
||||
import { inject as service } from '@ember/service';
|
||||
import { computed, action } from '@ember/object';
|
||||
import { computed, get, action } from '@ember/object';
|
||||
import { alias } from '@ember/object/computed';
|
||||
import { tracked } from '@glimmer/tracking';
|
||||
import { sort } from '@ember/object/computed';
|
||||
|
@ -32,18 +32,19 @@ export default class DataCollectionComponent extends Component {
|
|||
return this.term || this.args.search || '';
|
||||
}
|
||||
|
||||
@computed('type', 'searchMethod', 'filtered', 'searchProperties')
|
||||
@computed('type', 'searchMethod', 'filtered', 'args.filters')
|
||||
get searchable() {
|
||||
const searchproperties =
|
||||
get(this, 'args.filters.searchproperty.value') || get(this, 'args.filters.searchproperty');
|
||||
const Searchable =
|
||||
typeof this.searchMethod === 'string'
|
||||
? this.searchableMap[this.searchMethod]
|
||||
: this.args.searchable;
|
||||
|
||||
return new Searchable(this.filtered, {
|
||||
finders: Object.fromEntries(
|
||||
Object.entries(this.searchService.predicate(this.type)).filter(([key, value]) => {
|
||||
return typeof this.searchProperties === 'undefined'
|
||||
? true
|
||||
: this.searchProperties.includes(key);
|
||||
return typeof searchproperties === 'undefined' ? true : searchproperties.includes(key);
|
||||
})
|
||||
),
|
||||
});
|
||||
|
@ -89,7 +90,13 @@ export default class DataCollectionComponent extends Component {
|
|||
if (typeof predicate === 'undefined') {
|
||||
return this.content.slice();
|
||||
}
|
||||
return this.content.filter(predicate(this.args.filters));
|
||||
const filters = Object.entries(this.args.filters)
|
||||
.filter(([key, value]) => Boolean(value))
|
||||
.map(([key, value]) => {
|
||||
const val = typeof value !== 'string' ? value.value : value;
|
||||
return [key, val];
|
||||
});
|
||||
return this.content.filter(predicate(Object.fromEntries(filters)));
|
||||
}
|
||||
|
||||
@computed('args.{items.[],items.content.[]}')
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
(component 'popover-select/optgroup' components=components)
|
||||
(component 'popover-select/option'
|
||||
select=this components=components
|
||||
onclick=(queue
|
||||
onclick=(pipe
|
||||
(action "click")
|
||||
(if multiple (noop) menu.toggle)
|
||||
)
|
||||
|
|
|
@ -6,47 +6,50 @@ export default Component.extend(Slotted, {
|
|||
tagName: '',
|
||||
dom: service('dom'),
|
||||
multiple: false,
|
||||
subtractive: false,
|
||||
required: false,
|
||||
onchange: function() {},
|
||||
addOption: function(option) {
|
||||
if (typeof this._options === 'undefined') {
|
||||
this._options = new Set();
|
||||
}
|
||||
if (this.subtractive) {
|
||||
if (!option.selected) {
|
||||
this._options.add(option.value);
|
||||
}
|
||||
} else {
|
||||
if (option.selected) {
|
||||
this._options.add(option.value);
|
||||
}
|
||||
}
|
||||
this._options.add(option);
|
||||
},
|
||||
removeOption: function(option) {
|
||||
this._options.delete(option.value);
|
||||
this._options.delete(option);
|
||||
},
|
||||
actions: {
|
||||
click: function(e, value) {
|
||||
let options = [value];
|
||||
if (this.multiple) {
|
||||
if (this._options.has(value)) {
|
||||
this._options.delete(value);
|
||||
click: function(option, e) {
|
||||
// required={{true}} ?
|
||||
if (!this.multiple) {
|
||||
if (option.selected && this.required) {
|
||||
return e;
|
||||
}
|
||||
[...this._options]
|
||||
.filter(item => item !== option)
|
||||
.forEach(item => {
|
||||
item.selected = false;
|
||||
});
|
||||
} else {
|
||||
this._options.add(value);
|
||||
if (option.selected && this.required) {
|
||||
const other = [...this._options].find(item => item !== option && item.selected);
|
||||
if (!other) {
|
||||
return e;
|
||||
}
|
||||
options = this._options;
|
||||
}
|
||||
}
|
||||
option.selected = !option.selected;
|
||||
this.onchange(
|
||||
this.dom.setEventTargetProperties(e, {
|
||||
selected: target => value,
|
||||
selected: target => option.args.value,
|
||||
selectedItems: target => {
|
||||
return [...options].join(',');
|
||||
return [...this._options]
|
||||
.filter(item => item.selected)
|
||||
.map(item => item.args.value)
|
||||
.join(',');
|
||||
},
|
||||
})
|
||||
);
|
||||
},
|
||||
change: function(option, e) {
|
||||
this.onchange(this.dom.setEventTargetProperty(e, 'selected', selected => option));
|
||||
return e;
|
||||
},
|
||||
},
|
||||
});
|
||||
|
|
|
@ -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,9 +1,13 @@
|
|||
{{#let components.MenuItem as |MenuItem|}}
|
||||
{{#let @components.MenuItem as |MenuItem|}}
|
||||
<MenuItem
|
||||
class={{if selected 'is-active'}}
|
||||
class={{if this.selected 'is-active'}}
|
||||
{{did-insert this.connect}}
|
||||
{{did-insert (set this "selected" @selected)}}
|
||||
{{did-update (set this "selected" @selected)}}
|
||||
{{will-destroy this.disconnect}}
|
||||
...attributes
|
||||
@onclick={{action 'click'}}
|
||||
@selected={{selected}}
|
||||
@onclick={{action @onclick this}}
|
||||
@selected={{this.selected}}
|
||||
>
|
||||
<BlockSlot @name="label">
|
||||
{{yield}}
|
||||
|
|
|
@ -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,5 +1,5 @@
|
|||
export default {
|
||||
kinds: {
|
||||
kind: {
|
||||
management: (item, value) => item.Type === value,
|
||||
client: (item, value) => item.Type === value,
|
||||
},
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
export default {
|
||||
statuses: {
|
||||
status: {
|
||||
passing: (item, value) => item.Status === value,
|
||||
warning: (item, value) => item.Status === value,
|
||||
critical: (item, value) => item.Status === value,
|
||||
},
|
||||
kinds: {
|
||||
kind: {
|
||||
service: (item, value) => item.Kind === value,
|
||||
node: (item, value) => item.Kind === value,
|
||||
},
|
||||
checks: {
|
||||
check: {
|
||||
serf: (item, value) => item.Type === '',
|
||||
script: (item, value) => item.Type === value,
|
||||
http: (item, value) => item.Type === value,
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
export default {
|
||||
accesses: {
|
||||
access: {
|
||||
allow: (item, value) => item.Action === value,
|
||||
deny: (item, value) => item.Action === value,
|
||||
'app-aware': (item, value) => typeof item.Action === 'undefined',
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
export default {
|
||||
kinds: {
|
||||
kind: {
|
||||
folder: (item, value) => item.isFolder,
|
||||
key: (item, value) => !item.isFolder,
|
||||
},
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
export default {
|
||||
statuses: {
|
||||
status: {
|
||||
passing: (item, value) => item.Status === value,
|
||||
warning: (item, value) => item.Status === value,
|
||||
critical: (item, value) => item.Status === value,
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
import setHelpers from 'mnemonist/set';
|
||||
|
||||
export default {
|
||||
kinds: {
|
||||
kind: {
|
||||
'global-management': (item, value) => item.isGlobalManagement,
|
||||
standard: (item, value) => !item.isGlobalManagement,
|
||||
},
|
||||
dcs: (item, values) => {
|
||||
datacenter: (item, values) => {
|
||||
return (
|
||||
typeof item.Datacenters === 'undefined' ||
|
||||
setHelpers.intersectionSize(values, new Set(item.Datacenters)) > 0
|
||||
|
|
|
@ -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,7 +1,7 @@
|
|||
import setHelpers from 'mnemonist/set';
|
||||
|
||||
export default {
|
||||
kinds: {
|
||||
kind: {
|
||||
'ingress-gateway': (item, value) => item.Kind === value,
|
||||
'terminating-gateway': (item, value) => item.Kind === value,
|
||||
'mesh-gateway': (item, value) => item.Kind === value,
|
||||
|
@ -9,16 +9,17 @@ export default {
|
|||
'in-mesh': (item, value) => item.InMesh,
|
||||
'not-in-mesh': (item, value) => !item.InMesh,
|
||||
},
|
||||
statuses: {
|
||||
status: {
|
||||
passing: (item, value) => item.MeshStatus === value,
|
||||
warning: (item, value) => item.MeshStatus === value,
|
||||
critical: (item, value) => item.MeshStatus === value,
|
||||
empty: (item, value) => item.MeshChecksTotal === 0,
|
||||
},
|
||||
instances: {
|
||||
instance: {
|
||||
registered: (item, value) => item.InstanceCount > 0,
|
||||
'not-registered': (item, value) => item.InstanceCount === 0,
|
||||
},
|
||||
sources: (item, values) => {
|
||||
source: (item, values) => {
|
||||
return setHelpers.intersectionSize(values, new Set(item.ExternalSources || [])) !== 0;
|
||||
},
|
||||
};
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
export default {
|
||||
kinds: {
|
||||
kind: {
|
||||
'global-management': (item, value) => item.isGlobalManagement,
|
||||
global: (item, value) => !item.Local,
|
||||
local: (item, value) => item.Local,
|
||||
|
|
|
@ -17,7 +17,9 @@ export default class Role extends Model {
|
|||
@attr('number') SyncTime;
|
||||
@attr('number') CreateIndex;
|
||||
@attr('number') ModifyIndex;
|
||||
// frontend only for ordering where CreateIndex can't be used
|
||||
// frontend only for ordering where CreateIndex can't be used i.e. for when
|
||||
// we need to order items that aren't yet saved to the backend, for example
|
||||
// in the role-selector
|
||||
@attr('number') CreateTime;
|
||||
// TODO: Figure out whether we need this or not
|
||||
@attr() Datacenters; // string[]
|
||||
|
|
|
@ -48,6 +48,16 @@ export default class Service extends Model {
|
|||
|
||||
@attr() meta; // {}
|
||||
|
||||
@computed('ChecksPassing', 'ChecksWarning', 'ChecksCritical')
|
||||
get ChecksTotal() {
|
||||
return this.ChecksPassing + this.ChecksWarning + this.ChecksCritical;
|
||||
}
|
||||
|
||||
@computed('MeshChecksPassing', 'MeshChecksWarning', 'MeshChecksCritical')
|
||||
get MeshChecksTotal() {
|
||||
return this.MeshChecksPassing + this.MeshChecksWarning + this.MeshChecksCritical;
|
||||
}
|
||||
|
||||
/* Mesh properties involve both the service and the associated proxy */
|
||||
@computed('ConnectedWithProxy', 'ConnectedWithGateway')
|
||||
get MeshEnabled() {
|
||||
|
|
|
@ -1,13 +1,11 @@
|
|||
import { inject as service } from '@ember/service';
|
||||
import Route from 'consul-ui/routing/route';
|
||||
import { hash } from 'rsvp';
|
||||
import { get } from '@ember/object';
|
||||
|
||||
import WithAclActions from 'consul-ui/mixins/acl/with-actions';
|
||||
|
||||
export default class IndexRoute extends Route.extend(WithAclActions) {
|
||||
@service('repository/acl') repo;
|
||||
|
||||
@service('settings') settings;
|
||||
|
||||
queryParams = {
|
||||
|
@ -19,8 +17,8 @@ export default class IndexRoute extends Route.extend(WithAclActions) {
|
|||
},
|
||||
};
|
||||
|
||||
beforeModel(transition) {
|
||||
return this.settings.findBySlug('token').then(token => {
|
||||
async beforeModel(transition) {
|
||||
const token = await this.settings.findBySlug('token');
|
||||
// If you don't have a token set or you have a
|
||||
// token set with AccessorID set to not null (new ACL mode)
|
||||
// then rewrite to the new acls
|
||||
|
@ -29,14 +27,15 @@ export default class IndexRoute extends Route.extend(WithAclActions) {
|
|||
// everything works fine either way checking things manually
|
||||
this.replaceWith('dc.acls.tokens');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
model(params) {
|
||||
return hash({
|
||||
items: this.repo.findAllByDatacenter(this.modelFor('dc').dc.Name),
|
||||
token: this.settings.findBySlug('token'),
|
||||
});
|
||||
async model(params) {
|
||||
const _items = this.repo.findAllByDatacenter(this.modelFor('dc').dc.Name);
|
||||
const _token = this.settings.findBySlug('token');
|
||||
return {
|
||||
items: await _items,
|
||||
token: await _token,
|
||||
};
|
||||
}
|
||||
|
||||
setupController(controller, model) {
|
||||
|
|
|
@ -9,7 +9,9 @@ export default class IndexRoute extends Route.extend(WithPolicyActions) {
|
|||
|
||||
queryParams = {
|
||||
sortBy: 'sort',
|
||||
dc: 'dc',
|
||||
datacenter: {
|
||||
as: 'dc',
|
||||
},
|
||||
kind: 'kind',
|
||||
searchproperty: {
|
||||
as: 'searchproperty',
|
||||
|
@ -29,6 +31,7 @@ export default class IndexRoute extends Route.extend(WithPolicyActions) {
|
|||
this.modelFor('nspace').nspace.substr(1)
|
||||
),
|
||||
}),
|
||||
searchProperties: this.queryParams.searchproperty.empty[0],
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -27,6 +27,7 @@ export default class IndexRoute extends Route.extend(WithRoleActions) {
|
|||
this.modelFor('nspace').nspace.substr(1)
|
||||
),
|
||||
}),
|
||||
searchProperties: this.queryParams.searchproperty.empty[0],
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -21,8 +21,8 @@ export default class IndexRoute extends Route.extend(WithTokenActions) {
|
|||
},
|
||||
};
|
||||
|
||||
beforeModel(transition) {
|
||||
return this.settings.findBySlug('token').then(token => {
|
||||
async beforeModel(transition) {
|
||||
const token = await this.settings.findBySlug('token');
|
||||
// If you have a token set with AccessorID set to null (legacy mode)
|
||||
// then rewrite to the old acls
|
||||
if (token && get(token, 'AccessorID') === null) {
|
||||
|
@ -30,7 +30,6 @@ export default class IndexRoute extends Route.extend(WithTokenActions) {
|
|||
// everything works fine either way checking things manually
|
||||
this.replaceWith('dc.acls');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
model(params) {
|
||||
|
@ -43,6 +42,7 @@ export default class IndexRoute extends Route.extend(WithTokenActions) {
|
|||
}),
|
||||
nspace: this.modelFor('nspace').nspace.substr(1),
|
||||
token: this.settings.findBySlug('token'),
|
||||
searchProperties: this.queryParams.searchproperty.empty[0],
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -14,10 +14,11 @@ export default class IndexRoute extends Route {
|
|||
},
|
||||
};
|
||||
|
||||
model(params) {
|
||||
async model(params) {
|
||||
return {
|
||||
dc: this.modelFor('dc').dc.Name,
|
||||
nspace: this.modelFor('nspace').nspace.substr(1),
|
||||
searchProperties: this.queryParams.searchproperty.empty[0],
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import { inject as service } from '@ember/service';
|
||||
import Route from 'consul-ui/routing/route';
|
||||
import { hash } from 'rsvp';
|
||||
|
||||
export default class IndexRoute extends Route {
|
||||
@service('data-source/service') data;
|
||||
|
@ -18,13 +17,16 @@ export default class IndexRoute extends Route {
|
|||
},
|
||||
};
|
||||
|
||||
model(params) {
|
||||
async model(params) {
|
||||
const dc = this.modelFor('dc').dc.Name;
|
||||
const nspace = this.modelFor('nspace').nspace.substr(1);
|
||||
return hash({
|
||||
items: this.data.source(uri => uri`/${nspace}/${dc}/nodes`),
|
||||
leader: this.data.source(uri => uri`/${nspace}/${dc}/leader`),
|
||||
});
|
||||
const items = this.data.source(uri => uri`/${nspace}/${dc}/nodes`);
|
||||
const leader = this.data.source(uri => uri`/${nspace}/${dc}/leader`);
|
||||
return {
|
||||
items: await items,
|
||||
leader: await leader,
|
||||
searchProperties: this.queryParams.searchproperty.empty[0],
|
||||
};
|
||||
}
|
||||
|
||||
setupController(controller, model) {
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import { inject as service } from '@ember/service';
|
||||
import Route from 'consul-ui/routing/route';
|
||||
import { hash } from 'rsvp';
|
||||
|
||||
import WithNspaceActions from 'consul-ui/mixins/nspace/with-actions';
|
||||
export default class IndexRoute extends Route.extend(WithNspaceActions) {
|
||||
|
@ -19,10 +18,11 @@ export default class IndexRoute extends Route.extend(WithNspaceActions) {
|
|||
},
|
||||
};
|
||||
|
||||
model(params) {
|
||||
return hash({
|
||||
items: this.data.source(uri => uri`/*/*/namespaces`),
|
||||
});
|
||||
async model(params) {
|
||||
return {
|
||||
items: await this.data.source(uri => uri`/*/*/namespaces`),
|
||||
searchProperties: this.queryParams.searchproperty.empty[0],
|
||||
};
|
||||
}
|
||||
|
||||
setupController(controller, model) {
|
||||
|
|
|
@ -27,6 +27,7 @@ export default class IndexRoute extends Route {
|
|||
dc,
|
||||
nspace,
|
||||
items,
|
||||
searchProperties: this.queryParams.searchproperty.empty[0],
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -4,7 +4,6 @@ export default class HealthchecksRoute extends Route {
|
|||
queryParams = {
|
||||
sortBy: 'sort',
|
||||
status: 'status',
|
||||
kind: 'kind',
|
||||
check: 'check',
|
||||
searchproperty: {
|
||||
as: 'searchproperty',
|
||||
|
|
|
@ -14,11 +14,12 @@ export default class IndexRoute extends Route {
|
|||
},
|
||||
};
|
||||
|
||||
model(params) {
|
||||
async model(params) {
|
||||
return {
|
||||
dc: this.modelFor('dc').dc.Name,
|
||||
nspace: this.modelFor('nspace').nspace.substr(1) || 'default',
|
||||
slug: this.paramsFor('dc.services.show').name,
|
||||
searchProperties: this.queryParams.searchproperty.empty[0],
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -25,13 +25,12 @@ export default class ServicesRoute extends Route {
|
|||
.slice(0, -1)
|
||||
.join('.');
|
||||
const name = this.modelFor(parent).slug;
|
||||
const gatewayServices = await this.data.source(
|
||||
uri => uri`/${nspace}/${dc}/gateways/for-service/${name}`
|
||||
);
|
||||
const items = await this.data.source(uri => uri`/${nspace}/${dc}/gateways/for-service/${name}`);
|
||||
return {
|
||||
dc,
|
||||
nspace,
|
||||
gatewayServices,
|
||||
items,
|
||||
searchProperties: this.queryParams.searchproperty.empty[0],
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -53,6 +53,7 @@
|
|||
@import 'consul-ui/components/freetext-filter';
|
||||
@import 'consul-ui/components/informed-action';
|
||||
@import 'consul-ui/components/tab-nav';
|
||||
@import 'consul-ui/components/search-bar';
|
||||
|
||||
@import 'consul-ui/components/consul/tomography/graph';
|
||||
@import 'consul-ui/components/consul/discovery-chain';
|
||||
|
|
|
@ -18,7 +18,7 @@ html[data-route$='edit'] .app-view > header + div > *:first-child {
|
|||
/* if it is a filter bar and the thing after the filter bar is a p then it also */
|
||||
/* needs a top margun :S */
|
||||
%app-view-content .tab-section > *:first-child:not(.filter-bar):not(table),
|
||||
%app-view-content .tab-section > .filter-bar + p,
|
||||
%app-view-content .tab-section > .search-bar + p,
|
||||
%app-view-content .tab-section .consul-health-check-list {
|
||||
margin-top: 1.25em;
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@ h3 {
|
|||
%radio-card header,
|
||||
fieldset > header,
|
||||
%main-nav-horizontal-action,
|
||||
%app-view-content div > dl > dt,
|
||||
%definition-table dt,
|
||||
%table caption,
|
||||
%tbody-th,
|
||||
%form-element > span {
|
||||
|
|
|
@ -1,9 +1,23 @@
|
|||
{{page-title 'ACLs'}}
|
||||
{{#let (hash
|
||||
kinds=(if kind (split kind ',') undefined)
|
||||
) as |filters|}}
|
||||
{{#let (or sortBy "Name:asc") as |sort|}}
|
||||
<AppView>
|
||||
{{#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
|
||||
|
||||
as |sort filters items|}}
|
||||
|
||||
<AppView>
|
||||
<BlockSlot @name="notification" as |status type item error|>
|
||||
<Consul::Acl::Notifications
|
||||
@status={{status}}
|
||||
|
@ -27,19 +41,15 @@
|
|||
@onsearch={{action (mut search) value="target.value"}}
|
||||
|
||||
@sort={{sort}}
|
||||
@onsort={{action (mut sortBy) value="target.selected"}}
|
||||
|
||||
@filter={{filters}}
|
||||
@onfilter={{hash
|
||||
kind=(action (mut kind) value="target.selectedItems")
|
||||
}}
|
||||
/>
|
||||
{{/if}}
|
||||
</BlockSlot>
|
||||
<BlockSlot @name="content">
|
||||
<DataCollection
|
||||
@type="acl"
|
||||
@sort={{sort}}
|
||||
@sort={{sort.value}}
|
||||
@filters={{filters}}
|
||||
@search={{search}}
|
||||
@items={{items}}
|
||||
|
@ -78,6 +88,6 @@
|
|||
</collection.Empty>
|
||||
</DataCollection>
|
||||
</BlockSlot>
|
||||
</AppView>
|
||||
{{/let}}
|
||||
</AppView>
|
||||
|
||||
{{/let}}
|
||||
|
|
|
@ -3,15 +3,35 @@
|
|||
{{else}}
|
||||
{{page-title 'Access Controls'}}
|
||||
{{/if}}
|
||||
{{#let (hash
|
||||
kinds=(if kind (split kind ',') undefined)
|
||||
dcs=(if dc (split dc ',') undefined)
|
||||
searchproperties=(if (not-eq searchproperty undefined)
|
||||
(split searchproperty ',')
|
||||
(array 'Name' 'Description')
|
||||
{{#let
|
||||
|
||||
(hash
|
||||
value=(or sortBy "Name:asc")
|
||||
change=(action (mut sortBy) value="target.selected")
|
||||
)
|
||||
) as |filters|}}
|
||||
{{#let (or sortBy "Name:asc") as |sort|}}
|
||||
|
||||
(hash
|
||||
kind=(hash
|
||||
value=(if kind (split kind ',') undefined)
|
||||
change=(action (mut kind) value="target.selectedItems")
|
||||
)
|
||||
datacenter=(hash
|
||||
value=(if datacenter (split datacenter ',') undefined)
|
||||
change=(action (mut datacenter) value="target.selectedItems")
|
||||
)
|
||||
searchproperty=(hash
|
||||
value=(if (not-eq searchproperty undefined)
|
||||
(split searchproperty ',')
|
||||
searchProperties
|
||||
)
|
||||
change=(action (mut searchproperty) value="target.selectedItems")
|
||||
default=searchProperties
|
||||
)
|
||||
)
|
||||
|
||||
items
|
||||
|
||||
as |sort filters items|}}
|
||||
<AppView
|
||||
@authorized={{isAuthorized}}
|
||||
@enabled={{isEnabled}}
|
||||
|
@ -44,21 +64,15 @@
|
|||
@onsearch={{action (mut search) value="target.value"}}
|
||||
|
||||
@sort={{sort}}
|
||||
@onsort={{action (mut sortBy) value="target.selected"}}
|
||||
|
||||
@filter={{filters}}
|
||||
@onfilter={{hash
|
||||
searchproperty=(action (mut searchproperty) value="target.selectedItems")
|
||||
dc=(action (mut dc) value="target.selectedItems")
|
||||
kind=(action (mut kind) value="target.selectedItems")
|
||||
}}
|
||||
/>
|
||||
{{/if}}
|
||||
</BlockSlot>
|
||||
<BlockSlot @name="content">
|
||||
<DataCollection
|
||||
@type="role"
|
||||
@sort={{sort}}
|
||||
@type="policy"
|
||||
@sort={{sort.value}}
|
||||
@filters={{filters}}
|
||||
@search={{search}}
|
||||
@items={{items}}
|
||||
|
@ -102,5 +116,5 @@
|
|||
</DataCollection>
|
||||
</BlockSlot>
|
||||
</AppView>
|
||||
{{/let}}
|
||||
|
||||
{{/let}}
|
|
@ -4,13 +4,28 @@
|
|||
{{page-title 'Access Controls'}}
|
||||
{{/if}}
|
||||
|
||||
{{#let (hash
|
||||
searchproperties=(if (not-eq searchproperty undefined)
|
||||
(split searchproperty ',')
|
||||
(array 'Name' 'Description' 'Policy')
|
||||
{{#let
|
||||
|
||||
(hash
|
||||
value=(or sortBy "Name:asc")
|
||||
change=(action (mut sortBy) value="target.selected")
|
||||
)
|
||||
) as |filters|}}
|
||||
{{#let (or sortBy "Name:asc") as |sort|}}
|
||||
|
||||
(hash
|
||||
searchproperty=(hash
|
||||
value=(if (not-eq searchproperty undefined)
|
||||
(split searchproperty ',')
|
||||
searchProperties
|
||||
)
|
||||
change=(action (mut searchproperty) value="target.selectedItems")
|
||||
default=searchProperties
|
||||
)
|
||||
)
|
||||
|
||||
items
|
||||
|
||||
as |sort filters items|}}
|
||||
|
||||
<AppView
|
||||
@authorized={{isAuthorized}}
|
||||
@enabled={{isEnabled}}
|
||||
|
@ -43,19 +58,15 @@
|
|||
@onsearch={{action (mut search) value="target.value"}}
|
||||
|
||||
@sort={{sort}}
|
||||
@onsort={{action (mut sortBy) value="target.selected"}}
|
||||
|
||||
@filter={{filters}}
|
||||
@onfilter={{hash
|
||||
searchproperty=(action (mut searchproperty) value="target.selectedItems")
|
||||
}}
|
||||
/>
|
||||
{{/if}}
|
||||
</BlockSlot>
|
||||
<BlockSlot @name="content">
|
||||
<DataCollection
|
||||
@type="role"
|
||||
@sort={{sort}}
|
||||
@sort={{sort.value}}
|
||||
@filters={{filters}}
|
||||
@search={{search}}
|
||||
@items={{items}}
|
||||
|
@ -99,5 +110,4 @@
|
|||
</DataCollection>
|
||||
</BlockSlot>
|
||||
</AppView>
|
||||
{{/let}}
|
||||
{{/let}}
|
|
@ -4,14 +4,32 @@
|
|||
{{page-title 'Access Controls'}}
|
||||
{{/if}}
|
||||
|
||||
{{#let (hash
|
||||
kinds=(if kind (split kind ',') undefined)
|
||||
searchproperties=(if (not-eq searchproperty undefined)
|
||||
(split searchproperty ',')
|
||||
(array 'Description' 'Policy' 'Role')
|
||||
{{#let
|
||||
|
||||
(hash
|
||||
value=(or sortBy "CreateTime:desc")
|
||||
change=(action (mut sortBy) value="target.selected")
|
||||
)
|
||||
) as |filters|}}
|
||||
{{#let (or sortBy "CreateTime:desc") as |sort|}}
|
||||
|
||||
(hash
|
||||
kind=(hash
|
||||
value=(if kind (split kind ',') undefined)
|
||||
change=(action (mut kind) value="target.selectedItems")
|
||||
)
|
||||
searchproperty=(hash
|
||||
value=(if (not-eq searchproperty undefined)
|
||||
(split searchproperty ',')
|
||||
searchProperties
|
||||
)
|
||||
change=(action (mut searchproperty) value="target.selectedItems")
|
||||
default=searchProperties
|
||||
)
|
||||
)
|
||||
|
||||
items
|
||||
|
||||
as |sort filters items|}}
|
||||
|
||||
<AppView
|
||||
@authorized={{isAuthorized}}
|
||||
@enabled={{isEnabled}}
|
||||
|
@ -44,13 +62,8 @@
|
|||
@onsearch={{action (mut search) value="target.value"}}
|
||||
|
||||
@sort={{sort}}
|
||||
@onsort={{action (mut sortBy) value="target.selected"}}
|
||||
|
||||
@filter={{filters}}
|
||||
@onfilter={{hash
|
||||
searchproperty=(action (mut searchproperty) value="target.selectedItems")
|
||||
kind=(action (mut kind) value="target.selectedItems")
|
||||
}}
|
||||
/>
|
||||
{{/if}}
|
||||
</BlockSlot>
|
||||
|
@ -69,7 +82,7 @@
|
|||
{{/if}}
|
||||
<DataCollection
|
||||
@type="token"
|
||||
@sort={{sort}}
|
||||
@sort={{sort.value}}
|
||||
@filters={{filters}}
|
||||
@search={{search}}
|
||||
@items={{items}}
|
||||
|
@ -109,5 +122,4 @@
|
|||
</DataCollection>
|
||||
</BlockSlot>
|
||||
</AppView>
|
||||
{{/let}}
|
||||
{{/let}}
|
||||
|
|
|
@ -6,15 +6,32 @@
|
|||
</BlockSlot>
|
||||
|
||||
<BlockSlot @name="loaded">
|
||||
{{#let api.data as |items|}}
|
||||
{{#let (hash
|
||||
accesses=(if access (split access ',') undefined)
|
||||
searchproperties=(if (not-eq searchproperty undefined)
|
||||
(split searchproperty ',')
|
||||
(array 'SourceName' 'DestinationName')
|
||||
{{#let
|
||||
|
||||
(hash
|
||||
value=(or sortBy "Action:asc")
|
||||
change=(action (mut sortBy) value="target.selected")
|
||||
)
|
||||
) as |filters|}}
|
||||
{{#let (or sortBy "Action:asc") as |sort|}}
|
||||
|
||||
(hash
|
||||
access=(hash
|
||||
value=(if access (split access ',') undefined)
|
||||
change=(action (mut access) value="target.selectedItems")
|
||||
)
|
||||
searchproperty=(hash
|
||||
value=(if (not-eq searchproperty undefined)
|
||||
(split searchproperty ',')
|
||||
searchProperties
|
||||
)
|
||||
change=(action (mut searchproperty) value="target.selectedItems")
|
||||
default=searchProperties
|
||||
)
|
||||
)
|
||||
|
||||
api.data
|
||||
|
||||
as |sort filters items|}}
|
||||
|
||||
<AppView>
|
||||
<BlockSlot @name="header">
|
||||
<h1>
|
||||
|
@ -27,21 +44,16 @@
|
|||
</BlockSlot>
|
||||
<BlockSlot @name="toolbar">
|
||||
|
||||
{{#if (gt items.length 0) }}
|
||||
{{#if (gt items.length 0) }}
|
||||
<Consul::Intention::SearchBar
|
||||
@search={{search}}
|
||||
@onsearch={{action (mut search) value="target.value"}}
|
||||
|
||||
@sort={{sort}}
|
||||
@onsort={{action (mut sortBy) value="target.selected"}}
|
||||
|
||||
@filter={{filters}}
|
||||
@onfilter={{hash
|
||||
searchproperty=(action (mut searchproperty) value="target.selectedItems")
|
||||
access=(action (mut access) value="target.selectedItems")
|
||||
}}
|
||||
/>
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
|
||||
</BlockSlot>
|
||||
<BlockSlot @name="content">
|
||||
|
@ -53,7 +65,7 @@
|
|||
<BlockSlot @name="content">
|
||||
<DataCollection
|
||||
@type="intention"
|
||||
@sort={{sort}}
|
||||
@sort={{sort.value}}
|
||||
@filters={{filters}}
|
||||
@search={{search}}
|
||||
@items={{items}}
|
||||
|
@ -102,8 +114,7 @@
|
|||
</DataWriter>
|
||||
</BlockSlot>
|
||||
</AppView>
|
||||
{{/let}}
|
||||
{{/let}}
|
||||
|
||||
{{/let}}
|
||||
</BlockSlot>
|
||||
</DataLoader>
|
|
@ -1,8 +1,21 @@
|
|||
{{page-title 'Key/Value'}}
|
||||
{{#let (hash
|
||||
kinds=(if kind (split kind ',') undefined)
|
||||
) as |filters|}}
|
||||
{{#let (or sortBy "Kind:asc") as |sort|}}
|
||||
{{#let
|
||||
|
||||
(hash
|
||||
value=(or sortBy "Kind: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
|
||||
|
||||
as |sort filters items|}}
|
||||
<AppView>
|
||||
{{#if (not-eq parent.Key '/') }}
|
||||
<BlockSlot @name="breadcrumbs">
|
||||
|
@ -31,12 +44,8 @@
|
|||
@onsearch={{action (mut search) value="target.value"}}
|
||||
|
||||
@sort={{sort}}
|
||||
@onsort={{action (mut sortBy) value="target.selected"}}
|
||||
|
||||
@filter={{filters}}
|
||||
@onfilter={{hash
|
||||
kind=(action (mut kind) value="target.selectedItems")
|
||||
}}
|
||||
/>
|
||||
{{/if}}
|
||||
</BlockSlot>
|
||||
|
@ -57,7 +66,7 @@
|
|||
<BlockSlot @name="content">
|
||||
<DataCollection
|
||||
@type="kv"
|
||||
@sort={{sort}}
|
||||
@sort={{sort.value}}
|
||||
@filters={{filters}}
|
||||
@search={{search}}
|
||||
@items={{items}}
|
||||
|
@ -104,5 +113,4 @@
|
|||
</DataWriter>
|
||||
</BlockSlot>
|
||||
</AppView>
|
||||
{{/let}}
|
||||
{{/let}}
|
|
@ -1,14 +1,31 @@
|
|||
{{page-title 'Nodes'}}
|
||||
<EventSource @src={{items}} />
|
||||
<EventSource @src={{leader}} />
|
||||
{{#let (hash
|
||||
statuses=(if status (split status ',') undefined)
|
||||
searchproperties=(if (not-eq searchproperty undefined)
|
||||
(split searchproperty ',')
|
||||
(array 'Node' 'Address' 'Meta')
|
||||
{{#let
|
||||
|
||||
(hash
|
||||
value=(or sortBy "Status:asc")
|
||||
change=(action (mut sortBy) value="target.selected")
|
||||
)
|
||||
) as |filters|}}
|
||||
{{#let (or sortBy "Status:asc") as |sort|}}
|
||||
|
||||
(hash
|
||||
status=(hash
|
||||
value=(if status (split status ',') undefined)
|
||||
change=(action (mut status) value="target.selectedItems")
|
||||
)
|
||||
searchproperty=(hash
|
||||
value=(if (not-eq searchproperty undefined)
|
||||
(split searchproperty ',')
|
||||
searchProperties
|
||||
)
|
||||
change=(action (mut searchproperty) value="target.selectedItems")
|
||||
default=searchProperties
|
||||
)
|
||||
)
|
||||
|
||||
items
|
||||
|
||||
as |sort filters items|}}
|
||||
<AppView>
|
||||
<BlockSlot @name="header">
|
||||
<h1>
|
||||
|
@ -23,20 +40,15 @@
|
|||
@onsearch={{action (mut search) value="target.value"}}
|
||||
|
||||
@sort={{sort}}
|
||||
@onsort={{action (mut sortBy) value="target.selected"}}
|
||||
|
||||
@filter={{filters}}
|
||||
@onfilter={{hash
|
||||
searchproperty=(action (mut searchproperty) value="target.selectedItems")
|
||||
status=(action (mut status) value="target.selectedItems")
|
||||
}}
|
||||
/>
|
||||
{{/if}}
|
||||
</BlockSlot>
|
||||
<BlockSlot @name="content">
|
||||
<DataCollection
|
||||
@type="node"
|
||||
@sort={{sort}}
|
||||
@sort={{sort.value}}
|
||||
@filters={{filters}}
|
||||
@search={{search}}
|
||||
@items={{items}}
|
||||
|
@ -59,5 +71,4 @@
|
|||
</DataCollection>
|
||||
</BlockSlot>
|
||||
</AppView>
|
||||
{{/let}}
|
||||
{{/let}}
|
|
@ -1,40 +1,55 @@
|
|||
{{#let (hash
|
||||
statuses=(if status (split status ',') undefined)
|
||||
kinds=(if kind (split kind ',') undefined)
|
||||
checks=(if check (split check ',') undefined)
|
||||
searchproperties=(if (not-eq searchproperty undefined)
|
||||
{{#let
|
||||
|
||||
(hash
|
||||
value=(or sortBy "Status:asc")
|
||||
change=(action (mut sortBy) value="target.selected")
|
||||
)
|
||||
|
||||
(hash
|
||||
status=(hash
|
||||
value=(if status (split status ',') undefined)
|
||||
change=(action (mut status) value="target.selectedItems")
|
||||
)
|
||||
kind=(hash
|
||||
value=(if kind (split kind ',') undefined)
|
||||
change=(action (mut kind) value="target.selectedItems")
|
||||
)
|
||||
check=(hash
|
||||
value=(if check (split check ',') undefined)
|
||||
change=(action (mut check) value="target.selectedItems")
|
||||
)
|
||||
searchproperty=(hash
|
||||
value=(if (not-eq searchproperty undefined)
|
||||
(split searchproperty ',')
|
||||
searchProperties
|
||||
)
|
||||
) as |filters|}}
|
||||
{{#let (or sortBy "Status:asc") as |sort|}}
|
||||
change=(action (mut searchproperty) value="target.selectedItems")
|
||||
default=searchProperties
|
||||
)
|
||||
)
|
||||
|
||||
item.Checks
|
||||
|
||||
as |sort filters items|}}
|
||||
<div class="tab-section">
|
||||
{{#if (gt item.Checks.length 0) }}
|
||||
{{#if (gt items.length 0) }}
|
||||
<input type="checkbox" id="toolbar-toggle" />
|
||||
<Consul::HealthCheck::SearchBar
|
||||
|
||||
@search={{search}}
|
||||
@onsearch={{action (mut search) value="target.value"}}
|
||||
@searchproperties={{searchProperties}}
|
||||
|
||||
@sort={{sort}}
|
||||
@onsort={{action (mut sortBy) value="target.selected"}}
|
||||
|
||||
@filter={{filters}}
|
||||
@onfilter={{hash
|
||||
searchproperty=(action (mut searchproperty) value="target.selectedItems")
|
||||
status=(action (mut status) value="target.selectedItems")
|
||||
kind=(action (mut kind) value="target.selectedItems")
|
||||
check=(action (mut check) value="target.selectedItems")
|
||||
}}
|
||||
/>
|
||||
{{/if}}
|
||||
<DataCollection
|
||||
@type="health-check"
|
||||
@sort={{sort}}
|
||||
@sort={{sort.value}}
|
||||
@filters={{filters}}
|
||||
@search={{search}}
|
||||
@items={{item.Checks}}
|
||||
@items={{items}}
|
||||
as |collection|>
|
||||
<collection.Collection>
|
||||
<Consul::HealthCheck::List
|
||||
|
@ -45,12 +60,11 @@
|
|||
<EmptyState>
|
||||
<BlockSlot @name="body">
|
||||
<p>
|
||||
This node has no health checks{{#if (gt item.Checks.length 0)}} matching that search{{/if}}.
|
||||
This node has no health checks{{#if (gt items.length 0)}} matching that search{{/if}}.
|
||||
</p>
|
||||
</BlockSlot>
|
||||
</EmptyState>
|
||||
</collection.Empty>
|
||||
</DataCollection>
|
||||
</div>
|
||||
{{/let}}
|
||||
{{/let}}
|
|
@ -1,13 +1,32 @@
|
|||
{{#let (hash
|
||||
statuses=(if status (split status ',') undefined)
|
||||
sources=(if source (split source ',') undefined)
|
||||
searchproperties=(if (not-eq searchproperty undefined)
|
||||
{{#let
|
||||
|
||||
(hash
|
||||
value=(or sortBy "Status:asc")
|
||||
change=(action (mut sortBy) value="target.selected")
|
||||
)
|
||||
|
||||
(hash
|
||||
status=(hash
|
||||
value=(if status (split status ',') undefined)
|
||||
change=(action (mut status) value="target.selectedItems")
|
||||
)
|
||||
source=(hash
|
||||
value=(if source (split source ',') undefined)
|
||||
change=(action (mut source) value="target.selectedItems")
|
||||
)
|
||||
searchproperty=(hash
|
||||
value=(if (not-eq searchproperty undefined)
|
||||
(split searchproperty ',')
|
||||
searchProperties
|
||||
)
|
||||
) as |filters|}}
|
||||
{{#let (or sortBy "Status:asc") as |sort|}}
|
||||
{{#let (reject-by 'Service.Kind' 'connect-proxy' item.Services) as |items|}}
|
||||
change=(action (mut searchproperty) value="target.selectedItems")
|
||||
default=searchProperties
|
||||
)
|
||||
)
|
||||
|
||||
(reject-by 'Service.Kind' 'connect-proxy' item.Services)
|
||||
|
||||
as |sort filters items|}}
|
||||
<div class="tab-section">
|
||||
{{#if (gt items.length 0) }}
|
||||
<input type="checkbox" id="toolbar-toggle" />
|
||||
|
@ -18,20 +37,14 @@
|
|||
@searchproperties={{searchProperties}}
|
||||
|
||||
@sort={{sort}}
|
||||
@onsort={{action (mut sortBy) value="target.selected"}}
|
||||
|
||||
@filter={{filters}}
|
||||
@onfilter={{hash
|
||||
searchproperty=(action (mut searchproperty) value="target.selectedItems")
|
||||
status=(action (mut status) value="target.selectedItems")
|
||||
source=(action (mut source) value="target.selectedItems")
|
||||
}}
|
||||
/>
|
||||
{{/if}}
|
||||
{{! filter out any sidecar proxies }}
|
||||
<DataCollection
|
||||
@type="service-instance"
|
||||
@sort={{sort}}
|
||||
@sort={{sort.value}}
|
||||
@filters={{filters}}
|
||||
@search={{search}}
|
||||
@items={{items}}
|
||||
|
@ -55,6 +68,4 @@
|
|||
</collection.Empty>
|
||||
</DataCollection>
|
||||
</div>
|
||||
{{/let}}
|
||||
{{/let}}
|
||||
{{/let}}
|
|
@ -1,12 +1,27 @@
|
|||
{{page-title 'Namespaces'}}
|
||||
{{#let (hash
|
||||
searchproperties=(if (not-eq searchproperty undefined)
|
||||
(split searchproperty ',')
|
||||
(array 'Name' 'Description' 'Policy' 'Role')
|
||||
<EventSource @src={{items}} />
|
||||
{{#let
|
||||
|
||||
(hash
|
||||
value=(or sortBy "Name:asc")
|
||||
change=(action (mut sortBy) value="target.selected")
|
||||
)
|
||||
) as |filters|}}
|
||||
{{#let (or sortBy "Name:asc") as |sort|}}
|
||||
<EventSource @src={{items}} />
|
||||
|
||||
(hash
|
||||
searchproperty=(hash
|
||||
value=(if (not-eq searchproperty undefined)
|
||||
(split searchproperty ',')
|
||||
searchProperties
|
||||
)
|
||||
change=(action (mut searchproperty) value="target.selectedItems")
|
||||
default=searchProperties
|
||||
)
|
||||
)
|
||||
|
||||
items
|
||||
|
||||
as |sort filters items|}}
|
||||
|
||||
<AppView>
|
||||
<BlockSlot @name="notification" as |status type item error|>
|
||||
<Consul::Nspace::Notifications
|
||||
|
@ -30,19 +45,15 @@
|
|||
@onsearch={{action (mut search) value="target.value"}}
|
||||
|
||||
@sort={{sort}}
|
||||
@onsort={{action (mut sortBy) value="target.selected"}}
|
||||
|
||||
@filter={{filters}}
|
||||
@onfilter={{hash
|
||||
searchproperty=(action (mut searchproperty) value="target.selectedItems")
|
||||
}}
|
||||
/>
|
||||
{{/if}}
|
||||
</BlockSlot>
|
||||
<BlockSlot @name="content">
|
||||
<DataCollection
|
||||
@type="nspace"
|
||||
@sort={{sort}}
|
||||
@sort={{sort.value}}
|
||||
@filters={{filters}}
|
||||
@search={{search}}
|
||||
@items={{items}}
|
||||
|
@ -86,5 +97,4 @@
|
|||
</DataCollection>
|
||||
</BlockSlot>
|
||||
</AppView>
|
||||
{{/let}}
|
||||
{{/let}}
|
|
@ -4,15 +4,31 @@
|
|||
|
||||
{{#let
|
||||
|
||||
(or sortBy "Status:asc")
|
||||
(hash
|
||||
value=(or sortBy "Status:asc")
|
||||
change=(action (mut sortBy) value="target.selected")
|
||||
)
|
||||
|
||||
(hash
|
||||
statuses=(if status (split status ',') undefined)
|
||||
kinds=(if kind (split kind ',') undefined)
|
||||
sources=(if source (split source ',') undefined)
|
||||
searchproperties=(if (not-eq searchproperty undefined)
|
||||
status=(hash
|
||||
value=(if status (split status ',') undefined)
|
||||
change=(action (mut status) value="target.selectedItems")
|
||||
)
|
||||
kind=(hash
|
||||
value=(if kind (split kind ',') undefined)
|
||||
change=(action (mut kind) value="target.selectedItems")
|
||||
)
|
||||
source=(hash
|
||||
value=(if source (split source ',') undefined)
|
||||
change=(action (mut source) value="target.selectedItems")
|
||||
)
|
||||
searchproperty=(hash
|
||||
value=(if (not-eq searchproperty undefined)
|
||||
(split searchproperty ',')
|
||||
(array 'Name' 'Tags')
|
||||
searchProperties
|
||||
)
|
||||
change=(action (mut searchproperty) value="target.selectedItems")
|
||||
default=searchProperties
|
||||
)
|
||||
)
|
||||
|
||||
|
@ -36,22 +52,16 @@ as |sort filters items|}}
|
|||
@onsearch={{action (mut search) value="target.value"}}
|
||||
|
||||
@sort={{sort}}
|
||||
@onsort={{action (mut sortBy) value="target.selected"}}
|
||||
|
||||
@filter={{filters}}
|
||||
@onfilter={{hash
|
||||
searchproperty=(action (mut searchproperty) value="target.selectedItems")
|
||||
status=(action (mut status) value="target.selectedItems")
|
||||
kind=(action (mut kind) value="target.selectedItems")
|
||||
source=(action (mut source) value="target.selectedItems")
|
||||
}}
|
||||
|
||||
/>
|
||||
{{/if}}
|
||||
</BlockSlot>
|
||||
<BlockSlot @name="content">
|
||||
<DataCollection
|
||||
@type="service"
|
||||
@sort={{sort}}
|
||||
@sort={{sort.value}}
|
||||
@filters={{filters}}
|
||||
@search={{search}}
|
||||
@items={{items}}
|
||||
|
|
|
@ -1,41 +1,52 @@
|
|||
{{#let (hash
|
||||
statuses=(if status (split status ',') undefined)
|
||||
kinds=(if kind (split kind ',') undefined)
|
||||
checks=(if check (split check ',') undefined)
|
||||
searchproperties=(if (not-eq searchproperty undefined)
|
||||
{{#let
|
||||
|
||||
(hash
|
||||
value=(or sortBy "Status:asc")
|
||||
change=(action (mut sortBy) value="target.selected")
|
||||
)
|
||||
|
||||
(hash
|
||||
status=(hash
|
||||
value=(if status (split status ',') undefined)
|
||||
change=(action (mut status) value="target.selectedItems")
|
||||
)
|
||||
check=(hash
|
||||
value=(if check (split check ',') undefined)
|
||||
change=(action (mut check) value="target.selectedItems")
|
||||
)
|
||||
searchproperty=(hash
|
||||
value=(if (not-eq searchproperty undefined)
|
||||
(split searchproperty ',')
|
||||
searchProperties
|
||||
)
|
||||
) as |filters|}}
|
||||
{{#let (or sortBy "Status:asc") as |sort|}}
|
||||
change=(action (mut searchproperty) value="target.selectedItems")
|
||||
default=searchProperties
|
||||
)
|
||||
)
|
||||
|
||||
item.MeshChecks
|
||||
|
||||
as |sort filters items|}}
|
||||
<div class="tab-section">
|
||||
|
||||
{{#if (gt item.MeshChecks.length 0) }}
|
||||
{{#if (gt items.length 0) }}
|
||||
<input type="checkbox" id="toolbar-toggle" />
|
||||
<Consul::HealthCheck::SearchBar
|
||||
@search={{search}}
|
||||
@onsearch={{action (mut search) value="target.value"}}
|
||||
@searchproperties={{searchProperties}}
|
||||
|
||||
@sort={{sort}}
|
||||
@onsort={{action (mut sortBy) value="target.selected"}}
|
||||
|
||||
@filter={{filters}}
|
||||
@onfilter={{hash
|
||||
searchproperty=(action (mut searchproperty) value="target.selectedItems")
|
||||
status=(action (mut status) value="target.selectedItems")
|
||||
kind=(action (mut kind) value="target.selectedItems")
|
||||
check=(action (mut check) value="target.selectedItems")
|
||||
}}
|
||||
/>
|
||||
{{/if}}
|
||||
|
||||
<DataCollection
|
||||
@type="health-check"
|
||||
@sort={{sort}}
|
||||
@sort={{sort.value}}
|
||||
@filters={{filters}}
|
||||
@search={{search}}
|
||||
@items={{item.MeshChecks}}
|
||||
@items={{items}}
|
||||
as |collection|>
|
||||
<collection.Collection>
|
||||
<Consul::HealthCheck::List
|
||||
|
@ -46,7 +57,7 @@
|
|||
<EmptyState>
|
||||
<BlockSlot @name="body">
|
||||
<p>
|
||||
This instance has no health checks{{#if (gt item.MeshChecks.length 0)}} matching that search{{/if}}.
|
||||
This instance has no health checks{{#if (gt items.length 0)}} matching that search{{/if}}.
|
||||
</p>
|
||||
</BlockSlot>
|
||||
</EmptyState>
|
||||
|
@ -54,5 +65,4 @@
|
|||
</DataCollection>
|
||||
|
||||
</div>
|
||||
{{/let}}
|
||||
{{/let}}
|
||||
|
|
|
@ -1,12 +1,26 @@
|
|||
<div class="tab-section">
|
||||
{{#let (hash
|
||||
searchproperties=(if (not-eq searchproperty undefined)
|
||||
{{#let
|
||||
|
||||
(hash
|
||||
value=(or sortBy "DestinationName:asc")
|
||||
change=(action (mut sortBy) value="target.selected")
|
||||
)
|
||||
|
||||
(hash
|
||||
searchproperty=(hash
|
||||
value=(if (not-eq searchproperty undefined)
|
||||
(split searchproperty ',')
|
||||
searchProperties
|
||||
)
|
||||
) as |filters|}}
|
||||
{{#let (or sortBy "DestinationName:asc") as |sort|}}
|
||||
{{#if (gt proxy.Service.Proxy.Upstreams.length 0)}}
|
||||
change=(action (mut searchproperty) value="target.selectedItems")
|
||||
default=searchProperties
|
||||
)
|
||||
)
|
||||
|
||||
proxy.Service.Proxy.Upstreams
|
||||
|
||||
as |sort filters items|}}
|
||||
{{#if (gt items.length 0)}}
|
||||
<input type="checkbox" id="toolbar-toggle" />
|
||||
<Consul::UpstreamInstance::SearchBar
|
||||
@search={{search}}
|
||||
|
@ -14,20 +28,16 @@
|
|||
@searchproperties={{searchProperties}}
|
||||
|
||||
@sort={{sort}}
|
||||
@onsort={{action (mut sortBy) value="target.selected"}}
|
||||
|
||||
@filter={{filters}}
|
||||
@onfilter={{hash
|
||||
searchproperty=(action (mut searchproperty) value="target.selectedItems")
|
||||
}}
|
||||
/>
|
||||
{{/if}}
|
||||
<DataCollection
|
||||
@type="upstream-instance"
|
||||
@sort={{sort}}
|
||||
@sort={{sort.value}}
|
||||
@filters={{filters}}
|
||||
@search={{search}}
|
||||
@items={{proxy.Service.Proxy.Upstreams}}
|
||||
@items={{items}}
|
||||
as |collection|>
|
||||
<collection.Collection>
|
||||
<Consul::UpstreamInstance::List
|
||||
|
@ -40,12 +50,11 @@
|
|||
<EmptyState>
|
||||
<BlockSlot @name="body">
|
||||
<p>
|
||||
This service has no upstreams{{#if (gt proxy.Service.Proxy.Upstreams.length 0)}} matching that search{{/if}}.
|
||||
This service has no upstreams{{#if (gt items.length 0)}} matching that search{{/if}}.
|
||||
</p>
|
||||
</BlockSlot>
|
||||
</EmptyState>
|
||||
</collection.Empty>
|
||||
</DataCollection>
|
||||
{{/let}}
|
||||
{{/let}}
|
||||
</div>
|
|
@ -1,36 +1,49 @@
|
|||
<div class="tab-section">
|
||||
{{#let (hash
|
||||
statuses=(if status (split status ',') undefined)
|
||||
sources=(if source (split source ',') undefined)
|
||||
searchproperties=(if (not-eq searchproperty undefined)
|
||||
{{#let
|
||||
|
||||
(hash
|
||||
value=(or sortBy "Status:asc")
|
||||
change=(action (mut sortBy) value="target.selected")
|
||||
)
|
||||
|
||||
(hash
|
||||
status=(hash
|
||||
value=(if status (split status ',') undefined)
|
||||
change=(action (mut status) value="target.selectedItems")
|
||||
)
|
||||
source=(hash
|
||||
value=(if source (split source ',') undefined)
|
||||
change=(action (mut source) value="target.selectedItems")
|
||||
)
|
||||
searchproperty=(hash
|
||||
value=(if (not-eq searchproperty undefined)
|
||||
(split searchproperty ',')
|
||||
searchProperties
|
||||
)
|
||||
) as |filters|}}
|
||||
{{#let (or sortBy "Status:asc") as |sort|}}
|
||||
change=(action (mut searchproperty) value="target.selectedItems")
|
||||
default=searchProperties
|
||||
)
|
||||
)
|
||||
|
||||
items
|
||||
|
||||
as |sort filters items|}}
|
||||
{{#if (gt items.length 0) }}
|
||||
<input type="checkbox" id="toolbar-toggle" />
|
||||
<Consul::ServiceInstance::SearchBar
|
||||
@sources={{get (collection items) 'ExternalSources'}}
|
||||
@search={{search}}
|
||||
@onsearch={{action (mut search) value="target.value"}}
|
||||
@searchproperties={{searchProperties}}
|
||||
|
||||
@sort={{sort}}
|
||||
@onsort={{action (mut sortBy) value="target.selected"}}
|
||||
|
||||
@filter={{filters}}
|
||||
@onfilter={{hash
|
||||
searchproperty=(action (mut searchproperty) value="target.selectedItems")
|
||||
status=(action (mut status) value="target.selectedItems")
|
||||
source=(action (mut source) value="target.selectedItems")
|
||||
}}
|
||||
/>
|
||||
{{/if}}
|
||||
{{! Service > Service Instance view doesn't require filtering of proxies }}
|
||||
<DataCollection
|
||||
@type="service-instance"
|
||||
@sort={{sort}}
|
||||
@sort={{sort.value}}
|
||||
@filters={{filters}}
|
||||
@search={{search}}
|
||||
@items={{items}}
|
||||
|
@ -51,6 +64,5 @@
|
|||
</EmptyState>
|
||||
</collection.Empty>
|
||||
</DataCollection>
|
||||
{{/let}}
|
||||
{{/let}}
|
||||
</div>
|
||||
|
|
|
@ -12,15 +12,31 @@ as |api|>
|
|||
<ErrorState @error={{api.error}} />
|
||||
</BlockSlot>
|
||||
<BlockSlot @name="loaded">
|
||||
{{#let api.data as |items|}}
|
||||
{{#let (hash
|
||||
accesses=(if access (split access ',') undefined)
|
||||
searchproperties=(if (not-eq searchproperty undefined)
|
||||
(split searchproperty ',')
|
||||
(array 'SourceName' 'DestinationName')
|
||||
{{#let
|
||||
|
||||
(hash
|
||||
value=(or sortBy "Action:asc")
|
||||
change=(action (mut sortBy) value="target.selected")
|
||||
)
|
||||
) as |filters|}}
|
||||
{{#let (or sortBy "Action:asc") as |sort|}}
|
||||
|
||||
(hash
|
||||
access=(hash
|
||||
value=(if access (split access ',') undefined)
|
||||
change=(action (mut access) value="target.selectedItems")
|
||||
)
|
||||
searchproperty=(hash
|
||||
value=(if (not-eq searchproperty undefined)
|
||||
(split searchproperty ',')
|
||||
searchProperties
|
||||
)
|
||||
change=(action (mut searchproperty) value="target.selectedItems")
|
||||
default=searchProperties
|
||||
)
|
||||
)
|
||||
|
||||
api.data
|
||||
|
||||
as |sort filters items|}}
|
||||
<div class="tab-section">
|
||||
<Portal @target="app-view-actions">
|
||||
<a data-test-create href={{href-to 'dc.services.show.intentions.create'}} class="type-create">Create</a>
|
||||
|
@ -31,13 +47,8 @@ as |api|>
|
|||
@onsearch={{action (mut search) value="target.value"}}
|
||||
|
||||
@sort={{sort}}
|
||||
@onsort={{action (mut sortBy) value="target.selected"}}
|
||||
|
||||
@filter={{filters}}
|
||||
@onfilter={{hash
|
||||
searchproperty=(action (mut searchproperty) value="target.selectedItems")
|
||||
access=(action (mut access) value="target.selectedItems")
|
||||
}}
|
||||
/>
|
||||
{{/if}}
|
||||
|
||||
|
@ -49,7 +60,7 @@ as |api|>
|
|||
<BlockSlot @name="content">
|
||||
<DataCollection
|
||||
@type="intention"
|
||||
@sort={{sort}}
|
||||
@sort={{sort.value}}
|
||||
@filters={{filters}}
|
||||
@search={{search}}
|
||||
@items={{items}}
|
||||
|
@ -78,8 +89,6 @@ as |api|>
|
|||
</BlockSlot>
|
||||
</DataWriter>
|
||||
</div>
|
||||
{{/let}}
|
||||
{{/let}}
|
||||
{{/let}}
|
||||
</BlockSlot>
|
||||
</DataLoader>
|
||||
|
|
|
@ -1,27 +1,39 @@
|
|||
<EventSource @src={{gatewayServices}} />
|
||||
<EventSource @src={{items}} />
|
||||
<div class="tab-section">
|
||||
{{#let (hash
|
||||
instances=(if instance (split instance ',') undefined)
|
||||
searchproperties=(if (not-eq searchproperty undefined)
|
||||
(split searchproperty ',')
|
||||
(array 'Name' 'Tags')
|
||||
{{#let
|
||||
|
||||
(hash
|
||||
value=(or sortBy "Status:asc")
|
||||
change=(action (mut sortBy) value="target.selected")
|
||||
)
|
||||
) as |filters|}}
|
||||
{{#let (or sortBy "Name:asc") as |sort|}}
|
||||
{{#if (gt gatewayServices.length 0)}}
|
||||
|
||||
(hash
|
||||
instance=(hash
|
||||
value=(if instance (split instance ',') undefined)
|
||||
change=(action (mut instance) value="target.selectedItems")
|
||||
)
|
||||
searchproperty=(hash
|
||||
value=(if (not-eq searchproperty undefined)
|
||||
(split searchproperty ',')
|
||||
searchProperties
|
||||
)
|
||||
change=(action (mut searchproperty) value="target.selectedItems")
|
||||
default=searchProperties
|
||||
)
|
||||
)
|
||||
|
||||
items
|
||||
|
||||
as |sort filters items|}}
|
||||
{{#if (gt items.length 0)}}
|
||||
<input type="checkbox" id="toolbar-toggle" />
|
||||
<Consul::Upstream::SearchBar
|
||||
@search={{search}}
|
||||
@onsearch={{action (mut search) value="target.value"}}
|
||||
|
||||
@sort={{sort}}
|
||||
@onsort={{action (mut sortBy) value="target.selected"}}
|
||||
|
||||
@filter={{filters}}
|
||||
@onfilter={{hash
|
||||
searchproperty=(action (mut searchproperty) value="target.selectedItems")
|
||||
instance=(action (mut instance) value="target.selectedItems")
|
||||
}}
|
||||
/>
|
||||
{{/if}}
|
||||
<p>
|
||||
|
@ -30,10 +42,10 @@
|
|||
</p>
|
||||
<DataCollection
|
||||
@type="service"
|
||||
@sort={{sort}}
|
||||
@sort={{sort.value}}
|
||||
@filters={{filters}}
|
||||
@search={{search}}
|
||||
@items={{gatewayServices}}
|
||||
@items={{items}}
|
||||
as |collection|>
|
||||
<collection.Collection>
|
||||
<Consul::Service::List
|
||||
|
@ -46,12 +58,11 @@
|
|||
<EmptyState>
|
||||
<BlockSlot @name="body">
|
||||
<p>
|
||||
There are no linked services{{#if (gt gatewayServices.length 0)}} matching that search{{/if}}.
|
||||
There are no linked services{{#if (gt items.length 0)}} matching that search{{/if}}.
|
||||
</p>
|
||||
</BlockSlot>
|
||||
</EmptyState>
|
||||
</collection.Empty>
|
||||
</DataCollection>
|
||||
{{/let}}
|
||||
{{/let}}
|
||||
</div>
|
||||
|
|
|
@ -1,27 +1,39 @@
|
|||
<EventSource @src={{gatewayServices}} />
|
||||
<EventSource @src={{items}} />
|
||||
<div class="tab-section">
|
||||
{{#let (hash
|
||||
instances=(if instance (split instance ',') undefined)
|
||||
searchproperties=(if (not-eq searchproperty undefined)
|
||||
(split searchproperty ',')
|
||||
(array 'Name' 'Tags')
|
||||
{{#let
|
||||
|
||||
(hash
|
||||
value=(or sortBy "Status:asc")
|
||||
change=(action (mut sortBy) value="target.selected")
|
||||
)
|
||||
) as |filters|}}
|
||||
{{#let (or sortBy "Status:asc") as |sort|}}
|
||||
{{#if (gt gatewayServices.length 0)}}
|
||||
|
||||
(hash
|
||||
instance=(hash
|
||||
value=(if instance (split instance ',') undefined)
|
||||
change=(action (mut instance) value="target.selectedItems")
|
||||
)
|
||||
searchproperty=(hash
|
||||
value=(if (not-eq searchproperty undefined)
|
||||
(split searchproperty ',')
|
||||
searchProperties
|
||||
)
|
||||
change=(action (mut searchproperty) value="target.selectedItems")
|
||||
default=searchProperties
|
||||
)
|
||||
)
|
||||
|
||||
items
|
||||
|
||||
as |sort filters items|}}
|
||||
{{#if (gt items.length 0)}}
|
||||
<input type="checkbox" id="toolbar-toggle" />
|
||||
<Consul::Upstream::SearchBar
|
||||
@search={{search}}
|
||||
@onsearch={{action (mut search) value="target.value"}}
|
||||
|
||||
@sort={{sort}}
|
||||
@onsort={{action (mut sortBy) value="target.selected"}}
|
||||
|
||||
@filter={{filters}}
|
||||
@onfilter={{hash
|
||||
searchproperty=(action (mut searchproperty) value="target.selectedItems")
|
||||
instance=(action (mut instance) value="target.selectedItems")
|
||||
}}
|
||||
/>
|
||||
{{/if}}
|
||||
<p>
|
||||
|
@ -29,10 +41,10 @@
|
|||
</p>
|
||||
<DataCollection
|
||||
@type="service"
|
||||
@sort={{sort}}
|
||||
@sort={{sort.value}}
|
||||
@filters={{filters}}
|
||||
@search={{search}}
|
||||
@items={{gatewayServices}}
|
||||
@items={{items}}
|
||||
as |collection|>
|
||||
<collection.Collection>
|
||||
<Consul::Upstream::List
|
||||
|
@ -46,12 +58,11 @@
|
|||
<EmptyState>
|
||||
<BlockSlot @name="body">
|
||||
<p>
|
||||
There are no upstreams{{#if (gt gatewayServices.length 0)}} matching that search{{/if}}.
|
||||
There are no upstreams{{#if (gt items.length 0)}} matching that search{{/if}}.
|
||||
</p>
|
||||
</BlockSlot>
|
||||
</EmptyState>
|
||||
</collection.Empty>
|
||||
</DataCollection>
|
||||
{{/let}}
|
||||
{{/let}}
|
||||
</div>
|
||||
|
|
|
@ -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');
|
||||
});
|
||||
});
|
|
@ -6,7 +6,6 @@ import {
|
|||
collection,
|
||||
text,
|
||||
isPresent,
|
||||
triggerable,
|
||||
} from 'ember-cli-page-object';
|
||||
|
||||
import { alias } from 'ember-cli-page-object/macros';
|
||||
|
@ -26,9 +25,7 @@ import pageFactory from 'consul-ui/components/hashicorp-consul/pageobject';
|
|||
import radiogroup from 'consul-ui/components/radio-group/pageobject';
|
||||
import tabgroup from 'consul-ui/components/tab-nav/pageobject';
|
||||
import authFormFactory from 'consul-ui/components/auth-form/pageobject';
|
||||
import freetextFilterFactory from 'consul-ui/components/freetext-filter/pageobject';
|
||||
|
||||
import searchBarFactory from 'consul-ui/components/search-bar/pageobject';
|
||||
import emptyStateFactory from 'consul-ui/components/empty-state/pageobject';
|
||||
|
||||
import policyFormFactory from 'consul-ui/components/policy-form/pageobject';
|
||||
|
@ -82,11 +79,6 @@ const cancelable = createCancelable(clickable, is);
|
|||
// components
|
||||
const tokenList = tokenListFactory(clickable, attribute, collection, deletable);
|
||||
const authForm = authFormFactory(submitable, clickable, attribute);
|
||||
const freetextFilter = freetextFilterFactory(triggerable);
|
||||
const catalogToolbar = searchBarFactory(freetextFilter);
|
||||
const aclFilter = searchBarFactory(freetextFilter, () =>
|
||||
radiogroup('type', ['', 'management', 'client'])
|
||||
);
|
||||
const policyForm = policyFormFactory(submitable, cancelable, radiogroup, text);
|
||||
const policySelector = policySelectorFactory(clickable, deletable, collection, alias, policyForm);
|
||||
const roleForm = roleFormFactory(submitable, cancelable, policySelector);
|
||||
|
@ -160,18 +152,7 @@ export default {
|
|||
radiogroup
|
||||
)
|
||||
),
|
||||
service: create(
|
||||
service(
|
||||
visitable,
|
||||
clickable,
|
||||
attribute,
|
||||
collection,
|
||||
text,
|
||||
consulIntentionList,
|
||||
catalogToolbar,
|
||||
tabgroup
|
||||
)
|
||||
),
|
||||
service: create(service(visitable, clickable, attribute, collection, text, consulIntentionList, tabgroup)),
|
||||
instance: create(
|
||||
instance(
|
||||
visitable,
|
||||
|
@ -199,7 +180,7 @@ export default {
|
|||
),
|
||||
kvs: create(kvs(visitable, creatable, consulKvList)),
|
||||
kv: create(kv(visitable, attribute, submitable, deletable, cancelable, clickable)),
|
||||
acls: create(acls(visitable, deletable, creatable, clickable, attribute, collection, aclFilter)),
|
||||
acls: create(acls(visitable, deletable, creatable, clickable, attribute, collection)),
|
||||
acl: create(acl(visitable, submitable, deletable, cancelable, clickable)),
|
||||
policies: create(policies(visitable, creatable, consulPolicyList, popoverSelect)),
|
||||
policy: create(policy(visitable, submitable, deletable, cancelable, clickable, tokenList)),
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
export default function(visitable, deletable, creatable, clickable, attribute, collection, filter) {
|
||||
export default function(visitable, deletable, creatable, clickable, attribute, collection) {
|
||||
return creatable({
|
||||
visit: visitable('/:dc/acls'),
|
||||
acls: collection(
|
||||
|
@ -11,6 +11,5 @@ export default function(visitable, deletable, creatable, clickable, attribute, c
|
|||
confirmUse: clickable('[data-test-confirm-use]'),
|
||||
})
|
||||
),
|
||||
filter: filter('[data-test-acl-filter]'),
|
||||
});
|
||||
}
|
||||
|
|
|
@ -1,13 +1,4 @@
|
|||
export default function(
|
||||
visitable,
|
||||
clickable,
|
||||
attribute,
|
||||
collection,
|
||||
text,
|
||||
intentions,
|
||||
filter,
|
||||
tabs
|
||||
) {
|
||||
export default function(visitable, clickable, attribute, collection, text, intentions, tabs) {
|
||||
const page = {
|
||||
visit: visitable('/:dc/services/:service'),
|
||||
externalSource: attribute('data-test-external-source', '[data-test-external-source]', {
|
||||
|
@ -28,7 +19,6 @@ export default function(
|
|||
'routing',
|
||||
'tags',
|
||||
]),
|
||||
filter: filter(),
|
||||
// TODO: These need to somehow move to subpages
|
||||
instances: collection('.consul-service-instance-list > ul > li:not(:first-child)', {
|
||||
address: text('[data-test-address]'),
|
||||
|
|
|
@ -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);
|
||||
});
|
||||
});
|
||||
});
|
|
@ -20,7 +20,7 @@ module('Unit | Filter | Predicates | intention', function() {
|
|||
expected = [items[0]];
|
||||
actual = items.filter(
|
||||
predicate({
|
||||
accesses: ['allow'],
|
||||
access: ['allow'],
|
||||
})
|
||||
);
|
||||
assert.deepEqual(actual, expected);
|
||||
|
@ -28,7 +28,7 @@ module('Unit | Filter | Predicates | intention', function() {
|
|||
expected = [items[1]];
|
||||
actual = items.filter(
|
||||
predicate({
|
||||
accesses: ['deny'],
|
||||
access: ['deny'],
|
||||
})
|
||||
);
|
||||
assert.deepEqual(actual, expected);
|
||||
|
@ -36,7 +36,7 @@ module('Unit | Filter | Predicates | intention', function() {
|
|||
expected = items;
|
||||
actual = items.filter(
|
||||
predicate({
|
||||
accesses: ['allow', 'deny'],
|
||||
access: ['allow', 'deny'],
|
||||
})
|
||||
);
|
||||
assert.deepEqual(actual, expected);
|
||||
|
|
|
@ -20,7 +20,7 @@ module('Unit | Filter | Predicates | service', function() {
|
|||
expected = [items[0]];
|
||||
actual = items.filter(
|
||||
predicate({
|
||||
instances: ['registered'],
|
||||
instance: ['registered'],
|
||||
})
|
||||
);
|
||||
assert.deepEqual(actual, expected);
|
||||
|
@ -28,7 +28,7 @@ module('Unit | Filter | Predicates | service', function() {
|
|||
expected = [items[1]];
|
||||
actual = items.filter(
|
||||
predicate({
|
||||
instances: ['not-registered'],
|
||||
instance: ['not-registered'],
|
||||
})
|
||||
);
|
||||
assert.deepEqual(actual, expected);
|
||||
|
@ -36,7 +36,7 @@ module('Unit | Filter | Predicates | service', function() {
|
|||
expected = items;
|
||||
actual = items.filter(
|
||||
predicate({
|
||||
instances: ['registered', 'not-registered'],
|
||||
instance: ['registered', 'not-registered'],
|
||||
})
|
||||
);
|
||||
assert.deepEqual(actual, expected);
|
||||
|
@ -60,7 +60,7 @@ module('Unit | Filter | Predicates | service', function() {
|
|||
expected = [items[0]];
|
||||
actual = items.filter(
|
||||
predicate({
|
||||
statuses: ['passing'],
|
||||
status: ['passing'],
|
||||
})
|
||||
);
|
||||
assert.deepEqual(actual, expected);
|
||||
|
@ -68,7 +68,7 @@ module('Unit | Filter | Predicates | service', function() {
|
|||
expected = [items[1]];
|
||||
actual = items.filter(
|
||||
predicate({
|
||||
statuses: ['warning'],
|
||||
status: ['warning'],
|
||||
})
|
||||
);
|
||||
assert.deepEqual(actual, expected);
|
||||
|
@ -76,7 +76,7 @@ module('Unit | Filter | Predicates | service', function() {
|
|||
expected = items;
|
||||
actual = items.filter(
|
||||
predicate({
|
||||
statuses: ['passing', 'warning', 'critical'],
|
||||
status: ['passing', 'warning', 'critical'],
|
||||
})
|
||||
);
|
||||
assert.deepEqual(actual, expected);
|
||||
|
@ -98,7 +98,7 @@ module('Unit | Filter | Predicates | service', function() {
|
|||
expected = [items[0]];
|
||||
actual = items.filter(
|
||||
predicate({
|
||||
kinds: ['ingress-gateway'],
|
||||
kind: ['ingress-gateway'],
|
||||
})
|
||||
);
|
||||
assert.deepEqual(actual, expected);
|
||||
|
@ -106,7 +106,7 @@ module('Unit | Filter | Predicates | service', function() {
|
|||
expected = [items[1]];
|
||||
actual = items.filter(
|
||||
predicate({
|
||||
kinds: ['mesh-gateway'],
|
||||
kind: ['mesh-gateway'],
|
||||
})
|
||||
);
|
||||
assert.deepEqual(actual, expected);
|
||||
|
@ -114,7 +114,7 @@ module('Unit | Filter | Predicates | service', function() {
|
|||
expected = items;
|
||||
actual = items.filter(
|
||||
predicate({
|
||||
kinds: ['ingress-gateway', 'mesh-gateway', 'service'],
|
||||
kind: ['ingress-gateway', 'mesh-gateway', 'service'],
|
||||
})
|
||||
);
|
||||
assert.deepEqual(actual, expected);
|
||||
|
@ -142,9 +142,9 @@ module('Unit | Filter | Predicates | service', function() {
|
|||
expected = [items[0]];
|
||||
actual = items.filter(
|
||||
predicate({
|
||||
kinds: ['ingress-gateway'],
|
||||
statuses: ['passing'],
|
||||
instances: ['registered'],
|
||||
kind: ['ingress-gateway'],
|
||||
status: ['passing'],
|
||||
instance: ['registered'],
|
||||
})
|
||||
);
|
||||
assert.deepEqual(actual, expected);
|
||||
|
@ -152,9 +152,9 @@ module('Unit | Filter | Predicates | service', function() {
|
|||
expected = [items[1]];
|
||||
actual = items.filter(
|
||||
predicate({
|
||||
kinds: ['mesh-gateway'],
|
||||
statuses: ['warning'],
|
||||
instances: ['registered'],
|
||||
kind: ['mesh-gateway'],
|
||||
status: ['warning'],
|
||||
instance: ['registered'],
|
||||
})
|
||||
);
|
||||
assert.deepEqual(actual, expected);
|
||||
|
@ -162,9 +162,9 @@ module('Unit | Filter | Predicates | service', function() {
|
|||
expected = items;
|
||||
actual = items.filter(
|
||||
predicate({
|
||||
kinds: ['ingress-gateway', 'mesh-gateway', 'service'],
|
||||
statuses: ['passing', 'warning', 'critical'],
|
||||
instances: ['registered', 'not-registered'],
|
||||
kind: ['ingress-gateway', 'mesh-gateway', 'service'],
|
||||
status: ['passing', 'warning', 'critical'],
|
||||
instance: ['registered', 'not-registered'],
|
||||
})
|
||||
);
|
||||
assert.deepEqual(actual, 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