From a5e3303002f1d9b5a978ee2c9c033682cb6058cd Mon Sep 17 00:00:00 2001 From: Han Tuerker Date: Mon, 26 Dec 2022 23:29:51 +0300 Subject: [PATCH] feat(formula-field): fix function regexp, expand listener fields --- src/components/fields/Formula/DisplayCell.tsx | 4 +-- src/components/fields/Formula/useFormula.tsx | 8 ++--- src/components/fields/Formula/util.tsx | 35 ++++--------------- src/components/fields/Formula/worker.ts | 9 +++-- 4 files changed, 18 insertions(+), 38 deletions(-) diff --git a/src/components/fields/Formula/DisplayCell.tsx b/src/components/fields/Formula/DisplayCell.tsx index b0cb61f8..24c7e2c6 100644 --- a/src/components/fields/Formula/DisplayCell.tsx +++ b/src/components/fields/Formula/DisplayCell.tsx @@ -2,13 +2,13 @@ import CircularProgressOptical from "@src/components/CircularProgressOptical"; import { IDisplayCellProps } from "@src/components/fields/types"; import { useFormula } from "./useFormula"; -import { getDisplayCell } from "./util"; +import { defaultFn, getDisplayCell } from "./util"; export default function Formula(props: IDisplayCellProps) { const { result, error, loading } = useFormula({ row: props.row, listenerFields: props.column.config?.listenerFields || [], - formulaFn: props.column.config?.formulaFn || "", + formulaFn: props.column.config?.formulaFn || defaultFn, }); const type = props.column.config?.renderFieldType; diff --git a/src/components/fields/Formula/useFormula.tsx b/src/components/fields/Formula/useFormula.tsx index b316eccd..cfac7ef3 100644 --- a/src/components/fields/Formula/useFormula.tsx +++ b/src/components/fields/Formula/useFormula.tsx @@ -5,11 +5,7 @@ import { useAtom } from "jotai"; import { TableRow } from "@src/types/table"; import { tableColumnsOrderedAtom, tableScope } from "@src/atoms/tableScope"; -import { - getFunctionBody, - listenerFieldTypes, - useDeepCompareMemoize, -} from "./util"; +import { listenerFieldTypes, useDeepCompareMemoize } from "./util"; export const useFormula = ({ row, @@ -63,7 +59,7 @@ export const useFormula = ({ }; worker.postMessage({ - formulaFn: getFunctionBody(formulaFn), + formulaFn, row: availableFields, }); diff --git a/src/components/fields/Formula/util.tsx b/src/components/fields/Formula/util.tsx index 8b74b493..1378d8d4 100644 --- a/src/components/fields/Formula/util.tsx +++ b/src/components/fields/Formula/util.tsx @@ -12,6 +12,8 @@ import CheckboxDisplayCell from "@src/components/fields/Checkbox/DisplayCell"; import PercentageDisplayCell from "@src/components/fields/Percentage/DisplayCell"; import RatingDisplayCell from "@src/components/fields/Rating/DisplayCell"; import SliderDisplayCell from "@src/components/fields/Slider/DisplayCell"; +import SingleSelectDisplayCell from "@src/components/fields/SingleSelect/DisplayCell"; +import MultiSelectDisplayCell from "@src/components/fields/MultiSelect/DisplayCell"; import ColorDisplayCell from "@src/components/fields/Color/DisplayCell"; import GeoPointDisplayCell from "@src/components/fields/GeoPoint/DisplayCell"; import DateDisplayCell from "@src/components/fields/Date/DisplayCell"; @@ -38,17 +40,7 @@ export function useDeepCompareMemoize(value: T) { export const listenerFieldTypes = Object.values(FieldType).filter( (type) => - ![ - FieldType.action, - FieldType.status, - FieldType.formula, - FieldType.aggregate, - FieldType.connectService, - FieldType.connectTable, - FieldType.connector, - FieldType.subTable, - FieldType.last, - ].includes(type) + ![FieldType.formula, FieldType.subTable, FieldType.last].includes(type) ); export const outputFieldTypes = Object.values(FieldType).filter( @@ -99,6 +91,10 @@ export const getDisplayCell = (type: FieldType) => { return RatingDisplayCell; case FieldType.slider: return SliderDisplayCell; + case FieldType.singleSelect: + return SingleSelectDisplayCell; + case FieldType.multiSelect: + return MultiSelectDisplayCell; case FieldType.color: return ColorDisplayCell; case FieldType.geoPoint: @@ -120,23 +116,6 @@ export const getDisplayCell = (type: FieldType) => { case FieldType.createdBy: return CreatedByDisplayCell; default: - // FieldType url, email, phone, singleSelect, multiSelect return ShortTextDisplayCell; } }; - -export const getFunctionBody = (fn: string) => { - const sanitizedFn = fn.replace(/\/\*[\s\S]*?\*\/|\/\/.*/g, ""); - const matches = sanitizedFn.match(/=>\s*({?[\s\S]*}?)$/); - - if (!matches) { - return null; - } - - const body = matches[1].trim(); - const isOneLiner = body[0] !== "{" && body[body.length - 1] !== "}"; - - if (isOneLiner) return `return ${body}`; - - return body.slice(1, body.length - 1); -}; diff --git a/src/components/fields/Formula/worker.ts b/src/components/fields/Formula/worker.ts index 4c37bf5c..16295548 100644 --- a/src/components/fields/Formula/worker.ts +++ b/src/components/fields/Formula/worker.ts @@ -2,11 +2,16 @@ onmessage = async ({ data }) => { try { const { formulaFn, row } = data; const AsyncFunction = async function () {}.constructor as any; - const fn = new AsyncFunction("row", formulaFn); + const [_, fnBody] = formulaFn.match(/=>\s*({?[\s\S]*}?)$/); + if (!fnBody) return; + const fn = new AsyncFunction( + "row", + `const fn = async () => \n${fnBody}\n return fn();` + ); const result = await fn(row); postMessage({ result }); } catch (error: any) { - console.error("error: ", error); + console.error("Error: ", error); postMessage({ error, });