feat: duplicate report
This commit is contained in:
@@ -12,6 +12,7 @@ import {
|
||||
import { cn } from '@/utils/cn';
|
||||
import { createProjectTitle } from '@/utils/title';
|
||||
import {
|
||||
CopyIcon,
|
||||
LayoutPanelTopIcon,
|
||||
MoreHorizontal,
|
||||
PlusIcon,
|
||||
@@ -122,6 +123,7 @@ function ReportItem({
|
||||
endDate,
|
||||
interval,
|
||||
onDelete,
|
||||
onDuplicate,
|
||||
}: {
|
||||
report: any;
|
||||
organizationId: string;
|
||||
@@ -131,6 +133,7 @@ function ReportItem({
|
||||
endDate: any;
|
||||
interval: any;
|
||||
onDelete: (reportId: string) => void;
|
||||
onDuplicate: (reportId: string) => void;
|
||||
}) {
|
||||
const router = useRouter();
|
||||
const chartRange = report.range;
|
||||
@@ -218,6 +221,15 @@ function ReportItem({
|
||||
<MoreHorizontal size={16} />
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent align="end" className="w-[200px]">
|
||||
<DropdownMenuItem
|
||||
onClick={(event) => {
|
||||
event.stopPropagation();
|
||||
onDuplicate(report.id);
|
||||
}}
|
||||
>
|
||||
<CopyIcon size={16} className="mr-2" />
|
||||
Duplicate
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuGroup>
|
||||
<DropdownMenuItem
|
||||
className="text-destructive"
|
||||
@@ -320,6 +332,16 @@ function Component() {
|
||||
}),
|
||||
);
|
||||
|
||||
const reportDuplicate = useMutation(
|
||||
trpc.report.duplicate.mutationOptions({
|
||||
onError: handleErrorToastOptions({}),
|
||||
onSuccess() {
|
||||
reportsQuery.refetch();
|
||||
toast('Report duplicated');
|
||||
},
|
||||
}),
|
||||
);
|
||||
|
||||
const updateLayout = useMutation(
|
||||
trpc.report.updateLayout.mutationOptions({
|
||||
onError: handleErrorToastOptions({}),
|
||||
@@ -565,6 +587,9 @@ function Component() {
|
||||
onDelete={(reportId) => {
|
||||
reportDeletion.mutate({ reportId });
|
||||
}}
|
||||
onDuplicate={(reportId) => {
|
||||
reportDuplicate.mutate({ reportId });
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
))}
|
||||
|
||||
@@ -135,6 +135,49 @@ export const reportRouter = createTRPCRouter({
|
||||
},
|
||||
});
|
||||
}),
|
||||
duplicate: protectedProcedure
|
||||
.input(
|
||||
z.object({
|
||||
reportId: z.string(),
|
||||
}),
|
||||
)
|
||||
.mutation(async ({ input: { reportId }, 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');
|
||||
}
|
||||
|
||||
return db.report.create({
|
||||
data: {
|
||||
projectId: report.projectId,
|
||||
dashboardId: report.dashboardId,
|
||||
name: `Copy of ${report.name}`,
|
||||
events: report.events!,
|
||||
interval: report.interval,
|
||||
breakdowns: report.breakdowns!,
|
||||
chartType: report.chartType,
|
||||
lineType: report.lineType,
|
||||
range: report.range,
|
||||
formula: report.formula,
|
||||
previous: report.previous,
|
||||
unit: report.unit,
|
||||
criteria: report.criteria,
|
||||
metric: report.metric,
|
||||
funnelGroup: report.funnelGroup,
|
||||
funnelWindow: report.funnelWindow,
|
||||
},
|
||||
});
|
||||
}),
|
||||
get: protectedProcedure
|
||||
.input(
|
||||
z.object({
|
||||
|
||||
Reference in New Issue
Block a user