Vario
This commit is contained in:
@@ -8,35 +8,59 @@
|
|||||||
@inject IManageDataService ManageData
|
@inject IManageDataService ManageData
|
||||||
@inject IJSRuntime JS
|
@inject IJSRuntime JS
|
||||||
|
|
||||||
|
<HeaderLayout Title="@_headerTitle"
|
||||||
|
ShowFilter="true"
|
||||||
|
ShowCalendarToggle="true"
|
||||||
|
OnFilterToggle="ToggleFilter"
|
||||||
|
OnCalendarToggle="ToggleExpanded"/>
|
||||||
|
|
||||||
<HeaderLayout Title="@CurrentMonth.ToString("MMMM yyyy", new System.Globalization.CultureInfo("it-IT")).FirstCharToUpper()"
|
<div @ref="weekSliderRef" class="container week-slider @(Expanded ? "expanded" : "") @(SliderAnimation)">
|
||||||
ShowFilter="true"
|
@if (Expanded)
|
||||||
ShowCalendarToggle="true"
|
{
|
||||||
OnFilterToggle="ToggleFilter"
|
<!-- Vista mensile -->
|
||||||
OnCalendarToggle="ToggleExpanded" />
|
@foreach (var nomeGiorno in GiorniSettimana)
|
||||||
|
|
||||||
<div @ref="weekSliderRef" class="container week-slider @(Expanded ? "expanded" : "") @(SliderAnimation)">
|
|
||||||
@if (Expanded)
|
|
||||||
{
|
{
|
||||||
<!-- Vista mensile -->
|
<div class="week-day">
|
||||||
@foreach (var nomeGiorno in GiorniSettimana)
|
<div>@nomeGiorno</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
|
||||||
|
@foreach (var unused in Enumerable.Range(0, StartOffset))
|
||||||
|
{
|
||||||
|
<div class="day" style="visibility: hidden"></div>
|
||||||
|
}
|
||||||
|
|
||||||
|
@if (_isInitialized && _monthDaysData.Length > 0)
|
||||||
|
{
|
||||||
|
@for (var d = 1; d <= DaysInMonth; d++)
|
||||||
{
|
{
|
||||||
<div class="week-day">
|
var day = new DateTime(CurrentMonth.Year, CurrentMonth.Month, d);
|
||||||
<div>@nomeGiorno</div>
|
var dayData = _monthDaysData[d - 1];
|
||||||
|
|
||||||
|
<div class="day @dayData.CssClass"
|
||||||
|
@onclick="() => SelezionaDataDalMese(day)">
|
||||||
|
<div>@d</div>
|
||||||
|
@if (dayData.HasEvents)
|
||||||
|
{
|
||||||
|
<div class="event-dot-container" style="margin-top: 2px;">
|
||||||
|
@foreach (var cat in dayData.EventCategories)
|
||||||
|
{
|
||||||
|
<div class="event-dot @cat.CssClass" title="@cat.Title"></div>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
}
|
||||||
@foreach (var unused in Enumerable.Range(0, StartOffset))
|
else
|
||||||
{
|
{
|
||||||
<div class="day" style="visibility: hidden"></div>
|
@* Fallback rendering per prima inizializzazione *@
|
||||||
}
|
|
||||||
|
|
||||||
@for (var d = 1; d <= DaysInMonth; d++)
|
@for (var d = 1; d <= DaysInMonth; d++)
|
||||||
{
|
{
|
||||||
var day = new DateTime(CurrentMonth.Year, CurrentMonth.Month, d);
|
var day = new DateTime(CurrentMonth.Year, CurrentMonth.Month, d);
|
||||||
var isSelected = IsSameDay(day, SelectedDate);
|
var isSelected = IsSameDay(day, SelectedDate);
|
||||||
var isToday = IsSameDay(day, DateTime.Today);
|
var isToday = IsSameDay(day, DateTime.Today);
|
||||||
var events = ReturnFilteredActivity(day);
|
var events = GetEventsForDay(day);
|
||||||
|
|
||||||
<div class="day @(isSelected ? "selected" : (isToday ? "today" : ""))"
|
<div class="day @(isSelected ? "selected" : (isToday ? "today" : ""))"
|
||||||
@onclick="() => SelezionaDataDalMese(day)">
|
@onclick="() => SelezionaDataDalMese(day)">
|
||||||
@@ -52,29 +76,64 @@
|
|||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@foreach (var unused in Enumerable.Range(0, EndOffset))
|
@foreach (var unused in Enumerable.Range(0, EndOffset))
|
||||||
|
{
|
||||||
|
<div class="day" style="visibility: hidden"></div>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<!-- Vista settimanale -->
|
||||||
|
@if (_isInitialized && _weekDaysData.Length == 7 && _weekDaysData[0].Date != default)
|
||||||
|
{
|
||||||
|
@for (int i = 0; i < 7; i++)
|
||||||
{
|
{
|
||||||
<div class="day" style="visibility: hidden"></div>
|
var dayData = _weekDaysData[i];
|
||||||
|
var day = dayData.Date;
|
||||||
|
|
||||||
|
<div class="week-day">
|
||||||
|
<div>@dayData.DayName</div>
|
||||||
|
<div class="day @dayData.CssClass"
|
||||||
|
@onclick="() => SelezionaData(day)">
|
||||||
|
<div>@day.Day</div>
|
||||||
|
@if (dayData.HasEvents)
|
||||||
|
{
|
||||||
|
<div class="event-dot-container" style="margin-top: 2px;">
|
||||||
|
@foreach (var cat in dayData.EventCategories)
|
||||||
|
{
|
||||||
|
<div class="event-dot @cat.CssClass" title="@cat.Title"></div>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
<!-- Vista settimanale -->
|
var start = GetStartOfWeek(SelectedDate);
|
||||||
@foreach (var day in DaysOfWeek)
|
var culture = new System.Globalization.CultureInfo("it-IT");
|
||||||
|
|
||||||
|
|
||||||
|
for (var i = 0; i < 7; i++)
|
||||||
{
|
{
|
||||||
|
var day = start.AddDays(i);
|
||||||
var isSelected = IsSameDay(day, SelectedDate);
|
var isSelected = IsSameDay(day, SelectedDate);
|
||||||
var isToday = IsSameDay(day, DateTime.Today);
|
var isToday = IsSameDay(day, DateTime.Today);
|
||||||
|
var events = GetEventsForDay(day);
|
||||||
|
|
||||||
<div class="week-day">
|
<div class="week-day">
|
||||||
<div>@day.ToString("ddd", new System.Globalization.CultureInfo("it-IT"))</div>
|
<div>@day.ToString("ddd", culture)</div>
|
||||||
<div class="day @(isSelected ? "selected" : (isToday ? "today" : ""))"
|
<div class="day @(isSelected ? "selected" : (isToday ? "today" : ""))"
|
||||||
@onclick="() => SelezionaData(day)">
|
@onclick="() => SelezionaData(day)"
|
||||||
|
aria-label="@day.ToString("dddd d MMMM", culture)">
|
||||||
<div>@day.Day</div>
|
<div>@day.Day</div>
|
||||||
@if (ReturnFilteredActivity(day).Any())
|
@if (events.Any())
|
||||||
{
|
{
|
||||||
<div class="event-dot-container" style="margin-top: 2px;">
|
<div class="event-dot-container" style="margin-top: 2px;">
|
||||||
@foreach (var cat in ReturnFilteredActivity(day).Select(x => x.Category).Distinct())
|
@foreach (var cat in events.Select(x => x.Category).Distinct())
|
||||||
{
|
{
|
||||||
<div class="event-dot @cat.ConvertToHumanReadable()" title="@cat.ConvertToHumanReadable()"></div>
|
<div class="event-dot @cat.ConvertToHumanReadable()" title="@cat.ConvertToHumanReadable()"></div>
|
||||||
}
|
}
|
||||||
@@ -84,22 +143,23 @@
|
|||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</div>
|
}
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="container appointments">
|
<div class="container appointments">
|
||||||
@if (IsLoading)
|
@if (IsLoading)
|
||||||
{
|
{
|
||||||
<SpinnerLayout FullScreen="false" />
|
<SpinnerLayout FullScreen="false"/>
|
||||||
}
|
}
|
||||||
else if (FilteredActivities is { Count: > 0 })
|
else if (FilteredActivities is { Count: > 0 })
|
||||||
{
|
{
|
||||||
<Virtualize Items="FilteredActivities" Context="activity">
|
<Virtualize Items="FilteredActivities" Context="activity">
|
||||||
<ActivityCard Activity="activity" ActivityChanged="OnActivityChanged" />
|
<ActivityCard Activity="activity" ActivityChanged="OnActivityChanged"/>
|
||||||
</Virtualize>
|
</Virtualize>
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
<NoDataAvailable Text="Nessuna attività trovata" ImageSource="_content/Template.Shared/images/undraw_file-search_cbur.svg" />
|
<NoDataAvailable Text="Nessuna attività trovata" ImageSource="_content/Template.Shared/images/undraw_file-search_cbur.svg"/>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -107,6 +167,19 @@
|
|||||||
|
|
||||||
@code {
|
@code {
|
||||||
|
|
||||||
|
// Modelli per ottimizzazione rendering
|
||||||
|
private record DayData(DateTime Date, string CssClass, bool HasEvents, CategoryData[] EventCategories, string DayName = "");
|
||||||
|
|
||||||
|
private record CategoryData(string CssClass, string Title);
|
||||||
|
|
||||||
|
// Cache per rendering
|
||||||
|
private DayData[] _monthDaysData = Array.Empty<DayData>();
|
||||||
|
private DayData[] _weekDaysData = new DayData[7];
|
||||||
|
private string _headerTitle = string.Empty;
|
||||||
|
private Dictionary<DateTime, List<ActivityDTO>> _eventsCache = new();
|
||||||
|
private Dictionary<DateTime, CategoryData[]> _categoriesCache = new();
|
||||||
|
private bool _isInitialized = false;
|
||||||
|
|
||||||
// Stato UI
|
// Stato UI
|
||||||
private bool Expanded { get; set; } = false;
|
private bool Expanded { get; set; } = false;
|
||||||
private string SliderAnimation { get; set; } = string.Empty;
|
private string SliderAnimation { get; set; } = string.Empty;
|
||||||
@@ -141,16 +214,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Supporto rendering settimana
|
|
||||||
private IEnumerable<DateTime> DaysOfWeek
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
var start = GetStartOfWeek(SelectedDate);
|
|
||||||
return Enumerable.Range(0, 7).Select(i => start.AddDays(i));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override async Task OnAfterRenderAsync(bool firstRender)
|
protected override async Task OnAfterRenderAsync(bool firstRender)
|
||||||
{
|
{
|
||||||
if (firstRender)
|
if (firstRender)
|
||||||
@@ -162,17 +225,141 @@
|
|||||||
_internalMonth = new DateTime(SelectedDate.Year, SelectedDate.Month, 1);
|
_internalMonth = new DateTime(SelectedDate.Year, SelectedDate.Month, 1);
|
||||||
await LoadMonthData();
|
await LoadMonthData();
|
||||||
|
|
||||||
if (!Expanded)
|
PrepareRenderingData();
|
||||||
ApplyFilter();
|
_isInitialized = true;
|
||||||
|
ApplyFilter();
|
||||||
StateHasChanged();
|
StateHasChanged();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Metodo per preparare i dati di rendering una sola volta
|
||||||
|
private void PrepareRenderingData()
|
||||||
|
{
|
||||||
|
PrepareHeaderTitle();
|
||||||
|
PrepareEventsCache();
|
||||||
|
|
||||||
|
if (Expanded)
|
||||||
|
{
|
||||||
|
PrepareMonthDaysData();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PrepareWeekDaysData();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void PrepareHeaderTitle()
|
||||||
|
{
|
||||||
|
_headerTitle = CurrentMonth.ToString("MMMM yyyy", new System.Globalization.CultureInfo("it-IT")).FirstCharToUpper();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void PrepareEventsCache()
|
||||||
|
{
|
||||||
|
_eventsCache.Clear();
|
||||||
|
_categoriesCache.Clear();
|
||||||
|
|
||||||
|
// Raggruppa le attività per data
|
||||||
|
var activitiesByDate = MonthActivities
|
||||||
|
.GroupBy(x => (x.EffectiveDate ?? x.EstimatedDate!).Value.Date)
|
||||||
|
.ToDictionary(g => g.Key, g => g.ToList());
|
||||||
|
|
||||||
|
foreach (var (date, activities) in activitiesByDate)
|
||||||
|
{
|
||||||
|
_eventsCache[date] = activities;
|
||||||
|
|
||||||
|
// Pre-calcola le categorie per ogni giorno
|
||||||
|
var categories = activities
|
||||||
|
.Select(x => x.Category)
|
||||||
|
.Distinct()
|
||||||
|
.Select(cat => new CategoryData(cat.ConvertToHumanReadable(), cat.ConvertToHumanReadable()))
|
||||||
|
.ToArray();
|
||||||
|
|
||||||
|
_categoriesCache[date] = categories;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void PrepareMonthDaysData()
|
||||||
|
{
|
||||||
|
_monthDaysData = new DayData[DaysInMonth];
|
||||||
|
var today = DateTime.Today;
|
||||||
|
|
||||||
|
for (int d = 1; d <= DaysInMonth; d++)
|
||||||
|
{
|
||||||
|
var day = new DateTime(CurrentMonth.Year, CurrentMonth.Month, d);
|
||||||
|
var isSelected = day.Date == SelectedDate.Date;
|
||||||
|
var isToday = day.Date == today;
|
||||||
|
|
||||||
|
var cssClass = isSelected ? "selected" : (isToday ? "today" : "");
|
||||||
|
var hasEvents = _eventsCache.ContainsKey(day.Date);
|
||||||
|
var eventCategories = hasEvents ? GetFilteredCategoriesForDay(day.Date) : Array.Empty<CategoryData>();
|
||||||
|
|
||||||
|
_monthDaysData[d - 1] = new DayData(day, cssClass, eventCategories.Length > 0, eventCategories);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void PrepareWeekDaysData()
|
||||||
|
{
|
||||||
|
var start = GetStartOfWeek(SelectedDate);
|
||||||
|
var today = DateTime.Today;
|
||||||
|
var culture = new System.Globalization.CultureInfo("it-IT");
|
||||||
|
|
||||||
|
for (int i = 0; i < 7; i++)
|
||||||
|
{
|
||||||
|
var day = start.AddDays(i);
|
||||||
|
var isSelected = day.Date == SelectedDate.Date;
|
||||||
|
var isToday = day.Date == today;
|
||||||
|
|
||||||
|
var cssClass = isSelected ? "selected" : (isToday ? "today" : "");
|
||||||
|
var dayName = day.ToString("ddd", culture);
|
||||||
|
var hasEvents = _eventsCache.ContainsKey(day.Date);
|
||||||
|
var eventCategories = hasEvents ? GetFilteredCategoriesForDay(day.Date) : Array.Empty<CategoryData>();
|
||||||
|
|
||||||
|
_weekDaysData[i] = new DayData(day, cssClass, eventCategories.Length > 0, eventCategories, dayName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private CategoryData[] GetFilteredCategoriesForDay(DateTime date)
|
||||||
|
{
|
||||||
|
if (!_categoriesCache.TryGetValue(date, out var categories))
|
||||||
|
return Array.Empty<CategoryData>();
|
||||||
|
|
||||||
|
if (Filter.ClearFilter)
|
||||||
|
return categories;
|
||||||
|
|
||||||
|
// Applica i filtri alle categorie
|
||||||
|
var filteredActivities = GetFilteredActivitiesForDay(date);
|
||||||
|
if (!filteredActivities.Any())
|
||||||
|
return Array.Empty<CategoryData>();
|
||||||
|
|
||||||
|
return filteredActivities
|
||||||
|
.Select(x => x.Category)
|
||||||
|
.Distinct()
|
||||||
|
.Select(cat => new CategoryData(cat.ConvertToHumanReadable(), cat.ConvertToHumanReadable()))
|
||||||
|
.ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<ActivityDTO> GetFilteredActivitiesForDay(DateTime date)
|
||||||
|
{
|
||||||
|
if (!_eventsCache.TryGetValue(date, out var activities))
|
||||||
|
return new List<ActivityDTO>();
|
||||||
|
|
||||||
|
if (Filter.ClearFilter)
|
||||||
|
return activities;
|
||||||
|
|
||||||
|
return activities.Where(x =>
|
||||||
|
(!Filter.Text.IsNullOrEmpty() && x.ActivityDescription != null && x.ActivityDescription.ContainsIgnoreCase(Filter.Text!)) ||
|
||||||
|
(x.ActivityTypeId != null && !Filter.Type.IsNullOrEmpty() && x.ActivityTypeId.Equals(Filter.Type)) ||
|
||||||
|
(x.ActivityResultId != null && !Filter.Result.IsNullOrEmpty() && x.ActivityResultId.Equals(Filter.Result)) ||
|
||||||
|
(x.UserName != null && !Filter.User.IsNullOrEmpty() && Filter.User!.Contains(x.UserName)) ||
|
||||||
|
(Filter.Category != null && x.Category.Equals(Filter.Category))
|
||||||
|
).ToList();
|
||||||
|
}
|
||||||
|
|
||||||
[JSInvokable]
|
[JSInvokable]
|
||||||
public async Task OnSwipeLeft()
|
public async Task OnSwipeLeft()
|
||||||
{
|
{
|
||||||
await CambiaPeriodo(1);
|
await CambiaPeriodo(1);
|
||||||
|
PrepareRenderingData();
|
||||||
StateHasChanged();
|
StateHasChanged();
|
||||||
if (Expanded)
|
if (Expanded)
|
||||||
{
|
{
|
||||||
@@ -184,6 +371,7 @@
|
|||||||
public async Task OnSwipeRight()
|
public async Task OnSwipeRight()
|
||||||
{
|
{
|
||||||
await CambiaPeriodo(-1);
|
await CambiaPeriodo(-1);
|
||||||
|
PrepareRenderingData();
|
||||||
StateHasChanged();
|
StateHasChanged();
|
||||||
if (Expanded)
|
if (Expanded)
|
||||||
{
|
{
|
||||||
@@ -210,7 +398,6 @@
|
|||||||
{
|
{
|
||||||
if (Expanded)
|
if (Expanded)
|
||||||
{
|
{
|
||||||
// Cambio solo il mese visualizzato, NON cambiare SelectedDate
|
|
||||||
var y = CurrentMonth.Year;
|
var y = CurrentMonth.Year;
|
||||||
var m = CurrentMonth.Month + direzione;
|
var m = CurrentMonth.Month + direzione;
|
||||||
if (m < 1)
|
if (m < 1)
|
||||||
@@ -229,7 +416,6 @@
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Cambio settimana: aggiorno anche il giorno selezionato
|
|
||||||
await SelezionaData(SelectedDate.AddDays(7 * direzione));
|
await SelezionaData(SelectedDate.AddDays(7 * direzione));
|
||||||
_internalMonth = new DateTime(SelectedDate.Year, SelectedDate.Month, 1);
|
_internalMonth = new DateTime(SelectedDate.Year, SelectedDate.Month, 1);
|
||||||
}
|
}
|
||||||
@@ -241,16 +427,17 @@
|
|||||||
if (Expanded)
|
if (Expanded)
|
||||||
{
|
{
|
||||||
SliderAnimation = "collapse-animation";
|
SliderAnimation = "collapse-animation";
|
||||||
StateHasChanged();
|
|
||||||
Expanded = false;
|
Expanded = false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Expanded = true;
|
Expanded = true;
|
||||||
SliderAnimation = "expand-animation";
|
SliderAnimation = "expand-animation";
|
||||||
StateHasChanged();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PrepareRenderingData();
|
||||||
|
StateHasChanged();
|
||||||
|
|
||||||
SliderAnimation = "";
|
SliderAnimation = "";
|
||||||
StateHasChanged();
|
StateHasChanged();
|
||||||
}
|
}
|
||||||
@@ -261,7 +448,6 @@
|
|||||||
IsLoading = true;
|
IsLoading = true;
|
||||||
StateHasChanged();
|
StateHasChanged();
|
||||||
|
|
||||||
// Carica tutte le attività del mese corrente visualizzato
|
|
||||||
var start = CurrentMonth;
|
var start = CurrentMonth;
|
||||||
var end = start.AddDays(DaysInMonth - 1);
|
var end = start.AddDays(DaysInMonth - 1);
|
||||||
var activities = await ManageData.GetActivity(x =>
|
var activities = await ManageData.GetActivity(x =>
|
||||||
@@ -269,6 +455,7 @@
|
|||||||
(x.EffectiveDate >= start && x.EffectiveDate <= end));
|
(x.EffectiveDate >= start && x.EffectiveDate <= end));
|
||||||
MonthActivities = activities.OrderBy(x => x.EffectiveDate ?? x.EstimatedDate).ToList();
|
MonthActivities = activities.OrderBy(x => x.EffectiveDate ?? x.EstimatedDate).ToList();
|
||||||
|
|
||||||
|
PrepareRenderingData();
|
||||||
IsLoading = false;
|
IsLoading = false;
|
||||||
StateHasChanged();
|
StateHasChanged();
|
||||||
}
|
}
|
||||||
@@ -277,7 +464,6 @@
|
|||||||
private async Task SelezionaData(DateTime day)
|
private async Task SelezionaData(DateTime day)
|
||||||
{
|
{
|
||||||
SelectedDate = day;
|
SelectedDate = day;
|
||||||
StateHasChanged();
|
|
||||||
|
|
||||||
var cacheInternalMonth = _internalMonth;
|
var cacheInternalMonth = _internalMonth;
|
||||||
_internalMonth = new DateTime(day.Year, day.Month, 1);
|
_internalMonth = new DateTime(day.Year, day.Month, 1);
|
||||||
@@ -286,6 +472,10 @@
|
|||||||
{
|
{
|
||||||
await LoadMonthData();
|
await LoadMonthData();
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PrepareRenderingData();
|
||||||
|
}
|
||||||
|
|
||||||
ApplyFilter();
|
ApplyFilter();
|
||||||
StateHasChanged();
|
StateHasChanged();
|
||||||
@@ -295,12 +485,14 @@
|
|||||||
private async Task SelezionaDataDalMese(DateTime day)
|
private async Task SelezionaDataDalMese(DateTime day)
|
||||||
{
|
{
|
||||||
SelectedDate = day;
|
SelectedDate = day;
|
||||||
ApplyFilter();
|
|
||||||
// Chiudi la vista mese e passa alla settimana, con animazione
|
|
||||||
SliderAnimation = "collapse-animation";
|
SliderAnimation = "collapse-animation";
|
||||||
StateHasChanged();
|
|
||||||
Expanded = false;
|
Expanded = false;
|
||||||
_internalMonth = new DateTime(day.Year, day.Month, 1); // Sync il mese visualizzato
|
_internalMonth = new DateTime(day.Year, day.Month, 1);
|
||||||
|
|
||||||
|
PrepareRenderingData();
|
||||||
|
ApplyFilter();
|
||||||
|
StateHasChanged();
|
||||||
|
|
||||||
SliderAnimation = "";
|
SliderAnimation = "";
|
||||||
StateHasChanged();
|
StateHasChanged();
|
||||||
}
|
}
|
||||||
@@ -315,7 +507,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
private List<ActivityDTO> GetEventsForDay(DateTime day)
|
private List<ActivityDTO> GetEventsForDay(DateTime day)
|
||||||
=> MonthActivities?.Where(x => (x.EffectiveDate ?? x.EstimatedDate) == day.Date).ToList() ?? [];
|
=> _eventsCache.TryGetValue(day.Date, out var events) ? events : new List<ActivityDTO>();
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
@@ -330,6 +522,7 @@
|
|||||||
if (indexActivity != null && !newActivity.IsNullOrEmpty())
|
if (indexActivity != null && !newActivity.IsNullOrEmpty())
|
||||||
{
|
{
|
||||||
MonthActivities![indexActivity.Value] = newActivity[0];
|
MonthActivities![indexActivity.Value] = newActivity[0];
|
||||||
|
PrepareRenderingData(); // Ricalcola i dati di rendering
|
||||||
}
|
}
|
||||||
|
|
||||||
ApplyFilter();
|
ApplyFilter();
|
||||||
@@ -344,40 +537,25 @@
|
|||||||
|
|
||||||
private void ApplyFilter()
|
private void ApplyFilter()
|
||||||
{
|
{
|
||||||
FilteredActivities = GetEventsForDay(SelectedDate);
|
FilteredActivities = GetFilteredActivitiesForDay(SelectedDate);
|
||||||
|
|
||||||
if (!Filter.ClearFilter)
|
// Aggiorna i dati di rendering se il filtro è cambiato
|
||||||
|
if (Expanded)
|
||||||
{
|
{
|
||||||
FilteredActivities = GetEventsForDay(SelectedDate)?
|
PrepareMonthDaysData();
|
||||||
.Where(x =>
|
}
|
||||||
(!Filter.Text.IsNullOrEmpty() && x.ActivityDescription != null && x.ActivityDescription.ContainsIgnoreCase(Filter.Text!)) ||
|
else
|
||||||
(x.ActivityTypeId != null && !Filter.Type.IsNullOrEmpty() && x.ActivityTypeId.Equals(Filter.Type)) ||
|
{
|
||||||
(x.ActivityResultId != null && !Filter.Result.IsNullOrEmpty() && x.ActivityResultId.Equals(Filter.Result)) ||
|
PrepareWeekDaysData();
|
||||||
(x.UserName != null && !Filter.User.IsNullOrEmpty() && Filter.User!.Contains(x.UserName)) ||
|
|
||||||
(Filter.Category != null && x.Category.Equals(Filter.Category))
|
|
||||||
)
|
|
||||||
.ToList() ?? [];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
StateHasChanged();
|
StateHasChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Metodo ottimizzato per il rendering dei filtri
|
||||||
private List<ActivityDTO> ReturnFilteredActivity(DateTime day)
|
private List<ActivityDTO> ReturnFilteredActivity(DateTime day)
|
||||||
{
|
{
|
||||||
if (!Filter.ClearFilter)
|
return GetFilteredActivitiesForDay(day);
|
||||||
{
|
|
||||||
return GetEventsForDay(day)?
|
|
||||||
.Where(x =>
|
|
||||||
(!Filter.Text.IsNullOrEmpty() && x.ActivityDescription != null && x.ActivityDescription.ContainsIgnoreCase(Filter.Text!)) ||
|
|
||||||
(x.ActivityTypeId != null && !Filter.Type.IsNullOrEmpty() && x.ActivityTypeId.Equals(Filter.Type)) ||
|
|
||||||
(x.ActivityResultId != null && !Filter.Result.IsNullOrEmpty() && x.ActivityResultId.Equals(Filter.Result)) ||
|
|
||||||
(x.UserName != null && !Filter.User.IsNullOrEmpty() && Filter.User!.Contains(x.UserName)) ||
|
|
||||||
(Filter.Category != null && x.Category.Equals(Filter.Category))
|
|
||||||
)
|
|
||||||
.ToList() ?? [];
|
|
||||||
}
|
|
||||||
|
|
||||||
return GetEventsForDay(day);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -10,41 +10,34 @@
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
<div class="center-box container d-flex justify-content-center align-items-center min-vh-100">
|
<div class="login-page">
|
||||||
<div class="row rounded-4 bg-white">
|
<div class="container container-top-logo">
|
||||||
|
<span>SalesBook</span>
|
||||||
<div class="appName rounded-4 d-flex justify-content-center align-items-center flex-column">
|
</div>
|
||||||
<span>Nome App</span>
|
<div class="container container-login">
|
||||||
</div>
|
<div class="login-form-container">
|
||||||
|
<div class="input-group">
|
||||||
<div class="col-md-6 right-box">
|
<MudTextField @bind-Value="UserData.Username" Label="Username" Variant="Variant.Outlined"/>
|
||||||
<div class="row align-items-center">
|
</div>
|
||||||
<div class="input-group mb-2">
|
<div class="input-group">
|
||||||
<MudTextField @bind-Value="UserData.Username" Label="Username" Variant="Variant.Text"/>
|
<MudTextField InputType="@_passwordInput" @bind-Value="UserData.Password" Label="Password" Variant="Variant.Outlined" Adornment="Adornment.End" AdornmentIcon="@_passwordInputIcon" OnAdornmentClick="ShowPassword" AdornmentAriaLabel="Show Password" />
|
||||||
</div>
|
</div>
|
||||||
<div class="input-group mb-2">
|
<div class="input-group mb-2">
|
||||||
<MudTextField InputType="@_passwordInput" @bind-Value="UserData.Password" Label="Password" Variant="Variant.Text" Adornment="Adornment.End" AdornmentIcon="@_passwordInputIcon" OnAdornmentClick="ShowPassword" AdornmentAriaLabel="Show Password" />
|
<MudTextField @bind-Value="UserData.CodHash" Label="Profilo azienda" Variant="Variant.Outlined" />
|
||||||
</div>
|
|
||||||
<div class="input-group mb-4">
|
|
||||||
<MudTextField @bind-Value="UserData.CodHash" Label="Profilo azienda" Variant="Variant.Text"/>
|
|
||||||
</div>
|
|
||||||
<div class="input-group">
|
|
||||||
<div class="button-login" @onclick="SignInUser">
|
|
||||||
<span>Login</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="my-4 login-footer">
|
<MudButton OnClick="SignInUser" Color="Color.Primary" Variant="Variant.Filled">Login</MudButton>
|
||||||
<span>Powered by</span>
|
|
||||||
<img src="_content/Template.Shared/images/logoIntegry.svg" class="img-fluid" alt="Integry">
|
|
||||||
</div>
|
|
||||||
|
|
||||||
@if (_attemptFailed)
|
|
||||||
{
|
|
||||||
<MudAlert Class="my-3" Dense="true" Severity="Severity.Error" Variant="Variant.Filled">@ErrorMessage</MudAlert>
|
|
||||||
}
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="my-4 login-footer">
|
||||||
|
<span>Powered by</span>
|
||||||
|
<img src="_content/Template.Shared/images/logoIntegry.svg" class="img-fluid" alt="Integry">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
@if (_attemptFailed)
|
||||||
|
{
|
||||||
|
<MudAlert Class="my-3" Dense="true" Severity="Severity.Error" Variant="Variant.Filled">@ErrorMessage</MudAlert>
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,46 +1,44 @@
|
|||||||
.center-box {
|
.login-page {
|
||||||
margin-top: -1.1rem !important; /* remove page padding */
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
background: hsl(from var(--mud-palette-primary) h s 96%);
|
||||||
}
|
}
|
||||||
|
|
||||||
.box-area {
|
.container-top-logo > span {
|
||||||
width: 930px;
|
font-size: x-large;
|
||||||
}
|
|
||||||
|
|
||||||
.right-box {
|
|
||||||
padding: 15px 30px 0 30px;
|
|
||||||
}
|
|
||||||
|
|
||||||
::placeholder {
|
|
||||||
font-size: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.rounded-4 {
|
|
||||||
border-radius: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.rounded-5 {
|
|
||||||
border-radius: 30px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.bg-white {
|
|
||||||
background: var(--mud-palette-surface) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.appName {
|
|
||||||
margin-top: 15px;
|
|
||||||
font-size: large;
|
|
||||||
font-weight: 900;
|
font-weight: 900;
|
||||||
color: var(--mud-palette-primary)
|
color: var(--mud-palette-primary)
|
||||||
}
|
}
|
||||||
|
|
||||||
.button-login {
|
.container-login > span {
|
||||||
|
font-size: large;
|
||||||
|
font-weight: 900;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
background-color: var(--mud-palette-primary);
|
}
|
||||||
border-radius: 6px;
|
|
||||||
padding: .3rem 2rem;
|
.container-top-logo {
|
||||||
width: 100%;
|
height: 35vh;
|
||||||
font-weight: 700;
|
display: flex;
|
||||||
color: var(--mud-palette-appbar-text);
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-form-container {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container-login {
|
||||||
|
background: var(--mud-palette-surface);
|
||||||
|
border-top-left-radius: 16px;
|
||||||
|
border-top-right-radius: 16px;
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
padding: 4px 16px 16px;
|
||||||
|
box-shadow: 0 -2px 10px rgba(165, 165, 165, 0.5);
|
||||||
}
|
}
|
||||||
|
|
||||||
.login-footer {
|
.login-footer {
|
||||||
@@ -58,8 +56,3 @@
|
|||||||
height: 15px;
|
height: 15px;
|
||||||
margin-left: 4px;
|
margin-left: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.container > .bg-white {
|
|
||||||
box-shadow: var(--card-shadow);
|
|
||||||
border: 1px solid var(--card-border-color);
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user