1
0
mirror of https://github.com/kremalicious/metamask-extension.git synced 2024-12-23 09:52:26 +01:00

Added SiteOrigin and PermissionList components (#12832)

* Changed back button to the one in design

* PermissionConnect now uses Chip component

* Added SiteOrigin widget

* WIP

* Added new permission list

* Fix linting errors

* Removed unused messages

* Removed more unused messages

* Make SiteOrigin bigger

* Fix lint

* Code Review fixes

* Fix SiteOrigin overflowing

* Add stories

* Fix lint

* Added useMemo to constant

* Fix Chip's max-content overflowing SiteOrigin

* Fix code review issues

Co-authored-by: Olaf Tomalka <olaftomalka@Olafs-MacBook-Pro-2.local>
This commit is contained in:
Olaf Tomalka 2021-12-02 18:22:18 +01:00 committed by GitHub
parent 4cd957953d
commit 90b656bd66
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
33 changed files with 172 additions and 165 deletions

View File

@ -989,7 +989,7 @@
"message": "Backup gas price is provided as the main gas estimation service is unavailable right now."
},
"eth_accounts": {
"message": "View the addresses of your permitted accounts (required)",
"message": "See address, account balance, activity and initiate transactions",
"description": "The description for the `eth_accounts` permission"
},
"ethereumPublicAddress": {
@ -2036,15 +2036,9 @@
"message": "You have (1) pending transaction.",
"description": "$1 is count of pending transactions"
},
"permissionCheckedIconDescription": {
"message": "You have approved this permission"
},
"permissionRequest": {
"message": "Permission request"
},
"permissionUncheckedIconDescription": {
"message": "You have not approved this permission"
},
"permissions": {
"message": "Permissions"
},

View File

@ -1343,12 +1343,6 @@
"pending": {
"message": "Pendiente"
},
"permissionCheckedIconDescription": {
"message": "Aprobó este permiso"
},
"permissionUncheckedIconDescription": {
"message": "No aprobó este permiso"
},
"permissions": {
"message": "Permisos"
},

View File

@ -1343,12 +1343,6 @@
"pending": {
"message": "Pendiente"
},
"permissionCheckedIconDescription": {
"message": "Aprobó este permiso"
},
"permissionUncheckedIconDescription": {
"message": "No aprobó este permiso"
},
"permissions": {
"message": "Permisos"
},

View File

@ -1343,12 +1343,6 @@
"pending": {
"message": "लंबित"
},
"permissionCheckedIconDescription": {
"message": "आपने इस अनुमति को अनुमोदित कर दिया है"
},
"permissionUncheckedIconDescription": {
"message": "आपने इस अनुमति को अनुमोदित नहीं किया है"
},
"permissions": {
"message": "अनुमतियाँ"
},

View File

@ -1343,12 +1343,6 @@
"pending": {
"message": "Tunda"
},
"permissionCheckedIconDescription": {
"message": "Anda telah menyetujui izin ini"
},
"permissionUncheckedIconDescription": {
"message": "Anda belum menyetujui izin ini"
},
"permissions": {
"message": "Izin"
},

View File

@ -1102,12 +1102,6 @@
"pending": {
"message": "in corso"
},
"permissionCheckedIconDescription": {
"message": "Hai approvato questo permesso"
},
"permissionUncheckedIconDescription": {
"message": "Non hai approvato questo permesso"
},
"permissions": {
"message": "Permessi"
},

View File

@ -1343,12 +1343,6 @@
"pending": {
"message": "処理"
},
"permissionCheckedIconDescription": {
"message": "この許可の承認が完了しました。"
},
"permissionUncheckedIconDescription": {
"message": "この許可の承認が完了していません。"
},
"permissions": {
"message": "許可"
},

View File

@ -1343,12 +1343,6 @@
"pending": {
"message": "보류 중"
},
"permissionCheckedIconDescription": {
"message": "이 권한을 승인했습니다."
},
"permissionUncheckedIconDescription": {
"message": "이 권한을 승인하지 않았습니다."
},
"permissions": {
"message": "권한"
},

View File

@ -1343,12 +1343,6 @@
"pending": {
"message": "Nakabinbin"
},
"permissionCheckedIconDescription": {
"message": "Inaprubahan mo ang pahintulot na ito"
},
"permissionUncheckedIconDescription": {
"message": "Hindi mo inaprubahan ang pahintulot na ito"
},
"permissions": {
"message": "Mga Pahintulot"
},

View File

@ -1343,12 +1343,6 @@
"pending": {
"message": "Pendente"
},
"permissionCheckedIconDescription": {
"message": "Você aprovou esta permissão"
},
"permissionUncheckedIconDescription": {
"message": "Você não aprovou esta permissão"
},
"permissions": {
"message": "Permissões"
},

View File

@ -1343,12 +1343,6 @@
"pending": {
"message": "В ожидании"
},
"permissionCheckedIconDescription": {
"message": "Вы одобрили это разрешение"
},
"permissionUncheckedIconDescription": {
"message": "Вы не одобрили это разрешение"
},
"permissions": {
"message": "Разрешения"
},

View File

@ -1093,12 +1093,6 @@
"pending": {
"message": "Nakabinbin"
},
"permissionCheckedIconDescription": {
"message": "Inaprubahan mo ang pahintulot na ito"
},
"permissionUncheckedIconDescription": {
"message": "Hindi mo inaprubahan ang pahintulot na ito"
},
"permissions": {
"message": "Mga Pahintulot"
},

View File

@ -1343,12 +1343,6 @@
"pending": {
"message": "Đang chờ xử lý"
},
"permissionCheckedIconDescription": {
"message": "Bạn đã phê duyệt quyền này"
},
"permissionUncheckedIconDescription": {
"message": "Bạn chưa phê duyệt quyền này"
},
"permissions": {
"message": "Quyền"
},

View File

@ -1144,12 +1144,6 @@
"pending": {
"message": "待处理"
},
"permissionCheckedIconDescription": {
"message": "您已同意该权限"
},
"permissionUncheckedIconDescription": {
"message": "您还未同意该权限"
},
"permissions": {
"message": "权限"
},

View File

@ -32,6 +32,7 @@
@import 'permission-page-container/index';
@import 'permissions-connect-footer/index';
@import 'permissions-connect-header/index';
@import 'permissions-connect-permission-list/index';
@import 'recovery-phrase-reminder/index';
@import 'step-progress-bar/index.scss';
@import 'selected-account/index';

View File

