feat: implement preview work units preference with local storage support
All checks were successful
Publish Container / publish (push) Successful in 3m16s

This commit is contained in:
MaddoScientisto 2026-04-20 23:17:35 +02:00
commit 0991128b30
4 changed files with 104 additions and 5 deletions

View file

@ -199,6 +199,8 @@ else
@code { @code {
[Parameter] public string? YearMonth { get; set; } [Parameter] public string? YearMonth { get; set; }
private const string IncludePreviewPreferenceKey = "worktracker.includePreviewWorkUnits";
private DateOnly firstOfMonth; private DateOnly firstOfMonth;
private bool loading = true; private bool loading = true;
private List<CalendarCell?[]> weeks = []; private List<CalendarCell?[]> weeks = [];
@ -222,6 +224,22 @@ else
await LoadMonth(); await LoadMonth();
} }
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (!firstRender)
{
return;
}
var savedIncludePreview = await JS.InvokeAsync<bool?>("workTrackerPreferences.getBool", IncludePreviewPreferenceKey);
if (savedIncludePreview.HasValue && savedIncludePreview.Value != includePreviewTotals)
{
includePreviewTotals = savedIncludePreview.Value;
await LoadMonth();
await InvokeAsync(StateHasChanged);
}
}
private async Task LoadMonth() private async Task LoadMonth()
{ {
loading = true; loading = true;
@ -269,6 +287,7 @@ else
private async Task OnIncludePreviewTotalsChanged(ChangeEventArgs e) private async Task OnIncludePreviewTotalsChanged(ChangeEventArgs e)
{ {
includePreviewTotals = e.Value is bool value && value; includePreviewTotals = e.Value is bool value && value;
await JS.InvokeVoidAsync("workTrackerPreferences.setBool", IncludePreviewPreferenceKey, includePreviewTotals);
await LoadMonth(); await LoadMonth();
} }

View file

@ -5,6 +5,7 @@
@using System.Globalization @using System.Globalization
@inject global::WorkTracker.Services.WorkDays.IWorkDayService WorkDayService @inject global::WorkTracker.Services.WorkDays.IWorkDayService WorkDayService
@inject IJSRuntime JS
<PageTitle>Monthly Summary</PageTitle> <PageTitle>Monthly Summary</PageTitle>
@ -209,6 +210,7 @@ else if (viewMode == SummaryViewMode.Timesheet && timesheet is not null)
[Parameter] public string? YearMonth { get; set; } [Parameter] public string? YearMonth { get; set; }
private static readonly CultureInfo ItalianCulture = CultureInfo.GetCultureInfo("it-IT"); private static readonly CultureInfo ItalianCulture = CultureInfo.GetCultureInfo("it-IT");
private const string IncludePreviewPreferenceKey = "worktracker.includePreviewWorkUnits";
private DateOnly currentMonth; private DateOnly currentMonth;
private bool loading = true; private bool loading = true;
@ -231,9 +233,26 @@ else if (viewMode == SummaryViewMode.Timesheet && timesheet is not null)
await LoadSummary(); await LoadSummary();
} }
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (!firstRender)
{
return;
}
var savedIncludePreview = await JS.InvokeAsync<bool?>("workTrackerPreferences.getBool", IncludePreviewPreferenceKey);
if (savedIncludePreview.HasValue && savedIncludePreview.Value != includePreview)
{
includePreview = savedIncludePreview.Value;
await LoadSummary();
await InvokeAsync(StateHasChanged);
}
}
private async Task OnIncludePreviewChanged(ChangeEventArgs e) private async Task OnIncludePreviewChanged(ChangeEventArgs e)
{ {
includePreview = e.Value is bool value && value; includePreview = e.Value is bool value && value;
await JS.InvokeVoidAsync("workTrackerPreferences.setBool", IncludePreviewPreferenceKey, includePreview);
await LoadSummary(); await LoadSummary();
} }

View file

@ -715,22 +715,28 @@ h1:focus {
.timesheet-summary-table thead th { .timesheet-summary-table thead th {
background-color: var(--wt-summary-head-bg); background-color: var(--wt-summary-head-bg);
white-space: nowrap; white-space: normal;
} }
.timesheet-summary-table th, .timesheet-summary-table th,
.timesheet-summary-table td { .timesheet-summary-table td {
min-width: 2.2rem; min-width: 2.2rem;
padding: 0.25rem 0.12rem; padding: 0.35rem 0.16rem;
vertical-align: middle; vertical-align: middle;
line-height: 1.2;
} }
.timesheet-summary-sticky-column { .timesheet-summary-sticky-column {
position: sticky; position: sticky;
left: 0; left: 0;
z-index: 2; z-index: 2;
min-width: 15rem !important; min-width: 6.25rem !important;
max-width: 6.25rem;
background-color: var(--wt-summary-sticky-bg); background-color: var(--wt-summary-sticky-bg);
white-space: normal;
overflow-wrap: anywhere;
word-break: break-word;
text-align: left;
} }
.timesheet-summary-table thead .timesheet-summary-sticky-column { .timesheet-summary-table thead .timesheet-summary-sticky-column {
@ -739,8 +745,11 @@ h1:focus {
} }
.timesheet-summary-total-column { .timesheet-summary-total-column {
position: sticky;
right: 0;
z-index: 2;
background-color: var(--wt-summary-head-bg); background-color: var(--wt-summary-head-bg);
min-width: 3.3rem !important; min-width: 3.5rem !important;
} }
.timesheet-summary-table tbody tr:nth-child(odd) td, .timesheet-summary-table tbody tr:nth-child(odd) td,
@ -748,6 +757,18 @@ h1:focus {
background-color: var(--wt-summary-row-alt); background-color: var(--wt-summary-row-alt);
} }
.timesheet-summary-table tbody tr:nth-child(odd) .timesheet-summary-total-column {
background-color: var(--wt-summary-row-alt);
}
.timesheet-summary-table tbody .timesheet-summary-total-column {
background-color: var(--wt-summary-sticky-bg);
}
.timesheet-summary-table thead .timesheet-summary-total-column {
z-index: 3;
}
.timesheet-summary-table .timesheet-summary-day-danger { .timesheet-summary-table .timesheet-summary-day-danger {
background-color: #f8d7da !important; background-color: #f8d7da !important;
} }
@ -821,7 +842,16 @@ h1:focus {
@media (max-width: 767.98px) { @media (max-width: 767.98px) {
.timesheet-summary-sticky-column { .timesheet-summary-sticky-column {
min-width: 12rem !important; min-width: 4.75rem !important;
max-width: 4.75rem;
padding-left: 0.3rem !important;
padding-right: 0.3rem !important;
font-size: 0.82rem;
}
.timesheet-summary-total-column {
min-width: 3.1rem !important;
font-size: 0.82rem;
} }
.timesheet-summary-day-popup { .timesheet-summary-day-popup {

View file

@ -55,4 +55,35 @@ window.workTrackerTheme = (() => {
}; };
})(); })();
window.workTrackerPreferences = {
getBool(key) {
try {
const value = localStorage.getItem(key);
if (value === null) {
return null;
}
if (value === "true") {
return true;
}
if (value === "false") {
return false;
}
return null;
}
catch {
return null;
}
},
setBool(key, value) {
try {
localStorage.setItem(key, value ? "true" : "false");
}
catch {
}
}
};
window.workTrackerTheme.init(); window.workTrackerTheme.init();