parent
75eb0f862e
commit
9fb8be5a72
|
@ -5,8 +5,10 @@ const { computed } = Ember;
|
|||
const GLYPHS_WITH_SVG_TAG = [
|
||||
'folder',
|
||||
'file',
|
||||
'hidden',
|
||||
'perf-replication',
|
||||
'role',
|
||||
'visible',
|
||||
'information-reversed',
|
||||
'true',
|
||||
'false',
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
import Ember from 'ember';
|
||||
const { computed } = Ember;
|
||||
import autosize from 'autosize';
|
||||
|
||||
|
||||
export default Ember.Component.extend({
|
||||
value: null,
|
||||
didInsertElement(){
|
||||
this._super(...arguments);
|
||||
autosize(this.element.querySelector('textarea'));
|
||||
},
|
||||
didUpdate(){
|
||||
this._super(...arguments);
|
||||
autosize.update(this.element.querySelector('textarea'));
|
||||
},
|
||||
willDestroyElement(){
|
||||
this._super(...arguments);
|
||||
autosize.destroy(this.element.querySelector('textarea'));
|
||||
},
|
||||
shouldObscure: computed("isMasked", "isFocused", "value", function(){
|
||||
if(this.get('value') === "" ){
|
||||
return false;
|
||||
}
|
||||
if(this.get('isFocused') === true){
|
||||
return false;
|
||||
}
|
||||
return this.get('isMasked');
|
||||
}),
|
||||
displayValue: computed("shouldObscure", function(){
|
||||
if(this.get("shouldObscure")){
|
||||
return "■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■";
|
||||
}
|
||||
else{
|
||||
return this.get('value');
|
||||
}
|
||||
}),
|
||||
isMasked: true,
|
||||
isFocused: false,
|
||||
displayOnly: false,
|
||||
onKeyDown(){},
|
||||
onChange(){},
|
||||
actions: {
|
||||
toggleMask(){
|
||||
this.toggleProperty('isMasked');
|
||||
},
|
||||
updateValue(e){
|
||||
this.set('value', e.target.value);
|
||||
this.onChange();
|
||||
},
|
||||
}
|
||||
});
|
|
@ -1,7 +1,6 @@
|
|||
import Ember from 'ember';
|
||||
import FocusOnInsertMixin from 'vault/mixins/focus-on-insert';
|
||||
import keys from 'vault/lib/keycodes';
|
||||
import autosize from 'autosize';
|
||||
import KVObject from 'vault/lib/kv-object';
|
||||
|
||||
const LIST_ROUTE = 'vault.cluster.secrets.backend.list';
|
||||
|
@ -51,13 +50,6 @@ export default Ember.Component.extend(FocusOnInsertMixin, {
|
|||
}
|
||||
},
|
||||
|
||||
didRender() {
|
||||
const textareas = this.$('textarea');
|
||||
if (textareas.length) {
|
||||
autosize(textareas);
|
||||
}
|
||||
},
|
||||
|
||||
willDestroyElement() {
|
||||
const key = this.get('key');
|
||||
if (get(key, 'isError') && !key.isDestroyed) {
|
||||
|
@ -164,7 +156,7 @@ export default Ember.Component.extend(FocusOnInsertMixin, {
|
|||
},
|
||||
|
||||
actions: {
|
||||
handleKeyDown(_, e) {
|
||||
handleKeyDown(e) {
|
||||
e.stopPropagation();
|
||||
if (!(e.keyCode === keys.ENTER && e.metaKey)) {
|
||||
return;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
.console-ui-panel-scroller {
|
||||
background: linear-gradient(to right, #191A1C, #1B212D);
|
||||
background: linear-gradient(to right, #191a1c, #1b212d);
|
||||
height: 0;
|
||||
left: 0;
|
||||
overflow: auto;
|
||||
|
@ -24,8 +24,8 @@
|
|||
font-weight: $font-weight-semibold;
|
||||
transition: justify-content $speed ease-in;
|
||||
|
||||
|
||||
pre, p {
|
||||
pre,
|
||||
p {
|
||||
background: none;
|
||||
color: inherit;
|
||||
font-size: $body-size;
|
||||
|
@ -42,8 +42,7 @@
|
|||
padding: $size-8 $size-4;
|
||||
}
|
||||
|
||||
.button,
|
||||
{
|
||||
.button {
|
||||
background: transparent;
|
||||
border: none;
|
||||
color: $grey-dark;
|
||||
|
@ -130,19 +129,21 @@
|
|||
}
|
||||
|
||||
.panel-open {
|
||||
.navbar, .navbar-sections{
|
||||
.navbar,
|
||||
.navbar-sections {
|
||||
transition: transform $speed ease-in;
|
||||
}
|
||||
}
|
||||
|
||||
.panel-open.panel-fullscreen {
|
||||
.navbar, .navbar-sections{
|
||||
.navbar,
|
||||
.navbar-sections {
|
||||
transform: translate3d(0, -100px, 0);
|
||||
}
|
||||
}
|
||||
|
||||
.page-container > header {
|
||||
background: linear-gradient(to right, #191A1C, #1B212D);
|
||||
background: linear-gradient(to right, #191a1c, #1b212d);
|
||||
}
|
||||
|
||||
header .navbar,
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
bottom: 0;
|
||||
left: 0;
|
||||
margin: 10px;
|
||||
z-index: 1;
|
||||
z-index: 300;
|
||||
|
||||
.notification {
|
||||
box-shadow: $box-shadow-high;
|
||||
|
|
|
@ -0,0 +1,72 @@
|
|||
.masked-input {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.masked-input .masked-value {
|
||||
padding-left: 2.50rem;
|
||||
}
|
||||
|
||||
// we want to style the boxes the same everywhere so they
|
||||
// need to be the same font and small
|
||||
.masked-input.masked .masked-value {
|
||||
font-size: 9px;
|
||||
font-family: $family-primary;
|
||||
}
|
||||
|
||||
.masked-input.masked .masked-value {
|
||||
line-height: 2.5;
|
||||
}
|
||||
// aligns the boxes on the input page
|
||||
.masked-input.masked:not(.display-only) .masked-value {
|
||||
line-height: 3;
|
||||
}
|
||||
|
||||
//override bulma's pre styling
|
||||
.masked-input .display-only {
|
||||
line-height: 1.5;
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.masked-input-toggle {
|
||||
background: transparent;
|
||||
position: absolute;
|
||||
height: auto;
|
||||
top: $size-6/4;
|
||||
bottom: $size-6/4;
|
||||
left: 1px;
|
||||
line-height: 1rem;
|
||||
min-width: 0;
|
||||
max-height: 2rem;
|
||||
padding: 0 $size-8;
|
||||
z-index: 100;
|
||||
border: 0;
|
||||
box-shadow: none;
|
||||
color: $blue;
|
||||
|
||||
&:active,
|
||||
&.is-active,
|
||||
&:focus,
|
||||
&.is-focused,
|
||||
&:hover,
|
||||
&:focus:not(:active) {
|
||||
color: $blue;
|
||||
border: 0;
|
||||
box-shadow: none;
|
||||
}
|
||||
}
|
||||
|
||||
.masked-input.display-only .masked-input-toggle {
|
||||
top: 0;
|
||||
font-size: 0.5rem;
|
||||
height: 1rem;
|
||||
padding-left: 0;
|
||||
}
|
||||
|
||||
.masked-input .input:focus + .masked-input-toggle {
|
||||
background: rgba($white, 0.95);
|
||||
}
|
||||
|
||||
.masked-input.masked .masked-value,
|
||||
.masked-input.masked .masked-input-toggle {
|
||||
color: $grey-light;
|
||||
}
|
|
@ -57,6 +57,7 @@
|
|||
@import "./components/list-pagination";
|
||||
@import "./components/loader";
|
||||
@import "./components/login-form";
|
||||
@import "./components/masked-input";
|
||||
@import "./components/message-in-page";
|
||||
@import "./components/page-header";
|
||||
@import "./components/popup-menu";
|
||||
|
|
|
@ -64,10 +64,14 @@ $radius: 2px;
|
|||
//box
|
||||
$box-radius: 0;
|
||||
$box-shadow: 0 0 0 1px rgba($black, 0.1);
|
||||
$box-shadow-low: 0 5px 1px -2px rgba($black, 0.12), 0 3px 2px -1px rgba($black, 0);
|
||||
$box-shadow-middle: 0 8px 4px -4px rgba($black, 0.10), 0 6px 8px -2px rgba($black, 0.05);
|
||||
$box-shadow-high: 0 12px 5px -7px rgba($black, 0.08), 0 11px 10px -3px rgba($black, 0.10);
|
||||
$box-shadow-highest: 0 16px 6px -10px rgba($black, 0.06), 0 16px 16px -4px rgba($black, 0.20);
|
||||
$box-shadow-low: 0 5px 1px -2px rgba($black, 0.12),
|
||||
0 3px 2px -1px rgba($black, 0);
|
||||
$box-shadow-middle: 0 8px 4px -4px rgba($black, 0.10),
|
||||
0 6px 8px -2px rgba($black, 0.05);
|
||||
$box-shadow-high: 0 12px 5px -7px rgba($black, 0.08),
|
||||
0 11px 10px -3px rgba($black, 0.10);
|
||||
$box-shadow-highest: 0 16px 6px -10px rgba($black, 0.06),
|
||||
0 16px 16px -4px rgba($black, 0.20);
|
||||
|
||||
$link: $blue;
|
||||
$text: $black;
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
<div class="masked-input {{if shouldObscure "masked"}} {{if displayOnly "display-only"}}" data-test-masked-input>
|
||||
{{#if displayOnly}}
|
||||
<pre class="masked-value display-only">{{displayValue}}</pre>
|
||||
{{else}}
|
||||
<textarea
|
||||
class="input masked-value"
|
||||
rows=1
|
||||
wrap="off"
|
||||
placeholder="value"
|
||||
onfocus={{action (mut isFocused) true}}
|
||||
onblur={{action (mut isFocused) false}}
|
||||
onkeydown={{action onKeyDown}}
|
||||
onchange={{action "updateValue"}}
|
||||
value={{readonly displayValue}}
|
||||
data-test-textarea
|
||||
/>
|
||||
{{/if}}
|
||||
<button {{action "toggleMask"}} class="{{if (eq value "") "has-text-grey"}} masked-input-toggle button is-compact" data-test-button>
|
||||
{{i-con glyph=(if shouldObscure "hidden" "visible") aria-hidden="true" size=16}}
|
||||
</button>
|
||||
</div>
|
|
@ -18,16 +18,12 @@
|
|||
}}
|
||||
</div>
|
||||
<div class="column info-table-row-edit">
|
||||
{{textarea
|
||||
{{masked-input
|
||||
data-test-secret-value=true
|
||||
name=secret.name
|
||||
key-down="handleKeyDown"
|
||||
change="handleChange"
|
||||
onKeyDown=(action "handleKeyDown")
|
||||
onChange=(action "handleChange")
|
||||
value=secret.value
|
||||
wrap="off"
|
||||
class="input"
|
||||
placeholder="value"
|
||||
rows=1
|
||||
}}
|
||||
</div>
|
||||
<div class="column is-narrow info-table-row-edit">
|
||||
|
|
|
@ -17,6 +17,8 @@
|
|||
</div>
|
||||
</div>
|
||||
{{#each-in key.secretData as |key value|}}
|
||||
{{info-table-row label=key value=value alwaysRender=true}}
|
||||
{{#info-table-row label=key value=value alwaysRender=true}}
|
||||
{{masked-input value=value displayOnly=true}}
|
||||
{{/info-table-row}}
|
||||
{{/each-in}}
|
||||
{{/if}}
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
<svg width={{size}} height={{size}} viewBox="0 0 16 16" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<path d="M8,12 C5.05448133,12 2.38781467,10.6666667 0,8 C2.38781467,5.33333333 5.05448133,4 8,4 C10.9455187,4 13.6121853,5.33333333 16,8 C13.6121853,10.6666667 10.9455187,12 8,12 Z M8,5 C5.60667919,5 3.41034085,5.98473247 1.37808575,8 C3.41034085,10.0152675 5.60667919,11 8,11 C10.3933208,11 12.5896591,10.0152675 14.6219143,8 C12.5896591,5.98473247 10.3933208,5 8,5 Z M6.08844608,10.9323692 L3.20710678,13.8137085 L2.5,13.1066017 L5.3362082,10.2703935 C4.8147799,9.65920414 4.5,8.86636246 4.5,8 C4.5,6.06700338 6.06700338,4.5 8,4.5 C8.86636246,4.5 9.65920414,4.8147799 10.2703935,5.3362082 L13.1066017,2.5 L13.8137085,3.20710678 L10.9323692,6.08844608 C11.2913366,6.63798846 11.5,7.29462625 11.5,8 C11.5,9.93299662 9.93299662,11.5 8,11.5 C7.29462625,11.5 6.63798846,11.2913366 6.08844608,10.9323692 Z M6.81756939,10.2032459 C7.16962006,10.3925802 7.57226541,10.5 8,10.5 C9.38071187,10.5 10.5,9.38071187 10.5,8 C10.5,7.57226541 10.3925802,7.16962006 10.2032459,6.81756939 L6.81756939,10.2032459 Z M6.04644524,9.56015648 L9.56015648,6.04644524 C9.13251828,5.70447638 8.59013815,5.5 8,5.5 C6.61928813,5.5 5.5,6.61928813 5.5,8 C5.5,8.59013815 5.70447638,9.13251828 6.04644524,9.56015648 Z" id="path-1"></path>
|
||||
</svg>
|
After Width: | Height: | Size: 1.3 KiB |
|
@ -0,0 +1,3 @@
|
|||
<svg width={{size}} height={{size}} viewBox="0 0 16 16" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<path d="M10.2290316,5.30146576 C11.0053403,5.94343599 11.5,6.91395101 11.5,8 C11.5,9.08604899 11.0053403,10.056564 10.2290316,10.6985342 C11.7764341,10.2677626 13.2372598,9.37308018 14.6219143,8 C13.2372598,6.62691982 11.7764341,5.73223742 10.2290316,5.30146576 Z M5.77096844,10.6985342 C4.99465975,10.056564 4.5,9.08604899 4.5,8 C4.5,6.91395101 4.99465975,5.94343599 5.77096844,5.30146576 C4.22356585,5.73223742 2.76274022,6.62691982 1.37808575,8 C2.76274022,9.37308018 4.22356585,10.2677626 5.77096844,10.6985342 Z M8,12 C5.05448133,12 2.38781467,10.6666667 0,8 C2.38781467,5.33333333 5.05448133,4 8,4 C10.9455187,4 13.6121853,5.33333333 16,8 C13.6121853,10.6666667 10.9455187,12 8,12 Z M8.9651005,7.74939083 C9.51704882,7.76866529 9.98011637,7.33684781 9.99939083,6.7848995 C10.0186653,6.23295118 9.58684781,5.76988363 9.0348995,5.75060917 C8.48295118,5.73133471 8.01988363,6.16315219 8.00060917,6.7151005 C7.98133471,7.26704882 8.41315219,7.73011637 8.9651005,7.74939083 Z" id="path-1"></path>
|
||||
</svg>
|
After Width: | Height: | Size: 1.1 KiB |
|
@ -33,7 +33,7 @@
|
|||
},
|
||||
"devDependencies": {
|
||||
"Duration.js": "icholy/Duration.js#golang_compatible",
|
||||
"autosize": "3.0.17",
|
||||
"autosize": "^4.0.0",
|
||||
"babel-plugin-transform-object-rest-spread": "^6.23.0",
|
||||
"base64-js": "1.2.1",
|
||||
"broccoli-asset-rev": "^2.4.5",
|
||||
|
|
|
@ -8,7 +8,7 @@ moduleForAcceptance('Acceptance | console', {
|
|||
},
|
||||
});
|
||||
|
||||
test("refresh reloads the current route's data", function(assert) {
|
||||
test('refresh reloads the current route\'s data', function(assert) {
|
||||
let numEngines;
|
||||
enginesPage.visit();
|
||||
andThen(() => {
|
||||
|
|
|
@ -0,0 +1,95 @@
|
|||
import { moduleForComponent, test } from 'ember-qunit';
|
||||
import { create } from 'ember-cli-page-object';
|
||||
import hbs from 'htmlbars-inline-precompile';
|
||||
import maskedInput from 'vault/tests/pages/components/masked-input';
|
||||
|
||||
const component = create(maskedInput);
|
||||
|
||||
moduleForComponent('masked-input', 'Integration | Component | masked input', {
|
||||
integration: true,
|
||||
|
||||
beforeEach() {
|
||||
component.setContext(this);
|
||||
},
|
||||
|
||||
afterEach() {
|
||||
component.removeContext();
|
||||
},
|
||||
});
|
||||
|
||||
const hasClass = (classString = '', classToFind) => {
|
||||
return classString.split(' ').contains(classToFind);
|
||||
}
|
||||
|
||||
test('it renders', function(assert) {
|
||||
|
||||
this.render(hbs`{{masked-input}}`);
|
||||
|
||||
assert.ok(hasClass(component.wrapperClass, 'masked'));
|
||||
});
|
||||
|
||||
|
||||
test('it renders a textarea', function(assert) {
|
||||
|
||||
this.render(hbs`{{masked-input}}`);
|
||||
|
||||
assert.ok(component.textareaIsPresent);
|
||||
});
|
||||
|
||||
test('it does not render a textarea when displayOnly is true', function(assert) {
|
||||
|
||||
this.render(hbs`{{masked-input displayOnly=true}}`);
|
||||
|
||||
assert.notOk(component.textareaIsPresent);
|
||||
});
|
||||
|
||||
|
||||
test('it unmasks text on focus', function(assert) {
|
||||
|
||||
this.set('value', 'value');
|
||||
this.render(hbs`{{masked-input value=value}}`);
|
||||
|
||||
assert.ok(hasClass(component.wrapperClass, 'masked'));
|
||||
|
||||
component.focus();
|
||||
assert.notOk(hasClass(component.wrapperClass, 'masked'));
|
||||
});
|
||||
|
||||
test('it remasks text on blur', function(assert) {
|
||||
|
||||
this.set('value', 'value');
|
||||
this.render(hbs`{{masked-input value=value}}`);
|
||||
|
||||
assert.ok(hasClass(component.wrapperClass, 'masked'));
|
||||
|
||||
component.focus();
|
||||
component.blur();
|
||||
|
||||
assert.ok(hasClass(component.wrapperClass, 'masked'));
|
||||
});
|
||||
|
||||
test('it unmasks text when button is clicked', function(assert) {
|
||||
|
||||
this.set('value', 'value');
|
||||
this.render(hbs`{{masked-input value=value}}`);
|
||||
|
||||
assert.ok(hasClass(component.wrapperClass, 'masked'));
|
||||
|
||||
component.toggleMasked();
|
||||
|
||||
assert.notOk(hasClass(component.wrapperClass, 'masked'));
|
||||
|
||||
});
|
||||
|
||||
test('it remasks text when button is clicked', function(assert) {
|
||||
|
||||
this.set('value', 'value');
|
||||
this.render(hbs`{{masked-input value=value}}`);
|
||||
|
||||
component.toggleMasked();
|
||||
component.toggleMasked();
|
||||
|
||||
assert.ok(hasClass(component.wrapperClass, 'masked'));
|
||||
|
||||
});
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
import { attribute, clickable, fillable, focusable, blurrable, isPresent } from 'ember-cli-page-object';
|
||||
|
||||
export default {
|
||||
wrapperClass: attribute('class','[data-test-masked-input]'),
|
||||
enterText: fillable('[data-test-textarea]'),
|
||||
textareaIsPresent: isPresent('[data-test-textarea]'),
|
||||
toggleMasked: clickable('[data-test-button]'),
|
||||
focus: focusable('[data-test-textarea]'),
|
||||
blur: blurrable('[data-test-textarea]')
|
||||
};
|
|
@ -443,9 +443,9 @@ autoprefixer@^7.0.0:
|
|||
postcss "^6.0.17"
|
||||
postcss-value-parser "^3.2.3"
|
||||
|
||||
autosize@3.0.17:
|
||||
version "3.0.17"
|
||||
resolved "https://registry.yarnpkg.com/autosize/-/autosize-3.0.17.tgz#f5a2cd35b96d864634cffc600c8c628c658d805b"
|
||||
autosize@^4.0.0:
|
||||
version "4.0.2"
|
||||
resolved "https://registry.yarnpkg.com/autosize/-/autosize-4.0.2.tgz#073cfd07c8bf45da4b9fd153437f5bafbba1e4c9"
|
||||
|
||||
aws-sign2@~0.6.0:
|
||||
version "0.6.0"
|
||||
|
|
Loading…
Reference in New Issue