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

feat: Add max and min characters inputs for long text input for booking questions(Minor) #15596

Closed
wants to merge 8 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions apps/web/public/static/locales/en/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -930,6 +930,11 @@
"not_installed": "Not installed",
"error_password_mismatch": "Passwords don't match.",
"error_required_field": "This field is required.",
"min_characters": "Min.Characters",
"max_characters": "Max.Characters",
"error_min_long_text_field": "Min. {{minLength}} Characters",
"error_max_long_text_field": "Max. {{maxLength}} Characters",
"error_min_should_be_less_than_max": "Min Characters value should not be greater than max Characters value",
"status": "Status",
"team_view_user_availability": "View user availability",
"team_view_user_availability_disabled": "User needs to accept invite to view availability",
Expand Down
29 changes: 26 additions & 3 deletions packages/features/bookings/lib/getBookingResponsesSchema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -249,9 +249,32 @@ function preprocess<T extends z.ZodType>({
// Use fieldTypeConfig.propsType to validate for propsType=="text" or propsType=="select" as in those cases, the response would be a string.
// If say we want to do special validation for 'address' that can be added to `fieldTypesSchemaMap`
if (["address", "text", "select", "number", "radio", "textarea"].includes(bookingField.type)) {
const schema = stringSchema;
if (!schema.safeParse(value).success) {
ctx.addIssue({ code: z.ZodIssueCode.custom, message: m("Invalid string") });
let schema = stringSchema;
if (bookingField["min-length"]) {
schema = schema.min(Number(bookingField["min-length"]), {
message: m("error_min_long_text_field"),
});
}
if (bookingField["max-length"]) {
schema = schema.max(Number(bookingField["max-length"]), {
message: m("error_max_long_text_field"),
});
}
const result = schema.safeParse(value);
if (!result.success) {
if (bookingField.type === "textarea") {
result?.error?.errors?.forEach((error) => {
ctx.addIssue({
code: z.ZodIssueCode.custom,
message: error.message,
});
});
} else {
ctx.addIssue({
code: z.ZodIssueCode.custom,
message: m("Invalid string"),
});
}
}
continue;
}
Expand Down
37 changes: 35 additions & 2 deletions packages/features/form-builder/FormBuilder.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,6 @@ export const FormBuilder = function FormBuilder({
const removeField = (index: number) => {
remove(index);
};

return (
<div>
<div>
Expand Down Expand Up @@ -288,6 +287,17 @@ export const FormBuilder = function FormBuilder({
showToast(t("form_builder_field_already_exists"), "error");
return;
}

if (data.type === "textarea" && data["min-length"] && data["max-length"]) {
if (Number(data["min-length"]) > Number(data["max-length"])) {
showToast(t("error_min_should_be_less_than_max"), "error");
return;
}
}
if (data.type !== "textarea") {
delete data["min-length"];
delete data["max-length"];
}
if (fieldDialog.data) {
update(fieldDialog.fieldIndex, data);
} else {
Expand Down Expand Up @@ -438,7 +448,6 @@ function FieldEditDialog({
const variantsConfig = fieldForm.watch("variantsConfig");

const fieldTypes = Object.values(fieldTypesConfigMap);

return (
<Dialog open={dialog.isOpen} onOpenChange={onOpenChange}>
<DialogContent className="max-h-none p-0" data-testid="edit-field-dialog">
Expand Down Expand Up @@ -501,6 +510,30 @@ function FieldEditDialog({
placeholder={t(fieldForm.getValues("defaultPlaceholder") || "")}
/>
) : null}
{fieldType?.isTextType && fieldType.value === "textarea" ? (
<div className="flex justify-between">
<div className="mr-2 w-full">
<InputField
{...fieldForm.register("min-length")}
containerClassName="mt-6 w-full"
label={t("min_characters")}
type="number"
min={1}
max={2000}
/>
</div>
<div className="ml-2 w-full">
<InputField
{...fieldForm.register("max-length")}
containerClassName="mt-6 w-full"
label={t("max_characters")}
type="number"
min={1}
max={2000}
/>
</div>
</div>
) : null}
{fieldType?.needsOptions && !fieldForm.getValues("getOptionsAt") ? (
<Controller
name="options"
Expand Down
13 changes: 12 additions & 1 deletion packages/features/form-builder/FormBuilderField.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,15 @@ export const FormBuilderField = ({

const { hidden, placeholder, label } = getAndUpdateNormalizedValues(field, t);

function handleErrorMessage(message: string | undefined) {
if (field.type === "textarea" && message) {
return (
t(message, { minLength: field["min-length"], maxLength: field["max-length"] }) || t("invalid_input")
);
}
return t(message || "invalid_input");
}

return (
<div data-fob-field-name={field.name} className={classNames(className, hidden ? "hidden" : "")}>
<Controller
Expand Down Expand Up @@ -97,7 +106,7 @@ export const FormBuilderField = ({
data-testid={`error-message-${field.name}`}
className="mt-2 flex items-center text-sm text-red-700 ">
<Icon name="info" className="h-3 w-3 ltr:mr-2 rtl:ml-2" />
<p>{t(message || "invalid_input")}</p>
<p>{handleErrorMessage(message)}</p>
</div>
);
}}
Expand Down Expand Up @@ -235,6 +244,8 @@ export const ComponentForField = ({
readOnly={readOnly}
value={value as string}
setValue={setValue as (arg: typeof value) => void}
maxLength={field["max-length"]}
minLength={field["min-length"]}
/>
</WithLabel>
);
Expand Down
2 changes: 2 additions & 0 deletions packages/features/form-builder/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,8 @@ export const fieldSchema = baseFieldSchema.merge(
})
)
.optional(),
["max-length"]: z.string().optional(),
["min-length"]: z.string().optional(),
})
);

Expand Down
Loading