Fixes for mobile.
Some checks are pending
Create docker images (cloud) / Build, push, and deploy (push) Waiting to run
Node.js CI / build (postgresql, 18.18, 10) (push) Waiting to run

This commit is contained in:
Mike Cao 2025-10-18 01:12:45 -07:00
parent bcafa12349
commit 9a5604f236
11 changed files with 38 additions and 58 deletions

View file

@ -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 (

View file

@ -25,7 +25,7 @@ export function DialogButton({
icon,
label,
title,
width = '800px',
width,
height,
minWidth,
minHeight,

View file

@ -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 = () => {

View file

@ -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;

View file

@ -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>
);
}