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

[FLASK] Add permission cell component (#18372)

* Add permission cell component

Add storybook and handling for revoked permission colors

* Fix things after conflict resolve after rebase

* Add code refactoring and minor UI changes

* Add permission cell component to snap-update flow

* Update storybook

* Add unit tests for permission cell

* Update component padding

* Fix spacing between permission cells

* Fix main icon color for approved permissions

* Update width value with constant
This commit is contained in:
David Drazic 2023-04-03 19:33:54 +02:00 committed by GitHub
parent f51055802f
commit 8603a4b067
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 309 additions and 164 deletions

View File

@ -2927,7 +2927,7 @@
"description": "An extended description for the `snap_getBip32Entropy` permission. $1 is a derivation path (name)" "description": "An extended description for the `snap_getBip32Entropy` permission. $1 is a derivation path (name)"
}, },
"permission_manageBip44Keys": { "permission_manageBip44Keys": {
"message": "Control your \"$1\" accounts and assets.", "message": "Control your $1 accounts and assets.",
"description": "The description for the `snap_getBip44Entropy` permission. $1 is the name of a protocol, e.g. 'Filecoin'." "description": "The description for the `snap_getBip44Entropy` permission. $1 is the name of a protocol, e.g. 'Filecoin'."
}, },
"permission_manageBip44KeysDescription": { "permission_manageBip44KeysDescription": {

View File

@ -59,6 +59,7 @@
@import 'permissions-connect-footer/index'; @import 'permissions-connect-footer/index';
@import 'permissions-connect-header/index'; @import 'permissions-connect-header/index';
@import 'permissions-connect-permission-list/index'; @import 'permissions-connect-permission-list/index';
@import 'permission-cell/index';
@import 'recovery-phrase-reminder/index'; @import 'recovery-phrase-reminder/index';
@import 'set-approval-for-all-warning/index'; @import 'set-approval-for-all-warning/index';
@import 'step-progress-bar/index.scss'; @import 'step-progress-bar/index.scss';

View File

@ -1,14 +1,9 @@
import React from 'react'; import React from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { isFunction } from 'lodash'; import { getWeightedPermissions } from '../../../../helpers/utils/permission';
import {
getRightIcon,
getWeightedPermissions,
} from '../../../../helpers/utils/permission';
import { useI18nContext } from '../../../../hooks/useI18nContext'; import { useI18nContext } from '../../../../hooks/useI18nContext';
import { formatDate } from '../../../../helpers/utils/util'; import PermissionCell from '../../permission-cell';
import Typography from '../../../ui/typography/typography'; import Box from '../../../ui/box';
import { TextColor } from '../../../../helpers/constants/design-system';
export default function UpdateSnapPermissionList({ export default function UpdateSnapPermissionList({
approvedPermissions, approvedPermissions,
@ -17,52 +12,50 @@ export default function UpdateSnapPermissionList({
}) { }) {
const t = useI18nContext(); const t = useI18nContext();
const Permissions = ({ className, permissions, subText }) => {
return getWeightedPermissions(t, permissions).map((permission) => {
const { label, permissionName, permissionValue } = permission;
return (
<div className={className} key={permissionName}>
<i className="fas fa-x" />
<div className="permission-description">
{label}
<Typography
color={TextColor.textAlternative}
boxProps={{ paddingTop: 1 }}
className="permission-description-subtext"
>
{isFunction(subText)
? subText(permissionName, permissionValue)
: subText}
</Typography>
</div>
{getRightIcon(permission)}
</div>
);
});
};
return ( return (
<div className="update-snap-permission-list"> <Box paddingTop={1}>
<Permissions {getWeightedPermissions(t, newPermissions).map((permission, index) => {
className="new-permission" return (
permissions={newPermissions} <PermissionCell
subText={t('permissionRequested')} title={permission.label}
/> description={permission.description}
<Permissions weight={permission.weight}
className="approved-permission" avatarIcon={permission.leftIcon}
permissions={approvedPermissions} dateApproved={permission?.permissionValue?.date}
subText={(_, permissionValue) => { key={`${permission.permissionName}-${index}`}
const { date } = permissionValue; />
const formattedDate = formatDate(date, 'yyyy-MM-dd'); );
return t('approvedOn', [formattedDate]); })}
}} {getWeightedPermissions(t, approvedPermissions).map(
/> (permission, index) => {
<Permissions return (
className="revoked-permission" <PermissionCell
permissions={revokedPermissions} title={permission.label}
subText={t('permissionRevoked')} description={permission.description}
/> weight={permission.weight}
</div> avatarIcon={permission.leftIcon}
dateApproved={permission?.permissionValue?.date}
key={`${permission.permissionName}-${index}`}
/>
);
},
)}
{getWeightedPermissions(t, revokedPermissions).map(
(permission, index) => {
return (
<PermissionCell
title={permission.label}
description={permission.description}
weight={permission.weight}
avatarIcon={permission.leftIcon}
dateApproved={permission?.permissionValue?.date}
key={`${permission.permissionName}-${index}`}
revoked
/>
);
},
)}
</Box>
); );
} }

View File

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

View File

@ -0,0 +1,5 @@
.permission-cell {
&__title-revoked {
text-decoration: line-through;
}
}

View File

@ -0,0 +1,126 @@
import React from 'react';
import PropTypes from 'prop-types';
import classnames from 'classnames';
import Box from '../../ui/box';
import {
AlignItems,
Color,
IconColor,
JustifyContent,
Size,
TextColor,
TextVariant,
} from '../../../helpers/constants/design-system';
import {
AvatarIcon,
Icon,
ICON_NAMES,
ICON_SIZES,
Text,
} from '../../component-library';
import { formatDate } from '../../../helpers/utils/util';
import { useI18nContext } from '../../../hooks/useI18nContext';
import Tooltip from '../../ui/tooltip';
const PermissionCell = ({
title,
description,
weight,
avatarIcon,
dateApproved,
revoked,
}) => {
const t = useI18nContext();
let infoIconColor = IconColor.iconMuted;
let infoIcon = ICON_NAMES.INFO;
let iconColor = Color.primaryDefault;
let iconBackgroundColor = Color.primaryMuted;
if (!revoked && weight === 1) {
iconColor = Color.warningDefault;
iconBackgroundColor = Color.warningMuted;
infoIconColor = IconColor.warningDefault;
infoIcon = ICON_NAMES.DANGER;
}
if (dateApproved) {
iconColor = Color.iconMuted;
iconBackgroundColor = Color.backgroundAlternative;
}
if (revoked) {
iconColor = Color.iconMuted;
iconBackgroundColor = Color.backgroundAlternative;
}
return (
<Box
className="permission-cell"
justifyContent={JustifyContent.center}
alignItems={AlignItems.flexStart}
marginLeft={4}
marginRight={4}
paddingTop={2}
paddingBottom={2}
>
<Box>
{typeof avatarIcon === 'string' ? (
<AvatarIcon
iconName={avatarIcon}
size={ICON_SIZES.MD}
iconProps={{
size: ICON_SIZES.SM,
}}
color={iconColor}
backgroundColor={iconBackgroundColor}
/>
) : (
avatarIcon
)}
</Box>
<Box width="full" marginLeft={4} marginRight={4}>
<Text
size={Size.MD}
variant={TextVariant.bodyMd}
className={classnames('permission-cell__title', {
'permission-cell__title-revoked': revoked,
})}
>
{title}
</Text>
<Text
size={Size.XS}
className="permission-cell__status"
variant={TextVariant.bodyXs}
color={TextColor.textAlternative}
>
{!revoked &&
(dateApproved
? t('approvedOn', [formatDate(dateApproved, 'yyyy-MM-dd')])
: t('permissionRequested'))}
{revoked ? t('permissionRevoked') : ''}
</Text>
</Box>
<Box>
<Tooltip html={<div>{description}</div>} position="bottom">
<Icon color={infoIconColor} name={infoIcon} size={ICON_SIZES.SM} />
</Tooltip>
</Box>
</Box>
);
};
PermissionCell.propTypes = {
title: PropTypes.oneOfType([
PropTypes.string.isRequired,
PropTypes.object.isRequired,
]),
description: PropTypes.oneOfType([PropTypes.string, PropTypes.object]),
weight: PropTypes.number,
avatarIcon: PropTypes.any.isRequired,
dateApproved: PropTypes.number,
revoked: PropTypes.bool,
};
export default PermissionCell;

View File

@ -0,0 +1,22 @@
import React from 'react';
import PermissionCell from '.';
export default {
title: 'Components/App/PermissionCell',
component: PermissionCell,
};
export const DefaultStory = (args) => <PermissionCell {...args} />;
DefaultStory.storyName = 'Default';
DefaultStory.args = {
title: 'Access the Ethereum provider.',
description:
'Allow the snap to communicate with MetaMask direct…blockchain and suggest messages and transactions.',
weight: 1,
avatarIcon: 'ethereum',
dateApproved: 1680185432326,
revoked: false,
};

View File

@ -0,0 +1,69 @@
import React from 'react';
import { screen } from '@testing-library/react';
import { renderWithProvider } from '../../../../test/jest';
import PermissionCell from './permission-cell';
describe('Permission Cell', () => {
const mockPermissionData = {
label: 'Access the Ethereum provider.',
description:
'Allow the snap to communicate with MetaMask direct…blockchain and suggest messages and transactions.',
weight: 1,
leftIcon: 'ethereum',
permissionValue: {
date: 1680185432326,
},
permissionName: 'ethereum-provider',
};
it('renders approved permission cell', () => {
renderWithProvider(
<PermissionCell
title={mockPermissionData.label}
description={mockPermissionData.description}
weight={mockPermissionData.weight}
avatarIcon={mockPermissionData.leftIcon}
dateApproved={mockPermissionData?.permissionValue?.date}
key={`${mockPermissionData.permissionName}-${1}`}
/>,
);
expect(
screen.getByText('Access the Ethereum provider.'),
).toBeInTheDocument();
expect(screen.getByText('Approved on 2023-03-30')).toBeInTheDocument();
});
it('renders revoked permission cell', () => {
renderWithProvider(
<PermissionCell
title={mockPermissionData.label}
description={mockPermissionData.description}
weight={mockPermissionData.weight}
avatarIcon={mockPermissionData.leftIcon}
dateApproved={mockPermissionData?.permissionValue?.date}
key={`${mockPermissionData.permissionName}-${1}`}
revoked
/>,
);
expect(
screen.getByText('Access the Ethereum provider.'),
).toBeInTheDocument();
expect(screen.getByText('Revoked in this update')).toBeInTheDocument();
});
it('renders requested permission cell', () => {
renderWithProvider(
<PermissionCell
title={mockPermissionData.label}
description={mockPermissionData.description}
weight={mockPermissionData.weight}
avatarIcon={mockPermissionData.leftIcon}
key={`${mockPermissionData.permissionName}-${1}`}
/>,
);
expect(
screen.getByText('Access the Ethereum provider.'),
).toBeInTheDocument();
expect(screen.getByText('Requested now')).toBeInTheDocument();
});
});

View File

@ -1,37 +1,28 @@
import React from 'react'; import React from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { import { getWeightedPermissions } from '../../../helpers/utils/permission';
getRightIcon,
getWeightedPermissions,
} from '../../../helpers/utils/permission';
import { useI18nContext } from '../../../hooks/useI18nContext'; import { useI18nContext } from '../../../hooks/useI18nContext';
import PermissionCell from '../permission-cell';
/** import Box from '../../ui/box';
* Get one or more permission descriptions for a permission name.
*
* @param permission - The permission to render.
* @param index - The index of the permission.
* @returns {JSX.Element} A permission description node.
*/
function getDescriptionNode(permission, index) {
const { label, leftIcon, permissionName } = permission;
return (
<div className="permission" key={`${permissionName}-${index}`}>
{typeof leftIcon === 'string' ? <i className={leftIcon} /> : leftIcon}
{label}
{getRightIcon(permission)}
</div>
);
}
export default function PermissionsConnectPermissionList({ permissions }) { export default function PermissionsConnectPermissionList({ permissions }) {
const t = useI18nContext(); const t = useI18nContext();
return ( return (
<div className="permissions-connect-permission-list"> <Box paddingTop={2} paddingBottom={2}>
{getWeightedPermissions(t, permissions).map(getDescriptionNode)} {getWeightedPermissions(t, permissions).map((permission, index) => {
</div> return (
<PermissionCell
title={permission.label}
description={permission.description}
weight={permission.weight}
avatarIcon={permission.leftIcon}
dateApproved={permission?.permissionValue?.date}
key={`${permission.permissionName}-${index}`}
/>
);
})}
</Box>
); );
} }

View File

@ -15,21 +15,13 @@ import {
} from '../../../shared/constants/permissions'; } from '../../../shared/constants/permissions';
import Tooltip from '../../components/ui/tooltip'; import Tooltip from '../../components/ui/tooltip';
import { import {
AvatarIcon,
///: BEGIN:ONLY_INCLUDE_IN(flask) ///: BEGIN:ONLY_INCLUDE_IN(flask)
Icon,
Text, Text,
///: END:ONLY_INCLUDE_IN ///: END:ONLY_INCLUDE_IN
ICON_NAMES, ICON_NAMES,
ICON_SIZES,
} from '../../components/component-library'; } from '../../components/component-library';
///: BEGIN:ONLY_INCLUDE_IN(flask) ///: BEGIN:ONLY_INCLUDE_IN(flask)
import { import { Color, FONT_WEIGHT, TextVariant } from '../constants/design-system';
IconColor,
Color,
FONT_WEIGHT,
TextVariant,
} from '../constants/design-system';
import { import {
coinTypeToProtocolName, coinTypeToProtocolName,
getSnapDerivationPathName, getSnapDerivationPathName,
@ -39,63 +31,29 @@ import {
const UNKNOWN_PERMISSION = Symbol('unknown'); const UNKNOWN_PERMISSION = Symbol('unknown');
///: BEGIN:ONLY_INCLUDE_IN(flask)
const RIGHT_WARNING_ICON = (
<Icon
name={ICON_NAMES.DANGER}
size={ICON_SIZES.SM}
color={IconColor.warningDefault}
/>
);
const RIGHT_INFO_ICON = (
<Icon
name={ICON_NAMES.INFO}
size={ICON_SIZES.SM}
color={IconColor.iconMuted}
/>
);
///: END:ONLY_INCLUDE_IN
function getLeftIcon(iconName) {
return (
<AvatarIcon
iconName={iconName}
size={ICON_SIZES.SM}
iconProps={{
size: ICON_SIZES.XS,
}}
/>
);
}
export const PERMISSION_DESCRIPTIONS = deepFreeze({ export const PERMISSION_DESCRIPTIONS = deepFreeze({
[RestrictedMethods.eth_accounts]: ({ t }) => ({ [RestrictedMethods.eth_accounts]: ({ t }) => ({
label: t('permission_ethereumAccounts'), label: t('permission_ethereumAccounts'),
leftIcon: getLeftIcon(ICON_NAMES.EYE), leftIcon: ICON_NAMES.EYE,
rightIcon: null,
weight: 2, weight: 2,
}), }),
///: BEGIN:ONLY_INCLUDE_IN(flask) ///: BEGIN:ONLY_INCLUDE_IN(flask)
[RestrictedMethods.snap_confirm]: ({ t }) => ({ [RestrictedMethods.snap_confirm]: ({ t }) => ({
label: t('permission_customConfirmation'), label: t('permission_customConfirmation'),
description: t('permission_customConfirmationDescription'), description: t('permission_customConfirmationDescription'),
leftIcon: getLeftIcon(ICON_NAMES.SECURITY_TICK), leftIcon: ICON_NAMES.SECURITY_TICK,
rightIcon: RIGHT_INFO_ICON,
weight: 3, weight: 3,
}), }),
[RestrictedMethods.snap_dialog]: ({ t }) => ({ [RestrictedMethods.snap_dialog]: ({ t }) => ({
label: t('permission_dialog'), label: t('permission_dialog'),
description: t('permission_dialogDescription'), description: t('permission_dialogDescription'),
leftIcon: getLeftIcon(ICON_NAMES.MESSAGES), leftIcon: ICON_NAMES.MESSAGES,
rightIcon: RIGHT_INFO_ICON,
weight: 3, weight: 3,
}), }),
[RestrictedMethods.snap_notify]: ({ t }) => ({ [RestrictedMethods.snap_notify]: ({ t }) => ({
label: t('permission_notifications'), label: t('permission_notifications'),
description: t('permission_notificationsDescription'), description: t('permission_notificationsDescription'),
leftIcon: getLeftIcon(ICON_NAMES.NOTIFICATION), leftIcon: ICON_NAMES.NOTIFICATION,
rightIcon: RIGHT_INFO_ICON,
weight: 3, weight: 3,
}), }),
[RestrictedMethods.snap_getBip32PublicKey]: ({ [RestrictedMethods.snap_getBip32PublicKey]: ({
@ -105,8 +63,7 @@ export const PERMISSION_DESCRIPTIONS = deepFreeze({
}) => }) =>
permissionValue.caveats[0].value.map(({ path, curve }, i) => { permissionValue.caveats[0].value.map(({ path, curve }, i) => {
const baseDescription = { const baseDescription = {
leftIcon: getLeftIcon(ICON_NAMES.SECURITY_SEARCH), leftIcon: ICON_NAMES.SECURITY_SEARCH,
rightIcon: RIGHT_WARNING_ICON,
weight: 1, weight: 1,
id: `public-key-access-bip32-${path id: `public-key-access-bip32-${path
.join('-') .join('-')
@ -176,8 +133,7 @@ export const PERMISSION_DESCRIPTIONS = deepFreeze({
}) => }) =>
permissionValue.caveats[0].value.map(({ path, curve }, i) => { permissionValue.caveats[0].value.map(({ path, curve }, i) => {
const baseDescription = { const baseDescription = {
leftIcon: getLeftIcon(ICON_NAMES.KEY), leftIcon: ICON_NAMES.KEY,
rightIcon: RIGHT_WARNING_ICON,
weight: 1, weight: 1,
id: `key-access-bip32-${path id: `key-access-bip32-${path
.join('-') .join('-')
@ -261,8 +217,7 @@ export const PERMISSION_DESCRIPTIONS = deepFreeze({
t('unrecognizedProtocol', [coinType])} t('unrecognizedProtocol', [coinType])}
</span>, </span>,
]), ]),
leftIcon: getLeftIcon(ICON_NAMES.KEY), leftIcon: ICON_NAMES.KEY,
rightIcon: RIGHT_WARNING_ICON,
weight: 1, weight: 1,
id: `key-access-bip44-${coinType}-${i}`, id: `key-access-bip44-${coinType}-${i}`,
message: t('snapInstallWarningKeyAccess', [ message: t('snapInstallWarningKeyAccess', [
@ -284,22 +239,19 @@ export const PERMISSION_DESCRIPTIONS = deepFreeze({
[RestrictedMethods.snap_getEntropy]: ({ t }) => ({ [RestrictedMethods.snap_getEntropy]: ({ t }) => ({
label: t('permission_getEntropy'), label: t('permission_getEntropy'),
description: t('permission_getEntropyDescription'), description: t('permission_getEntropyDescription'),
leftIcon: getLeftIcon(ICON_NAMES.SECURITY_KEY), leftIcon: ICON_NAMES.SECURITY_KEY,
rightIcon: RIGHT_INFO_ICON,
weight: 3, weight: 3,
}), }),
[RestrictedMethods.snap_manageState]: ({ t }) => ({ [RestrictedMethods.snap_manageState]: ({ t }) => ({
label: t('permission_manageState'), label: t('permission_manageState'),
description: t('permission_manageStateDescription'), description: t('permission_manageStateDescription'),
leftIcon: getLeftIcon(ICON_NAMES.ADD_SQUARE), leftIcon: ICON_NAMES.ADD_SQUARE,
rightIcon: RIGHT_INFO_ICON,
weight: 3, weight: 3,
}), }),
[RestrictedMethods.wallet_snap]: ({ t, permissionValue }) => { [RestrictedMethods.wallet_snap]: ({ t, permissionValue }) => {
const snaps = permissionValue.caveats[0].value; const snaps = permissionValue.caveats[0].value;
const baseDescription = { const baseDescription = {
leftIcon: getLeftIcon(ICON_NAMES.FLASH), leftIcon: ICON_NAMES.FLASH,
rightIcon: RIGHT_INFO_ICON,
}; };
return Object.keys(snaps).map((snapId) => { return Object.keys(snaps).map((snapId) => {
@ -326,8 +278,7 @@ export const PERMISSION_DESCRIPTIONS = deepFreeze({
[EndowmentPermissions['endowment:network-access']]: ({ t }) => ({ [EndowmentPermissions['endowment:network-access']]: ({ t }) => ({
label: t('permission_accessNetwork'), label: t('permission_accessNetwork'),
description: t('permission_accessNetworkDescription'), description: t('permission_accessNetworkDescription'),
leftIcon: getLeftIcon(ICON_NAMES.GLOBAL), leftIcon: ICON_NAMES.GLOBAL,
rightIcon: RIGHT_INFO_ICON,
weight: 2, weight: 2,
}), }),
[EndowmentPermissions['endowment:webassembly']]: ({ t }) => ({ [EndowmentPermissions['endowment:webassembly']]: ({ t }) => ({
@ -340,8 +291,7 @@ export const PERMISSION_DESCRIPTIONS = deepFreeze({
[EndowmentPermissions['endowment:long-running']]: ({ t }) => ({ [EndowmentPermissions['endowment:long-running']]: ({ t }) => ({
label: t('permission_longRunning'), label: t('permission_longRunning'),
description: t('permission_longRunningDescription'), description: t('permission_longRunningDescription'),
leftIcon: getLeftIcon(ICON_NAMES.LINK), leftIcon: ICON_NAMES.LINK,
rightIcon: RIGHT_INFO_ICON,
weight: 3, weight: 3,
}), }),
[EndowmentPermissions['endowment:transaction-insight']]: ({ [EndowmentPermissions['endowment:transaction-insight']]: ({
@ -349,8 +299,7 @@ export const PERMISSION_DESCRIPTIONS = deepFreeze({
permissionValue, permissionValue,
}) => { }) => {
const baseDescription = { const baseDescription = {
leftIcon: getLeftIcon(ICON_NAMES.SPEEDOMETER), leftIcon: ICON_NAMES.SPEEDOMETER,
rightIcon: RIGHT_INFO_ICON,
weight: 3, weight: 3,
}; };
@ -371,7 +320,7 @@ export const PERMISSION_DESCRIPTIONS = deepFreeze({
...baseDescription, ...baseDescription,
label: t('permission_transactionInsightOrigin'), label: t('permission_transactionInsightOrigin'),
description: t('permission_transactionInsightOriginDescription'), description: t('permission_transactionInsightOriginDescription'),
leftIcon: getLeftIcon(ICON_NAMES.EXPLORE), leftIcon: ICON_NAMES.EXPLORE,
}); });
} }
@ -380,8 +329,7 @@ export const PERMISSION_DESCRIPTIONS = deepFreeze({
[EndowmentPermissions['endowment:cronjob']]: ({ t }) => ({ [EndowmentPermissions['endowment:cronjob']]: ({ t }) => ({
label: t('permission_cronjob'), label: t('permission_cronjob'),
description: t('permission_cronjobDescription'), description: t('permission_cronjobDescription'),
leftIcon: getLeftIcon(ICON_NAMES.CLOCK), leftIcon: ICON_NAMES.CLOCK,
rightIcon: RIGHT_INFO_ICON,
weight: 2, weight: 2,
}), }),
[EndowmentPermissions['endowment:ethereum-provider']]: ({ [EndowmentPermissions['endowment:ethereum-provider']]: ({
@ -390,16 +338,14 @@ export const PERMISSION_DESCRIPTIONS = deepFreeze({
}) => ({ }) => ({
label: t('permission_ethereumProvider'), label: t('permission_ethereumProvider'),
description: t('permission_ethereumProviderDescription'), description: t('permission_ethereumProviderDescription'),
leftIcon: getLeftIcon(ICON_NAMES.ETHEREUM), leftIcon: ICON_NAMES.ETHEREUM,
rightIcon: RIGHT_INFO_ICON,
weight: 1, weight: 1,
id: 'ethereum-provider-access', id: 'ethereum-provider-access',
message: t('ethereumProviderAccess', [targetSubjectMetadata?.origin]), message: t('ethereumProviderAccess', [targetSubjectMetadata?.origin]),
}), }),
[EndowmentPermissions['endowment:rpc']]: ({ t, permissionValue }) => { [EndowmentPermissions['endowment:rpc']]: ({ t, permissionValue }) => {
const baseDescription = { const baseDescription = {
leftIcon: getLeftIcon(ICON_NAMES.HIERARCHY), leftIcon: ICON_NAMES.HIERARCHY,
rightIcon: RIGHT_INFO_ICON,
weight: 2, weight: 2,
}; };
@ -427,8 +373,7 @@ export const PERMISSION_DESCRIPTIONS = deepFreeze({
///: END:ONLY_INCLUDE_IN ///: END:ONLY_INCLUDE_IN
[UNKNOWN_PERMISSION]: ({ t, permissionName }) => ({ [UNKNOWN_PERMISSION]: ({ t, permissionName }) => ({
label: t('permission_unknown', [permissionName ?? 'undefined']), label: t('permission_unknown', [permissionName ?? 'undefined']),
leftIcon: getLeftIcon(ICON_NAMES.QUESTION), leftIcon: ICON_NAMES.QUESTION,
rightIcon: null,
weight: 4, weight: 4,
}), }),
}); });

View File

@ -4,14 +4,6 @@
.headers { .headers {
flex: 1; flex: 1;
.permissions-connect-permission-list {
padding: 0 24px;
.permission {
padding: 8px 0;
}
}
.loader-container { .loader-container {
height: 100%; height: 100%;
} }
@ -21,7 +13,6 @@
} }
} }
.page-container__footer { .page-container__footer {
width: 100%; width: 100%;
margin-top: 12px; margin-top: 12px;

View File

@ -13,6 +13,7 @@ import {
TEXT_ALIGN, TEXT_ALIGN,
FRACTIONS, FRACTIONS,
TextColor, TextColor,
BLOCK_SIZES,
} from '../../../../helpers/constants/design-system'; } from '../../../../helpers/constants/design-system';
import SnapAuthorship from '../../../../components/app/flask/snap-authorship'; import SnapAuthorship from '../../../../components/app/flask/snap-authorship';
import Box from '../../../../components/ui/box'; import Box from '../../../../components/ui/box';
@ -176,7 +177,7 @@ function ViewSnap() {
> >
{t('snapAccess', [snap.manifest.proposedName])} {t('snapAccess', [snap.manifest.proposedName])}
</Typography> </Typography>
<Box width={FRACTIONS.TEN_TWELFTHS}> <Box width={BLOCK_SIZES.FULL}>
<PermissionsConnectPermissionList <PermissionsConnectPermissionList
permissions={permissions ?? {}} permissions={permissions ?? {}}
/> />