Extracted some QR code modal components to external components

This commit is contained in:
Alejandro Celaya 2021-08-16 17:26:54 +02:00
parent 520e52595f
commit 5166340779
4 changed files with 53 additions and 23 deletions

View file

@ -1,12 +1,11 @@
import { FC, useMemo, useState } from 'react'; import { FC, useMemo, useState } from 'react';
import { Modal, DropdownItem, FormGroup, ModalBody, ModalHeader, Row, Button } from 'reactstrap'; import { Modal, FormGroup, ModalBody, ModalHeader, Row, Button } from 'reactstrap';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faFileDownload as downloadIcon } from '@fortawesome/free-solid-svg-icons'; import { faFileDownload as downloadIcon } from '@fortawesome/free-solid-svg-icons';
import { ExternalLink } from 'react-external-link'; import { ExternalLink } from 'react-external-link';
import classNames from 'classnames'; import classNames from 'classnames';
import { ShortUrlModalProps } from '../data'; import { ShortUrlModalProps } from '../data';
import { SelectedServer } from '../../servers/data'; import { SelectedServer } from '../../servers/data';
import { DropdownBtn } from '../../utils/DropdownBtn';
import { CopyToClipboardIcon } from '../../utils/CopyToClipboardIcon'; import { CopyToClipboardIcon } from '../../utils/CopyToClipboardIcon';
import { buildQrCodeUrl, QrCodeCapabilities, QrCodeFormat, QrErrorCorrection } from '../../utils/helpers/qrCodes'; import { buildQrCodeUrl, QrCodeCapabilities, QrCodeFormat, QrErrorCorrection } from '../../utils/helpers/qrCodes';
import { import {
@ -17,7 +16,9 @@ import {
} from '../../utils/helpers/features'; } from '../../utils/helpers/features';
import { ImageDownloader } from '../../common/services/ImageDownloader'; import { ImageDownloader } from '../../common/services/ImageDownloader';
import { Versions } from '../../utils/helpers/version'; import { Versions } from '../../utils/helpers/version';
import { QrFormatDropdown } from './qr-codes/QrFormatDropdown';
import './QrCodeModal.scss'; import './QrCodeModal.scss';
import { QrErrorCorrectionDropdown } from './qr-codes/QrErrorCorrectionDropdown';
interface QrCodeModalConnectProps extends ShortUrlModalProps { interface QrCodeModalConnectProps extends ShortUrlModalProps {
selectedServer: SelectedServer; selectedServer: SelectedServer;
@ -90,28 +91,12 @@ const QrCodeModal = (imageDownloader: ImageDownloader, ForServerVersion: FC<Vers
)} )}
{capabilities.svgIsSupported && ( {capabilities.svgIsSupported && (
<FormGroup className={capabilities.marginIsSupported && !capabilities.errorCorrectionIsSupported ? 'col-md-4' : 'col-md-6'}> <FormGroup className={capabilities.marginIsSupported && !capabilities.errorCorrectionIsSupported ? 'col-md-4' : 'col-md-6'}>
<DropdownBtn text={`Format (${format})`}> <QrFormatDropdown format={format} setFormat={setFormat} />
<DropdownItem active={format === 'png'} onClick={() => setFormat('png')}>PNG</DropdownItem>
<DropdownItem active={format === 'svg'} onClick={() => setFormat('svg')}>SVG</DropdownItem>
</DropdownBtn>
</FormGroup> </FormGroup>
)} )}
{capabilities.errorCorrectionIsSupported && ( {capabilities.errorCorrectionIsSupported && (
<FormGroup className="col-md-6"> <FormGroup className="col-md-6">
<DropdownBtn text={`Error correction (${errorCorrection})`}> <QrErrorCorrectionDropdown errorCorrection={errorCorrection} setErrorCorrection={setErrorCorrection} />
<DropdownItem active={errorCorrection === 'L'} onClick={() => setErrorCorrection('L')}>
<b>L</b>ow
</DropdownItem>
<DropdownItem active={errorCorrection === 'M'} onClick={() => setErrorCorrection('M')}>
<b>M</b>edium
</DropdownItem>
<DropdownItem active={errorCorrection === 'Q'} onClick={() => setErrorCorrection('Q')}>
<b>Q</b>uartile
</DropdownItem>
<DropdownItem active={errorCorrection === 'H'} onClick={() => setErrorCorrection('H')}>
<b>H</b>igh
</DropdownItem>
</DropdownBtn>
</FormGroup> </FormGroup>
)} )}
</Row> </Row>

View file

@ -0,0 +1,28 @@
import { FC } from 'react';
import { DropdownItem } from 'reactstrap';
import { DropdownBtn } from '../../../utils/DropdownBtn';
import { QrErrorCorrection } from '../../../utils/helpers/qrCodes';
interface QrErrorCorrectionDropdownProps {
errorCorrection: QrErrorCorrection;
setErrorCorrection: (errorCorrection: QrErrorCorrection) => void;
}
export const QrErrorCorrectionDropdown: FC<QrErrorCorrectionDropdownProps> = (
{ errorCorrection, setErrorCorrection },
) => (
<DropdownBtn text={`Error correction (${errorCorrection})`}>
<DropdownItem active={errorCorrection === 'L'} onClick={() => setErrorCorrection('L')}>
<b>L</b>ow
</DropdownItem>
<DropdownItem active={errorCorrection === 'M'} onClick={() => setErrorCorrection('M')}>
<b>M</b>edium
</DropdownItem>
<DropdownItem active={errorCorrection === 'Q'} onClick={() => setErrorCorrection('Q')}>
<b>Q</b>uartile
</DropdownItem>
<DropdownItem active={errorCorrection === 'H'} onClick={() => setErrorCorrection('H')}>
<b>H</b>igh
</DropdownItem>
</DropdownBtn>
);

View file

@ -0,0 +1,16 @@
import { FC } from 'react';
import { DropdownItem } from 'reactstrap';
import { DropdownBtn } from '../../../utils/DropdownBtn';
import { QrCodeFormat } from '../../../utils/helpers/qrCodes';
interface QrFormatDropdownProps {
format: QrCodeFormat;
setFormat: (format: QrCodeFormat) => void;
}
export const QrFormatDropdown: FC<QrFormatDropdownProps> = ({ format, setFormat }) => (
<DropdownBtn text={`Format (${format})`}>
<DropdownItem active={format === 'png'} onClick={() => setFormat('png')}>PNG</DropdownItem>
<DropdownItem active={format === 'svg'} onClick={() => setFormat('svg')}>SVG</DropdownItem>
</DropdownBtn>
);

View file

@ -6,9 +6,10 @@ import createQrCodeModal from '../../../src/short-urls/helpers/QrCodeModal';
import { ShortUrl } from '../../../src/short-urls/data'; import { ShortUrl } from '../../../src/short-urls/data';
import { ReachableServer } from '../../../src/servers/data'; import { ReachableServer } from '../../../src/servers/data';
import { CopyToClipboardIcon } from '../../../src/utils/CopyToClipboardIcon'; import { CopyToClipboardIcon } from '../../../src/utils/CopyToClipboardIcon';
import { DropdownBtn } from '../../../src/utils/DropdownBtn';
import { SemVer } from '../../../src/utils/helpers/version'; import { SemVer } from '../../../src/utils/helpers/version';
import { ImageDownloader } from '../../../src/common/services/ImageDownloader'; import { ImageDownloader } from '../../../src/common/services/ImageDownloader';
import { QrFormatDropdown } from '../../../src/short-urls/helpers/qr-codes/QrFormatDropdown';
import { QrErrorCorrectionDropdown } from '../../../src/short-urls/helpers/qr-codes/QrErrorCorrectionDropdown';
describe('<QrCodeModal />', () => { describe('<QrCodeModal />', () => {
let wrapper: ShallowWrapper; let wrapper: ShallowWrapper;
@ -95,10 +96,10 @@ describe('<QrCodeModal />', () => {
[ '2.8.0' as SemVer, 2, 'col-md-6' ], [ '2.8.0' as SemVer, 2, 'col-md-6' ],
])('shows expected components based on server version', (version, expectedAmountOfDropdowns, expectedRangeClass) => { ])('shows expected components based on server version', (version, expectedAmountOfDropdowns, expectedRangeClass) => {
const wrapper = createWrapper(version); const wrapper = createWrapper(version);
const dropdown = wrapper.find(DropdownBtn); const dropdownsLength = wrapper.find(QrFormatDropdown).length + wrapper.find(QrErrorCorrectionDropdown).length;
const firstCol = wrapper.find(Row).find(FormGroup).first(); const firstCol = wrapper.find(Row).find(FormGroup).first();
expect(dropdown).toHaveLength(expectedAmountOfDropdowns); expect(dropdownsLength).toEqual(expectedAmountOfDropdowns);
expect(firstCol.prop('className')).toEqual(expectedRangeClass); expect(firstCol.prop('className')).toEqual(expectedRangeClass);
}); });