Skip to content

Add support for nested property names of same value#40

Open
doneill wants to merge 2 commits intodevelopfrom
39-nested-prop-names
Open

Add support for nested property names of same value#40
doneill wants to merge 2 commits intodevelopfrom
39-nested-prop-names

Conversation

@doneill
Copy link
Copy Markdown
Collaborator

@doneill doneill commented May 1, 2026

Adds support for #39

Proposed Changes

src/v2/utils.ts

  • createControl
    • added optional collectionId?: string parameter
  • generateCollectionUISchemaInternal
    • added required collectionId: string parameter

src/v2/mockData.ts

  • Updated to the new server format

v2.test.ts

  • Added a test that specifically validates the collision scenario
    • a top-level name field and a sightings.name collection item field sharing the same property name, each correctly resolving to their own ui.fields entry via the qualified ID

Implementation Test

In React Native client app, e.g. EarthRanger

- yarn remove @earthranger/react-native-jsonforms-formatter
- yarn add @earthranger/react-native-jsonforms-formatter@2.0.0-beta.26
  • Verify the app continues to display forms correctly where the same property name exists at multiple levels in a collection field and confirm each level gets its own property

Unit Tests

jest test/v2.test.ts
 PASS  test/v2.test.ts
  V2 generateUISchema
    ✓ should generate UI schema for basic V2 schema (3 ms)
    ✓ should create controls with proper scopes and labels (1 ms)
    ✓ should handle text field options correctly
    ✓ should handle numeric field options correctly
    ✓ should handle choice list field options correctly
    ✓ should handle date-time field options correctly (1 ms)
    ✓ should handle location field options correctly
    ✓ should handle collection field options correctly
    ✓ should exclude deprecated fields
    ✓ should handle inactive sections
    ✓ should respect section order
    ✓ should handle collection constraints and column layout
    ✓ should handle single column sections correctly
    ✓ should handle two column sections correctly (React Native single-column)
    ✓ should apply UI field properties to collection item fields
    ✓ should resolve same-named fields at different nesting levels using qualified ids
    ✓ should support nested collections (collection within collection) (1 ms)
  BOOLEAN field type
    ✓ generates a Control with boolean format
    ✓ includes the description in options
    ✓ deprecated boolean field is not rendered

Test Suites: 1 passed, 1 total
Tests:       20 passed, 20 total
Snapshots:   0 total
Time:        0.451 s, estimated 1 s

Copilot AI review requested due to automatic review settings May 1, 2026 19:51
@doneill doneill self-assigned this May 1, 2026
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds support for disambiguating same-named fields that exist at different nesting levels (notably within collections) by allowing ui.fields entries to be resolved via qualified IDs (e.g., sightings.name) instead of only local property names.

Changes:

  • Extend createControl / generateCollectionUISchemaInternal to propagate and use a collectionId so collection-item ui.fields can be resolved via qualified IDs.
  • Update V2 mock schema data to match the new server format using qualified field IDs for collection item fields.
  • Add a unit test covering the collision scenario (top-level name vs. sightings[].name).

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

File Description
test/v2.test.ts Adds a regression test validating correct resolution of same-named fields via qualified IDs.
src/v2/utils.ts Implements qualified-id lookup for collection item UI field configuration and propagates collectionId for nested collections.
src/v2/mockData.ts Updates mock V2 schema ui.fields and collection column entries to use qualified IDs.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/v2/utils.ts
Comment on lines +377 to 388
const qualifiedId = `${collectionId}.${localName}`;
const itemUiField = schema.ui.fields[qualifiedId] ?? schema.ui.fields[localName];

if (itemUiField) {
return createControl(
fieldName,
localName,
property as V2Property,
itemUiField,
schema,
undefined,
qualifiedId,
);
Copy link

Copilot AI May 1, 2026

Choose a reason for hiding this comment

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

itemUiField falls back to schema.ui.fields[localName] when the qualified entry is missing. In schemas with same-named fields at different levels, this can still accidentally pick up an unrelated UI config (e.g., the top-level name) and apply it to a collection item field, effectively reintroducing the collision when only one side is qualified. Consider restricting the fallback to cases where the unqualified field's parent matches the current collection (e.g., itemUiField.parent === collectionId or === collectionId.split('.').pop()) so an unrelated top-level field config is not applied to collection items.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants