mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-12-23 09:52:26 +01:00
[FLASK] Revert changes made to stable permission display (UI design) (#18470)
* Revert changes made to stable permission display (UI design) * Add test for new component * Update paddings for install flow * Fix missing icons on snap installation flow * Update storybook path * Add targetSubjectMetadata param --------- Co-authored-by: legobeat <109787230+legobeat@users.noreply.github.com> Co-authored-by: Frederik Bolding <frederik.bolding@gmail.com>
This commit is contained in:
parent
b7518c0810
commit
525d5ff54e
1
ui/components/app/flask/snap-permissions-list/index.js
Normal file
1
ui/components/app/flask/snap-permissions-list/index.js
Normal file
@ -0,0 +1 @@
|
|||||||
|
export { default } from './snap-permissions-list';
|
@ -0,0 +1,37 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import { getWeightedPermissions } from '../../../../helpers/utils/permission';
|
||||||
|
import { useI18nContext } from '../../../../hooks/useI18nContext';
|
||||||
|
import PermissionCell from '../../permission-cell';
|
||||||
|
import Box from '../../../ui/box';
|
||||||
|
|
||||||
|
export default function SnapPermissionsList({
|
||||||
|
permissions,
|
||||||
|
targetSubjectMetadata,
|
||||||
|
}) {
|
||||||
|
const t = useI18nContext();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Box paddingTop={2} paddingBottom={2} className="snap-permissions-list">
|
||||||
|
{getWeightedPermissions(t, permissions, targetSubjectMetadata).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}`}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
)}
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
SnapPermissionsList.propTypes = {
|
||||||
|
permissions: PropTypes.object.isRequired,
|
||||||
|
targetSubjectMetadata: PropTypes.object.isRequired,
|
||||||
|
};
|
@ -0,0 +1,37 @@
|
|||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
import SnapPermissionsList from '.';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
title: 'Components/App/flask/SnapPermissionsList',
|
||||||
|
|
||||||
|
component: SnapPermissionsList,
|
||||||
|
argTypes: {
|
||||||
|
permissions: {
|
||||||
|
control: 'object',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export const DefaultStory = (args) => <SnapPermissionsList {...args} />;
|
||||||
|
|
||||||
|
DefaultStory.storyName = 'Default';
|
||||||
|
|
||||||
|
DefaultStory.args = {
|
||||||
|
permissions: {
|
||||||
|
eth_accounts: {},
|
||||||
|
snap_dialog: {},
|
||||||
|
snap_getBip32PublicKey: {
|
||||||
|
caveats: [
|
||||||
|
{
|
||||||
|
value: [
|
||||||
|
{
|
||||||
|
path: ['m', `44'`, `0'`],
|
||||||
|
curve: 'secp256k1',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
@ -0,0 +1,37 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { screen } from '@testing-library/react';
|
||||||
|
import { renderWithProvider } from '../../../../../test/jest';
|
||||||
|
import SnapPermissionsList from './snap-permissions-list';
|
||||||
|
|
||||||
|
describe('Snap Permission List', () => {
|
||||||
|
const mockPermissionData = {
|
||||||
|
snap_dialog: {
|
||||||
|
caveats: null,
|
||||||
|
date: 1680709920602,
|
||||||
|
id: '4dduR1BpsmS0ZJfeVtiAh',
|
||||||
|
invoker: 'local:http://localhost:8080',
|
||||||
|
parentCapability: 'snap_dialog',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const mockTargetSubjectMetadata = {
|
||||||
|
extensionId: null,
|
||||||
|
iconUrl: null,
|
||||||
|
name: 'TypeScript Example Snap',
|
||||||
|
origin: 'local:http://localhost:8080',
|
||||||
|
subjectType: 'snap',
|
||||||
|
version: '0.2.2',
|
||||||
|
};
|
||||||
|
|
||||||
|
it('renders permissions list for snaps', () => {
|
||||||
|
renderWithProvider(
|
||||||
|
<SnapPermissionsList
|
||||||
|
permissions={mockPermissionData}
|
||||||
|
targetSubjectMetadata={mockTargetSubjectMetadata}
|
||||||
|
/>,
|
||||||
|
);
|
||||||
|
expect(
|
||||||
|
screen.getByText('Display dialog windows in MetaMask.'),
|
||||||
|
).toBeInTheDocument();
|
||||||
|
expect(screen.getByText('Approved on 2023-04-05')).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
});
|
@ -53,6 +53,11 @@ const PermissionCell = ({
|
|||||||
iconBackgroundColor = Color.backgroundAlternative;
|
iconBackgroundColor = Color.backgroundAlternative;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let permissionIcon = avatarIcon;
|
||||||
|
if (typeof avatarIcon !== 'string' && avatarIcon?.props?.iconName) {
|
||||||
|
permissionIcon = avatarIcon.props.iconName;
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box
|
<Box
|
||||||
className="permission-cell"
|
className="permission-cell"
|
||||||
@ -64,9 +69,9 @@ const PermissionCell = ({
|
|||||||
paddingBottom={2}
|
paddingBottom={2}
|
||||||
>
|
>
|
||||||
<Box>
|
<Box>
|
||||||
{typeof avatarIcon === 'string' ? (
|
{typeof permissionIcon === 'string' ? (
|
||||||
<AvatarIcon
|
<AvatarIcon
|
||||||
iconName={avatarIcon}
|
iconName={permissionIcon}
|
||||||
size={ICON_SIZES.MD}
|
size={ICON_SIZES.MD}
|
||||||
iconProps={{
|
iconProps={{
|
||||||
size: ICON_SIZES.SM,
|
size: ICON_SIZES.SM,
|
||||||
@ -75,7 +80,7 @@ const PermissionCell = ({
|
|||||||
backgroundColor={iconBackgroundColor}
|
backgroundColor={iconBackgroundColor}
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
avatarIcon
|
permissionIcon
|
||||||
)}
|
)}
|
||||||
</Box>
|
</Box>
|
||||||
<Box width="full" marginLeft={4} marginRight={4}>
|
<Box width="full" marginLeft={4} marginRight={4}>
|
||||||
|
@ -28,11 +28,14 @@ export default class PermissionPageContainerContent extends PureComponent {
|
|||||||
};
|
};
|
||||||
|
|
||||||
renderRequestedPermissions() {
|
renderRequestedPermissions() {
|
||||||
const { selectedPermissions } = this.props;
|
const { selectedPermissions, subjectMetadata } = this.props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="permission-approval-container__content__requested">
|
<div className="permission-approval-container__content__requested">
|
||||||
<PermissionsConnectPermissionList permissions={selectedPermissions} />
|
<PermissionsConnectPermissionList
|
||||||
|
permissions={selectedPermissions}
|
||||||
|
targetSubjectMetadata={subjectMetadata}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,29 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { getWeightedPermissions } from '../../../helpers/utils/permission';
|
import {
|
||||||
|
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({
|
export default function PermissionsConnectPermissionList({
|
||||||
permissions,
|
permissions,
|
||||||
@ -12,22 +32,11 @@ export default function PermissionsConnectPermissionList({
|
|||||||
const t = useI18nContext();
|
const t = useI18nContext();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box paddingTop={2} paddingBottom={2}>
|
<div className="permissions-connect-permission-list">
|
||||||
{getWeightedPermissions(t, permissions, targetSubjectMetadata).map(
|
{getWeightedPermissions(t, permissions, targetSubjectMetadata).map(
|
||||||
(permission, index) => {
|
getDescriptionNode,
|
||||||
return (
|
|
||||||
<PermissionCell
|
|
||||||
title={permission.label}
|
|
||||||
description={permission.description}
|
|
||||||
weight={permission.weight}
|
|
||||||
avatarIcon={permission.leftIcon}
|
|
||||||
dateApproved={permission?.permissionValue?.date}
|
|
||||||
key={`${permission.permissionName}-${index}`}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
},
|
|
||||||
)}
|
)}
|
||||||
</Box>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,18 +20,5 @@ DefaultStory.storyName = 'Default';
|
|||||||
DefaultStory.args = {
|
DefaultStory.args = {
|
||||||
permissions: {
|
permissions: {
|
||||||
eth_accounts: {},
|
eth_accounts: {},
|
||||||
snap_dialog: {},
|
|
||||||
snap_getBip32PublicKey: {
|
|
||||||
caveats: [
|
|
||||||
{
|
|
||||||
value: [
|
|
||||||
{
|
|
||||||
path: ['m', `44'`, `0'`],
|
|
||||||
curve: 'secp256k1',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -15,13 +15,23 @@ 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)
|
||||||
Text,
|
Text,
|
||||||
|
Icon,
|
||||||
///: END:ONLY_INCLUDE_IN
|
///: END:ONLY_INCLUDE_IN
|
||||||
} from '../../components/component-library';
|
} from '../../components/component-library';
|
||||||
import { ICON_NAMES } from '../../components/component-library/icon/deprecated';
|
import {
|
||||||
|
ICON_NAMES,
|
||||||
|
ICON_SIZES,
|
||||||
|
} from '../../components/component-library/icon/deprecated';
|
||||||
///: BEGIN:ONLY_INCLUDE_IN(flask)
|
///: BEGIN:ONLY_INCLUDE_IN(flask)
|
||||||
import { Color, FONT_WEIGHT, TextVariant } from '../constants/design-system';
|
import {
|
||||||
|
Color,
|
||||||
|
FONT_WEIGHT,
|
||||||
|
IconColor,
|
||||||
|
TextVariant,
|
||||||
|
} from '../constants/design-system';
|
||||||
import {
|
import {
|
||||||
coinTypeToProtocolName,
|
coinTypeToProtocolName,
|
||||||
getSnapDerivationPathName,
|
getSnapDerivationPathName,
|
||||||
@ -31,10 +41,33 @@ import {
|
|||||||
|
|
||||||
const UNKNOWN_PERMISSION = Symbol('unknown');
|
const UNKNOWN_PERMISSION = Symbol('unknown');
|
||||||
|
|
||||||
|
///: BEGIN:ONLY_INCLUDE_IN(flask)
|
||||||
|
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: ICON_NAMES.EYE,
|
leftIcon: getLeftIcon(ICON_NAMES.EYE),
|
||||||
|
rightIcon: null,
|
||||||
weight: 2,
|
weight: 2,
|
||||||
}),
|
}),
|
||||||
///: BEGIN:ONLY_INCLUDE_IN(flask)
|
///: BEGIN:ONLY_INCLUDE_IN(flask)
|
||||||
@ -251,7 +284,8 @@ export const PERMISSION_DESCRIPTIONS = deepFreeze({
|
|||||||
[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: ICON_NAMES.FLASH,
|
leftIcon: getLeftIcon(ICON_NAMES.FLASH),
|
||||||
|
rightIcon: RIGHT_INFO_ICON,
|
||||||
};
|
};
|
||||||
|
|
||||||
return Object.keys(snaps).map((snapId) => {
|
return Object.keys(snaps).map((snapId) => {
|
||||||
@ -373,7 +407,8 @@ 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: ICON_NAMES.QUESTION,
|
leftIcon: getLeftIcon(ICON_NAMES.QUESTION),
|
||||||
|
rightIcon: null,
|
||||||
weight: 4,
|
weight: 4,
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import React, { useCallback, useState } from 'react';
|
import React, { useCallback, useState } from 'react';
|
||||||
import { PageContainerFooter } from '../../../../components/ui/page-container';
|
import { PageContainerFooter } from '../../../../components/ui/page-container';
|
||||||
import PermissionsConnectPermissionList from '../../../../components/app/permissions-connect-permission-list';
|
|
||||||
import { useI18nContext } from '../../../../hooks/useI18nContext';
|
import { useI18nContext } from '../../../../hooks/useI18nContext';
|
||||||
import SnapInstallWarning from '../../../../components/app/flask/snap-install-warning';
|
import SnapInstallWarning from '../../../../components/app/flask/snap-install-warning';
|
||||||
import Box from '../../../../components/ui/box/box';
|
import Box from '../../../../components/ui/box/box';
|
||||||
@ -21,6 +20,7 @@ import SnapAuthorship from '../../../../components/app/flask/snap-authorship';
|
|||||||
import { Text } from '../../../../components/component-library';
|
import { Text } from '../../../../components/component-library';
|
||||||
import { useOriginMetadata } from '../../../../hooks/useOriginMetadata';
|
import { useOriginMetadata } from '../../../../hooks/useOriginMetadata';
|
||||||
import { getSnapName } from '../../../../helpers/utils/util';
|
import { getSnapName } from '../../../../helpers/utils/util';
|
||||||
|
import SnapPermissionsList from '../../../../components/app/flask/snap-permissions-list';
|
||||||
|
|
||||||
export default function SnapInstall({
|
export default function SnapInstall({
|
||||||
request,
|
request,
|
||||||
@ -87,12 +87,16 @@ export default function SnapInstall({
|
|||||||
className="headers"
|
className="headers"
|
||||||
alignItems={AlignItems.center}
|
alignItems={AlignItems.center}
|
||||||
flexDirection={FLEX_DIRECTION.COLUMN}
|
flexDirection={FLEX_DIRECTION.COLUMN}
|
||||||
paddingLeft={4}
|
|
||||||
paddingRight={4}
|
|
||||||
>
|
>
|
||||||
|
<Box paddingLeft={4} paddingRight={4}>
|
||||||
<SnapAuthorship snapId={targetSubjectMetadata.origin} />
|
<SnapAuthorship snapId={targetSubjectMetadata.origin} />
|
||||||
|
</Box>
|
||||||
{!hasError && (
|
{!hasError && (
|
||||||
<Text padding={[4, 4, 0, 4]} variant={TextVariant.headingLg}>
|
<Text
|
||||||
|
variant={TextVariant.headingLg}
|
||||||
|
paddingTop={4}
|
||||||
|
paddingBottom={2}
|
||||||
|
>
|
||||||
{t('snapInstall')}
|
{t('snapInstall')}
|
||||||
</Text>
|
</Text>
|
||||||
)}
|
)}
|
||||||
@ -114,6 +118,8 @@ export default function SnapInstall({
|
|||||||
<Text
|
<Text
|
||||||
className="headers__permission-description"
|
className="headers__permission-description"
|
||||||
paddingBottom={4}
|
paddingBottom={4}
|
||||||
|
paddingLeft={4}
|
||||||
|
paddingRight={4}
|
||||||
textAlign={TEXT_ALIGN.CENTER}
|
textAlign={TEXT_ALIGN.CENTER}
|
||||||
>
|
>
|
||||||
{t('snapInstallRequestsPermission', [
|
{t('snapInstallRequestsPermission', [
|
||||||
@ -121,7 +127,7 @@ export default function SnapInstall({
|
|||||||
<b key="2">{snapName}</b>,
|
<b key="2">{snapName}</b>,
|
||||||
])}
|
])}
|
||||||
</Text>
|
</Text>
|
||||||
<PermissionsConnectPermissionList
|
<SnapPermissionsList
|
||||||
permissions={requestState.permissions || {}}
|
permissions={requestState.permissions || {}}
|
||||||
targetSubjectMetadata={targetSubjectMetadata}
|
targetSubjectMetadata={targetSubjectMetadata}
|
||||||
/>
|
/>
|
||||||
|
@ -19,7 +19,6 @@ import SnapAuthorship from '../../../../components/app/flask/snap-authorship';
|
|||||||
import Box from '../../../../components/ui/box';
|
import Box from '../../../../components/ui/box';
|
||||||
import SnapRemoveWarning from '../../../../components/app/flask/snap-remove-warning';
|
import SnapRemoveWarning from '../../../../components/app/flask/snap-remove-warning';
|
||||||
import ToggleButton from '../../../../components/ui/toggle-button';
|
import ToggleButton from '../../../../components/ui/toggle-button';
|
||||||
import PermissionsConnectPermissionList from '../../../../components/app/permissions-connect-permission-list/permissions-connect-permission-list';
|
|
||||||
import ConnectedSitesList from '../../../../components/app/connected-sites-list';
|
import ConnectedSitesList from '../../../../components/app/connected-sites-list';
|
||||||
import Tooltip from '../../../../components/ui/tooltip';
|
import Tooltip from '../../../../components/ui/tooltip';
|
||||||
import { SNAPS_LIST_ROUTE } from '../../../../helpers/constants/routes';
|
import { SNAPS_LIST_ROUTE } from '../../../../helpers/constants/routes';
|
||||||
@ -38,6 +37,7 @@ import {
|
|||||||
getTargetSubjectMetadata,
|
getTargetSubjectMetadata,
|
||||||
} from '../../../../selectors';
|
} from '../../../../selectors';
|
||||||
import { formatDate } from '../../../../helpers/utils/util';
|
import { formatDate } from '../../../../helpers/utils/util';
|
||||||
|
import SnapPermissionsList from '../../../../components/app/flask/snap-permissions-list';
|
||||||
|
|
||||||
function ViewSnap() {
|
function ViewSnap() {
|
||||||
const t = useI18nContext();
|
const t = useI18nContext();
|
||||||
@ -182,7 +182,7 @@ function ViewSnap() {
|
|||||||
{t('snapAccess', [snap.manifest.proposedName])}
|
{t('snapAccess', [snap.manifest.proposedName])}
|
||||||
</Typography>
|
</Typography>
|
||||||
<Box width={BLOCK_SIZES.FULL}>
|
<Box width={BLOCK_SIZES.FULL}>
|
||||||
<PermissionsConnectPermissionList
|
<SnapPermissionsList
|
||||||
permissions={permissions ?? {}}
|
permissions={permissions ?? {}}
|
||||||
targetSubjectMetadata={targetSubjectMetadata}
|
targetSubjectMetadata={targetSubjectMetadata}
|
||||||
/>
|
/>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user