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

Pro 6799 design default values invisible fields #4816

Open
wants to merge 28 commits into
base: main
Choose a base branch
from

Conversation

ValJed
Copy link
Contributor

@ValJed ValJed commented Nov 26, 2024

PRO-6528

Summary

  • Adds control over when fields are ready and can be validated, by handling a new fieldReady property for each field.
    Must work with async fields like dynamic choices, being able to set a field not ready during fetching and ready when operation is finished.
  • Reworks schema level convert method. Check errors only when on root convert method to have access to the finale destination object to be able to check non visible fields, as well as non visible parents. No more order problem..

What are the specific steps to test this change?

Cypress tests 🟢

What kind of change does this PR introduce?

  • Bug fix
  • New feature
  • Refactor
  • Documentation
  • Build-related changes
  • Other

Make sure the PR fulfills these requirements:

  • It includes a) the existing issue ID being resolved, b) a convincing reason for adding this feature, or c) a clear description of the bug it resolves
  • The changelog is updated
  • Related documentation has been updated
  • Related tests have been updated

If adding a new feature without an already open issue, it's best to open a feature request issue first and wait for approval before working on it.

Other information:

@ValJed ValJed self-assigned this Nov 26, 2024
@ValJed ValJed marked this pull request as draft November 26, 2024 13:31
Copy link
Member

@boutell boutell left a comment

Choose a reason for hiding this comment

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

I like where you're going with this.

@@ -632,6 +632,15 @@ module.exports = {
}
);
} catch (error) {
const isVisible = isParentVisible === false
Copy link
Member

Choose a reason for hiding this comment

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

Thank you, I did wonder if there was a cleaner way.

@@ -263,15 +266,15 @@ export default {
// updating. This is only really a concern in editors that can swap
// the active doc/object without unmounting AposSchema.
this.$nextTick(() => {
this.schemaReady = true;
/* this.schemaReady = true; */
Copy link
Member

Choose a reason for hiding this comment

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

We generally do not use this comment syntax, but maybe you're relying on it to remind you to go back.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is a draft PR, so not ready for review, it's just for me to have a global vision on my work.

@ValJed ValJed force-pushed the pro-6799-design-default-values-invisible-fields branch 2 times, most recently from 6de153c to 9bbcd21 Compare November 26, 2024 17:22
const errorsList = [];
const isCurrentVisible = isParentVisible === false
? false
: await self.isVisible(req, schema, data, field.name);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Notable difference here (previous versions might be buggy). We pass data instead of destination because destination is not fully built at this point.
I think isVisible should compare data as they have been set by the user and not the potential default values.
Tests are green with it but you might have some reasons to not allow this.
Let me know.

Copy link
Member

Choose a reason for hiding this comment

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

Data can be unvalidated stuff of unexpected types etc., it could be anything. Trusting it is problematic. You might get away with that in isVisible because you're not saving the values, but then isVisible must be written carefully to not assume the values are at all well-formed, for instance it must not assume string fields are actually strings yet, etc. because nothing has been validated.

Copy link
Contributor

Choose a reason for hiding this comment

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

data might contains obsolete values.
You can also have preventFieldsOnly set to true meaning destination will only contains partial fields.
We should think about these and if it has any impact on your implementation.

@ValJed ValJed marked this pull request as ready for review November 27, 2024 13:17
@ValJed ValJed requested review from boutell and haroun November 27, 2024 13:17
handler() {
this.updateNextAndEmit();
}
},
Copy link
Contributor Author

Choose a reason for hiding this comment

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

We don't need a deep watch here, we can simply call the method when v-model updates fieldState, see above change.

@@ -52,6 +52,7 @@
:server-error="fields[field.name].serverError"
:doc-id="docId"
:generation="generation"
@update:model-value="updateNextAndEmit"
Copy link
Contributor Author

Choose a reason for hiding this comment

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

With this, no more need for a deep watcher.

Copy link
Contributor

Choose a reason for hiding this comment

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

Why not on the compare meta version?

} else {
this.next.data[field.name] = this.modelValue.data[field.name];
}
});
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Only indentation in this block

