Better empty state copy
This commit is contained in:
parent
70a12dcde6
commit
1a5e6fdce9
|
@ -1,5 +1,6 @@
|
|||
import Component from '@ember/component';
|
||||
|
||||
export default Component.extend({
|
||||
classNames: ['empty-state box is-sideless is-marginless is-fullwidth is-bottomless']
|
||||
title: null,
|
||||
classNames: ['empty-state box is-sideless is-marginless is-fullwidth is-bottomless'],
|
||||
});
|
||||
|
|
|
@ -7,8 +7,12 @@ export default Component.extend({
|
|||
items: null,
|
||||
itemNoun: 'item',
|
||||
|
||||
emptyTitle: computed('itemNoun', function() {
|
||||
let items = pluralize(this.get('itemNoun'));
|
||||
return `No ${items} yet`;
|
||||
}),
|
||||
emptyMessage: computed('itemNoun', function() {
|
||||
let items = pluralize(this.get('itemNoun'));
|
||||
return `There are currently no ${items}`;
|
||||
}),
|
||||
return `Your ${items} will be listed here. Add your first ${this.get('itemNoun')} to get started.`;
|
||||
})
|
||||
});
|
||||
|
|
|
@ -5,7 +5,7 @@ import { assign } from '@ember/polyfills';
|
|||
const DEFAULT_DISPLAY = {
|
||||
searchPlaceholder: 'Filter secrets',
|
||||
item: 'secret',
|
||||
create: 'Create secret',
|
||||
create: 'Add secret',
|
||||
navigateTree: true,
|
||||
editComponent: 'secret-edit',
|
||||
listItemPartial: 'partials/secret-list/item',
|
||||
|
@ -15,7 +15,7 @@ const SECRET_BACKENDS = {
|
|||
displayName: 'AWS',
|
||||
searchPlaceholder: 'Filter roles',
|
||||
item: 'role',
|
||||
create: 'Create role',
|
||||
create: 'Add role',
|
||||
navigateTree: false,
|
||||
editComponent: 'role-aws-edit',
|
||||
listItemPartial: 'partials/secret-list/aws-role-item',
|
||||
|
@ -30,7 +30,7 @@ const SECRET_BACKENDS = {
|
|||
label: 'Roles',
|
||||
searchPlaceholder: 'Filter roles',
|
||||
item: 'role',
|
||||
create: 'Create role',
|
||||
create: 'Add role',
|
||||
editComponent: 'role-pki-edit',
|
||||
},
|
||||
{
|
||||
|
@ -39,7 +39,7 @@ const SECRET_BACKENDS = {
|
|||
label: 'Certificates',
|
||||
searchPlaceholder: 'Filter certificates',
|
||||
item: 'certificates',
|
||||
create: 'Create role',
|
||||
create: 'Add role',
|
||||
tab: 'certs',
|
||||
listItemPartial: 'partials/secret-list/pki-cert-item',
|
||||
editComponent: 'pki-cert-show',
|
||||
|
@ -50,7 +50,7 @@ const SECRET_BACKENDS = {
|
|||
displayName: 'SSH',
|
||||
searchPlaceholder: 'Filter roles',
|
||||
item: 'role',
|
||||
create: 'Create role',
|
||||
create: 'Add role',
|
||||
navigateTree: false,
|
||||
editComponent: 'role-ssh-edit',
|
||||
listItemPartial: 'partials/secret-list/ssh-role-item',
|
||||
|
@ -58,7 +58,7 @@ const SECRET_BACKENDS = {
|
|||
transit: {
|
||||
searchPlaceholder: 'Filter keys',
|
||||
item: 'key',
|
||||
create: 'Create encryption key',
|
||||
create: 'Add encryption key',
|
||||
navigateTree: false,
|
||||
editComponent: 'transit-edit',
|
||||
listItemPartial: 'partials/secret-list/item',
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
<div class="empty-state-content">
|
||||
<h3 class="empty-state-title">
|
||||
{{{title}}}
|
||||
{{title}}
|
||||
</h3>
|
||||
{{#if message}}
|
||||
<p class="empty-state-message">
|
||||
{{{message}}}
|
||||
{{message}}
|
||||
</p>
|
||||
{{/if}}
|
||||
{{#if hasBlock}}
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
<EmptyState
|
||||
@title="No metadata for {{model.name}} yet"
|
||||
@message="You can store custom data that you want to associate with a {{lowercase (humanize model.identityType)}}. Edit this {{lowercase (humanize model.identityType)}} to get started.">
|
||||
{{#link-to "vault.cluster.access.identity.aliases.edit" model.id tagName="button" class="link"}}
|
||||
{{#link-to "vault.cluster.access.identity.aliases.edit" model.id tagName="button" class="link"}}
|
||||
Edit {{lowercase (humanize model.identityType)}}
|
||||
{{/link-to}}
|
||||
<DocLink @href="https://learn.hashicorp.com/vault/identity-access-management/iam-identity">
|
||||
|
|
|
@ -29,6 +29,6 @@
|
|||
{{/linked-block}}
|
||||
{{else}}
|
||||
<EmptyState
|
||||
@title="There are no {{model.identityType}} aliases for {{model.name}}"
|
||||
@title="No {{model.identityType}} aliases for {{model.name}} yet"
|
||||
/>
|
||||
{{/each}}
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
</div>
|
||||
{{else}}
|
||||
<EmptyState
|
||||
@title={{emptyMessage}}
|
||||
@title={{emptyTitle}}
|
||||
@message={{emptyMessage}}
|
||||
/>
|
||||
{{/if}}
|
||||
|
|
|
@ -1,11 +1,20 @@
|
|||
{{#if (and isV2 modelForData.destroyed)}}
|
||||
<EmptyState
|
||||
@title="Version {{modelForData.version}} of this secret has been permanently destroyed."
|
||||
/>
|
||||
@title="Version {{modelForData.version}} of this secret has been permanently destroyed"
|
||||
@message="A version that has been permanently deleted cannot be restored. You can see other versions of this secret in the History menu.">
|
||||
<DocLink @href="https://www.vaultproject.io/docs/secrets/kv/kv-v2.html">
|
||||
Learn More
|
||||
</DocLink>
|
||||
</EmptyState>
|
||||
{{else if (and isV2 modelForData.deleted)}}
|
||||
<EmptyState
|
||||
@title="Version {{modelForData.version}} of this secret has been deleted."
|
||||
/>
|
||||
@title="Version {{modelForData.version}} of this secret has been deleted"
|
||||
@message="A version that has been deleted but can be undeleted using the Version {{modelForData.version}} menu above.
|
||||
You can also see other versions of this secret in the History menu.">
|
||||
<DocLink @href="https://www.vaultproject.io/docs/secrets/kv/kv-v2.html">
|
||||
Learn More
|
||||
</DocLink>
|
||||
</EmptyState>
|
||||
{{else}}
|
||||
{{#if showAdvancedMode}}
|
||||
{{json-editor
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
{{identity/entity-nav identityType=identityType}}
|
||||
{{identity/entity-nav identityType=identityType model=model}}
|
||||
{{#if model.meta.total}}
|
||||
{{#each model as |item|}}
|
||||
{{#linked-block
|
||||
|
|
|
@ -10,32 +10,30 @@
|
|||
{{model.message}}
|
||||
{{/unless}}
|
||||
|
||||
<div class="box is-sideless is-fullwidth is-marginless">
|
||||
{{#if (eq model.httpStatus 400)}}
|
||||
{{#if (eq model.httpStatus 400)}}
|
||||
<AlertBanner
|
||||
@type="danger"
|
||||
@message="{{model.keyId}} is not a valid lease ID"
|
||||
/>
|
||||
{{else if (eq model.httpStatus 404)}}
|
||||
<EmptyState
|
||||
@title="No leases with that ID"
|
||||
@message="Unable to find lease for the ID "{{model.keyId}}". Try going back to the lookup and re-entering the ID."
|
||||
>
|
||||
{{#link-to "vault.cluster.access.leases" tagName="button" class="link"}}Back to lookup{{/link-to}}
|
||||
</EmptyState>
|
||||
{{else if (eq model.httpStatus 403)}}
|
||||
<EmptyState
|
||||
@title="You don't have access to a lease with that ID"
|
||||
@message="If you think you've reached this page in error, please contact your administrator."
|
||||
>
|
||||
{{#link-to "vault.cluster.access.leases" tagName="button" class="link"}}Back to lookup{{/link-to}}
|
||||
</EmptyState>
|
||||
{{else}}
|
||||
{{#each model.errors as |error|}}
|
||||
<AlertBanner
|
||||
@type="danger"
|
||||
@message="{{model.keyId}} is not a valid lease ID"
|
||||
@message={{error}}
|
||||
/>
|
||||
{{else if (eq model.httpStatus 404)}}
|
||||
<p class="message">
|
||||
Unable to find lease for the <code>id</code>: <code>{{model.keyId}}</code>. Try going back to the
|
||||
{{#link-to "vault.cluster.access.leases"}}lookup{{/link-to}}
|
||||
and re-entering the <code>id</code>.
|
||||
</p>
|
||||
{{else if (eq model.httpStatus 403)}}
|
||||
<p class="message">
|
||||
You don't have access to <code>{{model.keyId}}</code>. If you think you've reached this page in error, please contact your administrator.
|
||||
</p>
|
||||
{{else}}
|
||||
{{#each model.errors as |error|}}
|
||||
<p class="message">
|
||||
{{error}}
|
||||
</p>
|
||||
{{/each}}
|
||||
{{/if}}
|
||||
</div>
|
||||
<div class="field is-grouped box is-fullwidth is-bottomless">
|
||||
{{#link-to "vault.cluster.access.leases" class="button"}}
|
||||
Back
|
||||
{{/link-to}}
|
||||
</div>
|
||||
{{/each}}
|
||||
{{/if}}
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
</p.levelLeft>
|
||||
<p.levelRight>
|
||||
{{#link-to 'vault.cluster.access.namespaces.create' class="button has-icon-right is-ghost is-compact"}}
|
||||
Create a namespace
|
||||
Add namespace
|
||||
<ICon @glyph="chevron-right" @size=11 />
|
||||
{{/link-to}}
|
||||
</p.levelRight>
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
</div>
|
||||
{{else}}
|
||||
<EmptyState
|
||||
@title="The secondary <code>{{model.config.id}}</code> does not currently have performance mount filtering configured"
|
||||
@title="Performance Mount Filtering is not configured for this secondary"
|
||||
/>
|
||||
{{/if}}
|
||||
<div class="field is-fullwidth box is-shadowless">
|
||||
|
|
|
@ -48,7 +48,7 @@
|
|||
{{else}}
|
||||
<EmptyState
|
||||
@title="No known {{performanceMode}} secondary clusters associated with this cluster"
|
||||
@message="A list of secondary clusters will be listed here. Add your first secondary cluster to get started.">
|
||||
@message="Associated secondary clusters will be listed here. Add your first secondary cluster to get started.">
|
||||
{{#if model.canAddSecondary}}
|
||||
{{#link-to 'vault.cluster.replication.mode.secondaries.add' model.name replicationMode tagName="button" class="link" }}
|
||||
Add secondary
|
||||
|
|
|
@ -55,16 +55,34 @@
|
|||
{{/if}}
|
||||
{{else}}
|
||||
<div class="empty-state">
|
||||
<div class="empty-state-title">
|
||||
<div class="empty-state-content">
|
||||
{{#if (eq baseKey.id '')}}
|
||||
There are currently no {{pluralize options.item}} in this backend.
|
||||
<div class="empty-state-title">
|
||||
No {{pluralize options.item}} in this backend yet
|
||||
</div>
|
||||
<div class="empty-state-message">
|
||||
Secrets in this backend will be listed here. Add a secret to get started.
|
||||
</div>
|
||||
<div class="empty-state-actions">
|
||||
{{#secret-link
|
||||
mode="create"
|
||||
secret=''
|
||||
queryParams=(query-params initialKey=(or filter baseKey.id))
|
||||
class="link"
|
||||
data-test-secret-create=true
|
||||
}}
|
||||
{{options.create}}
|
||||
{{/secret-link}}
|
||||
</div>
|
||||
{{else}}
|
||||
{{#if filterIsFolder}}
|
||||
<div class="empty-state-title">
|
||||
{{#if (eq filter baseKey.id)}}
|
||||
There are no {{pluralize options.item}} under <code>{{or filter}}</code>.
|
||||
No {{pluralize options.item}} under <code>{{or filter}}</code>
|
||||
{{else}}
|
||||
We couldn't find a folder matching <code>{{filter}}</code>.
|
||||
No folders matching <code>{{filter}}</code>
|
||||
{{/if}}
|
||||
</div>
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
</div>
|
||||
|
|
|
@ -30,6 +30,6 @@
|
|||
</div>
|
||||
{{else}}
|
||||
<EmptyState
|
||||
@title="The token you are currently authenticated with does not have sufficient capabilities to seal this vault"
|
||||
@title="This token does not have sufficient capabilities to seal this vault"
|
||||
/>
|
||||
{{/if}}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { module, test } from 'qunit';
|
||||
import { setupRenderingTest } from 'ember-qunit';
|
||||
import { render } from '@ember/test-helpers';
|
||||
import { render, find } from '@ember/test-helpers';
|
||||
import hbs from 'htmlbars-inline-precompile';
|
||||
|
||||
module('Integration | Component | empty-state', function(hooks) {
|
||||
|
@ -16,11 +16,28 @@ module('Integration | Component | empty-state', function(hooks) {
|
|||
|
||||
// Template block usage:
|
||||
await render(hbs`
|
||||
{{#empty-state}}
|
||||
template block text
|
||||
{{#empty-state
|
||||
title="Empty State Title"
|
||||
message="This is the empty state message"
|
||||
}}
|
||||
Actions Link
|
||||
{{/empty-state}}
|
||||
`);
|
||||
|
||||
assert.equal(this.element.textContent.trim(), 'template block text');
|
||||
assert.equal(
|
||||
find('.empty-state-title').textContent.trim(),
|
||||
'Empty State Title',
|
||||
'renders empty state title'
|
||||
);
|
||||
assert.equal(
|
||||
find('.empty-state-message').textContent.trim(),
|
||||
'This is the empty state message',
|
||||
'renders empty state message'
|
||||
);
|
||||
assert.equal(
|
||||
find('.empty-state-actions').textContent.trim(),
|
||||
'Actions Link',
|
||||
'renders empty state actions'
|
||||
);
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Reference in a new issue