UI: Update flight icons (#24823)

This commit is contained in:
Chelsea Shaw
2024-01-11 15:19:16 -06:00
committed by GitHub
parent a1c2e49eaa
commit e09fd3fbbe
60 changed files with 163 additions and 160 deletions

3
changelog/24823.txt Normal file
View File

@@ -0,0 +1,3 @@
```release-note:change
ui: Update icons to use Flight icons where available.
```

View File

@@ -16,7 +16,7 @@
@disabled={{if type.requiredFeature (not (has-feature type.requiredFeature)) false}}
data-test-mount-type={{type.type}}
>
<Icon @name={{or type.glyph type.type}} @size="24" class="has-bottom-margin-xs" />
<Icon @name={{type.glyph}} @size="24" class="has-bottom-margin-xs" />
<Hds::Text::Body @tag="h3" @size="300">
{{type.displayName}}
</Hds::Text::Body>

View File

@@ -16,7 +16,12 @@ export default class MfaMethodCreateController extends Controller {
@service router;
queryParams = ['type'];
methodNames = ['TOTP', 'Duo', 'Okta', 'PingID'];
methods = [
{ name: 'TOTP', icon: 'history' },
{ name: 'Duo', icon: 'duo' },
{ name: 'Okta', icon: 'okta-color' },
{ name: 'PingID', icon: 'pingid' },
];
@tracked type = null;
@tracked method = null;

View File

@@ -28,6 +28,7 @@ const MOUNTABLE_AUTH_METHODS = [
value: 'approle',
type: 'approle',
category: 'generic',
glyph: 'cpu',
},
{
displayName: 'AWS',
@@ -61,14 +62,14 @@ const MOUNTABLE_AUTH_METHODS = [
displayName: 'JWT',
value: 'jwt',
type: 'jwt',
glyph: 'auth',
glyph: 'jwt',
category: 'generic',
},
{
displayName: 'OIDC',
value: 'oidc',
type: 'oidc',
glyph: 'auth',
glyph: 'openid-color',
category: 'generic',
},
{
@@ -82,7 +83,7 @@ const MOUNTABLE_AUTH_METHODS = [
displayName: 'LDAP',
value: 'ldap',
type: 'ldap',
glyph: 'auth',
glyph: 'folder-users',
category: 'infra',
},
{
@@ -96,7 +97,7 @@ const MOUNTABLE_AUTH_METHODS = [
displayName: 'RADIUS',
value: 'radius',
type: 'radius',
glyph: 'auth',
glyph: 'mainframe',
category: 'infra',
},
{
@@ -104,6 +105,7 @@ const MOUNTABLE_AUTH_METHODS = [
value: 'cert',
type: 'cert',
category: 'generic',
glyph: 'certificate',
},
{
displayName: 'Username & Password',

View File

@@ -19,6 +19,7 @@ const ENTERPRISE_SECRET_ENGINES = [
type: 'transform',
category: 'generic',
requiredFeature: 'Transform Secrets Engine',
glyph: 'transform-data',
},
{
displayName: 'Key Management',
@@ -59,6 +60,7 @@ const MOUNTABLE_SECRET_ENGINES = [
displayName: 'Databases',
type: 'database',
category: 'infra',
glyph: 'database',
},
{
displayName: 'Google Cloud',
@@ -95,6 +97,7 @@ const MOUNTABLE_SECRET_ENGINES = [
{
displayName: 'RabbitMQ',
type: 'rabbitmq',
glyph: 'rabbitmq-color',
category: 'infra',
},
{

View File

@@ -11,6 +11,7 @@ import fieldToAttrs, { expandAttributeMeta } from 'vault/utils/field-to-attrs';
import apiPath from 'vault/utils/api-path';
import attachCapabilities from 'vault/lib/attach-capabilities';
import { withModelValidations } from 'vault/decorators/model-validations';
import { allMethods } from 'vault/helpers/mountable-auth-methods';
const validations = {
path: [
@@ -42,6 +43,11 @@ const ModelExport = AuthMethodModel.extend({
methodType: computed('type', function () {
return this.type.replace(/^ns_/, '');
}),
icon: computed('methodType', function () {
const authMethods = allMethods().find((backend) => backend.type === this.methodType);
return authMethods?.glyph || 'users';
}),
description: attr('string', {
editType: 'textarea',
}),

View File

@@ -168,6 +168,15 @@ export default class MfaMethod extends Model {
return this.type === 'totp' ? this.type.toUpperCase() : capitalize(this.type);
}
get icon() {
switch (this.type) {
case 'totp':
return 'history';
default:
return this.type;
}
}
get formFields() {
return [...METHOD_PROPS.common, ...METHOD_PROPS[this.type]];
}

View File

@@ -15,7 +15,13 @@ const DOMAIN_STRINGS = {
'auth0.com': 'Auth0',
};
const PROVIDER_WITH_LOGO = ['GitHub', 'GitLab', 'Google', 'Okta', 'Auth0'];
const PROVIDER_WITH_LOGO = {
GitHub: 'github',
GitLab: 'gitlab',
Google: 'google',
Okta: 'okta',
Auth0: 'auth0',
};
export { DOMAIN_STRINGS, PROVIDER_WITH_LOGO };
@@ -30,6 +36,6 @@ export default class RoleJwtModel extends Model {
get providerIcon() {
const { providerName } = this;
return PROVIDER_WITH_LOGO.includes(providerName) ? providerName.toLowerCase() : null;
return PROVIDER_WITH_LOGO[providerName] || null;
}
}

View File

@@ -123,14 +123,9 @@ export default class SecretEngineModel extends Model {
}
get icon() {
const defaultIcon = this.engineType || 'secrets';
return (
{
keymgmt: 'key',
kmip: 'secrets',
ldap: 'folder-users',
}[this.engineType] || defaultIcon
);
const engineData = allEngines().find((engine) => engine.type === this.engineType);
return engineData?.glyph || 'lock';
}
get engineType() {

View File

@@ -11,7 +11,7 @@
<div class="level is-mobile">
<div class="level-left">
<div class="is-flex-row">
<Icon @size="24" @name={{@model.type}} class="has-text-grey" data-test-mfa-method-list-icon={{@model.type}} />
<Icon @size="24" @name={{@model.icon}} class="has-text-grey" data-test-mfa-method-list-icon={{@model.type}} />
<div>
<span class="has-text-weight-semibold has-text-black">
{{@model.name}}

View File

@@ -8,7 +8,7 @@
<h1 class="title is-3 title-with-icon" data-test-mount-form-header="true">
{{#if this.showEnable}}
{{#let (find-by "type" @mountModel.type @mountTypes) as |typeInfo|}}
<Icon @name={{or typeInfo.glyph typeInfo.type}} @size="24" class="has-text-grey-light" />
<Icon @name={{typeInfo.glyph}} @size="24" class="has-text-grey-light" />
{{#if (eq @mountType "secret")}}
{{concat "Enable " typeInfo.displayName " Secrets Engine"}}
{{else}}

View File

@@ -3,7 +3,7 @@
SPDX-License-Identifier: BUSL-1.1
~}}
<WizardContent @headerText="Vault Web UI" @glyph="tour" @selectProgress={{this.selectProgress}}>
<WizardContent @headerText="Vault Web UI" @glyph="guide" @selectProgress={{this.selectProgress}}>
<h2 class="title is-6">
Choosing where to go
</h2>

View File

@@ -3,7 +3,7 @@
SPDX-License-Identifier: BUSL-1.1
~}}
<WizardContent @headerText="Authentication" @glyph="tour">
<WizardContent @headerText="Authentication" @glyph="guide">
<WizardSection @headerText="Authenticate to Vault" @docText="Learn: Initialization" @docPath="/docs/concepts/tokens.html">
<p>
Vault is unsealed, but we still need to authenticate using the Initial Root Token that was generated. We recommend

View File

@@ -3,7 +3,7 @@
SPDX-License-Identifier: BUSL-1.1
~}}
<WizardContent @headerText="Initialization" @glyph="tour">
<WizardContent @headerText="Initialization" @glyph="guide">
<WizardSection
@headerText="Saving your keys"
@docText="Learn: Initialization"

View File

@@ -3,7 +3,7 @@
SPDX-License-Identifier: BUSL-1.1
~}}
<WizardContent @headerText="Initialization" @glyph="tour">
<WizardContent @headerText="Initialization" @glyph="guide">
<WizardSection
@headerText="Setting up your root keys"
@docText="Learn: Initialization"

View File

@@ -3,7 +3,7 @@
SPDX-License-Identifier: BUSL-1.1
~}}
<WizardContent @headerText="Initialization" @glyph="tour">
<WizardContent @headerText="Initialization" @glyph="guide">
<WizardSection
@headerText="Unsealing your vault"
@docText="Learn: Initialization"

View File

@@ -3,7 +3,7 @@
SPDX-License-Identifier: BUSL-1.1
~}}
<WizardContent @headerText={{capitalize this.currentMachine}} @glyph="tour">
<WizardContent @headerText={{capitalize this.currentMachine}} @glyph="guide">
{{component
this.stepComponent
mountSubtype=this.mountSubtype

View File

@@ -4,7 +4,7 @@
~}}
{{! template-lint-disable quotes }}
<WizardContent @headerText="Policies" @glyph="tour">
<WizardContent @headerText="Policies" @glyph="guide">
<WizardSection
@headerText="Creating a policy"
@docText="Docs: Policies"

View File

@@ -4,7 +4,7 @@
~}}
{{! template-lint-disable quotes }}
<WizardContent @headerText="Policies" @glyph="tour">
<WizardContent @headerText="Policies" @glyph="guide">
<WizardSection
@headerText="Deleting your policy"
@docText="Docs: Policies"

View File

@@ -4,7 +4,7 @@
~}}
{{! template-lint-disable quotes }}
<WizardContent @headerText="Policies" @glyph="tour">
<WizardContent @headerText="Policies" @glyph="guide">
<WizardSection
@headerText="Your new policy"
@docText="Docs: Policies"

View File

@@ -4,7 +4,7 @@
~}}
{{! template-lint-disable quotes }}
<WizardContent @headerText="Policies" @glyph="tour">
<WizardContent @headerText="Policies" @glyph="guide">
<WizardSection
@headerText="Choosing a policy type"
@docText="Docs: Policies"

View File

@@ -3,7 +3,7 @@
SPDX-License-Identifier: BUSL-1.1
~}}
<WizardContent @headerText="Policies" @glyph="tour">
<WizardContent @headerText="Policies" @glyph="guide">
<WizardSection @headerText="Other kinds of policies" @docText="Docs: Policies" @docPath="/docs/concepts/policies.html">
<p>
Good! Now you're ready to go writing your own policies. We only explored ACL policies, but there are two other types of

View File

@@ -4,7 +4,7 @@
~}}
{{! template-lint-disable quotes }}
<WizardContent @headerText="Replication" @glyph="tour">
<WizardContent @headerText="Replication" @glyph="guide">
<WizardSection
@headerText="Setting up Replication"
@docText="Docs: Replication"

