Class DraftsFacetImpl

java.lang.Object
io.jmix.flowui.facet.impl.AbstractFacet
io.jmix.uirecoveryflowui.facet.impl.DraftsFacetImpl
All Implemented Interfaces:
Facet, DraftsFacet

public class DraftsFacetImpl extends AbstractFacet implements DraftsFacet
Default implementation of DraftsFacet: captures the unsaved state of the owning view's DataContext into a draft, and offers it back when the view is opened again.
  • Field Details

    • MESSAGE_GROUP

      protected static final String MESSAGE_GROUP
      See Also:
    • properties

      @Autowired protected UiRecoveryDraftsProperties properties
    • viewDraftService

      @Autowired protected ViewDraftService viewDraftService
    • payloadSupport

      @Autowired protected DraftPayloadSupport payloadSupport
    • entityStates

      @Autowired protected EntityStates entityStates
    • idSerialization

      @Autowired protected IdSerialization idSerialization
    • timeSource

      @Autowired protected TimeSource timeSource
    • dialogs

      @Autowired protected Dialogs dialogs
    • notifications

      @Autowired protected Notifications notifications
    • messages

      @Autowired protected Messages messages
    • currentAuthentication

      @Autowired protected CurrentAuthentication currentAuthentication
    • taskScheduler

      @Autowired @Qualifier("core_ThreadPoolTaskScheduler") protected org.springframework.scheduling.TaskScheduler taskScheduler
    • minSaveInterval

      protected Duration minSaveInterval
    • restoreMode

      protected RestoreMode restoreMode
    • restoreDelegate

      protected Consumer<DraftRestoreContext> restoreDelegate
    • dataContext

      protected DataContext dataContext
    • viewData

      protected ViewData viewData
    • owningView

      protected View<?> owningView
    • viewId

      protected String viewId
    • entityId

      protected String entityId
    • lastSaveMillis

      protected long lastSaveMillis
    • pendingChanges

      protected boolean pendingChanges
    • roundTripFlushScheduled

      protected boolean roundTripFlushScheduled
    • applying

      protected boolean applying
    • trailingFlush

      protected @Nullable ScheduledFuture<?> trailingFlush
    • eventBus

      protected @Nullable EventBus eventBus
  • Constructor Details

    • DraftsFacetImpl

      public DraftsFacetImpl()
  • Method Details

    • init

      @PostConstruct protected void init()
      Applies the property defaults once the injected fields are available. The XML loader sets its own values after the facet is created, so an attribute in the descriptor still wins.
    • setOwner

      public <T extends com.vaadin.flow.component.Composite<?> & FacetOwner> void setOwner(@Nullable T owner)
      Description copied from interface: Facet
      Sets an owner containing this facet.
      Specified by:
      setOwner in interface Facet
      Overrides:
      setOwner in class AbstractFacet
      Type Parameters:
      T - the type of the owner
      Parameters:
      owner - an owner containing this facet
    • onViewReady

      protected void onViewReady(View.ReadyEvent event)
    • updateEntityKey

      protected void updateEntityKey(StandardDetailView<?> detailView)
    • onDataContextChange

      protected void onDataContextChange(DataContext.ChangeEvent event)
    • scheduleRoundTripFlush

      protected void scheduleRoundTripFlush()
      Defers the flush to the end of the current client round trip, so that one user action is captured as a whole. Adding a composition element, say, merges the new element into the data context, sets its attributes and only then adds it to the owner's collection - a draft written on the first of those events holds a new instance that nothing references yet.

      With no UI to hook into there is no round trip to wait for, so the flush runs right away.

    • flush

      protected void flush()
      Writes what is owed if getMinSaveInterval() has passed since the last write, and otherwise arms trailingFlush to write it once the interval does pass. The interval caps how often a draft is written; it must not decide whether a change is written.
    • scheduleTrailingFlush

      protected void scheduleTrailingFlush(long delayMillis)
      The write is handed to VaadinSession.access(com.vaadin.flow.server.Command) because it reads the data context the user is still editing, which may only be touched while holding the session lock. It is queued on the session and not on the UI: closing the browser window detaches the UI while the session lives on, and UI.access on a detached UI throws, dropping the one write that matters most.
    • runTrailingFlush

      protected void runTrailingFlush(com.vaadin.flow.server.VaadinSession session)
    • cancelTrailingFlush

      protected void cancelTrailingFlush()
    • getOwnerUi

      protected @Nullable com.vaadin.flow.component.UI getOwnerUi()
    • onDataContextPostSave

      protected void onDataContextPostSave(DataContext.PostSaveEvent event)
    • saveDraftNow

      public void saveDraftNow()
      Description copied from interface: DraftsFacet
      Builds a draft payload from the current state of the owning view's data context and writes it immediately, bypassing the minimum save interval throttle.
      Specified by:
      saveDraftNow in interface DraftsFacet
    • deleteDrafts

      public void deleteDrafts()
      Description copied from interface: DraftsFacet
      Deletes the draft associated with the owning view's key.
      Specified by:
      deleteDrafts in interface DraftsFacet
    • onViewDetach

      protected void onViewDetach()
      Last chance to write what is owed: after detach no change event can come and no flush can be scheduled, so the throttle is bypassed. On a normal close a save or an explicit discard has already cleared it and this does nothing.
    • onViewAfterClose

      protected void onViewAfterClose(View.AfterCloseEvent event)
    • restoreIfDraftPresent

      protected void restoreIfDraftPresent(View<?> view)
    • applyDraft

      protected boolean applyDraft(ViewDraft draft)
      Returns:
      true if the draft was applied to at least one instance. An empty result means every entry was skipped, so nothing was restored and the user must not be told otherwise.
    • refreshCollectionContainers

      protected void refreshCollectionContainers()
      Re-reads the view's collection property containers from their master instances. Restoring a to-many attribute mutates the owner's collection in place, which fires no property change event, and a CollectionPropertyContainer keeps its own copy of the list - so without this the data grid bound to it keeps showing the rows from before the restore.
    • refreshCollectionContainer

      protected void refreshCollectionContainer(CollectionPropertyContainer container)
    • switchToDraftedNewInstance

      protected void switchToDraftedNewInstance(List<Object> applied)
      For a detail view editing a NEW instance: the drafted instance has a different generated id than the freshly created one, so applying the payload adds it alongside. Switch the view to the drafted instance and evict the fresh one, which would otherwise stay tracked as new and be sent to the data store by a later save.
    • openRestoreDialog

      protected void openRestoreDialog(ViewDraft draft)
    • showAutoRestoredNotification

      protected void showAutoRestoredNotification(ViewDraft draft)
    • formatTimestamp

      protected String formatTimestamp(ViewDraft draft)
    • getMinSaveInterval

      public Duration getMinSaveInterval()
      Description copied from interface: DraftsFacet
      Returns the minimum interval between draft writes of the owning view.
      Specified by:
      getMinSaveInterval in interface DraftsFacet
    • setMinSaveInterval

      public void setMinSaveInterval(Duration interval)
      Description copied from interface: DraftsFacet
      Sets the minimum interval between draft writes of the owning view.
      Specified by:
      setMinSaveInterval in interface DraftsFacet
    • getRestoreMode

      public RestoreMode getRestoreMode()
      Description copied from interface: DraftsFacet
      Returns how a found draft is restored.
      Specified by:
      getRestoreMode in interface DraftsFacet
    • setRestoreMode

      public void setRestoreMode(RestoreMode mode)
      Description copied from interface: DraftsFacet
      Sets how a found draft is restored.
      Specified by:
      setRestoreMode in interface DraftsFacet
    • setRestoreDelegate

      public void setRestoreDelegate(@Nullable Consumer<DraftRestoreContext> delegate)
      Description copied from interface: DraftsFacet
      Sets a delegate invoked when a draft is found for the owning view, allowing custom restore logic or preventing the facet's own restore behavior.
      Specified by:
      setRestoreDelegate in interface DraftsFacet
    • getRestoreDelegate

      public @Nullable Consumer<DraftRestoreContext> getRestoreDelegate()
      Description copied from interface: DraftsFacet
      Returns the currently set restore delegate, if any.
      Specified by:
      getRestoreDelegate in interface DraftsFacet
    • addDraftRestoredListener

      public com.vaadin.flow.shared.Registration addDraftRestoredListener(Consumer<DraftsFacet.DraftRestoredEvent> listener)
      Description copied from interface: DraftsFacet
      Specified by:
      addDraftRestoredListener in interface DraftsFacet
      Parameters:
      listener - a listener to add
      Returns:
      a registration object for removing the listener
    • getEventBus

      protected EventBus getEventBus()