Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add custom errors hook and capability to prevent saving the page #216

Open
edvinasjurele opened this issue Jun 27, 2023 · 10 comments
Open

Comments

@edvinasjurele
Copy link

Is your feature request related to a problem? Please describe.

I have played around with React template and made my first field type plugin in this new new API. Unfortunately, I found out that there is no error interception or some hook to prevent CMS from saving, so I could make custom error handling within the field type plugin.

Describe the solution you'd like
My plugin is much more advanced and acts rather like a widget with input and some more inputs generated dynamically, so I have error handling to prevent invalid cases. The example could look like in the additional context.

My FieldPluginResponse.data.content is not a string, but rather an object {}, so I have to have custom error handling for better and UI with guided output.

I do not want to imply exact solution, but from top of my head there could be some setError (similar to setContent), so CMS could check it before saving the page and would generate the messages queue of single string and/or array of strings which are set by the field plugin. The rest could be part of the usual flow - that error icon next to Publish button to hint user to resolve listed errors.

Additional context

image

@eunjae-lee
Copy link
Contributor

Hi @edvinasjurele , Thanks for trying this and letting us know what you think :)

To better understand your situation, your content is not a string, but rather an object. But in what kind of scenario, could there be a string instead of object?

@edvinasjurele
Copy link
Author

Hi, sure, first of all tremendous job guys!
Well, the initial problem is much complex.
Coming from the react world and react-intl which is in ICU format - I am trying to do Storyblok Field Plugin to enable ICU message syntax format handling. I see that Storyblok does not support such thing, but I am sure it should do it natively (we might contact SB separately via company channels) in the long ru. We need it so hard!

The only hope now is to make it via custom Storyblok Field plugin, so I did my best here:

image

The outcome of such plugin is and lands to be part of the response JSON:

{
  "type": "icu",   // this is added just to distinguish the object in response JSON
  "identifier": "Hello, {who} and {company}!",
  "values": {
    "who": "Eunjae Lee",
    "company": "Storyblok"
  }
}

I am using the ICU Message Format Parser in the runtime.


If it happens so that the content must be a string, well, one of the wild ideas would be to make this object into some contracted string, but then the we should destructure it in the response as well as in some translations systems we would like to integrate Storyblok with. This sounds super sketchy..

Anyway, the problem is there eitherway that we cannot ensure the validity of the string, atm it is limited to only Required field checkbox on the Storyblok side. I am sure it may be logical to make field plugins joining the error handling flow, so the flield plugin authors could adapt the CMS to their needs better.

Let's see if there is any takeaway out of my situation in regards to improving field plugin API 🙏

@eunjae-lee
Copy link
Contributor

Hey @edvinasjurele thanks for providing the details!
Just in case you're missing this, you can use an object as content.

setContent({
  "type": "icu",   // this is added just to distinguish the object in response JSON
  "identifier": "Hello, {who} and {company}!",
  "values": {
    "who": "Eunjae Lee",
    "company": "Storyblok"
  }
})

This is totally possible. The only potential issue in this situation, in my opinion, is somehow user or another plugins like Tool mistakenly put a wrong value to this field. To recover from this situation, you may consider using validation libraries like zod. If invalid, you ignore the previous value.

parseContent as a part of parameters to createFieldPlugin has been suggested: #201 (comment)

Would it solve your issue? What do you think? Let me know if I missed something :)

@edvinasjurele
Copy link
Author

Thanks. I am totally aware that it is possible to set the content as object, that is not a problem, I even made field plugin fully functional as Proof-of-Concept. But... I cannot make CMS aware of errors. at all :) zod helps for logic within the field plugin itself, but I can save the data even if there is an error inside the field plugin:

Screen.Recording.2023-06-27.at.15.11.03.mov

How should I solve that?

IMHO, the CMS should be able to stop (intercept) content editor from saving the data and throw errors, as it is truly in broken state. So even if I would ignore value or restore some previous value (btw, making field plugin state valid all the time is not possible as I need to allow user keep writing the text.. it is just not possible to write character by character and be in valid state at all times. so this leaves my data in one of two states - broken and valid), I still cannot prevent user click that Save or Publish button at any time and set broken data.

We can forget the object notation, that bit is clear. Let's stay with simple string for now as a value. If I would do field plugin which has some regex validation which only allows some certain values to be entered, I could not intervene or force content editor to not save broken data to the database, even if I clearly state that there is an error within the field plugin. That is my problem.

I hope this makes situation clearer 🙏

@eunjae-lee
Copy link
Contributor

@edvinasjurele oh thanks for the clarification. It makes total sense. Let me think about this a bit with the team and I'll get back to you 🙏🏻

@eunjae-lee
Copy link
Contributor

@edvinasjurele Currently we don't have a way for a field plugin to tell the Visual Editor about its validity of the data. At this moment, it's not possible to disable "Save" button on the top navbar, or something like that. I'm initiating the discussion with the team responsible of the Visual Editor, but I cannot guarantee when and if we will have this feature.

However, in the meantime, your workaround would be to call setContent() only when the data is valid, and to show errors while invalid, instead of calling setContent() at every onChange.

What you do think? Does it make sense to you? I'm happy to hear more from you to improve Field Plugin SDK 😊

@edvinasjurele
Copy link
Author

No worries, no rush. Leave this task open till you guys find any solution, but IMHO error handling is something to improve here.

In regards to workarounds, none of them fits my situation or makes situation worse, so I may rely on the whoever to make sure they manually check for invalid data and be aware about it before hitting Save.

I am sure setContent() may be hook for live-editing experience. Also setting the value to previous valid or some other, may be conceptually wrong as it does not preserve the most recent state, so editor experience will be bad after refresh the page or getting back to same story after some time - setContent is the only method to preserve the data besides React internal state which lasts only until the field-plugin unmounted/mounted again.

@edvinasjurele
Copy link
Author

Hey, any news on this?

@eunjae-lee
Copy link
Contributor

Hi @edvinasjurele, glad to hear from you again.

No, not yet. However, we have recently collaborated closely with the Visual Editor team. We have made significant updates to the Field Plugin SDK and corresponding changes in the Editor. These updates will allow us to easily add functionalities in the near future.

@hoersamu
Copy link
Contributor

Hey there. Is there any news on this? We are facing this exact same problem

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants