Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for customizing display order of ATIS stations #139

Merged
merged 9 commits into from
Feb 16, 2025

Conversation

justinshannon
Copy link
Contributor

@justinshannon justinshannon commented Feb 15, 2025

Summary by CodeRabbit

  • New Features
    • Introduced a new, interactive sorting dialog that allows users to reorder ATIS stations.
    • Enhanced the ATIS configuration window with a dedicated sorting button.
    • Implemented an auto-scroll behavior to ensure the selected station is always visible.
    • Improved the station ordering mechanism by utilizing an ordinal property.
    • Added event handling to keep station order updated across the UI.

Copy link
Contributor

coderabbitai bot commented Feb 15, 2025

Warning

Rate limit exceeded

@justinshannon has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 22 minutes and 54 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between 447d36c and b524740.

📒 Files selected for processing (8)
  • vATIS.Desktop/Container/Factory/WindowFactory.cs (1 hunks)
  • vATIS.Desktop/Container/ServiceProvider.cs (2 hunks)
  • vATIS.Desktop/Ui/Dialogs/SortAtisStationsDialog.axaml (1 hunks)
  • vATIS.Desktop/Ui/IWindowFactory.cs (1 hunks)
  • vATIS.Desktop/Ui/ViewModels/AtisConfigurationWindowViewModel.cs (5 hunks)
  • vATIS.Desktop/Ui/ViewModels/AtisStationViewModel.cs (3 hunks)
  • vATIS.Desktop/Ui/ViewModels/MainWindowViewModel.cs (7 hunks)
  • vATIS.Desktop/Ui/ViewModels/SortAtisStationsDialogViewModel.cs (1 hunks)

Walkthrough

This pull request introduces a new sorting feature for ATIS stations. A dedicated dialog for sorting stations is added, along with its view model and corresponding UI layout. The service provider now registers the dialog and view model as transient services. Existing models and view models have been enhanced with an ordinal property and composite key logic to support ordering. Additionally, an event record is introduced to signal ordinal changes, and a behavior for auto-scrolling the TreeDataGrid to the selected item is implemented and integrated within existing dialogs and the main configuration window.

Changes

File(s) Change Summary
vATIS.Desktop/Container/Factory/WindowFactory.cs, vATIS.Desktop/Ui/IWindowFactory.cs, vATIS.Desktop/Ui/Dialogs/SortAtisStationsDialog.axaml, vATIS.Desktop/Ui/Dialogs/SortAtisStationsDialog.axaml.cs, vATIS.Desktop/Ui/ViewModels/SortAtisStationsDialogViewModel.cs Added a new dialog for sorting ATIS stations, including its UI layout, creation methods, and view model with sorting commands.
vATIS.Desktop/Container/ServiceProvider.cs Registered new transient services for SortAtisStationsDialog and SortAtisStationsDialogViewModel.
vATIS.Desktop/Events/AtisStationOrdinalChanged.cs, vATIS.Desktop/Profiles/Models/AtisStation.cs, vATIS.Desktop/Ui/ViewModels/AtisStationViewModel.cs, vATIS.Desktop/Ui/ViewModels/MainWindowViewModel.cs Introduced an ordinal property (and backing field) for ATIS stations, a new event record for ordinal changes, and updated sorting logic with composite key tracking in the main view model.
vATIS.Desktop/Ui/Behaviors/ScrollToSelectedItemBehavior.cs, vATIS.Desktop/Ui/Dialogs/SortPresetsDialog.axaml Added a behavior to auto-scroll the TreeDataGrid to the currently selected item by subscribing to selection changes.
vATIS.Desktop/Ui/ViewModels/AtisConfigurationWindowViewModel.cs, vATIS.Desktop/Ui/Windows/AtisConfigurationWindow.axaml Updated the ATIS configuration UI and view model to integrate the new sorting dialog command and adjusted the grid layout for new button arrangements.

Sequence Diagram(s)

