mavo
mavo copied to clipboard
Allow (backend) plugin authors to pass the `conflictPolicy` property when firing the `mv-remotedatachange` event
In the upcoming version of Mavo, we give plugin authors a way to tell Mavo that data on the backend changed. To do so, they can fire the mv-remotedatachange
event with (optional) data
property with some new data. Like so:
$.fire(this, "mv-remotedatachange", {data});
However, working on the Google Calendar plugin, I noticed that when I try to create an event by specifying its fields (title, start date and time, end date and time, etc.), the newly created event doesn't show up in the list of events. Even though it was added to the calendar. I needed to refresh the page to see the new event. I couldn't understand why that happened. And after a bit of debugging, I could manage to find the cause.
Mind the following code snippet:
<article property="event">
<input property="summary" value="Event Summary" />
<p property="start">Start: <input type="datetime-local" property="dateTime" /></p>
<p property="end">End: <input type="datetime-local" property="dateTime" /></p>
</article>
Changing any of those properties (either summary
, or dateTime
) will switch the unsavedChanges
flag on. Firing the mv-remotedatachange
will invoke Mavo.push()
: https://github.com/mavoweb/mavo/blob/2bded90708765dddd8e274e6eec6b96bb5f7e442/src/mavo.js#L498
Mavo.push()
in its turn will invoke Mavo.load()
but only if there are no unsaved changes (unsavedChanges === false
) or conflictPolicy === "force"
, or conflictPolicy === "ask"
and the user confirmed loading of the new data:
https://github.com/mavoweb/mavo/blob/2bded90708765dddd8e274e6eec6b96bb5f7e442/src/mavo.js#L514-L528
However, in my case with the newly created event (from the code snippet above), I have unsaved changes (unsavedChanges === true
) and conflictPolicy
is equal to "stop"
(the default value). So, Mavo.load()
won't be triggered, and the remote data won't be loaded. That's why I couldn't see the newly created event in the event list.
It would be nice if we could pass the conflictPolicy
parameter (property) with the mv-remotedatachange
event. In my case, I would fire it this way:
$.fire(this, "mv-remotedatachange", {conflictPolicy: "force"});
I don't provide data
here because Mavo will load (and render) it automatically.
Thank you for such a detailed writeup. I don't understand one thing: to add the event to your calendar, you saved, right? Why was the unsavedChanges flag on after saving?
Sorry, I didn't give you enough context. Let me fix it.
Technically, the Google Calendar plugin is read-only (there are neither put()
nor store()
methods). Even though Mavo provides the UI to modify the collection of events (add elements, update them, and delete), those changes won't have any effect (I wonder if it is possible to make the collection of events read-only on the plugin side? 🤔). There is no way for the user to save the changes back to the calendar.
Why did I follow this route? Unfortunately, I don't know the way to distinguish changes made by the user in the collection of events by looking at the data Mavo provides inside either store()
or put()
methods: which events were updated, which ones were created, and which ones were deleted. So I don't know which actions to perform on the user's calendar. Even if I get the collection of events itself, it will consist only of actual data (no deleted events), right?
However, I supposed that creating new events, updating and/or deleting the existing ones were the features end-users would love to have. And I decided to let authors provide those features to their users via custom actions: create_event()
, update_event()
, and delete_event()
. So, authors can work with events, but they need to be explicit in their intentions.
And if we get back to the code snippet from above, the exact code would look like this (mind the Create Event
button which is responsible for adding the event to the calendar):
<article property="event">
<input property="summary" value="Event Summary" />
<p property="start">Start: <input type="datetime-local" property="dateTime" /></p>
<p property="end">End: <input type="datetime-local" property="dateTime" /></p>
</article>
<button mv-action="create_event(event)">Create Event</button>
As you can see, this action is performed without actually saving the whole collection of events back to the calendar. That's why the unsavedChanges
flag remains on after adding/updating the event to/in the calendar—I don't invoke the save()
method.
I might do something wrong and violate some Mavo principles. Please, let me know if I do.
Actually, in the plugin, everything is ready to let users modify events simply by working with the collection of events the way they used to by working with other collections, if we can distinguish newly added, updated, and deleted collection items.
Hope my explanations are clear enough. If not, don't hesitate to ask any questions. I'll do my best to find the correct wording.
Will this pen be helpful: https://codepen.io/dmitrysharabin/pen/rNJgjGV?