Copy link
Member

@boutell boutell left a comment

Choose a reason for hiding this comment

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

It is possible that changes are not necessary but see my note here about trusting data, isVisible must be written very defensively if it is going to see unvalidated user input.

const errorsList = [];
const isCurrentVisible = isParentVisible === false
? false
: await self.isVisible(req, schema, data, field.name);
Copy link
Member

Choose a reason for hiding this comment

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

Data can be unvalidated stuff of unexpected types etc., it could be anything. Trusting it is problematic. You might get away with that in isVisible because you're not saving the values, but then isVisible must be written carefully to not assume the values are at all well-formed, for instance it must not assume string fields are actually strings yet, etc. because nothing has been validated.

@@ -52,6 +52,7 @@
:server-error="fields[field.name].serverError"
:doc-id="docId"
:generation="generation"
@update:model-value="updateNextAndEmit"
Copy link
Contributor

Choose a reason for hiding this comment

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

Why not on the compare meta version?

const errorsList = [];
const isCurrentVisible = isParentVisible === false
? false
: await self.isVisible(req, schema, data, field.name);
Copy link
Contributor

Choose a reason for hiding this comment

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

data might contains obsolete values.
You can also have preventFieldsOnly set to true meaning destination will only contains partial fields.
We should think about these and if it has any impact on your implementation.

@ValJed ValJed force-pushed the pro-6799-design-default-values-invisible-fields branch 4 times, most recently from f0a8ef6 to 3fe5a9c Compare December 9, 2024 18:24
@ValJed ValJed force-pushed the pro-6799-design-default-values-invisible-fields branch from 52e6290 to 2341d53 Compare December 10, 2024 09:02
@ValJed ValJed requested review from boutell and haroun December 10, 2024 09:20
@ValJed
Copy link
Contributor Author

ValJed commented Dec 10, 2024

@boutell @haroun Code could be cleaned but I would like your opinion on the general direction.

destination,
destinationPath = '',
hiddenAncestors = false
}) {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This method might be moved somewhere else

}

if (typeof error !== 'string') {
self.apos.util.error(error.path + '\n' + error.stack);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Makes sense to me to show what field failed, error path being the name.

Copy link
Member

Choose a reason for hiding this comment

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

I think it is better to log this detail later when logging the overall error. But I wouldn't die on that hill.

Will the error type ever be a string? I believe that went away in A3/A4...

Copy link
Member

Choose a reason for hiding this comment

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

I guess it's smart to check.

Copy link
Member

@boutell boutell left a comment

Choose a reason for hiding this comment

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

I like the general strategy. Still think it makes more sense to set aposPath on each field just once in schema.validate and its related functions.

@@ -7,6 +7,8 @@
* Focus properly Widget Editor modals when opened. Keep the previous active focus on the modal when closing the widget editor.
* a11y improvements for context menus.
* Fixes broken widget preview URL when the image is overridden (module improve) and external build module is registered.
* In th schema convert method, we wait all sub convert to run, to have access to the final destination object in order to check if
Copy link
Member

Choose a reason for hiding this comment

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

typo

} = {}
) {
const options = {
fetchRelationships,
ancestors,
isParentVisible
ancestorSchemas,
ancestorPath
Copy link
Member

Choose a reason for hiding this comment

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

I think it is better to compute the aposPath of a field once, in the validate method of schema and its related functions, rather than pushing this boulder up the hill on each convert call 🪨

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes good point. We agree that we are talking about the schema path and not the actual destination one.

}

if (typeof error !== 'string') {
self.apos.util.error(error.path + '\n' + error.stack);
Copy link
Member

Choose a reason for hiding this comment

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

I think it is better to log this detail later when logging the overall error. But I wouldn't die on that hill.

Will the error type ever be a string? I believe that went away in A3/A4...

}

if (typeof error !== 'string') {
self.apos.util.error(error.path + '\n' + error.stack);
Copy link
Member

Choose a reason for hiding this comment

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

I guess it's smart to check.

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.

3 participants