feat: dashboard v2, esm, upgrades (#211)

* esm

* wip

* wip

* wip

* wip

* wip

* wip

* subscription notice

* wip

* wip

* wip

* fix envs

* fix: update docker build

* fix

* esm/types

* delete dashboard :D

* add patches to dockerfiles

* update packages + catalogs + ts

* wip

* remove native libs

* ts

* improvements

* fix redirects and fetching session

* try fix favicon

* fixes

* fix

* order and resize reportds within a dashboard

* improvements

* wip

* added userjot to dashboard

* fix

* add op

* wip

* different cache key

* improve date picker

* fix table

* event details loading

* redo onboarding completely

* fix login

* fix

* fix

* extend session, billing and improve bars

* fix

* reduce price on 10M
This commit is contained in:
Carl-Gerhard Lindesvärd
2025-10-16 12:27:44 +02:00
committed by GitHub
parent 436e81ecc9
commit 81a7e5d62e
741 changed files with 32695 additions and 16996 deletions

View File

@@ -1,6 +1,6 @@
import { z } from 'zod';
import { db } from '@openpanel/db';
import { db, getReportById, getReportsByDashboardId } from '@openpanel/db';
import { zReportInput } from '@openpanel/validation';
import { getProjectAccess } from '../access';
@@ -8,6 +8,16 @@ import { TRPCAccessError } from '../errors';
import { createTRPCRouter, protectedProcedure } from '../trpc';
export const reportRouter = createTRPCRouter({
list: protectedProcedure
.input(
z.object({
dashboardId: z.string(),
projectId: z.string(),
}),
)
.query(async ({ input: { dashboardId, projectId }, ctx }) => {
return getReportsByDashboardId(dashboardId);
}),
create: protectedProcedure
.input(
z.object({
@@ -125,4 +135,127 @@ export const reportRouter = createTRPCRouter({
},
});
}),
get: protectedProcedure
.input(
z.object({
reportId: z.string(),
}),
)
.query(async ({ input: { reportId }, ctx }) => {
return getReportById(reportId);
}),
updateLayout: protectedProcedure
.input(
z.object({
reportId: z.string(),
layout: z.object({
x: z.number(),
y: z.number(),
w: z.number(),
h: z.number(),
minW: z.number().optional(),
minH: z.number().optional(),
maxW: z.number().optional(),
maxH: z.number().optional(),
}),
}),
)
.mutation(async ({ input: { reportId, layout }, ctx }) => {
const report = await db.report.findUniqueOrThrow({
where: {
id: reportId,
},
});
const access = await getProjectAccess({
userId: ctx.session.userId,
projectId: report.projectId,
});
if (!access) {
throw TRPCAccessError('You do not have access to this project');
}
// Upsert the layout (create if doesn't exist, update if it does)
return db.reportLayout.upsert({
where: {
reportId: reportId,
},
create: {
reportId: reportId,
x: layout.x,
y: layout.y,
w: layout.w,
h: layout.h,
minW: layout.minW,
minH: layout.minH,
maxW: layout.maxW,
maxH: layout.maxH,
},
update: {
x: layout.x,
y: layout.y,
w: layout.w,
h: layout.h,
minW: layout.minW,
minH: layout.minH,
maxW: layout.maxW,
maxH: layout.maxH,
},
});
}),
getLayouts: protectedProcedure
.input(
z.object({
dashboardId: z.string(),
projectId: z.string(),
}),
)
.query(async ({ input: { dashboardId, projectId }, ctx }) => {
const access = await getProjectAccess({
userId: ctx.session.userId,
projectId: projectId,
});
if (!access) {
throw TRPCAccessError('You do not have access to this project');
}
return db.reportLayout.findMany({
where: {
report: {
dashboardId: dashboardId,
},
},
include: {
report: true,
},
});
}),
resetLayout: protectedProcedure
.input(
z.object({
dashboardId: z.string(),
projectId: z.string(),
}),
)
.mutation(async ({ input: { dashboardId, projectId }, ctx }) => {
const access = await getProjectAccess({
userId: ctx.session.userId,
projectId: projectId,
});
if (!access) {
throw TRPCAccessError('You do not have access to this project');
}
// Delete all layout data for reports in this dashboard
return db.reportLayout.deleteMany({
where: {
report: {
dashboardId: dashboardId,
},
},
});
}),
});