Ensured export servers btn is not displayed when there are no servers

This commit is contained in:
Alejandro Celaya 2021-10-22 19:03:12 +02:00
parent 478209f50d
commit ada5488a6c
3 changed files with 29 additions and 9 deletions

View file

@ -43,10 +43,12 @@ export const ManageServers = (
<Row className="mb-3"> <Row className="mb-3">
<div className="col-md-6 d-flex d-md-block mb-2 mb-md-0"> <div className="col-md-6 d-flex d-md-block mb-2 mb-md-0">
<ImportServersBtn className="flex-fill" onImportError={setErrorImporting} /> <ImportServersBtn className="flex-fill" onImportError={setErrorImporting}>Import servers</ImportServersBtn>
<Button outline className="ml-2 flex-fill" onClick={async () => serversExporter.exportServers()}> {allServers.length > 0 && (
<FontAwesomeIcon icon={exportIcon} fixedWidth /> Export servers <Button outline className="ml-2 flex-fill" onClick={async () => serversExporter.exportServers()}>
</Button> <FontAwesomeIcon icon={exportIcon} fixedWidth /> Export servers
</Button>
)}
</div> </div>
<div className="col-md-6 text-md-right d-flex d-md-block"> <div className="col-md-6 text-md-right d-flex d-md-block">
<Button outline color="primary" className="flex-fill" tag={Link} to="/server/create"> <Button outline color="primary" className="flex-fill" tag={Link} to="/server/create">

View file

@ -1,4 +1,4 @@
import { useRef, RefObject, ChangeEvent, MutableRefObject } from 'react'; import { useRef, RefObject, ChangeEvent, MutableRefObject, FC } from 'react';
import { Button, UncontrolledTooltip } from 'reactstrap'; import { Button, UncontrolledTooltip } from 'reactstrap';
import { faFileUpload as importIcon } from '@fortawesome/free-solid-svg-icons'; import { faFileUpload as importIcon } from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
@ -20,14 +20,15 @@ interface ImportServersBtnConnectProps extends ImportServersBtnProps {
fileRef: Ref<HTMLInputElement>; fileRef: Ref<HTMLInputElement>;
} }
const ImportServersBtn = ({ importServersFromFile }: ServersImporter) => ({ const ImportServersBtn = ({ importServersFromFile }: ServersImporter): FC<ImportServersBtnConnectProps> => ({
createServers, createServers,
fileRef, fileRef,
children,
onImport = () => {}, onImport = () => {},
onImportError = () => {}, onImportError = () => {},
tooltipPlacement = 'bottom', tooltipPlacement = 'bottom',
className = '', className = '',
}: ImportServersBtnConnectProps) => { }) => {
const ref = fileRef ?? useRef<HTMLInputElement>(); const ref = fileRef ?? useRef<HTMLInputElement>();
const onChange = async ({ target }: ChangeEvent<HTMLInputElement>) => const onChange = async ({ target }: ChangeEvent<HTMLInputElement>) =>
importServersFromFile(target.files?.[0]) importServersFromFile(target.files?.[0])
@ -42,7 +43,7 @@ const ImportServersBtn = ({ importServersFromFile }: ServersImporter) => ({
return ( return (
<> <>
<Button outline id="importBtn" className={className} onClick={() => ref.current?.click()}> <Button outline id="importBtn" className={className} onClick={() => ref.current?.click()}>
<FontAwesomeIcon icon={importIcon} fixedWidth /> Import from file <FontAwesomeIcon icon={importIcon} fixedWidth /> {children ?? 'Import from file'}
</Button> </Button>
<UncontrolledTooltip placement={tooltipPlacement} target="importBtn"> <UncontrolledTooltip placement={tooltipPlacement} target="importBtn">
You can create servers by importing a CSV file with columns <b>name</b>, <b>apiKey</b> and <b>url</b>. You can create servers by importing a CSV file with columns <b>name</b>, <b>apiKey</b> and <b>url</b>.

View file

@ -1,3 +1,4 @@
import { ReactNode } from 'react';
import { shallow, ShallowWrapper } from 'enzyme'; import { shallow, ShallowWrapper } from 'enzyme';
import { UncontrolledTooltip } from 'reactstrap'; import { UncontrolledTooltip } from 'reactstrap';
import { Mock } from 'ts-mockery'; import { Mock } from 'ts-mockery';
@ -16,12 +17,13 @@ describe('<ImportServersBtn />', () => {
current: Mock.of<HTMLInputElement>({ click }), current: Mock.of<HTMLInputElement>({ click }),
}; };
const ImportServersBtn = importServersBtnConstruct(serversImporterMock); const ImportServersBtn = importServersBtnConstruct(serversImporterMock);
const createWrapper = (className?: string) => { const createWrapper = (className?: string, children?: ReactNode) => {
wrapper = shallow( wrapper = shallow(
<ImportServersBtn <ImportServersBtn
createServers={createServersMock} createServers={createServersMock}
className={className} className={className}
fileRef={fileRef} fileRef={fileRef}
children={children}
onImport={onImportMock} onImport={onImportMock}
/>, />,
); );
@ -50,6 +52,21 @@ describe('<ImportServersBtn />', () => {
expect(wrapper.find('#importBtn').prop('className')).toEqual(expectedClassName); expect(wrapper.find('#importBtn').prop('className')).toEqual(expectedClassName);
}); });
it.each([
[ undefined, true ],
[ 'foo', false ],
[ 'bar', false ],
])('has expected text', (children, expectToHaveDefaultText) => {
const wrapper = createWrapper(undefined, children);
if (expectToHaveDefaultText) {
expect(wrapper.find('#importBtn').html()).toContain('Import from file');
} else {
expect(wrapper.find('#importBtn').html()).toContain(children);
expect(wrapper.find('#importBtn').html()).not.toContain('Import from file');
}
});
it('triggers click on file ref when button is clicked', () => { it('triggers click on file ref when button is clicked', () => {
const wrapper = createWrapper(); const wrapper = createWrapper();
const btn = wrapper.find('#importBtn'); const btn = wrapper.find('#importBtn');