mirror of
https://github.com/umami-software/umami.git
synced 2025-12-06 01:18:00 +01:00
Fixes for mobile.
This commit is contained in:
parent
bcafa12349
commit
9a5604f236
11 changed files with 38 additions and 58 deletions
|
|
@ -78,7 +78,7 @@
|
|||
"@react-spring/web": "^10.0.3",
|
||||
"@svgr/cli": "^8.1.0",
|
||||
"@tanstack/react-query": "^5.90.5",
|
||||
"@umami/react-zen": "^0.200.0",
|
||||
"@umami/react-zen": "^0.203.0",
|
||||
"@umami/redis-client": "^0.29.0",
|
||||
"bcryptjs": "^3.0.2",
|
||||
"chalk": "^5.6.2",
|
||||
|
|
|
|||
10
pnpm-lock.yaml
generated
10
pnpm-lock.yaml
generated
|
|
@ -45,8 +45,8 @@ importers:
|
|||
specifier: ^5.90.5
|
||||
version: 5.90.5(react@19.2.0)
|
||||
'@umami/react-zen':
|
||||
specifier: ^0.200.0
|
||||
version: 0.200.0(@babel/core@7.28.3)(@types/react@19.2.2)(babel-plugin-react-compiler@19.1.0-rc.2)(immer@10.1.3)(use-sync-external-store@1.6.0(react@19.2.0))
|
||||
specifier: ^0.203.0
|
||||
version: 0.203.0(@babel/core@7.28.3)(@types/react@19.2.2)(babel-plugin-react-compiler@19.1.0-rc.2)(immer@10.1.3)(use-sync-external-store@1.6.0(react@19.2.0))
|
||||
'@umami/redis-client':
|
||||
specifier: ^0.29.0
|
||||
version: 0.29.0
|
||||
|
|
@ -2921,8 +2921,8 @@ packages:
|
|||
resolution: {integrity: sha512-ptkmIf2iDkNUjdeu2bQqhFPV1m6qTnFFjg7PPDjxKWaMaP0Z6I9l30Jr3g5QqbZGdw8YdYvLp+XnqnWWZOg/NA==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
|
||||
'@umami/react-zen@0.200.0':
|
||||
resolution: {integrity: sha512-En5H5XpssItNPPSxb+xwGyMUalmqeoWCzMInGi/MJau/kkcJ2V0mSrgZ8RVRryl8cBg8fpktK7JaCTNULweUFA==}
|
||||
'@umami/react-zen@0.203.0':
|
||||
resolution: {integrity: sha512-lgGUapA0zDbLu63GINaEPndIsT8ry85vE316AWU/EEH3qYDBNscetcBfZFr+DTD/c5eLKy9OxmMwIpbs7k+/UA==}
|
||||
|
||||
'@umami/redis-client@0.29.0':
|
||||
resolution: {integrity: sha512-Jaqh++jskqDB7ny75pfC02OvKp1JTS4asGDsFrRL3qy8sxL3PAl9+/mybCJe4/6vWrXDJKqpgkSfUDJq2bFjyw==}
|
||||
|
|
@ -10670,7 +10670,7 @@ snapshots:
|
|||
'@typescript-eslint/types': 8.46.1
|
||||
eslint-visitor-keys: 4.2.1
|
||||
|
||||
'@umami/react-zen@0.200.0(@babel/core@7.28.3)(@types/react@19.2.2)(babel-plugin-react-compiler@19.1.0-rc.2)(immer@10.1.3)(use-sync-external-store@1.6.0(react@19.2.0))':
|
||||
'@umami/react-zen@0.203.0(@babel/core@7.28.3)(@types/react@19.2.2)(babel-plugin-react-compiler@19.1.0-rc.2)(immer@10.1.3)(use-sync-external-store@1.6.0(react@19.2.0))':
|
||||
dependencies:
|
||||
'@fontsource/jetbrains-mono': 5.2.8
|
||||
'@internationalized/date': 3.10.0
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ export function MobileNav() {
|
|||
];
|
||||
|
||||
return (
|
||||
<Grid columns="auto 1fr" flexGrow={1}>
|
||||
<Grid columns="auto 1fr" flexGrow={1} backgroundColor="3" borderRadius>
|
||||
<MobileMenuButton>
|
||||
{({ close }) => {
|
||||
return (
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { Dialog, Modal, useBreakpoint } from '@umami/react-zen';
|
||||
import { Dialog, Modal } from '@umami/react-zen';
|
||||
import { WebsiteExpandedView } from '@/app/(main)/websites/[websiteId]/WebsiteExpandedView';
|
||||
import { useNavigation } from '@/components/hooks';
|
||||
import { useNavigation, useMobile } from '@/components/hooks';
|
||||
|
||||
export function ExpandedViewModal({
|
||||
websiteId,
|
||||
|
|
@ -14,8 +14,7 @@ export function ExpandedViewModal({
|
|||
query: { view },
|
||||
updateParams,
|
||||
} = useNavigation();
|
||||
const breakpoint = useBreakpoint();
|
||||
const isMobile = ['xs', 'sm', 'md'].includes(breakpoint);
|
||||
const { isMobile } = useMobile();
|
||||
|
||||
const handleClose = (close: () => void) => {
|
||||
router.push(updateParams({ view: undefined }));
|
||||
|
|
|
|||
|
|
@ -6,9 +6,9 @@ import {
|
|||
cloneElement,
|
||||
isValidElement,
|
||||
} from 'react';
|
||||
import { SearchField, Row, Column, useBreakpoint } from '@umami/react-zen';
|
||||
import { SearchField, Row, Column } from '@umami/react-zen';
|
||||
import { UseQueryResult } from '@tanstack/react-query';
|
||||
import { useMessages, useNavigation } from '@/components/hooks';
|
||||
import { useMessages, useMobile, useNavigation } from '@/components/hooks';
|
||||
import { Pager } from '@/components/common/Pager';
|
||||
import { LoadingPanel } from '@/components/common/LoadingPanel';
|
||||
import { PageResult } from '@/lib/types';
|
||||
|
|
@ -42,8 +42,8 @@ export function DataGrid({
|
|||
const { router, updateParams, query: queryParams } = useNavigation();
|
||||
const [search, setSearch] = useState(queryParams?.search || data?.search || '');
|
||||
const showPager = allowPaging && data && data.count > data.pageSize;
|
||||
const breakpoint = useBreakpoint();
|
||||
const displayMode = ['xs', 'sm', 'md', 'lg'].includes(breakpoint) ? 'cards' : undefined;
|
||||
const { isMobile } = useMobile();
|
||||
const displayMode = isMobile ? 'cards' : undefined;
|
||||
|
||||
const handleSearch = (value: string) => {
|
||||
if (value !== search) {
|
||||
|
|
|
|||
|
|
@ -1,16 +1,8 @@
|
|||
import { useState, Key, Fragment } from 'react';
|
||||
import {
|
||||
Modal,
|
||||
Select,
|
||||
ListItem,
|
||||
ListSeparator,
|
||||
Dialog,
|
||||
SelectProps,
|
||||
useBreakpoint,
|
||||
} from '@umami/react-zen';
|
||||
import { Modal, Select, ListItem, ListSeparator, Dialog, SelectProps } from '@umami/react-zen';
|
||||
import { endOfYear } from 'date-fns';
|
||||
import { DatePickerForm } from '@/components/metrics/DatePickerForm';
|
||||
import { useMessages } from '@/components/hooks';
|
||||
import { useMessages, useMobile } from '@/components/hooks';
|
||||
import { DateDisplay } from '@/components/common/DateDisplay';
|
||||
import { parseDateRange } from '@/lib/date';
|
||||
|
||||
|
|
@ -33,8 +25,7 @@ export function DateFilter({
|
|||
const { formatMessage, labels } = useMessages();
|
||||
const [showPicker, setShowPicker] = useState(false);
|
||||
const { startDate, endDate } = parseDateRange(value) || {};
|
||||
const breakpoint = useBreakpoint();
|
||||
const isMobile = ['xs', 'sm', 'md'].includes(breakpoint);
|
||||
const { isMobile } = useMobile();
|
||||
|
||||
const options = [
|
||||
{ label: formatMessage(labels.today), value: '0day' },
|
||||
|
|
@ -119,7 +110,8 @@ export function DateFilter({
|
|||
placeholder={formatMessage(labels.selectDate)}
|
||||
onChange={handleChange}
|
||||
renderValue={renderValue}
|
||||
popoverProps={{ placement, isNonModal: isMobile }}
|
||||
popoverProps={{ placement }}
|
||||
isFullscreen={isMobile}
|
||||
>
|
||||
{options.map(({ label, value, divider }: any) => {
|
||||
return (
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ export function DialogButton({
|
|||
icon,
|
||||
label,
|
||||
title,
|
||||
width = '800px',
|
||||
width,
|
||||
height,
|
||||
minWidth,
|
||||
minHeight,
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import { useFilters, useMessages, useNavigation } from '@/components/hooks';
|
||||
import { useFilters, useMessages, useMobile, useNavigation } from '@/components/hooks';
|
||||
import { FieldFilters } from '@/components/input/FieldFilters';
|
||||
import { SegmentFilters } from '@/components/input/SegmentFilters';
|
||||
import { Button, Column, Row, Tab, TabList, TabPanel, Tabs, useBreakpoint } from '@umami/react-zen';
|
||||
import { Button, Column, Row, Tab, TabList, TabPanel, Tabs } from '@umami/react-zen';
|
||||
import { useState } from 'react';
|
||||
|
||||
export interface FilterEditFormProps {
|
||||
|
|
@ -20,8 +20,7 @@ export function FilterEditForm({ websiteId, onChange, onClose }: FilterEditFormP
|
|||
const [currentFilters, setCurrentFilters] = useState(filters);
|
||||
const [currentSegment, setCurrentSegment] = useState(segment);
|
||||
const [currentCohort, setCurrentCohort] = useState(cohort);
|
||||
const breakpoint = useBreakpoint();
|
||||
const isMobile = ['xs', 'sm', 'md'].includes(breakpoint);
|
||||
const { isMobile } = useMobile();
|
||||
const excludeFilters = pathname.includes('/pixels') || pathname.includes('/links');
|
||||
|
||||
const handleReset = () => {
|
||||
|
|
|
|||
|
|
@ -12,9 +12,14 @@ import {
|
|||
Column,
|
||||
Pressable,
|
||||
IconLabel,
|
||||
useBreakpoint,
|
||||
} from '@umami/react-zen';
|
||||
import { useConfig, useLoginQuery, useMessages, useNavigation } from '@/components/hooks';
|
||||
import {
|
||||
useConfig,
|
||||
useLoginQuery,
|
||||
useMessages,
|
||||
useMobile,
|
||||
useNavigation,
|
||||
} from '@/components/hooks';
|
||||
import {
|
||||
BookText,
|
||||
ChevronRight,
|
||||
|
|
@ -40,11 +45,10 @@ export function NavButton({ showText = true }: TeamsButtonProps) {
|
|||
const { cloudMode } = useConfig();
|
||||
const { formatMessage, labels } = useMessages();
|
||||
const { teamId } = useNavigation();
|
||||
const breakpoint = useBreakpoint();
|
||||
const { isMobile } = useMobile();
|
||||
const team = user?.teams?.find(({ id }) => id === teamId);
|
||||
const selectedKeys = new Set([teamId || 'user']);
|
||||
const label = teamId ? team?.name : user.username;
|
||||
const isMobile = ['xs', 'sm', 'md'].includes(breakpoint);
|
||||
|
||||
const getUrl = (url: string) => {
|
||||
return cloudMode ? `${process.env.cloudUrl}${url}` : url;
|
||||
|
|
|
|||
|
|
@ -1,22 +1,18 @@
|
|||
import { Button, Icon, DialogTrigger, Dialog, Text, Modal, useBreakpoint } from '@umami/react-zen';
|
||||
import { ListFilter } from '@/components/icons';
|
||||
import { FilterEditForm } from '@/components/input/FilterEditForm';
|
||||
import { DialogButton } from '@/components/input/DialogButton';
|
||||
import { useMessages, useNavigation } from '@/components/hooks';
|
||||
import { filtersArrayToObject } from '@/lib/params';
|
||||
|
||||
export function WebsiteFilterButton({
|
||||
websiteId,
|
||||
showText = true,
|
||||
}: {
|
||||
websiteId: string;
|
||||
position?: 'bottom' | 'top' | 'left' | 'right';
|
||||
alignment?: 'end' | 'center' | 'start';
|
||||
showText?: boolean;
|
||||
}) {
|
||||
const { formatMessage, labels } = useMessages();
|
||||
const { updateParams, router } = useNavigation();
|
||||
const breakpoint = useBreakpoint();
|
||||
const isMobile = ['xs', 'sm', 'md'].includes(breakpoint);
|
||||
|
||||
const handleChange = ({ filters, segment, cohort }: any) => {
|
||||
const params = filtersArrayToObject(filters);
|
||||
|
|
@ -27,20 +23,10 @@ export function WebsiteFilterButton({
|
|||
};
|
||||
|
||||
return (
|
||||
<DialogTrigger>
|
||||
<Button variant="outline">
|
||||
<Icon>
|
||||
<ListFilter />
|
||||
</Icon>
|
||||
{showText && <Text>{formatMessage(labels.filter)}</Text>}
|
||||
</Button>
|
||||
<Modal placement={isMobile ? 'fullscreen' : 'center'}>
|
||||
<Dialog title={formatMessage(labels.filters)}>
|
||||
{({ close }) => {
|
||||
return <FilterEditForm websiteId={websiteId} onChange={handleChange} onClose={close} />;
|
||||
}}
|
||||
</Dialog>
|
||||
</Modal>
|
||||
</DialogTrigger>
|
||||
<DialogButton icon={<ListFilter />} label={formatMessage(labels.filter)} variant="outline">
|
||||
{({ close }) => {
|
||||
return <FilterEditForm websiteId={websiteId} onChange={handleChange} onClose={close} />;
|
||||
}}
|
||||
</DialogButton>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ export function DatePickerForm({
|
|||
<Calendar value={date} minValue={minDate} maxValue={maxDate} onChange={setDate} />
|
||||
)}
|
||||
{selected.includes(FILTER_RANGE) && (
|
||||
<Row gap>
|
||||
<Row gap wrap="wrap" style={{ margin: '0 auto' }}>
|
||||
<Calendar
|
||||
value={startDate}
|
||||
minValue={minDate}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue