jsonforms icon indicating copy to clipboard operation
jsonforms copied to clipboard

Value-based Enum Filters

Open tulrichtrimble opened this issue 1 year ago • 1 comments

Is your feature request related to a problem? Please describe.

The lack of support for Conditional Subschemas is understandable per the comments in #1772, but the need remains to handle a data hierarchy where the schema is consistent, but the allowed values are dependent on those already set.

Take a typical accounting structure

  graph TD;
      Company1-->CostCenter-A;
      Company1-->CostCenter-B;
      Company1-->CostCenter-C;
      Company2-->CostCenter-B;
      Company2-->CostCenter-C;
      Company2-->CostCenter-D;

The only valid CostCenters for Company1 are A, B, C. For Company2 it's B, C, and D.

This may be represented with the following schema:

{
    "$schema": "http://json-schema.org/draft-07/schema#",
    "type": "object",
    "properties": {
        "companies": {
            "type": "array",
            "items": {
                "type": "object",
                "properties": {
                    "company": {
                        "type": "string",
                        "enum": [
                            "Company1",
                            "Company2"
                        ]
                    },
                    "cost-centers": {
                        "type": "array",
                        "uniqueItems": true,
                        "items": {
                            "type": "object",
                            "properties": {
                                "cost-center": {
                                    "enum": ["cost-center-a", "cost-center-b", "cost-center-c", "cost-center-d"]
                                }
                            },
                            "required": [
                                "cost-center"
                            ]
                        }
                    }
                },
                "uniqueItems": true
            },
            "required": [
                "company",
                "cost-centers"
            ],
            "allOf": [
                {
                    "if": {
                        "properties": {
                            "company": {
                                "const": "Company1"
                            }
                        }
                    },
                    "then": {
                        "properties": {
                            "cost-centers": {
                                "items": {
                                    "properties": {
                                        "cost-center": {
                                            "enum": ["cost-center-a", "cost-center-b", "cost-center-c"]
                                        }
                                    }
                                }
                            }
                        }
                    }
                },
                {
                    "if": {
                        "properties": {
                            "company": {
                                "const": "Company2"
                            }
                        }
                    },
                    "then": {
                        "properties": {
                            "cost-centers": {
                                "items": {
                                    "properties": {
                                        "cost-center": {
                                            "enum": ["cost-center-d", "cost-center-b", "cost-center-c"]
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            ]
        }
    },
    "required": [
        "companies"
    ]
}

But all cost centers are available to all companies.

Describe the solution you'd like

Perhaps the UISchema conditional rendering might be leveraged to filter possible values:

{
    "type": "VerticalLayout",
    "elements": [
        {
            "type": "Control",
            "scope": "#/properties/companies/",
            "label": "Company"
        },
        {
            "type": "Data",
            "scope": "#/properties/companies/items/properties/cost-centers/items/properties/cost-center/",
            "rule": {
                "effect": "FILTER",
                "include": ["cost-center-a","cost-center-b","cost-center-c"],
                "condition": {
                    "scope": "#/properties/companies/items/properties/company",
                    "value": "Company1"
                }
            }
        }
    ]
}

Describe alternatives you've considered

We are contemplating inspecting the if/then/else of the schema directly within a custom renderer, but any recommended approach would be welcomed.

Framework

React

RendererSet

Material

Additional context

No response

tulrichtrimble avatar May 20 '24 22:05 tulrichtrimble