mirror of
https://github.com/umami-software/umami.git
synced 2026-02-04 04:37:11 +01:00
Merge branch 'dev' into bh/unregister
This commit is contained in:
commit
348ee22e18
27 changed files with 563 additions and 276 deletions
|
|
@ -1,12 +1,12 @@
|
|||
.link,
|
||||
.link:active,
|
||||
.link:visited {
|
||||
a.link,
|
||||
a.link:active,
|
||||
a.link:visited {
|
||||
position: relative;
|
||||
color: #2c2c2c;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.link:before {
|
||||
a.link:before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
bottom: -2px;
|
||||
|
|
@ -17,7 +17,7 @@
|
|||
transition: width 100ms;
|
||||
}
|
||||
|
||||
.link:hover:before {
|
||||
a.link:hover:before {
|
||||
width: 100%;
|
||||
transition: width 100ms;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import React, { useState, useEffect } from 'react';
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
import { setDateRange } from 'redux/actions/websites';
|
||||
import Button from './Button';
|
||||
import Refresh from 'assets/redo.svg';
|
||||
|
|
@ -24,5 +25,13 @@ export default function RefreshButton({ websiteId }) {
|
|||
setLoading(false);
|
||||
}, [completed]);
|
||||
|
||||
return <Button icon={loading ? <Dots /> : <Refresh />} size="small" onClick={handleClick} />;
|
||||
return (
|
||||
<Button
|
||||
icon={loading ? <Dots /> : <Refresh />}
|
||||
tooltip={<FormattedMessage id="button.refresh" defaultMessage="Refresh" />}
|
||||
tooltipId="button-refresh"
|
||||
size="small"
|
||||
onClick={handleClick}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
.buttons {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.buttons button + button {
|
||||
.buttons button + * {
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,21 +1,27 @@
|
|||
import React from 'react';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
import classNames from 'classnames';
|
||||
import Button from 'components/common/Button';
|
||||
import Logo from 'assets/logo.svg';
|
||||
import Link from 'components/common/Link';
|
||||
import styles from './Footer.module.css';
|
||||
|
||||
export default function Footer() {
|
||||
const version = process.env.VERSION;
|
||||
return (
|
||||
<footer className="container">
|
||||
<div className={classNames(styles.footer, 'row justify-content-center')}>
|
||||
<FormattedMessage id="footer.powered-by" defaultMessage="Powered by" />
|
||||
<a href="https://umami.is">
|
||||
<Button className={styles.button} icon={<Logo />} size="small">
|
||||
<b>umami</b>
|
||||
</Button>
|
||||
</a>
|
||||
<div className={styles.footer}>
|
||||
<div />
|
||||
<div>
|
||||
<FormattedMessage
|
||||
id="footer.powered-by"
|
||||
defaultMessage="Powered by {name}"
|
||||
values={{
|
||||
name: (
|
||||
<Link href="https://umami.is">
|
||||
<b>umami</b>
|
||||
</Link>
|
||||
),
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<div>{`v${version}`}</div>
|
||||
</div>
|
||||
</footer>
|
||||
|
|
|
|||
|
|
@ -5,11 +5,3 @@
|
|||
font-size: var(--font-size-small);
|
||||
min-height: 100px;
|
||||
}
|
||||
|
||||
.footer a {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.button {
|
||||
margin: 0 5px;
|
||||
}
|
||||
|
|
|
|||
17
components/messages.js
Normal file
17
components/messages.js
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
import React from 'react';
|
||||
import { defineMessages, FormattedMessage } from 'react-intl';
|
||||
|
||||
export const labels = defineMessages({
|
||||
unknown: { id: 'label.unknown', defaultMessage: 'Unknown' },
|
||||
});
|
||||
|
||||
export const devices = defineMessages({
|
||||
desktop: { id: 'device.desktop', defaultMessage: 'Desktop' },
|
||||
laptop: { id: 'device.laptop', defaultMessage: 'Laptop' },
|
||||
tablet: { id: 'device.tablet', defaultMessage: 'Tablet' },
|
||||
mobile: { id: 'device.mobile', defaultMessage: 'Mobile' },
|
||||
});
|
||||
|
||||
export function getDeviceMessage(device) {
|
||||
return <FormattedMessage {...(devices[device] || labels.unknown)} />;
|
||||
}
|
||||
|
|
@ -2,6 +2,7 @@ import React from 'react';
|
|||
import MetricsTable from './MetricsTable';
|
||||
import { deviceFilter } from 'lib/filters';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
import { getDeviceMessage } from 'components/messages';
|
||||
|
||||
export default function DevicesTable({ websiteId, limit, onExpand }) {
|
||||
return (
|
||||
|
|
@ -12,6 +13,7 @@ export default function DevicesTable({ websiteId, limit, onExpand }) {
|
|||
websiteId={websiteId}
|
||||
limit={limit}
|
||||
dataFilter={deviceFilter}
|
||||
renderLabel={({ x }) => getDeviceMessage(x)}
|
||||
onExpand={onExpand}
|
||||
/>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -1,17 +1,15 @@
|
|||
import React from 'react';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
import { useRouter } from 'next/router';
|
||||
import Link from 'components/common/Link';
|
||||
import PageHeader from 'components/layout/PageHeader';
|
||||
import Button from 'components/common/Button';
|
||||
import ActiveUsers from './ActiveUsers';
|
||||
import Arrow from 'assets/arrow-right.svg';
|
||||
import styles from './WebsiteHeader.module.css';
|
||||
import RefreshButton from '../common/RefreshButton';
|
||||
import ButtonLayout from '../layout/ButtonLayout';
|
||||
import Icon from '../common/Icon';
|
||||
|
||||
export default function WebsiteHeader({ websiteId, title, showLink = false }) {
|
||||
const router = useRouter();
|
||||
|
||||
return (
|
||||
<PageHeader>
|
||||
<div className={styles.title}>{title}</div>
|
||||
|
|
@ -19,19 +17,14 @@ export default function WebsiteHeader({ websiteId, title, showLink = false }) {
|
|||
<ButtonLayout>
|
||||
<RefreshButton websiteId={websiteId} />
|
||||
{showLink && (
|
||||
<Button
|
||||
icon={<Arrow />}
|
||||
onClick={() =>
|
||||
router.push('/website/[...id]', `/website/${websiteId}/${title}`, {
|
||||
shallow: true,
|
||||
})
|
||||
}
|
||||
size="small"
|
||||
<Link
|
||||
href="/website/[...id]"
|
||||
as={`/website/${websiteId}/${title}`}
|
||||
className={styles.link}
|
||||
>
|
||||
<div>
|
||||
<FormattedMessage id="button.view-details" defaultMessage="View details" />
|
||||
</div>
|
||||
</Button>
|
||||
<FormattedMessage id="button.view-details" defaultMessage="View details" />
|
||||
<Icon icon={<Arrow />} size="small" />
|
||||
</Link>
|
||||
)}
|
||||
</ButtonLayout>
|
||||
</PageHeader>
|
||||
|
|
|
|||
|
|
@ -4,8 +4,13 @@
|
|||
line-height: var(--font-size-large);
|
||||
}
|
||||
|
||||
.button {
|
||||
.link {
|
||||
font-size: var(--font-size-small);
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.link svg {
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 576px) {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import React, { useState } from 'react';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
import classNames from 'classnames';
|
||||
import Link from 'components/common/Link';
|
||||
import Table from 'components/common/Table';
|
||||
import Button from 'components/common/Button';
|
||||
import PageHeader from 'components/layout/PageHeader';
|
||||
|
|
@ -16,7 +17,7 @@ import Pen from 'assets/pen.svg';
|
|||
import Trash from 'assets/trash.svg';
|
||||
import Plus from 'assets/plus.svg';
|
||||
import Code from 'assets/code.svg';
|
||||
import Link from 'assets/link.svg';
|
||||
import LinkIcon from 'assets/link.svg';
|
||||
import useFetch from 'hooks/useFetch';
|
||||
import styles from './WebsiteSettings.module.css';
|
||||
|
||||
|
|
@ -34,7 +35,7 @@ export default function WebsiteSettings() {
|
|||
<ButtonLayout>
|
||||
{row.share_id && (
|
||||
<Button
|
||||
icon={<Link />}
|
||||
icon={<LinkIcon />}
|
||||
size="small"
|
||||
tooltip={<FormattedMessage id="tooltip.get-share-url" defaultMessage="Get share URL" />}
|
||||
tooltipId={`button-share-${row.website_id}`}
|
||||
|
|
@ -63,11 +64,18 @@ export default function WebsiteSettings() {
|
|||
</ButtonLayout>
|
||||
);
|
||||
|
||||
const DetailsLink = ({ website_id, name }) => (
|
||||
<Link href="/website/[...id]" as={`/website/${website_id}/${name}`}>
|
||||
{name}
|
||||
</Link>
|
||||
);
|
||||
|
||||
const columns = [
|
||||
{
|
||||
key: 'name',
|
||||
label: <FormattedMessage id="label.name" defaultMessage="Name" />,
|
||||
className: 'col-6 col-xl-4',
|
||||
render: DetailsLink,
|
||||
},
|
||||
{
|
||||
key: 'domain',
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue