mirror of
https://github.com/shlinkio/shlink-web-client.git
synced 2025-12-11 18:41:12 -06:00
Added new card in overview to display orphan visits
This commit is contained in:
parent
3c53f7d0fc
commit
5a373fd7ae
@ -46,6 +46,7 @@ export interface ShlinkVisits {
|
|||||||
|
|
||||||
export interface ShlinkVisitsOverview {
|
export interface ShlinkVisitsOverview {
|
||||||
visitsCount: number;
|
visitsCount: number;
|
||||||
|
orphanVisitsCount?: number; // Optional only for versions older than 2.6.0
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ShlinkVisitsParams {
|
export interface ShlinkVisitsParams {
|
||||||
|
|||||||
@ -38,7 +38,7 @@ export const Overview = (
|
|||||||
}: OverviewConnectProps) => {
|
}: OverviewConnectProps) => {
|
||||||
const { loading, shortUrls } = shortUrlsList;
|
const { loading, shortUrls } = shortUrlsList;
|
||||||
const { loading: loadingTags } = tagsList;
|
const { loading: loadingTags } = tagsList;
|
||||||
const { loading: loadingVisits, visitsCount } = visitsOverview;
|
const { loading: loadingVisits, visitsCount, orphanVisitsCount } = visitsOverview;
|
||||||
const serverId = isServerWithId(selectedServer) ? selectedServer.id : '';
|
const serverId = isServerWithId(selectedServer) ? selectedServer.id : '';
|
||||||
const history = useHistory();
|
const history = useHistory();
|
||||||
|
|
||||||
@ -51,7 +51,7 @@ export const Overview = (
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="row mb-3">
|
<div className="row mb-3">
|
||||||
<div className="col-md-6 col-lg-4">
|
<div className="col-md-6 col-xl-3">
|
||||||
<Card className="overview__card mb-2" body>
|
<Card className="overview__card mb-2" body>
|
||||||
<CardTitle tag="h5" className="overview__card-title">Visits</CardTitle>
|
<CardTitle tag="h5" className="overview__card-title">Visits</CardTitle>
|
||||||
<CardText tag="h2">
|
<CardText tag="h2">
|
||||||
@ -64,7 +64,20 @@ export const Overview = (
|
|||||||
</CardText>
|
</CardText>
|
||||||
</Card>
|
</Card>
|
||||||
</div>
|
</div>
|
||||||
<div className="col-md-6 col-lg-4">
|
<div className="col-md-6 col-xl-3">
|
||||||
|
<Card className="overview__card mb-2" body>
|
||||||
|
<CardTitle tag="h5" className="overview__card-title">Orphan visits</CardTitle>
|
||||||
|
<CardText tag="h2">
|
||||||
|
<ForServerVersion minVersion="2.6.0">
|
||||||
|
{loadingVisits ? 'Loading...' : prettify(orphanVisitsCount ?? 0)}
|
||||||
|
</ForServerVersion>
|
||||||
|
<ForServerVersion maxVersion="2.5.*">
|
||||||
|
<small className="text-muted"><i>Shlink 2.6 is needed</i></small>
|
||||||
|
</ForServerVersion>
|
||||||
|
</CardText>
|
||||||
|
</Card>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-6 col-xl-3">
|
||||||
<Card className="overview__card mb-2" body>
|
<Card className="overview__card mb-2" body>
|
||||||
<CardTitle tag="h5" className="overview__card-title">Short URLs</CardTitle>
|
<CardTitle tag="h5" className="overview__card-title">Short URLs</CardTitle>
|
||||||
<CardText tag="h2">
|
<CardText tag="h2">
|
||||||
@ -72,7 +85,7 @@ export const Overview = (
|
|||||||
</CardText>
|
</CardText>
|
||||||
</Card>
|
</Card>
|
||||||
</div>
|
</div>
|
||||||
<div className="col-md-12 col-lg-4">
|
<div className="col-md-6 col-xl-3">
|
||||||
<Card className="overview__card mb-2" body>
|
<Card className="overview__card mb-2" body>
|
||||||
<CardTitle tag="h5" className="overview__card-title">Tags</CardTitle>
|
<CardTitle tag="h5" className="overview__card-title">Tags</CardTitle>
|
||||||
<CardText tag="h2">{loadingTags ? 'Loading...' : prettify(tagsList.tags.length)}</CardText>
|
<CardText tag="h2">{loadingTags ? 'Loading...' : prettify(tagsList.tags.length)}</CardText>
|
||||||
|
|||||||
@ -13,6 +13,7 @@ export const GET_OVERVIEW = 'shlink/visitsOverview/GET_OVERVIEW';
|
|||||||
|
|
||||||
export interface VisitsOverview {
|
export interface VisitsOverview {
|
||||||
visitsCount: number;
|
visitsCount: number;
|
||||||
|
orphanVisitsCount?: number;
|
||||||
loading: boolean;
|
loading: boolean;
|
||||||
error: boolean;
|
error: boolean;
|
||||||
}
|
}
|
||||||
@ -21,6 +22,7 @@ export type GetVisitsOverviewAction = ShlinkVisitsOverview & Action<string>;
|
|||||||
|
|
||||||
const initialState: VisitsOverview = {
|
const initialState: VisitsOverview = {
|
||||||
visitsCount: 0,
|
visitsCount: 0,
|
||||||
|
orphanVisitsCount: 0,
|
||||||
loading: false,
|
loading: false,
|
||||||
error: false,
|
error: false,
|
||||||
};
|
};
|
||||||
@ -28,7 +30,7 @@ const initialState: VisitsOverview = {
|
|||||||
export default buildReducer<VisitsOverview, GetVisitsOverviewAction & CreateVisitsAction>({
|
export default buildReducer<VisitsOverview, GetVisitsOverviewAction & CreateVisitsAction>({
|
||||||
[GET_OVERVIEW_START]: () => ({ ...initialState, loading: true }),
|
[GET_OVERVIEW_START]: () => ({ ...initialState, loading: true }),
|
||||||
[GET_OVERVIEW_ERROR]: () => ({ ...initialState, error: true }),
|
[GET_OVERVIEW_ERROR]: () => ({ ...initialState, error: true }),
|
||||||
[GET_OVERVIEW]: (_, { visitsCount }) => ({ ...initialState, visitsCount }),
|
[GET_OVERVIEW]: (_, { visitsCount, orphanVisitsCount }) => ({ ...initialState, visitsCount, orphanVisitsCount }),
|
||||||
[CREATE_VISITS]: ({ visitsCount, ...rest }, { createdVisits }) => ({
|
[CREATE_VISITS]: ({ visitsCount, ...rest }, { createdVisits }) => ({
|
||||||
...rest,
|
...rest,
|
||||||
visitsCount: visitsCount + createdVisits.length,
|
visitsCount: visitsCount + createdVisits.length,
|
||||||
|
|||||||
@ -32,7 +32,7 @@ describe('<Overview />', () => {
|
|||||||
loadVisitsOverview={loadVisitsOverview}
|
loadVisitsOverview={loadVisitsOverview}
|
||||||
shortUrlsList={Mock.of<ShortUrlsListState>({ loading, shortUrls })}
|
shortUrlsList={Mock.of<ShortUrlsListState>({ loading, shortUrls })}
|
||||||
tagsList={Mock.of<TagsList>({ loading, tags: [ 'foo', 'bar', 'baz' ] })}
|
tagsList={Mock.of<TagsList>({ loading, tags: [ 'foo', 'bar', 'baz' ] })}
|
||||||
visitsOverview={Mock.of<VisitsOverview>({ loading, visitsCount: 3456 })}
|
visitsOverview={Mock.of<VisitsOverview>({ loading, visitsCount: 3456, orphanVisitsCount: 28 })}
|
||||||
selectedServer={Mock.of<ReachableServer>({ id: serverId })}
|
selectedServer={Mock.of<ReachableServer>({ id: serverId })}
|
||||||
createNewVisits={jest.fn()}
|
createNewVisits={jest.fn()}
|
||||||
loadMercureInfo={jest.fn()}
|
loadMercureInfo={jest.fn()}
|
||||||
@ -49,7 +49,7 @@ describe('<Overview />', () => {
|
|||||||
const wrapper = createWrapper(true);
|
const wrapper = createWrapper(true);
|
||||||
const cards = wrapper.find(CardText);
|
const cards = wrapper.find(CardText);
|
||||||
|
|
||||||
expect(cards).toHaveLength(3);
|
expect(cards).toHaveLength(4);
|
||||||
cards.forEach((card) => expect(card.html()).toContain('Loading...'));
|
cards.forEach((card) => expect(card.html()).toContain('Loading...'));
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -57,10 +57,11 @@ describe('<Overview />', () => {
|
|||||||
const wrapper = createWrapper();
|
const wrapper = createWrapper();
|
||||||
const cards = wrapper.find(CardText);
|
const cards = wrapper.find(CardText);
|
||||||
|
|
||||||
expect(cards).toHaveLength(3);
|
expect(cards).toHaveLength(4);
|
||||||
expect(cards.at(0).html()).toContain(prettify(3456));
|
expect(cards.at(0).html()).toContain(prettify(3456));
|
||||||
expect(cards.at(1).html()).toContain(prettify(83710));
|
expect(cards.at(1).html()).toContain(prettify(28));
|
||||||
expect(cards.at(2).html()).toContain(prettify(3));
|
expect(cards.at(2).html()).toContain(prettify(83710));
|
||||||
|
expect(cards.at(3).html()).toContain(prettify(3));
|
||||||
});
|
});
|
||||||
|
|
||||||
test('first card displays warning for old shlink versions', () => {
|
test('first card displays warning for old shlink versions', () => {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user