From 2178c0d5955428de264442c91ed6e7aca280f75d Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Fri, 5 Jun 2020 16:24:07 -0500 Subject: [PATCH] SecurityForm: Style OAuth tokens --- app/soapbox/features/security/index.js | 53 +++++++++++++++++++------- app/styles/forms.scss | 32 ++++++++++++++++ 2 files changed, 72 insertions(+), 13 deletions(-) diff --git a/app/soapbox/features/security/index.js b/app/soapbox/features/security/index.js index bfbd98946..c3d5fe41f 100644 --- a/app/soapbox/features/security/index.js +++ b/app/soapbox/features/security/index.js @@ -1,6 +1,6 @@ import React from 'react'; import { connect } from 'react-redux'; -import { defineMessages, injectIntl } from 'react-intl'; +import { defineMessages, injectIntl, FormattedDate } from 'react-intl'; import ImmutablePureComponent from 'react-immutable-pure-component'; import PropTypes from 'prop-types'; import ImmutablePropTypes from 'react-immutable-proptypes'; @@ -31,11 +31,20 @@ const messages = defineMessages({ oldPasswordFieldLabel: { id: 'security.fields.old_password.label', defaultMessage: 'Current password' }, newPasswordFieldLabel: { id: 'security.fields.new_password.label', defaultMessage: 'New password' }, confirmationFieldLabel: { id: 'security.fields.password_confirmation.label', defaultMessage: 'New password (again)' }, + revoke: { id: 'security.tokens.revoke', defaultMessage: 'Revoke' }, + emailHeader: { id: 'security.headers.update_email', defaultMessage: 'Change Email' }, + passwordHeader: { id: 'security.headers.update_password', defaultMessage: 'Change Password' }, + tokenHeader: { id: 'security.headers.tokens', defaultMessage: 'Sessions' }, }); export default @injectIntl class SecurityForm extends ImmutablePureComponent { + static propTypes = { + dispatch: PropTypes.func.isRequired, + intl: PropTypes.object.isRequired, + }; + render() { const { intl } = this.props; @@ -90,6 +99,7 @@ class ChangeEmailForm extends ImmutablePureComponent { return ( +

{intl.formatMessage(messages.emailHeader)}

+

{intl.formatMessage(messages.passwordHeader)}

({ class AuthTokenList extends ImmutablePureComponent { static propTypes = { + dispatch: PropTypes.func.isRequired, + intl: PropTypes.object.isRequired, tokens: ImmutablePropTypes.list, - } + }; handleRevoke = id => { return e => { @@ -222,20 +235,34 @@ class AuthTokenList extends ImmutablePureComponent { } render() { - if (this.props.tokens.isEmpty()) return null; + const { tokens, intl } = this.props; + if (tokens.isEmpty()) return null; return ( - {this.props.tokens.map((token, i) => ( -
-
{token.get('app_name')}
-
{token.get('valid_until')}
-
- +

{intl.formatMessage(messages.tokenHeader)}

+
+ {tokens.reverse().map((token, i) => ( +
+
{token.get('app_name')}
+
+ +
+
+ +
-
- ))} + ))} +
); } diff --git a/app/styles/forms.scss b/app/styles/forms.scss index d954d4e74..8510fc59e 100644 --- a/app/styles/forms.scss +++ b/app/styles/forms.scss @@ -504,6 +504,13 @@ code { } } } + + h2 { + font-size: 20px; + line-height: normal; + margin-bottom: 14px; + font-weight: bold; + } } .block-icon { @@ -930,3 +937,28 @@ code { border-radius: 0 0 4px 4px; } } + +.authtokens { + display: grid; + grid-template-columns: repeat(2, minmax(0, 1fr)); + grid-gap: 20px; +} + +.authtoken { + &__app-name { + font-size: 16px; + font-weight: bold; + overflow: hidden; + text-overflow: ellipsis; + } + + &__valid-until { + font-size: 14px; + overflow: hidden; + text-overflow: ellipsis; + } + + &__revoke { + margin-top: 10px; + } +}