Create new menu global after creating a page

default discord avatar
Braggedtooth
12 months ago
1 2

Hi!

i am trying to add a page to the global menu after its being created so far i have managed to replace the menu.

This is my current code run in page afterchange hook:

 import payload from "payload";

export const addPageToMenu = async (args) => {
  if (args.operation === "create" {
  
    let menu = await payload.findGlobal({ slug: "mainMenu" });

    if (args.doc) {
      await payload.updateGlobal({
        slug: "mainMenu",
        data: {
          items: [
            {
              type: "link",
              label: args.doc.title,
              link: {
                type: "reference",
                reference: {
                  value: args.doc.id,
                  relationTo: "pages",
                },
              },
              subMenu: { blocks: 0 },
            },
            ...menu.items.map((item) => {
              return {
                link: {
                  ...item.link,
                  reference: {
                    ...item.link.reference,
                    value: {
                      ...item.link.reference.value,
                      layout: {
                        ...item.link.reference.value.layout,
                      },
                    },
                  },
                },
                ...item,
              };
            }),
          ],
        },
      });

      return args.doc;
    }
  }
  return args.doc;
};

this create a new entry but the old entries loses connection is there a way to just use the ids instead of passing the whole referenced document? i.e

{
  "items": [
    {
      "link": {
        "reference": "id of  document"
      }
    }
  ]
}

Error Message:
image

  • default discord avatar
    Braggedtooth
    12 months ago

    Solution hook for adding page when created and deleting when page is deleted.

    import payload from "payload";
    import { FieldHookArgs } from "payload/dist/fields/config/types";
    import { MainMenu, Page } from "../../payload-types";
    
    /**
     *  fetches the main menu from the database
     */
    const fetchMenu = async (): Promise<MainMenu> =>
      await payload.findGlobal({ slug: "mainMenu" });
    
    /**
     *  fetch the menu, add the new page to it, and then update the menu
     * @param args - {
     * @returns The page that was created.
     */
    export const addPageToMenu = async (args: {
      doc: Page;
      operation: FieldHookArgs["operation"];
    }) => {
      const menu = await fetchMenu();
      if (args.operation === "create") {
        const newArray = menu.items.map((item) => {
          return {
            ...item,
            link: {
              ...item.link,
              reference: {
                value:
                  typeof item.link.reference.value !== "string" &&
                  item.link.reference.value.id,
                relationTo: item.link.reference.relationTo,
              },
            },
          };
        });
        if (args.doc && menu) {
          await payload.updateGlobal({
            slug: "mainMenu",
            data: {
              items: [
                ...newArray,
                {
                  type: "link",
                  label: args.doc.title,
                  link: {
                    type: "reference",
                    reference: {
                      value: args.doc.id,
                      relationTo: "pages",
                    },
                  },
                  subMenu: { blocks: 0 },
                },
              ],
            },
          });
    
          return args.doc;
        }
      }
    };
    /**
     *  fetches the menu, filters out the item with the id that matches the id passed in as an argument,
     * and then updates the menu with the filtered array
     * @param args - { id: string }
     * @returns The return type is a Promise<void>
     */
    
    export const deleteMenu = async (args: { id: string }) => {
      const menu = await fetchMenu();
      const deleteArray = menu.items.filter(
        (element) =>
          typeof element !== "string" &&
          typeof element.link.reference.value !== "string" &&
          element.link.reference.value.id !== args.id
      );
      await payload.updateGlobal({
        slug: "mainMenu",
        data: {
          items: [
            ...deleteArray.map((item) => {
              return {
                ...item,
                link: {
                  ...item.link,
                  reference: {
                    value:
                      typeof item.link.reference.value !== "string" &&
                      item.link.reference.value.id,
                    relationTo: item.link.reference.relationTo,
                  },
                },
              };
            }),
          ],
        },
      });
      return;
    };
  • default discord avatar
    Braggedtooth
    12 months ago

    Hi!

    I figured it out, the solution is in my question. Just have to pass the id as value instead of the whole object.
    i dont know why i didnt try that first even tho that was how i wanted it to work..
    welp will leave this here. Maybe helps someone else 👍🏿

Open the post
Continue the discussion in GitHub
Like what we're doing?
Star us on GitHub!

Star

Connect with the Payload Community on Discord

Discord

online

Can't find what you're looking for?

Get help straight from the Payload team with an Enterprise License.