Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

UI: VAULT-12949 use overview card component for kubernetes overview #18845

Merged
merged 4 commits into from
Jan 26, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion ui/lib/core/addon/components/overview-card.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,6 @@
</LinkTo>
{{/if}}
</div>
<p class="has-text-grey is-size-8 {{unless @actionText 'has-top-margin-xs'}}">{{@subText}}</p>
<p class="has-text-grey is-size-8 {{unless @actionText 'has-top-margin-s'}}">{{@subText}}</p>
{{yield}}
</div>
77 changes: 33 additions & 44 deletions ui/lib/kubernetes/addon/components/page/overview.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -3,51 +3,40 @@
</TabPageHeader>

{{#if @config}}
<div class="has-top-margin-m">
<div class="is-flex">
<div class="box has-padding-m has-right-margin-m is-rounded column is-flex-half" data-test-roles-card>
<div class="is-flex-between">
<h2 class="title is-3">
Roles
</h2>
{{#if @roles.length}}
<LinkTo class="is-no-underline" @route="roles">View Roles</LinkTo>
{{else}}
<LinkTo class="is-no-underline" @route="roles.create">Create Role</LinkTo>
{{/if}}
</div>
<p>The number of Vault roles being used to generate Kubernetes credentials.</p>
<h2 class="title has-font-weight-normal is-3 has-top-margin-l">
{{or @roles.length "None"}}
</h2>
<div class="selectable-card-container has-grid has-top-margin-l has-two-col-grid">
<OverviewCard
@cardTitle="Roles"
@subText="The number of Vault roles being used to generate Kubernetes credentials."
@actionText={{if @roles.length "View Roles" "Create Role"}}
@actionTo={{if @roles.length "roles" "roles.create"}}
>
<h2 class="title is-2 has-font-weight-normal has-top-margin-m" data-test-roles-card-overview-num>{{or
@roles.length
"None"
}}</h2>
</OverviewCard>
<OverviewCard @cardTitle="Generate credentials" @subText="Quickly generate credentials by typing the role name.">
<div class="has-top-margin-m is-flex">
<SearchSelect
class="is-flex-1"
@placeholder="Type to find a role..."
@disallowNewItems={{true}}
@options={{this.roleOptions}}
@selectLimit="1"
@fallbackComponent="input-search"
@onChange={{this.selectRole}}
/>
<button
class="button has-left-margin-s"
type="button"
disabled={{not this.selectedRole}}
{{on "click" this.generateCredential}}
data-test-generate-credential-button
>
Generate
</button>
</div>
<div class="box has-padding-m is-rounded column is-flex-half" data-test-generate-credential-card>
<h2 class="title is-3">
Generate credentials
</h2>
<p>Quickly generate credentials by typing the role name.</p>
<div class="is-flex-center has-top-margin-s">
<SearchSelect
class="is-marginless is-flex-1"
@placeholder="Type to find a role..."
@disallowNewItems={{true}}
@options={{this.roleOptions}}
@selectLimit="1"
@fallbackComponent="input-search"
@onChange={{this.selectRole}}
/>
<button
class="button has-left-margin-m"
type="button"
disabled={{not this.selectedRole}}
{{on "click" this.generateCredential}}
data-test-generate-credential-button
>
Generate
</button>
</div>
</div>
</div>
</OverviewCard>
</div>
{{else}}
<ConfigCta />
Expand Down
98 changes: 44 additions & 54 deletions ui/lib/pki/addon/components/page/pki-overview.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -21,62 +21,52 @@
</OverviewCard>
{{/if}}
<OverviewCard @cardTitle="Issue certificate" @subText="Begin issuing a certificate by choosing a role.">
<form
aria-label="issue certificate"
data-test-selectable-card="Issue certificate"
{{on "submit" this.transitionToIssueCertificates}}
>
<div class="has-top-padding-s is-flex">
<SearchSelect
class="is-flex-1"
@selectLimit="1"
@models={{array "pki/role"}}
@backend={{@engine.id}}
@placeholder="Type to find a role..."
@disallowNewItems={{true}}
@onChange={{this.handleRolesInput}}
@fallbackComponent="input-search"
data-test-issue-certificate-input
/>
<button
type="submit"
class="button is-secondary has-left-margin-s"
disabled={{unless this.rolesValue true}}
data-test-issue-certificate-button
>
Issue
</button>
</div>
</form>
<div class="has-top-margin-m is-flex">
<SearchSelect
class="is-flex-1"
@selectLimit="1"
@models={{array "pki/role"}}
@backend={{@engine.id}}
@placeholder="Type to find a role..."
@disallowNewItems={{true}}
@onChange={{this.handleRolesInput}}
@fallbackComponent="input-search"
data-test-issue-certificate-input
/>
<button
type="submit"
class="button is-secondary has-left-margin-s"
disabled={{unless this.rolesValue true}}
{{on "click" this.transitionToIssueCertificates}}
data-test-issue-certificate-button
>
Issue
</button>
</div>
</OverviewCard>

<OverviewCard @cardTitle="View certificate" @subText="Quickly view a certificate by typing its serial number.">
<form
aria-label="view certificate"
data-test-selectable-card="View certificate"
{{on "submit" this.transitionToViewCertificates}}
>
<div class="has-top-padding-s is-flex">
<SearchSelect
class="is-flex-1"
@selectLimit="1"
@models={{array "pki/certificate/base"}}
@backend={{@engine.id}}
@placeholder="33:a3:..."
@disallowNewItems={{true}}
@onChange={{this.handleCertificateInput}}
@fallbackComponent="input-search"
data-test-view-certificate-input
/>
<button
type="submit"
class="button is-secondary has-left-margin-s"
disabled={{unless this.certificateValue true}}
data-test-view-certificate-button
>
View
</button>
</div>
</form>
<div class="has-top-margin-m is-flex">
<SearchSelect
class="is-flex-1"
@selectLimit="1"
@models={{array "pki/certificate/base"}}
@backend={{@engine.id}}
@placeholder="33:a3:..."
@disallowNewItems={{true}}
@onChange={{this.handleCertificateInput}}
@fallbackComponent="input-search"
data-test-view-certificate-input
/>
<button
type="button"
class="button is-secondary has-left-margin-s"
disabled={{unless this.certificateValue true}}
{{on "click" this.transitionToViewCertificates}}
data-test-view-certificate-button
>
View
</button>
</div>
</OverviewCard>
</div>
6 changes: 2 additions & 4 deletions ui/lib/pki/addon/components/page/pki-overview.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,16 +22,14 @@ export default class PkiOverview extends Component<Args> {
@tracked certificateValue = '';

@action
transitionToViewCertificates(event: Event) {
event.preventDefault();
transitionToViewCertificates() {
this.router.transitionTo(
'vault.cluster.secrets.backend.pki.certificates.certificate.details',
this.certificateValue
);
}
@action
transitionToIssueCertificates(event: Event) {
event.preventDefault();
transitionToIssueCertificates() {
this.router.transitionTo('vault.cluster.secrets.backend.pki.roles.role.generate', this.rolesValue);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import ENV from 'vault/config/environment';
import authPage from 'vault/tests/pages/auth';
import { visit, click, currentRouteName } from '@ember/test-helpers';
import { selectChoose } from 'ember-power-select/test-support';
import { SELECTORS } from 'vault/tests/helpers/kubernetes/overview';

module('Acceptance | kubernetes | overview', function (hooks) {
setupApplicationTest(hooks);
Expand Down Expand Up @@ -41,15 +42,15 @@ module('Acceptance | kubernetes | overview', function (hooks) {
assert.expect(1);
this.createScenario();
await this.visitOverview();
await click('[data-test-roles-card] .is-no-underline');
await click(SELECTORS.rolesCardLink);
this.validateRoute(assert, 'roles.index', 'Transitions to roles route on View Roles click');
});

test('it should transition to create roles', async function (assert) {
assert.expect(1);
this.createScenario(false);
await this.visitOverview();
await click('[data-test-roles-card] .is-no-underline');
await click(SELECTORS.rolesCardLink);
this.validateRoute(assert, 'roles.create', 'Transitions to roles route on Create Roles click');
});

Expand Down
12 changes: 12 additions & 0 deletions ui/tests/helpers/kubernetes/overview.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
export const SELECTORS = {
rolesCardTitle: '[data-test-selectable-card="Roles"] .title',
rolesCardSubTitle: '[data-test-selectable-card-container="Roles"] p',
rolesCardLink: '[data-test-selectable-card="Roles"] a',
rolesCardNumRoles: '[data-test-roles-card-overview-num]',
generateCredentialsCardTitle: '[data-test-selectable-card="Generate credentials"] .title',
generateCredentialsCardSubTitle: '[data-test-selectable-card-container="Generate credentials"] p',
generateCredentialsCardButton: '[data-test-generate-credential-button]',
emptyStateTitle: '.empty-state .empty-state-title',
emptyStateMessage: '.empty-state .empty-state-message',
emptyStateActionText: '.empty-state .empty-state-actions',
};
29 changes: 16 additions & 13 deletions ui/tests/integration/components/kubernetes/page/overview-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { setupEngine } from 'ember-engines/test-support';
import { setupMirage } from 'ember-cli-mirage/test-support';
import { render } from '@ember/test-helpers';
import { typeInSearch, clickTrigger, selectChoose } from 'ember-power-select/test-support/helpers';
import { SELECTORS } from 'vault/tests/helpers/kubernetes/overview';
import hbs from 'htmlbars-inline-precompile';

module('Integration | Component | kubernetes | Page::Overview', function (hooks) {
Expand Down Expand Up @@ -53,33 +54,35 @@ module('Integration | Component | kubernetes | Page::Overview', function (hooks)

test('it should display role card', async function (assert) {
await this.renderComponent();
assert.dom('[data-test-roles-card] .title').hasText('Roles');
assert.dom(SELECTORS.rolesCardTitle).hasText('Roles');
assert
.dom('[data-test-roles-card] p')
.dom(SELECTORS.rolesCardSubTitle)
.hasText('The number of Vault roles being used to generate Kubernetes credentials.');
assert.dom('[data-test-roles-card] a').hasText('View Roles');
assert.dom(SELECTORS.rolesCardLink).hasText('View Roles');

this.roles = [];

await this.renderComponent();
assert.dom('[data-test-roles-card] a').hasText('Create Role');
assert.dom(SELECTORS.rolesCardLink).hasText('Create Role');
});

test('it should display correct number of roles in role card', async function (assert) {
await this.renderComponent();
assert.dom('[data-test-roles-card] .has-font-weight-normal').hasText('2');
assert.dom(SELECTORS.rolesCardNumRoles).hasText('2');

this.roles = [];

await this.renderComponent();
assert.dom('[data-test-roles-card] .has-font-weight-normal').hasText('None');

assert.dom(SELECTORS.rolesCardNumRoles).hasText('None');
});

test('it should display generate credentials card', async function (assert) {
await this.renderComponent();
assert.dom('[data-test-generate-credential-card] .title').hasText('Generate credentials');

assert.dom(SELECTORS.generateCredentialsCardTitle).hasText('Generate credentials');
assert
.dom('[data-test-generate-credential-card] p')
.dom(SELECTORS.generateCredentialsCardSubTitle)
.hasText('Quickly generate credentials by typing the role name.');
});

Expand All @@ -89,21 +92,21 @@ module('Integration | Component | kubernetes | Page::Overview', function (hooks)
assert.strictEqual(this.element.querySelectorAll('.ember-power-select-option').length, 2);
await typeInSearch('role-0');
assert.strictEqual(this.element.querySelectorAll('.ember-power-select-option').length, 1);
assert.dom('[data-test-generate-credential-card] button').isDisabled();
assert.dom(SELECTORS.generateCredentialsCardButton).isDisabled();
await selectChoose('', '.ember-power-select-option', 2);
assert.dom('[data-test-generate-credential-card] button').isNotDisabled();
assert.dom(SELECTORS.generateCredentialsCardButton).isNotDisabled();
});

test('it should show ConfigCta when no config is set up', async function (assert) {
this.config = null;

await this.renderComponent();
assert.dom('.empty-state .empty-state-title').hasText('Kubernetes not configured');
assert.dom(SELECTORS.emptyStateTitle).hasText('Kubernetes not configured');
assert
.dom('.empty-state .empty-state-message')
.dom(SELECTORS.emptyStateMessage)
.hasText(
'Get started by establishing the URL of the Kubernetes API to connect to, along with some additional options.'
);
assert.dom('.empty-state .empty-state-actions').hasText('Configure Kubernetes');
assert.dom(SELECTORS.emptyStateActionText).hasText('Configure Kubernetes');
});
});