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

Fix conditionally required property not applying #2228

Open
wants to merge 13 commits into
base: master
Choose a base branch
from

Conversation

gatanasov-asteasolutions

This PR fixes the long lasting problem of having conditionally required properties in the schema that do not show as required in the UI. It addresses issue #1390.

Fix the isRequired function's required check when having conditional
subschemas - whether it is a single if-the-else or multiple if-then-else
inside allOf combinator.
Make the if condition work with pattern and fix the check to work with
nested properties
…equired

Fix conditional required not applying
Copy link

netlify bot commented Dec 13, 2023

Deploy Preview for jsonforms-examples ready!

Name Link
🔨 Latest commit ec4273a
🔍 Latest deploy log https://app.netlify.com/sites/jsonforms-examples/deploys/659e7f31b463c60009a9121c
😎 Deploy Preview https://deploy-preview-2228--jsonforms-examples.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site configuration.

@CLAassistant
Copy link

CLAassistant commented Dec 13, 2023

CLA assistant check
All committers have signed the CLA.

@gatanasov-asteasolutions gatanasov-asteasolutions changed the title Fix conditionally required property not applying #1390 Fix conditionally required property not applying Dec 13, 2023
@coveralls
Copy link

coveralls commented Dec 13, 2023

Coverage Status

coverage: 85.591% (+2.5%) from 83.078%
when pulling ec4273a on gatanasov-asteasolutions:master
into b00754c on eclipsesource:master.

@sdirix
Copy link
Member

sdirix commented Dec 14, 2023

Thank you very much for the contribution ❤️. We will soon take a look.

@sdirix sdirix force-pushed the master branch 2 times, most recently from 8bd14c2 to e9946ef Compare December 15, 2023 16:07
Copy link
Member

@sdirix sdirix left a comment

Choose a reason for hiding this comment

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

Thanks for this interesting contribution!!

Technically speaking, what this PR is missing is a set of unit tests, testing the new functionality in detail.

Conceptionally this is breaking new grounds for JSON Forms as this introduces dynamic evaluation mechanism which we do not do yet. This is potentially expensive and will be executed with every render call. I'm wondering whether we should

  • make this behavior optional (default: false), and/or
  • introduce a generic prop-adaption mechanism. Then this "advanced" required analysis could be manually configured by the user if they need it.
    • Of course then we could already provide this adapter for them.

Once we introduce this, there will be a lot of follow up requests. For example it's a bit arbitrary that we only do this for required and not for other attributes too, e.g. title. So I'm leaning a bit to the generic prop-adaption mechanism which would allow for arbitrary behavior while keeping JSON Forms itself slim.

What do you think?

Comment on lines 93 to 101
if (has(propertyCondition, 'const')) {
return (
has(data, property) && data[property] === get(propertyCondition, 'const')
);
} else if (has(propertyCondition, 'enum')) {
return (
has(data, property) &&
(get(propertyCondition, 'enum') as unknown[]).includes(data[property])
);
Copy link
Member

Choose a reason for hiding this comment

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

These will only work when values are primitives. If a value is an object these comparisons will fail. We should probably use lodash's isEqual here to cover the more complex use cases too.

Choose a reason for hiding this comment

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

You are right, there were other places as well where it was needed to compare the values with isEqual. It is fixed in my latest commit.

Comment on lines +248 to +251
const ifInThen = has(get(schema, 'then'), 'if');
const ifInElse = has(get(schema, 'else'), 'if');
const allOfInThen = has(get(schema, 'then'), 'allOf');
const allOfInElse = has(get(schema, 'else'), 'allOf');
Copy link
Member

Choose a reason for hiding this comment

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

This seems a bit too hardcoded. I would prefer if the logic could be generalized. For example anyOf and oneOf are not checked here.

Choose a reason for hiding this comment

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

anyOf and oneOf are not checked, because they are not part of the conditionally required logic. We are only interested in required in the then and else clauses of if and allOf is used as a method of having multiples if-s in the schema.

Comment on lines 85 to 86
import { has } from 'lodash';
import { all, any } from 'lodash/fp';
Copy link
Member

Choose a reason for hiding this comment

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

We use the modular imports of lodash, see line 83,84.

Choose a reason for hiding this comment

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

I see, I have changed it in my latest commit.

@gatanasov-asteasolutions
Copy link
Author

gatanasov-asteasolutions commented Jan 8, 2024

I'm wondering whether we should

  • make this behavior optional (default: false), and/or

  • introduce a generic prop-adaption mechanism. Then this "advanced" required analysis could be manually configured by the user if they need it.

    • Of course then we could already provide this adapter for them.

Once we introduce this, there will be a lot of follow up requests. For example it's a bit arbitrary that we only do this for required and not for other attributes too, e.g. title. So I'm leaning a bit to the generic prop-adaption mechanism which would allow for arbitrary behavior while keeping JSON Forms itself slim.

What do you think?

The most appropriate place for me to add this toggle of these dynamic checks is the config property of the JsonForms component. It is an easy way to provide the users with the option to enable them only on specific schemas, just like they can use it to disable the asterisk. Also they can use the same property to enable future dynamic checks for other fields, if there appear to be any. I have added this functionality in my latest commit.

…ditionally-required

Add tests for conditionally required logic. Also make the whole dynamic check optional based on the `allowDynamicChecks` property of the `config` parameter of the `JsonForms` component.
@sdirix
Copy link
Member

sdirix commented Jan 24, 2024

Hi @gatanasov-asteasolutions, we were currently busy with the 3.2 release. We will discuss this proposal and what we think what the best way forward is within the team in the upcoming weeks and let you know.

In the mean time:

  • If you would like to contribute the "prop-adaption" mechanism to accomplish this feature for your renderers in a convenient way, then feel free to do so
  • If you would like to already consume your contributed mechanism, then you can do so via custom renderers. In there you can call the current bindings of JSON Forms and then just apply the "conditionally required property" evaluation on top.

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.

None yet

4 participants