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

[REFACTOR] Split in two distinct forms Settings Object Model page #10653

Merged
merged 32 commits into from
Mar 7, 2025

Conversation

prastoin
Copy link
Contributor

@prastoin prastoin commented Mar 4, 2025

Introduction

This PR contains around ~+300 tests + snapshot additions
Please check both object model creation and edition

Closes twentyhq/core-team-issues#355

Refactored into two agnostic forms the Object Model settings page for instance /settings/objects/notes#settings.

SettingsDataModelObjectAboutForm

Added a new abstraction SettingsUpdateDataModelObjectAboutForm to wrap SettingsDataModelObjectAboutForm in an update context

image
Schema:

const requiredFormFields = objectMetadataItemSchema.pick({
  description: true,
  icon: true,
  labelPlural: true,
  labelSingular: true,
});
const optionalFormFields = objectMetadataItemSchema
  .pick({
    nameSingular: true,
    namePlural: true,
    isLabelSyncedWithName: true,
  })
  .partial();
export const settingsDataModelObjectAboutFormSchema =
  requiredFormFields.merge(optionalFormFields);

SettingsDataModelObjectSettingsFormCard

Update on change
image
Schema:

export const settingsDataModelObjectIdentifiersFormSchema =
  objectMetadataItemSchema.pick({
    labelIdentifierFieldMetadataId: true,
    imageIdentifierFieldMetadataId: true,
  });

Error management and validation schema

Improved the frontend validation form in order to attest that:

  • Names are in camelCase
  • Names are differents
  • Names are not empty string SHOULD BE DONE SERVER SIDE TOO ( will in a next PR, atm it literally breaks any workspace )
  • Labels are differents
  • Labels aren't empty strings

Hide the error messages as we need to decide what kind of styling we want for our errors with forms
( Example with error labels )
image

@prastoin prastoin changed the title Prastoin split object settings model forms [REFACTOR] Split in two distinct forms Settings Object Model page Mar 4, 2025
@prastoin
Copy link
Contributor Author

prastoin commented Mar 4, 2025

Just discovered that we can corrup a workspace by sending an empty pluralNameIdentifier in advanced mode, investigating on this before continuing here

@prastoin
Copy link
Contributor Author

prastoin commented Mar 6, 2025

@greptileai trigger

Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

PR Summary

Here's my review of the changes in this pull request:

This PR refactors the Object Model settings page by splitting it into two distinct forms (SettingsDataModelObjectAboutForm and SettingsDataModelObjectSettingsFormCard) with improved validation and error handling.

Key changes:

  • Added settingsDataModelObjectAboutFormSchema with required fields (description, icon, labels) and optional fields (names, sync settings)
  • Created new SettingsUpdateDataModelObjectAboutForm wrapper component to handle object metadata updates
  • Introduced ReadonlyKeysArray and zodNonEmptyString types for improved type safety
  • Implemented custom validation rules for label/name differences and camelCase formatting
  • Removed debug console.log in SettingsUpdateDataModelObjectAboutForm.tsx that should be cleaned up

The refactoring improves code organization and maintainability, but there are a few items that need attention:

  • Remove console.log statement in SettingsUpdateDataModelObjectAboutForm
  • Consider adding error boundary around form components for better error handling
  • Verify form submission timing with the new onNewDirtyField approach to prevent race conditions

15 file(s) reviewed, 13 comment(s)
Edit PR Review Bot Settings | Greptile

@prastoin
Copy link
Contributor Author

prastoin commented Mar 6, 2025

@greptileai trigger

@prastoin prastoin marked this pull request as ready for review March 6, 2025 12:46
Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

PR Summary

(updates since last review)

This update focuses on refining the validation schema for the Object Model settings page with improved error handling and field validation.

Key changes:

  • Updated settingsDataModelObjectAboutFormSchema.ts to enforce case-insensitive comparison using trim().toLowerCase() for label/name validation
  • Changed description field to use nullish() instead of optional() in form schema
  • Added camelCase validation for nameSingular and namePlural fields using camelCaseStringSchema
  • Implemented zodNonEmptyString validation to prevent empty string values

The changes improve data validation while maintaining clean code structure. Note that server-side empty string validation is still pending implementation.

1 file(s) reviewed, no comment(s)
Edit PR Review Bot Settings | Greptile

@guillim
Copy link
Contributor

guillim commented Mar 6, 2025

