mirror of
https://github.com/umami-software/umami.git
synced 2026-02-06 21:57:16 +01:00
Cohort selection.
This commit is contained in:
parent
05f9a67727
commit
bab4f8ebcc
32 changed files with 841 additions and 655 deletions
|
|
@ -33,7 +33,7 @@ export function LanguageSetting() {
|
|||
allowSearch
|
||||
onSearch={setSearch}
|
||||
onOpenChange={handleOpen}
|
||||
listProps={{ style: { maxHeight: '300px' } }}
|
||||
listProps={{ style: { maxHeight: 300 } }}
|
||||
>
|
||||
{items.map(item => (
|
||||
<ListItem key={item} id={item}>
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ export function TimezoneSetting() {
|
|||
allowSearch={true}
|
||||
onSearch={setSearch}
|
||||
onOpenChange={handleOpen}
|
||||
listProps={{ style: { maxHeight: '300px' } }}
|
||||
listProps={{ style: { maxHeight: 300 } }}
|
||||
>
|
||||
{items.map((item: any) => (
|
||||
<ListItem key={item} id={item}>
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import { useDateRange, useMessages } from '@/components/hooks';
|
|||
|
||||
export function AttributionPage({ websiteId }: { websiteId: string }) {
|
||||
const [model, setModel] = useState('first-click');
|
||||
const [type, setType] = useState('page');
|
||||
const [type, setType] = useState('path');
|
||||
const [step, setStep] = useState('/');
|
||||
const { formatMessage, labels } = useMessages();
|
||||
const {
|
||||
|
|
@ -36,7 +36,7 @@ export function AttributionPage({ websiteId }: { websiteId: string }) {
|
|||
defaultValue={type}
|
||||
onChange={setType}
|
||||
>
|
||||
<ListItem id="page">{formatMessage(labels.page)}</ListItem>
|
||||
<ListItem id="path">{formatMessage(labels.page)}</ListItem>
|
||||
<ListItem id="event">{formatMessage(labels.event)}</ListItem>
|
||||
</Select>
|
||||
</Column>
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ export function Funnel({ id, name, type, parameters, websiteId }) {
|
|||
{ type, value, visitors, previous, dropped, dropoff, remaining }: FunnelResult,
|
||||
index: number,
|
||||
) => {
|
||||
const isPage = type === 'page';
|
||||
const isPage = type === 'path';
|
||||
return (
|
||||
<Grid key={index} columns="auto 1fr" gap="6">
|
||||
<Column alignItems="center" position="relative">
|
||||
|
|
@ -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 === 'page' ? <File /> : <Lightning />}</Icon>
|
||||
<Icon>{type === 'path' ? <File /> : <Lightning />}</Icon>
|
||||
<Text>{value}</Text>
|
||||
</Row>
|
||||
<Row alignItems="center" gap>
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ export function FunnelEditForm({
|
|||
const defaultValues = {
|
||||
name: data?.name || '',
|
||||
window: data?.parameters?.window || 60,
|
||||
steps: data?.parameters?.steps || [{ type: 'page', value: '/' }],
|
||||
steps: data?.parameters?.steps || [{ type: 'path', value: '/' }],
|
||||
};
|
||||
|
||||
return (
|
||||
|
|
@ -91,7 +91,7 @@ export function FunnelEditForm({
|
|||
onChange={field.onChange}
|
||||
>
|
||||
<Grid columns="1fr 1fr" flexGrow={1} gap>
|
||||
<Radio id="page" value="page">
|
||||
<Radio id="path" value="path">
|
||||
<Icon>
|
||||
<File />
|
||||
</Icon>
|
||||
|
|
@ -130,7 +130,7 @@ export function FunnelEditForm({
|
|||
})}
|
||||
<Row>
|
||||
<Button
|
||||
onPress={() => append({ type: 'page', value: '/' })}
|
||||
onPress={() => append({ type: 'path', value: '/' })}
|
||||
isDisabled={fields.length >= FUNNEL_STEPS_MAX}
|
||||
>
|
||||
<Icon>
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ export function Goal({ id, name, type, parameters, websiteId, startDate, endDate
|
|||
endDate,
|
||||
...parameters,
|
||||
});
|
||||
const isPage = parameters?.type === 'page';
|
||||
const isPage = parameters?.type === 'path';
|
||||
|
||||
return (
|
||||
<LoadingPanel data={data} isLoading={isLoading} isFetching={isFetching} error={error}>
|
||||
|
|
@ -68,7 +68,7 @@ export function Goal({ id, name, type, parameters, websiteId, startDate, endDate
|
|||
</Row>
|
||||
<Row alignItems="center" justifyContent="space-between" gap>
|
||||
<Row alignItems="center" gap>
|
||||
<Icon>{parameters.type === 'page' ? <File /> : <Lightning />}</Icon>
|
||||
<Icon>{parameters.type === 'path' ? <File /> : <Lightning />}</Icon>
|
||||
<Text>{parameters.value}</Text>
|
||||
</Row>
|
||||
<Row alignItems="center" gap>
|
||||
|
|
|
|||
|
|
@ -16,9 +16,10 @@ export function GoalAddButton({ websiteId }: { websiteId: string }) {
|
|||
</Button>
|
||||
<Modal>
|
||||
<Dialog
|
||||
aria-label="add goal"
|
||||
variant="modal"
|
||||
title={formatMessage(labels.goal)}
|
||||
style={{ minHeight: 375, minWidth: 400 }}
|
||||
style={{ minWidth: 800, minHeight: 300 }}
|
||||
>
|
||||
{({ close }) => <GoalEditForm websiteId={websiteId} onClose={close} />}
|
||||
</Dialog>
|
||||
|
|
|
|||
|
|
@ -6,14 +6,13 @@ import {
|
|||
FormButtons,
|
||||
FormSubmitButton,
|
||||
Button,
|
||||
RadioGroup,
|
||||
Radio,
|
||||
Text,
|
||||
Icon,
|
||||
Loading,
|
||||
Column,
|
||||
Label,
|
||||
} from '@umami/react-zen';
|
||||
import { useMessages, useReportQuery, useUpdateQuery } from '@/components/hooks';
|
||||
import { File, Lightning } from '@/components/icons';
|
||||
import { LookupField } from '@/components/input/LookupField';
|
||||
import { ActionSelect } from '@/components/input/ActionSelect';
|
||||
|
||||
export function GoalEditForm({
|
||||
id,
|
||||
|
|
@ -27,13 +26,12 @@ export function GoalEditForm({
|
|||
onClose?: () => void;
|
||||
}) {
|
||||
const { formatMessage, labels } = useMessages();
|
||||
|
||||
const { data } = useReportQuery(id);
|
||||
const { mutate, error, isPending, touch } = useUpdateQuery(`/reports${id ? `/${id}` : ''}`);
|
||||
|
||||
const handleSubmit = async ({ name, ...parameters }) => {
|
||||
const handleSubmit = async (formData: Record<string, any>) => {
|
||||
mutate(
|
||||
{ ...data, id, name, type: 'goal', websiteId, parameters },
|
||||
{ ...formData, type: 'goal', websiteId },
|
||||
{
|
||||
onSuccess: async () => {
|
||||
if (id) touch(`report:${id}`);
|
||||
|
|
@ -50,15 +48,15 @@ export function GoalEditForm({
|
|||
}
|
||||
|
||||
const defaultValues = {
|
||||
name: data?.name || '',
|
||||
type: data?.parameters?.type || 'page',
|
||||
value: data?.parameters?.value || '',
|
||||
name: '',
|
||||
parameters: { type: 'path', value: '' },
|
||||
};
|
||||
|
||||
return (
|
||||
<Form onSubmit={handleSubmit} error={error?.message} defaultValues={defaultValues}>
|
||||
<Form onSubmit={handleSubmit} error={error?.message} defaultValues={data || defaultValues}>
|
||||
{({ watch }) => {
|
||||
const watchType = watch('type');
|
||||
const type = watch('parameters.type');
|
||||
|
||||
return (
|
||||
<>
|
||||
<FormField
|
||||
|
|
@ -68,35 +66,30 @@ export function GoalEditForm({
|
|||
>
|
||||
<TextField autoFocus />
|
||||
</FormField>
|
||||
<FormField
|
||||
name="type"
|
||||
label={formatMessage(labels.type)}
|
||||
rules={{ required: formatMessage(labels.required) }}
|
||||
>
|
||||
<RadioGroup orientation="horizontal" variant="box">
|
||||
<Grid columns="1fr 1fr" flexGrow={1} gap>
|
||||
<Radio value="page">
|
||||
<Icon>
|
||||
<File />
|
||||
</Icon>
|
||||
<Text>{formatMessage(labels.page)}</Text>
|
||||
</Radio>
|
||||
<Radio value="event">
|
||||
<Icon>
|
||||
<Lightning />
|
||||
</Icon>
|
||||
<Text>{formatMessage(labels.event)}</Text>
|
||||
</Radio>
|
||||
</Grid>
|
||||
</RadioGroup>
|
||||
</FormField>
|
||||
<FormField
|
||||
name="value"
|
||||
label={formatMessage(watchType === 'event' ? labels.eventName : labels.path)}
|
||||
rules={{ required: formatMessage(labels.required) }}
|
||||
>
|
||||
<TextField />
|
||||
</FormField>
|
||||
<Column>
|
||||
<Label>{formatMessage(labels.action)}</Label>
|
||||
<Grid columns="260px 1fr" gap>
|
||||
<Column>
|
||||
<FormField
|
||||
name="parameters.type"
|
||||
rules={{ required: formatMessage(labels.required) }}
|
||||
>
|
||||
<ActionSelect />
|
||||
</FormField>
|
||||
</Column>
|
||||
<Column>
|
||||
<FormField
|
||||
name="parameters.value"
|
||||
rules={{ required: formatMessage(labels.required) }}
|
||||
>
|
||||
{({ field }) => {
|
||||
return <LookupField websiteId={websiteId} type={type} {...field} />;
|
||||
}}
|
||||
</FormField>
|
||||
</Column>
|
||||
</Grid>
|
||||
</Column>
|
||||
|
||||
<FormButtons>
|
||||
<Button onPress={onClose} isDisabled={isPending}>
|
||||
{formatMessage(labels.cancel)}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import { Button, Icon, DialogTrigger, Dialog, Modal, Text } from '@umami/react-zen';
|
||||
import { ListFilter } from '@/components/icons';
|
||||
import { FilterEditForm } from '@/components/input/FilterEditForm';
|
||||
import { useMessages, useNavigation, useFilters } from '@/components/hooks';
|
||||
import { useMessages, useNavigation } from '@/components/hooks';
|
||||
import { filtersArrayToObject } from '@/lib/params';
|
||||
|
||||
export function WebsiteFilterButton({
|
||||
|
|
@ -14,17 +14,12 @@ export function WebsiteFilterButton({
|
|||
showText?: boolean;
|
||||
}) {
|
||||
const { formatMessage, labels } = useMessages();
|
||||
const {
|
||||
replaceParams,
|
||||
router,
|
||||
query: { segment },
|
||||
} = useNavigation();
|
||||
const { filters } = useFilters();
|
||||
const { replaceParams, router } = useNavigation();
|
||||
|
||||
const handleChange = ({ filters, segment }) => {
|
||||
const handleChange = ({ filters, segment, cohort }: any) => {
|
||||
const params = filtersArrayToObject(filters);
|
||||
|
||||
const url = replaceParams({ ...params, segment });
|
||||
const url = replaceParams({ ...params, segment, cohort });
|
||||
|
||||
router.push(url);
|
||||
};
|
||||
|
|
@ -40,15 +35,7 @@ export function WebsiteFilterButton({
|
|||
<Modal>
|
||||
<Dialog title={formatMessage(labels.filters)} style={{ width: 800, minHeight: 600 }}>
|
||||
{({ close }) => {
|
||||
return (
|
||||
<FilterEditForm
|
||||
websiteId={websiteId}
|
||||
filters={filters}
|
||||
segmentId={segment}
|
||||
onChange={handleChange}
|
||||
onClose={close}
|
||||
/>
|
||||
);
|
||||
return <FilterEditForm websiteId={websiteId} onChange={handleChange} onClose={close} />;
|
||||
}}
|
||||
</Dialog>
|
||||
</Modal>
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ import { WebsiteControls } from './WebsiteControls';
|
|||
export function WebsitePage({ websiteId }: { websiteId: string }) {
|
||||
const {
|
||||
router,
|
||||
query: { view, compare },
|
||||
query: { view },
|
||||
updateParams,
|
||||
} = useNavigation();
|
||||
const handleClose = (close: () => void) => {
|
||||
|
|
@ -30,7 +30,7 @@ export function WebsitePage({ websiteId }: { websiteId: string }) {
|
|||
<WebsiteControls websiteId={websiteId} />
|
||||
<WebsiteMetricsBar websiteId={websiteId} showChange={true} />
|
||||
<Panel minHeight="520px">
|
||||
<WebsiteChart websiteId={websiteId} compareMode={compare} />
|
||||
<WebsiteChart websiteId={websiteId} />
|
||||
</Panel>
|
||||
<WebsitePanels websiteId={websiteId} />
|
||||
<Modal isOpen={!!view} onOpenChange={handleOpenChange} isDismissable>
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ export function WebsitePanels({ websiteId }: { websiteId: string }) {
|
|||
showMore: true,
|
||||
metric: formatMessage(labels.visitors),
|
||||
};
|
||||
const rowProps = { minHeight: 570 };
|
||||
const rowProps = { minHeight: '570px' };
|
||||
|
||||
return (
|
||||
<Grid gap="3">
|
||||
|
|
|
|||
|
|
@ -15,10 +15,7 @@ export function CohortAddButton({ websiteId }: { websiteId: string }) {
|
|||
<Text>{formatMessage(labels.cohort)}</Text>
|
||||
</Button>
|
||||
<Modal>
|
||||
<Dialog
|
||||
title={formatMessage(labels.cohort)}
|
||||
style={{ width: 800, minHeight: 300, maxHeight: '90vh' }}
|
||||
>
|
||||
<Dialog title={formatMessage(labels.cohort)} style={{ width: 800, minHeight: 300 }}>
|
||||
{({ close }) => {
|
||||
return <CohortEditForm websiteId={websiteId} onClose={close} />;
|
||||
}}
|
||||
|
|
|
|||
|
|
@ -18,10 +18,7 @@ export function CohortEditButton({
|
|||
|
||||
return (
|
||||
<ActionButton title={formatMessage(labels.edit)} icon={<Edit />}>
|
||||
<Dialog
|
||||
title={formatMessage(labels.cohort)}
|
||||
style={{ width: 800, minHeight: 300, maxHeight: '90vh' }}
|
||||
>
|
||||
<Dialog title={formatMessage(labels.cohort)} style={{ width: 800, minHeight: 300 }}>
|
||||
{({ close }) => {
|
||||
return (
|
||||
<CohortEditForm
|
||||
|
|
|
|||
|
|
@ -8,23 +8,13 @@ import {
|
|||
Label,
|
||||
Loading,
|
||||
Column,
|
||||
ComboBox,
|
||||
Select,
|
||||
ListItem,
|
||||
Grid,
|
||||
useDebounce,
|
||||
} from '@umami/react-zen';
|
||||
import {
|
||||
useMessages,
|
||||
useUpdateQuery,
|
||||
useWebsiteCohortQuery,
|
||||
useWebsiteValuesQuery,
|
||||
} from '@/components/hooks';
|
||||
import { useMessages, useUpdateQuery, useWebsiteCohortQuery } from '@/components/hooks';
|
||||
import { DateFilter } from '@/components/input/DateFilter';
|
||||
import { FieldFilters } from '@/components/input/FieldFilters';
|
||||
import { SetStateAction, useMemo, useState } from 'react';
|
||||
import { endOfDay, subMonths } from 'date-fns';
|
||||
import { Empty } from '@/components/common/Empty';
|
||||
import { LookupField } from '@/components/input/LookupField';
|
||||
import { ActionSelect } from '@/components/input/ActionSelect';
|
||||
|
||||
export function CohortEditForm({
|
||||
cohortId,
|
||||
|
|
@ -40,21 +30,8 @@ export function CohortEditForm({
|
|||
onSave?: () => void;
|
||||
onClose?: () => void;
|
||||
}) {
|
||||
const [action, setAction] = useState('path');
|
||||
const [search, setSearch] = useState('');
|
||||
const searchValue = useDebounce(search, 300);
|
||||
const { data } = useWebsiteCohortQuery(websiteId, cohortId);
|
||||
const { formatMessage, labels, messages } = useMessages();
|
||||
const startDate = subMonths(endOfDay(new Date()), 6);
|
||||
const endDate = endOfDay(new Date());
|
||||
|
||||
const { data: searchResults, isLoading } = useWebsiteValuesQuery({
|
||||
websiteId,
|
||||
type: action,
|
||||
search: searchValue,
|
||||
startDate,
|
||||
endDate,
|
||||
});
|
||||
|
||||
const { mutate, error, isPending, touch, toast } = useUpdateQuery(
|
||||
`/websites/${websiteId}/segments${cohortId ? `/${cohortId}` : ''}`,
|
||||
|
|
@ -63,10 +40,6 @@ export function CohortEditForm({
|
|||
},
|
||||
);
|
||||
|
||||
const items: string[] = useMemo(() => {
|
||||
return searchResults?.map(({ value }) => value) || [];
|
||||
}, [searchResults]);
|
||||
|
||||
const handleSubmit = async (formData: any) => {
|
||||
mutate(formData, {
|
||||
onSuccess: async () => {
|
||||
|
|
@ -78,105 +51,84 @@ export function CohortEditForm({
|
|||
});
|
||||
};
|
||||
|
||||
const handleSearch = (value: SetStateAction<string>) => {
|
||||
setSearch(value);
|
||||
};
|
||||
|
||||
if (cohortId && !data) {
|
||||
return <Loading position="page" />;
|
||||
}
|
||||
|
||||
const defaultValues = {
|
||||
parameters: { filters, dateRange: '30day', action: { type: 'path', value: '' } },
|
||||
};
|
||||
|
||||
return (
|
||||
<Form
|
||||
error={error}
|
||||
onSubmit={handleSubmit}
|
||||
defaultValues={
|
||||
data || { parameters: { filters, dateRange: '30day', action: { type: 'path' } } }
|
||||
}
|
||||
>
|
||||
<FormField
|
||||
name="name"
|
||||
label={formatMessage(labels.name)}
|
||||
rules={{ required: formatMessage(labels.required) }}
|
||||
>
|
||||
<TextField autoFocus />
|
||||
</FormField>
|
||||
<Form error={error} onSubmit={handleSubmit} defaultValues={data || defaultValues}>
|
||||
{({ watch }) => {
|
||||
const type = watch('parameters.action.type');
|
||||
|
||||
<Column>
|
||||
<Label>{formatMessage(labels.action)}</Label>
|
||||
<Grid columns="260px 1fr" gap>
|
||||
<Column>
|
||||
return (
|
||||
<>
|
||||
<FormField
|
||||
name="parameters.action.type"
|
||||
name="name"
|
||||
label={formatMessage(labels.name)}
|
||||
rules={{ required: formatMessage(labels.required) }}
|
||||
>
|
||||
<Select onSelectionChange={(value: any) => setAction(value)}>
|
||||
<ListItem id="path">{formatMessage(labels.viewedPage)}</ListItem>
|
||||
<ListItem id="event">{formatMessage(labels.triggeredEvent)}</ListItem>
|
||||
</Select>
|
||||
<TextField autoFocus />
|
||||
</FormField>
|
||||
</Column>
|
||||
<Column>
|
||||
<FormField
|
||||
name="parameters.action.value"
|
||||
rules={{ required: formatMessage(labels.required) }}
|
||||
>
|
||||
{({ field }) => {
|
||||
return (
|
||||
<ComboBox
|
||||
aria-label="action"
|
||||
items={items}
|
||||
inputValue={field?.value}
|
||||
onInputChange={value => {
|
||||
handleSearch(value);
|
||||
field?.onChange?.(value);
|
||||
}}
|
||||
formValue="text"
|
||||
allowsEmptyCollection
|
||||
allowsCustomValue
|
||||
renderEmptyState={() =>
|
||||
isLoading ? (
|
||||
<Loading position="center" icon="dots" />
|
||||
) : (
|
||||
<Empty message={formatMessage(messages.noResultsFound)} />
|
||||
)
|
||||
}
|
||||
|
||||
<Column>
|
||||
<Label>{formatMessage(labels.action)}</Label>
|
||||
<Grid columns="260px 1fr" gap>
|
||||
<Column>
|
||||
<FormField
|
||||
name="parameters.action.type"
|
||||
rules={{ required: formatMessage(labels.required) }}
|
||||
>
|
||||
{items.map(item => (
|
||||
<ListItem key={item} id={item}>
|
||||
{item}
|
||||
</ListItem>
|
||||
))}
|
||||
</ComboBox>
|
||||
);
|
||||
}}
|
||||
</FormField>
|
||||
</Column>
|
||||
</Grid>
|
||||
</Column>
|
||||
<ActionSelect />
|
||||
</FormField>
|
||||
</Column>
|
||||
<Column>
|
||||
<FormField
|
||||
name="parameters.action.value"
|
||||
rules={{ required: formatMessage(labels.required) }}
|
||||
>
|
||||
{({ field }) => {
|
||||
return <LookupField websiteId={websiteId} type={type} {...field} />;
|
||||
}}
|
||||
</FormField>
|
||||
</Column>
|
||||
</Grid>
|
||||
</Column>
|
||||
|
||||
<Column width="260px">
|
||||
<Label>{formatMessage(labels.dateRange)}</Label>
|
||||
<FormField name="parameters.dateRange" rules={{ required: formatMessage(labels.required) }}>
|
||||
<DateFilter placement="bottom start" />
|
||||
</FormField>
|
||||
</Column>
|
||||
<Column width="260px">
|
||||
<Label>{formatMessage(labels.dateRange)}</Label>
|
||||
<FormField
|
||||
name="parameters.dateRange"
|
||||
rules={{ required: formatMessage(labels.required) }}
|
||||
>
|
||||
<DateFilter placement="bottom start" />
|
||||
</FormField>
|
||||
</Column>
|
||||
|
||||
<Column>
|
||||
<Label>{formatMessage(labels.filters)}</Label>
|
||||
<FormField name="parameters.filters" rules={{ required: formatMessage(labels.required) }}>
|
||||
<FieldFilters websiteId={websiteId} exclude={['path', 'event']} />
|
||||
</FormField>
|
||||
</Column>
|
||||
<Column>
|
||||
<Label>{formatMessage(labels.filters)}</Label>
|
||||
<FormField
|
||||
name="parameters.filters"
|
||||
rules={{ required: formatMessage(labels.required) }}
|
||||
>
|
||||
<FieldFilters websiteId={websiteId} exclude={['path', 'event']} />
|
||||
</FormField>
|
||||
</Column>
|
||||
|
||||
<FormButtons>
|
||||
<Button isDisabled={isPending} onPress={onClose}>
|
||||
{formatMessage(labels.cancel)}
|
||||
</Button>
|
||||
<FormSubmitButton variant="primary" data-test="button-submit" isDisabled={isPending}>
|
||||
{formatMessage(labels.save)}
|
||||
</FormSubmitButton>
|
||||
</FormButtons>
|
||||
<FormButtons>
|
||||
<Button isDisabled={isPending} onPress={onClose}>
|
||||
{formatMessage(labels.cancel)}
|
||||
</Button>
|
||||
<FormSubmitButton variant="primary" data-test="button-submit" isDisabled={isPending}>
|
||||
{formatMessage(labels.save)}
|
||||
</FormSubmitButton>
|
||||
</FormButtons>
|
||||
</>
|
||||
);
|
||||
}}
|
||||
</Form>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,10 +15,7 @@ export function SegmentAddButton({ websiteId }: { websiteId: string }) {
|
|||
<Text>{formatMessage(labels.segment)}</Text>
|
||||
</Button>
|
||||
<Modal>
|
||||
<Dialog
|
||||
title={formatMessage(labels.segment)}
|
||||
style={{ width: 800, minHeight: 300, maxHeight: '90vh' }}
|
||||
>
|
||||
<Dialog title={formatMessage(labels.segment)} style={{ width: 800, minHeight: 300 }}>
|
||||
{({ close }) => {
|
||||
return <SegmentEditForm websiteId={websiteId} onClose={close} />;
|
||||
}}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
import { Dialog } from '@umami/react-zen';
|
||||
import { ActionButton } from '@/components/input/ActionButton';
|
||||
import { Edit } from '@/components/icons';
|
||||
import { Dialog } from '@umami/react-zen';
|
||||
import { SegmentEditForm } from '@/app/(main)/websites/[websiteId]/segments/SegmentEditForm';
|
||||
import { useMessages } from '@/components/hooks';
|
||||
import { SegmentEditForm } from './SegmentEditForm';
|
||||
import { Filter } from '@/lib/types';
|
||||
|
||||
export function SegmentEditButton({
|
||||
|
|
@ -18,10 +18,7 @@ export function SegmentEditButton({
|
|||
|
||||
return (
|
||||
<ActionButton title={formatMessage(labels.edit)} icon={<Edit />}>
|
||||
<Dialog
|
||||
title={formatMessage(labels.segment)}
|
||||
style={{ width: 800, minHeight: 300, maxHeight: '90vh' }}
|
||||
>
|
||||
<Dialog title={formatMessage(labels.segment)} style={{ width: 800, minHeight: 300 }}>
|
||||
{({ close }) => {
|
||||
return (
|
||||
<SegmentEditForm
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ export async function POST(
|
|||
type,
|
||||
name,
|
||||
description,
|
||||
parameters: parameters,
|
||||
parameters,
|
||||
} as any);
|
||||
|
||||
return json(result);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue