Files
ClaudeDo/src/ClaudeDo.Ui/Views/Islands/ListsIslandView.axaml
T
mika kuns c31f79d3d4
Changelog / changelog (push) Successful in 2s
Release / release (push) Successful in 41s
feat(ui): wählbares Listen-Icon und aufgeräumter Task-Detail-Header
Listen bekommen eine Icon-Spalte (Migration AddListIcon) und einen Icon-Picker
in den Listeneinstellungen; 34 kuratierte Geometrien aus der Icon-Bibliothek,
Fallback auf "Folder" bei unbekanntem Key.

Der Metadata-Footer im Task-Detail entfällt; created-at wandert in die
Header-Zeile neben das ID-Badge, der Close-Button (und CloseDetailsCommand)
fällt weg.
2026-08-28 14:17:38 +02:00

228 lines
12 KiB
XML

<UserControl xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vm="using:ClaudeDo.Ui.ViewModels.Islands"
xmlns:converters="using:ClaudeDo.Ui.Converters"
xmlns:loc="using:ClaudeDo.Ui.Localization"
x:Class="ClaudeDo.Ui.Views.Islands.ListsIslandView"
x:DataType="vm:ListsIslandViewModel">
<DockPanel LastChildFill="True">
<!-- ── Header ── -->
<Border DockPanel.Dock="Top" Classes="island-header">
<StackPanel Spacing="4">
<TextBlock Classes="heading" Text="{loc:Tr lists.heading}"/>
<!-- Search row -->
<Border Classes="search-wrap" Margin="0,8,0,12">
<Grid ColumnDefinitions="Auto,*,Auto" VerticalAlignment="Center">
<PathIcon Grid.Column="0" Width="14" Height="14"
Data="{StaticResource Icon.Search}"
Foreground="{DynamicResource TextFaintBrush}"
Margin="2,0,0,0"/>
<TextBox Grid.Column="1" x:Name="SearchBox" Classes="search-inner"
PlaceholderText="{loc:Tr lists.searchPlaceholder}"
Text="{Binding SearchText, Mode=TwoWay}"/>
<Border Grid.Column="2" Classes="kbd" Margin="0,0,2,0">
<TextBlock Text="{loc:Tr lists.searchKbd}"/>
</Border>
</Grid>
</Border>
</StackPanel>
</Border>
<!-- ── No-repo banner — visible until any User list has a linked working dir; no
dismiss, no persisted state, comes back if the last repo link is removed. ── -->
<Border DockPanel.Dock="Top"
IsVisible="{Binding HasNoLinkedRepo}"
Margin="12,0,12,12"
Background="{DynamicResource DeepBrush}"
BorderBrush="{DynamicResource LineBrush}"
BorderThickness="1"
CornerRadius="6"
Padding="14,10">
<StackPanel Spacing="8">
<TextBlock Classes="body" Text="{loc:Tr lists.noRepoBannerText}" TextWrapping="Wrap"/>
<Button Classes="btn" HorizontalAlignment="Right"
Content="{loc:Tr lists.noRepoBannerButton}"
Command="{Binding OpenRepoImportCommand}"/>
</StackPanel>
</Border>
<!-- ── Footer ── -->
<Border DockPanel.Dock="Bottom"
BorderBrush="{DynamicResource LineBrush}" BorderThickness="0,1,0,0"
Padding="12,10">
<Grid ColumnDefinitions="Auto,*,Auto" VerticalAlignment="Center">
<!-- Avatar circle -->
<Border Grid.Column="0" Classes="avatar-circle"
VerticalAlignment="Center">
<TextBlock Classes="eyebrow"
Text="{Binding UserInitials}"
FontWeight="SemiBold"
Foreground="{DynamicResource DeepBrush}"
HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
<!-- Name + machine -->
<StackPanel Grid.Column="1" Margin="8,0" Spacing="1" VerticalAlignment="Center">
<TextBlock Classes="title" Text="{Binding UserName}"/>
<TextBlock Classes="meta" Text="{Binding MachineNameLocal}"/>
</StackPanel>
<!-- Settings button -->
<Button Grid.Column="2" Classes="icon-btn" VerticalAlignment="Center"
Command="{Binding OpenSettingsCommand}"
ToolTip.Tip="{loc:Tr lists.settingsTip}">
<PathIcon Data="{StaticResource Icon.Settings}" Width="15" Height="15"/>
</Button>
</Grid>
</Border>
<!-- ── Scrollable body ── -->
<ScrollViewer>
<StackPanel Margin="6,0,6,4">
<!-- SMART LISTS section -->
<TextBlock Classes="section-label" Text="{loc:Tr lists.smartListsLabel}" Margin="10,10,10,4"/>
<ItemsControl ItemsSource="{Binding SmartLists}">
<ItemsControl.ItemTemplate>
<DataTemplate DataType="vm:ListNavItemViewModel">
<Border Classes="list-item" Classes.active="{Binding IsActive}"
Tapped="OnItemTapped">
<Grid ColumnDefinitions="20,*,Auto">
<!-- Left accent bar for active state -->
<Border Grid.Column="0" Grid.ColumnSpan="3"
Background="Transparent"
CornerRadius="8" IsHitTestVisible="False"
IsVisible="{Binding IsActive}">
<Border Width="2" Height="16"
Background="{DynamicResource AccentBrush}"
CornerRadius="1"
HorizontalAlignment="Left" VerticalAlignment="Center"
Margin="-8,0,0,0"/>
</Border>
<!-- Icon -->
<PathIcon Grid.Column="0" Classes="list-icon"
Width="14" Height="14"
Data="{Binding IconKey, Converter={StaticResource IconKey}}"
HorizontalAlignment="Center" VerticalAlignment="Center"/>
<!-- Name -->
<TextBlock Grid.Column="1" Classes="list-label"
Text="{Binding Name}"
VerticalAlignment="Center" Margin="8,0"
Foreground="{DynamicResource TextDimBrush}" FontSize="{StaticResource FontSizeBody}"/>
<!-- Count -->
<TextBlock Grid.Column="2" Classes="list-count"
Text="{Binding Count}"/>
</Grid>
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<!-- MY LISTS section -->
<TextBlock Classes="section-label" Text="{loc:Tr lists.myListsLabel}" Margin="10,10,10,4"/>
<ItemsControl ItemsSource="{Binding UserLists}">
<ItemsControl.ItemTemplate>
<DataTemplate DataType="vm:ListNavItemViewModel">
<Grid RowDefinitions="Auto,Auto,Auto">
<!-- Above-row drop indicator -->
<Border Grid.Row="0" Height="2" VerticalAlignment="Center" Margin="4,0"
Background="{DynamicResource MossBrush}" CornerRadius="1"
IsVisible="{Binding DropHintAbove}"/>
<Border Grid.Row="1" Classes="list-item" Classes.active="{Binding IsActive}"
Classes.drop-target="{Binding IsTaskDropTarget}"
Tapped="OnItemTapped"
DragDrop.AllowDrop="True"
DragDrop.DragOver="OnListDragOver"
DragDrop.Drop="OnListDrop">
<Border.ContextMenu>
<ContextMenu>
<MenuItem Header="{loc:Tr lists.contextWorktrees}"
Command="{Binding $parent[UserControl].((vm:ListsIslandViewModel)DataContext).OpenWorktreesOverviewCommand}"
CommandParameter="{Binding}"/>
<Separator IsVisible="{Binding WorkingDir, Converter={x:Static StringConverters.IsNotNullOrEmpty}}"/>
<MenuItem Header="{loc:Tr lists.contextOpenExplorer}"
IsVisible="{Binding WorkingDir, Converter={x:Static StringConverters.IsNotNullOrEmpty}}"
Command="{Binding $parent[UserControl].((vm:ListsIslandViewModel)DataContext).OpenInExplorerCommand}"
CommandParameter="{Binding}"/>
<MenuItem Header="{loc:Tr lists.contextOpenFindings}"
IsVisible="{Binding WorkingDir, Converter={x:Static StringConverters.IsNotNullOrEmpty}}"
Command="{Binding $parent[UserControl].((vm:ListsIslandViewModel)DataContext).OpenFindingsCommand}"
CommandParameter="{Binding}"/>
<MenuItem Header="{loc:Tr lists.contextOpenTerminal}"
IsVisible="{Binding WorkingDir, Converter={x:Static StringConverters.IsNotNullOrEmpty}}"
Command="{Binding $parent[UserControl].((vm:ListsIslandViewModel)DataContext).OpenInTerminalCommand}"
CommandParameter="{Binding}"/>
<MenuItem Header="{loc:Tr lists.contextImportTickets}"
IsVisible="{Binding HasTicketProject}"
Command="{Binding $parent[UserControl].((vm:ListsIslandViewModel)DataContext).ImportTicketsCommand}"
CommandParameter="{Binding}"/>
<Separator/>
<MenuItem Header="{loc:Tr lists.contextSettings}"
Command="{Binding $parent[UserControl].((vm:ListsIslandViewModel)DataContext).OpenListSettingsCommand}"
CommandParameter="{Binding}"/>
</ContextMenu>
</Border.ContextMenu>
<Grid ColumnDefinitions="20,*,Auto">
<!-- Left accent bar for active state -->
<Border Grid.Column="0" Grid.ColumnSpan="3"
Background="Transparent"
CornerRadius="8" IsHitTestVisible="False"
IsVisible="{Binding IsActive}">
<Border Width="2" Height="16"
Background="{DynamicResource AccentBrush}"
CornerRadius="1"
HorizontalAlignment="Left" VerticalAlignment="Center"
Margin="-8,0,0,0"/>
</Border>
<!-- Icon (list-settings → Icon tab; "Folder" when unset) -->
<PathIcon Grid.Column="0" Classes="list-icon"
Width="14" Height="14"
Data="{Binding IconKey, Converter={StaticResource IconKey}}"
HorizontalAlignment="Center" VerticalAlignment="Center"/>
<!-- Name -->
<TextBlock Grid.Column="1" Classes="list-label"
Text="{Binding Name}"
VerticalAlignment="Center" Margin="8,0"
Foreground="{DynamicResource TextDimBrush}" FontSize="{StaticResource FontSizeBody}"/>
<!-- Count -->
<TextBlock Grid.Column="2" Classes="list-count"
Text="{Binding Count}"/>
</Grid>
</Border>
<!-- Below-row drop indicator (last item only) -->
<Border Grid.Row="2" Height="2" VerticalAlignment="Center" Margin="4,0"
Background="{DynamicResource MossBrush}" CornerRadius="1"
IsVisible="{Binding DropHintBelow}"/>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<!-- New list + import row -->
<Grid ColumnDefinitions="*,Auto" Margin="0,4,0,0">
<Button Grid.Column="0" Classes="new-list-btn"
Command="{Binding CreateListCommand}">
<StackPanel Orientation="Horizontal" Spacing="6">
<PathIcon Data="{StaticResource Icon.Plus}"
Width="13" Height="13"
VerticalAlignment="Center"/>
<TextBlock Classes="body"
Text="{loc:Tr lists.newList}"
VerticalAlignment="Center"/>
</StackPanel>
</Button>
<Button Grid.Column="1" Classes="icon-btn" Margin="6,0,0,0"
Command="{Binding OpenRepoImportCommand}"
ToolTip.Tip="{loc:Tr lists.addReposTip}">
<PathIcon Data="{StaticResource Icon.Folder}" Width="14" Height="14"/>
</Button>
</Grid>
</StackPanel>
</ScrollViewer>
</DockPanel>
</UserControl>