From acd107b1a21921f3543f83993f2cc4b11c8e21c5 Mon Sep 17 00:00:00 2001 From: Paul Ruston <60648319+paulo-rico@users.noreply.github.com> Date: Fri, 13 Dec 2024 12:47:17 +0000 Subject: [PATCH] Scheduler New View - MultiDay (#1852) * Scheduler New View - MultiDay * Clean up. Remove comment marker --- Radzen.Blazor/RadzenMultiDayView.razor | 15 ++ Radzen.Blazor/RadzenMultiDayView.razor.cs | 105 ++++++++++++++ .../Pages/SchedulerMultiDay.razor | 128 ++++++++++++++++++ RadzenBlazorDemos/Pages/SchedulerPage.razor | 8 ++ 4 files changed, 256 insertions(+) create mode 100644 Radzen.Blazor/RadzenMultiDayView.razor create mode 100644 Radzen.Blazor/RadzenMultiDayView.razor.cs create mode 100644 RadzenBlazorDemos/Pages/SchedulerMultiDay.razor diff --git a/Radzen.Blazor/RadzenMultiDayView.razor b/Radzen.Blazor/RadzenMultiDayView.razor new file mode 100644 index 00000000000..5367d9d4fe7 --- /dev/null +++ b/Radzen.Blazor/RadzenMultiDayView.razor @@ -0,0 +1,15 @@ +@using Radzen.Blazor +@using Radzen.Blazor.Rendering + +@inherits SchedulerViewBase + +@code { + public override RenderFragment Render() + { + var appointments = Scheduler.GetAppointmentsInRange(StartDate, EndDate).ToList(); + + return @ + + ; + } +} diff --git a/Radzen.Blazor/RadzenMultiDayView.razor.cs b/Radzen.Blazor/RadzenMultiDayView.razor.cs new file mode 100644 index 00000000000..b5da606cb15 --- /dev/null +++ b/Radzen.Blazor/RadzenMultiDayView.razor.cs @@ -0,0 +1,105 @@ +using Microsoft.AspNetCore.Components; +using Radzen.Blazor.Rendering; +using System; + +namespace Radzen.Blazor +{ + /// + /// Displays the appointments in a multi-day view in + /// + /// + /// <RadzenScheduler Data="@appointments"> + /// <RadzenMultiDayView /> + /// </RadzenScheduler> + /// + public partial class RadzenMultiDayView : SchedulerViewBase + { + /// + public override string Icon => "calendar_view_week"; + + /// + [Parameter] + public override string Text { get; set; } = "Multi-Day"; + + /// + /// Gets or sets the time format. + /// + /// The time format. Set to h tt by default. + [Parameter] + public string TimeFormat { get; set; } = "h tt"; + + /// + /// Gets or sets the format used to display the header text. + /// + /// The header text format. Set to ddd by default. + [Parameter] + public string HeaderFormat { get; set; } = "ddd"; + + /// + /// Gets or sets the start time. + /// + /// The start time. + [Parameter] + public TimeSpan StartTime { get; set; } = TimeSpan.FromHours(8); + + /// + /// Gets or sets the end time. + /// + /// The end time. + [Parameter] + public TimeSpan EndTime { get; set; } = TimeSpan.FromHours(24); + + /// + /// Gets or sets slot size in minutes. Set to 30 by default. + /// + /// The slot size in minutes. + [Parameter] + public int MinutesPerSlot { get; set; } = 30; + + /// + /// Gets or sets number of days to view. Set to 2 by default. + /// + /// The number of days. + [Parameter] + public int NumberOfDays { get; set; } = 2; + /// + public override DateTime StartDate + { + get + { + return Scheduler.CurrentDate.Date; + } + } + + /// + public override DateTime EndDate + { + get + { + return StartDate.AddDays(NumberOfDays); + } + } + + /// + public override string Title + { + get + { + return $"{StartDate.ToString(Scheduler.Culture.DateTimeFormat.ShortDatePattern)} - {EndDate.AddDays(-1).ToString(Scheduler.Culture.DateTimeFormat.ShortDatePattern)}"; + } + } + + + /// + public override DateTime Next() + { + return Scheduler.CurrentDate.Date.AddDays(NumberOfDays); + } + + /// + public override DateTime Prev() + { + return Scheduler.CurrentDate.Date.AddDays(-NumberOfDays); + } + } +} diff --git a/RadzenBlazorDemos/Pages/SchedulerMultiDay.razor b/RadzenBlazorDemos/Pages/SchedulerMultiDay.razor new file mode 100644 index 00000000000..2ba9c7bd1c0 --- /dev/null +++ b/RadzenBlazorDemos/Pages/SchedulerMultiDay.razor @@ -0,0 +1,128 @@ +@inject DialogService DialogService + + + + + + @if(sliderNumberOfDays==2) + { + + } + + + + + + + + + + + +@code { + RadzenScheduler scheduler; + EventConsole console; + Dictionary events = new Dictionary(); + + int sliderNumberOfDays { get; set; } = 2; + + IList appointments = new List + { + new Appointment { Start = DateTime.Today.AddDays(-2), End = DateTime.Today.AddDays(-2), Text = "Birthday" }, + new Appointment { Start = DateTime.Today.AddDays(-11), End = DateTime.Today.AddDays(-10), Text = "Day off" }, + new Appointment { Start = DateTime.Today.AddDays(-10), End = DateTime.Today.AddDays(-8), Text = "Work from home" }, + new Appointment { Start = DateTime.Today.AddHours(10), End = DateTime.Today.AddHours(12), Text = "Online meeting" }, + new Appointment { Start = DateTime.Today.AddHours(10), End = DateTime.Today.AddHours(13), Text = "Skype call" }, + new Appointment { Start = DateTime.Today.AddHours(14), End = DateTime.Today.AddHours(14).AddMinutes(30), Text = "Dentist appointment" }, + new Appointment { Start = DateTime.Today.AddDays(1), End = DateTime.Today.AddDays(12), Text = "Vacation" }, + }; + + async Task NumberOfDaysChange() + { + await scheduler.Reload(); + } + + void OnSlotRender(SchedulerSlotRenderEventArgs args) + { + // Highlight today in month view + if (args.View.Text == "Month" && args.Start.Date == DateTime.Today) + { + args.Attributes["style"] = "background: var(--rz-scheduler-highlight-background-color, rgba(255,220,40,.2));"; + } + + // Highlight working hours (9-18) + if ((args.View.Text == "Week" || args.View.Text == "Day") && args.Start.Hour > 8 && args.Start.Hour < 19) + { + args.Attributes["style"] = "background: var(--rz-scheduler-highlight-background-color, rgba(255,220,40,.2));"; + } + } + + async Task OnSlotSelect(SchedulerSlotSelectEventArgs args) + { + console.Log($"SlotSelect: Start={args.Start} End={args.End}"); + + if (args.View.Text != "Year") + { + Appointment data = await DialogService.OpenAsync("Add Appointment", + new Dictionary { { "Start", args.Start }, { "End", args.End } }); + + if (data != null) + { + appointments.Add(data); + // Either call the Reload method or reassign the Data property of the Scheduler + await scheduler.Reload(); + } + } + } + + async Task OnAppointmentSelect(SchedulerAppointmentSelectEventArgs args) + { + console.Log($"AppointmentSelect: Appointment={args.Data.Text}"); + + var copy = new Appointment + { + Start = args.Data.Start, + End = args.Data.End, + Text = args.Data.Text + }; + + var data = await DialogService.OpenAsync("Edit Appointment", new Dictionary { { "Appointment", copy } }); + + if (data != null) + { + // Update the appointment + args.Data.Start = data.Start; + args.Data.End = data.End; + args.Data.Text = data.Text; + } + + await scheduler.Reload(); + } + + void OnAppointmentRender(SchedulerAppointmentRenderEventArgs args) + { + // Never call StateHasChanged in AppointmentRender - would lead to infinite loop + + if (args.Data.Text == "Birthday") + { + args.Attributes["style"] = "background: red"; + } + } + + async Task OnAppointmentMove(SchedulerAppointmentMoveEventArgs args) + { + var draggedAppointment = appointments.FirstOrDefault(x => x == args.Appointment.Data); + + if (draggedAppointment != null) + { + draggedAppointment.Start = draggedAppointment.Start + args.TimeSpan; + + draggedAppointment.End = draggedAppointment.End + args.TimeSpan; + + await scheduler.Reload(); + } + } +} \ No newline at end of file diff --git a/RadzenBlazorDemos/Pages/SchedulerPage.razor b/RadzenBlazorDemos/Pages/SchedulerPage.razor index d043e89290e..b22552d6096 100644 --- a/RadzenBlazorDemos/Pages/SchedulerPage.razor +++ b/RadzenBlazorDemos/Pages/SchedulerPage.razor @@ -31,6 +31,14 @@ + + Display any number of days side-by-side + + + + + + Keyboard Navigation