This commit is contained in:
ABHISHEK 2025-10-04 12:54:32 +02:00 committed by GitHub
commit e6458a383a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 593 additions and 307 deletions

View file

@ -149,6 +149,21 @@ describe('Website API tests', () => {
});
});
it('Updates a website with only shareId.', () => {
cy.request({
method: 'POST',
url: `/api/websites/${websiteId}`,
headers: {
'Content-Type': 'application/json',
Authorization: Cypress.env('authorization'),
},
body: { shareId: 'ABCDEF' },
}).then(response => {
expect(response.status).to.eq(200);
expect(response.body).to.have.property('shareId', 'ABCDEF');
});
});
it('Resets a website by removing all data related to the website.', () => {
cy.request({
method: 'POST',

View file

@ -3,11 +3,11 @@ services:
umami:
image: ghcr.io/umami-software/umami:postgresql-latest
ports:
- "3000:3000"
- "3001:3000"
environment:
DATABASE_URL: postgresql://umami:umami@db:5432/umami
DATABASE_TYPE: postgresql
APP_SECRET: replace-me-with-a-random-string
APP_SECRET: umami-local-development-secret-key-2025
depends_on:
db:
condition: service_healthy

View file

@ -107,9 +107,9 @@
"jsonwebtoken": "^9.0.2",
"jszip": "^3.10.1",
"kafkajs": "^2.1.0",
"lucide-react": "^0.543.0",
"maxmind": "^5.0.0",
"next": "15.5.3",
"maxmind": "^4.3.24",
"md5": "^2.3.0",
"next": "15.4.7",
"node-fetch": "^3.2.8",
"npm-run-all": "^4.1.5",
"papaparse": "^5.5.3",

811
pnpm-lock.yaml generated

File diff suppressed because it is too large Load diff

View file

@ -8,10 +8,40 @@ export function DashboardPage() {
const { formatMessage, labels } = useMessages();
return (
<PageBody>
<Column margin="2">
<PageHeader title={formatMessage(labels.dashboard)}></PageHeader>
</Column>
</PageBody>
<section style={{ marginBottom: 60 }}>
<PageHeader title={formatMessage(labels.dashboard)}>
{!editing && hasData && <DashboardSettingsButton />}
</PageHeader>
{!hasData && (
<EmptyPlaceholder message={formatMessage(messages.noWebsitesConfigured)}>
<LinkButton href={renderTeamUrl('/settings')}>
<Icon rotate={dir === 'rtl' ? 180 : 0}>
<Icons.ArrowRight />
</Icon>
<Text>{formatMessage(messages.goToSettings)}</Text>
</LinkButton>
</EmptyPlaceholder>
)}
{hasData && (
<>
{editing && <DashboardEdit teamId={teamId} />}
{!editing && (
<>
<WebsiteChartList
websites={result?.data as any}
showCharts={showCharts}
limit={pageSize}
/>
<Pager
page={Number(page) || 1}
pageSize={pageSize}
count={result?.count}
onPageChange={handlePageChange}
/>
</>
)}
</>
)}
</section>
);
}

View file

@ -94,18 +94,18 @@ export const DATE_FUNCTIONS = {
},
};
export const DATE_FORMATS = {
minute: 'yyyy-MM-dd HH:mm',
hour: 'yyyy-MM-dd HH',
day: 'yyyy-MM-dd',
week: "yyyy-'W'II",
month: 'yyyy-MM',
year: 'yyyy',
const TIMEZONE_MAPPINGS: Record<string, string> = {
'Asia/Calcutta': 'Asia/Kolkata',
};
export function normalizeTimezone(timezone: string): string {
return TIMEZONE_MAPPINGS[timezone] || timezone;
}
export function isValidTimezone(timezone: string) {
try {
Intl.DateTimeFormat(undefined, { timeZone: timezone });
const normalizedTimezone = normalizeTimezone(timezone);
Intl.DateTimeFormat(undefined, { timeZone: normalizedTimezone });
return true;
} catch {
return false;

View file

@ -1,5 +1,5 @@
import { z } from 'zod';
import { isValidTimezone } from '@/lib/date';
import { isValidTimezone, normalizeTimezone } from '@/lib/date';
import { UNIT_TYPES } from './constants';
export const timezoneParam = z.string().refine(value => isValidTimezone(value), {
@ -49,9 +49,9 @@ export const pagingParams = {
pageSize: z.coerce.number().int().positive().optional(),
};
export const sortingParams = {
orderBy: z.string().optional(),
};
export const timezoneParam = z.string().refine((value: string) => isValidTimezone(value), {
message: 'Invalid timezone',
}).transform((value: string) => normalizeTimezone(value));
export const userRoleParam = z.enum(['admin', 'user', 'view-only']);