All files / publisher/hooks useMutateListingData.ts

63.15% Statements 24/38
57.14% Branches 16/28
85.71% Functions 6/7
63.15% Lines 24/38

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126                                                                      126x   2x   2x   2x 2x   2x       2x       2x 2x 10x                                           2x   2x         2x       2x     2x     2x 2x     2x 2x 1x   1x     1x                     2x 2x                  
import { Dispatch, SetStateAction } from "react";
import { UseFormReset, FieldValues } from "react-hook-form";
import { useMutation, UseMutationOptions } from "react-query";
 
import { addDateToFilename, getListingChanges } from "../utils";
 
import type { ListingData, StatusNotification } from "../types";
 
type Options = {
  data: ListingData;
  dirtyFields: { [key: string]: boolean };
  getDefaultData: (arg: ListingData) => { [key: string]: unknown };
  refetch: () => void;
  reset: UseFormReset<FieldValues>;
  setStatusNotification: Dispatch<SetStateAction<StatusNotification>>;
  setUpdateMetadataOnRelease: Dispatch<SetStateAction<boolean>>;
  shouldShowUpdateMetadataWarning: (arg: FieldValues) => boolean;
  snapName: string | undefined;
};
 
export type MutationResponse = {
  success: boolean;
  errors: Array<{ code: string; message: string }>;
};
 
function useMutateListingData({
  data,
  dirtyFields,
  refetch,
  reset,
  setStatusNotification,
  setUpdateMetadataOnRelease,
  shouldShowUpdateMetadataWarning,
  snapName,
}: Options) {
  return useMutation({
    mutationFn: async (values: FieldValues) => {
      const formData = new FormData();
 
      const changes = getListingChanges(dirtyFields, values, data);
 
      formData.set("csrf_token", window.CSRF_TOKEN);
      formData.set("snap_id", data.snap_id);
 
      Iif (values.icon && values.icon.length > 0) {
        formData.append("icon", values.icon[0]);
      }
 
      Iif (values.banner && values.banner.length > 0) {
        formData.append("banner-image", values.banner[0]);
      }
 
      Eif (values.screenshots) {
        values.screenshots.forEach((screenshot: FileList) => {
          Iif (screenshot[0]) {
            const oldName = screenshot[0].name;
            const newFile = addDateToFilename(screenshot[0], new Date());
 
            formData.append("screenshots", newFile);
 
            const imageIndex = changes?.images?.findIndex(
              (image: {
                url: string;
                type: string;
                status: string;
                name?: string;
              }) => image.name === oldName,
            );
            if (changes.images && imageIndex) {
              changes.images[imageIndex].name = newFile.name;
              changes.images[imageIndex].url = URL.createObjectURL(newFile);
            }
          }
        });
      }
 
      formData.set("changes", JSON.stringify(changes));
 
      const response = await fetch(`/api/${snapName}/listing`, {
        method: "POST",
        body: formData,
      });
 
      Iif (shouldShowUpdateMetadataWarning(values)) {
        setUpdateMetadataOnRelease(false);
      }
 
      Iif (!response.ok) {
        throw new Error("There was a problem saving listing data");
      }
      return (await response.json()) as MutationResponse;
    },
    onSuccess: (data: MutationResponse) => {
      const mainPanel = document.querySelector(".l-main") as HTMLElement;
      Iif (mainPanel) {
        mainPanel.scrollTo({ top: 0, left: 0, behavior: "smooth" });
      }
      refetch();
      if (data.errors && data.errors.length > 0) {
        setStatusNotification({
          success: false,
          message: data.errors.map((value) => value.message),
        });
      } else {
        setStatusNotification({
          success: true,
          message: "Changes applied successfully.",
        });
      }
    },
    onSettled: (
      _data: MutationResponse,
      _error: unknown,
      values: FieldValues,
    ) => {
      if (values) {
        reset(values);
      } else E{
        reset();
      }
    },
  } as UseMutationOptions<MutationResponse, unknown, FieldValues, unknown>);
}
 
export default useMutateListingData;