View File

@@ -4,7 +4,7 @@
~}}
{{! template-lint-disable quotes }}
<WizardContent @headerText="Tools" @glyph="tour">
<WizardContent @headerText="Tools" @glyph="guide">
<WizardSection
@headerText="Information about your data"
@docText="API: Lookup Data"

View File

@@ -4,7 +4,7 @@
~}}
{{! template-lint-disable quotes }}
<WizardContent @headerText="Tools" @glyph="tour">
<WizardContent @headerText="Tools" @glyph="guide">
<WizardSection
@headerText="Lookup wrapped data"
@docText="API: Lookup Data"

View File

@@ -4,7 +4,7 @@
~}}
{{! template-lint-disable quotes }}
<WizardContent @headerText="Tools" @glyph="tour">
<WizardContent @headerText="Tools" @glyph="guide">
<WizardSection
@headerText="Rewrapping your data"
@docText="API: Rewrap Data"

View File

@@ -4,7 +4,7 @@
~}}
{{! template-lint-disable quotes }}
<WizardContent @headerText="Tools" @glyph="tour">
<WizardContent @headerText="Tools" @glyph="guide">
<WizardSection
@headerText="Your rewrapped data"
@docText="API: Rewrap Data"

View File

@@ -4,7 +4,7 @@
~}}
{{! template-lint-disable quotes }}
<WizardContent @headerText="Tools" @glyph="tour">
<WizardContent @headerText="Tools" @glyph="guide">
<WizardSection
@headerText="Unwrapping your data"
@docText="API: Unwrap Data"

View File

@@ -3,7 +3,7 @@
SPDX-License-Identifier: BUSL-1.1
~}}
<WizardContent @headerText="Tools" @glyph="tour">
<WizardContent @headerText="Tools" @glyph="guide">
<WizardSection @headerText="Your unwrapped data" @docText="API: Unwrap Data" @docPath="/api/system/wrapping-unwrap.html">
<p>
Here you can see that your data survived intact. These tools are mostly handy for applications to use, but if you ever

View File

@@ -4,7 +4,7 @@
~}}
{{! template-lint-disable quotes }}
<WizardContent @headerText="Tools" @glyph="tour">
<WizardContent @headerText="Tools" @glyph="guide">
<WizardSection
@headerText="Wrapping data"
@docText="API: Wrap Data"

View File

@@ -4,7 +4,7 @@
~}}
{{! template-lint-disable quotes }}
<WizardContent @headerText="Tools" @glyph="tour">
<WizardContent @headerText="Tools" @glyph="guide">
<WizardSection
@headerText="Copying your wrapped token"
@docText="API: Wrap Data"

View File

@@ -3,7 +3,7 @@
SPDX-License-Identifier: BUSL-1.1
~}}
<WizardContent @headerText="Thanks for taking the tour!" @glyph="tour" @class="collapsed">
<WizardContent @headerText="Thanks for taking the tour!" @glyph="guide" @class="collapsed">
<p>
We hope you enjoyed using Vault. You can get back to the guide in the user menu in the upper right.
</p>

View File

