Fixed funnel report saving invalid data.
Some checks are pending
Node.js CI / build (postgresql, 18.18) (push) Waiting to run

This commit is contained in:
Mike Cao 2025-09-22 22:03:26 -07:00
parent bf16ade184
commit 980e4e6b41
11 changed files with 34 additions and 25 deletions

View file

@ -1,7 +1,7 @@
import { Grid, Column, Row, Text, Icon, ProgressBar, Dialog, Box } from '@umami/react-zen';
import { useMessages, useResultQuery } from '@/components/hooks';
import { LoadingPanel } from '@/components/common/LoadingPanel';
import { File, Lightning, User } from '@/components/icons';
import { File, LightningSvg, User } from '@/components/icons';
import { formatLongNumber } from '@/lib/format';
import { ReportEditButton } from '@/components/input/ReportEditButton';
import { FunnelEditForm } from './FunnelEditForm';
@ -92,7 +92,7 @@ export function Funnel({ id, name, type, parameters, websiteId }) {
</Row>
<Row alignItems="center" justifyContent="space-between" gap>
<Row alignItems="center" gap>
<Icon>{type === 'path' ? <File /> : <Lightning />}</Icon>
<Icon>{type === 'path' ? <File /> : <LightningSvg />}</Icon>
<Text>{value}</Text>
</Row>
<Row alignItems="center" gap>

View file

@ -14,7 +14,7 @@ import {
Column,
} from '@umami/react-zen';
import { useMessages, useReportQuery, useUpdateQuery } from '@/components/hooks';
import { Close, Plus } from '@/components/icons';
import { X, Plus } from '@/components/icons';
import { ActionSelect } from '@/components/input/ActionSelect';
import { LookupField } from '@/components/input/LookupField';
@ -36,6 +36,8 @@ export function FunnelEditForm({
const { mutate, error, isPending, touch } = useUpdateQuery(`/reports${id ? `/${id}` : ''}`);
const handleSubmit = async ({ name, ...parameters }) => {
//
mutate(
{ ...data, id, name, type: 'funnel', websiteId, parameters },
{
@ -75,7 +77,13 @@ export function FunnelEditForm({
>
<TextField />
</FormField>
<FormFieldArray name="steps" label={formatMessage(labels.steps)}>
<FormFieldArray
name="steps"
label={formatMessage(labels.steps)}
rules={{
validate: value => value.length > 1 || 'At least two steps are required',
}}
>
{({ fields, append, remove, getValues }) => {
return (
<Grid gap>
@ -104,7 +112,7 @@ export function FunnelEditForm({
</Column>
<Button onPress={() => remove(index)}>
<Icon size="sm">
<Close />
<X />
</Icon>
</Button>
</Grid>

View file

@ -3,7 +3,7 @@ import { TooltipTrigger, Tooltip, Focusable, Icon, Text, Row, Column } from '@um
import { firstBy } from 'thenby';
import classNames from 'classnames';
import { useEscapeKey, useMessages, useResultQuery } from '@/components/hooks';
import { File, Lightning } from '@/components/icons';
import { File, LightningSvg } from '@/components/icons';
import { objectToArray } from '@/lib/data';
import { formatLongNumber } from '@/lib/format';
import { LoadingPanel } from '@/components/common/LoadingPanel';
@ -215,7 +215,7 @@ export function Journey({ websiteId, steps, startStep, endStep }: JourneyProps)
onClick={() => handleClick(name, columnIndex, paths)}
>
<Row alignItems="center" className={styles.name} title={name} gap>
<Icon>{name.startsWith('/') ? <File /> : <Lightning />}</Icon>
<Icon>{name.startsWith('/') ? <File /> : <LightningSvg />}</Icon>
<Text truncate>{name}</Text>
</Row>
<div className={styles.count} title={nodeCount}>

View file

@ -3,12 +3,12 @@ import { useMessages, useNavigation } from '@/components/hooks';
import { MetricsExpandedTable } from '@/components/metrics/MetricsExpandedTable';
import { SideMenu } from '@/components/common/SideMenu';
import {
Link,
LogOut,
LogIn,
Search,
Type,
ArrowRight,
SquareSlash,
SquareArrowRight,
Megaphone,
Earth,
Globe,
@ -45,7 +45,7 @@ export function WebsiteExpandedView({
id: 'path',
label: formatMessage(labels.path),
path: updateParams({ view: 'path' }),
icon: <Link />,
icon: <SquareSlash />,
},
{
id: 'entry',
@ -80,7 +80,7 @@ export function WebsiteExpandedView({
id: 'referrer',
label: formatMessage(labels.referrer),
path: updateParams({ view: 'referrer' }),
icon: <ArrowRight />,
icon: <SquareArrowRight />,
},
{
id: 'channel',