Hi!
We are currently testing Your scheduler controller ability to handle custom dialogs.
Given situation that, as Your tutorial states, we want to create a dialog for custom appointment edit with validation.
Assume, that:
Our dialog starts and async finish inside of method handling said event (async Task PopupOpen(PopupOpenEventArgs
Dialog is being open, user can edit all the data that he want and on close, dialog returns either modified or new instance of data model (appointment).
Said dialog is not a Syncfusion product.
Absolutely crude and ugly version of said method looks like that:
private async Task PopupOpen(PopupOpenEventArgs
{
if (args.Type == PopupType.Editor)
{
args.Cancel = true; //to prevent the default editor window
var action = args.Data.Id == 0 ? "CellClick" : "AppointmentClick"; //to check whether the window opens on cell or appointment
if (action.Equals("CellClick"))
{
var dialog = DialogService.Show
{
{"Data", args.Data}
});
var result = await dialog.Result;
if (result.Cancelled)
return;
var data = result.Data as DeparturePlanGuiModel;
data.Id = rand.Next(99999);
await SchedulerRef.AddEventAsync(data.Copy());
}
else
{
var dialog = DialogService.Show
{
{"Data", args.Data}
});
var result = await dialog.Result;
if (result.Cancelled)
return;
await SchedulerRef.SaveEventAsync(result.Data.Copy() as DeparturePlanGuiModel);
}
}
if (args.Type == PopupType.QuickInfo)
{
args.Cancel = true;
}
}
)
There are two main issues:
First - We cannot correctly hook to Scheduler's 'delete occurrence or series' popup - how we could do that?
Second - after editing recurring meeting's single occurrence, when tested with ActionComplete event handler, there is no new appointment created in addition to recurring meeting edit - only edited appointment is given in handler args.
Custom dialog is displayed using MudBlazor dialog service.
if (Action == "CellClick")
{
await ScheduleRef.AddEventAsync(EventData); //to add new appointment
}
else
{
if (EventData.RecurrenceRule == null)
{
await ScheduleRef.SaveEventAsync(EventData); // to save the existing appointment
}
else
{
if (ScheduleRef.GetCurrentAction() == CurrentAction.EditOccurrence)
{
await ScheduleRef.SaveEventAsync(EventData, CurrentAction.EditOccurrence);
}
else
{
await ScheduleRef.SaveEventAsync(EventData, CurrentAction.EditSeries);
}
}
} |
I presume, that problems with passing Edit occurrence are:
When editing already modified occurrence of a series by changing a subject for example, the newly changed occurrence does not replace the old one but instead adds completely new, edited occurrence to the scheduler.
Is this the case? Or is it issue on my side?
In this case, bottom right occurrence was edited and the additional 999 occurrence is the result.
Below is my current (after Your suggestions) implementation of OnPopupOpen handler.
I Would like your opinion on the matter.
private async Task PopupOpen(PopupOpenEventArgsargs)
{
var popupType = args.Type;
var schedulerAction = SchedulerRef.GetCurrentAction();
var plan = args.Data;
// Leave those as default Syncfusion implementations.
switch (popupType)
{
case PopupType.RecurrenceAlert or PopupType.DeleteAlert or PopupType.RecurrenceValidationAlert:
return;
// Disable QuickInfo
case PopupType.QuickInfo:
args.Cancel = true;
return;
}
// Everything else will be handle by custom dialogs
args.Cancel = true;
var dialog = DialogService.Show("Main dialog", new DialogParameters
{
{ "Data", plan.Copy() }, // Copy method creates deep copy of the plan object
{ "EditAction", plan.RecurrenceID is null ? CurrentAction.EditSeries : CurrentAction.EditOccurrence },
{ "DeleteAction", CurrentAction.Delete }
});
var result = await dialog.Result;
if (result.Cancelled) return;
var (model, action) = ((DeparturePlanGuiModel, CurrentAction?))result.Data;
switch (plan)
{
case var p when p.Id == default && action is CurrentAction.Delete:
break;
case var p when p.Id == default:
await SchedulerRef.AddEventAsync(model);
break;
case var p when p.RecurrenceRule is null && action is CurrentAction.Delete:
await SchedulerRef.DeleteEventAsync(model);
break;
case var p when p.RecurrenceRule is null:
await SchedulerRef.SaveEventAsync(model);
break;
case var _ when schedulerAction is CurrentAction.EditOccurrence or CurrentAction.EditSeries && action is CurrentAction.Delete:
await SchedulerRef.DeleteEventAsync(model, schedulerAction is CurrentAction.EditOccurrence ? CurrentAction.DeleteOccurrence : CurrentAction.DeleteSeries);break;
case var _ when schedulerAction is CurrentAction.EditOccurrence or CurrentAction.EditSeries:
await SchedulerRef.SaveEventAsync(model, schedulerAction);
break;
default:
throw new UnknownArgumentException($"Unhandled action for departure plan - {schedulerAction}", nameof(args));
}
}
With regards,
Henryk
private async void OnValidSubmit() //triggers on save button click
{
DialogVisibility = false;
AppointmentData EventData = new AppointmentData();
EventData.Subject = AppointmentValidation.Subject;
EventData.EndTime = (DateTime)AppointmentValidation.EndTime;
EventData.StartTime = (DateTime)AppointmentValidation.StartTime;
EventData.Description = AppointmentValidation.Description;
EventData.OwnerId = AppointmentValidation.OwnerId;
EventData.AppointmentType = AppointmentValidation.AppointmentType;
EventData.RecurrenceRule = AppointmentValidation.RecurrenceRule;
EventData.Id = Id;
if (Action == "CellClick")
{
await ScheduleRef.AddEventAsync(EventData); //to add new appointment
}
else
{
if (EventData.RecurrenceRule == null)
{
await ScheduleRef.SaveEventAsync(EventData); // to save the existing appointment
}
else
{
if (ScheduleRef.GetCurrentAction() == CurrentAction.EditOccurrence)
{
EventData.RecurrenceID = EventData.Id;
EventData.Id = await ScheduleRef.GetMaxEventIdAsync<int>() + 1;
await ScheduleRef.SaveEventAsync(EventData, CurrentAction.EditOccurrence);
}
else
{
await ScheduleRef.SaveEventAsync(EventData, CurrentAction.EditSeries);
}
}
}
}
private void PopupOpen(PopupOpenEventArgs<AppointmentData> args)
{
if (args.Type == PopupType.RecurrenceAlert || args.Type == PopupType.DeleteAlert || args.Type == PopupType.RecurrenceValidationAlert)
{
return;
}
if (args.Type == PopupType.Editor)
{
args.Cancel = true; //to prevent the default editor window
this.Action = args.Data.Id == 0 ? "CellClick" : "AppointmentClick"; //to check whether the window opens on cell or appointment
if (Action == "CellClick")
{
AppointmentValidation.StartTime = args.Data.StartTime;
AppointmentValidation.EndTime = args.Data.EndTime;
AppointmentValidation.Description = args.Data.Description;
AppointmentValidation.OwnerId = args.Data.OwnerId;
Random random = new Random();
Id = random.Next(2, 1000);
}
else
{
Id = args.Data.Id;
AppointmentValidation.StartTime = args.Data.StartTime;
AppointmentValidation.EndTime = args.Data.EndTime;
AppointmentValidation.AppointmentType = args.Data.AppointmentType;
AppointmentValidation.OwnerId = args.Data.OwnerId;
}
AppointmentValidation.Description = args.Data.Description == null ? "" : args.Data.Description;
AppointmentValidation.Subject = args.Data.Subject == null ? "Add title" : args.Data.Subject;
DialogVisibility = true;
}
if (args.Type == PopupType.QuickInfo)
{
args.Cancel = true;
}
} |