Moved 'add server' button inside servers dropdown

This commit is contained in:
Alejandro Celaya 2020-12-12 11:29:15 +01:00
parent bc82e7e7fd
commit d62edb2249
3 changed files with 20 additions and 16 deletions

View file

@ -1,4 +1,4 @@
import { faPlus as plusIcon, faChevronDown as arrowIcon, faCogs as cogsIcon } from '@fortawesome/free-solid-svg-icons'; import { faChevronDown as arrowIcon, faCogs as cogsIcon } from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { FC, useEffect } from 'react'; import { FC, useEffect } from 'react';
import { Link } from 'react-router-dom'; import { Link } from 'react-router-dom';
@ -15,7 +15,6 @@ const MainHeader = (ServersDropdown: FC) => ({ location }: RouteComponentProps)
useEffect(close, [ location ]); useEffect(close, [ location ]);
const createServerPath = '/server/create';
const settingsPath = '/settings'; const settingsPath = '/settings';
const toggleClass = classNames('main-header__toggle-icon', { 'main-header__toggle-icon--opened': isOpen }); const toggleClass = classNames('main-header__toggle-icon', { 'main-header__toggle-icon--opened': isOpen });
@ -32,15 +31,10 @@ const MainHeader = (ServersDropdown: FC) => ({ location }: RouteComponentProps)
<Collapse navbar isOpen={isOpen}> <Collapse navbar isOpen={isOpen}>
<Nav navbar className="ml-auto"> <Nav navbar className="ml-auto">
<NavItem> <NavItem>
<NavLink tag={Link} to={settingsPath} active={pathname === settingsPath}> <NavLink tag={Link} to={'/settings'} active={pathname === settingsPath}>
<FontAwesomeIcon icon={cogsIcon} />&nbsp; Settings <FontAwesomeIcon icon={cogsIcon} />&nbsp; Settings
</NavLink> </NavLink>
</NavItem> </NavItem>
<NavItem>
<NavLink tag={Link} to={createServerPath} active={pathname === createServerPath}>
<FontAwesomeIcon icon={plusIcon} />&nbsp; Add server
</NavLink>
</NavItem>
<ServersDropdown /> <ServersDropdown />
</Nav> </Nav>
</Collapse> </Collapse>

View file

@ -1,6 +1,8 @@
import { isEmpty, values } from 'ramda'; import { isEmpty, values } from 'ramda';
import { DropdownItem, DropdownMenu, DropdownToggle, UncontrolledDropdown } from 'reactstrap'; import { DropdownItem, DropdownMenu, DropdownToggle, UncontrolledDropdown } from 'reactstrap';
import { Link } from 'react-router-dom'; import { Link } from 'react-router-dom';
import { faPlus as plusIcon, faFileDownload as exportIcon, faServer as serverIcon } from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import ServersExporter from './services/ServersExporter'; import ServersExporter from './services/ServersExporter';
import { isServerWithId, SelectedServer, ServersMap } from './data'; import { isServerWithId, SelectedServer, ServersMap } from './data';
@ -11,10 +13,15 @@ export interface ServersDropdownProps {
const ServersDropdown = (serversExporter: ServersExporter) => ({ servers, selectedServer }: ServersDropdownProps) => { const ServersDropdown = (serversExporter: ServersExporter) => ({ servers, selectedServer }: ServersDropdownProps) => {
const serversList = values(servers); const serversList = values(servers);
const createServerItem = (
<DropdownItem tag={Link} to="/server/create">
<FontAwesomeIcon icon={plusIcon} /> <span className="ml-1">Add server</span>
</DropdownItem>
);
const renderServers = () => { const renderServers = () => {
if (isEmpty(serversList)) { if (isEmpty(serversList)) {
return <DropdownItem disabled><i>Add a server first...</i></DropdownItem>; return createServerItem;
} }
return ( return (
@ -30,8 +37,9 @@ const ServersDropdown = (serversExporter: ServersExporter) => ({ servers, select
</DropdownItem> </DropdownItem>
))} ))}
<DropdownItem divider /> <DropdownItem divider />
{createServerItem}
<DropdownItem className="servers-dropdown__export-item" onClick={async () => serversExporter.exportServers()}> <DropdownItem className="servers-dropdown__export-item" onClick={async () => serversExporter.exportServers()}>
Export servers <FontAwesomeIcon icon={exportIcon} /> <span className="ml-1">Export servers</span>
</DropdownItem> </DropdownItem>
</> </>
); );
@ -39,7 +47,9 @@ const ServersDropdown = (serversExporter: ServersExporter) => ({ servers, select
return ( return (
<UncontrolledDropdown nav inNavbar> <UncontrolledDropdown nav inNavbar>
<DropdownToggle nav caret>Servers</DropdownToggle> <DropdownToggle nav caret>
<FontAwesomeIcon icon={serverIcon} /> <span className="ml-1">Servers</span>
</DropdownToggle>
<DropdownMenu right>{renderServers()}</DropdownMenu> <DropdownMenu right>{renderServers()}</DropdownMenu>
</UncontrolledDropdown> </UncontrolledDropdown>
); );

View file

@ -22,8 +22,8 @@ describe('<ServersDropdown />', () => {
}); });
afterEach(() => wrapped.unmount()); afterEach(() => wrapped.unmount());
it('contains the list of servers, the divider and the export button', () => it('contains the list of servers, the divider, the create button and the export button', () =>
expect(wrapped.find(DropdownItem)).toHaveLength(values(servers).length + 2)); expect(wrapped.find(DropdownItem)).toHaveLength(values(servers).length + 3));
it('contains a toggle with proper title', () => it('contains a toggle with proper title', () =>
expect(wrapped.find(DropdownToggle)).toHaveLength(1)); expect(wrapped.find(DropdownToggle)).toHaveLength(1));
@ -35,14 +35,14 @@ describe('<ServersDropdown />', () => {
expect(items.filter('.servers-dropdown__export-item')).toHaveLength(1); expect(items.filter('.servers-dropdown__export-item')).toHaveLength(1);
}); });
it('shows a message when no servers exist yet', () => { it('shows only create link when no servers exist yet', () => {
wrapped = shallow( wrapped = shallow(
<ServersDropdown servers={{}} selectedServer={null} />, <ServersDropdown servers={{}} selectedServer={null} />,
); );
const item = wrapped.find(DropdownItem); const item = wrapped.find(DropdownItem);
expect(item).toHaveLength(1); expect(item).toHaveLength(1);
expect(item.prop('disabled')).toEqual(true); expect(item.prop('to')).toEqual('/server/create');
expect(item.find('i').text()).toEqual('Add a server first...'); expect(item.find('span').text()).toContain('Add server');
}); });
}); });