Hi.
When using OnPopupOpen as a way to intercept different dialog launch events, I have found out that
given recurring appointment (let's say daily recurrence), if I modify single occurrence and then will try to delete it by single mouse click to 'tick' it and pressing delete, ARGS from OnPopupOpen method will give me
type of 'PopupType.RecurrenceAlert' instead of 'PopupType.DeleteAlert'.
What is the correct way of handling such situation? Is there some hidden arg that will differentiate action of editing a recurring appointment vs deletin
|
public void OnActionBegin(ActionEventArgs<AppointmentData> args)
{
var currentAction = ScheduleRef.GetCurrentAction();
} |
If async dialog is being open inside of OnPopupOpen custom handler (per your tutorial with custom editor window, just different dialog control), mentioned "OnActionBegin" method or direct invocation of ScheduleRef.GetCurrentAction() inside of "OnPopupOpen" gives 'stale' result.
Current action retrieved this way will contain a previous action of scheduler, not the currently began action, at least in my case.
If it will help - whole action, including opening and closing dialog and then, for example saving, concludes in OnPopupOpen handler method.
One addition to the topic:
In situation where OnPopupOpen handler uses default Syncfusion popup for delete action, but custom dialog for the editor window, GetCurrentAction method also provides stale data.
Example, when edit following occurrences option is enabled:
At first nothing will happen.
Again, choose same occurrence and press delete on keyboard. Select delete following series(?).
This time it will work.
Code uses for handler:
private Task OnPopupOpen(PopupOpenEventArgs<DeparturePlanGuiModel> args)
{
var popupType = args.Type;
// Leave those as default Syncfusion implementations.
switch (popupType)
{
case PopupType.RecurrenceAlert or PopupType.DeleteAlert or PopupType.RecurrenceValidationAlert:
return Task.CompletedTask;
// Disable QuickInfo
case PopupType.QuickInfo:
args.Cancel = true;
return Task.CompletedTask;
}
// Everything else will be handle by custom dialogs
args.Cancel = true;
return popupType is PopupType.Editor
? EditorDialogHandler(args.Data)
: Task.CompletedTask;
}
private async Task EditorDialogHandler(DeparturePlanGuiModel originalPlan)
{
var dialog = DialogService.Show("Edit dialog", new DialogParameters
{
{ "Data", originalPlan.Copy() },
{ "EditAction", originalPlan.RecurrenceID is null ? CurrentAction.EditSeries : CurrentAction.EditOccurrence },
{ "DeleteAction", CurrentAction.Delete }
});
var result = await dialog.Result;
if (result.Cancelled) return;
var (modifiedPlan, action) = ((DeparturePlanGuiModel, CurrentAction?))result.Data;
var schedulerAction = SchedulerRef.GetCurrentAction();
FuncchosenAction = action is CurrentAction.Delete
? originalPlan switch
{
var pl when pl.Id == default => () => Task.CompletedTask,
{ RecurrenceRule: null } => () => SchedulerRef.DeleteEventAsync(originalPlan),
_ when schedulerAction is CurrentAction.EditOccurrence => () =>
SchedulerRef.DeleteEventAsync(originalPlan, CurrentAction.DeleteOccurrence),
_ when schedulerAction is CurrentAction.EditSeries =>
() => SchedulerRef.DeleteEventAsync(originalPlan, CurrentAction.DeleteSeries),
_ when schedulerAction is CurrentAction.EditFollowingEvents =>
() => SchedulerRef.DeleteEventAsync(originalPlan, CurrentAction.DeleteFollowingEvents),
_ => throw new UnknownArgumentException($"Unhandled action for departure plan - {schedulerAction}",
nameof(originalPlan))
}
: originalPlan switch
{
var pl when pl.Id == default => () => SchedulerRef.AddEventAsync(modifiedPlan),
{ RecurrenceRule: null } => () => SchedulerRef.SaveEventAsync(modifiedPlan),
_ when schedulerAction is CurrentAction.EditOccurrence or CurrentAction.EditSeries or CurrentAction.EditFollowingEvents =>
() => SchedulerRef.SaveEventAsync(modifiedPlan, schedulerAction),
_ => throw new UnknownArgumentException($"Unhandled action for departure plan - {schedulerAction}",
nameof(originalPlan))
};
await chosenAction().ConfigureAwait(false);
}
Hi Nevitha.
Given working sample has one big difference from presented code - it uses completely different dialog mechanism.
Please, take a look again at provided code, mainly at
var dialog = DialogService.Show
{
{ "Data", originalPlan.Copy() },
{ "EditAction", originalPlan.RecurrenceID is null ? CurrentAction.EditSeries : CurrentAction.EditOccurrence },
{ "DeleteAction", CurrentAction.Delete }
});
var result = await dialog.Result;
if (result.Cancelled) return;
var (modifiedPlan, action) = ((DeparturePlanGuiModel, CurrentAction?))result.Data;
This is the start and end of custom dialog (MudBlazor nuget) that we try to implement to check compatibility with rest of our application - we cannot have different components presenting different styles and actions.
Returned tuple is the "decision" of a user - it returns new, modified appointment (departure plan) and chosen action - be it delete or edit. Call to Result.Data is made after dialog is closed, therefore after this line user has made a decision and later in code that decision is applied.
Async execution pauses to display dialog, user makes a choice or edits, clicks button, dialog closes and returns result - after that, method EditorDialogHandler continues.
Edit action is only passed into it for it's internal display configuration and when returned, it is used only to state that user wants to edit or delete dialog - type of occurrence is determined by using GetCurrentAction method after dialog is closed.
This problem seems to stop after some modifications to editor handler method from other syncfusion thread. I decided to leave this post as is for You to check on Your side just to be sure.
Current version of handler is:
public partial class DeparturePlans
{
private DateTime _now;
private ResourceDataProvider _resourceProvider;
[Inject] private IDialogService DialogService { get; init; }
[Inject] private IMediator Mediator { get; init; }
[Inject] private IDateTime DateTimeService { get; init; }
private SfSchedule<DeparturePlanGuiModel> SchedulerRef { get; set; }
protected override void OnInitialized()
{
_resourceProvider = new ResourceDataProvider(Mediator);
_now = DateTimeService.Now;
base.OnInitialized();
}
private Task OnPopupOpen(PopupOpenEventArgs<DeparturePlanGuiModel> args)
{
var popupType = args.Type;
// Leave those as default Syncfusion implementations.
switch (popupType)
{
case PopupType.RecurrenceAlert or PopupType.DeleteAlert or PopupType.RecurrenceValidationAlert:
return Task.CompletedTask;
// Disable QuickInfo
case PopupType.QuickInfo:
args.Cancel = true;
return Task.CompletedTask;
}
// Everything else will be handle by custom dialogs
args.Cancel = true;
return popupType is PopupType.Editor
? EditorDialogHandler(args.Data)
: Task.CompletedTask;
}
private async Task EditorDialogHandler(DeparturePlanGuiModel originalPlan)
{
var dialog = DialogService.Show<EditDialog>("Edit dialog", new DialogParameters
{
{ "Data", originalPlan.Copy() },
{ "EditAction", originalPlan.RecurrenceID is null ? CurrentAction.EditSeries : CurrentAction.EditOccurrence },
{ "DeleteAction", CurrentAction.Delete }
});
var result = await dialog.Result;
if (result.Cancelled) return;
var (modifiedPlan, action) = ((DeparturePlanGuiModel, CurrentAction?))result.Data;
var schedulerAction = SchedulerRef.GetCurrentAction();
Func<Task> chosenAction = action is CurrentAction.Delete
? originalPlan switch
{
var pl when pl.Id == default => () => Task.CompletedTask,
{ RecurrenceRule: null } => () => SchedulerRef.DeleteEventAsync(originalPlan),
_ when schedulerAction is CurrentAction.EditOccurrence => () =>
SchedulerRef.DeleteEventAsync(originalPlan, CurrentAction.DeleteOccurrence),
_ when schedulerAction is CurrentAction.EditSeries =>
() => SchedulerRef.DeleteEventAsync(originalPlan, CurrentAction.DeleteSeries),
_ when schedulerAction is CurrentAction.EditFollowingEvents =>
() => SchedulerRef.DeleteEventAsync(originalPlan, CurrentAction.DeleteFollowingEvents),
_ => throw new UnknownArgumentException($"Unhandled action for departure plan - {schedulerAction}",
nameof(originalPlan))
}
: originalPlan switch
{
var pl when pl.Id == default => () => SchedulerRef.AddEventAsync(modifiedPlan),
{ RecurrenceRule: null } => () => SchedulerRef.SaveEventAsync(modifiedPlan),
_ when schedulerAction is CurrentAction.EditOccurrence or CurrentAction.EditFollowingEvents => () =>
{
modifiedPlan.RecurrenceID = modifiedPlan.Id;
return SchedulerRef.SaveEventAsync(modifiedPlan, schedulerAction);
}
,
_ when schedulerAction is CurrentAction.EditSeries or CurrentAction.EditFollowingEvents =>
() => SchedulerRef.SaveEventAsync(modifiedPlan, schedulerAction),
_ => throw new UnknownArgumentException($"Unhandled action for departure plan - {schedulerAction}",
nameof(originalPlan))
};
await chosenAction().ConfigureAwait(false);
}
}