sequenceDiagram
    participant ConfigVM as AtisConfigurationWindowViewModel
    participant WindowFactory as IWindowFactory
    participant SortDialog as SortAtisStationsDialog
    participant SortVM as SortAtisStationsDialogViewModel
    participant EventBus as Event Bus

    ConfigVM->>WindowFactory: Invoke OpenSortAtisStationsDialogCommand
    WindowFactory->>SortDialog: CreateSortAtisStationsDialog()
    SortDialog->>SortVM: Initialize with view model
    User->>SortDialog: Trigger move up/down commands
    SortVM->>SortDialog: Update order of ATIS stations
    SortVM->>EventBus: Publish AtisStationOrdinalChanged event
    EventBus->>ConfigVM: Notify MainWindowViewModel for UI update
Loading
sequenceDiagram
    participant TreeGrid as TreeDataGrid
    participant ScrollBehavior as ScrollToSelectedItemBehavior
    participant RowsPresenter as RowsPresenter

    TreeGrid->>ScrollBehavior: SelectionChanged event occurs
    ScrollBehavior->>RowsPresenter: Convert index and invoke ScrollToItemIndex
    RowsPresenter-->>TreeGrid: Scroll to selected item
Loading

Suggested labels

breaking

Poem

Oh, how I hop with glee,
A new sort dialog springs to be,
Stations arranged in ordered delight,
Scrolling smooth with every byte.
My whiskers twitch in code so bright—
Hooray for changes, day and night!
🐇✨


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR. (Beta)
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🔭 Outside diff range comments (1)
vATIS.Desktop/Profiles/Models/AtisStation.cs (1)

220-241: ⚠️ Potential issue

Add the Ordinal property to the Clone method.

The Ordinal property is not included in the Clone method, which could lead to inconsistencies when cloning ATIS stations.

Apply this diff to include the Ordinal property in the cloned instance:

 public AtisStation Clone()
 {
     return new AtisStation
     {
         Id = Guid.NewGuid().ToString(),
         Identifier = Identifier,
         Name = Name,
         AtisType = AtisType,
         CodeRange = CodeRange,
         AtisFormat = AtisFormat.Clone(),
         NotamsBeforeFreeText = NotamsBeforeFreeText,
         AirportConditionsBeforeFreeText = AirportConditionsBeforeFreeText,
         Frequency = Frequency,
         IdsEndpoint = IdsEndpoint,
         UseDecimalTerminology = UseDecimalTerminology,
         AtisVoice = AtisVoice.Clone(),
         Presets = Presets.Select(x => x.Clone()).ToList(),
         Contractions = Contractions.Select(x => x.Clone()).ToList(),
         AirportConditionDefinitions = AirportConditionDefinitions.Select(x => x.Clone()).ToList(),
         NotamDefinitions = NotamDefinitions.Select(x => x.Clone()).ToList(),
+        Ordinal = Ordinal,
     };
 }
🧹 Nitpick comments (5)
vATIS.Desktop/Ui/Dialogs/SortPresetsDialog.axaml (1)

40-42: Fix indentation for consistency.

The indentation of the Interaction.Behaviors section doesn't match the surrounding code style.

-                        <Interaction.Behaviors>
-                            <behaviors:ScrollToSelectedItemBehavior/>
-                        </Interaction.Behaviors>
+						<Interaction.Behaviors>
+							<behaviors:ScrollToSelectedItemBehavior/>
+						</Interaction.Behaviors>
vATIS.Desktop/Ui/Behaviors/ScrollToSelectedItemBehavior.cs (1)

31-59: Consider extracting index calculation logic into a separate method.

The index calculation logic within the Observable chain is complex and would be more maintainable if extracted into a dedicated method.

 Observable.FromEventPattern(rowSelection, nameof(rowSelection.SelectionChanged))
-    .Select(_ =>
-    {
-        // Retrieve the first selected index.
-        var selectedIndexPath = rowSelection.SelectedIndex.FirstOrDefault();
-        if (AssociatedObject.Rows is null)
-        {
-            return selectedIndexPath;
-        }
-
-        // Convert the logical index to the actual row index in the UI.
-        var rowIndex = AssociatedObject.Rows.ModelIndexToRowIndex(selectedIndexPath);
-
-        // Adjust the index if the selected item is a child of a parent row.
-        if (rowSelection.SelectedIndex.Count > 1)
-        {
-            // Skip the first index (parent), sum the child indices, and adjust.
-            rowIndex += rowSelection.SelectedIndex.Skip(1).Sum();
-
-            // Add 1 to correct the index for proper positioning.
-            rowIndex += 1;
-        }
-
-        return rowIndex;
-    })
+    .Select(_ => CalculateRowIndex(rowSelection))
     .WhereNotNull()
     .Do(ScrollToItemIndex)
     .Subscribe()
     .DisposeWith(disposable);

+ private int? CalculateRowIndex(ITreeDataGridRowSelection rowSelection)
+ {
+     var selectedIndexPath = rowSelection.SelectedIndex.FirstOrDefault();
+     if (AssociatedObject.Rows is null)
+     {
+         return selectedIndexPath;
+     }
+
+     var rowIndex = AssociatedObject.Rows.ModelIndexToRowIndex(selectedIndexPath);
+
+     if (rowSelection.SelectedIndex.Count > 1)
+     {
+         rowIndex += rowSelection.SelectedIndex.Skip(1).Sum() + 1;
+     }
+
+     return rowIndex;
+ }
vATIS.Desktop/Ui/Dialogs/SortAtisStationsDialog.axaml (2)

46-47: Enhance button labels for better accessibility.

Consider using more descriptive labels for the Up/Down buttons to improve accessibility and user experience.

-<Button Theme="{StaticResource Dark}" Command="{Binding MoveStationUpCommand, DataType=vm:SortAtisStationsDialogViewModel}">Up</Button>
-<Button Theme="{StaticResource Dark}" Command="{Binding MoveStationDownCommand, DataType=vm:SortAtisStationsDialogViewModel}">Down</Button>
+<Button Theme="{StaticResource Dark}" Command="{Binding MoveStationUpCommand, DataType=vm:SortAtisStationsDialogViewModel}">Move Up</Button>
+<Button Theme="{StaticResource Dark}" Command="{Binding MoveStationDownCommand, DataType=vm:SortAtisStationsDialogViewModel}">Move Down</Button>

31-43: Add accessibility attributes to TreeDataGrid.

The TreeDataGrid should have accessibility attributes to improve screen reader support.

-<TreeDataGrid Grid.Column="0" CornerRadius="5" BorderBrush="#646464" BorderThickness="1" MaxHeight="200" Source="{Binding Source, DataType=vm:SortAtisStationsDialogViewModel, Mode=OneWay}" CanUserResizeColumns="False" CanUserSortColumns="False">
+<TreeDataGrid Grid.Column="0" CornerRadius="5" BorderBrush="#646464" BorderThickness="1" MaxHeight="200" Source="{Binding Source, DataType=vm:SortAtisStationsDialogViewModel, Mode=OneWay}" CanUserResizeColumns="False" CanUserSortColumns="False"
+             AutomationProperties.Name="ATIS Stations List"
+             AutomationProperties.HelpText="Use Up and Down buttons to reorder stations">
vATIS.Desktop/Ui/ViewModels/MainWindowViewModel.cs (1)

115-116: Update the comment to accurately reflect the composite key components.

The comment doesn't mention all components of the composite key.

Apply this diff to improve the comment accuracy:

-// Generate composite keys using Identifier + Ordinal
+// Generate composite keys using Identifier + AtisType + Ordinal
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4f201a6 and 447d36c.