I cannot create a new object, even though the "Save" button sounds enabled. I cannot screenshot it because the mouse over disapears, but i cannot
Screenshot 2025-03-06 at 16 01 06

@prastoin
Copy link
Contributor Author

prastoin commented Mar 6, 2025

I cannot create a new object, even though the "Save" button sounds enabled. I cannot screenshot it because the mouse over disapears, but i cannot Screenshot 2025-03-06 at 16 01 06

Lets have a look together, regarding the saving button indeed this was already in place, it not changing its styling when disabled is not very intuitive

const result = settingsDataModelObjectAboutFormSchema.safeParse(input);
expect(result.success).toBe(expectedSuccess);
if (!expectedSuccess) {
expect(result.error).toMatchSnapshot();
Copy link
Contributor

@guillim guillim Mar 6, 2025

Choose a reason for hiding this comment

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

I am new to snapshotting in JEST. Correct me if I am wrong, but this is JEST that created the folder snapshot and its containg file.

Question: UI test tend to be flaky. even though I see in the doc the jest update function, it will break the CI. Are we ok and aware with implementing this as if a unit test ?

Copy link
Contributor Author

@prastoin prastoin Mar 6, 2025

Choose a reason for hiding this comment

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

I am new to snapshotting in JEST. Correct me if I am wrong, but this is JEST that created the folder snapshot and its containg file.

Exactly

Question: UI test tend to be flaky. even though I see in the doc the jest update function, it will break the CI. Are we ok and aware with implementing this ?

I think you're mistaking e2e tests and unit/integrations tests which by definition should be way less flaky ( querying a DOM always is etc etc), but regarding this PR tests suite we should never have flakiness as these are very low level javascript unit tests

Copy link
Contributor

Choose a reason for hiding this comment

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

True. But if we add a field to the form, do we want to break the test ? Answer could be yes, if we consider its a cruacial part. that's my point

Copy link
Contributor Author

@prastoin prastoin Mar 6, 2025

Choose a reason for hiding this comment

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

In my opinion yes, but before the test to fail, TypeScript would also raises regarding test definition itself saying: dude your mocks does not relate my inner types

Note that updating snapshot is pretty easy, but rely on the fact that users will review them
I always tend to snapshot errors because no need to be very strict
Regarding huge data set I'm not a fan, or at least binded with atomic assertion such as done within useDeleteOne.test.ts test suite with Apollo cache

@prastoin
Copy link
Contributor Author

prastoin commented Mar 6, 2025

@guillim Thank you for the advanced mode issue, nice catch ! 🚀 Fixed the form to always have a default value for the isSyncNameLabel which was blocking the creation form submition

Copy link
Contributor

@guillim guillim left a comment

Choose a reason for hiding this comment

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

great job @prastoin !!!

@prastoin prastoin merged commit 776632f into main Mar 7, 2025
47 checks passed
@prastoin prastoin deleted the prastoin-split-object-settings-model-forms branch March 7, 2025 09:14
Weiko pushed a commit that referenced this pull request Mar 11, 2025
# Introduction
This PR contains several SNAPSHOT files explaining big +

While refactoring the Object Model settings page in
#10653, encountered a critical
issue when submitting either one or both names with `""` empty string
hard corrupting a workspace.

This motivate this PR reviewing server side validation

I feel like we could share zod schema between front and back

## Refactored server validation
What to expect from Names:
- Plural and singular have to be different ( case insensitive and
trimmed check )
- Contains only a-z A-Z and 0-9
- Follows camelCase
- Is not empty => Is not too short ( 1 )
- Is not too long ( 63 )
- Is case insensitive( fooBar and fOoBar now rejected )

What to expect from Labels:
- Plural and singular have to be different ( case insensitive and
trimmed check )
- Is not empty => Is not too short ( 1 )
- Is not too long ( 63 )
- Is case insensitive ( fooBar and fOoBar now rejected )

close #10694

## Creation integrations tests
Created new integrations tests, following
[EachTesting](https://jestjs.io/docs/api#testeachtablename-fn-timeout)
pattern and uses snapshot to assert errors message. These tests cover
several failing use cases and started to implement ones for the happy
path but object metadata item deletion is currently broken unless I'm
mistaken @Weiko is on it

## Notes
- [ ] As we've added new validation rules towards names and labels we
should scan db in order to standardize existing values using either a
migration command or manual check
- [ ] Will review in an other PR the update path, adding integrations
tests and so on
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.

[Refactor] Split settings form in two agnostic rhf forms
2 participants