diff --git a/next.config.ts b/next.config.ts index 86aaae95..e229cb44 100644 --- a/next.config.ts +++ b/next.config.ts @@ -1,15 +1,10 @@ import 'dotenv/config'; -import { createRequire } from 'module'; - -const require = createRequire(import.meta.url); - -const pkg = require('./package.json'); +import pkg from './package.json' assert { type: 'json' }; const TRACKER_SCRIPT = '/script.js'; const basePath = process.env.BASE_PATH; const collectApiEndpoint = process.env.COLLECT_API_ENDPOINT; -const cloudMode = process.env.CLOUD_MODE; const cloudUrl = process.env.CLOUD_URL; const corsMaxAge = process.env.CORS_MAX_AGE; const defaultLocale = process.env.DEFAULT_LOCALE; @@ -162,7 +157,7 @@ if (trackerScriptName) { } } -if (cloudMode && cloudUrl) { +if (cloudUrl) { redirects.push({ source: '/login', destination: cloudUrl, @@ -175,7 +170,6 @@ export default { reactStrictMode: false, env: { basePath, - cloudMode, cloudUrl, currentVersion: pkg.version, defaultLocale, diff --git a/package.components.json b/package.components.json index 048673e8..27887f8f 100644 --- a/package.components.json +++ b/package.components.json @@ -1,6 +1,6 @@ { "name": "@umami/components", - "version": "0.115.0", + "version": "0.116.0", "description": "Umami React components.", "author": "Mike Cao ", "license": "MIT", diff --git a/package.json b/package.json index e6fe20f4..7d3528fa 100644 --- a/package.json +++ b/package.json @@ -82,7 +82,7 @@ "@react-spring/web": "^10.0.1", "@svgr/cli": "^8.1.0", "@tanstack/react-query": "^5.85.5", - "@umami/react-zen": "^0.176.0", + "@umami/react-zen": "^0.179.0", "@umami/redis-client": "^0.29.0", "bcryptjs": "^3.0.2", "chalk": "^5.6.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 3f5ea941..a587f004 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -45,8 +45,8 @@ importers: specifier: ^5.85.5 version: 5.85.5(react@19.1.1) '@umami/react-zen': - specifier: ^0.176.0 - version: 0.176.0(@babel/core@7.28.3)(@types/react@19.1.12)(babel-plugin-react-compiler@19.1.0-rc.2)(immer@10.1.1)(use-sync-external-store@1.5.0(react@19.1.1)) + specifier: ^0.179.0 + version: 0.179.0(@babel/core@7.28.3)(@types/react@19.1.12)(babel-plugin-react-compiler@19.1.0-rc.2)(immer@10.1.1)(use-sync-external-store@1.5.0(react@19.1.1)) '@umami/redis-client': specifier: ^0.29.0 version: 0.29.0 @@ -2735,8 +2735,8 @@ packages: '@prisma/client': ^6.1.0 '@prisma/extension-read-replicas': ^0.4.1 - '@umami/react-zen@0.176.0': - resolution: {integrity: sha512-GP+Df68w0Kfo09ZC5WgK1YCg/IbqOz7HWPw8PLYG3shYm+feuF8ND8DHjoTle4qXY4oRJFufXCEsDbTb8FITkg==} + '@umami/react-zen@0.179.0': + resolution: {integrity: sha512-OS6Xa1tMO2PfXYXEB98XyOBctvnw/gE2eO3gK5mkJF5P3Ati6Z9KpTpj28Fxi7PgJiWYqcQ5enFzQqHXjYy/3A==} '@umami/redis-client@0.29.0': resolution: {integrity: sha512-Jaqh++jskqDB7ny75pfC02OvKp1JTS4asGDsFrRL3qy8sxL3PAl9+/mybCJe4/6vWrXDJKqpgkSfUDJq2bFjyw==} @@ -10333,7 +10333,7 @@ snapshots: transitivePeerDependencies: - supports-color - '@umami/react-zen@0.176.0(@babel/core@7.28.3)(@types/react@19.1.12)(babel-plugin-react-compiler@19.1.0-rc.2)(immer@10.1.1)(use-sync-external-store@1.5.0(react@19.1.1))': + '@umami/react-zen@0.179.0(@babel/core@7.28.3)(@types/react@19.1.12)(babel-plugin-react-compiler@19.1.0-rc.2)(immer@10.1.1)(use-sync-external-store@1.5.0(react@19.1.1))': dependencies: '@fontsource/jetbrains-mono': 5.2.6 '@internationalized/date': 3.9.0 diff --git a/scripts/check-env.js b/scripts/check-env.js index 21de9469..c73bed54 100644 --- a/scripts/check-env.js +++ b/scripts/check-env.js @@ -22,6 +22,13 @@ if (!process.env.SKIP_DB_CHECK && !process.env.DATABASE_TYPE) { checkMissing(['DATABASE_URL']); } -if (process.env.CLOUD_MODE) { - checkMissing(['CLOUD_URL', 'KAFKA_BROKER', 'KAFKA_URL', 'REDIS_URL', 'KAFKA_SASL_MECHANISM']); +if (process.env.CLOUD_URL) { + checkMissing([ + 'CLOUD_URL', + 'CLICKHOUSE_URL', + 'REDIS_URL', + 'KAFKA_BROKER', + 'KAFKA_URL', + 'KAFKA_SASL_MECHANISM', + ]); } diff --git a/src/app/(main)/App.tsx b/src/app/(main)/App.tsx index bb33dc87..6c14a484 100644 --- a/src/app/(main)/App.tsx +++ b/src/app/(main)/App.tsx @@ -11,8 +11,8 @@ export function App({ children }) { const config = useConfig(); const pathname = usePathname(); - if (isLoading) { - return ; + if (isLoading || !config) { + return ; } if (error) { diff --git a/src/app/(main)/SideNav.tsx b/src/app/(main)/SideNav.tsx index a65640e1..7ffc9822 100644 --- a/src/app/(main)/SideNav.tsx +++ b/src/app/(main)/SideNav.tsx @@ -14,15 +14,13 @@ import { Link as LinkIcon, Logo, Pixel, - Settings, PanelLeft, } from '@/components/icons'; import { useMessages, useNavigation, useGlobalState } from '@/components/hooks'; import { TeamsButton } from '@/components/input/TeamsButton'; import { PanelButton } from '@/components/input/PanelButton'; -import { ProfileButton } from '@/components/input/ProfileButton'; -import { LanguageButton } from '@/components/input/LanguageButton'; import { Key } from 'react'; +import { SettingsButton } from '@/components/input/SettingsButton'; export function SideNav(props: SidebarProps) { const { formatMessage, labels } = useMessages(); @@ -58,17 +56,7 @@ export function SideNav(props: SidebarProps) { }, ]; - const bottomLinks = [ - { - id: 'settings', - label: formatMessage(labels.settings), - path: renderUrl('/settings'), - icon: , - }, - ]; - const handleSelect = (id: Key) => { - console.log({ id }); router.push(id === 'user' ? '/websites' : `/teams/${id}/websites`); }; @@ -78,18 +66,15 @@ export function SideNav(props: SidebarProps) { setIsCollapsed(false)}> - ) : ( - (window.location.href = process.env.cloudUrl)} /> - ) - } + icon={isCollapsed && !hasNav ? : } style={{ maxHeight: 40 }} > {!isCollapsed && !hasNav && } + + + {links.map(({ id, path, label, icon }) => { return ( @@ -104,30 +89,10 @@ export function SideNav(props: SidebarProps) { ); })} - - - - - {bottomLinks.map(({ id, path, label, icon }) => { - return ( - - - - ); - })} - - - {!isCollapsed && !hasNav && ( - - - - - )} + + + + {!isCollapsed && !hasNav && } diff --git a/src/app/(main)/UpdateNotice.tsx b/src/app/(main)/UpdateNotice.tsx index 35728791..c971d403 100644 --- a/src/app/(main)/UpdateNotice.tsx +++ b/src/app/(main)/UpdateNotice.tsx @@ -18,7 +18,7 @@ export function UpdateNotice({ user, config }) { !config?.updatesDisabled && !config?.privateMode && !pathname.includes('/share/') && - !process.env.cloudMode && + !process.env.cloudUrl && !dismissed; const updateCheck = useCallback(() => { diff --git a/src/app/(main)/admin/AdminLayout.tsx b/src/app/(main)/admin/AdminLayout.tsx index a33b745a..eb4c2ffa 100644 --- a/src/app/(main)/admin/AdminLayout.tsx +++ b/src/app/(main)/admin/AdminLayout.tsx @@ -11,7 +11,7 @@ export function AdminLayout({ children }: { children: ReactNode }) { const { formatMessage, labels } = useMessages(); const { pathname } = useNavigation(); - if (!user.isAdmin) { + if (!user.isAdmin || process.env.cloudUrl) { return null; } diff --git a/src/app/(main)/admin/layout.tsx b/src/app/(main)/admin/layout.tsx index 634fc658..3dea4142 100644 --- a/src/app/(main)/admin/layout.tsx +++ b/src/app/(main)/admin/layout.tsx @@ -2,7 +2,7 @@ import { Metadata } from 'next'; import { AdminLayout } from './AdminLayout'; export default function ({ children }) { - if (process.env.cloudMode) { + if (process.env.cloudUrl) { return null; } diff --git a/src/app/(main)/admin/users/[userId]/UserProvider.tsx b/src/app/(main)/admin/users/[userId]/UserProvider.tsx index 8ac321da..82dba512 100644 --- a/src/app/(main)/admin/users/[userId]/UserProvider.tsx +++ b/src/app/(main)/admin/users/[userId]/UserProvider.tsx @@ -9,7 +9,7 @@ export function UserProvider({ userId, children }: { userId: string; children: R const { data: user, isFetching, isLoading } = useUserQuery(userId); if (isFetching && isLoading) { - return ; + return ; } if (!user) { diff --git a/src/app/(main)/links/LinkEditForm.tsx b/src/app/(main)/links/LinkEditForm.tsx index b7a458dd..54237e43 100644 --- a/src/app/(main)/links/LinkEditForm.tsx +++ b/src/app/(main)/links/LinkEditForm.tsx @@ -78,7 +78,7 @@ export function LinkEditForm({ }, [data]); if (linkId && isLoading) { - return ; + return ; } return ( diff --git a/src/app/(main)/links/LinkProvider.tsx b/src/app/(main)/links/LinkProvider.tsx index 0a8900cf..de97cdcf 100644 --- a/src/app/(main)/links/LinkProvider.tsx +++ b/src/app/(main)/links/LinkProvider.tsx @@ -10,7 +10,7 @@ export function LinkProvider({ linkId, children }: { linkId?: string; children: const { data: link, isLoading, isFetching } = useLinkQuery(linkId); if (isFetching && isLoading) { - return ; + return ; } if (!link) { diff --git a/src/app/(main)/pixels/PixelEditForm.tsx b/src/app/(main)/pixels/PixelEditForm.tsx index bd29e69e..4d3def87 100644 --- a/src/app/(main)/pixels/PixelEditForm.tsx +++ b/src/app/(main)/pixels/PixelEditForm.tsx @@ -70,7 +70,7 @@ export function PixelEditForm({ }, [data]); if (pixelId && isLoading) { - return ; + return ; } return ( diff --git a/src/app/(main)/pixels/PixelProvider.tsx b/src/app/(main)/pixels/PixelProvider.tsx index d46b687d..3ba4c5e5 100644 --- a/src/app/(main)/pixels/PixelProvider.tsx +++ b/src/app/(main)/pixels/PixelProvider.tsx @@ -10,7 +10,7 @@ export function PixelProvider({ pixelId, children }: { pixelId?: string; childre const { data: pixel, isLoading, isFetching } = usePixelQuery(pixelId); if (isFetching && isLoading) { - return ; + return ; } if (!pixel) { diff --git a/src/app/(main)/settings/layout.tsx b/src/app/(main)/settings/layout.tsx index 1d4c418b..6f409e48 100644 --- a/src/app/(main)/settings/layout.tsx +++ b/src/app/(main)/settings/layout.tsx @@ -2,6 +2,10 @@ import { Metadata } from 'next'; import { SettingsLayout } from './SettingsLayout'; export default function ({ children }) { + if (process.env.cloudUrl) { + return null; + } + return {children}; } diff --git a/src/app/(main)/settings/preferences/DateRangeSetting.tsx b/src/app/(main)/settings/preferences/DateRangeSetting.tsx index ff92a8b0..2b81985f 100644 --- a/src/app/(main)/settings/preferences/DateRangeSetting.tsx +++ b/src/app/(main)/settings/preferences/DateRangeSetting.tsx @@ -15,7 +15,7 @@ export function DateRangeSetting() { return ( - + ); diff --git a/src/app/(main)/settings/preferences/LanguageSetting.tsx b/src/app/(main)/settings/preferences/LanguageSetting.tsx index 9e32196a..0bcaa6ba 100644 --- a/src/app/(main)/settings/preferences/LanguageSetting.tsx +++ b/src/app/(main)/settings/preferences/LanguageSetting.tsx @@ -26,7 +26,7 @@ export function LanguageSetting() { }; return ( - + saveTimezone(value)} diff --git a/src/app/(main)/settings/profile/ProfileSettings.tsx b/src/app/(main)/settings/profile/ProfileSettings.tsx index b580d686..156bf28e 100644 --- a/src/app/(main)/settings/profile/ProfileSettings.tsx +++ b/src/app/(main)/settings/profile/ProfileSettings.tsx @@ -1,12 +1,12 @@ import { Row, Column, Label } from '@umami/react-zen'; -import { useLoginQuery, useMessages } from '@/components/hooks'; +import { useConfig, useLoginQuery, useMessages } from '@/components/hooks'; import { ROLES } from '@/lib/constants'; import { PasswordChangeButton } from './PasswordChangeButton'; export function ProfileSettings() { const { user } = useLoginQuery(); const { formatMessage, labels } = useMessages(); - const cloudMode = !!process.env.cloudMode; + const { cloudMode } = useConfig(); if (!user) { return null; diff --git a/src/app/(main)/teams/TeamProvider.tsx b/src/app/(main)/teams/TeamProvider.tsx index 1c139b17..d4d31986 100644 --- a/src/app/(main)/teams/TeamProvider.tsx +++ b/src/app/(main)/teams/TeamProvider.tsx @@ -10,7 +10,7 @@ export function TeamProvider({ teamId, children }: { teamId?: string; children: const { data: team, isLoading, isFetching } = useTeamQuery(teamId); if (isFetching && isLoading) { - return ; + return ; } if (!team) { diff --git a/src/app/(main)/teams/TeamsDataTable.tsx b/src/app/(main)/teams/TeamsDataTable.tsx index 7700627c..b023f77e 100644 --- a/src/app/(main)/teams/TeamsDataTable.tsx +++ b/src/app/(main)/teams/TeamsDataTable.tsx @@ -1,10 +1,10 @@ +import { ReactNode } from 'react'; +import Link from 'next/link'; import { DataGrid } from '@/components/common/DataGrid'; import { TeamsTable } from './TeamsTable'; import { useLoginQuery, useUserTeamsQuery } from '@/components/hooks'; -import { ReactNode } from 'react'; export function TeamsDataTable({ - allowEdit, showActions, }: { allowEdit?: boolean; @@ -14,10 +14,18 @@ export function TeamsDataTable({ const { user } = useLoginQuery(); const query = useUserTeamsQuery(user.id); + const renderLink = (row: any) => { + return ( + + {row.name} + + ); + }; + return ( {({ data }) => { - return ; + return ; }} ); diff --git a/src/app/(main)/teams/TeamsHeader.tsx b/src/app/(main)/teams/TeamsHeader.tsx index 61244033..f7d7e520 100644 --- a/src/app/(main)/teams/TeamsHeader.tsx +++ b/src/app/(main)/teams/TeamsHeader.tsx @@ -1,14 +1,14 @@ import { Row } from '@umami/react-zen'; import { PageHeader } from '@/components/common/PageHeader'; import { ROLES } from '@/lib/constants'; -import { useLoginQuery, useMessages } from '@/components/hooks'; +import { useConfig, useLoginQuery, useMessages } from '@/components/hooks'; import { TeamsJoinButton } from './TeamsJoinButton'; import { TeamsAddButton } from './TeamsAddButton'; export function TeamsHeader({ allowCreate = true }: { allowCreate?: boolean }) { const { formatMessage, labels } = useMessages(); const { user } = useLoginQuery(); - const cloudMode = !!process.env.cloudMode; + const { cloudMode } = useConfig(); return ( diff --git a/src/app/(main)/teams/TeamsTable.tsx b/src/app/(main)/teams/TeamsTable.tsx index d77ede11..aaf27f52 100644 --- a/src/app/(main)/teams/TeamsTable.tsx +++ b/src/app/(main)/teams/TeamsTable.tsx @@ -1,25 +1,25 @@ import { DataColumn, DataTable, Icon, MenuItem, Text, Row } from '@umami/react-zen'; -import { useMessages, useNavigation } from '@/components/hooks'; +import { useMessages } from '@/components/hooks'; import { Eye, Edit } from '@/components/icons'; import { ROLES } from '@/lib/constants'; import { MenuButton } from '@/components/input/MenuButton'; -import Link from 'next/link'; +import { ReactNode } from 'react'; export function TeamsTable({ data = [], showActions = false, + renderLink, }: { data: any[]; - allowEdit?: boolean; showActions?: boolean; + renderLink?: (row: any) => ReactNode; }) { const { formatMessage, labels } = useMessages(); - const { renderUrl } = useNavigation(); return ( - {(row: any) => {row.name}} + {renderLink} {(row: any) => row?.members?.find(({ role }) => role === ROLES.teamOwner)?.user?.username} diff --git a/src/app/(main)/websites/WebsiteProvider.tsx b/src/app/(main)/websites/WebsiteProvider.tsx index 3f439550..4129cdd3 100644 --- a/src/app/(main)/websites/WebsiteProvider.tsx +++ b/src/app/(main)/websites/WebsiteProvider.tsx @@ -16,7 +16,7 @@ export function WebsiteProvider({ const { data: website, isFetching, isLoading } = useWebsiteQuery(websiteId); if (isFetching && isLoading) { - return ; + return ; } if (!website) { diff --git a/src/app/(main)/websites/WebsitesDataTable.tsx b/src/app/(main)/websites/WebsitesDataTable.tsx index 5015264a..612dc502 100644 --- a/src/app/(main)/websites/WebsitesDataTable.tsx +++ b/src/app/(main)/websites/WebsitesDataTable.tsx @@ -1,6 +1,7 @@ +import Link from 'next/link'; import { WebsitesTable } from './WebsitesTable'; import { DataGrid } from '@/components/common/DataGrid'; -import { useUserWebsitesQuery } from '@/components/hooks'; +import { useNavigation, useUserWebsitesQuery } from '@/components/hooks'; export function WebsitesDataTable({ teamId, @@ -14,16 +15,21 @@ export function WebsitesDataTable({ showActions?: boolean; }) { const queryResult = useUserWebsitesQuery({ teamId }); + const { renderUrl } = useNavigation(); + + const renderLink = (row: any) => ( + {row.name} + ); return ( {({ data }) => ( )} diff --git a/src/app/(main)/websites/WebsitesTable.tsx b/src/app/(main)/websites/WebsitesTable.tsx index c2077eb1..3fc22a98 100644 --- a/src/app/(main)/websites/WebsitesTable.tsx +++ b/src/app/(main)/websites/WebsitesTable.tsx @@ -3,27 +3,24 @@ import { Row, Text, Icon, DataTable, DataColumn, MenuItem } from '@umami/react-z import { useMessages, useNavigation } from '@/components/hooks'; import { MenuButton } from '@/components/input/MenuButton'; import { Eye, SquarePen } from '@/components/icons'; -import Link from 'next/link'; - -export interface WebsitesTableProps { - data: Record[]; - showActions?: boolean; - allowEdit?: boolean; - allowView?: boolean; - teamId?: string; - children?: ReactNode; -} export function WebsitesTable({ data = [], showActions, allowEdit, allowView, + renderLink, children, -}: WebsitesTableProps) { +}: { + data: Record[]; + showActions?: boolean; + allowEdit?: boolean; + allowView?: boolean; + renderLink?: (row: any) => ReactNode; + children?: ReactNode; +}) { const { formatMessage, labels } = useMessages(); - const { renderUrl, pathname } = useNavigation(); - const isSettings = pathname.includes('/settings'); + const { renderUrl } = useNavigation(); if (!data?.length) { return children; @@ -32,11 +29,7 @@ export function WebsitesTable({ return ( - {(row: any) => ( - - {row.name} - - )} + {renderLink} {showActions && ( diff --git a/src/app/(main)/websites/[websiteId]/(reports)/funnels/FunnelEditForm.tsx b/src/app/(main)/websites/[websiteId]/(reports)/funnels/FunnelEditForm.tsx index 1cf2bca2..57675bdf 100644 --- a/src/app/(main)/websites/[websiteId]/(reports)/funnels/FunnelEditForm.tsx +++ b/src/app/(main)/websites/[websiteId]/(reports)/funnels/FunnelEditForm.tsx @@ -50,7 +50,7 @@ export function FunnelEditForm({ }; if (id && !data) { - return ; + return ; } const defaultValues = { diff --git a/src/app/(main)/websites/[websiteId]/(reports)/goals/GoalEditForm.tsx b/src/app/(main)/websites/[websiteId]/(reports)/goals/GoalEditForm.tsx index 5556e4d8..2264ccf8 100644 --- a/src/app/(main)/websites/[websiteId]/(reports)/goals/GoalEditForm.tsx +++ b/src/app/(main)/websites/[websiteId]/(reports)/goals/GoalEditForm.tsx @@ -44,7 +44,7 @@ export function GoalEditForm({ }; if (id && !data) { - return ; + return ; } const defaultValues = { diff --git a/src/app/(main)/websites/[websiteId]/cohorts/CohortEditForm.tsx b/src/app/(main)/websites/[websiteId]/cohorts/CohortEditForm.tsx index 9e491a12..88e3d50d 100644 --- a/src/app/(main)/websites/[websiteId]/cohorts/CohortEditForm.tsx +++ b/src/app/(main)/websites/[websiteId]/cohorts/CohortEditForm.tsx @@ -52,7 +52,7 @@ export function CohortEditForm({ }; if (cohortId && !data) { - return ; + return ; } const defaultValues = { diff --git a/src/app/(main)/websites/[websiteId]/segments/SegmentEditForm.tsx b/src/app/(main)/websites/[websiteId]/segments/SegmentEditForm.tsx index b9a85c66..3be668d8 100644 --- a/src/app/(main)/websites/[websiteId]/segments/SegmentEditForm.tsx +++ b/src/app/(main)/websites/[websiteId]/segments/SegmentEditForm.tsx @@ -49,7 +49,7 @@ export function SegmentEditForm({ }; if (segmentId && !data) { - return ; + return ; } return ( diff --git a/src/app/(main)/websites/[websiteId]/settings/WebsiteTransferForm.tsx b/src/app/(main)/websites/[websiteId]/settings/WebsiteTransferForm.tsx index d0daefa9..4576b05e 100644 --- a/src/app/(main)/websites/[websiteId]/settings/WebsiteTransferForm.tsx +++ b/src/app/(main)/websites/[websiteId]/settings/WebsiteTransferForm.tsx @@ -64,7 +64,7 @@ export function WebsiteTransferForm({ }; if (isLoading) { - return ; + return ; } return ( diff --git a/src/app/actions/getConfig.ts b/src/app/actions/getConfig.ts index 9c26354a..534c008e 100644 --- a/src/app/actions/getConfig.ts +++ b/src/app/actions/getConfig.ts @@ -1,23 +1,27 @@ 'use server'; export type Config = { + cloudMode: boolean; + cloudUrl?: string; faviconUrl?: string; + linksUrl?: string; + pixelsUrl?: string; privateMode: boolean; telemetryDisabled: boolean; trackerScriptName?: string; updatesDisabled: boolean; - linksUrl?: string; - pixelsUrl?: string; }; export async function getConfig(): Promise { return { + cloudMode: !!process.env.CLOUD_URL, + cloudUrl: process.env.CLOUD_URL, faviconUrl: process.env.FAVICON_URL, + linksUrl: process.env.LINKS_URL, + pixelsUrl: process.env.PIXELS_URL, privateMode: !!process.env.PRIVATE_MODE, telemetryDisabled: !!process.env.DISABLE_TELEMETRY, trackerScriptName: process.env.TRACKER_SCRIPT_NAME, updatesDisabled: !!process.env.DISABLE_UPDATES, - linksUrl: process.env.LINKS_URL, - pixelsUrl: process.env.PIXELS_URL, }; } diff --git a/src/app/logout/LogoutPage.tsx b/src/app/logout/LogoutPage.tsx index 46988671..26dc4834 100644 --- a/src/app/logout/LogoutPage.tsx +++ b/src/app/logout/LogoutPage.tsx @@ -8,7 +8,7 @@ import { removeClientAuthToken } from '@/lib/client'; export function LogoutPage() { const router = useRouter(); const { post } = useApi(); - const disabled = process.env.cloudMode; + const disabled = process.env.cloudUrl; useEffect(() => { async function logout() { diff --git a/src/app/share/[...shareId]/Header.tsx b/src/app/share/[...shareId]/Header.tsx index eece42bb..88da5bec 100644 --- a/src/app/share/[...shareId]/Header.tsx +++ b/src/app/share/[...shareId]/Header.tsx @@ -1,7 +1,7 @@ import { Row, Icon, Text, ThemeButton } from '@umami/react-zen'; import Link from 'next/link'; import { LanguageButton } from '@/components/input/LanguageButton'; -import { SettingsButton } from '@/components/input/SettingsButton'; +import { PreferencesButton } from '@/components/input/PreferencesButton'; import { Logo } from '@/components/icons'; export function Header() { @@ -18,7 +18,7 @@ export function Header() { - + ); diff --git a/src/app/sso/SSOPage.tsx b/src/app/sso/SSOPage.tsx index b8893a6c..ec04c090 100644 --- a/src/app/sso/SSOPage.tsx +++ b/src/app/sso/SSOPage.tsx @@ -18,5 +18,5 @@ export function SSOPage() { } }, [router, url, token]); - return ; + return ; } diff --git a/src/components/common/LoadingPanel.tsx b/src/components/common/LoadingPanel.tsx index 9caffee8..d5abfef0 100644 --- a/src/components/common/LoadingPanel.tsx +++ b/src/components/common/LoadingPanel.tsx @@ -10,7 +10,7 @@ export interface LoadingPanelProps extends ColumnProps { isLoading?: boolean; isFetching?: boolean; loadingIcon?: 'dots' | 'spinner'; - loadingPosition?: 'center' | 'page' | 'inline'; + loadingPlacement?: 'center' | 'absolute' | 'inline'; renderEmpty?: () => ReactNode; children: ReactNode; } @@ -22,7 +22,7 @@ export function LoadingPanel({ isLoading, isFetching, loadingIcon = 'dots', - loadingPosition = 'page', + loadingPlacement = 'absolute', renderEmpty = () => , children, ...props @@ -34,7 +34,7 @@ export function LoadingPanel({ {/* Show loading spinner only if no data exists */} {(isLoading || isFetching) && ( - + )} diff --git a/src/components/common/PageBody.tsx b/src/components/common/PageBody.tsx index 7478280a..d7f1fc30 100644 --- a/src/components/common/PageBody.tsx +++ b/src/components/common/PageBody.tsx @@ -24,7 +24,7 @@ export function PageBody({ } if (isLoading) { - return ; + return ; } return ( diff --git a/src/components/icons.ts b/src/components/icons.ts index d25b5b72..c96a27b6 100644 --- a/src/components/icons.ts +++ b/src/components/icons.ts @@ -1,6 +1,7 @@ export { AlertTriangle as Alert, ArrowRight as Arrow, + Bookmark, Calendar, ChartPie, ChevronRight as Chevron, @@ -50,4 +51,20 @@ export { UserPlus, X as Close, } from 'lucide-react'; -export * from '@/components/svg'; +export { + Logo, + Bolt, + Change, + Compare, + Funnel, + Lightbulb, + Lightning, + Magnet, + Money, + Network, + Path, + Tag, + Target, + AddUser, + Visitor, +} from '@/components/svg'; diff --git a/src/components/input/DateFilter.tsx b/src/components/input/DateFilter.tsx index 2a1f9a2c..cd016491 100644 --- a/src/components/input/DateFilter.tsx +++ b/src/components/input/DateFilter.tsx @@ -1,12 +1,12 @@ import { useState, Key, Fragment } from 'react'; -import { Modal, Select, ListItem, ListSeparator, Dialog, Row } from '@umami/react-zen'; +import { Modal, Select, ListItem, ListSeparator, Dialog, SelectProps } from '@umami/react-zen'; import { endOfYear } from 'date-fns'; import { DatePickerForm } from '@/components/metrics/DatePickerForm'; import { useMessages } from '@/components/hooks'; import { DateDisplay } from '@/components/common/DateDisplay'; import { parseDateRange } from '@/lib/date'; -export interface DateFilterProps { +export interface DateFilterProps extends SelectProps { value?: string; onChange?: (value: string) => void; showAllTime?: boolean; @@ -20,6 +20,7 @@ export function DateFilter({ showAllTime, renderDate, placement = 'bottom', + ...props }: DateFilterProps) { const { formatMessage, labels } = useMessages(); const [showPicker, setShowPicker] = useState(false); @@ -99,8 +100,9 @@ export function DateFilter({ }; return ( - + <>