mirror of
https://github.com/kremalicious/umami.git
synced 2025-01-04 11:05:08 +01:00
Responsive CSS updates.
This commit is contained in:
parent
106fe90e26
commit
c95aa4aa56
@ -12,6 +12,7 @@
|
|||||||
|
|
||||||
.content {
|
.content {
|
||||||
min-height: 600px;
|
min-height: 600px;
|
||||||
|
padding: 20px 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.backButton {
|
.backButton {
|
||||||
@ -30,7 +31,7 @@
|
|||||||
|
|
||||||
.row > [class*='col-'] {
|
.row > [class*='col-'] {
|
||||||
border-left: 1px solid var(--gray300);
|
border-left: 1px solid var(--gray300);
|
||||||
padding: 0 20px;
|
padding: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.row > [class*='col-']:first-child {
|
.row > [class*='col-']:first-child {
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.button:active {
|
.button:active {
|
||||||
color: var(--gray700);
|
color: var(--gray900);
|
||||||
}
|
}
|
||||||
|
|
||||||
.large {
|
.large {
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
text-align: center;
|
text-align: center;
|
||||||
vertical-align: center;
|
vertical-align: center;
|
||||||
height: 40px;
|
height: 40px;
|
||||||
min-width: 40px;
|
width: 40px;
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
border: 1px solid transparent;
|
border: 1px solid transparent;
|
||||||
}
|
}
|
||||||
@ -103,3 +103,9 @@
|
|||||||
.icon {
|
.icon {
|
||||||
margin-left: 10px;
|
margin-left: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@media only screen and (max-width: 992px) {
|
||||||
|
.calendar table {
|
||||||
|
max-width: calc(100vw - 30px);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -37,7 +37,7 @@ export default function MenuButton({
|
|||||||
<div className={styles.container} ref={ref}>
|
<div className={styles.container} ref={ref}>
|
||||||
<Button
|
<Button
|
||||||
icon={icon}
|
icon={icon}
|
||||||
className={classNames({ [styles.open]: showMenu })}
|
className={classNames(styles.button, { [styles.open]: showMenu })}
|
||||||
onClick={toggleMenu}
|
onClick={toggleMenu}
|
||||||
variant="light"
|
variant="light"
|
||||||
>
|
>
|
||||||
|
@ -4,6 +4,11 @@
|
|||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.button {
|
||||||
|
border: 1px solid transparent;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
.menu {
|
.menu {
|
||||||
z-index: 100;
|
z-index: 100;
|
||||||
}
|
}
|
||||||
@ -12,10 +17,8 @@
|
|||||||
font-size: var(--font-size-small);
|
font-size: var(--font-size-small);
|
||||||
}
|
}
|
||||||
|
|
||||||
.open {
|
.open,
|
||||||
background: var(--gray200);
|
|
||||||
}
|
|
||||||
|
|
||||||
.open:hover {
|
.open:hover {
|
||||||
background: var(--gray200);
|
background: var(--gray50);
|
||||||
|
border: 1px solid var(--gray500);
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,16 @@ import React from 'react';
|
|||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import styles from './ButtonLayout.module.css';
|
import styles from './ButtonLayout.module.css';
|
||||||
|
|
||||||
export default function ButtonLayout({ className, children }) {
|
export default function ButtonLayout({ className, children, align = 'center' }) {
|
||||||
return <div className={classNames(styles.buttons, className)}>{children}</div>;
|
return (
|
||||||
|
<div
|
||||||
|
className={classNames(styles.buttons, className, {
|
||||||
|
[styles.left]: align === 'left',
|
||||||
|
[styles.center]: align === 'center',
|
||||||
|
[styles.right]: align === 'right',
|
||||||
|
})}
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
@ -6,3 +6,15 @@
|
|||||||
.buttons button + * {
|
.buttons button + * {
|
||||||
margin-left: 10px;
|
margin-left: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.center {
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.left {
|
||||||
|
justify-content: flex-start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.right {
|
||||||
|
justify-content: flex-end;
|
||||||
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
.page {
|
.page {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
padding: 0 30px;
|
padding: 0 30px;
|
||||||
background: var(--gray50);
|
background: var(--gray50);
|
||||||
height: 100%;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import classNames from 'classnames';
|
||||||
import styles from './PageHeader.module.css';
|
import styles from './PageHeader.module.css';
|
||||||
|
|
||||||
export default function PageHeader({ children }) {
|
export default function PageHeader({ children, className }) {
|
||||||
return <div className={styles.header}>{children}</div>;
|
return <div className={classNames(styles.header, className)}>{children}</div>;
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,7 @@ export default function BarChart({
|
|||||||
}) {
|
}) {
|
||||||
const canvas = useRef();
|
const canvas = useRef();
|
||||||
const chart = useRef();
|
const chart = useRef();
|
||||||
const [tooltip, setTooltip] = useState({});
|
const [tooltip, setTooltip] = useState(null);
|
||||||
const [locale] = useLocale();
|
const [locale] = useLocale();
|
||||||
const [theme] = useTheme();
|
const [theme] = useTheme();
|
||||||
const colors = {
|
const colors = {
|
||||||
@ -69,18 +69,19 @@ export default function BarChart({
|
|||||||
function renderTooltip(model) {
|
function renderTooltip(model) {
|
||||||
const { opacity, title, body, labelColors } = model;
|
const { opacity, title, body, labelColors } = model;
|
||||||
|
|
||||||
if (!opacity) {
|
if (!opacity || !title) {
|
||||||
setTooltip(null);
|
setTooltip(null);
|
||||||
} else {
|
return;
|
||||||
const [label, value] = body[0].lines[0].split(':');
|
|
||||||
|
|
||||||
setTooltip({
|
|
||||||
title: dateFormat(new Date(+title[0]), getTooltipFormat(unit), locale),
|
|
||||||
value,
|
|
||||||
label,
|
|
||||||
labelColor: labelColors[0].backgroundColor,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const [label, value] = body[0].lines[0].split(':');
|
||||||
|
|
||||||
|
setTooltip({
|
||||||
|
title: dateFormat(new Date(+title[0]), getTooltipFormat(unit), locale),
|
||||||
|
value,
|
||||||
|
label,
|
||||||
|
labelColor: labelColors[0].backgroundColor,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function getTooltipFormat(unit) {
|
function getTooltipFormat(unit) {
|
||||||
|
@ -3,7 +3,6 @@
|
|||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
min-width: 140px;
|
min-width: 140px;
|
||||||
padding-right: 20px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.value {
|
.value {
|
||||||
|
@ -3,11 +3,15 @@
|
|||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.bar > div + div {
|
||||||
|
padding-left: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
@media only screen and (max-width: 992px) {
|
@media only screen and (max-width: 992px) {
|
||||||
.bar {
|
.bar {
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
}
|
}
|
||||||
.bar > div:last-child {
|
.bar > div:nth-child(n + 3) {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,6 @@ export default function MetricsTable({
|
|||||||
dataFilter,
|
dataFilter,
|
||||||
filterOptions,
|
filterOptions,
|
||||||
limit,
|
limit,
|
||||||
headerComponent,
|
|
||||||
renderLabel,
|
renderLabel,
|
||||||
onDataLoad = () => {},
|
onDataLoad = () => {},
|
||||||
onExpand = () => {},
|
onExpand = () => {},
|
||||||
@ -85,7 +84,6 @@ export default function MetricsTable({
|
|||||||
<>
|
<>
|
||||||
<div className={styles.header}>
|
<div className={styles.header}>
|
||||||
<div className={styles.title}>{title}</div>
|
<div className={styles.title}>{title}</div>
|
||||||
{headerComponent}
|
|
||||||
<div className={styles.metric} onClick={handleSetFormat}>
|
<div className={styles.metric} onClick={handleSetFormat}>
|
||||||
{metric}
|
{metric}
|
||||||
</div>
|
</div>
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
position: relative;
|
position: relative;
|
||||||
min-height: 460px;
|
min-height: 460px;
|
||||||
font-size: var(--font-size-small);
|
font-size: var(--font-size-small);
|
||||||
padding: 20px 0;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@ import ButtonGroup from 'components/common/ButtonGroup';
|
|||||||
import { urlFilter } from 'lib/filters';
|
import { urlFilter } from 'lib/filters';
|
||||||
import { FILTER_COMBINED, FILTER_RAW } from 'lib/constants';
|
import { FILTER_COMBINED, FILTER_RAW } from 'lib/constants';
|
||||||
import MetricsTable from './MetricsTable';
|
import MetricsTable from './MetricsTable';
|
||||||
|
import ButtonLayout from '../layout/ButtonLayout';
|
||||||
|
|
||||||
export default function PagesTable({ websiteId, token, websiteDomain, limit, onExpand }) {
|
export default function PagesTable({ websiteId, token, websiteDomain, limit, onExpand }) {
|
||||||
const [filter, setFilter] = useState(FILTER_COMBINED);
|
const [filter, setFilter] = useState(FILTER_COMBINED);
|
||||||
@ -17,24 +18,28 @@ export default function PagesTable({ websiteId, token, websiteDomain, limit, onE
|
|||||||
];
|
];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<MetricsTable
|
<>
|
||||||
title={<FormattedMessage id="metrics.pages" defaultMessage="Pages" />}
|
{!limit && <FilterButtons buttons={buttons} selected={filter} onClick={setFilter} />}
|
||||||
type="url"
|
<MetricsTable
|
||||||
metric={<FormattedMessage id="metrics.views" defaultMessage="Views" />}
|
title={<FormattedMessage id="metrics.pages" defaultMessage="Pages" />}
|
||||||
headerComponent={
|
type="url"
|
||||||
limit ? null : <FilterButtons buttons={buttons} selected={filter} onClick={setFilter} />
|
metric={<FormattedMessage id="metrics.views" defaultMessage="Views" />}
|
||||||
}
|
websiteId={websiteId}
|
||||||
websiteId={websiteId}
|
token={token}
|
||||||
token={token}
|
limit={limit}
|
||||||
limit={limit}
|
dataFilter={urlFilter}
|
||||||
dataFilter={urlFilter}
|
filterOptions={{ domain: websiteDomain, raw: filter === FILTER_RAW }}
|
||||||
filterOptions={{ domain: websiteDomain, raw: filter === FILTER_RAW }}
|
renderLabel={({ x }) => decodeURI(x)}
|
||||||
renderLabel={({ x }) => decodeURI(x)}
|
onExpand={onExpand}
|
||||||
onExpand={onExpand}
|
/>
|
||||||
/>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const FilterButtons = ({ buttons, selected, onClick }) => {
|
const FilterButtons = ({ buttons, selected, onClick }) => {
|
||||||
return <ButtonGroup size="xsmall" items={buttons} selectedItem={selected} onClick={onClick} />;
|
return (
|
||||||
|
<ButtonLayout>
|
||||||
|
<ButtonGroup size="xsmall" items={buttons} selectedItem={selected} onClick={onClick} />
|
||||||
|
</ButtonLayout>
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
@ -4,6 +4,7 @@ import MetricsTable from './MetricsTable';
|
|||||||
import { refFilter } from 'lib/filters';
|
import { refFilter } from 'lib/filters';
|
||||||
import ButtonGroup from 'components/common/ButtonGroup';
|
import ButtonGroup from 'components/common/ButtonGroup';
|
||||||
import { FILTER_DOMAIN_ONLY, FILTER_COMBINED, FILTER_RAW } from 'lib/constants';
|
import { FILTER_DOMAIN_ONLY, FILTER_COMBINED, FILTER_RAW } from 'lib/constants';
|
||||||
|
import ButtonLayout from '../layout/ButtonLayout';
|
||||||
|
|
||||||
export default function ReferrersTable({
|
export default function ReferrersTable({
|
||||||
websiteId,
|
websiteId,
|
||||||
@ -37,29 +38,33 @@ export default function ReferrersTable({
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<MetricsTable
|
<>
|
||||||
title={<FormattedMessage id="metrics.referrers" defaultMessage="Referrers" />}
|
{!limit && <FilterButtons buttons={buttons} selected={filter} onClick={setFilter} />}
|
||||||
type="referrer"
|
<MetricsTable
|
||||||
metric={<FormattedMessage id="metrics.views" defaultMessage="Views" />}
|
title={<FormattedMessage id="metrics.referrers" defaultMessage="Referrers" />}
|
||||||
headerComponent={
|
type="referrer"
|
||||||
limit ? null : <FilterButtons buttons={buttons} selected={filter} onClick={setFilter} />
|
metric={<FormattedMessage id="metrics.views" defaultMessage="Views" />}
|
||||||
}
|
websiteId={websiteId}
|
||||||
websiteId={websiteId}
|
websiteDomain={websiteDomain}
|
||||||
websiteDomain={websiteDomain}
|
token={token}
|
||||||
token={token}
|
limit={limit}
|
||||||
limit={limit}
|
dataFilter={refFilter}
|
||||||
dataFilter={refFilter}
|
filterOptions={{
|
||||||
filterOptions={{
|
domain: websiteDomain,
|
||||||
domain: websiteDomain,
|
domainOnly: filter === FILTER_DOMAIN_ONLY,
|
||||||
domainOnly: filter === FILTER_DOMAIN_ONLY,
|
raw: filter === FILTER_RAW,
|
||||||
raw: filter === FILTER_RAW,
|
}}
|
||||||
}}
|
onExpand={onExpand}
|
||||||
onExpand={onExpand}
|
renderLabel={renderLink}
|
||||||
renderLabel={renderLink}
|
/>
|
||||||
/>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const FilterButtons = ({ buttons, selected, onClick }) => {
|
const FilterButtons = ({ buttons, selected, onClick }) => {
|
||||||
return <ButtonGroup size="xsmall" items={buttons} selectedItem={selected} onClick={onClick} />;
|
return (
|
||||||
|
<ButtonLayout>
|
||||||
|
<ButtonGroup size="xsmall" items={buttons} selectedItem={selected} onClick={onClick} />
|
||||||
|
</ButtonLayout>
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
@ -14,7 +14,7 @@ export default function WebsiteHeader({ websiteId, token, title, showLink = fals
|
|||||||
<PageHeader>
|
<PageHeader>
|
||||||
<div className={styles.title}>{title}</div>
|
<div className={styles.title}>{title}</div>
|
||||||
<ActiveUsers className={styles.active} websiteId={websiteId} token={token} />
|
<ActiveUsers className={styles.active} websiteId={websiteId} token={token} />
|
||||||
<ButtonLayout>
|
<ButtonLayout align="right">
|
||||||
<RefreshButton websiteId={websiteId} />
|
<RefreshButton websiteId={websiteId} />
|
||||||
{showLink && (
|
{showLink && (
|
||||||
<Link
|
<Link
|
||||||
|
@ -40,7 +40,7 @@ export default function AccountSettings() {
|
|||||||
|
|
||||||
const Buttons = row =>
|
const Buttons = row =>
|
||||||
row.username !== 'admin' ? (
|
row.username !== 'admin' ? (
|
||||||
<ButtonLayout>
|
<ButtonLayout align="right">
|
||||||
<Button icon={<Pen />} size="small" onClick={() => setEditAccount(row)}>
|
<Button icon={<Pen />} size="small" onClick={() => setEditAccount(row)}>
|
||||||
<div>
|
<div>
|
||||||
<FormattedMessage id="button.edit" defaultMessage="Edit" />
|
<FormattedMessage id="button.edit" defaultMessage="Edit" />
|
||||||
|
@ -1,3 +1,7 @@
|
|||||||
|
.button {
|
||||||
|
width: 50px;
|
||||||
|
}
|
||||||
|
|
||||||
.button svg {
|
.button svg {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
}
|
}
|
||||||
|
@ -32,7 +32,7 @@ export default function WebsiteSettings() {
|
|||||||
const { data } = useFetch(`/api/websites`, {}, { update: [saved] });
|
const { data } = useFetch(`/api/websites`, {}, { update: [saved] });
|
||||||
|
|
||||||
const Buttons = row => (
|
const Buttons = row => (
|
||||||
<ButtonLayout>
|
<ButtonLayout align="right">
|
||||||
{row.share_id && (
|
{row.share_id && (
|
||||||
<Button
|
<Button
|
||||||
icon={<LinkIcon />}
|
icon={<LinkIcon />}
|
||||||
|
@ -5,11 +5,11 @@ body {
|
|||||||
line-height: 1.8;
|
line-height: 1.8;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
height: 100%;
|
|
||||||
overflow: auto;
|
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
|
min-height: 100%;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
flex: 1;
|
||||||
|
|
||||||
font-size: var(--font-size-normal);
|
font-size: var(--font-size-normal);
|
||||||
color: var(--gray900);
|
color: var(--gray900);
|
||||||
@ -90,6 +90,8 @@ dd {
|
|||||||
|
|
||||||
main {
|
main {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
}
|
}
|
||||||
|
|
||||||
svg {
|
svg {
|
||||||
|
Loading…
Reference in New Issue
Block a user