Skip to content

Commit

Permalink
Merge pull request umami-software#2203 from umami-software/dev
Browse files Browse the repository at this point in the history
v2.5.0
  • Loading branch information
mikecao authored Aug 18, 2023
2 parents 3572df0 + fefea88 commit 7be4d56
Show file tree
Hide file tree
Showing 277 changed files with 21,983 additions and 11,263 deletions.
3 changes: 2 additions & 1 deletion .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,8 @@
"@next/next/no-img-element": "off",
"@typescript-eslint/no-empty-function": "off",
"@typescript-eslint/no-explicit-any": "off",
"@typescript-eslint/no-var-requires": "off"
"@typescript-eslint/no-var-requires": "off",
"@typescript-eslint/no-empty-interface": "off"
},
"globals": {
"React": "writable"
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/stale-issues.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,6 @@ jobs:
close-issue-message: 'This issue was closed because it has been inactive for 7 days since being marked as stale.'
days-before-pr-stale: -1
days-before-pr-close: -1
operations-per-run: 200
ascending: true
repo-token: ${{ secrets.GITHUB_TOKEN }}
1 change: 1 addition & 0 deletions assets/magnet.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
45 changes: 45 additions & 0 deletions components/common/Pager.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import styles from './Pager.module.css';
import { Button, Flexbox, Icon, Icons } from 'react-basics';
import useMessages from 'hooks/useMessages';

export function Pager({ page, pageSize, count, onPageChange }) {
const { formatMessage, labels } = useMessages();
const maxPage = Math.ceil(count / pageSize);
const lastPage = page === maxPage;
const firstPage = page === 1;

if (count === 0) {
return null;
}

const handlePageChange = value => {
const nextPage = page + value;
if (nextPage > 0 && nextPage <= maxPage) {
onPageChange(nextPage);
}
};

if (maxPage === 1) {
return null;
}

return (
<Flexbox justifyContent="center" className={styles.container}>
<Button onClick={() => handlePageChange(-1)} disabled={firstPage}>
<Icon rotate={90}>
<Icons.ChevronDown />
</Icon>
</Button>
<Flexbox alignItems="center" className={styles.text}>
{formatMessage(labels.pageOf, { current: page, total: maxPage })}
</Flexbox>
<Button onClick={() => handlePageChange(1)} disabled={lastPage}>
<Icon rotate={270}>
<Icons.ChevronDown />
</Icon>
</Button>
</Flexbox>
);
}

export default Pager;
7 changes: 7 additions & 0 deletions components/common/Pager.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
.container {
margin-top: 20px;
}

.text {
margin: 0 16px;
}
122 changes: 92 additions & 30 deletions components/common/SettingsTable.js
Original file line number Diff line number Diff line change
@@ -1,37 +1,99 @@
import { Table, TableHeader, TableBody, TableRow, TableCell, TableColumn } from 'react-basics';
import EmptyPlaceholder from 'components/common/EmptyPlaceholder';
import useMessages from 'hooks/useMessages';
import { useState } from 'react';
import {
SearchField,
Table,
TableBody,
TableCell,
TableColumn,
TableHeader,
TableRow,
} from 'react-basics';
import styles from './SettingsTable.module.css';
import Pager from 'components/common/Pager';

export function SettingsTable({
columns = [],
data,
children,
cellRender,
showSearch,
showPaging,
onFilterChange,
onPageChange,
onPageSizeChange,
filterValue,
}) {
const { formatMessage, messages } = useMessages();
const [filter, setFilter] = useState(filterValue);
const { data: value, page, count, pageSize } = data;

const handleFilterChange = value => {
setFilter(value);
onFilterChange(value);
};

export function SettingsTable({ columns = [], data = [], children, cellRender }) {
return (
<Table columns={columns} rows={data}>
<TableHeader className={styles.header}>
{(column, index) => {
return (
<TableColumn key={index} className={styles.cell} style={columns[index].style}>
{column.label}
</TableColumn>
);
}}
</TableHeader>
<TableBody className={styles.body}>
{(row, keys, rowIndex) => {
row.action = children(row, keys, rowIndex);
<>
{showSearch && (
<SearchField
onChange={handleFilterChange}
delay={1000}
value={filter}
autoFocus={true}
placeholder="Search"
style={{ maxWidth: '300px', marginBottom: '10px' }}
/>
)}
{value.length === 0 && filterValue && (
<EmptyPlaceholder message={formatMessage(messages.noResultsFound)}></EmptyPlaceholder>
)}
{value.length > 0 && (
<Table columns={columns} rows={value}>
<TableHeader className={styles.header}>
{(column, index) => {
return (
<TableColumn key={index} className={styles.cell} style={columns[index].style}>
{column.label}
</TableColumn>
);
}}
</TableHeader>
<TableBody className={styles.body}>
{(row, keys, rowIndex) => {
row.action = children(row, keys, rowIndex);

return (
<TableRow key={rowIndex} data={row} keys={keys} className={styles.row}>
{(data, key, colIndex) => {
return (
<TableCell key={colIndex} className={styles.cell} style={columns[colIndex].style}>
<label className={styles.label}>{columns[colIndex].label}</label>
{cellRender ? cellRender(row, data, key, colIndex) : data[key]}
</TableCell>
);
}}
</TableRow>
);
}}
</TableBody>
</Table>
return (
<TableRow key={rowIndex} data={row} keys={keys} className={styles.row}>
{(data, key, colIndex) => {
return (
<TableCell
key={colIndex}
className={styles.cell}
style={columns[colIndex].style}
>
<label className={styles.label}>{columns[colIndex].label}</label>
{cellRender ? cellRender(row, data, key, colIndex) : data[key]}
</TableCell>
);
}}
</TableRow>
);
}}
</TableBody>
{showPaging && (
<Pager
page={page}
pageSize={pageSize}
count={count}
onPageChange={onPageChange}
onPageSizeChange={onPageSizeChange}
/>
)}
</Table>
)}
</>
);
}

Expand Down
2 changes: 2 additions & 0 deletions components/icons.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import Gear from 'assets/gear.svg';
import Globe from 'assets/globe.svg';
import Lock from 'assets/lock.svg';
import Logo from 'assets/logo.svg';
import Magnet from 'assets/magnet.svg';
import Moon from 'assets/moon.svg';
import Nodes from 'assets/nodes.svg';
import Overview from 'assets/overview.svg';
Expand All @@ -35,6 +36,7 @@ const icons = {
Globe,
Lock,
Logo,
Magnet,
Moon,
Nodes,
Overview,
Expand Down
6 changes: 3 additions & 3 deletions components/input/DateFilter.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { Icon, Modal, Dropdown, Item, Text, Flexbox } from 'react-basics';
import { endOfYear, isSameDay } from 'date-fns';
import DatePickerForm from 'components/metrics/DatePickerForm';
import useLocale from 'hooks/useLocale';
import { dateFormat } from 'lib/date';
import { formatDate } from 'lib/date';
import Icons from 'components/icons';
import useMessages from 'hooks/useMessages';

Expand Down Expand Up @@ -135,8 +135,8 @@ const CustomRange = ({ startDate, endDate, onClick }) => {
<Icons.Calendar />
</Icon>
<Text>
{dateFormat(startDate, 'd LLL y', locale)}
{!isSameDay(startDate, endDate) && ` — ${dateFormat(endDate, 'd LLL y', locale)}`}
{formatDate(startDate, 'd LLL y', locale)}
{!isSameDay(startDate, endDate) && ` — ${formatDate(endDate, 'd LLL y', locale)}`}
</Text>
</Flexbox>
);
Expand Down
71 changes: 71 additions & 0 deletions components/input/MonthSelect.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import { useRef } from 'react';
import {
Text,
Icon,
CalendarMonthSelect,
CalendarYearSelect,
Button,
PopupTrigger,
Popup,
} from 'react-basics';
import { startOfMonth, endOfMonth } from 'date-fns';
import Icons from 'components/icons';
import { useLocale } from 'hooks';
import { formatDate } from 'lib/date';
import { getDateLocale } from 'lib/lang';
import styles from './MonthSelect.module.css';

export function MonthSelect({ date = new Date(), onChange }) {
const { locale } = useLocale();
const month = formatDate(date, 'MMMM', locale);
const year = date.getFullYear();
const ref = useRef();

const handleChange = (close, date) => {
onChange(`range:${startOfMonth(date).getTime()}:${endOfMonth(date).getTime()}`);
close();
};

return (
<>
<div ref={ref} className={styles.container}>
<PopupTrigger>
<Button className={styles.input} variant="quiet">
<Text>{month}</Text>
<Icon size="sm">
<Icons.ChevronDown />
</Icon>
</Button>
<Popup className={styles.popup} alignment="start">
{close => (
<CalendarMonthSelect
date={date}
locale={getDateLocale(locale)}
onSelect={handleChange.bind(null, close)}
/>
)}
</Popup>
</PopupTrigger>
<PopupTrigger>
<Button className={styles.input} variant="quiet">
<Text>{year}</Text>
<Icon size="sm">
<Icons.ChevronDown />
</Icon>
</Button>
<Popup className={styles.popup} alignment="start">
{close => (
<CalendarYearSelect
date={date}
locale={getDateLocale(locale)}
onSelect={handleChange.bind(null, close)}
/>
)}
</Popup>
</PopupTrigger>
</div>
</>
);
}

export default MonthSelect;
22 changes: 22 additions & 0 deletions components/input/MonthSelect.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
.container {
display: flex;
align-items: center;
justify-content: center;
border: 1px solid var(--base400);
border-radius: var(--border-radius);
}

.input {
display: flex;
align-items: center;
gap: 10px;
cursor: pointer;
}

.popup {
border: 1px solid var(--base400);
background: var(--base50);
border-radius: var(--border-radius);
padding: 20px;
margin-top: 5px;
}
4 changes: 2 additions & 2 deletions components/input/WebsiteSelect.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@ export function WebsiteSelect({ websiteId, onSelect }) {
const { data } = useQuery(['websites:me'], () => get('/me/websites'));

const renderValue = value => {
return data?.find(({ id }) => id === value)?.name;
return data?.data?.find(({ id }) => id === value)?.name;
};

return (
<Dropdown
items={data}
items={data?.data}
value={websiteId}
renderValue={renderValue}
onChange={onSelect}
Expand Down
6 changes: 2 additions & 4 deletions components/layout/AppLayout.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@ import { Container } from 'react-basics';
import Head from 'next/head';
import NavBar from 'components/layout/NavBar';
import UpdateNotice from 'components/common/UpdateNotice';
import useRequireLogin from 'hooks/useRequireLogin';
import useConfig from 'hooks/useConfig';
import { CURRENT_VERSION } from 'lib/constants';
import { useRequireLogin, useConfig } from 'hooks';
import styles from './AppLayout.module.css';

export function AppLayout({ title, children }) {
Expand All @@ -16,7 +14,7 @@ export function AppLayout({ title, children }) {
}

return (
<div className={styles.layout} data-app-version={CURRENT_VERSION}>
<div className={styles.layout}>
<UpdateNotice user={user} config={config} />
<Head>
<title>{title ? `${title} | umami` : 'umami'}</title>
Expand Down
1 change: 1 addition & 0 deletions components/layout/AppLayout.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
width: 100vw;
grid-column: 1;
grid-row: 1 / 2;
z-index: 1;
}

.body {
Expand Down
2 changes: 2 additions & 0 deletions components/layout/NavBar.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ export function NavBar() {

const links = [
{ label: formatMessage(labels.dashboard), url: '/dashboard' },
{ label: formatMessage(labels.websites), url: '/websites' },
{ label: formatMessage(labels.reports), url: '/reports' },
!cloudMode && { label: formatMessage(labels.settings), url: '/settings' },
].filter(n => n);

Expand Down
1 change: 1 addition & 0 deletions components/layout/SettingsLayout.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
display: flex;
flex-direction: column;
padding-top: 40px;
padding-right: 20px;
}

.content {
Expand Down
Loading

1 comment on commit 7be4d56

@vercel
Copy link

@vercel vercel bot commented on 7be4d56 Aug 28, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.