mirror of
https://github.com/umami-software/umami.git
synced 2026-02-09 15:17:23 +01:00
Updated components build.
This commit is contained in:
parent
5f27ba149b
commit
56af91950a
53 changed files with 942 additions and 333 deletions
|
|
@ -1,8 +1,9 @@
|
|||
import { createContext, ReactNode } from 'react';
|
||||
import { Loading } from '@umami/react-zen';
|
||||
import { useUserQuery } from '@/components/hooks';
|
||||
import { User } from '@/generated/prisma/client';
|
||||
import { useUserQuery } from '@/components/hooks/queries/useUserQuery';
|
||||
|
||||
export const UserContext = createContext(null);
|
||||
export const UserContext = createContext<User>(null);
|
||||
|
||||
export function UserProvider({ userId, children }: { userId: string; children: ReactNode }) {
|
||||
const { data: user, isFetching, isLoading } = useUserQuery(userId);
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ import {
|
|||
import { useConfig, useLinkQuery } from '@/components/hooks';
|
||||
import { useMessages } from '@/components/hooks';
|
||||
import { Refresh } from '@/components/icons';
|
||||
import { getRandomChars } from '@/lib/crypto';
|
||||
import { getRandomChars } from '@/lib/generate';
|
||||
import { useUpdateQuery } from '@/components/hooks/queries/useUpdateQuery';
|
||||
import { LINKS_URL } from '@/lib/constants';
|
||||
import { isValidUrl } from '@/lib/url';
|
||||
|
|
|
|||
|
|
@ -1,9 +1,10 @@
|
|||
'use client';
|
||||
import { createContext, ReactNode } from 'react';
|
||||
import { useLinkQuery } from '@/components/hooks';
|
||||
import { Loading } from '@umami/react-zen';
|
||||
import { Link } from '@/generated/prisma/client';
|
||||
import { useLinkQuery } from '@/components/hooks/queries/useLinkQuery';
|
||||
|
||||
export const LinkContext = createContext(null);
|
||||
export const LinkContext = createContext<Link>(null);
|
||||
|
||||
export function LinkProvider({ linkId, children }: { linkId?: string; children: ReactNode }) {
|
||||
const { data: link, isLoading, isFetching } = useLinkQuery(linkId);
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ import {
|
|||
import { useConfig, usePixelQuery } from '@/components/hooks';
|
||||
import { useMessages } from '@/components/hooks';
|
||||
import { Refresh } from '@/components/icons';
|
||||
import { getRandomChars } from '@/lib/crypto';
|
||||
import { getRandomChars } from '@/lib/generate';
|
||||
import { useUpdateQuery } from '@/components/hooks/queries/useUpdateQuery';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { PIXELS_URL } from '@/lib/constants';
|
||||
|
|
|
|||
|
|
@ -1,9 +1,10 @@
|
|||
'use client';
|
||||
import { createContext, ReactNode } from 'react';
|
||||
import { usePixelQuery } from '@/components/hooks';
|
||||
import { Loading } from '@umami/react-zen';
|
||||
import { Pixel } from '@/generated/prisma/client';
|
||||
import { usePixelQuery } from '@/components/hooks/queries/usePixelQuery';
|
||||
|
||||
export const PixelContext = createContext(null);
|
||||
export const PixelContext = createContext<Pixel>(null);
|
||||
|
||||
export function PixelProvider({ pixelId, children }: { pixelId?: string; children: ReactNode }) {
|
||||
const { data: pixel, isLoading, isFetching } = usePixelQuery(pixelId);
|
||||
|
|
|
|||
|
|
@ -41,9 +41,9 @@ export function SettingsLayout({ children }: { children: ReactNode }) {
|
|||
},
|
||||
];
|
||||
|
||||
const selectedKey =
|
||||
items.flatMap(e => e.items)?.find(({ path }) => path && pathname.includes(path))?.id ||
|
||||
'overview';
|
||||
const selectedKey = items
|
||||
.flatMap(e => e.items)
|
||||
.find(({ path }) => path && pathname.endsWith(path.split('?')[0]))?.id;
|
||||
|
||||
return (
|
||||
<Grid columns="auto 1fr" width="100%" height="100%">
|
||||
|
|
|
|||
|
|
@ -2,10 +2,6 @@ import { Metadata } from 'next';
|
|||
import { SettingsLayout } from './SettingsLayout';
|
||||
|
||||
export default function ({ children }) {
|
||||
if (process.env.cloudMode) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return <SettingsLayout>{children}</SettingsLayout>;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ export function TeamLeaveForm({
|
|||
<ConfirmationForm
|
||||
buttonLabel={formatMessage(labels.leave)}
|
||||
message={formatMessage(messages.confirmLeave, {
|
||||
target: <b key={messages.confirmLeave.id}>{teamName}</b>,
|
||||
target: teamName,
|
||||
})}
|
||||
onConfirm={handleConfirm}
|
||||
onClose={onClose}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,10 @@
|
|||
'use client';
|
||||
import { createContext, ReactNode } from 'react';
|
||||
import { useTeamQuery } from '@/components/hooks';
|
||||
import { Loading } from '@umami/react-zen';
|
||||
import { useTeamQuery } from '@/components/hooks/queries/useTeamQuery';
|
||||
import { Team } from '@/generated/prisma/client';
|
||||
|
||||
export const TeamContext = createContext(null);
|
||||
export const TeamContext = createContext<Team>(null);
|
||||
|
||||
export function TeamProvider({ teamId, children }: { teamId?: string; children: ReactNode }) {
|
||||
const { data: team, isLoading, isFetching } = useTeamQuery(teamId);
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import {
|
|||
TextField,
|
||||
Button,
|
||||
} from '@umami/react-zen';
|
||||
import { getRandomChars } from '@/lib/crypto';
|
||||
import { getRandomChars } from '@/lib/generate';
|
||||
import { useMessages, useTeam, useUpdateQuery } from '@/components/hooks';
|
||||
|
||||
const generateId = () => `team_${getRandomChars(16)}`;
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ import { PageHeader } from '@/components/common/PageHeader';
|
|||
import { Panel } from '@/components/common/Panel';
|
||||
|
||||
export function TeamSettings({ teamId }: { teamId: string }) {
|
||||
const team = useTeam();
|
||||
const team: any = useTeam();
|
||||
const { formatMessage, labels } = useMessages();
|
||||
const { user } = useLoginQuery();
|
||||
const { query, pathname } = useNavigation();
|
||||
|
|
|
|||
|
|
@ -1,8 +1,19 @@
|
|||
import { DataColumn, DataTable } from '@umami/react-zen';
|
||||
import { DataColumn, DataTable, Row } from '@umami/react-zen';
|
||||
import { useMessages } from '@/components/hooks';
|
||||
import Link from 'next/link';
|
||||
import { ROLES } from '@/lib/constants';
|
||||
import { TeamMemberEditButton } from '@/app/(main)/teams/[teamId]/TeamMemberEditButton';
|
||||
import { TeamMemberRemoveButton } from '@/app/(main)/teams/[teamId]/TeamMemberRemoveButton';
|
||||
|
||||
export function TeamWebsitesTable({ teamId, data = [] }: { teamId: string; data: any[] }) {
|
||||
export function TeamWebsitesTable({
|
||||
teamId,
|
||||
data = [],
|
||||
allowEdit,
|
||||
}: {
|
||||
teamId: string;
|
||||
data: any[];
|
||||
allowEdit: boolean;
|
||||
}) {
|
||||
const { formatMessage, labels } = useMessages();
|
||||
|
||||
return (
|
||||
|
|
@ -14,6 +25,26 @@ export function TeamWebsitesTable({ teamId, data = [] }: { teamId: string; data:
|
|||
<DataColumn id="createdBy" label={formatMessage(labels.createdBy)}>
|
||||
{(row: any) => row?.createUser?.username}
|
||||
</DataColumn>
|
||||
{allowEdit && (
|
||||
<DataColumn id="action" align="end">
|
||||
{(row: any) => {
|
||||
if (row?.role === ROLES.teamOwner) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<Row alignItems="center">
|
||||
<TeamMemberEditButton teamId={teamId} userId={row?.user?.id} role={row?.role} />
|
||||
<TeamMemberRemoveButton
|
||||
teamId={teamId}
|
||||
userId={row?.user?.id}
|
||||
userName={row?.user?.username}
|
||||
/>
|
||||
</Row>
|
||||
);
|
||||
}}
|
||||
</DataColumn>
|
||||
)}
|
||||
</DataTable>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
'use client';
|
||||
import { createContext, ReactNode } from 'react';
|
||||
import { useWebsiteQuery } from '@/components/hooks';
|
||||
import { Loading } from '@umami/react-zen';
|
||||
import { Website } from '@/generated/prisma/client';
|
||||
import { useWebsiteQuery } from '@/components/hooks/queries/useWebsiteQuery';
|
||||
|
||||
export const WebsiteContext = createContext<Website>(null);
|
||||
|
||||
|
|
|
|||
|
|
@ -143,12 +143,12 @@ export function WebsiteNav({ websiteId }: { websiteId: string }) {
|
|||
},
|
||||
];
|
||||
|
||||
const selectedKey =
|
||||
items.flatMap(e => e.items).find(({ path }) => path && pathname.endsWith(path.split('?')[0]))
|
||||
?.id || 'overview';
|
||||
const selectedKey = items
|
||||
.flatMap(e => e.items)
|
||||
.find(({ path }) => path && pathname.endsWith(path.split('?')[0]))?.id;
|
||||
|
||||
return (
|
||||
<SideMenu items={items} selectedKey={selectedKey} allowMinimize={false}>
|
||||
<SideMenu items={items} selectedKey={selectedKey} allowMinimize={false} muteItems={false}>
|
||||
<WebsiteSelect websiteId={websiteId} teamId={teamId} />
|
||||
</SideMenu>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { useMemo, useState } from 'react';
|
||||
import { Select, ListItem, Grid } from '@umami/react-zen';
|
||||
import { Select, ListItem, Grid, Column } from '@umami/react-zen';
|
||||
import {
|
||||
useEventDataPropertiesQuery,
|
||||
useEventDataValuesQuery,
|
||||
|
|
@ -33,40 +33,41 @@ export function EventProperties({ websiteId }: { websiteId: string }) {
|
|||
isFetching={isFetching}
|
||||
error={error}
|
||||
minHeight="300px"
|
||||
gap="6"
|
||||
>
|
||||
{data && (
|
||||
<Grid columns="repeat(auto-fill, minmax(300px, 1fr))" marginBottom="3" gap>
|
||||
<Select
|
||||
label={formatMessage(labels.event)}
|
||||
value={eventName}
|
||||
onChange={setEventName}
|
||||
placeholder=""
|
||||
>
|
||||
{events?.map(p => (
|
||||
<ListItem key={p} id={p}>
|
||||
{p}
|
||||
</ListItem>
|
||||
))}
|
||||
</Select>
|
||||
<Select
|
||||
label={formatMessage(labels.property)}
|
||||
value={propertyName}
|
||||
onChange={setPropertyName}
|
||||
isDisabled={!eventName}
|
||||
placeholder=""
|
||||
>
|
||||
{properties?.map(p => (
|
||||
<ListItem key={p} id={p}>
|
||||
{p}
|
||||
</ListItem>
|
||||
))}
|
||||
</Select>
|
||||
</Grid>
|
||||
)}
|
||||
{eventName && propertyName && (
|
||||
<EventValues websiteId={websiteId} eventName={eventName} propertyName={propertyName} />
|
||||
)}
|
||||
<Column gap="6">
|
||||
{data && (
|
||||
<Grid columns="repeat(auto-fill, minmax(300px, 1fr))" marginBottom="3" gap>
|
||||
<Select
|
||||
label={formatMessage(labels.event)}
|
||||
value={eventName}
|
||||
onChange={setEventName}
|
||||
placeholder=""
|
||||
>
|
||||
{events?.map(p => (
|
||||
<ListItem key={p} id={p}>
|
||||
{p}
|
||||
</ListItem>
|
||||
))}
|
||||
</Select>
|
||||
<Select
|
||||
label={formatMessage(labels.property)}
|
||||
value={propertyName}
|
||||
onChange={setPropertyName}
|
||||
isDisabled={!eventName}
|
||||
placeholder=""
|
||||
>
|
||||
{properties?.map(p => (
|
||||
<ListItem key={p} id={p}>
|
||||
{p}
|
||||
</ListItem>
|
||||
))}
|
||||
</Select>
|
||||
</Grid>
|
||||
)}
|
||||
{eventName && propertyName && (
|
||||
<EventValues websiteId={websiteId} eventName={eventName} propertyName={propertyName} />
|
||||
)}
|
||||
</Column>
|
||||
</LoadingPanel>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ import {
|
|||
Row,
|
||||
} from '@umami/react-zen';
|
||||
import { useState } from 'react';
|
||||
import { getRandomChars } from '@/lib/crypto';
|
||||
import { getRandomChars } from '@/lib/generate';
|
||||
import { useMessages, useUpdateQuery } from '@/components/hooks';
|
||||
|
||||
const generateId = () => getRandomChars(16);
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ const schema = z.object({
|
|||
url: urlOrPathParam.optional(),
|
||||
name: z.string().max(50).optional(),
|
||||
tag: z.string().max(50).optional(),
|
||||
ip: z.string().ip().optional(),
|
||||
ip: z.string().optional(),
|
||||
userAgent: z.string().optional(),
|
||||
timestamp: z.coerce.number().int().optional(),
|
||||
id: z.string().optional(),
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { z } from 'zod';
|
||||
import { getRandomChars } from '@/lib/crypto';
|
||||
import { getRandomChars } from '@/lib/generate';
|
||||
import { unauthorized, json } from '@/lib/response';
|
||||
import { canCreateTeam } from '@/validations';
|
||||
import { uuid } from '@/lib/crypto';
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue