52bf303537
This commit introduces functionality in the MeetingSchedule feature to manage student exclusions during scheduling. The Index.razor component has been updated to include methods for saving and loading excluded students, as well as UI elements for toggling exclusions. Additionally, the TeamScheduler logic has been modified to account for excluded students when calculating overlaps and scheduling teams. These changes improve the flexibility and accuracy of the scheduling process, enhancing the overall user experience.
208 lines
6.4 KiB
C#
208 lines
6.4 KiB
C#
using System.Text.Json;
|
|
using Microsoft.JSInterop;
|
|
|
|
namespace WebApp;
|
|
|
|
/// <summary>
|
|
/// Service for managing browser localStorage with type-safe methods.
|
|
/// </summary>
|
|
public sealed class LocalStorageService
|
|
{
|
|
private readonly IJSRuntime _jsRuntime;
|
|
private readonly ILogger<LocalStorageService> _logger;
|
|
|
|
public LocalStorageService(IJSRuntime jsRuntime, ILogger<LocalStorageService> logger)
|
|
{
|
|
_jsRuntime = jsRuntime;
|
|
_logger = logger;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets a boolean value from localStorage.
|
|
/// </summary>
|
|
/// <param name="key">The storage key.</param>
|
|
/// <param name="defaultValue">Default value if key doesn't exist or parsing fails.</param>
|
|
/// <returns>The stored boolean value or default value.</returns>
|
|
public async Task<bool> GetBoolAsync(string key, bool defaultValue = false)
|
|
{
|
|
try
|
|
{
|
|
var value = await _jsRuntime.InvokeAsync<string?>("localStorage.getItem", key);
|
|
return value != null && bool.TryParse(value, out var result) ? result : defaultValue;
|
|
}
|
|
catch
|
|
{
|
|
return defaultValue;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Sets a boolean value in localStorage.
|
|
/// </summary>
|
|
/// <param name="key">The storage key.</param>
|
|
/// <param name="value">The boolean value to store.</param>
|
|
public async Task SetBoolAsync(string key, bool value)
|
|
{
|
|
try
|
|
{
|
|
await _jsRuntime.InvokeVoidAsync("localStorage.setItem", key, value.ToString());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogWarning(ex, "Failed to save boolean to localStorage [{Key}]", key);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets an integer value from localStorage.
|
|
/// </summary>
|
|
/// <param name="key">The storage key.</param>
|
|
/// <param name="defaultValue">Default value if key doesn't exist or parsing fails.</param>
|
|
/// <returns>The stored integer value or default value.</returns>
|
|
public async Task<int> GetIntAsync(string key, int defaultValue = 0)
|
|
{
|
|
try
|
|
{
|
|
var value = await _jsRuntime.InvokeAsync<string?>("localStorage.getItem", key);
|
|
return value != null && int.TryParse(value, out var result) ? result : defaultValue;
|
|
}
|
|
catch
|
|
{
|
|
return defaultValue;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Sets an integer value in localStorage.
|
|
/// </summary>
|
|
/// <param name="key">The storage key.</param>
|
|
/// <param name="value">The integer value to store.</param>
|
|
public async Task SetIntAsync(string key, int value)
|
|
{
|
|
try
|
|
{
|
|
await _jsRuntime.InvokeVoidAsync("localStorage.setItem", key, value.ToString());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogWarning(ex, "Failed to save integer to localStorage [{Key}]", key);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets an array of integers from localStorage (stored as JSON).
|
|
/// </summary>
|
|
/// <param name="key">The storage key.</param>
|
|
/// <returns>Array of integers or empty array if not found.</returns>
|
|
public async Task<int[]> GetIntArrayAsync(string key)
|
|
{
|
|
try
|
|
{
|
|
var json = await _jsRuntime.InvokeAsync<string?>("localStorage.getItem", key);
|
|
if (!string.IsNullOrEmpty(json))
|
|
{
|
|
var array = JsonSerializer.Deserialize<int[]>(json);
|
|
return array ?? [];
|
|
}
|
|
return [];
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogWarning(ex, "Failed to load integer array from localStorage [{Key}]", key);
|
|
return [];
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Sets an array of integers in localStorage (stored as JSON).
|
|
/// </summary>
|
|
/// <param name="key">The storage key.</param>
|
|
/// <param name="values">The integer array to store.</param>
|
|
public async Task SetIntArrayAsync(string key, int[] values)
|
|
{
|
|
try
|
|
{
|
|
var json = JsonSerializer.Serialize(values);
|
|
await _jsRuntime.InvokeVoidAsync("localStorage.setItem", key, json);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogWarning(ex, "Failed to save integer array to localStorage [{Key}]", key);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Removes an item from localStorage.
|
|
/// </summary>
|
|
/// <param name="key">The storage key to remove.</param>
|
|
public async Task RemoveAsync(string key)
|
|
{
|
|
try
|
|
{
|
|
await _jsRuntime.InvokeVoidAsync("localStorage.removeItem", key);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogWarning(ex, "Failed to remove from localStorage [{Key}]", key);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets a JSON-serialized object from localStorage.
|
|
/// </summary>
|
|
/// <typeparam name="T">The type to deserialize to.</typeparam>
|
|
/// <param name="key">The storage key.</param>
|
|
/// <returns>The deserialized object or default value if not found.</returns>
|
|
public async Task<T?> GetJsonAsync<T>(string key)
|
|
{
|
|
try
|
|
{
|
|
var json = await _jsRuntime.InvokeAsync<string?>("localStorage.getItem", key);
|
|
if (!string.IsNullOrEmpty(json))
|
|
{
|
|
return JsonSerializer.Deserialize<T>(json);
|
|
}
|
|
return default;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogWarning(ex, "Failed to load JSON from localStorage [{Key}]", key);
|
|
return default;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Sets a JSON-serialized object in localStorage.
|
|
/// </summary>
|
|
/// <typeparam name="T">The type to serialize.</typeparam>
|
|
/// <param name="key">The storage key.</param>
|
|
/// <param name="value">The object to store.</param>
|
|
public async Task SetJsonAsync<T>(string key, T value)
|
|
{
|
|
try
|
|
{
|
|
var json = JsonSerializer.Serialize(value);
|
|
await _jsRuntime.InvokeVoidAsync("localStorage.setItem", key, json);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogWarning(ex, "Failed to save JSON to localStorage [{Key}]", key);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Clears all items from localStorage.
|
|
/// </summary>
|
|
public async Task ClearAsync()
|
|
{
|
|
try
|
|
{
|
|
await _jsRuntime.InvokeVoidAsync("localStorage.clear");
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogWarning(ex, "Failed to clear localStorage");
|
|
}
|
|
}
|
|
}
|