mirror of
https://github.com/umami-software/umami.git
synced 2026-02-04 04:37:11 +01:00
Layout changes.
This commit is contained in:
parent
16f1b15dee
commit
f5c4e1b46e
15 changed files with 71 additions and 1788 deletions
|
|
@ -1,4 +1,4 @@
|
||||||
export default {
|
{
|
||||||
"env": {
|
"env": {
|
||||||
"browser": true,
|
"browser": true,
|
||||||
"es2020": true,
|
"es2020": true,
|
||||||
|
|
@ -13,7 +13,7 @@ FROM node:22-alpine AS builder
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
COPY --from=deps /app/node_modules ./node_modules
|
COPY --from=deps /app/node_modules ./node_modules
|
||||||
COPY . .
|
COPY . .
|
||||||
COPY docker/middleware.js ./src
|
COPY docker/middleware.ts ./src
|
||||||
|
|
||||||
ARG DATABASE_TYPE
|
ARG DATABASE_TYPE
|
||||||
ARG BASE_PATH
|
ARG BASE_PATH
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
/* eslint-disable @typescript-eslint/no-var-requires */
|
/* eslint-disable @typescript-eslint/no-require-imports */
|
||||||
require('dotenv').config();
|
require('dotenv').config();
|
||||||
const pkg = require('./package.json');
|
const pkg = require('./package.json');
|
||||||
|
|
||||||
|
|
@ -182,7 +182,6 @@ const config = {
|
||||||
basePath,
|
basePath,
|
||||||
cloudMode,
|
cloudMode,
|
||||||
cloudUrl,
|
cloudUrl,
|
||||||
configUrl: '/config',
|
|
||||||
currentVersion: pkg.version,
|
currentVersion: pkg.version,
|
||||||
defaultLocale,
|
defaultLocale,
|
||||||
disableLogin,
|
disableLogin,
|
||||||
|
|
@ -191,9 +190,6 @@ const config = {
|
||||||
},
|
},
|
||||||
basePath,
|
basePath,
|
||||||
output: 'standalone',
|
output: 'standalone',
|
||||||
devIndicators: {
|
|
||||||
appIsrStatus: false,
|
|
||||||
},
|
|
||||||
eslint: {
|
eslint: {
|
||||||
ignoreDuringBuilds: true,
|
ignoreDuringBuilds: true,
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -112,7 +112,6 @@
|
||||||
"prisma": "6.5.0",
|
"prisma": "6.5.0",
|
||||||
"pure-rand": "^6.1.0",
|
"pure-rand": "^6.1.0",
|
||||||
"react": "^19.0.0",
|
"react": "^19.0.0",
|
||||||
"react-aria-components": "^1.6.0",
|
|
||||||
"react-basics": "^0.126.0",
|
"react-basics": "^0.126.0",
|
||||||
"react-dom": "^19.0.0",
|
"react-dom": "^19.0.0",
|
||||||
"react-error-boundary": "^5.0.0",
|
"react-error-boundary": "^5.0.0",
|
||||||
|
|
@ -196,7 +195,7 @@
|
||||||
"sharp"
|
"sharp"
|
||||||
],
|
],
|
||||||
"overrides": {
|
"overrides": {
|
||||||
"@umami/react-zen": "link:../../../Library/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"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
1753
pnpm-lock.yaml
generated
1753
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load diff
|
|
@ -1,5 +1,5 @@
|
||||||
'use client';
|
'use client';
|
||||||
import { Grid, Loading } from '@umami/react-zen';
|
import { Grid, Loading, Column } from '@umami/react-zen';
|
||||||
import Script from 'next/script';
|
import Script from 'next/script';
|
||||||
import { usePathname } from 'next/navigation';
|
import { usePathname } from 'next/navigation';
|
||||||
import { UpdateNotice } from './UpdateNotice';
|
import { UpdateNotice } from './UpdateNotice';
|
||||||
|
|
@ -30,10 +30,17 @@ export function App({ children }) {
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Grid height="100vh" width="100%" columns="auto 1fr">
|
<Grid
|
||||||
<Nav />
|
height="100vh"
|
||||||
<Grid rows="auto 1fr" overflow="auto">
|
width="100%"
|
||||||
<NavBar />
|
columns="auto 1fr"
|
||||||
|
rows="auto 1fr"
|
||||||
|
overflow="hidden"
|
||||||
|
backgroundColor="2"
|
||||||
|
>
|
||||||
|
<Nav gridColumn="1 / 2" gridRow="1 / 3" />
|
||||||
|
<NavBar gridColumn="2 / 3" gridRow="1 / 2" />
|
||||||
|
<Column alignItems="center" overflow="scroll">
|
||||||
<Page>
|
<Page>
|
||||||
<UpdateNotice user={user} config={config} />
|
<UpdateNotice user={user} config={config} />
|
||||||
{children}
|
{children}
|
||||||
|
|
@ -41,7 +48,7 @@ export function App({ children }) {
|
||||||
<Script src={`${process.env.basePath || ''}/telemetry.js`} />
|
<Script src={`${process.env.basePath || ''}/telemetry.js`} />
|
||||||
)}
|
)}
|
||||||
</Page>
|
</Page>
|
||||||
</Grid>
|
</Column>
|
||||||
</Grid>
|
</Grid>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,8 +11,9 @@ 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() {
|
export function Nav(props: SideNavProps) {
|
||||||
const { formatMessage, labels } = useMessages();
|
const { formatMessage, labels } = useMessages();
|
||||||
const { renderTeamUrl } = useTeamUrl();
|
const { renderTeamUrl } = useTeamUrl();
|
||||||
const [isCollapsed, setCollapsed] = useState(false);
|
const [isCollapsed, setCollapsed] = useState(false);
|
||||||
|
|
@ -46,7 +47,7 @@ export function Nav() {
|
||||||
].filter(n => n);
|
].filter(n => n);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<SideNav isCollapsed={isCollapsed} variant="3">
|
<SideNav {...props} isCollapsed={isCollapsed} variant="3" showBorder={false}>
|
||||||
<SideNavSection>
|
<SideNavSection>
|
||||||
<SideNavHeader label="umami" icon={<Icons.Logo />} />
|
<SideNavHeader label="umami" icon={<Icons.Logo />} />
|
||||||
</SideNavSection>
|
</SideNavSection>
|
||||||
|
|
@ -59,7 +60,7 @@ export function Nav() {
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
</SideNavSection>
|
</SideNavSection>
|
||||||
<SideNavSection>
|
<SideNavSection alignSelf="end">
|
||||||
<Row justifyContent="flex-start">
|
<Row justifyContent="flex-start">
|
||||||
<Button onPress={() => setCollapsed(!isCollapsed)} variant="quiet">
|
<Button onPress={() => setCollapsed(!isCollapsed)} variant="quiet">
|
||||||
<Icon>
|
<Icon>
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
'use client';
|
|
||||||
import { ThemeButton, Row } from '@umami/react-zen';
|
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';
|
||||||
|
|
@ -6,10 +5,9 @@ import { TeamsButton } from '@/components/input/TeamsButton';
|
||||||
|
|
||||||
export function NavBar() {
|
export function NavBar() {
|
||||||
return (
|
return (
|
||||||
<Row justifyContent="space-between" alignItems="center" paddingX="4" paddingY="3">
|
<Row justifyContent="space-between" alignItems="center" paddingY="3">
|
||||||
<div></div>
|
|
||||||
<Row justifyContent="flex-end">
|
|
||||||
<TeamsButton />
|
<TeamsButton />
|
||||||
|
<Row justifyContent="flex-end">
|
||||||
<ThemeButton />
|
<ThemeButton />
|
||||||
<LanguageButton />
|
<LanguageButton />
|
||||||
<ProfileButton />
|
<ProfileButton />
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ export default function ({ children }) {
|
||||||
<meta name="theme-color" content="#2f2f2f" media="(prefers-color-scheme: dark)" />
|
<meta name="theme-color" content="#2f2f2f" media="(prefers-color-scheme: dark)" />
|
||||||
<meta name="robots" content="noindex,nofollow" />
|
<meta name="robots" content="noindex,nofollow" />
|
||||||
</head>
|
</head>
|
||||||
<body suppressHydrationWarning>
|
<body>
|
||||||
<Providers>{children}</Providers>
|
<Providers>{children}</Providers>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
import type { Selection } from 'react-aria-components';
|
|
||||||
import { useRouter } from 'next/navigation';
|
import { useRouter } from 'next/navigation';
|
||||||
import {
|
import {
|
||||||
Text,
|
Text,
|
||||||
|
|
@ -31,7 +30,7 @@ export function TeamsButton({
|
||||||
const { teamId } = useTeamUrl();
|
const { teamId } = useTeamUrl();
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const team = result?.data?.find(({ id }) => id === teamId);
|
const team = result?.data?.find(({ id }) => id === teamId);
|
||||||
const [selectedKeys, setSelectedKeys] = useState<Selection>(new Set([teamId || user.id]));
|
const [selectedKeys, setSelectedKeys] = useState<any>(new Set([teamId || user.id]));
|
||||||
|
|
||||||
const handleSelect = (keys: Set<string>) => {
|
const handleSelect = (keys: Set<string>) => {
|
||||||
if (keys.size > 0) {
|
if (keys.size > 0) {
|
||||||
|
|
@ -58,7 +57,7 @@ export function TeamsButton({
|
||||||
</Icon>
|
</Icon>
|
||||||
</Row>
|
</Row>
|
||||||
</Button>
|
</Button>
|
||||||
<Popover placement="bottom end">
|
<Popover placement="bottom start">
|
||||||
<Box minWidth={300}>
|
<Box minWidth={300}>
|
||||||
<Menu
|
<Menu
|
||||||
selectionMode="single"
|
selectionMode="single"
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,13 @@
|
||||||
'use client';
|
'use client';
|
||||||
import { ReactNode } from 'react';
|
import { ReactNode } from 'react';
|
||||||
import classNames from 'classnames';
|
import { AlertBanner, Loading, Column } from '@umami/react-zen';
|
||||||
import { AlertBanner, Loading } from '@umami/react-zen';
|
|
||||||
import { useMessages } from '@/components/hooks';
|
import { useMessages } from '@/components/hooks';
|
||||||
import styles from './Page.module.css';
|
|
||||||
|
|
||||||
export function Page({
|
export function Page({
|
||||||
className,
|
|
||||||
error,
|
error,
|
||||||
isLoading,
|
isLoading,
|
||||||
children,
|
children,
|
||||||
|
...props
|
||||||
}: {
|
}: {
|
||||||
className?: string;
|
className?: string;
|
||||||
error?: unknown;
|
error?: unknown;
|
||||||
|
|
@ -26,5 +24,25 @@ export function Page({
|
||||||
return <Loading position="page" />;
|
return <Loading position="page" />;
|
||||||
}
|
}
|
||||||
|
|
||||||
return <div className={classNames(styles.page, className)}>{children}</div>;
|
return (
|
||||||
|
<Column
|
||||||
|
{...props}
|
||||||
|
gridColumn="2 / 3"
|
||||||
|
gridRow="2 / 3"
|
||||||
|
marginRight="6"
|
||||||
|
marginBottom="6"
|
||||||
|
width="100%"
|
||||||
|
maxWidth="1320px"
|
||||||
|
minHeight="600px"
|
||||||
|
margin="auto"
|
||||||
|
backgroundColor="1"
|
||||||
|
overflow="auto"
|
||||||
|
borderRadius="3"
|
||||||
|
borderSize="1"
|
||||||
|
paddingX="8"
|
||||||
|
paddingY="4"
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
</Column>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -85,7 +85,15 @@ export function MetricsTable({
|
||||||
}, [data, dataFilter, search, limit, formatValue, type]);
|
}, [data, dataFilter, search, limit, formatValue, type]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={classNames(styles.container, className)}>
|
<div
|
||||||
|
className={classNames(styles.container, className)}
|
||||||
|
style={{
|
||||||
|
background: 'var(--background-color)',
|
||||||
|
border: '1px solid var(--border-color)',
|
||||||
|
borderRadius: 'var(--border-radius)',
|
||||||
|
padding: '10px',
|
||||||
|
}}
|
||||||
|
>
|
||||||
{error && <ErrorMessage />}
|
{error && <ErrorMessage />}
|
||||||
<div className={styles.actions}>
|
<div className={styles.actions}>
|
||||||
{allowSearch && (
|
{allowSearch && (
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ export function ok() {
|
||||||
return Response.json({ ok: true });
|
return Response.json({ ok: true });
|
||||||
}
|
}
|
||||||
|
|
||||||
export function json(data: any) {
|
export function json(data: any = {}) {
|
||||||
return Response.json(data);
|
return Response.json(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -23,28 +23,24 @@ svg {
|
||||||
|
|
||||||
::-webkit-scrollbar {
|
::-webkit-scrollbar {
|
||||||
width: 15px;
|
width: 15px;
|
||||||
background: var(--background-color);
|
background: transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
::-webkit-scrollbar-track {
|
::-webkit-scrollbar-track {
|
||||||
border: 7px solid rgba(0, 0, 0, 0);
|
border: 7px solid rgba(0, 0, 0, 0);
|
||||||
background-color: var(--border-color);
|
background-color: var(--base-color-3);
|
||||||
background-clip: padding-box;
|
background-clip: padding-box;
|
||||||
}
|
}
|
||||||
|
|
||||||
body::-webkit-scrollbar-track,
|
|
||||||
main::-webkit-scrollbar-track {
|
|
||||||
background-color: var(--border-color);
|
|
||||||
}
|
|
||||||
|
|
||||||
::-webkit-scrollbar-thumb {
|
::-webkit-scrollbar-thumb {
|
||||||
border: 7px solid rgba(0, 0, 0, 0);
|
border: 7px solid rgba(0, 0, 0, 0);
|
||||||
background-color: var(--font-color);
|
background-color: var(--base-color-8);
|
||||||
|
border-radius: var(--border-radius-full);
|
||||||
background-clip: padding-box;
|
background-clip: padding-box;
|
||||||
}
|
}
|
||||||
|
|
||||||
::-webkit-scrollbar-thumb:hover {
|
::-webkit-scrollbar-thumb:hover {
|
||||||
border: 4px solid rgba(0, 0, 0, 0);
|
border: 4px solid rgba(0, 0, 0, 0);
|
||||||
background-color: var(--font-color);
|
background-color: var(--base-color-8);
|
||||||
background-clip: padding-box;
|
background-clip: padding-box;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue