mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-12-23 01:39:44 +01:00
[MMI] adds the jwt-url-form component (#18198)
* MMI adds the Jwt dropdown * MMI prettier * review fixes * adds the component * adds tests and story file * lint & prettier fix * prettier fix * prettier and clean up * prettier and clean up
This commit is contained in:
parent
c59e2b4d44
commit
033b776c0e
11
app/_locales/en/messages.json
generated
11
app/_locales/en/messages.json
generated
@ -257,6 +257,9 @@
|
|||||||
"message": "This network connection relies on third parties. This connection may be less reliable or enable third-parties to track activity. $1",
|
"message": "This network connection relies on third parties. This connection may be less reliable or enable third-parties to track activity. $1",
|
||||||
"description": "$1 is Learn more link"
|
"description": "$1 is Learn more link"
|
||||||
},
|
},
|
||||||
|
"addNewToken": {
|
||||||
|
"message": "Add new token"
|
||||||
|
},
|
||||||
"addSuggestedTokens": {
|
"addSuggestedTokens": {
|
||||||
"message": "Add suggested tokens"
|
"message": "Add suggested tokens"
|
||||||
},
|
},
|
||||||
@ -1370,6 +1373,9 @@
|
|||||||
"message": "File import not working? Click here!",
|
"message": "File import not working? Click here!",
|
||||||
"description": "Helps user import their account from a JSON file"
|
"description": "Helps user import their account from a JSON file"
|
||||||
},
|
},
|
||||||
|
"fileTooBig": {
|
||||||
|
"message": "The dropped file is too big."
|
||||||
|
},
|
||||||
"flaskSnapSettingsCardButtonCta": {
|
"flaskSnapSettingsCardButtonCta": {
|
||||||
"message": "See details",
|
"message": "See details",
|
||||||
"description": "Call to action a user can take to see more information about the snap that is installed"
|
"description": "Call to action a user can take to see more information about the snap that is installed"
|
||||||
@ -3331,6 +3337,9 @@
|
|||||||
"selectHdPath": {
|
"selectHdPath": {
|
||||||
"message": "Select HD path"
|
"message": "Select HD path"
|
||||||
},
|
},
|
||||||
|
"selectJWT": {
|
||||||
|
"message": "Select token"
|
||||||
|
},
|
||||||
"selectNFTPrivacyPreference": {
|
"selectNFTPrivacyPreference": {
|
||||||
"message": "Turn on NFT detection in Settings"
|
"message": "Turn on NFT detection in Settings"
|
||||||
},
|
},
|
||||||
@ -4003,7 +4012,7 @@
|
|||||||
"message": "Select a quote"
|
"message": "Select a quote"
|
||||||
},
|
},
|
||||||
"swapSelectAToken": {
|
"swapSelectAToken": {
|
||||||
"message": "Select a token"
|
"message": "Select token"
|
||||||
},
|
},
|
||||||
"swapSelectQuotePopoverDescription": {
|
"swapSelectQuotePopoverDescription": {
|
||||||
"message": "Below are all the quotes gathered from multiple liquidity sources."
|
"message": "Below are all the quotes gathered from multiple liquidity sources."
|
||||||
|
@ -0,0 +1,46 @@
|
|||||||
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
|
exports[`JwtUrlForm shows JWT text area when no jwt token exists 1`] = `
|
||||||
|
<div>
|
||||||
|
<div
|
||||||
|
class="box jwt-url-form box--margin-bottom-8 box--display-flex box--flex-direction-row box--align-items-flex-start"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="box jwt-url-form__jwt-container box--margin-bottom-6 box--flex-direction-row"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="box box--flex-direction-row"
|
||||||
|
>
|
||||||
|
<p
|
||||||
|
class="box mm-text jwt-url-form__instruction mm-text--body-md mm-text--color-text-default box--flex-direction-row"
|
||||||
|
>
|
||||||
|
input text
|
||||||
|
</p>
|
||||||
|
<textarea
|
||||||
|
bordercolor="border-default"
|
||||||
|
class="jwt-url-form__input-jwt"
|
||||||
|
data-testid="jwt-input"
|
||||||
|
id="jwt-box"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="box jwt-url-form__jwt-apiUrlInput box--flex-direction-row"
|
||||||
|
>
|
||||||
|
<p
|
||||||
|
class="box mm-text jwt-url-form__instruction mm-text--body-md mm-text--color-text-default box--flex-direction-row"
|
||||||
|
/>
|
||||||
|
<div
|
||||||
|
class="box box--flex-direction-row"
|
||||||
|
>
|
||||||
|
<input
|
||||||
|
class="jwt-url-form__input"
|
||||||
|
data-testid="jwt-api-url-input"
|
||||||
|
id="api-url-box"
|
||||||
|
value="url"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`;
|
1
ui/components/institutional/jwt-url-form/index.js
Normal file
1
ui/components/institutional/jwt-url-form/index.js
Normal file
@ -0,0 +1 @@
|
|||||||
|
export { default } from './jwt-url-form';
|
128
ui/components/institutional/jwt-url-form/jwt-url-form.js
Normal file
128
ui/components/institutional/jwt-url-form/jwt-url-form.js
Normal file
@ -0,0 +1,128 @@
|
|||||||
|
import React, { useState, useRef } from 'react';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import { useI18nContext } from '../../../hooks/useI18nContext';
|
||||||
|
import {
|
||||||
|
AlignItems,
|
||||||
|
DISPLAY,
|
||||||
|
BorderColor,
|
||||||
|
} from '../../../helpers/constants/design-system';
|
||||||
|
import { Text } from '../../component-library';
|
||||||
|
import JwtDropdown from '../jwt-dropdown';
|
||||||
|
import Button from '../../ui/button';
|
||||||
|
import Box from '../../ui/box';
|
||||||
|
|
||||||
|
const JwtUrlForm = (props) => {
|
||||||
|
const t = useI18nContext();
|
||||||
|
const inputRef = useRef();
|
||||||
|
const [addNewTokenClicked, setAddNewTokenClicked] = useState(false);
|
||||||
|
const [fileTooBigError, setFileTooBigError] = useState();
|
||||||
|
|
||||||
|
const renderJWTInput = () => {
|
||||||
|
const showAddNewToken = addNewTokenClicked;
|
||||||
|
const showJwtDropdown = props.jwtList.length >= 1;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Box className="jwt-url-form__jwt-container" marginBottom={6}>
|
||||||
|
{showJwtDropdown && (
|
||||||
|
<JwtDropdown
|
||||||
|
data-testid="jwt-dropdown"
|
||||||
|
currentJwt={props.currentJwt ? props.currentJwt : props.jwtList[0]}
|
||||||
|
jwtList={props.jwtList}
|
||||||
|
onChange={(value) => {
|
||||||
|
props.onJwtChange(value);
|
||||||
|
setFileTooBigError(false);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
{showJwtDropdown && !showAddNewToken && (
|
||||||
|
<Box
|
||||||
|
className="jwt-url-form__btn__container"
|
||||||
|
display={DISPLAY.FLEX}
|
||||||
|
alignItems={AlignItems.center}
|
||||||
|
marginTop={2}
|
||||||
|
>
|
||||||
|
<Text>{t('or')}</Text>
|
||||||
|
<Button
|
||||||
|
type="secondary"
|
||||||
|
medium="true"
|
||||||
|
onClick={() => {
|
||||||
|
props.onJwtChange('');
|
||||||
|
setAddNewTokenClicked(true);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Text>{t('addNewToken')}</Text>
|
||||||
|
</Button>
|
||||||
|
</Box>
|
||||||
|
)}
|
||||||
|
{(!showJwtDropdown || showAddNewToken) && (
|
||||||
|
<Box>
|
||||||
|
<Text className="jwt-url-form__instruction">
|
||||||
|
{props.jwtInputText}
|
||||||
|
</Text>
|
||||||
|
{fileTooBigError && (
|
||||||
|
<span className="error">
|
||||||
|
<Text>{t('fileTooBig')}</Text>
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
<textarea
|
||||||
|
className="jwt-url-form__input-jwt"
|
||||||
|
data-testid="jwt-input"
|
||||||
|
borderColor={BorderColor.borderDefault}
|
||||||
|
id="jwt-box"
|
||||||
|
onChange={(e) => {
|
||||||
|
props.onJwtChange(e.target.value);
|
||||||
|
setFileTooBigError(false);
|
||||||
|
}}
|
||||||
|
ref={inputRef.current}
|
||||||
|
value={props.currentJwt}
|
||||||
|
autoFocus
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
)}
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const renderAPIURLInput = () => {
|
||||||
|
return (
|
||||||
|
<Box className="jwt-url-form__jwt-apiUrlInput">
|
||||||
|
<Text className="jwt-url-form__instruction">{props.urlInputText}</Text>
|
||||||
|
<Box>
|
||||||
|
<input
|
||||||
|
className="jwt-url-form__input"
|
||||||
|
id="api-url-box"
|
||||||
|
data-testid="jwt-api-url-input"
|
||||||
|
onChange={(e) => {
|
||||||
|
props.onUrlChange(e.target.value);
|
||||||
|
}}
|
||||||
|
value={props.apiUrl}
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Box
|
||||||
|
className="jwt-url-form"
|
||||||
|
display={DISPLAY.FLEX}
|
||||||
|
alignItems={AlignItems.flexStart}
|
||||||
|
marginBottom={8}
|
||||||
|
>
|
||||||
|
{renderJWTInput()}
|
||||||
|
{renderAPIURLInput()}
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
JwtUrlForm.propTypes = {
|
||||||
|
jwtList: PropTypes.array,
|
||||||
|
currentJwt: PropTypes.string,
|
||||||
|
onJwtChange: PropTypes.func,
|
||||||
|
jwtInputText: PropTypes.string,
|
||||||
|
apiUrl: PropTypes.string,
|
||||||
|
urlInputText: PropTypes.string,
|
||||||
|
onUrlChange: PropTypes.func,
|
||||||
|
};
|
||||||
|
|
||||||
|
export default JwtUrlForm;
|
58
ui/components/institutional/jwt-url-form/jwt-url-form.scss
Normal file
58
ui/components/institutional/jwt-url-form/jwt-url-form.scss
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
.jwt-url-form {
|
||||||
|
flex-flow: column;
|
||||||
|
|
||||||
|
&__jwt-container {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__jwt-apiUrlInput {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__btn__container {
|
||||||
|
flex-flow: column;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
& > span {
|
||||||
|
padding-bottom: 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__instruction {
|
||||||
|
@include Paragraph;
|
||||||
|
|
||||||
|
align-self: flex-start;
|
||||||
|
display: block;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__input {
|
||||||
|
@include Paragraph;
|
||||||
|
|
||||||
|
height: 54px;
|
||||||
|
width: 100%;
|
||||||
|
border-radius: 4px;
|
||||||
|
background-color: var(--color-background-default);
|
||||||
|
margin-top: 16px;
|
||||||
|
padding: 0 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__input-jwt-container {
|
||||||
|
display: flex;
|
||||||
|
flex-flow: column;
|
||||||
|
align-items: center;
|
||||||
|
width: 100%;
|
||||||
|
margin-top: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__input-jwt {
|
||||||
|
@include Paragraph;
|
||||||
|
|
||||||
|
height: 154px;
|
||||||
|
width: 100%;
|
||||||
|
border-radius: 4px;
|
||||||
|
background-color: var(--color-background-default);
|
||||||
|
color: var(--color-text-default);
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,24 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import JwtUrlForm from '.';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
title: 'Components/Institutional/JwtUrlForm',
|
||||||
|
component: JwtUrlForm,
|
||||||
|
args: {
|
||||||
|
jwtList: ['jwt1', 'jwt2', 'jwt3'],
|
||||||
|
currentJwt: 'jwt1',
|
||||||
|
urlInputText: 'url',
|
||||||
|
apiUrl: 'https://apiurl.io/v1',
|
||||||
|
jwtInputText: 'some input text',
|
||||||
|
onJwtChange: () => {
|
||||||
|
/**/
|
||||||
|
},
|
||||||
|
onUrlChange: () => {
|
||||||
|
/**/
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export const DefaultStory = (args) => <JwtUrlForm {...args} />;
|
||||||
|
|
||||||
|
DefaultStory.storyName = 'JwtUrlForm';
|
@ -0,0 +1,77 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import sinon from 'sinon';
|
||||||
|
import { fireEvent, screen } from '@testing-library/react';
|
||||||
|
import configureMockStore from 'redux-mock-store';
|
||||||
|
import { renderWithProvider } from '../../../../test/lib/render-helpers';
|
||||||
|
import JwtUrlForm from './jwt-url-form';
|
||||||
|
|
||||||
|
describe('JwtUrlForm', function () {
|
||||||
|
const mockStore = {
|
||||||
|
metamask: {
|
||||||
|
provider: {
|
||||||
|
type: 'test',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const store = configureMockStore()(mockStore);
|
||||||
|
|
||||||
|
const props = {
|
||||||
|
jwtList: ['jwt1'],
|
||||||
|
currentJwt: 'jwt1',
|
||||||
|
onJwtChange: sinon.spy(),
|
||||||
|
jwtInputText: 'input text',
|
||||||
|
apiUrl: 'url',
|
||||||
|
urlInputText: '',
|
||||||
|
onUrlChange: sinon.spy(),
|
||||||
|
};
|
||||||
|
|
||||||
|
it('opens JWT Url Form without input for new JWT', () => {
|
||||||
|
const { container, getByText } = renderWithProvider(
|
||||||
|
<JwtUrlForm {...props} />,
|
||||||
|
store,
|
||||||
|
);
|
||||||
|
|
||||||
|
const btn = container.querySelector(
|
||||||
|
'.jwt-url-form__btn__container .btn-secondary',
|
||||||
|
);
|
||||||
|
expect(btn).toHaveClass('button');
|
||||||
|
expect(getByText('Add new token')).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('shows JWT textarea with provided input text', () => {
|
||||||
|
const { container } = renderWithProvider(<JwtUrlForm {...props} />, store);
|
||||||
|
|
||||||
|
const btn = container.querySelector(
|
||||||
|
'.jwt-url-form__btn__container .btn-secondary',
|
||||||
|
);
|
||||||
|
fireEvent.click(btn);
|
||||||
|
expect(screen.getByText('input text')).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('goes through the api url input', () => {
|
||||||
|
const { queryByTestId } = renderWithProvider(
|
||||||
|
<JwtUrlForm {...props} />,
|
||||||
|
store,
|
||||||
|
);
|
||||||
|
|
||||||
|
const apiUrlinput = queryByTestId('jwt-api-url-input');
|
||||||
|
fireEvent.change(apiUrlinput, { target: { value: 'url' } });
|
||||||
|
expect(apiUrlinput.value).toBe('url');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('shows JWT text area when no jwt token exists', () => {
|
||||||
|
const customProps = {
|
||||||
|
...props,
|
||||||
|
currentJwt: '',
|
||||||
|
jwtList: [],
|
||||||
|
};
|
||||||
|
|
||||||
|
const { container } = renderWithProvider(
|
||||||
|
<JwtUrlForm {...customProps} />,
|
||||||
|
store,
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(container).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
});
|
Loading…
Reference in New Issue
Block a user