Skip to content

Add grouping and override filtering to the config editor list - #24

Merged
duncan-daydream merged 10 commits into
mainfrom
duncan/config-editor-ux-improvements
Jul 27, 2026
Merged

duncan-daydream merged 10 commits into
mainfrom
duncan/config-editor-ux-improvements

Conversation

@duncan-daydream

@duncan-daydream duncan-daydream commented Jul 22, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • Adds ConfigVariableGroup/GroupMetadataKey metadata so config variables can be grouped into labeled sections in the editor list, with ungrouped variables collected into a separate section.
  • Updates the sample app's ContentViewModel to demonstrate grouping
  • Improves Variable List view UX:
    • The list can be filtered to show only variables with overrides
    • Row items take up less vertical space

Variable Grouping

RocketSim_Screenshot_iPhone_17_Pro_6 3_2026-07-22_16 16 56_converted

List Filtering

RocketSim_Screenshot_iPhone_17_Pro_6 3_2026-07-22_16 16 34_converted RocketSim_Screenshot_iPhone_17_Pro_6 3_2026-07-22_16 16 39_converted

duncan-daydream and others added 7 commits July 22, 2026 13:07
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Replaces the [(group: ConfigVariableGroup?, items: ...)] array, which used
a nil group as a sentinel for ungrouped items, with a GroupedVariables
typealias splitting grouped sections from the remainder.
@duncan-daydream
duncan-daydream marked this pull request as ready for review July 22, 2026 20:26
@github-actions

github-actions Bot commented Jul 22, 2026

Copy link
Copy Markdown

Code Coverage Report

Overall Coverage: 96.99% (3,388 of 3,493)

DevConfiguration: 96.99% (3,388 of 3,493)
File Coverage Covered Lines Executable Lines
CodableValueRepresentation.swift 100.00% 86 86
ConfigContent+Additions.swift 100.00% 137 137
ConfigSnapshot+ConfigContent.swift 100.00% 22 22
ConfigVariable.swift 100.00% 84 84
ConfigVariableAccessFailedEvent.swift 100.00% 4 4
ConfigVariableAccessSucceededEvent.swift 100.00% 5 5
ConfigVariableContent.swift 96.03% 1,936 2,016
ConfigVariableDecodingFailedEvent.swift 100.00% 5 5
ConfigVariableMetadata.swift 100.00% 30 30
ConfigVariableReader.swift 95.61% 196 205
DisplayNameMetadataKey.swift 100.00% 2 2
EditorControl.swift 100.00% 24 24
EditorDocument.swift 98.50% 395 401
EditorOverrideProvider.swift 98.75% 315 319
EventBusAccessReporter.swift 100.00% 32 32
GroupMetadataKey.swift 100.00% 8 8
IsEditableMetadataKey.swift 100.00% 2 2
Localization.swift 50.00% 3 6
NamedConfigProvider.swift 100.00% 5 5
RegisteredConfigVariable.swift 96.77% 90 93
String+NonEmptyTrimmedLines.swift 100.00% 7 7

}
}
}
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

So we don’t want to do grouping in the filtered view?

I would think 1) we should, and 2) that would actually make this code a bit simpler. We could do filtering in the view model and the view code is simple.

@duncan-daydream duncan-daydream Jul 23, 2026

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

🤷‍♂️

If you have lots of groups, but not a lot of overrides, the section headers produce a lot of visual clutter (obviously we'd hide empty sections)

On the other hand, if you have lots of overrides, you do lose some navigability by hiding the sections.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Another solution (that I don't love) would be to make grouping a second toggle.

/// ConfigVariable(key: "api.timeout", defaultValue: 30)
/// .metadata(\.group, .networking)
///
public struct ConfigVariableGroup: Hashable, Sendable, Comparable {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This feels like a text book TypedExtensibleEnum to me.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

🤔 For some reason I thought we got ride of TypdExtensibleEnum in DevFoundation


static func displayText(for value: ConfigVariableGroup?) -> String? {
value?.rawValue
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I believe you get this implementation for free.

From ConfigVariableMetadata.swift:220-224:

extension ConfigVariableMetadataKey where Value: OptionalRepresentable, Value.Wrapped: RawRepresentable<String> {
    public static func displayText(for value: Value) -> String? {
        return value.optionalRepresentation.map { $0.rawValue }
    }
}

Combines grouping and override/search filtering into one view model
property so the view no longer needs to branch on showOverridesOnly or
reason about "remainder" groups and empty-section checks; section
titles are now fully resolved by the view model.
Adopts the shared TypedExtensibleEnum protocol instead of hand-rolling
Hashable/Sendable conformance, and drops the now-redundant
displayText(for:) override.
@duncan-daydream

Copy link
Copy Markdown
Collaborator Author

Updated toolbar behavior:

RocketSim_Recording_iPhone_17_6.3_2026-07-26_21.43.44_converted.mp4

@duncan-daydream
duncan-daydream merged commit 29e8e06 into main Jul 27, 2026
6 checks passed
@duncan-daydream
duncan-daydream deleted the duncan/config-editor-ux-improvements branch July 27, 2026 16:19
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.

2 participants