mirror of
https://github.com/umami-software/umami.git
synced 2026-02-04 04:37:11 +01:00
Updated funnel edit form.
Some checks are pending
Node.js CI / build (postgresql, 18.18) (push) Waiting to run
Some checks are pending
Node.js CI / build (postgresql, 18.18) (push) Waiting to run
This commit is contained in:
parent
d534c0b221
commit
f0ec24e8f5
4 changed files with 492 additions and 108 deletions
|
|
@ -4,19 +4,19 @@ import {
|
|||
FormFieldArray,
|
||||
TextField,
|
||||
Grid,
|
||||
FormController,
|
||||
FormButtons,
|
||||
FormSubmitButton,
|
||||
Button,
|
||||
RadioGroup,
|
||||
Radio,
|
||||
Text,
|
||||
Icon,
|
||||
Row,
|
||||
Loading,
|
||||
Column,
|
||||
} from '@umami/react-zen';
|
||||
import { useMessages, useReportQuery, useUpdateQuery } from '@/components/hooks';
|
||||
import { File, Lightning, Close, Plus } from '@/components/icons';
|
||||
import { Close, Plus } from '@/components/icons';
|
||||
import { ActionSelect } from '@/components/input/ActionSelect';
|
||||
import { LookupField } from '@/components/input/LookupField';
|
||||
|
||||
const FUNNEL_STEPS_MAX = 8;
|
||||
|
||||
|
|
@ -41,6 +41,7 @@ export function FunnelEditForm({
|
|||
{
|
||||
onSuccess: async () => {
|
||||
touch('reports:funnel');
|
||||
touch(`report:${id}`);
|
||||
onSave?.();
|
||||
onClose?.();
|
||||
},
|
||||
|
|
@ -75,57 +76,38 @@ export function FunnelEditForm({
|
|||
<TextField />
|
||||
</FormField>
|
||||
<FormFieldArray name="steps" label={formatMessage(labels.steps)}>
|
||||
{({ fields, append, remove, control }) => {
|
||||
{({ fields, append, remove, getValues }) => {
|
||||
return (
|
||||
<Grid gap>
|
||||
{fields.map((field: { id: string; type: string; value: string }, index: number) => {
|
||||
{fields.map(({ id }: { id: string }, index: number) => {
|
||||
const type = getValues(`steps.${index}.type`);
|
||||
|
||||
return (
|
||||
<Row key={field.id} alignItems="center" justifyContent="space-between" gap>
|
||||
<FormController control={control} name={`steps.${index}.type`}>
|
||||
{({ field }) => {
|
||||
return (
|
||||
<RadioGroup
|
||||
orientation="horizontal"
|
||||
variant="box"
|
||||
value={field.value}
|
||||
onChange={field.onChange}
|
||||
>
|
||||
<Grid columns="1fr 1fr" flexGrow={1} gap>
|
||||
<Radio id="path" value="path">
|
||||
<Icon>
|
||||
<File />
|
||||
</Icon>
|
||||
<Text>{formatMessage(labels.page)}</Text>
|
||||
</Radio>
|
||||
<Radio id="event" value="event">
|
||||
<Icon>
|
||||
<Lightning />
|
||||
</Icon>
|
||||
<Text>{formatMessage(labels.event)}</Text>
|
||||
</Radio>
|
||||
</Grid>
|
||||
</RadioGroup>
|
||||
);
|
||||
}}
|
||||
</FormController>
|
||||
<FormController control={control} name={`steps.${index}.value`}>
|
||||
{({ field }) => {
|
||||
return (
|
||||
<TextField
|
||||
value={field.value}
|
||||
onChange={field.onChange}
|
||||
defaultValue={field.value}
|
||||
style={{ flexGrow: 1 }}
|
||||
/>
|
||||
);
|
||||
}}
|
||||
</FormController>
|
||||
<Button variant="quiet" onPress={() => remove(index)}>
|
||||
<Grid key={id} columns="260px 1fr auto" gap>
|
||||
<Column>
|
||||
<FormField
|
||||
name={`steps.${index}.type`}
|
||||
rules={{ required: formatMessage(labels.required) }}
|
||||
>
|
||||
<ActionSelect />
|
||||
</FormField>
|
||||
</Column>
|
||||
<Column>
|
||||
<FormField
|
||||
name={`steps.${index}.value`}
|
||||
rules={{ required: formatMessage(labels.required) }}
|
||||
>
|
||||
{({ field }) => {
|
||||
return <LookupField websiteId={websiteId} type={type} {...field} />;
|
||||
}}
|
||||
</FormField>
|
||||
</Column>
|
||||
<Button onPress={() => remove(index)}>
|
||||
<Icon size="sm">
|
||||
<Close />
|
||||
</Icon>
|
||||
</Button>
|
||||
</Row>
|
||||
</Grid>
|
||||
);
|
||||
})}
|
||||
<Row>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
import debug from 'debug';
|
||||
import { PrismaClient } from '@/generated/prisma/client';
|
||||
import { PrismaPg } from '@prisma/adapter-pg';
|
||||
import { readReplicas } from '@prisma/extension-read-replicas';
|
||||
import { UmamiPrismaClient } from '@umami/prisma-client';
|
||||
import { SESSION_COLUMNS, OPERATORS, DEFAULT_PAGE_SIZE, FILTER_COLUMNS } from './constants';
|
||||
import { QueryOptions, QueryFilters, Operator } from './types';
|
||||
import { filtersObjectToArray } from './params';
|
||||
|
|
@ -9,14 +8,6 @@ import { filtersObjectToArray } from './params';
|
|||
const log = debug('umami:prisma');
|
||||
|
||||
const PRISMA = 'prisma';
|
||||
const PRISMA_LOG_OPTIONS = {
|
||||
log: [
|
||||
{
|
||||
emit: 'event',
|
||||
level: 'query',
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const DATE_FORMATS = {
|
||||
minute: 'YYYY-MM-DD HH24:MI:00',
|
||||
|
|
@ -218,7 +209,7 @@ async function pagedQuery<T>(model: string, criteria: T, filters?: QueryFilters)
|
|||
return { data, count, page: +page, pageSize: size, orderBy, search };
|
||||
}
|
||||
|
||||
async function rawPagedQuery(
|
||||
async function pagedRawQuery(
|
||||
query: string,
|
||||
filters: QueryFilters,
|
||||
queryParams: Record<string, any>,
|
||||
|
|
@ -274,52 +265,18 @@ function transaction(input: any, options?: any) {
|
|||
return client.$transaction(input, options);
|
||||
}
|
||||
|
||||
function getClient(params?: {
|
||||
logQuery?: boolean;
|
||||
queryLogger?: () => void;
|
||||
replicaUrl?: string;
|
||||
options?: any;
|
||||
}): PrismaClient {
|
||||
const {
|
||||
logQuery = !!process.env.LOG_QUERY,
|
||||
queryLogger,
|
||||
replicaUrl = process.env.DATABASE_REPLICA_URL,
|
||||
options,
|
||||
} = params || {};
|
||||
|
||||
const url = new URL(process.env.DATABASE_URL);
|
||||
|
||||
const adapter = new PrismaPg(
|
||||
{ connectionString: url.toString() },
|
||||
{ schema: url.searchParams.get('schema') },
|
||||
);
|
||||
|
||||
const prisma = new PrismaClient({
|
||||
adapter,
|
||||
errorFormat: 'pretty',
|
||||
...(logQuery && PRISMA_LOG_OPTIONS),
|
||||
...options,
|
||||
function getClient() {
|
||||
const prisma = new UmamiPrismaClient({
|
||||
url: process.env.DATABASE_URL,
|
||||
prismaClient: PrismaClient,
|
||||
logQuery: !!process.env.LOG_QUERY,
|
||||
});
|
||||
|
||||
if (replicaUrl) {
|
||||
prisma.$extends(
|
||||
readReplicas({
|
||||
url: replicaUrl,
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
if (logQuery) {
|
||||
prisma.$on('query' as never, queryLogger || log);
|
||||
}
|
||||
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
globalThis[PRISMA] = prisma;
|
||||
globalThis[PRISMA] = prisma.client;
|
||||
}
|
||||
|
||||
log('Prisma initialized');
|
||||
|
||||
return prisma;
|
||||
return prisma.client;
|
||||
}
|
||||
|
||||
const client = globalThis[PRISMA] || getClient();
|
||||
|
|
@ -337,7 +294,7 @@ export default {
|
|||
getTimestampDiffSQL,
|
||||
getSearchSQL,
|
||||
pagedQuery,
|
||||
pagedRawQuery: rawPagedQuery,
|
||||
pagedRawQuery,
|
||||
parseFilters,
|
||||
rawQuery,
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue