Simplify your stack and build anything. Or everything.
Build tomorrow’s web with a modern solution you truly own.
Code-based nature means you can build on top of it to power anything.
It’s time to take back your content infrastructure.

Replace relationship field `Edit` view to include image media within the drop down selection UI

default discord avatar
jellygatorade3 years ago
13

Hi, I am new to Payload and starting to learn my way around the codebase. Enjoying it so far!



This post explains my scenario but basically asks "Are there any existing examples of replacing the relationship field in

Edit

views with a custom component that can get me started?"



I have followed the method in this thread to populate images within custom

Cell

components as pictured in the attachments.


https://discordapp.com/channels/967097582721572934/1041362545501548624

I would like to create a similar component for relationship types in

Edit

view to replace the dropdown list item (last image attachment).



Am I correct in thinking that I will need to target changing the

SingleValue

component? Here in the source:


https://github.com/payloadcms/payload/blob/master/src/admin/components/forms/field-types/Relationship/select-components/SingleValue/index.tsx

Or are there multiple components that I will have to target?


For example, does the

SingleValue

component specify the selections only when the drop down

DocumentDrawer

is open but there is a different component I need to target for when it is closed?


If this is the scenario of Payload - I would have to target the

Relationship

component in addition to

SingleValue

?


https://github.com/payloadcms/payload/blob/master/src/admin/components/forms/field-types/Relationship/index.tsx

And in my definition for the collection that makes use of this relationship - the field object will look something like this if my new component is called

ImageTitleRelationshipField

?



{
    name: "competitorOne",
    type: "relationship",
    relationTo: ["artworks"],
    admin: {
        components: {
            Cell: ImageTitleCell,
            Field: ImageTitleRelationshipField
        },
    },
},

I guess I am asking - what is the best approach? and are there any existing examples of replacing the relationship field in

Edit

views with a custom component that can get me started?

  • default discord avatar
    Deleted User3 years ago
    @1069626017846665307

    sorry i don't have the answer but i was wondering if i could see your ImageTitleCell and ImageTitleRelationshipField codes if possible? i'm trying to make a custom component to make my images look like those rather than appearing as filenames 😄



    i made my own component but i can't seem to locate the image's url inside the props, i just get the element's name

  • default discord avatar
    jellygatorade3 years ago
    @456226577798135808

    See this message for a good starting point:

    https://discordapp.com/channels/967097582721572934/1041362545501548624/1041487440310964225

    I have not yet started to create code for

    ImageTitleRelationshipField

    component yet because it's what I opened this thread to ask about.

  • default discord avatar
    Deleted User3 years ago

    ohhh gotcha, thanks a lot, good luck! 😄

  • discord user avatar
    denolfe
    3 years ago

    I don't know of any examples of replacing this field. That field component is by far the most complex of all the fields, so swapping that one out would be pretty intense.

  • default discord avatar
    jellygatorade3 years ago

    Thanks for your reply. I suppose that doesn't surprise me. Looking at the

    Relationship

    field source code (

    https://github.com/payloadcms/payload/blob/master/src/admin/components/forms/field-types/Relationship/index.tsx

    ) it doesn't seem very maintainable in the long term to try swapping this whole field out with all its dependencies... If I am correct in my reading of the source what I am actually interested in is changing the usage of

    props

    within

    ReactSelect

    component...in my case for the

    SingleValue

    variant.



    I'll have to do more thinking about this caveat over the next week or so when I have the time. I'll update this thread when I can.



    For now I could categorize this potential issue in broader terms by saying: Without any concept of an attached featured image per collection item, content editors do not have a way of rapidly identifying a target item when attaching as a relationship via the existing

    ReactSelect

    UI if they are not sure about its name because the UI offers text only. Any alternative suggestions for working around this issue would be appreciated 🙂 .

  • discord user avatar
    denolfe
    3 years ago

    Okay, so your goal is for admin users to rapidly scan the list view for image relationships? The only other workaround I can think of is to make a

    ui

    type field with a custom cell component and render anything helpful in it.

  • default discord avatar
    jellygatorade3 years ago

    Thanks for thinking it though. My ideal scenario is for the dropdown list items of the

    Relationship

    field in the

    Edit

    view to appear similarly to the custom

    Cell

    component I successfully created for the

    List

    view, where a related image thumbnail appears before the title. (This successful

    List

    view for the Polls collection is shown as an attached image to the original post).



    Is your suggested workaround to include a custom

    UI

    type component in the collection

    Edit

    view, adjacent to the

    Relationship

    field, that somehow listens for changes on the

    Relationship

    field and updates with a thumbnail image from the selected item?

  • discord user avatar
    denolfe
    3 years ago

    Yes, correct.



    Essentially, another field to augment the functionality instead of replacing the relationship field altogether

  • default discord avatar
    jellygatorade3 years ago

    I'd be happy to take a stab at that. Can you give an approach for the

    UI

    field to listen for changes on another field?

  • discord user avatar
    denolfe
    3 years ago
    @808734492645785600

    @281120856527077378

    Can you assist here? I'm not as familiar with the React hooks we have available to accomplish this



    These docs would be a good start from the react side:

    https://payloadcms.com/docs/admin/hooks#useformfields
  • discord user avatar
    jacobsfletch
    3 years ago
    make a ui type field with a custom component and render anything helpful in it.

    This is probably the way to go here



    To listen to changes on that field from within your custom component, fire the

    useFormFields

    hook like this:



      const { value } = useFormFields(([fields, dispatch]) => fields.yourRelationshipField);
  • default discord avatar
    jellygatorade3 years ago

    Awesome, thanks for your help! Hopefully I'll be able to update this thread later with my usage.



    Okay, thanks for all the help again. Here is a basic snippet to get anyone else started if searching in the future. The attached image shows how the custom

    UI

    component based on the code snippet looks next to the standard

    Relationship

    field...while using the

    Row

    field to parent both and with some additional CSS.



    import React, { useState, useEffect } from "react";
    import { useFormFields } from "payload/components/forms";
    
    const baseUrl = process.env.PAYLOAD_PUBLIC_SERVER_URL;
    
    const ThumbnailListener = (props) => {
      // value key holds current value of fields[props.label]
      // I am using the label key in the UI field options (defined in the collection) to pass the name of the target relationship field via props
      const { value } = useFormFields(([fields, dispatch]) => fields[props.label]);
    
      const [fetchItem, setFetchItem] = useState();
    
      useEffect(() => {
        value &&
          fetch(`${baseUrl}/api/${value.relationTo}/${value.value}/?depth=1`)
            .then((data) => data.json())
            .then((object) => setFetchItem(object));
      }, [value]);
    
      return (
        <>
          {fetchItem?.image?.sizes?.thumbnail?.url && (
            <img
              src={fetchItem.image.sizes.thumbnail.url}
            ></img>
          )}
        </>
      );
    };
  • discord user avatar
    jacobsfletch
    3 years ago

    BOOM! That's great.

Star on GitHub

Star

Chat on Discord

Discord

online

Can't find what you're looking for?

Get dedicated engineering support directly from the Payload team.