📒 Files selected for processing (14)
  • vATIS.Desktop/Container/Factory/WindowFactory.cs (1 hunks)
  • vATIS.Desktop/Container/ServiceProvider.cs (2 hunks)
  • vATIS.Desktop/Events/AtisStationOrdinalChanged.cs (1 hunks)
  • vATIS.Desktop/Profiles/Models/AtisStation.cs (1 hunks)
  • vATIS.Desktop/Ui/Behaviors/ScrollToSelectedItemBehavior.cs (1 hunks)
  • vATIS.Desktop/Ui/Dialogs/SortAtisStationsDialog.axaml (1 hunks)
  • vATIS.Desktop/Ui/Dialogs/SortAtisStationsDialog.axaml.cs (1 hunks)
  • vATIS.Desktop/Ui/Dialogs/SortPresetsDialog.axaml (2 hunks)
  • vATIS.Desktop/Ui/IWindowFactory.cs (1 hunks)
  • vATIS.Desktop/Ui/ViewModels/AtisConfigurationWindowViewModel.cs (4 hunks)
  • vATIS.Desktop/Ui/ViewModels/AtisStationViewModel.cs (3 hunks)
  • vATIS.Desktop/Ui/ViewModels/MainWindowViewModel.cs (7 hunks)
  • vATIS.Desktop/Ui/ViewModels/SortAtisStationsDialogViewModel.cs (1 hunks)
  • vATIS.Desktop/Ui/Windows/AtisConfigurationWindow.axaml (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (7)
  • GitHub Check: build (macos-latest)
  • GitHub Check: Analyze (cpp)
  • GitHub Check: build (windows-latest)
  • GitHub Check: Analyze (csharp)
  • GitHub Check: build (ubuntu-latest)
  • GitHub Check: Analyze (cpp)
  • GitHub Check: Analyze (csharp)
🔇 Additional comments (11)
vATIS.Desktop/Events/AtisStationOrdinalChanged.cs (1)

8-17: Well-structured event record implementation!

The record type is a good choice for this immutable event data, and the XML documentation clearly describes the purpose of each parameter.

vATIS.Desktop/Ui/Dialogs/SortAtisStationsDialog.axaml.cs (1)

16-49: Clean and well-structured dialog implementation!

The dialog follows best practices with proper cleanup, window drag functionality, and clear separation of concerns.

vATIS.Desktop/Ui/IWindowFactory.cs (1)

101-105: LGTM!

The new factory method follows the established pattern and is well-documented.

vATIS.Desktop/Container/ServiceProvider.cs (1)

75-75: LGTM!

The new service registrations follow the established pattern and are correctly registered as transient services.

Also applies to: 100-100

vATIS.Desktop/Container/Factory/WindowFactory.cs (1)

200-210: LGTM! The implementation follows the established factory pattern.

The new method CreateSortAtisStationsDialog is well-implemented, following the same pattern as other dialog creation methods in the class. It properly retrieves the view model from the service provider and initializes the dialog with it.

vATIS.Desktop/Ui/Windows/AtisConfigurationWindow.axaml (1)

107-110: LGTM! The UI changes are well-structured and consistent.

The grid layout modifications and the addition of the "Sort" button are well-implemented:

  • Grid layout properly expanded to 3 columns
  • Buttons are consistently sized with "Stretch" alignment
  • Commands are correctly bound to their respective view model commands
vATIS.Desktop/Profiles/Models/AtisStation.cs (1)

27-30: LGTM! The Ordinal property is well-documented.

The new property is properly documented with XML comments.

vATIS.Desktop/Ui/ViewModels/MainWindowViewModel.cs (1)

199-206: LGTM! The event subscription is well-implemented.

The subscription to AtisStationOrdinalChanged events properly updates the Ordinal property of the corresponding station.

vATIS.Desktop/Ui/ViewModels/AtisConfigurationWindowViewModel.cs (1)

129-133: LGTM!

The sorting logic correctly prioritizes the Ordinal property while maintaining Identifier and AtisType as secondary sort keys.

vATIS.Desktop/Ui/ViewModels/AtisStationViewModel.cs (2)

76-76: LGTM!

The ordinal field is correctly declared and initialized from the station parameter.

Also applies to: 140-140


596-603: LGTM!

The property is well-documented and correctly implements change notifications using RaiseAndSetIfChanged.

@justinshannon justinshannon added this pull request to the merge queue Feb 16, 2025
Merged via the queue into main with commit 7bcebfc Feb 16, 2025
9 checks passed
@justinshannon justinshannon deleted the feat/atis-station-display-order branch February 16, 2025 15:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant