diff --git a/CHANGELOG.md b/CHANGELOG.md
index 73f3bb1a..faf98cfa 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -19,6 +19,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
* Date filtering can be now selected through relative times (last 7 days, last 30 days, etc) or absolute dates using date pickers.
* Only the visits for last 30 days are loaded by default. You can change that at any moment if required.
+* [#355](https://github.com/shlinkio/shlink-web-client/issues/355) Improved home page, fixing also its scrolling behavior for mobile devices.
+
### Changed
* [#267](https://github.com/shlinkio/shlink-web-client/issues/267) Added some subtle but important improvements on UI/UX.
* [#352](https://github.com/shlinkio/shlink-web-client/issues/352) Moved from Scrutinizer to Codecov as the code coverage backend.
diff --git a/package-lock.json b/package-lock.json
index 9c87279e..40bb319c 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -23075,9 +23075,9 @@
"dev": true
},
"react-external-link": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/react-external-link/-/react-external-link-1.1.1.tgz",
- "integrity": "sha512-e2WnTWkg81cuqxmDfjOalliAE20+Y/uD+lserN4uuwkwu+ciGLB3BMz4m7GnXh2+TowIi4sLtCL7zr7aDnIaqA=="
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/react-external-link/-/react-external-link-1.2.0.tgz",
+ "integrity": "sha512-6Lm0pD6rxrvZGVrWIWda809cAtrIlM3fDsKh9y5bKEVpOI0FTO2nTnxaqEood8+rw3svHJgpJGN6lZHO69ZTAQ=="
},
"react-is": {
"version": "16.7.0",
diff --git a/package.json b/package.json
index e4e1524d..95928585 100644
--- a/package.json
+++ b/package.json
@@ -46,7 +46,7 @@
"react-copy-to-clipboard": "^5.0.2",
"react-datepicker": "^3.3.0",
"react-dom": "^17.0.1",
- "react-external-link": "^1.1.1",
+ "react-external-link": "^1.2.0",
"react-leaflet": "^3.0.2",
"react-moment": "^1.0.0",
"react-redux": "^7.2.2",
diff --git a/src/common/Home.scss b/src/common/Home.scss
index d82a49ce..775de88f 100644
--- a/src/common/Home.scss
+++ b/src/common/Home.scss
@@ -1,18 +1,41 @@
@import '../utils/base';
+@import '../utils/mixins/vertical-align';
.home {
- text-align: center;
- height: calc(100vh - #{$headerHeight} - #{($footer-height + $footer-margin)});
- display: flex;
- align-items: center;
- justify-content: center;
- flex-flow: column;
+ position: relative;
+ padding-top: 15px;
+
+ @media (min-width: $mdMin) {
+ padding-top: 0;
+ height: calc(100vh - #{$headerHeight} - #{($footer-height + $footer-margin)});
+ }
+}
+
+.home__logo {
+ @include vertical-align();
+}
+
+.home__main-card {
+ margin: 0 auto;
+ max-width: 720px;
+
+ @media (min-width: $mdMin) {
+ @include vertical-align();
+ }
}
.home__title {
+ text-align: center;
font-size: 1.75rem;
+ margin: 0;
@media (min-width: $mdMin) {
font-size: 2.2rem;
}
}
+
+.home__servers-container {
+ @media (min-width: $mdMin) {
+ border-left: 1px solid rgba(0, 0, 0, .125);
+ }
+}
diff --git a/src/common/Home.tsx b/src/common/Home.tsx
index 17e9e4b2..a72b1ee1 100644
--- a/src/common/Home.tsx
+++ b/src/common/Home.tsx
@@ -1,8 +1,11 @@
import { isEmpty, values } from 'ramda';
import { Link } from 'react-router-dom';
+import { Card, Row } from 'reactstrap';
+import { ExternalLink } from 'react-external-link';
import ServersListGroup from '../servers/ServersListGroup';
import './Home.scss';
import { ServersMap } from '../servers/data';
+import { ShlinkLogo } from './img/ShlinkLogo';
export interface HomeProps {
servers: ServersMap;
@@ -14,11 +17,32 @@ const Home = ({ servers }: HomeProps) => {
return (
-
Welcome to Shlink
-
- {hasServers && Please, select a server.}
- {!hasServers && Please, add a server.}
-
+
+
+
+
+
+
Welcome!
+
+
+ {!hasServers && (
+
+
This application will help you to manage your Shlink servers.
+
To start, please, add your first server.
+
+ You still don‘t have a Shlink server?
+ Learn how to get started.
+
+
+ )}
+
+
+
+
);
};
diff --git a/src/common/MainHeader.tsx b/src/common/MainHeader.tsx
index be06d9d0..4c213a7b 100644
--- a/src/common/MainHeader.tsx
+++ b/src/common/MainHeader.tsx
@@ -6,7 +6,7 @@ import { Collapse, Nav, Navbar, NavbarBrand, NavbarToggler, NavItem, NavLink } f
import classNames from 'classnames';
import { RouteComponentProps } from 'react-router';
import { useToggle } from '../utils/helpers/hooks';
-import shlinkLogo from './shlink-logo-white.png';
+import { ShlinkLogo } from './img/ShlinkLogo';
import './MainHeader.scss';
const MainHeader = (ServersDropdown: FC) => ({ location }: RouteComponentProps) => {
@@ -21,7 +21,7 @@ const MainHeader = (ServersDropdown: FC) => ({ location }: RouteComponentProps)
return (
-
Shlink
+ Shlink
diff --git a/src/common/img/ShlinkLogo.tsx b/src/common/img/ShlinkLogo.tsx
new file mode 100644
index 00000000..40094a67
--- /dev/null
+++ b/src/common/img/ShlinkLogo.tsx
@@ -0,0 +1,25 @@
+import { MAIN_COLOR } from '../../utils/theme';
+
+export interface ShlinkLogoProps {
+ color?: string;
+ className?: string;
+}
+
+export const ShlinkLogo = ({ color = MAIN_COLOR, className }: ShlinkLogoProps) => (
+
+);
diff --git a/src/common/shlink-logo-white.png b/src/common/shlink-logo-white.png
deleted file mode 100644
index 5590667b..00000000
Binary files a/src/common/shlink-logo-white.png and /dev/null differ
diff --git a/src/servers/Overview.tsx b/src/servers/Overview.tsx
index f6dd424e..892fe46e 100644
--- a/src/servers/Overview.tsx
+++ b/src/servers/Overview.tsx
@@ -1,6 +1,6 @@
import { FC, useEffect } from 'react';
import { Card, CardBody, CardHeader, CardText, CardTitle } from 'reactstrap';
-import { Link } from 'react-router-dom';
+import { Link, useHistory } from 'react-router-dom';
import { ShortUrlsListParams } from '../short-urls/reducers/shortUrlsListParams';
import { ShortUrlsList as ShortUrlsListState } from '../short-urls/reducers/shortUrlsList';
import { prettify } from '../utils/helpers/numbers';
@@ -40,6 +40,7 @@ export const Overview = (
const { loading: loadingTags } = tagsList;
const { loading: loadingVisits, visitsCount } = visitsOverview;
const serverId = isServerWithId(selectedServer) ? selectedServer.id : '';
+ const history = useHistory();
useEffect(() => {
listShortUrls({ itemsPerPage: 5, orderBy: { dateCreated: 'DESC' } });
@@ -95,7 +96,12 @@ export const Overview = (
See all »
-
+ history.push(`/server/${serverId}/list-short-urls/1?tag=${tag}`)}
+ />
>
diff --git a/src/servers/ServersListGroup.scss b/src/servers/ServersListGroup.scss
index 478fb19d..78457102 100644
--- a/src/servers/ServersListGroup.scss
+++ b/src/servers/ServersListGroup.scss
@@ -1,7 +1,12 @@
+@import '../utils/base';
@import '../utils/mixins/vertical-align';
+@import '../utils/mixins/thin-scroll';
-.servers-list__list-group {
+.servers-list__list-group.servers-list__list-group {
width: 100%;
+}
+
+.servers-list__list-group:not(.servers-list__list-group--embedded) {
max-width: 400px;
box-shadow: 0 .125rem .25rem rgba(0, 0, 0, .075);
}
@@ -12,8 +17,29 @@
padding: .75rem 2.5rem .75rem 1rem;
}
+.servers-list__server-item:hover {
+ background-color: $lightColor;
+}
+
.servers-list__server-item-icon {
@include vertical-align();
right: 1rem;
}
+
+.servers-list__list-group--embedded.servers-list__list-group--embedded {
+ border-radius: 0;
+ border-top: 1px solid rgba(0, 0, 0, .125);
+
+ @media (min-width: $mdMin) {
+ max-height: 220px;
+ overflow-x: auto;
+
+ @include thin-scroll();
+ }
+
+ .servers-list__server-item {
+ border: none;
+ border-bottom: 1px solid rgba(0, 0, 0, .125);
+ }
+}
diff --git a/src/servers/ServersListGroup.tsx b/src/servers/ServersListGroup.tsx
index ec0f1454..64b7c28c 100644
--- a/src/servers/ServersListGroup.tsx
+++ b/src/servers/ServersListGroup.tsx
@@ -1,6 +1,7 @@
import { FC } from 'react';
import { ListGroup, ListGroupItem } from 'reactstrap';
import { Link } from 'react-router-dom';
+import classNames from 'classnames';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faChevronRight as chevronIcon } from '@fortawesome/free-solid-svg-icons';
import { ServerWithId } from './data';
@@ -8,6 +9,7 @@ import './ServersListGroup.scss';
interface ServersListGroup {
servers: ServerWithId[];
+ embedded?: boolean;
}
const ServerListItem = ({ id, name }: { id: string; name: string }) => (
@@ -17,13 +19,13 @@ const ServerListItem = ({ id, name }: { id: string; name: string }) => (
);
-const ServersListGroup: FC = ({ servers, children }) => (
+const ServersListGroup: FC = ({ servers, children, embedded = false }) => (
<>
-
-
{children}
-
+ {children && {children}
}
{servers.length > 0 && (
-
+
{servers.map(({ id, name }) => )}
)}
diff --git a/src/short-urls/ShortUrlsList.tsx b/src/short-urls/ShortUrlsList.tsx
index 69287f81..485204dd 100644
--- a/src/short-urls/ShortUrlsList.tsx
+++ b/src/short-urls/ShortUrlsList.tsx
@@ -87,9 +87,8 @@ const ShortUrlsList = (ShortUrlsTable: FC) => boundToMercur
orderByColumn={orderByColumn}
renderOrderIcon={renderOrderIcon}
selectedServer={selectedServer}
- refreshList={refreshList}
- shortUrlsListParams={shortUrlsListParams}
shortUrlsList={shortUrlsList}
+ onTagClick={(tag) => refreshList({ tags: [ ...shortUrlsListParams.tags ?? [], tag ] })}
/>
>
);
diff --git a/src/short-urls/ShortUrlsTable.tsx b/src/short-urls/ShortUrlsTable.tsx
index 55351166..99e971a0 100644
--- a/src/short-urls/ShortUrlsTable.tsx
+++ b/src/short-urls/ShortUrlsTable.tsx
@@ -4,7 +4,7 @@ import classNames from 'classnames';
import { SelectedServer } from '../servers/data';
import { ShortUrlsList as ShortUrlsListState } from './reducers/shortUrlsList';
import { ShortUrlsRowProps } from './helpers/ShortUrlsRow';
-import { OrderableFields, ShortUrlsListParams } from './reducers/shortUrlsListParams';
+import { OrderableFields } from './reducers/shortUrlsListParams';
import './ShortUrlsTable.scss';
export interface ShortUrlsTableProps {
@@ -12,8 +12,7 @@ export interface ShortUrlsTableProps {
renderOrderIcon?: (column: OrderableFields) => ReactNode;
shortUrlsList: ShortUrlsListState;
selectedServer: SelectedServer;
- refreshList?: Function;
- shortUrlsListParams?: ShortUrlsListParams;
+ onTagClick?: (tag: string) => void;
className?: string;
}
@@ -21,8 +20,7 @@ export const ShortUrlsTable = (ShortUrlsRow: FC) => ({
orderByColumn,
renderOrderIcon,
shortUrlsList,
- refreshList,
- shortUrlsListParams,
+ onTagClick,
selectedServer,
className,
}: ShortUrlsTableProps) => {
@@ -54,8 +52,7 @@ export const ShortUrlsTable = (ShortUrlsRow: FC) => ({
key={shortUrl.shortUrl}
shortUrl={shortUrl}
selectedServer={selectedServer}
- refreshList={refreshList}
- shortUrlsListParams={shortUrlsListParams}
+ onTagClick={onTagClick}
/>
));
};
diff --git a/src/short-urls/helpers/ShortUrlsRow.tsx b/src/short-urls/helpers/ShortUrlsRow.tsx
index 7d7c6154..1399099b 100644
--- a/src/short-urls/helpers/ShortUrlsRow.tsx
+++ b/src/short-urls/helpers/ShortUrlsRow.tsx
@@ -5,7 +5,6 @@ import { ExternalLink } from 'react-external-link';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faCopy as copyIcon } from '@fortawesome/free-regular-svg-icons';
import CopyToClipboard from 'react-copy-to-clipboard';
-import { ShortUrlsListParams } from '../reducers/shortUrlsListParams';
import ColorGenerator from '../../utils/services/ColorGenerator';
import { StateFlagTimeout } from '../../utils/helpers/hooks';
import Tag from '../../tags/helpers/Tag';
@@ -16,8 +15,7 @@ import { ShortUrlsRowMenuProps } from './ShortUrlsRowMenu';
import './ShortUrlsRow.scss';
export interface ShortUrlsRowProps {
- refreshList?: Function;
- shortUrlsListParams?: ShortUrlsListParams;
+ onTagClick?: (tag: string) => void;
selectedServer: SelectedServer;
shortUrl: ShortUrl;
}
@@ -26,7 +24,7 @@ const ShortUrlsRow = (
ShortUrlsRowMenu: FC,
colorGenerator: ColorGenerator,
useStateFlagTimeout: StateFlagTimeout,
-) => ({ shortUrl, selectedServer, refreshList, shortUrlsListParams }: ShortUrlsRowProps) => {
+) => ({ shortUrl, selectedServer, onTagClick }: ShortUrlsRowProps) => {
const [ copiedToClipboard, setCopiedToClipboard ] = useStateFlagTimeout();
const [ active, setActive ] = useStateFlagTimeout(false, 500);
const isFirstRun = useRef(true);
@@ -36,14 +34,12 @@ const ShortUrlsRow = (
return No tags;
}
- const selectedTags = shortUrlsListParams?.tags ?? [];
-
return tags.map((tag) => (
refreshList?.({ tags: [ ...selectedTags, tag ] })}
+ onClick={() => onTagClick?.(tag)}
/>
));
};
diff --git a/src/utils/mixins/thin-scroll.scss b/src/utils/mixins/thin-scroll.scss
new file mode 100644
index 00000000..ae243490
--- /dev/null
+++ b/src/utils/mixins/thin-scroll.scss
@@ -0,0 +1,16 @@
+@mixin thin-scroll() {
+ /* Forefox scrollbar */
+ scrollbar-color: rgba(0, 0, 0, .2) #f5f5f5;
+ scrollbar-width: thin;
+
+ /* Chrome webkit scrollbar */
+ &::-webkit-scrollbar {
+ width: 6px;
+ background-color: #f5f5f5;
+ }
+
+ &::-webkit-scrollbar-thumb {
+ background-color: rgba(0, 0, 0, .2);
+ border-radius: .5rem;
+ }
+}
diff --git a/src/utils/theme/index.ts b/src/utils/theme/index.ts
new file mode 100644
index 00000000..a4b5f96b
--- /dev/null
+++ b/src/utils/theme/index.ts
@@ -0,0 +1,7 @@
+export const MAIN_COLOR = '#4696e5';
+
+export const MAIN_COLOR_ALPHA = 'rgba(70, 150, 229, 0.4)';
+
+export const HIGHLIGHTED_COLOR = '#F77F28';
+
+export const HIGHLIGHTED_COLOR_ALPHA = 'rgba(247, 127, 40, 0.4)';
diff --git a/src/visits/helpers/DefaultChart.tsx b/src/visits/helpers/DefaultChart.tsx
index 0753ad35..78d1863a 100644
--- a/src/visits/helpers/DefaultChart.tsx
+++ b/src/visits/helpers/DefaultChart.tsx
@@ -7,6 +7,7 @@ import { fillTheGaps } from '../../utils/helpers/visits';
import { Stats } from '../types';
import { prettify } from '../../utils/helpers/numbers';
import { pointerOnHover, renderDoughnutChartLabel, renderNonDoughnutChartLabel } from '../../utils/helpers/charts';
+import { HIGHLIGHTED_COLOR, HIGHLIGHTED_COLOR_ALPHA, MAIN_COLOR, MAIN_COLOR_ALPHA } from '../../utils/theme';
import './DefaultChart.scss';
export interface DefaultChartProps {
@@ -33,7 +34,7 @@ const generateGraphData = (
title,
label: highlightedData ? 'Non-selected' : 'Visits',
data,
- backgroundColor: isBarChart ? 'rgba(70, 150, 229, 0.4)' : [
+ backgroundColor: isBarChart ? MAIN_COLOR_ALPHA : [
'#97BBCD',
'#F7464A',
'#46BFBD',
@@ -46,15 +47,15 @@ const generateGraphData = (
'#DCDCDC',
'#463730',
],
- borderColor: isBarChart ? 'rgba(70, 150, 229, 1)' : 'white',
+ borderColor: isBarChart ? MAIN_COLOR : 'white',
borderWidth: 2,
},
highlightedData && {
title,
label: highlightedLabel ?? 'Selected',
data: highlightedData,
- backgroundColor: 'rgba(247, 127, 40, 0.4)',
- borderColor: '#F77F28',
+ backgroundColor: HIGHLIGHTED_COLOR_ALPHA,
+ borderColor: HIGHLIGHTED_COLOR,
borderWidth: 2,
},
].filter(Boolean) as ChartDataSets[],
diff --git a/src/visits/helpers/LineChartCard.tsx b/src/visits/helpers/LineChartCard.tsx
index 588f50ea..28f23a0c 100644
--- a/src/visits/helpers/LineChartCard.tsx
+++ b/src/visits/helpers/LineChartCard.tsx
@@ -19,6 +19,7 @@ import { rangeOf } from '../../utils/utils';
import ToggleSwitch from '../../utils/ToggleSwitch';
import { prettify } from '../../utils/helpers/numbers';
import { pointerOnHover, renderNonDoughnutChartLabel } from '../../utils/helpers/charts';
+import { HIGHLIGHTED_COLOR, MAIN_COLOR } from '../../utils/theme';
import './LineChartCard.scss';
interface LineChartCardProps {
@@ -173,8 +174,8 @@ const LineChartCard = (
const data: ChartData = {
labels,
datasets: [
- generateDataset(groupedVisits, 'Visits', '#4696e5'),
- highlightedVisits.length > 0 && generateDataset(groupedHighlighted, highlightedLabel, '#F77F28'),
+ generateDataset(groupedVisits, 'Visits', MAIN_COLOR),
+ highlightedVisits.length > 0 && generateDataset(groupedHighlighted, highlightedLabel, HIGHLIGHTED_COLOR),
].filter(Boolean) as ChartDataSets[],
};
const options: ChartOptions = {
diff --git a/test/common/Home.test.tsx b/test/common/Home.test.tsx
index 1f9c5a90..22a88cda 100644
--- a/test/common/Home.test.tsx
+++ b/test/common/Home.test.tsx
@@ -2,6 +2,7 @@ import { shallow, ShallowWrapper } from 'enzyme';
import { Mock } from 'ts-mockery';
import Home, { HomeProps } from '../../src/common/Home';
import { ServerWithId } from '../../src/servers/data';
+import { ShlinkLogo } from '../../src/common/img/ShlinkLogo';
describe('', () => {
let wrapped: ShallowWrapper;
@@ -19,21 +20,26 @@ describe('', () => {
afterEach(() => wrapped?.unmount());
- it('shows link to create server when no servers exist', () => {
+ it('renders logo and title', () => {
const wrapped = createComponent();
- expect(wrapped.find('Link')).toHaveLength(1);
+ expect(wrapped.find(ShlinkLogo)).toHaveLength(1);
+ expect(wrapped.find('.home__title')).toHaveLength(1);
});
- it('asks to select a server when servers exist', () => {
- const servers = {
- '1a': Mock.of({ name: 'foo', id: '1' }),
- '2b': Mock.of({ name: 'bar', id: '2' }),
- };
+ it.each([
+ [
+ {
+ '1a': Mock.of({ name: 'foo', id: '1' }),
+ '2b': Mock.of({ name: 'bar', id: '2' }),
+ },
+ 0,
+ ],
+ [{}, 3 ],
+ ])('shows link to create or set-up server only when no servers exist', (servers, expectedParagraphs) => {
const wrapped = createComponent({ servers });
- const span = wrapped.find('span');
+ const p = wrapped.find('p');
- expect(span).toHaveLength(1);
- expect(span.text()).toContain('Please, select a server.');
+ expect(p).toHaveLength(expectedParagraphs);
});
});
diff --git a/test/common/img/ShlinkLogo.test.tsx b/test/common/img/ShlinkLogo.test.tsx
new file mode 100644
index 00000000..6e4b6494
--- /dev/null
+++ b/test/common/img/ShlinkLogo.test.tsx
@@ -0,0 +1,34 @@
+import { shallow, ShallowWrapper } from 'enzyme';
+import { ShlinkLogo, ShlinkLogoProps } from '../../../src/common/img/ShlinkLogo';
+import { MAIN_COLOR } from '../../../src/utils/theme';
+
+describe('', () => {
+ let wrapper: ShallowWrapper;
+ const createWrapper = (props: ShlinkLogoProps) => {
+ wrapper = shallow();
+
+ return wrapper;
+ };
+
+ afterEach(() => wrapper?.unmount());
+
+ it.each([
+ [ undefined, MAIN_COLOR ],
+ [ 'red', 'red' ],
+ [ 'white', 'white' ],
+ ])('renders expected color', (color, expectedColor) => {
+ const wrapper = createWrapper({ color });
+
+ expect(wrapper.find('g').prop('fill')).toEqual(expectedColor);
+ });
+
+ it.each([
+ [ undefined, undefined ],
+ [ 'foo', 'foo' ],
+ [ 'bar', 'bar' ],
+ ])('renders expected class', (className, expectedClassName) => {
+ const wrapper = createWrapper({ className });
+
+ expect(wrapper.prop('className')).toEqual(expectedClassName);
+ });
+});
diff --git a/test/servers/ServersListGroup.test.tsx b/test/servers/ServersListGroup.test.tsx
index bab7c52d..9a6ad591 100644
--- a/test/servers/ServersListGroup.test.tsx
+++ b/test/servers/ServersListGroup.test.tsx
@@ -5,31 +5,58 @@ import ServersListGroup from '../../src/servers/ServersListGroup';
import { ServerWithId } from '../../src/servers/data';
describe('', () => {
+ const servers = [
+ Mock.of({ name: 'foo', id: '123' }),
+ Mock.of({ name: 'bar', id: '456' }),
+ ];
let wrapped: ShallowWrapper;
- const createComponent = (servers: ServerWithId[]) => {
- wrapped = shallow(The list of servers);
+ const createComponent = (params: { servers?: ServerWithId[]; withChildren?: boolean; embedded?: boolean }) => {
+ const { servers = [], withChildren = true, embedded } = params;
+
+ wrapped = shallow(
+
+ {withChildren ? 'The list of servers' : undefined}
+ ,
+ );
return wrapped;
};
afterEach(() => wrapped?.unmount());
- it('Renders title', () => {
- const wrapped = createComponent([]);
+ it('renders title', () => {
+ const wrapped = createComponent({});
const title = wrapped.find('h5');
expect(title).toHaveLength(1);
expect(title.text()).toEqual('The list of servers');
});
- it('shows servers list', () => {
- const servers = [
- Mock.of({ name: 'foo', id: '123' }),
- Mock.of({ name: 'bar', id: '456' }),
- ];
- const wrapped = createComponent(servers);
+ it('does not render title when children is not provided', () => {
+ const wrapped = createComponent({ withChildren: false });
+ const title = wrapped.find('h5');
- expect(wrapped.find(ListGroup)).toHaveLength(1);
+ expect(title).toHaveLength(0);
+ });
+
+ it.each([
+ [ servers ],
+ [[]],
+ ])('shows servers list', (servers) => {
+ const wrapped = createComponent({ servers });
+
+ expect(wrapped.find(ListGroup)).toHaveLength(servers.length ? 1 : 0);
expect(wrapped.find('ServerListItem')).toHaveLength(servers.length);
});
+
+ it.each([
+ [ true, 'servers-list__list-group servers-list__list-group--embedded' ],
+ [ false, 'servers-list__list-group' ],
+ [ undefined, 'servers-list__list-group' ],
+ ])('renders proper classes for embedded', (embedded, expectedClasses) => {
+ const wrapped = createComponent({ servers, embedded });
+ const listGroup = wrapped.find(ListGroup);
+
+ expect(listGroup.prop('className')).toEqual(expectedClasses);
+ });
});
diff --git a/test/short-urls/helpers/ShortUrlsRow.test.tsx b/test/short-urls/helpers/ShortUrlsRow.test.tsx
index e45640bc..c4f565a9 100644
--- a/test/short-urls/helpers/ShortUrlsRow.test.tsx
+++ b/test/short-urls/helpers/ShortUrlsRow.test.tsx
@@ -43,9 +43,7 @@ describe('', () => {
beforeEach(() => {
const ShortUrlsRow = createShortUrlsRow(ShortUrlsRowMenu, colorGenerator, useStateFlagTimeout);
- wrapper = shallow(
- ,
- );
+ wrapper = shallow();
});
afterEach(() => wrapper.unmount());
diff --git a/test/visits/helpers/DefaultChart.test.tsx b/test/visits/helpers/DefaultChart.test.tsx
index 9f0dee2b..49dd8069 100644
--- a/test/visits/helpers/DefaultChart.test.tsx
+++ b/test/visits/helpers/DefaultChart.test.tsx
@@ -3,6 +3,7 @@ import { Doughnut, HorizontalBar } from 'react-chartjs-2';
import { keys, values } from 'ramda';
import DefaultChart from '../../../src/visits/helpers/DefaultChart';
import { prettify } from '../../../src/utils/helpers/numbers';
+import { MAIN_COLOR, MAIN_COLOR_ALPHA } from '../../../src/utils/theme';
describe('', () => {
let wrapper: ShallowWrapper;
@@ -62,8 +63,8 @@ describe('', () => {
const { datasets: [{ backgroundColor, borderColor }] } = horizontal.prop('data') as any;
const { legend, legendCallback, scales } = horizontal.prop('options') ?? {};
- expect(backgroundColor).toEqual('rgba(70, 150, 229, 0.4)');
- expect(borderColor).toEqual('rgba(70, 150, 229, 1)');
+ expect(backgroundColor).toEqual(MAIN_COLOR_ALPHA);
+ expect(borderColor).toEqual(MAIN_COLOR);
expect(legend).toEqual({ display: false });
expect(legendCallback).toEqual(false);
expect(scales).toEqual({