mirror of
https://github.com/shlinkio/shlink-web-client.git
synced 2025-01-10 18:27:25 +03:00
Created Overview page as default page after connecting to a server
This commit is contained in:
parent
920effb4c6
commit
dba0ac6442
13 changed files with 73 additions and 6 deletions
|
@ -3,6 +3,7 @@ import {
|
|||
faLink as createIcon,
|
||||
faTags as tagsIcon,
|
||||
faPen as editIcon,
|
||||
faHome as overviewIcon,
|
||||
} from '@fortawesome/free-solid-svg-icons';
|
||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||
import { FC } from 'react';
|
||||
|
@ -48,6 +49,10 @@ const AsideMenu = (DeleteServerButton: FC<DeleteServerButtonProps>) => (
|
|||
return (
|
||||
<aside className={asideClass}>
|
||||
<nav className="nav flex-column aside-menu__nav">
|
||||
<AsideMenuItem to={buildPath('/overview')}>
|
||||
<FontAwesomeIcon icon={overviewIcon} />
|
||||
<span className="aside-menu__item-text">Overview</span>
|
||||
</AsideMenuItem>
|
||||
<AsideMenuItem to={buildPath('/list-short-urls/1')} isActive={shortUrlsIsActive}>
|
||||
<FontAwesomeIcon icon={listIcon} />
|
||||
<span className="aside-menu__item-text">List short URLs</span>
|
||||
|
|
|
@ -20,6 +20,7 @@ const MenuLayout = (
|
|||
ShortUrlVisits: FC,
|
||||
TagVisits: FC,
|
||||
ServerError: FC,
|
||||
Overview: FC,
|
||||
) => withSelectedServer(({ location, selectedServer }) => {
|
||||
const [ sidebarVisible, toggleSidebar, showSidebar, hideSidebar ] = useToggle();
|
||||
|
||||
|
@ -60,6 +61,7 @@ const MenuLayout = (
|
|||
<div className="col-lg-10 offset-lg-2 col-md-9 offset-md-3" onClick={() => hideSidebar()}>
|
||||
<div className="menu-layout__container">
|
||||
<Switch>
|
||||
<Route exact path="/server/:serverId/overview" component={Overview} />
|
||||
<Route exact path="/server/:serverId/list-short-urls/:page" component={ShortUrls} />
|
||||
<Route exact path="/server/:serverId/create-short-url" component={CreateShortUrl} />
|
||||
<Route exact path="/server/:serverId/short-code/:shortCode/visits" component={ShortUrlVisits} />
|
||||
|
|
|
@ -33,6 +33,7 @@ const provideServices = (bottle: Bottle, connect: ConnectDecorator, withRouter:
|
|||
'ShortUrlVisits',
|
||||
'TagVisits',
|
||||
'ServerError',
|
||||
'Overview',
|
||||
);
|
||||
bottle.decorator('MenuLayout', connect([ 'selectedServer', 'shortUrlsListParams' ], [ 'selectServer' ]));
|
||||
bottle.decorator('MenuLayout', withRouter);
|
||||
|
|
|
@ -39,7 +39,7 @@ const CreateServer = (ImportServersBtn: FC<ImportServersBtnProps>, useStateFlagT
|
|||
const id = uuid();
|
||||
|
||||
createServer({ ...serverData, id });
|
||||
push(`/server/${id}/list-short-urls/1`);
|
||||
push(`/server/${id}/overview`);
|
||||
};
|
||||
|
||||
return (
|
||||
|
|
|
@ -26,7 +26,7 @@ const DeleteServerModal = ({ server, toggle, isOpen, deleteServer, history }: De
|
|||
<p>Are you sure you want to remove <b>{server ? server.name : ''}</b>?</p>
|
||||
<p>
|
||||
<i>
|
||||
No data will be deleted, only the access to this server will be removed from this host.
|
||||
No data will be deleted, only the access to this server will be removed from this device.
|
||||
You can create it again at any moment.
|
||||
</i>
|
||||
</p>
|
||||
|
|
|
@ -18,7 +18,7 @@ export const EditServer = (ServerError: FC) => withSelectedServer<EditServerProp
|
|||
|
||||
const handleSubmit = (serverData: ServerData) => {
|
||||
editServer(selectedServer.id, serverData);
|
||||
push(`/server/${selectedServer.id}/list-short-urls/1`);
|
||||
push(`/server/${selectedServer.id}/overview`);
|
||||
};
|
||||
|
||||
return (
|
||||
|
|
50
src/servers/Overview.tsx
Normal file
50
src/servers/Overview.tsx
Normal file
|
@ -0,0 +1,50 @@
|
|||
import { useEffect } from 'react';
|
||||
import { Card, CardText, CardTitle } from 'reactstrap';
|
||||
import { ShortUrlsListParams } from '../short-urls/reducers/shortUrlsListParams';
|
||||
import { ShortUrlsList as ShortUrlsListState } from '../short-urls/reducers/shortUrlsList';
|
||||
import { prettify } from '../utils/helpers/numbers';
|
||||
import { TagsList } from '../tags/reducers/tagsList';
|
||||
|
||||
interface OverviewConnectProps {
|
||||
shortUrlsList: ShortUrlsListState;
|
||||
listShortUrls: (params: ShortUrlsListParams) => void;
|
||||
listTags: Function;
|
||||
tagsList: TagsList;
|
||||
}
|
||||
|
||||
export const Overview = ({ shortUrlsList, listShortUrls, listTags, tagsList }: OverviewConnectProps) => {
|
||||
const { loading, error, shortUrls } = shortUrlsList;
|
||||
const { loading: loadingTags } = tagsList;
|
||||
|
||||
useEffect(() => {
|
||||
listShortUrls({ itemsPerPage: 5 });
|
||||
listTags();
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div className="row">
|
||||
<div className="col-sm-4">
|
||||
<Card className="text-center mb-2 mb-sm-0" body>
|
||||
<CardTitle tag="h5">Visits</CardTitle>
|
||||
<CardText tag="h2">?</CardText>
|
||||
</Card>
|
||||
</div>
|
||||
<div className="col-sm-4">
|
||||
<Card className="text-center mb-2 mb-sm-0" body>
|
||||
<CardTitle tag="h5">Short URLs</CardTitle>
|
||||
<CardText tag="h2">
|
||||
{loading && !error && 'Loading...'}
|
||||
{error && !loading && 'Failed :('}
|
||||
{!error && !loading && prettify(shortUrls?.pagination.totalItems ?? 0)}
|
||||
</CardText>
|
||||
</Card>
|
||||
</div>
|
||||
<div className="col-sm-4">
|
||||
<Card className="text-center" body>
|
||||
<CardTitle tag="h5">Tags</CardTitle>
|
||||
<CardText tag="h2">{loadingTags ? 'Loading... ' : prettify(tagsList.tags.length)}</CardText>
|
||||
</Card>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
|
@ -23,7 +23,7 @@ const ServersDropdown = (serversExporter: ServersExporter) => ({ servers, select
|
|||
<DropdownItem
|
||||
key={id}
|
||||
tag={Link}
|
||||
to={`/server/${id}/list-short-urls/1`}
|
||||
to={`/server/${id}/overview`}
|
||||
active={isServerWithId(selectedServer) && selectedServer.id === id}
|
||||
>
|
||||
{name}
|
||||
|
|
|
@ -11,7 +11,7 @@ interface ServersListGroup {
|
|||
}
|
||||
|
||||
const ServerListItem = ({ id, name }: { id: string; name: string }) => (
|
||||
<ListGroupItem tag={Link} to={`/server/${id}/list-short-urls/1`} className="servers-list__server-item">
|
||||
<ListGroupItem tag={Link} to={`/server/${id}/overview`} className="servers-list__server-item">
|
||||
{name}
|
||||
<FontAwesomeIcon icon={chevronIcon} className="servers-list__server-item-icon" />
|
||||
</ListGroupItem>
|
||||
|
|
|
@ -13,6 +13,7 @@ import ForServerVersion from '../helpers/ForServerVersion';
|
|||
import { ServerError } from '../helpers/ServerError';
|
||||
import { ConnectDecorator } from '../../container/types';
|
||||
import { withoutSelectedServer } from '../helpers/withoutSelectedServer';
|
||||
import { Overview } from '../Overview';
|
||||
import ServersImporter from './ServersImporter';
|
||||
import ServersExporter from './ServersExporter';
|
||||
|
||||
|
@ -43,6 +44,12 @@ const provideServices = (bottle: Bottle, connect: ConnectDecorator, withRouter:
|
|||
bottle.serviceFactory('ServerError', ServerError, 'DeleteServerButton');
|
||||
bottle.decorator('ServerError', connect([ 'servers', 'selectedServer' ]));
|
||||
|
||||
bottle.serviceFactory('Overview', () => Overview);
|
||||
bottle.decorator('Overview', connect(
|
||||
[ 'shortUrlsList', 'tagsList' ],
|
||||
[ 'listShortUrls', 'listTags' ],
|
||||
));
|
||||
|
||||
// Services
|
||||
bottle.constant('csvjson', csvjson);
|
||||
bottle.constant('fileReaderFactory', () => new FileReader());
|
||||
|
|
|
@ -15,6 +15,7 @@ export type OrderableFields = keyof typeof SORTABLE_FIELDS;
|
|||
|
||||
export interface ShortUrlsListParams {
|
||||
page?: string;
|
||||
itemsPerPage?: number;
|
||||
tags?: string[];
|
||||
searchTerm?: string;
|
||||
startDate?: string;
|
||||
|
|
|
@ -36,6 +36,7 @@ export interface ShlinkTagsResponse {
|
|||
export interface ShlinkPaginator {
|
||||
currentPage: number;
|
||||
pagesCount: number;
|
||||
totalItems: number;
|
||||
}
|
||||
|
||||
export interface ShlinkVisits {
|
||||
|
|
|
@ -17,7 +17,7 @@ describe('<AsideMenu />', () => {
|
|||
it('contains links to different sections', () => {
|
||||
const links = wrapped.find('[to]');
|
||||
|
||||
expect(links).toHaveLength(4);
|
||||
expect(links).toHaveLength(5);
|
||||
links.forEach((link) => expect(link.prop('to')).toContain('abc123'));
|
||||
});
|
||||
|
||||
|
|
Loading…
Reference in a new issue