feat: implement board tab with dialogs, virtualized card lists and refresh-after-write

- board: columns in id order, per-column sort via config, column width presets (240/320/480) and custom 160-720
- column header new-card and edit/delete menu; card menu delete and move-to-column
- card editor as one unit of work with dirty check and discard confirmation; nested tag picker writes new tags immediately
- schema constraint violations mapped to typed exceptions and shown inside the modal
- dialog service with owner stack so nested modals center on their parent and get FlowDirection
- repository: filtered GetCards, CountCards; view-model tests
This commit is contained in:
doyaGu committed 2026-10-03 03:33:25 -04:00
1 parent 84d08c6768
commit e3f58ce150
41 files changed
+3004 -26

No files matched your search

@@ -0,0 +1,30 @@
<dialogs:DialogWindow xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vm="using:YKanBan.ViewModels.Dialogs"
xmlns:dialogs="using:YKanBan.Views.Dialogs"
xmlns:lang="using:YKanBan"
x:Class="YKanBan.Views.Dialogs.ColumnWidthDialog"
x:DataType="vm:ColumnWidthDialogViewModel"
Title="{x:Static lang:Resources.ColumnWidth_Title}"
Width="360"
WindowStartupLocation="CenterOwner">
<StackPanel Margin="20" Spacing="10">
<RadioButton GroupName="Width" Content="{Binding NarrowLabel}" IsChecked="{Binding IsNarrow}"/>
<RadioButton GroupName="Width" Content="{Binding StandardLabel}" IsChecked="{Binding IsStandard}"/>
<RadioButton GroupName="Width" Content="{Binding WideLabel}" IsChecked="{Binding IsWide}"/>
<RadioButton GroupName="Width" Content="{x:Static lang:Resources.ColumnWidth_Custom}" IsChecked="{Binding IsCustom}"/>
<StackPanel Orientation="Horizontal" Spacing="8" Margin="28,0,0,0" IsEnabled="{Binding IsCustom}">
<NumericUpDown Value="{Binding CustomPixels}" Minimum="{Binding MinPixels}" Maximum="{Binding MaxPixels}"
Increment="10" FormatString="0" Width="140"/>
<TextBlock Text="{Binding RangeLabel}" VerticalAlignment="Center" Opacity="0.7"/>
</StackPanel>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right" Spacing="8" Margin="0,8,0,0">
<Button Content="{x:Static lang:Resources.Common_Ok}" Command="{Binding ConfirmCommand}"
Classes="Primary" MinWidth="90" IsDefault="True"/>
<Button Content="{x:Static lang:Resources.Common_Cancel}" Command="{Binding CancelCommand}"
MinWidth="90" IsCancel="True"/>
</StackPanel>
</StackPanel>
</dialogs:DialogWindow>