Merge pull request #5758 from hashicorp/ui-empty-states
UI: Empty state styles
This commit is contained in:
commit
194c90a01d
|
@ -11,9 +11,10 @@ export default Component.extend({
|
|||
|
||||
target: '_blank',
|
||||
rel: 'noreferrer noopener',
|
||||
host: 'https://www.vaultproject.io',
|
||||
|
||||
path: '/',
|
||||
href: computed('path', function() {
|
||||
return `https://www.vaultproject.io${this.get('path')}`;
|
||||
href: computed('host', 'path', function() {
|
||||
return `${this.host}${this.path}`;
|
||||
}),
|
||||
});
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
import OuterHTML from './outer-html';
|
||||
|
||||
export default OuterHTML.extend({
|
||||
title: null,
|
||||
message: null,
|
||||
});
|
|
@ -0,0 +1,5 @@
|
|||
import DocLink from './doc-link';
|
||||
|
||||
export default DocLink.extend({
|
||||
host: 'https://learn.hashicorp.com',
|
||||
});
|
|
@ -6,9 +6,17 @@ export default Component.extend({
|
|||
tagName: '',
|
||||
items: null,
|
||||
itemNoun: 'item',
|
||||
// the dasherized name of a component to render
|
||||
// in the EmptyState component if there are no items in items.length
|
||||
emptyActions: '',
|
||||
|
||||
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.`;
|
||||
}),
|
||||
});
|
||||
|
|
|
@ -49,6 +49,21 @@ export default Controller.extend({
|
|||
return !!utils.keyIsFolder(this.get('filter'));
|
||||
}),
|
||||
|
||||
emptyTitle: computed('baseKey.id', 'filter', 'filterIsFolder', function() {
|
||||
let id = this.get('baseKey.id');
|
||||
let filter = this.filter;
|
||||
if (id === '') {
|
||||
return 'There are currently no leases.';
|
||||
}
|
||||
if (this.filterIsFolder) {
|
||||
if (filter === id) {
|
||||
return `There are no leases under "${filter}".`;
|
||||
} else {
|
||||
return `We couldn't find a prefix matching "${filter}".`;
|
||||
}
|
||||
}
|
||||
}),
|
||||
|
||||
actions: {
|
||||
setFilter(val) {
|
||||
this.set('filter', val);
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
.empty-state {
|
||||
align-items: center;
|
||||
color: $grey;
|
||||
display: flex;
|
||||
background: $ui-gray-050;
|
||||
justify-content: center;
|
||||
padding: $spacing-xxl $spacing-s;
|
||||
box-shadow: 0 -2px 0 -1px $ui-gray-300;
|
||||
}
|
||||
|
||||
.empty-state-content {
|
||||
max-width: 320px;
|
||||
}
|
||||
|
||||
.empty-state-title {
|
||||
color: $grey;
|
||||
font-size: $size-4;
|
||||
font-weight: $font-weight-semibold;
|
||||
line-height: 1.2;
|
||||
margin-bottom: $spacing-xs;
|
||||
}
|
||||
|
||||
.empty-state-actions {
|
||||
margin-top: $spacing-xs;
|
||||
|
||||
a,
|
||||
.link,
|
||||
a:not(.button):not(.file-delete-button):not(.tag) {
|
||||
color: $blue;
|
||||
font-size: $size-8;
|
||||
font-weight: $font-weight-semibold;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
> * + * {
|
||||
margin-left: $spacing-s;
|
||||
}
|
||||
}
|
|
@ -49,6 +49,7 @@
|
|||
@import "./components/console-ui-panel";
|
||||
@import "./components/control-group";
|
||||
@import "./components/doc-link";
|
||||
@import "./components/empty-state";
|
||||
@import "./components/env-banner";
|
||||
@import "./components/features-selection";
|
||||
@import "./components/form-section";
|
||||
|
|
|
@ -21,7 +21,7 @@ $ui-gray-050: #F7F8FA;
|
|||
$ui-gray-100: #EBEEF2;
|
||||
$ui-gray-200: #DCE0E6;
|
||||
$ui-gray-300: #BAC1CC;
|
||||
$ui-gray-500: #6a7786;
|
||||
$ui-gray-500: #6F7682;
|
||||
$ui-gray-700: #525761;
|
||||
$ui-gray-800: #373A42;
|
||||
$ui-gray-900: #1F2124;
|
||||
|
|
|
@ -1,11 +0,0 @@
|
|||
<div class="box is-bottomless has-background-white-bis">
|
||||
<div class="columns is-centered">
|
||||
<div class="column is-half has-text-centered">
|
||||
<div class="box is-shadowless has-background-white-bis">
|
||||
<p class="has-text-grey">
|
||||
{{yield}}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
|
@ -0,0 +1,7 @@
|
|||
{{#link-to "vault.cluster.access.namespaces.create"}}
|
||||
Create namespace
|
||||
{{/link-to}}
|
||||
|
||||
<LearnLink @path="/vault/security/namespaces">
|
||||
Learn More
|
||||
</LearnLink>
|
|
@ -0,0 +1,21 @@
|
|||
<div class="empty-state">
|
||||
<div class="empty-state-content">
|
||||
<h3 class="empty-state-title">
|
||||
{{title}}
|
||||
</h3>
|
||||
{{#if message}}
|
||||
<p class="empty-state-message">
|
||||
{{message}}
|
||||
</p>
|
||||
{{/if}}
|
||||
{{#if hasBlock}}
|
||||
<div class="empty-state-actions">
|
||||
{{yield}}
|
||||
</div>
|
||||
{{else if emptyActions}}
|
||||
<div class="empty-state-actions">
|
||||
{{component emptyActions}}
|
||||
</div>
|
||||
{{/if}}
|
||||
</div>
|
||||
</div>
|
|
@ -33,10 +33,12 @@
|
|||
</ul>
|
||||
</nav>
|
||||
</div>
|
||||
<div class="box is-sideless has-background-grey-lighter has-short-padding is-marginless">
|
||||
<div class="level">
|
||||
<div class="level-left">
|
||||
{{identity/lookup-input type=identityType}}
|
||||
{{#if model.meta.total}}
|
||||
<div class="box is-sideless has-background-grey-lighter has-short-padding is-marginless">
|
||||
<div class="level">
|
||||
<div class="level-left">
|
||||
{{identity/lookup-input type=identityType}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
|
|
|
@ -17,15 +17,15 @@
|
|||
</div>
|
||||
</div>
|
||||
{{else}}
|
||||
<div class="box is-bottomless has-background-white-bis">
|
||||
<div class="columns is-centered">
|
||||
<div class="column is-half has-text-centered">
|
||||
<div class="box is-shadowless has-background-white-bis">
|
||||
<p class="has-text-grey">
|
||||
There is no metadata associated with {{model.name}}.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<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"}}
|
||||
Edit {{lowercase (humanize model.identityType)}}
|
||||
{{/link-to}}
|
||||
<LearnLink @path="/vault/identity-access-management/iam-identity">
|
||||
Learn More
|
||||
</LearnLink>
|
||||
</EmptyState>
|
||||
{{/each-in}}
|
||||
|
|
|
@ -28,15 +28,7 @@
|
|||
</div>
|
||||
{{/linked-block}}
|
||||
{{else}}
|
||||
<div class="box is-bottomless has-background-white-bis">
|
||||
<div class="columns is-centered">
|
||||
<div class="column is-half has-text-centered">
|
||||
<div class="box is-shadowless has-background-white-bis">
|
||||
<p class="has-text-grey" data-test-no-entity-aliases-text>
|
||||
There are no {{model.identityType}} aliases for {{model.name}}.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<EmptyState
|
||||
@title="No {{model.identityType}} aliases for {{model.name}} yet"
|
||||
/>
|
||||
{{/each}}
|
||||
|
|
|
@ -25,15 +25,7 @@
|
|||
{{/linked-block}}
|
||||
{{/each}}
|
||||
{{else}}
|
||||
<div class="box is-bottomless has-background-white-bis">
|
||||
<div class="columns is-centered">
|
||||
<div class="column is-half has-text-centered">
|
||||
<div class="box is-shadowless has-background-white-bis">
|
||||
<p class="has-text-grey">
|
||||
{{model.name}} is not a member of any groups.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<EmptyState
|
||||
@title="{{model.name}} is not a member of any groups."
|
||||
/>
|
||||
{{/if}}
|
||||
|
|
|
@ -52,15 +52,7 @@
|
|||
{{/linked-block}}
|
||||
{{/each}}
|
||||
{{else}}
|
||||
<div class="box is-bottomless has-background-white-bis">
|
||||
<div class="columns is-centered">
|
||||
<div class="column is-half has-text-centered">
|
||||
<div class="box is-shadowless has-background-white-bis">
|
||||
<p class="has-text-grey">
|
||||
There are no members in this group.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<EmptyState
|
||||
@title="No members in this group yet"
|
||||
/>
|
||||
{{/if}}
|
||||
|
|
|
@ -14,15 +14,7 @@
|
|||
</div>
|
||||
</div>
|
||||
{{else}}
|
||||
<div class="box is-bottomless has-background-white-bis">
|
||||
<div class="columns is-centered">
|
||||
<div class="column is-half has-text-centered">
|
||||
<div class="box is-shadowless has-background-white-bis">
|
||||
<p class="has-text-grey">
|
||||
There is no metadata associated with {{model.name}}.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<EmptyState
|
||||
@title="No metadata associated with {{model.name}} yet"
|
||||
/>
|
||||
{{/each-in}}
|
||||
|
|
|
@ -23,15 +23,7 @@
|
|||
{{/linked-block}}
|
||||
{{/each}}
|
||||
{{else}}
|
||||
<div class="box is-bottomless has-background-white-bis">
|
||||
<div class="columns is-centered">
|
||||
<div class="column is-half has-text-centered">
|
||||
<div class="box is-shadowless has-background-white-bis">
|
||||
<p class="has-text-grey">
|
||||
This group has no parent groups.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<EmptyState
|
||||
@title="This group has no parent groups yet"
|
||||
/>
|
||||
{{/if}}
|
||||
|
|
|
@ -20,15 +20,7 @@
|
|||
</div>
|
||||
{{/linked-block}}
|
||||
{{else}}
|
||||
<div class="box is-bottomless has-background-white-bis">
|
||||
<div class="columns is-centered">
|
||||
<div class="column is-half has-text-centered">
|
||||
<div class="box is-shadowless has-background-white-bis">
|
||||
<p class="has-text-grey" data-test-no-entity-aliases-text>
|
||||
There are no policies associated with {{model.name}}.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<EmptyState
|
||||
@title="No policies associated with {{model.name}} yet"
|
||||
/>
|
||||
{{/each}}
|
||||
|
|
|
@ -5,15 +5,9 @@
|
|||
{{/each}}
|
||||
</div>
|
||||
{{else}}
|
||||
<div class="box is-bottomless has-background-white-bis">
|
||||
<div class="columns is-centered">
|
||||
<div class="column is-half has-text-centered">
|
||||
<div class="box is-shadowless has-background-white-bis">
|
||||
<p class="has-text-grey">
|
||||
{{emptyMessage}}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<EmptyState
|
||||
@title={{this.emptyTitle}}
|
||||
@message={{this.emptyMessage}}
|
||||
@emptyActions={{this.emptyActions}}
|
||||
/>
|
||||
{{/if}}
|
||||
|
|
|
@ -1,11 +1,22 @@
|
|||
{{#if (and isV2 modelForData.destroyed)}}
|
||||
<BlockEmpty>
|
||||
Version {{modelForData.version}} of this secret has been permanently destroyed.
|
||||
</BlockEmpty>
|
||||
<EmptyState
|
||||
@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 @path="/docs/secrets/kv/kv-v2.html">
|
||||
Learn More
|
||||
</DocLink>
|
||||
</EmptyState>
|
||||
{{else if (and isV2 modelForData.deleted)}}
|
||||
<BlockEmpty>
|
||||
Version {{modelForData.version}} of this secret has been deleted.
|
||||
</BlockEmpty>
|
||||
<EmptyState
|
||||
@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 @path="/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
|
||||
|
@ -35,23 +35,23 @@
|
|||
</div>
|
||||
{{/linked-block}}
|
||||
{{/each}}
|
||||
{{#if (gt model.meta.lastPage 1) }}
|
||||
{{list-pagination
|
||||
page=model.meta.currentPage
|
||||
lastPage=model.meta.lastPage
|
||||
link="vault.cluster.access.identity.aliases.index"
|
||||
}}
|
||||
{{/if}}
|
||||
{{else}}
|
||||
<div class="box is-bottomless has-background-white-bis">
|
||||
<div class="columns is-centered">
|
||||
<div class="column is-half has-text-centered">
|
||||
<div class="box is-shadowless has-background-white-bis">
|
||||
<p class="has-text-grey">
|
||||
There are currently no {{identityType}} aliases.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
{{#if (gt model.meta.lastPage 1) }}
|
||||
{{list-pagination
|
||||
page=model.meta.currentPage
|
||||
lastPage=model.meta.lastPage
|
||||
link="vault.cluster.access.identity.aliases.index"
|
||||
}}
|
||||
<EmptyState
|
||||
@title="No {{identityType}} aliases yet"
|
||||
@message="A list of {{identityType}} aliases in this namespace will be listed here. Choose one of the {{pluralize identityType}} and click "Create Alias" to get started."
|
||||
>
|
||||
{{#link-to "vault.cluster.access.identity.create" (pluralize identityType) tagName="button" class="link"}}
|
||||
Create {{identityType}}
|
||||
{{/link-to}}
|
||||
<LearnLink @path="/vault/identity-access-management/iam-identity">
|
||||
Learn More
|
||||
</LearnLink>
|
||||
</EmptyState>
|
||||
{{/if}}
|
||||
|
|
|
@ -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
|
||||
|
@ -57,7 +57,7 @@
|
|||
<button type="button" {{action "toggleDisabled" item}} class="link">
|
||||
Enable
|
||||
</button>
|
||||
{{else}}
|
||||
{{else if (eq identityType 'entity')}}
|
||||
{{#confirm-action
|
||||
confirmButtonClasses="button is-primary"
|
||||
confirmButtonText="Disable"
|
||||
|
@ -77,7 +77,7 @@
|
|||
{{#if item.canAddAlias}}
|
||||
<li class="action">
|
||||
{{#link-to "vault.cluster.access.identity.aliases.add" (pluralize identityType) item.id}}
|
||||
Add alias
|
||||
Create alias
|
||||
{{/link-to}}
|
||||
</li>
|
||||
{{/if}}
|
||||
|
@ -106,23 +106,23 @@
|
|||
</div>
|
||||
{{/linked-block}}
|
||||
{{/each}}
|
||||
{{#if (gt model.meta.lastPage 1) }}
|
||||
{{list-pagination
|
||||
page=model.meta.currentPage
|
||||
lastPage=model.meta.lastPage
|
||||
link="vault.cluster.access.identity.index"
|
||||
}}
|
||||
{{/if}}
|
||||
{{else}}
|
||||
<div class="box is-bottomless has-background-white-bis">
|
||||
<div class="columns is-centered">
|
||||
<div class="column is-half has-text-centered">
|
||||
<div class="box is-shadowless has-background-white-bis">
|
||||
<p class="has-text-grey">
|
||||
There are currently no {{pluralize identityType}}.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
{{#if (gt model.meta.lastPage 1) }}
|
||||
{{list-pagination
|
||||
page=model.meta.currentPage
|
||||
lastPage=model.meta.lastPage
|
||||
link="vault.cluster.access.identity.index"
|
||||
}}
|
||||
<EmptyState
|
||||
@title="No {{pluralize identityType}} yet"
|
||||
@message="A list of {{pluralize identityType}} in this namespace will be listed here. Create your first {{identityType}} to get started."
|
||||
>
|
||||
{{#link-to "vault.cluster.access.identity.create" (pluralize identityType) tagName="button" class="link"}}
|
||||
Create {{identityType}}
|
||||
{{/link-to}}
|
||||
<LearnLink @path="/vault/identity-access-management/iam-identity">
|
||||
Learn More
|
||||
</LearnLink>
|
||||
</EmptyState>
|
||||
{{/if}}
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
<div class="box is-sideless is-fullwidth is-paddingless is-marginless">
|
||||
<nav class="tabs sub-nav">
|
||||
<ul>
|
||||
{{#each (tabs-for-identity-show modennl.identityType model.type) as |tab|}}
|
||||
{{#each (tabs-for-identity-show model.identityType model.type) as |tab|}}
|
||||
{{#link-to "vault.cluster.access.identity.show" (pluralize model.identityType) model.id tab tagName="li"}}
|
||||
{{#link-to "vault.cluster.access.identity.show" (pluralize model.identityType) model.id tab}}
|
||||
{{capitalize (humanize tab)}}
|
||||
|
|
|
@ -10,32 +10,34 @@
|
|||
{{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" 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" 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}}
|
||||
|
|
|
@ -104,38 +104,16 @@
|
|||
glyph=(if item.isFolder 'folder' 'document')
|
||||
size=14
|
||||
class="has-text-grey-light"
|
||||
}}
|
||||
<span class="has-text-weight-semibold">
|
||||
{{or item.keyWithoutParent item.id}}
|
||||
</span>
|
||||
{{/link-to}}
|
||||
}}<span class="has-text-weight-semibold">{{or item.keyWithoutParent item.id}}</span>{{/link-to}}
|
||||
{{else}}
|
||||
<div class="box is-sideless">
|
||||
There are no leases matching <code>{{filter}}</code>
|
||||
</div>
|
||||
<EmptyState
|
||||
@title="There are no leases matching "{{this.filter}}""
|
||||
/>
|
||||
{{/each}}
|
||||
{{else}}
|
||||
<div class="box is-bottomless has-background-white-bis">
|
||||
<div class="columns is-centered">
|
||||
<div class="column is-half has-text-centered">
|
||||
<div class="box is-shadowless has-background-white-bis">
|
||||
<p class="has-text-grey">
|
||||
{{#if (eq baseKey.id '')}}
|
||||
There are currently no leases.
|
||||
{{else}}
|
||||
{{#if filterIsFolder}}
|
||||
{{#if (eq filter baseKey.id)}}
|
||||
There are no leases under <code>{{filter}}</code>.
|
||||
{{else}}
|
||||
We couldn't find a prefix matching <code>{{filter}}</code>.
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<EmptyState
|
||||
@title={{this.emptyTitle}}
|
||||
/>
|
||||
{{/if}}
|
||||
{{#if (gt model.meta.lastPage 1) }}
|
||||
{{list-pagination
|
||||
|
|
|
@ -7,12 +7,12 @@
|
|||
</p.levelLeft>
|
||||
<p.levelRight>
|
||||
{{#link-to 'vault.cluster.access.namespaces.create' class="button has-icon-right is-ghost is-compact"}}
|
||||
Create a namespace
|
||||
Create namespace
|
||||
<ICon @glyph="chevron-right" @size=11 />
|
||||
{{/link-to}}
|
||||
</p.levelRight>
|
||||
</PageHeader>
|
||||
<ListView @items={{model}} @itemNoun="namespace" as |list|>
|
||||
<ListView @items={{model}} @itemNoun="namespace" @emptyActions="empty-action-namespaces" as |list|>
|
||||
<ListItem as |Item|>
|
||||
<Item.content>
|
||||
{{list.item.id}}
|
||||
|
|
|
@ -17,35 +17,35 @@
|
|||
{{/link-to}}
|
||||
</p.levelRight>
|
||||
</PageHeader>
|
||||
<div class="box is-sideless has-background-grey-lighter has-short-padding is-marginless">
|
||||
<div class="level">
|
||||
<div class="level-left">
|
||||
{{navigate-input
|
||||
filterFocusDidChange=(action "setFilterFocus")
|
||||
filterDidChange=(action "setFilter")
|
||||
filter=filter
|
||||
filterMatchesKey=filterMatchesKey
|
||||
firstPartialMatch=firstPartialMatch
|
||||
extraNavParams=policyType
|
||||
placeholder="Filter policies"
|
||||
mode="policy"
|
||||
}}
|
||||
{{#if filterFocused}}
|
||||
{{#if filterMatchesKey}}
|
||||
<p class="input-hint">
|
||||
<kbd>ENTER</kbd> to go to <code>{{or pageFilter filter}}</code>
|
||||
</p>
|
||||
{{#if model.meta.total}}
|
||||
<div class="box is-sideless has-background-grey-lighter has-short-padding is-marginless">
|
||||
<div class="level">
|
||||
<div class="level-left">
|
||||
{{navigate-input
|
||||
filterFocusDidChange=(action "setFilterFocus")
|
||||
filterDidChange=(action "setFilter")
|
||||
filter=filter
|
||||
filterMatchesKey=filterMatchesKey
|
||||
firstPartialMatch=firstPartialMatch
|
||||
extraNavParams=policyType
|
||||
placeholder="Filter policies"
|
||||
mode="policy"
|
||||
}}
|
||||
{{#if filterFocused}}
|
||||
{{#if filterMatchesKey}}
|
||||
<p class="input-hint">
|
||||
<kbd>ENTER</kbd> to go to <code>{{or pageFilter filter}}</code>
|
||||
</p>
|
||||
{{/if}}
|
||||
{{#if firstPartialMatch}}
|
||||
<p class="input-hint">
|
||||
<kbd>TAB</kbd> to complete <code>{{firstPartialMatch.id}}</code>
|
||||
</p>
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
{{#if firstPartialMatch}}
|
||||
<p class="input-hint">
|
||||
<kbd>TAB</kbd> to complete <code>{{firstPartialMatch.id}}</code>
|
||||
</p>
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{#if model.meta.total}}
|
||||
{{#each model as |item|}}
|
||||
{{#if (eq item.id "root")}}
|
||||
<div class="list-item-row is-flex" data-test-policy-item>
|
||||
|
@ -139,30 +139,30 @@
|
|||
</div>
|
||||
{{/linked-block}}
|
||||
{{/if}}
|
||||
{{#if (gt model.meta.lastPage 1) }}
|
||||
{{list-pagination
|
||||
page=model.meta.currentPage
|
||||
lastPage=model.meta.lastPage
|
||||
link="vault.cluster.policies.index"
|
||||
}}
|
||||
{{/if}}
|
||||
{{else}}
|
||||
<div class="box is-sideless">
|
||||
<p> There are no policies matching <code>{{pageFilter}}</code>. </p>
|
||||
</div>
|
||||
<EmptyState
|
||||
@title="No policies matching "{{pageFilter}}""
|
||||
/>
|
||||
{{/each}}
|
||||
{{else}}
|
||||
<div class="box is-bottomless has-background-white-bis">
|
||||
<div class="columns is-centered">
|
||||
<div class="column is-half has-text-centered">
|
||||
<div class="box is-shadowless has-background-white-bis">
|
||||
<p class="has-text-grey" data-test-no-policies-text>
|
||||
There are currently no {{uppercase policyType}} policies.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
{{#if (gt model.meta.lastPage 1) }}
|
||||
{{list-pagination
|
||||
page=model.meta.currentPage
|
||||
lastPage=model.meta.lastPage
|
||||
link="vault.cluster.policies.index"
|
||||
}}
|
||||
<EmptyState
|
||||
@title="No {{uppercase policyType}} policies yet"
|
||||
@message="A list of policies will be listed here. Create your first {{uppercase policyType}} policy to get started."
|
||||
>
|
||||
{{#link-to "vault.cluster.policies.create" class="link"}}
|
||||
Create {{uppercase policyType}} policy
|
||||
{{/link-to}}
|
||||
<LearnLink @path="/vault/getting-started/policies">
|
||||
Learn More
|
||||
</LearnLink>
|
||||
</EmptyState>
|
||||
{{/if}}
|
||||
{{else}}
|
||||
{{upgrade-page title="Sentinel" minimumEdition="Vault Enterprise Premium"}}
|
||||
|
|
|
@ -6,11 +6,9 @@
|
|||
</h1>
|
||||
</p.levelLeft>
|
||||
</PageHeader>
|
||||
<div class="box is-sideless has-background-white-bis has-text-grey has-text-centered">
|
||||
<p>
|
||||
The current cluster configuration does not support replication.
|
||||
</p>
|
||||
</div>
|
||||
<EmptyState
|
||||
@title="The current cluster configuration does not support replication"
|
||||
/>
|
||||
{{else}}
|
||||
{{replication-summary
|
||||
cluster=model
|
||||
|
|
|
@ -17,17 +17,9 @@
|
|||
{{/info-table-row}}
|
||||
</div>
|
||||
{{else}}
|
||||
<div class="box is-bottomless has-background-white-bis is-marginless">
|
||||
<div class="columns is-centered">
|
||||
<div class="column is-half has-text-centered">
|
||||
<div class="box is-shadowless has-background-white-bis">
|
||||
<p class="has-text-grey">
|
||||
The secondary <code>{{model.config.id}}</code> does not currently have performance mount filtering configured.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<EmptyState
|
||||
@title="Performance Mount Filtering is not configured for this secondary"
|
||||
/>
|
||||
{{/if}}
|
||||
<div class="field is-fullwidth box is-shadowless">
|
||||
{{#if model.config.mode}}
|
||||
|
|
|
@ -46,17 +46,19 @@
|
|||
<hr class="is-marginless" />
|
||||
{{/each}}
|
||||
{{else}}
|
||||
<div class="box is-bottomless has-background-white-bis is-marginless">
|
||||
<div class="columns is-centered">
|
||||
<div class="column is-half has-text-centered">
|
||||
<div class="box is-shadowless has-background-white-bis">
|
||||
<p class="has-text-grey">
|
||||
There are currently no known {{performanceMode}} secondary clusters associated with this cluster.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<EmptyState
|
||||
@title="No known {{performanceMode}} secondary clusters associated with this cluster"
|
||||
@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 class="link" }}
|
||||
Add secondary
|
||||
{{/link-to}}
|
||||
{{/if}}
|
||||
<DocLink @path="/docs/internals/replication.html">
|
||||
Learn More
|
||||
</DocLink>
|
||||
</EmptyState>
|
||||
{{/if}}
|
||||
<div class="field is-grouped box is-shadowless is-fullwidth">
|
||||
{{#if model.canAddSecondary}}
|
||||
|
|
|
@ -1,39 +1,39 @@
|
|||
{{secret-list-header isCertTab=(eq tab "certs") model=backendModel baseKey=baseKey backendCrumb=backendCrumb filter=filter}}
|
||||
|
||||
{{#with (options-for-backend backendType tab) as |options|}}
|
||||
<div class="box is-sideless has-background-grey-lighter has-short-padding is-marginless">
|
||||
<div class="level">
|
||||
<div class="level-left">
|
||||
{{navigate-input
|
||||
enterpriseProduct="vault"
|
||||
filterFocusDidChange=(action "setFilterFocus")
|
||||
filterDidChange=(action "setFilter")
|
||||
filter=filter
|
||||
filterMatchesKey=filterMatchesKey
|
||||
firstPartialMatch=firstPartialMatch
|
||||
baseKey=(get baseKey "id")
|
||||
shouldNavigateTree=options.navigateTree
|
||||
placeholder=options.searchPlaceholder
|
||||
mode=(if (eq tab 'certs') 'secrets-cert' 'secrets')
|
||||
}}
|
||||
{{#if filterFocused}}
|
||||
{{#if filterMatchesKey}}
|
||||
{{#unless filterIsFolder}}
|
||||
{{#if model.meta.total}}
|
||||
<div class="box is-sideless has-background-grey-lighter has-short-padding is-marginless">
|
||||
<div class="level">
|
||||
<div class="level-left">
|
||||
{{navigate-input
|
||||
enterpriseProduct="vault"
|
||||
filterFocusDidChange=(action "setFilterFocus")
|
||||
filterDidChange=(action "setFilter")
|
||||
filter=filter
|
||||
filterMatchesKey=filterMatchesKey
|
||||
firstPartialMatch=firstPartialMatch
|
||||
baseKey=(get baseKey "id")
|
||||
shouldNavigateTree=options.navigateTree
|
||||
placeholder=options.searchPlaceholder
|
||||
mode=(if (eq tab 'certs') 'secrets-cert' 'secrets')
|
||||
}}
|
||||
{{#if filterFocused}}
|
||||
{{#if filterMatchesKey}}
|
||||
{{#unless filterIsFolder}}
|
||||
<p class="input-hint">
|
||||
<kbd>Enter</kbd> to view {{filter}}
|
||||
</p>
|
||||
{{/unless}}
|
||||
{{/if}}
|
||||
{{#if firstPartialMatch}}
|
||||
<p class="input-hint">
|
||||
<kbd>Enter</kbd> to view {{filter}}
|
||||
<kbd>Tab</kbd> to autocomplete
|
||||
</p>
|
||||
{{/unless}}
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
{{#if firstPartialMatch}}
|
||||
<p class="input-hint">
|
||||
<kbd>Tab</kbd> to autocomplete
|
||||
</p>
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{#if model.meta.total}}
|
||||
{{#each model as |item|}}
|
||||
{{partial options.listItemPartial}}
|
||||
{{else}}
|
||||
|
@ -45,27 +45,42 @@
|
|||
{{/if}}
|
||||
</div>
|
||||
{{/each}}
|
||||
{{#if (gt model.meta.lastPage 1) }}
|
||||
{{list-pagination
|
||||
page=model.meta.currentPage
|
||||
lastPage=model.meta.lastPage
|
||||
link=(concat "vault.cluster.secrets.backend.list" (if (not baseKey.id) "-root"))
|
||||
model=(compact (array backend (if baseKey.id baseKey.id)))
|
||||
}}
|
||||
{{/if}}
|
||||
{{else}}
|
||||
<BlockEmpty>
|
||||
{{#if (eq baseKey.id '')}}
|
||||
There are currently no {{pluralize options.item}} in this backend.
|
||||
{{else}}
|
||||
{{#if filterIsFolder}}
|
||||
{{#if (eq filter baseKey.id)}}
|
||||
There are no {{pluralize options.item}} under <code>{{or filter}}</code>.
|
||||
{{else}}
|
||||
We couldn't find a folder matching <code>{{filter}}</code>.
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
{{#if (eq baseKey.id '')}}
|
||||
<EmptyState
|
||||
@title="No {{pluralize options.item}} in this backend yet"
|
||||
@message="Secrets in this backend will be listed here. Add a secret to get started."
|
||||
>
|
||||
{{#secret-link
|
||||
mode="create"
|
||||
secret=''
|
||||
queryParams=(query-params initialKey=(or filter baseKey.id))
|
||||
class="link"
|
||||
}}
|
||||
{{options.create}}
|
||||
{{/secret-link}}
|
||||
</EmptyState>
|
||||
{{else}}
|
||||
{{#if filterIsFolder}}
|
||||
<EmptyState
|
||||
@title={{if (eq filter baseKey.id)
|
||||
(concat
|
||||
"No " (pluralize options.item) " under "" this.filter """
|
||||
)
|
||||
(concat
|
||||
"No folders matching "" this.filter """
|
||||
)
|
||||
}}
|
||||
/>
|
||||
{{/if}}
|
||||
</BlockEmpty>
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
{{/with}}
|
||||
{{#if (gt model.meta.lastPage 1) }}
|
||||
{{list-pagination
|
||||
page=model.meta.currentPage
|
||||
lastPage=model.meta.lastPage
|
||||
link=(concat "vault.cluster.secrets.backend.list" (if (not baseKey.id) "-root"))
|
||||
model=(compact (array backend (if baseKey.id baseKey.id)))
|
||||
}}
|
||||
{{/if}}
|
||||
|
|
|
@ -29,13 +29,7 @@
|
|||
{{/confirm-action}}
|
||||
</div>
|
||||
{{else}}
|
||||
<div class="box is-bottomless has-background-white-bis">
|
||||
<div class="columns is-centered">
|
||||
<div class="column is-half has-text-centered">
|
||||
<div class="box is-shadowless has-background-white-bis">
|
||||
<p class="has-text-grey">The token you are currently authenticated with does not have sufficient capabilities to seal this vault.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<EmptyState
|
||||
@title="This token does not have sufficient capabilities to seal this vault"
|
||||
/>
|
||||
{{/if}}
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
import { module, test } from 'qunit';
|
||||
import { setupRenderingTest } from 'ember-qunit';
|
||||
import { render, find } from '@ember/test-helpers';
|
||||
import hbs from 'htmlbars-inline-precompile';
|
||||
|
||||
module('Integration | Component | empty-state', function(hooks) {
|
||||
setupRenderingTest(hooks);
|
||||
|
||||
test('it renders', async function(assert) {
|
||||
// Set any properties with this.set('myProperty', 'value');
|
||||
// Handle any actions with this.set('myAction', function(val) { ... });
|
||||
|
||||
await render(hbs`{{empty-state}}`);
|
||||
|
||||
assert.equal(this.element.textContent.trim(), '');
|
||||
|
||||
// Template block usage:
|
||||
await render(hbs`
|
||||
{{#empty-state
|
||||
title="Empty State Title"
|
||||
message="This is the empty state message"
|
||||
}}
|
||||
Actions Link
|
||||
{{/empty-state}}
|
||||
`);
|
||||
|
||||
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 New Issue