optimize
This commit is contained in:
parent
419dd4453f
commit
f3389936b5
4 changed files with 33 additions and 38 deletions
|
|
@ -7,20 +7,10 @@
|
||||||
<button class="btn month-btn @(_isCurrentMonth ? "" : "selected")" @onclick="SelectNextMonth" disabled="@_isLoadingInitial">@MonthAndYear.NextMonthName</button>
|
<button class="btn month-btn @(_isCurrentMonth ? "" : "selected")" @onclick="SelectNextMonth" disabled="@_isLoadingInitial">@MonthAndYear.NextMonthName</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="action-buttons">
|
<div class="action-buttons">
|
||||||
<button class="btn export-btn" @onclick="ExportToIcs" disabled="@_isLoadingInitial"><span class="oi oi-calendar" aria-hidden="true"></span> Export to ICS</button>
|
<button class="btn export-btn" @onclick="ExportToIcs" disabled="@(_isLoadingInitial || _isSyncing)"><span class="oi oi-calendar" aria-hidden="true"></span> Export to ICS</button>
|
||||||
<button class="btn export-btn" @onclick="SyncToGoogleCalendar" disabled="@(_isLoadingInitial || _isSyncing)">
|
<button class="btn export-btn" @onclick="SyncToGoogleCalendar" disabled="@(_isLoadingInitial || _isSyncing)"><span class="oi oi-cloud-upload" aria-hidden="true"></span> Sync to Google Calendar</button>
|
||||||
@if (_isSyncing)
|
<button class="btn export-btn" @onclick="ExportToPdf" disabled="@(_isLoadingInitial || _isSyncing)"><span class="oi oi-document" aria-hidden="true"></span>Export to PDF</button>
|
||||||
{
|
<button class="btn config-btn" @onclick="ShowConfiguration" disabled="@(_isLoadingInitial || _isSyncing)"><span class="oi oi-cog" aria-hidden="true"></span> Configuration</button>
|
||||||
<span class="loading-spinner">⏳</span>
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
<span class="oi oi-cloud-upload" aria-hidden="true"></span>
|
|
||||||
}
|
|
||||||
Sync to Google Calendar
|
|
||||||
</button>
|
|
||||||
<button class="btn export-btn" @onclick="ExportToPdf" disabled="@_isLoadingInitial"><span class="oi oi-document" aria-hidden="true"></span>Export to PDF</button>
|
|
||||||
<button class="btn config-btn" @onclick="ShowConfiguration" disabled="@_isLoadingInitial"><span class="oi oi-cog" aria-hidden="true"></span> Configuration</button>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
@ -92,6 +82,15 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
else if (_isSyncing)
|
||||||
|
{
|
||||||
|
<div class="loading-overlay">
|
||||||
|
<div class="loading-content">
|
||||||
|
<div class="loading-spinner">⏳</div>
|
||||||
|
<p>Syncing with google calendar...</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ namespace ShiftScheduler.Services
|
||||||
{
|
{
|
||||||
public interface IConfigurationService
|
public interface IConfigurationService
|
||||||
{
|
{
|
||||||
|
string GetTimeZone();
|
||||||
ApplicationConfiguration GetConfiguration();
|
ApplicationConfiguration GetConfiguration();
|
||||||
void UpdateConfiguration(ApplicationConfiguration configuration);
|
void UpdateConfiguration(ApplicationConfiguration configuration);
|
||||||
Task<string> ExportConfigurationAsync();
|
Task<string> ExportConfigurationAsync();
|
||||||
|
|
@ -29,7 +30,12 @@ namespace ShiftScheduler.Services
|
||||||
private readonly string _shiftsFilePath;
|
private readonly string _shiftsFilePath;
|
||||||
private readonly string _transportFilePath;
|
private readonly string _transportFilePath;
|
||||||
|
|
||||||
readonly TimeZoneInfo localTimeZone = TimeZoneInfo.FindSystemTimeZoneById("Europe/Zurich");
|
private readonly TimeZoneInfo localTimeZone = TimeZoneInfo.FindSystemTimeZoneById("Europe/Zurich");
|
||||||
|
|
||||||
|
public string GetTimeZone()
|
||||||
|
{
|
||||||
|
return localTimeZone.Id;
|
||||||
|
}
|
||||||
|
|
||||||
public ConfigurationService(ApplicationConfiguration initialConfiguration)
|
public ConfigurationService(ApplicationConfiguration initialConfiguration)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,6 @@ using Google.Apis.Services;
|
||||||
using Microsoft.AspNetCore.Authentication;
|
using Microsoft.AspNetCore.Authentication;
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
using ShiftScheduler.Shared;
|
using ShiftScheduler.Shared;
|
||||||
using System.Net;
|
|
||||||
|
|
||||||
namespace ShiftScheduler.Services;
|
namespace ShiftScheduler.Services;
|
||||||
|
|
||||||
|
|
@ -15,17 +14,9 @@ public interface IGoogleCalendarService
|
||||||
Task SyncShiftsToCalendarAsync(string calendarId, List<ShiftWithTransport> shifts);
|
Task SyncShiftsToCalendarAsync(string calendarId, List<ShiftWithTransport> shifts);
|
||||||
}
|
}
|
||||||
|
|
||||||
public class GoogleCalendarService : IGoogleCalendarService
|
public class GoogleCalendarService(IHttpContextAccessor httpContextAccessor, IConfigurationService configurationService)
|
||||||
|
: IGoogleCalendarService
|
||||||
{
|
{
|
||||||
private readonly IHttpContextAccessor _httpContextAccessor;
|
|
||||||
private readonly IcsExportService _icsExportService;
|
|
||||||
|
|
||||||
public GoogleCalendarService(IHttpContextAccessor httpContextAccessor, IcsExportService icsExportService)
|
|
||||||
{
|
|
||||||
_httpContextAccessor = httpContextAccessor;
|
|
||||||
_icsExportService = icsExportService;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<List<CalendarListEntry>> GetCalendarsAsync()
|
public async Task<List<CalendarListEntry>> GetCalendarsAsync()
|
||||||
{
|
{
|
||||||
var service = await CreateCalendarServiceAsync();
|
var service = await CreateCalendarServiceAsync();
|
||||||
|
|
@ -110,25 +101,25 @@ public class GoogleCalendarService : IGoogleCalendarService
|
||||||
// Create morning event if it exists
|
// Create morning event if it exists
|
||||||
if (!string.IsNullOrEmpty(shift.MorningTime))
|
if (!string.IsNullOrEmpty(shift.MorningTime))
|
||||||
{
|
{
|
||||||
var morningEvent = CreateEventFromShift(shift, date, shift.MorningTime, "Morning", shiftWithTransport.MorningTransport);
|
var morningEvent = CreateEventFromShift(shift, date, shift.MorningTime, shiftWithTransport.MorningTransport);
|
||||||
await ExecuteWithRetryAsync(async () => await service.Events.Insert(morningEvent, calendarId).ExecuteAsync());
|
await ExecuteWithRetryAsync(async () => await service.Events.Insert(morningEvent, calendarId).ExecuteAsync());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create afternoon event if it exists
|
// Create afternoon event if it exists
|
||||||
if (!string.IsNullOrEmpty(shift.AfternoonTime))
|
if (!string.IsNullOrEmpty(shift.AfternoonTime))
|
||||||
{
|
{
|
||||||
var afternoonEvent = CreateEventFromShift(shift, date, shift.AfternoonTime, "Afternoon", shiftWithTransport.AfternoonTransport);
|
var afternoonEvent = CreateEventFromShift(shift, date, shift.AfternoonTime, shiftWithTransport.AfternoonTransport);
|
||||||
await ExecuteWithRetryAsync(async () => await service.Events.Insert(afternoonEvent, calendarId).ExecuteAsync());
|
await ExecuteWithRetryAsync(async () => await service.Events.Insert(afternoonEvent, calendarId).ExecuteAsync());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Event CreateEventFromShift(Shift shift, DateTime date, string timeRange, string period, TransportConnection? transport)
|
private Event CreateEventFromShift(Shift shift, DateTime date, string timeRange, TransportConnection? transport)
|
||||||
{
|
{
|
||||||
var times = timeRange.Split('-');
|
var times = timeRange.Split('-');
|
||||||
var startTime = date.Add(TimeSpan.Parse(times[0]));
|
var startTime = date.Add(TimeSpan.Parse(times[0]));
|
||||||
var endTime = date.Add(TimeSpan.Parse(times[1]));
|
var endTime = date.Add(TimeSpan.Parse(times[1]));
|
||||||
|
|
||||||
var summary = $"{shift.Name} ({period})";
|
var summary = $"{shift.Name}";
|
||||||
var description = "";
|
var description = "";
|
||||||
|
|
||||||
if (transport != null)
|
if (transport != null)
|
||||||
|
|
@ -144,20 +135,19 @@ public class GoogleCalendarService : IGoogleCalendarService
|
||||||
Start = new EventDateTime
|
Start = new EventDateTime
|
||||||
{
|
{
|
||||||
DateTimeDateTimeOffset = startTime,
|
DateTimeDateTimeOffset = startTime,
|
||||||
TimeZone = "Europe/Zurich"
|
TimeZone = configurationService.GetTimeZone()
|
||||||
},
|
},
|
||||||
End = new EventDateTime
|
End = new EventDateTime
|
||||||
{
|
{
|
||||||
DateTimeDateTimeOffset = endTime,
|
DateTimeDateTimeOffset = endTime,
|
||||||
TimeZone = "Europe/Zurich"
|
TimeZone = configurationService.GetTimeZone()
|
||||||
},
|
},
|
||||||
ExtendedProperties = new Event.ExtendedPropertiesData
|
ExtendedProperties = new Event.ExtendedPropertiesData
|
||||||
{
|
{
|
||||||
Private__ = new Dictionary<string, string>
|
Private__ = new Dictionary<string, string>
|
||||||
{
|
{
|
||||||
["shiftSchedulerEvent"] = "true",
|
["shiftSchedulerEvent"] = "true",
|
||||||
["shiftName"] = shift.Name,
|
["shiftName"] = shift.Name
|
||||||
["period"] = period.ToLower()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -167,12 +157,12 @@ public class GoogleCalendarService : IGoogleCalendarService
|
||||||
{
|
{
|
||||||
var departure = transport.DepartureTime.ToString("HH:mm");
|
var departure = transport.DepartureTime.ToString("HH:mm");
|
||||||
var arrival = transport.ArrivalTime.ToString("HH:mm");
|
var arrival = transport.ArrivalTime.ToString("HH:mm");
|
||||||
return $"{departure} → {arrival}";
|
return $"{transport.Platform}: {departure} → {arrival} ({transport.Duration.TotalMinutes} Minutes)";
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<CalendarService> CreateCalendarServiceAsync()
|
private async Task<CalendarService> CreateCalendarServiceAsync()
|
||||||
{
|
{
|
||||||
var httpContext = _httpContextAccessor.HttpContext ?? throw new InvalidOperationException("No HTTP context available");
|
var httpContext = httpContextAccessor.HttpContext ?? throw new InvalidOperationException("No HTTP context available");
|
||||||
|
|
||||||
var accessToken = await httpContext.GetTokenAsync("access_token");
|
var accessToken = await httpContext.GetTokenAsync("access_token");
|
||||||
if (string.IsNullOrEmpty(accessToken))
|
if (string.IsNullOrEmpty(accessToken))
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ namespace ShiftScheduler.Services
|
||||||
if (!string.IsNullOrEmpty(shift.MorningTime))
|
if (!string.IsNullOrEmpty(shift.MorningTime))
|
||||||
{
|
{
|
||||||
var times = shift.MorningTime.Split('-');
|
var times = shift.MorningTime.Split('-');
|
||||||
var summary = $"{shift.Name} (Morning)";
|
var summary = $"{shift.Name}";
|
||||||
var description = "";
|
var description = "";
|
||||||
|
|
||||||
if (shiftWithTransport.MorningTransport != null)
|
if (shiftWithTransport.MorningTransport != null)
|
||||||
|
|
@ -44,7 +44,7 @@ namespace ShiftScheduler.Services
|
||||||
if (!string.IsNullOrEmpty(shift.AfternoonTime))
|
if (!string.IsNullOrEmpty(shift.AfternoonTime))
|
||||||
{
|
{
|
||||||
var times = shift.AfternoonTime.Split('-');
|
var times = shift.AfternoonTime.Split('-');
|
||||||
var summary = $"{shift.Name} (Afternoon)";
|
var summary = $"{shift.Name}";
|
||||||
var description = "";
|
var description = "";
|
||||||
|
|
||||||
if (shiftWithTransport.AfternoonTransport != null)
|
if (shiftWithTransport.AfternoonTransport != null)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue