Remove server-related items from side menu

This commit is contained in:
Alejandro Celaya 2023-07-15 13:14:49 +02:00
parent deca5b31e1
commit cbbb679dfc
7 changed files with 14 additions and 66 deletions

View file

@ -58,24 +58,6 @@
background-color: var(--brand-color); background-color: var(--brand-color);
} }
.aside-menu__item--divider {
border-bottom: 1px solid #eeeeee;
margin: 20px 0;
}
.aside-menu__item--danger {
color: $dangerColor;
}
.aside-menu__item--push {
margin-top: auto;
}
.aside-menu__item--danger:hover {
color: #ffffff;
background-color: $dangerColor;
}
.aside-menu__item-text { .aside-menu__item-text {
margin-left: 8px; margin-left: 8px;
} }

View file

@ -3,7 +3,6 @@ import {
faHome as overviewIcon, faHome as overviewIcon,
faLink as createIcon, faLink as createIcon,
faList as listIcon, faList as listIcon,
faPen as editIcon,
faTags as tagsIcon, faTags as tagsIcon,
} from '@fortawesome/free-solid-svg-icons'; } from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
@ -13,7 +12,6 @@ import type { NavLinkProps } from 'react-router-dom';
import { NavLink, useLocation } from 'react-router-dom'; import { NavLink, useLocation } from 'react-router-dom';
import type { SelectedServer } from '../servers/data'; import type { SelectedServer } from '../servers/data';
import { isServerWithId } from '../servers/data'; import { isServerWithId } from '../servers/data';
import type { DeleteServerButtonProps } from '../servers/DeleteServerButton';
import './AsideMenu.scss'; import './AsideMenu.scss';
export interface AsideMenuProps { export interface AsideMenuProps {
@ -36,9 +34,7 @@ const AsideMenuItem: FC<AsideMenuItemProps> = ({ children, to, className, ...res
</NavLink> </NavLink>
); );
export const AsideMenu = (DeleteServerButton: FC<DeleteServerButtonProps>) => ( export const AsideMenu: FC<AsideMenuProps> = ({ selectedServer, showOnMobile = false }) => {
{ selectedServer, showOnMobile = false }: AsideMenuProps,
) => {
const hasId = isServerWithId(selectedServer); const hasId = isServerWithId(selectedServer);
const serverId = hasId ? selectedServer.id : ''; const serverId = hasId ? selectedServer.id : '';
const { pathname } = useLocation(); const { pathname } = useLocation();
@ -73,17 +69,6 @@ export const AsideMenu = (DeleteServerButton: FC<DeleteServerButtonProps>) => (
<FontAwesomeIcon fixedWidth icon={domainsIcon} /> <FontAwesomeIcon fixedWidth icon={domainsIcon} />
<span className="aside-menu__item-text">Manage domains</span> <span className="aside-menu__item-text">Manage domains</span>
</AsideMenuItem> </AsideMenuItem>
<AsideMenuItem to={buildPath('/edit')} className="aside-menu__item--push">
<FontAwesomeIcon fixedWidth icon={editIcon} />
<span className="aside-menu__item-text">Edit this server</span>
</AsideMenuItem>
{hasId && (
<DeleteServerButton
className="aside-menu__item aside-menu__item--danger"
textClassName="aside-menu__item-text"
server={selectedServer}
/>
)}
</nav> </nav>
</aside> </aside>
); );

View file

@ -8,7 +8,7 @@ import { isReachableServer } from '../servers/data';
import { withSelectedServer } from '../servers/helpers/withSelectedServer'; import { withSelectedServer } from '../servers/helpers/withSelectedServer';
import { useFeature } from '../utils/helpers/features'; import { useFeature } from '../utils/helpers/features';
import { useSwipeable, useToggle } from '../utils/helpers/hooks'; import { useSwipeable, useToggle } from '../utils/helpers/hooks';
import type { AsideMenuProps } from './AsideMenu'; import { AsideMenu } from './AsideMenu';
import { NotFound } from './NotFound'; import { NotFound } from './NotFound';
import './MenuLayout.scss'; import './MenuLayout.scss';
@ -20,7 +20,6 @@ interface MenuLayoutProps {
export const MenuLayout = ( export const MenuLayout = (
TagsList: FC, TagsList: FC,
ShortUrlsList: FC, ShortUrlsList: FC,
AsideMenu: FC<AsideMenuProps>,
CreateShortUrl: FC, CreateShortUrl: FC,
ShortUrlVisits: FC, ShortUrlVisits: FC,
TagVisits: FC, TagVisits: FC,

View file

@ -1,7 +1,6 @@
import type Bottle from 'bottlejs'; import type Bottle from 'bottlejs';
import type { ConnectDecorator } from '../../container/types'; import type { ConnectDecorator } from '../../container/types';
import { withoutSelectedServer } from '../../servers/helpers/withoutSelectedServer'; import { withoutSelectedServer } from '../../servers/helpers/withoutSelectedServer';
import { AsideMenu } from '../AsideMenu';
import { ErrorHandler } from '../ErrorHandler'; import { ErrorHandler } from '../ErrorHandler';
import { Home } from '../Home'; import { Home } from '../Home';
import { MainHeader } from '../MainHeader'; import { MainHeader } from '../MainHeader';
@ -37,7 +36,6 @@ export const provideServices = (bottle: Bottle, connect: ConnectDecorator) => {
MenuLayout, MenuLayout,
'TagsList', 'TagsList',
'ShortUrlsList', 'ShortUrlsList',
'AsideMenu',
'CreateShortUrl', 'CreateShortUrl',
'ShortUrlVisits', 'ShortUrlVisits',
'TagVisits', 'TagVisits',
@ -51,8 +49,6 @@ export const provideServices = (bottle: Bottle, connect: ConnectDecorator) => {
); );
bottle.decorator('MenuLayout', connect(['selectedServer'], ['selectServer', 'sidebarPresent', 'sidebarNotPresent'])); bottle.decorator('MenuLayout', connect(['selectedServer'], ['selectServer', 'sidebarPresent', 'sidebarNotPresent']));
bottle.serviceFactory('AsideMenu', AsideMenu, 'DeleteServerButton');
bottle.serviceFactory('ShlinkVersionsContainer', () => ShlinkVersionsContainer); bottle.serviceFactory('ShlinkVersionsContainer', () => ShlinkVersionsContainer);
bottle.decorator('ShlinkVersionsContainer', connect(['selectedServer', 'sidebar'])); bottle.decorator('ShlinkVersionsContainer', connect(['selectedServer', 'sidebar']));

View file

@ -12,8 +12,6 @@ export const PRIMARY_DARK_COLOR = '#161b22';
export type Theme = 'dark' | 'light'; export type Theme = 'dark' | 'light';
export const changeThemeInMarkup = (theme: Theme) => export const changeThemeInMarkup = (theme: Theme) => document.querySelector('html')?.setAttribute('data-theme', theme);
document.getElementsByTagName('html')?.[0]?.setAttribute('data-theme', theme);
export const isDarkThemeEnabled = (): boolean => export const isDarkThemeEnabled = (): boolean => document.querySelector('html')?.getAttribute('data-theme') === 'dark';
document.getElementsByTagName('html')?.[0]?.getAttribute('data-theme') === 'dark';

View file

@ -1,13 +1,12 @@
import { render, screen } from '@testing-library/react'; import { render, screen } from '@testing-library/react';
import { fromPartial } from '@total-typescript/shoehorn'; import { fromPartial } from '@total-typescript/shoehorn';
import { MemoryRouter } from 'react-router'; import { MemoryRouter } from 'react-router';
import { AsideMenu as createAsideMenu } from '../../src/common/AsideMenu'; import { AsideMenu } from '../../src/common/AsideMenu';
describe('<AsideMenu />', () => { describe('<AsideMenu />', () => {
const AsideMenu = createAsideMenu(() => <>DeleteServerButton</>); const setUp = () => render(
const setUp = (id: string | false = 'abc123') => render(
<MemoryRouter> <MemoryRouter>
<AsideMenu selectedServer={fromPartial({ id: id || undefined, version: '2.8.0' })} /> <AsideMenu selectedServer={fromPartial({ id: 'abc123', version: '2.8.0' })} />
</MemoryRouter>, </MemoryRouter>,
); );
@ -17,20 +16,7 @@ describe('<AsideMenu />', () => {
const links = screen.getAllByRole('link'); const links = screen.getAllByRole('link');
expect.assertions(links.length + 1); expect.assertions(links.length + 1);
expect(links).toHaveLength(6); expect(links).toHaveLength(5);
links.forEach((link) => expect(link.getAttribute('href')).toContain('abc123')); links.forEach((link) => expect(link.getAttribute('href')).toContain('abc123'));
}); });
it.each([
['abc', true],
[false, false],
])('contains a button to delete server if appropriate', (id, shouldHaveBtn) => {
setUp(id as string | false);
if (shouldHaveBtn) {
expect(screen.getByText('DeleteServerButton')).toBeInTheDocument();
} else {
expect(screen.queryByText('DeleteServerButton')).not.toBeInTheDocument();
}
});
}); });

View file

@ -6,13 +6,15 @@ import { MenuLayout as createMenuLayout } from '../../src/common/MenuLayout';
import type { NonReachableServer, NotFoundServer, SelectedServer } from '../../src/servers/data'; import type { NonReachableServer, NotFoundServer, SelectedServer } from '../../src/servers/data';
import type { SemVer } from '../../src/utils/helpers/version'; import type { SemVer } from '../../src/utils/helpers/version';
vi.mock('react-router-dom', async () => ({ ...(await vi.importActual<any>('react-router-dom')), useParams: vi.fn() })); vi.mock('react-router-dom', async () => ({
...(await vi.importActual<any>('react-router-dom')),
useParams: vi.fn(),
}));
describe('<MenuLayout />', () => { describe('<MenuLayout />', () => {
const MenuLayout = createMenuLayout( const MenuLayout = createMenuLayout(
() => <>TagsList</>, () => <>TagsList</>,
() => <>ShortUrlsList</>, () => <>ShortUrlsList</>,
() => <>AsideMenu</>,
() => <>CreateShortUrl</>, () => <>CreateShortUrl</>,
() => <>ShortUrlVisits</>, () => <>ShortUrlVisits</>,
() => <>TagVisits</>, () => <>TagVisits</>,
@ -20,7 +22,7 @@ describe('<MenuLayout />', () => {
() => <>OrphanVisits</>, () => <>OrphanVisits</>,
() => <>NonOrphanVisits</>, () => <>NonOrphanVisits</>,
() => <>ServerError</>, () => <>ServerError</>,
() => <>Overview</>, () => <>OverviewRoute</>,
() => <>EditShortUrl</>, () => <>EditShortUrl</>,
() => <>ManageDomains</>, () => <>ManageDomains</>,
); );
@ -62,7 +64,7 @@ describe('<MenuLayout />', () => {
}); });
it.each([ it.each([
['3.0.0' as SemVer, '/overview', 'Overview'], ['3.0.0' as SemVer, '/overview', 'OverviewRoute'],
['3.0.0' as SemVer, '/list-short-urls/1', 'ShortUrlsList'], ['3.0.0' as SemVer, '/list-short-urls/1', 'ShortUrlsList'],
['3.0.0' as SemVer, '/create-short-url', 'CreateShortUrl'], ['3.0.0' as SemVer, '/create-short-url', 'CreateShortUrl'],
['3.0.0' as SemVer, '/short-code/abc123/visits/foo', 'ShortUrlVisits'], ['3.0.0' as SemVer, '/short-code/abc123/visits/foo', 'ShortUrlVisits'],