feat: duplicate report
This commit is contained in:
@@ -12,6 +12,7 @@ import {
|
|||||||
import { cn } from '@/utils/cn';
|
import { cn } from '@/utils/cn';
|
||||||
import { createProjectTitle } from '@/utils/title';
|
import { createProjectTitle } from '@/utils/title';
|
||||||
import {
|
import {
|
||||||
|
CopyIcon,
|
||||||
LayoutPanelTopIcon,
|
LayoutPanelTopIcon,
|
||||||
MoreHorizontal,
|
MoreHorizontal,
|
||||||
PlusIcon,
|
PlusIcon,
|
||||||
@@ -122,6 +123,7 @@ function ReportItem({
|
|||||||
endDate,
|
endDate,
|
||||||
interval,
|
interval,
|
||||||
onDelete,
|
onDelete,
|
||||||
|
onDuplicate,
|
||||||
}: {
|
}: {
|
||||||
report: any;
|
report: any;
|
||||||
organizationId: string;
|
organizationId: string;
|
||||||
@@ -131,6 +133,7 @@ function ReportItem({
|
|||||||
endDate: any;
|
endDate: any;
|
||||||
interval: any;
|
interval: any;
|
||||||
onDelete: (reportId: string) => void;
|
onDelete: (reportId: string) => void;
|
||||||
|
onDuplicate: (reportId: string) => void;
|
||||||
}) {
|
}) {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const chartRange = report.range;
|
const chartRange = report.range;
|
||||||
@@ -218,6 +221,15 @@ function ReportItem({
|
|||||||
<MoreHorizontal size={16} />
|
<MoreHorizontal size={16} />
|
||||||
</DropdownMenuTrigger>
|
</DropdownMenuTrigger>
|
||||||
<DropdownMenuContent align="end" className="w-[200px]">
|
<DropdownMenuContent align="end" className="w-[200px]">
|
||||||
|
<DropdownMenuItem
|
||||||
|
onClick={(event) => {
|
||||||
|
event.stopPropagation();
|
||||||
|
onDuplicate(report.id);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<CopyIcon size={16} className="mr-2" />
|
||||||
|
Duplicate
|
||||||
|
</DropdownMenuItem>
|
||||||
<DropdownMenuGroup>
|
<DropdownMenuGroup>
|
||||||
<DropdownMenuItem
|
<DropdownMenuItem
|
||||||
className="text-destructive"
|
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(
|
const updateLayout = useMutation(
|
||||||
trpc.report.updateLayout.mutationOptions({
|
trpc.report.updateLayout.mutationOptions({
|
||||||
onError: handleErrorToastOptions({}),
|
onError: handleErrorToastOptions({}),
|
||||||
@@ -565,6 +587,9 @@ function Component() {
|
|||||||
onDelete={(reportId) => {
|
onDelete={(reportId) => {
|
||||||
reportDeletion.mutate({ reportId });
|
reportDeletion.mutate({ reportId });
|
||||||
}}
|
}}
|
||||||
|
onDuplicate={(reportId) => {
|
||||||
|
reportDuplicate.mutate({ reportId });
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</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
|
get: protectedProcedure
|
||||||
.input(
|
.input(
|
||||||
z.object({
|
z.object({
|
||||||
|
|||||||
Reference in New Issue
Block a user