feat(ui): improve asset catalog filtering and sorting - #5
Open
viniciusrodriguesai wants to merge 8 commits into
Open
feat(ui): improve asset catalog filtering and sorting#5viniciusrodriguesai wants to merge 8 commits into
viniciusrodriguesai wants to merge 8 commits into
Conversation
Context: The vehicle catalog can contain many base-game, content-pack, and custom assets. Text search alone does not let users isolate the assets that are currently forbidden or allowed. Changes: - add localized All, Forbidden, and Allowed visibility options - combine visibility filtering with text search and target transport compatibility - keep matching child assets associated with their parent group - reset pagination when the visibility option changes - replace repeated parent lookup scans with a set of relevant asset IDs Behavior: The catalog previously displayed every compatible asset that matched the text search. Users can now change which matching entries are visible without modifying the pending forbidden selection or the restriction stored on the selected target. Groups are expanded while a visibility filter is active so matching children remain discoverable. Compatibility: - no save-format changes - no pathfinding, vehicle movement, or ECS changes - no dependency or package changes - English and Simplified Chinese labels are included Security: - no network access - no filesystem access outside the repository - no executable, deployment, or publishing changes Validation: - git diff --check: passed - localization key/reference review: passed - static review of All, Forbidden, Allowed, search composition, target transport filtering, grouping, and pagination reset: passed - UI build: not performed because authorization was not granted - C# build: not performed because authorization was not granted - runtime test in Cities: Skylines II: not performed
Context: The catalog exposes vehicle performance data but previously kept a fixed backend name order. Users could not rank compatible assets by maximum speed, acceleration, or braking before reviewing a page. Changes: - add localized Name, Maximum speed, Acceleration, and Braking sort choices - add an accessible ascending and descending direction control - sort filtered roots before pagination with deterministic name and ID tie-breakers - keep child assets attached to their parent and order children alphabetically - reset pagination whenever the sort field or direction changes Behavior: Catalog roots can now be ordered locally by name or numeric vehicle metrics in either direction. Pagination consumes the sorted roots, while grouped trailers and carriages remain nested beneath their original parent in predictable alphabetical order. Compatibility: - no backend catalog order changes - no save-format, pathfinding, vehicle movement, or ECS changes - no dependency or package changes - English and Simplified Chinese labels are included Security: - no network access - no filesystem access outside the repository - no executable, deployment, or publishing changes Validation: - git diff --check: passed - localization key/reference review: passed - static review of name and numeric comparators, ascending and descending direction, deterministic ties, root-only sorting, grouping, and pre-pagination ordering: passed - UI build: not performed because authorization was not granted - C# build: not performed because authorization was not granted - runtime test in Cities: Skylines II: not performed
Context: The panel already keeps asset edits pending until Apply, but it does not indicate when those edits differ from the restriction stored on the selected target and offers no way to discard them without reselecting the target. Changes: - snapshot the applied asset entities whenever a target is selected - expose an order-independent pendingChanges binding based on HashSet.SetEquals - refresh the applied snapshot after Apply and after catalog membership changes - update the applied baseline after Clear without overwriting pending edits - add a Revert pending changes trigger that restores only the panel selection - show a compact localized pending status and revert action Behavior: Toggling assets now marks the selected target as having pending changes whenever the pending and applied sets differ. Manually restoring the same set or using Revert clears the indicator. Apply reloads the effective stored restriction, Clear makes the applied baseline empty while preserving distinct pending edits, and selecting another target rebuilds both sets for that target. Compatibility: - no save-format or persistence changes - no pathfinding, vehicle movement, or restriction component changes - existing Apply, Clear, and target-selection semantics remain distinct - no dependency or package changes - English and Simplified Chinese labels are included Security: - no network access - no filesystem access outside the repository - no executable, deployment, or publishing changes Validation: - git diff --check: passed - binding, trigger, and localization reference review: passed - static control-flow review of no target, empty and populated restrictions, edit/manual undo, Revert, Apply, target switching, and Clear: passed - order-independent set comparison review: passed - UI build: not performed because authorization was not granted - C# build: not performed because authorization was not granted - runtime test in Cities: Skylines II: not performed
Context: Asset toggle controls exposed English-only accessibility labels, and the existing refresh control referenced a localization key that was absent from the locale dictionary. Changes: - replace hardcoded Allow asset and Forbid asset aria labels with localized lookups - add English and Simplified Chinese labels for allowing and forbidding an asset - define the existing RefreshAssets localization key in both languages Behavior: Assistive labels for asset toggles and catalog refresh now follow the active supported language. Visible catalog behavior and restriction semantics are unchanged. Compatibility: - no save-format, gameplay, pathfinding, vehicle movement, or ECS changes - no dependency or package changes - existing localization fallback text remains available Security: - no network access - no filesystem access outside the repository - no executable, deployment, or publishing changes Validation: - git diff --check: passed - literal search confirmed each accessibility key has a locale entry and JSX reference - static localization review for English and Simplified Chinese: passed - UI build: not performed because authorization was not granted - C# build: not performed because authorization was not granted - runtime test in Cities: Skylines II: not performed
Context: Static review showed that the pending-change baseline depends on the live state of target restriction buffers and on how unavailable vehicle assets are represented by the running game. Those interactions cannot be validated responsibly without the Cities: Skylines II runtime and modding toolchain. Changes: - remove the applied-asset baseline set and pendingChanges binding from RouteFilterUISystem - remove the revertPendingChanges trigger and the Apply/Clear wrapper methods introduced for baseline synchronization - restore direct ApplySelection and ClearSelectedRestriction trigger handlers - remove the pending status and revert action from the React panel - remove pending/revert localization entries and their dedicated CSS rules - preserve visibility filters, sorting, and the localized AllowAsset, ForbidAsset, and RefreshAssets labels Behavior: The catalog continues to keep edits in the existing selection until Apply is invoked, but it no longer claims to detect or revert differences from the restriction stored on a live target. Apply, Clear, Cancel, target selection, and selected-asset loading return to their original pre-pending-workflow behavior. Compatibility: - no save format or persistence changes - no pathfinding, vehicle movement, or ECS changes - no dependency or version changes - existing restrictions are preserved - catalog filtering, sorting, and accessibility localization remain available Security: - no network behavior changes - no filesystem behavior changes - no executable or credential handling changes - no deployment or publishing changes Validation: - full staged diff review: passed - pending binding, trigger, localization, JSX, and CSS reference search: no references remain - comparison with the pre-pending implementation: Apply/Clear handlers and selection loading restored - git diff --check: passed - C# build: not performed because Cities: Skylines II assemblies/toolchain are unavailable - Cities: Skylines II runtime validation: not performed
Context: The selectedAssetIds binding uses a comma-separated string. Converting every split token directly with Number caused an empty binding to produce the numeric value 0 because Number of an empty string is zero. Changes: - trim each selected-asset token before conversion - discard empty tokens before calling Number - continue accepting only integer identifiers when constructing the selected Set Behavior: An empty selection now creates an empty Set instead of a Set containing 0. Normal lists such as 1,2,3 remain unchanged, repeated separators are ignored, and non-numeric or non-integer tokens do not enter the selection. Compatibility: - no save format or persistence changes - no pathfinding, gameplay, vehicle movement, or ECS changes - no dependency or version changes - valid existing selected asset identifiers retain their numeric values Security: - no network or filesystem behavior changes - no executable or credential handling changes - no deployment or publishing changes Validation: - empty string parsing: produced an empty array - 1,2,3 parsing: produced [1,2,3] - ,1,,2, parsing: produced [1,2] - x,1,2.5,3 parsing: produced [1,3] - full staged diff review: passed - git diff --check: passed - UI build: deferred until the complete branch validation - Cities: Skylines II runtime validation: not performed
Context: Catalog roots are retained when a matching child needs its parent for identification. The previous rendering treated that retained parent as a normal filter result, which could make an allowed parent look like a Forbidden result or a non-matching search result look directly selectable. Filtered groups were also forced open in a way that prevented the expand control from collapsing them. Changes: - identify roots that fail the active search/visibility criteria but contain a matching child as context-only rows - render context-only roots with neutral styling and a fixed spacer instead of the restriction toggle - continue rendering only children that satisfy both search and visibility criteria - track collapse overrides while filtering so automatically expanded matching groups can still be collapsed and reopened - reset filtered collapse overrides when search, visibility, or target transport changes Behavior: A root that matches the active criteria is rendered normally. A non-matching root is retained only to identify matching children, cannot change restrictions from its context row, and uses subdued styling. Parent-child relationships, root sorting, pre-pagination filtering, and child name ordering remain intact. Search and Allowed/Forbidden filters continue to combine, and filtered groups retain working expand/collapse controls. Compatibility: - no save format or persistence changes - no pathfinding, gameplay, vehicle movement, or ECS changes - no asset IDs or selected-state data are changed by filtering - no dependency or version changes Security: - no network or filesystem behavior changes - no executable or credential handling changes - no deployment or publishing changes Validation: - parent allowed with forbidden child: parent retained as context and only matching child returned - matching forbidden parent: parent rendered as a normal result - Allowed filter with forbidden child: non-matching child omitted - search for Carriage B under Train A: parent retained as context and child returned - filtered group collapse and re-expand simulation: passed - full staged TSX and SCSS diff review: passed - git diff --check: passed - UI build: deferred until the complete branch validation - Cities: Skylines II runtime validation: not performed
Context: Deferring the pending-change workflow should leave RouteFilterUISystem identical to its pre-feature implementation. Removing the deferred methods also removed an existing terminal blank line, leaving a formatting-only backend diff in the branch. Changes: - restore the original end-of-file spacing in RouteFilterUISystem.cs - eliminate the remaining backend file difference from main Behavior: There is no runtime or UI behavior change. The backend UI system content now matches the main branch exactly after the pending-change workflow removal. Compatibility: - no save format, persistence, pathfinding, gameplay, vehicle movement, or ECS changes - no dependency, version, or localization changes Security: - no network or filesystem behavior changes - no executable or credential handling changes - no deployment or publishing changes Validation: - full staged diff review: passed - git diff main -- Systems/RouteFilterUISystem.cs with the staged content: no differences - git diff --check main: passed - C# build: not performed because Cities: Skylines II assemblies/toolchain are unavailable - Cities: Skylines II runtime validation: not performed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This pull request improves RouteFilter's asset catalog UI with visibility filtering, configurable sorting, more precise grouped-asset behavior, and small robustness and accessibility improvements.
The goal is to make larger vehicle catalogs easier to inspect and manage without changing RouteFilter's restriction persistence, pathfinding, save data, ECS behavior, vehicle movement, or dependency graph. The final effective changes are limited to the catalog UI, its CSS module, and English/Simplified Chinese localization.
Motivation
Larger base-game, content-pack, and custom vehicle catalogs can be difficult to navigate with text search alone. Common tasks include isolating currently forbidden or allowed assets, comparing vehicle parameters, and locating a matching trailer or carriage while retaining its parent context.
This pull request adds those capabilities while preserving the existing restriction model and Apply/Clear/Cancel behavior.
User-facing changes
Visibility filtering
The catalog now supports:
All: all applicable catalog entries;Forbidden: assets in the current selected/restricted set;Allowed: assets not in that set.Visibility and text search are evaluated together. Changing search, visibility, sorting, or target transport resets pagination to the first page. Display filtering does not modify the selected set.
Sorting
The catalog can be sorted by Name, Maximum speed, Acceleration, or Braking in ascending or descending order.
Root assets are sorted before pagination. Numeric fields use numeric comparison. Name comparison is case-insensitive with asset ID as a deterministic tie-breaker. Sorting copies the root array instead of mutating React-derived catalog arrays.
Grouped parent/child assets
When a child matches but its parent does not, the parent remains visible only as structural context:
Root detection uses a memoized
Setof relevant IDs for constant-time parent lookup. Children use predictable case-insensitive name ordering.Selected-asset parsing
The comma-separated
selectedAssetIdsbinding now trims tokens, removes empty values before numeric conversion, and retains only integer IDs. This prevents an empty binding from producing artificial ID0throughNumber("").Validated behavior:
Accessibility and localization
Asset restriction and refresh controls now use localized accessibility labels instead of hardcoded English-only labels. All new player-facing controls are available in English and Simplified Chinese.
Final localization parity: 36 used RouteFilter UI keys, 36 registered keys, no missing or unused relevant keys.
Implementation notes
Set<number>;classNames, CSS modules, and existingcs2/uiintegration;Development-history note
An experimental pending-change indicator and revert workflow was implemented during development. Static review showed that reliably validating its baseline behavior requires live Cities: Skylines II restriction buffers and unavailable-asset behavior.
That workflow was fully removed in a later commit before submission. The final effective diff contains no pending binding, applied-selection baseline, revert trigger, pending/revert UI, localization, CSS, or backend synchronization logic. The commits remain visible because development history was intentionally not rebased, squashed, or rewritten.
Effective scope
The final diff contains only:
Setting.csUI/src/routeFilterUI.tsxUI/src/routeFilterUI.module.scssSystems/RouteFilterUISystem.cshas no effective difference frommain.This pull request does not modify package files or lockfiles, dependencies, save serialization, restriction persistence, pathfinding, vehicle movement, ECS components, mod version, releases, GitHub Actions, deployment, or publishing configuration.
Validation
e318ff6a04b480b7991f8e83202cceb0c5243cbegit diff --check main...HEADnode node_modules/typescript/bin/tsc --noEmitnpm run build5.97.1compiled successfullyUI/build5.97.1; chrome-trace-event1.0.4Static review also found no conditional hooks, direct
Setstate mutation, source-array mutation by root sorting, invalid React keys, or CRITICAL/HIGH issue.Build and runtime limitations
C# build was not performed because the required Cities: Skylines II assemblies/toolchain are unavailable in the contributor environment.
Cities: Skylines II runtime validation was not performed.
Visual validation inside the game was not performed.
Validation was limited to static review, TypeScript strict compilation, logical behavior tests, localization/CSS parity, a webpack production build, and Git diff checks. Runtime and visual testing require a maintainer or contributor with Cities: Skylines II.
Relationship to PR #4
Upstream
mainseparately contains an invalid lock entry for unpublishedchrome-trace-event@1.0.5. That pre-existing installation issue is addressed by PR #4,fix(build): restore valid chrome-trace-event lock entry.This feature PR intentionally does not duplicate the lockfile correction. If CI fails specifically because
npm cireceives HTTP 404 forchrome-trace-event@1.0.5, that failure originates from the upstream lockfile and is addressed separately by PR #4.Suggested review order
Setting.cs.routeFilterUI.tsx.