Files
calendar/packages/app-store/routing-forms/lib/transformResponse.ts
T
cf76cf7aae feat: Multiple Options Paste and Routing Form improvements related to Select fields (#15706)
* Add handlePaste function and integrate it with options fields

* Prevents function running if user does not paste a list, allows list items to be pasted without deleting following items

* Subs useState for rhf useWatch to fix issues with multiple form fields

* Sets options array as optional property in zod schema

* Assigns default value to options array to fix possibly undefined type errors

* Sets placedholder property as optional

* maps selectText to options on mount

* Removes comma & semicolon delimiting for pasted lists (new line only) & defines regex as a constant

* Sets default value of placeholder to empty string, provides default fallback for component text field if placeholder is omitted.

* Fix type error on placeholder

* Extracts handlePaste to service function & tests thoroughly

* Some improvements and tests arent needed

* More fixes

* Fix reporting as well

* TS fixes

* Do transforms to and fro from label

* Add unit tests

* Unit test reporting

* Test Improvements

* Self review feedback addressed

---------

Co-authored-by: Hariom Balhara <hariombalhara@gmail.com>
Co-authored-by: Anik Dhabal Babu <81948346+anikdhabal@users.noreply.github.com>
2024-08-22 13:38:46 +00:00

90 lines
2.9 KiB
TypeScript

import type { Field, FormResponse } from "../types/types";
/**
* It takes care of correctly transforming the input to label or id depending on various cases
* - It allows us to prefill with ID or Label
* - It allows backward compatibility with legacy routes(with labels for options)
*/
function transformSelectValue({
field,
idOrLabel,
}: {
field: Pick<Field, "options" | "type">;
idOrLabel: string;
}) {
idOrLabel = idOrLabel.trim();
const options = field.options;
if (!options) {
return idOrLabel;
}
const areOptionsInLegacyFormat = !!options.find((option) => !option.id);
// Because for legacy saved options, routes must have labels in them instead of ids
const shouldUseLabelAsValue = areOptionsInLegacyFormat;
const foundOptionById = options.find((option) => option.id === idOrLabel);
if (foundOptionById) {
if (shouldUseLabelAsValue) {
return foundOptionById.label;
} else {
// If shouldUseLabelAsValue is false, then we must use id as value
// Because shouldUseLabelAsValue is false, id must be set already
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
return foundOptionById.id!;
}
} else {
// No option was found that matches ID
// So check if the label is provided
const foundOptionByLabel = options.find((option) => {
return option.label === idOrLabel;
});
if (foundOptionByLabel) {
if (!shouldUseLabelAsValue) {
// If shouldUseLabelAsValue is false, then we must use id as value
// Because shouldUseLabelAsValue is false, id must be set already
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
return foundOptionByLabel.id!;
}
}
}
return idOrLabel;
}
export function getFieldResponseForJsonLogic({
field,
value,
}: {
field: Pick<Field, "options" | "type">;
value: FormResponse[string]["value"] | undefined;
}) {
if (!value) {
return "";
}
// type="number" still gives value as a string but we need to store that as number so that number operators can work.
if (field.type === "number") {
if (typeof value === "string") {
return Number(value);
}
return value;
}
if (field.type === "multiselect") {
// Could be option id(i.e. a UUIDv4) or option label for ease of prefilling
let valueOrLabelArray = value instanceof Array ? value : value.toString().split(",");
valueOrLabelArray = valueOrLabelArray.map((idOrLabel) => {
return transformSelectValue({ field, idOrLabel });
});
return valueOrLabelArray;
}
if (field.type === "select") {
const valueAsStringOrStringArray = typeof value === "number" ? String(value) : value;
const valueAsString =
valueAsStringOrStringArray instanceof Array
? valueAsStringOrStringArray[0]
: valueAsStringOrStringArray;
return transformSelectValue({ field, idOrLabel: valueAsString });
}
return value;
}