Choose accounts refactor (#13039)

* added wrapper around account list to prevent storybook from collapsing the list

* updated translation files

* added snap-connect page

* refactored account list out of the choose account component

* fixed width

* removed unnecessary scss from choose-account component, fixed props in choose account story

* removed snaps-connect page, added comments to ChooseAccount

* updated choose account subtitle text, updated styling for title & subtitle, removed redundant account list story

* updated component name, updated paths

* fixed linter errors

* added comments

* removed unused message

* removed selectAccounts key from all locales

* updated class name for account list header, updated allAreSelected function to use length checks

* Revert "removed unused message"

This reverts commit 32771bc83c08f120825ef75f0741f3034e7dbecb.

* Revert "removed selectAccounts key from all locales"

This reverts commit ccfa4a860f9a75693d893d7c404384e719de297e.

* updated locale messages to use selectAccounts key

* removed stray import

* updated scss

* updated translation key

* removed chooseAccounts key from en locale

* removed optional chaining

* changes

* updated subjectMetadata

* updated subject types

* update useOriginMetadata function to include unknown subject type

* updated permission connect header props, removed host and added subjectType to targetSubjectMetadata

* added subjectType to targetSubjectMetadata

* removed console.log

* changed prop name to iconUrl
feature/default_network_editable
Hassan Malik 3 years ago committed by GitHub
parent 8cc185a8b1
commit f946c030b5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      app/_locales/en/messages.json
  2. 3
      app/scripts/lib/rpc-method-middleware/handlers/send-metadata.js
  3. 1
      app/scripts/metamask-controller.js
  4. 3
      shared/constants/app.js
  5. 2
      ui/components/app/permission-page-container/permission-page-container-content/permission-page-container-content.component.js
  6. 3
      ui/components/app/permissions-connect-header/index.scss
  7. 8
      ui/components/app/permissions-connect-header/permissions-connect-header.component.js
  8. 175
      ui/components/ui/account-list/account-list.js
  9. 1
      ui/components/ui/account-list/index.js
  10. 140
      ui/components/ui/account-list/index.scss
  11. 1
      ui/components/ui/ui-components.scss
  12. 2
      ui/hooks/useOriginMetadata.js
  13. 242
      ui/pages/permissions-connect/choose-account/choose-account.component.js
  14. 148
      ui/pages/permissions-connect/choose-account/choose-account.js
  15. 2
      ui/pages/permissions-connect/choose-account/index.js
  16. 129
      ui/pages/permissions-connect/choose-account/index.scss
  17. 1
      ui/pages/permissions-connect/permissions-connect.component.js
  18. 4
      ui/pages/permissions-connect/permissions-connect.container.js

@ -2443,7 +2443,7 @@
"message": "Select a higher gas fee to accelerate the processing of your transaction.*"
},
"selectAccounts": {
"message": "Select account(s)"
"message": "Select the account(s) to use on this site"
},
"selectAll": {
"message": "Select all"

@ -38,7 +38,7 @@ function sendMetadataHandler(
end,
{ addSubjectMetadata, subjectType },
) {
const { params } = req;
const { origin, params } = req;
if (params && typeof params === 'object' && !Array.isArray(params)) {
const { icon = null, name = null, ...remainingParams } = params;
@ -47,6 +47,7 @@ function sendMetadataHandler(
iconUrl: icon,
name,
subjectType,
origin,
});
} else {
return end(ethErrors.rpc.invalidParams({ data: params }));

@ -2725,7 +2725,6 @@ export default class MetamaskController extends EventEmitter {
// Miscellaneous
addSubjectMetadata: this.subjectMetadataController.addSubjectMetadata.bind(
this.subjectMetadataController,
origin,
),
getProviderState: this.getProviderState.bind(this),
getUnlockPromise: this.appStateController.getUnlockPromise.bind(

@ -50,9 +50,10 @@ export const MESSAGE_TYPE = {
* third parties and itself (e.g. when the background communicated with the UI).
*/
export const SUBJECT_TYPES = {
WEBSITE: 'website',
EXTENSION: 'extension',
INTERNAL: 'internal',
UNKNOWN: 'unknown',
WEBSITE: 'website',
};
export const POLLING_TOKEN_ENVIRONMENT_TYPES = {

@ -100,7 +100,7 @@ export default class PermissionPageContainerContent extends PureComponent {
<div className="permission-approval-container__content">
<div className="permission-approval-container__content-container">
<PermissionsConnectHeader
icon={subjectMetadata.iconUrl}
iconUrl={subjectMetadata.iconUrl}
iconName={subjectMetadata.name}
headerTitle={title}
headerText={

@ -17,13 +17,14 @@
text-align: center;
color: $Black-100;
margin-top: 16px;
font-weight: bold;
}
&__subtitle {
@include H6;
text-align: center;
color: $Grey-500;
color: $Black-100;
}
&__subtitle {

@ -4,7 +4,7 @@ import SiteOrigin from '../../ui/site-origin/site-origin';
export default class PermissionsConnectHeader extends Component {
static propTypes = {
icon: PropTypes.string,
iconUrl: PropTypes.string,
iconName: PropTypes.string.isRequired,
siteOrigin: PropTypes.string.isRequired,
headerTitle: PropTypes.node,
@ -12,17 +12,17 @@ export default class PermissionsConnectHeader extends Component {
};
static defaultProps = {
icon: null,
iconUrl: null,
headerTitle: '',
headerText: '',
};
renderHeaderIcon() {
const { icon, iconName, siteOrigin } = this.props;
const { iconUrl, iconName, siteOrigin } = this.props;
return (
<div className="permissions-connect-header__icon">
<SiteOrigin siteOrigin={siteOrigin} iconSrc={icon} name={iconName} />
<SiteOrigin siteOrigin={siteOrigin} iconSrc={iconUrl} name={iconName} />
</div>
);
}

@ -0,0 +1,175 @@
import React from 'react';
import PropTypes from 'prop-types';
import classnames from 'classnames';
import { useI18nContext } from '../../../hooks/useI18nContext';
import CheckBox, { CHECKED, INDETERMINATE, UNCHECKED } from '../check-box';
import Identicon from '../identicon';
import UserPreferencedCurrencyDisplay from '../../app/user-preferenced-currency-display';
import { PRIMARY } from '../../../helpers/constants/common';
import Tooltip from '../tooltip';
const AccountList = ({
selectNewAccountViaModal,
accounts,
addressLastConnectedMap,
selectedAccounts,
nativeCurrency,
allAreSelected,
deselectAll,
selectAll,
handleAccountClick,
}) => {
const t = useI18nContext();
const Header = () => {
let checked;
if (allAreSelected()) {
checked = CHECKED;
} else if (selectedAccounts.size === 0) {
checked = UNCHECKED;
} else {
checked = INDETERMINATE;
}
return (
<div
className={classnames({
'choose-account-list__header--one-item': accounts.length === 1,
'choose-account-list__header--multiple-items': accounts.length > 1,
})}
>
{accounts.length > 1 ? (
<div className="choose-account-list__select-all">
<CheckBox
className="choose-account-list__header-check-box"
checked={checked}
onClick={() => (allAreSelected() ? deselectAll() : selectAll())}
/>
<div className="choose-account-list__text-grey">
{t('selectAll')}
</div>
<Tooltip
position="bottom"
html={
<div style={{ width: 200, padding: 4 }}>
{t('selectingAllWillAllow')}
</div>
}
>
<i className="fa fa-info-circle" />
</Tooltip>
</div>
) : null}
<div
className="choose-account-list__text-blue"
onClick={() => selectNewAccountViaModal(handleAccountClick)}
>
{t('newAccount')}
</div>
</div>
);
};
const List = () => {
return (
<div className="choose-account-list__wrapper">
<div className="choose-account-list__list">
{accounts.map((account, index) => {
const { address, addressLabel, balance } = account;
return (
<div
key={`choose-account-list-${index}`}
onClick={() => handleAccountClick(address)}
className="choose-account-list__account"
>
<div className="choose-account-list__account-info-wrapper">
<CheckBox
className="choose-account-list__list-check-box"
checked={selectedAccounts.has(address)}
/>
<Identicon diameter={34} address={address} />
<div className="choose-account-list__account__info">
<div className="choose-account-list__account__label">
{addressLabel}
</div>
<UserPreferencedCurrencyDisplay
className="choose-account-list__account__balance"
type={PRIMARY}
value={balance}
style={{ color: '#6A737D' }}
suffix={nativeCurrency}
/>
</div>
</div>
{addressLastConnectedMap[address] ? (
<Tooltip
title={`${t('lastConnected')} ${
addressLastConnectedMap[address]
}`}
>
<i className="fa fa-info-circle" />
</Tooltip>
) : null}
</div>
);
})}
</div>
</div>
);
};
return (
<div className="choose-account-list">
<Header />
<List />
</div>
);
};
AccountList.propTypes = {
/**
* Array of user account objects
*/
accounts: PropTypes.arrayOf(
PropTypes.shape({
address: PropTypes.string,
addressLabel: PropTypes.string,
lastConnectedDate: PropTypes.string,
balance: PropTypes.string,
}),
).isRequired,
/**
* Function to select a new account via modal
*/
selectNewAccountViaModal: PropTypes.func.isRequired,
/**
* A map of the last connected addresses
*/
addressLastConnectedMap: PropTypes.object,
/**
* Native currency of current chain
*/
nativeCurrency: PropTypes.string.isRequired,
/**
* Currently selected accounts
*/
selectedAccounts: PropTypes.object.isRequired,
/**
* Function to check if all accounts are selected
*/
allAreSelected: PropTypes.func.isRequired,
/**
* Function to deselect all accounts
*/
deselectAll: PropTypes.func.isRequired,
/**
* Function to select all accounts
*/
selectAll: PropTypes.func.isRequired,
/**
* Function to handle account click
*/
handleAccountClick: PropTypes.func.isRequired,
};
export default AccountList;

@ -0,0 +1 @@
export { default } from './account-list';

@ -0,0 +1,140 @@
.choose-account-list {
display: flex;
flex-direction: column;
width: 100%;
height: 100%;
align-items: center;
&__header--one-item,
&__header--multiple-items {
display: flex;
flex: 0;
margin-top: 36px;
width: 100%;
padding-inline-start: 15px;
padding-inline-end: 17px;
}
&__header--one-item {
justify-content: flex-end;
}
&__header--multiple-items {
justify-content: space-between;
}
&__select-all {
display: flex;
margin-inline-start: 16px;
align-items: center;
}
&__header-check-box {
margin-right: 16px;
}
&__wrapper {
width: 92%;
display: flex;
}
&__list {
flex: 2 1 0;
width: 92%;
max-height: max-content;
border: 1px solid #d0d5da;
box-sizing: border-box;
border-radius: 8px;
margin-top: 8px;
overflow-y: auto;
}
&__account {
display: flex;
align-items: center;
padding: 16px;
border-bottom: 1px solid #d2d8dd;
justify-content: space-between;
&:last-of-type {
border-bottom: none;
}
&:hover {
background: $Grey-000;
cursor: pointer;
}
&__info {
display: flex;
flex-direction: column;
margin-inline-start: 16px;
min-width: 0;
}
&__label {
@include H6;
color: $Black-100;
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
}
&__balance {
@include H7;
color: $Grey-500;
}
&__last-connected {
@include H8;
display: flex;
flex-direction: column;
align-items: flex-end;
color: $primary-blue;
}
}
&__account-info-wrapper {
display: flex;
justify-content: flex-start;
align-items: center;
min-width: 0;
}
&__list-check-box {
margin-inline-end: 16px;
i {
font-size: 0.8rem;
}
}
.fa-info-circle {
color: $Grey-200;
cursor: pointer;
margin-inline-start: 8px;
font-size: 0.9rem;
}
.fa-info-circle:hover {
color: $Grey-300;
}
&__text,
&__text-blue,
&__text-grey {
@include H6;
}
&__text-blue {
color: $primary-blue;
cursor: pointer;
}
&__text-grey {
color: $Grey-500;
}
}

@ -1,5 +1,6 @@
/** Please import your files in alphabetical order **/
@import 'account-mismatch-warning/index';
@import 'account-list/index';
@import 'actionable-message/index';
@import 'alert-circle-icon/index';
@import 'alert/index';

@ -1,5 +1,6 @@
import { useSelector } from 'react-redux';
import { getSubjectMetadata } from '../selectors';
import { SUBJECT_TYPES } from '../../shared/constants/app';
/**
* @typedef {Object} OriginMetadata
@ -27,6 +28,7 @@ export function useOriginMetadata(origin) {
host: url.host,
hostname: url.hostname,
origin,
subjectType: SUBJECT_TYPES.UNKNOWN,
};
if (subjectMetadata?.[origin]) {

@ -1,242 +0,0 @@
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import classnames from 'classnames';
import Identicon from '../../../components/ui/identicon';
import Button from '../../../components/ui/button';
import CheckBox, {
CHECKED,
INDETERMINATE,
UNCHECKED,
} from '../../../components/ui/check-box';
import Tooltip from '../../../components/ui/tooltip';
import { PRIMARY } from '../../../helpers/constants/common';
import UserPreferencedCurrencyDisplay from '../../../components/app/user-preferenced-currency-display';
import PermissionsConnectHeader from '../../../components/app/permissions-connect-header';
import PermissionsConnectFooter from '../../../components/app/permissions-connect-footer';
export default class ChooseAccount extends Component {
static propTypes = {
accounts: PropTypes.arrayOf(
PropTypes.shape({
address: PropTypes.string,
addressLabel: PropTypes.string,
lastConnectedDate: PropTypes.string,
balance: PropTypes.string,
}),
).isRequired,
selectAccounts: PropTypes.func.isRequired,
selectNewAccountViaModal: PropTypes.func.isRequired,
nativeCurrency: PropTypes.string.isRequired,
addressLastConnectedMap: PropTypes.object,
cancelPermissionsRequest: PropTypes.func.isRequired,
permissionsRequestId: PropTypes.string.isRequired,
selectedAccountAddresses: PropTypes.object.isRequired,
targetSubjectMetadata: PropTypes.shape({
extensionId: PropTypes.string,
iconUrl: PropTypes.string,
name: PropTypes.string.isRequired,
origin: PropTypes.string.isRequired,
}),
};
state = {
selectedAccounts: this.props.selectedAccountAddresses,
};
static defaultProps = {
addressLastConnectedMap: {},
};
static contextTypes = {
t: PropTypes.func,
};
handleAccountClick(address) {
const { selectedAccounts } = this.state;
const newSelectedAccounts = new Set(selectedAccounts);
if (newSelectedAccounts.has(address)) {
newSelectedAccounts.delete(address);
} else {
newSelectedAccounts.add(address);
}
this.setState({ selectedAccounts: newSelectedAccounts });
}
selectAll() {
const { accounts } = this.props;
const newSelectedAccounts = new Set(
accounts.map((account) => account.address),
);
this.setState({ selectedAccounts: newSelectedAccounts });
}
deselectAll() {
this.setState({ selectedAccounts: new Set() });
}
allAreSelected() {
const { accounts } = this.props;
const { selectedAccounts } = this.state;
return accounts.every(({ address }) => selectedAccounts.has(address));
}
renderAccountsList = () => {
const { accounts, nativeCurrency, addressLastConnectedMap } = this.props;
const { selectedAccounts } = this.state;
return (
<div className="permissions-connect-choose-account__accounts-list">
{accounts.map((account, index) => {
const { address, addressLabel, balance } = account;
return (
<div
key={`permissions-connect-choose-account-${index}`}
onClick={() => this.handleAccountClick(address)}
className="permissions-connect-choose-account__account"
>
<div className="permissions-connect-choose-account__account-info-wrapper">
<CheckBox
className="permissions-connect-choose-account__list-check-box"
checked={selectedAccounts.has(address)}
/>
<Identicon diameter={34} address={address} />
<div className="permissions-connect-choose-account__account__info">
<div className="permissions-connect-choose-account__account__label">
{addressLabel}
</div>
<UserPreferencedCurrencyDisplay
className="permissions-connect-choose-account__account__balance"
type={PRIMARY}
value={balance}
style={{ color: '#6A737D' }}
suffix={nativeCurrency}
/>
</div>
</div>
{addressLastConnectedMap[address] ? (
<Tooltip
title={`${this.context.t('lastConnected')} ${
addressLastConnectedMap[address]
}`}
>
<i className="fa fa-info-circle" />
</Tooltip>
) : null}
</div>
);
})}
</div>
);
};
renderAccountsListHeader() {
const { t } = this.context;
const { selectNewAccountViaModal, accounts } = this.props;
const { selectedAccounts } = this.state;
let checked;
if (this.allAreSelected()) {
checked = CHECKED;
} else if (selectedAccounts.size === 0) {
checked = UNCHECKED;
} else {
checked = INDETERMINATE;
}
return (
<div
className={classnames({
'permissions-connect-choose-account__accounts-list-header--one-item':
accounts.length === 1,
'permissions-connect-choose-account__accounts-list-header--two-items':
accounts.length > 1,
})}
>
{accounts.length > 1 ? (
<div className="permissions-connect-choose-account__select-all">
<CheckBox
className="permissions-connect-choose-account__header-check-box"
checked={checked}
onClick={() =>
this.allAreSelected() ? this.deselectAll() : this.selectAll()
}
/>
<div className="permissions-connect-choose-account__text-grey">
{this.context.t('selectAll')}
</div>
<Tooltip
position="bottom"
html={
<div style={{ width: 200, padding: 4 }}>
{t('selectingAllWillAllow')}
</div>
}
>
<i className="fa fa-info-circle" />
</Tooltip>
</div>
) : null}
<div
className="permissions-connect-choose-account__text-blue"
onClick={() =>
selectNewAccountViaModal(this.handleAccountClick.bind(this))
}
>
{this.context.t('newAccount')}
</div>
</div>
);
}
render() {
const {
selectAccounts,
permissionsRequestId,
cancelPermissionsRequest,
targetSubjectMetadata,
accounts,
} = this.props;
const { selectedAccounts } = this.state;
const { t } = this.context;
return (
<div className="permissions-connect-choose-account">
<PermissionsConnectHeader
icon={targetSubjectMetadata.iconUrl}
iconName={targetSubjectMetadata.name}
headerTitle={t('connectWithMetaMask')}
headerText={
accounts.length > 0
? t('selectAccounts')
: t('connectAccountOrCreate')
}
siteOrigin={targetSubjectMetadata.origin}
/>
{this.renderAccountsListHeader()}
{this.renderAccountsList()}
<div className="permissions-connect-choose-account__footer-container">
<PermissionsConnectFooter />
<div className="permissions-connect-choose-account__bottom-buttons">
<Button
onClick={() => cancelPermissionsRequest(permissionsRequestId)}
type="secondary"
>
{t('cancel')}
</Button>
<Button
onClick={() => selectAccounts(selectedAccounts)}
type="primary"
disabled={selectedAccounts.size === 0}
>
{t('next')}
</Button>
</div>
</div>
</div>
);
}
}

@ -0,0 +1,148 @@
import PropTypes from 'prop-types';
import React, { useState } from 'react';
import { useI18nContext } from '../../../hooks/useI18nContext';
import Button from '../../../components/ui/button';
import PermissionsConnectHeader from '../../../components/app/permissions-connect-header';
import PermissionsConnectFooter from '../../../components/app/permissions-connect-footer';
import AccountList from '../../../components/ui/account-list';
const ChooseAccount = ({
selectedAccountAddresses,
addressLastConnectedMap = {},
accounts,
selectAccounts,
selectNewAccountViaModal,
cancelPermissionsRequest,
permissionsRequestId,
targetSubjectMetadata,
nativeCurrency,
}) => {
const [selectedAccounts, setSelectedAccounts] = useState(
selectedAccountAddresses,
);
const t = useI18nContext();
const handleAccountClick = (address) => {
const newSelectedAccounts = new Set(selectedAccounts);
if (newSelectedAccounts.has(address)) {
newSelectedAccounts.delete(address);
} else {
newSelectedAccounts.add(address);
}
setSelectedAccounts(newSelectedAccounts);
};
const selectAll = () => {
const newSelectedAccounts = new Set(
accounts.map((account) => account.address),
);
setSelectedAccounts(newSelectedAccounts);
};
const deselectAll = () => {
setSelectedAccounts(new Set());
};
const allAreSelected = () => {
return accounts.length === selectedAccounts.size;
};
return (
<div className="permissions-connect-choose-account">
<PermissionsConnectHeader
iconUrl={targetSubjectMetadata?.iconUrl}
iconName={targetSubjectMetadata?.name}
headerTitle={t('connectWithMetaMask')}
headerText={
accounts.length > 0
? t('selectAccounts')
: t('connectAccountOrCreate')
}
siteOrigin={targetSubjectMetadata?.origin}
/>
<AccountList
accounts={accounts}
selectNewAccountViaModal={selectNewAccountViaModal}
addressLastConnectedMap={addressLastConnectedMap}
nativeCurrency={nativeCurrency}
selectedAccounts={selectedAccounts}
allAreSelected={allAreSelected}
deselectAll={deselectAll}
selectAll={selectAll}
handleAccountClick={handleAccountClick}
/>
<div className="permissions-connect-choose-account__footer-container">
<PermissionsConnectFooter />
<div className="permissions-connect-choose-account__bottom-buttons">
<Button
onClick={() => cancelPermissionsRequest(permissionsRequestId)}
type="secondary"
>
{t('cancel')}
</Button>
<Button
onClick={() => selectAccounts(selectedAccounts)}
type="primary"
disabled={selectedAccounts.size === 0}
>
{t('next')}
</Button>
</div>
</div>
</div>
);
};
ChooseAccount.propTypes = {
/**
* Array of user account objects
*/
accounts: PropTypes.arrayOf(
PropTypes.shape({
address: PropTypes.string,
addressLabel: PropTypes.string,
lastConnectedDate: PropTypes.string,
balance: PropTypes.string,
}),
).isRequired,
/**
* Function to select an account
*/
selectAccounts: PropTypes.func.isRequired,
/**
* Function to select a new account via modal
*/
selectNewAccountViaModal: PropTypes.func.isRequired,
/**
* Native currency of current chain
*/
nativeCurrency: PropTypes.string.isRequired,
/**
* A map of the last connected addresses
*/
addressLastConnectedMap: PropTypes.object,
/**
* Function to cancel permission request
*/
cancelPermissionsRequest: PropTypes.func.isRequired,
/**
* Permission request Id
*/
permissionsRequestId: PropTypes.string.isRequired,
/**
* Currently selected account addresses
*/
selectedAccountAddresses: PropTypes.object.isRequired,
/**
* Domain data used to display site-origin pill
*/
targetSubjectMetadata: PropTypes.shape({
extensionId: PropTypes.string,
iconUrl: PropTypes.string,
name: PropTypes.string.isRequired,
origin: PropTypes.string.isRequired,
subjectType: PropTypes.string,
}),
};
export default ChooseAccount;

@ -1 +1 @@
export { default } from './choose-account.component';
export { default } from './choose-account';

@ -7,143 +7,14 @@
margin-right: auto;
height: 100%;
.fa-info-circle {
color: $Grey-200;
cursor: pointer;
margin-left: 8px;
font-size: 0.9rem;
}
.fa-info-circle:hover {
color: $Grey-300;
}
@media screen and (min-width: $break-large) {
width: 426px;
}
&__title {
@include H4;
}
&__text,
&__text-blue,
&__text-grey {
@include H6;
}
&__text-blue {
color: $primary-blue;
cursor: pointer;
}
&__text-grey {
color: $Grey-500;
}
&__accounts-list {
flex: 2 1 0;
width: 92%;
max-height: max-content;
border: 1px solid #d0d5da;
box-sizing: border-box;
border-radius: 8px;
margin-top: 8px;
overflow-y: auto;
}
&__accounts-list-header--one-item,
&__accounts-list-header--two-items {
display: flex;
flex: 0;
margin-top: 36px;
width: 100%;
padding-left: 15px;
padding-right: 17px;
}
&__accounts-list-header--one-item {
justify-content: flex-end;
}
&__accounts-list-header--two-items {
justify-content: space-between;
}
&__account-info-wrapper {
display: flex;
justify-content: flex-start;
align-items: center;
min-width: 0;
}
&__list-check-box {
margin-right: 16px;
i {
font-size: 0.8rem;
}
}
&__header-check-box {
margin-right: 16px;
}
&__select-all {
display: flex;
margin-left: 16px;
align-items: center;
}
&__account {
display: flex;
align-items: center;
padding: 16px;
border-bottom: 1px solid #d2d8dd;
justify-content: space-between;
&:last-of-type {
border-bottom: none;
}
&:hover {
background: $Grey-000;
cursor: pointer;
}
&__info {
display: flex;
flex-direction: column;
margin-left: 16px;
min-width: 0;
}
&__label {
@include H6;
color: $Black-100;
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
}
&__balance {
@include H7;
color: $Grey-500;
}
&__last-connected {
@include H8;
display: flex;
flex-direction: column;
align-items: flex-end;
color: $primary-blue;
}
}
&__cancel {
color: $Red-400;
}

@ -36,6 +36,7 @@ export default class PermissionConnect extends Component {
iconUrl: PropTypes.string,
name: PropTypes.string.isRequired,
origin: PropTypes.string.isRequired,
subjectType: PropTypes.string,
}),
};

@ -21,6 +21,7 @@ import {
CONNECT_ROUTE,
CONNECT_CONFIRM_PERMISSIONS_ROUTE,
} from '../../helpers/constants/routes';
import { SUBJECT_TYPES } from '../../../shared/constants/app';
import PermissionApproval from './permissions-connect.component';
const mapStateToProps = (state, ownProps) => {
@ -46,7 +47,7 @@ const mapStateToProps = (state, ownProps) => {
let targetSubjectMetadata = null;
if (origin) {
if (subjectMetadata[origin]) {
targetSubjectMetadata = { ...subjectMetadata[origin], origin };
targetSubjectMetadata = subjectMetadata[origin];
} else {
const targetUrl = new URL(origin);
targetSubjectMetadata = {
@ -54,6 +55,7 @@ const mapStateToProps = (state, ownProps) => {
origin,
iconUrl: null,
extensionId: null,
subjectType: SUBJECT_TYPES.UNKNOWN,
};
}
}

Loading…
Cancel
Save