-
Notifications
You must be signed in to change notification settings - Fork 2.5k
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
Create form field number #8634
Create form field number #8634
Conversation
...-front/src/modules/object-record/record-field/form-types/components/FormNumberFieldInput.tsx
Outdated
Show resolved
Hide resolved
...-front/src/modules/object-record/record-field/form-types/components/FormNumberFieldInput.tsx
Outdated
Show resolved
Hide resolved
...-front/src/modules/object-record/record-field/form-types/components/FormNumberFieldInput.tsx
Outdated
Show resolved
Hide resolved
...-front/src/modules/object-record/record-field/form-types/components/FormNumberFieldInput.tsx
Show resolved
Hide resolved
5c9f0fc
to
ca5fbe5
Compare
packages/twenty-front/src/modules/workflow/components/WorkflowFormTextFieldInput.tsx
Outdated
Show resolved
Hide resolved
Functional testing observations
|
@martmull this is a discussion we got 👍 This is the current behavior of our Boolean field, this is why we kept the same. It should not be seen as a primitive boolean field but more as a True/False field. If the user needs a 3 options field (like null, false, true) he can still use the select field for this. |
...-front/src/modules/object-record/record-field/form-types/components/FormNumberFieldInput.tsx
Show resolved
Hide resolved
...wenty-front/src/modules/object-record/record-field/form-types/hooks/useTextVariableEditor.ts
Show resolved
Hide resolved
packages/twenty-front/src/modules/workflow/components/WorkflowFormFieldInputBase.tsx
Outdated
Show resolved
Hide resolved
packages/twenty-front/src/modules/workflow/components/WorkflowFormTextFieldInput.tsx
Outdated
Show resolved
Hide resolved
packages/twenty-front/src/modules/workflow/components/WorkflowFormTextFieldInput.tsx
Outdated
Show resolved
Hide resolved
...es/twenty-front/src/modules/workflow/search-variables/components/SearchVariablesDropdown.tsx
Outdated
Show resolved
Hide resolved
packages/twenty-front/src/modules/workflow/search-variables/components/VariableTagInput.tsx
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey nice job, some comments
...front/src/modules/object-record/record-field/form-types/components/FormBooleanFieldInput.tsx
Outdated
Show resolved
Hide resolved
Input={ | ||
<StyledBooleanInputContainer> | ||
<BooleanInput | ||
value={draftValue as boolean} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we should remove as boolean
and use a format to boolean utils
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's an important subject, and we should discuss it first. There are two policies: either we cast values to the type we expect or discard values that don't match their expected type. By casting, I mean doing things like this: String(mightBeAStringOrSomethingElse)
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should be sure that draftValue is a boolean
defaultValue, | ||
placeholder, | ||
onPersist, | ||
multiline, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
looks like multiline is not used. If not used we should remove it and related code
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure to understand why multiline wouldn't be used. It appears to be used multiple times in the commend for me. Am I missing something?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
By saying not used, i mean i don't see any component that set this multiline parameter to true:
<ComponentUsingMultilineTrue
...
multiline
...
/>
Did I miss one of them?
packages/twenty-front/src/modules/workflow/components/WorkflowFormFieldInputBase.tsx
Outdated
Show resolved
Hide resolved
) : ( | ||
<StyledVariableContainer> | ||
<SortOrFilterChip | ||
labelValue={extractVariableLabel(draftValue as string)} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we should remove as string
}; | ||
|
||
const handleChange = (newText: string) => { | ||
setDraftValue(newText); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think
if (!canBeCastAsNumberOrNull(newValue)) {
return;
}
should be used here!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we should also check for decimal and return if there is any
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I duplicated the logic of the NumberFieldInput file; I'm unsure if we want to behave differently than this component.
onPersist(false); | ||
}} | ||
onVariableTagInsert={(variable) => { | ||
setDraftValue(variable); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we should check that variable is a boolean or not, and only set if boolean. That should be possible as variable type is provided in outputSchema
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can improve this in another PR. However, it will require many changes, which we must consider beforehand.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Created another issue to track that: #8787.
onPersist(null); | ||
}} | ||
onVariableTagInsert={(variable) => { | ||
setDraftValue(variable); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we should check that variable has a type number, the best would be to remove the option in variable dropdown
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As mentioned here, I think we can check it later: #8634 (comment).
packages/twenty-front/src/modules/workflow/search-variables/utils/initializeEditorContent.ts
Outdated
Show resolved
Hide resolved
|
||
export const extractVariableLabel = (rawVariable: string) => { | ||
const variableWithoutBrackets = rawVariable.replace( | ||
/\{\{([^{}]+)\}\}/g, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we use REGEX_VARIABLE_TAG
here? I don't get the functional difference between the 2 regex
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This regex captures what's inside brackets. The other one also captures brackets. We could refactor it to use a single regex.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok nice, lets refactor then
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tried to reduce the number of regexes created to deal with variables, but every regex has a specific behavior, and I don't think it's excellent to unify them. We could make a one-size-fits-all regex, but it will necessarily be more complex and less readable, as well as the code using the regex. I think it's better to keep specialized regexes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Devessier I am not sure to get the full picture here. I was expecting an architecture like:
- Primitive input (Boolean, Number, Text) that would be a common base for Form Field Input and Field Input
- Primitive form field input (BooleanFormFieldInput, NumberFormFieldInput...)
- Global component FormFieldInput to switch on it
- WorkflowFormFieldInput that send the update functions, the variable component as right element and call the FormFieldInput as main input component.
- Hard to implement for tiptap, so we could have a special WorkflowFormFieldInputWithTipTap (not the real component name)
In your code:
- I do not see FormFieldInput actually used? To me it was supposed to be the base for workflow forms but also the futur forms without variables we will have to implement
- It seems that we will have to add a WorkflowFieldInput for each type. But except for text using tiptap, isn't the logic to store value and use variables always the same?
Happy to discuss the architecture, maybe this is unrealistic. I would also like your opinion @lucasbordeau @charlesBochet
I'm unsure how we could have a standalone Let's take The We could find solutions to reuse standalone components and enhance them with variables, but I wonder if this is the simplest way. I prefer some duplication of templating code (like creating more components) to trying to make things work together and finding in two weeks that one component shouldn't work the same way in workflows as it does in usual forms. Furthermore, we don't yet have a use case for |
Input={ | ||
<StyledInput | ||
placeholder={placeholder} | ||
value={String(draftValue)} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To remain consistent with the codebase
value={String(draftValue)} | |
value={`${draftValue}`} |
<StyledInput | ||
inputId={inputId} | ||
placeholder={placeholder} | ||
value={String(draftValue)} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same value={${...}
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Amazing work @Devessier!! 💪 🔥
Let's wait for @lucasbordeau review but LGTM!
...-front/src/modules/object-record/record-field/form-types/components/SelectedVariableChip.tsx
Outdated
Show resolved
Hide resolved
const currentValue = formData[field.name] as JsonValue; | ||
|
||
return ( | ||
<FormFieldInput |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
😍
}, | ||
}); | ||
|
||
const handleVariableTagInsert = (variable: string) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we avoid using just "variable" alone, either variableValue
, variableContent
or variableName
? As a first-time reader I don't clearly understand, which for this "meta" part of the code is important.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes 👌 Done.
...nty-front/src/modules/object-record/record-field/form-types/types/VariablePickerComponent.ts
Outdated
Show resolved
Hide resolved
...es/twenty-front/src/modules/workflow/search-variables/components/SearchVariablesDropdown.tsx
Outdated
Show resolved
Hide resolved
786c826
to
4e5dc98
Compare
…ble to take a variable picker
4e5dc98
to
fe39cfa
Compare
Thanks @Devessier for your contribution! |
Notes
Design decisions
Our main challenge was for variables and inputs to be able to communicate between each other. We chose an API that adds some duplication but remains simple and doesn't rely on "hacks" to work. Common styles are centralized.
Demo
"Workflow" mode with variables:
FormFieldInput mode, without variables:
Behavior difference between fields that can contain variables and static content, and inputs that can have either a variable value or a static value: