contentful / contentful-management.js

JavaScript library for Contentful's Management API (node & browser)
https://contentful.github.io/contentful-management.js
MIT License
270 stars 97 forks source link

Updating editor interface with the API seems to work but has no effect on the UI #1860

Open prceasar opened 1 year ago

prceasar commented 1 year ago

I am running the following code to update an editorInterface using the PlainClientAPI within a contentful App (using the useCMA() hook).

here is an example of the code:

const updateEditorInterface = async (cma: PlainClientAPI, widget: Control, contentType: ContentTypeProps, field: ContentFields, sdk: FieldAppSDK) => {
  const editorInterface = await cma.editorInterface.get({
    contentTypeId: contentType.sys.id,
  });
    let controls: Control[] = editorInterface.controls || [];

    if (controls.find((c) => c.fieldId === field.id)) {
      console.log(
        "a control exists for this field"
      );
      controls = controls.map((c) => {
        if (c.fieldId === field.id) {
          return widget;
        }
        return c;
      });
    } else {
      console.log("control does not exist");
      controls = [...controls, widget];
    }

    await cma.editorInterface.update(
      {
        contentTypeId: contentType.sys.id,
      },
      {
        ...editorInterface,
        controls,
      }
    );

}

After running this, I can see the updated editorInterface when I use the PlainClientAPI to query for them. Everything looks like it worked. But when I navigate to the content entry screen I do not see my widget being rendered. And then when I navigate to the Content Model tab and look at the field appearance, it shows the default editor as being selected.

It's strange because I can sometimes get it to work by changing something random in the content type and saving it. But even if I programmaticaly call cma.contentType.publish({ contentTypeId }, contentType) it does not seem to work. It seems like I have to manually make the change in the content model tab, which defeats the purpose of doing it programmatically.

prceasar commented 1 year ago

Note: This does not seem to be specific to the PlainClientAPI. I tried using the regular client, using createClient({ apiAdapter: sdk.cmaAdapter }) and got the same result.

neonVoice commented 1 year ago

I also encountered problem using plain cma client from react typescript project. After installing my extension that renders inside field I wanted to change editor interface to use my control for specific field, so basically, I needed to replace one of controls in editor interface controls array with this:

{
    fieldId: 'original',
    widgetId: sdk.ids.app,
    widgetNamespace: 'app'
}

however if I inspect network requests in browser for PUT requests I noticed that widgetId and widgetNamespace were omitted from request for some reason. This is what were sent instead:

{
    fieldId: 'original'
}

HOWEVER if I try to change editor interface from contentful directly and inspect PUT request - thouse values are not omitted and request is sent properly.

I'm confused by why this is happening and don't really know how to debug inside internals, but I think either it is getting removed by some code or there's a problem with spread operators working in async code OR I need to manually update/publish content type, because in react project content type version for example changes from v2 to v3, but if I do everything manually - content type gets saved 1 more extra time and it looks like v2 to v4, where v3 is request to update/save content type without changes. Not sure how to proceed from here, because I wanted to automate as much as possible, but probably not gonna waste time trying to solve this and instruct users to chose Appearance manually instead.

jamesmeticular commented 5 months ago

I was running into the same issue as @neonVoice. I'm using the sdk.cma in a custom app.

Your comment led me to the solution for me. updating the editor interface works, but you have to then get the new version of the content type and publish it. Here's where I landed:

const updated = await cma.editorInterface.update({contentTypeId}, newEditorInterface)

// Get the new version of the content type due to the above edits and publish it

const mostRecentContentType = await cma.contentType.get({contentTypeId})
const publishContentType = await cma.contentType.publish({contentTypeId}, mostRecentContentType)

I did try passing along an old version of the contentType to the publish function (I had already pulled earlier in my code and it seems like it does not contain the editor interface data.) But this caused version errors.

Either I missed this in the docs or it is not explicitly explained in the docs :) Hope this helps someone else!