mirror of
https://github.com/umami-software/umami.git
synced 2026-02-07 14:17:13 +01:00
Added tables to compare screen.
This commit is contained in:
parent
154b559315
commit
13e11ee371
15 changed files with 199 additions and 66 deletions
|
|
@ -9,7 +9,7 @@ export function WebsiteChart({
|
|||
compareMode = false,
|
||||
}: {
|
||||
websiteId: string;
|
||||
compareMode: boolean;
|
||||
compareMode?: boolean;
|
||||
}) {
|
||||
const { dateRange, dateCompare } = useDateRange(websiteId);
|
||||
const { startDate, endDate, unit } = dateRange;
|
||||
|
|
@ -27,13 +27,13 @@ export function WebsiteChart({
|
|||
result['compare'] = {
|
||||
pageviews: result.pageviews.map(({ x }, i) => ({
|
||||
x,
|
||||
y: compare.pageviews[i].y,
|
||||
d: compare.pageviews[i].x,
|
||||
y: compare.pageviews[i]?.y,
|
||||
d: compare.pageviews[i]?.x,
|
||||
})),
|
||||
sessions: result.sessions.map(({ x }, i) => ({
|
||||
x,
|
||||
y: compare.sessions[i].y,
|
||||
d: compare.pageviews[i].x,
|
||||
y: compare.sessions[i]?.y,
|
||||
d: compare.sessions[i]?.x,
|
||||
})),
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,25 +1,19 @@
|
|||
'use client';
|
||||
import { Loading } from 'react-basics';
|
||||
import { usePathname } from 'next/navigation';
|
||||
import Page from 'components/layout/Page';
|
||||
import FilterTags from 'components/metrics/FilterTags';
|
||||
import { useNavigation, useWebsite } from 'components/hooks';
|
||||
import { useNavigation } from 'components/hooks';
|
||||
import WebsiteChart from './WebsiteChart';
|
||||
import WebsiteExpandedView from './WebsiteExpandedView';
|
||||
import WebsiteHeader from './WebsiteHeader';
|
||||
import WebsiteMetricsBar from './WebsiteMetricsBar';
|
||||
import WebsiteTableView from './WebsiteTableView';
|
||||
import WebsiteProvider from './WebsiteProvider';
|
||||
import { FILTER_COLUMNS } from 'lib/constants';
|
||||
|
||||
export default function WebsiteDetails({ websiteId }: { websiteId: string }) {
|
||||
const { data: website, isLoading, error } = useWebsite(websiteId);
|
||||
export default function WebsiteDetailsPage({ websiteId }: { websiteId: string }) {
|
||||
const pathname = usePathname();
|
||||
const { query } = useNavigation();
|
||||
|
||||
if (isLoading || error) {
|
||||
return <Page isLoading={isLoading} error={error} />;
|
||||
}
|
||||
|
||||
const showLinks = !pathname.includes('/share/');
|
||||
const { view } = query;
|
||||
|
||||
|
|
@ -31,18 +25,13 @@ export default function WebsiteDetails({ websiteId }: { websiteId: string }) {
|
|||
}, {});
|
||||
|
||||
return (
|
||||
<>
|
||||
<WebsiteProvider websiteId={websiteId}>
|
||||
<WebsiteHeader websiteId={websiteId} showLinks={showLinks} />
|
||||
<FilterTags websiteId={websiteId} params={params} />
|
||||
<WebsiteMetricsBar websiteId={websiteId} showChange={true} sticky={true} />
|
||||
<WebsiteChart websiteId={websiteId} />
|
||||
{!website && <Loading icon="dots" style={{ minHeight: 300 }} />}
|
||||
{website && (
|
||||
<>
|
||||
{!view && <WebsiteTableView websiteId={websiteId} domainName={website.domain} />}
|
||||
{view && <WebsiteExpandedView websiteId={websiteId} domainName={website.domain} />}
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
{!view && <WebsiteTableView websiteId={websiteId} />}
|
||||
{view && <WebsiteExpandedView websiteId={websiteId} />}
|
||||
</WebsiteProvider>
|
||||
);
|
||||
}
|
||||
|
|
@ -10,17 +10,10 @@ import CountriesTable from 'components/metrics/CountriesTable';
|
|||
import EventsTable from 'components/metrics/EventsTable';
|
||||
import EventsChart from 'components/metrics/EventsChart';
|
||||
|
||||
export default function WebsiteTableView({
|
||||
websiteId,
|
||||
domainName,
|
||||
}: {
|
||||
websiteId: string;
|
||||
domainName: string;
|
||||
}) {
|
||||
export default function WebsiteTableView({ websiteId }: { websiteId: string }) {
|
||||
const [countryData, setCountryData] = useState();
|
||||
const tableProps = {
|
||||
websiteId,
|
||||
domainName,
|
||||
limit: 10,
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -5,6 +5,8 @@ import FilterTags from 'components/metrics/FilterTags';
|
|||
import { useNavigation } from 'components/hooks';
|
||||
import { FILTER_COLUMNS } from 'lib/constants';
|
||||
import WebsiteChart from '../WebsiteChart';
|
||||
import WebsiteCompareTables from './WebsiteCompareTables';
|
||||
import WebsiteProvider from '../WebsiteProvider';
|
||||
|
||||
export function WebsiteComparePage({ websiteId }) {
|
||||
const { query } = useNavigation();
|
||||
|
|
@ -17,12 +19,13 @@ export function WebsiteComparePage({ websiteId }) {
|
|||
}, {});
|
||||
|
||||
return (
|
||||
<>
|
||||
<WebsiteProvider websiteId={websiteId}>
|
||||
<WebsiteHeader websiteId={websiteId} />
|
||||
<FilterTags websiteId={websiteId} params={params} />
|
||||
<WebsiteMetricsBar websiteId={websiteId} compareMode={true} />
|
||||
<WebsiteChart websiteId={websiteId} compareMode={true} />
|
||||
</>
|
||||
<WebsiteCompareTables websiteId={websiteId} />
|
||||
</WebsiteProvider>
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,7 @@
|
|||
.container {
|
||||
margin-bottom: 60px;
|
||||
}
|
||||
|
||||
.nav {
|
||||
width: 200px;
|
||||
}
|
||||
|
|
@ -0,0 +1,137 @@
|
|||
import SideNav from 'components/layout/SideNav';
|
||||
import { useMessages, useNavigation } from 'components/hooks';
|
||||
import PagesTable from 'components/metrics/PagesTable';
|
||||
import ReferrersTable from 'components/metrics/ReferrersTable';
|
||||
import BrowsersTable from 'components/metrics/BrowsersTable';
|
||||
import OSTable from 'components/metrics/OSTable';
|
||||
import DevicesTable from 'components/metrics/DevicesTable';
|
||||
import ScreenTable from 'components/metrics/ScreenTable';
|
||||
import CountriesTable from 'components/metrics/CountriesTable';
|
||||
import RegionsTable from 'components/metrics/RegionsTable';
|
||||
import CitiesTable from 'components/metrics/CitiesTable';
|
||||
import LanguagesTable from 'components/metrics/LanguagesTable';
|
||||
import EventsTable from 'components/metrics/EventsTable';
|
||||
import QueryParametersTable from 'components/metrics/QueryParametersTable';
|
||||
import { Grid, GridRow } from 'components/layout/Grid';
|
||||
import styles from './WebsiteCompareTables.module.css';
|
||||
import { useContext, useState } from 'react';
|
||||
import MetricsTable from 'components/metrics/MetricsTable';
|
||||
import FilterLink from 'components/common/FilterLink';
|
||||
import { WebsiteContext } from '../WebsiteProvider';
|
||||
|
||||
const views = {
|
||||
url: PagesTable,
|
||||
title: PagesTable,
|
||||
referrer: ReferrersTable,
|
||||
browser: BrowsersTable,
|
||||
os: OSTable,
|
||||
device: DevicesTable,
|
||||
screen: ScreenTable,
|
||||
country: CountriesTable,
|
||||
region: RegionsTable,
|
||||
city: CitiesTable,
|
||||
language: LanguagesTable,
|
||||
event: EventsTable,
|
||||
query: QueryParametersTable,
|
||||
};
|
||||
|
||||
export function WebsiteCompareTables({ websiteId }: { websiteId: string }) {
|
||||
const { domain } = useContext(WebsiteContext);
|
||||
const [data, setData] = useState([]);
|
||||
const { formatMessage, labels } = useMessages();
|
||||
const {
|
||||
renderUrl,
|
||||
query: { view },
|
||||
} = useNavigation();
|
||||
const Component: typeof MetricsTable = views[view] || (() => null);
|
||||
|
||||
const items = [
|
||||
{
|
||||
key: 'url',
|
||||
label: formatMessage(labels.pages),
|
||||
url: renderUrl({ view: 'url' }),
|
||||
},
|
||||
{
|
||||
key: 'referrer',
|
||||
label: formatMessage(labels.referrers),
|
||||
url: renderUrl({ view: 'referrer' }),
|
||||
},
|
||||
{
|
||||
key: 'browser',
|
||||
label: formatMessage(labels.browsers),
|
||||
url: renderUrl({ view: 'browser' }),
|
||||
},
|
||||
{
|
||||
key: 'os',
|
||||
label: formatMessage(labels.os),
|
||||
url: renderUrl({ view: 'os' }),
|
||||
},
|
||||
{
|
||||
key: 'device',
|
||||
label: formatMessage(labels.devices),
|
||||
url: renderUrl({ view: 'device' }),
|
||||
},
|
||||
{
|
||||
key: 'country',
|
||||
label: formatMessage(labels.countries),
|
||||
url: renderUrl({ view: 'country' }),
|
||||
},
|
||||
{
|
||||
key: 'region',
|
||||
label: formatMessage(labels.regions),
|
||||
url: renderUrl({ view: 'region' }),
|
||||
},
|
||||
{
|
||||
key: 'city',
|
||||
label: formatMessage(labels.cities),
|
||||
url: renderUrl({ view: 'city' }),
|
||||
},
|
||||
{
|
||||
key: 'language',
|
||||
label: formatMessage(labels.languages),
|
||||
url: renderUrl({ view: 'language' }),
|
||||
},
|
||||
{
|
||||
key: 'screen',
|
||||
label: formatMessage(labels.screens),
|
||||
url: renderUrl({ view: 'screen' }),
|
||||
},
|
||||
{
|
||||
key: 'event',
|
||||
label: formatMessage(labels.events),
|
||||
url: renderUrl({ view: 'event' }),
|
||||
},
|
||||
{
|
||||
key: 'query',
|
||||
label: formatMessage(labels.queryParameters),
|
||||
url: renderUrl({ view: 'query' }),
|
||||
},
|
||||
];
|
||||
|
||||
const renderLabel = ({ x, y }, index) => {
|
||||
return (
|
||||
<FilterLink
|
||||
id={view}
|
||||
value={x}
|
||||
label={!x && formatMessage(labels.none)}
|
||||
externalUrl={
|
||||
view === 'url' ? `${domain.startsWith('http') ? domain : `https://${domain}`}${x}` : null
|
||||
}
|
||||
>
|
||||
{y} : {data[index]?.y} !
|
||||
</FilterLink>
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<Grid className={styles.container}>
|
||||
<GridRow columns="compare">
|
||||
<SideNav className={styles.nav} items={items} selectedKey={view} shallow={true} />
|
||||
<Component websiteId={websiteId} limit={20} showMore={false} onDataLoad={setData} />
|
||||
<Component websiteId={websiteId} limit={20} showMore={false} renderLabel={renderLabel} />
|
||||
</GridRow>
|
||||
</Grid>
|
||||
);
|
||||
}
|
||||
|
||||
export default WebsiteCompareTables;
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
import WebsiteDetails from './WebsiteDetails';
|
||||
import WebsiteDetailsPage from './WebsiteDetailsPage';
|
||||
import { Metadata } from 'next';
|
||||
|
||||
export default function WebsitePage({ params: { websiteId } }) {
|
||||
return <WebsiteDetails websiteId={websiteId} />;
|
||||
return <WebsiteDetailsPage websiteId={websiteId} />;
|
||||
}
|
||||
|
||||
export const metadata: Metadata = {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
'use client';
|
||||
import WebsiteDetails from 'app/(main)/websites/[websiteId]/WebsiteDetails';
|
||||
import WebsiteDetailsPage from '../../(main)/websites/[websiteId]/WebsiteDetailsPage';
|
||||
import { useShareToken } from 'components/hooks';
|
||||
import Page from 'components/layout/Page';
|
||||
import Header from './Header';
|
||||
|
|
@ -17,7 +17,7 @@ export default function SharePage({ shareId }) {
|
|||
<div className={styles.container}>
|
||||
<Page>
|
||||
<Header />
|
||||
<WebsiteDetails websiteId={shareToken.websiteId} />
|
||||
<WebsiteDetailsPage websiteId={shareToken.websiteId} />
|
||||
<Footer />
|
||||
</Page>
|
||||
</div>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue