async function duplicateWidget()

in backend/src/lib/controllers/widget-ctrl.ts [118:204]


async function duplicateWidget(req: Request, res: Response) {
  const user = req.user;
  const dashboardId = req.params.id;
  if (!dashboardId) {
    res.status(400).send("Missing required field `id`");
    return;
  }

  const widgetId = req.params.widgetId;
  if (!widgetId) {
    res.status(400).send("Missing required field `widgetId`");
    return;
  }

  const { updatedAt, copyLabel } = req.body;

  if (!updatedAt) {
    res.status(400).send("Missing required field `updatedAt`");
    return;
  }

  const repo = WidgetRepository.getInstance();
  const widget = await repo.getWidgetById(dashboardId, widgetId);

  if (widget.updatedAt > new Date(updatedAt)) {
    res.status(409);
    return res.send("Someone else updated the widget before us");
  }

  let newWidget;
  let newWidgets = [];
  try {
    newWidget = WidgetFactory.createWidget({
      name: `(${copyLabel || "Copy"}) ${widget.name}`,
      dashboardId,
      widgetType: widget.widgetType,
      showTitle: widget.showTitle,
      content: widget.content,
    });
    newWidget.updatedAt = widget.updatedAt;
    if (newWidget.content.title) {
      newWidget.content.title = `(${copyLabel || "Copy"}) ${
        newWidget.content.title
      }`;
    }
    if (
      widget.widgetType === WidgetType.Section &&
      widget.content.widgetIds &&
      widget.content.widgetIds.length
    ) {
      for (const id of widget.content.widgetIds) {
        const childWidget = await repo.getWidgetById(dashboardId, id);
        const newChildWidget = WidgetFactory.createWidget({
          name: `(${copyLabel || "Copy"}) ${childWidget.name}`,
          dashboardId,
          widgetType: childWidget.widgetType,
          showTitle: childWidget.showTitle,
          content: childWidget.content,
          section: newWidget.id,
        });
        newChildWidget.updatedAt = childWidget.updatedAt;
        if (newChildWidget.content.title) {
          newChildWidget.content.title = `(${copyLabel || "Copy"}) ${
            newChildWidget.content.title
          }`;
        }
        newWidgets.push(newChildWidget);
      }
      if (newWidgets.length) {
        newWidget.content.widgetIds = newWidgets.map((w) => w.id);
      }
    }
  } catch (err) {
    console.log("Invalid request to create widget", err);
    return res.status(400).send(err.message);
  }

  const dashboardRepo = DashboardRepository.getInstance();

  await repo.saveWidget(newWidget);
  for (const nw of newWidgets) {
    await repo.saveWidget(nw);
  }
  await dashboardRepo.updateAt(dashboardId, user);

  return res.json(newWidget);
}