@ -23,7 +23,6 @@
}
}
&__header {
display: flex;
flex-direction: column;

View File

@ -2,7 +2,7 @@ import PropTypes from 'prop-types';
import React, { PureComponent } from 'react';
import PermissionsConnectHeader from '../../permissions-connect-header';
import Tooltip from '../../../ui/tooltip';
import CheckBox from '../../../ui/check-box';
import PermissionsConnectPermissionList from '../../permissions-connect-permission-list';
export default class PermissionPageContainerContent extends PureComponent {
static propTypes = {
@ -14,7 +14,6 @@ export default class PermissionPageContainerContent extends PureComponent {
origin: PropTypes.string.isRequired,
}),
selectedPermissions: PropTypes.object.isRequired,
onPermissionToggle: PropTypes.func.isRequired,
selectedIdentities: PropTypes.array,
allIdentitiesSelected: PropTypes.bool,
};
@ -29,43 +28,11 @@ export default class PermissionPageContainerContent extends PureComponent {
};
renderRequestedPermissions() {
const { selectedPermissions, onPermissionToggle } = this.props;
const { t } = this.context;
const items = Object.keys(selectedPermissions).map((permissionName) => {
const description = t(permissionName);
// don't allow deselecting eth_accounts
const isDisabled = permissionName === 'eth_accounts';
const isChecked = Boolean(selectedPermissions[permissionName]);
const title = isChecked
? t('permissionCheckedIconDescription')
: t('permissionUncheckedIconDescription');
return (
<div
className="permission-approval-container__content__permission"
key={permissionName}
onClick={() => {
if (!isDisabled) {
onPermissionToggle(permissionName);
}
}}
>
<CheckBox
disabled={isDisabled}
id={permissionName}
className="permission-approval-container__checkbox"
checked={isChecked}
title={title}
/>
<label htmlFor={permissionName}>{description}</label>
</div>
);
});
const { selectedPermissions } = this.props;
return (
<div className="permission-approval-container__content__requested">
{items}
<PermissionsConnectPermissionList permissions={selectedPermissions} />
</div>
);
}

View File

@ -62,15 +62,6 @@ export default class PermissionPageContainer extends Component {
return Object.keys(props.request.permissions || {});
}
onPermissionToggle = (methodName) => {
this.setState({
selectedPermissions: {
...this.state.selectedPermissions,
[methodName]: !this.state.selectedPermissions[methodName],
},
});
};
componentDidMount() {
this.context.metricsEvent({
eventOpts: {
@ -129,7 +120,6 @@ export default class PermissionPageContainer extends Component {
requestMetadata={requestMetadata}
domainMetadata={targetDomainMetadata}
selectedPermissions={this.state.selectedPermissions}
onPermissionToggle={this.onPermissionToggle}
selectedIdentities={selectedIdentities}
allIdentitiesSelected={allIdentitiesSelected}
/>

View File

@ -9,20 +9,6 @@
display: flex;
flex-direction: column;
align-items: center;
.icon-with-fallback__identicon-container,
.icon-with-fallback__identicon-border {
height: 64px;
width: 64px;
}
.icon-with-fallback__identicon-border {
border: 1px solid $Grey-100;
}
.icon-with-fallback__identicon-container {
margin-bottom: 8px;
}
}
&__title {
@ -33,7 +19,6 @@
margin-top: 16px;
}
&__text,
&__subtitle {
@include H6;
@ -41,16 +26,6 @@
color: $Grey-500;
}
&__text {
width: 100%;
text-overflow: ellipsis;
overflow: hidden;
margin-top: 8px;
/*rtl:ignore*/
direction: rtl;
}
&__subtitle {
margin-top: 4px;
}

View File

@ -1,6 +1,6 @@
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import SiteIcon from '../../ui/site-icon';
import SiteOrigin from '../../ui/site-origin/site-origin';
export default class PermissionsConnectHeader extends Component {
static propTypes = {
@ -22,8 +22,7 @@ export default class PermissionsConnectHeader extends Component {
return (
<div className="permissions-connect-header__icon">
<SiteIcon icon={icon} name={iconName} size={64} />
<div className="permissions-connect-header__text">{siteOrigin}</div>
<SiteOrigin siteOrigin={siteOrigin} iconSrc={icon} name={iconName} />
</div>
);
}

View File

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

View File

@ -0,0 +1,22 @@
.permissions-connect-permission-list {
.permission {
@include H6;
width: 100%;
padding-bottom: 16px;
border-bottom: 1px solid $Grey-100;
display: flex;
flex-direction: row;
align-items: center;
color: $Black-100;
i {
display: block;
padding: 16px;
min-width: 16px;
min-height: 16px;
color: $Grey-500;
font-size: 1rem;
}
}
}

View File

@ -0,0 +1,33 @@
import React, { useMemo } from 'react';
import PropTypes from 'prop-types';
import { useI18nContext } from '../../../hooks/useI18nContext';
export default function PermissionsConnectPermissionList({ permissions }) {
const t = useI18nContext();
const PERMISSION_TYPES = useMemo(() => {
return {
eth_accounts: {
leftIcon: 'fas fa-eye',
label: t('eth_accounts'),
rightIcon: null,
},
};
}, [t]);
return (
<div className="permissions-connect-permission-list">
{Object.keys(permissions).map((permission) => (
<div className="permission" key={PERMISSION_TYPES[permission].label}>
<i className={PERMISSION_TYPES[permission].leftIcon} />
{PERMISSION_TYPES[permission].label}
<i className={PERMISSION_TYPES[permission].rightIcon} />
</div>
))}
</div>
);
}
PermissionsConnectPermissionList.propTypes = {
permissions: PropTypes.objectOf(PropTypes.bool).isRequired,
};

View File

@ -0,0 +1,24 @@
import React from 'react';
import PermissionsConnectList from '.';
export default {
title: 'Components/App/PermissionsConnectList',
id: __filename,
component: PermissionsConnectList,
argTypes: {
permissions: {
control: 'object',
},
},
};
export const DefaultStory = (args) => <PermissionsConnectList {...args} />;
DefaultStory.storyName = 'Default';
DefaultStory.args = {
permissions: {
eth_accounts: true,
},
};

View File

@ -16,6 +16,7 @@ export default function Chip({
leftIcon,
rightIcon,
onClick,
maxContent = true,
}) {
const onKeyPress = (event) => {
if (event.key === 'Enter' && onClick) {
@ -35,6 +36,7 @@ export default function Chip({
'chip--with-right-icon': Boolean(rightIcon),
[`chip--border-color-${borderColor}`]: true,
[`chip--background-color-${backgroundColor}`]: true,
'chip--max-content': maxContent,
})}
role={isInteractive ? 'button' : undefined}
tabIndex={isInteractive ? 0 : undefined}
@ -99,4 +101,9 @@ Chip.propTypes = {
* The onClick handler to be passed to the Chip component
*/
onClick: PropTypes.func,
/**
* If the width: max-content; is used in css.
* max-content can overflow the parent's width and break designs
*/
maxContent: PropTypes.bool,
};

View File

@ -9,7 +9,6 @@
margin: 0 4px;
display: flex;
align-items: center;
width: max-content;
&__left-icon,
&__right-icon {
@ -63,4 +62,8 @@
margin-right: 8px;
}
}
&--max-content {
width: max-content;
}
}

View File

@ -0,0 +1 @@
export { default } from './site-origin';

View File

@ -0,0 +1,15 @@
.site-origin {
.chip__left-icon {
padding: 4px 0 4px 8px;
}
span {
display: inline-block;
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
/*rtl:ignore*/
direction: rtl;
}
}

View File

@ -0,0 +1,22 @@
import React from 'react';
import PropTypes from 'prop-types';
import Chip from '../chip';
import IconWithFallback from '../icon-with-fallback';
export default function SiteOrigin({ siteOrigin, iconSrc, iconName }) {
return (
<div className="site-origin">
<Chip
label={siteOrigin}
maxContent={false}
leftIcon={<IconWithFallback icon={iconSrc} name={iconName} size={32} />}
/>
</div>
);
}
SiteOrigin.propTypes = {
siteOrigin: PropTypes.string.isRequired,
iconName: PropTypes.string,
iconSrc: PropTypes.string,
};

View File

@ -0,0 +1,30 @@
import React from 'react';
import SiteOrigin from '.';
export default {
title: 'Components/UI/SiteOrigin',
id: __filename,
component: SiteOrigin,
argTypes: {
siteOrigin: {
control: 'text',
},
iconSrc: {
control: 'text',
},
iconName: {
control: 'text',
},
},
};
export const DefaultStory = (args) => <SiteOrigin {...args} />;
DefaultStory.storyName = 'Default';
DefaultStory.args = {
siteOrigin: 'https://metamask.io',
iconName: 'MetaMask',
iconSrc: './metamark.svg',
};

View File

@ -45,6 +45,7 @@
@import 'readonly-input/index';
@import 'sender-to-recipient/index';
@import 'snackbar/index';
@import 'site-origin/index';
@import 'slider/index';
@import 'tabs/index';
@import 'toggle-button/index';

View File

@ -24,9 +24,10 @@
}
&__back {
@include H6;
@include H7;
color: $Grey-600;
color: $Grey-500;
font-weight: bold;
cursor: pointer;
i {
@ -37,7 +38,7 @@
&__page-count {
@include H7;
color: #6a737d;
color: $Grey-500;
grid-column: 2;
justify-self: end;
font-weight: bold;

View File

@ -174,7 +174,7 @@ export default class PermissionConnect extends Component {
className="permissions-connect__back"
onClick={() => this.goBack()}
>
<i className="fas fa-chevron-left" />
<i className="fas fa-chevron-left"></i>
{t('back')}
</div>
) : null}