ui: Various empty state improvements/fixups (#11892)
* ui: Add login button to per service intentions for zero results * Add login button and consistent header for when you have zero nodes * `services` doesn't exists use `items` consequently: Previous to this fix we would not show a more tailored message for when you empty result set was due to a user search rather than an empty result set straight from the backend * Fix `error` > `@error` in ErrorState plus code formatting and more docs * Changelog
This commit is contained in:
parent
acc7f572fd
commit
bb923d8705
|
@ -0,0 +1,3 @@
|
||||||
|
```release-note:bug
|
||||||
|
ui: Ensure a login buttons appear for some error states, plus text amends
|
||||||
|
```
|
|
@ -7,8 +7,11 @@ for more details.
|
||||||
Using this component for all of our errors means we can show a consistent
|
Using this component for all of our errors means we can show a consistent
|
||||||
error page for generic errors.
|
error page for generic errors.
|
||||||
|
|
||||||
This component show slighltly different visuals and copy depending on the
|
This component show slightly different visuals and copy depending on the
|
||||||
`status` of the error (the status is generally a HTTP error code)
|
`status` of the error (the status is generally a HTTP error code).
|
||||||
|
|
||||||
|
Please note: The examples below use a `hash` for demonstration purposes, you'll
|
||||||
|
probably just be using an `error` object in real-life.
|
||||||
|
|
||||||
## Arguments
|
## Arguments
|
||||||
|
|
||||||
|
@ -17,12 +20,26 @@ This component show slighltly different visuals and copy depending on the
|
||||||
| `login` | `Function` | `undefined` | A login action to call when the login button is pressed (if not provided no login button will be shown |
|
| `login` | `Function` | `undefined` | A login action to call when the login button is pressed (if not provided no login button will be shown |
|
||||||
| `error` | `Object` | `undefined` | 'Consul UI error shaped' JSON `{status: String, message: String, detail: String}` |
|
| `error` | `Object` | `undefined` | 'Consul UI error shaped' JSON `{status: String, message: String, detail: String}` |
|
||||||
|
|
||||||
|
Specifically 403 errors **always** use the same header/body copy, this is hardcoded in and not currently overridable.
|
||||||
|
|
||||||
```hbs preview-template
|
```hbs preview-template
|
||||||
<ErrorState
|
<ErrorState
|
||||||
@error={{hash status='403'}}
|
@error={{hash status='403'}}
|
||||||
/>
|
/>
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Other StatusCodes have a global default text but these *are* overridable by using the message/detail properties of the Consul UI shaped errors.
|
||||||
|
|
||||||
|
```hbs preview-template
|
||||||
|
<ErrorState
|
||||||
|
@error={{hash
|
||||||
|
status='404'
|
||||||
|
message="`message` is what is shown in the header"
|
||||||
|
detail="`detail` is what shown in the body"
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
```
|
||||||
|
|
||||||
As with `EmptyState` you can optionally chose to show a login button using the
|
As with `EmptyState` you can optionally chose to show a login button using the
|
||||||
`@login` argument.
|
`@login` argument.
|
||||||
|
|
||||||
|
|
|
@ -4,43 +4,63 @@
|
||||||
@login={{@login}}
|
@login={{@login}}
|
||||||
>
|
>
|
||||||
<BlockSlot @name="header">
|
<BlockSlot @name="header">
|
||||||
<h2>{{or @error.message "Consul returned an error"}}</h2>
|
<h2>
|
||||||
|
{{or @error.message "Consul returned an error"}}
|
||||||
|
</h2>
|
||||||
</BlockSlot>
|
</BlockSlot>
|
||||||
{{#if @error.status }}
|
{{#if @error.status }}
|
||||||
<BlockSlot @name="subheader">
|
<BlockSlot @name="subheader">
|
||||||
<h3 data-test-status={{@error.status}}>Error {{@error.status}}</h3>
|
<h3
|
||||||
|
data-test-status={{@error.status}}
|
||||||
|
>
|
||||||
|
Error {{@error.status}}
|
||||||
|
</h3>
|
||||||
</BlockSlot>
|
</BlockSlot>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
<BlockSlot @name="body">
|
<BlockSlot @name="body">
|
||||||
{{#if error.detail}}
|
<p>
|
||||||
<p>
|
{{#if @error.detail}}
|
||||||
{{error.detail}}
|
{{@error.detail}}
|
||||||
</p>
|
{{else}}
|
||||||
{{else}}
|
|
||||||
<p>
|
|
||||||
You may have visited a URL that is loading an unknown resource, so you can try going back to the root or try re-submitting your ACL Token/SecretID by going back to ACLs.
|
You may have visited a URL that is loading an unknown resource, so you can try going back to the root or try re-submitting your ACL Token/SecretID by going back to ACLs.
|
||||||
</p>
|
{{/if}}
|
||||||
{{/if}}
|
</p>
|
||||||
</BlockSlot>
|
</BlockSlot>
|
||||||
<BlockSlot @name="actions">
|
<BlockSlot @name="actions">
|
||||||
<li class="back-link">
|
<li class="back-link">
|
||||||
<a data-test-home rel="home" href={{href-to 'index'}}>Go back</a>
|
<Action
|
||||||
|
data-test-home
|
||||||
|
@href={{href-to 'index'}}
|
||||||
|
>
|
||||||
|
Go back
|
||||||
|
</Action>
|
||||||
</li>
|
</li>
|
||||||
<li class="docs-link">
|
<li class="docs-link">
|
||||||
<a href="{{env 'CONSUL_DOCS_URL'}}" rel="noopener noreferrer" target="_blank">Read the documentation</a>
|
<Action
|
||||||
|
@href="{{env 'CONSUL_DOCS_URL'}}"
|
||||||
|
@external={{true}}
|
||||||
|
>
|
||||||
|
Read the documentation
|
||||||
|
</Action>
|
||||||
</li>
|
</li>
|
||||||
</BlockSlot>
|
</BlockSlot>
|
||||||
</EmptyState>
|
</EmptyState>
|
||||||
{{else}}
|
{{else}}
|
||||||
<EmptyState
|
<EmptyState
|
||||||
class="status-403"
|
class={{concat "status-" @error.status}}
|
||||||
@login={{@login}}
|
@login={{@login}}
|
||||||
>
|
>
|
||||||
<BlockSlot @name="header">
|
<BlockSlot @name="header">
|
||||||
<h2 data-test-status={{@error.status}}>You are not authorized</h2>
|
<h2
|
||||||
|
data-test-status={{@error.status}}
|
||||||
|
>
|
||||||
|
You are not authorized
|
||||||
|
</h2>
|
||||||
</BlockSlot>
|
</BlockSlot>
|
||||||
<BlockSlot @name="subheader">
|
<BlockSlot @name="subheader">
|
||||||
<h3>Error 403</h3>
|
<h3>
|
||||||
|
Error {{@error.status}}
|
||||||
|
</h3>
|
||||||
</BlockSlot>
|
</BlockSlot>
|
||||||
<BlockSlot @name="body">
|
<BlockSlot @name="body">
|
||||||
<p>
|
<p>
|
||||||
|
@ -49,10 +69,20 @@
|
||||||
</BlockSlot>
|
</BlockSlot>
|
||||||
<BlockSlot @name="actions">
|
<BlockSlot @name="actions">
|
||||||
<li class="docs-link">
|
<li class="docs-link">
|
||||||
<a href="{{env 'CONSUL_DOCS_URL'}}/acl/index.html" rel="noopener noreferrer" target="_blank">Read the documentation</a>
|
<Action
|
||||||
|
@href="{{env 'CONSUL_DOCS_URL'}}/acl/index.html"
|
||||||
|
@external={{true}}
|
||||||
|
>
|
||||||
|
Read the documentation
|
||||||
|
</Action>
|
||||||
</li>
|
</li>
|
||||||
<li class="learn-link">
|
<li class="learn-link">
|
||||||
<a href="{{env 'CONSUL_DOCS_LEARN_URL'}}/consul/security-networking/production-acls" rel="noopener noreferrer" target="_blank">Follow the guide</a>
|
<Action
|
||||||
|
@href="{{env 'CONSUL_DOCS_LEARN_URL'}}/consul/security-networking/production-acls"
|
||||||
|
@external={{true}}
|
||||||
|
>
|
||||||
|
Follow the guide
|
||||||
|
</Action>
|
||||||
</li>
|
</li>
|
||||||
</BlockSlot>
|
</BlockSlot>
|
||||||
</EmptyState>
|
</EmptyState>
|
||||||
|
|
|
@ -90,7 +90,18 @@ as |route|>
|
||||||
/>
|
/>
|
||||||
</collection.Collection>
|
</collection.Collection>
|
||||||
<collection.Empty>
|
<collection.Empty>
|
||||||
<EmptyState>
|
<EmptyState
|
||||||
|
@login={{route.model.app.login.open}}
|
||||||
|
>
|
||||||
|
<BlockSlot @name="header">
|
||||||
|
<h2>
|
||||||
|
{{#if (gt items.length 0)}}
|
||||||
|
No nodes found
|
||||||
|
{{else}}
|
||||||
|
Welcome to Nodes
|
||||||
|
{{/if}}
|
||||||
|
</h2>
|
||||||
|
</BlockSlot>
|
||||||
<BlockSlot @name="body">
|
<BlockSlot @name="body">
|
||||||
<p>
|
<p>
|
||||||
There don't seem to be any registered nodes, or you may not have access to view nodes yet.
|
There don't seem to be any registered nodes, or you may not have access to view nodes yet.
|
||||||
|
|
|
@ -105,7 +105,7 @@ as |sort filters items partition nspace|}}
|
||||||
>
|
>
|
||||||
<BlockSlot @name="header">
|
<BlockSlot @name="header">
|
||||||
<h2>
|
<h2>
|
||||||
{{#if (gt services.length 0)}}
|
{{#if (gt items.length 0)}}
|
||||||
No services found
|
No services found
|
||||||
{{else}}
|
{{else}}
|
||||||
Welcome to Services
|
Welcome to Services
|
||||||
|
@ -114,7 +114,7 @@ as |sort filters items partition nspace|}}
|
||||||
</BlockSlot>
|
</BlockSlot>
|
||||||
<BlockSlot @name="body">
|
<BlockSlot @name="body">
|
||||||
<p>
|
<p>
|
||||||
{{#if (gt services.length 0)}}
|
{{#if (gt items.length 0)}}
|
||||||
No services where found matching that search, or you may not have access to view the services you are searching for.
|
No services where found matching that search, or you may not have access to view the services you are searching for.
|
||||||
{{else}}
|
{{else}}
|
||||||
There don't seem to be any registered services, or you may not have access to view services yet.
|
There don't seem to be any registered services, or you may not have access to view services yet.
|
||||||
|
|
|
@ -89,7 +89,9 @@ as |route|>
|
||||||
</Consul::Intention::List>
|
</Consul::Intention::List>
|
||||||
</collection.Collection>
|
</collection.Collection>
|
||||||
<collection.Empty>
|
<collection.Empty>
|
||||||
<EmptyState>
|
<EmptyState
|
||||||
|
@login={{route.model.app.login.open}}
|
||||||
|
>
|
||||||
<BlockSlot @name="header">
|
<BlockSlot @name="header">
|
||||||
<h2>
|
<h2>
|
||||||
{{#if (gt items.length 0)}}
|
{{#if (gt items.length 0)}}
|
||||||
|
|
Loading…
Reference in New Issue