diff --git a/components/common/FilterButtons.js b/components/common/FilterButtons.js index ba985110..4d08a132 100644 --- a/components/common/FilterButtons.js +++ b/components/common/FilterButtons.js @@ -1,9 +1,9 @@ import { ButtonGroup, Button, Flexbox } from 'react-basics'; -export default function FilterButtons({ items, selected, onSelect }) { +export default function FilterButtons({ items, selectedKey, onSelect }) { return ( - + {({ key, label }) => } diff --git a/components/metrics/DatePickerForm.js b/components/metrics/DatePickerForm.js index d5a6533b..17c7b5e5 100644 --- a/components/metrics/DatePickerForm.js +++ b/components/metrics/DatePickerForm.js @@ -7,9 +7,7 @@ import { getDateRangeValues } from 'lib/date'; import { getDateLocale } from 'lib/lang'; import { labels } from 'components/messages'; import styles from './DatePickerForm.module.css'; - -const FILTER_DAY = 'day'; -const FILTER_RANGE = 'range'; +import { FILTER_DAY, FILTER_RANGE } from 'lib/constants'; export default function DatePickerForm({ startDate: defaultStartDate, diff --git a/components/metrics/PagesTable.js b/components/metrics/PagesTable.js index fab22993..5f704318 100644 --- a/components/metrics/PagesTable.js +++ b/components/metrics/PagesTable.js @@ -5,9 +5,12 @@ import FilterButtons from 'components/common/FilterButtons'; import { urlFilter } from 'lib/filters'; import { labels } from 'components/messages'; import MetricsTable from './MetricsTable'; +import { FILTER_COMBINED, FILTER_RAW } from 'lib/constants'; -export const FILTER_COMBINED = 0; -export const FILTER_RAW = 1; +const filters = { + [FILTER_RAW]: null, + [FILTER_COMBINED]: urlFilter, +}; export default function PagesTable({ websiteId, showFilters, ...props }) { const [filter, setFilter] = useState(FILTER_COMBINED); @@ -16,11 +19,11 @@ export default function PagesTable({ websiteId, showFilters, ...props }) { const buttons = [ { label: formatMessage(labels.filterCombined), - value: FILTER_COMBINED, + key: FILTER_COMBINED, }, { label: formatMessage(labels.filterRaw), - value: FILTER_RAW, + key: FILTER_RAW, }, ]; @@ -30,13 +33,13 @@ export default function PagesTable({ websiteId, showFilters, ...props }) { return ( <> - {showFilters && } + {showFilters && } diff --git a/components/metrics/QueryParametersTable.js b/components/metrics/QueryParametersTable.js index 6743e6c6..ba6ad7cf 100644 --- a/components/metrics/QueryParametersTable.js +++ b/components/metrics/QueryParametersTable.js @@ -1,21 +1,17 @@ import { useState } from 'react'; -import { useIntl, defineMessages } from 'react-intl'; +import { useIntl } from 'react-intl'; import { safeDecodeURI } from 'next-basics'; import Tag from 'components/common/Tag'; import FilterButtons from 'components/common/FilterButtons'; import { paramFilter } from 'lib/filters'; +import { FILTER_RAW, FILTER_COMBINED } from 'lib/constants'; +import { labels } from 'components/messages'; import MetricsTable from './MetricsTable'; -const FILTER_COMBINED = 0; -const FILTER_RAW = 1; - -const messages = defineMessages({ - combined: { id: 'metrics.filter.combined', defaultMessage: 'Combined' }, - raw: { id: 'metrics.filter.raw', defaultMessage: 'Raw' }, - views: { id: 'metrics.views', defaultMessage: 'Views' }, - none: { id: 'label.none', defaultMessage: 'None' }, - query: { id: 'metrics.query-parameters', defaultMessage: 'Query parameters' }, -}); +const filters = { + [FILTER_RAW]: null, + [FILTER_COMBINED]: paramFilter, +}; export default function QueryParametersTable({ websiteId, showFilters, ...props }) { const [filter, setFilter] = useState(FILTER_COMBINED); @@ -23,22 +19,22 @@ export default function QueryParametersTable({ websiteId, showFilters, ...props const buttons = [ { - label: formatMessage(messages.combined), - value: FILTER_COMBINED, + label: formatMessage(labels.filterCombined), + key: FILTER_COMBINED, }, - { label: formatMessage(messages.raw), value: FILTER_RAW }, + { label: formatMessage(labels.filterRaw), key: FILTER_RAW }, ]; return ( <> - {showFilters && } + {showFilters && } filter === FILTER_RAW ? ( x diff --git a/components/metrics/RealtimeLog.js b/components/metrics/RealtimeLog.js index c2dbd202..d7a71ac8 100644 --- a/components/metrics/RealtimeLog.js +++ b/components/metrics/RealtimeLog.js @@ -54,19 +54,19 @@ export default function RealtimeLog({ data, websites, websiteId }) { const buttons = [ { label: , - value: TYPE_ALL, + key: TYPE_ALL, }, { label: , - value: TYPE_PAGEVIEW, + key: TYPE_PAGEVIEW, }, { label: , - value: TYPE_SESSION, + key: TYPE_SESSION, }, { label: , - value: TYPE_EVENT, + key: TYPE_EVENT, }, ]; @@ -165,7 +165,7 @@ export default function RealtimeLog({ data, websites, websiteId }) { return (
- +
diff --git a/components/metrics/RealtimeViews.js b/components/metrics/RealtimeViews.js index 155c2f07..19054837 100644 --- a/components/metrics/RealtimeViews.js +++ b/components/metrics/RealtimeViews.js @@ -4,9 +4,7 @@ import firstBy from 'thenby'; import { percentFilter } from 'lib/filters'; import DataTable from './DataTable'; import FilterButtons from 'components/common/FilterButtons'; - -const FILTER_REFERRERS = 0; -const FILTER_PAGES = 1; +import { FILTER_PAGES, FILTER_REFERRERS } from 'lib/constants'; export default function RealtimeViews({ websiteId, data, websites }) { const { pageviews } = data; @@ -23,11 +21,11 @@ export default function RealtimeViews({ websiteId, data, websites }) { const buttons = [ { label: , - value: FILTER_REFERRERS, + key: FILTER_REFERRERS, }, { label: , - value: FILTER_PAGES, + key: FILTER_PAGES, }, ]; @@ -90,7 +88,7 @@ export default function RealtimeViews({ websiteId, data, websites }) { return ( <> - + {filter === FILTER_REFERRERS && ( } diff --git a/components/metrics/ReferrersTable.js b/components/metrics/ReferrersTable.js index afc456d1..afbdecc0 100644 --- a/components/metrics/ReferrersTable.js +++ b/components/metrics/ReferrersTable.js @@ -5,9 +5,12 @@ import FilterButtons from 'components/common/FilterButtons'; import FilterLink from 'components/common/FilterLink'; import { refFilter } from 'lib/filters'; import { labels } from 'components/messages'; +import { FILTER_COMBINED, FILTER_RAW } from 'lib/constants'; -const FILTER_COMBINED = 0; -const FILTER_RAW = 1; +const filters = { + [FILTER_RAW]: null, + [FILTER_COMBINED]: refFilter, +}; export default function ReferrersTable({ websiteId, showFilters, ...props }) { const [filter, setFilter] = useState(FILTER_COMBINED); @@ -16,9 +19,9 @@ export default function ReferrersTable({ websiteId, showFilters, ...props }) { const items = [ { label: formatMessage(labels.filterCombined), - value: FILTER_COMBINED, + key: FILTER_COMBINED, }, - { label: formatMessage(labels.filterRaw), value: FILTER_RAW }, + { label: formatMessage(labels.filterRaw), key: FILTER_RAW }, ]; const renderLink = ({ w: link, x: referrer }) => { @@ -31,14 +34,14 @@ export default function ReferrersTable({ websiteId, showFilters, ...props }) { return ( <> - {showFilters && } + {showFilters && } diff --git a/components/pages/websites/WebsiteMenuView.js b/components/pages/websites/WebsiteMenuView.js index 464b3c1e..07a93268 100644 --- a/components/pages/websites/WebsiteMenuView.js +++ b/components/pages/websites/WebsiteMenuView.js @@ -1,4 +1,4 @@ -import { Row, Column, Menu, Item, Icon, Button } from 'react-basics'; +import { Row, Column, Menu, Item, Icon, Button, Flexbox, Text } from 'react-basics'; import { useIntl } from 'react-intl'; import Link from 'next/link'; import classNames from 'classnames'; @@ -39,44 +39,44 @@ export default function WebsiteMenuView({ websiteId, websiteDomain }) { const items = [ { + key: 'url', label: formatMessage(labels.pages), - value: resolve({ view: 'url' }), }, { + key: 'referrer', label: formatMessage(labels.referrers), - value: resolve({ view: 'referrer' }), }, { + key: 'browser', label: formatMessage(labels.browsers), - value: resolve({ view: 'browser' }), }, { + key: 'os', label: formatMessage(labels.os), - value: resolve({ view: 'os' }), }, { + key: 'device', label: formatMessage(labels.devices), - value: resolve({ view: 'device' }), }, { + key: 'country', label: formatMessage(labels.countries), - value: resolve({ view: 'country' }), }, { + key: 'language', label: formatMessage(labels.languages), - value: resolve({ view: 'language' }), }, { + key: 'screen', label: formatMessage(labels.screens), - value: resolve({ view: 'screen' }), }, { + key: 'event', label: formatMessage(labels.events), - value: resolve({ view: 'event' }), }, { + key: 'query', label: formatMessage(labels.query), - value: resolve({ view: 'query' }), }, ]; @@ -85,31 +85,37 @@ export default function WebsiteMenuView({ websiteId, websiteDomain }) { return ( - - - {({ value, label }) => ( - - + + + + + + + + + {({ key, label }) => ( + + {label} )} - + diff --git a/components/pages/websites/WebsiteMenuView.module.css b/components/pages/websites/WebsiteMenuView.module.css index 6084a12c..00e451c6 100644 --- a/components/pages/websites/WebsiteMenuView.module.css +++ b/components/pages/websites/WebsiteMenuView.module.css @@ -13,10 +13,19 @@ } .menu { - display: flex; gap: 20px; } -.menu a { +.item a { color: var(--font-color100); + flex: 1; + padding: var(--size300) var(--size600); +} + +.item { + padding: 0; +} + +.data { + min-height: 600px; } diff --git a/lib/constants.ts b/lib/constants.ts index 819fdff8..90f21388 100644 --- a/lib/constants.ts +++ b/lib/constants.ts @@ -25,6 +25,14 @@ export const REALTIME_INTERVAL = 3000; export const UI_LAYOUT_BODY = 'ui-layout-body'; +export const FILTER_COMBINED = 'filter-combined'; +export const FILTER_RAW = 'filter-raw'; +export const FILTER_IGNORED = 'filter-ignored'; +export const FILTER_DAY = 'filter-day'; +export const FILTER_RANGE = 'filter-range'; +export const FILTER_REFERRERS = 'filter-referrers'; +export const FILTER_PAGES = 'filter-pages'; + export const EVENT_TYPE = { pageView: 1, customEvent: 2, @@ -105,8 +113,6 @@ export const EVENT_COLORS = [ '#ffec16', ]; -export const FILTER_IGNORED = Symbol.for('filter-ignored'); - export const DOMAIN_REGEX = /^(localhost(:[1-9]\d{0,4})?|((?=[a-z0-9-]{1,63}\.)(xn--)?[a-z0-9]+(-[a-z0-9]+)*\.)+[a-z]{2,63})$/; diff --git a/lib/filters.js b/lib/filters.js index 4e7773f4..7e247220 100644 --- a/lib/filters.js +++ b/lib/filters.js @@ -1,15 +1,11 @@ export const urlFilter = data => { const isValidUrl = url => { - return url !== '' && url !== null && !url.startsWith('#'); + return url !== '' && url !== null; }; const cleanUrl = url => { try { - const { pathname, search } = new URL(url, location.origin); - - if (search.startsWith('?')) { - return `${pathname}${search}`; - } + const { pathname } = new URL(url, location.origin); return pathname; } catch { diff --git a/package.json b/package.json index 31f25fcd..a9cb51b0 100644 --- a/package.json +++ b/package.json @@ -93,7 +93,7 @@ "node-fetch": "^3.2.8", "npm-run-all": "^4.1.5", "react": "^18.2.0", - "react-basics": "^0.64.0", + "react-basics": "^0.66.0", "react-beautiful-dnd": "^13.1.0", "react-dom": "^18.2.0", "react-intl": "^5.24.7", diff --git a/yarn.lock b/yarn.lock index 96e53d7f..2a8d50c7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6676,10 +6676,10 @@ rc@^1.2.7: minimist "^1.2.0" strip-json-comments "~2.0.1" -react-basics@^0.64.0: - version "0.64.0" - resolved "https://registry.yarnpkg.com/react-basics/-/react-basics-0.64.0.tgz#b921dab7e437db6655f033cae15b8c963b93b7b2" - integrity sha512-MY/F5+VBqqi+Hx58PdRONoeu3W0sitPOFbvAGxiM9vpajQL1DD//0Xgl/MahW8sIDbMy00lFghouex5JS93C8Q== +react-basics@^0.66.0: + version "0.66.0" + resolved "https://registry.yarnpkg.com/react-basics/-/react-basics-0.66.0.tgz#c9d756936e9e996cbd70fb83e164fc673932fa0d" + integrity sha512-VKndXhIyWb/e080/TUXB2WnEfF/DSFSExer8AcxXJk58Illbg6bqMLjGuP2gtJ/dvr5skSPqm8b9gLVFU9C1ig== dependencies: classnames "^2.3.1" date-fns "^2.29.3"