mirror of
https://github.com/umami-software/umami.git
synced 2026-02-06 05:37:20 +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
|
|
@ -98,9 +98,9 @@ export function Chart({
|
|||
// Allow config changes before update
|
||||
onUpdate?.(chart.current);
|
||||
|
||||
setLegendItems(chart.current.legend.legendItems);
|
||||
|
||||
chart.current.update(updateMode);
|
||||
|
||||
setLegendItems(chart.current.legend.legendItems);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
|
|
|
|||
|
|
@ -23,6 +23,15 @@ export function WebsiteDateFilter({ websiteId }: { websiteId: string }) {
|
|||
|
||||
return (
|
||||
<div className={styles.container}>
|
||||
<DateFilter
|
||||
className={styles.dropdown}
|
||||
value={value}
|
||||
startDate={startDate}
|
||||
endDate={endDate}
|
||||
offset={offset}
|
||||
onChange={handleChange}
|
||||
showAllTime={true}
|
||||
/>
|
||||
{value !== 'all' && !value.startsWith('range') && (
|
||||
<div className={styles.buttons}>
|
||||
<Button onClick={() => handleIncrement(-1)}>
|
||||
|
|
@ -37,15 +46,6 @@ export function WebsiteDateFilter({ websiteId }: { websiteId: string }) {
|
|||
</Button>
|
||||
</div>
|
||||
)}
|
||||
<DateFilter
|
||||
className={styles.dropdown}
|
||||
value={value}
|
||||
startDate={startDate}
|
||||
endDate={endDate}
|
||||
offset={offset}
|
||||
onChange={handleChange}
|
||||
showAllTime={true}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,10 @@
|
|||
border-top: 1px solid var(--base300);
|
||||
}
|
||||
|
||||
.row.compare {
|
||||
grid-template-columns: max-content 1fr 1fr;
|
||||
}
|
||||
|
||||
.col {
|
||||
padding: 20px;
|
||||
min-height: 430px;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import { CSSProperties } from 'react';
|
||||
import classNames from 'classnames';
|
||||
import { mapChildren } from 'react-basics';
|
||||
// eslint-disable-next-line css-modules/no-unused-class
|
||||
import styles from './Grid.module.css';
|
||||
|
||||
export interface GridProps {
|
||||
|
|
@ -19,13 +20,13 @@ export function Grid({ className, style, children }: GridProps) {
|
|||
|
||||
export function GridRow(props: {
|
||||
[x: string]: any;
|
||||
columns?: 'one' | 'two' | 'three' | 'one-two' | 'two-one';
|
||||
columns?: 'one' | 'two' | 'three' | 'one-two' | 'two-one' | 'compare';
|
||||
className?: string;
|
||||
children?: any;
|
||||
}) {
|
||||
const { columns = 'two', className, children, ...otherProps } = props;
|
||||
return (
|
||||
<div {...otherProps} className={classNames(styles.row, className)}>
|
||||
<div {...otherProps} className={classNames(styles.row, className, { [styles[columns]]: true })}>
|
||||
{mapChildren(children, child => {
|
||||
return <div className={classNames(styles.col, { [styles[columns]]: true })}>{child}</div>;
|
||||
})}
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ export interface ListTableProps {
|
|||
title?: string;
|
||||
metric?: string;
|
||||
className?: string;
|
||||
renderLabel?: (row: any) => ReactNode;
|
||||
renderLabel?: (row: any, index: number) => ReactNode;
|
||||
animate?: boolean;
|
||||
virtualize?: boolean;
|
||||
showPercentage?: boolean;
|
||||
|
|
@ -34,13 +34,13 @@ export function ListTable({
|
|||
}: ListTableProps) {
|
||||
const { formatMessage, labels } = useMessages();
|
||||
|
||||
const getRow = row => {
|
||||
const getRow = (row: { x: any; y: any; z: any }, index: number) => {
|
||||
const { x: label, y: value, z: percent } = row;
|
||||
|
||||
return (
|
||||
<AnimatedRow
|
||||
key={label}
|
||||
label={renderLabel ? renderLabel(row) : label ?? formatMessage(labels.unknown)}
|
||||
label={renderLabel ? renderLabel(row, index) : label ?? formatMessage(labels.unknown)}
|
||||
value={value}
|
||||
percent={percent}
|
||||
animate={animate && !virtualize}
|
||||
|
|
@ -50,7 +50,7 @@ export function ListTable({
|
|||
};
|
||||
|
||||
const Row = ({ index, style }) => {
|
||||
return <div style={style}>{getRow(data[index])}</div>;
|
||||
return <div style={style}>{getRow(data[index], index)}</div>;
|
||||
};
|
||||
|
||||
return (
|
||||
|
|
@ -71,7 +71,7 @@ export function ListTable({
|
|||
{Row}
|
||||
</FixedSizeList>
|
||||
) : (
|
||||
data.map(row => getRow(row))
|
||||
data.map(getRow)
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -97,9 +97,7 @@ const AnimatedRow = ({ label, value = 0, percent, animate, showPercentage = true
|
|||
{showPercentage && (
|
||||
<div className={styles.percent}>
|
||||
<animated.div className={styles.bar} style={{ width: props.width.to(n => `${n}%`) }} />
|
||||
<animated.span className={styles.percentValue}>
|
||||
{props.width.to(n => `${n?.toFixed?.(0)}%`)}
|
||||
</animated.span>
|
||||
<animated.span>{props.width.to(n => `${n?.toFixed?.(0)}%`)}</animated.span>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -18,7 +18,6 @@ import styles from './MetricsTable.module.css';
|
|||
|
||||
export interface MetricsTableProps extends ListTableProps {
|
||||
websiteId: string;
|
||||
domainName: string;
|
||||
type?: string;
|
||||
className?: string;
|
||||
dataFilter?: (data: any) => any;
|
||||
|
|
@ -27,6 +26,7 @@ export interface MetricsTableProps extends ListTableProps {
|
|||
onDataLoad?: (data: any) => void;
|
||||
onSearch?: (search: string) => void;
|
||||
allowSearch?: boolean;
|
||||
showMore?: boolean;
|
||||
children?: ReactNode;
|
||||
}
|
||||
|
||||
|
|
@ -39,6 +39,7 @@ export function MetricsTable({
|
|||
onDataLoad,
|
||||
delay = null,
|
||||
allowSearch = false,
|
||||
showMore = true,
|
||||
children,
|
||||
...props
|
||||
}: MetricsTableProps) {
|
||||
|
|
@ -98,7 +99,7 @@ export function MetricsTable({
|
|||
)}
|
||||
{!data && isLoading && !isFetched && <Loading icon="dots" />}
|
||||
<div className={styles.footer}>
|
||||
{data && !error && limit && (
|
||||
{showMore && data && !error && limit && (
|
||||
<LinkButton href={renderUrl({ view: type })} variant="quiet">
|
||||
<Text>{formatMessage(labels.more)}</Text>
|
||||
<Icon size="sm" rotate={dir === 'rtl' ? 180 : 0}>
|
||||
|
|
|
|||
|
|
@ -4,18 +4,21 @@ import MetricsTable, { MetricsTableProps } from './MetricsTable';
|
|||
import { useMessages } from 'components/hooks';
|
||||
import { useNavigation } from 'components/hooks';
|
||||
import { emptyFilter } from 'lib/filters';
|
||||
import { useContext } from 'react';
|
||||
import { WebsiteContext } from 'app/(main)/websites/[websiteId]/WebsiteProvider';
|
||||
|
||||
export interface PagesTableProps extends MetricsTableProps {
|
||||
allowFilter?: boolean;
|
||||
}
|
||||
|
||||
export function PagesTable({ allowFilter, domainName, ...props }: PagesTableProps) {
|
||||
export function PagesTable({ allowFilter, ...props }: PagesTableProps) {
|
||||
const {
|
||||
router,
|
||||
renderUrl,
|
||||
query: { view = 'url' },
|
||||
} = useNavigation();
|
||||
const { formatMessage, labels } = useMessages();
|
||||
const { domain } = useContext(WebsiteContext);
|
||||
|
||||
const handleSelect = (key: any) => {
|
||||
router.push(renderUrl({ view: key }), { scroll: true });
|
||||
|
|
@ -39,9 +42,7 @@ export function PagesTable({ allowFilter, domainName, ...props }: PagesTableProp
|
|||
value={x}
|
||||
label={!x && formatMessage(labels.none)}
|
||||
externalUrl={
|
||||
view === 'url'
|
||||
? `${domainName.startsWith('http') ? domainName : `https://${domainName}`}${x}`
|
||||
: null
|
||||
view === 'url' ? `${domain.startsWith('http') ? domain : `https://${domain}`}${x}` : null
|
||||
}
|
||||
/>
|
||||
);
|
||||
|
|
@ -50,12 +51,11 @@ export function PagesTable({ allowFilter, domainName, ...props }: PagesTableProp
|
|||
return (
|
||||
<MetricsTable
|
||||
{...props}
|
||||
domainName={domainName}
|
||||
title={formatMessage(labels.pages)}
|
||||
type={view}
|
||||
metric={formatMessage(labels.views)}
|
||||
dataFilter={emptyFilter}
|
||||
renderLabel={renderLink}
|
||||
renderLabel={props.renderLabel || renderLink}
|
||||
>
|
||||
{allowFilter && <FilterButtons items={buttons} selectedKey={view} onSelect={handleSelect} />}
|
||||
</MetricsTable>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue