feat: add a Tools page printer for note merge and print presets

Chapter officers can merge a markdown note onto filtered students, teams, or events and save the recipe. Extra student-note columns are additional fields (any ## … fields heading) so they work as print tokens whether imported or typed by hand.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-08-30 15:38:43 -04:00
co-authored by Cursor
parent 4cfd85b902
commit 3f50d6e635
39 changed files with 2199 additions and 69 deletions
+13 -12
View File
@@ -59,7 +59,7 @@
var isExpanded = GetNoteExpanded(noteId);
<MudExpansionPanel @key="@($"note-{noteId}")"
Icon="@Icons.Material.Filled.Note"
IsExpanded="@isExpanded"
Expanded="@isExpanded"
ExpandedChanged="@((bool expanded) => OnPanelExpandedChanged(noteId, expanded))"
Class="@MarkdownHelper.GetNoteColorClass(noteId)">
<TitleContent>
@@ -71,15 +71,16 @@
</MudText>
@if (!NoteNamingService.IsPageNote(note.Title) && !note.IsDeleted && !isExpanded)
{
<MudButton StartIcon="@(note.IsPinned ? Icons.Material.Filled.PushPin : Icons.Material.Outlined.PushPin)"
OnClick="() => TogglePin(note)"
OnClick:StopPropagation="true"
Variant="Variant.Text"
Size="Size.Small"
Color="@(note.IsPinned ? Color.Primary : Color.Default)"
Disabled="@(IsPinDisabled(note))"
Title="@(note.IsPinned ? "Unpin note" : "Pin note")"
Class="flex-shrink-0" />
<div @onclick:stopPropagation="true" class="flex-shrink-0">
<MudTooltip Text="@(note.IsPinned ? "Unpin note" : "Pin note")">
<MudButton StartIcon="@(note.IsPinned ? Icons.Material.Filled.PushPin : Icons.Material.Outlined.PushPin)"
OnClick="() => TogglePin(note)"
Variant="Variant.Text"
Size="Size.Small"
Color="@(note.IsPinned ? Color.Primary : Color.Default)"
Disabled="@(IsPinDisabled(note))" />
</MudTooltip>
</div>
}
</MudStack>
</TitleContent>
@@ -301,7 +302,7 @@
var dialog = await DialogService.ShowAsync<NoteEditDialog>("Create Note", parameters, GetDefaultDialogOptions());
var result = await dialog.Result;
if (!result.Canceled && !_isDisposed)
if (result is { Canceled: false } && !_isDisposed)
{
await LoadNotes();
}
@@ -327,7 +328,7 @@
var dialog = await DialogService.ShowAsync<NoteEditDialog>("Edit Note", parameters, options);
var result = await dialog.Result;
if (!result.Canceled && !_isDisposed)
if (result is { Canceled: false } && !_isDisposed)
{
await LoadNotes();
}