UI/fix kmip role form (#13585)
* Fix info-table-row not rendering if alwaysRender=false and only block content present * use defaultFields for form and nonOperationFields for adapter * WIP: Move info table row template to addon component dir * Refactor InfoTableRow to glimmer component * Add changelog * passthrough attributes, change @data-test-x to data-test-x on InfoTableRow invocations
This commit is contained in:
parent
a09a20e758
commit
5301934368
|
@ -0,0 +1,3 @@
|
||||||
|
```release-note:bug
|
||||||
|
ui: Fixes issue saving KMIP role correctly
|
||||||
|
```
|
|
@ -38,7 +38,7 @@ export default BaseAdapter.extend({
|
||||||
|
|
||||||
serialize(snapshot) {
|
serialize(snapshot) {
|
||||||
// the endpoint here won't allow sending `operation_all` and `operation_none` at the same time or with
|
// the endpoint here won't allow sending `operation_all` and `operation_none` at the same time or with
|
||||||
// other values, so we manually check for them and send an abbreviated object
|
// other operation_ values, so we manually check for them and send an abbreviated object
|
||||||
let json = snapshot.serialize();
|
let json = snapshot.serialize();
|
||||||
let keys = snapshot.record.nonOperationFields.map(decamelize);
|
let keys = snapshot.record.nonOperationFields.map(decamelize);
|
||||||
let nonOperationFields = getProperties(json, keys);
|
let nonOperationFields = getProperties(json, keys);
|
||||||
|
|
|
@ -17,10 +17,16 @@ export const COMPUTEDS = {
|
||||||
return ['tlsClientKeyBits', 'tlsClientKeyType', 'tlsClientTtl'];
|
return ['tlsClientKeyBits', 'tlsClientKeyType', 'tlsClientTtl'];
|
||||||
}),
|
}),
|
||||||
|
|
||||||
nonOperationFields: computed('newFields', 'operationFields', 'tlsFields', function () {
|
// For rendering on the create/edit pages
|
||||||
|
defaultFields: computed('newFields', 'operationFields', 'tlsFields', function () {
|
||||||
let excludeFields = ['role'].concat(this.operationFields, this.tlsFields);
|
let excludeFields = ['role'].concat(this.operationFields, this.tlsFields);
|
||||||
return this.newFields.slice().removeObjects(excludeFields);
|
return this.newFields.slice().removeObjects(excludeFields);
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
// For adapter/serializer
|
||||||
|
nonOperationFields: computed('newFields', 'operationFields', function () {
|
||||||
|
return this.newFields.slice().removeObjects(this.operationFields);
|
||||||
|
}),
|
||||||
};
|
};
|
||||||
|
|
||||||
const ModelExport = Model.extend(COMPUTEDS, {
|
const ModelExport = Model.extend(COMPUTEDS, {
|
||||||
|
@ -31,10 +37,10 @@ const ModelExport = Model.extend(COMPUTEDS, {
|
||||||
getHelpUrl(path) {
|
getHelpUrl(path) {
|
||||||
return `/v1/${path}/scope/example/role/example?help=1`;
|
return `/v1/${path}/scope/example/role/example?help=1`;
|
||||||
},
|
},
|
||||||
fieldGroups: computed('fields', 'nonOperationFields.length', 'tlsFields', function () {
|
fieldGroups: computed('fields', 'defaultFields.length', 'tlsFields', function () {
|
||||||
const groups = [{ TLS: this.tlsFields }];
|
const groups = [{ TLS: this.tlsFields }];
|
||||||
if (this.nonOperationFields.length) {
|
if (this.defaultFields.length) {
|
||||||
groups.unshift({ default: this.nonOperationFields });
|
groups.unshift({ default: this.defaultFields });
|
||||||
}
|
}
|
||||||
let ret = fieldToAttrs(this, groups);
|
let ret = fieldToAttrs(this, groups);
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -61,7 +67,7 @@ const ModelExport = Model.extend(COMPUTEDS, {
|
||||||
];
|
];
|
||||||
if (others.length) {
|
if (others.length) {
|
||||||
groups.push({
|
groups.push({
|
||||||
'': others,
|
Other: others,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return fieldToAttrs(this, groups);
|
return fieldToAttrs(this, groups);
|
||||||
|
@ -69,8 +75,8 @@ const ModelExport = Model.extend(COMPUTEDS, {
|
||||||
tlsFormFields: computed('tlsFields', function () {
|
tlsFormFields: computed('tlsFields', function () {
|
||||||
return expandAttributeMeta(this, this.tlsFields);
|
return expandAttributeMeta(this, this.tlsFields);
|
||||||
}),
|
}),
|
||||||
fields: computed('nonOperationFields', function () {
|
fields: computed('defaultFields', function () {
|
||||||
return expandAttributeMeta(this, this.nonOperationFields);
|
return expandAttributeMeta(this, this.defaultFields);
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -56,12 +56,19 @@
|
||||||
attr.options.masked
|
attr.options.masked
|
||||||
)
|
)
|
||||||
}}
|
}}
|
||||||
<InfoTableRow
|
{{#if (get this.model attr.name)}}
|
||||||
@label={{capitalize (or attr.options.label (humanize (dasherize attr.name)))}}
|
<InfoTableRow
|
||||||
@value={{get this.model attr.name}}
|
@label={{capitalize (or attr.options.label (humanize (dasherize attr.name)))}}
|
||||||
>
|
@value={{get this.model attr.name}}
|
||||||
<MaskedInput @value={{get this.model attr.name}} @name={{attr.name}} @displayOnly={{true}} @allowCopy={{true}} />
|
>
|
||||||
</InfoTableRow>
|
<MaskedInput
|
||||||
|
@value={{get this.model attr.name}}
|
||||||
|
@name={{attr.name}}
|
||||||
|
@displayOnly={{true}}
|
||||||
|
@allowCopy={{true}}
|
||||||
|
/>
|
||||||
|
</InfoTableRow>
|
||||||
|
{{/if}}
|
||||||
{{else if (and (get this.model attr.name) (or (eq attr.name "issueDate") (eq attr.name "expiryDate")))}}
|
{{else if (and (get this.model attr.name) (or (eq attr.name "issueDate") (eq attr.name "expiryDate")))}}
|
||||||
<InfoTableRow
|
<InfoTableRow
|
||||||
data-test-table-row
|
data-test-table-row
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
<InfoTableRow @label="Name" @value={{@model.name}} @data-test-alias-name={{true}} />
|
<InfoTableRow @label="Name" @value={{@model.name}} data-test-alias-name={{true}} />
|
||||||
<InfoTableRow @label="ID" @value={{@model.id}} />
|
<InfoTableRow @label="ID" @value={{@model.id}} />
|
||||||
<InfoTableRow @label={{if (eq @model.identityType "entity-alias") "Entity ID" "Group ID"}} @value={{this.model.canonicalId}}>
|
<InfoTableRow @label={{if (eq @model.identityType "entity-alias") "Entity ID" "Group ID"}} @value={{this.model.canonicalId}}>
|
||||||
<LinkTo
|
<LinkTo
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
{{/if}}
|
{{/if}}
|
||||||
</AlertBanner>
|
</AlertBanner>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
<InfoTableRow @label="Name" @value={{@model.name}} @data-test-identity-item-name={{true}} />
|
<InfoTableRow @label="Name" @value={{@model.name}} data-test-identity-item-name={{true}} />
|
||||||
<InfoTableRow @label="Type" @value={{@model.type}} />
|
<InfoTableRow @label="Type" @value={{@model.type}} />
|
||||||
<InfoTableRow @label="ID" @value={{@model.id}} />
|
<InfoTableRow @label="ID" @value={{@model.id}} />
|
||||||
<InfoTableRow @label="Merged Ids" @value={{@model.mergedEntityIds}}>
|
<InfoTableRow @label="Merged Ids" @value={{@model.mergedEntityIds}}>
|
||||||
|
|
|
@ -7,13 +7,13 @@
|
||||||
<section class="box is-sideless is-marginless is-shadowless is-fullwidth">
|
<section class="box is-sideless is-marginless is-shadowless is-fullwidth">
|
||||||
<span class="title is-5">Details</span>
|
<span class="title is-5">Details</span>
|
||||||
<div class="field box is-fullwidth is-shadowless is-paddingless is-marginless">
|
<div class="field box is-fullwidth is-shadowless is-paddingless is-marginless">
|
||||||
<InfoTableRow @label="License ID" @value={{@licenseId}} @data-test-detail-row={{true}} />
|
<InfoTableRow @label="License ID" @value={{@licenseId}} data-test-detail-row />
|
||||||
<InfoTableRow @label="Valid from" @value={{@startTime}} @data-test-detail-row={{true}}>
|
<InfoTableRow @label="Valid from" @value={{@startTime}} data-test-detail-row>
|
||||||
{{date-format @startTime "MMM dd, yyyy hh:mm:ss a"}}
|
{{date-format @startTime "MMM dd, yyyy hh:mm:ss a"}}
|
||||||
to
|
to
|
||||||
{{date-format @expirationTime "MMM dd, yyyy hh:mm:ss a"}}
|
{{date-format @expirationTime "MMM dd, yyyy hh:mm:ss a"}}
|
||||||
</InfoTableRow>
|
</InfoTableRow>
|
||||||
<InfoTableRow @label="License state" @value={{if @autoloaded "Autoloaded" "Stored"}} @data-test-detail-row={{true}}>
|
<InfoTableRow @label="License state" @value={{if @autoloaded "Autoloaded" "Stored"}} data-test-detail-row>
|
||||||
{{#if @autoloaded}}
|
{{#if @autoloaded}}
|
||||||
Autoloaded
|
Autoloaded
|
||||||
{{else}}
|
{{else}}
|
||||||
|
@ -32,11 +32,7 @@
|
||||||
<span class="title is-5">Features</span>
|
<span class="title is-5">Features</span>
|
||||||
<div class="field box is-fullwidth is-shadowless is-paddingless is-marginless">
|
<div class="field box is-fullwidth is-shadowless is-paddingless is-marginless">
|
||||||
{{#each this.featuresInfo as |info|}}
|
{{#each this.featuresInfo as |info|}}
|
||||||
<InfoTableRow
|
<InfoTableRow @label={{info.name}} @value={{if info.active "Active" "Not Active"}} data-test-feature-row>
|
||||||
@label={{info.name}}
|
|
||||||
@value={{if info.active "Active" "Not Active"}}
|
|
||||||
@data-test-feature-row="data-test-feature-row"
|
|
||||||
>
|
|
||||||
{{#if info.active}}
|
{{#if info.active}}
|
||||||
<Icon @name="check-circle" class="icon-true" />
|
<Icon @name="check-circle" class="icon-true" />
|
||||||
<span data-test-feature-status>
|
<span data-test-feature-status>
|
||||||
|
|
|
@ -8,12 +8,12 @@
|
||||||
|
|
||||||
{{#if (or @creation_time @creation_ttl)}}
|
{{#if (or @creation_time @creation_ttl)}}
|
||||||
<div class="box is-fullwidth is-sideless is-paddingless is-marginless">
|
<div class="box is-fullwidth is-sideless is-paddingless is-marginless">
|
||||||
<InfoTableRow @label="Creation path" @value={{@creation_path}} @data-test-tools="token-lookup-row" />
|
<InfoTableRow @label="Creation path" @value={{@creation_path}} data-test-tools="token-lookup-row" />
|
||||||
<InfoTableRow @label="Creation time" @value={{@creation_time}} @data-test-tools="token-lookup-row" />
|
<InfoTableRow @label="Creation time" @value={{@creation_time}} data-test-tools="token-lookup-row" />
|
||||||
<InfoTableRow @label="Creation TTL" @value={{@creation_ttl}} @data-test-tools="token-lookup-row" />
|
<InfoTableRow @label="Creation TTL" @value={{@creation_ttl}} data-test-tools="token-lookup-row" />
|
||||||
{{#if @expirationDate}}
|
{{#if @expirationDate}}
|
||||||
<InfoTableRow @label="Expiration date" @value={{@expirationDate}} @data-test-tools="token-lookup-row" />
|
<InfoTableRow @label="Expiration date" @value={{@expirationDate}} data-test-tools="token-lookup-row" />
|
||||||
<InfoTableRow @label="Expires in" @value={{date-from-now @expirationDate}} @data-test-tools="token-lookup-row" />
|
<InfoTableRow @label="Expires in" @value={{date-from-now @expirationDate}} data-test-tools="token-lookup-row" />
|
||||||
{{/if}}
|
{{/if}}
|
||||||
</div>
|
</div>
|
||||||
<div class="field is-grouped box is-fullwidth is-bottomless">
|
<div class="field is-grouped box is-fullwidth is-bottomless">
|
||||||
|
|
|
@ -0,0 +1,90 @@
|
||||||
|
{{#if (or (has-block) this.isVisible)}}
|
||||||
|
<div class="info-table-row" data-test-component="info-table-row" ...attributes>
|
||||||
|
<div
|
||||||
|
class="column is-one-quarter {{if this.hasLabelOverflow "label-overflow"}}"
|
||||||
|
data-test-label-div
|
||||||
|
{{did-insert this.calculateLabelOverflow}}
|
||||||
|
>
|
||||||
|
{{#if @label}}
|
||||||
|
{{#if this.hasLabelOverflow}}
|
||||||
|
<ToolTip @verticalPosition="below" @horizontalPosition="left" as |T|>
|
||||||
|
<T.Trigger @tabindex={{false}}>
|
||||||
|
<span class="is-label has-text-grey-dark" data-test-row-label={{@label}}>{{@label}}</span>
|
||||||
|
</T.Trigger>
|
||||||
|
<T.Content class="tool-tip">
|
||||||
|
<div class="box fit-content" data-test-label-tooltip>
|
||||||
|
{{@label}}
|
||||||
|
</div>
|
||||||
|
</T.Content>
|
||||||
|
</ToolTip>
|
||||||
|
{{else}}
|
||||||
|
<span class="is-label has-text-grey-dark" data-test-row-label={{@label}}>{{@label}}</span>
|
||||||
|
{{/if}}
|
||||||
|
{{#if @helperText}}
|
||||||
|
<div>
|
||||||
|
<span class="is-label helper-text has-text-grey">{{@helperText}}</span>
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
{{else}}
|
||||||
|
<Icon @name="minus" />
|
||||||
|
{{/if}}
|
||||||
|
</div>
|
||||||
|
<div class="column is-flex foobar" data-test-value-div={{@label}}>
|
||||||
|
{{#if (has-block)}}
|
||||||
|
{{yield}}
|
||||||
|
{{else if this.valueIsBoolean}}
|
||||||
|
{{#if @value}}
|
||||||
|
<Icon class="icon-true" @name="check-circle" data-test-boolean-true />
|
||||||
|
Yes
|
||||||
|
{{else}}
|
||||||
|
<Icon @name="x-square" class="icon-false" data-test-boolean-false />
|
||||||
|
No
|
||||||
|
{{/if}}
|
||||||
|
{{! alwaysRender is still true }}
|
||||||
|
{{else if this.valueIsEmpty}}
|
||||||
|
{{#if @defaultShown}}
|
||||||
|
<span data-test-row-value={{@label}}>{{@defaultShown}}</span>
|
||||||
|
{{else}}
|
||||||
|
<Icon @name="minus" />
|
||||||
|
{{/if}}
|
||||||
|
{{else}}
|
||||||
|
{{#if (eq @type "array")}}
|
||||||
|
<InfoTableItemArray
|
||||||
|
@backend={{@backend}}
|
||||||
|
@displayArray={{@value}}
|
||||||
|
@isLink={{@isLink}}
|
||||||
|
@label={{@label}}
|
||||||
|
@modelType={{@modelType}}
|
||||||
|
@queryParam={{@queryParam}}
|
||||||
|
@viewAll={{@viewAll}}
|
||||||
|
@wildcardLabel={{@wildcardLabel}}
|
||||||
|
/>
|
||||||
|
{{else}}
|
||||||
|
{{#if @tooltipText}}
|
||||||
|
<ToolTip @verticalPosition="above" @horizontalPosition="left" as |T|>
|
||||||
|
<T.Trigger @tabindex={{false}}>
|
||||||
|
<span class="is-word-break has-text-black" data-test-row-value={{this.label}}>{{this.value}}</span>
|
||||||
|
</T.Trigger>
|
||||||
|
<T.Content class="tool-tip">
|
||||||
|
<CopyButton
|
||||||
|
@clipboardText={{@tooltipText}}
|
||||||
|
@success={{action (set-flash-message "Data copied!")}}
|
||||||
|
@tagName="div"
|
||||||
|
@disabled={{not @isTooltipCopyable}}
|
||||||
|
class={{if @isTooltipCopyable "has-pointer"}}
|
||||||
|
data-test-tooltip-copy
|
||||||
|
>
|
||||||
|
<div class="box">
|
||||||
|
{{@tooltipText}}
|
||||||
|
</div>
|
||||||
|
</CopyButton>
|
||||||
|
</T.Content>
|
||||||
|
</ToolTip>
|
||||||
|
{{else}}
|
||||||
|
<span class="is-word-break has-text-black" data-test-row-value={{@label}}>{{@value}}</span>
|
||||||
|
{{/if}}
|
||||||
|
{{/if}}
|
||||||
|
{{/if}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
|
@ -1,8 +1,8 @@
|
||||||
import { typeOf } from '@ember/utils';
|
import { typeOf } from '@ember/utils';
|
||||||
import { computed } from '@ember/object';
|
import Component from '@glimmer/component';
|
||||||
import { or } from '@ember/object/computed';
|
import { tracked } from '@glimmer/tracking';
|
||||||
import Component from '@ember/component';
|
import { action } from '@ember/object';
|
||||||
import layout from '../templates/components/info-table-row';
|
// import layout from '../templates/components/info-table-row';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @module InfoTableRow
|
* @module InfoTableRow
|
||||||
|
@ -14,42 +14,35 @@ import layout from '../templates/components/info-table-row';
|
||||||
* <InfoTableRow @value={{5}} @label="TTL" @helperText="Some description"/>
|
* <InfoTableRow @value={{5}} @label="TTL" @helperText="Some description"/>
|
||||||
* ```
|
* ```
|
||||||
*
|
*
|
||||||
* @param value=null {any} - The the data to be displayed - by default the content of the component will only show if there is a value. Also note that special handling is given to boolean values - they will render `Yes` for true and `No` for false.
|
|
||||||
* @param label=null {string} - The display name for the value.
|
* @param label=null {string} - The display name for the value.
|
||||||
* @param helperText=null {string} - Text to describe the value displayed beneath the label.
|
* @param helperText=null {string} - Text to describe the value displayed beneath the label.
|
||||||
* @param alwaysRender=false {Boolean} - Indicates if the component content should be always be rendered. When false, the value of `value` will be used to determine if the component should render.
|
* @param value=null {any} - The the data to be displayed - by default the content of the component will only show if there is a value. Also note that special handling is given to boolean values - they will render `Yes` for true and `No` for false. Overridden by block if exists
|
||||||
|
* @param [alwaysRender=false] {Boolean} - Indicates if the component content should be always be rendered. When false, the value of `value` will be used to determine if the component should render.
|
||||||
|
* @param [defaultShown] {String} - Text that renders as value if alwaysRender=true. Eg. "Vault default"
|
||||||
|
* @param [tooltipText] {String} - Text if a tooltip should display over the value.
|
||||||
|
* @param [isTooltipCopyable] {Boolean} - Allows tooltip click to copy
|
||||||
* @param [type=array] {string} - The type of value being passed in. This is used for when you want to trim an array. For example, if you have an array value that can equal length 15+ this will trim to show 5 and count how many more are there
|
* @param [type=array] {string} - The type of value being passed in. This is used for when you want to trim an array. For example, if you have an array value that can equal length 15+ this will trim to show 5 and count how many more are there
|
||||||
* @param [isLink=true] {Boolean} - Passed through to InfoTableItemArray. Indicates if the item should contain a link-to component. Only setup for arrays, but this could be changed if needed.
|
* @param [isLink=true] {Boolean} - Passed through to InfoTableItemArray. Indicates if the item should contain a link-to component. Only setup for arrays, but this could be changed if needed.
|
||||||
* @param [modelType=null] {string} - Passed through to InfoTableItemArray. Tells what model you want data for the allOptions to be returned from. Used in conjunction with the the isLink.
|
* @param [modelType=null] {string} - Passed through to InfoTableItemArray. Tells what model you want data for the allOptions to be returned from. Used in conjunction with the the isLink.
|
||||||
* @param [queryParam] {String} - Passed through to InfoTableItemArray. If you want to specific a tab for the View All XX to display to. Ex: role
|
* @param [queryParam] {String} - Passed through to InfoTableItemArray. If you want to specific a tab for the View All XX to display to. Ex= role
|
||||||
* @param [backend] {String} - Passed through to InfoTableItemArray. To specify secrets backend to point link to Ex: transformation
|
* @param [backend] {String} - Passed through to InfoTableItemArray. To specify secrets backend to point link to Ex= transformation
|
||||||
* @param [viewAll] {String} - Passed through to InfoTableItemArray. Specify the word at the end of the link View all.
|
* @param [viewAll] {String} - Passed through to InfoTableItemArray. Specify the word at the end of the link View all.
|
||||||
* @param [tooltipText] {String} - Text if a tooltip should display over the value.
|
|
||||||
* @param [isTooltipCopyable] {Boolean} - Allows tooltip click to copy
|
|
||||||
* @param [defaultShown] {String} - Text that renders as value if alwaysRender=true. Eg. "Vault default"
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export default Component.extend({
|
export default class InfoTableRowComponent extends Component {
|
||||||
layout,
|
@tracked
|
||||||
'data-test-component': 'info-table-row',
|
hasLabelOverflow = false; // is calculated and set in didInsertElement
|
||||||
classNames: ['info-table-row'],
|
|
||||||
isVisible: or('alwaysRender', 'value'),
|
|
||||||
|
|
||||||
alwaysRender: false,
|
get isVisible() {
|
||||||
label: null,
|
return this.args.alwaysRender || !this.valueIsEmpty;
|
||||||
helperText: null,
|
}
|
||||||
value: null,
|
|
||||||
tooltipText: '',
|
|
||||||
isTooltipCopyable: false,
|
|
||||||
defaultShown: '',
|
|
||||||
hasLabelOverflow: false, // is calculated and set in didInsertElement
|
|
||||||
|
|
||||||
valueIsBoolean: computed('value', function () {
|
get valueIsBoolean() {
|
||||||
return typeOf(this.value) === 'boolean';
|
return typeOf(this.args.value) === 'boolean';
|
||||||
}),
|
}
|
||||||
|
|
||||||
valueIsEmpty: computed('value', function () {
|
get valueIsEmpty() {
|
||||||
let { value } = this;
|
let { value } = this.args;
|
||||||
if (typeOf(value) === 'array' && value.length === 0) {
|
if (typeOf(value) === 'array' && value.length === 0) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -63,17 +56,16 @@ export default Component.extend({
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}),
|
}
|
||||||
|
|
||||||
didInsertElement() {
|
@action
|
||||||
this._super(...arguments);
|
calculateLabelOverflow(el) {
|
||||||
const labelDiv = this.element.querySelector('div');
|
const labelDiv = el;
|
||||||
const labelText = this.element.querySelector('.is-label');
|
const labelText = el.querySelector('.is-label');
|
||||||
if (labelDiv && labelText) {
|
if (labelDiv && labelText) {
|
||||||
if (labelText.offsetWidth > labelDiv.offsetWidth) {
|
if (labelText.offsetWidth > labelDiv.offsetWidth) {
|
||||||
labelDiv.classList.add('label-overflow');
|
this.hasLabelOverflow = true;
|
||||||
this.set('hasLabelOverflow', true);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
});
|
}
|
||||||
|
|
|
@ -1,82 +0,0 @@
|
||||||
{{#if (or this.alwaysRender this.value)}}
|
|
||||||
<div class="column is-one-quarter" data-test-label-div>
|
|
||||||
{{#if this.label}}
|
|
||||||
{{#if this.hasLabelOverflow}}
|
|
||||||
<ToolTip @verticalPosition="below" @horizontalPosition="left" as |T|>
|
|
||||||
<T.Trigger @tabindex={{false}}>
|
|
||||||
<span class="is-label has-text-grey-dark" data-test-row-label={{this.label}}>{{this.label}}</span>
|
|
||||||
</T.Trigger>
|
|
||||||
<T.Content class="tool-tip">
|
|
||||||
<div class="box fit-content">
|
|
||||||
{{this.label}}
|
|
||||||
</div>
|
|
||||||
</T.Content>
|
|
||||||
</ToolTip>
|
|
||||||
{{else}}
|
|
||||||
<span class="is-label has-text-grey-dark" data-test-row-label={{this.label}}>{{this.label}}</span>
|
|
||||||
{{/if}}
|
|
||||||
{{#if this.helperText}}
|
|
||||||
<div>
|
|
||||||
<span class="is-label helper-text has-text-grey">{{this.helperText}}</span>
|
|
||||||
</div>
|
|
||||||
{{/if}}
|
|
||||||
{{else}}
|
|
||||||
<Icon @name="minus" />
|
|
||||||
{{/if}}
|
|
||||||
</div>
|
|
||||||
<div class="column is-flex" data-test-value-div={{this.label}}>
|
|
||||||
{{#if (has-block)}}
|
|
||||||
{{yield}}
|
|
||||||
{{else if this.valueIsBoolean}}
|
|
||||||
{{#if this.value}}
|
|
||||||
<Icon class="icon-true" @name="check-circle" data-test-boolean-true />
|
|
||||||
Yes
|
|
||||||
{{else}}
|
|
||||||
<Icon @name="x-square" class="icon-false" />
|
|
||||||
No
|
|
||||||
{{/if}}
|
|
||||||
{{! alwaysRender is still true }}
|
|
||||||
{{else if (and (not this.value) this.defaultShown)}}
|
|
||||||
<span data-test-row-value={{this.label}}>{{this.defaultShown}}</span>
|
|
||||||
{{else if this.valueIsEmpty}}
|
|
||||||
<Icon @name="minus" />
|
|
||||||
{{else}}
|
|
||||||
{{#if (eq this.type "array")}}
|
|
||||||
<InfoTableItemArray
|
|
||||||
@backend={{this.backend}}
|
|
||||||
@displayArray={{this.value}}
|
|
||||||
@isLink={{this.isLink}}
|
|
||||||
@label={{this.label}}
|
|
||||||
@modelType={{this.modelType}}
|
|
||||||
@queryParam={{this.queryParam}}
|
|
||||||
@viewAll={{this.viewAll}}
|
|
||||||
@wildcardLabel={{this.wildcardLabel}}
|
|
||||||
/>
|
|
||||||
{{else}}
|
|
||||||
{{#if this.tooltipText}}
|
|
||||||
<ToolTip @verticalPosition="above" @horizontalPosition="left" as |T|>
|
|
||||||
<T.Trigger @tabindex={{false}}>
|
|
||||||
<span class="is-word-break has-text-black" data-test-row-value={{this.label}}>{{this.value}}</span>
|
|
||||||
</T.Trigger>
|
|
||||||
<T.Content class="tool-tip">
|
|
||||||
<CopyButton
|
|
||||||
@clipboardText={{this.tooltipText}}
|
|
||||||
@success={{action (set-flash-message "Data copied!")}}
|
|
||||||
@tagName="div"
|
|
||||||
@disabled={{not this.isTooltipCopyable}}
|
|
||||||
class={{if this.isTooltipCopyable "has-pointer"}}
|
|
||||||
data-test-tooltip-copy
|
|
||||||
>
|
|
||||||
<div class="box">
|
|
||||||
{{this.tooltipText}}
|
|
||||||
</div>
|
|
||||||
</CopyButton>
|
|
||||||
</T.Content>
|
|
||||||
</ToolTip>
|
|
||||||
{{else}}
|
|
||||||
<span class="is-word-break has-text-black" data-test-row-value={{this.label}}>{{this.value}}</span>
|
|
||||||
{{/if}}
|
|
||||||
{{/if}}
|
|
||||||
{{/if}}
|
|
||||||
</div>
|
|
||||||
{{/if}}
|
|
|
@ -25,7 +25,7 @@
|
||||||
</div>
|
</div>
|
||||||
{{#if this.model.config.mode}}
|
{{#if this.model.config.mode}}
|
||||||
<div class="box is-fullwidth is-shadowless">
|
<div class="box is-fullwidth is-shadowless">
|
||||||
<InfoTableRow @label="Mode" @value={{this.model.config.mode}} @data-test-mount-config-mode={{true}} />
|
<InfoTableRow @label="Mode" @value={{this.model.config.mode}} data-test-mount-config-mode={{true}} />
|
||||||
<InfoTableRow @label="Paths" @value={{this.model.config.paths}}>
|
<InfoTableRow @label="Paths" @value={{this.model.config.paths}}>
|
||||||
<ul class="list--comma" data-test-mount-config-paths={{true}}>
|
<ul class="list--comma" data-test-mount-config-paths={{true}}>
|
||||||
{{#each this.model.config.paths as |path|}}
|
{{#each this.model.config.paths as |path|}}
|
||||||
|
|
|
@ -55,8 +55,7 @@ elRplAzrMF4=
|
||||||
await settled();
|
await settled();
|
||||||
await generatePage.issueCert('foo');
|
await generatePage.issueCert('foo');
|
||||||
await settled();
|
await settled();
|
||||||
let countMaskedFonts = document.querySelectorAll('.masked-font').length;
|
assert.dom('.masked-font').exists({ count: 3 }, 'renders 3 masked rows');
|
||||||
assert.equal(countMaskedFonts, 3); // certificate, issuing ca, and private key
|
|
||||||
let firstUnMaskButton = document.querySelectorAll('.masked-input-toggle')[0];
|
let firstUnMaskButton = document.querySelectorAll('.masked-input-toggle')[0];
|
||||||
await click(firstUnMaskButton);
|
await click(firstUnMaskButton);
|
||||||
assert.dom('.masked-value').hasTextContaining('-----BEGIN CERTIFICATE-----');
|
assert.dom('.masked-value').hasTextContaining('-----BEGIN CERTIFICATE-----');
|
||||||
|
|
|
@ -76,9 +76,9 @@ module('Integration | Component | InfoTableRow', function (hooks) {
|
||||||
this.set('isCopyable', false);
|
this.set('isCopyable', false);
|
||||||
|
|
||||||
await render(hbs`
|
await render(hbs`
|
||||||
<InfoTableRow
|
<InfoTableRow
|
||||||
@label={{this.label}}
|
@label={{this.label}}
|
||||||
@value={{this.value}}
|
@value={{this.value}}
|
||||||
@tooltipText="Foo bar"
|
@tooltipText="Foo bar"
|
||||||
@isTooltipCopyable={{this.isCopyable}}
|
@isTooltipCopyable={{this.isCopyable}}
|
||||||
/>
|
/>
|
||||||
|
@ -156,10 +156,96 @@ module('Integration | Component | InfoTableRow', function (hooks) {
|
||||||
@value={{this.value}}
|
@value={{this.value}}
|
||||||
@label={{this.label}}
|
@label={{this.label}}
|
||||||
@alwaysRender={{true}}>
|
@alwaysRender={{true}}>
|
||||||
Block content is here
|
Block content is here
|
||||||
</InfoTableRow>`);
|
</InfoTableRow>`);
|
||||||
|
|
||||||
let block = document.querySelector('[data-test-value-div]').textContent.trim();
|
let block = document.querySelector('[data-test-value-div]').textContent.trim();
|
||||||
assert.equal(block, 'Block content is here', 'renders block passed through');
|
assert.equal(block, 'Block content is here', 'renders block passed through');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('Row renders when block content even if alwaysRender = false', async function (assert) {
|
||||||
|
await render(hbs`<InfoTableRow
|
||||||
|
@label={{this.label}}
|
||||||
|
@alwaysRender={{false}}>
|
||||||
|
Block content
|
||||||
|
</InfoTableRow>`);
|
||||||
|
assert.dom('[data-test-value-div]').exists('renders block');
|
||||||
|
assert.dom('[data-test-value-div]').hasText('Block content', 'renders block');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Row does not render empty block content when alwaysRender = false', async function (assert) {
|
||||||
|
await render(hbs`<InfoTableRow
|
||||||
|
@label={{this.label}}
|
||||||
|
@alwaysRender={{false}} />`);
|
||||||
|
assert.dom('[data-test-component="info-table-row"]').doesNotExist();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Has dashed label if none provided', async function (assert) {
|
||||||
|
await render(hbs`<InfoTableRow
|
||||||
|
@value={{this.value}}
|
||||||
|
/>`);
|
||||||
|
assert.dom('[data-test-component="info-table-row"]').exists();
|
||||||
|
assert.dom('[data-test-icon="minus"]').exists('renders dash when no label');
|
||||||
|
});
|
||||||
|
test('Truncates the label if too long', async function (assert) {
|
||||||
|
this.set('label', 'abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz');
|
||||||
|
await render(hbs`<InfoTableRow
|
||||||
|
@label={{this.label}}
|
||||||
|
@value={{this.value}}
|
||||||
|
/>`);
|
||||||
|
assert.dom('[data-test-component="info-table-row"]').exists('Row renders');
|
||||||
|
assert.dom('[data-test-label-div].label-overflow').exists('Label has class label-overflow');
|
||||||
|
await triggerEvent('[data-test-row-label]', 'mouseenter');
|
||||||
|
assert.dom('[data-test-label-tooltip]').exists('Label tooltip exists on hover');
|
||||||
|
});
|
||||||
|
test('Renders if block value and alwaysrender=false', async function (assert) {
|
||||||
|
await render(hbs`<InfoTableRow @alwaysRender={{false}}>{{this.value}}</InfoTableRow>`);
|
||||||
|
assert.dom('[data-test-component="info-table-row"]').exists();
|
||||||
|
});
|
||||||
|
test('Does not render if value is empty and alwaysrender=false', async function (assert) {
|
||||||
|
await render(hbs`<InfoTableRow @alwaysRender={{false}} @value="" />`);
|
||||||
|
assert.dom('[data-test-component="info-table-row"]').doesNotExist();
|
||||||
|
});
|
||||||
|
test('Renders dash for value if value empty and alwaysRender=true', async function (assert) {
|
||||||
|
await render(hbs`<InfoTableRow
|
||||||
|
@label={{this.label}}
|
||||||
|
@alwaysRender={{true}}
|
||||||
|
/>`);
|
||||||
|
assert.dom('[data-test-component="info-table-row"]').exists();
|
||||||
|
assert.dom('[data-test-value-div] [data-test-icon="minus"]').exists('renders dash for value');
|
||||||
|
});
|
||||||
|
test('Renders block over @value or @defaultShown', async function (assert) {
|
||||||
|
await render(hbs`<InfoTableRow
|
||||||
|
@label={{this.label}}
|
||||||
|
@value="bar"
|
||||||
|
@defaultShown="baz"
|
||||||
|
>
|
||||||
|
foo
|
||||||
|
</InfoTableRow>`);
|
||||||
|
assert.dom('[data-test-component="info-table-row"]').exists();
|
||||||
|
assert.dom('[data-test-value-div]').hasText('foo', 'renders block value');
|
||||||
|
});
|
||||||
|
test('Renders icons if value is boolean', async function (assert) {
|
||||||
|
this.set('value', true);
|
||||||
|
await render(hbs`<InfoTableRow
|
||||||
|
@label={{this.label}}
|
||||||
|
@value={{this.value}}
|
||||||
|
/>`);
|
||||||
|
|
||||||
|
assert.dom('[data-test-boolean-true]').exists('check icon exists');
|
||||||
|
assert.dom('[data-test-value-div]').hasText('Yes', 'Renders yes text');
|
||||||
|
this.set('value', false);
|
||||||
|
assert.dom('[data-test-boolean-false]').exists('x icon exists');
|
||||||
|
assert.dom('[data-test-value-div]').hasText('No', 'renders no text');
|
||||||
|
});
|
||||||
|
test('Renders data-test attrs passed from parent', async function (assert) {
|
||||||
|
this.set('value', true);
|
||||||
|
await render(hbs`<InfoTableRow
|
||||||
|
@label={{this.label}}
|
||||||
|
@value={{this.value}}
|
||||||
|
data-test-foo-bar
|
||||||
|
/>`);
|
||||||
|
|
||||||
|
assert.dom('[data-test-foo-bar]').exists();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue