feat(configmanager): add MainWindow view

This commit is contained in:
Joseph Doherty
2026-01-19 17:49:04 -05:00
parent 9677b751e6
commit e9fc764650
3 changed files with 219 additions and 5 deletions
@@ -0,0 +1,77 @@
using System.Collections.ObjectModel;
using System.Windows.Input;
using Avalonia.Media;
namespace JdeScoping.ConfigManager.ViewModels;
/// <summary>
/// Main window view model.
/// This is a stub implementation for Task 11 - full implementation in Task 13.
/// </summary>
public class MainWindowViewModel : ViewModelBase
{
private string _configFolderPath = "No folder selected";
private bool _hasUnsavedChanges;
private string _validationStatus = "Valid";
private IBrush _validationStatusColor = Brushes.LightGreen;
private TreeNodeViewModel? _selectedNode;
private object? _selectedFormViewModel;
public string ConfigFolderPath
{
get => _configFolderPath;
set => SetProperty(ref _configFolderPath, value);
}
public bool HasUnsavedChanges
{
get => _hasUnsavedChanges;
set => SetProperty(ref _hasUnsavedChanges, value);
}
public string ValidationStatus
{
get => _validationStatus;
set => SetProperty(ref _validationStatus, value);
}
public IBrush ValidationStatusColor
{
get => _validationStatusColor;
set => SetProperty(ref _validationStatusColor, value);
}
public TreeNodeViewModel? SelectedNode
{
get => _selectedNode;
set => SetProperty(ref _selectedNode, value);
}
public object? SelectedFormViewModel
{
get => _selectedFormViewModel;
set => SetProperty(ref _selectedFormViewModel, value);
}
public ObservableCollection<TreeNodeViewModel> TreeNodes { get; } = [];
public ICommand OpenFolderCommand { get; }
public ICommand SaveCommand { get; }
public ICommand ExitCommand { get; }
public ICommand UndoCommand { get; }
public ICommand RedoCommand { get; }
public ICommand ValidateCommand { get; }
public ICommand TestConnectionCommand { get; }
public MainWindowViewModel()
{
// Stub commands - full implementation in Task 13
OpenFolderCommand = new RelayCommand(() => { });
SaveCommand = new RelayCommand(() => { });
ExitCommand = new RelayCommand(() => { });
UndoCommand = new RelayCommand(() => { });
RedoCommand = new RelayCommand(() => { });
ValidateCommand = new RelayCommand(() => { });
TestConnectionCommand = new RelayCommand(() => { });
}
}
@@ -0,0 +1,23 @@
using System.Collections.ObjectModel;
namespace JdeScoping.ConfigManager.ViewModels;
/// <summary>
/// ViewModel for a tree node in the configuration tree.
/// This is a stub implementation for Task 11 - full implementation in Task 12.
/// </summary>
public class TreeNodeViewModel : ViewModelBase
{
private bool _isModified;
public string Name { get; set; } = string.Empty;
public string Icon { get; set; } = string.Empty;
public string StatusIcon { get; set; } = string.Empty;
public ObservableCollection<TreeNodeViewModel> Children { get; } = [];
public bool IsModified
{
get => _isModified;
set => SetProperty(ref _isModified, value);
}
}
@@ -1,11 +1,125 @@
<Window xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vm="using:JdeScoping.ConfigManager.ViewModels"
x:Class="JdeScoping.ConfigManager.Views.MainWindow"
x:DataType="vm:MainWindowViewModel"
Title="JdeScoping ConfigManager"
Width="1200" Height="800"
MinWidth="900" MinHeight="600">
<TextBlock Text="ConfigManager - Loading..."
HorizontalAlignment="Center"
VerticalAlignment="Center"
FontSize="24"/>
MinWidth="900" MinHeight="600"
Background="#0D0F12">
<Design.DataContext>
<vm:MainWindowViewModel/>
</Design.DataContext>
<DockPanel>
<!-- Menu Bar -->
<Menu DockPanel.Dock="Top" Background="#151920" Height="28">
<MenuItem Header="_File">
<MenuItem Header="_Open Folder..." Command="{Binding OpenFolderCommand}" InputGesture="Ctrl+O"/>
<MenuItem Header="_Save" Command="{Binding SaveCommand}" InputGesture="Ctrl+S"/>
<Separator/>
<MenuItem Header="E_xit" Command="{Binding ExitCommand}"/>
</MenuItem>
<MenuItem Header="_Edit">
<MenuItem Header="_Undo" Command="{Binding UndoCommand}" InputGesture="Ctrl+Z"/>
<MenuItem Header="_Redo" Command="{Binding RedoCommand}" InputGesture="Ctrl+Y"/>
</MenuItem>
<MenuItem Header="_Tools">
<MenuItem Header="_Validate All" Command="{Binding ValidateCommand}" InputGesture="F5"/>
<MenuItem Header="_Test Connection" Command="{Binding TestConnectionCommand}" InputGesture="F6"/>
<Separator/>
<MenuItem Header="View _Backups..."/>
</MenuItem>
<MenuItem Header="_Help">
<MenuItem Header="_About ConfigManager"/>
</MenuItem>
</Menu>
<!-- Toolbar -->
<Border DockPanel.Dock="Top" Background="#151920" Height="40"
BorderBrush="#2D3540" BorderThickness="0,0,0,1">
<StackPanel Orientation="Horizontal" Margin="8,0" VerticalAlignment="Center" Spacing="4">
<Button Content="Open" Command="{Binding OpenFolderCommand}" Classes="toolbar"/>
<Button Content="Save" Command="{Binding SaveCommand}" Classes="toolbar"/>
<Border Width="1" Height="20" Background="#2D3540" Margin="4,0"/>
<Button Content="Undo" Command="{Binding UndoCommand}" Classes="toolbar"/>
<Button Content="Redo" Command="{Binding RedoCommand}" Classes="toolbar"/>
<Border Width="1" Height="20" Background="#2D3540" Margin="4,0"/>
<Button Content="Test" Command="{Binding TestConnectionCommand}" Classes="toolbar"/>
<Button Content="Validate" Command="{Binding ValidateCommand}" Classes="toolbar"/>
</StackPanel>
</Border>
<!-- Status Bar -->
<Border DockPanel.Dock="Bottom" Background="#151920" Height="24"
BorderBrush="#2D3540" BorderThickness="0,1,0,0">
<Grid Margin="8,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="{Binding ConfigFolderPath}"
Foreground="#5C6A7A" FontFamily="JetBrains Mono" FontSize="11"
VerticalAlignment="Center"/>
<TextBlock Grid.Column="1" Text=" | Modified"
Foreground="#5C9AFF" FontSize="11"
IsVisible="{Binding HasUnsavedChanges}"
VerticalAlignment="Center" Margin="8,0"/>
<TextBlock Grid.Column="3" Text="{Binding ValidationStatus}"
Foreground="{Binding ValidationStatusColor}"
FontFamily="JetBrains Mono" FontSize="11"
VerticalAlignment="Center"/>
</Grid>
</Border>
<!-- Main Content -->
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="280" MinWidth="200" MaxWidth="400"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<!-- Tree View Panel -->
<Border Grid.Column="0" Background="#0D0F12" BorderBrush="#2D3540" BorderThickness="0,0,1,0">
<DockPanel>
<Border DockPanel.Dock="Top" Background="#151920" Height="36">
<TextBlock Text="CONFIGURATION"
Foreground="#5C6A7A" FontSize="12" FontWeight="SemiBold"
VerticalAlignment="Center" Margin="16,0"
LetterSpacing="0.5"/>
</Border>
<TreeView ItemsSource="{Binding TreeNodes}"
SelectedItem="{Binding SelectedNode}"
Background="Transparent"
Margin="8">
<TreeView.ItemTemplate>
<TreeDataTemplate ItemsSource="{Binding Children}">
<StackPanel Orientation="Horizontal" Spacing="8">
<TextBlock Text="{Binding Icon}" FontSize="14"/>
<TextBlock Text="{Binding Name}" Foreground="#E6EDF5"/>
<TextBlock Text="{Binding StatusIcon}" FontSize="12"/>
<TextBlock Text="*" Foreground="#5C9AFF"
IsVisible="{Binding IsModified}"/>
</StackPanel>
</TreeDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
</DockPanel>
</Border>
<!-- Splitter -->
<GridSplitter Grid.Column="1" Width="4" Background="Transparent"
ResizeDirection="Columns"/>
<!-- Form Panel -->
<Border Grid.Column="2" Background="#151920" Padding="24">
<ContentControl Content="{Binding SelectedFormViewModel}"/>
</Border>
</Grid>
</DockPanel>
</Window>