@@ -3,7 +3,7 @@
SPDX-License-Identifier: BUSL-1.1
~}}
<WizardContent @headerText="Welcome to Vault" @glyph="tour" @class="collapsed" @hidePopup={{true}}>
<WizardContent @headerText="Welcome to Vault" @glyph="guide" @class="collapsed" @hidePopup={{true}}>
<Hds::Button @text="Close" @icon="x" @isIconOnly={{true}} @color="secondary" {{on "click" (action @onDismiss)}} />
<p>Want a tour? Our helpful guide will introduce you to the Vault Web UI.</p>
<div class="box wizard-divider-box">

View File

@@ -3,7 +3,7 @@
SPDX-License-Identifier: BUSL-1.1
~}}
<WizardContent @headerText="Vault Web UI Guide" @glyph="tour" @class="collapsed" @hidePopup={{true}}>
<WizardContent @headerText="Vault Web UI Guide" @glyph="guide" @class="collapsed" @hidePopup={{true}}>
<Hds::Button @text="Close" @icon="x" @isIconOnly={{true}} @color="secondary" {{on "click" (action @onDismiss)}} />
<p>Feel free to explore Vault. Click below to get back to the guide or close this window.</p>
<div class="box wizard-divider-box">

View File

@@ -56,14 +56,7 @@
<div class="level-left">
<div>
<Hds::TooltipButton @text={{method.methodType}} aria-label="Type of auth mount">
<Icon
@name={{if
(or (find-by "type" method.methodType (mountable-auth-methods)) (eq method.methodType "token"))
method.methodType
"auth"
}}
class="has-text-grey-light"
/>
<Icon @name={{method.icon}} class="has-text-grey-light" />
</Hds::TooltipButton>
<span data-test-path data-test-id={{method.id}} class="has-text-weight-semibold has-text-black">
{{method.path}}

View File

@@ -51,22 +51,21 @@
<DocLink @path="/vault/api-docs/secret/identity/mfa">Learn more.</DocLink>
</p>
<div class="is-flex-row has-top-margin-xl">
{{#each this.methodNames as |methodName|}}
{{#each this.methods as |method|}}
<RadioCard
@value={{lowercase methodName}}
@value={{lowercase method.name}}
@groupValue={{this.type}}
@onChange={{this.onTypeSelect}}
data-test-radio-card={{lowercase methodName}}
data-test-radio-card={{lowercase method.name}}
>
<div class="radio-card-row is-flex-v-centered">
<div>
<Icon
@name={{if (eq methodName "Okta") "okta-color" (lowercase methodName)}}
@size="24"
class={{if (eq methodName "TOTP") "has-text-grey"}}
/>
<p class="has-text-weight-semibold has-text-center {{if (eq methodName 'Okta') 'has-top-margin-xs'}}">
{{methodName}}
<Icon @name={{method.icon}} @size="24" class={{if (eq method.name "TOTP") "has-text-grey"}} />
<p
class="has-text-weight-semibold has-text-center
{{if (or (eq method.name 'Okta') (eq method.name 'TOTP')) 'has-top-margin-xs'}}"
>
{{method.name}}
</p>
</div>
</div>

View File

@@ -12,7 +12,7 @@
</p.top>
<p.levelLeft>
<h1 class="title is-3">
<Icon @size="24" @name={{this.model.method.type}} />
<Icon @size="24" @name={{this.model.method.icon}} />
{{this.model.method.name}}
</h1>
</p.levelLeft>

View File

@@ -23,7 +23,7 @@ const appConfig = {
//optimize: false,
//paths: [],
optimizer: {},
sourceDirs: ['node_modules/@hashicorp/structure-icons/dist', 'public'],
sourceDirs: ['public'],
rootURL: '/ui/',
},
fingerprint: {
@@ -91,8 +91,5 @@ module.exports = function (defaults) {
app.import('app/styles/bulma/bulma-radio-checkbox.css');
app.import('node_modules/@hashicorp/structure-icons/dist/loading.css');
app.import('node_modules/@hashicorp/structure-icons/dist/run.css');
return app.toTree();
};

View File

@@ -4,9 +4,9 @@
~}}
{{#if this.isFlightIcon}}
<FlightIcon @name={{this.name}} @size={{this.size}} @stretched={{@stretched}} ...attributes />
<FlightIcon @name={{@name}} @size={{this.size}} @stretched={{@stretched}} ...attributes />
{{else}}
<span class="hs-icon {{this.hsIconClass}}" aria-hidden="true" ...attributes>
{{svg-jar this.name}}
{{svg-jar @name}}
</span>
{{/if}}

View File

@@ -10,15 +10,16 @@ const flightIconNames = flightIconMap.assets.mapBy('iconName').uniq();
/**
* @module Icon
* `Icon` components are glyphs used to indicate important information.
* `Icon` components are used to display an icon.
*
* Flight icon documentation at https://flight-hashicorp.vercel.app/
* Flight icon documentation at https://helios.hashicorp.design/icons/usage-guidelines?tab=code#how-to-use-icons
* Flight icon library at https://helios.hashicorp.design/icons/library
*
* @example
* ```js
* <Icon @name="cancel-square-outline" @size="24" />
* <Icon @name="x-square" @size="24" />
* ```
* @param {string} name=null - The name of the SVG to render inline.
* @param {string} name - The name of the SVG to render inline. Required.
* @param {string} [size=16] - size for flight icon, can be 16 or 24
*
*/
@@ -27,19 +28,16 @@ export default class Icon extends Component {
constructor(owner, args) {
super(owner, args);
assert('Icon component size argument must be either "16" or "24"', ['16', '24'].includes(this.size));
assert('Icon name argument must be provided', this.args.name);
}
get size() {
return this.args.size || '16';
}
get name() {
return this.args.name || null;
}
// favor flight icon set and fall back to structure icons if not found
get isFlightIcon() {
return this.name ? flightIconNames.includes(this.name) : false;
return this.args.name ? flightIconNames.includes(this.args.name) : false;
}
get hsIconClass() {

View File

@@ -35,10 +35,13 @@ export default Component.extend({
actions: {
iconClass(model, field) {
return this.trueOrFalseString(model, field, 'icon-true', 'icon-false');
return this.trueOrFalseString(model, field, 'hds-foreground-success', 'hds-foreground-faint');
},
iconGlyph(model, field) {
return this.trueOrFalseString(model, field, 'check-circle-outline', 'cancel-square-outline');
return this.trueOrFalseString(model, field, 'check-circle', 'x-square');
},
operationEnabled(model, field) {
return this.trueOrFalseString(model, field, 'Enabled', 'Disabled');
},
},
});

View File

@@ -9,7 +9,7 @@
</p.top>
<p.levelLeft>
<h1 class="title is-3">
<Icon @name="secrets" @size="24" class="has-text-grey-light" />
<Icon @name="lock" @size="24" class="has-text-grey-light" />
{{this.secretMountPath.currentPath}}
</h1>
</p.levelLeft>

View File

@@ -12,7 +12,7 @@
<div>
{{#each fieldsInGroup as |field|}}
<Icon
aria-hidden="true"
aria-label={{compute (action "operationEnabled") this.model field}}
class={{compute (action "iconClass") this.model field}}
@name={{compute (action "iconGlyph") this.model field}}
/>

View File

@@ -9,7 +9,7 @@
</p.top>
<p.levelLeft>
<h1 class="title is-3">
<Icon @name="secrets" @size="24" class="has-text-grey-light" />
<Icon @name="lock" @size="24" class="has-text-grey-light" />
Configure KMIP Secrets Engine
</h1>
</p.levelLeft>

View File

@@ -10,7 +10,7 @@
<p.levelLeft>
<h1 class="title is-3" data-test-header-title>
{{#if @mountName}}
<Icon @name="kv" @size="24" class="has-text-grey-light" />
<Icon @name="key-values" @size="24" class="has-text-grey-light" />
{{@mountName}}
<span class="tag">version 2</span>
{{else}}

View File

@@ -9,7 +9,7 @@
</p.top>
<p.levelLeft>
<h1 class="title is-3">
<Icon @name="pki" @size="24" class="has-text-grey-light" />
<Icon @name="certificate" @size="24" class="has-text-grey-light" />
Configure Automatic Tidy
</h1>
</p.levelLeft>

View File

@@ -9,7 +9,7 @@
</p.top>
<p.levelLeft>
<h1 class="title is-3">
<Icon @name="pki" @size="24" class="has-text-grey-light" />
<Icon @name="certificate" @size="24" class="has-text-grey-light" />
Manual Tidy
</h1>
</p.levelLeft>

View File

@@ -67,7 +67,6 @@
"@ember/test-waiters": "^3.0.0",
"@glimmer/component": "^1.1.2",
"@glimmer/tracking": "^1.1.2",
"@hashicorp/structure-icons": "^1.3.0",
"@icholy/duration": "^5.1.0",
"@tsconfig/ember": "^1.0.1",
"@types/ember": "^4.0.2",
@@ -251,8 +250,8 @@
]
},
"dependencies": {
"@hashicorp/design-system-components": "^3.3.0",
"@hashicorp/ember-flight-icons": "^4.0.4",
"@hashicorp/design-system-components": "^3.4.0",
"@hashicorp/ember-flight-icons": "^4.0.5",
"handlebars": "4.7.7",
"highlight.js": "^10.4.1",
"node-notifier": "^8.0.1",

View File

@@ -40,11 +40,7 @@ module('Integration | Component | confirm-action', function (hooks) {
'hds-modal hds-modal--size-small hds-modal--color-critical has-text-left',
'renders critical modal color by default'
);
assert.strictEqual(
find(SELECTORS.confirm).className,
'hds-button hds-button--size-medium hds-button--color-critical',
'renders critical confirm button'
);
assert.dom(SELECTORS.confirm).hasClass('hds-button--color-critical', 'renders critical confirm button');
assert.dom(SELECTORS.title).hasText('Are you sure?', 'renders default title');
assert
.dom(SELECTORS.message)
@@ -142,23 +138,10 @@ module('Integration | Component | confirm-action', function (hooks) {
/>
`);
// hasClass assertion wasn't working so this is the workaround
assert.strictEqual(
find(SELECTORS.modalToggle).className,
'hds-button hds-button--size-medium hds-button--color-secondary',
'renders @buttonColor classes'
);
assert.dom(SELECTORS.modalToggle).hasClass('hds-button--color-secondary', 'renders @buttonColor classes');
await click(SELECTORS.modalToggle);
assert.strictEqual(
find('#confirm-action-modal').className,
'hds-modal hds-modal--size-small hds-modal--color-warning has-text-left',
'renders warning modal'
);
assert.strictEqual(
find(SELECTORS.confirm).className,
'hds-button hds-button--size-medium hds-button--color-primary',
'renders primary confirm button'
);
assert.dom('#confirm-action-modal').hasClass('hds-modal--color-warning', 'renders warning modal');
assert.dom(SELECTORS.confirm).hasClass('hds-button--color-primary', 'renders primary confirm button');
assert.dom(SELECTORS.title).hasText('Do this?', 'renders passed title');
assert.dom(SELECTORS.message).hasText('Are you really, really sure?', 'renders passed body text');
assert.dom(SELECTORS.confirm).hasText('Confirm');

View File

@@ -134,7 +134,7 @@ module('Integration | Component | dashboard/secrets-engines-card', function (hoo
test('it adds disabled css styling to unsupported secret engines', async function (assert) {
await this.renderComponent();
assert.dom('[data-test-secrets-engines-row="nomad"] [data-test-view]').doesNotExist();
assert.dom('[data-test-icon="nomad"]').hasClass('has-text-grey');
assert.dom('[data-test-secrets-engines-row="nomad"] [data-test-secret-path]').hasClass('has-text-grey');
});
});
});

View File

@@ -13,24 +13,28 @@ module('Integration | Component | icon', function (hooks) {
setupRenderingTest(hooks);
test('it renders', async function (assert) {
await render(hbs`<Icon class="i-con" />`);
await render(hbs`<Icon @name="vault-color" class="i-con" />`);
assert.dom('.i-con').exists('renders');
// non-flight icon
await render(hbs`<Icon @name="vault-logo" />`);
assert.dom('.vault-logo').exists('inlines the SVG');
assert.dom('.hs-icon').hasClass('hs-icon-l', 'Default hs class applied');
await render(hbs`<Icon class="ah" aria-hidden="true" />`);
await render(hbs`<Icon @name="vault-color" class="ah" aria-hidden="true" />`);
assert.dom('.ah').hasAttribute('aria-hidden', 'true', 'renders aria-hidden');
await render(hbs`<Icon class="al" aria-label="Testing" />`);
await render(hbs`<Icon @name="vault-color" class="al" aria-label="Testing" />`);
assert.dom('.al').hasAttribute('aria-label', 'Testing', 'renders aria-label');
// non-flight icon
await render(hbs`<Icon @name="vault-logo" @size="24"/>`);
assert.dom('.hs-icon').hasClass('hs-icon-xlm', 'adds the larger size class');
});
test('it throws error when size attribute is invalid', async function (assert) {
const promise = waitForError();
render(hbs`<Icon @name="vault-logo" @size="12"/>`);
render(hbs`<Icon @name="vault-color" @size="12"/>`);
const err = await promise;
assert.strictEqual(
err.message,
@@ -39,8 +43,19 @@ module('Integration | Component | icon', function (hooks) {
);
});
test('it throws error when name attribute is not passed', async function (assert) {
const promise = waitForError();
render(hbs`<Icon />`);
const err = await promise;
assert.strictEqual(
err.message,
'Assertion Failed: Icon name argument must be provided',
'Error is thrown when name not provided'
);
});
test('it should render FlightIcon', async function (assert) {
assert.expect(4);
assert.expect(3);
await render(hbs`<Icon @name="x" />`);
assert.dom('.flight-icon').exists('FlightIcon renders when provided name of icon in set');
@@ -48,14 +63,5 @@ module('Integration | Component | icon', function (hooks) {
await render(hbs`<Icon @name="x" @size="24" />`);
assert.dom('.flight-icon').hasAttribute('width', '24', 'Size applied to svg');
const promise = waitForError();
render(hbs`<Icon @name="x" @size="12"/>`);
const err = await promise;
assert.strictEqual(
err.message,
'Assertion Failed: Icon component size argument must be either "16" or "24"',
'Error is thrown when supported size is not provided'
);
});
});

View File

@@ -58,7 +58,7 @@ module('Integration | Component | kubernetes | Page::Configuration', function (h
test('it should render tab page header, config cta and mount config', async function (assert) {
await this.renderComponent();
assert.dom('.title svg').hasClass('flight-icon-kubernetes', 'Kubernetes icon renders in title');
assert.dom('.title svg').hasClass('flight-icon-kubernetes-color', 'Kubernetes icon renders in title');
assert.dom('.title').hasText('kubernetes-test', 'Mount path renders in title');
assert
.dom('[data-test-toolbar-config-action]')

View File

@@ -50,7 +50,7 @@ module('Integration | Component | kubernetes | Page::Roles', function (hooks) {
test('it should render tab page header and config cta', async function (assert) {
this.promptConfig = true;
await this.renderComponent();
assert.dom('.title svg').hasClass('flight-icon-kubernetes', 'Kubernetes icon renders in title');
assert.dom('.title svg').hasClass('flight-icon-kubernetes-color', 'Kubernetes icon renders in title');
assert.dom('.title').hasText('kubernetes-test', 'Mount path renders in title');
assert
.dom('[data-test-toolbar-roles-action]')

View File

@@ -47,7 +47,7 @@ module('Integration | Component | kubernetes | TabPageHeader', function (hooks)
});
assert
.dom('[data-test-header-title] svg')
.hasClass('flight-icon-kubernetes', 'Correct icon renders in title');
.hasClass('flight-icon-kubernetes-color', 'Correct icon renders in title');
assert.dom('[data-test-header-title]').hasText(this.mount, 'Mount path renders in title');
});

View File

@@ -71,7 +71,9 @@ module('Integration | Component | kv | kv-page-header', function (hooks) {
assert
.dom('[data-test-header-title]')
.hasText(`${this.backend} version 2`, 'Mount path and version tag render for title.');
assert.dom('[data-test-header-title] span').hasClass('hs-icon', 'An icon renders next to title.');
assert
.dom('[data-test-header-title] [data-test-icon="key-values"]')
.exists('An icon renders next to title.');
});
test('it renders tabs', async function (assert) {

View File

@@ -33,7 +33,9 @@ module('Integration | Component | pki page header test', function (hooks) {
await render(hbs`<PkiPageHeader @backend={{this.model}} />`, {
owner: this.engine,
});
assert.dom('[data-test-header-title] span').hasClass('hs-icon', 'Correct icon renders in title');
assert
.dom('[data-test-header-title] [data-test-icon="certificate"]')
.exists('Correct icon renders in title');
assert.dom('[data-test-header-title]').hasText(this.mount, 'Mount path renders in title');
});

View File

@@ -79,11 +79,11 @@ module('Integration | Component | replication-secondary-card', function (hooks)
assert.dom('[data-test-empty-state]').exists('shows empty state');
});
test('it renders tooltip with check-circle-outline when state is stream-wals', async function (assert) {
test('it renders tooltip with check-circle when state is stream-wals', async function (assert) {
await render(
hbs`<ReplicationSecondaryCard @replicationDetails={{this.replicationDetails}} @title={{this.title}} />`
);
assert.dom('[data-test-glyph]').hasClass('has-text-success', `shows success icon`);
assert.dom('[data-test-icon="check-circle"]').hasClass('has-text-success', `shows success icon`);
});
test('it renders hasErrorMessage when state is idle', async function (assert) {

View File

@@ -37,7 +37,7 @@ module('Unit | Model | role-jwt', function (hooks) {
const expectedName = DOMAIN_STRINGS[domain];
assert.strictEqual(model.providerName, expectedName, `computes providerName: ${expectedName}`);
let expectedIcon = null;
if (PROVIDER_WITH_LOGO.includes(expectedName)) {
if (PROVIDER_WITH_LOGO[expectedName]) {
expectedIcon = expectedName.toLowerCase();
}
assert.strictEqual(model.providerIcon, expectedIcon, `computes providerIcon: ${domain}`);

View File

@@ -282,19 +282,19 @@ module('Unit | Model | secret-engine', function (hooks) {
});
module('icon', function () {
test('returns secrets if no engineType', function (assert) {
test('returns default icon if no engineType', function (assert) {
assert.expect(1);
const model = this.store.createRecord('secret-engine', {
type: '',
});
assert.strictEqual(model.icon, 'secrets');
assert.strictEqual(model.icon, 'lock', 'uses default icon');
});
test('returns secrets if kmip', function (assert) {
test('returns default icon if kmip', function (assert) {
assert.expect(1);
const model = this.store.createRecord('secret-engine', {
type: 'kmip',
});
assert.strictEqual(model.icon, 'secrets');
assert.strictEqual(model.icon, 'lock');
});
test('returns key if keymgmt', function (assert) {
assert.expect(1);
@@ -303,12 +303,12 @@ module('Unit | Model | secret-engine', function (hooks) {
});
assert.strictEqual(model.icon, 'key');
});
test('returns engineType by default', function (assert) {
test('returns default when engine type is not in list of mountable engines', function (assert) {
assert.expect(1);
const model = this.store.createRecord('secret-engine', {
type: 'ducks',
});
assert.strictEqual(model.icon, 'ducks');
assert.strictEqual(model.icon, 'lock');
});
});

View File

@@ -6204,15 +6204,15 @@ __metadata:
languageName: node
linkType: hard
"@hashicorp/design-system-components@npm:^3.3.0":
version: 3.3.0
resolution: "@hashicorp/design-system-components@npm:3.3.0"
"@hashicorp/design-system-components@npm:^3.4.0":
version: 3.4.0
resolution: "@hashicorp/design-system-components@npm:3.4.0"
dependencies:
"@ember/render-modifiers": ^2.0.5
"@ember/string": ^3.1.1
"@ember/test-waiters": ^3.1.0
"@hashicorp/design-system-tokens": ^1.9.0
"@hashicorp/ember-flight-icons": ^4.0.4
"@hashicorp/ember-flight-icons": ^4.0.5
dialog-polyfill: ^0.5.6
ember-a11y-refocus: ^3.0.2
ember-auto-import: ^2.6.3
@@ -6230,7 +6230,7 @@ __metadata:
prismjs: ^1.29.0
sass: ^1.69.5
tippy.js: ^6.3.7
checksum: 47b3262ec9a31e03110309c80833e1b504baa126851106328b0f5668b7c4f312116e35a9f876aedea80ed71de7a32ee8b530498a947adc8f1fe3db8102a6a227
checksum: a206648f67d84849069264a25dd32cd6af0608853018925400958f89c1b590b037408ab38e616c9f8ba9bcc08955c50820c80f5a137164023f30858e472a9008
languageName: node
linkType: hard
@@ -6241,30 +6241,23 @@ __metadata:
languageName: node
linkType: hard
"@hashicorp/ember-flight-icons@npm:^4.0.4":
version: 4.0.4
resolution: "@hashicorp/ember-flight-icons@npm:4.0.4"
"@hashicorp/ember-flight-icons@npm:^4.0.5":
version: 4.0.5
resolution: "@hashicorp/ember-flight-icons@npm:4.0.5"
dependencies:
"@hashicorp/flight-icons": ^2.23.0
"@hashicorp/flight-icons": ^2.24.0
ember-auto-import: ^2.6.3
ember-cli-babel: ^8.2.0
ember-cli-htmlbars: ^6.3.0
ember-get-config: ^2.1.1
checksum: fb0a0f26feb80d1dc663b6fd4e1b6849b8c93e4607f8d790f2fa646cee96b4f3df339951b8adddbf85c39052c72fdf54fc4b910baf2fd64c188d660635c8ba73
checksum: 68ed79595fdb7ed2cd9c33260c14f780a358eee9952f228897051f5994daa9e2a366b8f5c9992a2511c9ea0a79a5fefb1ac4e1068707bb8115708f3a91b60af6
languageName: node
linkType: hard
"@hashicorp/flight-icons@npm:^2.23.0":
version: 2.23.0
resolution: "@hashicorp/flight-icons@npm:2.23.0"
checksum: 0a216a868244bcb3220e13061e5353fd16a0296c1aa9f7444ba2a7148e78532698e7c36a1318573b8ec7fe0283c68c93e7bfbd79a19eb24b2f0006ab78d3b191
languageName: node
linkType: hard
"@hashicorp/structure-icons@npm:^1.3.0":
version: 1.8.1
resolution: "@hashicorp/structure-icons@npm:1.8.1"
checksum: 578afba4c884a32c196e87cfa22f66482faf0bd9ccf78591e8d16dedec1eff60e95d90858b0607e7a0136922c551f5649bcfc4d6557b27e2688f2c78434c12cd
"@hashicorp/flight-icons@npm:^2.24.0":
version: 2.24.0
resolution: "@hashicorp/flight-icons@npm:2.24.0"
checksum: f226e4e4aed2256680a0fd29bfeac215dc9a224f8ce7b532a64cc30917a2739d34e50e84f70d40b05193e5cb2fbbb603b7870d4a0da09c6335c7f94bfb6e18df
languageName: node
linkType: hard
@@ -27849,9 +27842,8 @@ __metadata:
"@ember/test-waiters": ^3.0.0
"@glimmer/component": ^1.1.2
"@glimmer/tracking": ^1.1.2
"@hashicorp/design-system-components": ^3.3.0
"@hashicorp/ember-flight-icons": ^4.0.4
"@hashicorp/structure-icons": ^1.3.0
"@hashicorp/design-system-components": ^3.4.0
"@hashicorp/ember-flight-icons": ^4.0.5
"@icholy/duration": ^5.1.0
"@tsconfig/ember": ^1.0.1
"@types/ember": ^4.0.2