mirror of
https://github.com/umami-software/umami.git
synced 2026-02-16 10:35:35 +01:00
Compare commits
5 commits
980e4e6b41
...
ee70baaeb7
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ee70baaeb7 | ||
|
|
b115131f4c | ||
|
|
f639bb07f4 | ||
|
|
4df6f06485 | ||
|
|
6faf16e9aa |
41 changed files with 126 additions and 125 deletions
|
|
@ -13,11 +13,11 @@ import { useMessages, useUpdateQuery } from '@/components/hooks';
|
||||||
import { ROLES } from '@/lib/constants';
|
import { ROLES } from '@/lib/constants';
|
||||||
|
|
||||||
export function UserAddForm({ onSave, onClose }) {
|
export function UserAddForm({ onSave, onClose }) {
|
||||||
const { mutate, error, isPending } = useUpdateQuery(`/users`);
|
const { mutateAsync, error, isPending } = useUpdateQuery(`/users`);
|
||||||
const { formatMessage, labels, getErrorMessage } = useMessages();
|
const { formatMessage, labels, getErrorMessage } = useMessages();
|
||||||
|
|
||||||
const handleSubmit = async (data: any) => {
|
const handleSubmit = async (data: any) => {
|
||||||
mutate(data, {
|
await mutateAsync(data, {
|
||||||
onSuccess: async () => {
|
onSuccess: async () => {
|
||||||
onSave(data);
|
onSave(data);
|
||||||
onClose();
|
onClose();
|
||||||
|
|
|
||||||
|
|
@ -13,11 +13,11 @@ export function UserDeleteForm({
|
||||||
onClose?: () => void;
|
onClose?: () => void;
|
||||||
}) {
|
}) {
|
||||||
const { messages, labels, formatMessage } = useMessages();
|
const { messages, labels, formatMessage } = useMessages();
|
||||||
const { mutate } = useDeleteQuery(`/users/${userId}`);
|
const { mutateAsync } = useDeleteQuery(`/users/${userId}`);
|
||||||
const { touch } = useModified();
|
const { touch } = useModified();
|
||||||
|
|
||||||
const handleConfirm = async () => {
|
const handleConfirm = async () => {
|
||||||
mutate(null, {
|
await mutateAsync(null, {
|
||||||
onSuccess: async () => {
|
onSuccess: async () => {
|
||||||
touch('users');
|
touch('users');
|
||||||
touch(`users:${userId}`);
|
touch(`users:${userId}`);
|
||||||
|
|
|
||||||
|
|
@ -16,10 +16,10 @@ export function UserEditForm({ userId, onSave }: { userId: string; onSave?: () =
|
||||||
const user = useUser();
|
const user = useUser();
|
||||||
const { user: login } = useLoginQuery();
|
const { user: login } = useLoginQuery();
|
||||||
|
|
||||||
const { mutate, error, toast, touch } = useUpdateQuery(`/users/${userId}`);
|
const { mutateAsync, error, toast, touch } = useUpdateQuery(`/users/${userId}`);
|
||||||
|
|
||||||
const handleSubmit = async (data: any) => {
|
const handleSubmit = async (data: any) => {
|
||||||
mutate(data, {
|
await mutateAsync(data, {
|
||||||
onSuccess: async () => {
|
onSuccess: async () => {
|
||||||
toast(formatMessage(messages.saved));
|
toast(formatMessage(messages.saved));
|
||||||
touch(`user:${user.id}`);
|
touch(`user:${user.id}`);
|
||||||
|
|
|
||||||
|
|
@ -13,10 +13,10 @@ export function BoardAddForm({
|
||||||
onClose?: () => void;
|
onClose?: () => void;
|
||||||
}) {
|
}) {
|
||||||
const { formatMessage, labels, messages } = useMessages();
|
const { formatMessage, labels, messages } = useMessages();
|
||||||
const { mutate, error, isPending } = useUpdateQuery('/websites', { teamId });
|
const { mutateAsync, error, isPending } = useUpdateQuery('/websites', { teamId });
|
||||||
|
|
||||||
const handleSubmit = async (data: any) => {
|
const handleSubmit = async (data: any) => {
|
||||||
mutate(data, {
|
await mutateAsync(data, {
|
||||||
onSuccess: async () => {
|
onSuccess: async () => {
|
||||||
onSave?.();
|
onSave?.();
|
||||||
onClose?.();
|
onClose?.();
|
||||||
|
|
|
||||||
|
|
@ -16,10 +16,10 @@ export function LinkDeleteButton({
|
||||||
onSave?: () => void;
|
onSave?: () => void;
|
||||||
}) {
|
}) {
|
||||||
const { formatMessage, labels, getErrorMessage } = useMessages();
|
const { formatMessage, labels, getErrorMessage } = useMessages();
|
||||||
const { mutate, isPending, error, touch } = useDeleteQuery(`/links/${linkId}`);
|
const { mutateAsync, isPending, error, touch } = useDeleteQuery(`/links/${linkId}`);
|
||||||
|
|
||||||
const handleConfirm = (close: () => void) => {
|
const handleConfirm = async (close: () => void) => {
|
||||||
mutate(null, {
|
await mutateAsync(null, {
|
||||||
onSuccess: () => {
|
onSuccess: () => {
|
||||||
touch('links');
|
touch('links');
|
||||||
onSave?.();
|
onSave?.();
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,7 @@ export function LinkEditForm({
|
||||||
onClose?: () => void;
|
onClose?: () => void;
|
||||||
}) {
|
}) {
|
||||||
const { formatMessage, labels, messages, getErrorMessage } = useMessages();
|
const { formatMessage, labels, messages, getErrorMessage } = useMessages();
|
||||||
const { mutate, error, isPending, touch, toast } = useUpdateQuery(
|
const { mutateAsync, error, isPending, touch, toast } = useUpdateQuery(
|
||||||
linkId ? `/links/${linkId}` : '/links',
|
linkId ? `/links/${linkId}` : '/links',
|
||||||
{
|
{
|
||||||
id: linkId,
|
id: linkId,
|
||||||
|
|
@ -46,7 +46,7 @@ export function LinkEditForm({
|
||||||
const [slug, setSlug] = useState(generateId());
|
const [slug, setSlug] = useState(generateId());
|
||||||
|
|
||||||
const handleSubmit = async (data: any) => {
|
const handleSubmit = async (data: any) => {
|
||||||
mutate(data, {
|
await mutateAsync(data, {
|
||||||
onSuccess: async () => {
|
onSuccess: async () => {
|
||||||
toast(formatMessage(messages.saved));
|
toast(formatMessage(messages.saved));
|
||||||
touch('links');
|
touch('links');
|
||||||
|
|
@ -139,9 +139,7 @@ export function LinkEditForm({
|
||||||
{formatMessage(labels.cancel)}
|
{formatMessage(labels.cancel)}
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
<FormSubmitButton isDisabled={false} isLoading={isPending}>
|
<FormSubmitButton>{formatMessage(labels.save)}</FormSubmitButton>
|
||||||
{formatMessage(labels.save)}
|
|
||||||
</FormSubmitButton>
|
|
||||||
</Row>
|
</Row>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -14,11 +14,11 @@ export function PixelDeleteButton({
|
||||||
onSave?: () => void;
|
onSave?: () => void;
|
||||||
}) {
|
}) {
|
||||||
const { formatMessage, labels, getErrorMessage } = useMessages();
|
const { formatMessage, labels, getErrorMessage } = useMessages();
|
||||||
const { mutate, isPending, error } = useDeleteQuery(`/pixels/${pixelId}`);
|
const { mutateAsync, isPending, error } = useDeleteQuery(`/pixels/${pixelId}`);
|
||||||
const { touch } = useModified();
|
const { touch } = useModified();
|
||||||
|
|
||||||
const handleConfirm = (close: () => void) => {
|
const handleConfirm = async (close: () => void) => {
|
||||||
mutate(null, {
|
await mutateAsync(null, {
|
||||||
onSuccess: () => {
|
onSuccess: () => {
|
||||||
touch('pixels');
|
touch('pixels');
|
||||||
onSave?.();
|
onSave?.();
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ export function PixelEditButton({ pixelId }: { pixelId: string }) {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ActionButton title={formatMessage(labels.edit)} icon={<Edit />}>
|
<ActionButton title={formatMessage(labels.edit)} icon={<Edit />}>
|
||||||
<Dialog title={formatMessage(labels.pixel)} style={{ width: 800, minHeight: 300 }}>
|
<Dialog title={formatMessage(labels.pixel)} style={{ width: 600, minHeight: 300 }}>
|
||||||
{({ close }) => {
|
{({ close }) => {
|
||||||
return <PixelEditForm pixelId={pixelId} onClose={close} />;
|
return <PixelEditForm pixelId={pixelId} onClose={close} />;
|
||||||
}}
|
}}
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@ export function PixelEditForm({
|
||||||
onClose?: () => void;
|
onClose?: () => void;
|
||||||
}) {
|
}) {
|
||||||
const { formatMessage, labels, messages, getErrorMessage } = useMessages();
|
const { formatMessage, labels, messages, getErrorMessage } = useMessages();
|
||||||
const { mutate, error, isPending, touch, toast } = useUpdateQuery(
|
const { mutateAsync, error, isPending, touch, toast } = useUpdateQuery(
|
||||||
pixelId ? `/pixels/${pixelId}` : '/pixels',
|
pixelId ? `/pixels/${pixelId}` : '/pixels',
|
||||||
{
|
{
|
||||||
id: pixelId,
|
id: pixelId,
|
||||||
|
|
@ -45,7 +45,7 @@ export function PixelEditForm({
|
||||||
const [slug, setSlug] = useState(generateId());
|
const [slug, setSlug] = useState(generateId());
|
||||||
|
|
||||||
const handleSubmit = async (data: any) => {
|
const handleSubmit = async (data: any) => {
|
||||||
mutate(data, {
|
await mutateAsync(data, {
|
||||||
onSuccess: async () => {
|
onSuccess: async () => {
|
||||||
toast(formatMessage(messages.saved));
|
toast(formatMessage(messages.saved));
|
||||||
touch('pixels');
|
touch('pixels');
|
||||||
|
|
@ -106,10 +106,7 @@ export function PixelEditForm({
|
||||||
allowCopy
|
allowCopy
|
||||||
style={{ width: '100%' }}
|
style={{ width: '100%' }}
|
||||||
/>
|
/>
|
||||||
<Button
|
<Button onPress={() => setValue('slug', handleSlug(), { shouldDirty: true })}>
|
||||||
variant="quiet"
|
|
||||||
onPress={() => setValue('slug', handleSlug(), { shouldDirty: true })}
|
|
||||||
>
|
|
||||||
<Icon>
|
<Icon>
|
||||||
<RefreshCw />
|
<RefreshCw />
|
||||||
</Icon>
|
</Icon>
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import { usePixel, useMessages, useSlug } from '@/components/hooks';
|
import { usePixel, useMessages, useSlug } from '@/components/hooks';
|
||||||
import { PageHeader } from '@/components/common/PageHeader';
|
import { PageHeader } from '@/components/common/PageHeader';
|
||||||
import { Icon, Text } from '@umami/react-zen';
|
import { Icon, Text } from '@umami/react-zen';
|
||||||
import { ExternalLink, Pixel } from '@/components/icons';
|
import { ExternalLink, Grid2x2 } from '@/components/icons';
|
||||||
import { LinkButton } from '@/components/common/LinkButton';
|
import { LinkButton } from '@/components/common/LinkButton';
|
||||||
|
|
||||||
export function PixelHeader() {
|
export function PixelHeader() {
|
||||||
|
|
@ -10,7 +10,7 @@ export function PixelHeader() {
|
||||||
const pixel = usePixel();
|
const pixel = usePixel();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<PageHeader title={pixel.name} description={pixel.url} icon={<Pixel />}>
|
<PageHeader title={pixel.name} description={pixel.slug} icon={<Grid2x2 />}>
|
||||||
<LinkButton href={getSlugUrl(pixel.slug)} target="_blank">
|
<LinkButton href={getSlugUrl(pixel.slug)} target="_blank">
|
||||||
<Icon>
|
<Icon>
|
||||||
<ExternalLink />
|
<ExternalLink />
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
import { PixelPage } from './PixelPage';
|
import { PixelPage } from './PixelPage';
|
||||||
import { Metadata } from 'next';
|
import { Metadata } from 'next';
|
||||||
|
|
||||||
export default async function ({ params }: { params: Promise<{ pixelId: string }> }) {
|
export default function ({ params }: { params: { pixelId: string } }) {
|
||||||
const { pixelId } = await params;
|
const { pixelId } = params;
|
||||||
|
|
||||||
return <PixelPage pixelId={pixelId} />;
|
return <PixelPage pixelId={pixelId} />;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ import { Grid, Column } from '@umami/react-zen';
|
||||||
import { useMessages, useNavigation } from '@/components/hooks';
|
import { useMessages, useNavigation } from '@/components/hooks';
|
||||||
import { PageBody } from '@/components/common/PageBody';
|
import { PageBody } from '@/components/common/PageBody';
|
||||||
import { SideMenu } from '@/components/common/SideMenu';
|
import { SideMenu } from '@/components/common/SideMenu';
|
||||||
import { UserCircle, Users, Knobs } from '@/components/icons';
|
import { UserCircle, Users, Settings2 } from '@/components/icons';
|
||||||
|
|
||||||
export function SettingsLayout({ children }: { children: ReactNode }) {
|
export function SettingsLayout({ children }: { children: ReactNode }) {
|
||||||
const { formatMessage, labels } = useMessages();
|
const { formatMessage, labels } = useMessages();
|
||||||
|
|
@ -18,7 +18,7 @@ export function SettingsLayout({ children }: { children: ReactNode }) {
|
||||||
id: 'preferences',
|
id: 'preferences',
|
||||||
label: formatMessage(labels.preferences),
|
label: formatMessage(labels.preferences),
|
||||||
path: renderUrl('/settings/preferences'),
|
path: renderUrl('/settings/preferences'),
|
||||||
icon: <Knobs />,
|
icon: <Settings2 />,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -10,10 +10,10 @@ import { useMessages, useUpdateQuery } from '@/components/hooks';
|
||||||
|
|
||||||
export function PasswordEditForm({ onSave, onClose }) {
|
export function PasswordEditForm({ onSave, onClose }) {
|
||||||
const { formatMessage, labels, messages, getErrorMessage } = useMessages();
|
const { formatMessage, labels, messages, getErrorMessage } = useMessages();
|
||||||
const { mutate, error, isPending } = useUpdateQuery('/me/password');
|
const { mutateAsync, error, isPending } = useUpdateQuery('/me/password');
|
||||||
|
|
||||||
const handleSubmit = async (data: any) => {
|
const handleSubmit = async (data: any) => {
|
||||||
mutate(data, {
|
await mutateAsync(data, {
|
||||||
onSuccess: async () => {
|
onSuccess: async () => {
|
||||||
onSave();
|
onSave();
|
||||||
onClose();
|
onClose();
|
||||||
|
|
|
||||||
|
|
@ -10,10 +10,10 @@ import {
|
||||||
|
|
||||||
export function TeamAddForm({ onSave, onClose }: { onSave: () => void; onClose: () => void }) {
|
export function TeamAddForm({ onSave, onClose }: { onSave: () => void; onClose: () => void }) {
|
||||||
const { formatMessage, labels, getErrorMessage } = useMessages();
|
const { formatMessage, labels, getErrorMessage } = useMessages();
|
||||||
const { mutate, error, isPending } = useUpdateQuery('/teams');
|
const { mutateAsync, error, isPending } = useUpdateQuery('/teams');
|
||||||
|
|
||||||
const handleSubmit = async (data: any) => {
|
const handleSubmit = async (data: any) => {
|
||||||
mutate(data, {
|
await mutateAsync(data, {
|
||||||
onSuccess: async () => {
|
onSuccess: async () => {
|
||||||
onSave?.();
|
onSave?.();
|
||||||
onClose?.();
|
onClose?.();
|
||||||
|
|
|
||||||
|
|
@ -10,10 +10,10 @@ import { useMessages, useUpdateQuery } from '@/components/hooks';
|
||||||
|
|
||||||
export function TeamJoinForm({ onSave, onClose }: { onSave: () => void; onClose: () => void }) {
|
export function TeamJoinForm({ onSave, onClose }: { onSave: () => void; onClose: () => void }) {
|
||||||
const { formatMessage, labels, getErrorMessage } = useMessages();
|
const { formatMessage, labels, getErrorMessage } = useMessages();
|
||||||
const { mutate, error, isPending, touch } = useUpdateQuery('/teams/join');
|
const { mutateAsync, error, touch } = useUpdateQuery('/teams/join');
|
||||||
|
|
||||||
const handleSubmit = async (data: any) => {
|
const handleSubmit = async (data: any) => {
|
||||||
mutate(data, {
|
await mutateAsync(data, {
|
||||||
onSuccess: async () => {
|
onSuccess: async () => {
|
||||||
touch('teams:members');
|
touch('teams:members');
|
||||||
onSave?.();
|
onSave?.();
|
||||||
|
|
@ -33,9 +33,7 @@ export function TeamJoinForm({ onSave, onClose }: { onSave: () => void; onClose:
|
||||||
</FormField>
|
</FormField>
|
||||||
<FormButtons>
|
<FormButtons>
|
||||||
<Button onPress={onClose}>{formatMessage(labels.cancel)}</Button>
|
<Button onPress={onClose}>{formatMessage(labels.cancel)}</Button>
|
||||||
<FormSubmitButton variant="primary" isLoading={isPending} isDisabled={isPending}>
|
<FormSubmitButton variant="primary">{formatMessage(labels.join)}</FormSubmitButton>
|
||||||
{formatMessage(labels.join)}
|
|
||||||
</FormSubmitButton>
|
|
||||||
</FormButtons>
|
</FormButtons>
|
||||||
</Form>
|
</Form>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -15,11 +15,11 @@ export function TeamLeaveForm({
|
||||||
onClose: () => void;
|
onClose: () => void;
|
||||||
}) {
|
}) {
|
||||||
const { formatMessage, labels, messages, getErrorMessage } = useMessages();
|
const { formatMessage, labels, messages, getErrorMessage } = useMessages();
|
||||||
const { mutate, error, isPending } = useDeleteQuery(`/teams/${teamId}/users/${userId}`);
|
const { mutateAsync, error, isPending } = useDeleteQuery(`/teams/${teamId}/users/${userId}`);
|
||||||
const { touch } = useModified();
|
const { touch } = useModified();
|
||||||
|
|
||||||
const handleConfirm = async () => {
|
const handleConfirm = async () => {
|
||||||
mutate(null, {
|
await mutateAsync(null, {
|
||||||
onSuccess: async () => {
|
onSuccess: async () => {
|
||||||
touch('teams:members');
|
touch('teams:members');
|
||||||
onSave();
|
onSave();
|
||||||
|
|
|
||||||
|
|
@ -13,10 +13,10 @@ export function TeamDeleteForm({
|
||||||
onClose?: () => void;
|
onClose?: () => void;
|
||||||
}) {
|
}) {
|
||||||
const { labels, formatMessage, getErrorMessage } = useMessages();
|
const { labels, formatMessage, getErrorMessage } = useMessages();
|
||||||
const { mutate, error, isPending, touch } = useDeleteQuery(`/teams/${teamId}`);
|
const { mutateAsync, error, isPending, touch } = useDeleteQuery(`/teams/${teamId}`);
|
||||||
|
|
||||||
const handleConfirm = async () => {
|
const handleConfirm = async () => {
|
||||||
mutate(null, {
|
await mutateAsync(null, {
|
||||||
onSuccess: async () => {
|
onSuccess: async () => {
|
||||||
touch('teams');
|
touch('teams');
|
||||||
onSave?.();
|
onSave?.();
|
||||||
|
|
|
||||||
|
|
@ -25,10 +25,10 @@ export function TeamEditForm({
|
||||||
const team = useTeam();
|
const team = useTeam();
|
||||||
const { formatMessage, labels, messages, getErrorMessage } = useMessages();
|
const { formatMessage, labels, messages, getErrorMessage } = useMessages();
|
||||||
|
|
||||||
const { mutate, error, isPending, touch, toast } = useUpdateQuery(`/teams/${teamId}`);
|
const { mutateAsync, error, isPending, touch, toast } = useUpdateQuery(`/teams/${teamId}`);
|
||||||
|
|
||||||
const handleSubmit = async (data: any) => {
|
const handleSubmit = async (data: any) => {
|
||||||
mutate(data, {
|
await mutateAsync(data, {
|
||||||
onSuccess: async () => {
|
onSuccess: async () => {
|
||||||
toast(formatMessage(messages.saved));
|
toast(formatMessage(messages.saved));
|
||||||
touch('teams');
|
touch('teams');
|
||||||
|
|
|
||||||
|
|
@ -23,11 +23,11 @@ export function TeamMemberEditForm({
|
||||||
onSave?: () => void;
|
onSave?: () => void;
|
||||||
onClose?: () => void;
|
onClose?: () => void;
|
||||||
}) {
|
}) {
|
||||||
const { mutate, error, isPending } = useUpdateQuery(`/teams/${teamId}/users/${userId}`);
|
const { mutateAsync, error, isPending } = useUpdateQuery(`/teams/${teamId}/users/${userId}`);
|
||||||
const { formatMessage, labels, getErrorMessage } = useMessages();
|
const { formatMessage, labels, getErrorMessage } = useMessages();
|
||||||
|
|
||||||
const handleSubmit = async (data: any) => {
|
const handleSubmit = async (data: any) => {
|
||||||
mutate(data, {
|
await mutateAsync(data, {
|
||||||
onSuccess: async () => {
|
onSuccess: async () => {
|
||||||
onSave();
|
onSave();
|
||||||
onClose();
|
onClose();
|
||||||
|
|
|
||||||
|
|
@ -18,11 +18,11 @@ export function TeamMemberRemoveButton({
|
||||||
onSave?: () => void;
|
onSave?: () => void;
|
||||||
}) {
|
}) {
|
||||||
const { formatMessage, labels } = useMessages();
|
const { formatMessage, labels } = useMessages();
|
||||||
const { mutate, isPending, error } = useDeleteQuery(`/teams/${teamId}/users/${userId}`);
|
const { mutateAsync, isPending, error } = useDeleteQuery(`/teams/${teamId}/users/${userId}`);
|
||||||
const { touch } = useModified();
|
const { touch } = useModified();
|
||||||
|
|
||||||
const handleConfirm = (close: () => void) => {
|
const handleConfirm = async (close: () => void) => {
|
||||||
mutate(null, {
|
await mutateAsync(null, {
|
||||||
onSuccess: () => {
|
onSuccess: () => {
|
||||||
touch('teams:members');
|
touch('teams:members');
|
||||||
onSave?.();
|
onSave?.();
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,13 @@
|
||||||
import { useDeleteQuery, useMessages } from '@/components/hooks';
|
import { useDeleteQuery, useMessages } from '@/components/hooks';
|
||||||
import { Icon, LoadingButton, Text } from '@umami/react-zen';
|
import { Icon, LoadingButton, Text } from '@umami/react-zen';
|
||||||
import { Close } from '@/components/icons';
|
import { X } from '@/components/icons';
|
||||||
|
|
||||||
export function TeamWebsiteRemoveButton({ teamId, websiteId, onSave }) {
|
export function TeamWebsiteRemoveButton({ teamId, websiteId, onSave }) {
|
||||||
const { formatMessage, labels } = useMessages();
|
const { formatMessage, labels } = useMessages();
|
||||||
const { mutate, isPending } = useDeleteQuery(`/teams/${teamId}/websites/${websiteId}`);
|
const { mutateAsync } = useDeleteQuery(`/teams/${teamId}/websites/${websiteId}`);
|
||||||
|
|
||||||
const handleRemoveTeamMember = async () => {
|
const handleRemoveTeamMember = async () => {
|
||||||
mutate(null, {
|
await mutateAsync(null, {
|
||||||
onSuccess: () => {
|
onSuccess: () => {
|
||||||
onSave();
|
onSave();
|
||||||
},
|
},
|
||||||
|
|
@ -15,9 +15,9 @@ export function TeamWebsiteRemoveButton({ teamId, websiteId, onSave }) {
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<LoadingButton variant="quiet" onClick={() => handleRemoveTeamMember()} isLoading={isPending}>
|
<LoadingButton variant="quiet" onClick={() => handleRemoveTeamMember()}>
|
||||||
<Icon>
|
<Icon>
|
||||||
<Close />
|
<X />
|
||||||
</Icon>
|
</Icon>
|
||||||
<Text>{formatMessage(labels.remove)}</Text>
|
<Text>{formatMessage(labels.remove)}</Text>
|
||||||
</LoadingButton>
|
</LoadingButton>
|
||||||
|
|
|
||||||
|
|
@ -13,10 +13,10 @@ export function WebsiteAddForm({
|
||||||
onClose?: () => void;
|
onClose?: () => void;
|
||||||
}) {
|
}) {
|
||||||
const { formatMessage, labels, messages } = useMessages();
|
const { formatMessage, labels, messages } = useMessages();
|
||||||
const { mutate, error, isPending } = useUpdateQuery('/websites', { teamId });
|
const { mutateAsync, error, isPending } = useUpdateQuery('/websites', { teamId });
|
||||||
|
|
||||||
const handleSubmit = async (data: any) => {
|
const handleSubmit = async (data: any) => {
|
||||||
mutate(data, {
|
await mutateAsync(data, {
|
||||||
onSuccess: async () => {
|
onSuccess: async () => {
|
||||||
onSave?.();
|
onSave?.();
|
||||||
onClose?.();
|
onClose?.();
|
||||||
|
|
|
||||||
|
|
@ -33,12 +33,10 @@ export function FunnelEditForm({
|
||||||
}) {
|
}) {
|
||||||
const { formatMessage, labels } = useMessages();
|
const { formatMessage, labels } = useMessages();
|
||||||
const { data } = useReportQuery(id);
|
const { data } = useReportQuery(id);
|
||||||
const { mutate, error, isPending, touch } = useUpdateQuery(`/reports${id ? `/${id}` : ''}`);
|
const { mutateAsync, error, isPending, touch } = useUpdateQuery(`/reports${id ? `/${id}` : ''}`);
|
||||||
|
|
||||||
const handleSubmit = async ({ name, ...parameters }) => {
|
const handleSubmit = async ({ name, ...parameters }) => {
|
||||||
//
|
await mutateAsync(
|
||||||
|
|
||||||
mutate(
|
|
||||||
{ ...data, id, name, type: 'funnel', websiteId, parameters },
|
{ ...data, id, name, type: 'funnel', websiteId, parameters },
|
||||||
{
|
{
|
||||||
onSuccess: async () => {
|
onSuccess: async () => {
|
||||||
|
|
|
||||||
|
|
@ -27,10 +27,10 @@ export function GoalEditForm({
|
||||||
}) {
|
}) {
|
||||||
const { formatMessage, labels } = useMessages();
|
const { formatMessage, labels } = useMessages();
|
||||||
const { data } = useReportQuery(id);
|
const { data } = useReportQuery(id);
|
||||||
const { mutate, error, isPending, touch } = useUpdateQuery(`/reports${id ? `/${id}` : ''}`);
|
const { mutateAsync, error, isPending, touch } = useUpdateQuery(`/reports${id ? `/${id}` : ''}`);
|
||||||
|
|
||||||
const handleSubmit = async (formData: Record<string, any>) => {
|
const handleSubmit = async (formData: Record<string, any>) => {
|
||||||
mutate(
|
await mutateAsync(
|
||||||
{ ...formData, type: 'goal', websiteId },
|
{ ...formData, type: 'goal', websiteId },
|
||||||
{
|
{
|
||||||
onSuccess: async () => {
|
onSuccess: async () => {
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ import {
|
||||||
Search,
|
Search,
|
||||||
Type,
|
Type,
|
||||||
SquareSlash,
|
SquareSlash,
|
||||||
SquareArrowRight,
|
Share2,
|
||||||
Megaphone,
|
Megaphone,
|
||||||
Earth,
|
Earth,
|
||||||
Globe,
|
Globe,
|
||||||
|
|
@ -20,7 +20,7 @@ import {
|
||||||
Monitor,
|
Monitor,
|
||||||
Cpu,
|
Cpu,
|
||||||
LightningSvg,
|
LightningSvg,
|
||||||
LucideCaseSensitive,
|
Network,
|
||||||
Tag,
|
Tag,
|
||||||
} from '@/components/icons';
|
} from '@/components/icons';
|
||||||
|
|
||||||
|
|
@ -80,7 +80,7 @@ export function WebsiteExpandedView({
|
||||||
id: 'referrer',
|
id: 'referrer',
|
||||||
label: formatMessage(labels.referrer),
|
label: formatMessage(labels.referrer),
|
||||||
path: updateParams({ view: 'referrer' }),
|
path: updateParams({ view: 'referrer' }),
|
||||||
icon: <SquareArrowRight />,
|
icon: <Share2 />,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'channel',
|
id: 'channel',
|
||||||
|
|
@ -167,7 +167,7 @@ export function WebsiteExpandedView({
|
||||||
id: 'hostname',
|
id: 'hostname',
|
||||||
label: formatMessage(labels.hostname),
|
label: formatMessage(labels.hostname),
|
||||||
path: updateParams({ view: 'hostname' }),
|
path: updateParams({ view: 'hostname' }),
|
||||||
icon: <LucideCaseSensitive />,
|
icon: <Network />,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'tag',
|
id: 'tag',
|
||||||
|
|
@ -181,7 +181,7 @@ export function WebsiteExpandedView({
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Grid columns="auto 1fr" gap="6" height="100%" overflow="hidden">
|
<Grid columns="auto 1fr" gap="6" height="100%" overflow="hidden">
|
||||||
<Column gap="6" border="right" paddingRight="3">
|
<Column gap="6" border="right" paddingRight="3" overflowY="auto">
|
||||||
<SideMenu items={items} selectedKey={view} muteItems={false} />
|
<SideMenu items={items} selectedKey={view} muteItems={false} />
|
||||||
</Column>
|
</Column>
|
||||||
<Column overflow="hidden">
|
<Column overflow="hidden">
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ import {
|
||||||
MagnetSvg,
|
MagnetSvg,
|
||||||
Tag,
|
Tag,
|
||||||
MoneySvg,
|
MoneySvg,
|
||||||
Network,
|
NetworkSvg,
|
||||||
ChartPie,
|
ChartPie,
|
||||||
UserPlus,
|
UserPlus,
|
||||||
CompareSvg,
|
CompareSvg,
|
||||||
|
|
@ -137,7 +137,7 @@ export function WebsiteNav({ websiteId }: { websiteId: string }) {
|
||||||
{
|
{
|
||||||
id: 'attribution',
|
id: 'attribution',
|
||||||
label: formatMessage(labels.attribution),
|
label: formatMessage(labels.attribution),
|
||||||
icon: <Network />,
|
icon: <NetworkSvg />,
|
||||||
path: renderPath('/attribution'),
|
path: renderPath('/attribution'),
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|
|
||||||
|
|
@ -17,12 +17,12 @@ export function CohortDeleteButton({
|
||||||
onSave?: () => void;
|
onSave?: () => void;
|
||||||
}) {
|
}) {
|
||||||
const { formatMessage, labels } = useMessages();
|
const { formatMessage, labels } = useMessages();
|
||||||
const { mutate, isPending, error, touch } = useDeleteQuery(
|
const { mutateAsync, isPending, error, touch } = useDeleteQuery(
|
||||||
`/websites/${websiteId}/segments/${cohortId}`,
|
`/websites/${websiteId}/segments/${cohortId}`,
|
||||||
);
|
);
|
||||||
|
|
||||||
const handleConfirm = (close: () => void) => {
|
const handleConfirm = async (close: () => void) => {
|
||||||
mutate(null, {
|
await mutateAsync(null, {
|
||||||
onSuccess: () => {
|
onSuccess: () => {
|
||||||
touch('cohorts');
|
touch('cohorts');
|
||||||
onSave?.();
|
onSave?.();
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,7 @@ export function CohortEditForm({
|
||||||
const { data } = useWebsiteCohortQuery(websiteId, cohortId);
|
const { data } = useWebsiteCohortQuery(websiteId, cohortId);
|
||||||
const { formatMessage, labels, messages, getErrorMessage } = useMessages();
|
const { formatMessage, labels, messages, getErrorMessage } = useMessages();
|
||||||
|
|
||||||
const { mutate, error, isPending, touch, toast } = useUpdateQuery(
|
const { mutateAsync, error, isPending, touch, toast } = useUpdateQuery(
|
||||||
`/websites/${websiteId}/segments${cohortId ? `/${cohortId}` : ''}`,
|
`/websites/${websiteId}/segments${cohortId ? `/${cohortId}` : ''}`,
|
||||||
{
|
{
|
||||||
type: 'cohort',
|
type: 'cohort',
|
||||||
|
|
@ -41,7 +41,7 @@ export function CohortEditForm({
|
||||||
);
|
);
|
||||||
|
|
||||||
const handleSubmit = async (formData: any) => {
|
const handleSubmit = async (formData: any) => {
|
||||||
mutate(formData, {
|
await mutateAsync(formData, {
|
||||||
onSuccess: async () => {
|
onSuccess: async () => {
|
||||||
toast(formatMessage(messages.saved));
|
toast(formatMessage(messages.saved));
|
||||||
touch('cohorts');
|
touch('cohorts');
|
||||||
|
|
|
||||||
|
|
@ -17,12 +17,12 @@ export function SegmentDeleteButton({
|
||||||
onSave?: () => void;
|
onSave?: () => void;
|
||||||
}) {
|
}) {
|
||||||
const { formatMessage, labels } = useMessages();
|
const { formatMessage, labels } = useMessages();
|
||||||
const { mutate, isPending, error, touch } = useDeleteQuery(
|
const { mutateAsync, isPending, error, touch } = useDeleteQuery(
|
||||||
`/websites/${websiteId}/segments/${segmentId}`,
|
`/websites/${websiteId}/segments/${segmentId}`,
|
||||||
);
|
);
|
||||||
|
|
||||||
const handleConfirm = (close: () => void) => {
|
const handleConfirm = async (close: () => void) => {
|
||||||
mutate(null, {
|
await mutateAsync(null, {
|
||||||
onSuccess: () => {
|
onSuccess: () => {
|
||||||
touch('segments');
|
touch('segments');
|
||||||
onSave?.();
|
onSave?.();
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@ export function SegmentEditForm({
|
||||||
const { data } = useWebsiteSegmentQuery(websiteId, segmentId);
|
const { data } = useWebsiteSegmentQuery(websiteId, segmentId);
|
||||||
const { formatMessage, labels, getErrorMessage } = useMessages();
|
const { formatMessage, labels, getErrorMessage } = useMessages();
|
||||||
|
|
||||||
const { mutate, error, isPending, touch, toast } = useUpdateQuery(
|
const { mutateAsync, error, isPending, touch, toast } = useUpdateQuery(
|
||||||
`/websites/${websiteId}/segments${segmentId ? `/${segmentId}` : ''}`,
|
`/websites/${websiteId}/segments${segmentId ? `/${segmentId}` : ''}`,
|
||||||
{
|
{
|
||||||
type: 'segment',
|
type: 'segment',
|
||||||
|
|
@ -38,7 +38,7 @@ export function SegmentEditForm({
|
||||||
);
|
);
|
||||||
|
|
||||||
const handleSubmit = async (formData: any) => {
|
const handleSubmit = async (formData: any) => {
|
||||||
mutate(formData, {
|
await mutateAsync(formData, {
|
||||||
onSuccess: async () => {
|
onSuccess: async () => {
|
||||||
toast(formatMessage(messages.saved));
|
toast(formatMessage(messages.saved));
|
||||||
touch('segments');
|
touch('segments');
|
||||||
|
|
|
||||||
|
|
@ -13,10 +13,10 @@ export function WebsiteDeleteForm({
|
||||||
onClose?: () => void;
|
onClose?: () => void;
|
||||||
}) {
|
}) {
|
||||||
const { formatMessage, labels } = useMessages();
|
const { formatMessage, labels } = useMessages();
|
||||||
const { mutate, isPending, error, touch } = useDeleteQuery(`/websites/${websiteId}`);
|
const { mutateAsync, isPending, error, touch } = useDeleteQuery(`/websites/${websiteId}`);
|
||||||
|
|
||||||
const handleConfirm = async () => {
|
const handleConfirm = async () => {
|
||||||
mutate(null, {
|
await mutateAsync(null, {
|
||||||
onSuccess: async () => {
|
onSuccess: async () => {
|
||||||
touch('websites');
|
touch('websites');
|
||||||
touch(`websites:${websiteId}`);
|
touch(`websites:${websiteId}`);
|
||||||
|
|
|
||||||
|
|
@ -5,10 +5,10 @@ import { DOMAIN_REGEX } from '@/lib/constants';
|
||||||
export function WebsiteEditForm({ websiteId, onSave }: { websiteId: string; onSave?: () => void }) {
|
export function WebsiteEditForm({ websiteId, onSave }: { websiteId: string; onSave?: () => void }) {
|
||||||
const website = useWebsite();
|
const website = useWebsite();
|
||||||
const { formatMessage, labels, messages, getErrorMessage } = useMessages();
|
const { formatMessage, labels, messages, getErrorMessage } = useMessages();
|
||||||
const { mutate, error, touch, toast, isPending } = useUpdateQuery(`/websites/${websiteId}`);
|
const { mutateAsync, error, touch, toast } = useUpdateQuery(`/websites/${websiteId}`);
|
||||||
|
|
||||||
const handleSubmit = async (data: any) => {
|
const handleSubmit = async (data: any) => {
|
||||||
mutate(data, {
|
await mutateAsync(data, {
|
||||||
onSuccess: async () => {
|
onSuccess: async () => {
|
||||||
toast(formatMessage(messages.saved));
|
toast(formatMessage(messages.saved));
|
||||||
touch(`website:${website.id}`);
|
touch(`website:${website.id}`);
|
||||||
|
|
@ -45,12 +45,7 @@ export function WebsiteEditForm({ websiteId, onSave }: { websiteId: string; onSa
|
||||||
<TextField />
|
<TextField />
|
||||||
</FormField>
|
</FormField>
|
||||||
<FormButtons>
|
<FormButtons>
|
||||||
<FormSubmitButton
|
<FormSubmitButton data-test="button-submit" variant="primary">
|
||||||
data-test="button-submit"
|
|
||||||
variant="primary"
|
|
||||||
isLoading={isPending}
|
|
||||||
isDisabled={isPending}
|
|
||||||
>
|
|
||||||
{formatMessage(labels.save)}
|
{formatMessage(labels.save)}
|
||||||
</FormSubmitButton>
|
</FormSubmitButton>
|
||||||
</FormButtons>
|
</FormButtons>
|
||||||
|
|
|
||||||
|
|
@ -13,10 +13,10 @@ export function WebsiteResetForm({
|
||||||
onClose?: () => void;
|
onClose?: () => void;
|
||||||
}) {
|
}) {
|
||||||
const { formatMessage, labels } = useMessages();
|
const { formatMessage, labels } = useMessages();
|
||||||
const { mutate, isPending, error } = useUpdateQuery(`/websites/${websiteId}/reset`);
|
const { mutateAsync, isPending, error } = useUpdateQuery(`/websites/${websiteId}/reset`);
|
||||||
|
|
||||||
const handleConfirm = async () => {
|
const handleConfirm = async () => {
|
||||||
mutate(null, {
|
await mutateAsync(null, {
|
||||||
onSuccess: async () => {
|
onSuccess: async () => {
|
||||||
onSave?.();
|
onSave?.();
|
||||||
onClose?.();
|
onClose?.();
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@ export interface WebsiteShareFormProps {
|
||||||
export function WebsiteShareForm({ websiteId, shareId, onSave, onClose }: WebsiteShareFormProps) {
|
export function WebsiteShareForm({ websiteId, shareId, onSave, onClose }: WebsiteShareFormProps) {
|
||||||
const { formatMessage, labels, messages, getErrorMessage } = useMessages();
|
const { formatMessage, labels, messages, getErrorMessage } = useMessages();
|
||||||
const [id, setId] = useState(shareId);
|
const [id, setId] = useState(shareId);
|
||||||
const { mutate, error, isPending, touch, toast } = useUpdateQuery(`/websites/${websiteId}`);
|
const { mutateAsync, error, touch, toast } = useUpdateQuery(`/websites/${websiteId}`);
|
||||||
|
|
||||||
const url = `${window?.location.origin || ''}${process.env.basePath || ''}/share/${id}`;
|
const url = `${window?.location.origin || ''}${process.env.basePath || ''}/share/${id}`;
|
||||||
|
|
||||||
|
|
@ -37,11 +37,11 @@ export function WebsiteShareForm({ websiteId, shareId, onSave, onClose }: Websit
|
||||||
setId(id ? null : generateId());
|
setId(id ? null : generateId());
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleSave = () => {
|
const handleSave = async () => {
|
||||||
const data = {
|
const data = {
|
||||||
shareId: id,
|
shareId: id,
|
||||||
};
|
};
|
||||||
mutate(data, {
|
await mutateAsync(data, {
|
||||||
onSuccess: async () => {
|
onSuccess: async () => {
|
||||||
toast(formatMessage(messages.saved));
|
toast(formatMessage(messages.saved));
|
||||||
touch(`website:${websiteId}`);
|
touch(`website:${websiteId}`);
|
||||||
|
|
@ -69,9 +69,7 @@ export function WebsiteShareForm({ websiteId, shareId, onSave, onClose }: Websit
|
||||||
</Row>
|
</Row>
|
||||||
<Row alignItems="center" gap>
|
<Row alignItems="center" gap>
|
||||||
{onClose && <Button onPress={onClose}>{formatMessage(labels.cancel)}</Button>}
|
{onClose && <Button onPress={onClose}>{formatMessage(labels.cancel)}</Button>}
|
||||||
<FormSubmitButton isDisabled={false} isLoading={isPending}>
|
<FormSubmitButton isDisabled={false}>{formatMessage(labels.save)}</FormSubmitButton>
|
||||||
{formatMessage(labels.save)}
|
|
||||||
</FormSubmitButton>
|
|
||||||
</Row>
|
</Row>
|
||||||
</FormButtons>
|
</FormButtons>
|
||||||
</Column>
|
</Column>
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@ export function WebsiteTransferForm({
|
||||||
const website = useWebsite();
|
const website = useWebsite();
|
||||||
const [teamId, setTeamId] = useState<string>(null);
|
const [teamId, setTeamId] = useState<string>(null);
|
||||||
const { formatMessage, labels, messages, getErrorMessage } = useMessages();
|
const { formatMessage, labels, messages, getErrorMessage } = useMessages();
|
||||||
const { mutate, error, isPending } = useUpdateQuery(`/websites/${websiteId}/transfer`);
|
const { mutateAsync, error, isPending } = useUpdateQuery(`/websites/${websiteId}/transfer`);
|
||||||
const { data: teams, isLoading } = useUserTeamsQuery(user.id);
|
const { data: teams, isLoading } = useUserTeamsQuery(user.id);
|
||||||
const isTeamWebsite = !!website?.teamId;
|
const isTeamWebsite = !!website?.teamId;
|
||||||
|
|
||||||
|
|
@ -45,7 +45,7 @@ export function WebsiteTransferForm({
|
||||||
) || [];
|
) || [];
|
||||||
|
|
||||||
const handleSubmit = async () => {
|
const handleSubmit = async () => {
|
||||||
mutate(
|
await mutateAsync(
|
||||||
{
|
{
|
||||||
userId: website.teamId ? user.id : undefined,
|
userId: website.teamId ? user.id : undefined,
|
||||||
teamId: website.userId ? teamId : undefined,
|
teamId: website.userId ? teamId : undefined,
|
||||||
|
|
|
||||||
|
|
@ -18,10 +18,10 @@ import { LogoSvg } from '@/components/icons';
|
||||||
export function LoginForm() {
|
export function LoginForm() {
|
||||||
const { formatMessage, labels, getErrorMessage } = useMessages();
|
const { formatMessage, labels, getErrorMessage } = useMessages();
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { mutate, error, isPending } = useUpdateQuery('/auth/login');
|
const { mutateAsync, error } = useUpdateQuery('/auth/login');
|
||||||
|
|
||||||
const handleSubmit = async (data: any) => {
|
const handleSubmit = async (data: any) => {
|
||||||
mutate(data, {
|
await mutateAsync(data, {
|
||||||
onSuccess: async ({ token, user }) => {
|
onSuccess: async ({ token, user }) => {
|
||||||
setClientAuthToken(token);
|
setClientAuthToken(token);
|
||||||
setUser(user);
|
setUser(user);
|
||||||
|
|
@ -55,13 +55,7 @@ export function LoginForm() {
|
||||||
<PasswordField />
|
<PasswordField />
|
||||||
</FormField>
|
</FormField>
|
||||||
<FormButtons>
|
<FormButtons>
|
||||||
<FormSubmitButton
|
<FormSubmitButton data-test="button-submit" variant="primary" style={{ flex: 1 }}>
|
||||||
data-test="button-submit"
|
|
||||||
variant="primary"
|
|
||||||
isLoading={isPending}
|
|
||||||
isDisabled={isPending}
|
|
||||||
style={{ flex: 1 }}
|
|
||||||
>
|
|
||||||
{formatMessage(labels.login)}
|
{formatMessage(labels.login)}
|
||||||
</FormSubmitButton>
|
</FormSubmitButton>
|
||||||
</FormButtons>
|
</FormButtons>
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,7 @@ export function ReportEditButton({
|
||||||
const { formatMessage, labels, messages } = useMessages();
|
const { formatMessage, labels, messages } = useMessages();
|
||||||
const [showEdit, setShowEdit] = useState(false);
|
const [showEdit, setShowEdit] = useState(false);
|
||||||
const [showDelete, setShowDelete] = useState(false);
|
const [showDelete, setShowDelete] = useState(false);
|
||||||
const { mutate, touch } = useDeleteQuery(`/reports/${id}`);
|
const { mutateAsync, touch } = useDeleteQuery(`/reports/${id}`);
|
||||||
|
|
||||||
const handleAction = (id: any) => {
|
const handleAction = (id: any) => {
|
||||||
if (id === 'edit') {
|
if (id === 'edit') {
|
||||||
|
|
@ -47,7 +47,7 @@ export function ReportEditButton({
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleDelete = async () => {
|
const handleDelete = async () => {
|
||||||
mutate(null, {
|
await mutateAsync(null, {
|
||||||
onSuccess: async () => {
|
onSuccess: async () => {
|
||||||
touch(`reports:${type}`);
|
touch(`reports:${type}`);
|
||||||
setShowDelete(false);
|
setShowDelete(false);
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
import { List, ListItem } from '@umami/react-zen';
|
import { List, ListItem } from '@umami/react-zen';
|
||||||
import { useWebsiteSegmentsQuery } from '@/components/hooks';
|
import { useWebsiteSegmentsQuery } from '@/components/hooks';
|
||||||
import { LoadingPanel } from '@/components/common/LoadingPanel';
|
import { LoadingPanel } from '@/components/common/LoadingPanel';
|
||||||
|
import { Empty } from '@/components/common/Empty';
|
||||||
|
|
||||||
export interface SegmentFiltersProps {
|
export interface SegmentFiltersProps {
|
||||||
websiteId: string;
|
websiteId: string;
|
||||||
|
|
@ -23,6 +24,7 @@ export function SegmentFilters({
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<LoadingPanel data={data} isLoading={isLoading} isFetching={isFetching} overflowY="auto">
|
<LoadingPanel data={data} isLoading={isLoading} isFetching={isFetching} overflowY="auto">
|
||||||
|
{data?.data?.length === 0 && <Empty />}
|
||||||
<List selectionMode="single" value={[segmentId]} onChange={id => handleChange(id[0])}>
|
<List selectionMode="single" value={[segmentId]} onChange={id => handleChange(id[0])}>
|
||||||
{data?.data?.map(item => {
|
{data?.data?.map(item => {
|
||||||
return (
|
return (
|
||||||
|
|
|
||||||
|
|
@ -10,23 +10,27 @@ import {
|
||||||
MenuSection,
|
MenuSection,
|
||||||
} from '@umami/react-zen';
|
} from '@umami/react-zen';
|
||||||
import { useMessages, useLoginQuery, useNavigation, useConfig } from '@/components/hooks';
|
import { useMessages, useLoginQuery, useNavigation, useConfig } from '@/components/hooks';
|
||||||
import { LogOut, LockKeyhole, Settings, UserCircle } from '@/components/icons';
|
import { LogOut, LockKeyhole, Settings, UserCircle, LifeBuoy, BookText } from '@/components/icons';
|
||||||
|
import { DOCS_URL } from '@/lib/constants';
|
||||||
|
|
||||||
export function SettingsButton() {
|
export function SettingsButton() {
|
||||||
const { formatMessage, labels } = useMessages();
|
const { formatMessage, labels } = useMessages();
|
||||||
const { user } = useLoginQuery();
|
const { user } = useLoginQuery();
|
||||||
const { router, renderUrl } = useNavigation();
|
const { router } = useNavigation();
|
||||||
const { cloudMode } = useConfig();
|
const { cloudMode } = useConfig();
|
||||||
|
|
||||||
const handleAction = (id: Key) => {
|
const handleAction = (id: Key) => {
|
||||||
if (id === 'settings') {
|
const url = id.toString();
|
||||||
if (cloudMode) {
|
|
||||||
window.location.href = `/settings`;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
router.push(renderUrl(`/${id}`));
|
if (cloudMode) {
|
||||||
|
if (url === '/docs') {
|
||||||
|
window.open(DOCS_URL, '_blank');
|
||||||
|
} else {
|
||||||
|
window.location.href = url;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
router.push(url);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
@ -40,12 +44,26 @@ export function SettingsButton() {
|
||||||
<Menu autoFocus="last" onAction={handleAction}>
|
<Menu autoFocus="last" onAction={handleAction}>
|
||||||
<MenuSection title={user.username}>
|
<MenuSection title={user.username}>
|
||||||
<MenuSeparator />
|
<MenuSeparator />
|
||||||
<MenuItem id="settings" icon={<Settings />} label={formatMessage(labels.settings)} />
|
<MenuItem id="/settings" icon={<Settings />} label={formatMessage(labels.settings)} />
|
||||||
{!cloudMode && user.isAdmin && (
|
{!cloudMode && user.isAdmin && (
|
||||||
<MenuItem id="admin" icon={<LockKeyhole />} label={formatMessage(labels.admin)} />
|
<MenuItem id="/admin" icon={<LockKeyhole />} label={formatMessage(labels.admin)} />
|
||||||
|
)}
|
||||||
|
{cloudMode && (
|
||||||
|
<>
|
||||||
|
<MenuItem
|
||||||
|
id="/docs"
|
||||||
|
icon={<BookText />}
|
||||||
|
label={formatMessage(labels.documentation)}
|
||||||
|
/>
|
||||||
|
<MenuItem
|
||||||
|
id="/settings/support"
|
||||||
|
icon={<LifeBuoy />}
|
||||||
|
label={formatMessage(labels.support)}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
)}
|
)}
|
||||||
<MenuSeparator />
|
<MenuSeparator />
|
||||||
<MenuItem id="logout" icon={<LogOut />} label={formatMessage(labels.logout)} />
|
<MenuItem id="/logout" icon={<LogOut />} label={formatMessage(labels.logout)} />
|
||||||
</MenuSection>
|
</MenuSection>
|
||||||
</Menu>
|
</Menu>
|
||||||
</Popover>
|
</Popover>
|
||||||
|
|
|
||||||
|
|
@ -360,6 +360,8 @@ export const labels = defineMessages({
|
||||||
environment: { id: 'label.environment', defaultMessage: 'Environment' },
|
environment: { id: 'label.environment', defaultMessage: 'Environment' },
|
||||||
criteria: { id: 'label.criteria', defaultMessage: 'Criteria' },
|
criteria: { id: 'label.criteria', defaultMessage: 'Criteria' },
|
||||||
share: { id: 'label.share', defaultMessage: 'Share' },
|
share: { id: 'label.share', defaultMessage: 'Share' },
|
||||||
|
support: { id: 'label.support', defaultMessage: 'Support' },
|
||||||
|
documentation: { id: 'label.documentation', defaultMessage: 'Documentation' },
|
||||||
});
|
});
|
||||||
|
|
||||||
export const messages = defineMessages({
|
export const messages = defineMessages({
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ export const DASHBOARD_CONFIG = 'umami.dashboard';
|
||||||
export const VERSION_CHECK = 'umami.version-check';
|
export const VERSION_CHECK = 'umami.version-check';
|
||||||
export const SHARE_TOKEN_HEADER = 'x-umami-share-token';
|
export const SHARE_TOKEN_HEADER = 'x-umami-share-token';
|
||||||
export const HOMEPAGE_URL = 'https://umami.is';
|
export const HOMEPAGE_URL = 'https://umami.is';
|
||||||
|
export const DOCS_URL = 'https://umami.is/docs';
|
||||||
export const REPO_URL = 'https://github.com/umami-software/umami';
|
export const REPO_URL = 'https://github.com/umami-software/umami';
|
||||||
export const UPDATES_URL = 'https://api.umami.is/v1/updates';
|
export const UPDATES_URL = 'https://api.umami.is/v1/updates';
|
||||||
export const TELEMETRY_PIXEL = 'https://i.umami.is/a.png';
|
export const TELEMETRY_PIXEL = 'https://i.umami.is/a.png';
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue