import { has } from "fp-ts/Record"; import { isObject, isString } from "lodash"; import { useEffect, useState } from "react"; import { Box, Button, Checkbox, Flex, Label, Text } from "theme-ui"; import * as yup from "yup"; import { AnyObject } from "yup/lib/types"; import { Col, Flex as FlexGrid } from "@/legacy/components/Flex"; import SliceMachineIconButton from "@/legacy/components/SliceMachineIconButton"; import WidgetFormField from "@/legacy/lib/builders/common/EditModal/Field"; import { createFieldNameFromKey } from "@/legacy/lib/forms"; import { DefaultFields } from "@/legacy/lib/forms/defaults"; import { CheckBox as CheckBoxConstructor } from "@/legacy/lib/forms/fields"; import options, { optionValues } from "./options"; const isAllSet = (curr: Array): boolean => // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions !optionValues.find((e) => !curr.includes(e)); const _createInitialOptions = (str: string) => { const arr = str.split(","); return options.reduce>((acc, { value }) => { if (arr.includes(value)) { return [...acc, value]; } return acc; }, []); }; function getValueFromYupContext( ctx: yup.TestContext, key: string, ): string | null { if ( has("parent", ctx) && isObject(ctx.parent) && has(key, ctx.parent) && isString(ctx.parent[key]) ) return ctx.parent[key]; return null; } function createValidator(key: "single" | "multi") { return () => yup.string().test({ name: key, message: `Options cannot be empty`, test: function (_, ctx) { const other = key === "single" ? "multi" : "single"; const val = getValueFromYupContext(ctx, key); const otherVal = getValueFromYupContext(ctx, other); // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions if (otherVal && typeof otherVal === "string") { return true; } if (typeof val !== "string") { return false; } // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions if ((!val || !val.length) && (!otherVal || !otherVal.length)) { return false; } const arr = val.split(","); // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions if (arr.find((e) => !optionValues.includes(e))) { return false; } return true; }, }); } const FormFields = { ...DefaultFields, allowTargetBlank: CheckBoxConstructor("Allow target blank for links"), single: { validate: createValidator("single"), }, multi: { validate: createValidator("multi"), }, }; const accessors = ["config.single", "config.multi"]; type Config = { allowTargetBlank: boolean; label: string; // RichText placeholder: string; single?: string; multi?: string; }; type FormValues = { config: Config; id: string; }; const WidgetForm: React.FC<{ initialValues: FormValues; values: FormValues; errors: FormValues; fields: Array>; // fields of all the widgets setFieldValue: (a: string, b?: string) => void; }> = (props) => { const { initialValues, values: formValues, errors, fields, setFieldValue, } = props; const { config: { single, multi }, } = formValues; // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions const initialOptions = single ? _createInitialOptions(single) : // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions multi ? _createInitialOptions(multi) : optionValues; // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions const [isMulti, setIsMulti] = useState(single ? false : true); const [acceptOptions, setAcceptOptions] = useState(initialOptions); useEffect(() => { const fieldNameIndex = isMulti ? 1 : 0; setFieldValue(accessors[fieldNameIndex], acceptOptions.join(",")); setTimeout(() => { // prevent tests from failing for both values setFieldValue(accessors[1 - fieldNameIndex], undefined); }, 100); // eslint-disable-next-line react-hooks/exhaustive-deps }, [isMulti, acceptOptions]); return ( {Object.entries(FormFields).map(([key, field]) => ( ))} {options.map((opt) => ( { // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions if (acceptOptions.find((e) => e === opt.value)) { return setAcceptOptions( acceptOptions.filter((e) => e !== opt.value), ); } setAcceptOptions([...acceptOptions, opt.value]); }} /> ))} {/* eslint-disable-next-line @typescript-eslint/strict-boolean-expressions */} {errors.config?.[isMulti ? "multi" : "single"] ? ( {errors.config[isMulti ? "multi" : "single"]} ) : null} ); }; export { FormFields }; export default WidgetForm;