Skip to content

Commit a7d4377

Browse files
authored
Scheduler component (#6092)
* Scheduler component moved from 2.0 branch * White toolbar * Docs * Fix month view sizing * Top borders * Fix column sizing * Refresh method * Drag Drop WIP * New feature badge * Add to nuget pack * dragdrop WIP * refactor drag drop * Drop month items * Draggable parameter * Add SchedulerPropertyMapper * DeletedOccurrences * treat DeleteOccurrenceImpl as an edit operation * Modify edit and delete logic * Use mapper on modal * Rename SchedulerItemModa * Edit occurrences * Null checks * Optimize recurrences * Manage drag of recurring items * Saving dropped items * Delete logic fixed * Semantics on delete * xml comments * Use TItem for passing items * Drag allday items * Recurring allday items * Simlify SchedulerItemInfo constructors * drag area WIP * DragArea fix * is null/is not null * Comments * Add ShowWeekNumbers on month view * Show Drag effect * Drag effect * Optimize fluent utilities allocations * DropAllowed callback * Reconcile edit and delete events * Bogus data faker * Rename DragArea and DragSection * Fix week view maxdate * ItemStyling * Add Fundamentals to the docs section * Use new Flex Basis utility * Add missing Basis chain to IFluentFlexAll * Overflow.Auto on day cell * Show Primary color for selected buttons * Fix modals naming * Fix day of week calculation * Fix bug with TimeOnly overflow * Create AllDay item on slot click * Missing localization and centralize constants * Value limitations * Prevent saving of invalid RecurrenceRule * Larger modal * Trigger date localization * Ability to close message on focus lost * Localization for validation messages * Add ViewHeight parameter * Add data attributes for start and end times * ItemTemplate * Add aria labels * Fix json * Scheduler: Selection logic (#6098) * Selection logic * Listen on document level with JS to cancel selection * Comment * Fix selecting css * Better transaction handling * Refactor transactions * SlotSelectionMode parameter * Enable selection in demo * Listen for document mouse only when selecting * Fix SelectionEnded * Use InvokeSafeVoidAsync in JSModule * Deselect when outside of valid day column * Add CSS file * Optimize slot mouse events to only use them when needed * Add extension methods to RenderTreeBuilderExtensions * Manually build slot and items * Add more Attribute overloads * Fix TW build error * null-coalescing * Refactor null selection dates * Remove unused totalSlots var * One line style * Add ThrottleDispatcher * Optimize loops with key * Remove unused BackgroundColor * DateUtils for Min and Max * Unregister previous mouseUpHandler if exists * Remove unused DraggableAttribute * Clean * Editable default to false * Examples * Editable demo * Rename navigate methods * Comments * Docs update * Autofocus on title
1 parent d9260d2 commit a7d4377

File tree

150 files changed

+13447
-5
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

150 files changed

+13447
-5
lines changed

Blazorise.sln

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Blazorise.Weavers", "Source
161161
EndProject
162162
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Blazorise.Weavers.Fody", "Source\SourceGenerators\Blazorise.Weavers.Fody\Blazorise.Weavers.Fody.csproj", "{FFC4A285-1A16-4DD4-8B8C-141521E405B0}"
163163
EndProject
164+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Blazorise.Scheduler", "Source\Extensions\Blazorise.Scheduler\Blazorise.Scheduler.csproj", "{E2582180-8E51-43E1-0943-588D720FCAB5}"
165+
EndProject
164166
Global
165167
GlobalSection(SolutionConfigurationPlatforms) = preSolution
166168
Debug|Any CPU = Debug|Any CPU
@@ -423,6 +425,10 @@ Global
423425
{FFC4A285-1A16-4DD4-8B8C-141521E405B0}.Debug|Any CPU.Build.0 = Debug|Any CPU
424426
{FFC4A285-1A16-4DD4-8B8C-141521E405B0}.Release|Any CPU.ActiveCfg = Release|Any CPU
425427
{FFC4A285-1A16-4DD4-8B8C-141521E405B0}.Release|Any CPU.Build.0 = Release|Any CPU
428+
{E2582180-8E51-43E1-0943-588D720FCAB5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
429+
{E2582180-8E51-43E1-0943-588D720FCAB5}.Debug|Any CPU.Build.0 = Debug|Any CPU
430+
{E2582180-8E51-43E1-0943-588D720FCAB5}.Release|Any CPU.ActiveCfg = Release|Any CPU
431+
{E2582180-8E51-43E1-0943-588D720FCAB5}.Release|Any CPU.Build.0 = Release|Any CPU
426432
EndGlobalSection
427433
GlobalSection(SolutionProperties) = preSolution
428434
HideSolutionNode = FALSE
@@ -495,6 +501,7 @@ Global
495501
{EAB7EC89-900A-4280-B24A-152B9DD2B503} = {9731051E-0AA7-411E-A76A-987854F034DA}
496502
{BF5FFB8C-45AD-4875-BB01-2DA388890419} = {0538DB67-B4F3-4D00-B969-D3874A52E405}
497503
{FFC4A285-1A16-4DD4-8B8C-141521E405B0} = {0538DB67-B4F3-4D00-B969-D3874A52E405}
504+
{E2582180-8E51-43E1-0943-588D720FCAB5} = {9731051E-0AA7-411E-A76A-987854F034DA}
498505
EndGlobalSection
499506
GlobalSection(ExtensibilityGlobals) = postSolution
500507
SolutionGuid = {205B3EA4-470F-45DA-911E-346AF7D0A9A5}

Build/Blazorise.Demo.props

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
<PackageReference Include="FluentValidation.DependencyInjectionExtensions" Version="11.10.0" />
2222
<PackageReference Include="Flurl.Http" Version="4.0.0-pre2" />
2323
<PackageReference Include="Blazored.LocalStorage" Version="4.5.0" />
24+
<PackageReference Include="Bogus" Version="35.6.3" />
2425
</ItemGroup>
2526

2627
</Project>

Demos/Blazorise.Demo/Blazorise.Demo.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
<ProjectReference Include="..\..\Source\Extensions\Blazorise.SignaturePad\Blazorise.SignaturePad.csproj" />
3030
<ProjectReference Include="..\..\Source\Extensions\Blazorise.FluentValidation\Blazorise.FluentValidation.csproj" />
3131
<ProjectReference Include="..\..\Source\Extensions\Blazorise.PdfViewer\Blazorise.PdfViewer.csproj" />
32+
<ProjectReference Include="..\..\Source\Extensions\Blazorise.Scheduler\Blazorise.Scheduler.csproj" />
3233
<ProjectReference Include="..\Apps\TodoApp\TodoApp.csproj" />
3334
</ItemGroup>
3435

Demos/Blazorise.Demo/Components/SideMenu.razor

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -309,6 +309,8 @@
309309
<BarDropdownItem To="tests/qrcode">QR Code</BarDropdownItem>
310310
<BarDropdownItem To="tests/repeater">Repeater</BarDropdownItem>
311311
<BarDropdownItem To="tests/richtextedit">RichTextEdit</BarDropdownItem>
312+
<BarDropdownItem To="tests/routertabs">Router Tabs</BarDropdownItem>
313+
<BarDropdownItem To="tests/scheduler">Scheduler</BarDropdownItem>
312314
<BarDropdownItem To="tests/selectlist">Select List</BarDropdownItem>
313315
<BarDropdownItem To="tests/signaturepad">SignaturePad</BarDropdownItem>
314316
<BarDropdownItem To="tests/snackbar">Snackbar</BarDropdownItem>
@@ -317,7 +319,6 @@
317319
<BarDropdownItem To="tests/transferlist">Transfer List</BarDropdownItem>
318320
<BarDropdownItem To="tests/treeview">TreeView</BarDropdownItem>
319321
<BarDropdownItem To="tests/video">Video</BarDropdownItem>
320-
<BarDropdownItem To="tests/routertabs">Router Tabs</BarDropdownItem>
321322
</BarDropdownMenu>
322323
</BarDropdown>
323324
</BarItem>
Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
@page "/tests/scheduler"
2+
@using Bogus
3+
<Row>
4+
<Column>
5+
<Card Margin="Margin.Is4.OnY">
6+
<CardHeader>
7+
<CardTitle>Scheduler</CardTitle>
8+
</CardHeader>
9+
<CardBody>
10+
<Scheduler TItem="SchedulerAppointment" @bind-Date="@selectedDate"
11+
Data="@Appointments"
12+
@bind-SelectedView="@selectedView"
13+
Editable
14+
Draggable
15+
ItemStyling="@OnItemStyling"
16+
SlotSelectionMode="SchedulerSlotSelectionMode.Mouse">
17+
<SchedulerToolbar />
18+
<SchedulerViews>
19+
<SchedulerDayView StartTime="@(new TimeOnly( 7, 0 ))" EndTime="@(new TimeOnly( 17, 0 ))" WorkDayStart="@(new TimeOnly( 8, 0 ))" WorkDayEnd="@(new TimeOnly( 16, 0 ))" />
20+
<SchedulerWeekView StartTime="@(new TimeOnly( 7, 0 ))" EndTime="@(new TimeOnly( 17, 0 ))" WorkDayStart="@(new TimeOnly( 8, 0 ))" WorkDayEnd="@(new TimeOnly( 16, 0 ))" />
21+
<SchedulerWorkWeekView StartTime="@(new TimeOnly( 7, 0 ))" EndTime="@(new TimeOnly( 17, 0 ))" WorkDayStart="@(new TimeOnly( 8, 0 ))" WorkDayEnd="@(new TimeOnly( 16, 0 ))" />
22+
<SchedulerMonthView StartTime="@(new TimeOnly( 7, 0 ))" EndTime="@(new TimeOnly( 17, 0 ))" WorkDayStart="@(new TimeOnly( 8, 0 ))" WorkDayEnd="@(new TimeOnly( 16, 0 ))" />
23+
</SchedulerViews>
24+
</Scheduler>
25+
</CardBody>
26+
</Card>
27+
</Column>
28+
</Row>
29+
<Row>
30+
<Column>
31+
Selected date: @selectedDate
32+
</Column>
33+
</Row>
34+
@code {
35+
[Inject] IMessageService MessageService { get; set; }
36+
private DateOnly selectedDate = DateOnly.FromDateTime( DateTime.Today );
37+
private SchedulerView selectedView = SchedulerView.Week;
38+
39+
private static DateTime start = DateTime.Today.AddHours( 10 );
40+
41+
private Faker<SchedulerAppointment> appointmentFaker = new Faker<SchedulerAppointment>()
42+
.RuleFor( a => a.Title, f => f.Lorem.Sentence( 3 ) )
43+
.RuleFor( a => a.Description, f => f.Lorem.Paragraph() );
44+
45+
private Task OnSlotClicked( SchedulerSlotClickedEventArgs eventArgs )
46+
{
47+
var start = eventArgs.Start;
48+
var end = eventArgs.End;
49+
50+
var fakeAppointment = appointmentFaker.Generate();
51+
fakeAppointment.Start = start;
52+
fakeAppointment.End = end;
53+
54+
Appointments.Add( fakeAppointment );
55+
56+
return Task.CompletedTask;
57+
}
58+
59+
private async Task<bool> IsDropAllowed( SchedulerDragEventArgs<SchedulerAppointment> eventArgs )
60+
{
61+
await MessageService.Warning( "You cannot drop this appointment here", "Drop not allowed" );
62+
63+
return false;
64+
}
65+
66+
private void OnItemStyling( SchedulerAppointment appointment, SchedulerItemStyling itemStyling )
67+
{
68+
if ( appointment.Title.Contains( "ceo", StringComparison.OrdinalIgnoreCase ) )
69+
itemStyling.Background = Background.Danger;
70+
else if ( appointment.Title.Contains( "client", StringComparison.OrdinalIgnoreCase ) )
71+
itemStyling.Background = Background.Success;
72+
else if ( appointment.Title.Contains( "lunch", StringComparison.OrdinalIgnoreCase ) )
73+
itemStyling.Background = Background.Info;
74+
}
75+
76+
public class SchedulerAppointment
77+
{
78+
public SchedulerAppointment()
79+
{
80+
}
81+
82+
public SchedulerAppointment( string title, string description, DateTime start, DateTime end, bool allDay = false )
83+
{
84+
Id = Guid.NewGuid().ToString();
85+
Title = title;
86+
Description = description;
87+
Start = start;
88+
End = end;
89+
AllDay = allDay;
90+
}
91+
92+
public SchedulerAppointment( string id, string title, string description, DateTime start, DateTime end, bool allDay = false )
93+
{
94+
Id = id;
95+
Title = title;
96+
Description = description;
97+
Start = start;
98+
End = end;
99+
AllDay = allDay;
100+
}
101+
102+
public string Id { get; set; }
103+
104+
public string Title { get; set; }
105+
106+
public string Description { get; set; }
107+
108+
public DateTime Start { get; set; }
109+
110+
public DateTime End { get; set; }
111+
112+
public bool AllDay { get; set; }
113+
114+
public string RecurrenceRule { get; set; }
115+
116+
public string RecurrenceId { get; set; }
117+
118+
public List<DateTime> DeletedOccurrences { get; set; }
119+
120+
public DateTime? OriginalStart { get; set; }
121+
122+
public List<SchedulerAppointment> RecurrenceExceptions { get; set; }
123+
}
124+
125+
List<SchedulerAppointment> Appointments = new List<SchedulerAppointment>
126+
{
127+
new SchedulerAppointment( "Meeting with the CEO", "Regarding the new margeting strategy", start, start.AddHours(1) ),
128+
new SchedulerAppointment( "Some other meeting", "Regarding the new margeting strategy", start, start.AddHours(1) ),
129+
new SchedulerAppointment( "Lunch with the team", "Discussing the new project", start.AddDays(-10).AddHours(2), start.AddDays(-10).AddHours(3))
130+
{
131+
RecurrenceRule = "FREQ=WEEKLY;BYDAY=MO,TU,WE,TH,FR;INTERVAL=2;COUNT=3"
132+
// RecurrenceRule = "FREQ=DAILY;INTERVAL=1;COUNT=10;"
133+
// RecurrenceRule = "FREQ=MONTHLY;INTERVAL=2;BYMONTHDAY=1;COUNT=2;"
134+
},
135+
new SchedulerAppointment( "Meeting with the client", "Discussing the new project", start.AddHours(4), start.AddHours(5) ),
136+
new SchedulerAppointment( "Test 1", "Test 1 desc", DateTime.Today.AddDays(-2), DateTime.Today.AddDays(-2), true ),
137+
new SchedulerAppointment( "All day event with the team", "Team building", DateTime.Today.AddDays(-2), DateTime.Today, true),
138+
new SchedulerAppointment( "Games with the team", "Having fun", DateTime.Today, DateTime.Today, true ),
139+
};
140+
}

Demos/Blazorise.Demo/_Imports.razor

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,4 +32,5 @@
3232
@using Blazorise.Shared.Models
3333
@using Blazorise.SignaturePad
3434
@using Blazorise.PdfViewer
35+
@using Blazorise.Scheduler
3536
@using TodoApp

Documentation/Blazorise.Docs/Blazorise.Docs.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
<ProjectReference Include="..\..\Source\Extensions\Blazorise.SignaturePad\Blazorise.SignaturePad.csproj" />
4141
<ProjectReference Include="..\..\Source\Extensions\Blazorise.Splitter\Blazorise.Splitter.csproj" />
4242
<ProjectReference Include="..\..\Source\Extensions\Blazorise.PdfViewer\Blazorise.PdfViewer.csproj" />
43+
<ProjectReference Include="..\..\Source\Extensions\Blazorise.Scheduler\Blazorise.Scheduler.csproj" />
4344
<PackageReference Include="MailKit" Version="4.8.0" />
4445
<PackageReference Include="Microsoft.Extensions.Http" Version="9.0.*" />
4546
<PackageReference Include="MimeKit" Version="4.8.0" />

Documentation/Blazorise.Docs/Layouts/DocsLayout.razor

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,9 @@
269269
<BarDropdownItem To="docs/extensions/routertabs" Flex="Flex.JustifyContent.Between">
270270
<DocsNewFeatureBadge>RouterTabs</DocsNewFeatureBadge>
271271
</BarDropdownItem>
272+
<BarDropdownItem To="docs/extensions/scheduler" Flex="Flex.JustifyContent.Between">
273+
<DocsNewFeatureBadge>Scheduler</DocsNewFeatureBadge>
274+
</BarDropdownItem>
272275
<BarDropdownItem To="docs/extensions/selectlist">SelectList</BarDropdownItem>
273276
<BarDropdownItem To="docs/extensions/sidebar">Sidebar</BarDropdownItem>
274277
<BarDropdownItem To="docs/extensions/signaturepad">SignaturePad</BarDropdownItem>

0 commit comments

Comments
 (0)