UI Conditionally Copy Tooltips (#12890)

* adds conditional tooltip copying to InfoTableRow component

* adds changelog entry
This commit is contained in:
Jordan Reimer 2021-10-21 09:26:56 -06:00 committed by GitHub
parent d66fd98d4a
commit 16be98fa1c
7 changed files with 49 additions and 7 deletions

3
changelog/12890.txt Normal file
View file

@ -0,0 +1,3 @@
```release-note:improvement
ui: Click to copy database static role last rotation value in tooltip
```

View file

@ -76,6 +76,7 @@
@label="Last Vault rotation" @label="Last Vault rotation"
@value={{date-format @model.lastVaultRotation 'MMMM d yyyy, h:mm:ss a'}} @value={{date-format @model.lastVaultRotation 'MMMM d yyyy, h:mm:ss a'}}
@tooltipText={{@model.lastVaultRotation}} @tooltipText={{@model.lastVaultRotation}}
@isTooltipCopyable={{true}}
/> />
<InfoTableRow @label="Password" @value={{@model.password}}> <InfoTableRow @label="Password" @value={{@model.password}}>
<MaskedInput <MaskedInput

View file

@ -25,6 +25,7 @@ import layout from '../templates/components/info-table-row';
* @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 [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" * @param [defaultShown] {String} - Text that renders as value if alwaysRender=true. Eg. "Vault default"
*/ */
@ -39,6 +40,7 @@ export default Component.extend({
helperText: null, helperText: null,
value: null, value: null,
tooltipText: '', tooltipText: '',
isTooltipCopyable: false,
defaultShown: '', defaultShown: '',
valueIsBoolean: computed('value', function() { valueIsBoolean: computed('value', function() {

View file

@ -3,6 +3,6 @@ import layout from '../templates/components/tool-tip';
export default HoverDropdown.extend({ export default HoverDropdown.extend({
layout, layout,
delay: 0, delay: 200, // delay allows tooltip to remain open on content hover
horizontalPosition: 'auto-right', horizontalPosition: 'auto-right',
}); });

View file

@ -58,9 +58,18 @@
<code class="is-word-break has-text-black" data-test-row-value="{{label}}">{{value}}</code> <code class="is-word-break has-text-black" data-test-row-value="{{label}}">{{value}}</code>
</T.trigger> </T.trigger>
<T.content @class="tool-tip"> <T.content @class="tool-tip">
<CopyButton
@clipboardText={{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"> <div class="box">
{{tooltipText}} {{tooltipText}}
</div> </div>
</CopyButton>
</T.content> </T.content>
</ToolTip> </ToolTip>
{{else}} {{else}}

View file

@ -1,4 +1,5 @@
{{#basic-dropdown-hover renderInPlace=renderInPlace {{#basic-dropdown-hover
renderInPlace=renderInPlace
verticalPosition=verticalPosition verticalPosition=verticalPosition
horizontalPosition=horizontalPosition horizontalPosition=horizontalPosition
matchTriggerWidth=matchTriggerWidth matchTriggerWidth=matchTriggerWidth
@ -8,14 +9,17 @@
onOpen=onOpen onOpen=onOpen
onClose=onClose onClose=onClose
onFocus=onFocus onFocus=onFocus
calculateInPlacePosition=calculateInPlacePosition as |dd|}} calculateInPlacePosition=calculateInPlacePosition
as |dd|
}}
{{yield (assign {{yield (assign
dd dd
(hash (hash
trigger=(component dd.trigger trigger=(component dd.trigger
onMouseDown=(action "prevent") onMouseDown=(action "prevent")
onMouseEnter=(action "open") onMouseEnter=(action "open")
onMouseLeave=(action "close")) onMouseLeave=(action "close")
)
content=(component dd.content content=(component dd.content
onMouseEnter=(action "open") onMouseEnter=(action "open")
onMouseLeave=(action "close") onMouseLeave=(action "close")

View file

@ -71,6 +71,29 @@ module('Integration | Component | InfoTableRow', function(hooks) {
assert.equal(tooltip, 'Tooltip text!', 'renders tooltip text'); assert.equal(tooltip, 'Tooltip text!', 'renders tooltip text');
}); });
test('it should copy tooltip', async function(assert) {
assert.expect(4);
this.set('isCopyable', false);
await render(hbs`
<InfoTableRow
@label={{label}}
@value={{value}}
@tooltipText="Foo bar"
@isTooltipCopyable={{isCopyable}}
/>
`);
await triggerEvent('[data-test-value-div="test label"] .ember-basic-dropdown-trigger', 'mouseenter');
await settled();
assert.dom('[data-test-tooltip-copy]').hasAttribute('disabled', '', 'Tooltip copy button is disabled');
assert.dom('[data-test-tooltip-copy]').doesNotHaveClass('has-pointer', 'Pointer class not applied when disabled');
this.set('isCopyable', true);
assert.dom('[data-test-tooltip-copy]').doesNotHaveAttribute('disabled', 'Tooltip copy button is enabled');
assert.dom('[data-test-tooltip-copy]').hasClass('has-pointer', 'Pointer class applied to copy button');
});
test('it renders a string with no link if isLink is true and the item type is not an array.', async function(assert) { test('it renders a string with no link if isLink is true and the item type is not an array.', async function(assert) {
// This could be changed in the component so that it adds a link for any item type, but right now it should only add a link if item type is an array. // This could be changed in the component so that it adds a link for any item type, but right now it should only add a link if item type is an array.
await render(hbs`<InfoTableRow await render(hbs`<InfoTableRow