Skip to content

Commit b42b8a0

Browse files
committed
changing secret inputs from password to text
with obfuscation using CSS.
1 parent be6b339 commit b42b8a0

File tree

6 files changed

+78
-46
lines changed

6 files changed

+78
-46
lines changed

modules/st2-auto-form/auto-form.component.js

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ import IntegerField from './fields/integer';
2323
import BooleanField from './fields/boolean';
2424
import StringField from './fields/string';
2525
import ObjectField from './fields/object';
26-
import PasswordField from './fields/password';
2726
import EnumField from './fields/enum';
2827

2928
import './style.css';
@@ -57,10 +56,6 @@ export default class AutoForm extends React.Component {
5756
case 'boolean':
5857
return BooleanField;
5958
case 'string':
60-
if (field.secret) {
61-
return PasswordField;
62-
}
63-
6459
return StringField;
6560
case 'object':
6661
return ObjectField;

modules/st2-auto-form/fields/base.js

Lines changed: 37 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import _ from 'lodash';
1616
import React from 'react';
1717
import { PropTypes } from 'prop-types';
1818

19-
import { TextFieldWrapper } from '../wrappers';
19+
import { TextFieldWrapper, Button } from '../wrappers';
2020
import TextareaAutosize from 'react-textarea-autosize';
2121

2222
export class Textarea extends TextareaAutosize {
@@ -75,6 +75,10 @@ export class BaseTextField extends React.Component {
7575
throw new Error('not implemented');
7676
}
7777

78+
toggleVisibility() {
79+
this.setState({ visible: !this.state.visible });
80+
}
81+
7882
validate(v, spec={}) {
7983
if ((v === '' || v === undefined) && spec.required) {
8084
return 'parameter is required';
@@ -111,20 +115,27 @@ export class BaseTextField extends React.Component {
111115

112116
render() {
113117
const { icon } = this.constructor;
114-
const { invalid } = this.state;
118+
const { invalid, visible } = this.state;
115119
const { spec={} } = this.props;
116120
const wrapperProps = Object.assign({}, this.props);
117121

118122
if (invalid) {
119123
wrapperProps.invalid = invalid;
120124
}
121125

126+
const buttonProps = {
127+
icon: visible ? 'view2' : 'view',
128+
title: visible ? 'hide value' : 'see value',
129+
onClick: () => this.toggleVisibility(),
130+
};
131+
122132
const inputProps = {
123-
className: 'st2-auto-form__field',
124-
type: spec.secret ? 'password' : 'text',
133+
className: spec.secret && !visible ? 'st2-auto-form__field--secret' : 'st2-auto-form__field',
134+
type: 'text',
125135
placeholder:this.toStateValue(spec.default),
126136
disabled: this.props.disabled,
127137
value: this.state.value,
138+
spellCheck: spec.secret && !visible ? false : true,
128139
onChange: (e) => this.handleChange(e, e.target.value),
129140
'data-test': this.props['data-test'],
130141
};
@@ -135,7 +146,10 @@ export class BaseTextField extends React.Component {
135146

136147
return (
137148
<TextFieldWrapper icon={icon} {...wrapperProps}>
138-
<input {...inputProps} />
149+
<div >
150+
{ !this.props.disabled && spec.secret && <Button {...buttonProps} /> }
151+
<input {...inputProps} />
152+
</div>
139153
</TextFieldWrapper>
140154
);
141155
}
@@ -144,20 +158,31 @@ export class BaseTextField extends React.Component {
144158
export class BaseTextareaField extends BaseTextField {
145159
render() {
146160
const { icon } = this.constructor;
147-
const { invalid } = this.state;
148-
const { spec={} } = this.props;
161+
const { invalid, visible } = this.state;
162+
const { spec = {} } = this.props;
149163

150164
const wrapperProps = Object.assign({}, this.props);
151165

152166
if (invalid) {
153167
wrapperProps.invalid = invalid;
154168
}
155169

170+
const buttonProps = {
171+
icon: visible ? 'view2' : 'view',
172+
title: visible ? 'hide value' : 'see value',
173+
onClick: () => this.toggleVisibility(),
174+
};
175+
176+
const wrapperBlockProps = {
177+
className: 'st2-auto-form__wrapper-block',
178+
};
179+
156180
const inputProps = {
157-
className: 'st2-auto-form__field',
181+
className: spec.secret && !visible ? 'st2-auto-form__field--secret' : 'st2-auto-form__field',
158182
placeholder: this.toStateValue(spec.default),
159183
disabled: this.props.disabled,
160184
value: this.state.value,
185+
spellCheck: spec.secret && !visible ? false : true,
161186
onChange: (e) => this.handleChange(e, e.target.value),
162187
minRows: 1,
163188
maxRows: 10,
@@ -170,7 +195,10 @@ export class BaseTextareaField extends BaseTextField {
170195

171196
return (
172197
<TextFieldWrapper icon={icon} {...wrapperProps}>
173-
<Textarea {...inputProps} />
198+
<div {...wrapperBlockProps}>
199+
{ !this.props.disabled && spec.secret && <Button {...buttonProps} /> }
200+
<Textarea {...inputProps} />
201+
</div>
174202
</TextFieldWrapper>
175203
);
176204
}

modules/st2-auto-form/fields/integer.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,6 @@ export default class IntegerField extends BaseTextField {
7272
}
7373
}
7474

75-
return v && !validator.isInt(v) && `'${v}' is not an integer`;
75+
return v && !validator.isInt(v) && `'${spec.secret ? "*".repeat(v.length) : v}' is not an integer`;
7676
}
7777
}

modules/st2-auto-form/fields/number.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ export default class NumberField extends BaseTextField {
4848
if (invalid !== void 0) {
4949
return invalid;
5050
}
51-
52-
return v && !validator.isFloat(v) && `'${v}' is not a number`;
51+
52+
return v && !validator.isFloat(v) && `'${spec.secret ? "*".repeat(v.length) : v}' is not a number`;
5353
}
5454
}

modules/st2-auto-form/fields/password.js

Lines changed: 0 additions & 27 deletions
This file was deleted.

modules/st2-auto-form/style.css

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,11 @@
1717
margin-bottom: 12px;
1818
}
1919

20+
&__wrapper-block {
21+
display: flex;
22+
align-items: center;
23+
}
24+
2025
&__title {
2126
font-size: 15px;
2227
line-height: 18px;
@@ -70,6 +75,21 @@
7075
&:hover {
7176
color: var(--aqua-base);
7277
}
78+
79+
&:before {
80+
font-family: "brocadeicons";
81+
font-size: 18px;
82+
font-weight: normal;
83+
font-style: normal;
84+
line-height: 36px;
85+
86+
display: flex;
87+
88+
vertical-align: middle;
89+
pointer-events: none;
90+
91+
color: var(--grey-base);
92+
}
7393
}
7494

7595
&__field {
@@ -88,6 +108,22 @@
88108
background-color: white;
89109
box-shadow: 0 1px 0 var(--grey-lighten-2);
90110

111+
&--secret {
112+
font-weight: normal;
113+
font-family: Roboto, sans-serif;
114+
-webkit-box-sizing: border-box;
115+
-moz-box-sizing: border-box;
116+
box-sizing: border-box;
117+
width: 100%;
118+
padding: 0 12px;
119+
120+
color: black;
121+
border: none;
122+
outline: 0;
123+
box-shadow: 0 1px 0 var(--grey-lighten-2);
124+
-webkit-text-security: disc;
125+
}
126+
91127
&&[disabled] {
92128
cursor: default;
93129

@@ -144,7 +180,8 @@
144180
color: black;
145181
}
146182

147-
&__text-field &__field {
183+
&__text-field &__field,
184+
&__text-field &__field--secret {
148185
font-size: 13px;
149186
line-height: 18px;
150187

@@ -249,7 +286,6 @@
249286
padding: 0 10px 0 0;
250287

251288
content: "\e91c";
252-
vertical-align: middle;
253289
pointer-events: none;
254290

255291
color: black;

0 commit comments

Comments
 (0)