mirror of
https://github.com/umami-software/umami.git
synced 2026-02-15 01:55:36 +01:00
Added Panel component. New color scheme.
This commit is contained in:
parent
a7dad20d8a
commit
5d2c1e27c2
13 changed files with 64 additions and 64 deletions
|
|
@ -194,9 +194,6 @@
|
||||||
"esbuild",
|
"esbuild",
|
||||||
"prisma",
|
"prisma",
|
||||||
"sharp"
|
"sharp"
|
||||||
],
|
]
|
||||||
"overrides": {
|
|
||||||
"@umami/react-zen": "link:C:/Users/mike/AppData/Local/pnpm/global/5/node_modules/@umami/react-zen"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
4
pnpm-lock.yaml
generated
4
pnpm-lock.yaml
generated
|
|
@ -5,7 +5,6 @@ settings:
|
||||||
excludeLinksFromLockfile: false
|
excludeLinksFromLockfile: false
|
||||||
|
|
||||||
overrides:
|
overrides:
|
||||||
react-zen: link:C:/Users/mike/AppData/Local/pnpm/global/5/node_modules/@umami/react-zen
|
|
||||||
'@umami/react-zen': link:C:/Users/mike/AppData/Local/pnpm/global/5/node_modules/@umami/react-zen
|
'@umami/react-zen': link:C:/Users/mike/AppData/Local/pnpm/global/5/node_modules/@umami/react-zen
|
||||||
|
|
||||||
importers:
|
importers:
|
||||||
|
|
@ -174,9 +173,6 @@ importers:
|
||||||
react-window:
|
react-window:
|
||||||
specifier: ^1.8.11
|
specifier: ^1.8.11
|
||||||
version: 1.8.11(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
|
version: 1.8.11(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
|
||||||
react-zen:
|
|
||||||
specifier: link:C:/Users/mike/AppData/Local/pnpm/global/5/node_modules/@umami/react-zen
|
|
||||||
version: link:C:/Users/mike/AppData/Local/pnpm/global/5/node_modules/@umami/react-zen
|
|
||||||
request-ip:
|
request-ip:
|
||||||
specifier: ^3.3.0
|
specifier: ^3.3.0
|
||||||
version: 3.3.0
|
version: 3.3.0
|
||||||
|
|
|
||||||
|
|
@ -30,25 +30,18 @@ export function App({ children }) {
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Grid
|
<Grid height="100vh" width="100%" columns="auto 1fr" rows="auto 1fr" overflow="hidden">
|
||||||
height="100vh"
|
|
||||||
width="100%"
|
|
||||||
columns="auto 1fr"
|
|
||||||
rows="auto 1fr"
|
|
||||||
overflow="hidden"
|
|
||||||
backgroundColor="2"
|
|
||||||
>
|
|
||||||
<Nav gridColumn="1 / 2" gridRow="1 / 3" />
|
<Nav gridColumn="1 / 2" gridRow="1 / 3" />
|
||||||
<NavBar gridColumn="2 / 3" gridRow="1 / 2" />
|
<NavBar gridColumn="2 / 3" gridRow="1 / 2" />
|
||||||
<Column alignItems="center" overflow="scroll">
|
<Column gridColumn="2 / 3" gridRow="2 / 3" alignItems="center" overflow="auto">
|
||||||
<Page>
|
<Page>
|
||||||
<UpdateNotice user={user} config={config} />
|
|
||||||
{children}
|
{children}
|
||||||
{process.env.NODE_ENV === 'production' && !pathname.includes('/share/') && (
|
{process.env.NODE_ENV === 'production' && !pathname.includes('/share/') && (
|
||||||
<Script src={`${process.env.basePath || ''}/telemetry.js`} />
|
<Script src={`${process.env.basePath || ''}/telemetry.js`} />
|
||||||
)}
|
)}
|
||||||
</Page>
|
</Page>
|
||||||
</Column>
|
</Column>
|
||||||
|
<UpdateNotice user={user} config={config} />
|
||||||
</Grid>
|
</Grid>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,11 +11,10 @@ import {
|
||||||
} from '@umami/react-zen';
|
} from '@umami/react-zen';
|
||||||
import { Lucide, Icons } from '@/components/icons';
|
import { Lucide, Icons } from '@/components/icons';
|
||||||
import { useMessages, useTeamUrl } from '@/components/hooks';
|
import { useMessages, useTeamUrl } from '@/components/hooks';
|
||||||
import type { SideNavProps } from '@umami/react-zen/SideNav';
|
|
||||||
|
|
||||||
export function Nav(props: SideNavProps) {
|
export function Nav(props: any) {
|
||||||
const { formatMessage, labels } = useMessages();
|
const { formatMessage, labels } = useMessages();
|
||||||
const { renderTeamUrl } = useTeamUrl();
|
const { renderTeamUrl, pathname } = useTeamUrl();
|
||||||
const [isCollapsed, setCollapsed] = useState(false);
|
const [isCollapsed, setCollapsed] = useState(false);
|
||||||
|
|
||||||
const links = [
|
const links = [
|
||||||
|
|
@ -47,7 +46,7 @@ export function Nav(props: SideNavProps) {
|
||||||
].filter(n => n);
|
].filter(n => n);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<SideNav {...props} isCollapsed={isCollapsed} variant="3" showBorder={false}>
|
<SideNav {...props} isCollapsed={isCollapsed} variant="3" showBorder={true}>
|
||||||
<SideNavSection>
|
<SideNavSection>
|
||||||
<SideNavHeader label="umami" icon={<Icons.Logo />} />
|
<SideNavHeader label="umami" icon={<Icons.Logo />} />
|
||||||
</SideNavSection>
|
</SideNavSection>
|
||||||
|
|
@ -55,7 +54,7 @@ export function Nav(props: SideNavProps) {
|
||||||
{links.map(({ href, label, icon }) => {
|
{links.map(({ href, label, icon }) => {
|
||||||
return (
|
return (
|
||||||
<Link key={href} href={href}>
|
<Link key={href} href={href}>
|
||||||
<SideNavItem label={label} icon={icon} />
|
<SideNavItem label={label} icon={icon} isSelected={pathname.startsWith(href)} />
|
||||||
</Link>
|
</Link>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
|
|
|
||||||
|
|
@ -2,10 +2,18 @@ import { ThemeButton, Row } from '@umami/react-zen';
|
||||||
import { LanguageButton } from '@/components/input/LanguageButton';
|
import { LanguageButton } from '@/components/input/LanguageButton';
|
||||||
import { ProfileButton } from '@/components/input/ProfileButton';
|
import { ProfileButton } from '@/components/input/ProfileButton';
|
||||||
import { TeamsButton } from '@/components/input/TeamsButton';
|
import { TeamsButton } from '@/components/input/TeamsButton';
|
||||||
|
import type { RowProps } from '@umami/react-zen/Row';
|
||||||
|
|
||||||
export function NavBar() {
|
export function NavBar(props: RowProps) {
|
||||||
return (
|
return (
|
||||||
<Row justifyContent="space-between" alignItems="center" paddingY="3">
|
<Row
|
||||||
|
{...props}
|
||||||
|
justifyContent="space-between"
|
||||||
|
alignItems="center"
|
||||||
|
paddingY="3"
|
||||||
|
paddingX="3"
|
||||||
|
paddingRight="5"
|
||||||
|
>
|
||||||
<TeamsButton />
|
<TeamsButton />
|
||||||
<Row justifyContent="flex-end">
|
<Row justifyContent="flex-end">
|
||||||
<ThemeButton />
|
<ThemeButton />
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ import { Column, Tabs, TabList, Tab, TabPanel } from '@umami/react-zen';
|
||||||
import { TeamLeaveButton } from '@/app/(main)/settings/teams/TeamLeaveButton';
|
import { TeamLeaveButton } from '@/app/(main)/settings/teams/TeamLeaveButton';
|
||||||
import { TeamManage } from './TeamManage';
|
import { TeamManage } from './TeamManage';
|
||||||
import { TeamEditForm } from './TeamEditForm';
|
import { TeamEditForm } from './TeamEditForm';
|
||||||
|
import { Panel } from '@/components/layout/Panel';
|
||||||
|
|
||||||
export function TeamDetails({ teamId }: { teamId: string }) {
|
export function TeamDetails({ teamId }: { teamId: string }) {
|
||||||
const team = useContext(TeamContext);
|
const team = useContext(TeamContext);
|
||||||
|
|
@ -30,18 +31,20 @@ export function TeamDetails({ teamId }: { teamId: string }) {
|
||||||
<PageHeader title={team?.name} icon={<Icons.Users />}>
|
<PageHeader title={team?.name} icon={<Icons.Users />}>
|
||||||
{!isTeamOwner && <TeamLeaveButton teamId={team.id} teamName={team.name} />}
|
{!isTeamOwner && <TeamLeaveButton teamId={team.id} teamName={team.name} />}
|
||||||
</PageHeader>
|
</PageHeader>
|
||||||
<Tabs selectedKey={tab} onSelectionChange={(value: any) => setTab(value)}>
|
<Panel>
|
||||||
<TabList>
|
<Tabs selectedKey={tab} onSelectionChange={(value: any) => setTab(value)}>
|
||||||
<Tab id="details">{formatMessage(labels.details)}</Tab>
|
<TabList>
|
||||||
{isTeamOwner && <Tab id="manage">{formatMessage(labels.manage)}</Tab>}
|
<Tab id="details">{formatMessage(labels.details)}</Tab>
|
||||||
</TabList>
|
{isTeamOwner && <Tab id="manage">{formatMessage(labels.manage)}</Tab>}
|
||||||
<TabPanel id="details">
|
</TabList>
|
||||||
<TeamEditForm teamId={teamId} allowEdit={canEdit} />
|
<TabPanel id="details">
|
||||||
</TabPanel>
|
<TeamEditForm teamId={teamId} allowEdit={canEdit} />
|
||||||
<TabPanel id="manage">
|
</TabPanel>
|
||||||
<TeamManage teamId={teamId} />
|
<TabPanel id="manage">
|
||||||
</TabPanel>
|
<TeamManage teamId={teamId} />
|
||||||
</Tabs>
|
</TabPanel>
|
||||||
|
</Tabs>
|
||||||
|
</Panel>
|
||||||
</Column>
|
</Column>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ import { Loading, SearchField, Row, Column } from '@umami/react-zen';
|
||||||
import { useMessages, useNavigation } from '@/components/hooks';
|
import { useMessages, useNavigation } from '@/components/hooks';
|
||||||
import { Empty } from '@/components/common/Empty';
|
import { Empty } from '@/components/common/Empty';
|
||||||
import { Pager } from '@/components/common/Pager';
|
import { Pager } from '@/components/common/Pager';
|
||||||
|
import { Panel } from '@/components/layout/Panel';
|
||||||
import { LoadingPanel } from '@/components/common/LoadingPanel';
|
import { LoadingPanel } from '@/components/common/LoadingPanel';
|
||||||
import { PagedQueryResult } from '@/lib/types';
|
import { PagedQueryResult } from '@/lib/types';
|
||||||
|
|
||||||
|
|
@ -59,12 +60,14 @@ export function DataGrid({
|
||||||
</Row>
|
</Row>
|
||||||
)}
|
)}
|
||||||
<LoadingPanel data={data} isLoading={isLoading} isFetched={isFetched} error={error}>
|
<LoadingPanel data={data} isLoading={isLoading} isFetched={isFetched} error={error}>
|
||||||
<Column>
|
<Panel>
|
||||||
{hasData ? (typeof children === 'function' ? children(result) : children) : null}
|
<Column>
|
||||||
{isLoading && <Loading position="page" />}
|
{hasData ? (typeof children === 'function' ? children(result) : children) : null}
|
||||||
{!isLoading && !hasData && !search && (renderEmpty ? renderEmpty() : <Empty />)}
|
{isLoading && <Loading position="page" />}
|
||||||
{!isLoading && noResults && <Empty message={formatMessage(messages.noResultsFound)} />}
|
{!isLoading && !hasData && !search && (renderEmpty ? renderEmpty() : <Empty />)}
|
||||||
</Column>
|
{!isLoading && noResults && <Empty message={formatMessage(messages.noResultsFound)} />}
|
||||||
|
</Column>
|
||||||
|
</Panel>
|
||||||
{allowPaging && hasData && (
|
{allowPaging && hasData && (
|
||||||
<Row marginTop="6">
|
<Row marginTop="6">
|
||||||
<Pager page={page} pageSize={pageSize} count={count} onPageChange={handlePageChange} />
|
<Pager page={page} pageSize={pageSize} count={count} onPageChange={handlePageChange} />
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,6 @@
|
||||||
import { usePathname } from 'next/navigation';
|
import { usePathname } from 'next/navigation';
|
||||||
|
|
||||||
export function useTeamUrl(): {
|
export function useTeamUrl() {
|
||||||
teamId?: string;
|
|
||||||
renderTeamUrl: (url: string) => string;
|
|
||||||
} {
|
|
||||||
const pathname = usePathname();
|
const pathname = usePathname();
|
||||||
const [, teamId] = pathname.match(/^\/teams\/([a-f0-9-]+)/) || [];
|
const [, teamId] = pathname.match(/^\/teams\/([a-f0-9-]+)/) || [];
|
||||||
|
|
||||||
|
|
@ -11,5 +8,5 @@ export function useTeamUrl(): {
|
||||||
return teamId ? `/teams/${teamId}${url}` : url;
|
return teamId ? `/teams/${teamId}${url}` : url;
|
||||||
}
|
}
|
||||||
|
|
||||||
return { teamId, renderTeamUrl };
|
return { teamId, renderTeamUrl, pathname };
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -35,12 +35,6 @@ export function Page({
|
||||||
maxWidth="1320px"
|
maxWidth="1320px"
|
||||||
minHeight="600px"
|
minHeight="600px"
|
||||||
margin="auto"
|
margin="auto"
|
||||||
backgroundColor="1"
|
|
||||||
overflow="auto"
|
|
||||||
borderRadius="3"
|
|
||||||
borderSize="1"
|
|
||||||
paddingX="8"
|
|
||||||
paddingY="4"
|
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
</Column>
|
</Column>
|
||||||
|
|
|
||||||
6
src/components/layout/Panel.tsx
Normal file
6
src/components/layout/Panel.tsx
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
import { Box } from '@umami/react-zen';
|
||||||
|
import type { BoxProps } from '@umami/react-zen/Box';
|
||||||
|
|
||||||
|
export function Panel(props: BoxProps) {
|
||||||
|
return <Box padding="6" borderSize="1" borderRadius="3" backgroundColor="solid" {...props} />;
|
||||||
|
}
|
||||||
|
|
@ -91,7 +91,7 @@ export function MetricsTable({
|
||||||
background: 'var(--background-color)',
|
background: 'var(--background-color)',
|
||||||
border: '1px solid var(--border-color)',
|
border: '1px solid var(--border-color)',
|
||||||
borderRadius: 'var(--border-radius)',
|
borderRadius: 'var(--border-radius)',
|
||||||
padding: '10px',
|
padding: '16px',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{error && <ErrorMessage />}
|
{error && <ErrorMessage />}
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ import { useMemo } from 'react';
|
||||||
import { BarChart, BarChartProps } from '@/components/charts/BarChart';
|
import { BarChart, BarChartProps } from '@/components/charts/BarChart';
|
||||||
import { useLocale, useTheme, useMessages } from '@/components/hooks';
|
import { useLocale, useTheme, useMessages } from '@/components/hooks';
|
||||||
import { renderDateLabels } from '@/lib/charts';
|
import { renderDateLabels } from '@/lib/charts';
|
||||||
|
import { Panel } from '@/components/layout/Panel';
|
||||||
|
|
||||||
export interface PageviewsChartProps extends BarChartProps {
|
export interface PageviewsChartProps extends BarChartProps {
|
||||||
data: {
|
data: {
|
||||||
|
|
@ -76,13 +77,15 @@ export function PageviewsChart({
|
||||||
}, [data, locale]);
|
}, [data, locale]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<BarChart
|
<Panel>
|
||||||
{...props}
|
<BarChart
|
||||||
data={chartData}
|
{...props}
|
||||||
unit={unit}
|
data={chartData}
|
||||||
isLoading={isLoading}
|
unit={unit}
|
||||||
isAllTime={isAllTime}
|
isLoading={isLoading}
|
||||||
renderXLabel={renderDateLabels(unit, locale)}
|
isAllTime={isAllTime}
|
||||||
/>
|
renderXLabel={renderDateLabels(unit, locale)}
|
||||||
|
/>
|
||||||
|
</Panel>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,9 +3,10 @@ body {
|
||||||
font-family: var(--font-family), sans-serif;
|
font-family: var(--font-family), sans-serif;
|
||||||
color: var(--font-color);
|
color: var(--font-color);
|
||||||
font-size: var(--font-size);
|
font-size: var(--font-size);
|
||||||
background-color: var(--base-color-1);
|
background-color: var(--base-color-2);
|
||||||
width: 100%;
|
width: 100%;
|
||||||
min-height: 100vh;
|
min-height: 100vh;
|
||||||
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
a,
|
a,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue