5
5
using System . Linq ;
6
6
using System . Threading . Tasks ;
7
7
using BlazorScheduler . Internal . Extensions ;
8
- using BlazorScheduler . Configuration ;
9
8
using BlazorScheduler . Internal . Components ;
10
9
using System . Collections . ObjectModel ;
11
10
12
11
namespace BlazorScheduler
13
12
{
14
13
public partial class Scheduler : IAsyncDisposable
15
14
{
16
- [ Parameter ] public RenderFragment Appointments { get ; set ; }
17
- [ Parameter ] public RenderFragment < Scheduler > HeaderTemplate { get ; set ; }
18
- [ Parameter ] public RenderFragment < DateTime > DayTemplate { get ; set ; }
19
-
20
- [ Parameter ] public Func < DateTime , DateTime , Task > OnRequestNewData { get ; set ; }
21
- [ Parameter ] public Func < DateTime , DateTime , Task > OnAddingNewAppointment { get ; set ; }
22
- [ Parameter ] public Func < DateTime , Task > OnOverflowAppointmentClick { get ; set ; }
23
-
24
- [ Parameter ] public Config Config { get ; set ; } = new ( ) ;
15
+ [ Parameter ] public RenderFragment Appointments { get ; set ; } = null ! ;
16
+ [ Parameter ] public RenderFragment < Scheduler > ? HeaderTemplate { get ; set ; }
17
+ [ Parameter ] public RenderFragment < DateTime > ? DayTemplate { get ; set ; }
18
+
19
+ [ Parameter ] public Func < DateTime , DateTime , Task > ? OnRequestNewData { get ; set ; }
20
+ [ Parameter ] public Func < DateTime , DateTime , Task > ? OnAddingNewAppointment { get ; set ; }
21
+ [ Parameter ] public Func < DateTime , Task > ? OnOverflowAppointmentClick { get ; set ; }
22
+
23
+ #region Config
24
+ [ Parameter ] public bool AlwaysShowYear { get ; set ; } = true ;
25
+ [ Parameter ] public int MaxVisibleAppointmentsPerDay { get ; set ; } = 5 ;
26
+ [ Parameter ] public bool EnableDragging { get ; set ; } = true ;
27
+ [ Parameter ] public bool EnableRescheduling { get ; set ; }
28
+ [ Parameter ] public string ThemeColor { get ; set ; } = "aqua" ;
29
+ [ Parameter ] public DayOfWeek StartDayOfWeek { get ; set ; } = DayOfWeek . Sunday ;
30
+ [ Parameter ] public string TodayButtonText { get ; set ; } = "Today" ;
31
+ [ Parameter ] public string PlusOthersText { get ; set ; } = "+ {n} others" ;
32
+ #endregion
25
33
26
34
public DateTime CurrentDate { get ; private set ; }
27
- public Appointment NewAppointment { get ; private set ; }
35
+ public Appointment ? DraggingAppointment { get ; private set ; }
28
36
29
37
private string MonthDisplay
30
38
{
31
39
get
32
40
{
33
41
var res = CurrentDate . ToString ( "MMMM" ) ;
34
- if ( Config . AlwaysShowYear || CurrentDate . Year != DateTime . Today . Year )
42
+ if ( AlwaysShowYear || CurrentDate . Year != DateTime . Today . Year )
35
43
{
36
44
return res += CurrentDate . ToString ( " yyyy" ) ;
37
45
}
@@ -40,12 +48,12 @@ private string MonthDisplay
40
48
}
41
49
42
50
private readonly ObservableCollection < Appointment > _appointments = new ( ) ;
43
- private DotNetObjectReference < Scheduler > _objReference ;
51
+ private DotNetObjectReference < Scheduler > _objReference = null ! ;
44
52
private bool _loading = false ;
45
53
46
54
public bool _showNewAppointment ;
47
- private DateTime _draggingAppointmentAnchor ;
48
- private DateTime _newAppointmentStart , _newAppointmentEnd ;
55
+ private DateTime ? _draggingAppointmentAnchor ;
56
+ private DateTime ? _draggingStart , _draggingEnd ;
49
57
50
58
protected override async Task OnInitializedAsync ( )
51
59
{
@@ -110,9 +118,9 @@ private async Task ChangeMonth(int months = 0)
110
118
111
119
private ( DateTime , DateTime ) GetDateRangeForCurrentMonth ( )
112
120
{
113
- var startDate = new DateTime ( CurrentDate . Year , CurrentDate . Month , 1 ) . GetPrevious ( Config . StartDayOfWeek ) ;
121
+ var startDate = new DateTime ( CurrentDate . Year , CurrentDate . Month , 1 ) . GetPrevious ( StartDayOfWeek ) ;
114
122
var endDate = new DateTime ( CurrentDate . Year , CurrentDate . Month , DateTime . DaysInMonth ( CurrentDate . Year , CurrentDate . Month ) )
115
- . GetNext ( ( DayOfWeek ) ( ( int ) ( Config . StartDayOfWeek - 1 + 7 ) % 7 ) ) ;
123
+ . GetNext ( ( DayOfWeek ) ( ( int ) ( StartDayOfWeek - 1 + 7 ) % 7 ) ) ;
116
124
117
125
return ( startDate , endDate ) ;
118
126
}
@@ -127,30 +135,69 @@ private IEnumerable<DateTime> GetDaysInRange()
127
135
128
136
private IEnumerable < Appointment > GetAppointmentsInRange ( DateTime start , DateTime end )
129
137
{
130
- var appointmentsInTimeframe = _appointments . Where ( x => ( start , end ) . Overlaps ( ( x . Start , x . End ) ) ) ;
138
+ var appointmentsInTimeframe = _appointments
139
+ . Where ( x => x . IsVisible )
140
+ . Where ( x => ( start , end ) . Overlaps ( ( x . Start . Date , x . End . Date ) ) ) ;
141
+
131
142
return appointmentsInTimeframe
132
143
. OrderBy ( x => x . Start )
133
144
. ThenByDescending ( x => ( x . End - x . Start ) . Days ) ;
134
145
}
135
146
147
+ private Appointment ? _reschedulingAppointment ;
148
+ public void BeginDrag ( Appointment appointment )
149
+ {
150
+ if ( ! EnableRescheduling || appointment . OnReschedule is null || _reschedulingAppointment is not null || _showNewAppointment )
151
+ return ;
152
+
153
+ appointment . IsVisible = false ;
154
+
155
+ _reschedulingAppointment = appointment ;
156
+ _draggingStart = appointment . Start ;
157
+ _draggingEnd = appointment . End ;
158
+ _draggingAppointmentAnchor = null ;
159
+
160
+ StateHasChanged ( ) ;
161
+ }
162
+
136
163
public void BeginDrag ( SchedulerDay day )
137
164
{
138
- _newAppointmentStart = _newAppointmentEnd = day . Day ;
165
+ if ( ! EnableDragging )
166
+ return ;
167
+
168
+ _draggingStart = _draggingEnd = day . Day ;
139
169
_showNewAppointment = true ;
140
170
141
- _draggingAppointmentAnchor = _newAppointmentStart ;
171
+ _draggingAppointmentAnchor = _draggingStart ;
142
172
StateHasChanged ( ) ;
143
173
}
144
174
175
+ public bool IsDayBeingScheduled ( Appointment appointment )
176
+ => ReferenceEquals ( appointment , DraggingAppointment ) && _reschedulingAppointment is not null ;
177
+
145
178
[ JSInvokable ]
146
179
public async Task OnMouseUp ( int button )
147
180
{
148
- if ( button == 0 )
181
+ if ( button == 0 && _draggingStart is not null && _draggingEnd is not null )
149
182
{
150
183
if ( _showNewAppointment )
151
184
{
152
185
_showNewAppointment = false ;
153
- await OnAddingNewAppointment ? . Invoke ( _newAppointmentStart , _newAppointmentEnd ) ;
186
+ if ( OnAddingNewAppointment is not null )
187
+ await OnAddingNewAppointment . Invoke ( _draggingStart . Value , _draggingEnd . Value ) ;
188
+
189
+ StateHasChanged ( ) ;
190
+ }
191
+
192
+ if ( _reschedulingAppointment is not null )
193
+ {
194
+ var tempApp = _reschedulingAppointment ;
195
+ _reschedulingAppointment = null ;
196
+
197
+ if ( tempApp . OnReschedule is not null )
198
+ await tempApp . OnReschedule . Invoke ( _draggingStart . Value , _draggingEnd . Value ) ;
199
+ tempApp . IsVisible = true ;
200
+
154
201
StateHasChanged ( ) ;
155
202
}
156
203
}
@@ -159,10 +206,23 @@ public async Task OnMouseUp(int button)
159
206
[ JSInvokable ]
160
207
public void OnMouseMove ( string date )
161
208
{
162
- if ( _showNewAppointment )
209
+ if ( _showNewAppointment && _draggingAppointmentAnchor is not null )
163
210
{
164
211
var day = DateTime . ParseExact ( date , "yyyyMMdd" , null ) ;
165
- ( _newAppointmentStart , _newAppointmentEnd ) = day < _draggingAppointmentAnchor ? ( day , _draggingAppointmentAnchor ) : ( _draggingAppointmentAnchor , day ) ;
212
+ ( _draggingStart , _draggingEnd ) = day < _draggingAppointmentAnchor ? ( day , _draggingAppointmentAnchor . Value ) : ( _draggingAppointmentAnchor . Value , day ) ;
213
+ StateHasChanged ( ) ;
214
+ }
215
+
216
+ if ( _reschedulingAppointment is not null )
217
+ {
218
+ var day = DateTime . ParseExact ( date , "yyyyMMdd" , null ) ;
219
+ _draggingAppointmentAnchor ??= day ;
220
+
221
+ var diff = ( day - _draggingAppointmentAnchor . Value ) . Days ;
222
+
223
+ _draggingStart = _reschedulingAppointment . Start . AddDays ( diff ) ;
224
+ _draggingEnd = _reschedulingAppointment . End . AddDays ( diff ) ;
225
+
166
226
StateHasChanged ( ) ;
167
227
}
168
228
}
0 commit comments