John Cowen 94dd1849b4 ui: New Empty States (#7940)
* ui: CSS and component changes to the <EmptyState /> component

* ui: Reset the auth-form component back to its initial state

Moving forwards we are going to have the auth-form on the page all the
time, even when logged in (for relogging in purposes). This means the
auth-form will not always be removed from the DOM when you log in.

This sets the form back to its idle state before calling onsubmit

* ui: Make a public api for modal-dialog with a single close method

* ui : Move cache reset somewhere that makes more sense, + single refresh

1. Centralize cache resetting elsewhere, for now the store makes most
sense, although I would prefer the Repository class, so using the store
is temporary
2. We only need to refresh on login once, unless we have a differing
nspace

* ui: Ensure visibilitychange events are cleaned up

* ui: Only cache DataSource data if we have any, + only clear the cache

* ui: Add the modal login dialog to both unauth and auth views

This means we can 'relogin' when already logged in

* ui: Add new empty states

* ui: CSS Tweaks

* Remove marketing grays
2020-06-03 16:46:50 +00:00

87 lines
3.4 KiB
Handlebars

{{title 'Nodes'}}
<AppView @class="node list">
<BlockSlot @name="header">
<h1>
Nodes <em>{{format-number items.length}} total</em>
</h1>
<label for="toolbar-toggle"></label>
</BlockSlot>
<BlockSlot @name="toolbar">
{{#if (gt items.length 0) }}
<CatalogFilter @searchable={{array searchableHealthy searchableUnhealthy}} @search={{s}} @status={{filters.status}} @onchange={{action "filter"}} />
{{/if}}
</BlockSlot>
<BlockSlot @name="content">
{{#if (gt unhealthy.length 0) }}
<div class="unhealthy">
<h2>Unhealthy Nodes</h2>
<div>
{{! think about 2 differing views here }}
<ul>
<ChangeableSet @dispatcher={{searchableUnhealthy}}>
<BlockSlot @name="set" as |unhealthy|>
{{#each unhealthy as |item|}}
<HealthcheckedResource @tagName="li" @data-test-node={{item.Node}} @href={{href-to "dc.nodes.show" item.Node}} @name={{item.Node}} @address={{item.Address}} @checks={{item.Checks}}>
<BlockSlot @name="icon">
{{#if (eq item.Address leader.Address)}}
<span data-test-leader={{leader.Address}} data-tooltip="Leader">Leader</span>
{{/if}}
</BlockSlot>
</HealthcheckedResource>
{{/each}}
</BlockSlot>
<BlockSlot @name="empty">
<p>
There are no unhealthy nodes for that search.
</p>
</BlockSlot>
</ChangeableSet>
</ul>
</div>
</div>
{{/if}}
{{#if (gt healthy.length 0) }}
<div class="healthy">
<h2>Healthy Nodes</h2>
<ChangeableSet @dispatcher={{searchableHealthy}}>
<BlockSlot @name="set" as |healthy|>
<GridCollection @cellHeight={{92}} @items={{healthy}} as |item index|>
<HealthcheckedResource @data-test-node={{item.Node}} @href={{href-to "dc.nodes.show" item.Node}} @name={{item.Node}} @address={{item.Address}} @checks={{item.Checks}}>
<BlockSlot @name="icon">
{{#if (eq item.Address leader.Address)}}
<span data-test-leader={{leader.Address}} data-tooltip="Leader">Leader</span>
{{/if}}
</BlockSlot>
</HealthcheckedResource>
</GridCollection>
</BlockSlot>
<BlockSlot @name="empty">
<p>
There are no healthy nodes for that search.
</p>
</BlockSlot>
</ChangeableSet>
</div>
{{/if}}
{{#if (and (eq healthy.length 0) (eq unhealthy.length 0)) }}
<EmptyState @allowLogin={{true}}>
<BlockSlot @name="header">
<h2>Welcome to Nodes</h2>
</BlockSlot>
<BlockSlot @name="body">
<p>
There don't seem to be any nodes, or you may not have access to view nodes yet.
</p>
</BlockSlot>
<BlockSlot @name="actions">
<li class="docs-link">
<a href="{{env 'CONSUL_DOCS_URL'}}" rel="noopener noreferrer" target="_blank">Documentation on nodes</a>
</li>
<li class="learn-link">
<a href="{{env 'CONSUL_DOCS_LEARN_URL'}}/consul/" rel="noopener noreferrer" target="_blank">Read the guide</a>
</li>
</BlockSlot>
</EmptyState>
{{/if}}
</BlockSlot>
</AppView>